1 /* ============================================================ 2 * 3 * This file is a part of digiKam project 4 * https://www.digikam.org 5 * 6 * Date : 2009-03-05 7 * Description : Qt item model for database entries 8 * 9 * Copyright (C) 2009-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 10 * Copyright (C) 2011 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_MODEL_H 29 #define DIGIKAM_ITEM_FILTER_MODEL_H 30 31 // Local includes 32 33 #include "dcategorizedsortfilterproxymodel.h" 34 #include "textfilter.h" 35 #include "itemfiltersettings.h" 36 #include "itemmodel.h" 37 #include "itemsortsettings.h" 38 #include "digikam_export.h" 39 40 namespace Digikam 41 { 42 43 class ImageChangeset; 44 class ItemFilterModel; 45 class ImageTagChangeset; 46 class FaceTagsIface; 47 48 class DIGIKAM_DATABASE_EXPORT ItemFilterModelPrepareHook 49 { 50 public: 51 ~ItemFilterModelPrepareHook()52 virtual ~ItemFilterModelPrepareHook() {}; 53 virtual void prepare(const QVector<ItemInfo>& infos) = 0; 54 55 private: 56 57 Q_DISABLE_COPY(ItemFilterModelPrepareHook) 58 }; 59 60 // ----------------------------------------------------------------------------------------------- 61 62 class DIGIKAM_DATABASE_EXPORT ImageSortFilterModel : public DCategorizedSortFilterProxyModel 63 { 64 Q_OBJECT 65 66 public: 67 68 explicit ImageSortFilterModel(QObject* const parent = nullptr); 69 70 void setSourceItemModel(ItemModel* const model); 71 ItemModel* sourceItemModel() const; 72 73 void setSourceFilterModel(ImageSortFilterModel* const model); 74 ImageSortFilterModel* sourceFilterModel() const; 75 76 QModelIndex mapToSourceItemModel(const QModelIndex& index) const; 77 QModelIndex mapFromSourceItemModel(const QModelIndex& imagemodel_index) const; 78 QModelIndex mapFromDirectSourceToSourceItemModel(const QModelIndex& sourceModel_index) const; 79 80 /** 81 * Convenience methods mapped to ItemModel. 82 * Mentioned indexes returned come from the source image model. 83 */ 84 QList<QModelIndex> mapListToSource(const QList<QModelIndex>& indexes) const; 85 QList<QModelIndex> mapListFromSource(const QList<QModelIndex>& sourceIndexes) const; 86 87 ItemInfo imageInfo(const QModelIndex& index) const; 88 qlonglong imageId(const QModelIndex& index) const; 89 QList<ItemInfo> imageInfos(const QList<QModelIndex>& indexes) const; 90 QList<qlonglong> imageIds(const QList<QModelIndex>& indexes) const; 91 92 QModelIndex indexForPath(const QString& filePath) const; 93 QModelIndex indexForItemInfo(const ItemInfo& info) const; 94 QModelIndex indexForImageId(qlonglong id) const; 95 96 /** 97 * Returns a list of all image infos, sorted according to this model. 98 * If you do not need a sorted list, use ItemModel's imageInfos() method. 99 */ 100 QList<ItemInfo> imageInfosSorted() const; 101 102 /** 103 * Returns this, any chained ItemFilterModel, or 0. 104 */ 105 virtual ItemFilterModel* imageFilterModel() const; 106 107 protected: 108 109 /** 110 * Reimplement if needed. Called only when model shall be set as (direct) sourceModel. 111 */ 112 virtual void setDirectSourceItemModel(ItemModel* const model); 113 114 /// NOTE: made protected 115 void setSourceModel(QAbstractItemModel* const model) override; 116 117 protected: 118 119 ImageSortFilterModel* m_chainedModel; 120 }; 121 122 // ----------------------------------------------------------------------------------------------- 123 124 class DIGIKAM_DATABASE_EXPORT ItemFilterModel : public ImageSortFilterModel 125 { 126 Q_OBJECT 127 128 public: 129 130 enum ItemFilterModelRoles 131 { 132 /// Returns the current categorization mode 133 CategorizationModeRole = ItemModel::FilterModelRoles + 1, 134 135 /// Returns the current sort order 136 SortOrderRole = ItemModel::FilterModelRoles + 2, 137 138 /// Returns the number of items in the index category 139 //CategoryCountRole = ItemModel::FilterModelRoles + 3, 140 141 /// Returns the id of the PAlbum of the index which is used for category 142 CategoryAlbumIdRole = ItemModel::FilterModelRoles + 3, 143 144 /// Returns the format of the index which is used for category 145 CategoryFormatRole = ItemModel::FilterModelRoles + 4, 146 147 /// Returns the date of the index which is used for category 148 CategoryDateRole = ItemModel::FilterModelRoles + 5, 149 150 /// Returns the suggested name for the face in this index 151 CategoryFaceRole = ItemModel::FilterModelRoles + 6, 152 153 /// Returns true if the given image is a group leader, and the group is opened 154 GroupIsOpenRole = ItemModel::FilterModelRoles + 7, 155 ItemFilterModelPointerRole = ItemModel::FilterModelRoles + 50 156 }; 157 158 public: 159 160 explicit ItemFilterModel(QObject* const parent = nullptr); 161 ~ItemFilterModel() override; 162 163 /** 164 * Add a hook to get added images for preparation tasks before they are added in the model 165 */ 166 void addPrepareHook(ItemFilterModelPrepareHook* const hook); 167 void removePrepareHook(ItemFilterModelPrepareHook* const hook); 168 169 /** 170 * Returns a set of DatabaseFields suggested to set as watch flags on the source ItemModel. 171 * The contained flags will be those that this model can sort or filter by. 172 */ 173 DatabaseFields::Set suggestedWatchFlags() const; 174 175 ItemFilterSettings imageFilterSettings() const; 176 VersionItemFilterSettings versionItemFilterSettings() const; 177 GroupItemFilterSettings groupItemFilterSettings() const; 178 ItemSortSettings imageSortSettings() const; 179 180 /** 181 * group is identified by the id of its group leader 182 */ 183 bool isGroupOpen(qlonglong group) const; 184 bool isAllGroupsOpen() const; 185 186 /** 187 * Enables sending imageInfosAdded and imageInfosAboutToBeRemoved 188 */ 189 void setSendItemInfoSignals(bool sendSignals); 190 191 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; 192 ItemFilterModel* imageFilterModel() const override; 193 194 public Q_SLOTS: 195 196 /** 197 * Changes the current version image filter settings and refilters. 198 */ 199 void setVersionItemFilterSettings(const VersionItemFilterSettings& settings); 200 201 /** 202 * Changes the current version image filter settings and refilters. 203 */ 204 void setGroupItemFilterSettings(const GroupItemFilterSettings& settings); 205 206 /** 207 * Adjust the current ItemFilterSettings. 208 * Equivalent to retrieving the current filter settings, adjusting the parameter 209 * and calling setItemFilterSettings. 210 * Provided for convenience. 211 * It is encouraged to use setItemFilterSettings if you change more than one 212 * parameter at a time. 213 */ 214 void setDayFilter(const QList<QDateTime>& days); 215 void setTagFilter(const QList<int>& includedTags, const QList<int>& excludedTags, 216 ItemFilterSettings::MatchingCondition matchingCond, bool showUnTagged, 217 const QList<int>& clTagIds, const QList<int>& plTagIds); 218 void setRatingFilter(int rating, ItemFilterSettings::RatingCondition ratingCond, bool isUnratedExcluded); 219 void setMimeTypeFilter(int mimeTypeFilter); 220 void setGeolocationFilter(const ItemFilterSettings::GeolocationCondition& condition); 221 void setTextFilter(const SearchTextFilterSettings& settings); 222 223 void setCategorizationMode(ItemSortSettings::CategorizationMode mode); 224 void setCategorizationSortOrder(ItemSortSettings::SortOrder order); 225 void setSortRole(ItemSortSettings::SortRole role); 226 void setSortOrder(ItemSortSettings::SortOrder order); 227 void setStringTypeNatural(bool natural); 228 void setUrlWhitelist(const QList<QUrl>& urlList, const QString& id); 229 void setIdWhitelist(const QList<qlonglong>& idList, const QString& id); 230 231 void setVersionManagerSettings(const VersionManagerSettings& settings); 232 void setExceptionList(const QList<qlonglong>& idlist, const QString& id); 233 234 void setGroupOpen(qlonglong group, bool open); 235 void toggleGroupOpen(qlonglong group); 236 void setAllGroupsOpen(bool open); 237 238 /** 239 * Changes the current image filter settings and refilters. 240 */ 241 virtual void setItemFilterSettings(const ItemFilterSettings& settings); 242 243 /** 244 * Changes the current image sort settings and resorts. 245 */ 246 virtual void setItemSortSettings(const ItemSortSettings& settings); 247 248 Q_SIGNALS: 249 250 /** 251 * Signals that the set filter matches at least one index 252 */ 253 void filterMatches(bool matches); 254 255 /** 256 * Signals that the set text filter matches at least one entry. 257 * If no text filter is set, this signal is emitted 258 * with 'false' when filterMatches() is emitted. 259 */ 260 void filterMatchesForText(bool matchesByText); 261 262 /** 263 * Emitted when the filter settings have been changed 264 * (the model may not yet have been updated) 265 */ 266 void filterSettingsChanged(const ItemFilterSettings& settings); 267 268 /** 269 * These signals need to be explicitly enabled with setSendItemInfoSignals() 270 */ 271 void imageInfosAdded(const QList<ItemInfo>& infos); 272 void imageInfosAboutToBeRemoved(const QList<ItemInfo>& infos); 273 274 public: 275 276 /// NOTE: Declared as public because of use in sub-classes. 277 class ItemFilterModelPrivate; 278 279 protected: 280 281 ItemFilterModelPrivate* const d_ptr; 282 283 protected: 284 285 ItemFilterModel(ItemFilterModelPrivate& dd, QObject* const parent); 286 287 void setDirectSourceItemModel(ItemModel* const model) override; 288 289 bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override; 290 291 int compareCategories(const QModelIndex& left, const QModelIndex& right) const override; 292 bool subSortLessThan(const QModelIndex& left, const QModelIndex& right) const override; 293 /* 294 virtual int categoryCount(const ItemInfo& info) const; 295 */ 296 /** 297 * Reimplement to customize category sorting, 298 * Return negative if category of left < category right, 299 * Return 0 if left and right are in the same category, else return positive. 300 */ 301 virtual int compareInfosCategories(const ItemInfo& left, const ItemInfo& right) const; 302 303 /** 304 * In order to be able to Categorize by Faces, it's necessary to pass in the 305 * face as well. One image may have multiple Faces in it, hence just the ItemInfo 306 * isn't sufficient. 307 */ 308 virtual int compareInfosCategories(const ItemInfo& left, const ItemInfo& right, 309 const FaceTagsIface& leftFace, 310 const FaceTagsIface& rightFace) const; 311 312 /** 313 * Reimplement to customize sorting. Do not take categories into account here. 314 */ 315 virtual bool infosLessThan(const ItemInfo& left, const ItemInfo& right) const; 316 317 /** 318 * Returns a unique identifier for the category if info. The string need not be for user display. 319 */ 320 virtual QString categoryIdentifier(const ItemInfo& info, const FaceTagsIface& face) const; 321 322 protected Q_SLOTS: 323 324 void slotModelReset(); 325 void slotUpdateFilter(); 326 327 void slotImageTagChange(const ImageTagChangeset& changeset); 328 void slotImageChange(const ImageChangeset& changeset); 329 330 void slotRowsInserted(const QModelIndex& parent, int start, int end); 331 void slotRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end); 332 333 private: 334 335 Q_DECLARE_PRIVATE(ItemFilterModel) 336 }; 337 338 // ----------------------------------------------------------------------------------------------------- 339 340 class DIGIKAM_DATABASE_EXPORT NoDuplicatesItemFilterModel : public ImageSortFilterModel 341 { 342 Q_OBJECT 343 344 public: 345 346 explicit NoDuplicatesItemFilterModel(QObject* const parent = nullptr); 347 348 protected: 349 350 bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override; 351 }; 352 353 } // namespace Digikam 354 355 Q_DECLARE_METATYPE(Digikam::ItemFilterModel*) 356 357 #endif // DIGIKAM_ITEM_FILTER_MODEL_H 358