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 @@ images/qmlfolder.png images/qmlproject.png images/qml_wizard.png + wizards/templates/app.pro + wizards/templates/qml/app.qml + wizards/templates/cpp/qmlapplicationview.h + wizards/templates/cpp/symbianicon.svg + wizards/templates/cpp/main.cpp + wizards/templates/cpp/qmlapplicationview.cpp 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 +#include +#include +#include + +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 ¶meter) +{ + 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 +#ifndef CREATORLESSTEST +#include +#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 + +#include + +#include +#include + +#include +#include +#include +#include + +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(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 +#include + +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 +#include + +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(orientation)) { + comboBox->setCurrentIndex(i); + break; + } +} + +QmlStandaloneApp::Orientation QmlStandaloneAppWizardOptionPage::orientation() const +{ + const int index = m_d->m_ui.orientationBehaviorComboBox->currentIndex(); + return static_cast(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 +#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 @@ + + + QmlStandaloneAppWizardOptionPage + + + + 0 + 0 + 382 + 285 + + + + WizardPage + + + + + + General + + + + 12 + + + + + + 0 + 0 + + + + Orientation Behavior: + + + orientationBehaviorComboBox + + + + + + + + + + Load dummy data + + + + + + + + + + Symbian specific + + + + + + + 0 + 0 + + + + Application Icon (.svg): + + + symbianAppIconLoadToolButton + + + + + + + + 0 + 0 + + + + Target UID3: + + + symbianTargetUid3LineEdit + + + + + + + + + + Enable network access + + + + + + + + 45 + 45 + + + + + 45 + 45 + + + + QFrame::Panel + + + QFrame::Sunken + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 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 +#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 +#include +#include +#include +#include + +#if defined(Q_OS_SYMBIAN) && defined(ORIENTATIONLOCK) +#include +#include +#include +#include +#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 (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 + +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 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + 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 + } +}