File indexing completed on 2024-05-05 04:19:15
0001 // vim: set tabstop=4 shiftwidth=4 expandtab: 0002 /* 0003 Gwenview: an image viewer 0004 Copyright 2008 Aurélien Gâteau <agateau@kde.org> 0005 0006 This program is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU General Public License 0008 as published by the Free Software Foundation; either version 2 0009 of the License, or (at your option) any later version. 0010 0011 This program is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 GNU General Public License for more details. 0015 0016 You should have received a copy of the GNU General Public License 0017 along with this program; if not, write to the Free Software 0018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA. 0019 0020 */ 0021 #ifndef FILTERCONTROLLER_H 0022 #define FILTERCONTROLLER_H 0023 0024 #include <config-gwenview.h> 0025 0026 // Qt 0027 #include <QDate> 0028 #include <QList> 0029 #include <QObject> 0030 #include <QWidget> 0031 0032 // KF 0033 #include <KFileItem> 0034 0035 // Local 0036 #include <lib/datewidget.h> 0037 #include <lib/semanticinfo/sorteddirmodel.h> 0038 #include <lib/timeutils.h> 0039 0040 #ifndef GWENVIEW_SEMANTICINFO_BACKEND_NONE 0041 // KF 0042 #include <KRatingWidget> 0043 0044 // Local 0045 #include <lib/semanticinfo/abstractsemanticinfobackend.h> 0046 #include <lib/semanticinfo/tagmodel.h> 0047 #endif 0048 0049 class QAction; 0050 class QFrame; 0051 class QLineEdit; 0052 class QComboBox; 0053 class KComboBox; 0054 0055 namespace Gwenview 0056 { 0057 class SortedDirModel; 0058 0059 /** 0060 * An AbstractSortedDirModelFilter which filters on the file names 0061 */ 0062 class NameFilter : public AbstractSortedDirModelFilter 0063 { 0064 public: 0065 enum Mode { 0066 Contains, 0067 DoesNotContain, 0068 }; 0069 NameFilter(SortedDirModel *model) 0070 : AbstractSortedDirModelFilter(model) 0071 , mText() 0072 , mMode(Contains) 0073 { 0074 } 0075 0076 bool needsSemanticInfo() const override 0077 { 0078 return false; 0079 } 0080 0081 bool acceptsIndex(const QModelIndex &index) const override 0082 { 0083 if (mText.isEmpty()) { 0084 return true; 0085 } 0086 switch (mMode) { 0087 case Contains: 0088 return index.data().toString().contains(mText, Qt::CaseInsensitive); 0089 default: /*DoesNotContain:*/ 0090 return !index.data().toString().contains(mText, Qt::CaseInsensitive); 0091 } 0092 } 0093 0094 void setText(const QString &text) 0095 { 0096 mText = text; 0097 model()->applyFilters(); 0098 } 0099 0100 void setMode(Mode mode) 0101 { 0102 mMode = mode; 0103 model()->applyFilters(); 0104 } 0105 0106 private: 0107 QString mText; 0108 Mode mMode; 0109 }; 0110 0111 class NameFilterWidget : public QWidget 0112 { 0113 Q_OBJECT 0114 public: 0115 NameFilterWidget(SortedDirModel *); 0116 ~NameFilterWidget() override; 0117 0118 private Q_SLOTS: 0119 void applyNameFilter(); 0120 0121 private: 0122 QPointer<NameFilter> mFilter; 0123 KComboBox *mModeComboBox; 0124 QLineEdit *mLineEdit; 0125 }; 0126 0127 /** 0128 * An AbstractSortedDirModelFilter which filters on the file dates 0129 */ 0130 class DateFilter : public AbstractSortedDirModelFilter 0131 { 0132 public: 0133 enum Mode { 0134 GreaterOrEqual, 0135 Equal, 0136 LessOrEqual, 0137 }; 0138 DateFilter(SortedDirModel *model) 0139 : AbstractSortedDirModelFilter(model) 0140 , mMode(GreaterOrEqual) 0141 { 0142 } 0143 0144 bool needsSemanticInfo() const override 0145 { 0146 return false; 0147 } 0148 0149 bool acceptsIndex(const QModelIndex &index) const override 0150 { 0151 if (!mDate.isValid()) { 0152 return true; 0153 } 0154 KFileItem fileItem = model()->itemForSourceIndex(index); 0155 QDate date = TimeUtils::dateTimeForFileItem(fileItem).date(); 0156 switch (mMode) { 0157 case GreaterOrEqual: 0158 return date >= mDate; 0159 case Equal: 0160 return date == mDate; 0161 default: /* LessOrEqual */ 0162 return date <= mDate; 0163 } 0164 } 0165 0166 void setDate(const QDate &date) 0167 { 0168 mDate = date; 0169 model()->applyFilters(); 0170 } 0171 0172 void setMode(Mode mode) 0173 { 0174 mMode = mode; 0175 model()->applyFilters(); 0176 } 0177 0178 private: 0179 QDate mDate; 0180 Mode mMode; 0181 }; 0182 0183 class DateFilterWidget : public QWidget 0184 { 0185 Q_OBJECT 0186 public: 0187 DateFilterWidget(SortedDirModel *); 0188 ~DateFilterWidget() override; 0189 0190 private Q_SLOTS: 0191 void applyDateFilter(); 0192 0193 private: 0194 QPointer<DateFilter> mFilter; 0195 KComboBox *mModeComboBox; 0196 DateWidget *mDateWidget; 0197 }; 0198 0199 #ifndef GWENVIEW_SEMANTICINFO_BACKEND_NONE 0200 /** 0201 * An AbstractSortedDirModelFilter which filters on file ratings 0202 */ 0203 class RatingFilter : public AbstractSortedDirModelFilter 0204 { 0205 public: 0206 enum Mode { 0207 GreaterOrEqual, 0208 Equal, 0209 LessOrEqual, 0210 }; 0211 0212 RatingFilter(SortedDirModel *model) 0213 : AbstractSortedDirModelFilter(model) 0214 , mRating(0) 0215 , mMode(GreaterOrEqual) 0216 { 0217 } 0218 0219 bool needsSemanticInfo() const override 0220 { 0221 return true; 0222 } 0223 0224 bool acceptsIndex(const QModelIndex &index) const override 0225 { 0226 SemanticInfo info = model()->semanticInfoForSourceIndex(index); 0227 switch (mMode) { 0228 case GreaterOrEqual: 0229 return info.mRating >= mRating; 0230 case Equal: 0231 return info.mRating == mRating; 0232 default: /* LessOrEqual */ 0233 return info.mRating <= mRating; 0234 } 0235 } 0236 0237 void setRating(int value) 0238 { 0239 mRating = value; 0240 model()->applyFilters(); 0241 } 0242 0243 void setMode(Mode mode) 0244 { 0245 mMode = mode; 0246 model()->applyFilters(); 0247 } 0248 0249 private: 0250 int mRating; 0251 Mode mMode; 0252 }; 0253 0254 class RatingFilterWidget : public QWidget 0255 { 0256 Q_OBJECT 0257 public: 0258 RatingFilterWidget(SortedDirModel *); 0259 ~RatingFilterWidget() override; 0260 0261 private Q_SLOTS: 0262 void slotRatingChanged(int value); 0263 void updateFilterMode(); 0264 0265 private: 0266 KComboBox *mModeComboBox; 0267 KRatingWidget *mRatingWidget; 0268 QPointer<RatingFilter> mFilter; 0269 }; 0270 0271 /** 0272 * An AbstractSortedDirModelFilter which filters on associated tags 0273 */ 0274 class TagFilter : public AbstractSortedDirModelFilter 0275 { 0276 public: 0277 TagFilter(SortedDirModel *model) 0278 : AbstractSortedDirModelFilter(model) 0279 , mWantMatchingTag(true) 0280 { 0281 } 0282 0283 bool needsSemanticInfo() const override 0284 { 0285 return true; 0286 } 0287 0288 bool acceptsIndex(const QModelIndex &index) const override 0289 { 0290 if (mTag.isEmpty()) { 0291 return true; 0292 } 0293 SemanticInfo info = model()->semanticInfoForSourceIndex(index); 0294 if (mWantMatchingTag) { 0295 return info.mTags.contains(mTag); 0296 } else { 0297 return !info.mTags.contains(mTag); 0298 } 0299 } 0300 0301 void setTag(const SemanticInfoTag &tag) 0302 { 0303 mTag = tag; 0304 model()->applyFilters(); 0305 } 0306 0307 void setWantMatchingTag(bool value) 0308 { 0309 mWantMatchingTag = value; 0310 model()->applyFilters(); 0311 } 0312 0313 private: 0314 SemanticInfoTag mTag; 0315 bool mWantMatchingTag; 0316 }; 0317 0318 class TagFilterWidget : public QWidget 0319 { 0320 Q_OBJECT 0321 public: 0322 TagFilterWidget(SortedDirModel *); 0323 ~TagFilterWidget() override; 0324 0325 private Q_SLOTS: 0326 void updateTagSetFilter(); 0327 0328 private: 0329 KComboBox *mModeComboBox; 0330 QComboBox *mTagComboBox; 0331 QPointer<TagFilter> mFilter; 0332 }; 0333 #endif 0334 0335 /** 0336 * This class manages the filter widgets in the filter frame and assign the 0337 * corresponding filters to the SortedDirModel 0338 */ 0339 class FilterController : public QObject 0340 { 0341 Q_OBJECT 0342 public: 0343 FilterController(QFrame *filterFrame, SortedDirModel *model); 0344 0345 QList<QAction *> actionList() const; 0346 0347 private Q_SLOTS: 0348 void addFilterByName(); 0349 void addFilterByDate(); 0350 #ifndef GWENVIEW_SEMANTICINFO_BACKEND_NONE 0351 void addFilterByRating(); 0352 void addFilterByTag(); 0353 #endif 0354 void slotFilterWidgetClosed(); 0355 0356 private: 0357 void addAction(const QString &text, const char *slot, const QKeySequence &shortcut); 0358 void addFilter(QWidget *widget); 0359 0360 FilterController *q; 0361 QFrame *mFrame; 0362 SortedDirModel *mDirModel; 0363 QList<QAction *> mActionList; 0364 0365 int mFilterWidgetCount; /**< How many filter widgets are in mFrame */ 0366 }; 0367 0368 } // namespace 0369 0370 #endif /* FILTERCONTROLLER_H */