From 8697072ce4c01fea020c68b3e7a660d09011994a Mon Sep 17 00:00:00 2001
From: dt <qtc-committer@nokia.com>
Date: Mon, 6 Dec 2010 16:15:41 +0100
Subject: [PATCH] ProjectExplorer: Move ITargetFactory to object pool

Makes multiple target factories per project possible

Reviewed-By: hunger
---
 .../cmakeprojectmanager/cmakeproject.cpp      | 11 +++-----
 .../cmakeprojectmanager/cmakeproject.h        |  2 --
 .../cmakeprojectplugin.cpp                    |  2 ++
 .../genericprojectmanager/genericproject.cpp  | 13 ++++------
 .../genericprojectmanager/genericproject.h    |  3 ---
 .../genericprojectplugin.cpp                  |  2 ++
 src/plugins/projectexplorer/project.cpp       | 14 +++++++++-
 src/plugins/projectexplorer/project.h         |  2 --
 .../projectexplorer/targetsettingspanel.cpp   | 26 +++++++++++++++++--
 src/plugins/qmlprojectmanager/qmlproject.cpp  | 13 ++++------
 src/plugins/qmlprojectmanager/qmlproject.h    |  3 ---
 .../qmlprojectmanager/qmlprojecttarget.cpp    |  8 +++---
 src/plugins/qt4projectmanager/qt4project.cpp  |  6 -----
 src/plugins/qt4projectmanager/qt4project.h    |  3 ---
 .../wizards/targetsetuppage.cpp               |  8 ++++--
 15 files changed, 65 insertions(+), 51 deletions(-)

diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
index 98aeb73ace3..2465347aba5 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
@@ -80,7 +80,6 @@ CMakeProject::CMakeProject(CMakeManager *manager, const QString &fileName)
       m_fileName(fileName),
       m_rootNode(new CMakeProjectNode(m_fileName)),
       m_insideFileChanged(false),
-      m_targetFactory(new CMakeTargetFactory(this)),
       m_lastEditor(0)
 {
     m_file = new CMakeFile(this, fileName);
@@ -454,11 +453,6 @@ Core::IFile *CMakeProject::file() const
     return m_file;
 }
 
-CMakeTargetFactory *CMakeProject::targetFactory() const
-{
-    return m_targetFactory;
-}
-
 CMakeManager *CMakeProject::projectManager() const
 {
     return m_manager;
@@ -500,7 +494,10 @@ bool CMakeProject::fromMap(const QVariantMap &map)
 
     bool hasUserFile = activeTarget();
     if (!hasUserFile) {
-        CMakeTarget *t = targetFactory()->create(this, QLatin1String(DEFAULT_CMAKE_TARGET_ID));
+        CMakeTargetFactory *factory =
+                ExtensionSystem::PluginManager::instance()->getObject<CMakeTargetFactory>();
+        CMakeTarget *t = factory->create(this, QLatin1String(DEFAULT_CMAKE_TARGET_ID));
+
         Q_ASSERT(t);
         Q_ASSERT(t->activeBuildConfiguration());
 
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h
index 8e0007c0047..b3cefd82340 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.h
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.h
@@ -78,7 +78,6 @@ public:
     QString displayName() const;
     QString id() const;
     Core::IFile *file() const;
-    CMakeTargetFactory *targetFactory() const;
     CMakeManager *projectManager() const;
 
     CMakeTarget *activeTarget() const;
@@ -142,7 +141,6 @@ private:
     ProjectExplorer::FileWatcher *m_watcher;
     bool m_insideFileChanged;
     QSet<QString> m_watchedFiles;
-    CMakeTargetFactory *m_targetFactory;
     QFuture<void> m_codeModelFuture;
 
     QMap<QString, CMakeUiCodeModelSupport *> m_uiCodeModelSupport;
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp
index acdbb0afe5d..588938f716b 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp
@@ -33,6 +33,7 @@
 #include "cmakeeditorfactory.h"
 #include "makestep.h"
 #include "cmakeprojectconstants.h"
+#include "cmaketarget.h"
 
 #include <coreplugin/icore.h>
 #include <coreplugin/mimedatabase.h>
@@ -67,6 +68,7 @@ bool CMakeProjectPlugin::initialize(const QStringList & /*arguments*/, QString *
            = new TextEditor::TextEditorActionHandler(CMakeProjectManager::Constants::C_CMAKEEDITOR);
 
     addAutoReleasedObject(new CMakeEditorFactory(manager, editorHandler));
+    addAutoReleasedObject(new CMakeTargetFactory);
 
     return true;
 }
diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp
index 7c9a1db5993..4a6aa82f56c 100644
--- a/src/plugins/genericprojectmanager/genericproject.cpp
+++ b/src/plugins/genericprojectmanager/genericproject.cpp
@@ -64,7 +64,6 @@ const char * const TOOLCHAIN_KEY("GenericProjectManager.GenericProject.Toolchain
 GenericProject::GenericProject(Manager *manager, const QString &fileName)
     : m_manager(manager),
       m_fileName(fileName),
-      m_targetFactory(new GenericTargetFactory(this)),
       m_toolChain(0)
 {
     QFileInfo fileInfo(m_fileName);
@@ -90,11 +89,6 @@ GenericProject::~GenericProject()
     delete m_toolChain;
 }
 
-GenericTargetFactory *GenericProject::targetFactory() const
-{
-    return m_targetFactory;
-}
-
 GenericTarget *GenericProject::activeTarget() const
 {
     return static_cast<GenericTarget *>(Project::activeTarget());
@@ -444,8 +438,11 @@ bool GenericProject::fromMap(const QVariantMap &map)
     }
 
     // Add default setup:
-    if (targets().isEmpty())
-        addTarget(targetFactory()->create(this, QLatin1String(GENERIC_DESKTOP_TARGET_ID)));
+    if (targets().isEmpty()) {
+        GenericTargetFactory *factory =
+                ExtensionSystem::PluginManager::instance()->getObject<GenericTargetFactory>();
+        addTarget(factory->create(this, QLatin1String(GENERIC_DESKTOP_TARGET_ID)));
+    }
 
     ToolChainType type =
             static_cast<ProjectExplorer::ToolChainType>
diff --git a/src/plugins/genericprojectmanager/genericproject.h b/src/plugins/genericprojectmanager/genericproject.h
index 7971d85998c..6e1eb7f81f0 100644
--- a/src/plugins/genericprojectmanager/genericproject.h
+++ b/src/plugins/genericprojectmanager/genericproject.h
@@ -57,7 +57,6 @@ namespace Internal {
 class GenericBuildConfiguration;
 class GenericProject;
 class GenericTarget;
-class GenericTargetFactory;
 class GenericMakeStep;
 class GenericProjectFile;
 
@@ -76,7 +75,6 @@ public:
     QString displayName() const;
     QString id() const;
     Core::IFile *file() const;
-    GenericTargetFactory *targetFactory() const;
     ProjectExplorer::IProjectManager *projectManager() const;
     GenericTarget *activeTarget() const;
 
@@ -130,7 +128,6 @@ private:
     QString m_configFileName;
     GenericProjectFile *m_file;
     QString m_projectName;
-    GenericTargetFactory *m_targetFactory;
 
     QStringList m_rawFileList;
     QStringList m_files;
diff --git a/src/plugins/genericprojectmanager/genericprojectplugin.cpp b/src/plugins/genericprojectmanager/genericprojectplugin.cpp
index faa627266a5..5184b7b83b8 100644
--- a/src/plugins/genericprojectmanager/genericprojectplugin.cpp
+++ b/src/plugins/genericprojectmanager/genericprojectplugin.cpp
@@ -33,6 +33,7 @@
 #include "genericprojectconstants.h"
 #include "genericprojectfileseditor.h"
 #include "genericmakestep.h"
+#include "generictarget.h"
 
 #include <coreplugin/icore.h>
 #include <coreplugin/mimedatabase.h>
@@ -78,6 +79,7 @@ bool GenericProjectPlugin::initialize(const QStringList &, QString *errorMessage
     addAutoReleasedObject(manager);
     addAutoReleasedObject(new GenericMakeStepFactory);
     addAutoReleasedObject(new GenericProjectWizard);
+    addAutoReleasedObject(new GenericTargetFactory);
 
     return true;
 }
diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp
index 9b2f4f0e78b..2a515bb7b45 100644
--- a/src/plugins/projectexplorer/project.cpp
+++ b/src/plugins/projectexplorer/project.cpp
@@ -276,7 +276,19 @@ bool Project::fromMap(const QVariantMap &map)
             qWarning() << key << "was not found in data.";
             return false;
         }
-        Target *t(targetFactory()->restore(this, map.value(key).toMap()));
+       QVariantMap targetMap = map.value(key).toMap();
+
+        QList<ITargetFactory *> factories =
+                ExtensionSystem::PluginManager::instance()->getObjects<ITargetFactory>();
+
+        Target *t = 0;
+        foreach (ITargetFactory *factory, factories) {
+            if (factory->canRestore(this, targetMap)) {
+                t = factory->restore(this, targetMap);
+                break;
+            }
+        }
+
         if (!t) {
             qWarning() << "Restoration of a target failed! (Continuing)";
             continue;
diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h
index b907a921bb7..97005649e42 100644
--- a/src/plugins/projectexplorer/project.h
+++ b/src/plugins/projectexplorer/project.h
@@ -94,8 +94,6 @@ public:
     void setActiveTarget(Target *target);
     Target *target(const QString &id) const;
 
-    virtual ITargetFactory *targetFactory() const = 0;
-
     void saveSettings();
     bool restoreSettings();
 
diff --git a/src/plugins/projectexplorer/targetsettingspanel.cpp b/src/plugins/projectexplorer/targetsettingspanel.cpp
index 6de64ac2730..f1d00aac9e2 100644
--- a/src/plugins/projectexplorer/targetsettingspanel.cpp
+++ b/src/plugins/projectexplorer/targetsettingspanel.cpp
@@ -200,7 +200,17 @@ void TargetSettingsPanelWidget::currentTargetChanged(int targetIndex, int subInd
 void TargetSettingsPanelWidget::addTarget(QAction *action)
 {
     QString id = action->data().toString();
-    Target *target(m_project->targetFactory()->create(m_project, id));
+    QList<ITargetFactory *> factories =
+            ExtensionSystem::PluginManager::instance()->getObjects<ITargetFactory>();
+
+    Target *target = 0;
+    foreach (ITargetFactory *fac, factories) {
+        if (fac->canCreate(m_project, id)) {
+            target = fac->create(m_project, id);
+            break;
+        }
+    }
+
     if (!target)
         return;
     m_project->addTarget(target);
@@ -267,8 +277,20 @@ void TargetSettingsPanelWidget::updateTargetAddAndRemoveButtons()
 
     m_addMenu->clear();
 
+    QList<ITargetFactory *> factories =
+            ExtensionSystem::PluginManager::instance()->getObjects<ITargetFactory>();
+
     foreach (const QString &id, m_project->possibleTargetIds()) {
-        QString displayName = m_project->targetFactory()->displayNameForId(id);
+        QString displayName;
+        foreach (ITargetFactory *fac, factories) {
+            if (fac->supportsTargetId(id)) {
+                displayName = fac->displayNameForId(id);
+                break;
+            }
+        }
+        if (displayName.isEmpty())
+            continue;
+
         QAction *action = new QAction(displayName, m_addMenu);
         action->setData(QVariant(id));
         bool added = false;
diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp
index 29c1c103697..bb43ea94fd7 100644
--- a/src/plugins/qmlprojectmanager/qmlproject.cpp
+++ b/src/plugins/qmlprojectmanager/qmlproject.cpp
@@ -32,6 +32,7 @@
 #include "qmlprojectmanagerconstants.h"
 #include "fileformat/qmlprojectitem.h"
 #include "qmlprojectrunconfiguration.h"
+#include "qmlprojecttarget.h"
 
 #include <coreplugin/icore.h>
 #include <coreplugin/messagemanager.h>
@@ -51,8 +52,7 @@ QmlProject::QmlProject(Internal::Manager *manager, const QString &fileName)
     : m_manager(manager),
       m_fileName(fileName),
       m_modelManager(ExtensionSystem::PluginManager::instance()->getObject<QmlJS::ModelManagerInterface>()),
-      m_fileWatcher(new ProjectExplorer::FileWatcher(this)),
-      m_targetFactory(new Internal::QmlProjectTargetFactory(this))
+      m_fileWatcher(new ProjectExplorer::FileWatcher(this))
 {
     setSupportedTargetIds(QSet<QString>() << QLatin1String(Constants::QML_VIEWER_TARGET_ID));
     QFileInfo fileInfo(m_fileName);
@@ -238,11 +238,6 @@ QList<ProjectExplorer::BuildConfigWidget*> QmlProject::subConfigWidgets()
     return QList<ProjectExplorer::BuildConfigWidget*>();
 }
 
-Internal::QmlProjectTargetFactory *QmlProject::targetFactory() const
-{
-    return m_targetFactory;
-}
-
 Internal::QmlProjectTarget *QmlProject::activeTarget() const
 {
     return static_cast<Internal::QmlProjectTarget *>(Project::activeTarget());
@@ -264,7 +259,9 @@ bool QmlProject::fromMap(const QVariantMap &map)
         return false;
 
     if (targets().isEmpty()) {
-        Internal::QmlProjectTarget *target(targetFactory()->create(this, QLatin1String(Constants::QML_VIEWER_TARGET_ID)));
+        Internal::QmlProjectTargetFactory *factory
+                = ExtensionSystem::PluginManager::instance()->getObject<Internal::QmlProjectTargetFactory>();
+        Internal::QmlProjectTarget *target = factory->create(this, QLatin1String(Constants::QML_VIEWER_TARGET_ID));
         addTarget(target);
     }
 
diff --git a/src/plugins/qmlprojectmanager/qmlproject.h b/src/plugins/qmlprojectmanager/qmlproject.h
index b895982b2f2..0f663eef18b 100644
--- a/src/plugins/qmlprojectmanager/qmlproject.h
+++ b/src/plugins/qmlprojectmanager/qmlproject.h
@@ -72,7 +72,6 @@ public:
     QString id() const;
     Core::IFile *file() const;
     Internal::Manager *projectManager() const;
-    Internal::QmlProjectTargetFactory *targetFactory() const;
     Internal::QmlProjectTarget *activeTarget() const;
 
     QList<ProjectExplorer::Project *> dependsOn();
@@ -127,8 +126,6 @@ private:
     ProjectExplorer::FileWatcher *m_fileWatcher;
 
     Internal::QmlProjectNode *m_rootNode;
-    Internal::QmlProjectTargetFactory *m_targetFactory;
-
 };
 
 } // namespace QmlProjectManager
diff --git a/src/plugins/qmlprojectmanager/qmlprojecttarget.cpp b/src/plugins/qmlprojectmanager/qmlprojecttarget.cpp
index f79b7c433f6..000f92e0cff 100644
--- a/src/plugins/qmlprojectmanager/qmlprojecttarget.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojecttarget.cpp
@@ -132,13 +132,13 @@ QmlProjectTarget *QmlProjectTargetFactory::create(ProjectExplorer::Project *pare
     if (!canCreate(parent, id))
         return 0;
     QmlProject *qmlproject(static_cast<QmlProject *>(parent));
-    QmlProjectTarget *t(new QmlProjectTarget(qmlproject));
+    QmlProjectTarget *target = new QmlProjectTarget(qmlproject);
 
     // Add RunConfiguration (QML does not have BuildConfigurations)
-    QmlProjectRunConfiguration *runConf(new QmlProjectRunConfiguration(t));
-    t->addRunConfiguration(runConf);
+    QmlProjectRunConfiguration *runConf = new QmlProjectRunConfiguration(target);
+    target->addRunConfiguration(runConf);
 
-    return t;
+    return target;
 }
 
 bool QmlProjectTargetFactory::canRestore(ProjectExplorer::Project *parent, const QVariantMap &map) const
diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp
index 6e43de33aff..689340d7afa 100644
--- a/src/plugins/qt4projectmanager/qt4project.cpp
+++ b/src/plugins/qt4projectmanager/qt4project.cpp
@@ -249,7 +249,6 @@ Qt4Project::Qt4Project(Qt4Manager *manager, const QString& fileName) :
     m_manager(manager),
     m_rootProjectNode(0),
     m_nodesWatcher(new Internal::Qt4NodesWatcher(this)),
-    m_targetFactory(new Qt4TargetFactory(this)),
     m_fileInfo(new Qt4ProjectFile(this, fileName, this)),
     m_projectFiles(new Qt4ProjectFiles),
     m_proFileOption(0),
@@ -355,11 +354,6 @@ bool Qt4Project::fromMap(const QVariantMap &map)
     return true;
 }
 
-Qt4TargetFactory *Qt4Project::targetFactory() const
-{
-    return m_targetFactory;
-}
-
 Qt4Target *Qt4Project::activeTarget() const
 {
     return static_cast<Qt4Target *>(Project::activeTarget());
diff --git a/src/plugins/qt4projectmanager/qt4project.h b/src/plugins/qt4projectmanager/qt4project.h
index 3807cf86d67..a98941738bd 100644
--- a/src/plugins/qt4projectmanager/qt4project.h
+++ b/src/plugins/qt4projectmanager/qt4project.h
@@ -151,8 +151,6 @@ public:
     ProjectExplorer::IProjectManager *projectManager() const;
     Qt4Manager *qt4ProjectManager() const;
 
-    Internal::Qt4TargetFactory *targetFactory() const;
-
     Qt4Target *activeTarget() const;
 
     QList<Core::IFile *> dependencies();     //NBS remove
@@ -239,7 +237,6 @@ private:
     Qt4Manager *m_manager;
     Internal::Qt4ProFileNode *m_rootProjectNode;
     Internal::Qt4NodesWatcher *m_nodesWatcher;
-    Internal::Qt4TargetFactory *m_targetFactory;
 
     Qt4ProjectFile *m_fileInfo;
 
diff --git a/src/plugins/qt4projectmanager/wizards/targetsetuppage.cpp b/src/plugins/qt4projectmanager/wizards/targetsetuppage.cpp
index b8f35530b5a..1a4fb986786 100644
--- a/src/plugins/qt4projectmanager/wizards/targetsetuppage.cpp
+++ b/src/plugins/qt4projectmanager/wizards/targetsetuppage.cpp
@@ -243,6 +243,10 @@ bool TargetSetupPage::setupProject(Qt4ProjectManager::Qt4Project *project)
     Q_ASSERT(project->targets().isEmpty());
     QtVersionManager *vm = QtVersionManager::instance();
 
+    // TODO remove again
+    Qt4TargetFactory *factory =
+            ExtensionSystem::PluginManager::instance()->getObject<Qt4TargetFactory>();
+
     for (int i = 0; i < m_ui->versionTree->topLevelItemCount(); ++i) {
         QTreeWidgetItem *current = m_ui->versionTree->topLevelItem(i);
         QString targetId = current->data(NAME_COLUMN, Qt::UserRole).toString();
@@ -275,7 +279,7 @@ bool TargetSetupPage::setupProject(Qt4ProjectManager::Qt4Project *project)
         // create the target:
         Qt4Target *target = 0;
         if (!targetInfos.isEmpty())
-            target = project->targetFactory()->create(project, targetId, targetInfos);
+            target = factory->create(project, targetId, targetInfos);
 
         if (target) {
             project->addTarget(target);
@@ -286,7 +290,7 @@ bool TargetSetupPage::setupProject(Qt4ProjectManager::Qt4Project *project)
 
     // Create the default target if nothing else was set up:
     if (project->targets().isEmpty()) {
-        Qt4Target *target = project->targetFactory()->create(project, Constants::DESKTOP_TARGET_ID);
+        Qt4Target *target = factory->create(project, Constants::DESKTOP_TARGET_ID);
         if (target)
             project->addTarget(target);
     }
-- 
GitLab