Libkleo

subkeylistmodel.cpp
1/* -*- mode: c++; c-basic-offset:4 -*-
2 models/subkeylistmodel.cpp
3
4 This file is part of Kleopatra, the KDE keymanager
5 SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
6
7 SPDX-License-Identifier: GPL-2.0-or-later
8*/
9
10#include <config-libkleo.h>
11
12#include "subkeylistmodel.h"
13
14#include <libkleo/formatting.h>
15
16#include <KLocalizedString>
17
18#include <QDate>
19#include <QVariant>
20
21#include <gpgme++/key.h>
22
23#include <algorithm>
24#include <iterator>
25
26using namespace GpgME;
27using namespace Kleo;
28
29class SubkeyListModel::Private
30{
31 friend class ::Kleo::SubkeyListModel;
32 SubkeyListModel *const q;
33
34public:
35 explicit Private(SubkeyListModel *qq)
36 : q(qq)
37 , key()
38 {
39 }
40
41private:
42 Key key;
43};
44
45SubkeyListModel::SubkeyListModel(QObject *p)
47 , d(new Private(this))
48{
49}
50
51SubkeyListModel::~SubkeyListModel()
52{
53}
54
55Key SubkeyListModel::key() const
56{
57 return d->key;
58}
59
60// slot
61void SubkeyListModel::setKey(const Key &key)
62{
63 const Key oldKey = d->key;
64
65 if (qstricmp(key.primaryFingerprint(), oldKey.primaryFingerprint()) != 0) {
66 // different key -> reset
68 d->key = key;
70 return;
71 }
72
73 d->key = key;
74
75 // ### diff them, and signal more fine-grained than this:
76
77 if (key.numSubkeys() > 0 && oldKey.numSubkeys() == key.numSubkeys()) {
78 Q_EMIT dataChanged(index(0, 0), index(key.numSubkeys() - 1, NumColumns - 1));
79 } else {
82 }
83}
84
85Subkey SubkeyListModel::subkey(const QModelIndex &idx) const
86{
87 if (idx.isValid()) {
88 return d->key.subkey(idx.row());
89 } else {
90 return Subkey();
91 }
92}
93
94std::vector<Subkey> SubkeyListModel::subkeys(const QList<QModelIndex> &indexes) const
95{
96 std::vector<Subkey> result;
97 result.reserve(indexes.size());
98 std::transform(indexes.begin(), //
99 indexes.end(),
100 std::back_inserter(result),
101 [this](const QModelIndex &idx) {
102 return subkey(idx);
103 });
104 return result;
105}
106
107QModelIndex SubkeyListModel::index(const Subkey &subkey, int col) const
108{
109 // O(N), but not sorted, so no better way...
110 for (unsigned int row = 0, end = d->key.numSubkeys(); row != end; ++row) {
111 if (qstricmp(subkey.keyID(), d->key.subkey(row).keyID()) == 0) {
112 return index(row, col);
113 }
114 }
115 return {};
116}
117
118QList<QModelIndex> SubkeyListModel::indexes(const std::vector<Subkey> &subkeys) const
119{
120 QList<QModelIndex> result;
121 result.reserve(subkeys.size());
122 // O(N*M), but who cares...?
123 std::transform(subkeys.begin(), //
124 subkeys.end(),
125 std::back_inserter(result),
126 [this](const Subkey &key) {
127 return index(key);
128 });
129 return result;
130}
131
132void SubkeyListModel::clear()
133{
135 d->key = Key::null;
137}
138
139int SubkeyListModel::columnCount(const QModelIndex &) const
140{
141 return NumColumns;
142}
143
144int SubkeyListModel::rowCount(const QModelIndex &pidx) const
145{
146 return pidx.isValid() ? 0 : d->key.numSubkeys();
147}
148
149QVariant SubkeyListModel::headerData(int section, Qt::Orientation o, int role) const
150{
151 if (o == Qt::Horizontal) {
152 if (role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::ToolTipRole) {
153 switch (section) {
154 case ID:
155 return i18n("ID");
156 case Type:
157 return i18n("Type");
158 case ValidFrom:
159 return i18n("Valid From");
160 case ValidUntil:
161 return i18n("Valid Until");
162 case Status:
163 return i18n("Status");
164 case Strength:
165 return i18n("Strength");
166 case Usage:
167 return i18n("Usage");
168 case NumColumns:;
169 }
170 }
171 }
172 return QVariant();
173}
174
175QVariant SubkeyListModel::data(const QModelIndex &idx, int role) const
176{
177 if (role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::ToolTipRole) {
178 return QVariant();
179 }
180
181 const Subkey subkey = this->subkey(idx);
182 if (subkey.isNull()) {
183 return QVariant();
184 }
185
186 switch (idx.column()) {
187 case ID:
188 return QString::fromLatin1(subkey.keyID());
189 case Type:
190 return Formatting::type(subkey);
191 case ValidFrom:
192 if (role == Qt::EditRole) {
193 return Formatting::creationDate(subkey);
194 } else {
195 return Formatting::creationDateString(subkey);
196 }
197 case ValidUntil:
198 if (role == Qt::EditRole) {
199 return Formatting::expirationDate(subkey);
200 } else {
201 return Formatting::expirationDateString(subkey);
202 }
203 case Status:
204 return Formatting::validityShort(subkey);
205 case Usage:
206 return Formatting::usageString(subkey);
207 case Strength:
208 const QString algName = QString::fromStdString(subkey.algoName());
209 // For ECC keys the algo name is something like bp512 and directly
210 // indicated the "strength"
211 return algName.isEmpty() ? QVariant(subkey.length()) : algName;
212 }
213
214 return QVariant();
215}
216
217#include "moc_subkeylistmodel.cpp"
QString i18n(const char *text, const TYPE &arg...)
const QList< QKeySequence > & end()
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles)
void layoutAboutToBeChanged(const QList< QPersistentModelIndex > &parents, QAbstractItemModel::LayoutChangeHint hint)
void layoutChanged(const QList< QPersistentModelIndex > &parents, QAbstractItemModel::LayoutChangeHint hint)
iterator begin()
iterator end()
void reserve(qsizetype size)
qsizetype size() const const
int column() const const
bool isValid() const const
int row() const const
Q_EMITQ_EMIT
QString fromLatin1(QByteArrayView str)
QString fromStdString(const std::string &str)
bool isEmpty() const const
DisplayRole
Orientation
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:14:12 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.