summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2019-11-01 15:31:19 +0100
committerEike Ziller <eike.ziller@qt.io>2019-11-01 15:31:19 +0100
commit04bd6e39c8991fcb89ab15728f622a5a3ae8f0b2 (patch)
tree0517ecde8091d1680651853a4a9d209c0636cffd
parentc92c255d1043f11478a61c1caae4069e7ef47114 (diff)
parenta1d22fd2f79afab8b2379f6d93bcb417b9c8e7d5 (diff)
downloadqt-creator-04bd6e39c8991fcb89ab15728f622a5a3ae8f0b2.tar.gz
Merge remote-tracking branch 'origin/4.11'
Conflicts: share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp Change-Id: I8ea57eba526ab830608fd928c28771c5441749f8
-rw-r--r--dist/changes-4.11.0.md20
-rw-r--r--doc/images/icons/download-icon.pngbin0 -> 119 bytes
-rw-r--r--doc/images/qtcreator-android-build-steps.pngbin0 -> 15846 bytes
-rw-r--r--doc/images/qtcreator-android-certificate.pngbin24115 -> 14613 bytes
-rw-r--r--doc/images/qtcreator-android-cmake-settings.pngbin0 -> 17057 bytes
-rw-r--r--doc/images/qtcreator-android-deploy-configurations.pngbin33466 -> 12989 bytes
-rw-r--r--doc/images/qtcreator-android-manifest-editor.pngbin16207 -> 20869 bytes
-rw-r--r--doc/images/qtcreator-git-commit-actions.pngbin0 -> 13722 bytes
-rw-r--r--doc/images/qtcreator-options-android1.pngbin61494 -> 18219 bytes
-rw-r--r--doc/images/qtcreator-options-android2.pngbin39198 -> 12943 bytes
-rw-r--r--doc/images/qtcreator-vcs-gitbranch.pngbin3991 -> 6812 bytes
-rw-r--r--doc/images/studio-curve-editor.pngbin18457 -> 10352 bytes
-rw-r--r--doc/images/studio-curve-picker.pngbin144647 -> 0 bytes
-rw-r--r--doc/images/studio-easing-curve-editor.pngbin0 -> 29814 bytes
-rw-r--r--doc/images/studio-edit-keyframe.pngbin0 -> 2831 bytes
-rw-r--r--doc/src/android/androiddev.qdoc23
-rw-r--r--doc/src/android/deploying-android.qdoc38
-rw-r--r--doc/src/debugger/creator-debugger-common.qdocinc2
-rw-r--r--doc/src/howto/creator-only/creator-how-tos.qdoc (renamed from doc/src/howto/creator-only/creator-tips.qdoc)147
-rw-r--r--doc/src/howto/creator-only/qtcreator-faq.qdoc4
-rw-r--r--doc/src/howto/creator-ui.qdoc5
-rw-r--r--doc/src/overview/creator-only/creator-help-overview.qdoc2
-rw-r--r--doc/src/overview/creator-only/creator-issues.qdoc2
-rw-r--r--doc/src/projects/creator-only/creator-projects-build-systems.qdocinc2
-rw-r--r--doc/src/projects/creator-only/creator-projects-compilers.qdoc10
-rw-r--r--doc/src/qtcreator-toc.qdoc2
-rw-r--r--doc/src/qtcreator.qdoc2
-rw-r--r--doc/src/qtquick/creator-only/creator-mobile-app-tutorial.qdoc7
-rw-r--r--doc/src/qtquick/creator-only/creator-tutorial-create-qq-project.qdocinc2
-rw-r--r--doc/src/qtquick/creator-only/qtquick-app-tutorial.qdoc6
-rw-r--r--doc/src/qtquick/creator-only/qtquick-creating.qdoc2
-rw-r--r--doc/src/qtquick/qtquick-components.qdoc2
-rw-r--r--doc/src/qtquick/qtquick-timeline.qdoc37
-rw-r--r--doc/src/vcs/creator-vcs-git.qdoc44
-rwxr-xr-xscripts/deployqtHelper_mac.sh13
-rw-r--r--share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.h2
-rw-r--r--share/qtcreator/qml/qmlpuppet/container/propertyvaluecontainer.cpp21
-rw-r--r--share/qtcreator/qml/qmlpuppet/container/propertyvaluecontainer.h3
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/Arrow.qml17
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/AutoScaleHelper.qml6
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/CameraGizmo.qml41
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml87
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/IconGizmo.qml81
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/LightGizmo.qml41
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/MoveGizmo.qml145
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/Overlay2D.qml15
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/camera-pick-icon.pngbin0 -> 206 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/camera-pick-icon@2x.pngbin0 -> 279 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/light-pick-icon.pngbin0 -> 348 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/images/light-pick-icon@2x.pngbin0 -> 525 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/meshes/Arrow.meshbin6356 -> 0 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/mockfiles/meshes/arrow.meshbin0 -> 14732 bytes
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.cpp20
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.h6
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp143
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.h9
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp8
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h3
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp108
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h14
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp5
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h2
-rw-r--r--share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc9
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml309
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml4
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Constants.qml67
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttfbin5280 -> 7576 bytes
-rw-r--r--src/libs/extensionsystem/CMakeLists.txt3
-rw-r--r--src/libs/utils/buildablehelperlibrary.cpp4
-rw-r--r--src/libs/utils/detailsbutton.cpp8
-rw-r--r--src/libs/utils/detailsbutton.h1
-rw-r--r--src/libs/utils/detailswidget.cpp10
-rw-r--r--src/libs/utils/detailswidget.h2
-rw-r--r--src/libs/utils/differ.cpp12
-rw-r--r--src/libs/utils/json.cpp18
-rw-r--r--src/libs/utils/reloadpromptutils.cpp18
-rw-r--r--src/libs/utils/reloadpromptutils.h1
-rw-r--r--src/plugins/boot2qt/device-detection/qdbmessagetracker.cpp2
-rw-r--r--src/plugins/boot2qt/device-detection/qdbwatcher.cpp6
-rw-r--r--src/plugins/boot2qt/qdbdevice.cpp12
-rw-r--r--src/plugins/boot2qt/qdbmakedefaultappservice.cpp2
-rw-r--r--src/plugins/clangtools/clangtool.cpp5
-rw-r--r--src/plugins/clangtools/clangtoolruncontrol.cpp5
-rw-r--r--src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp6
-rw-r--r--src/plugins/clangtools/clangtoolsdiagnosticmodel.h5
-rw-r--r--src/plugins/clangtools/clangtoolsdiagnosticview.cpp2
-rw-r--r--src/plugins/clangtools/clangtoolsprojectsettings.cpp2
-rw-r--r--src/plugins/classview/classviewparsertreeitem.cpp6
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeautocompleter.cpp5
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp2
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprocess.cpp6
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp2
-rw-r--r--src/plugins/cmakeprojectmanager/fileapiparser.cpp36
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.cpp27
-rw-r--r--src/plugins/coreplugin/documentmanager.cpp1
-rw-r--r--src/plugins/coreplugin/editormanager/editormanager.cpp4
-rw-r--r--src/plugins/coreplugin/mainwindow.cpp1
-rw-r--r--src/plugins/coreplugin/manhattanstyle.cpp14
-rw-r--r--src/plugins/cppeditor/cppdocumentationcommenthelper.cpp10
-rw-r--r--src/plugins/cppeditor/cppfunctiondecldeflink.cpp4
-rw-r--r--src/plugins/cppeditor/cppminimizableinfobars.cpp2
-rw-r--r--src/plugins/cppeditor/cppquickfixes.cpp18
-rw-r--r--src/plugins/cpptools/compileroptionsbuilder.cpp7
-rw-r--r--src/plugins/cpptools/cppchecksymbols.cpp23
-rw-r--r--src/plugins/cpptools/cppcodeformatter.cpp8
-rw-r--r--src/plugins/cpptools/cppcompletionassistprovider.cpp4
-rw-r--r--src/plugins/cpptools/cppfollowsymbolundercursor.cpp2
-rw-r--r--src/plugins/cpptools/cpprefactoringchanges.cpp10
-rw-r--r--src/plugins/cpptools/semantichighlighter.cpp2
-rw-r--r--src/plugins/debugger/breakhandler.cpp17
-rw-r--r--src/plugins/debugger/cdb/cdbengine.cpp19
-rw-r--r--src/plugins/debugger/debuggeritem.cpp5
-rw-r--r--src/plugins/debugger/gdb/gdbengine.cpp2
-rw-r--r--src/plugins/debugger/moduleshandler.cpp3
-rw-r--r--src/plugins/help/localhelpmanager.cpp9
-rw-r--r--src/plugins/languageclient/languageclientmanager.cpp2
-rw-r--r--src/plugins/languageclient/languageclientutils.cpp1
-rw-r--r--src/plugins/mcusupport/mcusupportoptions.cpp43
-rw-r--r--src/plugins/mcusupport/mcusupportoptionspage.cpp2
-rw-r--r--src/plugins/mcusupport/mcusupportrunconfiguration.cpp1
-rw-r--r--src/plugins/projectexplorer/abi.cpp5
-rw-r--r--src/plugins/projectexplorer/abi.h1
-rw-r--r--src/plugins/projectexplorer/gcctoolchain.cpp16
-rw-r--r--src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp18
-rw-r--r--src/plugins/projectexplorer/jsonwizard/jsonfieldpage_p.h3
-rw-r--r--src/plugins/projectexplorer/projectexplorer.cpp4
-rw-r--r--src/plugins/projectexplorer/projecttreewidget.cpp5
-rw-r--r--src/plugins/projectexplorer/projectwelcomepage.cpp1
-rw-r--r--src/plugins/projectexplorer/projectwindow.cpp2
-rw-r--r--src/plugins/projectexplorer/targetsettingspanel.cpp3
-rw-r--r--src/plugins/projectexplorer/targetsetuppage.cpp2
-rw-r--r--src/plugins/projectexplorer/targetsetupwidget.cpp36
-rw-r--r--src/plugins/projectexplorer/targetsetupwidget.h3
-rw-r--r--src/plugins/projectexplorer/userfileaccessor.cpp2
-rw-r--r--src/plugins/python/pythonrunconfiguration.cpp6
-rw-r--r--src/plugins/python/pythonsettings.cpp64
-rw-r--r--src/plugins/python/pythonsettings.h11
-rw-r--r--src/plugins/python/pythonutils.cpp21
-rw-r--r--src/plugins/qmldesigner/CMakeLists.txt1
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp13
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp6
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h5
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/playhead.cpp5
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/playhead.h2
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/images/item-3D_model-icon.pngbin492 -> 407 bytes
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/images/item-3D_model-icon@2x.pngbin942 -> 733 bytes
-rw-r--r--src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp13
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/aligndistribute.cpp696
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/aligndistribute.h100
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/itemfiltermodel.cpp19
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/itemfiltermodel.h5
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/propertyeditor.pri6
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp2
-rw-r--r--src/plugins/qmldesigner/components/timelineeditor/timelinetoolbar.cpp6
-rw-r--r--src/plugins/qmldesigner/designercore/include/nodeinstanceview.h4
-rw-r--r--src/plugins/qmldesigner/designercore/include/qmlitemnode.h1
-rw-r--r--src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp8
-rw-r--r--src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp5
-rw-r--r--src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp13
-rw-r--r--src/plugins/qmldesigner/designersettings.cpp1
-rw-r--r--src/plugins/qmldesigner/designersettings.h1
-rw-r--r--src/plugins/qmldesigner/qmldesignerplugin.cpp4
-rw-r--r--src/plugins/qmldesigner/qmldesignerplugin.qbs2
-rw-r--r--src/plugins/qmldesigner/settingspage.cpp6
-rw-r--r--src/plugins/qmldesigner/settingspage.ui15
-rw-r--r--src/plugins/updateinfo/updateinfoplugin.cpp4
-rw-r--r--src/tools/qtcdebugger/CMakeLists.txt2
-rw-r--r--tests/system/objects.map2
-rw-r--r--tests/system/shared/build_utils.py1
-rw-r--r--tests/system/suite_general/tst_create_proj_wizard/test.py3
170 files changed, 2590 insertions, 524 deletions
diff --git a/dist/changes-4.11.0.md b/dist/changes-4.11.0.md
index 8babf0c81e..a85f8e5c3d 100644
--- a/dist/changes-4.11.0.md
+++ b/dist/changes-4.11.0.md
@@ -18,6 +18,11 @@ you can check out from the public Git repository. For example:
* Made update notification less intrusive and more informative (QTCREATORBUG-22817)
* Made wizards remember user choices (QTCREATORBUG-16657)
+## Help
+
+* Fixed that removing Qt version only unregistered its documentation after
+ restart (QTCREATORBUG-16631)
+
## Editing
* Added option to change line ending style via editor tool bar
@@ -90,6 +95,7 @@ you can check out from the public Git repository. For example:
* Fixed handling of boolean semantics (`OFF`, `NO`, `FALSE`, and so on)
* Fixed `Build` > `Run CMake` (QTCREATORBUG-19704)
* Fixed registering `CMake.app` from official installer on macOS
+* Fixed code model issues when using precompiled headers (QTCREATORBUG-22888)
### Qbs
@@ -106,6 +112,12 @@ 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)
+## Debugging
+
+### CDB
+
+* Fixed assigning negative values to variables (QTCREATORBUG-17269)
+
## Analyzer
* Added viewer for Chrome trace report files
@@ -148,6 +160,10 @@ you can check out from the public Git repository. For example:
* Added settings per project (QTCREATORBUG-16704)
* Added option to run tests after successful build
+### Boost
+
+* Fixed running multiple tests (QTCREATORBUG-23091)
+
## Platforms
### Windows
@@ -184,6 +200,7 @@ you can check out from the public Git repository. For example:
* Fixed that it was not possible to add custom deployment steps (QTCREATORBUG-22977)
## Credits for these changes go to:
+
Aleksei German
Alessandro Portale
Andre Hartmann
@@ -211,6 +228,9 @@ Miikka Heikkinen
Milian Wolff
Nikolai Kosjar
Orgad Shaneh
+Pasi Keränen
+Richard Weickelt
+Robert Löhning
Sergey Levin
Sona Kurazyan
Tasuku Suzuki
diff --git a/doc/images/icons/download-icon.png b/doc/images/icons/download-icon.png
new file mode 100644
index 0000000000..59de1e81e9
--- /dev/null
+++ b/doc/images/icons/download-icon.png
Binary files differ
diff --git a/doc/images/qtcreator-android-build-steps.png b/doc/images/qtcreator-android-build-steps.png
new file mode 100644
index 0000000000..dda97e83cc
--- /dev/null
+++ b/doc/images/qtcreator-android-build-steps.png
Binary files differ
diff --git a/doc/images/qtcreator-android-certificate.png b/doc/images/qtcreator-android-certificate.png
index 2b4d235549..1798a91eb7 100644
--- a/doc/images/qtcreator-android-certificate.png
+++ b/doc/images/qtcreator-android-certificate.png
Binary files differ
diff --git a/doc/images/qtcreator-android-cmake-settings.png b/doc/images/qtcreator-android-cmake-settings.png
new file mode 100644
index 0000000000..6776e4fcba
--- /dev/null
+++ b/doc/images/qtcreator-android-cmake-settings.png
Binary files differ
diff --git a/doc/images/qtcreator-android-deploy-configurations.png b/doc/images/qtcreator-android-deploy-configurations.png
index b09cbce6de..c4602a8538 100644
--- a/doc/images/qtcreator-android-deploy-configurations.png
+++ b/doc/images/qtcreator-android-deploy-configurations.png
Binary files differ
diff --git a/doc/images/qtcreator-android-manifest-editor.png b/doc/images/qtcreator-android-manifest-editor.png
index 90fdb6a42b..67424baae3 100644
--- a/doc/images/qtcreator-android-manifest-editor.png
+++ b/doc/images/qtcreator-android-manifest-editor.png
Binary files differ
diff --git a/doc/images/qtcreator-git-commit-actions.png b/doc/images/qtcreator-git-commit-actions.png
new file mode 100644
index 0000000000..37295e48fc
--- /dev/null
+++ b/doc/images/qtcreator-git-commit-actions.png
Binary files differ
diff --git a/doc/images/qtcreator-options-android1.png b/doc/images/qtcreator-options-android1.png
index b3806a361d..81a94cb5e4 100644
--- a/doc/images/qtcreator-options-android1.png
+++ b/doc/images/qtcreator-options-android1.png
Binary files differ
diff --git a/doc/images/qtcreator-options-android2.png b/doc/images/qtcreator-options-android2.png
index 176b2cd3a1..5289c4b1b0 100644
--- a/doc/images/qtcreator-options-android2.png
+++ b/doc/images/qtcreator-options-android2.png
Binary files differ
diff --git a/doc/images/qtcreator-vcs-gitbranch.png b/doc/images/qtcreator-vcs-gitbranch.png
index aae80201bc..f6a5586eac 100644
--- a/doc/images/qtcreator-vcs-gitbranch.png
+++ b/doc/images/qtcreator-vcs-gitbranch.png
Binary files differ
diff --git a/doc/images/studio-curve-editor.png b/doc/images/studio-curve-editor.png
index f1f82e0abe..cdb675c881 100644
--- a/doc/images/studio-curve-editor.png
+++ b/doc/images/studio-curve-editor.png
Binary files differ
diff --git a/doc/images/studio-curve-picker.png b/doc/images/studio-curve-picker.png
deleted file mode 100644
index 37f1af0a39..0000000000
--- a/doc/images/studio-curve-picker.png
+++ /dev/null
Binary files differ
diff --git a/doc/images/studio-easing-curve-editor.png b/doc/images/studio-easing-curve-editor.png
new file mode 100644
index 0000000000..57d70f86cd
--- /dev/null
+++ b/doc/images/studio-easing-curve-editor.png
Binary files differ
diff --git a/doc/images/studio-edit-keyframe.png b/doc/images/studio-edit-keyframe.png
new file mode 100644
index 0000000000..446187d141
--- /dev/null
+++ b/doc/images/studio-edit-keyframe.png
Binary files differ
diff --git a/doc/src/android/androiddev.qdoc b/doc/src/android/androiddev.qdoc
index ac2a77a3fe..00737d5ef2 100644
--- a/doc/src/android/androiddev.qdoc
+++ b/doc/src/android/androiddev.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
@@ -66,10 +66,10 @@
\note Android SDK Tools have issues with JDK versions later than 8.
\li \l{http://www.gradle.org}{Gradle} for building application packages
- for Android devices (APK). Gradle is delivered with Qt 5.9, and
- later. Because Gradle scripts are not delivered with Android SDK
- Tools since version 26.0.0, they are delivered with Qt 5.9 and
- 5.6.3.
+ (APK) and app bundles (AAB) for Android devices. Gradle is delivered
+ with Qt 5.9, and later. Because Gradle scripts are not delivered
+ with Android SDK tools since version 26.0.0, they are delivered
+ with Qt 5.9 and 5.6.3.
\note Using Ant to build APKs is no longer supported.
@@ -77,6 +77,9 @@
by the \l{http://developer.android.com/tools/sdk/ndk/index.html}
{Android NDK} from Google.
+ \note To develop with Qt 5.14.0 or later, you need Android NDK r20
+ or later.
+
\li \l{http://developer.android.com/sdk/index.html}{Android SDK Tools}
The following Android SDK packages and tools are required for
@@ -167,7 +170,7 @@
\li In the \uicontrol {JDK location} field, add the path to the JDK.
- You can use the \inlineimage download.png
+ Select the \inlineimage icons/download-icon.png
(\uicontrol Download) button to go to the site where you can
download the JDK. \QC checks the JDK installation and reports
errors.
@@ -175,9 +178,8 @@
\li In the \uicontrol {Android Settings} group, add paths to the Android
NDK and SDK.
- You can use the \inlineimage download.png
- (\uicontrol Download) buttons to go to the sites where you can download
- the Android NDK and SDK.
+ Select \inlineimage icons/download-icon.png
+ to go to the sites where you can download the Android NDK and SDK.
The SDK Manager checks the Android NDK and SDK installations,
reports errors, and offers to install the necessary packages.
@@ -192,7 +194,8 @@
\li Select \uicontrol File > \uicontrol {New File or Project} > \uicontrol Application >
\uicontrol {Qt Quick Application} > \uicontrol Choose, and
- follow the instructions of the wizard. For more information, see
+ follow the instructions of the wizard to create a project. For more
+ information, see
\if defined(qtcreator)
\l{Creating Qt Quick Projects}.
\else
diff --git a/doc/src/android/deploying-android.qdoc b/doc/src/android/deploying-android.qdoc
index 998cc7f210..7690b435a6 100644
--- a/doc/src/android/deploying-android.qdoc
+++ b/doc/src/android/deploying-android.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
@@ -32,9 +32,19 @@
\title Deploying Applications to Android Devices
- On Android, applications are distributed in a specially structured type of
- ZIP package called an APK. \QC supports the following methods of deployment
- for Android applications:
+ On Android, applications are distributed in specially structured types of
+ ZIP packages called Application Packages (APK) or Android App Bundles (AAB).
+ APK files can be downloaded to and executed on a device, whereas AAB is
+ intended to be interpreted by the Google Play store and is used to generate
+ APK files.
+
+ \l{Qt for Android} has binaries for armv7a, arm64-v8a, x86, and x86-64.
+ To support several different ABIs in your application, build an AAB that
+ contains binaries for each of the ABIs. The Google Play store uses the
+ AAB to generate optimized APK packages for the devices issuing the download
+ request and automatically signs them with your publisher key.
+
+ \QC supports the following methods of deployment for Android applications:
\list
@@ -44,6 +54,9 @@
The Ministro tool downloads the necessary Qt libraries from a
repository of your choice.
+ \li Since Qt 5.14.0, as an app bundle (AAB), intended for distribution
+ in the Google Play store.
+
\endlist
To specify settings for application packages, select \uicontrol Projects >
@@ -137,6 +150,23 @@
the \uicontrol {Compile Output} pane. To view additional information, select the
\uicontrol {Verbose output} check box.
+ \section3 Building AABs
+
+ For testing the application locally, use the APK format, because
+ the package can be uploaded directly to the device and run. For
+ distribution to the Google Play store, create an AAB by selecting
+ the \uicontrol {Build .aab (Android App Bundle)} check box.
+
+ When building with CMake, you can select the ABIs to build the application
+ for in the \uicontrol CMake settings:
+
+ \image qtcreator-android-cmake-settings.png "CMake settings for building AABs"
+
+ When building with qmake, you can select the ABIs in the \uicontrol ABIs
+ field in the \uicontrol {Build Steps}:
+
+ \image qtcreator-android-build-steps.png "Android Build Steps"
+
\section3 Selecting API Level
In the \uicontrol {Android build SDK} field, you can select the API level to use
diff --git a/doc/src/debugger/creator-debugger-common.qdocinc b/doc/src/debugger/creator-debugger-common.qdocinc
index 5437b0d2a5..e5366aa968 100644
--- a/doc/src/debugger/creator-debugger-common.qdocinc
+++ b/doc/src/debugger/creator-debugger-common.qdocinc
@@ -398,7 +398,7 @@
entry.
You can enable tooltips in the main editor displaying this information.
- For more information, see \l{Showing Tooltips in Debug Mode}.
+ For more information, see \l{See the value of variables in tooltips while debugging}.
//! [debugger-qt-basic-objects]
*/
diff --git a/doc/src/howto/creator-only/creator-tips.qdoc b/doc/src/howto/creator-only/creator-how-tos.qdoc
index 5e481b42f2..d210b00618 100644
--- a/doc/src/howto/creator-only/creator-tips.qdoc
+++ b/doc/src/howto/creator-only/creator-how-tos.qdoc
@@ -32,12 +32,41 @@
/*!
\contentspage index.html
\previouspage creator-faq.html
- \page creator-tips.html
+ \page creator-how-tos.html
\nextpage creator-known-issues.html
- \title Tips and Tricks
+ \title How-tos
- \section1 Switching Between Modes
+ How do I:
+
+ \list
+ \li \l {Switch between modes}
+ \li \l {Move between open files}
+ \li \l {Switch to Edit mode}
+ \li \l {Find a specific setting}
+ \li \l {Open output panes}
+ \li \l {Find keyboard shortcuts}
+ \li \l {Run \QC from the command line}
+ \li \l {Show and hide sidebars}
+ \li \l {Move to symbols}
+ \li \l {Inspect signal-slot connections while debugging}
+ \li \l {Display low-level data in the debugger}
+ \li \l {See the value of variables in tooltips while debugging}
+ \li \l {Quickly locate files using the keyboard}
+ \li \l {Perform calculations}
+ \li \l {Jump to a function in QML code}
+ \li \l {Add a license header template for C++ code}
+ \li \l {Paste text from my clipboard history}
+ \li \l {Sort lines alphabetically}
+ \li \l {Enclose selected code in curly braces, parentheses, or double quotes}
+ \li \l {Select the enclosing block in C++}
+ \li \l {Add my own code snippets to the auto-complete menu}
+ \li \l {Quickly write down notes somewhere}
+ \li \l {Configure the amount of recent files shown}
+ \li \l {Search and replace across files using a regular expression}
+ \endlist
+
+ \section1 Switch between modes
\QC uses different modes for different purposes. You can quickly
switch between these modes with the following keyboard shortcuts:
@@ -55,7 +84,7 @@
For more information about \QC modes, see \l {Selecting Modes}.
- \section1 Moving Between Open Files
+ \section1 Move between open files
To quickly move between currently open files, press
\key Ctrl+Tab.
@@ -66,7 +95,7 @@
to jump to a symbol in the same file, you can jump back to your original
location in that file by pressing \key {Alt+Left}.
- \section1 Moving To the Edit Mode
+ \section1 Switch to Edit mode
To move to the \uicontrol Edit mode and currently active file, press
\key Esc.
@@ -81,12 +110,12 @@
\endlist
- \section1 Using the Filter in Options Dialog
+ \section1 Find a specific setting
To find specific settings you require in \uicontrol{Tools} > \uicontrol{Options}
use the filter located at the top left of the \uicontrol Options dialog box.
- \section1 Opening Output Panes
+ \section1 Open output panes
The output panes provide a list of errors and warnings encountered during
a build, detailed output from the compiler, status of a program when it is
@@ -112,7 +141,7 @@
For more information about output panes, see \l{Viewing Output}.
- \section1 Using Keyboard Shortcuts
+ \section1 Find keyboard shortcuts
\QC provides \l{Keyboard Shortcuts}{many useful keyboard shortcuts}.
You can see the keyboard shortcut for a menu command in the menu
@@ -121,7 +150,7 @@
To customize, import or export keyboard shortcuts, select \uicontrol Tools >
\uicontrol Options > \uicontrol Environment > \uicontrol Keyboard.
- \section1 Running \QC From Command Line
+ \section1 Run \QC from the command line
You can launch \QC from command line using the name of an
existing session or \c .pro file by giving the name as the command
@@ -132,7 +161,7 @@
For more information, see \l{Using Command Line Options}.
- \section1 Showing and Hiding Sidebars
+ \section1 Show and hide sidebars
You can toggle the left and right sidebar in some \QC modes.
@@ -147,7 +176,7 @@
For more information on using the sidebars, see
\l {Browsing Project Contents}.
- \section1 Moving To Symbols
+ \section1 Move to symbols
To move straight to a symbol used in a project, select the symbol in the
\uicontrol Editor toolbar drop-down menu. For more information on the editor
@@ -163,7 +192,7 @@
cursor on the symbol and press \key {F2}. For more information, see
\l{Moving to Symbol Definition or Declaration}.
- \section1 Displaying Signals and Slots
+ \section1 Inspect signal-slot connections while debugging
If an instance of a class is derived from QObject, and you would like to
find all other objects connected to one of your object's slots using
@@ -177,7 +206,7 @@
For more information about the \uicontrol{Locals} view, see
\l{Local Variables and Function Parameters}.
- \section1 Displaying Low Level Data
+ \section1 Display low-level data in the debugger
If special debugging of Qt objects fails due to data corruption within the
debugged objects, you can switch off the debugging helpers. When debugging
@@ -193,7 +222,7 @@
\endlist
- \section1 Showing Tooltips in Debug Mode
+ \section1 See the value of variables in tooltips while debugging
To inspect the value of variables from the editor, you can turn
on tooltips. Tooltips are hidden by default for performance reasons.
@@ -218,7 +247,7 @@
select \uicontrol {Close Editor Tooltips} in the context menu in the
\uicontrol {Locals} view.
- \section1 Locating Files
+ \section1 Quickly locate files using the keyboard
The \uicontrol Locator provides one of the easiest ways in \QC to browse
through projects, files, classes, functions, documentation and file systems.
@@ -230,7 +259,20 @@
For more information, see \l{Creating Locator Filters}.
- \section1 Adding a License Header Template for C++ Code
+ \section1 Perform calculations
+
+ Open the \uicontrol Locator with \key {Ctrl+K} and type =, followed by a space.
+ You can now do basic calculations, with options to copy the results to the clipboard
+ by navigating through the entries and pressing \key {Enter}.
+
+ For more information, see \l{Executing JavaScript}.
+
+ \section1 Jump to a function in QML code
+
+ Open the \uicontrol Locator with \key {Ctrl+K} and type m, followed by a space.
+ You can now go directly to any QML method in the file.
+
+ \section1 Add a license header template for C++ code
A file containing a license header for C++ can be specified under
\uicontrol{Tools > Options > C++ > License Template}. It may contain special
@@ -250,16 +292,85 @@
\endlist
- \section1 Pasting from Clipboard History
+ \section1 Paste text from my clipboard history
\QC stores copied text in clipboard history. To retrieve clips from the
history, press \key {Ctrl+Shift+V} until the clip appears.
The number of clips in the history is fixed to 10.
- \section1 Sorting Lines Alphabetically
+ \section1 Sort lines alphabetically
To sort selected lines alphabetically, select \uicontrol Edit >
\uicontrol Advanced > \uicontrol {Sort Selected Lines} or press
\key {Alt+Shift+S} (or \key Ctrl+Shift+S on \macos).
+ \section1 Enclose selected code in curly braces, parentheses, or double quotes
+
+ Press \key {Shift} and then the opening character.
+
+ \list
+ \li Curly braces: \key {Shift+\{}
+ \li Parentheses: \key {Shift+(}
+ \li Double quotes: \key {Shift+"}
+ \endlist
+
+ \section1 Select the enclosing block in C++
+
+ Press \key {Ctrl+U}.
+
+ \section1 Add my own code snippets to the auto-complete menu
+
+ You can add, modify, and remove snippets in the snippet editor.
+ To open the editor, select \uicontrol Tools > \uicontrol Options
+ > \uicontrol {Text Editor} > \uicontrol Snippets.
+
+ For more information, see \l {Adding and Editing Snippets}.
+
+ \section1 Quickly write down notes somewhere
+
+ Select \uicontrol File > \uicontrol {New File or Project} >
+ \uicontrol {Files and Classes} > \uicontrol General > \uicontrol {Scratch Buffer}.
+ Alternatively, \key {Ctrl+N} can be used to open this dialog, which is
+ fully navigable via keyboard by using the up and down arrow keys and the
+ tab key.
+
+ This creates a new empty text file and saves it to the temporary directory
+ on your machine. You can use it to write down notes without having to worry
+ about deleting the file afterwards. The operating system will eventually
+ remove the file automatically. If you want to keep the file, you can easily
+ save it as a new file somewhere else. If you accidentally close the file,
+ you can find it in the \uicontrol File > \uicontrol {Recent Files} menu.
+
+ \section1 Configure the amount of recent files shown
+
+ Select \uicontrol Tools > \uicontrol Options, and change the value of the
+ list under \uicontrol Environment > \uicontrol System
+ > \uicontrol {Maximum number of entries in "Recent Files"}.
+
+ \section1 Search and replace across files using a regular expression
+
+ As an example, say you want to replace equality checks (\c {foo == bar})
+ with a function (\c {foo.equals(bar)}):
+
+ \list 1
+ \li Ensure that any work you have done is committed to version control,
+ as the changes cannot be undone.
+ \li Press \key {Ctrl+Shift+F} to bring up the \uicontrol {Advanced Find}
+ form.
+ \li Change the scope to whatever is appropriate for your search.
+ \li Under the \uicontrol {Search for} text field, select
+ the \uicontrol {Use regular expressions} check box.
+ \li Enter the following text in the \uicontrol {Search for} text field:
+ \badcode
+ if \((.*) == (.*)\)
+ \endcode
+ \li Press \uicontrol {Search & Replace} to see a list of search results.
+ \li In the \uicontrol {Replace with} text field, enter the following text:
+ \badcode
+ if (\1.strictlyEquals(\2))
+ \endcode
+ \li Press \uicontrol Replace to replace all instances of the text.
+ \endlist
+
+ For more information, see \l {Advanced Search}.
*/
diff --git a/doc/src/howto/creator-only/qtcreator-faq.qdoc b/doc/src/howto/creator-only/qtcreator-faq.qdoc
index 712d81aeda..87bd22d00d 100644
--- a/doc/src/howto/creator-only/qtcreator-faq.qdoc
+++ b/doc/src/howto/creator-only/qtcreator-faq.qdoc
@@ -27,13 +27,13 @@
\contentspage index.html
\previouspage creator-help.html
\page creator-faq.html
- \nextpage creator-tips.html
+ \nextpage creator-how-tos.html
\title FAQ
This section contains answers to some frequently asked questions about \QC.
You might also find answers to your questions in the
- \l{Known Issues} and \l{Tips and Tricks} sections, or the Troubleshooting
+ \l{Known Issues} and \l{How-tos} sections, or the Troubleshooting
sections for a special area, such as
\l{Troubleshooting Debugger}{debugging}.
diff --git a/doc/src/howto/creator-ui.qdoc b/doc/src/howto/creator-ui.qdoc
index adc38a0cf3..8e6a23b317 100644
--- a/doc/src/howto/creator-ui.qdoc
+++ b/doc/src/howto/creator-ui.qdoc
@@ -107,7 +107,7 @@
\section1 Useful Features
For a list of useful \QC features described in other parts of the
- documentation, see \l{Tips and Tricks}.
+ documentation, see \l{How-tos}.
\endif
\section1 Changing Languages
@@ -404,6 +404,9 @@
\if defined(qtdesignstudio)
\li \uicontrol {Asset Importer Error} - Errors and warnings encountered
while importing assets from a design tool.
+ \else
+ \li \uicontrol Autotests - Errors and warnings encountered while running
+ tests.
\endif
\li \uicontrol {Build System} - Errors and warnings encountered during a
diff --git a/doc/src/overview/creator-only/creator-help-overview.qdoc b/doc/src/overview/creator-only/creator-help-overview.qdoc
index dd8c47dc25..fd16ed3e9f 100644
--- a/doc/src/overview/creator-only/creator-help-overview.qdoc
+++ b/doc/src/overview/creator-only/creator-help-overview.qdoc
@@ -53,7 +53,7 @@
Contains answers to some frequently asked questions about \QC.
- \li \l{Tips and Tricks}
+ \li \l{How-tos}
Lists useful \QC features.
diff --git a/doc/src/overview/creator-only/creator-issues.qdoc b/doc/src/overview/creator-only/creator-issues.qdoc
index 16c5263aee..bbbd71002f 100644
--- a/doc/src/overview/creator-only/creator-issues.qdoc
+++ b/doc/src/overview/creator-only/creator-issues.qdoc
@@ -31,7 +31,7 @@
/*!
\contentspage index.html
- \previouspage creator-tips.html
+ \previouspage creator-how-tos.html
\page creator-known-issues.html
\nextpage creator-glossary.html
diff --git a/doc/src/projects/creator-only/creator-projects-build-systems.qdocinc b/doc/src/projects/creator-only/creator-projects-build-systems.qdocinc
index e11cf0c340..b383c94e99 100644
--- a/doc/src/projects/creator-only/creator-projects-build-systems.qdocinc
+++ b/doc/src/projects/creator-only/creator-projects-build-systems.qdocinc
@@ -45,7 +45,7 @@
configuration. qmake is installed and configured when you install Qt.
To use one of the other supported build systems, you need to set it up.
- \l {CMake Manual}{CMake} is an alternative to qmake for automating the
+ \l {Build with CMake}{CMake} is an alternative to qmake for automating the
generation of build configurations. For more information, see
\l {Setting Up CMake}.
diff --git a/doc/src/projects/creator-only/creator-projects-compilers.qdoc b/doc/src/projects/creator-only/creator-projects-compilers.qdoc
index b91d5b7d9e..30d39dbffa 100644
--- a/doc/src/projects/creator-only/creator-projects-compilers.qdoc
+++ b/doc/src/projects/creator-only/creator-projects-compilers.qdoc
@@ -63,8 +63,9 @@
Windows applications on Windows. MinGW is
distributed together with \QC and Qt installers for Windows.
- \li Linux ICC (Intel C++ Compiler) is a group of C and C++ compilers
- for Linux.
+ \li ICC (Intel C++ Compiler) is a group of C and C++ compilers.
+ Only the GCC-compatible variant, available for Linux and \macos,
+ is currently supported by \QC.
\li Clang is a C, C++, Objective C, and Objective C++ front-end for the
LLVM compiler for Windows, Linux, and \macos.
@@ -87,7 +88,8 @@
\li \l{https://www.iar.com/iar-embedded-workbench/}{IAREW} is a group of
C and C++ bare-metal compilers from the various IAR Embedded Workbench
development environments.
- \note Currently supported architectures are \c 8051, \c AVR, and \c ARM.
+ \note Currently supported architectures are \c 8051, \c AVR, \c ARM,
+ \c STM8, and \c MSP430.
\li \l{https://www.keil.com}{KEIL} is a group of C and C++ bare-metal
compilers from the various KEIL development environments.
@@ -95,7 +97,7 @@
\li \l{https://sdcc.sourceforge.net}{SDCC} is a retargetable, optimizing
C bare-metal compiler for various architectures.
- \note Currently supported architecture is \c 8051.
+ \note Currently supported architectures are \c 8051 and \c STM8.
\endlist
diff --git a/doc/src/qtcreator-toc.qdoc b/doc/src/qtcreator-toc.qdoc
index f0bd3f9e02..fb796ae8bf 100644
--- a/doc/src/qtcreator-toc.qdoc
+++ b/doc/src/qtcreator-toc.qdoc
@@ -231,7 +231,7 @@
\list
\li \l{Using the Help Mode}
\li \l{FAQ}
- \li \l{Tips and Tricks}
+ \li \l{How-tos}
\li \l{Known Issues}
\li \l{Glossary}
\li \l{Technical Support}
diff --git a/doc/src/qtcreator.qdoc b/doc/src/qtcreator.qdoc
index 5401ecc442..58db763d76 100644
--- a/doc/src/qtcreator.qdoc
+++ b/doc/src/qtcreator.qdoc
@@ -123,7 +123,7 @@
\list
\li \l{Using the Help Mode}
\li \l{FAQ}
- \li \l{Tips and Tricks}
+ \li \l{How-tos}
\li \l{Known Issues}
\li \l{Glossary}
\endlist
diff --git a/doc/src/qtquick/creator-only/creator-mobile-app-tutorial.qdoc b/doc/src/qtquick/creator-only/creator-mobile-app-tutorial.qdoc
index 6f8b571bf8..6b09066b87 100644
--- a/doc/src/qtquick/creator-only/creator-mobile-app-tutorial.qdoc
+++ b/doc/src/qtquick/creator-only/creator-mobile-app-tutorial.qdoc
@@ -73,7 +73,7 @@
The main view of the application displays an SVG bubble image that moves
around the screen when you tilt the device.
- To use \l{accelbubble/Bluebubble.svg}{Bluebubble.svg} in your project,
+ To use \e {Bluebubble.svg} in your project,
copy it to the project directory (same subdirectory as the QML file).
The image appears in \uicontrol Resources. You can also use any other
image or a QML type, instead.
@@ -140,9 +140,8 @@
\QC creates a reference to the Bubble type in \e Page1Form.ui.qml.
- To check your code, you can compare \e Page1Form.ui.qml with the
- \l{accelbubble/Page1Form.ui.qml}{Page1Form.ui.qml} example file and
- \e Bubble.qml with the \l{accelbubble/Bubble.qml}{Bubble.qml} example file.
+ To check your code, you can compare your \e Page1Form.ui.qml and
+ \e {Bubble.qml} with the corresponding example files.
The UI is now ready and you can switch to editing the \e Bubble.qml and
\e main.qml files in the \uicontrol {Text Editor}, as described in the
diff --git a/doc/src/qtquick/creator-only/creator-tutorial-create-qq-project.qdocinc b/doc/src/qtquick/creator-only/creator-tutorial-create-qq-project.qdocinc
index b3f2bc67a1..04826f69fa 100644
--- a/doc/src/qtquick/creator-only/creator-tutorial-create-qq-project.qdocinc
+++ b/doc/src/qtquick/creator-only/creator-tutorial-create-qq-project.qdocinc
@@ -45,7 +45,7 @@
\l {Setting Up CMake}{CMake}, or \l {Setting Up Qbs}{Qbs}.
\li In the \uicontrol {Qt Quick Controls Style} field, select one of
- the predefined \l{Styling Qt Quick Controls 2}{UI styles} to use,
+ the predefined \l{Styling Qt Quick Controls}{UI styles} to use,
and then select \uicontrol Next.
\li Select \l{glossary-buildandrun-kit}{kits} for the platforms that
diff --git a/doc/src/qtquick/creator-only/qtquick-app-tutorial.qdoc b/doc/src/qtquick/creator-only/qtquick-app-tutorial.qdoc
index 55fe9f421c..0d93f62c9f 100644
--- a/doc/src/qtquick/creator-only/qtquick-app-tutorial.qdoc
+++ b/doc/src/qtquick/creator-only/qtquick-app-tutorial.qdoc
@@ -188,9 +188,9 @@
\endlist
- To check your code, you can view \e Page1Form.ui.qml in the
- \uicontrol {Text Editor} and compare it with the \l{transitions/Page1Form.ui.qml}
- {Page1Form.ui.qml} example file.
+ To check your code, you can view your \e {Page1Form.ui.qml} file in the
+ \uicontrol {Text Editor} and compare it with the \e {Page1Form.ui.qml}
+ example file.
The new project wizard adds boilerplate code to the \e Page1.qml file to
create menu items and push buttons. Modify the boilerplate code by removing
diff --git a/doc/src/qtquick/creator-only/qtquick-creating.qdoc b/doc/src/qtquick/creator-only/qtquick-creating.qdoc
index d37992ed2e..1e633f803c 100644
--- a/doc/src/qtquick/creator-only/qtquick-creating.qdoc
+++ b/doc/src/qtquick/creator-only/qtquick-creating.qdoc
@@ -172,7 +172,7 @@
\l {Setting Up CMake}{CMake}, or \l {Setting Up Qbs}{Qbs}.
\li In the \uicontrol {Qt Quick Controls Style} field, select one of
- the predefined \l{Styling Qt Quick Controls 2}{UI styles} to use,
+ the predefined \l{Styling Qt Quick Controls}{UI styles} to use,
and then select \uicontrol Next.
\li Select the \uicontrol {Use Qt Virtual Keyboard} check box to add
diff --git a/doc/src/qtquick/qtquick-components.qdoc b/doc/src/qtquick/qtquick-components.qdoc
index d8327fd2f8..e7908915ff 100644
--- a/doc/src/qtquick/qtquick-components.qdoc
+++ b/doc/src/qtquick/qtquick-components.qdoc
@@ -458,7 +458,7 @@
user interfaces for \l{glossary-device}{devices}.
Qt Quick Controls 2 achieve improved efficiency by employing a simplified
- \l {Styling Qt Quick Controls 2}{styling architecture} when compared to
+ \l {Styling Qt Quick Controls}{styling architecture} when compared to
Qt Quick Controls, on which the module is based. The visual editor reads the
\c qtquickcontrols2.conf file that specifies the preferred style and some
style-specific arguments. To change the style, select another style from
diff --git a/doc/src/qtquick/qtquick-timeline.qdoc b/doc/src/qtquick/qtquick-timeline.qdoc
index b3b40a8167..59eda721c0 100644
--- a/doc/src/qtquick/qtquick-timeline.qdoc
+++ b/doc/src/qtquick/qtquick-timeline.qdoc
@@ -199,12 +199,15 @@
To remove all the changes you recorded for a property, right-click the
property name on the timeline and select \uicontrol {Remove Property}.
- Keyframes a marked on the timeline by using markers of different colors and
+ Keyframes are marked on the timeline by using markers of different colors and
shapes, depending on whether they are active or inactive or whether you have
applied easing curves to them, for example.
- To edit the value of the selected keyframe, select
- \uicontrol {Edit Value for Keyframe} in the context menu.
+ To edit the value of a keyframe, double-click a keyframe marker or select
+ \uicontrol {Edit Keyframe} in the context menu. In the \uicontrol Frame
+ field, you can set the frame and the value:
+
+ \image studio-edit-keyframe.png "Edit Keyframe dialog"
You can copy the keyframes from the keyframe track for an item and
paste them to the keyframe track of another item. To copy all
@@ -241,13 +244,14 @@
components can appear to pick up speed, slow down, or bounce back at the
end of the animation. By default, the animations you specify on the
timeline are \e linear, which means that they move from the beginning to
- the end at a constant speed. You can use the \e {curve picker} to edit the
- easing curve between two keyframes. You can also use the more advanced
- \e {curve editor} to edit the curves for the whole animation.
+ the end at a constant speed. You can use the \uicontrol {Easing Curve Editor}
+ to edit the easing curve between two keyframes. You can also use the more
+ advanced \uicontrol {Curve Editor (C)} to edit the curves for the whole
+ animation.
\section2 Attaching Easing Curves to Keyframes
- \image studio-curve-picker.png
+ \image studio-easing-curve-editor.png "Easing Curve Editor"
You can use the preset curves or modify them by dragging the curve handlers
around. You can add points to the curve and drag them and the point handlers
@@ -255,22 +259,21 @@
custom curve. For more information about easing curve types, see the
documentation for \l [QML] {PropertyAnimation}{easing curves}.
- To zoom into and out of the easing curve picker, use the mouse roller. To
+ To zoom into and out of the easing curve editor, use the mouse roller. To
reset the zoom factor, right-click in the picker and select
\uicontrol {Reset Zoom}.
To attach easing curves to keyframes:
\list 1
- \li Select a keyframe on the timeline.
- \li Select \uicontrol {Curve Picker (C)} on the toolbar, or press
- \key C to open the curve picker.
+ \li Right-click a keyframe on the timeline and select
+ \uicontrol {Easing Curve Editor} in the context menu.
\li Select an easing curve in the \uicontrol Presets tab.
\li In the \uicontrol {Duration (ms)} field, select the duration of the
easing function in milliseconds.
\li Select \uicontrol Preview to preview the curve.
\li Select \uicontrol OK to attach the easing curve to the keyframe
- and to close the curve picker.
+ and to close the easing curve editor.
\endlist
When you attach easing curves to keyframes, the shape of the keyframe
@@ -283,8 +286,8 @@
To customize easing curves:
\list 1
- \li In the curve picker, select an easing curve in the
- \uicontrol Presets tab.
+ \li In the \uicontrol {Easing Curve Editor}, select an easing curve in
+ the \uicontrol Presets tab.
\li Drag the curve handlers to modify the curve.
\li Right-click in the editor, and select \uicontrol {Add Point} to add
points to the curve.
@@ -297,7 +300,7 @@
\uicontrol Custom tab.
\endlist
- To paste easing curve definitions to the curve picker as text, select
+ To paste easing curve definitions to the easing curve editor as text, select
the \uicontrol Text tab.
\section1 Editing Animation Curves
@@ -307,9 +310,9 @@
modify the curve. You can modify the appearance of the curve in the style
editor.
- You can also edit easing curves that you added with the curve picker.
+ You can also edit easing curves that you added with the easing curve editor.
- \image studio-curve-editor.png
+ \image studio-curve-editor.png "Curve Editor"
To edit animation curves:
diff --git a/doc/src/vcs/creator-vcs-git.qdoc b/doc/src/vcs/creator-vcs-git.qdoc
index 8705df4939..ec6b1a2ebe 100644
--- a/doc/src/vcs/creator-vcs-git.qdoc
+++ b/doc/src/vcs/creator-vcs-git.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
@@ -224,6 +224,13 @@
branch is shown in bold and underlined in the list of branches in the
\uicontrol {Git Branches} sidebar view.
+ \image qtcreator-vcs-gitbranch.png "Git Branches sidebar view"
+
+ Old entries and tags are filtered out of the list of branches
+ by default. To include them, select \inlineimage filtericon.png
+ (\uicontrol {Filter Tree}), and then select
+ \uicontrol {Include Old Entries} and \uicontrol {Include Tags}.
+
If you checked out a specific commit, the list of branches displays a
\e {Detached HEAD} entry.
@@ -233,8 +240,6 @@
To refresh the list of branches, click \inlineimage reload_gray.png
(\uicontrol Refresh).
- \image qtcreator-vcs-gitbranch.png "Git Branches sidebar view"
-
The following operations are supported in the context-menu for a branch:
\table
@@ -249,7 +254,8 @@
\li Remove a local branch. You cannot delete remote branches.
\row
\li \uicontrol Rename
- \li Rename a local branch. You cannot rename remote branches.
+ \li Rename a local branch or a tag. You cannot rename remote
+ branches.
\row
\li \uicontrol{Checkout}
\li Check out the selected branch and make it current. You can stash
@@ -302,12 +308,12 @@
\li Description
\row
\li \uicontrol{Fetch}
- \li Fetches all the branches and changes information from a
+ \li Fetch all the branches and changes information from a
specific remote repository, or from all remotes if applied
to \uicontrol {Remote Branches}.
\row
\li \uicontrol{Manage Remotes}
- \li Opens the \uicontrol Remotes dialog.
+ \li Open the \uicontrol Remotes dialog.
\endtable
\section3 Configuring Merge Tools
@@ -357,11 +363,33 @@
To browse a directory or the commit history and to apply actions on the
commits, select \uicontrol Tools > \uicontrol Git >
- \uicontrol {Actions on Commits}. You can checkout, revert, or cherry-pick
- commits or view them in the diff editor.
+ \uicontrol {Actions on Commits}.
\image creator-git-commit-actions.png "Select a Git Commit dialog"
+ You can apply the following actions on commits:
+
+ \table
+ \header
+ \li Menu Item
+ \li Description
+ \row
+ \li \uicontrol Archive
+ \li Package the commit as a ZIP or tarball.
+ \row
+ \li \uicontrol Checkout
+ \li Check out the change in a headless state.
+ \row
+ \li \uicontrol {Cherry Pick}
+ \li Cherry-pick the selected change to the local repository.
+ \row
+ \li \uicontrol Revert
+ \li Revert back to the state of the last commit.
+ \row
+ \li \uicontrol Show
+ \li Show the commit in the diff editor.
+ \endtable
+
\section1 Initializing Git Repositories
To start controlling a project directory that is currently not under
diff --git a/scripts/deployqtHelper_mac.sh b/scripts/deployqtHelper_mac.sh
index 1b312b0820..47c7613002 100755
--- a/scripts/deployqtHelper_mac.sh
+++ b/scripts/deployqtHelper_mac.sh
@@ -56,6 +56,19 @@ if [ ! -d "$designerDestDir" ]; then
done
fi
+# collect 3d assetimporter plugins
+assetimporterDestDir="$app_path/Contents/PlugIns/assetimporters"
+assetimporterSrcDir="$plugin_src/assetimporters"
+if [ -d "$assetimporterSrcDir" ]; then
+ if [ ! -d "$assetimporterDestDir" ]; then
+ echo "- Copying 3d assetimporter plugins"
+ mkdir -p "$assetimporterDestDir"
+ for plugin in "$assetimporterSrcDir"/*.dylib; do
+ cp "$plugin" "$assetimporterDestDir"/ || exit 1
+ done
+ fi
+fi
+
# copy Qt Quick 1 imports
importsDir="$app_path/Contents/Imports/qtquick1"
if [ -d "$quick1_src" ]; then
diff --git a/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.h b/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.h
index 5be50903df..3428944f68 100644
--- a/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.h
+++ b/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.h
@@ -39,7 +39,7 @@ class ValuesChangedCommand
friend bool operator ==(const ValuesChangedCommand &first, const ValuesChangedCommand &second);
public:
- enum TransactionOption { Start, End, None };
+ enum TransactionOption { Start = 1, End = 2, None = 0 };
ValuesChangedCommand();
explicit ValuesChangedCommand(const QVector<PropertyValueContainer> &valueChangeVector);
diff --git a/share/qtcreator/qml/qmlpuppet/container/propertyvaluecontainer.cpp b/share/qtcreator/qml/qmlpuppet/container/propertyvaluecontainer.cpp
index 19265df035..c460bbc712 100644
--- a/share/qtcreator/qml/qmlpuppet/container/propertyvaluecontainer.cpp
+++ b/share/qtcreator/qml/qmlpuppet/container/propertyvaluecontainer.cpp
@@ -74,12 +74,29 @@ TypeName PropertyValueContainer::dynamicTypeName() const
return m_dynamicTypeName;
}
+// The reflection flag indicates that a property change notification
+// is reflected. This means that the notification is the reaction to a
+// property change original done by the puppet itself.
+// In the Qt5InformationNodeInstanceServer such notification are
+// therefore ignored.
+
+void PropertyValueContainer::setReflectionFlag(bool b)
+{
+ m_isReflected = b;
+}
+
+bool PropertyValueContainer::isReflected() const
+{
+ return m_isReflected;
+}
+
QDataStream &operator<<(QDataStream &out, const PropertyValueContainer &container)
{
out << container.instanceId();
out << container.name();
out << container.value();
out << container.dynamicTypeName();
+ out << container.isReflected();
return out;
}
@@ -90,6 +107,7 @@ QDataStream &operator>>(QDataStream &in, PropertyValueContainer &container)
in >> container.m_name;
in >> container.m_value;
in >> container.m_dynamicTypeName;
+ in >> container.m_isReflected;
return in;
}
@@ -99,7 +117,8 @@ bool operator ==(const PropertyValueContainer &first, const PropertyValueContain
return first.m_instanceId == second.m_instanceId
&& first.m_name == second.m_name
&& first.m_value == second.m_value
- && first.m_dynamicTypeName == second.m_dynamicTypeName;
+ && first.m_dynamicTypeName == second.m_dynamicTypeName
+ && first.m_isReflected == second.m_isReflected;
}
bool operator <(const PropertyValueContainer &first, const PropertyValueContainer &second)
diff --git a/share/qtcreator/qml/qmlpuppet/container/propertyvaluecontainer.h b/share/qtcreator/qml/qmlpuppet/container/propertyvaluecontainer.h
index 4d30f3fb7e..8770355cfd 100644
--- a/share/qtcreator/qml/qmlpuppet/container/propertyvaluecontainer.h
+++ b/share/qtcreator/qml/qmlpuppet/container/propertyvaluecontainer.h
@@ -50,12 +50,15 @@ public:
QVariant value() const;
bool isDynamic() const;
TypeName dynamicTypeName() const;
+ void setReflectionFlag(bool b);
+ bool isReflected() const;
private:
qint32 m_instanceId;
PropertyName m_name;
QVariant m_value;
TypeName m_dynamicTypeName;
+ bool m_isReflected = false;
};
QDataStream &operator<<(QDataStream &out, const PropertyValueContainer &container);
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/Arrow.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/Arrow.qml
index dc2fee6454..0176a55dfa 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/Arrow.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/Arrow.qml
@@ -30,12 +30,12 @@ import MouseArea3D 1.0
Model {
id: arrow
rotationOrder: Node.XYZr
- source: "meshes/Arrow.mesh"
+ source: "meshes/arrow.mesh"
property View3D view3D
property alias color: material.emissiveColor
property Node targetNode: null
- property bool isDragging: false
+ property bool dragging: false
readonly property bool hovering: mouseAreaYZ.hovering || mouseAreaXZ.hovering
@@ -43,10 +43,11 @@ Model {
property var _targetStartPos
signal positionCommit()
+ signal positionMove()
materials: DefaultMaterial {
id: material
- emissiveColor: mouseAreaFront.hovering ? "white" : Qt.rgba(1.0, 0.0, 0.0, 1.0)
+ emissiveColor: "white"
lighting: DefaultMaterial.NoLighting
}
@@ -59,7 +60,7 @@ Model {
_pointerPosPressed = mouseArea.mapPositionToScene(maskedPosition);
var sp = targetNode.scenePosition;
_targetStartPos = Qt.vector3d(sp.x, sp.y, sp.z);
- isDragging = true;
+ dragging = true;
}
function posInParent(mouseArea, pointerPosition)
@@ -85,6 +86,7 @@ Model {
return;
targetNode.position = posInParent(mouseArea, pointerPosition);
+ arrow.positionMove();
}
function handleReleased(mouseArea, pointerPosition)
@@ -93,7 +95,7 @@ Model {
return;
targetNode.position = posInParent(mouseArea, pointerPosition);
- isDragging = false;
+ dragging = false;
arrow.positionCommit();
}
@@ -104,7 +106,7 @@ Model {
y: -1.5
width: 12
height: 3
- rotation: Qt.vector3d(0, 90, 0)
+ rotation: Qt.vector3d(0, 0, 90)
grabsMouse: targetNode
onPressed: arrow.handlePressed(mouseAreaYZ, pointerPosition)
onDragged: arrow.handleDragged(mouseAreaYZ, pointerPosition)
@@ -118,12 +120,11 @@ Model {
y: -1.5
width: 12
height: 3
- rotation: Qt.vector3d(90, 90, 0)
+ rotation: Qt.vector3d(0, 90, 90)
grabsMouse: targetNode
onPressed: arrow.handlePressed(mouseAreaXZ, pointerPosition)
onDragged: arrow.handleDragged(mouseAreaXZ, pointerPosition)
onReleased: arrow.handleReleased(mouseAreaXZ, pointerPosition)
}
-
}
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/AutoScaleHelper.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/AutoScaleHelper.qml
index 2e8425016d..9ffd3aa85b 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/AutoScaleHelper.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/AutoScaleHelper.qml
@@ -39,11 +39,17 @@ Node {
onSceneTransformChanged: updateScale()
onAutoScaleChanged: updateScale()
+
Connections {
target: view3D.camera
onSceneTransformChanged: updateScale()
}
+ Connections {
+ target: designStudioNativeCameraControlHelper
+ onOverlayUpdateNeeded: updateScale()
+ }
+
function getScale(baseScale)
{
return Qt.vector3d(baseScale.x * relativeScale, baseScale.y * relativeScale,
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/CameraGizmo.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/CameraGizmo.qml
new file mode 100644
index 0000000000..14e45951ae
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/CameraGizmo.qml
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** 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
+
+IconGizmo {
+ id: cameraGizmo
+
+ iconSource: "qrc:///qtquickplugin/mockfiles/images/camera-pick-icon.png"
+ gizmoModel.source: "#Cube"
+ gizmoModel.materials: [
+ DefaultMaterial {
+ id: defaultMaterial
+ emissiveColor: "blue"
+ lighting: DefaultMaterial.NoLighting
+ }
+ ]
+}
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml
index a0a9c0e599..e19e75acb8 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml
@@ -44,23 +44,65 @@ Window {
property Node selectedNode: null
+ property var lightGizmos: []
+ property var cameraGizmos: []
+
signal objectClicked(var object)
signal commitObjectPosition(var object)
+ signal moveObjectPosition(var object)
function selectObject(object) {
selectedNode = object;
}
+ function emitObjectClicked(object) {
+ selectObject(object);
+ objectClicked(object);
+ }
+
+ function addLightGizmo(obj)
+ {
+ var component = Qt.createComponent("LightGizmo.qml");
+ if (component.status === Component.Ready) {
+ var gizmo = component.createObject(overlayScene,
+ {"view3D": overlayView, "targetNode": obj});
+ lightGizmos[lightGizmos.length] = gizmo;
+ gizmo.selected.connect(emitObjectClicked);
+ }
+ }
+
+ function addCameraGizmo(obj)
+ {
+ var component = Qt.createComponent("CameraGizmo.qml");
+ if (component.status === Component.Ready) {
+ var gizmo = component.createObject(overlayScene,
+ {"view3D": overlayView, "targetNode": obj});
+ cameraGizmos[cameraGizmos.length] = gizmo;
+ gizmo.selected.connect(emitObjectClicked);
+ }
+ }
+
+ // 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();
+
+ onWidthChanged: designStudioNativeCameraControlHelper.requestOverlayUpdate();
+ onHeightChanged: designStudioNativeCameraControlHelper.requestOverlayUpdate();
+
Node {
id: overlayScene
- Camera {
- id: overlayCamera
- projectionMode: usePerspectiveCheckbox.checked ? Camera.Perspective
- : Camera.Orthographic
- clipFar: editCamera.clipFar
- position: editCamera.position
- rotation: editCamera.rotation
+ PerspectiveCamera {
+ id: overlayPerspectiveCamera
+ clipFar: editPerspectiveCamera.clipFar
+ position: editPerspectiveCamera.position
+ rotation: editPerspectiveCamera.rotation
+ }
+
+ OrthographicCamera {
+ id: overlayOrthoCamera
+ position: editOrthoCamera.position
+ rotation: editOrthoCamera.rotation
}
MoveGizmo {
@@ -70,14 +112,12 @@ Window {
targetNode: viewWindow.selectedNode
position: viewWindow.selectedNode ? viewWindow.selectedNode.scenePosition
: Qt.vector3d(0, 0, 0)
- rotation: globalControl.checked || !viewWindow.selectedNode
- ? Qt.vector3d(0, 0, 0)
- : viewWindow.selectedNode.sceneRotation
-
+ globalOrientation: globalControl.checked
visible: selectedNode
view3D: overlayView
onPositionCommit: viewWindow.commitObjectPosition(selectedNode)
+ onPositionMove: viewWindow.moveObjectPosition(selectedNode)
}
AutoScaleHelper {
@@ -97,15 +137,14 @@ Window {
onTapped: {
var pickResult = editView.pick(eventPoint.scenePosition.x,
eventPoint.scenePosition.y);
- viewWindow.objectClicked(pickResult.objectHit);
- selectObject(pickResult.objectHit);
+ emitObjectClicked(pickResult.objectHit);
}
}
View3D {
id: editView
anchors.fill: parent
- camera: editCamera
+ camera: usePerspective ? editPerspectiveCamera : editOrthoCamera
Node {
id: mainSceneHelpers
@@ -119,15 +158,21 @@ Window {
PointLight {
id: pointLight
visible: showEditLight
- position: editCamera.position
+ position: usePerspective ? editPerspectiveCamera.position
+ : editOrthoCamera.position
}
- Camera {
- id: editCamera
+ PerspectiveCamera {
+ id: editPerspectiveCamera
y: 200
z: -300
clipFar: 100000
- projectionMode: usePerspective ? Camera.Perspective : Camera.Orthographic
+ }
+
+ OrthographicCamera {
+ id: editOrthoCamera
+ y: 200
+ z: -300
}
}
}
@@ -135,7 +180,7 @@ Window {
View3D {
id: overlayView
anchors.fill: parent
- camera: overlayCamera
+ camera: usePerspective ? overlayPerspectiveCamera : overlayOrthoCamera
scene: overlayScene
}
@@ -145,7 +190,7 @@ Window {
targetView: overlayView
offsetX: 0
offsetY: 45
- visible: moveGizmo.isDragging
+ visible: moveGizmo.dragging
Rectangle {
color: "white"
@@ -204,7 +249,7 @@ Window {
CheckBox {
id: globalControl
checked: true
- text: qsTr("Use global orientation")
+ text: qsTr("Use Global Orientation")
onCheckedChanged: cameraControl.forceActiveFocus()
}
}
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/IconGizmo.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/IconGizmo.qml
new file mode 100644
index 0000000000..56bec4ae0c
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/IconGizmo.qml
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** 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
+
+Node {
+ id: iconGizmo
+
+ property View3D view3D
+ property bool highlightOnHover: true
+ property Node targetNode: null
+
+ property alias gizmoModel: gizmoModel
+ property alias iconSource: iconImage.source
+
+ signal positionCommit()
+ signal selected(Node node)
+
+ position: targetNode ? targetNode.scenePosition : Qt.vector3d(0, 0, 0)
+ rotation: targetNode ? targetNode.sceneRotation : Qt.vector3d(0, 0, 0)
+ visible: targetNode ? targetNode.visible : false
+
+ Model {
+ id: gizmoModel
+ scale: Qt.vector3d(0.05, 0.05, 0.05)
+ visible: iconGizmo.visible
+ }
+ Overlay2D {
+ id: gizmoLabel
+ targetNode: gizmoModel
+ targetView: view3D
+ offsetX: 0
+ offsetY: 0
+ visible: iconGizmo.visible && !isBehindCamera
+ parent: view3D
+
+ Rectangle {
+ width: 24
+ height: 24
+ x: -width / 2
+ y: -height
+ color: "transparent"
+ border.color: "#7777ff"
+ border.width: highlightOnHover && iconMouseArea.containsMouse ? 2 : 0
+ radius: 5
+ Image {
+ id: iconImage
+ anchors.fill: parent
+ MouseArea {
+ id: iconMouseArea
+ anchors.fill: parent
+ onClicked: selected(targetNode)
+ hoverEnabled: highlightOnHover
+ }
+ }
+ }
+ }
+}
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/LightGizmo.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/LightGizmo.qml
new file mode 100644
index 0000000000..d3a5932b39
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/LightGizmo.qml
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** 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
+
+IconGizmo {
+ id: lightGizmo
+
+ iconSource: "qrc:///qtquickplugin/mockfiles/images/light-pick-icon.png"
+ gizmoModel.source: "#Sphere"
+ gizmoModel.materials: [
+ DefaultMaterial {
+ id: defaultMaterial
+ emissiveColor: "yellow"
+ lighting: DefaultMaterial.NoLighting
+ }
+ ]
+}
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/MoveGizmo.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/MoveGizmo.qml
index 73b80018a9..7ad5a2a011 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/MoveGizmo.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/MoveGizmo.qml
@@ -25,56 +25,131 @@
import QtQuick 2.0
import QtQuick3D 1.0
+import MouseArea3D 1.0
Node {
- id: arrows
+ id: moveGizmo
property View3D view3D
property bool highlightOnHover: false
property Node targetNode: null
- readonly property bool isDragging: arrowX.isDragging || arrowY.isDragging || arrowZ.isDragging
+ property bool globalOrientation: true
+ readonly property bool dragging: arrowX.dragging || arrowY.dragging || arrowZ.dragging
+ || centerMouseArea.dragging
- scale: Qt.vector3d(5, 5, 5)
+ signal positionCommit()
+ signal positionMove()
- property alias arrowX: arrowX
- property alias arrowY: arrowY
- property alias arrowZ: arrowZ
+ Node {
+ rotation: globalOrientation || !targetNode ? Qt.vector3d(0, 0, 0) : targetNode.sceneRotation
- signal positionCommit()
+ Arrow {
+ id: arrowX
+ objectName: "Arrow X"
+ rotation: Qt.vector3d(0, 0, -90)
+ targetNode: moveGizmo.targetNode
+ color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(1, 0, 0, 1))
+ : Qt.rgba(1, 0, 0, 1)
+ view3D: moveGizmo.view3D
- Arrow {
- id: arrowX
- objectName: "Arrow X"
- rotation: Qt.vector3d(0, -90, 0)
- targetNode: arrows.targetNode
- color: highlightOnHover && hovering ? Qt.lighter(Qt.rgba(1, 0, 0, 1))
- : Qt.rgba(1, 0, 0, 1)
- view3D: arrows.view3D
+ onPositionCommit: moveGizmo.positionCommit()
+ onPositionMove: moveGizmo.positionMove()
+ }
- onPositionCommit: arrows.positionCommit()
- }
+ Arrow {
+ id: arrowY
+ objectName: "Arrow Y"
+ rotation: Qt.vector3d(0, 0, 0)
+ targetNode: moveGizmo.targetNode
+ color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0, 1, 1))
+ : Qt.rgba(0, 0, 1, 1)
+ view3D: moveGizmo.view3D
+
+ onPositionCommit: moveGizmo.positionCommit()
+ onPositionMove: moveGizmo.positionMove()
+ }
- Arrow {
- id: arrowY
- objectName: "Arrow Y"
- rotation: Qt.vector3d(90, 0, 0)
- targetNode: arrows.targetNode
- color: highlightOnHover && hovering ? Qt.lighter(Qt.rgba(0, 0, 1, 1))
- : Qt.rgba(0, 0, 1, 1)
- view3D: arrows.view3D
+ Arrow {
+ id: arrowZ
+ objectName: "Arrow Z"
+ rotation: Qt.vector3d(90, 0, 0)
+ targetNode: moveGizmo.targetNode
+ color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0.6, 0, 1))
+ : Qt.rgba(0, 0.6, 0, 1)
+ view3D: moveGizmo.view3D
+
+ onPositionCommit: moveGizmo.positionCommit()
+ onPositionMove: moveGizmo.positionMove()
+ }
- onPositionCommit: arrows.positionCommit()
}
- Arrow {
- id: arrowZ
- objectName: "Arrow Z"
- rotation: Qt.vector3d(0, 180, 0)
- targetNode: arrows.targetNode
- color: highlightOnHover && hovering ? Qt.lighter(Qt.rgba(0, 0.6, 0, 1))
- : Qt.rgba(0, 0.6, 0, 1)
- view3D: arrows.view3D
+ Model {
+ id: centerBall
+
+ source: "#Sphere"
+ scale: Qt.vector3d(0.024, 0.024, 0.024)
+ materials: DefaultMaterial {
+ id: material
+ emissiveColor: highlightOnHover
+ && (centerMouseArea.hovering || centerMouseArea.dragging)
+ ? Qt.lighter(Qt.rgba(0.5, 0.5, 0.5, 1))
+ : Qt.rgba(0.5, 0.5, 0.5, 1)
+ lighting: DefaultMaterial.NoLighting
+ }
+
+ MouseArea3D {
+ id: centerMouseArea
+ view3D: moveGizmo.view3D
+ x: -60
+ y: -60
+ width: 120
+ height: 120
+ rotation: view3D.camera.rotation
+ grabsMouse: moveGizmo.targetNode
+ priority: 1
+
+ property var _pointerPosPressed
+ property var _targetStartPos
+
+ function posInParent(pointerPosition)
+ {
+ var scenePointerPos = mapPositionToScene(pointerPosition);
+ var sceneRelativeDistance = Qt.vector3d(
+ scenePointerPos.x - _pointerPosPressed.x,
+ scenePointerPos.y - _pointerPosPressed.y,
+ scenePointerPos.z - _pointerPosPressed.z);
+
+ var newScenePos = Qt.vector3d(
+ _targetStartPos.x + sceneRelativeDistance.x,
+ _targetStartPos.y + sceneRelativeDistance.y,
+ _targetStartPos.z + sceneRelativeDistance.z);
+
+ return moveGizmo.targetNode.parent.mapPositionFromScene(newScenePos);
+ }
+
+ onPressed: {
+ if (!moveGizmo.targetNode)
+ return;
+
+ _pointerPosPressed = mapPositionToScene(pointerPosition);
+ var sp = moveGizmo.targetNode.scenePosition;
+ _targetStartPos = Qt.vector3d(sp.x, sp.y, sp.z);
+ }
+ onDragged: {
+ if (!moveGizmo.targetNode)
+ return;
+
+ moveGizmo.targetNode.position = posInParent(pointerPosition);
+ moveGizmo.positionMove();
+ }
+ onReleased: {
+ if (!moveGizmo.targetNode)
+ return;
- onPositionCommit: arrows.positionCommit()
+ moveGizmo.targetNode.position = posInParent(pointerPosition);
+ moveGizmo.positionCommit();
+ }
+ }
}
}
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/Overlay2D.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/Overlay2D.qml
index 7e1e231133..1392c60cb2 100644
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/Overlay2D.qml
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/Overlay2D.qml
@@ -34,6 +34,8 @@ Item {
property real offsetX: 0
property real offsetY: 0
+ property bool isBehindCamera
+
onTargetNodeChanged: updateOverlay()
Connections {
@@ -46,13 +48,20 @@ Item {
onSceneTransformChanged: updateOverlay()
}
+ Connections {
+ target: designStudioNativeCameraControlHelper
+ onOverlayUpdateNeeded: updateOverlay()
+ }
+
function updateOverlay()
{
- var scenePos = targetNode.scenePosition;
+ var scenePos = targetNode ? targetNode.scenePosition : Qt.vector3d(0, 0, 0);
var scenePosWithOffset = Qt.vector3d(scenePos.x + offsetX, scenePos.y + offsetY, scenePos.z);
- var viewPos = targetView.mapFrom3DScene(scenePosWithOffset);
+ var viewPos = targetView ? targetView.mapFrom3DScene(scenePosWithOffset)
+ : Qt.vector3d(0, 0, 0);
root.x = viewPos.x;
root.y = viewPos.y;
- root.z = 100000 - viewPos.z; // flip left-handed to right-handed
+
+ isBehindCamera = viewPos.z <= 0;
}
}
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/camera-pick-icon.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/camera-pick-icon.png
new file mode 100644
index 0000000000..47610f5450
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/camera-pick-icon.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/camera-pick-icon@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/camera-pick-icon@2x.png
new file mode 100644
index 0000000000..769934ae01
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/camera-pick-icon@2x.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/light-pick-icon.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/light-pick-icon.png
new file mode 100644
index 0000000000..b6ac242cbd
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/light-pick-icon.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/light-pick-icon@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/light-pick-icon@2x.png
new file mode 100644
index 0000000000..d3b041a604
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/images/light-pick-icon@2x.png
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/meshes/Arrow.mesh b/share/qtcreator/qml/qmlpuppet/mockfiles/meshes/Arrow.mesh
deleted file mode 100644
index f872b5e008..0000000000
--- a/share/qtcreator/qml/qmlpuppet/mockfiles/meshes/Arrow.mesh
+++ /dev/null
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/meshes/arrow.mesh b/share/qtcreator/qml/qmlpuppet/mockfiles/meshes/arrow.mesh
new file mode 100644
index 0000000000..be5f4df3b8
--- /dev/null
+++ b/share/qtcreator/qml/qmlpuppet/mockfiles/meshes/arrow.mesh
Binary files differ
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.cpp
index c05e8230bf..d681e10698 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.cpp
@@ -30,10 +30,14 @@ namespace Internal {
CameraControlHelper::CameraControlHelper()
: QObject()
{
- m_timer.setInterval(16);
- m_timer.setSingleShot(false);
- QObject::connect(&m_timer, &QTimer::timeout,
+ 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()
@@ -49,11 +53,17 @@ void CameraControlHelper::handleUpdateTimer()
void CameraControlHelper::setEnabled(bool enabled)
{
if (enabled)
- m_timer.start();
+ m_inputUpdateTimer.start();
else
- m_timer.stop();
+ m_inputUpdateTimer.stop();
m_enabled = enabled;
}
+void CameraControlHelper::requestOverlayUpdate()
+{
+ if (!m_overlayUpdateTimer.isActive())
+ m_overlayUpdateTimer.start();
+}
+
}
}
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.h
index 87ef1025ff..be00596ce8 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.h
@@ -41,16 +41,20 @@ public:
bool enabled();
void setEnabled(bool enabled);
+ Q_INVOKABLE void requestOverlayUpdate();
+
public slots:
void handleUpdateTimer();
signals:
void updateInputs();
void enabledChanged(bool enabled);
+ void overlayUpdateNeeded();
private:
bool m_enabled = false;
- QTimer m_timer;
+ QTimer m_inputUpdateTimer;
+ QTimer m_overlayUpdateTimer;
};
}
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp
index e3ec5c704b..4c1fdcc78e 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp
@@ -80,6 +80,11 @@ qreal MouseArea3D::height() const
return m_height;
}
+int MouseArea3D::priority() const
+{
+ return m_priority;
+}
+
void MouseArea3D::setView3D(QQuick3DViewport *view3D)
{
if (m_view3D == view3D)
@@ -134,6 +139,15 @@ void MouseArea3D::setHeight(qreal height)
emit heightChanged(height);
}
+void MouseArea3D::setPriority(int level)
+{
+ if (m_priority == level)
+ return;
+
+ m_priority = level;
+ emit priorityChanged(level);
+}
+
void MouseArea3D::componentComplete()
{
if (!m_view3D) {
@@ -193,51 +207,94 @@ QVector3D MouseArea3D::getMousePosInPlane(const QPointF &mousePosInView) const
bool MouseArea3D::eventFilter(QObject *, QEvent *event)
{
+ if (m_grabsMouse && s_mouseGrab && s_mouseGrab != this
+ && (m_priority <= s_mouseGrab->m_priority || s_mouseGrab->m_dragging)) {
+ return false;
+ }
+
+ auto mouseOnTopOfMouseArea = [this](const QVector3D &mousePosInPlane) -> bool {
+ return !qFuzzyCompare(mousePosInPlane.z(), -1)
+ && mousePosInPlane.x() >= float(m_x)
+ && mousePosInPlane.x() <= float(m_x + m_width)
+ && mousePosInPlane.y() >= float(m_y)
+ && mousePosInPlane.y() <= float(m_y + m_height);
+ };
+
switch (event->type()) {
+ case QEvent::MouseButtonPress: {
+ auto const mouseEvent = static_cast<QMouseEvent *>(event);
+ if (mouseEvent->button() == Qt::LeftButton) {
+ m_mousePosInPlane = getMousePosInPlane(mouseEvent->pos());
+ if (mouseOnTopOfMouseArea(m_mousePosInPlane)) {
+ setDragging(true);
+ emit pressed(m_mousePosInPlane);
+ if (m_grabsMouse) {
+ if (s_mouseGrab && s_mouseGrab != this) {
+ s_mouseGrab->setDragging(false);
+ s_mouseGrab->setHovering(false);
+ }
+ s_mouseGrab = this;
+ setHovering(true);
+ }
+ event->accept();
+ return true;
+ }
+ }
+ break;
+ }
+ case QEvent::MouseButtonRelease: {
+ auto const mouseEvent = static_cast<QMouseEvent *>(event);
+ if (mouseEvent->button() == Qt::LeftButton) {
+ if (m_dragging) {
+ QVector3D mousePosInPlane = getMousePosInPlane(mouseEvent->pos());
+ if (qFuzzyCompare(mousePosInPlane.z(), -1))
+ mousePosInPlane = m_mousePosInPlane;
+ setDragging(false);
+ emit released(mousePosInPlane);
+ if (m_grabsMouse) {
+ if (s_mouseGrab && s_mouseGrab != this) {
+ s_mouseGrab->setDragging(false);
+ s_mouseGrab->setHovering(false);
+ }
+ if (mouseOnTopOfMouseArea(mousePosInPlane)) {
+ s_mouseGrab = this;
+ setHovering(true);
+ } else {
+ s_mouseGrab = nullptr;
+ setHovering(false);
+ }
+ }
+ event->accept();
+ return true;
+ }
+ }
+ break;
+ }
+ case QEvent::MouseMove:
case QEvent::HoverMove: {
- if (m_grabsMouse && s_mouseGrab && s_mouseGrab != this)
- break;
-
auto const mouseEvent = static_cast<QMouseEvent *>(event);
const QVector3D mousePosInPlane = getMousePosInPlane(mouseEvent->pos());
- if (qFuzzyCompare(mousePosInPlane.z(), -1))
- break;
-
- const bool mouseOnTopOfMouseArea =
- mousePosInPlane.x() >= float(m_x) &&
- mousePosInPlane.x() <= float(m_x + m_width) &&
- mousePosInPlane.y() >= float(m_y) &&
- mousePosInPlane.y() <= float(m_y + m_height);
+ const bool hasMouse = mouseOnTopOfMouseArea(mousePosInPlane);
- const bool buttonPressed = QGuiApplication::mouseButtons().testFlag(Qt::LeftButton);
+ setHovering(hasMouse);
- // The filter will detect a mouse press on the view, but not a mouse release, since the
- // former is not accepted by the view, which means that the release will end up being
- // sent elsewhere. So we need this extra logic inside HoverMove, rather than in
- // MouseButtonRelease, which would otherwise be more elegant.
+ if (m_grabsMouse) {
+ if (m_hovering && s_mouseGrab && s_mouseGrab != this)
+ s_mouseGrab->setHovering(false);
- if (m_hovering != mouseOnTopOfMouseArea) {
- m_hovering = mouseOnTopOfMouseArea;
- emit hoveringChanged();
+ if (m_hovering || m_dragging)
+ s_mouseGrab = this;
+ else if (s_mouseGrab == this)
+ s_mouseGrab = nullptr;
}
- if (!m_dragging && m_hovering && buttonPressed) {
- m_dragging = true;
- emit pressed(mousePosInPlane);
- emit draggingChanged();
- } else if (m_dragging && !buttonPressed) {
- m_dragging = false;
- emit released(mousePosInPlane);
- emit draggingChanged();
- }
-
- if (m_grabsMouse)
- s_mouseGrab = m_hovering || m_dragging ? this : nullptr;
-
- if (m_dragging)
+ if (m_dragging && !qFuzzyCompare(mousePosInPlane.z(), -1)) {
+ m_mousePosInPlane = mousePosInPlane;
emit dragged(mousePosInPlane);
+ }
- break; }
+ break;
+ }
default:
break;
}
@@ -245,6 +302,24 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
return false;
}
+void MouseArea3D::setDragging(bool enable)
+{
+ if (m_dragging == enable)
+ return;
+
+ m_dragging = enable;
+ emit draggingChanged();
+}
+
+void MouseArea3D::setHovering(bool enable)
+{
+ if (m_hovering == enable)
+ return;
+
+ m_hovering = enable;
+ emit hoveringChanged();
+}
+
}
}
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.h
index b42b438b47..99a34be353 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.h
@@ -48,6 +48,7 @@ class MouseArea3D : public QQuick3DNode
Q_PROPERTY(qreal height READ height WRITE setHeight NOTIFY heightChanged)
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_INTERFACES(QQmlParserStatus)
@@ -60,6 +61,7 @@ public:
qreal y() const;
qreal width() const;
qreal height() const;
+ int priority() const;
bool hovering() const;
bool dragging() const;
@@ -73,6 +75,7 @@ public slots:
void setY(qreal y);
void setWidth(qreal width);
void setHeight(qreal height);
+ void setPriority(int level);
Q_INVOKABLE QVector3D rayIntersectsPlane(const QVector3D &rayPos0,
const QVector3D &rayPos1,
@@ -86,6 +89,7 @@ signals:
void yChanged(qreal y);
void widthChanged(qreal width);
void heightChanged(qreal height);
+ void priorityChanged(int level);
void hoveringChanged();
void draggingChanged();
@@ -100,6 +104,9 @@ protected:
bool eventFilter(QObject *obj, QEvent *event) override;
private:
+ void setDragging(bool enable);
+ void setHovering(bool enable);
+
Q_DISABLE_COPY(MouseArea3D)
QQuick3DViewport *m_view3D = nullptr;
@@ -107,6 +114,7 @@ private:
qreal m_y;
qreal m_width;
qreal m_height;
+ int m_priority = 0;
bool m_hovering = false;
bool m_dragging = false;
@@ -115,6 +123,7 @@ private:
static MouseArea3D *s_mouseGrab;
bool m_grabsMouse;
+ QVector3D m_mousePosInPlane;
};
}
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp
index 2f0244ddeb..83382fb198 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp
@@ -396,6 +396,11 @@ void ObjectNodeInstance::setHideInEditor(bool)
{
}
+void ObjectNodeInstance::setModifiedFlag(bool b)
+{
+ m_isModified = b;
+}
+
QVariant ObjectNodeInstance::convertEnumToValue(const QVariant &value, const PropertyName &name)
{
Q_ASSERT(value.canConvert<Enumeration>());
@@ -420,6 +425,9 @@ void ObjectNodeInstance::setPropertyVariant(const PropertyName &name, const QVar
if (ignoredProperties().contains(name))
return;
+ if (m_isModified)
+ return;
+
QQmlProperty property(object(), QString::fromUtf8(name), context());
if (!property.isValid())
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h
index 8aa7ce4ad4..ced76dee58 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h
@@ -195,6 +195,8 @@ public:
void virtual setHideInEditor(bool b);
+ void setModifiedFlag(bool b);
+
protected:
explicit ObjectNodeInstance(QObject *object);
void doResetProperty(const PropertyName &propertyName);
@@ -220,6 +222,7 @@ private:
qint32 m_instanceId;
bool m_deleteHeldInstance;
bool m_isInLayoutable;
+ bool m_isModified = false;
static QHash<EnumerationName, QVariant> m_enumationValueHash;
};
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
index b1fa8be60d..d97cc2d503 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
@@ -56,6 +56,7 @@
#include "tokencommand.h"
#include "removesharedmemorycommand.h"
#include "changeselectioncommand.h"
+#include "objectnodeinstance.h"
#include "dummycontextobject.h"
#include "../editor3d/cameracontrolhelper.h"
@@ -98,6 +99,10 @@ QObject *Qt5InformationNodeInstanceServer::createEditView3D(QQmlEngine *engine)
QObject::connect(window, SIGNAL(objectClicked(QVariant)), this, SLOT(objectClicked(QVariant)));
QObject::connect(window, SIGNAL(commitObjectPosition(QVariant)),
this, SLOT(handleObjectPositionCommit(QVariant)));
+ QObject::connect(window, SIGNAL(moveObjectPosition(QVariant)),
+ this, SLOT(handleObjectPositionMove(QVariant)));
+ QObject::connect(&m_moveTimer, &QTimer::timeout,
+ this, &Qt5InformationNodeInstanceServer::handleObjectPositionMoveTimeout);
//For macOS we have to use the 4.1 core profile
QSurfaceFormat surfaceFormat = window->requestedFormat();
@@ -149,21 +154,62 @@ Qt5InformationNodeInstanceServer::vectorToPropertyValue(
return result;
}
-void Qt5InformationNodeInstanceServer::handleObjectPositionCommit(const QVariant &object)
+void Qt5InformationNodeInstanceServer::modifyVariantValue(
+ const QVariant &node,
+ const PropertyName &propertyName,
+ ValuesModifiedCommand::TransactionOption option)
{
- auto *obj = object.value<QObject *>();
+ PropertyName targetPopertyName;
+
+ // Position is a special case, because the position can be 'position.x 'or simply 'x'.
+ // We prefer 'x'.
+ if (propertyName != "position")
+ targetPopertyName = propertyName;
+
+ auto *obj = node.value<QObject *>();
+
if (obj) {
- /* We do have to split position into position.x, position.y, position.z */
- nodeInstanceClient()->valuesModified(createValuesModifiedCommand(vectorToPropertyValue(
- instanceForObject(obj),
- "position",
- obj->property("position"))));
+ ServerNodeInstance instance = instanceForObject(obj);
+
+ if (option == ValuesModifiedCommand::TransactionOption::Start)
+ instance.setModifiedFlag(true);
+ else if (option == ValuesModifiedCommand::TransactionOption::End)
+ instance.setModifiedFlag(false);
+
+ // We do have to split position into position.x, position.y, position.z
+ ValuesModifiedCommand command = createValuesModifiedCommand(vectorToPropertyValue(
+ instance,
+ targetPopertyName,
+ obj->property(propertyName)));
+
+ command.transactionOption = option;
+
+ nodeInstanceClient()->valuesModified(command);
}
}
+void Qt5InformationNodeInstanceServer::handleObjectPositionCommit(const QVariant &object)
+{
+ modifyVariantValue(object, "position", ValuesModifiedCommand::TransactionOption::End);
+ m_movedNode = {};
+ m_moveTimer.stop();
+}
+
+void Qt5InformationNodeInstanceServer::handleObjectPositionMove(const QVariant &object)
+{
+ if (m_movedNode.isNull()) {
+ modifyVariantValue(object, "position", ValuesModifiedCommand::TransactionOption::Start);
+ } else {
+ if (!m_moveTimer.isActive())
+ m_moveTimer.start();
+ }
+ m_movedNode = object;
+}
+
Qt5InformationNodeInstanceServer::Qt5InformationNodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) :
Qt5NodeInstanceServer(nodeInstanceClient)
{
+ m_moveTimer.setInterval(100);
}
void Qt5InformationNodeInstanceServer::sendTokenBack()
@@ -236,6 +282,11 @@ void Qt5InformationNodeInstanceServer::modifyProperties(
nodeInstanceClient()->valuesModified(createValuesModifiedCommand(properties));
}
+void Qt5InformationNodeInstanceServer::handleObjectPositionMoveTimeout()
+{
+ modifyVariantValue(m_movedNode, "position", ValuesModifiedCommand::TransactionOption::None);
+}
+
QObject *Qt5InformationNodeInstanceServer::findRootNodeOf3DViewport(
const QList<ServerNodeInstance> &instanceList) const
{
@@ -252,6 +303,19 @@ QObject *Qt5InformationNodeInstanceServer::findRootNodeOf3DViewport(
return nullptr;
}
+void Qt5InformationNodeInstanceServer::findCamerasAndLights(
+ const QList<ServerNodeInstance> &instanceList,
+ QObjectList &cameras, QObjectList &lights) const
+{
+ QObjectList objList;
+ for (const ServerNodeInstance &instance : instanceList) {
+ if (instance.isSubclassOf("QQuick3DCamera"))
+ cameras << instance.internalObject();
+ else if (instance.isSubclassOf("QQuick3DAbstractLight"))
+ lights << instance.internalObject();
+ }
+}
+
void Qt5InformationNodeInstanceServer::setup3DEditView(const QList<ServerNodeInstance> &instanceList)
{
ServerNodeInstance root = rootNodeInstance();
@@ -279,6 +343,19 @@ void Qt5InformationNodeInstanceServer::setup3DEditView(const QList<ServerNodeIns
parentProperty.write(objectToVariant(m_editView3D));
QQmlProperty completeSceneProperty(m_editView3D, "showLight", context());
completeSceneProperty.write(showCustomLight);
+
+ // Create camera and light gizmos
+ QObjectList cameras;
+ QObjectList lights;
+ findCamerasAndLights(instanceList, cameras, lights);
+ for (auto &obj : qAsConst(cameras)) {
+ QMetaObject::invokeMethod(m_editView3D, "addCameraGizmo",
+ Q_ARG(QVariant, objectToVariant(obj)));
+ }
+ for (auto &obj : qAsConst(lights)) {
+ QMetaObject::invokeMethod(m_editView3D, "addLightGizmo",
+ Q_ARG(QVariant, objectToVariant(obj)));
+ }
}
}
@@ -471,4 +548,21 @@ void Qt5InformationNodeInstanceServer::changeSelection(const ChangeSelectionComm
}
}
+void Qt5InformationNodeInstanceServer::changePropertyValues(const ChangeValuesCommand &command)
+{
+ bool hasDynamicProperties = false;
+ const QVector<PropertyValueContainer> values = command.valueChanges();
+ for (const PropertyValueContainer &container : values) {
+ if (!container.isReflected()) {
+ hasDynamicProperties |= container.isDynamic();
+ setInstancePropertyVariant(container);
+ }
+ }
+
+ if (hasDynamicProperties)
+ refreshBindings();
+
+ startRenderTimer();
+}
+
} // namespace QmlDesigner
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h
index c574a6ed11..e8a0291a9f 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h
@@ -27,6 +27,10 @@
#include "qt5nodeinstanceserver.h"
#include "tokencommand.h"
+#include "valueschangedcommand.h"
+
+#include <QTimer>
+#include <QVariant>
namespace QmlDesigner {
@@ -43,10 +47,12 @@ public:
void token(const TokenCommand &command) override;
void removeSharedMemory(const RemoveSharedMemoryCommand &command) override;
void changeSelection(const ChangeSelectionCommand &command) override;
+ void changePropertyValues(const ChangeValuesCommand &command) override;
private slots:
void objectClicked(const QVariant &object);
void handleObjectPositionCommit(const QVariant &object);
+ void handleObjectPositionMove(const QVariant &object);
protected:
void collectItemChangesAndSendChangeCommands() override;
@@ -58,17 +64,25 @@ protected:
void modifyProperties(const QVector<InstancePropertyValueTriple> &properties);
private:
+ void handleObjectPositionMoveTimeout();
QObject *createEditView3D(QQmlEngine *engine);
void setup3DEditView(const QList<ServerNodeInstance> &instanceList);
QObject *findRootNodeOf3DViewport(const QList<ServerNodeInstance> &instanceList) const;
+ void findCamerasAndLights( const QList<ServerNodeInstance> &instanceList,
+ QObjectList &cameras, QObjectList &lights) const;
QVector<InstancePropertyValueTriple> vectorToPropertyValue(const ServerNodeInstance &instance,
const PropertyName &propertyName,
const QVariant &variant);
+ void modifyVariantValue(const QVariant &node,
+ const PropertyName &propertyName,
+ ValuesModifiedCommand::TransactionOption option);
QObject *m_editView3D = nullptr;
QSet<ServerNodeInstance> m_parentChangedSet;
QList<ServerNodeInstance> m_completedComponentList;
QList<TokenCommand> m_tokenList;
+ QTimer m_moveTimer;
+ QVariant m_movedNode;
};
} // namespace QmlDesigner
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp
index 376ca29524..b128161aee 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp
@@ -129,6 +129,11 @@ bool ServerNodeInstance::isSubclassOf(QObject *object, const QByteArray &superTy
return Internal::QmlPrivateGate::isSubclassOf(object, superTypeName);
}
+void ServerNodeInstance::setModifiedFlag(bool b)
+{
+ m_nodeInstance->setModifiedFlag(b);
+}
+
void ServerNodeInstance::setNodeSource(const QString &source)
{
m_nodeInstance->setNodeSource(source);
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h
index 7e72878dca..86003b51b6 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h
@@ -165,6 +165,8 @@ public:
static bool isSubclassOf(QObject *object, const QByteArray &superTypeName);
+ void setModifiedFlag(bool b);
+
private: // functions
ServerNodeInstance(const QSharedPointer<Internal::ObjectNodeInstance> &abstractInstance);
diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc b/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc
index 03931c280e..4bbd30e8fc 100644
--- a/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc
+++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc
@@ -11,7 +11,14 @@
<file>mockfiles/Arrow.qml</file>
<file>mockfiles/AutoScaleHelper.qml</file>
<file>mockfiles/MoveGizmo.qml</file>
+ <file>mockfiles/CameraGizmo.qml</file>
+ <file>mockfiles/LightGizmo.qml</file>
+ <file>mockfiles/IconGizmo.qml</file>
<file>mockfiles/Overlay2D.qml</file>
- <file>mockfiles/meshes/Arrow.mesh</file>
+ <file>mockfiles/meshes/arrow.mesh</file>
+ <file>mockfiles/images/camera-pick-icon.png</file>
+ <file>mockfiles/images/camera-pick-icon@2x.png</file>
+ <file>mockfiles/images/light-pick-icon.png</file>
+ <file>mockfiles/images/light-pick-icon@2x.png</file>
</qresource>
</RCC>
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml
index c8eb572141..389a9b02d2 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml
@@ -295,6 +295,315 @@ Rectangle {
backendValueRightMargin: backendValues.Layout_rightMargin
backendValueMargins: backendValues.Layout_margins
}
+
+ Section {
+ visible: !anchorBackend.isInLayout
+ anchors.left: parent.left
+ anchors.right: parent.right
+ caption: qsTr("Align")
+
+ ColumnLayout {
+ width: parent.width
+ enabled: alignDistribute.multiSelection &&
+ !alignDistribute.selectionHasAnchors &&
+ alignDistribute.selectionExclusivlyItems &&
+ !alignDistribute.selectionContainsRootItem
+
+ AlignDistribute {
+ id: alignDistribute
+ modelNodeBackendProperty: modelNodeBackend
+ }
+
+ Label {
+ text: qsTr("Align objects")
+ width: 120
+ }
+ RowLayout {
+ Row {
+ spacing: -StudioTheme.Values.border
+ AbstractButton {
+ buttonIcon: StudioTheme.Constants.alignLeft
+ tooltip: qsTr("Align objects to left edge")
+ onClicked: alignDistribute.alignObjects(AlignDistribute.Left,
+ alignToComboBox.currentEnum,
+ keyObjectComboBox.currentText)
+ }
+ AbstractButton {
+ buttonIcon: StudioTheme.Constants.alignCenterHorizontal
+ tooltip: qsTr("Align objects horizontal center")
+ onClicked: alignDistribute.alignObjects(AlignDistribute.CenterH,
+ alignToComboBox.currentEnum,
+ keyObjectComboBox.currentText)
+ }
+ AbstractButton {
+ buttonIcon: StudioTheme.Constants.alignRight
+ tooltip: qsTr("Align objects to right edge")
+ onClicked: alignDistribute.alignObjects(AlignDistribute.Right,
+ alignToComboBox.currentEnum,
+ keyObjectComboBox.currentText)
+ }
+ }
+
+ Row {
+ spacing: -StudioTheme.Values.border
+ AbstractButton {
+ buttonIcon: StudioTheme.Constants.alignTop
+ tooltip: qsTr("Align objects to top edge")
+ onClicked: alignDistribute.alignObjects(AlignDistribute.Top,
+ alignToComboBox.currentEnum,
+ keyObjectComboBox.currentText)
+ }
+ AbstractButton {
+ buttonIcon: StudioTheme.Constants.alignCenterVertical
+ tooltip: qsTr("Align objects vertical center")
+ onClicked: alignDistribute.alignObjects(AlignDistribute.CenterV,
+ alignToComboBox.currentEnum,
+ keyObjectComboBox.currentText)
+ }
+ AbstractButton {
+ buttonIcon: StudioTheme.Constants.alignBottom
+ tooltip: qsTr("Align objects to bottom edge")
+ onClicked: alignDistribute.alignObjects(AlignDistribute.Bottom,
+ alignToComboBox.currentEnum,
+ keyObjectComboBox.currentText)
+ }
+ }
+ }
+
+ Label {
+ text: qsTr("Distribute objects")
+ width: 120
+ }
+ RowLayout {
+ Row {
+ spacing: -StudioTheme.Values.border
+ AbstractButton {
+ buttonIcon: StudioTheme.Constants.distributeLeft
+ tooltip: qsTr("Distribute objects left edge")
+ onClicked: alignDistribute.distributeObjects(AlignDistribute.Left,
+ alignToComboBox.currentEnum,
+ keyObjectComboBox.currentText)
+ }
+ AbstractButton {
+ buttonIcon: StudioTheme.Constants.distributeCenterHorizontal
+ tooltip: qsTr("Distribute objects horizontal center")
+ onClicked: alignDistribute.distributeObjects(AlignDistribute.CenterH,
+ alignToComboBox.currentEnum,
+ keyObjectComboBox.currentText)
+ }
+ AbstractButton {
+ buttonIcon: StudioTheme.Constants.distributeRight
+ tooltip: qsTr("Distribute objects right edge")
+ onClicked: alignDistribute.distributeObjects(AlignDistribute.Right,
+ alignToComboBox.currentEnum,
+ keyObjectComboBox.currentText)
+ }
+ }
+
+ Row {
+ spacing: -StudioTheme.Values.border
+ AbstractButton {
+ buttonIcon: StudioTheme.Constants.distributeTop
+ tooltip: qsTr("Distribute objects top edge")
+ onClicked: alignDistribute.distributeObjects(AlignDistribute.Top,
+ alignToComboBox.currentEnum,
+ keyObjectComboBox.currentText)
+ }
+ AbstractButton {
+ buttonIcon: StudioTheme.Constants.distributeCenterVertical
+ tooltip: qsTr("Distribute objects vertical center")
+ onClicked: alignDistribute.distributeObjects(AlignDistribute.CenterV,
+ alignToComboBox.currentEnum,
+ keyObjectComboBox.currentText)
+ }
+ AbstractButton {
+ buttonIcon: StudioTheme.Constants.distributeBottom
+ tooltip: qsTr("Distribute objects bottom edge")
+ onClicked: alignDistribute.distributeObjects(AlignDistribute.Bottom,
+ alignToComboBox.currentEnum,
+ keyObjectComboBox.currentText)
+ }
+ }
+ }
+
+ Label {
+ text: qsTr("Distribute spacing")
+ width: 120
+ }
+ RowLayout {
+ Row {
+ spacing: -StudioTheme.Values.border
+ AbstractButton {
+ buttonIcon: StudioTheme.Constants.distributeSpacingHorizontal
+ tooltip: qsTr("Distribute spacing horizontal")
+ onClicked: alignDistribute.distributeSpacing(AlignDistribute.X,
+ alignToComboBox.currentEnum,
+ keyObjectComboBox.currentText,
+ distanceSpinBox.realValue,
+ buttonRow.getDistributeDirection())
+ }
+ AbstractButton {
+ buttonIcon: StudioTheme.Constants.distributeSpacingVertical
+ tooltip: qsTr("Distribute spacing vertical")
+ onClicked: alignDistribute.distributeSpacing(AlignDistribute.Y,
+ alignToComboBox.currentEnum,
+ keyObjectComboBox.currentText,
+ distanceSpinBox.realValue,
+ buttonRow.getDistributeDirection())
+ }
+ }
+
+ StudioControls.ButtonRow {
+ id: buttonRow
+ actionIndicatorVisible: false
+
+ StudioControls.ButtonGroup {
+ id: group
+ }
+
+ function getDistributeDirection()
+ {
+ if (buttonLeftToRight.checked)
+ return AlignDistribute.TopLeft
+ else if (buttonCenter.checked)
+ return AlignDistribute.Center
+ else if (buttonRightToLeft.checked)
+ return AlignDistribute.BottomRight
+ else
+ return AlignDistribute.None
+ }
+
+ AbstractButton {
+ id: buttonNone
+ checked: true // default state
+ buttonIcon: StudioTheme.Constants.distributeOriginNone
+ checkable: true
+ StudioControls.ButtonGroup.group: group
+ }
+ AbstractButton {
+ id: buttonLeftToRight
+ buttonIcon: StudioTheme.Constants.distributeOriginTopLeft
+ checkable: true
+ StudioControls.ButtonGroup.group: group
+ }
+ AbstractButton {
+ id: buttonCenter
+ buttonIcon: StudioTheme.Constants.distributeOriginCenter
+ checkable: true
+ StudioControls.ButtonGroup.group: group
+ }
+ AbstractButton {
+ id: buttonRightToLeft
+ buttonIcon: StudioTheme.Constants.distributeOriginBottomRight
+ checkable: true
+ StudioControls.ButtonGroup.group: group
+ }
+
+ StudioControls.RealSpinBox {
+ id: distanceSpinBox
+ width: 64
+ actionIndicatorVisible: false
+ realFrom: -1000
+ realTo: 1000
+ enabled: !buttonNone.checked
+ }
+ }
+ }
+
+ SectionLayout {
+ columns: 2
+
+ ItemFilterModel {
+ id: itemFilterModel
+ modelNodeBackendProperty: modelNodeBackend
+ selectionOnly: true
+ }
+
+ Label {
+ text: qsTr("Align to")
+ }
+ ComboBox {
+ id: alignToComboBox
+ Layout.fillWidth: true
+ property int currentEnum: alignTargets.get(alignToComboBox.currentIndex).value
+ textRole: "text"
+ model: ListModel {
+ id: alignTargets
+ ListElement { text: "Selection"; value: AlignDistribute.Selection }
+ ListElement { text: "Root"; value: AlignDistribute.Root }
+ ListElement { text: "Key object"; value: AlignDistribute.KeyObject }
+ }
+ }
+
+ Label {
+ text: qsTr("Key object")
+ }
+ ComboBox {
+ id: keyObjectComboBox
+ enabled: alignToComboBox.currentIndex === 2
+ model: itemFilterModel.itemModel
+ Layout.fillWidth: true
+ property string lastSelectedItem: ""
+ onCompressedActivated: lastSelectedItem = keyObjectComboBox.currentText
+ onModelChanged: {
+ var idx = model.indexOf(keyObjectComboBox.lastSelectedItem)
+ if (idx !== -1)
+ keyObjectComboBox.currentIndex = idx
+ else
+ lastSelectedItem = "" // TODO
+ }
+ }
+ }
+
+ SectionLayout {
+ columns: 1
+ Layout.topMargin: 30
+ visible: alignDistribute.multiSelection &&
+ (alignDistribute.selectionHasAnchors ||
+ !alignDistribute.selectionExclusivlyItems ||
+ alignDistribute.selectionContainsRootItem)
+
+ Text {
+ id: warningTitle
+ font.family: StudioTheme.Constants.font.family
+ font.pixelSize: StudioTheme.Values.myFontSize
+ font.weight: Font.Bold
+ color: StudioTheme.Values.themeTextColor
+ text: qsTr("Warning")
+ }
+ Text {
+ id: warningRoot
+ visible: alignDistribute.selectionContainsRootItem
+ Layout.fillWidth: true
+ font.family: StudioTheme.Constants.font.family
+ font.pixelSize: StudioTheme.Values.myFontSize
+ color: StudioTheme.Values.themeTextColor
+ wrapMode: Text.WordWrap
+ text: qsTr("- The selection contains the root item.")
+ }
+ Text {
+ id: warningNonVisual
+ visible: !alignDistribute.selectionExclusivlyItems
+ Layout.fillWidth: true
+ font.family: StudioTheme.Constants.font.family
+ font.pixelSize: StudioTheme.Values.myFontSize
+ color: StudioTheme.Values.themeTextColor
+ wrapMode: Text.WordWrap
+ text: qsTr("- The selection contains a non visual item.")
+ }
+ Text {
+ id: warningAnchors
+ visible: alignDistribute.selectionHasAnchors
+ Layout.fillWidth: true
+ font.family: StudioTheme.Constants.font.family
+ font.pixelSize: StudioTheme.Values.myFontSize
+ color: StudioTheme.Values.themeTextColor
+ wrapMode: Text.WordWrap
+ text: qsTr("- An item in the selection uses anchors.")
+ }
+ }
+ }
+ }
}
}
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml
index a3f0d2cdca..3c314cfea6 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml
@@ -26,6 +26,7 @@
import QtQuick 2.1
import HelperWidgets 2.0
import StudioControls 1.0 as StudioControls
+import StudioTheme 1.0 as StudioTheme
import QtQuick.Layouts 1.0
import QtQuick.Controls.Styles 1.1
@@ -145,8 +146,7 @@ RowLayout {
}
StudioControls.AbstractButton {
- buttonIcon: "..."
- iconFont: StudioTheme.Constants.font.family
+ buttonIcon: StudioTheme.Constants.addFile
iconColor: urlChooser.textColor
onClicked: {
fileModel.openFileDialog()
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Constants.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Constants.qml
index 18adbdb68a..421dabf757 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Constants.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Constants.qml
@@ -38,29 +38,50 @@ QtObject {
readonly property string actionIcon: "\u0021"
readonly property string actionIconBinding: "\u0022"
- readonly property string anchorBaseline: "\u0023"
- readonly property string anchorBottom: "\u0024"
- readonly property string anchorFill: "\u0025"
- readonly property string anchorLeft: "\u0026"
- readonly property string anchorRight: "\u0027"
- readonly property string anchorTop: "\u0028"
- readonly property string centerHorizontal: "\u002A"
- readonly property string centerVertical: "\u0029"
- readonly property string closeCross: "\u002B"
- readonly property string fontStyleBold: "\u002C"
- readonly property string fontStyleItalic: "\u002D"
- readonly property string fontStyleStrikethrough: "\u002E"
- readonly property string fontStyleUnderline: "\u002F"
- readonly property string textAlignBottom: "\u0030"
- readonly property string textAlignCenter: "\u0031"
- readonly property string textAlignLeft: "\u0032"
- readonly property string textAlignMiddle: "\u0033"
- readonly property string textAlignRight: "\u0034"
- readonly property string textAlignTop: "\u0035"
- readonly property string tickIcon: "\u0036"
- readonly property string triState: "\u0037"
- readonly property string upDownIcon: "\u0038"
- readonly property string upDownSquare2: "\u0039"
+ readonly property string addFile: "\u0023"
+ readonly property string alignBottom: "\u0024"
+ readonly property string alignCenterHorizontal: "\u0025"
+ readonly property string alignCenterVertical: "\u0026"
+ readonly property string alignLeft: "\u0027"
+ readonly property string alignRight: "\u0028"
+ readonly property string alignTo: "\u0029"
+ readonly property string alignTop: "\u002A"
+ readonly property string anchorBaseline: "\u002B"
+ readonly property string anchorBottom: "\u002C"
+ readonly property string anchorFill: "\u002D"
+ readonly property string anchorLeft: "\u002E"
+ readonly property string anchorRight: "\u002F"
+ readonly property string anchorTop: "\u0030"
+ readonly property string centerHorizontal: "\u0031"
+ readonly property string centerVertical: "\u0032"
+ readonly property string closeCross: "\u0033"
+ readonly property string distributeBottom: "\u0034"
+ readonly property string distributeCenterHorizontal: "\u0035"
+ readonly property string distributeCenterVertical: "\u0036"
+ readonly property string distributeLeft: "\u0037"
+ readonly property string distributeOriginBottomRight: "\u0038"
+ readonly property string distributeOriginCenter: "\u0039"
+ readonly property string distributeOriginNone: "\u003A"
+ readonly property string distributeOriginTopLeft: "\u003B"
+ readonly property string distributeRight: "\u003C"
+ readonly property string distributeSpacingHorizontal: "\u003D"
+ readonly property string distributeSpacingVertical: "\u003E"
+ readonly property string distributeTop: "\u003F"
+ readonly property string fontStyleBold: "\u0040"
+ readonly property string fontStyleItalic: "\u0041"
+ readonly property string fontStyleStrikethrough: "\u0042"
+ readonly property string fontStyleUnderline: "\u0043"
+ readonly property string testIcon: "\u0044"
+ readonly property string textAlignBottom: "\u0045"
+ readonly property string textAlignCenter: "\u0046"
+ readonly property string textAlignLeft: "\u0047"
+ readonly property string textAlignMiddle: "\u0048"
+ readonly property string textAlignRight: "\u0049"
+ readonly property string textAlignTop: "\u004A"
+ readonly property string tickIcon: "\u004B"
+ readonly property string triState: "\u004C"
+ readonly property string upDownIcon: "\u004D"
+ readonly property string upDownSquare2: "\u004E"
readonly property font iconFont: Qt.font({
"family": controlIcons.name,
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf
index 9658c01782..289326b3a5 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf
Binary files differ
diff --git a/src/libs/extensionsystem/CMakeLists.txt b/src/libs/extensionsystem/CMakeLists.txt
index 53f928153c..71e5cbd380 100644
--- a/src/libs/extensionsystem/CMakeLists.txt
+++ b/src/libs/extensionsystem/CMakeLists.txt
@@ -12,5 +12,8 @@ add_qtc_library(ExtensionSystem
pluginmanager.cpp pluginmanager.h pluginmanager_p.h
pluginspec.cpp pluginspec.h pluginspec_p.h
pluginview.cpp pluginview.h
+ EXPLICIT_MOC
+ pluginmanager.h
+ pluginmanager_p.h
SKIP_AUTOMOC pluginmanager.cpp
)
diff --git a/src/libs/utils/buildablehelperlibrary.cpp b/src/libs/utils/buildablehelperlibrary.cpp
index 0e19dba5e9..e1e75148fd 100644
--- a/src/libs/utils/buildablehelperlibrary.cpp
+++ b/src/libs/utils/buildablehelperlibrary.cpp
@@ -338,9 +338,7 @@ bool BuildableHelperLibrary::buildHelper(const BuildHelperArguments &arguments,
log->append(QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary",
"Running %1 %2 ...\n")
.arg(makeFullPath.toUserOutput(), arguments.makeArguments.join(QLatin1Char(' '))));
- if (!runBuildProcess(proc, makeFullPath, arguments.makeArguments, 120, false, log, errorMessage))
- return false;
- return true;
+ return runBuildProcess(proc, makeFullPath, arguments.makeArguments, 120, false, log, errorMessage);
}
bool BuildableHelperLibrary::getHelperFileInfoFor(const QStringList &validBinaryFilenames,
diff --git a/src/libs/utils/detailsbutton.cpp b/src/libs/utils/detailsbutton.cpp
index abceff7b2d..07c27d3b70 100644
--- a/src/libs/utils/detailsbutton.cpp
+++ b/src/libs/utils/detailsbutton.cpp
@@ -110,6 +110,14 @@ bool DetailsButton::event(QEvent *e)
return false;
}
+void DetailsButton::changeEvent(QEvent *e)
+{
+ if (e->type() == QEvent::EnabledChange) {
+ m_checkedPixmap = QPixmap();
+ m_uncheckedPixmap = QPixmap();
+ }
+}
+
void DetailsButton::paintEvent(QPaintEvent *e)
{
QWidget::paintEvent(e);
diff --git a/src/libs/utils/detailsbutton.h b/src/libs/utils/detailsbutton.h
index dabbe75918..3c7286e9ee 100644
--- a/src/libs/utils/detailsbutton.h
+++ b/src/libs/utils/detailsbutton.h
@@ -71,6 +71,7 @@ public:
protected:
void paintEvent(QPaintEvent *e) override;
bool event(QEvent *e) override;
+ void changeEvent(QEvent *e) override;
private:
QPixmap cacheRendering(const QSize &size, bool checked);
diff --git a/src/libs/utils/detailswidget.cpp b/src/libs/utils/detailswidget.cpp
index dd02d1a4a5..06159b101e 100644
--- a/src/libs/utils/detailswidget.cpp
+++ b/src/libs/utils/detailswidget.cpp
@@ -229,6 +229,16 @@ void DetailsWidget::setUseCheckBox(bool b)
d->updateControls();
}
+void DetailsWidget::setCheckable(bool b)
+{
+ d->m_summaryCheckBox->setEnabled(b);
+}
+
+void DetailsWidget::setExpandable(bool b)
+{
+ d->m_detailsButton->setEnabled(b);
+}
+
void DetailsWidget::setChecked(bool b)
{
d->m_summaryCheckBox->setChecked(b);
diff --git a/src/libs/utils/detailswidget.h b/src/libs/utils/detailswidget.h
index f96f0f549d..e9c55c9eaf 100644
--- a/src/libs/utils/detailswidget.h
+++ b/src/libs/utils/detailswidget.h
@@ -78,6 +78,8 @@ public:
bool useCheckBox();
void setUseCheckBox(bool b);
+ void setCheckable(bool b);
+ void setExpandable(bool b);
void setIcon(const QIcon &icon);
static QPixmap createBackground(const QSize &size, int topHeight, QWidget *widget);
diff --git a/src/libs/utils/differ.cpp b/src/libs/utils/differ.cpp
index 16fc0ced01..74ec99c78c 100644
--- a/src/libs/utils/differ.cpp
+++ b/src/libs/utils/differ.cpp
@@ -236,16 +236,12 @@ static int cleanupSemanticsScore(const QString &text1, const QString &text2)
static bool isWhitespace(const QChar &c)
{
- if (c == ' ' || c == '\t')
- return true;
- return false;
+ return c == ' ' || c == '\t';
}
static bool isNewLine(const QChar &c)
{
- if (c == '\n')
- return true;
- return false;
+ return c == '\n';
}
/*
@@ -719,9 +715,7 @@ static bool diffWithWhitespaceExpandedInEqualities(const QList<Diff> &leftInput,
return false;
*rightOutput = decodeExpandedWhitespace(rightDiffList,
commonRightCodeMap, &ok);
- if (!ok)
- return false;
- return true;
+ return ok;
}
static void appendWithEqualitiesSquashed(const QList<Diff> &leftInput,
diff --git a/src/libs/utils/json.cpp b/src/libs/utils/json.cpp
index 104cf571b9..b195e134d4 100644
--- a/src/libs/utils/json.cpp
+++ b/src/libs/utils/json.cpp
@@ -225,17 +225,13 @@ bool JsonSchema::typeMatches(const QString &expected, const QString &actual)
bool JsonSchema::isCheckableType(const QString &s)
{
- if (s == QLatin1String("string")
- || s == QLatin1String("number")
- || s == QLatin1String("integer")
- || s == QLatin1String("boolean")
- || s == QLatin1String("object")
- || s == QLatin1String("array")
- || s == QLatin1String("null")) {
- return true;
- }
-
- return false;
+ return s == QLatin1String("string")
+ || s == QLatin1String("number")
+ || s == QLatin1String("integer")
+ || s == QLatin1String("boolean")
+ || s == QLatin1String("object")
+ || s == QLatin1String("array")
+ || s == QLatin1String("null");
}
QStringList JsonSchema::validTypes() const
diff --git a/src/libs/utils/reloadpromptutils.cpp b/src/libs/utils/reloadpromptutils.cpp
index 09a9855784..210791157c 100644
--- a/src/libs/utils/reloadpromptutils.cpp
+++ b/src/libs/utils/reloadpromptutils.cpp
@@ -102,22 +102,14 @@ QTCREATOR_UTILS_EXPORT ReloadPromptAnswer reloadPrompt(const QString &title,
}
QTCREATOR_UTILS_EXPORT FileDeletedPromptAnswer
- fileDeletedPrompt(const QString &fileName, bool triggerExternally, QWidget *parent)
+ fileDeletedPrompt(const QString &fileName, QWidget *parent)
{
const QString title = QCoreApplication::translate("Utils::fileDeletedPrompt",
"File Has Been Removed");
- QString msg;
- if (triggerExternally) {
- msg = QCoreApplication::translate("Utils::fileDeletedPrompt",
- "The file %1 has been removed from disk. "
- "Do you want to save it under a different name, or close "
- "the editor?").arg(QDir::toNativeSeparators(fileName));
- } else {
- msg = QCoreApplication::translate("Utils::fileDeletedPrompt",
- "The file %1 has been removed from disk. "
- "Do you want to save it under a different name, or close "
- "the editor?").arg(QDir::toNativeSeparators(fileName));
- }
+ QString msg = QCoreApplication::translate("Utils::fileDeletedPrompt",
+ "The file %1 has been removed from disk. "
+ "Do you want to save it under a different name, or close "
+ "the editor?").arg(QDir::toNativeSeparators(fileName));
QMessageBox box(QMessageBox::Question, title, msg, QMessageBox::NoButton, parent);
QPushButton *close =
box.addButton(QCoreApplication::translate("Utils::fileDeletedPrompt", "&Close"),
diff --git a/src/libs/utils/reloadpromptutils.h b/src/libs/utils/reloadpromptutils.h
index 82aa409cf5..5b06596cd4 100644
--- a/src/libs/utils/reloadpromptutils.h
+++ b/src/libs/utils/reloadpromptutils.h
@@ -62,7 +62,6 @@ enum FileDeletedPromptAnswer {
};
QTCREATOR_UTILS_EXPORT FileDeletedPromptAnswer fileDeletedPrompt(const QString &fileName,
- bool triggerExternally,
QWidget *parent);
} // namespace Utils
diff --git a/src/plugins/boot2qt/device-detection/qdbmessagetracker.cpp b/src/plugins/boot2qt/device-detection/qdbmessagetracker.cpp
index 3e9bc558d0..8d623b6680 100644
--- a/src/plugins/boot2qt/device-detection/qdbmessagetracker.cpp
+++ b/src/plugins/boot2qt/device-detection/qdbmessagetracker.cpp
@@ -80,7 +80,7 @@ void QdbMessageTracker::handleWatchMessage(const QJsonDocument &document)
}
m_messageCache.append(message);
- showMessage(tr("Qdb message: %1").arg(message), true);
+ showMessage(tr("QDB message: %1").arg(message), true);
}
}
diff --git a/src/plugins/boot2qt/device-detection/qdbwatcher.cpp b/src/plugins/boot2qt/device-detection/qdbwatcher.cpp
index e5a9b5c2ef..ee2b091fd3 100644
--- a/src/plugins/boot2qt/device-detection/qdbwatcher.cpp
+++ b/src/plugins/boot2qt/device-detection/qdbwatcher.cpp
@@ -109,7 +109,7 @@ void QdbWatcher::handleWatchError(QLocalSocket::LocalSocketError error)
if (m_retried) {
stop();
- emit watcherError(tr("Could not connect to QDB host server even after trying to start it"));
+ emit watcherError(tr("Could not connect to QDB host server even after trying to start it."));
return;
}
retry();
@@ -142,7 +142,7 @@ void QdbWatcher::forkHostServer()
return;
}
if (QProcess::startDetached(qdbFilePath.toString(), {"server"}))
- showMessage(tr("QDB host server started"), false);
+ showMessage(tr("QDB host server started."), false);
else
showMessage(tr("Could not start QDB host server in %1").arg(qdbFilePath.toString()), true);
}
@@ -153,7 +153,7 @@ void QdbWatcher::retry()
{
QMutexLocker lock(&s_startMutex);
if (!s_startedServer) {
- showMessage(tr("Starting QDB host server"), false);
+ showMessage(tr("Starting QDB host server."), false);
forkHostServer();
s_startedServer = true;
}
diff --git a/src/plugins/boot2qt/qdbdevice.cpp b/src/plugins/boot2qt/qdbdevice.cpp
index c6e388878d..e8b8186b50 100644
--- a/src/plugins/boot2qt/qdbdevice.cpp
+++ b/src/plugins/boot2qt/qdbdevice.cpp
@@ -93,7 +93,7 @@ public:
Runnable r;
r.setCommandLine(command);
m_appRunner.start(r, device);
- showMessage(QdbDevice::tr("Starting command '%1' on device '%2'.")
+ showMessage(QdbDevice::tr("Starting command \"%1\" on device \"%2\".")
.arg(command.toUserOutput(), m_deviceName));
}
@@ -112,18 +112,18 @@ private:
if (!success) {
QString errorString;
if (!m_error.isEmpty()) {
- errorString = QdbDevice::tr("Command failed on device '%1': %2")
+ errorString = QdbDevice::tr("Command failed on device \"%1\": %2")
.arg(m_deviceName, m_error);
} else {
- errorString = QdbDevice::tr("Command failed on device '%1'.").arg(m_deviceName);
+ errorString = QdbDevice::tr("Command failed on device \"%1\".").arg(m_deviceName);
}
showMessage(errorString, true);
if (!m_stdout.isEmpty())
- showMessage(QdbDevice::tr("stdout was: '%1'").arg(m_stdout));
+ showMessage(QdbDevice::tr("stdout was: \"%1\"").arg(m_stdout));
if (!m_stderr.isEmpty())
- showMessage(QdbDevice::tr("stderr was: '%1'").arg(m_stderr));
+ showMessage(QdbDevice::tr("stderr was: \"%1\"").arg(m_stderr));
} else {
- showMessage(QdbDevice::tr("Commands on device '%1' finished successfully.")
+ showMessage(QdbDevice::tr("Commands on device \"%1\" finished successfully.")
.arg(m_deviceName));
}
deleteLater();
diff --git a/src/plugins/boot2qt/qdbmakedefaultappservice.cpp b/src/plugins/boot2qt/qdbmakedefaultappservice.cpp
index fc7212b910..9512ac8f7d 100644
--- a/src/plugins/boot2qt/qdbmakedefaultappservice.cpp
+++ b/src/plugins/boot2qt/qdbmakedefaultappservice.cpp
@@ -77,7 +77,7 @@ void QdbMakeDefaultAppService::handleProcessFinished(const QString &error)
QByteArray processOutput = d->processRunner->readAllStandardOutput();
if (d->makeDefault)
- emit progressMessage(tr("Application made as the default one."));
+ emit progressMessage(tr("Application set as the default one."));
else
emit progressMessage(tr("Reset the default application."));
diff --git a/src/plugins/clangtools/clangtool.cpp b/src/plugins/clangtools/clangtool.cpp
index 6b645ad952..607b78680c 100644
--- a/src/plugins/clangtools/clangtool.cpp
+++ b/src/plugins/clangtools/clangtool.cpp
@@ -495,12 +495,13 @@ void ClangTool::startTool(ClangTool::FileSelection fileSelection,
});
m_perspective.select();
-
m_diagnosticModel->clear();
- setToolBusy(true);
m_diagnosticFilterModel->setProject(project);
+ m_applyFixitsButton->setEnabled(false);
m_running = true;
+
+ setToolBusy(true);
handleStateUpdate();
updateRunActions();
diff --git a/src/plugins/clangtools/clangtoolruncontrol.cpp b/src/plugins/clangtools/clangtoolruncontrol.cpp
index 6d870d93c8..e58b77a769 100644
--- a/src/plugins/clangtools/clangtoolruncontrol.cpp
+++ b/src/plugins/clangtools/clangtoolruncontrol.cpp
@@ -227,6 +227,7 @@ ClangToolRunWorker::ClangToolRunWorker(RunControl *runControl,
const FileInfos &fileInfos,
bool preventBuild)
: RunWorker(runControl)
+ , m_runSettings(runSettings)
, m_diagnosticConfig(diagnosticConfig)
, m_fileInfos(fileInfos)
, m_temporaryDir("clangtools-XXXXXX")
@@ -305,7 +306,7 @@ void ClangToolRunWorker::start()
// Create log dir
if (!m_temporaryDir.isValid()) {
const QString errorMessage
- = tr("%1: Failed to create temporary dir, stop.").arg(toolName);
+ = tr("%1: Failed to create temporary directory. Stopped.").arg(toolName);
appendMessage(errorMessage, Utils::ErrorMessageFormat);
TaskHub::addTask(Task::Error, errorMessage, Debugger::Constants::ANALYZERTASK_ID);
TaskHub::requestPopup();
@@ -390,7 +391,7 @@ void ClangToolRunWorker::analyzeNextFile()
const QString executable = runner->executable();
if (!isFileExecutable(executable)) {
- const QString errorMessage = tr("%1: Invalid executable \"%2\", stop.")
+ const QString errorMessage = tr("%1: Invalid executable \"%2\". Stopped.")
.arg(runner->name(), executable);
TaskHub::addTask(Task::Error, errorMessage, Debugger::Constants::ANALYZERTASK_ID);
TaskHub::requestPopup();
diff --git a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp
index 6ac802d973..6608bb3ea4 100644
--- a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp
+++ b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp
@@ -101,10 +101,10 @@ QDebug operator<<(QDebug debug, const Diagnostic &d)
void ClangToolsDiagnosticModel::addDiagnostics(const Diagnostics &diagnostics)
{
- const auto onFixitStatusChanged = [this](FixitStatus newStatus) {
+ const auto onFixitStatusChanged = [this](FixitStatus oldStatus, FixitStatus newStatus) {
if (newStatus == FixitStatus::Scheduled)
++m_fixItsToApplyCount;
- else
+ else if (oldStatus == FixitStatus::Scheduled)
--m_fixItsToApplyCount;
emit fixItsToApplyCountChanged(m_fixItsToApplyCount);
};
@@ -463,7 +463,7 @@ void DiagnosticItem::setFixItStatus(const FixitStatus &status)
m_fixitStatus = status;
update();
if (m_onFixitStatusChanged && status != oldStatus)
- m_onFixitStatusChanged(status);
+ m_onFixitStatusChanged(oldStatus, status);
}
void DiagnosticItem::setFixitOperations(const ReplacementOperations &replacements)
diff --git a/src/plugins/clangtools/clangtoolsdiagnosticmodel.h b/src/plugins/clangtools/clangtoolsdiagnosticmodel.h
index 3ac1df0d0c..d9fb8b4cfb 100644
--- a/src/plugins/clangtools/clangtoolsdiagnosticmodel.h
+++ b/src/plugins/clangtools/clangtoolsdiagnosticmodel.h
@@ -71,8 +71,9 @@ private:
class DiagnosticItem : public Utils::TreeItem
{
public:
- using OnFixitStatusChanged = std::function<void(FixitStatus newStatus)>;
- DiagnosticItem(const Diagnostic &diag, const OnFixitStatusChanged &onFixitStatusChanged,
+ using OnFixitStatusChanged = std::function<void(FixitStatus oldStatus, FixitStatus newStatus)>;
+ DiagnosticItem(const Diagnostic &diag,
+ const OnFixitStatusChanged &onFixitStatusChanged,
ClangToolsDiagnosticModel *parent);
~DiagnosticItem() override;
diff --git a/src/plugins/clangtools/clangtoolsdiagnosticview.cpp b/src/plugins/clangtools/clangtoolsdiagnosticview.cpp
index 4408a597b7..769266b5e0 100644
--- a/src/plugins/clangtools/clangtoolsdiagnosticview.cpp
+++ b/src/plugins/clangtools/clangtoolsdiagnosticview.cpp
@@ -283,7 +283,7 @@ bool DiagnosticView::eventFilter(QObject *watched, QEvent *event)
return true;
}
default:
- return QObject::eventFilter(watched, event);
+ return QAbstractItemView::eventFilter(watched, event);
}
}
diff --git a/src/plugins/clangtools/clangtoolsprojectsettings.cpp b/src/plugins/clangtools/clangtoolsprojectsettings.cpp
index 005897b49c..c7d692704e 100644
--- a/src/plugins/clangtools/clangtoolsprojectsettings.cpp
+++ b/src/plugins/clangtools/clangtoolsprojectsettings.cpp
@@ -105,7 +105,7 @@ void ClangToolsProjectSettings::load()
// Load map
QVariantMap map = m_project->namedSettings(SETTINGS_KEY_MAIN).toMap();
- bool write;
+ bool write = false;
if (map.isEmpty()) {
if (!m_project->namedSettings(SETTINGS_KEY_SELECTED_DIRS).isNull()) {
map = convertToMapFromVersionBefore410(m_project);
diff --git a/src/plugins/classview/classviewparsertreeitem.cpp b/src/plugins/classview/classviewparsertreeitem.cpp
index eb2009c5ed..e80dc3e25b 100644
--- a/src/plugins/classview/classviewparsertreeitem.cpp
+++ b/src/plugins/classview/classviewparsertreeitem.cpp
@@ -333,11 +333,7 @@ bool ParserTreeItem::canFetchMore(QStandardItem *item) const
int storedChildren = item->rowCount();
int internalChildren = d->symbolInformations.count();
-
- if (storedChildren < internalChildren)
- return true;
-
- return false;
+ return storedChildren < internalChildren;
}
/*!
diff --git a/src/plugins/cmakeprojectmanager/cmakeautocompleter.cpp b/src/plugins/cmakeprojectmanager/cmakeautocompleter.cpp
index eca893b8ea..eb9ae0c76f 100644
--- a/src/plugins/cmakeprojectmanager/cmakeautocompleter.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeautocompleter.cpp
@@ -45,10 +45,7 @@ bool CMakeAutoCompleter::isInComment(const QTextCursor &cursor) const
// NOTE: This doesn't handle '#' inside quotes, nor multi-line comments
QTextCursor moved = cursor;
moved.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor);
- if (moved.selectedText().contains(QLatin1Char('#')))
- return true;
- else
- return false;
+ return moved.selectedText().contains(QLatin1Char('#'));
}
bool CMakeAutoCompleter::isInString(const QTextCursor &cursor) const
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
index c1d5f04142..ae1e20972f 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
@@ -151,7 +151,6 @@ void CMakeBuildSystem::handleTreeScanningFinished()
qDeleteAll(m_allFiles);
m_allFiles = Utils::transform(m_treeScanner.release(), [](const FileNode *fn) { return fn; });
- m_combinedScanAndParseResult = m_combinedScanAndParseResult && true;
m_waitingForScan = false;
combineScanAndParse();
@@ -165,7 +164,6 @@ void CMakeBuildSystem::handleParsingSuccess(CMakeBuildConfiguration *bc)
QTC_ASSERT(m_waitingForParse, return );
m_waitingForParse = false;
- m_combinedScanAndParseResult = m_combinedScanAndParseResult && true;
combineScanAndParse();
}
diff --git a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp
index e5d20de5dd..8517a5ee7f 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp
@@ -215,12 +215,12 @@ void CMakeProcess::handleProcessFinished(int code, QProcess::ExitStatus status)
QString msg;
if (status != QProcess::NormalExit) {
if (m_processWasCanceled) {
- msg = tr("*** cmake process was canceled by the user.");
+ msg = tr("CMake process was canceled by the user.");
} else {
- msg = tr("*** cmake process crashed.");
+ msg = tr("CMake process crashed.");
}
} else if (code != 0) {
- msg = tr("*** cmake process exited with exit code %1.").arg(code);
+ msg = tr("CMake process exited with exit code %1.").arg(code);
}
if (!msg.isEmpty()) {
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
index 4739d0f808..9943ca5784 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
@@ -88,7 +88,7 @@ void noAutoAdditionNotify(const QStringList &filePaths, const ProjectExplorer::P
"\nCopy the path to the source files to the clipboard?"),
"Remember My Choice", &checkValue, QDialogButtonBox::Yes | QDialogButtonBox::No,
QDialogButtonBox::Yes);
- if (true == checkValue) {
+ if (checkValue) {
if (QDialogButtonBox::Yes == reply)
settings->setAfterAddFileSetting(AfterAddFileAction::COPY_FILE_PATH);
else if (QDialogButtonBox::No == reply)
diff --git a/src/plugins/cmakeprojectmanager/fileapiparser.cpp b/src/plugins/cmakeprojectmanager/fileapiparser.cpp
index 657f798ceb..25dc5d701e 100644
--- a/src/plugins/cmakeprojectmanager/fileapiparser.cpp
+++ b/src/plugins/cmakeprojectmanager/fileapiparser.cpp
@@ -57,7 +57,7 @@ static void reportFileApiSetupFailure()
{
Core::MessageManager::write(QCoreApplication::translate(
"CMakeProjectManager::Internal",
- "Failed to set up cmake fileapi support. Creator can not extract project information."));
+ "Failed to set up CMake file API support. Qt Creator can not extract project information."));
}
static std::pair<int, int> cmakeVersion(const QJsonObject &obj)
@@ -112,7 +112,7 @@ static ReplyFileContents readReplyFile(const QFileInfo &fi, QString &errorMessag
{
const QJsonDocument document = readJsonFile(fi.filePath());
static const QString msg = QCoreApplication::translate("CMakeProjectManager::Internal",
- "Invalid reply file created by cmake.");
+ "Invalid reply file created by CMake.");
ReplyFileContents result;
if (document.isNull() || document.isEmpty() || !document.isObject()) {
@@ -175,7 +175,7 @@ static CMakeConfig readCacheFile(const QString &cacheFile, QString &errorMessage
if (!checkJsonObject(root, "cache", 2)) {
errorMessage = QCoreApplication::translate("CMakeProjectManager::Internal",
- "Invalid cache file generated by cmake.");
+ "Invalid cache file generated by CMake.");
return {};
}
@@ -221,7 +221,7 @@ std::vector<CMakeFileInfo> readCMakeFilesFile(const QString &cmakeFilesFile, QSt
if (!checkJsonObject(root, "cmakeFiles", 1)) {
errorMessage = QCoreApplication::translate("CMakeProjectManager::Internal",
- "Invalid cmakeFiles file generated by cmake.");
+ "Invalid cmakeFiles file generated by CMake.");
return {};
}
@@ -252,7 +252,7 @@ std::vector<Directory> extractDirectories(const QJsonArray &directories, QString
if (directories.isEmpty()) {
errorMessage = QCoreApplication::translate(
"CMakeProjectManager::Internal",
- "Invalid codemodel file generated by cmake: No directories.");
+ "Invalid codemodel file generated by CMake: No directories.");
return {};
}
@@ -262,7 +262,7 @@ std::vector<Directory> extractDirectories(const QJsonArray &directories, QString
if (obj.isEmpty()) {
errorMessage = QCoreApplication::translate(
"CMakeProjectManager::Internal",
- "Invalid codemodel file generated by cmake: Empty directory object.");
+ "Invalid codemodel file generated by CMake: Empty directory object.");
continue;
}
Directory dir;
@@ -284,7 +284,7 @@ static std::vector<Project> extractProjects(const QJsonArray &projects, QString
if (projects.isEmpty()) {
errorMessage = QCoreApplication::translate(
"CMakeProjectManager::Internal",
- "Invalid codemodel file generated by cmake: No projects.");
+ "Invalid codemodel file generated by CMake: No projects.");
return {};
}
@@ -294,7 +294,7 @@ static std::vector<Project> extractProjects(const QJsonArray &projects, QString
if (obj.isEmpty()) {
errorMessage = QCoreApplication::translate(
"CMakeProjectManager::Internal",
- "Invalid codemodel file generated by cmake: Empty project object.");
+ "Invalid codemodel file generated by CMake: Empty project object.");
continue;
}
Project project;
@@ -309,7 +309,7 @@ static std::vector<Project> extractProjects(const QJsonArray &projects, QString
if (project.name.isEmpty() || project.directories.empty()) {
errorMessage = QCoreApplication::translate(
"CMakeProjectManager::Internal",
- "Invalid codemodel file generated by cmake: Broken project data.");
+ "Invalid codemodel file generated by CMake: Broken project data.");
continue;
}
@@ -323,7 +323,7 @@ static std::vector<Target> extractTargets(const QJsonArray &targets, QString &er
if (targets.isEmpty()) {
errorMessage
= QCoreApplication::translate("CMakeProjectManager::Internal",
- "Invalid codemodel file generated by cmake: No targets.");
+ "Invalid codemodel file generated by CMake: No targets.");
return {};
}
@@ -333,7 +333,7 @@ static std::vector<Target> extractTargets(const QJsonArray &targets, QString &er
if (obj.isEmpty()) {
errorMessage = QCoreApplication::translate(
"CMakeProjectManager::Internal",
- "Invalid codemodel file generated by cmake: Empty target object.");
+ "Invalid codemodel file generated by CMake: Empty target object.");
continue;
}
Target target;
@@ -347,7 +347,7 @@ static std::vector<Target> extractTargets(const QJsonArray &targets, QString &er
|| target.directory == -1 || target.project == -1) {
errorMessage = QCoreApplication::translate(
"CMakeProjectManager::Internal",
- "Invalid codemodel file generated by cmake: Broken target data.");
+ "Invalid codemodel file generated by CMake: Broken target data.");
continue;
}
@@ -448,7 +448,7 @@ static std::vector<Configuration> extractConfigurations(const QJsonArray &config
if (configs.isEmpty()) {
errorMessage = QCoreApplication::translate(
"CMakeProjectManager::Internal",
- "Invalid codemodel file generated by cmake: No configurations.");
+ "Invalid codemodel file generated by CMake: No configurations.");
return {};
}
@@ -458,7 +458,7 @@ static std::vector<Configuration> extractConfigurations(const QJsonArray &config
if (obj.isEmpty()) {
errorMessage = QCoreApplication::translate(
"CMakeProjectManager::Internal",
- "Invalid codemodel file generated by cmake: Empty configuration object.");
+ "Invalid codemodel file generated by CMake: Empty configuration object.");
continue;
}
Configuration config;
@@ -471,8 +471,8 @@ static std::vector<Configuration> extractConfigurations(const QJsonArray &config
if (!validateIndexes(config)) {
errorMessage
= QCoreApplication::translate("CMakeProjectManager::Internal",
- "Invalid codemodel file generated by cmake: Broken "
- "indexes in directories/projects/targets.");
+ "Invalid codemodel file generated by CMake: Broken "
+ "indexes in directories, projects, or targets.");
return {};
}
@@ -489,7 +489,7 @@ static std::vector<Configuration> readCodemodelFile(const QString &codemodelFile
if (!checkJsonObject(root, "codemodel", 2)) {
errorMessage = QCoreApplication::translate("CMakeProjectManager::Internal",
- "Invalid codemodel file generated by cmake.");
+ "Invalid codemodel file generated by CMake.");
return {};
}
@@ -787,7 +787,7 @@ TargetDetails readTargetFile(const QString &targetFile, QString &errorMessage)
if (errorMessage.isEmpty() && !validateTargetDetails(result)) {
errorMessage = QCoreApplication::translate(
"CMakeProjectManager::Internal",
- "Invalid target file generated by cmake: Broken indexes in target details.");
+ "Invalid target file generated by CMake: Broken indexes in target details.");
}
return result;
}
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.cpp
index 1affca78fa..7d045f329e 100644
--- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.cpp
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseutils.cpp
@@ -28,6 +28,7 @@
#include <projectexplorer/headerpath.h>
#include <projectexplorer/projectmacro.h>
+#include <utils/algorithm.h>
#include <utils/hostosinfo.h>
#include <utils/optional.h>
@@ -155,14 +156,16 @@ void filteredFlags(const QString &fileName,
continue;
}
- if ((flag.startsWith("-I") || flag.startsWith("-isystem") || flag.startsWith("/I"))
- && flag != "-I" && flag != "-isystem" && flag != "/I") {
- bool userInclude = flag.startsWith("-I");
- const QString pathStr = updatedPathFlag(flag.mid(userInclude ? 2 : 8),
- workingDir);
- headerPaths.append({pathStr, userInclude
- ? HeaderPathType::User
- : HeaderPathType::System});
+ const QStringList userIncludeFlags{"-I", "/I"};
+ const QStringList systemIncludeFlags{"-isystem", "-imsvc", "/imsvc"};
+ const QStringList allIncludeFlags = QStringList(userIncludeFlags) << systemIncludeFlags;
+ const QString includeOpt = Utils::findOrDefault(allIncludeFlags, [flag](const QString &opt) {
+ return flag.startsWith(opt) && flag != opt;
+ });
+ if (!includeOpt.isEmpty()) {
+ const QString pathStr = updatedPathFlag(flag.mid(includeOpt.length()), workingDir);
+ headerPaths.append({pathStr, userIncludeFlags.contains(includeOpt)
+ ? HeaderPathType::User : HeaderPathType::System});
continue;
}
@@ -174,8 +177,12 @@ void filteredFlags(const QString &fileName,
continue;
}
- if (flag == "-I" || flag == "-isystem" || flag == "/I") {
- includePathType = (flag != "-isystem") ? HeaderPathType::User : HeaderPathType::System;
+ if (userIncludeFlags.contains(flag)) {
+ includePathType = HeaderPathType::User;
+ continue;
+ }
+ if (systemIncludeFlags.contains(flag)) {
+ includePathType = HeaderPathType::System;
continue;
}
diff --git a/src/plugins/coreplugin/documentmanager.cpp b/src/plugins/coreplugin/documentmanager.cpp
index 43760ed547..e1308ca8fe 100644
--- a/src/plugins/coreplugin/documentmanager.cpp
+++ b/src/plugins/coreplugin/documentmanager.cpp
@@ -1199,7 +1199,6 @@ void DocumentManager::checkForReload()
if (previousDeletedAnswer != FileDeletedCloseAll) {
previousDeletedAnswer =
fileDeletedPrompt(document->filePath().toString(),
- trigger == IDocument::TriggerExternal,
ICore::dialogParent());
}
switch (previousDeletedAnswer) {
diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp
index 0be92efe8a..5ec572e5a0 100644
--- a/src/plugins/coreplugin/editormanager/editormanager.cpp
+++ b/src/plugins/coreplugin/editormanager/editormanager.cpp
@@ -2427,9 +2427,7 @@ IEditor *EditorManager::currentEditor()
bool EditorManager::closeAllEditors(bool askAboutModifiedEditors)
{
DocumentModelPrivate::removeAllSuspendedEntries();
- if (closeDocuments(DocumentModel::openedDocuments(), askAboutModifiedEditors))
- return true;
- return false;
+ return closeDocuments(DocumentModel::openedDocuments(), askAboutModifiedEditors);
}
void EditorManager::closeOtherDocuments(IDocument *document)
diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp
index 732f485824..94e5aa78fe 100644
--- a/src/plugins/coreplugin/mainwindow.cpp
+++ b/src/plugins/coreplugin/mainwindow.cpp
@@ -131,6 +131,7 @@ MainWindow::MainWindow()
QCoreApplication::setApplicationName(QLatin1String(Constants::IDE_CASED_ID));
QCoreApplication::setApplicationVersion(QLatin1String(Constants::IDE_VERSION_LONG));
QCoreApplication::setOrganizationName(QLatin1String(Constants::IDE_SETTINGSVARIANT_STR));
+ QGuiApplication::setApplicationDisplayName(QLatin1String(Constants::IDE_DISPLAY_NAME));
QString baseName = QApplication::style()->objectName();
// Sometimes we get the standard windows 95 style as a fallback
if (HostOsInfo::isAnyUnixHost() && !HostOsInfo::isMacHost()
diff --git a/src/plugins/coreplugin/manhattanstyle.cpp b/src/plugins/coreplugin/manhattanstyle.cpp
index 544f57ad3e..f64275d332 100644
--- a/src/plugins/coreplugin/manhattanstyle.cpp
+++ b/src/plugins/coreplugin/manhattanstyle.cpp
@@ -273,10 +273,7 @@ void ManhattanStyle::polish(QWidget *widget)
widget->setContentsMargins(0, 0, 0, 0);
widget->setAttribute(Qt::WA_LayoutUsesWidgetRect, true);
- if (qobject_cast<QToolButton*>(widget)) {
- widget->setAttribute(Qt::WA_Hover);
- widget->setMaximumHeight(StyleHelper::navigationWidgetHeight() - 2);
- } else if (qobject_cast<QLineEdit*>(widget)) {
+ if (qobject_cast<QToolButton*>(widget) || qobject_cast<QLineEdit*>(widget)) {
widget->setAttribute(Qt::WA_Hover);
widget->setMaximumHeight(StyleHelper::navigationWidgetHeight() - 2);
} else if (qobject_cast<QLabel*>(widget)) {
@@ -303,12 +300,11 @@ void ManhattanStyle::unpolish(QWidget *widget)
QProxyStyle::unpolish(widget);
if (panelWidget(widget)) {
widget->setAttribute(Qt::WA_LayoutUsesWidgetRect, false);
- if (qobject_cast<QTabBar*>(widget))
- widget->setAttribute(Qt::WA_Hover, false);
- else if (qobject_cast<QToolBar*>(widget))
- widget->setAttribute(Qt::WA_Hover, false);
- else if (qobject_cast<QComboBox*>(widget))
+ if (qobject_cast<QTabBar*>(widget)
+ || qobject_cast<QToolBar*>(widget)
+ || qobject_cast<QComboBox*>(widget)) {
widget->setAttribute(Qt::WA_Hover, false);
+ }
}
}
diff --git a/src/plugins/cppeditor/cppdocumentationcommenthelper.cpp b/src/plugins/cppeditor/cppdocumentationcommenthelper.cpp
index 65c3dc9769..bb656d1900 100644
--- a/src/plugins/cppeditor/cppdocumentationcommenthelper.cpp
+++ b/src/plugins/cppeditor/cppdocumentationcommenthelper.cpp
@@ -88,10 +88,7 @@ bool isPreviousLineCppStyleComment(const QTextCursor &cursor)
return false;
const QString text = actual.text().trimmed();
- if (text.startsWith(QLatin1String("///")) || text.startsWith(QLatin1String("//!")))
- return true;
-
- return false;
+ return text.startsWith(QLatin1String("///")) || text.startsWith(QLatin1String("//!"));
}
/// Check if next line is a CppStyle Doxygen Comment
@@ -106,10 +103,7 @@ bool isNextLineCppStyleComment(const QTextCursor &cursor)
return false;
const QString text = actual.text().trimmed();
- if (text.startsWith(QLatin1String("///")) || text.startsWith(QLatin1String("//!")))
- return true;
-
- return false;
+ return text.startsWith(QLatin1String("///")) || text.startsWith(QLatin1String("//!"));
}
bool isCppStyleContinuation(const QTextCursor& cursor)
diff --git a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp
index beb2e2aaf7..7368ecb416 100644
--- a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp
+++ b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp
@@ -442,9 +442,7 @@ static bool canReplaceSpecifier(TranslationUnit *translationUnit, SpecifierAST *
return false;
}
}
- if (specifier->asAttributeSpecifier())
- return false;
- return true;
+ return !specifier->asAttributeSpecifier();
}
static SpecifierAST *findFirstReplaceableSpecifier(TranslationUnit *translationUnit, SpecifierListAST *list)
diff --git a/src/plugins/cppeditor/cppminimizableinfobars.cpp b/src/plugins/cppeditor/cppminimizableinfobars.cpp
index f90ae64227..7e65829219 100644
--- a/src/plugins/cppeditor/cppminimizableinfobars.cpp
+++ b/src/plugins/cppeditor/cppminimizableinfobars.cpp
@@ -156,7 +156,7 @@ static InfoBarEntry createMinimizableInfo(const Id &id,
void MinimizableInfoBars::addNoProjectConfigurationEntry(const Id &id)
{
const QString text = tr("<b>Warning</b>: This file is not part of any project. "
- "The code model might have issues to parse this file properly.");
+ "The code model might have issues parsing this file properly.");
m_infoBar.addInfo(createMinimizableInfo(id, text, []() {
settings()->setShowNoProjectInfoBar(false);
diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp
index 7689e960e0..d384322bdd 100644
--- a/src/plugins/cppeditor/cppquickfixes.cpp
+++ b/src/plugins/cppeditor/cppquickfixes.cpp
@@ -581,21 +581,11 @@ static bool checkDeclarationForSplit(SimpleDeclarationAST *declaration)
for (SpecifierListAST *it = declaration->decl_specifier_list; it; it = it->next) {
SpecifierAST *specifier = it->value;
-
- if (specifier->asEnumSpecifier() != nullptr)
- return false;
-
- else if (specifier->asClassSpecifier() != nullptr)
+ if (specifier->asEnumSpecifier() || specifier->asClassSpecifier())
return false;
}
- if (!declaration->declarator_list)
- return false;
-
- else if (!declaration->declarator_list->next)
- return false;
-
- return true;
+ return declaration->declarator_list && declaration->declarator_list->next;
}
namespace {
@@ -3502,9 +3492,7 @@ public:
bool preVisit(AST *) override
{
- if (m_done)
- return false;
- return true;
+ return !m_done;
}
void statement(StatementAST *stmt)
diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp
index aafcd35b37..ee534757ea 100644
--- a/src/plugins/cpptools/compileroptionsbuilder.cpp
+++ b/src/plugins/cpptools/compileroptionsbuilder.cpp
@@ -329,9 +329,14 @@ void CompilerOptionsBuilder::addPrecompiledHeaderOptions(UsePrecompiledHeaders u
for (const QString &pchFile : m_projectPart.precompiledHeaders) {
// Bail if build system precomiple header artifacts exists
// Clang cannot handle foreign PCH files.
- if (QFile::exists(pchFile + ".gch") || QFile::exists(pchFile + ".pch"))
+ if (QFile::exists(pchFile + ".gch") || QFile::exists(pchFile + ".pch")) {
usePrecompiledHeaders = UsePrecompiledHeaders::No;
+ // In case of Clang compilers, remove the pch-inclusion arguments
+ remove({"-Xclang", "-include-pch", "-Xclang", pchFile + ".gch"});
+ remove({"-Xclang", "-include-pch", "-Xclang", pchFile + ".pch"});
+ }
+
if (usePrecompiledHeaders == UsePrecompiledHeaders::No) {
// CMake PCH will already have force included the header file in
// command line options, remove it if exists.
diff --git a/src/plugins/cpptools/cppchecksymbols.cpp b/src/plugins/cpptools/cppchecksymbols.cpp
index f4458bd059..b42875492a 100644
--- a/src/plugins/cpptools/cppchecksymbols.cpp
+++ b/src/plugins/cpptools/cppchecksymbols.cpp
@@ -461,11 +461,7 @@ Scope *CheckSymbols::enclosingScope() const
bool CheckSymbols::preVisit(AST *ast)
{
_astStack.append(ast);
-
- if (isCanceled())
- return false;
-
- return true;
+ return !isCanceled();
}
void CheckSymbols::postVisit(AST *)
@@ -1256,13 +1252,12 @@ bool CheckSymbols::maybeAddTypeOrStatic(const QList<LookupItem> &candidates, Nam
Symbol *c = r.declaration();
if (c->isUsingDeclaration()) // skip using declarations...
continue;
- else if (c->isUsingNamespaceDirective()) // ... and using namespace directives.
+ if (c->isUsingNamespaceDirective()) // ... and using namespace directives.
continue;
- else if (c->isTypedef() || c->isNamespace() ||
- c->isStatic() || //consider also static variable
- c->isClass() || c->isEnum() || isTemplateClass(c) ||
- c->isForwardClassDeclaration() || c->isTypenameArgument() || c->enclosingEnum() != nullptr) {
-
+ if (c->isTypedef() || c->isNamespace() ||
+ c->isStatic() || //consider also static variable
+ c->isClass() || c->isEnum() || isTemplateClass(c) ||
+ c->isForwardClassDeclaration() || c->isTypenameArgument() || c->enclosingEnum()) {
int line, column;
getTokenStartPosition(startToken, &line, &column);
const unsigned length = tok.utf16chars();
@@ -1298,11 +1293,11 @@ bool CheckSymbols::maybeAddField(const QList<LookupItem> &candidates, NameAST *a
Symbol *c = r.declaration();
if (!c)
continue;
- else if (!c->isDeclaration())
+ if (!c->isDeclaration())
return false;
- else if (!(c->enclosingScope() && c->enclosingScope()->isClass()))
+ if (!(c->enclosingScope() && c->enclosingScope()->isClass()))
return false; // shadowed
- else if (c->isTypedef() || (c->type() && c->type()->isFunctionType()))
+ if (c->isTypedef() || (c->type() && c->type()->isFunctionType()))
return false; // shadowed
int line, column;
diff --git a/src/plugins/cpptools/cppcodeformatter.cpp b/src/plugins/cpptools/cppcodeformatter.cpp
index fca7998ece..413a5fde7b 100644
--- a/src/plugins/cpptools/cppcodeformatter.cpp
+++ b/src/plugins/cpptools/cppcodeformatter.cpp
@@ -179,8 +179,8 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block)
switch (kind) {
case T_LBRACE: enter(brace_list_open); break;
case T_RBRACE: leave(true); continue;
- case T_SEMICOLON: leave(); continue;
- case T_RPAREN: leave(); continue;
+ case T_SEMICOLON:
+ case T_RPAREN:
case T_COMMA: leave(); continue;
default: enter(assign_open); continue;
} break;
@@ -205,8 +205,8 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block)
case assign_open:
switch (kind) {
case T_RBRACE: leave(true); continue;
- case T_SEMICOLON: leave(); continue;
- case T_RPAREN: leave(); continue;
+ case T_SEMICOLON:
+ case T_RPAREN:
case T_COMMA: leave(); continue;
default: tryExpression(); break;
} break;
diff --git a/src/plugins/cpptools/cppcompletionassistprovider.cpp b/src/plugins/cpptools/cppcompletionassistprovider.cpp
index a06c4c7b42..08100dba44 100644
--- a/src/plugins/cpptools/cppcompletionassistprovider.cpp
+++ b/src/plugins/cpptools/cppcompletionassistprovider.cpp
@@ -51,9 +51,7 @@ bool CppCompletionAssistProvider::isActivationCharSequence(const QString &sequen
const QChar &ch = sequence.at(2);
const QChar &ch2 = sequence.at(1);
const QChar &ch3 = sequence.at(0);
- if (activationSequenceChar(ch, ch2, ch3, nullptr, true, false) != 0)
- return true;
- return false;
+ return activationSequenceChar(ch, ch2, ch3, nullptr, true, false);
}
bool CppCompletionAssistProvider::isContinuationChar(const QChar &c) const
diff --git a/src/plugins/cpptools/cppfollowsymbolundercursor.cpp b/src/plugins/cpptools/cppfollowsymbolundercursor.cpp
index 9a66467951..ded069a96e 100644
--- a/src/plugins/cpptools/cppfollowsymbolundercursor.cpp
+++ b/src/plugins/cpptools/cppfollowsymbolundercursor.cpp
@@ -374,7 +374,7 @@ Symbol *findDefinition(Symbol *symbol, const Snapshot &snapshot, SymbolFinder *s
if (symbol->isFunction())
return nullptr; // symbol is a function definition.
- else if (!symbol->type()->isFunctionType())
+ if (!symbol->type()->isFunctionType())
return nullptr; // not a function declaration
return symbolFinder->findMatchingDefinition(symbol, snapshot);
diff --git a/src/plugins/cpptools/cpprefactoringchanges.cpp b/src/plugins/cpptools/cpprefactoringchanges.cpp
index 4d16dd4813..c063e1efdd 100644
--- a/src/plugins/cpptools/cpprefactoringchanges.cpp
+++ b/src/plugins/cpptools/cpprefactoringchanges.cpp
@@ -172,10 +172,7 @@ bool CppRefactoringFile::isCursorOn(unsigned tokenIndex) const
int start = startOf(tokenIndex);
int end = endOf(tokenIndex);
- if (cursorBegin >= start && cursorBegin <= end)
- return true;
-
- return false;
+ return cursorBegin >= start && cursorBegin <= end;
}
bool CppRefactoringFile::isCursorOn(const AST *ast) const
@@ -186,10 +183,7 @@ bool CppRefactoringFile::isCursorOn(const AST *ast) const
int start = startOf(ast);
int end = endOf(ast);
- if (cursorBegin >= start && cursorBegin <= end)
- return true;
-
- return false;
+ return cursorBegin >= start && cursorBegin <= end;
}
Utils::ChangeSet::Range CppRefactoringFile::range(unsigned tokenIndex) const
diff --git a/src/plugins/cpptools/semantichighlighter.cpp b/src/plugins/cpptools/semantichighlighter.cpp
index 5c7c8110ca..2fdce4c743 100644
--- a/src/plugins/cpptools/semantichighlighter.cpp
+++ b/src/plugins/cpptools/semantichighlighter.cpp
@@ -87,7 +87,7 @@ void SemanticHighlighter::onHighlighterResultAvailable(int from, int to)
{
if (documentRevision() != m_revision)
return; // outdated
- else if (!m_watcher || m_watcher->isCanceled())
+ if (!m_watcher || m_watcher->isCanceled())
return; // aborted
qCDebug(log) << "onHighlighterResultAvailable()" << from << to;
diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp
index 90dd8f3c86..6015f29dec 100644
--- a/src/plugins/debugger/breakhandler.cpp
+++ b/src/plugins/debugger/breakhandler.cpp
@@ -1065,6 +1065,7 @@ QVariant BreakpointItem::data(int column, int role) const
if (role == Qt::DisplayRole) {
if (!m_parameters.functionName.isEmpty())
return simplifyType(m_parameters.functionName);
+
if (m_parameters.type == BreakpointAtMain
|| m_parameters.type == BreakpointAtThrow
|| m_parameters.type == BreakpointAtCatch
@@ -1073,15 +1074,13 @@ QVariant BreakpointItem::data(int column, int role) const
//|| m_response.type == BreakpointAtVFork
|| m_parameters.type == BreakpointAtSysCall)
return typeToString(m_parameters.type);
- if (m_parameters.type == WatchpointAtAddress) {
- quint64 address = m_parameters.address ? m_parameters.address : m_parameters.address;
- return BreakHandler::tr("Data at 0x%1").arg(address, 0, 16);
- }
- if (m_parameters.type == WatchpointAtExpression) {
- QString expression = !m_parameters.expression.isEmpty()
- ? m_parameters.expression : m_parameters.expression;
- return BreakHandler::tr("Data at %1").arg(expression);
- }
+
+ if (m_parameters.type == WatchpointAtAddress)
+ return BreakHandler::tr("Data at 0x%1").arg(m_parameters.address, 0, 16);
+
+ if (m_parameters.type == WatchpointAtExpression)
+ return BreakHandler::tr("Data at %1").arg(m_parameters.expression);
+
return empty;
}
break;
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp
index 4e04a02fc4..798013ed42 100644
--- a/src/plugins/debugger/cdb/cdbengine.cpp
+++ b/src/plugins/debugger/cdb/cdbengine.cpp
@@ -394,14 +394,7 @@ void CdbEngine::setupEngine()
if (!sourcePaths.isEmpty())
debugger.addArgs({"-srcpath", sourcePaths.join(';')});
- QStringList symbolPaths = stringListSetting(CdbSymbolPaths);
- QString symbolPath = sp.inferior.environment.expandedValueForKey("_NT_ALT_SYMBOL_PATH");
- if (!symbolPath.isEmpty())
- symbolPaths += symbolPath;
- symbolPath = sp.inferior.environment.expandedValueForKey("_NT_SYMBOL_PATH");
- if (!symbolPath.isEmpty())
- symbolPaths += symbolPath;
- debugger.addArgs({"-y", symbolPaths.join(';')});
+ debugger.addArgs({"-y", QChar('"') + stringListSetting(CdbSymbolPaths).join(';') + '"'});
switch (sp.startMode) {
case StartInternal:
@@ -501,6 +494,16 @@ void CdbEngine::handleInitialSessionIdle()
}
// Take ownership of the breakpoint. Requests insertion. TODO: Cpp only?
BreakpointManager::claimBreakpointsForEngine(this);
+
+ QStringList symbolPaths = stringListSetting(CdbSymbolPaths);
+ QString symbolPath = rp.inferior.environment.expandedValueForKey("_NT_ALT_SYMBOL_PATH");
+ if (!symbolPath.isEmpty())
+ symbolPaths += symbolPath;
+ symbolPath = rp.inferior.environment.expandedValueForKey("_NT_SYMBOL_PATH");
+ if (!symbolPath.isEmpty())
+ symbolPaths += symbolPath;
+
+ runCommand({QString(".sympath \"") + symbolPaths.join(';') + '"'});
runCommand({".symopt+0x8000"}); // disable searching public symbol table - improving the symbol lookup speed
runCommand({"sxn 0x4000001f", NoFlags}); // Do not break on WowX86 exceptions.
runCommand({"sxn ibp", NoFlags}); // Do not break on initial breakpoints.
diff --git a/src/plugins/debugger/debuggeritem.cpp b/src/plugins/debugger/debuggeritem.cpp
index 0fcd7a165a..3287095d82 100644
--- a/src/plugins/debugger/debuggeritem.cpp
+++ b/src/plugins/debugger/debuggeritem.cpp
@@ -381,6 +381,11 @@ static DebuggerItem::MatchLevel matchSingle(const Abi &debuggerAbi, const Abi &t
return DebuggerItem::DoesNotMatch;
// We have at least 'Matches well' now. Mark the combinations we really like.
+ if (HostOsInfo::isWindowsHost() && engineType == CdbEngineType
+ && targetAbi.osFlavor() >= Abi::WindowsMsvc2005Flavor
+ && targetAbi.osFlavor() <= Abi::WindowsLastMsvcFlavor) {
+ return DebuggerItem::MatchesPerfectly;
+ }
if (HostOsInfo::isWindowsHost() && engineType == GdbEngineType && targetAbi.osFlavor() == Abi::WindowsMSysFlavor)
return DebuggerItem::MatchesPerfectly;
if (HostOsInfo::isLinuxHost() && engineType == GdbEngineType && targetAbi.os() == Abi::LinuxOS)
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index ff0197c225..6cf048420e 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -806,7 +806,7 @@ void GdbEngine::runCommand(const DebuggerCommand &command)
int GdbEngine::commandTimeoutTime() const
{
int time = action(GdbWatchdogTimeout)->value().toInt();
- return 1000 * qMax(40, time);
+ return 1000 * qMax(20, time);
}
void GdbEngine::commandTimeout()
diff --git a/src/plugins/debugger/moduleshandler.cpp b/src/plugins/debugger/moduleshandler.cpp
index 9cb88b077e..4fd1e40669 100644
--- a/src/plugins/debugger/moduleshandler.cpp
+++ b/src/plugins/debugger/moduleshandler.cpp
@@ -111,9 +111,6 @@ QVariant ModuleItem::data(int column, int role) const
"information.\nStepping into the module or setting "
"breakpoints by file and line will not work.");
case PlainSymbols:
- return tr("This module contains debug information.\nStepping "
- "into the module or setting breakpoints by file and "
- "line is expected to work.");
case FastSymbols:
return tr("This module contains debug information.\nStepping "
"into the module or setting breakpoints by file and "
diff --git a/src/plugins/help/localhelpmanager.cpp b/src/plugins/help/localhelpmanager.cpp
index 0a29750b85..8af763f426 100644
--- a/src/plugins/help/localhelpmanager.cpp
+++ b/src/plugins/help/localhelpmanager.cpp
@@ -544,12 +544,9 @@ void LocalHelpManager::updateFilterModel()
bool LocalHelpManager::canOpenOnlineHelp(const QUrl &url)
{
const QString address = url.toString();
- if (address.startsWith("qthelp://org.qt-project.")
- || address.startsWith("qthelp://com.nokia.")
- || address.startsWith("qthelp://com.trolltech.")) {
- return true;
- }
- return false;
+ return address.startsWith("qthelp://org.qt-project.")
+ || address.startsWith("qthelp://com.nokia.")
+ || address.startsWith("qthelp://com.trolltech.");
}
bool LocalHelpManager::openOnlineHelp(const QUrl &url)
diff --git a/src/plugins/languageclient/languageclientmanager.cpp b/src/plugins/languageclient/languageclientmanager.cpp
index 83b67eadbc..defbd0bdac 100644
--- a/src/plugins/languageclient/languageclientmanager.cpp
+++ b/src/plugins/languageclient/languageclientmanager.cpp
@@ -459,7 +459,7 @@ void LanguageClientManager::openDocumentWithClient(TextEditor::TextDocument *doc
void LanguageClientManager::documentClosed(Core::IDocument *document)
{
if (auto textDocument = qobject_cast<TextEditor::TextDocument *>(document)) {
- for (Client *client : reachableClients())
+ for (Client *client : m_clients)
client->closeDocument(textDocument);
m_clientForDocument.remove(textDocument);
}
diff --git a/src/plugins/languageclient/languageclientutils.cpp b/src/plugins/languageclient/languageclientutils.cpp
index c476aaabcf..22c43650ee 100644
--- a/src/plugins/languageclient/languageclientutils.cpp
+++ b/src/plugins/languageclient/languageclientutils.cpp
@@ -213,6 +213,7 @@ void updateEditorToolBar(Core::IEditor *editor)
} else {
widget->toolBar()->removeAction(action);
actions.remove(widget);
+ delete action;
}
} else if (client) {
const QIcon icon = Utils::Icon({{":/languageclient/images/languageclient.png",
diff --git a/src/plugins/mcusupport/mcusupportoptions.cpp b/src/plugins/mcusupport/mcusupportoptions.cpp
index c61a3b6f6d..9cbd8a5a83 100644
--- a/src/plugins/mcusupport/mcusupportoptions.cpp
+++ b/src/plugins/mcusupport/mcusupportoptions.cpp
@@ -234,11 +234,26 @@ static PackageOptions *createQulPackage()
static PackageOptions *createArmGccPackage()
{
- const QString defaultPath =
- Utils::HostOsInfo::isWindowsHost() ?
- QDir::fromNativeSeparators(qEnvironmentVariable("ProgramFiles(x86)"))
- + "/GNU Tools ARM Embedded/"
- : QString("%{Env:ARMGCC_DIR}");
+ const char envVar[] = "ARMGCC_DIR";
+
+ QString defaultPath;
+ if (qEnvironmentVariableIsSet(envVar))
+ defaultPath = qEnvironmentVariable(envVar);
+ if (defaultPath.isEmpty() && Utils::HostOsInfo::isWindowsHost()) {
+ const QDir installDir(
+ qEnvironmentVariable("ProgramFiles(x86)") + "/GNU Tools ARM Embedded/");
+ if (installDir.exists()) {
+ // If GNU Tools installation dir has only one sub dir,
+ // select the sub dir, otherwise the installation dir.
+ const QFileInfoList subDirs =
+ installDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
+ if (subDirs.count() == 1)
+ defaultPath = subDirs.first().filePath() + '/';
+ }
+ }
+ if (defaultPath.isEmpty())
+ defaultPath = QDir::homePath();
+
auto result = new PackageOptions(
PackageOptions::tr("GNU Arm Embedded Toolchain"),
defaultPath,
@@ -246,7 +261,7 @@ static PackageOptions *createArmGccPackage()
Constants::SETTINGS_KEY_PACKAGE_ARMGCC);
result->setDownloadUrl(
"https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads");
- result->setEnvironmentVariableName("ARMGCC_DIR");
+ result->setEnvironmentVariableName(envVar);
return result;
}
@@ -286,8 +301,8 @@ static PackageOptions *createStm32CubeProgrammerPackage()
static PackageOptions *createEvkbImxrt1050SdkPackage()
{
auto result = new PackageOptions(
- PackageOptions::tr("NXP EVKB-IMXRT1050 SDK"),
- "%{Env:EVKB_IMXRT1050_SDK_PATH}",
+ PackageOptions::tr("NXP i.MXRT SDK"),
+ "%{Env:EVKB_IMXRT1050_SDK_PATH}", // TODO: Try to not use 1050 specifics
"EVKB-IMXRT1050_manifest_v3_5.xml",
"evkbImxrt1050Sdk");
result->setDownloadUrl("https://mcuxpresso.nxp.com/en/welcome");
@@ -306,6 +321,7 @@ static PackageOptions *createSeggerJLinkPackage()
Utils::HostOsInfo::withExecutableSuffix("JLink"),
"seggerJLink");
result->setDownloadUrl("https://www.segger.com/downloads/jlink");
+ result->setEnvironmentVariableName("SEGGER_JLINK_SOFTWARE_AND_DOCUMENTATION_PATH");
return result;
}
@@ -454,10 +470,11 @@ static void setKitEnvironment(ProjectExplorer::Kit *k, const BoardOptions* board
changes.append({package->environmentVariableName(),
QDir::toNativeSeparators(package->path())});
}
- if (!pathAdditions.isEmpty()) {
- pathAdditions.append("${Path}");
- changes.append({"Path", pathAdditions.join(Utils::HostOsInfo::pathListSeparator())});
- }
+ pathAdditions.append("${Path}");
+ if (Utils::HostOsInfo::isWindowsHost())
+ pathAdditions.append(QDir::toNativeSeparators(Core::ICore::libexecPath())); // for jom
+ pathAdditions.append(QDir::toNativeSeparators(Core::ICore::libexecPath() + "/clang/bin"));
+ changes.append({"Path", pathAdditions.join(Utils::HostOsInfo::pathListSeparator())});
EnvironmentKitAspect::setEnvironmentChanges(k, changes);
}
@@ -470,6 +487,8 @@ static void setKitCMakeOptions(ProjectExplorer::Kit *k, const BoardOptions* boar
("%{CurrentBuild:Env:Qul_DIR}/" +
board->toolChainFile()).toUtf8()));
CMakeConfigurationKitAspect::setConfiguration(k, config);
+ if (Utils::HostOsInfo::isWindowsHost())
+ CMakeGeneratorKitAspect::setGenerator(k, "NMake Makefiles JOM");
}
ProjectExplorer::Kit *McuSupportOptions::kit(const BoardOptions* board)
diff --git a/src/plugins/mcusupport/mcusupportoptionspage.cpp b/src/plugins/mcusupport/mcusupportoptionspage.cpp
index 1396d4226f..9057e2a054 100644
--- a/src/plugins/mcusupport/mcusupportoptionspage.cpp
+++ b/src/plugins/mcusupport/mcusupportoptionspage.cpp
@@ -68,7 +68,7 @@ McuSupportOptionsWidget::McuSupportOptionsWidget(const McuSupportOptions *option
auto mainLayout = new QVBoxLayout(this);
auto boardChooserlayout = new QHBoxLayout;
- auto boardChooserLabel = new QLabel(McuSupportOptionsPage::tr("MCU board:"));
+ auto boardChooserLabel = new QLabel(McuSupportOptionsPage::tr("Target:"));
boardChooserlayout->addWidget(boardChooserLabel);
auto boardComboBox = new QComboBox;
boardChooserLabel->setBuddy(boardComboBox);
diff --git a/src/plugins/mcusupport/mcusupportrunconfiguration.cpp b/src/plugins/mcusupport/mcusupportrunconfiguration.cpp
index 92dcb4181f..4ec72227e1 100644
--- a/src/plugins/mcusupport/mcusupportrunconfiguration.cpp
+++ b/src/plugins/mcusupport/mcusupportrunconfiguration.cpp
@@ -94,6 +94,7 @@ public:
r.workingDirectory =
target->activeBuildConfiguration()->buildDirectory().toUserOutput();
r.setCommandLine(cmd);
+ r.environment = target->activeBuildConfiguration()->environment();
SimpleTargetRunner::doStart(r, {});
});
}
diff --git a/src/plugins/projectexplorer/abi.cpp b/src/plugins/projectexplorer/abi.cpp
index 420a10ba98..42a34bbcdc 100644
--- a/src/plugins/projectexplorer/abi.cpp
+++ b/src/plugins/projectexplorer/abi.cpp
@@ -209,7 +209,6 @@ static Abi macAbiForCpu(quint32 type) {
case 0x01000000 + 7: // CPU_TYPE_X86_64
return Abi(Abi::X86Architecture, Abi::DarwinOS, Abi::GenericFlavor, Abi::MachOFormat, 64);
case 18: // CPU_TYPE_POWERPC
- return Abi(Abi::PowerPCArchitecture, Abi::DarwinOS, Abi::GenericFlavor, Abi::MachOFormat, 32);
case 0x01000000 + 18: // CPU_TYPE_POWERPC64
return Abi(Abi::PowerPCArchitecture, Abi::DarwinOS, Abi::GenericFlavor, Abi::MachOFormat, 32);
case 12: // CPU_TYPE_ARM
@@ -515,9 +514,7 @@ Abi Abi::abiFromTargetTriplet(const QString &triple)
if (flavor == UnknownFlavor)
flavor = GenericFlavor;
format = ElfFormat;
- } else if (p == "android") {
- flavor = AndroidLinuxFlavor;
- } else if (p == "androideabi") {
+ } else if (p == "android" || p == "androideabi") {
flavor = AndroidLinuxFlavor;
} else if (p.startsWith("freebsd")) {
os = BsdOS;
diff --git a/src/plugins/projectexplorer/abi.h b/src/plugins/projectexplorer/abi.h
index 21794d5be7..47605b10e6 100644
--- a/src/plugins/projectexplorer/abi.h
+++ b/src/plugins/projectexplorer/abi.h
@@ -97,6 +97,7 @@ public:
WindowsMsvc2015Flavor,
WindowsMsvc2017Flavor,
WindowsMsvc2019Flavor,
+ WindowsLastMsvcFlavor = WindowsMsvc2019Flavor,
WindowsMSysFlavor,
WindowsCEFlavor,
diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp
index e761647398..c5fb985707 100644
--- a/src/plugins/projectexplorer/gcctoolchain.cpp
+++ b/src/plugins/projectexplorer/gcctoolchain.cpp
@@ -221,8 +221,12 @@ static GccToolChain::DetectedAbisResult guessGccAbi(const FilePath &path, const
QStringList arguments = extraArgs;
arguments << "-dumpmachine";
QString machine = QString::fromLocal8Bit(runGcc(path, arguments, env)).trimmed();
- if (machine.isEmpty())
+ if (machine.isEmpty()) {
+ // ICC does not implement the -dumpmachine option on macOS.
+ if (HostOsInfo::isMacHost() && (path.fileName() == "icc" || path.fileName() == "icpc"))
+ return GccToolChain::DetectedAbisResult({Abi::hostAbi()});
return GccToolChain::DetectedAbisResult(); // no need to continue if running failed once...
+ }
return GccToolChain::DetectedAbisResult(guessGccAbi(machine, macros), machine);
}
@@ -660,7 +664,7 @@ ToolChain::BuiltInHeaderPathsRunner GccToolChain::createBuiltInHeaderPathsRunner
extraHeaderPathsFunction,
flags,
sysRoot,
- /*target=*/""); // Target must be empty for gcc.
+ /*originalTargetTriple=*/""); // Must be empty for gcc.
};
}
@@ -1335,9 +1339,7 @@ void GccToolChainConfigWidget::handleCompilerCommandChange()
// Find a good ABI for the new compiler:
Abi newAbi;
- if (customAbi)
- newAbi = currentAbi;
- else if (abiList.contains(currentAbi))
+ if (customAbi || abiList.contains(currentAbi))
newAbi = currentAbi;
m_abiWidget->setAbis(abiList, newAbi);
@@ -1833,7 +1835,7 @@ QList<ToolChain *> MingwToolChainFactory::detectForImport(const ToolChainDescrip
LinuxIccToolChain::LinuxIccToolChain() :
GccToolChain(Constants::LINUXICC_TOOLCHAIN_TYPEID)
{
- setTypeDisplayName(LinuxIccToolChainFactory::tr("Linux ICC"));
+ setTypeDisplayName(LinuxIccToolChainFactory::tr("ICC"));
}
/**
@@ -1874,7 +1876,7 @@ QStringList LinuxIccToolChain::suggestedMkspecList() const
LinuxIccToolChainFactory::LinuxIccToolChainFactory()
{
- setDisplayName(tr("Linux ICC"));
+ setDisplayName(tr("ICC"));
setSupportedToolChainType(Constants::LINUXICC_TOOLCHAIN_TYPEID);
setSupportedLanguages({Constants::CXX_LANGUAGE_ID, Constants::C_LANGUAGE_ID});
setToolchainConstructor([] { return new LinuxIccToolChain; });
diff --git a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp
index 432a22fec1..dbae037260 100644
--- a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp
+++ b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp
@@ -977,9 +977,7 @@ bool ListField::validate(MacroExpander *expander, QString *message)
return false;
updateIndex();
- if (selectionModel()->hasSelection())
- return true;
- return false;
+ return selectionModel()->hasSelection();
}
void ListField::initializeData(MacroExpander *expander)
@@ -1116,11 +1114,8 @@ void ComboBoxField::setup(JsonFieldPage *page, const QString &name)
selectionModel()->blockSignals(true);
w->blockSignals(false);
});
- page->registerObjectAsFieldWithName<QItemSelectionModel>(name, selectionModel(), &QItemSelectionModel::selectionChanged, [this]() {
- const QModelIndex i = selectionModel()->currentIndex();
- if (i.isValid())
- return i.data(ValueRole);
- return QVariant();
+ page->registerObjectAsFieldWithName<QComboBox>(name, w, QOverload<int>::of(&QComboBox::activated), [w]() {
+ return w->currentData(ValueRole);
});
QObject::connect(selectionModel(), &QItemSelectionModel::selectionChanged, page, [page]() {
emit page->completeChanged();
@@ -1143,6 +1138,13 @@ void ComboBoxField::initializeData(MacroExpander *expander)
w->setCurrentIndex(selectionModel()->currentIndex().row());
}
+QVariant ComboBoxField::toSettings() const
+{
+ if (auto w = qobject_cast<QComboBox*>(widget()))
+ return w->currentData(ValueRole);
+ return {};
+}
+
void IconListField::setup(JsonFieldPage *page, const QString &name)
{
auto w = qobject_cast<QListView*>(widget());
diff --git a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage_p.h b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage_p.h
index 62db37aff6..6e91500b8e 100644
--- a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage_p.h
+++ b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage_p.h
@@ -236,10 +236,11 @@ private:
class ComboBoxField : public ListField
{
-public:
+private:
void setup(JsonFieldPage *page, const QString &name) override;
QWidget *createWidget(const QString &displayName, JsonFieldPage *page) override;
void initializeData(Utils::MacroExpander *expander) override;
+ QVariant toSettings() const override;
};
class IconListField : public ListField
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index fb3e912a65..4d7aee5fc8 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -2790,9 +2790,7 @@ bool ProjectExplorerPlugin::coreAboutToClose()
if (box.clickedButton() != closeAnyway)
return false;
}
- if (!dd->m_outputPane.aboutToClose())
- return false;
- return true;
+ return dd->m_outputPane.aboutToClose();
}
void ProjectExplorerPlugin::handleCommandLineArguments(const QStringList &arguments)
diff --git a/src/plugins/projectexplorer/projecttreewidget.cpp b/src/plugins/projectexplorer/projecttreewidget.cpp
index 8f4d5adef7..b3ae5756e7 100644
--- a/src/plugins/projectexplorer/projecttreewidget.cpp
+++ b/src/plugins/projectexplorer/projecttreewidget.cpp
@@ -382,10 +382,7 @@ Node *ProjectTreeWidget::nodeForFile(const FilePath &fileName)
if (ProjectNode *projectNode = project->rootProjectNode()) {
projectNode->forEachGenericNode([&](Node *node) {
if (node->filePath() == fileName) {
- if (!bestNode) {
- bestNode = node;
- bestNodeExpandCount = ProjectTreeWidget::expandedCount(node);
- } else if (priority(node) < priority(bestNode)) {
+ if (!bestNode || priority(node) < priority(bestNode)) {
bestNode = node;
bestNodeExpandCount = ProjectTreeWidget::expandedCount(node);
} else if (priority(node) == priority(bestNode)) {
diff --git a/src/plugins/projectexplorer/projectwelcomepage.cpp b/src/plugins/projectexplorer/projectwelcomepage.cpp
index 0f2bfb4dc3..8d74b3f648 100644
--- a/src/plugins/projectexplorer/projectwelcomepage.cpp
+++ b/src/plugins/projectexplorer/projectwelcomepage.cpp
@@ -82,7 +82,6 @@ QVariant ProjectModel::data(const QModelIndex &index, int role) const
case Qt::DisplayRole:
return data.second;
case Qt::ToolTipRole:
- return data.first;
case FilePathRole:
return data.first;
case PrettyFilePathRole:
diff --git a/src/plugins/projectexplorer/projectwindow.cpp b/src/plugins/projectexplorer/projectwindow.cpp
index 96cfc251d3..dfa20793e3 100644
--- a/src/plugins/projectexplorer/projectwindow.cpp
+++ b/src/plugins/projectexplorer/projectwindow.cpp
@@ -213,8 +213,6 @@ public:
{
switch (role) {
case Qt::DisplayRole:
- return m_project->displayName();
-
case ProjectDisplayNameRole:
return m_project->displayName();
diff --git a/src/plugins/projectexplorer/targetsettingspanel.cpp b/src/plugins/projectexplorer/targetsettingspanel.cpp
index e1345cb50e..79cfe02fdb 100644
--- a/src/plugins/projectexplorer/targetsettingspanel.cpp
+++ b/src/plugins/projectexplorer/targetsettingspanel.cpp
@@ -669,8 +669,7 @@ TargetGroupItem::TargetGroupItem(const QString &displayName, Project *project)
{
d->m_displayName = displayName;
QObject::connect(project, &Project::addedTarget,
- d.get(), &TargetGroupItemPrivate::handleTargetAdded,
- Qt::QueuedConnection);
+ d.get(), &TargetGroupItemPrivate::handleTargetAdded);
QObject::connect(project, &Project::removedTarget,
d.get(), &TargetGroupItemPrivate::handleTargetRemoved);
QObject::connect(project, &Project::activeTargetChanged,
diff --git a/src/plugins/projectexplorer/targetsetuppage.cpp b/src/plugins/projectexplorer/targetsetuppage.cpp
index d80b2689c1..a200b9233d 100644
--- a/src/plugins/projectexplorer/targetsetuppage.cpp
+++ b/src/plugins/projectexplorer/targetsetuppage.cpp
@@ -101,7 +101,7 @@ public:
noValidKitLabel = new QLabel(setupTargetPage);
noValidKitLabel->setWordWrap(true);
noValidKitLabel->setText(TargetSetupPage::tr("<span style=\" font-weight:600;\">No suitable kits found.</span><br/>"
- "Please add a kit in the <a href=\"buildandrun\">options</a> "
+ "Add a kit in the <a href=\"buildandrun\">options</a> "
"or via the maintenance tool of the SDK."));
noValidKitLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
noValidKitLabel->setVisible(false);
diff --git a/src/plugins/projectexplorer/targetsetupwidget.cpp b/src/plugins/projectexplorer/targetsetupwidget.cpp
index cc5257fabc..ddcda6d8ff 100644
--- a/src/plugins/projectexplorer/targetsetupwidget.cpp
+++ b/src/plugins/projectexplorer/targetsetupwidget.cpp
@@ -122,7 +122,7 @@ bool TargetSetupWidget::isKitSelected() const
void TargetSetupWidget::setKitSelected(bool b)
{
// Only check target if there are build configurations possible
- b &= !selectedBuildInfoList().isEmpty();
+ b &= hasSelectedBuildConfigurations();
m_ignoreChange = true;
m_detailsWidget->setChecked(b);
m_detailsWidget->widget()->setEnabled(b);
@@ -187,9 +187,12 @@ void TargetSetupWidget::targetCheckBoxToggled(bool b)
if (m_ignoreChange)
return;
m_detailsWidget->widget()->setEnabled(b);
- m_detailsWidget->setState(b && Utils::contains(m_infoStore, &BuildInfoStore::hasIssues)
- ? Utils::DetailsWidget::Expanded
- : Utils::DetailsWidget::Collapsed);
+ if (b && (contains(m_infoStore, &BuildInfoStore::hasIssues)
+ || !contains(m_infoStore, &BuildInfoStore::isEnabled))) {
+ m_detailsWidget->setState(DetailsWidget::Expanded);
+ } else if (!b) {
+ m_detailsWidget->setState(Utils::DetailsWidget::Collapsed);
+ }
emit selectedToggled();
}
@@ -230,12 +233,13 @@ void TargetSetupWidget::update(const Kit::Predicate &predicate)
// Kits that don't fulfill the project predicate are not selectable, because we cannot
// guarantee that we can handle the project sensibly (e.g. qmake project without Qt).
if (predicate && !predicate(kit())) {
- setEnabled(false);
+ toggleEnabled(false);
+ m_infoStore.clear();
m_detailsWidget->setToolTip(tr("You cannot use this kit, because it does not fulfill "
"the project's prerequisites."));
return;
}
- setEnabled(true);
+ toggleEnabled(true);
m_detailsWidget->setIcon(kit()->isValid() ? kit()->icon() : Icons::CRITICAL.icon());
m_detailsWidget->setToolTip(m_kit->toHtml());
updateDefaultBuildDirectories();
@@ -251,6 +255,22 @@ const QList<BuildInfo> TargetSetupWidget::buildInfoList(const Kit *k, const File
return {info};
}
+bool TargetSetupWidget::hasSelectedBuildConfigurations() const
+{
+ return !selectedBuildInfoList().isEmpty();
+}
+
+void TargetSetupWidget::toggleEnabled(bool enabled)
+{
+ m_detailsWidget->widget()->setEnabled(enabled && hasSelectedBuildConfigurations());
+ m_detailsWidget->setCheckable(enabled);
+ m_detailsWidget->setExpandable(enabled);
+ if (!enabled) {
+ m_detailsWidget->setState(DetailsWidget::Collapsed);
+ m_detailsWidget->setChecked(false);
+ }
+}
+
const QList<BuildInfo> TargetSetupWidget::selectedBuildInfoList() const
{
QList<BuildInfo> result;
@@ -276,6 +296,7 @@ void TargetSetupWidget::updateDefaultBuildDirectories()
for (const BuildInfo &buildInfo : buildInfoList(m_kit, m_projectPath)) {
if (!buildInfo.factory())
continue;
+ bool found = false;
for (BuildInfoStore &buildInfoStore : m_infoStore) {
if (buildInfoStore.buildInfo.typeName == buildInfo.typeName) {
if (!buildInfoStore.customBuildDir) {
@@ -283,9 +304,12 @@ void TargetSetupWidget::updateDefaultBuildDirectories()
buildInfoStore.pathChooser->setFileName(buildInfo.buildDirectory);
m_ignoreChange = false;
}
+ found = true;
break;
}
}
+ if (!found) // the change of the kit may have produced more build information than before
+ addBuildInfo(buildInfo, false);
}
}
diff --git a/src/plugins/projectexplorer/targetsetupwidget.h b/src/plugins/projectexplorer/targetsetupwidget.h
index 80f64ad918..6534baf700 100644
--- a/src/plugins/projectexplorer/targetsetupwidget.h
+++ b/src/plugins/projectexplorer/targetsetupwidget.h
@@ -78,6 +78,9 @@ signals:
private:
static const QList<BuildInfo> buildInfoList(const Kit *k, const Utils::FilePath &projectPath);
+ bool hasSelectedBuildConfigurations() const;
+
+ void toggleEnabled(bool enabled);
void checkBoxToggled(bool b);
void pathChanged();
void targetCheckBoxToggled(bool b);
diff --git a/src/plugins/projectexplorer/userfileaccessor.cpp b/src/plugins/projectexplorer/userfileaccessor.cpp
index 676bcf7990..5f3c3692b7 100644
--- a/src/plugins/projectexplorer/userfileaccessor.cpp
+++ b/src/plugins/projectexplorer/userfileaccessor.cpp
@@ -799,7 +799,7 @@ QVariant UserFileVersion19Upgrader::process(const QVariant &entry, const QString
"ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory",
"Qbs.RunConfiguration.WorkingDirectory",
"Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory",
- "RemoteLinux.CustomRunConfig.WorkingDirectory"
+ "RemoteLinux.CustomRunConfig.WorkingDirectory",
"RemoteLinux.RunConfig.WorkingDirectory",
"WorkingDir"};
static const QStringList termKeys = {"CMakeProjectManager.CMakeRunConfiguration.UseTerminal",
diff --git a/src/plugins/python/pythonrunconfiguration.cpp b/src/plugins/python/pythonrunconfiguration.cpp
index 4477f11cb1..41386ef611 100644
--- a/src/plugins/python/pythonrunconfiguration.cpp
+++ b/src/plugins/python/pythonrunconfiguration.cpp
@@ -257,8 +257,10 @@ PythonRunConfiguration::PythonRunConfiguration(Target *target, Core::Id id)
connect(PythonSettings::instance(), &PythonSettings::interpretersChanged,
interpreterAspect, &InterpreterAspect::updateInterpreters);
- interpreterAspect->updateInterpreters(PythonSettings::interpreters());
- interpreterAspect->setDefaultInterpreter(PythonSettings::defaultInterpreter());
+ QList<Interpreter> interpreters = PythonSettings::detectPythonVenvs(project()->projectDirectory());
+ aspect<InterpreterAspect>()->updateInterpreters(PythonSettings::interpreters());
+ aspect<InterpreterAspect>()->setDefaultInterpreter(
+ interpreters.isEmpty() ? PythonSettings::defaultInterpreter() : interpreters.first());
auto scriptAspect = addAspect<MainScriptAspect>();
scriptAspect->setSettingsKey("PythonEditor.RunConfiguation.Script");
diff --git a/src/plugins/python/pythonsettings.cpp b/src/plugins/python/pythonsettings.cpp
index d9ab47093c..acb7a50ddd 100644
--- a/src/plugins/python/pythonsettings.cpp
+++ b/src/plugins/python/pythonsettings.cpp
@@ -211,6 +211,7 @@ public:
InterpreterOptionsPage();
void setInterpreter(const QList<Interpreter> &interpreters) { m_interpreters = interpreters; }
+ void addInterpreter(const Interpreter &interpreter) { m_interpreters << interpreter; }
QList<Interpreter> interpreters() const { return m_interpreters; }
void setDefaultInterpreter(const QString &defaultId)
{ m_defaultInterpreterId = defaultId; }
@@ -278,6 +279,7 @@ Interpreter::Interpreter(const FilePath &python, const QString &defaultName, boo
{
SynchronousProcess pythonProcess;
pythonProcess.setProcessChannelMode(QProcess::MergedChannels);
+ pythonProcess.setTimeoutS(1);
SynchronousProcessResponse response = pythonProcess.runBlocking(
CommandLine(python, {"--version"}));
if (response.result == SynchronousProcessResponse::Finished)
@@ -465,11 +467,21 @@ void PythonSettings::init()
void PythonSettings::setInterpreter(const QList<Interpreter> &interpreters, const QString &defaultId)
{
+ if (defaultId == interpreterOptionsPage().defaultInterpreter().id
+ && interpreters == interpreterOptionsPage().interpreters()) {
+ return;
+ }
interpreterOptionsPage().setInterpreter(interpreters);
interpreterOptionsPage().setDefaultInterpreter(defaultId);
- toSettings(Core::ICore::settings(), {interpreters, defaultId});
- if (QTC_GUARD(settingsInstance))
- emit settingsInstance->interpretersChanged(interpreters, defaultId);
+ saveSettings();
+}
+
+void PythonSettings::addInterpreter(const Interpreter &interpreter, bool isDefault)
+{
+ interpreterOptionsPage().addInterpreter(interpreter);
+ if (isDefault)
+ interpreterOptionsPage().setDefaultInterpreter(interpreter.id);
+ saveSettings();
}
PythonSettings *PythonSettings::instance()
@@ -478,6 +490,52 @@ PythonSettings *PythonSettings::instance()
return settingsInstance;
}
+QList<Interpreter> PythonSettings::detectPythonVenvs(const FilePath &path)
+{
+ QList<Interpreter> result;
+ QDir dir = path.toFileInfo().isDir() ? QDir(path.toString()) : path.toFileInfo().dir();
+ if (dir.exists()) {
+ const QString venvPython = HostOsInfo::withExecutableSuffix("python");
+ const QString activatePath = HostOsInfo::isWindowsHost() ? QString{"Scripts"}
+ : QString{"bin"};
+ do {
+ for (const QString &directory : dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
+ if (dir.cd(directory)) {
+ if (dir.cd(activatePath)) {
+ if (dir.exists("activate") && dir.exists(venvPython)) {
+ FilePath python = FilePath::fromString(dir.absoluteFilePath(venvPython));
+ dir.cdUp();
+ const QString defaultName = QString("Python (%1 Virtual Environment)")
+ .arg(dir.dirName());
+ Interpreter interpreter
+ = Utils::findOrDefault(PythonSettings::interpreters(),
+ Utils::equal(&Interpreter::command, python));
+ if (interpreter.command.isEmpty()) {
+ interpreter = Interpreter(python, defaultName);
+ PythonSettings::addInterpreter(interpreter);
+ }
+ result << interpreter;
+ } else {
+ dir.cdUp();
+ }
+ }
+ dir.cdUp();
+ }
+ }
+ } while (dir.cdUp());
+ }
+ return result;
+}
+
+void PythonSettings::saveSettings()
+{
+ const QList<Interpreter> &interpreters = interpreterOptionsPage().interpreters();
+ const QString &defaultId = interpreterOptionsPage().defaultInterpreter().id;
+ toSettings(Core::ICore::settings(), {interpreters, defaultId});
+ if (QTC_GUARD(settingsInstance))
+ emit settingsInstance->interpretersChanged(interpreters, defaultId);
+}
+
QList<Interpreter> PythonSettings::interpreters()
{
return interpreterOptionsPage().interpreters();
diff --git a/src/plugins/python/pythonsettings.h b/src/plugins/python/pythonsettings.h
index 7ca5218ae3..0ef6c62a0f 100644
--- a/src/plugins/python/pythonsettings.h
+++ b/src/plugins/python/pythonsettings.h
@@ -26,6 +26,7 @@
#pragma once
#include <utils/fileutils.h>
+#include <utils/optional.h>
#include <QUuid>
@@ -43,6 +44,11 @@ public:
const QString &name,
const Utils::FilePath &command);
+ inline bool operator==(const Interpreter &other) const
+ {
+ return id == other.id && name == other.name && command == other.command;
+ }
+
QString id = QUuid::createUuid().toString();
QString name;
Utils::FilePath command;
@@ -57,13 +63,18 @@ public:
static QList<Interpreter> interpreters();
static Interpreter defaultInterpreter();
static void setInterpreter(const QList<Interpreter> &interpreters, const QString &defaultId);
+ static void addInterpreter(const Interpreter &interpreter, bool isDefault = false);
static PythonSettings *instance();
+ static QList<Interpreter> detectPythonVenvs(const Utils::FilePath &path);
+
signals:
void interpretersChanged(const QList<Interpreter> &interpreters, const QString &defaultId);
private:
PythonSettings();
+
+ static void saveSettings();
};
} // namespace Internal
diff --git a/src/plugins/python/pythonutils.cpp b/src/plugins/python/pythonutils.cpp
index 03096ee96e..aa7051b396 100644
--- a/src/plugins/python/pythonutils.cpp
+++ b/src/plugins/python/pythonutils.cpp
@@ -175,6 +175,11 @@ static FilePath detectPython(const FilePath &documentPath)
}
}
+ // check whether this file is inside a python virtual environment
+ QList<Interpreter> venvInterpreters = PythonSettings::detectPythonVenvs(documentPath);
+ if (!python.exists())
+ python = venvInterpreters.value(0).command;
+
if (!python.exists())
python = PythonSettings::defaultInterpreter().command;
@@ -248,9 +253,15 @@ public:
? QString{"python-language-server[pyflakes]"}
: QString{"python-language-server[all]"};
- m_process.start(m_python.toString(), {"-m", "pip", "install", "--user", pylsVersion});
+ QStringList arguments = {"-m", "pip", "install", pylsVersion};
+
+ // add --user to global pythons, but skip it for venv pythons
+ if (!QDir(m_python.parentDir().toString()).exists("activate"))
+ arguments << "--user";
+
+ m_process.start(m_python.toString(), arguments);
- Core::MessageManager::write(tr("Running '%1 %2' to install python language server")
+ Core::MessageManager::write(tr("Running \"%1 %2\" to install Python language server")
.arg(m_process.program(), m_process.arguments().join(' ')));
m_killTimer.setSingleShot(true);
@@ -261,7 +272,7 @@ private:
void cancel()
{
SynchronousProcess::stopProcess(m_process);
- Core::MessageManager::write(tr("The Python language server installation canceled by %1.")
+ Core::MessageManager::write(tr("The Python language server installation was canceled by %1.")
.arg(m_killTimer.isActive() ? tr("user") : tr("time out")));
}
@@ -371,7 +382,7 @@ void PyLSConfigureAssistant::openDocumentWithPython(const FilePath &python,
&& infoBar->canInfoBeAdded(installPylsInfoBarId)) {
auto message
= tr("Install and set up Python language server (PyLS) for %1 (%2). "
- "The language server provides Python specific completions and annotations.")
+ "The language server provides Python specific completion and annotation.")
.arg(pythonName(python), python.toUserOutput());
Core::InfoBarEntry info(installPylsInfoBarId,
message,
@@ -383,7 +394,7 @@ void PyLSConfigureAssistant::openDocumentWithPython(const FilePath &python,
} else if (lsState.state == PythonLanguageServerState::AlreadyInstalled
&& infoBar->canInfoBeAdded(startPylsInfoBarId)) {
auto message = tr("Found a Python language server for %1 (%2). "
- "Should this one be set up for this document?")
+ "Set it up for this document?")
.arg(pythonName(python), python.toUserOutput());
Core::InfoBarEntry info(startPylsInfoBarId,
message,
diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt
index c645a96774..df5d381511 100644
--- a/src/plugins/qmldesigner/CMakeLists.txt
+++ b/src/plugins/qmldesigner/CMakeLists.txt
@@ -298,6 +298,7 @@ extend_qtc_plugin(QmlDesigner
extend_qtc_plugin(QmlDesigner
SOURCES_PREFIX components/propertyeditor
SOURCES
+ aligndistribute.cpp aligndistribute.h
designerpropertymap.cpp designerpropertymap.h
fileresourcesmodel.cpp fileresourcesmodel.h
itemfiltermodel.cpp itemfiltermodel.h
diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp
index d06ea3c495..72bdf4be13 100644
--- a/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp
@@ -113,9 +113,20 @@ QToolBar *CurveEditor::createToolBar()
durationWidget->setLayout(durationBox);
bar->addWidget(durationWidget);
+ auto *cfspin = new QSpinBox;
+ cfspin->setMinimum(0);
+ cfspin->setMaximum(std::numeric_limits<int>::max());
+
+ auto intSignal = static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged);
+ connect(cfspin, intSignal, [this](int val) { m_view->setCurrentFrame(val, false); });
+ connect(m_view, &GraphicsView::notifyFrameChanged, [cfspin](int val) {
+ QSignalBlocker blocker(cfspin);
+ cfspin->setValue(val);
+ });
+
auto *positionBox = new QHBoxLayout;
positionBox->addWidget(new QLabel(tr("Current Frame")));
- positionBox->addWidget(new QSpinBox);
+ positionBox->addWidget(cfspin);
auto *positionWidget = new QWidget;
positionWidget->setLayout(positionBox);
bar->addWidget(positionWidget);
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
index 7a711923cc..f225128a01 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
@@ -184,11 +184,14 @@ void GraphicsView::setZoomY(double zoom, const QPoint &pivot)
viewport()->update();
}
-void GraphicsView::setCurrentFrame(int frame)
+void GraphicsView::setCurrentFrame(int frame, bool notify)
{
int clampedFrame = clamp(frame, m_model->minimumTime(), m_model->maximumTime());
m_playhead.moveToFrame(clampedFrame, this);
viewport()->update();
+
+ if (notify)
+ notifyFrameChanged(frame);
}
void GraphicsView::scrollContent(double x, double y)
@@ -251,6 +254,7 @@ void GraphicsView::mousePressEvent(QMouseEvent *event)
QPointF pos = mapToScene(event->pos());
if (timeScaleRect().contains(pos)) {
setCurrentFrame(std::round(mapXtoTime(pos.x())));
+ m_playhead.setMoving(true);
event->accept();
return;
}
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h
index af138429bf..d7c2f14da0 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h
@@ -45,6 +45,9 @@ class GraphicsView : public QGraphicsView
friend class Playhead;
+signals:
+ void notifyFrameChanged(int frame);
+
public:
GraphicsView(CurveEditorModel *model, QWidget *parent = nullptr);
@@ -94,7 +97,7 @@ public:
void setZoomY(double zoom, const QPoint &pivot = QPoint());
- void setCurrentFrame(int frame);
+ void setCurrentFrame(int frame, bool notify = true);
void scrollContent(double x, double y);
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/playhead.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/playhead.cpp
index e2e6d21274..7b25bbb9af 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/playhead.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/playhead.cpp
@@ -56,6 +56,11 @@ int Playhead::currentFrame() const
return m_frame;
}
+void Playhead::setMoving(bool moving)
+{
+ m_moving = moving;
+}
+
void Playhead::moveToFrame(int frame, GraphicsView *view)
{
m_frame = frame;
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/playhead.h b/src/plugins/qmldesigner/components/curveeditor/detail/playhead.h
index 3a785624bd..9f6295c34a 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/playhead.h
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/playhead.h
@@ -45,6 +45,8 @@ public:
void paint(QPainter *painter, GraphicsView *view) const;
+ void setMoving(bool moving);
+
void moveToFrame(int frame, GraphicsView *view);
void resize(GraphicsView *view);
diff --git a/src/plugins/qmldesigner/components/itemlibrary/images/item-3D_model-icon.png b/src/plugins/qmldesigner/components/itemlibrary/images/item-3D_model-icon.png
index 1a69afa777..bbdafae887 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/images/item-3D_model-icon.png
+++ b/src/plugins/qmldesigner/components/itemlibrary/images/item-3D_model-icon.png
Binary files differ
diff --git a/src/plugins/qmldesigner/components/itemlibrary/images/item-3D_model-icon@2x.png b/src/plugins/qmldesigner/components/itemlibrary/images/item-3D_model-icon@2x.png
index d3aa02218b..7ab1e27ac3 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/images/item-3D_model-icon@2x.png
+++ b/src/plugins/qmldesigner/components/itemlibrary/images/item-3D_model-icon@2x.png
Binary files differ
diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp
index e82fbe9770..98735e5120 100644
--- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp
+++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp
@@ -257,14 +257,15 @@ void static appendForcedNodes(const NodeListProperty &property, QList<ModelNode>
QList<ModelNode> filteredList(const NodeListProperty &property, bool filter)
{
- if (!filter)
- return property.toModelNodeList();
-
QList<ModelNode> list;
- list.append(Utils::filtered(property.toModelNodeList(), [] (const ModelNode &arg) {
- return QmlItemNode::isValidQmlItemNode(arg) || NodeHints::fromModelNode(arg).visibleInNavigator();
- }));
+ if (filter) {
+ list.append(Utils::filtered(property.toModelNodeList(), [] (const ModelNode &arg) {
+ return QmlItemNode::isValidQmlItemNode(arg) || NodeHints::fromModelNode(arg).visibleInNavigator();
+ }));
+ } else {
+ list = property.toModelNodeList();
+ }
appendForcedNodes(property, list);
diff --git a/src/plugins/qmldesigner/components/propertyeditor/aligndistribute.cpp b/src/plugins/qmldesigner/components/propertyeditor/aligndistribute.cpp
new file mode 100644
index 0000000000..d6ef557388
--- /dev/null
+++ b/src/plugins/qmldesigner/components/propertyeditor/aligndistribute.cpp
@@ -0,0 +1,696 @@
+/****************************************************************************
+**
+** 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 "aligndistribute.h"
+
+#include <nodeabstractproperty.h>
+#include <qmldesignerplugin.h>
+#include <qmlmodelnodeproxy.h>
+
+#include <modelnode.h>
+#include <variantproperty.h>
+
+#include <coreplugin/icore.h>
+
+#include <utils/algorithm.h>
+#include <utils/checkablemessagebox.h>
+#include <utils/qtcassert.h>
+
+#include <cmath>
+
+namespace QmlDesigner {
+
+AlignDistribute::AlignDistribute(QObject *parent)
+ : QObject(parent)
+{}
+
+bool AlignDistribute::multiSelection() const
+{
+ if (!m_qmlObjectNode.isValid())
+ return false;
+
+ return m_qmlObjectNode.view()->selectedModelNodes().count() > 1;
+}
+
+bool AlignDistribute::selectionHasAnchors() const
+{
+ if (!m_qmlObjectNode.isValid())
+ return true;
+
+ const auto selectionContext = SelectionContext(m_qmlObjectNode.view());
+ for (const ModelNode &modelNode : selectionContext.selectedModelNodes()) {
+ QmlItemNode itemNode(modelNode);
+ if (itemNode.instanceHasAnchors())
+ return true;
+ }
+ return false;
+}
+
+bool AlignDistribute::selectionExclusivlyItems() const
+{
+ if (!m_qmlObjectNode.isValid())
+ return false;
+
+ const auto selectionContext = SelectionContext(m_qmlObjectNode.view());
+ for (const ModelNode &modelNode : selectionContext.selectedModelNodes()) {
+ if (!QmlItemNode::isValidQmlItemNode(modelNode))
+ return false;
+ }
+ return true;
+}
+
+bool AlignDistribute::selectionContainsRootItem() const
+{
+ if (!m_qmlObjectNode.isValid())
+ return true;
+
+ const auto selectionContext = SelectionContext(m_qmlObjectNode.view());
+ for (const ModelNode &modelNode : selectionContext.selectedModelNodes()) {
+ QmlItemNode itemNode(modelNode);
+ if (itemNode.isRootNode())
+ return true;
+ }
+ return false;
+}
+
+void AlignDistribute::setModelNodeBackend(const QVariant &modelNodeBackend)
+{
+ auto modelNodeBackendObject = modelNodeBackend.value<QObject *>();
+ const auto backendObjectCasted = qobject_cast<const QmlModelNodeProxy *>(modelNodeBackendObject);
+
+ if (backendObjectCasted)
+ m_qmlObjectNode = backendObjectCasted->qmlObjectNode();
+
+ emit modelNodeBackendChanged();
+}
+
+// The purpose of this function is to suppress the following warning:
+// Warning: Property declaration modelNodeBackendProperty has no READ accessor
+// function or associated MEMBER variable. The property will be invalid.
+QVariant AlignDistribute::getModelNodeBackend() const
+{
+ return {};
+}
+
+void AlignDistribute::registerDeclarativeType()
+{
+ qmlRegisterType<AlignDistribute>("HelperWidgets", 2, 0, "AlignDistribute");
+}
+
+// utility functions
+
+inline qreal width(const QmlItemNode &qmlItemNode)
+{
+ return qmlItemNode.instanceSize().width();
+}
+inline qreal halfWidth(const QmlItemNode &qmlItemNode)
+{
+ return qmlItemNode.instanceSize().width() * 0.5;
+}
+inline qreal height(const QmlItemNode &qmlItemNode)
+{
+ return qmlItemNode.instanceSize().height();
+}
+inline qreal halfHeight(const QmlItemNode &qmlItemNode)
+{
+ return qmlItemNode.instanceSize().height() * 0.5;
+}
+inline qreal left(const QmlItemNode &qmlItemNode)
+{
+ return qmlItemNode.instanceScenePosition().x();
+}
+inline qreal centerHorizontal(const QmlItemNode &qmlItemNode)
+{
+ return qmlItemNode.instanceScenePosition().x() + halfWidth(qmlItemNode);
+}
+inline qreal right(const QmlItemNode &qmlItemNode)
+{
+ return qmlItemNode.instanceScenePosition().x() + width(qmlItemNode);
+}
+inline qreal top(const QmlItemNode &qmlItemNode)
+{
+ return qmlItemNode.instanceScenePosition().y();
+}
+inline qreal centerVertical(const QmlItemNode &qmlItemNode)
+{
+ return qmlItemNode.instanceScenePosition().y() + halfHeight(qmlItemNode);
+}
+inline qreal bottom(const QmlItemNode &qmlItemNode)
+{
+ return qmlItemNode.instanceScenePosition().y() + height(qmlItemNode);
+}
+
+bool compareByLeft(const ModelNode &node1, const ModelNode &node2)
+{
+ const QmlItemNode itemNode1 = QmlItemNode(node1);
+ const QmlItemNode itemNode2 = QmlItemNode(node2);
+ if (itemNode1.isValid() && itemNode2.isValid())
+ return left(itemNode1) < left(itemNode2);
+ return false;
+}
+
+bool compareByCenterH(const ModelNode &node1, const ModelNode &node2)
+{
+ const QmlItemNode itemNode1 = QmlItemNode(node1);
+ const QmlItemNode itemNode2 = QmlItemNode(node2);
+ if (itemNode1.isValid() && itemNode2.isValid())
+ return centerHorizontal(itemNode1) < centerHorizontal(itemNode2);
+ return false;
+}
+
+bool compareByRight(const ModelNode &node1, const ModelNode &node2)
+{
+ const QmlItemNode itemNode1 = QmlItemNode(node1);
+ const QmlItemNode itemNode2 = QmlItemNode(node2);
+ if (itemNode1.isValid() && itemNode2.isValid())
+ return right(itemNode1) < right(itemNode2);
+ return false;
+}
+
+bool compareByTop(const ModelNode &node1, const ModelNode &node2)
+{
+ const QmlItemNode itemNode1 = QmlItemNode(node1);
+ const QmlItemNode itemNode2 = QmlItemNode(node2);
+ if (itemNode1.isValid() && itemNode2.isValid())
+ return top(itemNode1) < top(itemNode2);
+ return false;
+}
+
+bool compareByCenterV(const ModelNode &node1, const ModelNode &node2)
+{
+ const QmlItemNode itemNode1 = QmlItemNode(node1);
+ const QmlItemNode itemNode2 = QmlItemNode(node2);
+ if (itemNode1.isValid() && itemNode2.isValid())
+ return centerVertical(itemNode1) < centerVertical(itemNode2);
+ return false;
+}
+
+bool compareByBottom(const ModelNode &node1, const ModelNode &node2)
+{
+ const QmlItemNode itemNode1 = QmlItemNode(node1);
+ const QmlItemNode itemNode2 = QmlItemNode(node2);
+ if (itemNode1.isValid() && itemNode2.isValid())
+ return bottom(itemNode1) < bottom(itemNode2);
+ return false;
+}
+
+unsigned getDepth(const ModelNode &node)
+{
+ if (node.isRootNode())
+ return 0;
+
+ return 1 + getDepth(node.parentProperty().parentModelNode());
+}
+
+bool compareByDepth(const ModelNode &node1, const ModelNode &node2)
+{
+ if (node1.isValid() && node2.isValid())
+ return getDepth(node1) < getDepth(node2);
+ return false;
+}
+
+static inline QRectF getBoundingRect(const QList<ModelNode> &modelNodeList)
+{
+ QRectF boundingRect;
+ for (const ModelNode &modelNode : modelNodeList) {
+ if (QmlItemNode::isValidQmlItemNode(modelNode)) {
+ const QmlItemNode qmlItemNode(modelNode);
+ boundingRect = boundingRect.united(qmlItemNode.instanceSceneBoundingRect());
+ }
+ }
+ return boundingRect;
+}
+
+static inline QSizeF getSummedSize(const QList<ModelNode> &modelNodeList)
+{
+ QSizeF summedSize = QSizeF(0, 0);
+ for (const ModelNode &modelNode : modelNodeList) {
+ if (QmlItemNode::isValidQmlItemNode(modelNode)) {
+ const QmlItemNode qmlItemNode(modelNode);
+ summedSize += qmlItemNode.instanceSize();
+ }
+ }
+ return summedSize;
+}
+
+static inline qreal getInstanceSceneX(const QmlItemNode &qmlItemNode)
+{
+ const qreal x = qmlItemNode.modelValue("x").toReal();
+ if (qmlItemNode.hasInstanceParentItem())
+ return x + getInstanceSceneX(qmlItemNode.instanceParentItem());
+ return x;
+}
+
+static inline qreal getInstanceSceneY(const QmlItemNode &qmlItemNode)
+{
+ const qreal y = qmlItemNode.modelValue("y").toReal();
+ if (qmlItemNode.hasInstanceParentItem())
+ return y + getInstanceSceneY(qmlItemNode.instanceParentItem());
+ return y;
+}
+
+// utility functions
+
+void AlignDistribute::alignObjects(Target target, AlignTo alignTo, const QString &keyObject)
+{
+ QTC_ASSERT(m_qmlObjectNode.isValid(), return );
+
+ const auto selectionContext = SelectionContext(m_qmlObjectNode.view());
+ if (selectionContext.selectedModelNodes().empty())
+ return;
+
+ AbstractView *view = selectionContext.view();
+ QList<ModelNode> selectedNodes = selectionContext.selectedModelNodes();
+ QRectF boundingRect;
+ QmlItemNode keyObjectQmlItemNode;
+
+ switch (alignTo) {
+ case AlignTo::Selection: {
+ boundingRect = getBoundingRect(selectedNodes);
+ break;
+ }
+ case AlignTo::Root: {
+ const QmlItemNode rootQmlItemNode(selectionContext.view()->rootModelNode());
+ boundingRect = rootQmlItemNode.instanceSceneBoundingRect();
+ break;
+ }
+ case AlignTo::KeyObject: {
+ if (!view->hasId(keyObject))
+ return;
+
+ const auto keyObjectModelNode = view->modelNodeForId(keyObject);
+ keyObjectQmlItemNode = keyObjectModelNode;
+ boundingRect = keyObjectQmlItemNode.instanceSceneBoundingRect();
+ break;
+ }
+ }
+
+ Utils::sort(selectedNodes, compareByDepth);
+
+ const QByteArray operationName = "align" + QVariant::fromValue(target).toByteArray();
+ auto alignPosition =
+ [](Target target, const QRectF &boundingRect, const QmlItemNode &qmlItemNode) {
+ switch (target) {
+ case Target::Left:
+ return boundingRect.left();
+ case Target::CenterH:
+ return boundingRect.center().x() - halfWidth(qmlItemNode);
+ case Target::Right:
+ return boundingRect.right() - width(qmlItemNode);
+ case Target::Top:
+ return boundingRect.top();
+ case Target::CenterV:
+ return boundingRect.center().y() - halfHeight(qmlItemNode);
+ case Target::Bottom:
+ return boundingRect.bottom() - height(qmlItemNode);
+ }
+ return 0.0;
+ };
+
+ view->executeInTransaction("DesignerActionManager|" + operationName, [&]() {
+ for (const ModelNode &modelNode : selectedNodes) {
+ QTC_ASSERT(!modelNode.isRootNode(), continue);
+ if (QmlItemNode::isValidQmlItemNode(modelNode)) {
+ QmlItemNode qmlItemNode(modelNode);
+ qreal myPos;
+ qreal parentPos;
+ QByteArray propertyName;
+ switch (getDimension(target)) {
+ case Dimension::X: {
+ myPos = qmlItemNode.instanceScenePosition().x();
+ parentPos = getInstanceSceneX(qmlItemNode.instanceParentItem());
+ propertyName = "x";
+ break;
+ }
+ case Dimension::Y: {
+ myPos = qmlItemNode.instanceScenePosition().y();
+ parentPos = getInstanceSceneY(qmlItemNode.instanceParentItem());
+ propertyName = "y";
+ break;
+ }
+ }
+ if (alignTo == AlignTo::KeyObject && qmlItemNode == keyObjectQmlItemNode)
+ qmlItemNode.setVariantProperty(propertyName, myPos - parentPos);
+ else
+ qmlItemNode.setVariantProperty(propertyName,
+ qRound(alignPosition(target,
+ boundingRect,
+ qmlItemNode))
+ - parentPos);
+ }
+ }
+ });
+}
+
+void AlignDistribute::distributeObjects(Target target, AlignTo alignTo, const QString &keyObject)
+{
+ QTC_ASSERT(m_qmlObjectNode.isValid(), return );
+
+ const auto selectionContext = SelectionContext(m_qmlObjectNode.view());
+ if (selectionContext.selectedModelNodes().empty())
+ return;
+
+ AbstractView *view = selectionContext.view();
+ QList<ModelNode> selectedNodes = selectionContext.selectedModelNodes();
+ QRectF boundingRect;
+
+ switch (alignTo) {
+ case AlignDistribute::AlignTo::Selection: {
+ boundingRect = getBoundingRect(selectedNodes);
+ break;
+ }
+ case AlignDistribute::AlignTo::Root: {
+ const QmlItemNode rootQmlItemNode(selectionContext.view()->rootModelNode());
+ boundingRect = rootQmlItemNode.instanceSceneBoundingRect();
+ break;
+ }
+ case AlignDistribute::AlignTo::KeyObject: {
+ if (!view->hasId(keyObject))
+ return;
+
+ // Remove key object from selected nodes list and set bounding box according to key object.
+ const auto keyObjectModelNode = view->modelNodeForId(keyObject);
+ selectedNodes.removeOne(keyObjectModelNode);
+ const QmlItemNode keyObjectQmlItemNode(keyObjectModelNode);
+ boundingRect = keyObjectQmlItemNode.instanceSceneBoundingRect();
+ break;
+ }
+ }
+
+ Utils::sort(selectedNodes, getCompareFunction(target));
+
+ auto getMargins = [](Target target, const QList<ModelNode> &nodes) {
+ switch (target) {
+ case Target::Left:
+ return QMarginsF(0, 0, width(QmlItemNode(nodes.last())), 0);
+ case Target::CenterH:
+ return QMarginsF(halfWidth(QmlItemNode(nodes.first())),
+ 0,
+ halfWidth(QmlItemNode(nodes.last())),
+ 0);
+ case Target::Right:
+ return QMarginsF(width(QmlItemNode(nodes.first())), 0, 0, 0);
+ case Target::Top:
+ return QMarginsF(0, 0, 0, height(QmlItemNode(nodes.last())));
+ case Target::CenterV:
+ return QMarginsF(0,
+ halfHeight(QmlItemNode(nodes.first())),
+ 0,
+ halfHeight(QmlItemNode(nodes.last())));
+ case Target::Bottom:
+ return QMarginsF(0, height(QmlItemNode(nodes.first())), 0, 0);
+ }
+ return QMarginsF();
+ };
+
+ boundingRect -= getMargins(target, selectedNodes);
+
+ auto distributePosition = [](Target target, const QmlItemNode &node) {
+ switch (target) {
+ case Target::Left:
+ return 0.0;
+ case Target::CenterH:
+ return halfWidth(node);
+ case Target::Right:
+ return width(node);
+ case Target::Top:
+ return 0.0;
+ case Target::CenterV:
+ return halfHeight(node);
+ case Target::Bottom:
+ return height(node);
+ }
+ return 0.0;
+ };
+
+ QPointF position = boundingRect.topLeft();
+ const qreal equidistant = (getDimension(target) == Dimension::X)
+ ? boundingRect.width() / (selectedNodes.size() - 1)
+ : boundingRect.height() / (selectedNodes.size() - 1);
+ qreal tmp;
+ if (std::modf(equidistant, &tmp) != 0.0) {
+ if (!executePixelPerfectDialog())
+ return;
+ }
+
+ for (const ModelNode &modelNode : selectedNodes) {
+ if (QmlItemNode::isValidQmlItemNode(modelNode)) {
+ QmlItemNode qmlItemNode(modelNode);
+ qreal currentPosition;
+ if (getDimension(target) == Dimension::X) {
+ currentPosition = position.x();
+ position.rx() += equidistant;
+ } else {
+ currentPosition = position.y();
+ position.ry() += equidistant;
+ }
+ modelNode.setAuxiliaryData("tmp",
+ qRound(currentPosition
+ - distributePosition(target, qmlItemNode)));
+ }
+ }
+
+ // Append key object to selected nodes list again. This needs to be done, so relative distribution
+ // will also work on nested item targets. Otherwise change of parents position will move the inner
+ // objects too. To compensate for that, the absolute parent position needs to be substracted.
+ if (alignTo == AlignTo::KeyObject) {
+ if (!view->hasId(keyObject))
+ return;
+
+ const auto keyObjectModelNode = view->modelNodeForId(keyObject);
+ const QmlItemNode keyObjectQmlItemNode(keyObjectModelNode);
+ const auto scenePosition = keyObjectQmlItemNode.instanceScenePosition();
+ keyObjectModelNode.setAuxiliaryData("tmp",
+ (getDimension(target) == Dimension::X
+ ? scenePosition.x()
+ : scenePosition.y()));
+ selectedNodes.append(keyObjectModelNode);
+ }
+
+ Utils::sort(selectedNodes, compareByDepth);
+
+ const QByteArray operationName = "distribute" + QVariant::fromValue(target).toByteArray();
+
+ view->executeInTransaction("DesignerActionManager|" + operationName, [&]() {
+ for (const ModelNode &modelNode : selectedNodes) {
+ QTC_ASSERT(!modelNode.isRootNode(), continue);
+ if (QmlItemNode::isValidQmlItemNode(modelNode)) {
+ QmlItemNode qmlItemNode(modelNode);
+ qreal parentPosition;
+ QByteArray propertyName;
+ switch (getDimension(target)) {
+ case Dimension::X: {
+ parentPosition = getInstanceSceneX(qmlItemNode.instanceParentItem());
+ propertyName = "x";
+ break;
+ }
+ case Dimension::Y: {
+ parentPosition = getInstanceSceneY(qmlItemNode.instanceParentItem());
+ propertyName = "y";
+ break;
+ }
+ }
+ qmlItemNode.setVariantProperty(propertyName,
+ modelNode.auxiliaryData("tmp").toReal()
+ - parentPosition);
+ modelNode.removeAuxiliaryData("tmp");
+ }
+ }
+ });
+}
+
+void AlignDistribute::distributeSpacing(Dimension dimension,
+ AlignTo alignTo,
+ const QString &keyObject,
+ const qreal &distance,
+ DistributeOrigin distributeOrigin)
+{
+ QTC_ASSERT(m_qmlObjectNode.isValid(), return );
+
+ const auto selectionContext = SelectionContext(m_qmlObjectNode.view());
+ if (selectionContext.selectedModelNodes().empty())
+ return;
+
+ AbstractView *view = selectionContext.view();
+ QList<ModelNode> selectedNodes = selectionContext.selectedModelNodes();
+ QRectF boundingRect;
+
+ switch (alignTo) {
+ case AlignDistribute::AlignTo::Selection: {
+ boundingRect = getBoundingRect(selectedNodes);
+ break;
+ }
+ case AlignDistribute::AlignTo::Root: {
+ const QmlItemNode rootQmlItemNode(selectionContext.view()->rootModelNode());
+ boundingRect = rootQmlItemNode.instanceSceneBoundingRect();
+ break;
+ }
+ case AlignDistribute::AlignTo::KeyObject: {
+ if (!view->hasId(keyObject))
+ return;
+
+ // Remove key object from selected nodes list and set bounding box according to key object.
+ const auto keyObjectModelNode = view->modelNodeForId(keyObject);
+ selectedNodes.removeOne(keyObjectModelNode);
+ const QmlItemNode keyObjectQmlItemNode(keyObjectModelNode);
+ boundingRect = keyObjectQmlItemNode.instanceSceneBoundingRect();
+ break;
+ }
+ }
+
+ Utils::sort(selectedNodes, (dimension == Dimension::X) ? compareByCenterH : compareByCenterV);
+
+ // Calculate the space between the items and set a proper start position for the different
+ // distribution directions/origins.
+ QPointF position = boundingRect.topLeft();
+ const QSizeF summedSize = getSummedSize(selectedNodes);
+ qreal equidistant = distance;
+
+ if (distributeOrigin == DistributeOrigin::None) {
+ const qreal lengthDifference = (dimension == Dimension::X)
+ ? (boundingRect.width() - summedSize.width())
+ : (boundingRect.height() - summedSize.height());
+ equidistant = lengthDifference / (selectedNodes.size() - 1);
+ qreal tmp;
+ if (std::modf(equidistant, &tmp) != 0.0) {
+ if (!executePixelPerfectDialog())
+ return;
+ }
+ } else if (distributeOrigin == DistributeOrigin::Center
+ || distributeOrigin == DistributeOrigin::BottomRight) {
+ const qreal multiplier = (distributeOrigin == DistributeOrigin::Center) ? 0.5 : 1.0;
+ if (dimension == Dimension::X) {
+ const qreal totalLength = summedSize.width() + (distance * (selectedNodes.size() - 1));
+ position.rx() -= (totalLength - boundingRect.width()) * multiplier;
+ } else {
+ const qreal totalLength = summedSize.height() + (distance * (selectedNodes.size() - 1));
+ position.ry() -= (totalLength - boundingRect.height()) * multiplier;
+ }
+ }
+
+ for (const ModelNode &modelNode : selectedNodes) {
+ if (QmlItemNode::isValidQmlItemNode(modelNode)) {
+ const QmlItemNode qmlItemNode(modelNode);
+ qreal currentPosition;
+ if (dimension == Dimension::X) {
+ currentPosition = position.x();
+ position.rx() += width(qmlItemNode) + equidistant;
+ } else {
+ currentPosition = position.y();
+ position.ry() += height(qmlItemNode) + equidistant;
+ }
+ modelNode.setAuxiliaryData("tmp", qRound(currentPosition));
+ }
+ }
+
+ // Append key object to selected nodes list again. This needs to be done, so relative distribution
+ // will also work on nested item targets. Otherwise change of parents position will move the inner
+ // objects too. To compensate for that, the absolute parent position needs to be substracted.
+ if (alignTo == AlignTo::KeyObject) {
+ if (!view->hasId(keyObject))
+ return;
+
+ const auto keyObjectModelNode = view->modelNodeForId(keyObject);
+ const QmlItemNode keyObjectQmlItemNode(keyObjectModelNode);
+ const auto scenePosition = keyObjectQmlItemNode.instanceScenePosition();
+ keyObjectModelNode.setAuxiliaryData("tmp",
+ (dimension == Dimension::X ? scenePosition.x()
+ : scenePosition.y()));
+ selectedNodes.append(keyObjectModelNode);
+ }
+
+ Utils::sort(selectedNodes, compareByDepth);
+
+ const QByteArray operationName = (dimension == Dimension::X) ? "distributeSpacingHorizontal"
+ : "distributeSpacingVertical";
+
+ view->executeInTransaction("DesignerActionManager|" + operationName, [&]() {
+ for (const ModelNode &modelNode : selectedNodes) {
+ QTC_ASSERT(!modelNode.isRootNode(), continue);
+ if (QmlItemNode::isValidQmlItemNode(modelNode)) {
+ QmlItemNode qmlItemNode(modelNode);
+ qreal parentPos;
+ QByteArray propertyName;
+ switch (dimension) {
+ case Dimension::X: {
+ parentPos = getInstanceSceneX(qmlItemNode.instanceParentItem());
+ propertyName = "x";
+ break;
+ }
+ case Dimension::Y: {
+ parentPos = getInstanceSceneY(qmlItemNode.instanceParentItem());
+ propertyName = "y";
+ break;
+ }
+ }
+ qmlItemNode.setVariantProperty(propertyName,
+ modelNode.auxiliaryData("tmp").toReal() - parentPos);
+ modelNode.removeAuxiliaryData("tmp");
+ }
+ }
+ });
+}
+
+AlignDistribute::CompareFunction AlignDistribute::getCompareFunction(Target target) const
+{
+ static const std::map<Target, CompareFunction> cmpMap = {{Target::Left, compareByLeft},
+ {Target::CenterH, compareByCenterH},
+ {Target::Right, compareByRight},
+ {Target::Top, compareByTop},
+ {Target::CenterV, compareByCenterV},
+ {Target::Bottom, compareByBottom}};
+ return cmpMap.at(target);
+}
+
+AlignDistribute::Dimension AlignDistribute::getDimension(Target target) const
+{
+ switch (target) {
+ case Target::Left:
+ case Target::CenterH:
+ case Target::Right: {
+ return Dimension::X;
+ }
+ case Target::Top:
+ case Target::CenterV:
+ case Target::Bottom: {
+ return Dimension::Y;
+ }
+ }
+ return Dimension::X;
+}
+
+bool AlignDistribute::executePixelPerfectDialog() const
+{
+ QDialogButtonBox::StandardButton pressed = Utils::CheckableMessageBox::doNotAskAgainQuestion(
+ Core::ICore::dialogParent(),
+ tr("Cannot distribute perfectly"),
+ tr("These objects cannot be distributed to equal pixel values. "
+ "Do you want to distribute to the nearest possible values?"),
+ Core::ICore::settings(),
+ "WarnAboutPixelPerfectDistribution");
+ return (pressed == QDialogButtonBox::Yes) ? true : false;
+}
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/propertyeditor/aligndistribute.h b/src/plugins/qmldesigner/components/propertyeditor/aligndistribute.h
new file mode 100644
index 0000000000..1b2714f750
--- /dev/null
+++ b/src/plugins/qmldesigner/components/propertyeditor/aligndistribute.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** 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 ALIGNDISTRIBUTE_H
+#define ALIGNDISTRIBUTE_H
+
+#include <QtQml>
+
+#include <selectioncontext.h>
+#include <qmlitemnode.h>
+
+namespace QmlDesigner {
+
+class AlignDistribute : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool multiSelection READ multiSelection NOTIFY modelNodeBackendChanged)
+ Q_PROPERTY(bool selectionHasAnchors READ selectionHasAnchors NOTIFY modelNodeBackendChanged)
+ Q_PROPERTY(
+ bool selectionExclusivlyItems READ selectionExclusivlyItems NOTIFY modelNodeBackendChanged)
+ Q_PROPERTY(bool selectionContainsRootItem READ selectionContainsRootItem NOTIFY
+ modelNodeBackendChanged)
+
+ Q_PROPERTY(QVariant modelNodeBackendProperty READ getModelNodeBackend WRITE setModelNodeBackend
+ NOTIFY modelNodeBackendChanged)
+
+public:
+ explicit AlignDistribute(QObject *parent = nullptr);
+
+ enum AlignTo { Selection, Root, KeyObject };
+ Q_ENUM(AlignTo)
+
+ enum DistributeOrigin { None, TopLeft, Center, BottomRight };
+ Q_ENUM(DistributeOrigin)
+
+ enum Dimension { X, Y };
+ Q_ENUM(Dimension)
+
+ enum Target { Left, CenterH, Right, Top, CenterV, Bottom };
+ Q_ENUM(Target)
+
+ bool multiSelection() const;
+ bool selectionHasAnchors() const;
+ bool selectionExclusivlyItems() const;
+ bool selectionContainsRootItem() const;
+
+ void setModelNodeBackend(const QVariant &modelNodeBackend);
+ QVariant getModelNodeBackend() const;
+
+ static void registerDeclarativeType();
+
+ Q_INVOKABLE void alignObjects(Target target, AlignTo alignTo, const QString &keyObject);
+ Q_INVOKABLE void distributeObjects(Target target, AlignTo alignTo, const QString &keyObject);
+ Q_INVOKABLE void distributeSpacing(Dimension dimension,
+ AlignTo alignTo,
+ const QString &keyObject,
+ const qreal &distance,
+ DistributeOrigin distributeOrigin);
+
+signals:
+ void modelNodeBackendChanged();
+
+private:
+ using CompareFunction = std::function<bool(const ModelNode &, const ModelNode &)>;
+
+ CompareFunction getCompareFunction(Target target) const;
+ Dimension getDimension(Target target) const;
+ bool executePixelPerfectDialog() const;
+
+ QmlObjectNode m_qmlObjectNode;
+};
+
+} // namespace QmlDesigner
+
+QML_DECLARE_TYPE(QmlDesigner::AlignDistribute)
+
+#endif //ALIGNDISTRIBUTE_H
diff --git a/src/plugins/qmldesigner/components/propertyeditor/itemfiltermodel.cpp b/src/plugins/qmldesigner/components/propertyeditor/itemfiltermodel.cpp
index fab5366e6d..fab8cde66e 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/itemfiltermodel.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/itemfiltermodel.cpp
@@ -34,7 +34,7 @@
#include <qmlmodelnodeproxy.h>
ItemFilterModel::ItemFilterModel(QObject *parent) :
- QObject(parent), m_typeFilter("QtQuick.Item"), m_lock(false)
+ QObject(parent), m_typeFilter("QtQuick.Item"), m_lock(false), m_selectionOnly(false)
{
}
@@ -61,11 +61,24 @@ void ItemFilterModel::setTypeFilter(const QString &filter)
}
}
+void ItemFilterModel::setSelectionOnly(bool value)
+{
+ if (m_selectionOnly != value) {
+ m_selectionOnly = value;
+ setupModel();
+ }
+}
+
QString ItemFilterModel::typeFilter() const
{
return m_typeFilter;
}
+bool ItemFilterModel::selectionOnly() const
+{
+ return m_selectionOnly;
+}
+
void ItemFilterModel::registerDeclarativeType()
{
qmlRegisterType<ItemFilterModel>("HelperWidgets",2,0,"ItemFilterModel");
@@ -85,7 +98,9 @@ void ItemFilterModel::setupModel()
m_lock = true;
m_model.clear();
- for (const QmlDesigner::ModelNode &node : m_modelNode.view()->allModelNodes()) {
+ const auto nodes = m_selectionOnly ? m_modelNode.view()->selectedModelNodes() : m_modelNode.view()->allModelNodes();
+
+ for (const QmlDesigner::ModelNode &node : nodes) {
if (node.hasId() && node.metaInfo().isValid() && node.metaInfo().isSubclassOf(m_typeFilter.toUtf8()))
m_model.append(node.id());
}
diff --git a/src/plugins/qmldesigner/components/propertyeditor/itemfiltermodel.h b/src/plugins/qmldesigner/components/propertyeditor/itemfiltermodel.h
index 032bd2baff..a26cacc685 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/itemfiltermodel.h
+++ b/src/plugins/qmldesigner/components/propertyeditor/itemfiltermodel.h
@@ -40,13 +40,16 @@ class ItemFilterModel : public QObject
Q_PROPERTY(QString typeFilter READ typeFilter WRITE setTypeFilter)
Q_PROPERTY(QVariant modelNodeBackendProperty READ modelNodeBackend WRITE setModelNodeBackend NOTIFY modelNodeBackendChanged)
Q_PROPERTY(QStringList itemModel READ itemModel NOTIFY itemModelChanged)
+ Q_PROPERTY(bool selectionOnly READ selectionOnly WRITE setSelectionOnly NOTIFY selectionOnlyChanged)
public:
explicit ItemFilterModel(QObject *parent = nullptr);
void setModelNodeBackend(const QVariant &modelNodeBackend);
void setTypeFilter(const QString &typeFilter);
+ void setSelectionOnly(bool value);
QString typeFilter() const;
+ bool selectionOnly() const;
void setupModel();
QStringList itemModel() const;
@@ -55,6 +58,7 @@ public:
signals:
void modelNodeBackendChanged();
void itemModelChanged();
+ void selectionOnlyChanged();
private:
QVariant modelNodeBackend() const;
@@ -64,6 +68,7 @@ private:
bool m_lock;
QStringList m_model;
QmlDesigner::ModelNode m_modelNode;
+ bool m_selectionOnly;
};
QML_DECLARE_TYPE(ItemFilterModel)
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.pri b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.pri
index 0777202db4..1fb9a3981f 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.pri
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.pri
@@ -19,7 +19,8 @@ SOURCES += propertyeditorview.cpp \
simplecolorpalette.cpp \
simplecolorpalettemodel.cpp \
simplecolorpalettesingleton.cpp \
- itemfiltermodel.cpp
+ itemfiltermodel.cpp \
+ aligndistribute.cpp
HEADERS += propertyeditorview.h \
qmlanchorbindingproxy.h \
@@ -40,6 +41,7 @@ HEADERS += propertyeditorview.h \
simplecolorpalette.h \
simplecolorpalettemodel.h \
simplecolorpalettesingleton.h \
- itemfiltermodel.h
+ itemfiltermodel.h \
+ aligndistribute.h
QT += qml quick
diff --git a/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp
index 7ff25cad8e..3987435802 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp
@@ -35,6 +35,7 @@
#include "bindingeditor/bindingeditor.h"
#include "qmlanchorbindingproxy.h"
#include "theme.h"
+#include "aligndistribute.h"
namespace QmlDesigner {
@@ -59,6 +60,7 @@ void Quick2PropertyEditorView::registerQmlTypes()
SimpleColorPaletteModel::registerDeclarativeType();
Internal::QmlAnchorBindingProxy::registerDeclarativeType();
BindingEditor::registerDeclarativeType();
+ AlignDistribute::registerDeclarativeType();
}
}
diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinetoolbar.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinetoolbar.cpp
index 8ad8499d17..a233e19aad 100644
--- a/src/plugins/qmldesigner/components/timelineeditor/timelinetoolbar.cpp
+++ b/src/plugins/qmldesigner/components/timelineeditor/timelinetoolbar.cpp
@@ -272,7 +272,7 @@ void TimelineToolBar::createLeftControls()
auto *curveEditorAction = createAction(TimelineConstants::C_CURVE_EDITOR,
TimelineIcons::CURVE_EDITORDIALOG.icon(),
- tr("Curve Editor"),
+ tr("Animation Curve Editor"),
QKeySequence(Qt::Key_C));
connect(curveEditorAction,
@@ -396,10 +396,10 @@ void TimelineToolBar::createCenterControls()
auto *curvePicker = createAction(TimelineConstants::C_CURVE_PICKER,
TimelineIcons::CURVE_EDITOR.icon(),
- tr("Curve Picker"),
+ tr("Easing Curve Editor"),
QKeySequence(Qt::Key_C));
- curvePicker->setObjectName("Curve Picker");
+ curvePicker->setObjectName("Easing Curve Editor");
connect(curvePicker, &QAction::triggered, this, &TimelineToolBar::openEasingCurveEditor);
addAction(curvePicker);
diff --git a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h
index 2d19cf6b95..ba2f6b283c 100644
--- a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h
+++ b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h
@@ -46,7 +46,7 @@ class Target;
namespace QmlDesigner {
-class NodeInstanceServerInterface;
+class NodeInstanceServerProxy;
class CreateSceneCommand;
class CreateInstancesCommand;
class ClearSceneCommand;
@@ -195,7 +195,7 @@ private: //variables
QHash<ModelNode, NodeInstance> m_nodeInstanceHash;
QHash<ModelNode, QImage> m_statePreviewImage;
- QPointer<NodeInstanceServerInterface> m_nodeInstanceServer;
+ QPointer<NodeInstanceServerProxy> m_nodeInstanceServer;
QImage m_baseStatePreviewImage;
QElapsedTimer m_lastCrashTime;
NodeInstanceServerInterface::RunModus m_runModus;
diff --git a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h b/src/plugins/qmldesigner/designercore/include/qmlitemnode.h
index 88afc72cb1..0c6693f505 100644
--- a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h
+++ b/src/plugins/qmldesigner/designercore/include/qmlitemnode.h
@@ -98,6 +98,7 @@ public:
bool modelIsInLayout() const;
QRectF instanceBoundingRect() const;
+ QRectF instanceSceneBoundingRect() const;
QRectF instancePaintedBoundingRect() const;
QRectF instanceContentItemBoundingRect() const;
QTransform instanceTransform() const;
diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp
index c51b40f728..899dc5caee 100644
--- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp
+++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp
@@ -1074,11 +1074,14 @@ ChangeValuesCommand NodeInstanceView::createChangeValueCommand(const QList<Varia
{
QVector<PropertyValueContainer> containerList;
+ const bool reflectionFlag = m_puppetTransaction.isValid();
+
foreach (const VariantProperty &property, propertyList) {
ModelNode node = property.parentModelNode();
if (node.isValid() && hasInstanceForModelNode(node)) {
NodeInstance instance = instanceForModelNode(node);
PropertyValueContainer container(instance.instanceId(), property.name(), property.value(), property.dynamicTypeName());
+ container.setReflectionFlag(reflectionFlag);
containerList.append(container);
}
@@ -1222,8 +1225,6 @@ void NodeInstanceView::valuesModified(const ValuesModifiedCommand &command)
if (command.transactionOption == ValuesModifiedCommand::TransactionOption::Start)
startPuppetTransaction();
- else if (command.transactionOption == ValuesModifiedCommand::TransactionOption::End)
- endPuppetTransaction();
for (const PropertyValueContainer &container : command.valueChanges()) {
if (hasInstanceForId(container.instanceId())) {
@@ -1236,6 +1237,9 @@ void NodeInstanceView::valuesModified(const ValuesModifiedCommand &command)
}
}
}
+
+ if (command.transactionOption == ValuesModifiedCommand::TransactionOption::End)
+ endPuppetTransaction();
}
void NodeInstanceView::pixmapChanged(const PixmapChangedCommand &command)
diff --git a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp
index 0b33aa655a..2fc530ff10 100644
--- a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp
+++ b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp
@@ -384,6 +384,11 @@ QRectF QmlItemNode::instanceBoundingRect() const
return QRectF(QPointF(0, 0), nodeInstance().size());
}
+QRectF QmlItemNode::instanceSceneBoundingRect() const
+{
+ return QRectF(instanceScenePosition(), nodeInstance().size());
+}
+
QRectF QmlItemNode::instancePaintedBoundingRect() const
{
return nodeInstance().boundingRect();
diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp
index 69bc9ff0f9..a05c3b674a 100644
--- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp
+++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp
@@ -355,11 +355,14 @@ bool compareJavaScriptExpression(const QString &expression1, const QString &expr
}
bool smartVeryFuzzyCompare(const QVariant &value1, const QVariant &value2)
-{ //we ignore slight changes on doubles and only check three digits
- if ((value1.type() == QMetaType::Double)
- || (value2.type() == QMetaType::Double)
- || (value1.type() == QMetaType::Float)
- || (value2.type() == QMetaType::Float)) {
+{
+ //we ignore slight changes on doubles and only check three digits
+ const auto type1 = static_cast<QMetaType::Type>(value1.type());
+ const auto type2 = static_cast<QMetaType::Type>(value2.type());
+ if (type1 == QMetaType::Double
+ || type2 == QMetaType::Double
+ || type1 == QMetaType::Float
+ || type2 == QMetaType::Float) {
bool ok1, ok2;
qreal a = value1.toDouble(&ok1);
qreal b = value2.toDouble(&ok2);
diff --git a/src/plugins/qmldesigner/designersettings.cpp b/src/plugins/qmldesigner/designersettings.cpp
index 5870927d52..f1afe3cf66 100644
--- a/src/plugins/qmldesigner/designersettings.cpp
+++ b/src/plugins/qmldesigner/designersettings.cpp
@@ -77,6 +77,7 @@ void DesignerSettings::fromSettings(QSettings *settings)
restoreValue(settings, DesignerSettingsKey::STANDALONE_MODE, false);
restoreValue(settings, DesignerSettingsKey::ENABLE_TIMELINEVIEW, false);
restoreValue(settings, DesignerSettingsKey::SIMPLE_COLOR_PALETTE_CONTENT, QStringList());
+ restoreValue(settings, DesignerSettingsKey::ALWAYS_DESIGN_MODE, true);
settings->endGroup();
settings->endGroup();
diff --git a/src/plugins/qmldesigner/designersettings.h b/src/plugins/qmldesigner/designersettings.h
index 410abc267e..ec4dc1f7e5 100644
--- a/src/plugins/qmldesigner/designersettings.h
+++ b/src/plugins/qmldesigner/designersettings.h
@@ -66,6 +66,7 @@ const char IGNORE_DEVICE_PIXEL_RATIO[] = "IgnoreDevicePixelRaio"; /* The setting
const char STANDALONE_MODE[] = "StandAloneMode";
const char ENABLE_TIMELINEVIEW[] = "EnableTimelineView";
const char SIMPLE_COLOR_PALETTE_CONTENT[] = "SimpleColorPaletteContent";
+const char ALWAYS_DESIGN_MODE[] = "AlwaysDesignMode";
}
class DesignerSettings : public QHash<QByteArray, QVariant>
diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp
index 3ce4512fe1..2dbf40a7bb 100644
--- a/src/plugins/qmldesigner/qmldesignerplugin.cpp
+++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp
@@ -96,7 +96,9 @@ QtQuickDesignerFactory::QtQuickDesignerFactory()
addMimeType(QmlJSTools::Constants::QMLUI_MIMETYPE);
setDocumentCreator([this]() {
auto document = new QmlJSEditor::QmlJSEditorDocument(id());
- document->setIsDesignModePreferred(true);
+ document->setIsDesignModePreferred(
+ QmlDesigner::DesignerSettings::getValue(
+ QmlDesigner::DesignerSettingsKey::ALWAYS_DESIGN_MODE).toBool());
return document;
});
}
diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs
index 0d7b54c68e..f2fdd76598 100644
--- a/src/plugins/qmldesigner/qmldesignerplugin.qbs
+++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs
@@ -568,6 +568,8 @@ Project {
"navigator/navigatorview.h",
"navigator/navigatorwidget.cpp",
"navigator/navigatorwidget.h",
+ "propertyeditor/aligndistribute.cpp",
+ "propertyeditor/aligndistribute.h",
"propertyeditor/designerpropertymap.cpp",
"propertyeditor/designerpropertymap.h",
"propertyeditor/fileresourcesmodel.cpp",
diff --git a/src/plugins/qmldesigner/settingspage.cpp b/src/plugins/qmldesigner/settingspage.cpp
index a7d6bc2bb0..6cfc1ebf45 100644
--- a/src/plugins/qmldesigner/settingspage.cpp
+++ b/src/plugins/qmldesigner/settingspage.cpp
@@ -161,6 +161,8 @@ DesignerSettings SettingsPageWidget::settings() const
m_ui.showWarnExceptionsCheckBox->isChecked());
settings.insert(DesignerSettingsKey::ENABLE_TIMELINEVIEW,
m_ui.featureTimelineEditorCheckBox->isChecked());
+ settings.insert(DesignerSettingsKey::ALWAYS_DESIGN_MODE,
+ m_ui.designerAlwaysDesignModeCheckBox->isChecked());
return settings;
}
@@ -226,13 +228,15 @@ void SettingsPageWidget::setSettings(const DesignerSettings &settings)
m_ui.controls2StyleComboBox->setCurrentText(m_ui.styleLineEdit->text());
+ m_ui.designerAlwaysDesignModeCheckBox->setChecked(settings.value(
+ DesignerSettingsKey::ALWAYS_DESIGN_MODE).toBool());
m_ui.featureTimelineEditorCheckBox->setChecked(settings.value(
DesignerSettingsKey::ENABLE_TIMELINEVIEW).toBool());
if (settings.value(DesignerSettingsKey::STANDALONE_MODE).toBool()) {
m_ui.emulationGroupBox->hide();
m_ui.debugGroupBox->hide();
- m_ui.featuresGroupBox->hide();
+ m_ui.featureTimelineEditorCheckBox->hide();
}
}
diff --git a/src/plugins/qmldesigner/settingspage.ui b/src/plugins/qmldesigner/settingspage.ui
index 7da62b300a..dabe3df734 100644
--- a/src/plugins/qmldesigner/settingspage.ui
+++ b/src/plugins/qmldesigner/settingspage.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>685</width>
- <height>555</height>
+ <width>960</width>
+ <height>840</height>
</rect>
</property>
<property name="windowTitle">
@@ -415,14 +415,21 @@
<property name="title">
<string>Features</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_5">
- <item>
+ <layout class="QGridLayout" name="gridLayout_6">
+ <item row="0" column="1">
<widget class="QCheckBox" name="featureTimelineEditorCheckBox">
<property name="text">
<string>Enable Timeline editor</string>
</property>
</widget>
</item>
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="designerAlwaysDesignModeCheckBox">
+ <property name="text">
+ <string>Always open ui.qml files in Design mode</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/src/plugins/updateinfo/updateinfoplugin.cpp b/src/plugins/updateinfo/updateinfoplugin.cpp
index 4644823ed5..c602136ef2 100644
--- a/src/plugins/updateinfo/updateinfoplugin.cpp
+++ b/src/plugins/updateinfo/updateinfoplugin.cpp
@@ -193,7 +193,7 @@ void UpdateInfoPlugin::checkForUpdatesFinished()
d->m_progress->setKeepOnFinish(FutureProgress::HideOnFinish);
emit newUpdatesAvailable(true);
Core::InfoBarEntry info(InstallUpdates,
- tr("New updates are available. Do you want to start the update?"));
+ tr("New updates are available. Start the update?"));
info.setCustomButtonInfo(tr("Start Update"), [this] {
Core::ICore::infoBar()->removeInfo(InstallUpdates);
startUpdater();
@@ -202,7 +202,7 @@ void UpdateInfoPlugin::checkForUpdatesFinished()
info.setDetailsWidgetCreator([updates]() -> QWidget * {
const QString updateText = updates.join("</li><li>");
auto label = new QLabel;
- label->setText("<qt><p>" + tr("Available Updates:") + "<ul><li>" + updateText
+ label->setText("<qt><p>" + tr("Available updates:") + "<ul><li>" + updateText
+ "</li></ul></p></qt>");
label->setContentsMargins(0, 0, 0, 8);
return label;
diff --git a/src/tools/qtcdebugger/CMakeLists.txt b/src/tools/qtcdebugger/CMakeLists.txt
index af367a60b3..ff550d8910 100644
--- a/src/tools/qtcdebugger/CMakeLists.txt
+++ b/src/tools/qtcdebugger/CMakeLists.txt
@@ -3,7 +3,7 @@ if (NOT WIN32)
endif()
add_qtc_executable(qtcdebugger
- DEPENDS Qt5::Widgets registryaccess psapi
+ DEPENDS Qt5::Widgets registryaccess psapi app_version
SOURCES
main.cpp
PROPERTIES WIN32_EXECUTABLE ON
diff --git a/tests/system/objects.map b/tests/system/objects.map
index 27e82838e7..407acfb5cd 100644
--- a/tests/system/objects.map
+++ b/tests/system/objects.map
@@ -158,7 +158,7 @@
:Qt Creator_Issues_Core::Internal::OutputPaneToggleButton {occurrence='1' type='Core::Internal::OutputPaneToggleButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_QHelpContentWidget {type='Utils::NavigationTreeView' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_QmlJSEditor::Internal::QmlJSOutlineTreeView {type='QmlJSEditor::Internal::QmlJSOutlineTreeView' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
-:Qt Creator_QmlJSEditor::QmlJSTextEditorWidget {type='QmlJSEditor::Internal::QmlJSEditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
+:Qt Creator_QmlJSEditor::QmlJSTextEditorWidget {type='QmlJSEditor::QmlJSEditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_SearchResult_Core::Internal::OutputPaneToggleButton {occurrence='2' type='Core::Internal::OutputPaneToggleButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_TextEditor::TextEditorWidget {type='TextEditor::TextEditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_Utils::BuildDirectoryLineEdit {name='LineEdit' type='Utils::FancyLineEdit' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
diff --git a/tests/system/shared/build_utils.py b/tests/system/shared/build_utils.py
index b27000701e..db1b11c6c4 100644
--- a/tests/system/shared/build_utils.py
+++ b/tests/system/shared/build_utils.py
@@ -225,7 +225,6 @@ def runVerify():
test.fatal("Haven't found build configurations, quitting")
invokeMenuItem("File", "Save All")
invokeMenuItem("File", "Exit")
- # select debug configuration
for kit, config in availableConfigs:
selectBuildConfig(kit, config)
test.log("Using build config '%s'" % config)
diff --git a/tests/system/suite_general/tst_create_proj_wizard/test.py b/tests/system/suite_general/tst_create_proj_wizard/test.py
index 1d822c7ca5..69d1c4de4d 100644
--- a/tests/system/suite_general/tst_create_proj_wizard/test.py
+++ b/tests/system/suite_general/tst_create_proj_wizard/test.py
@@ -62,7 +62,8 @@ def main():
template = template.replace(".", "\\.")
# skip non-configurable
if template not in ["Qt Quick UI Prototype", "Auto Test Project", # FIXME
- "Qt for Python - Empty", "Qt for Python - Window"]:
+ "Qt for Python - Empty", "Qt for Python - Window",
+ "Qt Quick 2 Extension Plugin"]:
availableProjectTypes.append({category:template})
safeClickButton("Cancel")
for current in availableProjectTypes: