Mercurial > hg > svgui
changeset 1299:91670e4e76a6
Merge from branch plugin-path-config
author | Chris Cannam |
---|---|
date | Mon, 11 Jun 2018 14:40:36 +0100 |
parents | 51e6125627fa (current diff) f24f64e441ac (diff) |
children | 1589bc7528b7 |
files | |
diffstat | 6 files changed, 659 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/files.pri Tue May 08 14:27:54 2018 +0100 +++ b/files.pri Mon Jun 11 14:40:36 2018 +0100 @@ -74,6 +74,8 @@ widgets/Panner.h \ widgets/PluginParameterBox.h \ widgets/PluginParameterDialog.h \ + widgets/PluginPathConfigurator.h \ + widgets/PluginReviewDialog.h \ widgets/ProgressDialog.h \ widgets/PropertyBox.h \ widgets/PropertyStack.h \ @@ -156,6 +158,8 @@ widgets/Panner.cpp \ widgets/PluginParameterBox.cpp \ widgets/PluginParameterDialog.cpp \ + widgets/PluginPathConfigurator.cpp \ + widgets/PluginReviewDialog.cpp \ widgets/ProgressDialog.cpp \ widgets/PropertyBox.cpp \ widgets/PropertyStack.cpp \
--- a/widgets/InteractiveFileFinder.cpp Tue May 08 14:27:54 2018 +0100 +++ b/widgets/InteractiveFileFinder.cpp Mon Jun 11 14:40:36 2018 +0100 @@ -19,6 +19,7 @@ #include "data/fileio/DataFileReaderFactory.h" #include "rdf/RDFImporter.h" #include "rdf/RDFExporter.h" +#include "system/System.h" #include <QFileInfo> #include <QMessageBox> @@ -156,9 +157,12 @@ }; if (lastPath == "") { - char *home = getenv("HOME"); - if (home) lastPath = home; - else lastPath = "."; + std::string home; + if (getEnvUtf8("HOME", home)) { + lastPath = QString::fromStdString(home); + } else { + lastPath = "."; + } } else if (QFileInfo(lastPath).isDir()) { lastPath = QFileInfo(lastPath).canonicalPath(); } else { @@ -305,9 +309,12 @@ }; if (lastPath == "") { - char *home = getenv("HOME"); - if (home) lastPath = home; - else lastPath = "."; + std::string home; + if (getEnvUtf8("HOME", home)) { + lastPath = QString::fromStdString(home); + } else { + lastPath = "."; + } } else if (QFileInfo(lastPath).isDir()) { lastPath = QFileInfo(lastPath).canonicalPath(); } else {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/widgets/PluginPathConfigurator.cpp Mon Jun 11 14:40:36 2018 +0100 @@ -0,0 +1,384 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#include "PluginPathConfigurator.h" +#include "PluginReviewDialog.h" + +#include <QPushButton> +#include <QListWidget> +#include <QGridLayout> +#include <QComboBox> +#include <QLabel> +#include <QCheckBox> +#include <QFileDialog> + +#include "IconLoader.h" +#include "WidgetScale.h" + +#include "plugin/PluginPathSetter.h" + +PluginPathConfigurator::PluginPathConfigurator(QWidget *parent) : + QFrame(parent) +{ + m_layout = new QGridLayout; + setLayout(m_layout); + + QHBoxLayout *buttons = new QHBoxLayout; + + m_down = new QPushButton; + m_down->setIcon(IconLoader().load("down")); + m_down->setToolTip(tr("Move the selected location later in the list")); + connect(m_down, SIGNAL(clicked()), this, SLOT(downClicked())); + buttons->addWidget(m_down); + + m_up = new QPushButton; + m_up->setIcon(IconLoader().load("up")); + m_up->setToolTip(tr("Move the selected location earlier in the list")); + connect(m_up, SIGNAL(clicked()), this, SLOT(upClicked())); + buttons->addWidget(m_up); + + m_add = new QPushButton; + m_add->setIcon(IconLoader().load("plus")); + m_add->setToolTip(tr("Add a new location to the list")); + connect(m_add, SIGNAL(clicked()), this, SLOT(addClicked())); + buttons->addWidget(m_add); + + m_delete = new QPushButton; + m_delete->setIcon(IconLoader().load("datadelete")); + m_delete->setToolTip(tr("Remove the selected location from the list")); + connect(m_delete, SIGNAL(clicked()), this, SLOT(deleteClicked())); + buttons->addWidget(m_delete); + + m_reset = new QPushButton; + m_reset->setText(tr("Reset to Default")); + m_reset->setToolTip(tr("Reset the list for this plugin type to its default")); + connect(m_reset, SIGNAL(clicked()), this, SLOT(resetClicked())); + buttons->addWidget(m_reset); + + buttons->addStretch(50); + + m_seePlugins = new QPushButton; + m_seePlugins->setText(tr("Review plugins...")); + connect(m_seePlugins, SIGNAL(clicked()), this, SLOT(seePluginsClicked())); + buttons->addWidget(m_seePlugins); + + int row = 0; + + m_header = new QLabel; + m_header->setText(tr("Plugin locations for plugin type:")); + m_layout->addWidget(m_header, row, 0); + + m_pluginTypeSelector = new QComboBox; + m_layout->addWidget(m_pluginTypeSelector, row, 1, Qt::AlignLeft); + connect(m_pluginTypeSelector, SIGNAL(currentTextChanged(QString)), + this, SLOT(currentTypeChanged(QString))); + + m_layout->setColumnStretch(1, 10); + ++row; + + m_list = new QListWidget; + m_layout->addWidget(m_list, row, 0, 1, 3); + m_layout->setRowStretch(row, 20); + connect(m_list, SIGNAL(currentRowChanged(int)), + this, SLOT(currentLocationChanged(int))); + ++row; + + m_layout->addLayout(buttons, row, 0, 1, 3); + + ++row; + + m_envOverride = new QCheckBox; + connect(m_envOverride, SIGNAL(stateChanged(int)), + this, SLOT(envOverrideChanged(int))); + m_layout->addWidget(m_envOverride, row, 0, 1, 3); + ++row; +} + +PluginPathConfigurator::~PluginPathConfigurator() +{ +} + +QString +PluginPathConfigurator::getLabelFor(PluginPathSetter::TypeKey key) +{ + if (key.second == KnownPlugins::FormatNative) { + switch (key.first) { + case KnownPlugins::VampPlugin: + return tr("Vamp"); + case KnownPlugins::LADSPAPlugin: + return tr("LADSPA"); + case KnownPlugins::DSSIPlugin: + return tr("DSSI"); + } + } else if (key.second == KnownPlugins::FormatNonNative32Bit) { + switch (key.first) { + case KnownPlugins::VampPlugin: + return tr("Vamp (32-bit)"); + case KnownPlugins::LADSPAPlugin: + return tr("LADSPA (32-bit)"); + case KnownPlugins::DSSIPlugin: + return tr("DSSI (32-bit)"); + } + } + SVCERR << "PluginPathConfigurator::getLabelFor: WARNING: " + << "Unknown format value " << key.second << endl; + return "<unknown>"; +} + +PluginPathSetter::TypeKey +PluginPathConfigurator::getKeyForLabel(QString label) +{ + for (const auto &p: m_paths) { + auto key = p.first; + if (getLabelFor(key) == label) { + return key; + } + } + SVCERR << "PluginPathConfigurator::getKeyForLabel: WARNING: " + << "Unrecognised label \"" << label << "\"" << endl; + return { KnownPlugins::VampPlugin, KnownPlugins::FormatNative }; +} + +void +PluginPathConfigurator::setPaths(PluginPathSetter::Paths paths) +{ + m_paths = paths; + + m_defaultPaths = PluginPathSetter::getDefaultPaths(); + + m_pluginTypeSelector->clear(); + for (const auto &p: paths) { + m_pluginTypeSelector->addItem(getLabelFor(p.first)); + } + + populate(); +} + +void +PluginPathConfigurator::populate() +{ + m_list->clear(); + + if (m_paths.empty()) return; + + populateFor(m_paths.begin()->first, -1); +} + +void +PluginPathConfigurator::populateFor(PluginPathSetter::TypeKey key, + int makeCurrent) +{ + QString envVariable = m_paths.at(key).envVariable; + bool useEnvVariable = m_paths.at(key).useEnvVariable; + QString envVarValue = + PluginPathSetter::getOriginalEnvironmentValue(envVariable); + QString currentValueRubric; + if (envVarValue == QString()) { + currentValueRubric = tr("(Variable is currently unset)"); + } else { + if (envVarValue.length() > 100) { + QString envVarStart = envVarValue.left(95); + currentValueRubric = tr("(Current value begins: \"%1 ...\")") + .arg(envVarStart); + } else { + currentValueRubric = tr("(Currently set to: \"%1\")") + .arg(envVarValue); + } + } + m_envOverride->setText + (tr("Allow the %1 environment variable to take priority over this\n%2") + .arg(envVariable) + .arg(currentValueRubric)); + m_envOverride->setCheckState(useEnvVariable ? Qt::Checked : Qt::Unchecked); + + m_list->clear(); + + for (int i = 0; i < m_pluginTypeSelector->count(); ++i) { + if (getLabelFor(key) == m_pluginTypeSelector->itemText(i)) { + m_pluginTypeSelector->blockSignals(true); + m_pluginTypeSelector->setCurrentIndex(i); + m_pluginTypeSelector->blockSignals(false); + } + } + + QStringList path = m_paths.at(key).directories; + + for (int i = 0; i < path.size(); ++i) { + m_list->addItem(path[i]); + } + + if (makeCurrent < path.size()) { + m_list->setCurrentRow(makeCurrent); + currentLocationChanged(makeCurrent); + } +} + +void +PluginPathConfigurator::currentLocationChanged(int i) +{ + QString label = m_pluginTypeSelector->currentText(); + PluginPathSetter::TypeKey key = getKeyForLabel(label); + QStringList path = m_paths.at(key).directories; + m_up->setEnabled(i > 0); + m_down->setEnabled(i >= 0 && i + 1 < path.size()); + m_delete->setEnabled(i >= 0 && i < path.size()); + m_reset->setEnabled(path != m_defaultPaths.at(key).directories); +} + +void +PluginPathConfigurator::currentTypeChanged(QString label) +{ + populateFor(getKeyForLabel(label), -1); +} + +void +PluginPathConfigurator::envOverrideChanged(int state) +{ + bool useEnvVariable = (state == Qt::Checked); + + QString label = m_pluginTypeSelector->currentText(); + PluginPathSetter::TypeKey key = getKeyForLabel(label); + + auto newEntry = m_paths.at(key); + newEntry.useEnvVariable = useEnvVariable; + m_paths[key] = newEntry; + + emit pathsChanged(); +} + +void +PluginPathConfigurator::upClicked() +{ + QString label = m_pluginTypeSelector->currentText(); + PluginPathSetter::TypeKey key = getKeyForLabel(label); + QStringList path = m_paths.at(key).directories; + + int current = m_list->currentRow(); + if (current <= 0) return; + + QStringList newPath; + for (int i = 0; i < path.size(); ++i) { + if (i + 1 == current) { + newPath.push_back(path[i+1]); + newPath.push_back(path[i]); + ++i; + } else { + newPath.push_back(path[i]); + } + } + + auto newEntry = m_paths.at(key); + newEntry.directories = newPath; + m_paths[key] = newEntry; + + populateFor(key, current - 1); + + emit pathsChanged(); +} + +void +PluginPathConfigurator::downClicked() +{ + QString label = m_pluginTypeSelector->currentText(); + PluginPathSetter::TypeKey key = getKeyForLabel(label); + QStringList path = m_paths.at(key).directories; + + int current = m_list->currentRow(); + if (current < 0 || current + 1 >= path.size()) return; + + QStringList newPath; + for (int i = 0; i < path.size(); ++i) { + if (i == current) { + newPath.push_back(path[i+1]); + newPath.push_back(path[i]); + ++i; + } else { + newPath.push_back(path[i]); + } + } + + auto newEntry = m_paths.at(key); + newEntry.directories = newPath; + m_paths[key] = newEntry; + + populateFor(key, current + 1); + + emit pathsChanged(); +} + +void +PluginPathConfigurator::addClicked() +{ + QString label = m_pluginTypeSelector->currentText(); + PluginPathSetter::TypeKey key = getKeyForLabel(label); + + QString newDir = QFileDialog::getExistingDirectory + (this, tr("Choose directory to add")); + + if (newDir == QString()) return; + + auto newEntry = m_paths.at(key); + newEntry.directories.push_back(newDir); + m_paths[key] = newEntry; + + populateFor(key, newEntry.directories.size() - 1); + + emit pathsChanged(); +} + +void +PluginPathConfigurator::deleteClicked() +{ + QString label = m_pluginTypeSelector->currentText(); + PluginPathSetter::TypeKey key = getKeyForLabel(label); + QStringList path = m_paths.at(key).directories; + + int current = m_list->currentRow(); + if (current < 0) return; + + QStringList newPath; + for (int i = 0; i < path.size(); ++i) { + if (i != current) { + newPath.push_back(path[i]); + } + } + + auto newEntry = m_paths.at(key); + newEntry.directories = newPath; + m_paths[key] = newEntry; + + populateFor(key, current < newPath.size() ? current : current-1); + + emit pathsChanged(); +} + +void +PluginPathConfigurator::resetClicked() +{ + QString label = m_pluginTypeSelector->currentText(); + PluginPathSetter::TypeKey key = getKeyForLabel(label); + m_paths[key] = m_defaultPaths[key]; + populateFor(key, -1); + + emit pathsChanged(); +} + +void +PluginPathConfigurator::seePluginsClicked() +{ + PluginReviewDialog dialog(this); + dialog.populate(); + dialog.exec(); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/widgets/PluginPathConfigurator.h Mon Jun 11 14:40:36 2018 +0100 @@ -0,0 +1,81 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#ifndef SV_PLUGIN_PATH_CONFIGURATOR_H +#define SV_PLUGIN_PATH_CONFIGURATOR_H + +#include <QFrame> +#include <QStringList> + +class QLabel; +class QWidget; +class QListWidget; +class QPushButton; +class QGridLayout; +class QComboBox; +class QCheckBox; + +#include "plugin/PluginPathSetter.h" + +class PluginPathConfigurator : public QFrame +{ + Q_OBJECT + +public: + PluginPathConfigurator(QWidget *parent = 0); + ~PluginPathConfigurator(); + + void setPaths(PluginPathSetter::Paths paths); + PluginPathSetter::Paths getPaths() const { return m_paths; } + +signals: + void pathsChanged(); + +private slots: + void upClicked(); + void downClicked(); + void addClicked(); + void deleteClicked(); + void resetClicked(); + void currentTypeChanged(QString); + void currentLocationChanged(int); + void envOverrideChanged(int); + void seePluginsClicked(); + +private: + QGridLayout *m_layout; + QLabel *m_header; + QComboBox *m_pluginTypeSelector; + QListWidget *m_list; + QPushButton *m_seePlugins; + QPushButton *m_up; + QPushButton *m_down; + QPushButton *m_add; + QPushButton *m_delete; + QPushButton *m_reset; + QCheckBox *m_envOverride; + + PluginPathSetter::Paths m_paths; + PluginPathSetter::Paths m_defaultPaths; + + void populate(); + void populateFor(PluginPathSetter::TypeKey, int makeCurrent); + + QString getLabelFor(PluginPathSetter::TypeKey); + PluginPathSetter::TypeKey getKeyForLabel(QString label); +}; + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/widgets/PluginReviewDialog.cpp Mon Jun 11 14:40:36 2018 +0100 @@ -0,0 +1,140 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#include "PluginReviewDialog.h" + +#include <QGridLayout> +#include <QTableWidget> +#include <QDialogButtonBox> +#include <QFileInfo> +#include <QHeaderView> +#include <QDesktopWidget> +#include <QApplication> + +#include "plugin/FeatureExtractionPluginFactory.h" +#include "plugin/RealTimePluginFactory.h" + +PluginReviewDialog::PluginReviewDialog(QWidget *parent) : + QDialog(parent) +{ + setWindowTitle(tr("Plugins Loaded")); + + QGridLayout *layout = new QGridLayout; + setLayout(layout); + + m_table = new QTableWidget; + layout->addWidget(m_table, 0, 1); + + QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Close); + layout->addWidget(bb, 1, 1); + connect(bb, SIGNAL(rejected()), this, SLOT(close())); +} + +PluginReviewDialog::~PluginReviewDialog() +{ +} + +void +PluginReviewDialog::populate() +{ + FeatureExtractionPluginFactory *feFactory = + FeatureExtractionPluginFactory::instance(); + QString err; + std::vector<QString> feIds = feFactory->getPluginIdentifiers(err); + + RealTimePluginFactory *dssiFactory = + RealTimePluginFactory::instance("dssi"); + std::vector<QString> dssiIds = dssiFactory->getPluginIdentifiers(); + + RealTimePluginFactory *ladspaFactory = + RealTimePluginFactory::instance("ladspa"); + std::vector<QString> ladspaIds = ladspaFactory->getPluginIdentifiers(); + + m_table->setRowCount(int(feIds.size() + dssiIds.size() + ladspaIds.size())); + m_table->setColumnCount(5); + + QStringList headers; + int typeCol = 0, libCol = 1, idCol = 2, dirCol = 3, nameCol = 4; + headers << tr("Type") << tr("Library") + << tr("Identifier") << tr("Found in") << tr("Name"); + m_table->setHorizontalHeaderLabels(headers); + + int row = 0; + + for (QString id: feIds) { + auto staticData = feFactory->getPluginStaticData(id); + m_table->setItem(row, typeCol, new QTableWidgetItem + (tr("Vamp"))); + m_table->setItem(row, idCol, new QTableWidgetItem + (QString::fromStdString(staticData.basic.identifier))); + m_table->setItem(row, nameCol, new QTableWidgetItem + (QString::fromStdString(staticData.basic.name))); + QString path = feFactory->getPluginLibraryPath(id); + m_table->setItem(row, libCol, new QTableWidgetItem + (QFileInfo(path).fileName())); + m_table->setItem(row, dirCol, new QTableWidgetItem + (QFileInfo(path).path())); + row++; + } + + for (QString id: dssiIds) { + auto descriptor = dssiFactory->getPluginDescriptor(id); + if (!descriptor) continue; + m_table->setItem(row, typeCol, new QTableWidgetItem + (tr("DSSI"))); + m_table->setItem(row, idCol, new QTableWidgetItem + (QString::fromStdString(descriptor->label))); + m_table->setItem(row, nameCol, new QTableWidgetItem + (QString::fromStdString(descriptor->name))); + QString path = dssiFactory->getPluginLibraryPath(id); + m_table->setItem(row, libCol, new QTableWidgetItem + (QFileInfo(path).fileName())); + m_table->setItem(row, dirCol, new QTableWidgetItem + (QFileInfo(path).path())); + row++; + } + + for (QString id: ladspaIds) { + auto descriptor = ladspaFactory->getPluginDescriptor(id); + if (!descriptor) continue; + m_table->setItem(row, typeCol, new QTableWidgetItem + (tr("LADSPA"))); + m_table->setItem(row, idCol, new QTableWidgetItem + (QString::fromStdString(descriptor->label))); + m_table->setItem(row, nameCol, new QTableWidgetItem + (QString::fromStdString(descriptor->name))); + QString path = ladspaFactory->getPluginLibraryPath(id); + m_table->setItem(row, libCol, new QTableWidgetItem + (QFileInfo(path).fileName())); + m_table->setItem(row, dirCol, new QTableWidgetItem + (QFileInfo(path).path())); + row++; + } + + m_table->setSortingEnabled(true); + m_table->setSelectionMode(QAbstractItemView::NoSelection); + m_table->resizeColumnsToContents(); + + int twidth = m_table->horizontalHeader()->length(); + int theight = m_table->verticalHeader()->length(); + + QDesktopWidget *desktop = QApplication::desktop(); + QRect available = desktop->availableGeometry(); + + int width = std::min(twidth + 30, (available.width() * 3) / 4); + int height = std::min(theight + 30, (available.height() * 3) / 4); + + resize(width, height); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/widgets/PluginReviewDialog.h Mon Jun 11 14:40:36 2018 +0100 @@ -0,0 +1,37 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#ifndef SV_PLUGIN_REVIEW_DIALOG_H +#define SV_PLUGIN_REVIEW_DIALOG_H + +#include <QDialog> +#include <QTableWidget> + +class QEvent; + +class PluginReviewDialog : public QDialog +{ + Q_OBJECT + +public: + PluginReviewDialog(QWidget *parent = 0); + ~PluginReviewDialog(); + + void populate(); + +private: + QTableWidget *m_table; +}; + +#endif