From 3b330ee2d11221b598ec60e506cc4c5652e33dd6 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Fri, 30 Aug 2019 20:18:41 -0400 Subject: [PATCH] Improve accessibility (#3409) * Add application settings reset button - Corrects accessibility findings GP.2 * Use icons in addition to color to indicate password mismatch - Corrects accessibility finding CN.2 * Announce begin/end of list navigation - Corrects accessibility finding KF.4 * Fixes for keyboard navigation - Add Ctrl+F10 keyboard shortcut to show group/entry context menus. Fixes #3140 - Improve movement between form fields * Fix loading system-defined language in translator - Fixes #3202 - Bypass built-in Qt loading of QLocale for translations. The order of loading languages doesn't consider all file names prior to moving to the next language in the list. This resulted in English being chosen no matter what language is the top priority. * Improve message box defaults and fix documentation links * Better support for screen readers * Add accessible names on form fields * Prevent changing values during settings widget scrolling - Add an event filter to combo boxes and spin boxes on the settings page to prevent the mouse wheel from changing the values without having focus - Add horizontal stretch to the security settings to make the spin boxes more manageable. --- src/browser/BrowserAccessControlDialog.ui | 6 + src/browser/BrowserOptionDialog.ui | 6 + src/browser/BrowserService.cpp | 2 +- src/core/Config.cpp | 7 + src/core/Config.h | 1 + src/core/Translator.cpp | 105 +++++----- src/core/Translator.h | 4 +- src/gui/ApplicationSettingsWidget.cpp | 75 ++++++- src/gui/ApplicationSettingsWidget.h | 4 + src/gui/ApplicationSettingsWidgetGeneral.ui | 113 ++++++++++- src/gui/ApplicationSettingsWidgetSecurity.ui | 183 +++++++++++------- src/gui/EditWidgetProperties.ui | 18 ++ src/gui/EntryPreviewWidget.ui | 4 +- src/gui/MainWindow.cpp | 6 +- src/gui/MainWindow.ui | 27 ++- src/gui/MessageBox.cpp | 25 +-- src/gui/MessageBox.h | 35 ++-- src/gui/PasswordEdit.cpp | 23 ++- src/gui/PasswordEdit.h | 3 + src/gui/PasswordGeneratorWidget.ui | 104 +++++++++- src/gui/TotpSetupDialog.ui | 24 ++- src/gui/WelcomeWidget.ui | 11 ++ src/gui/csvImport/CsvImportWidget.ui | 20 +- .../DatabaseSettingsWidgetBrowser.ui | 6 + .../DatabaseSettingsWidgetEncryption.ui | 24 +++ .../DatabaseSettingsWidgetGeneral.ui | 33 +++- .../DatabaseSettingsWidgetMetaDataSimple.ui | 12 +- src/gui/entry/EditEntryWidgetAdvanced.ui | 35 +++- src/gui/entry/EditEntryWidgetAutoType.ui | 37 +++- src/gui/entry/EditEntryWidgetHistory.ui | 27 +++ src/gui/entry/EditEntryWidgetMain.ui | 64 +++++- src/gui/entry/EditEntryWidgetSSHAgent.ui | 34 +++- src/gui/entry/EntryAttachmentsWidget.ui | 26 ++- src/gui/entry/EntryView.cpp | 15 ++ src/gui/entry/EntryView.h | 1 + src/gui/group/EditGroupWidgetMain.ui | 33 +++- src/gui/group/GroupView.cpp | 11 ++ src/gui/group/GroupView.h | 1 + src/gui/masterkey/KeyFileEditWidget.ui | 11 +- src/gui/masterkey/PasswordEditWidget.ui | 15 +- src/gui/masterkey/YubiKeyEditWidget.ui | 6 + src/keeshare/SettingsWidgetKeeShare.ui | 51 ++++- src/keeshare/group/EditGroupWidgetKeeShare.ui | 27 ++- 43 files changed, 1073 insertions(+), 202 deletions(-) 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