1 #include "filefilteritems.h"
3 #include <QtGui/QImageReader>
5 namespace QmlProjectManager {
7 FileFilterBaseItem::FileFilterBaseItem(QObject *parent) :
8 QmlProjectContentItem(parent),
9 m_recurse(RecurseDefault)
11 connect(&m_dirWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(updateFileList()));
14 QString FileFilterBaseItem::directory() const
19 void FileFilterBaseItem::setDirectory(const QString &dirPath)
21 if (m_rootDir == dirPath)
24 emit directoryChanged();
29 void FileFilterBaseItem::setDefaultDirectory(const QString &dirPath)
31 if (m_defaultDir == dirPath)
33 m_defaultDir = dirPath;
38 QString FileFilterBaseItem::filter() const
43 void FileFilterBaseItem::setFilter(const QString &filter)
45 if (filter == m_filter)
50 m_fileSuffixes.clear();
52 foreach (const QString &pattern, filter.split(QLatin1Char(';'))) {
53 if (pattern.isEmpty())
55 // decide if it's a canonical pattern like *.x
56 if (pattern.startsWith(QLatin1String("*."))) {
57 const QString suffix = pattern.right(pattern.size() - 1);
58 if (!suffix.contains(QLatin1Char('*'))
59 && !suffix.contains(QLatin1Char('?'))
60 && !suffix.contains(QLatin1Char('['))) {
61 m_fileSuffixes << suffix;
65 m_regExpList << QRegExp(pattern, Qt::CaseInsensitive, QRegExp::Wildcard);
71 bool FileFilterBaseItem::recursive() const
74 if (m_recurse == Recurse) {
76 } else if (m_recurse == DoNotRecurse) {
78 } else { // RecurseDefault
79 if (m_explicitFiles.isEmpty()) {
88 void FileFilterBaseItem::setRecursive(bool recurse)
90 bool oldRecursive = recursive();
95 m_recurse = DoNotRecurse;
98 if (recurse != oldRecursive)
102 QStringList FileFilterBaseItem::pathsProperty() const
104 return m_explicitFiles;
107 void FileFilterBaseItem::setPathsProperty(const QStringList &path)
109 m_explicitFiles = path;
113 QStringList FileFilterBaseItem::files() const
115 return m_files.toList();
119 Check whether filter matches a file path - regardless whether the file already exists or not.
121 @param filePath: absolute file path
123 bool FileFilterBaseItem::matchesFile(const QString &filePath) const
125 foreach (const QString &explicitFile, m_explicitFiles) {
126 if (absolutePath(explicitFile) == filePath)
130 const QString &fileName = QFileInfo(filePath).fileName();
132 if (!fileMatches(fileName))
135 const QDir fileDir = QFileInfo(filePath).absoluteDir();
136 foreach (const QString &watchedDirectory, m_dirWatcher.directories()) {
137 if (QDir(watchedDirectory) == fileDir)
144 QString FileFilterBaseItem::absolutePath(const QString &path) const
146 if (QFileInfo(path).isAbsolute())
148 return QDir(absoluteDir()).absoluteFilePath(path);
151 QString FileFilterBaseItem::absoluteDir() const
154 if (QFileInfo(m_rootDir).isAbsolute()) {
155 absoluteDir = m_rootDir;
156 } else if (!m_defaultDir.isEmpty()) {
157 absoluteDir = m_defaultDir + QLatin1Char('/') + m_rootDir;
163 void FileFilterBaseItem::updateFileList()
165 const QString projectDir = absoluteDir();
166 if (projectDir.isEmpty())
169 QSet<QString> dirsToBeWatched;
170 QSet<QString> newFiles;
171 foreach (const QString &explicitPath, m_explicitFiles) {
172 newFiles << absolutePath(explicitPath);
174 if ((!m_fileSuffixes.isEmpty() || !m_regExpList.isEmpty()) && m_explicitFiles.isEmpty())
175 newFiles += filesInSubTree(QDir(m_defaultDir), QDir(projectDir), &dirsToBeWatched);
177 if (newFiles != m_files) {
178 QSet<QString> addedFiles = newFiles;
179 QSet<QString> removedFiles = m_files;
180 QSet<QString> unchanged = newFiles;
181 unchanged.intersect(m_files);
182 addedFiles.subtract(unchanged);
183 removedFiles.subtract(unchanged);
186 emit filesChanged(addedFiles, removedFiles);
189 // update watched directories
190 const QSet<QString> oldDirs = m_dirWatcher.directories().toSet();
191 const QSet<QString> unwatchDirs = oldDirs - dirsToBeWatched;
192 const QSet<QString> watchDirs = dirsToBeWatched - oldDirs;
194 if (!unwatchDirs.isEmpty())
195 m_dirWatcher.removeDirectories(unwatchDirs.toList());
196 if (!watchDirs.isEmpty())
197 m_dirWatcher.addDirectories(watchDirs.toList());
200 bool FileFilterBaseItem::fileMatches(const QString &fileName) const
202 foreach (const QString &suffix, m_fileSuffixes) {
203 if (fileName.endsWith(suffix, Qt::CaseInsensitive)) {
208 foreach (const QRegExp &filter, m_regExpList) {
209 if (filter.exactMatch(fileName)) {
217 QSet<QString> FileFilterBaseItem::filesInSubTree(const QDir &rootDir, const QDir &dir, QSet<QString> *parsedDirs)
219 QSet<QString> fileSet;
222 parsedDirs->insert(dir.absolutePath());
224 foreach (const QFileInfo &file, dir.entryInfoList(QDir::Files)) {
225 const QString fileName = file.fileName();
227 if (fileMatches(fileName))
228 fileSet.insert(file.absoluteFilePath());
232 foreach (const QFileInfo &subDir, dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) {
233 fileSet += filesInSubTree(rootDir, QDir(subDir.absoluteFilePath()), parsedDirs);
239 QmlFileFilterItem::QmlFileFilterItem(QObject *parent)
240 : FileFilterBaseItem(parent)
242 setFilter(QLatin1String("*.qml"));
245 JsFileFilterItem::JsFileFilterItem(QObject *parent)
246 : FileFilterBaseItem(parent)
248 setFilter(QLatin1String("*.js"));
251 void JsFileFilterItem::setFilter(const QString &filter)
253 FileFilterBaseItem::setFilter(filter);
254 emit filterChanged();
257 ImageFileFilterItem::ImageFileFilterItem(QObject *parent)
258 : FileFilterBaseItem(parent)
261 // supported image formats according to
262 QList<QByteArray> extensions = QImageReader::supportedImageFormats();
263 foreach (const QByteArray &extension, extensions) {
264 filter.append(QString("*.%1;").arg(QString::fromAscii(extension)));
269 void ImageFileFilterItem::setFilter(const QString &filter)
271 FileFilterBaseItem::setFilter(filter);
272 emit filterChanged();
275 CssFileFilterItem::CssFileFilterItem(QObject *parent)
276 : FileFilterBaseItem(parent)
278 setFilter(QLatin1String("*.css"));
281 void CssFileFilterItem::setFilter(const QString &filter)
283 FileFilterBaseItem::setFilter(filter);
284 emit filterChanged();
287 } // namespace QmlProjectManager