Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F21947172
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
8 KB
Subscribers
None
View Options
diff --git a/src/models/userslistmodel.cpp b/src/models/userslistmodel.cpp
index e3fe8b9..cd2b4d0 100644
--- a/src/models/userslistmodel.cpp
+++ b/src/models/userslistmodel.cpp
@@ -1,262 +1,249 @@
// SPDX-FileCopyrightText: 2024 g10 Code GmbH
// SPDX-FileContributor: Carl Schwan <carl.schwan@gnupg.com>
// SPDX-License-Identifier: GPL-3.0-or-later
#include "userslistmodel.h"
#include <QColor>
#include <QDir>
#include <QFileInfo>
#include <QFont>
#include <QLocale>
+#include <KColorScheme>
#include <KLocalizedString>
#include <QGpgME/Protocol>
#include <libkleo/formatting.h>
#include "gpgmehelpers.h"
UsersListModel::UsersListModel(QList<QByteArray> recipients, QObject *parent)
: QAbstractListModel(parent)
, m_recipients(recipients)
{
generateUserList();
}
UsersListModel::~UsersListModel() = default;
QVariant UsersListModel::data(const QModelIndex &index, int role) const
{
Q_ASSERT(checkIndex(index, QAbstractItemModel::CheckIndexOption::IndexIsValid));
const auto &user = m_users[index.row()];
switch (role) {
case Qt::DisplayRole: {
if (std::holds_alternative<GpgME::Key>(user)) {
return Kleo::Formatting::summaryLine(std::get<GpgME::Key>(user));
} else {
return i18nc("@info", "Unknown recipient: %1", QString::fromLatin1(std::get<QByteArray>(user)));
}
}
case Qt::CheckStateRole:
return m_recipients.contains(std::holds_alternative<GpgME::Key>(user) ? std::get<GpgME::Key>(user).keyID() : std::get<QByteArray>(user))
? Qt::Checked
: Qt::Unchecked;
case Qt::UserRole:
return QVariant::fromValue(user);
case Qt::FontRole:
if (std::holds_alternative<GpgME::Key>(user)) {
if (std::get<GpgME::Key>(user).hasSecret()) {
QFont font;
font.setFamily(font.defaultFamily());
font.setBold(true);
return font;
}
}
return {};
case Qt::ForegroundRole:
if (std::holds_alternative<GpgME::Key>(user)) {
const auto &key = std::get<GpgME::Key>(user);
- if (key.hasSecret()) {
- return {};
- } else if (key.userID(0).validity() < GpgME::UserID::Marginal) {
- return QColor(Qt::white);
- } else if (key.isExpired()) {
- return QColor(164, 0, 0);
- }
- }
- return {};
- case Qt::BackgroundRole:
- if (std::holds_alternative<GpgME::Key>(user)) {
- const auto &key = std::get<GpgME::Key>(user);
- if (key.hasSecret()) {
- return {}; // default
- } else if (key.userID(0).validity() < GpgME::UserID::Marginal) {
- return QColor(164, 0, 0);
- } else if (key.isExpired()) {
+ if (key.isBad() || key.userID(0).validity() < GpgME::UserID::Marginal) {
+ return KColorScheme(QPalette::Active, KColorScheme::View).foreground(KColorScheme::NegativeText).color();
+ } else if (key.hasSecret()) {
return {};
}
}
return {};
default:
return {};
}
}
bool UsersListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
Q_ASSERT(checkIndex(index, QAbstractItemModel::CheckIndexOption::IndexIsValid));
if (role != Qt::CheckStateRole) {
return false;
}
auto user = m_users[index.row()];
const auto keyId = std::holds_alternative<GpgME::Key>(user) ? std::get<GpgME::Key>(user).keyID() : std::get<QByteArray>(user);
if (value.toBool()) {
m_recipients.append(keyId);
} else {
m_recipients.removeAll(keyId);
}
Q_EMIT dataChanged(index, index, {Qt::CheckStateRole});
return true;
}
Qt::ItemFlags UsersListModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
if (index.isValid()) {
return defaultFlags | Qt::ItemIsUserCheckable;
}
return defaultFlags;
}
int UsersListModel::rowCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : (int)m_users.size();
}
void UsersListModel::generateUserList()
{
// Fetch all keys
auto job = QGpgME::openpgp()->keyListJob();
job->addMode(GpgME::KeyListMode::WithSecret);
job->addMode(GpgME::KeyListMode::Validate);
connect(job, &QGpgME::KeyListJob::result, this, &UsersListModel::slotUserListFetched);
job->start({}, false);
}
void UsersListModel::slotUserListFetched(const GpgME::KeyListResult &result,
const std::vector<GpgME::Key> &keys,
const QString &auditLogAsHtml,
const GpgME::Error &auditLogError)
{
Q_UNUSED(auditLogAsHtml);
Q_UNUSED(&auditLogError);
beginResetModel();
m_users.clear();
if (!isSuccess(result.error())) {
Q_EMIT errorOccurred(Kleo::Formatting::errorAsString(result.error()));
return;
}
std::transform(keys.cbegin(), keys.cend(), std::back_inserter(m_users), [](const auto &key) {
return key;
});
if (!m_recipients.isEmpty()) {
// Fetch all keys which are marked as recipients in the selected directory
auto job = QGpgME::openpgp()->keyListJob();
job->addMode(GpgME::KeyListMode::WithSecret);
QStringList recipientsList;
std::transform(m_recipients.cbegin(), m_recipients.cend(), std::back_inserter(recipientsList), [](auto byteArray) {
return QString::fromUtf8(byteArray);
});
connect(job,
&QGpgME::KeyListJob::result,
this,
[this, recipientsList](const GpgME::KeyListResult &result,
const std::vector<GpgME::Key> &keys,
const QString &auditLogAsHtml,
const GpgME::Error &auditLogError) {
Q_UNUSED(auditLogAsHtml);
Q_UNUSED(&auditLogError);
slotRecipientsFetched(result, keys, recipientsList);
});
job->start(recipientsList, false);
} else {
// No more keys to fetch
Q_EMIT finishedKeysFetching();
}
endResetModel();
}
void UsersListModel::slotRecipientsFetched(const GpgME::KeyListResult &result, const std::vector<GpgME::Key> &keys, const QStringList &recipients)
{
if (!isSuccess(result.error())) {
Q_EMIT errorOccurred(Kleo::Formatting::errorAsString(result.error()));
return;
}
QStringList missingRecipients = recipients;
for (const auto &selectedUser : std::as_const(keys)) {
missingRecipients.removeAll(QString::fromLatin1(selectedUser.keyID()));
}
for (const QString &missingRecipient : missingRecipients) {
beginInsertRows({}, m_users.size(), m_users.size());
m_users.push_back(missingRecipient.toLatin1());
endInsertRows();
}
Q_EMIT finishedKeysFetching();
}
FilterUsersListModel::FilterUsersListModel(QObject *parent)
: QSortFilterProxyModel(parent)
{
setFilterCaseSensitivity(Qt::CaseInsensitive);
}
FilterUsersListModel::~FilterUsersListModel() = default;
bool FilterUsersListModel::showOnlyValidUser() const
{
return m_showOnlyValidUser;
}
void FilterUsersListModel::setShowOnlyValidUser(bool state)
{
m_showOnlyValidUser = state;
invalidateFilter();
}
bool FilterUsersListModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
// filter by name
auto ok = QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
if (!ok) {
return false;
}
if (!m_showOnlyValidUser) {
return true;
}
const auto index = sourceModel()->index(sourceRow, 0, sourceParent);
if (index.data(Qt::CheckStateRole) == Qt::Checked) {
return true;
}
const auto user = index.data(Qt::UserRole).value<std::variant<QByteArray, GpgME::Key>>();
if (std::holds_alternative<GpgME::Key>(user)) {
const auto &key = std::get<GpgME::Key>(user);
return key.userID(0).validity() >= GpgME::UserID::Marginal && !key.isBad();
}
return false;
}
std::vector<std::variant<QByteArray, GpgME::Key>> UsersListModel::recipients() const
{
std::vector<std::variant<QByteArray, GpgME::Key>> recipients;
for (const auto &user : m_users) {
if (m_recipients.contains(std::holds_alternative<GpgME::Key>(user) ? std::get<GpgME::Key>(user).keyID() : std::get<QByteArray>(user))) {
recipients.push_back(user);
}
}
return recipients;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Apr 20, 5:55 AM (19 h, 8 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
66/05/da65359e2ae2a21a69289e855317
Attached To
rGPGPASS GnuPG Password Manager
Event Timeline
Log In to Comment