diff --git a/share/translations/keepassxc_en.ts b/share/translations/keepassxc_en.ts index ac5d43f56..7c4521579 100644 --- a/share/translations/keepassxc_en.ts +++ b/share/translations/keepassxc_en.ts @@ -503,6 +503,10 @@ recent files + + Show passwords in color + + ApplicationSettingsWidgetSecurity diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 8808abd75..44896bc1c 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -105,6 +105,7 @@ static const QHash configStrings = { {Config::GUI_HideUsernames, {QS("GUI/HideUsernames"), Roaming, false}}, {Config::GUI_HidePasswords, {QS("GUI/HidePasswords"), Roaming, true}}, {Config::GUI_AdvancedSettings, {QS("GUI/AdvancedSettings"), Roaming, false}}, + {Config::GUI_ColorPasswords, {QS("GUI/ColorPasswords"), Roaming, false}}, {Config::GUI_MonospaceNotes, {QS("GUI/MonospaceNotes"), Roaming, false}}, {Config::GUI_ApplicationTheme, {QS("GUI/ApplicationTheme"), Roaming, QS("auto")}}, {Config::GUI_CompactMode, {QS("GUI/CompactMode"), Roaming, false}}, diff --git a/src/core/Config.h b/src/core/Config.h index a48cb4c59..e0b42b35c 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -86,6 +86,7 @@ public: GUI_HideUsernames, GUI_HidePasswords, GUI_AdvancedSettings, + GUI_ColorPasswords, GUI_MonospaceNotes, GUI_ApplicationTheme, GUI_CompactMode, diff --git a/src/gui/Application.cpp b/src/gui/Application.cpp index cfe29cf96..8e8f4ca5b 100644 --- a/src/gui/Application.cpp +++ b/src/gui/Application.cpp @@ -183,6 +183,7 @@ void Application::applyTheme() auto* s = new LightStyle; setPalette(s->standardPalette()); setStyle(s); + m_darkTheme = false; } else if (appTheme == "dark") { auto* s = new DarkStyle; setPalette(s->standardPalette()); @@ -191,7 +192,9 @@ void Application::applyTheme() } else { // Classic mode, don't check for dark theme on Windows // because Qt 5.x does not support it -#ifndef Q_OS_WIN +#if defined(Q_OS_WIN) + m_darkTheme = false; +#else m_darkTheme = osUtils->isDarkMode(); #endif QFile stylesheetFile(":/styles/base/classicstyle.qss"); diff --git a/src/gui/ApplicationSettingsWidget.cpp b/src/gui/ApplicationSettingsWidget.cpp index be925c770..7972e8e0c 100644 --- a/src/gui/ApplicationSettingsWidget.cpp +++ b/src/gui/ApplicationSettingsWidget.cpp @@ -239,6 +239,7 @@ void ApplicationSettingsWidget::loadSettings() m_generalUi->toolbarMovableCheckBox->setChecked(config()->get(Config::GUI_MovableToolbar).toBool()); m_generalUi->monospaceNotesCheckBox->setChecked(config()->get(Config::GUI_MonospaceNotes).toBool()); + m_generalUi->colorPasswordsCheckBox->setChecked(config()->get(Config::GUI_ColorPasswords).toBool()); m_generalUi->toolButtonStyleComboBox->clear(); m_generalUi->toolButtonStyleComboBox->addItem(tr("Icon only"), Qt::ToolButtonIconOnly); @@ -383,6 +384,7 @@ void ApplicationSettingsWidget::saveSettings() config()->set(Config::GUI_MovableToolbar, m_generalUi->toolbarMovableCheckBox->isChecked()); config()->set(Config::GUI_MonospaceNotes, m_generalUi->monospaceNotesCheckBox->isChecked()); + config()->set(Config::GUI_ColorPasswords, m_generalUi->colorPasswordsCheckBox->isChecked()); config()->set(Config::GUI_ToolButtonStyle, m_generalUi->toolButtonStyleComboBox->currentData().toString()); diff --git a/src/gui/ApplicationSettingsWidgetGeneral.ui b/src/gui/ApplicationSettingsWidgetGeneral.ui index 0a67c57b7..53bf9f724 100644 --- a/src/gui/ApplicationSettingsWidgetGeneral.ui +++ b/src/gui/ApplicationSettingsWidgetGeneral.ui @@ -766,6 +766,13 @@ + + + + Show passwords in color + + + diff --git a/src/gui/EntryPreviewWidget.cpp b/src/gui/EntryPreviewWidget.cpp index 304fc733f..0e2e18ee9 100644 --- a/src/gui/EntryPreviewWidget.cpp +++ b/src/gui/EntryPreviewWidget.cpp @@ -19,6 +19,8 @@ #include "EntryPreviewWidget.h" #include "ui_EntryPreviewWidget.h" +#include "Application.h" +#include "core/Config.h" #include "gui/Clipboard.h" #include "gui/Font.h" #include "gui/Icons.h" @@ -232,14 +234,31 @@ void EntryPreviewWidget::setPasswordVisible(bool state) { const QString password = m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->password()); if (state) { - m_ui->entryPasswordLabel->setText(password); - m_ui->entryPasswordLabel->setCursorPosition(0); - m_ui->entryPasswordLabel->setFont(Font::fixedFont()); + if (config()->get(Config::GUI_ColorPasswords).toBool()) { + // Show the password in color + // clang-format off + QString html; + const auto dark = kpxcApp->isDarkTheme(); + for (const auto c : password) { + const auto color = c.isDigit() ? (dark ? "lightblue" : "blue") + : c.isUpper() ? (dark ? "lightgreen" : "darkgreen") + : c.isLower() ? (dark ? "yellow" : "red") + : (dark ? "white" : "black"); + html += "" + QString(c).toHtmlEscaped() + ""; + } + // clang-format on + m_ui->entryPasswordLabel->setHtml(html); + } else { + // No color + m_ui->entryPasswordLabel->setPlainText(password.toHtmlEscaped()); + } } else if (password.isEmpty() && !config()->get(Config::Security_PasswordEmptyPlaceholder).toBool()) { - m_ui->entryPasswordLabel->setText(""); + m_ui->entryPasswordLabel->setPlainText(""); } else { - m_ui->entryPasswordLabel->setText(QString("\u25cf").repeated(6)); + m_ui->entryPasswordLabel->setPlainText(QString("\u25cf").repeated(6)); } + + m_ui->entryPasswordLabel->setFont(Font::fixedFont()); m_ui->togglePasswordButton->setIcon(icons()->onOffIcon("password-show", state)); } @@ -280,7 +299,7 @@ void EntryPreviewWidget::updateEntryGeneralTab() // Hide password setPasswordVisible(false); // Show the password toggle button if there are dots in the label - m_ui->togglePasswordButton->setVisible(!m_ui->entryPasswordLabel->text().isEmpty()); + m_ui->togglePasswordButton->setVisible(!m_currentEntry->password().isEmpty()); m_ui->togglePasswordButton->setChecked(false); } else { // Show password diff --git a/src/gui/EntryPreviewWidget.ui b/src/gui/EntryPreviewWidget.ui index df7196a27..89d072059 100644 --- a/src/gui/EntryPreviewWidget.ui +++ b/src/gui/EntryPreviewWidget.ui @@ -315,24 +315,42 @@ - + 150 0 + + + 16777215 + 30 + + Qt::ClickFocus - - password + + QFrame::NoFrame - + + QFrame::Plain + + + 0 + + + Qt::ScrollBarAlwaysOff + + + true + + false - - true + + QTextEdit::NoWrap true