Commit bb966352 authored by Eike Ziller's avatar Eike Ziller

Merge remote-tracking branch 'origin/4.5'

Change-Id: Ie83666bd18e899dabf5190c360027bf02abecdaf
parents 7208ef1f 38d307ff
......@@ -42,7 +42,47 @@
the contained components, and therefore, the modules must provide extra type
information for code completion and the semantic checks to work correctly.
When you write a QML module or use QML from a C++ application you typically
To create a QML module and make it appear in the \uicontrol Library in
\QMLD:
\list 1
\li Create custom QML controls and place all the \c .qml files in a
directory dedicated to your module.
\li Create a \c qmldir file for your module and place it in the module
directory. For more information, see
\l {Module Definition qmldir Files}.
\li Create a \c qmltypes file, preferably using \c qmlplugindump.
For more information see, \l {Generating qmltypes Files}.
\li Create a directory named \c designer in your module directory.
\li Create a \c .metainfo file for your module and place it in the
\c designer directory. Meta information is needed to display the
components in the \uicontrol {QML Types} tab in the \uicontrol
Library. Use a metainfo file delivered with Qt, such as
\c qtquickcontrols2.metainfo, as an example.
\li Import your module into a project using \c QML_IMPORT_PATH in the
.pro file: \c {QML_IMPORT_PATH += path/to/module}.
For more information, see \l {Importing QML Modules}.
\li Make sure that the QML emulation layer of \QMLD is built with
the same Qt version as your QML modules. For more information, see
\l {Running QML Modules in Qt Quick Designer}. You can also try
skipping this step and take it later, if necessary.
\endlist
Your module should now appear in the \uicontrol Imports tab in the
\uicontrol Library in \QMLD. Your components should appear in the
\uicontrol {QML Types} tab if a valid \c .metainfo file is in place.
\section1 Registering QML Types
When you write a QML module or use QML from a C++ application, you typically
register new types with the qmlRegisterType() function or expose some
class instances with \l{QQmlContext::setContextProperty()}. The \QC C++
code model now scans for these calls and
......@@ -55,19 +95,7 @@
Classes registered with \c qmlRegisterType() can be used as backend objects
in the \QMLD. For more information, see \l {Adding Connections}.
By default, \QC will look in the QML import path of Qt for QML modules.
If your applications adds additional import paths that \QC should use,
then you can specify those using \c{QML_IMPORT_PATH} in the \c{.pro} file of your
application.
If you use CMake, add the following command to the CMakeLists.txt file to
set the QML import path:
\code
{set(QML_IMPORT_PATH ${CMAKE_SOURCE_DIR}/qml ${CMAKE_BINARY_DIR}/imports CACHE string "" FORCE)}
\endcode
The import path affects all the targets built by the CMake project.
\section1 Generating qmltypes Files
Ideally, QML modules have a \c{plugins.qmltypes} file in the same directory
as the \c qmldir file. The \c qmltypes file contains a description of the
......@@ -79,20 +107,18 @@
addition to \c{plugins.qmltypes}. For more information, see
\l{Writing a qmltypes File}.
\section1 Generating qmltypes Files
You can create and edit \c qmltypes files manually, but you are recommended
to use the \c qmlplugindump tool shipped with Qt 4.8 and later to generate
them automatically.
Once you have obtained qmlplugindump for the Qt version the QML module's
Once you have obtained \c qmlplugindump for the Qt version the QML module's
plugins were compiled with, run the following command to load My.Module
version 1.0 from \c{/import/path/my/module} including all its plugins and
output a description of the plugins' types to
\c{/import/path/my/module/plugins.qmltypes}:
\code
qmlplugindump My.Module 1.0 /import/path > /import/path/my/module/plugins.qmltypes
qmlplugindump -nonrelocatable My.Module 1.0 /import/path > /import/path/my/module/plugins.qmltypes
\endcode
You can safely ignore the debug output.
......@@ -101,13 +127,29 @@
the sources in \c{<QtCreator>/share/qtcreator/qml/qmldump} if the Qt version
contains private headers.
\section1 Dumping Plugins Automatically
\section2 Dumping Plugins Automatically
If a module with plugins lacks the \c qmltypes file, \QC tries to generate
a temporary file itself by running the \c qmldump program in the background.
However, this automatic dumping is a fallback mechanism with many points of
failure and you cannot rely upon it.
\section1 Importing QML Modules
By default, \QC will look in the QML import path of Qt for QML modules.
If your applications adds additional import paths that \QC should use,
then you can specify those using \c{QML_IMPORT_PATH} in the \c{.pro} file of your
application.
If you use CMake, add the following command to the CMakeLists.txt file to
set the QML import path:
\code
{set(QML_IMPORT_PATH ${CMAKE_SOURCE_DIR}/qml ${CMAKE_BINARY_DIR}/imports CACHE string "" FORCE)}
\endcode
The import path affects all the targets built by the CMake project.
\section1 Running QML Modules in Qt Quick Designer
\QMLD uses a QML emulation layer (also called QML Puppet) to render and
......
......@@ -15,7 +15,11 @@ QtcProduct {
project.buildDirectory + '/' + qtc.ide_library_path,
project.buildDirectory + '/' + qtc.ide_plugin_path
]
cpp.defines: base.filter(function(d) { return d != "QT_RESTRICTED_CAST_FROM_ASCII"; })
cpp.defines: base.filter(function(d) {
return d !== "QT_RESTRICTED_CAST_FROM_ASCII"
&& d !== "QT_USE_FAST_OPERATOR_PLUS"
&& d !== "QT_USE_FAST_CONCATENATION";
})
Group {
fileTagsFilter: product.type
......
......@@ -76,6 +76,8 @@ Module {
"QT_NO_CAST_TO_ASCII",
"QT_RESTRICTED_CAST_FROM_ASCII",
"QT_DISABLE_DEPRECATED_BEFORE=0x050600",
"QT_USE_FAST_OPERATOR_PLUS",
"QT_USE_FAST_CONCATENATION",
].concat(testsEnabled ? ["WITH_TESTS"] : [])
Rule {
......
......@@ -693,7 +693,7 @@ static inline QString fixComponentPathForIncompatibleQt(const QString &component
//plugin directories might contain the version number
fixedPath.chop(4);
fixedPath += QLatin1Char('/') + QFileInfo(componentPath).fileName();
if (QFileInfo(fixedPath).exists())
if (QFileInfo::exists(fixedPath))
return fixedPath;
}
}
......
......@@ -11,7 +11,7 @@
</rect>
</property>
<property name="windowTitle">
<string>Plugin loader messages</string>
<string>Plugin Loader Messages</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
......
/****************************************************************************
**
** Copyright (C) 2016 Konstantin Tokarev <annulen@yandex.ru>
** Contact: https://www.qt.io/licensing/
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "bracematcher.h"
#include <QTextDocument>
#include <QTextCursor>
/*!
\class Utils::BraceMatcher
\brief The BraceMatcher class implements a generic autocompleter of braces
and quotes.
This is a helper class for autocompleter implementations. To use it,
define \e brace, \e quote, and \e delimiter characters for a given language.
*/
namespace Utils {
/*!
* Adds a pair of characters, corresponding to \a opening and \a closing braces.
*/
void BraceMatcher::addBraceCharPair(const QChar opening, const QChar closing)
{
m_braceChars[opening] = closing;
}
/*!
* Adds a \a quote character.
*/
void BraceMatcher::addQuoteChar(const QChar quote)
{
m_quoteChars << quote;
}
/*!
* Adds a separator character \a sep that should be skipped when overtyping it.
* For example, it could be ';' or ',' in C-like languages.
*/
void BraceMatcher::addDelimiterChar(const QChar sep)
{
m_delimiterChars << sep;
}
bool BraceMatcher::shouldInsertMatchingText(const QTextCursor &tc) const
{
QTextDocument *doc = tc.document();
return shouldInsertMatchingText(doc->characterAt(tc.selectionEnd()));
}
bool BraceMatcher::shouldInsertMatchingText(const QChar lookAhead) const
{
return lookAhead.isSpace()
|| isQuote(lookAhead)
|| isDelimiter(lookAhead)
|| isClosingBrace(lookAhead);
}
QString BraceMatcher::insertMatchingBrace(const QTextCursor &cursor,
const QString &text,
const QChar la,
int *skippedChars) const
{
if (text.length() != 1)
return QString();
if (!shouldInsertMatchingText(cursor))
return QString();
const QChar ch = text.at(0);
if (isQuote(ch)) {
if (la != ch)
return QString(ch);
++*skippedChars;
return QString();
}
if (isOpeningBrace(ch))
return QString(m_braceChars[ch]);
if (isDelimiter(ch) || isClosingBrace(ch)) {
if (la == ch)
++*skippedChars;
}
return QString();
}
/*!
* Returns true if the character \a c was added as one of character types.
*/
bool BraceMatcher::isKnownChar(const QChar c) const
{
return isQuote(c) || isDelimiter(c) || isOpeningBrace(c) || isClosingBrace(c);
}
} // namespace Utils
/****************************************************************************
**
** Copyright (C) 2016 Konstantin Tokarev <annulen@yandex.ru>
** Contact: https://www.qt.io/licensing/
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "utils_global.h"
#include <QChar>
#include <QSet>
#include <QMap>
QT_BEGIN_NAMESPACE
class QString;
class QTextCursor;
QT_END_NAMESPACE
namespace Utils {
class QTCREATOR_UTILS_EXPORT BraceMatcher
{
public:
void addBraceCharPair(const QChar opening, const QChar closing);
void addQuoteChar(const QChar quote);
void addDelimiterChar(const QChar delim);
bool shouldInsertMatchingText(const QTextCursor &tc) const;
bool shouldInsertMatchingText(const QChar lookAhead) const;
QString insertMatchingBrace(const QTextCursor &tc, const QString &text,
const QChar la, int *skippedChars) const;
bool isOpeningBrace(const QChar c) const { return m_braceChars.contains(c); }
bool isClosingBrace(const QChar c) const { return m_braceChars.values().contains(c); }
bool isQuote(const QChar c) const { return m_quoteChars.contains(c); }
bool isDelimiter(const QChar c) const { return m_delimiterChars.contains(c); }
bool isKnownChar(const QChar c) const;
private:
QMap<QChar, QChar> m_braceChars;
QSet<QChar> m_quoteChars;
QSet<QChar> m_delimiterChars;
};
} // namespace Utils
......@@ -89,7 +89,6 @@ SOURCES += \
$$PWD/basetreeview.cpp \
$$PWD/qtcassert.cpp \
$$PWD/elfreader.cpp \
$$PWD/bracematcher.cpp \
$$PWD/proxyaction.cpp \
$$PWD/elidinglabel.cpp \
$$PWD/hostosinfo.cpp \
......@@ -197,7 +196,6 @@ HEADERS += \
$$PWD/appmainwindow.h \
$$PWD/basetreeview.h \
$$PWD/elfreader.h \
$$PWD/bracematcher.h \
$$PWD/proxyaction.h \
$$PWD/hostosinfo.h \
$$PWD/osspecificaspects.h \
......
......@@ -50,8 +50,6 @@ Project {
"basetreeview.h",
"benchmarker.cpp",
"benchmarker.h",
"bracematcher.cpp",
"bracematcher.h",
"buildablehelperlibrary.cpp",
"buildablehelperlibrary.h",
"camelhumpmatcher.cpp",
......
......@@ -138,19 +138,22 @@ QList<TestConfiguration *> GTestTreeItem::getAllTestConfigurations() const
const TestTreeItem *grandChild = child->childItem(grandChildRow);
const QString &key = grandChild->proFile();
proFilesWithTestSets.insert(key, proFilesWithTestSets[key] + 1);
proFilesWithInternalTargets.insert(key, grandChild->internalTargets());
proFilesWithInternalTargets[key].unite(grandChild->internalTargets());
}
}
QHash<QString, int>::ConstIterator it = proFilesWithTestSets.begin();
QHash<QString, int>::ConstIterator end = proFilesWithTestSets.end();
for ( ; it != end; ++it) {
GTestConfiguration *tc = new GTestConfiguration;
tc->setTestCaseCount(it.value());
tc->setProjectFile(it.key());
tc->setProject(project);
tc->setInternalTargets(proFilesWithInternalTargets.value(it.key()));
result << tc;
const QSet<QString> &internalTargets = proFilesWithInternalTargets[it.key()];
for (const QString &target : internalTargets) {
GTestConfiguration *tc = new GTestConfiguration;
tc->setTestCaseCount(it.value());
tc->setProjectFile(it.key());
tc->setProject(project);
tc->setInternalTarget(target);
result << tc;
}
}
return result;
......@@ -184,8 +187,8 @@ QList<TestConfiguration *> GTestTreeItem::getSelectedTestConfigurations() const
auto &testCases = proFilesWithCheckedTestSets[child->childItem(0)->proFile()];
testCases.filters.append(gtestFilter(child->state()).arg(child->name()).arg('*'));
testCases.additionalTestCaseCount += grandChildCount - 1;
proFilesWithInternalTargets.insert(child->childItem(0)->proFile(),
child->internalTargets());
proFilesWithInternalTargets[child->childItem(0)->proFile()].unite(
child->internalTargets());
break;
}
case Qt::PartiallyChecked: {
......@@ -194,8 +197,8 @@ QList<TestConfiguration *> GTestTreeItem::getSelectedTestConfigurations() const
if (grandChild->checked() == Qt::Checked) {
proFilesWithCheckedTestSets[grandChild->proFile()].filters.append(
gtestFilter(child->state()).arg(child->name()).arg(grandChild->name()));
proFilesWithInternalTargets.insert(grandChild->proFile(),
grandChild->internalTargets());
proFilesWithInternalTargets[grandChild->proFile()].unite(
grandChild->internalTargets());
}
}
break;
......@@ -206,13 +209,16 @@ QList<TestConfiguration *> GTestTreeItem::getSelectedTestConfigurations() const
QHash<QString, TestCases>::ConstIterator it = proFilesWithCheckedTestSets.begin();
QHash<QString, TestCases>::ConstIterator end = proFilesWithCheckedTestSets.end();
for ( ; it != end; ++it) {
GTestConfiguration *tc = new GTestConfiguration;
tc->setTestCases(it.value().filters);
tc->setTestCaseCount(tc->testCaseCount() + it.value().additionalTestCaseCount);
tc->setProjectFile(it.key());
tc->setProject(project);
tc->setInternalTargets(proFilesWithInternalTargets[it.key()]);
result << tc;
const QSet<QString> &internalTargets = proFilesWithInternalTargets[it.key()];
for (const QString &target : internalTargets) {
GTestConfiguration *tc = new GTestConfiguration;
tc->setTestCases(it.value().filters);
tc->setTestCaseCount(tc->testCaseCount() + it.value().additionalTestCaseCount);
tc->setProjectFile(it.key());
tc->setProject(project);
tc->setInternalTarget(target);
result << tc;
}
}
return result;
......
......@@ -320,6 +320,12 @@ void TestConfiguration::setProject(Project *project)
m_project = project;
}
void TestConfiguration::setInternalTarget(const QString &target)
{
m_buildTargets.clear();
m_buildTargets.insert(target);
}
void TestConfiguration::setInternalTargets(const QSet<QString> &targets)
{
m_buildTargets = targets;
......
......@@ -67,6 +67,7 @@ public:
void setDisplayName(const QString &displayName);
void setEnvironment(const Utils::Environment &env);
void setProject(ProjectExplorer::Project *project);
void setInternalTarget(const QString &target);
void setInternalTargets(const QSet<QString> &targets);
void setOriginalRunConfiguration(ProjectExplorer::RunConfiguration *runConfig);
......
......@@ -243,11 +243,14 @@ static bool isValidIdentifierChar(const QChar &character)
int ActivationSequenceContextProcessor::findStartOfName(
const TextEditor::AssistInterface *assistInterface,
int startPosition)
int startPosition,
NameCategory category)
{
int position = startPosition;
QChar character;
if (position > 2 && assistInterface->characterAt(position - 1) == '>'
if (category == NameCategory::Function
&& position > 2 && assistInterface->characterAt(position - 1) == '>'
&& assistInterface->characterAt(position - 2) != '-') {
uint unbalancedLessGreater = 1;
--position;
......@@ -267,11 +270,12 @@ int ActivationSequenceContextProcessor::findStartOfName(
} while (isValidIdentifierChar(character));
int prevPosition = skipPrecedingWhitespace(assistInterface, position);
if (assistInterface->characterAt(prevPosition) == ':'
if (category == NameCategory::Function
&& assistInterface->characterAt(prevPosition) == ':'
&& assistInterface->characterAt(prevPosition - 1) == ':') {
// Handle :: case - go recursive
prevPosition = skipPrecedingWhitespace(assistInterface, prevPosition - 2);
return findStartOfName(assistInterface, prevPosition + 1);
return findStartOfName(assistInterface, prevPosition + 1, category);
}
return position + 1;
......
......@@ -49,8 +49,10 @@ public:
const QTextCursor &textCursor_forTestOnly() const;
enum class NameCategory { Function, NonFunction };
static int findStartOfName(const TextEditor::AssistInterface *assistInterface,
int startPosition);
int startPosition,
NameCategory category = NameCategory::NonFunction);
static int skipPrecedingWhitespace(const TextEditor::AssistInterface *assistInterface,
int startPosition);
......
......@@ -101,8 +101,8 @@ int ClangCompletionContextAnalyzer::startOfFunctionCall(int endOfOperator) const
ExpressionUnderCursor euc(m_languageFeatures);
index = euc.startOfFunctionCall(textCursor);
index = ActivationSequenceContextProcessor::skipPrecedingWhitespace(m_interface, index);
const int functionNameStart = ActivationSequenceContextProcessor::findStartOfName(m_interface,
index);
const int functionNameStart = ActivationSequenceContextProcessor::findStartOfName(
m_interface, index, ActivationSequenceContextProcessor::NameCategory::Function);
if (functionNameStart == -1)
return -1;
......
......@@ -110,7 +110,6 @@ Project {
files: [
"gdbengine.cpp", "gdbengine.h",
"gdboptionspage.cpp",
"startgdbserverdialog.cpp", "startgdbserverdialog.h",
]
}
......
......@@ -61,7 +61,6 @@
#include "snapshothandler.h"
#include "threadshandler.h"
#include "commonoptionspage.h"
#include "gdb/startgdbserverdialog.h"
#include "analyzer/analyzerconstants.h"
#include "analyzer/analyzermanager.h"
......@@ -734,7 +733,6 @@ public:
void updateDebugWithoutDeployMenu();
void startRemoteCdbSession();
void startRemoteServerAndAttachToProcess();
void attachToRunningApplication();
void attachToUnstartedApplicationDialog();
void attachToQmlPort();
......@@ -980,7 +978,6 @@ public:
QAction *m_startAction = 0;
QAction *m_debugWithoutDeployAction = 0;
QAction *m_startAndDebugApplicationAction = 0;
QAction *m_startRemoteServerAction = 0;
QAction *m_attachToRunningApplication = 0;
QAction *m_attachToUnstartedApplication = 0;
QAction *m_attachToQmlPortAction = 0;
......@@ -1506,10 +1503,6 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
act->setText(tr("Attach to Running Debug Server..."));
connect(act, &QAction::triggered, this, &StartApplicationDialog::attachToRemoteServer);
act = m_startRemoteServerAction = new QAction(this);
act->setText(tr("Start Debug Server Attached to Process..."));
connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::startRemoteServerAndAttachToProcess);
act = m_attachToRunningApplication = new QAction(this);
act->setText(tr("Attach to Running Application..."));
connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::attachToRunningApplication);
......@@ -1583,11 +1576,6 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
cmd->setAttribute(Command::CA_Hide);
mstart->addAction(cmd, Constants::G_SPECIAL);
cmd = ActionManager::registerAction(m_startRemoteServerAction,
"Debugger.StartRemoteServer");
cmd->setDescription(tr("Start Gdbserver"));
mstart->addAction(cmd, Constants::G_SPECIAL);
if (m_startRemoteCdbAction) {
cmd = ActionManager::registerAction(m_startRemoteCdbAction,
"Debugger.AttachRemoteCdb");
......@@ -1991,30 +1979,48 @@ void DebuggerPluginPrivate::startRemoteCdbSession()
debugger->startRunControl();
}
void DebuggerPluginPrivate::startRemoteServerAndAttachToProcess()
class RemoteAttachRunner : public DebuggerRunTool
{
auto kitChooser = new DebuggerKitChooser(DebuggerKitChooser::AnyDebugging);
auto dlg = new DeviceProcessesDialog(kitChooser, ICore::dialogParent());
dlg->addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process"));
dlg->showAllDevices();
if (dlg->exec() == QDialog::Rejected) {
delete dlg;
return;
public:
RemoteAttachRunner(RunControl *runControl, Kit *kit, int pid)
: DebuggerRunTool(runControl, kit)
{
IDevice::ConstPtr device = DeviceKitInformation::device(kit);
setDisplayName("AttachToRunningProcess");
portsGatherer = new GdbServerPortsGatherer(runControl);
portsGatherer->setUseGdbServer(true);
portsGatherer->setUseQmlServer(false);
portsGatherer->setDevice(device);
auto gdbServer = new GdbServerRunner(runControl, portsGatherer);
gdbServer->setUseMulti(false);
gdbServer->addStartDependency(portsGatherer);
gdbServer->setDevice(device);
gdbServer->setAttachPid(ProcessHandle(pid));
addStartDependency(gdbServer);
setStartMode(AttachToRemoteProcess);
setCloseMode(DetachAtClose);
// setInferiorExecutable(localExecutable);
setUseContinueInsteadOfRun(true);
setContinueAfterAttach(false);
}
dlg->setAttribute(Qt::WA_DeleteOnClose);
Kit *kit = kitChooser->currentKit();
QTC_ASSERT(kit, return);
IDevice::ConstPtr device = DeviceKitInformation::device(kit);
QTC_ASSERT(device, return);
void start() final
{
setRemoteChannel(portsGatherer->gdbServerChannel());
DebuggerRunTool::start();
}
GdbServerStarter *starter = new GdbServerStarter(dlg, true);
starter->run();
}
GdbServerPortsGatherer *portsGatherer;
};
void DebuggerPluginPrivate::attachToRunningApplication()
{
auto kitChooser = new DebuggerKitChooser(DebuggerKitChooser::LocalDebugging);
auto kitChooser = new DebuggerKitChooser(DebuggerKitChooser::AnyDebugging);
auto dlg = new DeviceProcessesDialog(kitChooser, ICore::dialogParent());
dlg->addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process"));
......@@ -2030,11 +2036,14 @@ void DebuggerPluginPrivate::attachToRunningApplication()
IDevice::ConstPtr device = DeviceKitInformation::device(kit);
QTC_ASSERT(device, return);
DeviceProcessItem process = dlg->currentProcess();
if (device->type() == PE::DESKTOP_DEVICE_TYPE) {
attachToRunningProcess(kit, dlg->currentProcess(), false);
attachToRunningProcess(kit, process, false);
} else {
GdbServerStarter *starter = new GdbServerStarter(dlg, true);
starter->run();
auto runControl = new RunControl(nullptr, ProjectExplorer::Constants::DEBUG_RUN_MODE);
auto debugger = new RemoteAttachRunner(runControl, kit, process.pid);
debugger->startRunControl();
}
}
......
......@@ -937,6 +937,8 @@ GdbServerPortsGatherer::GdbServerPortsGatherer(RunControl *runControl)
this, &RunWorker::reportFailure);
connect(&m_portsGatherer, &DeviceUsedPortsGatherer::portListReady,
this, &GdbServerPortsGatherer::handlePortListReady);
m_device = runControl->device();
}
GdbServerPortsGatherer::~GdbServerPortsGatherer()
......@@ -945,26 +947,31 @@ GdbServerPortsGatherer::~GdbServerPortsGatherer()
QString GdbServerPortsGatherer::gdbServerChannel() const
{
const QString host = device()->sshParameters().host;
const QString host = m_device->sshParameters().host;
return QString("%1:%2").arg(host).arg(m_gdbServerPort.number());
}
QUrl GdbServerPortsGatherer::qmlServer() const
{
QUrl server = device()->toolControlChannel(IDevice::QmlControlChannel);
QUrl server = m_device->toolControlChannel(IDevice::QmlControlChannel);
server.setPort(m_qmlServerPort