Skip to content

Commit

Permalink
add dialogs for saving controller presets
Browse files Browse the repository at this point in the history
  • Loading branch information
ronso0 committed Nov 20, 2020
1 parent f99d07b commit 1f7dbcb
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 18 deletions.
144 changes: 126 additions & 18 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,30 +496,133 @@ 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();
QString filePath = m_pPreset->filePath();
QFileInfo fileInfo(filePath);
QString baseName = fileInfo.baseName();
QString displayName = m_pPreset->name();
// Only allow alphanumerical characters and _-+() in file and display name
const QRegExp rx = QRegExp("[^[(a-zA-Z0-9\\_\\-\\+\\(\\)|\\s]");

bool isUserPreset = fileInfo.absoluteDir().absolutePath().append("/") == m_pUserDir;
bool saveAsNew = true;

if (m_pOverwritePresets.contains(m_pPreset->filePath()) &&
m_pOverwritePresets.value(m_pPreset->filePath()) == 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 current session.
if (isUserPreset && saveAsNew) {
QMessageBox overwriteDialog;
overwriteDialog.setIcon(QMessageBox::Question);
overwriteDialog.setWindowTitle(tr("Preset already exists."));
overwriteDialog.setText(tr(
"<b>%1</b> already exists in user preset folder.<br>"
"Overwrite or save with a new name?")
.arg(baseName));
QCheckBox alwaysOverwrite;
alwaysOverwrite.setText(QObject::tr("Always overwrite during this Mixxx session"));
alwaysOverwrite.blockSignals(true);
alwaysOverwrite.setCheckState(Qt::Unchecked);
overwriteDialog.addButton(&alwaysOverwrite, QMessageBox::ActionRole);
QPushButton* pSaveAsNew = overwriteDialog.addButton(
tr("Save As"), QMessageBox::AcceptRole);
QPushButton* pOverwrite = overwriteDialog.addButton(
tr("Overwrite"), QMessageBox::AcceptRole);
overwriteDialog.setDefaultButton(pSaveAsNew);
overwriteDialog.exec();

if (overwriteDialog.clickedButton() == pOverwrite) {
saveAsNew = false;
if (alwaysOverwrite.checkState() == Qt::Checked) {
m_pOverwritePresets.insert(m_pPreset->filePath(), true);
}
} else if (overwriteDialog.close()) {
return;
}
}

// 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();
// Initially save a modified Mixxx preset to the user folder or save a user mapping
// with a new name.
if (saveAsNew) {
QString savePresetTitle = QObject::tr("Save user preset");
QString fileNameLabel = QObject::tr("Enter the file name for the preset:");
QString displayNameLabel = QObject::tr("Enter the display name for the preset:");

QString savingFailedTitle = QObject::tr("Saving preset failed");
QString renamingFailedTitle = QObject::tr("Renaming Preset Failed");
QString fileExistsLabel = QObject::tr("A preset with that name already exists.");
QString savingFailedLabel = QObject::tr(
"A preset cannot have a blank name and may not contain special characters.");

bool validBaseName = false;
bool validDisplayName = false;

// Choose a new file (base) name
while (!validBaseName) {
QString userDir = m_pUserDir;
bool ok = false;
baseName = QInputDialog::getText(nullptr,
savePresetTitle,
fileNameLabel,
QLineEdit::Normal,
baseName,
&ok)
.trimmed()
.remove(rx);
if (!ok) {
return;
}
if (baseName.isEmpty()) {
QMessageBox::warning(nullptr,
savingFailedTitle,
savingFailedLabel);
continue;
}
filePath = userDir + baseName + kPresetExt;
if (QFile::exists(filePath)) {
QMessageBox::warning(nullptr,
savingFailedTitle,
fileExistsLabel);
continue;
}
validBaseName = true;
}

// Add " (edited)" to file name (if it's not already present)
QString baseName = fileInfo.baseName();
if (baseName.endsWith(editedSuffix)) {
baseName.chop(editedSuffix.size());
// Choose a new name for the preset selector and the preset description
while (!validDisplayName) {
bool ok = false;
displayName = QInputDialog::getText(nullptr,
savePresetTitle,
displayNameLabel,
QLineEdit::Normal,
displayName,
&ok)
.trimmed()
.remove(rx);
if (!ok) {
return;
}
if (displayName.isEmpty()) {
QMessageBox::warning(nullptr,
renamingFailedTitle,
savingFailedLabel);
continue;
}
validDisplayName = true;
}
fileName = baseName + editedSuffix + QStringLiteral(".") + fileInfo.completeSuffix();
m_pPreset->setName(displayName);
qDebug() << "Renamed preset to " << m_pPreset->name();
}
QString filePath = QDir(userPresetsPath(m_pConfig)).absoluteFilePath(fileName);

if (!m_pPreset->savePreset(filePath)) {
qDebug() << "Failed to save preset!";
qDebug() << " Failed to save preset!";
return;
}

m_pPreset->setFilePath(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 1f7dbcb

Please sign in to comment.