Warning, file /office/calligra/libs/widgets/KoResourceFiltering.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*  This file is part of the KDE project
0002 
0003     Copyright (c) 2013 Sascha Suelzer <s.suelzer@gmail.com>
0004 
0005     This library is free software; you can redistribute it and/or
0006     modify it under the terms of the GNU Lesser General Public
0007     License as published by the Free Software Foundation; either
0008     version 2.1 of the License, or (at your option) any later version.
0009 
0010     This library is distributed in the hope that it will be useful,
0011     but WITHOUT ANY WARRANTY; without even the implied warranty of
0012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013     Lesser General Public License for more details.
0014 
0015     You should have received a copy of the GNU Lesser General Public
0016     License along with this library; if not, write to the Free Software
0017     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
0018  */
0019 
0020 #include "KoResourceFiltering.h"
0021 
0022 #include "KoResourceServer.h"
0023 
0024 #include <QStringList>
0025 #include <QString>
0026 
0027 
0028 class Q_DECL_HIDDEN KoResourceFiltering::Private
0029 {
0030 public:
0031     Private()
0032     : isTag("\\[([\\w\\s]+)\\]")
0033     , isExactMatch("\"([\\w\\s]+)\"")
0034     , searchTokenizer("\\s*,+\\s*")
0035     , hasNewFilters(false)
0036     , name(true)
0037     , filename(true)
0038     , resourceServer(0)
0039     {}
0040     QRegExp isTag;
0041     QRegExp isExactMatch;
0042     QRegExp searchTokenizer;
0043     bool hasNewFilters;
0044     bool name,filename;
0045     KoResourceServerBase *resourceServer;
0046     QStringList tagSetFilenames;
0047     QStringList includedNames;
0048     QStringList excludedNames;
0049     QString currentTag;
0050 };
0051 
0052 KoResourceFiltering::KoResourceFiltering() : d(new Private())
0053 {}
0054 
0055 KoResourceFiltering::~KoResourceFiltering()
0056 {
0057     delete d;
0058 }
0059 
0060 void KoResourceFiltering::configure(int filterType, bool enable) {
0061     switch (filterType) {
0062     case 0:
0063         d->name=true;
0064         d->filename=enable;
0065         break;
0066     case 1:
0067         d->name=enable;
0068         break;
0069     case 2:
0070         d->filename=enable;
0071         break;
0072     }
0073 }
0074 
0075 void KoResourceFiltering::setChanged()
0076 {
0077     d->hasNewFilters = true;
0078 }
0079 
0080 void KoResourceFiltering::setTagSetFilenames(const QStringList& filenames)
0081 {
0082     d->tagSetFilenames = filenames;
0083     d->excludedNames.clear();
0084     d->includedNames.clear();
0085     setChanged();
0086 }
0087 
0088 bool KoResourceFiltering::matchesResource(const QStringList &filteredList,const QStringList &filterList) const
0089 {
0090     Qt::CaseSensitivity sensitivity = Qt::CaseInsensitive;
0091     foreach (QString filter, filterList) {
0092         if (!filter.startsWith('"')) {
0093             foreach (QString filtered, filteredList) {
0094                 if (filtered.contains(filter,sensitivity)) {
0095                     return true;
0096                 }
0097             }
0098         }
0099         else if (d->name) {
0100             filter.remove('"');
0101             if (!filteredList.at(0).compare(filter)) {
0102                 return true;
0103             }
0104         }
0105     }
0106     return false;
0107 }
0108 
0109 void KoResourceFiltering::sanitizeExclusionList()
0110 {
0111    if(!d->includedNames.isEmpty()) {
0112 
0113         foreach (const QString &exclusion, d->excludedNames) {
0114             if (!excludeFilterIsValid(exclusion))
0115                 d->excludedNames.removeAll(exclusion);
0116         }
0117     }
0118 }
0119 
0120 QStringList KoResourceFiltering::tokenizeSearchString(const QString& searchString) const
0121 {
0122     return searchString.split(d->searchTokenizer, QString::SkipEmptyParts);
0123 }
0124 
0125 void KoResourceFiltering::populateIncludeExcludeFilters(const QStringList& filteredNames)
0126 {
0127     foreach (QString name, filteredNames) {
0128         QStringList* target;
0129 
0130         if(name.startsWith('!')) {
0131             name.remove('!');
0132             target = &d->excludedNames;
0133         } else {
0134             target = &d->includedNames;
0135         }
0136 
0137         if(!name.isEmpty()) {
0138             if (name.startsWith('[')) {
0139                 if (d->isTag.exactMatch(name) && d->resourceServer) {
0140                     name = d->isTag.cap(1);
0141                     (*target) += d->resourceServer->queryResources(name);
0142                 }
0143             }
0144             else if (name.startsWith('"')) {
0145                 if (d->isExactMatch.exactMatch(name)) {
0146                     target->push_back(name);
0147                 }
0148             }
0149             else {
0150                 target->push_back(name);
0151             }
0152         }
0153     }
0154     sanitizeExclusionList();
0155 }
0156 
0157 bool KoResourceFiltering::hasFilters() const
0158 {
0159     return (!d->tagSetFilenames.isEmpty() || !d->includedNames.isEmpty() || !d->excludedNames.isEmpty());
0160 }
0161 
0162 bool KoResourceFiltering::filtersHaveChanged() const
0163 {
0164     return d->hasNewFilters;
0165 }
0166 
0167 void KoResourceFiltering::setFilters(const QString &searchString)
0168 {
0169     d->excludedNames.clear();
0170     d->includedNames.clear();
0171     QStringList filteredNames = tokenizeSearchString(searchString);
0172     populateIncludeExcludeFilters(filteredNames);
0173     setChanged();
0174 }
0175 
0176 bool KoResourceFiltering::presetMatchesSearch(KoResource * resource) const
0177 {
0178     QList<QString> filteredList;
0179 
0180     QString resourceFileName = resource->shortFilename();
0181     QString resourceName = resource->name();
0182 
0183     if (d->name) {
0184         filteredList.push_front(resourceName);
0185     }
0186 
0187     if (d->filename) {
0188         filteredList.push_back(resourceFileName);
0189     }
0190 
0191     if (matchesResource(filteredList,d->excludedNames)) {
0192         return false;
0193     }
0194 
0195     if (matchesResource(filteredList,d->includedNames)) {
0196         return true;
0197     }
0198 
0199     foreach (const QString &filter, d->tagSetFilenames) {
0200         if (!resourceFileName.compare(filter) || !resourceName.compare(filter)) {
0201             return true;
0202         }
0203     }
0204 
0205     return false;
0206 }
0207 
0208 void KoResourceFiltering::setInclusions(const QStringList &inclusions)
0209 {
0210     d->includedNames = inclusions;
0211     setChanged();
0212 }
0213 
0214 void KoResourceFiltering::setExclusions(const QStringList &exclusions)
0215 {
0216     d->excludedNames = exclusions;
0217     setChanged();
0218 }
0219 
0220 bool KoResourceFiltering::excludeFilterIsValid(const QString &exclusion)
0221 {
0222     foreach(const QString &inclusion, d->includedNames) {
0223         if ((inclusion.startsWith(exclusion)  && exclusion.size() <= inclusion.size())) {
0224             return false;
0225         }
0226     }
0227     return true;
0228 }
0229 
0230 QList< KoResource* > KoResourceFiltering::filterResources(QList< KoResource* > resources)
0231 {
0232 
0233     foreach(KoResource* resource, resources) {
0234         if(!presetMatchesSearch(resource)) {
0235             resources.removeAll(resource);
0236         }
0237     }
0238     setDoneFiltering();
0239     return resources;
0240 }
0241 
0242 void KoResourceFiltering::setDoneFiltering()
0243 {
0244     d->hasNewFilters = false;
0245 }
0246 
0247 void KoResourceFiltering::rebuildCurrentTagFilenames()
0248 {
0249     d->tagSetFilenames = d->resourceServer->queryResources(d->currentTag);
0250 }
0251 
0252 void KoResourceFiltering::setCurrentTag(const QString& tagSet)
0253 {
0254     d->currentTag = tagSet;
0255     rebuildCurrentTagFilenames();
0256 }
0257 
0258 void KoResourceFiltering::setResourceServer(KoResourceServerBase* resourceServer)
0259 {
0260     d->resourceServer = resourceServer;
0261 }