1 /***************************************************************************
2 * Copyright (C) 2004-2018 by Thomas Fischer <fischer@unix-ag.uni-kl.de> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, see <https://www.gnu.org/licenses/>. *
16 ***************************************************************************/
17
18 #include "collectionmodel.h"
19
20 #include <QHash>
21
22 #include <QIcon>
23
24 #include "zotero/collection.h"
25
26 using namespace Zotero;
27
28 const int Zotero::CollectionModel::CollectionIdRole = Qt::UserRole + 6681;
29
30 class Zotero::CollectionModel::Private
31 {
32 public:
Private(Collection * c,Zotero::CollectionModel * parent)33 Private(Collection *c, Zotero::CollectionModel *parent)
34 : collection(c) {
35 Q_UNUSED(parent)
36 }
37
38 Collection *collection;
39
40 QHash<QString, QModelIndex> collectionIdToModelIndex;
41 };
42
CollectionModel(Collection * collection,QObject * parent)43 CollectionModel::CollectionModel(Collection *collection, QObject *parent)
44 : QAbstractItemModel(parent), d(new Zotero::CollectionModel::Private(collection, this))
45 {
46 beginResetModel();
47 connect(collection, &Collection::finishedLoading, this, &CollectionModel::fetchingDone);
48 }
49
data(const QModelIndex & index,int role) const50 QVariant CollectionModel::data(const QModelIndex &index, int role) const
51 {
52 if (!d->collection->initialized())
53 return QVariant();
54
55 if (index == QModelIndex())
56 return QVariant();
57
58 if (role == Qt::DecorationRole) {
59 /// Fancy icons for collections
60 if (index.internalId() == 0) /// root node
61 return QIcon::fromTheme(QStringLiteral("folder-orange"));
62 else /// any other node
63 return QIcon::fromTheme(QStringLiteral("folder-yellow"));
64 } else if (role == Qt::DisplayRole) {
65 /// Show collections' human-readable description
66 const QString collectionId = d->collection->collectionFromNumericId(index.internalId());
67 return d->collection->collectionLabel(collectionId);
68 } else if (role == CollectionIdRole) {
69 if (index.internalId() == 0) /// root node
70 return QString();
71 else /// any other node
72 return d->collection->collectionFromNumericId(index.internalId());
73 }
74
75 return QVariant();
76 }
77
index(int row,int column,const QModelIndex & parent) const78 QModelIndex CollectionModel::index(int row, int column, const QModelIndex &parent) const
79 {
80 if (!d->collection->initialized())
81 return QModelIndex();
82
83 if (parent == QModelIndex()) { ///< root node
84 const QModelIndex result = createIndex(row, column, (quintptr)0);
85 d->collectionIdToModelIndex.insert(d->collection->collectionFromNumericId(0), result);
86 return result;
87 }
88
89 const QString collectionId = d->collection->collectionFromNumericId(parent.internalId());
90 QVector<QString> children = d->collection->collectionChildren(collectionId);
91 if (row < children.count()) {
92 const QModelIndex result = createIndex(row, column, d->collection->collectionNumericId(children[row]));
93 d->collectionIdToModelIndex.insert(children[row], result);
94 return result;
95 }
96
97 return QModelIndex();
98 }
99
parent(const QModelIndex & index) const100 QModelIndex CollectionModel::parent(const QModelIndex &index) const
101 {
102 if (!d->collection->initialized())
103 return QModelIndex();
104
105 if (index == QModelIndex() || index.internalId() == 0)
106 return QModelIndex(); ///< invalid index or root node
107
108 const QString parentId = d->collection->collectionParent(d->collection->collectionFromNumericId(index.internalId()));
109 return d->collectionIdToModelIndex[parentId];
110 }
111
rowCount(const QModelIndex & parent) const112 int CollectionModel::rowCount(const QModelIndex &parent) const
113 {
114 if (!d->collection->initialized())
115 return 0;
116
117 if (parent == QModelIndex())
118 return 1; ///< just one single root node
119
120 const QString collectionId = d->collection->collectionFromNumericId(parent.internalId());
121 QVector<QString> children = d->collection->collectionChildren(collectionId);
122 return children.count();
123 }
124
columnCount(const QModelIndex &) const125 int CollectionModel::columnCount(const QModelIndex &) const
126 {
127 /// Singe column design;
128 return 1;
129 }
130
hasChildren(const QModelIndex & parent) const131 bool CollectionModel::hasChildren(const QModelIndex &parent) const
132 {
133 if (!d->collection->initialized())
134 return false;
135
136 return rowCount(parent) > 0;
137 }
138
fetchingDone()139 void CollectionModel::fetchingDone()
140 {
141 endResetModel();
142 }
143