From b4f5c17898317720662fc15a7828b68b2e81d950 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Mon, 7 Oct 2019 07:41:13 -0400 Subject: disallow empty titles --- src/editexecutablesdialog.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'src/editexecutablesdialog.cpp') diff --git a/src/editexecutablesdialog.cpp b/src/editexecutablesdialog.cpp index 0d6367b8..5c4ee149 100644 --- a/src/editexecutablesdialog.cpp +++ b/src/editexecutablesdialog.cpp @@ -222,6 +222,7 @@ void EditExecutablesDialog::updateUI( { // the ui is currently being set, ignore changes m_settingUI = true; + Guard g([&]{ m_settingUI = false; }); if (e) { setEdits(*e); @@ -230,9 +231,6 @@ void EditExecutablesDialog::updateUI( } setButtons(item, e); - - // any changes from now on are from the user - m_settingUI = false; } void EditExecutablesDialog::setButtons( @@ -274,6 +272,8 @@ void EditExecutablesDialog::clearEdits() ui->configureLibraries->setEnabled(false); ui->useApplicationIcon->setEnabled(false); ui->useApplicationIcon->setChecked(false); + + m_lastGoodTitle = ""; } void EditExecutablesDialog::setEdits(const Executable& e) @@ -287,6 +287,8 @@ void EditExecutablesDialog::setEdits(const Executable& e) ui->steamAppID->setText(e.steamAppID()); ui->useApplicationIcon->setChecked(e.usesOwnIcon()); + m_lastGoodTitle = e.title(); + { int modIndex = -1; @@ -559,6 +561,13 @@ void EditExecutablesDialog::on_title_textChanged(const QString& s) return; } + // don't allow empty names + if (s.trimmed().isEmpty()) { + return; + } + + m_lastGoodTitle = s; + // must save before modifying the item in the list widget because saving // relies on the item's text being the same as an item in m_executablesList save(); @@ -570,6 +579,13 @@ void EditExecutablesDialog::on_title_textChanged(const QString& s) } } +void EditExecutablesDialog::on_title_editingFinished() +{ + if (ui->title->text().trimmed().isEmpty()) { + ui->title->setText(m_lastGoodTitle); + } +} + void EditExecutablesDialog::on_overwriteSteamAppID_toggled(bool checked) { if (m_settingUI) { @@ -619,9 +635,8 @@ void EditExecutablesDialog::on_browseBinary_clicked() ui->binary->setText(QDir::toNativeSeparators(binaryName)); } - // setting title if currently empty or some variation of "New Executable" - if (ui->title->text().isEmpty() || - ui->title->text().startsWith(tr("New Executable"), Qt::CaseInsensitive)) { + // setting title if some variation of "New Executable" + if (ui->title->text().startsWith(tr("New Executable"), Qt::CaseInsensitive)) { const auto prefix = QFileInfo(binaryName).baseName(); const auto newTitle = m_executablesList.makeNonConflictingTitle(prefix); -- cgit v1.3.1 From 8bc84a1513325f73252f4a07504ee6d2aad4b2f3 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Tue, 8 Oct 2019 19:08:55 -0400 Subject: remove whitespace from executable names add from binary, clone --- src/editexecutablesdialog.cpp | 164 ++++++++++++++++++++++++++++++------------ src/editexecutablesdialog.h | 13 +++- src/editexecutablesdialog.ui | 7 +- 3 files changed, 136 insertions(+), 48 deletions(-) (limited to 'src/editexecutablesdialog.cpp') diff --git a/src/editexecutablesdialog.cpp b/src/editexecutablesdialog.cpp index 5c4ee149..41392712 100644 --- a/src/editexecutablesdialog.cpp +++ b/src/editexecutablesdialog.cpp @@ -33,6 +33,28 @@ along with Mod Organizer. If not, see . using namespace MOBase; using namespace MOShared; +class IgnoreChanges +{ +public: + IgnoreChanges(EditExecutablesDialog* d) + : m_dialog(d) + { + m_dialog->m_settingUI = true; + } + + ~IgnoreChanges() + { + m_dialog->m_settingUI = false; + } + + IgnoreChanges(const IgnoreChanges&) = delete; + IgnoreChanges& operator=(const IgnoreChanges&) = delete; + +private: + EditExecutablesDialog* m_dialog; +}; + + EditExecutablesDialog::EditExecutablesDialog(OrganizerCore& oc, QWidget* parent) : TutorableDialog("EditExecutables", parent) , ui(new Ui::EditExecutablesDialog) @@ -53,6 +75,12 @@ EditExecutablesDialog::EditExecutablesDialog(OrganizerCore& oc, QWidget* parent) fillList(); setDirty(false); + auto* m = new QMenu; + m->addAction(tr("Add from file..."), [&]{ addFromFile(); }); + m->addAction(tr("Add empty"), [&]{ addEmpty(); }); + m->addAction(tr("Clone selected"), [&]{ clone(); }); + ui->add->setMenu(m); + // some widgets need to do more than just save() and have their own handler connect(ui->binary, &QLineEdit::textChanged, [&]{ save(); }); connect(ui->workingDirectory, &QLineEdit::textChanged, [&]{ save(); }); @@ -221,8 +249,7 @@ void EditExecutablesDialog::updateUI( const QListWidgetItem* item, const Executable* e) { // the ui is currently being set, ignore changes - m_settingUI = true; - Guard g([&]{ m_settingUI = false; }); + IgnoreChanges c(this); if (e) { setEdits(*e); @@ -461,20 +488,7 @@ void EditExecutablesDialog::on_reset_clicked() void EditExecutablesDialog::on_add_clicked() { - auto title = m_executablesList.makeNonConflictingTitle(tr("New Executable")); - if (!title) { - return; - } - - const Executable e(*title); - - m_executablesList.setExecutable(e); - - auto* item = createListItem(e); - ui->list->addItem(item); - item->setSelected(true); - - setDirty(true); + addFromFile(); } void EditExecutablesDialog::on_remove_clicked() @@ -550,19 +564,21 @@ bool EditExecutablesDialog::isTitleConflicting(const QString& s) return false; } -void EditExecutablesDialog::on_title_textChanged(const QString& s) +void EditExecutablesDialog::on_title_textChanged(const QString& original) { if (m_settingUI) { return; } - // don't allow changing the title to something that already exists - if (isTitleConflicting(s)) { + auto s = original.trimmed(); + + // disallow empty names + if (s.isEmpty()) { return; } - // don't allow empty names - if (s.trimmed().isEmpty()) { + // disallow changing the title to something that already exists + if (isTitleConflicting(s)) { return; } @@ -581,9 +597,7 @@ void EditExecutablesDialog::on_title_textChanged(const QString& s) void EditExecutablesDialog::on_title_editingFinished() { - if (ui->title->text().trimmed().isEmpty()) { - ui->title->setText(m_lastGoodTitle); - } + ui->title->setText(m_lastGoodTitle); } void EditExecutablesDialog::on_overwriteSteamAppID_toggled(bool checked) @@ -618,34 +632,78 @@ void EditExecutablesDialog::on_forceLoadLibraries_toggled(bool checked) void EditExecutablesDialog::on_browseBinary_clicked() { - const QString binaryName = FileDialogMemory::getOpenFileName( - "editExecutableBinary", this, tr("Select a binary"), ui->binary->text(), - tr("Executable (%1)").arg("*.exe *.bat *.jar")); + const auto binaryName = browseBinary(ui->binary->text()); + if (binaryName.fileName().isEmpty()) { + return; + } - if (binaryName.isNull()) { - // canceled + setBinary(binaryName); + save(); +} + +void EditExecutablesDialog::addFromFile() +{ + const auto binary = browseBinary(ui->binary->text()); + if (binary.fileName().isEmpty()) { return; } + addNew(Executable(binary.fileName())); + setBinary(binary); +} + +void EditExecutablesDialog::addEmpty() +{ + addNew(Executable(tr("New Executable"))); +} + +void EditExecutablesDialog::clone() +{ + auto* e = selectedExe(); + if (!e) { + return; + } + + addNew(*e); +} + +void EditExecutablesDialog::addNew(Executable e) +{ + const auto fixedTitle = m_executablesList.makeNonConflictingTitle(e.title()); + if (!fixedTitle) { + return; + } + + e.title(*fixedTitle); + + m_executablesList.setExecutable(e); + + auto* item = createListItem(e); + ui->list->addItem(item); + item->setSelected(true); + + setDirty(true); +} + +void EditExecutablesDialog::setBinary(const QFileInfo& binary) +{ // setting binary - if (binaryName.endsWith(".jar", Qt::CaseInsensitive)) { + if (binary.suffix().compare("jar", Qt::CaseInsensitive) == 0) { // special case for jar files, uses the system java installation - setJarBinary(binaryName); + setJarBinary(binary); } else { - ui->binary->setText(QDir::toNativeSeparators(binaryName)); + ui->binary->setText(QDir::toNativeSeparators(binary.absoluteFilePath())); } // setting title if some variation of "New Executable" if (ui->title->text().startsWith(tr("New Executable"), Qt::CaseInsensitive)) { - const auto prefix = QFileInfo(binaryName).baseName(); + const auto prefix = binary.baseName(); const auto newTitle = m_executablesList.makeNonConflictingTitle(prefix); if (newTitle) { ui->title->setText(*newTitle); } } - - save(); } void EditExecutablesDialog::on_browseWorkingDirectory_clicked() @@ -655,7 +713,7 @@ void EditExecutablesDialog::on_browseWorkingDirectory_clicked() ui->workingDirectory->text()); if (dirName.isNull()) { - // canceled + // cancelled return; } @@ -694,9 +752,26 @@ void EditExecutablesDialog::on_buttons_clicked(QAbstractButton* b) } } -void EditExecutablesDialog::setJarBinary(const QString& binaryName) +QFileInfo EditExecutablesDialog::browseBinary(const QString& initial) { - auto java = OrganizerCore::findJavaInstallation(binaryName); + const QString Filters = + tr("Executables (*.exe *.bat *.jar)") + ";;" + + tr("All Files (*.*)"); + + const auto f = FileDialogMemory::getOpenFileName( + "editExecutableBinary", this, tr("Select an executable"), + initial, Filters); + + if (f.isNull()) { + return {}; + } + + return QFileInfo(f); +} + +void EditExecutablesDialog::setJarBinary(const QFileInfo& binary) +{ + auto java = OrganizerCore::findJavaInstallation(binary.absoluteFilePath()); if (java.isEmpty()) { QMessageBox::information( @@ -706,13 +781,14 @@ void EditExecutablesDialog::setJarBinary(const QString& binaryName) "the binary.")); } - // only save once + { + // only save once + IgnoreChanges c(this); - m_settingUI = true; - ui->binary->setText(java); - ui->workingDirectory->setText(QDir::toNativeSeparators(QFileInfo(binaryName).absolutePath())); - ui->arguments->setText("-jar \"" + QDir::toNativeSeparators(binaryName) + "\""); - m_settingUI = false; + ui->binary->setText(java); + ui->workingDirectory->setText(QDir::toNativeSeparators(binary.absolutePath())); + ui->arguments->setText("-jar \"" + QDir::toNativeSeparators(binary.absoluteFilePath()) + "\""); + } save(); } diff --git a/src/editexecutablesdialog.h b/src/editexecutablesdialog.h index 9e39b115..2e52c722 100644 --- a/src/editexecutablesdialog.h +++ b/src/editexecutablesdialog.h @@ -141,7 +141,8 @@ private: **/ class EditExecutablesDialog : public MOBase::TutorableDialog { - Q_OBJECT + Q_OBJECT; + friend class IgnoreChanges; public: using CustomOverwrites = ToggableMap; @@ -222,10 +223,18 @@ private: void saveOrder(); bool canMove(const QListWidgetItem* item, int direction); void move(QListWidgetItem* item, int direction); - void setJarBinary(const QString& binaryName); bool isTitleConflicting(const QString& s); void commitChanges(); void setDirty(bool b); + + void addFromFile(); + void addEmpty(); + void clone(); + void addNew(Executable e); + + QFileInfo browseBinary(const QString& initial); + void setBinary(const QFileInfo& binary); + void setJarBinary(const QFileInfo& binary); }; #endif // EDITEXECUTABLESDIALOG_H diff --git a/src/editexecutablesdialog.ui b/src/editexecutablesdialog.ui index c2ff7d31..64d5140d 100644 --- a/src/editexecutablesdialog.ui +++ b/src/editexecutablesdialog.ui @@ -106,6 +106,9 @@ :/MO/gui/add:/MO/gui/add + + QToolButton::InstantPopup + @@ -140,7 +143,7 @@ Move the executable up in the list - Move the executable up in the list + Up @@ -160,7 +163,7 @@ Move the executable down in the list - Move the executable down in the list + Down -- cgit v1.3.1 From 52db7e8c7ddd39609a8eecbf44fa15ec6369f843 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Tue, 8 Oct 2019 19:20:08 -0400 Subject: initial selection in the edit executables dialog from main window --- src/editexecutablesdialog.cpp | 6 +++++- src/editexecutablesdialog.h | 3 ++- src/mainwindow.cpp | 9 +++++---- src/mainwindow.h | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-) (limited to 'src/editexecutablesdialog.cpp') diff --git a/src/editexecutablesdialog.cpp b/src/editexecutablesdialog.cpp index 41392712..19b57e9a 100644 --- a/src/editexecutablesdialog.cpp +++ b/src/editexecutablesdialog.cpp @@ -55,7 +55,7 @@ private: }; -EditExecutablesDialog::EditExecutablesDialog(OrganizerCore& oc, QWidget* parent) +EditExecutablesDialog::EditExecutablesDialog(OrganizerCore& oc, int sel, QWidget* parent) : TutorableDialog("EditExecutables", parent) , ui(new Ui::EditExecutablesDialog) , m_organizerCore(oc) @@ -75,6 +75,10 @@ EditExecutablesDialog::EditExecutablesDialog(OrganizerCore& oc, QWidget* parent) fillList(); setDirty(false); + if (sel >= 0 && sel < ui->list->count()) { + ui->list->item(sel)->setSelected(true); + } + auto* m = new QMenu; m->addAction(tr("Add from file..."), [&]{ addFromFile(); }); m->addAction(tr("Add empty"), [&]{ addEmpty(); }); diff --git a/src/editexecutablesdialog.h b/src/editexecutablesdialog.h index 2e52c722..949aff66 100644 --- a/src/editexecutablesdialog.h +++ b/src/editexecutablesdialog.h @@ -148,7 +148,8 @@ public: using CustomOverwrites = ToggableMap; using ForcedLibraries = ToggableMap>; - explicit EditExecutablesDialog(OrganizerCore& oc, QWidget* parent=nullptr); + explicit EditExecutablesDialog( + OrganizerCore& oc, int selection=-1, QWidget* parent=nullptr); ~EditExecutablesDialog(); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 295c60a6..ba02267a 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2345,12 +2345,12 @@ void MainWindow::on_startButton_clicked() { ui->startButton->setEnabled(true); } -bool MainWindow::modifyExecutablesDialog() +bool MainWindow::modifyExecutablesDialog(int selection) { bool result = false; try { - EditExecutablesDialog dialog(m_OrganizerCore, this); + EditExecutablesDialog dialog(m_OrganizerCore, selection, this); result = (dialog.exec() == QDialog::Accepted); @@ -2375,7 +2375,7 @@ void MainWindow::on_executablesListBox_currentIndexChanged(int index) m_OldExecutableIndex = index; if (index == 0) { - modifyExecutablesDialog(); + modifyExecutablesDialog(previousIndex - 1); ui->executablesListBox->setCurrentIndex(previousIndex); } } @@ -2451,7 +2451,8 @@ void MainWindow::on_actionAdd_Profile_triggered() void MainWindow::on_actionModify_Executables_triggered() { - if (modifyExecutablesDialog()) { + const auto sel = (m_OldExecutableIndex > 0 ? m_OldExecutableIndex - 1 : 0); + if (modifyExecutablesDialog(sel)) { ui->executablesListBox->setCurrentIndex(m_OldExecutableIndex); } } diff --git a/src/mainwindow.h b/src/mainwindow.h index 524e2b6e..fa6a81cf 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -235,7 +235,7 @@ private: QList findFileInfos(const QString &path, const std::function &filter) const; - bool modifyExecutablesDialog(); + bool modifyExecutablesDialog(int selection); void displayModInformation(int row, ModInfoTabIDs tab=ModInfoTabIDs::None); void testExtractBSA(int modIndex); -- cgit v1.3.1 From 0ea975248b8cdb8319d3a366616f8d852726f83c Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Tue, 8 Oct 2019 19:38:56 -0400 Subject: remove separators and backups from mod list in the edit executables dialog --- src/editexecutablesdialog.cpp | 7 ++++++- src/modinfo.cpp | 25 ++++++++++++++++++++----- src/modinfo.h | 12 ++++++++++++ 3 files changed, 38 insertions(+), 6 deletions(-) (limited to 'src/editexecutablesdialog.cpp') diff --git a/src/editexecutablesdialog.cpp b/src/editexecutablesdialog.cpp index 19b57e9a..b56fdc41 100644 --- a/src/editexecutablesdialog.cpp +++ b/src/editexecutablesdialog.cpp @@ -71,7 +71,12 @@ EditExecutablesDialog::EditExecutablesDialog(OrganizerCore& oc, int sel, QWidget loadCustomOverwrites(); loadForcedLibraries(); - ui->mods->addItems(m_organizerCore.modList()->allMods()); + for (auto&& m : m_organizerCore.modList()->allMods()) { + if (ModInfo::isRegularName(m)) { + ui->mods->addItem(m); + } + } + fillList(); setDirty(false); diff --git a/src/modinfo.cpp b/src/modinfo.cpp index e3daa4fd..6e048bfb 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -61,17 +61,32 @@ bool ModInfo::ByName(const ModInfo::Ptr &LHS, const ModInfo::Ptr &RHS) return QString::compare(LHS->name(), RHS->name(), Qt::CaseInsensitive) < 0; } +bool ModInfo::isSeparatorName(const QString& name) +{ + static QRegExp separatorExp(".*_separator"); + return separatorExp.exactMatch(name); +} + +bool ModInfo::isBackupName(const QString& name) +{ + static QRegExp backupExp(".*backup[0-9]*"); + return backupExp.exactMatch(name); +} + +bool ModInfo::isRegularName(const QString& name) +{ + return !isSeparatorName(name) && !isBackupName(name); +} + ModInfo::Ptr ModInfo::createFrom(PluginContainer *pluginContainer, const MOBase::IPluginGame *game, const QDir &dir, DirectoryEntry **directoryStructure) { QMutexLocker locker(&s_Mutex); - // int id = s_NextID++; - static QRegExp backupExp(".*backup[0-9]*"); - static QRegExp separatorExp(".*_separator"); ModInfo::Ptr result; - if (backupExp.exactMatch(dir.dirName())) { + + if (isBackupName(dir.dirName())) { result = ModInfo::Ptr(new ModInfoBackup(pluginContainer, game, dir, directoryStructure)); - } else if(separatorExp.exactMatch(dir.dirName())){ + } else if (isSeparatorName(dir.dirName())) { result = Ptr(new ModInfoSeparator(pluginContainer, game, dir, directoryStructure)); } else { result = ModInfo::Ptr(new ModInfoRegular(pluginContainer, game, dir, directoryStructure)); diff --git a/src/modinfo.h b/src/modinfo.h index e395f45b..30a115c7 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -229,6 +229,18 @@ public: */ static ModInfo::Ptr createFromPlugin(const QString &modName, const QString &espName, const QStringList &bsaNames, ModInfo::EModType modType, MOShared::DirectoryEntry **directoryStructure, PluginContainer *pluginContainer); + // whether the given name is used for separators + // + static bool isSeparatorName(const QString& name); + + // whether the given name is used for backups + // + static bool isBackupName(const QString& name); + + // whether the given name is used for regular mods + // + static bool isRegularName(const QString& name); + /** * @brief retieve a name for one of the CONTENT_ enums * @param contentType the content value -- cgit v1.3.1 From de48d430eca4042f48be461fe5dc70d7e75d5596 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Tue, 8 Oct 2019 19:55:44 -0400 Subject: fixed tab order fixed list items being selected, but not focused, which broke keyboard nav --- src/editexecutablesdialog.cpp | 27 ++++++++++++++++++--------- src/editexecutablesdialog.h | 1 + src/editexecutablesdialog.ui | 11 +++++++++++ 3 files changed, 30 insertions(+), 9 deletions(-) (limited to 'src/editexecutablesdialog.cpp') diff --git a/src/editexecutablesdialog.cpp b/src/editexecutablesdialog.cpp index b56fdc41..b58531e5 100644 --- a/src/editexecutablesdialog.cpp +++ b/src/editexecutablesdialog.cpp @@ -81,7 +81,7 @@ EditExecutablesDialog::EditExecutablesDialog(OrganizerCore& oc, int sel, QWidget setDirty(false); if (sel >= 0 && sel < ui->list->count()) { - ui->list->item(sel)->setSelected(true); + selectIndex(sel); } auto* m = new QMenu; @@ -205,6 +205,14 @@ void EditExecutablesDialog::setDirty(bool b) } } +void EditExecutablesDialog::selectIndex(int i) +{ + if (i >= 0 && i < ui->list->count()) { + ui->list->selectionModel()->setCurrentIndex( + ui->list->model()->index(i, 0), QItemSelectionModel::ClearAndSelect); + } +} + QListWidgetItem* EditExecutablesDialog::selectedItem() { const auto selection = ui->list->selectedItems(); @@ -243,7 +251,7 @@ void EditExecutablesDialog::fillList() // select the first one in the list, if any if (ui->list->count() > 0) { - ui->list->item(0)->setSelected(true); + selectIndex(0); } else { updateUI(nullptr, nullptr); } @@ -459,13 +467,14 @@ void EditExecutablesDialog::move(QListWidgetItem* item, int direction) return; } - const auto row = ui->list->row(item); + const auto oldRow = ui->list->row(item); + const auto newRow = oldRow + (direction > 0 ? 1 : -1); // removing item - ui->list->takeItem(row); - ui->list->insertItem(row + (direction > 0 ? 1 : -1), item); - item->setSelected(true); + ui->list->takeItem(oldRow); + ui->list->insertItem(newRow, item); + selectIndex(newRow); setDirty(true); } @@ -530,10 +539,10 @@ void EditExecutablesDialog::on_remove_clicked() if (currentRow >= ui->list->count()) { // that was the last item, select the new list item, if any if (ui->list->count() > 0) { - ui->list->item(ui->list->count() - 1)->setSelected(true); + selectIndex(ui->list->count() - 1); } } else { - ui->list->item(currentRow)->setSelected(true); + selectIndex(currentRow); } setDirty(true); @@ -689,8 +698,8 @@ void EditExecutablesDialog::addNew(Executable e) auto* item = createListItem(e); ui->list->addItem(item); - item->setSelected(true); + selectIndex(ui->list->count() - 1); setDirty(true); } diff --git a/src/editexecutablesdialog.h b/src/editexecutablesdialog.h index 949aff66..c8be0bf6 100644 --- a/src/editexecutablesdialog.h +++ b/src/editexecutablesdialog.h @@ -227,6 +227,7 @@ private: bool isTitleConflicting(const QString& s); void commitChanges(); void setDirty(bool b); + void selectIndex(int i); void addFromFile(); void addEmpty(); diff --git a/src/editexecutablesdialog.ui b/src/editexecutablesdialog.ui index 64d5140d..5f7fee09 100644 --- a/src/editexecutablesdialog.ui +++ b/src/editexecutablesdialog.ui @@ -478,14 +478,25 @@ Right now the only case I know of where this needs to be overwritten is for the + add + remove + up + down + reset + list + title binary browseBinary workingDirectory browseWorkingDirectory + arguments overwriteSteamAppID steamAppID createFilesInMod mods + forceLoadLibraries + configureLibraries + useApplicationIcon -- cgit v1.3.1 From 21f55da7d3688eafc9e2dbae4535cf0c554be121 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Tue, 8 Oct 2019 23:03:45 -0400 Subject: added hide flag to executables --- src/editexecutablesdialog.cpp | 11 ++++ src/editexecutablesdialog.ui | 21 ++++-- src/executableslist.cpp | 16 ++++- src/executableslist.h | 6 +- src/mainwindow.cpp | 145 ++++++++++++++++++++++++++++++------------ src/mainwindow.h | 3 +- 6 files changed, 149 insertions(+), 53 deletions(-) (limited to 'src/editexecutablesdialog.cpp') diff --git a/src/editexecutablesdialog.cpp b/src/editexecutablesdialog.cpp index b58531e5..3efadc4c 100644 --- a/src/editexecutablesdialog.cpp +++ b/src/editexecutablesdialog.cpp @@ -97,6 +97,7 @@ EditExecutablesDialog::EditExecutablesDialog(OrganizerCore& oc, int sel, QWidget connect(ui->steamAppID, &QLineEdit::textChanged, [&]{ save(); }); connect(ui->mods, &QComboBox::currentTextChanged, [&]{ save(); }); connect(ui->useApplicationIcon, &QCheckBox::toggled, [&]{ save(); }); + connect(ui->hide, &QCheckBox::toggled, [&]{ save(); }); connect(ui->list->model(), &QAbstractItemModel::rowsMoved, [&]{ saveOrder(); }); } @@ -316,6 +317,8 @@ void EditExecutablesDialog::clearEdits() ui->configureLibraries->setEnabled(false); ui->useApplicationIcon->setEnabled(false); ui->useApplicationIcon->setChecked(false); + ui->hide->setEnabled(false); + ui->hide->setChecked(false); m_lastGoodTitle = ""; } @@ -330,6 +333,7 @@ void EditExecutablesDialog::setEdits(const Executable& e) ui->steamAppID->setEnabled(!e.steamAppID().isEmpty()); ui->steamAppID->setText(e.steamAppID()); ui->useApplicationIcon->setChecked(e.usesOwnIcon()); + ui->hide->setChecked(e.hide()); m_lastGoodTitle = e.title(); @@ -375,6 +379,7 @@ void EditExecutablesDialog::setEdits(const Executable& e) ui->useApplicationIcon->setEnabled(true); ui->createFilesInMod->setEnabled(true); ui->forceLoadLibraries->setEnabled(true); + ui->hide->setEnabled(true); } void EditExecutablesDialog::save() @@ -434,6 +439,12 @@ void EditExecutablesDialog::save() e->flags(e->flags() & (~Executable::UseApplicationIcon)); } + if (ui->hide->isChecked()) { + e->flags(e->flags() | Executable::Hide); + } else { + e->flags(e->flags() & (~Executable::Hide)); + } + setDirty(true); } diff --git a/src/editexecutablesdialog.ui b/src/editexecutablesdialog.ui index 5f7fee09..6f50b3b3 100644 --- a/src/editexecutablesdialog.ui +++ b/src/editexecutablesdialog.ui @@ -378,7 +378,7 @@ Right now the only case I know of where this needs to be overwritten is for the If this is enabled, new files are created in the specified mod instead of the "Overwrite" mod. - Create Files in Mod instead of Overwrite (*) + Create files in mod instead of overwrite (*) @@ -399,7 +399,7 @@ Right now the only case I know of where this needs to be overwritten is for the If this is enabled, the configured libraries will be automatically loaded when this executable is launched. - Force Load Libraries (*) + Force load libraries (*) @@ -431,14 +431,27 @@ Right now the only case I know of where this needs to be overwritten is for the - Use Application's Icon for desktop shortcuts + Use application's icon for desktop shortcuts + + + + + + + This executable will not appear in the list, on the toolbar or in the menu. It will still be visible in this dialog. + + + This executable will not appear in the list, on the toolbar or in the menu. It will still be visible in this dialog. + + + Hide in user interface - (*) Profile Specific + (*) Profile specific 5 diff --git a/src/executableslist.cpp b/src/executableslist.cpp index dce9181b..1be34b53 100644 --- a/src/executableslist.cpp +++ b/src/executableslist.cpp @@ -84,6 +84,9 @@ void ExecutablesList::load(const MOBase::IPluginGame* game, const Settings& s) if (map["ownicon"].toBool()) flags |= Executable::UseApplicationIcon; + if (map["hide"].toBool()) + flags |= Executable::Hide; + if (map.contains("custom")) { // the "custom" setting only exists in older versions needsUpgrade = true; @@ -116,6 +119,7 @@ void ExecutablesList::store(Settings& s) map["title"] = item.title(); map["toolbar"] = item.isShownOnToolbar(); map["ownicon"] = item.usesOwnIcon(); + map["hide"] = item.hide(); map["binary"] = item.binaryInfo().absoluteFilePath(); map["arguments"] = item.arguments(); map["workingDirectory"] = item.workingDirectory(); @@ -343,6 +347,10 @@ void ExecutablesList::dump() const flags.push_back("icon"); } + if (e.flags() & Executable::Hide) { + flags.push_back("hide"); + } + log::debug( " . executable '{}'\n" " binary: {}\n" @@ -456,11 +464,13 @@ bool Executable::usesOwnIcon() const return m_flags.testFlag(UseApplicationIcon); } -void Executable::mergeFrom(const Executable& other) +bool Executable::hide() const { - // flags on plugin executables that the user is allowed to change - const auto allow = ShowInToolbar; + return m_flags.testFlag(Hide); +} +void Executable::mergeFrom(const Executable& other) +{ // this happens after executables are loaded from settings and plugin // executables are being added, or when users are modifying executables diff --git a/src/executableslist.h b/src/executableslist.h index 23cf3cfe..a18042db 100644 --- a/src/executableslist.h +++ b/src/executableslist.h @@ -39,8 +39,9 @@ class Executable public: enum Flag { - ShowInToolbar = 0x02, - UseApplicationIcon = 0x04 + ShowInToolbar = 0x02, + UseApplicationIcon = 0x04, + Hide = 0x08 }; Q_DECLARE_FLAGS(Flags, Flag); @@ -69,6 +70,7 @@ public: bool isShownOnToolbar() const; void setShownOnToolbar(bool state); bool usesOwnIcon() const; + bool hide() const; void mergeFrom(const Executable& other); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index ba02267a..946caf08 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -757,7 +757,7 @@ void MainWindow::updatePinnedExecutables() bool hasLinks = false; for (const auto& exe : *m_OrganizerCore.executablesList()) { - if (exe.isShownOnToolbar()) { + if (!exe.hide() && exe.isShownOnToolbar()) { hasLinks = true; QAction *exeAction = new QAction( @@ -1792,23 +1792,44 @@ bool MainWindow::refreshProfiles(bool selectProfile) void MainWindow::refreshExecutablesList() { - QComboBox* executablesList = findChild("executablesListBox"); - executablesList->setEnabled(false); - executablesList->clear(); - executablesList->addItem(tr("")); + QAbstractItemModel *model = ui->executablesListBox->model(); + + auto add = [&](const QString& title, const QFileInfo& binary) { + QIcon icon; + if (!binary.fileName().isEmpty()) { + icon = iconForExecutable(binary.filePath()); + } + + ui->executablesListBox->addItem(icon, title); + + const auto i = ui->executablesListBox->count() - 1; + + model->setData( + model->index(i, 0), + QSize(0, ui->executablesListBox->iconSize().height() + 4), + Qt::SizeHintRole); + }; - QAbstractItemModel *model = executablesList->model(); - int i = 0; + ui->executablesListBox->setEnabled(false); + ui->executablesListBox->clear(); + + add(tr(""), {}); + for (const auto& exe : *m_OrganizerCore.executablesList()) { - QIcon icon = iconForExecutable(exe.binaryInfo().filePath()); - executablesList->addItem(icon, exe.title()); - model->setData(model->index(i, 0), QSize(0, executablesList->iconSize().height() + 4), Qt::SizeHintRole); - ++i; + if (!exe.hide()) { + add(exe.title(), exe.binaryInfo()); + } + } + + if (ui->executablesListBox->count() == 1) { + // all executables are hidden, add an empty one to at least be able to + // switch to edit + add(tr("(no executables)"), QFileInfo(":badfile")); } ui->executablesListBox->setCurrentIndex(1); - executablesList->setEnabled(true); + ui->executablesListBox->setEnabled(true); } @@ -2321,27 +2342,42 @@ void MainWindow::installMod(QString fileName) } } -void MainWindow::on_startButton_clicked() { - ui->startButton->setEnabled(false); +void MainWindow::on_startButton_clicked() +{ try { - const Executable &selectedExecutable(getSelectedExecutable()); - QString customOverwrite = m_OrganizerCore.currentProfile()->setting("custom_overwrites", selectedExecutable.title()).toString(); - auto forcedLibraries = m_OrganizerCore.currentProfile()->determineForcedLibraries(selectedExecutable.title()); - if (!m_OrganizerCore.currentProfile()->forcedLibrariesEnabled(selectedExecutable.title())) { + const Executable* selectedExecutable = getSelectedExecutable(); + if (!selectedExecutable) { + return; + } + + ui->startButton->setEnabled(false); + + auto* profile = m_OrganizerCore.currentProfile(); + + const QString customOverwrite = profile->setting( + "custom_overwrites", selectedExecutable->title()).toString(); + + auto forcedLibraries = profile->determineForcedLibraries( + selectedExecutable->title()); + + if (!profile->forcedLibrariesEnabled(selectedExecutable->title())) { forcedLibraries.clear(); } + m_OrganizerCore.spawnBinary( - selectedExecutable.binaryInfo(), selectedExecutable.arguments(), - selectedExecutable.workingDirectory().length() != 0 - ? selectedExecutable.workingDirectory() - : selectedExecutable.binaryInfo().absolutePath(), - selectedExecutable.steamAppID(), - customOverwrite, - forcedLibraries); + selectedExecutable->binaryInfo(), + selectedExecutable->arguments(), + selectedExecutable->workingDirectory().length() != 0 ? + selectedExecutable->workingDirectory() : + selectedExecutable->binaryInfo().absolutePath(), + selectedExecutable->steamAppID(), + customOverwrite, + forcedLibraries); } catch (...) { ui->startButton->setEnabled(true); throw; } + ui->startButton->setEnabled(true); } @@ -2376,7 +2412,13 @@ void MainWindow::on_executablesListBox_currentIndexChanged(int index) if (index == 0) { modifyExecutablesDialog(previousIndex - 1); - ui->executablesListBox->setCurrentIndex(previousIndex); + const auto newCount = ui->executablesListBox->count(); + + if (previousIndex >= 0 && previousIndex < newCount) { + ui->executablesListBox->setCurrentIndex(previousIndex); + } else { + ui->executablesListBox->setCurrentIndex(newCount - 1); + } } } @@ -2452,8 +2494,14 @@ void MainWindow::on_actionAdd_Profile_triggered() void MainWindow::on_actionModify_Executables_triggered() { const auto sel = (m_OldExecutableIndex > 0 ? m_OldExecutableIndex - 1 : 0); + if (modifyExecutablesDialog(sel)) { - ui->executablesListBox->setCurrentIndex(m_OldExecutableIndex); + const auto newCount = ui->executablesListBox->count(); + if (m_OldExecutableIndex >= 0 && m_OldExecutableIndex < newCount) { + ui->executablesListBox->setCurrentIndex(m_OldExecutableIndex); + } else { + ui->executablesListBox->setCurrentIndex(newCount - 1); + } } } @@ -4972,33 +5020,43 @@ void MainWindow::on_savegameList_customContextMenuRequested(const QPoint &pos) void MainWindow::linkToolbar() { - Executable& exe = getSelectedExecutable(); + Executable* exe = getSelectedExecutable(); + if (!exe) { + return; + } - exe.setShownOnToolbar(!exe.isShownOnToolbar()); + exe->setShownOnToolbar(!exe->isShownOnToolbar()); updatePinnedExecutables(); } void MainWindow::linkDesktop() { - env::Shortcut(getSelectedExecutable()).toggle(env::Shortcut::Desktop); + if (auto* exe=getSelectedExecutable()) { + env::Shortcut(*exe).toggle(env::Shortcut::Desktop); + } } void MainWindow::linkMenu() { - env::Shortcut(getSelectedExecutable()).toggle(env::Shortcut::StartMenu); + if (auto* exe=getSelectedExecutable()) { + env::Shortcut(*exe).toggle(env::Shortcut::StartMenu); + } } void MainWindow::on_linkButton_pressed() { - const Executable& exe = getSelectedExecutable(); + const Executable* exe = getSelectedExecutable(); + if (!exe) { + return; + } const QIcon addIcon(":/MO/gui/link"); const QIcon removeIcon(":/MO/gui/remove"); - env::Shortcut shortcut(exe); + env::Shortcut shortcut(*exe); m_LinkToolbar->setIcon( - exe.isShownOnToolbar() ? removeIcon : addIcon); + exe->isShownOnToolbar() ? removeIcon : addIcon); m_LinkDesktop->setIcon( shortcut.exists(env::Shortcut::Desktop) ? removeIcon : addIcon); @@ -6327,16 +6385,19 @@ void MainWindow::on_groupCombo_currentIndexChanged(int index) modFilterActive(m_ModListSortProxy->isFilterActive()); } -const Executable &MainWindow::getSelectedExecutable() const +Executable* MainWindow::getSelectedExecutable() { - const QString name = ui->executablesListBox->itemText(ui->executablesListBox->currentIndex()); - return m_OrganizerCore.executablesList()->get(name); -} + const QString name = ui->executablesListBox->itemText( + ui->executablesListBox->currentIndex()); -Executable &MainWindow::getSelectedExecutable() -{ - const QString name = ui->executablesListBox->itemText(ui->executablesListBox->currentIndex()); - return m_OrganizerCore.executablesList()->get(name); + try + { + return &m_OrganizerCore.executablesList()->get(name); + } + catch(std::runtime_error&) + { + return nullptr; + } } void MainWindow::on_showHiddenBox_toggled(bool checked) diff --git a/src/mainwindow.h b/src/mainwindow.h index fa6a81cf..dbb1a0d5 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -397,8 +397,7 @@ private: // when painting the count QIcon m_originalNotificationIcon; - Executable const &getSelectedExecutable() const; - Executable &getSelectedExecutable(); + Executable* getSelectedExecutable(); private slots: -- cgit v1.3.1