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 @@
+
+
@@ -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();