From 59386b205cae24a27449f4514a07cfeffe48e8cd Mon Sep 17 00:00:00 2001
From: Alessandro Portale <alessandro.portale@nokia.com>
Date: Thu, 15 Jul 2010 11:58:37 +0200
Subject: [PATCH] Wizard for standalone qml applications

Short: Create a new self running qml .sis/.deb package.

Long:
A typical Qml application usually consists of a couple of .qml,
.js and image files. Deploying such an application is challenging,
especially to mobile devices.

This wizard will generate a C++ project with a customized, light
weight Declarative Viewer, a helloworld Qml file and a .pro file
that takes care of the deployment of the Qml file(s).

This is just the first step. There will be an import wizard,
and further more there will be the possibility to add additional
Qml modules and probably also Qml directories to the package.

Task-number: QTCREATORBUG-1813
---
 src/plugins/qmlprojectmanager/qmlproject.qrc  |   6 +
 .../qmlprojectmanager/qmlprojectmanager.pro   |  19 +-
 .../qmlprojectmanager/qmlprojectplugin.cpp    |   2 +
 .../wizards/qmlstandaloneapp.cpp              | 328 ++++++++++++++++++
 .../wizards/qmlstandaloneapp.h                | 107 ++++++
 .../wizards/qmlstandaloneappwizard.cpp        | 153 ++++++++
 .../wizards/qmlstandaloneappwizard.h          |  67 ++++
 .../qmlstandaloneappwizardoptionspage.cpp     | 149 ++++++++
 .../qmlstandaloneappwizardoptionspage.h       |  71 ++++
 .../qmlstandaloneappwizardoptionspage.ui      | 152 ++++++++
 .../wizards/templates/app.pro                 |  42 +++
 .../wizards/templates/cpp/main.cpp            |  21 ++
 .../templates/cpp/qmlapplicationview.cpp      |  81 +++++
 .../templates/cpp/qmlapplicationview.h        |  26 ++
 .../wizards/templates/cpp/symbianicon.svg     |  93 +++++
 .../wizards/templates/qml/app.qml             |   8 +
 16 files changed, 1323 insertions(+), 2 deletions(-)
 create mode 100644 src/plugins/qmlprojectmanager/wizards/qmlstandaloneapp.cpp
 create mode 100644 src/plugins/qmlprojectmanager/wizards/qmlstandaloneapp.h
 create mode 100644 src/plugins/qmlprojectmanager/wizards/qmlstandaloneappwizard.cpp
 create mode 100644 src/plugins/qmlprojectmanager/wizards/qmlstandaloneappwizard.h
 create mode 100644 src/plugins/qmlprojectmanager/wizards/qmlstandaloneappwizardoptionspage.cpp
 create mode 100644 src/plugins/qmlprojectmanager/wizards/qmlstandaloneappwizardoptionspage.h
 create mode 100644 src/plugins/qmlprojectmanager/wizards/qmlstandaloneappwizardoptionspage.ui
 create mode 100644 src/plugins/qmlprojectmanager/wizards/templates/app.pro
 create mode 100644 src/plugins/qmlprojectmanager/wizards/templates/cpp/main.cpp
 create mode 100644 src/plugins/qmlprojectmanager/wizards/templates/cpp/qmlapplicationview.cpp
 create mode 100644 src/plugins/qmlprojectmanager/wizards/templates/cpp/qmlapplicationview.h
 create mode 100644 src/plugins/qmlprojectmanager/wizards/templates/cpp/symbianicon.svg
 create mode 100644 src/plugins/qmlprojectmanager/wizards/templates/qml/app.qml

diff --git a/src/plugins/qmlprojectmanager/qmlproject.qrc b/src/plugins/qmlprojectmanager/qmlproject.qrc
index 21338b6a545..c50f05276eb 100644
--- a/src/plugins/qmlprojectmanager/qmlproject.qrc
+++ b/src/plugins/qmlprojectmanager/qmlproject.qrc
@@ -4,5 +4,11 @@
         <file>images/qmlfolder.png</file>
         <file>images/qmlproject.png</file>
         <file>images/qml_wizard.png</file>
+        <file>wizards/templates/app.pro</file>
+        <file>wizards/templates/qml/app.qml</file>
+        <file>wizards/templates/cpp/qmlapplicationview.h</file>
+        <file>wizards/templates/cpp/symbianicon.svg</file>
+        <file>wizards/templates/cpp/main.cpp</file>
+        <file>wizards/templates/cpp/qmlapplicationview.cpp</file>
     </qresource>
 </RCC>
diff --git a/src/plugins/qmlprojectmanager/qmlprojectmanager.pro b/src/plugins/qmlprojectmanager/qmlprojectmanager.pro
index d97c600458e..97158b12ca2 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectmanager.pro
+++ b/src/plugins/qmlprojectmanager/qmlprojectmanager.pro
@@ -21,7 +21,11 @@ HEADERS += qmlproject.h \
     qmlprojectapplicationwizard.h \
     qmlprojectmanager_global.h \
     qmlprojectmanagerconstants.h \
-    qmlprojecttarget.h
+    qmlprojecttarget.h \
+    wizards/qmlstandaloneappwizard.h \
+    wizards/qmlstandaloneappwizardoptionspage.h \
+    wizards/qmlstandaloneapp.h
+
 SOURCES += qmlproject.cpp \
     qmlprojectplugin.cpp \
     qmlprojectmanager.cpp \
@@ -32,8 +36,19 @@ SOURCES += qmlproject.cpp \
     qmlprojectrunconfiguration.cpp \
     qmlprojectrunconfigurationfactory.cpp \
     qmlprojectapplicationwizard.cpp \
-    qmlprojecttarget.cpp
+    qmlprojecttarget.cpp \
+    wizards/qmlstandaloneappwizard.cpp \
+    wizards/qmlstandaloneappwizardoptionspage.cpp \
+    wizards/qmlstandaloneapp.cpp
+
 RESOURCES += qmlproject.qrc
 
+INCLUDEPATH += \
+    . \
+    wizards
+
+FORMS += \
+    wizards/qmlstandaloneappwizardoptionspage.ui
+
 OTHER_FILES += QmlProjectManager.pluginspec \
                QmlProject.mimetypes.xml
diff --git a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp
index 622f594079c..2bbacd7d264 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp
@@ -31,6 +31,7 @@
 #include "qmlprojectmanager.h"
 #include "qmlprojectimportwizard.h"
 #include "qmlprojectapplicationwizard.h"
+#include "qmlstandaloneappwizard.h"
 #include "qmlprojectconstants.h"
 #include "qmlproject.h"
 #include "qmlprojectrunconfigurationfactory.h"
@@ -76,6 +77,7 @@ bool QmlProjectPlugin::initialize(const QStringList &, QString *errorMessage)
     addAutoReleasedObject(manager);
     addAutoReleasedObject(new Internal::QmlProjectRunConfigurationFactory);
     addAutoReleasedObject(new Internal::QmlRunControlFactory);
+    addAutoReleasedObject(new QmlNewStandaloneAppWizard);
     addAutoReleasedObject(new QmlProjectApplicationWizard);
     addAutoReleasedObject(new QmlProjectImportWizard);
 
diff --git a/src/plugins/qmlprojectmanager/wizards/qmlstandaloneapp.cpp b/src/plugins/qmlprojectmanager/wizards/qmlstandaloneapp.cpp
new file mode 100644
index 00000000000..1ec01439aba
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/wizards/qmlstandaloneapp.cpp
@@ -0,0 +1,328 @@
+/**************************************************************************
+**
+** 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 "qmlstandaloneapp.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QRegExp>
+#include <QtCore/QTextStream>
+
+namespace QmlProjectManager {
+namespace Internal {
+
+QmlStandaloneApp::QmlStandaloneApp()
+    : m_loadDummyData(false)
+    , m_orientation(Auto)
+    , m_networkEnabled(false)
+{
+}
+
+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::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 = path;
+    if (!(m_projectPath.endsWith(QLatin1Char('\\'))
+        || m_projectPath.endsWith(QLatin1Char('/'))))
+        m_projectPath.append(QDir::separator());
+}
+
+void QmlStandaloneApp::setSymbianSvgIcon(const QString &icon)
+{
+    m_symbianSvgIcon = icon;
+}
+
+QString QmlStandaloneApp::symbianSvgIcon() const
+{
+    return path(SymbianSvgIcon, Source);
+}
+
+void QmlStandaloneApp::setSymbianTargetUid(const QString &uid)
+{
+    m_symbianTargetUid = uid;
+}
+
+QString QmlStandaloneApp::symbianTargetUid() const
+{
+    return !m_symbianTargetUid.isEmpty() ? m_symbianTargetUid
+        : symbianUidForPath(m_projectPath + m_projectName);
+}
+
+void QmlStandaloneApp::setLoadDummyData(bool loadIt)
+{
+    m_loadDummyData = loadIt;
+}
+
+bool QmlStandaloneApp::loadDummyData() const
+{
+    return m_loadDummyData;
+}
+
+void QmlStandaloneApp::setNetworkEnabled(bool enabled)
+{
+    m_networkEnabled = enabled;
+}
+
+bool QmlStandaloneApp::networkEnabled() const
+{
+    return m_networkEnabled;
+}
+
+QString QmlStandaloneApp::path(Path path, Location location) const
+{
+    const QString sourceRoot = QLatin1String(":/qmlproject/wizards/templates/");
+    const QString cppSourceSubDir = QLatin1String("cpp/");
+    const QString qmlSourceSubDir = QLatin1String("qml/");
+    const QString cppTargetSubDir = cppSourceSubDir;
+    const QString qmlTargetSubDir = qmlSourceSubDir;
+    const QString qmlExtension = QLatin1String(".qml");
+    const QString mainCpp = QLatin1String("main.cpp");
+    const QString appViewCpp = QLatin1String("qmlapplicationview.cpp");
+    const QString appViewH = QLatin1String("qmlapplicationview.h");
+    const QString symbianIcon = QLatin1String("symbianicon.svg");
+    const char* const errorMessage = "QmlStandaloneApp::path() needs more work";
+
+    switch (location) {
+        case Source: {
+            switch (path) {
+                case MainQml:           return sourceRoot + qmlSourceSubDir + QLatin1String("app.qml");
+                case AppProfile:        return sourceRoot + QLatin1String("app.pro");
+                case MainCpp:           return sourceRoot + cppSourceSubDir + mainCpp;
+                case AppViewerCpp:      return sourceRoot + cppSourceSubDir + appViewCpp;
+                case AppViewerH:        return sourceRoot + cppSourceSubDir + appViewH;
+                case SymbianSvgIcon:    return !m_symbianSvgIcon.isEmpty() ? m_symbianSvgIcon
+                                                    :sourceRoot + cppSourceSubDir + symbianIcon;
+                default:                qFatal(errorMessage);
+            }
+        }
+        case Target: {
+            const QString pathBase = m_projectPath + m_projectName + QDir::separator();
+            switch (path) {
+                case MainQml:           return pathBase + qmlTargetSubDir + m_projectName + qmlExtension;
+                case AppProfile:        return pathBase + m_projectName + QLatin1String(".pro");
+                case MainCpp:           return pathBase + cppTargetSubDir + mainCpp;
+                case AppViewerCpp:      return pathBase + cppTargetSubDir + appViewCpp;
+                case AppViewerH:        return pathBase + cppTargetSubDir + appViewH;
+                case SymbianSvgIcon:    return pathBase + cppTargetSubDir + symbianIcon;
+                default:                qFatal(errorMessage);
+            }
+        }
+        case AppProfileRelative: {
+            switch (path) {
+                case MainQml:           return qmlTargetSubDir + m_projectName + qmlExtension;
+                case MainCpp:           return cppTargetSubDir + mainCpp;
+                case AppViewerCpp:      return cppTargetSubDir + appViewCpp;
+                case AppViewerH:        return cppTargetSubDir + appViewH;
+                case SymbianSvgIcon:    return cppTargetSubDir + symbianIcon;
+                case QmlDir:            return QString(qmlTargetSubDir).remove(qmlTargetSubDir.length() - 1, 1);
+                default:                qFatal(errorMessage);
+            }
+        }
+        default: { /* case MainCppRelative: */
+            switch (path) {
+                case MainQml:           return qmlTargetSubDir + m_projectName + qmlExtension;
+                default:                qFatal(errorMessage);
+            }
+        }
+    }
+    return QString();
+}
+
+
+static QString insertParameter(const QString &line, const QString &parameter)
+{
+    return QString(line).replace(QRegExp(QLatin1String("\\([^()]+\\)")),
+                                 QLatin1Char('(') + parameter + QLatin1Char(')'));
+}
+
+QByteArray QmlStandaloneApp::generateMainCpp(const QString *errorMessage) const
+{
+    Q_UNUSED(errorMessage)
+
+    QFile sourceFile(path(MainCpp, Source));
+    sourceFile.open(QIODevice::ReadOnly);
+    Q_ASSERT(sourceFile.isOpen());
+    QTextStream in(&sourceFile);
+
+    QByteArray mainCppContent;
+    QTextStream out(&mainCppContent, QIODevice::WriteOnly);
+
+    QString line;
+    do {
+        line = in.readLine();
+        if (line.contains(QLatin1String("// MAINQML"))) {
+            line = insertParameter(line, QLatin1Char('"')
+                                   + path(MainQml, MainCppRelative) + QLatin1Char('"'));
+        } else if (line.contains(QLatin1String("// IMPORTPATHSLIST"))) {
+            continue;
+        } else if (line.contains(QLatin1String("// SETIMPORTPATHLIST"))) {
+            continue;
+        } else if (line.contains(QLatin1String("// ORIENTATION"))) {
+            if (m_orientation == Auto)
+                continue;
+            else
+                line = insertParameter(line, QLatin1String("QmlApplicationView::")
+                                       + QLatin1String(m_orientation == LockLandscape ?
+                                                       "LockLandscape" : "LockPortrait"));
+        } else if (line.contains(QLatin1String("// LOADDUMMYDATA"))) {
+            continue;
+        }
+        const int commentIndex = line.indexOf(QLatin1String(" //"));
+        if (commentIndex != -1)
+            line.truncate(commentIndex);
+        out << line << endl;
+    } while (!line.isNull());
+
+    return mainCppContent;
+}
+
+QByteArray QmlStandaloneApp::generateProFile(const QString *errorMessage) const
+{
+    Q_UNUSED(errorMessage)
+
+    QFile proFile(path(AppProfile, Source));
+    proFile.open(QIODevice::ReadOnly);
+    Q_ASSERT(proFile.isOpen());
+    QTextStream in(&proFile);
+
+    QByteArray proFileContent;
+    QTextStream out(&proFileContent, QIODevice::WriteOnly);
+
+    QString line;
+    QString valueOnNextLine;
+    bool uncommentNextLine = false;
+    do {
+        line = in.readLine();
+
+        if (line.contains(QLatin1String("# MAINQML"))) {
+            valueOnNextLine = path(MainQml, AppProfileRelative);
+        } else if (line.contains(QLatin1String("# TARGETUID3"))) {
+            valueOnNextLine = symbianTargetUid();
+        } else if (line.contains(QLatin1String("# DEPLOYMENTFOLDERS"))) {
+            valueOnNextLine = path(QmlDir, AppProfileRelative);
+        } else if (line.contains(QLatin1String("# ORIENTATIONLOCK")) && m_orientation == QmlStandaloneApp::Auto) {
+            uncommentNextLine = true;
+        } else if (line.contains(QLatin1String("# NETWORKACCESS")) && !m_networkEnabled) {
+            uncommentNextLine = true;
+        }
+
+        // Remove all marker comments
+        if (line.trimmed().startsWith(QLatin1Char('#'))
+            && line.trimmed().endsWith(QLatin1Char('#')))
+            continue;
+
+        if (!valueOnNextLine.isEmpty()) {
+            out << line.left(line.indexOf(QLatin1Char('=')) + 2)
+                    << QDir::fromNativeSeparators(valueOnNextLine) << endl;
+            valueOnNextLine.clear();
+            continue;
+        }
+
+        if (uncommentNextLine) {
+            out << QLatin1String("#") << line << endl;
+            uncommentNextLine = false;
+            continue;
+        }
+        out << line << endl;
+    } while (!line.isNull());
+
+    return proFileContent;
+}
+
+#ifndef CREATORLESSTEST
+static Core::GeneratedFile generateFileCopy(const QString &source,
+                                            const QString &target,
+                                            bool openEditor = false)
+{
+    QFile sourceFile(source);
+    sourceFile.open(QIODevice::ReadOnly);
+    Q_ASSERT(sourceFile.isOpen());
+    Core::GeneratedFile generatedFile(target);
+    generatedFile.setBinary(true);
+    generatedFile.setBinaryContents(sourceFile.readAll());
+    if (openEditor)
+        generatedFile.setAttributes(Core::GeneratedFile::OpenEditorAttribute);
+    return generatedFile;
+}
+
+Core::GeneratedFiles QmlStandaloneApp::generateFiles(QString *errorMessage) const
+{
+    Core::GeneratedFiles files;
+
+    Core::GeneratedFile generatedProFile(path(AppProfile, Target));
+    generatedProFile.setContents(generateProFile(errorMessage));
+    generatedProFile.setAttributes(Core::GeneratedFile::OpenProjectAttribute);
+    files.append(generatedProFile);
+
+    files.append(generateFileCopy(path(MainQml, Source), path(MainQml, Target), true));
+
+    Core::GeneratedFile generatedMainCppFile(path(MainCpp, Target));
+    generatedMainCppFile.setContents(generateMainCpp(errorMessage));
+    files.append(generatedMainCppFile);
+
+    files.append(generateFileCopy(path(AppViewerCpp, Source), path(AppViewerCpp, Target)));
+    files.append(generateFileCopy(path(AppViewerH, Source), path(AppViewerH, Target)));
+    files.append(generateFileCopy(path(SymbianSvgIcon, Source), path(SymbianSvgIcon, Target)));
+
+    return files;
+}
+#endif // CREATORLESSTEST
+
+} // namespace Internal
+} // namespace QmlProjectManager
diff --git a/src/plugins/qmlprojectmanager/wizards/qmlstandaloneapp.h b/src/plugins/qmlprojectmanager/wizards/qmlstandaloneapp.h
new file mode 100644
index 00000000000..b1d79e966ff
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/wizards/qmlstandaloneapp.h
@@ -0,0 +1,107 @@
+/**************************************************************************
+**
+** 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 QMLSTANDALONEAPP_H
+#define QMLSTANDALONEAPP_H
+
+#include <QtCore/QString>
+#ifndef CREATORLESSTEST
+#include <coreplugin/basefilewizard.h>
+#endif // CREATORLESSTEST
+
+namespace QmlProjectManager {
+namespace Internal {
+
+class QmlStandaloneApp
+{
+public:
+    enum Orientation {
+        LockLandscape,
+        LockPortrait,
+        Auto
+    };
+
+    enum Path {
+        MainQml,
+        MainCpp,
+        AppProfile,
+        AppViewerCpp,
+        AppViewerH,
+        SymbianSvgIcon,
+        QmlDir
+    };
+
+    enum Location {
+        Source,
+        Target,
+        AppProfileRelative,
+        MainCppRelative
+    };
+
+    QmlStandaloneApp();
+
+    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 setSymbianTargetUid(const QString &uid);
+    QString symbianTargetUid() const;
+    void setLoadDummyData(bool loadIt);
+    bool loadDummyData() const;
+    void setNetworkEnabled(bool enabled);
+    bool networkEnabled() const;
+
+    static QString symbianUidForPath(const QString &path);
+#ifndef CREATORLESSTEST
+    Core::GeneratedFiles generateFiles(QString *errorMessage) const;
+#else
+    bool generateFiles(QString *errorMessage) const;
+#endif // CREATORLESSTEST
+
+private:
+    QString path(Path path, Location location) const;
+    QByteArray generateMainCpp(const QString *errorMessage) const;
+    QByteArray generateProFile(const QString *errorMessage) const;
+
+    QString m_projectName;
+    QString m_projectPath;
+    QString m_symbianSvgIcon;
+    QString m_symbianTargetUid;
+    bool m_loadDummyData;
+    Orientation m_orientation;
+    bool m_networkEnabled;
+};
+
+} // end of namespace Internal
+} // end of namespace QmlProjectManager
+
+#endif // QMLSTANDALONEAPP_H
diff --git a/src/plugins/qmlprojectmanager/wizards/qmlstandaloneappwizard.cpp b/src/plugins/qmlprojectmanager/wizards/qmlstandaloneappwizard.cpp
new file mode 100644
index 00000000000..977f4c1d258
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/wizards/qmlstandaloneappwizard.cpp
@@ -0,0 +1,153 @@
+/**************************************************************************
+**
+** 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 "qmlstandaloneappwizard.h"
+#include "qmlstandaloneappwizardoptionspage.h"
+#include "qmlstandaloneapp.h"
+
+#include "qmlprojectconstants.h"
+
+#include <projectexplorer/customwizard/customwizard.h>
+
+#include <QtGui/QIcon>
+
+#include <QtGui/QPainter>
+#include <QtGui/QPixmap>
+
+#include <QtCore/QTextStream>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+
+namespace QmlProjectManager {
+namespace Internal {
+
+class QmlNewStandaloneAppWizardDialog : public ProjectExplorer::BaseProjectWizardDialog
+{
+    Q_OBJECT
+
+public:
+    explicit QmlNewStandaloneAppWizardDialog(QWidget *parent = 0);
+
+private:
+    class QmlStandaloneAppWizardOptionPage *m_qmlOptionsPage;
+    friend class QmlNewStandaloneAppWizard;
+};
+
+QmlNewStandaloneAppWizardDialog::QmlNewStandaloneAppWizardDialog(QWidget *parent)
+    : ProjectExplorer::BaseProjectWizardDialog(parent)
+{
+    setWindowTitle(tr("New Standalone QML Project"));
+    setIntroDescription(tr("This wizard generates a Standalone QML application project."));
+
+    m_qmlOptionsPage = new QmlStandaloneAppWizardOptionPage;
+
+    const int qmlOptionsPagePageId = addPage(m_qmlOptionsPage);
+    wizardProgress()->item(qmlOptionsPagePageId)->setTitle(tr("Qml App options"));
+}
+
+QmlNewStandaloneAppWizard::QmlNewStandaloneAppWizard()
+    : Core::BaseFileWizard(parameters())
+    , m_standaloneApp(new QmlStandaloneApp)
+    , m_wizardDialog(0)
+{
+}
+
+QmlNewStandaloneAppWizard::~QmlNewStandaloneAppWizard()
+{
+    delete m_standaloneApp;
+}
+
+Core::BaseFileWizardParameters QmlNewStandaloneAppWizard::parameters()
+{
+    Core::BaseFileWizardParameters parameters(ProjectWizard);
+    parameters.setIcon(QIcon(QLatin1String(Constants::QML_WIZARD_ICON)));
+    parameters.setDisplayName(tr("Qt QML Standalone Application"));
+    parameters.setId(QLatin1String("QA.QML Standalone Application"));
+    parameters.setDescription(tr("Creates a standalone, mobile-deployable Qt QML application "
+                                 "project. A lightweight Qt/C++ application with a QDeclarativeView "
+                                 "and a single QML file will be created."));
+    parameters.setCategory(QLatin1String(Constants::QML_WIZARD_CATEGORY));
+    parameters.setDisplayCategory(QCoreApplication::translate(Constants::QML_WIZARD_TR_SCOPE,
+                                                              Constants::QML_WIZARD_TR_CATEGORY));
+    return parameters;
+}
+
+QWizard *QmlNewStandaloneAppWizard::createWizardDialog(QWidget *parent,
+                                                       const QString &defaultPath,
+                                                       const WizardPageList &extensionPages) const
+{
+    m_wizardDialog = new QmlNewStandaloneAppWizardDialog(parent);
+
+    m_wizardDialog->setPath(defaultPath);
+    m_wizardDialog->setProjectName(QmlNewStandaloneAppWizardDialog::uniqueProjectName(defaultPath));
+    m_wizardDialog->m_qmlOptionsPage->setSymbianSvgIcon(m_standaloneApp->symbianSvgIcon());
+    m_wizardDialog->m_qmlOptionsPage->setOrientation(m_standaloneApp->orientation());
+    m_wizardDialog->m_qmlOptionsPage->setNetworkEnabled(m_standaloneApp->networkEnabled());
+    m_wizardDialog->m_qmlOptionsPage->setLoadDummyData(m_standaloneApp->loadDummyData());
+    connect(m_wizardDialog, SIGNAL(introPageLeft(QString, QString)), SLOT(useProjectPath(QString, QString)));
+
+    foreach (QWizardPage *p, extensionPages)
+        BaseFileWizard::applyExtensionPageShortTitle(m_wizardDialog, m_wizardDialog->addPage(p));
+
+    return m_wizardDialog;
+}
+
+Core::GeneratedFiles QmlNewStandaloneAppWizard::generateFiles(const QWizard *w,
+                                                              QString *errorMessage) const
+{
+    Q_UNUSED(errorMessage)
+
+    const QmlNewStandaloneAppWizardDialog *wizard = qobject_cast<const QmlNewStandaloneAppWizardDialog*>(w);
+
+    m_standaloneApp->setProjectName(wizard->projectName());
+    m_standaloneApp->setProjectPath(wizard->path());
+    m_standaloneApp->setSymbianTargetUid(wizard->m_qmlOptionsPage->symbianUid());
+    m_standaloneApp->setSymbianSvgIcon(wizard->m_qmlOptionsPage->symbianSvgIcon());
+    m_standaloneApp->setOrientation(wizard->m_qmlOptionsPage->orientation());
+    m_standaloneApp->setNetworkEnabled(wizard->m_qmlOptionsPage->networkEnabled());
+
+    return m_standaloneApp->generateFiles(errorMessage);
+}
+
+bool QmlNewStandaloneAppWizard::postGenerateFiles(const QWizard *wizard, const Core::GeneratedFiles &l, QString *errorMessage)
+{
+    Q_UNUSED(wizard)
+    return ProjectExplorer::CustomProjectWizard::postGenerateOpen(l, errorMessage);
+}
+
+void QmlNewStandaloneAppWizard::useProjectPath(const QString &projectName, const QString &projectPath)
+{
+    m_wizardDialog->m_qmlOptionsPage->setSymbianUid(QmlStandaloneApp::symbianUidForPath(projectPath + projectName));
+}
+
+} // namespace Internal
+} // namespace QmlProjectManager
+
+#include "qmlstandaloneappwizard.moc"
diff --git a/src/plugins/qmlprojectmanager/wizards/qmlstandaloneappwizard.h b/src/plugins/qmlprojectmanager/wizards/qmlstandaloneappwizard.h
new file mode 100644
index 00000000000..6c34812d5d0
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/wizards/qmlstandaloneappwizard.h
@@ -0,0 +1,67 @@
+/**************************************************************************
+**
+** 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 QMLSTANDALONEAPPWIZARD_H
+#define QMLSTANDALONEAPPWIZARD_H
+
+#include <coreplugin/basefilewizard.h>
+#include <projectexplorer/baseprojectwizarddialog.h>
+
+namespace QmlProjectManager {
+namespace Internal {
+
+class QmlNewStandaloneAppWizard : public Core::BaseFileWizard
+{
+    Q_OBJECT
+
+public:
+    QmlNewStandaloneAppWizard();
+    virtual ~QmlNewStandaloneAppWizard();
+    static Core::BaseFileWizardParameters parameters();
+
+protected:
+    QWizard *createWizardDialog(QWidget *parent, const QString &defaultPath,
+                                const WizardPageList &extensionPages) const;
+    Core::GeneratedFiles generateFiles(const QWizard *wizard,
+                                       QString *errorMessage) const;
+    bool postGenerateFiles(const QWizard *w, const Core::GeneratedFiles &l,
+                           QString *errorMessage);
+
+protected slots:
+    void useProjectPath(const QString &projectName, const QString &projectPath);
+
+private:
+    class QmlStandaloneApp *m_standaloneApp;
+    mutable class QmlNewStandaloneAppWizardDialog *m_wizardDialog;
+};
+
+} // end of namespace Internal
+} // end of namespace QmlProjectManager
+
+#endif // QMLSTANDALONEAPPWIZARD_H
diff --git a/src/plugins/qmlprojectmanager/wizards/qmlstandaloneappwizardoptionspage.cpp b/src/plugins/qmlprojectmanager/wizards/qmlstandaloneappwizardoptionspage.cpp
new file mode 100644
index 00000000000..6f18893f7d6
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/wizards/qmlstandaloneappwizardoptionspage.cpp
@@ -0,0 +1,149 @@
+/**************************************************************************
+**
+** 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 "qmlstandaloneappwizardoptionspage.h"
+#include "ui_qmlstandaloneappwizardoptionspage.h"
+
+#include <QtGui/QDesktopServices>
+#include <QtGui/QFileDialog>
+
+namespace QmlProjectManager {
+namespace Internal {
+
+class QmlStandaloneAppWizardOptionPagePrivate
+{
+    Ui::QmlStandaloneAppWizardOptionPage m_ui;
+    QString symbianSvgIcon;
+    friend class QmlStandaloneAppWizardOptionPage;
+};
+
+QmlStandaloneAppWizardOptionPage::QmlStandaloneAppWizardOptionPage(QWidget *parent) :
+    QWizardPage(parent),
+    m_d(new QmlStandaloneAppWizardOptionPagePrivate)
+{
+    m_d->m_ui.setupUi(this);
+
+    const QIcon open = QApplication::style()->standardIcon(QStyle::SP_DirOpenIcon);
+    m_d->m_ui.symbianAppIconLoadToolButton->setIcon(open);
+    connect(m_d->m_ui.symbianAppIconLoadToolButton, SIGNAL(clicked()), SLOT(openSymbianSvgIcon()));
+
+    m_d->m_ui.orientationBehaviorComboBox->addItem(tr("Auto rotate orientation"),
+                                                   QmlStandaloneApp::Auto);
+    m_d->m_ui.orientationBehaviorComboBox->addItem(tr("Lock to landscape orientation"),
+                                                   QmlStandaloneApp::LockLandscape);
+    m_d->m_ui.orientationBehaviorComboBox->addItem(tr("Lock to portrait orientation"),
+                                                   QmlStandaloneApp::LockPortrait);
+}
+
+QmlStandaloneAppWizardOptionPage::~QmlStandaloneAppWizardOptionPage()
+{
+    delete m_d;
+}
+
+bool QmlStandaloneAppWizardOptionPage::isComplete() const
+{
+    return true;
+}
+
+void QmlStandaloneAppWizardOptionPage::setOrientation(QmlStandaloneApp::Orientation orientation)
+{
+    QComboBox *const comboBox = m_d->m_ui.orientationBehaviorComboBox;
+    for (int i = 0; i < comboBox->count(); ++i)
+        if (comboBox->itemData(i).toInt() == static_cast<int>(orientation)) {
+            comboBox->setCurrentIndex(i);
+            break;
+        }
+}
+
+QmlStandaloneApp::Orientation QmlStandaloneAppWizardOptionPage::orientation() const
+{
+    const int index = m_d->m_ui.orientationBehaviorComboBox->currentIndex();
+    return static_cast<QmlStandaloneApp::Orientation>(m_d->m_ui.orientationBehaviorComboBox->itemData(index).toInt());
+}
+
+QString QmlStandaloneAppWizardOptionPage::symbianSvgIcon() const
+{
+    return m_d->symbianSvgIcon;
+}
+
+void QmlStandaloneAppWizardOptionPage::setSymbianSvgIcon(const QString &icon)
+{
+    QPixmap iconPixmap(icon);
+    if (!iconPixmap.isNull()) {
+        const int symbianIconSize = 44;
+        if (iconPixmap.height() > symbianIconSize || iconPixmap.width() > symbianIconSize)
+            iconPixmap = iconPixmap.scaledToHeight(symbianIconSize, Qt::SmoothTransformation);
+        m_d->m_ui.symbianAppIconPreview->setPixmap(iconPixmap);
+        m_d->symbianSvgIcon = icon;
+    }
+}
+
+QString QmlStandaloneAppWizardOptionPage::symbianUid() const
+{
+    return m_d->m_ui.symbianTargetUid3LineEdit->text();
+}
+
+void QmlStandaloneAppWizardOptionPage::setSymbianUid(const QString &uid)
+{
+    m_d->m_ui.symbianTargetUid3LineEdit->setText(uid);
+}
+
+void QmlStandaloneAppWizardOptionPage::setLoadDummyData(bool loadIt)
+{
+    m_d->m_ui.loadDummyDataCheckBox->setChecked(loadIt);
+}
+
+bool QmlStandaloneAppWizardOptionPage::loadDummyData() const
+{
+    return m_d->m_ui.loadDummyDataCheckBox->isChecked();
+}
+
+void QmlStandaloneAppWizardOptionPage::setNetworkEnabled(bool enableIt)
+{
+    m_d->m_ui.symbianEnableNetworkChackBox->setChecked(enableIt);
+}
+
+bool QmlStandaloneAppWizardOptionPage::networkEnabled() const
+{
+    return m_d->m_ui.symbianEnableNetworkChackBox->isChecked();
+}
+
+void QmlStandaloneAppWizardOptionPage::openSymbianSvgIcon()
+{
+    const QString svgIcon = QFileDialog::getOpenFileName(
+            this,
+            m_d->m_ui.symbianAppIconLabel->text(),
+            QDesktopServices::storageLocation(QDesktopServices::PicturesLocation),
+            QLatin1String("*.svg"));
+    if (!svgIcon.isEmpty())
+        setSymbianSvgIcon(svgIcon);
+}
+
+} // namespace Internal
+} // namespace QmlProjectManager
diff --git a/src/plugins/qmlprojectmanager/wizards/qmlstandaloneappwizardoptionspage.h b/src/plugins/qmlprojectmanager/wizards/qmlstandaloneappwizardoptionspage.h
new file mode 100644
index 00000000000..4714dd35b64
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/wizards/qmlstandaloneappwizardoptionspage.h
@@ -0,0 +1,71 @@
+/**************************************************************************
+**
+** 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 QMLSTANDALONEAPPWIZARDOPTIONPAGE_H
+#define QMLSTANDALONEAPPWIZARDOPTIONPAGE_H
+
+#include <QtGui/QWizardPage>
+#include "qmlstandaloneapp.h"
+
+namespace QmlProjectManager {
+namespace Internal {
+
+class QmlStandaloneAppWizardOptionPage : public QWizardPage
+{
+    Q_OBJECT
+    Q_DISABLE_COPY(QmlStandaloneAppWizardOptionPage)
+
+public:
+    explicit QmlStandaloneAppWizardOptionPage(QWidget *parent = 0);
+    virtual ~QmlStandaloneAppWizardOptionPage();
+
+    virtual bool isComplete() const;
+
+    void setOrientation(QmlStandaloneApp::Orientation orientation);
+    QmlStandaloneApp::Orientation orientation() const;
+    QString symbianSvgIcon() const;
+    void setSymbianSvgIcon(const QString &icon);
+    QString symbianUid() const;
+    void setLoadDummyData(bool loadIt);
+    bool loadDummyData() const;
+    void setNetworkEnabled(bool enableIt);
+    bool networkEnabled() const;
+    void setSymbianUid(const QString &uid);
+
+private slots:
+    void openSymbianSvgIcon(); // Via file open dialog
+
+private:
+    class QmlStandaloneAppWizardOptionPagePrivate *m_d;
+};
+
+} // end of namespace Internal
+} // end of namespace QmlProjectManager
+
+#endif // QMLSTANDALONEAPPWIZARDOPTIONPAGE_H
diff --git a/src/plugins/qmlprojectmanager/wizards/qmlstandaloneappwizardoptionspage.ui b/src/plugins/qmlprojectmanager/wizards/qmlstandaloneappwizardoptionspage.ui
new file mode 100644
index 00000000000..4e7621e3ee5
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/wizards/qmlstandaloneappwizardoptionspage.ui
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QmlStandaloneAppWizardOptionPage</class>
+ <widget class="QWizardPage" name="QmlStandaloneAppWizardOptionPage">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>382</width>
+    <height>285</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>WizardPage</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QGroupBox" name="groupBox_2">
+     <property name="title">
+      <string>General</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_2">
+      <property name="verticalSpacing">
+       <number>12</number>
+      </property>
+      <item row="0" column="0">
+       <widget class="QLabel" name="orientationBehaviorLabel">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string>Orientation Behavior:</string>
+        </property>
+        <property name="buddy">
+         <cstring>orientationBehaviorComboBox</cstring>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QComboBox" name="orientationBehaviorComboBox"/>
+      </item>
+      <item row="1" column="1">
+       <widget class="QCheckBox" name="loadDummyDataCheckBox">
+        <property name="text">
+         <string>Load dummy data</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="groupBox">
+     <property name="title">
+      <string>Symbian specific</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout">
+      <item row="0" column="0">
+       <widget class="QLabel" name="symbianAppIconLabel">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string>Application Icon (.svg):</string>
+        </property>
+        <property name="buddy">
+         <cstring>symbianAppIconLoadToolButton</cstring>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="symbianTargetUid3Label">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string>Target UID3:</string>
+        </property>
+        <property name="buddy">
+         <cstring>symbianTargetUid3LineEdit</cstring>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1" colspan="3">
+       <widget class="QLineEdit" name="symbianTargetUid3LineEdit"/>
+      </item>
+      <item row="2" column="1" colspan="3">
+       <widget class="QCheckBox" name="symbianEnableNetworkChackBox">
+        <property name="text">
+         <string>Enable network access</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QLabel" name="symbianAppIconPreview">
+        <property name="minimumSize">
+         <size>
+          <width>45</width>
+          <height>45</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>45</width>
+          <height>45</height>
+         </size>
+        </property>
+        <property name="frameShape">
+         <enum>QFrame::Panel</enum>
+        </property>
+        <property name="frameShadow">
+         <enum>QFrame::Sunken</enum>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="2">
+       <widget class="QToolButton" name="symbianAppIconLoadToolButton">
+        <property name="text">
+         <string/>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </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>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/plugins/qmlprojectmanager/wizards/templates/app.pro b/src/plugins/qmlprojectmanager/wizards/templates/app.pro
new file mode 100644
index 00000000000..ce18ae63631
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/wizards/templates/app.pro
@@ -0,0 +1,42 @@
+QT += declarative
+
+# MAINQML #
+OTHER_FILES = qml/app.qml
+SOURCES = cpp/main.cpp cpp/qmlapplicationview.cpp
+HEADERS = cpp/qmlapplicationview.h
+INCLUDEPATH += cpp
+
+# DEPLOYMENTFOLDERS #
+DEPLOYMENTFOLDERS = qml
+
+# Avoid auto screen rotation
+# ORIENTATIONLOCK #
+DEFINES += ORIENTATIONLOCK
+
+# Needs to be defined for Symbian
+# NETWORKACCESS #
+DEFINES += NETWORKACCESS
+
+symbian {
+    # TARGETUID3 #
+    TARGET.UID3 = 0xE1111234
+    ICON = cpp/symbianicon.svg
+    for(deploymentfolder, DEPLOYMENTFOLDERS) {
+        eval(item$${deploymentfolder}.sources = $${deploymentfolder})
+        eval(DEPLOYMENT += item$${deploymentfolder})
+    }
+    contains(DEFINES, ORIENTATIONLOCK):LIBS += -lavkon -leikcore -leiksrv -lcone
+    contains(DEFINES, NETWORKACCESS):TARGET.CAPABILITY += NetworkServices
+} else:win32 {
+    # Ossi will want to kill me when he reads this
+    # TODO: let Ossi create a (post link step) deployment for windows
+    !contains(CONFIG, build_pass):for(deploymentfolder, DEPLOYMENTFOLDERS) {
+        system($$QMAKE_COPY_DIR $$deploymentfolder $${OUTDIR} $$replace(OUT_PWD, /, \\)\\$$deploymentfolder\\)
+    }
+} else {
+    # TODO: make this work
+    for(deploymentfolder, DEPLOYMENTFOLDERS) {
+        eval(item$${deploymentfolder}.files = $${deploymentfolder})
+        eval(INSTALLS += item$${deploymentfolder})
+    }
+}
diff --git a/src/plugins/qmlprojectmanager/wizards/templates/cpp/main.cpp b/src/plugins/qmlprojectmanager/wizards/templates/cpp/main.cpp
new file mode 100644
index 00000000000..3ac84b1cfbe
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/wizards/templates/cpp/main.cpp
@@ -0,0 +1,21 @@
+#include <QtGui/QApplication>
+#include "qmlapplicationview.h"
+
+int main(int argc, char *argv[])
+{
+    QApplication app(argc, argv);
+
+    QmlApplicationView qmlApp(QLatin1String("app.qml")); // MAINQML
+    QStringList importPaths; // IMPORTPATHSLIST
+    qmlApp.setImportPathList(importPaths); // SETIMPORTPATHLIST
+    qmlApp.setOrientation(QmlApplicationView::Auto); // ORIENTATION
+    qmlApp.setLoadDummyData(false); // LOADDUMMYDATA
+
+#ifdef Q_OS_SYMBIAN
+    qmlApp.showFullScreen();
+#else
+    qmlApp.setGeometry(QRect(100, 100, 360, 640));
+    qmlApp.show();
+#endif
+    return app.exec();
+}
diff --git a/src/plugins/qmlprojectmanager/wizards/templates/cpp/qmlapplicationview.cpp b/src/plugins/qmlprojectmanager/wizards/templates/cpp/qmlapplicationview.cpp
new file mode 100644
index 00000000000..cff33e560bb
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/wizards/templates/cpp/qmlapplicationview.cpp
@@ -0,0 +1,81 @@
+#include "qmlapplicationview.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtDeclarative/QDeclarativeComponent>
+#include <QtDeclarative/QDeclarativeEngine>
+#include <QtDeclarative/QDeclarativeContext>
+
+#if defined(Q_OS_SYMBIAN) && defined(ORIENTATIONLOCK)
+#include <eikenv.h>
+#include <eikappui.h>
+#include <aknenv.h>
+#include <aknappui.h>
+#endif // Q_OS_SYMBIAN && ORIENTATIONLOCK
+
+class QmlApplicationViewPrivate
+{
+    QString mainQmlFile;
+    friend class QmlApplicationView;
+};
+
+QmlApplicationView::QmlApplicationView(const QString &mainQmlFile, QWidget *parent)
+    : QDeclarativeView(parent)
+    , m_d(new QmlApplicationViewPrivate)
+{
+    m_d->mainQmlFile = mainQmlFile;
+    setSource(QUrl(m_d->mainQmlFile));
+    connect(engine(), SIGNAL(quit()), SLOT(close()));
+    setResizeMode(QDeclarativeView::SizeRootObjectToView);
+}
+
+QmlApplicationView::~QmlApplicationView()
+{
+    delete m_d;
+}
+
+void QmlApplicationView::setImportPathList(const QStringList &importPaths)
+{
+    engine()->setImportPathList(importPaths);
+}
+
+void QmlApplicationView::setOrientation(Orientation orientation)
+{
+    if (orientation != Auto) {
+#if defined(Q_OS_SYMBIAN)
+#if defined(ORIENTATIONLOCK)
+        const CAknAppUiBase::TAppUiOrientation uiOrientation =
+                (orientation == LockPortrait) ? CAknAppUi::EAppUiOrientationPortrait
+                    : CAknAppUi::EAppUiOrientationLandscape;
+        CAknAppUi* appUi = dynamic_cast<CAknAppUi*> (CEikonEnv::Static()->AppUi());
+        TRAPD(error,
+            if (appUi)
+                appUi->SetOrientationL(uiOrientation);
+        );
+#else // ORIENTATIONLOCK
+        qWarning("'ORIENTATIONLOCK' needs to be defined on Symbian when locking the orientation.");
+#endif // ORIENTATIONLOCK
+#endif // Q_OS_SYMBIAN
+    }
+}
+
+void QmlApplicationView::setLoadDummyData(bool loadDummyData)
+{
+    if (loadDummyData) {
+        const QFileInfo mainQmlFileInfo(m_d->mainQmlFile);
+        const QDir dir(mainQmlFileInfo.absolutePath() + QLatin1String("/dummydata"),
+                 QLatin1String("*.qml"));
+        foreach (const QFileInfo &qmlFile, dir.entryInfoList()) {
+            QFile f(qmlFile.absoluteFilePath());
+            if (f.open(QIODevice::ReadOnly)) {
+                QDeclarativeComponent comp(engine());
+                comp.setData(f.readAll(), QUrl());
+                QObject *dummyData = comp.create();
+                if (dummyData) {
+                    rootContext()->setContextProperty(qmlFile.baseName(), dummyData);
+                    dummyData->setParent(this);
+                }
+            }
+        }
+    }
+}
diff --git a/src/plugins/qmlprojectmanager/wizards/templates/cpp/qmlapplicationview.h b/src/plugins/qmlprojectmanager/wizards/templates/cpp/qmlapplicationview.h
new file mode 100644
index 00000000000..0b8b998f975
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/wizards/templates/cpp/qmlapplicationview.h
@@ -0,0 +1,26 @@
+#ifndef QMLAPPLICATIONVIEW_H
+#define QMLAPPLICATIONVIEW_H
+
+#include <QtDeclarative/QDeclarativeView>
+
+class QmlApplicationView : public QDeclarativeView
+{
+public:
+    enum Orientation {
+        LockPortrait,
+        LockLandscape,
+        Auto
+    };
+
+    QmlApplicationView(const QString &mainQmlFile, QWidget *parent = 0);
+    virtual ~QmlApplicationView();
+
+    void setImportPathList(const QStringList &importPaths);
+    void setOrientation(Orientation orientation);
+    void setLoadDummyData(bool loadDummyData);
+
+private:
+    class QmlApplicationViewPrivate *m_d;
+};
+
+#endif // QMLAPPLICATIONVIEW_H
diff --git a/src/plugins/qmlprojectmanager/wizards/templates/cpp/symbianicon.svg b/src/plugins/qmlprojectmanager/wizards/templates/cpp/symbianicon.svg
new file mode 100644
index 00000000000..566acfada01
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/wizards/templates/cpp/symbianicon.svg
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   height="44px"
+   version="1.1"
+   viewBox="0 0 44 44"
+   width="44px"
+   x="0px"
+   y="0px"
+   id="svg2"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="qt.svg">
+  <metadata
+     id="metadata18">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs16">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 22 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="44 : 22 : 1"
+       inkscape:persp3d-origin="22 : 14.666667 : 1"
+       id="perspective2836" />
+  </defs>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1020"
+     id="namedview14"
+     showgrid="false"
+     inkscape:zoom="21.454545"
+     inkscape:cx="49.412871"
+     inkscape:cy="21.894358"
+     inkscape:window-x="-4"
+     inkscape:window-y="-4"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="g3" />
+  <g
+     transform="matrix(0.18308778,0,0,0.18308778,6.6100946,3.2385199)"
+     id="g3">
+    <path
+       d="M 43.09,0.3586 C 40.94,0.0036 38.84,-0.0824 36.81,0.0776 31.968136,0.39505671 27.122677,0.73638425 22.28,1.0696 9.62,2.0816 0,12.4996 0,26.8896 l 0,169.7 14.19,13.2 28.87,-209.42 0.03,-0.011 z"
+       style="fill:#006225"
+       id="path5"
+       sodipodi:nodetypes="cccccccc" />
+    <path
+       d="m 174.4,160 c 0,12.5 -7.75,24.07 -17.57,25.77 L 14.23,209.73 V 25.93 C 14.23,9.21 27.57,-2.27 43.12,0.3 l 131.3,21.52 v 138.2 z"
+       style="fill:#80c342"
+       id="path7" />
+    <path
+       d="m 154.9,80.96 -12.96,-0.598 0,0.278 6.945,0.32 6.016,0 z"
+       style="fill:#006225"
+       id="path11" />
+    <path
+       d="m 144.6,135.6 c 0.66,0.328 1.43,0.476 2.351,0.476 0.161,0 0.329,-0.004 0.497,-0.016 2.55,-0.148 5.32,-0.933 8.343,-2.308 h -6.015 c -1.821,0.832 -3.532,1.457 -5.176,1.848 z"
+       style="fill:#006225"
+       id="path13" />
+    <path
+       id="path17"
+       style="fill:#ffffff"
+       d="m 91.15,132.4 c 2.351,-6.051 3.511,-17.91 3.511,-35.62 0,-15.89 -1.148,-26.82 -3.484,-32.81 -2.336,-6.027 -5.832,-9.281 -10.52,-9.691 -0.359,-0.031 -0.714,-0.051 -1.058,-0.051 -4.34,0 -7.68,2.535 -10.01,7.625 -2.52,5.543 -3.793,17.04 -3.793,34.44 0,16.82 1.238,28.75 3.734,35.75 2.356,6.672 5.879,9.976 10.5,9.976 0.207,0 0.41,-0.008 0.621,-0.019 4.633,-0.293 8.121,-3.496 10.49,-9.602 m 17.98,3.75 c -4.117,9.707 -10.39,16.06 -18.99,19 0.867,4.449 2.176,7.441 3.922,9.019 1.351,1.211 3.433,1.821 6.222,1.821 0.805,0 1.668,-0.055 2.59,-0.157 v 13.12 l -5.961,0.782 c -1.758,0.23 -3.426,0.343 -5.004,0.343 -5.218,0 -9.445,-1.265 -12.62,-3.824 -4.207,-3.379 -7.308,-9.894 -9.297,-19.54 -9.136,-1.945 -16.26,-7.754 -21.19,-17.5 -5.004,-9.902 -7.551,-24.39 -7.551,-43.34 0,-20.43 3.484,-35.51 10.34,-45.07 5.789,-8.07 13.86,-12.04 24.02,-12.04 1.629,0 3.309,0.102 5.043,0.305 11.95,1.375 20.62,7.016 26.26,16.79 5.535,9.562 8.254,23.27 8.254,41.26 0,16.48 -2,29.45 -6.043,39.02 z M 130.4,45.91 l 11.52,1.238 0,20.21 12.96,0.914 0,12.68 -12.96,-0.598 0,46.33 c 0,4.032 0.445,6.625 1.34,7.789 0.8,1.067 2.046,1.594 3.71,1.594 0.161,0 0.329,-0.004 0.497,-0.016 2.55,-0.148 5.32,-0.933 8.343,-2.308 v 11.65 c -5.136,2.258 -10.18,3.598 -15.12,4.02 -0.718,0.055 -1.41,0.086 -2.078,0.086 -4.48,0 -7.906,-1.301 -10.25,-3.934 -2.73,-3.051 -4.09,-7.949 -4.09,-14.67 V 79.535 L 118.046,79.25 V 65.66 l 7.586,0.547 4.773,-20.3 z" />
+    <path
+       d="m 100.3,166 c 0.809,0 1.672,-0.055 2.59,-0.157 H 98.054 C 98.73,165.949 99.507,166 100.3,166 z"
+       style="fill:#006225"
+       id="path19" />
+    <path
+       id="path21"
+       style="fill:#006225"
+       d="m 84.85,63.98 c 2.336,5.997 3.484,16.92 3.484,32.81 0,17.7 -1.16,29.57 -3.512,35.62 -1.894,4.879 -4.527,7.902 -7.863,9.07 0.965,0.368 1.992,0.551 3.078,0.551 0.207,0 0.41,-0.008 0.621,-0.019 4.633,-0.293 8.121,-3.496 10.49,-9.602 2.351,-6.051 3.511,-17.91 3.511,-35.62 0,-15.89 -1.148,-26.82 -3.484,-32.81 -2.336,-6.027 -5.832,-9.281 -10.52,-9.691 -0.359,-0.031 -0.714,-0.051 -1.058,-0.051 -1.09,0 -2.117,0.16 -3.082,0.481 h -0.004 c 3.601,1.121 6.379,4.215 8.336,9.261 z m -2.344,114.3 c -0.113,-0.05 -0.227,-0.105 -0.336,-0.16 -0.012,-0.004 -0.023,-0.012 -0.035,-0.015 -0.102,-0.051 -0.207,-0.106 -0.309,-0.157 -0.019,-0.011 -0.039,-0.019 -0.058,-0.031 -0.09,-0.051 -0.184,-0.098 -0.278,-0.148 -0.027,-0.016 -0.054,-0.036 -0.086,-0.051 -0.082,-0.043 -0.164,-0.09 -0.242,-0.137 -0.039,-0.023 -0.078,-0.047 -0.113,-0.07 -0.07,-0.039 -0.145,-0.082 -0.215,-0.125 -0.047,-0.031 -0.094,-0.059 -0.14,-0.09 -0.059,-0.039 -0.118,-0.074 -0.176,-0.113 -0.059,-0.039 -0.114,-0.075 -0.168,-0.114 -0.051,-0.031 -0.102,-0.066 -0.149,-0.097 -0.066,-0.047 -0.132,-0.094 -0.195,-0.137 -0.039,-0.027 -0.078,-0.055 -0.113,-0.082 -0.078,-0.055 -0.153,-0.113 -0.231,-0.172 -0.023,-0.016 -0.05,-0.035 -0.078,-0.055 -0.098,-0.078 -0.199,-0.156 -0.297,-0.234 -4.207,-3.379 -7.308,-9.894 -9.297,-19.54 -9.136,-1.945 -16.26,-7.754 -21.19,-17.5 -5.004,-9.902 -7.551,-24.39 -7.551,-43.34 0,-20.43 3.484,-35.51 10.34,-45.07 5.789,-8.07 13.86,-12.04 24.02,-12.04 h -6.351 c -10.15,0.008 -18.22,3.977 -24,12.04 -6.855,9.563 -10.34,24.64 -10.34,45.07 0,18.95 2.547,33.44 7.551,43.34 4.934,9.75 12.05,15.56 21.19,17.5 1.989,9.641 5.09,16.16 9.297,19.54 3.176,2.559 7.403,3.824 12.62,3.824 0.098,0 0.199,0 0.297,-0.004 h 5.539 c -3.406,-0.05 -6.383,-0.66 -8.906,-1.828 L 82.498,178.28 z M 128.4,145.6 c -2.73,-3.051 -4.09,-7.949 -4.09,-14.67 V 79.57 l -6.226,-0.285 v -13.59 h -6.016 v 3.035 c 0.871,3.273 1.555,6.82 2.063,10.64 l 4.164,0.192 v 51.36 c 0,6.723 1.367,11.62 4.09,14.67 2.343,2.633 5.765,3.934 10.25,3.934 h 6.015 c -4.48,0 -7.906,-1.301 -10.25,-3.934 z m 2.043,-99.66 -6.016,0 -4.668,19.88 5.911,0.422 4.773,-20.3 z" />
+  </g>
+</svg>
diff --git a/src/plugins/qmlprojectmanager/wizards/templates/qml/app.qml b/src/plugins/qmlprojectmanager/wizards/templates/qml/app.qml
new file mode 100644
index 00000000000..baa3db352c2
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/wizards/templates/qml/app.qml
@@ -0,0 +1,8 @@
+import Qt 4.7
+
+Rectangle {
+    Text {
+        text: "Hello World"
+        anchors.centerIn: parent
+    }
+}
-- 
GitLab