diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 388a8c53bc70c3a06a870faff221d78c0961630b..ad25fcd0c4e2083ab7185a188e5723ee04fe6967 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -31,6 +31,7 @@ SUBDIRS = plugin_coreplugin \ plugin_designer \ plugin_resourceeditor \ plugin_genericprojectmanager \ + plugin_qmlprojectmanager \ debugger/dumper.pro plugin_coreplugin.subdir = coreplugin @@ -162,3 +163,8 @@ plugin_genericprojectmanager.depends += plugin_projectexplorer plugin_genericprojectmanager.depends += plugin_cpptools plugin_genericprojectmanager.depends += plugin_cppeditor plugin_genericprojectmanager.depends += plugin_help + +plugin_qmlprojectmanager.subdir = qmlprojectmanager +plugin_qmlprojectmanager.depends = plugin_texteditor +plugin_qmlprojectmanager.depends += plugin_projectexplorer +plugin_qmlprojectmanager.depends += plugin_help diff --git a/src/plugins/qmlprojectmanager/QmlProject.mimetypes.xml b/src/plugins/qmlprojectmanager/QmlProject.mimetypes.xml new file mode 100644 index 0000000000000000000000000000000000000000..9132ca54a667fe26385275be6fa495feff113be7 --- /dev/null +++ b/src/plugins/qmlprojectmanager/QmlProject.mimetypes.xml @@ -0,0 +1,16 @@ +<?xml version="1.0"?> + +<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'> + <mime-type type="text/x-qml-project"> + <sub-class-of type="text/plain"/> + <comment>Qml Project file</comment> + <glob pattern="*.qmlproject"/> + </mime-type> + + <mime-type type="application/vnd.nokia.qt.qml.files"> + <sub-class-of type="text/plain"/> + <comment>Qml Project Files</comment> + <glob pattern="*.files"/> + </mime-type> + +</mime-info> diff --git a/src/plugins/qmlprojectmanager/QmlProjectManager.pluginspec b/src/plugins/qmlprojectmanager/QmlProjectManager.pluginspec new file mode 100644 index 0000000000000000000000000000000000000000..7fc7c9efffdc34ed0e88e21221de5970cc26c12c --- /dev/null +++ b/src/plugins/qmlprojectmanager/QmlProjectManager.pluginspec @@ -0,0 +1,28 @@ +<plugin name="QmlProjectManager" version="1.1.80" compatVersion="1.1.80"> + <vendor>Nokia Corporation</vendor> + <copyright>(C) 2008-2009 Nokia Corporation</copyright> + <license> +Commercial Usage + +Licensees holding valid Qt Commercial licenses may use this plugin 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 plugin may be used under the terms of the GNU Lesser +General Public License version 2.1 as published by the Free Software +Foundation. 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.</license> + <description>Qml support</description> + <url>http://www.qtsoftware.com</url> + <dependencyList> + <dependency name="TextEditor" version="1.1.80"/> + <dependency name="ProjectExplorer" version="1.1.80"/> + <dependency name="CppTools" version="1.1.80"/> + <dependency name="CppEditor" version="1.1.80"/> + <dependency name="Help" version="1.1.80"/> + </dependencyList> +</plugin> diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9595e539e5d14bc675a5bc40bbb2493920d0b5dc --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlproject.cpp @@ -0,0 +1,385 @@ +/************************************************************************** +** +** 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 "qmlproject.h" +#include "qmlprojectconstants.h" + +#include <projectexplorer/toolchain.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <extensionsystem/pluginmanager.h> +#include <utils/pathchooser.h> +#include <utils/qtcassert.h> +#include <coreplugin/icore.h> + +#include <QtCore/QtDebug> +#include <QtCore/QDir> +#include <QtCore/QSettings> +#include <QtCore/QProcess> +#include <QtCore/QCoreApplication> + +#include <QtGui/QFormLayout> +#include <QtGui/QMainWindow> +#include <QtGui/QComboBox> +#include <QtGui/QStringListModel> +#include <QtGui/QListWidget> +#include <QtGui/QPushButton> + +using namespace QmlProjectManager; +using namespace QmlProjectManager::Internal; + +namespace { + +/** + * An editable string list model. New strings can be added by editing the entry + * called "<new>", displayed at the end. + */ +class ListModel: public QStringListModel +{ +public: + ListModel(QObject *parent) + : QStringListModel(parent) {} + + virtual ~ListModel() {} + + virtual int rowCount(const QModelIndex &parent) const + { return 1 + QStringListModel::rowCount(parent); } + + virtual Qt::ItemFlags flags(const QModelIndex &index) const + { return QStringListModel::flags(index) | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; } + + virtual QModelIndex index(int row, int column, const QModelIndex &parent) const + { + if (row == stringList().size()) + return createIndex(row, column); + + return QStringListModel::index(row, column, parent); + } + + virtual QVariant data(const QModelIndex &index, int role) const + { + if (role == Qt::DisplayRole || role == Qt::EditRole) { + if (index.row() == stringList().size()) + return QCoreApplication::translate("QmlProject", "<new>"); + } + + return QStringListModel::data(index, role); + } + + virtual bool setData(const QModelIndex &index, const QVariant &value, int role) + { + if (role == Qt::EditRole && index.row() == stringList().size()) + insertRow(index.row(), QModelIndex()); + + return QStringListModel::setData(index, value, role); + } +}; + +} // end of anonymous namespace + +//////////////////////////////////////////////////////////////////////////////////// +// QmlProject +//////////////////////////////////////////////////////////////////////////////////// + +QmlProject::QmlProject(Manager *manager, const QString &fileName) + : m_manager(manager), + m_fileName(fileName) +{ + QFileInfo fileInfo(m_fileName); + QDir dir = fileInfo.dir(); + + m_projectName = fileInfo.completeBaseName(); + m_filesFileName = QFileInfo(dir, m_projectName + QLatin1String(".files")).absoluteFilePath(); + + m_file = new QmlProjectFile(this, fileName); + m_rootNode = new QmlProjectNode(this, m_file); + + m_manager->registerProject(this); +} + +QmlProject::~QmlProject() +{ + m_manager->unregisterProject(this); + + delete m_rootNode; +} + +QString QmlProject::filesFileName() const +{ return m_filesFileName; } + +static QStringList readLines(const QString &absoluteFileName) +{ + QStringList lines; + + QFile file(absoluteFileName); + if (file.open(QFile::ReadOnly)) { + QTextStream stream(&file); + + forever { + QString line = stream.readLine(); + if (line.isNull()) + break; + + line = line.trimmed(); + if (line.isEmpty()) + continue; + + lines.append(line); + } + } + + return lines; +} + + +void QmlProject::parseProject(RefreshOptions options) +{ + if (options & Files) { + m_files = convertToAbsoluteFiles(readLines(filesFileName())); + m_files.removeDuplicates(); + } + + if (options & Configuration) { + // update configuration + } + + if (options & Files) + emit fileListChanged(); +} + +void QmlProject::refresh(RefreshOptions options) +{ + QSet<QString> oldFileList; + if (!(options & Configuration)) + oldFileList = m_files.toSet(); + + parseProject(options); + + if (options & Files) + m_rootNode->refresh(); +} + +QStringList QmlProject::convertToAbsoluteFiles(const QStringList &paths) const +{ + const QDir projectDir(QFileInfo(m_fileName).dir()); + QStringList absolutePaths; + foreach (const QString &file, paths) { + QFileInfo fileInfo(projectDir, file); + absolutePaths.append(fileInfo.absoluteFilePath()); + } + absolutePaths.removeDuplicates(); + return absolutePaths; +} + +QStringList QmlProject::files() const +{ return m_files; } + +QString QmlProject::buildParser(const QString &) const +{ + return QString(); +} + +QString QmlProject::name() const +{ + return m_projectName; +} + +Core::IFile *QmlProject::file() const +{ + return m_file; +} + +ProjectExplorer::IProjectManager *QmlProject::projectManager() const +{ + return m_manager; +} + +QList<ProjectExplorer::Project *> QmlProject::dependsOn() +{ + return QList<Project *>(); +} + +bool QmlProject::isApplication() const +{ + return true; +} + +ProjectExplorer::Environment QmlProject::environment(const QString &) const +{ + return ProjectExplorer::Environment::systemEnvironment(); +} + +QString QmlProject::buildDirectory(const QString &buildConfiguration) const +{ + QString buildDirectory = value(buildConfiguration, "buildDirectory").toString(); + + if (buildDirectory.isEmpty()) { + QFileInfo fileInfo(m_fileName); + + buildDirectory = fileInfo.absolutePath(); + } + + return buildDirectory; +} + +ProjectExplorer::BuildStepConfigWidget *QmlProject::createConfigWidget() +{ + return new QmlBuildSettingsWidget(this); +} + +QList<ProjectExplorer::BuildStepConfigWidget*> QmlProject::subConfigWidgets() +{ + return QList<ProjectExplorer::BuildStepConfigWidget*>(); +} + + void QmlProject::newBuildConfiguration(const QString &) + { + } + +QmlProjectNode *QmlProject::rootProjectNode() const +{ + return m_rootNode; +} + +QStringList QmlProject::files(FilesMode) const +{ + return m_files; +} + +QStringList QmlProject::targets() const +{ + QStringList targets; + return targets; +} + +QmlMakeStep *QmlProject::makeStep() const +{ + return 0; +} + +void QmlProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader &reader) +{ + Project::restoreSettingsImpl(reader); + + refresh(Everything); +} + +void QmlProject::saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &writer) +{ + Project::saveSettingsImpl(writer); +} + +//////////////////////////////////////////////////////////////////////////////////// +// QmlBuildSettingsWidget +//////////////////////////////////////////////////////////////////////////////////// + +QmlBuildSettingsWidget::QmlBuildSettingsWidget(QmlProject *project) + : m_project(project) +{ + QFormLayout *fl = new QFormLayout(this); + + // build directory + m_pathChooser = new Core::Utils::PathChooser(this); + m_pathChooser->setEnabled(true); + fl->addRow(tr("Build directory:"), m_pathChooser); + connect(m_pathChooser, SIGNAL(changed()), this, SLOT(buildDirectoryChanged())); +} + +QmlBuildSettingsWidget::~QmlBuildSettingsWidget() +{ } + +QString QmlBuildSettingsWidget::displayName() const +{ return tr("Qml Manager"); } + +void QmlBuildSettingsWidget::init(const QString &buildConfiguration) +{ + m_buildConfiguration = buildConfiguration; + m_pathChooser->setPath(m_project->buildDirectory(buildConfiguration)); +} + +void QmlBuildSettingsWidget::buildDirectoryChanged() +{ + m_project->setValue(m_buildConfiguration, "buildDirectory", m_pathChooser->path()); +} + +//////////////////////////////////////////////////////////////////////////////////// +// QmlProjectFile +//////////////////////////////////////////////////////////////////////////////////// + +QmlProjectFile::QmlProjectFile(QmlProject *parent, QString fileName) + : Core::IFile(parent), + m_project(parent), + m_fileName(fileName) +{ } + +QmlProjectFile::~QmlProjectFile() +{ } + +bool QmlProjectFile::save(const QString &) +{ + return false; +} + +QString QmlProjectFile::fileName() const +{ + return m_fileName; +} + +QString QmlProjectFile::defaultPath() const +{ + return QString(); +} + +QString QmlProjectFile::suggestedFileName() const +{ + return QString(); +} + +QString QmlProjectFile::mimeType() const +{ + return Constants::QMLMIMETYPE; +} + +bool QmlProjectFile::isModified() const +{ + return false; +} + +bool QmlProjectFile::isReadOnly() const +{ + return true; +} + +bool QmlProjectFile::isSaveAsAllowed() const +{ + return false; +} + +void QmlProjectFile::modified(ReloadBehavior *) +{ +} diff --git a/src/plugins/qmlprojectmanager/qmlproject.h b/src/plugins/qmlprojectmanager/qmlproject.h new file mode 100644 index 0000000000000000000000000000000000000000..7429a68c055c08b05868ff4f184d223bef28d0e8 --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlproject.h @@ -0,0 +1,169 @@ +/************************************************************************** +** +** 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 QMLPROJECT_H +#define QMLPROJECT_H + +#include "qmlprojectmanager.h" +#include "qmlprojectnodes.h" + +#include <projectexplorer/project.h> +#include <projectexplorer/projectnodes.h> +#include <projectexplorer/buildstep.h> +#include <coreplugin/ifile.h> + +QT_BEGIN_NAMESPACE +class QPushButton; +class QStringListModel; +QT_END_NAMESPACE + +namespace Core { +namespace Utils { +class PathChooser; +} +} + +namespace QmlProjectManager { +namespace Internal { + +class QmlMakeStep; +class QmlProjectFile; + +class QmlProject : public ProjectExplorer::Project +{ + Q_OBJECT + +public: + QmlProject(Manager *manager, const QString &filename); + virtual ~QmlProject(); + + QString filesFileName() const; + + virtual QString name() const; + virtual Core::IFile *file() const; + virtual ProjectExplorer::IProjectManager *projectManager() const; + + virtual QList<ProjectExplorer::Project *> dependsOn(); + + virtual bool isApplication() const; + + virtual ProjectExplorer::Environment environment(const QString &buildConfiguration) const; + virtual QString buildDirectory(const QString &buildConfiguration) const; + + virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget(); + virtual QList<ProjectExplorer::BuildStepConfigWidget*> subConfigWidgets(); + + virtual void newBuildConfiguration(const QString &buildConfiguration); + virtual QmlProjectNode *rootProjectNode() const; + virtual QStringList files(FilesMode fileMode) const; + + QStringList targets() const; + QmlMakeStep *makeStep() const; + QString buildParser(const QString &buildConfiguration) const; + + enum RefreshOptions { + Files = 0x01, + Configuration = 0x02, + Everything = Files | Configuration + }; + + void refresh(RefreshOptions options); + + QStringList files() const; + +protected: + virtual void saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &writer); + virtual void restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader &reader); + +private: + void parseProject(RefreshOptions options); + QStringList convertToAbsoluteFiles(const QStringList &paths) const; + + Manager *m_manager; + QString m_fileName; + QString m_filesFileName; + QmlProjectFile *m_file; + QString m_projectName; + + QStringList m_files; + + QmlProjectNode *m_rootNode; +}; + +class QmlProjectFile : public Core::IFile +{ + Q_OBJECT + +public: + QmlProjectFile(QmlProject *parent, QString fileName); + virtual ~QmlProjectFile(); + + virtual bool save(const QString &fileName = QString()); + virtual QString fileName() const; + + virtual QString defaultPath() const; + virtual QString suggestedFileName() const; + virtual QString mimeType() const; + + virtual bool isModified() const; + virtual bool isReadOnly() const; + virtual bool isSaveAsAllowed() const; + + virtual void modified(ReloadBehavior *behavior); + +private: + QmlProject *m_project; + QString m_fileName; +}; + +class QmlBuildSettingsWidget : public ProjectExplorer::BuildStepConfigWidget +{ + Q_OBJECT + +public: + QmlBuildSettingsWidget(QmlProject *project); + virtual ~QmlBuildSettingsWidget(); + + virtual QString displayName() const; + + virtual void init(const QString &buildConfiguration); + +private Q_SLOTS: + void buildDirectoryChanged(); + +private: + QmlProject *m_project; + Core::Utils::PathChooser *m_pathChooser; + QString m_buildConfiguration; +}; + +} // namespace Internal +} // namespace QmlProjectManager + +#endif // QMLPROJECT_H diff --git a/src/plugins/qmlprojectmanager/qmlproject.qrc b/src/plugins/qmlprojectmanager/qmlproject.qrc new file mode 100644 index 0000000000000000000000000000000000000000..3a446209bf7f05378d263be9d5a49000db00dc9e --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlproject.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/qmlproject" > + <file>QmlProject.mimetypes.xml</file> + </qresource> +</RCC> diff --git a/src/plugins/qmlprojectmanager/qmlprojectconstants.h b/src/plugins/qmlprojectmanager/qmlprojectconstants.h new file mode 100644 index 0000000000000000000000000000000000000000..55b548daba3e64e9164d7985b24152bae0b6724a --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectconstants.h @@ -0,0 +1,58 @@ +/************************************************************************** +** +** 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 QMLPROJECTCONSTANTS_H +#define QMLPROJECTCONSTANTS_H + +namespace QmlProjectManager { +namespace Constants { + +const char *const PROJECTCONTEXT = "QmlProject.ProjectContext"; +const char *const QMLMIMETYPE = "text/x-qml-project"; // ### FIXME +const char *const MAKESTEP = "QmlProjectManager.MakeStep"; + +// contexts +const char *const C_FILESEDITOR = ".files Editor"; + +// kinds +const char *const PROJECT_KIND = "Qml"; + +const char *const FILES_EDITOR = ".files Editor"; +const char *const FILES_MIMETYPE = "application/vnd.nokia.qt.qml.files"; + +const char *const INCLUDES_EDITOR = ".includes Editor"; +const char *const INCLUDES_MIMETYPE = "application/vnd.nokia.qt.qml.includes"; + +const char *const CONFIG_EDITOR = ".includes Editor"; +const char *const CONFIG_MIMETYPE = "application/vnd.nokia.qt.qml.config"; + +} // namespace Constants +} // namespace QmlProjectManager + +#endif // QMLPROJECTCONSTANTS_H diff --git a/src/plugins/qmlprojectmanager/qmlprojectfileseditor.cpp b/src/plugins/qmlprojectmanager/qmlprojectfileseditor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..afd40d81e1875720923e6c5e6385ac0540b81173 --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectfileseditor.cpp @@ -0,0 +1,189 @@ +/************************************************************************** +** +** 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 "qmlprojectfileseditor.h" +#include "qmlprojectmanager.h" +#include "qmlprojectconstants.h" + +#include <coreplugin/uniqueidmanager.h> +#include <coreplugin/editormanager/editormanager.h> +#include <texteditor/fontsettings.h> +#include <texteditor/texteditoractionhandler.h> +#include <texteditor/texteditorsettings.h> + +using namespace QmlProjectManager; +using namespace QmlProjectManager::Internal; + + +//////////////////////////////////////////////////////////////////////////////////////// +// ProjectFilesFactory +//////////////////////////////////////////////////////////////////////////////////////// + +ProjectFilesFactory::ProjectFilesFactory(Manager *manager, + TextEditor::TextEditorActionHandler *handler) + : Core::IEditorFactory(manager), + m_manager(manager), + m_actionHandler(handler) +{ + m_mimeTypes.append(QLatin1String(Constants::FILES_MIMETYPE)); + m_mimeTypes.append(QLatin1String(Constants::INCLUDES_MIMETYPE)); + m_mimeTypes.append(QLatin1String(Constants::CONFIG_MIMETYPE)); +} + +ProjectFilesFactory::~ProjectFilesFactory() +{ +} + +Manager *ProjectFilesFactory::manager() const +{ + return m_manager; +} + +Core::IEditor *ProjectFilesFactory::createEditor(QWidget *parent) +{ + ProjectFilesEditor *ed = new ProjectFilesEditor(parent, this, m_actionHandler); + TextEditor::TextEditorSettings::instance()->initializeEditor(ed); + return ed->editableInterface(); +} + +QStringList ProjectFilesFactory::mimeTypes() const +{ + return m_mimeTypes; +} + +QString ProjectFilesFactory::kind() const +{ + return QLatin1String(Constants::FILES_EDITOR); +} + +Core::IFile *ProjectFilesFactory::open(const QString &fileName) +{ + Core::EditorManager *editorManager = Core::EditorManager::instance(); + + if (Core::IEditor *editor = editorManager->openEditor(fileName, kind())) + return editor->file(); + + return 0; +} + +//////////////////////////////////////////////////////////////////////////////////////// +// ProjectFilesEditable +//////////////////////////////////////////////////////////////////////////////////////// + +ProjectFilesEditable::ProjectFilesEditable(ProjectFilesEditor *editor) + : TextEditor::BaseTextEditorEditable(editor) +{ + Core::UniqueIDManager *uidm = Core::UniqueIDManager::instance(); + m_context << uidm->uniqueIdentifier(Constants::C_FILESEDITOR); +} + +ProjectFilesEditable::~ProjectFilesEditable() +{ } + +QList<int> ProjectFilesEditable::context() const +{ + return m_context; +} + +const char *ProjectFilesEditable::kind() const +{ + return Constants::FILES_EDITOR; +} + +bool ProjectFilesEditable::duplicateSupported() const +{ + return true; +} + +Core::IEditor *ProjectFilesEditable::duplicate(QWidget *parent) +{ + ProjectFilesEditor *parentEditor = qobject_cast<ProjectFilesEditor *>(editor()); + ProjectFilesEditor *editor = new ProjectFilesEditor(parent, + parentEditor->factory(), + parentEditor->actionHandler()); + TextEditor::TextEditorSettings::instance()->initializeEditor(editor); + return editor->editableInterface(); +} + +//////////////////////////////////////////////////////////////////////////////////////// +// ProjectFilesEditor +//////////////////////////////////////////////////////////////////////////////////////// + +ProjectFilesEditor::ProjectFilesEditor(QWidget *parent, ProjectFilesFactory *factory, + TextEditor::TextEditorActionHandler *handler) + : TextEditor::BaseTextEditor(parent), + m_factory(factory), + m_actionHandler(handler) +{ + Manager *manager = factory->manager(); + ProjectFilesDocument *doc = new ProjectFilesDocument(manager); + setBaseTextDocument(doc); + + handler->setupActions(this); +} + +ProjectFilesEditor::~ProjectFilesEditor() +{ } + +ProjectFilesFactory *ProjectFilesEditor::factory() const +{ + return m_factory; +} + +TextEditor::TextEditorActionHandler *ProjectFilesEditor::actionHandler() const +{ + return m_actionHandler; +} + +TextEditor::BaseTextEditorEditable *ProjectFilesEditor::createEditableInterface() +{ + return new ProjectFilesEditable(this); +} + +//////////////////////////////////////////////////////////////////////////////////////// +// ProjectFilesDocument +//////////////////////////////////////////////////////////////////////////////////////// + +ProjectFilesDocument::ProjectFilesDocument(Manager *manager) + : m_manager(manager) +{ + setMimeType(QLatin1String(Constants::FILES_MIMETYPE)); +} + +ProjectFilesDocument::~ProjectFilesDocument() +{ } + +bool ProjectFilesDocument::save(const QString &name) +{ + if (! BaseTextDocument::save(name)) + return false; + + m_manager->notifyChanged(name); + return true; +} diff --git a/src/plugins/qmlprojectmanager/qmlprojectfileseditor.h b/src/plugins/qmlprojectmanager/qmlprojectfileseditor.h new file mode 100644 index 0000000000000000000000000000000000000000..4b189a379b37a1661159e756e7d48de35d8f46a5 --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectfileseditor.h @@ -0,0 +1,123 @@ +/************************************************************************** +** +** 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 QMLPROJECTFILESEDITOR_H +#define QMLPROJECTFILESEDITOR_H + +#include <texteditor/basetexteditor.h> +#include <texteditor/basetextdocument.h> + +#include <coreplugin/editormanager/ieditorfactory.h> + +namespace QmlProjectManager { +namespace Internal { + +class Manager; +class ProjectFilesEditable; +class ProjectFilesEditor; +class ProjectFilesDocument; +class ProjectFilesFactory; + +class ProjectFilesFactory: public Core::IEditorFactory +{ + Q_OBJECT + +public: + ProjectFilesFactory(Manager *manager, TextEditor::TextEditorActionHandler *handler); + virtual ~ProjectFilesFactory(); + + Manager *manager() const; + + virtual Core::IEditor *createEditor(QWidget *parent); + + virtual QStringList mimeTypes() const; + virtual QString kind() const; + virtual Core::IFile *open(const QString &fileName); + +private: + Manager *m_manager; + TextEditor::TextEditorActionHandler *m_actionHandler; + QStringList m_mimeTypes; +}; + +class ProjectFilesEditable: public TextEditor::BaseTextEditorEditable +{ + Q_OBJECT + +public: + ProjectFilesEditable(ProjectFilesEditor *editor); + virtual ~ProjectFilesEditable(); + + virtual QList<int> context() const; + virtual const char *kind() const; + + virtual bool duplicateSupported() const; + virtual Core::IEditor *duplicate(QWidget *parent); + +private: + QList<int> m_context; +}; + +class ProjectFilesEditor: public TextEditor::BaseTextEditor +{ + Q_OBJECT + +public: + ProjectFilesEditor(QWidget *parent, ProjectFilesFactory *factory, + TextEditor::TextEditorActionHandler *handler); + virtual ~ProjectFilesEditor(); + + ProjectFilesFactory *factory() const; + TextEditor::TextEditorActionHandler *actionHandler() const; + + virtual TextEditor::BaseTextEditorEditable *createEditableInterface(); + +private: + ProjectFilesFactory *m_factory; + TextEditor::TextEditorActionHandler *m_actionHandler; +}; + +class ProjectFilesDocument: public TextEditor::BaseTextDocument +{ + Q_OBJECT + +public: + ProjectFilesDocument(Manager *manager); + virtual ~ProjectFilesDocument(); + + virtual bool save(const QString &name); + +private: + Manager *m_manager; +}; + +} // end of namespace Internal +} // end of namespace QmlProjectManager + +#endif // QMLPROJECTFILESEDITOR_H diff --git a/src/plugins/qmlprojectmanager/qmlprojectmanager.cpp b/src/plugins/qmlprojectmanager/qmlprojectmanager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..02facd1dc5c9dfd275b75bf949064ceda8ebbb06 --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectmanager.cpp @@ -0,0 +1,86 @@ +/************************************************************************** +** +** 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 "qmlprojectmanager.h" +#include "qmlprojectconstants.h" +#include "qmlproject.h" + +#include <coreplugin/icore.h> +#include <coreplugin/uniqueidmanager.h> +#include <projectexplorer/projectexplorerconstants.h> + +#include <QtDebug> + +using namespace QmlProjectManager::Internal; + +Manager::Manager() +{ + Core::UniqueIDManager *uidm = Core::UniqueIDManager::instance(); + m_projectContext = uidm->uniqueIdentifier(QmlProjectManager::Constants::PROJECTCONTEXT); + m_projectLanguage = uidm->uniqueIdentifier(ProjectExplorer::Constants::LANG_CXX); +} + +Manager::~Manager() +{ } + +int Manager::projectContext() const +{ return m_projectContext; } + +int Manager::projectLanguage() const +{ return m_projectLanguage; } + +QString Manager::mimeType() const +{ return QLatin1String(Constants::QMLMIMETYPE); } + +ProjectExplorer::Project *Manager::openProject(const QString &fileName) +{ + QFileInfo fileInfo(fileName); + + if (fileInfo.isFile()) { + QmlProject *project = new QmlProject(this, fileName); + return project; + } + + return 0; +} + +void Manager::registerProject(QmlProject *project) +{ m_projects.append(project); } + +void Manager::unregisterProject(QmlProject *project) +{ m_projects.removeAll(project); } + +void Manager::notifyChanged(const QString &fileName) +{ + foreach (QmlProject *project, m_projects) { + if (fileName == project->filesFileName()) { + project->refresh(QmlProject::Files); + } + } +} diff --git a/src/plugins/qmlprojectmanager/qmlprojectmanager.h b/src/plugins/qmlprojectmanager/qmlprojectmanager.h new file mode 100644 index 0000000000000000000000000000000000000000..66a4271b0a5ed3f974834ce220b511ca8e02b6a1 --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectmanager.h @@ -0,0 +1,68 @@ +/************************************************************************** +** +** 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 QMLPROJECTMANAGER_H +#define QMLPROJECTMANAGER_H + +#include <projectexplorer/iprojectmanager.h> + +namespace QmlProjectManager { +namespace Internal { + +class QmlProject; + +class Manager: public ProjectExplorer::IProjectManager +{ + Q_OBJECT + +public: + Manager(); + virtual ~Manager(); + + virtual int projectContext() const; + virtual int projectLanguage() const; + + virtual QString mimeType() const; + virtual ProjectExplorer::Project *openProject(const QString &fileName); + + void notifyChanged(const QString &fileName); + + void registerProject(QmlProject *project); + void unregisterProject(QmlProject *project); + +private: + int m_projectContext; + int m_projectLanguage; + QList<QmlProject *> m_projects; +}; + +} // namespace Internal +} // namespace QmlProjectManager + +#endif // QMLPROJECTMANAGER_H diff --git a/src/plugins/qmlprojectmanager/qmlprojectmanager.pro b/src/plugins/qmlprojectmanager/qmlprojectmanager.pro new file mode 100644 index 0000000000000000000000000000000000000000..f9804420a759dc6fb4b99c4c20958cb21a5c958f --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectmanager.pro @@ -0,0 +1,20 @@ +TEMPLATE = lib +TARGET = QmlProjectManager +include(../../qworkbenchplugin.pri) +include(qmlprojectmanager_dependencies.pri) +HEADERS = qmlproject.h \ + qmlprojectplugin.h \ + qmlprojectmanager.h \ + qmlprojectconstants.h \ + qmlprojectnodes.h \ + qmlprojectwizard.h \ + qmlprojectfileseditor.h +SOURCES = qmlproject.cpp \ + qmlprojectplugin.cpp \ + qmlprojectmanager.cpp \ + qmlprojectnodes.cpp \ + qmlprojectwizard.cpp \ + qmlprojectfileseditor.cpp +RESOURCES += qmlproject.qrc + +OTHER_FILES += QmlProjectManager.pluginspec diff --git a/src/plugins/qmlprojectmanager/qmlprojectmanager_dependencies.pri b/src/plugins/qmlprojectmanager/qmlprojectmanager_dependencies.pri new file mode 100644 index 0000000000000000000000000000000000000000..191c4a96e9b40bd8f24770605b6bbf118f2695c4 --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectmanager_dependencies.pri @@ -0,0 +1,2 @@ +include(../../plugins/projectexplorer/projectexplorer.pri) +include(../../plugins/texteditor/texteditor.pri) diff --git a/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp b/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1943276502654bb8f480000e54ac09bd6bc4b3c4 --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp @@ -0,0 +1,196 @@ +/************************************************************************** +** +** 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 "qmlprojectnodes.h" +#include "qmlproject.h" + +#include <coreplugin/ifile.h> +#include <projectexplorer/projectexplorer.h> + +#include <QFileInfo> + +using namespace QmlProjectManager; +using namespace QmlProjectManager::Internal; + +QmlProjectNode::QmlProjectNode(QmlProject *project, Core::IFile *projectFile) + : ProjectExplorer::ProjectNode(QFileInfo(projectFile->fileName()).absolutePath()), + m_project(project), + m_projectFile(projectFile) +{ + setFolderName(QFileInfo(projectFile->fileName()).completeBaseName()); +} + +QmlProjectNode::~QmlProjectNode() +{ } + +Core::IFile *QmlProjectNode::projectFile() const +{ return m_projectFile; } + +QString QmlProjectNode::projectFilePath() const +{ return m_projectFile->fileName(); } + +void QmlProjectNode::refresh() +{ + using namespace ProjectExplorer; + + // remove the existing nodes. + removeFileNodes(fileNodes(), this); + removeFolderNodes(subFolderNodes(), this); + + //ProjectExplorerPlugin::instance()->setCurrentNode(0); // ### remove me + + FileNode *projectFilesNode = new FileNode(m_project->filesFileName(), + ProjectFileType, + /* generated = */ false); + + QStringList files = m_project->files(); + files.removeAll(m_project->filesFileName()); + + addFileNodes(QList<FileNode *>() + << projectFilesNode, + this); + + QStringList filePaths; + QHash<QString, QStringList> filesInPath; + + foreach (const QString &absoluteFileName, files) { + QFileInfo fileInfo(absoluteFileName); + const QString absoluteFilePath = fileInfo.path(); + + if (! absoluteFilePath.startsWith(path())) + continue; // `file' is not part of the project. + + const QString relativeFilePath = absoluteFilePath.mid(path().length() + 1); + + if (! filePaths.contains(relativeFilePath)) + filePaths.append(relativeFilePath); + + filesInPath[relativeFilePath].append(absoluteFileName); + } + + foreach (const QString &filePath, filePaths) { + FolderNode *folder = findOrCreateFolderByName(filePath); + + QList<FileNode *> fileNodes; + foreach (const QString &file, filesInPath.value(filePath)) { + FileType fileType = SourceType; // ### FIXME + FileNode *fileNode = new FileNode(file, fileType, /*generated = */ false); + fileNodes.append(fileNode); + } + + addFileNodes(fileNodes, folder); + } + + m_folderByName.clear(); +} + +ProjectExplorer::FolderNode *QmlProjectNode::findOrCreateFolderByName(const QStringList &components, int end) +{ + if (! end) + return 0; + + QString folderName; + for (int i = 0; i < end; ++i) { + folderName.append(components.at(i)); + folderName += QLatin1Char('/'); // ### FIXME + } + + const QString component = components.at(end - 1); + + if (component.isEmpty()) + return this; + + else if (FolderNode *folder = m_folderByName.value(folderName)) + return folder; + + FolderNode *folder = new FolderNode(component); + m_folderByName.insert(folderName, folder); + + FolderNode *parent = findOrCreateFolderByName(components, end - 1); + if (! parent) + parent = this; + addFolderNodes(QList<FolderNode*>() << folder, parent); + + return folder; +} + +ProjectExplorer::FolderNode *QmlProjectNode::findOrCreateFolderByName(const QString &filePath) +{ + QStringList components = filePath.split(QLatin1Char('/')); + return findOrCreateFolderByName(components, components.length()); +} + +bool QmlProjectNode::hasTargets() const +{ + return true; +} + +QList<ProjectExplorer::ProjectNode::ProjectAction> QmlProjectNode::supportedActions() const +{ + return QList<ProjectAction>(); +} + +bool QmlProjectNode::addSubProjects(const QStringList &proFilePaths) +{ + Q_UNUSED(proFilePaths); + return false; +} + +bool QmlProjectNode::removeSubProjects(const QStringList &proFilePaths) +{ + Q_UNUSED(proFilePaths); + return false; +} + +bool QmlProjectNode::addFiles(const ProjectExplorer::FileType fileType, + const QStringList &filePaths, QStringList *notAdded) +{ + Q_UNUSED(fileType); + Q_UNUSED(filePaths); + Q_UNUSED(notAdded); + return false; +} + +bool QmlProjectNode::removeFiles(const ProjectExplorer::FileType fileType, + const QStringList &filePaths, QStringList *notRemoved) +{ + Q_UNUSED(fileType); + Q_UNUSED(filePaths); + Q_UNUSED(notRemoved); + return false; +} + +bool QmlProjectNode::renameFile(const ProjectExplorer::FileType fileType, + const QString &filePath, const QString &newFilePath) +{ + Q_UNUSED(fileType); + Q_UNUSED(filePath); + Q_UNUSED(newFilePath); + return false; +} diff --git a/src/plugins/qmlprojectmanager/qmlprojectnodes.h b/src/plugins/qmlprojectmanager/qmlprojectnodes.h new file mode 100644 index 0000000000000000000000000000000000000000..c5f3851cc75a4c905e606eec13a0faaec9191f11 --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectnodes.h @@ -0,0 +1,91 @@ +/************************************************************************** +** +** 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 QMLPROJECTNODE_H +#define QMLPROJECTNODE_H + +#include <projectexplorer/projectnodes.h> + +#include <QStringList> +#include <QHash> + +namespace Core { +class IFile; +} + +namespace QmlProjectManager { +namespace Internal { + +class QmlProject; + +class QmlProjectNode : public ProjectExplorer::ProjectNode +{ +public: + QmlProjectNode(QmlProject *project, Core::IFile *projectFile); + virtual ~QmlProjectNode(); + + Core::IFile *projectFile() const; + QString projectFilePath() const; + + virtual bool hasTargets() const; + + virtual QList<ProjectExplorer::ProjectNode::ProjectAction> supportedActions() const; + + virtual bool addSubProjects(const QStringList &proFilePaths); + virtual bool removeSubProjects(const QStringList &proFilePaths); + + virtual bool addFiles(const ProjectExplorer::FileType fileType, + const QStringList &filePaths, + QStringList *notAdded = 0); + + virtual bool removeFiles(const ProjectExplorer::FileType fileType, + const QStringList &filePaths, + QStringList *notRemoved = 0); + + virtual bool renameFile(const ProjectExplorer::FileType fileType, + const QString &filePath, + const QString &newFilePath); + + + void refresh(); + +private: + FolderNode *findOrCreateFolderByName(const QString &filePath); + FolderNode *findOrCreateFolderByName(const QStringList &components, int end); + +private: + QmlProject *m_project; + Core::IFile *m_projectFile; + QHash<QString, FolderNode *> m_folderByName; +}; + +} // namespace Internal +} // namespace QmlProjectManager + +#endif // QMLPROJECTNODE_H diff --git a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1f4b0cbc001f8f77f7b036e264384bcfa6334b53 --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp @@ -0,0 +1,86 @@ +/************************************************************************** +** +** 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 "qmlprojectplugin.h" +#include "qmlprojectmanager.h" +#include "qmlprojectwizard.h" +#include "qmlprojectconstants.h" +#include "qmlprojectfileseditor.h" + +#include <coreplugin/icore.h> +#include <coreplugin/mimedatabase.h> + +#include <texteditor/texteditoractionhandler.h> + +#include <QtCore/QtPlugin> +#include <QtCore/QDebug> + +using namespace QmlProjectManager; +using namespace QmlProjectManager::Internal; + +QmlProjectPlugin::QmlProjectPlugin() + : m_projectFilesEditorFactory(0) +{ } + +QmlProjectPlugin::~QmlProjectPlugin() +{ + removeObject(m_projectFilesEditorFactory); + delete m_projectFilesEditorFactory; +} + +bool QmlProjectPlugin::initialize(const QStringList &, QString *errorMessage) +{ + using namespace Core; + + ICore *core = ICore::instance(); + Core::MimeDatabase *mimeDB = core->mimeDatabase(); + + const QLatin1String mimetypesXml(":qmlproject/QmlProject.mimetypes.xml"); + + if (! mimeDB->addMimeTypes(mimetypesXml, errorMessage)) + return false; + + Manager *manager = new Manager; + + TextEditor::TextEditorActionHandler *actionHandler = + new TextEditor::TextEditorActionHandler(Constants::C_FILESEDITOR); + + m_projectFilesEditorFactory = new ProjectFilesFactory(manager, actionHandler); + addObject(m_projectFilesEditorFactory); + + addAutoReleasedObject(manager); + addAutoReleasedObject(new QmlProjectWizard); + + return true; +} + +void QmlProjectPlugin::extensionsInitialized() +{ } + +Q_EXPORT_PLUGIN(QmlProjectPlugin) diff --git a/src/plugins/qmlprojectmanager/qmlprojectplugin.h b/src/plugins/qmlprojectmanager/qmlprojectplugin.h new file mode 100644 index 0000000000000000000000000000000000000000..8590bf53c52644905eb24def8537d8ba2d5d37f3 --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectplugin.h @@ -0,0 +1,60 @@ +/************************************************************************** +** +** 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 QMLPROJECTPLUGIN_H +#define QMLPROJECTPLUGIN_H + +#include <extensionsystem/iplugin.h> + +#include <QtCore/QObject> + +namespace QmlProjectManager { +namespace Internal { + +class ProjectFilesFactory; + +class QmlProjectPlugin: public ExtensionSystem::IPlugin +{ + Q_OBJECT + +public: + QmlProjectPlugin(); + ~QmlProjectPlugin(); + + virtual bool initialize(const QStringList &arguments, QString *errorString); + virtual void extensionsInitialized(); + +private: + ProjectFilesFactory *m_projectFilesEditorFactory; +}; + +} // namespace Internal +} // namespace QmlProject + +#endif // QMLPROJECTPLUGIN_H diff --git a/src/plugins/qmlprojectmanager/qmlprojectwizard.cpp b/src/plugins/qmlprojectmanager/qmlprojectwizard.cpp new file mode 100644 index 0000000000000000000000000000000000000000..68736377fc381ea97d45aed4de9f15935dbd109c --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectwizard.cpp @@ -0,0 +1,355 @@ +/************************************************************************** +** +** 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 "qmlprojectwizard.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 <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 + + +////////////////////////////////////////////////////////////////////////////// +// QmlProjectWizardDialog +////////////////////////////////////////////////////////////////////////////// + + +QmlProjectWizardDialog::QmlProjectWizardDialog(QWidget *parent) + : QWizard(parent) +{ + setWindowTitle(tr("Import of QML Project")); + + // first page + m_firstPage = new FileWizardPage; + m_firstPage->setTitle(tr("Qml Project")); + m_firstPage->setNameLabel(tr("Project name:")); + m_firstPage->setPathLabel(tr("Location:")); + + addPage(m_firstPage); + +#if 0 + // second page + QWizardPage *secondPage = new QWizardPage; + secondPage->setTitle(tr("Second Page Title")); + + QFormLayout *secondPageLayout = new QFormLayout(secondPage); + + m_dirView = new QTreeView; + m_dirModel = new DirModel(this); + m_dirView->setModel(_dirModel); + + Core::ICore *core = Core::ICore::instance(); + Core::MimeDatabase *mimeDatabase = core->mimeDatabase(); + + const QStringList suffixes = mimeDatabase->suffixes(); + + QStringList nameFilters; + foreach (const QString &suffix, suffixes) { + QString nameFilter; + nameFilter.append(QLatin1String("*.")); + nameFilter.append(suffix); + nameFilters.append(nameFilter); + } + + m_filesView = new QListView; + m_filesModel = new QDirModel(this); + m_filesModel->setNameFilters(nameFilters); + m_filesModel->setFilter(QDir::Files); + + connect(_dirView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), + this, SLOT(updateFilesView(QModelIndex,QModelIndex))); + + secondPageLayout->addRow(_dirView); + secondPageLayout->addRow(_filesView); + + m_secondPageId = addPage(secondPage); +#endif +} + +QmlProjectWizardDialog::~QmlProjectWizardDialog() +{ } + +QString QmlProjectWizardDialog::path() const +{ + return m_firstPage->path(); +} + +void QmlProjectWizardDialog::setPath(const QString &path) +{ + m_firstPage->setPath(path); +} + +QString QmlProjectWizardDialog::projectName() const +{ + return m_firstPage->name(); +} + +void QmlProjectWizardDialog::updateFilesView(const QModelIndex ¤t, + 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 QmlProjectWizardDialog::initializePage(int id) +{ + Q_UNUSED(id) +#if 0 + if (id == m_secondPageId) { + using namespace Core::Utils; + + const QString projectPath = m_pathChooser->path(); + + QDirModel *dirModel = qobject_cast<QDirModel *>(_dirView->model()); + m_dirView->setRootIndex(dirModel->index(projectPath)); + } +#endif +} + +bool QmlProjectWizardDialog::validateCurrentPage() +{ + using namespace Core::Utils; + +#if 0 + if (currentId() == m_secondPageId) { + return true; + } +#endif + + return QWizard::validateCurrentPage(); +} + +QmlProjectWizard::QmlProjectWizard() + : Core::BaseFileWizard(parameters()) +{ } + +QmlProjectWizard::~QmlProjectWizard() +{ } + +Core::BaseFileWizardParameters QmlProjectWizard::parameters() +{ + static Core::BaseFileWizardParameters parameters(ProjectWizard); + parameters.setIcon(QIcon(":/wizards/images/console.png")); + parameters.setName(tr("Import of QML Project")); + parameters.setDescription(tr("Creates a QML project.")); + parameters.setCategory(QLatin1String("Projects")); + parameters.setTrCategory(tr("Projects")); + return parameters; +} + +QWizard *QmlProjectWizard::createWizardDialog(QWidget *parent, + const QString &defaultPath, + const WizardPageList &extensionPages) const +{ + QmlProjectWizardDialog *wizard = new QmlProjectWizardDialog(parent); + setupWizard(wizard); + + wizard->setPath(defaultPath); + + foreach (QWizardPage *p, extensionPages) + wizard->addPage(p); + + return wizard; +} + +void QmlProjectWizard::getFileList(const QDir &dir, const QString &projectRoot, + const QStringList &suffixes, + QStringList *files, QStringList *paths) const +{ + const QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | + QDir::Dirs | + QDir::NoDotAndDotDot | + QDir::NoSymLinks); + + foreach (const QFileInfo &fileInfo, fileInfoList) { + QString filePath = fileInfo.absoluteFilePath(); + filePath = filePath.mid(projectRoot.length() + 1); + + if (fileInfo.isDir() && isValidDir(fileInfo)) { + getFileList(QDir(fileInfo.absoluteFilePath()), projectRoot, + suffixes, files, paths); + + if (! paths->contains(filePath)) + paths->append(filePath); + } + + else if (suffixes.contains(fileInfo.suffix())) + files->append(filePath); + } +} + +bool QmlProjectWizard::isValidDir(const QFileInfo &fileInfo) const +{ + const QString fileName = fileInfo.fileName(); + const QString suffix = fileInfo.suffix(); + + if (fileName.startsWith(QLatin1Char('.'))) + return false; + + else if (fileName == QLatin1String("CVS")) + return false; + + // ### user include/exclude + + return true; +} + +Core::GeneratedFiles QmlProjectWizard::generateFiles(const QWizard *w, + QString *errorMessage) const +{ + Q_UNUSED(errorMessage) + + const QmlProjectWizardDialog *wizard = qobject_cast<const QmlProjectWizardDialog *>(w); + const QString projectPath = wizard->path(); + const QDir dir(projectPath); + const QString projectName = wizard->projectName(); + const QString creatorFileName = QFileInfo(dir, projectName + QLatin1String(".qmlproject")).absoluteFilePath(); + const QString filesFileName = QFileInfo(dir, projectName + QLatin1String(".files")).absoluteFilePath(); + const QString includesFileName = QFileInfo(dir, projectName + QLatin1String(".includes")).absoluteFilePath(); + const QString configFileName = QFileInfo(dir, projectName + QLatin1String(".config")).absoluteFilePath(); + + Core::ICore *core = Core::ICore::instance(); + Core::MimeDatabase *mimeDatabase = core->mimeDatabase(); + + const QStringList suffixes = mimeDatabase->suffixes(); + + QStringList sources, paths; + getFileList(dir, projectPath, suffixes, &sources, &paths); + + Core::GeneratedFile generatedCreatorFile(creatorFileName); + generatedCreatorFile.setContents(QLatin1String("[General]\n")); + + Core::GeneratedFile generatedFilesFile(filesFileName); + generatedFilesFile.setContents(sources.join(QLatin1String("\n"))); + + Core::GeneratedFiles files; + files.append(generatedFilesFile); + files.append(generatedCreatorFile); + + return files; +} + +bool QmlProjectWizard::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/qmlprojectwizard.h b/src/plugins/qmlprojectmanager/qmlprojectwizard.h new file mode 100644 index 0000000000000000000000000000000000000000..a49cc5d4cb0682c73bdc58d31b7d9bedb778e89b --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectwizard.h @@ -0,0 +1,122 @@ +/************************************************************************** +** +** 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 QMLPROJECTWIZARD_H +#define QMLPROJECTWIZARD_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; + +} // namespace Utils +} // namespace Core + +namespace QmlProjectManager { +namespace Internal { + +class QmlProjectWizardDialog : public QWizard +{ + Q_OBJECT + +public: + QmlProjectWizardDialog(QWidget *parent = 0); + virtual ~QmlProjectWizardDialog(); + + QString path() const; + void setPath(const QString &path); + + QString projectName() const; + +private Q_SLOTS: + void updateFilesView(const QModelIndex ¤t, + const QModelIndex &previous); + +protected: + virtual void initializePage(int id); + virtual bool validateCurrentPage(); + +private: + int m_secondPageId; + + Core::Utils::FileWizardPage *m_firstPage; + + QTreeView *m_dirView; + QDirModel *m_dirModel; + + QListView *m_filesView; + QDirModel *m_filesModel; +}; + +class QmlProjectWizard : public Core::BaseFileWizard +{ + Q_OBJECT + +public: + QmlProjectWizard(); + virtual ~QmlProjectWizard(); + + 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); + + bool isValidDir(const QFileInfo &fileInfo) const; + + void getFileList(const QDir &dir, const QString &projectRoot, + const QStringList &suffixes, + QStringList *files, + QStringList *paths) const; +}; + +} // end of namespace Internal +} // end of namespace QmlProjectManager + +#endif // QMLPROJECTWIZARD_H