diff --git a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp index afb586f6a35f449463fcf2f8c83ce8379e1687a8..eae41bbef084e86216f3f0883b291a6597206dde 100644 --- a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp @@ -86,13 +86,25 @@ CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const m_creatingCbpFiles(true) { foreach(const QString &buildDirectory, needToCreate) - addPage(new CMakeRunPage(this, buildDirectory, false)); + addPage(new CMakeRunPage(this, CMakeRunPage::Recreate, buildDirectory)); foreach(const QString &buildDirectory, needToUpdate) - addPage(new CMakeRunPage(this, buildDirectory, true)); + addPage(new CMakeRunPage(this, CMakeRunPage::Update, buildDirectory)); setOption(QWizard::NoCancelButton); setOption(QWizard::NoBackButtonOnStartPage); } +CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, + const QString &oldBuildDirectory) + : m_cmakeManager(cmakeManager), + m_sourceDirectory(sourceDirectory), + m_creatingCbpFiles(true) +{ + m_buildDirectory = oldBuildDirectory; + addPage(new ShadowBuildPage(this, true)); + addPage(new CMakeRunPage(this, CMakeRunPage::Change)); + setOption(QWizard::NoBackButtonOnStartPage); +} + CMakeManager *CMakeOpenProjectWizard::cmakeManager() const { return m_cmakeManager; @@ -191,7 +203,7 @@ XmlFileUpToDatePage::XmlFileUpToDatePage(CMakeOpenProjectWizard *cmakeWizard) layout()->addWidget(label); } -ShadowBuildPage::ShadowBuildPage(CMakeOpenProjectWizard *cmakeWizard) +ShadowBuildPage::ShadowBuildPage(CMakeOpenProjectWizard *cmakeWizard, bool change) : QWizardPage(cmakeWizard), m_cmakeWizard(cmakeWizard) { QFormLayout *fl = new QFormLayout; @@ -199,10 +211,13 @@ ShadowBuildPage::ShadowBuildPage(CMakeOpenProjectWizard *cmakeWizard) QLabel *label = new QLabel(this); label->setWordWrap(true); - label->setText(tr("Please enter the directory in which you want to build your project. " - "Qt Creator recommends to not use the source directory for building. " - "This ensures that the source directory remains clean and enables multiple builds " - "with different settings.")); + if (change) + label->setText(tr("Please enter the directory in which you want to build your project. ")); + else + label->setText(tr("Please enter the directory in which you want to build your project. " + "Qt Creator recommends to not use the source directory for building. " + "This ensures that the source directory remains clean and enables multiple builds " + "with different settings.")); fl->addWidget(label); m_pc = new Core::Utils::PathChooser(this); m_pc->setPath(m_cmakeWizard->buildDirectory()); @@ -215,20 +230,12 @@ void ShadowBuildPage::buildDirectoryChanged() m_cmakeWizard->setBuildDirectory(m_pc->path()); } -CMakeRunPage::CMakeRunPage(CMakeOpenProjectWizard *cmakeWizard) - : QWizardPage(cmakeWizard), - m_cmakeWizard(cmakeWizard), - m_complete(false) -{ - initWidgets(); -} - -CMakeRunPage::CMakeRunPage(CMakeOpenProjectWizard *cmakeWizard, const QString &buildDirectory, bool update) +CMakeRunPage::CMakeRunPage(CMakeOpenProjectWizard *cmakeWizard, Mode mode, const QString &buildDirectory) : QWizardPage(cmakeWizard), m_cmakeWizard(cmakeWizard), m_complete(false), - m_update(update), - m_presetBuildDirectory(buildDirectory) + m_mode(mode), + m_buildDirectory(buildDirectory) { initWidgets(); } @@ -243,12 +250,10 @@ void CMakeRunPage::initWidgets() fl->addRow(m_descriptionLabel); m_argumentsLineEdit = new QLineEdit(this); - //fl->addRow(tr("Arguments:"), m_argumentsLineEdit); m_runCMake = new QPushButton(this); m_runCMake->setText(tr("Run CMake")); connect(m_runCMake, SIGNAL(clicked()), this, SLOT(runCMake())); - //fl->addWidget(m_runCMake); QHBoxLayout *hbox = new QHBoxLayout; hbox->addWidget(m_argumentsLineEdit); @@ -267,26 +272,29 @@ void CMakeRunPage::initWidgets() void CMakeRunPage::initializePage() { - if (m_presetBuildDirectory.isEmpty()) { + if (m_mode == Initial) { m_buildDirectory = m_cmakeWizard->buildDirectory(); m_descriptionLabel->setText( tr("The directory %1 does not contain a cbp file. Qt Creator needs to create this file by running cmake. " "Some projects require command line arguments to the initial cmake call.").arg(m_buildDirectory)); - } else { - m_buildDirectory = m_presetBuildDirectory; - if (m_update) - m_descriptionLabel->setText(tr("The directory %1 contains an outdated .cbp file. Qt " - "Creator needs to update this file by running cmake. " - "If you want to add additional command line arguments, " - "add them in the below. Note, that cmake remembers command " - "line arguments from the former runs.").arg(m_buildDirectory)); - else - m_descriptionLabel->setText(tr("The directory %1 specified in a buildconfiguration, " - "does not contain a cbp file. Qt Creator needs to " - "recreate this file, by running cmake. " - "Some projects require command line arguments to " - "the initial cmake call. Note, that cmake remembers command " - "line arguments from the former runs.").arg(m_buildDirectory)); + } else if (m_mode == CMakeRunPage::Update) { + m_descriptionLabel->setText(tr("The directory %1 contains an outdated .cbp file. Qt " + "Creator needs to update this file by running cmake. " + "If you want to add additional command line arguments, " + "add them in the below. Note, that cmake remembers command " + "line arguments from the former runs.").arg(m_buildDirectory)); + } else if(m_mode == CMakeRunPage::Recreate) { + m_descriptionLabel->setText(tr("The directory %1 specified in a buildconfiguration, " + "does not contain a cbp file. Qt Creator needs to " + "recreate this file, by running cmake. " + "Some projects require command line arguments to " + "the initial cmake call. Note, that cmake remembers command " + "line arguments from the former runs.").arg(m_buildDirectory)); + } else if(m_mode == CMakeRunPage::Change) { + m_buildDirectory = m_cmakeWizard->buildDirectory(); + m_descriptionLabel->setText(tr("Qt Creator needs to run cmake in the new build directory. " + "Some projects require command line arguments to the " + "initial cmake call.")); } } diff --git a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h index 27277151d131baf2e65b8c0d7208118e2d2e9a30..6d3e79b9aecb60fd9ef13a8e911ba13a49413cdc 100644 --- a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h +++ b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h @@ -58,8 +58,14 @@ public: XmlFileUpToDatePageId, CMakeRunPageId }; + + // used at importing a project without a .user file CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory); + // used to update if we have already a .user file CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, const QStringList &needToCreate, const QStringList &needToUpdate); + // used to change the build directory of one buildconfiguration + CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, const QString &oldBuildDirectory); + virtual int nextId() const; QString buildDirectory() const; QString sourceDirectory() const; @@ -101,7 +107,7 @@ class ShadowBuildPage : public QWizardPage { Q_OBJECT public: - ShadowBuildPage(CMakeOpenProjectWizard *cmakeWizard); + ShadowBuildPage(CMakeOpenProjectWizard *cmakeWizard, bool change = false); private slots: void buildDirectoryChanged(); private: @@ -113,8 +119,9 @@ class CMakeRunPage : public QWizardPage { Q_OBJECT public: - CMakeRunPage(CMakeOpenProjectWizard *cmakeWizard); - CMakeRunPage(CMakeOpenProjectWizard *cmakeWizard, const QString &buildDirectory, bool update); + enum Mode { Initial, Update, Recreate, Change }; + CMakeRunPage(CMakeOpenProjectWizard *cmakeWizard, Mode mode = Initial, const QString &buildDirectory = QString()); + virtual void initializePage(); virtual void cleanupPage(); virtual bool isComplete() const; @@ -131,9 +138,8 @@ private: QLineEdit *m_argumentsLineEdit; QLabel *m_descriptionLabel; bool m_complete; - bool m_update; + Mode m_mode; QString m_buildDirectory; - QString m_presetBuildDirectory; }; } diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index eab609388ab3768a56e0dbcc0e15f9b7da459baf..c9ef999cf4a5cf83585bdf60073f2256870c1c7d 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -120,11 +120,11 @@ void CMakeProject::updateToolChain(const QString &compiler) if (compiler == "gcc") { newToolChain = ProjectExplorer::ToolChain::createGccToolChain("gcc"); } else if (compiler == "msvc8") { - // TODO hmm + // TODO MSVC toolchain //newToolChain = ProjectExplorer::ToolChain::createMSVCToolChain("//TODO"); Q_ASSERT(false); } else { - // TODO hmm? + // TODO other toolchains qDebug()<<"Not implemented yet!!! Qt Creator doesn't know which toolchain to use for"<<compiler; } @@ -137,10 +137,20 @@ void CMakeProject::updateToolChain(const QString &compiler) } } +void CMakeProject::changeBuildDirectory(const QString &buildConfiguration, const QString &newBuildDirectory) +{ + setValue(buildConfiguration, "buildDirectory", newBuildDirectory); + parseCMakeLists(); +} + +QString CMakeProject::sourceDirectory() const +{ + return QFileInfo(m_fileName).absolutePath(); +} + void CMakeProject::parseCMakeLists() { // Find cbp file - QString sourceDirectory = QFileInfo(m_fileName).absolutePath(); QString cbpFile = CMakeManager::findCbpFile(buildDirectory(activeBuildConfiguration())); // setFolderName @@ -159,7 +169,7 @@ void CMakeProject::parseCMakeLists() QList<ProjectExplorer::FileNode *> fileList = cbpparser.fileList(); // Manually add the CMakeLists.txt file - fileList.append(new ProjectExplorer::FileNode(sourceDirectory + "/CMakeLists.txt", ProjectExplorer::ProjectFileType, false)); + fileList.append(new ProjectExplorer::FileNode(sourceDirectory() + "/CMakeLists.txt", ProjectExplorer::ProjectFileType, false)); m_files.clear(); foreach (ProjectExplorer::FileNode *fn, fileList) @@ -191,7 +201,7 @@ void CMakeProject::parseCMakeLists() allIncludePaths.append(headerPath.path()); } // This explicitly adds -I. to the include paths - allIncludePaths.append(sourceDirectory); + allIncludePaths.append(sourceDirectory()); allIncludePaths.append(cbpparser.includeFiles()); CppTools::CppModelManagerInterface *modelmanager = ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>(); @@ -405,7 +415,7 @@ Core::IFile *CMakeProject::file() const return m_file; } -ProjectExplorer::IProjectManager *CMakeProject::projectManager() const +CMakeManager *CMakeProject::projectManager() const { return m_manager; } @@ -423,7 +433,7 @@ bool CMakeProject::isApplication() const ProjectExplorer::Environment CMakeProject::environment(const QString &buildConfiguration) const { Q_UNUSED(buildConfiguration) - //TODO + //TODO CMakeProject::Environment; return ProjectExplorer::Environment::systemEnvironment(); } @@ -431,7 +441,7 @@ QString CMakeProject::buildDirectory(const QString &buildConfiguration) const { QString buildDirectory = value(buildConfiguration, "buildDirectory").toString(); if (buildDirectory.isEmpty()) - buildDirectory = QFileInfo(m_fileName).absolutePath() + "/qtcreator-build"; + buildDirectory = sourceDirectory() + "/qtcreator-build"; return buildDirectory; } @@ -489,7 +499,7 @@ void CMakeProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader // Ask the user for where he wants to build it // and the cmake command line - CMakeOpenProjectWizard copw(m_manager, QFileInfo(m_fileName).absolutePath()); + CMakeOpenProjectWizard copw(m_manager, sourceDirectory()); copw.exec(); // TODO handle cancel.... @@ -550,7 +560,6 @@ CMakeFile::CMakeFile(CMakeProject *parent, QString fileName) bool CMakeFile::save(const QString &fileName) { - // TODO // Once we have an texteditor open for this file, we probably do // need to implement this, don't we. Q_UNUSED(fileName); @@ -603,14 +612,22 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeProject *project) { QFormLayout *fl = new QFormLayout(this); setLayout(fl); - m_pathChooser = new Core::Utils::PathChooser(this); - m_pathChooser->setEnabled(false); + m_pathLineEdit = new QLineEdit(this); + m_pathLineEdit->setReadOnly(true); // TODO currently doesn't work // since creating the cbp file also creates makefiles // and then cmake builds in that directory instead of shadow building // We need our own generator for that to work - connect(m_pathChooser, SIGNAL(changed()), this, SLOT(buildDirectoryChanged())); - fl->addRow(tr("Build directory:"), m_pathChooser); + + 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 @@ -621,12 +638,20 @@ QString CMakeBuildSettingsWidget::displayName() const void CMakeBuildSettingsWidget::init(const QString &buildConfiguration) { m_buildConfiguration = buildConfiguration; - m_pathChooser->setPath(m_project->buildDirectory(buildConfiguration)); + m_pathLineEdit->setText(m_project->buildDirectory(buildConfiguration)); + if (m_project->buildDirectory(buildConfiguration) == m_project->sourceDirectory()) + m_changeButton->setEnabled(false); + else + m_changeButton->setEnabled(false); } -void CMakeBuildSettingsWidget::buildDirectoryChanged() +void CMakeBuildSettingsWidget::openChangeBuildDirectoryDialog() { - m_project->setValue(m_buildConfiguration, "buildDirectory", m_pathChooser->path()); + CMakeOpenProjectWizard copw(m_project->projectManager(), m_project->sourceDirectory(), m_project->buildDirectory(m_buildConfiguration)); + if (copw.exec() == QDialog::Accepted) { + m_project->changeBuildDirectory(m_buildConfiguration, copw.buildDirectory()); + m_pathLineEdit->setText(m_project->buildDirectory(m_buildConfiguration)); + } } ///// diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h index 90934d1bcbbaf437688a1800934a4ed83981f180..8de6ea42b0911e3a7ed68f5a3ae40e8958a08d5a 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.h +++ b/src/plugins/cmakeprojectmanager/cmakeproject.h @@ -40,9 +40,10 @@ #include <projectexplorer/toolchain.h> #include <projectexplorer/filewatcher.h> #include <coreplugin/ifile.h> -#include <utils/pathchooser.h> #include <QtCore/QXmlStreamReader> +#include <QtGui/QPushButton> +#include <QtGui/QLineEdit> namespace CMakeProjectManager { namespace Internal { @@ -59,16 +60,20 @@ struct CMakeTarget void clear(); }; +class CMakeBuildSettingsWidget; + class CMakeProject : public ProjectExplorer::Project { Q_OBJECT + // for changeBuildDirectory + friend class CMakeBuildSettingsWidget; public: CMakeProject(CMakeManager *manager, const QString &filename); ~CMakeProject(); virtual QString name() const; virtual Core::IFile *file() const; - virtual ProjectExplorer::IProjectManager *projectManager() const; + virtual CMakeManager *projectManager() const; virtual QList<ProjectExplorer::Project *> dependsOn(); //NBS TODO implement dependsOn @@ -84,29 +89,23 @@ public: // You should probably set some default values in this method virtual void newBuildConfiguration(const QString &buildConfiguration); -// // Returns the list of different views (such as "File View" or "Project View") the project supports. -// virtual QStringList supportedModels() const = 0; -// -// // Returns the tree representing the requested view. -// virtual QModelIndex model(const QString &modelId) const = 0; - virtual ProjectExplorer::ProjectNode *rootProjectNode() const; -// // Conversion functions -// virtual QModelIndex indexForNode(const Node *node, const QString &modelId) const = 0; -// virtual Node *nodeForIndex(const QModelIndex &index) const = 0; -// virtual Node *nodeForFile(const QString &filePath) const = 0; - virtual QStringList files(FilesMode fileMode) const; MakeStep *makeStep() const; QStringList targets() const; QString buildParser(const QString &buildConfiguration) const; CMakeTarget targetForTitle(const QString &title); + QString sourceDirectory() const; + protected: virtual void saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &writer); virtual void restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader &reader); + // called by CMakeBuildSettingsWidget + void changeBuildDirectory(const QString &buildConfiguration, const QString &newBuildDirectory); + private slots: void fileChanged(const QString &fileName); @@ -200,10 +199,11 @@ public: // buildConfiguration is QString::null for the non buildConfiguration specific page virtual void init(const QString &buildConfiguration); private slots: - void buildDirectoryChanged(); + void openChangeBuildDirectoryDialog(); private: CMakeProject *m_project; - Core::Utils::PathChooser *m_pathChooser; + QLineEdit *m_pathLineEdit; + QPushButton *m_changeButton; QString m_buildConfiguration; }; diff --git a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp index 817eeb35c3e68d67a8029d4bbac9920bb1437353..7f7875c1bdb33509f6c490798e02f04f8a77b288 100644 --- a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp @@ -81,7 +81,7 @@ QStringList CMakeRunConfiguration::commandLineArguments() const ProjectExplorer::Environment CMakeRunConfiguration::environment() const { - // TODO + // TODO have a way for the user to setup the environment return ProjectExplorer::Environment::systemEnvironment(); } diff --git a/src/plugins/cmakeprojectmanager/makestep.cpp b/src/plugins/cmakeprojectmanager/makestep.cpp index f67b8081b9136f2e479f160751c63f5ad71bda3f..90fcc25924d483637cd6cad817f3e4f66e4c8f9a 100644 --- a/src/plugins/cmakeprojectmanager/makestep.cpp +++ b/src/plugins/cmakeprojectmanager/makestep.cpp @@ -61,7 +61,6 @@ MakeStep::~MakeStep() bool MakeStep::init(const QString &buildConfiguration) { - // TODO figure out the correct build parser delete m_buildParser; m_buildParser = 0; QString buildParser = m_pro->buildParser(buildConfiguration);