Chris@1285: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@1285: Chris@1285: /* Chris@1285: Sonic Visualiser Chris@1285: An audio file viewer and annotation editor. Chris@1285: Centre for Digital Music, Queen Mary, University of London. Chris@1285: Chris@1285: This program is free software; you can redistribute it and/or Chris@1285: modify it under the terms of the GNU General Public License as Chris@1285: published by the Free Software Foundation; either version 2 of the Chris@1285: License, or (at your option) any later version. See the file Chris@1285: COPYING included with this distribution for more information. Chris@1285: */ Chris@1285: Chris@1285: #include "PluginPathConfigurator.h" Chris@1292: #include "PluginReviewDialog.h" Chris@1285: Chris@1285: #include Chris@1287: #include Chris@1288: #include Chris@1289: #include Chris@1285: #include Chris@1290: #include Chris@1291: #include Chris@1285: Chris@1285: #include "IconLoader.h" Chris@1285: #include "WidgetScale.h" Chris@1285: Chris@1293: #include "plugin/PluginPathSetter.h" Chris@1293: Chris@1285: PluginPathConfigurator::PluginPathConfigurator(QWidget *parent) : Chris@1287: QFrame(parent) Chris@1285: { Chris@1285: m_layout = new QGridLayout; Chris@1285: setLayout(m_layout); Chris@1292: Chris@1291: QHBoxLayout *buttons = new QHBoxLayout; Chris@1291: Chris@1291: m_down = new QPushButton; Chris@1291: m_down->setIcon(IconLoader().load("down")); Chris@1291: m_down->setToolTip(tr("Move the selected location later in the list")); Chris@1291: connect(m_down, SIGNAL(clicked()), this, SLOT(downClicked())); Chris@1291: buttons->addWidget(m_down); Chris@1291: Chris@1291: m_up = new QPushButton; Chris@1291: m_up->setIcon(IconLoader().load("up")); Chris@1291: m_up->setToolTip(tr("Move the selected location earlier in the list")); Chris@1291: connect(m_up, SIGNAL(clicked()), this, SLOT(upClicked())); Chris@1291: buttons->addWidget(m_up); Chris@1291: Chris@1291: m_add = new QPushButton; Chris@1291: m_add->setIcon(IconLoader().load("plus")); Chris@1295: m_add->setToolTip(tr("Add a new location to the list")); Chris@1291: connect(m_add, SIGNAL(clicked()), this, SLOT(addClicked())); Chris@1291: buttons->addWidget(m_add); Chris@1291: Chris@1291: m_delete = new QPushButton; Chris@1291: m_delete->setIcon(IconLoader().load("datadelete")); Chris@1291: m_delete->setToolTip(tr("Remove the selected location from the list")); Chris@1291: connect(m_delete, SIGNAL(clicked()), this, SLOT(deleteClicked())); Chris@1291: buttons->addWidget(m_delete); Chris@1291: Chris@1291: m_reset = new QPushButton; Chris@1293: m_reset->setText(tr("Reset to Default")); Chris@1291: m_reset->setToolTip(tr("Reset the list for this plugin type to its default")); Chris@1291: connect(m_reset, SIGNAL(clicked()), this, SLOT(resetClicked())); Chris@1291: buttons->addWidget(m_reset); Chris@1287: Chris@1297: buttons->addStretch(50); Chris@1297: Chris@1297: m_seePlugins = new QPushButton; Chris@1297: m_seePlugins->setText(tr("Review plugins...")); Chris@1297: connect(m_seePlugins, SIGNAL(clicked()), this, SLOT(seePluginsClicked())); Chris@1297: buttons->addWidget(m_seePlugins); Chris@1297: Chris@1287: int row = 0; Chris@1287: Chris@1289: m_header = new QLabel; Chris@1290: m_header->setText(tr("Plugin locations for plugin type:")); Chris@1289: m_layout->addWidget(m_header, row, 0); Chris@1289: Chris@1289: m_pluginTypeSelector = new QComboBox; Chris@1290: m_layout->addWidget(m_pluginTypeSelector, row, 1, Qt::AlignLeft); Chris@1289: connect(m_pluginTypeSelector, SIGNAL(currentTextChanged(QString)), Chris@1289: this, SLOT(currentTypeChanged(QString))); Chris@1289: Chris@1290: m_layout->setColumnStretch(1, 10); Chris@1287: ++row; Chris@1287: Chris@1287: m_list = new QListWidget; Chris@1290: m_layout->addWidget(m_list, row, 0, 1, 3); Chris@1290: m_layout->setRowStretch(row, 20); Chris@1288: connect(m_list, SIGNAL(currentRowChanged(int)), Chris@1288: this, SLOT(currentLocationChanged(int))); Chris@1287: ++row; Chris@1290: Chris@1297: m_layout->addLayout(buttons, row, 0, 1, 3); Chris@1292: Chris@1287: ++row; Chris@1291: Chris@1290: m_envOverride = new QCheckBox; Chris@1290: connect(m_envOverride, SIGNAL(stateChanged(int)), Chris@1290: this, SLOT(envOverrideChanged(int))); Chris@1290: m_layout->addWidget(m_envOverride, row, 0, 1, 3); Chris@1291: ++row; Chris@1285: } Chris@1285: Chris@1285: PluginPathConfigurator::~PluginPathConfigurator() Chris@1285: { Chris@1285: } Chris@1285: Chris@1296: QString Chris@1296: PluginPathConfigurator::getLabelFor(PluginPathSetter::TypeKey key) Chris@1296: { Chris@1296: if (key.second == KnownPlugins::FormatNative) { Chris@1296: switch (key.first) { Chris@1296: case KnownPlugins::VampPlugin: Chris@1296: return tr("Vamp"); Chris@1296: case KnownPlugins::LADSPAPlugin: Chris@1296: return tr("LADSPA"); Chris@1296: case KnownPlugins::DSSIPlugin: Chris@1296: return tr("DSSI"); Chris@1296: } Chris@1296: } else if (key.second == KnownPlugins::FormatNonNative32Bit) { Chris@1296: switch (key.first) { Chris@1296: case KnownPlugins::VampPlugin: Chris@1296: return tr("Vamp (32-bit)"); Chris@1296: case KnownPlugins::LADSPAPlugin: Chris@1296: return tr("LADSPA (32-bit)"); Chris@1296: case KnownPlugins::DSSIPlugin: Chris@1296: return tr("DSSI (32-bit)"); Chris@1296: } Chris@1296: } Chris@1298: SVCERR << "PluginPathConfigurator::getLabelFor: WARNING: " Chris@1298: << "Unknown format value " << key.second << endl; Chris@1298: return ""; Chris@1296: } Chris@1296: Chris@1296: PluginPathSetter::TypeKey Chris@1296: PluginPathConfigurator::getKeyForLabel(QString label) Chris@1296: { Chris@1296: for (const auto &p: m_paths) { Chris@1296: auto key = p.first; Chris@1296: if (getLabelFor(key) == label) { Chris@1296: return key; Chris@1296: } Chris@1296: } Chris@1296: SVCERR << "PluginPathConfigurator::getKeyForLabel: WARNING: " Chris@1296: << "Unrecognised label \"" << label << "\"" << endl; Chris@1296: return { KnownPlugins::VampPlugin, KnownPlugins::FormatNative }; Chris@1296: } Chris@1296: Chris@1285: void Chris@1293: PluginPathConfigurator::setPaths(PluginPathSetter::Paths paths) Chris@1285: { Chris@1289: m_paths = paths; Chris@1293: Chris@1293: m_defaultPaths = PluginPathSetter::getDefaultPaths(); Chris@1289: Chris@1289: m_pluginTypeSelector->clear(); Chris@1289: for (const auto &p: paths) { Chris@1296: m_pluginTypeSelector->addItem(getLabelFor(p.first)); Chris@1289: } Chris@1289: Chris@1285: populate(); Chris@1285: } Chris@1285: Chris@1285: void Chris@1289: PluginPathConfigurator::populate() Chris@1285: { Chris@1287: m_list->clear(); Chris@1286: Chris@1289: if (m_paths.empty()) return; Chris@1289: Chris@1296: populateFor(m_paths.begin()->first, -1); Chris@1289: } Chris@1289: Chris@1289: void Chris@1296: PluginPathConfigurator::populateFor(PluginPathSetter::TypeKey key, Chris@1296: int makeCurrent) Chris@1289: { Chris@1296: QString envVariable = m_paths.at(key).envVariable; Chris@1296: bool useEnvVariable = m_paths.at(key).useEnvVariable; Chris@1294: QString envVarValue = Chris@1294: PluginPathSetter::getOriginalEnvironmentValue(envVariable); Chris@1294: QString currentValueRubric; Chris@1294: if (envVarValue == QString()) { Chris@1294: currentValueRubric = tr("(Variable is currently unset)"); Chris@1294: } else { Chris@1294: if (envVarValue.length() > 100) { Chris@1294: QString envVarStart = envVarValue.left(95); Chris@1294: currentValueRubric = tr("(Current value begins: \"%1 ...\")") Chris@1294: .arg(envVarStart); Chris@1294: } else { Chris@1294: currentValueRubric = tr("(Currently set to: \"%1\")") Chris@1294: .arg(envVarValue); Chris@1294: } Chris@1294: } Chris@1290: m_envOverride->setText Chris@1294: (tr("Allow the %1 environment variable to take priority over this\n%2") Chris@1294: .arg(envVariable) Chris@1294: .arg(currentValueRubric)); Chris@1290: m_envOverride->setCheckState(useEnvVariable ? Qt::Checked : Qt::Unchecked); Chris@1294: Chris@1289: m_list->clear(); Chris@1289: Chris@1289: for (int i = 0; i < m_pluginTypeSelector->count(); ++i) { Chris@1296: if (getLabelFor(key) == m_pluginTypeSelector->itemText(i)) { Chris@1294: m_pluginTypeSelector->blockSignals(true); Chris@1289: m_pluginTypeSelector->setCurrentIndex(i); Chris@1294: m_pluginTypeSelector->blockSignals(false); Chris@1289: } Chris@1289: } Chris@1289: Chris@1296: QStringList path = m_paths.at(key).directories; Chris@1289: Chris@1289: for (int i = 0; i < path.size(); ++i) { Chris@1289: m_list->addItem(path[i]); Chris@1287: } Chris@1285: Chris@1290: if (makeCurrent < path.size()) { Chris@1287: m_list->setCurrentRow(makeCurrent); Chris@1290: currentLocationChanged(makeCurrent); Chris@1286: } Chris@1285: } Chris@1285: Chris@1285: void Chris@1288: PluginPathConfigurator::currentLocationChanged(int i) Chris@1288: { Chris@1296: QString label = m_pluginTypeSelector->currentText(); Chris@1296: PluginPathSetter::TypeKey key = getKeyForLabel(label); Chris@1296: QStringList path = m_paths.at(key).directories; Chris@1288: m_up->setEnabled(i > 0); Chris@1290: m_down->setEnabled(i >= 0 && i + 1 < path.size()); Chris@1290: m_delete->setEnabled(i >= 0 && i < path.size()); Chris@1296: m_reset->setEnabled(path != m_defaultPaths.at(key).directories); Chris@1289: } Chris@1289: Chris@1289: void Chris@1296: PluginPathConfigurator::currentTypeChanged(QString label) Chris@1289: { Chris@1296: populateFor(getKeyForLabel(label), -1); Chris@1290: } Chris@1290: Chris@1290: void Chris@1292: PluginPathConfigurator::envOverrideChanged(int state) Chris@1290: { Chris@1292: bool useEnvVariable = (state == Qt::Checked); Chris@1292: Chris@1296: QString label = m_pluginTypeSelector->currentText(); Chris@1296: PluginPathSetter::TypeKey key = getKeyForLabel(label); Chris@1292: Chris@1296: auto newEntry = m_paths.at(key); Chris@1292: newEntry.useEnvVariable = useEnvVariable; Chris@1296: m_paths[key] = newEntry; Chris@1292: Chris@1293: emit pathsChanged(); Chris@1288: } Chris@1288: Chris@1288: void Chris@1285: PluginPathConfigurator::upClicked() Chris@1285: { Chris@1296: QString label = m_pluginTypeSelector->currentText(); Chris@1296: PluginPathSetter::TypeKey key = getKeyForLabel(label); Chris@1296: QStringList path = m_paths.at(key).directories; Chris@1289: Chris@1287: int current = m_list->currentRow(); Chris@1287: if (current <= 0) return; Chris@1287: Chris@1286: QStringList newPath; Chris@1289: for (int i = 0; i < path.size(); ++i) { Chris@1287: if (i + 1 == current) { Chris@1289: newPath.push_back(path[i+1]); Chris@1289: newPath.push_back(path[i]); Chris@1286: ++i; Chris@1286: } else { Chris@1289: newPath.push_back(path[i]); Chris@1286: } Chris@1286: } Chris@1290: Chris@1296: auto newEntry = m_paths.at(key); Chris@1290: newEntry.directories = newPath; Chris@1296: m_paths[key] = newEntry; Chris@1287: Chris@1296: populateFor(key, current - 1); Chris@1292: Chris@1293: emit pathsChanged(); Chris@1285: } Chris@1285: Chris@1285: void Chris@1285: PluginPathConfigurator::downClicked() Chris@1285: { Chris@1296: QString label = m_pluginTypeSelector->currentText(); Chris@1296: PluginPathSetter::TypeKey key = getKeyForLabel(label); Chris@1296: QStringList path = m_paths.at(key).directories; Chris@1289: Chris@1287: int current = m_list->currentRow(); Chris@1289: if (current < 0 || current + 1 >= path.size()) return; Chris@1289: Chris@1286: QStringList newPath; Chris@1289: for (int i = 0; i < path.size(); ++i) { Chris@1287: if (i == current) { Chris@1289: newPath.push_back(path[i+1]); Chris@1289: newPath.push_back(path[i]); Chris@1286: ++i; Chris@1286: } else { Chris@1289: newPath.push_back(path[i]); Chris@1286: } Chris@1286: } Chris@1290: Chris@1296: auto newEntry = m_paths.at(key); Chris@1290: newEntry.directories = newPath; Chris@1296: m_paths[key] = newEntry; Chris@1287: Chris@1296: populateFor(key, current + 1); Chris@1292: Chris@1293: emit pathsChanged(); Chris@1285: } Chris@1285: Chris@1285: void Chris@1291: PluginPathConfigurator::addClicked() Chris@1291: { Chris@1296: QString label = m_pluginTypeSelector->currentText(); Chris@1296: PluginPathSetter::TypeKey key = getKeyForLabel(label); Chris@1291: Chris@1291: QString newDir = QFileDialog::getExistingDirectory Chris@1291: (this, tr("Choose directory to add")); Chris@1291: Chris@1291: if (newDir == QString()) return; Chris@1291: Chris@1296: auto newEntry = m_paths.at(key); Chris@1291: newEntry.directories.push_back(newDir); Chris@1296: m_paths[key] = newEntry; Chris@1291: Chris@1296: populateFor(key, newEntry.directories.size() - 1); Chris@1292: Chris@1293: emit pathsChanged(); Chris@1291: } Chris@1291: Chris@1291: void Chris@1285: PluginPathConfigurator::deleteClicked() Chris@1285: { Chris@1296: QString label = m_pluginTypeSelector->currentText(); Chris@1296: PluginPathSetter::TypeKey key = getKeyForLabel(label); Chris@1296: QStringList path = m_paths.at(key).directories; Chris@1289: Chris@1287: int current = m_list->currentRow(); Chris@1290: if (current < 0) return; Chris@1289: Chris@1286: QStringList newPath; Chris@1289: for (int i = 0; i < path.size(); ++i) { Chris@1287: if (i != current) { Chris@1289: newPath.push_back(path[i]); Chris@1286: } Chris@1286: } Chris@1290: Chris@1296: auto newEntry = m_paths.at(key); Chris@1290: newEntry.directories = newPath; Chris@1296: m_paths[key] = newEntry; Chris@1287: Chris@1296: populateFor(key, current < newPath.size() ? current : current-1); Chris@1292: Chris@1293: emit pathsChanged(); Chris@1285: } Chris@1290: Chris@1290: void Chris@1290: PluginPathConfigurator::resetClicked() Chris@1290: { Chris@1296: QString label = m_pluginTypeSelector->currentText(); Chris@1296: PluginPathSetter::TypeKey key = getKeyForLabel(label); Chris@1296: m_paths[key] = m_defaultPaths[key]; Chris@1296: populateFor(key, -1); Chris@1292: Chris@1293: emit pathsChanged(); Chris@1290: } Chris@1292: Chris@1292: void Chris@1292: PluginPathConfigurator::seePluginsClicked() Chris@1292: { Chris@1292: PluginReviewDialog dialog(this); Chris@1292: dialog.populate(); Chris@1292: dialog.exec(); Chris@1292: } Chris@1292: