2009-02-25 09:15:00 +01:00
|
|
|
/**************************************************************************
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
|
|
|
** This file is part of Qt Creator
|
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2009-06-17 00:01:27 +10:00
|
|
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Commercial Usage
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
|
|
|
** accordance with the Qt Commercial License Agreement provided with the
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
|
|
** a written agreement between you and Nokia.
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** GNU Lesser General Public License Usage
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
|
|
** General Public License version 2.1 as published by the Free Software
|
|
|
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
|
|
** packaging of this file. Please review the following information to
|
|
|
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
|
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** If you are unsure which license is appropriate for your use, please
|
2009-06-17 00:01:27 +10:00
|
|
|
** contact the sales department at http://www.qtsoftware.com/contact.
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
**************************************************************************/
|
2008-12-02 16:19:05 +01:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "qt4project.h"
|
2008-12-02 16:19:05 +01:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "qt4projectmanager.h"
|
|
|
|
#include "profilereader.h"
|
2008-12-02 18:14:06 +01:00
|
|
|
#include "prowriter.h"
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "makestep.h"
|
|
|
|
#include "qmakestep.h"
|
|
|
|
#include "deployhelper.h"
|
|
|
|
#include "qt4runconfiguration.h"
|
|
|
|
#include "qt4nodes.h"
|
2009-04-20 17:21:31 +02:00
|
|
|
#include "qt4projectconfigwidget.h"
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "qt4buildenvironmentwidget.h"
|
|
|
|
#include "qt4projectmanagerconstants.h"
|
|
|
|
#include "projectloadwizard.h"
|
2009-04-28 12:43:04 +02:00
|
|
|
#include "qtversionmanager.h"
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-06-22 14:32:54 +02:00
|
|
|
#ifdef QTCREATOR_WITH_S60
|
|
|
|
#include "qt-s60/gccetoolchain.h"
|
|
|
|
#endif
|
|
|
|
|
2009-01-20 11:52:04 +01:00
|
|
|
#include <coreplugin/icore.h>
|
2008-12-02 12:01:29 +01:00
|
|
|
#include <coreplugin/messagemanager.h>
|
|
|
|
#include <coreplugin/coreconstants.h>
|
2009-01-19 12:39:20 +01:00
|
|
|
#include <extensionsystem/pluginmanager.h>
|
2008-12-02 12:01:29 +01:00
|
|
|
#include <projectexplorer/nodesvisitor.h>
|
|
|
|
#include <projectexplorer/project.h>
|
|
|
|
#include <projectexplorer/customexecutablerunconfiguration.h>
|
|
|
|
|
|
|
|
#include <QtCore/QDebug>
|
2009-01-19 12:39:20 +01:00
|
|
|
#include <QtCore/QDir>
|
|
|
|
#include <QtGui/QFileDialog>
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
using namespace Qt4ProjectManager;
|
|
|
|
using namespace Qt4ProjectManager::Internal;
|
|
|
|
using namespace ProjectExplorer;
|
|
|
|
|
|
|
|
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 &)
|
|
|
|
{
|
2008-12-05 14:29:18 +01:00
|
|
|
// This is never used
|
|
|
|
return false;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
{
|
2008-12-05 14:29:18 +01:00
|
|
|
return false; // we save after changing anyway
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Qt4ProjectFile::isReadOnly() const
|
|
|
|
{
|
2008-12-02 18:14:06 +01:00
|
|
|
QFileInfo fi(m_filePath);
|
|
|
|
return !fi.isWritable();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Qt4ProjectFile::isSaveAsAllowed() const
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qt4ProjectFile::modified(Core::IFile::ReloadBehavior *)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
/class Qt4Project
|
|
|
|
|
|
|
|
Qt4Project manages information about an individual Qt 4 (.pro) project file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
Qt4Project::Qt4Project(Qt4Manager *manager, const QString& fileName) :
|
|
|
|
m_manager(manager),
|
2009-03-12 15:01:01 +01:00
|
|
|
m_rootProjectNode(0),
|
2008-12-02 12:01:29 +01:00
|
|
|
m_nodesWatcher(new Internal::Qt4NodesWatcher(this)),
|
|
|
|
m_fileInfo(new Qt4ProjectFile(this, fileName, this)),
|
|
|
|
m_isApplication(true),
|
2009-06-22 14:00:04 +02:00
|
|
|
m_projectFiles(new Qt4ProjectFiles),
|
|
|
|
m_toolChain(0)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2008-12-02 18:14:06 +01:00
|
|
|
m_manager->registerProject(this);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-04-28 12:43:04 +02:00
|
|
|
QtVersionManager *vm = QtVersionManager::instance();
|
2009-04-22 16:51:38 +02:00
|
|
|
|
|
|
|
connect(vm, SIGNAL(defaultQtVersionChanged()),
|
2008-12-02 12:01:29 +01:00
|
|
|
this, SLOT(defaultQtVersionChanged()));
|
2009-04-22 16:51:38 +02:00
|
|
|
connect(vm, SIGNAL(qtVersionsChanged()),
|
2008-12-02 12:01:29 +01:00
|
|
|
this, SLOT(qtVersionsChanged()));
|
|
|
|
|
|
|
|
m_updateCodeModelTimer.setSingleShot(true);
|
|
|
|
m_updateCodeModelTimer.setInterval(20);
|
|
|
|
connect(&m_updateCodeModelTimer, SIGNAL(timeout()), this, SLOT(updateCodeModel()));
|
|
|
|
}
|
|
|
|
|
|
|
|
Qt4Project::~Qt4Project()
|
|
|
|
{
|
2008-12-02 18:14:06 +01:00
|
|
|
m_manager->unregisterProject(this);
|
2008-12-02 12:01:29 +01:00
|
|
|
delete m_projectFiles;
|
2009-06-22 14:00:04 +02:00
|
|
|
delete m_toolChain;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Qt4Project::defaultQtVersionChanged()
|
|
|
|
{
|
|
|
|
if (qtVersionId(activeBuildConfiguration()) == 0)
|
2008-12-09 17:17:12 +01:00
|
|
|
m_rootProjectNode->update();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Qt4Project::qtVersionsChanged()
|
|
|
|
{
|
2009-04-22 16:51:38 +02:00
|
|
|
QtVersionManager *vm = QtVersionManager::instance();
|
2008-12-02 12:01:29 +01:00
|
|
|
foreach (QString bc, buildConfigurations()) {
|
2009-04-22 16:51:38 +02:00
|
|
|
if (!vm->version(qtVersionId(bc))->isValid()) {
|
2008-12-02 12:01:29 +01:00
|
|
|
setQtVersion(bc, 0);
|
2008-12-09 11:07:24 +01:00
|
|
|
if (bc == activeBuildConfiguration())
|
2008-12-09 17:17:12 +01:00
|
|
|
m_rootProjectNode->update();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
}
|
2009-06-22 14:00:04 +02:00
|
|
|
delete m_toolChain;
|
|
|
|
m_toolChain = 0;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
2009-06-10 15:39:16 +02:00
|
|
|
// Ensure that the qt version and tool chain in each build configuration is valid
|
2008-12-02 12:01:29 +01:00
|
|
|
// or if not, is reset to the default
|
2009-06-10 15:39:16 +02:00
|
|
|
foreach (const QString &bc, buildConfigurations()) {
|
2008-12-02 12:01:29 +01:00
|
|
|
qtVersionId(bc);
|
2009-06-10 15:39:16 +02:00
|
|
|
toolChainType(bc);
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-03-12 15:01:01 +01:00
|
|
|
m_rootProjectNode = new Qt4ProFileNode(this, m_fileInfo->fileName(), this);
|
|
|
|
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 *)),
|
2009-05-04 18:22:40 +02:00
|
|
|
this, SLOT(scheduleUpdateCodeModel(Qt4ProjectManager::Internal::Qt4ProFileNode *)));
|
2009-03-12 15:01:01 +01:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2009-05-04 18:22:40 +02:00
|
|
|
void Qt4Project::scheduleUpdateCodeModel(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
m_updateCodeModelTimer.start();
|
2009-05-04 18:22:40 +02:00
|
|
|
m_proFilesForCodeModelUpdate.append(pro);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
2009-06-09 18:02:23 +02:00
|
|
|
ProjectExplorer::ToolChain *Qt4Project::toolChain(const QString &buildConfiguration) const
|
|
|
|
{
|
2009-06-22 14:00:04 +02:00
|
|
|
if (!m_toolChain) {
|
|
|
|
m_toolChain = qtVersion(buildConfiguration)->createToolChain(toolChainType(buildConfiguration));
|
2009-06-22 14:32:54 +02:00
|
|
|
#ifdef QTCREATOR_WITH_S60
|
|
|
|
if (m_toolChain->type() == ToolChain::GCCE) {
|
|
|
|
static_cast<GCCEToolChain *>(m_toolChain)->setProject(this);
|
|
|
|
}
|
|
|
|
#endif
|
2009-06-22 14:00:04 +02:00
|
|
|
}
|
|
|
|
return m_toolChain;
|
2009-06-09 18:02:23 +02:00
|
|
|
}
|
|
|
|
|
2009-03-16 18:13:45 +01:00
|
|
|
QString Qt4Project::makeCommand(const QString &buildConfiguration) const
|
|
|
|
{
|
2009-06-26 14:53:13 +02:00
|
|
|
ToolChain *tc = toolChain(buildConfiguration);
|
|
|
|
return tc ? tc->makeCommand() : "make";
|
2009-02-10 15:34:25 +01:00
|
|
|
}
|
|
|
|
|
2009-06-05 16:10:26 +02:00
|
|
|
QString Qt4Project::defaultMakeTarget(const QString &buildConfiguration) const
|
|
|
|
{
|
2009-06-26 14:53:13 +02:00
|
|
|
ToolChain *tc = toolChain(buildConfiguration);
|
|
|
|
return tc ? toolChain(buildConfiguration)->defaultMakeTarget() : "";
|
2009-06-05 16:10:26 +02:00
|
|
|
}
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void Qt4Project::updateCodeModel()
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
qDebug()<<"Qt4Project::updateCodeModel()";
|
|
|
|
|
|
|
|
CppTools::CppModelManagerInterface *modelmanager =
|
2009-01-20 15:31:33 +01:00
|
|
|
ExtensionSystem::PluginManager::instance()
|
|
|
|
->getObject<CppTools::CppModelManagerInterface>();
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-01-20 15:31:33 +01:00
|
|
|
if (!modelmanager)
|
2008-12-02 12:01:29 +01:00
|
|
|
return;
|
|
|
|
|
2009-05-04 18:22:40 +02:00
|
|
|
QStringList predefinedIncludePaths;
|
|
|
|
QStringList predefinedFrameworkPaths;
|
|
|
|
QByteArray predefinedMacros;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-06-09 18:02:23 +02:00
|
|
|
ToolChain *tc = toolChain(activeBuildConfiguration());
|
2009-02-12 12:39:19 +01:00
|
|
|
QList<HeaderPath> allHeaderPaths;
|
|
|
|
if (tc) {
|
|
|
|
predefinedMacros = tc->predefinedMacros();
|
|
|
|
allHeaderPaths = tc->systemHeaderPaths();
|
2009-02-12 16:09:23 +01:00
|
|
|
//qDebug()<<"Predifined Macros";
|
|
|
|
//qDebug()<<tc->predefinedMacros();
|
|
|
|
//qDebug()<<"";
|
|
|
|
//qDebug()<<"System Header Paths";
|
|
|
|
//foreach(const HeaderPath &hp, tc->systemHeaderPaths())
|
|
|
|
// qDebug()<<hp.path();
|
2009-02-12 12:39:19 +01:00
|
|
|
}
|
2009-02-10 15:34:25 +01:00
|
|
|
foreach (HeaderPath headerPath, allHeaderPaths) {
|
|
|
|
if (headerPath.kind() == HeaderPath::FrameworkHeaderPath)
|
2009-05-04 18:22:40 +02:00
|
|
|
predefinedFrameworkPaths.append(headerPath.path());
|
2009-02-10 15:34:25 +01:00
|
|
|
else
|
2009-05-04 18:22:40 +02:00
|
|
|
predefinedIncludePaths.append(headerPath.path());
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
2009-05-04 18:22:40 +02:00
|
|
|
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"));
|
|
|
|
|
|
|
|
predefinedIncludePaths.append(newQtIncludePath);
|
2008-12-02 12:01:29 +01:00
|
|
|
QDir dir(newQtIncludePath);
|
|
|
|
foreach (QFileInfo info, dir.entryInfoList(QDir::Dirs)) {
|
2009-06-26 16:27:31 +02:00
|
|
|
const QString path = info.fileName();
|
|
|
|
|
|
|
|
if (path == QLatin1String("Qt"))
|
|
|
|
continue; // skip $QT_INSTALL_HEADERS/Qt. There's no need to include it.
|
|
|
|
else if (path.startsWith(QLatin1String("Qt")) || path == QLatin1String("phonon"))
|
|
|
|
predefinedIncludePaths.append(info.absoluteFilePath());
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
2009-05-05 10:17:32 +02:00
|
|
|
FindQt4ProFiles findQt4ProFiles;
|
|
|
|
QList<Qt4ProFileNode *> proFiles = findQt4ProFiles(rootProjectNode());
|
|
|
|
QByteArray definedMacros = predefinedMacros;
|
|
|
|
QStringList allIncludePaths = predefinedIncludePaths;
|
|
|
|
QStringList allFrameworkPaths = predefinedFrameworkPaths;
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
#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
|
|
|
|
|
|
|
|
foreach (Qt4ProFileNode *pro, proFiles) {
|
2009-05-04 18:22:40 +02:00
|
|
|
Internal::CodeModelInfo info;
|
|
|
|
info.defines = predefinedMacros;
|
|
|
|
info.includes = predefinedIncludePaths;
|
|
|
|
info.frameworkPaths = predefinedFrameworkPaths;
|
|
|
|
|
|
|
|
// Add custom defines
|
2008-12-02 12:01:29 +01:00
|
|
|
foreach (const QString def, pro->variableValue(DefinesVar)) {
|
|
|
|
definedMacros += "#define ";
|
2009-05-04 18:22:40 +02:00
|
|
|
info.defines += "#define ";
|
2008-12-02 12:01:29 +01:00
|
|
|
const int index = def.indexOf(QLatin1Char('='));
|
|
|
|
if (index == -1) {
|
|
|
|
definedMacros += def.toLatin1();
|
|
|
|
definedMacros += " 1\n";
|
2009-05-04 18:22:40 +02:00
|
|
|
info.defines += def.toLatin1();
|
|
|
|
info.defines += " 1\n";
|
2008-12-02 12:01:29 +01:00
|
|
|
} else {
|
|
|
|
const QString name = def.left(index);
|
|
|
|
const QString value = def.mid(index + 1);
|
|
|
|
definedMacros += name.toLatin1();
|
|
|
|
definedMacros += ' ';
|
|
|
|
definedMacros += value.toLocal8Bit();
|
|
|
|
definedMacros += '\n';
|
2009-05-04 18:22:40 +02:00
|
|
|
info.defines += name.toLatin1();
|
|
|
|
info.defines += ' ';
|
|
|
|
info.defines += value.toLocal8Bit();
|
|
|
|
info.defines += '\n';
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const QStringList proIncludePaths = pro->variableValue(IncludePathVar);
|
2009-05-13 18:09:47 +02:00
|
|
|
foreach (const QString &includePath, proIncludePaths) {
|
2009-05-04 18:22:40 +02:00
|
|
|
if (!allIncludePaths.contains(includePath))
|
|
|
|
allIncludePaths.append(includePath);
|
|
|
|
if (!info.includes.contains(includePath))
|
|
|
|
info.includes.append(includePath);
|
|
|
|
}
|
|
|
|
|
2009-05-13 18:09:47 +02:00
|
|
|
{ // Pkg Config support
|
|
|
|
QStringList pkgConfig = pro->variableValue(PkgConfigVar);
|
|
|
|
if (!pkgConfig.isEmpty()) {
|
|
|
|
pkgConfig.prepend("--cflags-only-I");
|
|
|
|
QProcess process;
|
|
|
|
process.start("pkg-config", pkgConfig);
|
|
|
|
process.waitForFinished();
|
|
|
|
QString result = process.readAllStandardOutput();
|
|
|
|
foreach(const QString &part, result.trimmed().split(' ', QString::SkipEmptyParts)) {
|
|
|
|
info.includes.append(part.mid(2)); // Chop off "-I"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-04 18:22:40 +02:00
|
|
|
// Add mkspec directory
|
|
|
|
info.includes.append(qtVersion(activeBuildConfiguration())->mkspecPath());
|
|
|
|
|
|
|
|
info.frameworkPaths = allFrameworkPaths;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-05-04 18:22:40 +02:00
|
|
|
foreach (FileNode *fileNode, pro->fileNodes()) {
|
|
|
|
const QString path = fileNode->path();
|
|
|
|
const int type = fileNode->fileType();
|
|
|
|
if (type == HeaderType || type == SourceType) {
|
|
|
|
m_codeModelInfo.insert(path, info);
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-08 12:44:28 +01:00
|
|
|
// Add mkspec directory
|
|
|
|
allIncludePaths.append(qtVersion(activeBuildConfiguration())->mkspecPath());
|
|
|
|
|
2009-05-04 18:22:40 +02:00
|
|
|
// Dump things out
|
|
|
|
// This is debugging output...
|
|
|
|
// qDebug()<<"CodeModel stuff:";
|
|
|
|
// QMap<QString, CodeModelInfo>::const_iterator it, end;
|
|
|
|
// end = m_codeModelInfo.constEnd();
|
|
|
|
// for(it = m_codeModelInfo.constBegin(); it != end; ++it) {
|
|
|
|
// qDebug()<<"File: "<<it.key()<<"\nIncludes:"<<it.value().includes<<"\nDefines"<<it.value().defines<<"\n";
|
|
|
|
// }
|
|
|
|
// qDebug()<<"----------------------------";
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
QStringList files;
|
|
|
|
files += m_projectFiles->files[HeaderType];
|
|
|
|
files += m_projectFiles->generatedFiles[HeaderType];
|
|
|
|
files += m_projectFiles->files[SourceType];
|
|
|
|
files += m_projectFiles->generatedFiles[SourceType];
|
|
|
|
|
2008-12-08 10:44:56 +01:00
|
|
|
CppTools::CppModelManagerInterface::ProjectInfo pinfo = modelmanager->projectInfo(this);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2008-12-08 10:44:56 +01:00
|
|
|
if (pinfo.defines == predefinedMacros &&
|
|
|
|
pinfo.includePaths == allIncludePaths &&
|
|
|
|
pinfo.frameworkPaths == allFrameworkPaths &&
|
|
|
|
pinfo.sourceFiles == files) {
|
|
|
|
modelmanager->updateProjectInfo(pinfo);
|
2008-12-02 12:01:29 +01:00
|
|
|
} else {
|
2009-05-04 18:22:40 +02:00
|
|
|
if (pinfo.defines != predefinedMacros ||
|
|
|
|
pinfo.includePaths != allIncludePaths ||
|
|
|
|
pinfo.frameworkPaths != allFrameworkPaths) {
|
|
|
|
pinfo.sourceFiles.append(QLatin1String("<configuration>"));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-08 10:44:56 +01:00
|
|
|
pinfo.defines = predefinedMacros;
|
2008-12-02 12:01:29 +01:00
|
|
|
// pinfo->defines += definedMacros; // ### FIXME: me
|
2008-12-08 10:44:56 +01:00
|
|
|
pinfo.includePaths = allIncludePaths;
|
|
|
|
pinfo.frameworkPaths = allFrameworkPaths;
|
|
|
|
pinfo.sourceFiles = files;
|
|
|
|
|
|
|
|
modelmanager->updateProjectInfo(pinfo);
|
|
|
|
modelmanager->updateSourceFiles(pinfo.sourceFiles);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
2009-05-04 18:22:40 +02:00
|
|
|
|
|
|
|
// TODO use this information
|
|
|
|
// These are the pro files that were actually changed
|
|
|
|
// if the list is empty we are at the initial stage
|
|
|
|
// TODO check that this also works if pro files get added
|
|
|
|
// and removed
|
|
|
|
m_proFilesForCodeModelUpdate.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
QByteArray Qt4Project::predefinedMacros(const QString &fileName) const
|
|
|
|
{
|
|
|
|
QMap<QString, CodeModelInfo>::const_iterator it = m_codeModelInfo.constFind(fileName);
|
|
|
|
if (it == m_codeModelInfo.constEnd())
|
|
|
|
return QByteArray();
|
|
|
|
else
|
|
|
|
return (*it).defines;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
2009-05-04 18:22:40 +02:00
|
|
|
QStringList Qt4Project::includePaths(const QString &fileName) const
|
|
|
|
{
|
|
|
|
QMap<QString, CodeModelInfo>::const_iterator it = m_codeModelInfo.constFind(fileName);
|
|
|
|
if (it == m_codeModelInfo.constEnd())
|
|
|
|
return QStringList();
|
|
|
|
else
|
|
|
|
return (*it).includes;
|
|
|
|
}
|
|
|
|
|
|
|
|
QStringList Qt4Project::frameworkPaths(const QString &fileName) const
|
|
|
|
{
|
|
|
|
QMap<QString, CodeModelInfo>::const_iterator it = m_codeModelInfo.constFind(fileName);
|
|
|
|
if (it == m_codeModelInfo.constEnd())
|
|
|
|
return QStringList();
|
|
|
|
else
|
|
|
|
return (*it).frameworkPaths;
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2008-12-09 17:17:12 +01:00
|
|
|
///*!
|
|
|
|
// Updates complete project
|
|
|
|
// */
|
2008-12-02 12:01:29 +01:00
|
|
|
void Qt4Project::update()
|
|
|
|
{
|
|
|
|
// TODO Maybe remove this method completely?
|
|
|
|
m_rootProjectNode->update();
|
|
|
|
//updateCodeModel();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
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];
|
|
|
|
}
|
|
|
|
return files;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
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);
|
2009-01-16 13:25:38 +01:00
|
|
|
insertCleanStep(1, cleanStep);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
ProjectLoadWizard wizard(this);
|
|
|
|
wizard.execDialog();
|
|
|
|
} else {
|
|
|
|
// Restoring configuration
|
2008-12-15 12:36:05 +01:00
|
|
|
foreach(const QString &bc, buildConfigurations()) {
|
|
|
|
setValue(bc, "addQDumper", QVariant());
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qt4Project::newBuildConfiguration(const QString &buildConfiguration)
|
|
|
|
{
|
|
|
|
Q_UNUSED(buildConfiguration);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qt4Project::proFileParseError(const QString &errorMessage)
|
|
|
|
{
|
2009-01-20 15:31:33 +01:00
|
|
|
Core::ICore::instance()->messageManager()->printToOutputPane(errorMessage);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Qt4ProFileNode *Qt4Project::rootProjectNode() const
|
|
|
|
{
|
|
|
|
return m_rootProjectNode;
|
|
|
|
}
|
|
|
|
|
2009-05-26 15:22:11 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
ProjectExplorer::Environment Qt4Project::baseEnvironment(const QString &buildConfiguration) const
|
|
|
|
{
|
2009-05-28 16:34:31 +02:00
|
|
|
Environment env = useSystemEnvironment(buildConfiguration) ? Environment::systemEnvironment() : Environment();
|
2009-02-10 15:34:25 +01:00
|
|
|
qtVersion(buildConfiguration)->addToEnvironment(env);
|
2009-06-26 14:53:13 +02:00
|
|
|
ToolChain *tc = toolChain(buildConfiguration);
|
|
|
|
if (tc)
|
|
|
|
tc->addToEnvironment(env);
|
2008-12-02 12:01:29 +01:00
|
|
|
return env;
|
|
|
|
}
|
|
|
|
|
|
|
|
ProjectExplorer::Environment Qt4Project::environment(const QString &buildConfiguration) const
|
|
|
|
{
|
|
|
|
Environment env = baseEnvironment(buildConfiguration);
|
|
|
|
env.modify(userEnvironmentChanges(buildConfiguration));
|
|
|
|
return env;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qt4Project::setUseSystemEnvironment(const QString &buildConfiguration, bool b)
|
|
|
|
{
|
2009-05-27 14:41:07 +02:00
|
|
|
if (useSystemEnvironment(buildConfiguration) == b)
|
|
|
|
return;
|
2008-12-02 12:01:29 +01:00
|
|
|
setValue(buildConfiguration, "clearSystemEnvironment", !b);
|
2009-05-27 14:41:07 +02:00
|
|
|
emit environmentChanged(buildConfiguration);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Qt4Project::useSystemEnvironment(const QString &buildConfiguration) const
|
|
|
|
{
|
|
|
|
bool b = !(value(buildConfiguration, "clearSystemEnvironment").isValid() && value(buildConfiguration, "clearSystemEnvironment").toBool());
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
2009-05-26 15:22:11 +02:00
|
|
|
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)
|
|
|
|
{
|
2009-05-27 14:41:07 +02:00
|
|
|
QStringList list = EnvironmentItem::toStringList(diff);
|
|
|
|
if (list == value(buildConfig, "userEnvironmentChanges").toStringList())
|
|
|
|
return;
|
|
|
|
setValue(buildConfig, "userEnvironmentChanges", list);
|
|
|
|
emit environmentChanged(buildConfig);
|
2009-05-26 15:22:11 +02:00
|
|
|
}
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
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
|
|
|
|
{
|
2009-04-22 16:51:38 +02:00
|
|
|
return QtVersionManager::instance()->version(qtVersionId(buildConfiguration));
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int Qt4Project::qtVersionId(const QString &buildConfiguration) const
|
|
|
|
{
|
2009-04-22 16:51:38 +02:00
|
|
|
QtVersionManager *vm = QtVersionManager::instance();
|
2008-12-02 12:01:29 +01:00
|
|
|
if (debug)
|
|
|
|
qDebug()<<"Looking for qtVersion ID of "<<buildConfiguration;
|
|
|
|
int id = 0;
|
|
|
|
QVariant vid = value(buildConfiguration, "QtVersionId");
|
2008-12-09 11:07:24 +01:00
|
|
|
if (vid.isValid()) {
|
2008-12-02 12:01:29 +01:00
|
|
|
id = vid.toInt();
|
2009-04-22 16:51:38 +02:00
|
|
|
if (vm->version(id)->isValid()) {
|
2008-12-02 12:01:29 +01:00
|
|
|
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;
|
2008-12-09 11:07:24 +01:00
|
|
|
if (!vname.isEmpty()) {
|
2009-04-22 16:51:38 +02:00
|
|
|
const QList<QtVersion *> &versions = vm->versions();
|
2008-12-02 12:01:29 +01:00
|
|
|
foreach (const QtVersion * const version, versions) {
|
2008-12-09 11:07:24 +01:00
|
|
|
if (version->name() == vname) {
|
2008-12-02 12:01:29 +01:00
|
|
|
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);
|
2009-06-23 14:14:29 +02:00
|
|
|
updateActiveRunConfiguration();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
2009-06-10 15:39:16 +02:00
|
|
|
void Qt4Project::setToolChainType(const QString &buildConfiguration, ProjectExplorer::ToolChain::ToolChainType type)
|
|
|
|
{
|
|
|
|
setValue(buildConfiguration, "ToolChain", (int)type);
|
2009-06-22 14:00:04 +02:00
|
|
|
delete m_toolChain;
|
|
|
|
m_toolChain = 0;
|
2009-06-23 14:14:29 +02:00
|
|
|
updateActiveRunConfiguration();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qt4Project::updateActiveRunConfiguration()
|
|
|
|
{
|
2009-06-25 12:10:30 +02:00
|
|
|
const QSharedPointer<RunConfiguration> activeRunConfig = activeRunConfiguration();
|
|
|
|
if (!activeRunConfig.isNull() && !activeRunConfig->isEnabled()) {
|
|
|
|
foreach (const QSharedPointer<RunConfiguration> &runConfiguration, runConfigurations()) {
|
2009-06-23 14:14:29 +02:00
|
|
|
if (runConfiguration->isEnabled()) {
|
|
|
|
setActiveRunConfiguration(runConfiguration);
|
2009-06-25 12:10:30 +02:00
|
|
|
break;
|
2009-06-23 14:14:29 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
emit runConfigurationsEnabledStateChanged();
|
|
|
|
emit invalidateCachedTargetInformation();
|
2009-06-10 15:39:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ProjectExplorer::ToolChain::ToolChainType Qt4Project::toolChainType(const QString &buildConfiguration) const
|
|
|
|
{
|
2009-06-23 14:14:29 +02:00
|
|
|
const ProjectExplorer::ToolChain::ToolChainType originalType =
|
2009-06-10 15:39:16 +02:00
|
|
|
(ProjectExplorer::ToolChain::ToolChainType)value(buildConfiguration, "ToolChain").toInt();
|
2009-06-23 14:14:29 +02:00
|
|
|
ProjectExplorer::ToolChain::ToolChainType type = originalType;
|
2009-06-10 15:39:16 +02:00
|
|
|
const QtVersion *version = qtVersion(buildConfiguration);
|
|
|
|
if (!version->possibleToolChainTypes().contains(type)) // use default tool chain
|
|
|
|
type = version->defaultToolchainType();
|
2009-06-23 14:14:29 +02:00
|
|
|
if (type != originalType)
|
|
|
|
const_cast<Qt4Project *>(this)->setToolChainType(buildConfiguration, type);
|
2009-06-10 15:39:16 +02:00
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
BuildStepConfigWidget *Qt4Project::createConfigWidget()
|
|
|
|
{
|
2009-04-20 17:21:31 +02:00
|
|
|
return new Qt4ProjectConfigWidget(this);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
QList<BuildStepConfigWidget*> Qt4Project::subConfigWidgets()
|
|
|
|
{
|
|
|
|
QList<BuildStepConfigWidget*> subWidgets;
|
|
|
|
subWidgets << new Qt4BuildEnvironmentWidget(this);
|
|
|
|
return subWidgets;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// **************************
|
|
|
|
/// 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());
|
|
|
|
|
2009-02-12 16:09:23 +01:00
|
|
|
// qDebug()<<"Still existing paths :"<<paths;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
QList<QSharedPointer<Qt4RunConfiguration> > removeList;
|
|
|
|
foreach (QSharedPointer<RunConfiguration> rc, runConfigurations()) {
|
|
|
|
if (QSharedPointer<Qt4RunConfiguration> qt4rc = rc.dynamicCast<Qt4RunConfiguration>()) {
|
|
|
|
if (!paths.contains(qt4rc->proFilePath())) {
|
|
|
|
removeList.append(qt4rc);
|
2009-02-12 16:09:23 +01:00
|
|
|
// qDebug()<<"Removing runConfiguration for "<<qt4rc->proFilePath();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool resetActiveRunConfiguration = false;
|
|
|
|
QSharedPointer<RunConfiguration> rc(new ProjectExplorer::CustomExecutableRunConfiguration(this));
|
2008-12-09 11:07:24 +01:00
|
|
|
foreach (QSharedPointer<Qt4RunConfiguration> qt4rc, removeList) {
|
2008-12-02 12:01:29 +01:00
|
|
|
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()) {
|
2009-03-19 15:04:43 +01:00
|
|
|
qt4rc->invalidateCachedTargetInformation();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2008-12-02 18:14:06 +01:00
|
|
|
|
2008-12-05 14:29:18 +01:00
|
|
|
bool Qt4Project::hasSubNode(Qt4PriFileNode *root, const QString &path)
|
2008-12-02 18:14:06 +01:00
|
|
|
{
|
2008-12-05 14:29:18 +01:00
|
|
|
if (root->path() == path)
|
|
|
|
return true;
|
|
|
|
foreach (FolderNode *fn, root->subFolderNodes()) {
|
|
|
|
if (qobject_cast<Qt4ProFileNode *>(fn)) {
|
|
|
|
// we aren't interested in pro file nodes
|
2008-12-09 11:07:24 +01:00
|
|
|
} else if (Qt4PriFileNode *qt4prifilenode = qobject_cast<Qt4PriFileNode *>(fn)) {
|
2008-12-05 14:29:18 +01:00
|
|
|
if (hasSubNode(qt4prifilenode, path))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
2008-12-02 18:14:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Qt4Project::findProFile(const QString& fileName, Qt4ProFileNode *root, QList<Qt4ProFileNode *> &list)
|
|
|
|
{
|
2008-12-05 14:29:18 +01:00
|
|
|
if (hasSubNode(root, fileName))
|
2008-12-02 18:14:06 +01:00
|
|
|
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)
|
|
|
|
{
|
2008-12-05 14:29:18 +01:00
|
|
|
if (files(Qt4Project::ExcludeGeneratedFiles).contains(name)) {
|
|
|
|
QList<Qt4ProFileNode *> list;
|
|
|
|
findProFile(name, rootProjectNode(), list);
|
|
|
|
foreach(Qt4ProFileNode *node, list)
|
|
|
|
node->update();
|
|
|
|
}
|
2008-12-02 18:14:06 +01:00
|
|
|
}
|
2009-03-19 15:04:43 +01:00
|
|
|
|
|
|
|
void Qt4Project::invalidateCachedTargetInformation()
|
|
|
|
{
|
2009-06-22 15:51:21 +02:00
|
|
|
emit targetInformationChanged();
|
2009-03-19 15:04:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Handle special case were a subproject of the qt directory is opened, and
|
|
|
|
qt was configured to be built as a shadow build -> also build in the sub-
|
|
|
|
project in the correct shadow build directory.
|
|
|
|
*/
|
|
|
|
|
|
|
|
// TODO this function should be called on project first load
|
|
|
|
// and it should check against all configured qt versions ?
|
|
|
|
//void Qt4Project::detectQtShadowBuild(const QString &buildConfiguration) const
|
|
|
|
//{
|
|
|
|
// if (project()->activeBuildConfiguration() == buildConfiguration)
|
|
|
|
// return;
|
|
|
|
//
|
|
|
|
// const QString currentQtDir = static_cast<Qt4Project *>(project())->qtDir(buildConfiguration);
|
|
|
|
// const QString qtSourceDir = static_cast<Qt4Project *>(project())->qtVersion(buildConfiguration)->sourcePath();
|
|
|
|
//
|
|
|
|
// // if the project is a sub-project of Qt and Qt was shadow-built then automatically
|
|
|
|
// // adjust the build directory of the sub-project.
|
|
|
|
// if (project()->file()->fileName().startsWith(qtSourceDir) && qtSourceDir != currentQtDir) {
|
|
|
|
// project()->setValue(buildConfiguration, "useShadowBuild", true);
|
|
|
|
// QString buildDir = QFileInfo(project()->file()->fileName()).absolutePath();
|
|
|
|
// buildDir.replace(qtSourceDir, currentQtDir);
|
|
|
|
// project()->setValue(buildConfiguration, "buildDirectory", buildDir);
|
|
|
|
// project()->setValue(buildConfiguration, "autoShadowBuild", true);
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
|
|
|
|
|