13#include <config-libkleo.h>
15#include "useridlistmodel.h"
19#include <libkleo/formatting.h>
21#include <KLocalizedString>
27#include <gpgme++/key.h>
39 explicit UIDModelItem(
const UserID::Signature &sig, UIDModelItem *parentItem,
bool showRemarks)
40 : mParentItem{parentItem}
43 const auto name = Formatting::prettyName(sig);
44 const auto email = Formatting::prettyEMail(sig);
46 Formatting::prettyID(sig.signerKeyID()),
49 Formatting::validityShort(sig),
50 sig.isExportable() ? QStringLiteral(
"✓") :
QString{},
51 Formatting::creationDateString(sig),
52 Formatting::expirationDateString(sig),
56 if (showRemarks && parentItem) {
57 for (
const auto ¬ation : sig.notations()) {
58 if (notation.name() && !strcmp(notation.name(),
"rem@gnupg.org")) {
65 const auto trustSignatureDomain = Formatting::trustSignatureDomain(sig);
66 mItemData.
push_back(trustSignatureDomain);
68 Formatting::accessibleHexID(sig.signerKeyID()),
69 name.isEmpty() ?
i18nc(
"text for screen readers for an empty name",
"no name") :
QVariant{},
70 email.isEmpty() ?
i18nc(
"text for screen readers for an empty email address",
"no email") :
QVariant{},
72 sig.isExportable() ?
i18nc(
"yes, is exportable",
"yes") :
i18nc(
"no, is not exportable",
"no"),
73 Formatting::accessibleDate(Formatting::creationDate(sig)),
74 Formatting::accessibleExpirationDate(sig),
75 lastNotation.isEmpty() ?
i18nc(
"accessible text for empty list of tags",
"none") :
QVariant{},
76 trustSignatureDomain.isEmpty() ?
i18n(
"not applicable") :
QVariant{},
78 Q_ASSERT(mAccessibleText.
size() == mItemData.
size());
81 explicit UIDModelItem(
const UserID &uid, UIDModelItem *parentItem)
82 : mParentItem{parentItem}
85 mItemData = {Formatting::prettyUserID(uid)};
104 i18n(
"User ID / Certification Key ID"),
112 i18n(
"Trust Signature For"),
119 qDeleteAll(mChildItems);
122 void appendChild(UIDModelItem *child)
124 mChildItems << child;
127 UIDModelItem *child(
int row)
const
129 return mChildItems.
value(row);
132 const UIDModelItem *constChild(
int row)
const
134 return mChildItems.
value(row);
137 int childCount()
const
139 return mChildItems.
count();
142 int columnCount()
const
148 return constChild(0)->columnCount();
150 return mItemData.
count();
155 return mItemData.
value(column);
158 QVariant accessibleText(
int column)
const
160 return mAccessibleText.
value(column);
165 if (!mSig.isNull()) {
166 if (column ==
static_cast<int>(UserIDListModel::Column::TrustSignatureDomain)) {
167 return Formatting::trustSignature(mSig);
170 return mItemData.
value(column);
175 if (!mSig.isNull() && column ==
static_cast<int>(UserIDListModel::Column::Status)) {
176 return Formatting::validityIcon(mSig);
184 return mParentItem->mChildItems.
indexOf(
const_cast<UIDModelItem *
>(
this));
189 UIDModelItem *parentItem()
const
194 UserID::Signature signature()
const
204 const char *signerKeyId()
const
206 return mSig.signerKeyID();
213 UIDModelItem *mParentItem =
nullptr;
214 UserID::Signature mSig;
218UserIDListModel::UserIDListModel(
QObject *p)
223UserIDListModel::~UserIDListModel() =
default;
225Key UserIDListModel::key()
const
230static std::vector<UserID::Signature> effectiveSignatures(
const UserID &userID)
232 std::vector<UserID::Signature> sigs = userID.signatures();
233 std::sort(sigs.begin(), sigs.end());
234 std::reverse(sigs.begin(), sigs.end());
235 auto last = std::unique(sigs.begin(), sigs.end(), [](
const auto &sig1,
const auto &sig2) {
236 return !qstricmp(sig1.signerKeyID(), sig2.signerKeyID());
238 sigs.erase(last, sigs.end());
239 std::reverse(sigs.begin(), sigs.end());
243void UserIDListModel::setKey(
const Key &key)
248 mRootItem.reset(
new UIDModelItem);
249 for (
int i = 0, ids = key.numUserIDs(); i < ids; ++i) {
250 UserID uid = key.userID(i);
251 auto uidItem =
new UIDModelItem(uid, mRootItem.get());
252 mRootItem->appendChild(uidItem);
254 for (
const auto &sig : effectiveSignatures(uid)) {
255 auto sigItem =
new UIDModelItem(sig, uidItem, mRemarksEnabled);
256 uidItem->appendChild(sigItem);
263int UserIDListModel::columnCount(
const QModelIndex &parent)
const
266 return static_cast<UIDModelItem *
>(
parent.internalPointer())->columnCount();
273 return mRootItem->columnCount();
276int UserIDListModel::rowCount(
const QModelIndex &parent)
const
278 if (
parent.column() > 0 || !mRootItem) {
282 const UIDModelItem *
const parentItem = !
parent.isValid() ? mRootItem.get() :
static_cast<UIDModelItem *
>(
parent.internalPointer());
283 return parentItem->childCount();
292 const UIDModelItem *
const parentItem = !
parent.isValid() ? mRootItem.get() :
static_cast<UIDModelItem *
>(
parent.internalPointer());
293 UIDModelItem *
const childItem = parentItem->child(row);
307 UIDModelItem *parentItem = childItem->parentItem();
309 if (parentItem == mRootItem.get()) {
313 return createIndex(parentItem->row(), 0, parentItem);
320 return mRootItem->data(section);
322 return mRootItem->accessibleText(section);
339 return item->data(index.
column());
341 return item->accessibleText(index.
column());
343 return item->toolTip(index.
column());
345 return item->icon(index.
column());
346 case UserIDListModel::SignerKeyIdRole:
354UserID UserIDListModel::userID(
const QModelIndex &index)
const
359 UIDModelItem *item =
static_cast<UIDModelItem *
>(index.
internalPointer());
363QList<UserID> UserIDListModel::userIDs(
const QModelIndexList &indexes)
const
367 if (!idx.isValid()) {
370 auto item =
static_cast<UIDModelItem *
>(idx.internalPointer());
371 if (!item->uid().isNull()) {
378UserID::Signature UserIDListModel::signature(
const QModelIndex &index)
const
381 return UserID::Signature();
383 UIDModelItem *item =
static_cast<UIDModelItem *
>(index.
internalPointer());
384 return item->signature();
391 if (!idx.isValid()) {
394 auto item =
static_cast<UIDModelItem *
>(idx.internalPointer());
395 if (!item->signature().isNull()) {
396 ret << item->signature();
402void UserIDListModel::enableRemarks(
bool value)
404 mRemarksEnabled = value;
407#include "moc_useridlistmodel.cpp"
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
QModelIndex createIndex(int row, int column, const void *ptr) const const
bool hasIndex(int row, int column, const QModelIndex &parent) const const
qsizetype count() const const
qsizetype indexOf(const AT &value, qsizetype from) const const
void push_back(parameter_type value)
qsizetype size() const const
T value(qsizetype i) const const
void * internalPointer() const const
bool isValid() const const
QObject * parent() const const
QString fromUtf8(QByteArrayView str)
QVariant fromValue(T &&value)