From ee85384cc99279a312289fb1baa98677b588a4b7 Mon Sep 17 00:00:00 2001
From: Christian Kandeler <christian.kandeler@nokia.com>
Date: Thu, 16 Sep 2010 14:11:15 +0200
Subject: [PATCH] QML/Mobile wizard: Factor out common parts.

Reviewed-by: Alessandro Portale
---
 .../qt4projectmanager/qt4projectmanager.pro   |   2 +
 .../wizards/abstractmobileapp.cpp             | 407 ++++++++++++++++
 .../wizards/abstractmobileapp.h               | 170 +++++++
 .../qt4projectmanager/wizards/mobileapp.cpp   | 359 ++------------
 .../qt4projectmanager/wizards/mobileapp.h     | 103 +---
 .../wizards/qmlstandaloneapp.cpp              | 448 ++++--------------
 .../wizards/qmlstandaloneapp.h                | 106 +----
 tests/manual/qmlstandalone/main.cpp           |   6 +-
 tests/manual/qmlstandalone/qmlstandalone.pro  |   4 +-
 9 files changed, 765 insertions(+), 840 deletions(-)
 create mode 100644 src/plugins/qt4projectmanager/wizards/abstractmobileapp.cpp
 create mode 100644 src/plugins/qt4projectmanager/wizards/abstractmobileapp.h

diff --git a/src/plugins/qt4projectmanager/qt4projectmanager.pro b/src/plugins/qt4projectmanager/qt4projectmanager.pro
index 18136288610..caa5bcb1887 100644
--- a/src/plugins/qt4projectmanager/qt4projectmanager.pro
+++ b/src/plugins/qt4projectmanager/qt4projectmanager.pro
@@ -36,6 +36,7 @@ HEADERS += qt4deployconfiguration.h \
     wizards/targetsetuppage.h \
     wizards/qmlstandaloneappwizard.h \
     wizards/qmlstandaloneappwizardpages.h \
+    wizards/abstractmobileapp.h \
     wizards/qmlstandaloneapp.h \
     qt4projectmanagerconstants.h \
     makestep.h \
@@ -90,6 +91,7 @@ SOURCES += qt4projectmanagerplugin.cpp \
     wizards/targetsetuppage.cpp \
     wizards/qmlstandaloneappwizard.cpp \
     wizards/qmlstandaloneappwizardpages.cpp \
+    wizards/abstractmobileapp.cpp \
     wizards/qmlstandaloneapp.cpp \
     makestep.cpp \
     qmakestep.cpp \
diff --git a/src/plugins/qt4projectmanager/wizards/abstractmobileapp.cpp b/src/plugins/qt4projectmanager/wizards/abstractmobileapp.cpp
new file mode 100644
index 00000000000..303981cb9ab
--- /dev/null
+++ b/src/plugins/qt4projectmanager/wizards/abstractmobileapp.cpp
@@ -0,0 +1,407 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "abstractmobileapp.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QTextStream>
+
+#ifndef CREATORLESSTEST
+#include <coreplugin/icore.h>
+#endif // CREATORLESSTEST
+
+namespace Qt4ProjectManager {
+namespace Internal {
+
+AbstractGeneratedFileInfo::AbstractGeneratedFileInfo()
+    : fileType(ExtendedFile)
+    , version(-1)
+    , dataChecksum(0)
+    , statedChecksum(0)
+{
+}
+
+bool AbstractGeneratedFileInfo::isUpToDate() const
+{
+    return !isOutdated() && !wasModified();
+}
+
+bool AbstractGeneratedFileInfo::wasModified() const
+{
+    return dataChecksum != statedChecksum;
+}
+
+
+const QString AbstractMobileApp::CFileComment(QLatin1String("//"));
+const QString AbstractMobileApp::ProFileComment(QLatin1String("#"));
+const QString AbstractMobileApp::DeploymentPriFileName(QLatin1String("deployment.pri"));
+const QString AbstractMobileApp::FileChecksum(QLatin1String("checksum"));
+const QString AbstractMobileApp::FileStubVersion(QLatin1String("version"));
+const int AbstractMobileApp::StubVersion = 1;
+
+AbstractMobileApp::AbstractMobileApp()
+    : m_orientation(Auto), m_networkEnabled(false)
+{
+}
+
+AbstractMobileApp::~AbstractMobileApp() { }
+
+QString AbstractMobileApp::symbianUidForPath(const QString &path)
+{
+    quint32 hash = 5381;
+    for (int i = 0; i < path.size(); ++i) {
+        const char c = path.at(i).toAscii();
+        hash ^= c + ((c - i) << i % 20) + ((c + i) << (i + 5) % 20) + ((c - 2 * i) << (i + 10) % 20) + ((c + 2 * i) << (i + 15) % 20);
+    }
+    return QString::fromLatin1("0xE")
+            + QString::fromLatin1("%1").arg(hash, 7, 16, QLatin1Char('0')).right(7);
+}
+
+void AbstractMobileApp::setOrientation(Orientation orientation)
+{
+    m_orientation = orientation;
+}
+
+AbstractMobileApp::Orientation AbstractMobileApp::orientation() const
+{
+    return m_orientation;
+}
+
+void AbstractMobileApp::setProjectName(const QString &name)
+{
+    m_projectName = name;
+}
+
+QString AbstractMobileApp::projectName() const
+{
+    return m_projectName;
+}
+
+void AbstractMobileApp::setProjectPath(const QString &path)
+{
+    m_projectPath.setFile(path);
+}
+
+void AbstractMobileApp::setSymbianSvgIcon(const QString &icon)
+{
+    m_symbianSvgIcon = icon;
+}
+
+QString AbstractMobileApp::symbianSvgIcon() const
+{
+    return path(SymbianSvgIconOrigin);
+}
+
+void AbstractMobileApp::setMaemoPngIcon(const QString &icon)
+{
+    m_maemoPngIcon = icon;
+}
+
+QString AbstractMobileApp::maemoPngIcon() const
+{
+    return path(MaemoPngIconOrigin);
+}
+
+void AbstractMobileApp::setSymbianTargetUid(const QString &uid)
+{
+    m_symbianTargetUid = uid;
+}
+
+QString AbstractMobileApp::symbianTargetUid() const
+{
+    return !m_symbianTargetUid.isEmpty() ? m_symbianTargetUid
+        : symbianUidForPath(path(AppPro));
+}
+
+void AbstractMobileApp::setNetworkEnabled(bool enabled)
+{
+    m_networkEnabled = enabled;
+}
+
+bool AbstractMobileApp::networkEnabled() const
+{
+    return m_networkEnabled;
+}
+
+QString AbstractMobileApp::path(int fileType) const
+{
+    const QString originsRootApp = originsRoot();
+    const QString originsRootShared = templatesRoot() + QLatin1String("shared/");
+    const QString mainCppFileName = QLatin1String("main.cpp");
+    const QString symbianIconFileName = QLatin1String("symbianicon.svg");
+    switch (fileType) {
+        case MainCpp:               return outputPathBase() + mainCppFileName;
+        case MainCppOrigin:         return originsRootApp + mainCppFileName;
+        case AppPro:                return outputPathBase() + m_projectName + QLatin1String(".pro");
+        case AppProOrigin:          return originsRootApp + QLatin1String("app.pro");
+        case AppProPath:            return outputPathBase();
+        case Desktop:               return outputPathBase() + m_projectName + QLatin1String(".desktop");
+        case DesktopOrigin:         return originsRootShared + QLatin1String("app.desktop");
+        case DeploymentPri:         return outputPathBase() + DeploymentPriFileName;
+        case DeploymentPriOrigin:   return originsRootShared + DeploymentPriFileName;
+        case SymbianSvgIcon:        return outputPathBase() + symbianIconFileName;
+        case SymbianSvgIconOrigin:  return !m_symbianSvgIcon.isEmpty() ? m_symbianSvgIcon
+                                        : originsRootShared + symbianIconFileName;
+        case MaemoPngIcon:          return outputPathBase() + projectName() +  QLatin1String(".png");
+        case MaemoPngIconOrigin:    return !m_maemoPngIcon.isEmpty() ? m_maemoPngIcon
+                                        : originsRootShared + QLatin1String("maemoicon.png");
+        default:                    return pathExtended(fileType);
+    }
+    return QString();
+}
+
+QByteArray AbstractMobileApp::generateDesktopFile(QString *errorMessage) const
+{
+    QFile desktopTemplate(path(DesktopOrigin));
+    if (!desktopTemplate.open(QIODevice::ReadOnly)) {
+        *errorMessage = QCoreApplication::translate("AbstractMobileApp",
+            "Could not open desktop file template");
+        return QByteArray();
+    }
+    QByteArray desktopFileContent = desktopTemplate.readAll();
+    return desktopFileContent.replace("thisApp", projectName().toUtf8());
+}
+
+QByteArray AbstractMobileApp::generateMainCpp(QString *errorMessage) const
+{
+    QFile sourceFile(path(MainCppOrigin));
+    if (!sourceFile.open(QIODevice::ReadOnly)) {
+        *errorMessage = tr("Could not open main.cpp template '%1'.")
+            .arg(sourceFile.fileName());
+        return QByteArray();
+    }
+    QTextStream in(&sourceFile);
+
+    QByteArray mainCppContent;
+    QTextStream out(&mainCppContent, QIODevice::WriteOnly);
+
+    QString line;
+    while (!(line = in.readLine()).isNull()) {
+        bool adaptLine = true;
+        if (line.contains(QLatin1String("// ORIENTATION"))) {
+            const char *orientationString;
+            switch (orientation()) {
+            case LockLandscape:
+                orientationString = "LockLandscape";
+                break;
+            case LockPortrait:
+                orientationString = "LockPortrait";
+                break;
+            case Auto:
+                orientationString = "Auto";
+                break;
+            }
+            insertParameter(line, mainWindowClassName() + QLatin1String("::")
+                + QLatin1String(orientationString));
+        } else {
+            adaptLine = adaptCurrentMainCppTemplateLine(line);
+        }
+        if (adaptLine) {
+            const int commentIndex = line.indexOf(QLatin1String(" //"));
+            if (commentIndex != -1)
+                line.truncate(commentIndex);
+            out << line << endl;
+        }
+    }
+
+    return mainCppContent;
+}
+
+QByteArray AbstractMobileApp::generateProFile(QString *errorMessage) const
+{
+    const QChar comment = QLatin1Char('#');
+    QFile proFile(path(AppProOrigin));
+    if (!proFile.open(QIODevice::ReadOnly)) {
+        *errorMessage = tr("Could not open project file template '%1'.")
+            .arg(proFile.fileName());
+        return QByteArray();
+    }
+    QTextStream in(&proFile);
+
+    QByteArray proFileContent;
+    QTextStream out(&proFileContent, QIODevice::WriteOnly);
+
+    QString valueOnNextLine;
+    bool uncommentNextLine = false;
+    QString line;
+    while (!(line = in.readLine()).isNull()) {
+        if (line.contains(QLatin1String("# TARGETUID3"))) {
+            valueOnNextLine = symbianTargetUid();
+        } else if (line.contains(QLatin1String("# ORIENTATIONLOCK"))
+            && orientation() == Auto) {
+            uncommentNextLine = true;
+        } else if (line.contains(QLatin1String("# NETWORKACCESS"))
+            && !networkEnabled()) {
+            uncommentNextLine = true;
+        } else {
+            handleCurrentProFileTemplateLine(line, in, out, uncommentNextLine);
+        }
+
+        // Remove all marker comments
+        if (line.trimmed().startsWith(comment)
+            && line.trimmed().endsWith(comment))
+            continue;
+
+        if (!valueOnNextLine.isEmpty()) {
+            out << line.left(line.indexOf(QLatin1Char('=')) + 2)
+                << QDir::fromNativeSeparators(valueOnNextLine) << endl;
+            valueOnNextLine.clear();
+            continue;
+        }
+
+        if (uncommentNextLine) {
+            out << comment << line << endl;
+            uncommentNextLine = false;
+            continue;
+        }
+        out << line << endl;
+    };
+
+    proFileContent.replace("../shared/" + DeploymentPriFileName.toAscii(),
+        DeploymentPriFileName.toAscii());
+    return proFileContent;
+}
+
+#ifndef CREATORLESSTEST
+// The definition of QmlStandaloneApp::templatesRoot() for
+// CREATORLESSTEST is in tests/manual/qmlstandalone/main.cpp
+QString AbstractMobileApp::templatesRoot()
+{
+    return Core::ICore::instance()->resourcePath()
+        + QLatin1String("/templates/");
+}
+
+Core::GeneratedFile AbstractMobileApp::file(const QByteArray &data,
+    const QString &targetFile)
+{
+    Core::GeneratedFile generatedFile(targetFile);
+    generatedFile.setBinary(true);
+    generatedFile.setBinaryContents(data);
+    return generatedFile;
+}
+
+Core::GeneratedFiles AbstractMobileApp::generateFiles(QString *errorMessage) const
+{
+    Core::GeneratedFiles files;
+    files << file(generateFile(AbstractGeneratedFileInfo::AppProFile, errorMessage), path(AppPro));
+    files.last().setAttributes(Core::GeneratedFile::OpenProjectAttribute);
+    files << file(generateFile(AbstractGeneratedFileInfo::MainCppFile, errorMessage), path(MainCpp));
+    files << file(generateFile(AbstractGeneratedFileInfo::SymbianSvgIconFile, errorMessage), path(SymbianSvgIcon));
+    files << file(generateFile(AbstractGeneratedFileInfo::MaemoPngIconFile, errorMessage), path(MaemoPngIcon));
+    files << file(generateFile(AbstractGeneratedFileInfo::DesktopFile, errorMessage), path(Desktop));
+    files << file(generateFile(AbstractGeneratedFileInfo::DeploymentPriFile, errorMessage), path(DeploymentPri));
+    return files;
+}
+#endif // CREATORLESSTEST
+
+QString AbstractMobileApp::error() const
+{
+    return m_error;
+}
+
+QByteArray AbstractMobileApp::readBlob(const QString &filePath,
+    QString *errorMsg) const
+{
+    QFile sourceFile(filePath);
+    if (!sourceFile.open(QIODevice::ReadOnly)) {
+        *errorMsg = QCoreApplication::translate("AbstractMobileApp",
+            "Could not open template file '%1'.").arg(filePath);
+        return QByteArray();
+    }
+    return sourceFile.readAll();
+}
+
+QByteArray AbstractMobileApp::generateFile(int fileType,
+    QString *errorMessage) const
+{
+    QByteArray data;
+    QString comment = CFileComment;
+    bool versionAndChecksum = false;
+    switch (fileType) {
+        case AbstractGeneratedFileInfo::MainCppFile:
+            data = generateMainCpp(errorMessage);
+            break;
+        case AbstractGeneratedFileInfo::AppProFile:
+            data = generateProFile(errorMessage);
+            comment = ProFileComment;
+            break;
+        case AbstractGeneratedFileInfo::SymbianSvgIconFile:
+            data = readBlob(path(SymbianSvgIconOrigin), errorMessage);
+            break;
+        case AbstractGeneratedFileInfo::MaemoPngIconFile:
+            data = readBlob(path(MaemoPngIconOrigin), errorMessage);
+            break;
+        case AbstractGeneratedFileInfo::DesktopFile:
+            data = generateDesktopFile(errorMessage);
+            break;
+        case AbstractGeneratedFileInfo::DeploymentPriFile:
+            data = readBlob(path(DeploymentPriOrigin), errorMessage);
+            comment = ProFileComment;
+            versionAndChecksum = true;
+            break;
+        default:
+            data = generateFileExtended(fileType, &versionAndChecksum,
+                &comment, errorMessage);
+    }
+    if (!versionAndChecksum)
+        return data;
+    QByteArray versioned = data;
+    versioned.replace('\x0D', "");
+    versioned.replace('\x0A', "");
+    const quint16 checkSum = qChecksum(versioned.constData(), versioned.length());
+    const QString checkSumString = QString::number(checkSum, 16);
+    const QString versionString = QString::number(makeStubVersion(stubVersionMinor()));
+    const QChar sep = QLatin1Char(' ');
+    const QString versionLine =
+            comment + sep + FileChecksum + sep + QLatin1String("0x") + checkSumString
+            + sep + FileStubVersion + sep + versionString + QLatin1Char('\x0A');
+    return versionLine.toAscii() + data;
+}
+
+int AbstractMobileApp::makeStubVersion(int minor)
+{
+    return StubVersion << 16 | minor;
+}
+
+QString AbstractMobileApp::outputPathBase() const
+{
+    return m_projectPath.absoluteFilePath() + QLatin1Char('/')
+        + projectName() + QLatin1Char('/');
+}
+
+void AbstractMobileApp::insertParameter(QString &line, const QString &parameter)
+{
+    line.replace(QRegExp(QLatin1String("\\([^()]+\\)")),
+        QLatin1Char('(') + parameter + QLatin1Char(')'));
+}
+
+} // namespace Internal
+} // namespace Qt4ProjectManager
diff --git a/src/plugins/qt4projectmanager/wizards/abstractmobileapp.h b/src/plugins/qt4projectmanager/wizards/abstractmobileapp.h
new file mode 100644
index 00000000000..23af085b45b
--- /dev/null
+++ b/src/plugins/qt4projectmanager/wizards/abstractmobileapp.h
@@ -0,0 +1,170 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef ABSTRACTMOBILEAPP_H
+#define ABSTRACTMOBILEAPP_H
+
+#include <QtCore/QFileInfo>
+
+#ifndef CREATORLESSTEST
+#include <coreplugin/basefilewizard.h>
+#endif // CREATORLESSTEST
+
+QT_FORWARD_DECLARE_CLASS(QTextStream);
+
+namespace Qt4ProjectManager {
+namespace Internal {
+
+struct AbstractGeneratedFileInfo
+{
+    enum FileType {
+        MainQmlFile,
+        MainCppFile,
+        AppProFile,
+        DeploymentPriFile,
+        SymbianSvgIconFile,
+        MaemoPngIconFile,
+        DesktopFile,
+        ExtendedFile
+    };
+
+    AbstractGeneratedFileInfo();
+
+    bool isUpToDate() const;
+    bool wasModified() const;
+    virtual bool isOutdated() const=0;
+
+    int fileType;
+    QFileInfo fileInfo;
+    int version;
+    quint16 dataChecksum;
+    quint16 statedChecksum;
+};
+
+class AbstractMobileApp : public QObject
+{
+public:
+    enum Orientation {
+        LockLandscape,
+        LockPortrait,
+        Auto
+    };
+
+    enum FileType {
+        MainCpp,
+        MainCppOrigin,
+        AppPro,
+        AppProOrigin,
+        AppProPath,
+        Desktop,
+        DesktopOrigin,
+        DeploymentPri,
+        DeploymentPriOrigin,
+        SymbianSvgIcon,
+        SymbianSvgIconOrigin,
+        MaemoPngIcon,
+        MaemoPngIconOrigin,
+        ExtendedFile
+    };
+
+    virtual ~AbstractMobileApp();
+
+    void setOrientation(Orientation orientation);
+    Orientation orientation() const;
+    void setProjectName(const QString &name);
+    QString projectName() const;
+    void setProjectPath(const QString &path);
+    void setSymbianSvgIcon(const QString &icon);
+    QString symbianSvgIcon() const;
+    void setMaemoPngIcon(const QString &icon);
+    QString maemoPngIcon() const;
+    void setSymbianTargetUid(const QString &uid);
+    QString symbianTargetUid() const;
+    void setNetworkEnabled(bool enabled);
+    bool networkEnabled() const;
+
+    static QString symbianUidForPath(const QString &path);
+    static int makeStubVersion(int minor);
+    QString path(int fileType) const;
+    QString error() const;
+
+    static const QString DeploymentPriFileName;
+protected:
+    AbstractMobileApp();
+
+    static QString templatesRoot();
+    static void insertParameter(QString &line, const QString &parameter);
+
+    QByteArray readBlob(const QString &filePath, QString *errorMsg) const;
+#ifndef CREATORLESSTEST
+    virtual Core::GeneratedFiles generateFiles(QString *errorMessage) const;
+    static Core::GeneratedFile file(const QByteArray &data,
+        const QString &targetFile);
+#else
+    bool generateFiles(QString *errorMessage) const;
+#endif // CREATORLESSTEST
+    QByteArray generateFile(int fileType, QString *errorMessage) const;
+    QString outputPathBase() const;
+
+    static const QString CFileComment;
+    static const QString ProFileComment;
+    static const QString FileChecksum;
+    static const QString FileStubVersion;
+    static const int StubVersion;
+
+    QString m_error;
+private:
+    QByteArray generateDesktopFile(QString *errorMessage) const;
+    QByteArray generateMainCpp(QString *errorMessage) const;
+    QByteArray generateProFile(QString *errorMessage) const;
+
+    virtual QByteArray generateFileExtended(int fileType,
+        bool *versionAndCheckSum, QString *comment, QString *errorMessage) const=0;
+    virtual QString pathExtended(int fileType) const=0;
+    virtual QString originsRoot() const=0;
+    virtual QString mainWindowClassName() const=0;
+    virtual int stubVersionMinor() const=0;
+    virtual bool adaptCurrentMainCppTemplateLine(QString &line) const=0;
+    virtual void handleCurrentProFileTemplateLine(const QString &line,
+        QTextStream &proFileTemplate, QTextStream &proFile,
+        bool &uncommentNextLine) const=0;
+
+    QString m_projectName;
+    QFileInfo m_projectPath;
+    QString m_symbianSvgIcon;
+    QString m_maemoPngIcon;
+    QString m_symbianTargetUid;
+    Orientation m_orientation;
+    bool m_networkEnabled;
+};
+
+} // end of namespace Internal
+} // end of namespace Qt4ProjectManager
+
+#endif // ABSTRACTMOBILEAPP_H
diff --git a/src/plugins/qt4projectmanager/wizards/mobileapp.cpp b/src/plugins/qt4projectmanager/wizards/mobileapp.cpp
index 5fc04d867f2..2debd118029 100644
--- a/src/plugins/qt4projectmanager/wizards/mobileapp.cpp
+++ b/src/plugins/qt4projectmanager/wizards/mobileapp.cpp
@@ -41,39 +41,17 @@ namespace Internal {
 
 const QString mainWindowBaseName(QLatin1String("mainwindow"));
 
-const QString deploymentPriFileName(QLatin1String("deployment.pri"));
-const QString deploymentPriOrigRelFilePath(QLatin1String("../shared/") + deploymentPriFileName);
 const QString mainWindowCppFileName(mainWindowBaseName + QLatin1String(".cpp"));
 const QString mainWindowHFileName(mainWindowBaseName + QLatin1String(".h"));
 const QString mainWindowUiFileName(mainWindowBaseName + QLatin1String(".ui"));
-const QString fileChecksum(QLatin1String("checksum"));
-const QString fileStubVersion(QLatin1String("version"));
 
 
-MobileAppGeneratedFileInfo::MobileAppGeneratedFileInfo()
-    : file(MainWindowCppFile)
-    , version(-1)
-    , dataChecksum(0)
-    , statedChecksum(0)
-{
-}
-
-bool MobileAppGeneratedFileInfo::isUpToDate() const
-{
-    return !isOutdated() && !wasModified();
-}
-
 bool MobileAppGeneratedFileInfo::isOutdated() const
 {
-    return version < MobileApp::stubVersion();
+    return version < AbstractMobileApp::makeStubVersion(MobileApp::StubVersion);
 }
 
-bool MobileAppGeneratedFileInfo::wasModified() const
-{
-    return dataChecksum != statedChecksum;
-}
-
-MobileApp::MobileApp() : m_orientation(Auto), m_networkEnabled(false)
+MobileApp::MobileApp() : AbstractMobileApp()
 {
 }
 
@@ -81,250 +59,41 @@ MobileApp::~MobileApp()
 {
 }
 
-QString MobileApp::symbianUidForPath(const QString &path)
+QString MobileApp::pathExtended(int fileType) const
 {
-    quint32 hash = 5381;
-    for (int i = 0; i < path.size(); ++i) {
-        const char c = path.at(i).toAscii();
-        hash ^= c + ((c - i) << i % 20) + ((c + i) << (i + 5) % 20) + ((c - 2 * i) << (i + 10) % 20) + ((c + 2 * i) << (i + 15) % 20);
-    }
-    return QString::fromLatin1("0xE")
-            + QString::fromLatin1("%1").arg(hash, 7, 16, QLatin1Char('0')).right(7);
-}
-
-void MobileApp::setOrientation(Orientation orientation)
-{
-    m_orientation = orientation;
-}
-
-MobileApp::Orientation MobileApp::orientation() const
-{
-    return m_orientation;
-}
-
-void MobileApp::setProjectName(const QString &name)
-{
-    m_projectName = name;
-}
-
-QString MobileApp::projectName() const
-{
-    return m_projectName;
-}
-
-void MobileApp::setProjectPath(const QString &path)
-{
-    m_projectPath.setFile(path);
-}
-
-void MobileApp::setSymbianSvgIcon(const QString &icon)
-{
-    m_symbianSvgIcon = icon;
-}
-
-QString MobileApp::symbianSvgIcon() const
-{
-    return path(SymbianSvgIconOrigin);
-}
-
-void MobileApp::setMaemoPngIcon(const QString &icon)
-{
-    m_maemoPngIcon = icon;
-}
-
-QString MobileApp::maemoPngIcon() const
-{
-    return path(MaemoPngIconOrigin);
-}
-
-void MobileApp::setSymbianTargetUid(const QString &uid)
-{
-    m_symbianTargetUid = uid;
-}
-
-QString MobileApp::symbianTargetUid() const
-{
-    return !m_symbianTargetUid.isEmpty() ? m_symbianTargetUid
-        : symbianUidForPath(path(AppPro));
-}
-
-void MobileApp::setNetworkEnabled(bool enabled)
-{
-    m_networkEnabled = enabled;
-}
-
-bool MobileApp::networkEnabled() const
-{
-    return m_networkEnabled;
-}
-
-
-QString MobileApp::path(Path path) const
-{
-    const QString originsRootMobileApp = templatesRoot(QLatin1String("mobileapp/"));
-    const QString originsRootShared = templatesRoot(QLatin1String("shared/"));
-    const QString mainCppFileName = QLatin1String("main.cpp");
-    const QString symbianIconFileName = QLatin1String("symbianicon.svg");
-    const QString pathBase = m_projectPath.absoluteFilePath() + QLatin1Char('/')
-                             + m_projectName + QLatin1Char('/');
-
-    switch (path) {
-        case MainCpp:                       return pathBase + mainCppFileName;
-        case MainCppOrigin:                 return originsRootMobileApp + mainCppFileName;
-        case AppPro:                        return pathBase + m_projectName + QLatin1String(".pro");
-        case AppProOrigin:                  return originsRootMobileApp + QLatin1String("app.pro");
-        case AppProPath:                    return pathBase;
-        case DeploymentPri:                 return pathBase + deploymentPriFileName;
-        case DeploymentPriOrigin:           return originsRootMobileApp + deploymentPriOrigRelFilePath;
-        case Desktop:                       return pathBase + m_projectName + QLatin1String(".desktop");
-        case DesktopOrigin:                 return originsRootShared + QLatin1String("app.desktop");
-        case MainWindowCpp:                 return pathBase + mainWindowCppFileName;
-        case MainWindowCppOrigin:           return originsRootMobileApp + mainWindowCppFileName;
-        case MainWindowH:                   return pathBase + mainWindowHFileName;
-        case MainWindowHOrigin:             return originsRootMobileApp + mainWindowHFileName;
-        case MainWindowUi:                  return pathBase + mainWindowUiFileName;
-        case MainWindowUiOrigin:            return originsRootMobileApp + mainWindowUiFileName;
-        case SymbianSvgIcon:                return pathBase + symbianIconFileName;
-        case SymbianSvgIconOrigin:          return !m_symbianSvgIcon.isEmpty() ? m_symbianSvgIcon
-                                                : originsRootShared + symbianIconFileName;
-        case MaemoPngIcon:                  return pathBase + projectName() +  QLatin1String(".png");
-        case MaemoPngIconOrigin:            return !m_maemoPngIcon.isEmpty() ? m_maemoPngIcon
-                                                : originsRootShared + QLatin1String("maemoicon.png");
-        default:                            qFatal("MobileApp::path() needs more work");
+    const QString pathBase = outputPathBase();
+    switch (fileType) {
+        case MainWindowCpp:       return pathBase + mainWindowCppFileName;
+        case MainWindowCppOrigin: return originsRoot() + mainWindowCppFileName;
+        case MainWindowH:         return pathBase + mainWindowHFileName;
+        case MainWindowHOrigin:   return originsRoot() + mainWindowHFileName;
+        case MainWindowUi:        return pathBase + mainWindowUiFileName;
+        case MainWindowUiOrigin:  return originsRoot() + mainWindowUiFileName;
+        default:                  qFatal("MobileApp::path() needs more work");
     }
     return QString();
 }
 
-static QString insertParameter(const QString &line, const QString &parameter)
-{
-    return QString(line).replace(QRegExp(QLatin1String("\\([^()]+\\)")),
-                                 QLatin1Char('(') + parameter + QLatin1Char(')'));
-}
-
-QByteArray MobileApp::generateMainCpp(const QString *errorMessage) const
-{
-    Q_UNUSED(errorMessage)
-
-    QFile sourceFile(path(MainCppOrigin));
-    sourceFile.open(QIODevice::ReadOnly);
-    Q_ASSERT(sourceFile.isOpen());
-    QTextStream in(&sourceFile);
-
-    QByteArray mainCppContent;
-    QTextStream out(&mainCppContent, QIODevice::WriteOnly);
-
-    QString line;
-    while (!(line = in.readLine()).isNull()) {
-        if (line.contains(QLatin1String("// ORIENTATION"))) {
-            const char *orientationString;
-            switch (m_orientation) {
-            case LockLandscape:
-                orientationString = "LockLandscape";
-                break;
-            case LockPortrait:
-                orientationString = "LockPortrait";
-                break;
-            case Auto:
-                orientationString = "Auto";
-                break;
-            }
-            line = insertParameter(line, QLatin1String("MainWindow::")
-                + QLatin1String(orientationString));
-        }
-        const int commentIndex = line.indexOf(QLatin1String(" //"));
-        if (commentIndex != -1)
-            line.truncate(commentIndex);
-        out << line << endl;
-    };
-
-    return mainCppContent;
-}
-
-QByteArray MobileApp::generateProFile(const QString *errorMessage) const
+bool MobileApp::adaptCurrentMainCppTemplateLine(QString &line) const
 {
-    Q_UNUSED(errorMessage)
-
-    const QChar comment = QLatin1Char('#');
-    QFile proFile(path(AppProOrigin));
-    proFile.open(QIODevice::ReadOnly);
-    Q_ASSERT(proFile.isOpen());
-    QTextStream in(&proFile);
-
-    QByteArray proFileContent;
-    QTextStream out(&proFileContent, QIODevice::WriteOnly);
-
-    QString valueOnNextLine;
-    bool uncommentNextLine = false;
-    QString line;
-    while (!(line = in.readLine()).isNull()) {
-        if (line.contains(QLatin1String("# TARGETUID3"))) {
-            valueOnNextLine = symbianTargetUid();
-        } else if (line.contains(QLatin1String("# ORIENTATIONLOCK")) && m_orientation == MobileApp::Auto) {
-            uncommentNextLine = true;
-        } else if (line.contains(QLatin1String("# NETWORKACCESS")) && !m_networkEnabled) {
-            uncommentNextLine = true;
-        }
-
-        // Remove all marker comments
-        if (line.trimmed().startsWith(comment)
-            && line.trimmed().endsWith(comment))
-            continue;
-
-        if (!valueOnNextLine.isEmpty()) {
-            out << line.left(line.indexOf(QLatin1Char('=')) + 2)
-                << QDir::fromNativeSeparators(valueOnNextLine) << endl;
-            valueOnNextLine.clear();
-            continue;
-        }
-
-        if (uncommentNextLine) {
-            out << comment << line << endl;
-            uncommentNextLine = false;
-            continue;
-        }
-        out << line << endl;
-    };
-
-    return proFileContent.replace(deploymentPriOrigRelFilePath.toAscii(),
-        deploymentPriFileName.toAscii());
+    Q_UNUSED(line);
+    return true;
 }
 
-QByteArray MobileApp::generateDesktopFile(const QString *errorMessage) const
+void MobileApp::handleCurrentProFileTemplateLine(const QString &line,
+    QTextStream &proFileTemplate, QTextStream &proFile,
+    bool &uncommentNextLine) const
 {
-    Q_UNUSED(errorMessage);
-
-    QFile desktopTemplate(path(DesktopOrigin));
-    desktopTemplate.open(QIODevice::ReadOnly);
-    Q_ASSERT(desktopTemplate.isOpen());
-    QByteArray desktopFileContent = desktopTemplate.readAll();
-    return desktopFileContent.replace("thisApp", projectName().toUtf8());
-}
-
-QString MobileApp::templatesRoot(const QString &dirName)
-{
-    return Core::ICore::instance()->resourcePath()
-        + QLatin1String("/templates/") + dirName;
-}
-
-static Core::GeneratedFile file(const QByteArray &data, const QString &targetFile)
-{
-    Core::GeneratedFile generatedFile(targetFile);
-    generatedFile.setBinary(true);
-    generatedFile.setBinaryContents(data);
-    return generatedFile;
+    Q_UNUSED(line);
+    Q_UNUSED(proFileTemplate);
+    Q_UNUSED(proFile);
+    Q_UNUSED(uncommentNextLine);
 }
 
 Core::GeneratedFiles MobileApp::generateFiles(QString *errorMessage) const
 {
-    Core::GeneratedFiles files;
+    Core::GeneratedFiles files = AbstractMobileApp::generateFiles(errorMessage);
 
-    files.append(file(generateFile(MobileAppGeneratedFileInfo::AppProFile, errorMessage), path(AppPro)));
-    files.last().setAttributes(Core::GeneratedFile::OpenProjectAttribute);
-    files.append(file(generateFile(MobileAppGeneratedFileInfo::MainCppFile, errorMessage), path(MainCpp)));
-    files.append(file(generateFile(MobileAppGeneratedFileInfo::SymbianSvgIconFile, errorMessage), path(SymbianSvgIcon)));
-    files.append(file(generateFile(MobileAppGeneratedFileInfo::MaemoPngIconFile, errorMessage), path(MaemoPngIcon)));
-    files.append(file(generateFile(MobileAppGeneratedFileInfo::DesktopFile, errorMessage), path(Desktop)));
-    files.append(file(generateFile(MobileAppGeneratedFileInfo::DeploymentPriFile, errorMessage), path(DeploymentPri)));
     files.append(file(generateFile(MobileAppGeneratedFileInfo::MainWindowCppFile, errorMessage), path(MainWindowCpp)));
     files.append(file(generateFile(MobileAppGeneratedFileInfo::MainWindowHFile, errorMessage), path(MainWindowH)));
     files.append(file(generateFile(MobileAppGeneratedFileInfo::MainWindowUiFile, errorMessage), path(MainWindowUi)));
@@ -333,82 +102,42 @@ Core::GeneratedFiles MobileApp::generateFiles(QString *errorMessage) const
     return files;
 }
 
-QString MobileApp::error() const
-{
-    return m_error;
-}
-
-static QByteArray readBlob(const QString &source)
-{
-    QFile sourceFile(source);
-    sourceFile.open(QIODevice::ReadOnly);
-    Q_ASSERT(sourceFile.isOpen());
-    return sourceFile.readAll();
-}
-
-QByteArray MobileApp::generateFile(MobileAppGeneratedFileInfo::File file,
-                                          const QString *errorMessage) const
+QByteArray MobileApp::generateFileExtended(int fileType,
+    bool *versionAndCheckSum, QString *comment, QString *errorMessage) const
 {
+    Q_UNUSED(comment);
     QByteArray data;
-    const QString cFileComment = QLatin1String("//");
-    const QString proFileComment = QLatin1String("#");
-    QString comment = cFileComment;
-    bool versionAndChecksum = false;
-    switch (file) {
-        case MobileAppGeneratedFileInfo::MainCppFile:
-            data = generateMainCpp(errorMessage);
-            break;
-        case MobileAppGeneratedFileInfo::SymbianSvgIconFile:
-            data = readBlob(path(SymbianSvgIconOrigin));
-            break;
-        case MobileAppGeneratedFileInfo::MaemoPngIconFile:
-            data = readBlob(path(MaemoPngIconOrigin));
-            break;
-        case MobileAppGeneratedFileInfo::DesktopFile:
-            data = generateDesktopFile(errorMessage);
-            break;
-        case MobileAppGeneratedFileInfo::AppProFile:
-            data = generateProFile(errorMessage);
-            comment = proFileComment;
-            break;
-        case MobileAppGeneratedFileInfo::DeploymentPriFile:
-            data = readBlob(path(DeploymentPriOrigin));
-            comment = proFileComment;
-            versionAndChecksum = true;
-            break;
+    switch (fileType) {
         case MobileAppGeneratedFileInfo::MainWindowCppFile:
-            data = readBlob(path(MainWindowCppOrigin));
-            versionAndChecksum = true;
+            data = readBlob(path(MainWindowCppOrigin), errorMessage);
+            *versionAndCheckSum = true;
             break;
         case MobileAppGeneratedFileInfo::MainWindowHFile:
-            data = readBlob(path(MainWindowHOrigin));
-            versionAndChecksum = true;
+            data = readBlob(path(MainWindowHOrigin), errorMessage);
+            *versionAndCheckSum = true;
             break;
         case MobileAppGeneratedFileInfo::MainWindowUiFile:
-            data = readBlob(path(MainWindowUiOrigin));
+            data = readBlob(path(MainWindowUiOrigin), errorMessage);
             break;
         default:
             Q_ASSERT_X(false, Q_FUNC_INFO, "Whoops, case missing!");
     }
-    if (!versionAndChecksum)
-        return data;
-    QByteArray versioned = data;
-    versioned.replace('\x0D', "");
-    versioned.replace('\x0A', "");
-    const quint16 checkSum = qChecksum(versioned.constData(), versioned.length());
-    const QString checkSumString = QString::number(checkSum, 16);
-    const QString versionString = QString::number(stubVersion());
-    const QChar sep = QLatin1Char(' ');
-    const QString versionLine =
-            comment + sep + fileChecksum + sep + QLatin1String("0x") + checkSumString
-            + sep + fileStubVersion + sep + versionString + QLatin1Char('\x0A');
-    return versionLine.toAscii() + data;
+    return data;
 }
 
-int MobileApp::stubVersion()
+QString MobileApp::originsRoot() const
 {
-    return 1;
+    return templatesRoot() + QLatin1String("mobileapp/");
 }
 
+QString MobileApp::mainWindowClassName() const
+{
+    return QLatin1String("MainWindow");
+}
+
+int MobileApp::stubVersionMinor() const { return StubVersion; }
+
+const int MobileApp::StubVersion = 1;
+
 } // namespace Internal
 } // namespace Qt4ProjectManager
diff --git a/src/plugins/qt4projectmanager/wizards/mobileapp.h b/src/plugins/qt4projectmanager/wizards/mobileapp.h
index b6c47c97d67..621219ce563 100644
--- a/src/plugins/qt4projectmanager/wizards/mobileapp.h
+++ b/src/plugins/qt4projectmanager/wizards/mobileapp.h
@@ -30,111 +30,52 @@
 #ifndef MOBILEAPP_H
 #define MOBILEAPP_H
 
-#include <coreplugin/basefilewizard.h>
-
-#include <QtCore/QStringList>
-#include <QtCore/QFileInfo>
-#include <QtCore/QHash>
+#include "abstractmobileapp.h"
 
 namespace Qt4ProjectManager {
 namespace Internal {
 
-struct MobileAppGeneratedFileInfo
+struct MobileAppGeneratedFileInfo : AbstractGeneratedFileInfo
 {
-    enum File {
-        MainCppFile,
-        AppProFile,
-        DeploymentPriFile,
-        MainWindowCppFile,
+    enum ExtendedFileType {
+        MainWindowCppFile = ExtendedFile,
         MainWindowHFile,
         MainWindowUiFile,
-        SymbianSvgIconFile,
-        MaemoPngIconFile,
-        DesktopFile
     };
 
-    MobileAppGeneratedFileInfo();
-
-    bool isUpToDate() const;
-    bool isOutdated() const;
-    bool wasModified() const;
-
-    File file;
-    QFileInfo fileInfo;
-    int version;
-    quint16 dataChecksum;
-    quint16 statedChecksum;
+    MobileAppGeneratedFileInfo() : AbstractGeneratedFileInfo() {}
+    virtual bool isOutdated() const;
 };
 
-class MobileApp: public QObject
+class MobileApp : public AbstractMobileApp
 {
 public:
-    enum Orientation {
-        LockLandscape,
-        LockPortrait,
-        Auto
-    };
-
-    enum Path {
-        MainCpp,
-        MainCppOrigin,
-        AppPro,
-        AppProOrigin,
-        AppProPath,
-        Desktop,
-        DesktopOrigin,
-        DeploymentPri,
-        DeploymentPriOrigin,
-        MainWindowCpp,
+    enum ExtendedFileType {
+        MainWindowCpp = ExtendedFile,
         MainWindowCppOrigin,
         MainWindowH,
         MainWindowHOrigin,
         MainWindowUi,
         MainWindowUiOrigin,
-        SymbianSvgIcon,
-        SymbianSvgIconOrigin,
-        MaemoPngIcon,
-        MaemoPngIconOrigin,
     };
 
     MobileApp();
-    ~MobileApp();
+    virtual ~MobileApp();
 
-    void setOrientation(Orientation orientation);
-    Orientation orientation() const;
-    void setProjectName(const QString &name);
-    QString projectName() const;
-    void setProjectPath(const QString &path);
-    void setSymbianSvgIcon(const QString &icon);
-    QString symbianSvgIcon() const;
-    void setMaemoPngIcon(const QString &icon);
-    QString maemoPngIcon() const;
-    void setSymbianTargetUid(const QString &uid);
-    QString symbianTargetUid() const;
-    void setNetworkEnabled(bool enabled);
-    bool networkEnabled() const;
+    virtual Core::GeneratedFiles generateFiles(QString *errorMessage) const;
 
-    static QString symbianUidForPath(const QString &path);
-    Core::GeneratedFiles generateFiles(QString *errorMessage) const;
-    QString path(Path path) const;
-    QString error() const;
-    QByteArray generateFile(MobileAppGeneratedFileInfo::File file,
-        const QString *errorMessage) const;
-    static int stubVersion();
+    static const int StubVersion;
 private:
-    QByteArray generateMainCpp(const QString *errorMessage) const;
-    QByteArray generateProFile(const QString *errorMessage) const;
-    QByteArray generateDesktopFile(const QString *errorMessage) const;
-    static QString templatesRoot(const QString &dirName);
-
-    QString m_projectName;
-    QFileInfo m_projectPath;
-    QString m_symbianSvgIcon;
-    QString m_maemoPngIcon;
-    QString m_symbianTargetUid;
-    Orientation m_orientation;
-    bool m_networkEnabled;
-    QString m_error;
+    virtual QByteArray generateFileExtended(int fileType,
+        bool *versionAndCheckSum, QString *comment, QString *errorMessage) const;
+    virtual QString pathExtended(int fileType) const;
+    virtual QString originsRoot() const;
+    virtual QString mainWindowClassName() const;
+    virtual int stubVersionMinor() const;
+    virtual bool adaptCurrentMainCppTemplateLine(QString &line) const;
+    virtual void handleCurrentProFileTemplateLine(const QString &line,
+        QTextStream &proFileTemplate, QTextStream &proFile,
+        bool &uncommentNextLine) const;
 };
 
 } // end of namespace Internal
diff --git a/src/plugins/qt4projectmanager/wizards/qmlstandaloneapp.cpp b/src/plugins/qt4projectmanager/wizards/qmlstandaloneapp.cpp
index d1cc4db00d3..0bfb34c5b21 100644
--- a/src/plugins/qt4projectmanager/wizards/qmlstandaloneapp.cpp
+++ b/src/plugins/qt4projectmanager/wizards/qmlstandaloneapp.cpp
@@ -48,11 +48,7 @@ const QString appViewerBaseName(QLatin1String("qmlapplicationviewer"));
 const QString appViewerPriFileName(appViewerBaseName + QLatin1String(".pri"));
 const QString appViewerCppFileName(appViewerBaseName + QLatin1String(".cpp"));
 const QString appViewerHFileName(appViewerBaseName + QLatin1String(".h"));
-const QString deploymentPriFileName(QLatin1String("deployment.pri"));
-const QString deploymentPriOrigRelFilePath(QLatin1String("../shared/") + deploymentPriFileName);
 const QString appViewerOriginsSubDir(appViewerBaseName + QLatin1Char('/'));
-const QString fileChecksum(QLatin1String("checksum"));
-const QString fileStubVersion(QLatin1String("version"));
 
 QmlModule::QmlModule(const QString &uri, const QFileInfo &rootDir, const QFileInfo &qmldir,
                      bool isExternal, QmlStandaloneApp *qmlStandaloneApp)
@@ -97,33 +93,13 @@ QmlCppPlugin::QmlCppPlugin(const QString &name, const QFileInfo &path,
     , proFile(proFile)
 {}
 
-QmlAppGeneratedFileInfo::QmlAppGeneratedFileInfo()
-    : file(MainQmlFile)
-    , version(-1)
-    , dataChecksum(0)
-    , statedChecksum(0)
-{
-}
-
-bool QmlAppGeneratedFileInfo::isUpToDate() const
-{
-    return !isOutdated() && !wasModified();
-}
-
 bool QmlAppGeneratedFileInfo::isOutdated() const
 {
-    return version < QmlStandaloneApp::stubVersion();
-}
-
-bool QmlAppGeneratedFileInfo::wasModified() const
-{
-    return dataChecksum != statedChecksum;
+    return version < AbstractMobileApp::makeStubVersion(QmlStandaloneApp::StubVersion);
 }
 
 QmlStandaloneApp::QmlStandaloneApp()
-    : m_loadDummyData(false)
-    , m_orientation(Auto)
-    , m_networkEnabled(false)
+    : AbstractMobileApp(), m_loadDummyData(false)
 {
 }
 
@@ -132,17 +108,6 @@ QmlStandaloneApp::~QmlStandaloneApp()
     clearModulesAndPlugins();
 }
 
-QString QmlStandaloneApp::symbianUidForPath(const QString &path)
-{
-    quint32 hash = 5381;
-    for (int i = 0; i < path.size(); ++i) {
-        const char c = path.at(i).toAscii();
-        hash ^= c + ((c - i) << i % 20) + ((c + i) << (i + 5) % 20) + ((c - 2 * i) << (i + 10) % 20) + ((c + 2 * i) << (i + 15) % 20);
-    }
-    return QString::fromLatin1("0xE")
-            + QString::fromLatin1("%1").arg(hash, 7, 16, QLatin1Char('0')).right(7);
-}
-
 void QmlStandaloneApp::setMainQmlFile(const QString &qmlFile)
 {
     m_mainQmlFile.setFile(qmlFile);
@@ -153,62 +118,6 @@ QString QmlStandaloneApp::mainQmlFile() const
     return path(MainQml);
 }
 
-void QmlStandaloneApp::setOrientation(Orientation orientation)
-{
-    m_orientation = orientation;
-}
-
-QmlStandaloneApp::Orientation QmlStandaloneApp::orientation() const
-{
-    return m_orientation;
-}
-
-void QmlStandaloneApp::setProjectName(const QString &name)
-{
-    m_projectName = name;
-}
-
-QString QmlStandaloneApp::projectName() const
-{
-    return m_projectName;
-}
-
-void QmlStandaloneApp::setProjectPath(const QString &path)
-{
-    m_projectPath.setFile(path);
-}
-
-void QmlStandaloneApp::setSymbianSvgIcon(const QString &icon)
-{
-    m_symbianSvgIcon = icon;
-}
-
-QString QmlStandaloneApp::symbianSvgIcon() const
-{
-    return path(SymbianSvgIconOrigin);
-}
-
-void QmlStandaloneApp::setMaemoPngIcon(const QString &icon)
-{
-    m_maemoPngIcon = icon;
-}
-
-QString QmlStandaloneApp::maemoPngIcon() const
-{
-    return path(MaemoPngIconOrigin);
-}
-
-void QmlStandaloneApp::setSymbianTargetUid(const QString &uid)
-{
-    m_symbianTargetUid = uid;
-}
-
-QString QmlStandaloneApp::symbianTargetUid() const
-{
-    return !m_symbianTargetUid.isEmpty() ? m_symbianTargetUid
-        : symbianUidForPath(path(AppPro));
-}
-
 void QmlStandaloneApp::setLoadDummyData(bool loadIt)
 {
     m_loadDummyData = loadIt;
@@ -219,16 +128,6 @@ bool QmlStandaloneApp::loadDummyData() const
     return m_loadDummyData;
 }
 
-void QmlStandaloneApp::setNetworkEnabled(bool enabled)
-{
-    m_networkEnabled = enabled;
-}
-
-bool QmlStandaloneApp::networkEnabled() const
-{
-    return m_networkEnabled;
-}
-
 bool QmlStandaloneApp::setExternalModules(const QStringList &uris,
                                           const QStringList &importPaths)
 {
@@ -270,197 +169,97 @@ bool QmlStandaloneApp::setExternalModules(const QStringList &uris,
     return true;
 }
 
-QString QmlStandaloneApp::path(Path path) const
+QString QmlStandaloneApp::pathExtended(int fileType) const
 {
     const QString qmlSubDir = QLatin1String("qml/")
-                              + (useExistingMainQml() ? m_mainQmlFile.dir().dirName() : m_projectName)
+                              + (useExistingMainQml() ? m_mainQmlFile.dir().dirName() : projectName())
                               + QLatin1Char('/');   
-    const QString originsRootQmlApp = templatesRoot() + QLatin1String("qmlapp/");
-    const QString originsRootShared = templatesRoot() + QLatin1String("shared/");
     const QString appViewerTargetSubDir = appViewerOriginsSubDir;
     const QString qmlExtension = QLatin1String(".qml");
-    const QString mainCppFileName = QLatin1String("main.cpp");
-    const QString symbianIconFileName = QLatin1String("symbianicon.svg");
-    const QString pathBase = m_projectPath.absoluteFilePath() + QLatin1Char('/')
-                             + m_projectName + QLatin1Char('/');
+    const QString pathBase = outputPathBase();
     const QDir appProFilePath(pathBase);
 
-    switch (path) {
+    switch (fileType) {
         case MainQml:                       return useExistingMainQml() ? m_mainQmlFile.canonicalFilePath()
-                                                : pathBase + qmlSubDir + m_projectName + qmlExtension;
+                                                : pathBase + qmlSubDir + projectName() + qmlExtension;
         case MainQmlDeployed:               return useExistingMainQml() ? qmlSubDir + m_mainQmlFile.fileName()
-                                                : QString(qmlSubDir + m_projectName + qmlExtension);
-        case MainQmlOrigin:                 return originsRootQmlApp + QLatin1String("qml/app/app.qml");
-        case MainCpp:                       return pathBase + mainCppFileName;
-        case MainCppOrigin:                 return originsRootQmlApp + mainCppFileName;
-        case AppPro:                        return pathBase + m_projectName + QLatin1String(".pro");
-        case AppProOrigin:                  return originsRootQmlApp + QLatin1String("app.pro");
-        case AppProPath:                    return pathBase;
-        case Desktop:                       return pathBase + m_projectName + QLatin1String(".desktop");
-        case DesktopOrigin:                 return originsRootShared + QLatin1String("app.desktop");
+                                                : QString(qmlSubDir + projectName() + qmlExtension);
+        case MainQmlOrigin:                 return originsRoot() + QLatin1String("qml/app/app.qml");
         case AppViewerPri:                  return pathBase + appViewerTargetSubDir + appViewerPriFileName;
-        case AppViewerPriOrigin:            return originsRootQmlApp + appViewerOriginsSubDir + appViewerPriFileName;
-        case DeploymentPri:                 return pathBase + deploymentPriFileName;
-        case DeploymentPriOrigin:           return originsRootQmlApp + deploymentPriOrigRelFilePath;
+        case AppViewerPriOrigin:            return originsRoot() + appViewerOriginsSubDir + appViewerPriFileName;
         case AppViewerCpp:                  return pathBase + appViewerTargetSubDir + appViewerCppFileName;
-        case AppViewerCppOrigin:            return originsRootQmlApp + appViewerOriginsSubDir + appViewerCppFileName;
+        case AppViewerCppOrigin:            return originsRoot() + appViewerOriginsSubDir + appViewerCppFileName;
         case AppViewerH:                    return pathBase + appViewerTargetSubDir + appViewerHFileName;
-        case AppViewerHOrigin:              return originsRootQmlApp + appViewerOriginsSubDir + appViewerHFileName;
-        case SymbianSvgIcon:                return pathBase + symbianIconFileName;
-        case SymbianSvgIconOrigin:          return !m_symbianSvgIcon.isEmpty() ? m_symbianSvgIcon
-                                                : originsRootShared + symbianIconFileName;
-        case MaemoPngIcon:                  return pathBase + projectName() +  QLatin1String(".png");
-        case MaemoPngIconOrigin:            return !m_maemoPngIcon.isEmpty() ? m_maemoPngIcon
-                                                : originsRootShared + QLatin1String("maemoicon.png");
+        case AppViewerHOrigin:              return originsRoot() + appViewerOriginsSubDir + appViewerHFileName;
         case QmlDir:                        return pathBase + qmlSubDir;
         case QmlDirProFileRelative:         return useExistingMainQml() ? appProFilePath.relativeFilePath(m_mainQmlFile.canonicalPath())
                                                 : QString(qmlSubDir).remove(qmlSubDir.length() - 1, 1);
         case ModulesDir:                    return QLatin1String("modules");
-        default:                            qFatal("QmlStandaloneApp::path() needs more work");
+        default:                            qFatal("QmlStandaloneApp::pathExtended() needs more work");
     }
     return QString();
 }
 
-static QString insertParameter(const QString &line, const QString &parameter)
+QString QmlStandaloneApp::originsRoot() const
 {
-    return QString(line).replace(QRegExp(QLatin1String("\\([^()]+\\)")),
-                                 QLatin1Char('(') + parameter + QLatin1Char(')'));
+    return templatesRoot() + QLatin1String("qmlapp/");
 }
 
-QByteArray QmlStandaloneApp::generateMainCpp(const QString *errorMessage) const
+QString QmlStandaloneApp::mainWindowClassName() const
 {
-    Q_UNUSED(errorMessage)
-
-    QFile sourceFile(path(MainCppOrigin));
-    sourceFile.open(QIODevice::ReadOnly);
-    Q_ASSERT(sourceFile.isOpen());
-    QTextStream in(&sourceFile);
-
-    QByteArray mainCppContent;
-    QTextStream out(&mainCppContent, QIODevice::WriteOnly);
-
-    QString line;
-    while (!(line = in.readLine()).isNull()) {
-        if (line.contains(QLatin1String("// MAINQML"))) {
-            line = insertParameter(line, QLatin1Char('"') + path(MainQmlDeployed) + QLatin1Char('"'));
-        } else if (line.contains(QLatin1String("// ADDIMPORTPATH"))) {
-            if (m_modules.isEmpty())
-                continue;
-            else
-                line = insertParameter(line, QLatin1Char('"') + path(ModulesDir) + QLatin1Char('"'));
-        } else if (line.contains(QLatin1String("// ORIENTATION"))) {
-            const char *orientationString;
-            switch (m_orientation) {
-            case LockLandscape:
-                orientationString = "LockLandscape";
-                break;
-            case LockPortrait:
-                orientationString = "LockPortrait";
-                break;
-            case Auto:
-                orientationString = "Auto";
-                break;
-            }
-            line = insertParameter(line, QLatin1String("QmlApplicationViewer::")
-                + QLatin1String(orientationString));
-        } else if (line.contains(QLatin1String("// LOADDUMMYDATA"))) {
-            continue;
-        }
-        const int commentIndex = line.indexOf(QLatin1String(" //"));
-        if (commentIndex != -1)
-            line.truncate(commentIndex);
-        out << line << endl;
-    };
-
-    return mainCppContent;
+    return QLatin1String("QmlApplicationViewer");
 }
 
-QByteArray QmlStandaloneApp::generateProFile(const QString *errorMessage) const
+bool QmlStandaloneApp::adaptCurrentMainCppTemplateLine(QString &line) const
 {
-    Q_UNUSED(errorMessage)
-
-    const QChar comment = QLatin1Char('#');
-    QFile proFile(path(AppProOrigin));
-    proFile.open(QIODevice::ReadOnly);
-    Q_ASSERT(proFile.isOpen());
-    QTextStream in(&proFile);
-
-    QByteArray proFileContent;
-    QTextStream out(&proFileContent, QIODevice::WriteOnly);
-
-    QString valueOnNextLine;
-    bool uncommentNextLine = false;
-    QString line;
-    while (!(line = in.readLine()).isNull()) {
-        if (line.contains(QLatin1String("# TARGETUID3"))) {
-            valueOnNextLine = symbianTargetUid();
-        } else if (line.contains(QLatin1String("# DEPLOYMENTFOLDERS"))) {
-            // Eat lines
-            while (!(line = in.readLine()).isNull() &&
-                   !line.contains(QLatin1String("# DEPLOYMENTFOLDERS_END")))
-            { }
-            if (line.isNull())
-                break;
-            QStringList folders;
-            out << "folder_01.source = " << path(QmlDirProFileRelative) << endl;
-            out << "folder_01.target = qml" << endl;
-            folders.append(QLatin1String("folder_01"));
-            int foldersCount = 1;
-            foreach (const QmlModule *module, m_modules) {
-                if (module->isExternal) {
-                    foldersCount ++;
-                    const QString folder =
-                            QString::fromLatin1("folder_%1").arg(foldersCount, 2, 10, QLatin1Char('0'));
-                    folders.append(folder);
-                    out << folder << ".source = " << module->path(QmlModule::ContentDir) << endl;
-                    out << folder << ".target = " << module->path(QmlModule::DeployedContentBase) << endl;
-                }
+    const QLatin1Char quote('"');
+    bool adaptLine = true;
+    if (line.contains(QLatin1String("// MAINQML"))) {
+        insertParameter(line, quote + path(MainQmlDeployed) + quote);
+    } else if (line.contains(QLatin1String("// ADDIMPORTPATH"))) {
+        if (m_modules.isEmpty())
+            adaptLine = false;
+        else
+            insertParameter(line, quote + path(ModulesDir) + quote);
+    } else if (line.contains(QLatin1String("// LOADDUMMYDATA"))) {
+        adaptLine = false;
+    }
+    return adaptLine;
+}
+
+void QmlStandaloneApp::handleCurrentProFileTemplateLine(const QString &line,
+    QTextStream &proFileTemplate, QTextStream &proFile,
+    bool &uncommentNextLine) const
+{
+    if (line.contains(QLatin1String("# DEPLOYMENTFOLDERS"))) {
+        // Eat lines
+        QString nextLine;
+        while (!(nextLine = proFileTemplate.readLine()).isNull()
+            && !nextLine.contains(QLatin1String("# DEPLOYMENTFOLDERS_END")))
+        { }
+        if (nextLine.isNull())
+            return;
+        QStringList folders;
+        proFile << "folder_01.source = " << path(QmlDirProFileRelative) << endl;
+        proFile << "folder_01.target = qml" << endl;
+        folders.append(QLatin1String("folder_01"));
+        int foldersCount = 1;
+        foreach (const QmlModule *module, m_modules) {
+            if (module->isExternal) {
+                foldersCount ++;
+                const QString folder =
+                    QString::fromLatin1("folder_%1").arg(foldersCount, 2, 10, QLatin1Char('0'));
+                folders.append(folder);
+                proFile << folder << ".source = " << module->path(QmlModule::ContentDir) << endl;
+                proFile << folder << ".target = " << module->path(QmlModule::DeployedContentBase) << endl;
             }
-            out << "DEPLOYMENTFOLDERS = " << folders.join(QLatin1String(" ")) << endl;
-        } else if (line.contains(QLatin1String("# ORIENTATIONLOCK")) && m_orientation == QmlStandaloneApp::Auto) {
-            uncommentNextLine = true;
-        } else if (line.contains(QLatin1String("# NETWORKACCESS")) && !m_networkEnabled) {
-            uncommentNextLine = true;
-        } else if (line.contains(QLatin1String("# QMLINSPECTOR"))) {
-            // ### disabled for now; figure out the private headers problem first.
-            //uncommentNextLine = true;
         }
-
-        // Remove all marker comments
-        if (line.trimmed().startsWith(comment)
-            && line.trimmed().endsWith(comment))
-            continue;
-
-        if (!valueOnNextLine.isEmpty()) {
-            out << line.left(line.indexOf(QLatin1Char('=')) + 2)
-                << QDir::fromNativeSeparators(valueOnNextLine) << endl;
-            valueOnNextLine.clear();
-            continue;
-        }
-
-        if (uncommentNextLine) {
-            out << comment << line << endl;
-            uncommentNextLine = false;
-            continue;
-        }
-        out << line << endl;
-    };
-
-    proFileContent.replace(deploymentPriOrigRelFilePath.toAscii(),
-        deploymentPriFileName.toAscii());
-
-    return proFileContent;
-}
-
-QByteArray QmlStandaloneApp::generateDesktopFile(const QString *errorMessage) const
-{
-    Q_UNUSED(errorMessage);
-
-    QFile desktopTemplate(path(DesktopOrigin));
-    desktopTemplate.open(QIODevice::ReadOnly);
-    Q_ASSERT(desktopTemplate.isOpen());
-    QByteArray desktopFileContent = desktopTemplate.readAll();
-    return desktopFileContent.replace("thisApp", projectName().toUtf8());
+        proFile << "DEPLOYMENTFOLDERS = " << folders.join(QLatin1String(" ")) << endl;
+    } else if (line.contains(QLatin1String("# QMLINSPECTOR"))) {
+        // ### disabled for now; figure out the private headers problem first.
+        //uncommentNextLine = true;
+        Q_UNUSED(uncommentNextLine);
+    }
 }
 
 void QmlStandaloneApp::clearModulesAndPlugins()
@@ -541,40 +340,15 @@ bool QmlStandaloneApp::addExternalModule(const QString &name, const QFileInfo &d
 }
 
 #ifndef CREATORLESSTEST
-// The definition of QmlStandaloneApp::templatesRoot() for
-// CREATORLESSTEST is in tests/manual/qmlstandalone/main.cpp
-QString QmlStandaloneApp::templatesRoot()
-{
-    return Core::ICore::instance()->resourcePath()
-            + QLatin1String("/templates/");
-}
-
-static Core::GeneratedFile file(const QByteArray &data, const QString &targetFile)
-{
-    Core::GeneratedFile generatedFile(targetFile);
-    generatedFile.setBinary(true);
-    generatedFile.setBinaryContents(data);
-    return generatedFile;
-}
-
 Core::GeneratedFiles QmlStandaloneApp::generateFiles(QString *errorMessage) const
 {
-    Core::GeneratedFiles files;
-
+    Core::GeneratedFiles files = AbstractMobileApp::generateFiles(errorMessage);
     if (!useExistingMainQml()) {
         files.append(file(generateFile(QmlAppGeneratedFileInfo::MainQmlFile, errorMessage), path(MainQml)));
         files.last().setAttributes(Core::GeneratedFile::OpenEditorAttribute);
     }
 
-    files.append(file(generateFile(QmlAppGeneratedFileInfo::AppProFile, errorMessage), path(AppPro)));
-    files.last().setAttributes(Core::GeneratedFile::OpenProjectAttribute);
-    files.append(file(generateFile(QmlAppGeneratedFileInfo::MainCppFile, errorMessage), path(MainCpp)));
-    files.append(file(generateFile(QmlAppGeneratedFileInfo::SymbianSvgIconFile, errorMessage), path(SymbianSvgIcon)));
-    files.append(file(generateFile(QmlAppGeneratedFileInfo::MaemoPngIconFile, errorMessage), path(MaemoPngIcon)));
-    files.append(file(generateFile(QmlAppGeneratedFileInfo::DesktopFile, errorMessage), path(Desktop)));
-
     files.append(file(generateFile(QmlAppGeneratedFileInfo::AppViewerPriFile, errorMessage), path(AppViewerPri)));
-    files.append(file(generateFile(QmlAppGeneratedFileInfo::DeploymentPriFile, errorMessage), path(DeploymentPri)));
     files.append(file(generateFile(QmlAppGeneratedFileInfo::AppViewerCppFile, errorMessage), path(AppViewerCpp)));
     files.append(file(generateFile(QmlAppGeneratedFileInfo::AppViewerHFile, errorMessage), path(AppViewerH)));
 
@@ -587,104 +361,54 @@ bool QmlStandaloneApp::useExistingMainQml() const
     return !m_mainQmlFile.filePath().isEmpty();
 }
 
-QString QmlStandaloneApp::error() const
-{
-    return m_error;
-}
-
 const QList<QmlModule*> QmlStandaloneApp::modules() const
 {
     return m_modules;
 }
 
-static QByteArray readBlob(const QString &source)
-{
-    QFile sourceFile(source);
-    sourceFile.open(QIODevice::ReadOnly);
-    Q_ASSERT(sourceFile.isOpen());
-    return sourceFile.readAll();
-}
-
-QByteArray QmlStandaloneApp::generateFile(QmlAppGeneratedFileInfo::File file,
-                                          const QString *errorMessage) const
+QByteArray QmlStandaloneApp::generateFileExtended(int fileType,
+    bool *versionAndCheckSum, QString *comment, QString *errorMessage) const
 {
     QByteArray data;
-    const QString cFileComment = QLatin1String("//");
-    const QString proFileComment = QLatin1String("#");
-    QString comment = cFileComment;
-    bool versionAndChecksum = false;
-    switch (file) {
+    switch (fileType) {
         case QmlAppGeneratedFileInfo::MainQmlFile:
-            data = readBlob(path(MainQmlOrigin));
-            break;
-        case QmlAppGeneratedFileInfo::MainCppFile:
-            data = generateMainCpp(errorMessage);
-            break;
-        case QmlAppGeneratedFileInfo::SymbianSvgIconFile:
-            data = readBlob(path(SymbianSvgIconOrigin));
-            break;
-        case QmlAppGeneratedFileInfo::MaemoPngIconFile:
-            data = readBlob(path(MaemoPngIconOrigin));
-            break;
-        case QmlAppGeneratedFileInfo::DesktopFile:
-            data = generateDesktopFile(errorMessage);
-            break;
-        case QmlAppGeneratedFileInfo::AppProFile:
-            data = generateProFile(errorMessage);
-            comment = proFileComment;
+            data = readBlob(path(MainQmlOrigin), errorMessage);
             break;
         case QmlAppGeneratedFileInfo::AppViewerPriFile:
-            data = readBlob(path(AppViewerPriOrigin));
-            comment = proFileComment;
-            versionAndChecksum = true;
-            break;
-        case QmlAppGeneratedFileInfo::DeploymentPriFile:
-            data = readBlob(path(DeploymentPriOrigin));
-            comment = proFileComment;
-            versionAndChecksum = true;
+            data = readBlob(path(AppViewerPriOrigin), errorMessage);
+            *comment = ProFileComment;
+            *versionAndCheckSum = true;
             break;
         case QmlAppGeneratedFileInfo::AppViewerCppFile:
-            data = readBlob(path(AppViewerCppOrigin));
-            versionAndChecksum = true;
+            data = readBlob(path(AppViewerCppOrigin), errorMessage);
+            *versionAndCheckSum = true;
             break;
         case QmlAppGeneratedFileInfo::AppViewerHFile:
         default:
-            data = readBlob(path(AppViewerHOrigin));
-            versionAndChecksum = true;
+            data = readBlob(path(AppViewerHOrigin), errorMessage);
+            *versionAndCheckSum = true;
             break;
     }
-    if (!versionAndChecksum)
-        return data;
-    QByteArray versioned = data;
-    versioned.replace('\x0D', "");
-    versioned.replace('\x0A', "");
-    const quint16 checkSum = qChecksum(versioned.constData(), versioned.length());
-    const QString checkSumString = QString::number(checkSum, 16);
-    const QString versionString = QString::number(stubVersion());
-    const QChar sep = QLatin1Char(' ');
-    const QString versionLine =
-            comment + sep + fileChecksum + sep + QLatin1String("0x") + checkSumString
-            + sep + fileStubVersion + sep + versionString + QLatin1Char('\x0A');
-    return versionLine.toAscii() + data;
+    return data;
 }
 
-int QmlStandaloneApp::stubVersion()
+int QmlStandaloneApp::stubVersionMinor() const
 {
-    return 5;
+    return StubVersion;
 }
 
 static QList<QmlAppGeneratedFileInfo> updateableFiles(const QString &mainProFile)
 {
     QList<QmlAppGeneratedFileInfo> result;
     static const struct {
-        QmlAppGeneratedFileInfo::File file;
+        int fileType;
         QString fileName;
     } files[] = {
         {QmlAppGeneratedFileInfo::AppViewerPriFile, appViewerPriFileName},
         {QmlAppGeneratedFileInfo::AppViewerHFile, appViewerHFileName},
         {QmlAppGeneratedFileInfo::AppViewerCppFile, appViewerCppFileName},
         {QmlAppGeneratedFileInfo::DeploymentPriFile,
-             QLatin1String("../") + deploymentPriFileName}
+             QLatin1String("../") + AbstractMobileApp::DeploymentPriFileName}
     };
     const QFileInfo mainProFileInfo(mainProFile);
     const int size = sizeof(files) / sizeof(files[0]);
@@ -694,7 +418,7 @@ static QList<QmlAppGeneratedFileInfo> updateableFiles(const QString &mainProFile
         if (!QFile::exists(fileName))
             continue;
         QmlAppGeneratedFileInfo file;
-        file.file = files[i].file;
+        file.fileType = files[i].fileType;
         file.fileInfo = QFileInfo(fileName);
         result.append(file);
     }
@@ -711,8 +435,8 @@ QList<QmlAppGeneratedFileInfo> QmlStandaloneApp::fileUpdates(const QString &main
            continue;
         const QString firstLine = readFile.readLine();
         const QStringList elements = firstLine.split(QLatin1Char(' '));
-        if (elements.count() != 5 || elements.at(1) != fileChecksum
-                || elements.at(3) != fileStubVersion)
+        if (elements.count() != 5 || elements.at(1) != FileChecksum
+                || elements.at(3) != FileStubVersion)
             continue;
         newFile.version = elements.at(4).toInt();
         newFile.statedChecksum = elements.at(2).toUShort(0, 16);
@@ -731,7 +455,7 @@ bool QmlStandaloneApp::updateFiles(const QList<QmlAppGeneratedFileInfo> &list, Q
     error.clear();
     const QmlStandaloneApp app;
     foreach (const QmlAppGeneratedFileInfo &info, list) {
-        const QByteArray data = app.generateFile(info.file, &error);
+        const QByteArray data = app.generateFile(info.fileType, &error);
         if (!error.isEmpty())
             return false;
         QFile file(info.fileInfo.absoluteFilePath());
@@ -746,5 +470,7 @@ bool QmlStandaloneApp::updateFiles(const QList<QmlAppGeneratedFileInfo> &list, Q
     return true;
 }
 
+const int QmlStandaloneApp::StubVersion = 5;
+
 } // namespace Internal
 } // namespace Qt4ProjectManager
diff --git a/src/plugins/qt4projectmanager/wizards/qmlstandaloneapp.h b/src/plugins/qt4projectmanager/wizards/qmlstandaloneapp.h
index d0f74209c57..b99dabbe392 100644
--- a/src/plugins/qt4projectmanager/wizards/qmlstandaloneapp.h
+++ b/src/plugins/qt4projectmanager/wizards/qmlstandaloneapp.h
@@ -30,13 +30,10 @@
 #ifndef QMLSTANDALONEAPP_H
 #define QMLSTANDALONEAPP_H
 
-#include <QtCore/QStringList>
-#include <QtCore/QFileInfo>
-#include <QtCore/QHash>
+#include "abstractmobileapp.h"
 
-#ifndef CREATORLESSTEST
-#include <coreplugin/basefilewizard.h>
-#endif // CREATORLESSTEST
+#include <QtCore/QHash>
+#include <QtCore/QStringList>
 
 namespace Qt4ProjectManager {
 namespace Internal {
@@ -76,132 +73,81 @@ struct QmlCppPlugin
     const QFileInfo proFile;        // .pro file for the plugin
 };
 
-struct QmlAppGeneratedFileInfo
+struct QmlAppGeneratedFileInfo : public AbstractGeneratedFileInfo
 {
-    enum File {
-        MainQmlFile,
-        MainCppFile,
-        AppProFile,
+    enum ExtendedFileType {
+        MainQmlFile = ExtendedFile,
         AppViewerPriFile,
-        DeploymentPriFile,
         AppViewerCppFile,
         AppViewerHFile,
-        SymbianSvgIconFile,
-        MaemoPngIconFile,
-        DesktopFile
     };
 
-    QmlAppGeneratedFileInfo();
-
-    bool isUpToDate() const;
-    bool isOutdated() const;
-    bool wasModified() const;
-
-    File file;
-    QFileInfo fileInfo;
-    int version;
-    quint16 dataChecksum;
-    quint16 statedChecksum;
+    QmlAppGeneratedFileInfo() : AbstractGeneratedFileInfo() {}
+    virtual bool isOutdated() const;
 };
 
-class QmlStandaloneApp: public QObject
+class QmlStandaloneApp : public AbstractMobileApp
 {
 public:
-    enum Orientation {
-        LockLandscape,
-        LockPortrait,
-        Auto
-    };
-
-    enum Path {
-        MainQml,
+    enum ExtendedFileType {
+        MainQml = ExtendedFile,
         MainQmlDeployed,
         MainQmlOrigin,
-        MainCpp,
-        MainCppOrigin,
-        AppPro,
-        AppProOrigin,
-        AppProPath,
-        Desktop,
-        DesktopOrigin,
         AppViewerPri,
         AppViewerPriOrigin,
-        DeploymentPri,
-        DeploymentPriOrigin,
         AppViewerCpp,
         AppViewerCppOrigin,
         AppViewerH,
         AppViewerHOrigin,
-        SymbianSvgIcon,
-        SymbianSvgIconOrigin,
-        MaemoPngIcon,
-        MaemoPngIconOrigin,
         QmlDir,
         QmlDirProFileRelative,
         ModulesDir
     };
 
     QmlStandaloneApp();
-    ~QmlStandaloneApp();
+    virtual ~QmlStandaloneApp();
 
     void setMainQmlFile(const QString &qmlFile);
     QString mainQmlFile() const;
-    void setOrientation(Orientation orientation);
-    Orientation orientation() const;
-    void setProjectName(const QString &name);
-    QString projectName() const;
-    void setProjectPath(const QString &path);
-    void setSymbianSvgIcon(const QString &icon);
-    QString symbianSvgIcon() const;
-    void setMaemoPngIcon(const QString &icon);
-    QString maemoPngIcon() const;
-    void setSymbianTargetUid(const QString &uid);
-    QString symbianTargetUid() const;
     void setLoadDummyData(bool loadIt);
     bool loadDummyData() const;
-    void setNetworkEnabled(bool enabled);
-    bool networkEnabled() const;
     bool setExternalModules(const QStringList &uris, const QStringList &importPaths);
 
-    static QString symbianUidForPath(const QString &path);
 #ifndef CREATORLESSTEST
-    Core::GeneratedFiles generateFiles(QString *errorMessage) const;
+    virtual Core::GeneratedFiles generateFiles(QString *errorMessage) const;
 #else
     bool generateFiles(QString *errorMessage) const;
 #endif // CREATORLESSTEST
-    QString path(Path path) const;
     bool useExistingMainQml() const;
-    QString error() const;
     const QList<QmlModule*> modules() const;
-    QByteArray generateFile(QmlAppGeneratedFileInfo::File file, const QString *errorMessage) const;
-    static int stubVersion();
     static QList<QmlAppGeneratedFileInfo> fileUpdates(const QString &mainProFile);
     static bool updateFiles(const QList<QmlAppGeneratedFileInfo> &list, QString &error);
 
+    static const int StubVersion;
+
 private:
-    QByteArray generateMainCpp(const QString *errorMessage) const;
-    QByteArray generateProFile(const QString *errorMessage) const;
-    QByteArray generateDesktopFile(const QString *errorMessage) const;
-    static QString templatesRoot();
+    virtual QByteArray generateFileExtended(int fileType,
+        bool *versionAndCheckSum, QString *comment, QString *errorMessage) const;
+    virtual QString pathExtended(int fileType) const;
+    virtual QString originsRoot() const;
+    virtual QString mainWindowClassName() const;
+    virtual int stubVersionMinor() const;
+    virtual bool adaptCurrentMainCppTemplateLine(QString &line) const;
+    virtual void handleCurrentProFileTemplateLine(const QString &line,
+        QTextStream &proFileTemplate, QTextStream &proFile,
+        bool &uncommentNextLine) const;
+
     bool addExternalModule(const QString &uri, const QFileInfo &dir,
                            const QFileInfo &contentDir);
     bool addCppPlugins(QmlModule *module);
     bool addCppPlugin(const QString &qmldirLine, QmlModule *module);
     void clearModulesAndPlugins();
 
-    QString m_projectName;
-    QFileInfo m_projectPath;
-    QString m_symbianSvgIcon;
-    QString m_maemoPngIcon;
-    QString m_symbianTargetUid;
     bool m_loadDummyData;
-    Orientation m_orientation;
-    bool m_networkEnabled;
     QFileInfo m_mainQmlFile;
     QStringList m_importPaths;
     QList <QmlModule*> m_modules;
     QList <QmlCppPlugin*> m_cppPlugins;
-    QString m_error;
 };
 
 } // end of namespace Internal
diff --git a/tests/manual/qmlstandalone/main.cpp b/tests/manual/qmlstandalone/main.cpp
index 68dc4b342c5..f6eaf4778ea 100644
--- a/tests/manual/qmlstandalone/main.cpp
+++ b/tests/manual/qmlstandalone/main.cpp
@@ -51,10 +51,12 @@ bool QmlStandaloneApp::generateFiles(QString *errorMessage) const
             && writeFile(generateFile(QmlAppGeneratedFileInfo::AppViewerCppFile, errorMessage), path(AppViewerCpp))
             && writeFile(generateFile(QmlAppGeneratedFileInfo::AppViewerHFile, errorMessage), path(AppViewerH))
             && writeFile(generateFile(QmlAppGeneratedFileInfo::SymbianSvgIconFile, errorMessage), path(SymbianSvgIcon))
-            && writeFile(generateFile(QmlAppGeneratedFileInfo::MaemoPngIconFile, errorMessage), path(MaemoPngIcon));
+            && writeFile(generateFile(QmlAppGeneratedFileInfo::MaemoPngIconFile, errorMessage), path(MaemoPngIcon))
+            && writeFile(generateFile(QmlAppGeneratedFileInfo::DesktopFile, errorMessage), path(Desktop))
+            && writeFile(generateFile(QmlAppGeneratedFileInfo::DeploymentPriFile, errorMessage), path(DeploymentPri));
 }
 
-QString QmlStandaloneApp::templatesRoot()
+QString AbstractMobileApp::templatesRoot()
 {
     return QLatin1String("../../../share/qtcreator/templates/");
 }
diff --git a/tests/manual/qmlstandalone/qmlstandalone.pro b/tests/manual/qmlstandalone/qmlstandalone.pro
index df5b8a33277..bc0b188035a 100644
--- a/tests/manual/qmlstandalone/qmlstandalone.pro
+++ b/tests/manual/qmlstandalone/qmlstandalone.pro
@@ -4,8 +4,10 @@ DEFINES += \
     CREATORLESSTEST
 APPSOURCEDIR = $$CREATORSOURCEDIR/src/plugins/qt4projectmanager/wizards
 HEADERS += \
-    $$APPSOURCEDIR/qmlstandaloneapp.h
+    $$APPSOURCEDIR/qmlstandaloneapp.h \
+    $$APPSOURCEDIR/abstractmobileapp.h
 SOURCES += \
     $$APPSOURCEDIR/qmlstandaloneapp.cpp \
+    $$APPSOURCEDIR/abstractmobileapp.cpp \
     main.cpp
 INCLUDEPATH += $$APPSOURCEDIR
-- 
GitLab