1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
10 ** GNU Lesser General Public License Usage
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
31 **************************************************************************/
33 #include "cmakerunconfiguration.h"
35 #include "cmakebuildconfiguration.h"
36 #include "cmakeproject.h"
37 #include "cmakeprojectconstants.h"
38 #include "cmaketarget.h"
40 #include <coreplugin/coreconstants.h>
41 #include <coreplugin/helpmanager.h>
42 #include <projectexplorer/debugginghelper.h>
43 #include <projectexplorer/environmentwidget.h>
45 #include <utils/pathchooser.h>
46 #include <utils/detailswidget.h>
47 #include <utils/qtcassert.h>
48 #include <utils/debuggerlanguagechooser.h>
50 #include <QtGui/QFormLayout>
51 #include <QtGui/QLineEdit>
52 #include <QtGui/QGroupBox>
53 #include <QtGui/QLabel>
54 #include <QtGui/QComboBox>
55 #include <QtGui/QToolButton>
57 using namespace CMakeProjectManager;
58 using namespace CMakeProjectManager::Internal;
61 const char * const CMAKE_RC_ID("CMakeProjectManager.CMakeRunConfiguration");
62 const char * const CMAKE_RC_PREFIX("CMakeProjectManager.CMakeRunConfiguration.");
64 const char * const USER_WORKING_DIRECTORY_KEY("CMakeProjectManager.CMakeRunConfiguration.UserWorkingDirectory");
65 const char * const USE_TERMINAL_KEY("CMakeProjectManager.CMakeRunConfiguration.UseTerminal");
66 const char * const TITLE_KEY("CMakeProjectManager.CMakeRunConfiguation.Title");
67 const char * const ARGUMENTS_KEY("CMakeProjectManager.CMakeRunConfiguration.Arguments");
68 const char * const USER_ENVIRONMENT_CHANGES_KEY("CMakeProjectManager.CMakeRunConfiguration.UserEnvironmentChanges");
69 const char * const BASE_ENVIRONMENT_BASE_KEY("CMakeProjectManager.BaseEnvironmentBase");
71 QString buildTargetFromId(const QString &id)
73 if (!id.startsWith(QLatin1String(CMAKE_RC_PREFIX)))
75 return id.mid(QString::fromLatin1(CMAKE_RC_PREFIX).length());
78 QString idFromBuildTarget(const QString &target)
80 return QString::fromLatin1(CMAKE_RC_PREFIX) + target;
85 CMakeRunConfiguration::CMakeRunConfiguration(CMakeTarget *parent, const QString &target, const QString &workingDirectory, const QString &title) :
86 ProjectExplorer::LocalApplicationRunConfiguration(parent, QString::fromLatin1(CMAKE_RC_PREFIX)),
88 m_buildTarget(target),
89 m_workingDirectory(workingDirectory),
91 m_baseEnvironmentBase(CMakeRunConfiguration::BuildEnvironmentBase),
97 CMakeRunConfiguration::CMakeRunConfiguration(CMakeTarget *parent, CMakeRunConfiguration *source) :
98 ProjectExplorer::LocalApplicationRunConfiguration(parent, source),
99 m_runMode(source->m_runMode),
100 m_buildTarget(source->m_buildTarget),
101 m_workingDirectory(source->m_workingDirectory),
102 m_userWorkingDirectory(source->m_userWorkingDirectory),
103 m_title(source->m_title),
104 m_arguments(source->m_arguments),
105 m_userEnvironmentChanges(source->m_userEnvironmentChanges),
106 m_baseEnvironmentBase(source->m_baseEnvironmentBase),
107 m_enabled(source->m_enabled)
112 CMakeRunConfiguration::~CMakeRunConfiguration()
116 void CMakeRunConfiguration::ctor()
118 setDefaultDisplayName(defaultDisplayName());
121 CMakeTarget *CMakeRunConfiguration::cmakeTarget() const
123 return static_cast<CMakeTarget *>(target());
126 CMakeBuildConfiguration *CMakeRunConfiguration::activeBuildConfiguration() const
128 return cmakeTarget()->activeBuildConfiguration();
131 QString CMakeRunConfiguration::executable() const
133 return m_buildTarget;
136 ProjectExplorer::LocalApplicationRunConfiguration::RunMode CMakeRunConfiguration::runMode() const
141 QString CMakeRunConfiguration::workingDirectory() const
143 return QDir::cleanPath(environment().expandVariables(
144 Utils::expandMacros(baseWorkingDirectory(), macroExpander())));
147 QString CMakeRunConfiguration::baseWorkingDirectory() const
149 if (!m_userWorkingDirectory.isEmpty())
150 return m_userWorkingDirectory;
151 return m_workingDirectory;
154 QString CMakeRunConfiguration::commandLineArguments() const
156 return Utils::QtcProcess::expandMacros(m_arguments, macroExpander());
159 QString CMakeRunConfiguration::title() const
164 void CMakeRunConfiguration::setExecutable(const QString &executable)
166 m_buildTarget = executable;
169 void CMakeRunConfiguration::setBaseWorkingDirectory(const QString &wd)
171 const QString &oldWorkingDirectory = workingDirectory();
173 m_workingDirectory = wd;
175 const QString &newWorkingDirectory = workingDirectory();
176 if (oldWorkingDirectory != newWorkingDirectory)
177 emit baseWorkingDirectoryChanged(newWorkingDirectory);
180 void CMakeRunConfiguration::setUserWorkingDirectory(const QString &wd)
182 const QString & oldWorkingDirectory = workingDirectory();
184 m_userWorkingDirectory = wd;
186 const QString &newWorkingDirectory = workingDirectory();
187 if (oldWorkingDirectory != newWorkingDirectory)
188 emit baseWorkingDirectoryChanged(newWorkingDirectory);
191 QVariantMap CMakeRunConfiguration::toMap() const
193 QVariantMap map(ProjectExplorer::LocalApplicationRunConfiguration::toMap());
195 map.insert(QLatin1String(USER_WORKING_DIRECTORY_KEY), m_userWorkingDirectory);
196 map.insert(QLatin1String(USE_TERMINAL_KEY), m_runMode == Console);
197 map.insert(QLatin1String(TITLE_KEY), m_title);
198 map.insert(QLatin1String(ARGUMENTS_KEY), m_arguments);
199 map.insert(QLatin1String(USER_ENVIRONMENT_CHANGES_KEY), Utils::EnvironmentItem::toStringList(m_userEnvironmentChanges));
200 map.insert(QLatin1String(BASE_ENVIRONMENT_BASE_KEY), m_baseEnvironmentBase);
205 bool CMakeRunConfiguration::fromMap(const QVariantMap &map)
207 m_userWorkingDirectory = map.value(QLatin1String(USER_WORKING_DIRECTORY_KEY)).toString();
208 m_runMode = map.value(QLatin1String(USE_TERMINAL_KEY)).toBool() ? Console : Gui;
209 m_title = map.value(QLatin1String(TITLE_KEY)).toString();
210 m_arguments = map.value(QLatin1String(ARGUMENTS_KEY)).toString();
211 m_userEnvironmentChanges = Utils::EnvironmentItem::fromStringList(map.value(QLatin1String(USER_ENVIRONMENT_CHANGES_KEY)).toStringList());
212 m_baseEnvironmentBase = static_cast<BaseEnvironmentBase>(map.value(QLatin1String(BASE_ENVIRONMENT_BASE_KEY), static_cast<int>(CMakeRunConfiguration::BuildEnvironmentBase)).toInt());
214 return RunConfiguration::fromMap(map);
217 QString CMakeRunConfiguration::defaultDisplayName() const
219 if (m_title.isEmpty())
220 return tr("Run CMake target");
221 return m_title + (m_enabled ? "" : tr(" (disabled)"));
224 QWidget *CMakeRunConfiguration::createConfigurationWidget()
226 return new CMakeRunConfigurationWidget(this);
229 void CMakeRunConfiguration::setCommandLineArguments(const QString &newText)
231 m_arguments = newText;
234 QString CMakeRunConfiguration::dumperLibrary() const
236 QString qmakePath = ProjectExplorer::DebuggingHelperLibrary::findSystemQt(environment());
237 QString qtInstallData = ProjectExplorer::DebuggingHelperLibrary::qtInstallDataDir(qmakePath);
238 QString dhl = ProjectExplorer::DebuggingHelperLibrary::debuggingHelperLibraryByInstallData(qtInstallData);
242 QStringList CMakeRunConfiguration::dumperLibraryLocations() const
244 QString qmakePath = ProjectExplorer::DebuggingHelperLibrary::findSystemQt(environment());
245 QString qtInstallData = ProjectExplorer::DebuggingHelperLibrary::qtInstallDataDir(qmakePath);
246 return ProjectExplorer::DebuggingHelperLibrary::locationsByInstallData(qtInstallData);
249 Utils::Environment CMakeRunConfiguration::baseEnvironment() const
251 Utils::Environment env;
252 if (m_baseEnvironmentBase == CMakeRunConfiguration::CleanEnvironmentBase) {
254 } else if (m_baseEnvironmentBase == CMakeRunConfiguration::SystemEnvironmentBase) {
255 env = Utils::Environment::systemEnvironment();
256 } else if (m_baseEnvironmentBase == CMakeRunConfiguration::BuildEnvironmentBase) {
257 env = activeBuildConfiguration()->environment();
262 QString CMakeRunConfiguration::baseEnvironmentText() const
264 if (m_baseEnvironmentBase == CMakeRunConfiguration::CleanEnvironmentBase) {
265 return tr("Clean Environment");
266 } else if (m_baseEnvironmentBase == CMakeRunConfiguration::SystemEnvironmentBase) {
267 return tr("System Environment");
268 } else if (m_baseEnvironmentBase == CMakeRunConfiguration::BuildEnvironmentBase) {
269 return tr("Build Environment");
274 void CMakeRunConfiguration::setBaseEnvironmentBase(BaseEnvironmentBase env)
276 if (m_baseEnvironmentBase == env)
278 m_baseEnvironmentBase = env;
279 emit baseEnvironmentChanged();
282 CMakeRunConfiguration::BaseEnvironmentBase CMakeRunConfiguration::baseEnvironmentBase() const
284 return m_baseEnvironmentBase;
287 Utils::Environment CMakeRunConfiguration::environment() const
289 Utils::Environment env = baseEnvironment();
290 env.modify(userEnvironmentChanges());
294 QList<Utils::EnvironmentItem> CMakeRunConfiguration::userEnvironmentChanges() const
296 return m_userEnvironmentChanges;
299 void CMakeRunConfiguration::setUserEnvironmentChanges(const QList<Utils::EnvironmentItem> &diff)
301 if (m_userEnvironmentChanges != diff) {
302 m_userEnvironmentChanges = diff;
303 emit userEnvironmentChangesChanged(diff);
307 void CMakeRunConfiguration::setEnabled(bool b)
312 emit isEnabledChanged(isEnabled());
313 setDefaultDisplayName(defaultDisplayName());
316 bool CMakeRunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration *bc) const
318 return m_enabled && LocalApplicationRunConfiguration::isEnabled(bc);
321 // Configuration widget
322 CMakeRunConfigurationWidget::CMakeRunConfigurationWidget(CMakeRunConfiguration *cmakeRunConfiguration, QWidget *parent)
323 : QWidget(parent), m_ignoreChange(false), m_cmakeRunConfiguration(cmakeRunConfiguration)
325 QFormLayout *fl = new QFormLayout();
327 fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
328 QLineEdit *argumentsLineEdit = new QLineEdit();
329 argumentsLineEdit->setText(cmakeRunConfiguration->commandLineArguments());
330 connect(argumentsLineEdit, SIGNAL(textChanged(QString)),
331 this, SLOT(setArguments(QString)));
332 fl->addRow(tr("Arguments:"), argumentsLineEdit);
334 m_workingDirectoryEdit = new Utils::PathChooser();
335 m_workingDirectoryEdit->setExpectedKind(Utils::PathChooser::Directory);
336 m_workingDirectoryEdit->setBaseDirectory(m_cmakeRunConfiguration->target()->project()->projectDirectory());
337 m_workingDirectoryEdit->setPath(m_cmakeRunConfiguration->baseWorkingDirectory());
338 m_workingDirectoryEdit->setPromptDialogTitle(tr("Select Working Directory"));
340 QToolButton *resetButton = new QToolButton();
341 resetButton->setToolTip(tr("Reset to default"));
342 resetButton->setIcon(QIcon(QLatin1String(Core::Constants::ICON_RESET)));
344 QHBoxLayout *boxlayout = new QHBoxLayout();
345 boxlayout->addWidget(m_workingDirectoryEdit);
346 boxlayout->addWidget(resetButton);
348 fl->addRow(tr("Working directory:"), boxlayout);
350 QWidget *debuggerLabelWidget = new QWidget(this);
351 QVBoxLayout *debuggerLabelLayout = new QVBoxLayout(debuggerLabelWidget);
352 debuggerLabelLayout->setMargin(0);
353 debuggerLabelLayout->setSpacing(0);
354 debuggerLabelWidget->setLayout(debuggerLabelLayout);
355 QLabel *debuggerLabel = new QLabel(tr("Debugger:"), this);
356 debuggerLabelLayout->addWidget(debuggerLabel);
357 debuggerLabelLayout->addStretch(10);
359 m_debuggerLanguageChooser = new Utils::DebuggerLanguageChooser(this);
360 fl->addRow(debuggerLabelWidget, m_debuggerLanguageChooser);
362 m_debuggerLanguageChooser->setCppChecked(m_cmakeRunConfiguration->useCppDebugger());
363 m_debuggerLanguageChooser->setQmlChecked(m_cmakeRunConfiguration->useQmlDebugger());
364 m_debuggerLanguageChooser->setQmlDebugServerPort(m_cmakeRunConfiguration->qmlDebugServerPort());
366 m_detailsContainer = new Utils::DetailsWidget(this);
367 m_detailsContainer->setState(Utils::DetailsWidget::NoSummary);
369 QWidget *m_details = new QWidget(m_detailsContainer);
370 m_detailsContainer->setWidget(m_details);
371 m_details->setLayout(fl);
373 QVBoxLayout *vbx = new QVBoxLayout(this);
375 vbx->addWidget(m_detailsContainer);
377 QLabel *environmentLabel = new QLabel(this);
378 environmentLabel->setText(tr("Run Environment"));
379 QFont f = environmentLabel->font();
381 f.setPointSizeF(f.pointSizeF() *1.2);
382 environmentLabel->setFont(f);
383 vbx->addWidget(environmentLabel);
385 QWidget *baseEnvironmentWidget = new QWidget;
386 QHBoxLayout *baseEnvironmentLayout = new QHBoxLayout(baseEnvironmentWidget);
387 baseEnvironmentLayout->setMargin(0);
388 QLabel *label = new QLabel(tr("Base environment for this runconfiguration:"), this);
389 baseEnvironmentLayout->addWidget(label);
390 m_baseEnvironmentComboBox = new QComboBox(this);
391 m_baseEnvironmentComboBox->addItems(QStringList()
392 << tr("Clean Environment")
393 << tr("System Environment")
394 << tr("Build Environment"));
395 m_baseEnvironmentComboBox->setCurrentIndex(m_cmakeRunConfiguration->baseEnvironmentBase());
396 connect(m_baseEnvironmentComboBox, SIGNAL(currentIndexChanged(int)),
397 this, SLOT(baseEnvironmentComboBoxChanged(int)));
398 baseEnvironmentLayout->addWidget(m_baseEnvironmentComboBox);
399 baseEnvironmentLayout->addStretch(10);
401 m_environmentWidget = new ProjectExplorer::EnvironmentWidget(this, baseEnvironmentWidget);
402 m_environmentWidget->setBaseEnvironment(m_cmakeRunConfiguration->baseEnvironment());
403 m_environmentWidget->setBaseEnvironmentText(m_cmakeRunConfiguration->baseEnvironmentText());
404 m_environmentWidget->setUserChanges(m_cmakeRunConfiguration->userEnvironmentChanges());
406 vbx->addWidget(m_environmentWidget);
408 connect(m_workingDirectoryEdit, SIGNAL(changed(QString)),
409 this, SLOT(setWorkingDirectory()));
411 connect(resetButton, SIGNAL(clicked()),
412 this, SLOT(resetWorkingDirectory()));
414 connect(m_debuggerLanguageChooser, SIGNAL(cppLanguageToggled(bool)),
415 this, SLOT(useCppDebuggerToggled(bool)));
416 connect(m_debuggerLanguageChooser, SIGNAL(qmlLanguageToggled(bool)),
417 this, SLOT(useQmlDebuggerToggled(bool)));
418 connect(m_debuggerLanguageChooser, SIGNAL(qmlDebugServerPortChanged(uint)),
419 this, SLOT(qmlDebugServerPortChanged(uint)));
420 connect(m_debuggerLanguageChooser, SIGNAL(openHelpUrl(QString)),
421 Core::HelpManager::instance(), SLOT(handleHelpRequest(QString)));
423 connect(m_environmentWidget, SIGNAL(userChangesChanged()),
424 this, SLOT(userChangesChanged()));
426 connect(m_cmakeRunConfiguration, SIGNAL(baseWorkingDirectoryChanged(QString)),
427 this, SLOT(workingDirectoryChanged(QString)));
428 connect(m_cmakeRunConfiguration, SIGNAL(baseEnvironmentChanged()),
429 this, SLOT(baseEnvironmentChanged()));
430 connect(m_cmakeRunConfiguration, SIGNAL(userEnvironmentChangesChanged(QList<Utils::EnvironmentItem>)),
431 this, SLOT(userEnvironmentChangesChanged()));
433 setEnabled(m_cmakeRunConfiguration->isEnabled());
436 void CMakeRunConfigurationWidget::setWorkingDirectory()
440 m_ignoreChange = true;
441 m_cmakeRunConfiguration->setUserWorkingDirectory(m_workingDirectoryEdit->rawPath());
442 m_ignoreChange = false;
445 void CMakeRunConfigurationWidget::workingDirectoryChanged(const QString &workingDirectory)
448 m_workingDirectoryEdit->setPath(workingDirectory);
451 void CMakeRunConfigurationWidget::resetWorkingDirectory()
453 // This emits a signal connected to workingDirectoryChanged()
454 // that sets the m_workingDirectoryEdit
455 m_cmakeRunConfiguration->setUserWorkingDirectory(QString());
458 void CMakeRunConfigurationWidget::useCppDebuggerToggled(bool toggled)
460 m_cmakeRunConfiguration->setUseCppDebugger(toggled);
463 void CMakeRunConfigurationWidget::useQmlDebuggerToggled(bool toggled)
465 m_cmakeRunConfiguration->setUseQmlDebugger(toggled);
468 void CMakeRunConfigurationWidget::qmlDebugServerPortChanged(uint port)
470 m_cmakeRunConfiguration->setQmlDebugServerPort(port);
473 void CMakeRunConfigurationWidget::userChangesChanged()
475 m_cmakeRunConfiguration->setUserEnvironmentChanges(m_environmentWidget->userChanges());
478 void CMakeRunConfigurationWidget::baseEnvironmentComboBoxChanged(int index)
480 m_ignoreChange = true;
481 m_cmakeRunConfiguration->setBaseEnvironmentBase(CMakeRunConfiguration::BaseEnvironmentBase(index));
483 m_environmentWidget->setBaseEnvironment(m_cmakeRunConfiguration->baseEnvironment());
484 m_environmentWidget->setBaseEnvironmentText(m_cmakeRunConfiguration->baseEnvironmentText());
485 m_ignoreChange = false;
488 void CMakeRunConfigurationWidget::baseEnvironmentChanged()
493 m_baseEnvironmentComboBox->setCurrentIndex(m_cmakeRunConfiguration->baseEnvironmentBase());
494 m_environmentWidget->setBaseEnvironment(m_cmakeRunConfiguration->baseEnvironment());
495 m_environmentWidget->setBaseEnvironmentText(m_cmakeRunConfiguration->baseEnvironmentText());
498 void CMakeRunConfigurationWidget::userEnvironmentChangesChanged()
500 m_environmentWidget->setUserChanges(m_cmakeRunConfiguration->userEnvironmentChanges());
503 void CMakeRunConfigurationWidget::setArguments(const QString &args)
505 m_cmakeRunConfiguration->setCommandLineArguments(args);
509 CMakeRunConfigurationFactory::CMakeRunConfigurationFactory(QObject *parent) :
510 ProjectExplorer::IRunConfigurationFactory(parent)
514 CMakeRunConfigurationFactory::~CMakeRunConfigurationFactory()
518 // used to show the list of possible additons to a project, returns a list of ids
519 QStringList CMakeRunConfigurationFactory::availableCreationIds(ProjectExplorer::Target *parent) const
521 CMakeTarget *t(qobject_cast<CMakeTarget *>(parent));
523 return QStringList();
525 foreach (const QString &buildTarget, t->cmakeProject()->buildTargetTitles())
526 allIds << idFromBuildTarget(buildTarget);
530 // used to translate the ids to names to display to the user
531 QString CMakeRunConfigurationFactory::displayNameForId(const QString &id) const
533 return buildTargetFromId(id);
536 bool CMakeRunConfigurationFactory::canCreate(ProjectExplorer::Target *parent, const QString &id) const
538 CMakeTarget *t(qobject_cast<CMakeTarget *>(parent));
541 return t->cmakeProject()->hasBuildTarget(buildTargetFromId(id));
544 ProjectExplorer::RunConfiguration *CMakeRunConfigurationFactory::create(ProjectExplorer::Target *parent, const QString &id)
546 if (!canCreate(parent, id))
548 CMakeTarget *t(static_cast<CMakeTarget *>(parent));
550 const QString title(buildTargetFromId(id));
551 const CMakeBuildTarget &ct = t->cmakeProject()->buildTargetForTitle(title);
552 return new CMakeRunConfiguration(t, ct.executable, ct.workingDirectory, ct.title);
555 bool CMakeRunConfigurationFactory::canClone(ProjectExplorer::Target *parent, ProjectExplorer::RunConfiguration *source) const
557 if (!qobject_cast<CMakeTarget *>(parent))
559 return source->id() == QLatin1String(CMAKE_RC_ID);
562 ProjectExplorer::RunConfiguration *CMakeRunConfigurationFactory::clone(ProjectExplorer::Target *parent, ProjectExplorer::RunConfiguration * source)
564 if (!canClone(parent, source))
566 CMakeTarget *t(static_cast<CMakeTarget *>(parent));
567 CMakeRunConfiguration *crc(static_cast<CMakeRunConfiguration *>(source));
568 return new CMakeRunConfiguration(t, crc);
571 bool CMakeRunConfigurationFactory::canRestore(ProjectExplorer::Target *parent, const QVariantMap &map) const
573 if (!qobject_cast<CMakeTarget *>(parent))
575 QString id(ProjectExplorer::idFromMap(map));
576 return id.startsWith(QLatin1String(CMAKE_RC_ID));
579 ProjectExplorer::RunConfiguration *CMakeRunConfigurationFactory::restore(ProjectExplorer::Target *parent, const QVariantMap &map)
581 if (!canRestore(parent, map))
583 CMakeTarget *t(static_cast<CMakeTarget *>(parent));
584 CMakeRunConfiguration *rc(new CMakeRunConfiguration(t, QString(), QString(), QString()));
585 if (rc->fromMap(map))