~ubuntu-branches/ubuntu/saucy/digikam/saucy

« back to all changes in this revision

Viewing changes to libs/models/albumfiltermodel.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Christian Mangold
  • Date: 2010-04-09 21:30:01 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100409213001-4bfyibrd359rn7o3
Tags: 2:1.2.0-0ubuntu1
* New upstream release (LP: #560576)
* Remove all patches, fixed upstream
  - Remove quilt build-depend

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
 * Description : Qt Model for Albums - filter model
8
8
 *
9
9
 * Copyright (C) 2008-2009 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
 
10
 * Copyright (C) 2009 by Johannes Wienke <languitar at semipol dot de>
10
11
 *
11
12
 * This program is free software; you can redistribute it
12
13
 * and/or modify it under the terms of the GNU General
29
30
 
30
31
// KDE includes
31
32
 
 
33
#include <kdebug.h>
32
34
#include <kstringhandler.h>
33
35
 
34
36
// Local includes
35
37
 
36
38
#include "albummodel.h"
 
39
#include "albumsettings.h"
37
40
 
38
41
namespace Digikam
39
42
{
41
44
AlbumFilterModel::AlbumFilterModel(QObject *parent)
42
45
    : QSortFilterProxyModel(parent)
43
46
{
 
47
    m_chainedModel = 0;
44
48
    setDynamicSortFilter(true);
 
49
    setSortRole(AbstractAlbumModel::AlbumSortRole);
 
50
    setSortCaseSensitivity(Qt::CaseInsensitive);
 
51
 
 
52
    // sorting may have changed when the string comparison is different
 
53
    connect(AlbumSettings::instance(), SIGNAL(setupChanged()),
 
54
            this, SLOT(invalidate()));
 
55
 
45
56
}
46
57
 
47
58
void AlbumFilterModel::setSearchTextSettings(const SearchTextSettings& settings)
48
59
{
 
60
 
 
61
    // don't use isFiltering here because it may be reimplemented
 
62
    bool wasSearching = settingsFilter(m_settings);
 
63
    bool willSearch = settingsFilter(settings);
 
64
    emit searchTextSettingsAboutToChange(wasSearching, willSearch);
 
65
 
49
66
    m_settings = settings;
50
67
    invalidateFilter();
51
68
    emit filterChanged();
 
69
 
 
70
    emit searchTextSettingsChanged(wasSearching, willSearch);
 
71
 
 
72
    if (sourceAlbumModel()->albumType() == Album::PHYSICAL)
 
73
    {
 
74
        // find out if this setting has some results or not
 
75
        int validRows = 0;
 
76
        // for every collection we got
 
77
        for(int i = 0; i < rowCount(rootAlbumIndex()); ++i)
 
78
        {
 
79
            QModelIndex collectionIndex = index(i, 0, rootAlbumIndex());
 
80
            // count the number of rows
 
81
            validRows += rowCount(collectionIndex);
 
82
        }
 
83
        bool hasResult = validRows > 0;
 
84
        kDebug() << "new search text settings: " << settings.text
 
85
                << ": hasResult = " << hasResult << ", validRows = "
 
86
                << validRows;
 
87
        emit hasSearchResult(hasResult);
 
88
    }
 
89
    else
 
90
    {
 
91
        QModelIndex head = rootAlbumIndex(); // either root, or invalid, thus toplevel
 
92
        emit hasSearchResult(rowCount(head));
 
93
    }
 
94
}
 
95
 
 
96
bool AlbumFilterModel::settingsFilter(const SearchTextSettings &settings) const
 
97
{
 
98
    return !settings.text.isEmpty();
52
99
}
53
100
 
54
101
bool AlbumFilterModel::isFiltering() const
55
102
{
56
 
    return !m_settings.text.isEmpty();
 
103
    return settingsFilter(m_settings);
57
104
}
58
105
 
59
106
SearchTextSettings AlbumFilterModel::searchTextSettings() const
63
110
 
64
111
void AlbumFilterModel::setSourceAlbumModel(AbstractAlbumModel *source)
65
112
{
 
113
    m_chainedModel = 0;
 
114
    setSourceModel(source);
 
115
}
 
116
 
 
117
void AlbumFilterModel::setSourceAlbumModel(AlbumFilterModel *source)
 
118
{
 
119
    m_chainedModel = source;
66
120
    setSourceModel(source);
67
121
}
68
122
 
74
128
 
75
129
AbstractAlbumModel *AlbumFilterModel::sourceAlbumModel() const
76
130
{
 
131
    if (m_chainedModel)
 
132
        return m_chainedModel->sourceAlbumModel();
77
133
    return static_cast<AbstractAlbumModel*>(sourceModel());
78
134
}
79
135
 
 
136
QModelIndex AlbumFilterModel::mapToSourceAlbumModel(const QModelIndex& index) const
 
137
{
 
138
    if (m_chainedModel)
 
139
        return m_chainedModel->mapToSourceAlbumModel(mapToSource(index));
 
140
    return mapToSource(index);
 
141
}
 
142
 
 
143
QModelIndex AlbumFilterModel::mapFromSourceAlbumModel(const QModelIndex& albummodel_index) const
 
144
{
 
145
    if (m_chainedModel)
 
146
        return mapFromSource(m_chainedModel->mapFromSourceAlbumModel(albummodel_index));
 
147
    return mapFromSource(albummodel_index);
 
148
}
 
149
 
80
150
Album *AlbumFilterModel::albumForIndex(const QModelIndex& index) const
81
151
{
82
 
    return sourceAlbumModel()->albumForIndex(mapToSource(index));
 
152
    return AbstractAlbumModel::retrieveAlbum(index);
83
153
}
84
154
 
85
155
QModelIndex AlbumFilterModel::indexForAlbum(Album *album) const
86
156
{
87
 
    return mapFromSource(sourceAlbumModel()->indexForAlbum(album));
 
157
    return mapFromSourceAlbumModel(sourceAlbumModel()->indexForAlbum(album));
88
158
}
89
159
 
90
160
QModelIndex AlbumFilterModel::rootAlbumIndex() const
91
161
{
92
 
    return mapFromSource(sourceAlbumModel()->rootAlbumIndex());
93
 
}
94
 
 
95
 
AlbumFilterModel::MatchResult AlbumFilterModel::matches(const QModelIndex& index) const
96
 
{
97
 
    return matches(sourceAlbumModel()->albumForIndex(mapToSource(index)));
98
 
}
99
 
 
100
 
AlbumFilterModel::MatchResult AlbumFilterModel::matches(Album *album) const
 
162
    return mapFromSourceAlbumModel(sourceAlbumModel()->rootAlbumIndex());
 
163
}
 
164
 
 
165
bool AlbumFilterModel::matches(Album *album) const
 
166
{
 
167
    // We want to work on the visual representation, so we use model data with AlbumTitleRole,
 
168
    // not a direct Album method.
 
169
    // We use direct source's index, not our index,
 
170
    // because if the item is currently filtered out, we won't have an index for this album.
 
171
    QModelIndex source_index = sourceAlbumModel()->indexForAlbum(album);
 
172
    if (m_chainedModel)
 
173
        source_index = m_chainedModel->mapFromSourceAlbumModel(source_index);
 
174
    QString displayTitle = source_index.data(AbstractAlbumModel::AlbumTitleRole).toString();
 
175
    return displayTitle.contains(m_settings.text, m_settings.caseSensitive);
 
176
}
 
177
 
 
178
AlbumFilterModel::MatchResult AlbumFilterModel::matchResult(const QModelIndex& index) const
 
179
{
 
180
    return matchResult(albumForIndex(index));
 
181
}
 
182
 
 
183
AlbumFilterModel::MatchResult AlbumFilterModel::matchResult(Album *album) const
101
184
{
102
185
    if (!album)
103
186
        return NoMatch;
107
190
    if (album->isRoot() || (palbum && palbum->isAlbumRoot()))
108
191
        return SpecialMatch;
109
192
 
110
 
    if (album->title().contains(m_settings.text, m_settings.caseSensitive))
 
193
    if (matches(album))
111
194
        return TitleMatch;
112
195
 
113
196
    // check if any of the parents match the search
116
199
 
117
200
    while (parent && !(parent->isRoot() || (pparent && pparent->isAlbumRoot()) ) )
118
201
    {
119
 
        if (parent->title().contains(m_settings.text, m_settings.caseSensitive))
 
202
        if (matches(parent))
120
203
            return ParentMatch;
121
204
 
122
205
        parent = parent->parent();
126
209
    AlbumIterator it(album);
127
210
    while (it.current())
128
211
    {
129
 
        if ((*it)->title().contains(m_settings.text, m_settings.caseSensitive))
 
212
        if (matches(*it))
130
213
            return ChildMatch;
131
214
        ++it;
132
215
    }
136
219
 
137
220
bool AlbumFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
138
221
{
139
 
    QModelIndex index = sourceAlbumModel()->index(source_row, 0, source_parent);
140
 
    Album *album = sourceAlbumModel()->albumForIndex(index);
141
 
    if (!album)
142
 
        return false;
143
 
    MatchResult result = matches(album);
 
222
    QModelIndex index = sourceModel()->index(source_row, 0, source_parent);
 
223
    Album *album = AbstractAlbumModel::retrieveAlbum(index);
 
224
    MatchResult result = matchResult(album);
144
225
    return result;
145
226
}
146
227
 
149
230
    QVariant valLeft = left.data(sortRole());
150
231
    QVariant valRight = right.data(sortRole());
151
232
 
152
 
    if (valLeft.type() == QVariant::String && valRight.type() == QVariant::String)
153
 
        return KStringHandler::naturalCompare(valLeft.toString(), valRight.toString(), sortCaseSensitivity()) < 0;
 
233
    if ((valLeft.type() == QVariant::String) && (valRight.type() == QVariant::String))
 
234
        switch (AlbumSettings::instance()->getStringComparisonType())
 
235
        {
 
236
            case AlbumSettings::Natural:
 
237
                return KStringHandler::naturalCompare(valLeft.toString(), valRight.toString(), sortCaseSensitivity()) < 0;
 
238
            case AlbumSettings::Normal:
 
239
            default:
 
240
                return QString::compare(valLeft.toString(), valRight.toString(), sortCaseSensitivity()) < 0;
 
241
        }
154
242
    else
155
243
        return QSortFilterProxyModel::lessThan(left, right);
156
244
}
157
245
 
 
246
// -----------------------------------------------------------------------------
 
247
 
 
248
CheckableAlbumFilterModel::CheckableAlbumFilterModel(QObject *parent) :
 
249
                AlbumFilterModel(parent), m_filterChecked(false),
 
250
                m_filterPartiallyChecked(false)
 
251
{
 
252
}
 
253
 
 
254
void CheckableAlbumFilterModel::setSourceCheckableAlbumModel(AbstractCheckableAlbumModel *source)
 
255
{
 
256
    setSourceModel(source);
 
257
}
 
258
 
 
259
AbstractCheckableAlbumModel *CheckableAlbumFilterModel::sourceAlbumModel() const
 
260
{
 
261
    return dynamic_cast<AbstractCheckableAlbumModel*> (sourceModel());
 
262
}
 
263
 
 
264
void CheckableAlbumFilterModel::setSourceAlbumModel(AbstractAlbumModel *source)
 
265
{
 
266
    AlbumFilterModel::setSourceAlbumModel(source);
 
267
}
 
268
 
 
269
void CheckableAlbumFilterModel::setFilterChecked(bool filter)
 
270
{
 
271
    m_filterChecked = filter;
 
272
    invalidateFilter();
 
273
    emit filterChanged();
 
274
}
 
275
 
 
276
void CheckableAlbumFilterModel::setFilterPartiallyChecked(bool filter)
 
277
{
 
278
    m_filterPartiallyChecked = filter;
 
279
    invalidateFilter();
 
280
    emit filterChanged();
 
281
}
 
282
 
 
283
bool CheckableAlbumFilterModel::isFiltering() const
 
284
{
 
285
    return AlbumFilterModel::isFiltering() || m_filterChecked
 
286
                    || m_filterPartiallyChecked;
 
287
}
 
288
 
 
289
bool CheckableAlbumFilterModel::matches(Album *album) const
 
290
{
 
291
 
 
292
    bool accepted = AlbumFilterModel::matches(album);
 
293
 
 
294
    if (!m_filterChecked && !m_filterPartiallyChecked)
 
295
    {
 
296
        return accepted;
 
297
    }
 
298
 
 
299
    Qt::CheckState state = sourceAlbumModel()->checkState(album);
 
300
 
 
301
    bool stateAccepted = false;
 
302
    if (m_filterPartiallyChecked)
 
303
    {
 
304
        stateAccepted |= state == Qt::PartiallyChecked;
 
305
    }
 
306
    if (m_filterChecked)
 
307
    {
 
308
        stateAccepted |= state == Qt::Checked;
 
309
    }
 
310
 
 
311
    return accepted && stateAccepted;
 
312
 
 
313
}
 
314
 
 
315
 
 
316
// -----------------------------------------------------------------------------
 
317
 
 
318
SearchFilterModel::SearchFilterModel(QObject *parent)
 
319
            : CheckableAlbumFilterModel(parent), m_searchType(-1)
 
320
{
 
321
}
 
322
 
 
323
void SearchFilterModel::setSourceSearchModel(SearchModel *source)
 
324
{
 
325
    setSourceModel(source);
 
326
}
 
327
 
 
328
SearchModel *SearchFilterModel::sourceSearchModel() const
 
329
{
 
330
    return dynamic_cast<SearchModel*> (sourceModel());
 
331
}
 
332
 
 
333
void SearchFilterModel::setFilterSearchType(DatabaseSearch::Type type)
 
334
{
 
335
    setTypeFilter(type);
 
336
}
 
337
 
 
338
void SearchFilterModel::listNormalSearches()
 
339
{
 
340
    setTypeFilter(-1);
 
341
}
 
342
 
 
343
void SearchFilterModel::listAllSearches()
 
344
{
 
345
    setTypeFilter(-2);
 
346
}
 
347
 
 
348
void SearchFilterModel::listTimelineSearches()
 
349
{
 
350
    setTypeFilter(DatabaseSearch::TimeLineSearch);
 
351
}
 
352
 
 
353
void SearchFilterModel::listHaarSearches()
 
354
{
 
355
    setTypeFilter(DatabaseSearch::HaarSearch);
 
356
}
 
357
 
 
358
void SearchFilterModel::listMapSearches()
 
359
{
 
360
    setTypeFilter(DatabaseSearch::MapSearch);
 
361
}
 
362
 
 
363
void SearchFilterModel::listDuplicatesSearches()
 
364
{
 
365
    setTypeFilter(DatabaseSearch::DuplicatesSearch);
 
366
}
 
367
 
 
368
void SearchFilterModel::setTypeFilter(int type)
 
369
{
 
370
    m_searchType = type;
 
371
    invalidateFilter();
 
372
    emit filterChanged();
 
373
}
 
374
 
 
375
void SearchFilterModel::setListTemporarySearches(bool list)
 
376
{
 
377
    m_listTemporary = list;
 
378
    invalidateFilter();
 
379
    emit filterChanged();
 
380
}
 
381
 
 
382
bool SearchFilterModel::isFiltering() const
 
383
{
 
384
    return m_searchType != -2 || !m_listTemporary;
 
385
}
 
386
 
 
387
bool SearchFilterModel::matches(Album *album) const
 
388
{
 
389
    if (!AlbumFilterModel::matches(album))
 
390
        return false;
 
391
 
 
392
    SAlbum *salbum = static_cast<SAlbum*>(album);
 
393
 
 
394
    if (m_searchType == -1)
 
395
    {
 
396
        if (!salbum->isNormalSearch())
 
397
            return false;
 
398
    }
 
399
    else if (m_searchType == -2)
 
400
    {
 
401
    }
 
402
    else
 
403
    {
 
404
        if (salbum->searchType() != (DatabaseSearch::Type)m_searchType)
 
405
            return false;
 
406
    }
 
407
 
 
408
    if (!m_listTemporary && salbum->isTemporarySearch())
 
409
        return false;
 
410
 
 
411
    return true;
 
412
}
 
413
 
 
414
void SearchFilterModel::setSourceAlbumModel(AbstractAlbumModel *source)
 
415
{
 
416
    AlbumFilterModel::setSourceAlbumModel(source);
 
417
}
 
418
 
158
419
} // namespace Digikam