forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/14.0'
Change-Id: Ia809bda892afe5321aaaca2275f24baaf9569abc
This commit is contained in:
Binary file not shown.
After Width: | Height: | Size: 8.2 KiB |
BIN
doc/qtcreator/images/qtcreator-projects-cpp-code-model.webp
Normal file
BIN
doc/qtcreator/images/qtcreator-projects-cpp-code-model.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
@@ -23,7 +23,9 @@
|
|||||||
applications on them.
|
applications on them.
|
||||||
|
|
||||||
\note If you use qmake to build the project and the device does not have
|
\note If you use qmake to build the project and the device does not have
|
||||||
Qt libraries, you need a fake Qt installation.
|
Qt libraries, you need a Qt installation that meets the requirements in
|
||||||
|
\l{Self-built Qt versions}. In addition, the \c mkspecs directory needs
|
||||||
|
to be complete enough to parse .pro files.
|
||||||
|
|
||||||
The following toolchains are supported for building applications:
|
The following toolchains are supported for building applications:
|
||||||
|
|
||||||
|
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
You are advised to use CMake to build applications in the Docker container.
|
You are advised to use CMake to build applications in the Docker container.
|
||||||
|
|
||||||
|
\note Enable the Docker plugin to use it.
|
||||||
|
|
||||||
To pull images from Docker hub or other registries, use the
|
To pull images from Docker hub or other registries, use the
|
||||||
\l{https://docs.docker.com/engine/reference/commandline/pull/}{docker pull}
|
\l{https://docs.docker.com/engine/reference/commandline/pull/}{docker pull}
|
||||||
command.
|
command.
|
||||||
@@ -64,7 +66,8 @@
|
|||||||
Go to \preferences > \uicontrol Kits to check
|
Go to \preferences > \uicontrol Kits to check
|
||||||
that the automatically generated kits point to the appropriate kit items.
|
that the automatically generated kits point to the appropriate kit items.
|
||||||
|
|
||||||
\sa {Docker}{How To: Develop for Docker}, {Manage Kits}{How To: Manage Kits}
|
\sa {Enable and disable plugins}, {Docker}{How To: Develop for Docker},
|
||||||
|
{Manage Kits}{How To: Manage Kits}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -75,6 +78,8 @@
|
|||||||
|
|
||||||
\title Set preferences for Docker devices
|
\title Set preferences for Docker devices
|
||||||
|
|
||||||
|
\note Enable the Docker plugin to use it.
|
||||||
|
|
||||||
To set preferences for Docker devices:
|
To set preferences for Docker devices:
|
||||||
|
|
||||||
\list 1
|
\list 1
|
||||||
@@ -165,7 +170,8 @@
|
|||||||
\uicontrol {List Auto-Detected Kit Items}. To remove
|
\uicontrol {List Auto-Detected Kit Items}. To remove
|
||||||
them, select \uicontrol {Remove Auto-Detected Kit Items}.
|
them, select \uicontrol {Remove Auto-Detected Kit Items}.
|
||||||
|
|
||||||
\sa {Docker}{How To: Develop for Docker}, {Manage Kits}{How To: Manage Kits}
|
\sa {Enable and disable plugins}, {Docker}{How To: Develop for Docker},
|
||||||
|
{Manage Kits}{How To: Manage Kits}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -176,6 +182,8 @@
|
|||||||
|
|
||||||
\title Build for and run on Docker devices
|
\title Build for and run on Docker devices
|
||||||
|
|
||||||
|
\note Enable the Docker plugin to use it.
|
||||||
|
|
||||||
To specify build settings for Docker images:
|
To specify build settings for Docker images:
|
||||||
|
|
||||||
\list 1
|
\list 1
|
||||||
@@ -188,5 +196,6 @@
|
|||||||
Select \uicontrol Run to specify run settings. Usually, you can use
|
Select \uicontrol Run to specify run settings. Usually, you can use
|
||||||
the default settings.
|
the default settings.
|
||||||
|
|
||||||
\sa {Docker}{How To: Develop for Docker}, {Manage Kits}{How To: Manage Kits}
|
\sa {Enable and disable plugins}, {Docker}{How To: Develop for Docker},
|
||||||
|
{Manage Kits}{How To: Manage Kits}
|
||||||
*/
|
*/
|
||||||
|
@@ -124,8 +124,34 @@
|
|||||||
The document outline in the \l{Outline} view is backed by clangd's document
|
The document outline in the \l{Outline} view is backed by clangd's document
|
||||||
symbol support, which makes the results more reliable than before.
|
symbol support, which makes the results more reliable than before.
|
||||||
|
|
||||||
\sa {Code Model}, {Clangd}, {Specify clangd settings},
|
\sa {Configure C++ code model}, {Specify clangd settings},
|
||||||
{Specify Clang tools settings}, {Use compilation databases}
|
{Specify Clang tools settings}, {Use compilation databases},
|
||||||
|
{Code Model}, {Clangd}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\page creator-how-to-cpp-code-model.html
|
||||||
|
\previouspage creator-how-tos.html
|
||||||
|
|
||||||
|
\ingroup creator-how-to-configure-editors
|
||||||
|
\ingroup creator-how-to-projects-configure
|
||||||
|
|
||||||
|
\title Configure C++ code model
|
||||||
|
|
||||||
|
The code model offers services such as code completion, syntactic and
|
||||||
|
semantic highlighting, and diagnostics.
|
||||||
|
|
||||||
|
To configure the C++ code model for a project:
|
||||||
|
|
||||||
|
\list 1
|
||||||
|
\li Go to \uicontrol Projects > \uicontrol {Project Settings} >
|
||||||
|
\uicontrol {C++ Code Model}.
|
||||||
|
\image qtcreator-projects-cpp-code-model.webp {C++ Code Model settings}
|
||||||
|
\li Clear \uicontrol {Use global settings}.
|
||||||
|
\li Set \uicontrol {C++ Code Model} settings for the project.
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
\sa {Code Model}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -138,40 +164,43 @@
|
|||||||
|
|
||||||
\brief Sets global preferences for the code model.
|
\brief Sets global preferences for the code model.
|
||||||
|
|
||||||
The Clang code model offers services such as code completion, syntactic and
|
The code model offers services such as code completion, syntactic and
|
||||||
semantic highlighting, and diagnostics.
|
semantic highlighting, and diagnostics.
|
||||||
|
|
||||||
To configure the Clang code model globally:
|
To configure the C++ code model globally, go to \preferences >
|
||||||
|
\uicontrol C++ > \uicontrol {Code Model}.
|
||||||
\list 1
|
|
||||||
|
|
||||||
\li Select \preferences > \uicontrol C++ >
|
|
||||||
\uicontrol {Code Model}.
|
|
||||||
|
|
||||||
\image qtcreator-preferences-code-model.webp {C++ Code Model preferences}
|
\image qtcreator-preferences-code-model.webp {C++ Code Model preferences}
|
||||||
|
|
||||||
\li To instruct the code model to interpret ambiguous header files as C
|
The following table summarizes the preferences.
|
||||||
language files if you develop mainly using C, select the
|
|
||||||
\uicontrol {Interpret ambiguous headers as C headers} check box.
|
|
||||||
|
|
||||||
\li To process precompiled headers, deselect the
|
|
||||||
\uicontrol {Ignore precompiled headers} check box.
|
|
||||||
|
|
||||||
\li To use the built-in preprocessor to show the
|
|
||||||
pre-processed source file in the editor, select
|
|
||||||
\uicontrol {Use built-in preprocessor to show pre-processed files}.
|
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Setting
|
||||||
|
\li Value
|
||||||
|
\row
|
||||||
|
\li \uicontrol {Interpret ambiguous headers as C headers}
|
||||||
|
\li Instructs the code model to interpret ambiguous header files as C
|
||||||
|
language files. Select this checkbox if you develop mainly using C.
|
||||||
|
\row
|
||||||
|
\li \uicontrol {Ignore precompiled headers}
|
||||||
|
\li Clear this checkbox to process precompiled headers.
|
||||||
|
\row
|
||||||
|
\li \uicontrol {Use built-in preprocessor to show pre-processed files}
|
||||||
|
\li Uses the built-in preprocessor to show the
|
||||||
|
pre-processed source file in the editor.
|
||||||
|
\row
|
||||||
|
\li \uicontrol {Do not index files greater than}
|
||||||
\li To avoid out-of-memory crashes caused by indexing huge source files
|
\li To avoid out-of-memory crashes caused by indexing huge source files
|
||||||
that are typically auto-generated by scripts or code, the size of
|
that are typically auto-generated by scripts or code, the size of
|
||||||
files to index is limited to 5MB by default. To adjust the limit,
|
files to index is limited to 5MB by default.
|
||||||
edit the value for the \uicontrol {Do not index files greater than}
|
|
||||||
check box. To index all files, deselect the check box.
|
|
||||||
|
|
||||||
\li To ignore files that match wildcard patterns, select the
|
To index all files, clear the checkbox.
|
||||||
\uicontrol {Ignore files} check box and enter each wildcard pattern
|
\row
|
||||||
on a separate line in the field.
|
\li \uicontrol {Ignore files}
|
||||||
|
\li To ignore files that match wildcard patterns, enter each wildcard
|
||||||
\endlist
|
pattern on a separate line in the field.
|
||||||
|
\endtable
|
||||||
|
|
||||||
\section1 Inspect preprocessed C++ code
|
\section1 Inspect preprocessed C++ code
|
||||||
|
|
||||||
@@ -186,7 +215,8 @@
|
|||||||
this action also expands all \c {"#include <foo.h>"} statements to their
|
this action also expands all \c {"#include <foo.h>"} statements to their
|
||||||
actual contents.
|
actual contents.
|
||||||
|
|
||||||
\sa {Specify clangd settings}, {Clang Code Model}, {Clangd}
|
\sa {Configure C++ code model}, {Specify clangd settings},
|
||||||
|
{Clang Code Model}, {Clangd}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@@ -108,28 +108,45 @@
|
|||||||
|
|
||||||
To verify the installation of a particular Qt version, \QC
|
To verify the installation of a particular Qt version, \QC
|
||||||
calls \c {qmake -query} and checks that the directories referenced in the
|
calls \c {qmake -query} and checks that the directories referenced in the
|
||||||
output exist. When \QC complains about the installation of a self-built Qt
|
output exist. If you installed Qt using \QOI, run
|
||||||
version, try running \c {make install} in the build directory to actually
|
\QMT to check for updates or to reinstall the Qt version.
|
||||||
install Qt into the configured location. If you installed Qt using the Qt
|
|
||||||
Installer, run \QMT to check for updates or to reinstall
|
|
||||||
the Qt version.
|
|
||||||
|
|
||||||
\section1 Minimum requirements
|
\section2 Self-built Qt versions
|
||||||
If your build of Qt is incomplete but you still want to use qmake as build
|
|
||||||
system, you need to ensure the following minimum requirements to use that
|
|
||||||
setup with \QC.
|
|
||||||
|
|
||||||
\list 1
|
To build projects with a self-built Qt version, add it as described in
|
||||||
|
\l{Set up new Qt versions}.
|
||||||
|
|
||||||
|
Your Qt has to meet the following minimum requirements:
|
||||||
|
|
||||||
|
\list
|
||||||
\li qmake is an executable that understands the \c -query command-line
|
\li qmake is an executable that understands the \c -query command-line
|
||||||
argument.
|
argument.
|
||||||
\li The \c bin and \c include directories have to exist. \QC fetches
|
\li The \c bin and \c include directories have to exist. \QC fetches
|
||||||
these directories by running \c{qmake -query}.
|
these directories by running \c{qmake -query}.
|
||||||
\li The \c mkspecs directory should be complete enough to parse .pro
|
|
||||||
files.
|
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
If your Qt version has no \c libQtCore.so, \QC cannot detect the ABI.
|
Add a kit for the Qt version and configure it for CMake.
|
||||||
|
|
||||||
\sa {kits-tab}{Kits}
|
\QC issues warnings if:
|
||||||
|
|
||||||
|
\list
|
||||||
|
\li \c libQtCore.so is missing, so \QC cannot detect the ABI.
|
||||||
|
\li \c toolchain.cmake is missing. For example, you built Qt with the
|
||||||
|
\c -static option for an x86 platform.
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
Try the following:
|
||||||
|
|
||||||
|
\list
|
||||||
|
\li Run \c {make install} in the build directory to install Qt into the
|
||||||
|
configured location.
|
||||||
|
\li Set the value of the \c CMAKE_PREFIX_PATH variable in \preferences >
|
||||||
|
\uicontrol Kits > \uicontrol Kits > \uicontrol {CMake Configuration}
|
||||||
|
to the location where you installed Qt.
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
\image qtcreator-edit-cmake-configuration-self-built-qt.webp {Setting the path to a self-built Qt}
|
||||||
|
|
||||||
|
\sa {Manage Kits}{How To: Manage Kits}, {kits-tab}{Kits}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@@ -85,6 +85,7 @@
|
|||||||
\li \l{Specify clangd settings}{Clangd}
|
\li \l{Specify clangd settings}{Clangd}
|
||||||
\li \l{Specify Clang tools settings}{Clang Tools}
|
\li \l{Specify Clang tools settings}{Clang Tools}
|
||||||
\li \l{Set Copilot preferences}{Copilot}
|
\li \l{Set Copilot preferences}{Copilot}
|
||||||
|
\li \l{Configure C++ code model}{C++ Code Model}
|
||||||
\li \l{Specify code style}{C++ Code Style}
|
\li \l{Specify code style}{C++ Code Style}
|
||||||
\li \l{Set C++ file naming preferences}{C++ File Naming}
|
\li \l{Set C++ file naming preferences}{C++ File Naming}
|
||||||
\li \l{Specify dependencies}{Dependencies}
|
\li \l{Specify dependencies}{Dependencies}
|
||||||
|
@@ -12,6 +12,7 @@ Product {
|
|||||||
property string versionTag: qtc.qtcreator_version.replace(/\.|-/g, "")
|
property string versionTag: qtc.qtcreator_version.replace(/\.|-/g, "")
|
||||||
|
|
||||||
Qt.core.qdocEnvironment: [
|
Qt.core.qdocEnvironment: [
|
||||||
|
"GENERATED_ATTRIBUTIONS_DIR=" + product.buildDirectory,
|
||||||
"IDE_DISPLAY_NAME=" + qtc.ide_display_name,
|
"IDE_DISPLAY_NAME=" + qtc.ide_display_name,
|
||||||
"IDE_CASED_ID=" + qtc.ide_cased_id,
|
"IDE_CASED_ID=" + qtc.ide_cased_id,
|
||||||
"IDE_ID=" + qtc.ide_id,
|
"IDE_ID=" + qtc.ide_id,
|
||||||
|
@@ -77,6 +77,8 @@ class Dumper(DumperBase):
|
|||||||
self.isCdb = True
|
self.isCdb = True
|
||||||
|
|
||||||
#FIXME
|
#FIXME
|
||||||
|
def register_known_qt_types(self):
|
||||||
|
DumperBase.register_known_qt_types(self)
|
||||||
typeid = self.typeid_for_string('@QVariantMap')
|
typeid = self.typeid_for_string('@QVariantMap')
|
||||||
del self.type_code_cache[typeid]
|
del self.type_code_cache[typeid]
|
||||||
del self.type_target_cache[typeid]
|
del self.type_target_cache[typeid]
|
||||||
|
@@ -172,8 +172,6 @@ class DumperBase():
|
|||||||
self.qtCustomEventFunc = 0
|
self.qtCustomEventFunc = 0
|
||||||
self.qtCustomEventPltFunc = 0
|
self.qtCustomEventPltFunc = 0
|
||||||
self.qtPropertyFunc = 0
|
self.qtPropertyFunc = 0
|
||||||
self.qtversion = None
|
|
||||||
self.qtns = None
|
|
||||||
self.passExceptions = False
|
self.passExceptions = False
|
||||||
self.isTesting = False
|
self.isTesting = False
|
||||||
self.qtLoaded = False
|
self.qtLoaded = False
|
||||||
@@ -189,6 +187,11 @@ class DumperBase():
|
|||||||
|
|
||||||
self.dumpermodules = []
|
self.dumpermodules = []
|
||||||
|
|
||||||
|
# These are sticky for the session
|
||||||
|
self.qtversion = None
|
||||||
|
self.qtversionAtLeast6 = None
|
||||||
|
self.qtnamespace = None
|
||||||
|
|
||||||
self.init_type_cache()
|
self.init_type_cache()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -211,7 +214,7 @@ class DumperBase():
|
|||||||
self.currentPrintsAddress = True
|
self.currentPrintsAddress = True
|
||||||
self.currentChildType = None
|
self.currentChildType = None
|
||||||
self.currentChildNumChild = None
|
self.currentChildNumChild = None
|
||||||
self.register_known_types()
|
self.register_known_simple_types()
|
||||||
|
|
||||||
def setVariableFetchingOptions(self, args):
|
def setVariableFetchingOptions(self, args):
|
||||||
self.last_args = args
|
self.last_args = args
|
||||||
@@ -233,9 +236,16 @@ class DumperBase():
|
|||||||
self.useTimeStamps = int(args.get('timestamps', '0'))
|
self.useTimeStamps = int(args.get('timestamps', '0'))
|
||||||
self.partialVariable = args.get('partialvar', '')
|
self.partialVariable = args.get('partialvar', '')
|
||||||
self.uninitialized = args.get('uninitialized', [])
|
self.uninitialized = args.get('uninitialized', [])
|
||||||
self.qtversion = args.get('qtversion', 0x060602)
|
|
||||||
self.qtnamespace = args.get('qtnamespace', '')
|
|
||||||
self.uninitialized = list(map(lambda x: self.hexdecode(x), self.uninitialized))
|
self.uninitialized = list(map(lambda x: self.hexdecode(x), self.uninitialized))
|
||||||
|
|
||||||
|
if self.qtversion is None:
|
||||||
|
self.qtversion = args.get('qtversion', None)
|
||||||
|
if self.qtversion == 0:
|
||||||
|
self.qtversion = None
|
||||||
|
if self.qtnamespace is None:
|
||||||
|
self.qtnamespace = args.get('qtnamespace', None)
|
||||||
|
|
||||||
#self.warn('NAMESPACE: "%s"' % self.qtNamespace())
|
#self.warn('NAMESPACE: "%s"' % self.qtNamespace())
|
||||||
#self.warn('EXPANDED INAMES: %s' % self.expandedINames)
|
#self.warn('EXPANDED INAMES: %s' % self.expandedINames)
|
||||||
#self.warn('WATCHERS: %s' % self.watchers)
|
#self.warn('WATCHERS: %s' % self.watchers)
|
||||||
@@ -256,11 +266,50 @@ class DumperBase():
|
|||||||
args['partialvar'] = ''
|
args['partialvar'] = ''
|
||||||
self.fetchVariables(args)
|
self.fetchVariables(args)
|
||||||
|
|
||||||
|
def extractQtVersion(self):
|
||||||
|
# can be overridden in bridges
|
||||||
|
pass
|
||||||
|
|
||||||
def qtVersion(self):
|
def qtVersion(self):
|
||||||
|
if self.qtversion:
|
||||||
return self.qtversion
|
return self.qtversion
|
||||||
|
|
||||||
|
#self.warn("ACCESSING UNKNOWN QT VERSION")
|
||||||
|
self.qtversion = self.extractQtVersion()
|
||||||
|
if self.qtversion:
|
||||||
|
return self.qtversion
|
||||||
|
|
||||||
|
#self.warn("EXTRACTING QT VERSION FAILED. GUESSING NOW.")
|
||||||
|
if self.qtversionAtLeast6 is None or self.qtversionAtLeast6 is True:
|
||||||
|
return 0x060602
|
||||||
|
return 0x050f00
|
||||||
|
|
||||||
|
def qtVersionAtLeast(self, version):
|
||||||
|
# A hack to cover most of the changes from Qt 5 to 6
|
||||||
|
if version == 0x60000 and self.qtversionAtLeast6 is not None:
|
||||||
|
return self.qtversionAtLeast6
|
||||||
|
if version == 0x50000: # FIXME: This drops unknown 4.x for now
|
||||||
|
return True
|
||||||
|
return self.qtVersion() >= version
|
||||||
|
|
||||||
|
def qtVersionPing(self, typeid, size_for_qt5=-1):
|
||||||
|
# To be called from places where the type size is sufficient
|
||||||
|
# to distinguish Qt 5.x and 6.x
|
||||||
|
if size_for_qt5 == -1:
|
||||||
|
size_for_qt5 = self.ptrSize()
|
||||||
|
test_size = self.type_size(typeid)
|
||||||
|
self.setQtVersionAtLeast6(test_size > size_for_qt5)
|
||||||
|
|
||||||
|
def setQtVersionAtLeast6(self, is6):
|
||||||
|
if self.qtversionAtLeast6 is None:
|
||||||
|
#self.warn("SETTING Qt VERSION AT LEAST 6 TO %s" % is6)
|
||||||
|
self.qtversionAtLeast6 = is6
|
||||||
|
self.register_known_qt_types()
|
||||||
|
#else:
|
||||||
|
# self.warn("QT VERSION ALREADY KNOWN")
|
||||||
|
|
||||||
def qtNamespace(self):
|
def qtNamespace(self):
|
||||||
return self.qtnamespace
|
return '' if self.qtnamespace is None else self.qtnamespace
|
||||||
|
|
||||||
def resetPerStepCaches(self):
|
def resetPerStepCaches(self):
|
||||||
self.perStepCache = {}
|
self.perStepCache = {}
|
||||||
@@ -494,8 +543,13 @@ class DumperBase():
|
|||||||
def register_struct(self, name, p5=0, p6=0, s=0, qobject_based=False):
|
def register_struct(self, name, p5=0, p6=0, s=0, qobject_based=False):
|
||||||
# p5 = n -> n * ptrsize for Qt 5
|
# p5 = n -> n * ptrsize for Qt 5
|
||||||
# p6 = n -> n * ptrsize for Qt 6
|
# p6 = n -> n * ptrsize for Qt 6
|
||||||
#if self.qtVersion() >= 0x060000: # FIXME: Qt 5, ptrSize()
|
if self.qtversionAtLeast6 is None:
|
||||||
|
self.warn("TOO EARLY TO GUESS QT VERSION")
|
||||||
size = 8 * p6 + s
|
size = 8 * p6 + s
|
||||||
|
elif self.qtversionAtLeast6 is True:
|
||||||
|
size = 8 * p6 + s
|
||||||
|
else:
|
||||||
|
size = 8 * p5 + s
|
||||||
typeid = self.typeid_for_string(name)
|
typeid = self.typeid_for_string(name)
|
||||||
self.type_code_cache[typeid] = TypeCode.Struct
|
self.type_code_cache[typeid] = TypeCode.Struct
|
||||||
self.type_size_cache[typeid] = size
|
self.type_size_cache[typeid] = size
|
||||||
@@ -503,7 +557,7 @@ class DumperBase():
|
|||||||
self.type_alignment_cache[typeid] = 8
|
self.type_alignment_cache[typeid] = 8
|
||||||
return typeid
|
return typeid
|
||||||
|
|
||||||
def register_known_types(self):
|
def register_known_simple_types(self):
|
||||||
typeid = 0
|
typeid = 0
|
||||||
self.typeid_cache[''] = typeid
|
self.typeid_cache[''] = typeid
|
||||||
self.type_code_cache[typeid] = TypeCode.Void
|
self.type_code_cache[typeid] = TypeCode.Void
|
||||||
@@ -563,6 +617,8 @@ class DumperBase():
|
|||||||
|
|
||||||
self.register_enum('@Qt::ItemDataRole', 4)
|
self.register_enum('@Qt::ItemDataRole', 4)
|
||||||
|
|
||||||
|
def register_known_qt_types(self):
|
||||||
|
#self.warn("REGISTERING KNOWN QT TYPES NOW")
|
||||||
self.register_struct('@QObject', p5=2, p6=2, qobject_based=True)
|
self.register_struct('@QObject', p5=2, p6=2, qobject_based=True)
|
||||||
self.register_struct('@QObjectPrivate', p5=10, p6=10) # FIXME: Not exact
|
self.register_struct('@QObjectPrivate', p5=10, p6=10) # FIXME: Not exact
|
||||||
|
|
||||||
@@ -680,9 +736,6 @@ class DumperBase():
|
|||||||
# Hex decoding operating on str, return str.
|
# Hex decoding operating on str, return str.
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def hexdecode(s, encoding='utf8'):
|
def hexdecode(s, encoding='utf8'):
|
||||||
if sys.version_info[0] == 2:
|
|
||||||
# For python2 we need an extra str() call to return str instead of unicode
|
|
||||||
return str(s.decode('hex').decode(encoding))
|
|
||||||
return bytes.fromhex(s).decode(encoding)
|
return bytes.fromhex(s).decode(encoding)
|
||||||
|
|
||||||
# Hex encoding operating on str or bytes, return str.
|
# Hex encoding operating on str or bytes, return str.
|
||||||
@@ -690,10 +743,6 @@ class DumperBase():
|
|||||||
def hexencode(s):
|
def hexencode(s):
|
||||||
if s is None:
|
if s is None:
|
||||||
s = ''
|
s = ''
|
||||||
if sys.version_info[0] == 2:
|
|
||||||
if isinstance(s, buffer):
|
|
||||||
return bytes(s).encode('hex')
|
|
||||||
return s.encode('hex')
|
|
||||||
if isinstance(s, str):
|
if isinstance(s, str):
|
||||||
s = s.encode('utf8')
|
s = s.encode('utf8')
|
||||||
return hexencode_(s)
|
return hexencode_(s)
|
||||||
@@ -711,9 +760,9 @@ class DumperBase():
|
|||||||
return limit
|
return limit
|
||||||
|
|
||||||
def vectorData(self, value):
|
def vectorData(self, value):
|
||||||
if self.qtVersion() >= 0x060000:
|
if self.qtVersionAtLeast(0x060000):
|
||||||
data, length, alloc = self.qArrayData(value)
|
data, length, alloc = self.qArrayData(value)
|
||||||
elif self.qtVersion() >= 0x050000:
|
elif self.qtVersionAtLeast(0x050000):
|
||||||
vector_data_ptr = self.extractPointer(value)
|
vector_data_ptr = self.extractPointer(value)
|
||||||
if self.ptrSize() == 4:
|
if self.ptrSize() == 4:
|
||||||
(ref, length, alloc, offset) = self.split('IIIp', vector_data_ptr)
|
(ref, length, alloc, offset) = self.split('IIIp', vector_data_ptr)
|
||||||
@@ -729,7 +778,7 @@ class DumperBase():
|
|||||||
return data, length
|
return data, length
|
||||||
|
|
||||||
def qArrayData(self, value):
|
def qArrayData(self, value):
|
||||||
if self.qtVersion() >= 0x60000:
|
if self.qtVersionAtLeast(0x60000):
|
||||||
dd, data, length = self.split('ppp', value)
|
dd, data, length = self.split('ppp', value)
|
||||||
if dd:
|
if dd:
|
||||||
_, _, alloc = self.split('iip', dd)
|
_, _, alloc = self.split('iip', dd)
|
||||||
@@ -740,7 +789,7 @@ class DumperBase():
|
|||||||
|
|
||||||
def qArrayDataHelper(self, array_data_ptr):
|
def qArrayDataHelper(self, array_data_ptr):
|
||||||
# array_data_ptr is what is e.g. stored in a QByteArray's d_ptr.
|
# array_data_ptr is what is e.g. stored in a QByteArray's d_ptr.
|
||||||
if self.qtVersion() >= 0x050000:
|
if self.qtVersionAtLeast(0x050000):
|
||||||
# QTypedArray:
|
# QTypedArray:
|
||||||
# - QtPrivate::RefCount ref
|
# - QtPrivate::RefCount ref
|
||||||
# - int length
|
# - int length
|
||||||
@@ -753,7 +802,7 @@ class DumperBase():
|
|||||||
data = data & 0xffffffff
|
data = data & 0xffffffff
|
||||||
else:
|
else:
|
||||||
data = data & 0xffffffffffffffff
|
data = data & 0xffffffffffffffff
|
||||||
elif self.qtVersion() >= 0x040000:
|
elif self.qtVersionAtLeast(0x040000):
|
||||||
# Data:
|
# Data:
|
||||||
# - QBasicAtomicInt ref;
|
# - QBasicAtomicInt ref;
|
||||||
# - int alloc, length;
|
# - int alloc, length;
|
||||||
@@ -1597,7 +1646,7 @@ class DumperBase():
|
|||||||
|
|
||||||
intSize = 4
|
intSize = 4
|
||||||
ptrSize = self.ptrSize()
|
ptrSize = self.ptrSize()
|
||||||
if self.qtVersion() >= 0x060000:
|
if self.qtVersionAtLeast(0x060000):
|
||||||
# Size of QObjectData: 9 pointer + 2 int
|
# Size of QObjectData: 9 pointer + 2 int
|
||||||
# - vtable
|
# - vtable
|
||||||
# - QObject *q_ptr;
|
# - QObject *q_ptr;
|
||||||
@@ -1618,7 +1667,7 @@ class DumperBase():
|
|||||||
# - QList<QPointer<QObject> > eventFilters;
|
# - QList<QPointer<QObject> > eventFilters;
|
||||||
# - QString objectName
|
# - QString objectName
|
||||||
objectNameAddress = extra + 12 * ptrSize
|
objectNameAddress = extra + 12 * ptrSize
|
||||||
elif self.qtVersion() >= 0x050000:
|
elif self.qtVersionAtLeast(0x050000):
|
||||||
# Size of QObjectData: 5 pointer + 2 int
|
# Size of QObjectData: 5 pointer + 2 int
|
||||||
# - vtable
|
# - vtable
|
||||||
# - QObject *q_ptr;
|
# - QObject *q_ptr;
|
||||||
@@ -1811,7 +1860,7 @@ class DumperBase():
|
|||||||
# a Q_OBJECT SMO has a non-null superdata (unless it's QObject itself),
|
# a Q_OBJECT SMO has a non-null superdata (unless it's QObject itself),
|
||||||
# a Q_GADGET SMO has a null superdata (hopefully)
|
# a Q_GADGET SMO has a null superdata (hopefully)
|
||||||
if result and not isQObjectProper:
|
if result and not isQObjectProper:
|
||||||
if self.qtVersion() >= 0x60000 and self.isWindowsTarget():
|
if self.qtVersionAtLeast(0x60000) and self.isWindowsTarget():
|
||||||
(direct, indirect) = self.split('pp', result)
|
(direct, indirect) = self.split('pp', result)
|
||||||
# since Qt 6 there is an additional indirect super data getter on windows
|
# since Qt 6 there is an additional indirect super data getter on windows
|
||||||
if direct == 0 and indirect == 0:
|
if direct == 0 and indirect == 0:
|
||||||
@@ -1895,14 +1944,14 @@ class DumperBase():
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def listData(self, value, check=True):
|
def listData(self, value, check=True):
|
||||||
if self.qtVersion() >= 0x60000:
|
if self.qtVersionAtLeast(0x60000):
|
||||||
dd, data, size = self.split('ppi', value)
|
dd, data, size = self.split('ppi', value)
|
||||||
return data, size
|
return data, size
|
||||||
|
|
||||||
base = self.extractPointer(value)
|
base = self.extractPointer(value)
|
||||||
(ref, alloc, begin, end) = self.split('IIII', base)
|
(ref, alloc, begin, end) = self.split('IIII', base)
|
||||||
array = base + 16
|
array = base + 16
|
||||||
if self.qtVersion() < 0x50000:
|
if not self.qtVersionAtLeast(0x50000):
|
||||||
array += self.ptrSize()
|
array += self.ptrSize()
|
||||||
size = end - begin
|
size = end - begin
|
||||||
|
|
||||||
@@ -1941,7 +1990,7 @@ class DumperBase():
|
|||||||
def metaString(self, metaObjectPtr, index, revision):
|
def metaString(self, metaObjectPtr, index, revision):
|
||||||
ptrSize = self.ptrSize()
|
ptrSize = self.ptrSize()
|
||||||
stringdataOffset = ptrSize
|
stringdataOffset = ptrSize
|
||||||
if self.isWindowsTarget() and self.qtVersion() >= 0x060000:
|
if self.isWindowsTarget() and self.qtVersionAtLeast(0x060000):
|
||||||
stringdataOffset += ptrSize # indirect super data member
|
stringdataOffset += ptrSize # indirect super data member
|
||||||
stringdata = self.extract_pointer_at_address(int(metaObjectPtr) + stringdataOffset)
|
stringdata = self.extract_pointer_at_address(int(metaObjectPtr) + stringdataOffset)
|
||||||
|
|
||||||
@@ -1970,19 +2019,19 @@ class DumperBase():
|
|||||||
self.putField('sortgroup', sortorder)
|
self.putField('sortgroup', sortorder)
|
||||||
|
|
||||||
def putQMetaStuff(self, value, origType):
|
def putQMetaStuff(self, value, origType):
|
||||||
if self.qtVersion() >= 0x060000:
|
if self.qtVersionAtLeast(0x060000):
|
||||||
metaObjectPtr, handle = value.split('pp')
|
metaObjectPtr, handle = value.split('pp')
|
||||||
else:
|
else:
|
||||||
metaObjectPtr, handle = value.split('pI')
|
metaObjectPtr, handle = value.split('pI')
|
||||||
if metaObjectPtr != 0:
|
if metaObjectPtr != 0:
|
||||||
if self.qtVersion() >= 0x060000:
|
if self.qtVersionAtLeast(0x060000):
|
||||||
if handle == 0:
|
if handle == 0:
|
||||||
self.putEmptyValue()
|
self.putEmptyValue()
|
||||||
return
|
return
|
||||||
revision = 9
|
revision = 9
|
||||||
name, alias, flags, keyCount, data = self.split('IIIII', handle)
|
name, alias, flags, keyCount, data = self.split('IIIII', handle)
|
||||||
index = name
|
index = name
|
||||||
elif self.qtVersion() >= 0x050000:
|
elif self.qtVersionAtLeast(0x050000):
|
||||||
revision = 7
|
revision = 7
|
||||||
dataPtr = self.extract_pointer_at_address(metaObjectPtr + 2 * self.ptrSize())
|
dataPtr = self.extract_pointer_at_address(metaObjectPtr + 2 * self.ptrSize())
|
||||||
index = self.extractInt(dataPtr + 4 * handle)
|
index = self.extractInt(dataPtr + 4 * handle)
|
||||||
@@ -2024,7 +2073,7 @@ class DumperBase():
|
|||||||
|
|
||||||
def extractDataPtr(someMetaObjectPtr):
|
def extractDataPtr(someMetaObjectPtr):
|
||||||
# dataPtr = metaObjectPtr['d']['data']
|
# dataPtr = metaObjectPtr['d']['data']
|
||||||
if self.qtVersion() >= 0x60000 and self.isWindowsTarget():
|
if self.qtVersionAtLeast(0x60000) and self.isWindowsTarget():
|
||||||
offset = 3
|
offset = 3
|
||||||
else:
|
else:
|
||||||
offset = 2
|
offset = 2
|
||||||
@@ -2054,13 +2103,13 @@ class DumperBase():
|
|||||||
extraData = 0
|
extraData = 0
|
||||||
if qobjectPtr:
|
if qobjectPtr:
|
||||||
dd = self.extract_pointer_at_address(qobjectPtr + ptrSize)
|
dd = self.extract_pointer_at_address(qobjectPtr + ptrSize)
|
||||||
if self.qtVersion() >= 0x60000:
|
if self.qtVersionAtLeast(0x60000):
|
||||||
(dvtablePtr, qptr, parent, children, bindingStorageData, bindingStatus,
|
(dvtablePtr, qptr, parent, children, bindingStorageData, bindingStatus,
|
||||||
flags, postedEvents, dynMetaObjectPtr, # Up to here QObjectData.
|
flags, postedEvents, dynMetaObjectPtr, # Up to here QObjectData.
|
||||||
extraData, threadDataPtr, connectionListsPtr,
|
extraData, threadDataPtr, connectionListsPtr,
|
||||||
sendersPtr, currentSenderPtr) \
|
sendersPtr, currentSenderPtr) \
|
||||||
= self.split('pp{@QObject*}{@QList<@QObject *>}ppIIp' + 'ppppp', dd)
|
= self.split('pp{@QObject*}{@QList<@QObject *>}ppIIp' + 'ppppp', dd)
|
||||||
elif self.qtVersion() >= 0x50000:
|
elif self.qtVersionAtLeast(0x50000):
|
||||||
(dvtablePtr, qptr, parent, children, flags, postedEvents,
|
(dvtablePtr, qptr, parent, children, flags, postedEvents,
|
||||||
dynMetaObjectPtr, # Up to here QObjectData.
|
dynMetaObjectPtr, # Up to here QObjectData.
|
||||||
extraData, threadDataPtr, connectionListsPtr,
|
extraData, threadDataPtr, connectionListsPtr,
|
||||||
@@ -2186,7 +2235,7 @@ typename))
|
|||||||
with Children(self):
|
with Children(self):
|
||||||
# Static properties.
|
# Static properties.
|
||||||
for i in range(propertyCount):
|
for i in range(propertyCount):
|
||||||
if self.qtVersion() >= 0x60000:
|
if self.qtVersionAtLeast(0x60000):
|
||||||
t = self.split('IIIII', dataPtr + properties * 4 + 20 * i)
|
t = self.split('IIIII', dataPtr + properties * 4 + 20 * i)
|
||||||
else:
|
else:
|
||||||
t = self.split('III', dataPtr + properties * 4 + 12 * i)
|
t = self.split('III', dataPtr + properties * 4 + 12 * i)
|
||||||
@@ -2239,18 +2288,18 @@ typename))
|
|||||||
data += inner_size
|
data += inner_size
|
||||||
|
|
||||||
variant_typeid = self.cheap_typeid_from_name('@QVariant')
|
variant_typeid = self.cheap_typeid_from_name('@QVariant')
|
||||||
if self.qtVersion() >= 0x60000:
|
if self.qtVersionAtLeast(0x60000):
|
||||||
values = vectorGenerator(extraData + 3 * ptrSize, variant_typeid)
|
values = vectorGenerator(extraData + 3 * ptrSize, variant_typeid)
|
||||||
elif self.qtVersion() >= 0x50600:
|
elif self.qtVersionAtLeast(0x50600):
|
||||||
values = vectorGenerator(extraData + 2 * ptrSize, variant_typeid)
|
values = vectorGenerator(extraData + 2 * ptrSize, variant_typeid)
|
||||||
elif self.qtVersion() >= 0x50000:
|
elif self.qtVersionAtLeast(0x50000):
|
||||||
values = list5Generator(extraData + 2 * ptrSize, variant_typeid)
|
values = list5Generator(extraData + 2 * ptrSize, variant_typeid)
|
||||||
else:
|
else:
|
||||||
variantptr_typeid = self.cheap_typeid_from_name('@QVariant')
|
variantptr_typeid = self.cheap_typeid_from_name('@QVariant')
|
||||||
values = list5Generator(extraData + 2 * ptrSize, variantptr_typeid)
|
values = list5Generator(extraData + 2 * ptrSize, variantptr_typeid)
|
||||||
|
|
||||||
bytearray_typeid = self.cheap_typeid_from_name('@QByteArray')
|
bytearray_typeid = self.cheap_typeid_from_name('@QByteArray')
|
||||||
if self.qtVersion() >= 0x60000:
|
if self.qtVersionAtLeast(0x60000):
|
||||||
names = list6Generator(extraData, bytearray_typeid)
|
names = list6Generator(extraData, bytearray_typeid)
|
||||||
else:
|
else:
|
||||||
names = list5Generator(extraData + ptrSize, bytearray_typeid)
|
names = list5Generator(extraData + ptrSize, bytearray_typeid)
|
||||||
@@ -2671,10 +2720,7 @@ typename))
|
|||||||
try:
|
try:
|
||||||
if funcname.startswith('qdump__'):
|
if funcname.startswith('qdump__'):
|
||||||
typename = funcname[7:]
|
typename = funcname[7:]
|
||||||
if sys.version_info > (3,):
|
|
||||||
spec = inspect.getfullargspec(function)
|
spec = inspect.getfullargspec(function)
|
||||||
else:
|
|
||||||
spec = inspect.getargspec(function)
|
|
||||||
if len(spec.args) == 2:
|
if len(spec.args) == 2:
|
||||||
self.qqDumpers[typename] = function
|
self.qqDumpers[typename] = function
|
||||||
elif len(spec.args) == 3 and len(spec.defaults) == 1:
|
elif len(spec.args) == 3 and len(spec.defaults) == 1:
|
||||||
@@ -2721,11 +2767,8 @@ typename))
|
|||||||
def reloadDumpers(self, args):
|
def reloadDumpers(self, args):
|
||||||
for mod in self.dumpermodules:
|
for mod in self.dumpermodules:
|
||||||
m = sys.modules[mod]
|
m = sys.modules[mod]
|
||||||
if sys.version_info[0] >= 3:
|
|
||||||
import importlib
|
import importlib
|
||||||
importlib.reload(m)
|
importlib.reload(m)
|
||||||
else:
|
|
||||||
reload(m)
|
|
||||||
self.setupDumpers(args)
|
self.setupDumpers(args)
|
||||||
|
|
||||||
def loadDumpers(self, args):
|
def loadDumpers(self, args):
|
||||||
@@ -3427,9 +3470,9 @@ typename))
|
|||||||
):
|
):
|
||||||
return True
|
return True
|
||||||
if strippedName == 'QStringList':
|
if strippedName == 'QStringList':
|
||||||
return self.dumper.qtVersion() >= 0x050000
|
return self.dumper.qtVersionAtLeast(0x050000)
|
||||||
if strippedName == 'QList':
|
if strippedName == 'QList':
|
||||||
return self.dumper.qtVersion() >= 0x050600
|
return self.dumper.qtVersionAtLeast(0x050600)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
class Field:
|
class Field:
|
||||||
@@ -3550,7 +3593,7 @@ typename))
|
|||||||
if typename.startswith('QList<') or typename.startswith('QVector<'):
|
if typename.startswith('QList<') or typename.startswith('QVector<'):
|
||||||
typeid = self.typeid_for_string(typename)
|
typeid = self.typeid_for_string(typename)
|
||||||
if typeid:
|
if typeid:
|
||||||
size = 3 * self.ptrSize() if self.qtVersion() >= 0x060000 else self.ptrSize()
|
size = 3 * self.ptrSize() if self.qtVersionAtLeast(0x060000) else self.ptrSize()
|
||||||
self.type_code_cache[typeid] = TypeCode.Struct
|
self.type_code_cache[typeid] = TypeCode.Struct
|
||||||
self.type_size_cache[typeid] = size
|
self.type_size_cache[typeid] = size
|
||||||
return typeid
|
return typeid
|
||||||
|
@@ -874,6 +874,36 @@ class Dumper(DumperBase):
|
|||||||
except:
|
except:
|
||||||
return '0x%x' % address
|
return '0x%x' % address
|
||||||
|
|
||||||
|
def qtVersionString(self):
|
||||||
|
try:
|
||||||
|
return str(gdb.lookup_symbol('qVersion')[0].value()())
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
ns = self.qtNamespace()
|
||||||
|
return str(gdb.parse_and_eval("((const char*(*)())'%sqVersion')()" % ns))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
|
def extractQtVersion(self):
|
||||||
|
try:
|
||||||
|
# Only available with Qt 5.3+
|
||||||
|
return int(str(gdb.parse_and_eval('((void**)&qtHookData)[2]')), 16)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
version = self.qtVersionString()
|
||||||
|
(major, minor, patch) = version[version.find('"') + 1:version.rfind('"')].split('.')
|
||||||
|
qtversion = 0x10000 * int(major) + 0x100 * int(minor) + int(patch)
|
||||||
|
self.qtVersion = lambda: qtversion
|
||||||
|
return qtversion
|
||||||
|
except:
|
||||||
|
# Use fallback until we have a better answer.
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def createSpecialBreakpoints(self, args):
|
def createSpecialBreakpoints(self, args):
|
||||||
self.specialBreakpoints = []
|
self.specialBreakpoints = []
|
||||||
|
|
||||||
|
@@ -18,11 +18,7 @@ sys.path.insert(1, os.path.dirname(os.path.abspath(inspect.getfile(inspect.curre
|
|||||||
|
|
||||||
# Simplify development of this module by reloading deps
|
# Simplify development of this module by reloading deps
|
||||||
if 'dumper' in sys.modules:
|
if 'dumper' in sys.modules:
|
||||||
if sys.version_info[0] >= 3:
|
|
||||||
if sys.version_info[1] > 3:
|
|
||||||
from importlib import reload
|
from importlib import reload
|
||||||
else:
|
|
||||||
def reload(m): print('Unsupported Python version - not reloading %s' % str(m))
|
|
||||||
reload(sys.modules['dumper'])
|
reload(sys.modules['dumper'])
|
||||||
|
|
||||||
from dumper import DumperBase, SubItem, Children, TopLevelItem
|
from dumper import DumperBase, SubItem, Children, TopLevelItem
|
||||||
@@ -34,16 +30,10 @@ from dumper import DumperBase, SubItem, Children, TopLevelItem
|
|||||||
#######################################################################
|
#######################################################################
|
||||||
|
|
||||||
qqWatchpointOffset = 10000
|
qqWatchpointOffset = 10000
|
||||||
_c_str_trans = None
|
|
||||||
|
|
||||||
if sys.version_info[0] >= 3:
|
|
||||||
_c_str_trans = str.maketrans({"\n": "\\n", '"':'\\"', "\\":"\\\\"})
|
_c_str_trans = str.maketrans({"\n": "\\n", '"':'\\"', "\\":"\\\\"})
|
||||||
|
|
||||||
def toCString(s):
|
def toCString(s):
|
||||||
if _c_str_trans is not None:
|
|
||||||
return str(s).translate(_c_str_trans)
|
return str(s).translate(_c_str_trans)
|
||||||
else:
|
|
||||||
return str(s).replace('\\', '\\\\').replace('\n', '\\n').replace('"', '\\"')
|
|
||||||
|
|
||||||
def fileNameAsString(file):
|
def fileNameAsString(file):
|
||||||
return toCString(file) if file.IsValid() else ''
|
return toCString(file) if file.IsValid() else ''
|
||||||
@@ -783,6 +773,54 @@ class Dumper(DumperBase):
|
|||||||
|
|
||||||
self.fetchInternalFunctions = lambda: None
|
self.fetchInternalFunctions = lambda: None
|
||||||
|
|
||||||
|
def extractQtVersion(self):
|
||||||
|
for func in self.target.FindFunctions('qVersion'):
|
||||||
|
name = func.GetSymbol().GetName()
|
||||||
|
if name == None:
|
||||||
|
continue
|
||||||
|
if name.endswith('()'):
|
||||||
|
name = name[:-2]
|
||||||
|
if name.count(':') > 2:
|
||||||
|
continue
|
||||||
|
|
||||||
|
#qtNamespace = name[:name.find('qVersion')]
|
||||||
|
#self.qtNamespace = lambda: qtNamespace
|
||||||
|
|
||||||
|
options = lldb.SBExpressionOptions()
|
||||||
|
res = self.target.EvaluateExpression(name + '()', options)
|
||||||
|
|
||||||
|
if not res.IsValid() or not res.GetType().IsPointerType():
|
||||||
|
exp = '((const char*())%s)()' % name
|
||||||
|
res = self.target.EvaluateExpression(exp, options)
|
||||||
|
|
||||||
|
if not res.IsValid() or not res.GetType().IsPointerType():
|
||||||
|
exp = '((const char*())_Z8qVersionv)()'
|
||||||
|
res = self.target.EvaluateExpression(exp, options)
|
||||||
|
|
||||||
|
if not res.IsValid() or not res.GetType().IsPointerType():
|
||||||
|
continue
|
||||||
|
|
||||||
|
version = str(res)
|
||||||
|
if version.count('.') != 2:
|
||||||
|
continue
|
||||||
|
|
||||||
|
version.replace("'", '"') # Both seem possible
|
||||||
|
version = version[version.find('"') + 1:version.rfind('"')]
|
||||||
|
|
||||||
|
(major, minor, patch) = version.split('.')
|
||||||
|
qtVersion = 0x10000 * int(major) + 0x100 * int(minor) + int(patch)
|
||||||
|
return qtVersion
|
||||||
|
|
||||||
|
try:
|
||||||
|
versionValue = self.target.EvaluateExpression('qtHookData[2]').GetNonSyntheticValue()
|
||||||
|
if versionValue.IsValid():
|
||||||
|
return versionValue.unsigned
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def handleCommand(self, command):
|
def handleCommand(self, command):
|
||||||
result = lldb.SBCommandReturnObject()
|
result = lldb.SBCommandReturnObject()
|
||||||
self.debugger.GetCommandInterpreter().HandleCommand(command, result)
|
self.debugger.GetCommandInterpreter().HandleCommand(command, result)
|
||||||
@@ -2312,9 +2350,6 @@ class SummaryProvider(LogMixin):
|
|||||||
if encoding in text_encodings:
|
if encoding in text_encodings:
|
||||||
try:
|
try:
|
||||||
decodedValue = Dumper.hexdecode(summaryValue, encoding)
|
decodedValue = Dumper.hexdecode(summaryValue, encoding)
|
||||||
# LLDB expects UTF-8 for python 2
|
|
||||||
if sys.version_info[0] < 3:
|
|
||||||
return "\"%s\"" % (decodedValue.encode('utf8'))
|
|
||||||
return '"' + decodedValue + '"'
|
return '"' + decodedValue + '"'
|
||||||
except:
|
except:
|
||||||
return "<failed to decode '%s' as '%s': %s>" % (summaryValue, encoding, sys.exc_info()[1])
|
return "<failed to decode '%s' as '%s': %s>" % (summaryValue, encoding, sys.exc_info()[1])
|
||||||
|
@@ -33,7 +33,8 @@ def qedit__QByteArray(d, value, data):
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QByteArray(d, value):
|
def qdump__QByteArray(d, value):
|
||||||
if d.qtVersion() >= 0x60000:
|
d.qtVersionPing(value.typeid)
|
||||||
|
if d.qtVersionAtLeast(0x060000):
|
||||||
dd, data, length = value.split('ppi')
|
dd, data, length = value.split('ppi')
|
||||||
if dd:
|
if dd:
|
||||||
_, _, alloc = d.split('iii', dd)
|
_, _, alloc = d.split('iii', dd)
|
||||||
@@ -76,7 +77,8 @@ def qdump__QByteArray(d, value):
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QBitArray(d, value):
|
def qdump__QBitArray(d, value):
|
||||||
if d.qtVersion() >= 0x60000:
|
d.qtVersionPing(value.typeid)
|
||||||
|
if d.qtVersionAtLeast(0x060000):
|
||||||
_, data, basize = value.split('ppi')
|
_, data, basize = value.split('ppi')
|
||||||
else:
|
else:
|
||||||
data, basize, _ = d.qArrayData(value['d'])
|
data, basize, _ = d.qArrayData(value['d'])
|
||||||
@@ -232,13 +234,13 @@ def qdump__QStandardItem(d, value):
|
|||||||
#d.createType('@QStandardItem*')
|
#d.createType('@QStandardItem*')
|
||||||
|
|
||||||
vtable, dptr = value.split('pp')
|
vtable, dptr = value.split('pp')
|
||||||
if d.qtVersion() >= 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
model, parent, values, children, rows, cols, item = \
|
model, parent, values, children, rows, cols, item = \
|
||||||
d.split('pp{@QList<@QStandardItemData>}{@QList<@QStandardItem *>}IIp', dptr)
|
d.split('pp{@QList<@QStandardItemData>}{@QList<@QStandardItem *>}IIp', dptr)
|
||||||
else:
|
else:
|
||||||
# There used to be a virtual destructor that got removed in
|
# There used to be a virtual destructor that got removed in
|
||||||
# 88b6abcebf29b455438 on Apr 18 17:01:22 2017
|
# 88b6abcebf29b455438 on Apr 18 17:01:22 2017
|
||||||
if d.qtVersion() < 0x050900 and not d.isMsvcTarget():
|
if not d.qtVersionAtLeast(0x050900) and not d.isMsvcTarget():
|
||||||
dptr += d.ptrSize();
|
dptr += d.ptrSize();
|
||||||
model, parent, values, children, rows, cols, item = \
|
model, parent, values, children, rows, cols, item = \
|
||||||
d.split('pp{@QVector<@QStandardItemData>}{@QVector<@QStandardItem *>}IIp', dptr)
|
d.split('pp{@QVector<@QStandardItemData>}{@QVector<@QStandardItem *>}IIp', dptr)
|
||||||
@@ -266,7 +268,7 @@ def qdump__QDate(d, value):
|
|||||||
d.enumExpression('DateFormat', 'TextDate'))
|
d.enumExpression('DateFormat', 'TextDate'))
|
||||||
d.putCallItem('(ISO)', '@QString', value, 'toString',
|
d.putCallItem('(ISO)', '@QString', value, 'toString',
|
||||||
d.enumExpression('DateFormat', 'ISODate'))
|
d.enumExpression('DateFormat', 'ISODate'))
|
||||||
if d.qtVersion() < 0x060000:
|
if not d.qtVersionAtLeast(0x060000):
|
||||||
d.putCallItem('(SystemLocale)', '@QString', value, 'toString',
|
d.putCallItem('(SystemLocale)', '@QString', value, 'toString',
|
||||||
d.enumExpression('DateFormat', 'SystemLocaleDate'))
|
d.enumExpression('DateFormat', 'SystemLocaleDate'))
|
||||||
d.putCallItem('(Locale)', '@QString', value, 'toString',
|
d.putCallItem('(Locale)', '@QString', value, 'toString',
|
||||||
@@ -286,7 +288,7 @@ def qdump__QTime(d, value):
|
|||||||
d.enumExpression('DateFormat', 'TextDate'))
|
d.enumExpression('DateFormat', 'TextDate'))
|
||||||
d.putCallItem('(ISO)', '@QString', value, 'toString',
|
d.putCallItem('(ISO)', '@QString', value, 'toString',
|
||||||
d.enumExpression('DateFormat', 'ISODate'))
|
d.enumExpression('DateFormat', 'ISODate'))
|
||||||
if d.canCallLocale() and d.qtVersion() < 0x060000:
|
if d.canCallLocale() and not d.qtVersionAtLeast(0x060000):
|
||||||
d.putCallItem('(SystemLocale)', '@QString', value, 'toString',
|
d.putCallItem('(SystemLocale)', '@QString', value, 'toString',
|
||||||
d.enumExpression('DateFormat', 'SystemLocaleDate'))
|
d.enumExpression('DateFormat', 'SystemLocaleDate'))
|
||||||
d.putCallItem('(Locale)', '@QString', value, 'toString',
|
d.putCallItem('(Locale)', '@QString', value, 'toString',
|
||||||
@@ -305,13 +307,12 @@ def qdump__QTimeZone(d, value):
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QDateTime(d, value):
|
def qdump__QDateTime(d, value):
|
||||||
qtVersion = d.qtVersion()
|
|
||||||
isValid = False
|
isValid = False
|
||||||
# This relies on the Qt4/Qt5 internal structure layout:
|
# This relies on the Qt4/Qt5 internal structure layout:
|
||||||
# {sharedref(4), ...
|
# {sharedref(4), ...
|
||||||
base = d.extractPointer(value)
|
base = d.extractPointer(value)
|
||||||
is32bit = d.ptrSize() == 4
|
is32bit = d.ptrSize() == 4
|
||||||
if qtVersion >= 0x050200:
|
if d.qtVersionAtLeast(0x050200):
|
||||||
tiVersion = d.qtTypeInfoVersion()
|
tiVersion = d.qtTypeInfoVersion()
|
||||||
#DumperBase.warn('TI VERSION: %s' % tiVersion)
|
#DumperBase.warn('TI VERSION: %s' % tiVersion)
|
||||||
if tiVersion is None:
|
if tiVersion is None:
|
||||||
@@ -384,9 +385,9 @@ def qdump__QDateTime(d, value):
|
|||||||
# - [QTime time;]
|
# - [QTime time;]
|
||||||
# - - uint mds;
|
# - - uint mds;
|
||||||
# - Spec spec;
|
# - Spec spec;
|
||||||
dateSize = 8 if qtVersion >= 0x050000 else 4 # Qt5: qint64, Qt4 uint
|
dateSize = 8 if qtVersionAtLeast(0x050000) else 4 # Qt5: qint64, Qt4 uint
|
||||||
# 4 byte padding after 4 byte QAtomicInt if we are on 64 bit and QDate is 64 bit
|
# 4 byte padding after 4 byte QAtomicInt if we are on 64 bit and QDate is 64 bit
|
||||||
refPlusPadding = 8 if qtVersion >= 0x050000 and d.ptrSize() == 8 else 4
|
refPlusPadding = 8 if qtVersionAtLeast(0x050000) and d.ptrSize() == 8 else 4
|
||||||
dateBase = base + refPlusPadding
|
dateBase = base + refPlusPadding
|
||||||
timeBase = dateBase + dateSize
|
timeBase = dateBase + dateSize
|
||||||
mds = d.extractInt(timeBase)
|
mds = d.extractInt(timeBase)
|
||||||
@@ -410,7 +411,7 @@ def qdump__QDateTime(d, value):
|
|||||||
d.enumExpression('DateFormat', 'ISODate'))
|
d.enumExpression('DateFormat', 'ISODate'))
|
||||||
d.putCallItem('toUTC', '@QDateTime', value, 'toTimeSpec',
|
d.putCallItem('toUTC', '@QDateTime', value, 'toTimeSpec',
|
||||||
d.enumExpression('TimeSpec', 'UTC'))
|
d.enumExpression('TimeSpec', 'UTC'))
|
||||||
if d.qtVersion() < 0x060000:
|
if not d.qtVersionAtLeast(0x060000):
|
||||||
d.putCallItem('(SystemLocale)', '@QString', value, 'toString',
|
d.putCallItem('(SystemLocale)', '@QString', value, 'toString',
|
||||||
d.enumExpression('DateFormat', 'SystemLocaleDate'))
|
d.enumExpression('DateFormat', 'SystemLocaleDate'))
|
||||||
d.putCallItem('(Locale)', '@QString', value, 'toString',
|
d.putCallItem('(Locale)', '@QString', value, 'toString',
|
||||||
@@ -756,7 +757,6 @@ def qdump__QFile(d, value):
|
|||||||
def qdump__QFileInfo(d, value):
|
def qdump__QFileInfo(d, value):
|
||||||
privAddress = d.extractPointer(value)
|
privAddress = d.extractPointer(value)
|
||||||
#bit32 = d.ptrSize() == 4
|
#bit32 = d.ptrSize() == 4
|
||||||
#qt5 = d.qtVersion() >= 0x050000
|
|
||||||
#try:
|
#try:
|
||||||
# d.putStringValue(value['d_ptr']['d'].dereference()['fileNames'][3])
|
# d.putStringValue(value['d_ptr']['d'].dereference()['fileNames'][3])
|
||||||
#except:
|
#except:
|
||||||
@@ -876,7 +876,7 @@ def qdump__QVariantHash(d, value):
|
|||||||
|
|
||||||
|
|
||||||
def qdumpHelper_QHash(d, value, keyType, valueType):
|
def qdumpHelper_QHash(d, value, keyType, valueType):
|
||||||
if d.qtVersion() >= 0x60000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
qdumpHelper_QHash_6(d, value, keyType, valueType)
|
qdumpHelper_QHash_6(d, value, keyType, valueType)
|
||||||
else:
|
else:
|
||||||
qdumpHelper_QHash_5(d, value, keyType, valueType)
|
qdumpHelper_QHash_5(d, value, keyType, valueType)
|
||||||
@@ -918,7 +918,7 @@ def qdumpHelper_QHash_5(d, value, keyType, valueType):
|
|||||||
|
|
||||||
d.putItemCount(size)
|
d.putItemCount(size)
|
||||||
if d.isExpanded():
|
if d.isExpanded():
|
||||||
isShort = d.qtVersion() < 0x050000 and keyType.name == 'int'
|
isShort = not d.qtVersionAtLeast(0x050000) and keyType.name == 'int'
|
||||||
with Children(d, size):
|
with Children(d, size):
|
||||||
node = hashDataFirstNode()
|
node = hashDataFirstNode()
|
||||||
for i in d.childRange():
|
for i in d.childRange():
|
||||||
@@ -994,7 +994,7 @@ def qHashIteratorHelper(d, value):
|
|||||||
if d.isExpanded():
|
if d.isExpanded():
|
||||||
with Children(d):
|
with Children(d):
|
||||||
node = d.extractPointer(value)
|
node = d.extractPointer(value)
|
||||||
isShort = d.qtVersion() < 0x050000 and keyType.name == 'int'
|
isShort = not d.qtVersionAtLeast(0x050000) and keyType.name == 'int'
|
||||||
if isShort:
|
if isShort:
|
||||||
typeCode = 'P{%s}@{%s}' % (keyType.name, valueType.name)
|
typeCode = 'P{%s}@{%s}' % (keyType.name, valueType.name)
|
||||||
(pnext, key, padding2, val) = d.split(typeCode, node)
|
(pnext, key, padding2, val) = d.split(typeCode, node)
|
||||||
@@ -1015,9 +1015,8 @@ def qdump__QHash__iterator(d, value):
|
|||||||
|
|
||||||
def qdump__QHostAddress(d, value):
|
def qdump__QHostAddress(d, value):
|
||||||
dd = d.extractPointer(value)
|
dd = d.extractPointer(value)
|
||||||
qtVersion = d.qtVersion()
|
|
||||||
tiVersion = d.qtTypeInfoVersion()
|
tiVersion = d.qtTypeInfoVersion()
|
||||||
#DumperBase.warn('QT: %x, TI: %s' % (qtVersion, tiVersion))
|
#DumperBase.warn('QT: %x, TI: %s' % (d.qtVersion(), tiVersion))
|
||||||
mayNeedParse = True
|
mayNeedParse = True
|
||||||
if tiVersion is not None:
|
if tiVersion is not None:
|
||||||
if tiVersion >= 16:
|
if tiVersion >= 16:
|
||||||
@@ -1032,14 +1031,14 @@ def qdump__QHostAddress(d, value):
|
|||||||
else:
|
else:
|
||||||
(ipString, scopeId, a4, pad, a6, protocol, isParsed) \
|
(ipString, scopeId, a4, pad, a6, protocol, isParsed) \
|
||||||
= d.split('{@QString}{@QString}{@quint32}I16sI{bool}', dd)
|
= d.split('{@QString}{@QString}{@quint32}I16sI{bool}', dd)
|
||||||
elif qtVersion >= 0x050600: # 5.6.0 at f3aabb42
|
elif qtVersionAtLeast(0x050600): # 5.6.0 at f3aabb42
|
||||||
if d.ptrSize() == 8 or d.isWindowsTarget():
|
if d.ptrSize() == 8 or d.isWindowsTarget():
|
||||||
(ipString, scopeId, a4, pad, a6, protocol, isParsed) \
|
(ipString, scopeId, a4, pad, a6, protocol, isParsed) \
|
||||||
= d.split('{@QString}{@QString}{@quint32}I16sI{bool}', dd)
|
= d.split('{@QString}{@QString}{@quint32}I16sI{bool}', dd)
|
||||||
else:
|
else:
|
||||||
(ipString, scopeId, a4, a6, protocol, isParsed) \
|
(ipString, scopeId, a4, a6, protocol, isParsed) \
|
||||||
= d.split('{@QString}{@QString}{@quint32}16sI{bool}', dd)
|
= d.split('{@QString}{@QString}{@quint32}16sI{bool}', dd)
|
||||||
elif qtVersion >= 0x050000: # 5.2.0 at 62feb088
|
elif qtVersionAtLeast(0x050000): # 5.2.0 at 62feb088
|
||||||
(ipString, scopeId, a4, a6, protocol, isParsed) \
|
(ipString, scopeId, a4, a6, protocol, isParsed) \
|
||||||
= d.split('{@QString}{@QString}{@quint32}16sI{bool}', dd)
|
= d.split('{@QString}{@QString}{@quint32}16sI{bool}', dd)
|
||||||
else: # 4.8.7 at b05d05f
|
else: # 4.8.7 at b05d05f
|
||||||
@@ -1104,7 +1103,8 @@ def qdumpHelper_QList(d, value, inner_typish):
|
|||||||
data, size = d.listData(value, check=True)
|
data, size = d.listData(value, check=True)
|
||||||
d.putItemCount(size)
|
d.putItemCount(size)
|
||||||
|
|
||||||
if d.qtVersion() >= 0x60000:
|
d.qtVersionPing(value.typeid)
|
||||||
|
if d.qtVersionAtLeast(0x060000):
|
||||||
d.putPlotData(data, size, innerType)
|
d.putPlotData(data, size, innerType)
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1145,9 +1145,9 @@ def qform__QImage():
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QImage(d, value):
|
def qdump__QImage(d, value):
|
||||||
if d.qtVersion() >= 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
vtbl, painters, image_data = value.split('ppp')
|
vtbl, painters, image_data = value.split('ppp')
|
||||||
elif d.qtVersion() >= 0x050000:
|
elif d.qtVersionAtLeast(0x050000):
|
||||||
vtbl, painters, reserved, image_data = value.split('pppp')
|
vtbl, painters, reserved, image_data = value.split('pppp')
|
||||||
else:
|
else:
|
||||||
vtbl, painters, image_data = value.split('ppp')
|
vtbl, painters, image_data = value.split('ppp')
|
||||||
@@ -1161,12 +1161,12 @@ def qdump__QImage(d, value):
|
|||||||
|
|
||||||
d.putExpandable()
|
d.putExpandable()
|
||||||
if d.isExpanded():
|
if d.isExpanded():
|
||||||
if d.qtVersion() < 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
(ref, width, height, depth, nbytes, pad, devicePixelRatio, colorTable,
|
|
||||||
bits, iformat) = d.split('iiiii@dppi', image_data)
|
|
||||||
else:
|
|
||||||
(ref, width, height, depth, nbytes, pad, devicePixelRatio, _, _, _,
|
(ref, width, height, depth, nbytes, pad, devicePixelRatio, _, _, _,
|
||||||
bits, iformat) = d.split('iiiii@dppppi', image_data)
|
bits, iformat) = d.split('iiiii@dppppi', image_data)
|
||||||
|
else:
|
||||||
|
(ref, width, height, depth, nbytes, pad, devicePixelRatio, colorTable,
|
||||||
|
bits, iformat) = d.split('iiiii@dppi', image_data)
|
||||||
with Children(d):
|
with Children(d):
|
||||||
d.putIntItem('width', width)
|
d.putIntItem('width', width)
|
||||||
d.putIntItem('height', height)
|
d.putIntItem('height', height)
|
||||||
@@ -1222,8 +1222,7 @@ def qdump__QLocale(d, value):
|
|||||||
# index = int(value['d']['d']['m_data']...)
|
# index = int(value['d']['d']['m_data']...)
|
||||||
#d.check(index >= 0)
|
#d.check(index >= 0)
|
||||||
#d.check(index <= qqLocalesCount)
|
#d.check(index <= qqLocalesCount)
|
||||||
qtVersion = d.qtVersion()
|
if not d.qtVersionAtLeast(0x50000):
|
||||||
if qtVersion < 0x50000:
|
|
||||||
d.putStringValue(d.call('const char *', value, 'name'))
|
d.putStringValue(d.call('const char *', value, 'name'))
|
||||||
d.putPlainChildren(value)
|
d.putPlainChildren(value)
|
||||||
return
|
return
|
||||||
@@ -1240,7 +1239,7 @@ def qdump__QLocale(d, value):
|
|||||||
|
|
||||||
prefix = ns + 'QLocale::'
|
prefix = ns + 'QLocale::'
|
||||||
try:
|
try:
|
||||||
if qtVersion >= 0x060700:
|
if qtVersionAtLeast(0x060700):
|
||||||
res = d.call('const char *', value, 'name', prefix + 'TagSeparator::Underscore')
|
res = d.call('const char *', value, 'name', prefix + 'TagSeparator::Underscore')
|
||||||
else:
|
else:
|
||||||
res = d.call('const char *', value, 'name')
|
res = d.call('const char *', value, 'name')
|
||||||
@@ -1347,9 +1346,9 @@ def qdump__QMap(d, value):
|
|||||||
|
|
||||||
|
|
||||||
def qdumpHelper_QMap(d, value, keyType, valueType):
|
def qdumpHelper_QMap(d, value, keyType, valueType):
|
||||||
if d.qtVersion() >= 0x60000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
qdumpHelper_Qt6_QMap(d, value, keyType, valueType)
|
qdumpHelper_Qt6_QMap(d, value, keyType, valueType)
|
||||||
elif d.qtVersion() >= 0x50000:
|
elif d.qtVersionAtLeast(0x50000):
|
||||||
qdumpHelper_Qt5_QMap(d, value, keyType, valueType)
|
qdumpHelper_Qt5_QMap(d, value, keyType, valueType)
|
||||||
else:
|
else:
|
||||||
qdumpHelper_Qt4_QMap(d, value, keyType, valueType)
|
qdumpHelper_Qt4_QMap(d, value, keyType, valueType)
|
||||||
@@ -1369,7 +1368,7 @@ def qdumpHelper_Qt6_QMultiMap(d, value, keyType, valueType):
|
|||||||
d.putBetterType('@QMultiMap<%s, %s>' % (keyType.name, valueType.name))
|
d.putBetterType('@QMultiMap<%s, %s>' % (keyType.name, valueType.name))
|
||||||
|
|
||||||
def qdump__QMultiMap(d, value):
|
def qdump__QMultiMap(d, value):
|
||||||
if d.qtVersion() >= 0x60000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
qdumpHelper_Qt6_QMultiMap(d, value, value.type[0], value.type[1])
|
qdumpHelper_Qt6_QMultiMap(d, value, value.type[0], value.type[1])
|
||||||
else:
|
else:
|
||||||
qdump__QMap(d, value)
|
qdump__QMap(d, value)
|
||||||
@@ -1449,9 +1448,9 @@ def qdump__QProcEnvKey(d, value):
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QPixmap(d, value):
|
def qdump__QPixmap(d, value):
|
||||||
if d.qtVersion() >= 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
vtbl, painters, data = value.split('ppp')
|
vtbl, painters, data = value.split('ppp')
|
||||||
elif d.qtVersion() >= 0x050000:
|
elif d.qtVersionAtLeast(0x050000):
|
||||||
vtbl, painters, reserved, data = s = d.split('pppp', value)
|
vtbl, painters, reserved, data = s = d.split('pppp', value)
|
||||||
else:
|
else:
|
||||||
vtbl, painters, data = value.split('ppp')
|
vtbl, painters, data = value.split('ppp')
|
||||||
@@ -1518,15 +1517,15 @@ def qdump__QRegion(d, value):
|
|||||||
if d_ptr == 0:
|
if d_ptr == 0:
|
||||||
d.putSpecialValue('empty')
|
d.putSpecialValue('empty')
|
||||||
else:
|
else:
|
||||||
if d.qtVersion() >= 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
ref, _, rgn = d.split('i@p', d_ptr)
|
ref, _, rgn = d.split('i@p', d_ptr)
|
||||||
numRects, innerArea, rects, extents, innerRect = \
|
numRects, innerArea, rects, extents, innerRect = \
|
||||||
d.split('ii{@QList<@QRect>}{@QRect}{@QRect}', rgn)
|
d.split('ii{@QList<@QRect>}{@QRect}{@QRect}', rgn)
|
||||||
elif d.qtVersion() >= 0x050400: # Padding removed in ee324e4ed
|
elif d.qtVersionAtLeast(0x050400): # Padding removed in ee324e4ed
|
||||||
ref, _, rgn = d.split('i@p', d_ptr)
|
ref, _, rgn = d.split('i@p', d_ptr)
|
||||||
numRects, innerArea, rects, extents, innerRect = \
|
numRects, innerArea, rects, extents, innerRect = \
|
||||||
d.split('ii{@QVector<@QRect>}{@QRect}{@QRect}', rgn)
|
d.split('ii{@QVector<@QRect>}{@QRect}{@QRect}', rgn)
|
||||||
elif d.qtVersion() >= 0x050000:
|
elif d.qtVersionAtLeast(0x050000):
|
||||||
ref, _, rgn = d.split('i@p', d_ptr)
|
ref, _, rgn = d.split('i@p', d_ptr)
|
||||||
numRects, _, rects, extents, innerRect, innerArea = \
|
numRects, _, rects, extents, innerRect, innerArea = \
|
||||||
d.split('i@{@QVector<@QRect>}{@QRect}{@QRect}i', rgn)
|
d.split('i@{@QVector<@QRect>}{@QRect}{@QRect}i', rgn)
|
||||||
@@ -1564,7 +1563,7 @@ def qdump__QScopedPointer(d, value):
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QSet(d, value):
|
def qdump__QSet(d, value):
|
||||||
if d.qtVersion() >= 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
qdumpHelper_QSet6(d, value)
|
qdumpHelper_QSet6(d, value)
|
||||||
else:
|
else:
|
||||||
qdumpHelper_QSet45(d, value)
|
qdumpHelper_QSet45(d, value)
|
||||||
@@ -1637,7 +1636,7 @@ def qdumpHelper_QSet45(d, value):
|
|||||||
d.putItemCount(length)
|
d.putItemCount(length)
|
||||||
if d.isExpanded():
|
if d.isExpanded():
|
||||||
keyType = value.type[0]
|
keyType = value.type[0]
|
||||||
isShort = d.qtVersion() < 0x050000 and keyType.name == 'int'
|
isShort = not d.qtVersionAtLeast(0x050000) and keyType.name == 'int'
|
||||||
with Children(d, length, childType=keyType):
|
with Children(d, length, childType=keyType):
|
||||||
node = hashDataFirstNode()
|
node = hashDataFirstNode()
|
||||||
for i in d.childRange():
|
for i in d.childRange():
|
||||||
@@ -1714,7 +1713,7 @@ def qform__QStack():
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QStack(d, value):
|
def qdump__QStack(d, value):
|
||||||
if d.qtVersion() >= 0x60000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
qdump__QList(d, value)
|
qdump__QList(d, value)
|
||||||
else:
|
else:
|
||||||
qdump__QVector(d, value)
|
qdump__QVector(d, value)
|
||||||
@@ -1734,7 +1733,7 @@ def qdump__QPolygon(d, value):
|
|||||||
|
|
||||||
def qdump__QGraphicsPolygonItem(d, value):
|
def qdump__QGraphicsPolygonItem(d, value):
|
||||||
(vtbl, dptr) = value.split('pp')
|
(vtbl, dptr) = value.split('pp')
|
||||||
if d.qtVersion() >= 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
if d.ptrSize() == 8:
|
if d.ptrSize() == 8:
|
||||||
offset = 424 # sizeof(QGraphicsPolygonItemPrivate), the base
|
offset = 424 # sizeof(QGraphicsPolygonItemPrivate), the base
|
||||||
else:
|
else:
|
||||||
@@ -1764,6 +1763,7 @@ def qform__QString():
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QString(d, value):
|
def qdump__QString(d, value):
|
||||||
|
d.qtVersionPing(value.typeid)
|
||||||
d.putStringValue(value)
|
d.putStringValue(value)
|
||||||
data, length, _ = d.stringData(value)
|
data, length, _ = d.stringData(value)
|
||||||
displayFormat = d.currentItemFormat()
|
displayFormat = d.currentItemFormat()
|
||||||
@@ -1924,7 +1924,7 @@ def qdump__QUrl(d, value):
|
|||||||
d.putValue('<invalid>')
|
d.putValue('<invalid>')
|
||||||
return
|
return
|
||||||
|
|
||||||
if d.qtVersion() < 0x050000:
|
if not d.qtVersionAtLeast(0x050000):
|
||||||
d.call('void', value, 'port') # Warm up internal cache.
|
d.call('void', value, 'port') # Warm up internal cache.
|
||||||
d.call('void', value, 'path')
|
d.call('void', value, 'path')
|
||||||
st = '{@QString}'
|
st = '{@QString}'
|
||||||
@@ -2154,7 +2154,8 @@ qdumpHelper_QVariants_F = [
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QVariant(d, value):
|
def qdump__QVariant(d, value):
|
||||||
if d.qtVersion() >= 0x060000:
|
d.qtVersionPing(value.typeid, 2 * d.ptrSize())
|
||||||
|
if d.qtVersionAtLeast(0x060000):
|
||||||
qdumpHelper__QVariant6(d, value)
|
qdumpHelper__QVariant6(d, value)
|
||||||
else:
|
else:
|
||||||
qdumpHelper__QVariant45(d, value)
|
qdumpHelper__QVariant45(d, value)
|
||||||
@@ -2208,12 +2209,12 @@ def qdumpHelper__QVariant45(d, value):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
# Extended Core type (Qt 5)
|
# Extended Core type (Qt 5)
|
||||||
if variantType >= 31 and variantType <= 38 and d.qtVersion() >= 0x050000:
|
if variantType >= 31 and variantType <= 38 and d.qtVersionAtLeast(0x050000):
|
||||||
qdumpHelper_QVariants_D[variantType - 31](d, value)
|
qdumpHelper_QVariants_D[variantType - 31](d, value)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Extended Core type (Qt 4)
|
# Extended Core type (Qt 4)
|
||||||
if variantType >= 128 and variantType <= 135 and d.qtVersion() < 0x050000:
|
if variantType >= 128 and variantType <= 135 and not d.qtVersionAtLeast(0x050000):
|
||||||
if variantType == 128:
|
if variantType == 128:
|
||||||
d.putBetterType('@QVariant (void *)')
|
d.putBetterType('@QVariant (void *)')
|
||||||
d.putValue('0x%x' % value.extractPointer())
|
d.putValue('0x%x' % value.extractPointer())
|
||||||
@@ -2234,7 +2235,7 @@ def qdumpHelper__QVariant45(d, value):
|
|||||||
innert = qdumpHelper_QVariants_B[variantType - 7]
|
innert = qdumpHelper_QVariants_B[variantType - 7]
|
||||||
elif variantType <= 74:
|
elif variantType <= 74:
|
||||||
innert = qdumpHelper_QVariants_E[variantType - 64]
|
innert = qdumpHelper_QVariants_E[variantType - 64]
|
||||||
elif d.qtVersion() < 0x050000:
|
elif not d.qtVersionAtLeast(0x050000):
|
||||||
innert = qdumpHelper_QVariants_F[variantType - 76]
|
innert = qdumpHelper_QVariants_F[variantType - 76]
|
||||||
else:
|
else:
|
||||||
innert = qdumpHelper_QVariants_F[variantType - 75]
|
innert = qdumpHelper_QVariants_F[variantType - 75]
|
||||||
@@ -2308,7 +2309,8 @@ def qform__QVector():
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QVector(d, value):
|
def qdump__QVector(d, value):
|
||||||
if d.qtVersion() >= 0x060000:
|
d.qtVersionPing(value.typeid)
|
||||||
|
if d.qtVersionAtLeast(0x060000):
|
||||||
data, length = d.listData(value)
|
data, length = d.listData(value)
|
||||||
d.putItemCount(length)
|
d.putItemCount(length)
|
||||||
d.putPlotData(data, length, value.type.target()[0])
|
d.putPlotData(data, length, value.type.target()[0])
|
||||||
@@ -2330,7 +2332,7 @@ if False:
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QVarLengthArray(d, value):
|
def qdump__QVarLengthArray(d, value):
|
||||||
if d.qtVersion() >= 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
cap, length, data = value.split('QQp')
|
cap, length, data = value.split('QQp')
|
||||||
else:
|
else:
|
||||||
cap, length, data = value.split('iip')
|
cap, length, data = value.split('iip')
|
||||||
@@ -2366,7 +2368,7 @@ def qdump_QWeakPointerHelper(d, value, isWeak, innerType=None):
|
|||||||
d.putValue('<invalid>')
|
d.putValue('<invalid>')
|
||||||
return
|
return
|
||||||
|
|
||||||
if d.qtVersion() >= 0x050000:
|
if d.qtVersionAtLeast(0x050000):
|
||||||
(weakref, strongref) = d.split('ii', d_ptr)
|
(weakref, strongref) = d.split('ii', d_ptr)
|
||||||
else:
|
else:
|
||||||
(vptr, weakref, strongref) = d.split('pii', d_ptr)
|
(vptr, weakref, strongref) = d.split('pii', d_ptr)
|
||||||
@@ -2872,7 +2874,7 @@ def qdump__QJSValue(d, value):
|
|||||||
if d.ptrSize() == 4:
|
if d.ptrSize() == 4:
|
||||||
qdump_32__QJSValue(d, value)
|
qdump_32__QJSValue(d, value)
|
||||||
else:
|
else:
|
||||||
if d.qtVersion() >= 0x60000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
qdump_64__QJSValue_6(d, value)
|
qdump_64__QJSValue_6(d, value)
|
||||||
else:
|
else:
|
||||||
qdump_64__QJSValue_5(d, value)
|
qdump_64__QJSValue_5(d, value)
|
||||||
@@ -2906,7 +2908,7 @@ def qdump_64__QJSValue_6(d, value):
|
|||||||
if dd == 0:
|
if dd == 0:
|
||||||
d.putValue('(undefined)')
|
d.putValue('(undefined)')
|
||||||
d.putType(value.type.name + ' (undefined)')
|
d.putType(value.type.name + ' (undefined)')
|
||||||
if d.qtVersion() < 0x60500:
|
if not d.qtVersionAtLeast(0x60500):
|
||||||
typ = dd >> 47
|
typ = dd >> 47
|
||||||
if typ == 5:
|
if typ == 5:
|
||||||
d.putValue('(null)')
|
d.putValue('(null)')
|
||||||
@@ -3326,7 +3328,7 @@ def qdumpHelper_QJsonObject(d, data, obj):
|
|||||||
def qdump__QJsonValue(d, value):
|
def qdump__QJsonValue(d, value):
|
||||||
(data, dd, t) = value.split('QpI')
|
(data, dd, t) = value.split('QpI')
|
||||||
|
|
||||||
if d.qtVersion() >= 0x050f00:
|
if d.qtVersionAtLeast(0x050f00):
|
||||||
value = d.createProxyValue((data, dd, t, False), 'QCborValue_proxy')
|
value = d.createProxyValue((data, dd, t, False), 'QCborValue_proxy')
|
||||||
d.putItem(value)
|
d.putItem(value)
|
||||||
return
|
return
|
||||||
@@ -3361,13 +3363,13 @@ def qdump__QJsonValue(d, value):
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QJsonArray(d, value):
|
def qdump__QJsonArray(d, value):
|
||||||
if d.qtVersion() >= 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
dptr = d.extractPointer(value)
|
dptr = d.extractPointer(value)
|
||||||
if not dptr:
|
if not dptr:
|
||||||
d.putItemCount(0)
|
d.putItemCount(0)
|
||||||
else:
|
else:
|
||||||
qdumpHelper_QCbor_array(d, dptr, False)
|
qdumpHelper_QCbor_array(d, dptr, False)
|
||||||
elif d.qtVersion() >= 0x050f00:
|
elif d.qtVersionAtLeast(0x050f00):
|
||||||
_, container_ptr = value.split('pp')
|
_, container_ptr = value.split('pp')
|
||||||
qdumpHelper_QCbor_array(d, container_ptr, False)
|
qdumpHelper_QCbor_array(d, container_ptr, False)
|
||||||
else:
|
else:
|
||||||
@@ -3375,13 +3377,13 @@ def qdump__QJsonArray(d, value):
|
|||||||
|
|
||||||
|
|
||||||
def qdump__QJsonObject(d, value):
|
def qdump__QJsonObject(d, value):
|
||||||
if d.qtVersion() >= 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
dptr = d.extractPointer(value)
|
dptr = d.extractPointer(value)
|
||||||
if not dptr:
|
if not dptr:
|
||||||
d.putItemCount(0)
|
d.putItemCount(0)
|
||||||
else:
|
else:
|
||||||
qdumpHelper_QCbor_map(d, dptr, False)
|
qdumpHelper_QCbor_map(d, dptr, False)
|
||||||
elif d.qtVersion() >= 0x050f00:
|
elif d.qtVersionAtLeast(0x050f00):
|
||||||
_, container_ptr = value.split('pp')
|
_, container_ptr = value.split('pp')
|
||||||
qdumpHelper_QCbor_map(d, container_ptr, False)
|
qdumpHelper_QCbor_map(d, container_ptr, False)
|
||||||
else:
|
else:
|
||||||
@@ -3456,15 +3458,15 @@ def qdump__qfloat16(d, value):
|
|||||||
def qdumpHelper_QCbor_string(d, container_ptr, element_index, is_bytes):
|
def qdumpHelper_QCbor_string(d, container_ptr, element_index, is_bytes):
|
||||||
# d.split('i@{@QByteArray::size_type}pp', container_ptr) doesn't work with CDB,
|
# d.split('i@{@QByteArray::size_type}pp', container_ptr) doesn't work with CDB,
|
||||||
# so be explicit:
|
# so be explicit:
|
||||||
data_pos = container_ptr + (2 * d.ptrSize() if d.qtVersion() >= 0x060000 else 8)
|
data_pos = container_ptr + (2 * d.ptrSize() if d.qtVersionAtLeast(0x060000) else 8)
|
||||||
elements_pos = data_pos + (3 * d.ptrSize() if d.qtVersion() >= 0x060000 else d.ptrSize())
|
elements_pos = data_pos + (3 * d.ptrSize() if d.qtVersionAtLeast(0x060000) else d.ptrSize())
|
||||||
elements_data_ptr, elements_size = d.vectorData(elements_pos)
|
elements_data_ptr, elements_size = d.vectorData(elements_pos)
|
||||||
element_at_n_addr = elements_data_ptr + element_index * 16 # sizeof(QtCbor::Element) == 16
|
element_at_n_addr = elements_data_ptr + element_index * 16 # sizeof(QtCbor::Element) == 16
|
||||||
element_value, _, element_flags = d.split('qII', element_at_n_addr)
|
element_value, _, element_flags = d.split('qII', element_at_n_addr)
|
||||||
enc = 'latin1' if is_bytes or (element_flags & 8) else 'utf16'
|
enc = 'latin1' if is_bytes or (element_flags & 8) else 'utf16'
|
||||||
bytedata, _, _ = d.qArrayData(data_pos)
|
bytedata, _, _ = d.qArrayData(data_pos)
|
||||||
bytedata += element_value
|
bytedata += element_value
|
||||||
if d.qtVersion() >= 0x060000:
|
if d.qtVersionAtLeast(0x060000):
|
||||||
bytedata_len = d.extractInt64(bytedata)
|
bytedata_len = d.extractInt64(bytedata)
|
||||||
bytedata_data = bytedata + 8
|
bytedata_data = bytedata + 8
|
||||||
else:
|
else:
|
||||||
@@ -3493,8 +3495,8 @@ def qdumpHelper_QCbor_array(d, container_ptr, is_cbor):
|
|||||||
return
|
return
|
||||||
# d.split('i@{@QByteArray::size_type}pp', container_ptr) doesn't work with CDB,
|
# d.split('i@{@QByteArray::size_type}pp', container_ptr) doesn't work with CDB,
|
||||||
# so be explicit:
|
# so be explicit:
|
||||||
data_pos = container_ptr + (2 * d.ptrSize() if d.qtVersion() >= 0x060000 else 8)
|
data_pos = container_ptr + (2 * d.ptrSize() if d.qtVersionAtLeast(0x060000) else 8)
|
||||||
elements_pos = data_pos + (3 * d.ptrSize() if d.qtVersion() >= 0x060000 else d.ptrSize())
|
elements_pos = data_pos + (3 * d.ptrSize() if d.qtVersionAtLeast(0x060000) else d.ptrSize())
|
||||||
elements_data_ptr, elements_size = d.vectorData(elements_pos)
|
elements_data_ptr, elements_size = d.vectorData(elements_pos)
|
||||||
d.putItemCount(elements_size)
|
d.putItemCount(elements_size)
|
||||||
if d.isExpanded():
|
if d.isExpanded():
|
||||||
@@ -3515,8 +3517,8 @@ def qdumpHelper_QCbor_map(d, container_ptr, is_cbor):
|
|||||||
return
|
return
|
||||||
# d.split('i@{@QByteArray::size_type}pp', container_ptr) doesn't work with CDB,
|
# d.split('i@{@QByteArray::size_type}pp', container_ptr) doesn't work with CDB,
|
||||||
# so be explicit:
|
# so be explicit:
|
||||||
data_pos = container_ptr + (2 * d.ptrSize() if d.qtVersion() >= 0x060000 else 8)
|
data_pos = container_ptr + (2 * d.ptrSize() if d.qtVersionAtLeast(0x060000) else 8)
|
||||||
elements_pos = data_pos + (3 * d.ptrSize() if d.qtVersion() >= 0x060000 else d.ptrSize())
|
elements_pos = data_pos + (3 * d.ptrSize() if d.qtVersionAtLeast(0x060000) else d.ptrSize())
|
||||||
elements_data_ptr, elements_size = d.vectorData(elements_pos)
|
elements_data_ptr, elements_size = d.vectorData(elements_pos)
|
||||||
elements_size = int(elements_size / 2)
|
elements_size = int(elements_size / 2)
|
||||||
d.putItemCount(elements_size)
|
d.putItemCount(elements_size)
|
||||||
|
@@ -844,11 +844,9 @@ Utils::expected_str<void> PluginSpecPrivate::readMetaData(const QJsonObject &dat
|
|||||||
value = metaData.value(QLatin1String(PLUGIN_DISABLED_BY_DEFAULT));
|
value = metaData.value(QLatin1String(PLUGIN_DISABLED_BY_DEFAULT));
|
||||||
if (!value.isUndefined() && !value.isBool())
|
if (!value.isUndefined() && !value.isBool())
|
||||||
return reportError(msgValueIsNotABool(PLUGIN_DISABLED_BY_DEFAULT));
|
return reportError(msgValueIsNotABool(PLUGIN_DISABLED_BY_DEFAULT));
|
||||||
enabledByDefault = !value.toBool(false);
|
enabledByDefault = !value.toBool(experimental || deprecated);
|
||||||
qCDebug(pluginLog) << "enabledByDefault =" << enabledByDefault;
|
qCDebug(pluginLog) << "enabledByDefault =" << enabledByDefault;
|
||||||
|
|
||||||
if (experimental || deprecated)
|
|
||||||
enabledByDefault = false;
|
|
||||||
enabledBySettings = enabledByDefault;
|
enabledBySettings = enabledByDefault;
|
||||||
|
|
||||||
value = metaData.value(QLatin1String(PLUGIN_SOFTLOADABLE));
|
value = metaData.value(QLatin1String(PLUGIN_SOFTLOADABLE));
|
||||||
|
@@ -261,6 +261,12 @@ DocumentHighlightsResult::DocumentHighlightsResult(const QJsonValue &value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
MarkedString fromJsonValue<MarkedString>(const QJsonValue &value)
|
||||||
|
{
|
||||||
|
return MarkedString(value);
|
||||||
|
}
|
||||||
|
|
||||||
MarkedString::MarkedString(const QJsonValue &value)
|
MarkedString::MarkedString(const QJsonValue &value)
|
||||||
{
|
{
|
||||||
if (value.isObject())
|
if (value.isObject())
|
||||||
|
@@ -52,6 +52,9 @@ public:
|
|||||||
operator QJsonValue() const;
|
operator QJsonValue() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
LANGUAGESERVERPROTOCOL_EXPORT MarkedString fromJsonValue<MarkedString>(const QJsonValue &value);
|
||||||
|
|
||||||
class LANGUAGESERVERPROTOCOL_EXPORT HoverContent
|
class LANGUAGESERVERPROTOCOL_EXPORT HoverContent
|
||||||
: public std::variant<MarkedString, QList<MarkedString>, MarkupContent>
|
: public std::variant<MarkedString, QList<MarkedString>, MarkupContent>
|
||||||
{
|
{
|
||||||
|
@@ -68,7 +68,7 @@ public:
|
|||||||
if (value.isArray()) {
|
if (value.isArray()) {
|
||||||
QList<T> values;
|
QList<T> values;
|
||||||
values.reserve(value.toArray().count());
|
values.reserve(value.toArray().count());
|
||||||
for (auto arrayValue : value.toArray())
|
for (const auto &arrayValue : value.toArray())
|
||||||
values << fromJsonValue<T>(arrayValue);
|
values << fromJsonValue<T>(arrayValue);
|
||||||
*this = values;
|
*this = values;
|
||||||
} else {
|
} else {
|
||||||
|
@@ -24,7 +24,7 @@ void Barrier::start()
|
|||||||
{
|
{
|
||||||
QT_ASSERT(!isRunning(), return);
|
QT_ASSERT(!isRunning(), return);
|
||||||
m_current = 0;
|
m_current = 0;
|
||||||
m_result = {};
|
m_result.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Barrier::advance()
|
void Barrier::advance()
|
||||||
|
@@ -1450,6 +1450,11 @@ ExecutableItem ExecutableItem::withTimeout(milliseconds timeout,
|
|||||||
|
|
||||||
static QString currentTime() { return QTime::currentTime().toString(Qt::ISODateWithMs); }
|
static QString currentTime() { return QTime::currentTime().toString(Qt::ISODateWithMs); }
|
||||||
|
|
||||||
|
static QString logHeader(const QString &logName)
|
||||||
|
{
|
||||||
|
return QString::fromLatin1("TASK TREE LOG [%1] \"%2\"").arg(currentTime(), logName);
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Attaches a custom debug printout to a copy of \c this ExecutableItem,
|
Attaches a custom debug printout to a copy of \c this ExecutableItem,
|
||||||
issued on task startup and after the task is finished, and returns the coupled item.
|
issued on task startup and after the task is finished, and returns the coupled item.
|
||||||
@@ -1463,9 +1468,6 @@ static QString currentTime() { return QTime::currentTime().toString(Qt::ISODateW
|
|||||||
*/
|
*/
|
||||||
ExecutableItem ExecutableItem::withLog(const QString &logName) const
|
ExecutableItem ExecutableItem::withLog(const QString &logName) const
|
||||||
{
|
{
|
||||||
const auto header = [logName] {
|
|
||||||
return QString::fromLatin1("TASK TREE LOG [%1] \"%2\"").arg(currentTime(), logName);
|
|
||||||
};
|
|
||||||
struct LogStorage
|
struct LogStorage
|
||||||
{
|
{
|
||||||
time_point<system_clock, nanoseconds> start;
|
time_point<system_clock, nanoseconds> start;
|
||||||
@@ -1474,21 +1476,22 @@ ExecutableItem ExecutableItem::withLog(const QString &logName) const
|
|||||||
const Storage<LogStorage> storage;
|
const Storage<LogStorage> storage;
|
||||||
return Group {
|
return Group {
|
||||||
storage,
|
storage,
|
||||||
onGroupSetup([storage, header] {
|
onGroupSetup([storage, logName] {
|
||||||
storage->start = system_clock::now();
|
storage->start = system_clock::now();
|
||||||
storage->asyncCount = activeTaskTree()->asyncCount();
|
storage->asyncCount = activeTaskTree()->asyncCount();
|
||||||
qDebug().noquote() << header() << "started.";
|
qDebug().noquote().nospace() << logHeader(logName) << " started.";
|
||||||
}),
|
}),
|
||||||
*this,
|
*this,
|
||||||
onGroupDone([storage, header](DoneWith result) {
|
onGroupDone([storage, logName](DoneWith result) {
|
||||||
const auto elapsed = duration_cast<milliseconds>(system_clock::now() - storage->start);
|
const auto elapsed = duration_cast<milliseconds>(system_clock::now() - storage->start);
|
||||||
const int asyncCountDiff = activeTaskTree()->asyncCount() - storage->asyncCount;
|
const int asyncCountDiff = activeTaskTree()->asyncCount() - storage->asyncCount;
|
||||||
QT_CHECK(asyncCountDiff >= 0);
|
QT_CHECK(asyncCountDiff >= 0);
|
||||||
const QMetaEnum doneWithEnum = QMetaEnum::fromType<DoneWith>();
|
const QMetaEnum doneWithEnum = QMetaEnum::fromType<DoneWith>();
|
||||||
const QString syncType = asyncCountDiff ? QString::fromLatin1("asynchronously")
|
const QString syncType = asyncCountDiff ? QString::fromLatin1("asynchronously")
|
||||||
: QString::fromLatin1("synchronously");
|
: QString::fromLatin1("synchronously");
|
||||||
qDebug().noquote().nospace() << header() << " finished " << syncType << " with "
|
qDebug().noquote().nospace() << logHeader(logName) << " finished " << syncType
|
||||||
<< doneWithEnum.valueToKey(int(result)) << " within " << elapsed.count() << "ms.";
|
<< " with " << doneWithEnum.valueToKey(int(result))
|
||||||
|
<< " within " << elapsed.count() << "ms.";
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -3383,7 +3386,7 @@ TimeoutTaskAdapter::~TimeoutTaskAdapter()
|
|||||||
void TimeoutTaskAdapter::start()
|
void TimeoutTaskAdapter::start()
|
||||||
{
|
{
|
||||||
m_timerId = scheduleTimeout(*task(), this, [this] {
|
m_timerId = scheduleTimeout(*task(), this, [this] {
|
||||||
m_timerId = {};
|
m_timerId.reset();
|
||||||
emit done(DoneResult::Success);
|
emit done(DoneResult::Success);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -29,23 +29,6 @@ QTCREATOR_UTILS_EXPORT QString fileNameToCppIdentifier(const QString &s)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTCREATOR_UTILS_EXPORT QString headerGuard(const QString &file)
|
|
||||||
{
|
|
||||||
return headerGuard(file, QStringList());
|
|
||||||
}
|
|
||||||
|
|
||||||
QTCREATOR_UTILS_EXPORT QString headerGuard(const QString &file, const QStringList &namespaceList)
|
|
||||||
{
|
|
||||||
const QChar underscore = QLatin1Char('_');
|
|
||||||
QString rc;
|
|
||||||
for (int i = 0; i < namespaceList.count(); i++)
|
|
||||||
rc += namespaceList.at(i).toUpper() + underscore;
|
|
||||||
|
|
||||||
const QFileInfo fi(file);
|
|
||||||
rc += fileNameToCppIdentifier(fi.fileName()).toUpper();
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
QTCREATOR_UTILS_EXPORT
|
QTCREATOR_UTILS_EXPORT
|
||||||
void writeIncludeFileDirective(const QString &file, bool globalInclude,
|
void writeIncludeFileDirective(const QString &file, bool globalInclude,
|
||||||
QTextStream &str)
|
QTextStream &str)
|
||||||
|
@@ -17,9 +17,6 @@ namespace Utils {
|
|||||||
// or replacing them by an underscore).
|
// or replacing them by an underscore).
|
||||||
QTCREATOR_UTILS_EXPORT QString fileNameToCppIdentifier(const QString &s);
|
QTCREATOR_UTILS_EXPORT QString fileNameToCppIdentifier(const QString &s);
|
||||||
|
|
||||||
QTCREATOR_UTILS_EXPORT QString headerGuard(const QString &file);
|
|
||||||
QTCREATOR_UTILS_EXPORT QString headerGuard(const QString &file, const QStringList &namespaceList);
|
|
||||||
|
|
||||||
QTCREATOR_UTILS_EXPORT
|
QTCREATOR_UTILS_EXPORT
|
||||||
void writeIncludeFileDirective(const QString &file,
|
void writeIncludeFileDirective(const QString &file,
|
||||||
bool globalInclude,
|
bool globalInclude,
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
"Version" : "${IDE_VERSION}",
|
"Version" : "${IDE_VERSION}",
|
||||||
"CompatVersion" : "${IDE_VERSION_COMPAT}",
|
"CompatVersion" : "${IDE_VERSION_COMPAT}",
|
||||||
"Experimental" : true,
|
"Experimental" : true,
|
||||||
|
"DisabledByDefault" : ${APPSTATISTICSMONITOR_DISABLEDBYDEFAULT},
|
||||||
"Vendor" : "The Qt Company Ltd",
|
"Vendor" : "The Qt Company Ltd",
|
||||||
"Copyright" : "(C) ${IDE_COPYRIGHT_YEAR} The Qt Company Ltd",
|
"Copyright" : "(C) ${IDE_COPYRIGHT_YEAR} The Qt Company Ltd",
|
||||||
"License" : [ "Commercial Usage",
|
"License" : [ "Commercial Usage",
|
||||||
|
@@ -13,6 +13,8 @@ set(CMAKE_CXX_EXTENSIONS OFF)
|
|||||||
|
|
||||||
find_package(Qt6 COMPONENTS Charts QUIET)
|
find_package(Qt6 COMPONENTS Charts QUIET)
|
||||||
|
|
||||||
|
set(APPSTATISTICSMONITOR_DISABLEDBYDEFAULT "true")
|
||||||
|
|
||||||
if (NOT QT_CREATOR_API_DEFINED)
|
if (NOT QT_CREATOR_API_DEFINED)
|
||||||
# standalone build
|
# standalone build
|
||||||
set(DESTINATION DESTINATION .)
|
set(DESTINATION DESTINATION .)
|
||||||
@@ -21,6 +23,8 @@ if (NOT QT_CREATOR_API_DEFINED)
|
|||||||
qtc_handle_compiler_cache_support()
|
qtc_handle_compiler_cache_support()
|
||||||
|
|
||||||
find_package(QtCreator COMPONENTS Core ProjectExplorer Utils REQUIRED)
|
find_package(QtCreator COMPONENTS Core ProjectExplorer Utils REQUIRED)
|
||||||
|
|
||||||
|
set(APPSTATISTICSMONITOR_DISABLEDBYDEFAULT "false")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
@@ -51,6 +51,8 @@ using namespace Utils;
|
|||||||
|
|
||||||
namespace Axivion::Internal {
|
namespace Axivion::Internal {
|
||||||
|
|
||||||
|
void showIssuesFromDashboard(const QString &kind); // impl at bottom
|
||||||
|
|
||||||
class DashboardWidget : public QScrollArea
|
class DashboardWidget : public QScrollArea
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -147,14 +149,24 @@ void DashboardWidget::updateUi()
|
|||||||
}
|
}
|
||||||
return prefix;
|
return prefix;
|
||||||
};
|
};
|
||||||
auto addValuesWidgets = [this, &toolTip](const QString &issueKind, qint64 total, qint64 added, qint64 removed, int row) {
|
auto linked = [](const QString &text, const QString &href, bool link) {
|
||||||
|
return link ? QString("<a href='%1'>%2</a>").arg(href).arg(text)
|
||||||
|
: text;
|
||||||
|
};
|
||||||
|
auto addValuesWidgets = [this, &toolTip, &linked](const QString &issueKind, qint64 total,
|
||||||
|
qint64 added, qint64 removed, int row, bool link) {
|
||||||
const QString currentToolTip = toolTip(issueKind);
|
const QString currentToolTip = toolTip(issueKind);
|
||||||
QLabel *label = new QLabel(issueKind, this);
|
QLabel *label = new QLabel(issueKind, this);
|
||||||
label->setToolTip(currentToolTip);
|
label->setToolTip(currentToolTip);
|
||||||
m_gridLayout->addWidget(label, row, 0);
|
m_gridLayout->addWidget(label, row, 0);
|
||||||
label = new QLabel(QString::number(total), this);
|
label = new QLabel(linked(QString::number(total), issueKind, link), this);
|
||||||
label->setToolTip(currentToolTip);
|
label->setToolTip(currentToolTip);
|
||||||
label->setAlignment(Qt::AlignRight);
|
label->setAlignment(Qt::AlignRight);
|
||||||
|
if (link) {
|
||||||
|
connect(label, &QLabel::linkActivated, this, [](const QString &issueKind) {
|
||||||
|
showIssuesFromDashboard(issueKind);
|
||||||
|
});
|
||||||
|
}
|
||||||
m_gridLayout->addWidget(label, row, 1);
|
m_gridLayout->addWidget(label, row, 1);
|
||||||
label = new QLabel(this);
|
label = new QLabel(this);
|
||||||
label->setPixmap(trendIcon(added, removed));
|
label->setPixmap(trendIcon(added, removed));
|
||||||
@@ -190,12 +202,12 @@ void DashboardWidget::updateUi()
|
|||||||
allAdded += added;
|
allAdded += added;
|
||||||
qint64 removed = extract_value(counts, QStringLiteral("Removed"));
|
qint64 removed = extract_value(counts, QStringLiteral("Removed"));
|
||||||
allRemoved += removed;
|
allRemoved += removed;
|
||||||
addValuesWidgets(issueCount.first, total, added, removed, row);
|
addValuesWidgets(issueCount.first, total, added, removed, row, true);
|
||||||
++row;
|
++row;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addValuesWidgets(Tr::tr("Total:"), allTotal, allAdded, allRemoved, row);
|
addValuesWidgets(Tr::tr("Total:"), allTotal, allAdded, allRemoved, row, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LinkWithColumns
|
struct LinkWithColumns
|
||||||
@@ -263,7 +275,7 @@ class IssuesWidget : public QScrollArea
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit IssuesWidget(QWidget *parent = nullptr);
|
explicit IssuesWidget(QWidget *parent = nullptr);
|
||||||
void updateUi();
|
void updateUi(const QString &kind);
|
||||||
|
|
||||||
const std::optional<Dto::TableInfoDto> currentTableInfo() const { return m_currentTableInfo; }
|
const std::optional<Dto::TableInfoDto> currentTableInfo() const { return m_currentTableInfo; }
|
||||||
IssueListSearch searchFromUi() const;
|
IssueListSearch searchFromUi() const;
|
||||||
@@ -378,7 +390,7 @@ IssuesWidget::IssuesWidget(QWidget *parent)
|
|||||||
setWidgetResizable(true);
|
setWidgetResizable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IssuesWidget::updateUi()
|
void IssuesWidget::updateUi(const QString &kind)
|
||||||
{
|
{
|
||||||
setFiltersEnabled(false);
|
setFiltersEnabled(false);
|
||||||
const std::optional<Dto::ProjectInfoDto> projectInfo = Internal::projectInfo();
|
const std::optional<Dto::ProjectInfoDto> projectInfo = Internal::projectInfo();
|
||||||
@@ -392,11 +404,30 @@ void IssuesWidget::updateUi()
|
|||||||
|
|
||||||
setFiltersEnabled(true);
|
setFiltersEnabled(true);
|
||||||
// avoid refetching existing data
|
// avoid refetching existing data
|
||||||
if (!m_currentPrefix.isEmpty() || m_issuesModel->rowCount())
|
if (kind.isEmpty() && (!m_currentPrefix.isEmpty() || m_issuesModel->rowCount()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (info.issueKinds.size())
|
if (!kind.isEmpty()) {
|
||||||
m_currentPrefix = info.issueKinds.front().prefix;
|
const int index
|
||||||
|
= Utils::indexOf( info.issueKinds, [kind](const Dto::IssueKindInfoDto &dto) {
|
||||||
|
return dto.prefix == kind; });
|
||||||
|
if (index != -1) {
|
||||||
|
m_currentPrefix = kind;
|
||||||
|
auto kindButton = m_typesButtonGroup->button(index + 1);
|
||||||
|
if (QTC_GUARD(kindButton))
|
||||||
|
kindButton->setChecked(true);
|
||||||
|
// reset filters - if kind is not empty we get triggered from dashboard overview
|
||||||
|
if (!m_userNames.isEmpty())
|
||||||
|
m_ownerFilter->setCurrentIndex(0);
|
||||||
|
m_pathGlobFilter->clear();
|
||||||
|
if (m_versionDates.size() > 1) {
|
||||||
|
m_versionStart->setCurrentIndex(m_versionDates.count() - 1);
|
||||||
|
m_versionEnd->setCurrentIndex(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_currentPrefix.isEmpty())
|
||||||
|
m_currentPrefix = info.issueKinds.size() ? info.issueKinds.front().prefix : QString{};
|
||||||
fetchTable();
|
fetchTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -767,12 +798,7 @@ public:
|
|||||||
m_showIssues->setIcon(Icons::ZOOM_TOOLBAR.icon());
|
m_showIssues->setIcon(Icons::ZOOM_TOOLBAR.icon());
|
||||||
m_showIssues->setToolTip(Tr::tr("Search for issues"));
|
m_showIssues->setToolTip(Tr::tr("Search for issues"));
|
||||||
m_showIssues->setCheckable(true);
|
m_showIssues->setCheckable(true);
|
||||||
connect(m_showIssues, &QToolButton::clicked, this, [this] {
|
connect(m_showIssues, &QToolButton::clicked, this, [this] { handleShowIssues({}); });
|
||||||
QTC_ASSERT(m_outputWidget, return);
|
|
||||||
m_outputWidget->setCurrentIndex(1);
|
|
||||||
if (auto issues = static_cast<IssuesWidget *>(m_outputWidget->widget(1)))
|
|
||||||
issues->updateUi();
|
|
||||||
});
|
|
||||||
auto *butonGroup = new QButtonGroup(this);
|
auto *butonGroup = new QButtonGroup(this);
|
||||||
butonGroup->addButton(m_showDashboard);
|
butonGroup->addButton(m_showDashboard);
|
||||||
butonGroup->addButton(m_showIssues);
|
butonGroup->addButton(m_showIssues);
|
||||||
@@ -814,6 +840,14 @@ public:
|
|||||||
void goToNext() final {}
|
void goToNext() final {}
|
||||||
void goToPrev() final {}
|
void goToPrev() final {}
|
||||||
|
|
||||||
|
void handleShowIssues(const QString &kind)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_outputWidget, return);
|
||||||
|
m_outputWidget->setCurrentIndex(1);
|
||||||
|
if (auto issues = static_cast<IssuesWidget *>(m_outputWidget->widget(1)))
|
||||||
|
issues->updateUi(kind);
|
||||||
|
}
|
||||||
|
|
||||||
void updateDashboard()
|
void updateDashboard()
|
||||||
{
|
{
|
||||||
if (auto dashboard = static_cast<DashboardWidget *>(m_outputWidget->widget(0))) {
|
if (auto dashboard = static_cast<DashboardWidget *>(m_outputWidget->widget(0))) {
|
||||||
@@ -897,4 +931,10 @@ static bool issueListContextMenuEvent(const ItemViewEvent &ev)
|
|||||||
return theAxivionOutputPane->handleContextMenu(issue, ev);
|
return theAxivionOutputPane->handleContextMenu(issue, ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void showIssuesFromDashboard(const QString &kind)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(theAxivionOutputPane, return);
|
||||||
|
theAxivionOutputPane->handleShowIssues(kind);
|
||||||
|
}
|
||||||
|
|
||||||
} // Axivion::Internal
|
} // Axivion::Internal
|
||||||
|
@@ -474,11 +474,10 @@ ClangTool::ClangTool(const QString &name, Id id, ClangToolType type)
|
|||||||
|
|
||||||
// Expand/Collapse
|
// Expand/Collapse
|
||||||
action = new QAction(this);
|
action = new QAction(this);
|
||||||
action->setDisabled(true);
|
|
||||||
action->setCheckable(true);
|
action->setCheckable(true);
|
||||||
action->setIcon(Utils::Icons::EXPAND_ALL_TOOLBAR.icon());
|
action->setIcon(Utils::Icons::EXPAND_ALL_TOOLBAR.icon());
|
||||||
action->setToolTip(Tr::tr("Expand All"));
|
m_expandCollapse = action;
|
||||||
connect(action, &QAction::toggled, this, [this](bool checked){
|
const auto handleCollapseExpandToggled = [this](bool checked){
|
||||||
if (checked) {
|
if (checked) {
|
||||||
m_expandCollapse->setToolTip(Tr::tr("Collapse All"));
|
m_expandCollapse->setToolTip(Tr::tr("Collapse All"));
|
||||||
m_diagnosticView->expandAll();
|
m_diagnosticView->expandAll();
|
||||||
@@ -486,8 +485,9 @@ ClangTool::ClangTool(const QString &name, Id id, ClangToolType type)
|
|||||||
m_expandCollapse->setToolTip(Tr::tr("Expand All"));
|
m_expandCollapse->setToolTip(Tr::tr("Expand All"));
|
||||||
m_diagnosticView->collapseAll();
|
m_diagnosticView->collapseAll();
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
m_expandCollapse = action;
|
connect(action, &QAction::toggled, this, handleCollapseExpandToggled);
|
||||||
|
handleCollapseExpandToggled(action->isChecked());
|
||||||
|
|
||||||
// Filter button
|
// Filter button
|
||||||
action = m_showFilter = new QAction(this);
|
action = m_showFilter = new QAction(this);
|
||||||
@@ -1242,8 +1242,32 @@ QSet<Diagnostic> ClangTool::diagnostics() const
|
|||||||
|
|
||||||
void ClangTool::onNewDiagnosticsAvailable(const Diagnostics &diagnostics, bool generateMarks)
|
void ClangTool::onNewDiagnosticsAvailable(const Diagnostics &diagnostics, bool generateMarks)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_diagnosticModel, return);
|
const int oldLevel1RowCount = m_diagnosticModel->rowCount();
|
||||||
|
const auto getOldLastLevel1Index = [&] {
|
||||||
|
return m_diagnosticModel->index(oldLevel1RowCount - 1, 0);
|
||||||
|
};
|
||||||
|
const auto getLevel2RowCountForOldLastLevel1Index = [&] {
|
||||||
|
return oldLevel1RowCount == 0 ? -1 : m_diagnosticModel->rowCount(getOldLastLevel1Index());
|
||||||
|
};
|
||||||
|
const int oldLevel2RowCount = getLevel2RowCountForOldLastLevel1Index();
|
||||||
m_diagnosticModel->addDiagnostics(diagnostics, generateMarks);
|
m_diagnosticModel->addDiagnostics(diagnostics, generateMarks);
|
||||||
|
if (!m_expandCollapse->isChecked())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Now expand newly added items, both in existing file nodes and in newly added ones.
|
||||||
|
// We assume diagnostics arrive "in order", i.e. things are only ever added at the end
|
||||||
|
// (in the source model).
|
||||||
|
const int newLevel2RowCount = getLevel2RowCountForOldLastLevel1Index();
|
||||||
|
for (int i = oldLevel2RowCount; i < newLevel2RowCount; ++i) {
|
||||||
|
m_diagnosticView->expand(m_diagnosticFilterModel->mapFromSource(
|
||||||
|
m_diagnosticModel
|
||||||
|
->index(i, 0, m_diagnosticFilterModel->mapFromSource(getOldLastLevel1Index()))));
|
||||||
|
}
|
||||||
|
const int newLevel1RowCount = m_diagnosticFilterModel->rowCount();
|
||||||
|
for (int i = oldLevel1RowCount; i < newLevel1RowCount; ++i) {
|
||||||
|
m_diagnosticView->expandRecursively(
|
||||||
|
m_diagnosticFilterModel->mapFromSource(m_diagnosticModel->index(i, 0)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangTool::updateForCurrentState()
|
void ClangTool::updateForCurrentState()
|
||||||
@@ -1273,7 +1297,6 @@ void ClangTool::updateForCurrentState()
|
|||||||
m_goBack->setEnabled(issuesVisible > 0);
|
m_goBack->setEnabled(issuesVisible > 0);
|
||||||
m_goNext->setEnabled(issuesVisible > 0);
|
m_goNext->setEnabled(issuesVisible > 0);
|
||||||
m_clear->setEnabled(!isRunning);
|
m_clear->setEnabled(!isRunning);
|
||||||
m_expandCollapse->setEnabled(issuesVisible);
|
|
||||||
m_loadExported->setEnabled(!isRunning);
|
m_loadExported->setEnabled(!isRunning);
|
||||||
m_showFilter->setEnabled(issuesFound > 1);
|
m_showFilter->setEnabled(issuesFound > 1);
|
||||||
|
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
#include <cppeditor/clangdiagnosticconfigsmodel.h>
|
#include <cppeditor/clangdiagnosticconfigsmodel.h>
|
||||||
|
#include <cppeditor/compileroptionsbuilder.h>
|
||||||
#include <cppeditor/cppcodemodelsettings.h>
|
#include <cppeditor/cppcodemodelsettings.h>
|
||||||
#include <cppeditor/cppprojectfile.h>
|
#include <cppeditor/cppprojectfile.h>
|
||||||
#include <cppeditor/cpptoolsreuse.h>
|
#include <cppeditor/cpptoolsreuse.h>
|
||||||
|
@@ -34,7 +34,6 @@
|
|||||||
#include <projectexplorer/devicesupport/idevice.h>
|
#include <projectexplorer/devicesupport/idevice.h>
|
||||||
#include <projectexplorer/environmentaspectwidget.h>
|
#include <projectexplorer/environmentaspectwidget.h>
|
||||||
#include <projectexplorer/environmentwidget.h>
|
#include <projectexplorer/environmentwidget.h>
|
||||||
#include <projectexplorer/gcctoolchain.h>
|
|
||||||
#include <projectexplorer/kitaspects.h>
|
#include <projectexplorer/kitaspects.h>
|
||||||
#include <projectexplorer/namedwidget.h>
|
#include <projectexplorer/namedwidget.h>
|
||||||
#include <projectexplorer/processparameters.h>
|
#include <projectexplorer/processparameters.h>
|
||||||
@@ -1184,30 +1183,6 @@ static CommandLine defaultInitialCMakeCommand(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GCC compiler and linker specific flags
|
|
||||||
for (Toolchain *tc : ToolchainKitAspect::toolChains(k)) {
|
|
||||||
if (auto *gccTc = tc->asGccToolchain()) {
|
|
||||||
const QStringList compilerFlags = gccTc->platformCodeGenFlags();
|
|
||||||
|
|
||||||
QLatin1String languageFlagsInit;
|
|
||||||
if (gccTc->language() == ProjectExplorer::Constants::C_LANGUAGE_ID)
|
|
||||||
languageFlagsInit = QLatin1String(CMAKE_C_FLAGS_INIT);
|
|
||||||
else if (gccTc->language() == ProjectExplorer::Constants::CXX_LANGUAGE_ID)
|
|
||||||
languageFlagsInit = QLatin1String(CMAKE_CXX_FLAGS_INIT);
|
|
||||||
|
|
||||||
if (!languageFlagsInit.isEmpty() && !compilerFlags.isEmpty())
|
|
||||||
cmd.addArg("-D" + languageFlagsInit + ":STRING=" + compilerFlags.join(" "));
|
|
||||||
|
|
||||||
const QStringList linkerFlags = gccTc->platformLinkerFlags();
|
|
||||||
if (!linkerFlags.isEmpty()) {
|
|
||||||
const QString joinedLinkerFlags = linkerFlags.join(" ");
|
|
||||||
cmd.addArg("-DCMAKE_EXE_LINKER_FLAGS_INIT:STRING=" + joinedLinkerFlags);
|
|
||||||
cmd.addArg("-DCMAKE_MODULE_LINKER_FLAGS_INIT:STRING=" + joinedLinkerFlags);
|
|
||||||
cmd.addArg("-DCMAKE_SHARED_LINKER_FLAGS_INIT:STRING=" + joinedLinkerFlags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.addArgs(CMakeConfigurationKitAspect::toArgumentsList(k));
|
cmd.addArgs(CMakeConfigurationKitAspect::toArgumentsList(k));
|
||||||
cmd.addArgs(CMakeConfigurationKitAspect::additionalConfiguration(k), CommandLine::Raw);
|
cmd.addArgs(CMakeConfigurationKitAspect::additionalConfiguration(k), CommandLine::Raw);
|
||||||
|
|
||||||
@@ -1356,7 +1331,7 @@ static void addCMakeConfigurePresetToInitialArguments(QStringList &initialArgume
|
|||||||
|
|
||||||
if (argFilePath != presetFilePath)
|
if (argFilePath != presetFilePath)
|
||||||
arg = presetItem.toArgument();
|
arg = presetItem.toArgument();
|
||||||
} else if (argItem.key == CMAKE_CXX_FLAGS_INIT) {
|
} else if (argItem.key == CMAKE_C_FLAGS_INIT || argItem.key == CMAKE_CXX_FLAGS_INIT) {
|
||||||
// Append the preset value with at the initial parameters value (e.g. QML Debugging)
|
// Append the preset value with at the initial parameters value (e.g. QML Debugging)
|
||||||
if (argItem.expandedValue(k) != QString::fromUtf8(presetItem.value)) {
|
if (argItem.expandedValue(k) != QString::fromUtf8(presetItem.value)) {
|
||||||
argItem.value.append(" ");
|
argItem.value.append(" ");
|
||||||
|
@@ -227,7 +227,7 @@ void CppEditorPlugin::initialize()
|
|||||||
void CppEditorPlugin::extensionsInitialized()
|
void CppEditorPlugin::extensionsInitialized()
|
||||||
{
|
{
|
||||||
setupCppQuickFixProjectPanel();
|
setupCppQuickFixProjectPanel();
|
||||||
setupCppFileSettings();
|
setupCppFileSettings(*this);
|
||||||
setupCppCodeModelProjectSettingsPanel();
|
setupCppCodeModelProjectSettingsPanel();
|
||||||
|
|
||||||
if (CppModelManager::isClangCodeModelActive()) {
|
if (CppModelManager::isClangCodeModelActive()) {
|
||||||
|
@@ -6,15 +6,19 @@
|
|||||||
#include "cppeditortr.h"
|
#include "cppeditortr.h"
|
||||||
#include "cppheadersource.h"
|
#include "cppheadersource.h"
|
||||||
|
|
||||||
|
#include <extensionsystem/iplugin.h>
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
|
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
#include <projectexplorer/projectpanelfactory.h>
|
#include <projectexplorer/projectpanelfactory.h>
|
||||||
|
|
||||||
|
#include <utils/aspects.h>
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
#include <utils/layoutbuilder.h>
|
#include <utils/layoutbuilder.h>
|
||||||
|
#include <utils/macroexpander.h>
|
||||||
#include <utils/mimeconstants.h>
|
#include <utils/mimeconstants.h>
|
||||||
#include <utils/mimeutils.h>
|
#include <utils/mimeutils.h>
|
||||||
#include <utils/pathchooser.h>
|
#include <utils/pathchooser.h>
|
||||||
@@ -29,10 +33,30 @@
|
|||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
#ifdef WITH_TESTS
|
||||||
|
#include <QtTest>
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
|
|
||||||
namespace CppEditor::Internal {
|
namespace CppEditor::Internal {
|
||||||
|
namespace {
|
||||||
|
class HeaderGuardExpander : public MacroExpander
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HeaderGuardExpander(const FilePath &filePath) : m_filePath(filePath)
|
||||||
|
{
|
||||||
|
setDisplayName(Tr::tr("Header file variables"));
|
||||||
|
registerFileVariables("Header", Tr::tr("Header file"), [this] {
|
||||||
|
return m_filePath;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const FilePath m_filePath;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
const char projectSettingsKeyC[] = "CppEditorFileNames";
|
const char projectSettingsKeyC[] = "CppEditorFileNames";
|
||||||
const char useGlobalKeyC[] = "UseGlobal";
|
const char useGlobalKeyC[] = "UseGlobal";
|
||||||
@@ -44,6 +68,7 @@ const char headerSearchPathsKeyC[] = "HeaderSearchPaths";
|
|||||||
const char sourceSearchPathsKeyC[] = "SourceSearchPaths";
|
const char sourceSearchPathsKeyC[] = "SourceSearchPaths";
|
||||||
const char headerPragmaOnceC[] = "HeaderPragmaOnce";
|
const char headerPragmaOnceC[] = "HeaderPragmaOnce";
|
||||||
const char licenseTemplatePathKeyC[] = "LicenseTemplate";
|
const char licenseTemplatePathKeyC[] = "LicenseTemplate";
|
||||||
|
const char headerGuardTemplateKeyC[] = "HeaderGuardTemplate";
|
||||||
|
|
||||||
const char *licenseTemplateTemplate = QT_TRANSLATE_NOOP("QtC::CppEditor",
|
const char *licenseTemplateTemplate = QT_TRANSLATE_NOOP("QtC::CppEditor",
|
||||||
"/**************************************************************************\n"
|
"/**************************************************************************\n"
|
||||||
@@ -67,6 +92,7 @@ void CppFileSettings::toSettings(QtcSettings *s) const
|
|||||||
s->setValueWithDefault(headerPragmaOnceC, headerPragmaOnce, def.headerPragmaOnce);
|
s->setValueWithDefault(headerPragmaOnceC, headerPragmaOnce, def.headerPragmaOnce);
|
||||||
s->setValueWithDefault(licenseTemplatePathKeyC, licenseTemplatePath.toSettings(),
|
s->setValueWithDefault(licenseTemplatePathKeyC, licenseTemplatePath.toSettings(),
|
||||||
def.licenseTemplatePath.toSettings());
|
def.licenseTemplatePath.toSettings());
|
||||||
|
s->setValueWithDefault(headerGuardTemplateKeyC, headerGuardTemplate, def.headerGuardTemplate);
|
||||||
s->endGroup();
|
s->endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,6 +110,7 @@ void CppFileSettings::fromSettings(QtcSettings *s)
|
|||||||
headerPragmaOnce = s->value(headerPragmaOnceC, def.headerPragmaOnce).toBool();
|
headerPragmaOnce = s->value(headerPragmaOnceC, def.headerPragmaOnce).toBool();
|
||||||
licenseTemplatePath = FilePath::fromSettings(s->value(licenseTemplatePathKeyC,
|
licenseTemplatePath = FilePath::fromSettings(s->value(licenseTemplatePathKeyC,
|
||||||
def.licenseTemplatePath.toSettings()));
|
def.licenseTemplatePath.toSettings()));
|
||||||
|
headerGuardTemplate = s->value(headerGuardTemplateKeyC, def.headerGuardTemplate).toString();
|
||||||
s->endGroup();
|
s->endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,6 +151,7 @@ bool CppFileSettings::equals(const CppFileSettings &rhs) const
|
|||||||
&& sourceSuffix == rhs.sourceSuffix
|
&& sourceSuffix == rhs.sourceSuffix
|
||||||
&& headerSearchPaths == rhs.headerSearchPaths
|
&& headerSearchPaths == rhs.headerSearchPaths
|
||||||
&& sourceSearchPaths == rhs.sourceSearchPaths
|
&& sourceSearchPaths == rhs.sourceSearchPaths
|
||||||
|
&& headerGuardTemplate == rhs.headerGuardTemplate
|
||||||
&& licenseTemplatePath == rhs.licenseTemplatePath;
|
&& licenseTemplatePath == rhs.licenseTemplatePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,6 +265,11 @@ QString CppFileSettings::licenseTemplate() const
|
|||||||
return license;
|
return license;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString CppFileSettings::headerGuard(const Utils::FilePath &headerFilePath) const
|
||||||
|
{
|
||||||
|
return HeaderGuardExpander(headerFilePath).expand(headerGuardTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------ CppFileSettingsWidget
|
// ------------------ CppFileSettingsWidget
|
||||||
|
|
||||||
class CppFileSettingsWidget final : public Core::IOptionsPageWidget
|
class CppFileSettingsWidget final : public Core::IOptionsPageWidget
|
||||||
@@ -269,6 +302,8 @@ private:
|
|||||||
QLineEdit *m_sourcePrefixesEdit = nullptr;
|
QLineEdit *m_sourcePrefixesEdit = nullptr;
|
||||||
QCheckBox *m_lowerCaseFileNamesCheckBox = nullptr;
|
QCheckBox *m_lowerCaseFileNamesCheckBox = nullptr;
|
||||||
PathChooser *m_licenseTemplatePathChooser = nullptr;
|
PathChooser *m_licenseTemplatePathChooser = nullptr;
|
||||||
|
StringAspect m_headerGuardAspect;
|
||||||
|
HeaderGuardExpander m_headerGuardExpander{{}};
|
||||||
};
|
};
|
||||||
|
|
||||||
CppFileSettingsWidget::CppFileSettingsWidget(CppFileSettings *settings)
|
CppFileSettingsWidget::CppFileSettingsWidget(CppFileSettings *settings)
|
||||||
@@ -276,7 +311,7 @@ CppFileSettingsWidget::CppFileSettingsWidget(CppFileSettings *settings)
|
|||||||
, m_headerSuffixComboBox(new QComboBox)
|
, m_headerSuffixComboBox(new QComboBox)
|
||||||
, m_headerSearchPathsEdit(new QLineEdit)
|
, m_headerSearchPathsEdit(new QLineEdit)
|
||||||
, m_headerPrefixesEdit(new QLineEdit)
|
, m_headerPrefixesEdit(new QLineEdit)
|
||||||
, m_headerPragmaOnceCheckBox(new QCheckBox(Tr::tr("Use \"#pragma once\" instead of \"#ifndef\" guards")))
|
, m_headerPragmaOnceCheckBox(new QCheckBox(Tr::tr("Use \"#pragma once\" instead")))
|
||||||
, m_sourceSuffixComboBox(new QComboBox)
|
, m_sourceSuffixComboBox(new QComboBox)
|
||||||
, m_sourceSearchPathsEdit(new QLineEdit)
|
, m_sourceSearchPathsEdit(new QLineEdit)
|
||||||
, m_sourcePrefixesEdit(new QLineEdit)
|
, m_sourcePrefixesEdit(new QLineEdit)
|
||||||
@@ -301,6 +336,8 @@ CppFileSettingsWidget::CppFileSettingsWidget(CppFileSettings *settings)
|
|||||||
m_sourcePrefixesEdit->setToolTip(Tr::tr("Comma-separated list of source prefixes.\n"
|
m_sourcePrefixesEdit->setToolTip(Tr::tr("Comma-separated list of source prefixes.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"These prefixes are used in addition to current file name on Switch Header/Source."));
|
"These prefixes are used in addition to current file name on Switch Header/Source."));
|
||||||
|
m_headerGuardAspect.setDisplayStyle(Utils::StringAspect::LineEditDisplay);
|
||||||
|
m_headerGuardAspect.setMacroExpander(&m_headerGuardExpander);
|
||||||
|
|
||||||
using namespace Layouting;
|
using namespace Layouting;
|
||||||
|
|
||||||
@@ -311,8 +348,8 @@ CppFileSettingsWidget::CppFileSettingsWidget(CppFileSettings *settings)
|
|||||||
Tr::tr("&Suffix:"), m_headerSuffixComboBox, st, br,
|
Tr::tr("&Suffix:"), m_headerSuffixComboBox, st, br,
|
||||||
Tr::tr("S&earch paths:"), m_headerSearchPathsEdit, br,
|
Tr::tr("S&earch paths:"), m_headerSearchPathsEdit, br,
|
||||||
Tr::tr("&Prefixes:"), m_headerPrefixesEdit, br,
|
Tr::tr("&Prefixes:"), m_headerPrefixesEdit, br,
|
||||||
Tr::tr("Include guards"), m_headerPragmaOnceCheckBox
|
Tr::tr("Include guard template:"), m_headerPragmaOnceCheckBox, m_headerGuardAspect
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
title(Tr::tr("Sources")),
|
title(Tr::tr("Sources")),
|
||||||
@@ -361,12 +398,21 @@ CppFileSettingsWidget::CppFileSettingsWidget(CppFileSettings *settings)
|
|||||||
this, &CppFileSettingsWidget::userChange);
|
this, &CppFileSettingsWidget::userChange);
|
||||||
connect(m_sourcePrefixesEdit, &QLineEdit::textEdited,
|
connect(m_sourcePrefixesEdit, &QLineEdit::textEdited,
|
||||||
this, &CppFileSettingsWidget::userChange);
|
this, &CppFileSettingsWidget::userChange);
|
||||||
connect(m_headerPragmaOnceCheckBox, &QCheckBox::stateChanged,
|
|
||||||
this, &CppFileSettingsWidget::userChange);
|
|
||||||
connect(m_lowerCaseFileNamesCheckBox, &QCheckBox::stateChanged,
|
connect(m_lowerCaseFileNamesCheckBox, &QCheckBox::stateChanged,
|
||||||
this, &CppFileSettingsWidget::userChange);
|
this, &CppFileSettingsWidget::userChange);
|
||||||
connect(m_licenseTemplatePathChooser, &PathChooser::textChanged,
|
connect(m_licenseTemplatePathChooser, &PathChooser::textChanged,
|
||||||
this, &CppFileSettingsWidget::userChange);
|
this, &CppFileSettingsWidget::userChange);
|
||||||
|
const auto updateHeaderGuardAspectState = [this] {
|
||||||
|
m_headerGuardAspect.setEnabled(!m_headerPragmaOnceCheckBox->isChecked());
|
||||||
|
};
|
||||||
|
connect(m_headerPragmaOnceCheckBox, &QCheckBox::stateChanged,
|
||||||
|
this, [this, updateHeaderGuardAspectState] {
|
||||||
|
updateHeaderGuardAspectState();
|
||||||
|
emit userChange();
|
||||||
|
});
|
||||||
|
connect(&m_headerGuardAspect, &StringAspect::changed,
|
||||||
|
this, &CppFileSettingsWidget::userChange);
|
||||||
|
updateHeaderGuardAspectState();
|
||||||
}
|
}
|
||||||
|
|
||||||
FilePath CppFileSettingsWidget::licenseTemplatePath() const
|
FilePath CppFileSettingsWidget::licenseTemplatePath() const
|
||||||
@@ -417,6 +463,7 @@ void CppFileSettingsWidget::setSettings(const CppFileSettings &s)
|
|||||||
m_headerSearchPathsEdit->setText(s.headerSearchPaths.join(comma));
|
m_headerSearchPathsEdit->setText(s.headerSearchPaths.join(comma));
|
||||||
m_sourceSearchPathsEdit->setText(s.sourceSearchPaths.join(comma));
|
m_sourceSearchPathsEdit->setText(s.sourceSearchPaths.join(comma));
|
||||||
setLicenseTemplatePath(s.licenseTemplatePath);
|
setLicenseTemplatePath(s.licenseTemplatePath);
|
||||||
|
m_headerGuardAspect.setValue(s.headerGuardTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
CppFileSettings CppFileSettingsWidget::currentSettings() const
|
CppFileSettings CppFileSettingsWidget::currentSettings() const
|
||||||
@@ -431,6 +478,7 @@ CppFileSettings CppFileSettingsWidget::currentSettings() const
|
|||||||
rc.headerSearchPaths = trimmedPaths(m_headerSearchPathsEdit->text());
|
rc.headerSearchPaths = trimmedPaths(m_headerSearchPathsEdit->text());
|
||||||
rc.sourceSearchPaths = trimmedPaths(m_sourceSearchPathsEdit->text());
|
rc.sourceSearchPaths = trimmedPaths(m_sourceSearchPathsEdit->text());
|
||||||
rc.licenseTemplatePath = licenseTemplatePath();
|
rc.licenseTemplatePath = licenseTemplatePath();
|
||||||
|
rc.headerGuardTemplate = m_headerGuardAspect.value();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,6 +584,8 @@ void CppFileSettingsForProject::loadSettings()
|
|||||||
m_customSettings.lowerCaseFiles).toBool();
|
m_customSettings.lowerCaseFiles).toBool();
|
||||||
m_customSettings.headerPragmaOnce = data.value(headerPragmaOnceC,
|
m_customSettings.headerPragmaOnce = data.value(headerPragmaOnceC,
|
||||||
m_customSettings.headerPragmaOnce).toBool();
|
m_customSettings.headerPragmaOnce).toBool();
|
||||||
|
m_customSettings.headerGuardTemplate
|
||||||
|
= data.value(headerGuardTemplateKeyC, m_customSettings.headerGuardTemplate).toString();
|
||||||
m_customSettings.licenseTemplatePath
|
m_customSettings.licenseTemplatePath
|
||||||
= FilePath::fromSettings(data.value(licenseTemplatePathKeyC,
|
= FilePath::fromSettings(data.value(licenseTemplatePathKeyC,
|
||||||
m_customSettings.licenseTemplatePath.toSettings()));
|
m_customSettings.licenseTemplatePath.toSettings()));
|
||||||
@@ -560,6 +610,7 @@ void CppFileSettingsForProject::saveSettings()
|
|||||||
data.insert(sourceSearchPathsKeyC, m_customSettings.sourceSearchPaths);
|
data.insert(sourceSearchPathsKeyC, m_customSettings.sourceSearchPaths);
|
||||||
data.insert(Constants::LOWERCASE_CPPFILES_KEY, m_customSettings.lowerCaseFiles);
|
data.insert(Constants::LOWERCASE_CPPFILES_KEY, m_customSettings.lowerCaseFiles);
|
||||||
data.insert(headerPragmaOnceC, m_customSettings.headerPragmaOnce);
|
data.insert(headerPragmaOnceC, m_customSettings.headerPragmaOnce);
|
||||||
|
data.insert(headerGuardTemplateKeyC, m_customSettings.headerGuardTemplate);
|
||||||
data.insert(licenseTemplatePathKeyC, m_customSettings.licenseTemplatePath.toSettings());
|
data.insert(licenseTemplatePathKeyC, m_customSettings.licenseTemplatePath.toSettings());
|
||||||
m_project->setNamedSettings(projectSettingsKeyC, data);
|
m_project->setNamedSettings(projectSettingsKeyC, data);
|
||||||
}
|
}
|
||||||
@@ -631,16 +682,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void setupCppFileSettings()
|
|
||||||
{
|
|
||||||
static CppFileSettingsProjectPanelFactory theCppFileSettingsProjectPanelFactory;
|
|
||||||
|
|
||||||
static CppFileSettingsPage theCppFileSettingsPage;
|
|
||||||
|
|
||||||
globalCppFileSettings().fromSettings(Core::ICore::settings());
|
|
||||||
globalCppFileSettings().addMimeInitializer();
|
|
||||||
}
|
|
||||||
|
|
||||||
CppFileSettings &globalCppFileSettings()
|
CppFileSettings &globalCppFileSettings()
|
||||||
{
|
{
|
||||||
// This is the global instance. There could be more.
|
// This is the global instance. There could be more.
|
||||||
@@ -653,6 +694,59 @@ CppFileSettings cppFileSettingsForProject(ProjectExplorer::Project *project)
|
|||||||
return CppFileSettingsForProject(project).settings();
|
return CppFileSettingsForProject(project).settings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_TESTS
|
||||||
|
namespace {
|
||||||
|
class CppFileSettingsTest : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void testHeaderGuard_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QString>("guardTemplate");
|
||||||
|
QTest::addColumn<QString>("headerFile");
|
||||||
|
QTest::addColumn<QString>("expectedGuard");
|
||||||
|
|
||||||
|
QTest::newRow("default template, .h")
|
||||||
|
<< QString() << QString("/tmp/header.h") << QString("HEADER_H");
|
||||||
|
QTest::newRow("default template, .hpp")
|
||||||
|
<< QString() << QString("/tmp/header.hpp") << QString("HEADER_HPP");
|
||||||
|
QTest::newRow("default template, two extensions")
|
||||||
|
<< QString() << QString("/tmp/header.in.h") << QString("HEADER_IN_H");
|
||||||
|
QTest::newRow("non-default template")
|
||||||
|
<< QString("%{JS: '%{Header:FilePath}'.toUpperCase().replace(/[.]/, '_').replace(/[/]/g, '_')}")
|
||||||
|
<< QString("/tmp/header.h") << QString("_TMP_HEADER_H");
|
||||||
|
}
|
||||||
|
|
||||||
|
void testHeaderGuard()
|
||||||
|
{
|
||||||
|
QFETCH(QString, guardTemplate);
|
||||||
|
QFETCH(QString, headerFile);
|
||||||
|
QFETCH(QString, expectedGuard);
|
||||||
|
|
||||||
|
CppFileSettings settings;
|
||||||
|
if (!guardTemplate.isEmpty())
|
||||||
|
settings.headerGuardTemplate = guardTemplate;
|
||||||
|
QCOMPARE(settings.headerGuard(FilePath::fromUserInput(headerFile)), expectedGuard);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
#endif // WITH_TESTS
|
||||||
|
|
||||||
|
void setupCppFileSettings(ExtensionSystem::IPlugin &plugin)
|
||||||
|
{
|
||||||
|
static CppFileSettingsProjectPanelFactory theCppFileSettingsProjectPanelFactory;
|
||||||
|
|
||||||
|
static CppFileSettingsPage theCppFileSettingsPage;
|
||||||
|
|
||||||
|
globalCppFileSettings().fromSettings(Core::ICore::settings());
|
||||||
|
globalCppFileSettings().addMimeInitializer();
|
||||||
|
|
||||||
|
#ifdef WITH_TESTS
|
||||||
|
plugin.addTestCreator([] { return new CppFileSettingsTest; });
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace CppEditor::Internal
|
} // namespace CppEditor::Internal
|
||||||
|
|
||||||
#include <cppfilesettingspage.moc>
|
#include <cppfilesettingspage.moc>
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
|
namespace ExtensionSystem { class IPlugin; }
|
||||||
namespace ProjectExplorer { class Project; }
|
namespace ProjectExplorer { class Project; }
|
||||||
|
|
||||||
namespace CppEditor::Internal {
|
namespace CppEditor::Internal {
|
||||||
@@ -28,6 +29,7 @@ public:
|
|||||||
QDir::toNativeSeparators("../Src"),
|
QDir::toNativeSeparators("../Src"),
|
||||||
".."};
|
".."};
|
||||||
Utils::FilePath licenseTemplatePath;
|
Utils::FilePath licenseTemplatePath;
|
||||||
|
QString headerGuardTemplate = "%{JS: '%{Header:FileName}'.toUpperCase().replace(/[.]/g, '_')}";
|
||||||
bool headerPragmaOnce = false;
|
bool headerPragmaOnce = false;
|
||||||
bool lowerCaseFiles = Constants::LOWERCASE_CPPFILES_DEFAULT;
|
bool lowerCaseFiles = Constants::LOWERCASE_CPPFILES_DEFAULT;
|
||||||
|
|
||||||
@@ -39,6 +41,9 @@ public:
|
|||||||
// Convenience to return a license template completely formatted.
|
// Convenience to return a license template completely formatted.
|
||||||
QString licenseTemplate() const;
|
QString licenseTemplate() const;
|
||||||
|
|
||||||
|
// Expanded headerGuardTemplate.
|
||||||
|
QString headerGuard(const Utils::FilePath &headerFilePath) const;
|
||||||
|
|
||||||
bool equals(const CppFileSettings &rhs) const;
|
bool equals(const CppFileSettings &rhs) const;
|
||||||
bool operator==(const CppFileSettings &s) const { return equals(s); }
|
bool operator==(const CppFileSettings &s) const { return equals(s); }
|
||||||
bool operator!=(const CppFileSettings &s) const { return !equals(s); }
|
bool operator!=(const CppFileSettings &s) const { return !equals(s); }
|
||||||
@@ -48,6 +53,6 @@ CppFileSettings &globalCppFileSettings();
|
|||||||
|
|
||||||
CppFileSettings cppFileSettingsForProject(ProjectExplorer::Project *project);
|
CppFileSettings cppFileSettingsForProject(ProjectExplorer::Project *project);
|
||||||
|
|
||||||
void setupCppFileSettings();
|
void setupCppFileSettings(ExtensionSystem::IPlugin &plugin);
|
||||||
|
|
||||||
} // namespace CppEditor::Internal
|
} // namespace CppEditor::Internal
|
||||||
|
@@ -42,7 +42,7 @@ static QString fileName(const QString &path, const QString &extension)
|
|||||||
|
|
||||||
QString CppToolsJsExtension::headerGuard(const QString &in) const
|
QString CppToolsJsExtension::headerGuard(const QString &in) const
|
||||||
{
|
{
|
||||||
return Utils::headerGuard(in);
|
return fileSettings().headerGuard(Utils::FilePath::fromString(in));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CppToolsJsExtension::licenseTemplate() const
|
QString CppToolsJsExtension::licenseTemplate() const
|
||||||
|
@@ -358,6 +358,11 @@ CppCompletionAssistProcessor *getCppCompletionAssistProcessor()
|
|||||||
return new Internal::InternalCppCompletionAssistProcessor();
|
return new Internal::InternalCppCompletionAssistProcessor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString deriveHeaderGuard(const Utils::FilePath &filePath, ProjectExplorer::Project *project)
|
||||||
|
{
|
||||||
|
return Internal::cppFileSettingsForProject(project).headerGuard(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
bool fileSizeExceedsLimit(const FilePath &filePath, int sizeLimitInMb)
|
bool fileSizeExceedsLimit(const FilePath &filePath, int sizeLimitInMb)
|
||||||
{
|
{
|
||||||
if (sizeLimitInMb <= 0)
|
if (sizeLimitInMb <= 0)
|
||||||
|
@@ -6,7 +6,6 @@
|
|||||||
#include "cppeditor_global.h"
|
#include "cppeditor_global.h"
|
||||||
|
|
||||||
#include "clangdiagnosticconfig.h"
|
#include "clangdiagnosticconfig.h"
|
||||||
#include "compileroptionsbuilder.h"
|
|
||||||
#include "projectpart.h"
|
#include "projectpart.h"
|
||||||
|
|
||||||
#include <texteditor/quickfix.h>
|
#include <texteditor/quickfix.h>
|
||||||
@@ -65,6 +64,9 @@ quickFixOperations(const TextEditor::AssistInterface *interface);
|
|||||||
|
|
||||||
CppCompletionAssistProcessor CPPEDITOR_EXPORT *getCppCompletionAssistProcessor();
|
CppCompletionAssistProcessor CPPEDITOR_EXPORT *getCppCompletionAssistProcessor();
|
||||||
|
|
||||||
|
QString CPPEDITOR_EXPORT
|
||||||
|
deriveHeaderGuard(const Utils::FilePath &filePath, ProjectExplorer::Project *project);
|
||||||
|
|
||||||
enum class CacheUsage { ReadWrite, ReadOnly };
|
enum class CacheUsage { ReadWrite, ReadOnly };
|
||||||
|
|
||||||
Utils::FilePath CPPEDITOR_EXPORT correspondingHeaderOrSource(
|
Utils::FilePath CPPEDITOR_EXPORT correspondingHeaderOrSource(
|
||||||
|
@@ -388,7 +388,7 @@ private:
|
|||||||
= Utils::transform<QStringList>(state->namespacePath, [&](const Namespace *ns) {
|
= Utils::transform<QStringList>(state->namespacePath, [&](const Namespace *ns) {
|
||||||
return ov.prettyName(ns->name());
|
return ov.prettyName(ns->name());
|
||||||
});
|
});
|
||||||
const QString headerGuard = Utils::headerGuard(headerFileName);
|
const QString headerGuard = fileSettings.headerGuard(headerFilePath);
|
||||||
if (fileSettings.headerPragmaOnce) {
|
if (fileSettings.headerPragmaOnce) {
|
||||||
headerContent.append("#pragma once\n");
|
headerContent.append("#pragma once\n");
|
||||||
} else {
|
} else {
|
||||||
|
@@ -27,6 +27,8 @@ const char SHOW_LOG[] = "showLog";
|
|||||||
const char SHOW_WARNING[] = "showWarning";
|
const char SHOW_WARNING[] = "showWarning";
|
||||||
const char SHOW_ERROR[] = "showError";
|
const char SHOW_ERROR[] = "showError";
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Debugger::Internal {
|
namespace Debugger::Internal {
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
@@ -90,8 +92,8 @@ Console::Console()
|
|||||||
m_showDebug.setLabelText(Tr::tr("Show debug, log, and info messages."));
|
m_showDebug.setLabelText(Tr::tr("Show debug, log, and info messages."));
|
||||||
m_showDebug.setToolTip(Tr::tr("Show debug, log, and info messages."));
|
m_showDebug.setToolTip(Tr::tr("Show debug, log, and info messages."));
|
||||||
m_showDebug.setValue(true);
|
m_showDebug.setValue(true);
|
||||||
m_showDebug.action()->setIcon(Utils::Icons::INFO_TOOLBAR.icon());
|
m_showDebug.setIcon(Icons::INFO_TOOLBAR.icon());
|
||||||
connect(&m_showDebug, &Utils::BoolAspect::changed,
|
connect(&m_showDebug, &BoolAspect::changed,
|
||||||
proxyModel, [this, proxyModel] { proxyModel->setShowLogs(m_showDebug()); });
|
proxyModel, [this, proxyModel] { proxyModel->setShowLogs(m_showDebug()); });
|
||||||
m_showDebugButton->setDefaultAction(m_showDebug.action());
|
m_showDebugButton->setDefaultAction(m_showDebug.action());
|
||||||
|
|
||||||
@@ -102,8 +104,8 @@ Console::Console()
|
|||||||
m_showWarning.setLabelText(Tr::tr("Show warning messages."));
|
m_showWarning.setLabelText(Tr::tr("Show warning messages."));
|
||||||
m_showWarning.setToolTip(Tr::tr("Show warning messages."));
|
m_showWarning.setToolTip(Tr::tr("Show warning messages."));
|
||||||
m_showWarning.setValue(true);
|
m_showWarning.setValue(true);
|
||||||
m_showWarning.action()->setIcon(Utils::Icons::WARNING_TOOLBAR.icon());
|
m_showWarning.setIcon(Icons::WARNING_TOOLBAR.icon());
|
||||||
connect(m_showWarning.action(), &QAction::toggled,
|
connect(&m_showWarning, &BoolAspect::changed,
|
||||||
proxyModel, [this, proxyModel] { proxyModel->setShowWarnings(m_showWarning()); });
|
proxyModel, [this, proxyModel] { proxyModel->setShowWarnings(m_showWarning()); });
|
||||||
m_showWarningButton->setDefaultAction(m_showWarning.action());
|
m_showWarningButton->setDefaultAction(m_showWarning.action());
|
||||||
|
|
||||||
@@ -114,8 +116,8 @@ Console::Console()
|
|||||||
m_showError.setLabelText(Tr::tr("Show error messages."));
|
m_showError.setLabelText(Tr::tr("Show error messages."));
|
||||||
m_showError.setToolTip(Tr::tr("Show error messages."));
|
m_showError.setToolTip(Tr::tr("Show error messages."));
|
||||||
m_showError.setValue(true);
|
m_showError.setValue(true);
|
||||||
m_showError.action()->setIcon(Utils::Icons::CRITICAL_TOOLBAR.icon());
|
m_showError.setIcon(Icons::CRITICAL_TOOLBAR.icon());
|
||||||
connect(m_showError.action(), &QAction::toggled,
|
connect(&m_showError, &BoolAspect::changed,
|
||||||
proxyModel, [this, proxyModel] { proxyModel->setShowErrors(m_showError()); });
|
proxyModel, [this, proxyModel] { proxyModel->setShowErrors(m_showError()); });
|
||||||
m_showErrorButton->setDefaultAction(m_showError.action());
|
m_showErrorButton->setDefaultAction(m_showError.action());
|
||||||
|
|
||||||
|
@@ -125,9 +125,6 @@ public:
|
|||||||
// Used by Valgrind
|
// Used by Valgrind
|
||||||
QStringList expectedSignals;
|
QStringList expectedSignals;
|
||||||
|
|
||||||
// For QNX debugging
|
|
||||||
bool useCtrlCStub = false;
|
|
||||||
|
|
||||||
// Used by Android to avoid false positives on warnOnRelease
|
// Used by Android to avoid false positives on warnOnRelease
|
||||||
bool skipExecutableValidation = false;
|
bool skipExecutableValidation = false;
|
||||||
bool useTargetAsync = false;
|
bool useTargetAsync = false;
|
||||||
|
@@ -440,8 +440,11 @@ static DebuggerItem::MatchLevel matchSingle(const Abi &debuggerAbi, const Abi &t
|
|||||||
return matchOnMultiarch;
|
return matchOnMultiarch;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debuggerAbi.wordWidth() == 64 && targetAbi.wordWidth() == 32)
|
if (debuggerAbi.wordWidth() == 64 && targetAbi.wordWidth() == 32) {
|
||||||
return DebuggerItem::MatchesSomewhat;
|
return HostOsInfo::isWindowsHost() && engineType == CdbEngineType
|
||||||
|
? DebuggerItem::MatchesPerfectly
|
||||||
|
: DebuggerItem::MatchesSomewhat;
|
||||||
|
}
|
||||||
if (debuggerAbi.wordWidth() != 0 && debuggerAbi.wordWidth() != targetAbi.wordWidth())
|
if (debuggerAbi.wordWidth() != 0 && debuggerAbi.wordWidth() != targetAbi.wordWidth())
|
||||||
return matchOnMultiarch;
|
return matchOnMultiarch;
|
||||||
|
|
||||||
|
@@ -783,6 +783,12 @@ void DebuggerItemModel::readDebuggers(const FilePath &fileName, bool isSystem)
|
|||||||
.arg(item.command().toUserOutput(), item.id().toString(), fileName.toUserOutput());
|
.arg(item.command().toUserOutput(), item.id().toString(), fileName.toUserOutput());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (item.engineType() == CdbEngineType
|
||||||
|
&& Abi::abisOfBinary(item.command()).value(0).wordWidth() == 32) {
|
||||||
|
qWarning() << QString("32 bit CDB \"%1\" (%2) read from \"%3\" dropped since it is not supported anymore.")
|
||||||
|
.arg(item.command().toUserOutput(), item.id().toString(), fileName.toUserOutput());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// FIXME: During startup, devices are not yet available, so we cannot check if the file still exists.
|
// FIXME: During startup, devices are not yet available, so we cannot check if the file still exists.
|
||||||
if (!item.command().needsDevice() && !item.command().isExecutableFile()) {
|
if (!item.command().needsDevice() && !item.command().isExecutableFile()) {
|
||||||
qWarning() << QString("DebuggerItem \"%1\" (%2) read from \"%3\" dropped since the command is not executable.")
|
qWarning() << QString("DebuggerItem \"%1\" (%2) read from \"%3\" dropped since the command is not executable.")
|
||||||
|
@@ -388,6 +388,15 @@ public:
|
|||||||
k->setValue(DebuggerKitAspect::id(), bestLevel != DebuggerItem::DoesNotMatch ? bestItem.id() : QVariant());
|
k->setValue(DebuggerKitAspect::id(), bestLevel != DebuggerItem::DoesNotMatch ? bestItem.id() : QVariant());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fix(Kit *k) override
|
||||||
|
{
|
||||||
|
const QVariant id = k->value(DebuggerKitAspect::id());
|
||||||
|
if (Utils::anyOf(DebuggerItemManager::debuggers(), Utils::equal(&DebuggerItem::id, id)))
|
||||||
|
return;
|
||||||
|
k->removeKeySilently(DebuggerKitAspect::id());
|
||||||
|
setup(k);
|
||||||
|
}
|
||||||
|
|
||||||
KitAspect *createKitAspect(Kit *k) const override
|
KitAspect *createKitAspect(Kit *k) const override
|
||||||
{
|
{
|
||||||
return new Internal::DebuggerKitAspectImpl(k, this);
|
return new Internal::DebuggerKitAspectImpl(k, this);
|
||||||
|
@@ -276,11 +276,6 @@ void DebuggerRunTool::setSkipExecutableValidation(bool on)
|
|||||||
m_runParameters.skipExecutableValidation = on;
|
m_runParameters.skipExecutableValidation = on;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerRunTool::setUseCtrlCStub(bool on)
|
|
||||||
{
|
|
||||||
m_runParameters.useCtrlCStub = on;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebuggerRunTool::setBreakOnMain(bool on)
|
void DebuggerRunTool::setBreakOnMain(bool on)
|
||||||
{
|
{
|
||||||
m_runParameters.breakOnMain = on;
|
m_runParameters.breakOnMain = on;
|
||||||
|
@@ -100,7 +100,6 @@ protected:
|
|||||||
void setRemoteChannel(const QUrl &url);
|
void setRemoteChannel(const QUrl &url);
|
||||||
void setUseTargetAsync(bool on);
|
void setUseTargetAsync(bool on);
|
||||||
void setSkipExecutableValidation(bool on);
|
void setSkipExecutableValidation(bool on);
|
||||||
void setUseCtrlCStub(bool on);
|
|
||||||
|
|
||||||
void setIosPlatform(const QString &platform);
|
void setIosPlatform(const QString &platform);
|
||||||
void setDeviceSymbolsRoot(const QString &deviceSymbolsRoot);
|
void setDeviceSymbolsRoot(const QString &deviceSymbolsRoot);
|
||||||
|
@@ -124,6 +124,7 @@ const char notCompatibleMessage[] = "is not compatible with target architecture"
|
|||||||
GdbEngine::GdbEngine()
|
GdbEngine::GdbEngine()
|
||||||
{
|
{
|
||||||
m_gdbProc.setProcessMode(ProcessMode::Writer);
|
m_gdbProc.setProcessMode(ProcessMode::Writer);
|
||||||
|
m_gdbProc.setUseCtrlCStub(true);
|
||||||
|
|
||||||
setObjectName("GdbEngine");
|
setObjectName("GdbEngine");
|
||||||
setDebuggerName("GDB");
|
setDebuggerName("GDB");
|
||||||
@@ -673,28 +674,9 @@ void GdbEngine::interruptInferior()
|
|||||||
} else {
|
} else {
|
||||||
showStatusMessage(Tr::tr("Stop requested..."), 5000);
|
showStatusMessage(Tr::tr("Stop requested..."), 5000);
|
||||||
showMessage("TRYING TO INTERRUPT INFERIOR");
|
showMessage("TRYING TO INTERRUPT INFERIOR");
|
||||||
if (HostOsInfo::isWindowsHost() && !m_isQnxGdb) {
|
|
||||||
IDevice::ConstPtr dev = device();
|
|
||||||
QTC_ASSERT(dev, notifyInferiorStopFailed(); return);
|
|
||||||
DeviceProcessSignalOperation::Ptr signalOperation = dev->signalOperation();
|
|
||||||
QTC_ASSERT(signalOperation, notifyInferiorStopFailed(); return);
|
|
||||||
connect(signalOperation.get(), &DeviceProcessSignalOperation::finished,
|
|
||||||
this, [this, signalOperation](const QString &error) {
|
|
||||||
if (error.isEmpty()) {
|
|
||||||
showMessage("Interrupted " + QString::number(inferiorPid()));
|
|
||||||
notifyInferiorStopOk();
|
|
||||||
} else {
|
|
||||||
showMessage(error, LogError);
|
|
||||||
notifyInferiorStopFailed();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
signalOperation->setDebuggerCommand(runParameters().debugger.command.executable());
|
|
||||||
signalOperation->interruptProcess(inferiorPid());
|
|
||||||
} else {
|
|
||||||
interruptInferior2();
|
interruptInferior2();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void GdbEngine::runCommand(const DebuggerCommand &command)
|
void GdbEngine::runCommand(const DebuggerCommand &command)
|
||||||
{
|
{
|
||||||
@@ -1265,9 +1247,11 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
|
|||||||
handleStop1(data);
|
handleStop1(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString stopSignal(const Abi &abi)
|
static QStringList stopSignals(const Abi &abi)
|
||||||
{
|
{
|
||||||
return QLatin1String(abi.os() == Abi::WindowsOS ? "SIGTRAP" : "SIGINT");
|
static QStringList winSignals = { "SIGTRAP", "SIGINT" };
|
||||||
|
static QStringList unixSignals = { "SIGINT" };
|
||||||
|
return abi.os() == Abi::WindowsOS ? winSignals : unixSignals;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::handleStop1(const GdbMi &data)
|
void GdbEngine::handleStop1(const GdbMi &data)
|
||||||
@@ -1416,7 +1400,7 @@ void GdbEngine::handleStop2(const GdbMi &data)
|
|||||||
QString meaning = data["signal-meaning"].data();
|
QString meaning = data["signal-meaning"].data();
|
||||||
// Ignore these as they are showing up regularly when
|
// Ignore these as they are showing up regularly when
|
||||||
// stopping debugging.
|
// stopping debugging.
|
||||||
if (name == stopSignal(rp.toolChainAbi) || rp.expectedSignals.contains(name)) {
|
if (stopSignals(rp.toolChainAbi).contains(name) || rp.expectedSignals.contains(name)) {
|
||||||
showMessage(name + " CONSIDERED HARMLESS. CONTINUING.");
|
showMessage(name + " CONSIDERED HARMLESS. CONTINUING.");
|
||||||
} else if (m_isQnxGdb && name == "0" && meaning == "Signal 0") {
|
} else if (m_isQnxGdb && name == "0" && meaning == "Signal 0") {
|
||||||
showMessage("SIGNAL 0 CONSIDERED BOGUS.");
|
showMessage("SIGNAL 0 CONSIDERED BOGUS.");
|
||||||
@@ -3817,9 +3801,6 @@ void GdbEngine::setupEngine()
|
|||||||
CHECK_STATE(EngineSetupRequested);
|
CHECK_STATE(EngineSetupRequested);
|
||||||
showMessage("TRYING TO START ADAPTER");
|
showMessage("TRYING TO START ADAPTER");
|
||||||
|
|
||||||
if (isRemoteEngine())
|
|
||||||
m_gdbProc.setUseCtrlCStub(runParameters().useCtrlCStub); // This is only set for QNX
|
|
||||||
|
|
||||||
const DebuggerRunParameters &rp = runParameters();
|
const DebuggerRunParameters &rp = runParameters();
|
||||||
CommandLine gdbCommand = rp.debugger.command;
|
CommandLine gdbCommand = rp.debugger.command;
|
||||||
|
|
||||||
@@ -4314,7 +4295,6 @@ void GdbEngine::interruptLocalInferior(qint64 pid)
|
|||||||
showMessage("TRYING TO INTERRUPT INFERIOR BEFORE PID WAS OBTAINED", LogError);
|
showMessage("TRYING TO INTERRUPT INFERIOR BEFORE PID WAS OBTAINED", LogError);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QString errorMessage;
|
|
||||||
if (runParameters().runAsRoot) {
|
if (runParameters().runAsRoot) {
|
||||||
Environment env = Environment::systemEnvironment();
|
Environment env = Environment::systemEnvironment();
|
||||||
RunControl::provideAskPassEntry(env);
|
RunControl::provideAskPassEntry(env);
|
||||||
@@ -4323,11 +4303,8 @@ void GdbEngine::interruptLocalInferior(qint64 pid)
|
|||||||
proc.setEnvironment(env);
|
proc.setEnvironment(env);
|
||||||
proc.start();
|
proc.start();
|
||||||
proc.waitForFinished();
|
proc.waitForFinished();
|
||||||
} else if (interruptProcess(pid, GdbEngineType, &errorMessage)) {
|
|
||||||
showMessage("Interrupted " + QString::number(pid));
|
|
||||||
} else {
|
} else {
|
||||||
showMessage(errorMessage, LogError);
|
m_gdbProc.interrupt();
|
||||||
notifyInferiorStopFailed();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -143,7 +143,7 @@ void PdbEngine::handlePdbStarted()
|
|||||||
void PdbEngine::interruptInferior()
|
void PdbEngine::interruptInferior()
|
||||||
{
|
{
|
||||||
QString error;
|
QString error;
|
||||||
interruptProcess(m_proc.processId(), GdbEngineType, &error);
|
interruptProcess(m_proc.processId(), &error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PdbEngine::executeStepIn(bool)
|
void PdbEngine::executeStepIn(bool)
|
||||||
|
@@ -23,128 +23,23 @@ static inline QString msgCannotInterrupt(qint64 pid, const QString &why)
|
|||||||
# define PROCESS_SUSPEND_RESUME (0x0800)
|
# define PROCESS_SUSPEND_RESUME (0x0800)
|
||||||
#endif // PROCESS_SUSPEND_RESUME
|
#endif // PROCESS_SUSPEND_RESUME
|
||||||
|
|
||||||
static BOOL isWow64Process(HANDLE hproc)
|
|
||||||
{
|
|
||||||
using LPFN_ISWOW64PROCESS = BOOL (WINAPI*)(HANDLE, PBOOL);
|
|
||||||
|
|
||||||
BOOL ret = false;
|
|
||||||
|
|
||||||
static LPFN_ISWOW64PROCESS fnIsWow64Process = NULL;
|
|
||||||
if (!fnIsWow64Process) {
|
|
||||||
if (HMODULE hModule = GetModuleHandle(L"kernel32.dll"))
|
|
||||||
fnIsWow64Process = reinterpret_cast<LPFN_ISWOW64PROCESS>(GetProcAddress(hModule, "IsWow64Process"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fnIsWow64Process) {
|
|
||||||
qWarning("Cannot retrieve symbol 'IsWow64Process'.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fnIsWow64Process(hproc, &ret)) {
|
|
||||||
qWarning("IsWow64Process() failed for %p: %s",
|
|
||||||
hproc, qPrintable(Utils::winErrorMessage(GetLastError())));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open the process and break into it
|
// Open the process and break into it
|
||||||
bool Debugger::Internal::interruptProcess(qint64 pID, int engineType, QString *errorMessage, const bool engineExecutableIs64Bit)
|
bool Debugger::Internal::interruptProcess(qint64 pID, QString *errorMessage)
|
||||||
{
|
{
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
HANDLE inferior = NULL;
|
HANDLE inferior = NULL;
|
||||||
do {
|
const DWORD rights = PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION | PROCESS_VM_OPERATION
|
||||||
const DWORD rights = PROCESS_QUERY_INFORMATION|PROCESS_SET_INFORMATION
|
| PROCESS_VM_WRITE | PROCESS_VM_READ | PROCESS_DUP_HANDLE
|
||||||
|PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ
|
| PROCESS_TERMINATE | PROCESS_CREATE_THREAD | PROCESS_SUSPEND_RESUME;
|
||||||
|PROCESS_DUP_HANDLE|PROCESS_TERMINATE|PROCESS_CREATE_THREAD|PROCESS_SUSPEND_RESUME;
|
|
||||||
inferior = OpenProcess(rights, FALSE, DWORD(pID));
|
inferior = OpenProcess(rights, FALSE, DWORD(pID));
|
||||||
if (inferior == NULL) {
|
if (inferior == NULL) {
|
||||||
*errorMessage = QString::fromLatin1("Cannot open process %1: %2").
|
*errorMessage = QString::fromLatin1("Cannot open process %1: %2")
|
||||||
arg(pID).arg(Utils::winErrorMessage(GetLastError()));
|
.arg(pID)
|
||||||
break;
|
.arg(Utils::winErrorMessage(GetLastError()));
|
||||||
}
|
} else if (ok = DebugBreakProcess(inferior); !ok) {
|
||||||
|
|
||||||
enum DebugBreakApi {
|
|
||||||
UseDebugBreakApi,
|
|
||||||
UseWin64Interrupt,
|
|
||||||
UseWin32Interrupt
|
|
||||||
};
|
|
||||||
/*
|
|
||||||
Windows 64 bit has a 32 bit subsystem (WOW64) which makes it possible to run a
|
|
||||||
32 bit application inside a 64 bit environment.
|
|
||||||
When GDB is used DebugBreakProcess must be called from the same system (32/64 bit) running
|
|
||||||
the inferior. If CDB is used we could in theory break wow64 processes,
|
|
||||||
but the break is actually a wow64 breakpoint. CDB is configured to ignore these
|
|
||||||
breakpoints, because they also appear on module loading.
|
|
||||||
Therefore we need helper executables (win(32/64)interrupt.exe) on Windows 64 bit calling
|
|
||||||
DebugBreakProcess from the correct system.
|
|
||||||
|
|
||||||
DebugBreak matrix for windows
|
|
||||||
|
|
||||||
Api = UseDebugBreakApi
|
|
||||||
Win64 = UseWin64Interrupt
|
|
||||||
Win32 = UseWin32Interrupt
|
|
||||||
N/A = This configuration is not possible
|
|
||||||
|
|
||||||
| Windows 32bit | Windows 64bit
|
|
||||||
| QtCreator 32bit | QtCreator 32bit | QtCreator 64bit
|
|
||||||
| Inferior 32bit | Inferior 32bit | Inferior 64bit | Inferior 32bit | Inferior 64bit |
|
|
||||||
----------|-----------------|-----------------|-----------------|-----------------|----------------|
|
|
||||||
CDB 32bit | Api | Api | NA | Win32 | NA |
|
|
||||||
64bit | NA | Win64 | Win64 | Api | Api |
|
|
||||||
----------|-----------------|-----------------|-----------------|-----------------|----------------|
|
|
||||||
GDB 32bit | Api | Api | NA | Win32 | NA |
|
|
||||||
64bit | NA | Api | Win64 | Win32 | Api |
|
|
||||||
----------|-----------------|-----------------|-----------------|-----------------|----------------|
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
DebugBreakApi breakApi = UseDebugBreakApi;
|
|
||||||
#ifdef Q_OS_WIN64
|
|
||||||
if ((engineType == GdbEngineType && isWow64Process(inferior))
|
|
||||||
|| (engineType == CdbEngineType && !engineExecutableIs64Bit)) {
|
|
||||||
breakApi = UseWin32Interrupt;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (isWow64Process(GetCurrentProcess())
|
|
||||||
&& ((engineType == CdbEngineType && engineExecutableIs64Bit)
|
|
||||||
|| (engineType == GdbEngineType && !isWow64Process(inferior)))) {
|
|
||||||
breakApi = UseWin64Interrupt;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (breakApi == UseDebugBreakApi) {
|
|
||||||
ok = DebugBreakProcess(inferior);
|
|
||||||
if (!ok)
|
|
||||||
*errorMessage = "DebugBreakProcess failed: " + Utils::winErrorMessage(GetLastError());
|
*errorMessage = "DebugBreakProcess failed: " + Utils::winErrorMessage(GetLastError());
|
||||||
} else {
|
|
||||||
const QString executable = breakApi == UseWin32Interrupt
|
|
||||||
? QCoreApplication::applicationDirPath() + "/win32interrupt.exe"
|
|
||||||
: QCoreApplication::applicationDirPath() + "/win64interrupt.exe";
|
|
||||||
if (!QFileInfo::exists(executable)) {
|
|
||||||
*errorMessage = QString::fromLatin1(
|
|
||||||
"%1 does not exist. If you have built %2 "
|
|
||||||
"on your own, checkout "
|
|
||||||
"https://code.qt.io/cgit/qt-creator/binary-artifacts.git/.")
|
|
||||||
.arg(QDir::toNativeSeparators(executable),
|
|
||||||
QGuiApplication::applicationDisplayName());
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
switch (QProcess::execute(executable, QStringList(QString::number(pID)))) {
|
|
||||||
case -2:
|
|
||||||
*errorMessage = QString::fromLatin1("Cannot start %1. Check src\\tools\\win64interrupt\\win64interrupt.c for more information.").
|
|
||||||
arg(QDir::toNativeSeparators(executable));
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
ok = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
*errorMessage = QDir::toNativeSeparators(executable)
|
|
||||||
+ " could not break the process.";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (false);
|
|
||||||
if (inferior != NULL)
|
if (inferior != NULL)
|
||||||
CloseHandle(inferior);
|
CloseHandle(inferior);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
@@ -159,8 +54,7 @@ GDB 32bit | Api | Api | NA | Win32
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
bool Debugger::Internal::interruptProcess(qint64 pID, int /* engineType */,
|
bool Debugger::Internal::interruptProcess(qint64 pID, QString *errorMessage)
|
||||||
QString *errorMessage, const bool /*engineExecutableIs64Bit*/)
|
|
||||||
{
|
{
|
||||||
if (pID <= 0) {
|
if (pID <= 0) {
|
||||||
*errorMessage = msgCannotInterrupt(pID, QString::fromLatin1("Invalid process id."));
|
*errorMessage = msgCannotInterrupt(pID, QString::fromLatin1("Invalid process id."));
|
||||||
|
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
namespace Debugger::Internal {
|
namespace Debugger::Internal {
|
||||||
|
|
||||||
bool interruptProcess(qint64 pID, int engineType, QString *errorMessage,
|
bool interruptProcess(qint64 pID, QString *errorMessage);
|
||||||
const bool engineExecutableIs64Bit = false);
|
|
||||||
|
|
||||||
} // Debugger::Internal
|
} // Debugger::Internal
|
||||||
|
@@ -904,7 +904,7 @@ static ConsoleItem *constructLogItemTree(const QVariant &result, const QString &
|
|||||||
if (child)
|
if (child)
|
||||||
item->appendChild(child);
|
item->appendChild(child);
|
||||||
}
|
}
|
||||||
} else if (result.canConvert(QMetaType::QString)) {
|
} else if (result.canConvert(QMetaType(QMetaType::QString))) {
|
||||||
item = new ConsoleItem(ConsoleItem::DefaultType, result.toString());
|
item = new ConsoleItem(ConsoleItem::DefaultType, result.toString());
|
||||||
} else {
|
} else {
|
||||||
item = new ConsoleItem(ConsoleItem::DefaultType, "Unknown Value");
|
item = new ConsoleItem(ConsoleItem::DefaultType, "Unknown Value");
|
||||||
|
@@ -25,7 +25,7 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_qtc_plugin(Designer
|
add_qtc_plugin(Designer
|
||||||
PLUGIN_CLASS FormEditorPlugin
|
PLUGIN_CLASS DesignerPlugin
|
||||||
CONDITION TARGET Qt::DesignerComponentsPrivate AND TARGET Qt::Designer
|
CONDITION TARGET Qt::DesignerComponentsPrivate AND TARGET Qt::Designer
|
||||||
DEPENDS designerintegrationv2
|
DEPENDS designerintegrationv2
|
||||||
Qt::Designer Qt::PrintSupport Qt::DesignerComponentsPrivate
|
Qt::Designer Qt::PrintSupport Qt::DesignerComponentsPrivate
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#include <extensionsystem/pluginmanager.h>
|
#include <extensionsystem/pluginmanager.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <cppeditor/abstracteditorsupport.h>
|
#include <cppeditor/abstracteditorsupport.h>
|
||||||
|
#include <cppeditor/cpptoolsreuse.h>
|
||||||
#include <projectexplorer/projecttree.h>
|
#include <projectexplorer/projecttree.h>
|
||||||
#include <qtsupport/codegenerator.h>
|
#include <qtsupport/codegenerator.h>
|
||||||
#include <qtsupport/codegensettings.h>
|
#include <qtsupport/codegensettings.h>
|
||||||
@@ -75,7 +76,8 @@ bool QtDesignerFormClassCodeGenerator::generateCpp(const FormClassWizardParamete
|
|||||||
const QString sourceLicense = CppEditor::AbstractEditorSupport::licenseTemplate(
|
const QString sourceLicense = CppEditor::AbstractEditorSupport::licenseTemplate(
|
||||||
project, FilePath::fromString(parameters.sourceFile), parameters.className);
|
project, FilePath::fromString(parameters.sourceFile), parameters.className);
|
||||||
// Include guards
|
// Include guards
|
||||||
const QString guard = Utils::headerGuard(parameters.headerFile);
|
const QString guard
|
||||||
|
= CppEditor::deriveHeaderGuard(FilePath::fromString(parameters.headerFile), project);
|
||||||
|
|
||||||
const QString uiInclude = "ui_" + QFileInfo(parameters.uiFile).completeBaseName() + ".h";
|
const QString uiInclude = "ui_" + QFileInfo(parameters.uiFile).completeBaseName() + ".h";
|
||||||
|
|
||||||
|
@@ -39,9 +39,9 @@ QString EffectComposerContextObject::convertColorToString(const QVariant &color)
|
|||||||
{
|
{
|
||||||
QString colorString;
|
QString colorString;
|
||||||
QColor theColor;
|
QColor theColor;
|
||||||
if (color.canConvert(QVariant::Color)) {
|
if (color.canConvert(QMetaType(QMetaType::QColor))) {
|
||||||
theColor = color.value<QColor>();
|
theColor = color.value<QColor>();
|
||||||
} else if (color.canConvert(QVariant::Vector3D)) {
|
} else if (color.canConvert(QMetaType(QMetaType::QVector3D))) {
|
||||||
auto vec = color.value<QVector3D>();
|
auto vec = color.value<QVector3D>();
|
||||||
theColor = QColor::fromRgbF(vec.x(), vec.y(), vec.z());
|
theColor = QColor::fromRgbF(vec.x(), vec.y(), vec.z());
|
||||||
}
|
}
|
||||||
|
@@ -548,6 +548,13 @@ static void registerLuaApi()
|
|||||||
// ... then register the settings.
|
// ... then register the settings.
|
||||||
LanguageClientManager::registerClientSettings(client);
|
LanguageClientManager::registerClientSettings(client);
|
||||||
|
|
||||||
|
// and the client type.
|
||||||
|
ClientType type;
|
||||||
|
type.id = client->m_settingsTypeId;
|
||||||
|
type.name = luaClient->m_name;
|
||||||
|
type.userAddable = false;
|
||||||
|
LanguageClientSettings::registerClientType(type);
|
||||||
|
|
||||||
return luaClient;
|
return luaClient;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
{
|
{
|
||||||
|
"$schema": "https://download.qt.io/official_releases/qtcreator/latest/installer_source/jsonschemas/project.json",
|
||||||
|
"files.exclude": [".qtcreator/project.json.user"],
|
||||||
"targets": [
|
"targets": [
|
||||||
{
|
{
|
||||||
"name": "Qt Creator",
|
"name": "Qt Creator",
|
||||||
|
@@ -78,7 +78,7 @@ public:
|
|||||||
const QVariant checkFormat = kit->value(McuDependenciesKitAspect::id());
|
const QVariant checkFormat = kit->value(McuDependenciesKitAspect::id());
|
||||||
if (!checkFormat.isValid() || checkFormat.isNull())
|
if (!checkFormat.isValid() || checkFormat.isNull())
|
||||||
return result;
|
return result;
|
||||||
if (!checkFormat.canConvert(QMetaType::QVariantList))
|
if (!checkFormat.canConvert(QMetaType(QMetaType::QVariantList)))
|
||||||
return {BuildSystemTask(Task::Error, Tr::tr("The MCU dependencies setting value is invalid."))};
|
return {BuildSystemTask(Task::Error, Tr::tr("The MCU dependencies setting value is invalid."))};
|
||||||
|
|
||||||
// check paths defined in cmake variables for given dependencies exist
|
// check paths defined in cmake variables for given dependencies exist
|
||||||
@@ -105,7 +105,7 @@ public:
|
|||||||
QTC_ASSERT(kit, return );
|
QTC_ASSERT(kit, return );
|
||||||
|
|
||||||
const QVariant variant = kit->value(McuDependenciesKitAspect::id());
|
const QVariant variant = kit->value(McuDependenciesKitAspect::id());
|
||||||
if (!variant.isNull() && !variant.canConvert(QMetaType::QVariantList)) {
|
if (!variant.isNull() && !variant.canConvert(QMetaType(QMetaType::QVariantList))) {
|
||||||
qWarning("Kit \"%s\" has a wrong mcu dependencies value set.",
|
qWarning("Kit \"%s\" has a wrong mcu dependencies value set.",
|
||||||
qPrintable(kit->displayName()));
|
qPrintable(kit->displayName()));
|
||||||
McuDependenciesKitAspect::setDependencies(kit, Utils::EnvironmentItems());
|
McuDependenciesKitAspect::setDependencies(kit, Utils::EnvironmentItems());
|
||||||
|
@@ -102,90 +102,20 @@ void DesktopProcessSignalOperation::killProcessSilently(qint64 pid)
|
|||||||
void DesktopProcessSignalOperation::interruptProcessSilently(qint64 pid)
|
void DesktopProcessSignalOperation::interruptProcessSilently(qint64 pid)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
enum SpecialInterrupt { NoSpecialInterrupt, Win32Interrupt, Win64Interrupt };
|
|
||||||
|
|
||||||
bool is64BitSystem = is64BitWindowsSystem();
|
|
||||||
SpecialInterrupt si = NoSpecialInterrupt;
|
|
||||||
if (is64BitSystem)
|
|
||||||
si = is64BitWindowsBinary(m_debuggerCommand) ? Win64Interrupt : Win32Interrupt;
|
|
||||||
/*
|
|
||||||
Windows 64 bit has a 32 bit subsystem (WOW64) which makes it possible to run a
|
|
||||||
32 bit application inside a 64 bit environment.
|
|
||||||
When GDB is used DebugBreakProcess must be called from the same system (32/64 bit) running
|
|
||||||
the inferior. If CDB is used we could in theory break wow64 processes,
|
|
||||||
but the break is actually a wow64 breakpoint. CDB is configured to ignore these
|
|
||||||
breakpoints, because they also appear on module loading.
|
|
||||||
Therefore we need helper executables (win(32/64)interrupt.exe) on Windows 64 bit calling
|
|
||||||
DebugBreakProcess from the correct system.
|
|
||||||
|
|
||||||
DebugBreak matrix for windows
|
|
||||||
|
|
||||||
Api = UseDebugBreakApi
|
|
||||||
Win64 = UseWin64InterruptHelper
|
|
||||||
Win32 = UseWin32InterruptHelper
|
|
||||||
N/A = This configuration is not possible
|
|
||||||
|
|
||||||
| Windows 32bit | Windows 64bit
|
|
||||||
| QtCreator 32bit | QtCreator 32bit | QtCreator 64bit
|
|
||||||
| Inferior 32bit | Inferior 32bit | Inferior 64bit | Inferior 32bit | Inferior 64bit
|
|
||||||
----------|-----------------|-----------------|-----------------|-----------------|----------------
|
|
||||||
CDB 32bit | Api | Api | N/A | Win32 | N/A
|
|
||||||
64bit | N/A | Win64 | Win64 | Api | Api
|
|
||||||
----------|-----------------|-----------------|-----------------|-----------------|----------------
|
|
||||||
GDB 32bit | Api | Api | N/A | Win32 | N/A
|
|
||||||
64bit | N/A | N/A | Win64 | N/A | Api
|
|
||||||
----------|-----------------|-----------------|-----------------|-----------------|----------------
|
|
||||||
|
|
||||||
*/
|
|
||||||
HANDLE inferior = NULL;
|
HANDLE inferior = NULL;
|
||||||
do {
|
const DWORD rights = PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION | PROCESS_VM_OPERATION
|
||||||
const DWORD rights = PROCESS_QUERY_INFORMATION|PROCESS_SET_INFORMATION
|
| PROCESS_VM_WRITE | PROCESS_VM_READ | PROCESS_DUP_HANDLE
|
||||||
|PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ
|
| PROCESS_TERMINATE | PROCESS_CREATE_THREAD | PROCESS_SUSPEND_RESUME;
|
||||||
|PROCESS_DUP_HANDLE|PROCESS_TERMINATE|PROCESS_CREATE_THREAD|PROCESS_SUSPEND_RESUME;
|
|
||||||
inferior = OpenProcess(rights, FALSE, pid);
|
inferior = OpenProcess(rights, FALSE, pid);
|
||||||
if (inferior == NULL) {
|
if (inferior == NULL) {
|
||||||
appendMsgCannotInterrupt(pid, Tr::tr("Cannot open process: %1")
|
appendMsgCannotInterrupt(
|
||||||
|
pid, Tr::tr("Cannot open process: %1") + winErrorMessage(GetLastError()));
|
||||||
|
} else if (!DebugBreakProcess(inferior)) {
|
||||||
|
appendMsgCannotInterrupt(
|
||||||
|
pid,
|
||||||
|
Tr::tr("DebugBreakProcess failed:") + QLatin1Char(' ')
|
||||||
+ winErrorMessage(GetLastError()));
|
+ winErrorMessage(GetLastError()));
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
bool creatorIs64Bit = is64BitWindowsBinary(
|
|
||||||
FilePath::fromUserInput(QCoreApplication::applicationFilePath()));
|
|
||||||
if (!is64BitSystem
|
|
||||||
|| si == NoSpecialInterrupt
|
|
||||||
|| (si == Win64Interrupt && creatorIs64Bit)
|
|
||||||
|| (si == Win32Interrupt && !creatorIs64Bit)) {
|
|
||||||
if (!DebugBreakProcess(inferior)) {
|
|
||||||
appendMsgCannotInterrupt(pid, Tr::tr("DebugBreakProcess failed:")
|
|
||||||
+ QLatin1Char(' ') + winErrorMessage(GetLastError()));
|
|
||||||
}
|
|
||||||
} else if (si == Win32Interrupt || si == Win64Interrupt) {
|
|
||||||
QString executable = QCoreApplication::applicationDirPath();
|
|
||||||
executable += si == Win32Interrupt
|
|
||||||
? QLatin1String("/win32interrupt.exe")
|
|
||||||
: QLatin1String("/win64interrupt.exe");
|
|
||||||
if (!QFileInfo::exists(executable)) {
|
|
||||||
appendMsgCannotInterrupt(pid,
|
|
||||||
Tr::tr("%1 does not exist. If you built %2 "
|
|
||||||
"yourself, check out https://code.qt.io/cgit/"
|
|
||||||
"qt-creator/binary-artifacts.git/.")
|
|
||||||
.arg(QDir::toNativeSeparators(executable),
|
|
||||||
QGuiApplication::applicationDisplayName()));
|
|
||||||
}
|
|
||||||
switch (QProcess::execute(executable, QStringList(QString::number(pid)))) {
|
|
||||||
case -2:
|
|
||||||
appendMsgCannotInterrupt(pid, Tr::tr(
|
|
||||||
"Cannot start %1. Check src\\tools\\win64interrupt\\win64interrupt.c "
|
|
||||||
"for more information.").arg(QDir::toNativeSeparators(executable)));
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
appendMsgCannotInterrupt(pid, QDir::toNativeSeparators(executable)
|
|
||||||
+ QLatin1Char(' ') + Tr::tr("could not break the process."));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (false);
|
|
||||||
if (inferior != NULL)
|
if (inferior != NULL)
|
||||||
CloseHandle(inferior);
|
CloseHandle(inferior);
|
||||||
#else
|
#else
|
||||||
|
@@ -1539,7 +1539,7 @@ Tasks EnvironmentKitAspectFactory::validate(const Kit *k) const
|
|||||||
QTC_ASSERT(k, return result);
|
QTC_ASSERT(k, return result);
|
||||||
|
|
||||||
const QVariant variant = k->value(EnvironmentKitAspect::id());
|
const QVariant variant = k->value(EnvironmentKitAspect::id());
|
||||||
if (!variant.isNull() && !variant.canConvert(QMetaType::QVariantList))
|
if (!variant.isNull() && !variant.canConvert(QMetaType(QMetaType::QVariantList)))
|
||||||
result << BuildSystemTask(Task::Error, Tr::tr("The environment setting value is invalid."));
|
result << BuildSystemTask(Task::Error, Tr::tr("The environment setting value is invalid."));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -1550,7 +1550,7 @@ void EnvironmentKitAspectFactory::fix(Kit *k)
|
|||||||
QTC_ASSERT(k, return);
|
QTC_ASSERT(k, return);
|
||||||
|
|
||||||
const QVariant variant = k->value(EnvironmentKitAspect::id());
|
const QVariant variant = k->value(EnvironmentKitAspect::id());
|
||||||
if (!variant.isNull() && !variant.canConvert(QMetaType::QVariantList)) {
|
if (!variant.isNull() && !variant.canConvert(QMetaType(QMetaType::QVariantList))) {
|
||||||
qWarning("Kit \"%s\" has a wrong environment value set.", qPrintable(k->displayName()));
|
qWarning("Kit \"%s\" has a wrong environment value set.", qPrintable(k->displayName()));
|
||||||
EnvironmentKitAspect::setEnvironmentChanges(k, EnvironmentItems());
|
EnvironmentKitAspect::setEnvironmentChanges(k, EnvironmentItems());
|
||||||
}
|
}
|
||||||
|
@@ -253,7 +253,12 @@ public:
|
|||||||
: Project(FOLDER_MIMETYPE, file.isDir() ? file / ".qtcreator" / "project.json" : file)
|
: Project(FOLDER_MIMETYPE, file.isDir() ? file / ".qtcreator" / "project.json" : file)
|
||||||
{
|
{
|
||||||
QTC_CHECK(projectFilePath().absolutePath().ensureWritableDir());
|
QTC_CHECK(projectFilePath().absolutePath().ensureWritableDir());
|
||||||
QTC_CHECK(projectFilePath().ensureExistingFile());
|
if (!projectFilePath().exists() && QTC_GUARD(projectFilePath().ensureExistingFile())) {
|
||||||
|
QJsonObject projectJson;
|
||||||
|
projectJson.insert("$schema", "https://download.qt.io/official_releases/qtcreator/latest/installer_source/jsonschemas/project.json");
|
||||||
|
projectJson.insert(FILES_EXCLUDE_KEY, QJsonArray{QJsonValue(".qtcreator/project.json.user")});
|
||||||
|
projectFilePath().writeFileContents(QJsonDocument(projectJson).toJson());
|
||||||
|
}
|
||||||
|
|
||||||
setId(Id::fromString(WORKSPACE_PROJECT_ID));
|
setId(Id::fromString(WORKSPACE_PROJECT_ID));
|
||||||
setDisplayName(projectDirectory().fileName());
|
setDisplayName(projectDirectory().fileName());
|
||||||
|
@@ -46,9 +46,9 @@ QString MaterialEditorContextObject::convertColorToString(const QVariant &color)
|
|||||||
{
|
{
|
||||||
QString colorString;
|
QString colorString;
|
||||||
QColor theColor;
|
QColor theColor;
|
||||||
if (color.canConvert(QVariant::Color)) {
|
if (color.canConvert(QMetaType(QMetaType::QColor))) {
|
||||||
theColor = color.value<QColor>();
|
theColor = color.value<QColor>();
|
||||||
} else if (color.canConvert(QVariant::Vector3D)) {
|
} else if (color.canConvert(QMetaType(QMetaType::QVector3D))) {
|
||||||
auto vec = color.value<QVector3D>();
|
auto vec = color.value<QVector3D>();
|
||||||
theColor = QColor::fromRgbF(vec.x(), vec.y(), vec.z());
|
theColor = QColor::fromRgbF(vec.x(), vec.y(), vec.z());
|
||||||
}
|
}
|
||||||
|
@@ -87,9 +87,9 @@ QString PropertyEditorContextObject::convertColorToString(const QVariant &color)
|
|||||||
{
|
{
|
||||||
QString colorString;
|
QString colorString;
|
||||||
QColor theColor;
|
QColor theColor;
|
||||||
if (color.canConvert(QVariant::Color)) {
|
if (color.canConvert(QMetaType(QMetaType::QColor))) {
|
||||||
theColor = color.value<QColor>();
|
theColor = color.value<QColor>();
|
||||||
} else if (color.canConvert(QVariant::Vector3D)) {
|
} else if (color.canConvert(QMetaType(QMetaType::QVector3D))) {
|
||||||
auto vec = color.value<QVector3D>();
|
auto vec = color.value<QVector3D>();
|
||||||
theColor = QColor::fromRgbF(vec.x(), vec.y(), vec.z());
|
theColor = QColor::fromRgbF(vec.x(), vec.y(), vec.z());
|
||||||
}
|
}
|
||||||
|
@@ -47,9 +47,9 @@ QString TextureEditorContextObject::convertColorToString(const QVariant &color)
|
|||||||
{
|
{
|
||||||
QString colorString;
|
QString colorString;
|
||||||
QColor theColor;
|
QColor theColor;
|
||||||
if (color.canConvert(QVariant::Color)) {
|
if (color.canConvert(QMetaType(QMetaType::QColor))) {
|
||||||
theColor = color.value<QColor>();
|
theColor = color.value<QColor>();
|
||||||
} else if (color.canConvert(QVariant::Vector3D)) {
|
} else if (color.canConvert(QMetaType(QMetaType::QVector3D))) {
|
||||||
auto vec = color.value<QVector3D>();
|
auto vec = color.value<QVector3D>();
|
||||||
theColor = QColor::fromRgbF(vec.x(), vec.y(), vec.z());
|
theColor = QColor::fromRgbF(vec.x(), vec.y(), vec.z());
|
||||||
}
|
}
|
||||||
|
@@ -107,14 +107,14 @@ static void editValue(const ModelNode &frameNode, const std::pair<qreal, qreal>
|
|||||||
int userType = value.typeId();
|
int userType = value.typeId();
|
||||||
QVariant newValue = dialog->value();
|
QVariant newValue = dialog->value();
|
||||||
|
|
||||||
if (newValue.canConvert(userType)) {
|
if (newValue.canConvert(QMetaType(userType))) {
|
||||||
QVariant newValueConverted = newValue;
|
QVariant newValueConverted = newValue;
|
||||||
bool converted = newValueConverted.convert(userType);
|
bool converted = newValueConverted.convert(QMetaType(userType));
|
||||||
|
|
||||||
if (!converted) {
|
if (!converted) {
|
||||||
// convert() fails for int to double, so we try this combination
|
// convert() fails for int to double, so we try this combination
|
||||||
newValueConverted = newValue;
|
newValueConverted = newValue;
|
||||||
converted = newValueConverted.convert(QMetaType::Double);
|
converted = newValueConverted.convert(QMetaType(QMetaType::Double));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (converted)
|
if (converted)
|
||||||
|
@@ -1565,7 +1565,7 @@ void TextToModelMerger::syncVariantProperty(AbstractProperty &modelProperty,
|
|||||||
const TypeName &astType,
|
const TypeName &astType,
|
||||||
DifferenceHandler &differenceHandler)
|
DifferenceHandler &differenceHandler)
|
||||||
{
|
{
|
||||||
if (astValue.canConvert(QMetaType::QString))
|
if (astValue.canConvert(QMetaType(QMetaType::QString)))
|
||||||
populateQrcMapping(astValue.toString());
|
populateQrcMapping(astValue.toString());
|
||||||
|
|
||||||
if (modelProperty.isVariantProperty()) {
|
if (modelProperty.isVariantProperty()) {
|
||||||
|
@@ -126,7 +126,6 @@ public:
|
|||||||
|
|
||||||
setStartMode(AttachToRemoteServer);
|
setStartMode(AttachToRemoteServer);
|
||||||
setCloseMode(KillAtClose);
|
setCloseMode(KillAtClose);
|
||||||
setUseCtrlCStub(true);
|
|
||||||
setSolibSearchPath(FileUtils::toFilePathList(searchPaths(k)));
|
setSolibSearchPath(FileUtils::toFilePathList(searchPaths(k)));
|
||||||
if (auto qtVersion = dynamic_cast<QnxQtVersion *>(QtSupport::QtKitAspect::qtVersion(k))) {
|
if (auto qtVersion = dynamic_cast<QnxQtVersion *>(QtSupport::QtKitAspect::qtVersion(k))) {
|
||||||
setSysRoot(qtVersion->qnxTarget());
|
setSysRoot(qtVersion->qnxTarget());
|
||||||
@@ -196,7 +195,6 @@ public:
|
|||||||
{
|
{
|
||||||
setId("QnxAttachDebugSupport");
|
setId("QnxAttachDebugSupport");
|
||||||
setUsePortsGatherer(isCppDebugging(), isQmlDebugging());
|
setUsePortsGatherer(isCppDebugging(), isQmlDebugging());
|
||||||
setUseCtrlCStub(true);
|
|
||||||
|
|
||||||
if (isCppDebugging()) {
|
if (isCppDebugging()) {
|
||||||
auto pdebugRunner = new PDebugRunner(runControl, portsGatherer());
|
auto pdebugRunner = new PDebugRunner(runControl, portsGatherer());
|
||||||
|
@@ -4,6 +4,7 @@ add_qtc_plugin(QtApplicationManagerIntegration
|
|||||||
PLUGIN_DEPENDS
|
PLUGIN_DEPENDS
|
||||||
Core Debugger ProjectExplorer
|
Core Debugger ProjectExplorer
|
||||||
QtSupport RemoteLinux
|
QtSupport RemoteLinux
|
||||||
|
PLUGIN_CLASS AppManagerPlugin
|
||||||
DEPENDS Qt::Network Qt::Widgets ExtensionSystem Utils yaml-cpp
|
DEPENDS Qt::Network Qt::Widgets ExtensionSystem Utils yaml-cpp
|
||||||
SOURCES
|
SOURCES
|
||||||
appmanagerconstants.h
|
appmanagerconstants.h
|
||||||
|
@@ -110,6 +110,21 @@ public:
|
|||||||
m_textEditorWidget->setTextDocument(m_document);
|
m_textEditorWidget->setTextDocument(m_document);
|
||||||
m_textEditorWidget->setupGenericHighlighter();
|
m_textEditorWidget->setupGenericHighlighter();
|
||||||
m_textEditorWidget->setMarksVisible(false);
|
m_textEditorWidget->setMarksVisible(false);
|
||||||
|
QObject::connect(
|
||||||
|
m_textEditorWidget,
|
||||||
|
&TextEditorWidget::saveCurrentStateForNavigationHistory,
|
||||||
|
this,
|
||||||
|
&MarkdownEditor::saveCurrentStateForNavigationHistory);
|
||||||
|
QObject::connect(
|
||||||
|
m_textEditorWidget,
|
||||||
|
&TextEditorWidget::addSavedStateToNavigationHistory,
|
||||||
|
this,
|
||||||
|
&MarkdownEditor::addSavedStateToNavigationHistory);
|
||||||
|
QObject::connect(
|
||||||
|
m_textEditorWidget,
|
||||||
|
&TextEditorWidget::addCurrentStateToNavigationHistory,
|
||||||
|
this,
|
||||||
|
&MarkdownEditor::addCurrentStateToNavigationHistory);
|
||||||
auto context = new IContext(this);
|
auto context = new IContext(this);
|
||||||
context->setWidget(m_textEditorWidget);
|
context->setWidget(m_textEditorWidget);
|
||||||
context->setContext(Context(MARKDOWNVIEWER_TEXT_CONTEXT));
|
context->setContext(Context(MARKDOWNVIEWER_TEXT_CONTEXT));
|
||||||
@@ -476,6 +491,18 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void saveCurrentStateForNavigationHistory() { m_savedNavigationState = saveState(); }
|
||||||
|
|
||||||
|
void addSavedStateToNavigationHistory()
|
||||||
|
{
|
||||||
|
EditorManager::addCurrentPositionToNavigationHistory(m_savedNavigationState);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addCurrentStateToNavigationHistory()
|
||||||
|
{
|
||||||
|
EditorManager::addCurrentPositionToNavigationHistory();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTimer m_previewTimer;
|
QTimer m_previewTimer;
|
||||||
bool m_performDelayedUpdate = false;
|
bool m_performDelayedUpdate = false;
|
||||||
@@ -491,6 +518,7 @@ private:
|
|||||||
QAction *m_togglePreviewVisibleAction;
|
QAction *m_togglePreviewVisibleAction;
|
||||||
QAction *m_swapViewsAction;
|
QAction *m_swapViewsAction;
|
||||||
std::optional<QPoint> m_previewRestoreScrollPosition;
|
std::optional<QPoint> m_previewRestoreScrollPosition;
|
||||||
|
QByteArray m_savedNavigationState;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MarkdownEditorFactory final : public IEditorFactory
|
class MarkdownEditorFactory final : public IEditorFactory
|
||||||
|
Reference in New Issue
Block a user