43
#error No metadata backend defined
43
#error No metadata backend defined
49
50
struct SemanticInfoCacheItem {
50
SemanticInfoCacheItem()
52
QPersistentModelIndex mIndex;
51
SemanticInfoCacheItem()
53
QPersistentModelIndex mIndex;
58
58
typedef QHash<KUrl, SemanticInfoCacheItem> SemanticInfoCache;
60
60
struct SemanticInfoDirModelPrivate {
61
SemanticInfoCache mSemanticInfoCache;
62
AbstractSemanticInfoBackEnd* mBackEnd;
61
SemanticInfoCache mSemanticInfoCache;
62
AbstractSemanticInfoBackEnd* mBackEnd;
66
65
SemanticInfoDirModel::SemanticInfoDirModel(QObject* parent)
67
66
: KDirModel(parent)
68
, d(new SemanticInfoDirModelPrivate) {
67
, d(new SemanticInfoDirModelPrivate)
69
69
#ifdef GWENVIEW_SEMANTICINFO_BACKEND_FAKE
70
d->mBackEnd = new FakeSemanticInfoBackEnd(this, FakeSemanticInfoBackEnd::InitializeRandom);
70
d->mBackEnd = new FakeSemanticInfoBackEnd(this, FakeSemanticInfoBackEnd::InitializeRandom);
71
71
#elif defined(GWENVIEW_SEMANTICINFO_BACKEND_NEPOMUK)
72
d->mBackEnd = new NepomukSemanticInfoBackEnd(this);
72
d->mBackEnd = new NepomukSemanticInfoBackEnd(this);
75
connect(d->mBackEnd, SIGNAL(semanticInfoRetrieved(const KUrl&, const SemanticInfo&)),
76
SLOT(slotSemanticInfoRetrieved(const KUrl&, const SemanticInfo&)),
77
Qt::QueuedConnection);
79
connect(this, SIGNAL(modelAboutToBeReset()),
80
SLOT(slotModelAboutToBeReset()) );
82
connect(this, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)),
83
SLOT(slotRowsAboutToBeRemoved(const QModelIndex&, int, int)) );
87
SemanticInfoDirModel::~SemanticInfoDirModel() {
92
void SemanticInfoDirModel::clearSemanticInfoCache() {
93
d->mSemanticInfoCache.clear();
97
bool SemanticInfoDirModel::semanticInfoAvailableForIndex(const QModelIndex& index) const {
98
if (!index.isValid()) {
101
KFileItem item = itemForIndex(index);
105
SemanticInfoCache::const_iterator it = d->mSemanticInfoCache.constFind(item.targetUrl());
106
if (it == d->mSemanticInfoCache.constEnd()) {
109
return it.value().mValid;
113
SemanticInfo SemanticInfoDirModel::semanticInfoForIndex(const QModelIndex& index) const {
114
if (!index.isValid()) {
115
kWarning() << "invalid index";
116
return SemanticInfo();
118
KFileItem item = itemForIndex(index);
120
kWarning() << "no item for index";
121
return SemanticInfo();
123
return d->mSemanticInfoCache.value(item.targetUrl()).mInfo;
127
void SemanticInfoDirModel::retrieveSemanticInfoForIndex(const QModelIndex& index) {
128
if (!index.isValid()) {
131
KFileItem item = itemForIndex(index);
133
kWarning() << "invalid item";
136
if (ArchiveUtils::fileItemIsDirOrArchive(item)) {
139
SemanticInfoCacheItem cacheItem;
140
cacheItem.mIndex = QPersistentModelIndex(index);
141
d->mSemanticInfoCache[item.targetUrl()] = cacheItem;
142
d->mBackEnd->retrieveSemanticInfo(item.targetUrl());
146
QVariant SemanticInfoDirModel::data(const QModelIndex& index, int role) const {
147
if (role == RatingRole || role == DescriptionRole || role == TagsRole) {
148
KFileItem item = itemForIndex(index);
152
SemanticInfoCache::ConstIterator it = d->mSemanticInfoCache.constFind(item.targetUrl());
153
if (it != d->mSemanticInfoCache.constEnd()) {
154
if (!it.value().mValid) {
157
const SemanticInfo& info = it.value().mInfo;
158
if (role == RatingRole) {
160
} else if (role == DescriptionRole) {
161
return info.mDescription;
162
} else if (role == TagsRole) {
163
return info.mTags.toVariant();
165
// We should never reach this part
170
const_cast<SemanticInfoDirModel*>(this)->retrieveSemanticInfoForIndex(index);
174
return KDirModel::data(index, role);
179
bool SemanticInfoDirModel::setData(const QModelIndex& index, const QVariant& data, int role) {
180
if (role == RatingRole || role == DescriptionRole || role == TagsRole) {
181
KFileItem item = itemForIndex(index);
183
kWarning() << "no item found for this index";
186
KUrl url = item.targetUrl();
187
SemanticInfoCache::iterator it = d->mSemanticInfoCache.find(url);
188
if (it == d->mSemanticInfoCache.end()) {
189
kWarning() << "No index for" << url;
192
if (!it.value().mValid) {
193
kWarning() << "Semantic info cache for" << url << "is invalid";
196
SemanticInfo& semanticInfo = it.value().mInfo;
197
if (role == RatingRole) {
198
semanticInfo.mRating = data.toInt();
199
} else if (role == DescriptionRole) {
200
semanticInfo.mDescription = data.toString();
201
} else if (role == TagsRole) {
202
semanticInfo.mTags = TagSet::fromVariant(data);
204
// We should never reach this part
207
emit dataChanged(index, index);
209
d->mBackEnd->storeSemanticInfo(url, semanticInfo);
212
return KDirModel::setData(index, data, role);
217
void SemanticInfoDirModel::slotSemanticInfoRetrieved(const KUrl& url, const SemanticInfo& semanticInfo) {
218
SemanticInfoCache::iterator it = d->mSemanticInfoCache.find(url);
219
if (it == d->mSemanticInfoCache.end()) {
220
kWarning() << "No index for" << url;
223
SemanticInfoCacheItem& cacheItem = it.value();
224
if (!cacheItem.mIndex.isValid()) {
225
kWarning() << "Index for" << url << "is invalid";
228
cacheItem.mInfo = semanticInfo;
229
cacheItem.mValid = true;
230
emit dataChanged(cacheItem.mIndex, cacheItem.mIndex);
234
void SemanticInfoDirModel::slotRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) {
235
for (int pos = start; pos <= end; ++pos) {
236
QModelIndex idx = index(pos, 0, parent);
237
KFileItem item = itemForIndex(idx);
241
d->mSemanticInfoCache.remove(item.targetUrl());
246
void SemanticInfoDirModel::slotModelAboutToBeReset() {
247
d->mSemanticInfoCache.clear();
251
AbstractSemanticInfoBackEnd* SemanticInfoDirModel::semanticInfoBackEnd() const {
75
connect(d->mBackEnd, SIGNAL(semanticInfoRetrieved(KUrl, SemanticInfo)),
76
SLOT(slotSemanticInfoRetrieved(KUrl, SemanticInfo)),
77
Qt::QueuedConnection);
79
connect(this, SIGNAL(modelAboutToBeReset()),
80
SLOT(slotModelAboutToBeReset()));
82
connect(this, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)),
83
SLOT(slotRowsAboutToBeRemoved(QModelIndex, int, int)));
86
SemanticInfoDirModel::~SemanticInfoDirModel()
91
void SemanticInfoDirModel::clearSemanticInfoCache()
93
d->mSemanticInfoCache.clear();
96
bool SemanticInfoDirModel::semanticInfoAvailableForIndex(const QModelIndex& index) const
98
if (!index.isValid()) {
101
KFileItem item = itemForIndex(index);
105
SemanticInfoCache::const_iterator it = d->mSemanticInfoCache.constFind(item.targetUrl());
106
if (it == d->mSemanticInfoCache.constEnd()) {
109
return it.value().mValid;
112
SemanticInfo SemanticInfoDirModel::semanticInfoForIndex(const QModelIndex& index) const
114
if (!index.isValid()) {
115
kWarning() << "invalid index";
116
return SemanticInfo();
118
KFileItem item = itemForIndex(index);
120
kWarning() << "no item for index";
121
return SemanticInfo();
123
return d->mSemanticInfoCache.value(item.targetUrl()).mInfo;
126
void SemanticInfoDirModel::retrieveSemanticInfoForIndex(const QModelIndex& index)
128
if (!index.isValid()) {
131
KFileItem item = itemForIndex(index);
133
kWarning() << "invalid item";
136
if (ArchiveUtils::fileItemIsDirOrArchive(item)) {
139
SemanticInfoCacheItem cacheItem;
140
cacheItem.mIndex = QPersistentModelIndex(index);
141
d->mSemanticInfoCache[item.targetUrl()] = cacheItem;
142
d->mBackEnd->retrieveSemanticInfo(item.targetUrl());
145
QVariant SemanticInfoDirModel::data(const QModelIndex& index, int role) const
147
if (role == RatingRole || role == DescriptionRole || role == TagsRole) {
148
KFileItem item = itemForIndex(index);
152
SemanticInfoCache::ConstIterator it = d->mSemanticInfoCache.constFind(item.targetUrl());
153
if (it != d->mSemanticInfoCache.constEnd()) {
154
if (!it.value().mValid) {
157
const SemanticInfo& info = it.value().mInfo;
158
if (role == RatingRole) {
160
} else if (role == DescriptionRole) {
161
return info.mDescription;
162
} else if (role == TagsRole) {
163
return info.mTags.toVariant();
165
// We should never reach this part
170
const_cast<SemanticInfoDirModel*>(this)->retrieveSemanticInfoForIndex(index);
174
return KDirModel::data(index, role);
178
bool SemanticInfoDirModel::setData(const QModelIndex& index, const QVariant& data, int role)
180
if (role == RatingRole || role == DescriptionRole || role == TagsRole) {
181
KFileItem item = itemForIndex(index);
183
kWarning() << "no item found for this index";
186
KUrl url = item.targetUrl();
187
SemanticInfoCache::iterator it = d->mSemanticInfoCache.find(url);
188
if (it == d->mSemanticInfoCache.end()) {
189
kWarning() << "No index for" << url;
192
if (!it.value().mValid) {
193
kWarning() << "Semantic info cache for" << url << "is invalid";
196
SemanticInfo& semanticInfo = it.value().mInfo;
197
if (role == RatingRole) {
198
semanticInfo.mRating = data.toInt();
199
} else if (role == DescriptionRole) {
200
semanticInfo.mDescription = data.toString();
201
} else if (role == TagsRole) {
202
semanticInfo.mTags = TagSet::fromVariant(data);
204
// We should never reach this part
207
emit dataChanged(index, index);
209
d->mBackEnd->storeSemanticInfo(url, semanticInfo);
212
return KDirModel::setData(index, data, role);
216
void SemanticInfoDirModel::slotSemanticInfoRetrieved(const KUrl& url, const SemanticInfo& semanticInfo)
218
SemanticInfoCache::iterator it = d->mSemanticInfoCache.find(url);
219
if (it == d->mSemanticInfoCache.end()) {
220
kWarning() << "No index for" << url;
223
SemanticInfoCacheItem& cacheItem = it.value();
224
if (!cacheItem.mIndex.isValid()) {
225
kWarning() << "Index for" << url << "is invalid";
228
cacheItem.mInfo = semanticInfo;
229
cacheItem.mValid = true;
230
emit dataChanged(cacheItem.mIndex, cacheItem.mIndex);
233
void SemanticInfoDirModel::slotRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end)
235
for (int pos = start; pos <= end; ++pos) {
236
QModelIndex idx = index(pos, 0, parent);
237
KFileItem item = itemForIndex(idx);
241
d->mSemanticInfoCache.remove(item.targetUrl());
245
void SemanticInfoDirModel::slotModelAboutToBeReset()
247
d->mSemanticInfoCache.clear();
250
AbstractSemanticInfoBackEnd* SemanticInfoDirModel::semanticInfoBackEnd() const