File indexing completed on 2024-05-05 17:56:56

0001 /*
0002     SPDX-FileCopyrightText: 2001 Shie Erlich <krusader@users.sourceforge.net>
0003     SPDX-FileCopyrightText: 2001 Rafi Yanai <krusader@users.sourceforge.net>
0004     SPDX-FileCopyrightText: 2004-2022 Krusader Krew <https://krusader.org>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 #ifndef KRQUERY_H
0009 #define KRQUERY_H
0010 
0011 // QtCore
0012 #include <QDateTime>
0013 #include <QElapsedTimer>
0014 #include <QStringList>
0015 #include <QUrl>
0016 
0017 #include <KConfigCore/KConfigGroup>
0018 #include <KIO/Job>
0019 
0020 class QTextCodec;
0021 
0022 class FileItem;
0023 
0024 /**
0025  * @brief A search query for files
0026  *
0027  * Can be used for finding or selecting files and folders by multiple limiting search criteria
0028  */
0029 class KrQuery : public QObject
0030 {
0031     Q_OBJECT
0032 
0033 public:
0034     // null query
0035     KrQuery();
0036     // query only with name filter
0037     explicit KrQuery(const QString &name, bool matchCase = true);
0038     // copy constructor
0039     KrQuery(const KrQuery &);
0040     // let operator
0041     KrQuery &operator=(const KrQuery &);
0042     // destructor
0043     ~KrQuery() override;
0044 
0045     // load parameters from config
0046     void load(const KConfigGroup &cfg);
0047     // save parameters to config
0048     void save(KConfigGroup cfg);
0049 
0050     // matching a file with the query
0051     bool match(FileItem *file) const; // checks if the given fileItem object matches the conditions
0052     // matching a name with the query
0053     bool match(const QString &name) const; // matching the filename only
0054     // matching the name of the directory
0055     bool matchDirName(const QString &name) const;
0056 
0057     // sets the text for name filtering
0058     void setNameFilter(const QString &text, bool cs = true);
0059     // returns the current filter mask
0060     const QString &nameFilter() const
0061     {
0062         return origFilter;
0063     }
0064     // returns whether the filter is case sensitive
0065     bool isCaseSensitive()
0066     {
0067         return matchesCaseSensitive;
0068     }
0069 
0070     // returns if the filter is null (was cancelled)
0071     bool isNull()
0072     {
0073         return bNull;
0074     }
0075 
0076     // sets the content part of the query
0077     void setContent(const QString &content, bool cs = true, bool wholeWord = false, const QString &encoding = QString(), bool regExp = false);
0078     const QString content()
0079     {
0080         return contain;
0081     }
0082 
0083     // sets the minimum file size limit
0084     void setMinimumFileSize(KIO::filesize_t);
0085     // sets the maximum file size limit
0086     void setMaximumFileSize(KIO::filesize_t);
0087 
0088     // sets the time the file newer than
0089     void setNewerThan(time_t time);
0090     // sets the time the file older than
0091     void setOlderThan(time_t time);
0092 
0093     // sets the owner
0094     void setOwner(const QString &ownerIn);
0095     // sets the group
0096     void setGroup(const QString &groupIn);
0097     // sets the permissions
0098     void setPermissions(const QString &permIn);
0099 
0100     // sets the mimetype for the query
0101     // type, must be one of the following:
0102     // 1. a valid mime type name
0103     // 2. one of: i18n("Archives"),   i18n("Folders"), i18n("Image Files")
0104     //            i18n("Text Files"), i18n("Video Files"), i18n("Audio Files")
0105     // 3. i18n("Custom") in which case you must supply a list of valid mime-types
0106     //    in the member QStringList customType
0107     void setMimeType(const QString &typeIn, QStringList customList = QStringList());
0108     // true if setMimeType was called
0109     bool hasMimeType()
0110     {
0111         return type.isEmpty();
0112     }
0113 
0114     // sets the search in archive flag
0115     void setSearchInArchives(bool flag)
0116     {
0117         inArchive = flag;
0118     }
0119     // gets the search in archive flag
0120     bool searchInArchives()
0121     {
0122         return inArchive;
0123     }
0124     // sets the recursive flag
0125     void setRecursive(bool flag)
0126     {
0127         recurse = flag;
0128     }
0129     // gets the recursive flag
0130     bool isRecursive()
0131     {
0132         return recurse;
0133     }
0134     // sets whether to follow symbolic links
0135     void setFollowLinks(bool flag)
0136     {
0137         followLinksP = flag;
0138     }
0139     // gets whether to follow symbolic links
0140     bool followLinks()
0141     {
0142         return followLinksP;
0143     }
0144 
0145     // sets the folder names which the searcher will exclude from traversing
0146     void setExcludeFolderNames(const QStringList &urls);
0147     // gets the folder names which the searcher excludes
0148     const QStringList excludeFolderNames()
0149     {
0150         return excludedFolderNames;
0151     }
0152     // sets the folders where the searcher will search
0153     void setSearchInDirs(const QList<QUrl> &urls);
0154     // gets the folders where the searcher searches
0155     const QList<QUrl> &searchInDirs()
0156     {
0157         return whereToSearch;
0158     }
0159     // sets the folders where search is not permitted
0160     void setDontSearchInDirs(const QList<QUrl> &urls);
0161     // gets the folders where search is not permitted
0162     const QList<QUrl> &dontSearchInDirs()
0163     {
0164         return whereNotToSearch;
0165     }
0166     // checks if a URL is excluded
0167     bool isExcluded(const QUrl &url);
0168     // gives whether we search for content
0169     bool isContentSearched() const
0170     {
0171         return !contain.isEmpty();
0172     }
0173 
0174     bool checkLine(const QString &line, bool backwards = false) const;
0175     const QString &foundText() const
0176     {
0177         return lastSuccessfulGrep;
0178     }
0179     int matchIndex() const
0180     {
0181         return lastSuccessfulGrepMatchIndex;
0182     }
0183     int matchLength() const
0184     {
0185         return lastSuccessfulGrepMatchLength;
0186     }
0187 
0188 protected:
0189     // important to know whether the event processor is connected
0190     void connectNotify(const QMetaMethod &signal) override;
0191     // important to know whether the event processor is connected
0192     void disconnectNotify(const QMetaMethod &signal) override;
0193 
0194 protected:
0195     QStringList matches; // what to search
0196     QStringList excludes; // what to exclude
0197     QStringList includedDirs; // what dirs to include
0198     QStringList excludedDirs; // what dirs to exclude
0199     bool matchesCaseSensitive;
0200 
0201     bool bNull; // flag if the query is null
0202 
0203     QString contain; // file must contain this string
0204     bool containCaseSensetive;
0205     bool containWholeWord;
0206     bool containRegExp;
0207 
0208     KIO::filesize_t minSize;
0209     KIO::filesize_t maxSize;
0210 
0211     time_t newerThen;
0212     time_t olderThen;
0213 
0214     QString owner;
0215     QString group;
0216     QString perm;
0217 
0218     QString type;
0219     QStringList customType;
0220 
0221     bool inArchive; // if true- search in archive.
0222     bool recurse; // if true recurse ob sub-dirs...
0223     bool followLinksP;
0224 
0225     QStringList excludedFolderNames; // substrings of paths where not to search
0226     QList<QUrl> whereToSearch; // directories to search
0227     QList<QUrl> whereNotToSearch; // directories NOT to search
0228 
0229 signals:
0230     void status(const QString &name);
0231     void processEvents(bool &stopped);
0232 
0233 private:
0234     bool matchCommon(const QString &, const QStringList &, const QStringList &) const;
0235     bool checkPerm(QString perm) const;
0236     bool checkType(const QString &mime) const;
0237     bool containsContent(const QString &file) const;
0238     bool containsContent(const QUrl &url) const;
0239     bool checkBuffer(const char *data, int len) const;
0240     bool checkTimer() const;
0241     QStringList split(QString);
0242 
0243 private slots:
0244     void containsContentData(KIO::Job *, const QByteArray &);
0245     void containsContentFinished(KJob *);
0246 
0247 private:
0248     QString origFilter;
0249     mutable bool busy;
0250     mutable bool containsContentResult;
0251     mutable char *receivedBuffer;
0252     mutable int receivedBufferLen;
0253     mutable QString lastSuccessfulGrep;
0254     mutable int lastSuccessfulGrepMatchIndex;
0255     mutable int lastSuccessfulGrepMatchLength;
0256     mutable QString fileName;
0257     mutable KIO::filesize_t receivedBytes;
0258     mutable KIO::filesize_t totalBytes;
0259     mutable int processEventsConnected;
0260     mutable QElapsedTimer timer;
0261 
0262     QTextCodec *codec;
0263 
0264     const char *encodedEnter;
0265     int encodedEnterLen;
0266     QByteArray encodedEnterArray;
0267 };
0268 
0269 #endif