diff --git a/src/controllers/controllerinputmappingtablemodel.cpp b/src/controllers/controllerinputmappingtablemodel.cpp index 0fd42de58f9..8e82168b455 100644 --- a/src/controllers/controllerinputmappingtablemodel.cpp +++ b/src/controllers/controllerinputmappingtablemodel.cpp @@ -9,8 +9,9 @@ #include "controllers/midi/midiutils.h" #include "moc_controllerinputmappingtablemodel.cpp" -ControllerInputMappingTableModel::ControllerInputMappingTableModel(QObject* pParent) - : ControllerMappingTableModel(pParent) { +ControllerInputMappingTableModel::ControllerInputMappingTableModel(QObject* pParent, + ControlPickerMenu* pControlPickerMenu) + : ControllerMappingTableModel(pParent, pControlPickerMenu) { } ControllerInputMappingTableModel::~ControllerInputMappingTableModel() { @@ -143,7 +144,7 @@ QAbstractItemDelegate* ControllerInputMappingTableModel::delegateForColumn( case MIDI_COLUMN_OPTIONS: return new MidiOptionsDelegate(pParent); case MIDI_COLUMN_ACTION: - pControlDelegate = new ControlDelegate(this); + pControlDelegate = new ControlDelegate(this, m_pControlPickerMenu); pControlDelegate->setMidiOptionsColumn(MIDI_COLUMN_OPTIONS); return pControlDelegate; } diff --git a/src/controllers/controllerinputmappingtablemodel.h b/src/controllers/controllerinputmappingtablemodel.h index 40d51d08c63..a4b443206f4 100644 --- a/src/controllers/controllerinputmappingtablemodel.h +++ b/src/controllers/controllerinputmappingtablemodel.h @@ -14,7 +14,7 @@ class ControllerInputMappingTableModel : public ControllerMappingTableModel { Q_OBJECT public: - ControllerInputMappingTableModel(QObject* pParent); + ControllerInputMappingTableModel(QObject* pParent, ControlPickerMenu* pControlPickerMenu); ~ControllerInputMappingTableModel() override; // Apply the changes to the loaded preset. diff --git a/src/controllers/controllermappingtablemodel.cpp b/src/controllers/controllermappingtablemodel.cpp index 75bb15da655..e4e7b92a6ce 100644 --- a/src/controllers/controllermappingtablemodel.cpp +++ b/src/controllers/controllermappingtablemodel.cpp @@ -2,8 +2,10 @@ #include "moc_controllermappingtablemodel.cpp" -ControllerMappingTableModel::ControllerMappingTableModel(QObject* pParent) +ControllerMappingTableModel::ControllerMappingTableModel(QObject* pParent, + ControlPickerMenu* pControlPickerMenu) : QAbstractTableModel(pParent), + m_pControlPickerMenu(pControlPickerMenu), m_pMidiPreset(nullptr), m_pHidPreset(nullptr) { } diff --git a/src/controllers/controllermappingtablemodel.h b/src/controllers/controllermappingtablemodel.h index d6de46532c7..cd4498965db 100644 --- a/src/controllers/controllermappingtablemodel.h +++ b/src/controllers/controllermappingtablemodel.h @@ -9,6 +9,7 @@ #include "controllers/controllerpreset.h" #include "controllers/controllerpresetvisitor.h" +#include "controllers/controlpickermenu.h" #include "controllers/midi/midicontrollerpreset.h" #include "controllers/hid/hidcontrollerpreset.h" @@ -16,7 +17,7 @@ class ControllerMappingTableModel : public QAbstractTableModel, public ControllerPresetVisitor { Q_OBJECT public: - ControllerMappingTableModel(QObject* pParent); + ControllerMappingTableModel(QObject* pParent, ControlPickerMenu* pControlPickerMenu); ~ControllerMappingTableModel() override; void setPreset(ControllerPresetPointer pPreset); @@ -42,6 +43,7 @@ class ControllerMappingTableModel : public QAbstractTableModel, virtual void onPresetLoaded() = 0; QVector > m_headerInfo; + ControlPickerMenu* m_pControlPickerMenu; ControllerPresetPointer m_pPreset; MidiControllerPreset* m_pMidiPreset; HidControllerPreset* m_pHidPreset; diff --git a/src/controllers/controlleroutputmappingtablemodel.cpp b/src/controllers/controlleroutputmappingtablemodel.cpp index 70284d70fcc..7d8a6632437 100644 --- a/src/controllers/controlleroutputmappingtablemodel.cpp +++ b/src/controllers/controlleroutputmappingtablemodel.cpp @@ -8,8 +8,9 @@ #include "controllers/midi/midiutils.h" #include "moc_controlleroutputmappingtablemodel.cpp" -ControllerOutputMappingTableModel::ControllerOutputMappingTableModel(QObject* pParent) - : ControllerMappingTableModel(pParent) { +ControllerOutputMappingTableModel::ControllerOutputMappingTableModel(QObject* pParent, + ControlPickerMenu* pControlPickerMenu) + : ControllerMappingTableModel(pParent, pControlPickerMenu) { } ControllerOutputMappingTableModel::~ControllerOutputMappingTableModel() { @@ -112,7 +113,7 @@ QAbstractItemDelegate* ControllerOutputMappingTableModel::delegateForColumn( case MIDI_COLUMN_OFF: return new MidiByteDelegate(pParent); case MIDI_COLUMN_ACTION: - return new ControlDelegate(this); + return new ControlDelegate(this, m_pControlPickerMenu); } } return nullptr; diff --git a/src/controllers/controlleroutputmappingtablemodel.h b/src/controllers/controlleroutputmappingtablemodel.h index 36be40f69a6..2ede677abf0 100644 --- a/src/controllers/controlleroutputmappingtablemodel.h +++ b/src/controllers/controlleroutputmappingtablemodel.h @@ -14,7 +14,7 @@ class ControllerOutputMappingTableModel : public ControllerMappingTableModel { Q_OBJECT public: - ControllerOutputMappingTableModel(QObject* pParent); + ControllerOutputMappingTableModel(QObject* pParent, ControlPickerMenu* pControlPickerMenu); ~ControllerOutputMappingTableModel() override; // Apply the changes to the loaded preset. diff --git a/src/controllers/controlpickermenu.cpp b/src/controllers/controlpickermenu.cpp index f10b44b4aca..84b331b64df 100644 --- a/src/controllers/controlpickermenu.cpp +++ b/src/controllers/controlpickermenu.cpp @@ -27,6 +27,19 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) m_parameterStr = tr("Parameter %1"); m_libraryStr = tr("Library"); + m_numGroupsTrMap.insert("Channel", m_deckStr); + m_numGroupsTrMap.insert("Sampler", m_samplerStr); + m_numGroupsTrMap.insert("PreviewDeck", m_previewdeckStr); + m_numGroupsTrMap.insert("Microphone", m_microphoneStr); + m_numGroupsTrMap.insert("Auxiliary", m_auxStr); + m_numGroupsTrMap.insert("EffectRack", m_effectRackStr); + + m_otherGroupsTrMap.insert("Skin", tr("Skin")); + m_otherGroupsTrMap.insert("Library", m_libraryStr); + m_otherGroupsTrMap.insert("Controller", tr("Controller")); + // TODO(ronso0) "translate" legacy 'Master' to 'Main' in main branch? + m_otherGroupsTrMap.insert("Master", "Master"); + // Mixer Controls QMenu* mixerMenu = addSubmenu(tr("Mixer")); // Crossfader / Orientation @@ -582,102 +595,66 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) addSeparator(); // Library Controls - QMenu* libraryMenu = addSubmenu(tr("Library")); + QMenu* libraryMenu = addSubmenu(m_libraryStr); QMenu* navigationMenu = addSubmenu(tr("Navigation"), libraryMenu); - addControl("[Library]", - "MoveUp", + addLibraryControl("MoveUp", tr("Move up"), tr("Equivalent to pressing the UP key on the keyboard"), - navigationMenu, - false, - m_libraryStr); - addControl("[Library]", - "MoveDown", + navigationMenu); + addLibraryControl("MoveDown", tr("Move down"), tr("Equivalent to pressing the DOWN key on the keyboard"), - navigationMenu, - false, - m_libraryStr); - addControl("[Library]", - "MoveVertical", + navigationMenu); + addLibraryControl("MoveVertical", tr("Move up/down"), tr("Move vertically in either direction using a knob, as if " "pressing UP/DOWN keys"), - navigationMenu, - false, - m_libraryStr); - addControl("[Library]", - "ScrollUp", + navigationMenu); + addLibraryControl("ScrollUp", tr("Scroll Up"), tr("Equivalent to pressing the PAGE UP key on the keyboard"), - navigationMenu, - false, - m_libraryStr); - addControl("[Library]", - "ScrollDown", + navigationMenu); + addLibraryControl("ScrollDown", tr("Scroll Down"), tr("Equivalent to pressing the PAGE DOWN key on the keyboard"), - navigationMenu, - false, - m_libraryStr); - addControl("[Library]", - "ScrollVertical", + navigationMenu); + addLibraryControl("ScrollVertical", tr("Scroll up/down"), tr("Scroll vertically in either direction using a knob, as if " "pressing PGUP/PGDOWN keys"), - navigationMenu, - false, - m_libraryStr); - addControl("[Library]", - "MoveLeft", + navigationMenu); + addLibraryControl("MoveLeft", tr("Move left"), tr("Equivalent to pressing the LEFT key on the keyboard"), - navigationMenu, - false, - m_libraryStr); - addControl("[Library]", - "MoveRight", + navigationMenu); + addLibraryControl("MoveRight", tr("Move right"), tr("Equivalent to pressing the RIGHT key on the keyboard"), - navigationMenu, - false, - m_libraryStr); - addControl("[Library]", - "MoveHorizontal", + navigationMenu); + addLibraryControl("MoveHorizontal", tr("Move left/right"), tr("Move horizontally in either direction using a knob, as if " "pressing LEFT/RIGHT keys"), - navigationMenu, - false, - m_libraryStr); + navigationMenu); navigationMenu->addSeparator(); - addControl("[Library]", - "MoveFocusForward", + addLibraryControl("MoveFocusForward", tr("Move focus to right pane"), tr("Equivalent to pressing the TAB key on the keyboard"), - navigationMenu, - false, - m_libraryStr); - addControl("[Library]", - "MoveFocusBackward", + navigationMenu); + addLibraryControl("MoveFocusBackward", tr("Move focus to left pane"), tr("Equivalent to pressing the SHIFT+TAB key on the keyboard"), - navigationMenu, - false, - m_libraryStr); - addControl("[Library]", - "MoveFocus", + navigationMenu); + addLibraryControl("MoveFocus", tr("Move focus to right/left pane"), tr("Move focus one pane to right or left using a knob, as if " "pressing TAB/SHIFT+TAB keys"), - navigationMenu, - false, - m_libraryStr); + navigationMenu); libraryMenu->addSeparator(); - addControl("[Library]", "GoToItem", + addLibraryControl("GoToItem", tr("Go to the currently selected item"), tr("Choose the currently selected item and advance forward one pane if appropriate"), - libraryMenu, false, m_libraryStr); + libraryMenu); // Load track (these can be loaded into any channel) addDeckAndSamplerControl("LoadSelectedTrack", tr("Load Track"), @@ -689,18 +666,18 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) libraryMenu); libraryMenu->addSeparator(); // Auto DJ - addControl("[Library]", "AutoDjAddBottom", + addLibraryControl("AutoDjAddBottom", tr("Add to Auto DJ Queue (bottom)"), tr("Append the selected track to the Auto DJ Queue"), - libraryMenu, false, m_libraryStr); - addControl("[Library]", "AutoDjAddTop", + libraryMenu); + addLibraryControl("AutoDjAddTop", tr("Add to Auto DJ Queue (top)"), tr("Prepend selected track to the Auto DJ Queue"), - libraryMenu, false, m_libraryStr); - addControl("[Library]", "AutoDjAddReplace", + libraryMenu); + addLibraryControl("AutoDjAddReplace", tr("Add to Auto DJ Queue (replace)"), tr("Replace Auto DJ Queue with selected tracks"), - libraryMenu, false, m_libraryStr); + libraryMenu); libraryMenu->addSeparator(); addControl("[Recording]", "toggle_recording", tr("Record Mix"), @@ -1418,6 +1395,13 @@ void ControlPickerMenu::addPreviewDeckControl(const QString& control, addPlayerControl(control, title, controlDescription, pMenu, false, false, true, addReset); } +void ControlPickerMenu::addLibraryControl(const QString& control, + const QString& title, + const QString& description, + QMenu* pMenu) { + addSingleControl("[Library]", control, title, description, pMenu, m_libraryStr); +} + QMenu* ControlPickerMenu::addSubmenu(QString title, QMenu* pParent) { if (pParent == nullptr) { pParent = this; diff --git a/src/controllers/controlpickermenu.h b/src/controllers/controlpickermenu.h index 62b9430388b..30e945ff774 100644 --- a/src/controllers/controlpickermenu.h +++ b/src/controllers/controlpickermenu.h @@ -19,6 +19,14 @@ class ControlPickerMenu : public QMenu { QString descriptionForConfigKey(const ConfigKey& key) const; QString controlTitleForConfigKey(const ConfigKey& key) const; + // share translated group strings + QMap getNumGroupsTrMap() const { + return m_numGroupsTrMap; + } + QMap getOtherGroupsTrMap() const { + return m_otherGroupsTrMap; + } + signals: // Emitted when the user selects a control from the menu. void controlPicked(const ConfigKey& control); @@ -88,6 +96,10 @@ class ControlPickerMenu : public QMenu { bool microphoneControls, bool auxControls, bool addReset = false); + void addLibraryControl(const QString& control, + const QString& title, + const QString& helpText, + QMenu* pMenu); int addAvailableControl(const ConfigKey& key, const QString& title, const QString& description); @@ -108,4 +120,7 @@ class ControlPickerMenu : public QMenu { QList m_controlsAvailable; QHash m_descriptionsByKey; QHash m_titlesByKey; + + QMap m_numGroupsTrMap; + QMap m_otherGroupsTrMap; }; diff --git a/src/controllers/delegates/controldelegate.cpp b/src/controllers/delegates/controldelegate.cpp index 16e09daf5f4..6c8880e7955 100644 --- a/src/controllers/delegates/controldelegate.cpp +++ b/src/controllers/delegates/controldelegate.cpp @@ -1,17 +1,20 @@ #include "controllers/delegates/controldelegate.h" #include +#include #include #include #include "controllers/midi/midimessage.h" #include "moc_controldelegate.cpp" -ControlDelegate::ControlDelegate(QObject* pParent) +ControlDelegate::ControlDelegate(QObject* pParent, ControlPickerMenu* pControlPickerMenu) : QStyledItemDelegate(pParent), - m_pPicker(new ControlPickerMenu(nullptr)), + m_pPicker(pControlPickerMenu), m_iMidiOptionsColumn(-1), m_bIsIndexScript(false) { + m_numGroupsTrMap = m_pPicker->getNumGroupsTrMap(); + m_otherGroupsTrMap = m_pPicker->getOtherGroupsTrMap(); } ControlDelegate::~ControlDelegate() { @@ -49,15 +52,15 @@ QString ControlDelegate::displayText(const QVariant& value, return tr("No control chosen."); } - if (m_bIsIndexScript) { - return tr("%1 %2").arg(key.group, key.item); - } - QString description = m_pPicker->descriptionForConfigKey(key); if (!description.isEmpty()) { return description; } + if (m_bIsIndexScript || description.isEmpty()) { + return QString("%1: %2").arg(translateConfigKeyGroup(key.group), key.item); + } + return key.group + "," + key.item; } @@ -91,3 +94,38 @@ void ControlDelegate::setModelData(QWidget* editor, ConfigKey(keyStrs.at(0), keyStrs.at(1))), Qt::EditRole); } } + +// return more readable group names like "Deck 1", "Sampler 1" etc. +QString ControlDelegate::translateConfigKeyGroup(const QString& group) const { + QMapIterator numIt(m_numGroupsTrMap); + while (numIt.hasNext()) { + numIt.next(); + QString regExpStr = QString("\\[%1([1-9]\\d*|)\\]").arg(numIt.key()); + QRegExp numGroupMatcher(regExpStr); + if (numGroupMatcher.exactMatch(group)) { + // special case for legacy group [Microphone] > "Microphone 1" + if (numIt.key() == "Microphone" && numGroupMatcher.cap(1).isEmpty()) { + return QString("%1 1").arg(numIt.value()); + } + bool ok = false; + int num = numGroupMatcher.cap(1).toInt(&ok); + if (ok) { + return numIt.value().arg(QString::number(num)); + } + return group; + } + } + + QMapIterator oIt(m_otherGroupsTrMap); + while (oIt.hasNext()) { + oIt.next(); + QString regExpStr = QString("\\[%1\\]").arg(oIt.key()); + QRegExp otherGroupMatcher(regExpStr); + if (otherGroupMatcher.exactMatch(group)) { + return oIt.value(); + } + } + + // no match (custom group maybe), return raw [Group] + return group; +} diff --git a/src/controllers/delegates/controldelegate.h b/src/controllers/delegates/controldelegate.h index 3ca6954b1c0..450e406087e 100644 --- a/src/controllers/delegates/controldelegate.h +++ b/src/controllers/delegates/controldelegate.h @@ -7,7 +7,7 @@ class ControlDelegate : public QStyledItemDelegate { Q_OBJECT public: - ControlDelegate(QObject* pParent); + ControlDelegate(QObject* pParent, ControlPickerMenu* pControlPickerMenu); virtual ~ControlDelegate(); inline void setMidiOptionsColumn(int column) { @@ -27,6 +27,8 @@ class ControlDelegate : public QStyledItemDelegate { void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; + QString translateConfigKeyGroup(const QString& group) const; + private: ControlPickerMenu* m_pPicker; int m_iMidiOptionsColumn; @@ -34,4 +36,6 @@ class ControlDelegate : public QStyledItemDelegate { // MidiOption. displayText does not give us the current QModelIndex so we // can't check there. mutable bool m_bIsIndexScript; + QMap m_numGroupsTrMap; + QMap m_otherGroupsTrMap; }; diff --git a/src/controllers/dlgcontrollerlearning.cpp b/src/controllers/dlgcontrollerlearning.cpp index 65fa50fd87a..c6d949d0984 100644 --- a/src/controllers/dlgcontrollerlearning.cpp +++ b/src/controllers/dlgcontrollerlearning.cpp @@ -16,11 +16,12 @@ bool namedControlComparator(const NamedControl& l1, const NamedControl& l2) { } // namespace DlgControllerLearning::DlgControllerLearning(QWidget* parent, - Controller* controller) + Controller* controller, + ControlPickerMenu* pControlPickerMenu) : QDialog(parent), m_pController(controller), m_pMidiController(nullptr), - m_controlPickerMenu(this), + m_pControlPickerMenu(pControlPickerMenu), m_messagesLearned(false) { qRegisterMetaType("MidiInputMappings"); @@ -65,7 +66,7 @@ DlgControllerLearning::DlgControllerLearning(QWidget* parent, setAttribute(Qt::WA_DeleteOnClose); setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); - connect(&m_controlPickerMenu, + connect(m_pControlPickerMenu, &ControlPickerMenu::controlPicked, this, &DlgControllerLearning::controlPicked); @@ -150,11 +151,10 @@ void DlgControllerLearning::populateComboBox() { comboBoxChosenControl->clear(); comboBoxChosenControl->addItem("", QVariant::fromValue(ConfigKey())); QList sorted_controls; - foreach(ConfigKey key, m_controlPickerMenu.controlsAvailable()) - { + foreach (ConfigKey key, m_pControlPickerMenu->controlsAvailable()) { sorted_controls.push_back( - NamedControl(m_controlPickerMenu.controlTitleForConfigKey(key), - key)); + NamedControl(m_pControlPickerMenu->controlTitleForConfigKey(key), + key)); } std::sort(sorted_controls.begin(), sorted_controls.end(), namedControlComparator); @@ -457,7 +457,7 @@ DlgControllerLearning::~DlgControllerLearning() { } void DlgControllerLearning::showControlMenu() { - m_controlPickerMenu.exec(pushButtonChooseControl->mapToGlobal(QPoint(0,0))); + m_pControlPickerMenu->exec(pushButtonChooseControl->mapToGlobal(QPoint(0, 0))); } void DlgControllerLearning::loadControl(const ConfigKey& key, @@ -488,8 +488,8 @@ void DlgControllerLearning::loadControl(const ConfigKey& key, } void DlgControllerLearning::controlPicked(const ConfigKey& control) { - QString title = m_controlPickerMenu.controlTitleForConfigKey(control); - QString description = m_controlPickerMenu.descriptionForConfigKey(control); + QString title = m_pControlPickerMenu->controlTitleForConfigKey(control); + QString description = m_pControlPickerMenu->descriptionForConfigKey(control); loadControl(control, title, description); } @@ -499,7 +499,7 @@ void DlgControllerLearning::controlClicked(ControlObject* pControl) { } ConfigKey key = pControl->getKey(); - if (!m_controlPickerMenu.controlExists(key)) { + if (!m_pControlPickerMenu->controlExists(key)) { qWarning() << "Mixxx UI element clicked for which there is no " "learnable control " << key.group << " " << key.item; QMessageBox::warning( diff --git a/src/controllers/dlgcontrollerlearning.h b/src/controllers/dlgcontrollerlearning.h index 1323de677bc..e2d659f1ef7 100644 --- a/src/controllers/dlgcontrollerlearning.h +++ b/src/controllers/dlgcontrollerlearning.h @@ -28,7 +28,9 @@ class DlgControllerLearning : public QDialog, Q_OBJECT public: - DlgControllerLearning(QWidget *parent, Controller *controller); + DlgControllerLearning(QWidget* parent, + Controller* controller, + ControlPickerMenu* pControlPickerMenu); virtual ~DlgControllerLearning(); void visit(MidiController* pController); @@ -84,7 +86,7 @@ class DlgControllerLearning : public QDialog, Controller* m_pController; MidiController* m_pMidiController; - ControlPickerMenu m_controlPickerMenu; + ControlPickerMenu* m_pControlPickerMenu; ConfigKey m_currentControl; bool m_messagesLearned; QTimer m_firstMessageTimer; diff --git a/src/controllers/dlgprefcontroller.cpp b/src/controllers/dlgprefcontroller.cpp index 1561a929859..1889da7f8aa 100644 --- a/src/controllers/dlgprefcontroller.cpp +++ b/src/controllers/dlgprefcontroller.cpp @@ -50,6 +50,8 @@ DlgPrefController::DlgPrefController(QWidget* parent, // Create text color for the file and wiki links createLinkColor(); + m_pControlPickerMenu = new ControlPickerMenu(this); + initTableView(m_ui.m_pInputMappingTableView); initTableView(m_ui.m_pOutputMappingTableView); @@ -153,7 +155,8 @@ void DlgPrefController::showLearningWizard() { // Note that DlgControllerLearning is set to delete itself on close using // the Qt::WA_DeleteOnClose attribute (so this "new" doesn't leak memory) - m_pDlgControllerLearning = new DlgControllerLearning(this, m_pController); + m_pDlgControllerLearning = + new DlgControllerLearning(this, m_pController, m_pControlPickerMenu); m_pDlgControllerLearning->show(); ControllerLearningEventFilter* pControllerLearning = m_pControllerManager->getControllerLearningEventFilter(); @@ -758,7 +761,7 @@ void DlgPrefController::slotShowPreset(ControllerPresetPointer preset) { m_pPreset = preset; ControllerInputMappingTableModel* pInputModel = - new ControllerInputMappingTableModel(this); + new ControllerInputMappingTableModel(this, m_pControlPickerMenu); pInputModel->setPreset(preset); QSortFilterProxyModel* pInputProxyModel = new QSortFilterProxyModel(this); @@ -782,7 +785,7 @@ void DlgPrefController::slotShowPreset(ControllerPresetPointer preset) { m_pInputTableModel = pInputModel; ControllerOutputMappingTableModel* pOutputModel = - new ControllerOutputMappingTableModel(this); + new ControllerOutputMappingTableModel(this, m_pControlPickerMenu); pOutputModel->setPreset(preset); QSortFilterProxyModel* pOutputProxyModel = new QSortFilterProxyModel(this); diff --git a/src/controllers/dlgprefcontroller.h b/src/controllers/dlgprefcontroller.h index fb0764877b3..8062f2c6cee 100644 --- a/src/controllers/dlgprefcontroller.h +++ b/src/controllers/dlgprefcontroller.h @@ -110,6 +110,7 @@ class DlgPrefController : public DlgPreferencePage { const QString m_pUserDir; ControllerManager* m_pControllerManager; Controller* m_pController; + ControlPickerMenu* m_pControlPickerMenu; DlgControllerLearning* m_pDlgControllerLearning; ControllerPresetPointer m_pPreset; QMap m_pOverwritePresets;