1 #include "filefilteritems.h"
3 #include <QtGui/QImageReader>
5 namespace QmlProjectManager {
7 FileFilterBaseItem::FileFilterBaseItem(QObject *parent) :
8 QmlProjectContentItem(parent),
9 m_recurse(RecurseDefault)
11 m_updateFileListTimer.setSingleShot(true);
12 m_updateFileListTimer.setInterval(50);
13 connect(&m_dirWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(updateFileList()));
14 connect(&m_updateFileListTimer, SIGNAL(timeout()), this, SLOT(updateFileListNow()));
17 QString FileFilterBaseItem::directory() const
22 void FileFilterBaseItem::setDirectory(const QString &dirPath)
24 if (m_rootDir == dirPath)
27 emit directoryChanged();
32 void FileFilterBaseItem::setDefaultDirectory(const QString &dirPath)
34 if (m_defaultDir == dirPath)
36 m_defaultDir = dirPath;
41 QString FileFilterBaseItem::filter() const
46 void FileFilterBaseItem::setFilter(const QString &filter)
48 if (filter == m_filter)
53 m_fileSuffixes.clear();
55 foreach (const QString &pattern, filter.split(QLatin1Char(';'))) {
56 if (pattern.isEmpty())
58 // decide if it's a canonical pattern like *.x
59 if (pattern.startsWith(QLatin1String("*."))) {
60 const QString suffix = pattern.right(pattern.size() - 1);
61 if (!suffix.contains(QLatin1Char('*'))
62 && !suffix.contains(QLatin1Char('?'))
63 && !suffix.contains(QLatin1Char('['))) {
64 m_fileSuffixes << suffix;
68 m_regExpList << QRegExp(pattern, Qt::CaseInsensitive, QRegExp::Wildcard);
74 bool FileFilterBaseItem::recursive() const
77 if (m_recurse == Recurse) {
79 } else if (m_recurse == DoNotRecurse) {
81 } else { // RecurseDefault
82 if (m_explicitFiles.isEmpty()) {
91 void FileFilterBaseItem::setRecursive(bool recurse)
93 bool oldRecursive = recursive();
98 m_recurse = DoNotRecurse;
101 if (recurse != oldRecursive)
105 QStringList FileFilterBaseItem::pathsProperty() const
107 return m_explicitFiles;
110 void FileFilterBaseItem::setPathsProperty(const QStringList &path)
112 m_explicitFiles = path;
116 QStringList FileFilterBaseItem::files() const
118 return m_files.toList();
122 Check whether filter matches a file path - regardless whether the file already exists or not.
124 @param filePath: absolute file path
126 bool FileFilterBaseItem::matchesFile(const QString &filePath) const
128 foreach (const QString &explicitFile, m_explicitFiles) {
129 if (absolutePath(explicitFile) == filePath)
133 const QString &fileName = QFileInfo(filePath).fileName();
135 if (!fileMatches(fileName))
138 const QDir fileDir = QFileInfo(filePath).absoluteDir();
139 foreach (const QString &watchedDirectory, m_dirWatcher.directories()) {
140 if (QDir(watchedDirectory) == fileDir)
147 QString FileFilterBaseItem::absolutePath(const QString &path) const
149 if (QFileInfo(path).isAbsolute())
151 return QDir(absoluteDir()).absoluteFilePath(path);
154 QString FileFilterBaseItem::absoluteDir() const
157 if (QFileInfo(m_rootDir).isAbsolute()) {
158 absoluteDir = m_rootDir;
159 } else if (!m_defaultDir.isEmpty()) {
160 absoluteDir = m_defaultDir + QLatin1Char('/') + m_rootDir;
166 void FileFilterBaseItem::updateFileList()
168 if (!m_updateFileListTimer.isActive())
169 m_updateFileListTimer.start();
172 void FileFilterBaseItem::updateFileListNow()
174 if (m_updateFileListTimer.isActive())
175 m_updateFileListTimer.stop();
177 const QString projectDir = absoluteDir();
178 if (projectDir.isEmpty())
181 QSet<QString> dirsToBeWatched;
182 QSet<QString> newFiles;
183 foreach (const QString &explicitPath, m_explicitFiles) {
184 newFiles << absolutePath(explicitPath);
186 if ((!m_fileSuffixes.isEmpty() || !m_regExpList.isEmpty()) && m_explicitFiles.isEmpty())
187 newFiles += filesInSubTree(QDir(m_defaultDir), QDir(projectDir), &dirsToBeWatched);
189 if (newFiles != m_files) {
190 QSet<QString> addedFiles = newFiles;
191 QSet<QString> removedFiles = m_files;
192 QSet<QString> unchanged = newFiles;
193 unchanged.intersect(m_files);
194 addedFiles.subtract(unchanged);
195 removedFiles.subtract(unchanged);
198 emit filesChanged(addedFiles, removedFiles);
201 // update watched directories
202 const QSet<QString> oldDirs = m_dirWatcher.directories().toSet();
203 const QSet<QString> unwatchDirs = oldDirs - dirsToBeWatched;
204 const QSet<QString> watchDirs = dirsToBeWatched - oldDirs;
206 if (!unwatchDirs.isEmpty())
207 m_dirWatcher.removeDirectories(unwatchDirs.toList());
208 if (!watchDirs.isEmpty())
209 m_dirWatcher.addDirectories(watchDirs.toList());
212 bool FileFilterBaseItem::fileMatches(const QString &fileName) const
214 foreach (const QString &suffix, m_fileSuffixes) {
215 if (fileName.endsWith(suffix, Qt::CaseInsensitive)) {
220 foreach (const QRegExp &filter, m_regExpList) {
221 if (filter.exactMatch(fileName)) {
229 QSet<QString> FileFilterBaseItem::filesInSubTree(const QDir &rootDir, const QDir &dir, QSet<QString> *parsedDirs)
231 QSet<QString> fileSet;
234 parsedDirs->insert(dir.absolutePath());
236 foreach (const QFileInfo &file, dir.entryInfoList(QDir::Files)) {
237 const QString fileName = file.fileName();
239 if (fileMatches(fileName))
240 fileSet.insert(file.absoluteFilePath());
244 foreach (const QFileInfo &subDir, dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) {
245 fileSet += filesInSubTree(rootDir, QDir(subDir.absoluteFilePath()), parsedDirs);
251 QmlFileFilterItem::QmlFileFilterItem(QObject *parent)
252 : FileFilterBaseItem(parent)
254 setFilter(QLatin1String("*.qml"));
257 JsFileFilterItem::JsFileFilterItem(QObject *parent)
258 : FileFilterBaseItem(parent)
260 setFilter(QLatin1String("*.js"));
263 void JsFileFilterItem::setFilter(const QString &filter)
265 FileFilterBaseItem::setFilter(filter);
266 emit filterChanged();
269 ImageFileFilterItem::ImageFileFilterItem(QObject *parent)
270 : FileFilterBaseItem(parent)
273 // supported image formats according to
274 QList<QByteArray> extensions = QImageReader::supportedImageFormats();
275 foreach (const QByteArray &extension, extensions) {
276 filter.append(QString("*.%1;").arg(QString::fromAscii(extension)));
281 void ImageFileFilterItem::setFilter(const QString &filter)
283 FileFilterBaseItem::setFilter(filter);
284 emit filterChanged();
287 CssFileFilterItem::CssFileFilterItem(QObject *parent)
288 : FileFilterBaseItem(parent)
290 setFilter(QLatin1String("*.css"));
293 void CssFileFilterItem::setFilter(const QString &filter)
295 FileFilterBaseItem::setFilter(filter);
296 emit filterChanged();
299 } // namespace QmlProjectManager