forked from qt-creator/qt-creator
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:
20
dist/changes-4.7.0.md
vendored
20
dist/changes-4.7.0.md
vendored
@@ -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
|
||||
|
||||
78
doc/src/cpp/creator-sidebar-cpp-views.qdocinc
Normal file
78
doc/src/cpp/creator-sidebar-cpp-views.qdocinc
Normal 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]
|
||||
*/
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 "%1" 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>
|
||||
|
||||
@@ -104,7 +104,9 @@ enum class HighlightingType : quint8
|
||||
ObjectiveCInterface,
|
||||
ObjectiveCImplementation,
|
||||
ObjectiveCProperty,
|
||||
ObjectiveCMethod
|
||||
ObjectiveCMethod,
|
||||
TemplateTypeParameter,
|
||||
TemplateTemplateParameter
|
||||
};
|
||||
|
||||
enum class StorageClass : quint8
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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 ®Ex) {
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Submodule src/shared/qbs updated: 872e4b883d...73d0d3a247
@@ -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;
|
||||
|
||||
@@ -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 *"])
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user