File indexing completed on 2024-05-19 04:56:02
0001 /** 0002 * \file fileinfogatherer_p.h 0003 * \cond 0004 * Taken from Qt Git, revision e73bd4a 0005 * qtbase/src/widgets/dialogs/qfileinfogatherer_p.h 0006 * Adapted for Kid3 with the following changes: 0007 * - Remove Q prefix from class names 0008 * - Remove QT_..._CONFIG, QT_..._NAMESPACE, Q_..._EXPORT... 0009 * - Allow compilation without Qt private headers (USE_QT_PRIVATE_HEADERS) 0010 * - Replace include guards by #pragma once 0011 * - Remove dependencies to Qt5::Widgets 0012 */ 0013 /**************************************************************************** 0014 ** 0015 ** Copyright (C) 2016 The Qt Company Ltd. 0016 ** Contact: https://www.qt.io/licensing/ 0017 ** 0018 ** This file is part of the QtWidgets module of the Qt Toolkit. 0019 ** 0020 ** $QT_BEGIN_LICENSE:LGPL$ 0021 ** Commercial License Usage 0022 ** Licensees holding valid commercial Qt licenses may use this file in 0023 ** accordance with the commercial license agreement provided with the 0024 ** Software or, alternatively, in accordance with the terms contained in 0025 ** a written agreement between you and The Qt Company. For licensing terms 0026 ** and conditions see https://www.qt.io/terms-conditions. For further 0027 ** information use the contact form at https://www.qt.io/contact-us. 0028 ** 0029 ** GNU Lesser General Public License Usage 0030 ** Alternatively, this file may be used under the terms of the GNU Lesser 0031 ** General Public License version 3 as published by the Free Software 0032 ** Foundation and appearing in the file LICENSE.LGPL3 included in the 0033 ** packaging of this file. Please review the following information to 0034 ** ensure the GNU Lesser General Public License version 3 requirements 0035 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 0036 ** 0037 ** GNU General Public License Usage 0038 ** Alternatively, this file may be used under the terms of the GNU 0039 ** General Public License version 2.0 or (at your option) the GNU General 0040 ** Public license version 3 or any later version approved by the KDE Free 0041 ** Qt Foundation. The licenses are as published by the Free Software 0042 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 0043 ** included in the packaging of this file. Please review the following 0044 ** information to ensure the GNU General Public License requirements will 0045 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and 0046 ** https://www.gnu.org/licenses/gpl-3.0.html. 0047 ** 0048 ** $QT_END_LICENSE$ 0049 ** 0050 ****************************************************************************/ 0051 0052 #pragma once 0053 0054 // 0055 // W A R N I N G 0056 // ------------- 0057 // 0058 // This file is not part of the Qt API. It exists purely as an 0059 // implementation detail. This header file may change from version to 0060 // version without notice, or even be removed. 0061 // 0062 // We mean it. 0063 // 0064 0065 #include <qthread.h> 0066 #include <qmutex.h> 0067 #include <qwaitcondition.h> 0068 #include <qfilesystemwatcher.h> 0069 #include <qvariant.h> 0070 #include <qpair.h> 0071 #include <qstack.h> 0072 #include <qdatetime.h> 0073 #include <qdir.h> 0074 #include <qelapsedtimer.h> 0075 0076 #ifdef USE_QT_PRIVATE_HEADERS 0077 #include <private/qfilesystemengine_p.h> 0078 #endif 0079 0080 class ExtendedInformation { 0081 public: 0082 enum Type { Dir, File, System }; 0083 0084 ExtendedInformation() {} 0085 explicit ExtendedInformation(const QFileInfo &info) : mFileInfo(info) {} 0086 0087 inline bool isDir() { return type() == Dir; } 0088 inline bool isFile() { return type() == File; } 0089 inline bool isSystem() { return type() == System; } 0090 0091 bool operator ==(const ExtendedInformation &fileInfo) const { 0092 return mFileInfo == fileInfo.mFileInfo 0093 && displayType == fileInfo.displayType 0094 && permissions() == fileInfo.permissions() 0095 && lastModified() == fileInfo.lastModified(); 0096 } 0097 0098 #ifndef QT_NO_FSFILEENGINE 0099 bool isCaseSensitive() const { 0100 #ifdef USE_QT_PRIVATE_HEADERS 0101 return QFileSystemEngine::isCaseSensitive(); 0102 #else 0103 return false; 0104 #endif 0105 } 0106 #endif 0107 0108 QFile::Permissions permissions() const { 0109 #ifdef Q_OS_WIN 0110 if (isInvalidDrive(mFileInfo.filePath())) { 0111 return {}; 0112 } 0113 #endif 0114 return mFileInfo.permissions(); 0115 } 0116 0117 Type type() const { 0118 if (mFileInfo.isDir()) { 0119 return ExtendedInformation::Dir; 0120 } 0121 if (mFileInfo.isFile()) { 0122 return ExtendedInformation::File; 0123 } 0124 if (!mFileInfo.exists() && mFileInfo.isSymLink()) { 0125 return ExtendedInformation::System; 0126 } 0127 return ExtendedInformation::System; 0128 } 0129 0130 bool isSymLink(bool ignoreNtfsSymLinks = false) const 0131 { 0132 if (ignoreNtfsSymLinks) { 0133 #ifdef Q_OS_WIN 0134 return !mFileInfo.suffix().compare(QLatin1String("lnk"), Qt::CaseInsensitive); 0135 #endif 0136 } 0137 return mFileInfo.isSymLink(); 0138 } 0139 0140 bool isHidden() const { 0141 return mFileInfo.isHidden(); 0142 } 0143 0144 QFileInfo fileInfo() const { 0145 return mFileInfo; 0146 } 0147 0148 QDateTime lastModified() const { 0149 return mFileInfo.lastModified(); 0150 } 0151 0152 qint64 size() const { 0153 qint64 size = -1; 0154 if (type() == ExtendedInformation::Dir) 0155 size = 0; 0156 if (type() == ExtendedInformation::File) 0157 size = mFileInfo.size(); 0158 if (!mFileInfo.exists() && !mFileInfo.isSymLink()) 0159 size = -1; 0160 return size; 0161 } 0162 0163 QString displayType; 0164 QVariant icon; 0165 0166 private : 0167 #ifdef Q_OS_WIN 0168 static bool isInvalidDrive(const QString &path); 0169 #endif 0170 QFileInfo mFileInfo; 0171 }; 0172 0173 class AbstractFileDecorationProvider; 0174 0175 class FileInfoGatherer : public QThread 0176 { 0177 Q_OBJECT 0178 0179 Q_SIGNALS: 0180 void updates(const QString &directory, const QVector<QPair<QString, QFileInfo> > &updates); 0181 void newListOfFiles(const QString &directory, const QStringList &listOfFiles) const; 0182 void nameResolved(const QString &fileName, const QString &resolvedName) const; 0183 void directoryLoaded(const QString &path); 0184 0185 public: 0186 explicit FileInfoGatherer(QObject *parent = 0); 0187 ~FileInfoGatherer(); 0188 0189 // only callable from this->thread(): 0190 void clear(); 0191 void addPath(const QString &path); 0192 void removePath(const QString &path); 0193 ExtendedInformation getInfo(const QFileInfo &fileInfo) const; 0194 AbstractFileDecorationProvider *decorationProvider() const; 0195 bool resolveSymlinks() const; 0196 0197 public Q_SLOTS: 0198 void list(const QString &directoryPath); 0199 void fetchExtendedInformation(const QString &path, const QStringList &files); 0200 void updateFile(const QString &filePath); 0201 void setResolveSymlinks(bool enable); 0202 void setDecorationProvider(AbstractFileDecorationProvider *provider); 0203 0204 private Q_SLOTS: 0205 void driveAdded(); 0206 void driveRemoved(); 0207 0208 private: 0209 void run() Q_DECL_OVERRIDE; 0210 // called by run(): 0211 void getFileInfos(const QString &path, const QStringList &files); 0212 void fetch(const QFileInfo &fileInfo, QElapsedTimer &base, bool &firstTime, QVector<QPair<QString, QFileInfo> > &updatedFiles, const QString &path); 0213 0214 private: 0215 mutable QMutex mutex; 0216 // begin protected by mutex 0217 QWaitCondition condition; 0218 QStack<QString> path; 0219 QStack<QStringList> files; 0220 // end protected by mutex 0221 QAtomicInt abort; 0222 0223 #ifndef QT_NO_FILESYSTEMWATCHER 0224 QFileSystemWatcher *watcher; 0225 #endif 0226 #ifdef Q_OS_WIN 0227 bool m_resolveSymlinks; // not accessed by run() 0228 #endif 0229 AbstractFileDecorationProvider *m_decorationProvider; 0230 }; 0231 /** \endcond */