From a8e266129a6cd35bc8db77de88c3bbbc9697be5e Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Wed, 16 Jan 2019 22:53:29 -0500 Subject: [PATCH] Corrected formatting and cleanup --- INSTALL.md | 5 +- README.md | 6 +- cmake/FindQuaZip.cmake | 16 +- snapcraft.yaml | 2 - src/core/Database.cpp | 2 +- src/crypto/CryptoHash.h | 1 - src/crypto/ssh/CMakeLists.txt | 6 +- src/gui/AboutDialog.cpp | 102 +-- src/gui/EntryPreviewWidget.cpp | 17 +- src/gui/MainWindow.cpp | 1429 ++++++++++++++++---------------- 10 files changed, 791 insertions(+), 795 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 9bdc1c868..5267cd85a 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -27,7 +27,6 @@ The following libraries are required: * libxi, libxtst, qtx11extras (optional for auto-type on X11) * libsodium (>= 1.0.12, optional for KeePassXC-Browser support) * libargon2 -* libquazip5 Prepare the Building Environment ================================ @@ -100,10 +99,12 @@ These steps place the compiled KeePassXC binary inside the `./build/src/` direct -DWITH_XC_BROWSER=[ON|OFF] Enable/Disable KeePassXC-Browser extension support (default: OFF) -DWITH_XC_NETWORKING=[ON|OFF] Enable/Disable Networking support (favicon download) (default: OFF) -DWITH_XC_SSHAGENT=[ON|OFF] Enable/Disable SSHAgent support (default: OFF) - -DWITH_XC_SHARING=[ON|OFF] Enable/Disable Sharing extension (default: OFF) + -DWITH_XC_KEESHARE=[ON|OFF] Enable/Disable KeeShare group syncronization extension (default: OFF) -DWITH_XC_TOUCHID=[ON|OFF] (macOS Only) Enable/Disable Touch ID unlock (default:OFF) -DWITH_XC_ALL=[ON|OFF] Enable/Disable compiling all plugins above (default: OFF) + -DWITH_XC_KEESHARE_SECURE=[ON|OFF] Enable/Disable KeeShare secure containers, requires libquazip5 (default: OFF) + -DWITH_TESTS=[ON|OFF] Enable/Disable building of unit tests (default: ON) -DWITH_GUI_TESTS=[ON|OFF] Enable/Disable building of GUI tests (default: OFF) -DWITH_DEV_BUILD=[ON|OFF] Enable/Disable deprecated method warnings (default: OFF) diff --git a/README.md b/README.md index d4ae0f840..6d4c29a2c 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,6 @@ # KeePassXC [![TeamCity Build Status](https://ci.keepassxc.org/app/rest/builds/buildType:\(project:KeepassXC\)/statusIcon)](https://ci.keepassxc.org/?guest=1) [![codecov](https://codecov.io/gh/keepassxreboot/keepassxc/branch/develop/graph/badge.svg)](https://codecov.io/gh/keepassxreboot/keepassxc) - -## Note -This is a feature fork to introduce the concept of Sharing to KeepPassXC. See [Using Sharing](./docs/QUICKSTART.md#using-sharing) for more details. - ## About KeePassXC [KeePassXC](https://keepassxc.org) is a cross-platform community fork of [KeePassX](https://www.keepassx.org/). @@ -38,7 +34,7 @@ so please check out your distribution's package list to see if KeePassXC is avai [Google Chrome or Chromium](https://chrome.google.com/webstore/detail/keepasshttp-connector/dafgdjggglmmknipkhngniifhplpcldb), and [passafari](https://github.com/mmichaa/passafari.safariextension/) in Safari. [[See note about KeePassHTTP]](#note-about-keepasshttp) - Browser integration with KeePassXC-Browser using [native messaging](https://developer.chrome.com/extensions/nativeMessaging) for [Mozilla Firefox](https://addons.mozilla.org/en-US/firefox/addon/keepassxc-browser/) and [Google Chrome or Chromium](https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk) -- Sharing of passwords using KeeShare. See [Using Sharing](./docs/QUICKSTART.md#using-sharing) for more details. +- Synchronize passwords using KeeShare. See [Using Sharing](./docs/QUICKSTART.md#using-sharing) for more details. - Many bug fixes For a full list of features and changes, read the [CHANGELOG](CHANGELOG) document. diff --git a/cmake/FindQuaZip.cmake b/cmake/FindQuaZip.cmake index f70973011..8d3091810 100644 --- a/cmake/FindQuaZip.cmake +++ b/cmake/FindQuaZip.cmake @@ -4,15 +4,14 @@ # QUAZIP_LIBRARIES - List of QuaZip libraries # QUAZIP_ZLIB_INCLUDE_DIR - The include dir of zlib headers - -IF (QUAZIP_INCLUDE_DIRS AND QUAZIP_LIBRARIES) +IF(QUAZIP_INCLUDE_DIRS AND QUAZIP_LIBRARIES) # in cache already SET(QUAZIP_FOUND TRUE) -ELSE (QUAZIP_INCLUDE_DIRS AND QUAZIP_LIBRARIES) - IF (Qt5Core_FOUND) +ELSE(QUAZIP_INCLUDE_DIRS AND QUAZIP_LIBRARIES) + IF(Qt5Core_FOUND) set(QUAZIP_LIB_VERSION_SUFFIX 5) ENDIF() - IF (WIN32) + IF(WIN32) FIND_PATH(QUAZIP_LIBRARY_DIR WIN32_DEBUG_POSTFIX d NAMES libquazip${QUAZIP_LIB_VERSION_SUFFIX}.dll @@ -24,11 +23,10 @@ ELSE (QUAZIP_INCLUDE_DIRS AND QUAZIP_LIBRARIES) FIND_PATH(QUAZIP_ZLIB_INCLUDE_DIR NAMES zlib.h) ELSE(WIN32) FIND_PACKAGE(PkgConfig) -# pkg_check_modules(PC_QCA2 QUIET qca2) pkg_check_modules(PC_QUAZIP quazip) FIND_LIBRARY(QUAZIP_LIBRARIES WIN32_DEBUG_POSTFIX d - NAMES quazip${QUAZIP_LIB_VERSION_SUFFIX} + NAMES quazip${QUAZIP_LIB_VERSION_SUFFIX} HINTS /usr/lib /usr/lib64 ) FIND_PATH(QUAZIP_INCLUDE_DIR quazip.h @@ -36,8 +34,8 @@ ELSE (QUAZIP_INCLUDE_DIRS AND QUAZIP_LIBRARIES) PATH_SUFFIXES quazip${QUAZIP_LIB_VERSION_SUFFIX} ) FIND_PATH(QUAZIP_ZLIB_INCLUDE_DIR zlib.h HINTS /usr/include /usr/local/include) - ENDIF (WIN32) + ENDIF(WIN32) INCLUDE(FindPackageHandleStandardArgs) SET(QUAZIP_INCLUDE_DIRS ${QUAZIP_INCLUDE_DIR} ${QUAZIP_ZLIB_INCLUDE_DIR}) find_package_handle_standard_args(QUAZIP DEFAULT_MSG QUAZIP_LIBRARIES QUAZIP_INCLUDE_DIR QUAZIP_ZLIB_INCLUDE_DIR QUAZIP_INCLUDE_DIRS) -ENDIF (QUAZIP_INCLUDE_DIRS AND QUAZIP_LIBRARIES) +ENDIF(QUAZIP_INCLUDE_DIRS AND QUAZIP_LIBRARIES) diff --git a/snapcraft.yaml b/snapcraft.yaml index ae5f42bc8..f7bc1434b 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -50,8 +50,6 @@ parts: - libsodium-dev - libargon2-0-dev - libqrencode-dev - - libquazip5-dev - - libquazip5-headers stage-packages: - dbus - qttranslations5-l10n # common translations diff --git a/src/core/Database.cpp b/src/core/Database.cpp index 0545107d0..261f2757a 100644 --- a/src/core/Database.cpp +++ b/src/core/Database.cpp @@ -476,7 +476,7 @@ bool Database::challengeMasterSeed(const QByteArray& masterSeed) m_data.masterSeed = masterSeed; return m_data.key->challenge(masterSeed, m_data.challengeResponseKey); } - return true; + return false; } void Database::setCipher(const QUuid& cipher) diff --git a/src/crypto/CryptoHash.h b/src/crypto/CryptoHash.h index bd312121a..02f90eb4d 100644 --- a/src/crypto/CryptoHash.h +++ b/src/crypto/CryptoHash.h @@ -34,7 +34,6 @@ public: explicit CryptoHash(Algorithm algo, bool hmac = false); ~CryptoHash(); void addData(const QByteArray& data); - void reset(); QByteArray result() const; void setKey(const QByteArray& data); diff --git a/src/crypto/ssh/CMakeLists.txt b/src/crypto/ssh/CMakeLists.txt index a1a31741d..fdaf68e41 100644 --- a/src/crypto/ssh/CMakeLists.txt +++ b/src/crypto/ssh/CMakeLists.txt @@ -4,9 +4,9 @@ if(WITH_XC_CRYPTO_SSH) set(crypto_ssh_SOURCES bcrypt_pbkdf.cpp blowfish.c - ASN1Key.cpp - BinaryStream.cpp - OpenSSHKey.cpp + ASN1Key.cpp + BinaryStream.cpp + OpenSSHKey.cpp ) add_library(crypto_ssh STATIC ${crypto_ssh_SOURCES}) diff --git a/src/gui/AboutDialog.cpp b/src/gui/AboutDialog.cpp index 8aac63440..7139a0224 100644 --- a/src/gui/AboutDialog.cpp +++ b/src/gui/AboutDialog.cpp @@ -28,90 +28,90 @@ #include AboutDialog::AboutDialog(QWidget* parent) - : QDialog(parent) - , m_ui(new Ui::AboutDialog()) + : QDialog(parent) + , m_ui(new Ui::AboutDialog()) { - m_ui->setupUi(this); + m_ui->setupUi(this); - resize(minimumSize()); - setWindowFlags(Qt::Sheet); - setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + resize(minimumSize()); + setWindowFlags(Qt::Sheet); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); - m_ui->nameLabel->setText(m_ui->nameLabel->text().replace("${VERSION}", KEEPASSXC_VERSION)); - QFont nameLabelFont = m_ui->nameLabel->font(); - nameLabelFont.setPointSize(nameLabelFont.pointSize() + 4); - m_ui->nameLabel->setFont(nameLabelFont); + m_ui->nameLabel->setText(m_ui->nameLabel->text().replace("${VERSION}", KEEPASSXC_VERSION)); + QFont nameLabelFont = m_ui->nameLabel->font(); + nameLabelFont.setPointSize(nameLabelFont.pointSize() + 4); + m_ui->nameLabel->setFont(nameLabelFont); - m_ui->iconLabel->setPixmap(filePath()->applicationIcon().pixmap(48)); + m_ui->iconLabel->setPixmap(filePath()->applicationIcon().pixmap(48)); - QString commitHash; - if (!QString(GIT_HEAD).isEmpty()) { - commitHash = GIT_HEAD; - } else if (!QString(DIST_HASH).contains("Format")) { - commitHash = DIST_HASH; - } + QString commitHash; + if (!QString(GIT_HEAD).isEmpty()) { + commitHash = GIT_HEAD; + } else if (!QString(DIST_HASH).contains("Format")) { + commitHash = DIST_HASH; + } - QString debugInfo = "KeePassXC - "; - debugInfo.append(tr("Version %1").arg(KEEPASSXC_VERSION).append("\n")); + QString debugInfo = "KeePassXC - "; + debugInfo.append(tr("Version %1").arg(KEEPASSXC_VERSION).append("\n")); #ifndef KEEPASSXC_BUILD_TYPE_RELEASE - debugInfo.append(tr("Build Type: %1").arg(KEEPASSXC_BUILD_TYPE).append("\n")); + debugInfo.append(tr("Build Type: %1").arg(KEEPASSXC_BUILD_TYPE).append("\n")); #endif - if (!commitHash.isEmpty()) { - debugInfo.append(tr("Revision: %1").arg(commitHash.left(7)).append("\n")); - } + if (!commitHash.isEmpty()) { + debugInfo.append(tr("Revision: %1").arg(commitHash.left(7)).append("\n")); + } #ifdef KEEPASSXC_DIST - debugInfo.append(tr("Distribution: %1").arg(KEEPASSXC_DIST_TYPE).append("\n")); + debugInfo.append(tr("Distribution: %1").arg(KEEPASSXC_DIST_TYPE).append("\n")); #endif - debugInfo.append("\n").append( - QString("%1\n- Qt %2\n- %3\n\n") - .arg(tr("Libraries:"), QString::fromLocal8Bit(qVersion()), Crypto::backendVersion())); + debugInfo.append("\n").append( + QString("%1\n- Qt %2\n- %3\n\n") + .arg(tr("Libraries:"), QString::fromLocal8Bit(qVersion()), Crypto::backendVersion())); #if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) - debugInfo.append(tr("Operating system: %1\nCPU architecture: %2\nKernel: %3 %4") - .arg(QSysInfo::prettyProductName(), - QSysInfo::currentCpuArchitecture(), - QSysInfo::kernelType(), - QSysInfo::kernelVersion())); + debugInfo.append(tr("Operating system: %1\nCPU architecture: %2\nKernel: %3 %4") + .arg(QSysInfo::prettyProductName(), + QSysInfo::currentCpuArchitecture(), + QSysInfo::kernelType(), + QSysInfo::kernelVersion())); - debugInfo.append("\n\n"); + debugInfo.append("\n\n"); #endif - QString extensions; + QString extensions; #ifdef WITH_XC_AUTOTYPE - extensions += "\n- " + tr("Auto-Type"); + extensions += "\n- " + tr("Auto-Type"); #endif #ifdef WITH_XC_BROWSER - extensions += "\n- " + tr("Browser Integration"); + extensions += "\n- " + tr("Browser Integration"); #endif #ifdef WITH_XC_SSHAGENT - extensions += "\n- " + tr("SSH Agent"); + extensions += "\n- " + tr("SSH Agent"); #endif #if defined(WITH_XC_KEESHARE_SECURE) && defined(WITH_XC_KEESHARE_INSECURE) - extensions += "\n- " + tr("KeeShare (signed and unsigned sharing)"); + extensions += "\n- " + tr("KeeShare (signed and unsigned sharing)"); #elif defined(WITH_XC_KEESHARE_SECURE) - extensions += "\n- " + tr("KeeShare (only signed sharing)"); + extensions += "\n- " + tr("KeeShare (only signed sharing)"); #elif defined(WITH_XC_KEESHARE_INSECURE) - extensions += "\n- " + tr("KeeShare (only unsigned sharing)"); + extensions += "\n- " + tr("KeeShare (only unsigned sharing)"); #endif #ifdef WITH_XC_YUBIKEY - extensions += "\n- " + tr("YubiKey"); + extensions += "\n- " + tr("YubiKey"); #endif #ifdef WITH_XC_TOUCHID - extensions += "\n- " + tr("TouchID"); + extensions += "\n- " + tr("TouchID"); #endif - if (extensions.isEmpty()) - extensions = " " + tr("None"); + if (extensions.isEmpty()) + extensions = " " + tr("None"); - debugInfo.append(tr("Enabled extensions:").append(extensions)); + debugInfo.append(tr("Enabled extensions:").append(extensions)); - m_ui->debugInfo->setPlainText(debugInfo); + m_ui->debugInfo->setPlainText(debugInfo); - setAttribute(Qt::WA_DeleteOnClose); - connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(close())); - connect(m_ui->copyToClipboard, SIGNAL(clicked()), SLOT(copyToClipboard())); + setAttribute(Qt::WA_DeleteOnClose); + connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(close())); + connect(m_ui->copyToClipboard, SIGNAL(clicked()), SLOT(copyToClipboard())); } AboutDialog::~AboutDialog() @@ -120,6 +120,6 @@ AboutDialog::~AboutDialog() void AboutDialog::copyToClipboard() { - QClipboard* clipboard = QApplication::clipboard(); - clipboard->setText(m_ui->debugInfo->toPlainText()); + QClipboard* clipboard = QApplication::clipboard(); + clipboard->setText(m_ui->debugInfo->toPlainText()); } diff --git a/src/gui/EntryPreviewWidget.cpp b/src/gui/EntryPreviewWidget.cpp index 19ec53ae9..06280a2a5 100644 --- a/src/gui/EntryPreviewWidget.cpp +++ b/src/gui/EntryPreviewWidget.cpp @@ -30,19 +30,18 @@ #include "keeshare/KeeShare.h" #endif -namespace -{ +namespace { constexpr int GeneralTabIndex = 0; } EntryPreviewWidget::EntryPreviewWidget(QWidget* parent) - : QWidget(parent) - , m_ui(new Ui::EntryPreviewWidget()) - , m_locked(false) - , m_currentEntry(nullptr) - , m_currentGroup(nullptr) - , m_selectedTabEntry(0) - , m_selectedTabGroup(0) + : QWidget(parent) + , m_ui(new Ui::EntryPreviewWidget()) + , m_locked(false) + , m_currentEntry(nullptr) + , m_currentGroup(nullptr) + , m_selectedTabEntry(0) + , m_selectedTabGroup(0) { m_ui->setupUi(this); diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index f3d1d4813..2ecaa31ce 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -20,8 +20,8 @@ #include "ui_MainWindow.h" #include -#include #include +#include #include #include #include @@ -33,12 +33,12 @@ #include "core/FilePath.h" #include "core/InactivityTimer.h" #include "core/Metadata.h" -#include "keys/CompositeKey.h" -#include "keys/PasswordKey.h" -#include "keys/FileKey.h" #include "gui/AboutDialog.h" #include "gui/DatabaseWidget.h" #include "gui/SearchWidget.h" +#include "keys/CompositeKey.h" +#include "keys/FileKey.h" +#include "keys/PasswordKey.h" #ifdef WITH_XC_SSHAGENT #include "sshagent/AgentSettingsPage.h" @@ -69,331 +69,335 @@ class BrowserPlugin : public ISettingsPage { public: - BrowserPlugin(DatabaseTabWidget* tabWidget) - { - m_nativeMessagingHost = - QSharedPointer(new NativeMessagingHost(tabWidget, browserSettings()->isEnabled())); - } + BrowserPlugin(DatabaseTabWidget* tabWidget) + { + m_nativeMessagingHost = + QSharedPointer(new NativeMessagingHost(tabWidget, browserSettings()->isEnabled())); + } - ~BrowserPlugin() - { - } + ~BrowserPlugin() + { + } - QString name() override - { - return QObject::tr("Browser Integration"); - } + QString name() override + { + return QObject::tr("Browser Integration"); + } - QIcon icon() override - { - return FilePath::instance()->icon("apps", "internet-web-browser"); - } + QIcon icon() override + { + return FilePath::instance()->icon("apps", "internet-web-browser"); + } - QWidget* createWidget() override - { - BrowserOptionDialog* dlg = new BrowserOptionDialog(); - return dlg; - } + QWidget* createWidget() override + { + BrowserOptionDialog* dlg = new BrowserOptionDialog(); + return dlg; + } - void loadSettings(QWidget* widget) override - { - qobject_cast(widget)->loadSettings(); - } + void loadSettings(QWidget* widget) override + { + qobject_cast(widget)->loadSettings(); + } - void saveSettings(QWidget* widget) override - { - qobject_cast(widget)->saveSettings(); - if (browserSettings()->isEnabled()) { - m_nativeMessagingHost->run(); - } else { - m_nativeMessagingHost->stop(); - } - } + void saveSettings(QWidget* widget) override + { + qobject_cast(widget)->saveSettings(); + if (browserSettings()->isEnabled()) { + m_nativeMessagingHost->run(); + } else { + m_nativeMessagingHost->stop(); + } + } private: - QSharedPointer m_nativeMessagingHost; + QSharedPointer m_nativeMessagingHost; }; #endif const QString MainWindow::BaseWindowTitle = "KeePassXC"; MainWindow* g_MainWindow = nullptr; -MainWindow* getMainWindow() { return g_MainWindow; } +MainWindow* getMainWindow() +{ + return g_MainWindow; +} MainWindow::MainWindow() - : m_ui(new Ui::MainWindow()) - , m_trayIcon(nullptr) - , m_appExitCalled(false) - , m_appExiting(false) + : m_ui(new Ui::MainWindow()) + , m_trayIcon(nullptr) + , m_appExitCalled(false) + , m_appExiting(false) { - g_MainWindow = this; + g_MainWindow = this; - m_ui->setupUi(this); + m_ui->setupUi(this); #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && !defined(QT_NO_DBUS) - new MainWindowAdaptor(this); - QDBusConnection dbus = QDBusConnection::sessionBus(); - dbus.registerObject("/keepassxc", this); - dbus.registerService("org.keepassxc.KeePassXC.MainWindow"); + new MainWindowAdaptor(this); + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.registerObject("/keepassxc", this); + dbus.registerService("org.keepassxc.KeePassXC.MainWindow"); #endif - setAcceptDrops(true); + setAcceptDrops(true); - // Setup the search widget in the toolbar - auto* search = new SearchWidget(); - search->connectSignals(m_actionMultiplexer); - m_searchWidgetAction = m_ui->toolBar->addWidget(search); - m_searchWidgetAction->setEnabled(false); + // Setup the search widget in the toolbar + auto* search = new SearchWidget(); + search->connectSignals(m_actionMultiplexer); + m_searchWidgetAction = m_ui->toolBar->addWidget(search); + m_searchWidgetAction->setEnabled(false); - m_countDefaultAttributes = m_ui->menuEntryCopyAttribute->actions().size(); + m_countDefaultAttributes = m_ui->menuEntryCopyAttribute->actions().size(); - restoreGeometry(config()->get("GUI/MainWindowGeometry").toByteArray()); + restoreGeometry(config()->get("GUI/MainWindowGeometry").toByteArray()); #ifdef WITH_XC_BROWSER - m_ui->settingsWidget->addSettingsPage(new BrowserPlugin(m_ui->tabWidget)); + m_ui->settingsWidget->addSettingsPage(new BrowserPlugin(m_ui->tabWidget)); #endif #ifdef WITH_XC_SSHAGENT - SSHAgent::init(this); - connect(SSHAgent::instance(), SIGNAL(error(QString)), this, SLOT(showErrorMessage(QString))); - m_ui->settingsWidget->addSettingsPage(new AgentSettingsPage(m_ui->tabWidget)); + SSHAgent::init(this); + connect(SSHAgent::instance(), SIGNAL(error(QString)), this, SLOT(showErrorMessage(QString))); + m_ui->settingsWidget->addSettingsPage(new AgentSettingsPage(m_ui->tabWidget)); #endif #if defined(WITH_XC_KEESHARE) - KeeShare::init(this); - m_ui->settingsWidget->addSettingsPage(new SettingsPageKeeShare(m_ui->tabWidget)); - connect(KeeShare::instance(), SIGNAL(sharingMessage(QString, MessageWidget::MessageType)), - SLOT(displayGlobalMessage(QString, MessageWidget::MessageType))); + KeeShare::init(this); + m_ui->settingsWidget->addSettingsPage(new SettingsPageKeeShare(m_ui->tabWidget)); + connect(KeeShare::instance(), + SIGNAL(sharingMessage(QString, MessageWidget::MessageType)), + SLOT(displayGlobalMessage(QString, MessageWidget::MessageType))); #endif - setWindowIcon(filePath()->applicationIcon()); - m_ui->globalMessageWidget->setHidden(true); - // clang-format off + setWindowIcon(filePath()->applicationIcon()); + m_ui->globalMessageWidget->setHidden(true); + // clang-format off connect(m_ui->globalMessageWidget, &MessageWidget::linkActivated, &MessageWidget::openHttpUrl); connect(m_ui->globalMessageWidget, SIGNAL(showAnimationStarted()), m_ui->globalMessageWidgetContainer, SLOT(show())); connect(m_ui->globalMessageWidget, SIGNAL(hideAnimationFinished()), m_ui->globalMessageWidgetContainer, SLOT(hide())); - // clang-format on + // clang-format on - m_clearHistoryAction = new QAction(tr("Clear history"), m_ui->menuFile); - m_lastDatabasesActions = new QActionGroup(m_ui->menuRecentDatabases); - connect(m_clearHistoryAction, SIGNAL(triggered()), this, SLOT(clearLastDatabases())); - connect(m_lastDatabasesActions, SIGNAL(triggered(QAction*)), this, SLOT(openRecentDatabase(QAction*))); - connect(m_ui->menuRecentDatabases, SIGNAL(aboutToShow()), this, SLOT(updateLastDatabasesMenu())); + m_clearHistoryAction = new QAction(tr("Clear history"), m_ui->menuFile); + m_lastDatabasesActions = new QActionGroup(m_ui->menuRecentDatabases); + connect(m_clearHistoryAction, SIGNAL(triggered()), this, SLOT(clearLastDatabases())); + connect(m_lastDatabasesActions, SIGNAL(triggered(QAction*)), this, SLOT(openRecentDatabase(QAction*))); + connect(m_ui->menuRecentDatabases, SIGNAL(aboutToShow()), this, SLOT(updateLastDatabasesMenu())); - m_copyAdditionalAttributeActions = new QActionGroup(m_ui->menuEntryCopyAttribute); - m_actionMultiplexer.connect( - m_copyAdditionalAttributeActions, SIGNAL(triggered(QAction*)), SLOT(copyAttribute(QAction*))); - connect(m_ui->menuEntryCopyAttribute, SIGNAL(aboutToShow()), this, SLOT(updateCopyAttributesMenu())); + m_copyAdditionalAttributeActions = new QActionGroup(m_ui->menuEntryCopyAttribute); + m_actionMultiplexer.connect( + m_copyAdditionalAttributeActions, SIGNAL(triggered(QAction*)), SLOT(copyAttribute(QAction*))); + connect(m_ui->menuEntryCopyAttribute, SIGNAL(aboutToShow()), this, SLOT(updateCopyAttributesMenu())); - Qt::Key globalAutoTypeKey = static_cast(config()->get("GlobalAutoTypeKey").toInt()); - Qt::KeyboardModifiers globalAutoTypeModifiers = - static_cast(config()->get("GlobalAutoTypeModifiers").toInt()); - if (globalAutoTypeKey > 0 && globalAutoTypeModifiers > 0) { - autoType()->registerGlobalShortcut(globalAutoTypeKey, globalAutoTypeModifiers); - } + Qt::Key globalAutoTypeKey = static_cast(config()->get("GlobalAutoTypeKey").toInt()); + Qt::KeyboardModifiers globalAutoTypeModifiers = + static_cast(config()->get("GlobalAutoTypeModifiers").toInt()); + if (globalAutoTypeKey > 0 && globalAutoTypeModifiers > 0) { + autoType()->registerGlobalShortcut(globalAutoTypeKey, globalAutoTypeModifiers); + } - m_ui->actionEntryAutoType->setVisible(autoType()->isAvailable()); + m_ui->actionEntryAutoType->setVisible(autoType()->isAvailable()); - m_inactivityTimer = new InactivityTimer(this); - connect(m_inactivityTimer, SIGNAL(inactivityDetected()), this, SLOT(lockDatabasesAfterInactivity())); + m_inactivityTimer = new InactivityTimer(this); + connect(m_inactivityTimer, SIGNAL(inactivityDetected()), this, SLOT(lockDatabasesAfterInactivity())); #ifdef WITH_XC_TOUCHID - m_touchIDinactivityTimer = new InactivityTimer(this); - connect(m_touchIDinactivityTimer, SIGNAL(inactivityDetected()), this, SLOT(forgetTouchIDAfterInactivity())); + m_touchIDinactivityTimer = new InactivityTimer(this); + connect(m_touchIDinactivityTimer, SIGNAL(inactivityDetected()), this, SLOT(forgetTouchIDAfterInactivity())); #endif - applySettingsChanges(); + applySettingsChanges(); - m_ui->actionDatabaseNew->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_N); - setShortcut(m_ui->actionDatabaseOpen, QKeySequence::Open, Qt::CTRL + Qt::Key_O); - setShortcut(m_ui->actionDatabaseSave, QKeySequence::Save, Qt::CTRL + Qt::Key_S); - setShortcut(m_ui->actionDatabaseSaveAs, QKeySequence::SaveAs, Qt::CTRL + Qt::SHIFT + Qt::Key_S); - setShortcut(m_ui->actionDatabaseClose, QKeySequence::Close, Qt::CTRL + Qt::Key_W); - m_ui->actionLockDatabases->setShortcut(Qt::CTRL + Qt::Key_L); - setShortcut(m_ui->actionQuit, QKeySequence::Quit, Qt::CTRL + Qt::Key_Q); - setShortcut(m_ui->actionEntryNew, QKeySequence::New, Qt::CTRL + Qt::Key_N); - m_ui->actionEntryEdit->setShortcut(Qt::CTRL + Qt::Key_E); - m_ui->actionEntryDelete->setShortcut(Qt::CTRL + Qt::Key_D); - m_ui->actionEntryDelete->setShortcut(Qt::Key_Delete); - m_ui->actionEntryClone->setShortcut(Qt::CTRL + Qt::Key_K); - m_ui->actionEntryTotp->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_T); - m_ui->actionEntryCopyTotp->setShortcut(Qt::CTRL + Qt::Key_T); - m_ui->actionEntryCopyUsername->setShortcut(Qt::CTRL + Qt::Key_B); - m_ui->actionEntryCopyPassword->setShortcut(Qt::CTRL + Qt::Key_C); - m_ui->actionEntryAutoType->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_V); - m_ui->actionEntryOpenUrl->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_U); - m_ui->actionEntryCopyURL->setShortcut(Qt::CTRL + Qt::Key_U); + m_ui->actionDatabaseNew->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_N); + setShortcut(m_ui->actionDatabaseOpen, QKeySequence::Open, Qt::CTRL + Qt::Key_O); + setShortcut(m_ui->actionDatabaseSave, QKeySequence::Save, Qt::CTRL + Qt::Key_S); + setShortcut(m_ui->actionDatabaseSaveAs, QKeySequence::SaveAs, Qt::CTRL + Qt::SHIFT + Qt::Key_S); + setShortcut(m_ui->actionDatabaseClose, QKeySequence::Close, Qt::CTRL + Qt::Key_W); + m_ui->actionLockDatabases->setShortcut(Qt::CTRL + Qt::Key_L); + setShortcut(m_ui->actionQuit, QKeySequence::Quit, Qt::CTRL + Qt::Key_Q); + setShortcut(m_ui->actionEntryNew, QKeySequence::New, Qt::CTRL + Qt::Key_N); + m_ui->actionEntryEdit->setShortcut(Qt::CTRL + Qt::Key_E); + m_ui->actionEntryDelete->setShortcut(Qt::CTRL + Qt::Key_D); + m_ui->actionEntryDelete->setShortcut(Qt::Key_Delete); + m_ui->actionEntryClone->setShortcut(Qt::CTRL + Qt::Key_K); + m_ui->actionEntryTotp->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_T); + m_ui->actionEntryCopyTotp->setShortcut(Qt::CTRL + Qt::Key_T); + m_ui->actionEntryCopyUsername->setShortcut(Qt::CTRL + Qt::Key_B); + m_ui->actionEntryCopyPassword->setShortcut(Qt::CTRL + Qt::Key_C); + m_ui->actionEntryAutoType->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_V); + m_ui->actionEntryOpenUrl->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_U); + m_ui->actionEntryCopyURL->setShortcut(Qt::CTRL + Qt::Key_U); #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) - // Qt 5.10 introduced a new "feature" to hide shortcuts in context menus - // Unfortunately, Qt::AA_DontShowShortcutsInContextMenus is broken, have to manually enable them - m_ui->actionEntryNew->setShortcutVisibleInContextMenu(true); - m_ui->actionEntryEdit->setShortcutVisibleInContextMenu(true); - m_ui->actionEntryDelete->setShortcutVisibleInContextMenu(true); - m_ui->actionEntryClone->setShortcutVisibleInContextMenu(true); - m_ui->actionEntryTotp->setShortcutVisibleInContextMenu(true); - m_ui->actionEntryCopyTotp->setShortcutVisibleInContextMenu(true); - m_ui->actionEntryCopyUsername->setShortcutVisibleInContextMenu(true); - m_ui->actionEntryCopyPassword->setShortcutVisibleInContextMenu(true); - m_ui->actionEntryAutoType->setShortcutVisibleInContextMenu(true); - m_ui->actionEntryOpenUrl->setShortcutVisibleInContextMenu(true); - m_ui->actionEntryCopyURL->setShortcutVisibleInContextMenu(true); + // Qt 5.10 introduced a new "feature" to hide shortcuts in context menus + // Unfortunately, Qt::AA_DontShowShortcutsInContextMenus is broken, have to manually enable them + m_ui->actionEntryNew->setShortcutVisibleInContextMenu(true); + m_ui->actionEntryEdit->setShortcutVisibleInContextMenu(true); + m_ui->actionEntryDelete->setShortcutVisibleInContextMenu(true); + m_ui->actionEntryClone->setShortcutVisibleInContextMenu(true); + m_ui->actionEntryTotp->setShortcutVisibleInContextMenu(true); + m_ui->actionEntryCopyTotp->setShortcutVisibleInContextMenu(true); + m_ui->actionEntryCopyUsername->setShortcutVisibleInContextMenu(true); + m_ui->actionEntryCopyPassword->setShortcutVisibleInContextMenu(true); + m_ui->actionEntryAutoType->setShortcutVisibleInContextMenu(true); + m_ui->actionEntryOpenUrl->setShortcutVisibleInContextMenu(true); + m_ui->actionEntryCopyURL->setShortcutVisibleInContextMenu(true); #endif - // Control window state - new QShortcut(Qt::CTRL + Qt::Key_M, this, SLOT(showMinimized())); - new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_M, this, SLOT(hideWindow())); - // Control database tabs - new QShortcut(Qt::CTRL + Qt::Key_Tab, this, SLOT(selectNextDatabaseTab())); - new QShortcut(Qt::CTRL + Qt::Key_PageUp, this, SLOT(selectNextDatabaseTab())); - new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_Tab, this, SLOT(selectPreviousDatabaseTab())); - new QShortcut(Qt::CTRL + Qt::Key_PageDown, this, SLOT(selectPreviousDatabaseTab())); - // Toggle password and username visibility in entry view - new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_C, this, SLOT(togglePasswordsHidden())); - new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_B, this, SLOT(toggleUsernamesHidden())); + // Control window state + new QShortcut(Qt::CTRL + Qt::Key_M, this, SLOT(showMinimized())); + new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_M, this, SLOT(hideWindow())); + // Control database tabs + new QShortcut(Qt::CTRL + Qt::Key_Tab, this, SLOT(selectNextDatabaseTab())); + new QShortcut(Qt::CTRL + Qt::Key_PageUp, this, SLOT(selectNextDatabaseTab())); + new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_Tab, this, SLOT(selectPreviousDatabaseTab())); + new QShortcut(Qt::CTRL + Qt::Key_PageDown, this, SLOT(selectPreviousDatabaseTab())); + // Toggle password and username visibility in entry view + new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_C, this, SLOT(togglePasswordsHidden())); + new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_B, this, SLOT(toggleUsernamesHidden())); - m_ui->actionDatabaseNew->setIcon(filePath()->icon("actions", "document-new")); - m_ui->actionDatabaseOpen->setIcon(filePath()->icon("actions", "document-open")); - m_ui->actionDatabaseSave->setIcon(filePath()->icon("actions", "document-save")); - m_ui->actionDatabaseSaveAs->setIcon(filePath()->icon("actions", "document-save-as")); - m_ui->actionDatabaseClose->setIcon(filePath()->icon("actions", "document-close")); - m_ui->actionChangeDatabaseSettings->setIcon(filePath()->icon("actions", "document-edit")); - m_ui->actionChangeMasterKey->setIcon(filePath()->icon("actions", "database-change-key")); - m_ui->actionLockDatabases->setIcon(filePath()->icon("actions", "document-encrypt")); - m_ui->actionQuit->setIcon(filePath()->icon("actions", "application-exit")); + m_ui->actionDatabaseNew->setIcon(filePath()->icon("actions", "document-new")); + m_ui->actionDatabaseOpen->setIcon(filePath()->icon("actions", "document-open")); + m_ui->actionDatabaseSave->setIcon(filePath()->icon("actions", "document-save")); + m_ui->actionDatabaseSaveAs->setIcon(filePath()->icon("actions", "document-save-as")); + m_ui->actionDatabaseClose->setIcon(filePath()->icon("actions", "document-close")); + m_ui->actionChangeDatabaseSettings->setIcon(filePath()->icon("actions", "document-edit")); + m_ui->actionChangeMasterKey->setIcon(filePath()->icon("actions", "database-change-key")); + m_ui->actionLockDatabases->setIcon(filePath()->icon("actions", "document-encrypt")); + m_ui->actionQuit->setIcon(filePath()->icon("actions", "application-exit")); - m_ui->actionEntryNew->setIcon(filePath()->icon("actions", "entry-new")); - m_ui->actionEntryClone->setIcon(filePath()->icon("actions", "entry-clone")); - m_ui->actionEntryEdit->setIcon(filePath()->icon("actions", "entry-edit")); - m_ui->actionEntryDelete->setIcon(filePath()->icon("actions", "entry-delete")); - m_ui->actionEntryAutoType->setIcon(filePath()->icon("actions", "auto-type")); - m_ui->actionEntryCopyUsername->setIcon(filePath()->icon("actions", "username-copy")); - m_ui->actionEntryCopyPassword->setIcon(filePath()->icon("actions", "password-copy")); - m_ui->actionEntryCopyURL->setIcon(filePath()->icon("actions", "url-copy")); + m_ui->actionEntryNew->setIcon(filePath()->icon("actions", "entry-new")); + m_ui->actionEntryClone->setIcon(filePath()->icon("actions", "entry-clone")); + m_ui->actionEntryEdit->setIcon(filePath()->icon("actions", "entry-edit")); + m_ui->actionEntryDelete->setIcon(filePath()->icon("actions", "entry-delete")); + m_ui->actionEntryAutoType->setIcon(filePath()->icon("actions", "auto-type")); + m_ui->actionEntryCopyUsername->setIcon(filePath()->icon("actions", "username-copy")); + m_ui->actionEntryCopyPassword->setIcon(filePath()->icon("actions", "password-copy")); + m_ui->actionEntryCopyURL->setIcon(filePath()->icon("actions", "url-copy")); - m_ui->actionGroupNew->setIcon(filePath()->icon("actions", "group-new")); - m_ui->actionGroupEdit->setIcon(filePath()->icon("actions", "group-edit")); - m_ui->actionGroupDelete->setIcon(filePath()->icon("actions", "group-delete")); - m_ui->actionGroupEmptyRecycleBin->setIcon(filePath()->icon("actions", "group-empty-trash")); + m_ui->actionGroupNew->setIcon(filePath()->icon("actions", "group-new")); + m_ui->actionGroupEdit->setIcon(filePath()->icon("actions", "group-edit")); + m_ui->actionGroupDelete->setIcon(filePath()->icon("actions", "group-delete")); + m_ui->actionGroupEmptyRecycleBin->setIcon(filePath()->icon("actions", "group-empty-trash")); - m_ui->actionSettings->setIcon(filePath()->icon("actions", "configure")); - m_ui->actionPasswordGenerator->setIcon(filePath()->icon("actions", "password-generator")); + m_ui->actionSettings->setIcon(filePath()->icon("actions", "configure")); + m_ui->actionPasswordGenerator->setIcon(filePath()->icon("actions", "password-generator")); - m_ui->actionAbout->setIcon(filePath()->icon("actions", "help-about")); + m_ui->actionAbout->setIcon(filePath()->icon("actions", "help-about")); - m_actionMultiplexer.connect( - SIGNAL(currentModeChanged(DatabaseWidget::Mode)), this, SLOT(setMenuActionState(DatabaseWidget::Mode))); - m_actionMultiplexer.connect(SIGNAL(groupChanged()), this, SLOT(setMenuActionState())); - m_actionMultiplexer.connect(SIGNAL(entrySelectionChanged()), this, SLOT(setMenuActionState())); - m_actionMultiplexer.connect(SIGNAL(groupContextMenuRequested(QPoint)), this, SLOT(showGroupContextMenu(QPoint))); - m_actionMultiplexer.connect(SIGNAL(entryContextMenuRequested(QPoint)), this, SLOT(showEntryContextMenu(QPoint))); + m_actionMultiplexer.connect( + SIGNAL(currentModeChanged(DatabaseWidget::Mode)), this, SLOT(setMenuActionState(DatabaseWidget::Mode))); + m_actionMultiplexer.connect(SIGNAL(groupChanged()), this, SLOT(setMenuActionState())); + m_actionMultiplexer.connect(SIGNAL(entrySelectionChanged()), this, SLOT(setMenuActionState())); + m_actionMultiplexer.connect(SIGNAL(groupContextMenuRequested(QPoint)), this, SLOT(showGroupContextMenu(QPoint))); + m_actionMultiplexer.connect(SIGNAL(entryContextMenuRequested(QPoint)), this, SLOT(showEntryContextMenu(QPoint))); - // Notify search when the active database changes or gets locked - connect(m_ui->tabWidget, - SIGNAL(activateDatabaseChanged(DatabaseWidget*)), - search, - SLOT(databaseChanged(DatabaseWidget*))); - connect(m_ui->tabWidget, SIGNAL(databaseLocked(DatabaseWidget*)), search, SLOT(databaseChanged())); + // Notify search when the active database changes or gets locked + connect(m_ui->tabWidget, + SIGNAL(activateDatabaseChanged(DatabaseWidget*)), + search, + SLOT(databaseChanged(DatabaseWidget*))); + connect(m_ui->tabWidget, SIGNAL(databaseLocked(DatabaseWidget*)), search, SLOT(databaseChanged())); - connect(m_ui->tabWidget, SIGNAL(tabNameChanged()), SLOT(updateWindowTitle())); - connect(m_ui->tabWidget, SIGNAL(currentChanged(int)), SLOT(updateWindowTitle())); - connect(m_ui->tabWidget, SIGNAL(currentChanged(int)), SLOT(databaseTabChanged(int))); - connect(m_ui->tabWidget, SIGNAL(currentChanged(int)), SLOT(setMenuActionState())); - connect(m_ui->tabWidget, SIGNAL(databaseLocked(DatabaseWidget*)), SLOT(databaseStatusChanged(DatabaseWidget*))); - connect(m_ui->tabWidget, SIGNAL(databaseUnlocked(DatabaseWidget*)), SLOT(databaseStatusChanged(DatabaseWidget*))); - connect(m_ui->stackedWidget, SIGNAL(currentChanged(int)), SLOT(setMenuActionState())); - connect(m_ui->stackedWidget, SIGNAL(currentChanged(int)), SLOT(updateWindowTitle())); - connect(m_ui->settingsWidget, SIGNAL(accepted()), SLOT(applySettingsChanges())); - connect(m_ui->settingsWidget, SIGNAL(apply()), SLOT(applySettingsChanges())); - connect(m_ui->settingsWidget, SIGNAL(accepted()), SLOT(switchToDatabases())); - connect(m_ui->settingsWidget, SIGNAL(rejected()), SLOT(switchToDatabases())); + connect(m_ui->tabWidget, SIGNAL(tabNameChanged()), SLOT(updateWindowTitle())); + connect(m_ui->tabWidget, SIGNAL(currentChanged(int)), SLOT(updateWindowTitle())); + connect(m_ui->tabWidget, SIGNAL(currentChanged(int)), SLOT(databaseTabChanged(int))); + connect(m_ui->tabWidget, SIGNAL(currentChanged(int)), SLOT(setMenuActionState())); + connect(m_ui->tabWidget, SIGNAL(databaseLocked(DatabaseWidget*)), SLOT(databaseStatusChanged(DatabaseWidget*))); + connect(m_ui->tabWidget, SIGNAL(databaseUnlocked(DatabaseWidget*)), SLOT(databaseStatusChanged(DatabaseWidget*))); + connect(m_ui->stackedWidget, SIGNAL(currentChanged(int)), SLOT(setMenuActionState())); + connect(m_ui->stackedWidget, SIGNAL(currentChanged(int)), SLOT(updateWindowTitle())); + connect(m_ui->settingsWidget, SIGNAL(accepted()), SLOT(applySettingsChanges())); + connect(m_ui->settingsWidget, SIGNAL(apply()), SLOT(applySettingsChanges())); + connect(m_ui->settingsWidget, SIGNAL(accepted()), SLOT(switchToDatabases())); + connect(m_ui->settingsWidget, SIGNAL(rejected()), SLOT(switchToDatabases())); - connect(m_ui->actionDatabaseNew, SIGNAL(triggered()), m_ui->tabWidget, SLOT(newDatabase())); - connect(m_ui->actionDatabaseOpen, SIGNAL(triggered()), m_ui->tabWidget, SLOT(openDatabase())); - connect(m_ui->actionDatabaseSave, SIGNAL(triggered()), m_ui->tabWidget, SLOT(saveDatabase())); - connect(m_ui->actionDatabaseSaveAs, SIGNAL(triggered()), m_ui->tabWidget, SLOT(saveDatabaseAs())); - connect(m_ui->actionDatabaseClose, SIGNAL(triggered()), m_ui->tabWidget, SLOT(closeCurrentDatabaseTab())); - connect(m_ui->actionDatabaseMerge, SIGNAL(triggered()), m_ui->tabWidget, SLOT(mergeDatabase())); - connect(m_ui->actionChangeMasterKey, SIGNAL(triggered()), m_ui->tabWidget, SLOT(changeMasterKey())); - connect(m_ui->actionChangeDatabaseSettings, SIGNAL(triggered()), m_ui->tabWidget, SLOT(changeDatabaseSettings())); - connect(m_ui->actionImportCsv, SIGNAL(triggered()), m_ui->tabWidget, SLOT(importCsv())); - connect(m_ui->actionImportKeePass1, SIGNAL(triggered()), m_ui->tabWidget, SLOT(importKeePass1Database())); - connect(m_ui->actionExportCsv, SIGNAL(triggered()), m_ui->tabWidget, SLOT(exportToCsv())); - connect(m_ui->actionLockDatabases, SIGNAL(triggered()), m_ui->tabWidget, SLOT(lockDatabases())); - connect(m_ui->actionQuit, SIGNAL(triggered()), SLOT(appExit())); + connect(m_ui->actionDatabaseNew, SIGNAL(triggered()), m_ui->tabWidget, SLOT(newDatabase())); + connect(m_ui->actionDatabaseOpen, SIGNAL(triggered()), m_ui->tabWidget, SLOT(openDatabase())); + connect(m_ui->actionDatabaseSave, SIGNAL(triggered()), m_ui->tabWidget, SLOT(saveDatabase())); + connect(m_ui->actionDatabaseSaveAs, SIGNAL(triggered()), m_ui->tabWidget, SLOT(saveDatabaseAs())); + connect(m_ui->actionDatabaseClose, SIGNAL(triggered()), m_ui->tabWidget, SLOT(closeCurrentDatabaseTab())); + connect(m_ui->actionDatabaseMerge, SIGNAL(triggered()), m_ui->tabWidget, SLOT(mergeDatabase())); + connect(m_ui->actionChangeMasterKey, SIGNAL(triggered()), m_ui->tabWidget, SLOT(changeMasterKey())); + connect(m_ui->actionChangeDatabaseSettings, SIGNAL(triggered()), m_ui->tabWidget, SLOT(changeDatabaseSettings())); + connect(m_ui->actionImportCsv, SIGNAL(triggered()), m_ui->tabWidget, SLOT(importCsv())); + connect(m_ui->actionImportKeePass1, SIGNAL(triggered()), m_ui->tabWidget, SLOT(importKeePass1Database())); + connect(m_ui->actionExportCsv, SIGNAL(triggered()), m_ui->tabWidget, SLOT(exportToCsv())); + connect(m_ui->actionLockDatabases, SIGNAL(triggered()), m_ui->tabWidget, SLOT(lockDatabases())); + connect(m_ui->actionQuit, SIGNAL(triggered()), SLOT(appExit())); - m_actionMultiplexer.connect(m_ui->actionEntryNew, SIGNAL(triggered()), SLOT(createEntry())); - m_actionMultiplexer.connect(m_ui->actionEntryClone, SIGNAL(triggered()), SLOT(cloneEntry())); - m_actionMultiplexer.connect(m_ui->actionEntryEdit, SIGNAL(triggered()), SLOT(switchToEntryEdit())); - m_actionMultiplexer.connect(m_ui->actionEntryDelete, SIGNAL(triggered()), SLOT(deleteSelectedEntries())); + m_actionMultiplexer.connect(m_ui->actionEntryNew, SIGNAL(triggered()), SLOT(createEntry())); + m_actionMultiplexer.connect(m_ui->actionEntryClone, SIGNAL(triggered()), SLOT(cloneEntry())); + m_actionMultiplexer.connect(m_ui->actionEntryEdit, SIGNAL(triggered()), SLOT(switchToEntryEdit())); + m_actionMultiplexer.connect(m_ui->actionEntryDelete, SIGNAL(triggered()), SLOT(deleteSelectedEntries())); - m_actionMultiplexer.connect(m_ui->actionEntryTotp, SIGNAL(triggered()), SLOT(showTotp())); - m_actionMultiplexer.connect(m_ui->actionEntrySetupTotp, SIGNAL(triggered()), SLOT(setupTotp())); + m_actionMultiplexer.connect(m_ui->actionEntryTotp, SIGNAL(triggered()), SLOT(showTotp())); + m_actionMultiplexer.connect(m_ui->actionEntrySetupTotp, SIGNAL(triggered()), SLOT(setupTotp())); - m_actionMultiplexer.connect(m_ui->actionEntryCopyTotp, SIGNAL(triggered()), SLOT(copyTotp())); - m_actionMultiplexer.connect(m_ui->actionEntryTotpQRCode, SIGNAL(triggered()), SLOT(showTotpKeyQrCode())); - m_actionMultiplexer.connect(m_ui->actionEntryCopyTitle, SIGNAL(triggered()), SLOT(copyTitle())); - m_actionMultiplexer.connect(m_ui->actionEntryCopyUsername, SIGNAL(triggered()), SLOT(copyUsername())); - m_actionMultiplexer.connect(m_ui->actionEntryCopyPassword, SIGNAL(triggered()), SLOT(copyPassword())); - m_actionMultiplexer.connect(m_ui->actionEntryCopyURL, SIGNAL(triggered()), SLOT(copyURL())); - m_actionMultiplexer.connect(m_ui->actionEntryCopyNotes, SIGNAL(triggered()), SLOT(copyNotes())); - m_actionMultiplexer.connect(m_ui->actionEntryAutoType, SIGNAL(triggered()), SLOT(performAutoType())); - m_actionMultiplexer.connect(m_ui->actionEntryOpenUrl, SIGNAL(triggered()), SLOT(openUrl())); + m_actionMultiplexer.connect(m_ui->actionEntryCopyTotp, SIGNAL(triggered()), SLOT(copyTotp())); + m_actionMultiplexer.connect(m_ui->actionEntryTotpQRCode, SIGNAL(triggered()), SLOT(showTotpKeyQrCode())); + m_actionMultiplexer.connect(m_ui->actionEntryCopyTitle, SIGNAL(triggered()), SLOT(copyTitle())); + m_actionMultiplexer.connect(m_ui->actionEntryCopyUsername, SIGNAL(triggered()), SLOT(copyUsername())); + m_actionMultiplexer.connect(m_ui->actionEntryCopyPassword, SIGNAL(triggered()), SLOT(copyPassword())); + m_actionMultiplexer.connect(m_ui->actionEntryCopyURL, SIGNAL(triggered()), SLOT(copyURL())); + m_actionMultiplexer.connect(m_ui->actionEntryCopyNotes, SIGNAL(triggered()), SLOT(copyNotes())); + m_actionMultiplexer.connect(m_ui->actionEntryAutoType, SIGNAL(triggered()), SLOT(performAutoType())); + m_actionMultiplexer.connect(m_ui->actionEntryOpenUrl, SIGNAL(triggered()), SLOT(openUrl())); - m_actionMultiplexer.connect(m_ui->actionGroupNew, SIGNAL(triggered()), SLOT(createGroup())); - m_actionMultiplexer.connect(m_ui->actionGroupEdit, SIGNAL(triggered()), SLOT(switchToGroupEdit())); - m_actionMultiplexer.connect(m_ui->actionGroupDelete, SIGNAL(triggered()), SLOT(deleteGroup())); - m_actionMultiplexer.connect(m_ui->actionGroupEmptyRecycleBin, SIGNAL(triggered()), SLOT(emptyRecycleBin())); + m_actionMultiplexer.connect(m_ui->actionGroupNew, SIGNAL(triggered()), SLOT(createGroup())); + m_actionMultiplexer.connect(m_ui->actionGroupEdit, SIGNAL(triggered()), SLOT(switchToGroupEdit())); + m_actionMultiplexer.connect(m_ui->actionGroupDelete, SIGNAL(triggered()), SLOT(deleteGroup())); + m_actionMultiplexer.connect(m_ui->actionGroupEmptyRecycleBin, SIGNAL(triggered()), SLOT(emptyRecycleBin())); - connect(m_ui->actionSettings, SIGNAL(toggled(bool)), SLOT(switchToSettings(bool))); - connect(m_ui->actionPasswordGenerator, SIGNAL(toggled(bool)), SLOT(switchToPasswordGen(bool))); - connect(m_ui->passwordGeneratorWidget, SIGNAL(dialogTerminated()), SLOT(closePasswordGen())); + connect(m_ui->actionSettings, SIGNAL(toggled(bool)), SLOT(switchToSettings(bool))); + connect(m_ui->actionPasswordGenerator, SIGNAL(toggled(bool)), SLOT(switchToPasswordGen(bool))); + connect(m_ui->passwordGeneratorWidget, SIGNAL(dialogTerminated()), SLOT(closePasswordGen())); - connect(m_ui->welcomeWidget, SIGNAL(newDatabase()), SLOT(switchToNewDatabase())); - connect(m_ui->welcomeWidget, SIGNAL(openDatabase()), SLOT(switchToOpenDatabase())); - connect(m_ui->welcomeWidget, SIGNAL(openDatabaseFile(QString)), SLOT(switchToDatabaseFile(QString))); - connect(m_ui->welcomeWidget, SIGNAL(importKeePass1Database()), SLOT(switchToKeePass1Database())); - connect(m_ui->welcomeWidget, SIGNAL(importCsv()), SLOT(switchToCsvImport())); + connect(m_ui->welcomeWidget, SIGNAL(newDatabase()), SLOT(switchToNewDatabase())); + connect(m_ui->welcomeWidget, SIGNAL(openDatabase()), SLOT(switchToOpenDatabase())); + connect(m_ui->welcomeWidget, SIGNAL(openDatabaseFile(QString)), SLOT(switchToDatabaseFile(QString))); + connect(m_ui->welcomeWidget, SIGNAL(importKeePass1Database()), SLOT(switchToKeePass1Database())); + connect(m_ui->welcomeWidget, SIGNAL(importCsv()), SLOT(switchToCsvImport())); - connect(m_ui->actionAbout, SIGNAL(triggered()), SLOT(showAboutDialog())); - connect(m_ui->actionDonate, SIGNAL(triggered()), SLOT(openDonateUrl())); - connect(m_ui->actionBugReport, SIGNAL(triggered()), SLOT(openBugReportUrl())); + connect(m_ui->actionAbout, SIGNAL(triggered()), SLOT(showAboutDialog())); + connect(m_ui->actionDonate, SIGNAL(triggered()), SLOT(openDonateUrl())); + connect(m_ui->actionBugReport, SIGNAL(triggered()), SLOT(openBugReportUrl())); #ifdef Q_OS_MACOS - setUnifiedTitleAndToolBarOnMac(true); + setUnifiedTitleAndToolBarOnMac(true); #endif - // clang-format off + // clang-format off connect(m_ui->tabWidget, SIGNAL(messageGlobal(QString,MessageWidget::MessageType)), this, SLOT(displayGlobalMessage(QString,MessageWidget::MessageType))); - // clang-format on + // clang-format on - connect(m_ui->tabWidget, SIGNAL(messageDismissGlobal()), this, SLOT(hideGlobalMessage())); + connect(m_ui->tabWidget, SIGNAL(messageDismissGlobal()), this, SLOT(hideGlobalMessage())); - m_screenLockListener = new ScreenLockListener(this); - connect(m_screenLockListener, SIGNAL(screenLocked()), SLOT(handleScreenLock())); + m_screenLockListener = new ScreenLockListener(this); + connect(m_screenLockListener, SIGNAL(screenLocked()), SLOT(handleScreenLock())); - updateTrayIcon(); + updateTrayIcon(); - if (config()->hasAccessError()) { - m_ui->globalMessageWidget->showMessage(tr("Access error for config file %1").arg(config()->getFileName()), - MessageWidget::Error); - } + if (config()->hasAccessError()) { + m_ui->globalMessageWidget->showMessage(tr("Access error for config file %1").arg(config()->getFileName()), + MessageWidget::Error); + } #if !defined(KEEPASSXC_BUILD_TYPE_RELEASE) - m_ui->globalMessageWidget->showMessage( - tr("WARNING: You are using an unstable build of KeePassXC!\n" - "There is a high risk of corruption, maintain a backup of your databases.\n" - "This version is not meant for production use."), - MessageWidget::Warning, - -1); + m_ui->globalMessageWidget->showMessage( + tr("WARNING: You are using an unstable build of KeePassXC!\n" + "There is a high risk of corruption, maintain a backup of your databases.\n" + "This version is not meant for production use."), + MessageWidget::Warning, + -1); #elif (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0) && QT_VERSION < QT_VERSION_CHECK(5, 6, 0)) - if (!config()->get("QtErrorMessageShown", false).toBool()) { - m_ui->globalMessageWidget->showMessage( - tr("WARNING: Your Qt version may cause KeePassXC to crash with an On-Screen Keyboard!\n" - "We recommend you use the AppImage available on our downloads page."), - MessageWidget::Warning, - -1); - config()->set("QtErrorMessageShown", true); - } + if (!config()->get("QtErrorMessageShown", false).toBool()) { + m_ui->globalMessageWidget->showMessage( + tr("WARNING: Your Qt version may cause KeePassXC to crash with an On-Screen Keyboard!\n" + "We recommend you use the AppImage available on our downloads page."), + MessageWidget::Warning, + -1); + config()->set("QtErrorMessageShown", true); + } #endif } @@ -403,748 +407,749 @@ MainWindow::~MainWindow() void MainWindow::showErrorMessage(const QString& message) { - m_ui->globalMessageWidget->showMessage(message, MessageWidget::Error); + m_ui->globalMessageWidget->showMessage(message, MessageWidget::Error); } void MainWindow::appExit() { - m_appExitCalled = true; - close(); + m_appExitCalled = true; + close(); } void MainWindow::updateLastDatabasesMenu() { - m_ui->menuRecentDatabases->clear(); + m_ui->menuRecentDatabases->clear(); - const QStringList lastDatabases = config()->get("LastDatabases", QVariant()).toStringList(); - for (const QString& database : lastDatabases) { - QAction* action = m_ui->menuRecentDatabases->addAction(database); - action->setData(database); - m_lastDatabasesActions->addAction(action); - } - m_ui->menuRecentDatabases->addSeparator(); - m_ui->menuRecentDatabases->addAction(m_clearHistoryAction); + const QStringList lastDatabases = config()->get("LastDatabases", QVariant()).toStringList(); + for (const QString& database : lastDatabases) { + QAction* action = m_ui->menuRecentDatabases->addAction(database); + action->setData(database); + m_lastDatabasesActions->addAction(action); + } + m_ui->menuRecentDatabases->addSeparator(); + m_ui->menuRecentDatabases->addAction(m_clearHistoryAction); } void MainWindow::updateCopyAttributesMenu() { - DatabaseWidget* dbWidget = m_ui->tabWidget->currentDatabaseWidget(); - if (!dbWidget) { - return; - } + DatabaseWidget* dbWidget = m_ui->tabWidget->currentDatabaseWidget(); + if (!dbWidget) { + return; + } - if (dbWidget->numberOfSelectedEntries() != 1) { - return; - } + if (dbWidget->numberOfSelectedEntries() != 1) { + return; + } - QList actions = m_ui->menuEntryCopyAttribute->actions(); - for (int i = m_countDefaultAttributes; i < actions.size(); i++) { - delete actions[i]; - } + QList actions = m_ui->menuEntryCopyAttribute->actions(); + for (int i = m_countDefaultAttributes; i < actions.size(); i++) { + delete actions[i]; + } - const QStringList customEntryAttributes = dbWidget->customEntryAttributes(); - for (const QString& key : customEntryAttributes) { - QAction* action = m_ui->menuEntryCopyAttribute->addAction(key); - action->setData(QVariant(key)); - m_copyAdditionalAttributeActions->addAction(action); - } + const QStringList customEntryAttributes = dbWidget->customEntryAttributes(); + for (const QString& key : customEntryAttributes) { + QAction* action = m_ui->menuEntryCopyAttribute->addAction(key); + action->setData(QVariant(key)); + m_copyAdditionalAttributeActions->addAction(action); + } } void MainWindow::openRecentDatabase(QAction* action) { - openDatabase(action->data().toString()); + openDatabase(action->data().toString()); } void MainWindow::clearLastDatabases() { - config()->set("LastDatabases", QVariant()); - bool inWelcomeWidget = (m_ui->stackedWidget->currentIndex() == 2); + config()->set("LastDatabases", QVariant()); + bool inWelcomeWidget = (m_ui->stackedWidget->currentIndex() == 2); - if (inWelcomeWidget) { - m_ui->welcomeWidget->refreshLastDatabases(); - } + if (inWelcomeWidget) { + m_ui->welcomeWidget->refreshLastDatabases(); + } } void MainWindow::openDatabase(const QString& filePath, const QString& pw, const QString& keyFile) { - if (pw.isEmpty() && keyFile.isEmpty()) { - m_ui->tabWidget->addDatabaseTab(filePath); - return; - } + if (pw.isEmpty() && keyFile.isEmpty()) { + m_ui->tabWidget->addDatabaseTab(filePath); + return; + } - auto db = QSharedPointer::create(); - auto key = QSharedPointer::create(); - if (!pw.isEmpty()) { - key->addKey(QSharedPointer::create(pw)); - } - if (!keyFile.isEmpty()) { - auto fileKey = QSharedPointer::create(); - fileKey->load(keyFile); - key->addKey(fileKey); - } - if (db->open(filePath, key, nullptr, false)) { - auto* dbWidget = new DatabaseWidget(db, this); - m_ui->tabWidget->addDatabaseTab(dbWidget); - dbWidget->switchToMainView(true); - } + auto db = QSharedPointer::create(); + auto key = QSharedPointer::create(); + if (!pw.isEmpty()) { + key->addKey(QSharedPointer::create(pw)); + } + if (!keyFile.isEmpty()) { + auto fileKey = QSharedPointer::create(); + fileKey->load(keyFile); + key->addKey(fileKey); + } + if (db->open(filePath, key, nullptr, false)) { + auto* dbWidget = new DatabaseWidget(db, this); + m_ui->tabWidget->addDatabaseTab(dbWidget); + dbWidget->switchToMainView(true); + } } void MainWindow::setMenuActionState(DatabaseWidget::Mode mode) { - int currentIndex = m_ui->stackedWidget->currentIndex(); + int currentIndex = m_ui->stackedWidget->currentIndex(); - bool inDatabaseTabWidget = (currentIndex == DatabaseTabScreen); - bool inWelcomeWidget = (currentIndex == WelcomeScreen); - bool inDatabaseTabWidgetOrWelcomeWidget = inDatabaseTabWidget || inWelcomeWidget; + bool inDatabaseTabWidget = (currentIndex == DatabaseTabScreen); + bool inWelcomeWidget = (currentIndex == WelcomeScreen); + bool inDatabaseTabWidgetOrWelcomeWidget = inDatabaseTabWidget || inWelcomeWidget; - m_ui->actionDatabaseMerge->setEnabled(inDatabaseTabWidget); + m_ui->actionDatabaseMerge->setEnabled(inDatabaseTabWidget); - m_ui->actionDatabaseNew->setEnabled(inDatabaseTabWidgetOrWelcomeWidget); - m_ui->actionDatabaseOpen->setEnabled(inDatabaseTabWidgetOrWelcomeWidget); - m_ui->menuRecentDatabases->setEnabled(inDatabaseTabWidgetOrWelcomeWidget); - m_ui->menuImport->setEnabled(inDatabaseTabWidgetOrWelcomeWidget); + m_ui->actionDatabaseNew->setEnabled(inDatabaseTabWidgetOrWelcomeWidget); + m_ui->actionDatabaseOpen->setEnabled(inDatabaseTabWidgetOrWelcomeWidget); + m_ui->menuRecentDatabases->setEnabled(inDatabaseTabWidgetOrWelcomeWidget); + m_ui->menuImport->setEnabled(inDatabaseTabWidgetOrWelcomeWidget); - m_ui->actionLockDatabases->setEnabled(m_ui->tabWidget->hasLockableDatabases()); + m_ui->actionLockDatabases->setEnabled(m_ui->tabWidget->hasLockableDatabases()); - if (inDatabaseTabWidget && m_ui->tabWidget->currentIndex() != -1) { - DatabaseWidget* dbWidget = m_ui->tabWidget->currentDatabaseWidget(); - Q_ASSERT(dbWidget); + if (inDatabaseTabWidget && m_ui->tabWidget->currentIndex() != -1) { + DatabaseWidget* dbWidget = m_ui->tabWidget->currentDatabaseWidget(); + Q_ASSERT(dbWidget); - if (mode == DatabaseWidget::Mode::None) { - mode = dbWidget->currentMode(); - } + if (mode == DatabaseWidget::Mode::None) { + mode = dbWidget->currentMode(); + } - switch (mode) { - case DatabaseWidget::Mode::ViewMode: { - // bool inSearch = dbWidget->isInSearchMode(); - bool singleEntrySelected = dbWidget->numberOfSelectedEntries() == 1 && dbWidget->currentEntryHasFocus(); - bool entriesSelected = dbWidget->numberOfSelectedEntries() > 0 && dbWidget->currentEntryHasFocus(); - bool groupSelected = dbWidget->isGroupSelected(); - bool recycleBinSelected = dbWidget->isRecycleBinSelected(); + switch (mode) { + case DatabaseWidget::Mode::ViewMode: { + // bool inSearch = dbWidget->isInSearchMode(); + bool singleEntrySelected = dbWidget->numberOfSelectedEntries() == 1 && dbWidget->currentEntryHasFocus(); + bool entriesSelected = dbWidget->numberOfSelectedEntries() > 0 && dbWidget->currentEntryHasFocus(); + bool groupSelected = dbWidget->isGroupSelected(); + bool recycleBinSelected = dbWidget->isRecycleBinSelected(); - m_ui->actionEntryNew->setEnabled(true); - m_ui->actionEntryClone->setEnabled(singleEntrySelected); - m_ui->actionEntryEdit->setEnabled(singleEntrySelected); - m_ui->actionEntryDelete->setEnabled(entriesSelected); - m_ui->actionEntryCopyTitle->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTitle()); - m_ui->actionEntryCopyUsername->setEnabled(singleEntrySelected && dbWidget->currentEntryHasUsername()); - m_ui->actionEntryCopyPassword->setEnabled(singleEntrySelected && dbWidget->currentEntryHasPassword()); - m_ui->actionEntryCopyURL->setEnabled(singleEntrySelected && dbWidget->currentEntryHasUrl()); - m_ui->actionEntryCopyNotes->setEnabled(singleEntrySelected && dbWidget->currentEntryHasNotes()); - m_ui->menuEntryCopyAttribute->setEnabled(singleEntrySelected); - m_ui->menuEntryTotp->setEnabled(singleEntrySelected); - m_ui->actionEntryAutoType->setEnabled(singleEntrySelected); - m_ui->actionEntryOpenUrl->setEnabled(singleEntrySelected && dbWidget->currentEntryHasUrl()); - m_ui->actionEntryTotp->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTotp()); - m_ui->actionEntryCopyTotp->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTotp()); - m_ui->actionEntrySetupTotp->setEnabled(singleEntrySelected); - m_ui->actionEntryTotpQRCode->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTotp()); - m_ui->actionGroupNew->setEnabled(groupSelected); - m_ui->actionGroupEdit->setEnabled(groupSelected); - m_ui->actionGroupDelete->setEnabled(groupSelected && dbWidget->canDeleteCurrentGroup()); - m_ui->actionGroupEmptyRecycleBin->setVisible(recycleBinSelected); - m_ui->actionGroupEmptyRecycleBin->setEnabled(recycleBinSelected); - m_ui->actionChangeMasterKey->setEnabled(true); - m_ui->actionChangeDatabaseSettings->setEnabled(true); - m_ui->actionDatabaseSave->setEnabled(m_ui->tabWidget->canSave()); - m_ui->actionDatabaseSaveAs->setEnabled(true); - m_ui->actionExportCsv->setEnabled(true); - m_ui->actionDatabaseMerge->setEnabled(m_ui->tabWidget->currentIndex() != -1); + m_ui->actionEntryNew->setEnabled(true); + m_ui->actionEntryClone->setEnabled(singleEntrySelected); + m_ui->actionEntryEdit->setEnabled(singleEntrySelected); + m_ui->actionEntryDelete->setEnabled(entriesSelected); + m_ui->actionEntryCopyTitle->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTitle()); + m_ui->actionEntryCopyUsername->setEnabled(singleEntrySelected && dbWidget->currentEntryHasUsername()); + m_ui->actionEntryCopyPassword->setEnabled(singleEntrySelected && dbWidget->currentEntryHasPassword()); + m_ui->actionEntryCopyURL->setEnabled(singleEntrySelected && dbWidget->currentEntryHasUrl()); + m_ui->actionEntryCopyNotes->setEnabled(singleEntrySelected && dbWidget->currentEntryHasNotes()); + m_ui->menuEntryCopyAttribute->setEnabled(singleEntrySelected); + m_ui->menuEntryTotp->setEnabled(singleEntrySelected); + m_ui->actionEntryAutoType->setEnabled(singleEntrySelected); + m_ui->actionEntryOpenUrl->setEnabled(singleEntrySelected && dbWidget->currentEntryHasUrl()); + m_ui->actionEntryTotp->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTotp()); + m_ui->actionEntryCopyTotp->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTotp()); + m_ui->actionEntrySetupTotp->setEnabled(singleEntrySelected); + m_ui->actionEntryTotpQRCode->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTotp()); + m_ui->actionGroupNew->setEnabled(groupSelected); + m_ui->actionGroupEdit->setEnabled(groupSelected); + m_ui->actionGroupDelete->setEnabled(groupSelected && dbWidget->canDeleteCurrentGroup()); + m_ui->actionGroupEmptyRecycleBin->setVisible(recycleBinSelected); + m_ui->actionGroupEmptyRecycleBin->setEnabled(recycleBinSelected); + m_ui->actionChangeMasterKey->setEnabled(true); + m_ui->actionChangeDatabaseSettings->setEnabled(true); + m_ui->actionDatabaseSave->setEnabled(m_ui->tabWidget->canSave()); + m_ui->actionDatabaseSaveAs->setEnabled(true); + m_ui->actionExportCsv->setEnabled(true); + m_ui->actionDatabaseMerge->setEnabled(m_ui->tabWidget->currentIndex() != -1); - m_searchWidgetAction->setEnabled(true); + m_searchWidgetAction->setEnabled(true); - break; - } - case DatabaseWidget::Mode::EditMode: - case DatabaseWidget::Mode::ImportMode: - case DatabaseWidget::Mode::LockedMode: { - const QList entryActions = m_ui->menuEntries->actions(); - for (QAction* action : entryActions) { - action->setEnabled(false); - } + break; + } + case DatabaseWidget::Mode::EditMode: + case DatabaseWidget::Mode::ImportMode: + case DatabaseWidget::Mode::LockedMode: { + const QList entryActions = m_ui->menuEntries->actions(); + for (QAction* action : entryActions) { + action->setEnabled(false); + } - const QList groupActions = m_ui->menuGroups->actions(); - for (QAction* action : groupActions) { - action->setEnabled(false); - } + const QList groupActions = m_ui->menuGroups->actions(); + for (QAction* action : groupActions) { + action->setEnabled(false); + } - m_ui->actionChangeMasterKey->setEnabled(false); - m_ui->actionChangeDatabaseSettings->setEnabled(false); - m_ui->actionDatabaseSave->setEnabled(false); - m_ui->actionDatabaseSaveAs->setEnabled(false); - m_ui->actionExportCsv->setEnabled(false); - m_ui->actionDatabaseMerge->setEnabled(false); + m_ui->actionChangeMasterKey->setEnabled(false); + m_ui->actionChangeDatabaseSettings->setEnabled(false); + m_ui->actionDatabaseSave->setEnabled(false); + m_ui->actionDatabaseSaveAs->setEnabled(false); + m_ui->actionExportCsv->setEnabled(false); + m_ui->actionDatabaseMerge->setEnabled(false); - m_searchWidgetAction->setEnabled(false); - break; - } - default: - Q_ASSERT(false); - } - m_ui->actionDatabaseClose->setEnabled(true); - } else { - const QList entryActions = m_ui->menuEntries->actions(); - for (QAction* action : entryActions) { - action->setEnabled(false); - } + m_searchWidgetAction->setEnabled(false); + break; + } + default: + Q_ASSERT(false); + } + m_ui->actionDatabaseClose->setEnabled(true); + } else { + const QList entryActions = m_ui->menuEntries->actions(); + for (QAction* action : entryActions) { + action->setEnabled(false); + } - const QList groupActions = m_ui->menuGroups->actions(); - for (QAction* action : groupActions) { - action->setEnabled(false); - } + const QList groupActions = m_ui->menuGroups->actions(); + for (QAction* action : groupActions) { + action->setEnabled(false); + } - m_ui->actionChangeMasterKey->setEnabled(false); - m_ui->actionChangeDatabaseSettings->setEnabled(false); - m_ui->actionDatabaseSave->setEnabled(false); - m_ui->actionDatabaseSaveAs->setEnabled(false); - m_ui->actionDatabaseClose->setEnabled(false); - m_ui->actionExportCsv->setEnabled(false); - m_ui->actionDatabaseMerge->setEnabled(false); + m_ui->actionChangeMasterKey->setEnabled(false); + m_ui->actionChangeDatabaseSettings->setEnabled(false); + m_ui->actionDatabaseSave->setEnabled(false); + m_ui->actionDatabaseSaveAs->setEnabled(false); + m_ui->actionDatabaseClose->setEnabled(false); + m_ui->actionExportCsv->setEnabled(false); + m_ui->actionDatabaseMerge->setEnabled(false); - m_searchWidgetAction->setEnabled(false); - } + m_searchWidgetAction->setEnabled(false); + } - if ((currentIndex == PasswordGeneratorScreen) != m_ui->actionPasswordGenerator->isChecked()) { - bool blocked = m_ui->actionPasswordGenerator->blockSignals(true); - m_ui->actionPasswordGenerator->toggle(); - m_ui->actionPasswordGenerator->blockSignals(blocked); - } else if ((currentIndex == SettingsScreen) != m_ui->actionSettings->isChecked()) { - bool blocked = m_ui->actionSettings->blockSignals(true); - m_ui->actionSettings->toggle(); - m_ui->actionSettings->blockSignals(blocked); - } + if ((currentIndex == PasswordGeneratorScreen) != m_ui->actionPasswordGenerator->isChecked()) { + bool blocked = m_ui->actionPasswordGenerator->blockSignals(true); + m_ui->actionPasswordGenerator->toggle(); + m_ui->actionPasswordGenerator->blockSignals(blocked); + } else if ((currentIndex == SettingsScreen) != m_ui->actionSettings->isChecked()) { + bool blocked = m_ui->actionSettings->blockSignals(true); + m_ui->actionSettings->toggle(); + m_ui->actionSettings->blockSignals(blocked); + } } void MainWindow::updateWindowTitle() { - QString customWindowTitlePart; - int stackedWidgetIndex = m_ui->stackedWidget->currentIndex(); - int tabWidgetIndex = m_ui->tabWidget->currentIndex(); - bool isModified = m_ui->tabWidget->isModified(tabWidgetIndex); + QString customWindowTitlePart; + int stackedWidgetIndex = m_ui->stackedWidget->currentIndex(); + int tabWidgetIndex = m_ui->tabWidget->currentIndex(); + bool isModified = m_ui->tabWidget->isModified(tabWidgetIndex); - if (stackedWidgetIndex == DatabaseTabScreen && tabWidgetIndex != -1) { - customWindowTitlePart = m_ui->tabWidget->tabName(tabWidgetIndex); - if (isModified) { - // remove asterisk '*' from title - customWindowTitlePart.remove(customWindowTitlePart.size() - 1, 1); - } - m_ui->actionDatabaseSave->setEnabled(m_ui->tabWidget->canSave(tabWidgetIndex)); - } else if (stackedWidgetIndex == 1) { - customWindowTitlePart = tr("Settings"); - } + if (stackedWidgetIndex == DatabaseTabScreen && tabWidgetIndex != -1) { + customWindowTitlePart = m_ui->tabWidget->tabName(tabWidgetIndex); + if (isModified) { + // remove asterisk '*' from title + customWindowTitlePart.remove(customWindowTitlePart.size() - 1, 1); + } + m_ui->actionDatabaseSave->setEnabled(m_ui->tabWidget->canSave(tabWidgetIndex)); + } else if (stackedWidgetIndex == 1) { + customWindowTitlePart = tr("Settings"); + } - QString windowTitle; - if (customWindowTitlePart.isEmpty()) { - windowTitle = BaseWindowTitle; - } else { - windowTitle = QString("%1[*] - %2").arg(customWindowTitlePart, BaseWindowTitle); - } + QString windowTitle; + if (customWindowTitlePart.isEmpty()) { + windowTitle = BaseWindowTitle; + } else { + windowTitle = QString("%1[*] - %2").arg(customWindowTitlePart, BaseWindowTitle); + } - if (customWindowTitlePart.isEmpty() || stackedWidgetIndex == 1) { - setWindowFilePath(""); - } else { - setWindowFilePath(m_ui->tabWidget->databaseWidgetFromIndex(tabWidgetIndex)->database()->filePath()); - } + if (customWindowTitlePart.isEmpty() || stackedWidgetIndex == 1) { + setWindowFilePath(""); + } else { + setWindowFilePath(m_ui->tabWidget->databaseWidgetFromIndex(tabWidgetIndex)->database()->filePath()); + } - setWindowTitle(windowTitle); - setWindowModified(isModified); + setWindowTitle(windowTitle); + setWindowModified(isModified); } void MainWindow::showAboutDialog() { - auto* aboutDialog = new AboutDialog(this); - aboutDialog->open(); + auto* aboutDialog = new AboutDialog(this); + aboutDialog->open(); } void MainWindow::openDonateUrl() { - QDesktopServices::openUrl(QUrl("https://keepassxc.org/donate")); + QDesktopServices::openUrl(QUrl("https://keepassxc.org/donate")); } void MainWindow::openBugReportUrl() { - QDesktopServices::openUrl(QUrl("https://github.com/keepassxreboot/keepassxc/issues")); + QDesktopServices::openUrl(QUrl("https://github.com/keepassxreboot/keepassxc/issues")); } void MainWindow::switchToDatabases() { - if (m_ui->tabWidget->currentIndex() == -1) { - m_ui->stackedWidget->setCurrentIndex(WelcomeScreen); - } else { - m_ui->stackedWidget->setCurrentIndex(DatabaseTabScreen); - } + if (m_ui->tabWidget->currentIndex() == -1) { + m_ui->stackedWidget->setCurrentIndex(WelcomeScreen); + } else { + m_ui->stackedWidget->setCurrentIndex(DatabaseTabScreen); + } } void MainWindow::switchToSettings(bool enabled) { - if (enabled) { - m_ui->settingsWidget->loadSettings(); - m_ui->stackedWidget->setCurrentIndex(SettingsScreen); - } else { - switchToDatabases(); - } + if (enabled) { + m_ui->settingsWidget->loadSettings(); + m_ui->stackedWidget->setCurrentIndex(SettingsScreen); + } else { + switchToDatabases(); + } } void MainWindow::switchToPasswordGen(bool enabled) { - if (enabled) { - m_ui->passwordGeneratorWidget->loadSettings(); - m_ui->passwordGeneratorWidget->regeneratePassword(); - m_ui->passwordGeneratorWidget->setStandaloneMode(true); - m_ui->stackedWidget->setCurrentIndex(PasswordGeneratorScreen); - } else { - m_ui->passwordGeneratorWidget->saveSettings(); - switchToDatabases(); - } + if (enabled) { + m_ui->passwordGeneratorWidget->loadSettings(); + m_ui->passwordGeneratorWidget->regeneratePassword(); + m_ui->passwordGeneratorWidget->setStandaloneMode(true); + m_ui->stackedWidget->setCurrentIndex(PasswordGeneratorScreen); + } else { + m_ui->passwordGeneratorWidget->saveSettings(); + switchToDatabases(); + } } void MainWindow::closePasswordGen() { - switchToPasswordGen(false); + switchToPasswordGen(false); } void MainWindow::switchToNewDatabase() { - m_ui->tabWidget->newDatabase(); - switchToDatabases(); + m_ui->tabWidget->newDatabase(); + switchToDatabases(); } void MainWindow::switchToOpenDatabase() { - m_ui->tabWidget->openDatabase(); - switchToDatabases(); + m_ui->tabWidget->openDatabase(); + switchToDatabases(); } void MainWindow::switchToDatabaseFile(const QString& file) { - m_ui->tabWidget->addDatabaseTab(file); - switchToDatabases(); + m_ui->tabWidget->addDatabaseTab(file); + switchToDatabases(); } void MainWindow::switchToKeePass1Database() { - m_ui->tabWidget->importKeePass1Database(); - switchToDatabases(); + m_ui->tabWidget->importKeePass1Database(); + switchToDatabases(); } void MainWindow::switchToCsvImport() { - m_ui->tabWidget->importCsv(); - switchToDatabases(); + m_ui->tabWidget->importCsv(); + switchToDatabases(); } void MainWindow::databaseStatusChanged(DatabaseWidget* dbWidget) { - Q_UNUSED(dbWidget); - updateTrayIcon(); + Q_UNUSED(dbWidget); + updateTrayIcon(); } void MainWindow::selectNextDatabaseTab() { - if (m_ui->stackedWidget->currentIndex() == DatabaseTabScreen) { - int index = m_ui->tabWidget->currentIndex() + 1; - if (index >= m_ui->tabWidget->count()) { - m_ui->tabWidget->setCurrentIndex(0); - } else { - m_ui->tabWidget->setCurrentIndex(index); - } - } + if (m_ui->stackedWidget->currentIndex() == DatabaseTabScreen) { + int index = m_ui->tabWidget->currentIndex() + 1; + if (index >= m_ui->tabWidget->count()) { + m_ui->tabWidget->setCurrentIndex(0); + } else { + m_ui->tabWidget->setCurrentIndex(index); + } + } } void MainWindow::selectPreviousDatabaseTab() { - if (m_ui->stackedWidget->currentIndex() == DatabaseTabScreen) { - int index = m_ui->tabWidget->currentIndex() - 1; - if (index < 0) { - m_ui->tabWidget->setCurrentIndex(m_ui->tabWidget->count() - 1); - } else { - m_ui->tabWidget->setCurrentIndex(index); - } - } + if (m_ui->stackedWidget->currentIndex() == DatabaseTabScreen) { + int index = m_ui->tabWidget->currentIndex() - 1; + if (index < 0) { + m_ui->tabWidget->setCurrentIndex(m_ui->tabWidget->count() - 1); + } else { + m_ui->tabWidget->setCurrentIndex(index); + } + } } void MainWindow::databaseTabChanged(int tabIndex) { - if (tabIndex != -1 && m_ui->stackedWidget->currentIndex() == WelcomeScreen) { - m_ui->stackedWidget->setCurrentIndex(DatabaseTabScreen); - } else if (tabIndex == -1 && m_ui->stackedWidget->currentIndex() == DatabaseTabScreen) { - m_ui->stackedWidget->setCurrentIndex(WelcomeScreen); - } + if (tabIndex != -1 && m_ui->stackedWidget->currentIndex() == WelcomeScreen) { + m_ui->stackedWidget->setCurrentIndex(DatabaseTabScreen); + } else if (tabIndex == -1 && m_ui->stackedWidget->currentIndex() == DatabaseTabScreen) { + m_ui->stackedWidget->setCurrentIndex(WelcomeScreen); + } - m_actionMultiplexer.setCurrentObject(m_ui->tabWidget->currentDatabaseWidget()); + m_actionMultiplexer.setCurrentObject(m_ui->tabWidget->currentDatabaseWidget()); } void MainWindow::togglePasswordsHidden() { - auto dbWidget = m_ui->tabWidget->currentDatabaseWidget(); - if (dbWidget) { - dbWidget->setPasswordsHidden(!dbWidget->isPasswordsHidden()); - } + auto dbWidget = m_ui->tabWidget->currentDatabaseWidget(); + if (dbWidget) { + dbWidget->setPasswordsHidden(!dbWidget->isPasswordsHidden()); + } } void MainWindow::toggleUsernamesHidden() { - auto dbWidget = m_ui->tabWidget->currentDatabaseWidget(); - if (dbWidget) { - dbWidget->setUsernamesHidden(!dbWidget->isUsernamesHidden()); - } + auto dbWidget = m_ui->tabWidget->currentDatabaseWidget(); + if (dbWidget) { + dbWidget->setUsernamesHidden(!dbWidget->isUsernamesHidden()); + } } void MainWindow::closeEvent(QCloseEvent* event) { - // ignore double close events (happens on macOS when closing from the dock) - if (m_appExiting) { - event->accept(); - return; - } + // ignore double close events (happens on macOS when closing from the dock) + if (m_appExiting) { + event->accept(); + return; + } - if (config()->get("GUI/MinimizeOnClose").toBool() && !m_appExitCalled) { - event->ignore(); - hideWindow(); - return; - } + if (config()->get("GUI/MinimizeOnClose").toBool() && !m_appExitCalled) { + event->ignore(); + hideWindow(); + return; + } - bool accept = saveLastDatabases(); + bool accept = saveLastDatabases(); - if (accept) { - m_appExiting = true; - saveWindowInformation(); + if (accept) { + m_appExiting = true; + saveWindowInformation(); - event->accept(); - QApplication::quit(); - } else { - event->ignore(); - } + event->accept(); + QApplication::quit(); + } else { + event->ignore(); + } } void MainWindow::changeEvent(QEvent* event) { - if ((event->type() == QEvent::WindowStateChange) && isMinimized()) { - if (isTrayIconEnabled() && m_trayIcon && m_trayIcon->isVisible() - && config()->get("GUI/MinimizeToTray").toBool()) { - event->ignore(); - QTimer::singleShot(0, this, SLOT(hide())); - } + if ((event->type() == QEvent::WindowStateChange) && isMinimized()) { + if (isTrayIconEnabled() && m_trayIcon && m_trayIcon->isVisible() + && config()->get("GUI/MinimizeToTray").toBool()) { + event->ignore(); + QTimer::singleShot(0, this, SLOT(hide())); + } - if (config()->get("security/lockdatabaseminimize").toBool()) { - m_ui->tabWidget->lockDatabases(); - } - } else { - QMainWindow::changeEvent(event); - } + if (config()->get("security/lockdatabaseminimize").toBool()) { + m_ui->tabWidget->lockDatabases(); + } + } else { + QMainWindow::changeEvent(event); + } } void MainWindow::saveWindowInformation() { - if (isVisible()) { - config()->set("GUI/MainWindowGeometry", saveGeometry()); - } + if (isVisible()) { + config()->set("GUI/MainWindowGeometry", saveGeometry()); + } } bool MainWindow::saveLastDatabases() { - bool accept; - m_openDatabases.clear(); - bool openPreviousDatabasesOnStartup = config()->get("OpenPreviousDatabasesOnStartup").toBool(); + bool accept; + m_openDatabases.clear(); + bool openPreviousDatabasesOnStartup = config()->get("OpenPreviousDatabasesOnStartup").toBool(); - if (openPreviousDatabasesOnStartup) { - connect(m_ui->tabWidget, SIGNAL(databaseClosed(const QString&)), this, SLOT(rememberOpenDatabases(const QString&))); - } + if (openPreviousDatabasesOnStartup) { + connect( + m_ui->tabWidget, SIGNAL(databaseClosed(const QString&)), this, SLOT(rememberOpenDatabases(const QString&))); + } - accept = m_ui->tabWidget->closeAllDatabaseTabs(); + accept = m_ui->tabWidget->closeAllDatabaseTabs(); - if (openPreviousDatabasesOnStartup) { - disconnect( - m_ui->tabWidget, SIGNAL(databaseClosed(const QString&)), this, SLOT(rememberOpenDatabases(const QString&))); - config()->set("LastOpenedDatabases", m_openDatabases); - } + if (openPreviousDatabasesOnStartup) { + disconnect( + m_ui->tabWidget, SIGNAL(databaseClosed(const QString&)), this, SLOT(rememberOpenDatabases(const QString&))); + config()->set("LastOpenedDatabases", m_openDatabases); + } - return accept; + return accept; } void MainWindow::updateTrayIcon() { - if (isTrayIconEnabled()) { - if (!m_trayIcon) { - m_trayIcon = new QSystemTrayIcon(this); - QMenu* menu = new QMenu(this); + if (isTrayIconEnabled()) { + if (!m_trayIcon) { + m_trayIcon = new QSystemTrayIcon(this); + QMenu* menu = new QMenu(this); - QAction* actionToggle = new QAction(tr("Toggle window"), menu); - menu->addAction(actionToggle); + QAction* actionToggle = new QAction(tr("Toggle window"), menu); + menu->addAction(actionToggle); #ifdef Q_OS_MACOS - QAction* actionQuit = new QAction(tr("Quit KeePassXC"), menu); - menu->addAction(actionQuit); + QAction* actionQuit = new QAction(tr("Quit KeePassXC"), menu); + menu->addAction(actionQuit); - connect(actionQuit, SIGNAL(triggered()), SLOT(appExit())); + connect(actionQuit, SIGNAL(triggered()), SLOT(appExit())); #else - menu->addAction(m_ui->actionQuit); + menu->addAction(m_ui->actionQuit); - connect(m_trayIcon, - SIGNAL(activated(QSystemTrayIcon::ActivationReason)), - SLOT(trayIconTriggered(QSystemTrayIcon::ActivationReason))); + connect(m_trayIcon, + SIGNAL(activated(QSystemTrayIcon::ActivationReason)), + SLOT(trayIconTriggered(QSystemTrayIcon::ActivationReason))); #endif - connect(actionToggle, SIGNAL(triggered()), SLOT(toggleWindow())); + connect(actionToggle, SIGNAL(triggered()), SLOT(toggleWindow())); - m_trayIcon->setContextMenu(menu); + m_trayIcon->setContextMenu(menu); - m_trayIcon->setIcon(filePath()->trayIcon()); - m_trayIcon->show(); - } - if (m_ui->tabWidget->hasLockableDatabases()) { - m_trayIcon->setIcon(filePath()->trayIconUnlocked()); - } else { - m_trayIcon->setIcon(filePath()->trayIconLocked()); - } - } else { - if (m_trayIcon) { - m_trayIcon->hide(); - delete m_trayIcon; - m_trayIcon = nullptr; - } - } + m_trayIcon->setIcon(filePath()->trayIcon()); + m_trayIcon->show(); + } + if (m_ui->tabWidget->hasLockableDatabases()) { + m_trayIcon->setIcon(filePath()->trayIconUnlocked()); + } else { + m_trayIcon->setIcon(filePath()->trayIconLocked()); + } + } else { + if (m_trayIcon) { + m_trayIcon->hide(); + delete m_trayIcon; + m_trayIcon = nullptr; + } + } } void MainWindow::showEntryContextMenu(const QPoint& globalPos) { - m_ui->menuEntries->popup(globalPos); + m_ui->menuEntries->popup(globalPos); } void MainWindow::showGroupContextMenu(const QPoint& globalPos) { - m_ui->menuGroups->popup(globalPos); + m_ui->menuGroups->popup(globalPos); } void MainWindow::setShortcut(QAction* action, QKeySequence::StandardKey standard, int fallback) { - if (!QKeySequence::keyBindings(standard).isEmpty()) { - action->setShortcuts(standard); - } else if (fallback != 0) { - action->setShortcut(QKeySequence(fallback)); - } + if (!QKeySequence::keyBindings(standard).isEmpty()) { + action->setShortcuts(standard); + } else if (fallback != 0) { + action->setShortcut(QKeySequence(fallback)); + } } void MainWindow::rememberOpenDatabases(const QString& filePath) { - m_openDatabases.prepend(filePath); + m_openDatabases.prepend(filePath); } void MainWindow::applySettingsChanges() { - int timeout = config()->get("security/lockdatabaseidlesec").toInt() * 1000; - if (timeout <= 0) { - timeout = 60; - } + int timeout = config()->get("security/lockdatabaseidlesec").toInt() * 1000; + if (timeout <= 0) { + timeout = 60; + } - m_inactivityTimer->setInactivityTimeout(timeout); - if (config()->get("security/lockdatabaseidle").toBool()) { - m_inactivityTimer->activate(); - } else { - m_inactivityTimer->deactivate(); - } + m_inactivityTimer->setInactivityTimeout(timeout); + if (config()->get("security/lockdatabaseidle").toBool()) { + m_inactivityTimer->activate(); + } else { + m_inactivityTimer->deactivate(); + } #ifdef WITH_XC_TOUCHID - // forget TouchID (in minutes) - timeout = config()->get("security/resettouchidtimeout").toInt() * 60 * 1000; - if (timeout <= 0) { - timeout = 30 * 60 * 1000; - } + // forget TouchID (in minutes) + timeout = config()->get("security/resettouchidtimeout").toInt() * 60 * 1000; + if (timeout <= 0) { + timeout = 30 * 60 * 1000; + } - m_touchIDinactivityTimer->setInactivityTimeout(timeout); - if (config()->get("security/resettouchid").toBool()) { - m_touchIDinactivityTimer->activate(); - } else { - m_touchIDinactivityTimer->deactivate(); - } + m_touchIDinactivityTimer->setInactivityTimeout(timeout); + if (config()->get("security/resettouchid").toBool()) { + m_touchIDinactivityTimer->activate(); + } else { + m_touchIDinactivityTimer->deactivate(); + } #endif - m_ui->toolBar->setHidden(config()->get("GUI/HideToolbar").toBool()); + m_ui->toolBar->setHidden(config()->get("GUI/HideToolbar").toBool()); - updateTrayIcon(); + updateTrayIcon(); } void MainWindow::trayIconTriggered(QSystemTrayIcon::ActivationReason reason) { - if (reason == QSystemTrayIcon::Trigger || reason == QSystemTrayIcon::MiddleClick) { - toggleWindow(); - } + if (reason == QSystemTrayIcon::Trigger || reason == QSystemTrayIcon::MiddleClick) { + toggleWindow(); + } } void MainWindow::hideWindow() { - saveWindowInformation(); + saveWindowInformation(); #if !defined(Q_OS_LINUX) && !defined(Q_OS_MACOS) - // On some Linux systems, the window should NOT be minimized and hidden (i.e. not shown), at - // the same time (which would happen if both minimize on startup and minimize to tray are set) - // since otherwise it causes problems on restore as seen on issue #1595. Hiding it is enough. - // TODO: Add an explanation for why this is also not done on Mac (or remove the check) - setWindowState(windowState() | Qt::WindowMinimized); + // On some Linux systems, the window should NOT be minimized and hidden (i.e. not shown), at + // the same time (which would happen if both minimize on startup and minimize to tray are set) + // since otherwise it causes problems on restore as seen on issue #1595. Hiding it is enough. + // TODO: Add an explanation for why this is also not done on Mac (or remove the check) + setWindowState(windowState() | Qt::WindowMinimized); #endif - // Only hide if tray icon is active, otherwise window will be gone forever - if (isTrayIconEnabled()) { - hide(); - } else { - showMinimized(); - } + // Only hide if tray icon is active, otherwise window will be gone forever + if (isTrayIconEnabled()) { + hide(); + } else { + showMinimized(); + } - if (config()->get("security/lockdatabaseminimize").toBool()) { - m_ui->tabWidget->lockDatabases(); - } + if (config()->get("security/lockdatabaseminimize").toBool()) { + m_ui->tabWidget->lockDatabases(); + } } void MainWindow::toggleWindow() { - if (isVisible() && !isMinimized()) { - hideWindow(); - } else { - bringToFront(); + if (isVisible() && !isMinimized()) { + hideWindow(); + } else { + bringToFront(); #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) && !defined(QT_NO_DBUS) && (QT_VERSION < QT_VERSION_CHECK(5, 9, 0)) - // re-register global D-Bus menu (needed on Ubuntu with Unity) - // see https://github.com/keepassxreboot/keepassxc/issues/271 - // and https://bugreports.qt.io/browse/QTBUG-58723 - // check for !isVisible(), because isNativeMenuBar() does not work with appmenu-qt5 - if (!m_ui->menubar->isVisible()) { - QDBusMessage msg = QDBusMessage::createMethodCall("com.canonical.AppMenu.Registrar", - "/com/canonical/AppMenu/Registrar", - "com.canonical.AppMenu.Registrar", - "RegisterWindow"); - QList args; - args << QVariant::fromValue(static_cast(winId())) - << QVariant::fromValue(QDBusObjectPath("/MenuBar/1")); - msg.setArguments(args); - QDBusConnection::sessionBus().send(msg); - } + // re-register global D-Bus menu (needed on Ubuntu with Unity) + // see https://github.com/keepassxreboot/keepassxc/issues/271 + // and https://bugreports.qt.io/browse/QTBUG-58723 + // check for !isVisible(), because isNativeMenuBar() does not work with appmenu-qt5 + if (!m_ui->menubar->isVisible()) { + QDBusMessage msg = QDBusMessage::createMethodCall("com.canonical.AppMenu.Registrar", + "/com/canonical/AppMenu/Registrar", + "com.canonical.AppMenu.Registrar", + "RegisterWindow"); + QList args; + args << QVariant::fromValue(static_cast(winId())) + << QVariant::fromValue(QDBusObjectPath("/MenuBar/1")); + msg.setArguments(args); + QDBusConnection::sessionBus().send(msg); + } #endif - } + } } void MainWindow::lockDatabasesAfterInactivity() { - // ignore event if a modal dialog is open (such as a message box or file dialog) - if (QApplication::activeModalWidget()) { - return; - } + // ignore event if a modal dialog is open (such as a message box or file dialog) + if (QApplication::activeModalWidget()) { + return; + } - m_ui->tabWidget->lockDatabases(); + m_ui->tabWidget->lockDatabases(); } void MainWindow::forgetTouchIDAfterInactivity() { #ifdef WITH_XC_TOUCHID - TouchID::getInstance().reset(); + TouchID::getInstance().reset(); #endif } bool MainWindow::isTrayIconEnabled() const { - return config()->get("GUI/ShowTrayIcon").toBool() && QSystemTrayIcon::isSystemTrayAvailable(); + return config()->get("GUI/ShowTrayIcon").toBool() && QSystemTrayIcon::isSystemTrayAvailable(); } void MainWindow::displayGlobalMessage(const QString& text, - MessageWidget::MessageType type, - bool showClosebutton, - int autoHideTimeout) + MessageWidget::MessageType type, + bool showClosebutton, + int autoHideTimeout) { - m_ui->globalMessageWidget->setCloseButtonVisible(showClosebutton); - m_ui->globalMessageWidget->showMessage(text, type, autoHideTimeout); + m_ui->globalMessageWidget->setCloseButtonVisible(showClosebutton); + m_ui->globalMessageWidget->showMessage(text, type, autoHideTimeout); } void MainWindow::displayTabMessage(const QString& text, - MessageWidget::MessageType type, - bool showClosebutton, - int autoHideTimeout) + MessageWidget::MessageType type, + bool showClosebutton, + int autoHideTimeout) { - m_ui->tabWidget->currentDatabaseWidget()->showMessage(text, type, showClosebutton, autoHideTimeout); + m_ui->tabWidget->currentDatabaseWidget()->showMessage(text, type, showClosebutton, autoHideTimeout); } void MainWindow::hideGlobalMessage() { - m_ui->globalMessageWidget->hideMessage(); + m_ui->globalMessageWidget->hideMessage(); } void MainWindow::showYubiKeyPopup() { - displayGlobalMessage(tr("Please touch the button on your YubiKey!"), - MessageWidget::Information, - false, - MessageWidget::DisableAutoHide); - setEnabled(false); + displayGlobalMessage(tr("Please touch the button on your YubiKey!"), + MessageWidget::Information, + false, + MessageWidget::DisableAutoHide); + setEnabled(false); } void MainWindow::hideYubiKeyPopup() { - hideGlobalMessage(); - setEnabled(true); + hideGlobalMessage(); + setEnabled(true); } void MainWindow::bringToFront() { - ensurePolished(); - setWindowState(windowState() & ~Qt::WindowMinimized); - show(); - raise(); - activateWindow(); + ensurePolished(); + setWindowState(windowState() & ~Qt::WindowMinimized); + show(); + raise(); + activateWindow(); } void MainWindow::handleScreenLock() { - if (config()->get("security/lockdatabasescreenlock").toBool()) { - lockDatabasesAfterInactivity(); - } + if (config()->get("security/lockdatabasescreenlock").toBool()) { + lockDatabasesAfterInactivity(); + } #ifdef WITH_XC_TOUCHID - if (config()->get("security/resettouchidscreenlock").toBool()) { - forgetTouchIDAfterInactivity(); - } + if (config()->get("security/resettouchidscreenlock").toBool()) { + forgetTouchIDAfterInactivity(); + } #endif } QStringList MainWindow::kdbxFilesFromUrls(const QList& urls) { - QStringList kdbxFiles; - for (const QUrl& url : urls) { - const QFileInfo fInfo(url.toLocalFile()); - const bool isKdbxFile = fInfo.isFile() && fInfo.suffix().toLower() == "kdbx"; - if (isKdbxFile) { - kdbxFiles.append(fInfo.absoluteFilePath()); - } - } + QStringList kdbxFiles; + for (const QUrl& url : urls) { + const QFileInfo fInfo(url.toLocalFile()); + const bool isKdbxFile = fInfo.isFile() && fInfo.suffix().toLower() == "kdbx"; + if (isKdbxFile) { + kdbxFiles.append(fInfo.absoluteFilePath()); + } + } - return kdbxFiles; + return kdbxFiles; } void MainWindow::dragEnterEvent(QDragEnterEvent* event) { - const QMimeData* mimeData = event->mimeData(); - if (mimeData->hasUrls()) { - const QStringList kdbxFiles = kdbxFilesFromUrls(mimeData->urls()); - if (!kdbxFiles.isEmpty()) { - event->acceptProposedAction(); - } - } + const QMimeData* mimeData = event->mimeData(); + if (mimeData->hasUrls()) { + const QStringList kdbxFiles = kdbxFilesFromUrls(mimeData->urls()); + if (!kdbxFiles.isEmpty()) { + event->acceptProposedAction(); + } + } } void MainWindow::dropEvent(QDropEvent* event) { - const QMimeData* mimeData = event->mimeData(); - if (mimeData->hasUrls()) { - const QStringList kdbxFiles = kdbxFilesFromUrls(mimeData->urls()); - if (!kdbxFiles.isEmpty()) { - event->acceptProposedAction(); - } - for (const QString& kdbxFile : kdbxFiles) { - openDatabase(kdbxFile); - } - } + const QMimeData* mimeData = event->mimeData(); + if (mimeData->hasUrls()) { + const QStringList kdbxFiles = kdbxFilesFromUrls(mimeData->urls()); + if (!kdbxFiles.isEmpty()) { + event->acceptProposedAction(); + } + for (const QString& kdbxFile : kdbxFiles) { + openDatabase(kdbxFile); + } + } } void MainWindow::closeAllDatabases() { - m_ui->tabWidget->closeAllDatabaseTabs(); + m_ui->tabWidget->closeAllDatabaseTabs(); } void MainWindow::lockAllDatabases() { - lockDatabasesAfterInactivity(); + lockDatabasesAfterInactivity(); }