1 /***************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Qt Software Information (qt-info@nokia.com)
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"
40 #include "qmakestep.h"
41 #include "deployhelper.h"
42 #include "qt4runconfiguration.h"
43 #include "qtversionmanager.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
;
69 namespace Qt4ProjectManager
{
72 // Qt4ProjectFiles: Struct for (Cached) lists of files in a project
73 struct Qt4ProjectFiles
{
75 bool equals(const Qt4ProjectFiles
&f
) const;
77 QStringList files
[ProjectExplorer::FileTypeSize
];
78 QStringList generatedFiles
[ProjectExplorer::FileTypeSize
];
82 void Qt4ProjectFiles::clear()
84 for (int i
= 0; i
< FileTypeSize
; ++i
) {
86 generatedFiles
[i
].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
])
96 if (proFiles
!= f
.proFiles
)
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';
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
);
123 static void findProjectFiles(Qt4ProFileNode
*rootNode
, Qt4ProjectFiles
*files
);
125 void visitProjectNode(ProjectNode
*projectNode
);
126 void visitFolderNode(FolderNode
*folderNode
);
129 Qt4ProjectFiles
*m_files
;
132 ProjectFilesVisitor::ProjectFilesVisitor(Qt4ProjectFiles
*files
) :
137 void ProjectFilesVisitor::findProjectFiles(Qt4ProFileNode
*rootNode
, Qt4ProjectFiles
*files
)
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
)),
180 bool Qt4ProjectFile::save(const QString
&)
182 // This is never used
186 QString
Qt4ProjectFile::fileName() const
191 QString
Qt4ProjectFile::defaultPath() const
196 QString
Qt4ProjectFile::suggestedFileName() const
201 QString
Qt4ProjectFile::mimeType() const
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
222 void Qt4ProjectFile::modified(Core::IFile::ReloadBehavior
*)
229 Qt4Project manages information about an individual Qt 4 (.pro) project file.
232 Qt4Project::Qt4Project(Qt4Manager
*manager
, const QString
& fileName
) :
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()) {
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();
290 qDebug() << Q_FUNC_INFO
<< *m_projectFiles
;
294 void Qt4Project::restoreSettingsImpl(PersistentSettingsReader
&settingsReader
)
296 Project::restoreSettingsImpl(settingsReader
);
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())
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());
320 QSharedPointer
<RunConfiguration
> rc(new ProjectExplorer::CustomExecutableRunConfiguration(this));
321 addRunConfiguration(rc
);
322 setActiveRunConfiguration(rc
);
323 m_isApplication
= false;
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
);
352 class FindQt4ProFiles
: protected ProjectExplorer::NodesVisitor
{
353 QList
<Qt4ProFileNode
*> m_proFiles
;
356 QList
<Qt4ProFileNode
*> operator()(ProjectNode
*root
)
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()
380 qDebug()<<"Qt4Project::updateCodeModel()";
382 CppTools::CppModelManagerInterface
*modelmanager
=
383 m_manager
->pluginManager()->getObject
<CppTools::CppModelManagerInterface
>();
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());
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(';')));
416 "#define __WIN32__\n"
420 "#define __WINNT__\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")))
433 allIncludePaths
.append(info
.absoluteFilePath());
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")))
443 allIncludePaths
.append(info
.absoluteFilePath()+"/Headers");
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('='));
456 definedMacros
+= def
.toLatin1();
457 definedMacros
+= " 1\n";
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
))
473 allIncludePaths
.append(includePath
);
477 // Add mkspec directory
478 allIncludePaths
.append(qtVersion(activeBuildConfiguration())->mkspecPath());
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
);
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
);
507 // Updates complete project
509 void Qt4Project::update()
511 // TODO Maybe remove this method completely?
512 m_rootProjectNode
->update();
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
);
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
546 Qt4Manager
*Qt4Project::qt4ProjectManager() const
551 QString
Qt4Project::name() const
553 return QFileInfo(file()->fileName()).completeBaseName();
556 Core::IFile
*Qt4Project::file() const
561 QStringList
Qt4Project::files(FilesMode fileMode
) const
564 for (int i
= 0; i
< FileTypeSize
; ++i
) {
565 files
+= m_projectFiles
->files
[i
];
566 if (fileMode
== AllFiles
)
567 files
+= m_projectFiles
->generatedFiles
[i
];
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);
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
);
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
);
661 ProjectExplorer::Environment
Qt4Project::environment(const QString
&buildConfiguration
) const
663 Environment env
= baseEnvironment(buildConfiguration
);
664 env
.modify(userEnvironmentChanges(buildConfiguration
));
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());
689 QString
Qt4Project::qtDir(const QString
&buildConfiguration
) const
691 QtVersion
*version
= qtVersion(buildConfiguration
);
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
705 qDebug()<<"Looking for qtVersion ID of "<<buildConfiguration
;
707 QVariant vid
= value(buildConfiguration
, "QtVersionId");
710 if (m_manager
->versionManager()->version(id
)->isValid()) {
713 const_cast<Qt4Project
*>(this)->setValue(buildConfiguration
, "QtVersionId", 0);
717 // Backward compatibilty, we might have just the name:
718 QString vname
= value(buildConfiguration
, "QtVersion").toString();
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
) {
726 qDebug()<<"found name in versions";
727 const_cast<Qt4Project
*>(this)->setValue(buildConfiguration
, "QtVersionId", version
->uniqueId());
728 return version
->uniqueId();
734 qDebug()<<" using qtversion with id ="<<id
;
735 // Nothing found, reset to default
736 const_cast<Qt4Project
*>(this)->setValue(buildConfiguration
, "QtVersionId", 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);
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
) {
778 foreach (ProjectNode
*n
, node
->subProjectNodes()) {
779 Qt4ProFileNode
*qt4ProFileNode
= qobject_cast
<Qt4ProFileNode
*>(n
);
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
);
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
) {
803 foreach (QSharedPointer
<RunConfiguration
> rc
, runConfigurations()) {
804 QSharedPointer
<Qt4RunConfiguration
> qtrc
= rc
.dynamicCast
<Qt4RunConfiguration
>();
805 if (qtrc
&& qtrc
->proFilePath() == qt4proFile
->path()) {
811 QSharedPointer
<Qt4RunConfiguration
> newRc(new Qt4RunConfiguration(this, qt4proFile
->path()));
812 addRunConfiguration(newRc
);
813 m_isApplication
= true;
818 void Qt4Project::checkForDeletedApplicationProjects()
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());
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
893 foreach(BuildStep
*bs
, buildSteps())
894 if ( (qs
= qobject_cast
<QMakeStep
*>(bs
)) != 0)
899 MakeStep
*Qt4Project::makeStep() const
902 foreach(BuildStep
*bs
, buildSteps())
903 if ((qs
= qobject_cast
<MakeStep
*>(bs
)) != 0)
908 bool Qt4Project::hasSubNode(Qt4PriFileNode
*root
, const QString
&path
)
910 if (root
->path() == path
)
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
))
923 void Qt4Project::findProFile(const QString
& fileName
, Qt4ProFileNode
*root
, QList
<Qt4ProFileNode
*> &list
)
925 if (hasSubNode(root
, fileName
))
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
)