diff --git a/src/browser/BrowserAccessControlDialog.ui b/src/browser/BrowserAccessControlDialog.ui
index 29715314d..55914bfec 100755
--- a/src/browser/BrowserAccessControlDialog.ui
+++ b/src/browser/BrowserAccessControlDialog.ui
@@ -48,6 +48,9 @@
-
+
+ Allow access
+
Allow
@@ -55,6 +58,9 @@
-
+
+ Deny access
+
Deny
diff --git a/src/browser/BrowserOptionDialog.ui b/src/browser/BrowserOptionDialog.ui
index 3466100a3..0e3e446f1 100755
--- a/src/browser/BrowserOptionDialog.ui
+++ b/src/browser/BrowserOptionDialog.ui
@@ -365,6 +365,9 @@
-
+
+ Custom proxy location field
+
999
@@ -375,6 +378,9 @@
-
+
+ Browser for custom proxy file
+
Browse...
diff --git a/src/browser/BrowserService.cpp b/src/browser/BrowserService.cpp
index f8e9f0371..eb88b5c1b 100644
--- a/src/browser/BrowserService.cpp
+++ b/src/browser/BrowserService.cpp
@@ -17,12 +17,12 @@
* along with this program. If not, see .
*/
+#include
#include
#include
#include
#include
#include
-#include
#include "BrowserAccessControlDialog.h"
#include "BrowserEntryConfig.h"
diff --git a/src/core/Config.cpp b/src/core/Config.cpp
index 681f87be4..ce0b5a65a 100644
--- a/src/core/Config.cpp
+++ b/src/core/Config.cpp
@@ -89,6 +89,13 @@ void Config::sync()
m_settings->sync();
}
+void Config::resetToDefaults()
+{
+ for (const auto& setting : m_defaults.keys()) {
+ m_settings->setValue(setting, m_defaults.value(setting));
+ }
+}
+
void Config::upgrade()
{
const auto keys = deprecationMap.keys();
diff --git a/src/core/Config.h b/src/core/Config.h
index ca77e0c0a..d65b3256b 100644
--- a/src/core/Config.h
+++ b/src/core/Config.h
@@ -38,6 +38,7 @@ public:
void set(const QString& key, const QVariant& value);
bool hasAccessError();
void sync();
+ void resetToDefaults();
static Config* instance();
static void createConfigFromFile(const QString& file);
diff --git a/src/core/Translator.cpp b/src/core/Translator.cpp
index 95de3ce91..4e3f568cb 100644
--- a/src/core/Translator.cpp
+++ b/src/core/Translator.cpp
@@ -34,16 +34,21 @@
*/
void Translator::installTranslators()
{
- QLocale locale;
- QString language = config()->get("GUI/Language").toString();
- if (!language.isEmpty() && language != "system") {
- // use actual English translation instead of the English locale source language
- if (language == "en") {
- language = "en_US";
- }
- locale = QLocale(language);
+ QStringList languages;
+ QString languageSetting = config()->get("GUI/Language").toString();
+ if (languageSetting.isEmpty() || languageSetting == "system") {
+ // NOTE: this is a workaround for the terrible way Qt loads languages
+ // using the QLocale::uiLanguages() approach. Instead, we search each
+ // language and all country variants in order before moving to the next.
+ QLocale locale;
+ languages = locale.uiLanguages();
+ } else {
+ languages << languageSetting;
}
+ // Always try to load english last
+ languages << "en_US";
+
const QStringList paths = {
#ifdef QT_DEBUG
QString("%1/share/translations").arg(KEEPASSX_BINARY_DIR),
@@ -52,9 +57,10 @@ void Translator::installTranslators()
bool translationsLoaded = false;
for (const QString& path : paths) {
- translationsLoaded |= installTranslator(locale, path) || installTranslator(QLocale("en_US"), path);
- if (!installQtTranslator(language, path)) {
- installQtTranslator(QLocale("en"), path);
+ installQtTranslator(languages, path);
+ if (installTranslator(languages, path)) {
+ translationsLoaded = true;
+ break;
}
}
@@ -64,6 +70,48 @@ void Translator::installTranslators()
}
}
+/**
+ * Install KeePassXC translator.
+ *
+ * @param languages priority-ordered list of languages
+ * @param path absolute search path
+ * @return true on success
+ */
+bool Translator::installTranslator(const QStringList& languages, const QString& path)
+{
+ for (const auto& language : languages) {
+ QLocale locale(language);
+ QScopedPointer translator(new QTranslator(qApp));
+ if (translator->load(locale, "keepassx_", "", path)) {
+ return QCoreApplication::installTranslator(translator.take());
+ }
+ }
+
+ return false;
+}
+
+/**
+ * Install Qt5 base translator from the specified local search path or the default system path
+ * if no qtbase_* translations were found at the local path.
+ *
+ * @param languages priority-ordered list of languages
+ * @param path absolute search path
+ * @return true on success
+ */
+bool Translator::installQtTranslator(const QStringList& languages, const QString& path)
+{
+ for (const auto& language : languages) {
+ QLocale locale(language);
+ QScopedPointer qtTranslator(new QTranslator(qApp));
+ if (qtTranslator->load(locale, "qtbase_", "", path)) {
+ return QCoreApplication::installTranslator(qtTranslator.take());
+ } else if (qtTranslator->load(locale, "qtbase_", "", QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
+ return QCoreApplication::installTranslator(qtTranslator.take());
+ }
+ }
+ return false;
+}
+
/**
* @return list of pairs of available language codes and names
*/
@@ -108,38 +156,3 @@ QList> Translator::availableLanguages()
return languages;
}
-
-/**
- * Install KeePassXC translator.
- *
- * @param language translator language
- * @param path local search path
- * @return true on success
- */
-bool Translator::installTranslator(const QLocale& locale, const QString& path)
-{
- QScopedPointer translator(new QTranslator(qApp));
- if (translator->load(locale, "keepassx_", "", path)) {
- return QCoreApplication::installTranslator(translator.take());
- }
- return false;
-}
-
-/**
- * Install Qt5 base translator from the specified local search path or the default system path
- * if no qtbase_* translations were found at the local path.
- *
- * @param language translator language
- * @param path local search path
- * @return true on success
- */
-bool Translator::installQtTranslator(const QLocale& locale, const QString& path)
-{
- QScopedPointer qtTranslator(new QTranslator(qApp));
- if (qtTranslator->load(locale, "qtbase_", "", path)) {
- return QCoreApplication::installTranslator(qtTranslator.take());
- } else if (qtTranslator->load(locale, "qtbase_", "", QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
- return QCoreApplication::installTranslator(qtTranslator.take());
- }
- return false;
-}
diff --git a/src/core/Translator.h b/src/core/Translator.h
index 23a18422c..8236ade43 100644
--- a/src/core/Translator.h
+++ b/src/core/Translator.h
@@ -29,8 +29,8 @@ public:
static QList> availableLanguages();
private:
- static bool installTranslator(const QLocale& locale, const QString& path);
- static bool installQtTranslator(const QLocale& locale, const QString& path);
+ static bool installTranslator(const QStringList& languages, const QString& path);
+ static bool installQtTranslator(const QStringList& languages, const QString& path);
};
#endif // KEEPASSX_TRANSLATOR_H
diff --git a/src/gui/ApplicationSettingsWidget.cpp b/src/gui/ApplicationSettingsWidget.cpp
index 22dea6a19..1e7dca651 100644
--- a/src/gui/ApplicationSettingsWidget.cpp
+++ b/src/gui/ApplicationSettingsWidget.cpp
@@ -28,6 +28,7 @@
#include "core/Global.h"
#include "core/Translator.h"
+#include "MessageBox.h"
#include "touchid/TouchID.h"
class ApplicationSettingsWidget::ExtraPage
@@ -54,6 +55,28 @@ private:
QWidget* widget;
};
+/**
+ * Helper class to ignore mouse wheel events on non-focused widgets
+ * NOTE: The widget must NOT have a focus policy of "WHEEL"
+ */
+class MouseWheelEventFilter : public QObject
+{
+public:
+ explicit MouseWheelEventFilter(QObject* parent)
+ : QObject(parent){};
+
+protected:
+ bool eventFilter(QObject* obj, QEvent* event) override
+ {
+ const auto* widget = qobject_cast(obj);
+ if (event->type() == QEvent::Wheel && widget && !widget->hasFocus()) {
+ event->ignore();
+ return true;
+ }
+ return QObject::eventFilter(obj, event);
+ }
+};
+
ApplicationSettingsWidget::ApplicationSettingsWidget(QWidget* parent)
: EditWidget(parent)
, m_secWidget(new QWidget())
@@ -84,6 +107,7 @@ ApplicationSettingsWidget::ApplicationSettingsWidget(QWidget* parent)
connect(m_generalUi->systrayShowCheckBox, SIGNAL(toggled(bool)), SLOT(systrayToggled(bool)));
connect(m_generalUi->toolbarHideCheckBox, SIGNAL(toggled(bool)), SLOT(toolbarSettingsToggled(bool)));
connect(m_generalUi->rememberLastDatabasesCheckBox, SIGNAL(toggled(bool)), SLOT(rememberDatabasesToggled(bool)));
+ connect(m_generalUi->resetSettingsButton, SIGNAL(clicked()), SLOT(resetSettings()));
connect(m_secUi->clearClipboardCheckBox, SIGNAL(toggled(bool)),
m_secUi->clearClipboardSpinBox, SLOT(setEnabled(bool)));
@@ -95,6 +119,13 @@ ApplicationSettingsWidget::ApplicationSettingsWidget(QWidget* parent)
m_secUi->touchIDResetSpinBox, SLOT(setEnabled(bool)));
// clang-format on
+ // Disable mouse wheel grab when scrolling
+ // This prevents combo box and spinner values from changing without explicit focus
+ auto mouseWheelFilter = new MouseWheelEventFilter(this);
+ m_generalUi->faviconTimeoutSpinBox->installEventFilter(mouseWheelFilter);
+ m_generalUi->toolButtonStyleComboBox->installEventFilter(mouseWheelFilter);
+ m_generalUi->languageComboBox->installEventFilter(mouseWheelFilter);
+
#ifdef WITH_XC_UPDATECHECK
connect(m_generalUi->checkForUpdatesOnStartupCheckBox, SIGNAL(toggled(bool)), SLOT(checkUpdatesToggled(bool)));
#else
@@ -246,7 +277,6 @@ void ApplicationSettingsWidget::loadSettings()
void ApplicationSettingsWidget::saveSettings()
{
-
if (config()->hasAccessError()) {
showMessage(tr("Access error for config file %1").arg(config()->getFileName()), MessageWidget::Error);
// We prevent closing the settings page if we could not write to
@@ -330,6 +360,7 @@ void ApplicationSettingsWidget::saveSettings()
config()->set("LastDatabases", {});
config()->set("OpenPreviousDatabasesOnStartup", {});
config()->set("LastActiveDatabase", {});
+ config()->set("LastAttachmentDir", {});
}
if (!config()->get("RememberLastKeyFiles").toBool()) {
@@ -342,6 +373,48 @@ void ApplicationSettingsWidget::saveSettings()
}
}
+void ApplicationSettingsWidget::resetSettings()
+{
+ // Confirm reset
+ auto ans = MessageBox::question(this,
+ tr("Reset Settings?"),
+ tr("Are you sure you want to reset all general and security settings to default?"),
+ MessageBox::Reset | MessageBox::Cancel,
+ MessageBox::Cancel);
+ if (ans == MessageBox::Cancel) {
+ return;
+ }
+
+ if (config()->hasAccessError()) {
+ showMessage(tr("Access error for config file %1").arg(config()->getFileName()), MessageWidget::Error);
+ // We prevent closing the settings page if we could not write to
+ // the config file.
+ return;
+ }
+
+ // Reset general and security settings to default
+ config()->resetToDefaults();
+
+ // Clear recently used data
+ config()->set("LastDatabases", {});
+ config()->set("OpenPreviousDatabasesOnStartup", {});
+ config()->set("LastActiveDatabase", {});
+ config()->set("LastAttachmentDir", {});
+ config()->set("LastKeyFiles", {});
+ config()->set("LastDir", "");
+
+ // Save the Extra Pages (these are NOT reset)
+ for (const ExtraPage& page : asConst(m_extraPages)) {
+ page.saveSettings();
+ }
+
+ config()->sync();
+
+ // Refresh the settings widget and notify listeners
+ loadSettings();
+ emit settingsReset();
+}
+
void ApplicationSettingsWidget::reject()
{
// register the old key again as it might have changed
diff --git a/src/gui/ApplicationSettingsWidget.h b/src/gui/ApplicationSettingsWidget.h
index fe9ac88fc..63487e1b5 100644
--- a/src/gui/ApplicationSettingsWidget.h
+++ b/src/gui/ApplicationSettingsWidget.h
@@ -50,8 +50,12 @@ public:
void addSettingsPage(ISettingsPage* page);
void loadSettings();
+signals:
+ void settingsReset();
+
private slots:
void saveSettings();
+ void resetSettings();
void reject();
void autoSaveToggled(bool checked);
void hideWindowOnCopyCheckBoxToggled(bool checked);
diff --git a/src/gui/ApplicationSettingsWidgetGeneral.ui b/src/gui/ApplicationSettingsWidgetGeneral.ui
index 311b408b8..d2ffd2a1a 100644
--- a/src/gui/ApplicationSettingsWidgetGeneral.ui
+++ b/src/gui/ApplicationSettingsWidgetGeneral.ui
@@ -7,7 +7,7 @@
0
0
684
- 860
+ 951
@@ -349,6 +349,12 @@
0
+
+ Qt::StrongFocus
+
+
+ Website icon download timeout in seconds
+
sec
@@ -437,7 +443,7 @@
-
-
+
0
@@ -487,8 +493,30 @@
0
+
+ Qt::StrongFocus
+
+
+ Toolbar button style
+
+
+ QComboBox::AdjustToContents
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
-
@@ -521,7 +549,7 @@
QLayout::SetMaximumSize
-
-
+
Qt::Horizontal
@@ -609,7 +637,7 @@
-
-
+
8
@@ -634,6 +662,12 @@
0
+
+ Qt::StrongFocus
+
+
+ Language selection
+
-
@@ -643,6 +677,68 @@
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 15
+
+
+
+
+ -
+
+
+ 0
+
+
+ QLayout::SetMaximumSize
+
+
-
+
+
+ Reset Settings to Default
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Expanding
+
+
+
+ 50
+ 20
+
+
+
+
@@ -715,6 +811,9 @@
0
+
+ Global auto-type shortcut
+
-
@@ -732,6 +831,9 @@
0
+
+ Auto-type character typing delay milliseconds
+
ms
@@ -761,6 +863,9 @@
0
+
+ Auto-type start delay milliseconds
+
ms
diff --git a/src/gui/ApplicationSettingsWidgetSecurity.ui b/src/gui/ApplicationSettingsWidgetSecurity.ui
index 209c156b3..2310bd07d 100644
--- a/src/gui/ApplicationSettingsWidgetSecurity.ui
+++ b/src/gui/ApplicationSettingsWidgetSecurity.ui
@@ -28,14 +28,7 @@
Timeouts
-
-
-
-
-
- Clear clipboard after
-
-
-
+
-
@@ -47,6 +40,9 @@
0
+
+ Clipboard clear seconds
+
sec
@@ -61,14 +57,93 @@
- -
-
+
-
+
- Clear search query after
+ Forget TouchID after inactivity of
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ false
+
+
+
+ 0
+ 0
+
+
+
+ Touch ID inactivity reset
+
+
+ min
+
+
+ 1440
+
+
+ 30
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Lock databases after inactivity of
-
+
+
+ false
+
+
+
+ 0
+ 0
+
+
+
+ Database lock timeout seconds
+
+
+ sec
+
+
+ 10
+
+
+ 43200
+
+
+ 240
+
+
+
+ -
false
@@ -96,70 +171,17 @@
+ -
+
+
+ Clear clipboard after
+
+
+
-
-
-
-
- 0
- 0
-
-
+
- Lock databases after inactivity of
-
-
-
- -
-
-
- false
-
-
-
- 0
- 0
-
-
-
- sec
-
-
- 10
-
-
- 43200
-
-
- 240
-
-
-
- -
-
-
- Forget TouchID after inactivity of
-
-
-
- -
-
-
- false
-
-
-
- 0
- 0
-
-
-
- min
-
-
- 1440
-
-
- 30
+ Clear search query after
@@ -272,6 +294,21 @@
+
+ clearClipboardCheckBox
+ clearClipboardSpinBox
+ touchIDResetSpinBox
+ lockDatabaseOnScreenLockCheckBox
+ touchIDResetOnScreenLockCheckBox
+ lockDatabaseMinimizeCheckBox
+ relockDatabaseAutoTypeCheckBox
+ passwordRepeatCheckBox
+ passwordCleartextCheckBox
+ passwordShowDotsCheckBox
+ passwordPreviewCleartextCheckBox
+ hideNotesCheckBox
+ fallbackToSearch
+
diff --git a/src/gui/EditWidgetProperties.ui b/src/gui/EditWidgetProperties.ui
index fb8ed5030..d80bf1584 100644
--- a/src/gui/EditWidgetProperties.ui
+++ b/src/gui/EditWidgetProperties.ui
@@ -46,6 +46,9 @@
0
+
+ Datetime created
+
true
@@ -66,6 +69,9 @@
0
+
+ Datetime modified
+
true
@@ -80,6 +86,9 @@
-
+
+ Datetime accessed
+
true
@@ -94,6 +103,9 @@
-
+
+ Unique ID
+
true
@@ -109,6 +121,9 @@
-
+
+ Plugin data
+
QAbstractItemView::NoEditTriggers
@@ -130,6 +145,9 @@
-
+
+ Remove selected plugin data
+
Remove
diff --git a/src/gui/EntryPreviewWidget.ui b/src/gui/EntryPreviewWidget.ui
index b2c8c28bf..b620da659 100644
--- a/src/gui/EntryPreviewWidget.ui
+++ b/src/gui/EntryPreviewWidget.ui
@@ -521,7 +521,7 @@
Advanced
-
+
0
@@ -976,7 +976,7 @@
-
-
+
6
diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp
index ad00a6621..bdfefab08 100644
--- a/src/gui/MainWindow.cpp
+++ b/src/gui/MainWindow.cpp
@@ -343,7 +343,7 @@ MainWindow::MainWindow()
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(settingsReset()), SLOT(applySettingsChanges()));
connect(m_ui->settingsWidget, SIGNAL(accepted()), SLOT(switchToDatabases()));
connect(m_ui->settingsWidget, SIGNAL(rejected()), SLOT(switchToDatabases()));
@@ -802,12 +802,12 @@ void MainWindow::openBugReportUrl()
void MainWindow::openGettingStartedGuide()
{
- customOpenUrl(filePath()->dataPath("docs/KeePassXC_GettingStarted.pdf"));
+ customOpenUrl(QString("file:///%1").arg(filePath()->dataPath("docs/KeePassXC_GettingStarted.pdf")));
}
void MainWindow::openUserGuide()
{
- customOpenUrl(filePath()->dataPath("docs/KeePassXC_UserGuide.pdf"));
+ customOpenUrl(QString("file:///%1").arg(filePath()->dataPath("docs/KeePassXC_UserGuide.pdf")));
}
void MainWindow::openOnlineHelp()
diff --git a/src/gui/MainWindow.ui b/src/gui/MainWindow.ui
index 807cdcf6e..135454f61 100644
--- a/src/gui/MainWindow.ui
+++ b/src/gui/MainWindow.ui
@@ -69,6 +69,9 @@
0
+
+ Qt::TabFocus
+
2
@@ -116,7 +119,11 @@
0
-
-
+
+
+ Qt::TabFocus
+
+
@@ -141,7 +148,11 @@
-
-
+
+
+ Qt::TabFocus
+
+
-
@@ -166,7 +177,11 @@
-
-
+
+
+ Qt::TabFocus
+
+
@@ -183,6 +198,9 @@
21
+
+ Qt::NoFocus
+
Qt::PreventContextMenu
@@ -316,6 +334,9 @@
+
+ Qt::NoFocus
+
Qt::PreventContextMenu
diff --git a/src/gui/MessageBox.cpp b/src/gui/MessageBox.cpp
index 7652d6345..7d2b2a516 100644
--- a/src/gui/MessageBox.cpp
+++ b/src/gui/MessageBox.cpp
@@ -18,8 +18,8 @@
#include "MessageBox.h"
-#include
#include
+#include
QWindow* MessageBox::m_overrideParent(nullptr);
@@ -63,6 +63,7 @@ void MessageBox::initializeButtonDefs()
{Skip, {QMessageBox::tr("Skip"), QMessageBox::ButtonRole::AcceptRole}},
{Disable, {QMessageBox::tr("Disable"), QMessageBox::ButtonRole::AcceptRole}},
{Merge, {QMessageBox::tr("Merge"), QMessageBox::ButtonRole::AcceptRole}},
+ {Continue, {QMessageBox::tr("Continue"), QMessageBox::ButtonRole::AcceptRole}},
};
}
@@ -146,6 +147,17 @@ MessageBox::Button MessageBox::critical(QWidget* parent,
return messageBox(parent, QMessageBox::Critical, title, text, buttons, defaultButton, action, checkbox);
}
+MessageBox::Button MessageBox::warning(QWidget* parent,
+ const QString& title,
+ const QString& text,
+ MessageBox::Buttons buttons,
+ MessageBox::Button defaultButton,
+ MessageBox::Action action,
+ QCheckBox* checkbox)
+{
+ return messageBox(parent, QMessageBox::Warning, title, text, buttons, defaultButton, action, checkbox);
+}
+
MessageBox::Button MessageBox::information(QWidget* parent,
const QString& title,
const QString& text,
@@ -168,17 +180,6 @@ MessageBox::Button MessageBox::question(QWidget* parent,
return messageBox(parent, QMessageBox::Question, title, text, buttons, defaultButton, action, checkbox);
}
-MessageBox::Button MessageBox::warning(QWidget* parent,
- const QString& title,
- const QString& text,
- MessageBox::Buttons buttons,
- MessageBox::Button defaultButton,
- MessageBox::Action action,
- QCheckBox* checkbox)
-{
- return messageBox(parent, QMessageBox::Warning, title, text, buttons, defaultButton, action, checkbox);
-}
-
void MessageBox::setNextAnswer(MessageBox::Button button)
{
m_nextAnswer = button;
diff --git a/src/gui/MessageBox.h b/src/gui/MessageBox.h
index 13deffb62..dc6ed4a40 100644
--- a/src/gui/MessageBox.h
+++ b/src/gui/MessageBox.h
@@ -59,10 +59,11 @@ public:
Skip = 1 << 24,
Disable = 1 << 25,
Merge = 1 << 26,
+ Continue = 1 << 27,
// Internal loop markers. Update Last when new KeePassXC button is added
First = Ok,
- Last = Merge,
+ Last = Continue,
};
enum Action
@@ -80,30 +81,30 @@ public:
const QString& title,
const QString& text,
Buttons buttons = MessageBox::Ok,
- Button defaultButton = MessageBox::NoButton,
- Action action = MessageBox::None,
- QCheckBox* checkbox = nullptr);
- static Button information(QWidget* parent,
- const QString& title,
- const QString& text,
- Buttons buttons = MessageBox::Ok,
- Button defaultButton = MessageBox::NoButton,
- Action action = MessageBox::None,
- QCheckBox* checkbox = nullptr);
- static Button question(QWidget* parent,
- const QString& title,
- const QString& text,
- Buttons buttons = MessageBox::Ok,
- Button defaultButton = MessageBox::NoButton,
+ Button defaultButton = MessageBox::Ok,
Action action = MessageBox::None,
QCheckBox* checkbox = nullptr);
static Button warning(QWidget* parent,
const QString& title,
const QString& text,
Buttons buttons = MessageBox::Ok,
- Button defaultButton = MessageBox::NoButton,
+ Button defaultButton = MessageBox::Ok,
Action action = MessageBox::None,
QCheckBox* checkbox = nullptr);
+ static Button information(QWidget* parent,
+ const QString& title,
+ const QString& text,
+ Buttons buttons = MessageBox::Ok,
+ Button defaultButton = MessageBox::Ok,
+ Action action = MessageBox::None,
+ QCheckBox* checkbox = nullptr);
+ static Button question(QWidget* parent,
+ const QString& title,
+ const QString& text,
+ Buttons buttons = MessageBox::Yes | MessageBox::Cancel,
+ Button defaultButton = MessageBox::Cancel,
+ Action action = MessageBox::None,
+ QCheckBox* checkbox = nullptr);
class OverrideParent
{
diff --git a/src/gui/PasswordEdit.cpp b/src/gui/PasswordEdit.cpp
index e341eddd4..bc5cfc9fd 100644
--- a/src/gui/PasswordEdit.cpp
+++ b/src/gui/PasswordEdit.cpp
@@ -19,6 +19,7 @@
#include "PasswordEdit.h"
#include "core/Config.h"
+#include "core/FilePath.h"
#include "gui/Font.h"
const QColor PasswordEdit::CorrectSoFarColor = QColor(255, 205, 15);
@@ -28,6 +29,16 @@ PasswordEdit::PasswordEdit(QWidget* parent)
: QLineEdit(parent)
, m_basePasswordEdit(nullptr)
{
+ const QIcon errorIcon = filePath()->icon("status", "dialog-error");
+ m_errorAction = addAction(errorIcon, QLineEdit::TrailingPosition);
+ m_errorAction->setVisible(false);
+ m_errorAction->setToolTip(tr("Passwords do not match"));
+
+ const QIcon correctIcon = filePath()->icon("actions", "dialog-ok");
+ m_correctAction = addAction(correctIcon, QLineEdit::TrailingPosition);
+ m_correctAction->setVisible(false);
+ m_correctAction->setToolTip(tr("Passwords match so far"));
+
setEchoMode(QLineEdit::Password);
updateStylesheet();
@@ -83,19 +94,23 @@ bool PasswordEdit::passwordsEqual() const
void PasswordEdit::updateStylesheet()
{
- QString stylesheet("QLineEdit { ");
+ QString stylesheet("QLineEdit { background: %1; }");
if (m_basePasswordEdit && !passwordsEqual()) {
- stylesheet.append("background: %1; ");
-
+ bool isCorrect = true;
if (m_basePasswordEdit->text().startsWith(text())) {
stylesheet = stylesheet.arg(CorrectSoFarColor.name());
} else {
stylesheet = stylesheet.arg(ErrorColor.name());
+ isCorrect = false;
}
+ m_correctAction->setVisible(isCorrect);
+ m_errorAction->setVisible(!isCorrect);
+ } else {
+ m_correctAction->setVisible(false);
+ m_errorAction->setVisible(false);
}
- stylesheet.append("}");
setStyleSheet(stylesheet);
}
diff --git a/src/gui/PasswordEdit.h b/src/gui/PasswordEdit.h
index 29b33f0bd..b6e74ed00 100644
--- a/src/gui/PasswordEdit.h
+++ b/src/gui/PasswordEdit.h
@@ -19,6 +19,7 @@
#ifndef KEEPASSX_PASSWORDEDIT_H
#define KEEPASSX_PASSWORDEDIT_H
+#include
#include
#include
@@ -47,6 +48,8 @@ private slots:
private:
bool passwordsEqual() const;
+ QPointer m_errorAction;
+ QPointer m_correctAction;
QPointer m_basePasswordEdit;
};
diff --git a/src/gui/PasswordGeneratorWidget.ui b/src/gui/PasswordGeneratorWidget.ui
index ca970fbda..ff2d0582f 100644
--- a/src/gui/PasswordGeneratorWidget.ui
+++ b/src/gui/PasswordGeneratorWidget.ui
@@ -160,6 +160,9 @@ QProgressBar::chunk {
-
+
+ Generated password
+
999
@@ -167,6 +170,12 @@ QProgressBar::chunk {
-
+
+ Toggle password visibiity
+
+
+
+
true
@@ -253,7 +262,13 @@ QProgressBar::chunk {
Qt::StrongFocus
- Upper Case Letters
+ Upper-case letters
+
+
+ Upper-case letters
+
+
+
A-Z
@@ -278,7 +293,13 @@ QProgressBar::chunk {
Qt::StrongFocus
- Lower Case Letters
+ Lower-case letters
+
+
+ Lower-case letters
+
+
+
a-z
@@ -305,6 +326,12 @@ QProgressBar::chunk {
Numbers
+
+ Numbers
+
+
+
+
0-9
@@ -331,7 +358,10 @@ QProgressBar::chunk {
Qt::StrongFocus
- Special Characters
+ Special characters
+
+
+ Special characters
/*_& ...
@@ -364,6 +394,9 @@ QProgressBar::chunk {
Extended ASCII
+
+ Extended ASCII
+
ExtendedASCII
@@ -447,7 +480,10 @@ QProgressBar::chunk {
Qt::StrongFocus
- Upper Case Letters A to F
+ Upper-case letters
+
+
+ Upper-case letters
A-Z
@@ -472,7 +508,10 @@ QProgressBar::chunk {
Qt::StrongFocus
- Lower Case Letters A to F
+ Lower-case letters
+
+
+ Lower-case letters
a-z
@@ -531,6 +570,9 @@ QProgressBar::chunk {
Braces
+
+ Braces
+
{[(
@@ -563,6 +605,9 @@ QProgressBar::chunk {
Punctuation
+
+ Punctuation
+
.,:;
@@ -618,7 +663,10 @@ QProgressBar::chunk {
Qt::StrongFocus
- Math
+ Math Symbols
+
+
+ Math Symbols
<*+!?=
@@ -643,7 +691,10 @@ QProgressBar::chunk {
Qt::StrongFocus
- Dashes
+ Dashes and Slashes
+
+
+ Dashes and Slashes
\_|-/
@@ -677,6 +728,9 @@ QProgressBar::chunk {
Logograms
+
+ Logograms
+
#$%&&@^`~
@@ -786,6 +840,9 @@ QProgressBar::chunk {
Character set to exclude from generated password
+
+ Excluded characters
+
true
@@ -809,6 +866,9 @@ QProgressBar::chunk {
Add non-hex letters to "do not include" list
+
+ Hex Passwords
+
Hex
@@ -881,6 +941,9 @@ QProgressBar::chunk {
-
+
+ Password length
+
1
@@ -903,6 +966,9 @@ QProgressBar::chunk {
-
+
+ Password length
+
1
@@ -1084,6 +1150,12 @@ QProgressBar::chunk {
-
+
+ Regenerate password
+
+
+
+
Regenerate
@@ -1091,6 +1163,12 @@ QProgressBar::chunk {
-
+
+ Copy password
+
+
+
+
Copy
@@ -1101,6 +1179,12 @@ QProgressBar::chunk {
false
+
+ Accept password
+
+
+
+
Accept
@@ -1136,6 +1220,7 @@ QProgressBar::chunk {
editNewPassword
togglePasswordButton
+ tabWidget
sliderLength
spinBoxLength
checkBoxUpper
@@ -1149,15 +1234,16 @@ QProgressBar::chunk {
checkBoxPunctuation
checkBoxMath
checkBoxLogograms
+ checkBoxLowerAdv
checkBoxBraces
checkBoxQuotes
checkBoxDashes
checkBoxExtASCIIAdv
editExcludedChars
- buttonSimpleMode
+ buttonAddHex
checkBoxExcludeAlike
checkBoxEnsureEvery
- tabWidget
+ buttonSimpleMode
comboBoxWordList
sliderWordCount
spinBoxWordCount
diff --git a/src/gui/TotpSetupDialog.ui b/src/gui/TotpSetupDialog.ui
index 6f2af49f1..a12da0fa4 100644
--- a/src/gui/TotpSetupDialog.ui
+++ b/src/gui/TotpSetupDialog.ui
@@ -7,7 +7,7 @@
0
0
249
- 248
+ 278
@@ -30,7 +30,14 @@
-
-
+
+
+ Secret key in Base32 format
+
+
+ Secret key field
+
+
@@ -121,6 +128,9 @@
-
+
+ Time step field
+
sec
@@ -181,6 +191,16 @@
+
+ seedEdit
+ radioDefault
+ radioSteam
+ radioCustom
+ stepSpinBox
+ radio6Digits
+ radio7Digits
+ radio8Digits
+
diff --git a/src/gui/WelcomeWidget.ui b/src/gui/WelcomeWidget.ui
index 3cc35c666..8b72df840 100644
--- a/src/gui/WelcomeWidget.ui
+++ b/src/gui/WelcomeWidget.ui
@@ -185,10 +185,21 @@
110
+
+ Open a recent database
+
+
+ buttonNewDatabase
+ buttonOpenDatabase
+ buttonImportKeePass1
+ buttonImportOpVault
+ buttonImportCSV
+ recentListWidget
+
diff --git a/src/gui/csvImport/CsvImportWidget.ui b/src/gui/csvImport/CsvImportWidget.ui
index df0af79f1..648351021 100644
--- a/src/gui/csvImport/CsvImportWidget.ui
+++ b/src/gui/csvImport/CsvImportWidget.ui
@@ -143,6 +143,9 @@
false
+
+ Codec
+
false
@@ -184,6 +187,9 @@
false
+
+ Text qualification
+
false
@@ -225,6 +231,9 @@
false
+
+ Field seperation
+
false
@@ -266,6 +275,9 @@
false
+
+ Comments start with
+
false
@@ -308,7 +320,7 @@
- Number of headers line to discard
+ Number of header lines to discard
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
@@ -323,6 +335,9 @@
false
+
+ Number of header lines to discard
+
@@ -417,6 +432,9 @@
false
+
+ CSV import preview
+
true
diff --git a/src/gui/dbsettings/DatabaseSettingsWidgetBrowser.ui b/src/gui/dbsettings/DatabaseSettingsWidgetBrowser.ui
index b9bbf433b..463f572d5 100644
--- a/src/gui/dbsettings/DatabaseSettingsWidgetBrowser.ui
+++ b/src/gui/dbsettings/DatabaseSettingsWidgetBrowser.ui
@@ -112,6 +112,9 @@
-
+
+ Stored browser keys
+
QAbstractItemView::NoEditTriggers
@@ -133,6 +136,9 @@
-
+
+ Remove selected key
+
Remove
diff --git a/src/gui/dbsettings/DatabaseSettingsWidgetEncryption.ui b/src/gui/dbsettings/DatabaseSettingsWidgetEncryption.ui
index 1de060e9a..f8ba579dc 100644
--- a/src/gui/dbsettings/DatabaseSettingsWidgetEncryption.ui
+++ b/src/gui/dbsettings/DatabaseSettingsWidgetEncryption.ui
@@ -77,6 +77,9 @@
-
+
+ Change existing decryption time
+
Change
@@ -89,6 +92,9 @@
-
+
+ Decryption time in seconds
+
1
@@ -198,6 +204,9 @@
0
+
+ Database format
+
@@ -240,6 +249,9 @@
0
+
+ Encryption algorithm
+
-
AES: 256 Bit (default)
@@ -267,6 +279,9 @@
0
+
+ Key derivation function
+
-
@@ -292,6 +307,9 @@
16777215
+
+ Transform rounds
+
Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
@@ -349,6 +367,9 @@
16777215
+
+ Memory usage
+
1
@@ -378,6 +399,9 @@
16777215
+
+ Parallelism
+
1
diff --git a/src/gui/dbsettings/DatabaseSettingsWidgetGeneral.ui b/src/gui/dbsettings/DatabaseSettingsWidgetGeneral.ui
index 00c1437bb..02f07952b 100644
--- a/src/gui/dbsettings/DatabaseSettingsWidgetGeneral.ui
+++ b/src/gui/dbsettings/DatabaseSettingsWidgetGeneral.ui
@@ -49,7 +49,11 @@
-
-
+
+
+ Database name field
+
+
-
@@ -59,7 +63,11 @@
-
-
+
+
+ Database description field
+
+
-
@@ -73,6 +81,9 @@
true
+
+ Default username field
+
@@ -88,6 +99,9 @@
-
+
+ Maximum number of history items per entry
+
Max. history items:
@@ -95,6 +109,9 @@
-
+
+ Maximum size of history per entry
+
Max. history size:
@@ -102,6 +119,12 @@
-
+
+ Maximum size of history per entry
+
+
+ Maximum size of history per entry
+
MiB
@@ -115,6 +138,12 @@
-
+
+ Maximum number of history items per entry
+
+
+ Maximum number of history items per entry
+
2000000000
diff --git a/src/gui/dbsettings/DatabaseSettingsWidgetMetaDataSimple.ui b/src/gui/dbsettings/DatabaseSettingsWidgetMetaDataSimple.ui
index b4ac30b9b..6878a5536 100644
--- a/src/gui/dbsettings/DatabaseSettingsWidgetMetaDataSimple.ui
+++ b/src/gui/dbsettings/DatabaseSettingsWidgetMetaDataSimple.ui
@@ -31,7 +31,11 @@
-
-
+
+
+ Database name field
+
+
-
@@ -41,7 +45,11 @@
-
-
+
+
+ Database description field
+
+
diff --git a/src/gui/entry/EditEntryWidgetAdvanced.ui b/src/gui/entry/EditEntryWidgetAdvanced.ui
index 9556eee19..7b079b676 100644
--- a/src/gui/entry/EditEntryWidgetAdvanced.ui
+++ b/src/gui/entry/EditEntryWidgetAdvanced.ui
@@ -7,7 +7,7 @@
0
0
532
- 364
+ 374
@@ -32,6 +32,9 @@
0
+
+ Attribute selection
+
QAbstractScrollArea::AdjustToContents
@@ -55,6 +58,9 @@
0
+
+ Attribute value
+
@@ -62,6 +68,9 @@
-
+
+ Add a new attribute
+
Add
@@ -72,6 +81,9 @@
false
+
+ Remove selected attribute
+
Remove
@@ -82,6 +94,9 @@
false
+
+ Edit attribute name
+
Edit Name
@@ -105,6 +120,9 @@
true
+
+ Toggle attribute protection
+
margin-left:50%;margin-right:50%
@@ -121,6 +139,9 @@
false
+
+ Show a protected attribute
+
Reveal
@@ -177,6 +198,9 @@
25
+
+ Foreground color selection
+
@@ -219,6 +243,9 @@
25
+
+ Background color selection
+
@@ -264,6 +291,12 @@
addAttributeButton
removeAttributeButton
editAttributeButton
+ protectAttributeButton
+ revealAttributeButton
+ fgColorCheckBox
+ fgColorButton
+ bgColorCheckBox
+ bgColorButton
diff --git a/src/gui/entry/EditEntryWidgetAutoType.ui b/src/gui/entry/EditEntryWidgetAutoType.ui
index 81261394d..d987e8047 100644
--- a/src/gui/entry/EditEntryWidgetAutoType.ui
+++ b/src/gui/entry/EditEntryWidgetAutoType.ui
@@ -83,6 +83,9 @@
false
+
+ Custom Auto-Type sequence
+
-
@@ -91,10 +94,10 @@
false
- Open AutoType help webpage
+ Open Auto-Type help webpage
- AutoType help button
+ Open Auto-Type help webpage
@@ -113,6 +116,9 @@
-
+
+ Existing window associations
+
false
@@ -159,6 +165,12 @@
25
+
+ Add new window association
+
+
+ Add new window association
+
+
@@ -181,6 +193,12 @@
25
+
+ Remove selected window association
+
+
+ Remove selected window association
+
-
@@ -200,7 +218,17 @@
-
-
+
+
+ You can use an asterisk (*) to match everything
+
+
+ Set the window association title
+
+
+ You can use an asterisk to match everything
+
+
-
@@ -248,6 +276,9 @@
false
+
+ Custom Auto-Type sequence for this window
+
diff --git a/src/gui/entry/EditEntryWidgetHistory.ui b/src/gui/entry/EditEntryWidgetHistory.ui
index 8390f22fa..b85d3f0c1 100644
--- a/src/gui/entry/EditEntryWidgetHistory.ui
+++ b/src/gui/entry/EditEntryWidgetHistory.ui
@@ -25,6 +25,9 @@
-
+
+ Entry history selection
+
true
@@ -43,6 +46,12 @@
false
+
+ Show entry at selected history state
+
+
+ Show entry at selected history state
+
Show
@@ -53,6 +62,12 @@
false
+
+ Restore entry to selected history state
+
+
+ Restore entry to selected history state
+
Restore
@@ -63,6 +78,12 @@
false
+
+ Delete selected history state
+
+
+ Delete selected history state
+
Delete
@@ -73,6 +94,12 @@
false
+
+ Delete all history
+
+
+ Delete all history
+
Delete all
diff --git a/src/gui/entry/EditEntryWidgetMain.ui b/src/gui/entry/EditEntryWidgetMain.ui
index 5ed534dc2..f9078f2d1 100644
--- a/src/gui/entry/EditEntryWidgetMain.ui
+++ b/src/gui/entry/EditEntryWidgetMain.ui
@@ -2,6 +2,14 @@
EditEntryWidgetMain
+
+
+ 0
+ 0
+ 329
+ 381
+
+
0
@@ -22,10 +30,20 @@
-
-
-
+
+
+ Url field
+
+
-
+
+ Download favicon for URL
+
+
+ Download favicon for URL
+
@@ -44,6 +62,9 @@
-
+
+ Repeat password field
+
QLineEdit::Password
@@ -51,6 +72,9 @@
-
+
+ Toggle password generator
+
true
@@ -62,6 +86,9 @@
-
+
+ Password field
+
QLineEdit::Password
@@ -69,6 +96,9 @@
-
+
+ Toggle password visibility
+
true
@@ -92,6 +122,9 @@
-
+
+ Toggle notes visible
+
Notes
@@ -104,6 +137,9 @@
false
+
+ Expiration field
+
true
@@ -117,6 +153,9 @@
0
+
+ Expiration presets
+
Presets
@@ -138,6 +177,9 @@
100
+
+ Notes field
+
-
@@ -161,13 +203,24 @@
-
-
+
+
+ Title field
+
+
-
-
+
+
+ Username field
+
+
-
+
+ Toggle expiration
+
Expires
@@ -193,12 +246,15 @@
titleEdit
usernameComboBox
passwordEdit
- passwordRepeatEdit
togglePasswordButton
+ passwordRepeatEdit
togglePasswordGeneratorButton
urlEdit
+ fetchFaviconButton
+ expireCheck
expireDatePicker
expirePresets
+ notesEnabled
notesEdit
diff --git a/src/gui/entry/EditEntryWidgetSSHAgent.ui b/src/gui/entry/EditEntryWidgetSSHAgent.ui
index 5957f6572..2e9d94b65 100644
--- a/src/gui/entry/EditEntryWidgetSSHAgent.ui
+++ b/src/gui/entry/EditEntryWidgetSSHAgent.ui
@@ -37,6 +37,9 @@
-
+
+ Remove key from agent after specified seconds
+
seconds
@@ -165,6 +168,9 @@
-
+
+ Browser for key file
+
Browse...
@@ -181,7 +187,14 @@
-
-
+
+
+ Qt::ClickFocus
+
+
+ External key file
+
+
-
@@ -209,6 +222,9 @@
0
+
+ Select attachment file
+
false
@@ -270,6 +286,22 @@
+
+ addKeyToAgentCheckBox
+ removeKeyFromAgentCheckBox
+ requireUserConfirmationCheckBox
+ lifetimeCheckBox
+ lifetimeSpinBox
+ attachmentRadioButton
+ attachmentComboBox
+ externalFileRadioButton
+ browseButton
+ addToAgentButton
+ removeFromAgentButton
+ decryptButton
+ publicKeyEdit
+ copyToClipboardButton
+
diff --git a/src/gui/entry/EntryAttachmentsWidget.ui b/src/gui/entry/EntryAttachmentsWidget.ui
index 60292309f..bd6e15538 100644
--- a/src/gui/entry/EntryAttachmentsWidget.ui
+++ b/src/gui/entry/EntryAttachmentsWidget.ui
@@ -2,6 +2,14 @@
EntryAttachmentsWidget
+
+
+ 0
+ 0
+ 337
+ 289
+
+
Form
@@ -19,7 +27,11 @@
0
-
-
+
+
+ Attachments
+
+
-
@@ -41,6 +53,9 @@
false
+
+ Add new attachment
+
Add
@@ -51,6 +66,9 @@
false
+
+ Remove selected attachment
+
Remove
@@ -61,6 +79,9 @@
false
+
+ Open selected attachment
+
Open
@@ -71,6 +92,9 @@
false
+
+ Save selected attachment to disk
+
Save
diff --git a/src/gui/entry/EntryView.cpp b/src/gui/entry/EntryView.cpp
index cd7896b06..bff11e124 100644
--- a/src/gui/entry/EntryView.cpp
+++ b/src/gui/entry/EntryView.cpp
@@ -18,9 +18,11 @@
#include "EntryView.h"
+#include
#include
#include
#include
+#include
#include "core/FilePath.h"
#include "gui/SortFilterHideProxyModel.h"
@@ -56,6 +58,8 @@ EntryView::EntryView(QWidget* parent)
connect(m_model, SIGNAL(passwordsHiddenChanged()), SIGNAL(viewStateChanged()));
// clang-format on
+ new QShortcut(Qt::CTRL + Qt::Key_F10, this, SLOT(contextMenuShortcutPressed()), nullptr, Qt::WidgetShortcut);
+
m_headerMenu = new QMenu(this);
m_headerMenu->setTitle(tr("Customize View"));
m_headerMenu->addSection(tr("Customize View"));
@@ -128,6 +132,14 @@ EntryView::EntryView(QWidget* parent)
m_model->setPaperClipPixmap(filePath()->icon("actions", "paperclip").pixmap(16));
}
+void EntryView::contextMenuShortcutPressed()
+{
+ auto index = currentIndex();
+ if (hasFocus() && index.isValid()) {
+ emit customContextMenuRequested(visualRect(index).bottomLeft());
+ }
+}
+
void EntryView::keyPressEvent(QKeyEvent* event)
{
if ((event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) && currentIndex().isValid()) {
@@ -140,15 +152,18 @@ void EntryView::keyPressEvent(QKeyEvent* event)
int last = m_model->rowCount() - 1;
if (last > 0) {
+ QAccessibleEvent accessibleEvent(this, QAccessible::PageChanged);
if (event->key() == Qt::Key_Up && currentIndex().row() == 0) {
QModelIndex index = m_sortModel->mapToSource(m_sortModel->index(last, 0));
setCurrentEntry(m_model->entryFromIndex(index));
+ QAccessible::updateAccessibility(&accessibleEvent);
return;
}
if (event->key() == Qt::Key_Down && currentIndex().row() == last) {
QModelIndex index = m_sortModel->mapToSource(m_sortModel->index(0, 0));
setCurrentEntry(m_model->entryFromIndex(index));
+ QAccessible::updateAccessibility(&accessibleEvent);
return;
}
}
diff --git a/src/gui/entry/EntryView.h b/src/gui/entry/EntryView.h
index 09dfd8dde..53de7aff5 100644
--- a/src/gui/entry/EntryView.h
+++ b/src/gui/entry/EntryView.h
@@ -72,6 +72,7 @@ private slots:
void fitColumnsToWindow();
void fitColumnsToContents();
void resetViewToDefaults();
+ void contextMenuShortcutPressed();
private:
void fillRemainingWidth(bool lastColumnOnly);
diff --git a/src/gui/group/EditGroupWidgetMain.ui b/src/gui/group/EditGroupWidgetMain.ui
index 20ce2f414..486e408b6 100644
--- a/src/gui/group/EditGroupWidgetMain.ui
+++ b/src/gui/group/EditGroupWidgetMain.ui
@@ -31,7 +31,11 @@
-
-
+
+
+ Name field
+
+
-
@@ -54,23 +58,36 @@
120
+
+ Notes field
+
-
+
+ Toggle expiration
+
Expires
-
-
+
+
+ Auto-Type toggle for this and sub groups
+
+
-
false
+
+ Expiration field
+
true
@@ -84,7 +101,11 @@
-
-
+
+
+ Search toggle for this and sub groups
+
+
-
@@ -130,6 +151,12 @@
false
+
+ Default auto-type sequence field
+
+
+
+
diff --git a/src/gui/group/GroupView.cpp b/src/gui/group/GroupView.cpp
index 77b5bff86..33c591696 100644
--- a/src/gui/group/GroupView.cpp
+++ b/src/gui/group/GroupView.cpp
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
#include "core/Database.h"
#include "core/Group.h"
@@ -42,6 +43,8 @@ GroupView::GroupView(Database* db, QWidget* parent)
connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), SLOT(emitGroupChanged()));
// clang-format on
+ new QShortcut(Qt::CTRL + Qt::Key_F10, this, SLOT(contextMenuShortcutPressed()), nullptr, Qt::WidgetShortcut);
+
modelReset();
setDragEnabled(true);
@@ -50,6 +53,14 @@ GroupView::GroupView(Database* db, QWidget* parent)
setDefaultDropAction(Qt::MoveAction);
}
+void GroupView::contextMenuShortcutPressed()
+{
+ auto index = currentIndex();
+ if (hasFocus() && index.isValid()) {
+ emit customContextMenuRequested(visualRect(index).bottomLeft());
+ }
+}
+
void GroupView::changeDatabase(const QSharedPointer& newDb)
{
m_model->changeDatabase(newDb.data());
diff --git a/src/gui/group/GroupView.h b/src/gui/group/GroupView.h
index 76425c6c3..00b5a28c0 100644
--- a/src/gui/group/GroupView.h
+++ b/src/gui/group/GroupView.h
@@ -45,6 +45,7 @@ private slots:
void emitGroupChanged();
void syncExpandedState(const QModelIndex& parent, int start, int end);
void modelReset();
+ void contextMenuShortcutPressed();
protected:
void dragMoveEvent(QDragMoveEvent* event) override;
diff --git a/src/gui/masterkey/KeyFileEditWidget.ui b/src/gui/masterkey/KeyFileEditWidget.ui
index a267935b5..fd52e2e1f 100644
--- a/src/gui/masterkey/KeyFileEditWidget.ui
+++ b/src/gui/masterkey/KeyFileEditWidget.ui
@@ -31,6 +31,9 @@
0
+
+ Key file selection
+
true
@@ -38,13 +41,19 @@
-
+
+ Browse for key file
+
- Browse
+ Browse...
-
+
+ Generate a new key file
+
Generate
diff --git a/src/gui/masterkey/PasswordEditWidget.ui b/src/gui/masterkey/PasswordEditWidget.ui
index e435e9901..d0a85eb59 100644
--- a/src/gui/masterkey/PasswordEditWidget.ui
+++ b/src/gui/masterkey/PasswordEditWidget.ui
@@ -34,6 +34,9 @@
-
+
+ Password field
+
QLineEdit::Password
@@ -41,6 +44,9 @@
-
+
+ Toggle password visibility
+
true
@@ -52,13 +58,20 @@
-
+
+ Repeat password field
+
QLineEdit::Password
-
-
+
+
+ Toggle password generator
+
+
diff --git a/src/gui/masterkey/YubiKeyEditWidget.ui b/src/gui/masterkey/YubiKeyEditWidget.ui
index 08508739a..fa150084b 100644
--- a/src/gui/masterkey/YubiKeyEditWidget.ui
+++ b/src/gui/masterkey/YubiKeyEditWidget.ui
@@ -30,6 +30,9 @@
-
+
+ Refresh hardware tokens
+
Refresh
@@ -43,6 +46,9 @@
0
+
+ Hardware key slot selection
+
-
diff --git a/src/keeshare/SettingsWidgetKeeShare.ui b/src/keeshare/SettingsWidgetKeeShare.ui
index 77a9e3eba..0840c9747 100644
--- a/src/keeshare/SettingsWidgetKeeShare.ui
+++ b/src/keeshare/SettingsWidgetKeeShare.ui
@@ -31,6 +31,12 @@
-
+
+ Allow KeeShare imports
+
+
+ Allow KeeShare imports
+
Allow import
@@ -38,6 +44,12 @@
-
+
+ Allow KeeShare exports
+
+
+ Allow KeeShare exports
+
Allow export
@@ -77,6 +89,9 @@
-
+
+ Key
+
true
@@ -105,16 +120,26 @@
-
+
+ Certificate
+
true
-
-
+
+
+ Signer name field
+
+
-
+
+ Fingerprint
+
true
@@ -137,6 +162,9 @@
-
+
+ Generate new certificate
+
Generate
@@ -144,6 +172,9 @@
-
+
+ Import existing certificate
+
Import
@@ -151,6 +182,9 @@
-
+
+ Export own certificate
+
Export
@@ -169,6 +203,9 @@
-
+
+ Known shares
+
QAbstractItemView::NoEditTriggers
@@ -215,6 +252,9 @@
-
+
+ Trust selected certificate
+
Trust
@@ -222,6 +262,9 @@
-
+
+ Ask whether to trust the selected certificate every time
+
Ask
@@ -229,6 +272,9 @@
-
+
+ Untrust selected certificate
+
Untrust
@@ -236,6 +282,9 @@
-
+
+ Remove selected certificate
+
Remove
diff --git a/src/keeshare/group/EditGroupWidgetKeeShare.ui b/src/keeshare/group/EditGroupWidgetKeeShare.ui
index 30e34962f..b64195c64 100644
--- a/src/keeshare/group/EditGroupWidgetKeeShare.ui
+++ b/src/keeshare/group/EditGroupWidgetKeeShare.ui
@@ -39,7 +39,11 @@
-
-
+
+
+ Sharing mode field
+
+
-
@@ -51,10 +55,17 @@
-
-
-
+
+
+ Path to share file field
+
+
-
+
+ Browser for share file
+
...
@@ -73,6 +84,9 @@
-
+
+ Password field
+
QLineEdit::Password
@@ -80,6 +94,9 @@
-
+
+ Toggle password visibility
+
true
@@ -87,6 +104,9 @@
-
+
+ Toggle password generator
+
true
@@ -99,6 +119,9 @@
-
+
+ Clear fields
+
Clear