unitas/app-admin/keepassx/files/tray.patch

275 lines
8.9 KiB
Diff

From 4cdb9a645d8af65ea37e3af41e668540f8a1b30c Mon Sep 17 00:00:00 2001
From: Felix Geyer <debfx@fobos.de>
Date: Sun, 2 Nov 2014 10:15:44 +0100
Subject: [PATCH] Add an option to display a tray icon.
Also implement "Minimize to tray" functionality.
---
src/core/Config.cpp | 2 ++
src/gui/MainWindow.cpp | 73 ++++++++++++++++++++++++++++++++++++++++
src/gui/MainWindow.h | 7 ++++
src/gui/SettingsWidget.cpp | 9 +++++
src/gui/SettingsWidgetGeneral.ui | 19 ++++++++++-
src/main.cpp | 2 ++
6 files changed, 111 insertions(+), 1 deletion(-)
diff --git a/src/core/Config.cpp b/src/core/Config.cpp
index d47541e..03b5129 100644
--- a/src/core/Config.cpp
+++ b/src/core/Config.cpp
@@ -104,6 +104,8 @@ void Config::init(const QString& fileName)
m_defaults.insert("security/passwordscleartext", false);
m_defaults.insert("security/autotypeask", true);
m_defaults.insert("GUI/Language", "system");
+ m_defaults.insert("GUI/ShowTrayIcon", false);
+ m_defaults.insert("GUI/MinimizeToTray", false);
}
Config* Config::instance()
diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp
index 48baa4c..dd77989 100644
--- a/src/gui/MainWindow.cpp
+++ b/src/gui/MainWindow.cpp
@@ -33,6 +33,7 @@ const QString MainWindow::BaseWindowTitle = "KeePassX";
MainWindow::MainWindow()
: m_ui(new Ui::MainWindow())
+ , m_trayIcon(Q_NULLPTR)
{
m_ui->setupUi(this);
@@ -201,6 +202,8 @@ MainWindow::MainWindow()
m_actionMultiplexer.connect(m_ui->actionSearch, SIGNAL(triggered()),
SLOT(toggleSearch()));
+
+ updateTrayIcon();
}
MainWindow::~MainWindow()
@@ -429,12 +432,26 @@ void MainWindow::closeEvent(QCloseEvent* event)
saveWindowInformation();
event->accept();
+ QApplication::quit();
}
else {
event->ignore();
}
}
+void MainWindow::changeEvent(QEvent *event)
+{
+ if ((event->type() == QEvent::WindowStateChange) && isMinimized()
+ && isTrayIconEnabled() && config()->get("GUI/MinimizeToTray").toBool())
+ {
+ event->ignore();
+ hide();
+ }
+ else {
+ QMainWindow::changeEvent(event);
+ }
+}
+
void MainWindow::saveWindowInformation()
{
config()->set("GUI/MainWindowGeometry", saveGeometry());
@@ -467,6 +484,35 @@ bool MainWindow::saveLastDatabases()
return accept;
}
+void MainWindow::updateTrayIcon()
+{
+ if (isTrayIconEnabled()) {
+ if (!m_trayIcon) {
+ m_trayIcon = new QSystemTrayIcon(filePath()->applicationIcon(), this);
+
+ QMenu* menu = new QMenu(this);
+
+ QAction* actionToggle = new QAction(tr("Toggle window"), menu);
+ menu->addAction(actionToggle);
+
+ menu->addAction(m_ui->actionQuit);
+
+ connect(m_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
+ SLOT(trayIconTriggered(QSystemTrayIcon::ActivationReason)));
+ connect(actionToggle, SIGNAL(triggered()), SLOT(toggleWindow()));
+
+ m_trayIcon->setContextMenu(menu);
+ m_trayIcon->show();
+ }
+ }
+ else {
+ if (m_trayIcon) {
+ delete m_trayIcon;
+ m_trayIcon = Q_NULLPTR;
+ }
+ }
+}
+
void MainWindow::showEntryContextMenu(const QPoint& globalPos)
{
m_ui->menuEntries->popup(globalPos);
@@ -511,4 +557,31 @@ void MainWindow::applySettingsChanges()
else {
m_inactivityTimer->deactivate();
}
+
+ updateTrayIcon();
+}
+
+void MainWindow::trayIconTriggered(QSystemTrayIcon::ActivationReason reason)
+{
+ if (reason == QSystemTrayIcon::Trigger) {
+ toggleWindow();
+ }
+}
+
+void MainWindow::toggleWindow()
+{
+ if (QApplication::activeWindow() == this) {
+ hide();
+ }
+ else {
+ show();
+ raise();
+ activateWindow();
+ }
+}
+
+bool MainWindow::isTrayIconEnabled() const
+{
+ return config()->get("GUI/ShowTrayIcon").toBool()
+ && QSystemTrayIcon::isSystemTrayAvailable();
}
diff --git a/src/gui/MainWindow.h b/src/gui/MainWindow.h
index e904426..b966703 100644
--- a/src/gui/MainWindow.h
+++ b/src/gui/MainWindow.h
@@ -20,6 +20,7 @@
#include <QActionGroup>
#include <QMainWindow>
+#include <QSystemTrayIcon>
#include "core/SignalMultiplexer.h"
#include "gui/DatabaseWidget.h"
@@ -44,6 +45,7 @@ public Q_SLOTS:
protected:
void closeEvent(QCloseEvent* event) Q_DECL_OVERRIDE;
+ void changeEvent(QEvent* event) Q_DECL_OVERRIDE;
private Q_SLOTS:
void setMenuActionState(DatabaseWidget::Mode mode = DatabaseWidget::None);
@@ -61,6 +63,8 @@ private Q_SLOTS:
void saveToolbarState(bool value);
void rememberOpenDatabases(const QString& filePath);
void applySettingsChanges();
+ void trayIconTriggered(QSystemTrayIcon::ActivationReason reason);
+ void toggleWindow();
private:
static void setShortcut(QAction* action, QKeySequence::StandardKey standard, int fallback = 0);
@@ -69,6 +73,8 @@ private Q_SLOTS:
void saveWindowInformation();
bool saveLastDatabases();
+ void updateTrayIcon();
+ bool isTrayIconEnabled() const;
const QScopedPointer<Ui::MainWindow> m_ui;
SignalMultiplexer m_actionMultiplexer;
@@ -78,6 +84,7 @@ private Q_SLOTS:
QStringList m_openDatabases;
InactivityTimer* m_inactivityTimer;
int m_countDefaultAttributes;
+ QSystemTrayIcon* m_trayIcon;
Q_DISABLE_COPY(MainWindow)
};
diff --git a/src/gui/SettingsWidget.cpp b/src/gui/SettingsWidget.cpp
index 929db37..a7863ea 100644
--- a/src/gui/SettingsWidget.cpp
+++ b/src/gui/SettingsWidget.cpp
@@ -47,6 +47,8 @@ SettingsWidget::SettingsWidget(QWidget* parent)
connect(m_generalUi->autoSaveAfterEveryChangeCheckBox, SIGNAL(toggled(bool)),
this, SLOT(enableAutoSaveOnExit(bool)));
+ connect(m_generalUi->systrayShowCheckBox, SIGNAL(toggled(bool)),
+ m_generalUi->systrayMinimizeToTrayCheckBox, SLOT(setEnabled(bool)));
connect(m_secUi->clearClipboardCheckBox, SIGNAL(toggled(bool)),
m_secUi->clearClipboardSpinBox, SLOT(setEnabled(bool)));
@@ -80,6 +82,9 @@ void SettingsWidget::loadSettings()
m_generalUi->languageComboBox->setCurrentIndex(defaultIndex);
}
+ m_generalUi->systrayShowCheckBox->setChecked(config()->get("GUI/ShowTrayIcon").toBool());
+ m_generalUi->systrayMinimizeToTrayCheckBox->setChecked(config()->get("GUI/MinimizeToTray").toBool());
+
if (autoType()->isAvailable()) {
m_globalAutoTypeKey = static_cast<Qt::Key>(config()->get("GlobalAutoTypeKey").toInt());
m_globalAutoTypeModifiers = static_cast<Qt::KeyboardModifiers>(config()->get("GlobalAutoTypeModifiers").toInt());
@@ -118,6 +123,10 @@ void SettingsWidget::saveSettings()
m_generalUi->autoTypeEntryTitleMatchCheckBox->isChecked());
int currentLangIndex = m_generalUi->languageComboBox->currentIndex();
config()->set("GUI/Language", m_generalUi->languageComboBox->itemData(currentLangIndex).toString());
+
+ config()->set("GUI/ShowTrayIcon", m_generalUi->systrayShowCheckBox->isChecked());
+ config()->set("GUI/MinimizeToTray", m_generalUi->systrayMinimizeToTrayCheckBox->isChecked());
+
if (autoType()->isAvailable()) {
config()->set("GlobalAutoTypeKey", m_generalUi->autoTypeShortcutWidget->key());
config()->set("GlobalAutoTypeModifiers",
diff --git a/src/gui/SettingsWidgetGeneral.ui b/src/gui/SettingsWidgetGeneral.ui
index f3dc079..cbad7e5 100644
--- a/src/gui/SettingsWidgetGeneral.ui
+++ b/src/gui/SettingsWidgetGeneral.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>456</width>
- <height>288</height>
+ <height>340</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
@@ -96,6 +96,23 @@
<item row="9" column="1">
<widget class="QComboBox" name="languageComboBox"/>
</item>
+ <item row="10" column="0">
+ <widget class="QCheckBox" name="systrayShowCheckBox">
+ <property name="text">
+ <string>Show a system tray icon</string>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="0">
+ <widget class="QCheckBox" name="systrayMinimizeToTrayCheckBox">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Hide window to system tray when minimized</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
<customwidgets>
diff --git a/src/main.cpp b/src/main.cpp
index b9659e4..2bdef5b 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -39,6 +39,8 @@ int main(int argc, char** argv)
// don't set organizationName as that changes the return value of
// QDesktopServices::storageLocation(QDesktopServices::DataLocation)
+ QApplication::setQuitOnLastWindowClosed(false);
+
if (!Crypto::init()) {
QString error = QCoreApplication::translate("Main",
"Fatal error while testing the cryptographic functions.");