forked from qt-creator/qt-creator
Initial import
This commit is contained in:
897
src/plugins/qt4projectmanager/qt4project.cpp
Normal file
897
src/plugins/qt4projectmanager/qt4project.cpp
Normal file
@@ -0,0 +1,897 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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 "qt4projectmanager.h"
|
||||
#include "profilecache.h"
|
||||
#include "profilereader.h"
|
||||
#include "makestep.h"
|
||||
#include "qmakestep.h"
|
||||
#include "deployhelper.h"
|
||||
#include "qt4runconfiguration.h"
|
||||
#include "qtversionmanager.h"
|
||||
#include "qt4nodes.h"
|
||||
#include "qt4buildconfigwidget.h"
|
||||
#include "qt4buildenvironmentwidget.h"
|
||||
#include "qt4projectmanagerconstants.h"
|
||||
#include "projectloadwizard.h"
|
||||
#include "gdbmacrosbuildstep.h"
|
||||
|
||||
#include <coreplugin/messagemanager.h>
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <cpptools/cppmodelmanagerinterface.h>
|
||||
#include <projectexplorer/nodesvisitor.h>
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/customexecutablerunconfiguration.h>
|
||||
|
||||
#include <QtGui/QFileDialog>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
using namespace Qt4ProjectManager;
|
||||
using namespace Qt4ProjectManager::Internal;
|
||||
using namespace ProjectExplorer;
|
||||
using Core::VariableManager;
|
||||
|
||||
enum { debug = 0 };
|
||||
|
||||
namespace Qt4ProjectManager {
|
||||
namespace Internal {
|
||||
|
||||
// Qt4ProjectFiles: Struct for (Cached) lists of files in a project
|
||||
struct Qt4ProjectFiles {
|
||||
void clear();
|
||||
bool equals(const Qt4ProjectFiles &f) const;
|
||||
|
||||
QStringList files[ProjectExplorer::FileTypeSize];
|
||||
QStringList generatedFiles[ProjectExplorer::FileTypeSize];
|
||||
QStringList proFiles;
|
||||
};
|
||||
|
||||
void Qt4ProjectFiles::clear()
|
||||
{
|
||||
for (int i = 0; i < FileTypeSize; ++i) {
|
||||
files[i].clear();
|
||||
generatedFiles[i].clear();
|
||||
}
|
||||
proFiles.clear();
|
||||
}
|
||||
|
||||
bool Qt4ProjectFiles::equals(const Qt4ProjectFiles &f) const
|
||||
{
|
||||
for (int i = 0; i < FileTypeSize; ++i)
|
||||
if (files[i] != f.files[i] || generatedFiles[i] != f.generatedFiles[i])
|
||||
return false;
|
||||
if (proFiles != f.proFiles)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool operator==(const Qt4ProjectFiles &f1, const Qt4ProjectFiles &f2)
|
||||
{ return f1.equals(f2); }
|
||||
|
||||
inline bool operator!=(const Qt4ProjectFiles &f1, const Qt4ProjectFiles &f2)
|
||||
{ return !f1.equals(f2); }
|
||||
|
||||
QDebug operator<<(QDebug d, const Qt4ProjectFiles &f)
|
||||
{
|
||||
QDebug nsp = d.nospace();
|
||||
nsp << "Qt4ProjectFiles: proFiles=" << f.proFiles << '\n';
|
||||
for (int i = 0; i < FileTypeSize; ++i)
|
||||
nsp << "Type " << i << " files=" << f.files[i] << " generated=" << f.generatedFiles[i] << '\n';
|
||||
return d;
|
||||
}
|
||||
|
||||
// A visitor to collect all files of a project in a Qt4ProjectFiles struct
|
||||
class ProjectFilesVisitor : public ProjectExplorer::NodesVisitor
|
||||
{
|
||||
Q_DISABLE_COPY(ProjectFilesVisitor)
|
||||
ProjectFilesVisitor(Qt4ProjectFiles *files);
|
||||
public:
|
||||
|
||||
static void findProjectFiles(Qt4ProFileNode *rootNode, Qt4ProjectFiles *files);
|
||||
|
||||
void visitProjectNode(ProjectNode *projectNode);
|
||||
void visitFolderNode(FolderNode *folderNode);
|
||||
|
||||
private:
|
||||
Qt4ProjectFiles *m_files;
|
||||
};
|
||||
|
||||
ProjectFilesVisitor::ProjectFilesVisitor(Qt4ProjectFiles *files) :
|
||||
m_files(files)
|
||||
{
|
||||
}
|
||||
|
||||
void ProjectFilesVisitor::findProjectFiles(Qt4ProFileNode *rootNode, Qt4ProjectFiles *files)
|
||||
{
|
||||
files->clear();
|
||||
ProjectFilesVisitor visitor(files);
|
||||
rootNode->accept(&visitor);
|
||||
for (int i = 0; i < FileTypeSize; ++i) {
|
||||
qSort(files->files[i]);
|
||||
qSort(files->generatedFiles[i]);
|
||||
}
|
||||
qSort(files->proFiles);
|
||||
}
|
||||
|
||||
void ProjectFilesVisitor::visitProjectNode(ProjectNode *projectNode)
|
||||
{
|
||||
const QString path = projectNode->path();
|
||||
if (!m_files->proFiles.contains(path))
|
||||
m_files->proFiles.append(path);
|
||||
visitFolderNode(projectNode);
|
||||
}
|
||||
|
||||
void ProjectFilesVisitor::visitFolderNode(FolderNode *folderNode)
|
||||
{
|
||||
foreach (FileNode *fileNode, folderNode->fileNodes()) {
|
||||
const QString path = fileNode->path();
|
||||
const int type = fileNode->fileType();
|
||||
QStringList &targetList = fileNode->isGenerated() ? m_files->generatedFiles[type] : m_files->files[type];
|
||||
if (!targetList.contains(path))
|
||||
targetList.push_back(path);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// ----------- Qt4ProjectFile
|
||||
Qt4ProjectFile::Qt4ProjectFile(Qt4Project *project, const QString &filePath, QObject *parent)
|
||||
: Core::IFile(parent),
|
||||
m_mimeType(QLatin1String(Qt4ProjectManager::Constants::PROFILE_MIMETYPE)),
|
||||
m_project(project),
|
||||
m_filePath(filePath)
|
||||
{
|
||||
}
|
||||
|
||||
bool Qt4ProjectFile::save(const QString &)
|
||||
{
|
||||
Core::IFile *file = fileFromCache();
|
||||
return file && file->save();
|
||||
}
|
||||
|
||||
QString Qt4ProjectFile::fileName() const
|
||||
{
|
||||
return m_filePath;
|
||||
}
|
||||
|
||||
QString Qt4ProjectFile::defaultPath() const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString Qt4ProjectFile::suggestedFileName() const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString Qt4ProjectFile::mimeType() const
|
||||
{
|
||||
return m_mimeType;
|
||||
}
|
||||
|
||||
bool Qt4ProjectFile::isModified() const
|
||||
{
|
||||
Core::IFile *file = fileFromCache();
|
||||
return file && fileFromCache()->isModified();
|
||||
}
|
||||
|
||||
bool Qt4ProjectFile::isReadOnly() const
|
||||
{
|
||||
Core::IFile *file = fileFromCache();
|
||||
return file && fileFromCache()->isReadOnly();
|
||||
}
|
||||
|
||||
bool Qt4ProjectFile::isSaveAsAllowed() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
Qt4Project manages information about an individual Qt 4 (.pro) project file.
|
||||
*/
|
||||
|
||||
Qt4Project::Qt4Project(Qt4Manager *manager, const QString& fileName) :
|
||||
m_manager(manager),
|
||||
m_rootProjectNode(new Qt4ProFileNode(this, fileName, this)),
|
||||
m_nodesWatcher(new Internal::Qt4NodesWatcher(this)),
|
||||
m_fileInfo(new Qt4ProjectFile(this, fileName, this)),
|
||||
m_isApplication(true),
|
||||
m_projectFiles(new Qt4ProjectFiles)
|
||||
{
|
||||
m_rootProjectNode->registerWatcher(m_nodesWatcher);
|
||||
connect(m_nodesWatcher, SIGNAL(foldersAdded()), this, SLOT(updateFileList()));
|
||||
connect(m_nodesWatcher, SIGNAL(foldersRemoved()), this, SLOT(updateFileList()));
|
||||
connect(m_nodesWatcher, SIGNAL(filesAdded()), this, SLOT(updateFileList()));
|
||||
connect(m_nodesWatcher, SIGNAL(filesRemoved()), this, SLOT(updateFileList()));
|
||||
connect(m_nodesWatcher, SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *)),
|
||||
this, SLOT(scheduleUpdateCodeModel()));
|
||||
|
||||
connect(qt4ProjectManager()->versionManager(), SIGNAL(defaultQtVersionChanged()),
|
||||
this, SLOT(defaultQtVersionChanged()));
|
||||
connect(qt4ProjectManager()->versionManager(), SIGNAL(qtVersionsChanged()),
|
||||
this, SLOT(qtVersionsChanged()));
|
||||
|
||||
m_updateCodeModelTimer.setSingleShot(true);
|
||||
m_updateCodeModelTimer.setInterval(20);
|
||||
connect(&m_updateCodeModelTimer, SIGNAL(timeout()), this, SLOT(updateCodeModel()));
|
||||
}
|
||||
|
||||
Qt4Project::~Qt4Project()
|
||||
{
|
||||
delete m_projectFiles;
|
||||
}
|
||||
|
||||
void Qt4Project::defaultQtVersionChanged()
|
||||
{
|
||||
if (qtVersionId(activeBuildConfiguration()) == 0)
|
||||
update();
|
||||
}
|
||||
|
||||
void Qt4Project::qtVersionsChanged()
|
||||
{
|
||||
foreach (QString bc, buildConfigurations()) {
|
||||
if (!qt4ProjectManager()->versionManager()->version(qtVersionId(bc))->isValid()) {
|
||||
setQtVersion(bc, 0);
|
||||
if(bc == activeBuildConfiguration())
|
||||
update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Qt4Project::updateFileList()
|
||||
{
|
||||
Qt4ProjectFiles newFiles;
|
||||
ProjectFilesVisitor::findProjectFiles(m_rootProjectNode, &newFiles);
|
||||
if (newFiles != *m_projectFiles) {
|
||||
*m_projectFiles = newFiles;
|
||||
emit fileListChanged();
|
||||
if (debug)
|
||||
qDebug() << Q_FUNC_INFO << *m_projectFiles;
|
||||
}
|
||||
}
|
||||
|
||||
void Qt4Project::restoreSettingsImpl(PersistentSettingsReader &settingsReader)
|
||||
{
|
||||
Project::restoreSettingsImpl(settingsReader);
|
||||
|
||||
addDefaultBuild();
|
||||
|
||||
// Ensure that the qt version in each build configuration is valid
|
||||
// or if not, is reset to the default
|
||||
foreach (const QString &bc, buildConfigurations())
|
||||
qtVersionId(bc);
|
||||
|
||||
update();
|
||||
|
||||
// restored old runconfigurations
|
||||
if (runConfigurations().isEmpty()) {
|
||||
// Oha no runConfigurations, add some
|
||||
QList<Qt4ProFileNode *> list;
|
||||
collectApplicationProFiles(list, m_rootProjectNode);
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
foreach (Qt4ProFileNode *node, list) {
|
||||
QSharedPointer<RunConfiguration> rc(new Qt4RunConfiguration(this, node->path()));
|
||||
addRunConfiguration(rc);
|
||||
}
|
||||
setActiveRunConfiguration(runConfigurations().first());
|
||||
} else {
|
||||
QSharedPointer<RunConfiguration> rc(new ProjectExplorer::CustomExecutableRunConfiguration(this));
|
||||
addRunConfiguration(rc);
|
||||
setActiveRunConfiguration(rc);
|
||||
m_isApplication = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Now connect
|
||||
connect(m_nodesWatcher, SIGNAL(foldersAboutToBeAdded(FolderNode *, const QList<FolderNode*> &)),
|
||||
this, SLOT(foldersAboutToBeAdded(FolderNode *, const QList<FolderNode*> &)));
|
||||
connect(m_nodesWatcher, SIGNAL(foldersAdded()), this, SLOT(checkForNewApplicationProjects()));
|
||||
|
||||
connect(m_nodesWatcher, SIGNAL(foldersRemoved()), this, SLOT(checkForDeletedApplicationProjects()));
|
||||
|
||||
connect(m_nodesWatcher, SIGNAL(projectTypeChanged(Qt4ProjectManager::Internal::Qt4ProFileNode *,
|
||||
const Qt4ProjectManager::Internal::Qt4ProjectType,
|
||||
const Qt4ProjectManager::Internal::Qt4ProjectType)),
|
||||
this, SLOT(projectTypeChanged(Qt4ProjectManager::Internal::Qt4ProFileNode *,
|
||||
const Qt4ProjectManager::Internal::Qt4ProjectType,
|
||||
const Qt4ProjectManager::Internal::Qt4ProjectType)));
|
||||
|
||||
connect(m_nodesWatcher, SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *)),
|
||||
this, SLOT(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *)));
|
||||
|
||||
}
|
||||
|
||||
void Qt4Project::saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &writer)
|
||||
{
|
||||
Project::saveSettingsImpl(writer);
|
||||
}
|
||||
|
||||
namespace {
|
||||
class FindQt4ProFiles: protected ProjectExplorer::NodesVisitor {
|
||||
QList<Qt4ProFileNode *> m_proFiles;
|
||||
|
||||
public:
|
||||
QList<Qt4ProFileNode *> operator()(ProjectNode *root)
|
||||
{
|
||||
m_proFiles.clear();
|
||||
root->accept(this);
|
||||
return m_proFiles;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void visitProjectNode(ProjectNode *projectNode)
|
||||
{
|
||||
if (Qt4ProFileNode *pro = qobject_cast<Qt4ProFileNode *>(projectNode))
|
||||
m_proFiles.append(pro);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void Qt4Project::scheduleUpdateCodeModel()
|
||||
{
|
||||
m_updateCodeModelTimer.start();
|
||||
}
|
||||
|
||||
void Qt4Project::updateCodeModel()
|
||||
{
|
||||
if (debug)
|
||||
qDebug()<<"Qt4Project::updateCodeModel()";
|
||||
|
||||
CppTools::CppModelManagerInterface *modelmanager =
|
||||
m_manager->pluginManager()->getObject<CppTools::CppModelManagerInterface>();
|
||||
|
||||
if (! modelmanager)
|
||||
return;
|
||||
|
||||
QStringList allIncludePaths;
|
||||
QStringList allFrameworkPaths;
|
||||
|
||||
const QHash<QString, QString> versionInfo = qtVersion(activeBuildConfiguration())->versionInfo();
|
||||
const QString newQtIncludePath = versionInfo.value(QLatin1String("QT_INSTALL_HEADERS"));
|
||||
const QString newQtLibsPath = versionInfo.value(QLatin1String("QT_INSTALL_LIBS"));
|
||||
|
||||
QByteArray predefinedMacros;
|
||||
QtVersion::ToolchainType t = qtVersion(activeBuildConfiguration())->toolchainType();
|
||||
if (t == QtVersion::MinGW || t == QtVersion::OTHER) {
|
||||
QStringList list = rootProjectNode()->variableValue(Internal::CxxCompilerVar);
|
||||
QString qmake_cxx = list.isEmpty() ? QString::null : list.first();
|
||||
qmake_cxx = environment(activeBuildConfiguration()).searchInPath(qmake_cxx);
|
||||
m_preproc.setGcc(qmake_cxx);
|
||||
predefinedMacros = m_preproc.predefinedMacros();
|
||||
foreach (HeaderPath headerPath, m_preproc.systemHeaderPaths()) {
|
||||
if (headerPath.kind() == HeaderPath::FrameworkHeaderPath)
|
||||
allFrameworkPaths.append(headerPath.path());
|
||||
else
|
||||
allIncludePaths.append(headerPath.path());
|
||||
}
|
||||
|
||||
} else if (t == QtVersion::MSVC || t == QtVersion::WINCE) {
|
||||
#ifdef QTCREATOR_WITH_MSVC_INCLUDES
|
||||
Environment env = environment(activeBuildConfiguration());
|
||||
allIncludePaths.append(env.value("INCLUDE").split(QLatin1Char(';')));
|
||||
#endif
|
||||
predefinedMacros +=
|
||||
"#define __WIN32__\n"
|
||||
"#define __WIN32\n"
|
||||
"#define _WIN32\n"
|
||||
"#define WIN32\n"
|
||||
"#define __WINNT__\n"
|
||||
"#define __WINNT\n"
|
||||
"#define WINNT\n"
|
||||
"#define _X86_\n"
|
||||
"#define __MSVCRT__\n";
|
||||
}
|
||||
|
||||
allIncludePaths.append(newQtIncludePath);
|
||||
|
||||
QDir dir(newQtIncludePath);
|
||||
foreach (QFileInfo info, dir.entryInfoList(QDir::Dirs)) {
|
||||
if (! info.fileName().startsWith(QLatin1String("Qt")))
|
||||
continue;
|
||||
allIncludePaths.append(info.absoluteFilePath());
|
||||
}
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
allFrameworkPaths.append(newQtLibsPath);
|
||||
// put QtXXX.framework/Headers directories in include path since that qmake's behavior
|
||||
QDir frameworkDir(newQtLibsPath);
|
||||
foreach (QFileInfo info, frameworkDir.entryInfoList(QDir::Dirs)) {
|
||||
if (! info.fileName().startsWith(QLatin1String("Qt")))
|
||||
continue;
|
||||
allIncludePaths.append(info.absoluteFilePath()+"/Headers");
|
||||
}
|
||||
#endif
|
||||
|
||||
FindQt4ProFiles findQt4ProFiles;
|
||||
QList<Qt4ProFileNode *> proFiles = findQt4ProFiles(rootProjectNode());
|
||||
QByteArray definedMacros;
|
||||
|
||||
foreach (Qt4ProFileNode *pro, proFiles) {
|
||||
foreach (const QString def, pro->variableValue(DefinesVar)) {
|
||||
definedMacros += "#define ";
|
||||
const int index = def.indexOf(QLatin1Char('='));
|
||||
if (index == -1) {
|
||||
definedMacros += def.toLatin1();
|
||||
definedMacros += " 1\n";
|
||||
} else {
|
||||
const QString name = def.left(index);
|
||||
const QString value = def.mid(index + 1);
|
||||
definedMacros += name.toLatin1();
|
||||
definedMacros += ' ';
|
||||
definedMacros += value.toLocal8Bit();
|
||||
definedMacros += '\n';
|
||||
}
|
||||
}
|
||||
|
||||
const QStringList proIncludePaths = pro->variableValue(IncludePathVar);
|
||||
foreach (QString includePath, proIncludePaths) {
|
||||
if (allIncludePaths.contains(includePath))
|
||||
continue;
|
||||
|
||||
allIncludePaths.append(includePath);
|
||||
}
|
||||
}
|
||||
|
||||
QStringList files;
|
||||
files += m_projectFiles->files[HeaderType];
|
||||
files += m_projectFiles->generatedFiles[HeaderType];
|
||||
files += m_projectFiles->files[SourceType];
|
||||
files += m_projectFiles->generatedFiles[SourceType];
|
||||
|
||||
CppTools::CppModelManagerInterface::ProjectInfo *pinfo = modelmanager->projectInfo(this);
|
||||
|
||||
if (pinfo->defines == predefinedMacros &&
|
||||
pinfo->includePaths == allIncludePaths &&
|
||||
pinfo->frameworkPaths == allFrameworkPaths &&
|
||||
pinfo->sourceFiles == files) {
|
||||
// Nothing to update...
|
||||
} else {
|
||||
pinfo->defines = predefinedMacros;
|
||||
// pinfo->defines += definedMacros; // ### FIXME: me
|
||||
pinfo->includePaths = allIncludePaths;
|
||||
pinfo->frameworkPaths = allFrameworkPaths;
|
||||
pinfo->sourceFiles = files;
|
||||
|
||||
modelmanager->GC();
|
||||
modelmanager->updateSourceFiles(pinfo->sourceFiles);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Updates complete project
|
||||
*/
|
||||
void Qt4Project::update()
|
||||
{
|
||||
// TODO Maybe remove this method completely?
|
||||
m_rootProjectNode->update();
|
||||
//updateCodeModel();
|
||||
}
|
||||
|
||||
ProFileReader *Qt4Project::createProFileReader() const
|
||||
{
|
||||
ProFileReader *reader = new ProFileReader(m_manager->proFileCache());
|
||||
connect(reader, SIGNAL(errorFound(const QString&)),
|
||||
this, SLOT(proFileParseError(const QString&)));
|
||||
QtVersion *version = qtVersion(activeBuildConfiguration());
|
||||
if (version->isValid()) {
|
||||
reader->setQtVersion(version);
|
||||
}
|
||||
return reader;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns whether the project is an application, or has an application as a subproject.
|
||||
*/
|
||||
bool Qt4Project::isApplication() const
|
||||
{
|
||||
return m_isApplication;
|
||||
}
|
||||
|
||||
ProjectExplorer::ProjectExplorerPlugin *Qt4Project::projectExplorer() const
|
||||
{
|
||||
return m_manager->projectExplorer();
|
||||
}
|
||||
|
||||
ProjectExplorer::IProjectManager *Qt4Project::projectManager() const
|
||||
{
|
||||
return m_manager;
|
||||
}
|
||||
|
||||
Qt4Manager *Qt4Project::qt4ProjectManager() const
|
||||
{
|
||||
return m_manager;
|
||||
}
|
||||
|
||||
QString Qt4Project::name() const
|
||||
{
|
||||
return QFileInfo(file()->fileName()).completeBaseName();
|
||||
}
|
||||
|
||||
Core::IFile *Qt4Project::file() const
|
||||
{
|
||||
return m_fileInfo;
|
||||
}
|
||||
|
||||
QStringList Qt4Project::files(FilesMode fileMode) const
|
||||
{
|
||||
QStringList files;
|
||||
for (int i = 0; i < FileTypeSize; ++i) {
|
||||
files += m_projectFiles->files[i];
|
||||
if (fileMode == AllFiles)
|
||||
files += m_projectFiles->generatedFiles[i];
|
||||
}
|
||||
files += m_projectFiles->proFiles;
|
||||
return files;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QList<ProjectExplorer::Project*> Qt4Project::dependsOn()
|
||||
{
|
||||
// NBS implement dependsOn
|
||||
return QList<Project *>();
|
||||
}
|
||||
|
||||
void Qt4Project::addDefaultBuild()
|
||||
{
|
||||
if (buildConfigurations().isEmpty()) {
|
||||
// We don't have any buildconfigurations, so this is a new project
|
||||
// The Project Load Wizard is a work of art
|
||||
// It will ask the user what kind of build setup he want
|
||||
// It will add missing Qt Versions
|
||||
// And get the project into a buildable state
|
||||
|
||||
//TODO have a better check wheter there is already a configuration?
|
||||
QMakeStep *qmakeStep = 0;
|
||||
MakeStep *makeStep = 0;
|
||||
GdbMacrosBuildStep *gdbmacrostep;
|
||||
|
||||
gdbmacrostep = new GdbMacrosBuildStep(this);
|
||||
insertBuildStep(0, gdbmacrostep);
|
||||
|
||||
qmakeStep = new QMakeStep(this);
|
||||
qmakeStep->setValue("mkspec", "");
|
||||
insertBuildStep(1, qmakeStep);
|
||||
|
||||
makeStep = new MakeStep(this);
|
||||
insertBuildStep(2, makeStep);
|
||||
|
||||
MakeStep* cleanStep = new MakeStep(this);
|
||||
cleanStep->setValue("clean", true);
|
||||
insertCleanStep(0, cleanStep);
|
||||
|
||||
ProjectLoadWizard wizard(this);
|
||||
wizard.execDialog();
|
||||
} else {
|
||||
// Restoring configuration
|
||||
// Do we already have a gdbmacrobuildstep?
|
||||
// If not add it and disable linking of debugging helper
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
void Qt4Project::newBuildConfiguration(const QString &buildConfiguration)
|
||||
{
|
||||
Q_UNUSED(buildConfiguration);
|
||||
}
|
||||
|
||||
void Qt4Project::proFileParseError(const QString &errorMessage)
|
||||
{
|
||||
m_manager->core()->messageManager()->printToOutputPane(errorMessage);
|
||||
}
|
||||
|
||||
Qt4ProFileNode *Qt4Project::rootProjectNode() const
|
||||
{
|
||||
return m_rootProjectNode;
|
||||
}
|
||||
|
||||
ProjectExplorer::Environment Qt4Project::baseEnvironment(const QString &buildConfiguration) const
|
||||
{
|
||||
Environment env = useSystemEnvironment(buildConfiguration) ? Environment(QProcess::systemEnvironment()) : Environment();
|
||||
env = qtVersion(buildConfiguration)->addToEnvironment(env);
|
||||
return env;
|
||||
}
|
||||
|
||||
ProjectExplorer::Environment Qt4Project::environment(const QString &buildConfiguration) const
|
||||
{
|
||||
Environment env = baseEnvironment(buildConfiguration);
|
||||
env.modify(userEnvironmentChanges(buildConfiguration));
|
||||
return env;
|
||||
}
|
||||
|
||||
QString Qt4Project::buildDirectory(const QString &buildConfiguration) const
|
||||
{
|
||||
QString workingDirectory;
|
||||
if (value(buildConfiguration, "useShadowBuild").toBool())
|
||||
workingDirectory = value(buildConfiguration, "buildDirectory").toString();
|
||||
if(workingDirectory.isEmpty())
|
||||
workingDirectory = QFileInfo(file()->fileName()).absolutePath();
|
||||
return workingDirectory;
|
||||
}
|
||||
|
||||
void Qt4Project::setUseSystemEnvironment(const QString &buildConfiguration, bool b)
|
||||
{
|
||||
setValue(buildConfiguration, "clearSystemEnvironment", !b);
|
||||
}
|
||||
|
||||
bool Qt4Project::useSystemEnvironment(const QString &buildConfiguration) const
|
||||
{
|
||||
bool b = !(value(buildConfiguration, "clearSystemEnvironment").isValid() && value(buildConfiguration, "clearSystemEnvironment").toBool());
|
||||
return b;
|
||||
}
|
||||
|
||||
QString Qt4Project::qtDir(const QString &buildConfiguration) const
|
||||
{
|
||||
QtVersion *version = qtVersion(buildConfiguration);
|
||||
if (version)
|
||||
return version->path();
|
||||
return QString::null;
|
||||
}
|
||||
|
||||
QtVersion *Qt4Project::qtVersion(const QString &buildConfiguration) const
|
||||
{
|
||||
return m_manager->versionManager()->version(qtVersionId(buildConfiguration));
|
||||
}
|
||||
|
||||
int Qt4Project::qtVersionId(const QString &buildConfiguration) const
|
||||
{
|
||||
if (debug)
|
||||
qDebug()<<"Looking for qtVersion ID of "<<buildConfiguration;
|
||||
int id = 0;
|
||||
QVariant vid = value(buildConfiguration, "QtVersionId");
|
||||
if(vid.isValid()) {
|
||||
id = vid.toInt();
|
||||
if (m_manager->versionManager()->version(id)->isValid()) {
|
||||
return id;
|
||||
} else {
|
||||
const_cast<Qt4Project *>(this)->setValue(buildConfiguration, "QtVersionId", 0);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
// Backward compatibilty, we might have just the name:
|
||||
QString vname = value(buildConfiguration, "QtVersion").toString();
|
||||
if (debug)
|
||||
qDebug()<<" Backward compatibility reading QtVersion"<<vname;
|
||||
if(!vname.isEmpty()) {
|
||||
const QList<QtVersion *> &versions = m_manager->versionManager()->versions();
|
||||
foreach (const QtVersion * const version, versions) {
|
||||
if(version->name() == vname) {
|
||||
if (debug)
|
||||
qDebug()<<"found name in versions";
|
||||
const_cast<Qt4Project *>(this)->setValue(buildConfiguration, "QtVersionId", version->uniqueId());
|
||||
return version->uniqueId();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (debug)
|
||||
qDebug()<<" using qtversion with id ="<<id;
|
||||
// Nothing found, reset to default
|
||||
const_cast<Qt4Project *>(this)->setValue(buildConfiguration, "QtVersionId", id);
|
||||
return id;
|
||||
}
|
||||
|
||||
void Qt4Project::setQtVersion(const QString &buildConfiguration, int id)
|
||||
{
|
||||
setValue(buildConfiguration, "QtVersionId", id);
|
||||
}
|
||||
|
||||
BuildStepConfigWidget *Qt4Project::createConfigWidget()
|
||||
{
|
||||
return new Qt4BuildConfigWidget(this);
|
||||
}
|
||||
|
||||
QList<BuildStepConfigWidget*> Qt4Project::subConfigWidgets()
|
||||
{
|
||||
QList<BuildStepConfigWidget*> subWidgets;
|
||||
subWidgets << new Qt4BuildEnvironmentWidget(this);
|
||||
return subWidgets;
|
||||
}
|
||||
|
||||
QList<ProjectExplorer::EnvironmentItem> Qt4Project::userEnvironmentChanges(const QString &buildConfig) const
|
||||
{
|
||||
return EnvironmentItem::fromStringList(value(buildConfig, "userEnvironmentChanges").toStringList());
|
||||
}
|
||||
|
||||
void Qt4Project::setUserEnvironmentChanges(const QString &buildConfig, const QList<ProjectExplorer::EnvironmentItem> &diff)
|
||||
{
|
||||
setValue(buildConfig, "userEnvironmentChanges", EnvironmentItem::toStringList(diff));
|
||||
}
|
||||
|
||||
/// **************************
|
||||
/// Qt4ProjectBuildConfigWidget
|
||||
/// **************************
|
||||
|
||||
|
||||
void Qt4Project::collectApplicationProFiles(QList<Qt4ProFileNode *> &list, Qt4ProFileNode *node)
|
||||
{
|
||||
if (node->projectType() == Internal::ApplicationTemplate
|
||||
|| node->projectType() == Internal::ScriptTemplate) {
|
||||
list.append(node);
|
||||
}
|
||||
foreach (ProjectNode *n, node->subProjectNodes()) {
|
||||
Qt4ProFileNode *qt4ProFileNode = qobject_cast<Qt4ProFileNode *>(n);
|
||||
if (qt4ProFileNode)
|
||||
collectApplicationProFiles(list, qt4ProFileNode);
|
||||
}
|
||||
}
|
||||
|
||||
void Qt4Project::foldersAboutToBeAdded(FolderNode *, const QList<FolderNode*> &nodes)
|
||||
{
|
||||
QList<Qt4ProFileNode *> list;
|
||||
foreach (FolderNode *node, nodes) {
|
||||
Qt4ProFileNode *qt4ProFileNode = qobject_cast<Qt4ProFileNode *>(node);
|
||||
if (qt4ProFileNode)
|
||||
collectApplicationProFiles(list, qt4ProFileNode);
|
||||
}
|
||||
m_applicationProFileChange = list;
|
||||
}
|
||||
|
||||
void Qt4Project::checkForNewApplicationProjects()
|
||||
{
|
||||
// Check all new project nodes
|
||||
// against all runConfigurations
|
||||
|
||||
foreach (Qt4ProFileNode *qt4proFile, m_applicationProFileChange) {
|
||||
bool found = false;
|
||||
foreach (QSharedPointer<RunConfiguration> rc, runConfigurations()) {
|
||||
QSharedPointer<Qt4RunConfiguration> qtrc = rc.dynamicCast<Qt4RunConfiguration>();
|
||||
if (qtrc && qtrc->proFilePath() == qt4proFile->path()) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
QSharedPointer<Qt4RunConfiguration> newRc(new Qt4RunConfiguration(this, qt4proFile->path()));
|
||||
addRunConfiguration(newRc);
|
||||
m_isApplication = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Qt4Project::checkForDeletedApplicationProjects()
|
||||
{
|
||||
QStringList paths;
|
||||
foreach (Qt4ProFileNode * node, applicationProFiles())
|
||||
paths.append(node->path());
|
||||
|
||||
qDebug()<<"Still existing paths :"<<paths;
|
||||
|
||||
QList<QSharedPointer<Qt4RunConfiguration> > removeList;
|
||||
foreach (QSharedPointer<RunConfiguration> rc, runConfigurations()) {
|
||||
if (QSharedPointer<Qt4RunConfiguration> qt4rc = rc.dynamicCast<Qt4RunConfiguration>()) {
|
||||
if (!paths.contains(qt4rc->proFilePath())) {
|
||||
removeList.append(qt4rc);
|
||||
qDebug()<<"Removing runConfiguration for "<<qt4rc->proFilePath();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool resetActiveRunConfiguration = false;
|
||||
QSharedPointer<RunConfiguration> rc(new ProjectExplorer::CustomExecutableRunConfiguration(this));
|
||||
foreach(QSharedPointer<Qt4RunConfiguration> qt4rc, removeList) {
|
||||
removeRunConfiguration(qt4rc);
|
||||
if (activeRunConfiguration() == qt4rc)
|
||||
resetActiveRunConfiguration = true;
|
||||
}
|
||||
|
||||
if (runConfigurations().isEmpty()) {
|
||||
QSharedPointer<RunConfiguration> rc(new ProjectExplorer::CustomExecutableRunConfiguration(this));
|
||||
addRunConfiguration(rc);
|
||||
setActiveRunConfiguration(rc);
|
||||
m_isApplication = false;
|
||||
} else if (resetActiveRunConfiguration) {
|
||||
setActiveRunConfiguration(runConfigurations().first());
|
||||
}
|
||||
}
|
||||
|
||||
QList<Qt4ProFileNode *> Qt4Project::applicationProFiles() const
|
||||
{
|
||||
QList<Qt4ProFileNode *> list;
|
||||
collectApplicationProFiles(list, rootProjectNode());
|
||||
return list;
|
||||
}
|
||||
|
||||
void Qt4Project::projectTypeChanged(Qt4ProFileNode *node, const Qt4ProjectType oldType, const Qt4ProjectType newType)
|
||||
{
|
||||
if (oldType == Internal::ApplicationTemplate
|
||||
|| oldType == Internal::ScriptTemplate) {
|
||||
// check wheter we need to delete a Run Configuration
|
||||
checkForDeletedApplicationProjects();
|
||||
}
|
||||
|
||||
if (newType == Internal::ApplicationTemplate
|
||||
|| newType == Internal::ScriptTemplate) {
|
||||
// add a new Run Configuration
|
||||
m_applicationProFileChange.clear();
|
||||
m_applicationProFileChange.append(node);
|
||||
checkForNewApplicationProjects();
|
||||
}
|
||||
}
|
||||
|
||||
void Qt4Project::proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *node)
|
||||
{
|
||||
foreach (QSharedPointer<RunConfiguration> rc, runConfigurations()) {
|
||||
if (QSharedPointer<Qt4RunConfiguration> qt4rc = rc.dynamicCast<Qt4RunConfiguration>()) {
|
||||
if (qt4rc->proFilePath() == node->path()) {
|
||||
qt4rc->updateCachedValues();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QMakeStep *Qt4Project::qmakeStep() const
|
||||
{
|
||||
QMakeStep *qs = 0;
|
||||
foreach(BuildStep *bs, buildSteps())
|
||||
if ( (qs = qobject_cast<QMakeStep *>(bs)) != 0)
|
||||
return qs;
|
||||
return 0;
|
||||
}
|
||||
|
||||
MakeStep *Qt4Project::makeStep() const
|
||||
{
|
||||
MakeStep *qs = 0;
|
||||
foreach(BuildStep *bs, buildSteps())
|
||||
if ((qs = qobject_cast<MakeStep *>(bs)) != 0)
|
||||
return qs;
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user