Newer
Older
/**************************************************************************
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Nokia Corporation (qt-info@nokia.com)
** 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
**************************************************************************/
#include "cmakeproject.h"
#include "cmakeprojectconstants.h"
#include "cmakeprojectnodes.h"
#include "makestep.h"
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/buildenvironmentwidget.h>
#include <projectexplorer/toolchain.h>
#include <coreplugin/editormanager/editormanager.h>
#include <QtGui/QInputDialog>
using namespace CMakeProjectManager;
using namespace CMakeProjectManager::Internal;
using namespace ProjectExplorer;
// QtCreator CMake Generator wishlist:
// Which make targets we need to build to get all executables
// What is the make we need to call
// What is the actual compiler executable
// DEFINES
// Open Questions
// Who sets up the environment for cl.exe ? INCLUDEPATH and so on
/*!
\class CMakeProject
*/
CMakeProject::CMakeProject(CMakeManager *manager, const QString &fileName)
: m_manager(manager),
m_fileName(fileName),
m_rootNode(new CMakeProjectNode(m_fileName)),
m_targetFactory(new CMakeTargetFactory(this)),
m_lastEditor(0)
connect(this, SIGNAL(addedTarget(ProjectExplorer::Target*)),
SLOT(targetAdded(ProjectExplorer::Target*)));
}
CMakeProject::~CMakeProject()
{
// Remove CodeModel support
CppTools::CppModelManagerInterface *modelManager
= ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>();
QMap<QString, CMakeUiCodeModelSupport *>::const_iterator it, end;
it = m_uiCodeModelSupport.constBegin();
end = m_uiCodeModelSupport.constEnd();
for (; it!=end; ++it) {
modelManager->removeEditorSupport(it.value());
delete it.value();
}
m_codeModelFuture.cancel();
void CMakeProject::fileChanged(const QString &fileName)
Q_UNUSED(fileName)
if (!activeTarget() ||
!activeTarget()->activeBuildConfiguration())
return;
if (m_insideFileChanged)
return;
m_insideFileChanged = true;
changeActiveBuildConfiguration(activeTarget()->activeBuildConfiguration());
m_insideFileChanged = false;
void CMakeProject::changeActiveBuildConfiguration(ProjectExplorer::BuildConfiguration *bc)
if (!bc || bc->target() != activeTarget())
return;
CMakeBuildConfiguration * cmakebc(qobject_cast<CMakeBuildConfiguration *>(bc));
if (!cmakebc)
return;
// Pop up a dialog asking the user to rerun cmake
QFileInfo sourceFileInfo(m_fileName);
QString cbpFile = CMakeManager::findCbpFile(QDir(bc->buildDirectory()));
CMakeOpenProjectWizard::Mode mode = CMakeOpenProjectWizard::Nothing;
if (!cbpFileFi.exists()) {
mode = CMakeOpenProjectWizard::NeedToCreate;
} else {
foreach(const QString &file, m_watchedFiles) {
if (QFileInfo(file).lastModified() > cbpFileFi.lastModified()) {
mode = CMakeOpenProjectWizard::NeedToUpdate;
break;
}
}
}
if (mode != CMakeOpenProjectWizard::Nothing) {
CMakeOpenProjectWizard copw(m_manager,
sourceFileInfo.absolutePath(),
}
// reparse
parseCMakeLists();
}
void CMakeProject::targetAdded(ProjectExplorer::Target *t)
connect(t, SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
SLOT(changeActiveBuildConfiguration(ProjectExplorer::BuildConfiguration*)));
void CMakeProject::changeBuildDirectory(CMakeBuildConfiguration *bc, const QString &newBuildDirectory)
bc->setBuildDirectory(newBuildDirectory);
QString CMakeProject::defaultBuildDirectory() const
{
return projectDirectory() + QLatin1String("/qtcreator-build");
}
if (!activeTarget() ||
!activeTarget()->activeBuildConfiguration())
return false;
CMakeBuildConfiguration *activeBC = activeTarget()->activeBuildConfiguration();
QString cbpFile = CMakeManager::findCbpFile(activeBC->buildDirectory());
m_rootNode->setDisplayName(QFileInfo(cbpFile).completeBaseName());
CMakeCbpParser cbpparser;
// Parsing
//qDebug()<<"Parsing file "<<cbpFile;
if (!cbpparser.parseCbpFile(cbpFile)) {
// TODO report error
qDebug()<<"Parsing failed";
// activeBC->updateToolChain(QString::null);
emit buildTargetsChanged();
return false;
}
// ToolChain
// activeBC->updateToolChain(cbpparser.compilerName());
m_projectName = cbpparser.projectName();
m_rootNode->setDisplayName(cbpparser.projectName());
//qDebug()<<"Building Tree";
QList<ProjectExplorer::FileNode *> fileList = cbpparser.fileList();
QSet<QString> projectFiles;
if (cbpparser.hasCMakeFiles()) {
fileList.append(cbpparser.cmakeFileList());
foreach(const ProjectExplorer::FileNode *node, cbpparser.cmakeFileList())
projectFiles.insert(node->path());
} else {
// Manually add the CMakeLists.txt file
QString cmakeListTxt = projectDirectory() + "/CMakeLists.txt";
bool generated = false;
fileList.append(new ProjectExplorer::FileNode(cmakeListTxt, ProjectExplorer::ProjectFileType, generated));
QSet<QString> added = projectFiles;
added.subtract(m_watchedFiles);
foreach(const QString &add, added)
m_watcher->addFile(add);
foreach(const QString &remove, m_watchedFiles.subtract(projectFiles))
m_watcher->removeFile(remove);
m_watchedFiles = projectFiles;
m_files.clear();
foreach (ProjectExplorer::FileNode *fn, fileList)
m_files.append(fn->path());
m_files.sort();
//qDebug()<<"Adding Targets";
m_buildTargets = cbpparser.buildTargets();
// foreach(CMakeBuildTarget ct, m_buildTargets) {
// qDebug()<<ct.title<<" with executable:"<<ct.executable;
// qDebug()<<"WD:"<<ct.workingDirectory;
// qDebug()<<ct.makeCommand<<ct.makeCleanCommand;
// qDebug()<<"";
// }
// TOOD this code ain't very pretty ...
m_uicCommand.clear();
QFile cmakeCache(activeBC->buildDirectory() + "/CMakeCache.txt");
cmakeCache.open(QIODevice::ReadOnly);
while (!cmakeCache.atEnd()) {
QString line = cmakeCache.readLine();
if (line.startsWith("QT_UIC_EXECUTABLE")) {
if (int pos = line.indexOf('=')) {
m_uicCommand = line.mid(pos + 1).trimmed();
}
break;
}
}
cmakeCache.close();
QStringList allIncludePaths;
QStringList allFrameworkPaths;
QList<ProjectExplorer::HeaderPath> allHeaderPaths = activeBC->toolChain()->systemHeaderPaths();
foreach (const ProjectExplorer::HeaderPath &headerPath, allHeaderPaths) {
if (headerPath.kind() == ProjectExplorer::HeaderPath::FrameworkHeaderPath)
allFrameworkPaths.append(headerPath.path());
else
allIncludePaths.append(headerPath.path());
}
// This explicitly adds -I. to the include paths
allIncludePaths.append(projectDirectory());
allIncludePaths.append(cbpparser.includeFiles());
CppTools::CppModelManagerInterface *modelmanager =
ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>();
if (modelmanager) {
CppTools::CppModelManagerInterface::ProjectInfo pinfo = modelmanager->projectInfo(this);
if (pinfo.includePaths != allIncludePaths
|| pinfo.sourceFiles != m_files
|| pinfo.defines != activeBC->toolChain()->predefinedMacros()
|| pinfo.frameworkPaths != allFrameworkPaths) {
pinfo.includePaths = allIncludePaths;
// TODO we only want C++ files, not all other stuff that might be in the project
pinfo.sourceFiles = m_files;
pinfo.defines = activeBC->toolChain()->predefinedMacros(); // TODO this is to simplistic
pinfo.frameworkPaths = allFrameworkPaths;
modelmanager->updateProjectInfo(pinfo);
m_codeModelFuture.cancel();
m_codeModelFuture = modelmanager->updateSourceFiles(pinfo.sourceFiles);
emit buildTargetsChanged();
QList<CMakeBuildTarget> CMakeProject::buildTargets() const
{
return m_buildTargets;
}
QStringList CMakeProject::buildTargetTitles() const
foreach (const CMakeBuildTarget &ct, m_buildTargets) {
if (ct.executable.isEmpty())
continue;
if (ct.title.endsWith(QLatin1String("/fast")))
bool CMakeProject::hasBuildTarget(const QString &title) const
foreach (const CMakeBuildTarget &ct, m_buildTargets) {
if (ct.executable.isEmpty())
continue;
if (ct.title.endsWith(QLatin1String("/fast")))
continue;
if (ct.title == title)
return true;
}
return false;
}
void CMakeProject::gatherFileNodes(ProjectExplorer::FolderNode *parent, QList<ProjectExplorer::FileNode *> &list)
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
foreach(ProjectExplorer::FolderNode *folder, parent->subFolderNodes())
gatherFileNodes(folder, list);
foreach(ProjectExplorer::FileNode *file, parent->fileNodes())
list.append(file);
}
void CMakeProject::buildTree(CMakeProjectNode *rootNode, QList<ProjectExplorer::FileNode *> newList)
{
// Gather old list
QList<ProjectExplorer::FileNode *> oldList;
gatherFileNodes(rootNode, oldList);
qSort(oldList.begin(), oldList.end(), ProjectExplorer::ProjectNode::sortNodesByPath);
qSort(newList.begin(), newList.end(), ProjectExplorer::ProjectNode::sortNodesByPath);
// generate added and deleted list
QList<ProjectExplorer::FileNode *>::const_iterator oldIt = oldList.constBegin();
QList<ProjectExplorer::FileNode *>::const_iterator oldEnd = oldList.constEnd();
QList<ProjectExplorer::FileNode *>::const_iterator newIt = newList.constBegin();
QList<ProjectExplorer::FileNode *>::const_iterator newEnd = newList.constEnd();
QList<ProjectExplorer::FileNode *> added;
QList<ProjectExplorer::FileNode *> deleted;
while(oldIt != oldEnd && newIt != newEnd) {
if ( (*oldIt)->path() == (*newIt)->path()) {
delete *newIt;
++oldIt;
++newIt;
} else if ((*oldIt)->path() < (*newIt)->path()) {
deleted.append(*oldIt);
++oldIt;
} else {
added.append(*newIt);
++newIt;
}
}
while (oldIt != oldEnd) {
deleted.append(*oldIt);
++oldIt;
}
while (newIt != newEnd) {
added.append(*newIt);
++newIt;
}
// add added nodes
foreach (ProjectExplorer::FileNode *fn, added) {
// qDebug()<<"added"<<fn->path();
// Get relative path to rootNode
QString parentDir = QFileInfo(fn->path()).absolutePath();
ProjectExplorer::FolderNode *folder = findOrCreateFolder(rootNode, parentDir);
rootNode->addFileNodes(QList<ProjectExplorer::FileNode *>()<< fn, folder);
}
// remove old file nodes and check whether folder nodes can be removed
foreach (ProjectExplorer::FileNode *fn, deleted) {
ProjectExplorer::FolderNode *parent = fn->parentFolderNode();
// qDebug()<<"removed"<<fn->path();
rootNode->removeFileNodes(QList<ProjectExplorer::FileNode *>() << fn, parent);
// Check for empty parent
while (parent->subFolderNodes().isEmpty() && parent->fileNodes().isEmpty()) {
ProjectExplorer::FolderNode *grandparent = parent->parentFolderNode();
rootNode->removeFolderNodes(QList<ProjectExplorer::FolderNode *>() << parent, grandparent);
parent = grandparent;
if (parent == rootNode)
break;
}
}
}
ProjectExplorer::FolderNode *CMakeProject::findOrCreateFolder(CMakeProjectNode *rootNode, QString directory)
{
QString relativePath = QDir(QFileInfo(rootNode->path()).path()).relativeFilePath(directory);
QStringList parts = relativePath.split(QLatin1Char('/'), QString::SkipEmptyParts);
QString path = QFileInfo(rootNode->path()).path();
path += QLatin1Char('/');
path += part;
foreach (ProjectExplorer::FolderNode *folder, parent->subFolderNodes()) {
if (folder->path() == path) {
// yeah found something :)
parent = folder;
found = true;
break;
}
}
if (!found) {
// No FolderNode yet, so create it
ProjectExplorer::FolderNode *tmp = new ProjectExplorer::FolderNode(path);
rootNode->addFolderNodes(QList<ProjectExplorer::FolderNode *>() << tmp, parent);
parent = tmp;
}
}
return parent;
}
QString CMakeProject::displayName() const
Core::IFile *CMakeProject::file() const
{
return m_file;
}
CMakeTargetFactory *CMakeProject::targetFactory() const
{
return m_targetFactory;
}
CMakeManager *CMakeProject::projectManager() const
CMakeTarget *CMakeProject::activeTarget() const
{
return static_cast<CMakeTarget *>(Project::activeTarget());
}
QList<ProjectExplorer::Project *> CMakeProject::dependsOn()
{
return QList<Project *>();
}
ProjectExplorer::BuildConfigWidget *CMakeProject::createConfigWidget()
return new CMakeBuildSettingsWidget(this);
QList<ProjectExplorer::BuildConfigWidget*> CMakeProject::subConfigWidgets()
list << new BuildEnvironmentWidget;
}
ProjectExplorer::ProjectNode *CMakeProject::rootProjectNode() const
{
return m_rootNode;
}
QStringList CMakeProject::files(FilesMode fileMode) const
{
bool CMakeProject::fromMap(const QVariantMap &map)
if (!Project::fromMap(map))
return false;
CMakeTarget *t = targetFactory()->create(this, QLatin1String(DEFAULT_CMAKE_TARGET_ID));
Q_ASSERT(t);
Q_ASSERT(t->activeBuildConfiguration());
// Ask the user for where he wants to build it
// and the cmake command line
CMakeOpenProjectWizard copw(m_manager, projectDirectory(), Utils::Environment::systemEnvironment());
if (copw.exec() != QDialog::Accepted)
return false;
CMakeBuildConfiguration *bc =
static_cast<CMakeBuildConfiguration *>(t->buildConfigurations().at(0));
bc->setMsvcVersion(copw.msvcVersion());
if (!copw.buildDirectory().isEmpty())
bc->setBuildDirectory(copw.buildDirectory());
} else {
// We have a user file, but we could still be missing the cbp file
// or simply run createXml with the saved settings
CMakeBuildConfiguration *activeBC = activeTarget()->activeBuildConfiguration();
QString cbpFile = CMakeManager::findCbpFile(QDir(activeBC->buildDirectory()));
CMakeOpenProjectWizard::Mode mode = CMakeOpenProjectWizard::Nothing;
mode = CMakeOpenProjectWizard::NeedToCreate;
else if (cbpFileFi.lastModified() < sourceFileInfo.lastModified())
mode = CMakeOpenProjectWizard::NeedToUpdate;
if (mode != CMakeOpenProjectWizard::Nothing) {
CMakeOpenProjectWizard copw(m_manager,
sourceFileInfo.absolutePath(),
if (copw.exec() != QDialog::Accepted)
return false;
activeBC->setMsvcVersion(copw.msvcVersion());
m_watcher = new ProjectExplorer::FileWatcher(this);
connect(m_watcher, SIGNAL(fileChanged(QString)), this, SLOT(fileChanged(QString)));
if (!parseCMakeLists()) // Gets the directory from the active buildconfiguration
MakeStep *makeStep = qobject_cast<MakeStep *>(
activeTarget()->activeBuildConfiguration()->stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD)->at(0));
makeStep->setBuildTarget("all", true);
foreach (Target *t, targets()) {
connect(t, SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
this, SLOT(changeActiveBuildConfiguration(ProjectExplorer::BuildConfiguration*)));
connect(t, SIGNAL(environmentChanged()),
this, SLOT(changeEnvironment()));
}
connect(Core::EditorManager::instance(), SIGNAL(editorAboutToClose(Core::IEditor*)),
this, SLOT(editorAboutToClose(Core::IEditor*)));
connect(Core::EditorManager::instance(), SIGNAL(currentEditorChanged(Core::IEditor*)),
this, SLOT(editorChanged(Core::IEditor*)));
connect(ProjectExplorer::ProjectExplorerPlugin::instance()->buildManager(), SIGNAL(buildStateChanged(ProjectExplorer::Project*)),
this, SLOT(buildStateChanged(ProjectExplorer::Project*)));
CMakeBuildTarget CMakeProject::buildTargetForTitle(const QString &title)
foreach(const CMakeBuildTarget &ct, m_buildTargets)
if (ct.title == title)
return ct;
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
QString CMakeProject::uicCommand() const
{
return m_uicCommand;
}
QString CMakeProject::uiHeaderFile(const QString &uiFile)
{
QDir srcDirRoot = QDir(projectDirectory());
QString relativePath = srcDirRoot.relativeFilePath(uiFile);
QDir buildDir = QDir(activeTarget()->activeBuildConfiguration()->buildDirectory());
QString uiHeaderFilePath = buildDir.absoluteFilePath(relativePath);
QFileInfo fi(uiHeaderFilePath);
uiHeaderFilePath = fi.absolutePath();
uiHeaderFilePath += QLatin1String("/ui_");
uiHeaderFilePath += fi.completeBaseName();
uiHeaderFilePath += QLatin1String(".h");
return QDir::cleanPath(uiHeaderFilePath);
}
void CMakeProject::createUiCodeModelSupport()
{
// qDebug()<<"creatUiCodeModelSupport()";
CppTools::CppModelManagerInterface *modelManager
= ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>();
// First move all to
QMap<QString, CMakeUiCodeModelSupport *> oldCodeModelSupport;
oldCodeModelSupport = m_uiCodeModelSupport;
m_uiCodeModelSupport.clear();
// Find all ui files
foreach (const QString &uiFile, m_files) {
if (uiFile.endsWith(".ui")) {
// UI file, not convert to
QString uiHeaderFilePath = uiHeaderFile(uiFile);
QMap<QString, CMakeUiCodeModelSupport *>::iterator it
= oldCodeModelSupport.find(uiFile);
if (it != oldCodeModelSupport.end()) {
// qDebug()<<"updated old codemodelsupport";
CMakeUiCodeModelSupport *cms = it.value();
cms->setFileName(uiHeaderFilePath);
m_uiCodeModelSupport.insert(it.key(), cms);
oldCodeModelSupport.erase(it);
} else {
// qDebug()<<"adding new codemodelsupport";
CMakeUiCodeModelSupport *cms = new CMakeUiCodeModelSupport(modelManager, this, uiFile, uiHeaderFilePath);
m_uiCodeModelSupport.insert(uiFile, cms);
modelManager->addEditorSupport(cms);
}
}
}
// Remove old
QMap<QString, CMakeUiCodeModelSupport *>::const_iterator it, end;
end = oldCodeModelSupport.constEnd();
for (it = oldCodeModelSupport.constBegin(); it!=end; ++it) {
modelManager->removeEditorSupport(it.value());
delete it.value();
}
}
void CMakeProject::updateCodeModelSupportFromEditor(const QString &uiFileName,
const QString &contents)
{
const QMap<QString, CMakeUiCodeModelSupport *>::const_iterator it =
m_uiCodeModelSupport.constFind(uiFileName);
if (it != m_uiCodeModelSupport.constEnd())
it.value()->updateFromEditor(contents);
}
void CMakeProject::editorChanged(Core::IEditor *editor)
{
// Handle old editor
Designer::FormWindowEditor *lastFormEditor = qobject_cast<Designer::FormWindowEditor *>(m_lastEditor);
if (lastFormEditor) {
disconnect(lastFormEditor, SIGNAL(changed()), this, SLOT(uiEditorContentsChanged()));
if (m_dirtyUic) {
const QString contents = lastFormEditor->contents();
updateCodeModelSupportFromEditor(lastFormEditor->file()->fileName(), contents);
m_dirtyUic = false;
}
}
m_lastEditor = editor;
// Handle new editor
if (Designer::FormWindowEditor *fw = qobject_cast<Designer::FormWindowEditor *>(editor))
connect(fw, SIGNAL(changed()), this, SLOT(uiEditorContentsChanged()));
}
void CMakeProject::editorAboutToClose(Core::IEditor *editor)
{
if (m_lastEditor == editor) {
// Oh no our editor is going to be closed
// get the content first
Designer::FormWindowEditor *lastEditor = qobject_cast<Designer::FormWindowEditor *>(m_lastEditor);
if (lastEditor) {
disconnect(lastEditor, SIGNAL(changed()), this, SLOT(uiEditorContentsChanged()));
if (m_dirtyUic) {
const QString contents = lastEditor->contents();
updateCodeModelSupportFromEditor(lastEditor->file()->fileName(), contents);
m_dirtyUic = false;
}
}
m_lastEditor = 0;
}
}
void CMakeProject::uiEditorContentsChanged()
{
// cast sender, get filename
if (m_dirtyUic)
return;
Designer::FormWindowEditor *fw = qobject_cast<Designer::FormWindowEditor *>(sender());
if (!fw)
return;
m_dirtyUic = true;
}
void CMakeProject::buildStateChanged(ProjectExplorer::Project *project)
{
if (project == this) {
if (!ProjectExplorer::ProjectExplorerPlugin::instance()->buildManager()->isBuilding(this)) {
QMap<QString, CMakeUiCodeModelSupport *>::const_iterator it, end;
end = m_uiCodeModelSupport.constEnd();
for (it = m_uiCodeModelSupport.constBegin(); it != end; ++it) {
it.value()->updateFromBuild();
}
}
}
}
CMakeFile::CMakeFile(CMakeProject *parent, QString fileName)
: Core::IFile(parent), m_project(parent), m_fileName(fileName)
{
}
bool CMakeFile::save(const QString &fileName)
{
// Once we have an texteditor open for this file, we probably do
// need to implement this, don't we.
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
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::rename(const QString &newName)
{
Q_ASSERT(false);
Q_UNUSED(newName);
// Can't happen....
}
Core::IFile::ReloadBehavior CMakeFile::reloadBehavior(ChangeTrigger state, ChangeType type) const
Q_UNUSED(state)
Q_UNUSED(type)
return BehaviorSilent;
}
void CMakeFile::reload(ReloadFlag flag, ChangeType type)
{
Q_UNUSED(flag)
Q_UNUSED(type)
CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeProject *project)
QFormLayout *fl = new QFormLayout(this);
fl->setContentsMargins(20, -1, 0, -1);
fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
// TODO add action to Build menu?
QPushButton *runCmakeButton = new QPushButton("Run cmake");
connect(runCmakeButton, SIGNAL(clicked()),
this, SLOT(runCMake()));
fl->addRow(tr("Reconfigure project:"), runCmakeButton);
m_pathLineEdit = new QLineEdit(this);
m_pathLineEdit->setReadOnly(true);
QHBoxLayout *hbox = new QHBoxLayout();
hbox->addWidget(m_pathLineEdit);
m_changeButton = new QPushButton(this);
m_changeButton->setText(tr("&Change"));
connect(m_changeButton, SIGNAL(clicked()), this, SLOT(openChangeBuildDirectoryDialog()));
hbox->addWidget(m_changeButton);
fl->addRow("Build directory:", hbox);
}
QString CMakeBuildSettingsWidget::displayName() const
{
return "CMake";
}
void CMakeBuildSettingsWidget::init(BuildConfiguration *bc)
m_buildConfiguration = static_cast<CMakeBuildConfiguration *>(bc);
m_pathLineEdit->setText(m_buildConfiguration->buildDirectory());
if (m_buildConfiguration->buildDirectory() == m_project->projectDirectory())
m_changeButton->setEnabled(false);
else
void CMakeBuildSettingsWidget::openChangeBuildDirectoryDialog()
CMakeOpenProjectWizard copw(m_project->projectManager(),
m_project->projectDirectory(),
m_buildConfiguration->buildDirectory(),
m_buildConfiguration->environment());
if (copw.exec() == QDialog::Accepted) {
m_project->changeBuildDirectory(m_buildConfiguration, copw.buildDirectory());
m_pathLineEdit->setText(m_buildConfiguration->buildDirectory());
void CMakeBuildSettingsWidget::runCMake()
{
// TODO skip build directory
CMakeOpenProjectWizard copw(m_project->projectManager(),
m_project->projectDirectory(),
m_buildConfiguration->buildDirectory(),
CMakeOpenProjectWizard::WantToUpdate,
m_buildConfiguration->environment());
if (copw.exec() == QDialog::Accepted) {
m_project->parseCMakeLists();
}
}
/////
// CMakeCbpParser
////
bool CMakeCbpParser::parseCbpFile(const QString &fileName)
{
QFile fi(fileName);
if (fi.exists() && fi.open(QFile::ReadOnly)) {
setDevice(&fi);
readNext();
if (name() == "CodeBlocks_project_file") {
parseCodeBlocks_project_file();
} else if (isStartElement()) {
parseUnknownElement();
}
}
fi.close();
m_includeFiles.sort();
m_includeFiles.removeDuplicates();
return true;
}
return false;
}
void CMakeCbpParser::parseCodeBlocks_project_file()
{
readNext();
if (isEndElement()) {
return;
} else if (name() == "Project") {
parseProject();
} else if (isStartElement()) {
parseUnknownElement();
}
}
}
void CMakeCbpParser::parseProject()
{
readNext();
if (isEndElement()) {
return;
} else if (name() == "Option") {
parseOption();
} else if (name() == "Unit") {
parseUnit();
} else if (name() == "Build") {
parseBuild();
} else if (isStartElement()) {
parseUnknownElement();
}
}
}
void CMakeCbpParser::parseBuild()
{
readNext();
if (isEndElement()) {
return;
} else if (name() == "Target") {
} else if (isStartElement()) {
parseUnknownElement();
}
}
}
void CMakeCbpParser::parseBuildTarget()
m_buildTargetType = false;
m_buildTarget.clear();
m_buildTarget.title = attributes().value("title").toString();
readNext();
if (isEndElement()) {
if (m_buildTargetType || m_buildTarget.title == "all" || m_buildTarget.title == "install") {
m_buildTargets.append(m_buildTarget);
return;
} else if (name() == "Compiler") {
parseCompiler();
} else if (isStartElement()) {
parseUnknownElement();
}
}
}
void CMakeCbpParser::parseBuildTargetOption()
if (attributes().hasAttribute("output")) {
m_buildTarget.executable = attributes().value("output").toString();
} else if (attributes().hasAttribute("type") && (attributes().value("type") == "1" || attributes().value("type") == "0")) {
} else if (attributes().hasAttribute("type") && (attributes().value("type") == "3" || attributes().value("type") == "2")) {
m_buildTargetType = true;
m_buildTarget.library = true;
} else if (attributes().hasAttribute("working_dir")) {
m_buildTarget.workingDirectory = attributes().value("working_dir").toString();
readNext();
if (isEndElement()) {
return;
} else if (name() == "MakeCommand") {
parseMakeCommand();
} else if (isStartElement()) {
parseUnknownElement();
}
}
}
QString CMakeCbpParser::projectName() const
{
return m_projectName;
}
void CMakeCbpParser::parseOption()
{
if (attributes().hasAttribute("title"))
m_projectName = attributes().value("title").toString();
if (attributes().hasAttribute("compiler"))
m_compiler = attributes().value("compiler").toString();