Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/keepassxreboot/keepassxc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan White <support@dmapps.us>2019-01-17 06:53:29 +0300
committerJonathan White <support@dmapps.us>2019-01-17 06:53:29 +0300
commita8e266129a6cd35bc8db77de88c3bbbc9697be5e (patch)
treeaaebeda0e6cf114d00ae0e58120b360f48ee5c41
parentd11bb247b34b9002b9b0949644c8d30f4388f205 (diff)
Corrected formatting and cleanup
-rw-r--r--INSTALL.md5
-rw-r--r--README.md6
-rw-r--r--cmake/FindQuaZip.cmake16
-rw-r--r--snapcraft.yaml2
-rw-r--r--src/core/Database.cpp2
-rw-r--r--src/crypto/CryptoHash.h1
-rw-r--r--src/crypto/ssh/CMakeLists.txt6
-rw-r--r--src/gui/AboutDialog.cpp102
-rw-r--r--src/gui/EntryPreviewWidget.cpp17
-rw-r--r--src/gui/MainWindow.cpp1559
10 files changed, 856 insertions, 860 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 @@
# <img src="https://keepassxc.org/logo.png" width="40" height="40"/> 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 <QSysInfo>
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 <QCloseEvent>
-#include <QFileInfo>
#include <QDesktopServices>
+#include <QFileInfo>
#include <QMimeData>
#include <QShortcut>
#include <QTimer>
@@ -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<NativeMessagingHost>(new NativeMessagingHost(tabWidget, browserSettings()->isEnabled()));
- }
-
- ~BrowserPlugin()
- {
- }
-
- QString name() override
- {
- return QObject::tr("Browser Integration");
- }
-
- QIcon icon() override
- {
- return FilePath::instance()->icon("apps", "internet-web-browser");
- }
-
- QWidget* createWidget() override
- {
- BrowserOptionDialog* dlg = new BrowserOptionDialog();
- return dlg;
- }
-
- void loadSettings(QWidget* widget) override
- {
- qobject_cast<BrowserOptionDialog*>(widget)->loadSettings();
- }
-
- void saveSettings(QWidget* widget) override
- {
- qobject_cast<BrowserOptionDialog*>(widget)->saveSettings();
- if (browserSettings()->isEnabled()) {
- m_nativeMessagingHost->run();
- } else {
- m_nativeMessagingHost->stop();
- }
- }
+ BrowserPlugin(DatabaseTabWidget* tabWidget)
+ {
+ m_nativeMessagingHost =
+ QSharedPointer<NativeMessagingHost>(new NativeMessagingHost(tabWidget, browserSettings()->isEnabled()));
+ }
+
+ ~BrowserPlugin()
+ {
+ }
+
+ QString name() override
+ {
+ return QObject::tr("Browser Integration");
+ }
+
+ QIcon icon() override
+ {
+ return FilePath::instance()->icon("apps", "internet-web-browser");
+ }
+
+ QWidget* createWidget() override
+ {
+ BrowserOptionDialog* dlg = new BrowserOptionDialog();
+ return dlg;
+ }
+
+ void loadSettings(QWidget* widget) override
+ {
+ qobject_cast<BrowserOptionDialog*>(widget)->loadSettings();
+ }
+
+ void saveSettings(QWidget* widget) override
+ {
+ qobject_cast<BrowserOptionDialog*>(widget)->saveSettings();
+ if (browserSettings()->isEnabled()) {
+ m_nativeMessagingHost->run();
+ } else {
+ m_nativeMessagingHost->stop();
+ }
+ }
private:
- QSharedPointer<NativeMessagingHost> m_nativeMessagingHost;
+ QSharedPointer<NativeMessagingHost> 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
-
- 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()));
-
- Qt::Key globalAutoTypeKey = static_cast<Qt::Key>(config()->get("GlobalAutoTypeKey").toInt());
- Qt::KeyboardModifiers globalAutoTypeModifiers =
- static_cast<Qt::KeyboardModifiers>(config()->get("GlobalAutoTypeModifiers").toInt());
- if (globalAutoTypeKey > 0 && globalAutoTypeModifiers > 0) {
- autoType()->registerGlobalShortcut(globalAutoTypeKey, globalAutoTypeModifiers);
- }
-
- m_ui->actionEntryAutoType->setVisible(autoType()->isAvailable());
-
- m_inactivityTimer = new InactivityTimer(this);
- connect(m_inactivityTimer, SIGNAL(inactivityDetected()), this, SLOT(lockDatabasesAfterInactivity()));
+ // 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_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<Qt::Key>(config()->get("GlobalAutoTypeKey").toInt());
+ Qt::KeyboardModifiers globalAutoTypeModifiers =
+ static_cast<Qt::KeyboardModifiers>(config()->get("GlobalAutoTypeModifiers").toInt());
+ if (globalAutoTypeKey > 0 && globalAutoTypeModifiers > 0) {
+ autoType()->registerGlobalShortcut(globalAutoTypeKey, globalAutoTypeModifiers);
+ }
+
+ m_ui->actionEntryAutoType->setVisible(autoType()->isAvailable());
+
+ 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();
-
- 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);
+ 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);
#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()));
-
- 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->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->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)));
-
- // 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->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->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->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->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()));
+ // 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->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->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_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()));
+
+ 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()));
+
+ 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->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()));
+
+ 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->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();
-
- 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);
+ 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);
}
void MainWindow::updateCopyAttributesMenu()
{
- DatabaseWidget* dbWidget = m_ui->tabWidget->currentDatabaseWidget();
- if (!dbWidget) {
- return;
- }
-
- if (dbWidget->numberOfSelectedEntries() != 1) {
- return;
- }
-
- QList<QAction*> 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);
- }
+ DatabaseWidget* dbWidget = m_ui->tabWidget->currentDatabaseWidget();
+ if (!dbWidget) {
+ return;
+ }
+
+ if (dbWidget->numberOfSelectedEntries() != 1) {
+ return;
+ }
+
+ QList<QAction*> 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);
+ }
}
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;
- }
-
- auto db = QSharedPointer<Database>::create();
- auto key = QSharedPointer<CompositeKey>::create();
- if (!pw.isEmpty()) {
- key->addKey(QSharedPointer<PasswordKey>::create(pw));
- }
- if (!keyFile.isEmpty()) {
- auto fileKey = QSharedPointer<FileKey>::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);
- }
+ if (pw.isEmpty() && keyFile.isEmpty()) {
+ m_ui->tabWidget->addDatabaseTab(filePath);
+ return;
+ }
+
+ auto db = QSharedPointer<Database>::create();
+ auto key = QSharedPointer<CompositeKey>::create();
+ if (!pw.isEmpty()) {
+ key->addKey(QSharedPointer<PasswordKey>::create(pw));
+ }
+ if (!keyFile.isEmpty()) {
+ auto fileKey = QSharedPointer<FileKey>::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();
-
- bool inDatabaseTabWidget = (currentIndex == DatabaseTabScreen);
- bool inWelcomeWidget = (currentIndex == WelcomeScreen);
- bool inDatabaseTabWidgetOrWelcomeWidget = inDatabaseTabWidget || inWelcomeWidget;
-
- 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->actionLockDatabases->setEnabled(m_ui->tabWidget->hasLockableDatabases());
-
- if (inDatabaseTabWidget && m_ui->tabWidget->currentIndex() != -1) {
- DatabaseWidget* dbWidget = m_ui->tabWidget->currentDatabaseWidget();
- Q_ASSERT(dbWidget);
-
- 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();
-
- 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);
-
- break;
- }
- case DatabaseWidget::Mode::EditMode:
- case DatabaseWidget::Mode::ImportMode:
- case DatabaseWidget::Mode::LockedMode: {
- const QList<QAction*> entryActions = m_ui->menuEntries->actions();
- for (QAction* action : entryActions) {
- action->setEnabled(false);
- }
-
- const QList<QAction*> 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_searchWidgetAction->setEnabled(false);
- break;
- }
- default:
- Q_ASSERT(false);
- }
- m_ui->actionDatabaseClose->setEnabled(true);
- } else {
- const QList<QAction*> entryActions = m_ui->menuEntries->actions();
- for (QAction* action : entryActions) {
- action->setEnabled(false);
- }
-
- const QList<QAction*> 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_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);
- }
+ int currentIndex = m_ui->stackedWidget->currentIndex();
+
+ bool inDatabaseTabWidget = (currentIndex == DatabaseTabScreen);
+ bool inWelcomeWidget = (currentIndex == WelcomeScreen);
+ bool inDatabaseTabWidgetOrWelcomeWidget = inDatabaseTabWidget || inWelcomeWidget;
+
+ 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->actionLockDatabases->setEnabled(m_ui->tabWidget->hasLockableDatabases());
+
+ if (inDatabaseTabWidget && m_ui->tabWidget->currentIndex() != -1) {
+ DatabaseWidget* dbWidget = m_ui->tabWidget->currentDatabaseWidget();
+ Q_ASSERT(dbWidget);
+
+ 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();
+
+ 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);
+
+ break;
+ }
+ case DatabaseWidget::Mode::EditMode:
+ case DatabaseWidget::Mode::ImportMode:
+ case DatabaseWidget::Mode::LockedMode: {
+ const QList<QAction*> entryActions = m_ui->menuEntries->actions();
+ for (QAction* action : entryActions) {
+ action->setEnabled(false);
+ }
+
+ const QList<QAction*> 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_searchWidgetAction->setEnabled(false);
+ break;
+ }
+ default:
+ Q_ASSERT(false);
+ }
+ m_ui->actionDatabaseClose->setEnabled(true);
+ } else {
+ const QList<QAction*> entryActions = m_ui->menuEntries->actions();
+ for (QAction* action : entryActions) {
+ action->setEnabled(false);
+ }
+
+ const QList<QAction*> 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_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);
+ }
}
void MainWindow::updateWindowTitle()
{
- 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");
- }
-
- 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());
- }
-
- setWindowTitle(windowTitle);
- setWindowModified(isModified);
+ 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");
+ }
+
+ 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());
+ }
+
+ 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;
- }
-
- if (config()->get("GUI/MinimizeOnClose").toBool() && !m_appExitCalled) {
- event->ignore();
- hideWindow();
- return;
- }
-
- bool accept = saveLastDatabases();
-
- if (accept) {
- m_appExiting = true;
- saveWindowInformation();
-
- event->accept();
- QApplication::quit();
- } else {
- event->ignore();
- }
+ // 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;
+ }
+
+ bool accept = saveLastDatabases();
+
+ if (accept) {
+ m_appExiting = true;
+ saveWindowInformation();
+
+ 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 (config()->get("security/lockdatabaseminimize").toBool()) {
- m_ui->tabWidget->lockDatabases();
- }
- } else {
- QMainWindow::changeEvent(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 (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()));
-
- 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;
- }
- }
+ connect(actionToggle, SIGNAL(triggered()), SLOT(toggleWindow()));
+
+ 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;
+ }
+ }
}
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;
- }
-
- m_inactivityTimer->setInactivityTimeout(timeout);
- if (config()->get("security/lockdatabaseidle").toBool()) {
- m_inactivityTimer->activate();
- } else {
- m_inactivityTimer->deactivate();
- }
+ 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();
+ }
#ifdef WITH_XC_TOUCHID
- // 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();
- }
+ // 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();
+ }
#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();
- }
-
- if (config()->get("security/lockdatabaseminimize").toBool()) {
- m_ui->tabWidget->lockDatabases();
- }
+ // 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();
+ }
}
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<QVariant> args;
- args << QVariant::fromValue(static_cast<uint32_t>(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<QVariant> args;
+ args << QVariant::fromValue(static_cast<uint32_t>(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<QUrl>& 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());
- }
- }
-
- return kdbxFiles;
+ 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;
}
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();
}