Project: Add signal triggered by project files becoming dirty

Add a signal triggered by project files becoming dirty and add
a way to register more project files than just the default with the
project.

This change enables getting rid of filesystemwatchers in derived
classes.

Change-Id: If985b46edf7cb88dd49f1c574f35cf13b5ce82d4
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Tobias Hunger
2019-08-15 12:42:26 +02:00
parent 087396fe00
commit d13307b5bf
3 changed files with 59 additions and 14 deletions

View File

@@ -1272,7 +1272,21 @@ QSet<T> toSet(const QList<T> &list)
#endif
}
template <class T>
template<class T>
QSet<T> toSet(const QVector<T> &vec)
{
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
QSet<T> result;
for (const T &p : vec) {
result.insert(p);
}
return result;
#else
return QSet<T>(vec.begin(), vec.end());
#endif
}
template<class T>
QList<T> toList(const QSet<T> &set)
{
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))

View File

@@ -120,10 +120,10 @@ ProjectDocument::ProjectDocument(const QString &mimeType, const Utils::FilePath
const ProjectDocument::ProjectCallback &callback) :
m_callback(callback)
{
QTC_CHECK(callback);
setFilePath(fileName);
setMimeType(mimeType);
if (m_callback)
Core::DocumentManager::addDocument(this);
Core::DocumentManager::addDocument(this);
}
Core::IDocument::ReloadBehavior
@@ -142,8 +142,7 @@ bool ProjectDocument::reload(QString *errorString, Core::IDocument::ReloadFlag f
Q_UNUSED(flag)
Q_UNUSED(type)
if (m_callback)
m_callback();
m_callback();
return true;
}
@@ -153,12 +152,6 @@ bool ProjectDocument::reload(QString *errorString, Core::IDocument::ReloadFlag f
class ProjectPrivate
{
public:
ProjectPrivate(const QString &mimeType, const Utils::FilePath &fileName,
const ProjectDocument::ProjectCallback &callback)
{
m_document = std::make_unique<ProjectDocument>(mimeType, fileName, callback);
}
~ProjectPrivate();
Core::Id m_id;
@@ -170,6 +163,7 @@ public:
bool m_hasMakeInstallEquivalent = false;
bool m_needsBuildConfigurations = true;
std::unique_ptr<Core::IDocument> m_document;
std::vector<std::unique_ptr<Core::IDocument>> m_extraProjectDocuments;
std::unique_ptr<ProjectNode> m_rootProjectNode;
std::unique_ptr<ContainerNode> m_containerNode;
std::vector<std::unique_ptr<Target>> m_targets;
@@ -195,10 +189,19 @@ ProjectPrivate::~ProjectPrivate()
std::unique_ptr<ProjectNode> oldNode = std::move(m_rootProjectNode);
}
Project::Project(const QString &mimeType, const Utils::FilePath &fileName,
const ProjectDocument::ProjectCallback &callback) :
d(new ProjectPrivate(mimeType, fileName, callback))
Project::Project(const QString &mimeType,
const Utils::FilePath &fileName,
const ProjectDocument::ProjectCallback &callback)
: d(new ProjectPrivate)
{
d->m_document = std::make_unique<ProjectDocument>(mimeType,
fileName,
[this, fileName, callback]() {
emit projectFileIsDirty(fileName);
if (callback)
callback();
});
d->m_macroExpander.setDisplayName(tr("Project"));
d->m_macroExpander.registerVariable("Project:Name", tr("Project Name"),
[this] { return displayName(); });
@@ -339,6 +342,28 @@ void Project::setNeedsInitialExpansion(bool needsExpansion)
d->m_needsInitialExpansion = needsExpansion;
}
void Project::setExtraProjectFiles(const QVector<Utils::FilePath> &projectDocumentPaths)
{
QSet<Utils::FilePath> uniqueNewFiles = Utils::toSet(projectDocumentPaths);
uniqueNewFiles.remove(projectFilePath()); // Make sure to never add the main project file!
QSet<Utils::FilePath> existingWatches = Utils::transform<QSet>(d->m_extraProjectDocuments,
&Core::IDocument::filePath);
QSet<Utils::FilePath> toAdd = uniqueNewFiles.subtract(existingWatches);
QSet<Utils::FilePath> toRemove = existingWatches.subtract(uniqueNewFiles);
Utils::erase(d->m_extraProjectDocuments, [&toRemove](const std::unique_ptr<Core::IDocument> &d) {
return toRemove.contains(d->filePath());
});
for (const Utils::FilePath &p : toAdd) {
d->m_extraProjectDocuments.emplace_back(
std::make_unique<ProjectDocument>(d->m_document->mimeType(), p, [this, p]() {
emit projectFileIsDirty(p);
}));
}
}
Target *Project::target(Core::Id id) const
{
return Utils::findOrDefault(d->m_targets, Utils::equal(&Target::id, id));

View File

@@ -250,7 +250,13 @@ public:
// FIXME: Make this private and the BuildSystem a friend
ParseGuard guardParsingRun() { return ParseGuard(this); }
// Set project files that will be watched and trigger the same callback
// as the main project file.
void setExtraProjectFiles(const QVector<Utils::FilePath> &projectDocumentPaths);
signals:
void projectFileIsDirty(const Utils::FilePath &path);
void displayNameChanged();
void fileListChanged();