aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/qt4projectmanager/qt4project.cpp
diff options
context:
space:
mode:
authorhjk <hjk121@nokiamail.com>2013-10-16 12:10:22 +0200
committerhjk <hjk121@nokiamail.com>2013-10-16 14:30:05 +0200
commit35695ebb0ca3abf8c3d8de1a70626225235ebb02 (patch)
treef58dfb7b36745512ca6abdf5050714f363ebd622 /src/plugins/qt4projectmanager/qt4project.cpp
parent710eea4a619baaf5402008fc901605d92bb31bc6 (diff)
Qt4ProjectManager: Rename the "normal" qt4* files to qmake*
Change-Id: I5e173900a4008c72c67a30eaa9c101027c1b43af Reviewed-by: Eike Ziller <eike.ziller@digia.com> Reviewed-by: David Schulz <david.schulz@digia.com>
Diffstat (limited to 'src/plugins/qt4projectmanager/qt4project.cpp')
-rw-r--r--src/plugins/qt4projectmanager/qt4project.cpp1640
1 files changed, 0 insertions, 1640 deletions
diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp
deleted file mode 100644
index 3812a8e8b6..0000000000
--- a/src/plugins/qt4projectmanager/qt4project.cpp
+++ /dev/null
@@ -1,1640 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** 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.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-****************************************************************************/
-
-#include "qt4project.h"
-
-#include "qt4projectmanager.h"
-#include "qmakeprojectimporter.h"
-#include "qmakebuildinfo.h"
-#include "qmakestep.h"
-#include "qt4nodes.h"
-#include "qt4projectmanagerconstants.h"
-#include "qt4buildconfiguration.h"
-#include "findqt4profiles.h"
-#include "qt4projectmanager/wizards/abstractmobileapp.h"
-#include "qt4projectmanager/wizards/qtquickapp.h"
-#include "qt4projectmanager/wizards/html5app.h"
-
-#include <coreplugin/icontext.h>
-#include <coreplugin/progressmanager/progressmanager.h>
-#include <coreplugin/documentmanager.h>
-#include <cpptools/cppmodelmanagerinterface.h>
-#include <qmljstools/qmljsmodelmanager.h>
-#include <projectexplorer/buildmanager.h>
-#include <projectexplorer/buildtargetinfo.h>
-#include <projectexplorer/deploymentdata.h>
-#include <projectexplorer/toolchain.h>
-#include <projectexplorer/headerpath.h>
-#include <projectexplorer/target.h>
-#include <projectexplorer/projectexplorer.h>
-#include <projectexplorer/projectmacroexpander.h>
-#include <proparser/qmakevfs.h>
-#include <qtsupport/profilereader.h>
-#include <qtsupport/qtkitinformation.h>
-#include <qtsupport/uicodemodelsupport.h>
-
-#include <QDebug>
-#include <QDir>
-#include <QFileSystemWatcher>
-#include <QMessageBox>
-
-using namespace QmakeProjectManager;
-using namespace QmakeProjectManager::Internal;
-using namespace ProjectExplorer;
-
-enum { debug = 0 };
-
-// -----------------------------------------------------------------------
-// Helpers:
-// -----------------------------------------------------------------------
-
-namespace {
-
-Qt4BuildConfiguration *enableActiveQt4BuildConfiguration(ProjectExplorer::Target *t, bool enabled)
-{
- if (!t)
- return 0;
- Qt4BuildConfiguration *bc = static_cast<Qt4BuildConfiguration *>(t->activeBuildConfiguration());
- if (!bc)
- return 0;
- bc->setEnabled(enabled);
- return bc;
-}
-
-void updateBoilerPlateCodeFiles(const AbstractMobileApp *app, const QString &proFile)
-{
- const QList<AbstractGeneratedFileInfo> updates =
- app->fileUpdates(proFile);
- if (!updates.empty()) {
- const QString title = Qt4Manager::tr("Update of Generated Files");
- QStringList fileNames;
- foreach (const AbstractGeneratedFileInfo &info, updates)
- fileNames.append(QDir::toNativeSeparators(info.fileInfo.fileName()));
- const QString message =
- Qt4Manager::tr("In project<br><br>%1<br><br>The following files are either "
- "outdated or have been modified:<br><br>%2<br><br>Do you want "
- "Qt Creator to update the files? Any changes will be lost.")
- .arg(proFile, fileNames.join(QLatin1String(", ")));
- if (QMessageBox::question(0, title, message, QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- QString error;
- if (!app->updateFiles(updates, error))
- QMessageBox::critical(0, title, error);
- }
- }
-}
-
-} // namespace
-
-namespace QmakeProjectManager {
-namespace Internal {
-
-class Qt4ProjectFile : public Core::IDocument
-{
- Q_OBJECT
-
-public:
- Qt4ProjectFile(const QString &filePath, QObject *parent = 0);
-
- bool save(QString *errorString, const QString &fileName, bool autoSave);
-
- QString defaultPath() const;
- QString suggestedFileName() const;
- virtual QString mimeType() const;
-
- bool isModified() const;
- bool isSaveAsAllowed() const;
-
- ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const;
- bool reload(QString *errorString, ReloadFlag flag, ChangeType type);
-
-private:
- const QString m_mimeType;
-};
-
-/// Watches folders for Qt4PriFile nodes
-/// use one file system watcher to watch all folders
-/// such minimizing system ressouce usage
-
-class CentralizedFolderWatcher : public QObject
-{
- Q_OBJECT
-public:
- CentralizedFolderWatcher(Qt4Project *parent);
- ~CentralizedFolderWatcher();
- void watchFolders(const QList<QString> &folders, QmakeProjectManager::Qt4PriFileNode *node);
- void unwatchFolders(const QList<QString> &folders, QmakeProjectManager::Qt4PriFileNode *node);
-
-private slots:
- void folderChanged(const QString &folder);
- void onTimer();
- void delayedFolderChanged(const QString &folder);
-
-private:
- Qt4Project *m_project;
- QSet<QString> recursiveDirs(const QString &folder);
- QFileSystemWatcher m_watcher;
- QMultiMap<QString, QmakeProjectManager::Qt4PriFileNode *> m_map;
-
- QSet<QString> m_recursiveWatchedFolders;
- QTimer m_compressTimer;
- QSet<QString> m_changedFolders;
-};
-
-// Qt4ProjectFiles: Struct for (Cached) lists of files in a project
-class Qt4ProjectFiles {
-public:
- 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
-{
- 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
-namespace Internal {
-Qt4ProjectFile::Qt4ProjectFile(const QString &filePath, QObject *parent)
- : Core::IDocument(parent),
- m_mimeType(QLatin1String(QmakeProjectManager::Constants::PROFILE_MIMETYPE))
-{
- setFilePath(filePath);
-}
-
-bool Qt4ProjectFile::save(QString *, const QString &, bool)
-{
- // This is never used
- return false;
-}
-
-QString Qt4ProjectFile::defaultPath() const
-{
- return QString();
-}
-
-QString Qt4ProjectFile::suggestedFileName() const
-{
- return QString();
-}
-
-QString Qt4ProjectFile::mimeType() const
-{
- return m_mimeType;
-}
-
-bool Qt4ProjectFile::isModified() const
-{
- return false; // we save after changing anyway
-}
-
-bool Qt4ProjectFile::isSaveAsAllowed() const
-{
- return false;
-}
-
-Core::IDocument::ReloadBehavior Qt4ProjectFile::reloadBehavior(ChangeTrigger state, ChangeType type) const
-{
- Q_UNUSED(state)
- Q_UNUSED(type)
- return BehaviorSilent;
-}
-
-bool Qt4ProjectFile::reload(QString *errorString, ReloadFlag flag, ChangeType type)
-{
- Q_UNUSED(errorString)
- Q_UNUSED(flag)
- Q_UNUSED(type)
- return true;
-}
-
-} // namespace Internal
-
-/*!
- \class Qt4Project
-
- Qt4Project manages information about an individual Qt 4 (.pro) project file.
- */
-
-Qt4Project::Qt4Project(Qt4Manager *manager, const QString& fileName) :
- m_manager(manager),
- m_rootProjectNode(0),
- m_nodesWatcher(new Internal::Qt4NodesWatcher(this)),
- m_fileInfo(new Qt4ProjectFile(fileName, this)),
- m_projectFiles(new Qt4ProjectFiles),
- m_qmakeVfs(new QMakeVfs),
- m_qmakeGlobals(0),
- m_asyncUpdateFutureInterface(0),
- m_pendingEvaluateFuturesCount(0),
- m_asyncUpdateState(NoState),
- m_cancelEvaluate(false),
- m_centralizedFolderWatcher(0),
- m_activeTarget(0)
-{
- setProjectContext(Core::Context(QmakeProjectManager::Constants::PROJECT_ID));
- setProjectLanguages(Core::Context(ProjectExplorer::Constants::LANG_CXX));
-
- m_asyncUpdateTimer.setSingleShot(true);
- m_asyncUpdateTimer.setInterval(3000);
- connect(&m_asyncUpdateTimer, SIGNAL(timeout()), this, SLOT(asyncUpdate()));
-
- connect(BuildManager::instance(), SIGNAL(buildQueueFinished(bool)),
- SLOT(buildFinished(bool)));
-}
-
-Qt4Project::~Qt4Project()
-{
- m_codeModelFuture.cancel();
- m_asyncUpdateState = ShuttingDown;
- m_manager->unregisterProject(this);
- delete m_qmakeVfs;
- delete m_projectFiles;
- m_cancelEvaluate = true;
- // Deleting the root node triggers a few things, make sure rootProjectNode
- // returns 0 already
- Qt4ProFileNode *root = m_rootProjectNode;
- m_rootProjectNode = 0;
- delete root;
-}
-
-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;
- }
-}
-
-bool Qt4Project::fromMap(const QVariantMap &map)
-{
- if (!Project::fromMap(map))
- return false;
-
- // Prune targets without buildconfigurations:
- // This can happen esp. when updating from a old version of Qt Creator
- QList<Target *>ts = targets();
- foreach (Target *t, ts) {
- if (t->buildConfigurations().isEmpty()) {
- qWarning() << "Removing" << t->id().name() << "since it has no buildconfigurations!";
- removeTarget(t);
- }
- }
-
- m_manager->registerProject(this);
-
- m_rootProjectNode = new Qt4ProFileNode(this, m_fileInfo->filePath(), this);
- m_rootProjectNode->registerWatcher(m_nodesWatcher);
-
- update();
- updateFileList();
- // This might be incorrect, need a full update
- updateCodeModels();
-
- // We have the profile nodes now, so we know the runconfigs!
- connect(m_nodesWatcher, SIGNAL(proFileUpdated(QmakeProjectManager::Qt4ProFileNode*,bool,bool)),
- this, SIGNAL(proFileUpdated(QmakeProjectManager::Qt4ProFileNode*,bool,bool)));
-
- // Now we emit update once :)
- m_rootProjectNode->emitProFileUpdatedRecursive();
-
- // On active buildconfiguration changes, reevaluate the .pro files
- m_activeTarget = activeTarget();
- if (m_activeTarget)
- connect(m_activeTarget, SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
- this, SLOT(scheduleAsyncUpdate()));
-
- connect(this, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
- this, SLOT(activeTargetWasChanged()));
-
- // // Update boiler plate code for subprojects.
- QtQuickApp qtQuickApp;
- const Html5App html5App;
-
- foreach (Qt4ProFileNode *node, applicationProFiles(Qt4Project::ExactAndCumulativeParse)) {
- const QString path = node->path();
-
- qtQuickApp.setComponentSet(QtQuickApp::QtQuick10Components);
- updateBoilerPlateCodeFiles(&qtQuickApp, path);
- qtQuickApp.setComponentSet(QtQuickApp::QtQuick20Components);
- updateBoilerPlateCodeFiles(&qtQuickApp, path);
- updateBoilerPlateCodeFiles(&html5App, path);
- }
- return true;
-}
-
-/// equalFileList compares two file lists ignoring
-/// <configuration> without generating temporary lists
-
-bool Qt4Project::equalFileList(const QStringList &a, const QStringList &b)
-{
- if (abs(a.length() - b.length()) > 1)
- return false;
- QStringList::const_iterator ait = a.constBegin();
- QStringList::const_iterator bit = b.constBegin();
- QStringList::const_iterator aend = a.constEnd();
- QStringList::const_iterator bend = b.constEnd();
-
- while (ait != aend && bit != bend) {
- if (*ait == CppTools::CppModelManagerInterface::configurationFileName())
- ++ait;
- else if (*bit == CppTools::CppModelManagerInterface::configurationFileName())
- ++bit;
- else if (*ait == *bit)
- ++ait, ++bit;
- else
- return false;
- }
- return (ait == aend && bit == bend);
-}
-
-void Qt4Project::updateCodeModels()
-{
- if (debug)
- qDebug()<<"Qt4Project::updateCodeModel()";
-
- if (activeTarget() && !activeTarget()->activeBuildConfiguration())
- return;
-
- updateCppCodeModel();
- updateQmlJSCodeModel();
-}
-
-void Qt4Project::updateCppCodeModel()
-{
- typedef CppTools::ProjectPart ProjectPart;
- typedef CppTools::ProjectFile ProjectFile;
-
- Kit *k = 0;
- QtSupport::BaseQtVersion *qtVersion = 0;
- if (ProjectExplorer::Target *target = activeTarget())
- k = target->kit();
- else
- k = KitManager::defaultKit();
- qtVersion = QtSupport::QtKitInformation::qtVersion(k);
-
- CppTools::CppModelManagerInterface *modelmanager =
- CppTools::CppModelManagerInterface::instance();
-
- if (!modelmanager)
- return;
-
- FindQt4ProFiles findQt4ProFiles;
- QList<Qt4ProFileNode *> proFiles = findQt4ProFiles(rootProjectNode());
-
- CppTools::CppModelManagerInterface::ProjectInfo pinfo = modelmanager->projectInfo(this);
- pinfo.clearProjectParts();
- ProjectPart::QtVersion qtVersionForPart = ProjectPart::NoQt;
- if (qtVersion) {
- if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
- qtVersionForPart = ProjectPart::Qt4;
- else
- qtVersionForPart = ProjectPart::Qt5;
- }
-
- QHash<QString, QString> uiCodeModelData;
- QStringList allFiles;
- foreach (Qt4ProFileNode *pro, proFiles) {
- ProjectPart::Ptr part(new ProjectPart);
- part->project = this;
- part->displayName = pro->displayName();
- part->projectFile = pro->path();
-
- if (pro->variableValue(ConfigVar).contains(QLatin1String("qt")))
- part->qtVersion = qtVersionForPart;
- else
- part->qtVersion = ProjectPart::NoQt;
-
- const QStringList cxxflags = pro->variableValue(CppFlagsVar);
- part->evaluateToolchain(ToolChainKitInformation::toolChain(k),
- cxxflags,
- cxxflags,
- SysRootKitInformation::sysRoot(k));
-
- // part->defines
- part->defines += pro->cxxDefines();
-
- // part->includePaths, part->frameworkPaths
- part->includePaths.append(pro->variableValue(IncludePathVar));
-
- if (qtVersion) {
- foreach (const HeaderPath &header, qtVersion->systemHeaderPathes(k)) {
- if (header.kind() == HeaderPath::FrameworkHeaderPath)
- part->frameworkPaths.append(header.path());
- else
- part->includePaths.append(header.path());
- }
- if (!qtVersion->frameworkInstallPath().isEmpty())
- part->frameworkPaths.append(qtVersion->frameworkInstallPath());
- }
-
- if (Qt4ProFileNode *node = rootQt4ProjectNode())
- part->includePaths.append(node->resolvedMkspecPath());
-
- // part->precompiledHeaders
- part->precompiledHeaders.append(pro->variableValue(PrecompiledHeaderVar));
-
- // part->files
- foreach (const QString &file, pro->variableValue(CppSourceVar)) {
- allFiles << file;
- part->files << ProjectFile(file, ProjectFile::CXXSource);
- }
- foreach (const QString &file, pro->variableValue(CppHeaderVar)) {
- allFiles << file;
- part->files << ProjectFile(file, ProjectFile::CXXHeader);
- }
-
- // Ui Files:
- QHash<QString, QString> uiData = pro->uiFiles();
- for (QHash<QString, QString>::const_iterator i = uiData.constBegin(); i != uiData.constEnd(); ++i) {
- allFiles << i.value();
- part->files << ProjectFile(i.value(), ProjectFile::CXXHeader);
- }
- uiCodeModelData.unite(uiData);
-
- part->files.prepend(ProjectFile(CppTools::CppModelManagerInterface::configurationFileName(),
- ProjectFile::CXXSource));
- foreach (const QString &file, pro->variableValue(ObjCSourceVar)) {
- allFiles << file;
- // Although the enum constant is called ObjCSourceVar, it actually is ObjC++ source
- // code, as qmake does not handle C (and ObjC).
- part->files << ProjectFile(file, ProjectFile::ObjCXXSource);
- }
- foreach (const QString &file, pro->variableValue(ObjCHeaderVar)) {
- allFiles << file;
- part->files << ProjectFile(file, ProjectFile::ObjCXXHeader);
- }
-
- pinfo.appendProjectPart(part);
- }
-
- setProjectLanguage(ProjectExplorer::Constants::LANG_CXX, !allFiles.isEmpty());
-
- // Also update Ui Code Model Support:
- QtSupport::UiCodeModelManager::update(this, uiCodeModelData);
-
- m_codeModelFuture = modelmanager->updateProjectInfo(pinfo);
-}
-
-void Qt4Project::updateQmlJSCodeModel()
-{
- QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
- if (!modelManager)
- return;
-
- QmlJS::ModelManagerInterface::ProjectInfo projectInfo =
- QmlJSTools::defaultProjectInfoForProject(this);
-
- FindQt4ProFiles findQt4ProFiles;
- QList<Qt4ProFileNode *> proFiles = findQt4ProFiles(rootProjectNode());
-
- projectInfo.importPaths.clear();
-
- bool hasQmlLib = false;
- foreach (Qt4ProFileNode *node, proFiles) {
- projectInfo.importPaths.append(node->variableValue(QmlImportPathVar));
- projectInfo.activeResourceFiles.append(node->variableValue(ExactResourceVar));
- projectInfo.allResourceFiles.append(node->variableValue(ResourceVar));
- if (!hasQmlLib) {
- QStringList qtLibs = node->variableValue(QtVar);
- hasQmlLib = qtLibs.contains(QLatin1String("declarative")) ||
- qtLibs.contains(QLatin1String("qml")) ||
- qtLibs.contains(QLatin1String("quick"));
- }
- }
-
- // If the project directory has a pro/pri file that includes a qml or quick or declarative
- // library then chances of the project being a QML project is quite high.
- // This assumption fails when there are no QDeclarativeEngine/QDeclarativeView (QtQuick 1)
- // or QQmlEngine/QQuickView (QtQuick 2) instances.
- Core::Context pl(ProjectExplorer::Constants::LANG_CXX);
- if (hasQmlLib)
- pl.add(ProjectExplorer::Constants::LANG_QMLJS);
- setProjectLanguages(pl);
-
- projectInfo.importPaths.removeDuplicates();
- projectInfo.activeResourceFiles.removeDuplicates();
- projectInfo.allResourceFiles.removeDuplicates();
-
- setProjectLanguage(ProjectExplorer::Constants::LANG_QMLJS, !projectInfo.sourceFiles.isEmpty());
-
- modelManager->updateProjectInfo(projectInfo);
-}
-
-///*!
-// Updates complete project
-// */
-void Qt4Project::update()
-{
- if (debug)
- qDebug()<<"Doing sync update";
- m_rootProjectNode->update();
-
- if (debug)
- qDebug()<<"State is now Base";
- m_asyncUpdateState = Base;
- enableActiveQt4BuildConfiguration(activeTarget(), true);
- updateBuildSystemData();
- updateRunConfigurations();
- emit proFilesEvaluated();
-}
-
-void Qt4Project::updateRunConfigurations()
-{
- if (activeTarget())
- activeTarget()->updateDefaultRunConfigurations();
-}
-
-void Qt4Project::scheduleAsyncUpdate(Qt4ProFileNode *node)
-{
- if (m_asyncUpdateState == ShuttingDown)
- return;
-
- if (debug)
- qDebug()<<"schduleAsyncUpdate (node)"<<node->path();
- Q_ASSERT(m_asyncUpdateState != NoState);
-
- if (m_cancelEvaluate) {
- if (debug)
- qDebug()<<" Already canceling, nothing to do";
- // A cancel is in progress
- // That implies that a full update is going to happen afterwards
- // So we don't need to do anything
- return;
- }
-
- enableActiveQt4BuildConfiguration(activeTarget(), false);
-
- if (m_asyncUpdateState == AsyncFullUpdatePending) {
- // Just postpone
- if (debug)
- qDebug()<<" full update pending, restarting timer";
- m_asyncUpdateTimer.start();
- } else if (m_asyncUpdateState == AsyncPartialUpdatePending
- || m_asyncUpdateState == Base) {
- if (debug)
- qDebug()<<" adding node to async update list, setting state to AsyncPartialUpdatePending";
- // Add the node
- m_asyncUpdateState = AsyncPartialUpdatePending;
-
- QList<Qt4ProFileNode *>::iterator it;
- bool add = true;
- if (debug)
- qDebug()<<"scheduleAsyncUpdate();"<<m_partialEvaluate.size()<<"nodes";
- it = m_partialEvaluate.begin();
- while (it != m_partialEvaluate.end()) {
- if (*it == node) {
- add = false;
- break;
- } else if (node->isParent(*it)) { // We already have the parent in the list, nothing to do
- it = m_partialEvaluate.erase(it);
- } else if ((*it)->isParent(node)) { // The node is the parent of a child already in the list
- add = false;
- break;
- } else {
- ++it;
- }
- }
-
- if (add)
- m_partialEvaluate.append(node);
- // and start the timer anew
- m_asyncUpdateTimer.start();
-
- // Cancel running code model update
- m_codeModelFuture.cancel();
- } else if (m_asyncUpdateState == AsyncUpdateInProgress) {
- // A update is in progress
- // And this slot only gets called if a file changed on disc
- // So we'll play it safe and schedule a complete evaluate
- // This might trigger if due to version control a few files
- // change a partial update gets in progress and then another
- // batch of changes come in, which triggers a full update
- // even if that's not really needed
- if (debug)
- qDebug()<<" Async update in progress, scheduling new one afterwards";
- scheduleAsyncUpdate();
- }
-}
-
-void Qt4Project::scheduleAsyncUpdate()
-{
- if (debug)
- qDebug()<<"scheduleAsyncUpdate";
- if (m_asyncUpdateState == ShuttingDown)
- return;
-
- Q_ASSERT(m_asyncUpdateState != NoState);
- if (m_cancelEvaluate) { // we are in progress of canceling
- // and will start the evaluation after that
- if (debug)
- qDebug()<<" canceling is in progress, doing nothing";
- return;
- }
- if (m_asyncUpdateState == AsyncUpdateInProgress) {
- if (debug)
- qDebug()<<" update in progress, canceling and setting state to full update pending";
- m_cancelEvaluate = true;
- m_asyncUpdateState = AsyncFullUpdatePending;
- enableActiveQt4BuildConfiguration(activeTarget(), false);
- m_rootProjectNode->setParseInProgressRecursive(true);
- return;
- }
-
- if (debug)
- qDebug()<<" starting timer for full update, setting state to full update pending";
- m_partialEvaluate.clear();
- enableActiveQt4BuildConfiguration(activeTarget(), false);
- m_rootProjectNode->setParseInProgressRecursive(true);
- m_asyncUpdateState = AsyncFullUpdatePending;
- m_asyncUpdateTimer.start();
-
- // Cancel running code model update
- m_codeModelFuture.cancel();
-}
-
-
-void Qt4Project::incrementPendingEvaluateFutures()
-{
- ++m_pendingEvaluateFuturesCount;
- if (debug)
- qDebug()<<"incrementPendingEvaluateFutures to"<<m_pendingEvaluateFuturesCount;
-
- m_asyncUpdateFutureInterface->setProgressRange(m_asyncUpdateFutureInterface->progressMinimum(),
- m_asyncUpdateFutureInterface->progressMaximum() + 1);
-}
-
-void Qt4Project::decrementPendingEvaluateFutures()
-{
- --m_pendingEvaluateFuturesCount;
-
- if (debug)
- qDebug()<<"decrementPendingEvaluateFutures to"<<m_pendingEvaluateFuturesCount;
-
- m_asyncUpdateFutureInterface->setProgressValue(m_asyncUpdateFutureInterface->progressValue() + 1);
- if (m_pendingEvaluateFuturesCount == 0) {
- if (debug)
- qDebug()<<" WOHOO, no pending futures, cleaning up";
- // We are done!
- if (debug)
- qDebug()<<" reporting finished";
-
- m_asyncUpdateFutureInterface->reportFinished();
- delete m_asyncUpdateFutureInterface;
- m_asyncUpdateFutureInterface = 0;
- m_cancelEvaluate = false;
-
- // TODO clear the profile cache ?
- if (m_asyncUpdateState == AsyncFullUpdatePending || m_asyncUpdateState == AsyncPartialUpdatePending) {
- if (debug)
- qDebug()<<" Oh update is pending start the timer";
- m_asyncUpdateTimer.start();
- } else if (m_asyncUpdateState != ShuttingDown){
- // After being done, we need to call:
- m_asyncUpdateState = Base;
- enableActiveQt4BuildConfiguration(activeTarget(), true);
- updateFileList();
- updateCodeModels();
- updateBuildSystemData();
- updateRunConfigurations();
- emit proFilesEvaluated();
- if (debug)
- qDebug()<<" Setting state to Base";
- }
- }
-}
-
-bool Qt4Project::wasEvaluateCanceled()
-{
- return m_cancelEvaluate;
-}
-
-void Qt4Project::asyncUpdate()
-{
- if (debug)
- qDebug()<<"async update, timer expired, doing now";
-
- m_qmakeVfs->invalidateCache();
-
- Q_ASSERT(!m_asyncUpdateFutureInterface);
- m_asyncUpdateFutureInterface = new QFutureInterface<void>();
-
- m_asyncUpdateFutureInterface->setProgressRange(0, 0);
- Core::ProgressManager::addTask(m_asyncUpdateFutureInterface->future(), tr("Evaluating"),
- Constants::PROFILE_EVALUATE);
- if (debug)
- qDebug()<<" adding task";
-
- m_asyncUpdateFutureInterface->reportStarted();
-
- if (m_asyncUpdateState == AsyncFullUpdatePending) {
- if (debug)
- qDebug()<<" full update, starting with root node";
- m_rootProjectNode->asyncUpdate();
- } else {
- if (debug)
- qDebug()<<" partial update,"<<m_partialEvaluate.size()<<"nodes to update";
- foreach (Qt4ProFileNode *node, m_partialEvaluate)
- node->asyncUpdate();
- }
-
- m_partialEvaluate.clear();
- if (debug)
- qDebug()<<" Setting state to AsyncUpdateInProgress";
- m_asyncUpdateState = AsyncUpdateInProgress;
-}
-
-void Qt4Project::buildFinished(bool success)
-{
- if (success)
- m_qmakeVfs->invalidateContents();
-}
-
-ProjectExplorer::IProjectManager *Qt4Project::projectManager() const
-{
- return m_manager;
-}
-
-Qt4Manager *Qt4Project::qt4ProjectManager() const
-{
- return m_manager;
-}
-
-bool Qt4Project::supportsKit(Kit *k, QString *errorMessage) const
-{
- QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(k);
- if (!version && errorMessage)
- *errorMessage = tr("No Qt version set in kit.");
- return version;
-}
-
-QString Qt4Project::displayName() const
-{
- return QFileInfo(projectFilePath()).completeBaseName();
-}
-
-Core::Id Qt4Project::id() const
-{
- return Core::Id(Constants::QT4PROJECT_ID);
-}
-
-Core::IDocument *Qt4Project::document() 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;
-}
-
-// Find the folder that contains a file a certain type (recurse down)
-static FolderNode *folderOf(FolderNode *in, FileType fileType, const QString &fileName)
-{
- foreach (FileNode *fn, in->fileNodes())
- if (fn->fileType() == fileType && fn->path() == fileName)
- return in;
- foreach (FolderNode *folder, in->subFolderNodes())
- if (FolderNode *pn = folderOf(folder, fileType, fileName))
- return pn;
- return 0;
-}
-
-// Find the Qt4ProFileNode that contains a file of a certain type.
-// First recurse down to folder, then find the pro-file.
-static Qt4ProFileNode *proFileNodeOf(Qt4ProFileNode *in, FileType fileType, const QString &fileName)
-{
- for (FolderNode *folder = folderOf(in, fileType, fileName); folder; folder = folder->parentFolderNode())
- if (Qt4ProFileNode *proFile = qobject_cast<Qt4ProFileNode *>(folder))
- return proFile;
- return 0;
-}
-
-QString Qt4Project::generatedUiHeader(const QString &formFile) const
-{
- // Look in sub-profiles as SessionManager::projectForFile returns
- // the top-level project only.
- if (m_rootProjectNode)
- if (const Qt4ProFileNode *pro = proFileNodeOf(m_rootProjectNode, FormType, formFile))
- return Qt4ProFileNode::uiHeaderFile(pro->uiDirectory(), formFile);
- return QString();
-}
-
-void Qt4Project::proFileParseError(const QString &errorMessage)
-{
- Core::MessageManager::write(errorMessage);
-}
-
-QtSupport::ProFileReader *Qt4Project::createProFileReader(const Qt4ProFileNode *qt4ProFileNode, Qt4BuildConfiguration *bc)
-{
- if (!m_qmakeGlobals) {
- m_qmakeGlobals = new ProFileGlobals;
- m_qmakeGlobalsRefCnt = 0;
-
- Kit *k;
- Utils::Environment env = Utils::Environment::systemEnvironment();
- QStringList qmakeArgs;
- if (!bc)
- bc = activeTarget() ? static_cast<Qt4BuildConfiguration *>(activeTarget()->activeBuildConfiguration()) : 0;
-
- if (bc) {
- k = bc->target()->kit();
- env = bc->environment();
- if (bc->qmakeStep())
- qmakeArgs = bc->qmakeStep()->parserArguments();
- else
- qmakeArgs = bc->configCommandLineArguments();
- } else {
- k = KitManager::defaultKit();
- }
-
- QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k);
- QString systemRoot = SysRootKitInformation::hasSysRoot(k)
- ? SysRootKitInformation::sysRoot(k).toString() : QString();
-
- if (qtVersion && qtVersion->isValid()) {
- m_qmakeGlobals->qmake_abslocation = QDir::cleanPath(qtVersion->qmakeCommand().toString());
- m_qmakeGlobals->setProperties(qtVersion->versionInfo());
- }
- m_qmakeGlobals->setDirectories(m_rootProjectNode->sourceDir(), m_rootProjectNode->buildDir());
- m_qmakeGlobals->sysroot = systemRoot;
-
- Utils::Environment::const_iterator eit = env.constBegin(), eend = env.constEnd();
- for (; eit != eend; ++eit)
- m_qmakeGlobals->environment.insert(env.key(eit), env.value(eit));
-
- m_qmakeGlobals->setCommandLineArguments(m_rootProjectNode->buildDir(), qmakeArgs);
-
- QtSupport::ProFileCacheManager::instance()->incRefCount();
- }
- ++m_qmakeGlobalsRefCnt;
-
- QtSupport::ProFileReader *reader = new QtSupport::ProFileReader(m_qmakeGlobals, m_qmakeVfs);
-
- reader->setOutputDir(qt4ProFileNode->buildDir());
-
- return reader;
-}
-
-ProFileGlobals *Qt4Project::qmakeGlobals()
-{
- return m_qmakeGlobals;
-}
-
-void Qt4Project::destroyProFileReader(QtSupport::ProFileReader *reader)
-{
- delete reader;
- if (!--m_qmakeGlobalsRefCnt) {
- QString dir = QFileInfo(m_fileInfo->filePath()).absolutePath();
- if (!dir.endsWith(QLatin1Char('/')))
- dir += QLatin1Char('/');
- QtSupport::ProFileCacheManager::instance()->discardFiles(dir);
- QtSupport::ProFileCacheManager::instance()->decRefCount();
-
- delete m_qmakeGlobals;
- m_qmakeGlobals = 0;
- }
-}
-
-ProjectExplorer::ProjectNode *Qt4Project::rootProjectNode() const
-{
- return m_rootProjectNode;
-}
-
-Qt4ProFileNode *Qt4Project::rootQt4ProjectNode() const
-{
- return m_rootProjectNode;
-}
-
-bool Qt4Project::validParse(const QString &proFilePath) const
-{
- if (!m_rootProjectNode)
- return false;
- const Qt4ProFileNode *node = m_rootProjectNode->findProFileFor(proFilePath);
- return node && node->validParse();
-}
-
-bool Qt4Project::parseInProgress(const QString &proFilePath) const
-{
- if (!m_rootProjectNode)
- return false;
- const Qt4ProFileNode *node = m_rootProjectNode->findProFileFor(proFilePath);
- return node && node->parseInProgress();
-}
-
-void Qt4Project::collectAllfProFiles(QList<Qt4ProFileNode *> &list, Qt4ProFileNode *node, Parsing parse)
-{
- if (parse == ExactAndCumulativeParse || node->includedInExactParse())
- list.append(node);
- foreach (ProjectNode *n, node->subProjectNodes()) {
- Qt4ProFileNode *qt4ProFileNode = qobject_cast<Qt4ProFileNode *>(n);
- if (qt4ProFileNode)
- collectAllfProFiles(list, qt4ProFileNode, parse);
- }
-}
-
-void Qt4Project::collectApplicationProFiles(QList<Qt4ProFileNode *> &list, Qt4ProFileNode *node, Parsing parse)
-{
- if (node->projectType() == ApplicationTemplate
- || node->projectType() == ScriptTemplate) {
- if (parse == ExactAndCumulativeParse || node->includedInExactParse())
- list.append(node);
- }
- foreach (ProjectNode *n, node->subProjectNodes()) {
- Qt4ProFileNode *qt4ProFileNode = qobject_cast<Qt4ProFileNode *>(n);
- if (qt4ProFileNode)
- collectApplicationProFiles(list, qt4ProFileNode, parse);
- }
-}
-
-QList<Qt4ProFileNode *> Qt4Project::allProFiles(Parsing parse) const
-{
- QList<Qt4ProFileNode *> list;
- if (!rootProjectNode())
- return list;
- collectAllfProFiles(list, rootQt4ProjectNode(), parse);
- return list;
-}
-
-QList<Qt4ProFileNode *> Qt4Project::applicationProFiles(Parsing parse) const
-{
- QList<Qt4ProFileNode *> list;
- if (!rootProjectNode())
- return list;
- collectApplicationProFiles(list, rootQt4ProjectNode(), parse);
- return list;
-}
-
-bool Qt4Project::hasApplicationProFile(const QString &path) const
-{
- if (path.isEmpty())
- return false;
-
- QList<Qt4ProFileNode *> list = applicationProFiles();
- foreach (Qt4ProFileNode * node, list)
- if (node->path() == path)
- return true;
- return false;
-}
-
-QStringList Qt4Project::applicationProFilePathes(const QString &prepend, Parsing parse) const
-{
- QStringList proFiles;
- foreach (Qt4ProFileNode *node, applicationProFiles(parse))
- proFiles.append(prepend + node->path());
- return proFiles;
-}
-
-void Qt4Project::activeTargetWasChanged()
-{
- if (m_activeTarget) {
- disconnect(m_activeTarget, SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
- this, SLOT(scheduleAsyncUpdate()));
- }
-
- m_activeTarget = activeTarget();
-
- if (!m_activeTarget)
- return;
-
- connect(m_activeTarget, SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
- this, SLOT(scheduleAsyncUpdate()));
-
- scheduleAsyncUpdate();
-}
-
-bool Qt4Project::hasSubNode(Qt4PriFileNode *root, const QString &path)
-{
- if (root->path() == path)
- return true;
- foreach (FolderNode *fn, root->subFolderNodes()) {
- if (qobject_cast<Qt4ProFileNode *>(fn)) {
- // we aren't interested in pro file nodes
- } else if (Qt4PriFileNode *qt4prifilenode = qobject_cast<Qt4PriFileNode *>(fn)) {
- if (hasSubNode(qt4prifilenode, path))
- return true;
- }
- }
- return false;
-}
-
-void Qt4Project::findProFile(const QString& fileName, Qt4ProFileNode *root, QList<Qt4ProFileNode *> &list)
-{
- if (hasSubNode(root, fileName))
- 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)
-{
- if (files(Qt4Project::ExcludeGeneratedFiles).contains(name)) {
- QList<Qt4ProFileNode *> list;
- findProFile(name, rootQt4ProjectNode(), list);
- foreach (Qt4ProFileNode *node, list) {
- QtSupport::ProFileCacheManager::instance()->discardFile(name);
- node->update();
- }
- updateFileList();
- }
-}
-
-void Qt4Project::watchFolders(const QStringList &l, Qt4PriFileNode *node)
-{
- if (l.isEmpty())
- return;
- if (!m_centralizedFolderWatcher)
- m_centralizedFolderWatcher = new Internal::CentralizedFolderWatcher(this);
- m_centralizedFolderWatcher->watchFolders(l, node);
-}
-
-void Qt4Project::unwatchFolders(const QStringList &l, Qt4PriFileNode *node)
-{
- if (m_centralizedFolderWatcher && !l.isEmpty())
- m_centralizedFolderWatcher->unwatchFolders(l, node);
-}
-
-/////////////
-/// Centralized Folder Watcher
-////////////
-
-// All the folder have a trailing slash!
-
-namespace {
- bool debugCFW = false;
-}
-
-CentralizedFolderWatcher::CentralizedFolderWatcher(Qt4Project *parent)
- : QObject(parent), m_project(parent)
-{
- m_compressTimer.setSingleShot(true);
- m_compressTimer.setInterval(200);
- connect(&m_compressTimer, SIGNAL(timeout()),
- this, SLOT(onTimer()));
- connect (&m_watcher, SIGNAL(directoryChanged(QString)),
- this, SLOT(folderChanged(QString)));
-}
-
-CentralizedFolderWatcher::~CentralizedFolderWatcher()
-{
-
-}
-
-QSet<QString> CentralizedFolderWatcher::recursiveDirs(const QString &folder)
-{
- QSet<QString> result;
- QDir dir(folder);
- QStringList list = dir.entryList(QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot);
- foreach (const QString &f, list) {
- const QString a = folder + f + QLatin1Char('/');
- result.insert(a);
- result += recursiveDirs(a);
- }
- return result;
-}
-
-void CentralizedFolderWatcher::watchFolders(const QList<QString> &folders, QmakeProjectManager::Qt4PriFileNode *node)
-{
- if (debugCFW)
- qDebug()<<"CFW::watchFolders()"<<folders<<"for node"<<node->path();
- m_watcher.addPaths(folders);
-
- const QChar slash = QLatin1Char('/');
- foreach (const QString &f, folders) {
- QString folder = f;
- if (!folder.endsWith(slash))
- folder.append(slash);
- m_map.insert(folder, node);
-
- // Support for recursive watching
- // we add the recursive directories we find
- QSet<QString> tmp = recursiveDirs(folder);
- if (!tmp.isEmpty())
- m_watcher.addPaths(tmp.toList());
- m_recursiveWatchedFolders += tmp;
-
- if (debugCFW)
- qDebug()<<"adding recursive dirs for"<< folder<<":"<<tmp;
- }
-}
-
-void CentralizedFolderWatcher::unwatchFolders(const QList<QString> &folders, QmakeProjectManager::Qt4PriFileNode *node)
-{
- if (debugCFW)
- qDebug()<<"CFW::unwatchFolders()"<<folders<<"for node"<<node->path();
- const QChar slash = QLatin1Char('/');
- foreach (const QString &f, folders) {
- QString folder = f;
- if (!folder.endsWith(slash))
- folder.append(slash);
- m_map.remove(folder, node);
- if (!m_map.contains(folder))
- m_watcher.removePath(folder);
-
- // Figure out which recursive directories we can remove
- // this might not scale. I'm pretty sure it doesn't
- // A scaling implementation would need to save more information
- // where a given directory watcher actual comes from...
-
- QStringList toRemove;
- foreach (const QString &rwf, m_recursiveWatchedFolders) {
- if (rwf.startsWith(folder)) {
- // So the rwf is a subdirectory of a folder we aren't watching
- // but maybe someone else wants us to watch
- bool needToWatch = false;
- QMultiMap<QString, QmakeProjectManager::Qt4PriFileNode *>::const_iterator it, end;
- end = m_map.constEnd();
- for (it = m_map.constEnd(); it != end; ++it) {
- if (rwf.startsWith(it.key())) {
- needToWatch = true;
- break;
- }
- }
- if (!needToWatch) {
- m_watcher.removePath(rwf);
- toRemove << rwf;
- }
- }
- }
-
- if (debugCFW)
- qDebug()<<"removing recursive dirs for"<<folder<<":"<<toRemove;
-
- foreach (const QString &tr, toRemove) {
- m_recursiveWatchedFolders.remove(tr);
- }
- }
-}
-
-void CentralizedFolderWatcher::folderChanged(const QString &folder)
-{
- m_changedFolders.insert(folder);
- m_compressTimer.start();
-}
-
-void CentralizedFolderWatcher::onTimer()
-{
- foreach (const QString &folder, m_changedFolders)
- delayedFolderChanged(folder);
- m_changedFolders.clear();
-}
-
-void CentralizedFolderWatcher::delayedFolderChanged(const QString &folder)
-{
- if (debugCFW)
- qDebug()<<"CFW::folderChanged"<<folder;
- // Figure out whom to inform
-
- QString dir = folder;
- const QChar slash = QLatin1Char('/');
- bool newOrRemovedFiles = false;
- while (true) {
- if (!dir.endsWith(slash))
- dir.append(slash);
- QList<QmakeProjectManager::Qt4PriFileNode *> nodes = m_map.values(dir);
- if (!nodes.isEmpty()) {
- // Collect all the files
- QSet<Utils::FileName> newFiles;
- newFiles += Qt4PriFileNode::recursiveEnumerate(folder);
- foreach (QmakeProjectManager::Qt4PriFileNode *node, nodes) {
- newOrRemovedFiles = newOrRemovedFiles
- || node->folderChanged(folder, newFiles);
- }
- }
-
- // Chop off last part, and break if there's nothing to chop off
- //
- if (dir.length() < 2)
- break;
-
- // We start before the last slash
- const int index = dir.lastIndexOf(slash, dir.length() - 2);
- if (index == -1)
- break;
- dir.truncate(index + 1);
- }
-
- QString folderWithSlash = folder;
- if (!folder.endsWith(slash))
- folderWithSlash.append(slash);
-
- // If a subdirectory was added, watch it too
- QSet<QString> tmp = recursiveDirs(folderWithSlash);
- if (!tmp.isEmpty()) {
- if (debugCFW)
- qDebug()<<"found new recursive dirs"<<tmp;
-
- QSet<QString> alreadyAdded = m_watcher.directories().toSet();
- tmp.subtract(alreadyAdded);
- if (!tmp.isEmpty())
- m_watcher.addPaths(tmp.toList());
- m_recursiveWatchedFolders += tmp;
- }
-
- if (newOrRemovedFiles) {
- m_project->updateFileList();
- m_project->updateCodeModels();
- }
-}
-
-bool Qt4Project::needsConfiguration() const
-{
- return targets().isEmpty();
-}
-
-void Qt4Project::configureAsExampleProject(const QStringList &platforms)
-{
- QList<const BuildInfo *> infoList;
- QList<Kit *> kits = ProjectExplorer::KitManager::kits();
- foreach (Kit *k, kits) {
- QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(k);
- if (!version)
- continue;
- if (!platforms.isEmpty() && !platforms.contains(version->platformName()))
- continue;
-
- IBuildConfigurationFactory *factory = IBuildConfigurationFactory::find(k, projectFilePath());
- if (!factory)
- continue;
- foreach (BuildInfo *info, factory->availableSetups(k, projectFilePath()))
- infoList << info;
- }
- setup(infoList);
- qDeleteAll(infoList);
- ProjectExplorer::ProjectExplorerPlugin::instance()->requestProjectModeUpdate(this);
-}
-
-bool Qt4Project::supportsNoTargetPanel() const
-{
- return true;
-}
-
-// All the Qt4 run configurations should share code.
-// This is a rather suboptimal way to do that for disabledReason()
-// but more pratical then duplicated the code everywhere
-QString Qt4Project::disabledReasonForRunConfiguration(const QString &proFilePath)
-{
- if (!QFileInfo(proFilePath).exists())
- return tr("The .pro file '%1' does not exist.")
- .arg(QFileInfo(proFilePath).fileName());
-
- if (!m_rootProjectNode) // Shutting down
- return QString();
-
- if (!m_rootProjectNode->findProFileFor(proFilePath))
- return tr("The .pro file '%1' is not part of the project.")
- .arg(QFileInfo(proFilePath).fileName());
-
- return tr("The .pro file '%1' could not be parsed.")
- .arg(QFileInfo(proFilePath).fileName());
-}
-
-QString Qt4Project::shadowBuildDirectory(const QString &proFilePath, const Kit *k, const QString &suffix)
-{
- if (proFilePath.isEmpty())
- return QString();
- QFileInfo info(proFilePath);
-
- QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(k);
- if (version && !version->supportsShadowBuilds())
- return info.absolutePath();
-
- const QString projectName = QFileInfo(proFilePath).completeBaseName();
- ProjectExplorer::ProjectMacroExpander expander(proFilePath, projectName, k, suffix);
- QDir projectDir = QDir(projectDirectory(proFilePath));
- QString buildPath = Utils::expandMacros(Core::DocumentManager::buildDirectory(), &expander);
- return QDir::cleanPath(projectDir.absoluteFilePath(buildPath));
-}
-
-QString Qt4Project::buildNameFor(const Kit *k)
-{
- if (!k)
- return QLatin1String("unknown");
-
- return k->fileSystemFriendlyName();
-}
-
-void Qt4Project::updateBuildSystemData()
-{
- Target * const target = activeTarget();
- if (!target)
- return;
- const Qt4ProFileNode * const rootNode = rootQt4ProjectNode();
- if (!rootNode || rootNode->parseInProgress())
- return;
-
- DeploymentData deploymentData;
- collectData(rootNode, deploymentData);
- target->setDeploymentData(deploymentData);
-
- BuildTargetInfoList appTargetList;
- foreach (const Qt4ProFileNode * const node, applicationProFiles())
- appTargetList.list << BuildTargetInfo(executableFor(node), node->path());
- target->setApplicationTargets(appTargetList);
-}
-
-void Qt4Project::collectData(const Qt4ProFileNode *node, DeploymentData &deploymentData)
-{
- if (!node->isSubProjectDeployable(node->path()))
- return;
-
- const InstallsList &installsList = node->installsList();
- foreach (const InstallsItem &item, installsList.items) {
- foreach (const QString &localFile, item.files)
- deploymentData.addFile(localFile, item.path);
- }
-
- switch (node->projectType()) {
- case ApplicationTemplate:
- if (!installsList.targetPath.isEmpty())
- collectApplicationData(node, deploymentData);
- break;
- case LibraryTemplate:
- collectLibraryData(node, deploymentData);
- break;
- case SubDirsTemplate:
- foreach (const ProjectNode * const subProject, node->subProjectNodesExact()) {
- const Qt4ProFileNode * const qt4SubProject
- = qobject_cast<const Qt4ProFileNode *>(subProject);
- if (!qt4SubProject)
- continue;
- collectData(qt4SubProject, deploymentData);
- }
- break;
- default:
- break;
- }
-}
-
-void Qt4Project::collectApplicationData(const Qt4ProFileNode *node, DeploymentData &deploymentData)
-{
- QString executable = executableFor(node);
- if (!executable.isEmpty())
- deploymentData.addFile(executable, node->installsList().targetPath,
- DeployableFile::TypeExecutable);
-}
-
-void Qt4Project::collectLibraryData(const Qt4ProFileNode *node, DeploymentData &deploymentData)
-{
- const QString targetPath = node->installsList().targetPath;
- if (targetPath.isEmpty())
- return;
- const ProjectExplorer::Kit * const kit = activeTarget()->kit();
- const ProjectExplorer::ToolChain * const toolchain
- = ProjectExplorer::ToolChainKitInformation::toolChain(kit);
- if (!toolchain)
- return;
-
- TargetInformation ti = node->targetInformation();
- QString targetFileName = ti.target;
- const QStringList config = node->variableValue(ConfigVar);
- const bool isStatic = config.contains(QLatin1String("static"));
- const bool isPlugin = config.contains(QLatin1String("plugin"));
- switch (toolchain->targetAbi().os()) {
- case ProjectExplorer::Abi::WindowsOS: {
- QString targetVersionExt = node->singleVariableValue(TargetVersionExtVar);
- if (targetVersionExt.isEmpty()) {
- const QString version = node->singleVariableValue(VersionVar);
- if (!version.isEmpty()) {
- targetVersionExt = version.left(version.indexOf(QLatin1Char('.')));
- if (targetVersionExt == QLatin1String("0"))
- targetVersionExt.clear();
- }
- }
- targetFileName += targetVersionExt + QLatin1Char('.');
- targetFileName += QLatin1String(isStatic ? "lib" : "dll");
- deploymentData.addFile(destDirFor(ti) + QLatin1Char('/') + targetFileName, targetPath);
- break;
- }
- case ProjectExplorer::Abi::MacOS: {
- QString destDir = destDirFor(ti);
- if (config.contains(QLatin1String("lib_bundle"))) {
- destDir.append(QLatin1Char('/')).append(ti.target)
- .append(QLatin1String(".framework"));
- } else {
- targetFileName.prepend(QLatin1String("lib"));
- if (!isPlugin) {
- targetFileName += QLatin1Char('.');
- const QString version = node->singleVariableValue(VersionVar);
- QString majorVersion = version.left(version.indexOf(QLatin1Char('.')));
- if (majorVersion.isEmpty())
- majorVersion = QLatin1String("1");
- targetFileName += majorVersion;
- }
- targetFileName += QLatin1Char('.');
- targetFileName += node->singleVariableValue(isStatic
- ? StaticLibExtensionVar : ShLibExtensionVar);
- }
- deploymentData.addFile(destDir + QLatin1Char('/') + targetFileName, targetPath);
- break;
- }
- case ProjectExplorer::Abi::LinuxOS:
- case ProjectExplorer::Abi::BsdOS:
- case ProjectExplorer::Abi::UnixOS:
- targetFileName.prepend(QLatin1String("lib"));
- targetFileName += QLatin1Char('.');
- if (isStatic) {
- targetFileName += QLatin1Char('a');
- } else {
- targetFileName += QLatin1String("so");
- deploymentData.addFile(destDirFor(ti) + QLatin1Char('/') + targetFileName, targetPath);
- if (!isPlugin) {
- QString version = node->singleVariableValue(VersionVar);
- if (version.isEmpty())
- version = QLatin1String("1.0.0");
- targetFileName += QLatin1Char('.');
- while (true) {
- deploymentData.addFile(destDirFor(ti) + QLatin1Char('/')
- + targetFileName + version, targetPath);
- const QString tmpVersion = version.left(version.lastIndexOf(QLatin1Char('.')));
- if (tmpVersion == version)
- break;
- version = tmpVersion;
- }
- }
- }
- break;
- default:
- break;
- }
-}
-
-QString Qt4Project::destDirFor(const TargetInformation &ti)
-{
- if (ti.destDir.isEmpty())
- return ti.buildDir;
- if (QDir::isRelativePath(ti.destDir))
- return QDir::cleanPath(ti.buildDir + QLatin1Char('/') + ti.destDir);
- return ti.destDir;
-}
-
-QString Qt4Project::executableFor(const Qt4ProFileNode *node)
-{
- const ProjectExplorer::Kit * const kit = activeTarget()->kit();
- const ProjectExplorer::ToolChain * const toolchain
- = ProjectExplorer::ToolChainKitInformation::toolChain(kit);
- if (!toolchain)
- return QString();
-
- TargetInformation ti = node->targetInformation();
-
- switch (toolchain->targetAbi().os()) {
- case ProjectExplorer::Abi::MacOS:
- if (node->variableValue(ConfigVar).contains(QLatin1String("app_bundle")))
- return QDir::cleanPath(destDirFor(ti) + QLatin1Char('/') + ti.target
- + QLatin1String(".app/Contents/MacOS/") + ti.target);
- // else fall through
- case ProjectExplorer::Abi::WindowsOS:
- case ProjectExplorer::Abi::LinuxOS:
- case ProjectExplorer::Abi::BsdOS:
- case ProjectExplorer::Abi::UnixOS: {
- QString extension = node->singleVariableValue(TargetExtVar);
- QString executable = QDir::cleanPath(destDirFor(ti) + QLatin1Char('/') + ti.target + extension);
- return executable;
- }
- default:
- return QString();
- }
-}
-
-void Qt4Project::emitBuildDirectoryInitialized()
-{
- emit buildDirectoryInitialized();
-}
-
-ProjectImporter *Qt4Project::createProjectImporter() const
-{
- return new QmakeProjectImporter(projectFilePath());
-}
-
-KitMatcher *Qt4Project::createRequiredKitMatcher() const
-{
- return new QtSupport::QtVersionKitMatcher;
-}
-
-} // namespace QmakeProjectManager
-
-#include "qt4project.moc"