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 29715314..55914bfe 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 3466100a..0e3e446f 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 f8e9f037..eb88b5c1 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 681f87be..ce0b5a65 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 ca77e0c0..d65b3256 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 95de3ce9..4e3f568c 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 23a18422..8236ade4 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 22dea6a1..1e7dca65 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 fe9ac88f..63487e1b 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 311b408b..d2ffd2a1 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 209c156b..2310bd07 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 fb8ed503..d80bf158 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 b2c8c28b..b620da65 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 ad00a662..bdfefab0 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 807cdcf6..135454f6 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 7652d634..7d2b2a51 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 13deffb6..dc6ed4a4 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 e341eddd..bc5cfc9f 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 29b33f0b..b6e74ed0 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 ca970fbd..ff2d0582 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 6f2af49f..a12da0fa 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 3cc35c66..8b72df84 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 df0af79f..64835102 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 b9bbf433..463f572d 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 1de060e9..f8ba579d 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 00c1437b..02f07952 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 b4ac30b9..6878a553 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 9556eee1..7b079b67 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 81261394..d987e804 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 8390f22f..b85d3f0c 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 5ed534dc..f9078f2d 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 5957f657..2e9d94b6 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 60292309..bd6e1553 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 cd7896b0..bff11e12 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 09dfd8dd..53de7aff 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 20ce2f41..486e408b 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 77b5bff8..33c59169 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 76425c6c..00b5a28c 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 a267935b..fd52e2e1 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 e435e990..d0a85eb5 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 08508739..fa150084 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 77a9e3eb..0840c974 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 30e34962..b64195c6 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