aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBojan Petrovic <bojan85@gmail.com>2012-05-03 23:15:18 +0200
committerOswald Buddenhagen <oswald.buddenhagen@digia.com>2014-03-11 19:54:51 +0100
commitafb07299882ef935d47dc4d6be82dc566f6a5818 (patch)
tree675ee5539d563b68104cae6d685a79e95ca19f89
parent52bf71fbdff62bdcd0c67e0a5edc45b695b3c519 (diff)
Initial commit.
-rw-r--r--src/plugins/plugins.pro1
-rw-r--r--src/plugins/vcprojectmanager/VcProject.mimetypes.xml8
-rw-r--r--src/plugins/vcprojectmanager/VcProjectManager.pluginspec.in10
-rw-r--r--src/plugins/vcprojectmanager/vcproject.cpp96
-rw-r--r--src/plugins/vcprojectmanager/vcproject.h55
-rw-r--r--src/plugins/vcprojectmanager/vcproject.qrc5
-rw-r--r--src/plugins/vcprojectmanager/vcprojectfile.cpp86
-rw-r--r--src/plugins/vcprojectmanager/vcprojectfile.h42
-rw-r--r--src/plugins/vcprojectmanager/vcprojectmanager.cpp104
-rw-r--r--src/plugins/vcprojectmanager/vcprojectmanager.h36
-rw-r--r--src/plugins/vcprojectmanager/vcprojectmanager.pro22
-rw-r--r--src/plugins/vcprojectmanager/vcprojectmanager_dependencies.pri4
-rw-r--r--src/plugins/vcprojectmanager/vcprojectmanager_global.h13
-rw-r--r--src/plugins/vcprojectmanager/vcprojectmanagerconstants.h22
-rw-r--r--src/plugins/vcprojectmanager/vcprojectmanagerplugin.cpp74
-rw-r--r--src/plugins/vcprojectmanager/vcprojectmanagerplugin.h28
-rw-r--r--src/plugins/vcprojectmanager/vcprojectnodes.cpp182
-rw-r--r--src/plugins/vcprojectmanager/vcprojectnodes.h56
-rw-r--r--src/plugins/vcprojectmanager/vcprojectreader.cpp309
-rw-r--r--src/plugins/vcprojectmanager/vcprojectreader.h92
20 files changed, 1245 insertions, 0 deletions
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index 8d377df12b..5dbf29d053 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -26,6 +26,7 @@ SUBDIRS = \
cpaster \
cmakeprojectmanager \
autotoolsprojectmanager \
+ vcprojectmanager \
fakevim \
designer \
resourceeditor \
diff --git a/src/plugins/vcprojectmanager/VcProject.mimetypes.xml b/src/plugins/vcprojectmanager/VcProject.mimetypes.xml
new file mode 100644
index 0000000000..5fa810584a
--- /dev/null
+++ b/src/plugins/vcprojectmanager/VcProject.mimetypes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
+ <mime-type type="text/x-vc-project">
+ <sub-class-of type="text/plain"/>
+ <comment>Vc Project file</comment>
+ <glob pattern="*.vcproj"/>
+ </mime-type>
+</mime-info>
diff --git a/src/plugins/vcprojectmanager/VcProjectManager.pluginspec.in b/src/plugins/vcprojectmanager/VcProjectManager.pluginspec.in
new file mode 100644
index 0000000000..7bf9bfb1e5
--- /dev/null
+++ b/src/plugins/vcprojectmanager/VcProjectManager.pluginspec.in
@@ -0,0 +1,10 @@
+<plugin name=\"VcProjectManager\" version=\"0.0.1\" compatVersion=\"0.0.1\">
+ <vendor>BojanPetrovic</vendor>
+ <copyright>(C) Bojan Petrovic</copyright>
+ <license>Public domain</license>
+ <description>Opens .vcproj</description>
+ <url>http://www.mycompany.com</url>
+ <category>Build Systems</category>
+ $$dependencyList
+</plugin>
+
diff --git a/src/plugins/vcprojectmanager/vcproject.cpp b/src/plugins/vcprojectmanager/vcproject.cpp
new file mode 100644
index 0000000000..0f972a0b41
--- /dev/null
+++ b/src/plugins/vcprojectmanager/vcproject.cpp
@@ -0,0 +1,96 @@
+#include "vcproject.h"
+
+#include "vcprojectfile.h"
+#include "vcprojectnodes.h"
+#include "vcprojectmanager.h"
+#include "vcprojectmanagerconstants.h"
+#include "vcprojectreader.h"
+
+#include <coreplugin/icontext.h>
+#include <coreplugin/icore.h>
+#include <projectexplorer/projectexplorerconstants.h>
+#include <utils/filesystemwatcher.h>
+
+#include <QFileInfo>
+#include <QFileSystemWatcher>
+
+using namespace ProjectExplorer;
+
+namespace VcProjectManager {
+namespace Internal {
+
+VcProject::VcProject(VcManager *projectManager, const QString &projectFilePath)
+ : m_projectManager(projectManager)
+ , m_projectFile(new VcProjectFile(projectFilePath))
+ , m_rootNode(new VcProjectNode(projectFilePath))
+ , m_projectFileWatcher(new QFileSystemWatcher(this))
+{
+ setProjectContext(Core::Context(Constants::VC_PROJECT_CONTEXT));
+ setProjectLanguage(Core::Context(ProjectExplorer::Constants::LANG_CXX));
+
+ reparse();
+
+ m_projectFileWatcher->addPath(projectFilePath);
+ connect(m_projectFileWatcher, SIGNAL(fileChanged(QString)), this, SLOT(reparse()));
+}
+
+QString VcProject::displayName() const
+{
+ return m_rootNode->displayName();
+}
+
+Core::Id VcProject::id() const
+{
+ return Core::Id(Constants::VC_PROJECT_ID);
+}
+
+Core::IDocument *VcProject::document() const
+{
+ return m_projectFile;
+}
+
+IProjectManager *VcProject::projectManager() const
+{
+ return m_projectManager;
+}
+
+ProjectNode *VcProject::rootProjectNode() const
+{
+ return m_rootNode;
+}
+
+QStringList VcProject::files(Project::FilesMode fileMode) const
+{
+ Q_UNUSED(fileMode);
+ // TODO: respect the mode
+ return m_rootNode->files();
+}
+
+void VcProject::reparse()
+{
+ qDebug() << "reparse";
+
+ QString projectFilePath = m_projectFile->filePath();
+ VcProjectInfo::Project *projInfo = reader.parse(projectFilePath);
+
+ // If file saving is done by replacing the file with the new file
+ // watcher will loose it from its list
+ if (m_projectFileWatcher->files().isEmpty())
+ m_projectFileWatcher->addPath(projectFilePath);
+
+ if (!projInfo) {
+ m_rootNode->setDisplayName(QFileInfo(projectFilePath).fileName());
+ m_rootNode->refresh(0);
+ } else {
+ m_rootNode->setDisplayName(projInfo->displayName);
+ m_rootNode->refresh(projInfo->files);
+ }
+
+ delete projInfo;
+
+ // TODO: can we (and is is important to) detect when the list really changed?
+ emit fileListChanged();
+}
+
+} // namespace Internal
+} // namespace VcProjectManager
diff --git a/src/plugins/vcprojectmanager/vcproject.h b/src/plugins/vcprojectmanager/vcproject.h
new file mode 100644
index 0000000000..3540465bbc
--- /dev/null
+++ b/src/plugins/vcprojectmanager/vcproject.h
@@ -0,0 +1,55 @@
+#ifndef VCPROJECTMANAGER_INTERNAL_VCPROJECT_H
+#define VCPROJECTMANAGER_INTERNAL_VCPROJECT_H
+
+#include "vcprojectreader.h"
+
+#include <projectexplorer/project.h>
+
+class QFileSystemWatcher;
+
+namespace VcProjectManager {
+namespace Internal {
+
+class VcProjectFile;
+class VcProjectNode;
+class VcManager;
+
+class VcProject : public ProjectExplorer::Project
+{
+ Q_OBJECT
+
+public:
+ VcProject(VcManager *projectManager, const QString &projectFilePath);
+
+ QString displayName() const;
+ Core::Id id() const;
+ Core::IDocument *document() const;
+ ProjectExplorer::IProjectManager *projectManager() const;
+ ProjectExplorer::ProjectNode *rootProjectNode() const;
+ QStringList files(FilesMode fileMode) const;
+
+public slots:
+ void reparse();
+
+// virtual QList<BuildConfigWidget*> subConfigWidgets();
+// virtual QString generatedUiHeader(const QString &formFile) const;
+// static QString makeUnique(const QString &preferedName, const QStringList &usedNames);
+// virtual QVariantMap toMap() const;
+// virtual Core::Context projectContext() const;
+// virtual Core::Context projectLanguage() const;
+// virtual bool needsConfiguration() const;
+// virtual void configureAsExampleProject(const QStringList &platforms);
+
+private:
+ VcManager *m_projectManager;
+ VcProjectFile *m_projectFile;
+ VcProjectNode *m_rootNode;
+ VcProjectReader reader;
+ QString m_name;
+ QFileSystemWatcher *m_projectFileWatcher;
+};
+
+} // namespace Internal
+} // namespace VcProjectManager
+
+#endif // VCPROJECTMANAGER_INTERNAL_VCPROJECT_H
diff --git a/src/plugins/vcprojectmanager/vcproject.qrc b/src/plugins/vcprojectmanager/vcproject.qrc
new file mode 100644
index 0000000000..1ecd03cc2c
--- /dev/null
+++ b/src/plugins/vcprojectmanager/vcproject.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/vcproject">
+ <file>VcProject.mimetypes.xml</file>
+ </qresource>
+</RCC>
diff --git a/src/plugins/vcprojectmanager/vcprojectfile.cpp b/src/plugins/vcprojectmanager/vcprojectfile.cpp
new file mode 100644
index 0000000000..2fa49a8695
--- /dev/null
+++ b/src/plugins/vcprojectmanager/vcprojectfile.cpp
@@ -0,0 +1,86 @@
+#include "vcprojectfile.h"
+
+#include "vcprojectmanagerconstants.h"
+
+#include <QFileInfo>
+
+namespace VcProjectManager {
+namespace Internal {
+
+VcProjectFile::VcProjectFile(const QString &filePath)
+ : m_filePath(filePath)
+ , m_path(QFileInfo(filePath).path())
+{
+}
+
+bool VcProjectFile::save(QString *errorString, const QString &fileName, bool autoSave)
+{
+ Q_UNUSED(errorString)
+ Q_UNUSED(fileName)
+ Q_UNUSED(autoSave)
+ // TODO: obvious
+ return false;
+}
+
+QString VcProjectFile::fileName() const
+{
+ return QFileInfo(m_filePath).fileName();
+}
+
+QString VcProjectFile::defaultPath() const
+{
+ // TODO: what's this for?
+ return QString();
+}
+
+QString VcProjectFile::suggestedFileName() const
+{
+ // TODO: what's this for?
+ return QString();
+}
+
+QString VcProjectFile::mimeType() const
+{
+ return Constants::VCPROJ_MIMETYPE;
+}
+
+bool VcProjectFile::isModified() const
+{
+ // TODO: obvious
+ return false;
+}
+
+bool VcProjectFile::isSaveAsAllowed() const
+{
+ return false;
+}
+
+bool VcProjectFile::reload(QString *errorString, Core::IDocument::ReloadFlag flag, Core::IDocument::ChangeType type)
+{
+ Q_UNUSED(errorString);
+ Q_UNUSED(flag);
+ Q_UNUSED(type);
+
+ // TODO: what's this for?
+ return false;
+}
+
+void VcProjectFile::rename(const QString &newName)
+{
+ Q_UNUSED(newName);
+
+ // TODO: obvious
+}
+
+QString VcProjectFile::filePath()
+{
+ return m_filePath;
+}
+
+QString VcProjectFile::path()
+{
+ return m_path;
+}
+
+} // namespace Internal
+} // namespace VcProjectManager
diff --git a/src/plugins/vcprojectmanager/vcprojectfile.h b/src/plugins/vcprojectmanager/vcprojectfile.h
new file mode 100644
index 0000000000..8eed0dccaa
--- /dev/null
+++ b/src/plugins/vcprojectmanager/vcprojectfile.h
@@ -0,0 +1,42 @@
+#ifndef VCPROJECTMANAGER_INTERNAL_VCPROJECTFILE_H
+#define VCPROJECTMANAGER_INTERNAL_VCPROJECTFILE_H
+
+#include <coreplugin/idocument.h>
+
+#include <QString>
+
+namespace VcProjectManager {
+namespace Internal {
+
+class VcProjectFile : public Core::IDocument
+{
+ Q_OBJECT
+
+public:
+ VcProjectFile(const QString &filePath);
+
+ bool save(QString *errorString, const QString &fileName = QString(), bool autoSave = false);
+ QString fileName() const;
+
+ QString defaultPath() const;
+ QString suggestedFileName() const;
+ QString mimeType() const;
+
+ bool isModified() const;
+ bool isSaveAsAllowed() const;
+
+ bool reload(QString *errorString, ReloadFlag flag, ChangeType type);
+ void rename(const QString &newName);
+
+ QString filePath();
+ QString path();
+
+private:
+ QString m_filePath;
+ QString m_path;
+};
+
+} // namespace Internal
+} // namespace VcProjectManager
+
+#endif // VCPROJECTMANAGER_INTERNAL_VCPROJECTFILE_H
diff --git a/src/plugins/vcprojectmanager/vcprojectmanager.cpp b/src/plugins/vcprojectmanager/vcprojectmanager.cpp
new file mode 100644
index 0000000000..9091a2ce00
--- /dev/null
+++ b/src/plugins/vcprojectmanager/vcprojectmanager.cpp
@@ -0,0 +1,104 @@
+#include "vcprojectmanager.h"
+
+#include "vcproject.h"
+#include "vcprojectmanagerconstants.h"
+
+#include <coreplugin/actionmanager/actionmanager.h>
+#include <coreplugin/actionmanager/actioncontainer.h>
+#include <coreplugin/icore.h>
+#include <coreplugin/icontext.h>
+#include <coreplugin/idocument.h>
+#include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/session.h>
+
+#include <QAction>
+
+using namespace ProjectExplorer;
+
+namespace VcProjectManager {
+namespace Internal {
+
+VcManager::VcManager()
+{
+ ProjectExplorerPlugin *projectExplorer = ProjectExplorerPlugin::instance();
+ connect(projectExplorer, SIGNAL(aboutToShowContextMenu(ProjectExplorer::Project*,ProjectExplorer::Node*)),
+ this, SLOT(updateContextMenu(ProjectExplorer::Project*,ProjectExplorer::Node*)));
+
+ Core::ActionManager *am = Core::ICore::actionManager();
+ Core::ActionContainer *buildMenu =
+ am->actionContainer(ProjectExplorer::Constants::M_BUILDPROJECT);
+ Core::ActionContainer *projectContexMenu =
+ am->actionContainer(ProjectExplorer::Constants::M_PROJECTCONTEXT);
+
+ const Core::Context projectContext(Constants::VC_PROJECT_CONTEXT);
+
+ m_reparseAction = new QAction(QIcon(), tr("Reparse"), this);
+ Core::Command *command = am->registerAction(m_reparseAction, Constants::REPARSE_ACTION_ID, projectContext);
+ // TODO: what is this for?
+ command->setAttribute(Core::Command::CA_Hide);
+ buildMenu->addAction(command, ProjectExplorer::Constants::G_BUILD_BUILD);
+ connect(m_reparseAction, SIGNAL(triggered()),
+ this, SLOT(reparseActiveProject()));
+
+ m_reparseContextMenuAction = new QAction(QIcon(), tr("Reparse"), this);
+ command = am->registerAction(m_reparseContextMenuAction, Constants::REPARSE_CONTEXT_MENU_ACTION_ID, projectContext);
+ // TODO: what is this for?
+ command->setAttribute(Core::Command::CA_Hide);
+ projectContexMenu->addAction(command, ProjectExplorer::Constants::G_PROJECT_TREE);
+ connect(m_reparseContextMenuAction, SIGNAL(triggered()),
+ this, SLOT(reparseContextProject()));
+}
+
+QString VcManager::mimeType() const
+{
+ return Constants::VCPROJ_MIMETYPE;
+}
+
+ProjectExplorer::Project *VcManager::openProject(const QString &fileName, QString *errorString)
+{
+ QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath();
+
+ // Check whether the project file exists.
+ if (canonicalFilePath.isEmpty()) {
+ if (errorString)
+ *errorString = tr("Failed opening project '%1': Project file does not exist")
+ .arg(QDir::toNativeSeparators(fileName));
+ return 0;
+ }
+
+ // Check whether the project is already open or not.
+ ProjectExplorerPlugin *projectExplorer = ProjectExplorerPlugin::instance();
+ foreach (Project *pi, projectExplorer->session()->projects()) {
+ if (canonicalFilePath == pi->document()->fileName()) {
+ *errorString = tr("Failed opening project '%1': Project already open")
+ .arg(QDir::toNativeSeparators(canonicalFilePath));
+ return 0;
+ }
+ }
+
+ return new VcProject(this, canonicalFilePath);
+}
+
+void VcManager::reparseActiveProject()
+{
+ VcProject *project = qobject_cast<VcProject *>(ProjectExplorerPlugin::currentProject());
+ if (project)
+ project->reparse();
+}
+
+void VcManager::reparseContextProject()
+{
+ VcProject *project = qobject_cast<VcProject *>(m_contextProject);
+ if (project)
+ project->reparse();
+}
+
+void VcManager::updateContextMenu(Project *project, ProjectExplorer::Node *node)
+{
+ Q_UNUSED(node);
+
+ m_contextProject = project;
+}
+
+} // namespace Internal
+} // namespace VcProjectManager
diff --git a/src/plugins/vcprojectmanager/vcprojectmanager.h b/src/plugins/vcprojectmanager/vcprojectmanager.h
new file mode 100644
index 0000000000..83d3f26770
--- /dev/null
+++ b/src/plugins/vcprojectmanager/vcprojectmanager.h
@@ -0,0 +1,36 @@
+#ifndef VCPROJECTMANAGER_H
+#define VCPROJECTMANAGER_H
+
+#include <projectexplorer/iprojectmanager.h>
+#include <projectexplorer/projectnodes.h>
+
+class QAction;
+
+namespace VcProjectManager {
+namespace Internal {
+
+class VcManager : public ProjectExplorer::IProjectManager
+{
+ Q_OBJECT
+
+public:
+ VcManager();
+
+ QString mimeType() const;
+ ProjectExplorer::Project *openProject(const QString &fileName, QString *errorString);
+
+private slots:
+ void reparseActiveProject();
+ void reparseContextProject();
+ void updateContextMenu(ProjectExplorer::Project *project, ProjectExplorer::Node *node);
+
+private:
+ ProjectExplorer::Project *m_contextProject;
+ QAction *m_reparseAction;
+ QAction *m_reparseContextMenuAction;
+};
+
+} // namespace Internal
+} // namespace VcProjectManager
+
+#endif // VCPROJECTMANAGER_H
diff --git a/src/plugins/vcprojectmanager/vcprojectmanager.pro b/src/plugins/vcprojectmanager/vcprojectmanager.pro
new file mode 100644
index 0000000000..a83fa5abf2
--- /dev/null
+++ b/src/plugins/vcprojectmanager/vcprojectmanager.pro
@@ -0,0 +1,22 @@
+include(../../qtcreatorplugin.pri)
+
+HEADERS = vcprojectmanagerplugin.h \
+ vcprojectreader.h \
+ vcprojectnodes.h \
+ vcprojectmanagerconstants.h \
+ vcprojectmanager_global.h \
+ vcprojectmanager.h \
+ vcprojectfile.h \
+ vcproject.h
+SOURCES = vcprojectmanagerplugin.cpp \
+ vcprojectreader.cpp \
+ vcprojectnodes.cpp \
+ vcprojectmanager.cpp \
+ vcprojectfile.cpp \
+ vcproject.cpp
+
+OTHER_FILES += \
+ VcProject.mimetypes.xml
+
+RESOURCES += \
+ vcproject.qrc
diff --git a/src/plugins/vcprojectmanager/vcprojectmanager_dependencies.pri b/src/plugins/vcprojectmanager/vcprojectmanager_dependencies.pri
new file mode 100644
index 0000000000..2ed5387255
--- /dev/null
+++ b/src/plugins/vcprojectmanager/vcprojectmanager_dependencies.pri
@@ -0,0 +1,4 @@
+QTC_PLUGIN_NAME = VcProjectManager
+QTC_PLUGIN_DEPENDS += \
+ coreplugin \
+ projectexplorer
diff --git a/src/plugins/vcprojectmanager/vcprojectmanager_global.h b/src/plugins/vcprojectmanager/vcprojectmanager_global.h
new file mode 100644
index 0000000000..176e919feb
--- /dev/null
+++ b/src/plugins/vcprojectmanager/vcprojectmanager_global.h
@@ -0,0 +1,13 @@
+#ifndef VCPROJECTMANAGER_GLOBAL_H
+#define VCPROJECTMANAGER_GLOBAL_H
+
+#include <QtGlobal>
+
+#if defined(VCPROJECTMANAGER_LIBRARY)
+# define VCPROJECTMANAGERSHARED_EXPORT Q_DECL_EXPORT
+#else
+# define VCPROJECTMANAGERSHARED_EXPORT Q_DECL_IMPORT
+#endif
+
+#endif // VCPROJECTMANAGER_GLOBAL_H
+
diff --git a/src/plugins/vcprojectmanager/vcprojectmanagerconstants.h b/src/plugins/vcprojectmanager/vcprojectmanagerconstants.h
new file mode 100644
index 0000000000..1b28f9f83e
--- /dev/null
+++ b/src/plugins/vcprojectmanager/vcprojectmanagerconstants.h
@@ -0,0 +1,22 @@
+#ifndef VCPROJECTMANAGERCONSTANTS_H
+#define VCPROJECTMANAGERCONSTANTS_H
+
+namespace VcProjectManager {
+namespace Constants {
+
+const char VCPROJ_MIMETYPE[] = "text/x-vc-project"; // TODO: is this good enough?
+const char VC_PROJECT_ID[] = "VcProject.VcProject";
+const char VC_PROJECT_CONTEXT[] = "VcProject.ProjectContext";
+const char VC_PROJECT_TARGET_ID[] = "VcProject.DefaultVcProjectTarget";
+
+const char REPARSE_ACTION_ID[] = "VcProject.ReparseMenuAction";
+const char REPARSE_CONTEXT_MENU_ACTION_ID[] = "VcProject.ReparseContextMenuAction";
+
+//const char ACTION_ID[] = "VcProjectManager.Action";
+//const char MENU_ID[] = "VcProjectManager.Menu";
+
+} // namespace VcProjectManager
+} // namespace Constants
+
+#endif // VCPROJECTMANAGERCONSTANTS_H
+
diff --git a/src/plugins/vcprojectmanager/vcprojectmanagerplugin.cpp b/src/plugins/vcprojectmanager/vcprojectmanagerplugin.cpp
new file mode 100644
index 0000000000..51ae6cb0b3
--- /dev/null
+++ b/src/plugins/vcprojectmanager/vcprojectmanagerplugin.cpp
@@ -0,0 +1,74 @@
+#include "vcprojectmanagerplugin.h"
+
+#include "vcprojectmanager.h"
+#include "vcprojectmanagerconstants.h"
+
+// TODO: clean up
+#include <coreplugin/actionmanager/actionmanager.h>
+#include <coreplugin/actionmanager/command.h>
+#include <coreplugin/actionmanager/actioncontainer.h>
+#include <coreplugin/coreconstants.h>
+#include <coreplugin/icontext.h>
+#include <coreplugin/icore.h>
+#include <coreplugin/mimedatabase.h>
+
+#include <QAction>
+#include <QMessageBox>
+#include <QMainWindow>
+#include <QMenu>
+
+#include <QtPlugin>
+
+namespace VcProjectManager {
+namespace Internal {
+
+VcProjectManagerPlugin::VcProjectManagerPlugin()
+{
+}
+
+VcProjectManagerPlugin::~VcProjectManagerPlugin()
+{
+ // Unregister objects from the plugin manager's object pool
+ // Delete members
+}
+
+bool VcProjectManagerPlugin::initialize(const QStringList &arguments, QString *errorString)
+{
+ // Register objects in the plugin manager's object pool
+ // Load settings
+ // Add actions to menus
+ // Connect to other plugins' signals
+ // In the initialize method, a plugin can be sure that the plugins it
+ // depends on have initialized their members.
+
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorString)
+
+ if (!Core::ICore::mimeDatabase()->addMimeTypes(QLatin1String(":vcproject/VcProject.mimetypes.xml"), errorString))
+ return false;
+
+ addAutoReleasedObject(new VcManager);
+
+ return true;
+}
+
+void VcProjectManagerPlugin::extensionsInitialized()
+{
+ // Retrieve objects from the plugin manager's object pool
+ // In the extensionsInitialized method, a plugin can be sure that all
+ // plugins that depend on it are completely initialized.
+}
+
+ExtensionSystem::IPlugin::ShutdownFlag VcProjectManagerPlugin::aboutToShutdown()
+{
+ // Save settings
+ // Disconnect from signals that are not needed during shutdown
+ // Hide UI (if you add UI that is not in the main window directly)
+ return SynchronousShutdown;
+}
+
+} // namespace Internal
+} // namespace VcProjectManager
+
+Q_EXPORT_PLUGIN2(VcProjectManager, VcProjectManager::Internal::VcProjectManagerPlugin)
+
diff --git a/src/plugins/vcprojectmanager/vcprojectmanagerplugin.h b/src/plugins/vcprojectmanager/vcprojectmanagerplugin.h
new file mode 100644
index 0000000000..f02ed17293
--- /dev/null
+++ b/src/plugins/vcprojectmanager/vcprojectmanagerplugin.h
@@ -0,0 +1,28 @@
+#ifndef VCPROJECTMANAGERPLUGIN_H
+#define VCPROJECTMANAGERPLUGIN_H
+
+#include "vcprojectmanager_global.h"
+
+#include <extensionsystem/iplugin.h>
+
+namespace VcProjectManager {
+namespace Internal {
+
+class VcProjectManagerPlugin : public ExtensionSystem::IPlugin
+{
+ Q_OBJECT
+
+public:
+ VcProjectManagerPlugin();
+ ~VcProjectManagerPlugin();
+
+ bool initialize(const QStringList &arguments, QString *errorString);
+ void extensionsInitialized();
+ ShutdownFlag aboutToShutdown();
+};
+
+} // namespace Internal
+} // namespace VcProjectManager
+
+#endif // VCPROJECTMANAGERPLUGIN_H
+
diff --git a/src/plugins/vcprojectmanager/vcprojectnodes.cpp b/src/plugins/vcprojectmanager/vcprojectnodes.cpp
new file mode 100644
index 0000000000..f9094b47ba
--- /dev/null
+++ b/src/plugins/vcprojectmanager/vcprojectnodes.cpp
@@ -0,0 +1,182 @@
+#include "vcprojectnodes.h"
+
+#include "vcprojectreader.h"
+
+// TODO: temp - just for VcProjectReader::typeForFileName()
+#include <coreplugin/icore.h>
+#include <coreplugin/mimedatabase.h>
+#include <projectexplorer/projectexplorerconstants.h>
+
+#include <QFileInfo>
+
+using namespace ProjectExplorer;
+
+namespace VcProjectManager {
+namespace Internal {
+
+VcProjectNode::VcProjectNode(const QString &projectFilePath)
+ : ProjectNode(projectFilePath)
+{
+}
+
+bool VcProjectNode::hasBuildTargets() const
+{
+ return true;
+}
+
+QList<ProjectNode::ProjectAction> VcProjectNode::supportedActions(ProjectExplorer::Node *node) const
+{
+ Q_UNUSED(node);
+ // TODO: add actions
+ return QList<ProjectNode::ProjectAction>();
+}
+
+bool VcProjectNode::canAddSubProject(const QString &proFilePath) const
+{
+ Q_UNUSED(proFilePath)
+ return false;
+}
+
+bool VcProjectNode::addSubProjects(const QStringList &proFilePaths)
+{
+ Q_UNUSED(proFilePaths);
+ return false;
+}
+
+bool VcProjectNode::removeSubProjects(const QStringList &proFilePaths)
+{
+ Q_UNUSED(proFilePaths);
+ return false;
+}
+
+bool VcProjectNode::addFiles(const FileType fileType,
+ const QStringList &filePaths,
+ QStringList *notAdded)
+{
+ Q_UNUSED(fileType);
+ Q_UNUSED(filePaths);
+ Q_UNUSED(notAdded);
+ // TODO: obvious
+ return false;
+}
+
+bool VcProjectNode::removeFiles(const FileType fileType,
+ const QStringList &filePaths,
+ QStringList *notRemoved)
+{
+ Q_UNUSED(fileType);
+ Q_UNUSED(filePaths);
+ Q_UNUSED(notRemoved);
+ // TODO: obvious
+ return false;
+}
+
+bool VcProjectNode::deleteFiles(const FileType fileType,
+ const QStringList &filePaths)
+{
+ Q_UNUSED(fileType);
+ Q_UNUSED(filePaths);
+ // TODO: obvious
+ return false;
+}
+
+bool VcProjectNode::renameFile(const FileType fileType,
+ const QString &filePath,
+ const QString &newFilePath)
+{
+ Q_UNUSED(fileType);
+ Q_UNUSED(filePath);
+ Q_UNUSED(newFilePath);
+ // TODO: obvious
+ return false;
+}
+
+QList<RunConfiguration *> VcProjectNode::runConfigurationsFor(Node *node)
+{
+ Q_UNUSED(node);
+ // TODO: what's this for
+ return QList<RunConfiguration *>();
+}
+
+void VcProjectNode::refresh(VcProjectInfo::Filter *files)
+{
+ removeFileNodes(fileNodes(), this);
+ removeFolderNodes(subFolderNodes(), this);
+ m_files.clear();
+
+ QList<FileNode *> projectFileNodeWrapped;
+ projectFileNodeWrapped.append(createFileNode(path()));
+ this->addFileNodes(projectFileNodeWrapped, this);
+
+ if (!files)
+ return;
+
+ QString projectPath = QFileInfo(path()).path();
+ QList<VcProjectInfo::Filter *> filterQueue;
+ QList<FolderNode *> parentQueue;
+ filterQueue.prepend(files);
+ parentQueue.prepend(this);
+
+ QList<FileNode *> fileNodes;
+ QList<FolderNode *> filterNodes;
+ while (!filterQueue.empty()) {
+ VcProjectInfo::Filter *filter = filterQueue.takeLast();
+ FolderNode *parent = parentQueue.takeLast();
+
+ fileNodes.clear();
+ filterNodes.clear();
+ foreach (VcProjectInfo::File *file, filter->files) {
+ FileNode *fileNode = createFileNode(projectPath + file->relativePath);
+ m_files.append(fileNode->path());
+ fileNodes.append(fileNode);
+ }
+ addFileNodes(fileNodes, parent);
+
+ foreach (VcProjectInfo::Filter *childFilter, filter->filters) {
+ FolderNode *filterNode = new FolderNode(parent->path() + childFilter->name);
+ filterNode->setDisplayName(childFilter->name);
+ filterQueue.prepend(childFilter);
+ parentQueue.prepend(filterNode);
+ filterNodes.append(filterNode);
+ }
+ addFolderNodes(filterNodes, parent);
+ }
+}
+
+QStringList VcProjectNode::files()
+{
+ return m_files;
+}
+
+FileNode *VcProjectNode::createFileNode(const QString &filePath)
+{
+ QFileInfo fileInfo = QFileInfo(filePath);
+ FileType fileType = typeForFileName(Core::ICore::mimeDatabase(), fileInfo);
+
+ return new FileNode(fileInfo.canonicalFilePath(), fileType, false);
+}
+
+FileType VcProjectNode::typeForFileName(const Core::MimeDatabase *db, const QFileInfo &file)
+{
+ const Core::MimeType mt = db->findByFile(file);
+ if (!mt)
+ return UnknownFileType;
+
+ const QString typeName = mt.type();
+ if (typeName == QLatin1String(ProjectExplorer::Constants::CPP_SOURCE_MIMETYPE)
+ || typeName == QLatin1String(ProjectExplorer::Constants::C_SOURCE_MIMETYPE))
+ return SourceType;
+ if (typeName == QLatin1String(ProjectExplorer::Constants::CPP_HEADER_MIMETYPE)
+ || typeName == QLatin1String(ProjectExplorer::Constants::C_HEADER_MIMETYPE))
+ return HeaderType;
+ if (typeName == QLatin1String(ProjectExplorer::Constants::RESOURCE_MIMETYPE))
+ return ResourceType;
+ if (typeName == QLatin1String(ProjectExplorer::Constants::FORM_MIMETYPE))
+ return FormType;
+ if (typeName == QLatin1String(ProjectExplorer::Constants::QML_MIMETYPE))
+ return QMLType;
+ return UnknownFileType;
+}
+
+} // namespace Internal
+} // namespace VcProjectManager
diff --git a/src/plugins/vcprojectmanager/vcprojectnodes.h b/src/plugins/vcprojectmanager/vcprojectnodes.h
new file mode 100644
index 0000000000..8e423f8091
--- /dev/null
+++ b/src/plugins/vcprojectmanager/vcprojectnodes.h
@@ -0,0 +1,56 @@
+#ifndef VCPROJECTMANAGER_INTERNAL_VCPROJECTNODES_H
+#define VCPROJECTMANAGER_INTERNAL_VCPROJECTNODES_H
+
+#include <projectexplorer/projectnodes.h>
+
+#include <QList>
+
+class QString;
+class QStringList;
+
+namespace VcProjectManager {
+namespace Internal {
+
+namespace VcProjectInfo {
+struct Filter;
+}
+
+class VcProjectNode : public ProjectExplorer::ProjectNode
+{
+public:
+ VcProjectNode(const QString &projectFilePath);
+
+ bool hasBuildTargets() const;
+ QList<ProjectAction> supportedActions(Node *node) const;
+ bool canAddSubProject(const QString &proFilePath) const;
+ bool addSubProjects(const QStringList &proFilePaths);
+ bool removeSubProjects(const QStringList &proFilePaths);
+ bool addFiles(const ProjectExplorer::FileType fileType,
+ const QStringList &filePaths,
+ QStringList *notAdded);
+ bool removeFiles(const ProjectExplorer::FileType fileType,
+ const QStringList &filePaths,
+ QStringList *notRemoved);
+ bool deleteFiles(const ProjectExplorer::FileType fileType,
+ const QStringList &filePaths);
+ bool renameFile(const ProjectExplorer::FileType fileType,
+ const QString &filePath,
+ const QString &newFilePath);
+ QList<ProjectExplorer::RunConfiguration *> runConfigurationsFor(Node *node);
+
+ void refresh(VcProjectInfo::Filter *files);
+ QStringList files();
+
+private:
+ static ProjectExplorer::FileNode *createFileNode(const QString &filePath);
+ // TODO: use the one from projectnodes.h
+ static ProjectExplorer::FileType typeForFileName(const Core::MimeDatabase *db, const QFileInfo &file);
+
+private:
+ QStringList m_files;
+};
+
+} // namespace Internal
+} // namespace VcProjectManager
+
+#endif // VCPROJECTMANAGER_INTERNAL_VCPROJECTNODES_H
diff --git a/src/plugins/vcprojectmanager/vcprojectreader.cpp b/src/plugins/vcprojectmanager/vcprojectreader.cpp
new file mode 100644
index 0000000000..6c19c29a72
--- /dev/null
+++ b/src/plugins/vcprojectmanager/vcprojectreader.cpp
@@ -0,0 +1,309 @@
+#include "vcprojectreader.h"
+
+#include <coreplugin/icore.h>
+#include <projectexplorer/projectnodes.h>
+
+#include <QFile>
+#include <QFileInfo>
+#include <QObject>
+
+using namespace ProjectExplorer;
+
+namespace VcProjectManager {
+namespace Internal {
+
+#define STRING(s) static const char str##s[] = #s
+
+STRING(Configuration);
+STRING(Configurations);
+STRING(File);
+STRING(Files);
+STRING(Filter);
+STRING(FileConfiguration);
+STRING(Globals);
+STRING(Name);
+STRING(Platform);
+STRING(Platforms);
+STRING(PublishingData);
+STRING(References);
+STRING(RelativePath);
+STRING(Tool);
+STRING(ToolFiles);
+STRING(VisualStudioProject);
+STRING(Version);
+
+using namespace VcProjectInfo;
+
+VcProjectInfo::Filter::~Filter()
+{
+ qDeleteAll(filters);
+ qDeleteAll(files);
+}
+
+Project::Project()
+ : files(0)
+{
+}
+
+Project::~Project()
+{
+ delete files;
+}
+
+VcProjectReader::VcProjectReader()
+ : m_project(0)
+ , m_currentFilter(0)
+{
+}
+
+Project *VcProjectReader::parse(const QString &filePath)
+{
+ QFile file(filePath);
+ if (!file.open(QFile::ReadOnly))
+ return 0;
+
+ setDevice(&file);
+
+ m_project = new Project;
+ m_project->projectFilePath = QFileInfo(filePath).canonicalPath();
+
+ if (!atEnd()) {
+ // read xml declaration
+ readNextNonSpace();
+ if (isStartDocument())
+ readNextNonSpace();
+ else
+ customError(QObject::tr("XML Declaration missing"));
+
+ if (elementStarts(strVisualStudioProject)) {
+ readVisualStudioProject();
+ readNextNonSpace();
+ }
+ else
+ missingMandatoryTag(strVisualStudioProject);
+
+ if (!isEndDocument())
+ unexpectedElement();
+ } else {
+ customError(QObject::tr("Project file is empty"));
+ }
+
+ if (hasError()) {
+ // TODO: error
+ qDebug() << errorString() << lineNumber() << columnNumber();
+ return 0;
+ }
+
+ qDebug() << "parsing successful";
+ return m_project;
+}
+
+void VcProjectReader::readVisualStudioProject()
+{
+ m_project->displayName = attrStr(strName);
+
+ // Platforms is mandatory element
+ readNextNonSpace();
+ if (elementStarts(strPlatforms)) {
+ readPlatforms();
+ readNextNonSpace();
+ } else {
+ missingMandatoryTag(strPlatforms);
+ }
+
+ // ToolFiles is optional element
+ if (elementStarts(strToolFiles)) {
+ readToolFiles();
+ readNextNonSpace();
+ }
+
+ // PublishingData is optional element
+ if (elementStarts(strPublishingData)) {
+ readPublishingData();
+ readNextNonSpace();
+ }
+
+ // Configurations is mandatory element
+ if (elementStarts(strConfigurations)) {
+ readConfigurations();
+ readNextNonSpace();
+ } else {
+ missingMandatoryTag(strConfigurations);
+ }
+
+ // References is optional element
+ if (elementStarts(strReferences)) {
+ readReferences();
+ readNextNonSpace();
+ }
+
+ // Files is optional element
+ if (elementStarts(strFiles)) {
+ readFiles();
+ readNextNonSpace();
+ }
+
+ // Globals is optional element
+ if (elementStarts(strGlobals)) {
+ readGlobals();
+ readNextNonSpace();
+ }
+
+ if (!elementEnds(strVisualStudioProject))
+ unexpectedElement();
+}
+
+void VcProjectReader::readPlatforms()
+{
+ while (!elementEnds(strPlatforms) && !hasError()) {
+ readNextNonSpace();
+ }
+}
+
+void VcProjectReader::readToolFiles()
+{
+ while (!elementEnds(strToolFiles) && !hasError()) {
+ readNextNonSpace();
+ }
+}
+
+void VcProjectReader::readPublishingData()
+{
+ while (!elementEnds(strPublishingData) && !hasError()) {
+ readNextNonSpace();
+ }
+}
+
+void VcProjectReader::readConfigurations()
+{
+ while (!elementEnds(strConfigurations) && !hasError()) {
+ readNextNonSpace();
+ }
+}
+
+void VcProjectReader::readReferences()
+{
+ while (!elementEnds(strReferences) && !hasError()) {
+ readNextNonSpace();
+ }
+}
+
+void VcProjectReader::readFiles()
+{
+ m_project->files = new Filter;
+ m_currentFilter = m_project->files;
+ readNextNonSpace();
+ while (!elementEnds(strFiles) && !hasError()) {
+ if (elementStarts(strFile)) {
+ readFile();
+ readNextNonSpace();
+ } else if (elementStarts(strFilter)) {
+ readFilter();
+ readNextNonSpace();
+ } else {
+ unexpectedElement();
+ }
+ }
+}
+
+void VcProjectReader::readFile()
+{
+ File *file = new File;
+ file->relativePath = attrStr(strRelativePath);
+ m_currentFilter->files.append(file);
+
+ readNextNonSpace();
+ while (!elementEnds(strFile) && !hasError()) {
+ if (elementStarts(strFileConfiguration)) {
+ readFileConfiguration();
+ readNextNonSpace();
+ } else {
+ unexpectedElement();
+ }
+ }
+}
+
+void VcProjectReader::readFileConfiguration()
+{
+ while (!elementEnds(strFileConfiguration) && !hasError()) {
+ readNextNonSpace();
+ }
+}
+
+void VcProjectReader::readFilter()
+{
+ Filter *filter = new Filter;
+ filter->name = attrStr(strName);
+ m_currentFilter->filters.append(filter);
+
+ Filter *prevFilter = m_currentFilter;
+ m_currentFilter = filter;
+
+ readNextNonSpace();
+ while (!elementEnds(strFilter) && !hasError()) {
+ if (elementStarts(strFile)) {
+ readFile();
+ readNextNonSpace();
+ } else if (elementStarts(strFilter)) {
+ readFilter();
+ readNextNonSpace();
+ } else {
+ unexpectedElement();
+ }
+ }
+
+ m_currentFilter = prevFilter;
+}
+
+void VcProjectReader::readGlobals()
+{
+ while (!elementEnds(strGlobals) && !hasError()) {
+ readNextNonSpace();
+ }
+}
+
+QString VcProjectReader::attrStr(const QString &attrName)
+{
+ // TODO: errors?
+ return attributes().value(attrName).toString();
+}
+
+bool VcProjectReader::elementStarts(const QString &str) const
+{
+ return isStartElement() && name() == str;
+}
+
+bool VcProjectReader::elementEnds(const QString &str) const
+{
+ return isEndElement() && name() == str;
+}
+
+void VcProjectReader::readNextNonSpace()
+{
+ if (!hasError()) {
+ do {
+ readNext();
+ } while (isCharacters() && text().toString().trimmed().isEmpty());
+ }
+ m_currentElement = name().toString();
+// qDebug() << "current element:" << (isEndElement() ? "\\": "") << m_currentElement;
+}
+
+void VcProjectReader::customError(const QString &message)
+{
+ if (!hasError())
+ raiseError(message);
+}
+
+void VcProjectReader::missingMandatoryTag(const QString &tagName)
+{
+ customError(QString("<") + tagName + ">" + " expected");
+}
+
+void VcProjectReader::unexpectedElement()
+{
+ customError(QString("Unexpected ") + name());
+}
+
+} // namespace Internal
+} // namespace VcProjectManager
diff --git a/src/plugins/vcprojectmanager/vcprojectreader.h b/src/plugins/vcprojectmanager/vcprojectreader.h
new file mode 100644
index 0000000000..0b66feec5a
--- /dev/null
+++ b/src/plugins/vcprojectmanager/vcprojectreader.h
@@ -0,0 +1,92 @@
+#ifndef VCPROJECTREADER_H
+#define VCPROJECTREADER_H
+
+#include "vcprojectnodes.h"
+
+#include <QXmlStreamReader>
+
+class QFileInfo;
+class QString;
+
+namespace Core {
+class MimeDatabase;
+}
+
+namespace ProjectExplorer {
+class FolderNode;
+}
+
+namespace VcProjectManager {
+namespace Internal {
+
+namespace VcProjectInfo {
+
+struct File
+{
+ QString relativePath;
+};
+
+struct Filter
+{
+ ~Filter();
+
+ QString name;
+ QList<Filter *> filters;
+ QList<File *> files;
+};
+
+struct Project
+{
+ Project();
+ ~Project();
+
+ QString projectFilePath; // TODO: redundant?
+ QString displayName;
+
+ Filter *files;
+};
+
+}
+
+class VcProjectNode;
+
+class VcProjectReader : public QXmlStreamReader
+{
+public:
+ VcProjectReader();
+
+ VcProjectInfo::Project *parse(const QString &filePath);
+
+private:
+ void readVisualStudioProject();
+ void readPlatforms();
+ void readToolFiles();
+ void readPublishingData();
+ void readConfigurations();
+ void readReferences();
+ void readFiles();
+ void readFile();
+ void readFileConfiguration();
+ void readFilter();
+ void readGlobals();
+
+ QString attrStr(const QString &attrName);
+ bool elementStarts(const QString &str) const;
+ bool elementEnds(const QString &str) const;
+ void readNextNonSpace();
+
+ void customError(const QString &message);
+ void missingMandatoryTag(const QString &tagName);
+ void unexpectedElement();
+
+private:
+ VcProjectInfo::Project *m_project;
+ VcProjectInfo::Filter *m_currentFilter;
+
+ QString m_currentElement;
+};
+
+} // namespace Internal
+} // namespace VcProjectManager
+
+#endif // VCPROJECTREADER_H