~ubuntu-branches/ubuntu/precise/gwenview/precise-proposed

« back to all changes in this revision

Viewing changes to lib/semanticinfo/semanticinfodirmodel.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2011-12-15 14:17:54 UTC
  • mto: This revision was merged to the branch mainline in revision 12.
  • Revision ID: package-import@ubuntu.com-20111215141754-z043hyx69dulbggf
Tags: upstream-4.7.90
ImportĀ upstreamĀ versionĀ 4.7.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// vim: set tabstop=4 shiftwidth=4 noexpandtab:
 
1
// vim: set tabstop=4 shiftwidth=4 expandtab:
2
2
/*
3
3
Gwenview: an image viewer
4
4
Copyright 2008 AurĆ©lien GĆ¢teau <agateau@kde.org>
40
40
 
41
41
#else
42
42
#ifdef __GNUC__
43
 
        #error No metadata backend defined
 
43
#error No metadata backend defined
44
44
#endif
45
45
#endif
46
46
 
47
 
namespace Gwenview {
 
47
namespace Gwenview
 
48
{
48
49
 
49
50
struct SemanticInfoCacheItem {
50
 
        SemanticInfoCacheItem()
51
 
        : mValid(false) {}
52
 
        QPersistentModelIndex mIndex;
53
 
        bool mValid;
54
 
        SemanticInfo mInfo;
 
51
    SemanticInfoCacheItem()
 
52
        : mValid(false) {}
 
53
    QPersistentModelIndex mIndex;
 
54
    bool mValid;
 
55
    SemanticInfo mInfo;
55
56
};
56
57
 
57
 
 
58
58
typedef QHash<KUrl, SemanticInfoCacheItem> SemanticInfoCache;
59
59
 
60
60
struct SemanticInfoDirModelPrivate {
61
 
        SemanticInfoCache mSemanticInfoCache;
62
 
        AbstractSemanticInfoBackEnd* mBackEnd;
 
61
    SemanticInfoCache mSemanticInfoCache;
 
62
    AbstractSemanticInfoBackEnd* mBackEnd;
63
63
};
64
64
 
65
 
 
66
65
SemanticInfoDirModel::SemanticInfoDirModel(QObject* parent)
67
66
: KDirModel(parent)
68
 
, d(new SemanticInfoDirModelPrivate) {
 
67
, d(new SemanticInfoDirModelPrivate)
 
68
{
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);
73
73
#endif
74
74
 
75
 
        connect(d->mBackEnd, SIGNAL(semanticInfoRetrieved(const KUrl&, const SemanticInfo&)),
76
 
                SLOT(slotSemanticInfoRetrieved(const KUrl&, const SemanticInfo&)),
77
 
                Qt::QueuedConnection);
78
 
 
79
 
        connect(this, SIGNAL(modelAboutToBeReset()),
80
 
                SLOT(slotModelAboutToBeReset()) );
81
 
 
82
 
        connect(this, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)),
83
 
                SLOT(slotRowsAboutToBeRemoved(const QModelIndex&, int, int)) );
84
 
}
85
 
 
86
 
 
87
 
SemanticInfoDirModel::~SemanticInfoDirModel() {
88
 
        delete d;
89
 
}
90
 
 
91
 
 
92
 
void SemanticInfoDirModel::clearSemanticInfoCache() {
93
 
        d->mSemanticInfoCache.clear();
94
 
}
95
 
 
96
 
 
97
 
bool SemanticInfoDirModel::semanticInfoAvailableForIndex(const QModelIndex& index) const {
98
 
        if (!index.isValid()) {
99
 
                return false;
100
 
        }
101
 
        KFileItem item = itemForIndex(index);
102
 
        if (item.isNull()) {
103
 
                return false;
104
 
        }
105
 
        SemanticInfoCache::const_iterator it = d->mSemanticInfoCache.constFind(item.targetUrl());
106
 
        if (it == d->mSemanticInfoCache.constEnd()) {
107
 
                return false;
108
 
        }
109
 
        return it.value().mValid;
110
 
}
111
 
 
112
 
 
113
 
SemanticInfo SemanticInfoDirModel::semanticInfoForIndex(const QModelIndex& index) const {
114
 
        if (!index.isValid()) {
115
 
                kWarning() << "invalid index";
116
 
                return SemanticInfo();
117
 
        }
118
 
        KFileItem item = itemForIndex(index);
119
 
        if (item.isNull()) {
120
 
                kWarning() << "no item for index";
121
 
                return SemanticInfo();
122
 
        }
123
 
        return d->mSemanticInfoCache.value(item.targetUrl()).mInfo;
124
 
}
125
 
 
126
 
 
127
 
void SemanticInfoDirModel::retrieveSemanticInfoForIndex(const QModelIndex& index) {
128
 
        if (!index.isValid()) {
129
 
                return;
130
 
        }
131
 
        KFileItem item = itemForIndex(index);
132
 
        if (item.isNull()) {
133
 
                kWarning() << "invalid item";
134
 
                return;
135
 
        }
136
 
        if (ArchiveUtils::fileItemIsDirOrArchive(item)) {
137
 
                return;
138
 
        }
139
 
        SemanticInfoCacheItem cacheItem;
140
 
        cacheItem.mIndex = QPersistentModelIndex(index);
141
 
        d->mSemanticInfoCache[item.targetUrl()] = cacheItem;
142
 
        d->mBackEnd->retrieveSemanticInfo(item.targetUrl());
143
 
}
144
 
 
145
 
 
146
 
QVariant SemanticInfoDirModel::data(const QModelIndex& index, int role) const {
147
 
        if (role == RatingRole || role == DescriptionRole || role == TagsRole) {
148
 
                KFileItem item = itemForIndex(index);
149
 
                if (item.isNull()) {
150
 
                        return QVariant();
151
 
                }
152
 
                SemanticInfoCache::ConstIterator it = d->mSemanticInfoCache.constFind(item.targetUrl());
153
 
                if (it != d->mSemanticInfoCache.constEnd()) {
154
 
                        if (!it.value().mValid) {
155
 
                                return QVariant();
156
 
                        }
157
 
                        const SemanticInfo& info = it.value().mInfo;
158
 
                        if (role == RatingRole) {
159
 
                                return info.mRating;
160
 
                        } else if (role == DescriptionRole) {
161
 
                                return info.mDescription;
162
 
                        } else if (role == TagsRole) {
163
 
                                return info.mTags.toVariant();
164
 
                        } else {
165
 
                                // We should never reach this part
166
 
                                Q_ASSERT(0);
167
 
                                return QVariant();
168
 
                        }
169
 
                } else {
170
 
                        const_cast<SemanticInfoDirModel*>(this)->retrieveSemanticInfoForIndex(index);
171
 
                        return QVariant();
172
 
                }
173
 
        } else {
174
 
                return KDirModel::data(index, role);
175
 
        }
176
 
}
177
 
 
178
 
 
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);
182
 
                if (item.isNull()) {
183
 
                        kWarning() << "no item found for this index";
184
 
                        return false;
185
 
                }
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;
190
 
                        return false;
191
 
                }
192
 
                if (!it.value().mValid) {
193
 
                        kWarning() << "Semantic info cache for" << url << "is invalid";
194
 
                        return false;
195
 
                }
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);
203
 
                } else {
204
 
                        // We should never reach this part
205
 
                        Q_ASSERT(0);
206
 
                }
207
 
                emit dataChanged(index, index);
208
 
 
209
 
                d->mBackEnd->storeSemanticInfo(url, semanticInfo);
210
 
                return true;
211
 
        } else {
212
 
                return KDirModel::setData(index, data, role);
213
 
        }
214
 
}
215
 
 
216
 
 
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;
221
 
                return;
222
 
        }
223
 
        SemanticInfoCacheItem& cacheItem = it.value();
224
 
        if (!cacheItem.mIndex.isValid()) {
225
 
                kWarning() << "Index for" << url << "is invalid";
226
 
                return;
227
 
        }
228
 
        cacheItem.mInfo = semanticInfo;
229
 
        cacheItem.mValid = true;
230
 
        emit dataChanged(cacheItem.mIndex, cacheItem.mIndex);
231
 
}
232
 
 
233
 
 
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);
238
 
                if (item.isNull()) {
239
 
                        continue;
240
 
                }
241
 
                d->mSemanticInfoCache.remove(item.targetUrl());
242
 
        }
243
 
}
244
 
 
245
 
 
246
 
void SemanticInfoDirModel::slotModelAboutToBeReset() {
247
 
        d->mSemanticInfoCache.clear();
248
 
}
249
 
 
250
 
 
251
 
AbstractSemanticInfoBackEnd* SemanticInfoDirModel::semanticInfoBackEnd() const {
252
 
        return d->mBackEnd;
253
 
}
254
 
 
 
75
    connect(d->mBackEnd, SIGNAL(semanticInfoRetrieved(KUrl, SemanticInfo)),
 
76
            SLOT(slotSemanticInfoRetrieved(KUrl, SemanticInfo)),
 
77
            Qt::QueuedConnection);
 
78
 
 
79
    connect(this, SIGNAL(modelAboutToBeReset()),
 
80
            SLOT(slotModelAboutToBeReset()));
 
81
 
 
82
    connect(this, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)),
 
83
            SLOT(slotRowsAboutToBeRemoved(QModelIndex, int, int)));
 
84
}
 
85
 
 
86
SemanticInfoDirModel::~SemanticInfoDirModel()
 
87
{
 
88
    delete d;
 
89
}
 
90
 
 
91
void SemanticInfoDirModel::clearSemanticInfoCache()
 
92
{
 
93
    d->mSemanticInfoCache.clear();
 
94
}
 
95
 
 
96
bool SemanticInfoDirModel::semanticInfoAvailableForIndex(const QModelIndex& index) const
 
97
{
 
98
    if (!index.isValid()) {
 
99
        return false;
 
100
    }
 
101
    KFileItem item = itemForIndex(index);
 
102
    if (item.isNull()) {
 
103
        return false;
 
104
    }
 
105
    SemanticInfoCache::const_iterator it = d->mSemanticInfoCache.constFind(item.targetUrl());
 
106
    if (it == d->mSemanticInfoCache.constEnd()) {
 
107
        return false;
 
108
    }
 
109
    return it.value().mValid;
 
110
}
 
111
 
 
112
SemanticInfo SemanticInfoDirModel::semanticInfoForIndex(const QModelIndex& index) const
 
113
{
 
114
    if (!index.isValid()) {
 
115
        kWarning() << "invalid index";
 
116
        return SemanticInfo();
 
117
    }
 
118
    KFileItem item = itemForIndex(index);
 
119
    if (item.isNull()) {
 
120
        kWarning() << "no item for index";
 
121
        return SemanticInfo();
 
122
    }
 
123
    return d->mSemanticInfoCache.value(item.targetUrl()).mInfo;
 
124
}
 
125
 
 
126
void SemanticInfoDirModel::retrieveSemanticInfoForIndex(const QModelIndex& index)
 
127
{
 
128
    if (!index.isValid()) {
 
129
        return;
 
130
    }
 
131
    KFileItem item = itemForIndex(index);
 
132
    if (item.isNull()) {
 
133
        kWarning() << "invalid item";
 
134
        return;
 
135
    }
 
136
    if (ArchiveUtils::fileItemIsDirOrArchive(item)) {
 
137
        return;
 
138
    }
 
139
    SemanticInfoCacheItem cacheItem;
 
140
    cacheItem.mIndex = QPersistentModelIndex(index);
 
141
    d->mSemanticInfoCache[item.targetUrl()] = cacheItem;
 
142
    d->mBackEnd->retrieveSemanticInfo(item.targetUrl());
 
143
}
 
144
 
 
145
QVariant SemanticInfoDirModel::data(const QModelIndex& index, int role) const
 
146
{
 
147
    if (role == RatingRole || role == DescriptionRole || role == TagsRole) {
 
148
        KFileItem item = itemForIndex(index);
 
149
        if (item.isNull()) {
 
150
            return QVariant();
 
151
        }
 
152
        SemanticInfoCache::ConstIterator it = d->mSemanticInfoCache.constFind(item.targetUrl());
 
153
        if (it != d->mSemanticInfoCache.constEnd()) {
 
154
            if (!it.value().mValid) {
 
155
                return QVariant();
 
156
            }
 
157
            const SemanticInfo& info = it.value().mInfo;
 
158
            if (role == RatingRole) {
 
159
                return info.mRating;
 
160
            } else if (role == DescriptionRole) {
 
161
                return info.mDescription;
 
162
            } else if (role == TagsRole) {
 
163
                return info.mTags.toVariant();
 
164
            } else {
 
165
                // We should never reach this part
 
166
                Q_ASSERT(0);
 
167
                return QVariant();
 
168
            }
 
169
        } else {
 
170
            const_cast<SemanticInfoDirModel*>(this)->retrieveSemanticInfoForIndex(index);
 
171
            return QVariant();
 
172
        }
 
173
    } else {
 
174
        return KDirModel::data(index, role);
 
175
    }
 
176
}
 
177
 
 
178
bool SemanticInfoDirModel::setData(const QModelIndex& index, const QVariant& data, int role)
 
179
{
 
180
    if (role == RatingRole || role == DescriptionRole || role == TagsRole) {
 
181
        KFileItem item = itemForIndex(index);
 
182
        if (item.isNull()) {
 
183
            kWarning() << "no item found for this index";
 
184
            return false;
 
185
        }
 
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;
 
190
            return false;
 
191
        }
 
192
        if (!it.value().mValid) {
 
193
            kWarning() << "Semantic info cache for" << url << "is invalid";
 
194
            return false;
 
195
        }
 
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);
 
203
        } else {
 
204
            // We should never reach this part
 
205
            Q_ASSERT(0);
 
206
        }
 
207
        emit dataChanged(index, index);
 
208
 
 
209
        d->mBackEnd->storeSemanticInfo(url, semanticInfo);
 
210
        return true;
 
211
    } else {
 
212
        return KDirModel::setData(index, data, role);
 
213
    }
 
214
}
 
215
 
 
216
void SemanticInfoDirModel::slotSemanticInfoRetrieved(const KUrl& url, const SemanticInfo& semanticInfo)
 
217
{
 
218
    SemanticInfoCache::iterator it = d->mSemanticInfoCache.find(url);
 
219
    if (it == d->mSemanticInfoCache.end()) {
 
220
        kWarning() << "No index for" << url;
 
221
        return;
 
222
    }
 
223
    SemanticInfoCacheItem& cacheItem = it.value();
 
224
    if (!cacheItem.mIndex.isValid()) {
 
225
        kWarning() << "Index for" << url << "is invalid";
 
226
        return;
 
227
    }
 
228
    cacheItem.mInfo = semanticInfo;
 
229
    cacheItem.mValid = true;
 
230
    emit dataChanged(cacheItem.mIndex, cacheItem.mIndex);
 
231
}
 
232
 
 
233
void SemanticInfoDirModel::slotRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end)
 
234
{
 
235
    for (int pos = start; pos <= end; ++pos) {
 
236
        QModelIndex idx = index(pos, 0, parent);
 
237
        KFileItem item = itemForIndex(idx);
 
238
        if (item.isNull()) {
 
239
            continue;
 
240
        }
 
241
        d->mSemanticInfoCache.remove(item.targetUrl());
 
242
    }
 
243
}
 
244
 
 
245
void SemanticInfoDirModel::slotModelAboutToBeReset()
 
246
{
 
247
    d->mSemanticInfoCache.clear();
 
248
}
 
249
 
 
250
AbstractSemanticInfoBackEnd* SemanticInfoDirModel::semanticInfoBackEnd() const
 
251
{
 
252
    return d->mBackEnd;
 
253
}
255
254
 
256
255
} // namespace