Remove #include <extensionsystem/pluginmanager.h> from icore.h, a
[qt-creator-color-themes.git] / src / plugins / qt4projectmanager / qt4project.cpp
blob0e64fc2be1eb2e22a78a69724004369c6ab1704d
1 /***************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Qt Software Information (qt-info@nokia.com)
8 **
9 **
10 ** Non-Open Source Usage
12 ** Licensees may use this file in accordance with the Qt Beta Version
13 ** License Agreement, Agreement version 2.2 provided with the Software or,
14 ** alternatively, in accordance with the terms contained in a written
15 ** agreement between you and Nokia.
17 ** GNU General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU General
20 ** Public License versions 2.0 or 3.0 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.GPL included in the packaging
22 ** of this file. Please review the following information to ensure GNU
23 ** General Public Licensing requirements will be met:
25 ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
26 ** http://www.gnu.org/copyleft/gpl.html.
28 ** In addition, as a special exception, Nokia gives you certain additional
29 ** rights. These rights are described in the Nokia Qt GPL Exception
30 ** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
32 ***************************************************************************/
34 #include "qt4project.h"
36 #include "qt4projectmanager.h"
37 #include "profilereader.h"
38 #include "prowriter.h"
39 #include "makestep.h"
40 #include "qmakestep.h"
41 #include "deployhelper.h"
42 #include "qt4runconfiguration.h"
43 #include "qtversionmanager.h"
44 #include "qt4nodes.h"
45 #include "qt4buildconfigwidget.h"
46 #include "qt4buildenvironmentwidget.h"
47 #include "qt4projectmanagerconstants.h"
48 #include "projectloadwizard.h"
49 #include "gdbmacrosbuildstep.h"
51 #include <coreplugin/messagemanager.h>
52 #include <coreplugin/coreconstants.h>
53 #include <cpptools/cppmodelmanagerinterface.h>
54 #include <extensionsystem/pluginmanager.h>
55 #include <projectexplorer/nodesvisitor.h>
56 #include <projectexplorer/project.h>
57 #include <projectexplorer/customexecutablerunconfiguration.h>
59 #include <QtCore/QDebug>
60 #include <QtCore/QDir>
61 #include <QtGui/QFileDialog>
63 using namespace Qt4ProjectManager;
64 using namespace Qt4ProjectManager::Internal;
65 using namespace ProjectExplorer;
67 enum { debug = 0 };
69 namespace Qt4ProjectManager {
70 namespace Internal {
72 // Qt4ProjectFiles: Struct for (Cached) lists of files in a project
73 struct Qt4ProjectFiles {
74 void clear();
75 bool equals(const Qt4ProjectFiles &f) const;
77 QStringList files[ProjectExplorer::FileTypeSize];
78 QStringList generatedFiles[ProjectExplorer::FileTypeSize];
79 QStringList proFiles;
82 void Qt4ProjectFiles::clear()
84 for (int i = 0; i < FileTypeSize; ++i) {
85 files[i].clear();
86 generatedFiles[i].clear();
88 proFiles.clear();
91 bool Qt4ProjectFiles::equals(const Qt4ProjectFiles &f) const
93 for (int i = 0; i < FileTypeSize; ++i)
94 if (files[i] != f.files[i] || generatedFiles[i] != f.generatedFiles[i])
95 return false;
96 if (proFiles != f.proFiles)
97 return false;
98 return true;
101 inline bool operator==(const Qt4ProjectFiles &f1, const Qt4ProjectFiles &f2)
102 { return f1.equals(f2); }
104 inline bool operator!=(const Qt4ProjectFiles &f1, const Qt4ProjectFiles &f2)
105 { return !f1.equals(f2); }
107 QDebug operator<<(QDebug d, const Qt4ProjectFiles &f)
109 QDebug nsp = d.nospace();
110 nsp << "Qt4ProjectFiles: proFiles=" << f.proFiles << '\n';
111 for (int i = 0; i < FileTypeSize; ++i)
112 nsp << "Type " << i << " files=" << f.files[i] << " generated=" << f.generatedFiles[i] << '\n';
113 return d;
116 // A visitor to collect all files of a project in a Qt4ProjectFiles struct
117 class ProjectFilesVisitor : public ProjectExplorer::NodesVisitor
119 Q_DISABLE_COPY(ProjectFilesVisitor)
120 ProjectFilesVisitor(Qt4ProjectFiles *files);
121 public:
123 static void findProjectFiles(Qt4ProFileNode *rootNode, Qt4ProjectFiles *files);
125 void visitProjectNode(ProjectNode *projectNode);
126 void visitFolderNode(FolderNode *folderNode);
128 private:
129 Qt4ProjectFiles *m_files;
132 ProjectFilesVisitor::ProjectFilesVisitor(Qt4ProjectFiles *files) :
133 m_files(files)
137 void ProjectFilesVisitor::findProjectFiles(Qt4ProFileNode *rootNode, Qt4ProjectFiles *files)
139 files->clear();
140 ProjectFilesVisitor visitor(files);
141 rootNode->accept(&visitor);
142 for (int i = 0; i < FileTypeSize; ++i) {
143 qSort(files->files[i]);
144 qSort(files->generatedFiles[i]);
146 qSort(files->proFiles);
149 void ProjectFilesVisitor::visitProjectNode(ProjectNode *projectNode)
151 const QString path = projectNode->path();
152 if (!m_files->proFiles.contains(path))
153 m_files->proFiles.append(path);
154 visitFolderNode(projectNode);
157 void ProjectFilesVisitor::visitFolderNode(FolderNode *folderNode)
159 foreach (FileNode *fileNode, folderNode->fileNodes()) {
160 const QString path = fileNode->path();
161 const int type = fileNode->fileType();
162 QStringList &targetList = fileNode->isGenerated() ? m_files->generatedFiles[type] : m_files->files[type];
163 if (!targetList.contains(path))
164 targetList.push_back(path);
171 // ----------- Qt4ProjectFile
172 Qt4ProjectFile::Qt4ProjectFile(Qt4Project *project, const QString &filePath, QObject *parent)
173 : Core::IFile(parent),
174 m_mimeType(QLatin1String(Qt4ProjectManager::Constants::PROFILE_MIMETYPE)),
175 m_project(project),
176 m_filePath(filePath)
180 bool Qt4ProjectFile::save(const QString &)
182 // This is never used
183 return false;
186 QString Qt4ProjectFile::fileName() const
188 return m_filePath;
191 QString Qt4ProjectFile::defaultPath() const
193 return QString();
196 QString Qt4ProjectFile::suggestedFileName() const
198 return QString();
201 QString Qt4ProjectFile::mimeType() const
203 return m_mimeType;
206 bool Qt4ProjectFile::isModified() const
208 return false; // we save after changing anyway
211 bool Qt4ProjectFile::isReadOnly() const
213 QFileInfo fi(m_filePath);
214 return !fi.isWritable();
217 bool Qt4ProjectFile::isSaveAsAllowed() const
219 return false;
222 void Qt4ProjectFile::modified(Core::IFile::ReloadBehavior *)
227 /class Qt4Project
229 Qt4Project manages information about an individual Qt 4 (.pro) project file.
232 Qt4Project::Qt4Project(Qt4Manager *manager, const QString& fileName) :
233 m_manager(manager),
234 m_rootProjectNode(new Qt4ProFileNode(this, fileName, this)),
235 m_nodesWatcher(new Internal::Qt4NodesWatcher(this)),
236 m_fileInfo(new Qt4ProjectFile(this, fileName, this)),
237 m_isApplication(true),
238 m_projectFiles(new Qt4ProjectFiles)
240 m_manager->registerProject(this);
241 m_rootProjectNode->registerWatcher(m_nodesWatcher);
242 connect(m_nodesWatcher, SIGNAL(foldersAdded()), this, SLOT(updateFileList()));
243 connect(m_nodesWatcher, SIGNAL(foldersRemoved()), this, SLOT(updateFileList()));
244 connect(m_nodesWatcher, SIGNAL(filesAdded()), this, SLOT(updateFileList()));
245 connect(m_nodesWatcher, SIGNAL(filesRemoved()), this, SLOT(updateFileList()));
246 connect(m_nodesWatcher, SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *)),
247 this, SLOT(scheduleUpdateCodeModel()));
249 connect(qt4ProjectManager()->versionManager(), SIGNAL(defaultQtVersionChanged()),
250 this, SLOT(defaultQtVersionChanged()));
251 connect(qt4ProjectManager()->versionManager(), SIGNAL(qtVersionsChanged()),
252 this, SLOT(qtVersionsChanged()));
254 m_updateCodeModelTimer.setSingleShot(true);
255 m_updateCodeModelTimer.setInterval(20);
256 connect(&m_updateCodeModelTimer, SIGNAL(timeout()), this, SLOT(updateCodeModel()));
259 Qt4Project::~Qt4Project()
261 m_manager->unregisterProject(this);
262 delete m_projectFiles;
265 void Qt4Project::defaultQtVersionChanged()
267 if (qtVersionId(activeBuildConfiguration()) == 0)
268 m_rootProjectNode->update();
271 void Qt4Project::qtVersionsChanged()
273 foreach (QString bc, buildConfigurations()) {
274 if (!qt4ProjectManager()->versionManager()->version(qtVersionId(bc))->isValid()) {
275 setQtVersion(bc, 0);
276 if (bc == activeBuildConfiguration())
277 m_rootProjectNode->update();
282 void Qt4Project::updateFileList()
284 Qt4ProjectFiles newFiles;
285 ProjectFilesVisitor::findProjectFiles(m_rootProjectNode, &newFiles);
286 if (newFiles != *m_projectFiles) {
287 *m_projectFiles = newFiles;
288 emit fileListChanged();
289 if (debug)
290 qDebug() << Q_FUNC_INFO << *m_projectFiles;
294 void Qt4Project::restoreSettingsImpl(PersistentSettingsReader &settingsReader)
296 Project::restoreSettingsImpl(settingsReader);
298 addDefaultBuild();
300 // Ensure that the qt version in each build configuration is valid
301 // or if not, is reset to the default
302 foreach (const QString &bc, buildConfigurations())
303 qtVersionId(bc);
305 update();
307 // restored old runconfigurations
308 if (runConfigurations().isEmpty()) {
309 // Oha no runConfigurations, add some
310 QList<Qt4ProFileNode *> list;
311 collectApplicationProFiles(list, m_rootProjectNode);
313 if (!list.isEmpty()) {
314 foreach (Qt4ProFileNode *node, list) {
315 QSharedPointer<RunConfiguration> rc(new Qt4RunConfiguration(this, node->path()));
316 addRunConfiguration(rc);
318 setActiveRunConfiguration(runConfigurations().first());
319 } else {
320 QSharedPointer<RunConfiguration> rc(new ProjectExplorer::CustomExecutableRunConfiguration(this));
321 addRunConfiguration(rc);
322 setActiveRunConfiguration(rc);
323 m_isApplication = false;
327 // Now connect
328 connect(m_nodesWatcher, SIGNAL(foldersAboutToBeAdded(FolderNode *, const QList<FolderNode*> &)),
329 this, SLOT(foldersAboutToBeAdded(FolderNode *, const QList<FolderNode*> &)));
330 connect(m_nodesWatcher, SIGNAL(foldersAdded()), this, SLOT(checkForNewApplicationProjects()));
332 connect(m_nodesWatcher, SIGNAL(foldersRemoved()), this, SLOT(checkForDeletedApplicationProjects()));
334 connect(m_nodesWatcher, SIGNAL(projectTypeChanged(Qt4ProjectManager::Internal::Qt4ProFileNode *,
335 const Qt4ProjectManager::Internal::Qt4ProjectType,
336 const Qt4ProjectManager::Internal::Qt4ProjectType)),
337 this, SLOT(projectTypeChanged(Qt4ProjectManager::Internal::Qt4ProFileNode *,
338 const Qt4ProjectManager::Internal::Qt4ProjectType,
339 const Qt4ProjectManager::Internal::Qt4ProjectType)));
341 connect(m_nodesWatcher, SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *)),
342 this, SLOT(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *)));
346 void Qt4Project::saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &writer)
348 Project::saveSettingsImpl(writer);
351 namespace {
352 class FindQt4ProFiles: protected ProjectExplorer::NodesVisitor {
353 QList<Qt4ProFileNode *> m_proFiles;
355 public:
356 QList<Qt4ProFileNode *> operator()(ProjectNode *root)
358 m_proFiles.clear();
359 root->accept(this);
360 return m_proFiles;
363 protected:
364 virtual void visitProjectNode(ProjectNode *projectNode)
366 if (Qt4ProFileNode *pro = qobject_cast<Qt4ProFileNode *>(projectNode))
367 m_proFiles.append(pro);
372 void Qt4Project::scheduleUpdateCodeModel()
374 m_updateCodeModelTimer.start();
377 void Qt4Project::updateCodeModel()
379 if (debug)
380 qDebug()<<"Qt4Project::updateCodeModel()";
382 CppTools::CppModelManagerInterface *modelmanager =
383 m_manager->pluginManager()->getObject<CppTools::CppModelManagerInterface>();
385 if (! modelmanager)
386 return;
388 QStringList allIncludePaths;
389 QStringList allFrameworkPaths;
391 const QHash<QString, QString> versionInfo = qtVersion(activeBuildConfiguration())->versionInfo();
392 const QString newQtIncludePath = versionInfo.value(QLatin1String("QT_INSTALL_HEADERS"));
393 const QString newQtLibsPath = versionInfo.value(QLatin1String("QT_INSTALL_LIBS"));
395 QByteArray predefinedMacros;
396 QtVersion::ToolchainType t = qtVersion(activeBuildConfiguration())->toolchainType();
397 if (t == QtVersion::MinGW || t == QtVersion::OTHER) {
398 QStringList list = rootProjectNode()->variableValue(Internal::CxxCompilerVar);
399 QString qmake_cxx = list.isEmpty() ? QString::null : list.first();
400 qmake_cxx = environment(activeBuildConfiguration()).searchInPath(qmake_cxx);
401 m_preproc.setGcc(qmake_cxx);
402 predefinedMacros = m_preproc.predefinedMacros();
403 foreach (HeaderPath headerPath, m_preproc.systemHeaderPaths()) {
404 if (headerPath.kind() == HeaderPath::FrameworkHeaderPath)
405 allFrameworkPaths.append(headerPath.path());
406 else
407 allIncludePaths.append(headerPath.path());
410 } else if (t == QtVersion::MSVC || t == QtVersion::WINCE) {
411 #ifdef QTCREATOR_WITH_MSVC_INCLUDES
412 Environment env = environment(activeBuildConfiguration());
413 allIncludePaths.append(env.value("INCLUDE").split(QLatin1Char(';')));
414 #endif
415 predefinedMacros +=
416 "#define __WIN32__\n"
417 "#define __WIN32\n"
418 "#define _WIN32\n"
419 "#define WIN32\n"
420 "#define __WINNT__\n"
421 "#define __WINNT\n"
422 "#define WINNT\n"
423 "#define _X86_\n"
424 "#define __MSVCRT__\n";
427 allIncludePaths.append(newQtIncludePath);
429 QDir dir(newQtIncludePath);
430 foreach (QFileInfo info, dir.entryInfoList(QDir::Dirs)) {
431 if (! info.fileName().startsWith(QLatin1String("Qt")))
432 continue;
433 allIncludePaths.append(info.absoluteFilePath());
436 #ifdef Q_OS_MAC
437 allFrameworkPaths.append(newQtLibsPath);
438 // put QtXXX.framework/Headers directories in include path since that qmake's behavior
439 QDir frameworkDir(newQtLibsPath);
440 foreach (QFileInfo info, frameworkDir.entryInfoList(QDir::Dirs)) {
441 if (! info.fileName().startsWith(QLatin1String("Qt")))
442 continue;
443 allIncludePaths.append(info.absoluteFilePath()+"/Headers");
445 #endif
447 FindQt4ProFiles findQt4ProFiles;
448 QList<Qt4ProFileNode *> proFiles = findQt4ProFiles(rootProjectNode());
449 QByteArray definedMacros;
451 foreach (Qt4ProFileNode *pro, proFiles) {
452 foreach (const QString def, pro->variableValue(DefinesVar)) {
453 definedMacros += "#define ";
454 const int index = def.indexOf(QLatin1Char('='));
455 if (index == -1) {
456 definedMacros += def.toLatin1();
457 definedMacros += " 1\n";
458 } else {
459 const QString name = def.left(index);
460 const QString value = def.mid(index + 1);
461 definedMacros += name.toLatin1();
462 definedMacros += ' ';
463 definedMacros += value.toLocal8Bit();
464 definedMacros += '\n';
468 const QStringList proIncludePaths = pro->variableValue(IncludePathVar);
469 foreach (QString includePath, proIncludePaths) {
470 if (allIncludePaths.contains(includePath))
471 continue;
473 allIncludePaths.append(includePath);
477 // Add mkspec directory
478 allIncludePaths.append(qtVersion(activeBuildConfiguration())->mkspecPath());
480 QStringList files;
481 files += m_projectFiles->files[HeaderType];
482 files += m_projectFiles->generatedFiles[HeaderType];
483 files += m_projectFiles->files[SourceType];
484 files += m_projectFiles->generatedFiles[SourceType];
486 CppTools::CppModelManagerInterface::ProjectInfo pinfo = modelmanager->projectInfo(this);
488 if (pinfo.defines == predefinedMacros &&
489 pinfo.includePaths == allIncludePaths &&
490 pinfo.frameworkPaths == allFrameworkPaths &&
491 pinfo.sourceFiles == files) {
492 modelmanager->updateProjectInfo(pinfo);
493 } else {
494 pinfo.defines = predefinedMacros;
495 // pinfo->defines += definedMacros; // ### FIXME: me
496 pinfo.includePaths = allIncludePaths;
497 pinfo.frameworkPaths = allFrameworkPaths;
498 pinfo.sourceFiles = files;
500 modelmanager->updateProjectInfo(pinfo);
501 modelmanager->updateSourceFiles(pinfo.sourceFiles);
506 ///*!
507 // Updates complete project
508 // */
509 void Qt4Project::update()
511 // TODO Maybe remove this method completely?
512 m_rootProjectNode->update();
513 //updateCodeModel();
516 ProFileReader *Qt4Project::createProFileReader() const
518 ProFileReader *reader = new ProFileReader();
519 connect(reader, SIGNAL(errorFound(const QString&)),
520 this, SLOT(proFileParseError(const QString&)));
521 QtVersion *version = qtVersion(activeBuildConfiguration());
522 if (version->isValid()) {
523 reader->setQtVersion(version);
525 return reader;
529 Returns whether the project is an application, or has an application as a subproject.
531 bool Qt4Project::isApplication() const
533 return m_isApplication;
536 ProjectExplorer::ProjectExplorerPlugin *Qt4Project::projectExplorer() const
538 return m_manager->projectExplorer();
541 ProjectExplorer::IProjectManager *Qt4Project::projectManager() const
543 return m_manager;
546 Qt4Manager *Qt4Project::qt4ProjectManager() const
548 return m_manager;
551 QString Qt4Project::name() const
553 return QFileInfo(file()->fileName()).completeBaseName();
556 Core::IFile *Qt4Project::file() const
558 return m_fileInfo;
561 QStringList Qt4Project::files(FilesMode fileMode) const
563 QStringList files;
564 for (int i = 0; i < FileTypeSize; ++i) {
565 files += m_projectFiles->files[i];
566 if (fileMode == AllFiles)
567 files += m_projectFiles->generatedFiles[i];
569 return files;
572 QList<ProjectExplorer::Project*> Qt4Project::dependsOn()
574 // NBS implement dependsOn
575 return QList<Project *>();
578 void Qt4Project::addDefaultBuild()
580 if (buildConfigurations().isEmpty()) {
581 // We don't have any buildconfigurations, so this is a new project
582 // The Project Load Wizard is a work of art
583 // It will ask the user what kind of build setup he want
584 // It will add missing Qt Versions
585 // And get the project into a buildable state
587 //TODO have a better check wheter there is already a configuration?
588 QMakeStep *qmakeStep = 0;
589 MakeStep *makeStep = 0;
590 GdbMacrosBuildStep *gdbmacrostep;
592 gdbmacrostep = new GdbMacrosBuildStep(this);
593 insertBuildStep(0, gdbmacrostep);
595 qmakeStep = new QMakeStep(this);
596 qmakeStep->setValue("mkspec", "");
597 insertBuildStep(1, qmakeStep);
599 makeStep = new MakeStep(this);
600 insertBuildStep(2, makeStep);
602 GdbMacrosBuildStep *gdbmacrosCleanStep = new GdbMacrosBuildStep(this);
603 gdbmacrosCleanStep->setValue("clean", true);
604 insertCleanStep(0, gdbmacrosCleanStep);
606 MakeStep* cleanStep = new MakeStep(this);
607 cleanStep->setValue("clean", true);
608 insertCleanStep(1, cleanStep);
610 ProjectLoadWizard wizard(this);
611 wizard.execDialog();
612 } else {
613 // Restoring configuration
614 // Do we already have a gdbmacrobuildstep?
615 // If not add it and disable linking of debugging helper
617 // Check for old link debugging helper setting in each buildConfiguration
618 // We add a gdbmacrosbuildstep if at least one has it
619 // TODO remove migration code from pre beta
620 foreach(const QString &bc, buildConfigurations()) {
621 QVariant v = value(bc, "addQDumper");
622 if (v.isValid() && v.toBool()) {
623 GdbMacrosBuildStep *gdbmacrostep = new GdbMacrosBuildStep(this);
624 insertBuildStep(0, gdbmacrostep);
626 GdbMacrosBuildStep *gdbmacrosCleanStep = new GdbMacrosBuildStep(this);
627 gdbmacrosCleanStep ->setValue("clean", true);
628 insertCleanStep(0, gdbmacrosCleanStep );
629 break;
633 foreach(const QString &bc, buildConfigurations()) {
634 setValue(bc, "addQDumper", QVariant());
639 void Qt4Project::newBuildConfiguration(const QString &buildConfiguration)
641 Q_UNUSED(buildConfiguration);
644 void Qt4Project::proFileParseError(const QString &errorMessage)
646 m_manager->core()->messageManager()->printToOutputPane(errorMessage);
649 Qt4ProFileNode *Qt4Project::rootProjectNode() const
651 return m_rootProjectNode;
654 ProjectExplorer::Environment Qt4Project::baseEnvironment(const QString &buildConfiguration) const
656 Environment env = useSystemEnvironment(buildConfiguration) ? Environment(QProcess::systemEnvironment()) : Environment();
657 env = qtVersion(buildConfiguration)->addToEnvironment(env);
658 return env;
661 ProjectExplorer::Environment Qt4Project::environment(const QString &buildConfiguration) const
663 Environment env = baseEnvironment(buildConfiguration);
664 env.modify(userEnvironmentChanges(buildConfiguration));
665 return env;
668 QString Qt4Project::buildDirectory(const QString &buildConfiguration) const
670 QString workingDirectory;
671 if (value(buildConfiguration, "useShadowBuild").toBool())
672 workingDirectory = value(buildConfiguration, "buildDirectory").toString();
673 if (workingDirectory.isEmpty())
674 workingDirectory = QFileInfo(file()->fileName()).absolutePath();
675 return workingDirectory;
678 void Qt4Project::setUseSystemEnvironment(const QString &buildConfiguration, bool b)
680 setValue(buildConfiguration, "clearSystemEnvironment", !b);
683 bool Qt4Project::useSystemEnvironment(const QString &buildConfiguration) const
685 bool b = !(value(buildConfiguration, "clearSystemEnvironment").isValid() && value(buildConfiguration, "clearSystemEnvironment").toBool());
686 return b;
689 QString Qt4Project::qtDir(const QString &buildConfiguration) const
691 QtVersion *version = qtVersion(buildConfiguration);
692 if (version)
693 return version->path();
694 return QString::null;
697 QtVersion *Qt4Project::qtVersion(const QString &buildConfiguration) const
699 return m_manager->versionManager()->version(qtVersionId(buildConfiguration));
702 int Qt4Project::qtVersionId(const QString &buildConfiguration) const
704 if (debug)
705 qDebug()<<"Looking for qtVersion ID of "<<buildConfiguration;
706 int id = 0;
707 QVariant vid = value(buildConfiguration, "QtVersionId");
708 if (vid.isValid()) {
709 id = vid.toInt();
710 if (m_manager->versionManager()->version(id)->isValid()) {
711 return id;
712 } else {
713 const_cast<Qt4Project *>(this)->setValue(buildConfiguration, "QtVersionId", 0);
714 return 0;
716 } else {
717 // Backward compatibilty, we might have just the name:
718 QString vname = value(buildConfiguration, "QtVersion").toString();
719 if (debug)
720 qDebug()<<" Backward compatibility reading QtVersion"<<vname;
721 if (!vname.isEmpty()) {
722 const QList<QtVersion *> &versions = m_manager->versionManager()->versions();
723 foreach (const QtVersion * const version, versions) {
724 if (version->name() == vname) {
725 if (debug)
726 qDebug()<<"found name in versions";
727 const_cast<Qt4Project *>(this)->setValue(buildConfiguration, "QtVersionId", version->uniqueId());
728 return version->uniqueId();
733 if (debug)
734 qDebug()<<" using qtversion with id ="<<id;
735 // Nothing found, reset to default
736 const_cast<Qt4Project *>(this)->setValue(buildConfiguration, "QtVersionId", id);
737 return id;
740 void Qt4Project::setQtVersion(const QString &buildConfiguration, int id)
742 setValue(buildConfiguration, "QtVersionId", id);
745 BuildStepConfigWidget *Qt4Project::createConfigWidget()
747 return new Qt4BuildConfigWidget(this);
750 QList<BuildStepConfigWidget*> Qt4Project::subConfigWidgets()
752 QList<BuildStepConfigWidget*> subWidgets;
753 subWidgets << new Qt4BuildEnvironmentWidget(this);
754 return subWidgets;
757 QList<ProjectExplorer::EnvironmentItem> Qt4Project::userEnvironmentChanges(const QString &buildConfig) const
759 return EnvironmentItem::fromStringList(value(buildConfig, "userEnvironmentChanges").toStringList());
762 void Qt4Project::setUserEnvironmentChanges(const QString &buildConfig, const QList<ProjectExplorer::EnvironmentItem> &diff)
764 setValue(buildConfig, "userEnvironmentChanges", EnvironmentItem::toStringList(diff));
767 /// **************************
768 /// Qt4ProjectBuildConfigWidget
769 /// **************************
772 void Qt4Project::collectApplicationProFiles(QList<Qt4ProFileNode *> &list, Qt4ProFileNode *node)
774 if (node->projectType() == Internal::ApplicationTemplate
775 || node->projectType() == Internal::ScriptTemplate) {
776 list.append(node);
778 foreach (ProjectNode *n, node->subProjectNodes()) {
779 Qt4ProFileNode *qt4ProFileNode = qobject_cast<Qt4ProFileNode *>(n);
780 if (qt4ProFileNode)
781 collectApplicationProFiles(list, qt4ProFileNode);
785 void Qt4Project::foldersAboutToBeAdded(FolderNode *, const QList<FolderNode*> &nodes)
787 QList<Qt4ProFileNode *> list;
788 foreach (FolderNode *node, nodes) {
789 Qt4ProFileNode *qt4ProFileNode = qobject_cast<Qt4ProFileNode *>(node);
790 if (qt4ProFileNode)
791 collectApplicationProFiles(list, qt4ProFileNode);
793 m_applicationProFileChange = list;
796 void Qt4Project::checkForNewApplicationProjects()
798 // Check all new project nodes
799 // against all runConfigurations
801 foreach (Qt4ProFileNode *qt4proFile, m_applicationProFileChange) {
802 bool found = false;
803 foreach (QSharedPointer<RunConfiguration> rc, runConfigurations()) {
804 QSharedPointer<Qt4RunConfiguration> qtrc = rc.dynamicCast<Qt4RunConfiguration>();
805 if (qtrc && qtrc->proFilePath() == qt4proFile->path()) {
806 found = true;
807 break;
810 if (!found) {
811 QSharedPointer<Qt4RunConfiguration> newRc(new Qt4RunConfiguration(this, qt4proFile->path()));
812 addRunConfiguration(newRc);
813 m_isApplication = true;
818 void Qt4Project::checkForDeletedApplicationProjects()
820 QStringList paths;
821 foreach (Qt4ProFileNode * node, applicationProFiles())
822 paths.append(node->path());
824 qDebug()<<"Still existing paths :"<<paths;
826 QList<QSharedPointer<Qt4RunConfiguration> > removeList;
827 foreach (QSharedPointer<RunConfiguration> rc, runConfigurations()) {
828 if (QSharedPointer<Qt4RunConfiguration> qt4rc = rc.dynamicCast<Qt4RunConfiguration>()) {
829 if (!paths.contains(qt4rc->proFilePath())) {
830 removeList.append(qt4rc);
831 qDebug()<<"Removing runConfiguration for "<<qt4rc->proFilePath();
836 bool resetActiveRunConfiguration = false;
837 QSharedPointer<RunConfiguration> rc(new ProjectExplorer::CustomExecutableRunConfiguration(this));
838 foreach (QSharedPointer<Qt4RunConfiguration> qt4rc, removeList) {
839 removeRunConfiguration(qt4rc);
840 if (activeRunConfiguration() == qt4rc)
841 resetActiveRunConfiguration = true;
844 if (runConfigurations().isEmpty()) {
845 QSharedPointer<RunConfiguration> rc(new ProjectExplorer::CustomExecutableRunConfiguration(this));
846 addRunConfiguration(rc);
847 setActiveRunConfiguration(rc);
848 m_isApplication = false;
849 } else if (resetActiveRunConfiguration) {
850 setActiveRunConfiguration(runConfigurations().first());
854 QList<Qt4ProFileNode *> Qt4Project::applicationProFiles() const
856 QList<Qt4ProFileNode *> list;
857 collectApplicationProFiles(list, rootProjectNode());
858 return list;
861 void Qt4Project::projectTypeChanged(Qt4ProFileNode *node, const Qt4ProjectType oldType, const Qt4ProjectType newType)
863 if (oldType == Internal::ApplicationTemplate
864 || oldType == Internal::ScriptTemplate) {
865 // check wheter we need to delete a Run Configuration
866 checkForDeletedApplicationProjects();
869 if (newType == Internal::ApplicationTemplate
870 || newType == Internal::ScriptTemplate) {
871 // add a new Run Configuration
872 m_applicationProFileChange.clear();
873 m_applicationProFileChange.append(node);
874 checkForNewApplicationProjects();
878 void Qt4Project::proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *node)
880 foreach (QSharedPointer<RunConfiguration> rc, runConfigurations()) {
881 if (QSharedPointer<Qt4RunConfiguration> qt4rc = rc.dynamicCast<Qt4RunConfiguration>()) {
882 if (qt4rc->proFilePath() == node->path()) {
883 qt4rc->updateCachedValues();
890 QMakeStep *Qt4Project::qmakeStep() const
892 QMakeStep *qs = 0;
893 foreach(BuildStep *bs, buildSteps())
894 if ( (qs = qobject_cast<QMakeStep *>(bs)) != 0)
895 return qs;
896 return 0;
899 MakeStep *Qt4Project::makeStep() const
901 MakeStep *qs = 0;
902 foreach(BuildStep *bs, buildSteps())
903 if ((qs = qobject_cast<MakeStep *>(bs)) != 0)
904 return qs;
905 return 0;
908 bool Qt4Project::hasSubNode(Qt4PriFileNode *root, const QString &path)
910 if (root->path() == path)
911 return true;
912 foreach (FolderNode *fn, root->subFolderNodes()) {
913 if (qobject_cast<Qt4ProFileNode *>(fn)) {
914 // we aren't interested in pro file nodes
915 } else if (Qt4PriFileNode *qt4prifilenode = qobject_cast<Qt4PriFileNode *>(fn)) {
916 if (hasSubNode(qt4prifilenode, path))
917 return true;
920 return false;
923 void Qt4Project::findProFile(const QString& fileName, Qt4ProFileNode *root, QList<Qt4ProFileNode *> &list)
925 if (hasSubNode(root, fileName))
926 list.append(root);
928 foreach (FolderNode *fn, root->subFolderNodes())
929 if (Qt4ProFileNode *qt4proFileNode = qobject_cast<Qt4ProFileNode *>(fn))
930 findProFile(fileName, qt4proFileNode, list);
933 void Qt4Project::notifyChanged(const QString &name)
935 if (files(Qt4Project::ExcludeGeneratedFiles).contains(name)) {
936 QList<Qt4ProFileNode *> list;
937 findProFile(name, rootProjectNode(), list);
938 foreach(Qt4ProFileNode *node, list)
939 node->update();