From 5ce3f8ab7a4b9b0ef93b732ff306343518d29fcc Mon Sep 17 00:00:00 2001
From: Pawel Polanski <pawel.3.polanski@nokia.com>
Date: Sat, 11 Sep 2010 10:33:14 +0200
Subject: [PATCH] Symbian target supports sub-projects.

Reviewed-by: Tobias Hunger
---
 .../qt-s60/s60deployconfiguration.cpp         | 138 ++++--------------
 .../qt-s60/s60deployconfiguration.h           |   9 +-
 .../qt-s60/s60devicerunconfiguration.cpp      | 127 +++++++++++++++-
 .../qt-s60/s60devicerunconfiguration.h        |   9 ++
 4 files changed, 158 insertions(+), 125 deletions(-)

diff --git a/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp
index 10e9c22d476..bbb5e0b086d 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp
@@ -111,7 +111,7 @@ void S60DeployConfiguration::ctor()
 {
     setDefaultDisplayName(defaultDisplayName());
     connect(qt4Target()->qt4Project(), SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
-            this, SLOT(proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode*)));
+            this, SIGNAL(targetInformationChanged()));
     connect(qt4Target(), SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
             this, SLOT(updateActiveBuildConfiguration(ProjectExplorer::BuildConfiguration*)));
     connect(qt4Target(), SIGNAL(activeRunConfigurationChanged(ProjectExplorer::RunConfiguration*)),
@@ -128,13 +128,6 @@ ProjectExplorer::DeployConfigurationWidget *S60DeployConfiguration::configuratio
     return new S60DeployConfigurationWidget();
 }
 
-void S60DeployConfiguration::proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
-{
-    S60DeviceRunConfiguration *deviceRunConf = s60DeviceRunConf();
-    if (deviceRunConf && deviceRunConf->projectFilePath() == pro->path())
-        emit targetInformationChanged();
-}
-
 QStringList S60DeployConfiguration::signedPackages() const
 {
     QList<Qt4ProFileNode *> list = qt4Target()->qt4Project()->leafProFiles();
@@ -149,22 +142,23 @@ QStringList S60DeployConfiguration::signedPackages() const
     return result;
 }
 
-QString S60DeployConfiguration::appSignedPackage() const
+QStringList S60DeployConfiguration::appSignedPackages() const
 {
-    S60DeviceRunConfiguration *deviceRunConf = s60DeviceRunConf();
-    Q_ASSERT(deviceRunConf);
-    TargetInformation ti = qt4Target()->qt4Project()->rootProjectNode()->targetInformation(deviceRunConf->projectFilePath());
-    if (!ti.valid)
-        return QString();
-    return ti.buildDir + QLatin1Char('/') + ti.target
-            + (runSmartInstaller() ? QLatin1String("_installer") : QLatin1String(""))
-            + QLatin1String(".sis");
+    QList<Qt4ProFileNode *> list = qt4Target()->qt4Project()->leafProFiles();
+    QStringList result;
+    foreach (Qt4ProFileNode *node, list) {
+        TargetInformation ti = node->targetInformation();
+        if (ti.valid)
+            result << ti.buildDir + QLatin1Char('/') + ti.target
+                      + (runSmartInstaller() ? QLatin1String("_installer") : QLatin1String(""))
+                      + QLatin1String(".sis");
+    }
+    return result;
 }
 
 QStringList S60DeployConfiguration::packageFileNamesWithTargetInfo() const
 {
     QList<Qt4ProFileNode *> leafs = qt4Target()->qt4Project()->leafProFiles();
-
     QStringList result;
     foreach (Qt4ProFileNode *qt4ProFileNode, leafs) {
         TargetInformation ti = qt4ProFileNode->targetInformation();
@@ -191,84 +185,16 @@ QStringList S60DeployConfiguration::packageTemplateFileNames() const
     return result;
 }
 
-QString S60DeployConfiguration::appPackageTemplateFileName() const
-{
-    S60DeviceRunConfiguration *deviceRunConf = s60DeviceRunConf();
-    Q_ASSERT(deviceRunConf);
-    TargetInformation ti = qt4Target()->qt4Project()->rootProjectNode()->targetInformation(deviceRunConf->projectFilePath());
-    if (!ti.valid)
-        return QString();
-    return ti.buildDir + QLatin1Char('/') + ti.target + QLatin1String("_template.pkg");
-}
-
-/* Grep a package file for the '.exe' file. Curently for use on Linux only
- * as the '.pkg'-files on Windows do not contain drive letters, which is not
- * handled here. \code
-; Executable and default resource files
-"./foo.exe"    - "!:\sys\bin\foo.exe"
-\endcode  */
-
-static inline QString executableFromPackageUnix(const QString &packageFileName)
-{
-    QFile packageFile(packageFileName);
-    if (!packageFile.open(QIODevice::ReadOnly|QIODevice::Text))
-        return QString();
-    QRegExp pattern(QLatin1String("^\"(.*.exe)\" *- \"!:.*.exe\"$"));
-    QTC_ASSERT(pattern.isValid(), return QString());
-    foreach(const QString &line, QString::fromLocal8Bit(packageFile.readAll()).split(QLatin1Char('\n')))
-        if (pattern.exactMatch(line)) {
-            // Expand relative paths by package file paths
-            QString rc = pattern.cap(1);
-            if (rc.startsWith(QLatin1String("./")))
-                rc.remove(0, 2);
-            const QFileInfo fi(rc);
-            if (fi.isAbsolute())
-                return rc;
-            return QFileInfo(packageFileName).absolutePath() + QLatin1Char('/') + rc;
-        }
-    return QString();
-}
-
-QString S60DeployConfiguration::localExecutableFileName() const
+QStringList S60DeployConfiguration::appPackageTemplateFileNames() const
 {
-    QString localExecutable;
-    switch (toolChainType()) {
-    case ToolChain::GCCE_GNUPOC:
-    case ToolChain::RVCT_ARMV5_GNUPOC:
-        localExecutable = executableFromPackageUnix(appPackageTemplateFileName());
-        break;
-    default: {
-            const QtVersion *qtv = qtVersion();
-            QTC_ASSERT(qtv, return QString());
-            const S60Devices::Device device = S60Manager::instance()->deviceForQtVersion(qtv);
-            QTextStream(&localExecutable) << device.epocRoot << "/epoc32/release/"
-                    << symbianPlatform() << '/' << symbianTarget() << '/' << targetName()
-                    << ".exe";
-        }
-        break;
-    }
-    return QDir::toNativeSeparators(localExecutable);
-}
-
-quint32 S60DeployConfiguration::executableUid() const
-{
-    quint32 uid = 0;
-    QString executablePath(localExecutableFileName());
-    if (!executablePath.isEmpty()) {
-        QFile file(executablePath);
-        if (file.open(QIODevice::ReadOnly)) {
-            // executable's UID is 4 bytes starting at 8.
-            const QByteArray data = file.read(12);
-            if (data.size() == 12) {
-                const unsigned char *d = reinterpret_cast<const unsigned char*>(data.data() + 8);
-                uid = *d++;
-                uid += *d++ << 8;
-                uid += *d++ << 16;
-                uid += *d++ << 24;
-            }
-        }
+    QList<Qt4ProFileNode *> list = qt4Target()->qt4Project()->leafProFiles();
+    QStringList result;
+    foreach (Qt4ProFileNode *node, list) {
+        TargetInformation ti = node->targetInformation();
+        if (ti.valid)
+            result << ti.buildDir + QLatin1Char('/') + ti.target + QLatin1String("_template.pkg");
     }
-    return uid;
+    return result;
 }
 
 bool S60DeployConfiguration::runSmartInstaller() const
@@ -293,16 +219,6 @@ ProjectExplorer::ToolChain::ToolChainType S60DeployConfiguration::toolChainType(
     return ProjectExplorer::ToolChain::INVALID;
 }
 
-QString S60DeployConfiguration::targetName() const
-{
-    S60DeviceRunConfiguration *deviceRunConf = s60DeviceRunConf();
-    Q_ASSERT(deviceRunConf);
-    TargetInformation ti = qt4Target()->qt4Project()->rootProjectNode()->targetInformation(deviceRunConf->projectFilePath());
-    if (!ti.valid)
-        return QString();
-    return ti.target;
-}
-
 QString S60DeployConfiguration::symbianPlatform() const
 {
     const Qt4BuildConfiguration *qt4bc = qt4Target()->activeBuildConfiguration();
@@ -353,11 +269,6 @@ void S60DeployConfiguration::updateActiveRunConfiguration(ProjectExplorer::RunCo
     setDefaultDisplayName(defaultDisplayName());
 }
 
-S60DeviceRunConfiguration* S60DeployConfiguration::s60DeviceRunConf() const
-{
-    return qobject_cast<S60DeviceRunConfiguration *>(qt4Target()->activeRunConfiguration());
-}
-
 QVariantMap S60DeployConfiguration::toMap() const
 {
     QVariantMap map(ProjectExplorer::DeployConfiguration::toMap());
@@ -370,9 +281,12 @@ QVariantMap S60DeployConfiguration::toMap() const
 
 QString S60DeployConfiguration::defaultDisplayName() const
 {
-    S60DeviceRunConfiguration* runConf = s60DeviceRunConf();
-    if (runConf && !runConf->projectFilePath().isEmpty())
-        return tr("Deploy %1 to Symbian device").arg(QFileInfo(runConf->projectFilePath()).completeBaseName());
+    QList<Qt4ProFileNode *> list = qt4Target()->qt4Project()->leafProFiles();
+    foreach (Qt4ProFileNode *node, list) {
+        TargetInformation ti = node->targetInformation();
+        if (ti.valid && !ti.buildDir.isEmpty())
+            return tr("Deploy %1 to Symbian device").arg(QFileInfo(ti.buildDir).completeBaseName());
+    }
     return tr("Deploy to Symbian device");
 }
 
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.h
index c8faf9892ba..8c49b1a4b2b 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.h
@@ -57,7 +57,6 @@ public:
 
     ProjectExplorer::DeployConfigurationWidget *configurationWidget() const;
 
-    QString targetName() const;
     const QtVersion *qtVersion() const;
     Qt4Target *qt4Target() const;
     ProjectExplorer::ToolChain::ToolChainType toolChainType() const;
@@ -72,12 +71,10 @@ public:
     void setSilentInstall(bool silent);
 
     QStringList signedPackages() const;
-    QString appSignedPackage() const;
+    QStringList appSignedPackages() const;
     QStringList packageFileNamesWithTargetInfo() const;
     QStringList packageTemplateFileNames() const;
-    QString appPackageTemplateFileName() const;
-    QString localExecutableFileName() const;
-    quint32 executableUid() const;
+    QStringList appPackageTemplateFileNames() const;
 
     QVariantMap toMap() const;
 
@@ -88,7 +85,6 @@ signals:
 private slots:
     void updateActiveBuildConfiguration(ProjectExplorer::BuildConfiguration *buildConfiguration);
     void updateActiveRunConfiguration(ProjectExplorer::RunConfiguration *runConfiguration);
-    void proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro);
 
 protected:
     S60DeployConfiguration(ProjectExplorer::Target *parent, S60DeployConfiguration *source);
@@ -97,7 +93,6 @@ protected:
 
 private:
     void ctor();
-    S60DeviceRunConfiguration* s60DeviceRunConf() const;
     bool runSmartInstaller() const;
     QString symbianPlatform() const;
     QString symbianTarget() const;
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
index 90ba2dc571f..6f223d2e815 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
@@ -224,6 +224,121 @@ static inline QString fixBaseNameTarget(const QString &in)
     return in;
 }
 
+QString S60DeviceRunConfiguration::targetName() const
+{
+    TargetInformation ti = qt4Target()->qt4Project()->rootProjectNode()->targetInformation(projectFilePath());
+    if (!ti.valid)
+        return QString();
+    return ti.target;
+}
+
+const QtVersion *S60DeviceRunConfiguration::qtVersion() const
+{
+    if (const BuildConfiguration *bc = target()->activeBuildConfiguration())
+        if (const Qt4BuildConfiguration *qt4bc = qobject_cast<const Qt4BuildConfiguration *>(bc))
+            return qt4bc->qtVersion();
+    return 0;
+}
+
+bool S60DeviceRunConfiguration::isDebug() const
+{
+    const Qt4BuildConfiguration *qt4bc = qt4Target()->activeBuildConfiguration();
+    return (qt4bc->qmakeBuildConfiguration() & QtVersion::DebugBuild);
+}
+
+QString S60DeviceRunConfiguration::symbianTarget() const
+{
+    return isDebug() ? QLatin1String("udeb") : QLatin1String("urel");
+}
+
+QString S60DeviceRunConfiguration::symbianPlatform() const
+{
+    const Qt4BuildConfiguration *qt4bc = qt4Target()->activeBuildConfiguration();
+    switch (qt4bc->toolChainType()) {
+    case ToolChain::GCCE:
+    case ToolChain::GCCE_GNUPOC:
+        return QLatin1String("gcce");
+    case ToolChain::RVCT_ARMV5:
+        return QLatin1String("armv5");
+    default: // including ToolChain::RVCT_ARMV6_GNUPOC:
+        return QLatin1String("armv6");
+    }
+}
+
+/* Grep a package file for the '.exe' file. Curently for use on Linux only
+ * as the '.pkg'-files on Windows do not contain drive letters, which is not
+ * handled here. \code
+; Executable and default resource files
+"./foo.exe"    - "!:\sys\bin\foo.exe"
+\endcode  */
+
+static inline QString executableFromPackageUnix(const QString &packageFileName)
+{
+    QFile packageFile(packageFileName);
+    if (!packageFile.open(QIODevice::ReadOnly|QIODevice::Text))
+        return QString();
+    QRegExp pattern(QLatin1String("^\"(.*.exe)\" *- \"!:.*.exe\"$"));
+    QTC_ASSERT(pattern.isValid(), return QString());
+    foreach(const QString &line, QString::fromLocal8Bit(packageFile.readAll()).split(QLatin1Char('\n')))
+        if (pattern.exactMatch(line)) {
+            // Expand relative paths by package file paths
+            QString rc = pattern.cap(1);
+            if (rc.startsWith(QLatin1String("./")))
+                rc.remove(0, 2);
+            const QFileInfo fi(rc);
+            if (fi.isAbsolute())
+                return rc;
+            return QFileInfo(packageFileName).absolutePath() + QLatin1Char('/') + rc;
+        }
+    return QString();
+}
+
+QString S60DeviceRunConfiguration::localExecutableFileName() const
+{
+    QString localExecutable;
+    switch (toolChainType()) {
+    case ToolChain::GCCE_GNUPOC:
+    case ToolChain::RVCT_ARMV5_GNUPOC: {
+        TargetInformation ti = qt4Target()->qt4Project()->rootProjectNode()->targetInformation(projectFilePath());
+        if (!ti.valid)
+            return QString();
+        localExecutable = executableFromPackageUnix(ti.buildDir + QLatin1Char('/') + ti.target + QLatin1String("_template.pkg"));
+        }
+        break;
+    default: {
+            const QtVersion *qtv = qtVersion();
+            QTC_ASSERT(qtv, return QString());
+            const S60Devices::Device device = S60Manager::instance()->deviceForQtVersion(qtv);
+            QTextStream(&localExecutable) << device.epocRoot << "/epoc32/release/"
+                    << symbianPlatform() << '/' << symbianTarget() << '/' << targetName()
+                    << ".exe";
+        }
+        break;
+    }
+    return QDir::toNativeSeparators(localExecutable);
+}
+
+quint32 S60DeviceRunConfiguration::executableUid() const
+{
+    quint32 uid = 0;
+    QString executablePath(localExecutableFileName());
+    if (!executablePath.isEmpty()) {
+        QFile file(executablePath);
+        if (file.open(QIODevice::ReadOnly)) {
+            // executable's UID is 4 bytes starting at 8.
+            const QByteArray data = file.read(12);
+            if (data.size() == 12) {
+                const unsigned char *d = reinterpret_cast<const unsigned char*>(data.data() + 8);
+                uid = *d++;
+                uid += *d++ << 8;
+                uid += *d++ << 16;
+                uid += *d++ << 24;
+            }
+        }
+    }
+    return uid;
+}
+
 QString S60DeviceRunConfiguration::projectFilePath() const
 {
     return m_proFilePath;
@@ -343,14 +458,14 @@ S60DeviceRunControl::S60DeviceRunControl(RunConfiguration *runConfiguration, QSt
     m_toolChain = s60runConfig->toolChainType();
     m_serialPortName = activeDeployConf->serialPortName();
     m_serialPortFriendlyName = SymbianUtils::SymbianDeviceManager::instance()->friendlyNameForPort(m_serialPortName);
-    m_targetName = activeDeployConf->targetName();
+    m_targetName = s60runConfig->targetName();
     m_commandLineArguments = s60runConfig->commandLineArguments();
     m_qtDir = activeBuildConf->qtVersion()->versionInfo().value("QT_INSTALL_DATA");
     m_installationDrive = activeDeployConf->installationDrive();
     if (const QtVersion *qtv = activeDeployConf->qtVersion())
         m_qtBinPath = qtv->versionInfo().value(QLatin1String("QT_INSTALL_BINS"));
     QTC_ASSERT(!m_qtBinPath.isEmpty(), return);
-    m_executableFileName = activeDeployConf->localExecutableFileName();
+    m_executableFileName = s60runConfig->localExecutableFileName();
     if (debug)
         qDebug() << "S60DeviceRunControl::CT" << m_targetName << ProjectExplorer::ToolChain::toolChainName(m_toolChain)
                  << m_serialPortName;
@@ -585,8 +700,8 @@ void S60DeviceRunControl::applicationRunFailedNotice(const QString &errorMessage
 
 static inline QString localExecutable(const S60DeviceRunConfiguration *rc)
 {
-    if (const S60DeployConfiguration *activeDeployConf = qobject_cast<S60DeployConfiguration *>(rc->qt4Target()->activeDeployConfiguration()))
-        return activeDeployConf->localExecutableFileName();
+    if (const S60DeviceRunConfiguration *s60runConfig = qobject_cast<const S60DeviceRunConfiguration *>(rc))
+        return s60runConfig->localExecutableFileName();
     return QString();
 }
 
@@ -599,14 +714,14 @@ Debugger::DebuggerStartParameters S60DeviceDebugRunControl::s60DebuggerStartPara
     const S60DeployConfiguration *activeDeployConf = qobject_cast<S60DeployConfiguration *>(rc->qt4Target()->activeDeployConfiguration());
 
     const QString debugFileName = QString::fromLatin1("%1:\\sys\\bin\\%2.exe")
-            .arg(activeDeployConf->installationDrive()).arg(activeDeployConf->targetName());
+            .arg(activeDeployConf->installationDrive()).arg(rc->targetName());
 
     sp.remoteChannel = activeDeployConf->serialPortName();
     sp.processArgs = rc->commandLineArguments();
     sp.startMode = Debugger::StartInternal;
     sp.toolChainType = rc->toolChainType();
     sp.executable = debugFileName;
-    sp.executableUid = activeDeployConf->executableUid();
+    sp.executableUid = rc->executableUid();
 
     QTC_ASSERT(sp.executableUid, return sp);
 
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
index cbc76204c4f..8ed9ed543cd 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
@@ -73,6 +73,7 @@ public:
     virtual ~S60DeviceRunConfiguration();
 
     Qt4Target *qt4Target() const;
+    const QtVersion *qtVersion() const;
 
     bool isEnabled(ProjectExplorer::BuildConfiguration *configuration) const;
     QWidget *createConfigurationWidget();
@@ -86,6 +87,14 @@ public:
 
     ProjectExplorer::ToolChain::ToolChainType toolChainType() const;
 
+    QString targetName() const;
+    QString localExecutableFileName() const;
+    quint32 executableUid() const;
+
+    bool isDebug() const;
+    QString symbianTarget() const;
+    QString symbianPlatform() const;
+
     QVariantMap toMap() const;
 
     void proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro);
-- 
GitLab