From ecc4615d56af25b162aa2d0d15a80bb0a61dc327 Mon Sep 17 00:00:00 2001
From: Roberto Raggi <roberto.raggi@nokia.com>
Date: Mon, 11 May 2009 10:58:04 +0200
Subject: [PATCH] Added a project wizard for QML applications.

---
 .../qmlprojectmanager/qmlnewprojectwizard.cpp | 256 ++++++++++++++++++
 .../qmlprojectmanager/qmlnewprojectwizard.h   | 115 ++++++++
 .../qmlprojectmanager/qmlprojectmanager.pro   |   2 +
 .../qmlprojectmanager/qmlprojectplugin.cpp    |   2 +
 4 files changed, 375 insertions(+)
 create mode 100644 src/plugins/qmlprojectmanager/qmlnewprojectwizard.cpp
 create mode 100644 src/plugins/qmlprojectmanager/qmlnewprojectwizard.h

diff --git a/src/plugins/qmlprojectmanager/qmlnewprojectwizard.cpp b/src/plugins/qmlprojectmanager/qmlnewprojectwizard.cpp
new file mode 100644
index 00000000000..efe12b0c2ba
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/qmlnewprojectwizard.cpp
@@ -0,0 +1,256 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (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 qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#include "qmlnewprojectwizard.h"
+
+#include <coreplugin/icore.h>
+#include <coreplugin/mimedatabase.h>
+#include <projectexplorer/projectexplorer.h>
+
+#include <utils/filenamevalidatinglineedit.h>
+#include <utils/filewizardpage.h>
+#include <utils/pathchooser.h>
+#include <utils/projectintropage.h>
+
+#include <QtCore/QDir>
+#include <QtCore/QtDebug>
+
+#include <QtGui/QDirModel>
+#include <QtGui/QFormLayout>
+#include <QtGui/QListView>
+#include <QtGui/QTreeView>
+
+using namespace QmlProjectManager::Internal;
+using namespace Core::Utils;
+
+namespace {
+
+class DirModel : public QDirModel
+{
+public:
+    DirModel(QObject *parent)
+        : QDirModel(parent)
+    { setFilter(QDir::Dirs | QDir::NoDotAndDotDot); }
+
+    virtual ~DirModel()
+    { }
+
+public:
+    virtual int columnCount(const QModelIndex &) const
+    { return 1; }
+
+    virtual Qt::ItemFlags flags(const QModelIndex &index) const
+    { return QDirModel::flags(index) | Qt::ItemIsUserCheckable; }
+
+    virtual QVariant data(const QModelIndex &index, int role) const
+    {
+        if (index.column() == 0 && role == Qt::CheckStateRole) {
+            if (m_selectedPaths.contains(index))
+                return Qt::Checked;
+
+            return Qt::Unchecked;
+        }
+
+        return QDirModel::data(index, role);
+    }
+
+    virtual bool setData(const QModelIndex &index, const QVariant &value, int role)
+    {
+        if (index.column() == 0 && role == Qt::CheckStateRole) {
+            if (value.toBool())
+                m_selectedPaths.insert(index);
+            else
+                m_selectedPaths.remove(index);
+
+            return true;
+        }
+
+        return QDirModel::setData(index, value, role);
+    }
+
+    void clearSelectedPaths()
+    { m_selectedPaths.clear(); }
+
+    QSet<QString> selectedPaths() const
+    {
+        QSet<QString> paths;
+
+        foreach (const QModelIndex &index, m_selectedPaths)
+            paths.insert(filePath(index));
+
+        return paths;
+    }
+
+private:
+    QSet<QModelIndex> m_selectedPaths;
+};
+
+} // end of anonymous namespace
+
+
+//////////////////////////////////////////////////////////////////////////////
+// QmlNewProjectWizardDialog
+//////////////////////////////////////////////////////////////////////////////
+
+
+QmlNewProjectWizardDialog::QmlNewProjectWizardDialog(QWidget *parent)
+    : QWizard(parent)
+{
+    setWindowTitle(tr("New QML Project"));
+
+    m_introPage = new Core::Utils::ProjectIntroPage();
+    m_introPage->setDescription(tr("This wizard generates a QML application project."));
+
+    addPage(m_introPage);
+}
+
+QmlNewProjectWizardDialog::~QmlNewProjectWizardDialog()
+{ }
+
+QString QmlNewProjectWizardDialog::path() const
+{
+    return m_introPage->path();
+}
+
+void QmlNewProjectWizardDialog::setPath(const QString &path)
+{
+    m_introPage->setPath(path);
+}
+
+QString QmlNewProjectWizardDialog::projectName() const
+{
+    return m_introPage->name();
+}
+
+void QmlNewProjectWizardDialog::updateFilesView(const QModelIndex &current,
+                                                 const QModelIndex &)
+{
+    if (! current.isValid())
+        m_filesView->setModel(0);
+
+    else {
+        const QString selectedPath = m_dirModel->filePath(current);
+
+        if (! m_filesView->model())
+            m_filesView->setModel(m_filesModel);
+
+        m_filesView->setRootIndex(m_filesModel->index(selectedPath));
+    }
+}
+
+void QmlNewProjectWizardDialog::initializePage(int id)
+{
+    Q_UNUSED(id)
+}
+
+bool QmlNewProjectWizardDialog::validateCurrentPage()
+{
+    return QWizard::validateCurrentPage();
+}
+
+QmlNewProjectWizard::QmlNewProjectWizard()
+    : Core::BaseFileWizard(parameters())
+{ }
+
+QmlNewProjectWizard::~QmlNewProjectWizard()
+{ }
+
+Core::BaseFileWizardParameters QmlNewProjectWizard::parameters()
+{
+    static Core::BaseFileWizardParameters parameters(ProjectWizard);
+    parameters.setIcon(QIcon(":/wizards/images/console.png"));
+    parameters.setName(tr("QML Application"));
+    parameters.setDescription(tr("Creates a QML application."));
+    parameters.setCategory(QLatin1String("Projects"));
+    parameters.setTrCategory(tr("Projects"));
+    return parameters;
+}
+
+QWizard *QmlNewProjectWizard::createWizardDialog(QWidget *parent,
+                                                  const QString &defaultPath,
+                                                  const WizardPageList &extensionPages) const
+{
+    QmlNewProjectWizardDialog *wizard = new QmlNewProjectWizardDialog(parent);
+    setupWizard(wizard);
+
+    wizard->setPath(defaultPath);
+
+    foreach (QWizardPage *p, extensionPages)
+        wizard->addPage(p);
+
+    return wizard;
+}
+
+Core::GeneratedFiles QmlNewProjectWizard::generateFiles(const QWizard *w,
+                                                     QString *errorMessage) const
+{
+    Q_UNUSED(errorMessage)
+
+    const QmlNewProjectWizardDialog *wizard = qobject_cast<const QmlNewProjectWizardDialog *>(w);
+    const QString projectName = wizard->projectName();
+    const QString projectPath = wizard->path() + QLatin1Char('/') + projectName;
+
+    const QString creatorFileName = Core::BaseFileWizard::buildFileName(projectPath,
+                                                                        projectName,
+                                                                        QLatin1String("qmlproject"));
+
+    const QString mainFileName = Core::BaseFileWizard::buildFileName(projectPath,
+                                                                     projectName,
+                                                                     QLatin1String("qml"));
+
+    QString contents;
+    QTextStream out(&contents);
+    out << "Text {" << endl
+        << "    text: \"Hello, world!\"" << endl
+        << "}" << endl;
+
+    Core::GeneratedFile generatedMainFile(mainFileName);
+    generatedMainFile.setContents(contents);
+
+    Core::GeneratedFile generatedCreatorFile(creatorFileName);
+    generatedCreatorFile.setContents(projectName + QLatin1String(".qml\n"));
+
+    Core::GeneratedFiles files;
+    files.append(generatedMainFile);
+    files.append(generatedCreatorFile);
+
+    return files;
+}
+
+bool QmlNewProjectWizard::postGenerateFiles(const Core::GeneratedFiles &l, QString *errorMessage)
+{
+    // Post-Generate: Open the project
+    const QString proFileName = l.back().path();
+    if (!ProjectExplorer::ProjectExplorerPlugin::instance()->openProject(proFileName)) {
+        *errorMessage = tr("The project %1 could not be opened.").arg(proFileName);
+        return false;
+    }
+    return true;
+}
+
diff --git a/src/plugins/qmlprojectmanager/qmlnewprojectwizard.h b/src/plugins/qmlprojectmanager/qmlnewprojectwizard.h
new file mode 100644
index 00000000000..8ac833376d3
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/qmlnewprojectwizard.h
@@ -0,0 +1,115 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (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 qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#ifndef QMLNEWPROJECTWIZARD_H
+#define QMLNEWPROJECTWIZARD_H
+
+#include <coreplugin/basefilewizard.h>
+#include <QtGui/QWizard>
+
+QT_BEGIN_NAMESPACE
+class QDir;
+class QDirModel;
+class QFileInfo;
+class QListView;
+class QModelIndex;
+class QStringList;
+class QTreeView;
+QT_END_NAMESPACE
+
+namespace Core {
+namespace Utils {
+
+class FileWizardPage;
+class ProjectIntroPage;
+
+} // namespace Utils
+} // namespace Core
+
+namespace QmlProjectManager {
+namespace Internal {
+
+class QmlNewProjectWizardDialog : public QWizard
+{
+    Q_OBJECT
+
+public:
+    QmlNewProjectWizardDialog(QWidget *parent = 0);
+    virtual ~QmlNewProjectWizardDialog();
+
+    QString path() const;
+    void setPath(const QString &path);
+
+    QString projectName() const;
+
+private Q_SLOTS:
+    void updateFilesView(const QModelIndex &current,
+                         const QModelIndex &previous);
+
+protected:
+    virtual void initializePage(int id);
+    virtual bool validateCurrentPage();
+
+private:
+    int m_secondPageId;
+
+    Core::Utils::ProjectIntroPage *m_introPage;
+
+    QTreeView *m_dirView;
+    QDirModel *m_dirModel;
+
+    QListView *m_filesView;
+    QDirModel *m_filesModel;
+};
+
+class QmlNewProjectWizard : public Core::BaseFileWizard
+{
+    Q_OBJECT
+
+public:
+    QmlNewProjectWizard();
+    virtual ~QmlNewProjectWizard();
+
+    static Core::BaseFileWizardParameters parameters();
+
+protected:
+    virtual QWizard *createWizardDialog(QWidget *parent,
+                                        const QString &defaultPath,
+                                        const WizardPageList &extensionPages) const;
+
+    virtual Core::GeneratedFiles generateFiles(const QWizard *w,
+                                               QString *errorMessage) const;
+
+    virtual bool postGenerateFiles(const Core::GeneratedFiles &l, QString *errorMessage);
+};
+
+} // end of namespace Internal
+} // end of namespace QmlProjectManager
+
+#endif // QMLNEWPROJECTWIZARD_H
diff --git a/src/plugins/qmlprojectmanager/qmlprojectmanager.pro b/src/plugins/qmlprojectmanager/qmlprojectmanager.pro
index f9804420a75..1a2bf725e0a 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectmanager.pro
+++ b/src/plugins/qmlprojectmanager/qmlprojectmanager.pro
@@ -8,12 +8,14 @@ HEADERS = qmlproject.h \
     qmlprojectconstants.h \
     qmlprojectnodes.h \
     qmlprojectwizard.h \
+    qmlnewprojectwizard.h \
     qmlprojectfileseditor.h
 SOURCES = qmlproject.cpp \
     qmlprojectplugin.cpp \
     qmlprojectmanager.cpp \
     qmlprojectnodes.cpp \
     qmlprojectwizard.cpp \
+    qmlnewprojectwizard.cpp \
     qmlprojectfileseditor.cpp
 RESOURCES += qmlproject.qrc
 
diff --git a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp
index 4187f520e0d..1cd74d055ad 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp
@@ -30,6 +30,7 @@
 #include "qmlprojectplugin.h"
 #include "qmlprojectmanager.h"
 #include "qmlprojectwizard.h"
+#include "qmlnewprojectwizard.h"
 #include "qmlprojectconstants.h"
 #include "qmlprojectfileseditor.h"
 #include "qmlproject.h"
@@ -77,6 +78,7 @@ bool QmlProjectPlugin::initialize(const QStringList &, QString *errorMessage)
 
     addAutoReleasedObject(manager);
     addAutoReleasedObject(new QmlRunConfigurationFactory);
+    addAutoReleasedObject(new QmlNewProjectWizard);
     addAutoReleasedObject(new QmlProjectWizard);
 
     return true;
-- 
GitLab