From 52775d4a3f10ed266f626c2e3f057ad03dc59330 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Sat, 15 Apr 2023 21:35:54 -0400 Subject: [PATCH] Fix various accessibility issues (#9138) Enable buddy fields in group and entry edit pages * Fixes #9060, you can now press Alt + [letter] to skip between fields on the group and entry edit pages. * Move the expire checkbox to the right hand column and use the standard eye icon button for notes reveal. Only show notes reveal button if the hide notes setting is enabled. Fix overflow of text in default auto-type sequence preview * Fixes #9083 Add copy title shortcut (Ctrl + I) * Closes #9109 Fix issues with menu actions being enabled incorrectly Add accessibility description to password widget to explain how to hide/show passwords and open the generator * Closes #9059 Add F6 shortcut to focus search * Closes #9163 --- share/translations/keepassxc_en.ts | 72 +++---- src/gui/EntryPreviewWidget.ui | 9 +- src/gui/MainWindow.cpp | 36 ++-- src/gui/PasswordWidget.ui | 6 +- src/gui/entry/EditEntryWidget.cpp | 8 +- src/gui/entry/EditEntryWidgetMain.ui | 281 ++++++++++++++++----------- 6 files changed, 239 insertions(+), 173 deletions(-) diff --git a/share/translations/keepassxc_en.ts b/share/translations/keepassxc_en.ts index d4a880df..3b5ae5f4 100644 --- a/share/translations/keepassxc_en.ts +++ b/share/translations/keepassxc_en.ts @@ -2840,22 +2840,10 @@ Would you like to correct it? Notes field - - Toggle the checkbox to reveal the notes section. - - Username field - - Toggle notes visible - - - - Notes: - - Expiration field @@ -2872,14 +2860,6 @@ Would you like to correct it? Presets - - Password: - - - - URL: - - Url field @@ -2888,18 +2868,10 @@ Would you like to correct it? Download favicon for URL - - Title: - - Title field - - Username: - - Password field @@ -2908,18 +2880,42 @@ Would you like to correct it? Toggle expiration - - Expires: - - - - Tags: - - Tags list + + &Username: + + + + &Title: + + + + &Password: + + + + UR&L: + + + + &Notes: + + + + Toggle notes visibility + + + + T&ags: + + + + &Expires: + + EditEntryWidgetSSHAgent @@ -6207,6 +6203,10 @@ Do you want to overwrite it? Password quality + + Toggle password visibilty using Control + H. Open the password generator using Control + G. + + PickcharsDialog diff --git a/src/gui/EntryPreviewWidget.ui b/src/gui/EntryPreviewWidget.ui index 6e0ce5ec..c251da3f 100644 --- a/src/gui/EntryPreviewWidget.ui +++ b/src/gui/EntryPreviewWidget.ui @@ -6,7 +6,7 @@ 0 0 - 508 + 530 257 @@ -177,7 +177,7 @@ - 0 + 2 false @@ -753,7 +753,7 @@ Default Sequence - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing @@ -771,6 +771,9 @@ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + true + diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index ea2ab4fc..aa9e3399 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -146,6 +146,9 @@ MainWindow::MainWindow() m_entryContextMenu->addAction(m_ui->actionEntryOpenUrl); m_entryContextMenu->addAction(m_ui->actionEntryDownloadIcon); m_entryContextMenu->addSeparator(); + m_entryContextMenu->addAction(m_ui->actionEntryAddToAgent); + m_entryContextMenu->addAction(m_ui->actionEntryRemoveFromAgent); + m_entryContextMenu->addSeparator(); m_entryContextMenu->addAction(m_ui->actionEntryRestore); m_entryNewContextMenu = new QMenu(this); @@ -192,18 +195,8 @@ MainWindow::MainWindow() connect(sshAgent(), SIGNAL(error(QString)), this, SLOT(showErrorMessage(QString))); connect(sshAgent(), SIGNAL(enabledChanged(bool)), this, SLOT(agentEnabled(bool))); m_ui->settingsWidget->addSettingsPage(new AgentSettingsPage()); - - m_entryContextMenu->addSeparator(); - m_entryContextMenu->addAction(m_ui->actionEntryAddToAgent); - m_entryContextMenu->addAction(m_ui->actionEntryRemoveFromAgent); - - m_ui->actionEntryAddToAgent->setIcon(icons()->icon("utilities-terminal")); - m_ui->actionEntryRemoveFromAgent->setIcon(icons()->icon("utilities-terminal")); #endif - m_ui->actionEntryAddToAgent->setVisible(false); - m_ui->actionEntryRemoveFromAgent->setVisible(false); - initViewMenu(); #if defined(WITH_XC_KEESHARE) @@ -289,6 +282,7 @@ MainWindow::MainWindow() m_ui->actionEntryMoveDown->setShortcut(Qt::CTRL + Qt::ALT + Qt::Key_Down); m_ui->actionEntryCopyUsername->setShortcut(Qt::CTRL + Qt::Key_B); m_ui->actionEntryCopyPassword->setShortcut(Qt::CTRL + Qt::Key_C); + m_ui->actionEntryCopyTitle->setShortcut(Qt::CTRL + Qt::Key_I); m_ui->actionEntryAutoTypeSequence->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_V); m_ui->actionEntryOpenUrl->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_U); m_ui->actionEntryCopyURL->setShortcut(Qt::CTRL + Qt::Key_U); @@ -322,6 +316,7 @@ MainWindow::MainWindow() m_ui->actionEntryAutoTypeSequence->setShortcutVisibleInContextMenu(true); m_ui->actionEntryOpenUrl->setShortcutVisibleInContextMenu(true); m_ui->actionEntryCopyURL->setShortcutVisibleInContextMenu(true); + m_ui->actionEntryCopyTitle->setShortcutVisibleInContextMenu(true); m_ui->actionEntryAddToAgent->setShortcutVisibleInContextMenu(true); m_ui->actionEntryRemoveFromAgent->setShortcutVisibleInContextMenu(true); #endif @@ -416,6 +411,8 @@ MainWindow::MainWindow() m_ui->actionEntryCopyPasswordTotp->setIcon(icons()->icon("totp-copy-password")); m_ui->actionEntryTotpQRCode->setIcon(icons()->icon("qrcode")); m_ui->actionEntrySetupTotp->setIcon(icons()->icon("totp-edit")); + m_ui->actionEntryAddToAgent->setIcon(icons()->icon("utilities-terminal")); + m_ui->actionEntryRemoveFromAgent->setIcon(icons()->icon("utilities-terminal")); m_ui->menuTags->setIcon(icons()->icon("tag-multiple")); m_ui->actionEntryDownloadIcon->setIcon(icons()->icon("favicon-download")); m_ui->actionGroupSortAsc->setIcon(icons()->icon("sort-alphabetical-ascending")); @@ -695,6 +692,7 @@ MainWindow::MainWindow() statusBar()->addPermanentWidget(m_statusBarLabel); restoreConfigState(); + setMenuActionState(); } MainWindow::~MainWindow() @@ -885,6 +883,7 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode) bool inWelcomeWidget = (currentIndex == WelcomeScreen); bool inDatabaseTabWidgetOrWelcomeWidget = inDatabaseTabWidget || inWelcomeWidget; + m_ui->actionDatabaseClose->setEnabled(true); m_ui->actionDatabaseMerge->setEnabled(inDatabaseTabWidget); m_ui->actionDatabaseNew->setEnabled(inDatabaseTabWidgetOrWelcomeWidget); m_ui->actionDatabaseOpen->setEnabled(inDatabaseTabWidgetOrWelcomeWidget); @@ -1042,6 +1041,13 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode) // Only disable the action in the database menu so that the // menu remains active in the toolbar, if necessary m_ui->actionLockDatabase->setEnabled(false); + // Never show in these modes + m_ui->actionEntryMoveUp->setVisible(false); + m_ui->actionEntryMoveDown->setVisible(false); + m_ui->actionEntryRestore->setVisible(false); + m_ui->actionEntryAddToAgent->setVisible(false); + m_ui->actionEntryRemoveFromAgent->setVisible(false); + m_ui->actionGroupEmptyRecycleBin->setVisible(false); m_searchWidgetAction->setEnabled(false); break; @@ -1049,7 +1055,6 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode) default: Q_ASSERT(false); } - m_ui->actionDatabaseClose->setEnabled(true); } else { const auto entryActions = m_ui->menuEntries->actions(); for (auto action : entryActions) { @@ -1072,6 +1077,13 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode) m_ui->actionExportCsv->setEnabled(false); m_ui->actionExportHtml->setEnabled(false); m_ui->actionDatabaseMerge->setEnabled(false); + // Hide entry-specific actions + m_ui->actionEntryMoveUp->setVisible(false); + m_ui->actionEntryMoveDown->setVisible(false); + m_ui->actionEntryRestore->setVisible(false); + m_ui->actionEntryAddToAgent->setVisible(false); + m_ui->actionEntryRemoveFromAgent->setVisible(false); + m_ui->actionGroupEmptyRecycleBin->setVisible(false); m_searchWidgetAction->setEnabled(false); } @@ -1415,7 +1427,7 @@ void MainWindow::keyPressEvent(QKeyEvent* event) } else if (event->key() == Qt::Key_F2) { dbWidget->focusOnEntries(true); return; - } else if (event->key() == Qt::Key_F3) { + } else if (event->key() == Qt::Key_F3 || event->key() == Qt::Key_F6) { focusSearchWidget(); return; } else if (event->key() == Qt::Key_Escape && dbWidget->isSearchActive()) { diff --git a/src/gui/PasswordWidget.ui b/src/gui/PasswordWidget.ui index 4419ad79..34cae29e 100644 --- a/src/gui/PasswordWidget.ui +++ b/src/gui/PasswordWidget.ui @@ -27,7 +27,11 @@ 0 - + + + Toggle password visibilty using Control + H. Open the password generator using Control + G. + + diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index b2977d6f..af28bab6 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -168,7 +168,7 @@ void EditEntryWidget::setupMain() } }); - connect(m_mainUi->notesEnabled, SIGNAL(toggled(bool)), this, SLOT(toggleHideNotes(bool))); + connect(m_mainUi->revealNotesButton, &QToolButton::clicked, this, &EditEntryWidget::toggleHideNotes); m_mainUi->expirePresets->setMenu(createPresetsMenu()); connect(m_mainUi->expirePresets->menu(), SIGNAL(triggered(QAction*)), this, SLOT(useExpiryPreset(QAction*))); @@ -839,7 +839,7 @@ void EditEntryWidget::useExpiryPreset(QAction* action) void EditEntryWidget::toggleHideNotes(bool visible) { m_mainUi->notesEdit->setVisible(visible); - m_mainUi->notesHint->setVisible(!visible); + m_mainUi->revealNotesButton->setIcon(icons()->onOffIcon("password-show", visible)); } Entry* EditEntryWidget::currentEntry() const @@ -898,10 +898,10 @@ void EditEntryWidget::setForms(Entry* entry, bool restore) m_mainUi->tagsList->completion(m_db->tagList()); m_mainUi->expireCheck->setEnabled(!m_history); m_mainUi->expireDatePicker->setReadOnly(m_history); - m_mainUi->notesEnabled->setChecked(!config()->get(Config::Security_HideNotes).toBool()); + m_mainUi->revealNotesButton->setIcon(icons()->onOffIcon("password-show", false)); + m_mainUi->revealNotesButton->setVisible(config()->get(Config::Security_HideNotes).toBool()); m_mainUi->notesEdit->setReadOnly(m_history); m_mainUi->notesEdit->setVisible(!config()->get(Config::Security_HideNotes).toBool()); - m_mainUi->notesHint->setVisible(config()->get(Config::Security_HideNotes).toBool()); if (config()->get(Config::GUI_MonospaceNotes).toBool()) { m_mainUi->notesEdit->setFont(Font::fixedFont()); } else { diff --git a/src/gui/entry/EditEntryWidgetMain.ui b/src/gui/entry/EditEntryWidgetMain.ui index 19dbf31f..6fe6637e 100644 --- a/src/gui/entry/EditEntryWidgetMain.ui +++ b/src/gui/entry/EditEntryWidgetMain.ui @@ -6,7 +6,7 @@ 0 0 - 539 + 400 523 @@ -33,11 +33,11 @@ 0 0 - 539 + 400 523 - + 0 @@ -56,7 +56,37 @@ 8 - + + + + Title field + + + + + + + &Username: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + usernameComboBox + + + + + + + Qt::StrongFocus + + + Password field + + + + @@ -77,21 +107,34 @@ - - - - true - - - Toggle the checkbox to reveal the notes section. - - - Qt::AlignTop - - - + + + + &Title: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + titleEdit + + + + + + + &Password: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + passwordEdit + + + @@ -99,41 +142,34 @@ - - - - - - Toggle notes visible - - - Toggle notes visible - - - Notes: - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - + + + + Qt::StrongFocus + + + Tags list + + - - + + 8 + + + + Toggle expiration + + + Toggle expiration + + + + + + @@ -168,24 +204,17 @@ - - - - Password: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - URL: + UR&L: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + urlEdit + @@ -215,80 +244,98 @@ - - - - Title: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Title field - - - - - - - Username: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Qt::StrongFocus - - - Password field - - - - - - - 0 - + + - - - Toggle expiration - - - Toggle expiration - + - Expires: + &Notes: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + notesEdit + + + + 6 + + + + + Qt::Horizontal + + + + 5 + 20 + + + + + + + + Toggle notes visibility + + + Toggle notes visibility + + + + 14 + 14 + + + + true + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + - Tags: + T&ags: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + tagsList + - - - - Qt::StrongFocus + + + + &Expires: - - Tags list + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + expireCheck @@ -325,7 +372,7 @@ expireCheck expireDatePicker expirePresets - notesEnabled + revealNotesButton notesEdit