00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "kgpgitemmodel.h"
00020 #include "kgpgitemnode.h"
00021 #include "kgpginterface.h"
00022 #include "kgpgsettings.h"
00023 #include "convert.h"
00024 #include <KLocale>
00025
00026 KGpgItemModel::KGpgItemModel(QObject *parent)
00027 : QAbstractItemModel(parent)
00028 {
00029 m_root = new KGpgRootNode(this);
00030 m_default = KGpgSettings::defaultKey();
00031 }
00032
00033 KGpgItemModel::~KGpgItemModel()
00034 {
00035 delete m_root;
00036 }
00037
00038 QModelIndex
00039 KGpgItemModel::index(int row, int column, const QModelIndex &parent) const
00040 {
00041 if (hasIndex(row, column, parent)) {
00042 KGpgNode *parentNode = nodeForIndex(parent);
00043 KGpgNode *childNode = parentNode->getChild(row);
00044 return createIndex(row, column, childNode);
00045 }
00046 return QModelIndex();
00047 }
00048
00049 QModelIndex
00050 KGpgItemModel::parent(const QModelIndex &child) const
00051 {
00052 if (!child.isValid())
00053 return QModelIndex();
00054 KGpgNode *childNode = nodeForIndex(child);
00055 KGpgNode *parentNode = childNode->m_parent;
00056
00057 if (parentNode == m_root)
00058 return QModelIndex();
00059
00060 Q_ASSERT(parentNode != NULL);
00061 int row = rowForNode(parentNode);
00062 int column = 0;
00063
00064 return createIndex(row, column, parentNode);
00065 }
00066
00067 int
00068 KGpgItemModel::rowCount(const QModelIndex &parent) const
00069 {
00070 if (parent.column() > 0)
00071 return 0;
00072
00073 KGpgNode *parentNode = nodeForIndex(parent);
00074
00075 return parentNode->getChildCount();
00076 }
00077
00078 bool
00079 KGpgItemModel::hasChildren(const QModelIndex &parent) const
00080 {
00081 if (parent.column() > 0)
00082 return false;
00083
00084 KGpgNode *parentNode = nodeForIndex(parent);
00085
00086 return parentNode->hasChildren();
00087 }
00088
00089 QVariant
00090 KGpgItemModel::data(const QModelIndex &index, int role) const
00091 {
00092 if (!index.isValid())
00093 return QVariant();
00094
00095 KGpgNode *node = nodeForIndex(index);
00096
00097 if (role == Qt::FontRole) {
00098 QFont f;
00099 f.setBold(isDefaultKey(node));
00100 return f;
00101 }
00102
00103 switch (index.column()) {
00104 case KEYCOLUMN_NAME:
00105 switch (role) {
00106 case Qt::DisplayRole:
00107 return node->getName();
00108 case Qt::DecorationRole:
00109 if (node->getType() == ITYPE_UAT) {
00110 KGpgUatNode *nd = static_cast<KGpgUatNode *>(node);
00111 return nd->getPixmap();
00112 } else {
00113 return Convert::toPixmap(node->getType());
00114 }
00115 case Qt::ToolTipRole:
00116 return node->getComment();
00117 }
00118 break;
00119 case KEYCOLUMN_EMAIL:
00120 if (role == Qt::DisplayRole)
00121 return node->getEmail();
00122 break;
00123 case KEYCOLUMN_TRUST:
00124 {
00125 KgpgKeyTrust t = node->getTrust();
00126
00127 switch (role) {
00128 case Qt::BackgroundColorRole: return Convert::toColor(t);
00129 case Qt::AccessibleTextRole: return Convert::toString(t);
00130 }
00131 break;
00132 }
00133 case KEYCOLUMN_EXPIR:
00134 if (role == Qt::DisplayRole)
00135 return node->getExpiration();
00136 break;
00137 case KEYCOLUMN_SIZE:
00138 switch (role) {
00139 case Qt::DisplayRole:
00140 return node->getSize();
00141 case Qt::ToolTipRole:
00142 switch (node->getType()) {
00143 case ITYPE_PAIR:
00144 case ITYPE_PUBLIC:
00145 return static_cast<KGpgKeyNode *>(node)->getSignCount();
00146 case ITYPE_UAT:
00147 return static_cast<KGpgUatNode *>(node)->getSignCount();
00148 case ITYPE_UID:
00149 return static_cast<KGpgUidNode *>(node)->getSignCount();
00150 case ITYPE_SUB:
00151 return static_cast<KGpgSubkeyNode *>(node)->getSignCount();
00152 }
00153 }
00154 break;
00155 case KEYCOLUMN_CREAT:
00156 if (role == Qt::DisplayRole)
00157 return node->getCreation();
00158 break;
00159 case KEYCOLUMN_ID:
00160 if (role == Qt::DisplayRole)
00161 return node->getId();
00162 break;
00163 }
00164
00165 Q_ASSERT(1);
00166 return QVariant();
00167 }
00168
00169 KGpgNode *
00170 KGpgItemModel::nodeForIndex(const QModelIndex &index) const
00171 {
00172 if (index.isValid())
00173 return static_cast<KGpgNode*>(index.internalPointer());
00174 return m_root;
00175 }
00176
00177 int
00178 KGpgItemModel::rowForNode(KGpgNode *node) const
00179 {
00180 return node->m_parent->getChildIndex(node);
00181 }
00182
00183 KGpgRootNode *
00184 KGpgItemModel::getRootNode() const
00185 {
00186 return m_root;
00187 }
00188
00189 QString
00190 KGpgItemModel::statusCountMessage() const
00191 {
00192 int groupNb = m_root->groupChildren();
00193 QString kmsg = i18np("1 Key", "%1 Keys", m_root->getChildCount() - groupNb);
00194
00195 if (groupNb == 0) {
00196 return kmsg;
00197 } else {
00198 QString gmsg = i18np("1 Group", "%1 Groups", groupNb);
00199
00200 return kmsg + ", " + gmsg;
00201 }
00202 }
00203
00204 KGpgGroupNode *
00205 KGpgItemModel::addGroup(const QString &name, const KGpgKeyNodeList &keys)
00206 {
00207 KGpgGroupNode *nd;
00208
00209 emit layoutAboutToBeChanged();
00210 nd = new KGpgGroupNode(m_root, name, keys);
00211 fixPersistentIndexes();
00212 emit layoutChanged();
00213
00214 return nd;
00215 }
00216
00217 void
00218 KGpgItemModel::delNode(const KGpgNode *node)
00219 {
00220 emit layoutAboutToBeChanged();
00221 delete node;
00222 fixPersistentIndexes();
00223 emit layoutChanged();
00224 }
00225
00226 void
00227 KGpgItemModel::changeGroup(KGpgGroupNode *node, const QList<KGpgNode *> &keys)
00228 {
00229 emit layoutAboutToBeChanged();
00230 for (int i = node->getChildCount() - 1; i >= 0; i--) {
00231 bool found = false;
00232
00233 for (int j = 0; j < keys.count(); j++) {
00234 found = (node->getChild(i)->getId() == keys.at(j)->getId());
00235 if (found)
00236 break;
00237 }
00238 if (found)
00239 continue;
00240 delete node->getChild(i);
00241 }
00242
00243 for (int i = 0; i < keys.count(); i++) {
00244 bool found = false;
00245 for (int j = 0; j < node->getChildCount(); j++) {
00246 found = (node->getChild(j)->getId() == keys.at(i)->getId());
00247 if (found)
00248 break;
00249 }
00250 if (found)
00251 continue;
00252 Q_ASSERT(!(keys.at(i)->getType() & ITYPE_GROUP));
00253 new KGpgGroupMemberNode(node, static_cast<KGpgKeyNode *>(keys.at(i)));
00254 }
00255 fixPersistentIndexes();
00256 emit layoutChanged();
00257 }
00258
00259 QVariant
00260 KGpgItemModel::headerData(int section, Qt::Orientation orientation, int role) const
00261 {
00262 if (role != Qt::DisplayRole)
00263 return QVariant();
00264
00265 if (orientation != Qt::Horizontal)
00266 return QVariant();
00267
00268 switch (section) {
00269 case KEYCOLUMN_NAME: return QString(i18n("Name"));
00270 case KEYCOLUMN_EMAIL: return QString(i18n("Email"));
00271 case KEYCOLUMN_TRUST: return QString(i18n("Trust"));
00272 case KEYCOLUMN_SIZE: return QString(i18n("Size"));
00273 case KEYCOLUMN_EXPIR: return QString(i18n("Expiration"));
00274 case KEYCOLUMN_CREAT: return QString(i18n("Creation"));
00275 case KEYCOLUMN_ID: return QString(i18n("ID"));
00276 default: return QVariant();
00277 }
00278 }
00279
00280 void
00281 KGpgItemModel::setDefaultKey(const QString &def)
00282 {
00283 int defrow = m_root->findKeyRow(def);
00284 int odefrow = m_root->findKeyRow(m_default);
00285 if (defrow == odefrow)
00286 return;
00287
00288 KGpgNode *n_def = m_root->getChild(defrow);
00289
00290 int lastcol = columnCount(QModelIndex()) - 1;
00291 if (odefrow >= 0) {
00292 KGpgNode *nd = m_root->getChild(odefrow);
00293 emit dataChanged(createIndex(odefrow, 0, nd), createIndex(odefrow, lastcol, nd));
00294 }
00295
00296 m_default = def;
00297 emit dataChanged(createIndex(defrow, 0, n_def), createIndex(defrow, lastcol, n_def));
00298 }
00299
00300 QModelIndex
00301 KGpgItemModel::nodeIndex(KGpgNode *node)
00302 {
00303 KGpgNode *p = node->getParentKeyNode();
00304
00305 for (int i = 0; i < p->getChildCount(); i++)
00306 if (p->getChild(i) == node)
00307 return createIndex(i, 0, node);
00308
00309 Q_ASSERT(1);
00310 return QModelIndex();
00311 }
00312
00313 void
00314 KGpgItemModel::refreshKey(KGpgKeyNode *nd)
00315 {
00316 KGpgKeyNodeList nodes;
00317
00318 nodes.append(nd);
00319
00320 refreshKeyIds(nodes);
00321 }
00322
00323 void
00324 KGpgItemModel::refreshKey(const QString &id)
00325 {
00326 refreshKeyIds(QStringList(id));
00327 }
00328
00329 void
00330 KGpgItemModel::refreshKeys(KGpgKeyNodeList keys)
00331 {
00332 refreshKeyIds(keys);
00333 }
00334
00335 void
00336 KGpgItemModel::refreshKeys(const QStringList &ids)
00337 {
00338 refreshKeyIds(ids);
00339 }
00340
00341 void
00342 KGpgItemModel::refreshKeyIds(const QStringList &ids)
00343 {
00344 emit layoutAboutToBeChanged();
00345 if (ids.isEmpty()) {
00346 for (int i = m_root->getChildCount() - 1; i >= 0; i--) {
00347 KGpgNode *nd = m_root->getChild(i);
00348 if (nd->getType() == ITYPE_GROUP)
00349 continue;
00350 delete nd;
00351 }
00352 } else {
00353 QStringList::ConstIterator it = ids.constBegin();
00354 const QStringList::ConstIterator itEnd = ids.constEnd();
00355
00356 for (; it != itEnd; ++it) {
00357 KGpgKeyNode *nd = m_root->findKey(*it);
00358 delete nd;
00359 }
00360 }
00361
00362 m_root->addKeys(ids);
00363 fixPersistentIndexes();
00364 emit layoutChanged();
00365 }
00366
00367 void
00368 KGpgItemModel::refreshKeyIds(KGpgKeyNodeList &nodes)
00369 {
00370 QStringList ids;
00371
00372 emit layoutAboutToBeChanged();
00373 m_root->refreshKeys(nodes);
00374 fixPersistentIndexes();
00375 emit layoutChanged();
00376 }
00377
00378 void
00379 KGpgItemModel::refreshGroups()
00380 {
00381 emit layoutAboutToBeChanged();
00382 for (int i = m_root->getChildCount() - 1; i >= 0; i--) {
00383 KGpgNode *nd = m_root->getChild(i);
00384 if (nd->getType() == ITYPE_GROUP)
00385 delete nd;
00386 }
00387
00388 m_root->addGroups();
00389 fixPersistentIndexes();
00390 emit layoutChanged();
00391 }
00392
00393 bool
00394 KGpgItemModel::isDefaultKey(const KGpgNode *node) const
00395 {
00396 return !m_default.isEmpty() && (m_default == node->getId().right(m_default.length()));
00397 }
00398
00399 void
00400 KGpgItemModel::fixPersistentIndexes()
00401 {
00402 if (persistentIndexList().isEmpty())
00403 return;
00404
00405 QModelIndexList newidx;
00406
00407 for (int i = 0; i < persistentIndexList().count(); i++) {
00408 QModelIndex idx = persistentIndexList().at(i);
00409
00410 if (!idx.isValid())
00411 continue;
00412
00413 KGpgNode *nd = nodeForIndex(idx);
00414 int j = rowForNode(nd);
00415 if (j == idx.row())
00416 continue;
00417
00418
00419 kDebug(3125) << i << nd << idx.column() << "row" << idx.row() << "new row" << j;
00420
00421 if (j >= 0)
00422 changePersistentIndex(idx, createIndex(j, idx.column(), nd));
00423 else
00424 changePersistentIndex(idx, QModelIndex());
00425 }
00426 }
00427
00428 void
00429 KGpgItemModel::invalidateIndexes(KGpgNode *nd)
00430 {
00431 for (int i = 0; i < persistentIndexList().count(); i++) {
00432 QModelIndex idx = persistentIndexList().at(i);
00433
00434 KGpgNode *n = nodeForIndex(idx);
00435
00436 if (n != nd)
00437 continue;
00438
00439 changePersistentIndex(idx, QModelIndex());
00440 }
00441 }
00442
00443 void
00444 KGpgItemModel::refreshTrust(const KgpgCore::KgpgKeyTrust &trust, const QColor &color)
00445 {
00446 updateNodeTrustColor(m_root, trust, color);
00447 }
00448
00449 void
00450 KGpgItemModel::updateNodeTrustColor(KGpgExpandableNode *node, const KgpgCore::KgpgKeyTrust &trust, const QColor &color)
00451 {
00452 for (int i = 0; i < node->getChildCount(); i++) {
00453 KGpgNode *child = node->getChild(i);
00454
00455 if (child->getTrust() == trust)
00456 emit dataChanged(createIndex(i, KEYCOLUMN_TRUST, child), createIndex(i, KEYCOLUMN_TRUST, child));
00457
00458 if (!child->hasChildren())
00459 continue;
00460
00461 KGpgExpandableNode *echild = static_cast<KGpgExpandableNode *>(child);
00462 if (echild->wasExpanded())
00463 updateNodeTrustColor(echild, trust, color);
00464 }
00465 }