diff --git a/src/gui/Application.cpp b/src/gui/Application.cpp index 273ab8763..31222401b 100644 --- a/src/gui/Application.cpp +++ b/src/gui/Application.cpp @@ -315,3 +315,15 @@ bool Application::isDarkTheme() const { return m_darkTheme; } + +void Application::restart() +{ + // Disable single instance + m_lockServer.close(); + if (m_lockFile) { + m_lockFile->unlock(); + delete m_lockFile; + } + + exit(RESTART_EXITCODE); +} diff --git a/src/gui/Application.h b/src/gui/Application.h index 21dff6aff..9f694f8c3 100644 --- a/src/gui/Application.h +++ b/src/gui/Application.h @@ -31,6 +31,8 @@ class OSEventFilter; class QLockFile; class QSocketNotifier; +constexpr int RESTART_EXITCODE = -1; + class Application : public QApplication { Q_OBJECT @@ -47,6 +49,8 @@ public: bool sendFileNamesToRunningInstance(const QStringList& fileNames); + void restart(); + signals: void openFile(const QString& filename); void anotherInstanceStarted(); diff --git a/src/gui/ApplicationSettingsWidget.cpp b/src/gui/ApplicationSettingsWidget.cpp index d3fa1ea4f..691115368 100644 --- a/src/gui/ApplicationSettingsWidget.cpp +++ b/src/gui/ApplicationSettingsWidget.cpp @@ -106,7 +106,6 @@ ApplicationSettingsWidget::ApplicationSettingsWidget(QWidget* parent) connect(m_generalUi->autoSaveAfterEveryChangeCheckBox, SIGNAL(toggled(bool)), SLOT(autoSaveToggled(bool))); connect(m_generalUi->hideWindowOnCopyCheckBox, SIGNAL(toggled(bool)), SLOT(hideWindowOnCopyCheckBoxToggled(bool))); connect(m_generalUi->systrayShowCheckBox, SIGNAL(toggled(bool)), SLOT(systrayToggled(bool))); - connect(m_generalUi->toolbarHideCheckBox, SIGNAL(toggled(bool)), SLOT(toolbarSettingsToggled(bool))); connect(m_generalUi->rememberLastDatabasesCheckBox, SIGNAL(toggled(bool)), SLOT(rememberDatabasesToggled(bool))); connect(m_generalUi->resetSettingsButton, SIGNAL(clicked()), SLOT(resetSettings())); @@ -126,7 +125,6 @@ ApplicationSettingsWidget::ApplicationSettingsWidget(QWidget* parent) m_generalUi->faviconTimeoutSpinBox->installEventFilter(mouseWheelFilter); m_generalUi->toolButtonStyleComboBox->installEventFilter(mouseWheelFilter); m_generalUi->languageComboBox->installEventFilter(mouseWheelFilter); - m_generalUi->appThemeSelection->installEventFilter(mouseWheelFilter); #ifdef WITH_XC_UPDATECHECK connect(m_generalUi->checkForUpdatesOnStartupCheckBox, SIGNAL(toggled(bool)), SLOT(checkUpdatesToggled(bool))); @@ -210,20 +208,9 @@ void ApplicationSettingsWidget::loadSettings() m_generalUi->languageComboBox->setCurrentIndex(defaultIndex); } - m_generalUi->previewHideCheckBox->setChecked(config()->get(Config::GUI_HidePreviewPanel).toBool()); - m_generalUi->toolbarHideCheckBox->setChecked(config()->get(Config::GUI_HideToolbar).toBool()); - toolbarSettingsToggled(m_generalUi->toolbarHideCheckBox->isChecked()); m_generalUi->toolbarMovableCheckBox->setChecked(config()->get(Config::GUI_MovableToolbar).toBool()); m_generalUi->monospaceNotesCheckBox->setChecked(config()->get(Config::GUI_MonospaceNotes).toBool()); - m_generalUi->appThemeSelection->clear(); - m_generalUi->appThemeSelection->addItem(tr("Automatic"), "auto"); - m_generalUi->appThemeSelection->addItem(tr("Light"), "light"); - m_generalUi->appThemeSelection->addItem(tr("Dark"), "dark"); - m_generalUi->appThemeSelection->addItem(tr("Classic (Platform-native)"), "classic"); - m_generalUi->appThemeSelection->setCurrentIndex( - m_generalUi->appThemeSelection->findData(config()->get(Config::GUI_ApplicationTheme).toString())); - m_generalUi->toolButtonStyleComboBox->clear(); m_generalUi->toolButtonStyleComboBox->addItem(tr("Icon only"), Qt::ToolButtonIconOnly); m_generalUi->toolButtonStyleComboBox->addItem(tr("Text only"), Qt::ToolButtonTextOnly); @@ -338,14 +325,9 @@ void ApplicationSettingsWidget::saveSettings() config()->set(Config::FaviconDownloadTimeout, m_generalUi->faviconTimeoutSpinBox->value()); config()->set(Config::GUI_Language, m_generalUi->languageComboBox->currentData().toString()); - config()->set(Config::GUI_HidePreviewPanel, m_generalUi->previewHideCheckBox->isChecked()); - config()->set(Config::GUI_HideToolbar, m_generalUi->toolbarHideCheckBox->isChecked()); config()->set(Config::GUI_MovableToolbar, m_generalUi->toolbarMovableCheckBox->isChecked()); config()->set(Config::GUI_MonospaceNotes, m_generalUi->monospaceNotesCheckBox->isChecked()); - QString theme = m_generalUi->appThemeSelection->currentData().toString(); - config()->set(Config::GUI_ApplicationTheme, theme); - config()->set(Config::GUI_ToolButtonStyle, m_generalUi->toolButtonStyleComboBox->currentData().toString()); config()->set(Config::GUI_ShowTrayIcon, m_generalUi->systrayShowCheckBox->isChecked()); @@ -481,13 +463,6 @@ void ApplicationSettingsWidget::systrayToggled(bool checked) m_generalUi->systrayMinimizeToTrayCheckBox->setEnabled(checked); } -void ApplicationSettingsWidget::toolbarSettingsToggled(bool checked) -{ - m_generalUi->toolbarMovableCheckBox->setEnabled(!checked); - m_generalUi->toolButtonStyleComboBox->setEnabled(!checked); - m_generalUi->toolButtonStyleLabel->setEnabled(!checked); -} - void ApplicationSettingsWidget::rememberDatabasesToggled(bool checked) { if (!checked) { diff --git a/src/gui/ApplicationSettingsWidget.h b/src/gui/ApplicationSettingsWidget.h index 63487e1b5..f36e5ef12 100644 --- a/src/gui/ApplicationSettingsWidget.h +++ b/src/gui/ApplicationSettingsWidget.h @@ -60,7 +60,6 @@ private slots: void autoSaveToggled(bool checked); void hideWindowOnCopyCheckBoxToggled(bool checked); void systrayToggled(bool checked); - void toolbarSettingsToggled(bool checked); void rememberDatabasesToggled(bool checked); void checkUpdatesToggled(bool checked); diff --git a/src/gui/ApplicationSettingsWidgetGeneral.ui b/src/gui/ApplicationSettingsWidgetGeneral.ui index fea7481aa..7324c5ab7 100644 --- a/src/gui/ApplicationSettingsWidgetGeneral.ui +++ b/src/gui/ApplicationSettingsWidgetGeneral.ui @@ -307,13 +307,6 @@ - - - - Hide the entry preview panel - - - @@ -460,8 +453,8 @@ 10 - - + + 0 @@ -472,51 +465,30 @@ Qt::StrongFocus - Application Theme Selection + Toolbar button style - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - (restart program to activate) + + QComboBox::AdjustToContents - + + + true + + + + 0 + 0 + + - (restart program to activate) + Movable toolbar - - - - Application theme: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - appThemeSelection - - - - + @@ -532,7 +504,7 @@ - + @@ -551,7 +523,27 @@ - + + + + (restart program to activate) + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + true @@ -576,66 +568,8 @@ - - - - - 0 - 0 - - - - Qt::StrongFocus - - - Toolbar button style - - - QComboBox::AdjustToContents - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - - - - - Hide toolbar - - - - - - - true - - - - 0 - 0 - - - - Movable toolbar - - - @@ -1102,20 +1036,18 @@ autoReloadOnChangeCheckBox useAtomicSavesCheckBox useGroupIconOnEntryCreationCheckBox - previewHideCheckBox minimizeOnOpenUrlCheckBox hideWindowOnCopyCheckBox minimizeOnCopyRadioButton dropToBackgroundOnCopyRadioButton faviconTimeoutSpinBox - appThemeSelection languageComboBox toolButtonStyleComboBox - toolbarHideCheckBox - toolbarMovableCheckBox monospaceNotesCheckBox + toolbarMovableCheckBox minimizeOnCloseCheckBox systrayShowCheckBox + trayIconAppearance systrayMinimizeToTrayCheckBox resetSettingsButton autoTypeEntryTitleMatchCheckBox diff --git a/src/gui/EntryPreviewWidget.cpp b/src/gui/EntryPreviewWidget.cpp index eee1dd00d..b873800a8 100644 --- a/src/gui/EntryPreviewWidget.cpp +++ b/src/gui/EntryPreviewWidget.cpp @@ -77,6 +77,12 @@ EntryPreviewWidget::EntryPreviewWidget(QWidget* parent) connect(m_ui->entryTabWidget, SIGNAL(tabBarClicked(int)), SLOT(updateTabIndexes()), Qt::QueuedConnection); connect(&m_totpTimer, SIGNAL(timeout()), SLOT(updateTotpLabel())); + connect(config(), &Config::changed, this, [this](Config::ConfigKey key) { + if (key == Config::GUI_HidePreviewPanel) { + setVisible(!config()->get(Config::GUI_HidePreviewPanel).toBool()); + } + }); + // Group m_ui->groupCloseButton->setIcon(resources()->icon("dialog-close")); connect(m_ui->groupCloseButton, SIGNAL(clicked()), SLOT(hide())); diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 3f85390f8..c0d6397c3 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -37,6 +37,7 @@ #include "core/Tools.h" #include "gui/AboutDialog.h" #include "gui/DatabaseWidget.h" +#include "gui/MessageBox.h" #include "gui/SearchWidget.h" #include "keys/CompositeKey.h" #include "keys/FileKey.h" @@ -50,7 +51,6 @@ #endif #ifdef WITH_XC_UPDATECHECK -#include "gui/MessageBox.h" #include "gui/UpdateCheckDialog.h" #include "updatecheck/UpdateChecker.h" #endif @@ -167,6 +167,8 @@ MainWindow::MainWindow() m_ui->actionEntryAddToAgent->setVisible(false); m_ui->actionEntryRemoveFromAgent->setVisible(false); + initViewMenu(); + #if defined(WITH_XC_KEESHARE) KeeShare::init(this); m_ui->settingsWidget->addSettingsPage(new SettingsPageKeeShare(m_ui->tabWidget)); @@ -1132,11 +1134,12 @@ void MainWindow::closeEvent(QCloseEvent* event) if (m_appExiting) { saveWindowInformation(); event->accept(); - QApplication::quit(); + m_restartRequested ? kpxcApp->restart() : QApplication::quit(); return; } m_appExitCalled = false; + m_restartRequested = false; event->ignore(); } @@ -1639,3 +1642,56 @@ void MainWindow::displayDesktopNotification(const QString& msg, QString title, i m_trayIcon->showMessage(title, msg, QSystemTrayIcon::Information, msTimeoutHint); #endif } + +void MainWindow::restartApp(const QString& message) +{ + auto ans = MessageBox::question( + this, tr("Restart Application?"), message, MessageBox::Yes | MessageBox::No, MessageBox::Yes); + if (ans == MessageBox::Yes) { + m_appExitCalled = true; + m_restartRequested = true; + close(); + } else { + m_restartRequested = false; + } +} + +void MainWindow::initViewMenu() +{ + m_ui->actionThemeAuto->setData("auto"); + m_ui->actionThemeLight->setData("light"); + m_ui->actionThemeDark->setData("dark"); + m_ui->actionThemeClassic->setData("classic"); + + auto themeActions = new QActionGroup(this); + themeActions->addAction(m_ui->actionThemeAuto); + themeActions->addAction(m_ui->actionThemeLight); + themeActions->addAction(m_ui->actionThemeDark); + themeActions->addAction(m_ui->actionThemeClassic); + + auto theme = config()->get(Config::GUI_ApplicationTheme).toString(); + for (auto action : themeActions->actions()) { + if (action->data() == theme) { + action->setChecked(true); + break; + } + } + + connect(themeActions, &QActionGroup::triggered, this, [this](QAction* action) { + if (action->data() != config()->get(Config::GUI_ApplicationTheme)) { + config()->set(Config::GUI_ApplicationTheme, action->data()); + restartApp(tr("You must restart the application to apply this setting. Would you like to restart now?")); + } + }); + + m_ui->actionShowToolbar->setChecked(!config()->get(Config::GUI_HideToolbar).toBool()); + connect(m_ui->actionShowToolbar, &QAction::toggled, this, [this](bool checked) { + config()->set(Config::GUI_HideToolbar, !checked); + applySettingsChanges(); + }); + + m_ui->actionShowPreviewPanel->setChecked(!config()->get(Config::GUI_HidePreviewPanel).toBool()); + connect(m_ui->actionShowPreviewPanel, &QAction::toggled, this, [](bool checked) { + config()->set(Config::GUI_HidePreviewPanel, !checked); + }); +} diff --git a/src/gui/MainWindow.h b/src/gui/MainWindow.h index 230e6256e..95e8e5a8b 100644 --- a/src/gui/MainWindow.h +++ b/src/gui/MainWindow.h @@ -81,6 +81,7 @@ public slots: void closeAllDatabases(); void lockAllDatabases(); void displayDesktopNotification(const QString& msg, QString title = "", int msTimeoutHint = 10000); + void restartApp(const QString& message); protected: void closeEvent(QCloseEvent* event) override; @@ -152,6 +153,8 @@ private: void dragEnterEvent(QDragEnterEvent* event) override; void dropEvent(QDropEvent* event) override; + void initViewMenu(); + const QScopedPointer m_ui; SignalMultiplexer m_actionMultiplexer; QPointer m_clearHistoryAction; @@ -171,6 +174,7 @@ private: bool m_appExitCalled = false; bool m_appExiting = false; + bool m_restartRequested = false; bool m_contextMenuFocusLock = false; bool m_showToolbarSeparator = false; qint64 m_lastFocusOutTime = 0; diff --git a/src/gui/MainWindow.ui b/src/gui/MainWindow.ui index c31275f5a..71efe1e6e 100644 --- a/src/gui/MainWindow.ui +++ b/src/gui/MainWindow.ui @@ -353,10 +353,28 @@ + + + View + + + + Theme + + + + + + + + + + + @@ -843,6 +861,63 @@ Remove key from SSH Agent + + + true + + + true + + + Automatic + + + + + true + + + Light + + + + + true + + + Dark + + + + + true + + + Classic (Platform-native) + + + + + true + + + true + + + Show Toolbar + + + + + true + + + true + + + Show Preview Panel + + diff --git a/src/main.cpp b/src/main.cpp index 9a0ba4172..ee8582b1b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -155,6 +155,12 @@ int main(int argc, char** argv) int exitCode = Application::exec(); + // Check if restart was requested + if (exitCode == RESTART_EXITCODE) { + QProcess* proc = new QProcess(); + proc->start(QCoreApplication::applicationFilePath()); + } + #if defined(WITH_ASAN) && defined(WITH_LSAN) // do leak check here to prevent massive tail of end-of-process leak errors from third-party libraries __lsan_do_leak_check();