1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
36 #include "cmakeprojectconstants.h"
37 #include "cmakeproject.h"
38 #include "cmaketarget.h"
39 #include "cmakebuildconfiguration.h"
41 #include <projectexplorer/buildsteplist.h>
42 #include <projectexplorer/toolchain.h>
43 #include <projectexplorer/projectexplorer.h>
44 #include <projectexplorer/gnumakeparser.h>
46 #include <utils/qtcprocess.h>
48 #include <QtGui/QFormLayout>
49 #include <QtGui/QGroupBox>
50 #include <QtGui/QCheckBox>
51 #include <QtGui/QLineEdit>
52 #include <QtGui/QListWidget>
54 using namespace CMakeProjectManager;
55 using namespace CMakeProjectManager::Internal;
56 using namespace ProjectExplorer;
59 const char * const MS_ID("CMakeProjectManager.MakeStep");
61 const char * const CLEAN_KEY("CMakeProjectManager.MakeStep.Clean");
62 const char * const BUILD_TARGETS_KEY("CMakeProjectManager.MakeStep.BuildTargets");
63 const char * const ADDITIONAL_ARGUMENTS_KEY("CMakeProjectManager.MakeStep.AdditionalArguments");
66 // TODO: Move progress information into an IOutputParser!
68 MakeStep::MakeStep(BuildStepList *bsl) :
69 AbstractProcessStep(bsl, QLatin1String(MS_ID)), m_clean(false),
75 MakeStep::MakeStep(BuildStepList *bsl, const QString &id) :
76 AbstractProcessStep(bsl, id), m_clean(false),
82 MakeStep::MakeStep(BuildStepList *bsl, MakeStep *bs) :
83 AbstractProcessStep(bsl, bs),
86 m_buildTargets(bs->m_buildTargets),
87 m_additionalArguments(Utils::QtcProcess::joinArgs(bs->m_buildTargets))
94 m_percentProgress = QRegExp("^\\[\\s*(\\d*)%\\]");
95 //: Default display name for the cmake make step.
96 setDefaultDisplayName(tr("Make"));
103 CMakeBuildConfiguration *MakeStep::cmakeBuildConfiguration() const
105 return static_cast<CMakeBuildConfiguration *>(buildConfiguration());
108 void MakeStep::setClean(bool clean)
113 QVariantMap MakeStep::toMap() const
115 QVariantMap map(AbstractProcessStep::toMap());
116 map.insert(QLatin1String(CLEAN_KEY), m_clean);
117 map.insert(QLatin1String(BUILD_TARGETS_KEY), m_buildTargets);
118 map.insert(QLatin1String(ADDITIONAL_ARGUMENTS_KEY), m_additionalArguments);
122 bool MakeStep::fromMap(const QVariantMap &map)
124 m_clean = map.value(QLatin1String(CLEAN_KEY)).toBool();
125 m_buildTargets = map.value(QLatin1String(BUILD_TARGETS_KEY)).toStringList();
126 m_additionalArguments = map.value(QLatin1String(ADDITIONAL_ARGUMENTS_KEY)).toString();
128 return BuildStep::fromMap(map);
132 bool MakeStep::init()
134 CMakeBuildConfiguration *bc = cmakeBuildConfiguration();
136 QString arguments = Utils::QtcProcess::joinArgs(m_buildTargets);
137 Utils::QtcProcess::addArgs(&arguments, additionalArguments());
140 setIgnoreReturnValue(m_clean);
142 ProcessParameters *pp = processParameters();
143 pp->setMacroExpander(bc->macroExpander());
144 pp->setEnvironment(bc->environment());
145 pp->setWorkingDirectory(bc->buildDirectory());
146 pp->setCommand(bc->toolChain()->makeCommand());
147 pp->setArguments(arguments);
149 setOutputParser(new ProjectExplorer::GnuMakeParser());
151 appendOutputParser(bc->toolChain()->outputParser());
152 outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory());
154 return AbstractProcessStep::init();
157 void MakeStep::run(QFutureInterface<bool> &fi)
159 m_futureInterface = &fi;
160 m_futureInterface->setProgressRange(0, 100);
161 AbstractProcessStep::run(fi);
162 m_futureInterface->setProgressValue(100);
163 m_futureInterface->reportFinished();
164 m_futureInterface = 0;
167 BuildStepConfigWidget *MakeStep::createConfigWidget()
169 return new MakeStepConfigWidget(this);
172 bool MakeStep::immutable() const
177 void MakeStep::stdOutput(const QString &line)
179 if (m_percentProgress.indexIn(line) != -1) {
181 int percent = m_percentProgress.cap(1).toInt(&ok);;
183 m_futureInterface->setProgressValue(percent);
185 AbstractProcessStep::stdOutput(line);
188 bool MakeStep::buildsBuildTarget(const QString &target) const
190 return m_buildTargets.contains(target);
193 void MakeStep::setBuildTarget(const QString &buildTarget, bool on)
195 QStringList old = m_buildTargets;
196 if (on && !old.contains(buildTarget))
198 else if(!on && old.contains(buildTarget))
199 old.removeOne(buildTarget);
200 m_buildTargets = old;
203 QString MakeStep::additionalArguments() const
205 return m_additionalArguments;
208 void MakeStep::setAdditionalArguments(const QString &list)
210 m_additionalArguments = list;
214 // MakeStepConfigWidget
217 MakeStepConfigWidget::MakeStepConfigWidget(MakeStep *makeStep)
218 : m_makeStep(makeStep)
220 QFormLayout *fl = new QFormLayout(this);
222 fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
225 m_additionalArguments = new QLineEdit(this);
226 fl->addRow(tr("Additional arguments:"), m_additionalArguments);
228 connect(m_additionalArguments, SIGNAL(textEdited(const QString &)), this, SLOT(additionalArgumentsEdited()));
230 m_buildTargetsList = new QListWidget;
231 m_buildTargetsList->setMinimumHeight(200);
232 fl->addRow(tr("Targets:"), m_buildTargetsList);
234 // TODO update this list also on rescans of the CMakeLists.txt
235 // TODO shouldn't be accessing project
236 CMakeProject *pro = m_makeStep->cmakeBuildConfiguration()->cmakeTarget()->cmakeProject();
237 foreach(const QString& buildTarget, pro->buildTargetTitles()) {
238 QListWidgetItem *item = new QListWidgetItem(buildTarget, m_buildTargetsList);
239 item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
240 item->setCheckState(Qt::Unchecked);
243 connect(m_buildTargetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
244 connect(ProjectExplorer::ProjectExplorerPlugin::instance(), SIGNAL(settingsChanged()),
245 this, SLOT(updateDetails()));
249 void MakeStepConfigWidget::additionalArgumentsEdited()
251 m_makeStep->setAdditionalArguments(m_additionalArguments->text());
255 void MakeStepConfigWidget::itemChanged(QListWidgetItem *item)
257 m_makeStep->setBuildTarget(item->text(), item->checkState() & Qt::Checked);
261 QString MakeStepConfigWidget::displayName() const
263 return tr("Make", "CMakeProjectManager::MakeStepConfigWidget display name.");
266 void MakeStepConfigWidget::init()
268 // disconnect to make the changes to the items
269 disconnect(m_buildTargetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
270 int count = m_buildTargetsList->count();
271 for(int i = 0; i < count; ++i) {
272 QListWidgetItem *item = m_buildTargetsList->item(i);
273 item->setCheckState(m_makeStep->buildsBuildTarget(item->text()) ? Qt::Checked : Qt::Unchecked);
276 connect(m_buildTargetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
278 m_additionalArguments->setText(m_makeStep->additionalArguments());
281 CMakeProject *pro = m_makeStep->cmakeBuildConfiguration()->cmakeTarget()->cmakeProject();
282 connect(pro, SIGNAL(buildTargetsChanged()),
283 this, SLOT(buildTargetsChanged()));
286 void MakeStepConfigWidget::buildTargetsChanged()
288 disconnect(m_buildTargetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
289 m_buildTargetsList->clear();
290 CMakeProject *pro = m_makeStep->cmakeBuildConfiguration()->cmakeTarget()->cmakeProject();
291 foreach(const QString& buildTarget, pro->buildTargetTitles()) {
292 QListWidgetItem *item = new QListWidgetItem(buildTarget, m_buildTargetsList);
293 item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
294 item->setCheckState(m_makeStep->buildsBuildTarget(item->text()) ? Qt::Checked : Qt::Unchecked);
296 connect(m_buildTargetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
300 void MakeStepConfigWidget::updateDetails()
302 CMakeBuildConfiguration *bc = m_makeStep->cmakeBuildConfiguration();
303 ProjectExplorer::ToolChain *tc = bc->toolChain();
305 QString arguments = Utils::QtcProcess::joinArgs(m_makeStep->m_buildTargets);
306 Utils::QtcProcess::addArgs(&arguments, m_makeStep->additionalArguments());
308 ProcessParameters param;
309 param.setMacroExpander(bc->macroExpander());
310 param.setEnvironment(bc->environment());
311 param.setWorkingDirectory(bc->buildDirectory());
312 param.setCommand(tc->makeCommand());
313 param.setArguments(arguments);
314 m_summaryText = param.summary(displayName());
316 m_summaryText = tr("<b>Unknown Toolchain</b>");
318 emit updateSummary();
321 QString MakeStepConfigWidget::summaryText() const
323 return m_summaryText;
330 MakeStepFactory::MakeStepFactory(QObject *parent) :
331 ProjectExplorer::IBuildStepFactory(parent)
335 MakeStepFactory::~MakeStepFactory()
339 bool MakeStepFactory::canCreate(BuildStepList *parent, const QString &id) const
341 if (parent->target()->project()->id() != QLatin1String(Constants::CMAKEPROJECT_ID))
343 return QLatin1String(MS_ID) == id;
346 BuildStep *MakeStepFactory::create(BuildStepList *parent, const QString &id)
348 if (!canCreate(parent, id))
350 return new MakeStep(parent);
353 bool MakeStepFactory::canClone(BuildStepList *parent, BuildStep *source) const
355 return canCreate(parent, source->id());
358 BuildStep *MakeStepFactory::clone(BuildStepList *parent, BuildStep *source)
360 if (!canClone(parent, source))
362 return new MakeStep(parent, static_cast<MakeStep *>(source));
365 bool MakeStepFactory::canRestore(BuildStepList *parent, const QVariantMap &map) const
367 QString id(ProjectExplorer::idFromMap(map));
368 return canCreate(parent, id);
371 BuildStep *MakeStepFactory::restore(BuildStepList *parent, const QVariantMap &map)
373 if (!canRestore(parent, map))
375 MakeStep *bs(new MakeStep(parent));
376 if (bs->fromMap(map))
382 QStringList MakeStepFactory::availableCreationIds(ProjectExplorer::BuildStepList *parent) const
384 if (parent->target()->project()->id() == QLatin1String(Constants::CMAKEPROJECT_ID))
385 return QStringList() << QLatin1String(MS_ID);
386 return QStringList();
389 QString MakeStepFactory::displayNameForId(const QString &id) const
391 if (id == QLatin1String(MS_ID))
392 return tr("Make", "Display name for CMakeProjectManager::MakeStep id.");