summaryrefslogtreecommitdiffstats
path: root/src/controllers
diff options
context:
space:
mode:
authorJan Holthuis <jan.holthuis@ruhr-uni-bochum.de>2020-11-29 21:30:54 +0100
committerGitHub <noreply@github.com>2020-11-29 21:30:54 +0100
commit754c0b5ec0b1be2aa4da9fdea4e8b8c535c757b0 (patch)
tree135eaa0a3f3844da2b6c855ace8ea7210947bcaa /src/controllers
parent18e88ed65d688708d6cba4bf7faf18aaa0d65eb6 (diff)
parentad6c6d3a922decda6c2d3c81bf52f606ada1d850 (diff)
Merge pull request #3278 from ronso0/midi-export
Improve UX in controller mapping editing workflow
Diffstat (limited to 'src/controllers')
-rw-r--r--src/controllers/dlgprefcontroller.cpp132
-rw-r--r--src/controllers/dlgprefcontroller.h2
2 files changed, 113 insertions, 21 deletions
diff --git a/src/controllers/dlgprefcontroller.cpp b/src/controllers/dlgprefcontroller.cpp
index 84e9e9460b..7146e0b38e 100644
--- a/src/controllers/dlgprefcontroller.cpp
+++ b/src/controllers/dlgprefcontroller.cpp
@@ -10,6 +10,7 @@
#include <QDesktopServices>
#include <QFileDialog>
#include <QFileInfo>
+#include <QInputDialog>
#include <QStandardPaths>
#include <QTableWidget>
#include <QTableWidgetItem>
@@ -23,11 +24,15 @@
#include "preferences/usersettings.h"
#include "util/version.h"
-DlgPrefController::DlgPrefController(QWidget* parent, Controller* controller,
- ControllerManager* controllerManager,
- UserSettingsPointer pConfig)
+const QString kPresetExt(".midi.xml");
+
+DlgPrefController::DlgPrefController(QWidget* parent,
+ Controller* controller,
+ ControllerManager* controllerManager,
+ UserSettingsPointer pConfig)
: DlgPreferencePage(parent),
m_pConfig(pConfig),
+ m_pUserDir(userPresetsPath(pConfig)),
m_pControllerManager(controllerManager),
m_pController(controller),
m_pDlgControllerLearning(NULL),
@@ -491,33 +496,118 @@ void DlgPrefController::savePreset() {
}
if (!m_pPreset->isDirty()) {
- qDebug() << "Preset is not dirty, no need to save it.";
+ qDebug() << "Preset has not been edited, no need to save it.";
return;
}
- QFileInfo fileInfo(m_pPreset->filePath());
- QString fileName = fileInfo.fileName();
-
- // Add " (edited)" to preset name (if it's not already present)
- QString editedSuffix = QStringLiteral(" (") + tr("edited") + QStringLiteral(")");
- if (!m_pPreset->name().endsWith(editedSuffix)) {
- m_pPreset->setName(m_pPreset->name() + editedSuffix);
- qDebug() << "Renamed preset to " << m_pPreset->name();
+ QString oldFilePath = m_pPreset->filePath();
+ QString newFilePath;
+ QFileInfo fileInfo(oldFilePath);
+ QString presetName = m_pPreset->name();
+
+ bool isUserPreset = fileInfo.absoluteDir().absolutePath().append("/") == m_pUserDir;
+ bool saveAsNew = true;
+ if (m_pOverwritePresets.contains(oldFilePath) &&
+ m_pOverwritePresets.value(oldFilePath) == true) {
+ saveAsNew = false;
+ }
+
+ // If this is a user preset, ask whether to overwrite or save with new name.
+ // Optionally, tick checkbox to always overwrite this preset in the current session.
+ if (isUserPreset && saveAsNew) {
+ QString overwriteTitle = tr("Preset already exists.");
+ QString overwriteLabel = tr(
+ "<b>%1</b> already exists in user preset folder.<br>"
+ "Overwrite or save with a new name?");
+ QString overwriteCheckLabel = tr("Always overwrite during this session");
+
+ QMessageBox overwriteMsgBox;
+ overwriteMsgBox.setIcon(QMessageBox::Question);
+ overwriteMsgBox.setWindowTitle(overwriteTitle);
+ overwriteMsgBox.setText(overwriteLabel.arg(presetName));
+ QCheckBox overwriteCheckBox;
+ overwriteCheckBox.setText(overwriteCheckLabel);
+ overwriteCheckBox.blockSignals(true);
+ overwriteCheckBox.setCheckState(Qt::Unchecked);
+ overwriteMsgBox.addButton(&overwriteCheckBox, QMessageBox::ActionRole);
+ QPushButton* pSaveAsNew = overwriteMsgBox.addButton(
+ tr("Save As"), QMessageBox::AcceptRole);
+ QPushButton* pOverwrite = overwriteMsgBox.addButton(
+ tr("Overwrite"), QMessageBox::AcceptRole);
+ overwriteMsgBox.setDefaultButton(pSaveAsNew);
+ overwriteMsgBox.exec();
+
+ if (overwriteMsgBox.clickedButton() == pOverwrite) {
+ saveAsNew = false;
+ if (overwriteCheckBox.checkState() == Qt::Checked) {
+ m_pOverwritePresets.insert(m_pPreset->filePath(), true);
+ }
+ } else if (overwriteMsgBox.close()) {
+ return;
+ }
+ }
- // Add " (edited)" to file name (if it's not already present)
- QString baseName = fileInfo.baseName();
- if (baseName.endsWith(editedSuffix)) {
- baseName.chop(editedSuffix.size());
+ // Ask for a preset name when
+ // * initially saving a modified Mixxx preset to the user folder
+ // * saving a user preset with a new name.
+ // The name will be used as display name and file name.
+ if (!saveAsNew) {
+ newFilePath = oldFilePath;
+ } else {
+ QString savePresetTitle = tr("Save user preset");
+ QString savePresetLabel = tr("Enter the name for saving the preset to the user folder.");
+ QString savingFailedTitle = tr("Saving preset failed");
+ QString invalidNameLabel =
+ tr("A preset cannot have a blank name and may not contain "
+ "special characters.");
+ QString fileExistsLabel = tr("A preset file with that name already exists.");
+ // Only allow the name to contain letters, numbers, whitespaces and _-+()/
+ const QRegExp rxRemove = QRegExp("[^[(a-zA-Z0-9\\_\\-\\+\\(\\)\\/|\\s]");
+
+ // Choose a new file (base) name
+ bool validPresetName = false;
+ while (!validPresetName) {
+ QString userDir = m_pUserDir;
+ bool ok = false;
+ presetName = QInputDialog::getText(nullptr,
+ savePresetTitle,
+ savePresetLabel,
+ QLineEdit::Normal,
+ presetName,
+ &ok)
+ .remove(rxRemove)
+ .trimmed();
+ if (!ok) {
+ return;
+ }
+ if (presetName.isEmpty()) {
+ QMessageBox::warning(nullptr,
+ savingFailedTitle,
+ invalidNameLabel);
+ continue;
+ }
+ // While / is allowed for the display name we can't use it for the file name.
+ QString fileName = presetName.replace(QString("/"), QString("-"));
+ newFilePath = userDir + fileName + kPresetExt;
+ if (QFile::exists(newFilePath)) {
+ QMessageBox::warning(nullptr,
+ savingFailedTitle,
+ fileExistsLabel);
+ continue;
+ }
+ validPresetName = true;
}
- fileName = baseName + editedSuffix + QStringLiteral(".") + fileInfo.completeSuffix();
+ m_pPreset->setName(presetName);
+ qDebug() << "Preset renamed to" << m_pPreset->name();
}
- QString filePath = QDir(userPresetsPath(m_pConfig)).absoluteFilePath(fileName);
- if (!m_pPreset->savePreset(filePath)) {
- qDebug() << "Failed to save preset!";
+ if (!m_pPreset->savePreset(newFilePath)) {
+ qDebug() << "Failed to save preset as" << newFilePath;
+ return;
}
+ qDebug() << "Preset saved as" << newFilePath;
- m_pPreset->setFilePath(filePath);
+ m_pPreset->setFilePath(newFilePath);
m_pPreset->setDirty(false);
enumeratePresets(m_pPreset->filePath());
diff --git a/src/controllers/dlgprefcontroller.h b/src/controllers/dlgprefcontroller.h
index 845494d43c..2e1e9d112e 100644
--- a/src/controllers/dlgprefcontroller.h
+++ b/src/controllers/dlgprefcontroller.h
@@ -110,10 +110,12 @@ class DlgPrefController : public DlgPreferencePage {
Ui::DlgPrefControllerDlg m_ui;
UserSettingsPointer m_pConfig;
+ const QString m_pUserDir;
ControllerManager* m_pControllerManager;
Controller* m_pController;
DlgControllerLearning* m_pDlgControllerLearning;
ControllerPresetPointer m_pPreset;
+ QMap<QString, bool> m_pOverwritePresets;
ControllerInputMappingTableModel* m_pInputTableModel;
QSortFilterProxyModel* m_pInputProxyModel;
ControllerOutputMappingTableModel* m_pOutputTableModel;