forked from qt-creator/qt-creator
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:
@@ -1519,12 +1519,9 @@ bool ProFileEvaluator::Private::evaluateFile(const QString &fileName, bool *resu
|
||||
if (pro) {
|
||||
m_profileStack.push(pro);
|
||||
ok = (currentProFile() ? pro->Accept(this) : false);
|
||||
if (ok) {
|
||||
if (m_profileStack.count() > 0) {
|
||||
ProFile *pro = m_profileStack.pop();
|
||||
m_profileStack.pop();
|
||||
q->releaseParsedProFile(pro);
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
*result = true;
|
||||
} else {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
if (modifiedFileHandle)
|
||||
fileManager->blockFileChange(modifiedFileHandle);
|
||||
modifiedFileHandle->save();
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user