summaryrefslogtreecommitdiff
path: root/src/plugins/cmakeprojectmanager/cmakeproject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/cmakeprojectmanager/cmakeproject.cpp')
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeproject.cpp441
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
+}