forked from qt-creator/qt-creator
Update project tree if .qmlproject file / included directories change
This commit is contained in:
@@ -7,6 +7,8 @@ FileFilterBaseItem::FileFilterBaseItem(QObject *parent) :
|
||||
QmlProjectContentItem(parent),
|
||||
m_recursive(false)
|
||||
{
|
||||
connect(&m_fsWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(updateFileList()));
|
||||
connect(&m_fsWatcher, SIGNAL(fileChanged(QString)), this, SLOT(updateFileList()));
|
||||
}
|
||||
|
||||
QString FileFilterBaseItem::directory() const
|
||||
@@ -82,24 +84,48 @@ QString FileFilterBaseItem::absoluteDir() const
|
||||
|
||||
void FileFilterBaseItem::updateFileList()
|
||||
{
|
||||
const QString dir = absoluteDir();
|
||||
if (dir.isEmpty())
|
||||
const QString projectDir = absoluteDir();
|
||||
if (projectDir.isEmpty())
|
||||
return;
|
||||
|
||||
const QSet<QString> newFiles = filesInSubTree(QDir(m_defaultDir), QDir(dir));
|
||||
QSet<QString> dirsToBeWatched;
|
||||
const QSet<QString> newFiles = filesInSubTree(QDir(m_defaultDir), QDir(projectDir), &dirsToBeWatched);
|
||||
|
||||
if (newFiles != m_files) {
|
||||
// update watched files
|
||||
foreach (const QString &file, m_files - newFiles) {
|
||||
m_fsWatcher.removePath(QDir(projectDir).absoluteFilePath(file));
|
||||
}
|
||||
foreach (const QString &file, newFiles - m_files) {
|
||||
m_fsWatcher.addPath(QDir(projectDir).absoluteFilePath(file));
|
||||
}
|
||||
|
||||
m_files = newFiles;
|
||||
|
||||
emit filesChanged();
|
||||
}
|
||||
|
||||
// update watched directories
|
||||
QSet<QString> watchedDirectories = m_fsWatcher.directories().toSet();
|
||||
foreach (const QString &dir, watchedDirectories - dirsToBeWatched) {
|
||||
m_fsWatcher.removePath(QDir(projectDir).absoluteFilePath(dir));
|
||||
}
|
||||
foreach (const QString &dir, dirsToBeWatched - watchedDirectories) {
|
||||
m_fsWatcher.addPath(QDir(projectDir).absoluteFilePath(dir));
|
||||
}
|
||||
}
|
||||
|
||||
QSet<QString> FileFilterBaseItem::filesInSubTree(const QDir &rootDir, const QDir &dir)
|
||||
QSet<QString> FileFilterBaseItem::filesInSubTree(const QDir &rootDir, const QDir &dir, QSet<QString> *parsedDirs)
|
||||
{
|
||||
QSet<QString> fileSet;
|
||||
|
||||
if (parsedDirs)
|
||||
parsedDirs->insert(dir.absolutePath());
|
||||
|
||||
foreach (const QFileInfo &file, dir.entryInfoList(QDir::Files)) {
|
||||
if (m_regex.exactMatch(file.fileName()))
|
||||
if (m_regex.exactMatch(file.fileName())) {
|
||||
fileSet.insert(rootDir.relativeFilePath(file.absoluteFilePath()));
|
||||
}
|
||||
}
|
||||
|
||||
if (m_recursive) {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <QObject>
|
||||
#include <QSet>
|
||||
#include <qml.h>
|
||||
#include <QFileSystemWatcher>
|
||||
|
||||
#include "qmlprojectitem.h"
|
||||
|
||||
@@ -40,11 +41,13 @@ signals:
|
||||
void filterChanged();
|
||||
void filesChanged();
|
||||
|
||||
private slots:
|
||||
void updateFileList();
|
||||
|
||||
private:
|
||||
QString absoluteDir() const;
|
||||
|
||||
void updateFileList();
|
||||
QSet<QString> filesInSubTree(const QDir &rootDir, const QDir &dir);
|
||||
QSet<QString> filesInSubTree(const QDir &rootDir, const QDir &dir, QSet<QString> *parsedDirs = 0);
|
||||
|
||||
QString m_rootDir;
|
||||
QString m_defaultDir;
|
||||
@@ -53,6 +56,8 @@ private:
|
||||
QRegExp m_regex;
|
||||
bool m_recursive;
|
||||
|
||||
QFileSystemWatcher m_fsWatcher;
|
||||
|
||||
QSet<QString> m_files;
|
||||
|
||||
friend class ProjectItem;
|
||||
|
||||
@@ -56,6 +56,7 @@ QString QmlProjectItem::sourceDirectory() const
|
||||
return d->sourceDirectory;
|
||||
}
|
||||
|
||||
// kind of initialization
|
||||
void QmlProjectItem::setSourceDirectory(const QString &directoryPath)
|
||||
{
|
||||
Q_D(QmlProjectItem);
|
||||
@@ -68,8 +69,10 @@ void QmlProjectItem::setSourceDirectory(const QString &directoryPath)
|
||||
for (int i = 0; i < d->content.size(); ++i) {
|
||||
QmlProjectContentItem *contentElement = d->content.at(i);
|
||||
FileFilterBaseItem *fileFilter = qobject_cast<FileFilterBaseItem*>(contentElement);
|
||||
if (fileFilter)
|
||||
if (fileFilter) {
|
||||
fileFilter->setDefaultDirectory(directoryPath);
|
||||
connect(fileFilter, SIGNAL(filesChanged()), this, SIGNAL(qmlFilesChanged()));
|
||||
}
|
||||
}
|
||||
|
||||
emit sourceDirectoryChanged();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef PROJECTITEM_H
|
||||
#define PROJECTITEM_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QtCore/QObject>
|
||||
#include <qml.h>
|
||||
|
||||
namespace QmlProjectManager {
|
||||
@@ -38,11 +38,11 @@ public:
|
||||
QStringList qmlFiles() const;
|
||||
|
||||
signals:
|
||||
void qmlFilesChanged();
|
||||
void sourceDirectoryChanged();
|
||||
|
||||
protected:
|
||||
QmlProjectItemPrivate *d_ptr;
|
||||
|
||||
};
|
||||
|
||||
} // namespace QmlProjectManager
|
||||
|
||||
@@ -76,7 +76,8 @@ enum {
|
||||
QmlProject::QmlProject(Manager *manager, const QString &fileName)
|
||||
: m_manager(manager),
|
||||
m_fileName(fileName),
|
||||
m_modelManager(ExtensionSystem::PluginManager::instance()->getObject<QmlJSEditor::QmlModelManagerInterface>())
|
||||
m_modelManager(ExtensionSystem::PluginManager::instance()->getObject<QmlJSEditor::QmlModelManagerInterface>()),
|
||||
m_fileWatcher(new ProjectExplorer::FileWatcher(this))
|
||||
{
|
||||
QFileInfo fileInfo(m_fileName);
|
||||
m_projectName = fileInfo.completeBaseName();
|
||||
@@ -84,6 +85,10 @@ QmlProject::QmlProject(Manager *manager, const QString &fileName)
|
||||
m_file = new QmlProjectFile(this, fileName);
|
||||
m_rootNode = new QmlProjectNode(this, m_file);
|
||||
|
||||
m_fileWatcher->addFile(fileName),
|
||||
connect(m_fileWatcher, SIGNAL(fileChanged(QString)),
|
||||
this, SLOT(refreshProjectFile()));
|
||||
|
||||
m_manager->registerProject(this);
|
||||
}
|
||||
|
||||
@@ -129,16 +134,23 @@ static QStringList readLines(const QString &absoluteFileName)
|
||||
void QmlProject::parseProject(RefreshOptions options)
|
||||
{
|
||||
if (options & Files) {
|
||||
if (options & ProjectFile)
|
||||
delete m_projectItem.data();
|
||||
if (!m_projectItem) {
|
||||
QmlComponent *component = new QmlComponent(&m_engine, m_fileName, this);
|
||||
if (component->isReady()
|
||||
&& qobject_cast<QmlProjectItem*>(component->create())) {
|
||||
m_projectItem = qobject_cast<QmlProjectItem*>(component->create());
|
||||
} else {
|
||||
qWarning() << m_fileName << "is not valid qml file, falling back to old format ...";
|
||||
m_files = convertToAbsoluteFiles(readLines(filesFileName()));
|
||||
m_files.removeDuplicates();
|
||||
m_modelManager->updateSourceFiles(m_files);
|
||||
QFile file(m_fileName);
|
||||
if (file.open(QFile::ReadOnly)) {
|
||||
QmlComponent *component = new QmlComponent(&m_engine, this);
|
||||
component->setData(file.readAll(), QUrl::fromLocalFile(m_fileName));
|
||||
if (component->isReady()
|
||||
&& qobject_cast<QmlProjectItem*>(component->create())) {
|
||||
m_projectItem = qobject_cast<QmlProjectItem*>(component->create());
|
||||
connect(m_projectItem.data(), SIGNAL(qmlFilesChanged()), this, SLOT(refreshFiles()));
|
||||
} else {
|
||||
qWarning() << m_fileName << "is not valid qml file, falling back to old format ...";
|
||||
m_files = convertToAbsoluteFiles(readLines(filesFileName()));
|
||||
m_files.removeDuplicates();
|
||||
m_modelManager->updateSourceFiles(m_files);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_projectItem) {
|
||||
@@ -191,6 +203,16 @@ QStringList QmlProject::files() const
|
||||
return files;
|
||||
}
|
||||
|
||||
void QmlProject::refreshProjectFile()
|
||||
{
|
||||
refresh(QmlProject::ProjectFile | Files);
|
||||
}
|
||||
|
||||
void QmlProject::refreshFiles()
|
||||
{
|
||||
refresh(Files);
|
||||
}
|
||||
|
||||
QString QmlProject::displayName() const
|
||||
{
|
||||
return m_projectName;
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <projectexplorer/projectnodes.h>
|
||||
#include <projectexplorer/buildstep.h>
|
||||
#include <projectexplorer/applicationrunconfiguration.h>
|
||||
#include <projectexplorer/filewatcher.h>
|
||||
#include <coreplugin/ifile.h>
|
||||
|
||||
#include <QtCore/QDir>
|
||||
@@ -170,17 +171,23 @@ public:
|
||||
virtual Internal::QmlProjectNode *rootProjectNode() const;
|
||||
virtual QStringList files(FilesMode fileMode) const;
|
||||
|
||||
enum RefreshOptions {
|
||||
Files = 0x01,
|
||||
Configuration = 0x02,
|
||||
Everything = Files | Configuration
|
||||
enum RefreshOption {
|
||||
ProjectFile = 0x01,
|
||||
Files = 0x02,
|
||||
Configuration = 0x04,
|
||||
Everything = ProjectFile | Files | Configuration
|
||||
};
|
||||
Q_DECLARE_FLAGS(RefreshOptions,RefreshOption)
|
||||
|
||||
void refresh(RefreshOptions options);
|
||||
|
||||
QDir projectDir() const;
|
||||
QStringList files() const;
|
||||
|
||||
private slots:
|
||||
void refreshProjectFile();
|
||||
void refreshFiles();
|
||||
|
||||
protected:
|
||||
virtual void saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &writer);
|
||||
virtual bool restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader &reader);
|
||||
@@ -202,6 +209,7 @@ private:
|
||||
// qml based, new format
|
||||
QmlEngine m_engine;
|
||||
QWeakPointer<QmlProjectItem> m_projectItem;
|
||||
ProjectExplorer::FileWatcher *m_fileWatcher;
|
||||
|
||||
Internal::QmlProjectNode *m_rootNode;
|
||||
};
|
||||
@@ -243,4 +251,6 @@ private:
|
||||
|
||||
} // namespace QmlProjectManager
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QmlProjectManager::QmlProject::RefreshOptions)
|
||||
|
||||
#endif // QMLPROJECT_H
|
||||
|
||||
Reference in New Issue
Block a user