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.
This commit is contained in:
Jonathan White 2019-08-30 20:18:41 -04:00 committed by GitHub
parent 58d357e9ce
commit 3b330ee2d1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
43 changed files with 1073 additions and 202 deletions

View file

@ -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<QWidget*>(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