diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index f02779acd70a3da8c2b4f3376028631af4fd20f7..5eda4b77e54ff171c2f081bc3b6f916807352a1a 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -988,13 +988,16 @@ void CppModelManager::parse(QFutureInterface<void> &future, Core::MimeType cSourceTy = db->findByType(QLatin1String("text/x-csrc")); Core::MimeType cppSourceTy = db->findByType(QLatin1String("text/x-c++src")); + Core::MimeType cHeaderTy = db->findByType(QLatin1String("text/x-hdr")); + Core::MimeType cppHeaderTy = db->findByType(QLatin1String("text/x-c++hdr")); + foreach (const QString &file, files) { const QFileInfo fileInfo(file); if (cSourceTy.matchesFile(fileInfo) || cppSourceTy.matchesFile(fileInfo)) sources.append(file); - else + else if (cHeaderTy.matchesFile(fileInfo) || cppHeaderTy.matchesFile(fileInfo)) headers.append(file); } diff --git a/src/plugins/cpptools/cpptoolsplugin.cpp b/src/plugins/cpptools/cpptoolsplugin.cpp index 63a1808e3d7938a8afad717760d54773354068d9..3ca1db880995ff0101cf697fea9a741c0766a13e 100644 --- a/src/plugins/cpptools/cpptoolsplugin.cpp +++ b/src/plugins/cpptools/cpptoolsplugin.cpp @@ -231,7 +231,7 @@ QString CppToolsPlugin::correspondingHeaderOrSourceI(const QString &fileName) co return QString(); const QDir absoluteDir = fi.absoluteDir(); - const QString baseName = fi.baseName(); + const QString baseName = fi.completeBaseName(); const QStringList suffixes = matchingCandidateSuffixes(mimeDatase, type); const QString privateHeaderSuffix = QLatin1String("_p"); diff --git a/src/plugins/genericprojectmanager/GenericProject.mimetypes.xml b/src/plugins/genericprojectmanager/GenericProject.mimetypes.xml new file mode 100644 index 0000000000000000000000000000000000000000..c45a828b20015181526ad3eacc354bcd067424c8 --- /dev/null +++ b/src/plugins/genericprojectmanager/GenericProject.mimetypes.xml @@ -0,0 +1,28 @@ +<?xml version="1.0"?> + +<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'> + <mime-type type="text/x-generic-project"> + <sub-class-of type="text/plain"/> + <comment>Generic Qt Creator Project file</comment> + <glob pattern="*.creator"/> + </mime-type> + + <mime-type type="application/vnd.nokia.qt.generic.files"> + <sub-class-of type="text/plain"/> + <comment>Generic Project Files</comment> + <glob pattern="*.files"/> + </mime-type> + + <mime-type type="application/vnd.nokia.qt.generic.includes"> + <sub-class-of type="text/plain"/> + <comment>Generic Project Include Paths</comment> + <glob pattern="*.includes"/> + </mime-type> + + <mime-type type="application/vnd.nokia.qt.generic.config"> + <sub-class-of type="text/plain"/> + <comment>Generic Project Configuration File</comment> + <glob pattern="*.config"/> + </mime-type> + +</mime-info> diff --git a/src/plugins/genericprojectmanager/GenericProjectManager.pluginspec b/src/plugins/genericprojectmanager/GenericProjectManager.pluginspec new file mode 100644 index 0000000000000000000000000000000000000000..d3cf9fd51310f6a87873e443a2d775e7187df137 --- /dev/null +++ b/src/plugins/genericprojectmanager/GenericProjectManager.pluginspec @@ -0,0 +1,28 @@ +<plugin name="GenericProjectManager" version="1.0.80" compatVersion="1.0.80"> + <vendor>Nokia Corporation</vendor> + <copyright>(C) 2008-2009 Nokia Corporation</copyright> + <license> +Commercial Usage + +Licensees holding valid Qt Commercial licenses may use this plugin in +accordance with the Qt Commercial License Agreement provided with the +Software or, alternatively, in accordance with the terms contained in +a written agreement between you and Nokia. + +GNU Lesser General Public License Usage + +Alternatively, this plugin may be used under the terms of the GNU Lesser +General Public License version 2.1 as published by the Free Software +Foundation. Please review the following information to +ensure the GNU Lesser General Public License version 2.1 requirements +will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> + <description>Generic support</description> + <url>http://www.qtsoftware.com</url> + <dependencyList> + <dependency name="TextEditor" version="1.0.80"/> + <dependency name="ProjectExplorer" version="1.0.80"/> + <dependency name="CppTools" version="1.0.80"/> + <dependency name="CppEditor" version="1.0.80"/> + <dependency name="Help" version="1.0.80"/> + </dependencyList> +</plugin> diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bad7c7c4e1c0cd545d4d612e4d24173e8b32f463 --- /dev/null +++ b/src/plugins/genericprojectmanager/genericproject.cpp @@ -0,0 +1,547 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#include "genericproject.h" +#include "genericprojectconstants.h" +#include "genericprojectnodes.h" +#include "makestep.h" + +#include <projectexplorer/projectexplorerconstants.h> +#include <cpptools/cppmodelmanagerinterface.h> +#include <extensionsystem/pluginmanager.h> +#include <utils/qtcassert.h> +#include <coreplugin/icore.h> + +#include <cpptools/cppmodelmanagerinterface.h> + +#include <QtCore/QtDebug> +#include <QtCore/QDir> +#include <QtCore/QSettings> +#include <QtCore/QProcess> + +#include <QtGui/QFormLayout> +#include <QtGui/QMainWindow> +#include <QtGui/QComboBox> +#include <QtGui/QStringListModel> +#include <QtGui/QListWidget> +#include <QtGui/QPushButton> + +using namespace GenericProjectManager; +using namespace GenericProjectManager::Internal; + +//////////////////////////////////////////////////////////////////////////////////// +// GenericProject +//////////////////////////////////////////////////////////////////////////////////// + +namespace { + +class ListModel: public QStringListModel +{ +public: + ListModel(QObject *parent) + : QStringListModel(parent) {} + + virtual ~ListModel() {} + + virtual int rowCount(const QModelIndex &parent) const + { return 1 + QStringListModel::rowCount(parent); } + + virtual Qt::ItemFlags flags(const QModelIndex &index) const + { return QStringListModel::flags(index) | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; } + + virtual QModelIndex index(int row, int column, const QModelIndex &parent) const + { + if (row == stringList().size()) + return createIndex(row, column); + + return QStringListModel::index(row, column, parent); + } + + virtual QVariant data(const QModelIndex &index, int role) const + { + if (role == Qt::DisplayRole || role == Qt::EditRole) { + if (index.row() == stringList().size()) + return tr("<new>"); + } + + return QStringListModel::data(index, role); + } + + virtual bool setData(const QModelIndex &index, const QVariant &value, int role) + { + if (role == Qt::EditRole && index.row() == stringList().size()) + insertRow(index.row(), QModelIndex()); + + return QStringListModel::setData(index, value, role); + } +}; + +} // end of anonymous namespace + +GenericProject::GenericProject(Manager *manager, const QString &fileName) + : _manager(manager), + _fileName(fileName), + _toolChain(0) +{ + QFileInfo fileInfo(_fileName); + const QString projectBaseName = fileInfo.baseName(); + QDir dir = fileInfo.dir(); + + _filesFileName = QFileInfo(dir, projectBaseName + QLatin1String(".files")).absoluteFilePath(); + _includesFileName = QFileInfo(dir, projectBaseName + QLatin1String(".includes")).absoluteFilePath(); + _configFileName = QFileInfo(dir, projectBaseName + QLatin1String(".config")).absoluteFilePath(); + + _file = new GenericProjectFile(this, fileName); + _rootNode = new GenericProjectNode(this, _file); + + _manager->registerProject(this); +} + +GenericProject::~GenericProject() +{ + _manager->unregisterProject(this); + + delete _rootNode; + delete _toolChain; +} + +QString GenericProject::filesFileName() const +{ return _filesFileName; } + +QString GenericProject::includesFileName() const +{ return _includesFileName; } + +QString GenericProject::configFileName() const +{ return _configFileName; } + +QStringList GenericProject::readLines(const QString &absoluteFileName) const +{ + QStringList lines; + + QFile file(absoluteFileName); + if (file.open(QFile::ReadOnly)) { + QTextStream stream(&file); + + forever { + QString line = stream.readLine(); + if (line.isNull()) + break; + + line = line.trimmed(); + if (line.isEmpty()) + continue; + + lines.append(line); + } + } + + return lines; +} + + +void GenericProject::parseProject() +{ + const QFileInfo projectFileInfo(_fileName); + + QSettings projectInfo(_fileName, QSettings::IniFormat); + + _files = convertToAbsoluteFiles(readLines(filesFileName())); + _files.removeDuplicates(); + + _projectIncludePaths = readLines(includesFileName()); + _projectIncludePaths.removeDuplicates(); + + _generated = convertToAbsoluteFiles(projectInfo.value(QLatin1String("generated")).toStringList()); + + _defines.clear(); + + QFile configFn(configFileName()); + if (configFn.open(QFile::ReadOnly)) + _defines = configFn.readAll(); + + emit fileListChanged(); +} + +void GenericProject::refresh() +{ + parseProject(); + + _rootNode->refresh(); + + CppTools::CppModelManagerInterface *modelManager = + ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>(); + + if (_toolChain && modelManager) { + const QByteArray predefinedMacros = _toolChain->predefinedMacros(); + const QList<ProjectExplorer::HeaderPath> systemHeaderPaths = _toolChain->systemHeaderPaths(); + + CppTools::CppModelManagerInterface::ProjectInfo pinfo = modelManager->projectInfo(this); + pinfo.defines = predefinedMacros; + pinfo.defines += '\n'; + pinfo.defines += _defines; + + QStringList allIncludePaths, allFrameworkPaths; + + foreach (const ProjectExplorer::HeaderPath &headerPath, _toolChain->systemHeaderPaths()) { + if (headerPath.kind() == ProjectExplorer::HeaderPath::FrameworkHeaderPath) + allFrameworkPaths.append(headerPath.path()); + + else + allIncludePaths.append(headerPath.path()); + } + + allIncludePaths += this->allIncludePaths(); + + pinfo.frameworkPaths = allFrameworkPaths; + pinfo.includePaths = allIncludePaths; + + // ### add _defines. + pinfo.sourceFiles = files(); + pinfo.sourceFiles += generated(); + + modelManager->updateProjectInfo(pinfo); + modelManager->updateSourceFiles(pinfo.sourceFiles); + } +} + +QStringList GenericProject::convertToAbsoluteFiles(const QStringList &paths) const +{ + const QDir projectDir(QFileInfo(_fileName).dir()); + QStringList absolutePaths; + foreach (const QString &file, paths) { + QFileInfo fileInfo(projectDir, file); + absolutePaths.append(fileInfo.absoluteFilePath()); + } + absolutePaths.removeDuplicates(); + return absolutePaths; +} + +QStringList GenericProject::allIncludePaths() const +{ + QStringList paths; + paths += _includePaths; + paths += _projectIncludePaths; + paths.removeDuplicates(); + return paths; +} + +QStringList GenericProject::projectIncludePaths() const +{ return _projectIncludePaths; } + +QStringList GenericProject::files() const +{ return _files; } + +QStringList GenericProject::generated() const +{ return _generated; } + +QStringList GenericProject::includePaths() const +{ return _includePaths; } + +void GenericProject::setIncludePaths(const QStringList &includePaths) +{ _includePaths = includePaths; } + +QByteArray GenericProject::defines() const +{ return _defines; } + +void GenericProject::setToolChainId(const QString &toolChainId) +{ + using namespace ProjectExplorer; + + _toolChainId = toolChainId; + + delete _toolChain; + _toolChain = 0; + + if (toolChainId == QLatin1String("mingw")) { + const QLatin1String qmake_cxx("g++"); // ### FIXME + const QString mingwDirectory; // ### FIXME + + _toolChain = ToolChain::createMinGWToolChain(qmake_cxx, mingwDirectory); + + } else if (toolChainId == QLatin1String("msvc")) { + const QString msvcVersion; // ### FIXME + _toolChain = ToolChain::createMSVCToolChain(msvcVersion); + + } else if (toolChainId == QLatin1String("wince")) { + const QString msvcVersion, wincePlatform; // ### FIXME + _toolChain = ToolChain::createWinCEToolChain(msvcVersion, wincePlatform); + + } else if (toolChainId == QLatin1String("gcc") || toolChainId == QLatin1String("icc")) { + const QLatin1String qmake_cxx("g++"); // ### FIXME + _toolChain = ToolChain::createGccToolChain(qmake_cxx); + } +} + +QString GenericProject::buildParser(const QString &buildConfiguration) const +{ + if (_toolChain) { + switch (_toolChain->type()) { + case ProjectExplorer::ToolChain::GCC: + case ProjectExplorer::ToolChain::LinuxICC: + case ProjectExplorer::ToolChain::MinGW: + return QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_GCC); + + case ProjectExplorer::ToolChain::MSVC: + case ProjectExplorer::ToolChain::WINCE: + return ProjectExplorer::Constants::BUILD_PARSER_MSVC; + + default: + break; + } // switch + } + + return QString(); +} + +QString GenericProject::toolChainId() const +{ return _toolChainId; } + +QString GenericProject::name() const +{ + return _projectName; +} + +Core::IFile *GenericProject::file() const +{ + return _file; +} + +ProjectExplorer::IProjectManager *GenericProject::projectManager() const +{ + return _manager; +} + +QList<ProjectExplorer::Project *> GenericProject::dependsOn() +{ + return QList<Project *>(); +} + +bool GenericProject::isApplication() const +{ + return true; +} + +ProjectExplorer::Environment GenericProject::environment(const QString &) const +{ + return ProjectExplorer::Environment::systemEnvironment(); +} + +QString GenericProject::buildDirectory(const QString &buildConfiguration) const +{ + QString buildDirectory = value(buildConfiguration, "buildDirectory").toString(); + + if (buildDirectory.isEmpty()) { + QFileInfo fileInfo(_fileName); + + buildDirectory = fileInfo.absolutePath(); + } + + return buildDirectory; +} + +ProjectExplorer::BuildStepConfigWidget *GenericProject::createConfigWidget() +{ + return new GenericBuildSettingsWidget(this); +} + +QList<ProjectExplorer::BuildStepConfigWidget*> GenericProject::subConfigWidgets() +{ + return QList<ProjectExplorer::BuildStepConfigWidget*>(); +} + + void GenericProject::newBuildConfiguration(const QString &buildConfiguration) + { + makeStep()->setBuildTarget(buildConfiguration, "all", true); + } + +GenericProjectNode *GenericProject::rootProjectNode() const +{ + return _rootNode; +} + +QStringList GenericProject::files(FilesMode fileMode) const +{ + return _files; // ### TODO: handle generated files here. +} + +QStringList GenericProject::targets() const +{ + QStringList targets; + targets.append(QLatin1String("all")); + targets.append(QLatin1String("clean")); + return targets; +} + +MakeStep *GenericProject::makeStep() const +{ + foreach (ProjectExplorer::BuildStep *bs, buildSteps()) { + if (MakeStep *ms = qobject_cast<MakeStep *>(bs)) + return ms; + } + + return 0; +} + +void GenericProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader &reader) +{ + Project::restoreSettingsImpl(reader); + + if (buildConfigurations().isEmpty()) { + MakeStep *makeStep = new MakeStep(this); + insertBuildStep(0, makeStep); + + const QLatin1String all("all"); + + addBuildConfiguration(all); + setActiveBuildConfiguration(all); + makeStep->setBuildTarget(all, all, /* on = */ true); + + const QLatin1String buildDirectory("buildDirectory"); + + const QFileInfo fileInfo(file()->fileName()); + setValue(all, buildDirectory, fileInfo.absolutePath()); + } + + QString toolChainId = reader.restoreValue(QLatin1String("toolChain")).toString(); + if (toolChainId.isEmpty()) + toolChainId = QLatin1String("gcc"); + + setToolChainId(toolChainId.toLower()); // ### move + + const QStringList userIncludePaths = + reader.restoreValue(QLatin1String("includePaths")).toStringList(); + + setIncludePaths(allIncludePaths()); + + parseProject(); + refresh(); +} + +void GenericProject::saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &writer) +{ + Project::saveSettingsImpl(writer); + + writer.saveValue(QLatin1String("toolChain"), _toolChainId); + writer.saveValue(QLatin1String("includePaths"), _includePaths); +} + +//////////////////////////////////////////////////////////////////////////////////// +// GenericBuildSettingsWidget +//////////////////////////////////////////////////////////////////////////////////// +GenericBuildSettingsWidget::GenericBuildSettingsWidget(GenericProject *project) + : _project(project) +{ + QFormLayout *fl = new QFormLayout(this); + + // build directory + _pathChooser = new Core::Utils::PathChooser(this); + _pathChooser->setEnabled(true); + fl->addRow(tr("Build directory:"), _pathChooser); + connect(_pathChooser, SIGNAL(changed()), this, SLOT(buildDirectoryChanged())); + + // tool chain + QComboBox *toolChainChooser = new QComboBox; + toolChainChooser->addItems(ProjectExplorer::ToolChain::supportedToolChains()); + toolChainChooser->setCurrentIndex(toolChainChooser->findText(_project->toolChainId())); + fl->addRow(tr("Tool chain:"), toolChainChooser); + connect(toolChainChooser, SIGNAL(activated(QString)), _project, SLOT(setToolChainId(QString))); +} + +GenericBuildSettingsWidget::~GenericBuildSettingsWidget() +{ } + +QString GenericBuildSettingsWidget::displayName() const +{ return tr("Generic Manager"); } + +void GenericBuildSettingsWidget::init(const QString &buildConfiguration) +{ + _buildConfiguration = buildConfiguration; + _pathChooser->setPath(_project->buildDirectory(buildConfiguration)); +} + +void GenericBuildSettingsWidget::buildDirectoryChanged() +{ + _project->setValue(_buildConfiguration, "buildDirectory", _pathChooser->path()); +} + +//////////////////////////////////////////////////////////////////////////////////// +// GenericProjectFile +//////////////////////////////////////////////////////////////////////////////////// +GenericProjectFile::GenericProjectFile(GenericProject *parent, QString fileName) + : Core::IFile(parent), + _project(parent), + _fileName(fileName) +{ } + +GenericProjectFile::~GenericProjectFile() +{ } + +bool GenericProjectFile::save(const QString &) +{ + return false; +} + +QString GenericProjectFile::fileName() const +{ + return _fileName; +} + +QString GenericProjectFile::defaultPath() const +{ + return QString(); +} + +QString GenericProjectFile::suggestedFileName() const +{ + return QString(); +} + +QString GenericProjectFile::mimeType() const +{ + return Constants::GENERICMIMETYPE; +} + +bool GenericProjectFile::isModified() const +{ + return false; +} + +bool GenericProjectFile::isReadOnly() const +{ + return true; +} + +bool GenericProjectFile::isSaveAsAllowed() const +{ + return false; +} + +void GenericProjectFile::modified(ReloadBehavior *) +{ +} diff --git a/src/plugins/genericprojectmanager/genericproject.h b/src/plugins/genericprojectmanager/genericproject.h new file mode 100644 index 0000000000000000000000000000000000000000..54cb7473ce42fd5dd81c5218a6cb999d4437bc8f --- /dev/null +++ b/src/plugins/genericprojectmanager/genericproject.h @@ -0,0 +1,182 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#ifndef GENERICPROJECT_H +#define GENERICPROJECT_H + +#include "genericprojectmanager.h" +#include "genericprojectnodes.h" +#include "makestep.h" + +#include <projectexplorer/project.h> +#include <projectexplorer/projectnodes.h> +#include <projectexplorer/buildstep.h> +#include <projectexplorer/toolchain.h> +#include <coreplugin/ifile.h> +#include <utils/pathchooser.h> + +QT_BEGIN_NAMESPACE +class QPushButton; +class QStringListModel; +QT_END_NAMESPACE + +namespace GenericProjectManager { +namespace Internal{ + +class GenericProjectFile; + +class GenericProject : public ProjectExplorer::Project +{ + Q_OBJECT + +public: + GenericProject(Manager *manager, const QString &filename); + virtual ~GenericProject(); + + QString filesFileName() const; + QString includesFileName() const; + QString configFileName() const; + + virtual QString name() const; + virtual Core::IFile *file() const; + virtual ProjectExplorer::IProjectManager *projectManager() const; + + virtual QList<ProjectExplorer::Project *> dependsOn(); + + virtual bool isApplication() const; + + virtual ProjectExplorer::Environment environment(const QString &buildConfiguration) const; + virtual QString buildDirectory(const QString &buildConfiguration) const; + + virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget(); + virtual QList<ProjectExplorer::BuildStepConfigWidget*> subConfigWidgets(); + + virtual void newBuildConfiguration(const QString &buildConfiguration); + virtual GenericProjectNode *rootProjectNode() const; + virtual QStringList files(FilesMode fileMode) const; + + QStringList targets() const; + MakeStep *makeStep() const; + QString buildParser(const QString &buildConfiguration) const; + + QStringList convertToAbsoluteFiles(const QStringList &paths) const; + + QStringList includePaths() const; + void setIncludePaths(const QStringList &includePaths); + + QByteArray defines() const; + QStringList allIncludePaths() const; + QStringList projectIncludePaths() const; + QStringList files() const; + QStringList generated() const; + QString toolChainId() const; + +public Q_SLOTS: + void setToolChainId(const QString &toolChainId); + void refresh(); + +protected: + virtual void saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &writer); + virtual void restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader &reader); + +private: + void parseProject(); + + QStringList readLines(const QString &absoluteFileName) const; + + Manager *_manager; + QString _fileName; + QString _filesFileName; + QString _includesFileName; + QString _configFileName; + GenericProjectFile *_file; + QString _projectName; + + QStringList _files; + QStringList _generated; + QStringList _includePaths; + QStringList _projectIncludePaths; + QByteArray _defines; + + GenericProjectNode* _rootNode; + ProjectExplorer::ToolChain *_toolChain; + QString _toolChainId; +}; + +class GenericProjectFile : public Core::IFile +{ + Q_OBJECT + +public: + GenericProjectFile(GenericProject *parent, QString fileName); + virtual ~GenericProjectFile(); + + virtual bool save(const QString &fileName = QString()); + virtual QString fileName() const; + + virtual QString defaultPath() const; + virtual QString suggestedFileName() const; + virtual QString mimeType() const; + + virtual bool isModified() const; + virtual bool isReadOnly() const; + virtual bool isSaveAsAllowed() const; + + virtual void modified(ReloadBehavior *behavior); + +private: + GenericProject *_project; + QString _fileName; +}; + +class GenericBuildSettingsWidget : public ProjectExplorer::BuildStepConfigWidget +{ + Q_OBJECT + +public: + GenericBuildSettingsWidget(GenericProject *project); + virtual ~GenericBuildSettingsWidget(); + + virtual QString displayName() const; + + virtual void init(const QString &buildConfiguration); + +private Q_SLOTS: + void buildDirectoryChanged(); + +private: + GenericProject *_project; + Core::Utils::PathChooser *_pathChooser; + QString _buildConfiguration; +}; + +} // namespace Internal +} // namespace GenericProjectManager + +#endif // GENERICPROJECT_H diff --git a/src/plugins/genericprojectmanager/genericproject.qrc b/src/plugins/genericprojectmanager/genericproject.qrc new file mode 100644 index 0000000000000000000000000000000000000000..e31e9270e7db98b5141b10cdd8399e797803245a --- /dev/null +++ b/src/plugins/genericprojectmanager/genericproject.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/genericproject" > + <file>GenericProject.mimetypes.xml</file> + </qresource> +</RCC> diff --git a/src/plugins/genericprojectmanager/genericprojectconstants.h b/src/plugins/genericprojectmanager/genericprojectconstants.h new file mode 100644 index 0000000000000000000000000000000000000000..d05c922b5e036f1c7ec63ba538ae5907e31ec14a --- /dev/null +++ b/src/plugins/genericprojectmanager/genericprojectconstants.h @@ -0,0 +1,58 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#ifndef GENERICPROJECTCONSTANTS_H +#define GENERICPROJECTCONSTANTS_H + +namespace GenericProjectManager { +namespace Constants { + +const char *const PROJECTCONTEXT = "GenericProject.ProjectContext"; +const char *const GENERICMIMETYPE = "text/x-generic-project"; // ### FIXME +const char *const MAKESTEP = "GenericProjectManager.MakeStep"; + +// contexts +const char *const C_FILESEDITOR = ".files Editor"; + +// kinds +const char *const PROJECT_KIND = "Generic"; + +const char *const FILES_EDITOR = ".files Editor"; +const char *const FILES_MIMETYPE = "application/vnd.nokia.qt.generic.files"; + +const char *const INCLUDES_EDITOR = ".includes Editor"; +const char *const INCLUDES_MIMETYPE = "application/vnd.nokia.qt.generic.includes"; + +const char *const CONFIG_EDITOR = ".includes Editor"; +const char *const CONFIG_MIMETYPE = "application/vnd.nokia.qt.generic.config"; + +} // namespace Constants +} // namespace GenericProjectManager + +#endif // GENERICPROJECTCONSTANTS_H diff --git a/src/plugins/genericprojectmanager/genericprojectfileseditor.cpp b/src/plugins/genericprojectmanager/genericprojectfileseditor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..789f13ba7ef097e5e866babb6c7d91fe52a27d09 --- /dev/null +++ b/src/plugins/genericprojectmanager/genericprojectfileseditor.cpp @@ -0,0 +1,135 @@ +#include "genericprojectfileseditor.h" +#include "genericprojectmanager.h" +#include "genericprojectconstants.h" + +#include <coreplugin/uniqueidmanager.h> +#include <coreplugin/editormanager/editormanager.h> + +#include <QtDebug> + +using namespace GenericProjectManager; +using namespace GenericProjectManager::Internal; + + +//////////////////////////////////////////////////////////////////////////////////////// +// ProjectFilesEditable +//////////////////////////////////////////////////////////////////////////////////////// +ProjectFilesFactory::ProjectFilesFactory(Manager *manager, + TextEditor::TextEditorActionHandler *handler) + : Core::IEditorFactory(manager), + _manager(manager), + _actionHandler(handler) +{ + _mimeTypes.append(QLatin1String(Constants::FILES_MIMETYPE)); + _mimeTypes.append(QLatin1String(Constants::INCLUDES_MIMETYPE)); + _mimeTypes.append(QLatin1String(Constants::CONFIG_MIMETYPE)); +} + +ProjectFilesFactory::~ProjectFilesFactory() +{ } + +Manager *ProjectFilesFactory::manager() const +{ return _manager; } + +Core::IEditor *ProjectFilesFactory::createEditor(QWidget *parent) +{ + ProjectFilesEditor *ed = new ProjectFilesEditor(parent, this, _actionHandler); + // ### initialize + return ed->editableInterface(); +} + +QStringList ProjectFilesFactory::mimeTypes() const +{ return _mimeTypes; } + +QString ProjectFilesFactory::kind() const +{ return QLatin1String(Constants::FILES_EDITOR); } + +Core::IFile *ProjectFilesFactory::open(const QString &fileName) +{ + Core::EditorManager *editorManager = Core::EditorManager::instance(); + + if (Core::IEditor *editor = editorManager->openEditor(fileName, kind())) + return editor->file(); + + return 0; +} + +//////////////////////////////////////////////////////////////////////////////////////// +// ProjectFilesEditable +//////////////////////////////////////////////////////////////////////////////////////// +ProjectFilesEditable::ProjectFilesEditable(ProjectFilesEditor *editor) + : TextEditor::BaseTextEditorEditable(editor) +{ + Core::UniqueIDManager *uidm = Core::UniqueIDManager::instance(); + _context << uidm->uniqueIdentifier(Constants::C_FILESEDITOR); +} + +ProjectFilesEditable::~ProjectFilesEditable() +{ } + +QList<int> ProjectFilesEditable::context() const +{ return _context; } + +const char *ProjectFilesEditable::kind() const +{ return Constants::FILES_EDITOR; } + +bool ProjectFilesEditable::duplicateSupported() const +{ return true; } + +Core::IEditor *ProjectFilesEditable::duplicate(QWidget *parent) +{ + ProjectFilesEditor *parentEditor = qobject_cast<ProjectFilesEditor *>(editor()); + ProjectFilesEditor *editor = new ProjectFilesEditor(parent, + parentEditor->factory(), + parentEditor->actionHandler()); + return editor->editableInterface(); + + +} + +//////////////////////////////////////////////////////////////////////////////////////// +// ProjectFilesEditor +//////////////////////////////////////////////////////////////////////////////////////// +ProjectFilesEditor::ProjectFilesEditor(QWidget *parent, ProjectFilesFactory *factory, + TextEditor::TextEditorActionHandler *handler) + : TextEditor::BaseTextEditor(parent), + _factory(factory), + _actionHandler(handler) +{ + Manager *manager = factory->manager(); + ProjectFilesDocument *doc = new ProjectFilesDocument(manager); + setBaseTextDocument(doc); +} + +ProjectFilesEditor::~ProjectFilesEditor() +{ } + +ProjectFilesFactory *ProjectFilesEditor::factory() const +{ return _factory; } + +TextEditor::TextEditorActionHandler *ProjectFilesEditor::actionHandler() const +{ return _actionHandler; } + +TextEditor::BaseTextEditorEditable *ProjectFilesEditor::createEditableInterface() +{ return new ProjectFilesEditable(this); } + +//////////////////////////////////////////////////////////////////////////////////////// +// ProjectFilesDocument +//////////////////////////////////////////////////////////////////////////////////////// +ProjectFilesDocument::ProjectFilesDocument(Manager *manager) + : _manager(manager) +{ + setMimeType(QLatin1String(Constants::FILES_MIMETYPE)); +} + +ProjectFilesDocument::~ProjectFilesDocument() +{ } + +bool ProjectFilesDocument::save(const QString &name) +{ + if (! BaseTextDocument::save(name)) + return false; + + _manager->notifyChanged(name); + return true; +} diff --git a/src/plugins/genericprojectmanager/genericprojectfileseditor.h b/src/plugins/genericprojectmanager/genericprojectfileseditor.h new file mode 100644 index 0000000000000000000000000000000000000000..14077aca5b738c244e5c9384c109ab5fa84751cb --- /dev/null +++ b/src/plugins/genericprojectmanager/genericprojectfileseditor.h @@ -0,0 +1,94 @@ +#ifndef GENERICPROJECTFILESEDITOR_H +#define GENERICPROJECTFILESEDITOR_H + +#include <texteditor/basetexteditor.h> +#include <texteditor/basetextdocument.h> + +#include <coreplugin/editormanager/ieditorfactory.h> + +namespace GenericProjectManager { +namespace Internal { + +class Manager; +class ProjectFilesEditable; +class ProjectFilesEditor; +class ProjectFilesDocument; +class ProjectFilesFactory; + +class ProjectFilesFactory: public Core::IEditorFactory +{ + Q_OBJECT + +public: + ProjectFilesFactory(Manager *manager, TextEditor::TextEditorActionHandler *handler); + virtual ~ProjectFilesFactory(); + + Manager *manager() const; + + virtual Core::IEditor *createEditor(QWidget *parent); + + virtual QStringList mimeTypes() const; + virtual QString kind() const; + virtual Core::IFile *open(const QString &fileName); + +private: + Manager *_manager; + TextEditor::TextEditorActionHandler *_actionHandler; + QStringList _mimeTypes; +}; + +class ProjectFilesEditable: public TextEditor::BaseTextEditorEditable +{ + Q_OBJECT + +public: + ProjectFilesEditable(ProjectFilesEditor *editor); + virtual ~ProjectFilesEditable(); + + virtual QList<int> context() const; + virtual const char *kind() const; + + virtual bool duplicateSupported() const; + virtual Core::IEditor *duplicate(QWidget *parent); + +private: + QList<int> _context; +}; + +class ProjectFilesEditor: public TextEditor::BaseTextEditor +{ + Q_OBJECT + +public: + ProjectFilesEditor(QWidget *parent, ProjectFilesFactory *factory, + TextEditor::TextEditorActionHandler *handler); + virtual ~ProjectFilesEditor(); + + ProjectFilesFactory *factory() const; + TextEditor::TextEditorActionHandler *actionHandler() const; + + virtual TextEditor::BaseTextEditorEditable *createEditableInterface(); + +private: + ProjectFilesFactory *_factory; + TextEditor::TextEditorActionHandler *_actionHandler; +}; + +class ProjectFilesDocument: public TextEditor::BaseTextDocument +{ + Q_OBJECT + +public: + ProjectFilesDocument(Manager *manager); + virtual ~ProjectFilesDocument(); + + virtual bool save(const QString &name); + +private: + Manager *_manager; +}; + +} // end of namespace Internal +} // end of namespace GenericProjectManager + +#endif // GENERICPROJECTFILESEDITOR_H diff --git a/src/plugins/genericprojectmanager/genericprojectmanager.cpp b/src/plugins/genericprojectmanager/genericprojectmanager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7714a8e5b368a5080c7a2bcdb255b17af914f041 --- /dev/null +++ b/src/plugins/genericprojectmanager/genericprojectmanager.cpp @@ -0,0 +1,88 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#include "genericprojectmanager.h" +#include "genericprojectconstants.h" +#include "genericproject.h" + +#include <coreplugin/icore.h> +#include <coreplugin/uniqueidmanager.h> +#include <projectexplorer/projectexplorerconstants.h> + +#include <QtDebug> + +using namespace GenericProjectManager::Internal; + +Manager::Manager() +{ + Core::UniqueIDManager *uidm = Core::UniqueIDManager::instance(); + _projectContext = uidm->uniqueIdentifier(GenericProjectManager::Constants::PROJECTCONTEXT); + _projectLanguage = uidm->uniqueIdentifier(ProjectExplorer::Constants::LANG_CXX); +} + +Manager::~Manager() +{ } + +int Manager::projectContext() const +{ return _projectContext; } + +int Manager::projectLanguage() const +{ return _projectLanguage; } + +QString Manager::mimeType() const +{ return QLatin1String(Constants::GENERICMIMETYPE); } + +ProjectExplorer::Project *Manager::openProject(const QString &fileName) +{ + QFileInfo fileInfo(fileName); + + if (fileInfo.isFile()) { + GenericProject *project = new GenericProject(this, fileName); + return project; + } + + return 0; +} + +void Manager::registerProject(GenericProject *project) +{ _projects.append(project); } + +void Manager::unregisterProject(GenericProject *project) +{ _projects.removeAll(project); } + +void Manager::notifyChanged(const QString &fileName) +{ + foreach (GenericProject *project, _projects) { + if (fileName == project->filesFileName() || + fileName == project->includesFileName() || + fileName == project->configFileName()) + project->refresh(); + } +} + diff --git a/src/plugins/genericprojectmanager/genericprojectmanager.h b/src/plugins/genericprojectmanager/genericprojectmanager.h new file mode 100644 index 0000000000000000000000000000000000000000..608313e13f028f513caaed7b6c3e4a975644211e --- /dev/null +++ b/src/plugins/genericprojectmanager/genericprojectmanager.h @@ -0,0 +1,68 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#ifndef GENERICPROJECTMANAGER_H +#define GENERICPROJECTMANAGER_H + +#include <projectexplorer/iprojectmanager.h> + +namespace GenericProjectManager { +namespace Internal { + +class GenericProject; + +class Manager: public ProjectExplorer::IProjectManager +{ + Q_OBJECT + +public: + Manager(); + virtual ~Manager(); + + virtual int projectContext() const; + virtual int projectLanguage() const; + + virtual QString mimeType() const; + virtual ProjectExplorer::Project *openProject(const QString &fileName); + + void notifyChanged(const QString &fileName); + + void registerProject(GenericProject *project); + void unregisterProject(GenericProject *project); + +private: + int _projectContext; + int _projectLanguage; + QList<GenericProject *> _projects; +}; + +} // namespace Internal +} // namespace GenericProjectManager + +#endif // GENERICPROJECTMANAGER_H diff --git a/src/plugins/genericprojectmanager/genericprojectmanager.pro b/src/plugins/genericprojectmanager/genericprojectmanager.pro new file mode 100644 index 0000000000000000000000000000000000000000..fa8bb3a987e1ad85cfbe402d9e79a8b3baf8feb3 --- /dev/null +++ b/src/plugins/genericprojectmanager/genericprojectmanager.pro @@ -0,0 +1,22 @@ +TEMPLATE = lib +TARGET = GenericProjectManager +include(../../qworkbenchplugin.pri) +include(genericprojectmanager_dependencies.pri) +HEADERS = genericproject.h \ + genericprojectplugin.h \ + genericprojectmanager.h \ + genericprojectconstants.h \ + genericprojectnodes.h \ + genericprojectwizard.h \ + genericprojectfileseditor.h \ + pkgconfigtool.h \ + makestep.h +SOURCES = genericproject.cpp \ + genericprojectplugin.cpp \ + genericprojectmanager.cpp \ + genericprojectnodes.cpp \ + genericprojectwizard.cpp \ + genericprojectfileseditor.cpp \ + pkgconfigtool.cpp \ + makestep.cpp +RESOURCES += genericproject.qrc diff --git a/src/plugins/genericprojectmanager/genericprojectmanager_dependencies.pri b/src/plugins/genericprojectmanager/genericprojectmanager_dependencies.pri new file mode 100644 index 0000000000000000000000000000000000000000..80118ad122efeb8ce51462307d35e13a66845e9f --- /dev/null +++ b/src/plugins/genericprojectmanager/genericprojectmanager_dependencies.pri @@ -0,0 +1,4 @@ +include(../../plugins/projectexplorer/projectexplorer.pri) +include(../../plugins/cpptools/cpptools.pri) +include(../../plugins/cppeditor/cppeditor.pri) +include(../../plugins/texteditor/texteditor.pri) diff --git a/src/plugins/genericprojectmanager/genericprojectnodes.cpp b/src/plugins/genericprojectmanager/genericprojectnodes.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cdd82f951b19416bcc0d7c1c517a3ba3116e4493 --- /dev/null +++ b/src/plugins/genericprojectmanager/genericprojectnodes.cpp @@ -0,0 +1,208 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#include "genericprojectnodes.h" +#include "genericproject.h" + +#include <projectexplorer/projectexplorer.h> + +#include <QDir> +#include <QFileInfo> +#include <QSettings> +#include <QtDebug> + +using namespace GenericProjectManager; +using namespace GenericProjectManager::Internal; + +GenericProjectNode::GenericProjectNode(GenericProject *project, Core::IFile *projectFile) + : ProjectExplorer::ProjectNode(QFileInfo(projectFile->fileName()).absolutePath()), + _project(project), + _projectFile(projectFile) +{} + +GenericProjectNode::~GenericProjectNode() +{ } + +Core::IFile *GenericProjectNode::projectFile() const +{ return _projectFile; } + +QString GenericProjectNode::projectFilePath() const +{ return _projectFile->fileName(); } + +void GenericProjectNode::refresh() +{ + using namespace ProjectExplorer; + + // remove the existing nodes. + removeFileNodes(fileNodes(), this); + removeFolderNodes(subFolderNodes(), this); + + ProjectExplorerPlugin::instance()->setCurrentNode(0); // ### remove me + + FileNode *projectFilesNode = new FileNode(_project->filesFileName(), + ProjectFileType, + /* generated = */ false); + + FileNode *projectIncludesNode = new FileNode(_project->includesFileName(), + ProjectFileType, + /* generated = */ false); + + FileNode *projectConfigNode = new FileNode(_project->configFileName(), + ProjectFileType, + /* generated = */ false); + + QStringList files = _project->files(); + files.removeAll(_project->filesFileName()); + files.removeAll(_project->includesFileName()); + files.removeAll(_project->configFileName()); + + addFileNodes(QList<FileNode *>() + << projectFilesNode + << projectIncludesNode + << projectConfigNode, + this); + + QStringList filePaths; + QHash<QString, QStringList> filesInPath; + + foreach (const QString &absoluteFileName, files) { + QFileInfo fileInfo(absoluteFileName); + const QString absoluteFilePath = fileInfo.path(); + + if (! absoluteFilePath.startsWith(path())) + continue; // `file' is not part of the project. + + const QString relativeFilePath = absoluteFilePath.mid(path().length() + 1); + + if (! filePaths.contains(relativeFilePath)) + filePaths.append(relativeFilePath); + + filesInPath[relativeFilePath].append(absoluteFileName); + } + + foreach (const QString &filePath, filePaths) { + FolderNode *folder = findOrCreateFolderByName(filePath); + + QList<FileNode *> fileNodes; + foreach (const QString &file, filesInPath.value(filePath)) { + FileType fileType = SourceType; // ### FIXME + FileNode *fileNode = new FileNode(file, fileType, /*generated = */ false); + fileNodes.append(fileNode); + } + + addFileNodes(fileNodes, folder); + } + + _folderByName.clear(); +} + +ProjectExplorer::FolderNode *GenericProjectNode::findOrCreateFolderByName(const QStringList &components, int end) +{ + if (! end) + return 0; + + QString folderName; + for (int i = 0; i < end; ++i) { + folderName.append(components.at(i)); + folderName += QLatin1Char('/'); // ### FIXME + } + + const QString component = components.at(end - 1); + + if (component.isEmpty()) + return this; + + else if (FolderNode *folder = _folderByName.value(folderName)) + return folder; + + FolderNode *folder = new FolderNode(component); + _folderByName.insert(folderName, folder); + + FolderNode *parent = findOrCreateFolderByName(components, end - 1); + if (! parent) + parent = this; + addFolderNodes(QList<FolderNode*>() << folder, parent); + + return folder; +} + +ProjectExplorer::FolderNode *GenericProjectNode::findOrCreateFolderByName(const QString &filePath) +{ + QStringList components = filePath.split(QLatin1Char('/')); + return findOrCreateFolderByName(components, components.length()); +} + +bool GenericProjectNode::hasTargets() const +{ + return true; +} + +QList<ProjectExplorer::ProjectNode::ProjectAction> GenericProjectNode::supportedActions() const +{ + return QList<ProjectAction>(); +} + +bool GenericProjectNode::addSubProjects(const QStringList &proFilePaths) +{ + Q_UNUSED(proFilePaths); + return false; +} + +bool GenericProjectNode::removeSubProjects(const QStringList &proFilePaths) +{ + Q_UNUSED(proFilePaths); + return false; +} + +bool GenericProjectNode::addFiles(const ProjectExplorer::FileType fileType, + const QStringList &filePaths, QStringList *notAdded) +{ + Q_UNUSED(fileType); + Q_UNUSED(filePaths); + Q_UNUSED(notAdded); + return false; +} + +bool GenericProjectNode::removeFiles(const ProjectExplorer::FileType fileType, + const QStringList &filePaths, QStringList *notRemoved) +{ + Q_UNUSED(fileType); + Q_UNUSED(filePaths); + Q_UNUSED(notRemoved); + return false; +} + +bool GenericProjectNode::renameFile(const ProjectExplorer::FileType fileType, + const QString &filePath, const QString &newFilePath) +{ + Q_UNUSED(fileType); + Q_UNUSED(filePath); + Q_UNUSED(newFilePath); + return false; +} diff --git a/src/plugins/genericprojectmanager/genericprojectnodes.h b/src/plugins/genericprojectmanager/genericprojectnodes.h new file mode 100644 index 0000000000000000000000000000000000000000..d31a14dbd625364b0d5f0d000b4ce1e2505b2b38 --- /dev/null +++ b/src/plugins/genericprojectmanager/genericprojectnodes.h @@ -0,0 +1,87 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#ifndef GENERICPROJECTNODE_H +#define GENERICPROJECTNODE_H + +#include <coreplugin/ifile.h> +#include <projectexplorer/projectnodes.h> +#include <QStringList> +#include <QHash> + +namespace GenericProjectManager { +namespace Internal { + +class GenericProject; + +class GenericProjectNode : public ProjectExplorer::ProjectNode +{ +public: + GenericProjectNode(GenericProject *project, Core::IFile *projectFile); + virtual ~GenericProjectNode(); + + Core::IFile *projectFile() const; + QString projectFilePath() const; + + virtual bool hasTargets() const; + + virtual QList<ProjectExplorer::ProjectNode::ProjectAction> supportedActions() const; + + virtual bool addSubProjects(const QStringList &proFilePaths); + virtual bool removeSubProjects(const QStringList &proFilePaths); + + virtual bool addFiles(const ProjectExplorer::FileType fileType, + const QStringList &filePaths, + QStringList *notAdded = 0); + + virtual bool removeFiles(const ProjectExplorer::FileType fileType, + const QStringList &filePaths, + QStringList *notRemoved = 0); + + virtual bool renameFile(const ProjectExplorer::FileType fileType, + const QString &filePath, + const QString &newFilePath); + + + void refresh(); + +private: + FolderNode *findOrCreateFolderByName(const QString &filePath); + FolderNode *findOrCreateFolderByName(const QStringList &components, int end); + +private: + GenericProject *_project; + Core::IFile *_projectFile; + QHash<QString, FolderNode *> _folderByName; +}; + +} // namespace Internal +} // namespace GenericProjectManager + +#endif // GENERICPROJECTNODE_H diff --git a/src/plugins/genericprojectmanager/genericprojectplugin.cpp b/src/plugins/genericprojectmanager/genericprojectplugin.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2fe1e713910079d402a5ace5f4f4da6c99cbf14d --- /dev/null +++ b/src/plugins/genericprojectmanager/genericprojectplugin.cpp @@ -0,0 +1,88 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#include "genericprojectplugin.h" +#include "genericprojectmanager.h" +#include "genericprojectwizard.h" +#include "genericprojectconstants.h" +#include "genericprojectfileseditor.h" +#include "makestep.h" + +#include <coreplugin/icore.h> +#include <coreplugin/mimedatabase.h> + +#include <texteditor/texteditoractionhandler.h> + +#include <QtCore/QtPlugin> +#include <QtCore/QDebug> + +using namespace GenericProjectManager; +using namespace GenericProjectManager::Internal; + +GenericProjectPlugin::GenericProjectPlugin() + : _projectFilesEditorFactory(0) +{ } + +GenericProjectPlugin::~GenericProjectPlugin() +{ + removeObject(_projectFilesEditorFactory); + delete _projectFilesEditorFactory; +} + +bool GenericProjectPlugin::initialize(const QStringList &, QString *errorMessage) +{ + using namespace Core; + + ICore *core = ICore::instance(); + Core::MimeDatabase *mimeDB = core->mimeDatabase(); + + const QLatin1String mimetypesXml(":genericproject/GenericProject.mimetypes.xml"); + + if (! mimeDB->addMimeTypes(mimetypesXml, errorMessage)) + return false; + + Manager *manager = new Manager; + + TextEditor::TextEditorActionHandler *actionHandler = + new TextEditor::TextEditorActionHandler(Constants::C_FILESEDITOR); + + _projectFilesEditorFactory = new ProjectFilesFactory(manager, actionHandler); + addObject(_projectFilesEditorFactory); + + addAutoReleasedObject(manager); + addAutoReleasedObject(new MakeBuildStepFactory); + addAutoReleasedObject(new GenericProjectWizard); + + return true; +} + +void GenericProjectPlugin::extensionsInitialized() +{ } + +Q_EXPORT_PLUGIN(GenericProjectPlugin) diff --git a/src/plugins/genericprojectmanager/genericprojectplugin.h b/src/plugins/genericprojectmanager/genericprojectplugin.h new file mode 100644 index 0000000000000000000000000000000000000000..e78d975e21f62db0be487aef6b9bedfd516415cf --- /dev/null +++ b/src/plugins/genericprojectmanager/genericprojectplugin.h @@ -0,0 +1,60 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#ifndef GENERICPROJECTPLUGIN_H +#define GENERICPROJECTPLUGIN_H + +#include <extensionsystem/iplugin.h> + +#include <QtCore/QObject> + +namespace GenericProjectManager { +namespace Internal { + +class ProjectFilesFactory; + +class GenericProjectPlugin: public ExtensionSystem::IPlugin +{ + Q_OBJECT + +public: + GenericProjectPlugin(); + ~GenericProjectPlugin(); + + virtual bool initialize(const QStringList &arguments, QString *errorString); + virtual void extensionsInitialized(); + +private: + ProjectFilesFactory *_projectFilesEditorFactory; +}; + +} // namespace Internal +} // namespace GenericProject + +#endif // GENERICPROJECTPLUGIN_H diff --git a/src/plugins/genericprojectmanager/genericprojectwizard.cpp b/src/plugins/genericprojectmanager/genericprojectwizard.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4db902a2323be86ada73c3abc038f5dd8421def2 --- /dev/null +++ b/src/plugins/genericprojectmanager/genericprojectwizard.cpp @@ -0,0 +1,332 @@ +#include "genericprojectwizard.h" + +#include <coreplugin/icore.h> +#include <coreplugin/mimedatabase.h> +#include <projectexplorer/projectexplorer.h> + +#include <utils/pathchooser.h> + +#include <QtCore/QDir> +#include <QtCore/QtDebug> + +#include <QtGui/QWizard> +#include <QtGui/QFormLayout> +#include <QtGui/QListView> +#include <QtGui/QTreeView> +#include <QtGui/QDirModel> + +using namespace GenericProjectManager::Internal; +using namespace Core::Utils; + +namespace { + +class DirModel: public QDirModel +{ +public: + DirModel(QObject *parent) + : QDirModel(parent) + { setFilter(QDir::Dirs | QDir::NoDotAndDotDot); } + + virtual ~DirModel() + { } + +public: + virtual int columnCount(const QModelIndex &) const + { return 1; } + + virtual Qt::ItemFlags flags(const QModelIndex &index) const + { return QDirModel::flags(index) | Qt::ItemIsUserCheckable; } + + virtual QVariant data(const QModelIndex &index, int role) const + { + if (index.column() == 0 && role == Qt::CheckStateRole) { + if (_selectedPaths.contains(index)) + return Qt::Checked; + + return Qt::Unchecked; + } + + return QDirModel::data(index, role); + } + + virtual bool setData(const QModelIndex &index, const QVariant &value, int role) + { + if (index.column() == 0 && role == Qt::CheckStateRole) { + if (value.toBool()) + _selectedPaths.insert(index); + else + _selectedPaths.remove(index); + + return true; + } + + return QDirModel::setData(index, value, role); + } + + void clearSelectedPaths() + { _selectedPaths.clear(); } + + QSet<QString> selectedPaths() const + { + QSet<QString> paths; + + foreach (const QModelIndex &index, _selectedPaths) + paths.insert(filePath(index)); + + return paths; + } + +private: + QSet<QModelIndex> _selectedPaths; +}; + +} // end of anonymous namespace + + +////////////////////////////////////////////////////////////////////////////// +// GenericProjectWizardDialog +////////////////////////////////////////////////////////////////////////////// + + +GenericProjectWizardDialog::GenericProjectWizardDialog(QWidget *parent) + : QWizard(parent) +{ + setWindowTitle(tr("Import Existing Project")); + + // first page + QWizardPage *firstPage = new QWizardPage; + firstPage->setTitle(tr("Project")); + + QFormLayout *layout = new QFormLayout(firstPage); + _pathChooser = new PathChooser; + layout->addRow(tr("Source Directory:"), _pathChooser); + + _firstPageId = addPage(firstPage); + +#if 0 + // second page + QWizardPage *secondPage = new QWizardPage; + secondPage->setTitle(tr("Second Page Title")); + + QFormLayout *secondPageLayout = new QFormLayout(secondPage); + + _dirView = new QTreeView; + _dirModel = new DirModel(this); + _dirView->setModel(_dirModel); + + Core::ICore *core = Core::ICore::instance(); + Core::MimeDatabase *mimeDatabase = core->mimeDatabase(); + + const QStringList suffixes = mimeDatabase->suffixes(); + + QStringList nameFilters; + foreach (const QString &suffix, suffixes) { + QString nameFilter; + nameFilter.append(QLatin1String("*.")); + nameFilter.append(suffix); + nameFilters.append(nameFilter); + } + + _filesView = new QListView; + _filesModel = new QDirModel(this); + _filesModel->setNameFilters(nameFilters); + _filesModel->setFilter(QDir::Files); + + connect(_dirView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), + this, SLOT(updateFilesView(QModelIndex,QModelIndex))); + + secondPageLayout->addRow(_dirView); + secondPageLayout->addRow(_filesView); + + _secondPageId = addPage(secondPage); +#endif +} + +GenericProjectWizardDialog::~GenericProjectWizardDialog() +{ } + +QString GenericProjectWizardDialog::path() const +{ return _pathChooser->path(); } + +void GenericProjectWizardDialog::updateFilesView(const QModelIndex ¤t, + const QModelIndex &) +{ + if (! current.isValid()) + _filesView->setModel(0); + + else { + const QString selectedPath = _dirModel->filePath(current); + + if (! _filesView->model()) + _filesView->setModel(_filesModel); + + _filesView->setRootIndex(_filesModel->index(selectedPath)); + } +} + +void GenericProjectWizardDialog::initializePage(int id) +{ + if (id == _secondPageId) { + using namespace Core::Utils; + + const QString projectPath = _pathChooser->path(); + + QDirModel *dirModel = qobject_cast<QDirModel *>(_dirView->model()); + _dirView->setRootIndex(dirModel->index(projectPath)); + } +} + +bool GenericProjectWizardDialog::validateCurrentPage() +{ + using namespace Core::Utils; + + if (currentId() == _firstPageId) { + return ! _pathChooser->path().isEmpty(); + + } else if (currentId() == _secondPageId) { + return true; + } + + return QWizard::validateCurrentPage(); +} + +GenericProjectWizard::GenericProjectWizard() + : Core::BaseFileWizard(parameters()) +{ } + +GenericProjectWizard::~GenericProjectWizard() +{ } + +Core::BaseFileWizardParameters GenericProjectWizard::parameters() +{ + static Core::BaseFileWizardParameters parameters(ProjectWizard); + parameters.setIcon(QIcon(":/wizards/images/console.png")); + parameters.setName(tr("Existing Project")); + parameters.setDescription(tr("Import Existing Project")); + parameters.setCategory(QLatin1String("Projects")); + parameters.setTrCategory(tr("Projects")); + return parameters; +} + +QWizard *GenericProjectWizard::createWizardDialog(QWidget *parent, + const QString &defaultPath, + const WizardPageList &extensionPages) const +{ + GenericProjectWizardDialog *wizard = new GenericProjectWizardDialog(parent); + setupWizard(wizard); + + foreach (QWizardPage *p, extensionPages) + wizard->addPage(p); + + return wizard; +} + +void GenericProjectWizard::getFileList(const QDir &dir, const QString &projectRoot, + const QStringList &suffixes, + QStringList *files, QStringList *paths) const +{ + const QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | + QDir::Dirs | + QDir::NoDotAndDotDot | + QDir::NoSymLinks); + + foreach (const QFileInfo &fileInfo, fileInfoList) { + QString filePath = fileInfo.absoluteFilePath(); + filePath = filePath.mid(projectRoot.length() + 1); + + if (fileInfo.isDir() && isValidDir(fileInfo)) { + getFileList(QDir(fileInfo.absoluteFilePath()), projectRoot, + suffixes, files, paths); + + if (! paths->contains(filePath)) + paths->append(filePath); + } + + else if (suffixes.contains(fileInfo.suffix())) + files->append(filePath); + } +} + +bool GenericProjectWizard::isValidDir(const QFileInfo &fileInfo) const +{ + const QString fileName = fileInfo.fileName(); + const QString suffix = fileInfo.suffix(); + + if (fileName.startsWith(QLatin1Char('.'))) + return false; + + else if (fileName == QLatin1String("CVS")) + return false; + + // ### user include/exclude + + return true; +} + +Core::GeneratedFiles GenericProjectWizard::generateFiles(const QWizard *w, + QString *errorMessage) const +{ + const GenericProjectWizardDialog *wizard = qobject_cast<const GenericProjectWizardDialog *>(w); + const QString projectPath = wizard->path(); + const QDir dir(projectPath); + const QString projectName = QFileInfo(projectPath).baseName(); + const QString creatorFileName = QFileInfo(dir, projectName + QLatin1String(".creator")).absoluteFilePath(); + const QString filesFileName = QFileInfo(dir, projectName + QLatin1String(".files")).absoluteFilePath(); + const QString includesFileName = QFileInfo(dir, projectName + QLatin1String(".includes")).absoluteFilePath(); + const QString configFileName = QFileInfo(dir, projectName + QLatin1String(".config")).absoluteFilePath(); + + Core::ICore *core = Core::ICore::instance(); + Core::MimeDatabase *mimeDatabase = core->mimeDatabase(); + + const QStringList suffixes = mimeDatabase->suffixes(); + + QStringList sources, paths; + getFileList(dir, projectPath, suffixes, &sources, &paths); + + Core::MimeType headerTy = mimeDatabase->findByType(QLatin1String("text/x-chdr")); + + QStringList nameFilters; + foreach (const QRegExp &rx, headerTy.globPatterns()) + nameFilters.append(rx.pattern()); + + QStringList includePaths; + foreach (const QString &path, paths) { + QFileInfo fileInfo(dir, path); + QDir thisDir(fileInfo.absoluteFilePath()); + + if (! thisDir.entryList(nameFilters, QDir::Files).isEmpty()) + includePaths.append(path); + } + + Core::GeneratedFile generatedCreatorFile(creatorFileName); + generatedCreatorFile.setContents(QLatin1String("[General]\n")); + + Core::GeneratedFile generatedFilesFile(filesFileName); + generatedFilesFile.setContents(sources.join(QLatin1String("\n"))); + + Core::GeneratedFile generatedIncludesFile(includesFileName); + generatedIncludesFile.setContents(includePaths.join(QLatin1String("\n"))); + + Core::GeneratedFile generatedConfigFile(configFileName); + generatedConfigFile.setContents(QLatin1String("// ADD PREDEFINED MACROS HERE!\n")); + + Core::GeneratedFiles files; + files.append(generatedFilesFile); + files.append(generatedIncludesFile); + files.append(generatedConfigFile); + files.append(generatedCreatorFile); + + return files; +} + +bool GenericProjectWizard::postGenerateFiles(const Core::GeneratedFiles &l, QString *errorMessage) +{ + // Post-Generate: Open the project + const QString proFileName = l.back().path(); + if (!ProjectExplorer::ProjectExplorerPlugin::instance()->openProject(proFileName)) { + *errorMessage = tr("The project %1 could not be opened.").arg(proFileName); + return false; + } + return true; +} + diff --git a/src/plugins/genericprojectmanager/genericprojectwizard.h b/src/plugins/genericprojectmanager/genericprojectwizard.h new file mode 100644 index 0000000000000000000000000000000000000000..6c3f87e16a6dd427ece44015689729739e325f32 --- /dev/null +++ b/src/plugins/genericprojectmanager/genericprojectwizard.h @@ -0,0 +1,83 @@ +#ifndef GENERICPROJECTWIZARD_H +#define GENERICPROJECTWIZARD_H + +#include <coreplugin/basefilewizard.h> +#include <utils/pathchooser.h> +#include <QWizard> + +QT_BEGIN_NAMESPACE +class QListView; +class QTreeView; +class QDirModel; +class QModelIndex; +class QDir; +class QStringList; +class QFileInfo; +QT_END_NAMESPACE + +namespace GenericProjectManager { +namespace Internal { + +class GenericProjectWizardDialog: public QWizard +{ + Q_OBJECT + +public: + GenericProjectWizardDialog(QWidget *parent = 0); + virtual ~GenericProjectWizardDialog(); + + QString path() const; + +private Q_SLOTS: + void updateFilesView(const QModelIndex ¤t, + const QModelIndex &previous); + +protected: + virtual void initializePage(int id); + virtual bool validateCurrentPage(); + +private: + int _firstPageId; + int _secondPageId; + + Core::Utils::PathChooser *_pathChooser; + + QTreeView *_dirView; + QDirModel *_dirModel; + + QListView *_filesView; + QDirModel *_filesModel; +}; + +class GenericProjectWizard : public Core::BaseFileWizard +{ + Q_OBJECT + +public: + GenericProjectWizard(); + virtual ~GenericProjectWizard(); + + static Core::BaseFileWizardParameters parameters(); + +protected: + virtual QWizard *createWizardDialog(QWidget *parent, + const QString &defaultPath, + const WizardPageList &extensionPages) const; + + virtual Core::GeneratedFiles generateFiles(const QWizard *w, + QString *errorMessage) const; + + virtual bool postGenerateFiles(const Core::GeneratedFiles &l, QString *errorMessage); + + bool isValidDir(const QFileInfo &fileInfo) const; + + void getFileList(const QDir &dir, const QString &projectRoot, + const QStringList &suffixes, + QStringList *files, + QStringList *paths) const; +}; + +} // end of namespace Internal +} // end of namespace GenericProjectManager + +#endif // GENERICPROJECTWIZARD_H diff --git a/src/plugins/genericprojectmanager/makestep.cpp b/src/plugins/genericprojectmanager/makestep.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ee0d3c67540bece09cf89dbe1bdbd55ac57f088f --- /dev/null +++ b/src/plugins/genericprojectmanager/makestep.cpp @@ -0,0 +1,301 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#include "makestep.h" +#include "genericprojectconstants.h" +#include "genericproject.h" +#include <extensionsystem/pluginmanager.h> + +#include <utils/qtcassert.h> +#include <QtGui/QFormLayout> +#include <QtGui/QGroupBox> +#include <QtGui/QCheckBox> +#include <QtGui/QLineEdit> +#include <QtGui/QListWidget> + +namespace { +bool debug = false; +} + + +using namespace GenericProjectManager; +using namespace GenericProjectManager::Internal; + +MakeStep::MakeStep(GenericProject *pro) + : AbstractProcessStep(pro), m_pro(pro), m_buildParser(0) +{ +} + +MakeStep::~MakeStep() +{ + delete m_buildParser; + m_buildParser = 0; +} + +bool MakeStep::init(const QString &buildConfiguration) +{ + // TODO figure out the correct build parser + delete m_buildParser; + m_buildParser = 0; + + const QString buildParser = m_pro->buildParser(buildConfiguration); + qDebug() << "*** build parser:" << buildParser; + + QList<ProjectExplorer::IBuildParserFactory *> buildParserFactories = + ExtensionSystem::PluginManager::instance()->getObjects<ProjectExplorer::IBuildParserFactory>(); + + foreach (ProjectExplorer::IBuildParserFactory *factory, buildParserFactories) { + if (factory->canCreate(buildParser)) { + m_buildParser = factory->create(buildParser); + break; + } + } + + if (m_buildParser) { + connect(m_buildParser, SIGNAL(addToOutputWindow(const QString &)), + this, SIGNAL(addToOutputWindow(const QString &)), + Qt::DirectConnection); + connect(m_buildParser, SIGNAL(addToTaskWindow(const QString &, int, int, const QString &)), + this, SLOT(slotAddToTaskWindow(const QString &, int, int, const QString &)), + Qt::DirectConnection); + connect(m_buildParser, SIGNAL(enterDirectory(const QString &)), + this, SLOT(addDirectory(const QString &)), + Qt::DirectConnection); + connect(m_buildParser, SIGNAL(leaveDirectory(const QString &)), + this, SLOT(removeDirectory(const QString &)), + Qt::DirectConnection); + } + + m_openDirectories.clear(); + addDirectory(m_pro->buildDirectory(buildConfiguration)); + + setEnabled(buildConfiguration, true); + setWorkingDirectory(buildConfiguration, m_pro->buildDirectory(buildConfiguration)); +#ifdef Q_OS_WIN + setCommand(buildConfiguration, "mingw32-make"); +#else // Q_OS_WIN + setCommand(buildConfiguration, "make"); // TODO give full path here? +#endif // Q_OS_WIN + setArguments(buildConfiguration, value(buildConfiguration, "buildTargets").toStringList()); // TODO + setEnvironment(buildConfiguration, m_pro->environment(buildConfiguration)); + return AbstractProcessStep::init(buildConfiguration); +} + +void MakeStep::run(QFutureInterface<bool> &fi) +{ + AbstractProcessStep::run(fi); +} + +QString MakeStep::name() +{ + return Constants::MAKESTEP; +} + +QString MakeStep::displayName() +{ + return "Make"; +} + +ProjectExplorer::BuildStepConfigWidget *MakeStep::createConfigWidget() +{ + return new MakeBuildStepConfigWidget(this); +} + +bool MakeStep::immutable() const +{ + return true; +} + +void MakeStep::stdOut(const QString &line) +{ + if (m_buildParser) + m_buildParser->stdOutput(line); + AbstractProcessStep::stdOut(line); +} + +void MakeStep::stdError(const QString &line) +{ + if (m_buildParser) + m_buildParser->stdError(line); + AbstractProcessStep::stdError(line); +} + +void MakeStep::slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description) +{ + QString filePath = fn; + if (!filePath.isEmpty() && !QDir::isAbsolutePath(filePath)) { + // We have no save way to decide which file in which subfolder + // is meant. Therefore we apply following heuristics: + // 1. Search for unique file in directories currently indicated as open by GNU make + // (Enter directory xxx, Leave directory xxx...) + current directory + // 3. Check if file is unique in whole project + // 4. Otherwise give up + + filePath = filePath.trimmed(); + + QList<QFileInfo> possibleFiles; + foreach (const QString &dir, m_openDirectories) { + QFileInfo candidate(dir + QLatin1Char('/') + filePath); + if (debug) + qDebug() << "Checking path " << candidate.filePath(); + if (candidate.exists() + && !possibleFiles.contains(candidate)) { + if (debug) + qDebug() << candidate.filePath() << "exists!"; + possibleFiles << candidate; + } + } + if (possibleFiles.count() == 0) { + if (debug) + qDebug() << "No success. Trying all files in project ..."; + QString fileName = QFileInfo(filePath).fileName(); + foreach (const QString &file, project()->files(ProjectExplorer::Project::AllFiles)) { + QFileInfo candidate(file); + if (candidate.fileName() == fileName) { + if (debug) + qDebug() << "Found " << file; + possibleFiles << candidate; + } + } + } + if (possibleFiles.count() == 1) + filePath = possibleFiles.first().filePath(); + else + qWarning() << "Could not find absolute location of file " << filePath; + } + emit addToTaskWindow(filePath, type, linenumber, description); +} + +void MakeStep::addDirectory(const QString &dir) +{ + if (!m_openDirectories.contains(dir)) + m_openDirectories.insert(dir); +} + +void MakeStep::removeDirectory(const QString &dir) +{ + if (m_openDirectories.contains(dir)) + m_openDirectories.remove(dir); +} + + +GenericProject *MakeStep::project() const +{ + return m_pro; +} + +bool MakeStep::buildsTarget(const QString &buildConfiguration, const QString &target) const +{ + return value(buildConfiguration, "buildTargets").toStringList().contains(target); +} + +void MakeStep::setBuildTarget(const QString &buildConfiguration, const QString &target, bool on) +{ + QStringList old = value(buildConfiguration, "buildTargets").toStringList(); + if (on && !old.contains(target)) + setValue(buildConfiguration, "buildTargets", old << target); + else if(!on && old.contains(target)) + setValue(buildConfiguration, "buildTargets", old.removeOne(target)); +} + +// +// GenericBuildStepConfigWidget +// +MakeBuildStepConfigWidget::MakeBuildStepConfigWidget(MakeStep *makeStep) + : m_makeStep(makeStep) +{ + QFormLayout *fl = new QFormLayout(this); + setLayout(fl); + + m_targetsList = new QListWidget; + fl->addRow("Targets:", m_targetsList); + + // TODO update this list also on rescans of the GenericLists.txt + GenericProject *pro = m_makeStep->project(); + foreach(const QString& target, pro->targets()) { + QListWidgetItem *item = new QListWidgetItem(target, m_targetsList); + item->setFlags(item->flags() | Qt::ItemIsUserCheckable); + item->setCheckState(Qt::Unchecked); + } + connect(m_targetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*))); +} + +void MakeBuildStepConfigWidget::itemChanged(QListWidgetItem *item) +{ + m_makeStep->setBuildTarget(m_buildConfiguration, item->text(), item->checkState() & Qt::Checked); +} + +QString MakeBuildStepConfigWidget::displayName() const +{ + return "Make"; +} + +void MakeBuildStepConfigWidget::init(const QString &buildConfiguration) +{ + // TODO + + // disconnect to make the changes to the items + disconnect(m_targetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*))); + m_buildConfiguration = buildConfiguration; + int count = m_targetsList->count(); + for(int i = 0; i < count; ++i) { + QListWidgetItem *item = m_targetsList->item(i); + item->setCheckState(m_makeStep->buildsTarget(buildConfiguration, item->text()) ? Qt::Checked : Qt::Unchecked); + } + // and connect again + connect(m_targetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*))); +} + +// +// MakeBuildStepFactory +// + +bool MakeBuildStepFactory::canCreate(const QString &name) const +{ + return (Constants::MAKESTEP == name); +} + +ProjectExplorer::BuildStep *MakeBuildStepFactory::create(ProjectExplorer::Project *project, const QString &name) const +{ + Q_ASSERT(name == Constants::MAKESTEP); + GenericProject *pro = qobject_cast<GenericProject *>(project); + Q_ASSERT(pro); + return new MakeStep(pro); +} + +QStringList MakeBuildStepFactory::canCreateForProject(ProjectExplorer::Project * /* pro */) const +{ + return QStringList(); +} + +QString MakeBuildStepFactory::displayNameForName(const QString & /* name */) const +{ + return "Make"; +} + diff --git a/src/plugins/genericprojectmanager/makestep.h b/src/plugins/genericprojectmanager/makestep.h new file mode 100644 index 0000000000000000000000000000000000000000..8841c5ebf464777a8e92d2ef2979c8f2e3906231 --- /dev/null +++ b/src/plugins/genericprojectmanager/makestep.h @@ -0,0 +1,102 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#ifndef MAKESTEP_H +#define MAKESTEP_H + +#include <projectexplorer/abstractprocessstep.h> + +QT_BEGIN_NAMESPACE +class QLineEdit; +class QListWidget; +class QListWidgetItem; +QT_END_NAMESPACE + +namespace GenericProjectManager { +namespace Internal { + +class GenericProject; + +class MakeStep : public ProjectExplorer::AbstractProcessStep +{ + Q_OBJECT +public: + MakeStep(GenericProject *pro); + ~MakeStep(); + virtual bool init(const QString &buildConfiguration); + + virtual void run(QFutureInterface<bool> &fi); + + virtual QString name(); + virtual QString displayName(); + virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget(); + virtual bool immutable() const; + GenericProject *project() const; + bool buildsTarget(const QString &buildConfiguration, const QString &target) const; + void setBuildTarget(const QString &buildConfiguration, const QString &target, bool on); +private slots: + void slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description); + void addDirectory(const QString &dir); + void removeDirectory(const QString &dir); +protected: + virtual void stdOut(const QString &line); + virtual void stdError(const QString &line); +private: + GenericProject *m_pro; + ProjectExplorer::BuildParserInterface *m_buildParser; + QSet<QString> m_openDirectories; +}; + +class MakeBuildStepConfigWidget :public ProjectExplorer::BuildStepConfigWidget +{ + Q_OBJECT +public: + MakeBuildStepConfigWidget(MakeStep *makeStep); + virtual QString displayName() const; + virtual void init(const QString &buildConfiguration); +private slots: + void itemChanged(QListWidgetItem*); +private: + QString m_buildConfiguration; + MakeStep * m_makeStep; + QListWidget *m_targetsList; +}; + +class MakeBuildStepFactory : public ProjectExplorer::IBuildStepFactory +{ + virtual bool canCreate(const QString &name) const; + virtual ProjectExplorer::BuildStep *create(ProjectExplorer::Project *pro, const QString &name) const; + virtual QStringList canCreateForProject(ProjectExplorer::Project *pro) const; + virtual QString displayNameForName(const QString &name) const; +}; + +} +} + +#endif // MAKESTEP_H diff --git a/src/plugins/genericprojectmanager/pkgconfigtool.cpp b/src/plugins/genericprojectmanager/pkgconfigtool.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eb4c6ad1f521342389438b740b1040d05dfab4ee --- /dev/null +++ b/src/plugins/genericprojectmanager/pkgconfigtool.cpp @@ -0,0 +1,101 @@ + +#include "pkgconfigtool.h" +#include <QProcess> +#include <QTextStream> +#include <QtDebug> + +using namespace GenericProjectManager::Internal; + +PkgConfigTool::PkgConfigTool() +{ } + +PkgConfigTool::~PkgConfigTool() +{ } + +QList<PkgConfigTool::Package> PkgConfigTool::packages() const +{ + if (_packages.isEmpty()) + packages_helper(); + + return _packages; +} + +void PkgConfigTool::packages_helper() const +{ + QStringList args; + args.append(QLatin1String("--list-all")); + + QProcess pkgconfig; + pkgconfig.start(QLatin1String("pkg-config"), args); + while (! pkgconfig.waitForFinished()) { + } + + QTextStream in(&pkgconfig); + forever { + const QString line = in.readLine(); + + if (line.isNull()) + break; + + else if (line.isEmpty()) + continue; + + int i = 0; + for (; i != line.length(); ++i) { + if (line.at(i).isSpace()) + break; + } + + Package package; + package.name = line.left(i).trimmed(); + package.description = line.mid(i).trimmed(); + + QStringList args; + args << package.name << QLatin1String("--cflags"); + pkgconfig.start(QLatin1String("pkg-config"), args); + + while (! pkgconfig.waitForFinished()) { + } + + const QString cflags = QString::fromUtf8(pkgconfig.readAll()); + + int index = 0; + while (index != cflags.size()) { + const QChar ch = cflags.at(index); + + if (ch.isSpace()) { + do { ++index; } + while (index < cflags.size() && cflags.at(index).isSpace()); + } + + else if (ch == QLatin1Char('-') && index + 1 < cflags.size()) { + ++index; + + const QChar opt = cflags.at(index); + + if (opt == QLatin1Char('I')) { + // include paths. + + int start = ++index; + for (; index < cflags.size(); ++index) { + if (cflags.at(index).isSpace()) + break; + } + + qDebug() << "*** add include path:" << cflags.mid(start, index - start); + package.includePaths.append(cflags.mid(start, index - start)); + } + } + + else { + for (; index < cflags.size(); ++index) { + if (cflags.at(index).isSpace()) + break; + } + } + } + + _packages.append(package); + } +} + diff --git a/src/plugins/genericprojectmanager/pkgconfigtool.h b/src/plugins/genericprojectmanager/pkgconfigtool.h new file mode 100644 index 0000000000000000000000000000000000000000..ac97d3e8eb0e9fe19313315c6010f0083144655e --- /dev/null +++ b/src/plugins/genericprojectmanager/pkgconfigtool.h @@ -0,0 +1,39 @@ +#ifndef PKGCONFIGTOOL_H +#define PKGCONFIGTOOL_H + +#include <QObject> +#include <QStringList> + +namespace GenericProjectManager { +namespace Internal { + +class PkgConfigTool: public QObject +{ + Q_OBJECT + +public: + struct Package { + QString name; + QString description; + QStringList includePaths; + QStringList defines; + QStringList undefines; + }; + +public: + PkgConfigTool(); + virtual ~PkgConfigTool(); + + QList<Package> packages() const; + +private: + void packages_helper() const; + +private: + mutable QList<Package> _packages; +}; + +} // end of namespace Internal +} // end of namespace GenericProjectManager + +#endif // PKGCONFIGTOOL_H diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 4db71df1f8f814c371c21428cad62b1a8a6d7f0d..3b06779d9809b31049eb4be13adc6eddc7ec5421 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -29,6 +29,7 @@ SUBDIRS = plugin_coreplugin \ plugin_fakevim \ plugin_designer \ plugin_resourceeditor \ + plugin_genericprojectmanager \ debugger/dumper.pro plugin_coreplugin.subdir = coreplugin @@ -149,3 +150,10 @@ plugin_cmakeprojectmanager.depends += plugin_projectexplorer plugin_cmakeprojectmanager.depends += plugin_cpptools plugin_cmakeprojectmanager.depends += plugin_cppeditor plugin_cmakeprojectmanager.depends += plugin_help + +plugin_genericprojectmanager.subdir = genericprojectmanager +plugin_genericprojectmanager.depends = plugin_texteditor +plugin_genericprojectmanager.depends += plugin_projectexplorer +plugin_genericprojectmanager.depends += plugin_cpptools +plugin_genericprojectmanager.depends += plugin_cppeditor +plugin_genericprojectmanager.depends += plugin_help diff --git a/src/plugins/projectexplorer/dependenciespanel.cpp b/src/plugins/projectexplorer/dependenciespanel.cpp index 8d88fbfa54840351e4263c714c86239d53f3dd13..d3eb7d810c5b7e3c2844ec1ade1a95b704a9f01e 100644 --- a/src/plugins/projectexplorer/dependenciespanel.cpp +++ b/src/plugins/projectexplorer/dependenciespanel.cpp @@ -43,9 +43,9 @@ namespace ProjectExplorer { namespace Internal { -/// -/// DependenciesModel -/// +// +// DependenciesModel +// class DependenciesModel : public QAbstractListModel { @@ -137,9 +137,9 @@ Qt::ItemFlags DependenciesModel::flags(const QModelIndex &index) const return rc; } -/// -/// DependenciesWidget -/// +// +// DependenciesWidget +// class DependenciesWidget : public QWidget { @@ -165,9 +165,9 @@ DependenciesWidget::DependenciesWidget(SessionManager *session, m_ui.dependenciesView->setHeaderHidden(true); } -/// -/// DependenciesPanel -/// +// +// DependenciesPanel +// DependenciesPanel::DependenciesPanel(SessionManager *session, Project *project) : PropertiesPanel() @@ -190,9 +190,9 @@ QWidget *DependenciesPanel::widget() return m_widget; } -/// -/// DependenciesPanelFactory -/// +// +// DependenciesPanelFactory +// DependenciesPanelFactory::DependenciesPanelFactory(SessionManager *session) : m_session(session) diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp index 2d0fcc5dc254bc0a3bff735293caa5f89e9a6b74..0d3a2d850d9e803ecb6f2ad787a456d14beb97ed 100644 --- a/src/plugins/projectexplorer/toolchain.cpp +++ b/src/plugins/projectexplorer/toolchain.cpp @@ -59,6 +59,14 @@ QStringList ToolChain::availableMSVCVersions() return versions; } +QStringList ToolChain::supportedToolChains() +{ + return QStringList() << QLatin1String("gcc") + << QLatin1String("mingw") + << QLatin1String("msvc") + << QLatin1String("wince"); +} + GccToolChain::GccToolChain(const QString &gcc) : m_gcc(gcc) { diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h index 0e7e16c5ffd4cc53195696b6ed89638fa9daf309..aeaa45fe7dfc2ad83964c9899d11b8756f663199 100644 --- a/src/plugins/projectexplorer/toolchain.h +++ b/src/plugins/projectexplorer/toolchain.h @@ -62,6 +62,7 @@ public: static ToolChain *createMSVCToolChain(const QString &name); static ToolChain *createWinCEToolChain(const QString &name, const QString &platform); static QStringList availableMSVCVersions(); + static QStringList supportedToolChains(); protected: virtual bool equals(ToolChain *other) const = 0;