From 5e5681709ab878f3aa6cf1344af44e8ae9544987 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Thu, 11 Jul 2019 01:55:31 -0400 Subject: reworked the nexus connection panel moved most of the stuff into a new NexusSSOLogin class --- src/settingsdialog.ui | 351 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 242 insertions(+), 109 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index faaf1653..dfbde943 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -451,111 +451,244 @@ If you use pre-releases, never contact me directly by e-mail or via private mess Nexus - + - - - Allows Mod Organizer to connect to the Nexus for downloading mods, checking for updates, and other such things. - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Allows Mod Organizer to connect to the Nexus for downloading mods, checking for updates, and other such things. Clicking &quot;Connect to Nexus&quot; will open a Nexus webpage to authorise Mod Organizer. You will need to be logged into your Nexus account. The authorisation is stored in the Windows Credential Manager. Your Nexus username and password are not required or stored by Mod Organizer.</p></body></html> - + - Nexus + Nexus Connection - + - - - - - Connect to Nexus - - - - + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Connect to Nexus + + + + + + + Manually enter the API key and try to login + + + Enter API Key Manually + + + + + + + Clear the stored Nexus API key and force reauthorization. + + + Disconnect from Nexus + + + + :/MO/gui/edit_clear:/MO/gui/edit_clear + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - Manually enter the API key and try to login - - - Enter API Key Manually - - - - - - - Clear the stored Nexus API key and force reauthorization. - - - Disconnect from Nexus - - - - :/MO/gui/edit_clear:/MO/gui/edit_clear - - - - - - - Remove cache and cookies. - - - Clear Cache - - - - :/MO/gui/edit_clear:/MO/gui/edit_clear - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QAbstractScrollArea::AdjustToContents + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Nexus Account + + + + + + User ID + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + id + + + + + + + Username + + + + + + + username + + + + + + + Account + + + + + + + account + + + + + + + + + + Statistics + + + + + + Daily requests + + + + + + + Hourly requests + + + + + + + hourly requests + + + + + + + Requests queued + + + + + + + queued + + + + + + + daily requests + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + @@ -618,6 +751,20 @@ p, li { white-space: pre-wrap; } + + + + Remove cache and cookies. + + + Clear Cache + + + + :/MO/gui/edit_clear:/MO/gui/edit_clear + + + @@ -682,19 +829,6 @@ p, li { white-space: pre-wrap; } - - - - Qt::Vertical - - - - 20 - 40 - - - - @@ -1359,7 +1493,6 @@ programs you are intentionally running. browseProfilesDirBtn overwriteDirEdit browseOverwriteDirBtn - clearCacheButton associateButton knownServersList preferredServersList -- cgit v1.3.1 From 45f0a9e78ac876a2a956bc538c6d34358703e338 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Fri, 12 Jul 2019 02:46:31 -0400 Subject: nexus info and stats in settings cleaned up double logging for github reset validation progress dialog parent just before the main window dies removed unused APIStats from APIUserAccount, added isValid() --- src/apiuseraccount.cpp | 22 +++++ src/apiuseraccount.h | 8 +- src/main.cpp | 8 +- src/nxmaccessmanager.cpp | 2 +- src/organizercore.cpp | 2 +- src/selfupdater.cpp | 2 +- src/settingsdialog.cpp | 98 ++++++++++++++++----- src/settingsdialog.h | 6 ++ src/settingsdialog.ui | 218 +++++++++++++++++++++++------------------------ 9 files changed, 226 insertions(+), 140 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/apiuseraccount.cpp b/src/apiuseraccount.cpp index 596f8aa7..35a868d5 100644 --- a/src/apiuseraccount.cpp +++ b/src/apiuseraccount.cpp @@ -1,10 +1,32 @@ #include "apiuseraccount.h" +QString localizedUserAccountType(APIUserAccountTypes t) +{ + switch (t) + { + case APIUserAccountTypes::Regular: + return QObject::tr("Regular"); + + case APIUserAccountTypes::Premium: + return QObject::tr("Premium"); + + case APIUserAccountTypes::None: // fall-through + default: + return QObject::tr("None"); + } +} + + APIUserAccount::APIUserAccount() : m_type(APIUserAccountTypes::None) { } +bool APIUserAccount::isValid() const +{ + return !m_key.isEmpty(); +} + const QString& APIUserAccount::apiKey() const { return m_key; diff --git a/src/apiuseraccount.h b/src/apiuseraccount.h index 7dd16128..ea4e8685 100644 --- a/src/apiuseraccount.h +++ b/src/apiuseraccount.h @@ -18,6 +18,8 @@ enum class APIUserAccountTypes Premium }; +QString localizedUserAccountType(APIUserAccountTypes t); + /** * current limits imposed on the user account @@ -61,6 +63,11 @@ public: APIUserAccount(); + /** + * whether the user is logged in + */ + bool isValid() const; + /** * api key */ @@ -134,7 +141,6 @@ private: QString m_key, m_id, m_name; APIUserAccountTypes m_type; APILimits m_limits; - APIStats m_stats; }; #endif // APIUSERACCOUNT_H diff --git a/src/main.cpp b/src/main.cpp index 0b078f03..4359c645 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -713,7 +713,13 @@ int runApplication(MOApplication &application, SingleInstance &instance, mainWindow.activateWindow(); splash.finish(&mainWindow); - return application.exec(); + + const auto ret = application.exec(); + + NexusInterface::instance(&pluginContainer) + ->getAccessManager()->setTopLevelWidget(nullptr); + + return ret; } } catch (const std::exception &e) { reportError(e.what()); diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp index a331b2e8..196368fd 100644 --- a/src/nxmaccessmanager.cpp +++ b/src/nxmaccessmanager.cpp @@ -167,7 +167,7 @@ QString NexusSSOLogin::stateToString(States s, const QString& e) return QObject::tr("Opened browser, waiting for user..."); case Finished: - return QObject::tr("Connected."); + return QObject::tr("Finished."); case Timeout: return QObject::tr( diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 87668f4b..eeb69e61 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -2484,7 +2484,7 @@ void OrganizerCore::loginSuccessfulUpdate(bool necessary) void OrganizerCore::loginFailed(const QString &message) { - qDebug().nospace().noquote() + qCritical().nospace().noquote() << "Nexus API validation failed: " << message; if (QMessageBox::question(qApp->activeWindow(), tr("Login failed"), diff --git a/src/selfupdater.cpp b/src/selfupdater.cpp index 271c621b..e967b27c 100644 --- a/src/selfupdater.cpp +++ b/src/selfupdater.cpp @@ -130,7 +130,7 @@ void SelfUpdater::testForUpdate() m_GitHub.releases(GitHub::Repository("Modorganizer2", "modorganizer"), [this](const QJsonArray &releases) { if (releases.isEmpty()) { - qDebug("Unable to connect to github.com to check version"); + // error message already logged return; } diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index df957f87..0dae31ac 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -55,6 +55,7 @@ public: : QDialog(parent), ui(new Ui::NexusManualKeyDialog) { ui->setupUi(this); + ui->key->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); connect(ui->openBrowser, &QPushButton::clicked, [&]{ openBrowser(); }); connect(ui->paste, &QPushButton::clicked, [&]{ paste(); }); @@ -111,7 +112,7 @@ SettingsDialog::SettingsDialog(PluginContainer *pluginContainer, Settings* setti QKeySequence(Qt::Key_Delete), ui->pluginBlacklist); connect(delShortcut, SIGNAL(activated()), this, SLOT(deleteBlacklistItem())); - updateNexusButtons(); + updateNexusState(); } SettingsDialog::~SettingsDialog() @@ -399,7 +400,7 @@ void SettingsDialog::on_nexusConnect_clicked() ui->nexusLog->clear(); m_nexusLogin->start(); - updateNexusButtons(); + updateNexusState(); } void SettingsDialog::on_nexusManualKey_clicked() @@ -421,8 +422,18 @@ void SettingsDialog::on_nexusManualKey_clicked() } ui->nexusLog->clear(); - ui->nexusLog->addItem(tr("Checking API key...")); + validateKey(key); +} + +void SettingsDialog::on_nexusDisconnect_clicked() +{ + clearKey(); + ui->nexusLog->clear(); + addNexusLog(tr("Disconnected.")); +} +void SettingsDialog::validateKey(const QString& key) +{ if (!m_nexusValidator) { m_nexusValidator.reset(new NexusKeyValidator( *NexusInterface::instance(m_PluginContainer)->getAccessManager())); @@ -436,6 +447,7 @@ void SettingsDialog::on_nexusManualKey_clicked() }; } + addNexusLog(tr("Checking API key...")); m_nexusValidator->start(key); } @@ -444,45 +456,62 @@ void SettingsDialog::onSSOKeyChanged(const QString& key) if (key.isEmpty()) { clearKey(); } else { - setKey(key); + addNexusLog(tr("Received API key.")); + validateKey(key); } } void SettingsDialog::onSSOStateChanged(NexusSSOLogin::States s, const QString& e) { - const auto log = NexusSSOLogin::stateToString(s, e); + if (s != NexusSSOLogin::Finished) { + // finished state is handled in onSSOKeyChanged() + const auto log = NexusSSOLogin::stateToString(s, e); - for (auto&& line : log.split("\n")) { - ui->nexusLog->addItem(line); + for (auto&& line : log.split("\n")) { + addNexusLog(line); + } } - updateNexusButtons(); + updateNexusState(); } void SettingsDialog::onValidatorStateChanged( NexusKeyValidator::States s, const QString& e) { - const auto log = NexusKeyValidator::stateToString(s, e); + if (s != NexusKeyValidator::Finished) { + // finished state is handled in onValidatorFinished() + const auto log = NexusKeyValidator::stateToString(s, e); - for (auto&& line : log.split("\n")) { - ui->nexusLog->addItem(line); + for (auto&& line : log.split("\n")) { + addNexusLog(line); + } } - updateNexusButtons(); + updateNexusState(); } void SettingsDialog::onValidatorFinished(const APIUserAccount& user) { + NexusInterface::instance(m_PluginContainer)->setUserAccount(user); + if (!user.apiKey().isEmpty()) { - setKey(user.apiKey()); + if (setKey(user.apiKey())) { + addNexusLog(tr("Linked with Nexus successfully.")); + } } } +void SettingsDialog::addNexusLog(const QString& s) +{ + ui->nexusLog->addItem(s); + ui->nexusLog->scrollToBottom(); +} + bool SettingsDialog::setKey(const QString& key) { m_keyChanged = true; const bool ret = m_settings->setNexusApiKey(key); - updateNexusButtons(); + updateNexusState(); return ret; } @@ -490,13 +519,19 @@ bool SettingsDialog::clearKey() { m_keyChanged = true; const auto ret = m_settings->clearNexusApiKey(); - updateNexusButtons(); NexusInterface::instance(m_PluginContainer)->getAccessManager()->clearApiKey(); + updateNexusState(); return ret; } +void SettingsDialog::updateNexusState() +{ + updateNexusButtons(); + updateNexusData(); +} + void SettingsDialog::updateNexusButtons() { if (m_nexusLogin && m_nexusLogin->isActive()) { @@ -532,6 +567,32 @@ void SettingsDialog::updateNexusButtons() } } +void SettingsDialog::updateNexusData() +{ + const auto user = NexusInterface::instance(m_PluginContainer) + ->getAPIUserAccount(); + + if (user.isValid()) { + ui->nexusUserID->setText(user.id()); + ui->nexusName->setText(user.name()); + ui->nexusAccount->setText(localizedUserAccountType(user.type())); + + ui->nexusDailyRequests->setText(QString("%1/%2") + .arg(user.limits().remainingDailyRequests) + .arg(user.limits().maxDailyRequests)); + + ui->nexusHourlyRequests->setText(QString("%1/%2") + .arg(user.limits().remainingHourlyRequests) + .arg(user.limits().maxHourlyRequests)); + } else { + ui->nexusUserID->setText(tr("N/A")); + ui->nexusName->setText(tr("N/A")); + ui->nexusAccount->setText(tr("N/A")); + ui->nexusDailyRequests->setText(tr("N/A")); + ui->nexusHourlyRequests->setText(tr("N/A")); + } +} + void SettingsDialog::storeSettings(QListWidgetItem *pluginItem) { if (pluginItem != nullptr) { @@ -599,13 +660,6 @@ void SettingsDialog::on_clearCacheButton_clicked() NexusInterface::instance(m_PluginContainer)->clearCache(); } -void SettingsDialog::on_nexusDisconnect_clicked() -{ - clearKey(); - ui->nexusLog->clear(); - ui->nexusLog->addItem(tr("Disconnected.")); -} - void SettingsDialog::normalizePath(QLineEdit *lineEdit) { QString text = lineEdit->text(); diff --git a/src/settingsdialog.h b/src/settingsdialog.h index 1741fc13..c5f487fd 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -145,15 +145,21 @@ private: std::unique_ptr m_nexusLogin; std::unique_ptr m_nexusValidator; + void validateKey(const QString& key); bool setKey(const QString& key); bool clearKey(); + + void updateNexusState(); void updateNexusButtons(); + void updateNexusData(); void onSSOKeyChanged(const QString& key); void onSSOStateChanged(NexusSSOLogin::States s, const QString& e); void onValidatorStateChanged(NexusKeyValidator::States s, const QString& e); void onValidatorFinished(const APIUserAccount& user); + + void addNexusLog(const QString& s); }; #endif // SETTINGSDIALOG_H diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index dfbde943..fccc8be0 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -451,103 +451,7 @@ If you use pre-releases, never contact me directly by e-mail or via private mess Nexus - - - - - Nexus Connection - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Connect to Nexus - - - - - - - Manually enter the API key and try to login - - - Enter API Key Manually - - - - - - - Clear the stored Nexus API key and force reauthorization. - - - Disconnect from Nexus - - - - :/MO/gui/edit_clear:/MO/gui/edit_clear - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QAbstractScrollArea::AdjustToContents - - - - - - - - - + @@ -569,10 +473,13 @@ If you use pre-releases, never contact me directly by e-mail or via private mess Nexus Account + + 10 + - User ID + User ID: Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse @@ -589,21 +496,21 @@ If you use pre-releases, never contact me directly by e-mail or via private mess - Username + Name: - + - username + name - Account + Account: @@ -623,17 +530,27 @@ If you use pre-releases, never contact me directly by e-mail or via private mess Statistics + + 10 + - Daily requests + Daily requests: + + + + + + + daily requests - Hourly requests + Hourly requests: @@ -644,24 +561,99 @@ If you use pre-releases, never contact me directly by e-mail or via private mess - - + + + + + + + + + + Nexus Connection + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + - Requests queued + Connect to Nexus - - + + + + Manually enter the API key and try to login + - queued + Enter API Key Manually - - + + + + Clear the stored Nexus API key and force reauthorization. + - daily requests + Disconnect from Nexus + + + + :/MO/gui/edit_clear:/MO/gui/edit_clear + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QAbstractScrollArea::AdjustToContents -- cgit v1.3.1 From bca6283311cf1dea4c96f8ee5bf192bdb1640cb3 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Wed, 17 Jul 2019 08:56:16 -0400 Subject: use log::Levels instead of ints create log level combobox in code, set selected index based on value instead added log level to context menu in log list --- src/mainwindow.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++--- src/mainwindow.h | 12 +++++++++--- src/mainwindow.ui | 30 +++++++++++++++--------------- src/organizercore.cpp | 4 +++- src/organizercore.h | 5 ++++- src/settings.cpp | 30 ++++++++++++++++++++++++++---- src/settings.h | 10 +++++++++- src/settingsdialog.ui | 20 -------------------- src/usvfsconnector.cpp | 20 +++++++++++--------- src/usvfsconnector.h | 7 ++++++- 10 files changed, 127 insertions(+), 58 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 4e91ef9f..f65bf4e1 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -357,7 +357,7 @@ MainWindow::MainWindow(QSettings &initSettings m_CategoryFactory.loadCategories(); - ui->logList->addAction(ui->actionCopy_Log_to_Clipboard); + setupLogMenu(); int splitterSize = this->size().height(); // actually total window size, but the splitter doesn't seem to return the true value ui->topLevelSplitter->setSizes(QList() << splitterSize - 100 << 100); @@ -812,6 +812,36 @@ void MainWindow::setupActionMenu(QAction* a) tb->setPopupMode(QToolButton::InstantPopup); } +void MainWindow::setupLogMenu() +{ + connect(ui->logList, &QWidget::customContextMenuRequested, [&](auto&& pos){ + auto* menu = new QMenu(ui->logList); + + menu->addAction(tr("Copy& Log"), [&]{ ui->logList->copyToClipboard(); }); + menu->addSeparator(); + + auto* levels = new QMenu(tr("&Level")); + menu->addMenu(levels); + + auto* ag = new QActionGroup(menu); + + auto addAction = [&](auto&& text, auto&& level) { + auto* a = new QAction(text, ag); + a->setCheckable(true); + a->setChecked(log::getDefault().level() == level); + connect(a, &QAction::triggered, [this, level]{ setLogLevel(level); }); + levels->addAction(a); + }; + + addAction(tr("&Errors"), log::Error); + addAction(tr("&Warnings"), log::Warning); + addAction(tr("&Info"), log::Info); + addAction(tr("&Debug"), log::Debug); + + menu->popup(ui->logList->viewport()->mapToGlobal(pos)); + }); +} + void MainWindow::updatePinnedExecutables() { for (auto* a : ui->toolBar->actions()) { @@ -5287,12 +5317,23 @@ void MainWindow::on_actionSettings_triggered() m_statusBar->checkSettings(m_OrganizerCore.settings()); updateDownloadView(); - m_OrganizerCore.updateVFSParams(settings.logLevel(), settings.crashDumpsType(), settings.executablesBlacklist()); + setLogLevel(settings.logLevel()); m_OrganizerCore.cycleDiagnostics(); toggleMO2EndorseState(); } +void MainWindow::setLogLevel(log::Levels level) +{ + auto& s = m_OrganizerCore.settings(); + + s.setLogLevel(level); + + m_OrganizerCore.updateVFSParams( + s.logLevel(), s.crashDumpsType(), s.executablesBlacklist()); + + log::getDefault().setLevel(s.logLevel()); +} void MainWindow::on_actionNexus_triggered() { @@ -6811,7 +6852,7 @@ void MainWindow::on_restoreModsButton_clicked() } } -void MainWindow::on_actionCopy_Log_to_Clipboard_triggered() +void MainWindow::on_actionLogCopy_triggered() { ui->logList->copyToClipboard(); } diff --git a/src/mainwindow.h b/src/mainwindow.h index d7dbfd90..74993667 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -30,6 +30,9 @@ along with Mod Organizer. If not, see . #include "modlistsortproxy.h" #include "savegameinfo.h" #include "tutorialcontrol.h" +#include "plugincontainer.h" //class PluginContainer; +#include "iplugingame.h" //namespace MOBase { class IPluginGame; } +#include //Note the commented headers here can be replaced with forward references, //when I get round to cleaning up main.cpp @@ -38,10 +41,10 @@ class CategoryFactory; class LockedDialogBase; class OrganizerCore; class StatusBar; -#include "plugincontainer.h" //class PluginContainer; + class PluginListSortProxy; namespace BSA { class Archive; } -#include "iplugingame.h" //namespace MOBase { class IPluginGame; } + namespace MOBase { class IPluginModPage; } namespace MOBase { class IPluginTool; } namespace MOBase { class ISaveGame; } @@ -633,10 +636,13 @@ private slots: void search_activated(); void searchClear_activated(); + void setupLogMenu(); void resetActionIcons(); void updateModCount(); void updatePluginCount(); + void setLogLevel(MOBase::log::Levels level); + private slots: // ui slots // actions void on_actionAdd_Profile_triggered(); @@ -690,7 +696,7 @@ private slots: // ui slots void on_restoreButton_clicked(); void on_restoreModsButton_clicked(); void on_saveModsButton_clicked(); - void on_actionCopy_Log_to_Clipboard_triggered(); + void on_actionLogCopy_triggered(); void on_categoriesAndBtn_toggled(bool checked); void on_categoriesOrBtn_toggled(bool checked); void on_managedArchiveLabel_linkHovered(const QString &link); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index c694abd4..fc2bcdd3 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1428,7 +1428,7 @@ p, li { white-space: pre-wrap; } - Qt::ActionsContextMenu + Qt::CustomContextMenu false @@ -1645,20 +1645,6 @@ p, li { white-space: pre-wrap; } Endorse Mod Organizer - - - Copy &Log - - - Copy &Log - - - Copy log to clipboard - - - Copy log to clipboard - - @@ -1771,6 +1757,20 @@ p, li { white-space: pre-wrap; } Log + + + Copy &Log + + + Copy &Log + + + Copy log to clipboard + + + Copy log to clipboard + + diff --git a/src/organizercore.cpp b/src/organizercore.cpp index d3cd54ee..25fbc7cd 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -726,7 +726,9 @@ void OrganizerCore::prepareVFS() m_USVFS.updateMapping(fileMapping(m_CurrentProfile->name(), QString())); } -void OrganizerCore::updateVFSParams(int logLevel, int crashDumpsType, QString executableBlacklist) { +void OrganizerCore::updateVFSParams( + log::Levels logLevel, int crashDumpsType, QString executableBlacklist) +{ setGlobalCrashDumpsType(crashDumpsType); m_USVFS.updateParams(logLevel, crashDumpsType, executableBlacklist); } diff --git a/src/organizercore.h b/src/organizercore.h index 99b1c5f2..ef1a4133 100644 --- a/src/organizercore.h +++ b/src/organizercore.h @@ -21,6 +21,7 @@ #include #include #include "executableinfo.h" +#include class ModListSortProxy; class PluginListSortProxy; @@ -191,7 +192,9 @@ public: void prepareVFS(); - void updateVFSParams(int logLevel, int crashDumpsType, QString executableBlacklist); + void updateVFSParams( + MOBase::log::Levels logLevel, int crashDumpsType, + QString executableBlacklist); bool cycleDiagnostics(); diff --git a/src/settings.cpp b/src/settings.cpp index 5cb2524f..e622d632 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -415,9 +415,14 @@ bool Settings::offlineMode() const return m_Settings.value("Settings/offline_mode", false).toBool(); } -int Settings::logLevel() const +log::Levels Settings::logLevel() const { - return m_Settings.value("Settings/log_level", static_cast(LogLevel::Info)).toInt(); + return static_cast(m_Settings.value("Settings/log_level").toInt()); +} + +void Settings::setLogLevel(log::Levels level) +{ + m_Settings.setValue("Settings/log_level", static_cast(level)); } int Settings::crashDumpsType() const @@ -1000,7 +1005,7 @@ Settings::DiagnosticsTab::DiagnosticsTab(Settings *m_parent, SettingsDialog &m_d , m_dumpsMaxEdit(m_dialog.findChild("dumpsMaxEdit")) , m_diagnosticsExplainedLabel(m_dialog.findChild("diagnosticsExplainedLabel")) { - m_logLevelBox->setCurrentIndex(m_parent->logLevel()); + setLevelsBox(); m_dumpsTypeBox->setCurrentIndex(m_parent->crashDumpsType()); m_dumpsMaxEdit->setValue(m_parent->crashDumpsMax()); QString logsPath = qApp->property("dataPath").toString() @@ -1016,11 +1021,28 @@ Settings::DiagnosticsTab::DiagnosticsTab(Settings *m_parent, SettingsDialog &m_d void Settings::DiagnosticsTab::update() { - m_Settings.setValue("Settings/log_level", m_logLevelBox->currentIndex()); + m_Settings.setValue("Settings/log_level", m_logLevelBox->currentData().toInt()); m_Settings.setValue("Settings/crash_dumps_type", m_dumpsTypeBox->currentIndex()); m_Settings.setValue("Settings/crash_dumps_max", m_dumpsMaxEdit->value()); } +void Settings::DiagnosticsTab::setLevelsBox() +{ + m_logLevelBox->clear(); + + m_logLevelBox->addItem(tr("Debug"), log::Debug); + m_logLevelBox->addItem(tr("Info (recommended)"), log::Info); + m_logLevelBox->addItem(tr("Warning"), log::Warning); + m_logLevelBox->addItem(tr("Error"), log::Error); + + for (int i=0; icount(); ++i) { + if (m_logLevelBox->itemData(i) == m_parent->logLevel()) { + m_logLevelBox->setCurrentIndex(i); + break; + } + } +} + Settings::NexusTab::NexusTab(Settings *parent, SettingsDialog &dialog) : Settings::SettingsTab(parent, dialog) , m_offlineBox(dialog.findChild("offlineBox")) diff --git a/src/settings.h b/src/settings.h index bccd1e81..c66eb94c 100644 --- a/src/settings.h +++ b/src/settings.h @@ -21,6 +21,7 @@ along with Mod Organizer. If not, see . #define SETTINGS_H #include "loadmechanism.h" +#include #include #include @@ -232,7 +233,12 @@ public: /** * @return the configured log level */ - int logLevel() const; + MOBase::log::Levels logLevel() const; + + /** + * sets the log level setting + */ + void setLogLevel(MOBase::log::Levels level); /** * @return the configured crash dumps type @@ -481,6 +487,8 @@ private: QComboBox *m_dumpsTypeBox; QSpinBox *m_dumpsMaxEdit; QLabel *m_diagnosticsExplainedLabel; + + void setLevelsBox(); }; /** Display/store the configuration in the 'nexus' tab of the settings dialogue */ diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index fccc8be0..1e94bcde 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -1426,26 +1426,6 @@ programs you are intentionally running. "Debug" produces very useful information for finding problems. There is usually no noteworthy performance impact but the file may become rather large. If this is a problem you may prefer the "Info" level for regular use. On the "Error" level the log file usually remains empty. - - - Debug - - - - - Info (recommended) - - - - - Warning - - - - - Error - - diff --git a/src/usvfsconnector.cpp b/src/usvfsconnector.cpp index b752667d..197955b8 100644 --- a/src/usvfsconnector.cpp +++ b/src/usvfsconnector.cpp @@ -32,7 +32,7 @@ along with Mod Organizer. If not, see . #include static const char SHMID[] = "mod_organizer_instance"; - +using namespace MOBase; std::string to_hex(void *bufferIn, size_t bufferSize) { @@ -90,15 +90,16 @@ void LogWorker::exit() m_QuitRequested = true; } -LogLevel logLevel(int level) +LogLevel toUsvfsLogLevel(log::Levels level) { - switch (static_cast(level)) { - case LogLevel::Info: + switch (level) { + case log::Info: return LogLevel::Info; - case LogLevel::Warning: + case log::Warning: return LogLevel::Warning; - case LogLevel::Error: + case log::Error: return LogLevel::Error; + case log::Debug: // fall-through default: return LogLevel::Debug; } @@ -121,7 +122,7 @@ CrashDumpsType crashDumpsType(int type) UsvfsConnector::UsvfsConnector() { USVFSParameters params; - LogLevel level = logLevel(Settings::instance().logLevel()); + LogLevel level = toUsvfsLogLevel(Settings::instance().logLevel()); CrashDumpsType dumpType = crashDumpsType(Settings::instance().crashDumpsType()); std::string dumpPath = MOShared::ToString(OrganizerCore::crashDumpsPath(), true); @@ -205,9 +206,10 @@ void UsvfsConnector::updateMapping(const MappingType &mapping) */ } -void UsvfsConnector::updateParams(int logLevel, int crashDumpsType, QString executableBlacklist) +void UsvfsConnector::updateParams( + MOBase::log::Levels logLevel, int crashDumpsType, QString executableBlacklist) { - USVFSUpdateParams(::logLevel(logLevel), ::crashDumpsType(crashDumpsType)); + USVFSUpdateParams(toUsvfsLogLevel(logLevel), ::crashDumpsType(crashDumpsType)); ClearExecutableBlacklist(); for (auto exec : executableBlacklist.split(";")) { std::wstring buf = exec.toStdWString(); diff --git a/src/usvfsconnector.h b/src/usvfsconnector.h index 8a88bde5..b0bd320c 100644 --- a/src/usvfsconnector.h +++ b/src/usvfsconnector.h @@ -29,6 +29,7 @@ along with Mod Organizer. If not, see . #include #include #include +#include #include "executableinfo.h" @@ -84,7 +85,11 @@ public: ~UsvfsConnector(); void updateMapping(const MappingType &mapping); - void updateParams(int logLevel, int crashDumpsType, QString executableBlacklist); + + void updateParams( + MOBase::log::Levels logLevel, int crashDumpsType, + QString executableBlacklist); + void updateForcedLibraries(const QList &forcedLibraries); private: -- cgit v1.3.1 From d91d0caba5fac3b2b27698a5e6ab4a9b60efbf53 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Sat, 20 Jul 2019 09:47:09 -0400 Subject: removed incorrect warning that steam password is unencrypted split steam tab --- src/CMakeLists.txt | 3 +++ src/settings.cpp | 36 +++++----------------------- src/settings.h | 13 ---------- src/settingsdialog.ui | 58 ++++++++++++++++----------------------------- src/settingsdialogsteam.cpp | 17 +++++++++++++ src/settingsdialogsteam.h | 17 +++++++++++++ 6 files changed, 64 insertions(+), 80 deletions(-) create mode 100644 src/settingsdialogsteam.cpp create mode 100644 src/settingsdialogsteam.h (limited to 'src/settingsdialog.ui') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b2407e17..a1adf2db 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -40,6 +40,7 @@ SET(organizer_SRCS settingsdialoggeneral.cpp settingsdialognexus.cpp settingsdialogpaths.cpp + settingsdialogsteam.cpp settings.cpp selfupdater.cpp selectiondialog.cpp @@ -157,6 +158,7 @@ SET(organizer_HDRS settingsdialoggeneral.h settingsdialognexus.h settingsdialogpaths.h + settingsdialogsteam.h settings.h selfupdater.h selectiondialog.h @@ -440,6 +442,7 @@ set(settings settingsdialoggeneral settingsdialognexus settingsdialogpaths + settingsdialogsteam ) set(utilities diff --git a/src/settings.cpp b/src/settings.cpp index bded470c..26c9720a 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -25,6 +25,7 @@ along with Mod Organizer. If not, see . #include "settingsdialoggeneral.h" #include "settingsdialognexus.h" #include "settingsdialogpaths.h" +#include "settingsdialogsteam.h" #include "versioninfo.h" #include "appconfig.h" #include "organizercore.h" @@ -391,15 +392,10 @@ bool Settings::hasNexusApiKey() const bool Settings::getSteamLogin(QString &username, QString &password) const { - if (m_Settings.contains("Settings/steam_username")) { - QString tempPass = deObfuscate("steam_password"); - if (!tempPass.isEmpty()) { - username = m_Settings.value("Settings/steam_username").toString(); - password = tempPass; - return true; - } - } - return false; + username = m_Settings.value("Settings/steam_username", "").toString(); + password = deObfuscate("steam_password"); + + return !username.isEmpty() && !password.isEmpty(); } bool Settings::compactDownloads() const { @@ -680,7 +676,7 @@ void Settings::query(PluginContainer *pluginContainer, QWidget *parent) tabs.push_back(std::unique_ptr(new PathsSettingsTab(this, dialog))); tabs.push_back(std::unique_ptr(new DiagnosticsTab(this, dialog))); tabs.push_back(std::unique_ptr(new NexusSettingsTab(this, dialog))); - tabs.push_back(std::unique_ptr(new SteamTab(this, dialog))); + tabs.push_back(std::unique_ptr(new SteamSettingsTab(this, dialog))); tabs.push_back(std::unique_ptr(new PluginsTab(this, dialog))); tabs.push_back(std::unique_ptr(new WorkaroundsTab(this, dialog))); @@ -770,26 +766,6 @@ void Settings::DiagnosticsTab::update() } -Settings::SteamTab::SteamTab(Settings *m_parent, SettingsDialog &m_dialog) - : SettingsTab(m_parent, m_dialog) - , m_steamUserEdit(m_dialog.findChild("steamUserEdit")) - , m_steamPassEdit(m_dialog.findChild("steamPassEdit")) -{ - if (m_Settings.contains("Settings/steam_username")) { - m_steamUserEdit->setText(m_Settings.value("Settings/steam_username", "").toString()); - QString password = deObfuscate("steam_password"); - if (!password.isEmpty()) { - m_steamPassEdit->setText(password); - } - } -} - -void Settings::SteamTab::update() -{ - //FIXME this should be inlined here? - m_parent->setSteamLogin(m_steamUserEdit->text(), m_steamPassEdit->text()); -} - Settings::PluginsTab::PluginsTab(Settings *m_parent, SettingsDialog &m_dialog) : SettingsTab(m_parent, m_dialog) , m_pluginsList(m_dialog.findChild("pluginsList")) diff --git a/src/settings.h b/src/settings.h index b9383ce4..5bf705d1 100644 --- a/src/settings.h +++ b/src/settings.h @@ -461,19 +461,6 @@ private: void setLevelsBox(); }; - /** Display/store the configuration in the 'steam' tab of the settings dialogue */ - class SteamTab : public SettingsTab - { - public: - SteamTab(Settings *m_parent, SettingsDialog &m_dialog); - - void update(); - - private: - QLineEdit *m_steamUserEdit; - QLineEdit *m_steamPassEdit; - }; - /** Display/store the configuration in the 'plugins' tab of the settings dialogue */ class PluginsTab : public SettingsTab { diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 1e94bcde..3ad525e1 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -828,71 +828,55 @@ If you use pre-releases, never contact me directly by e-mail or via private mess Steam - + Username - - - - - - - Password - - - - - - - QLineEdit::Password - - - - - + + Qt::Vertical - QSizePolicy::Minimum + QSizePolicy::Expanding 20 - 40 + 232 - + + + + - If you save your steam user ID and password here, they will be used when logging into steam. Note, however, your password will be stored unencrypted, so make sure your computer is secure. + <html><head/><body><p>If you save your steam user ID and password here, they will be used when logging into steam.</p></body></html> true - - - - Qt::Vertical - - - QSizePolicy::Expanding + + + + Password - - - 20 - 232 - + + + + + + QLineEdit::Password - + diff --git a/src/settingsdialogsteam.cpp b/src/settingsdialogsteam.cpp new file mode 100644 index 00000000..34c2d76b --- /dev/null +++ b/src/settingsdialogsteam.cpp @@ -0,0 +1,17 @@ +#include "settingsdialogsteam.h" +#include "ui_settingsdialog.h" + +SteamSettingsTab::SteamSettingsTab(Settings *m_parent, SettingsDialog &m_dialog) + : SettingsTab(m_parent, m_dialog) +{ + QString username, password; + m_parent->getSteamLogin(username, password); + + ui->steamUserEdit->setText(username); + ui->steamPassEdit->setText(password); +} + +void SteamSettingsTab::update() +{ + m_parent->setSteamLogin(ui->steamUserEdit->text(), ui->steamPassEdit->text()); +} diff --git a/src/settingsdialogsteam.h b/src/settingsdialogsteam.h new file mode 100644 index 00000000..dbd85151 --- /dev/null +++ b/src/settingsdialogsteam.h @@ -0,0 +1,17 @@ +#ifndef SETTINGSDIALOGSTEAM_H +#define SETTINGSDIALOGSTEAM_H + +#include "settings.h" +#include "settingsdialog.h" + +class SteamSettingsTab : public SettingsTab +{ +public: + SteamSettingsTab(Settings *m_parent, SettingsDialog &m_dialog); + + void update(); + +private: +}; + +#endif // SETTINGSDIALOGSTEAM_H -- cgit v1.3.1 From e8d7930edacdc04a4607ecd59fc402f2f04ea39d Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Sat, 20 Jul 2019 10:59:07 -0400 Subject: split diagnostics tab fixed log and crash dump directory links in label not working --- src/CMakeLists.txt | 3 +++ src/settings.cpp | 32 ++------------------------------ src/settings.h | 18 ------------------ src/settingsdialog.ui | 3 +++ src/settingsdialogdiagnostics.cpp | 28 ++++++++++++++++++++++++++++ src/settingsdialogdiagnostics.h | 17 +++++++++++++++++ 6 files changed, 53 insertions(+), 48 deletions(-) create mode 100644 src/settingsdialogdiagnostics.cpp create mode 100644 src/settingsdialogdiagnostics.h (limited to 'src/settingsdialog.ui') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 86ef9721..d8316e7e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -37,6 +37,7 @@ SET(organizer_SRCS spawn.cpp singleinstance.cpp settingsdialog.cpp + settingsdialogdiagnostics.cpp settingsdialoggeneral.cpp settingsdialognexus.cpp settingsdialogpaths.cpp @@ -157,6 +158,7 @@ SET(organizer_HDRS spawn.h singleinstance.h settingsdialog.h + settingsdialogdiagnostics.h settingsdialoggeneral.h settingsdialognexus.h settingsdialogpaths.h @@ -443,6 +445,7 @@ set(profiles set(settings settings settingsdialog + settingsdialogdiagnostics settingsdialoggeneral settingsdialognexus settingsdialogpaths diff --git a/src/settings.cpp b/src/settings.cpp index 515ff907..725b7e06 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -22,6 +22,7 @@ along with Mod Organizer. If not, see . #include "pluginsetting.h" #include "serverinfo.h" #include "settingsdialog.h" +#include "settingsdialogdiagnostics.h" #include "settingsdialoggeneral.h" #include "settingsdialognexus.h" #include "settingsdialogpaths.h" @@ -676,7 +677,7 @@ void Settings::query(PluginContainer *pluginContainer, QWidget *parent) tabs.push_back(std::unique_ptr(new GeneralSettingsTab(this, dialog))); tabs.push_back(std::unique_ptr(new PathsSettingsTab(this, dialog))); - tabs.push_back(std::unique_ptr(new DiagnosticsTab(this, dialog))); + tabs.push_back(std::unique_ptr(new DiagnosticsSettingsTab(this, dialog))); tabs.push_back(std::unique_ptr(new NexusSettingsTab(this, dialog))); tabs.push_back(std::unique_ptr(new SteamSettingsTab(this, dialog))); tabs.push_back(std::unique_ptr(new PluginsSettingsTab(this, dialog))); @@ -742,32 +743,3 @@ void Settings::query(PluginContainer *pluginContainer, QWidget *parent) } } - - -Settings::DiagnosticsTab::DiagnosticsTab(Settings *m_parent, SettingsDialog &m_dialog) - : SettingsTab(m_parent, m_dialog) - , m_logLevelBox(m_dialog.findChild("logLevelBox")) - , m_dumpsTypeBox(m_dialog.findChild("dumpsTypeBox")) - , m_dumpsMaxEdit(m_dialog.findChild("dumpsMaxEdit")) - , m_diagnosticsExplainedLabel(m_dialog.findChild("diagnosticsExplainedLabel")) -{ - setLevelsBox(); - m_dumpsTypeBox->setCurrentIndex(m_parent->crashDumpsType()); - m_dumpsMaxEdit->setValue(m_parent->crashDumpsMax()); - QString logsPath = qApp->property("dataPath").toString() - + "/" + QString::fromStdWString(AppConfig::logPath()); - m_diagnosticsExplainedLabel->setText( - m_diagnosticsExplainedLabel->text() - .replace("LOGS_FULL_PATH", logsPath) - .replace("LOGS_DIR", QString::fromStdWString(AppConfig::logPath())) - .replace("DUMPS_FULL_PATH", QString::fromStdWString(OrganizerCore::crashDumpsPath())) - .replace("DUMPS_DIR", QString::fromStdWString(AppConfig::dumpsDir())) - ); -} - -void Settings::DiagnosticsTab::update() -{ - m_Settings.setValue("Settings/log_level", m_logLevelBox->currentData().toInt()); - m_Settings.setValue("Settings/crash_dumps_type", m_dumpsTypeBox->currentIndex()); - m_Settings.setValue("Settings/crash_dumps_max", m_dumpsMaxEdit->value()); -} diff --git a/src/settings.h b/src/settings.h index 64068173..71fbcbc1 100644 --- a/src/settings.h +++ b/src/settings.h @@ -449,24 +449,6 @@ private: void readPluginBlacklist(); QString getConfigurablePath(const QString &key, const QString &def, bool resolve) const; - - - class DiagnosticsTab : public SettingsTab - { - public: - DiagnosticsTab(Settings *parent, SettingsDialog &dialog); - - void update(); - - private: - QComboBox *m_logLevelBox; - QComboBox *m_dumpsTypeBox; - QSpinBox *m_dumpsMaxEdit; - QLabel *m_diagnosticsExplainedLabel; - - void setLevelsBox(); - }; - private slots: signals: diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 3ad525e1..1deac400 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -1325,6 +1325,9 @@ programs you are intentionally running. true + + true + diff --git a/src/settingsdialogdiagnostics.cpp b/src/settingsdialogdiagnostics.cpp new file mode 100644 index 00000000..2ea4d478 --- /dev/null +++ b/src/settingsdialogdiagnostics.cpp @@ -0,0 +1,28 @@ +#include "settingsdialogdiagnostics.h" +#include "ui_settingsdialog.h" +#include "appconfig.h" +#include "organizercore.h" + +DiagnosticsSettingsTab::DiagnosticsSettingsTab(Settings *m_parent, SettingsDialog &m_dialog) + : SettingsTab(m_parent, m_dialog) +{ + ui->logLevelBox->setCurrentIndex(m_parent->logLevel()); + ui->dumpsTypeBox->setCurrentIndex(m_parent->crashDumpsType()); + ui->dumpsMaxEdit->setValue(m_parent->crashDumpsMax()); + QString logsPath = qApp->property("dataPath").toString() + + "/" + QString::fromStdWString(AppConfig::logPath()); + ui->diagnosticsExplainedLabel->setText( + ui->diagnosticsExplainedLabel->text() + .replace("LOGS_FULL_PATH", logsPath) + .replace("LOGS_DIR", QString::fromStdWString(AppConfig::logPath())) + .replace("DUMPS_FULL_PATH", QString::fromStdWString(OrganizerCore::crashDumpsPath())) + .replace("DUMPS_DIR", QString::fromStdWString(AppConfig::dumpsDir())) + ); +} + +void DiagnosticsSettingsTab::update() +{ + m_Settings.setValue("Settings/log_level", ui->logLevelBox->currentIndex()); + m_Settings.setValue("Settings/crash_dumps_type", ui->dumpsTypeBox->currentIndex()); + m_Settings.setValue("Settings/crash_dumps_max", ui->dumpsMaxEdit->value()); +} diff --git a/src/settingsdialogdiagnostics.h b/src/settingsdialogdiagnostics.h new file mode 100644 index 00000000..2341c253 --- /dev/null +++ b/src/settingsdialogdiagnostics.h @@ -0,0 +1,17 @@ +#ifndef SETTINGSDIALOGDIAGNOSTICS_H +#define SETTINGSDIALOGDIAGNOSTICS_H + +#include "settings.h" +#include "settingsdialog.h" + +class DiagnosticsSettingsTab : public SettingsTab +{ +public: + DiagnosticsSettingsTab(Settings *parent, SettingsDialog &dialog); + + void update(); + +private: +}; + +#endif // SETTINGSDIALOGDIAGNOSTICS_H -- cgit v1.3.1 From 712c8687c208629e22ef7b4d8015c899c2ea053a Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Fri, 2 Aug 2019 05:33:57 -0400 Subject: changed old whatsthis for prerelease apparently, QFontMetrics::width() is deprecated --- src/loglist.cpp | 3 ++- src/settingsdialog.ui | 6 +----- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/loglist.cpp b/src/loglist.cpp index 192913b6..c884be49 100644 --- a/src/loglist.cpp +++ b/src/loglist.cpp @@ -162,7 +162,8 @@ LogList::LogList(QWidget* parent) { setModel(&LogModel::instance()); - const int timestampWidth = QFontMetrics(font()).width("00:00:00.000"); + const QFontMetrics fm(font()); + const int timestampWidth = fm.horizontalAdvance("00:00:00.000"); header()->setMinimumSectionSize(0); header()->resizeSection(0, 20); diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 1deac400..e011542e 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -76,11 +76,7 @@ p, li { white-space: pre-wrap; } Update to non-stable releases. - If this is enabled, the integrated update mechanism will notify of all releases, including pre-releases (alphas, betas). - -Please use this only if you're sufficiently tech-savvy to investigate issues, look for known problems in the issue tracker and create meaningful reports. - -If you use pre-releases, never contact me directly by e-mail or via private messages! + If this is enabled, the integrated update mechanism will notify of all releases, including pre-releases (alphas, betas). Please use this only if you're sufficiently tech-savvy to investigate issues, look for known problems in the issue tracker and create meaningful reports. Install Pre-releases (Betas) -- cgit v1.3.1 From 3ca0a9fe1e7b751ecda37de53f9a01c88fcb576c Mon Sep 17 00:00:00 2001 From: erri120 Date: Wed, 14 Aug 2019 15:38:31 +0000 Subject: Updated string of the hideAPICounterBox The api counter box is in the bottom right corner since the last update. This change reflects that. --- src/settingsdialog.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index e011542e..660cae92 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -718,10 +718,10 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p>By default, a counter is displayed under the mod list. This informs the user of their remaining API requests. The Nexus API becomes unusable once these API requests run out. Checking this option will hide that counter.</p></body></html> + <html><head/><body><p>By default, a counter is displayed in the bottom right corner. This informs the user of their remaining API requests. The Nexus API becomes unusable once these API requests run out. Checking this option will hide that counter.</p></body></html> - <html><head/><body><p>By default, a counter is displayed under the mod list. This informs the user of their remaining API requests. The Nexus API becomes unusable once these API requests run out. Checking this option will hide that counter.</p></body></html> + <html><head/><body><p>By default, a counter is displayed in the bottom right corner. This informs the user of their remaining API requests. The Nexus API becomes unusable once these API requests run out. Checking this option will hide that counter.</p></body></html> Hide API Request Counter -- cgit v1.3.1 From a5cb39aaf44b1f84003fb2ec2d36f07bf28916e4 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Fri, 16 Aug 2019 08:02:14 -0400 Subject: moved all geometry save, restore and reset to GeometrySettings changed reset button in settings to restart immediately --- src/browserdialog.cpp | 3 +- src/main.cpp | 12 ++++-- src/mainwindow.cpp | 75 +++++++++++-------------------------- src/mainwindow.h | 1 - src/overwriteinfodialog.cpp | 4 +- src/settings.cpp | 79 ++++++++++++++++++++++++++------------- src/settings.h | 39 +++++++++---------- src/settingsdialog.cpp | 11 +----- src/settingsdialog.h | 2 - src/settingsdialog.ui | 3 -- src/settingsdialogworkarounds.cpp | 16 ++++++-- 11 files changed, 121 insertions(+), 124 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/browserdialog.cpp b/src/browserdialog.cpp index 73a6a2d0..70da0b9c 100644 --- a/src/browserdialog.cpp +++ b/src/browserdialog.cpp @@ -72,7 +72,7 @@ BrowserDialog::~BrowserDialog() void BrowserDialog::closeEvent(QCloseEvent *event) { -// m_AccessManager->showCookies(); + Settings::instance().geometry().saveGeometry(this); QDialog::closeEvent(event); } @@ -126,6 +126,7 @@ void BrowserDialog::urlChanged(const QUrl &url) void BrowserDialog::openUrl(const QUrl &url) { if (isHidden()) { + Settings::instance().geometry().restoreGeometry(this); show(); } openInNewTab(url); diff --git a/src/main.cpp b/src/main.cpp index 8eee41e4..6d4108fa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -718,6 +718,7 @@ int runApplication(MOApplication &application, SingleInstance &instance, } int res = 1; + { // scope to control lifetime of mainwindow // set up main window and its data structures MainWindow mainWindow(settings, organizer, pluginContainer); @@ -743,17 +744,20 @@ int runApplication(MOApplication &application, SingleInstance &instance, splash.finish(&mainWindow); - const auto ret = application.exec(); + res = application.exec(); NexusInterface::instance(&pluginContainer) ->getAccessManager()->setTopLevelWidget(nullptr); - - return ret; } + + settings.geometry().resetIfNeeded(); + return res; + } catch (const std::exception &e) { reportError(e.what()); - return 1; } + + return 1; } int doCoreDump(env::CoreDumpTypes type) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 6e6e3d22..28e1de2e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -366,9 +366,11 @@ MainWindow::MainWindow(Settings &settings initDownloadView(); - const bool pluginListAdjusted = settings.restoreState(ui->espList->header()); - settings.restoreState(ui->dataTree->header()); - settings.restoreState(ui->downloadView->header()); + const bool pluginListAdjusted = + settings.geometry().restoreState(ui->espList->header()); + + settings.geometry().restoreState(ui->dataTree->header()); + settings.geometry().restoreState(ui->downloadView->header()); ui->splitter->setStretchFactor(0, 3); ui->splitter->setStretchFactor(1, 2); @@ -575,7 +577,7 @@ void MainWindow::setupModList() ui->modList->header()->installEventFilter(m_OrganizerCore.modList()); - if (m_OrganizerCore.settings().restoreState(ui->modList->header())) { + if (m_OrganizerCore.settings().geometry().restoreState(ui->modList->header())) { // hack: force the resize-signal to be triggered because restoreState doesn't seem to do that for (int column = 0; column <= ModList::COL_LASTCOLUMN; ++column) { int sectionSize = ui->modList->header()->sectionSize(column); @@ -1417,12 +1419,6 @@ void MainWindow::cleanup() m_MetaSave.waitForFinished(); } - -void MainWindow::setBrowserGeometry(const QByteArray &geometry) -{ - m_IntegratedBrowser.restoreGeometry(geometry); -} - void MainWindow::displaySaveGameInfo(QListWidgetItem *newItem) { // don't display the widget if the main window doesn't have focus @@ -2259,10 +2255,10 @@ void MainWindow::activateProxy(bool activate) void MainWindow::readSettings(const Settings& settings) { - settings.restoreGeometry(this); - settings.restoreState(this); + settings.geometry().restoreGeometry(this); + settings.geometry().restoreState(this); settings.geometry().restoreToolbars(this); - settings.restoreState(ui->splitter); + settings.geometry().restoreState(ui->splitter); if (auto v=settings.geometry().getMenubarVisible()) { showMenuBar(*v); @@ -2340,38 +2336,22 @@ void MainWindow::storeSettings(Settings& s) { settings.setValue("selected_executable", ui->executablesListBox->currentIndex()); - if (settings.value("reset_geometry", false).toBool()) { - settings.remove("window_geometry"); - settings.remove("window_state"); - settings.remove("toolbar_size"); - settings.remove("toolbar_button_style"); - settings.remove("menubar_visible"); - settings.remove("window_split"); - settings.remove("window_monitor"); - settings.remove("filters_visible"); - settings.remove("browser_geometry"); - settings.remove("geometry"); - settings.remove("reset_geometry"); - } else { - s.saveState(this); - s.saveGeometry(this); - - s.geometry().setMenubarVisible(m_menuBarVisible); - s.geometry().saveToolbars(this); - s.geometry().setStatusbarVisible(m_statusBarVisible); - s.saveState(ui->splitter); - s.geometry().saveMainWindowMonitor(this); + s.geometry().saveState(this); + s.geometry().saveGeometry(this); - settings.setValue("browser_geometry", m_IntegratedBrowser.saveGeometry()); - settings.setValue("filters_visible", ui->displayCategoriesBtn->isChecked()); + s.geometry().setMenubarVisible(m_menuBarVisible); + s.geometry().saveToolbars(this); + s.geometry().setStatusbarVisible(m_statusBarVisible); + s.geometry().saveState(ui->splitter); + s.geometry().saveMainWindowMonitor(this); + s.geometry().setFiltersVisible(ui->displayCategoriesBtn->isChecked()); - s.saveState(ui->espList->header()); - s.saveState(ui->dataTree->header()); - s.saveState(ui->downloadView->header()); - s.saveState(ui->modList->header()); + s.geometry().saveState(ui->espList->header()); + s.geometry().saveState(ui->dataTree->header()); + s.geometry().saveState(ui->downloadView->header()); + s.geometry().saveState(ui->modList->header()); - DockFixer::save(this, s); - } + DockFixer::save(this, s); } ILockedWaitingForProcess* MainWindow::lock() @@ -6489,7 +6469,6 @@ void MainWindow::processLOOTOut(const std::string &lootOut, std::string &errorMe void MainWindow::on_bossButton_clicked() { - std::string reportURL; std::string errorMessages; //m_OrganizerCore.currentProfile()->writeModlistNow(); @@ -6637,16 +6616,6 @@ void MainWindow::on_bossButton_clicked() if (success) { m_DidUpdateMasterList = true; - if (reportURL.length() > 0) { - m_IntegratedBrowser.setWindowTitle("LOOT Report"); - QString report(reportURL.c_str()); - QStringList temp = report.split("?"); - QUrl url = QUrl::fromLocalFile(temp.at(0)); - if (temp.size() > 1) { - url.setQuery(temp.at(1).toUtf8()); - } - m_IntegratedBrowser.openUrl(url); - } m_OrganizerCore.refreshESPList(false); m_OrganizerCore.savePluginList(); } diff --git a/src/mainwindow.h b/src/mainwindow.h index 946a341b..8542dc8a 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -293,7 +293,6 @@ private: static void setupNetworkProxy(bool activate); void activateProxy(bool activate); - void setBrowserGeometry(const QByteArray &geometry); bool createBackup(const QString &filePath, const QDateTime &time); QString queryRestore(const QString &filePath); diff --git a/src/overwriteinfodialog.cpp b/src/overwriteinfodialog.cpp index 47416311..fe1d8825 100644 --- a/src/overwriteinfodialog.cpp +++ b/src/overwriteinfodialog.cpp @@ -106,13 +106,13 @@ OverwriteInfoDialog::~OverwriteInfoDialog() void OverwriteInfoDialog::showEvent(QShowEvent* e) { - Settings::instance().restoreGeometry(this); + Settings::instance().geometry().restoreGeometry(this); QDialog::showEvent(e); } void OverwriteInfoDialog::done(int r) { - Settings::instance().saveGeometry(this); + Settings::instance().geometry().saveGeometry(this); QDialog::done(r); } diff --git a/src/settings.cpp b/src/settings.cpp index a3d12070..db6cecdf 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -884,6 +884,7 @@ void Settings::dump() const m_Settings.endGroup(); } + QString widgetNameWithTopLevel(const QWidget* widget) { QStringList components; @@ -941,12 +942,46 @@ QString stateSettingName(const Widget* widget) return "geometry/" + widgetName(widget) + "_state"; } -void Settings::saveGeometry(const QWidget* w) + +GeometrySettings::GeometrySettings(QSettings& s) + : m_Settings(s), m_Reset(false) +{ +} + +void GeometrySettings::requestReset() +{ + m_Reset = true; +} + +void GeometrySettings::resetIfNeeded() +{ + if (!m_Reset) { + return; + } + + m_Settings.beginGroup("geometry"); + m_Settings.remove(""); + m_Settings.endGroup(); + + /*settings.remove("window_geometry"); + settings.remove("window_state"); + settings.remove("toolbar_size"); + settings.remove("toolbar_button_style"); + settings.remove("menubar_visible"); + settings.remove("window_split"); + settings.remove("window_monitor"); + settings.remove("filters_visible"); + settings.remove("browser_geometry"); + settings.remove("geometry"); + settings.remove("reset_geometry");*/ +} + +void GeometrySettings::saveGeometry(const QWidget* w) { m_Settings.setValue(geoSettingName(w), w->saveGeometry()); } -bool Settings::restoreGeometry(QWidget* w) const +bool GeometrySettings::restoreGeometry(QWidget* w) const { if (auto v=getOptional(m_Settings, geoSettingName(w))) { w->restoreGeometry(*v); @@ -956,12 +991,12 @@ bool Settings::restoreGeometry(QWidget* w) const return false; } -void Settings::saveState(const QMainWindow* w) +void GeometrySettings::saveState(const QMainWindow* w) { m_Settings.setValue(stateSettingName(w), w->saveState()); } -bool Settings::restoreState(QMainWindow* w) const +bool GeometrySettings::restoreState(QMainWindow* w) const { if (auto v=getOptional(m_Settings, stateSettingName(w))) { w->restoreState(*v); @@ -971,12 +1006,12 @@ bool Settings::restoreState(QMainWindow* w) const return false; } -void Settings::saveState(const QHeaderView* w) +void GeometrySettings::saveState(const QHeaderView* w) { m_Settings.setValue(stateSettingName(w), w->saveState()); } -bool Settings::restoreState(QHeaderView* w) const +bool GeometrySettings::restoreState(QHeaderView* w) const { if (auto v=getOptional(m_Settings, stateSettingName(w))) { w->restoreState(*v); @@ -986,12 +1021,12 @@ bool Settings::restoreState(QHeaderView* w) const return false; } -void Settings::saveState(const QSplitter* w) +void GeometrySettings::saveState(const QSplitter* w) { m_Settings.setValue(stateSettingName(w), w->saveState()); } -bool Settings::restoreState(QSplitter* w) const +bool GeometrySettings::restoreState(QSplitter* w) const { if (auto v=getOptional(m_Settings, stateSettingName(w))) { w->restoreState(*v); @@ -1001,12 +1036,6 @@ bool Settings::restoreState(QSplitter* w) const return false; } - -GeometrySettings::GeometrySettings(QSettings& s) - : m_Settings(s) -{ -} - bool GeometrySettings::restoreToolbars(QMainWindow* w) const { const auto size = getOptional(m_Settings, "toolbar_size"); @@ -1068,6 +1097,11 @@ std::optional GeometrySettings::getFiltersVisible() const return getOptional(m_Settings, "filters_visible"); } +void GeometrySettings::setFiltersVisible(bool b) +{ + m_Settings.setValue("filters_visible", b); +} + QStringList GeometrySettings::getModInfoTabOrder() const { QStringList v; @@ -1106,7 +1140,7 @@ void GeometrySettings::setModInfoTabOrder(const QString& names) std::optional GeometrySettings::getMainWindowMonitor() const { - return getOptional(m_Settings, "geometry/window_monitor"); + return getOptional(m_Settings, "geometry/MainWindow_monitor"); } void GeometrySettings::centerOnMainWindowMonitor(QWidget* w) @@ -1128,34 +1162,29 @@ void GeometrySettings::saveMainWindowMonitor(const QMainWindow* w) if (auto* handle=w->windowHandle()) { if (auto* screen = handle->screen()) { const int screenId = QGuiApplication::screens().indexOf(screen); - m_Settings.setValue("geometry/window_monitor", screenId); + m_Settings.setValue("geometry/MainWindow_monitor", screenId); } } } void GeometrySettings::setDockSize(const QString& name, int size) { - m_Settings.setValue("geometry/" + name + "_size", size); + m_Settings.setValue("geometry/MainWindow_docks_" + name + "_size", size); } std::optional GeometrySettings::getDockSize(const QString& name) const { - return getOptional(m_Settings, "geometry/" + name + "_size"); -} - -std::optional GeometrySettings::isCategoryListVisible() const -{ - return getOptional(m_Settings, "categorylist_visible"); + return getOptional(m_Settings, "geometry/MainWindow_docks_" + name + "_size"); } GeometrySaver::GeometrySaver(Settings& s, QDialog* dialog) : m_settings(s), m_dialog(dialog) { - m_settings.restoreGeometry(m_dialog); + m_settings.geometry().restoreGeometry(m_dialog); } GeometrySaver::~GeometrySaver() { - m_settings.saveGeometry(m_dialog); + m_settings.geometry().saveGeometry(m_dialog); } diff --git a/src/settings.h b/src/settings.h index bbf008f0..9ae58803 100644 --- a/src/settings.h +++ b/src/settings.h @@ -51,6 +51,24 @@ class GeometrySettings public: GeometrySettings(QSettings& s); + void requestReset(); + void resetIfNeeded(); + + void saveGeometry(const QWidget* w); + bool restoreGeometry(QWidget* w) const; + + void saveState(const QMainWindow* window); + bool restoreState(QMainWindow* window) const; + + void saveState(const QHeaderView* header); + bool restoreState(QHeaderView* header) const; + + void saveState(const QToolBar* toolbar); + bool restoreState(QToolBar* toolbar) const; + + void saveState(const QSplitter* splitter); + bool restoreState(QSplitter* splitter) const; + std::optional getMenubarVisible() const; void setMenubarVisible(bool b); @@ -61,6 +79,7 @@ public: void setStatusbarVisible(bool b); std::optional getFiltersVisible() const; + void setFiltersVisible(bool b); QStringList getModInfoTabOrder() const; void setModInfoTabOrder(const QString& names); @@ -73,10 +92,9 @@ public: std::optional getDockSize(const QString& name) const; - std::optional isCategoryListVisible() const; - private: QSettings& m_Settings; + bool m_Reset; }; @@ -210,23 +228,6 @@ public: GeometrySettings& geometry(); const GeometrySettings& geometry() const; - - void saveGeometry(const QWidget* w); - bool restoreGeometry(QWidget* w) const; - - void saveState(const QMainWindow* window); - bool restoreState(QMainWindow* window) const; - - void saveState(const QHeaderView* header); - bool restoreState(QHeaderView* header) const; - - void saveState(const QToolBar* toolbar); - bool restoreState(QToolBar* toolbar) const; - - void saveState(const QSplitter* splitter); - bool restoreState(QSplitter* splitter) const; - - /** * retrieve the directory where profiles stored (with native separators) **/ diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index fbd9ecd1..d74507c9 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -34,7 +34,6 @@ SettingsDialog::SettingsDialog(PluginContainer *pluginContainer, Settings* setti , ui(new Ui::SettingsDialog) , m_settings(settings) , m_PluginContainer(pluginContainer) - , m_GeometriesReset(false) , m_keyChanged(false) { ui->setupUi(this); @@ -101,10 +100,7 @@ int SettingsDialog::exec() if (getApiKeyChanged()) { restartNeeded = true; } - if (getResetGeometries()) { - restartNeeded = true; - qsettings.setValue("reset_geometry", true); - } + if (restartNeeded) { if (QMessageBox::question(nullptr, tr("Restart Mod Organizer?"), @@ -156,11 +152,6 @@ void SettingsDialog::accept() TutorableDialog::accept(); } -bool SettingsDialog::getResetGeometries() -{ - return ui->resetGeometryBtn->isChecked(); -} - bool SettingsDialog::getApiKeyChanged() { return m_keyChanged; diff --git a/src/settingsdialog.h b/src/settingsdialog.h index 03bba7cf..efc4a095 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -71,7 +71,6 @@ public: // temp Ui::SettingsDialog *ui; bool m_keyChanged; - bool m_GeometriesReset; PluginContainer *m_PluginContainer; int exec() override; @@ -81,7 +80,6 @@ public slots: public: bool getApiKeyChanged(); - bool getResetGeometries(); private: Settings* m_settings; diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index e011542e..e7676387 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -1233,9 +1233,6 @@ programs you are intentionally running. Reset Window Geometries - - true - diff --git a/src/settingsdialogworkarounds.cpp b/src/settingsdialogworkarounds.cpp index 9ac46ac1..fc859289 100644 --- a/src/settingsdialogworkarounds.cpp +++ b/src/settingsdialogworkarounds.cpp @@ -26,8 +26,6 @@ WorkaroundsSettingsTab::WorkaroundsSettingsTab(Settings *m_parent, SettingsDialo ui->lockGUIBox->setChecked(m_parent->lockGUI()); ui->enableArchiveParsingBox->setChecked(m_parent->archiveParsing()); - ui->resetGeometryBtn->setChecked(m_parent->directInterface().value("reset_geometry", false).toBool()); - setExecutableBlacklist(m_parent->executablesBlacklist()); QObject::connect(ui->bsaDateBtn, &QPushButton::clicked, [&]{ on_bsaDateBtn_clicked(); }); @@ -89,6 +87,16 @@ void WorkaroundsSettingsTab::on_bsaDateBtn_clicked() void WorkaroundsSettingsTab::on_resetGeometryBtn_clicked() { - m_dialog.m_GeometriesReset = true; - ui->resetGeometryBtn->setChecked(true); + const auto caption = QObject::tr("Restart Mod Organizer?"); + const auto text = QObject::tr( + "In order to reset the geometry, Mod Organizer must be restarted.\n" + "Restart now?"); + + const auto res = QMessageBox::question( + nullptr, caption, text, QMessageBox::Yes | QMessageBox::Cancel); + + if (res == QMessageBox::Yes) { + m_parent->geometry().requestReset(); + qApp->exit(INT_MAX); + } } -- cgit v1.3.1 From 4f1b15f0a1b2e6cbca4b420608d81570af489067 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Sat, 24 Aug 2019 16:07:07 -0400 Subject: changed crash dump type to use enum instead of int added ColorSettings settings dialog general and diag tabs don't use qsettings anymore removed logging of setting changes, will be added back to Settings class --- src/modinfo.cpp | 1 - src/modlist.cpp | 10 +-- src/organizercore.cpp | 6 +- src/organizercore.h | 4 +- src/pluginlist.cpp | 2 +- src/settings.cpp | 160 ++++++++++++++++++++++++++++++-------- src/settings.h | 70 ++++++++++------- src/settingsdialog.cpp | 26 +------ src/settingsdialog.ui | 20 ----- src/settingsdialogdiagnostics.cpp | 38 ++++++++- src/settingsdialogdiagnostics.h | 1 + src/settingsdialoggeneral.cpp | 66 ++++++++-------- src/usvfsconnector.cpp | 7 +- src/usvfsconnector.h | 2 +- 14 files changed, 259 insertions(+), 154 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/modinfo.cpp b/src/modinfo.cpp index 5a05e7ca..e3daa4fd 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -42,7 +42,6 @@ along with Mod Organizer. If not, see . #include #include #include -#include using namespace MOBase; using namespace MOShared; diff --git a/src/modlist.cpp b/src/modlist.cpp index c591c49b..94b4a387 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -416,15 +416,15 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const bool archiveOverwritten = m_ArchiveOverwritten.find(modIndex) != m_ArchiveOverwritten.end(); bool archiveLooseOverwritten = m_ArchiveLooseOverwritten.find(modIndex) != m_ArchiveLooseOverwritten.end(); if (modInfo->getHighlight() & ModInfo::HIGHLIGHT_PLUGIN) { - return Settings::instance().modlistContainsPluginColor(); + return Settings::instance().colors().modlistContainsPlugin(); } else if (overwritten || archiveLooseOverwritten) { - return Settings::instance().modlistOverwritingLooseColor(); + return Settings::instance().colors().modlistOverwritingLoose(); } else if (overwrite || archiveLooseOverwrite) { - return Settings::instance().modlistOverwrittenLooseColor(); + return Settings::instance().colors().modlistOverwrittenLoose(); } else if (archiveOverwritten) { - return Settings::instance().modlistOverwritingArchiveColor(); + return Settings::instance().colors().modlistOverwritingArchive(); } else if (archiveOverwrite) { - return Settings::instance().modlistOverwrittenArchiveColor(); + return Settings::instance().colors().modlistOverwrittenArchive(); } else if (modInfo->hasFlag(ModInfo::FLAG_SEPARATOR) && modInfo->getColor().isValid() && ((role != ViewMarkingScrollBar::DEFAULT_ROLE) diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 73d0abac..5a8ee4c2 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -667,7 +667,7 @@ void OrganizerCore::prepareVFS() } void OrganizerCore::updateVFSParams( - log::Levels logLevel, int crashDumpsType, QString executableBlacklist) + log::Levels logLevel, CrashDumpsType crashDumpsType, QString executableBlacklist) { setGlobalCrashDumpsType(crashDumpsType); m_USVFS.updateParams(logLevel, crashDumpsType, executableBlacklist); @@ -692,8 +692,8 @@ bool OrganizerCore::cycleDiagnostics() { } //static -void OrganizerCore::setGlobalCrashDumpsType(int crashDumpsType) { - m_globalCrashDumpsType = ::crashDumpsType(crashDumpsType); +void OrganizerCore::setGlobalCrashDumpsType(CrashDumpsType type) { + m_globalCrashDumpsType = type; } //static diff --git a/src/organizercore.h b/src/organizercore.h index 4bcfe745..a14d79a9 100644 --- a/src/organizercore.h +++ b/src/organizercore.h @@ -193,7 +193,7 @@ public: void prepareVFS(); void updateVFSParams( - MOBase::log::Levels logLevel, int crashDumpsType, + MOBase::log::Levels logLevel, CrashDumpsType crashDumpsType, QString executableBlacklist); void setLogLevel(MOBase::log::Levels level); @@ -201,7 +201,7 @@ public: bool cycleDiagnostics(); static CrashDumpsType getGlobalCrashDumpsType() { return m_globalCrashDumpsType; } - static void setGlobalCrashDumpsType(int crashDumpsType); + static void setGlobalCrashDumpsType(CrashDumpsType crashDumpsType); static std::wstring crashDumpsPath(); public: diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index 8637f546..ddfe492e 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -931,7 +931,7 @@ QVariant PluginList::data(const QModelIndex &modelIndex, int role) const } else if (role == Qt::BackgroundRole || (role == ViewMarkingScrollBar::DEFAULT_ROLE)) { if (m_ESPs[index].m_ModSelected) { - return Settings::instance().pluginListContainedColor(); + return Settings::instance().colors().pluginListContained(); } else { return QVariant(); } diff --git a/src/settings.cpp b/src/settings.cpp index 844ee81e..2236fc9d 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -24,7 +24,6 @@ along with Mod Organizer. If not, see . #include "expanderwidget.h" #include #include -#include using namespace MOBase; @@ -33,7 +32,13 @@ std::optional getOptional( const QSettings& s, const QString& name, std::optional def={}) { if (s.contains(name)) { - return s.value(name).value(); + const auto v = s.value(name); + + if constexpr (std::is_enum_v) { + return static_cast(v.value>()); + } else { + return v.value(); + } } return def; @@ -160,10 +165,12 @@ void warnIfNotCheckable(const QAbstractButton* b) } } + Settings *Settings::s_Instance = nullptr; -Settings::Settings(const QString& path) - : m_Settings(path, QSettings::IniFormat), m_Geometry(m_Settings) +Settings::Settings(const QString& path) : + m_Settings(path, QSettings::IniFormat), + m_Geometry(m_Settings), m_Colors(m_Settings) { if (s_Instance != nullptr) { throw std::runtime_error("second instance of \"Settings\" created"); @@ -280,6 +287,11 @@ bool Settings::colorSeparatorScrollbar() const return m_Settings.value("Settings/colorSeparatorScrollbars", true).toBool(); } +void Settings::setColorSeparatorScrollbar(bool b) +{ + m_Settings.setValue("Settings/colorSeparatorScrollbars", b); +} + void Settings::managedGameChanged(IPluginGame const *gamePlugin) { m_GamePlugin = gamePlugin; @@ -397,6 +409,11 @@ bool Settings::usePrereleases() const return m_Settings.value("Settings/use_prereleases", false).toBool(); } +void Settings::setUsePrereleases(bool b) +{ + m_Settings.setValue("Settings/use_prereleases", b); +} + void Settings::setDownloadSpeed(const QString &serverName, int bytesPerSecond) { m_Settings.beginGroup("Servers"); @@ -615,16 +632,27 @@ bool Settings::getSteamLogin(QString &username, QString &password) const return !username.isEmpty() && !password.isEmpty(); } + bool Settings::compactDownloads() const { return m_Settings.value("Settings/compact_downloads", false).toBool(); } +void Settings::setCompactDownloads(bool b) +{ + m_Settings.setValue("Settings/compact_downloads", b); +} + bool Settings::metaDownloads() const { return m_Settings.value("Settings/meta_downloads", false).toBool(); } +void Settings::setMetaDownloads(bool b) +{ + m_Settings.setValue("Settings/meta_downloads", b); +} + bool Settings::offlineMode() const { return m_Settings.value("Settings/offline_mode", false).toBool(); @@ -640,44 +668,25 @@ void Settings::setLogLevel(log::Levels level) m_Settings.setValue("Settings/log_level", static_cast(level)); } -int Settings::crashDumpsType() const +CrashDumpsType Settings::crashDumpsType() const { - return m_Settings.value("Settings/crash_dumps_type", static_cast(CrashDumpsType::Mini)).toInt(); + const auto v = getOptional(m_Settings, "Settings/crash_dumps_type"); + return v.value_or(CrashDumpsType::Mini); } -int Settings::crashDumpsMax() const +void Settings::setCrashDumpsType(CrashDumpsType type) { - return m_Settings.value("Settings/crash_dumps_max", 5).toInt(); + m_Settings.setValue("Settings/crash_dumps_type", static_cast(type)); } -QColor Settings::modlistOverwrittenLooseColor() const -{ - return m_Settings.value("Settings/overwrittenLooseFilesColor", QColor(0, 255, 0, 64)).value(); -} - -QColor Settings::modlistOverwritingLooseColor() const -{ - return m_Settings.value("Settings/overwritingLooseFilesColor", QColor(255, 0, 0, 64)).value(); -} - -QColor Settings::modlistOverwrittenArchiveColor() const -{ - return m_Settings.value("Settings/overwrittenArchiveFilesColor", QColor(0, 255, 255, 64)).value(); -} - -QColor Settings::modlistOverwritingArchiveColor() const -{ - return m_Settings.value("Settings/overwritingArchiveFilesColor", QColor(255, 0, 255, 64)).value(); -} - -QColor Settings::modlistContainsPluginColor() const +int Settings::crashDumpsMax() const { - return m_Settings.value("Settings/containsPluginColor", QColor(0, 0, 255, 64)).value(); + return m_Settings.value("Settings/crash_dumps_max", 5).toInt(); } -QColor Settings::pluginListContainedColor() const +void Settings::setCrashDumpsMax(int n) { - return m_Settings.value("Settings/containedColor", QColor(0, 0, 255, 64)).value(); + return m_Settings.setValue("Settings/crash_dumps_max", n); } QString Settings::executablesBlacklist() const @@ -850,6 +859,11 @@ QString Settings::language() return result; } +void Settings::setLanguage(const QString& name) +{ + m_Settings.setValue("Settings/language", name); +} + void Settings::updateServers(const QList &servers) { m_Settings.beginGroup("Servers"); @@ -1132,6 +1146,16 @@ const GeometrySettings& Settings::geometry() const return m_Geometry; } +ColorSettings& Settings::colors() +{ + return m_Colors; +} + +const ColorSettings& Settings::colors() const +{ + return m_Colors; +} + QSettings::Status Settings::sync() const { m_Settings.sync(); @@ -1451,6 +1475,78 @@ void GeometrySettings::restoreDocks(QMainWindow* mw) const } +ColorSettings::ColorSettings(QSettings& s) + : m_Settings(s) +{ +} + +QColor ColorSettings::modlistOverwrittenLoose() const +{ + return getOptional(m_Settings, "Settings/overwrittenLooseFilesColor") + .value_or(QColor(0, 255, 0, 64)); +} + +void ColorSettings::setModlistOverwrittenLoose(const QColor& c) +{ + m_Settings.setValue("Settings/overwrittenLooseFilesColor", c); +} + +QColor ColorSettings::modlistOverwritingLoose() const +{ + return getOptional(m_Settings, "Settings/overwritingLooseFilesColor") + .value_or(QColor(255, 0, 0, 64)); +} + +void ColorSettings::setModlistOverwritingLoose(const QColor& c) +{ + m_Settings.setValue("Settings/overwritingLooseFilesColor", c); +} + +QColor ColorSettings::modlistOverwrittenArchive() const +{ + return getOptional(m_Settings, "Settings/overwrittenArchiveFilesColor") + .value_or(QColor(0, 255, 255, 64)); +} + +void ColorSettings::setModlistOverwrittenArchive(const QColor& c) +{ + m_Settings.setValue("Settings/overwrittenArchiveFilesColor", c); +} + +QColor ColorSettings::modlistOverwritingArchive() const +{ + return getOptional(m_Settings, "Settings/overwritingArchiveFilesColor") + .value_or(QColor(255, 0, 255, 64)); +} + +void ColorSettings::setModlistOverwritingArchive(const QColor& c) +{ + m_Settings.setValue("Settings/overwritingArchiveFilesColor", c); +} + +QColor ColorSettings::modlistContainsPlugin() const +{ + return getOptional(m_Settings, "Settings/containsPluginColor") + .value_or(QColor(0, 0, 255, 64)); +} + +void ColorSettings::setModlistContainsPlugin(const QColor& c) +{ + m_Settings.setValue("Settings/containsPluginColor", c); +} + +QColor ColorSettings::pluginListContained() const +{ + return getOptional(m_Settings, "Settings/containedColor") + .value_or(QColor(0, 0, 255, 64)); +} + +void ColorSettings::setPluginListContained(const QColor& c) +{ + m_Settings.setValue("Settings/containedColor", c); +} + + GeometrySaver::GeometrySaver(Settings& s, QDialog* dialog) : m_settings(s), m_dialog(dialog) { diff --git a/src/settings.h b/src/settings.h index b25af15f..5b1d7bfc 100644 --- a/src/settings.h +++ b/src/settings.h @@ -23,6 +23,7 @@ along with Mod Organizer. If not, see . #include "loadmechanism.h" #include #include +#include namespace MOBase { class IPlugin; @@ -96,6 +97,36 @@ private: }; +class ColorSettings +{ +public: + ColorSettings(QSettings& s); + + void setCrashDumpsMax(int i) const; + + QColor modlistOverwrittenLoose() const; + void setModlistOverwrittenLoose(const QColor& c); + + QColor modlistOverwritingLoose() const; + void setModlistOverwritingLoose(const QColor& c); + + QColor modlistOverwrittenArchive() const; + void setModlistOverwrittenArchive(const QColor& c); + + QColor modlistOverwritingArchive() const; + void setModlistOverwritingArchive(const QColor& c); + + QColor modlistContainsPlugin() const; + void setModlistContainsPlugin(const QColor& c); + + QColor pluginListContained() const; + void setPluginListContained(const QColor& c) ; + +private: + QSettings& m_Settings; +}; + + enum class EndorsementState { Accepted = 1, @@ -268,6 +299,10 @@ public: GeometrySettings& geometry(); const GeometrySettings& geometry() const; + ColorSettings& colors(); + const ColorSettings& colors() const; + + /** * retrieve the directory where profiles stored (with native separators) **/ @@ -329,43 +364,22 @@ public: * @return true if the user chose compact downloads */ bool compactDownloads() const; + void setCompactDownloads(bool b); /** * @return true if the user chose meta downloads */ bool metaDownloads() const; + void setMetaDownloads(bool b); - /** - * @return the configured log level - */ MOBase::log::Levels logLevel() const; - - /** - * sets the log level setting - */ void setLogLevel(MOBase::log::Levels level); - /** - * @return the configured crash dumps type - */ - int crashDumpsType() const; + CrashDumpsType crashDumpsType() const; + void setCrashDumpsType(CrashDumpsType type); - /** - * @return the configured crash dumps max - */ int crashDumpsMax() const; - - QColor modlistOverwrittenLooseColor() const; - - QColor modlistOverwritingLooseColor() const; - - QColor modlistOverwrittenArchiveColor() const; - - QColor modlistOverwritingArchiveColor() const; - - QColor modlistContainsPluginColor() const; - - QColor pluginListContainedColor() const; + void setCrashDumpsMax(int n); QString executablesBlacklist() const; @@ -473,6 +487,7 @@ public: * @return short code of the configured language (corresponding to the translation files) */ QString language(); + void setLanguage(const QString& name); /** * @brief updates the list of known servers @@ -499,6 +514,7 @@ public: std::vector plugins() const { return m_Plugins; } bool usePrereleases() const; + void setUsePrereleases(bool b); /** * @brief register MO as the handler for nxm links @@ -512,6 +528,7 @@ public: * @return the state of the setting */ bool colorSeparatorScrollbar() const; + void setColorSeparatorScrollbar(bool b); static QColor getIdealTextColor(const QColor& rBackgroundColor); @@ -540,6 +557,7 @@ private: MOBase::IPluginGame const *m_GamePlugin; mutable QSettings m_Settings; GeometrySettings m_Geometry; + ColorSettings m_Colors; LoadMechanism m_LoadMechanism; std::vector m_Plugins; diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 097dafc8..9d031785 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -51,43 +51,19 @@ int SettingsDialog::exec() { GeometrySaver gs(m_settings, this); - auto& qsettings = m_settings.directInterface(); auto ret = TutorableDialog::exec(); if (ret == QDialog::Accepted) { - for (auto&& tab : m_tabs) { tab->closing(); } - // remember settings before change - QMap before; - qsettings.beginGroup("Settings"); - for (auto k : qsettings.allKeys()) - before[k] = qsettings.value(k).toString(); - qsettings.endGroup(); - - // transfer modified settings to configuration file + // update settings for each tab for (std::unique_ptr const &tab: m_tabs) { tab->update(); } - - // print "changed" settings - qsettings.beginGroup("Settings"); - bool first_update = true; - for (auto k : qsettings.allKeys()) - if (qsettings.value(k).toString() != before[k] && !k.contains("username") && !k.contains("password")) - { - if (first_update) { - log::debug("Changed settings:"); - first_update = false; - } - log::debug(" {}={}", k, qsettings.value(k).toString()); - } - qsettings.endGroup(); } - // These changes happen regardless of accepted or rejected bool restartNeeded = false; if (getApiKeyChanged()) { restartNeeded = true; diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index e7676387..af230bc0 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -1346,26 +1346,6 @@ programs you are intentionally running. "Full" Even larger dumps with a full memory dump of the process. - - - None - - - - - Mini (recommended) - - - - - Data - - - - - Full - - diff --git a/src/settingsdialogdiagnostics.cpp b/src/settingsdialogdiagnostics.cpp index 227d1dfa..278da0bf 100644 --- a/src/settingsdialogdiagnostics.cpp +++ b/src/settingsdialogdiagnostics.cpp @@ -10,10 +10,13 @@ DiagnosticsSettingsTab::DiagnosticsSettingsTab(Settings& s, SettingsDialog& d) : SettingsTab(s, d) { setLevelsBox(); - ui->dumpsTypeBox->setCurrentIndex(settings().crashDumpsType()); + setCrashDumpTypesBox(); + ui->dumpsMaxEdit->setValue(settings().crashDumpsMax()); + QString logsPath = qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::logPath()); + ui->diagnosticsExplainedLabel->setText( ui->diagnosticsExplainedLabel->text() .replace("LOGS_FULL_PATH", logsPath) @@ -40,9 +43,36 @@ void DiagnosticsSettingsTab::setLevelsBox() } } +void DiagnosticsSettingsTab::setCrashDumpTypesBox() +{ + ui->dumpsTypeBox->clear(); + + auto add = [&](auto&& text, auto&& type) { + ui->dumpsTypeBox->addItem(text, static_cast(type)); + }; + + add(QObject::tr("None"), CrashDumpsType::None); + add(QObject::tr("Mini (recommended)"), CrashDumpsType::Mini); + add(QObject::tr("Data"), CrashDumpsType::Data); + add(QObject::tr("Full"), CrashDumpsType::Full); + + const auto current = static_cast(settings().crashDumpsType()); + + for (int i=0; idumpsTypeBox->count(); ++i) { + if (ui->dumpsTypeBox->itemData(i) == current) { + ui->dumpsTypeBox->setCurrentIndex(i); + break; + } + } +} + void DiagnosticsSettingsTab::update() { - qsettings().setValue("Settings/log_level", ui->logLevelBox->currentData().toInt()); - qsettings().setValue("Settings/crash_dumps_type", ui->dumpsTypeBox->currentIndex()); - qsettings().setValue("Settings/crash_dumps_max", ui->dumpsMaxEdit->value()); + settings().setLogLevel( + static_cast(ui->logLevelBox->currentData().toInt())); + + settings().setCrashDumpsType( + static_cast(ui->dumpsTypeBox->currentData().toInt())); + + settings().setCrashDumpsMax(ui->dumpsMaxEdit->value()); } diff --git a/src/settingsdialogdiagnostics.h b/src/settingsdialogdiagnostics.h index f20413f8..f0fbf770 100644 --- a/src/settingsdialogdiagnostics.h +++ b/src/settingsdialogdiagnostics.h @@ -13,6 +13,7 @@ public: private: void setLevelsBox(); + void setCrashDumpTypesBox(); }; #endif // SETTINGSDIALOGDIAGNOSTICS_H diff --git a/src/settingsdialoggeneral.cpp b/src/settingsdialoggeneral.cpp index 35012db7..e3d73037 100644 --- a/src/settingsdialoggeneral.cpp +++ b/src/settingsdialoggeneral.cpp @@ -26,28 +26,30 @@ GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d) } addStyles(); + { - int currentID = ui->styleBox->findData( - qsettings().value("Settings/style", "").toString()); + const int currentID = ui->styleBox->findData( + settings().getStyleName().value_or("")); + if (currentID != -1) { ui->styleBox->setCurrentIndex(currentID); } } //version with stylesheet - setButtonColor(ui->overwritingBtn, settings().modlistOverwritingLooseColor()); - setButtonColor(ui->overwrittenBtn, settings().modlistOverwrittenLooseColor()); - setButtonColor(ui->overwritingArchiveBtn, settings().modlistOverwritingArchiveColor()); - setButtonColor(ui->overwrittenArchiveBtn, settings().modlistOverwrittenArchiveColor()); - setButtonColor(ui->containsBtn, settings().modlistContainsPluginColor()); - setButtonColor(ui->containedBtn, settings().pluginListContainedColor()); - - setOverwritingColor(settings().modlistOverwritingLooseColor()); - setOverwrittenColor(settings().modlistOverwrittenLooseColor()); - setOverwritingArchiveColor(settings().modlistOverwritingArchiveColor()); - setOverwrittenArchiveColor(settings().modlistOverwrittenArchiveColor()); - setContainsColor(settings().modlistContainsPluginColor()); - setContainedColor(settings().pluginListContainedColor()); + setButtonColor(ui->overwritingBtn, settings().colors().modlistOverwritingLoose()); + setButtonColor(ui->overwrittenBtn, settings().colors().modlistOverwrittenLoose()); + setButtonColor(ui->overwritingArchiveBtn, settings().colors().modlistOverwritingArchive()); + setButtonColor(ui->overwrittenArchiveBtn, settings().colors().modlistOverwrittenArchive()); + setButtonColor(ui->containsBtn, settings().colors().modlistContainsPlugin()); + setButtonColor(ui->containedBtn, settings().colors().pluginListContained()); + + setOverwritingColor(settings().colors().modlistOverwritingLoose()); + setOverwrittenColor(settings().colors().modlistOverwrittenLoose()); + setOverwritingArchiveColor(settings().colors().modlistOverwritingArchive()); + setOverwrittenArchiveColor(settings().colors().modlistOverwrittenArchive()); + setContainsColor(settings().colors().modlistContainsPlugin()); + setContainedColor(settings().colors().pluginListContained()); ui->compactBox->setChecked(settings().compactDownloads()); ui->showMetaBox->setChecked(settings().metaDownloads()); @@ -67,30 +69,32 @@ GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d) void GeneralSettingsTab::update() { - QString oldLanguage = settings().language(); - QString newLanguage = ui->languageBox->itemData(ui->languageBox->currentIndex()).toString(); + const QString oldLanguage = settings().language(); + const QString newLanguage = ui->languageBox->itemData(ui->languageBox->currentIndex()).toString(); + if (newLanguage != oldLanguage) { - qsettings().setValue("Settings/language", newLanguage); + settings().setLanguage(newLanguage); emit settings().languageChanged(newLanguage); } - QString oldStyle = qsettings().value("Settings/style", "").toString(); - QString newStyle = ui->styleBox->itemData(ui->styleBox->currentIndex()).toString(); + const QString oldStyle = settings().getStyleName().value_or(""); + const QString newStyle = ui->styleBox->itemData(ui->styleBox->currentIndex()).toString(); if (oldStyle != newStyle) { - qsettings().setValue("Settings/style", newStyle); + settings().setStyleName(newStyle); emit settings().styleChanged(newStyle); } - qsettings().setValue("Settings/overwritingLooseFilesColor", getOverwritingColor()); - qsettings().setValue("Settings/overwrittenLooseFilesColor", getOverwrittenColor()); - qsettings().setValue("Settings/overwritingArchiveFilesColor", getOverwritingArchiveColor()); - qsettings().setValue("Settings/overwrittenArchiveFilesColor", getOverwrittenArchiveColor()); - qsettings().setValue("Settings/containsPluginColor", getContainsColor()); - qsettings().setValue("Settings/containedColor", getContainedColor()); - qsettings().setValue("Settings/compact_downloads", ui->compactBox->isChecked()); - qsettings().setValue("Settings/meta_downloads", ui->showMetaBox->isChecked()); - qsettings().setValue("Settings/use_prereleases", ui->usePrereleaseBox->isChecked()); - qsettings().setValue("Settings/colorSeparatorScrollbars", ui->colorSeparatorsBox->isChecked()); + settings().colors().setModlistOverwritingLoose(getOverwritingColor()); + settings().colors().setModlistOverwrittenLoose(getOverwrittenColor()); + settings().colors().setModlistOverwritingArchive(getOverwritingArchiveColor()); + settings().colors().setModlistOverwrittenArchive(getOverwrittenArchiveColor()); + settings().colors().setModlistContainsPlugin(getContainsColor()); + settings().colors().setPluginListContained(getContainedColor()); + + settings().setCompactDownloads(ui->compactBox->isChecked()); + settings().setMetaDownloads(ui->showMetaBox->isChecked()); + settings().setUsePrereleases(ui->usePrereleaseBox->isChecked()); + settings().setColorSeparatorScrollbar(ui->colorSeparatorsBox->isChecked()); } void GeneralSettingsTab::addLanguages() diff --git a/src/usvfsconnector.cpp b/src/usvfsconnector.cpp index b5e6edb1..41f58308 100644 --- a/src/usvfsconnector.cpp +++ b/src/usvfsconnector.cpp @@ -164,7 +164,7 @@ UsvfsConnector::UsvfsConnector() { USVFSParameters params; LogLevel level = toUsvfsLogLevel(Settings::instance().logLevel()); - CrashDumpsType dumpType = crashDumpsType(Settings::instance().crashDumpsType()); + CrashDumpsType dumpType = Settings::instance().crashDumpsType(); std::string dumpPath = MOShared::ToString(OrganizerCore::crashDumpsPath(), true); USVFSInitParameters(¶ms, SHMID, false, level, dumpType, dumpPath.c_str()); @@ -249,9 +249,10 @@ void UsvfsConnector::updateMapping(const MappingType &mapping) } void UsvfsConnector::updateParams( - MOBase::log::Levels logLevel, int crashDumpsType, QString executableBlacklist) + MOBase::log::Levels logLevel, CrashDumpsType crashDumpsType, + QString executableBlacklist) { - USVFSUpdateParams(toUsvfsLogLevel(logLevel), ::crashDumpsType(crashDumpsType)); + USVFSUpdateParams(toUsvfsLogLevel(logLevel), crashDumpsType); ClearExecutableBlacklist(); for (auto exec : executableBlacklist.split(";")) { std::wstring buf = exec.toStdWString(); diff --git a/src/usvfsconnector.h b/src/usvfsconnector.h index b0bd320c..cd5d56b2 100644 --- a/src/usvfsconnector.h +++ b/src/usvfsconnector.h @@ -87,7 +87,7 @@ public: void updateMapping(const MappingType &mapping); void updateParams( - MOBase::log::Levels logLevel, int crashDumpsType, + MOBase::log::Levels logLevel, CrashDumpsType crashDumpsType, QString executableBlacklist); void updateForcedLibraries(const QList &forcedLibraries); -- cgit v1.3.1 From 9bac57e3e864bd300fadccfaa194a6f3d28c9de2 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Thu, 19 Sep 2019 15:03:03 -0400 Subject: steam confirmation now using TaskDialog fixed dialog choices not remembering files --- src/settings.cpp | 2 +- src/settingsdialog.ui | 2 +- src/spawn.cpp | 95 ++++++++++++++++++++++++++++++++++----------------- 3 files changed, 65 insertions(+), 34 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/settings.cpp b/src/settings.cpp index ae487c18..7cea52fb 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -946,7 +946,7 @@ QuestionBoxMemory::Button WidgetSettings::questionButton( if (!filename.isEmpty()) { const auto fileSetting = windowName + "/" + filename; - if (auto v=getOptional(m_Settings, sectionName, filename)) { + if (auto v=getOptional(m_Settings, sectionName, fileSetting)) { return static_cast(*v); } } diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 1a3726fb..40079441 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -191,7 +191,7 @@ p, li { white-space: pre-wrap; } This will make all dialogs show up again where you checked the "Remember selection"-box. - Reset Dialogs + Reset Dialog Choices diff --git a/src/spawn.cpp b/src/spawn.cpp index 45324d79..e18e6bb3 100644 --- a/src/spawn.cpp +++ b/src/spawn.cpp @@ -183,6 +183,7 @@ QMessageBox::StandardButton badSteamReg( "The path to the Steam executable cannot be found. You might try " "reinstalling Steam.")) .details(details) + .icon(QMessageBox::Critical) .button({ QObject::tr("Continue without starting Steam"), QObject::tr("The program may fail to launch."), @@ -203,6 +204,7 @@ QMessageBox::StandardButton startSteamFailed( .main(QObject::tr("Cannot start Steam")) .content(makeContent(sp, e)) .details(details) + .icon(QMessageBox::Critical) .button({ QObject::tr("Continue without starting Steam"), QObject::tr("The program may fail to launch."), @@ -232,6 +234,7 @@ void spawnFailed(const SpawnParameters& sp, DWORD code) .main(mainText) .content(makeContent(sp, code)) .details(details) + .icon(QMessageBox::Critical) .exec(); } @@ -261,6 +264,7 @@ void helperFailed( .main(mainText) .content(makeContent(sp, code)) .details(details) + .icon(QMessageBox::Critical) .exec(); } @@ -295,26 +299,45 @@ bool confirmRestartAsAdmin(const SpawnParameters& sp) .main(mainText) .content(content) .details(details) + .icon(QMessageBox::Question) .button({ - QObject::tr("Restart Mod Organizer as administrator"), - QObject::tr("You must allow \"helper.exe\" to make changes to the system."), - QMessageBox::Yes}) + QObject::tr("Restart Mod Organizer as administrator"), + QObject::tr("You must allow \"helper.exe\" to make changes to the system."), + QMessageBox::Yes}) .button({ - QObject::tr("Cancel"), - QMessageBox::Cancel}) + QObject::tr("Cancel"), + QMessageBox::Cancel}) .exec(); return (r == QMessageBox::Yes); } -QuestionBoxMemory::Button confirmStartSteam(QWidget* parent, const SpawnParameters& sp) +QMessageBox::StandardButton confirmStartSteam( + QWidget* window, const SpawnParameters& sp, const QString& details) { - return QuestionBoxMemory::query( - parent, "steamQuery", sp.binary.fileName(), - QObject::tr("Start Steam?"), - QObject::tr("Steam is required to be running already to correctly start the game. " - "Should MO try to start steam now?"), - QDialogButtonBox::Yes | QDialogButtonBox::No | QDialogButtonBox::Cancel); + const auto title = QObject::tr("Launch Steam"); + const auto mainText = QObject::tr("This program requires Steam"); + const auto content = QObject::tr( + "Mod Organizer has detected that this program likely requires Steam to be " + "running to function properly."); + + return MOBase::TaskDialog(window, title) + .main(mainText) + .content(content) + .details(details) + .icon(QMessageBox::Question) + .button({ + QObject::tr("Start Steam"), + QMessageBox::Yes}) + .button({ + QObject::tr("Continue without starting Steam"), + QObject::tr("The program might fail to run."), + QMessageBox::No}) + .button({ + QObject::tr("Cancel"), + QMessageBox::Cancel}) + .remember("steamQuery", sp.binary.fileName()) + .exec(); } QuestionBoxMemory::Button confirmRestartAsAdminForSteam(QWidget* parent, const SpawnParameters& sp) @@ -561,27 +584,14 @@ bool startSteam(QWidget* parent) return true; } -bool gameRequiresSteam(const QDir& gameDirectory, const Settings& settings) -{ - static const std::vector files = { - "steam_api.dll", "steam_api64.dll" - }; - - for (const auto& file : files) { - const QFileInfo fi(gameDirectory.absoluteFilePath(file)); - if (fi.exists()) { - log::debug("found '{}'", fi.absoluteFilePath()); - return true; - } - } - - return false; -} - bool checkSteam( QWidget* parent, const SpawnParameters& sp, const QDir& gameDirectory, const QString &steamAppID, const Settings& settings) { + static const std::vector steamFiles = { + "steam_api.dll", "steam_api64.dll" + }; + log::debug("checking steam"); if (!steamAppID.isEmpty()) { @@ -590,16 +600,37 @@ bool checkSteam( env::set("SteamAPPId", settings.steam().appID()); } - if (!gameRequiresSteam(gameDirectory, settings)) { - log::debug("games doesn't seem to require steam"); + + bool steamRequired = false; + QString details; + + for (const auto& file : steamFiles) { + const QFileInfo fi(gameDirectory.absoluteFilePath(file)); + if (fi.exists()) { + details = QString( + "managed game is located at '%1' and file '%2' exists") + .arg(gameDirectory.absolutePath()) + .arg(fi.absoluteFilePath()); + + log::debug("{}", details); + steamRequired = true; + + break; + } + } + + if (!steamRequired) { + log::debug("program doesn't seem to require steam"); return true; } + auto ss = getSteamStatus(); if (!ss.running) { log::debug("steam isn't running, asking to start steam"); - const auto c = dialogs::confirmStartSteam(parent, sp); + + const auto c = dialogs::confirmStartSteam(parent, sp, details); if (c == QDialogButtonBox::Yes) { log::debug("user wants to start steam"); -- cgit v1.3.1 From 200b5283eb5a0eff5ed18e772930b99eea5e11ef Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Mon, 23 Sep 2019 18:21:39 -0400 Subject: added center dialogs option moved download list options to their own group box renamed confusing "Download Meta Information" to "Show Meta Information" --- src/settings.cpp | 34 ++++++- src/settings.h | 6 ++ src/settingsdialog.ui | 208 ++++++++++++++++++++++-------------------- src/settingsdialoggeneral.cpp | 2 + 4 files changed, 149 insertions(+), 101 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/settings.cpp b/src/settings.cpp index 19eca5ec..c3e8781e 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -623,7 +623,13 @@ void GeometrySettings::saveGeometry(const QDialog* d) bool GeometrySettings::restoreGeometry(QDialog* d) const { - return restoreWindowGeometry(d); + const auto r = restoreWindowGeometry(d); + + if (centerDialogs()) { + centerOnParent(d); + } + + return r; } void GeometrySettings::saveWindowGeometry(const QWidget* w) @@ -829,6 +835,16 @@ void GeometrySettings::setModInfoTabOrder(const QString& names) set(m_Settings, "Widgets", "ModInfoTabOrder", names); } +bool GeometrySettings::centerDialogs() const +{ + return get(m_Settings, "Settings", "center_dialogs", false); +} + +void GeometrySettings::setCenterDialogs(bool b) +{ + set(m_Settings, "Settings", "center_dialogs", b); +} + void GeometrySettings::centerOnMainWindowMonitor(QWidget* w) { const auto monitor = getOptional( @@ -850,6 +866,22 @@ void GeometrySettings::centerOnMonitor(QWidget* w, int monitor) w->move(center - w->rect().center()); } +void GeometrySettings::centerOnParent(QWidget* w, QWidget* parent) +{ + if (!parent) { + parent = w->parentWidget(); + + if (!parent) { + parent = qApp->activeWindow(); + } + } + + if (parent && parent->isVisible()) { + const auto pr = parent->geometry(); + w->move(pr.center() - w->rect().center()); + } +} + void GeometrySettings::saveMainWindowMonitor(const QMainWindow* w) { if (auto* handle=w->windowHandle()) { diff --git a/src/settings.h b/src/settings.h index b5366911..ee6ff3fe 100644 --- a/src/settings.h +++ b/src/settings.h @@ -160,6 +160,11 @@ public: QStringList modInfoTabOrder() const; void setModInfoTabOrder(const QString& names); + // whether dialogs should be centered on their parent + // + bool centerDialogs() const; + void setCenterDialogs(bool b); + // assumes the given widget is a top-level // void centerOnMainWindowMonitor(QWidget* w); @@ -177,6 +182,7 @@ private: void ensureWindowOnScreen(QWidget* w) const; static void centerOnMonitor(QWidget* w, int monitor); + static void centerOnParent(QWidget* w, QWidget* parent=nullptr); }; diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 40079441..9d1e4da1 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -86,97 +86,23 @@ p, li { white-space: pre-wrap; } - User interface + User Interface - - - - - Colors - - - - - - When this is enabled, the color defined for a separator will be shown on the mod list scrollbar at the location of the separator. This can be useful for quick navigation between separator sections or to a specific separator section. - - - When this is enabled, the color defined for a separator will be shown on the mod list scrollbar at the location of the separator. This can be useful for quick navigation between separator sections or to a specific separator section. - - - Show mod list separator colors on the scrollbar - - - true - - - - - - - Plugin is Contained in selected Mod - - - - - - - Is overwritten (loose files) - - - - - - - Is overwriting (loose files) - - - - - - - Reset Colors - - - - - - - Mod Contains selected Plugin - - - - - - - Is overwritten (archive files) - - - - - - - Is overwriting (archive files) - - - - - - - - - - Modify the categories available to arrange your mods. + + + + + Dialogs will always be centered on the main window, but will remember their size. - Modify the categories available to arrange your mods. + Dialogs will always be centered on the main window, but will remember their size. - Configure Mod Categories + Always center dialogs - + @@ -195,36 +121,119 @@ p, li { white-space: pre-wrap; } - - + + - If checked, the download interface will be more compact. + Modify the categories available to arrange your mods. + + + Modify the categories available to arrange your mods. - Compact Download Interface + Configure Mod Categories - - - - Qt::Vertical + + + + + + + Download List + + + + + + If checked, the download interface will be more compact. - - - 20 - 40 - + + Compact List - + - + If checked, the download list will display meta information instead of file names. - Download Meta Information + Show Meta Information + + + + + + + + + + Colors + + + + + + When this is enabled, the color defined for a separator will be shown on the mod list scrollbar at the location of the separator. This can be useful for quick navigation between separator sections or to a specific separator section. + + + When this is enabled, the color defined for a separator will be shown on the mod list scrollbar at the location of the separator. This can be useful for quick navigation between separator sections or to a specific separator section. + + + Show mod list separator colors on the scrollbar + + + true + + + + + + + Plugin is Contained in selected Mod + + + + + + + Is overwritten (loose files) + + + + + + + Is overwriting (loose files) + + + + + + + Reset Colors + + + + + + + Mod Contains selected Plugin + + + + + + + Is overwritten (archive files) + + + + + + + Is overwriting (archive files) @@ -1411,7 +1420,6 @@ programs you are intentionally running. styleBox logLevelBox usePrereleaseBox - compactBox categoriesBtn baseDirEdit browseBaseDirBtn diff --git a/src/settingsdialoggeneral.cpp b/src/settingsdialoggeneral.cpp index 8ecdcbb9..ae924393 100644 --- a/src/settingsdialoggeneral.cpp +++ b/src/settingsdialoggeneral.cpp @@ -51,6 +51,7 @@ GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d) setContainsColor(settings().colors().modlistContainsPlugin()); setContainedColor(settings().colors().pluginListContained()); + ui->centerDialogs->setChecked(settings().geometry().centerDialogs()); ui->compactBox->setChecked(settings().interface().compactDownloads()); ui->showMetaBox->setChecked(settings().interface().metaDownloads()); ui->usePrereleaseBox->setChecked(settings().usePrereleases()); @@ -91,6 +92,7 @@ void GeneralSettingsTab::update() settings().colors().setModlistContainsPlugin(getContainsColor()); settings().colors().setPluginListContained(getContainedColor()); + settings().geometry().setCenterDialogs(ui->centerDialogs->isChecked()); settings().interface().setCompactDownloads(ui->compactBox->isChecked()); settings().interface().setMetaDownloads(ui->showMetaBox->isChecked()); settings().setUsePrereleases(ui->usePrereleaseBox->isChecked()); -- cgit v1.3.1 From 088f27fe48cd8f218052090a97e8187eedf0c06e Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Mon, 23 Sep 2019 19:10:19 -0400 Subject: changed the layout of the general settings tab added option to disable checking for updates removed online check, just try it and see --- src/mainwindow.cpp | 16 ++++ src/mainwindow.h | 1 + src/organizercore.cpp | 36 ++------ src/organizercore.h | 1 + src/selfupdater.cpp | 12 ++- src/selfupdater.h | 14 ++- src/settings.cpp | 10 +++ src/settings.h | 5 ++ src/settingsdialog.ui | 203 ++++++++++++++++++++++++++---------------- src/settingsdialoggeneral.cpp | 2 + 10 files changed, 187 insertions(+), 113 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 42cbe919..cd650d2f 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -263,6 +263,7 @@ MainWindow::MainWindow(Settings &settings setupToolbar(); toggleMO2EndorseState(); + toggleUpdateAction(); TaskProgressManager::instance().tryCreateTaskbar(); @@ -5007,6 +5008,7 @@ void MainWindow::on_actionSettings_triggered() bool oldDisplayForeign(settings.interface().displayForeign()); bool proxy = settings.network().useProxy(); DownloadManager *dlManager = m_OrganizerCore.downloadManager(); + const bool oldCheckForUpdates = settings.checkForUpdates(); SettingsDialog dialog(&m_PluginContainer, settings, this); @@ -5084,6 +5086,14 @@ void MainWindow::on_actionSettings_triggered() m_OrganizerCore.cycleDiagnostics(); toggleMO2EndorseState(); + + if (oldCheckForUpdates != settings.checkForUpdates()) { + toggleUpdateAction(); + + if (settings.checkForUpdates()) { + m_OrganizerCore.checkForUpdates(); + } + } } void MainWindow::on_actionNexus_triggered() @@ -5596,6 +5606,12 @@ void MainWindow::toggleMO2EndorseState() ui->actionEndorseMO->setStatusTip(text); } +void MainWindow::toggleUpdateAction() +{ + const auto& s = m_OrganizerCore.settings(); + ui->actionUpdate->setVisible(s.checkForUpdates()); +} + void MainWindow::nxmEndorsementsAvailable(QVariant userData, QVariant resultData, int) { QVariantList data = resultData.toList(); diff --git a/src/mainwindow.h b/src/mainwindow.h index 1f997ab1..524e2b6e 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -313,6 +313,7 @@ private: void sendSelectedPluginsToPriority(int newPriority); void toggleMO2EndorseState(); + void toggleUpdateAction(); private: diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 0da5b604..a4a89c99 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -74,25 +74,6 @@ using namespace MOBase; //static CrashDumpsType OrganizerCore::m_globalCrashDumpsType = CrashDumpsType::None; -static bool isOnline() -{ - const auto runningFlags = - QNetworkInterface::IsUp | QNetworkInterface::IsRunning; - - for (auto&& i : QNetworkInterface::allInterfaces()) { - if (!(i.flags() & QNetworkInterface::IsLoopBack)) { - if (i.flags() & runningFlags) { - auto addresses = i.addressEntries(); - if (!addresses.empty()) { - return true; - } - } - } - } - - return false; -} - static std::wstring getProcessName(HANDLE process) { wchar_t buffer[MAX_PATH]; @@ -307,14 +288,15 @@ void OrganizerCore::setUserInterface(IUserInterface *userInterface, m_InstallationManager.setParentWidget(widget); m_Updater.setUserInterface(widget); - if (userInterface != nullptr) { - // this currently wouldn't work reliably if the ui isn't initialized yet to - // display the result - if (isOnline() && !m_Settings.network().offlineMode()) { - m_Updater.testForUpdate(); - } else { - log::debug("user doesn't seem to be connected to the internet"); - } + checkForUpdates(); +} + +void OrganizerCore::checkForUpdates() +{ + // this currently wouldn't work reliably if the ui isn't initialized yet to + // display the result + if (m_UserInterface != nullptr) { + m_Updater.testForUpdate(m_Settings); } } diff --git a/src/organizercore.h b/src/organizercore.h index a14d79a9..5de550df 100644 --- a/src/organizercore.h +++ b/src/organizercore.h @@ -109,6 +109,7 @@ public: void updateExecutablesList(); + void checkForUpdates(); void startMOUpdate(); Settings &settings(); diff --git a/src/selfupdater.cpp b/src/selfupdater.cpp index 0ca39b19..8887927a 100644 --- a/src/selfupdater.cpp +++ b/src/selfupdater.cpp @@ -122,8 +122,18 @@ void SelfUpdater::setPluginContainer(PluginContainer *pluginContainer) m_Interface->setPluginContainer(pluginContainer); } -void SelfUpdater::testForUpdate() +void SelfUpdater::testForUpdate(const Settings& settings) { + if (settings.network().offlineMode()) { + log::debug("not checking for updates, in offline mode"); + return; + } + + if (!settings.checkForUpdates()) { + log::debug("not checking for updates, disabled"); + return; + } + // TODO: if prereleases are disabled we could just request the latest release // directly try { diff --git a/src/selfupdater.h b/src/selfupdater.h index bce49495..0c81efc5 100644 --- a/src/selfupdater.h +++ b/src/selfupdater.h @@ -37,7 +37,7 @@ namespace MOBase { class IPluginGame; } class QNetworkReply; class QProgressDialog; - +class Settings; /** * @brief manages updates for Mod Organizer itself @@ -80,6 +80,11 @@ public: void setPluginContainer(PluginContainer *pluginContainer); + /** + * @brief request information about the current version + **/ + void testForUpdate(const Settings& settings); + /** * @brief start the update process * @note this should not be called if there is no update available @@ -91,13 +96,6 @@ public: **/ MOBase::VersionInfo getVersion() const { return m_MOVersion; } -public slots: - - /** - * @brief request information about the current version - **/ - void testForUpdate(); - signals: /** diff --git a/src/settings.cpp b/src/settings.cpp index c3e8781e..462cd92a 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -178,6 +178,16 @@ QString Settings::filename() const return m_Settings.fileName(); } +bool Settings::checkForUpdates() const +{ + return get(m_Settings, "Settings", "check_for_updates", true); +} + +void Settings::setCheckForUpdates(bool b) +{ + set(m_Settings, "Settings", "check_for_updates", b); +} + bool Settings::usePrereleases() const { return get(m_Settings, "Settings", "use_prereleases", false); diff --git a/src/settings.h b/src/settings.h index ee6ff3fe..1556ba1e 100644 --- a/src/settings.h +++ b/src/settings.h @@ -692,6 +692,11 @@ public: bool archiveParsing() const; void setArchiveParsing(bool b); + // whether the user wants to check for updates + // + bool checkForUpdates() const; + void setCheckForUpdates(bool b); + // whether the user wants to upgrade to pre-releases // bool usePrereleases() const; diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 9d1e4da1..78bae6d7 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -7,7 +7,7 @@ 0 0 586 - 486 + 491 @@ -23,75 +23,67 @@ General - - - - - - - Language - - - - - - - The display language - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">The display language. This will only displaye languages for which you have a translation installed.</span></p></body></html> - - - - - - - - - - - Style - - - - - - - graphical style - - - graphical style of the MO user interface - - - - - - - - - Update to non-stable releases. - - - If this is enabled, the integrated update mechanism will notify of all releases, including pre-releases (alphas, betas). Please use this only if you're sufficiently tech-savvy to investigate issues, look for known problems in the issue tracker and create meaningful reports. + + + + + Qt::Vertical - - Install Pre-releases (Betas) + + + 0 + 0 + - + - + User Interface - - + + + + + Style + + + + + + + Language + + + + + + + The display language + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">The display language. This will only displaye languages for which you have a translation installed.</span></p></body></html> + + + + + + + graphical style + + + graphical style of the MO user interface + + + + - + Dialogs will always be centered on the main window, but will remember their size. @@ -102,7 +94,7 @@ p, li { white-space: pre-wrap; } - + @@ -121,7 +113,7 @@ p, li { white-space: pre-wrap; } - + Modify the categories available to arrange your mods. @@ -137,36 +129,49 @@ p, li { white-space: pre-wrap; } - + Download List - + - + - If checked, the download interface will be more compact. + If checked, the download list will display meta information instead of file names. - Compact List + Show Meta Information - + - If checked, the download list will display meta information instead of file names. + If checked, the download interface will be more compact. - Show Meta Information + Compact List + + + + Qt::Vertical + + + + 0 + 0 + + + + - + Colors @@ -240,6 +245,54 @@ p, li { white-space: pre-wrap; } + + + + Updates + + + + + + Mod Organizer checks for updates on Github on startup. + + + Mod Organizer checks for updates on Github on startup. + + + Check for updates + + + + + + + Update to non-stable releases. + + + If this is enabled, the integrated update mechanism will notify of all releases, including pre-releases (alphas, betas). Please use this only if you're sufficiently tech-savvy to investigate issues, look for known problems in the issue tracker and create meaningful reports. + + + Install Pre-releases (Betas) + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + @@ -1416,11 +1469,7 @@ programs you are intentionally running. - languageBox - styleBox logLevelBox - usePrereleaseBox - categoriesBtn baseDirEdit browseBaseDirBtn downloadDirEdit diff --git a/src/settingsdialoggeneral.cpp b/src/settingsdialoggeneral.cpp index ae924393..07aff4a1 100644 --- a/src/settingsdialoggeneral.cpp +++ b/src/settingsdialoggeneral.cpp @@ -54,6 +54,7 @@ GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d) ui->centerDialogs->setChecked(settings().geometry().centerDialogs()); ui->compactBox->setChecked(settings().interface().compactDownloads()); ui->showMetaBox->setChecked(settings().interface().metaDownloads()); + ui->checkForUpdates->setChecked(settings().checkForUpdates()); ui->usePrereleaseBox->setChecked(settings().usePrereleases()); ui->colorSeparatorsBox->setChecked(settings().colors().colorSeparatorScrollbar()); @@ -95,6 +96,7 @@ void GeneralSettingsTab::update() settings().geometry().setCenterDialogs(ui->centerDialogs->isChecked()); settings().interface().setCompactDownloads(ui->compactBox->isChecked()); settings().interface().setMetaDownloads(ui->showMetaBox->isChecked()); + settings().setCheckForUpdates(ui->checkForUpdates->isChecked()); settings().setUsePrereleases(ui->usePrereleaseBox->isChecked()); settings().colors().setColorSeparatorScrollbar(ui->colorSeparatorsBox->isChecked()); } -- cgit v1.3.1 From 01b2a8201dbbb3e5ba8c09246a45cde4f11ed2bc Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Wed, 25 Sep 2019 18:24:08 -0400 Subject: replaced color buttons by a QTableWidget --- src/settingsdialog.ui | 237 ++++++++++++++++++----------- src/settingsdialoggeneral.cpp | 347 +++++++++++++++++++++++++++--------------- src/settingsdialoggeneral.h | 42 ++--- 3 files changed, 381 insertions(+), 245 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 78bae6d7..1ecf19f9 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -42,46 +42,64 @@ User Interface - - - - - Style - - - - - - - Language - - - - - - - The display language - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Language + + + + + + + The display language + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">The display language. This will only displaye languages for which you have a translation installed.</span></p></body></html> - - - - - - - graphical style - - - graphical style of the MO user interface - + + + + + + + Style + + + + + + + graphical style + + + graphical style of the MO user interface + + + + - + Dialogs will always be centered on the main window, but will remember their size. @@ -94,7 +112,7 @@ p, li { white-space: pre-wrap; } - + @@ -113,7 +131,7 @@ p, li { white-space: pre-wrap; } - + Modify the categories available to arrange your mods. @@ -126,6 +144,19 @@ p, li { white-space: pre-wrap; } + + + + Qt::Vertical + + + + 0 + 0 + + + + @@ -176,70 +207,90 @@ p, li { white-space: pre-wrap; } Colors - - - - - When this is enabled, the color defined for a separator will be shown on the mod list scrollbar at the location of the separator. This can be useful for quick navigation between separator sections or to a specific separator section. - - - When this is enabled, the color defined for a separator will be shown on the mod list scrollbar at the location of the separator. This can be useful for quick navigation between separator sections or to a specific separator section. - - - Show mod list separator colors on the scrollbar + + + + + QAbstractItemView::NoEditTriggers - - true + + QAbstractItemView::SingleSelection - - - - - - Plugin is Contained in selected Mod + + QAbstractItemView::SelectRows - - - - - - Is overwritten (loose files) + + QAbstractItemView::ScrollPerPixel - - - - - - Is overwriting (loose files) - - - - - - - Reset Colors - - - - - - - Mod Contains selected Plugin - - - - - - - Is overwritten (archive files) + + false + + false + + + false + + + true + + + false + - - - - Is overwriting (archive files) - + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + When this is enabled, the color defined for a separator will be shown on the mod list scrollbar at the location of the separator. This can be useful for quick navigation between separator sections or to a specific separator section. + + + When this is enabled, the color defined for a separator will be shown on the mod list scrollbar at the location of the separator. This can be useful for quick navigation between separator sections or to a specific separator section. + + + Show mod list separator colors on the scrollbar + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Reset Colors + + + + diff --git a/src/settingsdialoggeneral.cpp b/src/settingsdialoggeneral.cpp index 07aff4a1..be57101e 100644 --- a/src/settingsdialoggeneral.cpp +++ b/src/settingsdialoggeneral.cpp @@ -6,64 +6,121 @@ using MOBase::QuestionBoxMemory; -GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d) - : SettingsTab(s, d) + +class ColorItem : public QTableWidgetItem { - addLanguages(); +public: + ColorItem( + const QColor& defaultColor, + std::function get, + std::function commit) + : m_default(defaultColor), m_get(get), m_commit(commit) + { + set(get()); + } + + QColor get() const + { + return m_temp; + } + + bool set(const QColor& c) { - QString languageCode = settings().interface().language(); - int currentID = ui->languageBox->findData(languageCode); - // I made a mess. :( Most languages are stored with only the iso country - // code (2 characters like "de") but chinese - // with the exact language variant (zh_TW) so I have to search for both - // variants - if (currentID == -1) { - currentID = ui->languageBox->findData(languageCode.mid(0, 2)); + if (m_temp != c) { + m_temp = c; + return true; } - if (currentID != -1) { - ui->languageBox->setCurrentIndex(currentID); + + return false; + } + + void commit() + { + m_commit(m_temp); + } + + bool reset() + { + return set(m_default); + } + +private: + const QColor m_default; + std::function m_get; + std::function m_commit; + QColor m_temp; +}; + + +class ColorDelegate : public QStyledItemDelegate +{ +public: + ColorDelegate(QTableWidget* table) + : m_table(table) + { + } + +protected: + void paint( + QPainter* p, const QStyleOptionViewItem& option, + const QModelIndex& index) const override + { + if (!paintColor(p, option, index)) { + QStyledItemDelegate::paint(p, option, index); } } - addStyles(); +private: + QTableWidget* m_table; + bool paintColor( + QPainter* p, const QStyleOptionViewItem& option, + const QModelIndex& index) const { - const int currentID = ui->styleBox->findData( - settings().interface().styleName().value_or("")); + if (index.column() != 1) { + return false; + } + + const auto* item = dynamic_cast( + m_table->item(index.row(), index.column())); + + if (!item) { + return false; + } + + p->save(); + p->fillRect(option.rect, item->get()); + p->restore(); + + return true; + } +}; - if (currentID != -1) { - ui->styleBox->setCurrentIndex(currentID); + +template +void forEachColorItem(QTableWidget* table, F&& f) +{ + const auto rowCount = table->rowCount(); + + for (int i=0; i(table->item(i, 1))) { + f(item); } } +} + + +GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d) + : SettingsTab(s, d) +{ + addLanguages(); + selectLanguage(); + + addStyles(); + selectStyle(); + + setColorTable(); - //version with stylesheet - setButtonColor(ui->overwritingBtn, settings().colors().modlistOverwritingLoose()); - setButtonColor(ui->overwrittenBtn, settings().colors().modlistOverwrittenLoose()); - setButtonColor(ui->overwritingArchiveBtn, settings().colors().modlistOverwritingArchive()); - setButtonColor(ui->overwrittenArchiveBtn, settings().colors().modlistOverwrittenArchive()); - setButtonColor(ui->containsBtn, settings().colors().modlistContainsPlugin()); - setButtonColor(ui->containedBtn, settings().colors().pluginListContained()); - - setOverwritingColor(settings().colors().modlistOverwritingLoose()); - setOverwrittenColor(settings().colors().modlistOverwrittenLoose()); - setOverwritingArchiveColor(settings().colors().modlistOverwritingArchive()); - setOverwrittenArchiveColor(settings().colors().modlistOverwrittenArchive()); - setContainsColor(settings().colors().modlistContainsPlugin()); - setContainedColor(settings().colors().pluginListContained()); - - ui->centerDialogs->setChecked(settings().geometry().centerDialogs()); - ui->compactBox->setChecked(settings().interface().compactDownloads()); - ui->showMetaBox->setChecked(settings().interface().metaDownloads()); - ui->checkForUpdates->setChecked(settings().checkForUpdates()); - ui->usePrereleaseBox->setChecked(settings().usePrereleases()); - ui->colorSeparatorsBox->setChecked(settings().colors().colorSeparatorScrollbar()); - - QObject::connect(ui->overwritingArchiveBtn, &QPushButton::clicked, [&]{ on_overwritingArchiveBtn_clicked(); }); - QObject::connect(ui->overwritingBtn, &QPushButton::clicked, [&]{ on_overwritingBtn_clicked(); }); - QObject::connect(ui->overwrittenArchiveBtn, &QPushButton::clicked, [&]{ on_overwrittenArchiveBtn_clicked(); }); - QObject::connect(ui->overwrittenBtn, &QPushButton::clicked, [&]{ on_overwrittenBtn_clicked(); }); - QObject::connect(ui->containedBtn, &QPushButton::clicked, [&]{ on_containedBtn_clicked(); }); - QObject::connect(ui->containsBtn, &QPushButton::clicked, [&]{ on_containsBtn_clicked(); }); QObject::connect(ui->categoriesBtn, &QPushButton::clicked, [&]{ on_categoriesBtn_clicked(); }); QObject::connect(ui->resetColorsBtn, &QPushButton::clicked, [&]{ on_resetColorsBtn_clicked(); }); QObject::connect(ui->resetDialogsButton, &QPushButton::clicked, [&]{ on_resetDialogsButton_clicked(); }); @@ -86,18 +143,16 @@ void GeneralSettingsTab::update() emit settings().styleChanged(newStyle); } - settings().colors().setModlistOverwritingLoose(getOverwritingColor()); - settings().colors().setModlistOverwrittenLoose(getOverwrittenColor()); - settings().colors().setModlistOverwritingArchive(getOverwritingArchiveColor()); - settings().colors().setModlistOverwrittenArchive(getOverwrittenArchiveColor()); - settings().colors().setModlistContainsPlugin(getContainsColor()); - settings().colors().setPluginListContained(getContainedColor()); - settings().geometry().setCenterDialogs(ui->centerDialogs->isChecked()); settings().interface().setCompactDownloads(ui->compactBox->isChecked()); settings().interface().setMetaDownloads(ui->showMetaBox->isChecked()); settings().setCheckForUpdates(ui->checkForUpdates->isChecked()); settings().setUsePrereleases(ui->usePrereleaseBox->isChecked()); + + forEachColorItem(ui->colorTable, [](auto* item) { + item->commit(); + }); + settings().colors().setColorSeparatorScrollbar(ui->colorSeparatorsBox->isChecked()); } @@ -134,6 +189,22 @@ void GeneralSettingsTab::addLanguages() } } +void GeneralSettingsTab::selectLanguage() +{ + QString languageCode = settings().interface().language(); + int currentID = ui->languageBox->findData(languageCode); + // I made a mess. :( Most languages are stored with only the iso country + // code (2 characters like "de") but chinese + // with the exact language variant (zh_TW) so I have to search for both + // variants + if (currentID == -1) { + currentID = ui->languageBox->findData(languageCode.mid(0, 2)); + } + if (currentID != -1) { + ui->languageBox->setCurrentIndex(currentID); + } +} + void GeneralSettingsTab::addStyles() { ui->styleBox->addItem("None", ""); @@ -147,107 +218,136 @@ void GeneralSettingsTab::addStyles() } } -void GeneralSettingsTab::resetDialogs() +void GeneralSettingsTab::selectStyle() { - settings().widgets().resetQuestionButtons(); + const int currentID = ui->styleBox->findData( + settings().interface().styleName().value_or("")); + + if (currentID != -1) { + ui->styleBox->setCurrentIndex(currentID); + } } -void GeneralSettingsTab::setButtonColor(QPushButton *button, const QColor &color) +void GeneralSettingsTab::setColorTable() { - button->setStyleSheet( - QString("QPushButton {" - "background-color: rgba(%1, %2, %3, %4);" - "color: %5;" - "border: 1px solid;" - "padding: 3px;" - "}") - .arg(color.red()) - .arg(color.green()) - .arg(color.blue()) - .arg(color.alpha()) - .arg(ColorSettings::idealTextColor(color).name()) - ); -}; + ui->colorTable->setColumnCount(2); + ui->colorTable->setHorizontalHeaderLabels({ + QObject::tr("Item"), QObject::tr("Color") + }); -void GeneralSettingsTab::on_containsBtn_clicked() -{ - QColor result = QColorDialog::getColor(m_ContainsColor, &dialog(), "Color Picker: Mod contains selected plugin", QColorDialog::ShowAlphaChannel); - if (result.isValid()) { - m_ContainsColor = result; - setButtonColor(ui->containsBtn, result); - } + ui->colorTable->setItemDelegate(new ColorDelegate(ui->colorTable)); + + addColor( + QObject::tr("Is overwritten (loose files)"), + QColor(0, 255, 0, 64), + [this]{ return settings().colors().modlistOverwrittenLoose(); }, + [this](auto&& v){ settings().colors().setModlistOverwrittenLoose(v); }); + + addColor( + QObject::tr("Is overwriting (loose files)"), + QColor(255, 0, 0, 64), + [this]{ return settings().colors().modlistOverwritingLoose(); }, + [this](auto&& v){ settings().colors().setModlistOverwritingLoose(v); }); + + addColor( + QObject::tr("Is overwritten (archives)"), + QColor(0, 255, 255, 64), + [this]{ return settings().colors().modlistOverwrittenArchive(); }, + [this](auto&& v){ settings().colors().setModlistOverwrittenArchive(v); }); + + addColor( + QObject::tr("Is overwriting (archives)"), + QColor(255, 0, 255, 64), + [this]{ return settings().colors().modlistOverwritingArchive(); }, + [this](auto&& v){ settings().colors().setModlistOverwritingArchive(v); }); + + addColor( + QObject::tr("Mod contains selected plugin"), + QColor(0, 0, 255, 64), + [this]{ return settings().colors().modlistContainsPlugin(); }, + [this](auto&& v){ settings().colors().setModlistContainsPlugin(v); }); + + addColor( + QObject::tr("Plugin is contained in selected mod"), + QColor(0, 0, 255, 64), + [this]{ return settings().colors().pluginListContained(); }, + [this](auto&& v){ settings().colors().setPluginListContained(v); }); + + QObject::connect( + ui->colorTable, &QTableWidget::cellActivated, + [&]{ onColorActivated(); }); } -void GeneralSettingsTab::on_containedBtn_clicked() +void GeneralSettingsTab::addColor( + const QString& text, const QColor& defaultColor, + std::function get, + std::function commit) { - QColor result = QColorDialog::getColor(m_ContainedColor, &dialog(), "ColorPicker: Plugin is Contained in selected Mod", QColorDialog::ShowAlphaChannel); - if (result.isValid()) { - m_ContainedColor = result; - setButtonColor(ui->containedBtn, result); - } + const auto r = ui->colorTable->rowCount(); + ui->colorTable->setRowCount(r + 1); + + ui->colorTable->setItem(r, 0, new QTableWidgetItem(text)); + ui->colorTable->setItem(r, 1, new ColorItem(defaultColor, get, commit)); + + ui->colorTable->resizeColumnsToContents(); } -void GeneralSettingsTab::on_overwrittenBtn_clicked() +void GeneralSettingsTab::resetDialogs() { - QColor result = QColorDialog::getColor(m_OverwrittenColor, &dialog(), "ColorPicker: Is overwritten (loose files)", QColorDialog::ShowAlphaChannel); - if (result.isValid()) { - m_OverwrittenColor = result; - setButtonColor(ui->overwrittenBtn, result); - } + settings().widgets().resetQuestionButtons(); } -void GeneralSettingsTab::on_overwritingBtn_clicked() +void GeneralSettingsTab::onColorActivated() { - QColor result = QColorDialog::getColor(m_OverwritingColor, &dialog(), "ColorPicker: Is overwriting (loose files)", QColorDialog::ShowAlphaChannel); - if (result.isValid()) { - m_OverwritingColor = result; - setButtonColor(ui->overwritingBtn, result); + const auto rows = ui->colorTable->selectionModel()->selectedRows(); + if (rows.isEmpty()) { + return; } -} -void GeneralSettingsTab::on_overwrittenArchiveBtn_clicked() -{ - QColor result = QColorDialog::getColor(m_OverwrittenArchiveColor, &dialog(), "ColorPicker: Is overwritten (archive files)", QColorDialog::ShowAlphaChannel); - if (result.isValid()) { - m_OverwrittenArchiveColor = result; - setButtonColor(ui->overwrittenArchiveBtn, result); + const auto row = rows[0].row(); + + const auto text = ui->colorTable->item(row, 0)->text(); + auto* item = dynamic_cast(ui->colorTable->item(row, 1)); + + if (!item) { + return; } -} -void GeneralSettingsTab::on_overwritingArchiveBtn_clicked() -{ - QColor result = QColorDialog::getColor(m_OverwritingArchiveColor, &dialog(), "ColorPicker: Is overwriting (archive files)", QColorDialog::ShowAlphaChannel); + const QColor result = QColorDialog::getColor( + item->get(), &dialog(), text, QColorDialog::ShowAlphaChannel); + if (result.isValid()) { - m_OverwritingArchiveColor = result; - setButtonColor(ui->overwritingArchiveBtn, result); + item->set(result); + ui->colorTable->update(ui->colorTable->model()->index(row, 1)); } } void GeneralSettingsTab::on_resetColorsBtn_clicked() { - m_OverwritingColor = QColor(255, 0, 0, 64); - m_OverwrittenColor = QColor(0, 255, 0, 64); - m_OverwritingArchiveColor = QColor(255, 0, 255, 64); - m_OverwrittenArchiveColor = QColor(0, 255, 255, 64); - m_ContainsColor = QColor(0, 0, 255, 64); - m_ContainedColor = QColor(0, 0, 255, 64); - - setButtonColor(ui->overwritingBtn, m_OverwritingColor); - setButtonColor(ui->overwrittenBtn, m_OverwrittenColor); - setButtonColor(ui->overwritingArchiveBtn, m_OverwritingArchiveColor); - setButtonColor(ui->overwrittenArchiveBtn, m_OverwrittenArchiveColor); - setButtonColor(ui->containsBtn, m_ContainsColor); - setButtonColor(ui->containedBtn, m_ContainedColor); + bool changed = false; + + forEachColorItem(ui->colorTable, [&](auto* item) { + if (item->reset()) { + changed = true; + } + }); + + if (changed) { + ui->colorTable->update(); + } } void GeneralSettingsTab::on_resetDialogsButton_clicked() { - if (QMessageBox::question( - parentWidget(), QObject::tr("Confirm?"), + const auto r = QMessageBox::question( + parentWidget(), + QObject::tr("Confirm?"), QObject::tr( "This will reset all the choices you made to dialogs and make them all " "visible again. Continue?"), - QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { + QMessageBox::Yes | QMessageBox::No); + + if (r == QMessageBox::Yes) { resetDialogs(); } } @@ -255,6 +355,7 @@ void GeneralSettingsTab::on_resetDialogsButton_clicked() void GeneralSettingsTab::on_categoriesBtn_clicked() { CategoriesDialog dialog(&dialog()); + if (dialog.exec() == QDialog::Accepted) { dialog.commitChanges(); } diff --git a/src/settingsdialoggeneral.h b/src/settingsdialoggeneral.h index 2038ba31..1f7fafff 100644 --- a/src/settingsdialoggeneral.h +++ b/src/settingsdialoggeneral.h @@ -12,38 +12,22 @@ public: void update(); private: - QColor m_OverwritingColor; - QColor m_OverwrittenColor; - QColor m_OverwritingArchiveColor; - QColor m_OverwrittenArchiveColor; - QColor m_ContainsColor; - QColor m_ContainedColor; - void addLanguages(); + void selectLanguage(); + void addStyles(); + void selectStyle(); + + void setColorTable(); + void resetDialogs(); - void setButtonColor(QPushButton *button, const QColor &color); - - QColor getOverwritingColor() { return m_OverwritingColor; } - QColor getOverwrittenColor() { return m_OverwrittenColor; } - QColor getOverwritingArchiveColor() { return m_OverwritingArchiveColor; } - QColor getOverwrittenArchiveColor() { return m_OverwrittenArchiveColor; } - QColor getContainsColor() { return m_ContainsColor; } - QColor getContainedColor() { return m_ContainedColor; } - - void setOverwritingColor(QColor col) { m_OverwritingColor = col; } - void setOverwrittenColor(QColor col) { m_OverwrittenColor = col; } - void setOverwritingArchiveColor(QColor col) { m_OverwritingArchiveColor = col; } - void setOverwrittenArchiveColor(QColor col) { m_OverwrittenArchiveColor = col; } - void setContainsColor(QColor col) { m_ContainsColor = col; } - void setContainedColor(QColor col) { m_ContainedColor = col; } - - void on_overwritingArchiveBtn_clicked(); - void on_overwritingBtn_clicked(); - void on_overwrittenArchiveBtn_clicked(); - void on_overwrittenBtn_clicked(); - void on_containedBtn_clicked(); - void on_containsBtn_clicked(); + + void addColor( + const QString& text, const QColor& defaultColor, + std::function get, + std::function commit); + + void onColorActivated(); void on_categoriesBtn_clicked(); void on_resetColorsBtn_clicked(); -- cgit v1.3.1 From 5d74bd3789515a3e04e54267f1cdfe8f5397f6df Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Wed, 25 Sep 2019 19:32:53 -0400 Subject: refactored addLanguages() a bit changed some of the tooltips --- src/settingsdialog.ui | 42 ++++++++++++++++++------------- src/settingsdialoggeneral.cpp | 57 ++++++++++++++++++++++++++++--------------- 2 files changed, 63 insertions(+), 36 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 1ecf19f9..704e4134 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -68,14 +68,10 @@ - The display language + The language of the user interface. - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">The display language. This will only displaye languages for which you have a translation installed.</span></p></body></html> + The language of the user interface. @@ -89,10 +85,10 @@ p, li { white-space: pre-wrap; } - graphical style + Visual theme of the user interface. - graphical style of the MO user interface + Visual theme of the user interface. @@ -121,10 +117,10 @@ p, li { white-space: pre-wrap; } - Reset stored information from dialogs. + Reset all choices made in dialogs. - This will make all dialogs show up again where you checked the "Remember selection"-box. + Reset all choices made in dialogs. Reset Dialog Choices @@ -169,7 +165,10 @@ p, li { white-space: pre-wrap; } - If checked, the download list will display meta information instead of file names. + Show meta information instead of file names in the download list. + + + Show meta information instead of file names in the download list. Show Meta Information @@ -179,7 +178,10 @@ p, li { white-space: pre-wrap; } - If checked, the download interface will be more compact. + Make the download list more compact. + + + Make the download list more compact. Compact List @@ -257,10 +259,10 @@ p, li { white-space: pre-wrap; } - When this is enabled, the color defined for a separator will be shown on the mod list scrollbar at the location of the separator. This can be useful for quick navigation between separator sections or to a specific separator section. + Colors set on separators will also be shown in the mod list scrollbar at the location of the separator. This can be useful for quickly navigating to a specific separator. - When this is enabled, the color defined for a separator will be shown on the mod list scrollbar at the location of the separator. This can be useful for quick navigation between separator sections or to a specific separator section. + Colors set on separators will also be shown in the mod list scrollbar at the location of the separator. This can be useful for quickly navigating to a specific separator. Show mod list separator colors on the scrollbar @@ -285,6 +287,12 @@ p, li { white-space: pre-wrap; } + + Reset all colors to their default value. + + + Reset all colors to their default value. + Reset Colors @@ -305,10 +313,10 @@ p, li { white-space: pre-wrap; } - Mod Organizer checks for updates on Github on startup. + Check for Mod Organizer updates on Github on startup. - Mod Organizer checks for updates on Github on startup. + Check for Mod Organizer updates on Github on startup. Check for updates @@ -321,7 +329,7 @@ p, li { white-space: pre-wrap; } Update to non-stable releases. - If this is enabled, the integrated update mechanism will notify of all releases, including pre-releases (alphas, betas). Please use this only if you're sufficiently tech-savvy to investigate issues, look for known problems in the issue tracker and create meaningful reports. + Update to non-stable releases. Install Pre-releases (Betas) diff --git a/src/settingsdialoggeneral.cpp b/src/settingsdialoggeneral.cpp index 754d10cb..0dfd3a08 100644 --- a/src/settingsdialoggeneral.cpp +++ b/src/settingsdialoggeneral.cpp @@ -158,33 +158,52 @@ void GeneralSettingsTab::update() void GeneralSettingsTab::addLanguages() { + // matches the end of filenames for something like "_en.qm" or "_zh_CN.qm" + const QString pattern = + QString::fromStdWString(AppConfig::translationPrefix()) + + "_([a-z]{2,3}(_[A-Z]{2,2})?).qm"; + + const QRegExp exp(pattern); + + QDirIterator iter( + QCoreApplication::applicationDirPath() + "/translations", + QDir::Files); + std::vector> languages; - QDirIterator langIter(QCoreApplication::applicationDirPath() + "/translations", QDir::Files); - QString pattern = QString::fromStdWString(AppConfig::translationPrefix()) + "_([a-z]{2,3}(_[A-Z]{2,2})?).qm"; - QRegExp exp(pattern); - while (langIter.hasNext()) { - langIter.next(); - QString file = langIter.fileName(); - if (exp.exactMatch(file)) { - QString languageCode = exp.cap(1); - QLocale locale(languageCode); - QString languageString = QString("%1 (%2)").arg(locale.nativeLanguageName()).arg(locale.nativeCountryName()); //QLocale::languageToString(locale.language()); - if (locale.language() == QLocale::Chinese) { - if (languageCode == "zh_TW") { - languageString = "Chinese (traditional)"; - } else { - languageString = "Chinese (simplified)"; - } + while (iter.hasNext()) { + iter.next(); + + const QString file = iter.fileName(); + if (!exp.exactMatch(file)) { + continue; + } + + const QString languageCode = exp.cap(1); + const QLocale locale(languageCode); + + QString languageString = QString("%1 (%2)") + .arg(locale.nativeLanguageName()) + .arg(locale.nativeCountryName()); + + if (locale.language() == QLocale::Chinese) { + if (languageCode == "zh_TW") { + languageString = "Chinese (Traditional)"; + } else { + languageString = "Chinese (Simplified)"; } - languages.push_back(std::make_pair(QString("%1").arg(languageString), exp.cap(1))); } + + languages.push_back({languageString, exp.cap(1)}); } + if (!ui->languageBox->findText("English")) { - languages.push_back(std::make_pair(QString("English"), QString("en_US"))); + languages.push_back({QString("English"), QString("en_US")}); } + std::sort(languages.begin(), languages.end()); - for (const auto &lang : languages) { + + for (const auto& lang : languages) { ui->languageBox->addItem(lang.first, lang.second); } } -- cgit v1.3.1 From 51d664d76ce6b611e7a7585b209bad9d68fe65d7 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Fri, 27 Sep 2019 15:20:02 -0400 Subject: moved color stuff to ColorTable, now shows sample text and icons --- src/CMakeLists.txt | 3 + src/colortable.cpp | 278 ++++++++++++++++++++++++++++++++++++++++++ src/colortable.h | 28 +++++ src/icondelegate.cpp | 15 ++- src/icondelegate.h | 18 +-- src/modflagicondelegate.cpp | 114 +++++++++-------- src/modflagicondelegate.h | 11 +- src/settingsdialog.ui | 9 +- src/settingsdialoggeneral.cpp | 235 +++-------------------------------- src/settingsdialoggeneral.h | 9 -- 10 files changed, 421 insertions(+), 299 deletions(-) create mode 100644 src/colortable.cpp create mode 100644 src/colortable.h (limited to 'src/settingsdialog.ui') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7c29ff48..b21d1a8b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -141,6 +141,7 @@ SET(organizer_SRCS envsecurity.cpp envshortcut.cpp envwindows.cpp + colortable.cpp shared/windows_error.cpp shared/error_report.cpp @@ -263,6 +264,7 @@ SET(organizer_HDRS envsecurity.h envshortcut.h envwindows.h + colortable.h shared/windows_error.h shared/error_report.h @@ -473,6 +475,7 @@ set(utilities ) set(widgets + colortable genericicondelegate filerenamer filterwidget diff --git a/src/colortable.cpp b/src/colortable.cpp new file mode 100644 index 00000000..7546abe5 --- /dev/null +++ b/src/colortable.cpp @@ -0,0 +1,278 @@ +#include "colortable.h" +#include "modflagicondelegate.h" +#include "settings.h" + +class ColorItem; +ColorItem* colorItemForRow(QTableWidget* table, int row); + +void paintBackground( + QTableWidget* table, QPainter* p, const QStyleOptionViewItem& option, + const QModelIndex& index); + + +class ColoredBackgroundDelegate : public QStyledItemDelegate +{ +public: + ColoredBackgroundDelegate(QTableWidget* table) + : m_table(table) + { + } + + void paint( + QPainter* p, const QStyleOptionViewItem& option, + const QModelIndex& index) const override + { + paintBackground(m_table, p, option, index); + + QStyleOptionViewItem itemOption(option); + initStyleOption(&itemOption, index); + itemOption.state = QStyle::State_Enabled; + + QStyledItemDelegate::paint(p, itemOption, index); + } + +private: + QTableWidget* m_table; +}; + + +class FakeModFlagIconDelegate : public ModFlagIconDelegate +{ +public: + explicit FakeModFlagIconDelegate(QTableWidget* table) + : m_table(table) + { + } + + void paint( + QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const override + { + paintBackground(m_table, painter, option, index); + ModFlagIconDelegate::paintIcons(painter, option, index, getIcons(index)); + } + +protected: + QList getIcons(const QModelIndex &index) const override + { + const auto flags = { + ModInfo::FLAG_CONFLICT_MIXED, + ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE, + ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITTEN, + ModInfo::FLAG_ARCHIVE_CONFLICT_MIXED, + ModInfo::FLAG_BACKUP, + ModInfo::FLAG_NOTENDORSED, + ModInfo::FLAG_NOTES, + ModInfo::FLAG_ALTERNATE_GAME + }; + + return getIconsForFlags(flags, false); + } + + size_t getNumIcons(const QModelIndex &index) const override + { + return getIcons(index).size(); + } + +private: + QTableWidget* m_table; +}; + + +class ColorItem : public QTableWidgetItem +{ +public: + ColorItem( + QString caption, QColor defaultColor, + std::function get, + std::function commit) : + m_caption(std::move(caption)), m_default(defaultColor), + m_get(get), m_commit(commit) + { + setText(m_caption); + set(get()); + } + + const QString& caption() const + { + return m_caption; + } + + QColor get() const + { + return m_temp; + } + + bool set(const QColor& c) + { + if (m_temp != c) { + m_temp = c; + return true; + } + + return false; + } + + void commit() + { + m_commit(m_temp); + } + + bool reset() + { + return set(m_default); + } + +private: + const QString m_caption; + const QColor m_default; + std::function m_get; + std::function m_commit; + QColor m_temp; +}; + + +ColorItem* colorItemForRow(QTableWidget* table, int row) +{ + return dynamic_cast(table->item(row, 0)); +} + +template +void forEachColorItem(QTableWidget* table, F&& f) +{ + const auto rowCount = table->rowCount(); + + for (int i=0; isave(); + p->fillRect(option.rect, ci->get()); + p->restore(); + } +} + + +ColorTable::ColorTable(QWidget* parent) + : QTableWidget(parent), m_settings(nullptr) +{ + setColumnCount(3); + setHorizontalHeaderLabels({"", "", ""}); + + setItemDelegateForColumn(1, new ColoredBackgroundDelegate(this)); + setItemDelegateForColumn(2, new FakeModFlagIconDelegate(this)); + + connect( + this, &QTableWidget::cellActivated, + [&]{ onColorActivated(); }); +} + +void ColorTable::load(Settings& s) +{ + m_settings = &s; + + addColor( + QObject::tr("Is overwritten (loose files)"), + QColor(0, 255, 0, 64), + [this]{ return m_settings->colors().modlistOverwrittenLoose(); }, + [this](auto&& v){ m_settings->colors().setModlistOverwrittenLoose(v); }); + + addColor( + QObject::tr("Is overwriting (loose files)"), + QColor(255, 0, 0, 64), + [this]{ return m_settings->colors().modlistOverwritingLoose(); }, + [this](auto&& v){ m_settings->colors().setModlistOverwritingLoose(v); }); + + addColor( + QObject::tr("Is overwritten (archives)"), + QColor(0, 255, 255, 64), + [this]{ return m_settings->colors().modlistOverwrittenArchive(); }, + [this](auto&& v){ m_settings->colors().setModlistOverwrittenArchive(v); }); + + addColor( + QObject::tr("Is overwriting (archives)"), + QColor(255, 0, 255, 64), + [this]{ return m_settings->colors().modlistOverwritingArchive(); }, + [this](auto&& v){ m_settings->colors().setModlistOverwritingArchive(v); }); + + addColor( + QObject::tr("Mod contains selected plugin"), + QColor(0, 0, 255, 64), + [this]{ return m_settings->colors().modlistContainsPlugin(); }, + [this](auto&& v){ m_settings->colors().setModlistContainsPlugin(v); }); + + addColor( + QObject::tr("Plugin is contained in selected mod"), + QColor(0, 0, 255, 64), + [this]{ return m_settings->colors().pluginListContained(); }, + [this](auto&& v){ m_settings->colors().setPluginListContained(v); }); +} + +void ColorTable::resetColors() +{ + bool changed = false; + + forEachColorItem(this, [&](auto* item) { + if (item->reset()) { + changed = true; + } + }); + + if (changed) { + update(); + } +} + +void ColorTable::commitColors() +{ + forEachColorItem(this, [](auto* item) { + item->commit(); + }); +} + +void ColorTable::addColor( + const QString& text, const QColor& defaultColor, + std::function get, + std::function commit) +{ + const auto r = rowCount(); + setRowCount(r + 1); + + auto* item = new ColorItem(text, defaultColor, get, commit); + + setItem(r, 0, item); + setItem(r, 1, new QTableWidgetItem("Text")); + setItem(r, 2, new QTableWidgetItem); + + resizeColumnsToContents(); +} + +void ColorTable::onColorActivated() +{ + const auto rows = selectionModel()->selectedRows(); + if (rows.isEmpty()) { + return; + } + + const auto row = rows[0].row(); + auto* ci = colorItemForRow(this, row); + if (!ci) { + return; + } + + const QColor result = QColorDialog::getColor( + ci->get(), topLevelWidget(), ci->caption(), QColorDialog::ShowAlphaChannel); + + if (result.isValid()) { + ci->set(result); + update(model()->index(row, 1)); + } +} diff --git a/src/colortable.h b/src/colortable.h new file mode 100644 index 00000000..c2b64a4d --- /dev/null +++ b/src/colortable.h @@ -0,0 +1,28 @@ +#ifndef COLORTABLE_H +#define COLORTABLE_H + +#include + +class Settings; + +class ColorTable : public QTableWidget +{ +public: + ColorTable(QWidget* parent=nullptr); + + void load(Settings& s); + void resetColors(); + void commitColors(); + +private: + Settings* m_settings; + + void addColor( + const QString& text, const QColor& defaultColor, + std::function get, + std::function commit); + + void onColorActivated(); +}; + +#endif // COLORTABLE_H diff --git a/src/icondelegate.cpp b/src/icondelegate.cpp index 39038f3c..03964263 100644 --- a/src/icondelegate.cpp +++ b/src/icondelegate.cpp @@ -32,13 +32,10 @@ IconDelegate::IconDelegate(QObject *parent) { } - -void IconDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +void IconDelegate::paintIcons( + QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index, const QList& icons) { - QStyledItemDelegate::paint(painter, option, index); - - QList icons = getIcons(index); - int x = 4; painter->save(); @@ -67,3 +64,9 @@ void IconDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, painter->restore(); } +void IconDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyledItemDelegate::paint(painter, option, index); + paintIcons(painter, option, index, getIcons(index)); +} + diff --git a/src/icondelegate.h b/src/icondelegate.h index 39694481..bac71a62 100644 --- a/src/icondelegate.h +++ b/src/icondelegate.h @@ -27,25 +27,19 @@ along with Mod Organizer. If not, see . class IconDelegate : public QStyledItemDelegate { - Q_OBJECT -public: + Q_OBJECT; +public: explicit IconDelegate(QObject *parent = 0); - virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; -signals: - -public slots: - -private: + static void paintIcons( + QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index, const QList& icons); +protected: virtual QList getIcons(const QModelIndex &index) const = 0; virtual size_t getNumIcons(const QModelIndex &index) const = 0; - - -private: - }; #endif // ICONDELEGATE_H diff --git a/src/modflagicondelegate.cpp b/src/modflagicondelegate.cpp index 7110a590..a5e9aa22 100644 --- a/src/modflagicondelegate.cpp +++ b/src/modflagicondelegate.cpp @@ -31,72 +31,82 @@ void ModFlagIconDelegate::columnResized(int logicalIndex, int, int newSize) } } -QList ModFlagIconDelegate::getIcons(const QModelIndex &index) const { +QList ModFlagIconDelegate::getIconsForFlags( + std::vector flags, bool compact) +{ QList result; - QVariant modid = index.data(Qt::UserRole + 1); - if (modid.isValid()) { - ModInfo::Ptr info = ModInfo::getByIndex(modid.toInt()); - std::vector flags = info->getFlags(); - // Don't do flags for overwrite - if (std::find(flags.begin(), flags.end(),ModInfo::FLAG_OVERWRITE) != flags.end()) - return result; - - // insert conflict icons to provide nicer alignment - { // insert loose file conflicts first - auto iter = std::find_first_of(flags.begin(), flags.end(), - m_ConflictFlags, m_ConflictFlags + 4); - if (iter != flags.end()) { - result.append(getFlagIcon(*iter)); - flags.erase(iter); - } else if (!m_Compact) { - result.append(QString()); - } + // Don't do flags for overwrite + if (std::find(flags.begin(), flags.end(),ModInfo::FLAG_OVERWRITE) != flags.end()) + return result; + + // insert conflict icons to provide nicer alignment + { // insert loose file conflicts first + auto iter = std::find_first_of(flags.begin(), flags.end(), + m_ConflictFlags, m_ConflictFlags + 4); + if (iter != flags.end()) { + result.append(getFlagIcon(*iter)); + flags.erase(iter); + } else if (!compact) { + result.append(QString()); } + } - { // insert loose vs archive overwrite second - auto iter = std::find(flags.begin(), flags.end(), - ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE); - if (iter != flags.end()) { - result.append(getFlagIcon(*iter)); - flags.erase(iter); - } else if (!m_Compact) { - result.append(QString()); - } + { // insert loose vs archive overwrite second + auto iter = std::find(flags.begin(), flags.end(), + ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE); + if (iter != flags.end()) { + result.append(getFlagIcon(*iter)); + flags.erase(iter); + } else if (!compact) { + result.append(QString()); } + } - { // insert loose vs archive overwritten third - auto iter = std::find_first_of(flags.begin(), flags.end(), - m_ArchiveLooseConflictFlags + 1, m_ArchiveLooseConflictFlags + 2); - if (iter != flags.end()) { - result.append(getFlagIcon(*iter)); - flags.erase(iter); - } else if (!m_Compact) { - result.append(QString()); - } + { // insert loose vs archive overwritten third + auto iter = std::find_first_of(flags.begin(), flags.end(), + m_ArchiveLooseConflictFlags + 1, m_ArchiveLooseConflictFlags + 2); + if (iter != flags.end()) { + result.append(getFlagIcon(*iter)); + flags.erase(iter); + } else if (!compact) { + result.append(QString()); } + } - { // insert archive conflicts last - auto iter = std::find_first_of(flags.begin(), flags.end(), - m_ArchiveConflictFlags, m_ArchiveConflictFlags + 3); - if (iter != flags.end()) { - result.append(getFlagIcon(*iter)); - flags.erase(iter); - } else if (!m_Compact) { - result.append(QString()); - } + { // insert archive conflicts last + auto iter = std::find_first_of(flags.begin(), flags.end(), + m_ArchiveConflictFlags, m_ArchiveConflictFlags + 3); + if (iter != flags.end()) { + result.append(getFlagIcon(*iter)); + flags.erase(iter); + } else if (!compact) { + result.append(QString()); } + } - for (auto iter = flags.begin(); iter != flags.end(); ++iter) { - auto iconPath = getFlagIcon(*iter); - if (!iconPath.isEmpty()) - result.append(iconPath); - } + for (auto iter = flags.begin(); iter != flags.end(); ++iter) { + auto iconPath = getFlagIcon(*iter); + if (!iconPath.isEmpty()) + result.append(iconPath); } + return result; } -QString ModFlagIconDelegate::getFlagIcon(ModInfo::EFlag flag) const +QList ModFlagIconDelegate::getIcons(const QModelIndex &index) const +{ + QVariant modid = index.data(Qt::UserRole + 1); + + if (modid.isValid()) { + ModInfo::Ptr info = ModInfo::getByIndex(modid.toInt()); + return getIconsForFlags(info->getFlags(), m_Compact); + } + + return {}; +} + +QString ModFlagIconDelegate::getFlagIcon(ModInfo::EFlag flag) { switch (flag) { case ModInfo::FLAG_BACKUP: return QStringLiteral(":/MO/gui/emblem_backup"); diff --git a/src/modflagicondelegate.h b/src/modflagicondelegate.h index eb6a76ab..4f22dd90 100644 --- a/src/modflagicondelegate.h +++ b/src/modflagicondelegate.h @@ -5,21 +5,24 @@ class ModFlagIconDelegate : public IconDelegate { -Q_OBJECT + Q_OBJECT; public: explicit ModFlagIconDelegate(QObject *parent = 0, int logicalIndex = -1, int compactSize = 120); virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; + static QList getIconsForFlags( + std::vector flags, bool compact); + + static QString getFlagIcon(ModInfo::EFlag flag); + public slots: void columnResized(int logicalIndex, int oldSize, int newSize); -private: +protected: virtual QList getIcons(const QModelIndex &index) const; virtual size_t getNumIcons(const QModelIndex &index) const; - QString getFlagIcon(ModInfo::EFlag flag) const; - private: static ModInfo::EFlag m_ConflictFlags[4]; static ModInfo::EFlag m_ArchiveLooseConflictFlags[2]; diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 704e4134..fba65545 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -211,7 +211,7 @@ - + QAbstractItemView::NoEditTriggers @@ -1527,6 +1527,13 @@ programs you are intentionally running. + + + ColorTable + QTableWidget +
colortable.h
+
+
logLevelBox baseDirEdit diff --git a/src/settingsdialoggeneral.cpp b/src/settingsdialoggeneral.cpp index 0dfd3a08..a9ec5cae 100644 --- a/src/settingsdialoggeneral.cpp +++ b/src/settingsdialoggeneral.cpp @@ -2,114 +2,9 @@ #include "ui_settingsdialog.h" #include "appconfig.h" #include "categoriesdialog.h" +#include "colortable.h" #include -using MOBase::QuestionBoxMemory; - - -class ColorItem : public QTableWidgetItem -{ -public: - ColorItem( - const QColor& defaultColor, - std::function get, - std::function commit) - : m_default(defaultColor), m_get(get), m_commit(commit) - { - set(get()); - } - - QColor get() const - { - return m_temp; - } - - bool set(const QColor& c) - { - if (m_temp != c) { - m_temp = c; - return true; - } - - return false; - } - - void commit() - { - m_commit(m_temp); - } - - bool reset() - { - return set(m_default); - } - -private: - const QColor m_default; - std::function m_get; - std::function m_commit; - QColor m_temp; -}; - - -class ColorDelegate : public QStyledItemDelegate -{ -public: - ColorDelegate(QTableWidget* table) - : m_table(table) - { - } - -protected: - void paint( - QPainter* p, const QStyleOptionViewItem& option, - const QModelIndex& index) const override - { - if (!paintColor(p, option, index)) { - QStyledItemDelegate::paint(p, option, index); - } - } - -private: - QTableWidget* m_table; - - bool paintColor( - QPainter* p, const QStyleOptionViewItem& option, - const QModelIndex& index) const - { - if (index.column() != 1) { - return false; - } - - const auto* item = dynamic_cast( - m_table->item(index.row(), index.column())); - - if (!item) { - return false; - } - - p->save(); - p->fillRect(option.rect, item->get()); - p->restore(); - - return true; - } -}; - - -template -void forEachColorItem(QTableWidget* table, F&& f) -{ - const auto rowCount = table->rowCount(); - - for (int i=0; i(table->item(i, 1))) { - f(item); - } - } -} - - GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d) : SettingsTab(s, d) { @@ -119,17 +14,26 @@ GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d) addStyles(); selectStyle(); - setColorTable(); + ui->colorTable->load(s); - QObject::connect(ui->categoriesBtn, &QPushButton::clicked, [&]{ on_categoriesBtn_clicked(); }); - QObject::connect(ui->resetColorsBtn, &QPushButton::clicked, [&]{ on_resetColorsBtn_clicked(); }); - QObject::connect(ui->resetDialogsButton, &QPushButton::clicked, [&]{ on_resetDialogsButton_clicked(); }); + QObject::connect( + ui->categoriesBtn, &QPushButton::clicked, + [&]{ on_categoriesBtn_clicked(); }); + + QObject::connect( + ui->resetColorsBtn, &QPushButton::clicked, + [&]{ on_resetColorsBtn_clicked(); }); + + QObject::connect( + ui->resetDialogsButton, &QPushButton::clicked, + [&]{ on_resetDialogsButton_clicked(); }); } void GeneralSettingsTab::update() { const QString oldLanguage = settings().interface().language(); - const QString newLanguage = ui->languageBox->itemData(ui->languageBox->currentIndex()).toString(); + const QString newLanguage = ui->languageBox->itemData( + ui->languageBox->currentIndex()).toString(); if (newLanguage != oldLanguage) { settings().interface().setLanguage(newLanguage); @@ -137,7 +41,9 @@ void GeneralSettingsTab::update() } const QString oldStyle = settings().interface().styleName().value_or(""); - const QString newStyle = ui->styleBox->itemData(ui->styleBox->currentIndex()).toString(); + const QString newStyle = ui->styleBox->itemData( + ui->styleBox->currentIndex()).toString(); + if (oldStyle != newStyle) { settings().interface().setStyleName(newStyle); emit settings().styleChanged(newStyle); @@ -149,9 +55,7 @@ void GeneralSettingsTab::update() settings().setCheckForUpdates(ui->checkForUpdates->isChecked()); settings().setUsePrereleases(ui->usePrereleaseBox->isChecked()); - forEachColorItem(ui->colorTable, [](auto* item) { - item->commit(); - }); + ui->colorTable->commitColors(); settings().colors().setColorSeparatorScrollbar(ui->colorSeparatorsBox->isChecked()); } @@ -258,113 +162,14 @@ void GeneralSettingsTab::selectStyle() } } -void GeneralSettingsTab::setColorTable() -{ - ui->colorTable->setColumnCount(2); - ui->colorTable->setHorizontalHeaderLabels({ - QObject::tr("Item"), QObject::tr("Color") - }); - - ui->colorTable->setItemDelegate(new ColorDelegate(ui->colorTable)); - - addColor( - QObject::tr("Is overwritten (loose files)"), - QColor(0, 255, 0, 64), - [this]{ return settings().colors().modlistOverwrittenLoose(); }, - [this](auto&& v){ settings().colors().setModlistOverwrittenLoose(v); }); - - addColor( - QObject::tr("Is overwriting (loose files)"), - QColor(255, 0, 0, 64), - [this]{ return settings().colors().modlistOverwritingLoose(); }, - [this](auto&& v){ settings().colors().setModlistOverwritingLoose(v); }); - - addColor( - QObject::tr("Is overwritten (archives)"), - QColor(0, 255, 255, 64), - [this]{ return settings().colors().modlistOverwrittenArchive(); }, - [this](auto&& v){ settings().colors().setModlistOverwrittenArchive(v); }); - - addColor( - QObject::tr("Is overwriting (archives)"), - QColor(255, 0, 255, 64), - [this]{ return settings().colors().modlistOverwritingArchive(); }, - [this](auto&& v){ settings().colors().setModlistOverwritingArchive(v); }); - - addColor( - QObject::tr("Mod contains selected plugin"), - QColor(0, 0, 255, 64), - [this]{ return settings().colors().modlistContainsPlugin(); }, - [this](auto&& v){ settings().colors().setModlistContainsPlugin(v); }); - - addColor( - QObject::tr("Plugin is contained in selected mod"), - QColor(0, 0, 255, 64), - [this]{ return settings().colors().pluginListContained(); }, - [this](auto&& v){ settings().colors().setPluginListContained(v); }); - - QObject::connect( - ui->colorTable, &QTableWidget::cellActivated, - [&]{ onColorActivated(); }); -} - -void GeneralSettingsTab::addColor( - const QString& text, const QColor& defaultColor, - std::function get, - std::function commit) -{ - const auto r = ui->colorTable->rowCount(); - ui->colorTable->setRowCount(r + 1); - - ui->colorTable->setItem(r, 0, new QTableWidgetItem(text)); - ui->colorTable->setItem(r, 1, new ColorItem(defaultColor, get, commit)); - - ui->colorTable->resizeColumnsToContents(); -} - void GeneralSettingsTab::resetDialogs() { settings().widgets().resetQuestionButtons(); } -void GeneralSettingsTab::onColorActivated() -{ - const auto rows = ui->colorTable->selectionModel()->selectedRows(); - if (rows.isEmpty()) { - return; - } - - const auto row = rows[0].row(); - - const auto text = ui->colorTable->item(row, 0)->text(); - auto* item = dynamic_cast(ui->colorTable->item(row, 1)); - - if (!item) { - return; - } - - const QColor result = QColorDialog::getColor( - item->get(), &dialog(), text, QColorDialog::ShowAlphaChannel); - - if (result.isValid()) { - item->set(result); - ui->colorTable->update(ui->colorTable->model()->index(row, 1)); - } -} - void GeneralSettingsTab::on_resetColorsBtn_clicked() { - bool changed = false; - - forEachColorItem(ui->colorTable, [&](auto* item) { - if (item->reset()) { - changed = true; - } - }); - - if (changed) { - ui->colorTable->update(); - } + ui->colorTable->resetColors(); } void GeneralSettingsTab::on_resetDialogsButton_clicked() diff --git a/src/settingsdialoggeneral.h b/src/settingsdialoggeneral.h index 1f7fafff..706ba9ef 100644 --- a/src/settingsdialoggeneral.h +++ b/src/settingsdialoggeneral.h @@ -18,17 +18,8 @@ private: void addStyles(); void selectStyle(); - void setColorTable(); - void resetDialogs(); - void addColor( - const QString& text, const QColor& defaultColor, - std::function get, - std::function commit); - - void onColorActivated(); - void on_categoriesBtn_clicked(); void on_resetColorsBtn_clicked(); void on_resetDialogsButton_clicked(); -- cgit v1.3.1 From 239cfbe6854f727b5dd3e6922cacc17587361cf5 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Fri, 4 Oct 2019 06:29:23 -0400 Subject: explicit tab order, seems to fix hang when switching tabs --- src/settingsdialog.ui | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index fba65545..0ecbd101 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -1535,7 +1535,19 @@ programs you are intentionally running. - logLevelBox + tabWidget + languageBox + styleBox + centerDialogs + resetDialogsButton + categoriesBtn + showMetaBox + compactBox + checkForUpdates + usePrereleaseBox + colorTable + colorSeparatorsBox + resetColorsBtn baseDirEdit browseBaseDirBtn downloadDirEdit @@ -1548,7 +1560,18 @@ programs you are intentionally running. browseProfilesDirBtn overwriteDirEdit browseOverwriteDirBtn + managedGameDirEdit + browseGameDirBtn + nexusConnect + nexusManualKey + nexusDisconnect + nexusLog + offlineBox + endorsementBox + proxyBox + hideAPICounterBox associateButton + clearCacheButton knownServersList preferredServersList steamUserEdit @@ -1558,8 +1581,17 @@ programs you are intentionally running. pluginBlacklist appIDEdit mechanismBox + hideUncheckedBox + forceEnableBox + lockGUIBox + displayForeignBox + enableArchiveParsingBox bsaDateBtn - tabWidget + execBlacklistBtn + resetGeometryBtn + logLevelBox + dumpsTypeBox + dumpsMaxEdit -- cgit v1.3.1 From 8fcaea9de32b888ec8839ef6b7f394556383275e Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Fri, 22 Nov 2019 07:44:09 -0500 Subject: added loot log level option --- src/loot.cpp | 79 +++++++++++++--------- src/settings.cpp | 11 +++ src/settings.h | 5 ++ src/settingsdialog.ui | 136 ++++++++++++++++++-------------------- src/settingsdialogdiagnostics.cpp | 36 +++++++++- src/settingsdialogdiagnostics.h | 3 +- 6 files changed, 164 insertions(+), 106 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/loot.cpp b/src/loot.cpp index 7184cce8..c5df8c9d 100644 --- a/src/loot.cpp +++ b/src/loot.cpp @@ -6,6 +6,30 @@ using namespace MOBase; +log::Levels levelFromLoot(lootcli::LogLevels level) +{ + using LC = lootcli::LogLevels; + + switch (level) + { + case LC::Trace: // fall-through + case LC::Debug: + return log::Debug; + + case LC::Info: + return log::Info; + + case LC::Warning: + return log::Warning; + + case LC::Error: + return log::Error; + + default: + return log::Info; + } +} + class LootDialog : public QDialog { @@ -15,6 +39,7 @@ public: m_label(nullptr), m_progress(nullptr), m_buttons(nullptr), m_finished(false) { createUI(); + m_progress->setMaximum(0); QObject::connect( &m_loot, &Loot::output, this, @@ -45,6 +70,11 @@ public: void setProgress(lootcli::Progress p) { setText(progressToString(p)); + + if (p == lootcli::Progress::Done) { + m_progress->setRange(0, 1); + m_progress->setValue(1); + } } QString progressToString(lootcli::Progress p) @@ -65,13 +95,12 @@ public: } } - void setIndeterminate() - { - m_progress->setMaximum(0); - } - void addOutput(const QString& s) { + if (m_core.settings().diagnostics().lootLogLevel() > lootcli::LogLevels::Debug) { + return; + } + const auto lines = s.split(QRegExp("[\\r\\n]"), QString::SkipEmptyParts); for (auto&& line : lines) { @@ -101,17 +130,7 @@ public: int exec() override { - QDialog::exec(); - - if (m_errorMessages.length() > 0) { - QMessageBox *warn = new QMessageBox( - QMessageBox::Warning, tr("Errors occurred"), - m_errorMessages, QMessageBox::Ok, parentWidget()); - - warn->exec(); - } - - return 0; + return QDialog::exec(); } void onError(const QString& s) @@ -126,8 +145,6 @@ private: QProgressBar* m_progress; QDialogButtonBox* m_buttons; QPlainTextEdit* m_output; - QString m_lastLine; - QString m_errorMessages; bool m_finished; void createUI() @@ -146,11 +163,14 @@ private: ly->addWidget(m_progress); m_output = new QPlainTextEdit; + m_output->setWordWrapMode(QTextOption::NoWrap); ly->addWidget(m_output); m_buttons = new QDialogButtonBox(QDialogButtonBox::Cancel); connect(m_buttons, &QDialogButtonBox::clicked, [&](auto* b){ onButton(b); }); ly->addWidget(m_buttons); + + resize(700, 400); } void closeEvent(QCloseEvent* e) override @@ -173,7 +193,6 @@ private: void addLineOutput(const QString& line) { m_output->appendPlainText(line); - m_lastLine = line; } void onFinished() @@ -183,14 +202,12 @@ private: void log(log::Levels lv, const QString& s) { - if (lv == log::Levels::Error) { - MOBase::log::error("{}", s); - - if (!m_errorMessages.isEmpty()) { - m_errorMessages += "\n"; - } + if (lv >= log::Levels::Warning) { + log::log(lv, "{}", s); + } - m_errorMessages += s; + if (m_core.settings().diagnostics().lootLogLevel() > lootcli::LogLevels::Debug) { + addLineOutput(QString("[%1] %2").arg(log::levelToString(lv)).arg(s)); } } }; @@ -210,11 +227,14 @@ bool Loot::start(QWidget* parent, OrganizerCore& core, bool didUpdateMasterList) { m_outPath = QDir::temp().absoluteFilePath("lootreport.json"); + const auto logLevel = core.settings().diagnostics().lootLogLevel(); + QStringList parameters; parameters << "--game" << core.managedGame()->gameShortName() << "--gamePath" << QString("\"%1\"").arg(core.managedGame()->gameDirectory().absolutePath()) << "--pluginListPath" << QString("\"%1/loadorder.txt\"").arg(core.profilePath()) + << "--logLevel" << QString::fromStdString(lootcli::logLevelToString(logLevel)) << "--out" << QString("\"%1\"").arg(m_outPath); if (didUpdateMasterList) { @@ -406,7 +426,7 @@ void Loot::processMessage(const lootcli::Message& m) { case lootcli::MessageType::Log: { - if (m.logLevel == spdlog::level::err) { + if (m.logLevel == lootcli::LogLevels::Error) { std::smatch match; if (std::regex_match(m.log, match, exRequires)) { @@ -422,10 +442,10 @@ void Loot::processMessage(const lootcli::Message& m) QString::fromStdString(modName), tr("incompatible with \"%1\"").arg(dependency.c_str())); } else { - emit log(log::levelFromSpdlog(m.logLevel), QString::fromStdString(m.log)); + emit log(levelFromLoot(m.logLevel), QString::fromStdString(m.log)); } } else { - emit log(log::levelFromSpdlog(m.logLevel), QString::fromStdString(m.log)); + emit log(levelFromLoot(m.logLevel), QString::fromStdString(m.log)); } break; @@ -657,7 +677,6 @@ bool runLoot(QWidget* parent, OrganizerCore& core, bool didUpdateMasterList) loot.start(parent, core, didUpdateMasterList); dialog.setText(QObject::tr("Please wait while LOOT is running")); - dialog.setIndeterminate(); dialog.exec(); return dialog.result(); diff --git a/src/settings.cpp b/src/settings.cpp index 5aeb82fe..b533b400 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1977,6 +1977,17 @@ void DiagnosticsSettings::setLogLevel(log::Levels level) set(m_Settings, "Settings", "log_level", level); } +lootcli::LogLevels DiagnosticsSettings::lootLogLevel() const +{ + return get( + m_Settings, "Settings", "loot_log_level", lootcli::LogLevels::Info); +} + +void DiagnosticsSettings::setLootLogLevel(lootcli::LogLevels level) +{ + set(m_Settings, "Settings", "loot_log_level", level); +} + CrashDumpsType DiagnosticsSettings::crashDumpsType() const { return get(m_Settings, diff --git a/src/settings.h b/src/settings.h index d604823a..d71fabf4 100644 --- a/src/settings.h +++ b/src/settings.h @@ -21,6 +21,7 @@ along with Mod Organizer. If not, see . #define SETTINGS_H #include "loadmechanism.h" +#include #include #include #include @@ -619,6 +620,10 @@ public: MOBase::log::Levels logLevel() const; void setLogLevel(MOBase::log::Levels level); + // log level for loot + lootcli::LogLevels lootLogLevel() const; + void setLootLogLevel(lootcli::LogLevels level); + // crash dump type for both MO and usvfs // CrashDumpsType crashDumpsType() const; diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 0ecbd101..b88c8b71 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -1386,44 +1386,23 @@ programs you are intentionally running. Diagnostics - - - - - - Max Dumps To Keep - - - - - - - Qt::Horizontal - - - - 60 - 20 - - - - - - - - Maximum number of crash dumps to keep on disk. Use 0 for unlimited. - - - - Maximum number of crash dumps to keep on disk. Use 0 for unlimited. - Set "Crash Dumps" above to None to disable crash dump collection. - - - - - - + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 232 + + + + + Hint: right click link and copy link location @@ -1444,16 +1423,42 @@ programs you are intentionally running. - - - + + + + QFormLayout::ExpandingFieldsGrow + + + 12 + + + + + Log Level + + + + + + + Decides the amount of data printed to "ModOrganizer.log" + + + + Decides the amount of data printed to "ModOrganizer.log". + "Debug" produces very useful information for finding problems. There is usually no noteworthy performance impact but the file may become rather large. If this is a problem you may prefer the "Info" level for regular use. On the "Error" level the log file usually remains empty. + + + + + Crash Dumps - + Decides which type of crash dumps are collected when injected processes crash. @@ -1469,46 +1474,36 @@ programs you are intentionally running. - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 232 - - - - - - - - + + - Log Level + Max Dumps To Keep - - + + - Decides the amount of data printed to "ModOrganizer.log" + Maximum number of crash dumps to keep on disk. Use 0 for unlimited. - Decides the amount of data printed to "ModOrganizer.log". - "Debug" produces very useful information for finding problems. There is usually no noteworthy performance impact but the file may become rather large. If this is a problem you may prefer the "Info" level for regular use. On the "Error" level the log file usually remains empty. + Maximum number of crash dumps to keep on disk. Use 0 for unlimited. + Set "Crash Dumps" above to None to disable crash dump collection. + + + + LOOT Log Level + + + + + + @@ -1589,9 +1584,6 @@ programs you are intentionally running. bsaDateBtn execBlacklistBtn resetGeometryBtn - logLevelBox - dumpsTypeBox - dumpsMaxEdit diff --git a/src/settingsdialogdiagnostics.cpp b/src/settingsdialogdiagnostics.cpp index 386c7425..74cadaa9 100644 --- a/src/settingsdialogdiagnostics.cpp +++ b/src/settingsdialogdiagnostics.cpp @@ -9,7 +9,8 @@ using namespace MOBase; DiagnosticsSettingsTab::DiagnosticsSettingsTab(Settings& s, SettingsDialog& d) : SettingsTab(s, d) { - setLevelsBox(); + setLogLevel(); + setLootLogLevel(); setCrashDumpTypesBox(); ui->dumpsMaxEdit->setValue(settings().diagnostics().crashDumpsMax()); @@ -26,7 +27,7 @@ DiagnosticsSettingsTab::DiagnosticsSettingsTab(Settings& s, SettingsDialog& d) ); } -void DiagnosticsSettingsTab::setLevelsBox() +void DiagnosticsSettingsTab::setLogLevel() { ui->logLevelBox->clear(); @@ -35,14 +36,40 @@ void DiagnosticsSettingsTab::setLevelsBox() ui->logLevelBox->addItem(QObject::tr("Warning"), log::Warning); ui->logLevelBox->addItem(QObject::tr("Error"), log::Error); + const auto sel = settings().diagnostics().logLevel(); + for (int i=0; ilogLevelBox->count(); ++i) { - if (ui->logLevelBox->itemData(i) == settings().diagnostics().logLevel()) { + if (ui->logLevelBox->itemData(i) == sel) { ui->logLevelBox->setCurrentIndex(i); break; } } } +void DiagnosticsSettingsTab::setLootLogLevel() +{ + using L = lootcli::LogLevels; + + auto v = [](L level) { return QVariant(static_cast(level)); }; + + ui->lootLogLevel->clear(); + + ui->lootLogLevel->addItem(QObject::tr("Trace"), v(L::Trace)); + ui->lootLogLevel->addItem(QObject::tr("Debug"), v(L::Debug)); + ui->lootLogLevel->addItem(QObject::tr("Info (recommended)"), v(L::Info)); + ui->lootLogLevel->addItem(QObject::tr("Warning"), v(L::Warning)); + ui->lootLogLevel->addItem(QObject::tr("Error"), v(L::Error)); + + const auto sel = settings().diagnostics().lootLogLevel(); + + for (int i=0; ilootLogLevel->count(); ++i) { + if (ui->lootLogLevel->itemData(i) == v(sel)) { + ui->lootLogLevel->setCurrentIndex(i); + break; + } + } +} + void DiagnosticsSettingsTab::setCrashDumpTypesBox() { ui->dumpsTypeBox->clear(); @@ -76,4 +103,7 @@ void DiagnosticsSettingsTab::update() static_cast(ui->dumpsTypeBox->currentData().toInt())); settings().diagnostics().setCrashDumpsMax(ui->dumpsMaxEdit->value()); + + settings().diagnostics().setLootLogLevel( + static_cast(ui->lootLogLevel->currentData().toInt())); } diff --git a/src/settingsdialogdiagnostics.h b/src/settingsdialogdiagnostics.h index f0fbf770..e01ee22f 100644 --- a/src/settingsdialogdiagnostics.h +++ b/src/settingsdialogdiagnostics.h @@ -12,7 +12,8 @@ public: void update(); private: - void setLevelsBox(); + void setLogLevel(); + void setLootLogLevel(); void setCrashDumpTypesBox(); }; -- cgit v1.3.1 From 9194bfa16bb78c10bc4e23abd26ba16c33956794 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Tue, 26 Nov 2019 08:59:04 -0500 Subject: added option to hide confirmation when switching instances --- src/mainwindow.cpp | 16 ++++++++++------ src/settings.cpp | 10 ++++++++++ src/settings.h | 5 +++++ src/settingsdialog.ui | 7 +++++++ src/settingsdialoggeneral.cpp | 2 ++ 5 files changed, 34 insertions(+), 6 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 9ea554a2..844456a6 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -6139,14 +6139,18 @@ void MainWindow::on_actionNotifications_triggered() void MainWindow::on_actionChange_Game_triggered() { - const auto r = QMessageBox::question( - this, tr("Are you sure?"), tr("This will restart MO, continue?"), - QMessageBox::Yes | QMessageBox::Cancel); + if (m_OrganizerCore.settings().interface().showChangeGameConfirmation()) { + const auto r = QMessageBox::question( + this, tr("Are you sure?"), tr("This will restart MO, continue?"), + QMessageBox::Yes | QMessageBox::Cancel); - if (r == QMessageBox::Yes) { - InstanceManager::instance().clearCurrentInstance(); - ExitModOrganizer(Exit::Restart); + if (r != QMessageBox::Yes) { + return; + } } + + InstanceManager::instance().clearCurrentInstance(); + ExitModOrganizer(Exit::Restart); } void MainWindow::setCategoryListVisible(bool visible) diff --git a/src/settings.cpp b/src/settings.cpp index b533b400..e1e5c2da 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1961,6 +1961,16 @@ void InterfaceSettings::setTutorialCompleted(const QString& windowName, bool b) set(m_Settings, "CompletedWindowTutorials", windowName, b); } +bool InterfaceSettings::showChangeGameConfirmation() const +{ + return get(m_Settings, "Settings", "show_change_game_confirmation", true); +} + +void InterfaceSettings::setShowChangeGameConfirmation(bool b) const +{ + set(m_Settings, "Settings", "show_change_game_confirmation", b); +} + DiagnosticsSettings::DiagnosticsSettings(QSettings& settings) : m_Settings(settings) diff --git a/src/settings.h b/src/settings.h index d71fabf4..870e0fc4 100644 --- a/src/settings.h +++ b/src/settings.h @@ -605,6 +605,11 @@ public: bool isTutorialCompleted(const QString& windowName) const; void setTutorialCompleted(const QString& windowName, bool b=true); + // whether to show the confirmation when switching instances + // + bool showChangeGameConfirmation() const; + void setShowChangeGameConfirmation(bool b) const; + private: QSettings& m_Settings; }; diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index b88c8b71..e63ca692 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -108,6 +108,13 @@
+ + + + Show confirmation when changing instance + + + diff --git a/src/settingsdialoggeneral.cpp b/src/settingsdialoggeneral.cpp index e21fc5d0..b0e64305 100644 --- a/src/settingsdialoggeneral.cpp +++ b/src/settingsdialoggeneral.cpp @@ -17,6 +17,7 @@ GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d) ui->colorTable->load(s); ui->centerDialogs->setChecked(settings().geometry().centerDialogs()); + ui->changeGameConfirmation->setChecked(settings().interface().showChangeGameConfirmation()); ui->compactBox->setChecked(settings().interface().compactDownloads()); ui->showMetaBox->setChecked(settings().interface().metaDownloads()); ui->checkForUpdates->setChecked(settings().checkForUpdates()); @@ -59,6 +60,7 @@ void GeneralSettingsTab::update() ui->colorTable->commitColors(); settings().geometry().setCenterDialogs(ui->centerDialogs->isChecked()); + settings().interface().setShowChangeGameConfirmation(ui->changeGameConfirmation->isChecked()); settings().interface().setCompactDownloads(ui->compactBox->isChecked()); settings().interface().setMetaDownloads(ui->showMetaBox->isChecked()); settings().setCheckForUpdates(ui->checkForUpdates->isChecked()); -- cgit v1.3.1 From 70e66802a2d46a1ffdac7528b134c9d7741a8797 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Wed, 27 Nov 2019 14:10:50 -0500 Subject: changed labels that have links to new LinkLabel, removed hardcoded colors changed the link colors on dark themes to something saner --- src/aboutdialog.ui | 11 +++++++++-- src/mainwindow.ui | 9 +++++++-- src/settingsdialog.ui | 7 ++++++- src/stylesheets/Night Eyes.qss | 4 ++++ src/stylesheets/Paper Dark by 6788.qss | 4 ++++ src/stylesheets/Transparent-Style-101-Green.qss | 5 +++++ src/stylesheets/Transparent-Style-BOS.qss | 4 ++++ src/stylesheets/Transparent-Style-Skyrim.qss | 4 ++++ src/stylesheets/dark.qss | 6 +++++- src/stylesheets/dracula.qss | 4 ++++ src/stylesheets/skyrim.qss | 3 +++ src/stylesheets/vs15 Dark-Green.qss | 3 +++ src/stylesheets/vs15 Dark-Orange.qss | 3 +++ src/stylesheets/vs15 Dark-Purple.qss | 3 +++ src/stylesheets/vs15 Dark-Red.qss | 3 +++ src/stylesheets/vs15 Dark-Yellow.qss | 3 +++ src/stylesheets/vs15 Dark.qss | 3 +++ 17 files changed, 73 insertions(+), 6 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/aboutdialog.ui b/src/aboutdialog.ui index 415ce0a7..424a80f9 100644 --- a/src/aboutdialog.ui +++ b/src/aboutdialog.ui @@ -158,9 +158,9 @@ - + - <html><head/><body><p>Source code can be found at <a href="https://github.com/ModOrganizer2/modorganizer"><span style=" text-decoration: underline; color:#007af4;">GitHub</span></a>.</p></body></html> + <html><head/><body><p>Source code can be found at <a href="https://github.com/ModOrganizer2/modorganizer">GitHub</a>.</p></body></html> @@ -536,6 +536,13 @@
+ + + LinkLabel + QLabel +
linklabel.h
+
+
diff --git a/src/mainwindow.ui b/src/mainwindow.ui index b8aeeeb5..723b42fe 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -941,12 +941,12 @@ p, li { white-space: pre-wrap; } - + <html><head/><body><p>BSAs / BA2s are bundles of game assets (textures, scripts, etc.). By default, the engine loads these bundles in a separate step from loose files. <p>Their load order is specified by the priority of the corresponding plugin (right pane, plugins tab).</p><p>If there is a matching plugin, the game will load them no matter what.</p></body></html> - <html><head/><body><p>Currently detected archives. (<a href="#"><span style=" text-decoration: underline; color:#0000ff;">What is an archive?</span></a>)</p></body></html> + <html><head/><body><p>Currently detected archives. (<a href="#">What is an archive?</a>)</p></body></html> true @@ -1773,6 +1773,11 @@ p, li { white-space: pre-wrap; } QStatusBar
statusbar.h
+ + LinkLabel + QLabel +
linklabel.h
+
diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index e63ca692..c5a1d2ef 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -1410,7 +1410,7 @@ programs you are intentionally running.
- + Hint: right click link and copy link location @@ -1535,6 +1535,11 @@ programs you are intentionally running. QTableWidget
colortable.h
+ + LinkLabel + QLabel +
linklabel.h
+
tabWidget diff --git a/src/stylesheets/Night Eyes.qss b/src/stylesheets/Night Eyes.qss index 0430a8c8..14f7434e 100644 --- a/src/stylesheets/Night Eyes.qss +++ b/src/stylesheets/Night Eyes.qss @@ -49,6 +49,10 @@ QAbstractScrollArea::corner margin: 0px -2px -2px 0px; } +LinkLabel +{ + qproperty-linkColor: #3399FF; +} /* Toolbar -------------------------------------------------------------------- */ diff --git a/src/stylesheets/Paper Dark by 6788.qss b/src/stylesheets/Paper Dark by 6788.qss index 77086c15..6043ae6b 100644 --- a/src/stylesheets/Paper Dark by 6788.qss +++ b/src/stylesheets/Paper Dark by 6788.qss @@ -66,6 +66,10 @@ QSplitter { width: 8px; } +LinkLabel { + qproperty-linkColor: #3399FF; +} + /* Toolbar */ QToolBar { diff --git a/src/stylesheets/Transparent-Style-101-Green.qss b/src/stylesheets/Transparent-Style-101-Green.qss index a4ed2623..3bbdb5db 100644 --- a/src/stylesheets/Transparent-Style-101-Green.qss +++ b/src/stylesheets/Transparent-Style-101-Green.qss @@ -485,6 +485,11 @@ QStatusBar::item {border: None;} font-family: Source Sans Pro; font-size: 14px; } + +LinkLabel { + qproperty-linkColor: #3399FF; +} + QAbstractItemView { color: #cccccc; font-family: Source Sans Pro; diff --git a/src/stylesheets/Transparent-Style-BOS.qss b/src/stylesheets/Transparent-Style-BOS.qss index efad0859..33eed327 100644 --- a/src/stylesheets/Transparent-Style-BOS.qss +++ b/src/stylesheets/Transparent-Style-BOS.qss @@ -743,3 +743,7 @@ QStatusBar::item {border: None;} border-bottom:1px solid #9A9A00; */ } + +LinkLabel { + qproperty-linkColor: #3399FF; +} diff --git a/src/stylesheets/Transparent-Style-Skyrim.qss b/src/stylesheets/Transparent-Style-Skyrim.qss index 89e36c74..308580a5 100644 --- a/src/stylesheets/Transparent-Style-Skyrim.qss +++ b/src/stylesheets/Transparent-Style-Skyrim.qss @@ -743,3 +743,7 @@ QStatusBar::item {border: None;} border-bottom:1px solid #9A9A00; */ } + +LinkLabel { + qproperty-linkColor: #3399FF; +} diff --git a/src/stylesheets/dark.qss b/src/stylesheets/dark.qss index 22cd598c..9d11109d 100644 --- a/src/stylesheets/dark.qss +++ b/src/stylesheets/dark.qss @@ -380,4 +380,8 @@ DownloadListWidget[downloadView=standard]::item { DownloadListWidget[downloadView=compact]::item { padding: 4px; -} \ No newline at end of file +} + +LinkLabel { + qproperty-linkColor: #3399FF; +} diff --git a/src/stylesheets/dracula.qss b/src/stylesheets/dracula.qss index 2a7fbf9e..537ff083 100644 --- a/src/stylesheets/dracula.qss +++ b/src/stylesheets/dracula.qss @@ -30,6 +30,10 @@ QCheckBox, QGroupBox { selection-color: #bbbbbb; } +LinkLabel { + qproperty-linkColor: #3399FF; +} + /* * GroupBox and CheckBox */ diff --git a/src/stylesheets/skyrim.qss b/src/stylesheets/skyrim.qss index 2da5154d..a516f5ff 100644 --- a/src/stylesheets/skyrim.qss +++ b/src/stylesheets/skyrim.qss @@ -113,6 +113,9 @@ QListView::item { QLabel { background-color: transparent; } +LinkLabel { + qproperty-linkColor: #3399FF; } + /* Font size */ QLabel, QTextEdit, diff --git a/src/stylesheets/vs15 Dark-Green.qss b/src/stylesheets/vs15 Dark-Green.qss index 88e7651f..6d95c6cc 100644 --- a/src/stylesheets/vs15 Dark-Green.qss +++ b/src/stylesheets/vs15 Dark-Green.qss @@ -94,6 +94,9 @@ QTreeView::branch:selected { QLabel { background-color: transparent; } +LinkLabel { + qproperty-linkColor: #3399FF; } + /* Left Pane & File Trees #QTreeView, #QListView*/ QTreeView::branch:closed:has-children { image: url(./vs15/branch-closed.png); } diff --git a/src/stylesheets/vs15 Dark-Orange.qss b/src/stylesheets/vs15 Dark-Orange.qss index 488da3c4..2dd27df4 100644 --- a/src/stylesheets/vs15 Dark-Orange.qss +++ b/src/stylesheets/vs15 Dark-Orange.qss @@ -95,6 +95,9 @@ QTreeView::branch:selected { QLabel { background-color: transparent; } +LinkLabel { + qproperty-linkColor: #3399FF; } + /* Left Pane & File Trees #QTreeView, #QListView*/ QTreeView::branch:closed:has-children { image: url(./vs15/branch-closed.png); } diff --git a/src/stylesheets/vs15 Dark-Purple.qss b/src/stylesheets/vs15 Dark-Purple.qss index 24c8705a..116aaa7d 100644 --- a/src/stylesheets/vs15 Dark-Purple.qss +++ b/src/stylesheets/vs15 Dark-Purple.qss @@ -95,6 +95,9 @@ QTreeView::branch:selected { QLabel { background-color: transparent; } +LinkLabel { + qproperty-linkColor: #3399FF; } + /* Left Pane & File Trees #QTreeView, #QListView*/ QTreeView::branch:closed:has-children { image: url(./vs15/branch-closed.png); } diff --git a/src/stylesheets/vs15 Dark-Red.qss b/src/stylesheets/vs15 Dark-Red.qss index 0c0e21a8..60f565a1 100644 --- a/src/stylesheets/vs15 Dark-Red.qss +++ b/src/stylesheets/vs15 Dark-Red.qss @@ -95,6 +95,9 @@ QTreeView::branch:selected { QLabel { background-color: transparent; } +LinkLabel { + qproperty-linkColor: #3399FF; } + /* Left Pane & File Trees #QTreeView, #QListView*/ QTreeView::branch:closed:has-children { image: url(./vs15/branch-closed.png); } diff --git a/src/stylesheets/vs15 Dark-Yellow.qss b/src/stylesheets/vs15 Dark-Yellow.qss index 2cf1cb2e..bfaa4c94 100644 --- a/src/stylesheets/vs15 Dark-Yellow.qss +++ b/src/stylesheets/vs15 Dark-Yellow.qss @@ -95,6 +95,9 @@ QTreeView::branch:selected { QLabel { background-color: transparent; } +LinkLabel { + qproperty-linkColor: #3399FF; } + /* Left Pane & File Trees #QTreeView, #QListView*/ QTreeView::branch:closed:has-children { image: url(./vs15/branch-closed.png); } diff --git a/src/stylesheets/vs15 Dark.qss b/src/stylesheets/vs15 Dark.qss index a5781d72..1d27be17 100644 --- a/src/stylesheets/vs15 Dark.qss +++ b/src/stylesheets/vs15 Dark.qss @@ -94,6 +94,9 @@ QTreeView::branch:selected { QLabel { background-color: transparent; } +LinkLabel { + qproperty-linkColor: #3399FF; } + /* Left Pane & File Trees #QTreeView, #QListView*/ QTreeView::branch:closed:has-children { image: url(./vs15/branch-closed.png); } -- cgit v1.3.1 From 376f835edd3ebd778eed4b1250808188904be93c Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Wed, 27 Nov 2019 14:23:11 -0500 Subject: added transifex link in the settings --- src/settingsdialog.ui | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index c5a1d2ef..ad7e2ab3 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -75,14 +75,14 @@
- + Style - + Visual theme of the user interface. @@ -92,6 +92,16 @@ + + + + <a href="https://www.transifex.com/tannin/mod-organizer/">Help translate Mod Organizer</a> + + + true + + +
-- cgit v1.3.1 From dd6f0fed1085682f56d2815ff885a5ab58058a0b Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Wed, 4 Dec 2019 12:00:54 -0500 Subject: added explore button in the settings to open stylesheets folder added stylesheets folder to the open folders button moved "Open MO2 Logs folder" up to be with instance folders, removed "MO2" in the name --- src/mainwindow.cpp | 17 +++++++---------- src/mainwindow.h | 1 + src/settingsdialog.ui | 31 +++++++++++++++++++------------ src/settingsdialoggeneral.cpp | 42 +++++++++++++++++++++++++----------------- src/settingsdialoggeneral.h | 7 ++++--- 5 files changed, 56 insertions(+), 42 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 3af0f30c..c365fb6b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -4302,6 +4302,11 @@ void MainWindow::openPluginsFolder() shell::Explore(pluginsPath); } +void MainWindow::openStylesheetsFolder() +{ + QString ssPath = QCoreApplication::applicationDirPath() + "/" + ToQString(AppConfig::stylesheetsPath()); + shell::Explore(ssPath); +} void MainWindow::openProfileFolder() { @@ -4519,33 +4524,25 @@ static void addMenuAsPushButton(QMenu *menu, QMenu *subMenu) QMenu *MainWindow::openFolderMenu() { - QMenu *FolderMenu = new QMenu(this); FolderMenu->addAction(tr("Open Game folder"), this, SLOT(openGameFolder())); - FolderMenu->addAction(tr("Open MyGames folder"), this, SLOT(openMyGamesFolder())); - FolderMenu->addAction(tr("Open INIs folder"), this, SLOT(openIniFolder())); FolderMenu->addSeparator(); FolderMenu->addAction(tr("Open Instance folder"), this, SLOT(openInstanceFolder())); - FolderMenu->addAction(tr("Open Mods folder"), this, SLOT(openModsFolder())); - FolderMenu->addAction(tr("Open Profile folder"), this, SLOT(openProfileFolder())); - FolderMenu->addAction(tr("Open Downloads folder"), this, SLOT(openDownloadsFolder())); + FolderMenu->addAction(tr("Open Logs folder"), this, SLOT(openLogsFolder())); FolderMenu->addSeparator(); FolderMenu->addAction(tr("Open MO2 Install folder"), this, SLOT(openInstallFolder())); - FolderMenu->addAction(tr("Open MO2 Plugins folder"), this, SLOT(openPluginsFolder())); - - FolderMenu->addAction(tr("Open MO2 Logs folder"), this, SLOT(openLogsFolder())); - + FolderMenu->addAction(tr("Open MO2 Stylesheets folder"), this, SLOT(openStylesheetsFolder())); return FolderMenu; } diff --git a/src/mainwindow.h b/src/mainwindow.h index 2894b2e7..f5bab586 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -545,6 +545,7 @@ private slots: void openLogsFolder(); void openInstallFolder(); void openPluginsFolder(); + void openStylesheetsFolder(); void openDownloadsFolder(); void openModsFolder(); void openProfileFolder(); diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index ad7e2ab3..bc59d635 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -45,7 +45,7 @@ - + 0 @@ -65,16 +65,6 @@ - - - - The language of the user interface. - - - The language of the user interface. - - - @@ -92,7 +82,24 @@ - + + + + Explore... + + + + + + + The language of the user interface. + + + The language of the user interface. + + + + <a href="https://www.transifex.com/tannin/mod-organizer/">Help translate Mod Organizer</a> diff --git a/src/settingsdialoggeneral.cpp b/src/settingsdialoggeneral.cpp index b0e64305..dca4410b 100644 --- a/src/settingsdialoggeneral.cpp +++ b/src/settingsdialoggeneral.cpp @@ -3,8 +3,11 @@ #include "appconfig.h" #include "categoriesdialog.h" #include "colortable.h" +#include #include +using namespace MOBase; + GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d) : SettingsTab(s, d) { @@ -24,17 +27,16 @@ GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d) ui->usePrereleaseBox->setChecked(settings().usePrereleases()); ui->colorSeparatorsBox->setChecked(settings().colors().colorSeparatorScrollbar()); + QObject::connect(ui->exploreStyles, &QPushButton::clicked, [&]{ onExploreStyles(); }); + QObject::connect( - ui->categoriesBtn, &QPushButton::clicked, - [&]{ on_categoriesBtn_clicked(); }); + ui->categoriesBtn, &QPushButton::clicked, [&]{ onEditCategories(); }); QObject::connect( - ui->resetColorsBtn, &QPushButton::clicked, - [&]{ on_resetColorsBtn_clicked(); }); + ui->resetColorsBtn, &QPushButton::clicked, [&]{ onResetColors(); }); QObject::connect( - ui->resetDialogsButton, &QPushButton::clicked, - [&]{ on_resetDialogsButton_clicked(); }); + ui->resetDialogsButton, &QPushButton::clicked, [&]{ onResetDialogs(); }); } void GeneralSettingsTab::update() @@ -175,12 +177,27 @@ void GeneralSettingsTab::resetDialogs() settings().widgets().resetQuestionButtons(); } -void GeneralSettingsTab::on_resetColorsBtn_clicked() +void GeneralSettingsTab::onExploreStyles() +{ + QString ssPath = QCoreApplication::applicationDirPath() + "/" + ToQString(AppConfig::stylesheetsPath()); + shell::Explore(ssPath); +} + +void GeneralSettingsTab::onEditCategories() +{ + CategoriesDialog dialog(&dialog()); + + if (dialog.exec() == QDialog::Accepted) { + dialog.commitChanges(); + } +} + +void GeneralSettingsTab::onResetColors() { ui->colorTable->resetColors(); } -void GeneralSettingsTab::on_resetDialogsButton_clicked() +void GeneralSettingsTab::onResetDialogs() { const auto r = QMessageBox::question( parentWidget(), @@ -194,12 +211,3 @@ void GeneralSettingsTab::on_resetDialogsButton_clicked() resetDialogs(); } } - -void GeneralSettingsTab::on_categoriesBtn_clicked() -{ - CategoriesDialog dialog(&dialog()); - - if (dialog.exec() == QDialog::Accepted) { - dialog.commitChanges(); - } -} diff --git a/src/settingsdialoggeneral.h b/src/settingsdialoggeneral.h index 706ba9ef..455edcaf 100644 --- a/src/settingsdialoggeneral.h +++ b/src/settingsdialoggeneral.h @@ -20,9 +20,10 @@ private: void resetDialogs(); - void on_categoriesBtn_clicked(); - void on_resetColorsBtn_clicked(); - void on_resetDialogsButton_clicked(); + void onExploreStyles(); + void onEditCategories(); + void onResetColors(); + void onResetDialogs(); }; #endif // SETTINGSDIALOGGENERAL_H -- cgit v1.3.1 From a0fa896e68856ec5204e7f74db775bdb3595010a Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Wed, 4 Dec 2019 12:42:15 -0500 Subject: added open previews on double-click option implemented for filetree --- src/modinfodialogfiletree.cpp | 42 +++++++++++++++++++++++++++++++++--------- src/settings.cpp | 12 +++++++++++- src/settings.h | 7 ++++++- src/settingsdialog.ui | 10 ++++++++++ src/settingsdialoggeneral.cpp | 2 ++ 5 files changed, 62 insertions(+), 11 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/modinfodialogfiletree.cpp b/src/modinfodialogfiletree.cpp index e94b0a4f..c79a5264 100644 --- a/src/modinfodialogfiletree.cpp +++ b/src/modinfodialogfiletree.cpp @@ -32,10 +32,6 @@ FileTreeTab::FileTreeTab(ModInfoDialogTabContext cx) m_actions.hide = new QAction(tr("&Hide"), ui->filetree); m_actions.unhide = new QAction(tr("&Unhide"), ui->filetree); - auto bold = m_actions.open->font(); - bold.setBold(true); - m_actions.open->setFont(bold); - connect(m_actions.newFolder, &QAction::triggered, [&]{ onCreateDirectory(); }); connect(m_actions.open, &QAction::triggered, [&]{ onOpen(); }); connect(m_actions.runHooked, &QAction::triggered, [&]{ onRunHooked(); }); @@ -152,10 +148,17 @@ void FileTreeTab::onOpen() return; } - core().processRunner() - .setFromFile(parentWidget(), m_fs->filePath(selection)) - .setWaitForCompletion() - .run(); + const auto path = m_fs->filePath(selection); + const auto tryPreview = core().settings().interface().doubleClicksOpenPreviews(); + + if (tryPreview && canPreviewFile(plugin(), false, path)) { + core().previewFile(parentWidget(), mod().name(), path); + } else { + core().processRunner() + .setFromFile(parentWidget(), path) + .setWaitForCompletion() + .run(); + } } void FileTreeTab::onRunHooked() @@ -408,7 +411,6 @@ void FileTreeTab::onContextMenu(const QPoint &pos) // this is a multiple selection, don't show open or explore actions so users // don't open a thousand files enableNewFolder = true; - enablePreview = true; enableDelete = true; if (selection.size() < max_scan_for_context_menu) { @@ -446,6 +448,28 @@ void FileTreeTab::onContextMenu(const QPoint &pos) menu.addAction(m_actions.preview); m_actions.preview->setEnabled(enablePreview); + auto bold = m_actions.preview->font(); + bold.setBold(true); + auto notBold = m_actions.preview->font(); + notBold.setBold(false); + + // preview is bold if the file is previewable and [the preview on double-click + // option is enabled or the file can't be opened]; open is bold if the file + // can be opened and cannot be previewed + if (enablePreview && core().settings().interface().doubleClicksOpenPreviews()) { + m_actions.open->setFont(notBold); + m_actions.preview->setFont(bold); + } else if (enableOpen) { + m_actions.open->setFont(bold); + m_actions.preview->setFont(notBold); + } else if (enablePreview) { + m_actions.open->setFont(notBold); + m_actions.preview->setFont(bold); + } else { + m_actions.open->setFont(notBold); + m_actions.preview->setFont(notBold); + } + menu.addAction(m_actions.explore); m_actions.explore->setEnabled(enableExplore); diff --git a/src/settings.cpp b/src/settings.cpp index e1e5c2da..68dc19d9 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1966,11 +1966,21 @@ bool InterfaceSettings::showChangeGameConfirmation() const return get(m_Settings, "Settings", "show_change_game_confirmation", true); } -void InterfaceSettings::setShowChangeGameConfirmation(bool b) const +void InterfaceSettings::setShowChangeGameConfirmation(bool b) { set(m_Settings, "Settings", "show_change_game_confirmation", b); } +bool InterfaceSettings::doubleClicksOpenPreviews() const +{ + return get(m_Settings, "Settings", "double_click_previews", false); +} + +void InterfaceSettings::setDoubleClicksOpenPreviews(bool b) +{ + set(m_Settings, "Settings", "double_click_previews", b); +} + DiagnosticsSettings::DiagnosticsSettings(QSettings& settings) : m_Settings(settings) diff --git a/src/settings.h b/src/settings.h index 870e0fc4..0e5238b1 100644 --- a/src/settings.h +++ b/src/settings.h @@ -608,7 +608,12 @@ public: // whether to show the confirmation when switching instances // bool showChangeGameConfirmation() const; - void setShowChangeGameConfirmation(bool b) const; + void setShowChangeGameConfirmation(bool b); + + // whether double-clicks on files should try to open previews first + // + bool doubleClicksOpenPreviews() const; + void setDoubleClicksOpenPreviews(bool b); private: QSettings& m_Settings; diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index bc59d635..8e175312 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -101,6 +101,9 @@ + + https://www.transifex.com/tannin/mod-organizer/ + <a href="https://www.transifex.com/tannin/mod-organizer/">Help translate Mod Organizer</a> @@ -132,6 +135,13 @@ + + + + Open previews on double-click + + + diff --git a/src/settingsdialoggeneral.cpp b/src/settingsdialoggeneral.cpp index dca4410b..58871cee 100644 --- a/src/settingsdialoggeneral.cpp +++ b/src/settingsdialoggeneral.cpp @@ -21,6 +21,7 @@ GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d) ui->centerDialogs->setChecked(settings().geometry().centerDialogs()); ui->changeGameConfirmation->setChecked(settings().interface().showChangeGameConfirmation()); + ui->doubleClickPreviews->setChecked(settings().interface().doubleClicksOpenPreviews()); ui->compactBox->setChecked(settings().interface().compactDownloads()); ui->showMetaBox->setChecked(settings().interface().metaDownloads()); ui->checkForUpdates->setChecked(settings().checkForUpdates()); @@ -63,6 +64,7 @@ void GeneralSettingsTab::update() settings().geometry().setCenterDialogs(ui->centerDialogs->isChecked()); settings().interface().setShowChangeGameConfirmation(ui->changeGameConfirmation->isChecked()); + settings().interface().setDoubleClicksOpenPreviews(ui->doubleClickPreviews->isChecked()); settings().interface().setCompactDownloads(ui->compactBox->isChecked()); settings().interface().setMetaDownloads(ui->showMetaBox->isChecked()); settings().setCheckForUpdates(ui->checkForUpdates->isChecked()); -- cgit v1.3.1 From 91b95d00a6fda3788e774488ebeb72b28c89e656 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Wed, 4 Dec 2019 13:24:31 -0500 Subject: implemented previews on double-click for the data and conflicts tabs --- src/mainwindow.cpp | 90 +++++++++++++++++++++++++++++++++++++----- src/mainwindow.h | 1 + src/modinfodialogconflicts.cpp | 57 +++++++++++++++++++------- src/modinfodialogconflicts.h | 3 ++ src/modinfodialogfiletree.cpp | 50 +++++++++++------------ src/modinfodialogfiletree.h | 1 + src/settingsdialog.ui | 3 ++ 7 files changed, 154 insertions(+), 51 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index c365fb6b..01f683a7 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -198,6 +198,55 @@ QString UnmanagedModName() bool runLoot(QWidget* parent, OrganizerCore& core, bool didUpdateMasterList); +void setDefaultActivationActionForFile(QAction* open, QAction* preview) +{ + if (!open && !preview) { + return; + } + + QFont bold, notBold; + + if (open) { + bold = open->font(); + notBold = open->font(); + } else { + bold = preview->font(); + notBold = preview->font(); + } + + notBold.setBold(false); + bold.setBold(true); + + + const auto& s = Settings::instance(); + const auto openEnabled = (open && open->isEnabled()); + const auto previewEnabled = (preview && preview->isEnabled()); + + bool doPreview = false; + + // preview is bold if the file is previewable and [the preview on double-click + // option is enabled or the file can't be opened]; open is bold if the file + // can be opened and cannot be previewed + if (previewEnabled && s.interface().doubleClicksOpenPreviews()) { + doPreview = true; + } else if (openEnabled) { + doPreview = false; + } else if (previewEnabled) { + doPreview = true; + } else { + // shouldn't happen, checked above + return; + } + + if (open) { + open->setFont(doPreview ? notBold : bold); + } + + if (preview) { + preview->setFont(doPreview ? bold : notBold); + } +} + MainWindow::MainWindow(Settings &settings , OrganizerCore &organizerCore @@ -1770,7 +1819,23 @@ void MainWindow::expandDataTreeItem(QTreeWidgetItem *item) void MainWindow::activateDataTreeItem(QTreeWidgetItem *item, int column) { - openDataFile(item); + const auto isArchive = item->data(0, Qt::UserRole + 1).toBool(); + const auto isDirectory = item->data(0, Qt::UserRole + 3).toBool(); + + if (isArchive || isDirectory) { + return; + } + + const QString path = item->data(0, Qt::UserRole).toString(); + const QFileInfo targetInfo(path); + + const auto tryPreview = m_OrganizerCore.settings().interface().doubleClicksOpenPreviews(); + + if (tryPreview && m_PluginContainer.previewGenerator().previewSupported(targetInfo.suffix())) { + previewDataFile(item); + } else { + openDataFile(item); + } } bool MainWindow::refreshProfiles(bool selectProfile) @@ -5287,7 +5352,16 @@ void MainWindow::disableSelectedMods_clicked() void MainWindow::previewDataFile() { - QString fileName = QDir::fromNativeSeparators(m_ContextItem->data(0, Qt::UserRole).toString()); + if (m_ContextItem == nullptr) { + return; + } + + previewDataFile(m_ContextItem); +} + +void MainWindow::previewDataFile(QTreeWidgetItem* item) +{ + QString fileName = QDir::fromNativeSeparators(item->data(0, Qt::UserRole).toString()); m_OrganizerCore.previewFileWithAlternatives(this, fileName); } @@ -5413,6 +5487,7 @@ void MainWindow::on_dataTree_customContextMenuRequested(const QPoint &pos) const auto isDirectory = m_ContextItem->data(0, Qt::UserRole + 3).toBool(); QAction* open = nullptr; + QAction* preview = nullptr; if (canRunFile(isArchive, fileName)) { open = menu.addAction(tr("&Execute"), this, SLOT(openDataFile())); @@ -5421,16 +5496,10 @@ void MainWindow::on_dataTree_customContextMenuRequested(const QPoint &pos) menu.addAction(tr("Open with &VFS"), this, SLOT(runDataFileHooked())); } - if (open) { - auto bold = open->font(); - bold.setBold(true); - open->setFont(bold); - } - menu.addAction(tr("&Add as Executable"), this, SLOT(addAsExecutable())); if (m_PluginContainer.previewGenerator().previewSupported(QFileInfo(fileName).suffix())) { - menu.addAction(tr("Preview"), this, SLOT(previewDataFile())); + preview = menu.addAction(tr("Preview"), this, SLOT(previewDataFile())); } if (!isArchive && !isDirectory) { @@ -5449,7 +5518,10 @@ void MainWindow::on_dataTree_customContextMenuRequested(const QPoint &pos) menu.addAction(tr("Hide"), this, SLOT(hideFile())); } } + + setDefaultActivationActionForFile(open, preview); } + menu.addAction(tr("Write To File..."), this, SLOT(writeDataToFile())); menu.addAction(tr("Refresh"), this, SLOT(on_btnRefreshData_clicked())); diff --git a/src/mainwindow.h b/src/mainwindow.h index f5bab586..98573423 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -444,6 +444,7 @@ private slots: void runDataFileHooked(); void addAsExecutable(); void previewDataFile(); + void previewDataFile(QTreeWidgetItem* item); void hideFile(); void unhideFile(); void openDataOriginExplorer_clicked(); diff --git a/src/modinfodialogconflicts.cpp b/src/modinfodialogconflicts.cpp index daa40cb3..9c7ccc8c 100644 --- a/src/modinfodialogconflicts.cpp +++ b/src/modinfodialogconflicts.cpp @@ -12,6 +12,9 @@ using namespace MOBase; // checking whether menu items apply to them, just show all of them const std::size_t max_small_selection = 50; +// in mainwindow.cpp +void setDefaultActivationActionForFile(QAction* open, QAction* preview); + class ConflictItem { @@ -527,20 +530,43 @@ void ConflictsTab::changeItemsVisibility(QTreeView* tree, bool visible) } } -void ConflictsTab::openItems(QTreeView* tree) +void ConflictsTab::activateItems(QTreeView* tree) { + const auto tryPreview = core().settings().interface().doubleClicksOpenPreviews(); + // the menu item is only shown for a single selection, but handle all of them // in case this changes for_each_in_selection(tree, [&](const ConflictItem* item) { - core().processRunner() - .setFromFile(parentWidget(), item->fileName()) - .setWaitForCompletion() - .run(); + const auto path = item->fileName(); + + if (tryPreview && canPreviewFile(plugin(), item->isArchive(), path)) { + previewItem(item); + } else { + openItem(item); + } + + return true; + }); +} +void ConflictsTab::openItems(QTreeView* tree) +{ + // the menu item is only shown for a single selection, but handle all of them + // in case this changes + for_each_in_selection(tree, [&](const ConflictItem* item) { + openItem(item); return true; }); } +void ConflictsTab::openItem(const ConflictItem* item) +{ + core().processRunner() + .setFromFile(parentWidget(), item->fileName()) + .setWaitForCompletion() + .run(); +} + void ConflictsTab::runItemsHooked(QTreeView* tree) { // the menu item is only shown for a single selection, but handle all of them @@ -560,11 +586,16 @@ void ConflictsTab::previewItems(QTreeView* tree) // the menu item is only shown for a single selection, but handle all of them // in case this changes for_each_in_selection(tree, [&](const ConflictItem* item) { - core().previewFileWithAlternatives(parentWidget(), item->fileName()); + previewItem(item); return true; }); } +void ConflictsTab::previewItem(const ConflictItem* item) +{ + core().previewFileWithAlternatives(parentWidget(), item->fileName()); +} + void ConflictsTab::exploreItems(QTreeView* tree) { // the menu item is only shown for a single selection, but handle all of them @@ -587,10 +618,6 @@ void ConflictsTab::showContextMenu(const QPoint &pos, QTreeView* tree) openItems(tree); }); - auto bold = actions.open->font(); - bold.setBold(true); - actions.open->setFont(bold); - menu.addAction(actions.open); } @@ -654,6 +681,8 @@ void ConflictsTab::showContextMenu(const QPoint &pos, QTreeView* tree) menu.addAction(actions.unhide); } + setDefaultActivationActionForFile(actions.open, actions.preview); + if (!menu.isEmpty()) { menu.exec(tree->viewport()->mapToGlobal(pos)); } @@ -828,15 +857,15 @@ GeneralConflictsTab::GeneralConflictsTab( QObject::connect( ui->overwriteTree, &QTreeView::doubleClicked, - [&](auto&&){ m_tab->openItems(ui->overwriteTree); }); + [&](auto&&){ m_tab->activateItems(ui->overwriteTree); }); QObject::connect( ui->overwrittenTree, &QTreeView::doubleClicked, - [&](auto&& item){ m_tab->openItems(ui->overwrittenTree); }); + [&](auto&& item){ m_tab->activateItems(ui->overwrittenTree); }); QObject::connect( ui->noConflictTree, &QTreeView::doubleClicked, - [&](auto&& item){ m_tab->openItems(ui->noConflictTree); }); + [&](auto&& item){ m_tab->activateItems(ui->noConflictTree); }); QObject::connect( ui->overwriteTree, &QTreeView::customContextMenuRequested, @@ -1049,7 +1078,7 @@ AdvancedConflictsTab::AdvancedConflictsTab( QObject::connect( ui->conflictsAdvancedList, &QTreeView::activated, - [&]{ m_tab->openItems(ui->conflictsAdvancedList); }); + [&]{ m_tab->activateItems(ui->conflictsAdvancedList); }); QObject::connect( ui->conflictsAdvancedList, &QTreeView::customContextMenuRequested, diff --git a/src/modinfodialogconflicts.h b/src/modinfodialogconflicts.h index 8baa62b6..3ac8de23 100644 --- a/src/modinfodialogconflicts.h +++ b/src/modinfodialogconflicts.h @@ -107,11 +107,14 @@ public: void restoreState(const Settings& s) override; bool canHandleUnmanaged() const override; + void activateItems(QTreeView* tree); void openItems(QTreeView* tree); void runItemsHooked(QTreeView* tree); void previewItems(QTreeView* tree); void exploreItems(QTreeView* tree); + void openItem(const ConflictItem* item); + void previewItem(const ConflictItem* item); void changeItemsVisibility(QTreeView* tree, bool visible); void showContextMenu(const QPoint &pos, QTreeView* tree); diff --git a/src/modinfodialogfiletree.cpp b/src/modinfodialogfiletree.cpp index c79a5264..d1ae3823 100644 --- a/src/modinfodialogfiletree.cpp +++ b/src/modinfodialogfiletree.cpp @@ -14,6 +14,9 @@ namespace shell = MOBase::shell; // checking whether menu items apply to them, just show all of them const int max_scan_for_context_menu = 50; +// in mainwindow.cpp +void setDefaultActivationActionForFile(QAction* open, QAction* preview); + FileTreeTab::FileTreeTab(ModInfoDialogTabContext cx) : ModInfoDialogTab(std::move(cx)), m_fs(nullptr) { @@ -52,7 +55,7 @@ FileTreeTab::FileTreeTab(ModInfoDialogTabContext cx) ui->filetree->setEditTriggers( ui->filetree->editTriggers() & (~QAbstractItemView::DoubleClicked)); - connect(ui->filetree, &QTreeView::activated, [&](auto&&){ onOpen(); }); + connect(ui->filetree, &QTreeView::activated, [&](auto&&){ onActivated(); }); } void FileTreeTab::clear() @@ -141,7 +144,7 @@ void FileTreeTab::onCreateDirectory() ui->filetree->edit(newIndex); } -void FileTreeTab::onOpen() +void FileTreeTab::onActivated() { auto selection = singleSelection(); if (!selection.isValid()) { @@ -152,13 +155,24 @@ void FileTreeTab::onOpen() const auto tryPreview = core().settings().interface().doubleClicksOpenPreviews(); if (tryPreview && canPreviewFile(plugin(), false, path)) { - core().previewFile(parentWidget(), mod().name(), path); + onPreview(); } else { - core().processRunner() - .setFromFile(parentWidget(), path) - .setWaitForCompletion() - .run(); + onOpen(); + } +} + +void FileTreeTab::onOpen() +{ + auto selection = singleSelection(); + if (!selection.isValid()) { + return; } + + const auto path = m_fs->filePath(selection); + core().processRunner() + .setFromFile(parentWidget(), path) + .setWaitForCompletion() + .run(); } void FileTreeTab::onRunHooked() @@ -448,27 +462,7 @@ void FileTreeTab::onContextMenu(const QPoint &pos) menu.addAction(m_actions.preview); m_actions.preview->setEnabled(enablePreview); - auto bold = m_actions.preview->font(); - bold.setBold(true); - auto notBold = m_actions.preview->font(); - notBold.setBold(false); - - // preview is bold if the file is previewable and [the preview on double-click - // option is enabled or the file can't be opened]; open is bold if the file - // can be opened and cannot be previewed - if (enablePreview && core().settings().interface().doubleClicksOpenPreviews()) { - m_actions.open->setFont(notBold); - m_actions.preview->setFont(bold); - } else if (enableOpen) { - m_actions.open->setFont(bold); - m_actions.preview->setFont(notBold); - } else if (enablePreview) { - m_actions.open->setFont(notBold); - m_actions.preview->setFont(bold); - } else { - m_actions.open->setFont(notBold); - m_actions.preview->setFont(notBold); - } + setDefaultActivationActionForFile(m_actions.open, m_actions.preview); menu.addAction(m_actions.explore); m_actions.explore->setEnabled(enableExplore); diff --git a/src/modinfodialogfiletree.h b/src/modinfodialogfiletree.h index 2f2e501c..c3c84ed4 100644 --- a/src/modinfodialogfiletree.h +++ b/src/modinfodialogfiletree.h @@ -35,6 +35,7 @@ private: Actions m_actions; void onCreateDirectory(); + void onActivated(); void onOpen(); void onRunHooked(); void onPreview(); diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 8e175312..84ca5731 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -137,6 +137,9 @@ + + Whether double-clicking on a file opens the preview window or launches the program associated with it. This applies to the Data tab as well as the Conflicts and Filetree tabs in the mod info window. + Open previews on double-click -- cgit v1.3.1 From 2c59d13be645bb8c12adae883938c9a8652f3dee Mon Sep 17 00:00:00 2001 From: Silarn Date: Sat, 7 Dec 2019 19:31:20 -0600 Subject: Update transifex location --- src/settingsdialog.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 84ca5731..b836e321 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -102,10 +102,10 @@ - https://www.transifex.com/tannin/mod-organizer/ + https://www.transifex.com/mod-organizer-2-team/mod-organizer-2/ - <a href="https://www.transifex.com/tannin/mod-organizer/">Help translate Mod Organizer</a> + <a href="https://www.transifex.com/mod-organizer-2-team/mod-organizer-2/">Help translate Mod Organizer</a> true -- cgit v1.3.1 From db59ebdba062de05292b648a5da48e6c4630d680 Mon Sep 17 00:00:00 2001 From: Silarn Date: Sat, 14 Dec 2019 02:23:40 -0600 Subject: Fix tutorial targets --- src/settingsdialog.ui | 2 +- src/tutorials/tutorial_primer_main.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/settingsdialog.ui') diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index b836e321..2ceb91db 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -722,7 +722,7 @@ - + Nexus Connection diff --git a/src/tutorials/tutorial_primer_main.js b/src/tutorials/tutorial_primer_main.js index 7972cca4..95faa33d 100644 --- a/src/tutorials/tutorial_primer_main.js +++ b/src/tutorials/tutorial_primer_main.js @@ -80,7 +80,7 @@ function setupTooptips() { tooltipWidget("displayCategoriesBtn", qsTr("Show/hide the category pane.")) tooltipWidget("modFilterEdit", qsTr("Quickly filter the mod list as you type.")) tooltipWidget("qt_tabwidget_tabbar", qsTr("Switch between information views."), 0, true) - tooltipWidget("categoriesList", qsTr("This shows mod categories and some meta categories (in angle-brackets). Select some to filter the mod list. For example select \"\" to show only active mods.")) + tooltipWidget("categoriesGroup", qsTr("This shows mod categories and some meta categories (in angle-brackets). Select some to filter the mod list. For example select \"\" to show only active mods.")) tooltipWidget("executablesListBox", qsTr("Customizable list for choosing the program to run.")) tooltipWidget("startButton", qsTr("When this button is clicked, Mod Organizer creates a virtual directory structure then runs the program selected to the left.")) tooltipWidget("linkButton", qsTr("Will create a shortcut for quick access. The shortcut can be placed in the toolbar at the top, in the Start Menu or on the Windows Desktop.")) -- cgit v1.3.1