Merge remote-tracking branch 'origin/4.12'

Conflicts:
	src/plugins/cmakeprojectmanager/tealeafreader.cpp
	src/plugins/cmakeprojectmanager/tealeafreader.h
	src/plugins/projectexplorer/miniprojecttargetselector.cpp

Change-Id: I88d85be3903f57a55fddb7901e771a4822db1b85
This commit is contained in:
Eike Ziller
2020-03-04 08:15:50 +01:00
368 changed files with 8945 additions and 6485 deletions

View File

@@ -382,14 +382,12 @@ function(enable_pch target)
endfunction()
if (NOT TARGET QtCreatorPchGui AND NOT TARGET QtCreatorPchConsole)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/empty_pch.c_cpp.in "/*empty file*/")
configure_file(
${CMAKE_CURRENT_BINARY_DIR}/empty_pch.c_cpp.in
${CMAKE_CURRENT_BINARY_DIR}/empty_pch.cpp)
configure_file(
${CMAKE_CURRENT_BINARY_DIR}/empty_pch.c_cpp.in
${CMAKE_CURRENT_BINARY_DIR}/empty_pch.c)
file(GENERATE
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/empty_pch.c
CONTENT "/*empty file*/")
file(GENERATE
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/empty_pch.cpp
CONTENT "/*empty file*/")
_add_pch_target(QtCreatorPchGui
"${PROJECT_SOURCE_DIR}/src/shared/qtcreator_gui_pch.h" Qt5::Widgets)
_add_pch_target(QtCreatorPchConsole
@@ -728,9 +726,10 @@ function(add_qtc_plugin target_name)
string(REGEX REPLACE "^.*=" "" json_value ${_arg_PLUGIN_JSON_IN})
string(REPLACE "$$${json_key}" "${json_value}" plugin_json_in ${plugin_json_in})
endif()
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${name}.json.cmakein" ${plugin_json_in})
configure_file("${CMAKE_CURRENT_BINARY_DIR}/${name}.json.cmakein" "${name}.json")
string(CONFIGURE "${plugin_json_in}" plugin_json)
file(GENERATE
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${name}.json"
CONTENT "${plugin_json}")
endif()
add_library(${target_name} SHARED ${_arg_SOURCES})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

View File

@@ -669,10 +669,18 @@
\l{http://linterrors.com/js/the-array-literal-notation-is-preferrable}
{The array literal notation [] is preferable}.
\row
\li M324
\li Error
\li Hit maximum recursion limit visiting AST, the code model will be unreliable
and most likely invalid
\li
\row
\li M400
\li Warning
\li Duplicate import
\li
\endtable

View File

@@ -54,12 +54,18 @@
\section2 Navigating Between Open Files and Symbols
Use the toolbar to navigate between open files and symbols in use. To browse
backward or forward through your location history, click
\inlineimage prev.png
Use the toolbar, \uicontrol Window menu items, or
\l{General Keyboard Shortcuts}{keyboard shortcuts}
to navigate between open files and symbols in use.
To browse backward or forward through your
location history, click \inlineimage prev.png
(\uicontrol {Go Back}) and \inlineimage next.png
(\uicontrol {Go Forward}).
To return to the last location where you made a change, select
\uicontrol Window > \uicontrol {Go to Last Edit}.
To go to any open file, select it from the \uicontrol {Open files} drop-down
menu (1). To open a context menu that contains commands for managing open
files, right-click the file name or icon on the toolbar. In addition to the
@@ -80,8 +86,7 @@
number in the locator, separated by a colon (:).
\note Other convenient ways of navigating in \QC are provided
by the \l{Keyboard Shortcuts} {keyboard shortcuts} and the
\l{Browsing Project Contents}{sidebar}.
by the \l{Browsing Project Contents}{sidebars}.
\if defined(qtcreator)
\section2 Selecting Parse Context
@@ -187,10 +192,10 @@
the bookmark.
To go to the previous bookmark in the current session, select
\uicontrol Tools \uicontrol Bookmarks > \uicontrol {Previous Bookmark}
\uicontrol Tools > \uicontrol Bookmarks > \uicontrol {Previous Bookmark}
or press \key {Ctrl+,}.
To go to the next bookmark in the current session, select \uicontrol Tools
To go to the next bookmark in the current session, select \uicontrol Tools >
\uicontrol Bookmarks > \uicontrol {Previous Bookmark} or press
\key {Ctrl+.}.
@@ -265,10 +270,10 @@
\section1 Inspecting the Code Model
When you report a bug that is related to the C++ code model, the \QC
developers might ask you to write information about the internal state of
the code model into a log file and to deliver the file to them for
inspection.
When you \l{https://bugreports.qt.io/}{report a bug} that is related to the
C++ code model, the \QC developers might ask you to write information about
the internal state of the code model into a log file and to deliver the file
to them for inspection.
To view information about the C++ code model in the
\uicontrol {C++ Code Model Inspector} dialog and write it to a log file,

View File

@@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
@@ -80,11 +80,11 @@
\image creator-diff-editor.png "Diff editor output in the Edit mode"
The changes are displayed in the \uicontrol Edit mode. Color coding is used
to mark changed lines. By default, light red indicates lines that contain
removed text (painted a darker red) in the left pane and light green
indicates lines that contain added text (painted a darker green) in the
right pane.
The changes are displayed in the \uicontrol Edit mode. Color coding is
used to mark changed lines. By default, red indicates lines that contain
removed text (painted another shade of red) in the left pane and green
indicates lines that contain added text (painted another shade of green)
in the right pane.
To revert the changes, right-click added text and then select
\uicontrol {Revert Chunk} in the context menu. To apply the changes, select

View File

@@ -33,7 +33,7 @@
You can find the locator in the bottom left of the \QC window.
\image qtcreator-locator.png
\image qtcreator-locator.png "List of locator filters"
To activate the locator:
@@ -59,7 +59,7 @@
\li Start typing the filename.
\image qtcreator-locator-open.png
\image qtcreator-locator-open.png "List of files found in the locator"
\li Move to the filename in the list and press \key Enter.
@@ -148,6 +148,9 @@
\li Triggering menu items from the main menu (\c {t})
\li Searching for issues from the \l{https://bugreports.qt.io/}
{Qt Project Bug Tracker} (\c bug).
\if defined(qtcreator)
\li Running external tools (\c x)
\li Using CMake to build the project for the current run configuration
@@ -184,7 +187,7 @@
The locator lists the results.
\image qtcreator-navigate-popup.png
\image qtcreator-locator-example.png "List of files matching the locator filter"
\endlist
@@ -265,7 +268,7 @@
\li Select \uicontrol Add to add a new entry to the list.
\image qtcreator-add-online-doc.png "Filter Configuration dialog"
\image qtcreator-add-online-doc.png "List of URLs in Filter Configuration dialog"
\li Double-click the new entry to specify a URL and a search command.
For example, \c {http://www.google.com/search?q=%1}.
@@ -276,49 +279,48 @@
\section1 Creating Locator Filters
You can create custom locator filters for finding in a directory structure
or on the web.
To quickly access files not directly mentioned in your project, you can
create your own locator filters. That way you can locate files in a
create your own directory filters. That way you can locate files in a
directory structure you have defined.
To create a locator filter:
To create custom locator filters:
\list 1
\li In the locator, select \uicontrol Options >
\uicontrol Configure to open the \uicontrol Locator options.
\image qtcreator-locator-customize.png
\image qtcreator-locator-customize.png "Locator options tab"
\li Click \uicontrol Add.
\li Select \uicontrol Add > \uicontrol {Files in Directories} to add
a directory filter or \uicontrol {URL Template} to add a URL
filter. The settings to specify depend on the filter type.
\li In the \uicontrol {Filter Configuration} dialog:
\image qtcreator-locator-generic-directory-filter.png "Filter Configuration dialog"
\image qtcreator-navigate-customfilter.png
\li In the \uicontrol Name field, enter a name for your filter.
\list
\li In the \uicontrol Directories field, select at least one
directory. The locator searches directories recursively.
\li In the \uicontrol Name field, enter a name for your filter.
\li In the \uicontrol {File pattern} field, specify file patterns to
restrict the search to files that match the pattern.
Use a comma separated list. For example, to search for all
\c {.qml} and \c {.ui.qml} files, enter \c{*.qml,*.ui.qml}
\li In the \uicontrol Directories field, select at least one
directory. The locator searches directories recursively.
\li In the \uicontrol {Exclusion pattern} field, specify file
patterns to omit files from the search.
\li In the \uicontrol {File pattern} field, specify file patterns to
restrict the search to files that match the pattern.
Use a comma separated list. For example, to search for all
\c {.qml} and \c {.ui.qml} files, enter \c{*.qml,*.ui.qml}
\li In the \uicontrol Prefix field, specify the prefix string.
\li In the \uicontrol {Exclusion pattern} field, specify file
patterns to omit files from the search.
To implicitly include the filter even when not typing a prefix
as a part of the search string, select
\uicontrol {Include by default}.
\li In the \uicontrol Prefix field, specify the prefix string.
To implicitly include the filter even when not typing a prefix
as a part of the search string, select
\uicontrol {Include by default}.
\endlist
\li Click \uicontrol OK.
\li Select \uicontrol OK.
\endlist

View File

@@ -38,15 +38,22 @@
\list
\li \l{Completing Code}{Code completion}
\li Sending document formatting requests to the language server to
automatically format documents using the settings specified in
\uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor}
> \uicontrol Behavior
\li Highlighting the symbol under cursor
\li \l{Viewing Function Tooltips}{Viewing function tooltips}
\li \l{Semantic Highlighting}{Semantic highlighting}, as defined in
\l{https://github.com/microsoft/vscode-languageserver-node/pull/367}
{Proposal of the semantic highlighting protocol extension}
\li Navigating in the code by using the \l{Searching with the Locator}
{locator} or \l{Moving to Symbol Definition or Declaration}
{moving to the symbol definition}
\li Inspecting code by viewing the document
\l{Viewing Defined Types and Symbols}{outline}
\li Inspecting code by viewing the document outline in the
\l{Viewing Defined Types and Symbols}{Outline} view or
in the \uicontrol Symbols list on the \l{Using the Editor Toolbar}
{editor toolbar}
\li \l{Finding Symbols}{Finding references to symbols}
\li Code actions
\li Integrating diagnostics from the language server
@@ -123,7 +130,8 @@
The language service client has been mostly tested with Python.
If problems arise when you try it or some other language, please select
\uicontrol Help > \uicontrol {Report Bug} to report them in the Qt Bug
Tracker. The reports should include \QC console output with the environment
\uicontrol Help > \uicontrol {Report Bug} to report them in the
\l{https://bugreports.qt.io/}{Qt Project Bug Tracker}. The reports
should include \QC console output with the environment
variable \c {QT_LOGGING_RULES=qtc.languageclient.*=true} set.
*/

View File

@@ -92,6 +92,12 @@
\QC, \QSDK and other Qt deliverables contain documentation
as .qch files. All the documentation is accessible in the \uicontrol Help mode.
By default, \QC registers only the latest available version of the
documentation for each installed Qt module. To register all installed
documentation, select \uicontrol Tools > \uicontrol Options >
\uicontrol Kits > \uicontrol {Qt Versions} >
\uicontrol {Register documentation}.
To find information in the documentation, select:
\list
@@ -210,6 +216,9 @@
in the \uicontrol {On context help} field. To detach the help window, select
\uicontrol {Always Show in External Window}.
To change this setting in a help view, select the \inlineimage linkicon.png
toolbar button.
\section1 Selecting the Start Page
You can select the page to display when you open the \uicontrol Help mode in the

View File

@@ -73,7 +73,7 @@
\b {Has a reported issue been addressed?}
You can look up any issue in the
\l{https://bugreports.qt.io/}{Qt bug tracker}.
\l{https://bugreports.qt.io/}{Qt Project Bug Tracker}.
\include widgets/creator-faq-qtdesigner.qdocinc qt designer faq

View File

@@ -74,9 +74,12 @@
Each kit consists of a set of values that define one environment, such as a
\l{glossary-device}{device}, compiler, and Qt version. If you know you have
installed a Qt
version, but it is not listed in \uicontrol Tools > \uicontrol Options >
\uicontrol Kits > \uicontrol {Qt Versions}, you must add it.
installed a Qt version, but it is not listed in \uicontrol Tools >
\uicontrol Options > \uicontrol Kits > \uicontrol {Qt Versions}, select
\uicontrol {Link with Qt}.
If the Qt version is still not listed under \uicontrol Auto-detected, select
\uicontrol {Add} to add it manually.
For more information, see \l{Adding Qt Versions}.

View File

@@ -43,7 +43,7 @@
For a list of fixed issues and added features, see the changelog file in
the \c{qtcreator\dist} folder or the \l{https://bugreports.qt.io}
{Qt Bug Tracker}.
{Qt Project Bug Tracker}.
\section1 General Issues

View File

@@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
@@ -42,12 +42,41 @@
\l{glossary-device}{device} manufacturers provide special Qt versions for
developing applications for their devices.
\section1 Registering Installed Qt Versions
\QC automatically detects the Qt versions that are registered by
your system or by installers. To view detailed information for each Qt
version, select it in the list and select \uicontrol Details in the
\uicontrol {Qt version for} section. To add Qt versions, select
\uicontrol Tools > \uicontrol Options > \uicontrol Kits >
\uicontrol {Qt Versions}.
\uicontrol {Qt version for} section.
\image qtcreator-qt-versions.png "Qt Versions tab in Kit options"
To remove invalid Qt versions, select \uicontrol {Clean Up}.
You can link to a Qt that you installed using the Qt Maintenance Tool to
automatically register the installed Qt versions. The mechanism does not
handle Qt versions installed by the system using some other package manager,
such as your Linux distribution, brew on \macos, or Chocolatey on Windows,
nor a self-built Qt.
To link to a Qt installation:
\list 1
\li Select \uicontrol Tools > \uicontrol Options > \uicontrol Kits >
\uicontrol {Qt Versions} > \uicontrol {Link with Qt}.
\image qtcreator-link-with-qt.png "Choose Qt Installation dialog"
\li In the \uicontrol {Qt installation path} field, enter the path to
the directory where you installed Qt.
\li Select \uicontrol {Link with Qt} to automatically register Qt
versions and kits in the Qt installation directory.
\li Select \uicontrol {Restart Now} to restart \QC.
\endlist
To remove the automatically detected Qt versions from the list, select
\uicontrol {Link with Qt} > \uicontrol {Remove Link}.
If a Qt version is still not listed under \uicontrol Auto-detected, select
\uicontrol {Add} to add it manually.
You specify the Qt version to use for each \l{glossary-buildandrun-kit}
{kit} for building and running your projects
@@ -67,8 +96,6 @@
\li Select the Qt version to view and edit it.
\image qtcreator-qt4-qtversions-add.png
\li In the \uicontrol{Version name} field, edit the name that \QC
suggests for the Qt version.
@@ -80,7 +107,10 @@
\endlist
\section1 Documentation
To remove a Qt version that you added manually, select it in the
\uicontrol Manual list and then select \uicontrol Remove.
\section1 Registering Documentation
By default, \QC registers only the latest available version of the documentation for each
installed Qt module.
@@ -109,13 +139,15 @@
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 be able to use that setup with \QC.
\list 1
\li qmake is an executable that understands the -query command line argument.
\li The bin and include directories have to exist. \QC fetches these directories by running \c{qmake -query}.
\li The mkspecs directory should be complete enough to parse .pro files.
\li qmake is an executable that understands the \c -query command line
argument.
\li The \c bin and \c include directories have to exist. \QC fetches
these directories by running \c{qmake -query}.
\li The \c mkspecs directory should be complete enough to parse .pro
files.
\endlist
If your Qt version has no libQtCore.so, \QC is unable to detect the ABI.
If your Qt version has no \c libQtCore.so, \QC is unable to detect the ABI.
*/

View File

@@ -130,8 +130,9 @@
\row
\li {4,1} \l{All Topics}
\row
\li {4,1} \note To report bugs and suggestions to the Qt Bug
Tracker, select \uicontrol {Help > Report Bug}.
\li {4,1} \note To report bugs and suggestions to the
\l{https://bugreports.qt.io/}{Qt Project Bug Tracker},
select \uicontrol {Help > Report Bug}.
To copy and paste detailed information about your system to the
bug report, select \uicontrol Help >
\uicontrol {System Information}.

View File

@@ -151,7 +151,8 @@
instead, select the \uicontrol {Switch to Text Diff Editor} (1) option from
the toolbar. In the inline
diff view, you can use context menu commands to apply, revert, stage, and
unstage hunks, as well as send them to a code pasting service.
unstage chunks or selected lines, as well as send chunks to a code pasting
service.
\section2 Viewing Versioning History and Change Details

View File

@@ -89,7 +89,8 @@
by default. To use the unified diff view instead, select the
\uicontrol {Switch to Unified Diff Editor} (1) option from the toolbar.
In both views, you can use context menu commands to apply, revert, stage,
and unstage hunks, as well as send them to a code pasting service.
and unstage chunks or selected lines, as well as send chunks to a code
pasting service.
\section2 Viewing Git Log
@@ -186,11 +187,18 @@
When you have finished filling out the commit page information, click on
\uicontrol Commit to start committing.
The \uicontrol {Diff Selected Files} button brings up a diff view of the
files selected in the file list. Since the commit page is just another
editor, you can go back to it by closing the diff view. You can also switch
to an open diff view by selecting it in the \uicontrol {Open Documents} view
in the sidebar.
The \uicontrol {Diff Selected Files} button opens a \l{Viewing Git Diff}
{diff view} of the files selected in the file list. Select
\uicontrol {Stage Chunk} in the context menu to stage a chunk or
\uicontrol {Stage Selection} to stage the selected lines.
To unstage chunks or selected lines, select \uicontrol {Unstage Chunk} or
\uicontrol {Unstage Selection} in the context menu. To revert the changes
in a chunk, select \uicontrol {Revert Chunk}.
The commit page is just another editor, and therefore you return to it when
you close the diff view. You can also switch to an open diff view by
selecting it in the \uicontrol {Open Documents} view in the sidebar.
\section2 Amending Commits

View File

@@ -107,8 +107,9 @@
\row
\li {4,1} \l{All Topics}
\row
\li {4,1} \note To report bugs and suggestions to the Qt Bug
Tracker, select \uicontrol {Help > Report Bug}.
\li {4,1} \note To report bugs and suggestions to the
\l{https://bugreports.qt.io/}{Qt Project Bug Tracker},
select \uicontrol {Help > Report Bug}.
To copy and paste detailed information about your system to the
bug report, select \uicontrol Help >
\uicontrol {System Information}.

View File

@@ -161,7 +161,7 @@
or press \key R.
You can use the scale handles to adjust the local x, y, or z scale of an
item. You can ajust the scale across one, two, or three axes, depending
item. You can adjust the scale across one, two, or three axes, depending
on the handle.
To adjust the scale across one axis, select the scale handle attached to

View File

@@ -25,6 +25,7 @@
from dumper import Children
def qdump__boost__bimaps__bimap(d, value):
#leftType = value.type[0]
#rightType = value.type[1]
@@ -64,7 +65,7 @@ def qdump__boost__shared_ptr(d, value):
(vptr, usecount, weakcount) = d.split('pii', pi)
d.check(weakcount >= 0)
d.check(weakcount <= usecount)
d.check(usecount <= 10*1000*1000)
d.check(usecount <= 10 * 1000 * 1000)
d.putItem(d.createValue(px, value.type[0]))
d.putBetterType(value.type)
@@ -105,7 +106,7 @@ def qdump__boost__posix_time__time_duration(d, value):
def qdump__boost__unordered__unordered_set(d, value):
innerType = value.type[0]
if value.type.size() == 6 * d.ptrSize(): # 48 for boost 1.55+, 40 for 1.48
if value.type.size() == 6 * d.ptrSize(): # 48 for boost 1.55+, 40 for 1.48
# boost 1.58 or 1.55
# bases are 3? bytes, and mlf is actually a float, but since
# its followed by size_t maxload, it's # effectively padded to a size_t
@@ -125,6 +126,7 @@ def qdump__boost__unordered__unordered_set(d, value):
if forward:
# boost 1.58
code = 'pp{%s}' % innerType.name
def children(p):
while True:
p, dummy, val = d.split(code, p)
@@ -134,12 +136,13 @@ def qdump__boost__unordered__unordered_set(d, value):
code = '{%s}@p' % innerType.name
(pp, ssize, fields) = d.describeStruct(code)
offset = fields[2].offset()
def children(p):
while True:
val, pad, p = d.split(code, p - offset)
yield val
p = d.extractPointer(buckets + bucketCount * d.ptrSize())
d.putItems(size, children(p), maxNumChild = 10000)
d.putItems(size, children(p), maxNumChild=10000)
def qdump__boost__variant(d, value):

View File

@@ -35,8 +35,9 @@ sys.path.insert(1, os.path.dirname(os.path.abspath(inspect.getfile(inspect.curre
from dumper import DumperBase, SubItem
class FakeVoidType(cdbext.Type):
def __init__(self, name , dumper):
def __init__(self, name, dumper):
cdbext.Type.__init__(self)
self.typeName = name.strip()
self.dumper = dumper
@@ -49,19 +50,19 @@ class FakeVoidType(cdbext.Type):
def code(self):
if self.typeName.endswith('*'):
return TypeCode.TypeCodePointer
return TypeCode.Pointer
if self.typeName.endswith(']'):
return TypeCode.TypeCodeArray
return TypeCode.TypeCodeVoid
return TypeCode.Array
return TypeCode.Void
def unqualified(self):
return self
def target(self):
code = self.code()
if code == TypeCode.TypeCodePointer:
if code == TypeCode.Pointer:
return FakeVoidType(self.typeName[:-1], self.dumper)
if code == TypeCode.TypeCodeVoid:
if code == TypeCode.Void:
return self
try:
return FakeVoidType(self.typeName[:self.typeName.rindex('[')], self.dumper)
@@ -89,6 +90,7 @@ class FakeVoidType(cdbext.Type):
def templateArguments(self):
return []
class Dumper(DumperBase):
def __init__(self):
DumperBase.__init__(self)
@@ -107,14 +109,14 @@ class Dumper(DumperBase):
val.type = self.fromNativeType(nativeValue.type())
# There is no cdb api for the size of bitfields.
# Workaround this issue by parsing the native debugger text for integral types.
if val.type.code == TypeCode.TypeCodeIntegral:
if val.type.code == TypeCode.Integral:
integerString = nativeValue.nativeDebuggerValue()
if integerString == 'true':
val.ldata = int(1).to_bytes(1, byteorder='little')
elif integerString == 'false':
val.ldata = int(0).to_bytes(1, byteorder='little')
else:
integerString = integerString.replace('`','')
integerString = integerString.replace('`', '')
integerString = integerString.split(' ')[0]
if integerString.startswith('0n'):
integerString = integerString[2:]
@@ -125,12 +127,12 @@ class Dumper(DumperBase):
base = 10
signed = not val.type.name.startswith('unsigned')
try:
val.ldata = int(integerString, base).to_bytes(val.type.size(), \
byteorder='little', signed=signed)
val.ldata = int(integerString, base).to_bytes(val.type.size(),
byteorder='little', signed=signed)
except:
# read raw memory in case the integerString can not be interpreted
pass
if val.type.code == TypeCode.TypeCodeEnum:
if val.type.code == TypeCode.Enum:
val.ldisplay = self.enumValue(nativeValue)
val.isBaseClass = val.name == val.type.name
val.nativeValue = nativeValue
@@ -148,7 +150,8 @@ class Dumper(DumperBase):
c = 'u'
else:
return name
typeId = c + ''.join(['{%s:%s}' % (f.name(), self.nativeTypeId(f.type())) for f in nativeType.fields()])
typeId = c + ''.join(['{%s:%s}' % (f.name(), self.nativeTypeId(f.type()))
for f in nativeType.fields()])
return typeId
def fromNativeType(self, nativeType):
@@ -161,21 +164,22 @@ class Dumper(DumperBase):
nativeType = FakeVoidType(nativeType.name(), self)
code = nativeType.code()
if code == TypeCode.TypeCodePointer:
if code == TypeCode.Pointer:
if not nativeType.name().startswith('<function>'):
targetType = self.lookupType(nativeType.targetName(), nativeType.moduleId())
if targetType is not None:
return self.createPointerType(targetType)
code = TypeCode.TypeCodeFunction
code = TypeCode.Function
if code == TypeCode.TypeCodeArray:
if code == TypeCode.Array:
# cdb reports virtual function tables as arrays those ar handled separetly by
# the DumperBase. Declare those types as structs prevents a lookup to a none existing type
# the DumperBase. Declare those types as structs prevents a lookup to a
# none existing type
if not nativeType.name().startswith('__fptr()') and not nativeType.name().startswith('<gentype '):
targetType = self.lookupType(nativeType.targetName(), nativeType.moduleId())
if targetType is not None:
return self.createArrayType(targetType, nativeType.arrayElements())
code = TypeCode.TypeCodeStruct
code = TypeCode.Struct
tdata = self.TypeData(self)
tdata.name = nativeType.name()
@@ -183,17 +187,17 @@ class Dumper(DumperBase):
tdata.lbitsize = nativeType.bitsize()
tdata.code = code
tdata.moduleName = nativeType.module()
self.registerType(typeId, tdata) # Prevent recursion in fields.
if code == TypeCode.TypeCodeStruct:
tdata.lfields = lambda value : \
self.registerType(typeId, tdata) # Prevent recursion in fields.
if code == TypeCode.Struct:
tdata.lfields = lambda value: \
self.listFields(nativeType, value)
tdata.lalignment = lambda : \
tdata.lalignment = lambda: \
self.nativeStructAlignment(nativeType)
if code == TypeCode.TypeCodeEnum:
tdata.enumDisplay = lambda intval, addr, form : \
if code == TypeCode.Enum:
tdata.enumDisplay = lambda intval, addr, form: \
self.nativeTypeEnumDisplay(nativeType, intval, form)
tdata.templateArguments = self.listTemplateParameters(nativeType.name())
self.registerType(typeId, tdata) # Fix up fields and template args
self.registerType(typeId, tdata) # Fix up fields and template args
return self.Type(self, typeId)
def listFields(self, nativeType, value):
@@ -320,14 +324,16 @@ class Dumper(DumperBase):
if namespaceIndex > 0:
namespace = name[:namespaceIndex + 2]
self.qtNamespace = lambda: namespace
self.qtCustomEventFunc = self.parseAndEvaluate('%s!%sQObject::customEvent'
% (self.qtCoreModuleName(), namespace)).address()
self.qtCustomEventFunc = self.parseAndEvaluate(
'%s!%sQObject::customEvent' %
(self.qtCoreModuleName(), namespace)).address()
return namespace
def qtVersion(self):
qtVersion = None
try:
qtVersion = self.parseAndEvaluate('((void**)&%s)[2]' % self.qtHookDataSymbolName()).integer()
qtVersion = self.parseAndEvaluate(
'((void**)&%s)[2]' % self.qtHookDataSymbolName()).integer()
except:
if self.qtCoreModuleName() is not None:
try:
@@ -391,7 +397,7 @@ class Dumper(DumperBase):
else:
return typeName
def lookupType(self, typeNameIn, module = 0):
def lookupType(self, typeNameIn, module=0):
if len(typeNameIn) == 0:
return None
typeName = self.stripQintTypedefs(typeNameIn)
@@ -405,7 +411,7 @@ class Dumper(DumperBase):
return type
return self.Type(self, typeName)
def lookupNativeType(self, name, module = 0):
def lookupNativeType(self, name, module=0):
if name.startswith('void'):
return FakeVoidType(name, self)
return cdbext.lookupType(name, module)
@@ -447,7 +453,7 @@ class Dumper(DumperBase):
variables = []
for val in cdbext.listOfLocals(self.partialVariable):
dumperVal = self.fromNativeValue(val)
dumperVal.lIsInScope = not dumperVal.name in self.uninitialized
dumperVal.lIsInScope = dumperVal.name not in self.uninitialized
variables.append(dumperVal)
self.handleLocals(variables)
@@ -472,7 +478,7 @@ class Dumper(DumperBase):
return cdbext.parseAndEvaluate(exp)
def nativeDynamicTypeName(self, address, baseType):
return None # Does not work with cdb
return None # Does not work with cdb
def nativeValueDereferenceReference(self, value):
return self.nativeValueDereferencePointer(value)

View File

@@ -23,15 +23,18 @@
#
############################################################################
def typeTarget(type):
target = type.target()
if target:
return target
return type
def stripTypeName(value):
return typeTarget(value.type).unqualified().name
def extractPointerType(d, value):
postfix = ""
while stripTypeName(value) == "CPlusPlus::PointerType":
@@ -47,6 +50,7 @@ def extractPointerType(d, value):
return "void" + postfix
return "<unsupported>"
def readTemplateName(d, value):
name = readLiteral(d, value["_identifier"]) + "<"
args = value["_templateArguments"]
@@ -65,6 +69,7 @@ def readTemplateName(d, value):
name += ">"
return name
def readLiteral(d, value):
if not value.integer():
return "<null>"
@@ -78,9 +83,11 @@ def readLiteral(d, value):
except:
return "<unsupported>"
def dumpLiteral(d, value):
d.putValue(d.hexencode(readLiteral(d, value)), "latin1")
def qdump__Core__Id(d, value):
val = value.extractPointer()
if True:
@@ -93,36 +100,44 @@ def qdump__Core__Id(d, value):
d.putValue(val)
d.putPlainChildren(value)
def qdump__Debugger__Internal__GdbMi(d, value):
val = d.encodeString(value["m_name"]) + "3a002000" \
+ d.encodeString(value["m_data"])
d.putValue(val, "utf16")
d.putPlainChildren(value)
def qdump__Debugger__Internal__DisassemblerLine(d, value):
d.putByteArrayValue(value["m_data"])
d.putPlainChildren(value)
def qdump__Debugger__Internal__WatchData(d, value):
d.putStringValue(value["iname"])
d.putPlainChildren(value)
def qdump__Debugger__Internal__WatchItem(d, value):
d.putStringValue(value["iname"])
d.putPlainChildren(value)
def qdump__Debugger__Internal__BreakpointModelId(d, value):
d.putValue("%s.%s" % (value["m_majorPart"].integer(), value["m_minorPart"].integer()))
d.putPlainChildren(value)
def qdump__Debugger__Internal__ThreadId(d, value):
d.putValue("%s" % value["m_id"])
d.putPlainChildren(value)
def qdump__CPlusPlus__ByteArrayRef(d, value):
d.putSimpleCharArray(value["m_start"], value["m_length"])
d.putPlainChildren(value)
def qdump__CPlusPlus__Identifier(d, value):
try:
d.putSimpleCharArray(value["_chars"], value["_size"])
@@ -130,14 +145,17 @@ def qdump__CPlusPlus__Identifier(d, value):
pass
d.putPlainChildren(value)
def qdump__CPlusPlus__Symbol(d, value):
dumpLiteral(d, value["_name"])
d.putBetterType(value.type)
d.putPlainChildren(value)
def qdump__CPlusPlus__Class(d, value):
qdump__CPlusPlus__Symbol(d, value)
def kindName(d, value):
e = value.integer()
if e:
@@ -146,10 +164,12 @@ def kindName(d, value):
else:
return ''
def qdump__CPlusPlus__IntegerType(d, value):
d.putValue(kindName(d, value["_kind"]))
d.putPlainChildren(value)
def qdump__CPlusPlus__FullySpecifiedType(d, value):
type = value["_type"]
typeName = stripTypeName(type)
@@ -159,36 +179,44 @@ def qdump__CPlusPlus__FullySpecifiedType(d, value):
d.putValue(d.hexencode(extractPointerType(d, type)), "latin1")
d.putPlainChildren(value)
def qdump__CPlusPlus__NamedType(d, value):
dumpLiteral(d, value["_name"])
d.putBetterType(value.type)
d.putPlainChildren(value)
def qdump__CPlusPlus__PointerType(d, value):
d.putValue(d.hexencode(extractPointerType(d, value)), "latin1")
d.putPlainChildren(value)
def qdump__CPlusPlus__TemplateNameId(d, value):
dumpLiteral(d, value)
d.putBetterType(value.type)
d.putPlainChildren(value)
def qdump__CPlusPlus__QualifiedNameId(d, value):
dumpLiteral(d, value)
d.putPlainChildren(value)
def qdump__CPlusPlus__Literal(d, value):
dumpLiteral(d, value)
d.putPlainChildren(value)
def qdump__CPlusPlus__StringLiteral(d, value):
d.putSimpleCharArray(value["_chars"], value["_size"])
d.putPlainChildren(value)
def qdump__CPlusPlus__Internal__Value(d, value):
d.putValue(value["l"])
d.putPlainChildren(value)
def qdump__Utils__FilePath(d, value):
try:
if not d.extractPointer(value["m_url"]): # there is no valid URL
@@ -199,21 +227,26 @@ def qdump__Utils__FilePath(d, value):
d.putStringValue(value) # support FileName before 4.10 as well
d.putPlainChildren(value)
def qdump__Utils__FileName(d, value):
qdump__Utils__FilePath(d, value)
def qdump__Utils__ElfSection(d, value):
d.putByteArrayValue(value["name"])
d.putPlainChildren(value)
def qdump__Utils__Port(d, value):
d.putValue(d.extractInt(value))
d.putPlainChildren(value)
def qdump__Utf8String(d, value):
d.putByteArrayValue(value['byteArray'])
d.putPlainChildren(value)
def qdump__CPlusPlus__Token(d, value):
k = value["f"]["kind"]
e = k.lvalue
@@ -228,6 +261,7 @@ def qdump__CPlusPlus__Token(d, value):
d.putValue(type)
d.putPlainChildren(value)
def qdump__CPlusPlus__Internal__PPToken(d, value):
data, size, alloc = d.byteArrayData(value["m_src"])
length = value["f"]["utf16chars"].integer()
@@ -237,6 +271,7 @@ def qdump__CPlusPlus__Internal__PPToken(d, value):
d.putValue(d.readMemory(data + offset, min(100, length)), "latin1")
d.putPlainChildren(value)
def qdump__ProString(d, value):
try:
s = value["m_string"]
@@ -249,10 +284,12 @@ def qdump__ProString(d, value):
d.putEmptyValue()
d.putPlainChildren(value)
def qdump__ProKey(d, value):
qdump__ProString(d, value)
d.putBetterType(value.type)
def qdump__Core__GeneratedFile(d, value):
d.putStringValue(value["m_d"]["d"]["path"])
d.putPlainChildren(value)
@@ -275,14 +312,18 @@ def qdump__Core__GeneratedFile(d, value):
# d.putStringValue(value["d"]["m_unexpandedDisplayName"])
# d.putPlainChildren(value)
def qdump__ProjectExplorer__ProjectNode(d, value):
qdump__ProjectExplorer__FolderNode(d, value)
def qdump__CMakeProjectManager__Internal__CMakeProjectNode(d, value):
qdump__ProjectExplorer__FolderNode(d, value)
def qdump__QmakeProjectManager__QmakePriFileNode(d, value):
qdump__ProjectExplorer__FolderNode(d, value)
def qdump__QmakeProjectManager__QmakeProFileNode(d, value):
qdump__ProjectExplorer__FolderNode(d, value)

File diff suppressed because it is too large Load Diff

View File

@@ -35,7 +35,6 @@ import re
import sys
import struct
import tempfile
import types
from dumper import DumperBase, Children, toInteger, TopLevelItem
from utils import TypeCode
@@ -46,6 +45,7 @@ from utils import TypeCode
#
#######################################################################
def safePrint(output):
try:
print(output)
@@ -61,18 +61,19 @@ def safePrint(output):
out += c
print(out)
def registerCommand(name, func):
class Command(gdb.Command):
def __init__(self):
super(Command, self).__init__(name, gdb.COMMAND_OBSCURE)
def invoke(self, args, from_tty):
safePrint(func(args))
Command()
#######################################################################
#
# Convenience
@@ -83,18 +84,24 @@ def registerCommand(name, func):
class PPCommand(gdb.Command):
def __init__(self):
super(PPCommand, self).__init__('pp', gdb.COMMAND_OBSCURE)
def invoke(self, args, from_tty):
print(theCliDumper.fetchVariable(args))
PPCommand()
# Just convenience for 'python print gdb.parse_and_eval(...)'
class PPPCommand(gdb.Command):
def __init__(self):
super(PPPCommand, self).__init__('ppp', gdb.COMMAND_OBSCURE)
def invoke(self, args, from_tty):
print(gdb.parse_and_eval(args))
PPPCommand()
@@ -109,14 +116,17 @@ def scanStack(p, n):
p += f.type.sizeof
return r
class ScanStackCommand(gdb.Command):
def __init__(self):
super(ScanStackCommand, self).__init__('scanStack', gdb.COMMAND_OBSCURE)
def invoke(self, args, from_tty):
if len(args) == 0:
args = 20
safePrint(scanStack(gdb.parse_and_eval('$sp'), int(args)))
ScanStackCommand()
@@ -126,7 +136,7 @@ ScanStackCommand()
#
#######################################################################
class PlainDumper:
class PlainDumper():
def __init__(self, printer):
self.printer = printer
self.typeCache = {}
@@ -143,7 +153,7 @@ class PlainDumper:
d.putValue(d.hexencode(val), 'utf8:1:0')
elif sys.version_info[0] <= 2 and isinstance(val, unicode):
d.putValue(val)
elif val is not None: # Assuming LazyString
elif val is not None: # Assuming LazyString
d.putCharArrayValue(val.address, val.length,
val.type.target().sizeof)
@@ -162,6 +172,7 @@ class PlainDumper:
break
d.putNumChild(1)
def importPlainDumpers(args):
if args == 'off':
try:
@@ -172,11 +183,11 @@ def importPlainDumpers(args):
else:
theDumper.importPlainDumpers()
registerCommand('importPlainDumpers', importPlainDumpers)
class OutputSaver:
class OutputSaver():
def __init__(self, d):
self.d = d
@@ -185,7 +196,7 @@ class OutputSaver:
self.d.output = ''
def __exit__(self, exType, exValue, exTraceBack):
if self.d.passExceptions and not exType is None:
if self.d.passExceptions and exType is not None:
self.d.showException('OUTPUTSAVER', exType, exValue, exTraceBack)
self.d.output = self.savedOutput
else:
@@ -194,7 +205,6 @@ class OutputSaver:
return False
#######################################################################
#
# The Dumper Class
@@ -220,9 +230,9 @@ class Dumper(DumperBase):
#DumperBase.warn('FROM FRAME VALUE: %s' % nativeValue.address)
val = nativeValue
try:
val = nativeValue.cast(nativeValue.dynamic_type)
val = nativeValue.cast(nativeValue.dynamic_type)
except:
pass
pass
return self.fromNativeValue(val)
def fromNativeValue(self, nativeValue):
@@ -249,7 +259,7 @@ class Dumper(DumperBase):
# is surprisingly expensive.
val.nativeValue = nativeValue
#DumperBase.warn('CREATED PTR 1: %s' % val)
if not nativeValue.address is None:
if nativeValue.address is not None:
val.laddress = toInteger(nativeValue.address)
#DumperBase.warn('CREATED PTR 2: %s' % val)
return val
@@ -272,7 +282,7 @@ class Dumper(DumperBase):
val = self.Value(self)
val.nativeValue = nativeValue
if not nativeValue.address is None:
if nativeValue.address is not None:
val.laddress = toInteger(nativeValue.address)
else:
size = nativeType.sizeof
@@ -355,35 +365,35 @@ class Dumper(DumperBase):
tdata.typeId = typeId
tdata.lbitsize = nativeType.sizeof * 8
tdata.code = {
#gdb.TYPE_CODE_TYPEDEF : TypeCodeTypedef, # Handled above.
gdb.TYPE_CODE_METHOD : TypeCode.TypeCodeFunction,
gdb.TYPE_CODE_VOID : TypeCode.TypeCodeVoid,
gdb.TYPE_CODE_FUNC : TypeCode.TypeCodeFunction,
gdb.TYPE_CODE_METHODPTR : TypeCode.TypeCodeFunction,
gdb.TYPE_CODE_MEMBERPTR : TypeCode.TypeCodeFunction,
#gdb.TYPE_CODE_PTR : TypeCode.TypeCodePointer, # Handled above.
#gdb.TYPE_CODE_REF : TypeCode.TypeCodeReference, # Handled above.
gdb.TYPE_CODE_BOOL : TypeCode.TypeCodeIntegral,
gdb.TYPE_CODE_CHAR : TypeCode.TypeCodeIntegral,
gdb.TYPE_CODE_INT : TypeCode.TypeCodeIntegral,
gdb.TYPE_CODE_FLT : TypeCode.TypeCodeFloat,
gdb.TYPE_CODE_ENUM : TypeCode.TypeCodeEnum,
#gdb.TYPE_CODE_ARRAY : TypeCode.TypeCodeArray,
gdb.TYPE_CODE_STRUCT : TypeCode.TypeCodeStruct,
gdb.TYPE_CODE_UNION : TypeCode.TypeCodeStruct,
gdb.TYPE_CODE_COMPLEX : TypeCode.TypeCodeComplex,
gdb.TYPE_CODE_STRING : TypeCode.TypeCodeFortranString,
#gdb.TYPE_CODE_TYPEDEF : TypeCode.Typedef, # Handled above.
gdb.TYPE_CODE_METHOD: TypeCode.Function,
gdb.TYPE_CODE_VOID: TypeCode.Void,
gdb.TYPE_CODE_FUNC: TypeCode.Function,
gdb.TYPE_CODE_METHODPTR: TypeCode.Function,
gdb.TYPE_CODE_MEMBERPTR: TypeCode.Function,
#gdb.TYPE_CODE_PTR : TypeCode.Pointer, # Handled above.
#gdb.TYPE_CODE_REF : TypeCode.Reference, # Handled above.
gdb.TYPE_CODE_BOOL: TypeCode.Integral,
gdb.TYPE_CODE_CHAR: TypeCode.Integral,
gdb.TYPE_CODE_INT: TypeCode.Integral,
gdb.TYPE_CODE_FLT: TypeCode.Float,
gdb.TYPE_CODE_ENUM: TypeCode.Enum,
#gdb.TYPE_CODE_ARRAY : TypeCode.Array,
gdb.TYPE_CODE_STRUCT: TypeCode.Struct,
gdb.TYPE_CODE_UNION: TypeCode.Struct,
gdb.TYPE_CODE_COMPLEX: TypeCode.Complex,
gdb.TYPE_CODE_STRING: TypeCode.FortranString,
}[code]
if tdata.code == TypeCode.TypeCodeEnum:
tdata.enumDisplay = lambda intval, addr, form : \
if tdata.code == TypeCode.Enum:
tdata.enumDisplay = lambda intval, addr, form: \
self.nativeTypeEnumDisplay(nativeType, intval, form)
if tdata.code == TypeCode.TypeCodeStruct:
tdata.lalignment = lambda : \
if tdata.code == TypeCode.Struct:
tdata.lalignment = lambda: \
self.nativeStructAlignment(nativeType)
tdata.lfields = lambda value : \
tdata.lfields = lambda value: \
self.listMembers(value, nativeType)
tdata.templateArguments = self.listTemplateParameters(nativeType)
self.registerType(typeId, tdata) # Fix up fields and template args
self.registerType(typeId, tdata) # Fix up fields and template args
# warn('CREATE TYPE: %s' % typeId)
#else:
# warn('REUSE TYPE: %s' % typeId)
@@ -417,7 +427,7 @@ class Dumper(DumperBase):
enumerators.append((field.name, field.enumval))
# No match was found, try to return as flags
enumerators.sort(key = lambda x: x[1])
enumerators.sort(key=lambda x: x[1])
flags = []
v = intval
found = False
@@ -460,16 +470,14 @@ class Dumper(DumperBase):
align = handleItem(f.type, align)
return align
#except:
# # Happens in the BoostList dumper for a 'const bool'
# # item named 'constant_time_size'. There isn't anything we can do
# # in this case.
# pass
# pass
#yield value.extractField(field)
def memberFromNativeFieldAndValue(self, nativeField, nativeValue, fieldName, value):
nativeMember = self.nativeMemberFromField(nativeValue, nativeField)
if nativeMember is None:
@@ -554,9 +562,9 @@ class Dumper(DumperBase):
extractor = None
else:
extractor = lambda value, \
capturedNativeField = nativeField, \
capturedNativeValue = nativeValue, \
capturedFieldName = fieldName : \
capturedNativeField = nativeField, \
capturedNativeValue = nativeValue, \
capturedFieldName = fieldName: \
self.memberFromNativeFieldAndValue(capturedNativeField,
capturedNativeValue,
capturedFieldName,
@@ -564,10 +572,8 @@ class Dumper(DumperBase):
#DumperBase.warn("FOUND NATIVE FIELD: %s bitpos: %s" % (fieldName, bitpos))
return self.Field(dumper=self, name=fieldName, isBase=nativeField.is_base_class,
bitsize=bitsize, bitpos=bitpos, type=fieldType,
extractor=extractor)
bitsize=bitsize, bitpos=bitpos, type=fieldType,
extractor=extractor)
def listLocals(self, partialVar):
frame = gdb.selected_frame()
@@ -590,67 +596,67 @@ class Dumper(DumperBase):
break
for symbol in block:
# Filter out labels etc.
if symbol.is_variable or symbol.is_argument:
name = symbol.print_name
# Filter out labels etc.
if symbol.is_variable or symbol.is_argument:
name = symbol.print_name
if name in ('__in_chrg', '__PRETTY_FUNCTION__'):
continue
if name in ('__in_chrg', '__PRETTY_FUNCTION__'):
continue
if not partialVar is None and partialVar != name:
continue
if partialVar is not None and partialVar != name:
continue
# 'NotImplementedError: Symbol type not yet supported in
# Python scripts.'
#DumperBase.warn('SYMBOL %s (%s, %s)): ' % (symbol, name, symbol.name))
if self.passExceptions and not self.isTesting:
nativeValue = frame.read_var(name, block)
value = self.fromFrameValue(nativeValue)
value.name = name
#DumperBase.warn('READ 0: %s' % value.stringify())
items.append(value)
continue
# 'NotImplementedError: Symbol type not yet supported in
# Python scripts.'
#DumperBase.warn('SYMBOL %s (%s, %s)): ' % (symbol, name, symbol.name))
if self.passExceptions and not self.isTesting:
nativeValue = frame.read_var(name, block)
value = self.fromFrameValue(nativeValue)
value.name = name
#DumperBase.warn('READ 0: %s' % value.stringify())
items.append(value)
continue
try:
# Same as above, but for production.
nativeValue = frame.read_var(name, block)
value = self.fromFrameValue(nativeValue)
value.name = name
#DumperBase.warn('READ 1: %s' % value.stringify())
items.append(value)
continue
except:
pass
try:
# Same as above, but for production.
nativeValue = frame.read_var(name, block)
value = self.fromFrameValue(nativeValue)
value.name = name
#DumperBase.warn('READ 1: %s' % value.stringify())
items.append(value)
continue
except:
pass
try:
#DumperBase.warn('READ 2: %s' % item.value)
value = self.fromFrameValue(frame.read_var(name))
value.name = name
items.append(value)
continue
except:
# RuntimeError: happens for
# void foo() { std::string s; std::wstring w; }
# ValueError: happens for (as of 2010/11/4)
# a local struct as found e.g. in
# gcc sources in gcc.c, int execute()
pass
try:
#DumperBase.warn('READ 2: %s' % item.value)
value = self.fromFrameValue(frame.read_var(name))
value.name = name
items.append(value)
continue
except:
# RuntimeError: happens for
# void foo() { std::string s; std::wstring w; }
# ValueError: happens for (as of 2010/11/4)
# a local struct as found e.g. in
# gcc sources in gcc.c, int execute()
pass
try:
#DumperBase.warn('READ 3: %s %s' % (name, item.value))
#DumperBase.warn('ITEM 3: %s' % item.value)
value = self.fromFrameValue(gdb.parse_and_eval(name))
value.name = name
items.append(value)
except:
# Can happen in inlined code (see last line of
# RowPainter::paintChars(): 'RuntimeError:
# No symbol '__val' in current context.\n'
pass
try:
#DumperBase.warn('READ 3: %s %s' % (name, item.value))
#DumperBase.warn('ITEM 3: %s' % item.value)
value = self.fromFrameValue(gdb.parse_and_eval(name))
value.name = name
items.append(value)
except:
# Can happen in inlined code (see last line of
# RowPainter::paintChars(): 'RuntimeError:
# No symbol '__val' in current context.\n'
pass
# The outermost block in a function has the function member
# FIXME: check whether this is guaranteed.
if not block.function is None:
if block.function is not None:
break
block = block.superblock
@@ -670,7 +676,7 @@ class Dumper(DumperBase):
self.resetStats()
self.prepare(args)
self.isBigEndian = gdb.execute('show endian', to_string = True).find('big endian') > 0
self.isBigEndian = gdb.execute('show endian', to_string=True).find('big endian') > 0
self.packCode = '>' if self.isBigEndian else '<'
(ok, res) = self.tryFetchInterpreterVariables(args)
@@ -757,7 +763,7 @@ class Dumper(DumperBase):
#exp = '((class %s*)%s)->%s(%s)' % (typeName, value.laddress, function, arg)
addr = value.address()
if addr is None:
addr = self.pokeValue(value)
addr = self.pokeValue(value)
#DumperBase.warn('PTR: %s -> %s(%s)' % (value, function, addr))
exp = '((%s*)0x%x)->%s(%s)' % (typeName, addr, function, arg)
#DumperBase.warn('CALL: %s' % exp)
@@ -777,9 +783,9 @@ class Dumper(DumperBase):
def makeStdString(init):
# Works only for small allocators, but they are usually empty.
gdb.execute('set $d=(std::string*)calloc(sizeof(std::string), 2)');
gdb.execute('set $d=(std::string*)calloc(sizeof(std::string), 2)')
gdb.execute('call($d->basic_string("' + init +
'",*(std::allocator<char>*)(1+$d)))')
'",*(std::allocator<char>*)(1+$d)))')
value = gdb.parse_and_eval('$d').dereference()
return value
@@ -791,7 +797,7 @@ class Dumper(DumperBase):
data = value.data()
h = self.hexencode(data)
#DumperBase.warn('DATA: %s' % h)
string = ''.join('\\x' + h[2*i:2*i+2] for i in range(size))
string = ''.join('\\x' + h[2 * i:2 * i + 2] for i in range(size))
exp = '(%s*)memcpy(calloc(%d, 1), "%s", %d)' \
% (value.type.name, size, string, size)
#DumperBase.warn('EXP: %s' % exp)
@@ -886,7 +892,7 @@ class Dumper(DumperBase):
try:
version = self.qtVersionString()
(major, minor, patch) = version[version.find('"')+1:version.rfind('"')].split('.')
(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
@@ -896,6 +902,7 @@ class Dumper(DumperBase):
def createSpecialBreakpoints(self, args):
self.specialBreakpoints = []
def newSpecial(spec):
# GDB < 8.1 does not have the 'qualified' parameter here,
# GDB >= 8.1 applies some generous pattern matching, hitting
@@ -903,7 +910,7 @@ class Dumper(DumperBase):
class Pre81SpecialBreakpoint(gdb.Breakpoint):
def __init__(self, spec):
super(Pre81SpecialBreakpoint, self).__init__(spec,
gdb.BP_BREAKPOINT, internal=True)
gdb.BP_BREAKPOINT, internal=True)
self.spec = spec
def stop(self):
@@ -913,7 +920,9 @@ class Dumper(DumperBase):
class SpecialBreakpoint(gdb.Breakpoint):
def __init__(self, spec):
super(SpecialBreakpoint, self).__init__(spec,
gdb.BP_BREAKPOINT, internal=True, qualified=True)
gdb.BP_BREAKPOINT,
internal=True,
qualified=True)
self.spec = spec
def stop(self):
@@ -999,7 +1008,6 @@ class Dumper(DumperBase):
# oldthread.switch()
#return out + ']'
def importPlainDumper(self, printer):
name = printer.name.replace('::', '__')
self.qqDumpers[name] = PlainDumper(printer)
@@ -1024,9 +1032,9 @@ class Dumper(DumperBase):
def handleNewObjectFile(self, objfile):
name = objfile.filename
if self.isWindowsTarget():
qtCoreMatch = re.match('.*Qt5?Core[^/.]*d?\.dll', name)
qtCoreMatch = re.match(r'.*Qt5?Core[^/.]*d?\.dll', name)
else:
qtCoreMatch = re.match('.*/libQt5?Core[^/.]*\.so', name)
qtCoreMatch = re.match(r'.*/libQt5?Core[^/.]*\.so', name)
if qtCoreMatch is not None:
self.addDebugLibs(objfile)
@@ -1043,18 +1051,17 @@ class Dumper(DumperBase):
except:
pass
def handleQtCoreLoaded(self, objfile):
fd, tmppath = tempfile.mkstemp()
os.close(fd)
cmd = 'maint print msymbols %s "%s"' % (tmppath, objfile.filename)
try:
symbols = gdb.execute(cmd, to_string = True)
symbols = gdb.execute(cmd, to_string=True)
except:
# command syntax depends on gdb version - below is gdb 8+
cmd = 'maint print msymbols -objfile "%s" -- %s' % (objfile.filename, tmppath)
try:
symbols = gdb.execute(cmd, to_string = True)
symbols = gdb.execute(cmd, to_string=True)
except:
pass
ns = ''
@@ -1063,14 +1070,14 @@ class Dumper(DumperBase):
if line.find('msgHandlerGrabbed ') >= 0:
# [11] b 0x7ffff683c000 _ZN4MynsL17msgHandlerGrabbedE
# section .tbss Myns::msgHandlerGrabbed qlogging.cpp
ns = re.split('_ZN?(\d*)(\w*)L17msgHandlerGrabbedE? ', line)[2]
ns = re.split(r'_ZN?(\d*)(\w*)L17msgHandlerGrabbedE? ', line)[2]
if len(ns):
ns += '::'
break
if line.find('currentThreadData ') >= 0:
# [ 0] b 0x7ffff67d3000 _ZN2UUL17currentThreadDataE
# section .tbss UU::currentThreadData qthread_unix.cpp\\n
ns = re.split('_ZN?(\d*)(\w*)L17currentThreadDataE? ', line)[2]
ns = re.split(r'_ZN?(\d*)(\w*)L17currentThreadDataE? ', line)[2]
if len(ns):
ns += '::'
break
@@ -1179,14 +1186,14 @@ class Dumper(DumperBase):
def lookupNativeType(self, typeName):
nativeType = self.lookupNativeTypeHelper(typeName)
if not nativeType is None:
if nativeType is not None:
self.check(isinstance(nativeType, gdb.Type))
return nativeType
def lookupNativeTypeHelper(self, typeName):
typeobj = self.typeCache.get(typeName)
#DumperBase.warn('LOOKUP 1: %s -> %s' % (typeName, typeobj))
if not typeobj is None:
if typeobj is not None:
return typeobj
if typeName == 'void':
@@ -1212,7 +1219,7 @@ class Dumper(DumperBase):
ts = typeName
ts = ts.replace('{anonymous}', '(anonymous namespace)')
typeobj = self.lookupNativeType(ts)
if not typeobj is None:
if typeobj is not None:
self.typeCache[typeName] = typeobj
self.typesToReport[typeName] = typeobj
return typeobj
@@ -1248,7 +1255,7 @@ class Dumper(DumperBase):
if ts.endswith('*'):
typeobj = self.lookupNativeType(ts[0:-1])
if not typeobj is None:
if typeobj is not None:
typeobj = typeobj.pointer()
self.typeCache[typeName] = typeobj
self.typesToReport[typeName] = typeobj
@@ -1271,7 +1278,7 @@ class Dumper(DumperBase):
#DumperBase.warn("LOOKING UP '%s' FAILED" % ts)
pass
if not typeobj is None:
if typeobj is not None:
#DumperBase.warn('CACHING: %s' % typeobj)
self.typeCache[typeName] = typeobj
self.typesToReport[typeName] = typeobj
@@ -1292,7 +1299,7 @@ class Dumper(DumperBase):
extraQml = int(args.get('extraqml', '0'))
limit = int(args['limit'])
if limit <= 0:
limit = 10000
limit = 10000
self.prepare(args)
self.output = ''
@@ -1316,8 +1323,8 @@ class Dumper(DumperBase):
value = symbol.value(frame)
typeobj = value.type
if typeobj.code == gdb.TYPE_CODE_PTR:
dereftype = typeobj.target().unqualified()
if dereftype.name == needle:
dereftype = typeobj.target().unqualified()
if dereftype.name == needle:
addr = toInteger(value)
expr = pat % (ns, addr)
res = str(gdb.parse_and_eval(expr))
@@ -1347,7 +1354,7 @@ class Dumper(DumperBase):
if sal:
line = sal.line
symtab = sal.symtab
if not symtab is None:
if symtab is not None:
objfile = fromNativePath(symtab.objfile.filename)
fullname = symtab.fullname()
if fullname is None:
@@ -1366,22 +1373,22 @@ class Dumper(DumperBase):
context = interpreterFrame.get('context', 0)
self.put(('frame={function="%s",file="%s",'
'line="%s",language="%s",context="%s"}')
% (function, self.hexencode(fileName), lineNumber, language, context))
'line="%s",language="%s",context="%s"}')
% (function, self.hexencode(fileName), lineNumber, language, context))
if False and self.isInternalInterpreterFrame(functionName):
frame = frame.older()
self.put(('frame={address="0x%x",function="%s",'
'file="%s",line="%s",'
'module="%s",language="c",usable="0"}') %
(pc, functionName, fileName, line, objfile))
'file="%s",line="%s",'
'module="%s",language="c",usable="0"}') %
(pc, functionName, fileName, line, objfile))
i += 1
frame = frame.older()
continue
self.put(('frame={level="%s",address="0x%x",function="%s",'
'file="%s",line="%s",module="%s",language="c"}') %
(i, pc, functionName, fileName, line, objfile))
'file="%s",line="%s",module="%s",language="c"}') %
(i, pc, functionName, fileName, line, objfile))
frame = frame.older()
i += 1
@@ -1406,7 +1413,7 @@ class Dumper(DumperBase):
def exitGdb(self, _):
gdb.execute('quit')
def reportResult(self, result, args = {}):
def reportResult(self, result, args={}):
print('result={token="%s",%s}' % (args.get("token", 0), result))
def profile1(self, args):
@@ -1420,8 +1427,7 @@ class Dumper(DumperBase):
def profile2(self, args):
import timeit
print(timeit.repeat('theDumper.fetchVariables(%s)' % args,
'from __main__ import theDumper', number=10))
'from __main__ import theDumper', number=10))
class CliDumper(Dumper):
@@ -1473,6 +1479,7 @@ theCliDumper = CliDumper()
def threadnames(arg):
return theDumper.threadnames(int(arg))
registerCommand('threadnames', threadnames)
#######################################################################
@@ -1481,6 +1488,7 @@ registerCommand('threadnames', threadnames)
#
#######################################################################
class InterpreterMessageBreakpoint(gdb.Breakpoint):
def __init__(self):
spec = 'qt_qmlDebugMessageAvailable'
@@ -1501,6 +1509,7 @@ class InterpreterMessageBreakpoint(gdb.Breakpoint):
def new_objfile_handler(event):
return theDumper.handleNewObjectFile(event.new_objfile)
gdb.events.new_objfile.connect(new_objfile_handler)

View File

@@ -52,6 +52,7 @@ from dumper import DumperBase, SubItem, Children, TopLevelItem
qqWatchpointOffset = 10000
def fileNameAsString(file):
return str(file) if file.IsValid() else ''
@@ -60,8 +61,9 @@ def check(exp):
if not exp:
raise RuntimeError('Check failed')
class Dumper(DumperBase):
def __init__(self, debugger = None):
def __init__(self, debugger=None):
DumperBase.__init__(self)
lldb.theDumper = self
@@ -169,14 +171,14 @@ class Dumper(DumperBase):
elif code == lldb.eTypeClassTypedef:
nativeTargetType = nativeType.GetUnqualifiedType()
if hasattr(nativeTargetType, 'GetCanonicalType'):
nativeTargetType = nativeTargetType.GetCanonicalType()
nativeTargetType = nativeTargetType.GetCanonicalType()
val = self.fromNativeValue(nativeValue.Cast(nativeTargetType))
val.type = self.fromNativeType(nativeType)
#DumperBase.warn('CREATED TYPEDEF: %s' % val)
else:
val = self.Value(self)
address = nativeValue.GetLoadAddress()
if not address is None:
if address is not None:
val.laddress = address
if True:
data = nativeValue.GetData()
@@ -270,27 +272,27 @@ class Dumper(DumperBase):
fieldBitpos = None
isBitfield = False
if isBitfield: # Bit fields
if isBitfield: # Bit fields
fieldType = self.createBitfieldType(
self.createType(self.typeName(nativeFieldType)), fieldBitsize)
yield self.Field(self, name=fieldName, type=fieldType,
bitsize=fieldBitsize, bitpos=fieldBitpos)
elif fieldName is None: # Anon members
elif fieldName is None: # Anon members
anonNumber += 1
fieldName = '#%s' % anonNumber
fakeMember = fakeValue.GetChildAtIndex(i)
fakeMemberAddress = fakeMember.GetLoadAddress()
offset = fakeMemberAddress - fakeAddress
yield self.Field(self, name=fieldName, type=self.fromNativeType(nativeFieldType),
bitsize=fieldBitsize, bitpos=8*offset)
bitsize=fieldBitsize, bitpos=8 * offset)
elif fieldName in baseNames: # Simple bases
member = self.fromNativeValue(fakeValue.GetChildAtIndex(i))
member.isBaseClass = True
yield member
else: # Normal named members
else: # Normal named members
member = self.fromNativeValue(fakeValue.GetChildAtIndex(i))
member.name = nativeField.GetName()
yield member
@@ -389,7 +391,7 @@ class Dumper(DumperBase):
#DumperBase.warn('TYPEDEF')
nativeTargetType = nativeType.GetUnqualifiedType()
if hasattr(nativeTargetType, 'GetCanonicalType'):
nativeTargetType = nativeTargetType.GetCanonicalType()
nativeTargetType = nativeTargetType.GetCanonicalType()
targetType = self.fromNativeType(nativeTargetType)
return self.createTypedefedType(targetType, nativeType.GetName())
@@ -398,10 +400,10 @@ class Dumper(DumperBase):
if code in (lldb.eTypeClassArray, lldb.eTypeClassVector):
#DumperBase.warn('ARRAY: %s' % nativeType.GetName())
if hasattr(nativeType, 'GetArrayElementType'): # New in 3.8(?) / 350.x
if hasattr(nativeType, 'GetArrayElementType'): # New in 3.8(?) / 350.x
nativeTargetType = nativeType.GetArrayElementType()
if not nativeTargetType.IsValid():
if hasattr(nativeType, 'GetVectorElementType'): # New in 3.8(?) / 350.x
if hasattr(nativeType, 'GetVectorElementType'): # New in 3.8(?) / 350.x
#DumperBase.warn('BAD: %s ' % nativeTargetType.get_fields_array())
nativeTargetType = nativeType.GetVectorElementType()
count = nativeType.GetByteSize() // nativeTargetType.GetByteSize()
@@ -414,9 +416,9 @@ class Dumper(DumperBase):
targetType = self.fromNativeType(nativeTargetType)
tdata = targetType.typeData().copy()
tdata.name = targetTypeName
targetType.typeData = lambda : tdata
targetType.typeData = lambda: tdata
return self.createArrayType(targetType, count)
if hasattr(nativeType, 'GetVectorElementType'): # New in 3.8(?) / 350.x
if hasattr(nativeType, 'GetVectorElementType'): # New in 3.8(?) / 350.x
nativeTargetType = nativeType.GetVectorElementType()
count = nativeType.GetByteSize() // nativeTargetType.GetByteSize()
targetType = self.fromNativeType(nativeTargetType)
@@ -434,34 +436,34 @@ class Dumper(DumperBase):
tdata.lbitsize = nativeType.GetByteSize() * 8
if code == lldb.eTypeClassBuiltin:
if utils.isFloatingPointTypeName(typeName):
tdata.code = TypeCode.TypeCodeFloat
tdata.code = TypeCode.Float
elif utils.isIntegralTypeName(typeName):
tdata.code = TypeCode.TypeCodeIntegral
tdata.code = TypeCode.Integral
elif typeName in ('__int128', 'unsigned __int128'):
tdata.code = TypeCode.TypeCodeIntegral
tdata.code = TypeCode.Integral
elif typeName == 'void':
tdata.code = TypeCode.TypeCodeVoid
tdata.code = TypeCode.Void
else:
self.warn('UNKNOWN TYPE KEY: %s: %s' % (typeName, code))
elif code == lldb.eTypeClassEnumeration:
tdata.code = TypeCode.TypeCodeEnum
tdata.enumDisplay = lambda intval, addr, form : \
tdata.code = TypeCode.Enum
tdata.enumDisplay = lambda intval, addr, form: \
self.nativeTypeEnumDisplay(nativeType, intval, form)
elif code in (lldb.eTypeClassComplexInteger, lldb.eTypeClassComplexFloat):
tdata.code = TypeCode.TypeCodeComplex
tdata.code = TypeCode.Complex
elif code in (lldb.eTypeClassClass, lldb.eTypeClassStruct, lldb.eTypeClassUnion):
tdata.code = TypeCode.TypeCodeStruct
tdata.lalignment = lambda : \
tdata.code = TypeCode.Struct
tdata.lalignment = lambda: \
self.nativeStructAlignment(nativeType)
tdata.lfields = lambda value : \
tdata.lfields = lambda value: \
self.listMembers(value, nativeType)
tdata.templateArguments = self.listTemplateParametersHelper(nativeType)
elif code == lldb.eTypeClassFunction:
tdata.code = TypeCode.TypeCodeFunction
tdata.code = TypeCode.Function
elif code == lldb.eTypeClassMemberPointer:
tdata.code = TypeCode.TypeCodeMemberPointer
tdata.code = TypeCode.MemberPointer
self.registerType(typeId, tdata) # Fix up fields and template args
self.registerType(typeId, tdata) # Fix up fields and template args
# warn('CREATE TYPE: %s' % typeId)
#else:
# warn('REUSE TYPE: %s' % typeId)
@@ -489,7 +491,8 @@ class Dumper(DumperBase):
# eTemplateArgumentKindExpression,
# eTemplateArgumentKindPack
if kind == lldb.eTemplateArgumentKindType:
innerType = nativeType.GetTemplateArgumentType(i).GetUnqualifiedType().GetCanonicalType()
innerType = nativeType.GetTemplateArgumentType(
i).GetUnqualifiedType().GetCanonicalType()
targs.append(self.fromNativeType(innerType))
#elif kind == lldb.eTemplateArgumentKindIntegral:
# innerType = nativeType.GetTemplateArgumentType(i).GetUnqualifiedType().GetCanonicalType()
@@ -510,7 +513,7 @@ class Dumper(DumperBase):
# targs.append(value)
else:
#DumperBase.warn('UNHANDLED TEMPLATE TYPE : %s' % kind)
targs.append(stringArgs[i]) # Best we can do.
targs.append(stringArgs[i]) # Best we can do.
#DumperBase.warn('TARGS: %s %s' % (nativeType.GetName(), [str(x) for x in targs]))
return targs
@@ -562,7 +565,7 @@ class Dumper(DumperBase):
return form % intval
def nativeDynamicTypeName(self, address, baseType):
return None # FIXME: Seems sufficient, no idea why.
return None # FIXME: Seems sufficient, no idea why.
addr = self.target.ResolveLoadAddress(address)
ctx = self.target.ResolveSymbolContextForAddress(addr, 0)
sym = ctx.GetSymbol()
@@ -573,20 +576,20 @@ class Dumper(DumperBase):
# See db.StateType
return (
'invalid',
'unloaded', # Process is object is valid, but not currently loaded
'connected', # Process is connected to remote debug services,
# but not launched or attached to anything yet
'attaching', # Process is currently trying to attach
'launching', # Process is in the process of launching
'stopped', # Process or thread is stopped and can be examined.
'running', # Process or thread is running and can't be examined.
'stepping', # Process or thread is in the process of stepping
# and can not be examined.
'crashed', # Process or thread has crashed and can be examined.
'detached', # Process has been detached and can't be examined.
'exited', # Process has exited and can't be examined.
'suspended' # Process or thread is in a suspended state as far
)[s]
'unloaded', # Process is object is valid, but not currently loaded
'connected', # Process is connected to remote debug services,
# but not launched or attached to anything yet
'attaching', # Process is currently trying to attach
'launching', # Process is in the process of launching
'stopped', # Process or thread is stopped and can be examined.
'running', # Process or thread is running and can't be examined.
'stepping', # Process or thread is in the process of stepping
# and can not be examined.
'crashed', # Process or thread has crashed and can be examined.
'detached', # Process has been detached and can't be examined.
'exited', # Process has exited and can't be examined.
'suspended' # Process or thread is in a suspended state as far
)[s]
except:
return 'unknown(%s)' % s
@@ -604,7 +607,7 @@ class Dumper(DumperBase):
'plancomplete',
'threadexiting',
'instrumentation',
)[s]
)[s]
except:
return 'unknown(%s)' % s
@@ -708,8 +711,8 @@ class Dumper(DumperBase):
if version.count('.') != 2:
continue
version.replace("'", '"') # Both seem possible
version = version[version.find('"')+1:version.rfind('"')]
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)
@@ -753,7 +756,7 @@ class Dumper(DumperBase):
def lookupNativeType(self, name):
#DumperBase.warn('LOOKUP TYPE NAME: %s' % name)
typeobj = self.typeCache.get(name)
if not typeobj is None:
if typeobj is not None:
#DumperBase.warn('CACHED: %s' % name)
return typeobj
typeobj = self.target.FindFirstType(name)
@@ -845,7 +848,7 @@ class Dumper(DumperBase):
self.startMode_ = args.get('startmode', 1)
self.breakOnMain_ = args.get('breakonmain', 0)
self.useTerminal_ = args.get('useterminal', 0)
pargs = self.hexdecode(args.get('processargs', ''))
pargs = self.hexdecode(args.get('processargs', ''))
self.processArgs_ = pargs.split('\0') if len(pargs) else []
self.environment_ = args.get('environment', [])
self.environment_ = list(map(lambda x: self.hexdecode(x), self.environment_))
@@ -858,7 +861,7 @@ class Dumper(DumperBase):
if self.workingDirectory_ == '':
try:
self.workingDirectory_ = os.getcwd()
except: # Could have been deleted in the mean time.
except: # Could have been deleted in the mean time.
pass
self.ignoreStops = 0
@@ -884,7 +887,7 @@ class Dumper(DumperBase):
state = 1 if self.target.IsValid() else 0
self.reportResult('success="%s",msg="%s",exe="%s"'
% (state, error, self.executable_), args)
% (state, error, self.executable_), args)
def runEngine(self, args):
if self.runEngineAttempted:
@@ -927,7 +930,7 @@ class Dumper(DumperBase):
# better to mirror that and wait for the spontaneous stop.
self.reportState('enginerunandinferiorrunok')
elif self.startMode_ == DebuggerStartMode.AttachCore:
coreFile = args.get('coreFile', '');
coreFile = args.get('coreFile', '')
self.process = self.target.LoadCore(coreFile)
if self.process.IsValid():
self.reportState('enginerunokandinferiorunrunnable')
@@ -952,8 +955,8 @@ class Dumper(DumperBase):
broadcaster.AddListener(listener, lldb.SBProcess.eBroadcastBitStateChanged)
listener.StartListeningForEvents(broadcaster, lldb.SBProcess.eBroadcastBitStateChanged)
broadcaster.AddListener(listener, lldb.SBTarget.eBroadcastBitBreakpointChanged)
listener.StartListeningForEvents(broadcaster, lldb.SBTarget.eBroadcastBitBreakpointChanged)
listener.StartListeningForEvents(
broadcaster, lldb.SBTarget.eBroadcastBitBreakpointChanged)
def loop(self):
event = lldb.SBEvent()
@@ -968,7 +971,6 @@ class Dumper(DumperBase):
#if listener.WaitForEventForBroadcaster(0, broadcaster, event):
# self.handleEvent(event)
def describeError(self, error):
desc = lldb.SBStream()
error.GetDescription(desc)
@@ -1092,8 +1094,8 @@ class Dumper(DumperBase):
lineNumber = interpreterFrame.get('line', 0)
context = interpreterFrame.get('context', 0)
result += ('frame={function="%s",file="%s",'
'line="%s",language="%s",context="%s"}'
% (function, fileName, lineNumber, language, context))
'line="%s",language="%s",context="%s"}'
% (function, fileName, lineNumber, language, context))
fileName = fileNameAsString(lineEntry.file)
result += '{pc="0x%x"' % pc
@@ -1118,11 +1120,9 @@ class Dumper(DumperBase):
# logview pane feature.
self.report('token(\"%s\")' % args["token"])
def reportBreakpointUpdate(self, bp):
self.report('breakpointmodified={%s}' % self.describeBreakpoint(bp))
def readRawMemory(self, address, size):
if size == 0:
return bytes()
@@ -1203,7 +1203,7 @@ class Dumper(DumperBase):
#else:
if True:
values = list(frame.GetVariables(True, True, False, True))
values.reverse() # To get shadowed vars numbered backwards.
values.reverse() # To get shadowed vars numbered backwards.
variables = []
for val in values:
@@ -1225,7 +1225,7 @@ class Dumper(DumperBase):
self.put('],partial="%d"' % isPartial)
self.reportResult(self.output, args)
def fetchRegisters(self, args = None):
def fetchRegisters(self, args=None):
if self.process is None:
result = 'process="none"'
else:
@@ -1253,7 +1253,7 @@ class Dumper(DumperBase):
self.reportResult('output="%s"' % result.GetOutput(), args)
return
# Try again with register write xmm0 "{0x00 ... 0x02}" syntax:
vec = ' '.join(["0x" + value[i:i+2] for i in range(2, len(value), 2)])
vec = ' '.join(["0x" + value[i:i + 2] for i in range(2, len(value), 2)])
success = interp.HandleCommand('register write %s "{%s}"' % (name, vec), result)
if success:
self.reportResult('output="%s"' % result.GetOutput(), args)
@@ -1295,7 +1295,6 @@ class Dumper(DumperBase):
self.process.Kill()
self.reportResult('', args)
def handleBreakpointEvent(self, event):
eventType = lldb.SBBreakpoint.GetBreakpointEventTypeFromEvent(event)
# handle only the resolved locations for now..
@@ -1304,7 +1303,6 @@ class Dumper(DumperBase):
if bp is not None:
self.reportBreakpointUpdate(bp)
def handleEvent(self, event):
if lldb.SBBreakpoint.EventIsBreakpointEvent(event):
self.handleBreakpointEvent(event)
@@ -1321,16 +1319,17 @@ class Dumper(DumperBase):
flavor = event.GetDataFlavor()
state = lldb.SBProcess.GetStateFromEvent(event)
bp = lldb.SBBreakpoint.GetBreakpointFromEvent(event)
skipEventReporting = eventType in (lldb.SBProcess.eBroadcastBitSTDOUT, lldb.SBProcess.eBroadcastBitSTDERR)
skipEventReporting = eventType in (
lldb.SBProcess.eBroadcastBitSTDOUT, lldb.SBProcess.eBroadcastBitSTDERR)
self.report('event={type="%s",data="%s",msg="%s",flavor="%s",state="%s",bp="%s"}'
% (eventType, out.GetData(), msg, flavor, self.stateName(state), bp))
% (eventType, out.GetData(), msg, flavor, self.stateName(state), bp))
if state == lldb.eStateExited:
self.eventState = state
if not self.isShuttingDown_:
self.reportState("inferiorexited")
self.report('exited={status="%s",desc="%s"}'
% (self.process.GetExitStatus(), self.process.GetExitDescription()))
% (self.process.GetExitStatus(), self.process.GetExitDescription()))
elif state != self.eventState and not skipEventReporting:
self.eventState = state
if state == lldb.eStateStopped:
@@ -1347,7 +1346,7 @@ class Dumper(DumperBase):
resolver()
self.report("AUTO-CONTINUE AFTER RESOLVING")
self.reportState("inferiorstopok")
self.process.Continue();
self.process.Continue()
return
if functionName == "::qt_qmlDebugMessageAvailable()":
self.report("ASYNC MESSAGE FROM SERVICE")
@@ -1355,7 +1354,7 @@ class Dumper(DumperBase):
if not res:
self.report("EVENT NEEDS NO STOP")
self.reportState("stopped")
self.process.Continue();
self.process.Continue()
return
if self.isInterrupting_:
self.isInterrupting_ = False
@@ -1368,13 +1367,13 @@ class Dumper(DumperBase):
else:
self.reportState(self.stateName(state))
if eventType == lldb.SBProcess.eBroadcastBitStateChanged: # 1
if eventType == lldb.SBProcess.eBroadcastBitStateChanged: # 1
state = self.process.GetState()
if state == lldb.eStateStopped:
stoppedThread = self.firstStoppedThread()
if stoppedThread:
self.process.SetSelectedThread(stoppedThread)
elif eventType == lldb.SBProcess.eBroadcastBitInterrupt: # 2
elif eventType == lldb.SBProcess.eBroadcastBitInterrupt: # 2
pass
elif eventType == lldb.SBProcess.eBroadcastBitSTDOUT:
# FIXME: Size?
@@ -1391,9 +1390,9 @@ class Dumper(DumperBase):
def describeBreakpoint(self, bp):
isWatch = isinstance(bp, lldb.SBWatchpoint)
if isWatch:
result = 'lldbid="%s"' % (qqWatchpointOffset + bp.GetID())
result = 'lldbid="%s"' % (qqWatchpointOffset + bp.GetID())
else:
result = 'lldbid="%s"' % bp.GetID()
result = 'lldbid="%s"' % bp.GetID()
result += ',valid="%s"' % (1 if bp.IsValid() else 0)
result += ',hitcount="%s"' % bp.GetHitCount()
if bp.IsValid():
@@ -1469,7 +1468,7 @@ class Dumper(DumperBase):
value = frame.FindVariable(args['expression'])
error = lldb.SBError()
bp = self.target.WatchAddress(value.GetLoadAddress(),
value.GetByteSize(), False, True, error)
value.GetByteSize(), False, True, error)
except:
bp = self.target.BreakpointCreateByName(None)
else:
@@ -1528,7 +1527,7 @@ class Dumper(DumperBase):
enabled = loc.IsEnabled()
res = True
self.reportResult('success="%s",enabled="%s",locid="%s"'
% (int(res), int(enabled), locId), args)
% (int(res), int(enabled), locId), args)
def removeBreakpoint(self, args):
lldbId = int(args['lldbid'])
@@ -1608,7 +1607,7 @@ class Dumper(DumperBase):
self.currentThread().StepInstruction(False)
self.reportResult('', args)
def executeStepOut(self, args = {}):
def executeStepOut(self, args={}):
self.currentThread().StepOut()
self.reportResult('', args)
@@ -1622,7 +1621,7 @@ class Dumper(DumperBase):
if bp.GetNumLocations() == 0:
self.target.BreakpointDelete(bp.GetID())
self.reportResult(self.describeStatus('No target location found.')
+ self.describeLocation(frame), args)
+ self.describeLocation(frame), args)
return
bp.SetOneShot(True)
self.reportResult('', args)
@@ -1647,7 +1646,7 @@ class Dumper(DumperBase):
bp = self.target.BreakpointCreateByAddress(addr)
else:
bp = self.target.BreakpointCreateByLocation(
str(args['file']), int(args['line']))
str(args['file']), int(args['line']))
if bp.GetNumLocations() == 0:
self.target.BreakpointDelete(bp.GetID())
status = 'No target location found.'
@@ -1663,7 +1662,7 @@ class Dumper(DumperBase):
result = lldb.SBCommandReturnObject()
self.debugger.GetCommandInterpreter().HandleCommand('break list', result)
self.report('success="%d",output="%s",error="%s"'
% (result.Succeeded(), result.GetOutput(), result.GetError()))
% (result.Succeeded(), result.GetOutput(), result.GetError()))
def activateFrame(self, args):
self.reportToken(args)
@@ -1675,7 +1674,7 @@ class Dumper(DumperBase):
self.process.SetSelectedThreadByID(int(args['id']))
self.reportResult('', args)
def fetchFullBacktrace(self, _ = None):
def fetchFullBacktrace(self, _=None):
command = 'thread backtrace all'
result = lldb.SBCommandReturnObject()
self.debugger.GetCommandInterpreter().HandleCommand(command, result)
@@ -1748,7 +1747,7 @@ class Dumper(DumperBase):
result += ',hunk="%s"}' % hunk
result += '{address="%s"' % loadAddr
result += ',data="%s %s"' % (insn.GetMnemonic(self.target),
insn.GetOperands(self.target))
insn.GetOperands(self.target))
result += ',function="%s"' % functionName
rawData = insn.GetData(self.target).uint8s
result += ',rawdata="%s"' % ' '.join(["%02x" % x for x in rawData])
@@ -1854,7 +1853,7 @@ class Tester(Dumper):
error = lldb.SBError()
launchInfo = lldb.SBLaunchInfo([])
launchInfo.SetWorkingDirectory(os.getcwd())
environmentList = [key + '=' + value for key,value in os.environ.items()]
environmentList = [key + '=' + value for key, value in os.environ.items()]
launchInfo.SetEnvironmentEntries(environmentList, False)
self.process = self.target.Launch(launchInfo, error)
@@ -1868,9 +1867,9 @@ class Tester(Dumper):
if listener.WaitForEvent(100, event):
#DumperBase.warn('EVENT: %s' % event)
state = lldb.SBProcess.GetStateFromEvent(event)
if state == lldb.eStateExited: # 10
if state == lldb.eStateExited: # 10
break
if state == lldb.eStateStopped: # 5
if state == lldb.eStateStopped: # 5
stoppedThread = None
for i in range(0, self.process.GetNumThreads()):
thread = self.process.GetThreadAtIndex(i)
@@ -1904,14 +1903,16 @@ class Tester(Dumper):
# ------------------------------ For use in LLDB ------------------------------
from pprint import pprint
__module__ = sys.modules[__name__]
DEBUG = False if not hasattr(__module__, 'DEBUG') else DEBUG
class LogMixin:
class LogMixin():
@staticmethod
def log(message = '', log_caller = False, frame = 1, args = ''):
def log(message='', log_caller=False, frame=1, args=''):
if not DEBUG:
return
if log_caller:
@@ -1925,13 +1926,15 @@ class LogMixin:
print(message)
@staticmethod
def log_fn(arg_str = ''):
LogMixin.log(log_caller = True, frame = 2, args = arg_str)
def log_fn(arg_str=''):
LogMixin.log(log_caller=True, frame=2, args=arg_str)
class DummyDebugger(object):
def __getattr__(self, attr):
raise AttributeError("Debugger should not be needed to create summaries")
class SummaryDumper(Dumper, LogMixin):
_instance = None
_lock = threading.RLock()
@@ -1971,9 +1974,9 @@ class SummaryDumper(Dumper, LogMixin):
Dumper.__init__(self, DummyDebugger())
self.setVariableFetchingOptions({
'fancy' : True,
'qobjectnames' : True,
'passexceptions' : True
'fancy': True,
'qobjectnames': True,
'passexceptions': True
})
self.dumpermodules = ['qttypes']
@@ -1981,19 +1984,19 @@ class SummaryDumper(Dumper, LogMixin):
self.output = ''
def report(self, stuff):
return # Don't mess up lldb output
return # Don't mess up lldb output
def lookupNativeTypeInAllModules(self, name):
self.warn('Failed to resolve type %s' % name)
return None
def dump_summary(self, valobj, expanded = False):
def dump_summary(self, valobj, expanded=False):
try:
from pygdbmi import gdbmiparser
except ImportError:
print("Qt summary provider requires the pygdbmi module, "
"please install using 'sudo /usr/bin/easy_install pygdbmi', "
"and then restart Xcode.")
"please install using 'sudo /usr/bin/easy_install pygdbmi', "
"and then restart Xcode.")
lldb.debugger.HandleCommand('type category delete Qt')
return None
@@ -2021,14 +2024,15 @@ class SummaryDumper(Dumper, LogMixin):
return summary
class SummaryProvider(LogMixin):
DEFAULT_SUMMARY = ''
VOID_PTR_TYPE = None
@staticmethod
def provide_summary(valobj, internal_dict, options = None):
if not __name__ in internal_dict:
def provide_summary(valobj, internal_dict, options=None):
if __name__ not in internal_dict:
# When disabling the import of the Qt summary providers, the
# summary functions are still registered with LLDB, and we will
# get callbacks to provide summaries, but at this point the child
@@ -2048,7 +2052,7 @@ class SummaryProvider(LogMixin):
return provider.get_summary(options)
def __init__(self, valobj, expand = False):
def __init__(self, valobj, expand=False):
# Prevent recursive evaluation during logging, etc
valobj.SetPreferSyntheticValue(False)
@@ -2088,29 +2092,29 @@ class SummaryProvider(LogMixin):
if encoding:
special_encodings = {
"empty" : "<empty>",
"minimumitemcount" : "<at least %s items>" % summaryValue,
"undefined" : "<undefined>",
"null" : "<null>",
"itemcount" : "<%s items>" % summaryValue,
"notaccessible" : "<not accessible>",
"optimizedout" : "<optimized out>",
"nullreference" : "<null reference>",
"emptystructure" : "<empty structure>",
"uninitialized" : "<uninitialized>",
"invalid" : "<invalid>",
"notcallable" : "<not callable>",
"outofscope" : "<out of scope>"
"empty": "<empty>",
"minimumitemcount": "<at least %s items>" % summaryValue,
"undefined": "<undefined>",
"null": "<null>",
"itemcount": "<%s items>" % summaryValue,
"notaccessible": "<not accessible>",
"optimizedout": "<optimized out>",
"nullreference": "<null reference>",
"emptystructure": "<empty structure>",
"uninitialized": "<uninitialized>",
"invalid": "<invalid>",
"notcallable": "<not callable>",
"outofscope": "<out of scope>"
}
if encoding in special_encodings:
return special_encodings[encoding]
text_encodings = [
'latin1',
# 'local8bit',
# 'local8bit',
'utf8',
'utf16',
# 'ucs4'
# 'ucs4'
]
if encoding in text_encodings:
@@ -2122,8 +2126,15 @@ class SummaryProvider(LogMixin):
return "<failed to decode '%s' as '%s'>" % (summaryValue, encoding)
# FIXME: Support these
other_encodings = ['int', 'uint', 'float', 'juliandate', 'juliandateandmillisecondssincemidnight',
'millisecondssincemidnight', 'ipv6addressandhexscopeid', 'datetimeinternal']
other_encodings = [
'int',
'uint',
'float',
'juliandate',
'juliandateandmillisecondssincemidnight',
'millisecondssincemidnight',
'ipv6addressandhexscopeid',
'datetimeinternal']
summaryValue += " <encoding='%s'>" % encoding
@@ -2136,9 +2147,10 @@ class SummaryProvider(LogMixin):
return summaryValue.strip()
class SyntheticChildrenProvider(SummaryProvider):
def __init__(self, valobj, dict):
SummaryProvider.__init__(self, valobj, expand = True)
SummaryProvider.__init__(self, valobj, expand=True)
self.summary = None
self.synthetic_children = []
@@ -2147,7 +2159,7 @@ class SyntheticChildrenProvider(SummaryProvider):
def num_children(self):
self.log("native: %d synthetic: %d" %
(self.num_native_children(), len(self.synthetic_children)), True)
(self.num_native_children(), len(self.synthetic_children)), True)
return self._num_children()
def _num_children(self):
@@ -2181,7 +2193,7 @@ class SyntheticChildrenProvider(SummaryProvider):
return value
def create_value(self, child, name = ''):
def create_value(self, child, name=''):
child_type = child.get('type', self.summary.get('childtype'))
value = None
@@ -2196,8 +2208,8 @@ class SyntheticChildrenProvider(SummaryProvider):
# Create as void* so that the value is fully initialized before
# we trigger our own summary/child providers recursively.
value = self.valobj.synthetic_child_from_address(name, address,
SummaryProvider.VOID_PTR_TYPE).Cast(value_type)
value = self.valobj.synthetic_child_from_address(
name, address, SummaryProvider.VOID_PTR_TYPE).Cast(value_type)
else:
self.log("Don't know how to create value for child %s" % child)
# FIXME: Figure out if we ever will hit this case, and deal with it
@@ -2219,7 +2231,7 @@ class SyntheticChildrenProvider(SummaryProvider):
dereference_child = None
for child in self.summary['children']:
if not child or not type(child) is dict:
if not child or not isinstance(child, dict):
continue
# Skip base classes, they are built-in children
@@ -2254,8 +2266,9 @@ class SyntheticChildrenProvider(SummaryProvider):
# the debugger UI, even if dereferencing the pointer works fine.
# We fall back to the special child reported by the Qt dumper.
if not self.valobj.GetNumChildren() and dereference_child:
self.valobj = self.create_value(dereference_child)
self.update()
self.valobj = self.create_value(dereference_child)
self.update()
def __lldb_init_module(debugger, internal_dict):
# Module is being imported in an LLDB session
@@ -2266,25 +2279,25 @@ def __lldb_init_module(debugger, internal_dict):
# Concrete types
summary_function = "%s.%s.%s" % (__name__, 'SummaryProvider', 'provide_summary')
types = map(lambda x: x.replace('__', '::'), dumper.qqDumpers)
debugger.HandleCommand("type summary add -F %s -w %s %s" \
% (summary_function, type_category, ' '.join(types)))
debugger.HandleCommand("type summary add -F %s -w %s %s"
% (summary_function, type_category, ' '.join(types)))
regex_types = list(map(lambda x: "'" + x + "'", dumper.qqDumpersEx.keys()))
if regex_types:
debugger.HandleCommand("type summary add -x -F %s -w %s %s" \
% (summary_function, type_category, ' '.join(regex_types)))
debugger.HandleCommand("type summary add -x -F %s -w %s %s"
% (summary_function, type_category, ' '.join(regex_types)))
# Global catch-all for Qt classes
debugger.HandleCommand("type summary add -x '^Q.*$' -F %s -w %s" \
% (summary_function, type_category))
debugger.HandleCommand("type summary add -x '^Q.*$' -F %s -w %s"
% (summary_function, type_category))
# Named summary ('frame variable foo --summary Qt')
debugger.HandleCommand("type summary add --name Qt -F %s -w %s" \
% (summary_function, type_category))
debugger.HandleCommand("type summary add --name Qt -F %s -w %s"
% (summary_function, type_category))
# Synthetic children
debugger.HandleCommand("type synthetic add -x '^Q.*$' -l %s -w %s" \
% ("lldbbridge.SyntheticChildrenProvider", type_category))
debugger.HandleCommand("type synthetic add -x '^Q.*$' -l %s -w %s"
% ("lldbbridge.SyntheticChildrenProvider", type_category))
debugger.HandleCommand('type category enable %s' % type_category)

View File

@@ -33,39 +33,46 @@ import re
#
#######################################################################
def qdump____m128(d, value):
d.putEmptyValue()
if d.isExpanded():
d.putArrayData(value.address(), 4, d.lookupType('float'))
def qdump____m256(d, value):
d.putEmptyValue()
if d.isExpanded():
d.putArrayData(value.address(), 8, d.lookupType('float'))
def qdump____m512(d, value):
d.putEmptyValue()
if d.isExpanded():
d.putArrayData(value.address(), 16, d.lookupType('float'))
def qdump____m128d(d, value):
d.putEmptyValue()
if d.isExpanded():
d.putArrayData(value.address(), 2, d.lookupType('double'))
def qdump____m256d(d, value):
d.putEmptyValue()
if d.isExpanded():
d.putArrayData(value.address(), 4, d.lookupType('double'))
def qdump____m512d(d, value):
d.putEmptyValue()
if d.isExpanded():
d.putArrayData(value.address(), 8, d.lookupType('double'))
def qdump____m128i(d, value):
data = d.hexencode(value.data(16))
d.putValue(':'.join('%04x' % int(data[i:i+4], 16) for i in range(0, 32, 4)))
d.putValue(':'.join('%04x' % int(data[i:i + 4], 16) for i in range(0, 32, 4)))
if d.isExpanded():
with Children(d):
addr = value.address()
@@ -74,9 +81,10 @@ def qdump____m128i(d, value):
d.putArrayItem('uint32x4', addr, 4, 'unsigned int')
d.putArrayItem('uint64x2', addr, 2, 'unsigned long long')
def qdump____m256i(d, value):
data = d.hexencode(value.data(32))
d.putValue(':'.join('%04x' % int(data[i:i+4], 16) for i in range(0, 64, 4)))
d.putValue(':'.join('%04x' % int(data[i:i + 4], 16) for i in range(0, 64, 4)))
if d.isExpanded():
with Children(d):
addr = value.address()
@@ -85,10 +93,11 @@ def qdump____m256i(d, value):
d.putArrayItem('uint32x8', addr, 8, 'unsigned int')
d.putArrayItem('uint64x4', addr, 4, 'unsigned long long')
def qdump____m512i(d, value):
data = d.hexencode(value.data(64))
d.putValue(':'.join('%04x' % int(data[i:i+4], 16) for i in range(0, 64, 4))
+ ', ' + ':'.join('%04x' % int(data[i:i+4], 16) for i in range(64, 128, 4)))
d.putValue(':'.join('%04x' % int(data[i:i + 4], 16) for i in range(0, 64, 4))
+ ', ' + ':'.join('%04x' % int(data[i:i + 4], 16) for i in range(64, 128, 4)))
if d.isExpanded():
with Children(d):
d.putArrayItem('uint32x16', value.address(), 16, 'unsigned int')
@@ -100,8 +109,10 @@ def qdump____m512i(d, value):
#
#######################################################################
def qform__std__array():
return [DisplayFormat.ArrayPlotFormat]
return [DisplayFormat.ArrayPlot]
def qdump__gsl__span(d, value):
size, pointer = value.split('pp')
@@ -109,6 +120,7 @@ def qdump__gsl__span(d, value):
if d.isExpanded():
d.putPlotData(pointer, size, value.type[0])
def qdump__gsl__byte(d, value):
d.putNumChild(0)
d.putValue(value.integer())
@@ -122,6 +134,7 @@ def qdump__gsl__byte(d, value):
#def qform__Eigen__Matrix():
# return 'Transposed'
def qdump__Eigen__Matrix(d, value):
innerType = value.type[0]
argRow = value.type[1]
@@ -185,9 +198,10 @@ def qdump__NimStringDesc(d, value):
d.putBetterType('string')
d.putCharArrayHelper(data, size, d.createType('char'), 'utf8')
def qdump__NimGenericSequence__(d, value, regex = '^TY[\d]+$'):
def qdump__NimGenericSequence__(d, value, regex=r'^TY[\d]+$'):
code = value.type.stripTypedefs().code
if code == TypeCode.TypeCodeStruct:
if code == TypeCode.Struct:
size, reserved = d.split('pp', value)
data = value.address() + 2 * d.ptrSize()
typeobj = value['data'].type.dereference()
@@ -198,6 +212,7 @@ def qdump__NimGenericSequence__(d, value, regex = '^TY[\d]+$'):
d.putEmptyValue()
d.putPlainChildren(value)
def qdump__TNimNode(d, value):
name = value['name'].pointer()
d.putSimpleCharArray(name) if name != 0 else d.putEmptyValue()
@@ -222,6 +237,7 @@ def qdump__TNimNode(d, value):
def cleanDType(type):
return str(type).replace('uns long long', 'string')
def qdump_Array(d, value):
n = value['length']
p = value['ptr']
@@ -251,7 +267,7 @@ def qdump_AArray(d, value):
d.putEmptyValue()
if d.isExpanded():
with Children(d, 1):
d.putSubItem('ptr', p)
d.putSubItem('ptr', p)
#######################################################################
@@ -264,7 +280,7 @@ if False:
def qdump__tree_entry(d, value):
d.putValue('len: %s, offset: %s, type: %s' %
(value['blocklength'], value['offset'], value['type']))
(value['blocklength'], value['offset'], value['type']))
d.putNumChild(0)
def qdump__tree(d, value):
@@ -273,42 +289,42 @@ if False:
base = value['base'].pointer()
d.putItemCount(count)
if d.isExpanded():
with Children(d):
with SubItem(d, 'tree'):
d.putEmptyValue()
d.putNoType()
if d.isExpanded():
with Children(d):
for i in range(count):
d.putSubItem(Item(entries[i], iname))
with SubItem(d, 'data'):
d.putEmptyValue()
d.putNoType()
if d.isExpanded():
with Children(d):
for i in range(count):
with SubItem(d, i):
entry = entries[i]
mpitype = str(entry['type'])
d.putType(mpitype)
length = int(entry['blocklength'])
offset = int(entry['offset'])
d.putValue('%s items at %s' % (length, offset))
if mpitype == 'MPI_INT':
innerType = 'int'
elif mpitype == 'MPI_CHAR':
innerType = 'char'
elif mpitype == 'MPI_DOUBLE':
innerType = 'double'
else:
length = 0
d.putNumChild(length)
if d.isExpanded():
with Children(d):
t = d.lookupType(innerType).pointer()
p = (base + offset).cast(t)
for j in range(length):
d.putSubItem(j, p.dereference())
with Children(d):
with SubItem(d, 'tree'):
d.putEmptyValue()
d.putNoType()
if d.isExpanded():
with Children(d):
for i in range(count):
d.putSubItem(Item(entries[i], iname))
with SubItem(d, 'data'):
d.putEmptyValue()
d.putNoType()
if d.isExpanded():
with Children(d):
for i in range(count):
with SubItem(d, i):
entry = entries[i]
mpitype = str(entry['type'])
d.putType(mpitype)
length = int(entry['blocklength'])
offset = int(entry['offset'])
d.putValue('%s items at %s' % (length, offset))
if mpitype == 'MPI_INT':
innerType = 'int'
elif mpitype == 'MPI_CHAR':
innerType = 'char'
elif mpitype == 'MPI_DOUBLE':
innerType = 'double'
else:
length = 0
d.putNumChild(length)
if d.isExpanded():
with Children(d):
t = d.lookupType(innerType).pointer()
p = (base + offset).cast(t)
for j in range(length):
d.putSubItem(j, p.dereference())
#######################################################################
@@ -322,6 +338,7 @@ def qdump__KDSoapValue1(d, value):
d.putStringValue(inner['m_name'])
d.putPlainChildren(inner)
def qdump__KDSoapValue(d, value):
p = (value.cast(d.lookupType('char*')) + 4).dereference().cast(d.lookupType('QString'))
d.putStringValue(p)
@@ -528,6 +545,7 @@ def qdump__PyVarObject(d, value):
def qdump__QtcDumperTest_FieldAccessByIndex(d, value):
d.putValue(value["d"][2].integer())
def qdump__QtcDumperTest_PointerArray(d, value):
foos = value["foos"]
d.putItemCount(10)
@@ -536,6 +554,7 @@ def qdump__QtcDumperTest_PointerArray(d, value):
for i in d.childRange():
d.putSubItem(i, foos[i])
def qdump__QtcDumperTest_BufArray(d, value):
maxItems = 1000
buffer = value['buffer']
@@ -549,11 +568,12 @@ def qdump__QtcDumperTest_BufArray(d, value):
for i in d.childRange():
d.putSubItem(i, (buffer + (i * objsize)).dereference().cast(valueType))
def qdump__QtcDumperTest_List__NodeX(d, value):
typename = value.type.unqualified().name
pos0 = typename.find('<')
pos1 = typename.find('>')
tName = typename[pos0+1:pos1]
tName = typename[pos0 + 1:pos1]
d.putBetterType('QtcDumperTest_List<' + tName + '>::Node')
d.putNumChild(1)
if d.isExpanded():
@@ -563,6 +583,7 @@ def qdump__QtcDumperTest_List__NodeX(d, value):
d.putFields(value)
#d.putPlainChildren(value)
def qdump__QtcDumperTest_List(d, value):
innerType = value.type[0]
d.putNumChild(1)
@@ -574,6 +595,7 @@ def qdump__QtcDumperTest_List(d, value):
d.putFields(value)
#d.putPlainChildren(value)
def qdump__QtcDumperTest_String(d, value):
with Children(d):
first = d.hexdecode(d.putSubItem('first', value['first']).value)

View File

@@ -26,16 +26,19 @@
from dumper import Children, SubItem
from utils import TypeCode, DisplayFormat
def qdump__cv__Size_(d, value):
d.putValue('(%s, %s)' % (value[0].display(), value[1].display()))
d.putPlainChildren(value)
def qform__cv__Mat():
return [DisplayFormat.SeparateFormat]
return [DisplayFormat.Separate]
def qdump__cv__Mat(d, value):
(flag, dims, rows, cols, data, refcount, datastart, dataend,
datalimit, allocator, size, stepp) \
datalimit, allocator, size, stepp) \
= value.split('iiiipppppppp')
steps = d.split('p' * dims, stepp)
innerSize = 0 if dims == 0 else steps[dims - 1]
@@ -44,7 +47,7 @@ def qdump__cv__Mat(d, value):
d.putPlainChildren(value)
return
if d.currentItemFormat() == DisplayFormat.SeparateFormat:
if d.currentItemFormat() == DisplayFormat.Separate:
rs = steps[0] * innerSize
cs = cols * innerSize
dform = 'arraydata:separate:int:%d::2:%d:%d' % (innerSize, cols, rows)
@@ -54,7 +57,7 @@ def qdump__cv__Mat(d, value):
d.putValue('(%s x %s)' % (rows, cols))
if d.isExpanded():
with Children(d):
innerType = d.createType(TypeCode.TypeCodeIntegral, innerSize)
innerType = d.createType(TypeCode.Integral, innerSize)
for i in range(rows):
for j in range(cols):
with SubItem(d, None):

View File

@@ -41,7 +41,7 @@ class QuitException(Exception):
pass
class QtcInternalBreakpoint:
class QtcInternalBreakpoint():
"""Breakpoint class.
Breakpoints are indexed by number through bpbynumber and by
the file,line tuple using bplist. The former points to a
@@ -52,9 +52,9 @@ class QtcInternalBreakpoint:
next = 1 # Next bp to be assigned
bplist = {} # indexed by (file, lineno) tuple
bpbynumber = [None] # Each entry is None or an instance of Bpt
# index 0 is unused, except for marking an
# effective break .... see effective()
bpbynumber = [None] # Each entry is None or an instance of Bpt
# index 0 is unused, except for marking an
# effective break .... see effective()
def __init__(self, filepath, line, temporary=False, cond=None, funcname=None):
self.funcname = funcname
@@ -115,7 +115,7 @@ def checkfuncname(b, frame):
# The function is entered for the 1st time.
b.func_first_executable_line = frame.f_lineno
if b.func_first_executable_line != frame.f_lineno:
if b.func_first_executable_line != frame.f_lineno:
# But we are not at the first line number: don't break.
return False
return True
@@ -193,7 +193,7 @@ class _rstr(str):
return self
class QtcInternalDumper:
class QtcInternalDumper():
identchars = string.ascii_letters + string.digits + '_'
lastcmd = ''
use_rawinput = 1
@@ -387,7 +387,7 @@ class QtcInternalDumper:
# (CT) stopframe may now also be None, see dispatch_call.
# (CT) the former test for None is therefore removed from here.
if self.skip and \
self.is_skipped_module(frame.f_globals.get('__name__')):
self.is_skipped_module(frame.f_globals.get('__name__')):
return False
if frame is self.stopframe:
if self.stoplineno == -1:
@@ -696,7 +696,7 @@ class QtcInternalDumper:
return None, None, line
i, length = 0, len(line)
while i < length and line[i] in self.identchars:
i = i+1
i = i + 1
cmd, arg = line[:i], line[i:].strip()
return cmd, arg, line
@@ -745,10 +745,10 @@ class QtcInternalDumper:
import __main__
# __main__.__dict__.clear()
__main__.__dict__.update({'__name__' : '__main__',
'__file__' : mainpyfile,
# '__builtins__': __builtins__,
})
__main__.__dict__.update({'__name__': '__main__',
'__file__': mainpyfile,
#'__builtins__': __builtins__,
})
# When bdb sets tracing, a number of call and line events happens
# BEFORE debugger even reaches user's code (and the exact sequence of
@@ -966,7 +966,7 @@ class QtcInternalDumper:
comma = arg.find(',')
if comma > 0:
# parse stuff after comma: 'condition'
cond = arg[comma+1:].lstrip()
cond = arg[comma + 1:].lstrip()
arg = arg[:comma].rstrip()
# parse stuff before comma: [filename:]lineno | function
colon = arg.rfind(':')
@@ -979,7 +979,7 @@ class QtcInternalDumper:
return
else:
filename = f
arg = arg[colon+1:].lstrip()
arg = arg[colon + 1:].lstrip()
try:
lineno = int(arg)
except ValueError:
@@ -1212,7 +1212,7 @@ class QtcInternalDumper:
# Make sure it works for 'clear C:\foo\bar.py:12'
i = arg.rfind(':')
filename = arg[:i]
arg = arg[i+1:]
arg = arg[i + 1:]
try:
lineno = int(arg)
except ValueError:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,15 @@
[pycodestyle]
max-line-length = 100
ignore =
# E222 - multiple spaces after operator: Used for alignments
E222,
# E241 - multiple spaces after ',': Used for alignments
E241,
# E265 - block comment should start with '# ': We have a bunch of #warn(foo) lines
# a space after # would leave an incorrect indentation after uncommenting
E265,
# E402 - module level import not at top of file: Sometimes we need to adjust the sys.path before
# we can import
E402,
# E722 - do not use bare except, specify exception instead: TODO
E722

View File

@@ -26,8 +26,10 @@
from utils import DisplayFormat
from dumper import Children, SubItem
def qform__std__array():
return [DisplayFormat.ArrayPlotFormat]
return [DisplayFormat.ArrayPlot]
def qdump__std__array(d, value):
size = value.type[1]
@@ -37,7 +39,8 @@ def qdump__std__array(d, value):
def qform__std____1__array():
return [DisplayFormat.ArrayPlotFormat]
return [DisplayFormat.ArrayPlot]
def qdump__std____1__array(d, value):
qdump__std__array(d, value)
@@ -66,6 +69,7 @@ def qdump__std__complex(d, value):
d.putSubItem("real", real)
d.putSubItem("imag", imag)
def qdump__std____1__complex(d, value):
qdump__std__complex(d, value)
@@ -85,7 +89,7 @@ def qdump__std__deque(d, value):
bufsize = 512 // innerSize
(mapptr, mapsize, startCur, startFirst, startLast, startNode,
finishCur, finishFirst, finishLast, finishNode) = value.split("pppppppppp")
finishCur, finishFirst, finishLast, finishNode) = value.split("pppppppppp")
size = bufsize * ((finishNode - startNode) // d.ptrSize() - 1)
size += (finishCur - finishFirst) // innerSize
@@ -108,6 +112,7 @@ def qdump__std__deque(d, value):
pcur = pfirst
pnode = newnode
def qdump__std____1__deque(d, value):
mptr, mfirst, mbegin, mend, start, size = value.split("pppptt")
d.check(0 <= size and size <= 1000 * 1000 * 1000)
@@ -123,6 +128,7 @@ def qdump__std____1__deque(d, value):
base = d.extractPointer(mfirst + k * ptrSize)
d.putSubItem(i, d.createValue(base + j * innerSize, innerType))
def qdump__std__deque__QNX(d, value):
innerType = value.type[0]
innerSize = innerType.size()
@@ -157,7 +163,8 @@ def qdump__std__deque__QNX(d, value):
if mapsize <= block:
block -= mapsize
d.putSubItem(i, map[block][offset])
myoff += 1;
myoff += 1
def qdump__std__deque__MSVC(d, value):
innerType = value.type[0]
@@ -187,6 +194,7 @@ def qdump__std__deque__MSVC(d, value):
d.putSubItem(i, d.createValue(address, innerType))
myoff += 1
def qdump__std____debug__deque(d, value):
qdump__std__deque(d, value)
@@ -218,6 +226,7 @@ def qdump__std__list(d, value):
d.putSubItem(i, d.createValue(p + 2 * d.ptrSize(), innerType))
p = d.extractPointer(p)
def qdump__std__list__QNX(d, value):
(proxy, head, size) = value.split("ppp")
d.putItemCount(size, 1000)
@@ -230,12 +239,15 @@ def qdump__std__list__QNX(d, value):
d.putSubItem(i, d.createValue(p + 2 * d.ptrSize(), innerType))
p = d.extractPointer(p)
def qdump__std____debug__list(d, value):
qdump__std__list(d, value)
def qdump__std____cxx11__list(d, value):
qdump__std__list(d, value)
def qdump__std____1__list(d, value):
if value.type.size() == 3 * d.ptrSize():
# C++11 only.
@@ -260,8 +272,10 @@ def qdump__std____1__list(d, value):
(prev, p, val) = d.split(typeCode, p)
d.putSubItem(i, val)
def qform__std__map():
return [DisplayFormat.CompactMapFormat]
return [DisplayFormat.CompactMap]
def qdump__std__map(d, value):
if d.isQnxTarget() or d.isMsvcTarget():
@@ -270,7 +284,7 @@ def qdump__std__map(d, value):
# stuff is actually (color, pad) with 'I@', but we can save cycles/
(compare, stuff, parent, left, right, size) = value.split('pppppp')
d.check(0 <= size and size <= 100*1000*1000)
d.check(0 <= size and size <= 100 * 1000 * 1000)
d.putItemCount(size)
if d.isExpanded():
@@ -299,16 +313,19 @@ def qdump__std__map(d, value):
break
node = node["_M_left"]
def qdump_std__map__helper(d, value):
(proxy, head, size) = value.split("ppp")
d.check(0 <= size and size <= 100*1000*1000)
d.check(0 <= size and size <= 100 * 1000 * 1000)
d.putItemCount(size)
if d.isExpanded():
keyType = value.type[0]
valueType = value.type[1]
pairType = value.type[3][0]
def helper(node):
(left, parent, right, color, isnil, pad, pair) = d.split("pppcc@{%s}" % (pairType.name), node)
(left, parent, right, color, isnil, pad, pair) = d.split(
"pppcc@{%s}" % (pairType.name), node)
if left != head:
for res in helper(left):
yield res
@@ -322,24 +339,31 @@ def qdump_std__map__helper(d, value):
for (pair, i) in zip(helper(root), d.childRange()):
d.putPairItem(i, pair)
def qdump__std____debug__map(d, value):
qdump__std__map(d, value)
def qdump__std____debug__set(d, value):
qdump__std__set(d, value)
def qdump__std__multiset(d, value):
qdump__std__set(d, value)
def qdump__std____cxx1998__map(d, value):
qdump__std__map(d, value)
def qform__std__multimap():
return [DisplayFormat.CompactMapFormat]
return [DisplayFormat.CompactMap]
def qdump__std__multimap(d, value):
return qdump__std__map(d, value)
def qdumpHelper__std__tree__iterator(d, value, isSet=False):
treeTypeName = None
if value.type.name.endswith("::iterator"):
@@ -375,30 +399,39 @@ def qdumpHelper__std__tree__iterator(d, value, isSet=False):
d.putSubItem("right", d.createValue(right, nodeType))
d.putSubItem("parent", d.createValue(parent, nodeType))
def qdump__std___Rb_tree_iterator(d, value):
qdumpHelper__std__tree__iterator(d, value)
def qdump__std___Rb_tree_const_iterator(d, value):
qdumpHelper__std__tree__iterator(d, value)
def qdump__std__map__iterator(d, value):
qdumpHelper__std__tree__iterator(d, value)
def qdump____gnu_debug___Safe_iterator(d, value):
d.putItem(value["_M_current"])
def qdump__std__map__const_iterator(d, value):
qdumpHelper__std__tree__iterator(d, value)
def qdump__std__set__iterator(d, value):
qdumpHelper__std__tree__iterator(d, value, True)
def qdump__std__set__const_iterator(d, value):
qdumpHelper__std__tree__iterator(d, value, True)
def qdump__std____cxx1998__set(d, value):
qdump__std__set(d, value)
def qdumpHelper__std__tree__iterator_MSVC(d, value):
d.putNumChild(1)
d.putEmptyValue()
@@ -416,9 +449,11 @@ def qdumpHelper__std__tree__iterator_MSVC(d, value):
else:
d.putSubItem("value", child)
def qdump__std___Tree_const_iterator(d, value):
qdumpHelper__std__tree__iterator_MSVC(d, value)
def qdump__std___Tree_iterator(d, value):
qdumpHelper__std__tree__iterator_MSVC(d, value)
@@ -430,7 +465,7 @@ def qdump__std__set(d, value):
impl = value["_M_t"]["_M_impl"]
size = impl["_M_node_count"].integer()
d.check(0 <= size and size <= 100*1000*1000)
d.check(0 <= size and size <= 100 * 1000 * 1000)
d.putItemCount(size)
if d.isExpanded():
valueType = value.type[0]
@@ -453,14 +488,17 @@ def qdump__std__set(d, value):
while node["_M_left"].pointer() != 0:
node = node["_M_left"]
def qdump__std__set__QNX(d, value):
(proxy, head, size) = value.split("ppp")
d.check(0 <= size and size <= 100*1000*1000)
d.check(0 <= size and size <= 100 * 1000 * 1000)
d.putItemCount(size)
if d.isExpanded():
childType=value.type[0]
childType = value.type[0]
def helper(node):
(left, parent, right, color, isnil, pad, value) = d.split("pppcc@{%s}" % childType.name, node)
(left, parent, right, color, isnil, pad, value) = d.split(
"pppcc@{%s}" % childType.name, node)
if left != head:
for res in helper(left):
yield res
@@ -474,6 +512,7 @@ def qdump__std__set__QNX(d, value):
for (item, i) in zip(helper(root), d.childRange()):
d.putSubItem(i, item)
def std1TreeMin(d, node):
#_NodePtr __tree_min(_NodePtr __x):
# while (__x->__left_ != nullptr)
@@ -485,6 +524,7 @@ def std1TreeMin(d, node):
node = left
return node
def std1TreeIsLeftChild(d, node):
# bool __tree_is_left_child(_NodePtr __x):
# return __x == __x->__parent_->__left_;
@@ -508,10 +548,11 @@ def std1TreeNext(d, node):
node = node['__parent_']
return node['__parent_']
def qdump__std____1__set(d, value):
(proxy, head, size) = value.split("ppp")
d.check(0 <= size and size <= 100*1000*1000)
d.check(0 <= size and size <= 100 * 1000 * 1000)
d.putItemCount(size)
if d.isExpanded():
@@ -534,21 +575,24 @@ def qdump__std____1__set(d, value):
for (i, data) in zip(d.childRange(), in_order_traversal(head)):
d.putSubItem(i, data)
def qdump__std____1__multiset(d, value):
qdump__std____1__set(d, value)
def qform__std____1__map():
return [DisplayFormat.CompactMapFormat]
return [DisplayFormat.CompactMap]
def qdump__std____1__map(d, value):
try:
(proxy, head, size) = value.split("ppp")
d.check(0 <= size and size <= 100*1000*1000)
d.check(0 <= size and size <= 100 * 1000 * 1000)
# Sometimes there is extra data at the front. Don't know why at the moment.
except RuntimeError:
(junk, proxy, head, size) = value.split("pppp")
d.check(0 <= size and size <= 100*1000*1000)
d.check(0 <= size and size <= 100 * 1000 * 1000)
d.putItemCount(size)
@@ -574,12 +618,15 @@ def qdump__std____1__map(d, value):
for (i, pair) in zip(d.childRange(), in_order_traversal(head)):
d.putPairItem(i, pair, 'key', 'value')
def qform__std____1__multimap():
return [DisplayFormat.CompactMapFormat]
return [DisplayFormat.CompactMap]
def qdump__std____1__multimap(d, value):
qdump__std____1__map(d, value)
def qdump__std____1__map__iterator(d, value):
d.putEmptyValue()
if d.isExpanded():
@@ -588,9 +635,11 @@ def qdump__std____1__map__iterator(d, value):
d.putSubItem('first', node['first'])
d.putSubItem('second', node['second'])
def qdump__std____1__map__const_iterator(d, value):
qdump__std____1__map__iterator(d, value)
def qdump__std____1__set__iterator(d, value):
d.putEmptyValue()
d.putNumChild(1)
@@ -606,27 +655,34 @@ def qdump__std____1__set__iterator(d, value):
node = node.cast(keyType)
d.putSubItem('value', node)
def qdump__std____1__set_const_iterator(d, value):
qdump__std____1__set__iterator(d, value)
def qdump__std__stack(d, value):
d.putItem(value["c"])
d.putBetterType(value.type)
def qdump__std____debug__stack(d, value):
qdump__std__stack(d, value)
def qdump__std____1__stack(d, value):
d.putItem(value["c"])
d.putBetterType(value.type)
def qform__std__string():
return [DisplayFormat.Latin1StringFormat, DisplayFormat.SeparateLatin1StringFormat,
DisplayFormat.Utf8StringFormat, DisplayFormat.SeparateUtf8StringFormat ]
return [DisplayFormat.Latin1String, DisplayFormat.SeparateLatin1String,
DisplayFormat.Utf8String, DisplayFormat.SeparateUtf8String]
def qdump__std__string(d, value):
qdumpHelper_std__string(d, value, d.createType("char"), d.currentItemFormat())
def qdumpHelper_std__string(d, value, charType, format):
if d.isQnxTarget():
qdumpHelper__std__string__QNX(d, value, charType, format)
@@ -650,34 +706,37 @@ def qdumpHelper_std__string(d, value, charType, format):
# struct { size_type _M_length, size_type _M_capacity, int _M_refcount; }
(size, alloc, refcount) = d.split("ppp", data - 3 * d.ptrSize())
refcount = refcount & 0xffffffff
d.check(refcount >= -1) # Can be -1 according to docs.
d.check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
d.check(refcount >= -1) # Can be -1 according to docs.
d.check(0 <= size and size <= alloc and alloc <= 100 * 1000 * 1000)
d.putCharArrayHelper(data, size, charType, format)
def qdumpHelper__std__string__QNX(d, value, charType, format):
size = value['_Mysize']
alloc = value['_Myres']
_BUF_SIZE = int(16 / charType.size())
if _BUF_SIZE <= alloc: #(_BUF_SIZE <= _Myres ? _Bx._Ptr : _Bx._Buf);
if _BUF_SIZE <= alloc: # (_BUF_SIZE <= _Myres ? _Bx._Ptr : _Bx._Buf);
data = value['_Bx']['_Ptr']
else:
data = value['_Bx']['_Buf']
sizePtr = data.cast(d.charType().pointer())
refcount = int(sizePtr[-1])
d.check(refcount >= -1) # Can be -1 accoring to docs.
d.check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
d.check(refcount >= -1) # Can be -1 accoring to docs.
d.check(0 <= size and size <= alloc and alloc <= 100 * 1000 * 1000)
d.putCharArrayHelper(sizePtr, size, charType, format)
def qdumpHelper__std__string__MSVC(d, value, charType, format):
(proxy, buffer, size, alloc) = value.split("p16spp");
_BUF_SIZE = int(16 / charType.size());
d.check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
(proxy, buffer, size, alloc) = value.split("p16spp")
_BUF_SIZE = int(16 / charType.size())
d.check(0 <= size and size <= alloc and alloc <= 100 * 1000 * 1000)
if _BUF_SIZE <= alloc:
(proxy, data) = value.split("pp");
(proxy, data) = value.split("pp")
else:
data = value.address() + d.ptrSize()
d.putCharArrayHelper(data, size, charType, format)
def qdump__std____1__string(d, value):
firstByte = value.split('b')[0]
if int(firstByte & 1) == 0:
@@ -707,9 +766,11 @@ def qdump__std____1__wstring(d, value):
def qdump__std____weak_ptr(d, value):
return qdump__std__shared_ptr(d, value)
def qdump__std__weak_ptr(d, value):
return qdump__std__shared_ptr(d, value)
def qdump__std____1__weak_ptr(d, value):
return qdump__std____1__shared_ptr(d, value)
@@ -727,6 +788,7 @@ def qdump__std__shared_ptr(d, value):
d.putItem(i.dereference())
d.putBetterType(value.type)
def qdump__std____1__shared_ptr(d, value):
i = value["__ptr_"]
if i.pointer() == 0:
@@ -736,6 +798,7 @@ def qdump__std____1__shared_ptr(d, value):
d.putItem(i.dereference())
d.putBetterType(value.type)
def qdump__std__unique_ptr(d, value):
p = d.extractPointer(value)
if p == 0:
@@ -745,6 +808,7 @@ def qdump__std__unique_ptr(d, value):
d.putItem(d.createValue(p, value.type[0]))
d.putBetterType(value.type)
def qdump__std____1__unique_ptr(d, value):
qdump__std__unique_ptr(d, value)
@@ -760,11 +824,14 @@ def qdump__std__pair(d, value):
d.putField('keyencoded', key.encoding)
d.putValue(value.value, value.encoding)
def qform__std__unordered_map():
return [DisplayFormat.CompactMapFormat]
return [DisplayFormat.CompactMap]
def qform__std____debug__unordered_map():
return [DisplayFormat.CompactMapFormat]
return [DisplayFormat.CompactMap]
def qdump__std__unordered_map(d, value):
if d.isQnxTarget() or d.isMsvcTarget():
@@ -806,6 +873,7 @@ def qdump__std__unordered_map(d, value):
p, pad, key, pad, val = d.split(typeCode, p)
d.putPairItem(i, (key, val))
def qdump__std____debug__unordered_map(d, value):
qdump__std__unordered_map(d, value)
@@ -813,12 +881,15 @@ def qdump__std____debug__unordered_map(d, value):
def qform__std__unordered_multimap():
return qform__std__unordered_map()
def qform__std____debug__unordered_multimap():
return qform__std____debug__unordered_map()
def qdump__std__unordered_multimap(d, value):
qdump__std__unordered_map(d, value)
def qdump__std____debug__unordered_multimap(d, value):
qdump__std__unordered_multimap(d, value)
@@ -861,8 +932,10 @@ def qdump__std__unordered_set(d, value):
d.putSubItem(i, d.createValue(p + ptrSize - offset, valueType))
p = d.extractPointer(p + offset)
def qform__std____1__unordered_map():
return [DisplayFormat.CompactMapFormat]
return [DisplayFormat.CompactMap]
def qdump__std____1__unordered_map(d, value):
(size, _) = value["__table_"]["__p2_"].split("pp")
@@ -909,15 +982,18 @@ def qdump__std____1__unordered_set(d, value):
def qdump__std____debug__unordered_set(d, value):
qdump__std__unordered_set(d, value)
def qdump__std__unordered_multiset(d, value):
qdump__std__unordered_set(d, value)
def qdump__std____debug__unordered_multiset(d, value):
qdump__std__unordered_multiset(d, value)
def qform__std__valarray():
return [DisplayFormat.ArrayPlotFormat]
return [DisplayFormat.ArrayPlot]
def qdump__std__valarray(d, value):
if d.isMsvcTarget():
@@ -929,7 +1005,8 @@ def qdump__std__valarray(d, value):
def qform__std____1__valarray():
return [DisplayFormat.ArrayPlotFormat]
return [DisplayFormat.ArrayPlot]
def qdump__std____1__valarray(d, value):
innerType = value.type[0]
@@ -940,7 +1017,8 @@ def qdump__std____1__valarray(d, value):
def qform__std__vector():
return [DisplayFormat.ArrayPlotFormat]
return [DisplayFormat.ArrayPlot]
def qedit__std__vector(d, value, data):
import gdb
@@ -954,12 +1032,14 @@ def qedit__std__vector(d, value, data):
cmd = "set (%s[%d])*$d={%s}" % (innerType, n, data)
gdb.execute(cmd)
def qdump__std__vector(d, value):
if d.isQnxTarget() or d.isMsvcTarget():
qdumpHelper__std__vector__QNX(d, value)
else:
qdumpHelper__std__vector(d, value, False)
def qdumpHelper__std__vector(d, value, isLibCpp):
innerType = value.type[0]
isBool = innerType.name == 'bool'
@@ -975,7 +1055,7 @@ def qdumpHelper__std__vector(d, value, isLibCpp):
finish = value["_M_finish"]["_M_p"].pointer()
foffset = value["_M_finish"]["_M_offset"].integer()
alloc = value["_M_end_of_storage"].pointer()
size = (finish - start) * 8 + foffset - soffset # 8 is CHAR_BIT.
size = (finish - start) * 8 + foffset - soffset # 8 is CHAR_BIT.
else:
if isLibCpp:
start = value["__begin_"].pointer()
@@ -1007,6 +1087,7 @@ def qdumpHelper__std__vector(d, value, isLibCpp):
else:
d.putPlotData(start, size, innerType)
def qdumpHelper__std__vector__QNX(d, value):
innerType = value.type[0]
isBool = innerType.name == 'bool'
@@ -1036,14 +1117,18 @@ def qdumpHelper__std__vector__QNX(d, value):
else:
d.putPlotData(start, size, innerType)
def qform__std____1__vector():
return [DisplayFormat.ArrayPlotFormat]
return [DisplayFormat.ArrayPlot]
def qdump__std____1__vector(d, value):
qdumpHelper__std__vector(d, value, True)
def qform__std____debug__vector():
return [DisplayFormat.ArrayPlotFormat]
return [DisplayFormat.ArrayPlot]
def qdump__std____debug__vector(d, value):
qdump__std__vector(d, value)
@@ -1067,37 +1152,48 @@ def qdump__std__initializer_list(d, value):
if d.isExpanded():
d.putPlotData(start, size, innerType)
def qedit__std__string(d, value, data):
d.call('void', value, 'assign', '"%s"' % data.replace('"', '\\"'))
def qedit__string(d, expr, value):
qedit__std__string(d, expr, value)
def qedit__std____cxx11__string(d, expr, value):
qedit__std__string(d, expr, value)
def qedit__std__wstring(d, value, data):
d.call('void', value, 'assign', 'L"%s"' % data.replace('"', '\\"'))
def qedit__wstring(d, expr, value):
qedit__std__wstring(d, expr, value)
def qedit__std____cxx11__wstring(d, expr, value):
qedit__std__wstring(d, expr, value)
def qdump__string(d, value):
qdump__std__string(d, value)
def qform__std__wstring():
return [DisplayFormat.SimpleFormat, DisplayFormat.SeparateFormat]
return [DisplayFormat.Simple, DisplayFormat.Separate]
def qdump__std__wstring(d, value):
qdumpHelper_std__string(d, value, d.createType('wchar_t'), d.currentItemFormat())
def qdump__std__basic_string(d, value):
innerType = value.type[0]
qdumpHelper_std__string(d, value, innerType, d.currentItemFormat())
def qdump__std____cxx11__basic_string(d, value):
innerType = value.type[0]
try:
@@ -1107,24 +1203,30 @@ def qdump__std____cxx11__basic_string(d, value):
d.putEmptyValue()
d.putPlainChildren(value)
return
d.check(0 <= size) #and size <= alloc and alloc <= 100*1000*1000)
d.check(0 <= size) # and size <= alloc and alloc <= 100*1000*1000)
d.putCharArrayHelper(data, size, innerType, d.currentItemFormat())
def qform__std____cxx11__string(d, value):
qform__std__string(d, value)
def qdump__std____cxx11__string(d, value):
(data, size) = value.split("pI")
d.check(0 <= size) #and size <= alloc and alloc <= 100*1000*1000)
d.check(0 <= size) # and size <= alloc and alloc <= 100*1000*1000)
d.putCharArrayHelper(data, size, d.charType(), d.currentItemFormat())
# Needed only to trigger the form report above.
def qform__std____cxx11__string():
return qform__std__string()
def qform__std____cxx11__wstring():
return qform__std__wstring()
def qdump__std____1__basic_string(d, value):
innerType = value.type[0].name
if innerType == "char":
@@ -1134,12 +1236,15 @@ def qdump__std____1__basic_string(d, value):
else:
d.warn("UNKNOWN INNER TYPE %s" % innerType)
def qdump__wstring(d, value):
qdump__std__wstring(d, value)
def qdump__std____1__once_flag(d, value):
qdump__std__once_flag(d, value)
def qdump__std__once_flag(d, value):
d.putValue(value.split("i")[0])
d.putBetterType(value.type)
@@ -1174,14 +1279,17 @@ def qdump__uint8_t(d, value):
d.putNumChild(0)
d.putValue(value.integer())
def qdump__int8_t(d, value):
d.putNumChild(0)
d.putValue(value.integer())
def qdump__std__byte(d, value):
d.putNumChild(0)
d.putValue(value.integer())
def qdump__std__optional(d, value):
innerType = value.type[0]
(payload, pad, initialized) = d.split('{%s}@b' % innerType.name, value)
@@ -1192,5 +1300,6 @@ def qdump__std__optional(d, value):
d.putSpecialValue("uninitialized")
d.putNumChild(0)
def qdump__std__experimental__optional(d, value):
qdump__std__optional(d, value)

View File

@@ -26,7 +26,7 @@
# Debugger start modes. Keep in sync with DebuggerStartMode in debuggerconstants.h
class DebuggerStartMode:
class DebuggerStartMode():
(
NoStartMode,
StartInternal,
@@ -41,33 +41,33 @@ class DebuggerStartMode:
# Known special formats. Keep in sync with DisplayFormat in debuggerprotocol.h
class DisplayFormat:
class DisplayFormat():
(
AutomaticFormat,
RawFormat,
SimpleFormat,
EnhancedFormat,
SeparateFormat,
Latin1StringFormat,
SeparateLatin1StringFormat,
Utf8StringFormat,
SeparateUtf8StringFormat,
Local8BitStringFormat,
Utf16StringFormat,
Ucs4StringFormat,
Array10Format,
Array100Format,
Array1000Format,
Array10000Format,
ArrayPlotFormat,
CompactMapFormat,
DirectQListStorageFormat,
IndirectQListStorageFormat,
Automatic,
Raw,
Simple,
Enhanced,
Separate,
Latin1String,
SeparateLatin1String,
Utf8String,
SeparateUtf8String,
Local8BitString,
Utf16String,
Ucs4String,
Array10,
Array100,
Array1000,
Array10000,
ArrayPlot,
CompactMap,
DirectQListStorage,
IndirectQListStorage,
) = range(0, 20)
# Breakpoints. Keep synchronized with BreakpointType in breakpoint.h
class BreakpointType:
class BreakpointType():
(
UnknownType,
BreakpointByFileAndLine,
@@ -87,24 +87,24 @@ class BreakpointType:
# Internal codes for types keep in sync with cdbextensions pytype.cpp
class TypeCode:
class TypeCode():
(
TypeCodeTypedef,
TypeCodeStruct,
TypeCodeVoid,
TypeCodeIntegral,
TypeCodeFloat,
TypeCodeEnum,
TypeCodePointer,
TypeCodeArray,
TypeCodeComplex,
TypeCodeReference,
TypeCodeFunction,
TypeCodeMemberPointer,
TypeCodeFortranString,
TypeCodeUnresolvable,
TypeCodeBitfield,
TypeCodeRValueReference,
Typedef,
Struct,
Void,
Integral,
Float,
Enum,
Pointer,
Array,
Complex,
Reference,
Function,
MemberPointer,
FortranString,
Unresolvable,
Bitfield,
RValueReference,
) = range(0, 16)

View File

@@ -50,7 +50,7 @@ public:
int angleDelta() const { return m_angleDelta; }
private:
QEvent::Type m_type;
QEvent::Type m_type = QEvent::None;
QPoint m_pos;
Qt::MouseButton m_button = Qt::NoButton;
Qt::MouseButtons m_buttons = Qt::NoButton;

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import QtQuick3D 1.15
import MouseArea3D 1.0
DirectionalDraggable {

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import QtQuick3D 1.15
import MouseArea3D 1.0
Node {
@@ -45,12 +45,12 @@ Node {
Connections {
target: camera
onSceneTransformChanged: updateScale()
function onSceneTransformChanged() { updateScale() }
}
Connections {
target: _generalHelper
onOverlayUpdateNeeded: updateScale()
function onOverlayUpdateNeeded() { updateScale() }
}
function getScale(baseScale)

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import QtQuick3D 1.15
View3D {
id: axisHelperView
@@ -37,7 +37,7 @@ View3D {
Node {
OrthographicCamera {
id: axisHelperCamera
rotation: editCameraCtrl.camera ? editCameraCtrl.camera.rotation : Qt.vector3d(0, 0, 0)
rotation: editCameraCtrl.camera ? editCameraCtrl.camera.rotation : Qt.quaternion(1, 0, 0, 0)
position: editCameraCtrl.camera ? editCameraCtrl.camera.position.minus(editCameraCtrl._lookAtPoint)
.normalized().times(600) : Qt.vector3d(0, 0, 0)
}
@@ -54,7 +54,7 @@ View3D {
AxisHelperArm {
id: armX
rotation: Qt.vector3d(0, 0, -90)
eulerRotation: Qt.vector3d(0, 0, -90)
color: Qt.rgba(1, 0, 0, 1)
hoverColor: Qt.lighter(Qt.rgba(1, 0, 0, 1))
view3D: axisHelperView
@@ -64,7 +64,7 @@ View3D {
AxisHelperArm {
id: armY
rotation: Qt.vector3d(0, 0, 0)
eulerRotation: Qt.vector3d(0, 0, 0)
color: Qt.rgba(0, 0.6, 0, 1)
hoverColor: Qt.lighter(Qt.rgba(0, 0.6, 0, 1))
view3D: axisHelperView
@@ -74,7 +74,7 @@ View3D {
AxisHelperArm {
id: armZ
rotation: Qt.vector3d(90, 0, 0)
eulerRotation: Qt.vector3d(90, 0, 0)
color: Qt.rgba(0, 0, 1, 1)
hoverColor: Qt.lighter(Qt.rgba(0, 0, 1, 1))
view3D: axisHelperView

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import QtQuick3D 1.15
Node {
id: armRoot

View File

@@ -0,0 +1,61 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.15
import CameraGeometry 1.0
Model {
id: cameraFrustum
property alias geometryName: cameraGeometry.name // Name must be unique for each geometry
property alias viewPortRect: cameraGeometry.viewPortRect
property Node targetNode: null
property Node scene: null
property bool selected: false
function updateGeometry()
{
cameraGeometry.update();
}
position: targetNode ? targetNode.scenePosition : Qt.vector3d(0, 0, 0)
rotation: targetNode ? targetNode.sceneRotation : Qt.quaternion(1, 0, 0, 0)
geometry: cameraGeometry
materials: [
DefaultMaterial {
id: defaultMaterial
emissiveColor: cameraFrustum.selected ? "#FF0000" : "#555555"
lighting: DefaultMaterial.NoLighting
cullingMode: Material.DisableCulling
}
]
CameraGeometry {
id: cameraGeometry
camera: cameraFrustum.scene && cameraFrustum.targetNode ? cameraFrustum.targetNode : null
}
}

View File

@@ -24,37 +24,33 @@
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import CameraGeometry 1.0
IconGizmo {
id: cameraGizmo
property var frustumModel: null
iconSource: "qrc:///qtquickplugin/mockfiles/images/editor_camera.png"
property alias geometryName: cameraGeometry.name // Name must be unique for each geometry
property alias viewPortRect: cameraGeometry.viewPortRect
function connectFrustum(frustum)
{
frustumModel = frustum;
frustum.selected = selected;
frustum.selected = Qt.binding(function() {return selected;});
frustum.scene = scene;
frustum.scene = Qt.binding(function() {return scene;});
frustum.targetNode = targetNode;
frustum.targetNode = Qt.binding(function() {return targetNode;});
frustum.visible = visible;
frustum.visible = Qt.binding(function() {return visible;});
}
onActiveSceneChanged: {
if (activeScene == scene)
cameraGeometry.update();
}
Model {
id: gizmoModel
geometry: cameraGeometry
visible: cameraGizmo.visible
materials: [
DefaultMaterial {
id: defaultMaterial
emissiveColor: cameraGizmo.selected ? "#FF0000" : "#555555"
lighting: DefaultMaterial.NoLighting
cullingMode: Material.DisableCulling
}
]
}
CameraGeometry {
id: cameraGeometry
camera: cameraGizmo.scene && cameraGizmo.targetNode ? cameraGizmo.targetNode : null
if (frustumModel && activeScene == scene)
frustumModel.updateGeometry();
}
}

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import QtQuick3D 1.15
import MouseArea3D 1.0
Model {
@@ -61,8 +61,6 @@ Model {
var maskedPosition = Qt.vector3d(planePos.x, 0, 0);
_posPressed = planePos.x;
_scenePosPressed = mouseArea.dragHelper.mapPositionToScene(maskedPosition);
if (targetNode.orientation === Node.RightHanded)
_scenePosPressed.z = -_scenePosPressed.z;
_targetStartPos = mouseArea.pivotScenePosition(targetNode);
pressed(mouseArea);
}
@@ -71,8 +69,6 @@ Model {
{
var maskedPosition = Qt.vector3d(planePos.x, 0, 0);
var scenePointerPos = mouseArea.dragHelper.mapPositionToScene(maskedPosition);
if (targetNode.orientation === Node.RightHanded)
scenePointerPos.z = -scenePointerPos.z;
return scenePointerPos.minus(_scenePosPressed);
}
@@ -99,7 +95,7 @@ Model {
y: -1.5
width: 12
height: 3
rotation: Qt.vector3d(0, 0, 90)
eulerRotation: Qt.vector3d(0, 0, 90)
grabsMouse: targetNode
active: rootModel.active
dragHelper: rootModel.dragHelper
@@ -116,7 +112,7 @@ Model {
y: -1.5
width: 12
height: 3
rotation: Qt.vector3d(0, 90, 90)
eulerRotation: Qt.vector3d(0, 90, 90)
grabsMouse: targetNode
active: rootModel.active
dragHelper: rootModel.dragHelper

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.12
import QtQuick3D 1.0
import QtQuick3D 1.15
Item {
id: cameraCtrl
@@ -43,8 +43,8 @@ Item {
property int _button
property real _zoomFactor: 1
property Camera _prevCamera: null
readonly property vector3d _defaultCameraPosition: Qt.vector3d(0, 600, -600)
readonly property vector3d _defaultCameraRotation: Qt.vector3d(45, 0, 0)
readonly property vector3d _defaultCameraPosition: Qt.vector3d(0, 600, 600)
readonly property vector3d _defaultCameraRotation: Qt.vector3d(-45, 0, 0)
readonly property real _defaultCameraLookAtDistance: _defaultCameraPosition.length()
function restoreCameraState(cameraState)
@@ -68,7 +68,7 @@ Item {
_lookAtPoint = Qt.vector3d(0, 0, 0);
_zoomFactor = 1;
camera.position = _defaultCameraPosition;
camera.rotation = _defaultCameraRotation;
camera.eulerRotation = _defaultCameraRotation;
_generalHelper.zoomCamera(camera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
_zoomFactor, false);
}
@@ -92,7 +92,7 @@ Item {
if (!camera)
return;
camera.rotation = rotation;
camera.eulerRotation = rotation;
var newLookAtAndZoom = _generalHelper.focusObjectToCamera(
camera, _defaultCameraLookAtDistance, targetObject, view3d, _zoomFactor, updateZoom);
_lookAtPoint = newLookAtAndZoom.toVector3d();
@@ -151,7 +151,7 @@ Item {
onPressed: {
if (cameraCtrl.camera && mouse.modifiers === Qt.AltModifier) {
cameraCtrl._dragging = true;
cameraCtrl._startRotation = cameraCtrl.camera.rotation;
cameraCtrl._startRotation = cameraCtrl.camera.eulerRotation;
cameraCtrl._startPosition = cameraCtrl.camera.position;
cameraCtrl._startLookAtPoint = _lookAtPoint;
cameraCtrl._pressPoint = Qt.vector3d(mouse.x, mouse.y, 0);

View File

@@ -25,7 +25,7 @@
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick3D 1.0
import QtQuick3D 1.15
import QtQuick.Controls 2.0
import QtGraphicalEffects 1.0
import MouseArea3D 1.0
@@ -62,33 +62,42 @@ Item {
onUsePerspectiveChanged: _generalHelper.storeToolState(sceneId, "usePerspective", usePerspective)
onShowEditLightChanged: _generalHelper.storeToolState(sceneId,"showEditLight", showEditLight)
onGlobalOrientationChanged: _generalHelper.storeToolState(sceneId, "globalOrientation", globalOrientation)
onActiveSceneChanged: updateActiveScene();
onActiveSceneChanged: {
function updateActiveScene()
{
if (editView) {
// Destroy is async, so make sure we don't get any more updates for the old editView
_generalHelper.enableItemUpdate(editView, false);
editView.destroy();
}
if (activeScene) {
// importScene cannot be updated after initial set, so we need to reconstruct entire View3D
var component = Qt.createComponent("SceneView3D.qml");
if (component.status === Component.Ready) {
editView = component.createObject(viewRect,
{"usePerspective": usePerspective,
"showSceneLight": showEditLight,
"importScene": activeScene,
"cameraZoomFactor": cameraControl._zoomFactor,
"z": 1});
editView.usePerspective = Qt.binding(function() {return usePerspective;});
editView.showSceneLight = Qt.binding(function() {return showEditLight;});
editView.cameraZoomFactor = Qt.binding(function() {return cameraControl._zoomFactor;});
selectionBoxes.length = 0;
updateToolStates(_generalHelper.getToolStates(sceneId), true);
}
// importScene cannot be updated after initial set, so we need to reconstruct entire View3D
var component = Qt.createComponent("SceneView3D.qml");
if (component.status === Component.Ready) {
editView = component.createObject(viewRect,
{"usePerspective": usePerspective,
"showSceneLight": showEditLight,
"importScene": activeScene,
"cameraZoomFactor": cameraControl._zoomFactor,
"z": 1});
editView.usePerspective = Qt.binding(function() {return usePerspective;});
editView.showSceneLight = Qt.binding(function() {return showEditLight;});
editView.cameraZoomFactor = Qt.binding(function() {return cameraControl._zoomFactor;});
selectionBoxes.length = 0;
updateToolStates(_generalHelper.getToolStates(sceneId), true);
}
}
function clearActiveScene()
{
activeScene = null;
sceneId = "";
updateActiveScene();
}
// Disables edit view update if scene doesn't match current activeScene.
// If it matches, updates are enabled.
function enableEditViewUpdate(scene)
@@ -102,7 +111,7 @@ Item {
if (editView) {
var targetNode = selectedNodes.length > 0
? selectionBoxes[0].model : null;
cameraControl.focusObject(targetNode, editView.camera.rotation, true);
cameraControl.focusObject(targetNode, editView.camera.eulerRotation, true);
}
}
@@ -243,7 +252,7 @@ Item {
// No free gizmos available, create a new one
var component = Qt.createComponent("LightGizmo.qml");
if (component.status === Component.Ready) {
var gizmo = component.createObject(overlayScene,
var gizmo = component.createObject(overlayView,
{"view3D": overlayView, "targetNode": obj,
"selectedNodes": selectedNodes, "scene": scene,
"activeScene": activeScene});
@@ -265,19 +274,24 @@ Item {
}
}
// No free gizmos available, create a new one
var component = Qt.createComponent("CameraGizmo.qml");
if (component.status === Component.Ready) {
var gizmoComponent = Qt.createComponent("CameraGizmo.qml");
var frustumComponent = Qt.createComponent("CameraFrustum.qml");
if (gizmoComponent.status === Component.Ready && frustumComponent.status === Component.Ready) {
var geometryName = _generalHelper.generateUniqueName("CameraGeometry");
var gizmo = component.createObject(
var frustum = frustumComponent.createObject(
overlayScene,
{"view3D": overlayView, "targetNode": obj, "geometryName": geometryName,
"viewPortRect": viewPortRect, "selectedNodes": selectedNodes,
"scene": scene, "activeScene": activeScene});
{"geometryName": geometryName, "viewPortRect": viewPortRect});
var gizmo = gizmoComponent.createObject(
overlayView,
{"view3D": overlayView, "targetNode": obj,
"selectedNodes": selectedNodes, "scene": scene, "activeScene": activeScene});
cameraGizmos[cameraGizmos.length] = gizmo;
gizmo.clicked.connect(handleObjectClicked);
gizmo.viewPortRect = Qt.binding(function() {return viewPortRect;});
gizmo.selectedNodes = Qt.binding(function() {return selectedNodes;});
gizmo.activeScene = Qt.binding(function() {return activeScene;});
frustum.viewPortRect = Qt.binding(function() {return viewPortRect;});
gizmo.connectFrustum(frustum);
}
}
@@ -341,7 +355,7 @@ Item {
clipFar: viewRoot.editView ? viewRoot.editView.perpectiveCamera.clipFar : 1000
clipNear: viewRoot.editView ? viewRoot.editView.perpectiveCamera.clipNear : 1
position: viewRoot.editView ? viewRoot.editView.perpectiveCamera.position : Qt.vector3d(0, 0, 0)
rotation: viewRoot.editView ? viewRoot.editView.perpectiveCamera.rotation : Qt.vector3d(0, 0, 0)
rotation: viewRoot.editView ? viewRoot.editView.perpectiveCamera.rotation : Qt.quaternion(1, 0, 0, 0)
}
OrthographicCamera {
@@ -349,7 +363,7 @@ Item {
clipFar: viewRoot.editView ? viewRoot.editView.orthoCamera.clipFar : 1000
clipNear: viewRoot.editView ? viewRoot.editView.orthoCamera.clipNear : 1
position: viewRoot.editView ? viewRoot.editView.orthoCamera.position : Qt.vector3d(0, 0, 0)
rotation: viewRoot.editView ? viewRoot.editView.orthoCamera.rotation : Qt.vector3d(0, 0, 0)
rotation: viewRoot.editView ? viewRoot.editView.orthoCamera.rotation : Qt.quaternion(1, 0, 0, 0)
scale: viewRoot.editView ? viewRoot.editView.orthoCamera.scale : Qt.vector3d(0, 0, 0)
}
@@ -395,15 +409,14 @@ Item {
view3D: overlayView
dragHelper: gizmoDragHelper
onRotateCommit: viewRoot.commitObjectProperty(viewRoot.selectedNode, "rotation")
onRotateChange: viewRoot.changeObjectProperty(viewRoot.selectedNode, "rotation")
onRotateCommit: viewRoot.commitObjectProperty(viewRoot.selectedNode, "eulerRotation")
onRotateChange: viewRoot.changeObjectProperty(viewRoot.selectedNode, "eulerRotation")
}
AutoScaleHelper {
id: autoScale
view3D: overlayView
position: moveGizmo.scenePosition
orientation: moveGizmo.orientation
}
Line3D {
@@ -412,27 +425,20 @@ Item {
name: "3D Edit View Pivot Line"
color: "#ddd600"
function flipIfNeeded(vec) {
if (!viewRoot.selectedNode || viewRoot.selectedNode.orientation === Node.LeftHanded)
return vec;
else
return Qt.vector3d(vec.x, vec.y, -vec.z);
}
startPos: viewRoot.selectedNode ? flipIfNeeded(viewRoot.selectedNode.scenePosition)
: Qt.vector3d(0, 0, 0)
startPos: viewRoot.selectedNode ? viewRoot.selectedNode.scenePosition
: Qt.vector3d(0, 0, 0)
Connections {
target: viewRoot
onSelectedNodeChanged: {
pivotLine.endPos = pivotLine.flipIfNeeded(gizmoDragHelper.pivotScenePosition(
viewRoot.selectedNode));
function onSelectedNodeChanged()
{
pivotLine.endPos = gizmoDragHelper.pivotScenePosition(viewRoot.selectedNode);
}
}
Connections {
target: viewRoot.selectedNode
onSceneTransformChanged: {
pivotLine.endPos = pivotLine.flipIfNeeded(gizmoDragHelper.pivotScenePosition(
viewRoot.selectedNode));
function onSceneTransformChanged()
{
pivotLine.endPos = gizmoDragHelper.pivotScenePosition(viewRoot.selectedNode);
}
}
@@ -529,6 +535,32 @@ Item {
}
}
Rectangle {
id: rotateGizmoLabel
color: "white"
x: rotateGizmo.currentMousePos.x - (10 + width)
y: rotateGizmo.currentMousePos.y - (10 + height)
width: rotateGizmoLabelText.width + 4
height: rotateGizmoLabelText.height + 4
border.width: 1
visible: rotateGizmo.dragging
parent: rotateGizmo.view3D
Text {
id: rotateGizmoLabelText
text: {
var l = Qt.locale();
if (rotateGizmo.targetNode) {
var degrees = rotateGizmo.currentAngle * (180 / Math.PI);
return qsTr(Number(degrees).toLocaleString(l, 'f', 1));
} else {
return "";
}
}
anchors.centerIn: parent
}
}
EditCameraController {
id: cameraControl
camera: viewRoot.editView ? viewRoot.editView.camera : null

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import QtQuick3D 1.15
import GridGeometry 1.0
Node {
@@ -34,7 +34,7 @@ Node {
property alias step: gridGeometry.step
property alias subdivAlpha: subGridMaterial.opacity
rotation.x: 90
eulerRotation.x: 90
// Note: Only one instance of HelperGrid is supported, as the geometry names are fixed
@@ -89,7 +89,7 @@ Node {
]
}
Model { // X Axis
rotation.z: 90
eulerRotation.z: 90
geometry: GridGeometry {
lines: gridGeometry.lines
step: gridGeometry.step

View File

@@ -24,10 +24,10 @@
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import QtQuick3D 1.15
import QtGraphicalEffects 1.12
Node {
Item {
id: iconGizmo
property Node activeScene: null
@@ -50,16 +50,13 @@ Node {
signal positionCommit()
signal clicked(Node node, bool multi)
position: targetNode ? targetNode.scenePosition : Qt.vector3d(0, 0, 0)
rotation: targetNode ? targetNode.sceneRotation : Qt.vector3d(0, 0, 0)
visible: activeScene === scene && (targetNode ? targetNode.visible : false)
Overlay2D {
id: iconOverlay
targetNode: iconGizmo
targetNode: iconGizmo.targetNode
targetView: view3D
visible: iconGizmo.visible && !isBehindCamera
parent: view3D
Rectangle {
id: iconRect

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import QtQuick3D 1.15
IconGizmo {
id: lightGizmo

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import QtQuick3D 1.15
import LineGeometry 1.0
Node {

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import QtQuick3D 1.15
import MouseArea3D 1.0
Node {
@@ -40,13 +40,13 @@ Node {
property MouseArea3D dragHelper: null
position: dragHelper.pivotScenePosition(targetNode)
orientation: targetNode ? targetNode.orientation : Node.LeftHanded
onTargetNodeChanged: position = dragHelper.pivotScenePosition(targetNode)
Connections {
target: moveGizmo.targetNode
onSceneTransformChanged: {
function onSceneTransformChanged()
{
moveGizmo.position = moveGizmo.dragHelper.pivotScenePosition(moveGizmo.targetNode);
}
}
@@ -55,14 +55,11 @@ Node {
signal positionMove()
Node {
rotation: globalOrientation || !moveGizmo.targetNode ? Qt.vector3d(0, 0, 0)
rotation: globalOrientation || !moveGizmo.targetNode ? Qt.quaternion(1, 0, 0, 0)
: moveGizmo.targetNode.sceneRotation
rotationOrder: moveGizmo.targetNode ? moveGizmo.targetNode.rotationOrder : Node.YXZ
orientation: moveGizmo.orientation
Arrow {
id: arrowX
rotation: Qt.vector3d(0, 0, -90)
eulerRotation: Qt.vector3d(0, 0, -90)
targetNode: moveGizmo.targetNode
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(1, 0, 0, 1))
: Qt.rgba(1, 0, 0, 1)
@@ -76,7 +73,7 @@ Node {
Arrow {
id: arrowY
rotation: Qt.vector3d(0, 0, 0)
eulerRotation: Qt.vector3d(0, 0, 0)
targetNode: moveGizmo.targetNode
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0.6, 0, 1))
: Qt.rgba(0, 0.6, 0, 1)
@@ -90,7 +87,7 @@ Node {
Arrow {
id: arrowZ
rotation: Qt.vector3d(90, 0, 0)
eulerRotation: Qt.vector3d(90, 0, 0)
targetNode: moveGizmo.targetNode
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0, 1, 1))
: Qt.rgba(0, 0, 1, 1)
@@ -108,7 +105,7 @@ Node {
y: 10
z: 10
rotation: Qt.vector3d(0, 90, 0)
eulerRotation: Qt.vector3d(0, 90, 0)
targetNode: moveGizmo.targetNode
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(1, 0, 0, 1))
: Qt.rgba(1, 0, 0, 1)
@@ -126,7 +123,7 @@ Node {
x: 10
z: 10
rotation: Qt.vector3d(90, 0, 0)
eulerRotation: Qt.vector3d(90, 0, 0)
targetNode: moveGizmo.targetNode
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0.6, 0, 1))
: Qt.rgba(0, 0.6, 0, 1)
@@ -144,7 +141,7 @@ Node {
x: 10
y: 10
rotation: Qt.vector3d(0, 0, 0)
eulerRotation: Qt.vector3d(0, 0, 0)
targetNode: moveGizmo.targetNode
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0, 1, 1))
: Qt.rgba(0, 0, 1, 1)

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import QtQuick3D 1.15
Item {
id: root
@@ -39,29 +39,26 @@ Item {
Connections {
target: targetNode
onSceneTransformChanged: updateOverlay()
function onSceneTransformChanged() { updateOverlay() }
}
Connections {
target: targetView.camera
onSceneTransformChanged: updateOverlay()
function onSceneTransformChanged() { updateOverlay() }
}
Connections {
target: _generalHelper
onOverlayUpdateNeeded: updateOverlay()
function onOverlayUpdateNeeded() { updateOverlay() }
}
function updateOverlay()
{
var scenePos = targetNode ? targetNode.scenePosition : Qt.vector3d(0, 0, 0);
// Need separate variable as scenePos is reference to read-only property
var scenePosZ = scenePos.z
if (targetNode && targetNode.orientation === Node.RightHanded)
scenePosZ = -scenePosZ;
var scenePosWithOffset = Qt.vector3d(scenePos.x + offset.x,
scenePos.y + offset.y,
scenePosZ + offset.z);
scenePos.z + offset.z);
var viewPos = targetView ? targetView.mapFrom3DScene(scenePosWithOffset)
: Qt.vector3d(0, 0, 0);
root.x = viewPos.x;

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import QtQuick3D 1.15
import MouseArea3D 1.0
Model {
@@ -48,7 +48,6 @@ Model {
signal dragged(var mouseArea, vector3d sceneRelativeDistance, vector2d relativeDistance)
signal released(var mouseArea, vector3d sceneRelativeDistance, vector2d relativeDistance)
rotationOrder: Node.XYZr
source: "#Rectangle"
DefaultMaterial {
@@ -66,8 +65,6 @@ Model {
_planePosPressed = planePos;
_scenePosPressed = mouseArea.dragHelper.mapPositionToScene(planePos.toVector3d());
if (targetNode.orientation === Node.RightHanded)
_scenePosPressed.z = -_scenePosPressed.z;
_targetStartPos = mouseArea.pivotScenePosition(targetNode);
pressed(mouseArea);
}
@@ -75,8 +72,6 @@ Model {
function calcRelativeDistance(mouseArea, planePos)
{
var scenePointerPos = mouseArea.dragHelper.mapPositionToScene(planePos.toVector3d());
if (targetNode.orientation === Node.RightHanded)
scenePointerPos.z = -scenePointerPos.z;
return scenePointerPos.minus(_scenePosPressed);
}

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import QtQuick3D 1.15
import MouseArea3D 1.0
PlanarDraggable {

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import QtQuick3D 1.15
import MouseArea3D 1.0
PlanarDraggable {

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import QtQuick3D 1.15
import MouseArea3D 1.0
Node {
@@ -41,13 +41,13 @@ Node {
property point currentMousePos
position: dragHelper.pivotScenePosition(targetNode)
orientation: targetNode ? targetNode.orientation : Node.LeftHanded
onTargetNodeChanged: position = dragHelper.pivotScenePosition(targetNode)
Connections {
target: rotateGizmo.targetNode
onSceneTransformChanged: {
function onSceneTransformChanged()
{
rotateGizmo.position = rotateGizmo.dragHelper.pivotScenePosition(rotateGizmo.targetNode);
}
}
@@ -70,44 +70,16 @@ Node {
copyRingProperties(rotRingZ)
}
Rectangle {
id: angleLabel
color: "white"
x: rotateGizmo.currentMousePos.x - (10 + width)
y: rotateGizmo.currentMousePos.y - (10 + height)
width: gizmoLabelText.width + 4
height: gizmoLabelText.height + 4
border.width: 1
visible: rotateGizmo.dragging
parent: rotateGizmo.view3D
Text {
id: gizmoLabelText
text: {
var l = Qt.locale();
if (rotateGizmo.targetNode) {
var degrees = currentAngle * (180 / Math.PI);
return qsTr(Number(degrees).toLocaleString(l, 'f', 1));
} else {
return "";
}
}
anchors.centerIn: parent
}
}
Node {
id: rotNode
rotation: globalOrientation || !rotateGizmo.targetNode ? Qt.vector3d(0, 0, 0)
rotation: globalOrientation || !rotateGizmo.targetNode ? Qt.quaternion(1, 0, 0, 0)
: rotateGizmo.targetNode.sceneRotation
rotationOrder: rotateGizmo.targetNode ? rotateGizmo.targetNode.rotationOrder : Node.YXZ
orientation: rotateGizmo.orientation
visible: !rotateGizmo.dragging && !freeRotator.dragging
RotateRing {
id: rotRingX
objectName: "Rotate Ring X"
rotation: Qt.vector3d(0, 90, 0)
eulerRotation: Qt.vector3d(0, 90, 0)
targetNode: rotateGizmo.targetNode
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(1, 0, 0, 1))
: Qt.rgba(1, 0, 0, 1)
@@ -125,7 +97,7 @@ Node {
RotateRing {
id: rotRingY
objectName: "Rotate Ring Y"
rotation: Qt.vector3d(90, 0, 0)
eulerRotation: Qt.vector3d(90, 0, 0)
targetNode: rotateGizmo.targetNode
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0.6, 0, 1))
: Qt.rgba(0, 0.6, 0, 1)
@@ -145,7 +117,7 @@ Node {
RotateRing {
id: rotRingZ
objectName: "Rotate Ring Z"
rotation: Qt.vector3d(0, 0, 0)
eulerRotation: Qt.vector3d(0, 0, 0)
targetNode: rotateGizmo.targetNode
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0, 1, 1))
: Qt.rgba(0, 0, 1, 1)
@@ -174,7 +146,6 @@ Node {
view3D: rotateGizmo.view3D
active: false
visible: rotRingX.dragging || rotRingY.dragging || rotRingZ.dragging
orientation: rotateGizmo.orientation
}
RotateRing {
@@ -223,16 +194,14 @@ Node {
// Need to recreate vector as we need to adjust it and we can't do that on reference of
// scenePosition, which is read-only property
var scenePos = rotateGizmo.dragHelper.pivotScenePosition(rotateGizmo.targetNode);
if (rotateGizmo.targetNode && rotateGizmo.targetNode.orientation === Node.RightHanded)
scenePos.z = -scenePos.z
_targetPosOnScreen = view3D.mapFrom3DScene(scenePos);
_targetPosOnScreen.z = 0;
_pointerPosPressed = Qt.vector3d(screenPos.x, screenPos.y, 0);
// Recreate vector so we don't follow the changes in targetNode.rotation
_startRotation = Qt.vector3d(rotateGizmo.targetNode.rotation.x,
rotateGizmo.targetNode.rotation.y,
rotateGizmo.targetNode.rotation.z);
_startRotation = Qt.vector3d(rotateGizmo.targetNode.eulerRotation.x,
rotateGizmo.targetNode.eulerRotation.y,
rotateGizmo.targetNode.eulerRotation.z);
dragging = true;
}

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import QtQuick3D 1.15
import MouseArea3D 1.0
Model {
@@ -80,18 +80,16 @@ Model {
// Need to recreate vector as we need to adjust it and we can't do that on reference of
// scenePosition, which is read-only property
var scenePos = mouseAreaMain.pivotScenePosition(targetNode);
if (targetNode && targetNode.orientation === Node.RightHanded)
scenePos.z = -scenePos.z
_targetPosOnScreen = view3D.mapFrom3DScene(scenePos);
_targetPosOnScreen.z = 0;
_pointerPosPressed = Qt.vector3d(screenPos.x, screenPos.y, 0);
_trackBall = angle < 0.1;
// Recreate vector so we don't follow the changes in targetNode.rotation
_startRotation = Qt.vector3d(targetNode.rotation.x,
targetNode.rotation.y,
targetNode.rotation.z);
// Recreate vector so we don't follow the changes in targetNode.eulerRotation
_startRotation = Qt.vector3d(targetNode.eulerRotation.x,
targetNode.eulerRotation.y,
targetNode.eulerRotation.z);
currentAngle = 0;
currentMousePos = screenPos;
}

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import QtQuick3D 1.15
import MouseArea3D 1.0
Node {
@@ -39,13 +39,13 @@ Node {
property MouseArea3D dragHelper: null
position: dragHelper.pivotScenePosition(targetNode)
orientation: targetNode ? targetNode.orientation : Node.LeftHanded
onTargetNodeChanged: position = dragHelper.pivotScenePosition(targetNode)
Connections {
target: scaleGizmo.targetNode
onSceneTransformChanged: {
function onSceneTransformChanged()
{
scaleGizmo.position = scaleGizmo.dragHelper.pivotScenePosition(scaleGizmo.targetNode);
}
}
@@ -54,13 +54,11 @@ Node {
signal scaleChange()
Node {
rotation: !targetNode ? Qt.vector3d(0, 0, 0) : targetNode.sceneRotation
rotationOrder: scaleGizmo.targetNode ? scaleGizmo.targetNode.rotationOrder : Node.YXZ
orientation: scaleGizmo.orientation
rotation: !targetNode ? Qt.quaternion(1, 0, 0, 0) : targetNode.sceneRotation
ScaleRod {
id: scaleRodX
rotation: Qt.vector3d(0, 0, -90)
eulerRotation: Qt.vector3d(0, 0, -90)
axis: Qt.vector3d(1, 0, 0)
targetNode: scaleGizmo.targetNode
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(1, 0, 0, 1))
@@ -75,7 +73,7 @@ Node {
ScaleRod {
id: scaleRodY
rotation: Qt.vector3d(0, 0, 0)
eulerRotation: Qt.vector3d(0, 0, 0)
axis: Qt.vector3d(0, 1, 0)
targetNode: scaleGizmo.targetNode
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0.6, 0, 1))
@@ -90,7 +88,7 @@ Node {
ScaleRod {
id: scaleRodZ
rotation: Qt.vector3d(90, 0, 0)
eulerRotation: Qt.vector3d(90, 0, 0)
axis: Qt.vector3d(0, 0, 1)
targetNode: scaleGizmo.targetNode
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0, 1, 1))
@@ -109,7 +107,7 @@ Node {
y: 10
z: 10
rotation: Qt.vector3d(0, 90, 0)
eulerRotation: Qt.vector3d(0, 90, 0)
axisX: Qt.vector3d(0, 0, -1)
axisY: Qt.vector3d(0, 1, 0)
targetNode: scaleGizmo.targetNode
@@ -129,7 +127,7 @@ Node {
x: 10
z: 10
rotation: Qt.vector3d(90, 0, 0)
eulerRotation: Qt.vector3d(90, 0, 0)
axisX: Qt.vector3d(1, 0, 0)
axisY: Qt.vector3d(0, 0, 1)
targetNode: scaleGizmo.targetNode
@@ -149,7 +147,7 @@ Node {
x: 10
y: 10
rotation: Qt.vector3d(0, 0, 0)
eulerRotation: Qt.vector3d(0, 0, 0)
axisX: Qt.vector3d(1, 0, 0)
axisY: Qt.vector3d(0, 1, 0)
targetNode: scaleGizmo.targetNode

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import QtQuick3D 1.15
import MouseArea3D 1.0
DirectionalDraggable {

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.12
import QtQuick3D 1.14
import QtQuick3D 1.15
View3D {
id: sceneView
@@ -74,18 +74,18 @@ View3D {
// point.
PerspectiveCamera {
id: scenePerspectiveCamera
z: -600
z: 600
y: 600
rotation.x: 45
eulerRotation.x: -45
clipFar: 100000
clipNear: 1
}
OrthographicCamera {
id: sceneOrthoCamera
z: -600
z: 600
y: 600
rotation.x: 45
eulerRotation.x: -45
clipFar: 100000
clipNear: -10000
}

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import QtQuick3D 1.15
import SelectionBoxGeometry 1.0
Node {
@@ -48,11 +48,9 @@ Node {
geometry: selectionBoxGeometry
scale: selectionBox.targetNode ? selectionBox.targetNode.scale : Qt.vector3d(1, 1, 1)
rotation: selectionBox.targetNode ? selectionBox.targetNode.rotation : Qt.vector3d(0, 0, 0)
rotation: selectionBox.targetNode ? selectionBox.targetNode.rotation : Qt.quaternion(1, 0, 0, 0)
position: selectionBox.targetNode ? selectionBox.targetNode.position : Qt.vector3d(0, 0, 0)
pivot: selectionBox.targetNode ? selectionBox.targetNode.pivot : Qt.vector3d(0, 0, 0)
orientation: selectionBox.targetNode ? selectionBox.targetNode.orientation : Node.LeftHanded
rotationOrder: selectionBox.targetNode ? selectionBox.targetNode.rotationOrder : Node.YXZ
visible: selectionBox.targetNode && !selectionBoxGeometry.isEmpty

View File

@@ -28,9 +28,9 @@
#include "selectionboxgeometry.h"
#include <QtQuick3D/qquick3dobject.h>
#include <QtQuick3D/private/qquick3dorthographiccamera_p.h>
#include <QtQuick3D/private/qquick3dperspectivecamera_p.h>
#include <QtQuick3D/private/qquick3dobject_p_p.h>
#include <QtQuick3D/private/qquick3dcamera_p.h>
#include <QtQuick3D/private/qquick3dnode_p.h>
#include <QtQuick3D/private/qquick3dmodel_p.h>
@@ -85,17 +85,17 @@ void GeneralHelper::orbitCamera(QQuick3DCamera *camera, const QVector3D &startRo
if (dragVector.length() < 0.001f)
return;
camera->setRotation(startRotation);
QVector3D newRotation(dragVector.y(), dragVector.x(), 0.f);
camera->setEulerRotation(startRotation);
QVector3D newRotation(-dragVector.y(), -dragVector.x(), 0.f);
newRotation *= 0.5f; // Emprically determined multiplier for nice drag
newRotation += startRotation;
camera->setRotation(newRotation);
camera->setEulerRotation(newRotation);
const QVector3D oldLookVector = camera->position() - lookAtPoint;
QMatrix4x4 m = camera->sceneTransform();
const float *dataPtr(m.data());
QVector3D newLookVector(-dataPtr[8], -dataPtr[9], -dataPtr[10]);
QVector3D newLookVector(dataPtr[8], dataPtr[9], dataPtr[10]);
newLookVector.normalize();
newLookVector *= oldLookVector.length();
@@ -187,7 +187,6 @@ QVector4D GeneralHelper::focusObjectToCamera(QQuick3DCamera *camera, float defau
// Adjust lookAt to look directly at the center of the object bounds
lookAt = renderModel->globalTransform.map(center);
lookAt.setZ(-lookAt.z()); // Render node transforms have inverted z
}
}
}
@@ -196,7 +195,7 @@ QVector4D GeneralHelper::focusObjectToCamera(QQuick3DCamera *camera, float defau
// Reset camera position to default zoom
QMatrix4x4 m = camera->sceneTransform();
const float *dataPtr(m.data());
QVector3D newLookVector(-dataPtr[8], -dataPtr[9], -dataPtr[10]);
QVector3D newLookVector(dataPtr[8], dataPtr[9], dataPtr[10]);
newLookVector.normalize();
newLookVector *= defaultLookAtDistance;

View File

@@ -81,10 +81,10 @@ QSSGRenderGraphObject *LineGeometry::updateSpatialNode(QSSGRenderGraphObject *no
dataPtr[0] = m_startPos[0];
dataPtr[1] = m_startPos[1];
dataPtr[2] = -m_startPos[2];
dataPtr[2] = m_startPos[2];
dataPtr[3] = m_endPos[0];
dataPtr[4] = m_endPos[1];
dataPtr[5] = -m_endPos[2];
dataPtr[5] = m_endPos[2];
geometry->addAttribute(QSSGRenderGeometry::Attribute::PositionSemantic, 0,
QSSGRenderGeometry::Attribute::ComponentType::F32Type);

View File

@@ -396,16 +396,12 @@ qreal QmlDesigner::Internal::MouseArea3D::getNewRotationAngle(
if (dragVector.length() < 0.001f)
return prevAngle;
// Get camera to node direction in node orientation
// Get camera to node direction
QVector3D cameraToNodeDir = getCameraToNodeDir(node);
if (trackBall) {
// Only the distance in plane direction is relevant in trackball drag
QVector3D dragDir = QVector3D::crossProduct(getNormal(), cameraToNodeDir).normalized();
QVector3D scenePos = pivotScenePosition(node);
if (node->orientation() == QQuick3DNode::RightHanded) {
scenePos.setZ(-scenePos.z());
dragDir = -dragDir;
}
QVector3D screenDragDir = m_view3D->mapFrom3DScene(scenePos + dragDir);
screenDragDir.setZ(0);
dragDir = (screenDragDir - nodePos).normalized();
@@ -420,12 +416,10 @@ qreal QmlDesigner::Internal::MouseArea3D::getNewRotationAngle(
// Determine drag direction left/right
QVector3D dragNormal = QVector3D::crossProduct(nodeToPress, nodeToCurrent).normalized();
if (node->orientation() == QQuick3DNode::RightHanded)
dragNormal = -dragNormal;
angle *= QVector3D::dotProduct(QVector3D(0.f, 0.f, 1.f), dragNormal) < 0 ? -1.0 : 1.0;
// Determine drag ring orientation relative to camera
angle *= QVector3D::dotProduct(getNormal(), cameraToNodeDir) < 0 ? 1.0 : -1.0;
angle *= QVector3D::dotProduct(getNormal(), cameraToNodeDir) < 0 ? -1.0 : 1.0;
qreal adjustedPrevAngle = prevAngle;
const qreal PI_2 = M_PI * 2.0;
@@ -451,10 +445,8 @@ void QmlDesigner::Internal::MouseArea3D::applyRotationAngleToNode(
QQuick3DNode *node, const QVector3D &startRotation, qreal angle)
{
if (!qFuzzyIsNull(angle)) {
node->setRotation(startRotation);
node->setEulerRotation(startRotation);
QVector3D normal = getNormal();
if (orientation() != node->orientation())
normal.setZ(-normal.z());
node->rotate(qRadiansToDegrees(angle), normal, QQuick3DNode::SceneSpace);
}
}
@@ -468,20 +460,15 @@ void MouseArea3D::applyFreeRotation(QQuick3DNode *node, const QVector3D &startRo
return;
const float *dataPtr(sceneTransform().data());
QVector3D xAxis = QVector3D(-dataPtr[0], -dataPtr[1], -dataPtr[2]).normalized();
QVector3D yAxis = QVector3D(-dataPtr[4], -dataPtr[5], -dataPtr[6]).normalized();
if (node->orientation() == QQuick3DNode::RightHanded) {
xAxis = QVector3D(-xAxis.x(), -xAxis.y(), xAxis.z());
yAxis = QVector3D(-yAxis.x(), -yAxis.y(), yAxis.z());
}
QVector3D xAxis = QVector3D(dataPtr[0], dataPtr[1], dataPtr[2]).normalized();
QVector3D yAxis = QVector3D(dataPtr[4], dataPtr[5], dataPtr[6]).normalized();
QVector3D finalAxis = (dragVector.x() * yAxis + dragVector.y() * xAxis);
qreal degrees = qRadiansToDegrees(qreal(finalAxis.length()) * mouseDragMultiplier());
finalAxis.normalize();
node->setRotation(startRotation);
node->setEulerRotation(startRotation);
node->rotate(degrees, finalAxis, QQuick3DNode::SceneSpace);
}
@@ -513,8 +500,6 @@ double MouseArea3D::getRelativeScale(QQuick3DNode *node) const
// view and scene, will tell us what the distance independent scale should be.
QVector3D nodePos(node->scenePosition());
if (orientation() == QQuick3DNode::RightHanded)
nodePos.setZ(-nodePos.z());
DoubleVec3D posInView1(m_view3D->mapFrom3DScene(nodePos));
@@ -718,12 +703,9 @@ QVector3D MouseArea3D::getCameraToNodeDir(QQuick3DNode *node) const
QVector3D dir;
if (qobject_cast<QQuick3DOrthographicCamera *>(m_view3D->camera())) {
dir = -m_view3D->camera()->cameraNode()->getDirection();
dir.setZ(-dir.z());
} else {
QVector3D camPos = m_view3D->camera()->scenePosition();
QVector3D nodePos = pivotScenePosition(node);
if (node->orientation() == QQuick3DNode::RightHanded)
nodePos.setZ(-nodePos.z());
dir = (nodePos - camPos).normalized();
}
return dir;

View File

@@ -32,7 +32,7 @@
#include <QtQuick3DRuntimeRender/private/qssgrendercontextcore_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrenderbuffermanager_p.h>
#include <QtQuick3D/private/qquick3dmodel_p.h>
#include <QtQuick3D/private/qquick3dobject_p_p.h>
#include <QtQuick3D/qquick3dobject.h>
#include <QtQuick/qquickwindow.h>
#include <QtCore/qvector.h>
@@ -367,10 +367,6 @@ void SelectionBoxGeometry::trackNodeChanges(QQuick3DNode *node)
this, &SelectionBoxGeometry::update, Qt::QueuedConnection);
m_connections << QObject::connect(node, &QQuick3DNode::pivotChanged,
this, &SelectionBoxGeometry::update, Qt::QueuedConnection);
m_connections << QObject::connect(node, &QQuick3DNode::orientationChanged,
this, &SelectionBoxGeometry::update, Qt::QueuedConnection);
m_connections << QObject::connect(node, &QQuick3DNode::rotationOrderChanged,
this, &SelectionBoxGeometry::update, Qt::QueuedConnection);
}
}

View File

@@ -1,6 +1,6 @@
INCLUDEPATH += $$PWD/
qtHaveModule(quick3d) {
versionAtLeast(QT_VERSION, 5.15.0):qtHaveModule(quick3d) {
QT *= quick3d-private
DEFINES *= QUICK3D_MODULE
}

View File

@@ -174,6 +174,7 @@ void Qt5InformationNodeInstanceServer::createEditView3D()
#ifdef QUICK3D_MODULE
static bool showEditView = qEnvironmentVariableIsSet("QMLDESIGNER_QUICK3D_SHOW_EDIT_WINDOW");
qmlRegisterRevision<QQuick3DNode, 1>("MouseArea3D", 1, 0);
qmlRegisterType<QmlDesigner::Internal::MouseArea3D>("MouseArea3D", 1, 0, "MouseArea3D");
qmlRegisterType<QmlDesigner::Internal::CameraGeometry>("CameraGeometry", 1, 0, "CameraGeometry");
qmlRegisterType<QmlDesigner::Internal::GridGeometry>("GridGeometry", 1, 0, "GridGeometry");
@@ -420,14 +421,22 @@ void Qt5InformationNodeInstanceServer::updateActiveSceneToEditView3D()
sceneIdVar = QVariant::fromValue(sceneId);
sceneIdProperty.write(sceneIdVar);
QQmlProperty sceneProperty(m_editView3DRootItem, "activeScene", context());
sceneProperty.write(activeSceneVar);
auto helper = qobject_cast<QmlDesigner::Internal::GeneralHelper *>(m_3dHelper);
QVariantMap toolStates;
if (helper)
toolStates = helper->getToolStates(sceneId);
toolStates.insert("sceneInstanceId", QVariant::fromValue(sceneInstance.instanceId()));
// if m_active3DScene is null, QQmlProperty::write() doesn't work so invoke the updateActiveScene
// qml method directly
if (!m_active3DScene) {
QMetaObject::invokeMethod(m_editView3DRootItem, "clearActiveScene", Qt::QueuedConnection);
toolStates.insert("sceneInstanceId", QVariant::fromValue(-1));
} else {
QQmlProperty sceneProperty(m_editView3DRootItem, "activeScene", context());
sceneProperty.write(activeSceneVar);
auto helper = qobject_cast<QmlDesigner::Internal::GeneralHelper *>(m_3dHelper);
if (helper)
toolStates = helper->getToolStates(sceneId);
toolStates.insert("sceneInstanceId", QVariant::fromValue(sceneInstance.instanceId()));
}
nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::ActiveSceneChanged,
toolStates});
@@ -514,7 +523,6 @@ void Qt5InformationNodeInstanceServer::doRender3DEditView()
{
static bool showEditView = qEnvironmentVariableIsSet("QMLDESIGNER_QUICK3D_SHOW_EDIT_WINDOW");
if (m_editView3DRootItem && !showEditView) {
auto t = std::chrono::steady_clock::now();
if (!m_editView3DContentItem) {
m_editView3DContentItem = QQmlProperty::read(m_editView3DRootItem, "contentItem").value<QQuickItem *>();
if (m_editView3DContentItem) {
@@ -544,10 +552,6 @@ void Qt5InformationNodeInstanceServer::doRender3DEditView()
// send the rendered image to creator process
nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::Render3DView,
QVariant::fromValue(imgContainer)});
qDebug() << "\x1b[42m \x1b[1m" << __FUNCTION__
<< ", t=" << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now()-t).count()
<< "\x1b[m";
if (m_needRender) {
m_renderTimer.start(0);
m_needRender = false;
@@ -880,32 +884,31 @@ void Qt5InformationNodeInstanceServer::setup3DEditView(const QList<ServerNodeIns
m_active3DScene = m_3DSceneMap.begin().key();
m_active3DView = findView3DForSceneRoot(m_active3DScene);
}
if (m_active3DScene) {
createEditView3D();
if (!m_editView3DRootItem) {
m_active3DScene = nullptr;
m_active3DView = nullptr;
return;
}
auto helper = qobject_cast<QmlDesigner::Internal::GeneralHelper *>(m_3dHelper);
if (helper) {
auto it = toolStates.constBegin();
while (it != toolStates.constEnd()) {
helper->initToolStates(it.key(), it.value());
++it;
}
helper->restoreWindowState();
if (toolStates.contains(helper->globalStateId())
&& toolStates[helper->globalStateId()].contains("rootSize")) {
m_editView3DRootItem->setSize(toolStates[helper->globalStateId()]["rootSize"].value<QSize>());
}
}
updateActiveSceneToEditView3D();
createCameraAndLightGizmos(instanceList);
createEditView3D();
if (!m_editView3DRootItem) {
m_active3DScene = nullptr;
m_active3DView = nullptr;
return;
}
auto helper = qobject_cast<QmlDesigner::Internal::GeneralHelper *>(m_3dHelper);
if (helper) {
auto it = toolStates.constBegin();
while (it != toolStates.constEnd()) {
helper->initToolStates(it.key(), it.value());
++it;
}
helper->restoreWindowState();
if (toolStates.contains(helper->globalStateId())
&& toolStates[helper->globalStateId()].contains("rootSize")) {
m_editView3DRootItem->setSize(toolStates[helper->globalStateId()]["rootSize"].value<QSize>());
}
}
updateActiveSceneToEditView3D();
createCameraAndLightGizmos(instanceList);
#else
Q_UNUSED(instanceList)
Q_UNUSED(toolStates)

View File

@@ -129,7 +129,7 @@ void Quick3DNodeInstance::setPickable(bool enable, bool checkParent, bool applyT
checkChildren(node);
}
}
if (nodeType == QQuick3DObject::Model)
if (nodeType == QQuick3DObject::Type::Model)
setPropertyVariant("pickable", enable); // allow 3D objects to receive mouse clicks
}
}

View File

@@ -13,6 +13,7 @@
<file>mockfiles/Arrow.qml</file>
<file>mockfiles/AutoScaleHelper.qml</file>
<file>mockfiles/MoveGizmo.qml</file>
<file>mockfiles/CameraFrustum.qml</file>
<file>mockfiles/CameraGizmo.qml</file>
<file>mockfiles/LightGizmo.qml</file>
<file>mockfiles/IconGizmo.qml</file>

View File

@@ -37,14 +37,17 @@ Section {
Label {
text: qsTr("Origin")
disabledState: !backendValues.transformOrigin.isAvailable
}
OriginControl {
backendValue: backendValues.transformOrigin
enabled: backendValues.transformOrigin.isAvailable
}
Label {
text: qsTr("Scale")
disabledState: !backendValues.scale.isAvailable
}
SecondColumnLayout {
@@ -57,12 +60,14 @@ Section {
minimumValue: -10
maximumValue: 10
Layout.preferredWidth: 140
enabled: backendValues.scale.isAvailable
}
ExpandingSpacer {
}
}
Label {
text: qsTr("Rotation")
disabledState: !backendValues.rotation.isAvailable
}
SecondColumnLayout {
SpinBox {
@@ -73,6 +78,7 @@ Section {
minimumValue: -360
maximumValue: 360
Layout.preferredWidth: 140
enabled: backendValues.rotation.isAvailable
}
ExpandingSpacer {
}
@@ -110,12 +116,14 @@ Section {
Label {
visible: majorQtQuickVersion > 1
text: qsTr("Smooth")
disabledState: !backendValues.smooth.isAvailable
}
SecondColumnLayout {
visible: majorQtQuickVersion > 1
CheckBox {
backendValue: backendValues.smooth
text: qsTr("Smooth sampling active")
enabled: backendValues.smooth.isAvailable
}
ExpandingSpacer {
}
@@ -124,12 +132,14 @@ Section {
Label {
visible: majorQtQuickVersion > 1
text: qsTr("Antialiasing")
disabledState: !backendValues.antialiasing.isAvailable
}
SecondColumnLayout {
visible: majorQtQuickVersion > 1
CheckBox {
backendValue: backendValues.antialiasing
text: qsTr("Anti-aliasing active")
enabled: backendValues.antialiasing.isAvailable
}
ExpandingSpacer {
}

View File

@@ -31,6 +31,7 @@ Section {
anchors.left: parent.left
anchors.right: parent.right
caption: qsTr("Layer")
visible: backendValues.layer_effect.isAvailable
SectionLayout {
columns: 2

View File

@@ -50,6 +50,7 @@ Column {
anchors.left: parent.left
anchors.right: parent.right
caption: qsTr("Border Color")
visible: backendValues.border_color.isAvailable
ColorEditor {
caption: qsTr("Border Color")
@@ -63,6 +64,7 @@ Column {
anchors.left: parent.left
anchors.right: parent.right
caption: "Rectangle"
visible: backendValues.border_color.isAvailable
SectionLayout {
rows: 2

View File

@@ -37,7 +37,8 @@ Label {
property alias toolTip: toolTipArea.tooltip
width: Math.max(Math.min(240, parent.width - 280), 50)
color: StudioTheme.Values.themeTextColor
color: label.disabledState ? StudioTheme.Values.themeDisabledTextColor : StudioTheme.Values.themeTextColor
elide: Text.ElideRight
font.pixelSize: StudioTheme.Values.myFontSize
@@ -46,9 +47,27 @@ Label {
Layout.minimumWidth: width
Layout.maximumWidth: width
leftPadding: label.disabledState ? 10 : 0
rightPadding: label.disabledState ? 10 : 0
property bool disabledState: false
Text {
text: "["
color: StudioTheme.Values.themeTextColor//StudioTheme.Values.themeDisabledTextColor
visible: label.disabledState
}
Text {
text: "]"
color: StudioTheme.Values.themeTextColor//StudioTheme.Values.themeDisabledTextColor//
visible: label.disabledState
x: label.contentWidth + 10 + contentWidth
}
ToolTipArea {
id: toolTipArea
anchors.fill: parent
tooltip: label.text
tooltip: label.disabledState ? qsTr("This property is not available in this configuration.") : label.text
}
}

View File

@@ -42,6 +42,8 @@ Item {
readonly property color selectedColor: Theme.qmlDesignerBackgroundColorDarkAlternate()
readonly property color unselectedColor: Theme.qmlDesignerBackgroundColorDarker()
property bool enabled: true
ExtendedFunctionLogic {
id: extFuncLogic
backendValue: originControl.backendValue
@@ -69,6 +71,7 @@ Item {
}
Grid {
opacity: originControl.enabled ? 1 : 0.5
rows: 3
columns: 3
spacing: 5
@@ -76,7 +79,8 @@ Item {
id: grid
function setValue(myValue) {
originControl.backendValue.setEnumeration("Item", myValue)
if (originControl.enabled)
originControl.backendValue.setEnumeration("Item", myValue)
}
function select(myValue) {

View File

@@ -84,6 +84,7 @@ QtObject {
property string themeControlBackground: "#242424"
property string themeControlOutline: "#404040"
property string themeTextColor: "#ffffff"
property string themeDisabledTextColor: "#909090"
property string themePanelBackground: "#2a2a2a"
property string themeHoverHighlight: "#313131"

View File

@@ -59,12 +59,13 @@ namespace ADS
/**
* Private data class of DockAreaTabBar class (pimpl)
*/
struct DockAreaTabBarPrivate
class DockAreaTabBarPrivate
{
public:
DockAreaTabBar *q;
DockAreaWidget *m_dockArea;
QWidget *m_tabsContainerWidget;
QBoxLayout *m_tabsLayout;
DockAreaWidget *m_dockArea = nullptr;
QWidget *m_tabsContainerWidget = nullptr;
QBoxLayout *m_tabsLayout = nullptr;
int m_currentIndex = -1;
/**
@@ -87,8 +88,7 @@ namespace ADS
* Convenience function to access last tab
*/
DockWidgetTab *lastTab() const {return q->tab(q->count() - 1);}
};
// struct DockAreaTabBarPrivate
}; // class DockAreaTabBarPrivate
DockAreaTabBarPrivate::DockAreaTabBarPrivate(DockAreaTabBar *parent)
: q(parent)

View File

@@ -43,7 +43,7 @@ namespace ADS {
class DockAreaWidget;
class DockWidgetTab;
struct DockAreaTabBarPrivate;
class DockAreaTabBarPrivate;
class DockAreaTitleBar;
class FloatingDockContainer;
class AbstractFloatingWidget;
@@ -62,7 +62,7 @@ class ADS_EXPORT DockAreaTabBar : public QScrollArea
Q_OBJECT
private:
DockAreaTabBarPrivate *d; ///< private data (pimpl)
friend struct DockAreaTabBarPrivate;
friend class DockAreaTabBarPrivate;
friend class DockAreaTitleBar;
void onTabClicked();

View File

@@ -64,17 +64,17 @@ namespace ADS
/**
* Private data class of DockAreaTitleBar class (pimpl)
*/
struct DockAreaTitleBarPrivate
class DockAreaTitleBarPrivate
{
public:
DockAreaTitleBar *q;
QPointer<TitleBarButtonType> m_tabsMenuButton;
QPointer<TitleBarButtonType> m_undockButton;
QPointer<TitleBarButtonType> m_closeButton;
QBoxLayout *m_layout;
DockAreaWidget *m_dockArea;
DockAreaTabBar *m_tabBar;
QBoxLayout *m_layout = nullptr;
DockAreaWidget *m_dockArea = nullptr;
DockAreaTabBar *m_tabBar = nullptr;
bool m_menuOutdated = true;
QMenu *m_tabsMenu;
QList<TitleBarButtonType *> m_dockWidgetActionsButtons;
QPoint m_dragStartMousePos;
@@ -124,8 +124,7 @@ namespace ADS
* Makes the dock area floating
*/
AbstractFloatingWidget *makeAreaFloating(const QPoint &offset, eDragState dragState);
}; // struct DockAreaTitleBarPrivate
}; // class DockAreaTitleBarPrivate
DockAreaTitleBarPrivate::DockAreaTitleBarPrivate(DockAreaTitleBar *parent)
: q(parent)

View File

@@ -48,7 +48,7 @@ namespace ADS {
class DockAreaTabBar;
class DockAreaWidget;
struct DockAreaTitleBarPrivate;
class DockAreaTitleBarPrivate;
using TitleBarButtonType = QToolButton;
@@ -106,7 +106,7 @@ class ADS_EXPORT DockAreaTitleBar : public QFrame
Q_OBJECT
private:
DockAreaTitleBarPrivate *d; ///< private data (pimpl)
friend struct DockAreaTitleBarPrivate;
friend class DockAreaTitleBarPrivate;
void onTabsMenuAboutToShow();
void onCloseButtonClicked();

View File

@@ -67,9 +67,9 @@ private:
friend class DockContainerWidget;
friend class DockContainerWidgetPrivate;
friend class DockWidgetTab;
friend struct DockWidgetPrivate;
friend class DockWidgetPrivate;
friend class DockWidget;
friend struct DockManagerPrivate;
friend class DockManagerPrivate;
friend class DockManager;
void onTabCloseRequested(int index);

View File

@@ -50,12 +50,12 @@ class DockContainerWidgetPrivate;
class DockAreaWidget;
class DockWidget;
class DockManager;
struct DockManagerPrivate;
class DockManagerPrivate;
class FloatingDockContainer;
struct FloatingDockContainerPrivate;
class FloatingDockContainerPrivate;
class FloatingDragPreview;
struct FloatingDragPreviewPrivate;
class DockingStateReader;
class FloatingDragPreviewPrivate;
/**
* Container that manages a number of dock areas with single dock widgets
@@ -71,14 +71,14 @@ private:
DockContainerWidgetPrivate *d; ///< private data (pimpl)
friend class DockContainerWidgetPrivate;
friend class DockManager;
friend struct DockManagerPrivate;
friend class DockManagerPrivate;
friend class DockAreaWidget;
friend struct DockAreaWidgetPrivate;
friend class FloatingDockContainer;
friend struct FloatingDockContainerPrivate;
friend class FloatingDockContainerPrivate;
friend class DockWidget;
friend class FloatingDragPreview;
friend struct FloatingDragPreviewPrivate;
friend class FloatingDragPreviewPrivate;
protected:
/**

View File

@@ -77,13 +77,14 @@ namespace ADS
/**
* Private data class of DockManager class (pimpl)
*/
struct DockManagerPrivate
class DockManagerPrivate
{
public:
DockManager *q;
QList<FloatingDockContainer *> m_floatingWidgets;
QList<DockContainerWidget *> m_containers;
DockOverlay *m_containerOverlay;
DockOverlay *m_dockAreaOverlay;
DockOverlay *m_containerOverlay = nullptr;
DockOverlay *m_dockAreaOverlay = nullptr;
QMap<QString, DockWidget *> m_dockWidgetsMap;
bool m_restoringState = false;
QVector<FloatingDockContainer *> m_uninitializedFloatingWidgets;
@@ -94,7 +95,7 @@ namespace ADS
QHash<QString, QDateTime> m_workspaceDateTimes;
QString m_workspaceToRestoreAtStartup;
bool m_autorestoreLastWorkspace; // This option is set in the Workspace Manager!
QSettings *m_settings;
QSettings *m_settings = nullptr;
/**
* Private data constructor
@@ -144,8 +145,7 @@ namespace ADS
bool restoreContainer(int index, DockingStateReader &stream, bool testing);
void workspaceLoadingProgress();
};
// struct DockManagerPrivate
}; // class DockManagerPrivate
DockManagerPrivate::DockManagerPrivate(DockManager *parent)
: q(parent)
@@ -188,6 +188,8 @@ namespace ADS
}
DockingStateReader stateReader(state);
stateReader.readNextStartElement();
if (!stateReader.readNextStartElement())
return false;
if (stateReader.name() != "QtAdvancedDockingSystem") {
return false;
}

View File

@@ -66,16 +66,16 @@ const char STARTUP_WORKSPACE_SETTINGS_KEY[] = "QML/Designer/StartupWorkspace";
const char AUTO_RESTORE_WORKSPACE_SETTINGS_KEY[] = "QML/Designer/AutoRestoreLastWorkspace";
} // namespace Constants
struct DockManagerPrivate;
class DockManagerPrivate;
class FloatingDockContainer;
struct FloatingDockContainerPrivate;
class FloatingDockContainerPrivate;
class DockComponentsFactory;
class DockContainerWidget;
class DockContainerWidgetPrivate;
class DockOverlay;
class DockAreaTabBar;
class DockWidgetTab;
struct DockWidgetTabPrivate;
class DockWidgetTabPrivate;
struct DockAreaWidgetPrivate;
class IconProvider;
@@ -96,17 +96,17 @@ class ADS_EXPORT DockManager : public DockContainerWidget
Q_OBJECT
private:
DockManagerPrivate *d; ///< private data (pimpl)
friend struct DockManagerPrivate;
friend class DockManagerPrivate;
friend class FloatingDockContainer;
friend struct FloatingDockContainerPrivate;
friend class FloatingDockContainerPrivate;
friend class DockContainerWidget;
friend class DockContainerWidgetPrivate;
friend class DockAreaTabBar;
friend class DockWidgetTab;
friend struct DockAreaWidgetPrivate;
friend struct DockWidgetTabPrivate;
friend class DockWidgetTabPrivate;
friend class FloatingDragPreview;
friend struct FloatingDragPreviewPrivate;
friend class FloatingDragPreviewPrivate;
friend class DockAreaTitleBar;
protected:

View File

@@ -59,11 +59,12 @@ namespace ADS {
/**
* Private data class of DockOverlay
*/
struct DockOverlayPrivate
class DockOverlayPrivate
{
public:
DockOverlay *q;
DockWidgetAreas m_allowedAreas = InvalidDockWidgetArea;
DockOverlayCross *m_cross;
DockOverlayCross *m_cross = nullptr;
QPointer<QWidget> m_targetWidget;
DockWidgetArea m_lastLocation = InvalidDockWidgetArea;
bool m_dropPreviewEnabled = true;
@@ -81,13 +82,14 @@ namespace ADS {
/**
* Private data of DockOverlayCross class
*/
struct DockOverlayCrossPrivate
class DockOverlayCrossPrivate
{
public:
DockOverlayCross *q;
DockOverlay::eMode m_mode = DockOverlay::ModeDockAreaOverlay;
DockOverlay *m_dockOverlay;
DockOverlay *m_dockOverlay = nullptr;
QHash<DockWidgetArea, QWidget *> m_dropIndicatorWidgets;
QGridLayout *m_gridLayout;
QGridLayout *m_gridLayout = nullptr;
QColor m_iconColors[5];
bool m_updateRequired = false;
double m_lastDevicePixelRatio = 0.1;
@@ -335,7 +337,7 @@ namespace ADS {
pixmap.setDevicePixelRatio(devicePixelRatio);
return pixmap;
}
};
}; // class DockOverlayCrossPrivate
DockOverlay::DockOverlay(QWidget *parent, eMode mode)
: QFrame(parent)

View File

@@ -48,7 +48,7 @@ QT_END_NAMESPACE
namespace ADS {
struct DockOverlayPrivate;
class DockOverlayPrivate;
class DockOverlayCross;
/**
@@ -60,7 +60,7 @@ class ADS_EXPORT DockOverlay : public QFrame
Q_OBJECT
private:
DockOverlayPrivate *d; //< private data class
friend struct DockOverlayPrivate;
friend class DockOverlayPrivate;
friend class DockOverlayCross;
public:
@@ -130,7 +130,7 @@ protected:
virtual void hideEvent(QHideEvent *event) override;
};
struct DockOverlayCrossPrivate;
class DockOverlayCrossPrivate;
/**
* DockOverlayCross shows a cross with 5 different drop area possibilities.
* I could have handled everything inside DockOverlay, but because of some
@@ -176,7 +176,7 @@ public:
private:
DockOverlayCrossPrivate *d;
friend struct DockOverlayCrossPrivate;
friend class DockOverlayCrossPrivate;
friend class DockOverlay;
protected:

View File

@@ -63,8 +63,9 @@ namespace ADS
/**
* Private data class of DockWidget class (pimpl)
*/
struct DockWidgetPrivate
class DockWidgetPrivate
{
public:
DockWidget *q = nullptr;
QBoxLayout *m_layout = nullptr;
QWidget *m_widget = nullptr;
@@ -114,8 +115,7 @@ namespace ADS
* Setup the main scroll area
*/
void setupScrollArea();
};
// struct DockWidgetPrivate
}; // class DockWidgetPrivate
DockWidgetPrivate::DockWidgetPrivate(DockWidget *parent)
: q(parent)
@@ -336,9 +336,9 @@ namespace ADS
void DockWidget::toggleViewInternal(bool open)
{
DockContainerWidget *dockContainerWidget = dockContainer();
DockWidget *topLevelDockWidgetBefore = dockContainerWidget
? dockContainerWidget->topLevelDockWidget()
const DockContainerWidget *const beforeDockContainerWidget = dockContainer();
DockWidget *topLevelDockWidgetBefore = beforeDockContainerWidget
? beforeDockContainerWidget->topLevelDockWidget()
: nullptr;
if (open) {
@@ -359,12 +359,14 @@ namespace ADS
// Here we need to call the dockContainer() function again, because if
// this dock widget was unassigned before the call to showDockWidget() then
// it has a dock container now
dockContainerWidget = dockContainer();
const DockContainerWidget *const dockContainerWidget = dockContainer();
DockWidget *topLevelDockWidgetAfter = dockContainerWidget
? dockContainerWidget->topLevelDockWidget()
: nullptr;
DockWidget::emitTopLevelEventForWidget(topLevelDockWidgetAfter, true);
FloatingDockContainer *floatingContainer = dockContainerWidget->floatingWidget();
FloatingDockContainer *floatingContainer = dockContainerWidget
? dockContainerWidget->floatingWidget()
: nullptr;
if (floatingContainer)
floatingContainer->updateWindowTitle();

View File

@@ -46,7 +46,7 @@ QT_END_NAMESPACE
namespace ADS {
struct DockWidgetPrivate;
class DockWidgetPrivate;
class DockWidgetTab;
class DockManager;
class DockContainerWidget;
@@ -63,7 +63,7 @@ class ADS_EXPORT DockWidget : public QFrame
Q_OBJECT
private:
DockWidgetPrivate *d; ///< private data (pimpl)
friend struct DockWidgetPrivate;
friend class DockWidgetPrivate;
/**
* Adjusts the toolbar icon sizes according to the floating state
@@ -75,12 +75,12 @@ protected:
friend class DockAreaWidget;
friend class FloatingDockContainer;
friend class DockManager;
friend struct DockManagerPrivate;
friend class DockManagerPrivate;
friend class DockContainerWidgetPrivate;
friend class DockAreaTabBar;
friend class DockWidgetTab;
friend struct DockWidgetTabPrivate;
friend struct DockAreaTitleBarPrivate;
friend class DockWidgetTabPrivate;
friend class DockAreaTitleBarPrivate;
/**
* Assigns the dock manager that manages this dock widget

View File

@@ -67,12 +67,13 @@ namespace ADS
/**
* Private data class of DockWidgetTab class (pimpl)
*/
struct DockWidgetTabPrivate
class DockWidgetTabPrivate
{
public:
DockWidgetTab *q;
DockWidget *m_dockWidget;
DockWidget *m_dockWidget = nullptr;
QLabel *m_iconLabel = nullptr;
TabLabelType *m_titleLabel;
TabLabelType *m_titleLabel = nullptr;
QPoint m_globalDragStartMousePosition;
QPoint m_dragStartMousePosition;
bool m_isActiveTab = false;
@@ -81,7 +82,6 @@ namespace ADS
AbstractFloatingWidget *m_floatingWidget = nullptr;
QIcon m_icon;
QAbstractButton *m_closeButton = nullptr;
QSpacerItem *m_iconTextSpacer;
QPoint m_tabDragStartPosition;
/**
@@ -155,8 +155,7 @@ namespace ADS
m_globalDragStartMousePosition = globalPos;
m_dragStartMousePosition = q->mapFromGlobal(globalPos);
}
};
// struct DockWidgetTabPrivate
}; // class DockWidgetTabPrivate
DockWidgetTabPrivate::DockWidgetTabPrivate(DockWidgetTab *parent)
: q(parent)

View File

@@ -43,7 +43,7 @@ namespace ADS {
class DockWidget;
class DockAreaWidget;
struct DockWidgetTabPrivate;
class DockWidgetTabPrivate;
/**
* A dock widget tab that shows a title and an icon.
@@ -57,7 +57,7 @@ class ADS_EXPORT DockWidgetTab : public QFrame
private:
DockWidgetTabPrivate *d; ///< private data (pimpl)
friend struct DockWidgetTabPrivate;
friend class DockWidgetTabPrivate;
friend class DockWidget;
void onDockWidgetFeaturesChanged();
void detachDockWidget();

View File

@@ -62,10 +62,11 @@ namespace ADS
/**
* Private data class of FloatingDockContainer class (pimpl)
*/
struct FloatingDockContainerPrivate
class FloatingDockContainerPrivate
{
public:
FloatingDockContainer *q;
DockContainerWidget *m_dockContainer;
DockContainerWidget *m_dockContainer = nullptr;
unsigned int m_zOrderIndex = ++zOrderCounter;
QPointer<DockManager> m_dockManager;
eDragState m_draggingState = DraggingInactive;
@@ -125,8 +126,7 @@ namespace ADS
q->setWindowIcon(QApplication::windowIcon());
}
}
};
// struct FloatingDockContainerPrivate
}; // class FloatingDockContainerPrivate
FloatingDockContainerPrivate::FloatingDockContainerPrivate(FloatingDockContainer *parent)
: q(parent)

View File

@@ -48,18 +48,18 @@ using FloatingWidgetBaseType = QWidget;
namespace ADS {
struct FloatingDockContainerPrivate;
class FloatingDockContainerPrivate;
class DockManager;
struct DockManagerPrivate;
class DockManagerPrivate;
class DockAreaWidget;
class DockContainerWidget;
class DockWidget;
class DockManager;
class DockAreaTabBar;
class DockWidgetTab;
struct DockWidgetTabPrivate;
class DockWidgetTabPrivate;
class DockAreaTitleBar;
struct DockAreaTitleBarPrivate;
class DockAreaTitleBarPrivate;
class FloatingWidgetTitleBar;
class DockingStateReader;
@@ -111,14 +111,14 @@ class ADS_EXPORT FloatingDockContainer : public FloatingWidgetBaseType,
Q_OBJECT
private:
FloatingDockContainerPrivate *d; ///< private data (pimpl)
friend struct FloatingDockContainerPrivate;
friend class FloatingDockContainerPrivate;
friend class DockManager;
friend struct DockManagerPrivate;
friend class DockManagerPrivate;
friend class DockAreaTabBar;
friend struct DockWidgetTabPrivate;
friend class DockWidgetTabPrivate;
friend class DockWidgetTab;
friend class DockAreaTitleBar;
friend struct DockAreaTitleBarPrivate;
friend class DockAreaTitleBarPrivate;
friend class DockWidget;
friend class DockAreaWidget;
friend class FloatingWidgetTitleBar;

View File

@@ -56,16 +56,16 @@ namespace ADS
/**
* Private data class (pimpl)
*/
struct FloatingDragPreviewPrivate
class FloatingDragPreviewPrivate
{
public:
FloatingDragPreview *q;
QWidget *m_content;
QWidget *m_content = nullptr;
DockAreaWidget *m_contentSourceArea = nullptr;
DockContainerWidget *m_contenSourceContainer = nullptr;
QPoint m_dragStartMousePosition;
DockManager *m_dockManager;
DockManager *m_dockManager = nullptr;
DockContainerWidget *m_dropContainer = nullptr;
qreal m_windowOpacity;
bool m_hidden = false;
QPixmap m_contentPreviewPixmap;
@@ -91,8 +91,7 @@ namespace ADS
m_dockManager->dockAreaOverlay()->hideOverlay();
q->close();
}
};
// struct FloatingDragPreviewPrivate
}; // class FloatingDragPreviewPrivate
void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &globalPosition)
{

View File

@@ -43,7 +43,7 @@ namespace ADS {
class DockWidget;
class DockAreaWidget;
struct FloatingDragPreviewPrivate;
class FloatingDragPreviewPrivate;
/**
* A floating overlay is a temporary floating widget that is just used to
@@ -56,7 +56,7 @@ class FloatingDragPreview : public QWidget, public AbstractFloatingWidget
Q_OBJECT
private:
FloatingDragPreviewPrivate *d;
friend struct FloatingDragPreviewPrivate;
friend class FloatingDragPreviewPrivate;
/**
* Cancel non opaque undocking if application becomes inactive

Some files were not shown because too many files have changed in this diff Show More