diff options
author | Bojan Petrovic <bojan85@gmail.com> | 2012-05-03 23:15:18 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@digia.com> | 2014-03-11 19:54:51 +0100 |
commit | afb07299882ef935d47dc4d6be82dc566f6a5818 (patch) | |
tree | 675ee5539d563b68104cae6d685a79e95ca19f89 | |
parent | 52bf71fbdff62bdcd0c67e0a5edc45b695b3c519 (diff) |
Initial commit.
Change-Id: I780993c008f95614b46da16b346fe40c5c15f8dc
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 |