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 
26 using namespace GpgME;
27 using namespace Kleo;
28 
29 class SubkeyListModel::Private
30 {
31  friend class ::Kleo::SubkeyListModel;
32  SubkeyListModel *const q;
33 
34 public:
35  explicit Private(SubkeyListModel *qq)
36  : q(qq)
37  , key()
38  {
39  }
40 
41 private:
42  Key key;
43 };
44 
45 SubkeyListModel::SubkeyListModel(QObject *p)
47  , d(new Private(this))
48 {
49 }
50 
51 SubkeyListModel::~SubkeyListModel()
52 {
53 }
54 
55 Key SubkeyListModel::key() const
56 {
57  return d->key;
58 }
59 
60 // slot
61 void 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
67  beginResetModel();
68  d->key = key;
69  endResetModel();
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 {
80  Q_EMIT layoutAboutToBeChanged();
81  Q_EMIT layoutChanged();
82  }
83 }
84 
85 Subkey 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 
94 std::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 
107 QModelIndex 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 
118 QList<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 
132 void SubkeyListModel::clear()
133 {
134  beginResetModel();
135  d->key = Key::null;
136  endResetModel();
137 }
138 
139 int SubkeyListModel::columnCount(const QModelIndex &) const
140 {
141  return NumColumns;
142 }
143 
144 int SubkeyListModel::rowCount(const QModelIndex &pidx) const
145 {
146  return pidx.isValid() ? 0 : d->key.numSubkeys();
147 }
148 
149 QVariant 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 
175 QVariant 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"
DisplayRole
int column() const const
void reserve(int alloc)
int size() const const
QString i18n(const char *text, const TYPE &arg...)
QString fromStdString(const std::string &str)
Orientation
bool isEmpty() const const
bool isValid() const const
int row() const const
QString fromLatin1(const char *str, int size)
QList::iterator begin()
QList::iterator end()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Thu Feb 15 2024 03:56:14 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.