diff --git a/src/controllers/controllermanager.cpp b/src/controllers/controllermanager.cpp index ec74976f7f5d..3d54baf3a0b2 100644 --- a/src/controllers/controllermanager.cpp +++ b/src/controllers/controllermanager.cpp @@ -39,6 +39,12 @@ const int kPollIntervalMillis = 5; const int kPollIntervalMillis = 1; #endif +// Strip slashes and spaces from device name, so that it can be used as config +// key or a filename. +QString sanitizeDeviceName(QString name) { + return name.replace(" ", "_").replace("/", "_").replace("\\", "_"); +} + } // anonymous namespace QString firstAvailableFilename(QSet& filenames, @@ -119,11 +125,10 @@ void ControllerManager::slotInitialize() { // Initialize preset info parsers. This object is only for use in the main // thread. Do not touch it from within ControllerManager. - QStringList presetSearchPaths; - presetSearchPaths << userPresetsPath(m_pConfig) - << resourcePresetsPath(m_pConfig); - m_pMainThreadPresetEnumerator = QSharedPointer( - new PresetInfoEnumerator(presetSearchPaths)); + m_pMainThreadUserPresetEnumerator = QSharedPointer( + new PresetInfoEnumerator(QStringList{userPresetsPath(m_pConfig)})); + m_pMainThreadSystemPresetEnumerator = QSharedPointer( + new PresetInfoEnumerator(QStringList{resourcePresetsPath(m_pConfig)})); // Instantiate all enumerators. Enumerators can take a long time to // construct since they interact with host MIDI APIs. @@ -205,6 +210,10 @@ QList ControllerManager::getControllerList(bool bOutputDevices, boo return filteredDeviceList; } +QString ControllerManager::getConfiguredPresetFileForDevice(QString name) { + return m_pConfig->getValueString(ConfigKey("[ControllerPreset]", sanitizeDeviceName(name))); +} + void ControllerManager::slotSetUpDevices() { qDebug() << "ControllerManager: Setting up devices"; @@ -221,27 +230,25 @@ void ControllerManager::slotSetUpDevices() { } // The filename for this device name. - QString presetBaseName = presetFilenameFromName(name); + QString deviceName = sanitizeDeviceName(name); + if (m_pConfig->getValueString(ConfigKey("[Controller]", deviceName)) != "1") { + continue; + } - // The first unique filename for this device (appends numbers at the end - // if we have already seen a controller by this name on this run of - // Mixxx. - presetBaseName = firstAvailableFilename(filenames, presetBaseName); + QString presetFile = getConfiguredPresetFileForDevice(deviceName); + if (presetFile.isEmpty()) { + continue; + } - ControllerPresetPointer pPreset = - ControllerPresetFileHandler::loadPreset( - presetBaseName + pController->presetExtension(), - getPresetPaths(m_pConfig)); + ControllerPresetPointer pPreset = ControllerPresetFileHandler::loadPreset( + presetFile, + getPresetPaths(m_pConfig)); if (!loadPreset(pController, pPreset)) { // TODO(XXX) : auto load midi preset here. continue; } - if (m_pConfig->getValueString(ConfigKey("[Controller]", presetBaseName)) != "1") { - continue; - } - // If we are in safe mode, skip opening controllers. if (CmdlineArgs::Instance().getSafeMode()) { qDebug() << "We are in safe mode -- skipping opening controller."; @@ -350,8 +357,8 @@ void ControllerManager::openController(Controller* pController) { pController->applyPreset(getPresetPaths(m_pConfig), true); // Update configuration to reflect controller is enabled. - m_pConfig->setValue(ConfigKey( - "[Controller]", presetFilenameFromName(pController->getName())), 1); + m_pConfig->setValue( + ConfigKey("[Controller]", sanitizeDeviceName(pController->getName())), 1); } } @@ -362,8 +369,8 @@ void ControllerManager::closeController(Controller* pController) { pController->close(); maybeStartOrStopPolling(); // Update configuration to reflect controller is disabled. - m_pConfig->setValue(ConfigKey( - "[Controller]", presetFilenameFromName(pController->getName())), 0); + m_pConfig->setValue( + ConfigKey("[Controller]", sanitizeDeviceName(pController->getName())), 0); } bool ControllerManager::loadPreset(Controller* pController, @@ -375,9 +382,8 @@ bool ControllerManager::loadPreset(Controller* pController, // Save the file path/name in the config so it can be auto-loaded at // startup next time m_pConfig->set( - ConfigKey("[ControllerPreset]", - presetFilenameFromName(pController->getName())), - preset->filePath()); + ConfigKey("[ControllerPreset]", sanitizeDeviceName(pController->getName())), + preset->filePath()); return true; } @@ -392,15 +398,15 @@ void ControllerManager::slotSavePresets(bool onlyActive) { if (onlyActive && !pController->isOpen()) { continue; } - QString name = pController->getName(); - QString filename = firstAvailableFilename( - filenames, presetFilenameFromName(name)); + QString deviceName = sanitizeDeviceName(pController->getName()); + QString filename = firstAvailableFilename(filenames, deviceName); QString presetPath = userPresetsPath(m_pConfig) + filename + pController->presetExtension(); if (!pController->savePreset(presetPath)) { qWarning() << "Failed to write preset for device" - << name << "to" << presetPath; + << deviceName << "to" << presetPath; } + m_pConfig->set(ConfigKey("[ControllerPreset]", deviceName), presetPath); } } diff --git a/src/controllers/controllermanager.h b/src/controllers/controllermanager.h index 1fa873ba4bc0..dae740ee713c 100644 --- a/src/controllers/controllermanager.h +++ b/src/controllers/controllermanager.h @@ -33,9 +33,13 @@ class ControllerManager : public QObject { QList getControllers() const; QList getControllerList(bool outputDevices=true, bool inputDevices=true); ControllerLearningEventFilter* getControllerLearningEventFilter() const; - QSharedPointer getMainThreadPresetEnumerator() { - return m_pMainThreadPresetEnumerator; + QSharedPointer getMainThreadUserPresetEnumerator() { + return m_pMainThreadUserPresetEnumerator; } + QSharedPointer getMainThreadSystemPresetEnumerator() { + return m_pMainThreadSystemPresetEnumerator; + } + QString getConfiguredPresetFileForDevice(QString name); // Prevent other parts of Mixxx from having to manually connect to our slots void setUpDevices() { emit requestSetUpDevices(); }; @@ -85,10 +89,6 @@ class ControllerManager : public QObject { void stopPolling(); void maybeStartOrStopPolling(); - static QString presetFilenameFromName(QString name) { - return name.replace(" ", "_").replace("/", "_").replace("\\", "_"); - } - private: UserSettingsPointer m_pConfig; ControllerLearningEventFilter* m_pControllerLearningEventFilter; @@ -97,7 +97,8 @@ class ControllerManager : public QObject { QList m_enumerators; QList m_controllers; QThread* m_pThread; - QSharedPointer m_pMainThreadPresetEnumerator; + QSharedPointer m_pMainThreadUserPresetEnumerator; + QSharedPointer m_pMainThreadSystemPresetEnumerator; bool m_skipPoll; }; diff --git a/src/controllers/controllerpresetinfo.cpp b/src/controllers/controllerpresetinfo.cpp index 3e8c1d581f4a..bf0051209af9 100644 --- a/src/controllers/controllerpresetinfo.cpp +++ b/src/controllers/controllerpresetinfo.cpp @@ -10,7 +10,6 @@ */ #include "controllers/controllerpresetinfo.h" -#include "controllers/controllerpresetinfoenumerator.h" #include "controllers/defs_controllers.h" #include "util/xml.h" diff --git a/src/controllers/dlgprefcontroller.cpp b/src/controllers/dlgprefcontroller.cpp index 6217a12f13a4..0e35ebd95a62 100644 --- a/src/controllers/dlgprefcontroller.cpp +++ b/src/controllers/dlgprefcontroller.cpp @@ -239,34 +239,60 @@ void DlgPrefController::enumeratePresets() { // user has their controller plugged in) m_ui.comboBoxPreset->addItem("..."); - // Ask the controller manager for a list of applicable presets - QSharedPointer pie = - m_pControllerManager->getMainThreadPresetEnumerator(); + QList presets; + PresetInfo match; - // Not ready yet. Should be rare. We will re-enumerate on the next open of - // the preferences. - if (pie.isNull()) { - return; + // Ask the controller manager for a list of applicable user presets + QSharedPointer userPresetEnumerator = + m_pControllerManager->getMainThreadUserPresetEnumerator(); + // Check if enumerator is ready. Should be rare. We will re-enumerate on + // the next open of the preferences. + if (!userPresetEnumerator.isNull()) { + // Making the list of presets in the alphabetical order + QList userPresets = userPresetEnumerator->getPresetsByExtension( + m_pController->presetExtension()); + + for (const PresetInfo& preset : userPresets) { + m_ui.comboBoxPreset->addItem(preset.getName(), preset.getPath()); + if (m_pController->matchPreset(preset)) { + match = preset; + } + } } - // Making the list of presets in the alphabetical order - QList presets = pie->getPresetsByExtension( - m_pController->presetExtension()); + // Insert a separator between user presets (+ dummy item) and system presets + m_ui.comboBoxPreset->insertSeparator(m_ui.comboBoxPreset->count()); - PresetInfo match; - for (const PresetInfo& preset : presets) { - m_ui.comboBoxPreset->addItem(preset.getName(), preset.getPath()); - if (m_pController->matchPreset(preset)) { - match = preset; + // Ask the controller manager for a list of applicable system presets + QSharedPointer systemPresetEnumerator = + m_pControllerManager->getMainThreadSystemPresetEnumerator(); + // Check if enumerator is ready. Should be rare. We will re-enumerate on + // the next open of the preferences. + if (!systemPresetEnumerator.isNull()) { + // Making the list of presets in the alphabetical order + QList systemPresets = systemPresetEnumerator->getPresetsByExtension( + m_pController->presetExtension()); + + for (const PresetInfo& preset : systemPresets) { + m_ui.comboBoxPreset->addItem(preset.getName(), preset.getPath()); + if (m_pController->matchPreset(preset)) { + match = preset; + } } } - // Jump to matching device in list if it was found. - if (match.isValid()) { - int index = m_ui.comboBoxPreset->findText(match.getName()); - if (index != -1) { - m_ui.comboBoxPreset->setCurrentIndex(index); - } + QString configuredPresetFile = m_pControllerManager->getConfiguredPresetFileForDevice( + m_pController->getName()); + + // Preselect configured or matching preset + int index = -1; + if (!configuredPresetFile.isEmpty()) { + index = m_ui.comboBoxPreset->findData(configuredPresetFile); + } else if (match.isValid()) { + index = m_ui.comboBoxPreset->findText(match.getName()); + } + if (index != -1) { + m_ui.comboBoxPreset->setCurrentIndex(index); } } @@ -334,9 +360,6 @@ void DlgPrefController::slotApply() { // the same preset. emit loadPreset(m_pController, m_pPreset); - //Select the "..." item again in the combobox. - m_ui.comboBoxPreset->setCurrentIndex(0); - bool wantEnabled = m_ui.chkEnabledDevice->isChecked(); bool enabled = m_pController->isOpen(); if (wantEnabled && !enabled) {