Fixes: Mem leak in the pro file parser.

Details:  ProFileCache be gone, as is ManagedProFile, not to be missed.
Drastically simplified how ownership works.
This commit is contained in:
dt
2008-12-02 18:14:06 +01:00
parent 4eaa9f5052
commit bd827512bb
14 changed files with 141 additions and 551 deletions

View File

@@ -1,363 +0,0 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception
** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "qt4project.h"
#include "qt4nodes.h"
#include "qt4projectmanager.h"
#include "profilecache.h"
#include "proparser/prowriter.h"
#include "proitems.h"
#include "qt4projectmanagerconstants.h"
#include <coreplugin/filemanager.h>
#include <utils/reloadpromptutils.h>
#include <QtCore/QFileInfo>
#include <QtCore/QDebug>
#include <QtGui/QMainWindow>
#include <QtCore/QDir>
using namespace Qt4ProjectManager;
using namespace Qt4ProjectManager::Internal;
namespace {
bool debug = false;
}
namespace Qt4ProjectManager {
namespace Internal {
class ManagedProjectFile
: public Core::IFile
{
Q_OBJECT
public:
ManagedProjectFile(ProFileCache *parent, ProFile *profile);
virtual ~ManagedProjectFile();
ProFile *profile();
void setProfile(ProFile *profile);
bool isOutOfSync() { return m_outOfSync; }
void setOutOfSync(bool state) { m_outOfSync = state; }
// Core::IFile
bool save(const QString &fileName = QString());
QString fileName() const;
QString defaultPath() const;
QString suggestedFileName() const;
virtual QString mimeType() const;
bool isModified() const;
bool isReadOnly() const;
bool isSaveAsAllowed() const;
void modified(ReloadBehavior *behavior);
signals:
void changed();
private:
const QString m_mimeType;
ProFile *m_profile;
ProFileCache *m_cache;
bool m_outOfSync;
};
} // namespace Internal
} // namespace Qt4ProFileNodemanager
ManagedProjectFile::ManagedProjectFile(ProFileCache *parent, ProFile *profile) :
Core::IFile(parent),
m_mimeType(QLatin1String(Qt4ProjectManager::Constants::PROFILE_MIMETYPE)),
m_profile(profile),
m_cache(parent),
m_outOfSync(false)
{
}
ManagedProjectFile::~ManagedProjectFile()
{
delete m_profile;
}
ProFile *ManagedProjectFile::profile()
{
return m_profile;
}
void ManagedProjectFile::setProfile(ProFile *profile)
{
m_outOfSync = false;
if (profile == m_profile)
return;
delete m_profile;
m_profile = profile;
}
bool ManagedProjectFile::save(const QString &)
{
if (!m_profile)
return false;
ProWriter pw;
bool ok = pw.write(m_profile, m_profile->fileName());
m_profile->setModified(false);
m_cache->notifyModifiedChanged(m_profile);
return ok;
}
QString ManagedProjectFile::fileName() const
{
return QDir::cleanPath(m_profile->fileName());
}
QString ManagedProjectFile::defaultPath() const
{
QFileInfo fi(fileName());
return fi.absolutePath();
}
QString ManagedProjectFile::suggestedFileName() const
{
QFileInfo fi(fileName());
return fi.fileName();
}
bool ManagedProjectFile::isModified() const
{
return m_profile->isModified();
}
bool ManagedProjectFile::isReadOnly() const
{
QFileInfo fi(fileName());
return !fi.isWritable();
}
bool ManagedProjectFile::isSaveAsAllowed() const
{
return false;
}
void ManagedProjectFile::modified(ReloadBehavior *behavior)
{
switch (*behavior) {
case Core::IFile::ReloadNone:
case Core::IFile::ReloadPermissions:
return;
case Core::IFile::ReloadAll:
m_cache->notifyChanged(QSet<ProFile *>() << m_profile, true);
return;
case Core::IFile::AskForReload:
break;
}
const QString prompt = tr("The project file %1 has changed outside Qt Creator. Do you want to reload it?").arg(m_profile->fileName());
switch (const Core::Utils::ReloadPromptAnswer answer = Core::Utils::reloadPrompt(tr("File Changed"), prompt, m_cache->manager()->core()->mainWindow())) {
case Core::Utils::ReloadAll:
case Core::Utils::ReloadCurrent:
m_cache->notifyChanged(QSet<ProFile *>() << m_profile, true);
if (answer == Core::Utils::ReloadAll)
*behavior = Core::IFile::ReloadAll;
break;
case Core::Utils::ReloadSkipCurrent:
break;
case Core::Utils::ReloadNone:
*behavior = Core::IFile::ReloadNone;
break;
}
}
QString ManagedProjectFile::mimeType() const
{
return m_mimeType;
}
#include "profilecache.moc"
ProFileCache::ProFileCache(Qt4Manager *manager)
: QObject(manager)
{
m_manager = manager;
}
ProFileCache::~ProFileCache()
{
qDeleteAll(m_profiles.values());
m_profiles.clear();
m_projects.clear();
}
void ProFileCache::notifyModifiedChanged(ProFile *profile)
{
QList<Qt4ProFileNode *> pros = m_projects.values(profile->fileName());
for (int i=0; i<pros.count(); ++i) {
Qt4ProFileNode *pro = pros.at(i);
pro->update();
}
}
void ProFileCache::notifyChanged(const QSet<ProFile *> &profiles, bool external)
{
QList<Qt4ProFileNode *> notifyProjects;
foreach (ProFile *profile, profiles) {
QList<Qt4ProFileNode *> pros = m_projects.values(profile->fileName());
if (external) {
ManagedProjectFile *file = m_profiles.value(profile->fileName());
if (file)
file->setOutOfSync(true);
}
QList<Qt4ProFileNode *>::const_iterator i = pros.constBegin();
for (; i != pros.constEnd(); ++i) {
if (!notifyProjects.contains(*i))
notifyProjects << *i;
}
}
QList<Qt4ProFileNode *>::const_iterator i = notifyProjects.constBegin();
while (i != notifyProjects.constEnd()) {
(*i)->update();
++i;
}
}
void ProFileCache::updateDependencies(const QSet<ProFile *> &files, Qt4ProFileNode *project)
{
// just remove and add files that have changed
const QSet<QString> &oldFiles = m_projects.keys(project).toSet();
QSet<QString> newFiles;
QList<Core::IFile *> addedFiles;
foreach (ProFile *file, files) {
newFiles << file->fileName();
if (!m_profiles.contains(file->fileName())) {
ManagedProjectFile *profile = new ManagedProjectFile(this, file);
m_profiles.insert(file->fileName(), profile);
if (debug)
qDebug() << "ProFileCache - inserting file " << file->fileName();
addedFiles << profile;
} else {
ManagedProjectFile *profile = m_profiles.value(file->fileName());
profile->setProfile(file);
}
}
m_manager->core()->fileManager()->addFiles(addedFiles);
if (oldFiles.isEmpty()) {
connect(project, SIGNAL(destroyed(QObject *)),
this, SLOT(removeProject(QObject *)));
}
foreach (const QString &profile, (oldFiles - newFiles).toList()) {
removeFile(profile, project);
}
foreach (const QString &profile, (newFiles - oldFiles).toList()) {
m_projects.insertMulti(profile, project);
}
}
QStringList ProFileCache::dependencies(Qt4ProFileNode *project) const
{
return m_projects.keys(project);
}
ProFile *ProFileCache::proFile(const QString &file) const
{
QSet<ProFile *> profiles = proFiles(QStringList(file));
if (profiles.isEmpty())
return 0;
return profiles.toList().first();
}
QSet<ProFile *> ProFileCache::proFiles(const QStringList &files) const
{
QSet<ProFile *> results;
foreach (const QString &file, files) {
ManagedProjectFile *managedFile = m_profiles.value(file, 0);
if (managedFile && !managedFile->isOutOfSync()) {
results << managedFile->profile();
}
}
return results;
}
QSet<ProFile *> ProFileCache::proFiles(Qt4ProFileNode *project) const
{
return proFiles(m_projects.keys(project));
}
Core::IFile *ProFileCache::fileInterface(const QString &file)
{
return m_profiles.value(file);
}
void ProFileCache::removeFile(const QString &file, Qt4ProFileNode *proj)
{
QList<Qt4ProFileNode*> projects = m_projects.values(file);
m_projects.remove(file);
projects.removeAll(proj);
if (!projects.isEmpty()) {
foreach (Qt4ProFileNode *p, projects) {
m_projects.insert(file, p);
}
} else {
ManagedProjectFile *mp = m_profiles.value(file, 0);
if (debug)
qDebug() << "ProFileCache - removing file " << file;
m_manager->core()->fileManager()->removeFile(mp);
m_profiles.remove(file);
delete mp;
}
}
void ProFileCache::removeProject(QObject *obj)
{
// Cannot use qobject_cast here because
// it is triggered by destroyed signal
Qt4ProFileNode *proj = static_cast<Qt4ProFileNode*>(obj);
QStringList files = m_projects.keys(proj);
foreach (const QString &file, files) {
removeFile(file, proj);
}
}

View File

@@ -1,98 +0,0 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception
** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef PROFILECACHE_H
#define PROFILECACHE_H
#include <QtCore/QObject>
#include <QtCore/QSet>
#include <QtCore/QStringList>
#include <QtCore/QMap>
QT_BEGIN_NAMESPACE
class ProFile;
QT_END_NAMESPACE
namespace Core {
class IFile;
}
namespace Qt4ProjectManager {
//class Qt4Project;
class Qt4Manager;
namespace Internal {
class Qt4ProFileNode;
class ManagedProjectFile;
class ProFileCache : public QObject
{
Q_OBJECT
public:
ProFileCache(Qt4Manager *manager);
~ProFileCache();
// does not result in a reparse or resolve
void notifyModifiedChanged(ProFile *profile);
// if external is true we need to reparse, it it's false we only resolve
void notifyChanged(const QSet<ProFile *> &profiles, bool external = false);
void updateDependencies(const QSet<ProFile *> &files, Qt4ProFileNode *projectNode);
QStringList dependencies(Qt4ProFileNode *projectNode) const;
ProFile *proFile(const QString &filename) const;
QSet<ProFile *> proFiles(const QStringList &files) const;
QSet<ProFile *> proFiles(Qt4ProFileNode *projectNode) const;
Core::IFile *fileInterface(const QString &filename);
inline Qt4Manager *manager() const { return m_manager; }
protected slots:
void removeProject(QObject *obj);
private:
void removeFile(const QString &profile, Qt4ProFileNode *projectNode);
Qt4Manager *m_manager;
QMultiMap<QString, Qt4ProFileNode *> m_projects;
QMap<QString, ManagedProjectFile *> m_profiles;
};
} // namespace Internal
} // namespace Qt4ProjectManager
#endif // PROFILECACHE_H

View File

@@ -36,7 +36,6 @@
#include "profilehighlighter.h"
#include "qt4projectmanager.h"
#include "qt4projectmanagerconstants.h"
#include "profilecache.h"
#include "profileeditorfactory.h"
#include "proeditormodel.h"
#include "procommandmanager.h"
@@ -51,6 +50,7 @@
#include <QtCore/QFileInfo>
#include <QtGui/QTextEdit>
#include <QtGui/QHeaderView>
#include <QtCore/QDebug>
using namespace ExtensionSystem;
using namespace Core;
@@ -150,9 +150,7 @@ ProFileDocument::ProFileDocument(Qt4Manager *manager)
bool ProFileDocument::save(const QString &name)
{
if (BaseTextDocument::save(name)) {
ProFile *profile = m_manager->proFileCache()->proFile(name);
if (profile)
m_manager->proFileCache()->notifyChanged(QSet<ProFile*>() << profile, true);
m_manager->notifyChanged(name);
return true;
}
return false;

View File

@@ -32,7 +32,6 @@
***************************************************************************/
#include "profilereader.h"
#include "profilecache.h"
#include <QtCore/QDir>
#include <QtCore/QDebug>
@@ -40,11 +39,16 @@
using namespace Qt4ProjectManager;
using namespace Qt4ProjectManager::Internal;
ProFileReader::ProFileReader(ProFileCache *cache)
: m_cache(cache)
ProFileReader::ProFileReader()
{
}
ProFileReader::~ProFileReader()
{
foreach(ProFile *pf, m_proFiles)
delete pf;
}
void ProFileReader::setQtVersion(QtVersion *qtVersion) {
QHash<QString, QStringList> additionalVariables;
additionalVariables.insert(QString("QT_BUILD_TREE"), QStringList() << qtVersion->path());
@@ -72,6 +76,7 @@ bool ProFileReader::readProFile(const QString &fileName)
return false;
}
m_includeFiles.insert(fn, pro);
m_proFiles.append(pro);
return accept(pro);
}
@@ -84,23 +89,23 @@ ProFile *ProFileReader::parsedProFile(const QString &fileName)
ProFile *pro = ProFileEvaluator::parsedProFile(fn);
if (pro) {
m_includeFiles.insert(fn, pro);
m_proFiles.append(pro);
}
return pro;
}
void ProFileReader::releaseParsedProFile(ProFile */*proFile*/)
void ProFileReader::releaseParsedProFile(ProFile *)
{
return;
}
ProFile *ProFileReader::proFileFromCache(const QString &fileName) const
{
QString fn = QFileInfo(fileName).filePath();
ProFile *pro = 0;
if (m_includeFiles.contains(fn))
pro = m_includeFiles.value(fn);
else
pro = m_cache->proFile(fn); // this can expand to null
return pro;
}

View File

@@ -43,14 +43,14 @@
namespace Qt4ProjectManager {
namespace Internal {
class ProFileCache;
class ProFileReader : public QObject, public ProFileEvaluator
{
Q_OBJECT
public:
ProFileReader(ProFileCache *cache);
ProFileReader();
~ProFileReader();
void setQtVersion(QtVersion *qtVersion);
bool readProFile(const QString &fileName);
@@ -63,7 +63,7 @@ public:
const QString &baseDirectory,
PathValuesMode mode,
const ProFile *pro = 0) const;
ProFile *proFileFromCache(const QString &fileName) const;
signals:
void errorFound(const QString &error);
@@ -75,9 +75,8 @@ private:
virtual void errorMessage(const QString &msg);
private:
ProFile *proFileFromCache(const QString &fileName) const;
ProFileCache *m_cache;
QMap<QString, ProFile *> m_includeFiles;
QList<ProFile *> m_proFiles;
};
} // namespace Internal

View File

@@ -87,7 +87,8 @@ Qt4PriFileNode::Qt4PriFileNode(Qt4Project *project,
m_projectFilePath(filePath),
m_projectDir(QFileInfo(filePath).absolutePath()),
m_includeFile(0),
m_saveTimer(new QTimer(this))
m_saveTimer(new QTimer(this)),
m_reader(0)
{
Q_ASSERT(project);
setFolderName(QFileInfo(filePath).baseName());
@@ -104,6 +105,7 @@ void Qt4PriFileNode::update(ProFile *includeFile, ProFileReader *reader)
{
Q_ASSERT(includeFile);
Q_ASSERT(reader);
m_reader = reader;
m_includeFile = includeFile;
@@ -363,10 +365,6 @@ void Qt4PriFileNode::changeFiles(const FileType fileType,
return;
// Check if file is readonly
ProFileCache *cache = m_project->qt4ProjectManager()->proFileCache();
if (cache->fileInterface(m_projectFilePath)->isReadOnly() && !priFileWritable(m_projectFilePath))
return;
ProEditorModel proModel;
proModel.setProFiles(QList<ProFile*>() << m_includeFile);
@@ -449,22 +447,26 @@ void Qt4PriFileNode::changeFiles(const FileType fileType,
void Qt4PriFileNode::save()
{
// Prevent any reload questions; just reload
Core::FileManager *fileManager = m_core->fileManager();
ProFileCache *cache = m_project->qt4ProjectManager()->proFileCache();
QList<Core::IFile *> allFileHandles = fileManager->managedFiles(m_includeFile->fileName());
Core::IFile *modifiedFileHandle = cache->fileInterface(m_includeFile->fileName());
Core::IFile *modifiedFileHandle = 0;
foreach(Core::IFile *file, allFileHandles)
if (file->fileName() == m_includeFile->fileName())
modifiedFileHandle = file;
fileManager->blockFileChange(modifiedFileHandle);
modifiedFileHandle->save();
fileManager->unblockFileChange(modifiedFileHandle);
if (modifiedFileHandle)
fileManager->blockFileChange(modifiedFileHandle);
ProWriter pw;
bool ok = pw.write(m_includeFile, m_includeFile->fileName());
m_includeFile->setModified(false);
m_project->qt4ProjectManager()->notifyChanged(m_includeFile->fileName());
if (modifiedFileHandle)
fileManager->unblockFileChange(modifiedFileHandle);
Core::IFile::ReloadBehavior tempBehavior =
Core::IFile::ReloadAll;
foreach (Core::IFile *file, allFileHandles) {
foreach (Core::IFile *file, allFileHandles)
file->modified(&tempBehavior);
}
}
/*
@@ -516,8 +518,8 @@ Qt4ProFileNode::Qt4ProFileNode(Qt4Project *project,
// own stuff
m_projectType(InvalidProject),
m_isQBuildProject(false),
m_cache(project->qt4ProjectManager()->proFileCache()),
m_dirWatcher(new DirectoryWatcher(this))
m_dirWatcher(new DirectoryWatcher(this)),
m_reader(0)
{
if (parent)
setParent(parent);
@@ -530,6 +532,11 @@ Qt4ProFileNode::Qt4ProFileNode(Qt4Project *project,
this, SLOT(update()));
}
Qt4ProFileNode::~Qt4ProFileNode()
{
delete m_reader;
}
bool Qt4ProFileNode::hasTargets() const
{
return (projectType() == ApplicationTemplate) || (projectType() == LibraryTemplate);
@@ -547,10 +554,11 @@ QStringList Qt4ProFileNode::variableValue(const Qt4Variable var) const
void Qt4ProFileNode::update()
{
ProFileReader *reader = createProFileReader();
if (!reader->readProFile(m_projectFilePath)) {
delete m_reader;
m_reader = createProFileReader();
if (!m_reader->readProFile(m_projectFilePath)) {
m_project->proFileParseError(tr("Error while parsing file %1. Giving up.").arg(m_projectFilePath));
delete reader;
delete m_reader;
invalidate();
return;
}
@@ -565,7 +573,7 @@ void Qt4ProFileNode::update()
#endif
Qt4ProjectType projectType = InvalidProject;
switch (reader->templateType()) {
switch (m_reader->templateType()) {
case ProFileEvaluator::TT_Unknown:
case ProFileEvaluator::TT_Application: {
projectType = ApplicationTemplate;
@@ -604,11 +612,11 @@ void Qt4ProFileNode::update()
ProFile *fileForCurrentProject = 0;
{
if (projectType == SubDirsTemplate) {
foreach (const QString &subDirProject, subDirsPaths(reader))
foreach (const QString &subDirProject, subDirsPaths(m_reader))
newProjectFiles << subDirProject;
}
foreach (ProFile *includeFile, reader->includeFiles()) {
foreach (ProFile *includeFile, m_reader->includeFiles()) {
if (includeFile->fileName() == m_projectFilePath) { // this file
fileForCurrentProject = includeFile;
} else {
@@ -637,7 +645,7 @@ void Qt4ProFileNode::update()
Qt4PriFileNode *priFileNode
= new Qt4PriFileNode(m_project,
*newProjectFileIter);
priFileNode->update(file, reader);
priFileNode->update(file, m_reader);
toAdd << priFileNode;
} else {
toAdd << createSubProFileNode(*newProjectFileIter);
@@ -646,7 +654,7 @@ void Qt4ProFileNode::update()
} else { // *existingNodeIter->path() == *newProjectFileIter
if (ProFile *file = includeFiles.value(*newProjectFileIter)) {
Qt4PriFileNode *priFileNode = static_cast<Qt4PriFileNode*>(*existingNodeIter);
priFileNode->update(file, reader);
priFileNode->update(file, m_reader);
}
++existingNodeIter;
@@ -662,7 +670,7 @@ void Qt4ProFileNode::update()
Qt4PriFileNode *priFileNode
= new Qt4PriFileNode(m_project,
*newProjectFileIter);
priFileNode->update(file, reader);
priFileNode->update(file, m_reader);
toAdd << priFileNode;
} else {
toAdd << createSubProFileNode(*newProjectFileIter);
@@ -675,15 +683,15 @@ void Qt4ProFileNode::update()
if (!toAdd.isEmpty())
addProjectNodes(toAdd);
Qt4PriFileNode::update(fileForCurrentProject, reader);
Qt4PriFileNode::update(fileForCurrentProject, m_reader);
// update other variables
QHash<Qt4Variable, QStringList> newVarValues;
newVarValues[CxxCompilerVar] << reader->value(QLatin1String("QMAKE_CXX"));
newVarValues[DefinesVar] = reader->values(QLatin1String("DEFINES"));
newVarValues[IncludePathVar] = includePaths(reader);
newVarValues[UiDirVar] = uiDirPaths(reader);
newVarValues[MocDirVar] = mocDirPaths(reader);
newVarValues[CxxCompilerVar] << m_reader->value(QLatin1String("QMAKE_CXX"));
newVarValues[DefinesVar] = m_reader->values(QLatin1String("DEFINES"));
newVarValues[IncludePathVar] = includePaths(m_reader);
newVarValues[UiDirVar] = uiDirPaths(m_reader);
newVarValues[MocDirVar] = mocDirPaths(m_reader);
if (m_varValues != newVarValues) {
m_varValues = newVarValues;
@@ -693,9 +701,7 @@ void Qt4ProFileNode::update()
}
updateGeneratedFiles();
m_project->qt4ProjectManager()->proFileCache()->updateDependencies(reader->includeFiles().toSet(), this);
delete reader;
foreach (NodesWatcher *watcher, watchers())
if (Qt4NodesWatcher *qt4Watcher = qobject_cast<Qt4NodesWatcher*>(watcher))
emit qt4Watcher->proFileUpdated(this);
@@ -812,7 +818,7 @@ void Qt4ProFileNode::updateGeneratedFiles()
ProFileReader *Qt4ProFileNode::createProFileReader() const
{
ProFileReader *reader = new ProFileReader(m_cache);
ProFileReader *reader = new ProFileReader();
connect(reader, SIGNAL(errorFound(const QString &)),
m_project, SLOT(proFileParseError(const QString &)));
@@ -971,6 +977,12 @@ void Qt4ProFileNode::invalidate()
emit qt4Watcher->projectTypeChanged(this, oldType, InvalidProject);
}
ProFile *Qt4ProFileNode::proFileFromCache(const QString &fileName)
{
return m_reader->proFileFromCache(fileName);
}
Qt4NodesWatcher::Qt4NodesWatcher(QObject *parent)
: NodesWatcher(parent)
{

View File

@@ -73,7 +73,6 @@ namespace Internal {
using ProjectExplorer::FileType;
class ProFileCache;
class ProFileReader;
class DirectoryWatcher;
@@ -154,6 +153,7 @@ private:
QString m_projectDir;
ProFile *m_includeFile;
QTimer *m_saveTimer;
ProFileReader *m_reader;
// managed by Qt4ProFileNode
friend class Qt4ProFileNode;
@@ -167,12 +167,14 @@ public:
Qt4ProFileNode(Qt4Project *project,
const QString &filePath,
QObject *parent = 0);
~Qt4ProFileNode();
bool hasTargets() const;
Qt4ProjectType projectType() const;
QStringList variableValue(const Qt4Variable var) const;
ProFile *proFileFromCache(const QString &fileName);
public slots:
void update();
@@ -200,8 +202,8 @@ private:
QHash<Qt4Variable, QStringList> m_varValues;
bool m_isQBuildProject;
ProFileCache *m_cache;
DirectoryWatcher *m_dirWatcher;
ProFileReader *m_reader;
friend class Qt4NodeHierarchy;
};

View File

@@ -34,8 +34,8 @@
#include "qt4project.h"
#include "qt4projectmanager.h"
#include "profilecache.h"
#include "profilereader.h"
#include "prowriter.h"
#include "makestep.h"
#include "qmakestep.h"
#include "deployhelper.h"
@@ -179,8 +179,12 @@ Qt4ProjectFile::Qt4ProjectFile(Qt4Project *project, const QString &filePath, QOb
bool Qt4ProjectFile::save(const QString &)
{
Core::IFile *file = fileFromCache();
return file && file->save();
ProFile *file = m_project->proFileFromCache(m_filePath);
ProWriter pw;
bool ok = pw.write(file, file->fileName());
file->setModified(false);
m_project->qt4ProjectManager()->notifyChanged(file->fileName());
return ok;
}
QString Qt4ProjectFile::fileName() const
@@ -205,14 +209,13 @@ QString Qt4ProjectFile::mimeType() const
bool Qt4ProjectFile::isModified() const
{
Core::IFile *file = fileFromCache();
return file && fileFromCache()->isModified();
return m_project->proFileFromCache(m_filePath)->isModified();
}
bool Qt4ProjectFile::isReadOnly() const
{
Core::IFile *file = fileFromCache();
return file && fileFromCache()->isReadOnly();
QFileInfo fi(m_filePath);
return !fi.isWritable();
}
bool Qt4ProjectFile::isSaveAsAllowed() const
@@ -224,15 +227,6 @@ void Qt4ProjectFile::modified(Core::IFile::ReloadBehavior *)
{
}
Core::IFile *Qt4ProjectFile::fileFromCache() const
{
ProFileCache *cache = m_project->qt4ProjectManager()->proFileCache();
Core::IFile *fi = cache->fileInterface(fileName());
if (!fi && debug)
qWarning() << "Could not retrieve IFile interface from ProFileCache";
return fi;
}
/*!
/class Qt4Project
@@ -247,6 +241,7 @@ Qt4Project::Qt4Project(Qt4Manager *manager, const QString& fileName) :
m_isApplication(true),
m_projectFiles(new Qt4ProjectFiles)
{
m_manager->registerProject(this);
m_rootProjectNode->registerWatcher(m_nodesWatcher);
connect(m_nodesWatcher, SIGNAL(foldersAdded()), this, SLOT(updateFileList()));
connect(m_nodesWatcher, SIGNAL(foldersRemoved()), this, SLOT(updateFileList()));
@@ -267,6 +262,7 @@ Qt4Project::Qt4Project(Qt4Manager *manager, const QString& fileName) :
Qt4Project::~Qt4Project()
{
m_manager->unregisterProject(this);
delete m_projectFiles;
}
@@ -520,7 +516,7 @@ void Qt4Project::update()
ProFileReader *Qt4Project::createProFileReader() const
{
ProFileReader *reader = new ProFileReader(m_manager->proFileCache());
ProFileReader *reader = new ProFileReader();
connect(reader, SIGNAL(errorFound(const QString&)),
this, SLOT(proFileParseError(const QString&)));
QtVersion *version = qtVersion(activeBuildConfiguration());
@@ -578,10 +574,11 @@ QStringList Qt4Project::files(FilesMode fileMode) const
QList<Core::IFile *> Qt4Project::dependencies()
{
QList<Core::IFile *> result;
ProFileCache *cache = m_manager->proFileCache();
foreach (const QString &file, cache->dependencies(m_rootProjectNode)) {
result << cache->fileInterface(file);
}
// TODO profile cache is no longer
// ProFileCache *cache = m_manager->proFileCache();
// foreach (const QString &file, cache->dependencies(m_rootProjectNode)) {
// result << cache->fileInterface(file);
// }
return result;
}
@@ -897,3 +894,29 @@ MakeStep *Qt4Project::makeStep() const
return qs;
return 0;
}
ProFile *Qt4Project::proFileFromCache(const QString &fileName)
{
return rootProjectNode()->proFileFromCache(fileName);
}
void Qt4Project::findProFile(const QString& fileName, Qt4ProFileNode *root, QList<Qt4ProFileNode *> &list)
{
if (root->path() == fileName)
list.append(root);
else if (root->proFileFromCache(fileName))
list.append(root);
foreach (FolderNode *fn, root->subFolderNodes())
if (Qt4ProFileNode *qt4proFileNode = qobject_cast<Qt4ProFileNode *>(fn))
findProFile(fileName, qt4proFileNode, list);
}
void Qt4Project::notifyChanged(const QString &name)
{
QList<Qt4ProFileNode *> list;
findProFile(name, rootProjectNode(), list);
foreach(Qt4ProFileNode *node, list)
node->update();
}

View File

@@ -107,8 +107,6 @@ public:
void modified(Core::IFile::ReloadBehavior *behavior);
private:
Core::IFile *fileFromCache() const;
const QString m_mimeType;
Qt4Project *m_project;
QString m_filePath;
@@ -182,6 +180,9 @@ public:
QMakeStep *qmakeStep() const;
MakeStep *makeStep() const;
ProFile *proFileFromCache(const QString &fileName);
void notifyChanged(const QString &name);
public slots:
void update();
void proFileParseError(const QString &errorMessage);
@@ -207,6 +208,7 @@ protected:
private:
static void collectApplicationProFiles(QList<Internal::Qt4ProFileNode *> &list, Internal::Qt4ProFileNode *node);
static void findProFile(const QString& fileName, Internal::Qt4ProFileNode *root, QList<Internal::Qt4ProFileNode *> &list);
QList<Internal::Qt4ProFileNode *> m_applicationProFileChange;
ProjectExplorer::ProjectExplorerPlugin *projectExplorer() const;

View File

@@ -37,7 +37,6 @@
#include "qt4projectmanagerplugin.h"
#include "qt4nodes.h"
#include "qt4project.h"
#include "profilecache.h"
#include "profilereader.h"
#include "qtversionmanager.h"
#include "qmakestep.h"
@@ -81,18 +80,33 @@ Qt4Manager::Qt4Manager(Qt4ProjectManagerPlugin *plugin, Core::ICore *core) :
m_core(core),
m_projectExplorer(0),
m_contextProject(0),
m_languageID(0),
m_proFileCache(0)
m_languageID(0)
{
m_languageID = m_core->uniqueIDManager()->
uniqueIdentifier(ProjectExplorer::Constants::LANG_CXX);
m_proFileCache = new ProFileCache(this);
}
Qt4Manager::~Qt4Manager()
{
}
void Qt4Manager::registerProject(Qt4Project *project)
{
m_projects.append(project);
}
void Qt4Manager::unregisterProject(Qt4Project *project)
{
m_projects.removeOne(project);
}
void Qt4Manager::notifyChanged(const QString &name)
{
foreach(Qt4Project *pro, m_projects) {
pro->notifyChanged(name);
}
}
void Qt4Manager::init()
{
m_projectExplorer = m_core->pluginManager()->getObject<ProjectExplorer::ProjectExplorerPlugin>();

View File

@@ -57,7 +57,6 @@ namespace Qt4ProjectManager {
namespace Internal {
class Qt4Builder;
class ProFileCache;
class ProFileEditor;
class Qt4ProjectManagerPlugin;
class QtVersionManager;
@@ -75,7 +74,10 @@ public:
~Qt4Manager();
void init();
inline Internal::ProFileCache *proFileCache() const { return m_proFileCache; }
void registerProject(Qt4Project *project);
void unregisterProject(Qt4Project *project);
void notifyChanged(const QString &name);
ProjectExplorer::ProjectExplorerPlugin *projectExplorer() const;
ExtensionSystem::PluginManager *pluginManager() const;
@@ -104,6 +106,7 @@ public slots:
void runQMakeContextMenu();
private:
QList<Qt4Project *> m_projects;
void runQMake(ProjectExplorer::Project *p);
const QString m_mimeType;
@@ -116,7 +119,6 @@ private:
int m_languageID;
Internal::ProFileCache *m_proFileCache;
};
} // namespace Qt4ProjectManager

View File

@@ -13,7 +13,6 @@ HEADERS = qt4projectmanagerplugin.h \
profilehighlighter.h \
profileeditorfactory.h \
profilereader.h \
profilecache.h \
wizards/qtprojectparameters.h \
wizards/guiappwizard.h \
wizards/consoleappwizard.h \
@@ -55,7 +54,6 @@ SOURCES = qt4projectmanagerplugin.cpp \
profilehighlighter.cpp \
profileeditorfactory.cpp \
profilereader.cpp \
profilecache.cpp \
wizards/qtprojectparameters.cpp \
wizards/guiappwizard.cpp \
wizards/consoleappwizard.cpp \

View File

@@ -40,7 +40,6 @@
#include "profileeditorfactory.h"
#include "qt4projectmanagerconstants.h"
#include "qt4project.h"
#include "profilecache.h"
#include "qmakebuildstepfactory.h"
#include "buildparserfactory.h"
#include "qtversionmanager.h"