summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--dist/changes-4.11.0.md7
-rw-r--r--doc/config/qtcreator-project.qdocconf3
-rw-r--r--doc/images/qtcreator-clang-tools-options.pngbin5355 -> 8210 bytes
-rw-r--r--doc/images/qtcreator-clang-tools.pngbin16541 -> 9933 bytes
-rw-r--r--doc/images/qtcreator-cmake-build-settings.pngbin41710 -> 11650 bytes
-rw-r--r--doc/images/qtcreator-cmake-build-steps.pngbin7998 -> 5838 bytes
-rw-r--r--doc/images/qtcreator-cmake-clean-steps.pngbin8315 -> 6320 bytes
-rw-r--r--doc/images/qtcreator-cmakeexecutable.pngbin11541 -> 13050 bytes
-rw-r--r--doc/images/qtcreator-files-to-analyze.pngbin9716 -> 5402 bytes
-rw-r--r--doc/images/qtcreator-kits.pngbin28799 -> 27172 bytes
-rw-r--r--doc/src/analyze/creator-clang-static-analyzer.qdoc37
-rw-r--r--doc/src/cmake/creator-projects-cmake-building.qdocinc6
-rw-r--r--doc/src/cmake/creator-projects-cmake.qdoc11
-rw-r--r--doc/src/editors/creator-locator.qdoc5
-rw-r--r--doc/src/projects/creator-only/creator-projects-building.qdoc31
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/AutoScaleHelper.qml3
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/AxisHelper.qml133
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/AxisHelperArm.qml (renamed from share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.h)66
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/CameraGizmo.qml25
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/DirectionalDraggable.qml4
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/EditCameraController.qml128
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml197
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/HelperGrid.qml2
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/IconGizmo.qml31
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/LightGizmo.qml19
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/Overlay2D.qml9
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/PlanarDraggable.qml4
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/RotateGizmo.qml3
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/RotateRing.qml4
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/SelectionBox.qml66
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/ToggleButton.qml70
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/ToolBarButton.qml6
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/area_light_gradient.pngbin0 -> 1054 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/area_light_gradient@2x.pngbin0 -> 1268 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/directional_light_gradient.pngbin0 -> 1420 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/directional_light_gradient@2x.pngbin0 -> 3367 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_off.pngbin0 -> 1189 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_off@2x.pngbin0 -> 1430 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_on.pngbin0 -> 1355 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_on@2x.pngbin0 -> 1766 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_active.pngbin0 -> 266 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_active@2x.pngbin0 -> 386 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_selected.pngbin0 -> 266 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_selected@2x.pngbin0 -> 386 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/global.pngbin0 -> 433 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/global@2x.pngbin0 -> 561 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/local.pngbin0 -> 1309 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/local@2x.pngbin0 -> 1960 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/ortho.pngbin0 -> 1310 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/ortho@2x.pngbin0 -> 1727 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/persp.pngbin0 -> 1391 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/persp@2x.pngbin0 -> 1971 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/point_light_gradient.pngbin0 -> 1177 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/point_light_gradient@2x.pngbin0 -> 2634 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/meshes/axishelper.meshbin0 -> 158516 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.cpp78
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/editor3d.pri10
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp210
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h80
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp19
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.h6
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/selectionboxgeometry.cpp336
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/selectionboxgeometry.h90
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp32
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp60
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h1
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h2
-rw-r--r--share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc28
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml1
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml23
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Menu.qml10
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSliderPopup.qml4
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBoxInput.qml1
-rw-r--r--src/plugins/clangcodemodel/test/clangbatchfileprocessor.cpp2
-rw-r--r--src/plugins/clangtools/clangtidyclazyrunner.cpp4
-rw-r--r--src/plugins/clangtools/clangtool.cpp11
-rw-r--r--src/plugins/clangtools/clangtool.h1
-rw-r--r--src/plugins/clangtools/clangtoolsconstants.h2
-rw-r--r--src/plugins/clangtools/clangtoolslogfilereader.cpp2
-rw-r--r--src/plugins/clangtools/clangtoolsplugin.cpp10
-rw-r--r--src/plugins/clangtools/clangtoolsplugin.h4
-rw-r--r--src/plugins/clangtools/clangtoolssettings.h2
-rw-r--r--src/plugins/cmakeprojectmanager/cmakekitinformation.cpp4
-rw-r--r--src/plugins/cpptools/cpptoolstestcase.cpp21
-rw-r--r--src/plugins/cpptools/cpptoolstestcase.h5
-rw-r--r--src/plugins/designer/codemodelhelpers.cpp8
-rw-r--r--src/plugins/designer/cpp/formclasswizard.cpp7
-rw-r--r--src/plugins/designer/formeditorplugin.cpp2
-rw-r--r--src/plugins/designer/formeditorstack.cpp6
-rw-r--r--src/plugins/designer/formeditorw.cpp21
-rw-r--r--src/plugins/designer/formtemplatewizardpage.cpp3
-rw-r--r--src/plugins/designer/formwindoweditor.cpp4
-rw-r--r--src/plugins/designer/formwindowfile.cpp2
-rw-r--r--src/plugins/designer/qtcreatorintegration.cpp16
-rw-r--r--src/plugins/designer/resourcehandler.cpp5
-rw-r--r--src/plugins/mcusupport/mcusupportoptions.cpp2
-rw-r--r--src/plugins/mcusupport/mcusupportoptionspage.cpp3
-rw-r--r--src/plugins/mcusupport/mcusupportplugin.cpp4
-rw-r--r--src/plugins/mcusupport/mcusupportrunconfiguration.cpp2
-rw-r--r--src/plugins/mcusupport/mcusupportrunconfiguration.h4
-rw-r--r--src/plugins/projectexplorer/projectexplorer.cpp6
-rw-r--r--src/plugins/projectexplorer/projectexplorer.h2
-rw-r--r--src/plugins/projectexplorer/projectpanelfactory.cpp10
-rw-r--r--src/plugins/projectexplorer/projectpanelfactory.h6
-rw-r--r--src/plugins/projectexplorer/projectwindow.cpp22
-rw-r--r--src/plugins/projectexplorer/projectwindow.h4
-rw-r--r--src/plugins/qmldesigner/CMakeLists.txt2
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp408
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/bindingeditor.h112
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/bindingeditor.pri4
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/bindingeditordialog.cpp263
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/bindingeditordialog.h102
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp160
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.h104
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp1
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h1
-rw-r--r--src/plugins/qmldesigner/qmldesignerplugin.qbs4
-rw-r--r--src/shared/designerintegrationv2/formresizer.cpp7
-rw-r--r--src/shared/designerintegrationv2/formresizer.h4
-rw-r--r--src/shared/designerintegrationv2/widgethost.cpp6
-rw-r--r--src/shared/designerintegrationv2/widgethost.h2
m---------src/shared/qbs0
-rw-r--r--src/tools/qml2puppet/CMakeLists.txt3
-rw-r--r--src/tools/qml2puppet/qml2puppet.qbs6
125 files changed, 2379 insertions, 880 deletions
diff --git a/README.md b/README.md
index 9af659edb0..896d2e8b71 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,6 @@ Prerequisites:
* ActiveState Active Perl
* MinGW with g++ 5.3 or Visual Studio 2017 or later
* jom
- * Ninja (optional, needed for CMake)
* Python 3.5 or later (optional, needed for the python enabled debug helper)
* On Mac OS X: latest Xcode
* On Linux: g++ 5.3 or later
@@ -40,6 +39,7 @@ Prerequisites:
"Get LLVM/Clang for the Clang Code Model". The LLVM C++ API provides no compatibility garantee,
so if later versions don't compile we don't support that version.)
* CMake (for manual builds of LLVM/Clang, and Qt Creator itself)
+* Ninja (optional, recommended for building with CMake)
* Qbs 1.7.x (optional, sources also contain Qbs itself)
The installed toolchains have to match the one Qt was compiled with.
diff --git a/dist/changes-4.11.0.md b/dist/changes-4.11.0.md
index a85f8e5c3d..3b24537c3e 100644
--- a/dist/changes-4.11.0.md
+++ b/dist/changes-4.11.0.md
@@ -112,6 +112,10 @@ you can check out from the public Git repository. For example:
* Added option to remove directories directly from project tree (QTCREATORBUG-16575)
* Added support for Framework paths (QTCREATORBUG-20099)
+### Compilation Database
+
+* Fixed issue with `/imsvc` compiler option (QTCREATORBUG-23146)
+
## Debugging
### CDB
@@ -131,6 +135,7 @@ you can check out from the public Git repository. For example:
* Changed to use separate `clang-tidy` executable
* Separated diagnostic configuration settings for code model
(`C++` > `Code Model`) and analyzer (`Analyzer` > `Clang Tools`)
+* Fixed invocation of `clazy` with latest `clazy` versions
## Qt Widget Designer
@@ -174,6 +179,8 @@ you can check out from the public Git repository. For example:
* Removed auto-detection of GCC toolchains
* Fixed closing of terminal window after application finishes (QTCREATORBUG-15138)
+* Fixed execution of `qtc-askpass` (QTCREATORBUG-23120)
+* Fixed environment when opening terminal with `zsh` (QTCREATORBUG-21712)
### Android
diff --git a/doc/config/qtcreator-project.qdocconf b/doc/config/qtcreator-project.qdocconf
index 82daf9faad..b6710edb43 100644
--- a/doc/config/qtcreator-project.qdocconf
+++ b/doc/config/qtcreator-project.qdocconf
@@ -23,7 +23,8 @@ imagedirs = ../images \
../../src/plugins/qmldesigner/qmlpreviewplugin/images \
../../src/plugins/scxmleditor/common/images \
../../src/plugins/texteditor/images \
- ../../src/plugins/valgrind/images
+ ../../src/plugins/valgrind/images \
+ ../../src/plugins/welcome/images
exampledirs = ../examples
examples.fileextensions += *.qml *.svg
diff --git a/doc/images/qtcreator-clang-tools-options.png b/doc/images/qtcreator-clang-tools-options.png
index 6cf866f13f..3fce1e2dff 100644
--- a/doc/images/qtcreator-clang-tools-options.png
+++ b/doc/images/qtcreator-clang-tools-options.png
Binary files differ
diff --git a/doc/images/qtcreator-clang-tools.png b/doc/images/qtcreator-clang-tools.png
index 0ae985591c..cd80438a8a 100644
--- a/doc/images/qtcreator-clang-tools.png
+++ b/doc/images/qtcreator-clang-tools.png
Binary files differ
diff --git a/doc/images/qtcreator-cmake-build-settings.png b/doc/images/qtcreator-cmake-build-settings.png
index 35b4401820..534ddf6be1 100644
--- a/doc/images/qtcreator-cmake-build-settings.png
+++ b/doc/images/qtcreator-cmake-build-settings.png
Binary files differ
diff --git a/doc/images/qtcreator-cmake-build-steps.png b/doc/images/qtcreator-cmake-build-steps.png
index 1679217c51..5809136a85 100644
--- a/doc/images/qtcreator-cmake-build-steps.png
+++ b/doc/images/qtcreator-cmake-build-steps.png
Binary files differ
diff --git a/doc/images/qtcreator-cmake-clean-steps.png b/doc/images/qtcreator-cmake-clean-steps.png
index 9ecfbc74f1..88be99d715 100644
--- a/doc/images/qtcreator-cmake-clean-steps.png
+++ b/doc/images/qtcreator-cmake-clean-steps.png
Binary files differ
diff --git a/doc/images/qtcreator-cmakeexecutable.png b/doc/images/qtcreator-cmakeexecutable.png
index a0475e0c04..b98085b4e0 100644
--- a/doc/images/qtcreator-cmakeexecutable.png
+++ b/doc/images/qtcreator-cmakeexecutable.png
Binary files differ
diff --git a/doc/images/qtcreator-files-to-analyze.png b/doc/images/qtcreator-files-to-analyze.png
index fcdf05c0db..add972f337 100644
--- a/doc/images/qtcreator-files-to-analyze.png
+++ b/doc/images/qtcreator-files-to-analyze.png
Binary files differ
diff --git a/doc/images/qtcreator-kits.png b/doc/images/qtcreator-kits.png
index 05e8cc0df3..4dfaa560f3 100644
--- a/doc/images/qtcreator-kits.png
+++ b/doc/images/qtcreator-kits.png
Binary files differ
diff --git a/doc/src/analyze/creator-clang-static-analyzer.qdoc b/doc/src/analyze/creator-clang-static-analyzer.qdoc
index c4468ef038..b378553495 100644
--- a/doc/src/analyze/creator-clang-static-analyzer.qdoc
+++ b/doc/src/analyze/creator-clang-static-analyzer.qdoc
@@ -60,6 +60,11 @@
Clang tools are delivered and installed with \QC, and therefore you do not
need to set them up separately.
+ In addition to running the tools to collect diagnostics, you can select
+ \inlineimage open.png
+ to load diagnostics from \l{https://yaml.org/}{YAML} files that you exported
+ using the \c {-export fixes} option.
+
\section1 Running Clang Tools
To run the Clang tools to analyze an open project:
@@ -68,41 +73,25 @@
\li Select \uicontrol Analyze > \uicontrol {Clang-Tidy and Clazy}.
- \image qtcreator-files-to-analyze.png "Analyzer Configuration dialog"
-
- \li In the \uicontrol General group, select \uicontrol {Custom Settings}
- to modify the analyzer configuration.
-
- \li To build the project before running the Clang tools, select the
- \uicontrol {Build the project before analysis} check box. The Clang
- tools do not require the project to be built before analysis, but
- they might display misleading warnings about files missing that are
- generated during the build. For big projects, not building the
- project might save some time.
-
- \li In the \uicontrol {Diagnostic configuration} field, select a Clang
- configuration in the list of pre-defined configurations (1). For
- more information about creating a custom configuration, see
- \l {Configuring Clang Tools}.
+ \image qtcreator-files-to-analyze.png "Files to Analyze dialog"
- \li In the \uicontrol {Files to Analyze} group, select the files to
- apply the checks to.
+ \li Select the files to apply the checks to.
\li Select \uicontrol Analyze to start the checks.
\endlist
- If you select \uicontrol Debug in the mode selector to open the
- \uicontrol Debug mode and then select \uicontrol {Clang-Tidy and Clazy},
- you must select the \inlineimage qtcreator-analyze-start-button.png
- (\uicontrol Start) button to open the \uicontrol {Analyzer Configuration}
- dialog.
-
The found issues are displayed in the \uicontrol {Clang-Tidy and Clazy}
view:
\image qtcreator-clang-tools.png "Clang-Tidy and Clazy view"
+ \note If you select \uicontrol Debug in the mode selector to open the
+ \uicontrol Debug mode and then select \uicontrol {Clang-Tidy and Clazy},
+ you must select the \inlineimage qtcreator-analyze-start-button.png
+ (\uicontrol Start) button to open the \uicontrol {Files to Analyze}
+ dialog.
+
Double-click an issue to move to the location where the issue appears in
the code editor.
diff --git a/doc/src/cmake/creator-projects-cmake-building.qdocinc b/doc/src/cmake/creator-projects-cmake-building.qdocinc
index bca11658e4..a31449984c 100644
--- a/doc/src/cmake/creator-projects-cmake-building.qdocinc
+++ b/doc/src/cmake/creator-projects-cmake-building.qdocinc
@@ -57,6 +57,10 @@
To reset the changes that you made, select \uicontrol Reset.
+ To reconfigure CMake, select \uicontrol Build >
+ \uicontrol {Clear CMake Configuration}, and then
+ select \uicontrol Build > \uicontrol {Rescan Project}.
+
//! [cmake build configuration]
@@ -65,7 +69,7 @@
\section2 CMake Build Steps
\QC builds CMake projects by running \c {cmake . --build}, which then runs
- run whatever is needed based on how the project was configured: \c make,
+ whatever is needed based on how the project was configured: \c make,
\c mingw32-make, \c nmake, or \c ninja, for example.
You can add arguments and targets for the build command in
diff --git a/doc/src/cmake/creator-projects-cmake.qdoc b/doc/src/cmake/creator-projects-cmake.qdoc
index 585031ded7..a6d0ad6671 100644
--- a/doc/src/cmake/creator-projects-cmake.qdoc
+++ b/doc/src/cmake/creator-projects-cmake.qdoc
@@ -61,6 +61,10 @@
provide less information to the code model, which will then fail to resolve
includes and defines.
+ For CMake version 3.14, or later, \QC supports the
+ \l {https://cmake.org/cmake/help/latest/manual/cmake-file-api.7.html}
+ {file-based API}.
+
To specify paths to CMake executables:
\list 1
@@ -99,9 +103,14 @@
\section1 Editing CMake Configuration Files
To open a CMakeLists.txt file for editing, right-click it in the
- \uicontrol Projects view and select \uicontrol {Open with} >
+ \uicontrol Projects view and select \uicontrol {Open With} >
\uicontrol {CMake Editor}.
+ You can also use the \c cmo filter in the \l {Searching with the Locator}
+ {locator} to open the CMakeLists.txt file for the current run configuration
+ in the editor. This is the same build target as when you select
+ \uicontrol Build > \uicontrol {Build for Run Configuration}.
+
The following features are supported:
\list
diff --git a/doc/src/editors/creator-locator.qdoc b/doc/src/editors/creator-locator.qdoc
index e7c048f6d2..cd99ab139b 100644
--- a/doc/src/editors/creator-locator.qdoc
+++ b/doc/src/editors/creator-locator.qdoc
@@ -150,6 +150,11 @@
\if defined(qtcreator)
\li Running external tools (\c x)
+ \li Using CMake to build the project for the current run configuration
+ (\c {cm}). For more information, see \l {Setting up CMake}.
+ \li Opening the CMakeLists.txt file for the current run configuration in
+ the editor (\c {cmo}). This is the same build target as when you
+ select \uicontrol Build > \uicontrol {Build for Run Configuration}.
\endif
\endlist
diff --git a/doc/src/projects/creator-only/creator-projects-building.qdoc b/doc/src/projects/creator-only/creator-projects-building.qdoc
index c87557dc69..86b8b61748 100644
--- a/doc/src/projects/creator-only/creator-projects-building.qdoc
+++ b/doc/src/projects/creator-only/creator-projects-building.qdoc
@@ -84,16 +84,18 @@
To quickly check the compile output for changes that you made in one file or
subproject, you can use the \uicontrol Build menu commands to build a file or
- subproject.
+ subproject. The available build menu commands depend on the build system
+ you selected for the project: CMake, qmake, or Qbs.
- To build the executable that corresponds to the selected run configuration,
- select \uicontrol Build > \uicontrol {Build for Run Configuration}.
+ Select \uicontrol Build > \uicontrol {Build for Run Configuration} to
+ build the executable that corresponds to the selected run configuration.
+ You can also use the \c cm filter in the \l {Searching with the Locator}
+ {locator}.
To remove all build artifacts, select \uicontrol Build > \uicontrol {Clean All} or
\uicontrol {Clean Project}. To clean the build directory and then build
the project, select \uicontrol Build > \uicontrol {Rebuild All} or
- \uicontrol {Rebuild Project}. If you use qmake, rebuilding also runs qmake
- to generate new Makefiles between cleaning and building.
+ \uicontrol {Rebuild Project}.
To build and clean projects without dependencies, select the
\uicontrol {Build Without Dependencies},
@@ -101,11 +103,22 @@
\uicontrol {Clean Without Dependencies} options in the context menu in the
\uicontrol Projects view.
- \section1 Additional qmake Commands
+ To run qmake or CMake to regenerate build system files, select
+ \uicontrol Build > \uicontrol {Run qmake} or \uicontrol {Run CMake}.
- To run qmake to generate new Makefiles, select \uicontrol Build >
- \uicontrol qmake. To prevent failures on incremental builds, it might make
- sense to always run qmake before building, even though it means that
+ \section2 Building with CMake
+
+ \QC automatically runs CMake when you make changes to \c {CMakeLists.txt}
+ files. To disable this feature, select \uicontrol Tools >
+ \uicontrol Options > \uicontrol Kits > \uicontrol CMake >
+ \uicontrol {Autorun CMake}.
+
+ For more information, see \l {Setting Up CMake}.
+
+ \section2 Building with qmake
+
+ To prevent failures on incremental builds, it might make sense
+ to always run qmake before building, even though it means that
building will take more time. To enable this option, select \uicontrol Tools
> \uicontrol Options > \uicontrol {Build & Run} > \uicontrol qmake >
\uicontrol {Run qmake on every build}.
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/AutoScaleHelper.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/AutoScaleHelper.qml
index 9ffd3aa85b..dc4c38d100 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/AutoScaleHelper.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/AutoScaleHelper.qml
@@ -46,7 +46,7 @@ Node {
}
Connections {
- target: designStudioNativeCameraControlHelper
+ target: _generalHelper
onOverlayUpdateNeeded: updateScale()
}
@@ -81,6 +81,7 @@ Node {
MouseArea3D {
id: helper
+ active: false
view3D: overlayNode.view3D
}
}
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/AxisHelper.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/AxisHelper.qml
new file mode 100644
index 0000000000..86c60db721
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/AxisHelper.qml
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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.0
+
+View3D {
+ id: axisHelperView
+
+ property var editCameraCtrl
+ property Node selectedNode
+
+ camera: axisHelperCamera
+
+ Node {
+ OrthographicCamera {
+ id: axisHelperCamera
+ rotation: editCameraCtrl.camera.rotation
+ position: editCameraCtrl.camera.position.minus(editCameraCtrl._lookAtPoint)
+ .normalized().times(600)
+ }
+
+ AutoScaleHelper {
+ id: autoScale
+ view3D: axisHelperView
+ position: axisHelperGizmo.scenePosition
+ }
+
+ Node {
+ id: axisHelperGizmo
+ scale: autoScale.getScale(Qt.vector3d(4, 4, 4))
+
+ AxisHelperArm {
+ id: armX
+ rotation: Qt.vector3d(0, 0, -90)
+ color: Qt.rgba(1, 0, 0, 1)
+ hoverColor: Qt.lighter(Qt.rgba(1, 0, 0, 1))
+ view3D: axisHelperView
+ camRotPos: Qt.vector3d(0, 90, 0)
+ camRotNeg: Qt.vector3d(0, -90, 0)
+ }
+
+ AxisHelperArm {
+ id: armY
+ rotation: Qt.vector3d(0, 0, 0)
+ color: Qt.rgba(0, 0.6, 0, 1)
+ hoverColor: Qt.lighter(Qt.rgba(0, 0.6, 0, 1))
+ view3D: axisHelperView
+ camRotPos: Qt.vector3d(-90, 0, 0)
+ camRotNeg: Qt.vector3d(90, 0, 0)
+ }
+
+ AxisHelperArm {
+ id: armZ
+ rotation: Qt.vector3d(90, 0, 0)
+ color: Qt.rgba(0, 0, 1, 1)
+ hoverColor: Qt.lighter(Qt.rgba(0, 0, 1, 1))
+ view3D: axisHelperView
+ camRotPos: Qt.vector3d(0, 0, 0)
+ camRotNeg: Qt.vector3d(0, 180, 0)
+ }
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+ acceptedButtons: Qt.LeftButton
+
+ property var pickObj: null
+
+ function cancelHover()
+ {
+ if (pickObj) {
+ pickObj.hovering = false;
+ pickObj = null;
+ }
+ }
+
+ function pick(mouse)
+ {
+ var result = axisHelperView.pick(mouse.x, mouse.y);
+ if (result.objectHit) {
+ if (result.objectHit !== pickObj) {
+ cancelHover();
+ pickObj = result.objectHit;
+ pickObj.hovering = true;
+ }
+ } else {
+ cancelHover();
+ }
+ }
+
+ onPositionChanged: {
+ pick(mouse);
+ }
+
+ onPressed: {
+ pick(mouse);
+ if (pickObj) {
+ axisHelperView.editCameraCtrl.fitObject(axisHelperView.selectedNode,
+ pickObj.cameraRotation);
+ } else {
+ mouse.accepted = false;
+ }
+ }
+
+ onExited: cancelHover()
+ onCanceled: cancelHover()
+ }
+}
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.h b/share/qtcreator/qml/qmlpuppet/mockfiles/AxisHelperArm.qml
index ae17196044..23d2f9bbaf 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.h
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/AxisHelperArm.qml
@@ -23,40 +23,48 @@
**
****************************************************************************/
-#pragma once
+import QtQuick 2.0
+import QtQuick3D 1.0
-#include <QtCore/QObject>
-#include <QtCore/QTimer>
+Node {
+ id: armRoot
+ property alias posModel: posModel
+ property alias negModel: negModel
+ property View3D view3D
+ property color hoverColor
+ property color color
+ property vector3d camRotPos
+ property vector3d camRotNeg
-namespace QmlDesigner {
-namespace Internal {
-class CameraControlHelper : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
+ Model {
+ id: posModel
-public:
- CameraControlHelper();
+ property bool hovering: false
+ property vector3d cameraRotation: armRoot.camRotPos
- bool enabled();
- void setEnabled(bool enabled);
+ source: "meshes/axishelper.mesh"
+ materials: DefaultMaterial {
+ id: posMat
+ emissiveColor: posModel.hovering ? armRoot.hoverColor : armRoot.color
+ lighting: DefaultMaterial.NoLighting
+ }
+ pickable: true
+ }
- Q_INVOKABLE void requestOverlayUpdate();
- Q_INVOKABLE QString generateUniqueName(const QString &nameRoot);
+ Model {
+ id: negModel
-public slots:
- void handleUpdateTimer();
+ property bool hovering: false
+ property vector3d cameraRotation: armRoot.camRotNeg
-signals:
- void updateInputs();
- void enabledChanged(bool enabled);
- void overlayUpdateNeeded();
-
-private:
- bool m_enabled = false;
- QTimer m_inputUpdateTimer;
- QTimer m_overlayUpdateTimer;
-};
-
-}
+ source: "#Sphere"
+ y: -6
+ scale: Qt.vector3d(0.025, 0.025, 0.025)
+ materials: DefaultMaterial {
+ id: negMat
+ emissiveColor: negModel.hovering ? armRoot.hoverColor : armRoot.color
+ lighting: DefaultMaterial.NoLighting
+ }
+ pickable: true
+ }
}
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/CameraGizmo.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/CameraGizmo.qml
index e158128a5f..3b6badbb28 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/CameraGizmo.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/CameraGizmo.qml
@@ -31,21 +31,26 @@ IconGizmo {
id: cameraGizmo
iconSource: "qrc:///qtquickplugin/mockfiles/images/editor_camera.png"
- gizmoModel.geometry: cameraGeometry
property alias geometryName: cameraGeometry.name // Name must be unique for each geometry
property alias viewPortRect: cameraGeometry.viewPortRect
+ Model {
+ id: gizmoModel
+ geometry: cameraGeometry
+ visible: cameraGizmo.visible
+ materials: [
+ DefaultMaterial {
+ id: defaultMaterial
+ emissiveColor: cameraGizmo.targetNode === cameraGizmo.selectedNode ? "#FF0000"
+ : "#555555"
+ lighting: DefaultMaterial.NoLighting
+ cullingMode: Material.DisableCulling
+ }
+ ]
+ }
+
CameraGeometry {
id: cameraGeometry
camera: cameraGizmo.targetNode
}
-
- gizmoModel.materials: [
- DefaultMaterial {
- id: defaultMaterial
- emissiveColor: cameraGizmo.targetNode === cameraGizmo.selectedNode ? "#FF0000" : "#555555"
- lighting: DefaultMaterial.NoLighting
- cullingMode: Material.DisableCulling
- }
- ]
}
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/DirectionalDraggable.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/DirectionalDraggable.qml
index 243744210e..7ccfaa9816 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/DirectionalDraggable.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/DirectionalDraggable.qml
@@ -34,7 +34,7 @@ Model {
property View3D view3D
property alias color: material.emissiveColor
property Node targetNode: null
- property bool dragging: false
+ property bool dragging: mouseAreaYZ.dragging || mouseAreaXZ.dragging
property bool active: false
readonly property bool hovering: mouseAreaYZ.hovering || mouseAreaXZ.hovering
@@ -61,7 +61,6 @@ Model {
_pointerPosPressed = mouseArea.mapPositionToScene(maskedPosition);
var sp = targetNode.scenePosition;
_targetStartPos = Qt.vector3d(sp.x, sp.y, sp.z);
- dragging = true;
pressed(mouseArea);
}
@@ -88,7 +87,6 @@ Model {
return;
released(mouseArea, calcRelativeDistance(mouseArea, scenePos));
- dragging = false;
}
MouseArea3D {
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/EditCameraController.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/EditCameraController.qml
new file mode 100644
index 0000000000..dba7e30f96
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/EditCameraController.qml
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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.12
+import QtQuick3D 1.0
+
+Item {
+ id: cameraCtrl
+
+ property Camera camera: null
+ property View3D view3d: null
+
+ property vector3d _lookAtPoint
+ property vector3d _pressPoint
+ property vector3d _prevPoint
+ property vector3d _startRotation
+ property vector3d _startPosition
+ property vector3d _startLookAtPoint
+ property matrix4x4 _startTransform
+ property bool _dragging
+ property int _button
+ property real _zoomFactor: 1
+ property real _defaultCameraLookAtDistance: 0
+ property Camera _prevCamera: null
+
+ function fitObject(targetObject, rotation)
+ {
+ camera.rotation = rotation;
+ var newLookAtAndZoom = _generalHelper.fitObjectToCamera(
+ camera, _defaultCameraLookAtDistance, targetObject, view3d);
+ _lookAtPoint = newLookAtAndZoom.toVector3d();
+ _zoomFactor = newLookAtAndZoom.w;
+ }
+
+ function zoomRelative(distance)
+ {
+ _zoomFactor = _generalHelper.zoomCamera(camera, distance, _defaultCameraLookAtDistance,
+ _lookAtPoint, _zoomFactor, true);
+ }
+
+ Component.onCompleted: {
+ cameraCtrl._defaultCameraLookAtDistance = cameraCtrl.camera.position.length();
+ }
+
+ onCameraChanged: {
+ if (_prevCamera) {
+ // Reset zoom on previous camera to ensure it's properties are good to copy to new cam
+ _generalHelper.zoomCamera(_prevCamera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
+ 1, false);
+
+ camera.position = _prevCamera.position;
+ camera.rotation = _prevCamera.rotation;
+
+ // Apply correct zoom to new camera
+ _generalHelper.zoomCamera(camera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
+ _zoomFactor, false);
+ }
+ _prevCamera = camera;
+ }
+
+ MouseArea {
+ id: mouseHandler
+ acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
+ hoverEnabled: false
+ anchors.fill: parent
+ onPositionChanged: {
+ if (mouse.modifiers === Qt.AltModifier && cameraCtrl._dragging) {
+ var currentPoint = Qt.vector3d(mouse.x, mouse.y, 0);
+ if (cameraCtrl._button == Qt.LeftButton) {
+ _generalHelper.orbitCamera(cameraCtrl.camera, cameraCtrl._startRotation,
+ cameraCtrl._lookAtPoint, cameraCtrl._pressPoint,
+ currentPoint);
+ } else if (cameraCtrl._button == Qt.MiddleButton) {
+ cameraCtrl._lookAtPoint = _generalHelper.panCamera(
+ cameraCtrl.camera, cameraCtrl._startTransform,
+ cameraCtrl._startPosition, cameraCtrl._startLookAtPoint,
+ cameraCtrl._pressPoint, currentPoint, _zoomFactor);
+ } else if (cameraCtrl._button == Qt.RightButton) {
+ cameraCtrl.zoomRelative(currentPoint.y - cameraCtrl._prevPoint.y)
+ cameraCtrl._prevPoint = currentPoint;
+ }
+ }
+ }
+ onPressed: {
+ if (mouse.modifiers === Qt.AltModifier) {
+ cameraCtrl._dragging = true;
+ cameraCtrl._startRotation = cameraCtrl.camera.rotation;
+ cameraCtrl._startPosition = cameraCtrl.camera.position;
+ cameraCtrl._startLookAtPoint = _lookAtPoint;
+ cameraCtrl._pressPoint = Qt.vector3d(mouse.x, mouse.y, 0);
+ cameraCtrl._prevPoint = cameraCtrl._pressPoint;
+ cameraCtrl._button = mouse.button;
+ cameraCtrl._startTransform = cameraCtrl.camera.sceneTransform;
+ } else {
+ mouse.accepted = false;
+ }
+ }
+
+ onReleased: cameraCtrl._dragging = false;
+ onCanceled: cameraCtrl._dragging = false;
+ onWheel: {
+ // Emprically determined divisor for nice zoom
+ cameraCtrl.zoomRelative(wheel.angleDelta.y / -40);
+ }
+ }
+}
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml
index 9db9d0c8a8..2200048fa5 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml
@@ -26,7 +26,6 @@
import QtQuick 2.12
import QtQuick.Window 2.0
import QtQuick3D 1.0
-import QtQuick3D.Helpers 1.0
import QtQuick.Controls 2.0
import QtGraphicalEffects 1.0
@@ -39,8 +38,8 @@ Window {
flags: Qt.WindowStaysOnTopHint | Qt.Window | Qt.WindowTitleHint | Qt.WindowCloseButtonHint
property alias scene: editView.importScene
- property alias showEditLight: editLightCheckbox.checked
- property alias usePerspective: usePerspectiveCheckbox.checked
+ property alias showEditLight: btnEditViewLight.toggled
+ property alias usePerspective: btnPerspective.toggled
property Node selectedNode: null
@@ -56,9 +55,14 @@ Window {
selectedNode = object;
}
- function emitObjectClicked(object) {
- selectObject(object);
- objectClicked(object);
+ function handleObjectClicked(object) {
+ var theObject = object;
+ if (btnSelectGroup.selected) {
+ while (theObject && theObject.parent !== scene)
+ theObject = theObject.parent;
+ }
+ selectObject(theObject);
+ objectClicked(theObject);
}
function addLightGizmo(obj)
@@ -69,7 +73,7 @@ Window {
{"view3D": overlayView, "targetNode": obj,
"selectedNode": selectedNode});
lightGizmos[lightGizmos.length] = gizmo;
- gizmo.clicked.connect(emitObjectClicked);
+ gizmo.clicked.connect(handleObjectClicked);
gizmo.selectedNode = Qt.binding(function() {return selectedNode;});
}
}
@@ -78,13 +82,13 @@ Window {
{
var component = Qt.createComponent("CameraGizmo.qml");
if (component.status === Component.Ready) {
- var geometryName = designStudioNativeCameraControlHelper.generateUniqueName("CameraGeometry");
+ var geometryName = _generalHelper.generateUniqueName("CameraGeometry");
var gizmo = component.createObject(
overlayScene,
{"view3D": overlayView, "targetNode": obj, "geometryName": geometryName,
"viewPortRect": viewPortRect, "selectedNode": selectedNode});
cameraGizmos[cameraGizmos.length] = gizmo;
- gizmo.clicked.connect(emitObjectClicked);
+ gizmo.clicked.connect(handleObjectClicked);
gizmo.viewPortRect = Qt.binding(function() {return viewPortRect;});
gizmo.selectedNode = Qt.binding(function() {return selectedNode;});
}
@@ -92,10 +96,10 @@ Window {
// Work-around the fact that the projection matrix for the camera is not calculated until
// the first frame is rendered, so any initial calls to mapFrom3DScene() will fail.
- Component.onCompleted: designStudioNativeCameraControlHelper.requestOverlayUpdate();
+ Component.onCompleted: _generalHelper.requestOverlayUpdate();
- onWidthChanged: designStudioNativeCameraControlHelper.requestOverlayUpdate();
- onHeightChanged: designStudioNativeCameraControlHelper.requestOverlayUpdate();
+ onWidthChanged: _generalHelper.requestOverlayUpdate();
+ onHeightChanged: _generalHelper.requestOverlayUpdate();
Node {
id: overlayScene
@@ -114,6 +118,7 @@ Window {
clipNear: editOrthoCamera.clipNear
position: editOrthoCamera.position
rotation: editOrthoCamera.rotation
+ scale: editOrthoCamera.scale
}
MoveGizmo {
@@ -123,7 +128,7 @@ Window {
targetNode: viewWindow.selectedNode
position: viewWindow.selectedNode ? viewWindow.selectedNode.scenePosition
: Qt.vector3d(0, 0, 0)
- globalOrientation: globalControl.checked
+ globalOrientation: btnLocalGlobal.toggled
visible: selectedNode && btnMove.selected
view3D: overlayView
@@ -138,7 +143,7 @@ Window {
targetNode: viewWindow.selectedNode
position: viewWindow.selectedNode ? viewWindow.selectedNode.scenePosition
: Qt.vector3d(0, 0, 0)
- globalOrientation: globalControl.checked
+ globalOrientation: false
visible: selectedNode && btnScale.selected
view3D: overlayView
@@ -153,7 +158,7 @@ Window {
targetNode: viewWindow.selectedNode
position: viewWindow.selectedNode ? viewWindow.selectedNode.scenePosition
: Qt.vector3d(0, 0, 0)
- globalOrientation: globalControl.checked
+ globalOrientation: btnLocalGlobal.toggled
visible: selectedNode && btnRotate.selected
view3D: overlayView
@@ -169,16 +174,19 @@ Window {
}
Rectangle {
- id: sceneBg
- color: "#FFFFFF"
anchors.fill: parent
focus: true
+ gradient: Gradient {
+ GradientStop { position: 1.0; color: "#222222" }
+ GradientStop { position: 0.0; color: "#999999" }
+ }
+
TapHandler { // check tapping/clicking an object in the scene
onTapped: {
var pickResult = editView.pick(eventPoint.scenePosition.x,
eventPoint.scenePosition.y);
- emitObjectClicked(pickResult.objectHit);
+ handleObjectClicked(pickResult.objectHit);
}
}
@@ -200,6 +208,12 @@ Window {
step: 50
}
+ SelectionBox {
+ id: selectionBox
+ view3D: editView
+ targetNode: viewWindow.selectedNode
+ }
+
PointLight {
id: editLight
visible: showEditLight
@@ -209,11 +223,14 @@ Window {
linearFade: 0
}
+ // Initial camera position and rotation should be such that they look at origin.
+ // Otherwise EditCameraController._lookAtPoint needs to be initialized to correct
+ // point.
PerspectiveCamera {
id: editPerspectiveCamera
z: -600
- y: 200
- rotation.x: 30
+ y: 600
+ rotation.x: 45
clipFar: 100000
clipNear: 1
}
@@ -221,10 +238,10 @@ Window {
OrthographicCamera {
id: editOrthoCamera
z: -600
- y: 200
- rotation.x: 30
+ y: 600
+ rotation.x: 45
clipFar: 100000
- clipNear: 1
+ clipNear: -10000
}
}
}
@@ -240,14 +257,12 @@ Window {
id: gizmoLabel
targetNode: moveGizmo.visible ? moveGizmo : scaleGizmo
targetView: overlayView
- offsetX: 0
- offsetY: 45
visible: targetNode.dragging
Rectangle {
color: "white"
x: -width / 2
- y: -height
+ y: -height - 8
width: gizmoLabelText.width + 4
height: gizmoLabelText.height + 4
border.width: 1
@@ -273,19 +288,11 @@ Window {
}
}
- WasdController {
+ EditCameraController {
id: cameraControl
- controlledObject: editView.camera
- acceptedButtons: Qt.RightButton
-
- onInputsNeedProcessingChanged: designStudioNativeCameraControlHelper.enabled
- = cameraControl.inputsNeedProcessing
-
- // Use separate native timer as QML timers don't work inside Qt Design Studio
- Connections {
- target: designStudioNativeCameraControlHelper
- onUpdateInputs: cameraControl.processInputs()
- }
+ camera: editView.camera
+ anchors.fill: parent
+ view3d: editView
}
}
@@ -301,7 +308,8 @@ Window {
spacing: 5
padding: 5
- property var group: [btnSelectItem, btnSelectGroup, btnMove, btnRotate, btnScale]
+ property var groupSelect: [btnSelectGroup, btnSelectItem]
+ property var groupTransform: [btnMove, btnRotate, btnScale]
ToolBarButton {
id: btnSelectItem
@@ -310,7 +318,7 @@ Window {
shortcut: "Q"
currentShortcut: selected ? "" : shortcut
tool: "item_selection"
- buttonsGroup: col.group
+ buttonsGroup: col.groupSelect
}
ToolBarButton {
@@ -319,7 +327,7 @@ Window {
shortcut: "Q"
currentShortcut: btnSelectItem.currentShortcut === shortcut ? "" : shortcut
tool: "group_selection"
- buttonsGroup: col.group
+ buttonsGroup: col.groupSelect
}
Rectangle { // separator
@@ -331,11 +339,12 @@ Window {
ToolBarButton {
id: btnMove
+ selected: true
tooltip: qsTr("Move current selection")
- shortcut: "M"
+ shortcut: "W"
currentShortcut: shortcut
tool: "move"
- buttonsGroup: col.group
+ buttonsGroup: col.groupTransform
}
ToolBarButton {
@@ -344,60 +353,96 @@ Window {
shortcut: "E"
currentShortcut: shortcut
tool: "rotate"
- buttonsGroup: col.group
+ buttonsGroup: col.groupTransform
}
ToolBarButton {
id: btnScale
tooltip: qsTr("Scale current selection")
- shortcut: "T"
+ shortcut: "R"
currentShortcut: shortcut
tool: "scale"
- buttonsGroup: col.group
+ buttonsGroup: col.groupTransform
+ }
+
+ Rectangle { // separator
+ width: 25
+ height: 1
+ color: "#f1f1f1"
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+
+ ToolBarButton {
+ id: btnFit
+ tooltip: qsTr("Fit camera to current selection")
+ shortcut: "F"
+ currentShortcut: shortcut
+ tool: "fit"
+ togglable: false
+
+ onSelectedChanged: {
+ if (selected) {
+ var targetNode = viewWindow.selectedNode ? selectionBox.model : null;
+ cameraControl.fitObject(targetNode, editView.camera.rotation);
+ }
+ }
}
}
}
- Column {
- y: 8
+ AxisHelper {
anchors.right: parent.right
- CheckBox {
- id: editLightCheckbox
- checked: false
- text: qsTr("Use Edit View Light")
- onCheckedChanged: cameraControl.forceActiveFocus()
+ anchors.top: parent.top
+ width: 100
+ height: width
+ editCameraCtrl: cameraControl
+ selectedNode : viewWindow.selectedNode ? selectionBox.model : null
+ }
+
+ Rectangle { // top controls bar
+ color: "#aa000000"
+ width: 265
+ height: btnPerspective.height + 10
+ anchors.top: parent.top
+ anchors.right: parent.right
+ anchors.rightMargin: 100
+
+ ToggleButton {
+ id: btnPerspective
+ anchors.top: parent.top
+ anchors.topMargin: 5
+ anchors.left: parent.left
+ anchors.leftMargin: 5
+ tooltip: qsTr("Toggle Perspective / Orthographic Projection")
+ states: [{iconId: "ortho", text: qsTr("Orthographic")}, {iconId: "persp", text: qsTr("Perspective")}]
}
- CheckBox {
- id: usePerspectiveCheckbox
- checked: true
- text: qsTr("Use Perspective Projection")
- onCheckedChanged: {
- // Since WasdController always acts on active camera, we need to update pos/rot
- // to the other camera when we change
- if (checked) {
- editPerspectiveCamera.position = editOrthoCamera.position;
- editPerspectiveCamera.rotation = editOrthoCamera.rotation;
- } else {
- editOrthoCamera.position = editPerspectiveCamera.position;
- editOrthoCamera.rotation = editPerspectiveCamera.rotation;
- }
- designStudioNativeCameraControlHelper.requestOverlayUpdate();
- cameraControl.forceActiveFocus();
- }
+ ToggleButton {
+ id: btnLocalGlobal
+ anchors.top: parent.top
+ anchors.topMargin: 5
+ anchors.left: parent.left
+ anchors.leftMargin: 100
+ tooltip: qsTr("Toggle Global / Local Orientation")
+ states: [{iconId: "local", text: qsTr("Local")}, {iconId: "global", text: qsTr("Global")}]
}
- CheckBox {
- id: globalControl
- checked: true
- text: qsTr("Use Global Orientation")
- onCheckedChanged: cameraControl.forceActiveFocus()
+ ToggleButton {
+ id: btnEditViewLight
+ anchors.top: parent.top
+ anchors.topMargin: 5
+ anchors.left: parent.left
+ anchors.leftMargin: 165
+ toggleBackground: true
+ tooltip: qsTr("Toggle Edit Light")
+ states: [{iconId: "edit_light_off", text: qsTr("Edit Light Off")}, {iconId: "edit_light_on", text: qsTr("Edit Light On")}]
}
}
Text {
id: helpText
- text: qsTr("Camera: W,A,S,D,R,F,right mouse drag")
+ color: "white"
+ text: qsTr("Camera controls: ALT + mouse press and drag. Left: Rotate, Middle: Pan, Right/Wheel: Zoom.")
anchors.bottom: parent.bottom
}
}
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/HelperGrid.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/HelperGrid.qml
index 54af572a7b..2d70c0b95c 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/HelperGrid.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/HelperGrid.qml
@@ -45,7 +45,7 @@ Node {
materials: [
DefaultMaterial {
id: mainGridMaterial
- emissiveColor: "#e6e6e6"
+ emissiveColor: "#cccccc"
lighting: DefaultMaterial.NoLighting
cullingMode: Material.DisableCulling
}
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/IconGizmo.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/IconGizmo.qml
index 8623b87a84..3d4183a9dc 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/IconGizmo.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/IconGizmo.qml
@@ -25,6 +25,7 @@
import QtQuick 2.0
import QtQuick3D 1.0
+import QtGraphicalEffects 1.12
Node {
id: iconGizmo
@@ -34,8 +35,8 @@ Node {
property Node targetNode: null
property Node selectedNode: null
- property alias gizmoModel: gizmoModel
property alias iconSource: iconImage.source
+ property alias overlayColor: colorOverlay.color
signal positionCommit()
signal clicked(Node node)
@@ -44,30 +45,25 @@ Node {
rotation: targetNode ? targetNode.sceneRotation : Qt.vector3d(0, 0, 0)
visible: targetNode ? targetNode.visible : false
- Model {
- id: gizmoModel
- visible: iconGizmo.visible
- }
Overlay2D {
- id: gizmoLabel
- targetNode: gizmoModel
+ id: iconOverlay
+ targetNode: iconGizmo
targetView: view3D
- offsetX: 0
- offsetY: 0
visible: iconGizmo.visible && !isBehindCamera
parent: view3D
Rectangle {
+ id: iconRect
width: iconImage.width
height: iconImage.height
x: -width / 2
- y: -height
+ y: -height / 2
color: "transparent"
border.color: "#7777ff"
- border.width: iconGizmo.selectedNode === iconGizmo.targetNode
- || (iconGizmo.highlightOnHover && iconMouseArea.containsMouse) ? 2 : 0
+ border.width: iconGizmo.selectedNode !== iconGizmo.targetNode
+ && iconGizmo.highlightOnHover && iconMouseArea.containsMouse ? 2 : 0
radius: 5
- opacity: iconGizmo.selectedNode === iconGizmo.targetNode ? 0.3 : 1
+ opacity: iconGizmo.selectedNode === iconGizmo.targetNode ? 0.2 : 1
Image {
id: iconImage
fillMode: Image.Pad
@@ -81,6 +77,15 @@ Node {
? Qt.LeftButton : Qt.NoButton
}
}
+ ColorOverlay {
+ id: colorOverlay
+ anchors.fill: parent
+ cached: true
+ source: iconImage
+ color: "transparent"
+ opacity: 0.6
+ }
+
}
}
}
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/LightGizmo.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/LightGizmo.qml
index 888b2fce5c..6e321f8398 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/LightGizmo.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/LightGizmo.qml
@@ -29,14 +29,13 @@ import QtQuick3D 1.0
IconGizmo {
id: lightGizmo
- iconSource: "qrc:///qtquickplugin/mockfiles/images/light-pick-icon.png"
- gizmoModel.source: "#Sphere"
- gizmoModel.scale: Qt.vector3d(0.10, 0.10, 0.10)
- gizmoModel.materials: [
- DefaultMaterial {
- id: defaultMaterial
- emissiveColor: "yellow"
- lighting: DefaultMaterial.NoLighting
- }
- ]
+ iconSource: targetNode
+ ? targetNode instanceof DirectionalLight
+ ? "qrc:///qtquickplugin/mockfiles/images/directional_light_gradient.png"
+ : targetNode instanceof AreaLight
+ ? "qrc:///qtquickplugin/mockfiles/images/area_light_gradient.png"
+ : "qrc:///qtquickplugin/mockfiles/images/point_light_gradient.png"
+ : "qrc:///qtquickplugin/mockfiles/images/point_light_gradient.png"
+
+ overlayColor: targetNode ? targetNode.color : "transparent"
}
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/Overlay2D.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/Overlay2D.qml
index 1392c60cb2..f4a85226b7 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/Overlay2D.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/Overlay2D.qml
@@ -31,8 +31,7 @@ Item {
property Node targetNode
property View3D targetView
- property real offsetX: 0
- property real offsetY: 0
+ property vector3d offset: Qt.vector3d(0, 0, 0)
property bool isBehindCamera
@@ -49,14 +48,16 @@ Item {
}
Connections {
- target: designStudioNativeCameraControlHelper
+ target: _generalHelper
onOverlayUpdateNeeded: updateOverlay()
}
function updateOverlay()
{
var scenePos = targetNode ? targetNode.scenePosition : Qt.vector3d(0, 0, 0);
- var scenePosWithOffset = Qt.vector3d(scenePos.x + offsetX, scenePos.y + offsetY, scenePos.z);
+ var scenePosWithOffset = Qt.vector3d(scenePos.x + offset.x,
+ scenePos.y + offset.y,
+ scenePos.z + offset.z);
var viewPos = targetView ? targetView.mapFrom3DScene(scenePosWithOffset)
: Qt.vector3d(0, 0, 0);
root.x = viewPos.x;
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/PlanarDraggable.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/PlanarDraggable.qml
index 7bb1085e65..bd4fcd388b 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/PlanarDraggable.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/PlanarDraggable.qml
@@ -34,7 +34,7 @@ Model {
property alias color: gizmoMaterial.emissiveColor
property alias priority: mouseArea.priority
property Node targetNode: null
- property bool dragging: false
+ property bool dragging: mouseArea.dragging
property bool active: false
readonly property bool hovering: mouseArea.hovering
@@ -65,7 +65,6 @@ Model {
_pointerPosPressed = mouseArea.mapPositionToScene(scenePos);
var sp = targetNode.scenePosition;
_targetStartPos = Qt.vector3d(sp.x, sp.y, sp.z);
- dragging = true;
pressed(mouseArea);
}
@@ -91,7 +90,6 @@ Model {
return;
released(mouseArea, calcRelativeDistance(mouseArea, scenePos));
- dragging = false;
}
MouseArea3D {
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/RotateGizmo.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/RotateGizmo.qml
index b2f42b39e2..b730e86910 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/RotateGizmo.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/RotateGizmo.qml
@@ -134,8 +134,7 @@ Node {
targetNode: rotateGizmo.targetNode
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0.5, 0.5, 0.5, 1))
: Qt.rgba(0.5, 0.5, 0.5, 1)
- // Just a smidge smaller than higher priority rings so that it doesn't obscure them
- scale: Qt.vector3d(0.994, 0.994, 0.994)
+ scale: Qt.vector3d(1.1, 1.1, 1.1)
priority: 10
view3D: rotateGizmo.view3D
active: rotateGizmo.visible
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/RotateRing.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/RotateRing.qml
index 634eb017c9..3d21f8fd6a 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/RotateRing.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/RotateRing.qml
@@ -33,7 +33,7 @@ Model {
property View3D view3D
property alias color: material.emissiveColor
property Node targetNode: null
- property bool dragging: false
+ property bool dragging: mouseAreaMain.dragging
property bool active: false
property alias hovering: mouseAreaMain.hovering
property alias priority: mouseAreaMain.priority
@@ -80,7 +80,6 @@ Model {
_targetPosOnScreen = view3D.mapFrom3DScene(targetNode.scenePosition);
_targetPosOnScreen.z = 0;
_pointerPosPressed = Qt.vector3d(screenPos.x, screenPos.y, 0);
- dragging = true;
_trackBall = angle < 0.1;
// Recreate vector so we don't follow the changes in targetNode.rotation
@@ -108,7 +107,6 @@ Model {
applyLocalRotation(screenPos);
rotateCommit();
- dragging = false;
currentAngle = 0;
currentMousePos = screenPos;
}
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/SelectionBox.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/SelectionBox.qml
new file mode 100644
index 0000000000..995b4badd8
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/SelectionBox.qml
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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.0
+import SelectionBoxGeometry 1.0
+
+Node {
+ id: selectionBox
+
+ property View3D view3D
+ property Node targetNode: null
+ property alias model: selectionBoxModel
+
+ SelectionBoxGeometry {
+ id: selectionBoxGeometry
+ name: "Selection Box of 3D Edit View"
+ view3D: selectionBox.view3D
+ targetNode: selectionBox.targetNode
+ rootNode: selectionBox
+ }
+
+ Model {
+ id: selectionBoxModel
+ geometry: selectionBoxGeometry
+
+ scale: selectionBox.targetNode ? selectionBox.targetNode.scale : Qt.vector3d(1, 1, 1)
+ rotation: selectionBox.targetNode ? selectionBox.targetNode.rotation : 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)
+ orientation: selectionBox.targetNode ? selectionBox.targetNode.orientation : Node.LeftHanded
+ rotationOrder: selectionBox.targetNode ? selectionBox.targetNode.rotationOrder : Node.YXZ
+
+ visible: selectionBox.targetNode && !selectionBoxGeometry.isEmpty
+
+ materials: [
+ DefaultMaterial {
+ emissiveColor: "#fff600"
+ lighting: DefaultMaterial.NoLighting
+ cullingMode: Material.DisableCulling
+ }
+ ]
+ }
+}
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/ToggleButton.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/ToggleButton.qml
new file mode 100644
index 0000000000..a0ebeabbd4
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/ToggleButton.qml
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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.12
+import QtQuick 2.0
+import QtQuick.Controls 2.0
+
+Rectangle {
+ property bool toggled: false
+ property string tooltip
+ property bool toggleBackground: false // show a black background for the toggled state
+ property var states: [] // array of 2 state-objects, idx 0: untoggled, idx 1: toggled
+
+ id: root
+ color: toggleBackground && toggled ? "#aa000000" : mouseArea.containsMouse ? "#44000000" : "#00000000"
+ width: img.width + txt.width + 5
+ height: img.height
+
+ Image {
+ id: img
+ anchors.verticalCenter: parent.verticalCenter
+ source: "qrc:///qtquickplugin/mockfiles/images/" + root.states[toggled ? 1 : 0].iconId + ".png"
+ }
+
+ Text {
+ id: txt
+ color: "#b5b5b5"
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: img.right
+ text: root.states[toggled ? 1 : 0].text
+ }
+
+ ToolTip {
+ text: tooltip
+ visible: mouseArea.containsMouse
+ delay: 1000
+ }
+
+ MouseArea {
+ id: mouseArea
+ cursorShape: "PointingHandCursor"
+ hoverEnabled: true
+ anchors.fill: parent
+ onClicked: root.toggled = !root.toggled
+ }
+}
+
+
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/ToolBarButton.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/ToolBarButton.qml
index cbc450ed2b..38a8608e47 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/ToolBarButton.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/ToolBarButton.qml
@@ -34,6 +34,7 @@ Rectangle {
property string currentShortcut
property string tool
property variant buttonsGroup: []
+ property bool togglable: true
id: root
width: img.width + 5
@@ -71,6 +72,11 @@ Rectangle {
root.buttonsGroup[i].selected = false;
root.selected = true;
+
+ if (!root.togglable) {
+ // Deselect button after a short while (selection acts as simple click indicator)
+ _generalHelper.delayedPropertySet(root, 200, "selected", false);
+ }
}
}
}
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/area_light_gradient.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/area_light_gradient.png
new file mode 100644
index 0000000000..bd6404a36c
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/area_light_gradient.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/area_light_gradient@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/area_light_gradient@2x.png
new file mode 100644
index 0000000000..463f3ac481
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/area_light_gradient@2x.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/directional_light_gradient.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/directional_light_gradient.png
new file mode 100644
index 0000000000..f3c013e157
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/directional_light_gradient.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/directional_light_gradient@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/directional_light_gradient@2x.png
new file mode 100644
index 0000000000..87d60515f5
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/directional_light_gradient@2x.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_off.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_off.png
new file mode 100644
index 0000000000..73e6e92374
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_off.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_off@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_off@2x.png
new file mode 100644
index 0000000000..5166264e16
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_off@2x.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_on.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_on.png
new file mode 100644
index 0000000000..7660c28546
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_on.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_on@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_on@2x.png
new file mode 100644
index 0000000000..836bd2a0d5
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_on@2x.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_active.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_active.png
new file mode 100644
index 0000000000..056e9ec3c8
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_active.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_active@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_active@2x.png
new file mode 100644
index 0000000000..4b05f83d46
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_active@2x.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_selected.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_selected.png
new file mode 100644
index 0000000000..b8f98d9f12
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_selected.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_selected@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_selected@2x.png
new file mode 100644
index 0000000000..eac4361253
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_selected@2x.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/global.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/global.png
new file mode 100644
index 0000000000..1bd09c680a
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/global.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/global@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/global@2x.png
new file mode 100644
index 0000000000..a2a857fb10
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/global@2x.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/local.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/local.png
new file mode 100644
index 0000000000..0a608f6816
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/local.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/local@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/local@2x.png
new file mode 100644
index 0000000000..a5c931e750
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/local@2x.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/ortho.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/ortho.png
new file mode 100644
index 0000000000..35b36203fa
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/ortho.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/ortho@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/ortho@2x.png
new file mode 100644
index 0000000000..443c73e444
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/ortho@2x.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/persp.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/persp.png
new file mode 100644
index 0000000000..9a48e76399
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/persp.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/persp@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/persp@2x.png
new file mode 100644
index 0000000000..88a4eab9c6
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/persp@2x.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/point_light_gradient.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/point_light_gradient.png
new file mode 100644
index 0000000000..5136b39fc2
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/point_light_gradient.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/point_light_gradient@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/point_light_gradient@2x.png
new file mode 100644
index 0000000000..ccbfb1c846
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/point_light_gradient@2x.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/meshes/axishelper.mesh b/share/qtcreator/qml/qmlpuppet/mockfiles/meshes/axishelper.mesh
new file mode 100644
index 0000000000..3e9e4958e4
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/meshes/axishelper.mesh
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.cpp
deleted file mode 100644
index 1091e45911..0000000000
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 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.
-**
-****************************************************************************/
-#include "cameracontrolhelper.h"
-
-#include <QHash>
-
-namespace QmlDesigner {
-namespace Internal {
-
-CameraControlHelper::CameraControlHelper()
- : QObject()
-{
- m_inputUpdateTimer.setInterval(16);
- QObject::connect(&m_inputUpdateTimer, &QTimer::timeout,
- this, &CameraControlHelper::handleUpdateTimer);
-
- m_overlayUpdateTimer.setInterval(16);
- m_overlayUpdateTimer.setSingleShot(true);
- QObject::connect(&m_overlayUpdateTimer, &QTimer::timeout,
- this, &CameraControlHelper::overlayUpdateNeeded);
-}
-
-bool CameraControlHelper::enabled()
-{
- return m_enabled;
-}
-
-void CameraControlHelper::handleUpdateTimer()
-{
- emit updateInputs();
-}
-
-void CameraControlHelper::setEnabled(bool enabled)
-{
- if (enabled)
- m_inputUpdateTimer.start();
- else
- m_inputUpdateTimer.stop();
- m_enabled = enabled;
-}
-
-void CameraControlHelper::requestOverlayUpdate()
-{
- if (!m_overlayUpdateTimer.isActive())
- m_overlayUpdateTimer.start();
-}
-
-QString CameraControlHelper::generateUniqueName(const QString &nameRoot)
-{
- static QHash<QString, int> counters;
- int count = counters[nameRoot]++;
- return QStringLiteral("%1_%2").arg(nameRoot).arg(count);
-}
-
-}
-}
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/editor3d.pri b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/editor3d.pri
index e8f546e818..7b515e7a60 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/editor3d.pri
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/editor3d.pri
@@ -1,9 +1,11 @@
-HEADERS += $$PWD/cameracontrolhelper.h \
+HEADERS += $$PWD/generalhelper.h \
$$PWD/mousearea3d.h \
$$PWD/camerageometry.h \
- $$PWD/gridgeometry.h
+ $$PWD/gridgeometry.h \
+ $$PWD/selectionboxgeometry.h
-SOURCES += $$PWD/cameracontrolhelper.cpp \
+SOURCES += $$PWD/generalhelper.cpp \
$$PWD/mousearea3d.cpp \
$$PWD/camerageometry.cpp \
- $$PWD/gridgeometry.cpp
+ $$PWD/gridgeometry.cpp \
+ $$PWD/selectionboxgeometry.cpp
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp
new file mode 100644
index 0000000000..850a440a12
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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.
+**
+****************************************************************************/
+#include "generalhelper.h"
+
+#ifdef QUICK3D_MODULE
+
+#include "selectionboxgeometry.h"
+
+#include <QtQuick3D/private/qquick3dorthographiccamera_p.h>
+#include <QtQuick3D/private/qquick3dperspectivecamera_p.h>
+#include <QtQuick3D/private/qquick3dobject_p_p.h>
+#include <QtQuick3D/private/qquick3dcamera_p.h>
+#include <QtQuick3D/private/qquick3dnode_p.h>
+#include <QtQuick3D/private/qquick3dmodel_p.h>
+#include <QtQuick3D/private/qquick3dviewport_p.h>
+#include <QtQuick3D/private/qquick3ddefaultmaterial_p.h>
+#include <QtQuick3DRuntimeRender/private/qssgrendercontextcore_p.h>
+#include <QtQuick3DRuntimeRender/private/qssgrenderbuffermanager_p.h>
+#include <QtQuick3DRuntimeRender/private/qssgrendermodel_p.h>
+#include <QtQuick3DUtils/private/qssgbounds3_p.h>
+#include <QtQuick/qquickwindow.h>
+#include <QtCore/qmath.h>
+
+namespace QmlDesigner {
+namespace Internal {
+
+GeneralHelper::GeneralHelper()
+ : QObject()
+{
+ m_overlayUpdateTimer.setInterval(16);
+ m_overlayUpdateTimer.setSingleShot(true);
+ QObject::connect(&m_overlayUpdateTimer, &QTimer::timeout,
+ this, &GeneralHelper::overlayUpdateNeeded);
+}
+
+void GeneralHelper::requestOverlayUpdate()
+{
+ if (!m_overlayUpdateTimer.isActive())
+ m_overlayUpdateTimer.start();
+}
+
+QString GeneralHelper::generateUniqueName(const QString &nameRoot)
+{
+ static QHash<QString, int> counters;
+ int count = counters[nameRoot]++;
+ return QStringLiteral("%1_%2").arg(nameRoot).arg(count);
+}
+
+void GeneralHelper::orbitCamera(QQuick3DCamera *camera, const QVector3D &startRotation,
+ const QVector3D &lookAtPoint, const QVector3D &pressPos,
+ const QVector3D &currentPos)
+{
+ QVector3D dragVector = currentPos - pressPos;
+
+ if (dragVector.length() < 0.001f)
+ return;
+
+ camera->setRotation(startRotation);
+ QVector3D newRotation(dragVector.y(), dragVector.x(), 0.f);
+ newRotation *= 0.5f; // Emprically determined multiplier for nice drag
+ newRotation += startRotation;
+
+ camera->setRotation(newRotation);
+
+ const QVector3D oldLookVector = camera->position() - lookAtPoint;
+ QMatrix4x4 m = camera->sceneTransform();
+ const float *dataPtr(m.data());
+ QVector3D newLookVector(-dataPtr[8], -dataPtr[9], -dataPtr[10]);
+ newLookVector.normalize();
+ newLookVector *= oldLookVector.length();
+
+ camera->setPosition(lookAtPoint + newLookVector);
+}
+
+// Pans camera and returns the new look-at point
+QVector3D GeneralHelper::panCamera(QQuick3DCamera *camera, const QMatrix4x4 startTransform,
+ const QVector3D &startPosition, const QVector3D &startLookAt,
+ const QVector3D &pressPos, const QVector3D &currentPos,
+ float zoomFactor)
+{
+ QVector3D dragVector = currentPos - pressPos;
+
+ if (dragVector.length() < 0.001f)
+ return startLookAt;
+
+ const float *dataPtr(startTransform.data());
+ const QVector3D xAxis = QVector3D(dataPtr[0], dataPtr[1], dataPtr[2]).normalized();
+ const QVector3D yAxis = QVector3D(dataPtr[4], dataPtr[5], dataPtr[6]).normalized();
+ const QVector3D xDelta = -1.f * xAxis * dragVector.x();
+ const QVector3D yDelta = yAxis * dragVector.y();
+ const QVector3D delta = (xDelta + yDelta) * zoomFactor;
+
+ camera->setPosition(startPosition + delta);
+ return startLookAt + delta;
+}
+
+float GeneralHelper::zoomCamera(QQuick3DCamera *camera, float distance, float defaultLookAtDistance,
+ const QVector3D &lookAt, float zoomFactor, bool relative)
+{
+ // Emprically determined divisor for nice zoom
+ float multiplier = 1.f + (distance / 40.f);
+ float newZoomFactor = relative ? qBound(.0001f, zoomFactor * multiplier, 10000.f)
+ : zoomFactor;
+
+ if (qobject_cast<QQuick3DOrthographicCamera *>(camera)) {
+ // Ortho camera we can simply scale
+ camera->setScale(QVector3D(newZoomFactor, newZoomFactor, newZoomFactor));
+ } else if (qobject_cast<QQuick3DPerspectiveCamera *>(camera)) {
+ // Perspective camera is zoomed by moving camera forward or backward while keeping the
+ // look-at point the same
+ const QVector3D lookAtVec = (camera->position() - lookAt).normalized();
+ const float newDistance = defaultLookAtDistance * newZoomFactor;
+ camera->setPosition(lookAt + (lookAtVec * newDistance));
+ }
+
+ return newZoomFactor;
+}
+
+// Return value contains new lookAt point (xyz) and zoom factor (w)
+QVector4D GeneralHelper::fitObjectToCamera(QQuick3DCamera *camera, float defaultLookAtDistance,
+ QQuick3DNode *targetObject, QQuick3DViewport *viewPort)
+{
+ if (!camera)
+ return QVector4D(0.f, 0.f, 0.f, 1.f);
+
+ QVector3D lookAt = targetObject ? targetObject->scenePosition() : QVector3D();
+
+ // Get object bounds
+ qreal maxExtent = 200.;
+ if (auto modelNode = qobject_cast<QQuick3DModel *>(targetObject)) {
+ auto targetPriv = QQuick3DObjectPrivate::get(targetObject);
+ if (auto renderModel = static_cast<QSSGRenderModel *>(targetPriv->spatialNode)) {
+ QWindow *window = static_cast<QWindow *>(viewPort->window());
+ if (window) {
+ auto context = QSSGRenderContextInterface::getRenderContextInterface(quintptr(window));
+ if (!context.isNull()) {
+ QSSGBounds3 bounds;
+ auto geometry = qobject_cast<SelectionBoxGeometry *>(modelNode->geometry());
+ if (geometry) {
+ bounds = geometry->bounds();
+ } else {
+ auto bufferManager = context->bufferManager();
+ bounds = renderModel->getModelBounds(bufferManager);
+ }
+
+ QVector3D center = bounds.center();
+ const QVector3D e = bounds.extents();
+ const QVector3D s = targetObject->sceneScale();
+ qreal maxScale = qSqrt(qreal(s.x() * s.x() + s.y() * s.y() + s.z() * s.z()));
+ maxExtent = qSqrt(qreal(e.x() * e.x() + e.y() * e.y() + e.z() * e.z()));
+ maxExtent *= maxScale;
+
+ // Adjust lookAt to look directly at the center of the object bounds
+ lookAt = renderModel->globalTransform.map(center);
+ lookAt.setZ(-lookAt.z()); // Render node transforms have inverted z
+ }
+ }
+ }
+ }
+
+ // Reset camera position to default zoom
+ QMatrix4x4 m = camera->sceneTransform();
+ const float *dataPtr(m.data());
+ QVector3D newLookVector(-dataPtr[8], -dataPtr[9], -dataPtr[10]);
+ newLookVector.normalize();
+ newLookVector *= defaultLookAtDistance;
+
+ camera->setPosition(lookAt + newLookVector);
+
+ // Emprically determined algorithm for nice zoom
+ float newZoomFactor = qBound(.0001f, float(maxExtent / 700.), 10000.f);
+
+ return QVector4D(lookAt,
+ zoomCamera(camera, 0, defaultLookAtDistance, lookAt, newZoomFactor, false));
+}
+
+void GeneralHelper::delayedPropertySet(QObject *obj, int delay, const QString &property,
+ const QVariant &value)
+{
+ QTimer::singleShot(delay, [obj, property, value]() {
+ obj->setProperty(property.toLatin1().constData(), value);
+ });
+}
+
+}
+}
+
+#endif // QUICK3D_MODULE
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h
new file mode 100644
index 0000000000..16007e6798
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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.
+**
+****************************************************************************/
+
+#pragma once
+
+#ifdef QUICK3D_MODULE
+
+#include <QtCore/qobject.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qhash.h>
+#include <QtGui/qvector3d.h>
+#include <QtGui/qmatrix4x4.h>
+
+QT_BEGIN_NAMESPACE
+class QQuick3DCamera;
+class QQuick3DNode;
+class QQuick3DViewport;
+QT_END_NAMESPACE
+
+namespace QmlDesigner {
+namespace Internal {
+
+class GeneralHelper : public QObject
+{
+ Q_OBJECT
+
+public:
+ GeneralHelper();
+
+ Q_INVOKABLE void requestOverlayUpdate();
+ Q_INVOKABLE QString generateUniqueName(const QString &nameRoot);
+
+ Q_INVOKABLE void orbitCamera(QQuick3DCamera *camera, const QVector3D &startRotation,
+ const QVector3D &lookAtPoint, const QVector3D &pressPos,
+ const QVector3D &currentPos);
+ Q_INVOKABLE QVector3D panCamera(QQuick3DCamera *camera, const QMatrix4x4 startTransform,
+ const QVector3D &startPosition, const QVector3D &startLookAt,
+ const QVector3D &pressPos, const QVector3D &currentPos,
+ float zoomFactor);
+ Q_INVOKABLE float zoomCamera(QQuick3DCamera *camera, float distance,
+ float defaultLookAtDistance, const QVector3D &lookAt,
+ float zoomFactor, bool relative);
+ Q_INVOKABLE QVector4D fitObjectToCamera(QQuick3DCamera *camera, float defaultLookAtDistance,
+ QQuick3DNode *targetObject, QQuick3DViewport *viewPort);
+ Q_INVOKABLE void delayedPropertySet(QObject *obj, int delay, const QString &property,
+ const QVariant& value);
+
+signals:
+ void overlayUpdateNeeded();
+
+private:
+ QTimer m_overlayUpdateTimer;
+};
+
+}
+}
+
+#endif // QUICK3D_MODULE
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp
index 31ed661125..d571b24dcb 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp
@@ -37,7 +37,6 @@ namespace QmlDesigner {
namespace Internal {
MouseArea3D *MouseArea3D::s_mouseGrab = nullptr;
-static const qreal s_mouseDragMultiplier = .02;
MouseArea3D::MouseArea3D(QQuick3DNode *parent)
: QQuick3DNode(parent)
@@ -124,6 +123,13 @@ void MouseArea3D::setGrabsMouse(bool grabsMouse)
return;
m_grabsMouse = grabsMouse;
+
+ if (!m_grabsMouse && s_mouseGrab == this) {
+ setDragging(false);
+ setHovering(false);
+ s_mouseGrab = nullptr;
+ }
+
emit grabsMouseChanged();
}
@@ -133,6 +139,13 @@ void MouseArea3D::setActive(bool active)
return;
m_active = active;
+
+ if (!m_active && s_mouseGrab == this) {
+ setDragging(false);
+ setHovering(false);
+ s_mouseGrab = nullptr;
+ }
+
emit activeChanged();
}
@@ -340,7 +353,7 @@ qreal QmlDesigner::Internal::MouseArea3D::getNewRotationAngle(
dragDir = (screenDragDir - nodePos).normalized();
const QVector3D pressToCurrent = (currentPos - pressPos);
float magnitude = QVector3D::dotProduct(pressToCurrent, dragDir);
- qreal angle = -s_mouseDragMultiplier * qreal(magnitude);
+ qreal angle = -mouseDragMultiplier() * qreal(magnitude);
return angle;
} else {
const QVector3D nodeToPress = (pressPos - nodePos).normalized();
@@ -397,7 +410,7 @@ void MouseArea3D::applyFreeRotation(QQuick3DNode *node, const QVector3D &startRo
QVector3D finalAxis = (dragVector.x() * yAxis + dragVector.y() * xAxis);
- qreal degrees = qRadiansToDegrees(qreal(finalAxis.length()) * s_mouseDragMultiplier);
+ qreal degrees = qRadiansToDegrees(qreal(finalAxis.length()) * mouseDragMultiplier());
finalAxis.normalize();
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.h
index e227b3f9dd..c824b92969 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.h
@@ -51,7 +51,7 @@ class MouseArea3D : public QQuick3DNode
Q_PROPERTY(bool hovering READ hovering NOTIFY hoveringChanged)
Q_PROPERTY(bool dragging READ dragging NOTIFY draggingChanged)
Q_PROPERTY(int priority READ priority WRITE setPriority NOTIFY priorityChanged)
- Q_PROPERTY(int active READ active WRITE setActive NOTIFY activeChanged)
+ Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
Q_PROPERTY(QPointF circlePickArea READ circlePickArea WRITE setCirclePickArea NOTIFY circlePickAreaChanged)
Q_PROPERTY(qreal minAngle READ minAngle WRITE setMinAngle NOTIFY minAngleChanged)
Q_PROPERTY(QQuick3DNode *pickNode READ pickNode WRITE setPickNode NOTIFY pickNodeChanged)
@@ -77,6 +77,8 @@ public:
qreal minAngle() const;
QQuick3DNode *pickNode() const;
+ static qreal mouseDragMultiplier() { return .02; }
+
public slots:
void setView3D(QQuick3DViewport *view3D);
void setGrabsMouse(bool grabsMouse);
@@ -157,7 +159,7 @@ private:
QVector3D getMousePosInPlane(const QPointF &mousePosInView) const;
static MouseArea3D *s_mouseGrab;
- bool m_grabsMouse;
+ bool m_grabsMouse = false;
QVector3D m_mousePosInPlane;
QPointF m_circlePickArea;
qreal m_minAngle = 0.;
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/selectionboxgeometry.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/selectionboxgeometry.cpp
new file mode 100644
index 0000000000..7770061923
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/selectionboxgeometry.cpp
@@ -0,0 +1,336 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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.
+**
+****************************************************************************/
+
+#ifdef QUICK3D_MODULE
+
+#include "selectionboxgeometry.h"
+
+#include <QtQuick3DRuntimeRender/private/qssgrendergeometry_p.h>
+#include <QtQuick3DRuntimeRender/private/qssgrendermodel_p.h>
+#include <QtQuick3DRuntimeRender/private/qssgrendercontextcore_p.h>
+#include <QtQuick3DRuntimeRender/private/qssgrenderbuffermanager_p.h>
+#include <QtQuick3D/private/qquick3dmodel_p.h>
+#include <QtQuick3D/private/qquick3dobject_p_p.h>
+#include <QtQuick/qquickwindow.h>
+#include <QtCore/qvector.h>
+
+#include <limits>
+
+namespace QmlDesigner {
+namespace Internal {
+
+SelectionBoxGeometry::SelectionBoxGeometry()
+ : QQuick3DGeometry()
+{
+}
+
+SelectionBoxGeometry::~SelectionBoxGeometry()
+{
+ for (auto &connection : qAsConst(m_connections))
+ QObject::disconnect(connection);
+ m_connections.clear();
+}
+
+QQuick3DNode *SelectionBoxGeometry::targetNode() const
+{
+ return m_targetNode;
+}
+
+QQuick3DNode *SelectionBoxGeometry::rootNode() const
+{
+ return m_rootNode;
+}
+
+QQuick3DViewport *SelectionBoxGeometry::view3D() const
+{
+ return m_view3D;
+}
+
+bool QmlDesigner::Internal::SelectionBoxGeometry::isEmpty() const
+{
+ return m_isEmpty;
+}
+
+QSSGBounds3 SelectionBoxGeometry::bounds() const
+{
+ return m_bounds;
+}
+
+void SelectionBoxGeometry::setTargetNode(QQuick3DNode *targetNode)
+{
+ if (m_targetNode == targetNode)
+ return;
+
+ if (m_targetNode)
+ m_targetNode->disconnect(this);
+ m_targetNode = targetNode;
+
+ if (auto model = qobject_cast<QQuick3DModel *>(m_targetNode)) {
+ QObject::connect(model, &QQuick3DModel::sourceChanged,
+ this, &SelectionBoxGeometry::update, Qt::QueuedConnection);
+ QObject::connect(model, &QQuick3DModel::geometryChanged,
+ this, &SelectionBoxGeometry::update, Qt::QueuedConnection);
+ }
+
+ emit targetNodeChanged();
+ update();
+}
+
+void SelectionBoxGeometry::setRootNode(QQuick3DNode *rootNode)
+{
+ if (m_rootNode == rootNode)
+ return;
+
+ m_rootNode = rootNode;
+
+ emit rootNodeChanged();
+ update();
+}
+
+void SelectionBoxGeometry::setView3D(QQuick3DViewport *view)
+{
+ if (m_view3D == view)
+ return;
+
+ m_view3D = view;
+
+ emit view3DChanged();
+ update();
+}
+
+QSSGRenderGraphObject *SelectionBoxGeometry::updateSpatialNode(QSSGRenderGraphObject *node)
+{
+ node = QQuick3DGeometry::updateSpatialNode(node);
+ QSSGRenderGeometry *geometry = static_cast<QSSGRenderGeometry *>(node);
+
+ geometry->clear();
+ for (auto &connection : qAsConst(m_connections))
+ QObject::disconnect(connection);
+ m_connections.clear();
+
+ QByteArray vertexData;
+ QByteArray indexData;
+
+ static const float floatMin = std::numeric_limits<float>::lowest();
+ static const float floatMax = std::numeric_limits<float>::max();
+
+ QVector3D minBounds = QVector3D(floatMax, floatMax, floatMax);
+ QVector3D maxBounds = QVector3D(floatMin, floatMin, floatMin);
+
+ if (m_targetNode) {
+ auto rootPriv = QQuick3DObjectPrivate::get(m_rootNode);
+ auto targetPriv = QQuick3DObjectPrivate::get(m_targetNode);
+ auto rootRN = static_cast<QSSGRenderNode *>(rootPriv->spatialNode);
+ auto targetRN = static_cast<QSSGRenderNode *>(targetPriv->spatialNode);
+ if (rootRN && targetRN) {
+ // Explicitly set local transform of root node to target node parent's global transform
+ // to avoid having to reparent the selection box. This has to be done directly on render
+ // nodes.
+ targetRN->parent->calculateGlobalVariables();
+ QMatrix4x4 m = targetRN->parent->globalTransform;
+ rootRN->localTransform = m;
+ rootRN->markDirty(QSSGRenderNode::TransformDirtyFlag::TransformNotDirty);
+ rootRN->calculateGlobalVariables();
+ }
+ getBounds(m_targetNode, vertexData, indexData, minBounds, maxBounds, QMatrix4x4());
+ } else {
+ // Fill some dummy data so geometry won't get rejected
+ appendVertexData(vertexData, indexData, minBounds, maxBounds);
+ }
+
+ geometry->addAttribute(QSSGRenderGeometry::Attribute::PositionSemantic, 0,
+ QSSGRenderGeometry::Attribute::ComponentType::F32Type);
+ geometry->addAttribute(QSSGRenderGeometry::Attribute::IndexSemantic, 0,
+ QSSGRenderGeometry::Attribute::ComponentType::U16Type);
+ geometry->setStride(12);
+ geometry->setVertexData(vertexData);
+ geometry->setIndexData(indexData);
+ geometry->setPrimitiveType(QSSGRenderGeometry::Lines);
+ geometry->setBounds(minBounds, maxBounds);
+
+ m_bounds = QSSGBounds3(minBounds, maxBounds);
+
+ bool empty = minBounds.isNull() && maxBounds.isNull();
+ if (m_isEmpty != empty) {
+ m_isEmpty = empty;
+ // Delay notification until we're done with spatial node updates
+ QTimer::singleShot(0, this, &SelectionBoxGeometry::isEmptyChanged);
+ }
+
+ return node;
+}
+
+void SelectionBoxGeometry::getBounds(QQuick3DNode *node, QByteArray &vertexData,
+ QByteArray &indexData, QVector3D &minBounds,
+ QVector3D &maxBounds, const QMatrix4x4 &transform)
+{
+ QMatrix4x4 fullTransform;
+ auto nodePriv = QQuick3DObjectPrivate::get(node);
+ auto renderNode = static_cast<QSSGRenderNode *>(nodePriv->spatialNode);
+
+ // All transforms are relative to targetNode transform, so its local transform is ignored
+ if (node != m_targetNode) {
+ if (renderNode) {
+ if (renderNode->flags.testFlag(QSSGRenderNode::Flag::TransformDirty))
+ renderNode->calculateLocalTransform();
+ fullTransform = transform * renderNode->localTransform;
+ }
+
+ m_connections << QObject::connect(node, &QQuick3DNode::scaleChanged,
+ this, &SelectionBoxGeometry::update, Qt::QueuedConnection);
+ m_connections << QObject::connect(node, &QQuick3DNode::rotationChanged,
+ this, &SelectionBoxGeometry::update, Qt::QueuedConnection);
+ m_connections << QObject::connect(node, &QQuick3DNode::positionChanged,
+ this, &SelectionBoxGeometry::update, Qt::QueuedConnection);
+ m_connections << QObject::connect(node, &QQuick3DNode::pivotChanged,
+ this, &SelectionBoxGeometry::update, Qt::QueuedConnection);
+ m_connections << QObject::connect(node, &QQuick3DNode::orientationChanged,
+ this, &SelectionBoxGeometry::update, Qt::QueuedConnection);
+ m_connections << QObject::connect(node, &QQuick3DNode::rotationOrderChanged,
+ this, &SelectionBoxGeometry::update, Qt::QueuedConnection);
+ }
+
+ QVector<QVector3D> minBoundsVec;
+ QVector<QVector3D> maxBoundsVec;
+
+ // Check for children
+ const auto children = node->childItems();
+ for (const auto child : children) {
+ if (auto childNode = qobject_cast<QQuick3DNode *>(child)) {
+ QVector3D newMinBounds = minBounds;
+ QVector3D newMaxBounds = maxBounds;
+ getBounds(childNode, vertexData, indexData, newMinBounds, newMaxBounds, fullTransform);
+ minBoundsVec << newMinBounds;
+ maxBoundsVec << newMaxBounds;
+ }
+ }
+
+ // Combine all child bounds
+ for (const auto &newBounds : qAsConst(minBoundsVec)) {
+ minBounds.setX(qMin(newBounds.x(), minBounds.x()));
+ minBounds.setY(qMin(newBounds.y(), minBounds.y()));
+ minBounds.setZ(qMin(newBounds.z(), minBounds.z()));
+ }
+ for (const auto &newBounds : qAsConst(maxBoundsVec)) {
+ maxBounds.setX(qMax(newBounds.x(), maxBounds.x()));
+ maxBounds.setY(qMax(newBounds.y(), maxBounds.y()));
+ maxBounds.setZ(qMax(newBounds.z(), maxBounds.z()));
+ }
+
+ if (auto modelNode = qobject_cast<QQuick3DModel *>(node)) {
+ if (auto renderModel = static_cast<QSSGRenderModel *>(renderNode)) {
+ QWindow *window = static_cast<QWindow *>(m_view3D->window());
+ if (window) {
+ auto context = QSSGRenderContextInterface::getRenderContextInterface(
+ quintptr(window));
+ if (!context.isNull()) {
+ auto bufferManager = context->bufferManager();
+ QSSGBounds3 bounds = renderModel->getModelBounds(bufferManager);
+ QVector3D center = bounds.center();
+ QVector3D extents = bounds.extents();
+ QVector3D localMin = center - extents;
+ QVector3D localMax = center + extents;
+
+ // Transform all corners of the local bounding box to find final extent in
+ // in parent space
+
+ auto checkCorner = [&minBounds, &maxBounds, &fullTransform]
+ (const QVector3D &corner) {
+ QVector3D mappedCorner = fullTransform.map(corner);
+ minBounds.setX(qMin(mappedCorner.x(), minBounds.x()));
+ minBounds.setY(qMin(mappedCorner.y(), minBounds.y()));
+ minBounds.setZ(qMin(mappedCorner.z(), minBounds.z()));
+ maxBounds.setX(qMax(mappedCorner.x(), maxBounds.x()));
+ maxBounds.setY(qMax(mappedCorner.y(), maxBounds.y()));
+ maxBounds.setZ(qMax(mappedCorner.z(), maxBounds.z()));
+ };
+
+ checkCorner(localMin);
+ checkCorner(localMax);
+ checkCorner(QVector3D(localMin.x(), localMin.y(), localMax.z()));
+ checkCorner(QVector3D(localMin.x(), localMax.y(), localMin.z()));
+ checkCorner(QVector3D(localMax.x(), localMin.y(), localMin.z()));
+ checkCorner(QVector3D(localMin.x(), localMax.y(), localMax.z()));
+ checkCorner(QVector3D(localMax.x(), localMax.y(), localMin.z()));
+ checkCorner(QVector3D(localMax.x(), localMin.y(), localMax.z()));
+ }
+ }
+ }
+ }
+
+ // Target node and immediate children get selection boxes
+ if (transform.isIdentity()) {
+ // Adjust bounds to reduce targetNode pixels obscuring the selection box
+ QVector3D extents = (maxBounds - minBounds) / 1000.f;
+ QVector3D minAdjBounds = minBounds - extents;
+ QVector3D maxAdjBounds = maxBounds + extents;
+
+ appendVertexData(vertexData, indexData, minAdjBounds, maxAdjBounds);
+ }
+}
+
+void SelectionBoxGeometry::appendVertexData(QByteArray &vertexData, QByteArray &indexData,
+ const QVector3D &minBounds, const QVector3D &maxBounds)
+{
+ int initialVertexSize = vertexData.size();
+ int initialIndexSize = indexData.size();
+ const int vertexSize = int(sizeof(float)) * 8 * 3; // 8 vertices, 3 floats/vert
+ quint16 indexAdd = quint16(initialVertexSize / 12);
+ vertexData.resize(initialVertexSize + vertexSize);
+ const int indexSize = int(sizeof(quint16)) * 12 * 2; // 12 lines, 2 vert/line
+ indexData.resize(initialIndexSize + indexSize);
+
+ auto dataPtr = reinterpret_cast<float *>(vertexData.data() + initialVertexSize);
+ auto indexPtr = reinterpret_cast<quint16 *>(indexData.data() + initialIndexSize);
+
+ *dataPtr++ = maxBounds.x(); *dataPtr++ = maxBounds.y(); *dataPtr++ = maxBounds.z();
+ *dataPtr++ = minBounds.x(); *dataPtr++ = maxBounds.y(); *dataPtr++ = maxBounds.z();
+ *dataPtr++ = minBounds.x(); *dataPtr++ = minBounds.y(); *dataPtr++ = maxBounds.z();
+ *dataPtr++ = maxBounds.x(); *dataPtr++ = minBounds.y(); *dataPtr++ = maxBounds.z();
+ *dataPtr++ = maxBounds.x(); *dataPtr++ = maxBounds.y(); *dataPtr++ = minBounds.z();
+ *dataPtr++ = minBounds.x(); *dataPtr++ = maxBounds.y(); *dataPtr++ = minBounds.z();
+ *dataPtr++ = minBounds.x(); *dataPtr++ = minBounds.y(); *dataPtr++ = minBounds.z();
+ *dataPtr++ = maxBounds.x(); *dataPtr++ = minBounds.y(); *dataPtr++ = minBounds.z();
+
+ *indexPtr++ = 0 + indexAdd; *indexPtr++ = 1 + indexAdd;
+ *indexPtr++ = 1 + indexAdd; *indexPtr++ = 2 + indexAdd;
+ *indexPtr++ = 2 + indexAdd; *indexPtr++ = 3 + indexAdd;
+ *indexPtr++ = 3 + indexAdd; *indexPtr++ = 0 + indexAdd;
+
+ *indexPtr++ = 0 + indexAdd; *indexPtr++ = 4 + indexAdd;
+ *indexPtr++ = 1 + indexAdd; *indexPtr++ = 5 + indexAdd;
+ *indexPtr++ = 2 + indexAdd; *indexPtr++ = 6 + indexAdd;
+ *indexPtr++ = 3 + indexAdd; *indexPtr++ = 7 + indexAdd;
+
+ *indexPtr++ = 4 + indexAdd; *indexPtr++ = 5 + indexAdd;
+ *indexPtr++ = 5 + indexAdd; *indexPtr++ = 6 + indexAdd;
+ *indexPtr++ = 6 + indexAdd; *indexPtr++ = 7 + indexAdd;
+ *indexPtr++ = 7 + indexAdd; *indexPtr++ = 4 + indexAdd;
+}
+
+}
+}
+
+#endif // QUICK3D_MODULE
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/selectionboxgeometry.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/selectionboxgeometry.h
new file mode 100644
index 0000000000..08a28cec06
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/selectionboxgeometry.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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.
+**
+****************************************************************************/
+
+#pragma once
+
+#ifdef QUICK3D_MODULE
+
+#include <QtQuick3D/private/qquick3dnode_p.h>
+#include <QtQuick3D/private/qquick3dgeometry_p.h>
+#include <QtQuick3D/private/qquick3dviewport_p.h>
+#include <QtQuick3DUtils/private/qssgbounds3_p.h>
+
+namespace QmlDesigner {
+namespace Internal {
+
+class SelectionBoxGeometry : public QQuick3DGeometry
+{
+ Q_OBJECT
+ Q_PROPERTY(QQuick3DNode *targetNode READ targetNode WRITE setTargetNode NOTIFY targetNodeChanged)
+ Q_PROPERTY(QQuick3DNode *rootNode READ rootNode WRITE setRootNode NOTIFY rootNodeChanged)
+ Q_PROPERTY(QQuick3DViewport *view3D READ view3D WRITE setView3D NOTIFY view3DChanged)
+ Q_PROPERTY(bool isEmpty READ isEmpty NOTIFY isEmptyChanged)
+
+public:
+ SelectionBoxGeometry();
+ ~SelectionBoxGeometry() override;
+
+ QQuick3DNode *targetNode() const;
+ QQuick3DNode *rootNode() const;
+ QQuick3DViewport *view3D() const;
+ bool isEmpty() const;
+
+ QSSGBounds3 bounds() const;
+
+public Q_SLOTS:
+ void setTargetNode(QQuick3DNode *targetNode);
+ void setRootNode(QQuick3DNode *rootNode);
+ void setView3D(QQuick3DViewport *view);
+
+Q_SIGNALS:
+ void targetNodeChanged();
+ void rootNodeChanged();
+ void view3DChanged();
+ void isEmptyChanged();
+
+protected:
+ QSSGRenderGraphObject *updateSpatialNode(QSSGRenderGraphObject *node) override;
+
+private:
+ void getBounds(QQuick3DNode *node, QByteArray &vertexData, QByteArray &indexData,
+ QVector3D &minBounds, QVector3D &maxBounds, const QMatrix4x4 &transform);
+ void appendVertexData(QByteArray &vertexData, QByteArray &indexData,
+ const QVector3D &minBounds, const QVector3D &maxBounds);
+
+ QQuick3DNode *m_targetNode = nullptr;
+ QQuick3DViewport *m_view3D = nullptr;
+ QQuick3DNode *m_rootNode = nullptr;
+ bool m_isEmpty = true;
+ QVector<QMetaObject::Connection> m_connections;
+ QSSGBounds3 m_bounds;
+};
+
+}
+}
+
+QML_DECLARE_TYPE(QmlDesigner::Internal::SelectionBoxGeometry)
+
+#endif // QUICK3D_MODULE
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
index 2cd59af460..95360eaa4f 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
@@ -62,10 +62,11 @@
#include <drop3dlibraryitemcommand.h>
#include "dummycontextobject.h"
-#include "../editor3d/cameracontrolhelper.h"
+#include "../editor3d/generalhelper.h"
#include "../editor3d/mousearea3d.h"
#include "../editor3d/camerageometry.h"
#include "../editor3d/gridgeometry.h"
+#include "../editor3d/selectionboxgeometry.h"
#include <designersupportdelegate.h>
@@ -104,13 +105,13 @@ bool Qt5InformationNodeInstanceServer::eventFilter(QObject *, QEvent *event)
QObject *Qt5InformationNodeInstanceServer::createEditView3D(QQmlEngine *engine)
{
- auto helper = new QmlDesigner::Internal::CameraControlHelper();
- engine->rootContext()->setContextProperty("designStudioNativeCameraControlHelper", helper);
-
#ifdef QUICK3D_MODULE
+ auto helper = new QmlDesigner::Internal::GeneralHelper();
+ engine->rootContext()->setContextProperty("_generalHelper", helper);
qmlRegisterType<QmlDesigner::Internal::MouseArea3D>("MouseArea3D", 1, 0, "MouseArea3D");
qmlRegisterType<QmlDesigner::Internal::CameraGeometry>("CameraGeometry", 1, 0, "CameraGeometry");
qmlRegisterType<QmlDesigner::Internal::GridGeometry>("GridGeometry", 1, 0, "GridGeometry");
+ qmlRegisterType<QmlDesigner::Internal::SelectionBoxGeometry>("SelectionBoxGeometry", 1, 0, "SelectionBoxGeometry");
#endif
QQmlComponent component(engine, QUrl("qrc:/qtquickplugin/mockfiles/EditView3D.qml"));
@@ -136,7 +137,10 @@ QObject *Qt5InformationNodeInstanceServer::createEditView3D(QQmlEngine *engine)
surfaceFormat.setVersion(4, 1);
surfaceFormat.setProfile(QSurfaceFormat::CoreProfile);
window->setFormat(surfaceFormat);
+
+#ifdef QUICK3D_MODULE
helper->setParent(window);
+#endif
return window;
}
@@ -336,12 +340,24 @@ QObject *Qt5InformationNodeInstanceServer::findRootNodeOf3DViewport(
{
for (const ServerNodeInstance &instance : instanceList) {
if (instance.isSubclassOf("QQuick3DViewport")) {
+ QObject *rootObj = nullptr;
+ int viewChildCount = 0;
for (const ServerNodeInstance &child : instanceList) { /* Look for scene node */
/* The QQuick3DViewport always creates a root node.
* This root node contains the complete scene. */
- if (child.isSubclassOf("QQuick3DNode") && child.parent() == instance)
- return child.internalObject()->property("parent").value<QObject *>();
+ if (child.isSubclassOf("QQuick3DNode") && child.parent() == instance) {
+ // Implicit root node is not visible in editor, so there is often another node
+ // added below it that serves as the actual scene root node.
+ // If the found root is the only node child of the view, assume that is the case.
+ ++viewChildCount;
+ if (!rootObj)
+ rootObj = child.internalObject();
+ }
}
+ if (viewChildCount == 1)
+ return rootObj;
+ else if (rootObj)
+ return rootObj->property("parent").value<QObject *>();
}
}
return nullptr;
@@ -599,10 +615,8 @@ void Qt5InformationNodeInstanceServer::changeSelection(const ChangeSelectionComm
if (hasInstanceForId(id)) {
ServerNodeInstance instance = instanceForId(id);
QObject *object = nullptr;
- if (instance.isSubclassOf("QQuick3DModel") || instance.isSubclassOf("QQuick3DCamera")
- || instance.isSubclassOf("QQuick3DAbstractLight")) {
+ if (instance.isSubclassOf("QQuick3DNode"))
object = instance.internalObject();
- }
QMetaObject::invokeMethod(m_editView3D, "selectObject", Q_ARG(QVariant,
objectToVariant(object)));
return; // TODO: support multi-selection
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp
index 61b21b7810..db0f0f847f 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp
@@ -56,17 +56,7 @@ void Quick3DNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNo
InstanceContainer::NodeFlags flags)
{
ObjectNodeInstance::initialize(objectNodeInstance, flags);
-
-#ifdef QUICK3D_MODULE
- if (quick3DNode()) {
- QQuick3DObject::Type nodeType = quick3DNode()->type();
- if (nodeType == QQuick3DObject::Camera || nodeType == QQuick3DObject::Light
- || nodeType == QQuick3DObject::Model || nodeType == QQuick3DObject::Image
- || nodeType == QQuick3DObject::Text) {
- setPropertyVariant("pickable", true); // allow 3D objects to receive mouse clicks
- }
- }
-#endif
+ setPickable(true, true, false);
}
Qt5NodeInstanceServer *Quick3DNodeInstance::qt5NodeInstanceServer() const
@@ -83,6 +73,48 @@ QQuick3DNode *Quick3DNodeInstance::quick3DNode() const
#endif
}
+void Quick3DNodeInstance::setPickable(bool enable, bool checkParent, bool applyToChildren)
+{
+#ifdef QUICK3D_MODULE
+ auto node = quick3DNode();
+ if (node) {
+ QQuick3DObject::Type nodeType = node->type();
+ bool parentHidden = false;
+ if (checkParent) {
+ // First check if any parent node is already hidden. Never set pickable on that case.
+ auto parentNode = node->parentNode();
+ while (parentNode && !parentHidden) {
+ parentHidden = QQuick3DNodePrivate::get(parentNode)->m_isHiddenInEditor;
+ parentNode = parentNode->parentNode();
+ }
+
+ }
+ if (!parentHidden) {
+ if (applyToChildren) {
+ auto getQuick3DInstance = [this](QQuick3DObject *obj) -> Quick3DNodeInstance * {
+ if (nodeInstanceServer()->hasInstanceForObject(obj)) {
+ ServerNodeInstance instance = nodeInstanceServer()->instanceForObject(obj);
+ if (instance.isValid() && qobject_cast<QQuick3DNode *>(instance.internalObject()))
+ return static_cast<Quick3DNodeInstance *>(instance.internalInstance().data());
+ }
+ return nullptr;
+ };
+ const auto childItems = node->childItems();
+ for (auto childItem : childItems) {
+ if (auto quick3dInstance = getQuick3DInstance(childItem)) {
+ // Don't override explicit block in children
+ if (!QQuick3DNodePrivate::get(quick3dInstance->quick3DNode())->m_isHiddenInEditor)
+ quick3dInstance->setPickable(enable, false, true);
+ }
+ }
+ }
+ if (nodeType == QQuick3DObject::Model)
+ setPropertyVariant("pickable", enable); // allow 3D objects to receive mouse clicks
+ }
+ }
+#endif
+}
+
Quick3DNodeInstance::Pointer Quick3DNodeInstance::create(QObject *object)
{
Pointer instance(new Quick3DNodeInstance(object));
@@ -94,8 +126,12 @@ void Quick3DNodeInstance::setHideInEditor(bool b)
{
#ifdef QUICK3D_MODULE
QQuick3DNodePrivate *privateNode = QQuick3DNodePrivate::get(quick3DNode());
- if (privateNode)
+ if (privateNode) {
privateNode->setIsHiddenInEditor(b);
+
+ // Hidden objects should not be pickable
+ setPickable(!b, true, true);
+ }
#else
Q_UNUSED(b)
#endif
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h
index 96c44c4d52..27e2488eb3 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h
@@ -53,6 +53,7 @@ protected:
private:
Qt5NodeInstanceServer *qt5NodeInstanceServer() const;
QQuick3DNode *quick3DNode() const;
+ void setPickable(bool enable, bool checkParent, bool applyToChildren);
};
} // namespace Internal
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h
index 86003b51b6..c85ba9a2b8 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h
@@ -60,6 +60,7 @@ namespace Internal {
class GraphicsObjectNodeInstance;
class QmlStateNodeInstance;
class QuickItemNodeInstance;
+ class Quick3DNodeInstance;
}
class ServerNodeInstance
@@ -82,6 +83,7 @@ class ServerNodeInstance
friend class QmlDesigner::Internal::ObjectNodeInstance;
friend class QmlDesigner::Internal::QmlPropertyChangesNodeInstance;
friend class QmlDesigner::Internal::QmlStateNodeInstance;
+ friend class QmlDesigner::Internal::Quick3DNodeInstance;
public:
enum ComponentWrap {
diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc b/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc
index f818f23fd5..c4a49064b6 100644
--- a/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc
+++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc
@@ -8,6 +8,7 @@
<file>mockfiles/GenericBackend.qml</file>
<file>mockfiles/Dialog.qml</file>
<file>mockfiles/EditView3D.qml</file>
+ <file>mockfiles/EditCameraController.qml</file>
<file>mockfiles/Arrow.qml</file>
<file>mockfiles/AutoScaleHelper.qml</file>
<file>mockfiles/MoveGizmo.qml</file>
@@ -23,12 +24,17 @@
<file>mockfiles/ScaleRod.qml</file>
<file>mockfiles/ScaleGizmo.qml</file>
<file>mockfiles/ToolBarButton.qml</file>
+ <file>mockfiles/ToggleButton.qml</file>
<file>mockfiles/RotateGizmo.qml</file>
<file>mockfiles/RotateRing.qml</file>
+ <file>mockfiles/SelectionBox.qml</file>
+ <file>mockfiles/AxisHelper.qml</file>
+ <file>mockfiles/AxisHelperArm.qml</file>
<file>mockfiles/meshes/arrow.mesh</file>
<file>mockfiles/meshes/scalerod.mesh</file>
<file>mockfiles/meshes/ring.mesh</file>
<file>mockfiles/meshes/ringselect.mesh</file>
+ <file>mockfiles/meshes/axishelper.mesh</file>
<file>mockfiles/images/editor_camera.png</file>
<file>mockfiles/images/editor_camera@2x.png</file>
<file>mockfiles/images/light-pick-icon.png</file>
@@ -53,5 +59,27 @@
<file>mockfiles/images/scale_active@2x.png</file>
<file>mockfiles/images/scale_selected.png</file>
<file>mockfiles/images/scale_selected@2x.png</file>
+ <file>mockfiles/images/directional_light_gradient.png</file>
+ <file>mockfiles/images/directional_light_gradient@2x.png</file>
+ <file>mockfiles/images/point_light_gradient.png</file>
+ <file>mockfiles/images/point_light_gradient@2x.png</file>
+ <file>mockfiles/images/area_light_gradient.png</file>
+ <file>mockfiles/images/area_light_gradient@2x.png</file>
+ <file>mockfiles/images/fit_active.png</file>
+ <file>mockfiles/images/fit_active@2x.png</file>
+ <file>mockfiles/images/fit_selected.png</file>
+ <file>mockfiles/images/fit_selected@2x.png</file>
+ <file>mockfiles/images/local.png</file>
+ <file>mockfiles/images/local@2x.png</file>
+ <file>mockfiles/images/global.png</file>
+ <file>mockfiles/images/global@2x.png</file>
+ <file>mockfiles/images/ortho.png</file>
+ <file>mockfiles/images/ortho@2x.png</file>
+ <file>mockfiles/images/persp.png</file>
+ <file>mockfiles/images/persp@2x.png</file>
+ <file>mockfiles/images/edit_light_off.png</file>
+ <file>mockfiles/images/edit_light_off@2x.png</file>
+ <file>mockfiles/images/edit_light_on.png</file>
+ <file>mockfiles/images/edit_light_on@2x.png</file>
</qresource>
</RCC>
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml
index 6cbc8a77c0..a97923a032 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml
@@ -41,7 +41,6 @@ Section {
function getBackendValue(name)
{
- print(fontSection.fontName + "_" + name)
return backendValues[fontSection.fontName + "_" + name]
}
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml
index f8865e62cf..1c3dc46c15 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml
@@ -185,7 +185,9 @@ T.ComboBox {
StudioTheme.Values.maxComboBoxPopupHeight)
padding: StudioTheme.Values.border
margins: 0 // If not defined margin will be -1
- closePolicy: T.Popup.CloseOnEscape | T.Popup.CloseOnPressOutsideParent
+ closePolicy: T.Popup.CloseOnPressOutside | T.Popup.CloseOnPressOutsideParent
+ | T.Popup.CloseOnEscape | T.Popup.CloseOnReleaseOutside
+ | T.Popup.CloseOnReleaseOutsideParent
contentItem: ListView {
clip: true
@@ -242,7 +244,7 @@ T.ComboBox {
},
State {
name: "edit"
- when: myComboBox.edit && myComboBox.editable
+ when: myComboBox.edit && myComboBox.editable && !comboBoxPopup.opened
PropertyChanges {
target: myComboBox
wheelEnabled: true
@@ -250,12 +252,29 @@ T.ComboBox {
PropertyChanges {
target: comboBoxInput
selectByMouse: true
+ readOnly: false
}
PropertyChanges {
target: comboBoxBackground
color: StudioTheme.Values.themeInteraction
border.color: StudioTheme.Values.themeInteraction
}
+ StateChangeScript {
+ script: comboBoxPopup.close()
+ }
+ },
+ State {
+ name: "popup"
+ when: myComboBox.edit && comboBoxPopup.opened
+ PropertyChanges {
+ target: myComboBox
+ wheelEnabled: true
+ }
+ PropertyChanges {
+ target: comboBoxInput
+ selectByMouse: false
+ readOnly: true
+ }
}
]
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Menu.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Menu.qml
index 01a86847fc..773282958f 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Menu.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Menu.qml
@@ -1,3 +1,5 @@
+
+
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
@@ -22,7 +24,6 @@
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
-
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Templates 2.12 as T
@@ -43,10 +44,11 @@ T.Menu {
overlap: 1
padding: 0
- closePolicy: T.Popup.CloseOnPressOutside | T.Popup.CloseOnPressOutsideParent | T.Popup.CloseOnEscape
+ closePolicy: T.Popup.CloseOnPressOutside | T.Popup.CloseOnPressOutsideParent
+ | T.Popup.CloseOnEscape | T.Popup.CloseOnReleaseOutside
+ | T.Popup.CloseOnReleaseOutsideParent
- delegate: MenuItem {
- }
+ delegate: MenuItem {}
contentItem: ListView {
model: control.contentModel
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSliderPopup.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSliderPopup.qml
index fe83e82ee6..dd6be8cbc1 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSliderPopup.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSliderPopup.qml
@@ -33,7 +33,9 @@ T.Popup {
property T.Control myControl
dim: false
- closePolicy: T.Popup.CloseOnEscape | T.Popup.CloseOnPressOutsideParent
+ closePolicy: T.Popup.CloseOnPressOutside | T.Popup.CloseOnPressOutsideParent
+ | T.Popup.CloseOnEscape | T.Popup.CloseOnReleaseOutside
+ | T.Popup.CloseOnReleaseOutsideParent
background: Rectangle {
color: StudioTheme.Values.themeControlBackground
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBoxInput.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBoxInput.qml
index 72a713c282..98c592f112 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBoxInput.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBoxInput.qml
@@ -193,6 +193,7 @@ TextInput {
PropertyChanges {
target: mouseArea
cursorShape: Qt.PointingHandCursor
+ enabled: false
}
},
State {
diff --git a/src/plugins/clangcodemodel/test/clangbatchfileprocessor.cpp b/src/plugins/clangcodemodel/test/clangbatchfileprocessor.cpp
index 25d22bb1c1..8556c84b4b 100644
--- a/src/plugins/clangcodemodel/test/clangbatchfileprocessor.cpp
+++ b/src/plugins/clangcodemodel/test/clangbatchfileprocessor.cpp
@@ -237,7 +237,7 @@ bool OpenProjectCommand::run()
Project *project = openProjectSucceeded.project();
project->configureAsExampleProject();
- return CppTools::Tests::TestCase::waitUntilCppModelManagerIsAwareOf(project, timeOutInMs());
+ return CppTools::Tests::TestCase::waitUntilProjectIsFullyOpened(project, timeOutInMs());
}
Command::Ptr OpenProjectCommand::parse(BatchFileLineTokenizer &arguments,
diff --git a/src/plugins/clangtools/clangtidyclazyrunner.cpp b/src/plugins/clangtools/clangtidyclazyrunner.cpp
index bd909384d0..34a149c823 100644
--- a/src/plugins/clangtools/clangtidyclazyrunner.cpp
+++ b/src/plugins/clangtools/clangtidyclazyrunner.cpp
@@ -66,10 +66,6 @@ static QStringList clazyPluginArguments(const ClangDiagnosticConfig diagnosticCo
arguments << XclangArgs({"-add-plugin",
"clazy",
"-plugin-arg-clazy",
- "enable-all-fixits",
- "-plugin-arg-clazy",
- "no-autowrite-fixits",
- "-plugin-arg-clazy",
diagnosticConfig.clazyChecks()});
}
diff --git a/src/plugins/clangtools/clangtool.cpp b/src/plugins/clangtools/clangtool.cpp
index 607b78680c..780a38c4ff 100644
--- a/src/plugins/clangtools/clangtool.cpp
+++ b/src/plugins/clangtools/clangtool.cpp
@@ -33,6 +33,7 @@
#include "clangtoolsdiagnosticmodel.h"
#include "clangtoolsdiagnosticview.h"
#include "clangtoolslogfilereader.h"
+#include "clangtoolsplugin.h"
#include "clangtoolsprojectsettings.h"
#include "clangtoolssettings.h"
#include "clangtoolsutils.h"
@@ -399,6 +400,15 @@ ClangTool::ClangTool()
ApplyFixIts(diagnosticItems).apply(m_diagnosticModel);
});
+ // Open Project Settings
+ action = new QAction(this);
+ action->setIcon(Utils::Icons::SETTINGS_TOOLBAR.icon());
+ //action->setToolTip(tr("Open Project Settings")); // TODO: Uncomment in master.
+ connect(action, &QAction::triggered, []() {
+ ProjectExplorerPlugin::activateProjectPanel(Constants::PROJECT_PANEL_ID);
+ });
+ m_openProjectSettings = action;
+
ActionContainer *menu = ActionManager::actionContainer(Debugger::Constants::M_DEBUG_ANALYZER);
const QString toolTip = tr("Clang-Tidy and Clazy use a customized Clang executable from the "
"Clang project to search for diagnostics.");
@@ -424,6 +434,7 @@ ClangTool::ClangTool()
m_perspective.addToolBarAction(m_startAction);
m_perspective.addToolBarAction(m_startOnCurrentFileAction);
m_perspective.addToolBarAction(m_stopAction);
+ m_perspective.addToolBarAction(m_openProjectSettings);
m_perspective.addToolBarAction(m_loadExported);
m_perspective.addToolBarAction(m_clear);
m_perspective.addToolBarAction(m_goBack);
diff --git a/src/plugins/clangtools/clangtool.h b/src/plugins/clangtools/clangtool.h
index bde31d355d..d994a6b2f9 100644
--- a/src/plugins/clangtools/clangtool.h
+++ b/src/plugins/clangtools/clangtool.h
@@ -129,6 +129,7 @@ private:
Utils::FancyLineEdit *m_filterLineEdit = nullptr;
QToolButton *m_applyFixitsButton = nullptr;
+ QAction *m_openProjectSettings = nullptr;
QAction *m_goBack = nullptr;
QAction *m_goNext = nullptr;
QAction *m_loadExported = nullptr;
diff --git a/src/plugins/clangtools/clangtoolsconstants.h b/src/plugins/clangtools/clangtoolsconstants.h
index a3da1d78f5..8f09865b1c 100644
--- a/src/plugins/clangtools/clangtoolsconstants.h
+++ b/src/plugins/clangtools/clangtoolsconstants.h
@@ -28,6 +28,8 @@
namespace ClangTools {
namespace Constants {
+const char PROJECT_PANEL_ID[] = "ClangTools";
+
const char RUN_ON_PROJECT[] = "ClangTools.RunOnProject";
const char RUN_ON_CURRENT_FILE[] = "ClangTools.RunOnCurrentFile";
diff --git a/src/plugins/clangtools/clangtoolslogfilereader.cpp b/src/plugins/clangtools/clangtoolslogfilereader.cpp
index 1fe490a6bf..8c4211544b 100644
--- a/src/plugins/clangtools/clangtoolslogfilereader.cpp
+++ b/src/plugins/clangtools/clangtoolslogfilereader.cpp
@@ -347,7 +347,7 @@ public:
int extraOffset = 0)
: m_node(node)
, m_fileCache(fileCache)
- , m_filePath(asString(node["FilePath"]))
+ , m_filePath(QDir::cleanPath(asString(node["FilePath"])))
, m_fileOffsetKey(fileOffsetKey)
, m_extraOffset(extraOffset)
{}
diff --git a/src/plugins/clangtools/clangtoolsplugin.cpp b/src/plugins/clangtools/clangtoolsplugin.cpp
index cdcda4d3c6..b53901e95a 100644
--- a/src/plugins/clangtools/clangtoolsplugin.cpp
+++ b/src/plugins/clangtools/clangtoolsplugin.cpp
@@ -67,6 +67,13 @@ using namespace ProjectExplorer;
namespace ClangTools {
namespace Internal {
+static ProjectPanelFactory *m_projectPanelFactoryInstance = nullptr;
+
+ProjectPanelFactory *projectPanelFactory()
+{
+ return m_projectPanelFactoryInstance;
+}
+
class ClangToolsOptionsPage : public IOptionsPage
{
public:
@@ -123,8 +130,9 @@ bool ClangToolsPlugin::initialize(const QStringList &arguments, QString *errorSt
ActionManager::registerAction(d->clangTool.startOnCurrentFileAction(),
Constants::RUN_ON_CURRENT_FILE);
- auto panelFactory = new ProjectPanelFactory();
+ auto panelFactory = m_projectPanelFactoryInstance = new ProjectPanelFactory;
panelFactory->setPriority(100);
+ panelFactory->setId(Constants::PROJECT_PANEL_ID);
panelFactory->setDisplayName(tr("Clang Tools"));
panelFactory->setCreateWidgetFunction([](Project *project) { return new ProjectSettingsWidget(project); });
ProjectPanelFactory::registerFactory(panelFactory);
diff --git a/src/plugins/clangtools/clangtoolsplugin.h b/src/plugins/clangtools/clangtoolsplugin.h
index 7f24d79f4b..30c28b276b 100644
--- a/src/plugins/clangtools/clangtoolsplugin.h
+++ b/src/plugins/clangtools/clangtoolsplugin.h
@@ -27,9 +27,13 @@
#include <extensionsystem/iplugin.h>
+namespace ProjectExplorer { class ProjectPanelFactory; }
+
namespace ClangTools {
namespace Internal {
+ProjectExplorer::ProjectPanelFactory *projectPanelFactory();
+
class ClangToolsPlugin : public ExtensionSystem::IPlugin
{
Q_OBJECT
diff --git a/src/plugins/clangtools/clangtoolssettings.h b/src/plugins/clangtools/clangtoolssettings.h
index 36da00d293..aaa52011b1 100644
--- a/src/plugins/clangtools/clangtoolssettings.h
+++ b/src/plugins/clangtools/clangtoolssettings.h
@@ -34,7 +34,7 @@
namespace ClangTools {
namespace Internal {
-const char diagnosticConfigIdKey[] = "DiagnosticConfigId";
+const char diagnosticConfigIdKey[] = "DiagnosticConfig";
class RunSettings
{
diff --git a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp
index 63dfdac4c6..26e4bffdeb 100644
--- a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp
@@ -318,7 +318,7 @@ class CMakeGeneratorKitAspectWidget : public KitAspectWidget
public:
CMakeGeneratorKitAspectWidget(Kit *kit, const ::KitAspect *ki)
: KitAspectWidget(kit, ki),
- m_label(new QLabel),
+ m_label(new Utils::ElidingLabel),
m_changeButton(new QPushButton)
{
m_label->setToolTip(ki->description());
@@ -459,7 +459,7 @@ private:
}
bool m_ignoreChange = false;
- QLabel *m_label;
+ Utils::ElidingLabel *m_label;
QPushButton *m_changeButton;
CMakeTool *m_currentTool = nullptr;
};
diff --git a/src/plugins/cpptools/cpptoolstestcase.cpp b/src/plugins/cpptools/cpptoolstestcase.cpp
index b9ba701aeb..8040e3f811 100644
--- a/src/plugins/cpptools/cpptoolstestcase.cpp
+++ b/src/plugins/cpptools/cpptoolstestcase.cpp
@@ -226,22 +226,17 @@ QList<CPlusPlus::Document::Ptr> TestCase::waitForFilesInGlobalSnapshot(const QSt
return result;
}
-bool TestCase::waitUntilCppModelManagerIsAwareOf(Project *project, int timeOutInMs)
+bool TestCase::waitUntilProjectIsFullyOpened(Project *project, int timeOutInMs)
{
if (!project)
return false;
- QElapsedTimer t;
- t.start();
-
- CppModelManager *modelManager = CppModelManager::instance();
- forever {
- if (modelManager->projectInfo(project).isValid())
- return true;
- if (t.elapsed() > timeOutInMs)
- return false;
- QCoreApplication::processEvents();
- }
+ return QTest::qWaitFor(
+ [project]() {
+ return !project->isParsing()
+ && CppModelManager::instance()->projectInfo(project).isValid();
+ },
+ timeOutInMs);
}
bool TestCase::writeFile(const QString &filePath, const QByteArray &contents)
@@ -293,7 +288,7 @@ ProjectInfo ProjectOpenerAndCloser::open(const QString &projectFile, bool config
if (configureAsExampleProject)
project->configureAsExampleProject();
- if (TestCase::waitUntilCppModelManagerIsAwareOf(project)) {
+ if (TestCase::waitUntilProjectIsFullyOpened(project)) {
m_openProjects.append(project);
return CppModelManager::instance()->projectInfo(project);
}
diff --git a/src/plugins/cpptools/cpptoolstestcase.h b/src/plugins/cpptools/cpptoolstestcase.h
index 009a5a9c3e..d6e306d255 100644
--- a/src/plugins/cpptools/cpptoolstestcase.h
+++ b/src/plugins/cpptools/cpptoolstestcase.h
@@ -92,9 +92,8 @@ public:
static bool waitForProcessedEditorDocument(const QString &filePath, int timeOutInMs = 5000);
enum { defaultTimeOutInMs = 30 * 1000 /*= 30 secs*/ };
- static bool waitUntilCppModelManagerIsAwareOf(
- ProjectExplorer::Project *project,
- int timeOutInMs = defaultTimeOutInMs);
+ static bool waitUntilProjectIsFullyOpened(ProjectExplorer::Project *project,
+ int timeOutInMs = defaultTimeOutInMs);
static CPlusPlus::Document::Ptr waitForFileInGlobalSnapshot(
const QString &filePath,
int timeOutInMs = defaultTimeOutInMs);
diff --git a/src/plugins/designer/codemodelhelpers.cpp b/src/plugins/designer/codemodelhelpers.cpp
index f57f1081d2..7beed0874a 100644
--- a/src/plugins/designer/codemodelhelpers.cpp
+++ b/src/plugins/designer/codemodelhelpers.cpp
@@ -40,10 +40,10 @@
using namespace ProjectExplorer;
-typedef QMap<QString, QStringList> DependencyMap;
-typedef CPlusPlus::Document::Ptr DocumentPtr;
-typedef QList<CPlusPlus::Symbol *> SymbolList;
-typedef QList<DocumentPtr> DocumentPtrList;
+using DependencyMap = QMap<QString, QStringList>;
+using DocumentPtr = CPlusPlus::Document::Ptr;
+using SymbolList = QList<CPlusPlus::Symbol *>;
+using DocumentPtrList = QList<DocumentPtr>;
static const char setupUiC[] = "setupUi";
diff --git a/src/plugins/designer/cpp/formclasswizard.cpp b/src/plugins/designer/cpp/formclasswizard.cpp
index 88c1b5da4c..9b878cf32c 100644
--- a/src/plugins/designer/cpp/formclasswizard.cpp
+++ b/src/plugins/designer/cpp/formclasswizard.cpp
@@ -58,14 +58,14 @@ QString FormClassWizard::formSuffix() const
Core::BaseFileWizard *FormClassWizard::create(QWidget *parent, const Core::WizardDialogParameters &parameters) const
{
- FormClassWizardDialog *wizardDialog = new FormClassWizardDialog(this, parent);
+ auto wizardDialog = new FormClassWizardDialog(this, parent);
wizardDialog->setPath(parameters.defaultPath());
return wizardDialog;
}
Core::GeneratedFiles FormClassWizard::generateFiles(const QWizard *w, QString *errorMessage) const
{
- const FormClassWizardDialog *wizardDialog = qobject_cast<const FormClassWizardDialog *>(w);
+ auto wizardDialog = qobject_cast<const FormClassWizardDialog *>(w);
const Designer::FormClassWizardParameters params = wizardDialog->parameters();
if (params.uiTemplate.isEmpty()) {
@@ -90,7 +90,8 @@ Core::GeneratedFiles FormClassWizard::generateFiles(const QWizard *w, QString *e
uiFile.setContents(params.uiTemplate);
uiFile.setAttributes(Core::GeneratedFile::OpenEditorAttribute);
- QString source, header;
+ QString source;
+ QString header;
QtDesignerFormClassCodeGenerator::generateCpp(params, &header, &source);
sourceFile.setContents(source);
diff --git a/src/plugins/designer/formeditorplugin.cpp b/src/plugins/designer/formeditorplugin.cpp
index 06be563702..9a912ac68e 100644
--- a/src/plugins/designer/formeditorplugin.cpp
+++ b/src/plugins/designer/formeditorplugin.cpp
@@ -105,7 +105,7 @@ bool FormEditorPlugin::initialize(const QStringList &arguments, QString *error)
// Ensure that loading designer translations is done before FormEditorW is instantiated
const QString locale = ICore::userInterfaceLanguage();
if (!locale.isEmpty()) {
- QTranslator *qtr = new QTranslator(this);
+ auto qtr = new QTranslator(this);
const QString &creatorTrPath = ICore::resourcePath() + "/translations";
const QString &qtTrPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
const QString &trFile = "designer_" + locale;
diff --git a/src/plugins/designer/formeditorstack.cpp b/src/plugins/designer/formeditorstack.cpp
index f109138cb3..65c89fc359 100644
--- a/src/plugins/designer/formeditorstack.cpp
+++ b/src/plugins/designer/formeditorstack.cpp
@@ -92,7 +92,7 @@ void FormEditorStack::add(const EditorData &data)
// Since we have 1 pixel splitters we enforce no frame
// on the content widget
- if (QFrame *frame = qobject_cast<QFrame*>(data.widgetHost))
+ if (auto frame = qobject_cast<QFrame*>(data.widgetHost))
frame->setFrameStyle(QFrame::NoFrame);
}
@@ -122,7 +122,7 @@ EditorData FormEditorStack::activeEditor() const
if (index >= 0)
return m_formEditors.at(index);
}
- return EditorData();
+ return {};
}
SharedTools::WidgetHost *FormEditorStack::formWindowEditorForFormWindow(const QDesignerFormWindowInterface *fw) const
@@ -173,7 +173,7 @@ void FormEditorStack::formSizeChanged(int w, int h)
// Handle main container resize.
if (Designer::Constants::Internal::debug)
qDebug() << Q_FUNC_INFO << w << h;
- if (const SharedTools::WidgetHost *wh = qobject_cast<const SharedTools::WidgetHost *>(sender())) {
+ if (auto wh = qobject_cast<const SharedTools::WidgetHost *>(sender())) {
wh->formWindow()->setDirty(true);
static const QString geometry = "geometry";
m_designerCore->propertyEditor()->setPropertyValue(geometry, QRect(0,0,w,h) );
diff --git a/src/plugins/designer/formeditorw.cpp b/src/plugins/designer/formeditorw.cpp
index 36db2e05ba..d7df1c8e85 100644
--- a/src/plugins/designer/formeditorw.cpp
+++ b/src/plugins/designer/formeditorw.cpp
@@ -115,7 +115,7 @@ namespace Internal {
class DesignerXmlEditorWidget : public TextEditor::TextEditorWidget
{
public:
- DesignerXmlEditorWidget() {}
+ using TextEditorWidget::TextEditorWidget;
void finalizeInitialization() override
{
@@ -196,7 +196,7 @@ public:
QDesignerFormEditorInterface *m_formeditor = nullptr;
QtCreatorIntegration *m_integration = nullptr;
QDesignerFormWindowManagerInterface *m_fwm = nullptr;
- FormEditorW::InitializationStage m_initStage;
+ FormEditorW::InitializationStage m_initStage = FormEditorW::RegisterPlugins;
QWidget *m_designerSubWindows[DesignerSubWindowCount];
@@ -229,8 +229,7 @@ static FormEditorData *d = nullptr;
static FormEditorW *m_instance = nullptr;
FormEditorData::FormEditorData() :
- m_formeditor(QDesignerComponents::createFormEditor(nullptr)),
- m_initStage(FormEditorW::RegisterPlugins)
+ m_formeditor(QDesignerComponents::createFormEditor(nullptr))
{
if (Designer::Constants::Internal::debug)
qDebug() << Q_FUNC_INFO;
@@ -409,19 +408,18 @@ void FormEditorData::fullInit()
m_modeWidget = new QWidget;
m_modeWidget->setObjectName("DesignerModeWidget");
- QVBoxLayout *layout = new QVBoxLayout;
+ auto layout = new QVBoxLayout(m_modeWidget);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->addWidget(m_toolBar);
// Avoid mode switch to 'Edit' mode when the application started by
// 'Run' in 'Design' mode emits output.
- MiniSplitter *splitter = new MiniSplitter(Qt::Vertical);
+ auto splitter = new MiniSplitter(Qt::Vertical);
splitter->addWidget(m_editorWidget);
QWidget *outputPane = new OutputPanePlaceHolder(Core::Constants::MODE_DESIGN, splitter);
outputPane->setObjectName("DesignerOutputPanePlaceHolder");
splitter->addWidget(outputPane);
layout->addWidget(splitter);
- m_modeWidget->setLayout(layout);
Context designerContexts = m_contexts;
designerContexts.add(Core::Constants::C_EDITORMANAGER);
@@ -648,9 +646,8 @@ void FormEditorData::setupActions()
QToolBar *FormEditorData::createEditorToolBar() const
{
QToolBar *editorToolBar = new QToolBar;
- const QList<Id>::const_iterator cend = m_toolActionIds.constEnd();
- for (QList<Id>::const_iterator it = m_toolActionIds.constBegin(); it != cend; ++it) {
- Command *cmd = ActionManager::command(*it);
+ for (const auto &id : m_toolActionIds) {
+ Command *cmd = ActionManager::command(id);
QTC_ASSERT(cmd, continue);
QAction *action = cmd->action();
if (!action->icon().isNull()) // Simplify grid has no action yet
@@ -735,7 +732,7 @@ QAction *FormEditorData::createEditModeAction(QActionGroup *ag,
const QString &iconName,
const QString &keySequence)
{
- QAction *rc = new QAction(actionName, ag);
+ auto rc = new QAction(actionName, ag);
rc->setCheckable(true);
if (!iconName.isEmpty())
rc->setIcon(designerIcon(iconName));
@@ -774,7 +771,7 @@ IEditor *FormEditorData::createEditor()
QTC_ASSERT(form, return nullptr);
QObject::connect(form, &QDesignerFormWindowInterface::toolChanged, [this] (int i) { toolChanged(i); });
- SharedTools::WidgetHost *widgetHost = new SharedTools::WidgetHost( /* parent */ nullptr, form);
+ auto widgetHost = new SharedTools::WidgetHost( /* parent */ nullptr, form);
FormWindowEditor *formWindowEditor = m_xmlEditorFactory->create(form);
m_editorWidget->add(widgetHost, formWindowEditor);
diff --git a/src/plugins/designer/formtemplatewizardpage.cpp b/src/plugins/designer/formtemplatewizardpage.cpp
index 3387ec6395..738a70285d 100644
--- a/src/plugins/designer/formtemplatewizardpage.cpp
+++ b/src/plugins/designer/formtemplatewizardpage.cpp
@@ -60,8 +60,7 @@ Utils::WizardPage *FormPageFactory::create(ProjectExplorer::JsonWizard *wizard,
QTC_ASSERT(canCreate(typeId), return nullptr);
- FormTemplateWizardPage *page = new FormTemplateWizardPage;
- return page;
+ return new FormTemplateWizardPage;
}
bool FormPageFactory::validateData(Core::Id typeId, const QVariant &data, QString *errorMessage)
diff --git a/src/plugins/designer/formwindoweditor.cpp b/src/plugins/designer/formwindoweditor.cpp
index b75bad127f..27dfb06889 100644
--- a/src/plugins/designer/formwindoweditor.cpp
+++ b/src/plugins/designer/formwindoweditor.cpp
@@ -44,9 +44,7 @@ FormWindowEditor::FormWindowEditor()
addContext(Designer::Constants::C_DESIGNER_XML_EDITOR);
}
-FormWindowEditor::~FormWindowEditor()
-{
-}
+FormWindowEditor::~FormWindowEditor() = default;
QWidget *FormWindowEditor::toolBar()
{
diff --git a/src/plugins/designer/formwindowfile.cpp b/src/plugins/designer/formwindowfile.cpp
index 2a3b77df5d..176cf41741 100644
--- a/src/plugins/designer/formwindowfile.cpp
+++ b/src/plugins/designer/formwindowfile.cpp
@@ -84,7 +84,7 @@ Core::IDocument::OpenResult FormWindowFile::open(QString *errorString, const QSt
Utils::TextFileFormat::ReadResult readResult = read(absfileName, &contents, errorString);
if (readResult == Utils::TextFileFormat::ReadEncodingError)
return OpenResult::CannotHandle;
- else if (readResult != Utils::TextFileFormat::ReadSuccess)
+ if (readResult != Utils::TextFileFormat::ReadSuccess)
return OpenResult::ReadError;
form->setFileName(absfileName);
diff --git a/src/plugins/designer/qtcreatorintegration.cpp b/src/plugins/designer/qtcreatorintegration.cpp
index 4a760ff65e..3775642529 100644
--- a/src/plugins/designer/qtcreatorintegration.cpp
+++ b/src/plugins/designer/qtcreatorintegration.cpp
@@ -218,18 +218,18 @@ static const Class *findClass(const Namespace *parentNameSpace, const LookupCont
static Function *findDeclaration(const Class *cl, const QString &functionName)
{
const QString funName = QString::fromUtf8(QMetaObject::normalizedSignature(functionName.toUtf8()));
- const unsigned mCount = cl->memberCount();
+ const int mCount = cl->memberCount();
// we are interested only in declarations (can be decl of function or of a field)
// we are only interested in declarations of functions
const Overview overview;
- for (unsigned j = 0; j < mCount; ++j) { // go through all members
+ for (int j = 0; j < mCount; ++j) { // go through all members
if (Declaration *decl = cl->memberAt(j)->asDeclaration())
if (Function *fun = decl->type()->asFunctionType()) {
// Format signature
QString memberFunction = overview.prettyName(fun->name());
memberFunction += '(';
- const uint aCount = fun->argumentCount();
- for (uint i = 0; i < aCount; i++) { // we build argument types string
+ const int aCount = fun->argumentCount();
+ for (int i = 0; i < aCount; i++) { // we build argument types string
const Argument *arg = fun->argumentAt(i)->asArgument();
if (i > 0)
memberFunction += ',';
@@ -350,7 +350,7 @@ static QString addConstRefIfNeeded(const QString &argument)
"unsigned", "qint64", "quint64"});
for (int i = 0; i < nonConstRefs.count(); i++) {
- const QString nonConstRef = nonConstRefs.at(i);
+ const QString &nonConstRef = nonConstRefs.at(i);
if (argument == nonConstRef || argument.startsWith(nonConstRef + ' '))
return argument;
}
@@ -411,7 +411,7 @@ static QString addParameterNames(const QString &functionSignature, const QString
// included files (going down [maxIncludeDepth] includes) and return a pair
// of <Class*, Document>.
-typedef QPair<const Class *, Document::Ptr> ClassDocumentPtrPair;
+using ClassDocumentPtrPair = QPair<const Class *, Document::Ptr>;
static ClassDocumentPtrPair
findClassRecursively(const LookupContext &context, const QString &className,
@@ -431,7 +431,7 @@ static ClassDocumentPtrPair
for (const QString &include : includedFiles) {
const Snapshot::const_iterator it = docTable.find(include);
if (it != docTable.end()) {
- const Document::Ptr includeDoc = it.value();
+ const Document::Ptr &includeDoc = it.value();
LookupContext context(includeDoc, docTable);
const ClassDocumentPtrPair irc = findClassRecursively(context, className,
recursionMaxIncludeDepth, namespaceName);
@@ -489,7 +489,7 @@ bool QtCreatorIntegration::navigateToSlot(const QString &objectName,
const QStringList &parameterNames,
QString *errorMessage)
{
- typedef QMap<int, Document::Ptr> DocumentMap;
+ using DocumentMap = QMap<int, Document::Ptr>;
const Utils::FilePath currentUiFile = FormEditorW::activeEditor()->document()->filePath();
#if 0
diff --git a/src/plugins/designer/resourcehandler.cpp b/src/plugins/designer/resourcehandler.cpp
index 392b632a8f..f111e8dbf8 100644
--- a/src/plugins/designer/resourcehandler.cpp
+++ b/src/plugins/designer/resourcehandler.cpp
@@ -73,10 +73,7 @@ void ResourceHandler::ensureInitialized()
qDebug() << "ResourceHandler::ensureInitialized() origPaths=" << m_originalUiQrcPaths;
}
-ResourceHandler::~ResourceHandler()
-{
-
-}
+ResourceHandler::~ResourceHandler() = default;
void ResourceHandler::updateResourcesHelper(bool updateProjectResources)
{
diff --git a/src/plugins/mcusupport/mcusupportoptions.cpp b/src/plugins/mcusupport/mcusupportoptions.cpp
index 10147d2ac3..431b91f1e2 100644
--- a/src/plugins/mcusupport/mcusupportoptions.cpp
+++ b/src/plugins/mcusupport/mcusupportoptions.cpp
@@ -267,7 +267,7 @@ static McuPackage *createQtForMCUsPackage()
McuPackage::tr("Qt for MCUs SDK"),
QDir::homePath(),
Utils::HostOsInfo::withExecutableSuffix("bin/qmltocpp"),
- "QtMCUSdk");
+ "QtForMCUsSdk");
result->setEnvironmentVariableName("Qul_DIR");
return result;
}
diff --git a/src/plugins/mcusupport/mcusupportoptionspage.cpp b/src/plugins/mcusupport/mcusupportoptionspage.cpp
index 06bb9a86e6..c0d1c42afc 100644
--- a/src/plugins/mcusupport/mcusupportoptionspage.cpp
+++ b/src/plugins/mcusupport/mcusupportoptionspage.cpp
@@ -168,6 +168,9 @@ void McuSupportOptionsPage::apply()
QTC_ASSERT(m_options->armGccPackage, return);
QTC_ASSERT(m_options->qtForMCUsSdkPackage, return);
+ if (!widget()->isVisible())
+ return; // Only create/overwrite kits when this option page is shown
+
const McuTarget *mcuTarget = m_widget->currentMcuTarget();
if (!mcuTarget)
return;
diff --git a/src/plugins/mcusupport/mcusupportplugin.cpp b/src/plugins/mcusupport/mcusupportplugin.cpp
index 68ec688c5f..d6b2dd427a 100644
--- a/src/plugins/mcusupport/mcusupportplugin.cpp
+++ b/src/plugins/mcusupport/mcusupportplugin.cpp
@@ -45,8 +45,8 @@ class McuSupportPluginPrivate
{
public:
McuSupportDeviceFactory deviceFactory;
- EmrunRunConfigurationFactory emrunRunConfigurationFactory;
- RunWorkerFactory emrunRunWorkerFactory{
+ McuSupportRunConfigurationFactory runConfigurationFactory;
+ RunWorkerFactory runWorkerFactory{
makeFlashAndRunWorker(),
{ProjectExplorer::Constants::NORMAL_RUN_MODE},
{Constants::RUNCONFIGURATION}
diff --git a/src/plugins/mcusupport/mcusupportrunconfiguration.cpp b/src/plugins/mcusupport/mcusupportrunconfiguration.cpp
index 49e2d798db..88dbf8349b 100644
--- a/src/plugins/mcusupport/mcusupportrunconfiguration.cpp
+++ b/src/plugins/mcusupport/mcusupportrunconfiguration.cpp
@@ -103,7 +103,7 @@ RunWorkerFactory::WorkerCreator makeFlashAndRunWorker()
return RunWorkerFactory::make<FlashAndRunWorker>();
}
-EmrunRunConfigurationFactory::EmrunRunConfigurationFactory()
+McuSupportRunConfigurationFactory::McuSupportRunConfigurationFactory()
: FixedRunConfigurationFactory(FlashAndRunConfiguration::tr("Flash and run"))
{
registerRunConfiguration<FlashAndRunConfiguration>(Constants::RUNCONFIGURATION);
diff --git a/src/plugins/mcusupport/mcusupportrunconfiguration.h b/src/plugins/mcusupport/mcusupportrunconfiguration.h
index b53eea03a4..704c8c9c90 100644
--- a/src/plugins/mcusupport/mcusupportrunconfiguration.h
+++ b/src/plugins/mcusupport/mcusupportrunconfiguration.h
@@ -31,10 +31,10 @@
namespace McuSupport {
namespace Internal {
-class EmrunRunConfigurationFactory : public ProjectExplorer::FixedRunConfigurationFactory
+class McuSupportRunConfigurationFactory : public ProjectExplorer::FixedRunConfigurationFactory
{
public:
- EmrunRunConfigurationFactory();
+ McuSupportRunConfigurationFactory();
};
class FlashAndRunConfiguration : public ProjectExplorer::RunConfiguration
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index 4d04a7da68..6a186b380c 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -3917,6 +3917,12 @@ void ProjectExplorerPlugin::updateActions()
dd->updateActions();
}
+void ProjectExplorerPlugin::activateProjectPanel(Core::Id panelId)
+{
+ Core::ModeManager::activateMode(Constants::MODE_SESSION);
+ dd->m_proWindow->activateProjectPanel(panelId);
+}
+
QList<QPair<QString, QString> > ProjectExplorerPlugin::recentProjects()
{
return dd->recentProjects();
diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h
index c2dffd4f6f..d7de49c83b 100644
--- a/src/plugins/projectexplorer/projectexplorer.h
+++ b/src/plugins/projectexplorer/projectexplorer.h
@@ -172,6 +172,8 @@ public:
static void updateActions();
+ static void activateProjectPanel(Core::Id panelId);
+
signals:
void finishedInitialization();
diff --git a/src/plugins/projectexplorer/projectpanelfactory.cpp b/src/plugins/projectexplorer/projectpanelfactory.cpp
index d734b8d336..c4eaef05b4 100644
--- a/src/plugins/projectexplorer/projectpanelfactory.cpp
+++ b/src/plugins/projectexplorer/projectpanelfactory.cpp
@@ -80,6 +80,16 @@ void ProjectPanelFactory::destroyFactories()
s_factories.clear();
}
+Core::Id ProjectPanelFactory::id() const
+{
+ return m_id;
+}
+
+void ProjectPanelFactory::setId(Core::Id id)
+{
+ m_id = id;
+}
+
QString ProjectPanelFactory::icon() const
{
return m_icon;
diff --git a/src/plugins/projectexplorer/projectpanelfactory.h b/src/plugins/projectexplorer/projectpanelfactory.h
index 27e643b0ed..6d03125398 100644
--- a/src/plugins/projectexplorer/projectpanelfactory.h
+++ b/src/plugins/projectexplorer/projectpanelfactory.h
@@ -30,6 +30,8 @@
#include "panelswidget.h"
#include "projectwindow.h"
+#include <coreplugin/id.h>
+
#include <utils/treemodel.h>
#include <functional>
@@ -44,6 +46,9 @@ class PROJECTEXPLORER_EXPORT ProjectPanelFactory
public:
ProjectPanelFactory();
+ Core::Id id() const;
+ void setId(Core::Id id);
+
// simple properties
QString displayName() const;
void setDisplayName(const QString &name);
@@ -78,6 +83,7 @@ private:
friend class ProjectExplorerPlugin;
static void destroyFactories();
+ Core::Id m_id;
int m_priority = 0;
QString m_displayName;
SupportsFunction m_supportsFunction;
diff --git a/src/plugins/projectexplorer/projectwindow.cpp b/src/plugins/projectexplorer/projectwindow.cpp
index 267a8626b9..3314b78dde 100644
--- a/src/plugins/projectexplorer/projectwindow.cpp
+++ b/src/plugins/projectexplorer/projectwindow.cpp
@@ -88,6 +88,8 @@ public:
Qt::ItemFlags flags(int column) const override;
bool setData(int column, const QVariant &, int role) override;
+ ProjectPanelFactory *factory() const { return m_factory; }
+
protected:
ProjectPanelFactory *m_factory = nullptr;
QPointer<Project> m_project;
@@ -285,6 +287,13 @@ public:
return activeItem ? activeItem->index() : QModelIndex();
}
+ TreeItem *itemForProjectPanel(Core::Id panelId)
+ {
+ return m_miscItem->findChildAtLevel(1, [panelId](const TreeItem *item){
+ return static_cast<const MiscSettingsPanelItem *>(item)->factory()->id() == panelId;
+ });
+ }
+
private:
int m_currentChildIndex = 0; // Start with Build & Run.
Project *m_project = nullptr;
@@ -509,6 +518,14 @@ public:
item->setData(0, QVariant(), ItemActivatedDirectlyRole);
}
+ void activateProjectPanel(Core::Id panelId)
+ {
+ if (ProjectItem *projectItem = m_projectsModel.rootItem()->childAt(0)) {
+ if (TreeItem *item = projectItem->itemForProjectPanel(panelId))
+ itemActivated(item->index());
+ }
+ }
+
void openContextMenu(const QPoint &pos)
{
QMenu menu;
@@ -618,6 +635,11 @@ ProjectWindow::ProjectWindow()
setContextMenuPolicy(Qt::CustomContextMenu);
}
+void ProjectWindow::activateProjectPanel(Core::Id panelId)
+{
+ d->activateProjectPanel(panelId);
+}
+
ProjectWindow::~ProjectWindow() = default;
QSize SelectorDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
diff --git a/src/plugins/projectexplorer/projectwindow.h b/src/plugins/projectexplorer/projectwindow.h
index 1aeeb882f9..01840951ab 100644
--- a/src/plugins/projectexplorer/projectwindow.h
+++ b/src/plugins/projectexplorer/projectwindow.h
@@ -31,6 +31,8 @@
#include <memory>
+namespace Core { class Id; }
+
namespace ProjectExplorer {
namespace Internal {
@@ -60,6 +62,8 @@ public:
ProjectWindow();
~ProjectWindow() override;
+ void activateProjectPanel(Core::Id panelId);
+
private:
const std::unique_ptr<ProjectWindowPrivate> d;
};
diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt
index 9d291c7bad..5689455b63 100644
--- a/src/plugins/qmldesigner/CMakeLists.txt
+++ b/src/plugins/qmldesigner/CMakeLists.txt
@@ -524,6 +524,8 @@ extend_qtc_plugin(QmlDesigner
extend_qtc_plugin(QmlDesigner
SOURCES_PREFIX components/bindingeditor
SOURCES bindingeditor.cpp bindingeditor.h
+ bindingeditordialog.cpp bindingeditordialog.h
+ bindingeditorwidget.cpp bindingeditorwidget.h
)
extend_qtc_plugin(QmlDesigner
diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp
index e56822b2a3..fe3871c6c1 100644
--- a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp
+++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp
@@ -26,393 +26,19 @@
#include "bindingeditor.h"
#include <qmldesignerplugin.h>
-
-#include "texteditorview.h"
-#include "texteditorwidget.h"
-#include <texteditor/texteditor.h>
-
#include <coreplugin/icore.h>
#include <coreplugin/actionmanager/actionmanager.h>
-#include <qmldesigner/qmldesignerplugin.h>
-#include <qmldesigner/qmldesignerconstants.h>
-#include <qmljseditor/qmljseditor.h>
-#include <qmljseditor/qmljseditorconstants.h>
-#include <qmljstools/qmljstoolsconstants.h>
-#include <qmljseditor/qmljscompletionassist.h>
-#include <qmljseditor/qmljshighlighter.h>
-#include <qmljseditor/qmljshoverhandler.h>
-#include <qmljstools/qmljsindenter.h>
-#include <qmljseditor/qmljsautocompleter.h>
-#include <qmljseditor/qmljseditordocument.h>
-#include <qmljseditor/qmljssemantichighlighter.h>
-#include <texteditor/textdocument.h>
-#include <texteditor/texteditoractionhandler.h>
-#include <texteditor/codeassist/assistinterface.h>
-#include <texteditor/codeassist/completionassistprovider.h>
-#include <texteditor/syntaxhighlighter.h>
-#include <projectexplorer/projectexplorerconstants.h>
-#include <coreplugin/editormanager/editormanager.h>
#include <metainfo.h>
#include <qmlmodelnodeproxy.h>
-#include <variantproperty.h>
-#include <bindingproperty.h>
#include <nodeabstractproperty.h>
#include <nodelistproperty.h>
#include <propertyeditorvalue.h>
-#include <QDialogButtonBox>
-#include <QPushButton>
-#include <QDebug>
-#include <QVBoxLayout>
-#include <QHBoxLayout>
-#include <QComboBox>
-#include <QPlainTextEdit>
-
namespace QmlDesigner {
static BindingEditor *s_lastBindingEditor = nullptr;
-const char BINDINGEDITOR_CONTEXT_ID[] = "BindingEditor.BindingEditorContext";
-
-BindingEditorWidget::BindingEditorWidget()
- : m_context(new BindingEditorContext(this))
-{
- Core::ICore::addContextObject(m_context);
-
- const Core::Context context(BINDINGEDITOR_CONTEXT_ID);
-
- /*
- * We have to register our own active auto completion shortcut, because the original short cut will
- * use the cursor position of the original editor in the editor manager.
- */
-
- m_completionAction = new QAction(tr("Trigger Completion"), this);
- Core::Command *command = Core::ActionManager::registerAction(
- m_completionAction, TextEditor::Constants::COMPLETE_THIS, context);
- command->setDefaultKeySequence(QKeySequence(
- Core::useMacShortcuts
- ? tr("Meta+Space")
- : tr("Ctrl+Space")));
-
- connect(m_completionAction, &QAction::triggered, [this]() {
- invokeAssist(TextEditor::Completion);
- });
-}
-
-BindingEditorWidget::~BindingEditorWidget()
-{
- unregisterAutoCompletion();
-
- Core::ICore::removeContextObject(m_context);
- delete m_context;
-}
-
-void BindingEditorWidget::unregisterAutoCompletion()
-{
- if (m_completionAction) {
- Core::ActionManager::unregisterAction(m_completionAction, TextEditor::Constants::COMPLETE_THIS);
- delete m_completionAction;
- m_completionAction = nullptr;
- }
-}
-
-bool BindingEditorWidget::event(QEvent *event)
-{
- if (event->type() == QEvent::KeyPress) {
- QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
- if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) {
- emit returnKeyClicked();
- return true;
- } else {
- return QmlJSEditor::QmlJSEditorWidget::event(event);
- }
- }
- return QmlJSEditor::QmlJSEditorWidget::event(event);
-}
-
-TextEditor::AssistInterface *BindingEditorWidget::createAssistInterface(
- TextEditor::AssistKind assistKind, TextEditor::AssistReason assistReason) const
-{
- Q_UNUSED(assistKind)
- return new QmlJSEditor::QmlJSCompletionAssistInterface(
- document(), position(), QString(),
- assistReason, qmljsdocument->semanticInfo());
-}
-
-class BindingDocument : public QmlJSEditor::QmlJSEditorDocument
-{
-public:
- BindingDocument()
- : QmlJSEditor::QmlJSEditorDocument(BINDINGEDITOR_CONTEXT_ID)
- , m_semanticHighlighter(new QmlJSEditor::SemanticHighlighter(this)) {}
- ~BindingDocument() { delete m_semanticHighlighter; }
-
-protected:
- void applyFontSettings()
- {
- TextDocument::applyFontSettings();
- m_semanticHighlighter->updateFontSettings(fontSettings());
- if (!isSemanticInfoOutdated())
- m_semanticHighlighter->rerun(semanticInfo());
- }
-
- void triggerPendingUpdates()
- {
- TextDocument::triggerPendingUpdates(); // calls applyFontSettings if necessary
- if (!isSemanticInfoOutdated())
- m_semanticHighlighter->rerun(semanticInfo());
- }
-
-private:
- QmlJSEditor::SemanticHighlighter *m_semanticHighlighter = nullptr;
-};
-
-class BindingEditorFactory : public TextEditor::TextEditorFactory
-{
-public:
- BindingEditorFactory()
- {
- setId(BINDINGEDITOR_CONTEXT_ID);
- setDisplayName(QCoreApplication::translate("OpenWith::Editors", BINDINGEDITOR_CONTEXT_ID));
-
-
- setDocumentCreator([]() { return new BindingDocument; });
- setEditorWidgetCreator([]() { return new BindingEditorWidget; });
- setEditorCreator([]() { return new QmlJSEditor::QmlJSEditor; });
- setAutoCompleterCreator([]() { return new QmlJSEditor::AutoCompleter; });
- setCommentDefinition(Utils::CommentDefinition::CppStyle);
- setParenthesesMatchingEnabled(true);
- setCodeFoldingSupported(true);
-
- addHoverHandler(new QmlJSEditor::QmlJSHoverHandler);
- setCompletionAssistProvider(new QmlJSEditor::QmlJSCompletionAssistProvider);
- }
-
- static void decorateEditor(TextEditor::TextEditorWidget *editor)
- {
- editor->textDocument()->setSyntaxHighlighter(new QmlJSEditor::QmlJSHighlighter);
- editor->textDocument()->setIndenter(new QmlJSEditor::Internal::Indenter(
- editor->textDocument()->document()));
- editor->setAutoCompleter(new QmlJSEditor::AutoCompleter);
- }
-};
-
-BindingEditorDialog::BindingEditorDialog(QWidget *parent)
- : QDialog(parent)
-{
- setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
- setWindowTitle(tr("Binding Editor"));
- setModal(false);
-
- setupJSEditor();
- setupUIComponents();
-
- QObject::connect(m_buttonBox, &QDialogButtonBox::accepted,
- this, &BindingEditorDialog::accepted);
- QObject::connect(m_buttonBox, &QDialogButtonBox::rejected,
- this, &BindingEditorDialog::rejected);
- QObject::connect(m_editorWidget, &BindingEditorWidget::returnKeyClicked,
- this, &BindingEditorDialog::accepted);
-
- QObject::connect(m_comboBoxItem, QOverload<int>::of(&QComboBox::currentIndexChanged),
- this, &BindingEditorDialog::itemIDChanged);
- QObject::connect(m_comboBoxProperty, QOverload<int>::of(&QComboBox::currentIndexChanged),
- this, &BindingEditorDialog::propertyIDChanged);
- QObject::connect(m_editorWidget, &QPlainTextEdit::textChanged,
- this, &BindingEditorDialog::textChanged);
-}
-
-BindingEditorDialog::~BindingEditorDialog()
-{
- delete m_editor; //m_editorWidget is handled by basetexteditor destructor
- delete m_buttonBox;
- delete m_comboBoxItem;
- delete m_comboBoxProperty;
- delete m_comboBoxLayout;
- delete m_verticalLayout;
-}
-
-void BindingEditorDialog::showWidget(int x, int y)
-{
- this->show();
- this->raise();
- move(QPoint(x, y));
- m_editorWidget->setFocus();
-}
-
-QString BindingEditorDialog::editorValue() const
-{
- if (!m_editorWidget)
- return {};
-
- return m_editorWidget->document()->toPlainText();
-}
-
-void BindingEditorDialog::setEditorValue(const QString &text)
-{
- if (m_editorWidget)
- m_editorWidget->document()->setPlainText(text);
-}
-
-void BindingEditorDialog::setAllBindings(QList<BindingEditorDialog::BindingOption> bindings)
-{
- m_lock = true;
-
- m_bindings = bindings;
- setupComboBoxes();
- adjustProperties();
-
- m_lock = false;
-}
-
-void BindingEditorDialog::adjustProperties()
-{
- const QString expression = editorValue();
- QString item;
- QString property;
- QStringList expressionElements = expression.split(".");
-
- if (!expressionElements.isEmpty()) {
- const int itemIndex = m_bindings.indexOf(expressionElements.at(0));
-
- if (itemIndex != -1) {
- item = expressionElements.at(0);
- expressionElements.removeFirst();
-
- if (!expressionElements.isEmpty()) {
- const QString sum = expressionElements.join(".");
-
- if (m_bindings.at(itemIndex).properties.contains(sum))
- property = sum;
- }
- }
- }
-
- if (item.isEmpty()) {
- item = undefinedString;
- if (m_comboBoxItem->findText(item) == -1)
- m_comboBoxItem->addItem(item);
- }
- m_comboBoxItem->setCurrentText(item);
-
- if (property.isEmpty()) {
- property = undefinedString;
- if (m_comboBoxProperty->findText(property) == -1)
- m_comboBoxProperty->addItem(property);
- }
- m_comboBoxProperty->setCurrentText(property);
-}
-
-void BindingEditorDialog::unregisterAutoCompletion()
-{
- if (m_editorWidget)
- m_editorWidget->unregisterAutoCompletion();
-}
-
-void BindingEditorDialog::setupJSEditor()
-{
- static BindingEditorFactory f;
- m_editor = qobject_cast<TextEditor::BaseTextEditor*>(f.createEditor());
- m_editorWidget = qobject_cast<BindingEditorWidget*>(m_editor->editorWidget());
-
- Core::Context context = m_editor->context();
- context.prepend(BINDINGEDITOR_CONTEXT_ID);
- m_editorWidget->m_context->setContext(context);
-
- auto qmlDesignerEditor = QmlDesignerPlugin::instance()->currentDesignDocument()->textEditor();
-
- m_editorWidget->qmljsdocument = qobject_cast<QmlJSEditor::QmlJSEditorWidget *>(
- qmlDesignerEditor->widget())->qmlJsEditorDocument();
-
-
- m_editorWidget->setLineNumbersVisible(false);
- m_editorWidget->setMarksVisible(false);
- m_editorWidget->setCodeFoldingSupported(false);
- m_editorWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
- m_editorWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
- m_editorWidget->setTabChangesFocus(true);
-}
-
-void BindingEditorDialog::setupUIComponents()
-{
- m_verticalLayout = new QVBoxLayout(this);
- m_comboBoxLayout = new QHBoxLayout;
-
- m_comboBoxItem = new QComboBox(this);
- m_comboBoxProperty = new QComboBox(this);
-
- m_editorWidget->setParent(this);
- m_editorWidget->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
- m_editorWidget->show();
-
- m_buttonBox = new QDialogButtonBox(this);
- m_buttonBox->setOrientation(Qt::Horizontal);
- m_buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
- m_buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
-
-
- m_comboBoxLayout->addWidget(m_comboBoxItem);
- m_comboBoxLayout->addWidget(m_comboBoxProperty);
-
- m_verticalLayout->addLayout(m_comboBoxLayout);
- m_verticalLayout->addWidget(m_editorWidget);
- m_verticalLayout->addWidget(m_buttonBox);
-
- this->resize(660, 240);
-}
-
-void BindingEditorDialog::setupComboBoxes()
-{
- m_comboBoxItem->clear();
- m_comboBoxProperty->clear();
-
- for (auto bind : m_bindings)
- m_comboBoxItem->addItem(bind.item);
-}
-
-void BindingEditorDialog::itemIDChanged(int itemID)
-{
- const QString previousProperty = m_comboBoxProperty->currentText();
- m_comboBoxProperty->clear();
-
- if (m_bindings.size() > itemID && itemID != -1) {
- m_comboBoxProperty->addItems(m_bindings.at(itemID).properties);
-
- if (!m_lock)
- if (m_comboBoxProperty->findText(previousProperty) != -1)
- m_comboBoxProperty->setCurrentText(previousProperty);
-
- const int undefinedItem = m_comboBoxItem->findText(undefinedString);
- if ((undefinedItem != -1) && (m_comboBoxItem->itemText(itemID) != undefinedString))
- m_comboBoxItem->removeItem(undefinedItem);
- }
-}
-
-void BindingEditorDialog::propertyIDChanged(int propertyID)
-{
- const int itemID = m_comboBoxItem->currentIndex();
-
- if (!m_lock)
- if (!m_comboBoxProperty->currentText().isEmpty() && (m_comboBoxProperty->currentText() != undefinedString))
- setEditorValue(m_comboBoxItem->itemText(itemID) + "." + m_comboBoxProperty->itemText(propertyID));
-
- const int undefinedProperty = m_comboBoxProperty->findText(undefinedString);
- if ((undefinedProperty != -1) && (m_comboBoxProperty->itemText(propertyID) != undefinedString))
- m_comboBoxProperty->removeItem(undefinedProperty);
-}
-
-void BindingEditorDialog::textChanged()
-{
- if (m_lock)
- return;
-
- m_lock = true;
- adjustProperties();
- m_lock = false;
-}
-
-
BindingEditor::BindingEditor(QObject *)
{
}
@@ -476,9 +102,16 @@ void BindingEditor::setBackendValue(const QVariant &backendValue)
m_backendValue = backendValue;
const QObject *backendValueObj = backendValue.value<QObject*>();
const PropertyEditorValue *propertyEditorValue = qobject_cast<const PropertyEditorValue *>(backendValueObj);
+ const ModelNode node = propertyEditorValue->modelNode();
+
+ if (node.isValid())
+ {
+ m_backendValueTypeName = node.metaInfo().propertyTypeName(propertyEditorValue->name());
- m_backendValueTypeName = propertyEditorValue->modelNode().metaInfo().propertyTypeName(
- propertyEditorValue->name());
+ if (m_backendValueTypeName == "alias" || m_backendValueTypeName == "unknown")
+ if (QmlObjectNode::isValidQmlObjectNode(node))
+ m_backendValueTypeName = QmlObjectNode(node).instanceType(propertyEditorValue->name());
+ }
emit backendValueChanged();
}
@@ -528,8 +161,16 @@ void BindingEditor::prepareBindings()
for (auto objnode : allNodes) {
BindingEditorDialog::BindingOption binding;
for (auto propertyName : objnode.metaInfo().propertyNames())
- if (m_backendValueTypeName == objnode.metaInfo().propertyTypeName(propertyName))
+ {
+ TypeName propertyTypeName = objnode.metaInfo().propertyTypeName(propertyName);
+
+ if ((propertyTypeName == "alias" || propertyTypeName == "unknown"))
+ if (QmlObjectNode::isValidQmlObjectNode(objnode))
+ propertyTypeName = QmlObjectNode(objnode).instanceType(propertyName);
+
+ if (m_backendValueTypeName == propertyTypeName)
binding.properties.append(QString::fromUtf8(propertyName));
+ }
if (!binding.properties.isEmpty() && objnode.hasId()) {
binding.item = objnode.displayName();
@@ -539,6 +180,16 @@ void BindingEditor::prepareBindings()
if (!bindings.isEmpty() && !m_dialog.isNull())
m_dialog->setAllBindings(bindings);
+
+ updateWindowName();
+}
+
+void BindingEditor::updateWindowName()
+{
+ if (!m_dialog.isNull() && !m_backendValueTypeName.isEmpty())
+ {
+ m_dialog->setWindowTitle(m_dialog->defaultTitle() + " [" + m_backendValueTypeName + "]");
+ }
}
QVariant BindingEditor::backendValue() const
@@ -556,5 +207,4 @@ QVariant BindingEditor::stateModelNode() const
return m_stateModelNode;
}
-
-}
+} // QmlDesigner namespace
diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.h b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.h
index a1deb74108..8f9a77baec 100644
--- a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.h
+++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.h
@@ -26,117 +26,16 @@
#ifndef BINDINGEDITOR_H
#define BINDINGEDITOR_H
-#include "texteditorview.h"
-#include <texteditor/texteditor.h>
-#include <QtQml>
+#include <bindingeditor/bindingeditordialog.h>
+#include <qmldesignercorelib_global.h>
+#include <modelnode.h>
-#include <QWidget>
-#include <QDialog>
+#include <QtQml>
+#include <QObject>
#include <QPointer>
-#include <qmljseditor/qmljseditor.h>
-
-#include <memory>
-
-QT_BEGIN_NAMESPACE
-class QTextEdit;
-class QDialogButtonBox;
-class QVBoxLayout;
-class QHBoxLayout;
-class QComboBox;
-QT_END_NAMESPACE
-
namespace QmlDesigner {
-class BindingEditorContext : public Core::IContext
-{
- Q_OBJECT
-
-public:
- BindingEditorContext(QWidget *parent) : Core::IContext(parent)
- {
- setWidget(parent);
- }
-};
-
-class BindingEditorWidget : public QmlJSEditor::QmlJSEditorWidget
-{
- Q_OBJECT
-
-public:
- BindingEditorWidget();
- ~BindingEditorWidget() override;
-
- void unregisterAutoCompletion();
-
- bool event(QEvent *event) override;
-
- TextEditor::AssistInterface *createAssistInterface(TextEditor::AssistKind assistKind,
- TextEditor::AssistReason assistReason) const override;
-
-signals:
- void returnKeyClicked();
-
-public:
- QmlJSEditor::QmlJSEditorDocument *qmljsdocument = nullptr;
- BindingEditorContext *m_context = nullptr;
- QAction *m_completionAction = nullptr;
-};
-
-class BindingEditorDialog : public QDialog
-{
- Q_OBJECT
-
-public:
- struct BindingOption
- {
- BindingOption() {}
- BindingOption(const QString &value) { item = value; }
-
- bool operator==(const QString &value) const { return value == item; }
- bool operator==(const BindingOption &value) const { return value.item == item; }
-
- QString item;
- QStringList properties;
- };
-
-public:
- BindingEditorDialog(QWidget *parent = nullptr);
- ~BindingEditorDialog() override;
-
- void showWidget(int x, int y);
-
- QString editorValue() const;
- void setEditorValue(const QString &text);
-
- void setAllBindings(QList<BindingEditorDialog::BindingOption> bindings);
- void adjustProperties();
-
- void unregisterAutoCompletion();
-
-private:
- void setupJSEditor();
- void setupUIComponents();
- void setupComboBoxes();
-
-public slots:
- void itemIDChanged(int);
- void propertyIDChanged(int);
- void textChanged();
-
-private:
- TextEditor::BaseTextEditor *m_editor = nullptr;
- BindingEditorWidget *m_editorWidget = nullptr;
- QVBoxLayout *m_verticalLayout = nullptr;
- QDialogButtonBox *m_buttonBox = nullptr;
- QHBoxLayout *m_comboBoxLayout = nullptr;
- QComboBox *m_comboBoxItem = nullptr;
- QComboBox *m_comboBoxProperty = nullptr;
- QList<BindingEditorDialog::BindingOption> m_bindings;
- bool m_lock = false;
- const QString undefinedString = {"[Undefined]"};
-};
-
class BindingEditor : public QObject
{
Q_OBJECT
@@ -163,6 +62,7 @@ public:
void setStateModelNode(const QVariant &stateModelNode);
Q_INVOKABLE void prepareBindings();
+ Q_INVOKABLE void updateWindowName();
signals:
void accepted();
diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.pri b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.pri
index 518905eb2a..88b2897c7b 100644
--- a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.pri
+++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.pri
@@ -1,3 +1,7 @@
HEADERS += $$PWD/bindingeditor.h
+HEADERS += $$PWD/bindingeditordialog.h
+HEADERS += $$PWD/bindingeditorwidget.h
SOURCES += $$PWD/bindingeditor.cpp
+SOURCES += $$PWD/bindingeditordialog.cpp
+SOURCES += $$PWD/bindingeditorwidget.cpp
diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditordialog.cpp b/src/plugins/qmldesigner/components/bindingeditor/bindingeditordialog.cpp
new file mode 100644
index 0000000000..51bd771843
--- /dev/null
+++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditordialog.cpp
@@ -0,0 +1,263 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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.
+**
+****************************************************************************/
+
+#include "bindingeditordialog.h"
+
+#include <texteditor/texteditor.h>
+
+#include <qmldesigner/qmldesignerplugin.h>
+#include <qmljseditor/qmljseditor.h>
+#include <qmljseditor/qmljseditordocument.h>
+#include <texteditor/textdocument.h>
+
+#include <QDialogButtonBox>
+#include <QPushButton>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QComboBox>
+#include <QPlainTextEdit>
+
+namespace QmlDesigner {
+
+BindingEditorDialog::BindingEditorDialog(QWidget *parent)
+ : QDialog(parent)
+{
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ setWindowTitle(defaultTitle());
+ setModal(false);
+
+ setupJSEditor();
+ setupUIComponents();
+
+ QObject::connect(m_buttonBox, &QDialogButtonBox::accepted,
+ this, &BindingEditorDialog::accepted);
+ QObject::connect(m_buttonBox, &QDialogButtonBox::rejected,
+ this, &BindingEditorDialog::rejected);
+ QObject::connect(m_editorWidget, &BindingEditorWidget::returnKeyClicked,
+ this, &BindingEditorDialog::accepted);
+
+ QObject::connect(m_comboBoxItem, QOverload<int>::of(&QComboBox::currentIndexChanged),
+ this, &BindingEditorDialog::itemIDChanged);
+ QObject::connect(m_comboBoxProperty, QOverload<int>::of(&QComboBox::currentIndexChanged),
+ this, &BindingEditorDialog::propertyIDChanged);
+ QObject::connect(m_editorWidget, &QPlainTextEdit::textChanged,
+ this, &BindingEditorDialog::textChanged);
+}
+
+BindingEditorDialog::~BindingEditorDialog()
+{
+ delete m_editor; //m_editorWidget is handled by basetexteditor destructor
+ delete m_buttonBox;
+ delete m_comboBoxItem;
+ delete m_comboBoxProperty;
+ delete m_comboBoxLayout;
+ delete m_verticalLayout;
+}
+
+void BindingEditorDialog::showWidget(int x, int y)
+{
+ this->show();
+ this->raise();
+ move(QPoint(x, y));
+ m_editorWidget->setFocus();
+}
+
+QString BindingEditorDialog::editorValue() const
+{
+ if (!m_editorWidget)
+ return {};
+
+ return m_editorWidget->document()->toPlainText();
+}
+
+void BindingEditorDialog::setEditorValue(const QString &text)
+{
+ if (m_editorWidget)
+ m_editorWidget->document()->setPlainText(text);
+}
+
+void BindingEditorDialog::setAllBindings(QList<BindingEditorDialog::BindingOption> bindings)
+{
+ m_lock = true;
+
+ m_bindings = bindings;
+ setupComboBoxes();
+ adjustProperties();
+
+ m_lock = false;
+}
+
+void BindingEditorDialog::adjustProperties()
+{
+ const QString expression = editorValue();
+ QString item;
+ QString property;
+ QStringList expressionElements = expression.split(".");
+
+ if (!expressionElements.isEmpty()) {
+ const int itemIndex = m_bindings.indexOf(expressionElements.at(0));
+
+ if (itemIndex != -1) {
+ item = expressionElements.at(0);
+ expressionElements.removeFirst();
+
+ if (!expressionElements.isEmpty()) {
+ const QString sum = expressionElements.join(".");
+
+ if (m_bindings.at(itemIndex).properties.contains(sum))
+ property = sum;
+ }
+ }
+ }
+
+ if (item.isEmpty()) {
+ item = undefinedString;
+ if (m_comboBoxItem->findText(item) == -1)
+ m_comboBoxItem->addItem(item);
+ }
+ m_comboBoxItem->setCurrentText(item);
+
+ if (property.isEmpty()) {
+ property = undefinedString;
+ if (m_comboBoxProperty->findText(property) == -1)
+ m_comboBoxProperty->addItem(property);
+ }
+ m_comboBoxProperty->setCurrentText(property);
+}
+
+void BindingEditorDialog::unregisterAutoCompletion()
+{
+ if (m_editorWidget)
+ m_editorWidget->unregisterAutoCompletion();
+}
+
+QString BindingEditorDialog::defaultTitle() const
+{
+ return titleString;
+}
+
+void BindingEditorDialog::setupJSEditor()
+{
+ static BindingEditorFactory f;
+ m_editor = qobject_cast<TextEditor::BaseTextEditor*>(f.createEditor());
+ m_editorWidget = qobject_cast<BindingEditorWidget*>(m_editor->editorWidget());
+
+ Core::Context context = m_editor->context();
+ context.prepend(BINDINGEDITOR_CONTEXT_ID);
+ m_editorWidget->m_context->setContext(context);
+
+ auto qmlDesignerEditor = QmlDesignerPlugin::instance()->currentDesignDocument()->textEditor();
+
+ m_editorWidget->qmljsdocument = qobject_cast<QmlJSEditor::QmlJSEditorWidget *>(
+ qmlDesignerEditor->widget())->qmlJsEditorDocument();
+
+
+ m_editorWidget->setLineNumbersVisible(false);
+ m_editorWidget->setMarksVisible(false);
+ m_editorWidget->setCodeFoldingSupported(false);
+ m_editorWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ m_editorWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ m_editorWidget->setTabChangesFocus(true);
+}
+
+void BindingEditorDialog::setupUIComponents()
+{
+ m_verticalLayout = new QVBoxLayout(this);
+ m_comboBoxLayout = new QHBoxLayout;
+
+ m_comboBoxItem = new QComboBox(this);
+ m_comboBoxProperty = new QComboBox(this);
+
+ m_editorWidget->setParent(this);
+ m_editorWidget->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
+ m_editorWidget->show();
+
+ m_buttonBox = new QDialogButtonBox(this);
+ m_buttonBox->setOrientation(Qt::Horizontal);
+ m_buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ m_buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
+
+
+ m_comboBoxLayout->addWidget(m_comboBoxItem);
+ m_comboBoxLayout->addWidget(m_comboBoxProperty);
+
+ m_verticalLayout->addLayout(m_comboBoxLayout);
+ m_verticalLayout->addWidget(m_editorWidget);
+ m_verticalLayout->addWidget(m_buttonBox);
+
+ this->resize(660, 240);
+}
+
+void BindingEditorDialog::setupComboBoxes()
+{
+ m_comboBoxItem->clear();
+ m_comboBoxProperty->clear();
+
+ for (auto bind : m_bindings)
+ m_comboBoxItem->addItem(bind.item);
+}
+
+void BindingEditorDialog::itemIDChanged(int itemID)
+{
+ const QString previousProperty = m_comboBoxProperty->currentText();
+ m_comboBoxProperty->clear();
+
+ if (m_bindings.size() > itemID && itemID != -1) {
+ m_comboBoxProperty->addItems(m_bindings.at(itemID).properties);
+
+ if (!m_lock)
+ if (m_comboBoxProperty->findText(previousProperty) != -1)
+ m_comboBoxProperty->setCurrentText(previousProperty);
+
+ const int undefinedItem = m_comboBoxItem->findText(undefinedString);
+ if ((undefinedItem != -1) && (m_comboBoxItem->itemText(itemID) != undefinedString))
+ m_comboBoxItem->removeItem(undefinedItem);
+ }
+}
+
+void BindingEditorDialog::propertyIDChanged(int propertyID)
+{
+ const int itemID = m_comboBoxItem->currentIndex();
+
+ if (!m_lock)
+ if (!m_comboBoxProperty->currentText().isEmpty() && (m_comboBoxProperty->currentText() != undefinedString))
+ setEditorValue(m_comboBoxItem->itemText(itemID) + "." + m_comboBoxProperty->itemText(propertyID));
+
+ const int undefinedProperty = m_comboBoxProperty->findText(undefinedString);
+ if ((undefinedProperty != -1) && (m_comboBoxProperty->itemText(propertyID) != undefinedString))
+ m_comboBoxProperty->removeItem(undefinedProperty);
+}
+
+void BindingEditorDialog::textChanged()
+{
+ if (m_lock)
+ return;
+
+ m_lock = true;
+ adjustProperties();
+ m_lock = false;
+}
+
+} // QmlDesigner namespace
diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditordialog.h b/src/plugins/qmldesigner/components/bindingeditor/bindingeditordialog.h
new file mode 100644
index 0000000000..6cb0c00361
--- /dev/null
+++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditordialog.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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.
+**
+****************************************************************************/
+
+#ifndef BINDINGEDITORDIALOG_H
+#define BINDINGEDITORDIALOG_H
+
+#include <bindingeditor/bindingeditorwidget.h>
+#include <texteditor/texteditor.h>
+
+#include <QDialog>
+
+QT_BEGIN_NAMESPACE
+class QDialogButtonBox;
+class QVBoxLayout;
+class QHBoxLayout;
+class QComboBox;
+QT_END_NAMESPACE
+
+namespace QmlDesigner {
+
+class BindingEditorDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ struct BindingOption
+ {
+ BindingOption() {}
+ BindingOption(const QString &value) { item = value; }
+
+ bool operator==(const QString &value) const { return value == item; }
+ bool operator==(const BindingOption &value) const { return value.item == item; }
+
+ QString item;
+ QStringList properties;
+ };
+
+public:
+ BindingEditorDialog(QWidget *parent = nullptr);
+ ~BindingEditorDialog() override;
+
+ void showWidget(int x, int y);
+
+ QString editorValue() const;
+ void setEditorValue(const QString &text);
+
+ void setAllBindings(QList<BindingEditorDialog::BindingOption> bindings);
+ void adjustProperties();
+
+ void unregisterAutoCompletion();
+
+ QString defaultTitle() const;
+
+private:
+ void setupJSEditor();
+ void setupUIComponents();
+ void setupComboBoxes();
+
+public slots:
+ void itemIDChanged(int);
+ void propertyIDChanged(int);
+ void textChanged();
+
+private:
+ TextEditor::BaseTextEditor *m_editor = nullptr;
+ BindingEditorWidget *m_editorWidget = nullptr;
+ QVBoxLayout *m_verticalLayout = nullptr;
+ QDialogButtonBox *m_buttonBox = nullptr;
+ QHBoxLayout *m_comboBoxLayout = nullptr;
+ QComboBox *m_comboBoxItem = nullptr;
+ QComboBox *m_comboBoxProperty = nullptr;
+ QList<BindingEditorDialog::BindingOption> m_bindings;
+ bool m_lock = false;
+ const QString undefinedString = {"[Undefined]"};
+ const QString titleString = {tr("Binding Editor")};
+};
+
+}
+
+#endif //BINDINGEDITORDIALOG_H
diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp b/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp
new file mode 100644
index 0000000000..6a058cb49a
--- /dev/null
+++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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.
+**
+****************************************************************************/
+
+#include "bindingeditorwidget.h"
+
+#include <coreplugin/icore.h>
+#include <coreplugin/actionmanager/actionmanager.h>
+#include <qmljseditor/qmljseditor.h>
+#include <qmljseditor/qmljscompletionassist.h>
+#include <qmljseditor/qmljshighlighter.h>
+#include <qmljseditor/qmljshoverhandler.h>
+#include <qmljseditor/qmljsautocompleter.h>
+#include <qmljseditor/qmljseditordocument.h>
+#include <qmljseditor/qmljssemantichighlighter.h>
+#include <qmljstools/qmljsindenter.h>
+
+#include <QAction>
+
+namespace QmlDesigner {
+
+BindingEditorWidget::BindingEditorWidget()
+ : m_context(new BindingEditorContext(this))
+{
+ Core::ICore::addContextObject(m_context);
+
+ const Core::Context context(BINDINGEDITOR_CONTEXT_ID);
+
+ /*
+ * We have to register our own active auto completion shortcut, because the original short cut will
+ * use the cursor position of the original editor in the editor manager.
+ */
+
+ m_completionAction = new QAction(tr("Trigger Completion"), this);
+ Core::Command *command = Core::ActionManager::registerAction(
+ m_completionAction, TextEditor::Constants::COMPLETE_THIS, context);
+ command->setDefaultKeySequence(QKeySequence(
+ Core::useMacShortcuts
+ ? tr("Meta+Space")
+ : tr("Ctrl+Space")));
+
+ connect(m_completionAction, &QAction::triggered, [this]() {
+ invokeAssist(TextEditor::Completion);
+ });
+}
+
+BindingEditorWidget::~BindingEditorWidget()
+{
+ unregisterAutoCompletion();
+
+ Core::ICore::removeContextObject(m_context);
+ delete m_context;
+}
+
+void BindingEditorWidget::unregisterAutoCompletion()
+{
+ if (m_completionAction) {
+ Core::ActionManager::unregisterAction(m_completionAction, TextEditor::Constants::COMPLETE_THIS);
+ delete m_completionAction;
+ m_completionAction = nullptr;
+ }
+}
+
+bool BindingEditorWidget::event(QEvent *event)
+{
+ if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
+ if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) {
+ emit returnKeyClicked();
+ return true;
+ } else {
+ return QmlJSEditor::QmlJSEditorWidget::event(event);
+ }
+ }
+ return QmlJSEditor::QmlJSEditorWidget::event(event);
+}
+
+TextEditor::AssistInterface *BindingEditorWidget::createAssistInterface(
+ TextEditor::AssistKind assistKind, TextEditor::AssistReason assistReason) const
+{
+ Q_UNUSED(assistKind)
+ return new QmlJSEditor::QmlJSCompletionAssistInterface(
+ document(), position(), QString(),
+ assistReason, qmljsdocument->semanticInfo());
+}
+
+BindingDocument::BindingDocument()
+ : QmlJSEditor::QmlJSEditorDocument(BINDINGEDITOR_CONTEXT_ID)
+ , m_semanticHighlighter(new QmlJSEditor::SemanticHighlighter(this))
+{
+
+}
+
+BindingDocument::~BindingDocument()
+{
+ delete m_semanticHighlighter;
+}
+
+void BindingDocument::applyFontSettings()
+{
+ TextDocument::applyFontSettings();
+ m_semanticHighlighter->updateFontSettings(fontSettings());
+ if (!isSemanticInfoOutdated())
+ m_semanticHighlighter->rerun(semanticInfo());
+}
+
+void BindingDocument::triggerPendingUpdates()
+{
+ TextDocument::triggerPendingUpdates(); // calls applyFontSettings if necessary
+ if (!isSemanticInfoOutdated())
+ m_semanticHighlighter->rerun(semanticInfo());
+}
+
+BindingEditorFactory::BindingEditorFactory()
+{
+ setId(BINDINGEDITOR_CONTEXT_ID);
+ setDisplayName(QCoreApplication::translate("OpenWith::Editors", QmlDesigner::BINDINGEDITOR_CONTEXT_ID));
+
+ setDocumentCreator([]() { return new BindingDocument; });
+ setEditorWidgetCreator([]() { return new BindingEditorWidget; });
+ setEditorCreator([]() { return new QmlJSEditor::QmlJSEditor; });
+ setAutoCompleterCreator([]() { return new QmlJSEditor::AutoCompleter; });
+ setCommentDefinition(Utils::CommentDefinition::CppStyle);
+ setParenthesesMatchingEnabled(true);
+ setCodeFoldingSupported(true);
+
+ addHoverHandler(new QmlJSEditor::QmlJSHoverHandler);
+ setCompletionAssistProvider(new QmlJSEditor::QmlJSCompletionAssistProvider);
+}
+
+void BindingEditorFactory::decorateEditor(TextEditor::TextEditorWidget *editor)
+{
+ editor->textDocument()->setSyntaxHighlighter(new QmlJSEditor::QmlJSHighlighter);
+ editor->textDocument()->setIndenter(new QmlJSEditor::Internal::Indenter(
+ editor->textDocument()->document()));
+ editor->setAutoCompleter(new QmlJSEditor::AutoCompleter);
+}
+
+} // QmlDesigner namespace
diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.h b/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.h
new file mode 100644
index 0000000000..597051d89f
--- /dev/null
+++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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.
+**
+****************************************************************************/
+
+#ifndef BINDINGEDITORWIDGET_H
+#define BINDINGEDITORWIDGET_H
+
+#include <texteditor/texteditor.h>
+#include <qmljseditor/qmljseditordocument.h>
+#include <qmljseditor/qmljssemantichighlighter.h>
+#include <qmljseditor/qmljseditor.h>
+
+#include <QtQml>
+#include <QWidget>
+#include <QDialog>
+
+namespace QmlDesigner {
+
+const char BINDINGEDITOR_CONTEXT_ID[] = "BindingEditor.BindingEditorContext";
+
+
+class BindingEditorContext : public Core::IContext
+{
+ Q_OBJECT
+
+public:
+ BindingEditorContext(QWidget *parent) : Core::IContext(parent)
+ {
+ setWidget(parent);
+ }
+};
+
+class BindingEditorWidget : public QmlJSEditor::QmlJSEditorWidget
+{
+ Q_OBJECT
+
+public:
+ BindingEditorWidget();
+ ~BindingEditorWidget() override;
+
+ void unregisterAutoCompletion();
+
+ bool event(QEvent *event) override;
+
+ TextEditor::AssistInterface *createAssistInterface(TextEditor::AssistKind assistKind,
+ TextEditor::AssistReason assistReason) const override;
+
+signals:
+ void returnKeyClicked();
+
+public:
+ QmlJSEditor::QmlJSEditorDocument *qmljsdocument = nullptr;
+ BindingEditorContext *m_context = nullptr;
+ QAction *m_completionAction = nullptr;
+};
+
+class BindingDocument : public QmlJSEditor::QmlJSEditorDocument
+{
+public:
+ BindingDocument();
+ ~BindingDocument();
+
+protected:
+ void applyFontSettings();
+
+ void triggerPendingUpdates();
+
+private:
+ QmlJSEditor::SemanticHighlighter *m_semanticHighlighter = nullptr;
+};
+
+
+class BindingEditorFactory : public TextEditor::TextEditorFactory
+{
+public:
+ BindingEditorFactory();
+
+ static void decorateEditor(TextEditor::TextEditorWidget *editor);
+};
+
+}
+
+#endif //BINDINGEDITORWIDGET_H
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
index f225128a01..b0f0c7637f 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
@@ -54,6 +54,7 @@ GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent)
setScene(&m_scene);
setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
setResizeAnchor(QGraphicsView::NoAnchor);
+ setRenderHint(QPainter::Antialiasing, true);
setTransformationAnchor(QGraphicsView::NoAnchor);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h
index 76af5b8013..67b36c6e72 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h
@@ -24,6 +24,7 @@
****************************************************************************/
#pragma once
+#include <QSet>
#include <QtCore/qobject.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qhash.h>
diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs
index 4ebac8ce31..736d4ed52c 100644
--- a/src/plugins/qmldesigner/qmldesignerplugin.qbs
+++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs
@@ -630,6 +630,10 @@ Project {
files: [
"bindingeditor/bindingeditor.cpp",
"bindingeditor/bindingeditor.h",
+ "bindingeditor/bindingeditordialog.cpp",
+ "bindingeditor/bindingeditordialog.h",
+ "bindingeditor/bindingeditorwidget.cpp",
+ "bindingeditor/bindingeditorwidget.h",
"colortool/colortool.cpp",
"colortool/colortool.h",
"connectioneditor/addnewbackenddialog.h",
diff --git a/src/shared/designerintegrationv2/formresizer.cpp b/src/shared/designerintegrationv2/formresizer.cpp
index 34de90a477..354c7b4f46 100644
--- a/src/shared/designerintegrationv2/formresizer.cpp
+++ b/src/shared/designerintegrationv2/formresizer.cpp
@@ -42,14 +42,13 @@ using namespace SharedTools::Internal;
FormResizer::FormResizer(QWidget *parent) :
QWidget(parent),
- m_frame(new QFrame),
- m_formWindow(0)
+ m_frame(new QFrame)
{
// Make the resize grip of a mainwindow form find us as resizable window.
setWindowFlags(windowFlags() | Qt::SubWindow);
setBackgroundRole(QPalette::Base);
- QVBoxLayout *handleLayout = new QVBoxLayout(this);
+ auto handleLayout = new QVBoxLayout(this);
handleLayout->setContentsMargins(SELECTION_MARGIN, SELECTION_MARGIN,
SELECTION_MARGIN, SELECTION_MARGIN);
handleLayout->addWidget(m_frame);
@@ -166,7 +165,7 @@ QWidget *FormResizer::mainContainer()
{
if (m_formWindow)
return m_formWindow->mainContainer();
- return 0;
+ return nullptr;
}
void FormResizer::mainContainerChanged()
diff --git a/src/shared/designerintegrationv2/formresizer.h b/src/shared/designerintegrationv2/formresizer.h
index aad1a57b0f..a1bdf02161 100644
--- a/src/shared/designerintegrationv2/formresizer.h
+++ b/src/shared/designerintegrationv2/formresizer.h
@@ -60,7 +60,7 @@ class FormResizer : public QWidget
Q_OBJECT
public:
- FormResizer(QWidget *parent = 0);
+ FormResizer(QWidget *parent = nullptr);
void updateGeometry();
void setState(SelectionHandleState st);
@@ -84,7 +84,7 @@ private:
QFrame *m_frame;
typedef QVector<SizeHandleRect*> Handles;
Handles m_handles;
- QDesignerFormWindowInterface * m_formWindow;
+ QDesignerFormWindowInterface *m_formWindow = nullptr;
};
}
diff --git a/src/shared/designerintegrationv2/widgethost.cpp b/src/shared/designerintegrationv2/widgethost.cpp
index ed7f2fb91d..3ce7975c03 100644
--- a/src/shared/designerintegrationv2/widgethost.cpp
+++ b/src/shared/designerintegrationv2/widgethost.cpp
@@ -41,7 +41,6 @@ using namespace SharedTools;
// ---------- WidgetHost
WidgetHost::WidgetHost(QWidget *parent, QDesignerFormWindowInterface *formWindow) :
QScrollArea(parent),
- m_formWindow(0),
m_formResizer(new Internal::FormResizer)
{
setWidget(m_formResizer);
@@ -52,8 +51,7 @@ WidgetHost::WidgetHost(QWidget *parent, QDesignerFormWindowInterface *formWindow
WidgetHost::~WidgetHost()
{
- if (m_formWindow)
- delete m_formWindow;
+ delete m_formWindow;
}
void WidgetHost::setFormWindow(QDesignerFormWindowInterface *fw)
@@ -75,7 +73,7 @@ void WidgetHost::setFormWindow(QDesignerFormWindowInterface *fw)
QSize WidgetHost::formWindowSize() const
{
if (!m_formWindow || !m_formWindow->mainContainer())
- return QSize();
+ return {};
return m_formWindow->mainContainer()->size();
}
diff --git a/src/shared/designerintegrationv2/widgethost.h b/src/shared/designerintegrationv2/widgethost.h
index ccf8590e91..1545509493 100644
--- a/src/shared/designerintegrationv2/widgethost.h
+++ b/src/shared/designerintegrationv2/widgethost.h
@@ -60,7 +60,7 @@ private slots:
private:
QSize formWindowSize() const;
- QDesignerFormWindowInterface *m_formWindow;
+ QDesignerFormWindowInterface *m_formWindow = nullptr;
Internal::FormResizer *m_formResizer;
QSize m_oldFakeWidgetSize;
};
diff --git a/src/shared/qbs b/src/shared/qbs
-Subproject de04ecbbf59b361320a174ee0117c2cfa8c1001
+Subproject 491b293b07e59f69f2c8d9721ac6a098844d590
diff --git a/src/tools/qml2puppet/CMakeLists.txt b/src/tools/qml2puppet/CMakeLists.txt
index b62d063e62..e2475a3ae7 100644
--- a/src/tools/qml2puppet/CMakeLists.txt
+++ b/src/tools/qml2puppet/CMakeLists.txt
@@ -108,10 +108,11 @@ extend_qtc_executable(qml2puppet
extend_qtc_executable(qml2puppet
SOURCES_PREFIX "${SRCDIR}/qml2puppet/editor3d"
SOURCES
- cameracontrolhelper.cpp cameracontrolhelper.h
+ generalhelper.cpp generalhelper.h
mousearea3d.cpp mousearea3d.h
camerageometry.cpp camerageometry.h
gridgeometry.cpp gridgeometry.h
+ selectionboxgeometry.cpp selectionboxgeometry.h
)
extend_qtc_executable(qml2puppet
diff --git a/src/tools/qml2puppet/qml2puppet.qbs b/src/tools/qml2puppet/qml2puppet.qbs
index ca1c3654fb..fe42083d6e 100644
--- a/src/tools/qml2puppet/qml2puppet.qbs
+++ b/src/tools/qml2puppet/qml2puppet.qbs
@@ -197,14 +197,16 @@ QtcTool {
"instances/qt5testnodeinstanceserver.h",
"instances/servernodeinstance.cpp",
"instances/servernodeinstance.h",
- "editor3d/cameracontrolhelper.cpp",
- "editor3d/cameracontrolhelper.h",
+ "editor3d/generalhelper.cpp",
+ "editor3d/generalhelper.h",
"editor3d/mousearea3d.cpp",
"editor3d/mousearea3d.h",
"editor3d/camerageometry.cpp",
"editor3d/camerageometry.h",
"editor3d/gridgeometry.cpp",
"editor3d/gridgeometry.h",
+ "editor3d/selectionboxgeometry.cpp",
+ "editor3d/selectionboxgeometry.h",
"qml2puppetmain.cpp",
]
}