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

IJHack / QtPass / 23676417477

28 Mar 2026 03:23AM UTC coverage: 18.415% (-0.02%) from 18.43%
23676417477

push

github

web-flow
Merge pull request #808 from IJHack/refactor/usersdialog-colors

refactor: improve UsersDialog code quality

0 of 40 new or added lines in 2 files covered. (0.0%)

925 of 5023 relevant lines covered (18.42%)

7.53 hits per line

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

0.0
/src/usersdialog.cpp
1
// SPDX-FileCopyrightText: 2016 Anne Jan Brouwer
2
// SPDX-License-Identifier: GPL-3.0-or-later
3
#include "usersdialog.h"
4
#include "qtpasssettings.h"
5
#include "ui_usersdialog.h"
6
#include <QCloseEvent>
7
#include <QKeyEvent>
8
#include <QMessageBox>
9
#include <QRegularExpression>
10
#include <QWidget>
11
#include <utility>
12

13
#ifdef QT_DEBUG
14
#include "debughelper.h"
15
#endif
16
/**
17
 * @brief UsersDialog::UsersDialog basic constructor
18
 * @param parent
19
 */
20
UsersDialog::UsersDialog(QString dir, QWidget *parent)
×
21
    : QDialog(parent), ui(new Ui::UsersDialog), m_dir(std::move(dir)) {
×
22

23
  ui->setupUi(this);
×
24

25
  QList<UserInfo> users = QtPassSettings::getPass()->listKeys();
×
26
  if (users.isEmpty()) {
×
27
    QMessageBox::critical(parent, tr("Keylist missing"),
×
28
                          tr("Could not fetch list of available GPG keys"));
×
29
    return;
30
  }
31

32
  QList<UserInfo> secret_keys = QtPassSettings::getPass()->listKeys("", true);
×
33
  foreach (const UserInfo &sec, secret_keys) {
×
34
    for (auto &user : users) {
×
35
      if (sec.key_id == user.key_id) {
×
36
        user.have_secret = true;
×
37
      }
38
    }
39
  }
40

41
  QList<UserInfo> selected_users;
×
42
  int count = 0;
×
43

44
  QStringList recipients = QtPassSettings::getPass()->getRecipientString(
×
45
      m_dir.isEmpty() ? "" : m_dir, " ", &count);
×
46
  if (!recipients.isEmpty()) {
×
47
    selected_users = QtPassSettings::getPass()->listKeys(recipients);
×
48
  }
49
  foreach (const UserInfo &sel, selected_users) {
×
50
    for (auto &user : users) {
×
51
      if (sel.key_id == user.key_id) {
×
52
        user.enabled = true;
×
53
      }
54
    }
55
  }
56

57
  if (count > selected_users.size()) {
×
58
    // Some keys seem missing from keyring, add them separately
59
    QStringList recipients = QtPassSettings::getPass()->getRecipientList(
×
60
        m_dir.isEmpty() ? "" : m_dir);
×
61
    foreach (const QString recipient, recipients) {
×
62
      if (QtPassSettings::getPass()->listKeys(recipient).empty()) {
×
63
        UserInfo i;
×
64
        i.enabled = true;
×
65
        i.key_id = recipient;
×
66
        i.name = " ?? " + tr("Key not found in keyring");
×
67
        users.append(i);
68
      }
×
69
    }
70
  }
71

72
  m_userList = users;
73
  populateList();
×
74

75
  connect(ui->buttonBox, &QDialogButtonBox::accepted, this,
×
76
          &UsersDialog::accept);
×
77
  connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
×
78
  connect(ui->listWidget, &QListWidget::itemChanged, this,
×
79
          &UsersDialog::itemChange);
×
80

81
  ui->lineEdit->setClearButtonEnabled(true);
×
82
}
×
83

84
/**
85
 * @brief UsersDialog::~UsersDialog basic destructor.
86
 */
87
UsersDialog::~UsersDialog() { delete ui; }
×
88

89
Q_DECLARE_METATYPE(UserInfo *)
×
90

91
/**
92
 * @brief UsersDialog::accept
93
 */
94
void UsersDialog::accept() {
×
95
  QtPassSettings::getPass()->Init(m_dir, m_userList);
×
96

97
  QDialog::accept();
×
98
}
×
99

100
/**
101
 * @brief UsersDialog::closeEvent might have to store size and location if that
102
 * is wanted.
103
 * @param event
104
 */
105
void UsersDialog::closeEvent(QCloseEvent *event) {
×
106
  // TODO(annejan): save window size or something
107
  event->accept();
108
}
×
109

110
/**
111
 * @brief UsersDialog::keyPressEvent clear the lineEdit when escape is pressed.
112
 * No action for Enter currently.
113
 * @param event
114
 */
115
void UsersDialog::keyPressEvent(QKeyEvent *event) {
×
116
  switch (event->key()) {
×
117
  case Qt::Key_Escape:
×
118
    ui->lineEdit->clear();
×
119
    break;
×
120
  default:
121
    break;
122
  }
123
}
×
124

125
/**
126
 * @brief UsersDialog::itemChange update the item information.
127
 * @param item
128
 */
129
void UsersDialog::itemChange(QListWidgetItem *item) {
×
130
  if (!item) {
×
131
    return;
132
  }
133
  auto *info = item->data(Qt::UserRole).value<UserInfo *>();
×
134
  if (!info) {
×
135
    return;
136
  }
137
  info->enabled = item->checkState() == Qt::Checked;
×
138
}
139

140
/**
141
 * @brief UsersDialog::populateList update the view based on filter options
142
 * (such as searching).
143
 * @param filter
144
 */
145
void UsersDialog::populateList(const QString &filter) {
×
146
  QRegularExpression nameFilter(
147
      QRegularExpression::wildcardToRegularExpression("*" + filter + "*"),
×
148
      QRegularExpression::CaseInsensitiveOption);
×
149
  ui->listWidget->clear();
×
150

NEW
151
  for (auto &user : m_userList) {
×
NEW
152
    if (!passesFilter(user, filter, nameFilter)) {
×
NEW
153
      continue;
×
154
    }
155

NEW
156
    auto *item = new QListWidgetItem(buildUserText(user), ui->listWidget);
×
NEW
157
    applyUserStyling(item, user);
×
NEW
158
    item->setCheckState(user.enabled ? Qt::Checked : Qt::Unchecked);
×
NEW
159
    item->setData(Qt::UserRole, QVariant::fromValue(&user));
×
NEW
160
    ui->listWidget->addItem(item);
×
161
  }
NEW
162
}
×
163

NEW
164
bool UsersDialog::passesFilter(const UserInfo &user, const QString &filter,
×
165
                               const QRegularExpression &nameFilter) const {
NEW
166
  if (!filter.isEmpty() && !nameFilter.match(user.name).hasMatch()) {
×
167
    return false;
168
  }
NEW
169
  if (!user.isValid() && !ui->checkBox->isChecked()) {
×
170
    return false;
171
  }
NEW
172
  bool expired = user.expiry.toSecsSinceEpoch() > 0 &&
×
NEW
173
                 user.expiry.daysTo(QDateTime::currentDateTime()) > 0;
×
NEW
174
  return !(expired && !ui->checkBox->isChecked());
×
175
}
176

NEW
177
QString UsersDialog::buildUserText(const UserInfo &user) const {
×
NEW
178
  QString text = user.name + "\n" + user.key_id;
×
NEW
179
  if (user.created.toSecsSinceEpoch() > 0) {
×
NEW
180
    text += " " + tr("created") + " " +
×
NEW
181
            QLocale::system().toString(user.created, QLocale::ShortFormat);
×
182
  }
NEW
183
  if (user.expiry.toSecsSinceEpoch() > 0) {
×
NEW
184
    text += " " + tr("expires") + " " +
×
NEW
185
            QLocale::system().toString(user.expiry, QLocale::ShortFormat);
×
186
  }
NEW
187
  return text;
×
188
}
189

NEW
190
void UsersDialog::applyUserStyling(QListWidgetItem *item,
×
191
                                   const UserInfo &user) const {
NEW
192
  if (user.have_secret) {
×
NEW
193
    item->setForeground(Qt::blue);
×
NEW
194
    QFont font;
×
195
    font.setBold(true);
NEW
196
    item->setFont(font);
×
NEW
197
  } else if (!user.isValid()) {
×
NEW
198
    item->setBackground(Qt::darkRed);
×
NEW
199
    item->setForeground(Qt::white);
×
NEW
200
  } else if (user.expiry.toSecsSinceEpoch() > 0 &&
×
NEW
201
             user.expiry.daysTo(QDateTime::currentDateTime()) > 0) {
×
NEW
202
    item->setForeground(Qt::darkRed);
×
NEW
203
  } else if (!user.fullyValid()) {
×
NEW
204
    item->setBackground(Qt::darkYellow);
×
NEW
205
    item->setForeground(Qt::white);
×
206
  }
207
}
×
208

209
/**
210
 * @brief UsersDialog::on_lineEdit_textChanged typing in the searchbox.
211
 * @param filter
212
 */
213
void UsersDialog::on_lineEdit_textChanged(const QString &filter) {
×
214
  populateList(filter);
×
215
}
×
216

217
/**
218
 * @brief UsersDialog::on_checkBox_clicked filtering.
219
 */
220
void UsersDialog::on_checkBox_clicked() { populateList(ui->lineEdit->text()); }
×
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