• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

IJHack / QtPass / 24833334319

23 Apr 2026 11:44AM UTC coverage: 27.079% (-0.07%) from 27.146%
24833334319

push

github

web-flow
Merge pull request #1138 from IJHack/fix/132-edit-template-fields

fix: Allow editing all password fields (#132)

2 of 2 new or added lines in 1 file covered. (100.0%)

3 existing lines in 1 file now uncovered.

1592 of 5879 relevant lines covered (27.08%)

30.1 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

54.55
/src/passworddialog.cpp
1
// SPDX-FileCopyrightText: 2015 Anne Jan Brouwer
2
// SPDX-License-Identifier: GPL-3.0-or-later
3
#include "passworddialog.h"
4
#include "filecontent.h"
5
#include "helpers.h"
6
#include "pass.h"
7
#include "passwordconfiguration.h"
8
#include "qtpasssettings.h"
9
#include "ui_passworddialog.h"
10

11
#include <QLabel>
12
#include <QLineEdit>
13
#include <utility>
14

15
#ifdef QT_DEBUG
16
#include "debughelper.h"
17
#endif
18

19
/**
20
 * @brief PasswordDialog::PasswordDialog basic constructor.
21
 * @param passConfig configuration constant
22
 * @param parent
23
 */
24
PasswordDialog::PasswordDialog(PasswordConfiguration passConfig,
8✔
25
                               QWidget *parent)
8✔
26
    : QDialog(parent), ui(new Ui::PasswordDialog),
16✔
27
      m_passConfig(std::move(passConfig)) {
8✔
28
  m_templating = false;
29
  m_isNew = false;
8✔
30

31
  ui->setupUi(this);
8✔
32
  setLength(m_passConfig.length);
8✔
33
  setPasswordCharTemplate(m_passConfig.selected);
8✔
34

35
  connect(QtPassSettings::getPass(), &Pass::finishedShow, this,
8✔
36
          &PasswordDialog::setPass);
8✔
37
}
8✔
38

39
/**
40
 * @brief PasswordDialog::PasswordDialog complete constructor.
41
 * @param file
42
 * @param isNew
43
 * @param parent pointer
44
 */
45
PasswordDialog::PasswordDialog(QString file, const bool &isNew, QWidget *parent)
×
46
    : QDialog(parent), ui(new Ui::PasswordDialog), m_file(std::move(file)),
×
47
      m_isNew(isNew) {
×
48

49
  if (!isNew) {
×
50
    QtPassSettings::getPass()->Show(m_file);
×
51
  }
52

53
  ui->setupUi(this);
×
54

55
  setWindowTitle(this->windowTitle() + " " + m_file);
×
56
  m_passConfig = QtPassSettings::getPasswordConfiguration();
×
57
  usePwgen(QtPassSettings::isUsePwgen());
×
58
  setTemplate(QtPassSettings::getPassTemplate(),
×
59
              QtPassSettings::isUseTemplate());
×
60

UNCOV
61
  setLength(m_passConfig.length);
×
62
  setPasswordCharTemplate(m_passConfig.selected);
×
63

64
  connect(QtPassSettings::getPass(), &Pass::finishedShow, this,
×
65
          &PasswordDialog::setPass);
×
66
  connect(QtPassSettings::getPass(), &Pass::processErrorExit, this,
×
67
          &PasswordDialog::close);
×
68
  connect(this, &PasswordDialog::accepted, this, &PasswordDialog::on_accepted);
×
69
  connect(this, &PasswordDialog::rejected, this, &PasswordDialog::on_rejected);
×
70
}
×
71

72
/**
73
 * @brief PasswordDialog::~PasswordDialog basic destructor.
74
 */
75
PasswordDialog::~PasswordDialog() { delete ui; }
24✔
76

77
/**
78
 * @brief PasswordDialog::on_checkBoxShow_stateChanged hide or show passwords.
79
 * @param arg1
80
 */
81
void PasswordDialog::on_checkBoxShow_stateChanged(int arg1) {
×
82
  if (arg1) {
×
83
    ui->lineEditPassword->setEchoMode(QLineEdit::Normal);
×
84
  } else {
85
    ui->lineEditPassword->setEchoMode(QLineEdit::Password);
×
86
  }
87
}
×
88

89
/**
90
 * @brief PasswordDialog::on_createPasswordButton_clicked generate a random
91
 * password.
92
 */
93
void PasswordDialog::on_createPasswordButton_clicked() {
×
94
  ui->widget->setEnabled(false);
×
95
  const int currentIndex = ui->passwordTemplateSwitch->currentIndex();
×
96
  if (currentIndex < 0 ||
×
97
      currentIndex >= static_cast<int>(PasswordConfiguration::CHARSETS_COUNT)) {
98
    ui->widget->setEnabled(true);
×
99
    return;
×
100
  }
101

102
  QString newPass = QtPassSettings::getPass()->generatePassword(
×
103
      static_cast<unsigned int>(ui->spinBox_pwdLength->value()),
×
104
      m_passConfig.Characters[static_cast<PasswordConfiguration::characterSet>(
105
          currentIndex)]);
×
106
  if (!newPass.isEmpty()) {
×
107
    ui->lineEditPassword->setText(newPass);
×
108
  }
109
  ui->widget->setEnabled(true);
×
110
}
111

112
/**
113
 * @brief PasswordDialog::on_accepted handle Ok click for QDialog
114
 */
115
void PasswordDialog::on_accepted() {
×
116
  QString newValue = getPassword();
×
117
  if (newValue.isEmpty()) {
×
118
    return;
119
  }
120

121
  if (newValue.right(1) != "\n") {
×
122
    newValue += "\n";
×
123
  }
124

125
  QtPassSettings::getPass()->Insert(m_file, newValue, !m_isNew);
×
126
}
127

128
/**
129
 * @brief PasswordDialog::on_rejected handle Cancel click for QDialog
130
 */
131
void PasswordDialog::on_rejected() { setPassword(QString()); }
×
132

133
/**
134
 * @brief PasswordDialog::setPassword populate the (templated) fields.
135
 * @param password
136
 */
137
void PasswordDialog::setPassword(const QString &password) {
8✔
138
  // Always parse all fields as editable so users can edit any field in the
139
  // password file. This fixes issue #132 where users couldn't edit
140
  // fields without toggling the "Show all fields templated" setting.
141
  FileContent fileContent = FileContent::parse(password, m_fields, true);
8✔
142
  ui->lineEditPassword->setText(fileContent.getPassword());
8✔
143

144
  QWidget *previous = ui->checkBoxShow;
8✔
145
  // first set templated values
146
  NamedValues namedValues = fileContent.getNamedValues();
8✔
147
  for (QLineEdit *line : AS_CONST(templateLines)) {
9✔
148
    line->setText(namedValues.takeValue(line->objectName()));
2✔
149
    previous = line;
150
  }
151
  // show remaining values (if there are)
152
  otherLines.clear();
8✔
153
  for (const NamedValue &nv : AS_CONST(namedValues)) {
11✔
154
    auto *line = new QLineEdit();
3✔
155
    line->setObjectName(nv.name);
3✔
156
    line->setText(nv.value);
3✔
157
    ui->formLayout->addRow(new QLabel(nv.name), line);
3✔
158
    setTabOrder(previous, line);
3✔
159
    otherLines.append(line);
3✔
160
    previous = line;
161
  }
162

163
  ui->plainTextEdit->insertPlainText(fileContent.getRemainingData());
16✔
164
}
8✔
165

166
/**
167
 * @brief PasswordDialog::getPassword  join the (templated) fields to a QString
168
 * for writing back.
169
 * @return collapsed password.
170
 */
171
auto PasswordDialog::getPassword() -> QString {
8✔
172
  QString passFile = ui->lineEditPassword->text() + "\n";
16✔
173
  QList<QLineEdit *> allLines(templateLines);
174
  allLines.append(otherLines);
8✔
175
  for (QLineEdit *line : allLines) {
20✔
176
    QString text = line->text();
4✔
177
    if (text.isEmpty()) {
4✔
178
      continue;
179
    }
180
    passFile += line->objectName() + ": " + text + "\n";
8✔
181
  }
182
  passFile += ui->plainTextEdit->toPlainText();
16✔
183
  return passFile;
8✔
184
}
185

186
/**
187
 * @brief PasswordDialog::setTemplate set the template and create the fields.
188
 * @param rawFields
189
 */
190
void PasswordDialog::setTemplate(const QString &rawFields, bool useTemplate) {
7✔
191
  m_fields = rawFields.split('\n');
7✔
192
  m_templating = useTemplate;
7✔
193
  templateLines.clear();
7✔
194

195
  if (m_templating) {
7✔
196
    QWidget *previous = ui->checkBoxShow;
1✔
197
    for (const QString &field : std::as_const(m_fields)) {
2✔
UNCOV
198
      if (field.isEmpty()) {
×
UNCOV
199
        continue;
×
200
      }
201
      auto *line = new QLineEdit();
1✔
202
      line->setObjectName(field);
1✔
203
      ui->formLayout->addRow(new QLabel(field), line);
1✔
204
      setTabOrder(previous, line);
1✔
205
      templateLines.append(line);
1✔
206
      previous = line;
207
    }
208
  }
209
}
7✔
210

211
/**
212
 * @brief PasswordDialog::setLength
213
 * PasswordDialog::setLength password length.
214
 * @param length
215
 */
216
void PasswordDialog::setLength(int length) {
8✔
217
  ui->spinBox_pwdLength->setValue(length);
8✔
218
}
8✔
219

220
/**
221
 * @brief PasswordDialog::setPasswordCharTemplate
222
 * PasswordDialog::setPasswordCharTemplate chose the template style.
223
 * @param templateIndex
224
 */
225
void PasswordDialog::setPasswordCharTemplate(int templateIndex) {
8✔
226
  ui->passwordTemplateSwitch->setCurrentIndex(templateIndex);
8✔
227
}
8✔
228

229
/**
230
 * @brief PasswordDialog::usePwgen
231
 * PasswordDialog::usePwgen don't use own password generator.
232
 * @param usePwgen
233
 */
234
void PasswordDialog::usePwgen(bool usePwgen) {
×
235
  ui->passwordTemplateSwitch->setDisabled(usePwgen);
×
236
  ui->label_characterset->setDisabled(usePwgen);
×
237
}
×
238

239
/**
240
 * @brief Sets the password from pass show output.
241
 * @param output Output from pass show command
242
 */
243
void PasswordDialog::setPass(const QString &output) {
8✔
244
  setPassword(output);
8✔
245
  // UI is enabled by default when password is set - no additional action needed
246
}
8✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc