From 04edb4513c79edfd35b7e48689dcda333b3067e0 Mon Sep 17 00:00:00 2001
From: Christian Kandeler <christian.kandeler@nokia.com>
Date: Mon, 1 Aug 2011 16:44:59 +0200
Subject: [PATCH] RemoteLinux: Overhaul deployment infrastructure.

- Introduce generic and Madde-specific deploy configuration widgets.
- Move project file update logic into dedicated class.
- Generic deploy configuration widget no longer has the ability to change deployment settings via the GUI, because we cannot know which qmake scope to use for that.

Change-Id: Ie542a0852c8aa1c6b416cd7aece4e48c1cc2de7c
Reviewed-on: http://codereview.qt.nokia.com/2445
Reviewed-by: Christian Kandeler <christian.kandeler@nokia.com>
---
 .../remotelinux/abstractpackagingstep.cpp     |   2 +
 .../remotelinux/deployablefilesperprofile.cpp | 225 +-----------------
 .../remotelinux/deployablefilesperprofile.h   |  44 +---
 src/plugins/remotelinux/deploymentinfo.cpp    |  43 +---
 src/plugins/remotelinux/deploymentinfo.h      |   7 +-
 .../deploymentsettingsassistant.cpp           | 157 ++++++++++++
 .../remotelinux/deploymentsettingsassistant.h |  72 ++++++
 .../maemodeployconfigurationwidget.cpp        | 217 ++++++++---------
 .../maemodeployconfigurationwidget.h          |  28 ++-
 .../maemodeployconfigurationwidget.ui         | 172 ++-----------
 .../remotelinux/maemoinstalltosysrootstep.cpp |   7 +-
 .../maemopublisherfremantlefree.cpp           |  12 +-
 .../qt4maemodeployconfiguration.cpp           | 114 +++++++--
 .../remotelinux/qt4maemodeployconfiguration.h |  20 +-
 .../remotelinux/qt4maemotargetfactory.cpp     |   8 +-
 src/plugins/remotelinux/remotelinux.pro       |  11 +-
 .../remotelinuxdeployconfiguration.cpp        |  67 ++++--
 .../remotelinuxdeployconfiguration.h          |   6 +-
 .../remotelinuxdeployconfigurationwidget.cpp  | 165 +++++++++++++
 .../remotelinuxdeployconfigurationwidget.h    |  79 ++++++
 .../remotelinuxdeployconfigurationwidget.ui   | 133 +++++++++++
 .../remotelinux/tarpackagecreationstep.cpp    |   1 +
 ...pespecificdeviceconfigurationlistmodel.cpp |   4 +-
 ...typespecificdeviceconfigurationlistmodel.h |   2 +-
 24 files changed, 957 insertions(+), 639 deletions(-)
 create mode 100644 src/plugins/remotelinux/deploymentsettingsassistant.cpp
 create mode 100644 src/plugins/remotelinux/deploymentsettingsassistant.h
 create mode 100644 src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.cpp
 create mode 100644 src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.h
 create mode 100644 src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.ui

diff --git a/src/plugins/remotelinux/abstractpackagingstep.cpp b/src/plugins/remotelinux/abstractpackagingstep.cpp
index 4f5bd6a0d08..d83539cdfda 100644
--- a/src/plugins/remotelinux/abstractpackagingstep.cpp
+++ b/src/plugins/remotelinux/abstractpackagingstep.cpp
@@ -30,6 +30,7 @@
 **************************************************************************/
 #include "abstractpackagingstep.h"
 
+#include "deployablefile.h"
 #include "deploymentinfo.h"
 #include "remotelinuxdeployconfiguration.h"
 
@@ -38,6 +39,7 @@
 #include <projectexplorer/target.h>
 #include <utils/fileutils.h>
 
+#include <QtCore/QDateTime>
 #include <QtCore/QFileInfo>
 
 using namespace ProjectExplorer;
diff --git a/src/plugins/remotelinux/deployablefilesperprofile.cpp b/src/plugins/remotelinux/deployablefilesperprofile.cpp
index 4871f8a5e6e..c649a5298b0 100644
--- a/src/plugins/remotelinux/deployablefilesperprofile.cpp
+++ b/src/plugins/remotelinux/deployablefilesperprofile.cpp
@@ -31,36 +31,19 @@
 **************************************************************************/
 #include "deployablefilesperprofile.h"
 
-#include "maemoglobal.h"
-#include "maemoconstants.h"
-
-#include <coreplugin/icore.h>
-#include <coreplugin/filemanager.h>
-#include <projectexplorer/projectexplorer.h>
-#include <projectexplorer/session.h>
-#include <qt4projectmanager/qt4buildconfiguration.h>
-#include <qt4projectmanager/qt4nodes.h>
-#include <qt4projectmanager/qt4target.h>
-#include <qtsupport/baseqtversion.h>
-
 #include <utils/qtcassert.h>
-#include <utils/fileutils.h>
 
-#include <QtCore/QFile>
 #include <QtCore/QFileInfo>
 #include <QtGui/QBrush>
-#include <QtGui/QImageReader>
-#include <QtGui/QMainWindow>
 
 using namespace Qt4ProjectManager;
 
 namespace RemoteLinux {
 using namespace Internal;
 
-DeployableFilesPerProFile::DeployableFilesPerProFile(const Qt4BaseTarget *target,
-    const Qt4ProFileNode *proFileNode, ProFileUpdateSetting updateSetting, QObject *parent)
+DeployableFilesPerProFile::DeployableFilesPerProFile(const Qt4ProFileNode *proFileNode,
+        QObject *parent)
     : QAbstractTableModel(parent),
-      m_target(target),
       m_projectType(proFileNode->projectType()),
       m_proFilePath(proFileNode->path()),
       m_projectName(proFileNode->displayName()),
@@ -68,30 +51,9 @@ DeployableFilesPerProFile::DeployableFilesPerProFile(const Qt4BaseTarget *target
       m_installsList(proFileNode->installsList()),
       m_projectVersion(proFileNode->projectVersion()),
       m_config(proFileNode->variableValue(ConfigVar)),
-      m_modified(false),
-      m_proFileUpdateSetting(updateSetting),
-      m_hasTargetPath(false)
-{
-    buildModel();
-}
-
-DeployableFilesPerProFile::~DeployableFilesPerProFile() {}
-
-bool DeployableFilesPerProFile::buildModel()
+      m_modified(true)
 {
-    m_deployables.clear();
-
-    m_hasTargetPath = !m_installsList.targetPath.isEmpty();
-    if (!m_hasTargetPath && m_proFileUpdateSetting == UpdateProFile) {
-        const QString remoteDirSuffix
-            = QLatin1String(m_projectType == LibraryTemplate
-                ? "/lib" : "/bin");
-        const QString remoteDir = QLatin1String("target.path = ")
-            + installPrefix() + remoteDirSuffix;
-        const QStringList deployInfo = QStringList() << remoteDir
-            << QLatin1String("INSTALLS += target");
-        return addLinesToProFile(deployInfo);
-    } else if (m_projectType == ApplicationTemplate) {
+    if (m_projectType == ApplicationTemplate) {
         m_deployables.prepend(DeployableFile(localExecutableFilePath(),
             m_installsList.targetPath));
     } else if (m_projectType == LibraryTemplate) {
@@ -104,11 +66,10 @@ bool DeployableFilesPerProFile::buildModel()
         foreach (const QString &file, elem.files)
             m_deployables << DeployableFile(file, elem.path);
     }
-
-    m_modified = true;
-    return true;
 }
 
+DeployableFilesPerProFile::~DeployableFilesPerProFile() {}
+
 DeployableFile DeployableFilesPerProFile::deployableAt(int row) const
 {
     Q_ASSERT(row >= 0 && row < rowCount());
@@ -130,7 +91,8 @@ QVariant DeployableFilesPerProFile::data(const QModelIndex &index, int role) con
     if (!index.isValid() || index.row() >= rowCount())
         return QVariant();
 
-    if (isEditable(index)) {
+    if (m_projectType != AuxTemplate && !hasTargetPath() && index.row() == 0
+            && index.column() == 1) {
         if (role == Qt::DisplayRole)
             return tr("<no target path set>");
         if (role == Qt::ForegroundRole) {
@@ -148,29 +110,6 @@ QVariant DeployableFilesPerProFile::data(const QModelIndex &index, int role) con
     return QVariant();
 }
 
-Qt::ItemFlags DeployableFilesPerProFile::flags(const QModelIndex &index) const
-{
-    Qt::ItemFlags parentFlags = QAbstractTableModel::flags(index);
-    if (isEditable(index))
-        return parentFlags | Qt::ItemIsEditable;
-    return parentFlags;
-}
-
-bool DeployableFilesPerProFile::setData(const QModelIndex &index,
-                                   const QVariant &value, int role)
-{
-    if (!isEditable(index) || role != Qt::EditRole)
-        return false;
-    const QString &remoteDir = value.toString();
-    if (!addLinesToProFile(QStringList()
-             << QString::fromLocal8Bit("target.path = %1").arg(remoteDir)
-             << QLatin1String("INSTALLS += target")))
-        return false;
-    m_deployables.first().remoteDir = remoteDir;
-    emit dataChanged(index, index);
-    return true;
-}
-
 QVariant DeployableFilesPerProFile::headerData(int section,
              Qt::Orientation orientation, int role) const
 {
@@ -208,8 +147,8 @@ QStringList DeployableFilesPerProFile::localLibraryFilePaths() const
 
 QString DeployableFilesPerProFile::remoteExecutableFilePath() const
 {
-    return m_hasTargetPath && m_projectType == ApplicationTemplate
-        ? deployableAt(0).remoteDir + '/'
+    return hasTargetPath() && m_projectType == ApplicationTemplate
+        ? deployableAt(0).remoteDir + QLatin1Char('/')
               + QFileInfo(localExecutableFilePath()).fileName()
         : QString();
 }
@@ -219,148 +158,4 @@ QString DeployableFilesPerProFile::projectDir() const
     return QFileInfo(m_proFilePath).dir().path();
 }
 
-void DeployableFilesPerProFile::setProFileUpdateSetting(ProFileUpdateSetting updateSetting)
-{
-    m_proFileUpdateSetting = updateSetting;
-    if (updateSetting == UpdateProFile)
-        buildModel();
-}
-
-bool DeployableFilesPerProFile::isEditable(const QModelIndex &index) const
-{
-    return m_projectType != AuxTemplate
-        && index.row() == 0 && index.column() == 1
-        && m_deployables.first().remoteDir.isEmpty();
-}
-
-QString DeployableFilesPerProFile::localDesktopFilePath() const
-{
-    if (m_projectType == LibraryTemplate)
-        return QString();
-    foreach (const DeployableFile &d, m_deployables) {
-        if (QFileInfo(d.localFilePath).fileName() == m_projectName + QLatin1String(".desktop"))
-            return d.localFilePath;
-    }
-    return QString();
-}
-
-bool DeployableFilesPerProFile::addDesktopFile()
-{
-    if (!canAddDesktopFile())
-        return true;
-    const QString desktopFilePath = QFileInfo(m_proFilePath).path()
-        + QLatin1Char('/') + m_projectName + QLatin1String(".desktop");
-    if (!QFile::exists(desktopFilePath)) {
-        const QByteArray desktopTemplate("[Desktop Entry]\nEncoding=UTF-8\n"
-            "Version=1.0\nType=Application\nTerminal=false\nName=%1\nExec=%2\n"
-            "Icon=%1\nX-Window-Icon=\nX-HildonDesk-ShowInToolbar=true\n"
-            "X-Osso-Type=application/x-executable\n");
-        Utils::FileSaver saver(desktopFilePath);
-        saver.write(QString::fromLatin1(desktopTemplate)
-                    .arg(m_projectName, remoteExecutableFilePath()).toUtf8());
-        if (!saver.finalize(Core::ICore::instance()->mainWindow()))
-            return false;
-    }
-
-    const QtSupport::BaseQtVersion * const version = qtVersion();
-    QTC_ASSERT(version && version->isValid(), return false);
-    QString remoteDir = QLatin1String("/usr/share/applications");
-    if (MaemoGlobal::osType(version->qmakeCommand()) == QLatin1String(Maemo5OsType))
-        remoteDir += QLatin1String("/hildon");
-    const QLatin1String filesLine("desktopfile.files = $${TARGET}.desktop");
-    const QString pathLine = QLatin1String("desktopfile.path = ") + remoteDir;
-    const QLatin1String installsLine("INSTALLS += desktopfile");
-    if (!addLinesToProFile(QStringList() << filesLine << pathLine
-            << installsLine))
-        return false;
-
-    beginInsertRows(QModelIndex(), rowCount(), rowCount());
-    m_deployables << DeployableFile(desktopFilePath, remoteDir);
-    endInsertRows();
-    return true;
-}
-
-bool DeployableFilesPerProFile::addIcon(const QString &fileName)
-{
-    if (!canAddIcon())
-        return true;
-
-    const QString filesLine = QLatin1String("icon.files = ") + fileName;
-    const QString pathLine = QLatin1String("icon.path = ") + remoteIconDir();
-    const QLatin1String installsLine("INSTALLS += icon");
-    if (!addLinesToProFile(QStringList() << filesLine << pathLine
-            << installsLine))
-        return false;
-
-    beginInsertRows(QModelIndex(), rowCount(), rowCount());
-    const QString filePath = QFileInfo(m_proFilePath).path()
-        + QLatin1Char('/') + fileName;
-    m_deployables << DeployableFile(filePath, remoteIconDir());
-    endInsertRows();
-    return true;
-}
-
-QString DeployableFilesPerProFile::remoteIconFilePath() const
-{
-    if (m_projectType == LibraryTemplate)
-        return QString();
-    const QList<QByteArray> &imageTypes = QImageReader::supportedImageFormats();
-    foreach (const DeployableFile &d, m_deployables) {
-        const QByteArray extension
-            = QFileInfo(d.localFilePath).suffix().toLocal8Bit();
-        if (d.remoteDir.startsWith(remoteIconDir())
-                && imageTypes.contains(extension))
-            return d.remoteDir + QLatin1Char('/')
-                + QFileInfo(d.localFilePath).fileName();
-    }
-    return QString();
-}
-
-bool DeployableFilesPerProFile::addLinesToProFile(const QStringList &lines)
-{
-    Core::FileChangeBlocker update(m_proFilePath);
-
-    const QLatin1String separator("\n    ");
-    const QString proFileString = QString(QLatin1Char('\n') + proFileScope()
-        + QLatin1String(" {") + separator + lines.join(separator)
-        + QLatin1String("\n}\n"));
-    Utils::FileSaver saver(m_proFilePath, QIODevice::Append);
-    saver.write(proFileString.toLocal8Bit());
-    return saver.finalize(Core::ICore::instance()->mainWindow());
-}
-
-const QtSupport::BaseQtVersion *DeployableFilesPerProFile::qtVersion() const
-{
-    const Qt4BuildConfiguration *const bc = m_target->activeBuildConfiguration();
-    QTC_ASSERT(bc, return 0);
-    return bc->qtVersion();
-}
-
-QString DeployableFilesPerProFile::proFileScope() const
-{
-    const QtSupport::BaseQtVersion *const qv = qtVersion();
-    QTC_ASSERT(qv && qv->isValid(), return QString());
-    const QString osType = MaemoGlobal::osType(qv->qmakeCommand());
-    if (osType == QLatin1String(Maemo5OsType))
-        return QLatin1String("maemo5");
-    if (osType == QLatin1String(HarmattanOsType))
-        return QLatin1String("contains(MEEGO_EDITION,harmattan)");
-    if (osType == QLatin1String(MeeGoOsType))
-        return QLatin1String("!isEmpty(MEEGO_VERSION_MAJOR):!contains(MEEGO_EDITION,harmattan)");
-    return QLatin1String("unix:!symbian:!maemo5:isEmpty(MEEGO_VERSION_MAJOR)");
-}
-
-QString DeployableFilesPerProFile::installPrefix() const
-{
-    return QLatin1String("/opt/") + m_projectName;
-}
-
-QString DeployableFilesPerProFile::remoteIconDir() const
-{
-    const QtSupport::BaseQtVersion *const qv = qtVersion();
-    QTC_ASSERT(qv && qv->isValid(), return QString());
-    return QString::fromLocal8Bit("/usr/share/icons/hicolor/%1x%1/apps")
-            .arg(MaemoGlobal::applicationIconSize(MaemoGlobal::osType(qv->qmakeCommand())));
-}
-
 } // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/deployablefilesperprofile.h b/src/plugins/remotelinux/deployablefilesperprofile.h
index 4c96e72e087..44812aa14e3 100644
--- a/src/plugins/remotelinux/deployablefilesperprofile.h
+++ b/src/plugins/remotelinux/deployablefilesperprofile.h
@@ -40,30 +40,16 @@
 #include <qt4projectmanager/qt4nodes.h>
 
 #include <QtCore/QAbstractTableModel>
-#include <QtCore/QHash>
 #include <QtCore/QList>
-#include <QtCore/QScopedPointer>
 #include <QtCore/QString>
 
-namespace QtSupport {
-class BaseQtVersion;
-}
-namespace Qt4ProjectManager {
-class Qt4BaseTarget;
-}
-
 namespace RemoteLinux {
 
 class REMOTELINUX_EXPORT DeployableFilesPerProFile : public QAbstractTableModel
 {
     Q_OBJECT
 public:
-    enum ProFileUpdateSetting {
-        UpdateProFile, DontUpdateProFile, AskToUpdateProFile
-    };
-
-    DeployableFilesPerProFile(const Qt4ProjectManager::Qt4BaseTarget *target,
-        const Qt4ProjectManager::Qt4ProFileNode *proFileNode, ProFileUpdateSetting updateSetting,
+    DeployableFilesPerProFile(const Qt4ProjectManager::Qt4ProFileNode *proFileNode,
         QObject *parent);
     ~DeployableFilesPerProFile();
 
@@ -72,7 +58,6 @@ public:
     DeployableFile deployableAt(int row) const;
     bool isModified() const { return m_modified; }
     void setUnModified() { m_modified = false; }
-    const QtSupport::BaseQtVersion *qtVersion() const;
     QString localExecutableFilePath() const;
     QString remoteExecutableFilePath() const;
     QString projectName() const { return m_projectName; }
@@ -81,18 +66,7 @@ public:
     Qt4ProjectManager::Qt4ProjectType projectType() const { return m_projectType; }
     bool isApplicationProject() const { return m_projectType == Qt4ProjectManager::ApplicationTemplate; }
     QString applicationName() const { return m_targetInfo.target; }
-    bool hasTargetPath() const { return m_hasTargetPath; }
-    bool canAddDesktopFile() const { return isApplicationProject() && !hasDesktopFile(); }
-    QString localDesktopFilePath() const;
-    bool hasDesktopFile() const { return !localDesktopFilePath().isEmpty(); }
-    bool addDesktopFile();
-    bool canAddIcon() const { return isApplicationProject() && remoteIconFilePath().isEmpty(); }
-    bool addIcon(const QString &fileName);
-    QString remoteIconFilePath() const;
-    ProFileUpdateSetting proFileUpdateSetting() const {
-        return m_proFileUpdateSetting;
-    }
-    void setProFileUpdateSetting(ProFileUpdateSetting updateSetting);
+    bool hasTargetPath() const { return !m_installsList.targetPath.isEmpty(); }
 
 private:
     virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
@@ -100,19 +74,9 @@ private:
                           int role = Qt::DisplayRole) const;
     virtual QVariant headerData(int section, Qt::Orientation orientation,
                                 int role = Qt::DisplayRole) const;
-    virtual Qt::ItemFlags flags(const QModelIndex &index) const;
-    virtual bool setData(const QModelIndex &index, const QVariant &value,
-                         int role = Qt::EditRole);
 
-    bool isEditable(const QModelIndex &index) const;
-    bool buildModel();
-    bool addLinesToProFile(const QStringList &lines);
-    QString proFileScope() const;
-    QString installPrefix() const;
-    QString remoteIconDir() const;
     QStringList localLibraryFilePaths() const;
 
-    const Qt4ProjectManager::Qt4BaseTarget * const m_target;
     const Qt4ProjectManager::Qt4ProjectType m_projectType;
     const QString m_proFilePath;
     const QString m_projectName;
@@ -121,9 +85,7 @@ private:
     const Qt4ProjectManager::ProjectVersion m_projectVersion;
     const QStringList m_config;
     QList<DeployableFile> m_deployables;
-    mutable bool m_modified;
-    ProFileUpdateSetting m_proFileUpdateSetting;
-    bool m_hasTargetPath;
+    bool m_modified;
 };
 
 } // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/deploymentinfo.cpp b/src/plugins/remotelinux/deploymentinfo.cpp
index 23b23f5b6e9..be54f522142 100644
--- a/src/plugins/remotelinux/deploymentinfo.cpp
+++ b/src/plugins/remotelinux/deploymentinfo.cpp
@@ -32,7 +32,7 @@
 #include "deploymentinfo.h"
 
 #include "deployablefile.h"
-#include "maemoprofilesupdatedialog.h"
+#include "deployablefilesperprofile.h"
 
 #include <projectexplorer/buildstep.h>
 #include <qt4projectmanager/qt4buildconfiguration.h>
@@ -74,6 +74,7 @@ void DeploymentInfo::createModels()
     if (!m_target->activeBuildConfiguration() || !m_target->activeBuildConfiguration()->qtVersion()
             || !m_target->activeBuildConfiguration()->qtVersion()->isValid()) {
         beginResetModel();
+        qDeleteAll(m_listModels);
         m_listModels.clear();
         endResetModel();
         return;
@@ -90,30 +91,6 @@ void DeploymentInfo::createModels()
     qDeleteAll(m_listModels);
     m_listModels.clear();
     createModels(rootNode);
-    QList<DeployableFilesPerProFile *> modelsWithoutTargetPath;
-    foreach (DeployableFilesPerProFile *const model, m_listModels) {
-        if (!model->hasTargetPath()) {
-            if (model->proFileUpdateSetting() == DeployableFilesPerProFile::AskToUpdateProFile)
-                modelsWithoutTargetPath << model;
-        }
-    }
-
-    if (!modelsWithoutTargetPath.isEmpty()) {
-        MaemoProFilesUpdateDialog dialog(modelsWithoutTargetPath);
-        dialog.exec();
-        const QList<MaemoProFilesUpdateDialog::UpdateSetting> &settings
-            = dialog.getUpdateSettings();
-        foreach (const MaemoProFilesUpdateDialog::UpdateSetting &setting, settings) {
-            const DeployableFilesPerProFile::ProFileUpdateSetting updateSetting
-                = setting.second
-                    ? DeployableFilesPerProFile::UpdateProFile
-                    : DeployableFilesPerProFile::DontUpdateProFile;
-            m_updateSettings.insert(setting.first->proFilePath(),
-                updateSetting);
-            setting.first->setProFileUpdateSetting(updateSetting);
-        }
-    }
-
     endResetModel();
     connect(m_target->qt4Project(),
             SIGNAL(proFileUpdated(Qt4ProjectManager::Qt4ProFileNode*,bool,bool)),
@@ -125,21 +102,9 @@ void DeploymentInfo::createModels(const Qt4ProFileNode *proFileNode)
     switch (proFileNode->projectType()) {
     case ApplicationTemplate:
     case LibraryTemplate:
-    case AuxTemplate: {
-        DeployableFilesPerProFile::ProFileUpdateSetting updateSetting;
-        if (proFileNode->projectType() == AuxTemplate) {
-            updateSetting = DeployableFilesPerProFile::DontUpdateProFile;
-        } else {
-            UpdateSettingsMap::ConstIterator it
-                = m_updateSettings.find(proFileNode->path());
-            updateSetting = it != m_updateSettings.end()
-                ? it.value() : DeployableFilesPerProFile::AskToUpdateProFile;
-        }
-        DeployableFilesPerProFile *const newModel
-            = new DeployableFilesPerProFile(m_target, proFileNode, updateSetting, this);
-        m_listModels << newModel;
+    case AuxTemplate:
+        m_listModels << new DeployableFilesPerProFile(proFileNode, this);
         break;
-    }
     case SubDirsTemplate: {
         const QList<ProjectExplorer::ProjectNode *> &subProjects
             = proFileNode->subProjectNodes();
diff --git a/src/plugins/remotelinux/deploymentinfo.h b/src/plugins/remotelinux/deploymentinfo.h
index 3ad5d2eac2c..564268d91a8 100644
--- a/src/plugins/remotelinux/deploymentinfo.h
+++ b/src/plugins/remotelinux/deploymentinfo.h
@@ -32,23 +32,21 @@
 #ifndef DEPLOYMENTINFO_H
 #define DEPLOYMENTINFO_H
 
-#include "deployablefilesperprofile.h"
 #include "remotelinux_export.h"
 
 #include <QtCore/QAbstractListModel>
-#include <QtCore/QHash>
 #include <QtCore/QList>
 
 QT_FORWARD_DECLARE_CLASS(QTimer)
 
 namespace Qt4ProjectManager {
-class Qt4BuildConfiguration;
 class Qt4BaseTarget;
 class Qt4ProFileNode;
 } // namespace Qt4ProjectManager
 
 namespace RemoteLinux {
 class DeployableFile;
+class DeployableFilesPerProFile;
 
 class REMOTELINUX_EXPORT DeploymentInfo : public QAbstractListModel
 {
@@ -68,8 +66,6 @@ private slots:
     void startTimer(Qt4ProjectManager::Qt4ProFileNode *, bool success, bool parseInProgress);
 
 private:
-    typedef QHash<QString, DeployableFilesPerProFile::ProFileUpdateSetting> UpdateSettingsMap;
-
     virtual int rowCount(const QModelIndex &parent) const;
     virtual QVariant data(const QModelIndex &index, int role) const;
 
@@ -77,7 +73,6 @@ private:
     void createModels(const Qt4ProjectManager::Qt4ProFileNode *proFileNode);
 
     QList<DeployableFilesPerProFile *> m_listModels;
-    UpdateSettingsMap m_updateSettings;
     const Qt4ProjectManager::Qt4BaseTarget * const m_target;
     QTimer *const m_updateTimer;
 };
diff --git a/src/plugins/remotelinux/deploymentsettingsassistant.cpp b/src/plugins/remotelinux/deploymentsettingsassistant.cpp
new file mode 100644
index 00000000000..2fa9af4f1a6
--- /dev/null
+++ b/src/plugins/remotelinux/deploymentsettingsassistant.cpp
@@ -0,0 +1,157 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** GNU Lesser General Public License Usage
+**
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+#include "deploymentsettingsassistant.h"
+
+#include "deploymentinfo.h"
+#include "deployablefile.h"
+#include "deployablefilesperprofile.h"
+#include "maemoprofilesupdatedialog.h"
+
+#include <coreplugin/filemanager.h>
+#include <coreplugin/icore.h>
+#include <qt4projectmanager/qt4nodes.h>
+#include <utils/fileutils.h>
+#include <utils/qtcassert.h>
+
+#include <QtCore/QDir>
+#include <QtCore/QHash>
+#include <QtCore/QString>
+#include <QtGui/QMainWindow>
+
+using namespace Qt4ProjectManager;
+
+namespace RemoteLinux {
+namespace Internal {
+namespace {
+
+enum ProFileUpdateSetting { UpdateProFile, DontUpdateProFile };
+typedef QHash<QString, ProFileUpdateSetting> UpdateSettingsMap;
+
+} // anonymous namespace
+
+class DeploymentSettingsAssistantInternal
+{
+public:
+    DeploymentSettingsAssistantInternal(const QString &qmakeScope, const QString &installPrefix,
+            const QSharedPointer<DeploymentInfo> &deploymentInfo)
+        : qmakeScope(qmakeScope), installPrefix(installPrefix), deploymentInfo(deploymentInfo)
+    {
+    }
+
+    const QString qmakeScope;
+    const QString installPrefix;
+    const QSharedPointer<DeploymentInfo> deploymentInfo;
+    UpdateSettingsMap updateSettings;
+};
+
+} // namespace Internal
+
+using namespace Internal;
+
+DeploymentSettingsAssistant::DeploymentSettingsAssistant(const QString &qmakeScope,
+        const QString &installPrefix, const QSharedPointer<DeploymentInfo> &deploymentInfo,
+        QObject *parent)
+    : QObject(parent),
+      m_d(new DeploymentSettingsAssistantInternal(qmakeScope, installPrefix, deploymentInfo))
+{
+    connect(m_d->deploymentInfo.data(), SIGNAL(modelReset()), SLOT(handleDeploymentInfoUpdated()));
+}
+
+DeploymentSettingsAssistant::~DeploymentSettingsAssistant()
+{
+    delete m_d;
+}
+
+bool DeploymentSettingsAssistant::addDeployableToProFile(const DeployableFilesPerProFile *proFileInfo,
+    const QString &variableName, const DeployableFile &deployable)
+{
+    const QString filesLine = variableName + QLatin1String(".files = ")
+        + QDir(proFileInfo->projectDir()).relativeFilePath(deployable.localFilePath);
+    const QString pathLine = variableName + QLatin1String(".path = ") + deployable.remoteDir;
+    const QString installsLine = QLatin1String("INSTALLS += ") + variableName;
+    return addLinesToProFile(proFileInfo, QStringList() << filesLine << pathLine << installsLine);
+}
+
+bool DeploymentSettingsAssistant::addLinesToProFile(const DeployableFilesPerProFile *proFileInfo,
+    const QStringList &lines)
+{
+    Core::FileChangeBlocker update(proFileInfo->proFilePath());
+
+    const QString separator = QLatin1String("\n    ");
+    const QString proFileString = QLatin1Char('\n') + m_d->qmakeScope + QLatin1String(" {")
+        + separator + lines.join(separator) + QLatin1String("\n}\n");
+    Utils::FileSaver saver(proFileInfo->proFilePath(), QIODevice::Append);
+    saver.write(proFileString.toLocal8Bit());
+    return saver.finalize(Core::ICore::instance()->mainWindow());
+}
+
+void DeploymentSettingsAssistant::handleDeploymentInfoUpdated()
+{
+    QList<DeployableFilesPerProFile *> proFilesToAskAbout;
+    QList<DeployableFilesPerProFile *> proFilesToUpdate;
+    for (int i = 0; i < m_d->deploymentInfo->modelCount(); ++i) {
+        DeployableFilesPerProFile * const proFileInfo = m_d->deploymentInfo->modelAt(i);
+        if (proFileInfo->projectType() != AuxTemplate && !proFileInfo->hasTargetPath()) {
+            const UpdateSettingsMap::ConstIterator it
+                = m_d->updateSettings.find(proFileInfo->proFilePath());
+            if (it == m_d->updateSettings.constEnd())
+                proFilesToAskAbout << proFileInfo;
+            else if (it.value() == UpdateProFile)
+                proFilesToUpdate << proFileInfo;
+        }
+    }
+
+    if (!proFilesToAskAbout.isEmpty()) {
+        MaemoProFilesUpdateDialog dialog(proFilesToAskAbout);
+        dialog.exec();
+        const QList<MaemoProFilesUpdateDialog::UpdateSetting> &settings
+            = dialog.getUpdateSettings();
+        foreach (const MaemoProFilesUpdateDialog::UpdateSetting &setting, settings) {
+            const ProFileUpdateSetting updateSetting = setting.second
+                ? UpdateProFile : DontUpdateProFile;
+            m_d->updateSettings.insert(setting.first->proFilePath(), updateSetting);
+            if (updateSetting == UpdateProFile)
+                proFilesToUpdate << setting.first;
+        }
+    }
+
+    foreach (const DeployableFilesPerProFile * const proFileInfo, proFilesToUpdate) {
+        const QString remoteDirSuffix = QLatin1String(proFileInfo->projectType() == LibraryTemplate
+                ? "/lib" : "/bin");
+        const QString remoteDir = QLatin1String("target.path = ") + m_d->installPrefix
+            + QLatin1Char('/') + proFileInfo->projectName() + remoteDirSuffix;
+        const QStringList deployInfo = QStringList() << remoteDir
+            << QLatin1String("INSTALLS += target");
+        addLinesToProFile(proFileInfo, deployInfo);
+    }
+}
+
+} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/deploymentsettingsassistant.h b/src/plugins/remotelinux/deploymentsettingsassistant.h
new file mode 100644
index 00000000000..dbf6aea49ce
--- /dev/null
+++ b/src/plugins/remotelinux/deploymentsettingsassistant.h
@@ -0,0 +1,72 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** GNU Lesser General Public License Usage
+**
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+#ifndef DEPLOYMENTSETTINGSASSISTANT_H
+#define DEPLOYMENTSETTINGSASSISTANT_H
+
+#include "remotelinux_export.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QStringList>
+
+namespace RemoteLinux {
+class DeployableFile;
+class DeployableFilesPerProFile;
+class DeploymentInfo;
+
+namespace Internal {
+class DeploymentSettingsAssistantInternal;
+} // namespace Internal
+
+class REMOTELINUX_EXPORT DeploymentSettingsAssistant : public QObject
+{
+    Q_OBJECT
+    Q_DISABLE_COPY(DeploymentSettingsAssistant)
+public:
+    DeploymentSettingsAssistant(const QString &qmakeScope, const QString &iunstallPrefix,
+        const QSharedPointer<DeploymentInfo> &deploymentInfo, QObject *parent = 0);
+    ~DeploymentSettingsAssistant();
+
+    bool addDeployableToProFile(const DeployableFilesPerProFile *proFileInfo,
+        const QString &variableName, const DeployableFile &deployable);
+
+private slots:
+    void handleDeploymentInfoUpdated();
+
+private:
+    bool addLinesToProFile(const DeployableFilesPerProFile *proFileInfo, const QStringList &lines);
+
+    Internal::DeploymentSettingsAssistantInternal * const m_d;
+};
+
+} // namespace RemoteLinux
+
+#endif // DEPLOYMENTSETTINGSASSISTANT_H
diff --git a/src/plugins/remotelinux/maemodeployconfigurationwidget.cpp b/src/plugins/remotelinux/maemodeployconfigurationwidget.cpp
index dd92e7cacd5..a8408201e36 100644
--- a/src/plugins/remotelinux/maemodeployconfigurationwidget.cpp
+++ b/src/plugins/remotelinux/maemodeployconfigurationwidget.cpp
@@ -29,35 +29,49 @@
 ** Nokia at info@qt.nokia.com.
 **
 **************************************************************************/
-
 #include "maemodeployconfigurationwidget.h"
 #include "ui_maemodeployconfigurationwidget.h"
 
-#include "deployablefilesperprofile.h"
-#include "deploymentinfo.h"
-#include "linuxdeviceconfigurations.h"
+#include "deploymentsettingsassistant.h"
 #include "maemoglobal.h"
-#include "remotelinuxdeployconfiguration.h"
-#include "remotelinuxsettingspages.h"
-#include "typespecificdeviceconfigurationlistmodel.h"
-
-#include <coreplugin/icore.h>
+#include "qt4maemodeployconfiguration.h"
+#include "qt4maemotarget.h"
+
+#include <qt4projectmanager/qt4nodes.h>
+#include <remotelinux/deployablefilesperprofile.h>
+#include <remotelinux/deploymentinfo.h>
+#include <remotelinux/remotelinuxdeployconfigurationwidget.h>
+#include <utils/fileutils.h>
 #include <utils/qtcassert.h>
 
+#include <QtCore/QFileInfo>
 #include <QtGui/QFileDialog>
 #include <QtGui/QMessageBox>
 #include <QtGui/QPixmap>
+#include <QtGui/QVBoxLayout>
 
 using namespace ProjectExplorer;
+using namespace Qt4ProjectManager;
 
 namespace RemoteLinux {
 namespace Internal {
 
 MaemoDeployConfigurationWidget::MaemoDeployConfigurationWidget(QWidget *parent)
     : DeployConfigurationWidget(parent),
-      ui(new Ui::MaemoDeployConfigurationWidget)
+      ui(new Ui::MaemoDeployConfigurationWidget),
+      m_remoteLinuxWidget(new RemoteLinuxDeployConfigurationWidget)
 {
-    ui->setupUi(this);
+    QVBoxLayout *mainLayout = new QVBoxLayout(this);
+    mainLayout->setSpacing(0);
+    mainLayout->addWidget(m_remoteLinuxWidget);
+    QWidget * const subWidget = new QWidget;
+    ui->setupUi(subWidget);
+    mainLayout->addWidget(subWidget);
+    mainLayout->addStretch(1);
+
+    connect(m_remoteLinuxWidget, SIGNAL(currentModelChanged(const DeployableFilesPerProFile*)),
+        SLOT(handleCurrentModelChanged(const DeployableFilesPerProFile*)));
+    handleCurrentModelChanged(0);
 }
 
 MaemoDeployConfigurationWidget::~MaemoDeployConfigurationWidget()
@@ -67,113 +81,70 @@ MaemoDeployConfigurationWidget::~MaemoDeployConfigurationWidget()
 
 void MaemoDeployConfigurationWidget::init(DeployConfiguration *dc)
 {
-    m_deployConfig = qobject_cast<RemoteLinuxDeployConfiguration *>(dc);
-    Q_ASSERT(m_deployConfig);
-
-    connect(ui->manageDevConfsLabel, SIGNAL(linkActivated(QString)),
-        SLOT(showDeviceConfigurations()));
-
-    ui->deviceConfigsComboBox->setModel(m_deployConfig->deviceConfigModel().data());
-    connect(ui->deviceConfigsComboBox, SIGNAL(activated(int)),
-        SLOT(handleSelectedDeviceConfigurationChanged(int)));
-    connect(m_deployConfig, SIGNAL(deviceConfigurationListChanged()),
-        SLOT(handleDeviceConfigurationListChanged()));
-    handleDeviceConfigurationListChanged();
-
-    ui->projectsComboBox->setModel(m_deployConfig->deploymentInfo().data());
-    connect(m_deployConfig->deploymentInfo().data(), SIGNAL(modelAboutToBeReset()),
-        SLOT(handleModelListToBeReset()));
-
-    // Queued connection because of race condition with combo box's reaction
-    // to modelReset().
-    connect(m_deployConfig->deploymentInfo().data(), SIGNAL(modelReset()),
-        SLOT(handleModelListReset()), Qt::QueuedConnection);
-
-    connect(ui->projectsComboBox, SIGNAL(currentIndexChanged(int)),
-        SLOT(setModel(int)));
-    connect(ui->addDesktopFileButton, SIGNAL(clicked()),
-        SLOT(addDesktopFile()));
+    m_remoteLinuxWidget->init(dc);
+    connect(ui->addDesktopFileButton, SIGNAL(clicked()), SLOT(addDesktopFile()));
     connect(ui->addIconButton, SIGNAL(clicked()), SLOT(addIcon()));
-    handleModelListReset();
-}
-
-void MaemoDeployConfigurationWidget::handleModelListToBeReset()
-{
-    ui->tableView->reset(); // Otherwise we'll crash if the user is currently editing.
-    ui->tableView->setModel(0);
-    ui->addDesktopFileButton->setEnabled(false);
-    ui->addIconButton->setEnabled(false);
-}
-
-void MaemoDeployConfigurationWidget::handleModelListReset()
-{
-    QTC_ASSERT(m_deployConfig->deploymentInfo()->modelCount() == ui->projectsComboBox->count(), return);
-    if (m_deployConfig->deploymentInfo()->modelCount() > 0) {
-        if (ui->projectsComboBox->currentIndex() == -1)
-            ui->projectsComboBox->setCurrentIndex(0);
-        else
-            setModel(ui->projectsComboBox->currentIndex());
-    }
+    connect(deployConfiguration()->deploymentInfo().data(), SIGNAL(modelAboutToBeReset()),
+        SLOT(handleDeploymentInfoToBeReset()));
 }
 
-void MaemoDeployConfigurationWidget::setModel(int row)
+Qt4MaemoDeployConfiguration *MaemoDeployConfigurationWidget::deployConfiguration() const
 {
-    bool canAddDesktopFile = false;
-    bool canAddIconFile = false;
-    if (row != -1) {
-        DeployableFilesPerProFile * const model
-            = m_deployConfig->deploymentInfo()->modelAt(row);
-        ui->tableView->setModel(model);
-        ui->tableView->resizeRowsToContents();
-        canAddDesktopFile = model->canAddDesktopFile();
-        canAddIconFile = model->canAddIcon();
-    }
-    ui->addDesktopFileButton->setEnabled(canAddDesktopFile);
-    ui->addIconButton->setEnabled(canAddIconFile);
+    return qobject_cast<Qt4MaemoDeployConfiguration *>(m_remoteLinuxWidget->deployConfiguration());
 }
 
-void MaemoDeployConfigurationWidget::handleSelectedDeviceConfigurationChanged(int index)
+void MaemoDeployConfigurationWidget::handleDeploymentInfoToBeReset()
 {
-    disconnect(m_deployConfig, SIGNAL(deviceConfigurationListChanged()), this,
-        SLOT(handleDeviceConfigurationListChanged()));
-    m_deployConfig->setDeviceConfiguration(index);
-    connect(m_deployConfig, SIGNAL(deviceConfigurationListChanged()),
-        SLOT(handleDeviceConfigurationListChanged()));
+    ui->addDesktopFileButton->setEnabled(false);
+    ui->addIconButton->setEnabled(false);
 }
 
-void MaemoDeployConfigurationWidget::handleDeviceConfigurationListChanged()
+void MaemoDeployConfigurationWidget::handleCurrentModelChanged(const DeployableFilesPerProFile *proFileInfo)
 {
-    const LinuxDeviceConfiguration::ConstPtr &devConf = m_deployConfig->deviceConfiguration();
-    const LinuxDeviceConfiguration::Id internalId
-        = LinuxDeviceConfigurations::instance()->internalId(devConf);
-    const int newIndex = m_deployConfig->deviceConfigModel()->indexForInternalId(internalId);
-    ui->deviceConfigsComboBox->setCurrentIndex(newIndex);
+    ui->addDesktopFileButton->setEnabled(canAddDesktopFile(proFileInfo));
+    ui->addIconButton->setEnabled(canAddIcon(proFileInfo));
 }
 
 void MaemoDeployConfigurationWidget::addDesktopFile()
 {
-    const int modelRow = ui->projectsComboBox->currentIndex();
-    if (modelRow == -1)
-        return;
-    DeployableFilesPerProFile *const model
-        = m_deployConfig->deploymentInfo()->modelAt(modelRow);
-    model->addDesktopFile();
-    ui->addDesktopFileButton->setEnabled(model->canAddDesktopFile());
-    ui->tableView->resizeRowsToContents();
+    DeployableFilesPerProFile * const proFileInfo = m_remoteLinuxWidget->currentModel();
+    QTC_ASSERT(canAddDesktopFile(proFileInfo), return);
+
+    const QString desktopFilePath = QFileInfo(proFileInfo->proFilePath()).path()
+        + QLatin1Char('/') + proFileInfo->projectName() + QLatin1String(".desktop");
+    if (!QFile::exists(desktopFilePath)) {
+        const QString desktopTemplate = QLatin1String("[Desktop Entry]\nEncoding=UTF-8\n"
+            "Version=1.0\nType=Application\nTerminal=false\nName=%1\nExec=%2\n"
+            "Icon=%1\nX-Window-Icon=\nX-HildonDesk-ShowInToolbar=true\n"
+            "X-Osso-Type=application/x-executable\n");
+        Utils::FileSaver saver(desktopFilePath);
+        saver.write(desktopTemplate.arg(proFileInfo->projectName(),
+            proFileInfo->remoteExecutableFilePath()).toUtf8());
+        if (!saver.finalize(this))
+            return;
+    }
+
+    DeployableFile d;
+    d.remoteDir = QLatin1String("/usr/share/applications");
+    if (qobject_cast<Qt4Maemo5Target *>(deployConfiguration()->target()))
+        d.remoteDir += QLatin1String("/hildon");
+    d.localFilePath = desktopFilePath;
+    if (!deployConfiguration()->deploymentSettingsAssistant()->addDeployableToProFile(proFileInfo,
+        QLatin1String("desktopfile"), d)) {
+        QMessageBox::critical(this, tr("Project File Update Failed"),
+            tr("Could not update the project file."));
+    } else {
+        ui->addDesktopFileButton->setEnabled(false);
+    }
 }
 
 void MaemoDeployConfigurationWidget::addIcon()
 {
-    const int modelRow = ui->projectsComboBox->currentIndex();
-    if (modelRow == -1)
-        return;
-
-    DeployableFilesPerProFile *const model
-        = m_deployConfig->deploymentInfo()->modelAt(modelRow);
-    const int iconDim = MaemoGlobal::applicationIconSize(MaemoGlobal::osType(model->qtVersion()->qmakeCommand()));
+    DeployableFilesPerProFile * const proFileInfo = m_remoteLinuxWidget->currentModel();
+    const int iconDim = MaemoGlobal::applicationIconSize(deployConfiguration()->supportedOsType());
     const QString origFilePath = QFileDialog::getOpenFileName(this,
         tr("Choose Icon (will be scaled to %1x%1 pixels, if necessary)").arg(iconDim),
-        model->projectDir(), QLatin1String("(*.png)"));
+        proFileInfo->projectDir(), QLatin1String("(*.png)"));
     if (origFilePath.isEmpty())
         return;
     QPixmap pixmap(origFilePath);
@@ -185,25 +156,55 @@ void MaemoDeployConfigurationWidget::addIcon()
     const QSize iconSize(iconDim, iconDim);
     if (pixmap.size() != iconSize)
         pixmap = pixmap.scaled(iconSize);
-    const QString newFileName = model->projectName() + QLatin1Char('.')
-            + QFileInfo(origFilePath).suffix();
-    const QString newFilePath = model->projectDir() + QLatin1Char('/')
-        + newFileName;
+    const QString newFileName = proFileInfo->projectName() + QLatin1Char('.')
+        + QFileInfo(origFilePath).suffix();
+    const QString newFilePath = proFileInfo->projectDir() + QLatin1Char('/') + newFileName;
     if (!pixmap.save(newFilePath)) {
         QMessageBox::critical(this, tr("Failed to Save Icon"),
             tr("Could not save icon to '%1'.").arg(newFilePath));
         return;
     }
 
-    model->addIcon(newFileName);
-    ui->addIconButton->setEnabled(model->canAddIcon());
-    ui->tableView->resizeRowsToContents();
+    if (!deployConfiguration()->deploymentSettingsAssistant()->addDeployableToProFile(proFileInfo,
+        QLatin1String("icon"), DeployableFile(newFilePath, remoteIconDir()))) {
+        QMessageBox::critical(this, tr("Project File Update Failed"),
+            tr("Could not update the project file."));
+    } else {
+        ui->addIconButton->setEnabled(false);
+    }
+}
+
+bool MaemoDeployConfigurationWidget::canAddDesktopFile(const DeployableFilesPerProFile *proFileInfo) const
+{
+    return proFileInfo && proFileInfo->isApplicationProject()
+        && deployConfiguration()->localDesktopFilePath(proFileInfo).isEmpty();
+}
+
+bool MaemoDeployConfigurationWidget::canAddIcon(const DeployableFilesPerProFile *proFileInfo) const
+{
+    return proFileInfo && proFileInfo->isApplicationProject()
+        && remoteIconFilePath(proFileInfo).isEmpty();
+}
+
+QString MaemoDeployConfigurationWidget::remoteIconFilePath(const DeployableFilesPerProFile *proFileInfo) const
+{
+    QTC_ASSERT(proFileInfo->projectType() == ApplicationTemplate, return  QString());
+
+    const QStringList imageTypes = QStringList() << QLatin1String("jpg") << QLatin1String("png")
+        << QLatin1String("svg");
+    for (int i = 0; i < proFileInfo->rowCount(); ++i) {
+        const DeployableFile &d = proFileInfo->deployableAt(i);
+        const QString extension = QFileInfo(d.localFilePath).suffix();
+        if (d.remoteDir.startsWith(remoteIconDir()) && imageTypes.contains(extension))
+            return d.remoteDir + QLatin1Char('/') + QFileInfo(d.localFilePath).fileName();
+    }
+    return QString();
 }
 
-void MaemoDeployConfigurationWidget::showDeviceConfigurations()
+QString MaemoDeployConfigurationWidget::remoteIconDir() const
 {
-    Core::ICore::instance()->showOptionsDialog(LinuxDeviceConfigurationsSettingsPage::pageCategory(),
-        LinuxDeviceConfigurationsSettingsPage::pageId());
+    return QString::fromLocal8Bit("/usr/share/icons/hicolor/%1x%1/apps")
+        .arg(MaemoGlobal::applicationIconSize(deployConfiguration()->supportedOsType()));
 }
 
 } // namespace Internal
diff --git a/src/plugins/remotelinux/maemodeployconfigurationwidget.h b/src/plugins/remotelinux/maemodeployconfigurationwidget.h
index ca7cf967193..ea9b7b62084 100644
--- a/src/plugins/remotelinux/maemodeployconfigurationwidget.h
+++ b/src/plugins/remotelinux/maemodeployconfigurationwidget.h
@@ -37,14 +37,16 @@
 
 QT_BEGIN_NAMESPACE
 namespace Ui {
-    class MaemoDeployConfigurationWidget;
+class MaemoDeployConfigurationWidget;
 }
 QT_END_NAMESPACE
 
 namespace RemoteLinux {
-class RemoteLinuxDeployConfiguration;
+class DeployableFilesPerProFile;
+class RemoteLinuxDeployConfigurationWidget;
 
 namespace Internal {
+class Qt4MaemoDeployConfiguration;
 
 class MaemoDeployConfigurationWidget : public ProjectExplorer::DeployConfigurationWidget
 {
@@ -56,18 +58,22 @@ public:
 
     void init(ProjectExplorer::DeployConfiguration *dc);
 
+    Qt4MaemoDeployConfiguration *deployConfiguration() const;
+
+private slots:
+    void addDesktopFile();
+    void addIcon();
+    void handleDeploymentInfoToBeReset();
+    void handleCurrentModelChanged(const DeployableFilesPerProFile *proFileInfo);
+
 private:
-    Q_SLOT void handleModelListToBeReset();
-    Q_SLOT void handleModelListReset();
-    Q_SLOT void setModel(int row);
-    Q_SLOT void handleSelectedDeviceConfigurationChanged(int index);
-    Q_SLOT void handleDeviceConfigurationListChanged();
-    Q_SLOT void addDesktopFile();
-    Q_SLOT void addIcon();
-    Q_SLOT void showDeviceConfigurations();
+    bool canAddDesktopFile(const DeployableFilesPerProFile *proFileInfo) const;
+    bool canAddIcon(const DeployableFilesPerProFile *proFileInfo) const;
+    QString remoteIconFilePath(const DeployableFilesPerProFile *proFileInfo) const;
+    QString remoteIconDir() const;
 
     Ui::MaemoDeployConfigurationWidget *ui;
-    RemoteLinuxDeployConfiguration *m_deployConfig;
+    RemoteLinuxDeployConfigurationWidget * const m_remoteLinuxWidget;
 };
 
 } // namespace Internal
diff --git a/src/plugins/remotelinux/maemodeployconfigurationwidget.ui b/src/plugins/remotelinux/maemodeployconfigurationwidget.ui
index e0c7f9eb67c..6cca3cac017 100644
--- a/src/plugins/remotelinux/maemodeployconfigurationwidget.ui
+++ b/src/plugins/remotelinux/maemodeployconfigurationwidget.ui
@@ -6,160 +6,40 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>570</width>
-    <height>407</height>
+    <width>273</width>
+    <height>45</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Form</string>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout_2">
+  <layout class="QHBoxLayout" name="horizontalLayout">
    <item>
-    <layout class="QFormLayout" name="formLayout">
-     <item row="0" column="0">
-      <widget class="QLabel" name="label">
-       <property name="text">
-        <string>Device configuration:</string>
-       </property>
-      </widget>
-     </item>
-     <item row="0" column="1">
-      <layout class="QHBoxLayout" name="horizontalLayout_2">
-       <item>
-        <widget class="QComboBox" name="deviceConfigsComboBox"/>
-       </item>
-       <item>
-        <widget class="QLabel" name="manageDevConfsLabel">
-         <property name="text">
-          <string>&lt;a href=&quot;irrelevant&quot;&gt;Manage device configurations&lt;/a&gt;</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <spacer name="horizontalSpacer">
-         <property name="orientation">
-          <enum>Qt::Horizontal</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>40</width>
-           <height>20</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-      </layout>
-     </item>
-     <item row="1" column="0">
-      <widget class="QLabel" name="installLabel">
-       <property name="toolTip">
-        <string>These show the INSTALLS settings from the project file(s).</string>
-       </property>
-       <property name="text">
-        <string>Files to install for subproject:</string>
-       </property>
-      </widget>
-     </item>
-     <item row="1" column="1">
-      <layout class="QHBoxLayout" name="horizontalLayout">
-       <item>
-        <widget class="QComboBox" name="projectsComboBox">
-         <property name="sizeAdjustPolicy">
-          <enum>QComboBox::AdjustToContents</enum>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <spacer name="horizontalSpacer_2">
-         <property name="orientation">
-          <enum>Qt::Horizontal</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>40</width>
-           <height>20</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-      </layout>
-     </item>
-    </layout>
+    <widget class="QPushButton" name="addDesktopFileButton">
+     <property name="text">
+      <string>Add Desktop File</string>
+     </property>
+    </widget>
    </item>
    <item>
-    <layout class="QHBoxLayout" name="horizontalLayout_4">
-     <item>
-      <widget class="QTableView" name="tableView">
-       <property name="minimumSize">
-        <size>
-         <width>0</width>
-         <height>150</height>
-        </size>
-       </property>
-       <property name="toolTip">
-        <string>Edit the project file to add or remove entries.</string>
-       </property>
-       <property name="textElideMode">
-        <enum>Qt::ElideMiddle</enum>
-       </property>
-       <property name="horizontalScrollMode">
-        <enum>QAbstractItemView::ScrollPerPixel</enum>
-       </property>
-       <property name="showGrid">
-        <bool>false</bool>
-       </property>
-       <property name="wordWrap">
-        <bool>false</bool>
-       </property>
-       <attribute name="horizontalHeaderDefaultSectionSize">
-        <number>400</number>
-       </attribute>
-       <attribute name="horizontalHeaderHighlightSections">
-        <bool>false</bool>
-       </attribute>
-       <attribute name="horizontalHeaderMinimumSectionSize">
-        <number>100</number>
-       </attribute>
-       <attribute name="horizontalHeaderStretchLastSection">
-        <bool>true</bool>
-       </attribute>
-       <attribute name="verticalHeaderVisible">
-        <bool>false</bool>
-       </attribute>
-      </widget>
-     </item>
-     <item>
-      <layout class="QVBoxLayout" name="verticalLayout">
-       <item>
-        <widget class="QPushButton" name="addDesktopFileButton">
-         <property name="text">
-          <string>Add Desktop File</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QPushButton" name="addIconButton">
-         <property name="text">
-          <string>Add Launcher Icon...</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <spacer name="verticalSpacer">
-         <property name="orientation">
-          <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>20</width>
-           <height>40</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-      </layout>
-     </item>
-    </layout>
+    <widget class="QPushButton" name="addIconButton">
+     <property name="text">
+      <string>Add Launcher Icon...</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <spacer name="horizontalSpacer">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>40</width>
+       <height>20</height>
+      </size>
+     </property>
+    </spacer>
    </item>
   </layout>
  </widget>
diff --git a/src/plugins/remotelinux/maemoinstalltosysrootstep.cpp b/src/plugins/remotelinux/maemoinstalltosysrootstep.cpp
index f46f5fc0833..33afc0f0259 100644
--- a/src/plugins/remotelinux/maemoinstalltosysrootstep.cpp
+++ b/src/plugins/remotelinux/maemoinstalltosysrootstep.cpp
@@ -32,18 +32,21 @@
 
 #include "maemoinstalltosysrootstep.h"
 
-#include "deploymentinfo.h"
 #include "maemoglobal.h"
 #include "maemopackagecreationstep.h"
 #include "maemoqtversion.h"
-#include "remotelinuxdeployconfiguration.h"
 
 #include <utils/fileutils.h>
 
 #include <qt4projectmanager/qt4buildconfiguration.h>
 #include <qt4projectmanager/qt4target.h>
 #include <qtsupport/baseqtversion.h>
+#include <remotelinux/deployablefile.h>
+#include <remotelinux/deploymentinfo.h>
+#include <remotelinux/remotelinuxdeployconfiguration.h>
 
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
 #include <QtCore/QLatin1Char>
 #include <QtCore/QProcess>
 #include <QtCore/QWeakPointer>
diff --git a/src/plugins/remotelinux/maemopublisherfremantlefree.cpp b/src/plugins/remotelinux/maemopublisherfremantlefree.cpp
index 695969e4bd9..9fd91d1ef37 100644
--- a/src/plugins/remotelinux/maemopublisherfremantlefree.cpp
+++ b/src/plugins/remotelinux/maemopublisherfremantlefree.cpp
@@ -31,13 +31,11 @@
 **************************************************************************/
 #include "maemopublisherfremantlefree.h"
 
-#include "deployablefilesperprofile.h"
-#include "deploymentinfo.h"
 #include "maemoglobal.h"
 #include "maemopackagecreationstep.h"
 #include "maemopublishingfileselectiondialog.h"
+#include "qt4maemodeployconfiguration.h"
 #include "qt4maemotarget.h"
-#include "remotelinuxdeployconfiguration.h"
 
 #include <coreplugin/ifile.h>
 #include <projectexplorer/project.h>
@@ -45,6 +43,8 @@
 #include <qt4projectmanager/qmakestep.h>
 #include <qt4projectmanager/qt4buildconfiguration.h>
 #include <qtsupport/baseqtversion.h>
+#include <remotelinux/deployablefilesperprofile.h>
+#include <remotelinux/deploymentinfo.h>
 #include <utils/fileutils.h>
 #include <utils/qtcassert.h>
 
@@ -533,13 +533,13 @@ void MaemoPublisherFremantleFree::finishWithFailure(const QString &progressMsg,
 bool MaemoPublisherFremantleFree::updateDesktopFiles(QString *error) const
 {
     bool success = true;
-    const RemoteLinuxDeployConfiguration * const deployConfig
-        = qobject_cast<RemoteLinuxDeployConfiguration *>(m_buildConfig->target()->activeDeployConfiguration());
+    const Qt4MaemoDeployConfiguration * const deployConfig
+        = qobject_cast<Qt4MaemoDeployConfiguration *>(m_buildConfig->target()->activeDeployConfiguration());
     const QSharedPointer<DeploymentInfo> deploymentInfo
         = deployConfig->deploymentInfo();
     for (int i = 0; i < deploymentInfo->modelCount(); ++i) {
         const DeployableFilesPerProFile * const model = deploymentInfo->modelAt(i);
-        QString desktopFilePath = model->localDesktopFilePath();
+        QString desktopFilePath = deployConfig->localDesktopFilePath(model);
         if (desktopFilePath.isEmpty())
             continue;
         desktopFilePath.replace(model->projectDir(), m_tmpProjectDir);
diff --git a/src/plugins/remotelinux/qt4maemodeployconfiguration.cpp b/src/plugins/remotelinux/qt4maemodeployconfiguration.cpp
index de82de57581..422915d5873 100644
--- a/src/plugins/remotelinux/qt4maemodeployconfiguration.cpp
+++ b/src/plugins/remotelinux/qt4maemodeployconfiguration.cpp
@@ -29,19 +29,28 @@
 ** Nokia at info@qt.nokia.com.
 **
 **************************************************************************/
-
 #include "qt4maemodeployconfiguration.h"
 
 #include "maddeuploadandinstallpackagesteps.h"
 #include "maemoconstants.h"
 #include "maemodeploybymountsteps.h"
+#include "maemodeployconfigurationwidget.h"
 #include "maemoinstalltosysrootstep.h"
 #include "maemopackagecreationstep.h"
 #include "qt4maemotarget.h"
 
 #include <projectexplorer/buildsteplist.h>
+#include <qt4projectmanager/qt4target.h>
+#include <remotelinux/deployablefilesperprofile.h>
+#include <remotelinux/deploymentinfo.h>
+#include <remotelinux/deploymentsettingsassistant.h>
+#include <utils/qtcassert.h>
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QString>
 
 using namespace ProjectExplorer;
+using namespace Qt4ProjectManager;
 
 namespace RemoteLinux {
 namespace Internal {
@@ -53,24 +62,81 @@ Qt4MaemoDeployConfiguration::Qt4MaemoDeployConfiguration(ProjectExplorer::Target
         const QString &id, const QString &displayName, const QString &supportedOsType)
     : RemoteLinuxDeployConfiguration(target, id, displayName, supportedOsType)
 {
+    const QList<DeployConfiguration *> &deployConfigs = target->deployConfigurations();
+    foreach (const DeployConfiguration * const dc, deployConfigs) {
+        const Qt4MaemoDeployConfiguration * const mdc
+            = qobject_cast<const Qt4MaemoDeployConfiguration *>(dc);
+        if (mdc) {
+            m_deploymentSettingsAssistant = mdc->deploymentSettingsAssistant();
+            break;
+        }
+    }
+    if (!m_deploymentSettingsAssistant) {
+        QString qmakeScope;
+        if (supportedOsType == QLatin1String(Maemo5OsType))
+            qmakeScope = QLatin1String("maemo5");
+        else if (supportedOsType == QLatin1String(HarmattanOsType))
+            qmakeScope = QLatin1String("contains(MEEGO_EDITION,harmattan)");
+        else if (supportedOsType == QLatin1String(MeeGoOsType))
+            qmakeScope = QLatin1String("!isEmpty(MEEGO_VERSION_MAJOR):!contains(MEEGO_EDITION,harmattan)");
+        else
+            qDebug("%s: Unexpected OS type %s", Q_FUNC_INFO, qPrintable(supportedOsType));
+        m_deploymentSettingsAssistant = QSharedPointer<DeploymentSettingsAssistant>
+            (new DeploymentSettingsAssistant(qmakeScope, QLatin1String("/opt"), deploymentInfo()));
+    }
 }
 
 Qt4MaemoDeployConfiguration::Qt4MaemoDeployConfiguration(ProjectExplorer::Target *target,
         Qt4MaemoDeployConfiguration *source)
     : RemoteLinuxDeployConfiguration(target, source)
 {
+    m_deploymentSettingsAssistant = source->deploymentSettingsAssistant();
+}
+
+QSharedPointer<DeploymentSettingsAssistant> Qt4MaemoDeployConfiguration::deploymentSettingsAssistant() const
+{
+    return m_deploymentSettingsAssistant;
+}
+
+QString Qt4MaemoDeployConfiguration::localDesktopFilePath(const DeployableFilesPerProFile *proFileInfo) const
+{
+    QTC_ASSERT(proFileInfo->projectType() == ApplicationTemplate, return QString());
+
+    for (int i = 0; i < proFileInfo->rowCount(); ++i) {
+        const DeployableFile &d = proFileInfo->deployableAt(i);
+        if (QFileInfo(d.localFilePath).fileName().endsWith(QLatin1String(".desktop")))
+            return d.localFilePath;
+    }
+    return QString();
+}
+
+
+DeployConfigurationWidget *Qt4MaemoDeployConfiguration::configurationWidget() const
+{
+    return new MaemoDeployConfigurationWidget;
 }
 
 Qt4MaemoDeployConfiguration::~Qt4MaemoDeployConfiguration() {}
 
-const QString Qt4MaemoDeployConfiguration::FremantleWithPackagingId
-    = QLatin1String("DeployToFremantleWithPackaging");
-const QString Qt4MaemoDeployConfiguration::FremantleWithoutPackagingId
-    = QLatin1String("DeployToFremantleWithoutPackaging");
-const QString Qt4MaemoDeployConfiguration::HarmattanId
-    = QLatin1String("DeployToHarmattan");
-const QString Qt4MaemoDeployConfiguration::MeegoId
-    = QLatin1String("DeployToMeego");
+QString Qt4MaemoDeployConfiguration::fremantleWithPackagingId()
+{
+    return QLatin1String("DeployToFremantleWithPackaging");
+}
+
+QString Qt4MaemoDeployConfiguration::fremantleWithoutPackagingId()
+{
+    return QLatin1String("DeployToFremantleWithoutPackaging");
+}
+
+QString Qt4MaemoDeployConfiguration::harmattanId()
+{
+    return QLatin1String("DeployToHarmattan");
+}
+
+QString Qt4MaemoDeployConfiguration::meegoId()
+{
+    return QLatin1String("DeployToMeego");
+}
 
 
 Qt4MaemoDeployConfigurationFactory::Qt4MaemoDeployConfigurationFactory(QObject *parent)
@@ -81,12 +147,12 @@ QStringList Qt4MaemoDeployConfigurationFactory::availableCreationIds(Target *par
 {
     QStringList ids;
     if (qobject_cast<Qt4Maemo5Target *>(parent)) {
-        ids << Qt4MaemoDeployConfiguration::FremantleWithPackagingId
-            << Qt4MaemoDeployConfiguration::FremantleWithoutPackagingId;
+        ids << Qt4MaemoDeployConfiguration::fremantleWithPackagingId()
+            << Qt4MaemoDeployConfiguration::fremantleWithoutPackagingId();
     } else if (qobject_cast<Qt4HarmattanTarget *>(parent)) {
-        ids << Qt4MaemoDeployConfiguration::HarmattanId;
+        ids << Qt4MaemoDeployConfiguration::harmattanId();
     } else if (qobject_cast<Qt4MeegoTarget *>(parent)) {
-        ids << Qt4MaemoDeployConfiguration::MeegoId;
+        ids << Qt4MaemoDeployConfiguration::meegoId();
     }
 
     return ids;
@@ -94,13 +160,13 @@ QStringList Qt4MaemoDeployConfigurationFactory::availableCreationIds(Target *par
 
 QString Qt4MaemoDeployConfigurationFactory::displayNameForId(const QString &id) const
 {
-    if (id == Qt4MaemoDeployConfiguration::FremantleWithoutPackagingId)
+    if (id == Qt4MaemoDeployConfiguration::fremantleWithoutPackagingId())
         return tr("Copy Files to Maemo5 Device");
-    else if (id == Qt4MaemoDeployConfiguration::FremantleWithPackagingId)
+    else if (id == Qt4MaemoDeployConfiguration::fremantleWithPackagingId())
         return tr("Build Debian Package and Install to Maemo5 Device");
-    else if (id == Qt4MaemoDeployConfiguration::HarmattanId)
+    else if (id == Qt4MaemoDeployConfiguration::harmattanId())
         return tr("Build Debian Package and Install to Harmattan Device");
-    else if (id == Qt4MaemoDeployConfiguration::MeegoId)
+    else if (id == Qt4MaemoDeployConfiguration::meegoId())
         return tr("Build RPM Package and Install to MeeGo Device");
     return QString();
 }
@@ -118,22 +184,22 @@ DeployConfiguration *Qt4MaemoDeployConfigurationFactory::create(Target *parent,
 
     DeployConfiguration *dc = 0;
     const QString displayName = displayNameForId(id);
-    if (id == Qt4MaemoDeployConfiguration::FremantleWithoutPackagingId) {
+    if (id == Qt4MaemoDeployConfiguration::fremantleWithoutPackagingId()) {
         dc = new Qt4MaemoDeployConfiguration(parent, id, displayName, QLatin1String(Maemo5OsType));
         dc->stepList()->insertStep(0, new MaemoMakeInstallToSysrootStep(dc->stepList()));
         dc->stepList()->insertStep(1, new MaemoCopyFilesViaMountStep(dc->stepList()));
-    } else if (id == Qt4MaemoDeployConfiguration::FremantleWithPackagingId) {
+    } else if (id == Qt4MaemoDeployConfiguration::fremantleWithPackagingId()) {
         dc = new Qt4MaemoDeployConfiguration(parent, id, displayName, QLatin1String(Maemo5OsType));
         dc->stepList()->insertStep(0, new MaemoDebianPackageCreationStep(dc->stepList()));
         dc->stepList()->insertStep(1, new MaemoInstallDebianPackageToSysrootStep(dc->stepList()));
         dc->stepList()->insertStep(2, new MaemoInstallPackageViaMountStep(dc->stepList()));
-    } else if (id == Qt4MaemoDeployConfiguration::HarmattanId) {
+    } else if (id == Qt4MaemoDeployConfiguration::harmattanId()) {
         dc = new Qt4MaemoDeployConfiguration(parent, id, displayName,
             QLatin1String(HarmattanOsType));
         dc->stepList()->insertStep(0, new MaemoDebianPackageCreationStep(dc->stepList()));
         dc->stepList()->insertStep(1, new MaemoInstallDebianPackageToSysrootStep(dc->stepList()));
         dc->stepList()->insertStep(2, new MaemoUploadAndInstallPackageStep(dc->stepList()));
-    } else if (id == Qt4MaemoDeployConfiguration::MeegoId) {
+    } else if (id == Qt4MaemoDeployConfiguration::meegoId()) {
         dc = new Qt4MaemoDeployConfiguration(parent, id, displayName, QLatin1String(MeeGoOsType));
         dc->stepList()->insertStep(0, new MaemoRpmPackageCreationStep(dc->stepList()));
         dc->stepList()->insertStep(1, new MaemoInstallRpmPackageToSysrootStep(dc->stepList()));
@@ -158,11 +224,11 @@ DeployConfiguration *Qt4MaemoDeployConfigurationFactory::restore(Target *parent,
     QString id = idFromMap(map);
     if (id == OldDeployConfigId) {
         if (qobject_cast<Qt4Maemo5Target *>(parent))
-            id = Qt4MaemoDeployConfiguration::FremantleWithPackagingId;
+            id = Qt4MaemoDeployConfiguration::fremantleWithPackagingId();
         else if (qobject_cast<Qt4HarmattanTarget *>(parent))
-            id = Qt4MaemoDeployConfiguration::HarmattanId;
+            id = Qt4MaemoDeployConfiguration::harmattanId();
         else if (qobject_cast<Qt4MeegoTarget *>(parent))
-            id = Qt4MaemoDeployConfiguration::MeegoId;
+            id = Qt4MaemoDeployConfiguration::meegoId();
     }
     Qt4MaemoDeployConfiguration * const dc
         = qobject_cast<Qt4MaemoDeployConfiguration *>(create(parent, id));
diff --git a/src/plugins/remotelinux/qt4maemodeployconfiguration.h b/src/plugins/remotelinux/qt4maemodeployconfiguration.h
index 02e76d7ac76..be7226bdf8a 100644
--- a/src/plugins/remotelinux/qt4maemodeployconfiguration.h
+++ b/src/plugins/remotelinux/qt4maemodeployconfiguration.h
@@ -36,6 +36,9 @@
 #include <remotelinux/remotelinuxdeployconfiguration.h>
 
 namespace RemoteLinux {
+class DeployableFilesPerProFile;
+class DeploymentSettingsAssistant;
+
 namespace Internal {
 
 class Qt4MaemoDeployConfigurationFactory : public ProjectExplorer::DeployConfigurationFactory
@@ -57,17 +60,22 @@ public:
         ProjectExplorer::DeployConfiguration *product);
 };
 
-class Qt4MaemoDeployConfiguration : public RemoteLinuxDeployConfiguration
+class Qt4MaemoDeployConfiguration : public RemoteLinux::RemoteLinuxDeployConfiguration
 {
     Q_OBJECT
 
 public:
     ~Qt4MaemoDeployConfiguration();
 
-    static const QString FremantleWithPackagingId;
-    static const QString FremantleWithoutPackagingId;
-    static const QString HarmattanId;
-    static const QString MeegoId;
+    ProjectExplorer::DeployConfigurationWidget *configurationWidget() const;
+
+    QSharedPointer<DeploymentSettingsAssistant> deploymentSettingsAssistant() const;
+    QString localDesktopFilePath(const DeployableFilesPerProFile *proFileInfo) const;
+
+    static QString fremantleWithPackagingId();
+    static QString fremantleWithoutPackagingId();
+    static QString harmattanId();
+    static QString meegoId();
 
 private:
     friend class Internal::Qt4MaemoDeployConfigurationFactory;
@@ -76,6 +84,8 @@ private:
         const QString &displayName, const QString &supportedOsType);
     Qt4MaemoDeployConfiguration(ProjectExplorer::Target *target,
         Qt4MaemoDeployConfiguration *source);
+
+    QSharedPointer<DeploymentSettingsAssistant> m_deploymentSettingsAssistant;
 };
 
 } // namespace Internal
diff --git a/src/plugins/remotelinux/qt4maemotargetfactory.cpp b/src/plugins/remotelinux/qt4maemotargetfactory.cpp
index 0577ede5626..6696f2a819e 100644
--- a/src/plugins/remotelinux/qt4maemotargetfactory.cpp
+++ b/src/plugins/remotelinux/qt4maemotargetfactory.cpp
@@ -199,14 +199,14 @@ ProjectExplorer::Target *Qt4MaemoTargetFactory::create(ProjectExplorer::Project
     QStringList deployConfigIds;
     if (id == QLatin1String(MAEMO5_DEVICE_TARGET_ID)) {
         target = new Qt4Maemo5Target(static_cast<Qt4Project *>(parent), id);
-        deployConfigIds << Qt4MaemoDeployConfiguration::FremantleWithPackagingId
-            << Qt4MaemoDeployConfiguration::FremantleWithoutPackagingId;
+        deployConfigIds << Qt4MaemoDeployConfiguration::fremantleWithPackagingId()
+            << Qt4MaemoDeployConfiguration::fremantleWithoutPackagingId();
     } else if (id == QLatin1String(HARMATTAN_DEVICE_TARGET_ID)) {
         target = new Qt4HarmattanTarget(static_cast<Qt4Project *>(parent), id);
-        deployConfigIds << Qt4MaemoDeployConfiguration::HarmattanId;
+        deployConfigIds << Qt4MaemoDeployConfiguration::harmattanId();
     } else if (id == QLatin1String(MEEGO_DEVICE_TARGET_ID)) {
         target = new Qt4MeegoTarget(static_cast<Qt4Project *>(parent), id);
-        deployConfigIds << Qt4MaemoDeployConfiguration::MeegoId;
+        deployConfigIds << Qt4MaemoDeployConfiguration::meegoId();
     }
     Q_ASSERT(target);
 
diff --git a/src/plugins/remotelinux/remotelinux.pro b/src/plugins/remotelinux/remotelinux.pro
index 158ebd3d365..cd02169e97a 100644
--- a/src/plugins/remotelinux/remotelinux.pro
+++ b/src/plugins/remotelinux/remotelinux.pro
@@ -98,7 +98,9 @@ HEADERS += \
     sshkeycreationdialog.h \
     remotelinuxusedportsgatherer.h \
     remotelinuxsettingspages.h \
-    remotelinuxutils.h
+    remotelinuxutils.h \
+    deploymentsettingsassistant.h \
+    remotelinuxdeployconfigurationwidget.h
 
 SOURCES += \
     remotelinuxplugin.cpp \
@@ -189,7 +191,9 @@ SOURCES += \
     sshkeycreationdialog.cpp \
     remotelinuxusedportsgatherer.cpp \
     remotelinuxsettingspages.cpp \
-    remotelinuxutils.cpp
+    remotelinuxutils.cpp \
+    deploymentsettingsassistant.cpp \
+    remotelinuxdeployconfigurationwidget.cpp
 
 FORMS += \
     maemopackagecreationwidget.ui \
@@ -210,7 +214,8 @@ FORMS += \
     linuxdevicetestdialog.ui \
     remotelinuxprocessesdialog.ui \
     linuxdeviceconfigurationssettingswidget.ui \
-    sshkeycreationdialog.ui
+    sshkeycreationdialog.ui \
+    remotelinuxdeployconfigurationwidget.ui
 
 RESOURCES += qt-maemo.qrc
 DEFINES += QT_NO_CAST_TO_ASCII
diff --git a/src/plugins/remotelinux/remotelinuxdeployconfiguration.cpp b/src/plugins/remotelinux/remotelinuxdeployconfiguration.cpp
index a807aba2381..083b1fe5407 100644
--- a/src/plugins/remotelinux/remotelinuxdeployconfiguration.cpp
+++ b/src/plugins/remotelinux/remotelinuxdeployconfiguration.cpp
@@ -33,7 +33,7 @@
 
 #include "deploymentinfo.h"
 #include "linuxdeviceconfigurations.h"
-#include "maemodeployconfigurationwidget.h"
+#include "remotelinuxdeployconfigurationwidget.h"
 #include "typespecificdeviceconfigurationlistmodel.h"
 
 #include <qt4projectmanager/qt4target.h>
@@ -46,19 +46,30 @@ namespace Internal {
 namespace {
 const char DeviceIdKey[] = "Qt4ProjectManager.MaemoRunConfiguration.DeviceId";
 } // anonymous namespace
+
+class RemoteLinuxDeployConfigurationPrivate
+{
+public:
+    QSharedPointer<DeploymentInfo> deploymentInfo;
+    QSharedPointer<Internal::TypeSpecificDeviceConfigurationListModel> devConfModel;
+    QSharedPointer<const LinuxDeviceConfiguration> deviceConfiguration;
+    QString supportedOsType;
+};
+
 } // namespace Internal
 
 using namespace Internal;
 
 RemoteLinuxDeployConfiguration::RemoteLinuxDeployConfiguration(ProjectExplorer::Target *target,
         const QString &id, const QString &defaultDisplayName, const QString &supportedOsType)
-    : DeployConfiguration(target, id)
+    : DeployConfiguration(target, id), m_d(new RemoteLinuxDeployConfigurationPrivate)
 {
+    m_d->supportedOsType = supportedOsType;
     setDefaultDisplayName(defaultDisplayName);
 
     // A DeploymentInfo object is only dependent on the active build
     // configuration and therefore can (and should) be shared among all
-    // deploy steps. The per-target device configurations model is
+    // deploy configurations. The per-target device configurations model is
     // similarly only dependent on the target.
     const QList<DeployConfiguration *> &deployConfigs
         = this->target()->deployConfigurations();
@@ -66,45 +77,50 @@ RemoteLinuxDeployConfiguration::RemoteLinuxDeployConfiguration(ProjectExplorer::
         const RemoteLinuxDeployConfiguration * const mdc
             = qobject_cast<const RemoteLinuxDeployConfiguration *>(dc);
         if (mdc) {
-            m_deploymentInfo = mdc->deploymentInfo();
-            m_devConfModel = mdc->m_devConfModel;
+            m_d->deploymentInfo = mdc->deploymentInfo();
+            m_d->devConfModel = mdc->m_d->devConfModel;
             break;
         }
     }
-    if (!m_deploymentInfo) {
-        m_deploymentInfo = QSharedPointer<DeploymentInfo>(new DeploymentInfo(qobject_cast<Qt4BaseTarget *>(target)));
-        m_devConfModel = QSharedPointer<TypeSpecificDeviceConfigurationListModel>
-            (new TypeSpecificDeviceConfigurationListModel(0, supportedOsType));
+    if (!m_d->deploymentInfo) {
+        m_d->deploymentInfo = QSharedPointer<DeploymentInfo>(new DeploymentInfo(qobject_cast<Qt4BaseTarget *>(target)));
+        m_d->devConfModel = QSharedPointer<TypeSpecificDeviceConfigurationListModel>
+            (new TypeSpecificDeviceConfigurationListModel(supportedOsType));
     }
 
     initialize();
 }
 
 RemoteLinuxDeployConfiguration::RemoteLinuxDeployConfiguration(ProjectExplorer::Target *target,
-    RemoteLinuxDeployConfiguration *source) : DeployConfiguration(target, source)
+        RemoteLinuxDeployConfiguration *source)
+    : DeployConfiguration(target, source), m_d(new RemoteLinuxDeployConfigurationPrivate)
 {
-    m_deploymentInfo = source->deploymentInfo();
-    m_devConfModel = source->deviceConfigModel();
+    m_d->supportedOsType = source->supportedOsType();
+    m_d->deploymentInfo = source->deploymentInfo();
+    m_d->devConfModel = source->deviceConfigModel();
     initialize();
 }
 
-RemoteLinuxDeployConfiguration::~RemoteLinuxDeployConfiguration() {}
+RemoteLinuxDeployConfiguration::~RemoteLinuxDeployConfiguration()
+{
+    delete m_d;
+}
 
 void RemoteLinuxDeployConfiguration::initialize()
 {
-    m_deviceConfiguration = deviceConfigModel()->defaultDeviceConfig();
+    m_d->deviceConfiguration = deviceConfigModel()->defaultDeviceConfig();
     connect(deviceConfigModel().data(), SIGNAL(updated()),
         SLOT(handleDeviceConfigurationListUpdated()));
 }
 
 void RemoteLinuxDeployConfiguration::handleDeviceConfigurationListUpdated()
 {
-    setDeviceConfig(LinuxDeviceConfigurations::instance()->internalId(m_deviceConfiguration));
+    setDeviceConfig(LinuxDeviceConfigurations::instance()->internalId(m_d->deviceConfiguration));
 }
 
 void RemoteLinuxDeployConfiguration::setDeviceConfig(LinuxDeviceConfiguration::Id internalId)
 {
-    m_deviceConfiguration = deviceConfigModel()->find(internalId);
+    m_d->deviceConfiguration = deviceConfigModel()->find(internalId);
     emit deviceConfigurationListChanged();
     emit currentDeviceConfigurationChanged();
 }
@@ -122,37 +138,42 @@ QVariantMap RemoteLinuxDeployConfiguration::toMap() const
 {
     QVariantMap map = DeployConfiguration::toMap();
     map.insert(QLatin1String(DeviceIdKey),
-        LinuxDeviceConfigurations::instance()->internalId(m_deviceConfiguration));
+        LinuxDeviceConfigurations::instance()->internalId(m_d->deviceConfiguration));
     return map;
 }
 
 void RemoteLinuxDeployConfiguration::setDeviceConfiguration(int index)
 {
     const LinuxDeviceConfiguration::ConstPtr &newDevConf = deviceConfigModel()->deviceAt(index);
-    if (m_deviceConfiguration != newDevConf) {
-        m_deviceConfiguration = newDevConf;
+    if (m_d->deviceConfiguration != newDevConf) {
+        m_d->deviceConfiguration = newDevConf;
         emit currentDeviceConfigurationChanged();
     }
 }
 
 DeployConfigurationWidget *RemoteLinuxDeployConfiguration::configurationWidget() const
 {
-    return new MaemoDeployConfigurationWidget;
+    return new RemoteLinuxDeployConfigurationWidget;
 }
 
 QSharedPointer<DeploymentInfo> RemoteLinuxDeployConfiguration::deploymentInfo() const
 {
-    return m_deploymentInfo;
+    return m_d->deploymentInfo;
 }
 
 QSharedPointer<TypeSpecificDeviceConfigurationListModel> RemoteLinuxDeployConfiguration::deviceConfigModel() const
 {
-    return m_devConfModel;
+    return m_d->devConfModel;
 }
 
 LinuxDeviceConfiguration::ConstPtr RemoteLinuxDeployConfiguration::deviceConfiguration() const
 {
-    return m_deviceConfiguration;
+    return m_d->deviceConfiguration;
+}
+
+QString RemoteLinuxDeployConfiguration::supportedOsType() const
+{
+    return m_d->supportedOsType;
 }
 
 } // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxdeployconfiguration.h b/src/plugins/remotelinux/remotelinuxdeployconfiguration.h
index 962f29a12f6..3b96a43ced9 100644
--- a/src/plugins/remotelinux/remotelinuxdeployconfiguration.h
+++ b/src/plugins/remotelinux/remotelinuxdeployconfiguration.h
@@ -45,6 +45,7 @@ namespace RemoteLinux {
 class DeploymentInfo;
 
 namespace Internal {
+class RemoteLinuxDeployConfigurationPrivate;
 class TypeSpecificDeviceConfigurationListModel;
 } // namespace Internal
 
@@ -67,6 +68,7 @@ public:
     QSharedPointer<DeploymentInfo> deploymentInfo() const;
     QSharedPointer<Internal::TypeSpecificDeviceConfigurationListModel> deviceConfigModel() const;
     QSharedPointer<const LinuxDeviceConfiguration> deviceConfiguration() const;
+    QString supportedOsType() const;
 
     template<class T> T *earlierBuildStep(const ProjectExplorer::BuildStep *laterBuildStep) const
     {
@@ -91,9 +93,7 @@ private:
     void setDeviceConfig(LinuxDeviceConfiguration::Id internalId);
     Q_SLOT void handleDeviceConfigurationListUpdated();
 
-    QSharedPointer<DeploymentInfo> m_deploymentInfo;
-    QSharedPointer<Internal::TypeSpecificDeviceConfigurationListModel> m_devConfModel;
-    QSharedPointer<const LinuxDeviceConfiguration> m_deviceConfiguration;
+    Internal::RemoteLinuxDeployConfigurationPrivate * const m_d;
 };
 
 } // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.cpp b/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.cpp
new file mode 100644
index 00000000000..a1b46d0a258
--- /dev/null
+++ b/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.cpp
@@ -0,0 +1,165 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** GNU Lesser General Public License Usage
+**
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+#include "remotelinuxdeployconfigurationwidget.h"
+#include "ui_remotelinuxdeployconfigurationwidget.h"
+
+#include "deployablefilesperprofile.h"
+#include "deploymentinfo.h"
+#include "linuxdeviceconfigurations.h"
+#include "remotelinuxdeployconfiguration.h"
+#include "remotelinuxsettingspages.h"
+#include "typespecificdeviceconfigurationlistmodel.h"
+
+#include <coreplugin/icore.h>
+#include <utils/qtcassert.h>
+
+using namespace ProjectExplorer;
+
+namespace RemoteLinux {
+namespace Internal {
+
+class RemoteLinuxDeployConfigurationWidgetPrivate
+{
+public:
+    Ui::RemoteLinuxDeployConfigurationWidget ui;
+    RemoteLinuxDeployConfiguration *deployConfiguration;
+};
+
+} // namespace Internal
+
+using namespace Internal;
+
+RemoteLinuxDeployConfigurationWidget::RemoteLinuxDeployConfigurationWidget(QWidget *parent) :
+    DeployConfigurationWidget(parent), m_d(new RemoteLinuxDeployConfigurationWidgetPrivate)
+{
+    m_d->ui.setupUi(this);
+}
+
+RemoteLinuxDeployConfigurationWidget::~RemoteLinuxDeployConfigurationWidget()
+{
+    delete m_d;
+}
+
+void RemoteLinuxDeployConfigurationWidget::init(DeployConfiguration *dc)
+{
+    m_d->deployConfiguration = qobject_cast<RemoteLinuxDeployConfiguration *>(dc);
+    Q_ASSERT(m_d->deployConfiguration);
+
+    connect(m_d->ui.manageDevConfsLabel, SIGNAL(linkActivated(QString)),
+        SLOT(showDeviceConfigurations()));
+
+    m_d->ui.deviceConfigsComboBox->setModel(m_d->deployConfiguration->deviceConfigModel().data());
+    connect(m_d->ui.deviceConfigsComboBox, SIGNAL(activated(int)),
+        SLOT(handleSelectedDeviceConfigurationChanged(int)));
+    connect(m_d->deployConfiguration, SIGNAL(deviceConfigurationListChanged()),
+        SLOT(handleDeviceConfigurationListChanged()));
+    handleDeviceConfigurationListChanged();
+
+    m_d->ui.projectsComboBox->setModel(m_d->deployConfiguration->deploymentInfo().data());
+    connect(m_d->deployConfiguration->deploymentInfo().data(), SIGNAL(modelAboutToBeReset()),
+        SLOT(handleModelListToBeReset()));
+
+    // Queued connection because of race condition with combo box's reaction
+    // to modelReset().
+    connect(m_d->deployConfiguration->deploymentInfo().data(), SIGNAL(modelReset()),
+        SLOT(handleModelListReset()), Qt::QueuedConnection);
+
+    connect(m_d->ui.projectsComboBox, SIGNAL(currentIndexChanged(int)), SLOT(setModel(int)));
+    handleModelListReset();
+}
+
+RemoteLinuxDeployConfiguration *RemoteLinuxDeployConfigurationWidget::deployConfiguration() const
+{
+    return m_d->deployConfiguration;
+}
+
+DeployableFilesPerProFile *RemoteLinuxDeployConfigurationWidget::currentModel() const
+{
+    const int modelRow = m_d->ui.projectsComboBox->currentIndex();
+    if (modelRow == -1)
+        return 0;
+    return m_d->deployConfiguration->deploymentInfo()->modelAt(modelRow);
+}
+
+void RemoteLinuxDeployConfigurationWidget::handleModelListToBeReset()
+{
+    m_d->ui.tableView->setModel(0);
+}
+
+void RemoteLinuxDeployConfigurationWidget::handleModelListReset()
+{
+    QTC_ASSERT(m_d->deployConfiguration->deploymentInfo()->modelCount()
+        == m_d->ui.projectsComboBox->count(), return);
+
+    if (m_d->deployConfiguration->deploymentInfo()->modelCount() > 0) {
+        if (m_d->ui.projectsComboBox->currentIndex() == -1)
+            m_d->ui.projectsComboBox->setCurrentIndex(0);
+        else
+            setModel(m_d->ui.projectsComboBox->currentIndex());
+    }
+}
+
+void RemoteLinuxDeployConfigurationWidget::setModel(int row)
+{
+    DeployableFilesPerProFile * const proFileInfo = row == -1
+        ? 0 : m_d->deployConfiguration->deploymentInfo()->modelAt(row);
+    m_d->ui.tableView->setModel(proFileInfo);
+    if (proFileInfo)
+        m_d->ui.tableView->resizeRowsToContents();
+    emit currentModelChanged(proFileInfo);
+}
+
+void RemoteLinuxDeployConfigurationWidget::handleSelectedDeviceConfigurationChanged(int index)
+{
+    disconnect(m_d->deployConfiguration, SIGNAL(deviceConfigurationListChanged()), this,
+        SLOT(handleDeviceConfigurationListChanged()));
+    m_d->deployConfiguration->setDeviceConfiguration(index);
+    connect(m_d->deployConfiguration, SIGNAL(deviceConfigurationListChanged()),
+        SLOT(handleDeviceConfigurationListChanged()));
+}
+
+void RemoteLinuxDeployConfigurationWidget::handleDeviceConfigurationListChanged()
+{
+    const LinuxDeviceConfiguration::ConstPtr &devConf
+        = m_d->deployConfiguration->deviceConfiguration();
+    const LinuxDeviceConfiguration::Id internalId
+        = LinuxDeviceConfigurations::instance()->internalId(devConf);
+    const int newIndex = m_d->deployConfiguration->deviceConfigModel()->indexForInternalId(internalId);
+    m_d->ui.deviceConfigsComboBox->setCurrentIndex(newIndex);
+}
+
+void RemoteLinuxDeployConfigurationWidget::showDeviceConfigurations()
+{
+    Core::ICore::instance()->showOptionsDialog(LinuxDeviceConfigurationsSettingsPage::pageCategory(),
+        LinuxDeviceConfigurationsSettingsPage::pageId());
+}
+
+} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.h b/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.h
new file mode 100644
index 00000000000..4a4e6dbf57d
--- /dev/null
+++ b/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.h
@@ -0,0 +1,79 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** GNU Lesser General Public License Usage
+**
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+#ifndef REMOTELINUXDEPLOYCONFIGURATIONWIDGET_H
+#define REMOTELINUXDEPLOYCONFIGURATIONWIDGET_H
+
+#include "remotelinux_export.h"
+
+#include <projectexplorer/deployconfiguration.h>
+
+#include <QtGui/QWidget>
+
+namespace RemoteLinux {
+class DeployableFilesPerProFile;
+class RemoteLinuxDeployConfiguration;
+
+namespace Internal {
+class RemoteLinuxDeployConfigurationWidgetPrivate;
+} // namespace Internal
+
+class REMOTELINUX_EXPORT RemoteLinuxDeployConfigurationWidget
+    : public ProjectExplorer::DeployConfigurationWidget
+{
+    Q_OBJECT
+
+public:
+    explicit RemoteLinuxDeployConfigurationWidget(QWidget *parent = 0);
+    ~RemoteLinuxDeployConfigurationWidget();
+
+    void init(ProjectExplorer::DeployConfiguration *dc);
+
+    RemoteLinuxDeployConfiguration *deployConfiguration() const;
+    DeployableFilesPerProFile *currentModel() const;
+
+signals:
+    void currentModelChanged(const DeployableFilesPerProFile *proFileInfo);
+
+private slots:
+    void handleModelListToBeReset();
+    void handleModelListReset();
+    void setModel(int row);
+    void handleSelectedDeviceConfigurationChanged(int index);
+    void handleDeviceConfigurationListChanged();
+    void showDeviceConfigurations();
+
+private:
+    Internal::RemoteLinuxDeployConfigurationWidgetPrivate * const m_d;
+};
+
+} // namespace RemoteLinux
+
+#endif // REMOTELINUXDEPLOYCONFIGURATIONWIDGET_H
diff --git a/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.ui b/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.ui
new file mode 100644
index 00000000000..8b2ca89497a
--- /dev/null
+++ b/src/plugins/remotelinux/remotelinuxdeployconfigurationwidget.ui
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>RemoteLinuxDeployConfigurationWidget</class>
+ <widget class="QWidget" name="RemoteLinuxDeployConfigurationWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>617</width>
+    <height>361</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QFormLayout" name="formLayout">
+     <item row="0" column="0">
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>Device configuration:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <layout class="QHBoxLayout" name="horizontalLayout_2">
+       <item>
+        <widget class="QComboBox" name="deviceConfigsComboBox"/>
+       </item>
+       <item>
+        <widget class="QLabel" name="manageDevConfsLabel">
+         <property name="text">
+          <string>&lt;a href=&quot;irrelevant&quot;&gt;Manage device configurations&lt;/a&gt;</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>40</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="installLabel">
+       <property name="toolTip">
+        <string>These show the INSTALLS settings from the project file(s).</string>
+       </property>
+       <property name="text">
+        <string>Files to install for subproject:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <layout class="QHBoxLayout" name="horizontalLayout">
+       <item>
+        <widget class="QComboBox" name="projectsComboBox">
+         <property name="sizeAdjustPolicy">
+          <enum>QComboBox::AdjustToContents</enum>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer_2">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>40</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QTableView" name="tableView">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>150</height>
+      </size>
+     </property>
+     <property name="toolTip">
+      <string>Edit the project file to add or remove entries.</string>
+     </property>
+     <property name="textElideMode">
+      <enum>Qt::ElideMiddle</enum>
+     </property>
+     <property name="horizontalScrollMode">
+      <enum>QAbstractItemView::ScrollPerPixel</enum>
+     </property>
+     <property name="showGrid">
+      <bool>false</bool>
+     </property>
+     <property name="wordWrap">
+      <bool>false</bool>
+     </property>
+     <attribute name="horizontalHeaderDefaultSectionSize">
+      <number>400</number>
+     </attribute>
+     <attribute name="horizontalHeaderHighlightSections">
+      <bool>false</bool>
+     </attribute>
+     <attribute name="horizontalHeaderMinimumSectionSize">
+      <number>100</number>
+     </attribute>
+     <attribute name="horizontalHeaderStretchLastSection">
+      <bool>true</bool>
+     </attribute>
+     <attribute name="verticalHeaderVisible">
+      <bool>false</bool>
+     </attribute>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/plugins/remotelinux/tarpackagecreationstep.cpp b/src/plugins/remotelinux/tarpackagecreationstep.cpp
index a0f718265e8..fe616fe4e47 100644
--- a/src/plugins/remotelinux/tarpackagecreationstep.cpp
+++ b/src/plugins/remotelinux/tarpackagecreationstep.cpp
@@ -37,6 +37,7 @@
 #include <projectexplorer/project.h>
 #include <projectexplorer/target.h>
 
+#include <QtCore/QDateTime>
 #include <QtCore/QDir>
 #include <QtCore/QFile>
 #include <QtCore/QFileInfo>
diff --git a/src/plugins/remotelinux/typespecificdeviceconfigurationlistmodel.cpp b/src/plugins/remotelinux/typespecificdeviceconfigurationlistmodel.cpp
index 668dd616f38..be342dc8be8 100644
--- a/src/plugins/remotelinux/typespecificdeviceconfigurationlistmodel.cpp
+++ b/src/plugins/remotelinux/typespecificdeviceconfigurationlistmodel.cpp
@@ -37,8 +37,8 @@
 namespace RemoteLinux {
 namespace Internal {
 
-TypeSpecificDeviceConfigurationListModel::TypeSpecificDeviceConfigurationListModel(QObject *parent,
-    const QString &osType) : QAbstractListModel(parent), m_targetOsType(osType)
+TypeSpecificDeviceConfigurationListModel::TypeSpecificDeviceConfigurationListModel(const QString &osType,
+    QObject *parent) : QAbstractListModel(parent), m_targetOsType(osType)
 {
     const LinuxDeviceConfigurations * const devConfs
         = LinuxDeviceConfigurations::instance();
diff --git a/src/plugins/remotelinux/typespecificdeviceconfigurationlistmodel.h b/src/plugins/remotelinux/typespecificdeviceconfigurationlistmodel.h
index 4ba72814255..9695ea9a716 100644
--- a/src/plugins/remotelinux/typespecificdeviceconfigurationlistmodel.h
+++ b/src/plugins/remotelinux/typespecificdeviceconfigurationlistmodel.h
@@ -44,7 +44,7 @@ class TypeSpecificDeviceConfigurationListModel : public QAbstractListModel
 {
     Q_OBJECT
 public:
-    explicit TypeSpecificDeviceConfigurationListModel(QObject *parent, const QString &osType);
+    explicit TypeSpecificDeviceConfigurationListModel(const QString &osType, QObject *parent = 0);
     ~TypeSpecificDeviceConfigurationListModel();
 
     virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
-- 
GitLab