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/icore.h>
52 #include <coreplugin/messagemanager.h>
53 #include <coreplugin/coreconstants.h>
54 #include <cpptools/cppmodelmanagerinterface.h>
55 #include <extensionsystem/pluginmanager.h>
56 #include <projectexplorer/nodesvisitor.h>
57 #include <projectexplorer/project.h>
58 #include <projectexplorer/customexecutablerunconfiguration.h>
60 #include <QtCore/QDebug>
61 #include <QtCore/QDir>
62 #include <QtGui/QFileDialog>
64 using namespace Qt4ProjectManager
;
65 using namespace Qt4ProjectManager::Internal
;
66 using namespace ProjectExplorer
;
70 namespace Qt4ProjectManager
{
73 // Qt4ProjectFiles: Struct for (Cached) lists of files in a project
74 struct Qt4ProjectFiles
{
76 bool equals(const Qt4ProjectFiles
&f
) const;
78 QStringList files
[ProjectExplorer::FileTypeSize
];
79 QStringList generatedFiles
[ProjectExplorer::FileTypeSize
];
83 void Qt4ProjectFiles::clear()
85 for (int i
= 0; i
< FileTypeSize
; ++i
) {
87 generatedFiles
[i
].clear();
92 bool Qt4ProjectFiles::equals(const Qt4ProjectFiles
&f
) const
94 for (int i
= 0; i
< FileTypeSize
; ++i
)
95 if (files
[i
] != f
.files
[i
] || generatedFiles
[i
] != f
.generatedFiles
[i
])
97 if (proFiles
!= f
.proFiles
)
102 inline bool operator==(const Qt4ProjectFiles
&f1
, const Qt4ProjectFiles
&f2
)
103 { return f1
.equals(f2
); }
105 inline bool operator!=(const Qt4ProjectFiles
&f1
, const Qt4ProjectFiles
&f2
)
106 { return !f1
.equals(f2
); }
108 QDebug
operator<<(QDebug d
, const Qt4ProjectFiles
&f
)
110 QDebug nsp
= d
.nospace();
111 nsp
<< "Qt4ProjectFiles: proFiles=" << f
.proFiles
<< '\n';
112 for (int i
= 0; i
< FileTypeSize
; ++i
)
113 nsp
<< "Type " << i
<< " files=" << f
.files
[i
] << " generated=" << f
.generatedFiles
[i
] << '\n';
117 // A visitor to collect all files of a project in a Qt4ProjectFiles struct
118 class ProjectFilesVisitor
: public ProjectExplorer::NodesVisitor
120 Q_DISABLE_COPY(ProjectFilesVisitor
)
121 ProjectFilesVisitor(Qt4ProjectFiles
*files
);
124 static void findProjectFiles(Qt4ProFileNode
*rootNode
, Qt4ProjectFiles
*files
);
126 void visitProjectNode(ProjectNode
*projectNode
);
127 void visitFolderNode(FolderNode
*folderNode
);
130 Qt4ProjectFiles
*m_files
;
133 ProjectFilesVisitor::ProjectFilesVisitor(Qt4ProjectFiles
*files
) :
138 void ProjectFilesVisitor::findProjectFiles(Qt4ProFileNode
*rootNode
, Qt4ProjectFiles
*files
)
141 ProjectFilesVisitor
visitor(files
);
142 rootNode
->accept(&visitor
);
143 for (int i
= 0; i
< FileTypeSize
; ++i
) {
144 qSort(files
->files
[i
]);
145 qSort(files
->generatedFiles
[i
]);
147 qSort(files
->proFiles
);
150 void ProjectFilesVisitor::visitProjectNode(ProjectNode
*projectNode
)
152 const QString path
= projectNode
->path();
153 if (!m_files
->proFiles
.contains(path
))
154 m_files
->proFiles
.append(path
);
155 visitFolderNode(projectNode
);
158 void ProjectFilesVisitor::visitFolderNode(FolderNode
*folderNode
)
160 foreach (FileNode
*fileNode
, folderNode
->fileNodes()) {
161 const QString path
= fileNode
->path();
162 const int type
= fileNode
->fileType();
163 QStringList
&targetList
= fileNode
->isGenerated() ? m_files
->generatedFiles
[type
] : m_files
->files
[type
];
164 if (!targetList
.contains(path
))
165 targetList
.push_back(path
);
172 // ----------- Qt4ProjectFile
173 Qt4ProjectFile::Qt4ProjectFile(Qt4Project
*project
, const QString
&filePath
, QObject
*parent
)
174 : Core::IFile(parent
),
175 m_mimeType(QLatin1String(Qt4ProjectManager::Constants::PROFILE_MIMETYPE
)),
181 bool Qt4ProjectFile::save(const QString
&)
183 // This is never used
187 QString
Qt4ProjectFile::fileName() const
192 QString
Qt4ProjectFile::defaultPath() const
197 QString
Qt4ProjectFile::suggestedFileName() const
202 QString
Qt4ProjectFile::mimeType() const
207 bool Qt4ProjectFile::isModified() const
209 return false; // we save after changing anyway
212 bool Qt4ProjectFile::isReadOnly() const
214 QFileInfo
fi(m_filePath
);
215 return !fi
.isWritable();
218 bool Qt4ProjectFile::isSaveAsAllowed() const
223 void Qt4ProjectFile::modified(Core::IFile::ReloadBehavior
*)
230 Qt4Project manages information about an individual Qt 4 (.pro) project file.
233 Qt4Project::Qt4Project(Qt4Manager
*manager
, const QString
& fileName
) :
235 m_rootProjectNode(new Qt4ProFileNode(this, fileName
, this)),
236 m_nodesWatcher(new Internal::Qt4NodesWatcher(this)),
237 m_fileInfo(new Qt4ProjectFile(this, fileName
, this)),
238 m_isApplication(true),
239 m_projectFiles(new Qt4ProjectFiles
)
241 m_manager
->registerProject(this);
242 m_rootProjectNode
->registerWatcher(m_nodesWatcher
);
243 connect(m_nodesWatcher
, SIGNAL(foldersAdded()), this, SLOT(updateFileList()));
244 connect(m_nodesWatcher
, SIGNAL(foldersRemoved()), this, SLOT(updateFileList()));
245 connect(m_nodesWatcher
, SIGNAL(filesAdded()), this, SLOT(updateFileList()));
246 connect(m_nodesWatcher
, SIGNAL(filesRemoved()), this, SLOT(updateFileList()));
247 connect(m_nodesWatcher
, SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode
*)),
248 this, SLOT(scheduleUpdateCodeModel()));
250 connect(qt4ProjectManager()->versionManager(), SIGNAL(defaultQtVersionChanged()),
251 this, SLOT(defaultQtVersionChanged()));
252 connect(qt4ProjectManager()->versionManager(), SIGNAL(qtVersionsChanged()),
253 this, SLOT(qtVersionsChanged()));
255 m_updateCodeModelTimer
.setSingleShot(true);
256 m_updateCodeModelTimer
.setInterval(20);
257 connect(&m_updateCodeModelTimer
, SIGNAL(timeout()), this, SLOT(updateCodeModel()));
259 m_addUiFilesTimer
.setSingleShot(true);
260 m_addUiFilesTimer
.setInterval(20);
261 connect(&m_addUiFilesTimer
, SIGNAL(timeout()), this, SLOT(addUiFiles()));
264 Qt4Project::~Qt4Project()
266 m_manager
->unregisterProject(this);
267 delete m_projectFiles
;
270 void Qt4Project::defaultQtVersionChanged()
272 if (qtVersionId(activeBuildConfiguration()) == 0)
273 m_rootProjectNode
->update();
276 void Qt4Project::qtVersionsChanged()
278 foreach (QString bc
, buildConfigurations()) {
279 if (!qt4ProjectManager()->versionManager()->version(qtVersionId(bc
))->isValid()) {
281 if (bc
== activeBuildConfiguration())
282 m_rootProjectNode
->update();
287 void Qt4Project::updateFileList()
289 Qt4ProjectFiles newFiles
;
290 ProjectFilesVisitor::findProjectFiles(m_rootProjectNode
, &newFiles
);
291 if (newFiles
!= *m_projectFiles
) {
292 *m_projectFiles
= newFiles
;
293 emit
fileListChanged();
295 qDebug() << Q_FUNC_INFO
<< *m_projectFiles
;
299 void Qt4Project::restoreSettingsImpl(PersistentSettingsReader
&settingsReader
)
301 Project::restoreSettingsImpl(settingsReader
);
305 // Ensure that the qt version in each build configuration is valid
306 // or if not, is reset to the default
307 foreach (const QString
&bc
, buildConfigurations())
312 // restored old runconfigurations
313 if (runConfigurations().isEmpty()) {
314 // Oha no runConfigurations, add some
315 QList
<Qt4ProFileNode
*> list
;
316 collectApplicationProFiles(list
, m_rootProjectNode
);
318 if (!list
.isEmpty()) {
319 foreach (Qt4ProFileNode
*node
, list
) {
320 QSharedPointer
<RunConfiguration
> rc(new Qt4RunConfiguration(this, node
->path()));
321 addRunConfiguration(rc
);
323 setActiveRunConfiguration(runConfigurations().first());
325 QSharedPointer
<RunConfiguration
> rc(new ProjectExplorer::CustomExecutableRunConfiguration(this));
326 addRunConfiguration(rc
);
327 setActiveRunConfiguration(rc
);
328 m_isApplication
= false;
333 connect(m_nodesWatcher
, SIGNAL(foldersAboutToBeAdded(FolderNode
*, const QList
<FolderNode
*> &)),
334 this, SLOT(foldersAboutToBeAdded(FolderNode
*, const QList
<FolderNode
*> &)));
335 connect(m_nodesWatcher
, SIGNAL(foldersAdded()), this, SLOT(checkForNewApplicationProjects()));
337 connect(m_nodesWatcher
, SIGNAL(foldersRemoved()), this, SLOT(checkForDeletedApplicationProjects()));
339 connect(m_nodesWatcher
, SIGNAL(projectTypeChanged(Qt4ProjectManager::Internal::Qt4ProFileNode
*,
340 const Qt4ProjectManager::Internal::Qt4ProjectType
,
341 const Qt4ProjectManager::Internal::Qt4ProjectType
)),
342 this, SLOT(projectTypeChanged(Qt4ProjectManager::Internal::Qt4ProFileNode
*,
343 const Qt4ProjectManager::Internal::Qt4ProjectType
,
344 const Qt4ProjectManager::Internal::Qt4ProjectType
)));
346 connect(m_nodesWatcher
, SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode
*)),
347 this, SLOT(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode
*)));
351 void Qt4Project::saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter
&writer
)
353 Project::saveSettingsImpl(writer
);
357 class FindQt4ProFiles
: protected ProjectExplorer::NodesVisitor
{
358 QList
<Qt4ProFileNode
*> m_proFiles
;
361 QList
<Qt4ProFileNode
*> operator()(ProjectNode
*root
)
369 virtual void visitProjectNode(ProjectNode
*projectNode
)
371 if (Qt4ProFileNode
*pro
= qobject_cast
<Qt4ProFileNode
*>(projectNode
))
372 m_proFiles
.append(pro
);
377 void Qt4Project::addUiFilesToCodeModel(const QStringList
&files
)
379 // if we already have a full updateCodeModel() scheduled
380 // then we don't need to this seperately
381 // since that one will add also all the ui files
382 if (m_updateCodeModelTimer
.isActive())
384 m_addUiFilesTimer
.start();
385 m_uiFilesToAdd
<< files
;
388 void Qt4Project::addUiFiles()
390 if (m_updateCodeModelTimer
.isActive())
392 CppTools::CppModelManagerInterface
*modelManager
=
393 ExtensionSystem::PluginManager::instance()->getObject
<CppTools::CppModelManagerInterface
>();
394 modelManager
->updateSourceFiles(m_uiFilesToAdd
);
395 m_uiFilesToAdd
.clear();
398 void Qt4Project::scheduleUpdateCodeModel()
400 m_updateCodeModelTimer
.start();
403 void Qt4Project::updateCodeModel()
406 qDebug()<<"Qt4Project::updateCodeModel()";
408 CppTools::CppModelManagerInterface
*modelmanager
=
409 ExtensionSystem::PluginManager::instance()
410 ->getObject
<CppTools::CppModelManagerInterface
>();
415 QStringList allIncludePaths
;
416 QStringList allFrameworkPaths
;
418 const QHash
<QString
, QString
> versionInfo
= qtVersion(activeBuildConfiguration())->versionInfo();
419 const QString newQtIncludePath
= versionInfo
.value(QLatin1String("QT_INSTALL_HEADERS"));
420 const QString newQtLibsPath
= versionInfo
.value(QLatin1String("QT_INSTALL_LIBS"));
422 QByteArray predefinedMacros
;
423 QtVersion::ToolchainType t
= qtVersion(activeBuildConfiguration())->toolchainType();
424 if (t
== QtVersion::MinGW
|| t
== QtVersion::OTHER
) {
425 QStringList list
= rootProjectNode()->variableValue(Internal::CxxCompilerVar
);
426 QString qmake_cxx
= list
.isEmpty() ? QString::null
: list
.first();
427 qmake_cxx
= environment(activeBuildConfiguration()).searchInPath(qmake_cxx
);
428 m_preproc
.setGcc(qmake_cxx
);
429 predefinedMacros
= m_preproc
.predefinedMacros();
430 foreach (HeaderPath headerPath
, m_preproc
.systemHeaderPaths()) {
431 if (headerPath
.kind() == HeaderPath::FrameworkHeaderPath
)
432 allFrameworkPaths
.append(headerPath
.path());
434 allIncludePaths
.append(headerPath
.path());
437 } else if (t
== QtVersion::MSVC
|| t
== QtVersion::WINCE
) {
438 #ifdef QTCREATOR_WITH_MSVC_INCLUDES
439 Environment env
= environment(activeBuildConfiguration());
440 allIncludePaths
.append(env
.value("INCLUDE").split(QLatin1Char(';')));
443 "#define __WIN32__\n"
447 "#define __WINNT__\n"
451 "#define __MSVCRT__\n";
454 allIncludePaths
.append(newQtIncludePath
);
456 QDir
dir(newQtIncludePath
);
457 foreach (QFileInfo info
, dir
.entryInfoList(QDir::Dirs
)) {
458 if (! info
.fileName().startsWith(QLatin1String("Qt")))
460 allIncludePaths
.append(info
.absoluteFilePath());
464 allFrameworkPaths
.append(newQtLibsPath
);
465 // put QtXXX.framework/Headers directories in include path since that qmake's behavior
466 QDir
frameworkDir(newQtLibsPath
);
467 foreach (QFileInfo info
, frameworkDir
.entryInfoList(QDir::Dirs
)) {
468 if (! info
.fileName().startsWith(QLatin1String("Qt")))
470 allIncludePaths
.append(info
.absoluteFilePath()+"/Headers");
474 FindQt4ProFiles findQt4ProFiles
;
475 QList
<Qt4ProFileNode
*> proFiles
= findQt4ProFiles(rootProjectNode());
476 QByteArray definedMacros
;
478 foreach (Qt4ProFileNode
*pro
, proFiles
) {
479 foreach (const QString def
, pro
->variableValue(DefinesVar
)) {
480 definedMacros
+= "#define ";
481 const int index
= def
.indexOf(QLatin1Char('='));
483 definedMacros
+= def
.toLatin1();
484 definedMacros
+= " 1\n";
486 const QString name
= def
.left(index
);
487 const QString value
= def
.mid(index
+ 1);
488 definedMacros
+= name
.toLatin1();
489 definedMacros
+= ' ';
490 definedMacros
+= value
.toLocal8Bit();
491 definedMacros
+= '\n';
495 const QStringList proIncludePaths
= pro
->variableValue(IncludePathVar
);
496 foreach (QString includePath
, proIncludePaths
) {
497 if (allIncludePaths
.contains(includePath
))
500 allIncludePaths
.append(includePath
);
504 // Add mkspec directory
505 allIncludePaths
.append(qtVersion(activeBuildConfiguration())->mkspecPath());
508 files
+= m_projectFiles
->files
[HeaderType
];
509 files
+= m_projectFiles
->generatedFiles
[HeaderType
];
510 files
+= m_projectFiles
->files
[SourceType
];
511 files
+= m_projectFiles
->generatedFiles
[SourceType
];
513 CppTools::CppModelManagerInterface::ProjectInfo pinfo
= modelmanager
->projectInfo(this);
515 if (pinfo
.defines
== predefinedMacros
&&
516 pinfo
.includePaths
== allIncludePaths
&&
517 pinfo
.frameworkPaths
== allFrameworkPaths
&&
518 pinfo
.sourceFiles
== files
) {
519 modelmanager
->updateProjectInfo(pinfo
);
521 pinfo
.defines
= predefinedMacros
;
522 // pinfo->defines += definedMacros; // ### FIXME: me
523 pinfo
.includePaths
= allIncludePaths
;
524 pinfo
.frameworkPaths
= allFrameworkPaths
;
525 pinfo
.sourceFiles
= files
;
527 modelmanager
->updateProjectInfo(pinfo
);
528 modelmanager
->updateSourceFiles(pinfo
.sourceFiles
);
534 // Updates complete project
536 void Qt4Project::update()
538 // TODO Maybe remove this method completely?
539 m_rootProjectNode
->update();
543 ProFileReader
*Qt4Project::createProFileReader() const
545 ProFileReader
*reader
= new ProFileReader();
546 connect(reader
, SIGNAL(errorFound(const QString
&)),
547 this, SLOT(proFileParseError(const QString
&)));
548 QtVersion
*version
= qtVersion(activeBuildConfiguration());
549 if (version
->isValid()) {
550 reader
->setQtVersion(version
);
556 Returns whether the project is an application, or has an application as a subproject.
558 bool Qt4Project::isApplication() const
560 return m_isApplication
;
563 ProjectExplorer::ProjectExplorerPlugin
*Qt4Project::projectExplorer() const
565 return m_manager
->projectExplorer();
568 ProjectExplorer::IProjectManager
*Qt4Project::projectManager() const
573 Qt4Manager
*Qt4Project::qt4ProjectManager() const
578 QString
Qt4Project::name() const
580 return QFileInfo(file()->fileName()).completeBaseName();
583 Core::IFile
*Qt4Project::file() const
588 QStringList
Qt4Project::files(FilesMode fileMode
) const
591 for (int i
= 0; i
< FileTypeSize
; ++i
) {
592 files
+= m_projectFiles
->files
[i
];
593 if (fileMode
== AllFiles
)
594 files
+= m_projectFiles
->generatedFiles
[i
];
599 QList
<ProjectExplorer::Project
*> Qt4Project::dependsOn()
601 // NBS implement dependsOn
602 return QList
<Project
*>();
605 void Qt4Project::addDefaultBuild()
607 if (buildConfigurations().isEmpty()) {
608 // We don't have any buildconfigurations, so this is a new project
609 // The Project Load Wizard is a work of art
610 // It will ask the user what kind of build setup he want
611 // It will add missing Qt Versions
612 // And get the project into a buildable state
614 //TODO have a better check wheter there is already a configuration?
615 QMakeStep
*qmakeStep
= 0;
616 MakeStep
*makeStep
= 0;
617 GdbMacrosBuildStep
*gdbmacrostep
;
619 gdbmacrostep
= new GdbMacrosBuildStep(this);
620 insertBuildStep(0, gdbmacrostep
);
622 qmakeStep
= new QMakeStep(this);
623 qmakeStep
->setValue("mkspec", "");
624 insertBuildStep(1, qmakeStep
);
626 makeStep
= new MakeStep(this);
627 insertBuildStep(2, makeStep
);
629 GdbMacrosBuildStep
*gdbmacrosCleanStep
= new GdbMacrosBuildStep(this);
630 gdbmacrosCleanStep
->setValue("clean", true);
631 insertCleanStep(0, gdbmacrosCleanStep
);
633 MakeStep
* cleanStep
= new MakeStep(this);
634 cleanStep
->setValue("clean", true);
635 insertCleanStep(1, cleanStep
);
637 ProjectLoadWizard
wizard(this);
640 // Restoring configuration
641 // Do we already have a gdbmacrobuildstep?
642 // If not add it and disable linking of debugging helper
644 // Check for old link debugging helper setting in each buildConfiguration
645 // We add a gdbmacrosbuildstep if at least one has it
646 // TODO remove migration code from pre beta
647 foreach(const QString
&bc
, buildConfigurations()) {
648 QVariant v
= value(bc
, "addQDumper");
649 if (v
.isValid() && v
.toBool()) {
650 GdbMacrosBuildStep
*gdbmacrostep
= new GdbMacrosBuildStep(this);
651 insertBuildStep(0, gdbmacrostep
);
653 GdbMacrosBuildStep
*gdbmacrosCleanStep
= new GdbMacrosBuildStep(this);
654 gdbmacrosCleanStep
->setValue("clean", true);
655 insertCleanStep(0, gdbmacrosCleanStep
);
660 foreach(const QString
&bc
, buildConfigurations()) {
661 setValue(bc
, "addQDumper", QVariant());
666 void Qt4Project::newBuildConfiguration(const QString
&buildConfiguration
)
668 Q_UNUSED(buildConfiguration
);
671 void Qt4Project::proFileParseError(const QString
&errorMessage
)
673 Core::ICore::instance()->messageManager()->printToOutputPane(errorMessage
);
676 Qt4ProFileNode
*Qt4Project::rootProjectNode() const
678 return m_rootProjectNode
;
681 ProjectExplorer::Environment
Qt4Project::baseEnvironment(const QString
&buildConfiguration
) const
683 Environment env
= useSystemEnvironment(buildConfiguration
) ? Environment(QProcess::systemEnvironment()) : Environment();
684 env
= qtVersion(buildConfiguration
)->addToEnvironment(env
);
688 ProjectExplorer::Environment
Qt4Project::environment(const QString
&buildConfiguration
) const
690 Environment env
= baseEnvironment(buildConfiguration
);
691 env
.modify(userEnvironmentChanges(buildConfiguration
));
695 QString
Qt4Project::buildDirectory(const QString
&buildConfiguration
) const
697 QString workingDirectory
;
698 if (value(buildConfiguration
, "useShadowBuild").toBool())
699 workingDirectory
= value(buildConfiguration
, "buildDirectory").toString();
700 if (workingDirectory
.isEmpty())
701 workingDirectory
= QFileInfo(file()->fileName()).absolutePath();
702 return workingDirectory
;
705 void Qt4Project::setUseSystemEnvironment(const QString
&buildConfiguration
, bool b
)
707 setValue(buildConfiguration
, "clearSystemEnvironment", !b
);
710 bool Qt4Project::useSystemEnvironment(const QString
&buildConfiguration
) const
712 bool b
= !(value(buildConfiguration
, "clearSystemEnvironment").isValid() && value(buildConfiguration
, "clearSystemEnvironment").toBool());
716 QString
Qt4Project::qtDir(const QString
&buildConfiguration
) const
718 QtVersion
*version
= qtVersion(buildConfiguration
);
720 return version
->path();
721 return QString::null
;
724 QtVersion
*Qt4Project::qtVersion(const QString
&buildConfiguration
) const
726 return m_manager
->versionManager()->version(qtVersionId(buildConfiguration
));
729 int Qt4Project::qtVersionId(const QString
&buildConfiguration
) const
732 qDebug()<<"Looking for qtVersion ID of "<<buildConfiguration
;
734 QVariant vid
= value(buildConfiguration
, "QtVersionId");
737 if (m_manager
->versionManager()->version(id
)->isValid()) {
740 const_cast<Qt4Project
*>(this)->setValue(buildConfiguration
, "QtVersionId", 0);
744 // Backward compatibilty, we might have just the name:
745 QString vname
= value(buildConfiguration
, "QtVersion").toString();
747 qDebug()<<" Backward compatibility reading QtVersion"<<vname
;
748 if (!vname
.isEmpty()) {
749 const QList
<QtVersion
*> &versions
= m_manager
->versionManager()->versions();
750 foreach (const QtVersion
* const version
, versions
) {
751 if (version
->name() == vname
) {
753 qDebug()<<"found name in versions";
754 const_cast<Qt4Project
*>(this)->setValue(buildConfiguration
, "QtVersionId", version
->uniqueId());
755 return version
->uniqueId();
761 qDebug()<<" using qtversion with id ="<<id
;
762 // Nothing found, reset to default
763 const_cast<Qt4Project
*>(this)->setValue(buildConfiguration
, "QtVersionId", id
);
767 void Qt4Project::setQtVersion(const QString
&buildConfiguration
, int id
)
769 setValue(buildConfiguration
, "QtVersionId", id
);
772 BuildStepConfigWidget
*Qt4Project::createConfigWidget()
774 return new Qt4BuildConfigWidget(this);
777 QList
<BuildStepConfigWidget
*> Qt4Project::subConfigWidgets()
779 QList
<BuildStepConfigWidget
*> subWidgets
;
780 subWidgets
<< new Qt4BuildEnvironmentWidget(this);
784 QList
<ProjectExplorer::EnvironmentItem
> Qt4Project::userEnvironmentChanges(const QString
&buildConfig
) const
786 return EnvironmentItem::fromStringList(value(buildConfig
, "userEnvironmentChanges").toStringList());
789 void Qt4Project::setUserEnvironmentChanges(const QString
&buildConfig
, const QList
<ProjectExplorer::EnvironmentItem
> &diff
)
791 setValue(buildConfig
, "userEnvironmentChanges", EnvironmentItem::toStringList(diff
));
794 /// **************************
795 /// Qt4ProjectBuildConfigWidget
796 /// **************************
799 void Qt4Project::collectApplicationProFiles(QList
<Qt4ProFileNode
*> &list
, Qt4ProFileNode
*node
)
801 if (node
->projectType() == Internal::ApplicationTemplate
802 || node
->projectType() == Internal::ScriptTemplate
) {
805 foreach (ProjectNode
*n
, node
->subProjectNodes()) {
806 Qt4ProFileNode
*qt4ProFileNode
= qobject_cast
<Qt4ProFileNode
*>(n
);
808 collectApplicationProFiles(list
, qt4ProFileNode
);
812 void Qt4Project::foldersAboutToBeAdded(FolderNode
*, const QList
<FolderNode
*> &nodes
)
814 QList
<Qt4ProFileNode
*> list
;
815 foreach (FolderNode
*node
, nodes
) {
816 Qt4ProFileNode
*qt4ProFileNode
= qobject_cast
<Qt4ProFileNode
*>(node
);
818 collectApplicationProFiles(list
, qt4ProFileNode
);
820 m_applicationProFileChange
= list
;
823 void Qt4Project::checkForNewApplicationProjects()
825 // Check all new project nodes
826 // against all runConfigurations
828 foreach (Qt4ProFileNode
*qt4proFile
, m_applicationProFileChange
) {
830 foreach (QSharedPointer
<RunConfiguration
> rc
, runConfigurations()) {
831 QSharedPointer
<Qt4RunConfiguration
> qtrc
= rc
.dynamicCast
<Qt4RunConfiguration
>();
832 if (qtrc
&& qtrc
->proFilePath() == qt4proFile
->path()) {
838 QSharedPointer
<Qt4RunConfiguration
> newRc(new Qt4RunConfiguration(this, qt4proFile
->path()));
839 addRunConfiguration(newRc
);
840 m_isApplication
= true;
845 void Qt4Project::checkForDeletedApplicationProjects()
848 foreach (Qt4ProFileNode
* node
, applicationProFiles())
849 paths
.append(node
->path());
851 qDebug()<<"Still existing paths :"<<paths
;
853 QList
<QSharedPointer
<Qt4RunConfiguration
> > removeList
;
854 foreach (QSharedPointer
<RunConfiguration
> rc
, runConfigurations()) {
855 if (QSharedPointer
<Qt4RunConfiguration
> qt4rc
= rc
.dynamicCast
<Qt4RunConfiguration
>()) {
856 if (!paths
.contains(qt4rc
->proFilePath())) {
857 removeList
.append(qt4rc
);
858 qDebug()<<"Removing runConfiguration for "<<qt4rc
->proFilePath();
863 bool resetActiveRunConfiguration
= false;
864 QSharedPointer
<RunConfiguration
> rc(new ProjectExplorer::CustomExecutableRunConfiguration(this));
865 foreach (QSharedPointer
<Qt4RunConfiguration
> qt4rc
, removeList
) {
866 removeRunConfiguration(qt4rc
);
867 if (activeRunConfiguration() == qt4rc
)
868 resetActiveRunConfiguration
= true;
871 if (runConfigurations().isEmpty()) {
872 QSharedPointer
<RunConfiguration
> rc(new ProjectExplorer::CustomExecutableRunConfiguration(this));
873 addRunConfiguration(rc
);
874 setActiveRunConfiguration(rc
);
875 m_isApplication
= false;
876 } else if (resetActiveRunConfiguration
) {
877 setActiveRunConfiguration(runConfigurations().first());
881 QList
<Qt4ProFileNode
*> Qt4Project::applicationProFiles() const
883 QList
<Qt4ProFileNode
*> list
;
884 collectApplicationProFiles(list
, rootProjectNode());
888 void Qt4Project::projectTypeChanged(Qt4ProFileNode
*node
, const Qt4ProjectType oldType
, const Qt4ProjectType newType
)
890 if (oldType
== Internal::ApplicationTemplate
891 || oldType
== Internal::ScriptTemplate
) {
892 // check wheter we need to delete a Run Configuration
893 checkForDeletedApplicationProjects();
896 if (newType
== Internal::ApplicationTemplate
897 || newType
== Internal::ScriptTemplate
) {
898 // add a new Run Configuration
899 m_applicationProFileChange
.clear();
900 m_applicationProFileChange
.append(node
);
901 checkForNewApplicationProjects();
905 void Qt4Project::proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode
*node
)
907 foreach (QSharedPointer
<RunConfiguration
> rc
, runConfigurations()) {
908 if (QSharedPointer
<Qt4RunConfiguration
> qt4rc
= rc
.dynamicCast
<Qt4RunConfiguration
>()) {
909 if (qt4rc
->proFilePath() == node
->path()) {
910 qt4rc
->updateCachedValues();
917 QMakeStep
*Qt4Project::qmakeStep() const
920 foreach(BuildStep
*bs
, buildSteps())
921 if ( (qs
= qobject_cast
<QMakeStep
*>(bs
)) != 0)
926 MakeStep
*Qt4Project::makeStep() const
929 foreach(BuildStep
*bs
, buildSteps())
930 if ((qs
= qobject_cast
<MakeStep
*>(bs
)) != 0)
935 bool Qt4Project::hasSubNode(Qt4PriFileNode
*root
, const QString
&path
)
937 if (root
->path() == path
)
939 foreach (FolderNode
*fn
, root
->subFolderNodes()) {
940 if (qobject_cast
<Qt4ProFileNode
*>(fn
)) {
941 // we aren't interested in pro file nodes
942 } else if (Qt4PriFileNode
*qt4prifilenode
= qobject_cast
<Qt4PriFileNode
*>(fn
)) {
943 if (hasSubNode(qt4prifilenode
, path
))
950 void Qt4Project::findProFile(const QString
& fileName
, Qt4ProFileNode
*root
, QList
<Qt4ProFileNode
*> &list
)
952 if (hasSubNode(root
, fileName
))
955 foreach (FolderNode
*fn
, root
->subFolderNodes())
956 if (Qt4ProFileNode
*qt4proFileNode
= qobject_cast
<Qt4ProFileNode
*>(fn
))
957 findProFile(fileName
, qt4proFileNode
, list
);
960 void Qt4Project::notifyChanged(const QString
&name
)
962 if (files(Qt4Project::ExcludeGeneratedFiles
).contains(name
)) {
963 QList
<Qt4ProFileNode
*> list
;
964 findProFile(name
, rootProjectNode(), list
);
965 foreach(Qt4ProFileNode
*node
, list
)