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() endfunction()
if (NOT TARGET QtCreatorPchGui AND NOT TARGET QtCreatorPchConsole) if (NOT TARGET QtCreatorPchGui AND NOT TARGET QtCreatorPchConsole)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/empty_pch.c_cpp.in "/*empty file*/") file(GENERATE
configure_file( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/empty_pch.c
${CMAKE_CURRENT_BINARY_DIR}/empty_pch.c_cpp.in CONTENT "/*empty file*/")
${CMAKE_CURRENT_BINARY_DIR}/empty_pch.cpp) file(GENERATE
configure_file( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/empty_pch.cpp
${CMAKE_CURRENT_BINARY_DIR}/empty_pch.c_cpp.in CONTENT "/*empty file*/")
${CMAKE_CURRENT_BINARY_DIR}/empty_pch.c)
_add_pch_target(QtCreatorPchGui _add_pch_target(QtCreatorPchGui
"${PROJECT_SOURCE_DIR}/src/shared/qtcreator_gui_pch.h" Qt5::Widgets) "${PROJECT_SOURCE_DIR}/src/shared/qtcreator_gui_pch.h" Qt5::Widgets)
_add_pch_target(QtCreatorPchConsole _add_pch_target(QtCreatorPchConsole
@@ -728,9 +726,10 @@ function(add_qtc_plugin target_name)
string(REGEX REPLACE "^.*=" "" json_value ${_arg_PLUGIN_JSON_IN}) string(REGEX REPLACE "^.*=" "" json_value ${_arg_PLUGIN_JSON_IN})
string(REPLACE "$$${json_key}" "${json_value}" plugin_json_in ${plugin_json_in}) string(REPLACE "$$${json_key}" "${json_value}" plugin_json_in ${plugin_json_in})
endif() endif()
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${name}.json.cmakein" ${plugin_json_in}) string(CONFIGURE "${plugin_json_in}" plugin_json)
file(GENERATE
configure_file("${CMAKE_CURRENT_BINARY_DIR}/${name}.json.cmakein" "${name}.json") OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${name}.json"
CONTENT "${plugin_json}")
endif() endif()
add_library(${target_name} SHARED ${_arg_SOURCES}) 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} \l{http://linterrors.com/js/the-array-literal-notation-is-preferrable}
{The array literal notation [] is preferable}. {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 \row
\li M400 \li M400
\li Warning \li Warning
\li Duplicate import \li Duplicate import
\li
\endtable \endtable

View File

@@ -54,12 +54,18 @@
\section2 Navigating Between Open Files and Symbols \section2 Navigating Between Open Files and Symbols
Use the toolbar to navigate between open files and symbols in use. To browse Use the toolbar, \uicontrol Window menu items, or
backward or forward through your location history, click \l{General Keyboard Shortcuts}{keyboard shortcuts}
\inlineimage prev.png 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 Back}) and \inlineimage next.png
(\uicontrol {Go Forward}). (\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 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 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 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 (:). number in the locator, separated by a colon (:).
\note Other convenient ways of navigating in \QC are provided \note Other convenient ways of navigating in \QC are provided
by the \l{Keyboard Shortcuts} {keyboard shortcuts} and the by the \l{Browsing Project Contents}{sidebars}.
\l{Browsing Project Contents}{sidebar}.
\if defined(qtcreator) \if defined(qtcreator)
\section2 Selecting Parse Context \section2 Selecting Parse Context
@@ -187,10 +192,10 @@
the bookmark. the bookmark.
To go to the previous bookmark in the current session, select 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+,}. 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 \uicontrol Bookmarks > \uicontrol {Previous Bookmark} or press
\key {Ctrl+.}. \key {Ctrl+.}.
@@ -265,10 +270,10 @@
\section1 Inspecting the Code Model \section1 Inspecting the Code Model
When you report a bug that is related to the C++ code model, the \QC When you \l{https://bugreports.qt.io/}{report a bug} that is related to the
developers might ask you to write information about the internal state of C++ code model, the \QC developers might ask you to write information about
the code model into a log file and to deliver the file to them for the internal state of the code model into a log file and to deliver the file
inspection. to them for inspection.
To view information about the C++ code model in the To view information about the C++ code model in the
\uicontrol {C++ Code Model Inspector} dialog and write it to a log file, \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/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** 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" \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 The changes are displayed in the \uicontrol Edit mode. Color coding is
to mark changed lines. By default, light red indicates lines that contain used to mark changed lines. By default, red indicates lines that contain
removed text (painted a darker red) in the left pane and light green removed text (painted another shade of red) in the left pane and green
indicates lines that contain added text (painted a darker green) in the indicates lines that contain added text (painted another shade of green)
right pane. in the right pane.
To revert the changes, right-click added text and then select To revert the changes, right-click added text and then select
\uicontrol {Revert Chunk} in the context menu. To apply the changes, 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. 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: To activate the locator:
@@ -59,7 +59,7 @@
\li Start typing the filename. \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. \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 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) \if defined(qtcreator)
\li Running external tools (\c x) \li Running external tools (\c x)
\li Using CMake to build the project for the current run configuration \li Using CMake to build the project for the current run configuration
@@ -184,7 +187,7 @@
The locator lists the results. The locator lists the results.
\image qtcreator-navigate-popup.png \image qtcreator-locator-example.png "List of files matching the locator filter"
\endlist \endlist
@@ -265,7 +268,7 @@
\li Select \uicontrol Add to add a new entry to the list. \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. \li Double-click the new entry to specify a URL and a search command.
For example, \c {http://www.google.com/search?q=%1}. For example, \c {http://www.google.com/search?q=%1}.
@@ -276,49 +279,48 @@
\section1 Creating Locator Filters \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 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. directory structure you have defined.
To create a locator filter: To create custom locator filters:
\list 1 \list 1
\li In the locator, select \uicontrol Options > \li In the locator, select \uicontrol Options >
\uicontrol Configure to open the \uicontrol Locator 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 \li In the \uicontrol {Exclusion pattern} field, specify file
directory. The locator searches directories recursively. patterns to omit files from the search.
\li In the \uicontrol {File pattern} field, specify file patterns to \li In the \uicontrol Prefix field, specify the prefix string.
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 {Exclusion pattern} field, specify file To implicitly include the filter even when not typing a prefix
patterns to omit files from the search. as a part of the search string, select
\uicontrol {Include by default}.
\li In the \uicontrol Prefix field, specify the prefix string. \li Select \uicontrol OK.
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.
\endlist \endlist

View File

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

View File

@@ -92,6 +92,12 @@
\QC, \QSDK and other Qt deliverables contain documentation \QC, \QSDK and other Qt deliverables contain documentation
as .qch files. All the documentation is accessible in the \uicontrol Help mode. 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: To find information in the documentation, select:
\list \list
@@ -210,6 +216,9 @@
in the \uicontrol {On context help} field. To detach the help window, select in the \uicontrol {On context help} field. To detach the help window, select
\uicontrol {Always Show in External Window}. \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 \section1 Selecting the Start Page
You can select the page to display when you open the \uicontrol Help mode in the 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?} \b {Has a reported issue been addressed?}
You can look up any issue in the 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 \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 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 \l{glossary-device}{device}, compiler, and Qt version. If you know you have
installed a Qt installed a Qt version, but it is not listed in \uicontrol Tools >
version, but it is not listed in \uicontrol Tools > \uicontrol Options > \uicontrol Options > \uicontrol Kits > \uicontrol {Qt Versions}, select
\uicontrol Kits > \uicontrol {Qt Versions}, you must add it. \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}. 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 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} the \c{qtcreator\dist} folder or the \l{https://bugreports.qt.io}
{Qt Bug Tracker}. {Qt Project Bug Tracker}.
\section1 General Issues \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/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -42,12 +42,41 @@
\l{glossary-device}{device} manufacturers provide special Qt versions for \l{glossary-device}{device} manufacturers provide special Qt versions for
developing applications for their devices. developing applications for their devices.
\section1 Registering Installed Qt Versions
\QC automatically detects the Qt versions that are registered by \QC automatically detects the Qt versions that are registered by
your system or by installers. To view detailed information for each Qt your system or by installers. To view detailed information for each Qt
version, select it in the list and select \uicontrol Details in the version, select it in the list and select \uicontrol Details in the
\uicontrol {Qt version for} section. To add Qt versions, select \uicontrol {Qt version for} section.
\uicontrol Tools > \uicontrol Options > \uicontrol Kits >
\uicontrol {Qt Versions}. \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} You specify the Qt version to use for each \l{glossary-buildandrun-kit}
{kit} for building and running your projects {kit} for building and running your projects
@@ -67,8 +96,6 @@
\li Select the Qt version to view and edit it. \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 \li In the \uicontrol{Version name} field, edit the name that \QC
suggests for the Qt version. suggests for the Qt version.
@@ -80,7 +107,10 @@
\endlist \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 By default, \QC registers only the latest available version of the documentation for each
installed Qt module. installed Qt module.
@@ -109,13 +139,15 @@
If your build of Qt is incomplete but you still want to use QMake as build 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. system, you need to ensure the following minimum requirements to be able to use that setup with \QC.
\list 1 \list 1
\li qmake is an executable that understands the -query command line argument. \li qmake is an executable that understands the \c -query command line
\li The bin and include directories have to exist. \QC fetches these directories by running \c{qmake -query}. argument.
\li The mkspecs directory should be complete enough to parse .pro files. \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 \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 \row
\li {4,1} \l{All Topics} \li {4,1} \l{All Topics}
\row \row
\li {4,1} \note To report bugs and suggestions to the Qt Bug \li {4,1} \note To report bugs and suggestions to the
Tracker, select \uicontrol {Help > Report Bug}. \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 To copy and paste detailed information about your system to the
bug report, select \uicontrol Help > bug report, select \uicontrol Help >
\uicontrol {System Information}. \uicontrol {System Information}.

View File

@@ -151,7 +151,8 @@
instead, select the \uicontrol {Switch to Text Diff Editor} (1) option from instead, select the \uicontrol {Switch to Text Diff Editor} (1) option from
the toolbar. In the inline the toolbar. In the inline
diff view, you can use context menu commands to apply, revert, stage, and 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 \section2 Viewing Versioning History and Change Details

View File

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

View File

@@ -107,8 +107,9 @@
\row \row
\li {4,1} \l{All Topics} \li {4,1} \l{All Topics}
\row \row
\li {4,1} \note To report bugs and suggestions to the Qt Bug \li {4,1} \note To report bugs and suggestions to the
Tracker, select \uicontrol {Help > Report Bug}. \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 To copy and paste detailed information about your system to the
bug report, select \uicontrol Help > bug report, select \uicontrol Help >
\uicontrol {System Information}. \uicontrol {System Information}.

View File

@@ -161,7 +161,7 @@
or press \key R. or press \key R.
You can use the scale handles to adjust the local x, y, or z scale of an 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. on the handle.
To adjust the scale across one axis, select the scale handle attached to To adjust the scale across one axis, select the scale handle attached to

View File

@@ -25,6 +25,7 @@
from dumper import Children from dumper import Children
def qdump__boost__bimaps__bimap(d, value): def qdump__boost__bimaps__bimap(d, value):
#leftType = value.type[0] #leftType = value.type[0]
#rightType = value.type[1] #rightType = value.type[1]
@@ -64,7 +65,7 @@ def qdump__boost__shared_ptr(d, value):
(vptr, usecount, weakcount) = d.split('pii', pi) (vptr, usecount, weakcount) = d.split('pii', pi)
d.check(weakcount >= 0) d.check(weakcount >= 0)
d.check(weakcount <= usecount) 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.putItem(d.createValue(px, value.type[0]))
d.putBetterType(value.type) 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): def qdump__boost__unordered__unordered_set(d, value):
innerType = value.type[0] 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 # boost 1.58 or 1.55
# bases are 3? bytes, and mlf is actually a float, but since # 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 # 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: if forward:
# boost 1.58 # boost 1.58
code = 'pp{%s}' % innerType.name code = 'pp{%s}' % innerType.name
def children(p): def children(p):
while True: while True:
p, dummy, val = d.split(code, p) p, dummy, val = d.split(code, p)
@@ -134,12 +136,13 @@ def qdump__boost__unordered__unordered_set(d, value):
code = '{%s}@p' % innerType.name code = '{%s}@p' % innerType.name
(pp, ssize, fields) = d.describeStruct(code) (pp, ssize, fields) = d.describeStruct(code)
offset = fields[2].offset() offset = fields[2].offset()
def children(p): def children(p):
while True: while True:
val, pad, p = d.split(code, p - offset) val, pad, p = d.split(code, p - offset)
yield val yield val
p = d.extractPointer(buckets + bucketCount * d.ptrSize()) 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): 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 from dumper import DumperBase, SubItem
class FakeVoidType(cdbext.Type): class FakeVoidType(cdbext.Type):
def __init__(self, name , dumper): def __init__(self, name, dumper):
cdbext.Type.__init__(self) cdbext.Type.__init__(self)
self.typeName = name.strip() self.typeName = name.strip()
self.dumper = dumper self.dumper = dumper
@@ -49,19 +50,19 @@ class FakeVoidType(cdbext.Type):
def code(self): def code(self):
if self.typeName.endswith('*'): if self.typeName.endswith('*'):
return TypeCode.TypeCodePointer return TypeCode.Pointer
if self.typeName.endswith(']'): if self.typeName.endswith(']'):
return TypeCode.TypeCodeArray return TypeCode.Array
return TypeCode.TypeCodeVoid return TypeCode.Void
def unqualified(self): def unqualified(self):
return self return self
def target(self): def target(self):
code = self.code() code = self.code()
if code == TypeCode.TypeCodePointer: if code == TypeCode.Pointer:
return FakeVoidType(self.typeName[:-1], self.dumper) return FakeVoidType(self.typeName[:-1], self.dumper)
if code == TypeCode.TypeCodeVoid: if code == TypeCode.Void:
return self return self
try: try:
return FakeVoidType(self.typeName[:self.typeName.rindex('[')], self.dumper) return FakeVoidType(self.typeName[:self.typeName.rindex('[')], self.dumper)
@@ -89,6 +90,7 @@ class FakeVoidType(cdbext.Type):
def templateArguments(self): def templateArguments(self):
return [] return []
class Dumper(DumperBase): class Dumper(DumperBase):
def __init__(self): def __init__(self):
DumperBase.__init__(self) DumperBase.__init__(self)
@@ -107,14 +109,14 @@ class Dumper(DumperBase):
val.type = self.fromNativeType(nativeValue.type()) val.type = self.fromNativeType(nativeValue.type())
# There is no cdb api for the size of bitfields. # There is no cdb api for the size of bitfields.
# Workaround this issue by parsing the native debugger text for integral types. # 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() integerString = nativeValue.nativeDebuggerValue()
if integerString == 'true': if integerString == 'true':
val.ldata = int(1).to_bytes(1, byteorder='little') val.ldata = int(1).to_bytes(1, byteorder='little')
elif integerString == 'false': elif integerString == 'false':
val.ldata = int(0).to_bytes(1, byteorder='little') val.ldata = int(0).to_bytes(1, byteorder='little')
else: else:
integerString = integerString.replace('`','') integerString = integerString.replace('`', '')
integerString = integerString.split(' ')[0] integerString = integerString.split(' ')[0]
if integerString.startswith('0n'): if integerString.startswith('0n'):
integerString = integerString[2:] integerString = integerString[2:]
@@ -125,12 +127,12 @@ class Dumper(DumperBase):
base = 10 base = 10
signed = not val.type.name.startswith('unsigned') signed = not val.type.name.startswith('unsigned')
try: try:
val.ldata = int(integerString, base).to_bytes(val.type.size(), \ val.ldata = int(integerString, base).to_bytes(val.type.size(),
byteorder='little', signed=signed) byteorder='little', signed=signed)
except: except:
# read raw memory in case the integerString can not be interpreted # read raw memory in case the integerString can not be interpreted
pass pass
if val.type.code == TypeCode.TypeCodeEnum: if val.type.code == TypeCode.Enum:
val.ldisplay = self.enumValue(nativeValue) val.ldisplay = self.enumValue(nativeValue)
val.isBaseClass = val.name == val.type.name val.isBaseClass = val.name == val.type.name
val.nativeValue = nativeValue val.nativeValue = nativeValue
@@ -148,7 +150,8 @@ class Dumper(DumperBase):
c = 'u' c = 'u'
else: else:
return name 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 return typeId
def fromNativeType(self, nativeType): def fromNativeType(self, nativeType):
@@ -161,21 +164,22 @@ class Dumper(DumperBase):
nativeType = FakeVoidType(nativeType.name(), self) nativeType = FakeVoidType(nativeType.name(), self)
code = nativeType.code() code = nativeType.code()
if code == TypeCode.TypeCodePointer: if code == TypeCode.Pointer:
if not nativeType.name().startswith('<function>'): if not nativeType.name().startswith('<function>'):
targetType = self.lookupType(nativeType.targetName(), nativeType.moduleId()) targetType = self.lookupType(nativeType.targetName(), nativeType.moduleId())
if targetType is not None: if targetType is not None:
return self.createPointerType(targetType) 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 # 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 '): if not nativeType.name().startswith('__fptr()') and not nativeType.name().startswith('<gentype '):
targetType = self.lookupType(nativeType.targetName(), nativeType.moduleId()) targetType = self.lookupType(nativeType.targetName(), nativeType.moduleId())
if targetType is not None: if targetType is not None:
return self.createArrayType(targetType, nativeType.arrayElements()) return self.createArrayType(targetType, nativeType.arrayElements())
code = TypeCode.TypeCodeStruct code = TypeCode.Struct
tdata = self.TypeData(self) tdata = self.TypeData(self)
tdata.name = nativeType.name() tdata.name = nativeType.name()
@@ -183,17 +187,17 @@ class Dumper(DumperBase):
tdata.lbitsize = nativeType.bitsize() tdata.lbitsize = nativeType.bitsize()
tdata.code = code tdata.code = code
tdata.moduleName = nativeType.module() tdata.moduleName = nativeType.module()
self.registerType(typeId, tdata) # Prevent recursion in fields. self.registerType(typeId, tdata) # Prevent recursion in fields.
if code == TypeCode.TypeCodeStruct: if code == TypeCode.Struct:
tdata.lfields = lambda value : \ tdata.lfields = lambda value: \
self.listFields(nativeType, value) self.listFields(nativeType, value)
tdata.lalignment = lambda : \ tdata.lalignment = lambda: \
self.nativeStructAlignment(nativeType) self.nativeStructAlignment(nativeType)
if code == TypeCode.TypeCodeEnum: if code == TypeCode.Enum:
tdata.enumDisplay = lambda intval, addr, form : \ tdata.enumDisplay = lambda intval, addr, form: \
self.nativeTypeEnumDisplay(nativeType, intval, form) self.nativeTypeEnumDisplay(nativeType, intval, form)
tdata.templateArguments = self.listTemplateParameters(nativeType.name()) 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) return self.Type(self, typeId)
def listFields(self, nativeType, value): def listFields(self, nativeType, value):
@@ -320,14 +324,16 @@ class Dumper(DumperBase):
if namespaceIndex > 0: if namespaceIndex > 0:
namespace = name[:namespaceIndex + 2] namespace = name[:namespaceIndex + 2]
self.qtNamespace = lambda: namespace self.qtNamespace = lambda: namespace
self.qtCustomEventFunc = self.parseAndEvaluate('%s!%sQObject::customEvent' self.qtCustomEventFunc = self.parseAndEvaluate(
% (self.qtCoreModuleName(), namespace)).address() '%s!%sQObject::customEvent' %
(self.qtCoreModuleName(), namespace)).address()
return namespace return namespace
def qtVersion(self): def qtVersion(self):
qtVersion = None qtVersion = None
try: try:
qtVersion = self.parseAndEvaluate('((void**)&%s)[2]' % self.qtHookDataSymbolName()).integer() qtVersion = self.parseAndEvaluate(
'((void**)&%s)[2]' % self.qtHookDataSymbolName()).integer()
except: except:
if self.qtCoreModuleName() is not None: if self.qtCoreModuleName() is not None:
try: try:
@@ -391,7 +397,7 @@ class Dumper(DumperBase):
else: else:
return typeName return typeName
def lookupType(self, typeNameIn, module = 0): def lookupType(self, typeNameIn, module=0):
if len(typeNameIn) == 0: if len(typeNameIn) == 0:
return None return None
typeName = self.stripQintTypedefs(typeNameIn) typeName = self.stripQintTypedefs(typeNameIn)
@@ -405,7 +411,7 @@ class Dumper(DumperBase):
return type return type
return self.Type(self, typeName) return self.Type(self, typeName)
def lookupNativeType(self, name, module = 0): def lookupNativeType(self, name, module=0):
if name.startswith('void'): if name.startswith('void'):
return FakeVoidType(name, self) return FakeVoidType(name, self)
return cdbext.lookupType(name, module) return cdbext.lookupType(name, module)
@@ -447,7 +453,7 @@ class Dumper(DumperBase):
variables = [] variables = []
for val in cdbext.listOfLocals(self.partialVariable): for val in cdbext.listOfLocals(self.partialVariable):
dumperVal = self.fromNativeValue(val) dumperVal = self.fromNativeValue(val)
dumperVal.lIsInScope = not dumperVal.name in self.uninitialized dumperVal.lIsInScope = dumperVal.name not in self.uninitialized
variables.append(dumperVal) variables.append(dumperVal)
self.handleLocals(variables) self.handleLocals(variables)
@@ -472,7 +478,7 @@ class Dumper(DumperBase):
return cdbext.parseAndEvaluate(exp) return cdbext.parseAndEvaluate(exp)
def nativeDynamicTypeName(self, address, baseType): def nativeDynamicTypeName(self, address, baseType):
return None # Does not work with cdb return None # Does not work with cdb
def nativeValueDereferenceReference(self, value): def nativeValueDereferenceReference(self, value):
return self.nativeValueDereferencePointer(value) return self.nativeValueDereferencePointer(value)

View File

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

View File

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

View File

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

View File

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

View File

@@ -41,7 +41,7 @@ class QuitException(Exception):
pass pass
class QtcInternalBreakpoint: class QtcInternalBreakpoint():
"""Breakpoint class. """Breakpoint class.
Breakpoints are indexed by number through bpbynumber and by Breakpoints are indexed by number through bpbynumber and by
the file,line tuple using bplist. The former points to a the file,line tuple using bplist. The former points to a
@@ -52,9 +52,9 @@ class QtcInternalBreakpoint:
next = 1 # Next bp to be assigned next = 1 # Next bp to be assigned
bplist = {} # indexed by (file, lineno) tuple bplist = {} # indexed by (file, lineno) tuple
bpbynumber = [None] # Each entry is None or an instance of Bpt bpbynumber = [None] # Each entry is None or an instance of Bpt
# index 0 is unused, except for marking an # index 0 is unused, except for marking an
# effective break .... see effective() # effective break .... see effective()
def __init__(self, filepath, line, temporary=False, cond=None, funcname=None): def __init__(self, filepath, line, temporary=False, cond=None, funcname=None):
self.funcname = funcname self.funcname = funcname
@@ -115,7 +115,7 @@ def checkfuncname(b, frame):
# The function is entered for the 1st time. # The function is entered for the 1st time.
b.func_first_executable_line = frame.f_lineno 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. # But we are not at the first line number: don't break.
return False return False
return True return True
@@ -193,7 +193,7 @@ class _rstr(str):
return self return self
class QtcInternalDumper: class QtcInternalDumper():
identchars = string.ascii_letters + string.digits + '_' identchars = string.ascii_letters + string.digits + '_'
lastcmd = '' lastcmd = ''
use_rawinput = 1 use_rawinput = 1
@@ -387,7 +387,7 @@ class QtcInternalDumper:
# (CT) stopframe may now also be None, see dispatch_call. # (CT) stopframe may now also be None, see dispatch_call.
# (CT) the former test for None is therefore removed from here. # (CT) the former test for None is therefore removed from here.
if self.skip and \ if self.skip and \
self.is_skipped_module(frame.f_globals.get('__name__')): self.is_skipped_module(frame.f_globals.get('__name__')):
return False return False
if frame is self.stopframe: if frame is self.stopframe:
if self.stoplineno == -1: if self.stoplineno == -1:
@@ -696,7 +696,7 @@ class QtcInternalDumper:
return None, None, line return None, None, line
i, length = 0, len(line) i, length = 0, len(line)
while i < length and line[i] in self.identchars: while i < length and line[i] in self.identchars:
i = i+1 i = i + 1
cmd, arg = line[:i], line[i:].strip() cmd, arg = line[:i], line[i:].strip()
return cmd, arg, line return cmd, arg, line
@@ -745,10 +745,10 @@ class QtcInternalDumper:
import __main__ import __main__
# __main__.__dict__.clear() # __main__.__dict__.clear()
__main__.__dict__.update({'__name__' : '__main__', __main__.__dict__.update({'__name__': '__main__',
'__file__' : mainpyfile, '__file__': mainpyfile,
# '__builtins__': __builtins__, #'__builtins__': __builtins__,
}) })
# When bdb sets tracing, a number of call and line events happens # When bdb sets tracing, a number of call and line events happens
# BEFORE debugger even reaches user's code (and the exact sequence of # BEFORE debugger even reaches user's code (and the exact sequence of
@@ -966,7 +966,7 @@ class QtcInternalDumper:
comma = arg.find(',') comma = arg.find(',')
if comma > 0: if comma > 0:
# parse stuff after comma: 'condition' # parse stuff after comma: 'condition'
cond = arg[comma+1:].lstrip() cond = arg[comma + 1:].lstrip()
arg = arg[:comma].rstrip() arg = arg[:comma].rstrip()
# parse stuff before comma: [filename:]lineno | function # parse stuff before comma: [filename:]lineno | function
colon = arg.rfind(':') colon = arg.rfind(':')
@@ -979,7 +979,7 @@ class QtcInternalDumper:
return return
else: else:
filename = f filename = f
arg = arg[colon+1:].lstrip() arg = arg[colon + 1:].lstrip()
try: try:
lineno = int(arg) lineno = int(arg)
except ValueError: except ValueError:
@@ -1212,7 +1212,7 @@ class QtcInternalDumper:
# Make sure it works for 'clear C:\foo\bar.py:12' # Make sure it works for 'clear C:\foo\bar.py:12'
i = arg.rfind(':') i = arg.rfind(':')
filename = arg[:i] filename = arg[:i]
arg = arg[i+1:] arg = arg[i + 1:]
try: try:
lineno = int(arg) lineno = int(arg)
except ValueError: 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 utils import DisplayFormat
from dumper import Children, SubItem from dumper import Children, SubItem
def qform__std__array(): def qform__std__array():
return [DisplayFormat.ArrayPlotFormat] return [DisplayFormat.ArrayPlot]
def qdump__std__array(d, value): def qdump__std__array(d, value):
size = value.type[1] size = value.type[1]
@@ -37,7 +39,8 @@ def qdump__std__array(d, value):
def qform__std____1__array(): def qform__std____1__array():
return [DisplayFormat.ArrayPlotFormat] return [DisplayFormat.ArrayPlot]
def qdump__std____1__array(d, value): def qdump__std____1__array(d, value):
qdump__std__array(d, value) qdump__std__array(d, value)
@@ -66,6 +69,7 @@ def qdump__std__complex(d, value):
d.putSubItem("real", real) d.putSubItem("real", real)
d.putSubItem("imag", imag) d.putSubItem("imag", imag)
def qdump__std____1__complex(d, value): def qdump__std____1__complex(d, value):
qdump__std__complex(d, value) qdump__std__complex(d, value)
@@ -85,7 +89,7 @@ def qdump__std__deque(d, value):
bufsize = 512 // innerSize bufsize = 512 // innerSize
(mapptr, mapsize, startCur, startFirst, startLast, startNode, (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 = bufsize * ((finishNode - startNode) // d.ptrSize() - 1)
size += (finishCur - finishFirst) // innerSize size += (finishCur - finishFirst) // innerSize
@@ -108,6 +112,7 @@ def qdump__std__deque(d, value):
pcur = pfirst pcur = pfirst
pnode = newnode pnode = newnode
def qdump__std____1__deque(d, value): def qdump__std____1__deque(d, value):
mptr, mfirst, mbegin, mend, start, size = value.split("pppptt") mptr, mfirst, mbegin, mend, start, size = value.split("pppptt")
d.check(0 <= size and size <= 1000 * 1000 * 1000) 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) base = d.extractPointer(mfirst + k * ptrSize)
d.putSubItem(i, d.createValue(base + j * innerSize, innerType)) d.putSubItem(i, d.createValue(base + j * innerSize, innerType))
def qdump__std__deque__QNX(d, value): def qdump__std__deque__QNX(d, value):
innerType = value.type[0] innerType = value.type[0]
innerSize = innerType.size() innerSize = innerType.size()
@@ -157,7 +163,8 @@ def qdump__std__deque__QNX(d, value):
if mapsize <= block: if mapsize <= block:
block -= mapsize block -= mapsize
d.putSubItem(i, map[block][offset]) d.putSubItem(i, map[block][offset])
myoff += 1; myoff += 1
def qdump__std__deque__MSVC(d, value): def qdump__std__deque__MSVC(d, value):
innerType = value.type[0] innerType = value.type[0]
@@ -187,6 +194,7 @@ def qdump__std__deque__MSVC(d, value):
d.putSubItem(i, d.createValue(address, innerType)) d.putSubItem(i, d.createValue(address, innerType))
myoff += 1 myoff += 1
def qdump__std____debug__deque(d, value): def qdump__std____debug__deque(d, value):
qdump__std__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)) d.putSubItem(i, d.createValue(p + 2 * d.ptrSize(), innerType))
p = d.extractPointer(p) p = d.extractPointer(p)
def qdump__std__list__QNX(d, value): def qdump__std__list__QNX(d, value):
(proxy, head, size) = value.split("ppp") (proxy, head, size) = value.split("ppp")
d.putItemCount(size, 1000) 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)) d.putSubItem(i, d.createValue(p + 2 * d.ptrSize(), innerType))
p = d.extractPointer(p) p = d.extractPointer(p)
def qdump__std____debug__list(d, value): def qdump__std____debug__list(d, value):
qdump__std__list(d, value) qdump__std__list(d, value)
def qdump__std____cxx11__list(d, value): def qdump__std____cxx11__list(d, value):
qdump__std__list(d, value) qdump__std__list(d, value)
def qdump__std____1__list(d, value): def qdump__std____1__list(d, value):
if value.type.size() == 3 * d.ptrSize(): if value.type.size() == 3 * d.ptrSize():
# C++11 only. # C++11 only.
@@ -260,8 +272,10 @@ def qdump__std____1__list(d, value):
(prev, p, val) = d.split(typeCode, p) (prev, p, val) = d.split(typeCode, p)
d.putSubItem(i, val) d.putSubItem(i, val)
def qform__std__map(): def qform__std__map():
return [DisplayFormat.CompactMapFormat] return [DisplayFormat.CompactMap]
def qdump__std__map(d, value): def qdump__std__map(d, value):
if d.isQnxTarget() or d.isMsvcTarget(): 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/ # stuff is actually (color, pad) with 'I@', but we can save cycles/
(compare, stuff, parent, left, right, size) = value.split('pppppp') (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) d.putItemCount(size)
if d.isExpanded(): if d.isExpanded():
@@ -299,16 +313,19 @@ def qdump__std__map(d, value):
break break
node = node["_M_left"] node = node["_M_left"]
def qdump_std__map__helper(d, value): def qdump_std__map__helper(d, value):
(proxy, head, size) = value.split("ppp") (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) d.putItemCount(size)
if d.isExpanded(): if d.isExpanded():
keyType = value.type[0] keyType = value.type[0]
valueType = value.type[1] valueType = value.type[1]
pairType = value.type[3][0] pairType = value.type[3][0]
def helper(node): 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: if left != head:
for res in helper(left): for res in helper(left):
yield res yield res
@@ -322,24 +339,31 @@ def qdump_std__map__helper(d, value):
for (pair, i) in zip(helper(root), d.childRange()): for (pair, i) in zip(helper(root), d.childRange()):
d.putPairItem(i, pair) d.putPairItem(i, pair)
def qdump__std____debug__map(d, value): def qdump__std____debug__map(d, value):
qdump__std__map(d, value) qdump__std__map(d, value)
def qdump__std____debug__set(d, value): def qdump__std____debug__set(d, value):
qdump__std__set(d, value) qdump__std__set(d, value)
def qdump__std__multiset(d, value): def qdump__std__multiset(d, value):
qdump__std__set(d, value) qdump__std__set(d, value)
def qdump__std____cxx1998__map(d, value): def qdump__std____cxx1998__map(d, value):
qdump__std__map(d, value) qdump__std__map(d, value)
def qform__std__multimap(): def qform__std__multimap():
return [DisplayFormat.CompactMapFormat] return [DisplayFormat.CompactMap]
def qdump__std__multimap(d, value): def qdump__std__multimap(d, value):
return qdump__std__map(d, value) return qdump__std__map(d, value)
def qdumpHelper__std__tree__iterator(d, value, isSet=False): def qdumpHelper__std__tree__iterator(d, value, isSet=False):
treeTypeName = None treeTypeName = None
if value.type.name.endswith("::iterator"): 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("right", d.createValue(right, nodeType))
d.putSubItem("parent", d.createValue(parent, nodeType)) d.putSubItem("parent", d.createValue(parent, nodeType))
def qdump__std___Rb_tree_iterator(d, value): def qdump__std___Rb_tree_iterator(d, value):
qdumpHelper__std__tree__iterator(d, value) qdumpHelper__std__tree__iterator(d, value)
def qdump__std___Rb_tree_const_iterator(d, value): def qdump__std___Rb_tree_const_iterator(d, value):
qdumpHelper__std__tree__iterator(d, value) qdumpHelper__std__tree__iterator(d, value)
def qdump__std__map__iterator(d, value): def qdump__std__map__iterator(d, value):
qdumpHelper__std__tree__iterator(d, value) qdumpHelper__std__tree__iterator(d, value)
def qdump____gnu_debug___Safe_iterator(d, value): def qdump____gnu_debug___Safe_iterator(d, value):
d.putItem(value["_M_current"]) d.putItem(value["_M_current"])
def qdump__std__map__const_iterator(d, value): def qdump__std__map__const_iterator(d, value):
qdumpHelper__std__tree__iterator(d, value) qdumpHelper__std__tree__iterator(d, value)
def qdump__std__set__iterator(d, value): def qdump__std__set__iterator(d, value):
qdumpHelper__std__tree__iterator(d, value, True) qdumpHelper__std__tree__iterator(d, value, True)
def qdump__std__set__const_iterator(d, value): def qdump__std__set__const_iterator(d, value):
qdumpHelper__std__tree__iterator(d, value, True) qdumpHelper__std__tree__iterator(d, value, True)
def qdump__std____cxx1998__set(d, value): def qdump__std____cxx1998__set(d, value):
qdump__std__set(d, value) qdump__std__set(d, value)
def qdumpHelper__std__tree__iterator_MSVC(d, value): def qdumpHelper__std__tree__iterator_MSVC(d, value):
d.putNumChild(1) d.putNumChild(1)
d.putEmptyValue() d.putEmptyValue()
@@ -416,9 +449,11 @@ def qdumpHelper__std__tree__iterator_MSVC(d, value):
else: else:
d.putSubItem("value", child) d.putSubItem("value", child)
def qdump__std___Tree_const_iterator(d, value): def qdump__std___Tree_const_iterator(d, value):
qdumpHelper__std__tree__iterator_MSVC(d, value) qdumpHelper__std__tree__iterator_MSVC(d, value)
def qdump__std___Tree_iterator(d, value): def qdump__std___Tree_iterator(d, value):
qdumpHelper__std__tree__iterator_MSVC(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"] impl = value["_M_t"]["_M_impl"]
size = impl["_M_node_count"].integer() 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) d.putItemCount(size)
if d.isExpanded(): if d.isExpanded():
valueType = value.type[0] valueType = value.type[0]
@@ -453,14 +488,17 @@ def qdump__std__set(d, value):
while node["_M_left"].pointer() != 0: while node["_M_left"].pointer() != 0:
node = node["_M_left"] node = node["_M_left"]
def qdump__std__set__QNX(d, value): def qdump__std__set__QNX(d, value):
(proxy, head, size) = value.split("ppp") (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) d.putItemCount(size)
if d.isExpanded(): if d.isExpanded():
childType=value.type[0] childType = value.type[0]
def helper(node): 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: if left != head:
for res in helper(left): for res in helper(left):
yield res yield res
@@ -474,6 +512,7 @@ def qdump__std__set__QNX(d, value):
for (item, i) in zip(helper(root), d.childRange()): for (item, i) in zip(helper(root), d.childRange()):
d.putSubItem(i, item) d.putSubItem(i, item)
def std1TreeMin(d, node): def std1TreeMin(d, node):
#_NodePtr __tree_min(_NodePtr __x): #_NodePtr __tree_min(_NodePtr __x):
# while (__x->__left_ != nullptr) # while (__x->__left_ != nullptr)
@@ -485,6 +524,7 @@ def std1TreeMin(d, node):
node = left node = left
return node return node
def std1TreeIsLeftChild(d, node): def std1TreeIsLeftChild(d, node):
# bool __tree_is_left_child(_NodePtr __x): # bool __tree_is_left_child(_NodePtr __x):
# return __x == __x->__parent_->__left_; # return __x == __x->__parent_->__left_;
@@ -508,10 +548,11 @@ def std1TreeNext(d, node):
node = node['__parent_'] node = node['__parent_']
return node['__parent_'] return node['__parent_']
def qdump__std____1__set(d, value): def qdump__std____1__set(d, value):
(proxy, head, size) = value.split("ppp") (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) d.putItemCount(size)
if d.isExpanded(): 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)): for (i, data) in zip(d.childRange(), in_order_traversal(head)):
d.putSubItem(i, data) d.putSubItem(i, data)
def qdump__std____1__multiset(d, value): def qdump__std____1__multiset(d, value):
qdump__std____1__set(d, value) qdump__std____1__set(d, value)
def qform__std____1__map(): def qform__std____1__map():
return [DisplayFormat.CompactMapFormat] return [DisplayFormat.CompactMap]
def qdump__std____1__map(d, value): def qdump__std____1__map(d, value):
try: try:
(proxy, head, size) = value.split("ppp") (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. # Sometimes there is extra data at the front. Don't know why at the moment.
except RuntimeError: except RuntimeError:
(junk, proxy, head, size) = value.split("pppp") (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) 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)): for (i, pair) in zip(d.childRange(), in_order_traversal(head)):
d.putPairItem(i, pair, 'key', 'value') d.putPairItem(i, pair, 'key', 'value')
def qform__std____1__multimap(): def qform__std____1__multimap():
return [DisplayFormat.CompactMapFormat] return [DisplayFormat.CompactMap]
def qdump__std____1__multimap(d, value): def qdump__std____1__multimap(d, value):
qdump__std____1__map(d, value) qdump__std____1__map(d, value)
def qdump__std____1__map__iterator(d, value): def qdump__std____1__map__iterator(d, value):
d.putEmptyValue() d.putEmptyValue()
if d.isExpanded(): if d.isExpanded():
@@ -588,9 +635,11 @@ def qdump__std____1__map__iterator(d, value):
d.putSubItem('first', node['first']) d.putSubItem('first', node['first'])
d.putSubItem('second', node['second']) d.putSubItem('second', node['second'])
def qdump__std____1__map__const_iterator(d, value): def qdump__std____1__map__const_iterator(d, value):
qdump__std____1__map__iterator(d, value) qdump__std____1__map__iterator(d, value)
def qdump__std____1__set__iterator(d, value): def qdump__std____1__set__iterator(d, value):
d.putEmptyValue() d.putEmptyValue()
d.putNumChild(1) d.putNumChild(1)
@@ -606,27 +655,34 @@ def qdump__std____1__set__iterator(d, value):
node = node.cast(keyType) node = node.cast(keyType)
d.putSubItem('value', node) d.putSubItem('value', node)
def qdump__std____1__set_const_iterator(d, value): def qdump__std____1__set_const_iterator(d, value):
qdump__std____1__set__iterator(d, value) qdump__std____1__set__iterator(d, value)
def qdump__std__stack(d, value): def qdump__std__stack(d, value):
d.putItem(value["c"]) d.putItem(value["c"])
d.putBetterType(value.type) d.putBetterType(value.type)
def qdump__std____debug__stack(d, value): def qdump__std____debug__stack(d, value):
qdump__std__stack(d, value) qdump__std__stack(d, value)
def qdump__std____1__stack(d, value): def qdump__std____1__stack(d, value):
d.putItem(value["c"]) d.putItem(value["c"])
d.putBetterType(value.type) d.putBetterType(value.type)
def qform__std__string(): def qform__std__string():
return [DisplayFormat.Latin1StringFormat, DisplayFormat.SeparateLatin1StringFormat, return [DisplayFormat.Latin1String, DisplayFormat.SeparateLatin1String,
DisplayFormat.Utf8StringFormat, DisplayFormat.SeparateUtf8StringFormat ] DisplayFormat.Utf8String, DisplayFormat.SeparateUtf8String]
def qdump__std__string(d, value): def qdump__std__string(d, value):
qdumpHelper_std__string(d, value, d.createType("char"), d.currentItemFormat()) qdumpHelper_std__string(d, value, d.createType("char"), d.currentItemFormat())
def qdumpHelper_std__string(d, value, charType, format): def qdumpHelper_std__string(d, value, charType, format):
if d.isQnxTarget(): if d.isQnxTarget():
qdumpHelper__std__string__QNX(d, value, charType, format) 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; } # struct { size_type _M_length, size_type _M_capacity, int _M_refcount; }
(size, alloc, refcount) = d.split("ppp", data - 3 * d.ptrSize()) (size, alloc, refcount) = d.split("ppp", data - 3 * d.ptrSize())
refcount = refcount & 0xffffffff refcount = refcount & 0xffffffff
d.check(refcount >= -1) # Can be -1 according to docs. d.check(refcount >= -1) # Can be -1 according to docs.
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, charType, format) d.putCharArrayHelper(data, size, charType, format)
def qdumpHelper__std__string__QNX(d, value, charType, format): def qdumpHelper__std__string__QNX(d, value, charType, format):
size = value['_Mysize'] size = value['_Mysize']
alloc = value['_Myres'] alloc = value['_Myres']
_BUF_SIZE = int(16 / charType.size()) _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'] data = value['_Bx']['_Ptr']
else: else:
data = value['_Bx']['_Buf'] data = value['_Bx']['_Buf']
sizePtr = data.cast(d.charType().pointer()) sizePtr = data.cast(d.charType().pointer())
refcount = int(sizePtr[-1]) refcount = int(sizePtr[-1])
d.check(refcount >= -1) # Can be -1 accoring to docs. d.check(refcount >= -1) # Can be -1 accoring to docs.
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(sizePtr, size, charType, format) d.putCharArrayHelper(sizePtr, size, charType, format)
def qdumpHelper__std__string__MSVC(d, value, charType, format): def qdumpHelper__std__string__MSVC(d, value, charType, format):
(proxy, buffer, size, alloc) = value.split("p16spp"); (proxy, buffer, size, alloc) = value.split("p16spp")
_BUF_SIZE = int(16 / charType.size()); _BUF_SIZE = int(16 / charType.size())
d.check(0 <= size and size <= alloc and alloc <= 100*1000*1000) d.check(0 <= size and size <= alloc and alloc <= 100 * 1000 * 1000)
if _BUF_SIZE <= alloc: if _BUF_SIZE <= alloc:
(proxy, data) = value.split("pp"); (proxy, data) = value.split("pp")
else: else:
data = value.address() + d.ptrSize() data = value.address() + d.ptrSize()
d.putCharArrayHelper(data, size, charType, format) d.putCharArrayHelper(data, size, charType, format)
def qdump__std____1__string(d, value): def qdump__std____1__string(d, value):
firstByte = value.split('b')[0] firstByte = value.split('b')[0]
if int(firstByte & 1) == 0: if int(firstByte & 1) == 0:
@@ -707,9 +766,11 @@ def qdump__std____1__wstring(d, value):
def qdump__std____weak_ptr(d, value): def qdump__std____weak_ptr(d, value):
return qdump__std__shared_ptr(d, value) return qdump__std__shared_ptr(d, value)
def qdump__std__weak_ptr(d, value): def qdump__std__weak_ptr(d, value):
return qdump__std__shared_ptr(d, value) return qdump__std__shared_ptr(d, value)
def qdump__std____1__weak_ptr(d, value): def qdump__std____1__weak_ptr(d, value):
return qdump__std____1__shared_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.putItem(i.dereference())
d.putBetterType(value.type) d.putBetterType(value.type)
def qdump__std____1__shared_ptr(d, value): def qdump__std____1__shared_ptr(d, value):
i = value["__ptr_"] i = value["__ptr_"]
if i.pointer() == 0: if i.pointer() == 0:
@@ -736,6 +798,7 @@ def qdump__std____1__shared_ptr(d, value):
d.putItem(i.dereference()) d.putItem(i.dereference())
d.putBetterType(value.type) d.putBetterType(value.type)
def qdump__std__unique_ptr(d, value): def qdump__std__unique_ptr(d, value):
p = d.extractPointer(value) p = d.extractPointer(value)
if p == 0: if p == 0:
@@ -745,6 +808,7 @@ def qdump__std__unique_ptr(d, value):
d.putItem(d.createValue(p, value.type[0])) d.putItem(d.createValue(p, value.type[0]))
d.putBetterType(value.type) d.putBetterType(value.type)
def qdump__std____1__unique_ptr(d, value): def qdump__std____1__unique_ptr(d, value):
qdump__std__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.putField('keyencoded', key.encoding)
d.putValue(value.value, value.encoding) d.putValue(value.value, value.encoding)
def qform__std__unordered_map(): def qform__std__unordered_map():
return [DisplayFormat.CompactMapFormat] return [DisplayFormat.CompactMap]
def qform__std____debug__unordered_map(): def qform__std____debug__unordered_map():
return [DisplayFormat.CompactMapFormat] return [DisplayFormat.CompactMap]
def qdump__std__unordered_map(d, value): def qdump__std__unordered_map(d, value):
if d.isQnxTarget() or d.isMsvcTarget(): 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) p, pad, key, pad, val = d.split(typeCode, p)
d.putPairItem(i, (key, val)) d.putPairItem(i, (key, val))
def qdump__std____debug__unordered_map(d, value): def qdump__std____debug__unordered_map(d, value):
qdump__std__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(): def qform__std__unordered_multimap():
return qform__std__unordered_map() return qform__std__unordered_map()
def qform__std____debug__unordered_multimap(): def qform__std____debug__unordered_multimap():
return qform__std____debug__unordered_map() return qform__std____debug__unordered_map()
def qdump__std__unordered_multimap(d, value): def qdump__std__unordered_multimap(d, value):
qdump__std__unordered_map(d, value) qdump__std__unordered_map(d, value)
def qdump__std____debug__unordered_multimap(d, value): def qdump__std____debug__unordered_multimap(d, value):
qdump__std__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)) d.putSubItem(i, d.createValue(p + ptrSize - offset, valueType))
p = d.extractPointer(p + offset) p = d.extractPointer(p + offset)
def qform__std____1__unordered_map(): def qform__std____1__unordered_map():
return [DisplayFormat.CompactMapFormat] return [DisplayFormat.CompactMap]
def qdump__std____1__unordered_map(d, value): def qdump__std____1__unordered_map(d, value):
(size, _) = value["__table_"]["__p2_"].split("pp") (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): def qdump__std____debug__unordered_set(d, value):
qdump__std__unordered_set(d, value) qdump__std__unordered_set(d, value)
def qdump__std__unordered_multiset(d, value): def qdump__std__unordered_multiset(d, value):
qdump__std__unordered_set(d, value) qdump__std__unordered_set(d, value)
def qdump__std____debug__unordered_multiset(d, value): def qdump__std____debug__unordered_multiset(d, value):
qdump__std__unordered_multiset(d, value) qdump__std__unordered_multiset(d, value)
def qform__std__valarray(): def qform__std__valarray():
return [DisplayFormat.ArrayPlotFormat] return [DisplayFormat.ArrayPlot]
def qdump__std__valarray(d, value): def qdump__std__valarray(d, value):
if d.isMsvcTarget(): if d.isMsvcTarget():
@@ -929,7 +1005,8 @@ def qdump__std__valarray(d, value):
def qform__std____1__valarray(): def qform__std____1__valarray():
return [DisplayFormat.ArrayPlotFormat] return [DisplayFormat.ArrayPlot]
def qdump__std____1__valarray(d, value): def qdump__std____1__valarray(d, value):
innerType = value.type[0] innerType = value.type[0]
@@ -940,7 +1017,8 @@ def qdump__std____1__valarray(d, value):
def qform__std__vector(): def qform__std__vector():
return [DisplayFormat.ArrayPlotFormat] return [DisplayFormat.ArrayPlot]
def qedit__std__vector(d, value, data): def qedit__std__vector(d, value, data):
import gdb import gdb
@@ -954,12 +1032,14 @@ def qedit__std__vector(d, value, data):
cmd = "set (%s[%d])*$d={%s}" % (innerType, n, data) cmd = "set (%s[%d])*$d={%s}" % (innerType, n, data)
gdb.execute(cmd) gdb.execute(cmd)
def qdump__std__vector(d, value): def qdump__std__vector(d, value):
if d.isQnxTarget() or d.isMsvcTarget(): if d.isQnxTarget() or d.isMsvcTarget():
qdumpHelper__std__vector__QNX(d, value) qdumpHelper__std__vector__QNX(d, value)
else: else:
qdumpHelper__std__vector(d, value, False) qdumpHelper__std__vector(d, value, False)
def qdumpHelper__std__vector(d, value, isLibCpp): def qdumpHelper__std__vector(d, value, isLibCpp):
innerType = value.type[0] innerType = value.type[0]
isBool = innerType.name == 'bool' isBool = innerType.name == 'bool'
@@ -975,7 +1055,7 @@ def qdumpHelper__std__vector(d, value, isLibCpp):
finish = value["_M_finish"]["_M_p"].pointer() finish = value["_M_finish"]["_M_p"].pointer()
foffset = value["_M_finish"]["_M_offset"].integer() foffset = value["_M_finish"]["_M_offset"].integer()
alloc = value["_M_end_of_storage"].pointer() 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: else:
if isLibCpp: if isLibCpp:
start = value["__begin_"].pointer() start = value["__begin_"].pointer()
@@ -1007,6 +1087,7 @@ def qdumpHelper__std__vector(d, value, isLibCpp):
else: else:
d.putPlotData(start, size, innerType) d.putPlotData(start, size, innerType)
def qdumpHelper__std__vector__QNX(d, value): def qdumpHelper__std__vector__QNX(d, value):
innerType = value.type[0] innerType = value.type[0]
isBool = innerType.name == 'bool' isBool = innerType.name == 'bool'
@@ -1036,14 +1117,18 @@ def qdumpHelper__std__vector__QNX(d, value):
else: else:
d.putPlotData(start, size, innerType) d.putPlotData(start, size, innerType)
def qform__std____1__vector(): def qform__std____1__vector():
return [DisplayFormat.ArrayPlotFormat] return [DisplayFormat.ArrayPlot]
def qdump__std____1__vector(d, value): def qdump__std____1__vector(d, value):
qdumpHelper__std__vector(d, value, True) qdumpHelper__std__vector(d, value, True)
def qform__std____debug__vector(): def qform__std____debug__vector():
return [DisplayFormat.ArrayPlotFormat] return [DisplayFormat.ArrayPlot]
def qdump__std____debug__vector(d, value): def qdump__std____debug__vector(d, value):
qdump__std__vector(d, value) qdump__std__vector(d, value)
@@ -1067,37 +1152,48 @@ def qdump__std__initializer_list(d, value):
if d.isExpanded(): if d.isExpanded():
d.putPlotData(start, size, innerType) d.putPlotData(start, size, innerType)
def qedit__std__string(d, value, data): def qedit__std__string(d, value, data):
d.call('void', value, 'assign', '"%s"' % data.replace('"', '\\"')) d.call('void', value, 'assign', '"%s"' % data.replace('"', '\\"'))
def qedit__string(d, expr, value): def qedit__string(d, expr, value):
qedit__std__string(d, expr, value) qedit__std__string(d, expr, value)
def qedit__std____cxx11__string(d, expr, value): def qedit__std____cxx11__string(d, expr, value):
qedit__std__string(d, expr, value) qedit__std__string(d, expr, value)
def qedit__std__wstring(d, value, data): def qedit__std__wstring(d, value, data):
d.call('void', value, 'assign', 'L"%s"' % data.replace('"', '\\"')) d.call('void', value, 'assign', 'L"%s"' % data.replace('"', '\\"'))
def qedit__wstring(d, expr, value): def qedit__wstring(d, expr, value):
qedit__std__wstring(d, expr, value) qedit__std__wstring(d, expr, value)
def qedit__std____cxx11__wstring(d, expr, value): def qedit__std____cxx11__wstring(d, expr, value):
qedit__std__wstring(d, expr, value) qedit__std__wstring(d, expr, value)
def qdump__string(d, value): def qdump__string(d, value):
qdump__std__string(d, value) qdump__std__string(d, value)
def qform__std__wstring(): def qform__std__wstring():
return [DisplayFormat.SimpleFormat, DisplayFormat.SeparateFormat] return [DisplayFormat.Simple, DisplayFormat.Separate]
def qdump__std__wstring(d, value): def qdump__std__wstring(d, value):
qdumpHelper_std__string(d, value, d.createType('wchar_t'), d.currentItemFormat()) qdumpHelper_std__string(d, value, d.createType('wchar_t'), d.currentItemFormat())
def qdump__std__basic_string(d, value): def qdump__std__basic_string(d, value):
innerType = value.type[0] innerType = value.type[0]
qdumpHelper_std__string(d, value, innerType, d.currentItemFormat()) qdumpHelper_std__string(d, value, innerType, d.currentItemFormat())
def qdump__std____cxx11__basic_string(d, value): def qdump__std____cxx11__basic_string(d, value):
innerType = value.type[0] innerType = value.type[0]
try: try:
@@ -1107,24 +1203,30 @@ def qdump__std____cxx11__basic_string(d, value):
d.putEmptyValue() d.putEmptyValue()
d.putPlainChildren(value) d.putPlainChildren(value)
return 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()) d.putCharArrayHelper(data, size, innerType, d.currentItemFormat())
def qform__std____cxx11__string(d, value): def qform__std____cxx11__string(d, value):
qform__std__string(d, value) qform__std__string(d, value)
def qdump__std____cxx11__string(d, value): def qdump__std____cxx11__string(d, value):
(data, size) = value.split("pI") (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()) d.putCharArrayHelper(data, size, d.charType(), d.currentItemFormat())
# Needed only to trigger the form report above. # Needed only to trigger the form report above.
def qform__std____cxx11__string(): def qform__std____cxx11__string():
return qform__std__string() return qform__std__string()
def qform__std____cxx11__wstring(): def qform__std____cxx11__wstring():
return qform__std__wstring() return qform__std__wstring()
def qdump__std____1__basic_string(d, value): def qdump__std____1__basic_string(d, value):
innerType = value.type[0].name innerType = value.type[0].name
if innerType == "char": if innerType == "char":
@@ -1134,12 +1236,15 @@ def qdump__std____1__basic_string(d, value):
else: else:
d.warn("UNKNOWN INNER TYPE %s" % innerType) d.warn("UNKNOWN INNER TYPE %s" % innerType)
def qdump__wstring(d, value): def qdump__wstring(d, value):
qdump__std__wstring(d, value) qdump__std__wstring(d, value)
def qdump__std____1__once_flag(d, value): def qdump__std____1__once_flag(d, value):
qdump__std__once_flag(d, value) qdump__std__once_flag(d, value)
def qdump__std__once_flag(d, value): def qdump__std__once_flag(d, value):
d.putValue(value.split("i")[0]) d.putValue(value.split("i")[0])
d.putBetterType(value.type) d.putBetterType(value.type)
@@ -1174,14 +1279,17 @@ def qdump__uint8_t(d, value):
d.putNumChild(0) d.putNumChild(0)
d.putValue(value.integer()) d.putValue(value.integer())
def qdump__int8_t(d, value): def qdump__int8_t(d, value):
d.putNumChild(0) d.putNumChild(0)
d.putValue(value.integer()) d.putValue(value.integer())
def qdump__std__byte(d, value): def qdump__std__byte(d, value):
d.putNumChild(0) d.putNumChild(0)
d.putValue(value.integer()) d.putValue(value.integer())
def qdump__std__optional(d, value): def qdump__std__optional(d, value):
innerType = value.type[0] innerType = value.type[0]
(payload, pad, initialized) = d.split('{%s}@b' % innerType.name, value) (payload, pad, initialized) = d.split('{%s}@b' % innerType.name, value)
@@ -1192,5 +1300,6 @@ def qdump__std__optional(d, value):
d.putSpecialValue("uninitialized") d.putSpecialValue("uninitialized")
d.putNumChild(0) d.putNumChild(0)
def qdump__std__experimental__optional(d, value): def qdump__std__experimental__optional(d, value):
qdump__std__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 # Debugger start modes. Keep in sync with DebuggerStartMode in debuggerconstants.h
class DebuggerStartMode: class DebuggerStartMode():
( (
NoStartMode, NoStartMode,
StartInternal, StartInternal,
@@ -41,33 +41,33 @@ class DebuggerStartMode:
# Known special formats. Keep in sync with DisplayFormat in debuggerprotocol.h # Known special formats. Keep in sync with DisplayFormat in debuggerprotocol.h
class DisplayFormat: class DisplayFormat():
( (
AutomaticFormat, Automatic,
RawFormat, Raw,
SimpleFormat, Simple,
EnhancedFormat, Enhanced,
SeparateFormat, Separate,
Latin1StringFormat, Latin1String,
SeparateLatin1StringFormat, SeparateLatin1String,
Utf8StringFormat, Utf8String,
SeparateUtf8StringFormat, SeparateUtf8String,
Local8BitStringFormat, Local8BitString,
Utf16StringFormat, Utf16String,
Ucs4StringFormat, Ucs4String,
Array10Format, Array10,
Array100Format, Array100,
Array1000Format, Array1000,
Array10000Format, Array10000,
ArrayPlotFormat, ArrayPlot,
CompactMapFormat, CompactMap,
DirectQListStorageFormat, DirectQListStorage,
IndirectQListStorageFormat, IndirectQListStorage,
) = range(0, 20) ) = range(0, 20)
# Breakpoints. Keep synchronized with BreakpointType in breakpoint.h # Breakpoints. Keep synchronized with BreakpointType in breakpoint.h
class BreakpointType: class BreakpointType():
( (
UnknownType, UnknownType,
BreakpointByFileAndLine, BreakpointByFileAndLine,
@@ -87,24 +87,24 @@ class BreakpointType:
# Internal codes for types keep in sync with cdbextensions pytype.cpp # Internal codes for types keep in sync with cdbextensions pytype.cpp
class TypeCode: class TypeCode():
( (
TypeCodeTypedef, Typedef,
TypeCodeStruct, Struct,
TypeCodeVoid, Void,
TypeCodeIntegral, Integral,
TypeCodeFloat, Float,
TypeCodeEnum, Enum,
TypeCodePointer, Pointer,
TypeCodeArray, Array,
TypeCodeComplex, Complex,
TypeCodeReference, Reference,
TypeCodeFunction, Function,
TypeCodeMemberPointer, MemberPointer,
TypeCodeFortranString, FortranString,
TypeCodeUnresolvable, Unresolvable,
TypeCodeBitfield, Bitfield,
TypeCodeRValueReference, RValueReference,
) = range(0, 16) ) = range(0, 16)

View File

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

View File

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

View File

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

View File

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

View File

@@ -24,7 +24,7 @@
****************************************************************************/ ****************************************************************************/
import QtQuick 2.0 import QtQuick 2.0
import QtQuick3D 1.0 import QtQuick3D 1.15
Node { Node {
id: armRoot 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 QtQuick 2.0
import QtQuick3D 1.0
import CameraGeometry 1.0
IconGizmo { IconGizmo {
id: cameraGizmo id: cameraGizmo
property var frustumModel: null
iconSource: "qrc:///qtquickplugin/mockfiles/images/editor_camera.png" 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: { onActiveSceneChanged: {
if (activeScene == scene) if (frustumModel && activeScene == scene)
cameraGeometry.update(); frustumModel.updateGeometry();
}
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
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

@@ -24,10 +24,10 @@
****************************************************************************/ ****************************************************************************/
import QtQuick 2.0 import QtQuick 2.0
import QtQuick3D 1.0 import QtQuick3D 1.15
import QtGraphicalEffects 1.12 import QtGraphicalEffects 1.12
Node { Item {
id: iconGizmo id: iconGizmo
property Node activeScene: null property Node activeScene: null
@@ -50,16 +50,13 @@ Node {
signal positionCommit() signal positionCommit()
signal clicked(Node node, bool multi) 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) visible: activeScene === scene && (targetNode ? targetNode.visible : false)
Overlay2D { Overlay2D {
id: iconOverlay id: iconOverlay
targetNode: iconGizmo targetNode: iconGizmo.targetNode
targetView: view3D targetView: view3D
visible: iconGizmo.visible && !isBehindCamera visible: iconGizmo.visible && !isBehindCamera
parent: view3D
Rectangle { Rectangle {
id: iconRect id: iconRect

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -24,7 +24,7 @@
****************************************************************************/ ****************************************************************************/
import QtQuick 2.0 import QtQuick 2.0
import QtQuick3D 1.0 import QtQuick3D 1.15
import MouseArea3D 1.0 import MouseArea3D 1.0
Node { Node {
@@ -41,13 +41,13 @@ Node {
property point currentMousePos property point currentMousePos
position: dragHelper.pivotScenePosition(targetNode) position: dragHelper.pivotScenePosition(targetNode)
orientation: targetNode ? targetNode.orientation : Node.LeftHanded
onTargetNodeChanged: position = dragHelper.pivotScenePosition(targetNode) onTargetNodeChanged: position = dragHelper.pivotScenePosition(targetNode)
Connections { Connections {
target: rotateGizmo.targetNode target: rotateGizmo.targetNode
onSceneTransformChanged: { function onSceneTransformChanged()
{
rotateGizmo.position = rotateGizmo.dragHelper.pivotScenePosition(rotateGizmo.targetNode); rotateGizmo.position = rotateGizmo.dragHelper.pivotScenePosition(rotateGizmo.targetNode);
} }
} }
@@ -70,44 +70,16 @@ Node {
copyRingProperties(rotRingZ) 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 { Node {
id: rotNode id: rotNode
rotation: globalOrientation || !rotateGizmo.targetNode ? Qt.vector3d(0, 0, 0) rotation: globalOrientation || !rotateGizmo.targetNode ? Qt.quaternion(1, 0, 0, 0)
: rotateGizmo.targetNode.sceneRotation : rotateGizmo.targetNode.sceneRotation
rotationOrder: rotateGizmo.targetNode ? rotateGizmo.targetNode.rotationOrder : Node.YXZ
orientation: rotateGizmo.orientation
visible: !rotateGizmo.dragging && !freeRotator.dragging visible: !rotateGizmo.dragging && !freeRotator.dragging
RotateRing { RotateRing {
id: rotRingX id: rotRingX
objectName: "Rotate Ring X" objectName: "Rotate Ring X"
rotation: Qt.vector3d(0, 90, 0) eulerRotation: Qt.vector3d(0, 90, 0)
targetNode: rotateGizmo.targetNode targetNode: rotateGizmo.targetNode
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(1, 0, 0, 1)) color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(1, 0, 0, 1))
: Qt.rgba(1, 0, 0, 1) : Qt.rgba(1, 0, 0, 1)
@@ -125,7 +97,7 @@ Node {
RotateRing { RotateRing {
id: rotRingY id: rotRingY
objectName: "Rotate Ring Y" objectName: "Rotate Ring Y"
rotation: Qt.vector3d(90, 0, 0) eulerRotation: Qt.vector3d(90, 0, 0)
targetNode: rotateGizmo.targetNode targetNode: rotateGizmo.targetNode
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0.6, 0, 1)) color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0.6, 0, 1))
: Qt.rgba(0, 0.6, 0, 1) : Qt.rgba(0, 0.6, 0, 1)
@@ -145,7 +117,7 @@ Node {
RotateRing { RotateRing {
id: rotRingZ id: rotRingZ
objectName: "Rotate Ring Z" objectName: "Rotate Ring Z"
rotation: Qt.vector3d(0, 0, 0) eulerRotation: Qt.vector3d(0, 0, 0)
targetNode: rotateGizmo.targetNode targetNode: rotateGizmo.targetNode
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0, 1, 1)) color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0, 1, 1))
: Qt.rgba(0, 0, 1, 1) : Qt.rgba(0, 0, 1, 1)
@@ -174,7 +146,6 @@ Node {
view3D: rotateGizmo.view3D view3D: rotateGizmo.view3D
active: false active: false
visible: rotRingX.dragging || rotRingY.dragging || rotRingZ.dragging visible: rotRingX.dragging || rotRingY.dragging || rotRingZ.dragging
orientation: rotateGizmo.orientation
} }
RotateRing { 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 // 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 // scenePosition, which is read-only property
var scenePos = rotateGizmo.dragHelper.pivotScenePosition(rotateGizmo.targetNode); var scenePos = rotateGizmo.dragHelper.pivotScenePosition(rotateGizmo.targetNode);
if (rotateGizmo.targetNode && rotateGizmo.targetNode.orientation === Node.RightHanded)
scenePos.z = -scenePos.z
_targetPosOnScreen = view3D.mapFrom3DScene(scenePos); _targetPosOnScreen = view3D.mapFrom3DScene(scenePos);
_targetPosOnScreen.z = 0; _targetPosOnScreen.z = 0;
_pointerPosPressed = Qt.vector3d(screenPos.x, screenPos.y, 0); _pointerPosPressed = Qt.vector3d(screenPos.x, screenPos.y, 0);
// Recreate vector so we don't follow the changes in targetNode.rotation // Recreate vector so we don't follow the changes in targetNode.rotation
_startRotation = Qt.vector3d(rotateGizmo.targetNode.rotation.x, _startRotation = Qt.vector3d(rotateGizmo.targetNode.eulerRotation.x,
rotateGizmo.targetNode.rotation.y, rotateGizmo.targetNode.eulerRotation.y,
rotateGizmo.targetNode.rotation.z); rotateGizmo.targetNode.eulerRotation.z);
dragging = true; dragging = true;
} }

View File

@@ -24,7 +24,7 @@
****************************************************************************/ ****************************************************************************/
import QtQuick 2.0 import QtQuick 2.0
import QtQuick3D 1.0 import QtQuick3D 1.15
import MouseArea3D 1.0 import MouseArea3D 1.0
Model { 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 // 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 // scenePosition, which is read-only property
var scenePos = mouseAreaMain.pivotScenePosition(targetNode); var scenePos = mouseAreaMain.pivotScenePosition(targetNode);
if (targetNode && targetNode.orientation === Node.RightHanded)
scenePos.z = -scenePos.z
_targetPosOnScreen = view3D.mapFrom3DScene(scenePos); _targetPosOnScreen = view3D.mapFrom3DScene(scenePos);
_targetPosOnScreen.z = 0; _targetPosOnScreen.z = 0;
_pointerPosPressed = Qt.vector3d(screenPos.x, screenPos.y, 0); _pointerPosPressed = Qt.vector3d(screenPos.x, screenPos.y, 0);
_trackBall = angle < 0.1; _trackBall = angle < 0.1;
// Recreate vector so we don't follow the changes in targetNode.rotation // Recreate vector so we don't follow the changes in targetNode.eulerRotation
_startRotation = Qt.vector3d(targetNode.rotation.x, _startRotation = Qt.vector3d(targetNode.eulerRotation.x,
targetNode.rotation.y, targetNode.eulerRotation.y,
targetNode.rotation.z); targetNode.eulerRotation.z);
currentAngle = 0; currentAngle = 0;
currentMousePos = screenPos; currentMousePos = screenPos;
} }

View File

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

View File

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

View File

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

View File

@@ -24,7 +24,7 @@
****************************************************************************/ ****************************************************************************/
import QtQuick 2.0 import QtQuick 2.0
import QtQuick3D 1.0 import QtQuick3D 1.15
import SelectionBoxGeometry 1.0 import SelectionBoxGeometry 1.0
Node { Node {
@@ -48,11 +48,9 @@ Node {
geometry: selectionBoxGeometry geometry: selectionBoxGeometry
scale: selectionBox.targetNode ? selectionBox.targetNode.scale : Qt.vector3d(1, 1, 1) 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) position: selectionBox.targetNode ? selectionBox.targetNode.position : Qt.vector3d(0, 0, 0)
pivot: selectionBox.targetNode ? selectionBox.targetNode.pivot : 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 visible: selectionBox.targetNode && !selectionBoxGeometry.isEmpty

View File

@@ -28,9 +28,9 @@
#include "selectionboxgeometry.h" #include "selectionboxgeometry.h"
#include <QtQuick3D/qquick3dobject.h>
#include <QtQuick3D/private/qquick3dorthographiccamera_p.h> #include <QtQuick3D/private/qquick3dorthographiccamera_p.h>
#include <QtQuick3D/private/qquick3dperspectivecamera_p.h> #include <QtQuick3D/private/qquick3dperspectivecamera_p.h>
#include <QtQuick3D/private/qquick3dobject_p_p.h>
#include <QtQuick3D/private/qquick3dcamera_p.h> #include <QtQuick3D/private/qquick3dcamera_p.h>
#include <QtQuick3D/private/qquick3dnode_p.h> #include <QtQuick3D/private/qquick3dnode_p.h>
#include <QtQuick3D/private/qquick3dmodel_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) if (dragVector.length() < 0.001f)
return; return;
camera->setRotation(startRotation); camera->setEulerRotation(startRotation);
QVector3D newRotation(dragVector.y(), dragVector.x(), 0.f); QVector3D newRotation(-dragVector.y(), -dragVector.x(), 0.f);
newRotation *= 0.5f; // Emprically determined multiplier for nice drag newRotation *= 0.5f; // Emprically determined multiplier for nice drag
newRotation += startRotation; newRotation += startRotation;
camera->setRotation(newRotation); camera->setEulerRotation(newRotation);
const QVector3D oldLookVector = camera->position() - lookAtPoint; const QVector3D oldLookVector = camera->position() - lookAtPoint;
QMatrix4x4 m = camera->sceneTransform(); QMatrix4x4 m = camera->sceneTransform();
const float *dataPtr(m.data()); const float *dataPtr(m.data());
QVector3D newLookVector(-dataPtr[8], -dataPtr[9], -dataPtr[10]); QVector3D newLookVector(dataPtr[8], dataPtr[9], dataPtr[10]);
newLookVector.normalize(); newLookVector.normalize();
newLookVector *= oldLookVector.length(); 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 // Adjust lookAt to look directly at the center of the object bounds
lookAt = renderModel->globalTransform.map(center); 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 // Reset camera position to default zoom
QMatrix4x4 m = camera->sceneTransform(); QMatrix4x4 m = camera->sceneTransform();
const float *dataPtr(m.data()); const float *dataPtr(m.data());
QVector3D newLookVector(-dataPtr[8], -dataPtr[9], -dataPtr[10]); QVector3D newLookVector(dataPtr[8], dataPtr[9], dataPtr[10]);
newLookVector.normalize(); newLookVector.normalize();
newLookVector *= defaultLookAtDistance; newLookVector *= defaultLookAtDistance;

View File

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

View File

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

View File

@@ -32,7 +32,7 @@
#include <QtQuick3DRuntimeRender/private/qssgrendercontextcore_p.h> #include <QtQuick3DRuntimeRender/private/qssgrendercontextcore_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrenderbuffermanager_p.h> #include <QtQuick3DRuntimeRender/private/qssgrenderbuffermanager_p.h>
#include <QtQuick3D/private/qquick3dmodel_p.h> #include <QtQuick3D/private/qquick3dmodel_p.h>
#include <QtQuick3D/private/qquick3dobject_p_p.h> #include <QtQuick3D/qquick3dobject.h>
#include <QtQuick/qquickwindow.h> #include <QtQuick/qquickwindow.h>
#include <QtCore/qvector.h> #include <QtCore/qvector.h>
@@ -367,10 +367,6 @@ void SelectionBoxGeometry::trackNodeChanges(QQuick3DNode *node)
this, &SelectionBoxGeometry::update, Qt::QueuedConnection); this, &SelectionBoxGeometry::update, Qt::QueuedConnection);
m_connections << QObject::connect(node, &QQuick3DNode::pivotChanged, m_connections << QObject::connect(node, &QQuick3DNode::pivotChanged,
this, &SelectionBoxGeometry::update, Qt::QueuedConnection); 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/ INCLUDEPATH += $$PWD/
qtHaveModule(quick3d) { versionAtLeast(QT_VERSION, 5.15.0):qtHaveModule(quick3d) {
QT *= quick3d-private QT *= quick3d-private
DEFINES *= QUICK3D_MODULE DEFINES *= QUICK3D_MODULE
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -37,7 +37,8 @@ Label {
property alias toolTip: toolTipArea.tooltip property alias toolTip: toolTipArea.tooltip
width: Math.max(Math.min(240, parent.width - 280), 50) 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 elide: Text.ElideRight
font.pixelSize: StudioTheme.Values.myFontSize font.pixelSize: StudioTheme.Values.myFontSize
@@ -46,9 +47,27 @@ Label {
Layout.minimumWidth: width Layout.minimumWidth: width
Layout.maximumWidth: 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 { ToolTipArea {
id: toolTipArea id: toolTipArea
anchors.fill: parent 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 selectedColor: Theme.qmlDesignerBackgroundColorDarkAlternate()
readonly property color unselectedColor: Theme.qmlDesignerBackgroundColorDarker() readonly property color unselectedColor: Theme.qmlDesignerBackgroundColorDarker()
property bool enabled: true
ExtendedFunctionLogic { ExtendedFunctionLogic {
id: extFuncLogic id: extFuncLogic
backendValue: originControl.backendValue backendValue: originControl.backendValue
@@ -69,6 +71,7 @@ Item {
} }
Grid { Grid {
opacity: originControl.enabled ? 1 : 0.5
rows: 3 rows: 3
columns: 3 columns: 3
spacing: 5 spacing: 5
@@ -76,7 +79,8 @@ Item {
id: grid id: grid
function setValue(myValue) { function setValue(myValue) {
originControl.backendValue.setEnumeration("Item", myValue) if (originControl.enabled)
originControl.backendValue.setEnumeration("Item", myValue)
} }
function select(myValue) { function select(myValue) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -77,13 +77,14 @@ namespace ADS
/** /**
* Private data class of DockManager class (pimpl) * Private data class of DockManager class (pimpl)
*/ */
struct DockManagerPrivate class DockManagerPrivate
{ {
public:
DockManager *q; DockManager *q;
QList<FloatingDockContainer *> m_floatingWidgets; QList<FloatingDockContainer *> m_floatingWidgets;
QList<DockContainerWidget *> m_containers; QList<DockContainerWidget *> m_containers;
DockOverlay *m_containerOverlay; DockOverlay *m_containerOverlay = nullptr;
DockOverlay *m_dockAreaOverlay; DockOverlay *m_dockAreaOverlay = nullptr;
QMap<QString, DockWidget *> m_dockWidgetsMap; QMap<QString, DockWidget *> m_dockWidgetsMap;
bool m_restoringState = false; bool m_restoringState = false;
QVector<FloatingDockContainer *> m_uninitializedFloatingWidgets; QVector<FloatingDockContainer *> m_uninitializedFloatingWidgets;
@@ -94,7 +95,7 @@ namespace ADS
QHash<QString, QDateTime> m_workspaceDateTimes; QHash<QString, QDateTime> m_workspaceDateTimes;
QString m_workspaceToRestoreAtStartup; QString m_workspaceToRestoreAtStartup;
bool m_autorestoreLastWorkspace; // This option is set in the Workspace Manager! bool m_autorestoreLastWorkspace; // This option is set in the Workspace Manager!
QSettings *m_settings; QSettings *m_settings = nullptr;
/** /**
* Private data constructor * Private data constructor
@@ -144,8 +145,7 @@ namespace ADS
bool restoreContainer(int index, DockingStateReader &stream, bool testing); bool restoreContainer(int index, DockingStateReader &stream, bool testing);
void workspaceLoadingProgress(); void workspaceLoadingProgress();
}; }; // class DockManagerPrivate
// struct DockManagerPrivate
DockManagerPrivate::DockManagerPrivate(DockManager *parent) DockManagerPrivate::DockManagerPrivate(DockManager *parent)
: q(parent) : q(parent)
@@ -188,6 +188,8 @@ namespace ADS
} }
DockingStateReader stateReader(state); DockingStateReader stateReader(state);
stateReader.readNextStartElement(); stateReader.readNextStartElement();
if (!stateReader.readNextStartElement())
return false;
if (stateReader.name() != "QtAdvancedDockingSystem") { if (stateReader.name() != "QtAdvancedDockingSystem") {
return false; 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"; const char AUTO_RESTORE_WORKSPACE_SETTINGS_KEY[] = "QML/Designer/AutoRestoreLastWorkspace";
} // namespace Constants } // namespace Constants
struct DockManagerPrivate; class DockManagerPrivate;
class FloatingDockContainer; class FloatingDockContainer;
struct FloatingDockContainerPrivate; class FloatingDockContainerPrivate;
class DockComponentsFactory; class DockComponentsFactory;
class DockContainerWidget; class DockContainerWidget;
class DockContainerWidgetPrivate; class DockContainerWidgetPrivate;
class DockOverlay; class DockOverlay;
class DockAreaTabBar; class DockAreaTabBar;
class DockWidgetTab; class DockWidgetTab;
struct DockWidgetTabPrivate; class DockWidgetTabPrivate;
struct DockAreaWidgetPrivate; struct DockAreaWidgetPrivate;
class IconProvider; class IconProvider;
@@ -96,17 +96,17 @@ class ADS_EXPORT DockManager : public DockContainerWidget
Q_OBJECT Q_OBJECT
private: private:
DockManagerPrivate *d; ///< private data (pimpl) DockManagerPrivate *d; ///< private data (pimpl)
friend struct DockManagerPrivate; friend class DockManagerPrivate;
friend class FloatingDockContainer; friend class FloatingDockContainer;
friend struct FloatingDockContainerPrivate; friend class FloatingDockContainerPrivate;
friend class DockContainerWidget; friend class DockContainerWidget;
friend class DockContainerWidgetPrivate; friend class DockContainerWidgetPrivate;
friend class DockAreaTabBar; friend class DockAreaTabBar;
friend class DockWidgetTab; friend class DockWidgetTab;
friend struct DockAreaWidgetPrivate; friend struct DockAreaWidgetPrivate;
friend struct DockWidgetTabPrivate; friend class DockWidgetTabPrivate;
friend class FloatingDragPreview; friend class FloatingDragPreview;
friend struct FloatingDragPreviewPrivate; friend class FloatingDragPreviewPrivate;
friend class DockAreaTitleBar; friend class DockAreaTitleBar;
protected: protected:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -43,7 +43,7 @@ namespace ADS {
class DockWidget; class DockWidget;
class DockAreaWidget; class DockAreaWidget;
struct FloatingDragPreviewPrivate; class FloatingDragPreviewPrivate;
/** /**
* A floating overlay is a temporary floating widget that is just used to * 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 Q_OBJECT
private: private:
FloatingDragPreviewPrivate *d; FloatingDragPreviewPrivate *d;
friend struct FloatingDragPreviewPrivate; friend class FloatingDragPreviewPrivate;
/** /**
* Cancel non opaque undocking if application becomes inactive * Cancel non opaque undocking if application becomes inactive

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