Skip to content

Commit

Permalink
DlgPrefController: add dialog for saving controller presets
Browse files Browse the repository at this point in the history
  • Loading branch information
ronso0 committed Nov 25, 2020
1 parent f99d07b commit ad6c6d3
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 21 deletions.
132 changes: 111 additions & 21 deletions src/controllers/dlgprefcontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <QDesktopServices>
#include <QFileDialog>
#include <QFileInfo>
#include <QInputDialog>
#include <QStandardPaths>
#include <QTableWidget>
#include <QTableWidgetItem>
Expand All @@ -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),
Expand Down Expand Up @@ -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());
Expand Down
2 changes: 2 additions & 0 deletions src/controllers/dlgprefcontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit ad6c6d3

Please sign in to comment.