diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp index 74d472ec82a82fcd0de4c436cd08844845881395..02f7517ee1167b9e5c34c3f2720eecb74e8dac3e 100644 --- a/src/plugins/debugger/debuggerrunner.cpp +++ b/src/plugins/debugger/debuggerrunner.cpp @@ -54,6 +54,8 @@ #include <utils/qtcassert.h> #include <utils/qtcprocess.h> +#include <utils/portlist.h> +#include <utils/tcpportsgatherer.h> #include <coreplugin/icore.h> #include <coreplugin/helpmanager.h> @@ -491,7 +493,7 @@ static DebuggerStartParameters localStartParameters(RunConfiguration *runConfigu sp.executable = rc->executable(); if (sp.executable.isEmpty()) return sp; - sp.startMode = StartInternal; + sp.processArgs = rc->commandLineArguments(); sp.useTerminal = rc->runMode() == LocalApplicationRunConfiguration::Console; sp.dumperLibrary = rc->dumperLibrary(); @@ -513,8 +515,22 @@ static DebuggerStartParameters localStartParameters(RunConfiguration *runConfigu sp.languages |= CppLanguage; if (aspect->useQmlDebugger()) { + const ProjectExplorer::IDevice::ConstPtr device = + DeviceKitInformation::device(runConfiguration->target()->kit()); sp.qmlServerAddress = _("127.0.0.1"); - sp.qmlServerPort = aspect->qmlDebugServerPort(); + QTC_ASSERT(device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE, return sp); + TcpPortsGatherer portsGatherer; + portsGatherer.update(QAbstractSocket::UnknownNetworkLayerProtocol); + Utils::PortList portList = device->freePorts(); + int freePort = portsGatherer.getNextFreePort(&portList); + if (freePort == -1) { + if (errorMessage) + *errorMessage = DebuggerPlugin::tr("Not enough free ports for QML debugging. " + "Increase the port range for Desktop device in " + "Device settings."); + return sp; + } + sp.qmlServerPort = freePort; sp.languages |= QmlLanguage; // Makes sure that all bindings go through the JavaScript engine, so that @@ -526,6 +542,8 @@ static DebuggerStartParameters localStartParameters(RunConfiguration *runConfigu QtcProcess::addArg(&sp.processArgs, QString::fromLatin1("-qmljsdebugger=port:%1,block").arg(sp.qmlServerPort)); } + sp.startMode = StartInternal; + // FIXME: If it's not yet build this will be empty and not filled // when rebuild as the runConfiguration is not stored and therefore // cannot be used to retrieve the dumper location. diff --git a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp index 990657f742970eaebb1d89cfd12edcd105691121..696a24a8c60fae4370bbd921327fad5f0721ff26 100644 --- a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp @@ -31,17 +31,27 @@ #include "projectexplorerconstants.h" #include "deviceprocesslist.h" #include "localprocesslist.h" +#include "desktopdeviceconfigurationwidget.h" + +#include <ssh/sshconnection.h> +#include <utils/portlist.h> #include <QCoreApplication> +using namespace ProjectExplorer::Constants; + namespace ProjectExplorer { -DesktopDevice::DesktopDevice() : IDevice(Core::Id(Constants::DESKTOP_DEVICE_TYPE), +DesktopDevice::DesktopDevice() : IDevice(Core::Id(DESKTOP_DEVICE_TYPE), IDevice::AutoDetected, IDevice::Hardware, - Core::Id(Constants::DESKTOP_DEVICE_ID)) + Core::Id(DESKTOP_DEVICE_ID)) { - setDisplayName(QCoreApplication::translate("ProjectExplorer::DesktopDevice", "Run locally")); + setDisplayName(QCoreApplication::translate("ProjectExplorer::DesktopDevice", "Local PC")); + setDeviceState(IDevice::DeviceReadyToUse); + const QString portRange = + QString::fromLatin1("%1-%2").arg(DESKTOP_PORT_START).arg(DESKTOP_PORT_END); + setFreePorts(Utils::PortList::fromString(portRange)); } DesktopDevice::DesktopDevice(const DesktopDevice &other) : @@ -60,7 +70,7 @@ QString DesktopDevice::displayType() const IDeviceWidget *DesktopDevice::createWidget() { - return 0; + return new DesktopDeviceConfigurationWidget(sharedFromThis()); } QList<Core::Id> DesktopDevice::actionIds() const diff --git a/src/plugins/projectexplorer/devicesupport/desktopdeviceconfigurationwidget.cpp b/src/plugins/projectexplorer/devicesupport/desktopdeviceconfigurationwidget.cpp new file mode 100644 index 0000000000000000000000000000000000000000..19120a46ef3effe4d427ccec66eaa27dd20c49b8 --- /dev/null +++ b/src/plugins/projectexplorer/devicesupport/desktopdeviceconfigurationwidget.cpp @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "desktopdeviceconfigurationwidget.h" +#include "ui_desktopdeviceconfigurationwidget.h" +#include "projectexplorerconstants.h" + +#include <utils/portlist.h> +#include <utils/qtcassert.h> + +using namespace ProjectExplorer::Constants; + +namespace ProjectExplorer { + +DesktopDeviceConfigurationWidget::DesktopDeviceConfigurationWidget(const IDevice::Ptr &device, + QWidget *parent) : + IDeviceWidget(device, parent), + m_ui(new Ui::DesktopDeviceConfigurationWidget) +{ + m_ui->setupUi(this); + connect(m_ui->freePortsLineEdit, SIGNAL(textChanged(QString)), + SLOT(updateFreePorts())); + + initGui(); +} + +DesktopDeviceConfigurationWidget::~DesktopDeviceConfigurationWidget() +{ + delete m_ui; +} + +void DesktopDeviceConfigurationWidget::updateDeviceFromUi() +{ + updateFreePorts(); +} + +void DesktopDeviceConfigurationWidget::updateFreePorts() +{ + device()->setFreePorts(Utils::PortList::fromString(m_ui->freePortsLineEdit->text())); + m_ui->portsWarningLabel->setVisible(!device()->freePorts().hasMore()); +} + +void DesktopDeviceConfigurationWidget::initGui() +{ + QTC_CHECK(device()->machineType() == IDevice::Hardware); + m_ui->machineTypeValueLabel->setText(tr("Physical Device")); + m_ui->freePortsLineEdit->setPlaceholderText( + QString::fromLatin1("eg: %1-%2").arg(DESKTOP_PORT_START).arg(DESKTOP_PORT_END)); + m_ui->portsWarningLabel->setPixmap( + QPixmap(QLatin1String(":/projectexplorer/images/compile_warning.png"))); + m_ui->portsWarningLabel->setToolTip(QLatin1String("<font color=\"red\">") + + tr("You will need at least one port for QML debugging.") + + QLatin1String("</font>")); + QRegExpValidator * const portsValidator + = new QRegExpValidator(QRegExp(Utils::PortList::regularExpression()), this); + m_ui->freePortsLineEdit->setValidator(portsValidator); + + m_ui->freePortsLineEdit->setText(device()->freePorts().toString()); + updateFreePorts(); +} + +} // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/devicesupport/desktopdeviceconfigurationwidget.h b/src/plugins/projectexplorer/devicesupport/desktopdeviceconfigurationwidget.h new file mode 100644 index 0000000000000000000000000000000000000000..d0a56701a79ee3635ebaaeb98d4af1e85441ea03 --- /dev/null +++ b/src/plugins/projectexplorer/devicesupport/desktopdeviceconfigurationwidget.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef DESKTOPDEVICECONFIGURATIONWIDGET_H +#define DESKTOPDEVICECONFIGURATIONWIDGET_H + +#include "idevicewidget.h" + +namespace ProjectExplorer { +namespace Ui { +class DesktopDeviceConfigurationWidget; +} + +class DesktopDeviceConfigurationWidget : public IDeviceWidget +{ + Q_OBJECT +public: + explicit DesktopDeviceConfigurationWidget(const IDevice::Ptr &device, QWidget *parent = 0); + ~DesktopDeviceConfigurationWidget(); + + void updateDeviceFromUi(); + +private slots: + void updateFreePorts(); + +private: + void initGui(); + +private: + Ui::DesktopDeviceConfigurationWidget *m_ui; +}; + +} // namespace ProjectExplorer + +#endif // DESKTOPDEVICECONFIGURATIONWIDGET_H diff --git a/src/plugins/projectexplorer/devicesupport/desktopdeviceconfigurationwidget.ui b/src/plugins/projectexplorer/devicesupport/desktopdeviceconfigurationwidget.ui new file mode 100644 index 0000000000000000000000000000000000000000..548dd8813de39fe9d5cc2a7ba7c89f209884749d --- /dev/null +++ b/src/plugins/projectexplorer/devicesupport/desktopdeviceconfigurationwidget.ui @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ProjectExplorer::DesktopDeviceConfigurationWidget</class> + <widget class="QWidget" name="ProjectExplorer::DesktopDeviceConfigurationWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>437</width> + <height>265</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="machineTypeLabel"> + <property name="text"> + <string>Machine type:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="machineTypeValueLabel"> + <property name="text"> + <string>TextLabel</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="freePortsLabel"> + <property name="text"> + <string>Free ports:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLineEdit" name="freePortsLineEdit"/> + </item> + <item> + <widget class="QLabel" name="portsWarningLabel"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/plugins/projectexplorer/devicesupport/desktopdevicefactory.cpp b/src/plugins/projectexplorer/devicesupport/desktopdevicefactory.cpp index c01ee49dfb24aa37434cd18ae9f681d3a6c8e676..24e01d9336396db94ae6c7964d7fa832c9be780b 100644 --- a/src/plugins/projectexplorer/devicesupport/desktopdevicefactory.cpp +++ b/src/plugins/projectexplorer/devicesupport/desktopdevicefactory.cpp @@ -31,6 +31,8 @@ #include "desktopdevice.h" #include "projectexplorerconstants.h" +#include <utils/qtcassert.h> + namespace ProjectExplorer { namespace Internal { @@ -67,8 +69,10 @@ bool DesktopDeviceFactory::canRestore(const QVariantMap &map) const IDevice::Ptr DesktopDeviceFactory::restore(const QVariantMap &map) const { - Q_UNUSED(map); - return IDevice::Ptr(new DesktopDevice); + QTC_ASSERT(canRestore(map), return ProjectExplorer::IDevice::Ptr()); + const ProjectExplorer::IDevice::Ptr device = IDevice::Ptr(new DesktopDevice); + device->fromMap(map); + return device; } } // namespace Internal diff --git a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp index ad2115221ffe23624ea000b05a3a024ebd2d5288..038884ca2d988ed6b5a599a5fc9c47a1a634a3ba 100644 --- a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp @@ -33,9 +33,11 @@ #include <coreplugin/icore.h> #include <extensionsystem/pluginmanager.h> #include <projectexplorer/project.h> +#include <projectexplorer/projectexplorerconstants.h> #include <utils/fileutils.h> #include <utils/persistentsettings.h> #include <utils/qtcassert.h> +#include <utils/portlist.h> #include <QFileInfo> #include <QHash> @@ -163,6 +165,14 @@ void DeviceManager::load() break; } } + // TODO: Remove this in 2.9; this code introduces a bug #QTCREATORBUG-9055 + // Set default port for desktop devices. + if (device->type() == Constants::DESKTOP_DEVICE_TYPE + && device->freePorts().toString().isEmpty()) { + Utils::PortList freePorts; + freePorts.addRange(Constants::DESKTOP_PORT_START, Constants::DESKTOP_PORT_END); + device->setFreePorts(freePorts); + } addDevice(device); } // Append the new SDK devices to the model. diff --git a/src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp b/src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp index 1d7469cd0648aca41e3b57b1b68a4d74c6af4f57..a8204d97ea9bf569c4cbfec992ff60b90781412b 100644 --- a/src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp @@ -95,7 +95,6 @@ DeviceSettingsWidget::DeviceSettingsWidget(QWidget *parent) m_additionalActionsMapper(new QSignalMapper(this)), m_configWidget(0) { - m_deviceManagerModel->setFilter(QList<Core::Id>() << Core::Id(Constants::DESKTOP_DEVICE_ID)); initGui(); connect(m_additionalActionsMapper, SIGNAL(mapped(int)), SLOT(handleAdditionalActionRequest(int))); diff --git a/src/plugins/projectexplorer/localapplicationrunconfiguration.cpp b/src/plugins/projectexplorer/localapplicationrunconfiguration.cpp index 057f2f43a8d506ccd4580d1606e388e56f015e41..841cc46391f7a1de71e146c6f6ee72e4d3305e08 100644 --- a/src/plugins/projectexplorer/localapplicationrunconfiguration.cpp +++ b/src/plugins/projectexplorer/localapplicationrunconfiguration.cpp @@ -40,11 +40,13 @@ namespace ProjectExplorer { LocalApplicationRunConfiguration::LocalApplicationRunConfiguration(Target *target, const Core::Id id) : RunConfiguration(target, id) { + ctor(); } LocalApplicationRunConfiguration::LocalApplicationRunConfiguration(Target *target, LocalApplicationRunConfiguration *rc) : RunConfiguration(target, rc) { + ctor(); } LocalApplicationRunConfiguration::~LocalApplicationRunConfiguration() @@ -58,4 +60,9 @@ Utils::AbstractMacroExpander *LocalApplicationRunConfiguration::macroExpander() return Core::VariableManager::macroExpander(); } +void LocalApplicationRunConfiguration::ctor() +{ + debuggerAspect()->suppressQmlDebuggingSpinbox(); +} + } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/localapplicationrunconfiguration.h b/src/plugins/projectexplorer/localapplicationrunconfiguration.h index 0942e7e6ec5afd6756d30547c14e7a2490490f68..8d9a57bd2aa9cf8ac9013650ddd08862a9a51ab2 100644 --- a/src/plugins/projectexplorer/localapplicationrunconfiguration.h +++ b/src/plugins/projectexplorer/localapplicationrunconfiguration.h @@ -63,6 +63,9 @@ protected: explicit LocalApplicationRunConfiguration(Target *target, LocalApplicationRunConfiguration *rc); Utils::AbstractMacroExpander *macroExpander() const; + +private: + void ctor(); }; } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro index 12d0db35f3d70b7fb2712d17bbaf9d2ac6d321f6..e46b32e44191933c7b457519f44de4e085b9a8a1 100644 --- a/src/plugins/projectexplorer/projectexplorer.pro +++ b/src/plugins/projectexplorer/projectexplorer.pro @@ -121,6 +121,7 @@ HEADERS += projectexplorer.h \ devicesupport/deviceapplicationrunner.h \ devicesupport/localprocesslist.h \ devicesupport/sshdeviceprocesslist.h \ + devicesupport/desktopdeviceconfigurationwidget.h \ deploymentdata.h \ buildtargetinfo.h \ customtoolchain.h \ @@ -232,6 +233,7 @@ SOURCES += projectexplorer.cpp \ devicesupport/deviceapplicationrunner.cpp \ devicesupport/localprocesslist.cpp \ devicesupport/sshdeviceprocesslist.cpp \ + devicesupport/desktopdeviceconfigurationwidget.cpp \ deployablefile.cpp \ customtoolchain.cpp \ projectmacroexpander.cpp @@ -246,7 +248,8 @@ FORMS += processstep.ui \ publishing/publishingwizardselectiondialog.ui \ codestylesettingspropertiespage.ui \ devicesupport/devicefactoryselectiondialog.ui \ - devicesupport/devicesettingswidget.ui + devicesupport/devicesettingswidget.ui \ + devicesupport/desktopdeviceconfigurationwidget.ui WINSOURCES += \ windebuginterface.cpp \ diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs index 136953d0d81d975ca7d116782e3268c3101a25d8..b18b89f44694de0ca0792ad31d6e7ab6a56b5973 100644 --- a/src/plugins/projectexplorer/projectexplorer.qbs +++ b/src/plugins/projectexplorer/projectexplorer.qbs @@ -273,6 +273,9 @@ QtcPlugin { "devicesupport/localprocesslist.h", "devicesupport/sshdeviceprocesslist.cpp", "devicesupport/sshdeviceprocesslist.h", + "devicesupport/desktopdeviceconfigurationwidget.cpp", + "devicesupport/desktopdeviceconfigurationwidget.h", + "devicesupport/desktopdeviceconfigurationwidget.ui", "images/BuildSettings.png", "images/CodeStyleSettings.png", "images/Desktop.png", diff --git a/src/plugins/projectexplorer/projectexplorerconstants.h b/src/plugins/projectexplorer/projectexplorerconstants.h index 9ab4d47e8e6d19f305309b091e07284b5232a9b8..4a5fd3f23eafb23bb060b64f72066cbe9605a45f 100644 --- a/src/plugins/projectexplorer/projectexplorerconstants.h +++ b/src/plugins/projectexplorer/projectexplorerconstants.h @@ -235,6 +235,8 @@ const char DEFAULT_WORKING_DIR[] = "%{buildDir}"; // Desktop Device related ids: const char DESKTOP_DEVICE_ID[] = "Desktop Device"; const char DESKTOP_DEVICE_TYPE[] = "Desktop"; +const int DESKTOP_PORT_START = 30000; +const int DESKTOP_PORT_END = 31000; // Variable Names: const char VAR_CURRENTPROJECT_PREFIX[] = "CurrentProject"; diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp index 3216246ad81c45007da48466bbc2f613dabe92a5..fc49e5b1418c1d102bb03731362000da91c84eb3 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp @@ -93,6 +93,7 @@ void QmlProjectRunConfiguration::ctor() // reset default settings in constructor debuggerAspect()->setUseCppDebugger(false); debuggerAspect()->setUseQmlDebugger(true); + debuggerAspect()->suppressQmlDebuggingSpinbox(); EditorManager *em = Core::EditorManager::instance(); connect(em, SIGNAL(currentEditorChanged(Core::IEditor*)), diff --git a/src/plugins/qmlprojectmanager/qmlprojectruncontrol.cpp b/src/plugins/qmlprojectmanager/qmlprojectruncontrol.cpp index 7ae086727fc579cf3fe8632b34d50047644d03a8..8612ab28ae05804741425a2eb1a83b84bb177f0b 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectruncontrol.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectruncontrol.cpp @@ -33,9 +33,12 @@ #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/target.h> #include <projectexplorer/kit.h> +#include <projectexplorer/kitinformation.h> #include <projectexplorer/project.h> #include <projectexplorer/projectexplorer.h> #include <utils/qtcassert.h> +#include <utils/qtcprocess.h> +#include <utils/tcpportsgatherer.h> #include <debugger/debuggerrunner.h> #include <debugger/debuggerplugin.h> @@ -199,26 +202,43 @@ RunControl *QmlProjectRunControlFactory::createDebugRunControl(QmlProjectRunConf Debugger::DebuggerStartParameters params; params.startMode = Debugger::StartInternal; params.executable = runConfig->observerPath(); - params.qmlServerAddress = QLatin1String("127.0.0.1"); - params.qmlServerPort = runConfig->debuggerAspect()->qmlDebugServerPort(); - params.processArgs = QString::fromLatin1("-qmljsdebugger=port:%1,block").arg(params.qmlServerPort); - params.processArgs += QLatin1Char(' ') + runConfig->viewerArguments(); + params.processArgs = runConfig->viewerArguments(); params.workingDirectory = runConfig->workingDirectory(); params.environment = runConfig->environment(); params.displayName = runConfig->displayName(); params.projectSourceDirectory = runConfig->target()->project()->projectDirectory(); params.projectSourceFiles = runConfig->target()->project()->files(Project::ExcludeGeneratedFiles); - if (runConfig->debuggerAspect()->useQmlDebugger()) + if (runConfig->debuggerAspect()->useQmlDebugger()) { + const ProjectExplorer::IDevice::ConstPtr device = + DeviceKitInformation::device(runConfig->target()->kit()); + params.qmlServerAddress = QLatin1String("127.0.0.1"); + QTC_ASSERT(device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE, return 0); + Utils::TcpPortsGatherer portsGatherer; + portsGatherer.update(QAbstractSocket::UnknownNetworkLayerProtocol); + Utils::PortList portList = device->freePorts(); + int freePort = portsGatherer.getNextFreePort(&portList); + if (freePort == -1) { + if (errorMessage) + *errorMessage = tr("Not enough free ports for QML debugging. Increase the " + "port range for Desktop device in Device settings."); + return 0; + } + params.qmlServerPort = freePort; params.languages |= Debugger::QmlLanguage; + + // Makes sure that all bindings go through the JavaScript engine, so that + // breakpoints are actually hit! + const QString optimizerKey = QLatin1String("QML_DISABLE_OPTIMIZER"); + if (!params.environment.hasKey(optimizerKey)) + params.environment.set(optimizerKey, QLatin1String("1")); + + Utils::QtcProcess::addArg(¶ms.processArgs, + QString::fromLatin1("-qmljsdebugger=port:%1,block").arg( + params.qmlServerPort)); + } if (runConfig->debuggerAspect()->useCppDebugger()) params.languages |= Debugger::CppLanguage; - // Makes sure that all bindings go through the JavaScript engine, so that - // breakpoints are actually hit! - const QString optimizerKey = QLatin1String("QML_DISABLE_OPTIMIZER"); - if (!params.environment.hasKey(optimizerKey)) - params.environment.set(optimizerKey, QLatin1String("1")); - if (params.executable.isEmpty()) { QmlProjectPlugin::showQmlObserverToolWarning(); errorMessage->clear(); // hack, we already showed a error message