diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2019-08-16 10:29:42 -0400 |
|---|---|---|
| committer | isanae <14251494+isanae@users.noreply.github.com> | 2019-08-16 10:29:42 -0400 |
| commit | 965eccb328a0a2b0cb4d1945a0382df9f0f91147 (patch) | |
| tree | cdc794d2ee5876a6884373600522c81e271a9c39 /src | |
| parent | 0374291a3451c464fb27e53077da42ad21c27cd6 (diff) | |
merged DockFixer into GeometrySettings
added combobox index to settings
Diffstat (limited to 'src')
| -rw-r--r-- | src/mainwindow.cpp | 156 | ||||
| -rw-r--r-- | src/mainwindow.h | 2 | ||||
| -rw-r--r-- | src/pch.h | 1 | ||||
| -rw-r--r-- | src/settings.cpp | 258 | ||||
| -rw-r--r-- | src/settings.h | 18 |
5 files changed, 210 insertions, 225 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 7e471d24..bce92e48 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -194,90 +194,6 @@ const QSize MediumToolbarSize(32, 32); const QSize LargeToolbarSize(42, 36); -// this attempts to fix https://bugreports.qt.io/browse/QTBUG-46620 where dock -// sizes are not restored when the main window is maximized; it is used in -// MainWindow::readSettings() and MainWindow::storeSettings() -// -// there's also https://stackoverflow.com/questions/44005852, which has what -// seems to be a popular fix, but it breaks the restored size of the window -// by setting it to the desktop's resolution, so that doesn't work -// -// the only fix I could find is to remember the sizes of the docks and manually -// setting them back; saving is straightforward, but restoring is messy -// -// this also depends on the window being visible before the timer in restore() -// is fired and the timer must be processed by application.exec(); therefore, -// the splash screen _must_ be closed before readSettings() is called, because -// it has its own event loop, which seems to interfere with this -// -// all of this should become unnecessary when QTBUG-46620 is fixed -// -class DockFixer -{ -public: - static void save(MainWindow* mw, Settings& settings) - { - // saves the size of each dock - for (const auto* dock : mw->findChildren<QDockWidget*>()) { - int size = 0; - - // save the width for horizontal docks, or the height for vertical - if (orientation(mw, dock) == Qt::Horizontal) { - size = dock->size().width(); - } else { - size = dock->size().height(); - } - - settings.geometry().setDockSize(dock->objectName(), size); - } - } - - static void restore(MainWindow* mw, const Settings& settings) - { - struct DockInfo - { - QDockWidget* d; - int size = 0; - Qt::Orientation ori; - }; - - std::vector<DockInfo> dockInfos; - - // for each dock - for (auto* dock : mw->findChildren<QDockWidget*>()) { - if (auto size=settings.geometry().getDockSize(dock->objectName())) { - // remember this dock, its size and orientation - dockInfos.push_back({dock, *size, orientation(mw, dock)}); - } - } - - // the main window must have had time to process the settings from - // readSettings() or it seems to override whatever is set here - // - // some people said a single processEvents() call is enough, but it doesn't - // look like it - QTimer::singleShot(5, [=] { - for (const auto& info : dockInfos) { - mw->resizeDocks({info.d}, {info.size}, info.ori); - } - }); - } - - static Qt::Orientation orientation(QMainWindow* mw, const QDockWidget* d) - { - // docks in these areas are horizontal - const auto horizontalAreas = - Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea; - - if (mw->dockWidgetArea(const_cast<QDockWidget*>(d)) & horizontalAreas) { - return Qt::Horizontal; - } else { - return Qt::Vertical; - } - } -}; - - MainWindow::MainWindow(Settings &settings , OrganizerCore &organizerCore , PluginContainer &pluginContainer @@ -1328,12 +1244,10 @@ void MainWindow::showEvent(QShowEvent *event) QObject::tr("Please use \"Help\" from the toolbar to get usage instructions to all elements")); } - m_OrganizerCore.settings().directInterface().setValue("first_start", false); + m_OrganizerCore.settings().directInterface().setValue("first_start", false); } - // this has no visible impact when called before the ui is visible - int grouping = m_OrganizerCore.settings().directInterface().value("group_state").toInt(); - ui->groupCombo->setCurrentIndex(grouping); + m_OrganizerCore.settings().restoreIndex(ui->groupCombo); allowListResize(); @@ -1621,18 +1535,6 @@ void MainWindow::startExeAction() } - -void MainWindow::setExecutableIndex(int index) -{ - QComboBox *executableBox = findChild<QComboBox*>("executablesListBox"); - - if ((index != 0) && (executableBox->count() > index)) { - executableBox->setCurrentIndex(index); - } else { - executableBox->setCurrentIndex(1); - } -} - void MainWindow::activateSelectedProfile() { m_OrganizerCore.setCurrentProfile(ui->profileBox->currentText()); @@ -1895,7 +1797,7 @@ void MainWindow::refreshExecutablesList() ++i; } - setExecutableIndex(1); + ui->executablesListBox->setCurrentIndex(1); executablesList->setEnabled(true); } @@ -2230,29 +2132,36 @@ void MainWindow::readSettings(const Settings& settings) { settings.geometry().restoreGeometry(this); settings.geometry().restoreState(this); + settings.geometry().restoreDocks(this); settings.geometry().restoreToolbars(this); settings.geometry().restoreState(ui->splitter); settings.geometry().restoreVisibility(ui->menuBar); settings.geometry().restoreVisibility(ui->statusBar); { + // special case in case someone puts 0 in the INI + auto v = settings.getIndex(ui->executablesListBox); + if (!v || v == 0) { + v = 1; + } + + ui->executablesListBox->setCurrentIndex(*v); + } + + settings.restoreIndex(ui->groupCombo); + + { settings.geometry().restoreVisibility(ui->categoriesGroup, false); const auto v = ui->categoriesGroup->isVisible(); setCategoryListVisible(v); ui->displayCategoriesBtn->setChecked(v); } - if (auto v=settings.getSelectedExecutable()) { - setExecutableIndex(*v); - } - if (auto v=settings.getUseProxy()) { if (*v) { activateProxy(true); } } - - DockFixer::restore(this, settings); } void MainWindow::processUpdates(Settings& settings) { @@ -2297,15 +2206,11 @@ void MainWindow::processUpdates(Settings& settings) { } } -void MainWindow::storeSettings(Settings& s) { - auto& settings = s.directInterface(); - - settings.setValue("group_state", ui->groupCombo->currentIndex()); - settings.setValue("selected_executable", - ui->executablesListBox->currentIndex()); - +void MainWindow::storeSettings(Settings& s) +{ s.geometry().saveState(this); s.geometry().saveGeometry(this); + s.geometry().saveDocks(this); s.geometry().saveVisibility(ui->menuBar); s.geometry().saveVisibility(ui->statusBar); @@ -2319,7 +2224,8 @@ void MainWindow::storeSettings(Settings& s) { s.geometry().saveState(ui->downloadView->header()); s.geometry().saveState(ui->modList->header()); - DockFixer::save(this, s); + s.saveIndex(ui->groupCombo); + s.saveIndex(ui->executablesListBox); } ILockedWaitingForProcess* MainWindow::lock() @@ -2451,20 +2357,16 @@ bool MainWindow::modifyExecutablesDialog() void MainWindow::on_executablesListBox_currentIndexChanged(int index) { - QComboBox* executablesList = findChild<QComboBox*>("executablesListBox"); + if (!ui->executablesListBox->isEnabled()) { + return; + } - int previousIndex = m_OldExecutableIndex; + const int previousIndex = m_OldExecutableIndex; m_OldExecutableIndex = index; - if (executablesList->isEnabled()) { - //I think the 2nd test is impossible - if ((index == 0) || (index > static_cast<int>(m_OrganizerCore.executablesList()->size()))) { - if (modifyExecutablesDialog()) { - setExecutableIndex(previousIndex); - } - } else { - setExecutableIndex(index); - } + if (index == 0) { + modifyExecutablesDialog(); + ui->executablesListBox->setCurrentIndex(previousIndex); } } @@ -2540,7 +2442,7 @@ void MainWindow::on_actionAdd_Profile_triggered() void MainWindow::on_actionModify_Executables_triggered() { if (modifyExecutablesDialog()) { - setExecutableIndex(m_OldExecutableIndex); + ui->executablesListBox->setCurrentIndex(m_OldExecutableIndex); } } diff --git a/src/mainwindow.h b/src/mainwindow.h index a905a163..6f06b9d5 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -226,8 +226,6 @@ private: QMenu* createPopupMenu() override; void activateSelectedProfile(); - void setExecutableIndex(int index); - void startSteam(); void updateTo(QTreeWidgetItem *subTree, const std::wstring &directorySoFar, const MOShared::DirectoryEntry &directoryEntry, bool conflictsOnly, QIcon *fileIcon, QIcon *folderIcon); @@ -95,6 +95,7 @@ #include <QDialogButtonBox> #include <QDir> #include <QDirIterator> +#include <QDockWidget> #include <QDragEnterEvent> #include <QDropEvent> #include <QElapsedTimer> diff --git a/src/settings.cpp b/src/settings.cpp index 06b4446a..40f4dd95 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -28,13 +28,88 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. using namespace MOBase; template <class T> -std::optional<T> getOptional(const QSettings& s, const QString& name) +std::optional<T> getOptional( + const QSettings& s, const QString& name, std::optional<T> def={}) { if (s.contains(name)) { return s.value(name).value<T>(); } - return {}; + return def; +} + + +QString widgetNameWithTopLevel(const QWidget* widget) +{ + QStringList components; + + auto* tl = widget->window(); + + if (tl == widget) { + // this is a top level widget, such as a dialog + components.push_back(widget->objectName()); + } else { + // this is a widget + const auto toplevelName = tl->objectName(); + if (!toplevelName.isEmpty()) { + components.push_back(toplevelName); + } + + const auto widgetName = widget->objectName(); + if (!widgetName.isEmpty()) { + components.push_back(widgetName); + } + } + + if (components.isEmpty()) { + // can't do much + return "unknown_widget"; + } + + return components.join("_"); +} + +QString widgetName(const QMainWindow* w) +{ + return w->objectName(); +} + +QString widgetName(const QHeaderView* w) +{ + return widgetNameWithTopLevel(w->parentWidget()); +} + +QString widgetName(const QWidget* w) +{ + return widgetNameWithTopLevel(w); +} + +template <class Widget> +QString geoSettingName(const Widget* widget) +{ + return "geometry/" + widgetName(widget) + "_geometry"; +} + +template <class Widget> +QString stateSettingName(const Widget* widget) +{ + return "geometry/" + widgetName(widget) + "_state"; +} + +template <class Widget> +QString visibilitySettingName(const Widget* widget) +{ + return "geometry/" + widgetName(widget) + "_visibility"; +} + +QString dockSettingName(const QDockWidget* dock) +{ + return "geometry/MainWindow_docks_" + dock->objectName() + "_size"; +} + +QString indexSettingName(const QWidget* widget) +{ + return widgetNameWithTopLevel(widget) + "_index"; } @@ -395,11 +470,6 @@ void Settings::setStyleName(const QString& name) m_Settings.setValue("Settings/style", name); } -std::optional<int> Settings::getSelectedExecutable() const -{ - return getOptional<int>(m_Settings, "selected_executable"); -} - std::optional<bool> Settings::getUseProxy() const { return getOptional<bool>(m_Settings, "Settings/use_proxy"); @@ -847,6 +917,23 @@ void Settings::setExecutables(const std::vector<std::map<QString, QVariant>>& v) m_Settings.endArray(); } +std::optional<int> Settings::getIndex(QComboBox* cb) const +{ + return getOptional<int>(m_Settings, indexSettingName(cb)); +} + +void Settings::saveIndex(const QComboBox* cb) +{ + m_Settings.setValue(indexSettingName(cb), cb->currentIndex()); +} + +void Settings::restoreIndex(QComboBox* cb, std::optional<int> def) const +{ + if (auto v=getOptional<int>(m_Settings, indexSettingName(cb), def)) { + cb->setCurrentIndex(*v); + } +} + GeometrySettings& Settings::geometry() { return m_Geometry; @@ -885,70 +972,6 @@ void Settings::dump() const } -QString widgetNameWithTopLevel(const QWidget* widget) -{ - QStringList components; - - auto* tl = widget->window(); - - if (tl == widget) { - // this is a top level widget, such as a dialog - components.push_back(widget->objectName()); - } else { - // this is a widget - const auto toplevelName = tl->objectName(); - if (!toplevelName.isEmpty()) { - components.push_back(toplevelName); - } - - const auto widgetName = widget->objectName(); - if (!widgetName.isEmpty()) { - components.push_back(widgetName); - } - } - - if (components.isEmpty()) { - // can't do much - return "unknown_widget"; - } - - return components.join("_"); -} - -QString widgetName(const QMainWindow* w) -{ - return w->objectName(); -} - -QString widgetName(const QHeaderView* w) -{ - return widgetNameWithTopLevel(w->parentWidget()); -} - -QString widgetName(const QWidget* w) -{ - return widgetNameWithTopLevel(w); -} - -template <class Widget> -QString geoSettingName(const Widget* widget) -{ - return "geometry/" + widgetName(widget) + "_geometry"; -} - -template <class Widget> -QString stateSettingName(const Widget* widget) -{ - return "geometry/" + widgetName(widget) + "_state"; -} - -template <class Widget> -QString visibilitySettingName(const Widget* widget) -{ - return "geometry/" + widgetName(widget) + "_visibility"; -} - - GeometrySettings::GeometrySettings(QSettings& s) : m_Settings(s), m_Reset(false) { @@ -1037,12 +1060,7 @@ void GeometrySettings::saveVisibility(const QWidget* w) bool GeometrySettings::restoreVisibility(QWidget* w, std::optional<bool> def) const { - auto v = getOptional<bool>(m_Settings, visibilitySettingName(w)); - if (!v) { - v = def; - } - - if (v) { + if (auto v=getOptional<bool>(m_Settings, visibilitySettingName(w), def)) { w->setVisible(*v); return true; } @@ -1124,14 +1142,10 @@ void GeometrySettings::setModInfoTabOrder(const QString& names) m_Settings.setValue("mod_info_tab_order", names); } -std::optional<int> GeometrySettings::getMainWindowMonitor() const -{ - return getOptional<int>(m_Settings, "geometry/MainWindow_monitor"); -} - void GeometrySettings::centerOnMainWindowMonitor(QWidget* w) { - const auto monitor = getMainWindowMonitor(); + const auto monitor = getOptional<int>(m_Settings, "geometry/MainWindow_monitor"); + QPoint center; if (monitor && QGuiApplication::screens().size() > *monitor) { @@ -1153,14 +1167,84 @@ void GeometrySettings::saveMainWindowMonitor(const QMainWindow* w) } } -void GeometrySettings::setDockSize(const QString& name, int size) +Qt::Orientation dockOrientation(const QMainWindow* mw, const QDockWidget* d) { - m_Settings.setValue("geometry/MainWindow_docks_" + name + "_size", size); + // docks in these areas are horizontal + const auto horizontalAreas = + Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea; + + if (mw->dockWidgetArea(const_cast<QDockWidget*>(d)) & horizontalAreas) { + return Qt::Horizontal; + } else { + return Qt::Vertical; + } } -std::optional<int> GeometrySettings::getDockSize(const QString& name) const +void GeometrySettings::saveDocks(const QMainWindow* mw) { - return getOptional<int>(m_Settings, "geometry/MainWindow_docks_" + name + "_size"); + // this attempts to fix https://bugreports.qt.io/browse/QTBUG-46620 where dock + // sizes are not restored when the main window is maximized; it is used in + // MainWindow::readSettings() and MainWindow::storeSettings() + // + // there's also https://stackoverflow.com/questions/44005852, which has what + // seems to be a popular fix, but it breaks the restored size of the window + // by setting it to the desktop's resolution, so that doesn't work + // + // the only fix I could find is to remember the sizes of the docks and manually + // setting them back; saving is straightforward, but restoring is messy + // + // this also depends on the window being visible before the timer in restore() + // is fired and the timer must be processed by application.exec(); therefore, + // the splash screen _must_ be closed before readSettings() is called, because + // it has its own event loop, which seems to interfere with this + // + // all of this should become unnecessary when QTBUG-46620 is fixed + // + + // saves the size of each dock + for (const auto* dock : mw->findChildren<QDockWidget*>()) { + int size = 0; + + // save the width for horizontal docks, or the height for vertical + if (dockOrientation(mw, dock) == Qt::Horizontal) { + size = dock->size().width(); + } else { + size = dock->size().height(); + } + + m_Settings.setValue(dockSettingName(dock), size); + } +} + +void GeometrySettings::restoreDocks(QMainWindow* mw) const +{ + struct DockInfo + { + QDockWidget* d; + int size = 0; + Qt::Orientation ori; + }; + + std::vector<DockInfo> dockInfos; + + // for each dock + for (auto* dock : mw->findChildren<QDockWidget*>()) { + if (auto size=getOptional<int>(m_Settings, dockSettingName(dock))) { + // remember this dock, its size and orientation + dockInfos.push_back({dock, *size, dockOrientation(mw, dock)}); + } + } + + // the main window must have had time to process the settings from + // readSettings() or it seems to override whatever is set here + // + // some people said a single processEvents() call is enough, but it doesn't + // look like it + QTimer::singleShot(5, [=] { + for (const auto& info : dockInfos) { + mw->resizeDocks({info.d}, {info.size}, info.ori); + } + }); } diff --git a/src/settings.h b/src/settings.h index 072b4066..1b6616a0 100644 --- a/src/settings.h +++ b/src/settings.h @@ -70,25 +70,21 @@ public: void saveState(const QSplitter* splitter); bool restoreState(QSplitter* splitter) const; - void saveVisibility(const QWidget* w); - bool restoreVisibility(QWidget* w, std::optional<bool> defaultValue={}) const; - + bool restoreVisibility(QWidget* w, std::optional<bool> def={}) const; void saveToolbars(const QMainWindow* w); void restoreToolbars(QMainWindow* w) const; + void saveDocks(const QMainWindow* w); + void restoreDocks(QMainWindow* w) const; + QStringList getModInfoTabOrder() const; void setModInfoTabOrder(const QString& names); - std::optional<int> getMainWindowMonitor() const; void centerOnMainWindowMonitor(QWidget* w); void saveMainWindowMonitor(const QMainWindow* w); - void setDockSize(const QString& name, int size); - - std::optional<int> getDockSize(const QString& name) const; - private: QSettings& m_Settings; bool m_Reset; @@ -206,7 +202,6 @@ public: std::optional<QString> getStyleName() const; void setStyleName(const QString& name); - std::optional<int> getSelectedExecutable() const; std::optional<bool> getUseProxy() const; std::optional<QVersionNumber> getVersion() const; @@ -222,6 +217,11 @@ public: std::vector<std::map<QString, QVariant>> getExecutables() const; void setExecutables(const std::vector<std::map<QString, QVariant>>& v); + + std::optional<int> getIndex(QComboBox* cb) const; + void saveIndex(const QComboBox* cb); + void restoreIndex(QComboBox* cb, std::optional<int> def={}) const; + GeometrySettings& geometry(); const GeometrySettings& geometry() const; |
