Merge remote-tracking branch 'origin/4.7'

Conflicts:
	qbs/modules/qtc/qtc.qbs
	qtcreator.pri
	src/plugins/android/androiddebugsupport.cpp

Change-Id: I01c4880850ad25432a65bb32849365d2aeb0756f
This commit is contained in:
Eike Ziller
2018-07-10 07:44:53 +02:00
31 changed files with 369 additions and 109 deletions

20
dist/changes-4.7.0.md vendored
View File

@@ -29,6 +29,7 @@ Editing
* Added `Context Help` to editor context menu (QTCREATORBUG-55)
* Added previous and next buttons to bookmarks view, and polished their
behavior (QTCREATORBUG-9859, QTCREATORBUG-20061)
* Added support for `WordDetect` in Kate highlighting files
* Fixed that extra editor windows were not restored when opening session
(QTCREATORBUG-13840)
* Fixed that editor could stay busy repainting annotations (QTCREATORBUG-20422)
@@ -76,6 +77,7 @@ C++ Support
(category `Clang Code Model`)
* Added highlighting style for overloaded operators (QTCREATORBUG-19659)
* Added option to use `.clang-tidy` configuration file or checks string
* Added default configurations for Clang-Tidy and Clazy checks
* Added link to the documentation in tooltip for Clang-Tidy and Clazy
diagnostics
* Improved reparse performance and memory usage
@@ -92,6 +94,7 @@ QML Support
* Fixed that reformatting incorrectly removed quotes (QTCREATORBUG-17455)
* Fixed that `.pragma` and `.import` were removed when reformatting
(QTCREATORBUG-13038)
* Fixed that import completion did not offer `QtWebEngine` (QTCREATORBUG-20723)
Python Support
@@ -99,8 +102,16 @@ Python Support
Debugging
* Fixed updating of memory view
* QML
* Added support for nested properties (QTBUG-68474)
* Fixed issue with different endianness (QTBUG-68721)
Qt Quick Designer
* Fixed crash when adding quotes to text (QTCREATORBUG-20684)
* Fixed that meta data could move in source code even when no changes occurred
(QTCREATORBUG-20686)
Clang Static Analyzer
@@ -119,6 +130,7 @@ Version Control Systems
* Added `-git-show <ref>` command line parameter
* Gerrit
* Added warning when pushing to wrong branch (QTCREATORBUG-20062)
* Fixed updating after settings change (QTCREATORBUG-20536)
Image Viewer
@@ -134,6 +146,7 @@ Test Integration
(QTCREATORBUG-18725)
* Qt Quick
* Fixed parsing issue with non-ASCII characters (QTCREATORBUG-20105)
* Fixed detection of test name (QTCREATORBUG-20642)
Platform Specific
@@ -141,11 +154,15 @@ Windows
* Improved parsing of MSVC error messages (QTCREATORBUG-20297)
* Fixed that querying MSVC tool chains at startup could block Qt Creator
* Fixed issue with writing to network drives (QTCREATORBUG-20560)
* Fixed issue with Clang and Qt 5.8 and later (QTCREATORBUG-20021)
* Fixed handling of Windows debug stream which could lead to freezes
(QTCREATORBUG-20640)
Android
* Improved behavior when emulator cannot be started (QTCREATORBUG-20160)
* Fixed QML debugger connection issue from macOS client (QTCREATORBUG-20730)
Credits for these changes go to:
Aaron Barany
@@ -172,9 +189,11 @@ Jaroslaw Kobus
Jay Gupta
José Tomás Tocino
Jörg Bornemann
Kai Köhne
Kari Oikarinen
Kimmo Linnavuo
Leena Miettinen
Lorenz Haas
Marco Benelli
Marco Bubke
Mitch Curtis
@@ -187,6 +206,7 @@ Przemyslaw Gorszkowski
Razi Alavizadeh
Robert Löhning
Rune Espeseth
Sergey Belyashov
Sergey Morozov
Tasuku Suzuki
Thiago Macieira

View File

@@ -0,0 +1,78 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
**
** 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 Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
**
****************************************************************************/
/*!
//! [cpp sidebar views]
The following views display additional information about C++ code:
\list
\li \uicontrol {Class View} shows the class hierarchy of the currently
open projects.
\li \uicontrol Tests lists autotests and Qt Quick tests in the project.
For more information, see \l {Running Autotests}.
\li \uicontrol {Type Hierarchy} shows the base classes of a class.
\li \uicontrol {Include Hierarchy} shows which files are included in
the current file and which files include the current file.
\endlist
//! [cpp sidebar views]
//! [class view]
\section2 Viewing the Class Hierarchy
The \uicontrol {Class View} shows the class hierarchy of the currently
open projects. To organize the view by subprojects, click
\inlineimage qtcreator-show-subprojects.png
(\uicontrol {Show Subprojects}).
To visit all parts of a namespace, double-click on the namespace item
multiple times.
//! [class view]
//! [type hierarchy view]
\section2 Viewing Type Hierarchy
To view the base classes of a class, right-click the class and select
\uicontrol {Open Type Hierarchy} or press \key {Ctrl+Shift+T}.
//! [type hierarchy view]
//! [include hierarchy view]
\section2 Viewing Include Hierarchy
To view which files are included in the current file and which files include
the current file, right-click in the editor and select
\uicontrol {Open Include Hierarchy} or press \key {Ctrl+Shift+I}.
//! [include hierarchy view]
*/

View File

@@ -136,22 +136,13 @@
\li \uicontrol{File System} shows all files in the currently selected
directory.
\li \uicontrol {Class View} shows the class hierarchy of the currently
open projects.
\li \uicontrol Outline shows the symbol hierarchy of a C++ file and the type
hierarchy of a QML file.
\li \uicontrol Tests lists autotests and Qt Quick tests in the project.
For more information, see \l {Running Autotests}.
\li \uicontrol {Type Hierarchy} shows the base classes of a class.
\li \uicontrol {Include Hierarchy} shows which files are included in the current file
and which files include the current file.
\li \uicontrol Outline shows an overview of defined types and other
symbols, as well as their properties and hierarchy in a source file.
\endlist
\include creator-sidebar-cpp-views.qdocinc cpp sidebar views
For more information about the sidebar views that are only
available when editing QML files in the Design mode, see
\l{Editing QML Files in Design Mode}.
@@ -326,16 +317,6 @@
\endlist
\section2 Viewing the Class Hierarchy
The \uicontrol {Class View} shows the class hierarchy of the currently
open projects. To organize the view by subprojects, click
\inlineimage qtcreator-show-subprojects.png
(\uicontrol {Show Subprojects}).
To visit all parts of a namespace, double-click on the namespace item
multiple times.
\section2 Viewing QML Types
The \uicontrol Outline view shows the type hierarchy in a QML file.
@@ -350,16 +331,9 @@
\endlist
\section2 Viewing Type Hierarchy
To view the base classes of a class, right-click the class and select
\uicontrol {Open Type Hierarchy} or press \key {Ctrl+Shift+T}.
\section2 Viewing Include Hierarchy
To view which files are included in the current file and which files include
the current file, right-click in the editor and select \uicontrol {Open Include Hierarchy}
or press \key {Ctrl+Shift+I}.
\include creator-sidebar-cpp-views.qdocinc class view
\include creator-sidebar-cpp-views.qdocinc type hierarchy view
\include creator-sidebar-cpp-views.qdocinc include hierarchy view
\section1 Viewing Output

View File

@@ -1002,7 +1002,12 @@ class Dumper(DumperBase):
try:
symbols = gdb.execute(cmd, to_string = True)
except:
pass
# command syntax depends on gdb version - below is gdb 8+
cmd = 'maint print msymbols -objfile "%s" -- %s' % (objfile.filename, tmppath)
try:
symbols = gdb.execute(cmd, to_string = True)
except:
pass
ns = ''
with open(tmppath) as f:
for line in f:

View File

@@ -11,5 +11,5 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt5 COMPONENTS Core Quick REQUIRED)
add_executable(${PROJECT_NAME} "%{MainCppFileName}" "qml.qrc")
target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Quick)
target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Core Qt5::Quick)

View File

@@ -16812,7 +16812,7 @@ Soll es noch einmal versucht werden?</translation>
</message>
<message>
<source>No compiler can produce code for this Qt version. Please define one or more compilers for: %1</source>
<translation>Kein Compiler kann für diese Qt-Version Code erzeugen. Bitte richten Sie einen oder mehrere für &quot;%1&quot; geeignete Compiler ein.</translation>
<translation>Kein Compiler kann für diese Qt-Version Code erzeugen. Bitte richten Sie einen oder mehrere Compiler ein, geeignet für: %1</translation>
</message>
<message>
<source>The following ABIs are currently not supported: %1</source>

View File

@@ -104,7 +104,9 @@ enum class HighlightingType : quint8
ObjectiveCInterface,
ObjectiveCImplementation,
ObjectiveCProperty,
ObjectiveCMethod
ObjectiveCMethod,
TemplateTypeParameter,
TemplateTemplateParameter
};
enum class StorageClass : quint8

View File

@@ -70,6 +70,8 @@ static const char *highlightingTypeToCStringLiteral(HighlightingType type)
RETURN_TEXT_FOR_CASE(ObjectiveCMethod);
RETURN_TEXT_FOR_CASE(PrimitiveType);
RETURN_TEXT_FOR_CASE(Declaration);
RETURN_TEXT_FOR_CASE(TemplateTypeParameter);
RETURN_TEXT_FOR_CASE(TemplateTemplateParameter);
default: return "UnhandledHighlightingType";
}
}

View File

@@ -129,6 +129,13 @@ public:
bool isGlobalDeclaration() const
{
if (types.mixinHighlightingTypes.contains(
ClangBackEnd::HighlightingType::TemplateTypeParameter)
|| types.mixinHighlightingTypes.contains(
ClangBackEnd::HighlightingType::TemplateTemplateParameter)) {
return false;
}
return extraInfo.declaration
&& types.mainHighlightingType != HighlightingType::LocalVariable
&& ((types.mainHighlightingType == HighlightingType::Operator)

View File

@@ -416,6 +416,17 @@ FileName AndroidConfig::avdManagerToolPath() const
return avdManagerPath;
}
FileName AndroidConfig::aaptToolPath() const
{
Utils::FileName aaptToolPath = m_sdkLocation;
aaptToolPath.appendPath("build-tools");
QString toolPath = QString("%1/aapt").arg(buildToolsVersion().toString());
if (HostOsInfo::isWindowsHost())
toolPath += ANDROID_BAT_SUFFIX;
aaptToolPath.appendPath(toolPath);
return aaptToolPath;
}
FileName AndroidConfig::gccPath(const Abi &abi, Core::Id lang,
const QString &ndkToolChainVersion) const
{

View File

@@ -132,6 +132,7 @@ public:
Utils::FileName emulatorToolPath() const;
Utils::FileName sdkManagerToolPath() const;
Utils::FileName avdManagerToolPath() const;
Utils::FileName aaptToolPath() const;
Utils::FileName gccPath(const ProjectExplorer::Abi &abi, Core::Id lang,
const QString &ndkToolChainVersion) const;

View File

@@ -45,6 +45,7 @@
#include <QDirIterator>
#include <QLoggingCategory>
#include <QHostAddress>
namespace {
Q_LOGGING_CATEGORY(androidDebugSupportLog, "qtc.android.run.androiddebugsupport")
@@ -142,7 +143,10 @@ void AndroidDebugSupport::start()
+ "/app_process");
setSkipExecutableValidation(true);
setUseExtendedRemote(true);
setRemoteChannel(":" + m_runner->gdbServerPort().toString());
QUrl gdbServer;
gdbServer.setHost(QHostAddress(QHostAddress::LocalHost).toString());
gdbServer.setPort(m_runner->gdbServerPort().number());
setRemoteChannel(gdbServer);
QString sysRoot = AndroidConfigurations::currentConfig().ndkLocation().appendPath("platforms")
.appendPath(QString("android-%1").arg(AndroidManager::minimumSDK(target)))

View File

@@ -61,17 +61,43 @@
#include <QApplication>
#include <QDomDocument>
#include <QVersionNumber>
namespace {
Q_LOGGING_CATEGORY(androidManagerLog, "qtc.android.androidManager")
}
#include <QRegularExpression>
namespace {
const QLatin1String AndroidManifestName("AndroidManifest.xml");
const QLatin1String AndroidDefaultPropertiesName("project.properties");
const QLatin1String AndroidDeviceSn("AndroidDeviceSerialNumber");
const QLatin1String ApiLevelKey("AndroidVersion.ApiLevel");
const QString packageNameRegEx("(package: name=)\\'(([a-z]{1}[a-z\\d_]*\\."
")*[a-z][a-z\\d_]*)\\'");
const QString activityRegEx("(launchable-activity: name=)\\'"
"(([a-z]{1}[a-z\\d_]*\\.)*[a-z][a-z\\d_]*)\\'");
const QString apkVersionRegEx("package: name=([\\=a-z\\d_\\.\\'\\s]*)"
"\\sversionName='([\\d\\.]*)'");
Q_LOGGING_CATEGORY(androidManagerLog, "qtc.android.androidManager")
bool runCommand(const QString &executable, const QStringList &args,
QString *output = nullptr, int timeoutS = 30)
{
Utils::SynchronousProcess cmdProc;
cmdProc.setTimeoutS(timeoutS);
qCDebug(androidManagerLog) << executable << args.join(' ');
Utils::SynchronousProcessResponse response = cmdProc.runBlocking(executable, args);
if (output)
*output = response.allOutput();
return response.result == Utils::SynchronousProcessResponse::Finished;
}
QString parseAaptOutput(const QString &output, const QString &regEx) {
const QRegularExpression regRx(regEx,
QRegularExpression::CaseInsensitiveOption |
QRegularExpression::MultilineOption);
QRegularExpressionMatch match = regRx.match(output);
if (match.hasMatch())
return match.captured(2);
return QString();
};
} // anonymous namespace
@@ -127,6 +153,53 @@ QString AndroidManager::packageName(const Utils::FileName &manifestFile)
return manifestElem.attribute(QLatin1String("package"));
}
bool AndroidManager::packageInstalled(const QString &deviceSerial,
const QString &packageName)
{
if (deviceSerial.isEmpty() || packageName.isEmpty())
return false;
QStringList args = AndroidDeviceInfo::adbSelector(deviceSerial);
args << "shell" << "pm" << "list" << "packages";
QString output;
runAdbCommand(args, &output);
QStringList lines = output.split(QRegularExpression("[\\n\\r]"),
QString::SkipEmptyParts);
for (const QString &line : lines) {
// Don't want to confuse com.abc.xyz with com.abc.xyz.def so check with
// endsWith
if (line.endsWith(packageName))
return true;
}
return false;
}
void AndroidManager::apkInfo(const Utils::FileName &apkPath,
QString *packageName,
QVersionNumber *version,
QString *activityPath)
{
QString output;
runAaptCommand({"dump", "badging", apkPath.toString()}, &output);
QString packageStr;
if (activityPath) {
packageStr = parseAaptOutput(output, packageNameRegEx);
QString path = parseAaptOutput(output, activityRegEx);
if (!packageStr.isEmpty() && !path.isEmpty())
*activityPath = packageStr + '/' + path;
}
if (packageName) {
*packageName = activityPath ? packageStr :
parseAaptOutput(output, packageNameRegEx);
}
if (version) {
QString versionStr = parseAaptOutput(output, apkVersionRegEx);
*version = QVersionNumber::fromString(versionStr);
}
}
QString AndroidManager::intentName(ProjectExplorer::Target *target)
{
return packageName(target) + QLatin1Char('/') + activityName(target);
@@ -381,16 +454,9 @@ void AndroidManager::cleanLibsOnDevice(ProjectExplorer::Target *target)
Core::MessageManager::write(tr("Starting Android virtual device failed."));
}
QProcess *process = new QProcess();
QStringList arguments = AndroidDeviceInfo::adbSelector(deviceSerialNumber);
arguments << QLatin1String("shell") << QLatin1String("rm") << QLatin1String("-r") << QLatin1String("/data/local/tmp/qt");
QObject::connect(process, static_cast<void (QProcess::*)(int)>(&QProcess::finished),
process, &QObject::deleteLater);
const QString adb = AndroidConfigurations::currentConfig().adbToolPath().toString();
Core::MessageManager::write(adb + QLatin1Char(' ') + arguments.join(QLatin1Char(' ')));
process->start(adb, arguments);
if (!process->waitForStarted(500))
delete process;
runAdbCommandDetached(arguments);
}
void AndroidManager::installQASIPackage(ProjectExplorer::Target *target, const QString &packagePath)
@@ -410,17 +476,9 @@ void AndroidManager::installQASIPackage(ProjectExplorer::Target *target, const Q
Core::MessageManager::write(tr("Starting Android virtual device failed."));
}
QProcess *process = new QProcess();
QStringList arguments = AndroidDeviceInfo::adbSelector(deviceSerialNumber);
arguments << QLatin1String("install") << QLatin1String("-r ") << packagePath;
connect(process, static_cast<void (QProcess::*)(int)>(&QProcess::finished),
process, &QObject::deleteLater);
const QString adb = AndroidConfigurations::currentConfig().adbToolPath().toString();
Core::MessageManager::write(adb + QLatin1Char(' ') + arguments.join(QLatin1Char(' ')));
process->start(adb, arguments);
if (!process->waitForStarted(500) && process->state() != QProcess::Running)
delete process;
runAdbCommandDetached(arguments);
}
bool AndroidManager::checkKeystorePassword(const QString &keystorePath, const QString &keystorePasswd)
@@ -603,4 +661,27 @@ int AndroidManager::findApiLevel(const Utils::FileName &platformPath)
return apiLevel;
}
void AndroidManager::runAdbCommandDetached(const QStringList &args)
{
QProcess *process = new QProcess();
connect(process, static_cast<void (QProcess::*)(int)>(&QProcess::finished),
process, &QObject::deleteLater);
const QString adb = AndroidConfigurations::currentConfig().adbToolPath().toString();
qCDebug(androidManagerLog) << adb << args.join(' ');
process->start(adb, args);
if (!process->waitForStarted(500) && process->state() != QProcess::Running)
delete process;
}
bool AndroidManager::runAdbCommand(const QStringList &args, QString *output)
{
return runCommand(AndroidConfigurations::currentConfig().adbToolPath().toString(),
args, output);
}
bool AndroidManager::runAaptCommand(const QStringList &args, QString *output)
{
return runCommand(AndroidConfigurations::currentConfig().aaptToolPath().toString(),
args, output);
}
} // namespace Android

View File

@@ -29,6 +29,7 @@
#include <QPair>
#include <QObject>
#include <QVersionNumber>
namespace ProjectExplorer {
class Kit;
@@ -48,7 +49,12 @@ class ANDROID_EXPORT AndroidManager : public QObject
public:
static QString packageName(ProjectExplorer::Target *target);
static QString packageName(const Utils::FileName &manifestFile);
static bool packageInstalled(const QString &deviceSerial,
const QString &packageName);
static void apkInfo(const Utils::FileName &apkPath,
QString *packageName = nullptr,
QVersionNumber *version = nullptr,
QString *activityPath = nullptr);
static QString intentName(ProjectExplorer::Target *target);
static QString activityName(ProjectExplorer::Target *target);
@@ -86,6 +92,10 @@ public:
static AndroidQtSupport *androidQtSupport(ProjectExplorer::Target *target);
static bool updateGradleProperties(ProjectExplorer::Target *target);
static int findApiLevel(const Utils::FileName &platformPath);
static void runAdbCommandDetached(const QStringList &args);
static bool runAdbCommand(const QStringList &args, QString *output = nullptr);
static bool runAaptCommand(const QStringList &args, QString *output = nullptr);
};
} // namespace Android

View File

@@ -34,6 +34,7 @@
#include "androidavdmanager.h"
#include "androidrunnerworker.h"
#include <QHostAddress>
#include <coreplugin/messagemanager.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorersettings.h>
@@ -206,6 +207,7 @@ void AndroidRunner::qmlServerPortReady(Port port)
// device side. It only happens to work since we redirect
// host port n to target port n via adb.
QUrl serverUrl;
serverUrl.setHost(QHostAddress(QHostAddress::LocalHost).toString());
serverUrl.setPort(port.number());
serverUrl.setScheme(urlTcpScheme());
emit qmlServerReady(serverUrl);

View File

@@ -176,8 +176,7 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa
if (m_qmlDebugServices != QmlDebug::NoQmlDebugServices) {
qCDebug(androidRunWorkerLog) << "QML debugging enabled";
QTcpServer server;
QTC_ASSERT(server.listen(QHostAddress::LocalHost)
|| server.listen(QHostAddress::LocalHostIPv6),
QTC_ASSERT(server.listen(QHostAddress::LocalHost),
qDebug() << tr("No free ports available on host for QML debugging."));
m_qmlServer.setScheme(Utils::urlTcpScheme());
m_qmlServer.setHost(server.serverAddress().toString());

View File

@@ -108,6 +108,8 @@ bool ignore(ClangBackEnd::HighlightingType type)
case HighlightingType::ObjectiveCImplementation:
case HighlightingType::ObjectiveCProperty:
case HighlightingType::ObjectiveCMethod:
case HighlightingType::TemplateTypeParameter:
case HighlightingType::TemplateTemplateParameter:
return true;
}

View File

@@ -96,6 +96,20 @@ static QString addType(const QString &name, const ClangBackEnd::ExtraInfo &extra
return name + QLatin1String(" -> ", 4) + extraInfo.typeSpelling.toString();
}
static QString fullName(const ClangBackEnd::ExtraInfo &extraInfo, TokenTreeItem *parent)
{
const QString parentType = parent->token.extraInfo.typeSpelling.toString();
if (extraInfo.semanticParentTypeSpelling.startsWith(parentType)) {
const QString parentQualification = parentType.isEmpty()
? extraInfo.semanticParentTypeSpelling
: extraInfo.semanticParentTypeSpelling.mid(parentType.length() + 2);
if (!parentQualification.isEmpty())
return parentQualification + "::" + extraInfo.token.toString();
}
return extraInfo.token.toString();
}
QVariant TokenTreeItem::data(int column, int role) const
{
Q_UNUSED(column)
@@ -109,7 +123,8 @@ QVariant TokenTreeItem::data(int column, int role) const
switch (role) {
case Qt::DisplayRole: {
QString name = token.extraInfo.token.toString();
QString name = fullName(token.extraInfo, static_cast<TokenTreeItem *>(parent()));
ClangBackEnd::HighlightingType mainType = token.types.mainHighlightingType;
if (mainType == ClangBackEnd::HighlightingType::VirtualFunction

View File

@@ -140,6 +140,8 @@ public:
void setPerspectiveEnabled(const QByteArray &perspectiveId, bool enabled);
private:
void closeEvent(QCloseEvent *) final { saveCurrentPerspective(); }
QDockWidget *registerDockWidget(const QByteArray &dockId, QWidget *widget);
void loadPerspectiveHelper(const QByteArray &perspectiveId, bool fromStoredSettings = true);

View File

@@ -2795,7 +2795,6 @@ void DebuggerPluginPrivate::aboutToShutdown()
disconnect(SessionManager::instance(), &SessionManager::startupProjectChanged, this, nullptr);
m_mainWindow->saveCurrentPerspective();
m_shutdownTimer.setInterval(0);
m_shutdownTimer.setSingleShot(true);
connect(&m_shutdownTimer, &QTimer::timeout, this, &DebuggerPluginPrivate::doShutdown);

View File

@@ -138,6 +138,12 @@ struct LookupData
typedef QHash<int, LookupData> LookupItems; // id -> (iname, exp)
static void setWatchItemHasChildren(WatchItem *item, bool hasChildren)
{
item->setHasChildren(hasChildren);
item->valueEditable = !hasChildren;
}
class QmlEnginePrivate : public QmlDebugClient
{
public:
@@ -1311,7 +1317,7 @@ void QmlEnginePrivate::handleEvaluateExpression(const QVariantMap &response,
if (success) {
item->type = body.type;
item->value = body.value.toString();
item->setHasChildren(body.hasChildren());
setWatchItemHasChildren(item, body.hasChildren());
} else {
//Do not set type since it is unknown
item->setError(body.value.toString());
@@ -2156,11 +2162,11 @@ void QmlEnginePrivate::handleFrame(const QVariantMap &response)
item->id = objectData.handle;
item->type = objectData.type;
item->value = objectData.value.toString();
item->setHasChildren(objectData.hasChildren());
setWatchItemHasChildren(item, objectData.hasChildren());
// In case of global object, we do not get children
// Set children nevertheless and query later.
if (item->value == "global") {
item->setHasChildren(true);
setWatchItemHasChildren(item, true);
item->id = 0;
}
watchHandler->insertItem(item);
@@ -2244,10 +2250,13 @@ void QmlEnginePrivate::handleScope(const QVariantMap &response)
item->id = localData.handle;
item->type = localData.type;
item->value = localData.value.toString();
item->setHasChildren(localData.hasChildren());
setWatchItemHasChildren(item.get(), localData.hasChildren());
if (localData.value.isValid() || item->wantsChildren || localData.expectedProperties == 0) {
engine->watchHandler()->insertItem(item.release());
WatchHandler *watchHander = engine->watchHandler();
if (watchHander->isExpandedIName(item->iname))
itemsToLookup.insert(int(item->id), {item->iname, item->name, item->exp});
watchHander->insertItem(item.release());
} else {
itemsToLookup.insert(int(item->id), {item->iname, item->name, item->exp});
}
@@ -2387,7 +2396,7 @@ void QmlEnginePrivate::insertSubItems(WatchItem *parent, const QVariantList &pro
item->value = propertyData.value.toString();
if (item->type.isEmpty() || expandedINames.contains(item->iname))
itemsToLookup.insert(propertyData.handle, {item->iname, item->name, item->exp});
item->setHasChildren(propertyData.hasChildren());
setWatchItemHasChildren(item.get(), propertyData.hasChildren());
parent->appendChild(item.release());
}
@@ -2443,7 +2452,7 @@ void QmlEnginePrivate::handleLookup(const QVariantMap &response)
item->type = bodyObjectData.type;
item->value = bodyObjectData.value.toString();
item->setHasChildren(bodyObjectData.hasChildren());
setWatchItemHasChildren(item, bodyObjectData.hasChildren());
insertSubItems(item, bodyObjectData.properties);
engine->watchHandler()->insertItem(item);

View File

@@ -795,7 +795,8 @@ QString GitClient::findGitDirForRepository(const QString &repositoryDir) const
bool GitClient::managesFile(const QString &workingDirectory, const QString &fileName) const
{
return vcsFullySynchronousExec(workingDirectory, {"ls-files", "--error-unmatch", fileName}).result
return vcsFullySynchronousExec(workingDirectory, {"ls-files", "--error-unmatch", fileName},
Core::ShellCommand::NoOutput).result
== SynchronousProcessResponse::Finished;
}

View File

@@ -1008,6 +1008,32 @@ static const ToolChain *selectMsvcToolChain(const QString &clangClPath,
return toolChain;
}
static void detectClangClToolChainInPath(const QString &clangClPath, QList<ToolChain *> *list)
{
const unsigned char wordWidth = Utils::is64BitWindowsBinary(clangClPath) ? 64 : 32;
const ToolChain *toolChain = selectMsvcToolChain(clangClPath, *list, wordWidth);
QDir path = QFileInfo(clangClPath).absoluteDir(); // bin folder
path.cdUp(); // cd to LLVM root
const QString rootPath = path.canonicalPath();
if (!toolChain) {
qWarning("Unable to find a suitable MSVC version for \"%s\".",
qPrintable(QDir::toNativeSeparators(rootPath)));
return;
}
const MsvcToolChain *msvcToolChain = static_cast<const MsvcToolChain *>(toolChain);
const Abi targetAbi = msvcToolChain->targetAbi();
const QString name = QStringLiteral("LLVM ") + QString::number(wordWidth)
+ QStringLiteral("bit based on ")
+ Abi::toString(targetAbi.osFlavor()).toUpper();
for (auto language: {Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID}) {
list->append(new ClangClToolChain(name, rootPath, targetAbi,
msvcToolChain->varsBat(), msvcToolChain->varsBatArg(),
language, ToolChain::AutoDetection));
}
}
// Detect Clang-cl on top of MSVC2017, MSVC2015 or MSVC2013.
static void detectClangClToolChain(QList<ToolChain *> *list)
{
@@ -1018,28 +1044,19 @@ static void detectClangClToolChain(QList<ToolChain *> *list)
#endif
const QSettings registry(QLatin1String(registryNode), QSettings::NativeFormat);
if (registry.status() != QSettings::NoError)
return;
const QString path = QDir::cleanPath(registry.value(QStringLiteral(".")).toString());
if (path.isEmpty())
return;
const QString clangClPath = compilerFromPath(path);
const unsigned char wordWidth = Utils::is64BitWindowsBinary(clangClPath) ? 64 : 32;
const ToolChain *toolChain = selectMsvcToolChain(clangClPath, *list, wordWidth);
if (!toolChain) {
qWarning("Unable to find a suitable MSVC version for \"%s\".", qPrintable(QDir::toNativeSeparators(path)));
return;
}
const MsvcToolChain *msvcToolChain = static_cast<const MsvcToolChain *>(toolChain);
const Abi targetAbi = msvcToolChain->targetAbi();
const QString name = QStringLiteral("LLVM ") + QString::number(wordWidth)
+ QStringLiteral("bit based on ")
+ Abi::toString(targetAbi.osFlavor()).toUpper();
for (auto language: {Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID}) {
list->append(new ClangClToolChain(name, path, targetAbi,
msvcToolChain->varsBat(), msvcToolChain->varsBatArg(),
language, ToolChain::AutoDetection));
if (registry.status() == QSettings::NoError) {
const QString path = QDir::cleanPath(registry.value(QStringLiteral(".")).toString());
const QString clangClPath = compilerFromPath(path);
if (!path.isEmpty()) {
detectClangClToolChainInPath(path, list);
return;
}
}
const Utils::Environment systemEnvironment = Utils::Environment::systemEnvironment();
const Utils::FileName clangClPath = systemEnvironment.searchInPath("clang-cl");
if (!clangClPath.isEmpty())
detectClangClToolChainInPath(clangClPath.toString(), list);
}
QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)

View File

@@ -337,7 +337,10 @@ TaskFilterModel::TaskFilterModel(TaskModel *sourceModel, QObject *parent) : QAbs
connect(m_sourceModel, &QAbstractItemModel::rowsRemoved,
this, [this](const QModelIndex &parent, int, int) {
QTC_ASSERT(!parent.isValid(), return);
endRemoveRows();
if (m_beginRemoveRowsSent) {
m_beginRemoveRowsSent = false;
endRemoveRows();
}
});
connect(m_sourceModel, &QAbstractItemModel::modelReset,
@@ -430,6 +433,7 @@ void TaskFilterModel::handleNewRows(const QModelIndex &index, int first, int las
void TaskFilterModel::handleRowsAboutToBeRemoved(const QModelIndex &index, int first, int last)
{
m_beginRemoveRowsSent = false;
QTC_ASSERT(!index.isValid(), return);
const QPair<int, int> range = findFilteredRange(first, last, m_mapping);
@@ -437,6 +441,7 @@ void TaskFilterModel::handleRowsAboutToBeRemoved(const QModelIndex &index, int f
return;
beginRemoveRows(QModelIndex(), range.first, range.second);
m_beginRemoveRowsSent = true;
m_mapping.erase(m_mapping.begin() + range.first, m_mapping.begin() + range.second + 1);
const int sourceRemovedCount = (last - first) + 1;
for (int i = range.first; i < m_mapping.count(); ++i)

View File

@@ -165,6 +165,7 @@ private:
void updateMapping() const;
bool filterAcceptsTask(const Task &task) const;
bool m_beginRemoveRowsSent = false;
bool m_includeUnknowns;
bool m_includeWarnings;
bool m_includeErrors;

View File

@@ -198,15 +198,15 @@ bool QmlDesignerPlugin::delayedInitialize()
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::TextTool);
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::PathTool);
connect(Core::DesignMode::instance(), &Core::DesignMode::actionsUpdated,
&d->shortCutManager, &ShortCutManager::updateActions);
return true;
}
void QmlDesignerPlugin::extensionsInitialized()
{
integrateIntoQtCreator(&d->mainWidget);
// delay after Core plugin's extensionsInitialized, so the DesignMode is availabe
connect(Core::ICore::instance(), &Core::ICore::coreAboutToOpen, this, [this] {
integrateIntoQtCreator(&d->mainWidget);
});
}
static QStringList allUiQmlFilesforCurrentProject(const Utils::FileName &fileName)
@@ -255,6 +255,9 @@ void QmlDesignerPlugin::integrateIntoQtCreator(QWidget *modeWidget)
Core::DesignMode::registerDesignWidget(modeWidget, mimeTypes, d->context->context());
connect(Core::DesignMode::instance(), &Core::DesignMode::actionsUpdated,
&d->shortCutManager, &ShortCutManager::updateActions);
connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged, [this] (Core::IEditor *editor) {
if (d && checkIfEditorIsQtQuick(editor) && isInDesignerMode())
changeEditor();

View File

@@ -357,8 +357,12 @@ void WelcomeMode::initPlugins()
addPage(page);
if (!m_activePage.isValid() && !m_pageButtons.isEmpty()) {
m_activePage = m_pluginList.at(0)->id();
m_pageButtons.at(0)->click();
const int welcomeIndex = Utils::indexOf(m_pluginList,
Utils::equal(&IWelcomePage::id,
Core::Id("Examples")));
const int defaultIndex = welcomeIndex >= 0 ? welcomeIndex : 0;
m_activePage = m_pluginList.at(defaultIndex)->id();
m_pageButtons.at(defaultIndex)->click();
}
}

View File

@@ -341,9 +341,13 @@ void TokenInfo::typeKind(const Cursor &cursor)
case CXCursor_ObjCCategoryImplDecl:
m_types.mixinHighlightingTypes.push_back(HighlightingType::ObjectiveCCategory);
return;
case CXCursor_ObjCSuperClassRef:
case CXCursor_TemplateTypeParameter:
m_types.mixinHighlightingTypes.push_back(HighlightingType::TemplateTypeParameter);
return;
case CXCursor_TemplateTemplateParameter:
m_types.mixinHighlightingTypes.push_back(HighlightingType::TemplateTemplateParameter);
return;
case CXCursor_ObjCSuperClassRef:
case CXCursor_CXXStaticCastExpr:
case CXCursor_CXXReinterpretCastExpr:
break;

View File

@@ -100,7 +100,7 @@ def main():
editor = getEditorForFileSuffix("%s.h" % className.lower())
oldContent = str(editor.plainText)
placeCursorToLine(editor, "class %s.*" % className, True)
snooze(1) # avoid timing issue with the parser
snooze(4) # avoid timing issue with the parser
invokeContextMenuItem(editor, "Refactor", "Insert Virtual Functions of Base Classes")
handleInsertVirtualFunctions(["keys() const = 0 : QStringList",
"create(const QString &, const QString &) = 0 : QObject *"])

View File

@@ -77,12 +77,14 @@ def main():
"possible to select one of the suggestions.")
# Step 4: Insert text "voi" to new line and press Tab.
resetLine(editorWidget)
type(editorWidget, "voi")
type(editorWidget, "unsi")
try:
waitForObjectItem(":popupFrame_Proposal_QListView", "void")
type(waitForObject(":popupFrame_Proposal_QListView"), "<Tab>")
test.compare(str(lineUnderCursor(editorWidget)).strip(), "void",
"Step 4: Verifying if: Word 'void' is completed because only one option is available.")
proposalListView = waitForObject(":popupFrame_Proposal_QListView")
waitForObjectItem(proposalListView, "unsigned")
test.compare(proposalListView.model().rowCount(), 1, 'Only one proposal for "unsi"?')
type(proposalListView, "<Tab>")
test.compare(str(lineUnderCursor(editorWidget)).strip(), "unsigned",
"Step 4: Verifying if: Word 'unsigned' is completed because only one option is available.")
except:
test.fail("The expected completion popup was not shown.")
# Step 4.5: Insert text "2." to new line and verify that code completion is not triggered (QTCREATORBUG-16188)