| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 1d7ef5d commit fe1189e
20 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -180,6 +180,8 @@ Files: share/icons/application/scalable/categories/preferences-other.svg | |||
| 180 | 180 | share/icons/application/scalable/actions/favicon-download.svg | |
| 181 | 181 | share/icons/application/scalable/actions/document-open.svg | |
| 182 | 182 | share/icons/application/scalable/actions/document-save-as.svg | |
| 183 | + share/icons/application/scalable/actions/refresh.svg | ||
| 184 | + share/icons/application/scalable/actions/clipboard-text.svg | ||
| 183 | 185 | Copyright: 2019 Austin Andrews <http://templarian.com/> | |
| 184 | 186 | License: SIL OPEN FONT LICENSE Version 1.1 | |
| 185 | 187 | Comment: Taken from Material Design icon set (https://github.com/templarian/MaterialDesign/) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -56,9 +56,6 @@ DatabaseOpenWidget::DatabaseOpenWidget(QWidget* parent) | |||
| 56 | 56 | ||
| 57 | 57 | m_ui->comboKeyFile->lineEdit()->addAction(m_ui->keyFileClearIcon, QLineEdit::TrailingPosition); | |
| 58 | 58 | ||
| 59 | - m_ui->buttonTogglePassword->setIcon(filePath()->onOffIcon("actions", "password-show")); | ||
| 60 | - connect(m_ui->buttonTogglePassword, SIGNAL(toggled(bool)), m_ui->editPassword, SLOT(setShowPassword(bool))); | ||
| 61 | - connect(m_ui->buttonTogglePassword, SIGNAL(toggled(bool)), m_ui->editPassword, SLOT(setFocus())); | ||
| 62 | 59 | connect(m_ui->buttonBrowseFile, SIGNAL(clicked()), SLOT(browseKeyFile())); | |
| 63 | 60 | ||
| 64 | 61 | connect(m_ui->buttonBox, SIGNAL(accepted()), SLOT(openDatabase())); | |
@@ -166,10 +163,10 @@ void DatabaseOpenWidget::clearForms() | |||
| 166 | 163 | { | |
| 167 | 164 | if (!m_isOpeningDatabase) { | |
| 168 | 165 | m_ui->editPassword->setText(""); | |
| 166 | + m_ui->editPassword->setShowPassword(false); | ||
| 169 | 167 | m_ui->comboKeyFile->clear(); | |
| 170 | 168 | m_ui->comboKeyFile->setEditText(""); | |
| 171 | 169 | m_ui->checkTouchID->setChecked(false); | |
| 172 | - m_ui->buttonTogglePassword->setChecked(false); | ||
| 173 | 170 | m_db.reset(); | |
| 174 | 171 | } | |
| 175 | 172 | } | |
@@ -195,7 +192,6 @@ void DatabaseOpenWidget::openDatabase() | |||
| 195 | 192 | } | |
| 196 | 193 | ||
| 197 | 194 | m_ui->editPassword->setShowPassword(false); | |
| 198 | - m_ui->buttonTogglePassword->setChecked(false); | ||
| 199 | 195 | QCoreApplication::processEvents(); | |
| 200 | 196 | ||
| 201 | 197 | m_isOpeningDatabase = true; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,6 +2,14 @@ | |||
| 2 | 2 | <ui version="4.0"> | |
| 3 | 3 | <class>DatabaseOpenWidget</class> | |
| 4 | 4 | <widget class="QWidget" name="DatabaseOpenWidget"> | |
| 5 | + <property name="geometry"> | ||
| 6 | + <rect> | ||
| 7 | + <x>0</x> | ||
| 8 | + <y>0</y> | ||
| 9 | + <width>580</width> | ||
| 10 | + <height>410</height> | ||
| 11 | + </rect> | ||
| 12 | + </property> | ||
| 5 | 13 | <property name="accessibleName"> | |
| 6 | 14 | <string>Unlock KeePassXC Database</string> | |
| 7 | 15 | </property> | |
@@ -157,31 +165,14 @@ | |||
| 157 | 165 | </widget> | |
| 158 | 166 | </item> | |
| 159 | 167 | <item> | |
| 160 | - <layout class="QHBoxLayout" name="passwordLayout"> | ||
| 161 | - <item> | ||
| 162 | - <widget class="PasswordEdit" name="editPassword"> | ||
| 163 | - <property name="accessibleName"> | ||
| 164 | - <string>Password field</string> | ||
| 165 | - </property> | ||
| 166 | - <property name="echoMode"> | ||
| 167 | - <enum>QLineEdit::Password</enum> | ||
| 168 | - </property> | ||
| 169 | - </widget> | ||
| 170 | - </item> | ||
| 171 | - <item> | ||
| 172 | - <widget class="QToolButton" name="buttonTogglePassword"> | ||
| 173 | - <property name="toolTip"> | ||
| 174 | - <string>Toggle password visibility</string> | ||
| 175 | - </property> | ||
| 176 | - <property name="accessibleName"> | ||
| 177 | - <string>Toggle password visibility</string> | ||
| 178 | - </property> | ||
| 179 | - <property name="checkable"> | ||
| 180 | - <bool>true</bool> | ||
| 181 | - </property> | ||
| 182 | - </widget> | ||
| 183 | - </item> | ||
| 184 | - </layout> | ||
| 168 | + <widget class="PasswordEdit" name="editPassword"> | ||
| 169 | + <property name="accessibleName"> | ||
| 170 | + <string>Password field</string> | ||
| 171 | + </property> | ||
| 172 | + <property name="echoMode"> | ||
| 173 | + <enum>QLineEdit::Password</enum> | ||
| 174 | + </property> | ||
| 175 | + </widget> | ||
| 185 | 176 | </item> | |
| 186 | 177 | <item> | |
| 187 | 178 | <spacer name="verticalSpacer_4"> | |
@@ -612,8 +603,6 @@ | |||
| 612 | 603 | </customwidget> | |
| 613 | 604 | </customwidgets> | |
| 614 | 605 | <tabstops> | |
| 615 | - <tabstop>editPassword</tabstop> | ||
| 616 | - <tabstop>buttonTogglePassword</tabstop> | ||
| 617 | 606 | <tabstop>comboKeyFile</tabstop> | |
| 618 | 607 | <tabstop>buttonBrowseFile</tabstop> | |
| 619 | 608 | <tabstop>hardwareKeyLabelHelp</tabstop> | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -451,7 +451,7 @@ MainWindow::MainWindow() | |||
| 451 | 451 | ||
| 452 | 452 | connect(m_ui->actionSettings, SIGNAL(toggled(bool)), SLOT(switchToSettings(bool))); | |
| 453 | 453 | connect(m_ui->actionPasswordGenerator, SIGNAL(toggled(bool)), SLOT(switchToPasswordGen(bool))); | |
| 454 | - connect(m_ui->passwordGeneratorWidget, SIGNAL(dialogTerminated()), SLOT(closePasswordGen())); | ||
| 454 | + connect(m_ui->passwordGeneratorWidget, SIGNAL(closePasswordGenerator()), SLOT(closePasswordGen())); | ||
| 455 | 455 | ||
| 456 | 456 | connect(m_ui->welcomeWidget, SIGNAL(newDatabase()), SLOT(switchToNewDatabase())); | |
| 457 | 457 | connect(m_ui->welcomeWidget, SIGNAL(openDatabase()), SLOT(switchToOpenDatabase())); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -186,13 +186,35 @@ | |||
| 186 | 186 | </widget> | |
| 187 | 187 | <widget class="QWidget" name="pagePasswordGenerator"> | |
| 188 | 188 | <layout class="QVBoxLayout" name="verticalLayout_6"> | |
| 189 | + <property name="leftMargin"> | ||
| 190 | + <number>60</number> | ||
| 191 | + </property> | ||
| 192 | + <property name="topMargin"> | ||
| 193 | + <number>30</number> | ||
| 194 | + </property> | ||
| 195 | + <property name="rightMargin"> | ||
| 196 | + <number>60</number> | ||
| 197 | + </property> | ||
| 189 | 198 | <item> | |
| 190 | 199 | <widget class="PasswordGeneratorWidget" name="passwordGeneratorWidget" native="true"> | |
| 191 | 200 | <property name="focusPolicy"> | |
| 192 | 201 | <enum>Qt::TabFocus</enum> | |
| 193 | 202 | </property> | |
| 194 | 203 | </widget> | |
| 195 | 204 | </item> | |
| 205 | + <item> | ||
| 206 | + <spacer name="verticalSpacer"> | ||
| 207 | + <property name="orientation"> | ||
| 208 | + <enum>Qt::Vertical</enum> | ||
| 209 | + </property> | ||
| 210 | + <property name="sizeHint" stdset="0"> | ||
| 211 | + <size> | ||
| 212 | + <width>20</width> | ||
| 213 | + <height>40</height> | ||
| 214 | + </size> | ||
| 215 | + </property> | ||
| 216 | + </spacer> | ||
| 217 | + </item> | ||
| 196 | 218 | </layout> | |
| 197 | 219 | </widget> | |
| 198 | 220 | </widget> | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -20,14 +20,24 @@ | |||
| 20 | 20 | ||
| 21 | 21 | #include "core/Config.h" | |
| 22 | 22 | #include "core/FilePath.h" | |
| 23 | + #include "gui/Application.h" | ||
| 23 | 24 | #include "gui/Font.h" | |
| 25 | + #include "gui/PasswordGeneratorWidget.h" | ||
| 24 | 26 | ||
| 25 | - const QColor PasswordEdit::CorrectSoFarColor = QColor(255, 205, 15); | ||
| 26 | - const QColor PasswordEdit::ErrorColor = QColor(255, 125, 125); | ||
| 27 | + #include <QDialog> | ||
| 28 | + #include <QVBoxLayout> | ||
| 29 | + | ||
| 30 | + namespace | ||
| 31 | + { | ||
| 32 | + const QColor CorrectSoFarColor(255, 205, 15); | ||
| 33 | + const QColor CorrectSoFarColorDark(115, 104, 46); | ||
| 34 | + const QColor ErrorColor(255, 125, 125); | ||
| 35 | + const QColor ErrorColorDark(128, 45, 45); | ||
| 36 | + | ||
| 37 | + } // namespace | ||
| 27 | 38 | ||
| 28 | 39 | PasswordEdit::PasswordEdit(QWidget* parent) | |
| 29 | 40 | : QLineEdit(parent) | |
| 30 | - , m_basePasswordEdit(nullptr) | ||
| 31 | 41 | { | |
| 32 | 42 | const QIcon errorIcon = filePath()->icon("status", "dialog-error"); | |
| 33 | 43 | m_errorAction = addAction(errorIcon, QLineEdit::TrailingPosition); | |
@@ -40,70 +50,122 @@ PasswordEdit::PasswordEdit(QWidget* parent) | |||
| 40 | 50 | m_correctAction->setToolTip(tr("Passwords match so far")); | |
| 41 | 51 | ||
| 42 | 52 | setEchoMode(QLineEdit::Password); | |
| 43 | - updateStylesheet(); | ||
| 44 | 53 | ||
| 45 | 54 | // use a monospace font for the password field | |
| 46 | 55 | QFont passwordFont = Font::fixedFont(); | |
| 47 | 56 | passwordFont.setLetterSpacing(QFont::PercentageSpacing, 110); | |
| 48 | 57 | setFont(passwordFont); | |
| 58 | + | ||
| 59 | + m_toggleVisibleAction = new QAction( | ||
| 60 | + filePath()->icon("actions", "password-show-off"), | ||
| 61 | + tr("Toggle Password (%1)").arg(QKeySequence(Qt::CTRL + Qt::Key_H).toString(QKeySequence::NativeText)), | ||
| 62 | + nullptr); | ||
| 63 | + m_toggleVisibleAction->setCheckable(true); | ||
| 64 | + m_toggleVisibleAction->setShortcut(Qt::CTRL + Qt::Key_H); | ||
| 65 | + m_toggleVisibleAction->setShortcutContext(Qt::WidgetShortcut); | ||
| 66 | + addAction(m_toggleVisibleAction, QLineEdit::TrailingPosition); | ||
| 67 | + connect(m_toggleVisibleAction, &QAction::triggered, this, &PasswordEdit::setShowPassword); | ||
| 68 | + | ||
| 69 | + m_passwordGeneratorAction = new QAction( | ||
| 70 | + filePath()->icon("actions", "password-generator"), | ||
| 71 | + tr("Generate Password (%1)").arg(QKeySequence(Qt::CTRL + Qt::Key_G).toString(QKeySequence::NativeText)), | ||
| 72 | + nullptr); | ||
| 73 | + m_passwordGeneratorAction->setShortcut(Qt::CTRL + Qt::Key_G); | ||
| 74 | + m_passwordGeneratorAction->setShortcutContext(Qt::WidgetShortcut); | ||
| 75 | + addAction(m_passwordGeneratorAction, QLineEdit::TrailingPosition); | ||
| 76 | + m_passwordGeneratorAction->setVisible(false); | ||
| 49 | 77 | } | |
| 50 | 78 | ||
| 51 | - void PasswordEdit::enableVerifyMode(PasswordEdit* basePasswordEdit) | ||
| 79 | + void PasswordEdit::setRepeatPartner(PasswordEdit* repeatEdit) | ||
| 52 | 80 | { | |
| 53 | - m_basePasswordEdit = basePasswordEdit; | ||
| 81 | + m_repeatPasswordEdit = repeatEdit; | ||
| 82 | + m_repeatPasswordEdit->setParentPasswordEdit(this); | ||
| 54 | 83 | ||
| 55 | - updateStylesheet(); | ||
| 84 | + connect(this, SIGNAL(textChanged(QString)), m_repeatPasswordEdit, SLOT(autocompletePassword(QString))); | ||
| 85 | + connect(this, SIGNAL(textChanged(QString)), m_repeatPasswordEdit, SLOT(updateRepeatStatus())); | ||
| 86 | + connect(m_repeatPasswordEdit, SIGNAL(textChanged(QString)), m_repeatPasswordEdit, SLOT(updateRepeatStatus())); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + void PasswordEdit::setParentPasswordEdit(PasswordEdit* parent) | ||
| 90 | + { | ||
| 91 | + m_parentPasswordEdit = parent; | ||
| 92 | + // Hide actions | ||
| 93 | + m_toggleVisibleAction->setVisible(false); | ||
| 94 | + m_passwordGeneratorAction->setVisible(false); | ||
| 95 | + } | ||
| 56 | 96 | ||
| 57 | - connect(m_basePasswordEdit, SIGNAL(textChanged(QString)), SLOT(autocompletePassword(QString))); | ||
| 58 | - connect(m_basePasswordEdit, SIGNAL(textChanged(QString)), SLOT(updateStylesheet())); | ||
| 59 | - connect(this, SIGNAL(textChanged(QString)), SLOT(updateStylesheet())); | ||
| 97 | + void PasswordEdit::enablePasswordGenerator(bool signalOnly) | ||
| 98 | + { | ||
| 99 | + disconnect(m_passwordGeneratorAction); | ||
| 100 | + m_passwordGeneratorAction->setVisible(true); | ||
| 60 | 101 | ||
| 61 | - connect(m_basePasswordEdit, SIGNAL(showPasswordChanged(bool)), SLOT(setShowPassword(bool))); | ||
| 102 | + if (signalOnly) { | ||
| 103 | + connect(m_passwordGeneratorAction, &QAction::triggered, this, &PasswordEdit::togglePasswordGenerator); | ||
| 104 | + } else { | ||
| 105 | + connect(m_passwordGeneratorAction, &QAction::triggered, this, &PasswordEdit::popupPasswordGenerator); | ||
| 106 | + } | ||
| 62 | 107 | } | |
| 63 | 108 | ||
| 64 | 109 | void PasswordEdit::setShowPassword(bool show) | |
| 65 | 110 | { | |
| 66 | 111 | setEchoMode(show ? QLineEdit::Normal : QLineEdit::Password); | |
| 67 | - // if I have a parent, I'm the child | ||
| 68 | - if (m_basePasswordEdit) { | ||
| 112 | + m_toggleVisibleAction->setIcon(filePath()->icon("actions", show ? "password-show-on" : "password-show-off")); | ||
| 113 | + m_toggleVisibleAction->setChecked(show); | ||
| 114 | + | ||
| 115 | + if (m_repeatPasswordEdit) { | ||
| 116 | + m_repeatPasswordEdit->setEchoMode(show ? QLineEdit::Normal : QLineEdit::Password); | ||
| 69 | 117 | if (config()->get("security/passwordsrepeat").toBool()) { | |
| 70 | - setEnabled(!show); | ||
| 71 | - setReadOnly(show); | ||
| 72 | - setText(m_basePasswordEdit->text()); | ||
| 118 | + m_repeatPasswordEdit->setEnabled(!show); | ||
| 119 | + m_repeatPasswordEdit->setText(text()); | ||
| 73 | 120 | } else { | |
| 74 | - // This fix a bug when the QLineEdit is disabled while switching config | ||
| 75 | - if (!isEnabled()) { | ||
| 76 | - setEnabled(true); | ||
| 77 | - setReadOnly(false); | ||
| 78 | - } | ||
| 121 | + m_repeatPasswordEdit->setEnabled(true); | ||
| 79 | 122 | } | |
| 80 | 123 | } | |
| 81 | - updateStylesheet(); | ||
| 82 | - emit showPasswordChanged(show); | ||
| 83 | 124 | } | |
| 84 | 125 | ||
| 85 | 126 | bool PasswordEdit::isPasswordVisible() const | |
| 86 | 127 | { | |
| 87 | - return isEnabled(); | ||
| 128 | + return echoMode() == QLineEdit::Normal; | ||
| 88 | 129 | } | |
| 89 | 130 | ||
| 90 | - bool PasswordEdit::passwordsEqual() const | ||
| 131 | + void PasswordEdit::popupPasswordGenerator() | ||
| 91 | 132 | { | |
| 92 | - return text() == m_basePasswordEdit->text(); | ||
| 133 | + auto pwGenerator = new PasswordGeneratorWidget(); | ||
| 134 | + QDialog pwDialog(this); | ||
| 135 | + pwDialog.setWindowTitle(tr("Generate Password")); | ||
| 136 | + auto layout = new QVBoxLayout(); | ||
| 137 | + pwDialog.setLayout(layout); | ||
| 138 | + layout->addWidget(pwGenerator); | ||
| 139 | + | ||
| 140 | + pwGenerator->setStandaloneMode(false); | ||
| 141 | + pwGenerator->setPasswordVisible(isPasswordVisible()); | ||
| 142 | + | ||
| 143 | + connect(pwGenerator, SIGNAL(closePasswordGenerator()), &pwDialog, SLOT(close())); | ||
| 144 | + connect(pwGenerator, SIGNAL(appliedPassword(QString)), SLOT(setText(QString))); | ||
| 145 | + if (m_repeatPasswordEdit) { | ||
| 146 | + connect(pwGenerator, SIGNAL(appliedPassword(QString)), m_repeatPasswordEdit, SLOT(setText(QString))); | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + pwDialog.exec(); | ||
| 93 | 150 | } | |
| 94 | 151 | ||
| 95 | - void PasswordEdit::updateStylesheet() | ||
| 152 | + void PasswordEdit::updateRepeatStatus() | ||
| 96 | 153 | { | |
| 97 | - const QString stylesheetTemplate("QLineEdit { background: %1; }"); | ||
| 154 | + static const auto stylesheetTemplate = QStringLiteral("QLineEdit { background: %1; }"); | ||
| 155 | + if (!m_parentPasswordEdit) { | ||
| 156 | + return; | ||
| 157 | + } | ||
| 98 | 158 | ||
| 99 | - if (m_basePasswordEdit && !passwordsEqual()) { | ||
| 100 | - bool isCorrect = true; | ||
| 101 | - if (m_basePasswordEdit->text().startsWith(text())) { | ||
| 102 | - setStyleSheet(stylesheetTemplate.arg(CorrectSoFarColor.name())); | ||
| 103 | - } else { | ||
| 104 | - setStyleSheet(stylesheetTemplate.arg(ErrorColor.name())); | ||
| 105 | - isCorrect = false; | ||
| 159 | + const auto otherPassword = m_parentPasswordEdit->text(); | ||
| 160 | + const auto password = text(); | ||
| 161 | + if (otherPassword != password) { | ||
| 162 | + bool isCorrect = false; | ||
| 163 | + QColor color = kpxcApp->isDarkTheme() ? ErrorColorDark : ErrorColor; | ||
| 164 | + if (!password.isEmpty() && otherPassword.startsWith(password)) { | ||
| 165 | + color = kpxcApp->isDarkTheme() ? CorrectSoFarColorDark : CorrectSoFarColor; | ||
| 166 | + isCorrect = true; | ||
| 106 | 167 | } | |
| 168 | + setStyleSheet(stylesheetTemplate.arg(color.name())); | ||
| 107 | 169 | m_correctAction->setVisible(isCorrect); | |
| 108 | 170 | m_errorAction->setVisible(!isCorrect); | |
| 109 | 171 | } else { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -28,29 +28,32 @@ class PasswordEdit : public QLineEdit | |||
| 28 | 28 | Q_OBJECT | |
| 29 | 29 | ||
| 30 | 30 | public: | |
| 31 | - static const QColor CorrectSoFarColor; | ||
| 32 | - static const QColor ErrorColor; | ||
| 33 | - | ||
| 34 | 31 | explicit PasswordEdit(QWidget* parent = nullptr); | |
| 35 | - void enableVerifyMode(PasswordEdit* baseEdit); | ||
| 32 | + void enablePasswordGenerator(bool signalOnly = false); | ||
| 33 | + void setRepeatPartner(PasswordEdit* repeatEdit); | ||
| 36 | 34 | bool isPasswordVisible() const; | |
| 37 | 35 | ||
| 38 | 36 | public slots: | |
| 39 | 37 | void setShowPassword(bool show); | |
| 38 | + void updateRepeatStatus(); | ||
| 40 | 39 | ||
| 41 | 40 | signals: | |
| 42 | - void showPasswordChanged(bool show); | ||
| 41 | + void togglePasswordGenerator(); | ||
| 43 | 42 | ||
| 44 | 43 | private slots: | |
| 45 | - void updateStylesheet(); | ||
| 46 | 44 | void autocompletePassword(const QString& password); | |
| 45 | + void popupPasswordGenerator(); | ||
| 46 | + void setParentPasswordEdit(PasswordEdit* parent); | ||
| 47 | 47 | ||
| 48 | 48 | private: | |
| 49 | - bool passwordsEqual() const; | ||
| 50 | - | ||
| 51 | 49 | QPointer<QAction> m_errorAction; | |
| 52 | 50 | QPointer<QAction> m_correctAction; | |
| 53 | - QPointer<PasswordEdit> m_basePasswordEdit; | ||
| 51 | + QPointer<QAction> m_toggleVisibleAction; | ||
| 52 | + QPointer<QAction> m_passwordGeneratorAction; | ||
| 53 | + QPointer<PasswordEdit> m_repeatPasswordEdit; | ||
| 54 | + QPointer<PasswordEdit> m_parentPasswordEdit; | ||
| 55 | + bool m_sendGeneratorSignal = false; | ||
| 56 | + bool m_isRepeatPartner = false; | ||
| 54 | 57 | }; | |
| 55 | 58 | ||
| 56 | 59 | #endif // KEEPASSX_PASSWORDEDIT_H | |
| Back | FazBrowse Home | New Git URL |
0 commit comments