diff --git a/src/passworddialog.cpp b/src/passworddialog.cpp index e211b74..2a599df 100644 --- a/src/passworddialog.cpp +++ b/src/passworddialog.cpp @@ -1,242 +1,254 @@ /* SPDX-FileCopyrightText: 2014-2023 Anne Jan Brouwer SPDX-FileCopyrightText: 2018 Lukas Vogel SPDX-FileCopyrightText: 2018 Claudio Maradonna SPDX-FileCopyrightText: 2023 g10 Code GmbH SPDX-FileContributor: Sune Stolborg Vuorela SPDX-License-Identifier: GPL-3.0-or-later */ #include "passworddialog.h" #include "filecontent.h" #include "pass.h" #include "passwordconfiguration.h" #include "settings.h" #include "ui_passworddialog.h" #include #include #include /** * @brief PasswordDialog::PasswordDialog basic constructor. * @param passConfig configuration constant * @param parent */ PasswordDialog::PasswordDialog(Pass &pass, const PasswordConfiguration &passConfig, QWidget *parent) : QDialog(parent) , ui(std::make_unique()) , m_pass(pass) , m_passConfig(passConfig) { m_templating = false; m_allFields = false; m_isNew = false; ui->setupUi(this); setLength(m_passConfig.length); setPasswordCharTemplate(m_passConfig.selected); connect(&m_pass, &Pass::finishedShow, this, &PasswordDialog::setPass); + connect(ui->createPasswordOptionsButton, &QAbstractButton::toggled, this, &PasswordDialog::togglePasswordGenerationOption); + togglePasswordGenerationOption(false); } /** * @brief PasswordDialog::PasswordDialog complete constructor. * @param file * @param isNew * @param parent pointer */ PasswordDialog::PasswordDialog(Pass &pass, const QString &file, const bool &isNew, QWidget *parent) : QDialog(parent) , ui(std::make_unique()) , m_pass(pass) , m_file(file) , m_isNew(isNew) { if (!isNew) m_pass.Show(m_file); ui->setupUi(this); setWindowTitle(this->windowTitle() + QStringLiteral(" ") + QFileInfo(m_file).baseName()); m_passConfig = Settings::getPasswordConfiguration(); setTemplate(Settings::getPassTemplate(), Settings::isUseTemplate()); templateAll(Settings::isTemplateAllFields()); setLength(m_passConfig.length); setPasswordCharTemplate(m_passConfig.selected); connect(&m_pass, &Pass::finishedShow, this, &PasswordDialog::setPass); connect(&m_pass, &Pass::decryptionError, this, &PasswordDialog::close); connect(this, &PasswordDialog::accepted, this, &PasswordDialog::dialogAccepted); connect(this, &PasswordDialog::rejected, this, &PasswordDialog::dialogCancelled); connect(ui->createPasswordButton, &QAbstractButton::clicked, this, &PasswordDialog::createPassword); - connect(ui->checkBoxShow, &QCheckBox::stateChanged, this, &PasswordDialog::showPasswordChanged); + connect(ui->createPasswordOptionsButton, &QAbstractButton::toggled, this, &PasswordDialog::togglePasswordGenerationOption); + togglePasswordGenerationOption(false); } /** * @brief Pass{}{}wordDialog::~PasswordDialog basic destructor. */ PasswordDialog::~PasswordDialog() = default; -/** - * @brief PasswordDialog::on_checkBoxShow_stateChanged hide or show passwords. - * @param arg1 - */ -void PasswordDialog::showPasswordChanged(int arg1) -{ - if (arg1) - ui->lineEditPassword->setEchoMode(QLineEdit::Normal); - else - ui->lineEditPassword->setEchoMode(QLineEdit::Password); -} - /** * @brief PasswordDialog::on_createPasswordButton_clicked generate a random * passwords. * @todo refactor when process is untangled from MainWindow class. */ void PasswordDialog::createPassword() { - ui->widget->setEnabled(false); + setEnabled(false); QString newPass = m_pass.Generate_b(static_cast(ui->spinBox_pwdLength->value()), m_passConfig.Characters[static_cast(ui->passwordTemplateSwitch->currentIndex())]); if (newPass.length() > 0) - ui->lineEditPassword->setText(newPass); - ui->widget->setEnabled(true); + ui->lineEditPassword->setPassword(newPass); + setEnabled(true); } /** * @brief PasswordDialog::on_accepted handle Ok click for QDialog */ void PasswordDialog::dialogAccepted() { QString newValue = getPassword(); if (newValue.isEmpty()) return; if (newValue.right(1) != QLatin1Char('\n')) newValue += QLatin1Char('\n'); m_pass.Insert(m_file, newValue); } /** * @brief PasswordDialog::on_rejected handle Cancel click for QDialog */ void PasswordDialog::dialogCancelled() { setPassword(QString()); } /** * @brief PasswordDialog::setPassword populate the (templated) fields. * @param password */ void PasswordDialog::setPassword(const QString& password) { FileContent fileContent = FileContent::parse(password, m_templating ? m_fields : QStringList(), m_allFields); - ui->lineEditPassword->setText(fileContent.getPassword()); + ui->lineEditPassword->setPassword(fileContent.getPassword()); - QWidget *previous = ui->checkBoxShow; + QWidget *previous = ui->createPasswordButton; // first set templated values NamedValues namedValues = fileContent.getNamedValues(); for (QLineEdit *line : std::as_const(templateLines)) { line->setText(namedValues.takeValue(line->objectName())); previous = line; } // show remaining values (if there are) otherLines.clear(); for (const NamedValue &nv : std::as_const(namedValues)) { auto *line = new QLineEdit(); line->setObjectName(nv.name); line->setText(nv.value); ui->formLayout->addRow(new QLabel(nv.name), line); setTabOrder(previous, line); otherLines.append(line); previous = line; } ui->plainTextEdit->insertPlainText(fileContent.getRemainingData()); } /** * @brief PasswordDialog::getPassword join the (templated) fields to a QString * for writing back. * @return collappsed password. */ QString PasswordDialog::getPassword() { - QString passFile = ui->lineEditPassword->text() + QLatin1Char('\n'); + QString passFile = ui->lineEditPassword->password() + QLatin1Char('\n'); QList allLines(templateLines); allLines.append(otherLines); for (QLineEdit *line : allLines) { QString text = line->text(); if (text.isEmpty()) continue; passFile += line->objectName() + QStringLiteral(": ") + text + QLatin1Char('\n'); } passFile += ui->plainTextEdit->toPlainText(); return passFile; } /** * @brief PasswordDialog::setTemplate set the template and create the fields. * @param rawFields */ void PasswordDialog::setTemplate(const QString& rawFields, bool useTemplate) { m_fields = rawFields.split(QLatin1Char('\n')); m_templating = useTemplate; templateLines.clear(); if (m_templating) { - QWidget *previous = ui->checkBoxShow; + QWidget *previous = ui->createPasswordButton; for (const QString &field : std::as_const(m_fields)) { if (field.isEmpty()) continue; auto *line = new QLineEdit(); line->setObjectName(field); - ui->formLayout->addRow(new QLabel(field), line); + ui->formLayout->addRow(new QLabel(i18nc("Field name", "%1:", field)), line); setTabOrder(previous, line); templateLines.append(line); previous = line; } } } /** * @brief PasswordDialog::templateAll basic setter for use in * PasswordDialog::setPassword templating all tokenisable lines. * @param templateAll */ void PasswordDialog::templateAll(bool templateAll) { m_allFields = templateAll; } /** * @brief PasswordDialog::setLength * PasswordDialog::setLength password length. * @param l */ void PasswordDialog::setLength(int l) { ui->spinBox_pwdLength->setValue(l); } /** * @brief PasswordDialog::setPasswordCharTemplate * PasswordDialog::setPasswordCharTemplate chose the template style. * @param t */ void PasswordDialog::setPasswordCharTemplate(int t) { ui->passwordTemplateSwitch->setCurrentIndex(t); } void PasswordDialog::setPass(const QString &output) { setPassword(output); // TODO(bezet): enable ui } + +void PasswordDialog::togglePasswordGenerationOption(bool checked) +{ + if (checked) { + ui->createPasswordOptionsButton->setIcon(QIcon::fromTheme(QStringLiteral("collapse-symbolic"))); + ui->createPasswordOptionsButton->setToolTip(i18nc("@info:tooltip", "Collapse password options")); + ui->createPasswordOptionsButton->setAccessibleName(i18nc("@info:tooltip", "Collapse password options")); + ui->label_characterset->setVisible(true); + ui->passwordTemplateSwitch->setVisible(true); + ui->label_length->setVisible(true); + ui->spinBox_pwdLength->setVisible(true); + } else { + ui->createPasswordOptionsButton->setIcon(QIcon::fromTheme(QStringLiteral("expand-symbolic"))); + ui->createPasswordOptionsButton->setToolTip(i18nc("@info:tooltip", "Toggle password options")); + ui->createPasswordOptionsButton->setAccessibleName(i18nc("@info:tooltip", "Toggle password options")); + ui->label_characterset->setVisible(false); + ui->passwordTemplateSwitch->setVisible(false); + ui->label_length->setVisible(false); + ui->spinBox_pwdLength->setVisible(false); + } +} diff --git a/src/passworddialog.h b/src/passworddialog.h index 71b5c1f..2b8644c 100644 --- a/src/passworddialog.h +++ b/src/passworddialog.h @@ -1,84 +1,84 @@ /* SPDX-FileCopyrightText: 2014-2023 Anne Jan Brouwer SPDX-FileCopyrightText: 2018 Lukas Vogel SPDX-FileCopyrightText: 2018 Claudio Maradonna SPDX-FileCopyrightText: 2023 g10 Code GmbH SPDX-FileContributor: Sune Stolborg Vuorela SPDX-License-Identifier: GPL-3.0-or-later */ #ifndef PASSWORDDIALOG_H_ #define PASSWORDDIALOG_H_ #include "passwordconfiguration.h" #include namespace Ui { class PasswordDialog; } class QLineEdit; class QWidget; class Pass; /*! \class PasswordDialog \brief PasswordDialog Handles the inserting and editing of passwords. Includes templated views. */ class PasswordDialog : public QDialog { Q_OBJECT public: explicit PasswordDialog(Pass &pass, const PasswordConfiguration &passConfig, QWidget *parent = nullptr); PasswordDialog(Pass &pass, const QString &file, const bool &isNew, QWidget *parent = nullptr); ~PasswordDialog(); /*! Sets content in the password field in the interface. \param password the password as a QString \sa getPassword */ void setPassword(const QString& password); /*! Returns the password as set in the password field in the interface. \return password as a QString \sa setPassword */ QString getPassword(); /*! Sets content in the template for the interface. \param rawFields is the template as a QString \param useTemplate whether the template is used */ void setTemplate(const QString& rawFields, bool useTemplate); void templateAll(bool templateAll); void setLength(int l); void setPasswordCharTemplate(int t); public Q_SLOTS: void setPass(const QString &output); private Q_SLOTS: - void showPasswordChanged(int arg1); void createPassword(); void dialogAccepted(); void dialogCancelled(); + void togglePasswordGenerationOption(bool checked); private: std::unique_ptr ui; Pass &m_pass; PasswordConfiguration m_passConfig; QStringList m_fields; QString m_file; bool m_templating; bool m_allFields; bool m_isNew; QList templateLines; QList otherLines; }; #endif // PASSWORDDIALOG_H_ diff --git a/src/passworddialog.ui b/src/passworddialog.ui index 589d94e..ad9f5d7 100644 --- a/src/passworddialog.ui +++ b/src/passworddialog.ui @@ -1,224 +1,211 @@ PasswordDialog 0 0 504 263 Password 6 6 6 6 - - - - 0 - 0 - + + + 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - QLineEdit::Password - - - Password - - - - - - - true - - - Generate - - - - - - - - - - - Show password - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Character Set: - - - - - - - - All Characters - - - - - Alphabetical - - - - - Alphanumerical - - - - - - - - - 0 - 0 - - - - Length: - - - - - - - 8 - - - 255 - - - - - - - - - QFormLayout::AllNonFixedFieldsGrow - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + 0 + + + 0 + + + 0 + + + + + Password: + + + lineEditPassword + + + + + + + + + KPassword::RevealMode::Always + + + + + + + Generate + + + + + + + true + + + + + + + + + + + + Character Set: + + + passwordTemplateSwitch + + + + + + + + 0 + 0 + + + + + All Characters - - - - - - - - - Qt::Horizontal + + + + Alphabetical - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + Alphanumerical - - - + + + + + + + Length: + + + spinBox_pwdLength + + + + + + + + 0 + 0 + + + + 8 + + + 255 + + + + + + + + + Additional Notes: + + + plainTextEdit + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + lineEditPassword createPasswordButton - checkBoxShow passwordTemplateSwitch spinBox_pwdLength plainTextEdit buttonBox accepted() PasswordDialog accept() 248 254 157 274 buttonBox rejected() PasswordDialog reject() 316 260 286 274