1 /* ============================================================
2  *
3  * This file is a part of digiKam project
4  * https://www.digikam.org
5  *
6  * Date        : 2009-03-05
7  * Description : Filter values for use with ItemFilterModel
8  *
9  * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
10  * Copyright (C) 2011-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
11  * Copyright (C)      2010 by Andi Clemens <andi dot clemens at gmail dot com>
12  * Copyright (C)      2011 by Michael G. Hansen <mike at mghansen dot de>
13  * Copyright (C)      2014 by Mohamed_Anwer <m_dot_anwer at gmx dot com>
14  *
15  * This program is free software; you can redistribute it
16  * and/or modify it under the terms of the GNU General
17  * Public License as published by the Free Software Foundation;
18  * either version 2, or (at your option)
19  * any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * ============================================================ */
27 
28 #ifndef DIGIKAM_ITEM_FILTER_SETTINGS_H
29 #define DIGIKAM_ITEM_FILTER_SETTINGS_H
30 
31 // Qt includes
32 
33 #include <QHash>
34 #include <QList>
35 #include <QMap>
36 #include <QString>
37 #include <QSet>
38 #include <QUrl>
39 #include <QDateTime>
40 
41 // Local includes
42 
43 #include "searchtextbar.h"
44 #include "mimefilter.h"
45 #include "digikam_export.h"
46 
47 namespace Digikam
48 {
49 
50 class ItemInfo;
51 class VersionManagerSettings;
52 
53 namespace DatabaseFields
54 {
55     class Set;
56 }
57 
58 // ---------------------------------------------------------------------------------------
59 
60 class DIGIKAM_DATABASE_EXPORT SearchTextFilterSettings : public SearchTextSettings
61 {
62 
63 public:
64 
65     enum TextFilterFields
66     {
67         None             = 0x00,
68         ImageName        = 0x01,
69         ImageTitle       = 0x02,
70         ImageComment     = 0x04,
71         TagName          = 0x08,
72         AlbumName        = 0x10,
73         ImageAspectRatio = 0x20,
74         ImagePixelSize   = 0x40,
75         All              = ImageName | ImageTitle | ImageComment | TagName | AlbumName | ImageAspectRatio | ImagePixelSize
76     };
77 
78 public:
79 
SearchTextFilterSettings()80     SearchTextFilterSettings()
81     {
82         textFields = None;
83     }
84 
SearchTextFilterSettings(const SearchTextSettings & settings)85     explicit SearchTextFilterSettings(const SearchTextSettings& settings)
86     {
87         caseSensitive = settings.caseSensitive;
88         text          = settings.text;
89         textFields    = None;
90     }
91 
92     TextFilterFields textFields;
93 };
94 
95 // ---------------------------------------------------------------------------------------
96 
97 class DIGIKAM_DATABASE_EXPORT ItemFilterSettings
98 {
99 public:
100 
101     /// Possible logical matching condition used to sort tags id.
102     enum MatchingCondition
103     {
104         OrCondition,
105         AndCondition
106     };
107 
108     /// Possible conditions used to filter rating: >=, =, <=
109     enum RatingCondition
110     {
111         GreaterEqualCondition,
112         EqualCondition,
113         LessEqualCondition
114     };
115 
116     /// Possible logical matching condition used to sort geolocation.
117     enum GeolocationCondition
118     {
119         GeolocationNoFilter       = 0,
120         GeolocationNoCoordinates  = 1 << 1,
121         GeolocationHasCoordinates = 1 << 2
122     };
123 
124 public:
125 
126     explicit ItemFilterSettings();
127 
128     /**
129      *  Returns true if the given ItemInfo matches the filter criteria.
130      *  Optionally, foundText is set to true if it matched by text search.
131      */
132     bool matches(const ItemInfo& info, bool* const foundText = nullptr) const;
133 
134 public:
135 
136     /// --- Tags filter ---
137 
138     void setTagFilter(const QList<int>& includedTags,
139                       const QList<int>& excludedTags,
140                       MatchingCondition matchingCond,
141                       bool              showUnTagged,
142                       const QList<int>& clTagIds,
143                       const QList<int>& plTagIds);
144 
145 public:
146 
147     /// --- Rating filter ---
148     void setRatingFilter(int rating, RatingCondition ratingCond, bool isUnratedExcluded);
149 
150 public:
151 
152     /// --- Date filter ---
153     void setDayFilter(const QList<QDateTime>& days);
154 
155 public:
156 
157     /// --- Text filter ---
158     void setTextFilter(const SearchTextFilterSettings& settings);
159     void setTagNames(const QHash<int, QString>& tagNameHash);
160     void setAlbumNames(const QHash<int, QString>& albumNameHash);
161 
162 public:
163 
164     /// --- Mime filter ---
165     void setMimeTypeFilter(int mimeTypeFilter);
166 
167 public:
168 
169     /// --- Geolocation filter
170     void setGeolocationFilter(const GeolocationCondition& condition);
171 
172 public:
173 
174     /// Returns if the day is a filter criteria
175     bool isFilteringByDay()                                 const;
176 
177     /// Returns if the type mime is a filter criteria
178     bool isFilteringByTypeMime()                            const;
179 
180     /// Returns whether geolocation is a filter criteria
181     bool isFilteringByGeolocation()                         const;
182 
183     /// Returns if the rating is a filter criteria
184     bool isFilteringByRating()                              const;
185 
186     /// Returns if the pick labels is a filter criteria
187     bool isFilteringByPickLabels()                          const;
188 
189     /// Returns if the color labels is a filter criteria
190     bool isFilteringByColorLabels()                         const;
191 
192     /// Returns if the tag is a filter criteria
193     bool isFilteringByTags()                                const;
194 
195     /// Returns if the text (including comment) is a filter criteria
196     bool isFilteringByText()                                const;
197 
198     /// Returns if images will be filtered by these criteria at all
199     bool isFiltering()                                      const;
200 
201 public:
202 
203     /// --- URL whitelist filter
204     void setUrlWhitelist(const QList<QUrl>& urlList, const QString& id);
205 
206 public:
207 
208     /// --- ID whitelist filter
209     void setIdWhitelist(const QList<qlonglong>& idList, const QString& id);
210 
211 public:
212 
213     /// --- Change notification ---
214 
215     /** Returns database fields a change in which would affect the current filtering.
216      *  To find out if an image tag change affects filtering, test isFilteringByTags().
217      *  The text filter will also be affected by changes in tags and album names.
218      */
219     DatabaseFields::Set watchFlags()                        const;
220 
221 private:
222 
223     /**
224      * @brief Returns whether some internal filtering (whitelist by id or URL) or normal filtering is going on
225      */
226     bool isFilteringInternally()                            const;
227 
228 private:
229 
230     /// --- Tags filter ---
231     bool                              m_untaggedFilter;
232     QList<int>                        m_includeTagFilter;
233     QList<int>                        m_excludeTagFilter;
234     MatchingCondition                 m_matchingCond;
235     QList<int>                        m_colorLabelTagFilter;
236     QList<int>                        m_pickLabelTagFilter;
237 
238     /// --- Rating filter ---
239     int                               m_ratingFilter;
240     RatingCondition                   m_ratingCond;
241     bool                              m_isUnratedExcluded;
242 
243     /// --- Date filter ---
244     QHash<QDateTime, bool>            m_dayFilter;
245 
246     /// --- Text filter ---
247     SearchTextFilterSettings          m_textFilterSettings;
248 
249     /// Helpers for text search: Set these if you want to search album or tag names with text search
250     QHash<int, QString>               m_tagNameHash;
251     QHash<int, QString>               m_albumNameHash;
252 
253     /// --- Mime filter ---
254     MimeFilter::TypeMimeFilter        m_mimeTypeFilter;
255 
256     /// --- Geolocation filter
257     GeolocationCondition              m_geolocationCondition;
258 
259     /// --- URL whitelist filter
260     QHash<QString,QList<QUrl>>        m_urlWhitelists;
261 
262     /// --- ID whitelist filter
263     QHash<QString, QList<qlonglong> > m_idWhitelists;
264 };
265 
266 // ---------------------------------------------------------------------------------------
267 
268 class DIGIKAM_DATABASE_EXPORT VersionItemFilterSettings
269 {
270 public:
271 
272     VersionItemFilterSettings();
273     explicit VersionItemFilterSettings(const VersionManagerSettings& settings);
274 
275     bool operator==(const VersionItemFilterSettings& other) const;
276 
277     /**
278      *  Returns true if the given ItemInfo matches the filter criteria.
279      */
280     bool matches(const ItemInfo& info)                      const;
281 
282     bool isHiddenBySettings(const ItemInfo& info)           const;
283     bool isExemptedBySettings(const ItemInfo& info)         const;
284 
285     /// --- Tags filter ---
286 
287     void setVersionManagerSettings(const VersionManagerSettings& settings);
288 
289     /**
290      * Add list with exceptions: These images will be exempted from filtering by this filter
291      */
292     void setExceptionList(const QList<qlonglong>& idlist, const QString& id);
293 
294     /// Returns if images will be filtered by these criteria at all
295     bool isFiltering()                                      const;
296 
297     /// Returns if the tag is a filter criteria
298     bool isFilteringByTags()                                const;
299 
300     /// DatabaseFields::Set watchFlags() const: Would return 0
301 
302 protected:
303 
304     QList<int>                        m_excludeTagFilter;
305     int                               m_includeTagFilter;
306     int                               m_exceptionTagFilter;
307     QHash<QString, QList<qlonglong> > m_exceptionLists;
308 };
309 
310 // ---------------------------------------------------------------------------------------
311 
312 class DIGIKAM_DATABASE_EXPORT GroupItemFilterSettings
313 {
314 public:
315 
316     explicit GroupItemFilterSettings();
317 
318     bool operator==(const GroupItemFilterSettings& other)   const;
319 
320     /**
321      *  Returns true if the given ItemInfo matches the filter criteria.
322      */
323     bool matches(const ItemInfo& info)                      const;
324 
325     /**
326      * Open or close a group.
327      */
328     void setOpen(qlonglong group, bool open);
329     bool isOpen(qlonglong group)                            const;
330 
331     /**
332      * Open all groups
333      */
334     void setAllOpen(bool open);
335     bool isAllOpen()                                        const;
336 
337     /// Returns if images will be filtered by these criteria at all
338     bool isFiltering()                                      const;
339 
340     DatabaseFields::Set watchFlags()                        const;
341 
342 protected:
343 
344     bool            m_allOpen;
345     QSet<qlonglong> m_openGroups;
346 };
347 
348 } // namespace Digikam
349 
350 Q_DECLARE_METATYPE(Digikam::ItemFilterSettings::GeolocationCondition)
351 
352 #endif // DIGIKAM_ITEM_FILTER_SETTINGS_H
353