1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418 | /* ============================================================
*
* This file is a part of digiKam project
* https://www.digikam.org
*
* Date : 2009-03-24
* Description : Qt Model for Albums - filter model
*
* SPDX-FileCopyrightText: 2008-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
* SPDX-FileCopyrightText: 2009 by Johannes Wienke <languitar at semipol dot de>
* SPDX-FileCopyrightText: 2014 by Mohamed_Anwer <m_dot_anwer at gmx dot com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* ============================================================ */
#pragma once
// Qt includes
#include <QPointer>
#include <QSortFilterProxyModel>
#include <QTreeView>
// Local includes
#include "albummodel.h"
#include "searchtextbar.h"
#include "digikam_export.h"
namespace Digikam
{
class DIGIKAM_GUI_EXPORT AlbumFilterModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
enum MatchResult
{
/// This enum can be used as a boolean value if match/no match only is needed
NoMatch = 0,
/// The index itself is matched
DirectMatch,
/// A parent if the index is matched
ParentMatch,
/// A child of the index is matched
ChildMatch,
/// The index is matched not because of search settings, but because it has a special type
SpecialMatch
};
enum FilterBehavior
{
/**
* If an index does not matched, the index and all its children are filtered out.
* This is the Qt default behavior, but undesirable for album trees.
*/
SimpleFiltering,
/**
* Default behavior.
* If an index matches, it is shown, which directly means all its parents are shown as well.
* In addition, all its children are shown as well.
*/
FullFiltering,
/**
* If an index matches, it is shown, which directly means all its parents are shown as well.
* Its children are not shown unless they also match.
*/
StrictFiltering
};
public:
explicit AlbumFilterModel(QObject* const parent = nullptr);
/**
* Sets the source model.
* Note: If a chained filter model is set, it will not be reset, but
* the source album model will be made source of the chained filter model.
*/
void setSourceAlbumModel(AbstractAlbumModel* const source);<--- Parent function 'AlbumFilterModel::setSourceAlbumModel'
AbstractAlbumModel* sourceAlbumModel() const;<--- Parent function 'AlbumFilterModel::sourceAlbumModel'
/**
* Sets a chained filter model.
* Note: If a direct source album model is set as current source, it will be set as
* sourceAlbumModel of the new source filter model.
*/
void setSourceFilterModel(AlbumFilterModel* const source);
AlbumFilterModel* sourceFilterModel() const;
QModelIndex mapToSourceAlbumModel(const QModelIndex& index) const;
QModelIndex mapFromSourceAlbumModel(const QModelIndex& index) const;
/// Convenience methods
Album* albumForIndex(const QModelIndex& index) const;
QModelIndex indexForAlbum(Album* album) const;
QModelIndex rootAlbumIndex() const;
QVariant dataForCurrentSortRole(Album* album) const;
/**
* Returns the settings currently used for filtering.
*
* @return current settings for filtering.
*/
SearchTextSettings searchTextSettings() const;
/**
* Sets the filter behavior. Default is FullFiltering.
*/
void setFilterBehavior(FilterBehavior behavior);
/**
* Returns the MatchResult of an index of this model.
* Never returns NoMatch for a valid index, because in this case,
* the index would rather be filtered out.
*/
MatchResult matchResult(const QModelIndex& index) const;
/**
* Returns if the currently applied filters will result in any filtering.
*
* @return <code>true</code> if the current selected filter could result in
* any filtering without checking if this really happens.
*/
virtual bool isFiltering() const;
/**
* Force invalidateFilter() externally.
*/
void updateFilter();
/**
* Returns the usual compare result of -1, 0, or 1 for lessThan, equals and greaterThan.
*/
template <typename T>
static inline int compareValue(const T& a, const T& b)
{
if (a == b)
{
return 0;
}
if (a < b)
{
return -1;
}
else
{
return 1;
}
}
/**
* Takes a typical result from a compare method (0 is equal, -1 is less than, 1 is greater than)
* and applies the given sort order to it.
*/
static inline int compareByOrder(int compareResult, Qt::SortOrder sortOrder)
{
if (sortOrder == Qt::AscendingOrder)
{
return compareResult;
}
else
{
return (- compareResult);
}
}
template <typename T>
static inline int compareByOrder(const T& a, const T& b, Qt::SortOrder sortOrder)
{
return compareByOrder(compareValue(a, b), sortOrder);
}
public Q_SLOTS:
/**
* Accepts new settings used for filtering and applies them to the model.
*
* @param settings new settings to apply. An empty text will be interpreted
* as no filtering
*/
void setSearchTextSettings(const SearchTextSettings& settings);
Q_SIGNALS:
/**
* This signal indicates that a new SearchTextSettings arrived and is about
* to be applied to the model.
*
* @param searched <code>true</code> if filtering by text was enabled before
* applying the new settings
* @param willSearch <code>true</code> if the new settings can result in
* any filtering by text, else <code>false</code>.
*/
void searchTextSettingsAboutToChange(bool searched, bool willSearch);
/**
* Indicates that new search text settings were applied.
*
* @param wasSearching <code>true</code> if this is not a new search that
* @param searched <code>true</code> if the new settings result in any
* filtering
*/
void searchTextSettingsChanged(bool wasSearching, bool searched);
/**
* Indicates that a new filter was applied to the model.
*/
void signalFilterChanged();
/**
* Indicates whether the newly applied filter results in a search result or
* not.
*
* @param hasResult <code>true</code> if the new filter matches any album,
* else <code>false</code>
*/
void hasSearchResult(bool hasResult);
protected:
/**
* Returns if the filter matches this album (same logic as filterAcceptsRow).
* An album matches if the search text settings are found in a parent album's title,
* in the album's title or in a child album's title, or if it is a special album (root)
* that is never filtered out.
*/
MatchResult matchResult(Album* album) const;
/**
* This method provides the basic match checking algorithm.
* Return true if this single album matches the current criteria.
* This method can be overridden to provide custom filtering.
*
* @param album the album to tell if it matches the filter criteria or not.
*/
virtual bool matches(Album* album) const;
/**
* Use setSourceAlbumModel.
*
* @see setSourceAlbumModel
* @param model source model
*/
void setSourceModel(QAbstractItemModel* const model) override;
bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override;
bool lessThan(const QModelIndex& left, const QModelIndex& right) const override;
protected Q_SLOTS:
void slotAlbumRenamed(Album* album);
void slotAlbumsHaveBeenUpdated(int type);
private:
/**
* Tells whether the given settings result in filtering.
*
* @return <code>true</code> if the provided settings result in filtering
* the model
*/
bool settingsFilter(const SearchTextSettings& settings) const;
protected:
FilterBehavior m_filterBehavior = FullFiltering;
SearchTextSettings m_settings;
QPointer<AlbumFilterModel> m_chainedModel = nullptr;
QObject* m_parent = nullptr;
};
// -----------------------------------------------------------------------------------
/**
* Filter model for checkable album models that allows more filtering options
* based on check state.
*/
class DIGIKAM_GUI_EXPORT CheckableAlbumFilterModel : public AlbumFilterModel
{
Q_OBJECT
public:
explicit CheckableAlbumFilterModel(QObject* const parent = nullptr);
void setSourceAlbumModel(AbstractCheckableAlbumModel* const source);
AbstractCheckableAlbumModel* sourceAlbumModel() const;<--- Derived function 'CheckableAlbumFilterModel::sourceAlbumModel'<--- Derived function 'CheckableAlbumFilterModel::sourceAlbumModel'
void setSourceFilterModel(CheckableAlbumFilterModel* const source);
void setFilterChecked(bool filter);
void setFilterPartiallyChecked(bool filter);
bool isFiltering() const override;
protected:
bool matches(Album* album) const override;
protected:
bool m_filterChecked = false;
bool m_filterPartiallyChecked = false;
};
// -----------------------------------------------------------------------------------
/**
* Filter model for searches that can filter by search type
*/
class DIGIKAM_GUI_EXPORT SearchFilterModel : public CheckableAlbumFilterModel
{
Q_OBJECT
public:
explicit SearchFilterModel(QObject* const parent = nullptr);
void setSourceSearchModel(SearchModel* const source);
SearchModel* sourceSearchModel() const;
/**
* Set the DatabaseSearch::Type.
*/
void setFilterSearchType(DatabaseSearch::Type);
void listAllSearches();
void listNormalSearches();
void listTimelineSearches();
void listHaarSearches();
void listMapSearches();
void listDuplicatesSearches();
/**
* Sets if temporary search albums shall be listed
*/
void setListTemporarySearches(bool list);
bool isFiltering() const override;
protected:
// make protected
void setSourceAlbumModel(AbstractAlbumModel* const source);<--- Derived function 'SearchFilterModel::setSourceAlbumModel'<--- Derived function 'SearchFilterModel::setSourceAlbumModel'
void setTypeFilter(int type);
bool matches(Album* album) const override;
protected:
int m_searchType = -1;
bool m_listTemporary = false;
};
// -----------------------------------------------------------------------------------
/**
* Filter model for tags that can filter by tag property
*/
class DIGIKAM_GUI_EXPORT TagPropertiesFilterModel : public CheckableAlbumFilterModel
{
Q_OBJECT
public:
explicit TagPropertiesFilterModel(QObject* const parent = nullptr);
void setSourceAlbumModel(TagModel* const source);
TagModel* sourceTagModel() const;
void listOnlyTagsWithProperty(const QString& property);
void removeListOnlyProperty(const QString& property);
void doNotListTagsWithProperty(const QString& property);
void removeDoNotListProperty(const QString& property);
bool isFiltering() const override;
protected Q_SLOTS:
void tagPropertiesChanged(TAlbum*);
protected:
bool matches(Album* album) const override;
protected:
QSet<QString> m_propertiesBlackList;
QSet<QString> m_propertiesWhiteList;
};
// -----------------------------------------------------------------------------------
class DIGIKAM_GUI_EXPORT TagsManagerFilterModel : public TagPropertiesFilterModel
{
Q_OBJECT
public:
explicit TagsManagerFilterModel(QObject* const data = nullptr);
void setQuickListTags(const QList<int>& tags);
protected:
bool matches(Album* album) const override;
protected:
QSet<int> m_keywords;
};
} // namespace Digikam
|