From 6f45ec97f8c25fe94afbbd58380d9847b25c1462 Mon Sep 17 00:00:00 2001
From: Daniel Teske <daniel.teske@nokia.com>
Date: Tue, 6 Mar 2012 13:14:42 +0100
Subject: [PATCH] Automatically configure examples opened from the welcome
 page.

Each example can now provide a list of platforms by the examples manifest
.xml file. This list can control the target configuration of the example
when it is opened in the welcomepage.

Change-Id: I893230fd2850b7a1272db71a7f589044d52041d1
Reviewed-by: hjk <qthjk@ovi.com>
---
 .../welcomescreen/widgets/Delegate.qml        |  2 +-
 .../projectexplorer/iprojectproperties.h      |  2 --
 src/plugins/projectexplorer/project.cpp       |  5 +++
 src/plugins/projectexplorer/project.h         |  1 +
 .../projectexplorer/projectexplorer.cpp       |  5 +++
 src/plugins/projectexplorer/projectexplorer.h |  3 ++
 src/plugins/projectexplorer/projectwindow.cpp |  4 ---
 src/plugins/projectexplorer/projectwindow.h   |  2 +-
 src/plugins/qt4projectmanager/qt4project.cpp  | 32 +++++++++++++++++++
 src/plugins/qt4projectmanager/qt4project.h    |  2 ++
 .../unconfiguredprojectpanel.cpp              |  5 ++-
 .../unconfiguredprojectpanel.h                |  2 --
 src/plugins/qtsupport/exampleslistmodel.cpp   | 18 +++++++++--
 src/plugins/qtsupport/exampleslistmodel.h     |  3 +-
 .../qtsupport/gettingstartedwelcomepage.cpp   | 19 +++++++++--
 .../qtsupport/gettingstartedwelcomepage.h     |  2 +-
 16 files changed, 88 insertions(+), 19 deletions(-)

diff --git a/share/qtcreator/welcomescreen/widgets/Delegate.qml b/share/qtcreator/welcomescreen/widgets/Delegate.qml
index 25e100d6abe..d2e8fe2b6fa 100644
--- a/share/qtcreator/welcomescreen/widgets/Delegate.qml
+++ b/share/qtcreator/welcomescreen/widgets/Delegate.qml
@@ -235,7 +235,7 @@ Rectangle {
             if (model.isVideo)
                 gettingStarted.openUrl(model.videoUrl);
             else if (model.hasSourceCode)
-                gettingStarted.openProject(model.projectPath, model.filesToOpen, model.docUrl, model.dependencies)
+                gettingStarted.openProject(model.projectPath, model.filesToOpen, model.docUrl, model.dependencies, model.platforms)
             else
                 gettingStarted.openSplitHelp(model.docUrl);
         }
diff --git a/src/plugins/projectexplorer/iprojectproperties.h b/src/plugins/projectexplorer/iprojectproperties.h
index 110b4f9a535..b86d3351e94 100644
--- a/src/plugins/projectexplorer/iprojectproperties.h
+++ b/src/plugins/projectexplorer/iprojectproperties.h
@@ -87,8 +87,6 @@ class PROJECTEXPLORER_EXPORT IProjectPanelFactory : public IPanelFactory
 public:
     virtual bool supports(Project *project) = 0;
     virtual PropertiesPanel *createPanel(Project *project) = 0;
-signals:
-    void projectUpdated(ProjectExplorer::Project *project);
 };
 
 class PROJECTEXPLORER_EXPORT ITargetPanelFactory : public IPanelFactory
diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp
index cb603226213..c50b612e0f2 100644
--- a/src/plugins/projectexplorer/project.cpp
+++ b/src/plugins/projectexplorer/project.cpp
@@ -388,4 +388,9 @@ bool Project::needsConfiguration() const
     return false;
 }
 
+void Project::configureAsExampleProject(const QStringList &platforms)
+{
+
+}
+
 } // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h
index b4f217c900f..1c8598acf82 100644
--- a/src/plugins/projectexplorer/project.h
+++ b/src/plugins/projectexplorer/project.h
@@ -118,6 +118,7 @@ public:
     void setNamedSettings(const QString &name, QVariant &value);
 
     virtual bool needsConfiguration() const;
+    virtual void configureAsExampleProject(const QStringList &platforms);
 
 signals:
     void fileListChanged();
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index 741309ebec6..95c1ffab642 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -1869,6 +1869,11 @@ void ProjectExplorerPlugin::buildProject(ProjectExplorer::Project *p)
           QStringList(QLatin1String(Constants::BUILDSTEPS_BUILD)));
 }
 
+void ProjectExplorerPlugin::requestProjectModeUpdate(Project *p)
+{
+    d->m_proWindow->projectUpdated(p);
+}
+
 void ProjectExplorerPlugin::buildProject()
 {
     queue(d->m_session->projectOrder(session()->startupProject()),
diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h
index c111150cb1a..70e8a5a4736 100644
--- a/src/plugins/projectexplorer/projectexplorer.h
+++ b/src/plugins/projectexplorer/projectexplorer.h
@@ -127,6 +127,9 @@ public:
     void addExistingFiles(const QStringList &filePaths);
 
     void buildProject(ProjectExplorer::Project *p);
+    /// Normally there's no need to call this function.
+    /// This function needs to be called, only if the pages that support a project changed.
+    void requestProjectModeUpdate(ProjectExplorer::Project *p);
 
     QList<RunControl *> runControls() const;
 
diff --git a/src/plugins/projectexplorer/projectwindow.cpp b/src/plugins/projectexplorer/projectwindow.cpp
index 5ea53f46c16..ceddef50bd6 100644
--- a/src/plugins/projectexplorer/projectwindow.cpp
+++ b/src/plugins/projectexplorer/projectwindow.cpp
@@ -268,10 +268,6 @@ void ProjectWindow::extensionsInitialized()
 
     QList<IProjectPanelFactory *> list = ExtensionSystem::PluginManager::instance()->getObjects<IProjectPanelFactory>();
     qSort(list.begin(), list.end(), &IPanelFactory::prioritySort);
-    foreach (IProjectPanelFactory *fac, list)
-        connect (fac, SIGNAL(projectUpdated(ProjectExplorer::Project*)),
-                 this, SLOT(projectUpdated(ProjectExplorer::Project*)));
-
 }
 
 void ProjectWindow::aboutToShutdown()
diff --git a/src/plugins/projectexplorer/projectwindow.h b/src/plugins/projectexplorer/projectwindow.h
index c4f372a09e2..8a5be9f2f94 100644
--- a/src/plugins/projectexplorer/projectwindow.h
+++ b/src/plugins/projectexplorer/projectwindow.h
@@ -82,6 +82,7 @@ public:
 
     void aboutToShutdown();
     void extensionsInitialized();
+    void projectUpdated(ProjectExplorer::Project *p);
 private slots:
     void targetFactoriesChanged();
     void showProperties(int index, int subIndex);
@@ -90,7 +91,6 @@ private slots:
     void registerProject(ProjectExplorer::Project*);
     void deregisterProject(ProjectExplorer::Project*);
     void startupProjectChanged(ProjectExplorer::Project *);
-    void projectUpdated(ProjectExplorer::Project *p);
 
 private:
     bool useTargetPage(ProjectExplorer::Project *project);
diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp
index e935e5cea36..bb7a8301938 100644
--- a/src/plugins/qt4projectmanager/qt4project.cpp
+++ b/src/plugins/qt4projectmanager/qt4project.cpp
@@ -41,6 +41,8 @@
 #include "qt4projectmanagerconstants.h"
 #include "qt4buildconfiguration.h"
 #include "findqt4profiles.h"
+#include "qt4basetargetfactory.h"
+#include "buildconfigurationinfo.h"
 
 #include <coreplugin/icore.h>
 #include <coreplugin/idocument.h>
@@ -1334,6 +1336,36 @@ bool Qt4Project::needsConfiguration() const
     return targets().isEmpty();
 }
 
+void Qt4Project::configureAsExampleProject(const QStringList &platforms)
+{
+    QList<Qt4BaseTargetFactory *> factories = ExtensionSystem::PluginManager::instance()->getObjects<Qt4BaseTargetFactory>();
+    foreach (Qt4BaseTargetFactory *factory, factories) {
+        foreach (const QString &id, factory->supportedTargetIds()) {
+            QList<BuildConfigurationInfo> infos
+                    = factory->availableBuildConfigurations(id, rootProjectNode()->path(),
+                                                            QtSupport::QtVersionNumber(),
+                                                            QtSupport::QtVersionNumber(INT_MAX, INT_MAX, INT_MAX),
+                                                            Core::FeatureSet());
+            if (!platforms.isEmpty()) {
+                QList<BuildConfigurationInfo> filtered;
+                foreach (const BuildConfigurationInfo &info, infos) {
+                    foreach (const QString &platform, platforms) {
+                        if (info.version()->supportsPlatform(platform)) {
+                            filtered << info;
+                            break;
+                        }
+                    }
+                }
+                infos = filtered;
+            }
+
+            if (!infos.isEmpty())
+                addTarget(factory->create(this, id, infos));
+        }
+    }
+    ProjectExplorer::ProjectExplorerPlugin::instance()->requestProjectModeUpdate(this);
+}
+
 /*!
   Handle special case were a subproject of the qt directory is opened, and
   qt was configured to be built as a shadow build -> also build in the sub-
diff --git a/src/plugins/qt4projectmanager/qt4project.h b/src/plugins/qt4projectmanager/qt4project.h
index 4b57c4f1e51..8b2f5817a71 100644
--- a/src/plugins/qt4projectmanager/qt4project.h
+++ b/src/plugins/qt4projectmanager/qt4project.h
@@ -140,6 +140,8 @@ public:
 
     bool needsConfiguration() const;
 
+    void configureAsExampleProject(const QStringList &platforms);
+
 signals:
     void proParsingDone();
     void proFileUpdated(Qt4ProjectManager::Qt4ProFileNode *node, bool, bool);
diff --git a/src/plugins/qt4projectmanager/unconfiguredprojectpanel.cpp b/src/plugins/qt4projectmanager/unconfiguredprojectpanel.cpp
index 0481e059ffa..ad088177801 100644
--- a/src/plugins/qt4projectmanager/unconfiguredprojectpanel.cpp
+++ b/src/plugins/qt4projectmanager/unconfiguredprojectpanel.cpp
@@ -43,6 +43,7 @@
 #include <coreplugin/coreconstants.h>
 
 #include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/projectexplorer.h>
 #include <projectexplorer/toolchain.h>
 
 #include <QLabel>
@@ -87,8 +88,6 @@ ProjectExplorer::PropertiesPanel *Qt4ProjectManager::Internal::UnconfiguredProje
     panel->setIcon(QIcon(":/projectexplorer/images/unconfigured.png"));
 
     TargetSetupPageWrapper *w = new TargetSetupPageWrapper(project);
-    connect (w, SIGNAL(projectUpdated(ProjectExplorer::Project*)),
-             this, SIGNAL(projectUpdated(ProjectExplorer::Project*)));
     panel->setWidget(w);
     return panel;
 }
@@ -188,7 +187,7 @@ void TargetSetupPageWrapper::keyReleaseEvent(QKeyEvent *event)
 void TargetSetupPageWrapper::done()
 {
     m_targetSetupPage->setupProject(m_project);
-    emit projectUpdated(m_project);
+    ProjectExplorer::ProjectExplorerPlugin::instance()->requestProjectModeUpdate(m_project);
     Core::ICore::instance()->modeManager()->activateMode(QLatin1String(Core::Constants::MODE_EDIT));
 }
 
diff --git a/src/plugins/qt4projectmanager/unconfiguredprojectpanel.h b/src/plugins/qt4projectmanager/unconfiguredprojectpanel.h
index c8a00cf3cde..6466108f3e2 100644
--- a/src/plugins/qt4projectmanager/unconfiguredprojectpanel.h
+++ b/src/plugins/qt4projectmanager/unconfiguredprojectpanel.h
@@ -65,8 +65,6 @@ public:
 protected:
     void keyReleaseEvent(QKeyEvent *event);
     void keyPressEvent(QKeyEvent *event);
-signals:
-    void projectUpdated(ProjectExplorer::Project *project);
 private slots:
     void done();
     void noteTextLinkActivated();
diff --git a/src/plugins/qtsupport/exampleslistmodel.cpp b/src/plugins/qtsupport/exampleslistmodel.cpp
index c3ea5d3e7d2..36324d3c3b7 100644
--- a/src/plugins/qtsupport/exampleslistmodel.cpp
+++ b/src/plugins/qtsupport/exampleslistmodel.cpp
@@ -73,6 +73,7 @@ ExamplesListModel::ExamplesListModel(QObject *parent) :
     roleNames[IsVideo] = "isVideo";
     roleNames[VideoUrl] = "videoUrl";
     roleNames[VideoLength] = "videoLength";
+    roleNames[Platforms] = "platforms";
     setRoleNames(roleNames);
 
     connect(Core::HelpManager::instance(), SIGNAL(setupFinished()),
@@ -91,6 +92,15 @@ static inline QString fixStringForTags(const QString &string)
     return returnString;
 }
 
+static inline QStringList trimStringList(const QStringList &stringlist)
+{
+    QStringList returnList;
+    foreach (const QString &string, stringlist)
+        returnList << string.trimmed();
+
+    return returnList;
+}
+
 QList<ExampleItem> ExamplesListModel::parseExamples(QXmlStreamReader* reader, const QString& projectsOffset)
 {
     QList<ExampleItem> examples;
@@ -117,9 +127,11 @@ QList<ExampleItem> ExamplesListModel::parseExamples(QXmlStreamReader* reader, co
             } else if (reader->name() == QLatin1String("dependency")) {
                 item.dependencies.append(projectsOffset + slash + reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement));
             } else if (reader->name() == QLatin1String("tags")) {
-                item.tags = reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement).split(QLatin1Char(','));
+                item.tags = trimStringList(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement).split(QLatin1Char(','), QString::SkipEmptyParts));
                 m_tags.append(item.tags);
-            }
+            } else if (reader->name() == QLatin1String("platforms")) {
+                item.platforms = trimStringList(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement).split(QLatin1Char(','), QString::SkipEmptyParts));
+        }
             break;
         case QXmlStreamReader::EndElement:
             if (reader->name() == QLatin1String("example"))
@@ -429,6 +441,8 @@ QVariant ExamplesListModel::data(const QModelIndex &index, int role) const
         return item.videoUrl;
     case VideoLength:
         return item.videoLength;
+    case Platforms:
+        return item.platforms;
     default:
         qDebug() << Q_FUNC_INFO << "role type not supported";
         return QVariant();
diff --git a/src/plugins/qtsupport/exampleslistmodel.h b/src/plugins/qtsupport/exampleslistmodel.h
index 75f98e1c1e9..c56f4b6ed7c 100644
--- a/src/plugins/qtsupport/exampleslistmodel.h
+++ b/src/plugins/qtsupport/exampleslistmodel.h
@@ -43,7 +43,7 @@ namespace Internal {
 
 enum ExampleRoles { Name=Qt::UserRole, ProjectPath, Description, ImageUrl,
                     DocUrl,  FilesToOpen, Tags, Difficulty, HasSourceCode,
-                    Type, Dependencies, IsVideo, VideoUrl, VideoLength };
+                    Type, Dependencies, IsVideo, VideoUrl, VideoLength, Platforms };
 
 enum InstructionalType { Example=0, Demo, Tutorial };
 
@@ -63,6 +63,7 @@ struct ExampleItem {
     bool isVideo;
     QString videoUrl;
     QString videoLength;
+    QStringList platforms;
 };
 
 class ExamplesListModel : public QAbstractListModel {
diff --git a/src/plugins/qtsupport/gettingstartedwelcomepage.cpp b/src/plugins/qtsupport/gettingstartedwelcomepage.cpp
index 496094ee923..1b49f3fd701 100644
--- a/src/plugins/qtsupport/gettingstartedwelcomepage.cpp
+++ b/src/plugins/qtsupport/gettingstartedwelcomepage.cpp
@@ -44,6 +44,9 @@
 #include <coreplugin/icore.h>
 #include <coreplugin/helpmanager.h>
 #include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/session.h>
+#include <projectexplorer/project.h>
+#include <projectexplorer/projectnodes.h>
 
 #include <QMutex>
 #include <QThread>
@@ -389,7 +392,7 @@ QString ExamplesWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileI
 }
 
 void ExamplesWelcomePage::openProject(const QString &projectFile, const QStringList &additionalFilesToOpen,
-                                            const QUrl &help, const QStringList &dependencies)
+                                            const QUrl &help, const QStringList &dependencies, const QStringList &platforms)
 {
     QString proFile = projectFile;
     if (proFile.isEmpty())
@@ -403,12 +406,24 @@ void ExamplesWelcomePage::openProject(const QString &projectFile, const QStringL
 
     // don't try to load help and files if loading the help request is being cancelled
     QString errorMessage;
-    if (!proFile.isEmpty() && ProjectExplorer::ProjectExplorerPlugin::instance()->openProject(proFile, &errorMessage)) {
+    ProjectExplorer::ProjectExplorerPlugin *peplugin = ProjectExplorer::ProjectExplorerPlugin::instance();
+    if (!proFile.isEmpty() && peplugin->openProject(proFile, &errorMessage)) {
         Core::ICore::openFiles(filesToOpen);
         Core::ICore::helpManager()->handleHelpRequest(help.toString()+QLatin1String("?view=split"));
     }
     if (!errorMessage.isEmpty())
         QMessageBox::critical(Core::ICore::mainWindow(), tr("Failed to open project"), errorMessage);
+    // Configure project for building
+    ProjectExplorer::Project *project = 0;
+    foreach (ProjectExplorer::Project *pro, peplugin->session()->projects()) {
+        if (pro->rootProjectNode()->path() == proFile) {
+            project = pro;
+            break;
+        }
+    }
+    if (project && project->needsConfiguration())
+        project->configureAsExampleProject(platforms);
+
 }
 
 void ExamplesWelcomePage::updateTagsModel()
diff --git a/src/plugins/qtsupport/gettingstartedwelcomepage.h b/src/plugins/qtsupport/gettingstartedwelcomepage.h
index 678b9bea02d..1b7855572ef 100644
--- a/src/plugins/qtsupport/gettingstartedwelcomepage.h
+++ b/src/plugins/qtsupport/gettingstartedwelcomepage.h
@@ -88,7 +88,7 @@ public slots:
     void openSplitHelp(const QUrl &help);
     void openHelp(const QUrl &help);
     void openProject(const QString& projectFile, const QStringList& additionalFilesToOpen,
-                     const QUrl& help, const QStringList &dependencies);
+                     const QUrl& help, const QStringList &dependencies, const QStringList &platforms);
     void updateTagsModel();
 
 private:
-- 
GitLab