diff options
Diffstat (limited to 'src/plugins/cmakeprojectmanager/cmakeproject.cpp')
-rw-r--r-- | src/plugins/cmakeprojectmanager/cmakeproject.cpp | 441 |
1 files changed, 441 insertions, 0 deletions
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp new file mode 100644 index 0000000000..2c98124bb9 --- /dev/null +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -0,0 +1,441 @@ +/*************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** +** Non-Open Source Usage +** +** Licensees may use this file in accordance with the Qt Beta Version +** License Agreement, Agreement version 2.2 provided with the Software or, +** alternatively, in accordance with the terms contained in a written +** agreement between you and Nokia. +** +** GNU General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the packaging +** of this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt GPL Exception version +** 1.2, included in the file GPL_EXCEPTION.txt in this package. +** +***************************************************************************/ +#include "cmakeproject.h" +#include "cmakeprojectconstants.h" +#include "cmakeprojectnodes.h" +#include <extensionsystem/pluginmanager.h> +#include <cpptools/cppmodelmanagerinterface.h> +#include <QtCore/QDebug> + +using namespace CMakeProjectManager; +using namespace CMakeProjectManager::Internal; + +CMakeProject::CMakeProject(CMakeManager *manager, const QString &fileName) + : m_manager(manager), m_fileName(fileName), m_rootNode(new CMakeProjectNode(m_fileName)) +{ + //TODO + m_file = new CMakeFile(this, fileName); + QDir dir = QFileInfo(m_fileName).absoluteDir(); + QString cbpFile = findCbpFile(dir); + if (cbpFile.isEmpty()) + cbpFile = createCbpFile(dir); + QList<ProjectExplorer::FileNode *> fileList; + QStringList includeFiles; + if (parseCbpFile(cbpFile, fileList, includeFiles)) { + buildTree(m_rootNode, fileList); + foreach(ProjectExplorer::FileNode *fn, fileList) + m_files.append(fn->path()); + m_files.sort(); + + includeFiles.sort(); + includeFiles.removeDuplicates(); + CppTools::CppModelManagerInterface *modelmanager = ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>(); + if (modelmanager) { + CppTools::CppModelManagerInterface::ProjectInfo *pinfo = modelmanager->projectInfo(this); + pinfo->includePaths = includeFiles; + pinfo->sourceFiles = m_files; // TODO we only want C++ files, not all other stuff that might be in the project + // TODO defines + } + } else { + // TODO report error + } +} + +CMakeProject::~CMakeProject() +{ + delete m_rootNode; +} + +QString CMakeProject::findCbpFile(const QDir &directory) +{ + // Find the cbp file + // TODO the cbp file is named like the project() command in the CMakeList.txt file + // so this method below could find the wrong cbp file, if the user changes the project() + // name + foreach(const QString &cbpFile , directory.entryList()) + { + if (cbpFile.endsWith(".cbp")) { + return directory.path() + "/" + cbpFile; + } + } + return QString::null; +} + + +QString CMakeProject::createCbpFile(const QDir &) +{ + // TODO create a cbp file. + // Issue: Where to create it? We want to do that in the build directory + // but at this stage we don't know the build directory yet + // So create it in a temp directory? + // Issue: We want to reuse whatever CMakeCache.txt that is alread there, which + // would indicate, creating it in the build directory + // Or we could use a temp directory and use -C builddirectory + return QString::null; +} + +bool CMakeProject::parseCbpFile(const QString &fileName, QList<ProjectExplorer::FileNode *> &fileList, QStringList &includeFiles) +{ + QFile fi(fileName); + if (fi.exists() && fi.open(QFile::ReadOnly)) { + QXmlStreamReader stream(&fi); + + while(!stream.atEnd()) { + stream.readNext(); + if (stream.name() == "CodeBlocks_project_file") { + parseCodeBlocks_project_file(stream, fileList, includeFiles); + } else if (stream.isStartElement()) { + parseUnknownElement(stream); + } + } + fi.close(); + return true; + } + return false; +} + +void CMakeProject::parseCodeBlocks_project_file(QXmlStreamReader &stream, QList<ProjectExplorer::FileNode *> &fileList, QStringList &includeFiles) +{ + while(!stream.atEnd()) { + stream.readNext(); + if (stream.isEndElement()) { + return; + } else if (stream.name() == "Project") { + parseProject(stream, fileList, includeFiles); + } else if (stream.isStartElement()) { + parseUnknownElement(stream); + } + } +} + +void CMakeProject::parseProject(QXmlStreamReader &stream, QList<ProjectExplorer::FileNode *> &fileList, QStringList &includeFiles) +{ + while(!stream.atEnd()) { + stream.readNext(); + if (stream.isEndElement()) { + return; + } else if (stream.name() == "Unit") { + parseUnit(stream, fileList); + } else if (stream.name() == "Build") { + parseBuild(stream, includeFiles); + } else if (stream.isStartElement()) { + parseUnknownElement(stream); + } + } +} + +void CMakeProject::parseBuild(QXmlStreamReader &stream, QStringList &includeFiles) +{ + while(!stream.atEnd()) { + stream.readNext(); + if (stream.isEndElement()) { + return; + } else if (stream.name() == "Target") { + parseTarget(stream, includeFiles); + } else if (stream.isStartElement()) { + parseUnknownElement(stream); + } + } +} + +void CMakeProject::parseTarget(QXmlStreamReader &stream, QStringList &includeFiles) +{ + while(!stream.atEnd()) { + stream.readNext(); + if (stream.isEndElement()) { + return; + } else if (stream.name() == "Compiler") { + parseCompiler(stream, includeFiles); + } else if (stream.isStartElement()) { + parseUnknownElement(stream); + } + } +} + +void CMakeProject::parseCompiler(QXmlStreamReader &stream, QStringList &includeFiles) +{ + while(!stream.atEnd()) { + stream.readNext(); + if (stream.isEndElement()) { + return; + } else if (stream.name() == "Add") { + parseAdd(stream, includeFiles); + } else if (stream.isStartElement()) { + parseUnknownElement(stream); + } + } +} + +void CMakeProject::parseAdd(QXmlStreamReader &stream, QStringList &includeFiles) +{ + includeFiles.append(stream.attributes().value("directory").toString()); + while(!stream.atEnd()) { + stream.readNext(); + if (stream.isEndElement()) { + return; + } else if (stream.isStartElement()) { + parseUnknownElement(stream); + } + } +} + +void CMakeProject::parseUnit(QXmlStreamReader &stream, QList<ProjectExplorer::FileNode *> &fileList) +{ + //qDebug()<<stream.attributes().value("filename"); + QString fileName = stream.attributes().value("filename").toString(); + if (!fileName.endsWith(".rule")) + fileList.append( new ProjectExplorer::FileNode(fileName, ProjectExplorer::SourceType, false)); + while(!stream.atEnd()) { + stream.readNext(); + if (stream.isEndElement()) { + return; + } else if (stream.isStartElement()) { + parseUnknownElement(stream); + } + } +} +void CMakeProject::parseUnknownElement(QXmlStreamReader &stream) +{ + Q_ASSERT(stream.isStartElement()); + + while (!stream.atEnd()) { + stream.readNext(); + + if (stream.isEndElement()) + break; + + if (stream.isStartElement()) + parseUnknownElement(stream); + } +} + +void CMakeProject::buildTree(CMakeProjectNode *rootNode, QList<ProjectExplorer::FileNode *> list) +{ + //m_rootNode->addFileNodes(fileList, m_rootNode); + qSort(list.begin(), list.end(), ProjectExplorer::ProjectNode::sortNodesByPath); + foreach( ProjectExplorer::FileNode *fn, list) { + // Get relative path to rootNode + QString parentDir = QFileInfo(fn->path()).absolutePath(); + ProjectExplorer::FolderNode *folder = findOrCreateFolder(rootNode, parentDir); + rootNode->addFileNodes(QList<ProjectExplorer::FileNode *>()<< fn, folder); + } + //m_rootNode->addFileNodes(list, rootNode); +} + +ProjectExplorer::FolderNode *CMakeProject::findOrCreateFolder(CMakeProjectNode *rootNode, QString directory) +{ + QString relativePath = QDir(QFileInfo(rootNode->path()).path()).relativeFilePath(directory); + QStringList parts = relativePath.split("/"); + ProjectExplorer::FolderNode *parent = rootNode; + foreach(const QString &part, parts) { + // Find folder in subFolders + bool found = false; + foreach(ProjectExplorer::FolderNode *folder, parent->subFolderNodes()) { + if (QFileInfo(folder->path()).fileName() == part) { + // yeah found something :) + parent = folder; + found = true; + break; + } + } + if (!found) { + // No FolderNode yet, so create it + ProjectExplorer::FolderNode *tmp = new ProjectExplorer::FolderNode(part); + rootNode->addFolderNodes(QList<ProjectExplorer::FolderNode *>() << tmp, parent); + parent = tmp; + } + } + return parent; +} + +QString CMakeProject::name() const +{ + // TODO + return ""; +} + +Core::IFile *CMakeProject::file() const +{ + return m_file; +} + +ProjectExplorer::IProjectManager *CMakeProject::projectManager() const +{ + return m_manager; +} + +QList<Core::IFile *> CMakeProject::dependencies() +{ + return QList<Core::IFile *>(); +} + +QList<ProjectExplorer::Project *> CMakeProject::dependsOn() +{ + return QList<Project *>(); +} + +bool CMakeProject::isApplication() const +{ + return true; +} + +ProjectExplorer::Environment CMakeProject::environment(const QString &buildConfiguration) const +{ + Q_UNUSED(buildConfiguration) + //TODO + return ProjectExplorer::Environment::systemEnvironment(); +} + +QString CMakeProject::buildDirectory(const QString &buildConfiguration) const +{ + Q_UNUSED(buildConfiguration) + //TODO + return ""; +} + +ProjectExplorer::BuildStepConfigWidget *CMakeProject::createConfigWidget() +{ + return new CMakeBuildSettingsWidget; +} + +QList<ProjectExplorer::BuildStepConfigWidget*> CMakeProject::subConfigWidgets() +{ + return QList<ProjectExplorer::BuildStepConfigWidget*>(); +} + +// This method is called for new build configurations +// You should probably set some default values in this method + void CMakeProject::newBuildConfiguration(const QString &buildConfiguration) + { + Q_UNUSED(buildConfiguration); + //TODO + } + +ProjectExplorer::ProjectNode *CMakeProject::rootProjectNode() const +{ + return m_rootNode; +} + + +QStringList CMakeProject::files(FilesMode fileMode) const +{ + Q_UNUSED(fileMode); + // TODO + return m_files; +} + +void CMakeProject::saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &writer) +{ + // TODO + Q_UNUSED(writer) +} + +void CMakeProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader &reader) +{ + // TODO + Q_UNUSED(reader) +} + + +CMakeFile::CMakeFile(CMakeProject *parent, QString fileName) + : Core::IFile(parent), m_project(parent), m_fileName(fileName) +{ + +} + +bool CMakeFile::save(const QString &fileName) +{ + // TODO + // Once we have an texteditor open for this file, we probably do + // need to implement this, don't we. + Q_UNUSED(fileName); + return false; +} + +QString CMakeFile::fileName() const +{ + return m_fileName; +} + +QString CMakeFile::defaultPath() const +{ + return QString(); +} + +QString CMakeFile::suggestedFileName() const +{ + return QString(); +} + +QString CMakeFile::mimeType() const +{ + return Constants::CMAKEMIMETYPE; +} + + +bool CMakeFile::isModified() const +{ + return false; +} + +bool CMakeFile::isReadOnly() const +{ + return true; +} + +bool CMakeFile::isSaveAsAllowed() const +{ + return false; +} + +void CMakeFile::modified(ReloadBehavior *behavior) +{ + Q_UNUSED(behavior); +} + + +CMakeBuildSettingsWidget::CMakeBuildSettingsWidget() +{ + +} + +QString CMakeBuildSettingsWidget::displayName() const +{ + return "CMake"; +} + +void CMakeBuildSettingsWidget::init(const QString &buildConfiguration) +{ + Q_UNUSED(buildConfiguration); + // TODO +} |