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