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();
153 QVariant data(
int column)
const
155 return mItemData.value(column);
158 QVariant accessibleText(
int column)
const
160 return mAccessibleText.value(column);
163 QVariant toolTip(
int column)
const
165 if (!mSig.isNull()) {
166 if (column ==
static_cast<int>(UserIDListModel::Column::TrustSignatureDomain)) {
167 return Formatting::trustSignature(mSig);
170 return mItemData.value(column);
173 QVariant icon(
int column)
const
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();
210 QList<UIDModelItem *> mChildItems;
211 QList<QVariant> mItemData;
212 QList<QVariant> mAccessibleText;
213 UIDModelItem *mParentItem =
nullptr;
214 UserID::Signature mSig;
218UserIDListModel::UserIDListModel(QObject *p)
219 : QAbstractItemModel{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
265 if (parent.isValid()) {
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();
286QModelIndex UserIDListModel::index(
int row,
int column,
const QModelIndex &parent)
const
288 if (!
hasIndex(row, column, parent)) {
292 const UIDModelItem *
const parentItem = !parent.isValid() ? mRootItem.get() :
static_cast<UIDModelItem *
>(parent.internalPointer());
293 UIDModelItem *
const childItem = parentItem->child(row);
297 return QModelIndex();
303 if (!index.isValid()) {
306 auto childItem =
static_cast<UIDModelItem *
>(index.internalPointer());
307 UIDModelItem *parentItem = childItem->parentItem();
309 if (parentItem == mRootItem.get()) {
310 return QModelIndex();
313 return createIndex(parentItem->row(), 0, parentItem);
316QVariant UserIDListModel::headerData(
int section,
Qt::Orientation o,
int role)
const
320 return mRootItem->data(section);
322 return mRootItem->accessibleText(section);
328QVariant UserIDListModel::data(
const QModelIndex &index,
int role)
const
330 if (!index.isValid()) {
334 auto item =
static_cast<UIDModelItem *
>(index.internalPointer());
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
356 if (!index.isValid()) {
359 UIDModelItem *item =
static_cast<UIDModelItem *
>(index.internalPointer());
363QList<UserID> UserIDListModel::userIDs(
const QModelIndexList &indexes)
const
365 QList<GpgME::UserID> ret;
366 for (
const QModelIndex &idx : indexes) {
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
380 if (!index.isValid()) {
381 return UserID::Signature();
383 UIDModelItem *item =
static_cast<UIDModelItem *
>(index.internalPointer());
384 return item->signature();
387QList<UserID::Signature> UserIDListModel::signatures(
const QModelIndexList &indexes)
const
389 QList<GpgME::UserID::Signature> ret;
390 for (
const QModelIndex &idx : indexes) {
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
QObject * parent() const const
QString fromUtf8(QByteArrayView str)
QVariant fromValue(T &&value)