diff --git a/.clang-format b/.clang-format
index 0a0df0c152d..c433c9809ef 100644
--- a/.clang-format
+++ b/.clang-format
@@ -79,6 +79,7 @@ IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
+InsertBraces: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
diff --git a/.gitignore b/.gitignore
index de76458a885..bb073b45dc2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -280,7 +280,6 @@ tmp/
/tests/manual/ssh/shell/shell
/tests/tools/qml-ast2dot/qml-ast2dot
/tests/unit/echoserver/echo
-/tests/unit/unittest/unittest
# qbs builds
/*-debug/
diff --git a/.gitmodules b/.gitmodules
index 428e75ff118..45d62de0644 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -6,9 +6,9 @@
path = src/tools/perfparser
url = ../perfparser.git
ignore = dirty
-[submodule "googletest"]
- path = tests/unit/unittest/3rdparty/googletest
- url = https://github.com/google/googletest.git
[submodule "src/libs/qlitehtml"]
path = src/libs/qlitehtml
url = https://code.qt.io/playground/qlitehtml.git
+[submodule "googletest"]
+ path = src/libs/3rdparty/googletest
+ url = https://github.com/google/googletest.git
diff --git a/cmake/FindGoogletest.cmake b/cmake/FindGoogletest.cmake
deleted file mode 100644
index e3bd22ba217..00000000000
--- a/cmake/FindGoogletest.cmake
+++ /dev/null
@@ -1,116 +0,0 @@
-#.rst:
-# FindGoogletest
-# -----------------
-#
-# Try to locate the Googletest source files, and then build them as a
-# static library.
-#
-# The ``GOOGLETEST_DIR`` (CMake or Environment) variable should be used
-# to pinpoint the Googletest source files.
-#
-# If found, this will define the following variables:
-#
-# ``Googletest_FOUND``
-# True if the Googletest source package has been found.
-#
-# ``Googletest``
-# Target compiled as static library.
-#
-
-find_path(GOOGLE_TEST_INCLUDE_DIR
- NAMES gtest/gtest.h
- PATH_SUFFIXES googletest/include
- HINTS
- "${GOOGLETEST_DIR}" ENV GOOGLETEST_DIR
- "${PROJECT_SOURCE_DIR}/googletest"
- "${PROJECT_SOURCE_DIR}/../googletest"
- "${PROJECT_SOURCE_DIR}/../../googletest"
- "${PROJECT_SOURCE_DIR}/tests/unit/unittest/3rdparty/googletest"
-)
-
-find_path(GOOGLE_TEST_SRC_ALL
- NAMES gtest-all.cc
- PATH_SUFFIXES googletest/src
- HINTS
- "${GOOGLETEST_DIR}" ENV GOOGLETEST_DIR
- "${PROJECT_SOURCE_DIR}/googletest"
- "${PROJECT_SOURCE_DIR}/../googletest"
- "${PROJECT_SOURCE_DIR}/../../googletest"
- "${PROJECT_SOURCE_DIR}/tests/unit/unittest/3rdparty/googletest"
-)
-
-
-find_path(GOOGLE_MOCK_INCLUDE_DIR
- NAMES gmock/gmock.h
- PATH_SUFFIXES googlemock/include
- HINTS
- "${GOOGLETEST_DIR}" ENV GOOGLETEST_DIR
- "${PROJECT_SOURCE_DIR}/googletest"
- "${PROJECT_SOURCE_DIR}/../googletest"
- "${PROJECT_SOURCE_DIR}/../../googletest"
- "${PROJECT_SOURCE_DIR}/tests/unit/unittest/3rdparty/googletest"
-)
-
-find_path(GOOGLE_MOCK_SRC_ALL
- NAMES gmock-all.cc
- PATH_SUFFIXES googlemock/src
- HINTS
- "${GOOGLETEST_DIR}" ENV GOOGLETEST_DIR
- "${PROJECT_SOURCE_DIR}/googletest"
- "${PROJECT_SOURCE_DIR}/../googletest"
- "${PROJECT_SOURCE_DIR}/../../googletest"
- "${PROJECT_SOURCE_DIR}/tests/unit/unittest/3rdparty/googletest"
-)
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(Googletest
- DEFAULT_MSG
- GOOGLE_TEST_INCLUDE_DIR GOOGLE_MOCK_INCLUDE_DIR
- GOOGLE_TEST_SRC_ALL GOOGLE_MOCK_SRC_ALL
-)
-find_package(Threads REQUIRED)
-
-if(Googletest_FOUND AND NOT TARGET Googletest)
- add_library(Googletest STATIC
- "${GOOGLE_TEST_SRC_ALL}/gtest-all.cc"
- "${GOOGLE_MOCK_SRC_ALL}/gmock-all.cc"
- )
- target_include_directories(Googletest
- PUBLIC
- "${GOOGLE_TEST_INCLUDE_DIR}"
- "${GOOGLE_MOCK_INCLUDE_DIR}"
- PRIVATE
- "${GOOGLE_TEST_SRC_ALL}/.."
- "${GOOGLE_MOCK_SRC_ALL}/.."
- )
- target_compile_definitions(Googletest
- PRIVATE
- GTEST_HAS_STD_INITIALIZER_LIST_
- GTEST_LANG_CXX11
- GTEST_HAS_STD_TUPLE_
- GTEST_HAS_STD_TYPE_TRAITS_
- GTEST_HAS_STD_FUNCTION_
- GTEST_HAS_RTTI
- GTEST_HAS_STD_BEGIN_AND_END_
- GTEST_HAS_STD_UNIQUE_PTR_
- GTEST_HAS_EXCEPTIONS
- GTEST_HAS_STREAM_REDIRECTION
- GTEST_HAS_TYPED_TEST
- GTEST_HAS_TYPED_TEST_P
- GTEST_HAS_PARAM_TEST
- GTEST_HAS_DEATH_TEST
- )
- set_target_properties(Googletest PROPERTIES AUTOMOC OFF AUTOUIC OFF QT_COMPILE_OPTIONS_DISABLE_WARNINGS ON)
- set_property(TARGET Googletest PROPERTY POSITION_INDEPENDENT_CODE ON)
- target_compile_definitions(Googletest PUBLIC GOOGLE_TEST_IS_FOUND)
-
- target_link_libraries(Googletest Threads::Threads)
-endif()
-
-mark_as_advanced(GOOGLE_TEST_INCLUDE_DIR GOOGLE_MOCK_INCLUDE_DIR
- GOOGLE_TEST_SRC_ALL GOOGLE_MOCK_SRC_ALL)
-
-include(FeatureSummary)
-set_package_properties(Googletest PROPERTIES
- URL "https://github.com/google/googletest"
- DESCRIPTION "Google Testing and Mocking Framework")
diff --git a/dist/branding/qtdesignstudio/QtCreatorIDEBranding.cmake b/dist/branding/qtdesignstudio/QtCreatorIDEBranding.cmake
index 9b805bff125..5877838a481 100644
--- a/dist/branding/qtdesignstudio/QtCreatorIDEBranding.cmake
+++ b/dist/branding/qtdesignstudio/QtCreatorIDEBranding.cmake
@@ -1,6 +1,6 @@
-set(IDE_VERSION "4.2.0") # The IDE version.
-set(IDE_VERSION_COMPAT "4.2.0") # The IDE Compatibility version.
-set(IDE_VERSION_DISPLAY "4.2.0") # The IDE display version.
+set(IDE_VERSION "4.3.0") # The IDE version.
+set(IDE_VERSION_COMPAT "4.3.0") # The IDE Compatibility version.
+set(IDE_VERSION_DISPLAY "4.3.0") # The IDE display version.
set(IDE_COPYRIGHT_YEAR "2023") # The IDE current copyright year.
set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation.
diff --git a/doc/qtcreator/images/qtcreator-application-output.png b/doc/qtcreator/images/qtcreator-application-output.png
deleted file mode 100644
index 064e8d9e0d3..00000000000
Binary files a/doc/qtcreator/images/qtcreator-application-output.png and /dev/null differ
diff --git a/doc/qtcreator/images/qtcreator-application-output.webp b/doc/qtcreator/images/qtcreator-application-output.webp
new file mode 100644
index 00000000000..4a6277c7ba4
Binary files /dev/null and b/doc/qtcreator/images/qtcreator-application-output.webp differ
diff --git a/doc/qtcreator/images/qtcreator-compile-output.png b/doc/qtcreator/images/qtcreator-compile-output.png
deleted file mode 100644
index 3ecc83c25ec..00000000000
Binary files a/doc/qtcreator/images/qtcreator-compile-output.png and /dev/null differ
diff --git a/doc/qtcreator/images/qtcreator-compile-output.webp b/doc/qtcreator/images/qtcreator-compile-output.webp
new file mode 100644
index 00000000000..ef7d16003b8
Binary files /dev/null and b/doc/qtcreator/images/qtcreator-compile-output.webp differ
diff --git a/doc/qtcreator/images/qtcreator-general-messages.png b/doc/qtcreator/images/qtcreator-general-messages.png
deleted file mode 100644
index 89d80a260cd..00000000000
Binary files a/doc/qtcreator/images/qtcreator-general-messages.png and /dev/null differ
diff --git a/doc/qtcreator/images/qtcreator-general-messages.webp b/doc/qtcreator/images/qtcreator-general-messages.webp
new file mode 100644
index 00000000000..c77cc159e4e
Binary files /dev/null and b/doc/qtcreator/images/qtcreator-general-messages.webp differ
diff --git a/doc/qtcreator/images/qtcreator-installed-plugins.png b/doc/qtcreator/images/qtcreator-installed-plugins.png
deleted file mode 100644
index 2d9e9da951d..00000000000
Binary files a/doc/qtcreator/images/qtcreator-installed-plugins.png and /dev/null differ
diff --git a/doc/qtcreator/images/qtcreator-installed-plugins.webp b/doc/qtcreator/images/qtcreator-installed-plugins.webp
new file mode 100644
index 00000000000..b6aa4253b2b
Binary files /dev/null and b/doc/qtcreator/images/qtcreator-installed-plugins.webp differ
diff --git a/doc/qtcreator/images/qtcreator-issues.webp b/doc/qtcreator/images/qtcreator-issues.webp
index 329a66b29b3..503e23a5113 100644
Binary files a/doc/qtcreator/images/qtcreator-issues.webp and b/doc/qtcreator/images/qtcreator-issues.webp differ
diff --git a/doc/qtcreator/images/qtcreator-search-results-matches.webp b/doc/qtcreator/images/qtcreator-search-results-matches.webp
new file mode 100644
index 00000000000..8b49a72fbf2
Binary files /dev/null and b/doc/qtcreator/images/qtcreator-search-results-matches.webp differ
diff --git a/doc/qtcreator/images/qtcreator-search-results.png b/doc/qtcreator/images/qtcreator-search-results.png
deleted file mode 100644
index 363207038a7..00000000000
Binary files a/doc/qtcreator/images/qtcreator-search-results.png and /dev/null differ
diff --git a/doc/qtcreator/images/qtcreator-search-results.webp b/doc/qtcreator/images/qtcreator-search-results.webp
new file mode 100644
index 00000000000..d36ec5e2851
Binary files /dev/null and b/doc/qtcreator/images/qtcreator-search-results.webp differ
diff --git a/doc/qtcreator/images/qtcreator-searchresults.png b/doc/qtcreator/images/qtcreator-searchresults.png
deleted file mode 100644
index 3e2bc2f5309..00000000000
Binary files a/doc/qtcreator/images/qtcreator-searchresults.png and /dev/null differ
diff --git a/doc/qtcreator/images/qtcreator-to-do-entries.webp b/doc/qtcreator/images/qtcreator-to-do-entries.webp
new file mode 100644
index 00000000000..0662993be13
Binary files /dev/null and b/doc/qtcreator/images/qtcreator-to-do-entries.webp differ
diff --git a/doc/qtcreator/images/qtcreator-todo-pane.png b/doc/qtcreator/images/qtcreator-todo-pane.png
deleted file mode 100644
index 21122b96a22..00000000000
Binary files a/doc/qtcreator/images/qtcreator-todo-pane.png and /dev/null differ
diff --git a/doc/qtcreator/src/editors/creator-coding-edit-mode.qdoc b/doc/qtcreator/src/editors/creator-coding-edit-mode.qdoc
index fb7cc429f43..c5042fd7553 100644
--- a/doc/qtcreator/src/editors/creator-coding-edit-mode.qdoc
+++ b/doc/qtcreator/src/editors/creator-coding-edit-mode.qdoc
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
// **********************************************************************
@@ -11,7 +11,7 @@
\previouspage creator-editor-functions.html
\page creator-coding-navigating.html
\if defined(qtdesignstudio)
- \nextpage creator-sidebars.html
+ \nextpage creator-views.html
\else
\nextpage creator-highlighting.html
\endif
@@ -246,7 +246,12 @@
\endlist
To view the note, move the mouse pointer over the bookmark or open the
- \uicontrol Bookmarks view in the \l{Working with Sidebars}{sidebar}.
+ \uicontrol Bookmarks view
+ \if defined(qtcreator)
+ in the \l{Show and hide sidebars}{sidebar}.
+ \else
+ in the \l{Managing Workspaces}{workspace}.
+ \endif
\section2 Navigating Bookmarks
@@ -358,13 +363,11 @@
\QC underlines semantic errors in olive in the C++ code editor. To check the
correct paths for includes that are not resolved or that are resolved to the
wrong file, select \uicontrol {Project Parts} > \uicontrol {Header Paths}.
- \endif
- \if defined(qtdesignstudio)
+ \else
\section1 Related Topics
\list
- \li \l{Working with Sidebars}
\li \l{Browsing Project Contents}
\li \l{Viewing Output}
\endlist
diff --git a/doc/qtcreator/src/editors/creator-search.qdoc b/doc/qtcreator/src/editors/creator-search.qdoc
index 13dc963896e..502a87367aa 100644
--- a/doc/qtcreator/src/editors/creator-search.qdoc
+++ b/doc/qtcreator/src/editors/creator-search.qdoc
@@ -176,7 +176,7 @@
\li Enter the text you are looking for and click \uicontrol Search.
- \image qtcreator-searchresults.png
+ \image qtcreator-search-results-matches.webp {Found matches in Search Results}
\l {Search Results} shows a list of files that have the searched text.
diff --git a/doc/qtcreator/src/external-resources/external-resources-qds.qdoc b/doc/qtcreator/src/external-resources/external-resources-qds.qdoc
index b1c64e785d1..610e0926344 100644
--- a/doc/qtcreator/src/external-resources/external-resources-qds.qdoc
+++ b/doc/qtcreator/src/external-resources/external-resources-qds.qdoc
@@ -57,3 +57,7 @@
\externalpage https://doc.qt.io/QtForMCUs/qtul-renesas-rh850-qsg.html
\title Renesas RH850-D1M1A quick start guide
*/
+/*!
+ \externalpage https://doc.qt.io/QtForMCUs/qtul-known-issues.html
+ \title \QMCU Known Issues or Limitations
+*/
diff --git a/doc/qtcreator/src/howto/creator-only/creator-how-to-enable-plugins.qdoc b/doc/qtcreator/src/howto/creator-only/creator-how-to-enable-plugins.qdoc
new file mode 100644
index 00000000000..72592cdca5a
--- /dev/null
+++ b/doc/qtcreator/src/howto/creator-only/creator-how-to-enable-plugins.qdoc
@@ -0,0 +1,35 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \page creator-how-to-enable-plugins.html
+ \previouspage creator-how-tos.html
+ \nextpage creator-known-issues.html
+ \ingroup creator-how-to-use
+
+ \title Enable and disable plugins
+
+ New \QC plugins are often introduced as \e {experimental plugins} to let you
+ try them out before they are fully supported. Experimental plugins are
+ disabled by default and you must enable them for them to become visible
+ after you restart \QC. By default, all the plugins that the plugin depends
+ on are also enabled.
+
+ You can also disable plugins that you do not use, to streamline \QC.
+ By default, all the plugins that depend on the plugin are also disabled.
+
+ To enable and disable plugins:
+
+ \list 1
+ \li Select \uicontrol Help > \uicontrol {About Plugins}.
+ \li Start typing in the \uicontrol Filter field to find a plugin.
+ \image qtcreator-installed-plugins.webp {Installed Plugins dialog}
+ \li Select the \uicontrol Load check box to enable a plugin, or deselect
+ it to disable a plugin.
+ \li Select \uicontrol OK.
+ \li Select \uicontrol {Restart Now} to restart \QC and have the changes
+ take effect.
+ \endlist
+
+ \sa {Install plugins}{How-to: Install plugins}
+*/
diff --git a/doc/qtcreator/src/howto/creator-only/creator-how-to-install-plugins.qdoc b/doc/qtcreator/src/howto/creator-only/creator-how-to-install-plugins.qdoc
new file mode 100644
index 00000000000..10eb5e36c45
--- /dev/null
+++ b/doc/qtcreator/src/howto/creator-only/creator-how-to-install-plugins.qdoc
@@ -0,0 +1,43 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \page creator-how-to-install-plugins.html
+ \previouspage creator-how-tos.html
+ \nextpage creator-known-issues.html
+ \ingroup creator-how-to-use
+
+ \title Install plugins
+
+ \l{https://marketplace.qt.io/}{Qt Marketplace} has links to \QC plugins that
+ you can download and install either for free or for a price set by their
+ publisher. Browse the available plugins in the \uicontrol Marketplace tab
+ in the \uicontrol Welcome mode.
+
+ You can also install plugins from other sources, such as
+ \l{https://github.com/}{GitHub}.
+
+ \note You can install only plugins that your \QC version supports.
+
+ To install plugins:
+
+ \list 1
+ \li Select \uicontrol Help > \uicontrol {About Plugins} >
+ \uicontrol {Install Plugins}.
+ \li In the \uicontrol Source dialog, enter the path to the archive
+ or library that has the plugin.
+ \image qtcreator-install-plugin-source.png
+ \li In the \uicontrol {Install Location} dialog, select
+ \uicontrol {User plugins} to make the plugin available for the
+ current user in all compatible \QC instances or
+ \uicontrol {\QC installation} to make the plugin available for
+ all users of a particular \QC instance.
+ \image qtcreator-install-plugin-location.png
+ \li In the \uicontrol Summary dialog, select \uicontrol Finish to
+ install the plugin.
+ \image qtcreator-install-plugin-summary.png
+ \li Select \uicontrol {Restart Now} to restart \QC and load the plugin.
+ \endlist
+
+ \sa {Enable and disable plugins}{How-to: Enable and disable plugins}
+*/
diff --git a/doc/qtcreator/src/howto/creator-only/creator-how-tos.qdoc b/doc/qtcreator/src/howto/creator-only/creator-how-tos.qdoc
index e4fb87f7c10..ae2b15c2509 100644
--- a/doc/qtcreator/src/howto/creator-only/creator-how-tos.qdoc
+++ b/doc/qtcreator/src/howto/creator-only/creator-how-tos.qdoc
@@ -64,36 +64,13 @@
\section1 Use \QC
\list
+ \li \l {Enable and disable plugins}
\li \l {Find settings files}
+ \li \l {Install plugins}
\li \l {Run \QC from the command line}
\endlist
*/
-/*!
- \page creator-how-to-switch-between-modes.html
- \previouspage creator-how-tos.html
- \nextpage creator-known-issues.html
- \ingroup creator-how-to-ui
-
- \title Switch between modes
-
- \QC uses different modes for different purposes. You can quickly
- switch between these modes with the following keyboard shortcuts:
-
- \list
-
- \li \uicontrol Welcome mode \key Ctrl+1
- \li \uicontrol Edit mode \key Ctrl+2
- \li \uicontrol Design mode \key Ctrl+3
- \li \uicontrol Debug mode \key Ctrl+4
- \li \uicontrol Projects mode \key Ctrl+5
- \li \uicontrol Help mode \key Ctrl+6
-
- \endlist
-
- For more information about \QC modes, see \l {Selecting Modes}.
-*/
-
/*!
\page creator-how-to-move-between-open-files.html
\previouspage creator-how-tos.html
@@ -216,28 +193,6 @@
For more information, see \l{Using Command Line Options}.
*/
-/*!
- \page creator-how-to-show-and-hide-sidebars.html
- \previouspage creator-how-tos.html
- \nextpage creator-known-issues.html
- \ingroup creator-how-to-ui
-
- \title Show and hide sidebars
-
- You can toggle the left and right sidebar in some \QC modes.
-
- To toggle the left sidebar, click \inlineimage icons/leftsidebaricon.png
- (\uicontrol {Hide Left Sidebar/Show Left Sidebar}) or press \key Alt+0
- (\key Cmd+0 on \macos).
-
- To toggle the right sidebar, click \inlineimage icons/rightsidebaricon.png
- (\uicontrol {Hide Right Sidebar/Show Right Sidebar}) or press
- \key Alt+Shift+0 (\key Cmd+Shift+0 on \macos).
-
- For more information on using the sidebars, see
- \l {Browsing Project Contents}.
-*/
-
/*!
\page creator-how-to-move-to-symbols.html
\previouspage creator-how-tos.html
diff --git a/doc/qtcreator/src/howto/creator-only/creator-squish.qdoc b/doc/qtcreator/src/howto/creator-only/creator-squish.qdoc
index 27918da3e48..874b4b389e4 100644
--- a/doc/qtcreator/src/howto/creator-only/creator-squish.qdoc
+++ b/doc/qtcreator/src/howto/creator-only/creator-squish.qdoc
@@ -130,7 +130,7 @@
\section1 Managing Test Suites and Cases
You can manage Squish test suites and cases in the \uicontrol Squish
- \l {Working with Sidebars}{view}.
+ \l {Show and hide sidebars}{view}.
\image qtcreator-squish-view.png "Squish sidebar view"
diff --git a/doc/qtcreator/src/meson/creator-projects-meson.qdoc b/doc/qtcreator/src/meson/creator-projects-meson.qdoc
index ac15cd4ed83..ffc9a0d4c7b 100644
--- a/doc/qtcreator/src/meson/creator-projects-meson.qdoc
+++ b/doc/qtcreator/src/meson/creator-projects-meson.qdoc
@@ -22,7 +22,7 @@
in different build and run \l{glossary-buildandrun-kit}{kits}.
\note Meson build plugin is disabled by default, see
- \l{Enabling and Disabling Plugins}.
+ \l{Enable and disable plugins}{How-to: Enable and disable plugins}.
\section1 Adding Meson Tools
diff --git a/doc/qtcreator/src/overview/creator-only/creator-configuring.qdoc b/doc/qtcreator/src/overview/creator-only/creator-configuring.qdoc
index 631e7e879c7..2e9330159f5 100644
--- a/doc/qtcreator/src/overview/creator-only/creator-configuring.qdoc
+++ b/doc/qtcreator/src/overview/creator-only/creator-configuring.qdoc
@@ -1,4 +1,4 @@
-// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
// **********************************************************************
@@ -142,55 +142,16 @@
\section1 Managing Plugins
\QC comes with a set of plugins, some of which are disabled by default.
- You can enable disabled plugins if you need them and disable plugins you
- don't need.
+ You can \l{Enable and disable plugins}{enable} disabled plugins if you
+ need them and disable plugins you don't need.
- You can download and install additional plugins from
+ You can \l{Install plugins}{download and install} more plugins from
\l{https://marketplace.qt.io/}{Qt Marketplace} or some
other source, such as \l{https://github.com/}{GitHub}.
- \section2 Enabling and Disabling Plugins
-
- New \QC plugins are often introduced as \e {experimental plugins} to let you
- try them out before they are fully supported. Experimental plugins are
- disabled by default and you must enable them for them to become visible
- after you restart \QC. By default, all the plugins that the plugin depends
- on are also enabled.
-
- You can also disable plugins that you do not use, to streamline \QC.
- By default, all the plugins that depend on the plugin are also disabled.
-
To enable and disable plugins, select \uicontrol Help >
\uicontrol {About Plugins}.
- \image qtcreator-installed-plugins.png "Installed Plugins dialog"
-
- \section2 Installing Plugins
-
- Qt Marketplace has links to \QC plugins that you can download and
- install either for free or for a price set by their publisher. You can
- browse the available plugins in the \uicontrol Marketplace tab in the
- Welcome mode.
-
- \note You can install only plugins that your \QC version supports.
-
- To install plugins:
-
- \list 1
- \li Select \uicontrol Help > \uicontrol {About Plugins} >
- \uicontrol {Install Plugins}.
- \li In the \uicontrol Source dialog, enter the path to the archive
- or library that has the plugin.
- \image qtcreator-install-plugin-source.png
- \li In the \uicontrol {Install Location} dialog, select
- \uicontrol {User plugins} to make the plugin available for the
- current user in all compatible \QC instances or
- \uicontrol {\QC installation} to make the plugin available for
- all users of a particular \QC instance.
- \image qtcreator-install-plugin-location.png
- \li In the \uicontrol Summary dialog, select \uicontrol Finish to
- install the plugin.
- \image qtcreator-install-plugin-summary.png
- \li Select \uicontrol {Restart Now} to restart \QC and load the plugin.
- \endlist
+ To install plugins, select \uicontrol Help > \uicontrol {About Plugins} >
+ \uicontrol {Install Plugins}.
*/
diff --git a/doc/qtcreator/src/projects/creator-projects-running.qdoc b/doc/qtcreator/src/projects/creator-projects-running.qdoc
index 2393c4d2bb1..a6311d58d0a 100644
--- a/doc/qtcreator/src/projects/creator-projects-running.qdoc
+++ b/doc/qtcreator/src/projects/creator-projects-running.qdoc
@@ -64,7 +64,7 @@
the application has large image files that would need to be bundled
into the resource file before running the application.
- \image qtcreator-application-output.png
+ \image qtcreator-application-output.webp {Application Output view}
\if defined(qtcreator)
For more information on the options you have, see
diff --git a/doc/qtcreator/src/qtcreator-toc.qdoc b/doc/qtcreator/src/qtcreator-toc.qdoc
index acf3ca83a7c..eb8ced88e3b 100644
--- a/doc/qtcreator/src/qtcreator-toc.qdoc
+++ b/doc/qtcreator/src/qtcreator-toc.qdoc
@@ -19,8 +19,6 @@
\li \l{IDE Overview}
\li \l{User Interface}
\list
- \li \l{Selecting Modes}
- \li \l{Working with Sidebars}
\li \l{Browsing Project Contents}
\list
\li \l{Projects}
diff --git a/doc/qtcreator/src/user-interface/creator-file-system-view.qdoc b/doc/qtcreator/src/user-interface/creator-file-system-view.qdoc
index da554a3ab08..b7eddea19a0 100644
--- a/doc/qtcreator/src/user-interface/creator-file-system-view.qdoc
+++ b/doc/qtcreator/src/user-interface/creator-file-system-view.qdoc
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
@@ -8,8 +8,7 @@
\title File System
- If you cannot see a file in the \l Projects view, switch to the
- \uicontrol {File System} view, which shows all the files in the file system.
+ The \uicontrol {File System} view shows all the files in the file system.
\note Usually, \l{Searching with the Locator}{searching with the locator}
is the fastest way to find a particular project, file, class, or function,
@@ -17,12 +16,9 @@
to open files from anywhere in the file system.
\if defined(qtdesignstudio)
- The following image displays the \uicontrol {File System} view in the
- \uicontrol Design mode:
-
- \image qtcreator-filesystem-view-design.png "File System view in the Design mode"
+ \image qtcreator-filesystem-view-design.png {File System view}
\else
- \image qtcreator-filesystem-view.webp "File System view in the sidebar"
+ \image qtcreator-filesystem-view.webp {File System view in the sidebar}
\endif
To move to the root directory of the file system, select \uicontrol Computer
@@ -87,19 +83,11 @@
\li Collapse all open folders.
\endlist
+ \if defined(qtcreator)
\section1 File System View Toolbar
- \if defined(qtdesignstudio)
- In the \uicontrol Edit and \uicontrol Debug mode, the
- \uicontrol {File System} view is displayed in the \l{Working with Sidebars}
- {sidebar}. It has a toolbar with additional options.
-
- \image qtcreator-filesystem-view.webp "File System view in the sidebar"
- \else
The toolbar in the \uicontrol {File System} view has additional
options.
- \endif
-
To manage view contents, select \inlineimage icons/filtericon.png
(\uicontrol Options):
@@ -116,4 +104,5 @@
To stop the synchronization with the file currently open in the
editor, deselect \inlineimage icons/linkicon.png
(\uicontrol {Synchronize with Editor}).
+ \endif
*/
diff --git a/doc/qtcreator/src/user-interface/creator-sidebars.qdoc b/doc/qtcreator/src/user-interface/creator-only/creator-how-to-show-and-hide-sidebars.qdoc
similarity index 53%
rename from doc/qtcreator/src/user-interface/creator-sidebars.qdoc
rename to doc/qtcreator/src/user-interface/creator-only/creator-how-to-show-and-hide-sidebars.qdoc
index aecb42aa76c..d1a07de2cef 100644
--- a/doc/qtcreator/src/user-interface/creator-sidebars.qdoc
+++ b/doc/qtcreator/src/user-interface/creator-only/creator-how-to-show-and-hide-sidebars.qdoc
@@ -1,24 +1,19 @@
-// Copyright (C) 2020 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
- \page creator-sidebars.html
- \if defined(qtdesignstudio)
- \previouspage creator-coding-navigating.html
- \else
- \previouspage creator-modes.html
- \endif
- \nextpage creator-views.html
+ \page creator-how-to-show-and-hide-sidebars.html
+ \previouspage creator-how-tos.html
+ \nextpage creator-known-issues.html
+ \ingroup creator-how-to-ui
+ \title Show and hide sidebars
- \title Working with Sidebars
+ In some \l{Switch between modes}{modes}, you can use a left and right
+ sidebar to organize different views into project contents. Only views
+ that are relevant to the mode you are working in are available in it.
- In the \uicontrol Edit mode, you can use a left and right sidebar to
- organize different views into project contents. Only views that are
- relevant to the \l{Selecting Modes}{mode} you are working in are
- available in it.
-
- You can select views in the sidebar menu (1):
+ Select views in the sidebar menu (1):
\image qtcreator-sidebar.png
@@ -27,8 +22,8 @@
\list
\li To toggle the left sidebar, click \inlineimage icons/leftsidebaricon.png
(\uicontrol {Hide Left Sidebar/Show Left Sidebar}) or press
- \key Alt+0 (\key Cmd+0 on \macos). To toggle the right
- sidebar, click \inlineimage icons/rightsidebaricon.png
+ \key Alt+0 (\key Cmd+0 on \macos).
+ \li To toggle the right sidebar, click \inlineimage icons/rightsidebaricon.png
(\uicontrol {Hide Right Sidebar/Show Right Sidebar}) or press
\key Alt+Shift+0 (\key Cmd+Shift+0 on \macos).
\li To split a sidebar, click \inlineimage icons/splitbutton_horizontal.png
diff --git a/doc/qtcreator/src/user-interface/creator-only/creator-how-to-switch-between-modes.qdoc b/doc/qtcreator/src/user-interface/creator-only/creator-how-to-switch-between-modes.qdoc
new file mode 100644
index 00000000000..a43cffc4f04
--- /dev/null
+++ b/doc/qtcreator/src/user-interface/creator-only/creator-how-to-switch-between-modes.qdoc
@@ -0,0 +1,75 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \page creator-how-to-switch-between-modes.html
+ \previouspage creator-how-tos.html
+ \nextpage creator-known-issues.html
+ \ingroup creator-how-to-ui
+
+ \title Switch between modes
+
+ \e Modes let you quickly switch between tasks such as editing
+ project and source files, designing application UIs, configuring projects
+ for building and running, and debugging or analyzing source code.
+
+ To switch between modes:
+
+ \list
+ \li Click the icons on the mode selector.
+ \li Use the \l{keyboard-shortcuts}{corresponding keyboard shortcut}.
+ \endlist
+
+ \table
+ \header
+ \li {2,1} Mode
+ \li Keyboard Shortcut
+ \li Purpose
+ \li Read More
+ \row
+ \li {1,7} \inlineimage qtcreator-mode-selector.png
+ \row
+ \li \uicontrol Welcome
+ \li \key Ctrl+1
+ \li Open projects, tutorials, and examples.
+ \li \l{User Interface}
+ \row
+ \li \uicontrol Edit
+ \li \key Ctrl+2
+ \li Edit project and source files.
+ \li \l{Working in Edit Mode}
+ \row
+ \li \uicontrol Design
+ \li \key Ctrl+3
+ \li Design and develop application user interfaces.
+ This mode is available for UI files.
+ \li \l{Designing User Interfaces}
+ \row
+ \li \uicontrol Debug
+ \li \key Ctrl+4
+ \li Inspect the state of your application while debugging or use code
+ analysis tools to detect memory leaks and profile code.
+ \li \l{Debugging}
+ \row
+ \li \uicontrol Projects
+ \li \key Ctrl+5
+ \li Configure how to build and run projects.
+ This mode is available when a project is open.
+ \li \l{Specifying Build Settings}
+ \row
+ \li \uicontrol Help
+ \li \key Ctrl+6
+ \li Read documentation.
+ \li \l{Using the Help Mode}
+ \endtable
+
+ Some actions in \QC trigger a mode change. For example,
+ selecting \uicontrol {Debug} > \uicontrol {Start Debugging} >
+ \uicontrol {Start Debugging of Startup Project} automatically
+ switches to \uicontrol {Debug} mode.
+
+ To hide the mode selector and to save space on the display, select
+ \uicontrol View > \uicontrol {Mode Selector Style} > \uicontrol Hidden.
+ To only show icons on the mode selector, select the \uicontrol {Icons Only}
+ style.
+*/
diff --git a/doc/qtcreator/src/user-interface/creator-projects-view.qdoc b/doc/qtcreator/src/user-interface/creator-projects-view.qdoc
index cd8fd9a62a6..ef356c81cf4 100644
--- a/doc/qtcreator/src/user-interface/creator-projects-view.qdoc
+++ b/doc/qtcreator/src/user-interface/creator-projects-view.qdoc
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
@@ -13,6 +13,7 @@
\title Projects
The \uicontrol Projects view displays projects in a project tree.
+
The project tree has a list of all projects open in the current
\l{Managing Sessions}{session}. For each project, the tree visualizes
the build system structure of the project and lists all files that
@@ -23,12 +24,9 @@
or almost anything else in your project.
\if defined(qtdesignstudio)
- The following image displays the \uicontrol Projects view in the
- \uicontrol Design mode:
-
- \image qtcreator-projects-view-design.png "Projects view in the Design mode"
+ \image qtcreator-projects-view-design.png {Projects view}
\else
- \image qtcreator-projects-view-edit.png "Projects view in the sidebar"
+ \image qtcreator-projects-view-edit.png {Projects view in the sidebar}
\endif
You can use the project tree in the following ways:
@@ -37,8 +35,11 @@
\li To open files that belong to a \l{Creating Projects}{project},
double-click them in the project tree. Files open in the
appropriate editor, according to the file type. For example, code
- source files open in the code editor. Use the \l{Selecting Modes}
- {mode selector} to open the current file in another editor.
+ source files open in the code editor.
+ \if defined(qtcreator)
+ Use the \l{Switch between modes} {mode selector} to open the current
+ file in another editor.
+ \endif
\li To bring up a \l{Projects View Context Menu}{context menu}
that has the actions most commonly needed, right-click an
item in the project tree. For example, through the menu of
@@ -51,6 +52,9 @@
configuration files.
\endlist
+ \note If you cannot see a file in the \l Projects view, switch to the
+ \uicontrol {File System} view, which shows all the files in the file system.
+
\section1 Projects View Context Menu
The \uicontrol Projects view has context menus for managing projects,
@@ -58,8 +62,10 @@
projects and subprojects:
\list
+ \if defined(qtcreator)
\li Set a project as the active project.
- \li Execute the \uicontrol Build menu commands.
+ \endif
+ \li Execute \uicontrol Build menu commands.
\li Create new files. For more information, see
\if defined(qtdesignstudio)
\l{Adding Files to Projects}.
@@ -106,18 +112,10 @@
the \l {File System} view. To view a project in it, select
\uicontrol {Show in File System View}.
+ \if defined(qtcreator)
\section1 Projects View Toolbar
- \if defined(qtdesignstudio)
- In the \uicontrol Edit and \uicontrol Debug mode, the
- \l{Working with Sidebars}{sidebar} has the \uicontrol Projects
- view. It has a toolbar with additional options.
-
- \image qtcreator-projects-view-edit.png "Projects view in the sidebar"
- \else
The toolbar in the \uicontrol Projects view has additional options.
- \endif
-
To filter view contents, select \inlineimage icons/filtericon.png
(\uicontrol {Filter Tree}):
@@ -140,7 +138,6 @@
currently opened in the editor, deselect \inlineimage icons/linkicon.png
(\uicontrol {Synchronize with Editor}).
- \if defined(qtcreator)
Some build systems support adding and removing files to a project in \QC
(currently qmake and Qbs). The faithful display of the project structure
enables you to specify exactly where to place a new file in the build system.
@@ -152,8 +149,5 @@
from the version control system in brackets after the project name.
\QC currently implements this for Git (the view displays the branch name
or a tag) and ClearCase (the view displays the branch name).
- \else
- If the project is under Git version control, you can see the currently
- checked out branch or tag in brackets after the project name.
\endif
*/
diff --git a/doc/qtcreator/src/user-interface/creator-ui.qdoc b/doc/qtcreator/src/user-interface/creator-ui.qdoc
index f2261381d55..29fe61bb26b 100644
--- a/doc/qtcreator/src/user-interface/creator-ui.qdoc
+++ b/doc/qtcreator/src/user-interface/creator-ui.qdoc
@@ -11,10 +11,11 @@
\page creator-quick-tour.html
\if defined(qtdesignstudio)
\previouspage {Tutorials}
+ \nextpage creator-using-qt-quick-designer.html
\else
\previouspage creator-overview.html
+ \nextpage creator-views.html
\endif
- \nextpage creator-modes.html
\title User Interface
@@ -34,7 +35,7 @@
\li Mode selector
\li Perform a particular task, such as designing the UI, writing code, or
debugging the application.
- \li \l{Selecting Modes}
+ \li \l{Switch between modes}
\row
\li \inlineimage numbers/02.png
\li Kit selector
@@ -81,9 +82,11 @@
For information about new features and bug fixes in each \QC release,
select \uicontrol Help > \uicontrol {Change Log}.
- \sa {Working with Sidebars}, {Browsing Project Contents}
+ \sa {Show and hide sidebars}, {Browsing Project Contents}
\sa {Use the UI}{How-to: Use the UI}
+
\else
+
When you start \QC, it opens to the \uicontrol Welcome mode, where you can:
\list
@@ -139,91 +142,6 @@
\endif
*/
-/*!
- \page creator-modes.html
- \previouspage creator-quick-tour.html
- \if defined(qtdesignstudio)
- \nextpage creator-using-qt-quick-designer.html
- \else
- \nextpage creator-sidebars.html
- \endif
-
- \title Selecting Modes
-
- \image qtcreator-mode-selector.png
-
- \if defined(qtcreator)
- The mode selector allows you to quickly switch between tasks such as editing
- project and source files, designing application UIs, configuring projects for
- building and running, and debugging your applications. To change
- modes, click the icons, or use the \l{keyboard-shortcuts}
- {corresponding keyboard shortcut}.
-
- To hide the mode selector and to save space on the display, select
- \uicontrol View > \uicontrol {Mode Selector Style} > \uicontrol Hidden.
- To only show icons on the mode selector, select the \uicontrol {Icons Only}
- style.
- \endif
-
- \if defined(qtdesignstudio)
- The mode selector is hidden by default.
-
- To show the mode selector, go to \uicontrol Views >
- \uicontrol {Mode Selector Style} and select \uicontrol {Icons and Text}
- or \uicontrol {Icons Only}.
- \endif
-
-
- You can use \QC in the following modes:
-
- \list
-
- \li \uicontrol {\l{User Interface}{Welcome}} mode for opening projects,
- tutorials, and examples.
-
- \li \uicontrol{\l{Coding}{Edit}} mode for editing project and source
- files.
-
- \if defined(qtcreator)
- \li \uicontrol{\l{Designing User Interfaces}{Design}}
- mode for designing and developing application user interfaces.
- This mode is available for UI files.
- \else
- \li \uicontrol{\l{Design Views}{Design}}
- mode for designing and developing application user interfaces.
- As a designer, you'll do most of your work in this mode.
- \endif
-
- \if defined(qtcreator)
- \li \uicontrol{\l{Debugging}{Debug}}
- \else
- \li \uicontrol {\l{Debugging and Profiling}{Debug}}
- \endif
- mode for inspecting the state of your
- application while debugging and for using code analysis tools
- to detect memory leaks and profile code.
-
- \if defined(qtcreator)
- \li \uicontrol{\l{Specifying Build Settings}{Projects}} mode
- for configuring project building and execution.
- \else
- \li \uicontrol{\l{Selecting the Preview Tool}{Projects}} mode
- for selecting the tool to use for live preview.
- \endif
- This mode is available when a project is open.
-
- \li \uicontrol{\l{Using the Help Mode}{Help}} mode for viewing
- documentation.
-
- \endlist
-
- \if defined(qtcreator)
- Certain actions in \QC trigger a mode change. Clicking on \uicontrol {Debug} >
- \uicontrol {Start Debugging} > \uicontrol {Start Debugging} automatically switches to
- \uicontrol {Debug} mode.
- \endif
-*/
-
/*!
\page creator-output-panes.html
\if defined(qtdesignstudio)
@@ -236,9 +154,9 @@
\title Viewing Output
- \image qtcreator-general-messages.png "General Messages"
+ \image qtcreator-general-messages.webp {General Messages}
- The taskbar in \QC can display following types of output:
+ You can view the following types of output:
\list
@@ -276,7 +194,12 @@
\endlist
- Output is available on the taskbar in all \l{Selecting Modes}{modes}.
+ Output is available on the taskbar in all
+ \if defined(qtcreator)
+ \l{Switch between modes}{modes}.
+ \else
+ \l{Mode}{modes}.
+ \endif
\image qtcreator-output-panes-taskbar.webp "Output on the taskbar"
@@ -441,7 +364,7 @@
In \uicontrol{Search Results}, you can search through projects, files on
a file system or the currently open files:
- \image qtcreator-search-results.png "Search Results"
+ \image qtcreator-search-results.webp {Search Results - criteria}
The search history (1) stores the search results. You can select earlier
searches from the history.
@@ -449,7 +372,7 @@
The figure below shows an example search result for all
occurrences of the search string in the specified directory.
- \image qtcreator-searchresults.png
+ \image qtcreator-search-results-matches.webp {Search Results - matches found}
For more information about the different search options, see
\l {Finding and Replacing}.
@@ -459,7 +382,7 @@
\uicontrol{Application Output} displays the status of a program when
you execute it, and the debug output.
- \image qtcreator-application-output.png
+ \image qtcreator-application-output.webp {Application Output}
\if defined(qtcreator)
If you specify command line arguments in the run settings that are passed
@@ -485,7 +408,7 @@
The \uicontrol{Compile Output} is a more detailed version of information
displayed in \l Issues.
- \image qtcreator-compile-output.png "Compile Output"
+ \image qtcreator-compile-output.webp {Compile Output}
Double-click on a file name in an error message to open the file in the
code editor.
@@ -636,13 +559,13 @@
subproject. Click the icons on the toolbar to show only the selected
keywords.
- \image qtcreator-todo-pane.png
+ \image qtcreator-to-do-entries.webp {To-Do Entries}
To add keywords, select \uicontrol Edit > \uicontrol Preferences >
\uicontrol {To-Do} > \uicontrol Add. Set an icon and a line background color
for the keyword.
- \image qtcreator-todo-options.png "To-Do preferences"
+ \image qtcreator-todo-options.png {To-Do preferences}
To change the icon and line background color of the selected keyword, select
\uicontrol Edit.
@@ -659,7 +582,7 @@
To exclude files from scanning, select \uicontrol {Project Settings} >
\uicontrol {To-Do} in the \uicontrol Projects mode.
- \image qtcreator-todo-excluded-files.png "Excluded Files in To-Do preferences"
+ \image qtcreator-todo-excluded-files.png {Excluded Files in To-Do preferences}
Select \uicontrol Add and double-click the placeholder text in
\uicontrol {Exclude Files} to enter a regular expression that
diff --git a/doc/qtcreator/src/user-interface/creator-views.qdoc b/doc/qtcreator/src/user-interface/creator-views.qdoc
index e676ed18907..673e902736d 100644
--- a/doc/qtcreator/src/user-interface/creator-views.qdoc
+++ b/doc/qtcreator/src/user-interface/creator-views.qdoc
@@ -1,26 +1,25 @@
-// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page creator-views.html
- \previouspage creator-sidebars.html
\if defined(qtdesignstudio)
+ \previouspage creator-coding-navigating.html
\nextpage creator-output-panes.html
\else
+ \previouspage creator-quick-tour.html
\nextpage creator-projects-view.html
\endif
\title Browsing Project Contents
- You can organize \QC views in \l {Working with Sidebars}{sidebars} or as
\if defined(qtdesignstudio)
- \l {Managing Workspaces}{workspaces},
+ You can organize \QDS views as \l {Managing Workspaces}{workspaces}.
\else
- workspaces
+ You can organize \QC views in \l {Show and hide sidebars}{sidebars} or as
+ workspaces, depending on the \l{Switch between modes}{mode} you are working
+ in. Only views that are relevant to a mode are available in it.
\endif
- depending on the \l{Selecting Modes}
- {mode} you are working in. Only views that are relevant to a mode are
- available in it.
\note Usually, \l{Searching with the Locator}{searching with the locator}
is the fastest way to find a particular project, file, class, or function,
diff --git a/doc/qtdesignstudio/config/qtdesignstudio.qdocconf b/doc/qtdesignstudio/config/qtdesignstudio.qdocconf
index 5bcfe70d400..86a948bd889 100644
--- a/doc/qtdesignstudio/config/qtdesignstudio.qdocconf
+++ b/doc/qtdesignstudio/config/qtdesignstudio.qdocconf
@@ -54,6 +54,7 @@ excludedirs += ../../qtcreator/examples/accelbubble \
../../qtcreator/src/python \
../../qtcreator/src/qnx \
../../qtcreator/src/qtquick/creator-only \
+ ../../qtcreator/src/user-interface/creator-only \
../../qtcreator/src/vcs/creator-only \
../../qtcreator/src/widgets \
../../qtcreator/src/webassembly
diff --git a/doc/qtdesignstudio/examples/Loginui1/src/main.cpp b/doc/qtdesignstudio/examples/Loginui1/src/main.cpp
index 1df03ed16b6..eacbde58784 100644
--- a/doc/qtdesignstudio/examples/Loginui1/src/main.cpp
+++ b/doc/qtdesignstudio/examples/Loginui1/src/main.cpp
@@ -14,7 +14,7 @@ int main(int argc, char *argv[])
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
- const QUrl url(u"qrc:Main/main.qml"_qs);
+ const QUrl url(u"qrc:/qt/qml/Main/main.qml"_qs);
QObject::connect(
&engine, &QQmlApplicationEngine::objectCreated, &app,
[url](QObject *obj, const QUrl &objUrl) {
diff --git a/doc/qtdesignstudio/examples/doc/3DsceneTutorial.qdoc b/doc/qtdesignstudio/examples/doc/3DsceneTutorial.qdoc
new file mode 100644
index 00000000000..78a3490113f
--- /dev/null
+++ b/doc/qtdesignstudio/examples/doc/3DsceneTutorial.qdoc
@@ -0,0 +1,120 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \page 3d-scene-tutorial.html
+ \ingroup gstutorials
+
+ \title Setting up a 3D Scene
+ \sa {Content Library}
+ \brief Illustrates how to set up a 3D scene with, for example, lights, models, and materials in
+ \QDS.
+
+ \image 3d-scene-tutorial.webp
+
+ The \e {Setting up a 3D Scene} tutorial illustrates how you can set up and improve a 3D
+ scene with the following:
+ \list
+ \li 3D models
+ \li Materials
+ \li Lights
+ \li Environmental lights
+ \li Background images
+ \endlist
+
+ The assets you use in this tutorial are available in \uicontrol {Content Library}.
+
+ To follow this tutorial, you need to first download the starting project from
+ \l{https://git.qt.io/public-demos/qtdesign-studio/-/tree/master/tutorial%20projects/3Dscene%20tutorial/Start}{here}.
+
+ Download the completed project from
+ \l{https://git.qt.io/public-demos/qtdesign-studio/-/tree/master/tutorial%20projects/3Dscene%20tutorial/Completed/}{here}.
+
+ This tutorial requires that you know the basics of \QDS, see
+ \l{Getting Started}.
+
+ \section1 The Starting Project
+
+ The starting project consists of an animated 3D model of a ball bearing. Control the animations
+ with a slider and a switch in the user interface.
+
+ Besides the 3D model, the 3D scene also has the default camera and the default directional
+ light.
+
+ \section1 Adding Materials to the 3D Models
+
+ First, use materials from \uicontrol {Content Library} on the ball bearing.
+
+ \list 1
+ \li In the \uicontrol 3D view, right-click the ball bearing and select
+ \uicontrol {Edit Component}.
+ \image 3d-scene-edit-component-menu.png
+ \li From \uicontrol {Content Library}, drag materials to the different parts of the ball
+ bearing in the \uicontrol Navigator view.
+ Drag the following materials to the following parts:
+ \list
+ \li Chrome to \e inner_race and \e outer_race.
+ \li Copper to \e balls.
+ \li Gold to \e retainer.
+ \li Carbon Fiber to \e shield_left and \e shield_right.
+ \endlist
+ \note The first time you use an asset from \uicontrol {Content Library}, you need to
+ download it.
+ \image 3d-scene-drag-material.png
+ \li Select \e {Screen01.ui.qml} in the breadcrumb in the top menu bar to return to the 3D
+ scene.
+ \image 3d-scene-bread-crumb.png
+ \endlist
+ When you run the application or live preview, notice that you don't see much of the materials.
+ The next step is to set up the environmental light.
+
+ \section1 Adding Environmental Lighting to the Scene
+
+ Environmental lighting is a good way to create a realistic light for your scene.
+
+ \list 1
+ \li In \uicontrol {Content Library}, go to the \uicontrol Environments tab.
+ \li Right-click the image \e BasicLights3_4k.hdr and select \uicontrol {Add Light Probe}.
+ \image 3d-scene-add-light-probe.webp
+ Setting an image as a light probe for a scene adds the image as the source for the image-based
+ lighting and also sets it as a skybox, meaning that the same image is used as the background
+ in the scene.
+ \endlist
+
+ When you run the application, notice an improvement in the scene lighting.
+
+ Next, adjust the environmental light. As you will add a background image to the scene later,
+ you don't want to use the skybox.
+ \list 1
+ \li In the \uicontrol Navigator view, select \e sceneEnvironment.
+ \li In the \uicontrol Properties view, set \uicontrol {Background Mode} to
+ \uicontrol Transparent.
+ \endlist
+
+ You also want to increase the brightness of the light a bit. In the \uicontrol Properties view,
+ set \uicontrol Exposure to 10.
+
+ \section2 Adding a Background Image to the Scene
+
+ In the final step of this tutorial, you add a background image to your scene.
+
+ \list 1
+ \li Go to the \uicontrol Textures tab in \uicontrol {Content Library}.
+ \li Right-click the image \e 4kScratchySurface.png and select \uicontrol {Add Texture}
+ \image 3d-scene-add-texture.webp
+ This adds the image as a texture to the project. It is now available in the \uicontrol Assets
+ view.
+ \li From the \uicontrol Assets view, drag \e 4KScratchySurface.png to \e Rectangle in the
+ \uicontrol Navigator view.
+ \li Go to the \uicontrol Layout tab in \uicontrol Properties and set \uicontrol Anchors to
+ \uicontrol FillParentComponent.
+ \image 3d-scene-fill-parent.png
+ \li Go to the \uicontrol Image tab and set \uicontrol {Fill Mode} to \uicontrol Stretch.
+ \li The background is rendered on top of the 3D scene as it is located at the bottom of the
+ \uicontrol Navigator view.
+ With the background image selected, select the down arrow to move it to the top of the
+ hierarchy.
+ \image 3d-scene-navigator-background.png
+ \endlist
+
+*/
diff --git a/doc/qtdesignstudio/examples/doc/images/3d-scene-add-light-probe.webp b/doc/qtdesignstudio/examples/doc/images/3d-scene-add-light-probe.webp
new file mode 100644
index 00000000000..79ea955232b
Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/3d-scene-add-light-probe.webp differ
diff --git a/doc/qtdesignstudio/examples/doc/images/3d-scene-add-texture.webp b/doc/qtdesignstudio/examples/doc/images/3d-scene-add-texture.webp
new file mode 100644
index 00000000000..3624fa94183
Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/3d-scene-add-texture.webp differ
diff --git a/doc/qtdesignstudio/examples/doc/images/3d-scene-bread-crumb.png b/doc/qtdesignstudio/examples/doc/images/3d-scene-bread-crumb.png
new file mode 100644
index 00000000000..810deb47498
Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/3d-scene-bread-crumb.png differ
diff --git a/doc/qtdesignstudio/examples/doc/images/3d-scene-drag-material.png b/doc/qtdesignstudio/examples/doc/images/3d-scene-drag-material.png
new file mode 100644
index 00000000000..5d346e761f7
Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/3d-scene-drag-material.png differ
diff --git a/doc/qtdesignstudio/examples/doc/images/3d-scene-edit-component-menu.png b/doc/qtdesignstudio/examples/doc/images/3d-scene-edit-component-menu.png
new file mode 100644
index 00000000000..ca43f352ed4
Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/3d-scene-edit-component-menu.png differ
diff --git a/doc/qtdesignstudio/examples/doc/images/3d-scene-fill-parent.png b/doc/qtdesignstudio/examples/doc/images/3d-scene-fill-parent.png
new file mode 100644
index 00000000000..fecb23b9f34
Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/3d-scene-fill-parent.png differ
diff --git a/doc/qtdesignstudio/examples/doc/images/3d-scene-navigator-background.png b/doc/qtdesignstudio/examples/doc/images/3d-scene-navigator-background.png
new file mode 100644
index 00000000000..54a9a3cc2bf
Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/3d-scene-navigator-background.png differ
diff --git a/doc/qtdesignstudio/examples/doc/images/3d-scene-tutorial.webp b/doc/qtdesignstudio/examples/doc/images/3d-scene-tutorial.webp
new file mode 100644
index 00000000000..6aeb929608d
Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/3d-scene-tutorial.webp differ
diff --git a/doc/qtdesignstudio/examples/doc/images/robot-arm-components.png b/doc/qtdesignstudio/examples/doc/images/robot-arm-components.png
new file mode 100644
index 00000000000..6db6cbddff2
Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/robot-arm-components.png differ
diff --git a/doc/qtdesignstudio/examples/doc/images/robotarm-3d-view.png b/doc/qtdesignstudio/examples/doc/images/robotarm-3d-view.png
new file mode 100644
index 00000000000..70de427f164
Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/robotarm-3d-view.png differ
diff --git a/doc/qtdesignstudio/examples/doc/images/robotarm-button-connections.png b/doc/qtdesignstudio/examples/doc/images/robotarm-button-connections.png
new file mode 100644
index 00000000000..93bb6c4016e
Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/robotarm-button-connections.png differ
diff --git a/doc/qtdesignstudio/examples/doc/images/robotarm-example.webp b/doc/qtdesignstudio/examples/doc/images/robotarm-example.webp
new file mode 100644
index 00000000000..aa9aab9297a
Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/robotarm-example.webp differ
diff --git a/doc/qtdesignstudio/examples/doc/loginui1.qdoc b/doc/qtdesignstudio/examples/doc/loginui1.qdoc
index c10c118fdd6..afb7c50556e 100644
--- a/doc/qtdesignstudio/examples/doc/loginui1.qdoc
+++ b/doc/qtdesignstudio/examples/doc/loginui1.qdoc
@@ -275,8 +275,7 @@
\li In \uicontrol Component > \uicontrol ID, enter \e username.
\li In \uicontrol {Button Content} > \uicontrol Text, enter
\e {Username or Email} and select \uicontrol tr to mark the text
- \l {Internationalization and Localization with Qt Quick}
- {translatable}.
+ \l {Mark Strings for Translation}{translatable}.
\li Select the second EntryField instance, and change its ID to
\e password and text to \e Password. Again, mark the text
translatable.
diff --git a/doc/qtdesignstudio/examples/doc/robotarm.qdoc b/doc/qtdesignstudio/examples/doc/robotarm.qdoc
new file mode 100644
index 00000000000..6c6ae78b023
--- /dev/null
+++ b/doc/qtdesignstudio/examples/doc/robotarm.qdoc
@@ -0,0 +1,97 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \page robotarm-example.html
+ \ingroup gstutorials
+
+ \title Creating a C++ Backend for a \QDS Application
+
+ \brief Illustrates how to create an application in \QDS and add a backend
+ in Qt Creator.
+
+ \image robotarm-example.webp
+
+ The \e Robotarm example demonstrates adding a C++ backend to a 3D project created in \QDS.
+
+ The example itself consists of an interactive industrial robot arm in a Qt Quick 3D scene.
+ The 2D UI to control the robot arm is implemented using Qt Quick Controls.
+
+ You can open the example from the \uicontrol Examples tab on the \uicontrol Welcome page
+ in \QDS.
+
+ To complete this tutorial, you need experience in using \QDS and Qt Creator as well as knowledge
+ in C++ programming.
+
+ \section1 The Designer-Developer Workflow
+
+ This section describes the high-level steps for creating the robot arm example.
+
+ \section2 Creating the User Interface
+
+ First, the designer creates the user interface in \QDS.
+
+ \list 1
+ \li Create a new 3D project.
+ \li Import the 3D asset (RoboticArm).
+ \li Create the following custom components:
+ \list
+ \li NodeIndicator: This component consists of a rounded rectangle and a label. It is used
+ to indicate which joint in the robotic arm is currently active. Located in the 3D
+ scene, it follows the movement of the 3D model.
+ \li LabeledSlider: This component is a slider with a label. It is connected to the
+ rotation of the different robot arm parts so that you can use it to control the rotation
+ of those parts.
+ \li Toggle: This component consists of a switch and a label. It is used in two places; to
+ toggle dark mode and to toggle the claw of the robotic arm.
+ \li Backend: This serves as a mock backend for the \QDS application. Once you open,
+ compile, and run the application in Qt Creator, it uses the C++ backend.
+ \endlist
+ \li Add the 3D model and lights to the \uicontrol View3D scene.
+ \image robotarm-3d-view.png
+ \li Create the 2D UI controls:
+ \list
+ \li Four buttons for preset positions. As you can see from the \uicontrol Connections tab
+ in the \uicontrol Connections view, each button changes the rotation of the robot arm
+ parts.
+ \image robotarm-button-connections.png
+ \li Four sliders for controlling the robot arm parts individually. The \uicontrol Backend
+ component uses these sliders to control the robot arm position.
+ \li A switch to control the robot arm claw. This is also done through the
+ \uicontrol Backend component.
+ \li A switch to toggle dark mode of the application.
+ \li A label to display the status of the robot arm through the \uicontrol Backend
+ component.
+ \endlist
+ \endlist
+
+ \section2 Creating the C++ Backend
+
+ With the frontend and user interface created, it is time to create the C++ backend.
+
+ To open the project in Qt Creator:
+ \list 1
+ \li Open \c CMakeLists.txt located in the root folder of the robot arm example. This is the
+ CMake project file.
+ \li In Qt Creator, add the empty C++ backend classes in the \c backend folder.
+ \li Ensure that the \c CMakeLists.txt file in the \c backend folder has the classes in it. It
+ should look something like this:
+ \code
+ find_package(Qt6 REQUIRED COMPONENTS Gui)
+
+ qt_add_qml_module(backend
+ URI Backend
+ VERSION 1.0
+ SOURCES
+ animatedparam.cpp
+ animatedparam.h
+ backend.cpp
+ backend.h
+ )
+
+ target_link_libraries(backend PRIVATE Qt6::Gui)
+ \endcode
+ \li Add the backend logic to the created backend classes.
+ \endlist
+
+*/
diff --git a/doc/qtdesignstudio/images/bake-lights-dialog.png b/doc/qtdesignstudio/images/bake-lights-dialog.png
new file mode 100644
index 00000000000..d35599dce6a
Binary files /dev/null and b/doc/qtdesignstudio/images/bake-lights-dialog.png differ
diff --git a/doc/qtdesignstudio/images/qds-front-advanced.png b/doc/qtdesignstudio/images/qds-front-advanced.png
new file mode 100644
index 00000000000..87780aa3863
Binary files /dev/null and b/doc/qtdesignstudio/images/qds-front-advanced.png differ
diff --git a/doc/qtdesignstudio/images/qds-front-gs.png b/doc/qtdesignstudio/images/qds-front-gs.png
new file mode 100644
index 00000000000..27706a8cc6a
Binary files /dev/null and b/doc/qtdesignstudio/images/qds-front-gs.png differ
diff --git a/doc/qtdesignstudio/images/qds-front-help.png b/doc/qtdesignstudio/images/qds-front-help.png
new file mode 100644
index 00000000000..d2f9d42fece
Binary files /dev/null and b/doc/qtdesignstudio/images/qds-front-help.png differ
diff --git a/doc/qtdesignstudio/images/qds-front-preview.png b/doc/qtdesignstudio/images/qds-front-preview.png
new file mode 100644
index 00000000000..fe7aab39668
Binary files /dev/null and b/doc/qtdesignstudio/images/qds-front-preview.png differ
diff --git a/doc/qtdesignstudio/images/qds-front-projects.png b/doc/qtdesignstudio/images/qds-front-projects.png
new file mode 100644
index 00000000000..69414f48626
Binary files /dev/null and b/doc/qtdesignstudio/images/qds-front-projects.png differ
diff --git a/doc/qtdesignstudio/images/qds-front-ui.png b/doc/qtdesignstudio/images/qds-front-ui.png
new file mode 100644
index 00000000000..d413b52dbfd
Binary files /dev/null and b/doc/qtdesignstudio/images/qds-front-ui.png differ
diff --git a/doc/qtdesignstudio/images/qds-studio-3d-scenes.png b/doc/qtdesignstudio/images/qds-studio-3d-scenes.png
new file mode 100644
index 00000000000..e4774e8223e
Binary files /dev/null and b/doc/qtdesignstudio/images/qds-studio-3d-scenes.png differ
diff --git a/doc/qtdesignstudio/images/qds-studio-animation.png b/doc/qtdesignstudio/images/qds-studio-animation.png
new file mode 100644
index 00000000000..b08a6deed86
Binary files /dev/null and b/doc/qtdesignstudio/images/qds-studio-animation.png differ
diff --git a/doc/qtdesignstudio/src/components/qtquick-text.qdoc b/doc/qtdesignstudio/src/components/qtquick-text.qdoc
index f47ac82d7bd..0bb541f1c31 100644
--- a/doc/qtdesignstudio/src/components/qtquick-text.qdoc
+++ b/doc/qtdesignstudio/src/components/qtquick-text.qdoc
@@ -69,15 +69,13 @@
\c qsTrId(). Select \uicontrol Edit > \uicontrol Preferences >
\uicontrol {Qt Quick} > \uicontrol {Qt Quick Designer}, and then select the
\uicontrol {qsTrId()} radio button in the \uicontrol Internationalization
- group. For more information about text ID based translations, see
- \l {Qt Linguist Manual: Text ID Based Translations}.
+ group. For more information, see \l {Text ID based translations}.
To preserve the context when editing the text or to change the context
by setting a binding on the text property, change the default call to
\c qsTranslate() by selecting the \uicontrol {qsTranslate()} radio button.
- For more information, see
- \l {Internationalization and Localization with Qt Quick}.
+ For more information, see \l {Mark Strings for Translation}.
\section1 Character Properties
diff --git a/doc/qtdesignstudio/src/mcus/qtdesignstudio-compatibility-with-mcu-sdks.qdoc b/doc/qtdesignstudio/src/mcus/qtdesignstudio-compatibility-with-mcu-sdks.qdoc
index c6dab76398d..2a0e49cda65 100644
--- a/doc/qtdesignstudio/src/mcus/qtdesignstudio-compatibility-with-mcu-sdks.qdoc
+++ b/doc/qtdesignstudio/src/mcus/qtdesignstudio-compatibility-with-mcu-sdks.qdoc
@@ -4,7 +4,7 @@
/*!
\previouspage studio-on-mcus.html
\page studio-compatibility-with-mcu-sdks.html
- \nextpage studio-help.html
+ \nextpage studio-features-on-mcu-projects.html
\title \QDS Version Compatibility with \QMCU SDKs
diff --git a/doc/qtdesignstudio/src/mcus/qtdesignstudio-features-on-mcu-projects.qdoc b/doc/qtdesignstudio/src/mcus/qtdesignstudio-features-on-mcu-projects.qdoc
new file mode 100644
index 00000000000..5cec8d690e4
--- /dev/null
+++ b/doc/qtdesignstudio/src/mcus/qtdesignstudio-features-on-mcu-projects.qdoc
@@ -0,0 +1,129 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \previouspage studio-compatibility-with-mcu-sdks.html
+ \page studio-features-on-mcu-projects.html
+ \nextpage studio-help.html
+
+ \title \QDS Features on MCU Projects
+
+ The table below provides a summary of how the key \QDS features are supported
+ for developing MCU projects.
+
+ \table
+ \header
+ \li View
+ \li Fully Supported
+ \li Partially Supported
+ \li Not Supported
+ \li Comments
+ \row
+ \li \l 2D
+ \li \b X
+ \li \b -
+ \li \b -
+ \li A scene in the \uicontrol 2D view is rendered by the regular Qt Quick
+ and QML, and not as \QUL and \QMCU, so some imperfections or inaccuracies
+ can occur.
+ \row
+ \li \l 3D
+ \li \b -
+ \li \b -
+ \li \b X
+ \li The \uicontrol 3D view is not a part of \QUL or \QMCU.
+ \row
+ \li \l {Material Editor and Browser}
+ \li \b -
+ \li \b -
+ \li \b X
+ \li The \uicontrol {Material Editor} and \uicontrol {Material Browser} views
+ are not a part of \QUL or \QMCU.
+ \row
+ \li \l {Components}
+ \li \b X
+ \li \b -
+ \li \b -
+ \li Shows only the components and modules available for MCU projects.
+ \row
+ \li \l {Assets}
+ \li \b X
+ \li \b -
+ \li \b -
+ \li Shows all the listed assets in the \c QmlProject file.
+ \row
+ \li \l {Navigator}
+ \li \b X
+ \li \b -
+ \li \b -
+ \li Displays the composition of the current component file as a tree
+ structure.
+ \row
+ \li \l {Properties}
+ \li \b X
+ \li \b -
+ \li \b -
+ \li Shows only the preset properties available for MCU projects (such as
+ by Qt Quick and its modules).
+ \row
+ \li \l {Connections}
+ \li \b X
+ \li \b -
+ \li \b -
+ \li The \uicontrol Connections view displays all signal handlers in the
+ current file but it doesn't filter available signals, so you can still
+ see and select signals that are available in Qt Quick, but not in \QUL.
+ \row
+ \li \l {States}
+ \li \b X
+ \li \b -
+ \li \b -
+ \li The feature is fully supported as such, but there are some
+ limitations listed in \l {\QMCU Known Issues or Limitations}.
+ \row
+ \li \l {Transitions}
+ \li \b X
+ \li \b -
+ \li \b -
+ \li \b -
+ \row
+ \li \l {Translations}
+ \li \b -
+ \li \b -
+ \li \b X
+ \li \b -
+ \row
+ \li \l {Timeline}
+ \li \b X
+ \li \b -
+ \li \b -
+ \li \b -
+ \row
+ \li \l {Curves}
+ \li \b -
+ \li \b X
+ \li \b -
+ \li Linear interpolation works, but \QMCU does not support the
+ \c easing.bezierCurve property of a keyframe.
+ \row
+ \li \l Code
+ \li \b X
+ \li \b -
+ \li \b -
+ \li The \uicontrol Code view uses regular Qt Quick instead of \QUL, so it may
+ not show an error if you are using or assigning an unsupported property.
+ \row
+ \li \l {Content Library}
+ \li \b -
+ \li \b -
+ \li \b X
+ \li The \uicontrol {Content Library} view is not a part of \QUL or \QMCU.
+ \row
+ \li \l {Texture Editor}
+ \li \b -
+ \li \b -
+ \li \b X
+ \li The \uicontrol {Texture Editor} view is not a part of \QUL or \QMCU.
+ \endtable
+
+*/
diff --git a/doc/qtdesignstudio/src/overviews/qtquick-motion-design.qdoc b/doc/qtdesignstudio/src/overviews/qtquick-motion-design.qdoc
index 70ebb9115dc..382c2f5fea8 100644
--- a/doc/qtdesignstudio/src/overviews/qtquick-motion-design.qdoc
+++ b/doc/qtdesignstudio/src/overviews/qtquick-motion-design.qdoc
@@ -10,7 +10,7 @@
\table
\row
- \li \image studio-animation.png
+ \li \image qds-studio-animation.png
\li You can use different animation techniques for different
purposes. \QDS supports common motion design techniques,
such as timeline and keyframe based animation and easing
diff --git a/doc/qtdesignstudio/src/overviews/qtquick-prototyping.qdoc b/doc/qtdesignstudio/src/overviews/qtquick-prototyping.qdoc
index 2cda8239de4..af936f1507f 100644
--- a/doc/qtdesignstudio/src/overviews/qtquick-prototyping.qdoc
+++ b/doc/qtdesignstudio/src/overviews/qtquick-prototyping.qdoc
@@ -10,7 +10,7 @@
\table
\row
- \li \image studio-3d-scenes.png
+ \li \image qds-studio-3d-scenes.png
\li After your UI wireframe has been approved, you can turn it
into an interactive prototype to ensure that you and the
developers share a common vision about the UI appearance
diff --git a/doc/qtdesignstudio/src/overviews/qtquick-uis.qdoc b/doc/qtdesignstudio/src/overviews/qtquick-uis.qdoc
index 82a6f2acfa3..2f0aa723b8f 100644
--- a/doc/qtdesignstudio/src/overviews/qtquick-uis.qdoc
+++ b/doc/qtdesignstudio/src/overviews/qtquick-uis.qdoc
@@ -10,7 +10,7 @@
\table
\row
- \li \image front-ui.png
+ \li \image qds-front-ui.png
\li Plan your UI properly. Know what elements, such as screens,
components, and states, you need. Create a descriptive wireframe
and acquire a detailed UI specification before you start to make
diff --git a/doc/qtdesignstudio/src/qtdesignstudio-advanced.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-advanced.qdoc
index 21733c996ac..fbc362f6c8c 100644
--- a/doc/qtdesignstudio/src/qtdesignstudio-advanced.qdoc
+++ b/doc/qtdesignstudio/src/qtdesignstudio-advanced.qdoc
@@ -10,7 +10,7 @@
\table
\row
- \li \image front-advanced.png
+ \li \image qds-front-advanced.png
\li Learn more about the UI files (.ui.qml), collecting data about
using \QDS, and about packaging applications for delivering
them to users or uploading them to app stores.
diff --git a/doc/qtdesignstudio/src/qtdesignstudio-developer-topics.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-developer-topics.qdoc
index 845e25b0198..da1799439a4 100644
--- a/doc/qtdesignstudio/src/qtdesignstudio-developer-topics.qdoc
+++ b/doc/qtdesignstudio/src/qtdesignstudio-developer-topics.qdoc
@@ -10,7 +10,7 @@
\table
\row
- \li \image front-projects.png
+ \li \image qds-front-projects.png
\li Learn more about using the Git version control system,
converting UI projects into applications, and using
external tools directly from \QDS.
diff --git a/doc/qtdesignstudio/src/qtdesignstudio-getting-started.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-getting-started.qdoc
index 76aac701ce8..47800afab72 100644
--- a/doc/qtdesignstudio/src/qtdesignstudio-getting-started.qdoc
+++ b/doc/qtdesignstudio/src/qtdesignstudio-getting-started.qdoc
@@ -10,7 +10,7 @@
\table
\row
- \li \image front-gs.png
+ \li \image qds-front-gs.png
\li When you install \QDS, everything you need to start wireframing
and prototyping UIs is installed and set up for you. You can
move directly to learning about how to use the different \QDS
diff --git a/doc/qtdesignstudio/src/qtdesignstudio-help-overview.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-help-overview.qdoc
index e3a00cb8dfb..578129024a9 100644
--- a/doc/qtdesignstudio/src/qtdesignstudio-help-overview.qdoc
+++ b/doc/qtdesignstudio/src/qtdesignstudio-help-overview.qdoc
@@ -3,14 +3,14 @@
/*!
\page studio-help.html
- \previouspage studio-compatibility-with-mcu-sdks.html
+ \previouspage studio-features-on-mcu-projects.html
\nextpage creator-help.html
\title Help
\table
\row
- \li \image front-help.png
+ \li \image qds-front-help.png
\li Learn more about using the \uicontrol Help mode, frequently
asked questions, and supported platforms.
\endtable
diff --git a/doc/qtdesignstudio/src/qtdesignstudio-implementing-applications.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-implementing-applications.qdoc
index ace3fe41482..8c88d525426 100644
--- a/doc/qtdesignstudio/src/qtdesignstudio-implementing-applications.qdoc
+++ b/doc/qtdesignstudio/src/qtdesignstudio-implementing-applications.qdoc
@@ -10,7 +10,7 @@
\table
\row
- \li \image front-preview.png
+ \li \image qds-front-preview.png
\li \QDS attempts to meet your needs, whether you have previous
experience with QML and coding or not. When you install \QDS,
the default configuration allows you to start wireframing,
diff --git a/doc/qtdesignstudio/src/qtdesignstudio-terms.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-terms.qdoc
index 4859c20488c..d4dcb9a75ee 100644
--- a/doc/qtdesignstudio/src/qtdesignstudio-terms.qdoc
+++ b/doc/qtdesignstudio/src/qtdesignstudio-terms.qdoc
@@ -151,12 +151,11 @@
\image studio-design-mode.webp "Design mode"
- Read more about modes:
+ The mode selector is hidden by default.
- \list
- \li \l{Selecting Modes}
- \li \l{Design Views}
- \endlist
+ To show the mode selector, go to \uicontrol Views >
+ \uicontrol {Mode Selector Style} and select \uicontrol {Icons and Text}
+ or \uicontrol {Icons Only}.
\section1 Project
\target glossary-project
diff --git a/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc
index 6fc2014020f..0448079cbb4 100644
--- a/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc
+++ b/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc
@@ -12,7 +12,6 @@
\li \l{Tutorials}
\li \l{User Interface}
\list
- \li \l{Selecting Modes}
\li \l{Design Views}
\list
\li \l{2D}
@@ -203,7 +202,6 @@
\list
\li \l{Working in Edit Mode}
\list
- \li \l{Working with Sidebars}
\li \l{Browsing Project Contents}
\li \l{Viewing Output}
\endlist
@@ -262,6 +260,7 @@
\li \l{\QDS on MCUs}
\list
\li \l {\QDS Version Compatibility with \QMCU SDKs}
+ \li \l {\QDS Features on MCU Projects}
\endlist
\endlist
\li \l Help
diff --git a/doc/qtdesignstudio/src/qtdesignstudio-use-cases.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-use-cases.qdoc
index 1efb484160c..54e90305c0c 100644
--- a/doc/qtdesignstudio/src/qtdesignstudio-use-cases.qdoc
+++ b/doc/qtdesignstudio/src/qtdesignstudio-use-cases.qdoc
@@ -13,10 +13,10 @@
\table
\row
- \li \inlineimage front-ui.png
+ \li \inlineimage qds-front-ui.png
\li \inlineimage studio-flow.png
- \li \inlineimage studio-3d-scenes.png
- \li \inlineimage front-projects.png
+ \li \inlineimage qds-studio-3d-scenes.png
+ \li \inlineimage qds-front-projects.png
\row
\li \b {Creating UI wireframes}
\li \b {Creating UI prototypes}
diff --git a/doc/qtdesignstudio/src/qtdesignstudio.qdoc b/doc/qtdesignstudio/src/qtdesignstudio.qdoc
index adf772987d4..94ad24b6cc5 100644
--- a/doc/qtdesignstudio/src/qtdesignstudio.qdoc
+++ b/doc/qtdesignstudio/src/qtdesignstudio.qdoc
@@ -18,10 +18,10 @@
\table
\row
- \li \inlineimage front-gs.png
- \li \inlineimage front-ui.png
- \li \inlineimage studio-3d-scenes.png
- \li \inlineimage studio-animation.png
+ \li \inlineimage qds-front-gs.png
+ \li \inlineimage qds-front-ui.png
+ \li \inlineimage qds-studio-3d-scenes.png
+ \li \inlineimage qds-studio-animation.png
\row
\li \b {\l{Getting Started}}
\list
@@ -58,10 +58,10 @@
\li \l{Optimizing Designs}
\endlist
\row
- \li \inlineimage front-preview.png
- \li \inlineimage front-advanced.png
- \li \inlineimage front-projects.png
- \li \inlineimage front-help.png
+ \li \inlineimage qds-front-preview.png
+ \li \inlineimage qds-front-advanced.png
+ \li \inlineimage qds-front-projects.png
+ \li \inlineimage qds-front-help.png
\row
\li \b {\l{Implementing Applications}}
\list
diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc
index 1f69fe95cdf..23c998d9fcd 100644
--- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc
+++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc
@@ -313,7 +313,7 @@
\endlist
You can pause the particle animation by selecting
- \inlineimage icons/particle-animation-on.png
+ \inlineimage icons/particle-pause.png
. When the animation is paused, you can use
\inlineimage icons/particles-seek.png
to manually seek forward or backward in the particle animation.
diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc
index 8c798a31a4f..ec1de943f2b 100644
--- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc
+++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc
@@ -209,11 +209,38 @@
\uicontrol {Shadow map far} property value. Using smaller values
may improve the precision and effects of the map.
- \section1 Baking Lightmaps
+ \section1 Baked Lightmaps
\note Lightmaps baking is released as technical preview in \QDS 4.1.
- \section2 Baking Lightmaps for a 3D Model
+ Baked lightmaps allow pre-generating the direct lighting from lights such as DirectionalLight,
+ PointLight, and SpotLight, including the shadows cast by the lights. At run time, instead of
+ performing the appropriate calculations in the fragment shader, and, in case of shadows,
+ generating the potentially costly shadow maps in real time, the pre-generated light map is
+ sampled instead.
+
+ \section2 Baking Lightmaps
+
+ To bake lightmaps for models in your 3D scene:
+
+ \list 1
+ \li Right-click anywhere in the \uicontrol 3D view and select \uicontrol {Bake Lights}.
+ \li In the \uicontrol {Lights Baking Setup} dialog:
+ \list
+ \li For every light you want to use to bake lightmaps, set \uicontrol {Bake Mode} to BakeModeAll.
+ \li For every 3D model you want to bake lightmaps, select \uicontrol {In Use} and
+ \uicontrol {Enabled}, and set the desired \uicontrol {Resolution}.
+ \endlist
+ \li Optional. If you have components with unexposed models or lights (for example, imported
+ 3D models created in other software), select \uicontrol {Expose models and lights} to add the
+ models and light of that component to the \uicontrol Models and \uicontrol Lights sections of
+ the dialog.
+ \li Select \uicontrol Bake.
+ \endlist
+
+ \image bake-lights-dialog.png
+
+ \section2 Manually Baking Lightmaps for a 3D Model
Baked lightmap components are not visible in the \uicontrol Navigator view by default. To make
them visible, select \inlineimage icons/visibilityon.png
in the \uicontrol Navigator view.
@@ -239,9 +266,10 @@
\li In the \uicontrol Navigator view, select the light component that you want to bake
lightmaps for, and in the \uicontrol Properties view, set \uicontrol {Bake Mode} to BakeModeAll.
\li Right-click anywhere in the \uicontrol 3D view and select \uicontrol {Bake Lights}.
+ \li Select \uicontrol {Setup baking manually}, and then select \uicontrol Bake.
\endlist
- \section2 Baking Lightmaps for a 3D Model Inside a Sub Component
+ \section2 Manually Baking Lightmaps for a 3D Model Inside a Sub Component
To bake lightmaps for a 3D model inside a sub component, first add a local custom property to
expose the model:
@@ -299,6 +327,7 @@
a unique name.
\endlist
\li Right-click anywhere in the \uicontrol 3D view and select \uicontrol {Bake Lights}.
+ \li Select \uicontrol {Setup baking manually}, and then select \uicontrol Bake.
\endlist
*/
diff --git a/doc/qtdesignstudio/src/views/qtquick-designer.qdoc b/doc/qtdesignstudio/src/views/qtquick-designer.qdoc
index cc18d924417..1e7d58326ee 100644
--- a/doc/qtdesignstudio/src/views/qtquick-designer.qdoc
+++ b/doc/qtdesignstudio/src/views/qtquick-designer.qdoc
@@ -10,7 +10,7 @@
/*!
\page creator-using-qt-quick-designer.html
- \previouspage creator-modes.html
+ \previouspage creator-quick-tour.html
\nextpage qtquick-form-editor.html
\title Design Views
@@ -31,52 +31,65 @@
\section1 Summary of Design Views
+ In addition to the summary of design views, the table below includes an MCU
+ column that indicates the views which are fully supported on MCU projects.
+ For more information, see \l {\QDS Features on MCU Projects}.
+
\table
\header
\li View
\li Purpose
+ \li MCU
\li Read More
\row
\li \l {2D}
\li Provides a working area for designing 2D UIs.
When you are editing 3D scenes, the \uicontrol {2D} view is
used as a canvas for the 3D scene projected by the camera.
+ \li \image ok.png
\li \l {2D}
\row
\li \l {3D}
\li Provides an editor for files you created using 3D graphics
applications and stored in one of the supported formats.
+ \li
\li \l {3D}
\row
\li \l {Material Editor and Browser}
\li In the \uicontrol {Material Editor} and
\uicontrol {Material Browser} views, you create and manage materials and
textures.
+ \li
\li \l {Material Editor and Browser}
\row
\li \l Components
\li Contains preset components and your own components, that you can use
to design you application.
+ \li \image ok.png
\li \l{Using Components}
\row
\li \l Assets
\li Contains assets such as images and fonts that you can use in your
application.
+ \li \image ok.png
\li \l Assets
\row
\li \l Navigator
\li Displays the composition of the current component file as
a tree structure. A component file can contain references
to other components and assets.
+ \li \image ok.png
\li \l Navigator
\row
\li \l Properties
\li Enables you to modify the properties of the selected component.
+ \li \image ok.png
\li \l {Specifying Component Properties}
\row
\li \l{Connections}
\li Enables you to add functionality to the UI by creating
connections between components, signals, and component properties.
+ \li \image ok.png
\li \l{Working with Connections}
\row
\li \l States
@@ -84,54 +97,65 @@
Typically, states describe UI configurations, such as the
visibility and behavior of components and the available user
actions.
+ \li \image ok.png
\li \l{Working with States}
\row
\li \l{Transitions}
\li Enables you to make movement between states smooth by animating
the changes between states.
+ \li \image ok.png
\li \l{Animating Transitions Between States}
\row
\li \l Translations
\li Provides functionality to add multi-language support to your
project.
+ \li
\li \l{Translations}
\row
\li \l Timeline
\li Provides a timeline and keyframe based editor for animating
the properties of components.
+ \li \image ok.png
\li \l{Creating Timeline Animations}
\row
\li \l{Curves}
\li Enables you to view and modify the whole animation curve by
inserting keyframes to the curve and dragging them and the point
handlers to modify the curve.
+ \li
\li \l {Editing Animation Curves}
\row
\li \l{Code}
\li Provides a code editor for viewing and modifying the code
generated by the visual editors.
+ \li \image ok.png
\li \l {Working in Edit Mode}
\row
\li \l Projects
\li Shows a list of open projects and the files they contain.
+ \li \image ok.png
\li \l Projects
\row
\li \l{File System}
\li Shows all files in the currently selected directory.
+ \li \image ok.png
\li \l{File System}
\row
\li \l{Open Documents}
\li Shows currently open files.
+ \li \image ok.png
\li \l{Open Documents}
\row
\li \l{Content Library}
\li The \uicontrol {Content Library} view contains material, texture,
and environment bundles with assets that you can use in your project.
+ \li
\li \l{Content Library}
\row
\li \l{Texture Editor}
\li In the \uicontrol {Texture Editor} view, you create and manage
textures.
+ \li
\li \l{Texture Editor}
\endtable
diff --git a/qbs/modules/qtc_gtest_gmock/qtc_gtest_gmock.qbs b/qbs/modules/qtc_gtest_gmock/qtc_gtest_gmock.qbs
index 02bbb8a3022..7b1d663cf0e 100644
--- a/qbs/modules/qtc_gtest_gmock/qtc_gtest_gmock.qbs
+++ b/qbs/modules/qtc_gtest_gmock/qtc_gtest_gmock.qbs
@@ -19,7 +19,7 @@ Module {
property bool hasRepo
configure: {
- repoDir = FileInfo.cleanPath(path + "/../../../tests/unit/unittest/3rdparty/googletest");
+ repoDir = FileInfo.cleanPath(path + "/../../../tests/unit/3rdparty/googletest");
gtestDir = FileInfo.joinPaths(repoDir, "googletest");
gmockDir = FileInfo.joinPaths(repoDir, "googlemock");
hasRepo = File.exists(gtestDir);
diff --git a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml
index 7c017476cdd..12f5ebf4c15 100644
--- a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml
+++ b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml
@@ -9,6 +9,8 @@ import AssetsLibraryBackend
TreeViewDelegate {
id: root
+ property StudioTheme.ControlStyle style: StudioTheme.Values.controlStyle
+
required property Item assetsView
required property Item assetsRoot
@@ -68,6 +70,21 @@ TreeViewDelegate {
root.depth = root.initialDepth
}
+ indicator: Item {
+ implicitWidth: 20
+ implicitHeight: root.implicitHeight
+ anchors.left: bg.left
+
+ Image {
+ id: arrow
+ width: 8
+ height: 4
+ source: "image://icons/down-arrow"
+ anchors.centerIn: parent
+ rotation: root.expanded ? 0 : -90
+ }
+ }
+
background: Rectangle {
id: bg
@@ -109,7 +126,7 @@ TreeViewDelegate {
id: assetLabel
text: assetLabel.__computeText()
color: StudioTheme.Values.themeTextColor
- font.pixelSize: StudioTheme.Values.mediumFont
+ font.pixelSize: StudioTheme.Values.baseFontSize
anchors.verticalCenter: parent.verticalCenter
verticalAlignment: Qt.AlignVCenter
diff --git a/share/qtcreator/qmldesigner/contentLibraryImages/new_flag_triangle.png b/share/qtcreator/qmldesigner/contentLibraryImages/new_flag_triangle.png
new file mode 100644
index 00000000000..af282807491
Binary files /dev/null and b/share/qtcreator/qmldesigner/contentLibraryImages/new_flag_triangle.png differ
diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml
index 37154ec170b..1932af0eef9 100644
--- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml
+++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml
@@ -19,6 +19,7 @@ Item {
materialsView.closeContextMenu()
texturesView.closeContextMenu()
environmentsView.closeContextMenu()
+ effectsView.closeContextMenu()
HelperWidgets.Controller.closeContextMenu()
}
@@ -67,6 +68,7 @@ Item {
materialsView.expandVisibleSections()
texturesView.expandVisibleSections()
environmentsView.expandVisibleSections()
+ effectsView.expandVisibleSections()
}
}
@@ -76,7 +78,8 @@ Item {
height: StudioTheme.Values.toolbarHeight
tabsModel: [{name: qsTr("Materials"), icon: StudioTheme.Constants.material_medium},
{name: qsTr("Textures"), icon: StudioTheme.Constants.textures_medium},
- {name: qsTr("Environments"), icon: StudioTheme.Constants.languageList_medium}]
+ {name: qsTr("Environments"), icon: StudioTheme.Constants.languageList_medium},
+ {name: qsTr("Effects"), icon: StudioTheme.Constants.effects}]
}
}
}
@@ -98,7 +101,8 @@ Item {
searchBox: searchBox
onUnimport: (bundleMat) => {
- confirmUnimportDialog.targetBundleMaterial = bundleMat
+ confirmUnimportDialog.targetBundleItem = bundleMat
+ confirmUnimportDialog.targetBundleType = "material"
confirmUnimportDialog.open()
}
}
@@ -122,6 +126,20 @@ Item {
searchBox: searchBox
}
+
+ ContentLibraryEffectsView {
+ id: effectsView
+
+ width: root.width
+
+ searchBox: searchBox
+
+ onUnimport: (bundleItem) => {
+ confirmUnimportDialog.targetBundleItem = bundleItem
+ confirmUnimportDialog.targetBundleType = "effect"
+ confirmUnimportDialog.open()
+ }
+ }
}
}
}
diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryEffect.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryEffect.qml
new file mode 100644
index 00000000000..6230d38974e
--- /dev/null
+++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryEffect.qml
@@ -0,0 +1,90 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import QtQuick.Layouts
+import QtQuickDesignerTheme
+import HelperWidgets
+import QtQuick.Controls
+
+import StudioTheme as StudioTheme
+import ContentLibraryBackend
+
+Item {
+ id: root
+
+ signal showContextMenu()
+
+ visible: modelData.bundleItemVisible
+
+ MouseArea {
+ id: mouseArea
+
+ hoverEnabled: true
+ anchors.fill: parent
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
+
+ onPressed: (mouse) => {
+ if (mouse.button === Qt.LeftButton && !ContentLibraryBackend.effectsModel.importerRunning)
+ ContentLibraryBackend.rootView.startDragEffect(modelData, mapToGlobal(mouse.x, mouse.y))
+ else if (mouse.button === Qt.RightButton)
+ root.showContextMenu()
+ }
+ }
+
+ Column {
+ anchors.fill: parent
+ spacing: 1
+
+ Item { width: 1; height: 5 } // spacer
+
+ Image {
+ id: img
+
+ width: root.width - 10
+ height: img.width
+ anchors.horizontalCenter: parent.horizontalCenter
+ source: modelData.bundleItemIcon
+ cache: false
+
+ Rectangle { // circular indicator for imported bundle effect
+ width: 10
+ height: 10
+ radius: 5
+ anchors.right: img.right
+ anchors.top: img.top
+ anchors.margins: 5
+ color: "#00ff00"
+ border.color: "#555555"
+ border.width: 1
+ visible: modelData.bundleItemImported
+
+ ToolTip {
+ visible: indicatorMouseArea.containsMouse
+ text: qsTr("Effect is imported to project")
+ delay: 1000
+ }
+
+ MouseArea {
+ id: indicatorMouseArea
+ anchors.fill: parent
+ hoverEnabled: true
+ }
+ }
+ }
+
+ Text {
+ text: modelData.bundleItemName
+
+ width: img.width
+ clip: true
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ horizontalAlignment: TextInput.AlignHCenter
+
+ font.pixelSize: StudioTheme.Values.myFontSize
+
+ color: StudioTheme.Values.themeTextColor
+ }
+ } // Column
+}
diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryEffectContextMenu.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryEffectContextMenu.qml
new file mode 100644
index 00000000000..3abbfe88ada
--- /dev/null
+++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryEffectContextMenu.qml
@@ -0,0 +1,39 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import HelperWidgets
+import StudioControls as StudioControls
+import StudioTheme as StudioTheme
+import ContentLibraryBackend
+
+StudioControls.Menu {
+ id: root
+
+ property var targetItem: null
+
+ readonly property bool targetAvailable: targetItem && !ContentLibraryBackend.effectsModel.importerRunning
+
+ signal unimport(var bundleEff);
+
+ function popupMenu(targetItem = null)
+ {
+ this.targetItem = targetItem
+ popup()
+ }
+
+ closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside
+
+ StudioControls.MenuItem {
+ text: qsTr("Add an instance")
+ enabled: root.targetAvailable
+ onTriggered: ContentLibraryBackend.effectsModel.addInstance(root.targetItem)
+ }
+
+ StudioControls.MenuItem {
+ enabled: root.targetAvailable && root.targetItem.bundleItemImported
+ text: qsTr("Remove from project")
+
+ onTriggered: root.unimport(root.targetItem)
+ }
+}
diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryEffectsView.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryEffectsView.qml
new file mode 100644
index 00000000000..1fe8f52c134
--- /dev/null
+++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryEffectsView.qml
@@ -0,0 +1,112 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import HelperWidgets as HelperWidgets
+import StudioControls as StudioControls
+import StudioTheme as StudioTheme
+import ContentLibraryBackend
+
+HelperWidgets.ScrollView {
+ id: root
+
+ clip: true
+ interactive: !ctxMenu.opened && !ContentLibraryBackend.rootView.isDragging
+ && !HelperWidgets.Controller.contextMenuOpened
+
+ readonly property int cellWidth: 100
+ readonly property int cellHeight: 120
+
+ required property var searchBox
+
+ signal unimport(var bundleItem);
+
+ function closeContextMenu()
+ {
+ ctxMenu.close()
+ }
+
+ function expandVisibleSections()
+ {
+ for (let i = 0; i < categoryRepeater.count; ++i) {
+ let cat = categoryRepeater.itemAt(i)
+ if (cat.visible && !cat.expanded)
+ cat.expandSection()
+ }
+ }
+
+ Column {
+ ContentLibraryEffectContextMenu {
+ id: ctxMenu
+
+ onUnimport: (bundleEff) => root.unimport(bundleEff)
+ }
+
+ Repeater {
+ id: categoryRepeater
+
+ model: ContentLibraryBackend.effectsModel
+
+ delegate: HelperWidgets.Section {
+ width: root.width
+ caption: bundleCategoryName
+ addTopPadding: false
+ sectionBackgroundColor: "transparent"
+ visible: bundleCategoryVisible && !ContentLibraryBackend.effectsModel.isEmpty
+ expanded: bundleCategoryExpanded
+ expandOnClick: false
+ category: "ContentLib_Effect"
+
+ onToggleExpand: bundleCategoryExpanded = !bundleCategoryExpanded
+ onExpand: bundleCategoryExpanded = true
+ onCollapse: bundleCategoryExpanded = false
+
+ function expandSection() {
+ bundleCategoryExpanded = true
+ }
+
+ Grid {
+ width: root.width
+ leftPadding: 5
+ rightPadding: 5
+ bottomPadding: 5
+ columns: root.width / root.cellWidth
+
+ Repeater {
+ model: bundleCategoryItems
+
+ delegate: ContentLibraryEffect {
+ width: root.cellWidth
+ height: root.cellHeight
+
+ onShowContextMenu: ctxMenu.popupMenu(modelData)
+ }
+ }
+ }
+ }
+ }
+
+ Text {
+ id: infoText
+ text: {
+ if (!ContentLibraryBackend.effectsModel.bundleExists)
+ qsTr("No effects available.")
+ else if (!ContentLibraryBackend.rootView.hasQuick3DImport)
+ qsTr("To use Content Library, first add the QtQuick3D module in the Components view.")
+ else if (!ContentLibraryBackend.effectsModel.hasRequiredQuick3DImport)
+ qsTr("To use Content Library, version 6.4 or later of the QtQuick3D module is required.")
+ else if (!ContentLibraryBackend.rootView.hasMaterialLibrary)
+ qsTr("Content Library is disabled inside a non-visual component.")
+ else if (!searchBox.isEmpty())
+ qsTr("No match found.")
+ else
+ ""
+ }
+ color: StudioTheme.Values.themeTextColor
+ font.pixelSize: StudioTheme.Values.baseFontSize
+ topPadding: 10
+ leftPadding: 10
+ visible: ContentLibraryBackend.effectsModel.isEmpty
+ }
+ }
+}
diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterial.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterial.qml
index aadd4b0d991..9d723dc0ef8 100644
--- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterial.qml
+++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterial.qml
@@ -95,7 +95,7 @@ Item {
icon: StudioTheme.Constants.plus
tooltip: qsTr("Add an instance to project")
buttonSize: 22
- property color c: StudioTheme.Values.themeIconColor
+ property color c: "white"
normalColor: Qt.hsla(c.hslHue, c.hslSaturation, c.hslLightness, .2)
hoverColor: Qt.hsla(c.hslHue, c.hslSaturation, c.hslLightness, .3)
pressColor: Qt.hsla(c.hslHue, c.hslSaturation, c.hslLightness, .4)
@@ -118,7 +118,7 @@ Item {
iconColor: root.downloadState === "unavailable" || root.downloadState === "failed"
? StudioTheme.Values.themeRedLight
- : StudioTheme.Values.themeTextColor
+ : "white"
iconSize: 22
iconScale: downloadIcon.containsMouse ? 1.2 : 1
diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTexture.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTexture.qml
index 3ba94430290..6a938ed14d6 100644
--- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTexture.qml
+++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTexture.qml
@@ -20,6 +20,8 @@ Item {
property string downloadState: modelData.isDownloaded() ? "downloaded" : ""
property bool delegateVisible: modelData.textureVisible
+ property bool _isUpdating: false
+
property alias allowCancel: progressBar.closeButtonVisible
property alias progressValue: progressBar.value
property alias progressText: progressLabel.text
@@ -40,6 +42,55 @@ Item {
return qsTr("Click to download the texture.")
}
+ function startDownload(message)
+ {
+ if (root.downloadState !== "" && root.downloadState !== "failed")
+ return
+
+ root._startDownload(textureDownloader, message)
+ }
+
+ function updateTexture()
+ {
+ if (root.downloadState !== "downloaded")
+ return
+
+ root._isUpdating = true
+ root._startDownload(textureDownloader, qsTr("Updating..."))
+ }
+
+ function _startDownload(downloader, message)
+ {
+ progressBar.visible = true
+ tooltip.visible = false
+ root.progressText = message
+ root.allowCancel = true
+ root.progressValue = Qt.binding(function() { return downloader.progress })
+
+ root.downloadState = ""
+ downloader.start()
+ }
+
+ MouseArea {
+ id: mouseArea
+
+ anchors.fill: parent
+ hoverEnabled: !downloadIcon.visible
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
+
+ onEntered: tooltip.visible = image.visible
+ onExited: tooltip.visible = false
+
+ onPressed: (mouse) => {
+ if (mouse.button === Qt.LeftButton) {
+ if (root.downloadState === "downloaded")
+ ContentLibraryBackend.rootView.startDragTexture(modelData, mapToGlobal(mouse.x, mouse.y))
+ } else if (mouse.button === Qt.RightButton && root.downloadState === "downloaded") {
+ root.showContextMenu()
+ }
+ }
+ }
+
Rectangle {
id: downloadPane
anchors.fill: parent
@@ -60,7 +111,7 @@ Item {
visible: false
onCancelRequested: {
- downloader.cancel()
+ textureDownloader.cancel()
}
Text {
@@ -114,7 +165,7 @@ Item {
iconColor: root.downloadState === "unavailable" || root.downloadState === "failed"
? StudioTheme.Values.themeRedLight
- : StudioTheme.Values.themeTextColor
+ : "white"
iconSize: 22
iconScale: downloadIcon.containsMouse ? 1.2 : 1
@@ -144,20 +195,76 @@ Item {
}
onClicked: {
- if (root.downloadState !== "" && root.downloadState !== "failed")
- return
-
- progressBar.visible = true
- tooltip.visible = false
- root.progressText = qsTr("Downloading...")
- root.allowCancel = true
- root.progressValue = Qt.binding(function() { return downloader.progress })
-
- root.downloadState = ""
- downloader.start()
+ root.startDownload(qsTr("Downloading..."))
}
} // IconButton
+ IconButton {
+ id: updateButton
+ icon: StudioTheme.Constants.updateAvailable_medium
+ iconColor: "white"
+ tooltip: qsTr("Update texture")
+ buttonSize: 22
+ iconSize: 22
+
+ iconScale: updateButton.containsMouse ? 1.2 : 1
+ iconStyle: Text.Outline
+ iconStyleColor: "black"
+
+ anchors.left: parent.left
+ anchors.bottom: parent.bottom
+
+ visible: root.downloadState === "downloaded" && modelData.textureHasUpdate
+ transparentBg: true
+
+ onClicked: root.updateTexture()
+
+ Text {
+ text: StudioTheme.Constants.updateContent_medium
+ font.family: StudioTheme.Constants.iconFont.family
+ color: "black"
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 5
+
+ font.pixelSize: 10
+ font.bold: true
+
+ scale: updateButton.containsMouse ? 1.2 : 1
+ }
+ } // Update IconButton
+
+ Rectangle {
+ id: isNewFlag
+
+ width: 32
+ height: 32
+
+ visible: downloadIcon.visible && modelData.textureIsNew
+ color: "transparent"
+
+ anchors.top: parent.top
+ anchors.right: parent.right
+
+ Image {
+ source: "image://contentlibrary/new_flag_triangle.png"
+ width: 32
+ height: 32
+ }
+
+ Text {
+ color: "white"
+ font.family: StudioTheme.Constants.iconFont.family
+ text: StudioTheme.Constants.favorite
+ font.pixelSize: StudioTheme.Values.baseIconFontSize
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.topMargin: 2
+ anchors.rightMargin: 4
+ } // New texture flag
+ }
+
ToolTip {
id: tooltip
// contentWidth is not calculated correctly by the toolTip (resulting in a wider tooltip than
@@ -177,29 +284,8 @@ Item {
}
} // Image
- MouseArea {
- id: mouseArea
-
- anchors.fill: parent
- hoverEnabled: !downloadIcon.visible
- propagateComposedEvents: downloadIcon.visible
- acceptedButtons: Qt.LeftButton | Qt.RightButton
-
- onEntered: tooltip.visible = image.visible
- onExited: tooltip.visible = false
-
- onPressed: (mouse) => {
- if (mouse.button === Qt.LeftButton) {
- if (root.downloadState === "downloaded")
- ContentLibraryBackend.rootView.startDragTexture(modelData, mapToGlobal(mouse.x, mouse.y))
- } else if (mouse.button === Qt.RightButton && root.downloadState === "downloaded") {
- root.showContextMenu()
- }
- }
- }
-
FileDownloader {
- id: downloader
+ id: textureDownloader
url: image.webUrl
probeUrl: false
downloadEnabled: true
@@ -210,9 +296,9 @@ Item {
onFinishedChanged: {
root.progressText = qsTr("Extracting...")
root.allowCancel = false
- root.progressValue = Qt.binding(function() { return extractor.progress })
+ root.progressValue = Qt.binding(function() { return textureExtractor.progress })
- extractor.extract()
+ textureExtractor.extract()
}
onDownloadCanceled: {
@@ -238,14 +324,50 @@ Item {
}
FileExtractor {
- id: extractor
- archiveName: downloader.completeBaseName
- sourceFile: downloader.outputFile
+ id: textureExtractor
+ archiveName: textureDownloader.completeBaseName
+ sourceFile: textureDownloader.outputFile
targetPath: modelData.textureParentPath
alwaysCreateDir: false
clearTargetPathContents: false
onFinishedChanged: {
+ if (root._isUpdating)
+ root._startDownload(iconDownloader, qsTr("Updating..."))
+ else
+ delayedFinish.restart()
+ }
+ }
+
+ FileDownloader {
+ id: iconDownloader
+ url: modelData.textureWebIconUrl
+ probeUrl: false
+ downloadEnabled: true
+ targetFilePath: modelData.textureIconPath
+ overwriteTarget: true
+
+ onDownloadStarting: {
+ root.downloadState = "downloading"
+ }
+
+ onFinishedChanged: {
+ image.source = ""
+ image.source = modelData.textureIcon
+
+ ContentLibraryBackend.rootView.markTextureUpdated(modelData.textureKey)
+
delayedFinish.restart()
}
+
+ onDownloadCanceled: {
+ root.progressText = ""
+ root.progressValue = 0
+
+ root.downloadState = ""
+ }
+
+ onDownloadFailed: {
+ root.downloadState = "failed"
+ }
}
}
diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/UnimportBundleMaterialDialog.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/UnimportBundleMaterialDialog.qml
index a8c3758eb5b..edb6ce36707 100644
--- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/UnimportBundleMaterialDialog.qml
+++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/UnimportBundleMaterialDialog.qml
@@ -10,7 +10,7 @@ import StudioControls as StudioControls
import StudioTheme as StudioTheme
import ContentLibraryBackend
-Dialog {
+StudioControls.Dialog {
id: root
title: qsTr("Bundle material might be in use")
@@ -19,7 +19,8 @@ Dialog {
implicitWidth: 300
modal: true
- property var targetBundleMaterial
+ property var targetBundleType // "effect" or "material"
+ property var targetBundleItem
contentItem: Column {
spacing: 20
@@ -28,7 +29,8 @@ Dialog {
Text {
id: folderNotEmpty
- text: qsTr("If the material you are removing is in use, it might cause the project to malfunction.\n\nAre you sure you want to remove the material?")
+ text: qsTr("If the %1 you are removing is in use, it might cause the project to malfunction.\n\nAre you sure you want to remove the %1?")
+ .arg(root.targetBundleType)
color: StudioTheme.Values.themeTextColor
wrapMode: Text.WordWrap
anchors.right: parent.right
@@ -48,7 +50,11 @@ Dialog {
text: qsTr("Remove")
onClicked: {
- ContentLibraryBackend.materialsModel.removeFromProject(root.targetBundleMaterial)
+ if (root.targetBundleType === "material")
+ ContentLibraryBackend.materialsModel.removeFromProject(root.targetBundleItem)
+ else if (root.targetBundleType === "effect")
+ ContentLibraryBackend.effectsModel.removeFromProject(root.targetBundleItem)
+
root.accept()
}
}
diff --git a/share/qtcreator/qmldesigner/edit3dQmlSource/BakeLightsProgressDialog.qml b/share/qtcreator/qmldesigner/edit3dQmlSource/BakeLightsProgressDialog.qml
index 18494d5f327..259a0a1ab59 100644
--- a/share/qtcreator/qmldesigner/edit3dQmlSource/BakeLightsProgressDialog.qml
+++ b/share/qtcreator/qmldesigner/edit3dQmlSource/BakeLightsProgressDialog.qml
@@ -63,11 +63,14 @@ Rectangle {
}
}
- Text {
+ TextEdit {
id: progressText
width: scrollView.width
font.pixelSize: StudioTheme.Values.myFontSize
color: StudioTheme.Values.themeTextColor
+ readOnly: true
+ selectByMouse: true
+ selectByKeyboard: true
}
function ensureVisible()
diff --git a/share/qtcreator/qmldesigner/edit3dQmlSource/BakeLightsSetupDialog.qml b/share/qtcreator/qmldesigner/edit3dQmlSource/BakeLightsSetupDialog.qml
index 5924756bedf..5c202a4a60b 100644
--- a/share/qtcreator/qmldesigner/edit3dQmlSource/BakeLightsSetupDialog.qml
+++ b/share/qtcreator/qmldesigner/edit3dQmlSource/BakeLightsSetupDialog.qml
@@ -12,6 +12,8 @@ import StudioTheme as StudioTheme
Rectangle {
id: root
+ property int toolTipDelay: 1000
+
color: StudioTheme.Values.themePanelBackground
Column {
@@ -99,6 +101,7 @@ Rectangle {
hoverEnabled: true
ToolTip.visible: hovered
ToolTip.text: qsTr("The baking mode applied to this light.")
+ ToolTip.delay: root.toolTipDelay
onActivated: bakeMode = currentValue
}
@@ -112,6 +115,7 @@ Rectangle {
hoverEnabled: true
ToolTip.visible: hovered
ToolTip.text: qsTr("If checked, this model contributes to baked lighting,\nfor example in form of casting shadows or indirect light.")
+ ToolTip.delay: root.toolTipDelay
onToggled: inUse = checked
}
@@ -125,6 +129,7 @@ Rectangle {
hoverEnabled: true
ToolTip.visible: hovered
ToolTip.text: qsTr("If checked, baked lightmap texture is generated and rendered for this model.")
+ ToolTip.delay: root.toolTipDelay
onToggled: isEnabled = checked
}
@@ -155,6 +160,7 @@ Rectangle {
hoverEnabled: true
ToolTip.visible: hovered
ToolTip.text: qsTr("Generated lightmap resolution for this model.")
+ ToolTip.delay: root.toolTipDelay
onRealValueChanged: resolution = realValue
}
@@ -176,6 +182,7 @@ Rectangle {
hoverEnabled: true
ToolTip.visible: hovered
ToolTip.text: qsTr("If checked, baking settings above are not applied on close or bake.\nInstead, user is expected to set baking properties manually.")
+ ToolTip.delay: root.toolTipDelay
onToggled: rootView.manualMode = checked
}
diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialItem.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialItem.qml
index 86fec0936da..f055d1d665d 100644
--- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialItem.qml
+++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialItem.qml
@@ -24,6 +24,11 @@ Rectangle {
matName.commitRename()
}
+ function startRename()
+ {
+ matName.startRename()
+ }
+
border.width: MaterialBrowserBackend.materialBrowserModel.selectedIndex === index ? MaterialBrowserBackend.rootView.materialSectionFocused ? 3 : 1 : 0
border.color: MaterialBrowserBackend.materialBrowserModel.selectedIndex === index
? StudioTheme.Values.themeControlOutlineInteraction
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/EditableListView.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/EditableListView.qml
index b8792c71ea6..1d007e0222a 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/EditableListView.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/EditableListView.qml
@@ -24,7 +24,9 @@ Item {
property real __actionIndicatorWidth: StudioTheme.Values.squareComponentWidth
property real __actionIndicatorHeight: StudioTheme.Values.height
property string typeFilter: "QtQuick3D.Material"
- property string textRole: "idAndName"
+ // This binding is a workaround to overcome the rather long adaption to new Qt versions. This
+ // should actually be fixed in the ModelSection.qml by setting the textRole: "idAndName".
+ property string textRole: (root.typeFilter === "QtQuick3D.Material") ? "idAndName" : "id"
property string valueRole: "id"
property int activatedReason: ComboBox.ActivatedReason.Other
@@ -42,60 +44,78 @@ Item {
Layout.preferredWidth: StudioTheme.Values.height * 10
Layout.preferredHeight: myColumn.height
+ HelperWidgets.ListValidator {
+ id: listValidator
+ filterList: itemFilterModel.validationItems
+ }
+
HelperWidgets.ItemFilterModel {
id: itemFilterModel
typeFilter: root.typeFilter
modelNodeBackendProperty: modelNodeBackend
selectedItems: root.allowDuplicates ? [] : root.model
+ validationRoles: [root.textRole, root.valueRole]
}
Component {
id: myDelegate
Row {
- property alias comboBox: itemFilterComboBox
+ property alias comboBox: delegateComboBox
ListViewComboBox {
- id: itemFilterComboBox
+ id: delegateComboBox
property int myIndex: index
- property bool empty: itemFilterComboBox.initialModelData === ""
-
- validator: RegExpValidator { regExp: /(^[a-z_]\w*|^[A-Z]\w*\.{1}([a-z_]\w*\.?)+)/ }
+ property bool empty: delegateComboBox.initialModelData === ""
+ validator: listValidator
actionIndicatorVisible: false
model: itemFilterModel
initialModelData: modelData
textRole: root.textRole
valueRole: root.valueRole
implicitWidth: StudioTheme.Values.singleControlColumnWidth
- width: implicitWidth
+ width: delegateComboBox.implicitWidth
textElidable: true
onFocusChanged: {
- if (itemFilterComboBox.focus)
+ if (delegateComboBox.focus) {
myColumn.currentIndex = index
+ } else {
+ if (!delegateComboBox.dirty)
+ return
- var curValue = itemFilterComboBox.availableValue()
- if (itemFilterComboBox.empty && curValue !== "") {
- myRepeater.dirty = false
- root.add(curValue)
+ // If focus is lost check if text was changed and try to search for it in
+ // the text as well as in the value role.
+ let idx = delegateComboBox.indexOfString(delegateComboBox.editText)
+ if (idx === -1) {
+ delegateComboBox.editText = delegateComboBox.preFocusText
+ } else {
+ delegateComboBox.currentIndex = idx
+ if (delegateComboBox.empty && delegateComboBox.currentValue !== "") {
+ myRepeater.dirty = false
+ root.add(delegateComboBox.currentValue)
+ } else {
+ root.replace(delegateComboBox.myIndex, delegateComboBox.currentValue)
+ }
+ }
}
}
onCompressedActivated: function(index, reason) {
root.activatedReason = reason
- var curValue = itemFilterComboBox.availableValue()
- if (itemFilterComboBox.empty && curValue) {
+ var curValue = delegateComboBox.availableValue()
+ if (delegateComboBox.empty && curValue) {
myRepeater.dirty = false
root.add(curValue)
} else {
- root.replace(itemFilterComboBox.myIndex, curValue)
+ root.replace(delegateComboBox.myIndex, curValue)
}
}
- onHoverChanged: root.delegateHover = itemFilterComboBox.hover
+ onHoverChanged: root.delegateHover = delegateComboBox.hover
}
Spacer { implicitWidth: extraButton.visible ? 5 : StudioTheme.Values.twoControlColumnGap }
@@ -114,15 +134,17 @@ Item {
icon: StudioTheme.Constants.closeCross
onClicked: {
var lastItem = index === myRepeater.localModel.length - 1
- if (myColumn.currentItem.initialModelData === "") {
+ var tmp = myRepeater.itemAt(index)
+
+ myColumn.currentIndex = index - 1
+
+ if (tmp.comboBox.initialModelData === "") {
myRepeater.localModel.pop()
myRepeater.dirty = false
myRepeater.model = myRepeater.localModel // trigger on change handler
} else {
root.remove(index)
}
- if (!lastItem)
- myColumn.currentIndex = index - 1
}
onHoveredChanged: root.delegateHover = closeIndicator.hovered
}
@@ -152,6 +174,11 @@ Item {
myColumn.currentItem = tmp.comboBox
}
+ onCurrentItemChanged: {
+ if (myColumn.currentItem !== null)
+ myColumn.currentItem.forceActiveFocus()
+ }
+
Repeater {
id: myRepeater
@@ -162,7 +189,7 @@ Item {
onItemAdded: function(index, item) {
if (index === myColumn.currentIndex)
- myColumn.currentItem = item
+ myColumn.currentItem = item.comboBox
}
function updateModel() {
@@ -180,9 +207,7 @@ Item {
myRepeater.model = myRepeater.localModel // trigger on change handler
- if (lastIndex < 0 && myRepeater.localModel.length > 0)
- myColumn.currentIndex = 0
- else if (myRepeater.localModel.length > lastIndex)
+ if (myRepeater.localModel.length > lastIndex)
myColumn.currentIndex = lastIndex
else
myColumn.currentIndex = myRepeater.localModel.length - 1
@@ -196,28 +221,41 @@ Item {
ListViewComboBox {
id: dummyComboBox
visible: myRepeater.count === 0
- validator: RegExpValidator { regExp: /(^[a-z_]\w*|^[A-Z]\w*\.{1}([a-z_]\w*\.?)+)/ }
+ validator: listValidator
actionIndicatorVisible: false
model: itemFilterModel
textRole: root.textRole
valueRole: root.valueRole
implicitWidth: StudioTheme.Values.singleControlColumnWidth
- width: implicitWidth
+ width: dummyComboBox.implicitWidth
+
+ onVisibleChanged: dummyComboBox.currentIndex = -1
onFocusChanged: {
- var curValue = dummyComboBox.availableValue()
- if (curValue !== "")
- root.add(curValue)
+ if (dummyComboBox.focus)
+ return
+
+ if (!dummyComboBox.dirty)
+ return
+
+ // If focus is lost check if text was changed and try to search for it in
+ // the text as well as in the value role.
+ let idx = dummyComboBox.indexOfString(dummyComboBox.editText)
+ if (idx === -1) {
+ dummyComboBox.editText = dummyComboBox.preFocusText
+ } else {
+ dummyComboBox.currentIndex = idx
+ if (dummyComboBox.currentValue !== "")
+ root.add(dummyComboBox.currentValue)
+ }
}
- onCompressedActivated: {
+ onCompressedActivated: function(index, reason) {
root.activatedReason = reason
var curValue = dummyComboBox.availableValue()
if (curValue !== "")
root.add(curValue)
- else
- root.replace(dummyComboBox.myIndex, curValue)
}
onHoverChanged: root.delegateHover = dummyComboBox.hover
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/LineEdit.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/LineEdit.qml
index b73bde29310..dffe3d779ea 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/LineEdit.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/LineEdit.qml
@@ -40,7 +40,7 @@ StudioControls.TextField {
function escapeString(string) {
var str = string
str = str.replace(/\\/g, "\\\\")
- str.replace(/\"/g, "\\\"")
+ str = str.replace(/\"/g, "\\\"")
str = str.replace(/\t/g, "\\t")
str = str.replace(/\r/g, "\\r")
str = str.replace(/\n/g, '\\n')
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ListViewComboBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ListViewComboBox.qml
index 1f8dbbb3d41..3e15540d140 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ListViewComboBox.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ListViewComboBox.qml
@@ -51,4 +51,21 @@ StudioControls.ComboBox {
return root.editText
}
+
+ // Checks if the given parameter can be found as a value or text (valueRole vs. textRole). If
+ // both searches result an index !== -1 the text is preferred, otherwise index will be returned
+ // or -1 if not found.
+ // Text is preferred due to the fact that usually the users use the autocomplete functionality
+ // of an editable ComboBox hence there will be more hits on text search then on value.
+ function indexOfString(text) {
+ let textIndex = root.find(text)
+ if (textIndex !== -1)
+ return textIndex
+
+ let valueIndex = root.indexOfValue(text)
+ if (valueIndex !== -1)
+ return valueIndex
+
+ return -1
+ }
}
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/OriginControl.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/OriginControl.qml
index f4d4f7af856..e07b371cbde 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/OriginControl.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/OriginControl.qml
@@ -17,6 +17,11 @@ Row {
root.backendValue.setEnumeration("Item", value)
}
+ Connections {
+ target: modelNodeBackend
+ function onSelectionChanged() { originPopup.close() }
+ }
+
ExtendedFunctionLogic {
id: extFuncLogic
backendValue: root.backendValue
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml
index 39b1ac8a1cf..abbb32744b5 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml
@@ -34,6 +34,8 @@ T.ComboBox {
property int maximumPopupHeight: control.style.maxComboBoxPopupHeight
+ property string preFocusText: ""
+
signal compressedActivated(int index, int reason)
enum ActivatedReason { EditingFinished, Other }
@@ -53,7 +55,7 @@ T.ComboBox {
onActiveFocusChanged: {
if (control.activeFocus)
- comboBoxInput.preFocusText = control.editText
+ control.preFocusText = control.editText
}
ActionIndicator {
@@ -69,8 +71,6 @@ T.ComboBox {
contentItem: ComboBoxInput {
id: comboBoxInput
- property string preFocusText: ""
-
style: control.style
__parentControl: control
text: control.editText
@@ -332,8 +332,8 @@ T.ComboBox {
Keys.onPressed: function(event) {
if (event.key === Qt.Key_Escape) {
- control.editText = comboBoxInput.preFocusText
- control.dirty = true
+ control.editText = control.preFocusText
+ control.dirty = false
control.focus = false
}
}
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml
index 1a07944b241..f5a3bbdc7bf 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml
@@ -133,209 +133,212 @@ QtObject {
readonly property string editLightOn_medium: "\u0096"
readonly property string edit_medium: "\u0097"
readonly property string edit_small: "\u0098"
- readonly property string events_small: "\u0099"
- readonly property string export_medium: "\u009A"
- readonly property string eyeDropper: "\u009B"
- readonly property string favorite: "\u009D"
- readonly property string fitAll_medium: "\u009E"
- readonly property string fitSelected_small: "\u009F"
- readonly property string fitSelection_medium: "\u00A0"
- readonly property string fitToView_medium: "\u00A1"
- readonly property string flowAction: "\u00A2"
- readonly property string flowTransition: "\u00A3"
- readonly property string fontStyleBold: "\u00A4"
- readonly property string fontStyleItalic: "\u00A5"
- readonly property string fontStyleStrikethrough: "\u00A6"
- readonly property string fontStyleUnderline: "\u00A7"
- readonly property string forward_medium: "\u00A8"
- readonly property string globalOrient_medium: "\u00A9"
- readonly property string gradient: "\u00AA"
- readonly property string gridView: "\u00AB"
- readonly property string grid_medium: "\u00AC"
- readonly property string group_small: "\u00AE"
- readonly property string home_large: "\u00AF"
- readonly property string idAliasOff: "\u00B0"
- readonly property string idAliasOn: "\u00B1"
- readonly property string import_medium: "\u00B2"
- readonly property string imported: "\u00B3"
- readonly property string importedModels_small: "\u00B4"
- readonly property string infinity: "\u00B5"
- readonly property string invisible_medium: "\u00B6"
- readonly property string keyframe: "\u00B7"
- readonly property string languageList_medium: "\u00B8"
- readonly property string layouts_small: "\u00B9"
- readonly property string lights_small: "\u00BA"
- readonly property string linear_medium: "\u00BB"
- readonly property string linkTriangle: "\u00BC"
- readonly property string linked: "\u00BD"
- readonly property string listView: "\u00BE"
- readonly property string list_medium: "\u00BF"
- readonly property string localOrient_medium: "\u00C0"
- readonly property string lockOff: "\u00C1"
- readonly property string lockOn: "\u00C2"
- readonly property string loopPlayback_medium: "\u00C3"
- readonly property string materialBrowser_medium: "\u00C4"
- readonly property string materialPreviewEnvironment: "\u00C5"
- readonly property string materialPreviewModel: "\u00C6"
- readonly property string material_medium: "\u00C7"
- readonly property string mergeCells: "\u00C8"
- readonly property string merge_small: "\u00C9"
- readonly property string minus: "\u00CA"
- readonly property string mirror: "\u00CB"
- readonly property string more_medium: "\u00CC"
- readonly property string mouseArea_small: "\u00CD"
- readonly property string moveDown_medium: "\u00CE"
- readonly property string moveInwards_medium: "\u00CF"
- readonly property string moveUp_medium: "\u00D0"
- readonly property string moveUpwards_medium: "\u00D1"
- readonly property string move_medium: "\u00D2"
- readonly property string newMaterial: "\u00D3"
- readonly property string nextFile_large: "\u00D4"
- readonly property string openLink: "\u00D5"
- readonly property string openMaterialBrowser: "\u00D6"
- readonly property string orientation: "\u00D7"
- readonly property string orthCam_medium: "\u00D8"
- readonly property string orthCam_small: "\u00D9"
- readonly property string paddingEdge: "\u00DA"
- readonly property string paddingFrame: "\u00DB"
- readonly property string particleAnimation_medium: "\u00DC"
- readonly property string pasteStyle: "\u00DD"
- readonly property string paste_small: "\u00DE"
- readonly property string pause: "\u00DF"
- readonly property string perspectiveCam_medium: "\u00E0"
- readonly property string perspectiveCam_small: "\u00E1"
- readonly property string pin: "\u00E2"
- readonly property string plane_medium: "\u00E3"
- readonly property string plane_small: "\u00E4"
- readonly property string play: "\u00E5"
- readonly property string playFill_medium: "\u00E6"
- readonly property string playOutline_medium: "\u00E7"
- readonly property string plus: "\u00E8"
- readonly property string pointLight_small: "\u00E9"
- readonly property string positioners_small: "\u00EA"
- readonly property string previewEnv_medium: "\u00EB"
- readonly property string previousFile_large: "\u00EC"
- readonly property string promote: "\u00ED"
- readonly property string properties_medium: "\u00EE"
- readonly property string readOnly: "\u00EF"
- readonly property string recordFill_medium: "\u00F0"
- readonly property string recordOutline_medium: "\u00F1"
- readonly property string redo: "\u00F2"
- readonly property string reload_medium: "\u00F3"
- readonly property string remove_medium: "\u00F4"
- readonly property string remove_small: "\u00F5"
- readonly property string rename_small: "\u00F6"
- readonly property string replace_small: "\u00F7"
- readonly property string resetView_small: "\u00F8"
- readonly property string restartParticles_medium: "\u00F9"
- readonly property string reverseOrder_medium: "\u00FA"
- readonly property string roatate_medium: "\u00FB"
- readonly property string rotationFill: "\u00FC"
- readonly property string rotationOutline: "\u00FD"
- readonly property string runProjFill_large: "\u00FE"
- readonly property string runProjOutline_large: "\u00FF"
- readonly property string s_anchors: "\u0100"
- readonly property string s_annotations: "\u0101"
- readonly property string s_arrange: "\u0102"
- readonly property string s_boundingBox: "\u0103"
- readonly property string s_component: "\u0104"
- readonly property string s_connections: "\u0105"
- readonly property string s_edit: "\u0106"
- readonly property string s_enterComponent: "\u0107"
- readonly property string s_eventList: "\u0108"
- readonly property string s_group: "\u0109"
- readonly property string s_layouts: "\u010A"
- readonly property string s_merging: "\u010B"
- readonly property string s_mouseArea: "\u010C"
- readonly property string s_positioners: "\u010D"
- readonly property string s_selection: "\u010E"
- readonly property string s_snapping: "\u010F"
- readonly property string s_timeline: "\u0110"
- readonly property string s_visibility: "\u0111"
- readonly property string saveLogs_medium: "\u0112"
- readonly property string scale_medium: "\u0113"
- readonly property string search: "\u0114"
- readonly property string search_small: "\u0115"
- readonly property string sectionToggle: "\u0116"
- readonly property string selectFill_medium: "\u0117"
- readonly property string selectOutline_medium: "\u0118"
- readonly property string selectParent_small: "\u0119"
- readonly property string selection_small: "\u011A"
- readonly property string settings_medium: "\u011B"
- readonly property string signal_small: "\u011C"
- readonly property string snapping_small: "\u011D"
- readonly property string sphere_medium: "\u011E"
- readonly property string sphere_small: "\u011F"
- readonly property string splitColumns: "\u0120"
- readonly property string splitRows: "\u0121"
- readonly property string spotLight_small: "\u0122"
- readonly property string stackedContainer_small: "\u0123"
- readonly property string startNode: "\u0124"
- readonly property string step_medium: "\u0125"
- readonly property string stop_medium: "\u0126"
- readonly property string testIcon: "\u0127"
- readonly property string textAlignBottom: "\u0128"
- readonly property string textAlignCenter: "\u0129"
- readonly property string textAlignJustified: "\u012A"
- readonly property string textAlignLeft: "\u012B"
- readonly property string textAlignMiddle: "\u012C"
- readonly property string textAlignRight: "\u012D"
- readonly property string textAlignTop: "\u012E"
- readonly property string textBulletList: "\u012F"
- readonly property string textFullJustification: "\u0130"
- readonly property string textNumberedList: "\u0131"
- readonly property string textures_medium: "\u0132"
- readonly property string tickIcon: "\u0133"
- readonly property string tickMark_small: "\u0134"
- readonly property string timeline_small: "\u0135"
- readonly property string toEndFrame_medium: "\u0136"
- readonly property string toNextFrame_medium: "\u0137"
- readonly property string toPrevFrame_medium: "\u0138"
- readonly property string toStartFrame_medium: "\u0139"
- readonly property string topToolbar_annotations: "\u013A"
- readonly property string topToolbar_closeFile: "\u013B"
- readonly property string topToolbar_designMode: "\u013C"
- readonly property string topToolbar_enterComponent: "\u013D"
- readonly property string topToolbar_home: "\u013E"
- readonly property string topToolbar_makeComponent: "\u013F"
- readonly property string topToolbar_navFile: "\u0140"
- readonly property string topToolbar_runProject: "\u0141"
- readonly property string translationCreateFiles: "\u0142"
- readonly property string translationCreateReport: "\u0143"
- readonly property string translationExport: "\u0144"
- readonly property string translationImport: "\u0145"
- readonly property string translationSelectLanguages: "\u0146"
- readonly property string translationTest: "\u0147"
- readonly property string transparent: "\u0148"
- readonly property string triState: "\u0149"
- readonly property string triangleArcA: "\u014A"
- readonly property string triangleArcB: "\u014B"
- readonly property string triangleCornerA: "\u014C"
- readonly property string triangleCornerB: "\u014D"
- readonly property string unLinked: "\u014E"
- readonly property string undo: "\u014F"
- readonly property string unify_medium: "\u0150"
- readonly property string unpin: "\u0151"
- readonly property string upDownIcon: "\u0152"
- readonly property string upDownSquare2: "\u0153"
- readonly property string visibilityOff: "\u0154"
- readonly property string visibilityOn: "\u0155"
- readonly property string visible_medium: "\u0156"
- readonly property string visible_small: "\u0157"
- readonly property string wildcard: "\u0158"
- readonly property string wizardsAutomotive: "\u0159"
- readonly property string wizardsDesktop: "\u015A"
- readonly property string wizardsGeneric: "\u015B"
- readonly property string wizardsMcuEmpty: "\u015C"
- readonly property string wizardsMcuGraph: "\u015D"
- readonly property string wizardsMobile: "\u015E"
- readonly property string wizardsUnknown: "\u015F"
- readonly property string zoomAll: "\u0160"
- readonly property string zoomIn: "\u0161"
- readonly property string zoomIn_medium: "\u0162"
- readonly property string zoomOut: "\u0163"
- readonly property string zoomOut_medium: "\u0164"
- readonly property string zoomSelection: "\u0165"
+ readonly property string effects: "\u0099"
+ readonly property string events_small: "\u009A"
+ readonly property string export_medium: "\u009B"
+ readonly property string eyeDropper: "\u009D"
+ readonly property string favorite: "\u009E"
+ readonly property string fitAll_medium: "\u009F"
+ readonly property string fitSelected_small: "\u00A0"
+ readonly property string fitSelection_medium: "\u00A1"
+ readonly property string fitToView_medium: "\u00A2"
+ readonly property string flowAction: "\u00A3"
+ readonly property string flowTransition: "\u00A4"
+ readonly property string fontStyleBold: "\u00A5"
+ readonly property string fontStyleItalic: "\u00A6"
+ readonly property string fontStyleStrikethrough: "\u00A7"
+ readonly property string fontStyleUnderline: "\u00A8"
+ readonly property string forward_medium: "\u00A9"
+ readonly property string globalOrient_medium: "\u00AA"
+ readonly property string gradient: "\u00AB"
+ readonly property string gridView: "\u00AC"
+ readonly property string grid_medium: "\u00AE"
+ readonly property string group_small: "\u00AF"
+ readonly property string home_large: "\u00B0"
+ readonly property string idAliasOff: "\u00B1"
+ readonly property string idAliasOn: "\u00B2"
+ readonly property string import_medium: "\u00B3"
+ readonly property string imported: "\u00B4"
+ readonly property string importedModels_small: "\u00B5"
+ readonly property string infinity: "\u00B6"
+ readonly property string invisible_medium: "\u00B7"
+ readonly property string keyframe: "\u00B8"
+ readonly property string languageList_medium: "\u00B9"
+ readonly property string layouts_small: "\u00BA"
+ readonly property string lights_small: "\u00BB"
+ readonly property string linear_medium: "\u00BC"
+ readonly property string linkTriangle: "\u00BD"
+ readonly property string linked: "\u00BE"
+ readonly property string listView: "\u00BF"
+ readonly property string list_medium: "\u00C0"
+ readonly property string localOrient_medium: "\u00C1"
+ readonly property string lockOff: "\u00C2"
+ readonly property string lockOn: "\u00C3"
+ readonly property string loopPlayback_medium: "\u00C4"
+ readonly property string materialBrowser_medium: "\u00C5"
+ readonly property string materialPreviewEnvironment: "\u00C6"
+ readonly property string materialPreviewModel: "\u00C7"
+ readonly property string material_medium: "\u00C8"
+ readonly property string mergeCells: "\u00C9"
+ readonly property string merge_small: "\u00CA"
+ readonly property string minus: "\u00CB"
+ readonly property string mirror: "\u00CC"
+ readonly property string more_medium: "\u00CD"
+ readonly property string mouseArea_small: "\u00CE"
+ readonly property string moveDown_medium: "\u00CF"
+ readonly property string moveInwards_medium: "\u00D0"
+ readonly property string moveUp_medium: "\u00D1"
+ readonly property string moveUpwards_medium: "\u00D2"
+ readonly property string move_medium: "\u00D3"
+ readonly property string newMaterial: "\u00D4"
+ readonly property string nextFile_large: "\u00D5"
+ readonly property string openLink: "\u00D6"
+ readonly property string openMaterialBrowser: "\u00D7"
+ readonly property string orientation: "\u00D8"
+ readonly property string orthCam_medium: "\u00D9"
+ readonly property string orthCam_small: "\u00DA"
+ readonly property string paddingEdge: "\u00DB"
+ readonly property string paddingFrame: "\u00DC"
+ readonly property string particleAnimation_medium: "\u00DD"
+ readonly property string pasteStyle: "\u00DE"
+ readonly property string paste_small: "\u00DF"
+ readonly property string pause: "\u00E0"
+ readonly property string perspectiveCam_medium: "\u00E1"
+ readonly property string perspectiveCam_small: "\u00E2"
+ readonly property string pin: "\u00E3"
+ readonly property string plane_medium: "\u00E4"
+ readonly property string plane_small: "\u00E5"
+ readonly property string play: "\u00E6"
+ readonly property string playFill_medium: "\u00E7"
+ readonly property string playOutline_medium: "\u00E8"
+ readonly property string plus: "\u00E9"
+ readonly property string pointLight_small: "\u00EA"
+ readonly property string positioners_small: "\u00EB"
+ readonly property string previewEnv_medium: "\u00EC"
+ readonly property string previousFile_large: "\u00ED"
+ readonly property string promote: "\u00EE"
+ readonly property string properties_medium: "\u00EF"
+ readonly property string readOnly: "\u00F0"
+ readonly property string recordFill_medium: "\u00F1"
+ readonly property string recordOutline_medium: "\u00F2"
+ readonly property string redo: "\u00F3"
+ readonly property string reload_medium: "\u00F4"
+ readonly property string remove_medium: "\u00F5"
+ readonly property string remove_small: "\u00F6"
+ readonly property string rename_small: "\u00F7"
+ readonly property string replace_small: "\u00F8"
+ readonly property string resetView_small: "\u00F9"
+ readonly property string restartParticles_medium: "\u00FA"
+ readonly property string reverseOrder_medium: "\u00FB"
+ readonly property string roatate_medium: "\u00FC"
+ readonly property string rotationFill: "\u00FD"
+ readonly property string rotationOutline: "\u00FE"
+ readonly property string runProjFill_large: "\u00FF"
+ readonly property string runProjOutline_large: "\u0100"
+ readonly property string s_anchors: "\u0101"
+ readonly property string s_annotations: "\u0102"
+ readonly property string s_arrange: "\u0103"
+ readonly property string s_boundingBox: "\u0104"
+ readonly property string s_component: "\u0105"
+ readonly property string s_connections: "\u0106"
+ readonly property string s_edit: "\u0107"
+ readonly property string s_enterComponent: "\u0108"
+ readonly property string s_eventList: "\u0109"
+ readonly property string s_group: "\u010A"
+ readonly property string s_layouts: "\u010B"
+ readonly property string s_merging: "\u010C"
+ readonly property string s_mouseArea: "\u010D"
+ readonly property string s_positioners: "\u010E"
+ readonly property string s_selection: "\u010F"
+ readonly property string s_snapping: "\u0110"
+ readonly property string s_timeline: "\u0111"
+ readonly property string s_visibility: "\u0112"
+ readonly property string saveLogs_medium: "\u0113"
+ readonly property string scale_medium: "\u0114"
+ readonly property string search: "\u0115"
+ readonly property string search_small: "\u0116"
+ readonly property string sectionToggle: "\u0117"
+ readonly property string selectFill_medium: "\u0118"
+ readonly property string selectOutline_medium: "\u0119"
+ readonly property string selectParent_small: "\u011A"
+ readonly property string selection_small: "\u011B"
+ readonly property string settings_medium: "\u011C"
+ readonly property string signal_small: "\u011D"
+ readonly property string snapping_small: "\u011E"
+ readonly property string sphere_medium: "\u011F"
+ readonly property string sphere_small: "\u0120"
+ readonly property string splitColumns: "\u0121"
+ readonly property string splitRows: "\u0122"
+ readonly property string spotLight_small: "\u0123"
+ readonly property string stackedContainer_small: "\u0124"
+ readonly property string startNode: "\u0125"
+ readonly property string step_medium: "\u0126"
+ readonly property string stop_medium: "\u0127"
+ readonly property string testIcon: "\u0128"
+ readonly property string textAlignBottom: "\u0129"
+ readonly property string textAlignCenter: "\u012A"
+ readonly property string textAlignJustified: "\u012B"
+ readonly property string textAlignLeft: "\u012C"
+ readonly property string textAlignMiddle: "\u012D"
+ readonly property string textAlignRight: "\u012E"
+ readonly property string textAlignTop: "\u012F"
+ readonly property string textBulletList: "\u0130"
+ readonly property string textFullJustification: "\u0131"
+ readonly property string textNumberedList: "\u0132"
+ readonly property string textures_medium: "\u0133"
+ readonly property string tickIcon: "\u0134"
+ readonly property string tickMark_small: "\u0135"
+ readonly property string timeline_small: "\u0136"
+ readonly property string toEndFrame_medium: "\u0137"
+ readonly property string toNextFrame_medium: "\u0138"
+ readonly property string toPrevFrame_medium: "\u0139"
+ readonly property string toStartFrame_medium: "\u013A"
+ readonly property string topToolbar_annotations: "\u013B"
+ readonly property string topToolbar_closeFile: "\u013C"
+ readonly property string topToolbar_designMode: "\u013D"
+ readonly property string topToolbar_enterComponent: "\u013E"
+ readonly property string topToolbar_home: "\u013F"
+ readonly property string topToolbar_makeComponent: "\u0140"
+ readonly property string topToolbar_navFile: "\u0141"
+ readonly property string topToolbar_runProject: "\u0142"
+ readonly property string translationCreateFiles: "\u0143"
+ readonly property string translationCreateReport: "\u0144"
+ readonly property string translationExport: "\u0145"
+ readonly property string translationImport: "\u0146"
+ readonly property string translationSelectLanguages: "\u0147"
+ readonly property string translationTest: "\u0148"
+ readonly property string transparent: "\u0149"
+ readonly property string triState: "\u014A"
+ readonly property string triangleArcA: "\u014B"
+ readonly property string triangleArcB: "\u014C"
+ readonly property string triangleCornerA: "\u014D"
+ readonly property string triangleCornerB: "\u014E"
+ readonly property string unLinked: "\u014F"
+ readonly property string undo: "\u0150"
+ readonly property string unify_medium: "\u0151"
+ readonly property string unpin: "\u0152"
+ readonly property string upDownIcon: "\u0153"
+ readonly property string upDownSquare2: "\u0154"
+ readonly property string updateAvailable_medium: "\u0155"
+ readonly property string updateContent_medium: "\u0156"
+ readonly property string visibilityOff: "\u0157"
+ readonly property string visibilityOn: "\u0158"
+ readonly property string visible_medium: "\u0159"
+ readonly property string visible_small: "\u015A"
+ readonly property string wildcard: "\u015B"
+ readonly property string wizardsAutomotive: "\u015C"
+ readonly property string wizardsDesktop: "\u015D"
+ readonly property string wizardsGeneric: "\u015E"
+ readonly property string wizardsMcuEmpty: "\u015F"
+ readonly property string wizardsMcuGraph: "\u0160"
+ readonly property string wizardsMobile: "\u0161"
+ readonly property string wizardsUnknown: "\u0162"
+ readonly property string zoomAll: "\u0163"
+ readonly property string zoomIn: "\u0164"
+ readonly property string zoomIn_medium: "\u0165"
+ readonly property string zoomOut: "\u0166"
+ readonly property string zoomOut_medium: "\u0167"
+ readonly property string zoomSelection: "\u0168"
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 1b1821ae999..3c3fa3bd67d 100644
Binary files a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf and b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf differ
diff --git a/share/qtcreator/qmldesigner/qt4mcu/qul-24.qml b/share/qtcreator/qmldesigner/qt4mcu/qul-24.qml
index f78b00b8c65..1c5d00a33f3 100644
--- a/share/qtcreator/qmldesigner/qt4mcu/qul-24.qml
+++ b/share/qtcreator/qmldesigner/qt4mcu/qul-24.qml
@@ -207,4 +207,8 @@ VersionData {
bannedProperties: ["dashOffset", "dashPattern",
"fillGradient", "strokeStyle"]
}
+
+ QtQuickUltralite.Extras.ItemBuffer {
+ allowedProperties: ["rotation", "scale", "transformOrigin"]
+ }
}
diff --git a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml
deleted file mode 100644
index 3f42fb75117..00000000000
--- a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml
+++ /dev/null
@@ -1,296 +0,0 @@
-// Copyright (C) 2020 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-import QtQuick 2.15
-import QtQuick.Layouts 1.15
-import QtQuickDesignerTheme 1.0
-import HelperWidgets 2.0
-import StudioControls 1.0 as StudioControls
-import StudioTheme 1.0 as StudioTheme
-
-Rectangle {
- id: myRoot
-
- property bool isBaseState
- property bool isCurrentState
- property string delegateStateName
- property string delegateStateImageSource
- property bool delegateHasWhenCondition
- property string delegateWhenConditionString
- property bool hasAnnotation: checkAnnotation()
- property int topAreaHeight
- property int bottomAreaHeight
- property int stateMargin
- property int previewMargin
-
- readonly property bool isDefaultState: isDefault
-
- property int closeButtonMargin: 6
- property int textFieldMargin: 4
-
- property int scrollBarH: 0
- property int listMargin: 0
-
- function autoComplete(text, pos, explicitComplete, filter) {
- var stringList = statesEditorModel.autoComplete(text, pos, explicitComplete)
- return stringList
- }
-
- function checkAnnotation() {
- return statesEditorModel.hasAnnotation(internalNodeId)
- }
-
- color: isCurrentState ? StudioTheme.Values.themeInteraction
- : StudioTheme.Values.themeControlBackgroundInteraction
- MouseArea {
- id: mouseArea
- anchors.fill: parent
-
- onClicked: {
- focus = true
- root.currentStateInternalId = internalNodeId
- contextMenu.dismiss() // close potentially open context menu
- }
- }
-
- StudioControls.AbstractButton {
- id: removeStateButton
-
- buttonIcon: StudioTheme.Constants.closeCross
-
- anchors.right: parent.right
- anchors.rightMargin: myRoot.closeButtonMargin
- anchors.top: parent.top
- anchors.topMargin: myRoot.closeButtonMargin
-
- visible: !isBaseState && isCurrentState
-
- onClicked: {
- if (isDefaultState)
- statesEditorModel.resetDefaultState()
-
- root.deleteState(internalNodeId)
- }
- }
-
- StudioControls.Menu {
- id: contextMenu
-
- StudioControls.MenuItem {
- enabled: !isBaseState
- text: qsTr("Set when Condition")
- onTriggered: {
- bindingEditor.showWidget()
- bindingEditor.text = delegateWhenConditionString
- bindingEditor.prepareBindings()
- bindingEditor.updateWindowName()
- }
- }
-
- StudioControls.MenuItem {
- enabled: !isBaseState && delegateHasWhenCondition
- text: qsTr("Reset when Condition")
- onTriggered: {
- statesEditorModel.resetWhenCondition(internalNodeId)
- }
- }
-
- StudioControls.MenuItem {
- enabled: !isBaseState && !isDefaultState
- text: qsTr("Set as Default")
- onTriggered: {
- statesEditorModel.setStateAsDefault(internalNodeId)
- }
- }
-
- StudioControls.MenuItem {
- enabled: (!isBaseState && isDefaultState) || (isBaseState && modelHasDefaultState)
- text: qsTr("Reset Default")
- onTriggered: {
- statesEditorModel.resetDefaultState()
- }
- }
-
- StudioControls.MenuItem {
- enabled: !isBaseState
- text: (hasAnnotation ? qsTr("Edit Annotation")
- : qsTr("Add Annotation"))
- onTriggered: {
- statesEditorModel.setAnnotation(internalNodeId)
- hasAnnotation = checkAnnotation()
- }
- }
-
- StudioControls.MenuItem {
- enabled: !isBaseState && hasAnnotation
- text: qsTr("Remove Annotation")
- onTriggered: {
- statesEditorModel.removeAnnotation(internalNodeId)
- hasAnnotation = checkAnnotation()
- }
- }
-
- onClosed: {
- stateNameField.actionIndicator.forceVisible = false
- }
-
- onOpened: {
- hasAnnotation = checkAnnotation()
- myRoot.delegateInteraction()
- }
- }
-
- Column {
- id: column
-
- anchors.margins: myRoot.stateMargin
- anchors.fill: parent
-
- Rectangle {
- width: myRoot.width - 2 * myRoot.stateMargin
- height: myRoot.topAreaHeight
-
- color: StudioTheme.Values.themeStateBackground
-
- StudioControls.TextField {
- id: stateNameField
-
- property string oldValue
-
- width: StudioTheme.Values.height * 5.5
-
- anchors.top: parent.top
- anchors.topMargin: myRoot.textFieldMargin
- anchors.left: parent.left
- anchors.leftMargin: myRoot.textFieldMargin
-
- translationIndicatorVisible: false
- readOnly: isBaseState
-
- actionIndicator.icon.text: delegateHasWhenCondition
- ? StudioTheme.Constants.actionIconBinding
- : StudioTheme.Constants.actionIcon
-
-
- actionIndicator.onClicked: {
- stateNameField.actionIndicator.forceVisible = true
- contextMenu.popup()
- }
-
- onEditChanged: {
- if (contextMenu.open && stateNameField.edit)
- contextMenu.dismiss()
- }
-
- onActiveFocusChanged: {
- if (activeFocus)
- root.currentStateInternalId = internalNodeId
- }
-
- onEditingFinished: {
- if (stateNameField.oldValue === stateNameField.text)
- return
-
- stateNameField.oldValue = stateNameField.text
-
- if (stateNameField.text !== myRoot.delegateStateName)
- statesEditorModel.renameState(internalNodeId, stateNameField.text)
- }
-
- Component.onCompleted: {
- text = myRoot.delegateStateName
- }
-
- //QDS-5649:
- Keys.priority: Keys.BeforeItem
- Keys.onEscapePressed: function (event) {
- event.accepted = true
- stateNameField.text = myRoot.delegateStateName
- stateNameField.focus = false
- }
- }
-
- Text {
- id: stateDefaultIndicator
-
- anchors.right: parent.right
- anchors.rightMargin: myRoot.previewMargin
- anchors.verticalCenter: stateNameField.verticalCenter
-
- color: StudioTheme.Values.themeTextColor
- font.italic: true
- font.pixelSize: StudioTheme.Values.myFontSize
- font.family: StudioTheme.Constants.font
-
- visible: isDefaultState || (isBaseState && !modelHasDefaultState)
-
- text: qsTr("Default")
- }
- }
-
- Rectangle { // separator
- width: column.width
- height: 2
- color: StudioTheme.Values.themeStateSeparator
- }
-
- Rectangle {
- id: stateImageArea
- width: myRoot.width - 2 * myRoot.stateMargin
- height: myRoot.bottomAreaHeight
- color: StudioTheme.Values.themeStateBackground
-
- Image {
- anchors.fill: stateImageBackground
- source: "images/checkers.png"
- fillMode: Image.Tile
- }
-
- Rectangle {
- id: stateImageBackground
- anchors.centerIn: parent
- width: Math.round(stateImage.paintedWidth) + 2 * StudioTheme.Values.border
- height: Math.round(stateImage.paintedHeight) + 2 * StudioTheme.Values.border
- color: "transparent"
- border.width: StudioTheme.Values.border
- border.color: StudioTheme.Values.themeStatePreviewOutline
- }
-
- Image {
- id: stateImage
- anchors.margins: myRoot.previewMargin
- anchors.centerIn: parent
- anchors.fill: parent
- source: delegateStateImageSource
- fillMode: Image.PreserveAspectFit
- mipmap: true
- }
- }
- }
-
- BindingEditor {
- id: bindingEditor
-
- property string newWhenCondition
-
- property Timer timer: Timer {
- id: timer
- running: false
- interval: 50
- repeat: false
- onTriggered: statesEditorModel.setWhenCondition(internalNodeId, bindingEditor.newWhenCondition)
- }
-
- stateModelNodeProperty: statesEditorModel.stateModelNode()
- stateNameProperty: myRoot.delegateStateName
-
- onRejected: {
- hideWidget()
- }
- onAccepted: {
- bindingEditor.newWhenCondition = bindingEditor.text.trim()
- timer.start()
- hideWidget()
- }
- }
-}
diff --git a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesList.qml b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesList.qml
deleted file mode 100644
index e56d7419099..00000000000
--- a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesList.qml
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright (C) 2020 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-import QtQuick 2.15
-import QtQuick.Controls 2.15
-import QtQuickDesignerTheme 1.0
-import Qt.labs.qmlmodels 1.0
-import HelperWidgets 2.0
-import StudioControls 1.0 as StudioControls
-import StudioTheme 1.0 as StudioTheme
-
-FocusScope {
- id: root
-
- readonly property int delegateTopAreaHeight: StudioTheme.Values.height + 8
- readonly property int delegateBottomAreaHeight: delegateHeight - 2 * delegateStateMargin - delegateTopAreaHeight - 2
- readonly property int delegateStateMargin: 16
- readonly property int delegatePreviewMargin: 10
- readonly property int effectiveHeight: root.height < 130 ? 89 : Math.min(root.height, 287)
-
- readonly property int scrollBarH: statesListView.ScrollBar.horizontal.scrollBarVisible ? StudioTheme.Values.scrollBarThickness : 0
- readonly property int listMargin: 10
- readonly property int delegateWidth: 264
- readonly property int delegateHeight: Math.max(effectiveHeight - scrollBarH - 2 * listMargin, 69)
- readonly property int innerSpacing: 2
-
- property int currentStateInternalId: 0
-
- signal createNewState
- signal deleteState(int internalNodeId)
- signal duplicateCurrentState
-
- Connections {
- target: statesEditorModel
- function onChangedToState(n) { root.currentStateInternalId = n }
- }
-
- Rectangle {
- id: background
- anchors.fill: parent
- color: StudioTheme.Values.themePanelBackground
- }
-
- AbstractButton {
- id: addStateButton
-
- buttonIcon: StudioTheme.Constants.plus
- iconFont: StudioTheme.Constants.iconFont
- iconSize: StudioTheme.Values.myIconFontSize
- tooltip: qsTr("Add a new state.")
- visible: canAddNewStates
- anchors.right: parent.right
- anchors.rightMargin: 4
- anchors.bottom: parent.bottom
- anchors.bottomMargin: statesListView.contentWidth - statesListView.contentX - root.delegateWidth / 2 > statesListView.width ? scrollBarH + 5 : -35
- width: 35
- height: 35
-
- Behavior on anchors.bottomMargin {
- PropertyAnimation {
- duration: 700
- easing.type: Easing.InOutBack
- }
- }
-
- onClicked: root.createNewState()
- }
-
- ListView {
- id: statesListView
-
- clip: true
- anchors.fill: parent
- anchors.topMargin: listMargin
- anchors.leftMargin: listMargin
- anchors.rightMargin: listMargin
-
- model: statesEditorModel
- orientation: ListView.Horizontal
- spacing: root.innerSpacing
-
- property int prevCount: 0
- onCountChanged: {
- if (count > prevCount)
- Qt.callLater(statesListView.positionViewAtEnd)
- prevCount = count
- }
-
- delegate: DelegateChooser {
- role: "type"
-
- DelegateChoice {
- roleValue: "state"
-
- StatesDelegate {
- width: root.delegateWidth
- height: root.delegateHeight
- anchors.verticalCenter: parent ? parent.verticalCenter : undefined
- anchors.verticalCenterOffset: -.5 * (scrollBarH + listMargin)
- isBaseState: 0 === internalNodeId
- isCurrentState: root.currentStateInternalId === internalNodeId
- delegateStateName: stateName
- delegateStateImageSource: stateImageSource
- delegateHasWhenCondition: hasWhenCondition
- delegateWhenConditionString: whenConditionString
-
- topAreaHeight: root.delegateTopAreaHeight
- bottomAreaHeight: root.delegateBottomAreaHeight
- stateMargin: root.delegateStateMargin
- previewMargin: root.delegatePreviewMargin
- scrollBarH: root.scrollBarH
- listMargin: root.listMargin
- }
- }
-
- DelegateChoice {
- roleValue: "add"
-
- Rectangle {
- visible: canAddNewStates
-
- width: root.delegateWidth
- height: root.delegateHeight
- anchors.verticalCenter: parent ? parent.verticalCenter : undefined
- anchors.verticalCenterOffset: -.5 * (scrollBarH + listMargin)
- color: Qt.lighter(StudioTheme.Values.themeControlBackgroundInteraction, addState.containsMouse ? 1.5 : 1)
-
- ToolTip.text: qsTr("Add a new state.")
- ToolTip.visible: addState.containsMouse
- ToolTip.delay: 1000
-
- Rectangle { // inner rect
- width: parent.width - 30
- height: parent.height - 30
- anchors.centerIn: parent
- color: StudioTheme.Values.themeStateBackground
- }
-
- Text {
- text: "+"
- anchors.centerIn: parent
- anchors.verticalCenterOffset: -(5 + (font.pixelSize - 35) / 9)
- font.pixelSize: parent.height * .5
- color: Qt.lighter(StudioTheme.Values.themeControlBackgroundInteraction, addState.containsMouse ? 1.5 : 1)
- }
-
- MouseArea {
- id: addState
- hoverEnabled: true
- anchors.fill: parent
- onClicked: root.createNewState()
- }
- }
- }
- }
-
- ScrollBar.horizontal: HorizontalScrollBar {}
- }
-}
diff --git a/share/qtcreator/qmldesigner/statesEditorQmlSources/images/checkers.png b/share/qtcreator/qmldesigner/statesEditorQmlSources/images/checkers.png
deleted file mode 100644
index 72cb9f03506..00000000000
Binary files a/share/qtcreator/qmldesigner/statesEditorQmlSources/images/checkers.png and /dev/null differ
diff --git a/share/qtcreator/qmldesigner/newstateseditor/Main.qml b/share/qtcreator/qmldesigner/stateseditor/Main.qml
similarity index 92%
rename from share/qtcreator/qmldesigner/newstateseditor/Main.qml
rename to share/qtcreator/qmldesigner/stateseditor/Main.qml
index 4cd85bb1ad3..13f26884bcf 100644
--- a/share/qtcreator/qmldesigner/newstateseditor/Main.qml
+++ b/share/qtcreator/qmldesigner/stateseditor/Main.qml
@@ -29,6 +29,7 @@ import StatesEditor
import HelperWidgets 2.0 as HelperWidgets
import StudioControls 1.0 as StudioControls
import StudioTheme as StudioTheme
+import StatesEditorBackend
Rectangle {
id: root
@@ -221,20 +222,20 @@ Rectangle {
// These function assume that the order of the states is as follows:
// State A, State B (extends State A), ... so the extended state always comes first
function isInRange(i) {
- return i >= 0 && i < statesEditorModel.count()
+ return i >= 0 && i < StatesEditorBackend.statesEditorModel.count()
}
function nextStateHasExtend(i) {
let next = i + 1
- return root.isInRange(next) ? statesEditorModel.get(next).hasExtend : false
+ return root.isInRange(next) ? StatesEditorBackend.statesEditorModel.get(next).hasExtend : false
}
function previousStateHasExtend(i) {
let prev = i - 1
- return root.isInRange(prev) ? statesEditorModel.get(prev).hasExtend : false
+ return root.isInRange(prev) ? StatesEditorBackend.statesEditorModel.get(prev).hasExtend : false
}
- property bool showExtendGroups: statesEditorModel.hasExtend
+ property bool showExtendGroups: StatesEditorBackend.statesEditorModel.hasExtend
onShowExtendGroupsChanged: root.responsiveResize(root.width, root.height)
@@ -263,7 +264,7 @@ Rectangle {
property int menuOpen: 0
Connections {
- target: statesEditorModel
+ target: StatesEditorBackend.statesEditorModel
function onModelReset() {
root.menuOpen = 0
editDialog.close()
@@ -343,7 +344,7 @@ Rectangle {
}
onAccepted: {
- let renamed = statesEditorModel.renameActiveStateGroup(editTextField.text)
+ let renamed = StatesEditorBackend.statesEditorModel.renameActiveStateGroup(editTextField.text)
if (renamed)
editDialog.close()
}
@@ -351,8 +352,8 @@ Rectangle {
property string previousString
onAboutToShow: {
- editTextField.text = statesEditorModel.activeStateGroup
- editDialog.previousString = statesEditorModel.activeStateGroup
+ editTextField.text = StatesEditorBackend.statesEditorModel.activeStateGroup
+ editDialog.previousString = StatesEditorBackend.statesEditorModel.activeStateGroup
let btn = editDialog.standardButton(Dialog.Apply)
btn.enabled = false
@@ -406,8 +407,8 @@ Rectangle {
style: StudioTheme.Values.viewBarControlStyle
id: stateGroupComboBox
actionIndicatorVisible: false
- model: statesEditorModel.stateGroups
- currentIndex: statesEditorModel.activeStateGroupIndex
+ model: StatesEditorBackend.statesEditorModel.stateGroups
+ currentIndex: StatesEditorBackend.statesEditorModel.activeStateGroupIndex
anchors.verticalCenter: parent.verticalCenter
width: stateGroupLabel.visible ? StudioTheme.Values.defaultControlWidth
: root.width - 2 * root.padding
@@ -434,18 +435,18 @@ Rectangle {
// currentIndex needs special treatment, because if model is changed, it will be
// reset regardless of binding.
Connections {
- target: statesEditorModel
+ target: StatesEditorBackend.statesEditorModel
function onActiveStateGroupIndexChanged() {
- stateGroupComboBox.currentIndex = statesEditorModel.activeStateGroupIndex
+ stateGroupComboBox.currentIndex = StatesEditorBackend.statesEditorModel.activeStateGroupIndex
}
}
onModelChanged: {
- stateGroupComboBox.currentIndex = statesEditorModel.activeStateGroupIndex
+ stateGroupComboBox.currentIndex = StatesEditorBackend.statesEditorModel.activeStateGroupIndex
}
onCompressedActivated: function (index, reason) {
- statesEditorModel.activeStateGroupIndex = index
+ StatesEditorBackend.statesEditorModel.activeStateGroupIndex = index
root.responsiveResize(root.width, root.height)
}
}
@@ -463,16 +464,16 @@ Rectangle {
buttonIcon: StudioTheme.Constants.add_medium
anchors.verticalCenter: parent.verticalCenter
tooltip: qsTr("Create State Group")
- onClicked: statesEditorModel.addStateGroup("stateGroup")
+ onClicked: StatesEditorBackend.statesEditorModel.addStateGroup("stateGroup")
}
HelperWidgets.AbstractButton {
style: StudioTheme.Values.viewBarButtonStyle
buttonIcon: StudioTheme.Constants.remove_medium
anchors.verticalCenter: parent.verticalCenter
- enabled: statesEditorModel.activeStateGroupIndex !== 0
+ enabled: StatesEditorBackend.statesEditorModel.activeStateGroupIndex !== 0
tooltip: qsTr("Remove State Group")
- onClicked: statesEditorModel.removeStateGroup()
+ onClicked: StatesEditorBackend.statesEditorModel.removeStateGroup()
}
HelperWidgets.AbstractButton {
@@ -480,7 +481,7 @@ Rectangle {
style: StudioTheme.Values.viewBarButtonStyle
buttonIcon: StudioTheme.Constants.edit_medium
anchors.verticalCenter: parent.verticalCenter
- enabled: statesEditorModel.activeStateGroupIndex !== 0
+ enabled: StatesEditorBackend.statesEditorModel.activeStateGroupIndex !== 0
checked: editDialog.visible
tooltip: qsTr("Rename State Group")
onClicked: {
@@ -550,13 +551,13 @@ Rectangle {
width: Constants.thumbnailSize
height: Constants.thumbnailSize
baseState: true
- defaultChecked: !statesEditorModel.baseState.modelHasDefaultState // TODO Make this one a model property
+ defaultChecked: !StatesEditorBackend.statesEditorModel.baseState.modelHasDefaultState // TODO Make this one a model property
isChecked: root.currentStateInternalId === 0
- thumbnailImageSource: statesEditorModel.baseState.stateImageSource ?? "" // TODO Get rid of the QVariantMap
+ thumbnailImageSource: StatesEditorBackend.statesEditorModel.baseState.stateImageSource ?? "" // TODO Get rid of the QVariantMap
isTiny: root.tinyMode
onFocusSignal: root.currentStateInternalId = 0
- onDefaultClicked: statesEditorModel.resetDefaultState()
+ onDefaultClicked: StatesEditorBackend.statesEditorModel.resetDefaultState
}
}
@@ -649,7 +650,7 @@ Rectangle {
property int grabIndex: -1
- model: statesEditorModel
+ model: StatesEditorBackend.statesEditorModel
onItemAdded: root.responsiveResize(root.width, root.height)
onItemRemoved: root.responsiveResize(root.width, root.height)
@@ -691,7 +692,7 @@ Rectangle {
return
}
- statesEditorModel.move(dragSource.visualIndex,
+ StatesEditorBackend.statesEditorModel.move(dragSource.visualIndex,
stateThumbnail.visualIndex)
}
@@ -709,7 +710,7 @@ Rectangle {
if (statesRepeater.grabIndex === dropSource.visualIndex)
return
- statesEditorModel.drop(statesRepeater.grabIndex,
+ StatesEditorBackend.statesEditorModel.drop(statesRepeater.grabIndex,
dropSource.visualIndex)
statesRepeater.grabIndex = -1
}
@@ -807,7 +808,7 @@ Rectangle {
hasExtend: delegateRoot.hasExtend
extendString: delegateRoot.extendString
- extendedState: statesEditorModel.extendedStates.includes(
+ extendedState: StatesEditorBackend.statesEditorModel.extendedStates.includes(
delegateRoot.stateName)
hasWhenCondition: delegateRoot.hasWhenCondition
@@ -840,19 +841,14 @@ Rectangle {
isChecked: root.currentStateInternalId === delegateRoot.internalNodeId
onFocusSignal: root.currentStateInternalId = delegateRoot.internalNodeId
- onDefaultClicked: statesEditorModel.setStateAsDefault(
+ onDefaultClicked: StatesEditorBackend.statesEditorModel.setStateAsDefault(
delegateRoot.internalNodeId)
onClone: root.cloneState(delegateRoot.internalNodeId)
onExtend: root.extendState(delegateRoot.internalNodeId)
- onRemove: {
- if (delegateRoot.isDefault)
- statesEditorModel.resetDefaultState()
+ onRemove: root.deleteState(delegateRoot.internalNodeId)
- root.deleteState(delegateRoot.internalNodeId)
- }
-
- onStateNameFinished: statesEditorModel.renameState(
+ onStateNameFinished: StatesEditorBackend.statesEditorModel.renameState(
delegateRoot.internalNodeId,
stateThumbnail.stateName)
}
@@ -865,7 +861,7 @@ Rectangle {
Item {
id: addWrapper
- visible: canAddNewStates
+ visible: StatesEditorBackend.statesEditorModel.canAddNewStates
Canvas {
id: addCanvas
diff --git a/share/qtcreator/qmldesigner/newstateseditor/MenuButton.qml b/share/qtcreator/qmldesigner/stateseditor/MenuButton.qml
similarity index 100%
rename from share/qtcreator/qmldesigner/newstateseditor/MenuButton.qml
rename to share/qtcreator/qmldesigner/stateseditor/MenuButton.qml
diff --git a/share/qtcreator/qmldesigner/newstateseditor/StateMenu.qml b/share/qtcreator/qmldesigner/stateseditor/StateMenu.qml
similarity index 100%
rename from share/qtcreator/qmldesigner/newstateseditor/StateMenu.qml
rename to share/qtcreator/qmldesigner/stateseditor/StateMenu.qml
diff --git a/share/qtcreator/qmldesigner/newstateseditor/StateScrollBar.qml b/share/qtcreator/qmldesigner/stateseditor/StateScrollBar.qml
similarity index 100%
rename from share/qtcreator/qmldesigner/newstateseditor/StateScrollBar.qml
rename to share/qtcreator/qmldesigner/stateseditor/StateScrollBar.qml
diff --git a/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml b/share/qtcreator/qmldesigner/stateseditor/StateThumbnail.qml
similarity index 97%
rename from share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml
rename to share/qtcreator/qmldesigner/stateseditor/StateThumbnail.qml
index e54732c8d09..1d8147d0425 100644
--- a/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml
+++ b/share/qtcreator/qmldesigner/stateseditor/StateThumbnail.qml
@@ -28,6 +28,7 @@ import QtQuick.Controls
import HelperWidgets 2.0 as HelperWidgets
import StudioControls 1.0 as StudioControls
import StudioTheme 1.0 as StudioTheme
+import StatesEditorBackend
Item {
id: root
@@ -77,7 +78,7 @@ Item {
property alias dragActive: dragHandler.active
function checkAnnotation() {
- return statesEditorModel.hasAnnotation(root.internalNodeId)
+ return StatesEditorBackend.statesEditorModel.hasAnnotation(root.internalNodeId)
}
function setPropertyChangesVisible(value) {
@@ -256,7 +257,7 @@ Item {
PropertyChangesModel {
id: propertyChangesModel
- modelNodeBackendProperty: statesEditorModel.stateModelNode(root.internalNodeId)
+ modelNodeBackendProperty: StatesEditorBackend.statesEditorModel.stateModelNode(root.internalNodeId)
}
Text {
@@ -631,14 +632,14 @@ Item {
return
if ( bindingEditor.newWhenCondition !== "")
- statesEditorModel.setWhenCondition(root.internalNodeId,
+ StatesEditorBackend.statesEditorModel.setWhenCondition(root.internalNodeId,
bindingEditor.newWhenCondition)
else
- statesEditorModel.resetWhenCondition(root.internalNodeId)
+ StatesEditorBackend.statesEditorModel.resetWhenCondition(root.internalNodeId)
}
}
- stateModelNodeProperty: statesEditorModel.stateModelNode(root.internalNodeId)
+ stateModelNodeProperty: StatesEditorBackend.statesEditorModel.stateModelNode(root.internalNodeId)
stateNameProperty: root.stateName
onRejected: bindingEditor.hideWidget()
@@ -691,9 +692,9 @@ Item {
whenCondition.previousCondition = whenCondition.text
if (whenCondition.text !== "")
- statesEditorModel.setWhenCondition(root.internalNodeId, root.whenCondition)
+ StatesEditorBackend.statesEditorModel.setWhenCondition(root.internalNodeId, root.whenCondition)
else
- statesEditorModel.resetWhenCondition(root.internalNodeId)
+ StatesEditorBackend.statesEditorModel.resetWhenCondition(root.internalNodeId)
}
@@ -736,11 +737,11 @@ Item {
onToggle: root.setPropertyChangesVisible(!root.propertyChangesVisible)
onResetWhenCondition: statesEditorModel.resetWhenCondition(root.internalNodeId)
onEditAnnotation: {
- statesEditorModel.setAnnotation(root.internalNodeId)
+ StatesEditorBackend.statesEditorModel.setAnnotation(root.internalNodeId)
stateMenu.hasAnnotation = root.checkAnnotation()
}
onRemoveAnnotation: {
- statesEditorModel.removeAnnotation(root.internalNodeId)
+ StatesEditorBackend.statesEditorModel.removeAnnotation(root.internalNodeId)
stateMenu.hasAnnotation = root.checkAnnotation()
}
diff --git a/share/qtcreator/qmldesigner/newstateseditor/images/checkers.png b/share/qtcreator/qmldesigner/stateseditor/images/checkers.png
similarity index 100%
rename from share/qtcreator/qmldesigner/newstateseditor/images/checkers.png
rename to share/qtcreator/qmldesigner/stateseditor/images/checkers.png
diff --git a/share/qtcreator/qmldesigner/newstateseditor/imports/StatesEditor/Constants.qml b/share/qtcreator/qmldesigner/stateseditor/imports/StatesEditor/Constants.qml
similarity index 100%
rename from share/qtcreator/qmldesigner/newstateseditor/imports/StatesEditor/Constants.qml
rename to share/qtcreator/qmldesigner/stateseditor/imports/StatesEditor/Constants.qml
diff --git a/share/qtcreator/qmldesigner/newstateseditor/imports/StatesEditor/qmldir b/share/qtcreator/qmldesigner/stateseditor/imports/StatesEditor/qmldir
similarity index 100%
rename from share/qtcreator/qmldesigner/newstateseditor/imports/StatesEditor/qmldir
rename to share/qtcreator/qmldesigner/stateseditor/imports/StatesEditor/qmldir
diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/app_mcu.qmlproject b/share/qtcreator/qmldesigner/studio_templates/projects/app_mcu.qmlproject
index 55204175faa..80bb0c5743e 100644
--- a/share/qtcreator/qmldesigner/studio_templates/projects/app_mcu.qmlproject
+++ b/share/qtcreator/qmldesigner/studio_templates/projects/app_mcu.qmlproject
@@ -4,6 +4,7 @@ import QmlProject 1.3
Project {
mainFile: "%{MainQmlFileName}"
+ QDS.mainUiFile: "Screen01.ui.qml"
/* Include .qml, .js, and image files from current directory and subdirectories */
QmlFiles {
@@ -47,18 +48,18 @@ Project {
/* Following entries are for Qt Design Studio compatibility: */
- Environment {
+ QDS.Environment {
QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf"
}
- qtForMCUs: true
- qt6Project: true
+ QDS.qtForMCUs: true
+ QDS.qt6Project: true
- qdsVersion: "4.1"
- quickVersion: "6.5"
+ QDS.qdsVersion: "4.2"
+ QDS.quickVersion: "6.5"
/* List of plugin directories passed to QML runtime */
importPaths: [ "imports" ]
- targetDirectory: "/opt/%{ProjectName}"
+ QDS.targetDirectory: "/opt/%{ProjectName}"
}
diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json
index 3e26a5f0f20..0bc60900074 100644
--- a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json
+++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json
@@ -241,14 +241,6 @@
"index": 4,
"items":
[
- {
- "trKey": "Qt 5",
- "value":
- "({
- 'TargetQuickVersion': '2.15',
- 'TargetQuick3DVersion': '1.15'
- })"
- },
{
"trKey": "Qt 6.2",
"value":
diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/Constants.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/Constants.qml.tpl
index ad50e39e9ac..c6bbb001993 100644
--- a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/Constants.qml.tpl
+++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/Constants.qml.tpl
@@ -1,5 +1,5 @@
pragma Singleton
-import QtQuick 6.5
+import QtQuick
QtObject {
readonly property int width: %{ScreenWidth}
diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/Screen01.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/Screen01.ui.qml.tpl
index 4a70ce692b6..4a16e2c6b1c 100644
--- a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/Screen01.ui.qml.tpl
+++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/Screen01.ui.qml.tpl
@@ -5,8 +5,8 @@ this file manually, you might introduce QML code that is not supported by Qt Des
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
*/
-import QtQuick 6.5
-import Constants 1.0
+import QtQuick
+import Constants
Rectangle {
width: Constants.width
diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/main.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/main.qml.tpl
index e25113c67f9..cd6a735a099 100644
--- a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/main.qml.tpl
+++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/main.qml.tpl
@@ -1,5 +1,5 @@
-import QtQuick 6.5
-import Constants 1.0
+import QtQuick
+import Constants
Item {
width: Constants.width
diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json
index ea5f9ef671b..e1a25e23fb5 100644
--- a/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json
+++ b/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json
@@ -296,23 +296,28 @@
},
{
"source": "../common/CMakeLists.main.txt.tpl",
- "target": "%{ProjectDirectory}/CMakeLists.txt"
+ "target": "%{ProjectDirectory}/CMakeLists.txt",
+ "condition": "%{IsQt6Project}"
},
{
"source": "../common/qmlmodules.tpl",
- "target": "%{ProjectDirectory}/qmlmodules"
+ "target": "%{ProjectDirectory}/qmlmodules",
+ "condition": "%{IsQt6Project}"
},
{
"source": "../common/qmlcomponents.tpl",
- "target": "%{ProjectDirectory}/qmlcomponents"
+ "target": "%{ProjectDirectory}/qmlcomponents",
+ "condition": "%{IsQt6Project}"
},
{
"source": "../common/insight.tpl",
- "target": "%{ProjectDirectory}/insight"
+ "target": "%{ProjectDirectory}/insight",
+ "condition": "%{IsQt6Project}"
},
{
"source": "../common/main.qml",
- "target": "%{ProjectDirectory}/main.qml"
+ "target": "%{ProjectDirectory}/main.qml",
+ "condition": "%{IsQt6Project}"
},
{
"source": "../common/qtquickcontrols2.conf.tpl",
@@ -320,23 +325,28 @@
},
{
"source": "../common/main.cpp.tpl",
- "target": "%{ProjectDirectory}/src/main.cpp"
+ "target": "%{ProjectDirectory}/src/main.cpp",
+ "condition": "%{IsQt6Project}"
},
{
"source": "../common/app_environment.h.tpl",
- "target": "%{ProjectDirectory}/src/app_environment.h"
+ "target": "%{ProjectDirectory}/src/app_environment.h",
+ "condition": "%{IsQt6Project}"
},
{
"source": "../common/import_qml_plugins.h.tpl",
- "target": "%{ProjectDirectory}/src/import_qml_plugins.h"
+ "target": "%{ProjectDirectory}/src/import_qml_plugins.h",
+ "condition": "%{IsQt6Project}"
},
{
"source": "../common/import_qml_components_plugins.h.tpl",
- "target": "%{ProjectDirectory}/src/import_qml_components_plugins.h"
+ "target": "%{ProjectDirectory}/src/import_qml_components_plugins.h",
+ "condition": "%{IsQt6Project}"
},
{
"source": "../common/CMakeLists.content.txt.tpl",
- "target": "%{ProjectDirectory}/content/CMakeLists.txt"
+ "target": "%{ProjectDirectory}/content/CMakeLists.txt",
+ "condition": "%{IsQt6Project}"
},
{
"source": "../common/App.qml.tpl",
@@ -356,11 +366,13 @@
},
{
"source": "../common/CMakeLists.imports.txt.tpl",
- "target": "%{ProjectDirectory}/imports/CMakeLists.txt"
+ "target": "%{ProjectDirectory}/imports/CMakeLists.txt",
+ "condition": "%{IsQt6Project}"
},
{
"source": "../shared-plugin/name/CMakeLists.importmodule.txt.tpl",
- "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/CMakeLists.txt"
+ "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/CMakeLists.txt",
+ "condition": "%{IsQt6Project}"
},
{
"source": "../shared-plugin/name/importmodule.qmldir.tpl",
diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/common/CMakeLists.content.txt.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/common/CMakeLists.content.txt.tpl
index a95da583f37..a5a4360e3f2 100644
--- a/share/qtcreator/qmldesigner/studio_templates/projects/common/CMakeLists.content.txt.tpl
+++ b/share/qtcreator/qmldesigner/studio_templates/projects/common/CMakeLists.content.txt.tpl
@@ -5,6 +5,7 @@ qt_add_library(content STATIC)
qt6_add_qml_module(content
URI "content"
VERSION 1.0
+ RESOURCE_PREFIX "/qt/qml"
QML_FILES
App.qml
%{UIClassFileName}
diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl
index 9cfbab9228b..0b96ccf3ba3 100644
--- a/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl
+++ b/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl
@@ -105,7 +105,7 @@ Project {
/* Required for deployment */
targetDirectory: "/opt/%{ProjectName}"
- qdsVersion: "4.1"
+ qdsVersion: "4.2"
quickVersion: "%{QtQuickVersion}"
diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/common/main.cpp.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/common/main.cpp.tpl
index 53c355b6b8a..915d08462e2 100644
--- a/share/qtcreator/qmldesigner/studio_templates/projects/common/main.cpp.tpl
+++ b/share/qtcreator/qmldesigner/studio_templates/projects/common/main.cpp.tpl
@@ -15,7 +15,7 @@ int main(int argc, char *argv[])
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
- const QUrl url(u"qrc:Main/main.qml"_qs);
+ const QUrl url(u"qrc:/qt/qml/Main/main.qml"_qs);
QObject::connect(
&engine, &QQmlApplicationEngine::objectCreated, &app,
[url](QObject *obj, const QUrl &objUrl) {
diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/common/qmlmodules.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/common/qmlmodules.tpl
index fa3069a770a..5a22661b5a1 100644
--- a/share/qtcreator/qmldesigner/studio_templates/projects/common/qmlmodules.tpl
+++ b/share/qtcreator/qmldesigner/studio_templates/projects/common/qmlmodules.tpl
@@ -4,6 +4,7 @@
qt6_add_qml_module(${CMAKE_PROJECT_NAME}
URI "Main"
VERSION 1.0
+ RESOURCE_PREFIX "/qt/qml"
NO_PLUGIN
QML_FILES main.qml
)
diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/CMakeLists.content.txt.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/CMakeLists.content.txt.tpl
index 255afffa3ea..5601c89997d 100644
--- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/CMakeLists.content.txt.tpl
+++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/CMakeLists.content.txt.tpl
@@ -5,6 +5,7 @@ qt_add_library(content STATIC)
qt6_add_qml_module(content
URI "content"
VERSION 1.0
+ RESOURCE_PREFIX "/qt/qml"
QML_FILES
App.qml
Screen01.ui.qml
diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/CMakeLists.content.txt.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/CMakeLists.content.txt.tpl
index 255afffa3ea..5601c89997d 100644
--- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/CMakeLists.content.txt.tpl
+++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/CMakeLists.content.txt.tpl
@@ -5,6 +5,7 @@ qt_add_library(content STATIC)
qt6_add_qml_module(content
URI "content"
VERSION 1.0
+ RESOURCE_PREFIX "/qt/qml"
QML_FILES
App.qml
Screen01.ui.qml
diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/CMakeLists.importmodule.txt.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/CMakeLists.importmodule.txt.tpl
index df10020cb23..517b91355a7 100644
--- a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/CMakeLists.importmodule.txt.tpl
+++ b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/CMakeLists.importmodule.txt.tpl
@@ -8,11 +8,12 @@ set_source_files_properties(Constants.qml
)
qt6_add_qml_module(%{ImportModuleName}
- URI "%{ImportModuleName}"
- VERSION 1.0
- QML_FILES
- Constants.qml
- DirectoryFontLoader.qml
- EventListModel.qml
- EventListSimulator.qml
+ URI "%{ImportModuleName}"
+ VERSION 1.0
+ RESOURCE_PREFIX "/qt/qml"
+ QML_FILES
+ Constants.qml
+ DirectoryFontLoader.qml
+ EventListModel.qml
+ EventListSimulator.qml
)
diff --git a/tests/unit/unittest/3rdparty/googletest b/src/libs/3rdparty/googletest
similarity index 100%
rename from tests/unit/unittest/3rdparty/googletest
rename to src/libs/3rdparty/googletest
diff --git a/src/libs/3rdparty/sqlite/config.h b/src/libs/3rdparty/sqlite/config.h
index 3672f4c5ddf..f0e73be3009 100644
--- a/src/libs/3rdparty/sqlite/config.h
+++ b/src/libs/3rdparty/sqlite/config.h
@@ -27,10 +27,6 @@
#include
-#if defined(SQLITE_STATIC_LIBRARY) || defined(SQLITEC_STATIC_LIBRARY)
-#include "sqlite_static_config.h"
-#endif
-
#if __has_include()
#include
#endif
diff --git a/src/libs/CMakeLists.txt b/src/libs/CMakeLists.txt
index de2d2b01ef3..73a554bae8b 100644
--- a/src/libs/CMakeLists.txt
+++ b/src/libs/CMakeLists.txt
@@ -22,6 +22,10 @@ if (WITH_QMLDESIGNER)
add_subdirectory(qmlpuppetcommunication)
endif()
+if (WITH_TESTS)
+ add_subdirectory(googletest)
+endif()
+
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/qlitehtml/src/CMakeLists.txt)
option(BUILD_LIBRARY_QLITEHTML "Build library qlitehtml." ${BUILD_LIBRARIES_BY_DEFAULT})
set(QLITEHTML_VERSION_COMPAT ${IDE_VERSION_COMPAT} CACHE STRING "")
diff --git a/src/libs/googletest/CMakeLists.txt b/src/libs/googletest/CMakeLists.txt
new file mode 100644
index 00000000000..50e82e1edf6
--- /dev/null
+++ b/src/libs/googletest/CMakeLists.txt
@@ -0,0 +1,27 @@
+set(GOOGLETEST_DIR ${CMAKE_CURRENT_LIST_DIR}/../3rdparty/googletest)
+
+if(EXISTS "${GOOGLETEST_DIR}/googletest")
+ set(GOOGLETEST_SUBMODULE_IS_CHECKED_OUT YES)
+else()
+ set(GOOGLETEST_SUBMODULE_IS_CHECKED_OUT NO)
+endif()
+
+add_qtc_library(Googletest STATIC
+ CONDITION GOOGLETEST_SUBMODULE_IS_CHECKED_OUT
+ DEPENDS
+ Threads::Threads
+ PUBLIC_INCLUDES
+ "${GOOGLETEST_DIR}/googletest/include"
+ "${GOOGLETEST_DIR}/googlemock/include"
+ INCLUDES
+ "${GOOGLETEST_DIR}/googletest"
+ "${GOOGLETEST_DIR}/googlemock"
+ PROPERTIES
+ AUTOMOC OFF AUTOUIC OFF QT_COMPILE_OPTIONS_DISABLE_WARNINGS ON
+ POSITION_INDEPENDENT_CODE ON
+ URL "https://github.com/google/googletest"
+ DESCRIPTION "Google Testing and Mocking Framework"
+ SOURCES
+ "${GOOGLETEST_DIR}/googletest/src/gtest-all.cc"
+ "${GOOGLETEST_DIR}/googlemock/src/gmock-all.cc"
+)
diff --git a/src/libs/qmljs/qmljsreformatter.cpp b/src/libs/qmljs/qmljsreformatter.cpp
index 232c0361a1a..d2891451e95 100644
--- a/src/libs/qmljs/qmljsreformatter.cpp
+++ b/src/libs/qmljs/qmljsreformatter.cpp
@@ -590,14 +590,35 @@ protected:
return true;
}
- bool visit(UiObjectDefinition *ast) override
+ bool visit(UiAnnotation *ast) override
{
+ out("@");
accept(ast->qualifiedTypeNameId);
out(" ");
accept(ast->initializer);
return false;
}
+ bool visit(UiAnnotationList *ast) override
+ {
+ for (UiAnnotationList *it = ast; it; it = it->next) {
+ accept(it->annotation);
+ newLine();
+ }
+ return false;
+ }
+
+ bool visit(UiObjectDefinition *ast) override
+ {
+ accept(ast->annotations);
+
+ accept(ast->qualifiedTypeNameId);
+ out(" ");
+ accept(ast->initializer);
+
+ return false;
+ }
+
bool visit(UiObjectInitializer *ast) override
{
out(ast->lbraceToken);
@@ -687,9 +708,12 @@ protected:
bool visit(UiScriptBinding *ast) override
{
+ accept(ast->annotations);
+
accept(ast->qualifiedId);
out(": ", ast->colonToken);
accept(ast->statement);
+
return false;
}
@@ -1290,6 +1314,7 @@ protected:
{
for (UiObjectMemberList *it = ast; it; it = it->next) {
accept(it->member);
+
if (it->next)
newLine();
}
diff --git a/src/libs/sqlite/CMakeLists.txt b/src/libs/sqlite/CMakeLists.txt
index 4c7cd774c60..aa33171bab1 100644
--- a/src/libs/sqlite/CMakeLists.txt
+++ b/src/libs/sqlite/CMakeLists.txt
@@ -1,8 +1,7 @@
-add_qtc_library(SqliteC OBJECT
+add_qtc_library(SqliteInternal OBJECT
PROPERTIES AUTOMOC OFF AUTOUIC OFF QT_COMPILE_OPTIONS_DISABLE_WARNINGS ON
DEFINES SQLITE_CORE SQLITE_CUSTOM_INCLUDE=config.h $<$:SQLITE_DEBUG>
- PROPERTIES COMPILE_OPTIONS $,/FIconfig.h,-includeconfig.h>
- PUBLIC_INCLUDES
+ INCLUDES
../3rdparty/sqlite
SOURCES
../3rdparty/sqlite
@@ -11,12 +10,26 @@ add_qtc_library(SqliteC OBJECT
../3rdparty/sqlite/sqlite3ext.h
../3rdparty/sqlite/carray.c
../3rdparty/sqlite/config.h
+ ../3rdparty/sqlite/sqlite_static_config.h
../3rdparty/sqlite/sqlite.h
)
+extend_qtc_library(SqliteInternal
+ CONDITION QTC_STATIC_BUILD
+ PROPERTIES COMPILE_OPTIONS $,/FIsqlite_static_config.h,-includesqlite_static_config.h>
+)
+
+if (APPLE)
+ extend_qtc_library(SqliteInternal DEFINES _BSD_SOURCE)
+elseif (UNIX)
+ extend_qtc_library(SqliteInternal DEFINES _POSIX_C_SOURCE=200809L _GNU_SOURCE _DEFAULT_SOURCE)
+endif()
+
add_qtc_library(Sqlite
PROPERTIES AUTOMOC OFF AUTOUIC OFF
- DEPENDS Qt::Core Threads::Threads ${CMAKE_DL_LIBS} SqliteC
+ DEPENDS Qt::Core Threads::Threads ${CMAKE_DL_LIBS} SqliteInternal
+ INCLUDES
+ ../3rdparty/sqlite
PUBLIC_INCLUDES
"${CMAKE_CURRENT_LIST_DIR}"
DEFINES SQLITE_CUSTOM_INCLUDE=config.h $<$:SQLITE_REVERSE>
@@ -53,8 +66,7 @@ add_qtc_library(Sqlite
sqliteids.h
)
-if (APPLE)
- extend_qtc_library(SqliteC DEFINES _BSD_SOURCE)
-elseif (UNIX)
- extend_qtc_library(SqliteC DEFINES _POSIX_C_SOURCE=200809L _GNU_SOURCE _DEFAULT_SOURCE)
-endif()
+extend_qtc_library(Sqlite
+ CONDITION QTC_STATIC_BUILD
+ PROPERTIES COMPILE_OPTIONS $,/FIsqlite_static_config.h,-includesqlite_static_config.h>
+)
diff --git a/src/libs/sqlite/sqlitebasestatement.cpp b/src/libs/sqlite/sqlitebasestatement.cpp
index 91b417bea12..d9d677c3959 100644
--- a/src/libs/sqlite/sqlitebasestatement.cpp
+++ b/src/libs/sqlite/sqlitebasestatement.cpp
@@ -274,6 +274,9 @@ void BaseStatement::bind(int index, ValueView value)
void BaseStatement::prepare(Utils::SmallStringView sqlStatement)
{
+ if (!m_database.isLocked())
+ throw DatabaseIsNotLocked{};
+
int resultCode;
do {
diff --git a/src/libs/sqlite/sqlitebasestatement.h b/src/libs/sqlite/sqlitebasestatement.h
index 1178b97f3a1..54d08260b7c 100644
--- a/src/libs/sqlite/sqlitebasestatement.h
+++ b/src/libs/sqlite/sqlitebasestatement.h
@@ -49,6 +49,7 @@ public:
BaseStatement(const BaseStatement &) = delete;
BaseStatement &operator=(const BaseStatement &) = delete;
+ BaseStatement(BaseStatement &&) = default;
bool next() const;
void step() const;
@@ -146,6 +147,7 @@ class StatementImplementation : public BaseStatement
public:
using BaseStatement::BaseStatement;
+ StatementImplementation(StatementImplementation &&) = default;
void execute()
{
@@ -496,16 +498,30 @@ private:
return createValue(std::make_integer_sequence{});
}
+ template
+ CallbackControl invokeCallable(Callable &&callable, Arguments &&...arguments)
+ {
+ if constexpr (std::is_void_v>) {
+ std::invoke(std::forward(callable), std::forward(arguments)...);
+ return CallbackControl::Continue;
+ } else {
+ return std::invoke(std::forward(callable),
+ std::forward(arguments)...);
+ }
+ }
+
template
CallbackControl callCallable(Callable &&callable, std::integer_sequence)
{
- return std::invoke(callable, ValueGetter(*this, ColumnIndices)...);
+ return invokeCallable(std::forward(callable),
+ ValueGetter(*this, ColumnIndices)...);
}
template
CallbackControl callCallable(Callable &&callable)
{
- return callCallable(callable, std::make_integer_sequence{});
+ return callCallable(std::forward(callable),
+ std::make_integer_sequence{});
}
void setMaximumResultCount(std::size_t count)
diff --git a/src/libs/utils/set_algorithm.h b/src/libs/utils/set_algorithm.h
index a3e442f736d..f6d3f73fedf 100644
--- a/src/libs/utils/set_algorithm.h
+++ b/src/libs/utils/set_algorithm.h
@@ -60,8 +60,17 @@ bool set_intersection_compare(
++first1;
} else {
if (!comp(*first2, *first1)) {
- if (call(*first1++, *first2))
- return true;
+ if constexpr (std::is_void_v>) {
+ call(*first1, *first2);
+ ++first1;
+ } else {
+ auto success = call(*first1, *first2);
+ ++first1;
+ if (success)
+ return true;
+ }
}
++first2;
}
@@ -70,6 +79,52 @@ bool set_intersection_compare(
return false;
}
+template
+bool set_greedy_intersection_compare(
+ InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Callable call, Compare comp)
+{
+ while (first1 != last1 && first2 != last2) {
+ if (comp(*first1, *first2)) {
+ ++first1;
+ } else {
+ if (!comp(*first2, *first1)) {
+ if constexpr (std::is_void_v>) {
+ call(*first1, *first2);
+ ++first1;
+ } else {
+ auto success = call(*first1, *first2);
+ ++first1;
+ if (success)
+ return true;
+ }
+ } else {
+ ++first2;
+ }
+ }
+ }
+
+ return false;
+}
+
+template
+constexpr OutputIt set_greedy_intersection(
+ InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt result)
+{
+ while (first1 != last1 && first2 != last2)
+ if (*first1 < *first2)
+ ++first1;
+ else if (*first2 < *first1)
+ ++first2;
+ else {
+ *result = *first1;
+ ++first1;
+ ++result;
+ }
+ return result;
+}
+
template
void set_greedy_difference(
InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Callable call, Compare comp)
diff --git a/src/libs/utils/smallstringview.h b/src/libs/utils/smallstringview.h
index 82a8c503051..982192c7a44 100644
--- a/src/libs/utils/smallstringview.h
+++ b/src/libs/utils/smallstringview.h
@@ -12,6 +12,12 @@
#include
#include
+#if __cpp_lib_constexpr_string >= 201907L
+#define constexpr_string constexpr
+#else
+#define constexpr_string
+#endif
+
namespace Utils {
template
@@ -63,7 +69,7 @@ public:
return SmallStringView(data() + position, length);
}
- constexpr20 operator std::string() const { return std::string(data(), size()); }
+ constexpr_string operator std::string() const { return std::string(data(), size()); }
explicit operator QString() const
{
@@ -131,38 +137,6 @@ constexpr int compare(SmallStringView first, SmallStringView second) noexcept
return first.compare(second);
}
-namespace Internal {
-constexpr int reverse_memcmp(const char *first, const char *second, size_t n)
-{
- const char *currentFirst = first + n - 1;
- const char *currentSecond = second + n - 1;
-
- while (n > 0) {
- // If the current characters differ, return an appropriately signed
- // value; otherwise, keep searching backwards
- int difference = *currentFirst - *currentSecond;
- if (difference != 0)
- return difference;
-
- --currentFirst;
- --currentSecond;
- --n;
- }
-
- return 0;
-}
-} // namespace Internal
-
-constexpr int reverseCompare(SmallStringView first, SmallStringView second) noexcept
-{
- int difference = Internal::reverse_memcmp(first.data(), second.data(), first.size());
-
- if (difference == 0)
- return int(first.size()) - int(second.size());
-
- return difference;
-}
-
} // namespace Utils
constexpr Utils::SmallStringView operator""_sv(const char *const string, size_t size)
diff --git a/src/plugins/insight/insightmodel.cpp b/src/plugins/insight/insightmodel.cpp
index b80249d2124..2d2550aac55 100644
--- a/src/plugins/insight/insightmodel.cpp
+++ b/src/plugins/insight/insightmodel.cpp
@@ -227,7 +227,7 @@ InsightModel::InsightModel(InsightView *view, ExternalDependenciesInterface &ext
int InsightModel::rowCount(const QModelIndex &) const
{
- return m_qtdsConfig.empty() ? 0 : m_qtdsConfig.size();
+ return m_qtdsConfig.empty() ? 0 : static_cast(m_qtdsConfig.size());
}
QVariant InsightModel::data(const QModelIndex &index, int role) const
diff --git a/src/plugins/mcusupport/test/CMakeLists.txt b/src/plugins/mcusupport/test/CMakeLists.txt
index 2df4faa891d..7d2a94c286e 100644
--- a/src/plugins/mcusupport/test/CMakeLists.txt
+++ b/src/plugins/mcusupport/test/CMakeLists.txt
@@ -1,13 +1,8 @@
-find_package(Googletest MODULE)
-
-if(TARGET Googletest)
- message("Googletest target is present")
- extend_qtc_plugin(McuSupport
- CONDITION WITH_TESTS
- DEPENDS Googletest
- SOURCES
- unittest.h unittest.cpp packagemock.h settingshandlermock.h
- )
-else()
- message("Googletest target is missing")
-endif()
+extend_qtc_plugin(McuSupport
+ CONDITION WITH_TESTS AND TARGET Googletest
+ DEPENDS Googletest
+ SOURCES
+ unittest.h unittest.cpp
+ packagemock.h
+ settingshandlermock.h
+)
diff --git a/src/plugins/projectexplorer/projectwindow.cpp b/src/plugins/projectexplorer/projectwindow.cpp
index 6d51ada4106..a69ee4c855a 100644
--- a/src/plugins/projectexplorer/projectwindow.cpp
+++ b/src/plugins/projectexplorer/projectwindow.cpp
@@ -585,7 +585,7 @@ public:
PanelsWidget::PanelVMargin, 0);
QStringList list = Core::ICore::settings()->value("HideOptionCategories").toStringList();
- if (!list.contains("Kit")) {
+ if (!list.contains("Kits")) {
innerLayout->addWidget(m_manageKits);
innerLayout->addSpacerItem(new QSpacerItem(10, 30, QSizePolicy::Maximum, QSizePolicy::Maximum));
}
diff --git a/src/plugins/python/pythonlanguageclient.cpp b/src/plugins/python/pythonlanguageclient.cpp
index 9f347d8e486..eecfb35c97f 100644
--- a/src/plugins/python/pythonlanguageclient.cpp
+++ b/src/plugins/python/pythonlanguageclient.cpp
@@ -115,6 +115,7 @@ static PythonLanguageServerState checkPythonLanguageServer(const FilePath &pytho
const FilePath &modulePath = getPylsModulePath(pythonLShelpCommand);
Process pythonProcess;
+ pythonProcess.setTimeoutS(2);
pythonProcess.setCommand(pythonLShelpCommand);
pythonProcess.runBlocking();
if (pythonProcess.allOutput().contains("Python Language Server"))
diff --git a/src/plugins/qmldesigner/.clang-format b/src/plugins/qmldesigner/.clang-format
index e1dad0fa0c0..968dfdec7d1 100644
--- a/src/plugins/qmldesigner/.clang-format
+++ b/src/plugins/qmldesigner/.clang-format
@@ -6,10 +6,12 @@ AlignConsecutiveDeclarations: false
AlignEscapedNewlines: DontAlign
AlignOperands: true
AlignTrailingComments: true
+AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
+AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
@@ -32,13 +34,16 @@ BraceWrapping:
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
+BreakAfterAttributes: Never
BreakBeforeBinaryOperators: All
BreakBeforeBraces: Custom
+BreakBeforeConceptDeclarations: Always
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false
+BreakInheritanceList: AfterComma
BreakStringLiterals: true
ColumnLimit: 100
CommentPragmas: '^ IWYU pragma:'
@@ -49,6 +54,8 @@ ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
+EmptyLineAfterAccessModifier: Never
+EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
@@ -56,17 +63,23 @@ ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
+#IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^(this));
- connect(m_preprocessWatcher.get(), &QFutureWatcher::resultReadyAt, this,
+ connect(m_preprocessWatcher.get(),
+ &QFutureWatcher::resultReadyAt,
+ this,
[this](int resultIndex) {
- beginInsertRows(index(0, 0) , m_files.count(), m_files.count());
- m_files.append(m_preprocessWatcher->resultAt(resultIndex));
- endInsertRows();
- });
+ beginInsertRows(index(0, 0), m_files.size(), m_files.size());
+ m_files.append(m_preprocessWatcher->resultAt(resultIndex));
+ endInsertRows();
+ });
connect(m_preprocessWatcher.get(), &QFutureWatcher::finished,
this, &FilePathModel::endResetModel);
diff --git a/src/plugins/qmldesigner/components/annotationeditor/annotationtableview.cpp b/src/plugins/qmldesigner/components/annotationeditor/annotationtableview.cpp
index 7c8daa5eebb..f3cc629dd80 100644
--- a/src/plugins/qmldesigner/components/annotationeditor/annotationtableview.cpp
+++ b/src/plugins/qmldesigner/components/annotationeditor/annotationtableview.cpp
@@ -66,7 +66,7 @@ void CommentDelegate::updateEditorGeometry(QWidget *editor,
editor->setGeometry(option.rect);
}
-Comment CommentDelegate::comment(QModelIndex const &index)
+Comment CommentDelegate::comment(const QModelIndex &index)
{
auto *model = index.model();
return model->data(model->index(index.row(), ColumnId::Title), CommentRole).value();
@@ -136,9 +136,9 @@ void CommentValueDelegate::paint(QPainter *painter,
const QModelIndex &index) const
{
auto data = index.model()->data(index, Qt::DisplayRole);
- if (data.userType() == qMetaTypeId())
+ if (data.typeId() == qMetaTypeId())
drawDisplay(painter, option, option.rect, data.value().plainText());
- else if (data.userType() == QMetaType::QColor)
+ else if (data.typeId() == QMetaType::QColor)
painter->fillRect(option.rect, data.value());
else
QItemDelegate::paint(painter, option, index);
@@ -147,7 +147,7 @@ void CommentValueDelegate::paint(QPainter *painter,
void CommentValueDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
auto data = index.model()->data(index, Qt::DisplayRole);
- if (data.userType() == qMetaTypeId()) {
+ if (data.typeId() == qMetaTypeId()) {
auto richText = data.value();
auto *e = qobject_cast(editor);
e->setText(richText.plainText());
@@ -157,10 +157,10 @@ void CommentValueDelegate::setEditorData(QWidget *editor, const QModelIndex &ind
this,
&CommentValueDelegate::richTextEditorRequested,
Qt::UniqueConnection);
- } else if (data.userType() == QMetaType::QString) {
+ } else if (data.typeId() == QMetaType::QString) {
auto *e = qobject_cast(editor);
e->setText(data.toString());
- } else if (data.userType() == QMetaType::QColor) {
+ } else if (data.typeId() == QMetaType::QColor) {
auto *e = qobject_cast(editor);
e->setColor(data.value());
e->installEventFilter(e);
@@ -206,15 +206,13 @@ void CommentValueDelegate::setModelData(QWidget *editor,
const QModelIndex &index) const
{
auto data = model->data(index, Qt::EditRole);
- if (data.userType() == qMetaTypeId())
+ if (data.typeId() == qMetaTypeId())
return;
- else if (data.userType() == QMetaType::QColor)
- {
+ else if (data.typeId() == QMetaType::QColor) {
model->setData(index,
qobject_cast(editor)->color(),
Qt::DisplayRole);
- }
- else if (data.userType() == QMetaType::QString)
+ } else if (data.typeId() == QMetaType::QString)
model->setData(index, qobject_cast(editor)->text(), Qt::DisplayRole);
else
QItemDelegate::setModelData(editor, model, index);
@@ -288,7 +286,7 @@ AnnotationTableView::AnnotationTableView(QWidget *parent)
// When comment title was edited, make value item editable
if (item->column() == ColumnId::Title && valueItem) {
valueItem->setEditable(!item->text().isEmpty());
- valueItem->setCheckable(valueItem->data(Qt::DisplayRole).userType() == QMetaType::Bool);
+ valueItem->setCheckable(valueItem->data(Qt::DisplayRole).typeId() == QMetaType::Bool);
}
m_modelUpdating = true;
@@ -344,7 +342,7 @@ Comment AnnotationTableView::fetchComment(int row) const
return comment;
}
-void AnnotationTableView::setupComments(QVector const &comments)
+void AnnotationTableView::setupComments(const QVector &comments)
{
m_model->clear();
m_modelUpdating = true;
@@ -379,7 +377,7 @@ void AnnotationTableView::setDefaultAnnotations(DefaultAnnotationsModel *default
m_valueDelegate.setDefaultAnnotations(defaults);
}
-void AnnotationTableView::changeRow(int index, Comment const &comment)
+void AnnotationTableView::changeRow(int index, const Comment &comment)
{
auto *titleItem = m_model->item(index, ColumnId::Title);
auto *authorItem = m_model->item(index, ColumnId::Author);
@@ -395,7 +393,7 @@ void AnnotationTableView::changeRow(int index, Comment const &comment)
: QMetaType::UnknownType);
textItem->setEditable(data.isValid());
- textItem->setCheckable(data.userType() == QMetaType::Bool);
+ textItem->setCheckable(data.typeId() == QMetaType::Bool);
textItem->setData(data, Qt::DisplayRole);
}
@@ -433,9 +431,9 @@ bool AnnotationTableView::rowIsEmpty(int row) const
return QString(itemText(0) + itemText(1) + itemText(2)).isEmpty();
}
-QString AnnotationTableView::dataToCommentText(QVariant const &data)
+QString AnnotationTableView::dataToCommentText(const QVariant &data)
{
- auto type = data.userType();
+ auto type = data.typeId();
if (type == qMetaTypeId())
return data.value().text;
@@ -451,7 +449,7 @@ QString AnnotationTableView::dataToCommentText(QVariant const &data)
return {};
}
-QVariant AnnotationTableView::commentToData(Comment const& comment, QMetaType::Type type)
+QVariant AnnotationTableView::commentToData(const Comment &comment, QMetaType::Type type)
{
switch (type) {
case QMetaType::Bool:
diff --git a/src/plugins/qmldesigner/components/annotationeditor/defaultannotations.cpp b/src/plugins/qmldesigner/components/annotationeditor/defaultannotations.cpp
index 7a9212d5353..d3a302a7829 100644
--- a/src/plugins/qmldesigner/components/annotationeditor/defaultannotations.cpp
+++ b/src/plugins/qmldesigner/components/annotationeditor/defaultannotations.cpp
@@ -58,7 +58,7 @@ bool DefaultAnnotationsModel::hasDefault(const Comment &comment) const
QMetaType::Type DefaultAnnotationsModel::defaultType(const Comment &comment) const
{
- return hasDefault(comment) ? QMetaType::Type(m_defaultMap[comment.title().toLower()].userType())
+ return hasDefault(comment) ? QMetaType::Type(m_defaultMap[comment.title().toLower()].typeId())
: QMetaType::UnknownType;
}
@@ -73,7 +73,7 @@ bool DefaultAnnotationsModel::isRichText(const Comment &comment) const
return type == QMetaType::UnknownType || type == qMetaTypeId();
}
-void DefaultAnnotationsModel::loadFromFile(QString const &filename)
+void DefaultAnnotationsModel::loadFromFile(const QString &filename)
{
QFile file(filename);
if (file.open(QFile::ReadOnly)) {
diff --git a/src/plugins/qmldesigner/components/bindingeditor/actioneditordialog.cpp b/src/plugins/qmldesigner/components/bindingeditor/actioneditordialog.cpp
index ba797ee1a77..8fddcb1ade8 100644
--- a/src/plugins/qmldesigner/components/bindingeditor/actioneditordialog.cpp
+++ b/src/plugins/qmldesigner/components/bindingeditor/actioneditordialog.cpp
@@ -88,7 +88,7 @@ void ActionEditorDialog::adjustProperties()
bool typeDone = false;
bool targetDone = false;
- for (int i = 0; i < expression.count(); ++i) {
+ for (int i = 0; i < expression.size(); ++i) {
switch (expression[i].first) {
case QmlJS::AST::Node::Kind::Kind_CallExpression:
@@ -592,7 +592,7 @@ void ActionEditorDialog::fillAndSetSourceProperty(const QString &value,
for (const auto &state : std::as_const(m_states))
m_assignmentSourceProperty->addItem(state, specificItem);
- specificsEnd = m_states.count();
+ specificsEnd = m_states.size();
}
if (specificsEnd != -1)
diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp
index 6cd3e814929..8c8d0911793 100644
--- a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp
+++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp
@@ -174,27 +174,38 @@ void BindingEditor::prepareBindings()
QList bindings;
- const QList variantTypes = {"alias", "unknown", "variant", "var"};
- const QList numericTypes = {"double", "real", "int"};
- const QList colorTypes = {"QColor", "color"};
- auto isVariant = [&variantTypes](const TypeName &compareType) { return variantTypes.contains(compareType); };
- auto isNumeric = [&numericTypes](const TypeName &compareType) { return numericTypes.contains(compareType); };
- auto isColor = [&colorTypes](const TypeName &compareType) { return colorTypes.contains(compareType); };
+ const QVarLengthArray variantTypes = {"alias", "unknown", "variant", "var"};
+ const QVarLengthArray numericTypes = {"double", "real", "int"};
+ const QVarLengthArray colorTypes = {"QColor", "color"};
+ const QVarLengthArray stringTypes = {"QString", "string"};
- const bool skipTypeFiltering = isVariant(m_backendValueTypeName);
- const bool targetTypeIsNumeric = isNumeric(m_backendValueTypeName);
+ auto isVariant = [&variantTypes](const TypeName &compareType) {
+ return variantTypes.contains(compareType);
+ };
+ auto isNumeric = [&numericTypes](const TypeName &compareType) {
+ return numericTypes.contains(compareType);
+ };
+ auto isColor = [&colorTypes](const TypeName &compareType) {
+ return colorTypes.contains(compareType);
+ };
+ auto isString = [&stringTypes](const TypeName &compareType) {
+ return stringTypes.contains(compareType);
+ };
+
+ auto compareTypes = [&](const TypeName &targetType, const TypeName &sourceType) {
+ return isVariant(targetType) || isVariant(sourceType) || (targetType == sourceType)
+ || (isNumeric(targetType) && isNumeric(sourceType))
+ || (isColor(targetType) && isColor(sourceType))
+ || (isString(targetType) && isString(sourceType));
+ };
for (const auto &objnode : allNodes) {
BindingEditorDialog::BindingOption binding;
for (const auto &property : objnode.metaInfo().properties()) {
const TypeName &propertyTypeName = property.propertyType().simplifiedTypeName();
- if (skipTypeFiltering
- || (m_backendValueTypeName == propertyTypeName)
- || isVariant(propertyTypeName)
- || (targetTypeIsNumeric && isNumeric(propertyTypeName))) {
+ if (compareTypes(m_backendValueTypeName, propertyTypeName))
binding.properties.append(QString::fromUtf8(property.name()));
- }
}
//dynamic properties:
@@ -202,12 +213,8 @@ void BindingEditor::prepareBindings()
if (bindingProperty.isValid()) {
if (bindingProperty.isDynamic()) {
const TypeName dynamicTypeName = bindingProperty.dynamicTypeName();
- if (skipTypeFiltering
- || (dynamicTypeName == m_backendValueTypeName)
- || isVariant(dynamicTypeName)
- || (targetTypeIsNumeric && isNumeric(dynamicTypeName))) {
+ if (compareTypes(m_backendValueTypeName, dynamicTypeName))
binding.properties.append(QString::fromUtf8(bindingProperty.name()));
- }
}
}
}
@@ -215,12 +222,8 @@ void BindingEditor::prepareBindings()
if (variantProperty.isValid()) {
if (variantProperty.isDynamic()) {
const TypeName dynamicTypeName = variantProperty.dynamicTypeName();
- if (skipTypeFiltering
- || (dynamicTypeName == m_backendValueTypeName)
- || isVariant(dynamicTypeName)
- || (targetTypeIsNumeric && isNumeric(dynamicTypeName))) {
+ if (compareTypes(m_backendValueTypeName, dynamicTypeName))
binding.properties.append(QString::fromUtf8(variantProperty.name()));
- }
}
}
}
@@ -241,15 +244,10 @@ void BindingEditor::prepareBindings()
BindingEditorDialog::BindingOption binding;
for (const auto &property : metaInfo.properties()) {
- TypeName propertyTypeName = property.propertyType().typeName();
+ const TypeName propertyTypeName = property.propertyType().typeName();
- if (skipTypeFiltering
- || (m_backendValueTypeName == propertyTypeName)
- || (isVariant(propertyTypeName))
- || (targetTypeIsNumeric && isNumeric(propertyTypeName))
- || (isColor(m_backendValueTypeName) && isColor(propertyTypeName))) {
+ if (compareTypes(m_backendValueTypeName, propertyTypeName))
binding.properties.append(QString::fromUtf8(property.name()));
- }
}
if (!binding.properties.isEmpty()) {
diff --git a/src/plugins/qmldesigner/components/componentcore/crumblebar.cpp b/src/plugins/qmldesigner/components/componentcore/crumblebar.cpp
index f4b6697c86b..005e353be25 100644
--- a/src/plugins/qmldesigner/components/componentcore/crumblebar.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/crumblebar.cpp
@@ -73,10 +73,8 @@ void CrumbleBar::pushFile(const Utils::FilePath &fileName)
}
if (match != -1) {
- for (int i = crumblePath()->length() - 1 - match; i > 0; --i) {
- crumblePath()->popElement();
- m_pathes.removeLast();
- }
+ for (int i = crumblePath()->length() - 1 - match; i > 0; --i)
+ popElement();
}
}
@@ -163,6 +161,14 @@ bool CrumbleBar::showSaveDialog()
return !canceled;
}
+void CrumbleBar::popElement()
+{
+ crumblePath()->popElement();
+
+ if (!m_pathes.isEmpty())
+ m_pathes.removeLast();
+}
+
void CrumbleBar::onCrumblePathElementClicked(const QVariant &data)
{
CrumbleBarInfo clickedCrumbleBarInfo = data.value();
@@ -176,15 +182,12 @@ void CrumbleBar::onCrumblePathElementClicked(const QVariant &data)
if (!inlineComp && !showSaveDialog())
return;
- while (clickedCrumbleBarInfo != crumblePath()->dataForLastIndex().value()) {
- crumblePath()->popElement();
- m_pathes.removeLast();
- }
+ while (clickedCrumbleBarInfo != crumblePath()->dataForLastIndex().value()
+ && crumblePath()->length() > 0)
+ popElement();
- if (crumblePath()->dataForLastIndex().value().modelNode.isValid()) {
- crumblePath()->popElement();
- m_pathes.removeLast();
- }
+ if (crumblePath()->dataForLastIndex().value().modelNode.isValid())
+ popElement();
m_isInternalCalled = true;
if (inlineComp) {
@@ -192,8 +195,7 @@ void CrumbleBar::onCrumblePathElementClicked(const QVariant &data)
currentDesignDocument()->changeToDocumentModel();
QmlDesignerPlugin::instance()->viewManager().setComponentViewToMaster();
} else {
- crumblePath()->popElement();
- m_pathes.removeLast();
+ popElement();
nextFileIsCalledInternally();
Core::EditorManager::openEditor(clickedCrumbleBarInfo.fileName,
Utils::Id(),
diff --git a/src/plugins/qmldesigner/components/componentcore/crumblebar.h b/src/plugins/qmldesigner/components/componentcore/crumblebar.h
index b9da4488f69..48e71efba6d 100644
--- a/src/plugins/qmldesigner/components/componentcore/crumblebar.h
+++ b/src/plugins/qmldesigner/components/componentcore/crumblebar.h
@@ -54,6 +54,7 @@ signals:
private:
void updateVisibility();
bool showSaveDialog();
+ void popElement();
private:
bool m_isInternalCalled = false;
diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
index 7243225c887..1562d13b0e4 100644
--- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
@@ -50,7 +50,7 @@
namespace QmlDesigner {
-static inline QString captionForModelNode(const ModelNode &modelNode)
+inline static QString captionForModelNode(const ModelNode &modelNode)
{
if (modelNode.id().isEmpty())
return modelNode.simplifiedTypeName();
@@ -58,7 +58,7 @@ static inline QString captionForModelNode(const ModelNode &modelNode)
return modelNode.id();
}
-static inline bool contains(const QmlItemNode &node, const QPointF &position)
+inline static bool contains(const QmlItemNode &node, const QPointF &position)
{
return node.isValid() && node.instanceSceneTransform().mapRect(node.instanceBoundingRect()).contains(position);
}
@@ -1208,7 +1208,7 @@ bool isStackedContainerAndIndexCanBeIncreased(const SelectionContext &context)
const int value = containerItemNode.instanceValue(propertyName).toInt();
- const int maxValue = currentSelectedNode.directSubModelNodes().count() - 1;
+ const int maxValue = currentSelectedNode.directSubModelNodes().size() - 1;
return value < maxValue;
}
diff --git a/src/plugins/qmldesigner/components/componentcore/formatoperation.cpp b/src/plugins/qmldesigner/components/componentcore/formatoperation.cpp
index 4676e0f46a9..546ad0cc6b0 100644
--- a/src/plugins/qmldesigner/components/componentcore/formatoperation.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/formatoperation.cpp
@@ -52,7 +52,7 @@ void readFormatConfiguration(){
QVariantMap rootMap = jsonObject.toVariantMap();
QJsonArray jsonArray = rootMap["propertylist"].toJsonArray();
- for (int i=0; i< jsonArray.count(); ++i){
+ for (int i = 0; i < jsonArray.size(); ++i) {
auto item = jsonArray.at(i).toObject();
QVariantMap itemMap = item.toVariantMap();
StylePropertyStruct current;
diff --git a/src/plugins/qmldesigner/components/componentcore/layoutingridlayout.cpp b/src/plugins/qmldesigner/components/componentcore/layoutingridlayout.cpp
index 09d3fdeffd9..89a5868d89d 100644
--- a/src/plugins/qmldesigner/components/componentcore/layoutingridlayout.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/layoutingridlayout.cpp
@@ -15,7 +15,7 @@
namespace QmlDesigner {
-static inline void reparentTo(const ModelNode &node, const QmlItemNode &parent)
+inline static void reparentTo(const ModelNode &node, const QmlItemNode &parent)
{
if (parent.isValid() && node.isValid()) {
@@ -78,7 +78,7 @@ static int lowerBound(int i)
return i;
}
-static inline QPointF getUpperLeftPosition(const QList &modelNodeList)
+inline static QPointF getUpperLeftPosition(const QList &modelNodeList)
{
QPointF postion(std::numeric_limits::max(), std::numeric_limits::max());
for (const ModelNode &modelNode : modelNodeList) {
@@ -193,7 +193,7 @@ void LayoutInGridLayout::doIt()
}
}
-bool static hasQtQuickLayoutImport(const SelectionContext &context)
+static bool hasQtQuickLayoutImport(const SelectionContext &context)
{
if (context.view() && context.view()->model()) {
Import import = Import::createLibraryImport(QStringLiteral("QtQuick.Layouts"), QStringLiteral("1.0"));
@@ -219,12 +219,12 @@ void LayoutInGridLayout::layout(const SelectionContext &context)
int LayoutInGridLayout::columnCount() const
{
- return m_xTopOffsets.count();
+ return m_xTopOffsets.size();
}
int LayoutInGridLayout::rowCount() const
{
- return m_yTopOffsets.count();
+ return m_yTopOffsets.size();
}
void LayoutInGridLayout::collectItemNodes()
diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp
index 258ae0ba925..d791b04672b 100644
--- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp
@@ -88,7 +88,7 @@ Utils::SmallString auxPropertyString(Utils::SmallStringView name)
}
} // namespace
-static inline void reparentTo(const ModelNode &node, const QmlItemNode &parent)
+inline static void reparentTo(const ModelNode &node, const QmlItemNode &parent)
{
if (parent.isValid() && node.isValid()) {
@@ -103,7 +103,7 @@ static inline void reparentTo(const ModelNode &node, const QmlItemNode &parent)
}
}
-static inline QPointF getUpperLeftPosition(const QList &modelNodeList)
+inline static QPointF getUpperLeftPosition(const QList &modelNodeList)
{
QPointF postion(std::numeric_limits::max(), std::numeric_limits::max());
for (const ModelNode &modelNode : modelNodeList) {
@@ -364,7 +364,7 @@ void reverse(const SelectionContext &selectionState)
});
}
-static inline void backupPropertyAndRemove(const ModelNode &node, const PropertyName &propertyName)
+inline static void backupPropertyAndRemove(const ModelNode &node, const PropertyName &propertyName)
{
if (node.hasVariantProperty(propertyName)) {
node.setAuxiliaryData(AuxiliaryDataType::Document,
@@ -695,7 +695,8 @@ void addSignalHandlerOrGotoImplementation(const SelectionContext &selectionState
Core::ModeManager::activateMode(Core::Constants::MODE_EDIT);
- if (!usages.isEmpty() && (addAlwaysNewSlot || usages.count() < 2) && (!isModelNodeRoot || addAlwaysNewSlot)) {
+ if (!usages.isEmpty() && (addAlwaysNewSlot || usages.size() < 2)
+ && (!isModelNodeRoot || addAlwaysNewSlot)) {
Core::EditorManager::openEditorAt(
{usages.constFirst().path, usages.constFirst().line, usages.constFirst().col});
@@ -879,7 +880,7 @@ void addItemToStackedContainer(const SelectionContext &selectionContext)
if (potentialTabBar.isValid()) {// The stacked container is hooked up to a TabBar
NodeMetaInfo tabButtonMetaInfo = view->model()->metaInfo("QtQuick.Controls.TabButton", -1, -1);
if (tabButtonMetaInfo.isValid()) {
- const int buttonIndex = potentialTabBar.directSubModelNodes().count();
+ const int buttonIndex = potentialTabBar.directSubModelNodes().size();
ModelNode tabButtonNode =
view->createModelNode("QtQuick.Controls.TabButton",
tabButtonMetaInfo.majorVersion(),
@@ -949,7 +950,7 @@ void increaseIndexOfStackedContainer(const SelectionContext &selectionContext)
int value = containerItemNode.instanceValue(propertyName).toInt();
++value;
- const int maxValue = container.directSubModelNodes().count();
+ const int maxValue = container.directSubModelNodes().size();
QTC_ASSERT(value < maxValue, return);
@@ -1012,7 +1013,7 @@ void addTabBarToStackedContainer(const SelectionContext &selectionContext)
container.parentProperty().reparentHere(tabBarNode);
- const int maxValue = container.directSubModelNodes().count();
+ const int maxValue = container.directSubModelNodes().size();
QmlItemNode tabBarItem(tabBarNode);
@@ -1239,8 +1240,7 @@ void setFlowStartItem(const SelectionContext &selectionContext)
});
}
-
-bool static hasStudioComponentsImport(const SelectionContext &context)
+static bool hasStudioComponentsImport(const SelectionContext &context)
{
if (context.view() && context.view()->model()) {
Import import = Import::createLibraryImport("QtQuick.Studio.Components", "1.0");
@@ -1250,7 +1250,7 @@ bool static hasStudioComponentsImport(const SelectionContext &context)
return false;
}
-static inline void setAdjustedPos(const QmlDesigner::ModelNode &modelNode)
+inline static void setAdjustedPos(const QmlDesigner::ModelNode &modelNode)
{
if (modelNode.hasParentProperty()) {
ModelNode parentNode = modelNode.parentProperty().parentModelNode();
diff --git a/src/plugins/qmldesigner/components/componentcore/svgpasteaction.cpp b/src/plugins/qmldesigner/components/componentcore/svgpasteaction.cpp
index 99bf56078b9..738b1affedd 100644
--- a/src/plugins/qmldesigner/components/componentcore/svgpasteaction.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/svgpasteaction.cpp
@@ -27,7 +27,7 @@ namespace {
/* Copied from qquicksvgparser.cpp 3e783b26a8fb41e3f5a53b883735f5d10fbbd98a */
// '0' is 0x30 and '9' is 0x39
-static inline bool isDigit(ushort ch)
+inline static bool isDigit(ushort ch)
{
static quint16 magic = 0x3ff;
return ((ch >> 4) == 3) && (magic >> (ch & 15));
@@ -110,7 +110,7 @@ static qreal toDouble(const QChar *&str)
return val;
}
-static inline void parseNumbersArray(const QChar *&str, QVarLengthArray &points)
+inline static void parseNumbersArray(const QChar *&str, QVarLengthArray &points)
{
while (str->isSpace())
++str;
@@ -261,7 +261,7 @@ bool parsePathDataFast(const QString &dataStr, QPainterPath &path)
if (pathElem == QLatin1Char('z') || pathElem == QLatin1Char('Z'))
arg.append(0);//dummy
const qreal *num = arg.constData();
- int count = arg.count();
+ int count = arg.size();
while (count > 0) {
qreal offsetX = x; // correction offsets
qreal offsetY = y; // for relative commands
diff --git a/src/plugins/qmldesigner/components/componentcore/theme.h b/src/plugins/qmldesigner/components/componentcore/theme.h
index 8e5f10d3615..a565ae03fcf 100644
--- a/src/plugins/qmldesigner/components/componentcore/theme.h
+++ b/src/plugins/qmldesigner/components/componentcore/theme.h
@@ -141,6 +141,7 @@ public:
editLightOn_medium,
edit_medium,
edit_small,
+ effects,
events_small,
export_medium,
eyeDropper,
@@ -326,6 +327,8 @@ public:
unpin,
upDownIcon,
upDownSquare2,
+ updateAvailable_medium,
+ updateContent_medium,
visibilityOff,
visibilityOn,
visible_medium,
diff --git a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp
index ee7ae3f6788..29bee73620a 100644
--- a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp
@@ -8,9 +8,8 @@
#include
#include
#include
-#include
-#include
#include
+#include
#include
#include
#include
@@ -23,12 +22,11 @@
#include
#include
#include
+#include
#include
-#include
#include
#include
#include
-#include
#include
@@ -38,14 +36,6 @@
namespace QmlDesigner {
-static bool useOldStatesEditor()
-{
- return QmlDesignerPlugin::instance()
- ->settings()
- .value(DesignerSettingsKey::OLD_STATES_EDITOR)
- .toBool();
-}
-
static Q_LOGGING_CATEGORY(viewBenchmark, "qtc.viewmanager.attach", QtWarningMsg)
class ViewManagerData
@@ -58,7 +48,8 @@ public:
, nodeInstanceView(QCoreApplication::arguments().contains("-capture-puppet-stream")
? capturingConnectionManager
: connectionManager,
- externalDependencies)
+ externalDependencies,
+ true)
, contentLibraryView{externalDependencies}
, componentView{externalDependencies}
, edit3DView{externalDependencies}
@@ -72,7 +63,6 @@ public:
, materialBrowserView{imageCache, externalDependencies}
, textureEditorView{imageCache, externalDependencies}
, statesEditorView{externalDependencies}
- , newStatesEditorView{externalDependencies}
{}
InteractiveConnectionManager connectionManager;
@@ -94,7 +84,6 @@ public:
MaterialBrowserView materialBrowserView;
TextureEditorView textureEditorView;
StatesEditorView statesEditorView;
- Experimental::StatesEditorView newStatesEditorView;
std::vector> additionalViews;
bool disableStandardViews = false;
@@ -176,30 +165,16 @@ void ViewManager::detachRewriterView()
void ViewManager::switchStateEditorViewToBaseState()
{
- if (useOldStatesEditor()) {
- if (d->statesEditorView.isAttached()) {
- d->savedState = d->statesEditorView.currentState();
- d->statesEditorView.setCurrentState(d->statesEditorView.baseState());
- }
- } else {
- // TODO remove old statesview
- if (d->newStatesEditorView.isAttached()) {
- d->savedState = d->newStatesEditorView.currentState();
- d->newStatesEditorView.setCurrentState(d->newStatesEditorView.baseState());
- }
+ if (d->statesEditorView.isAttached()) {
+ d->savedState = d->statesEditorView.currentState();
+ d->statesEditorView.setCurrentState(d->statesEditorView.baseState());
}
}
void ViewManager::switchStateEditorViewToSavedState()
{
- if (useOldStatesEditor()) {
- if (d->savedState.isValid() && d->statesEditorView.isAttached())
- d->statesEditorView.setCurrentState(d->savedState);
- } else {
- // TODO remove old statesview
- if (d->savedState.isValid() && d->newStatesEditorView.isAttached())
- d->newStatesEditorView.setCurrentState(d->savedState);
- }
+ if (d->savedState.isValid() && d->statesEditorView.isAttached())
+ d->statesEditorView.setCurrentState(d->savedState);
}
QList ViewManager::views() const
@@ -223,14 +198,8 @@ QList ViewManager::standardViews() const
&d->materialBrowserView,
&d->textureEditorView,
&d->statesEditorView,
- &d->newStatesEditorView, // TODO
&d->designerActionManagerView};
- if (useOldStatesEditor())
- list.removeAll(&d->newStatesEditorView);
- else
- list.removeAll(&d->statesEditorView);
-
if (QmlDesignerPlugin::instance()
->settings()
.value(DesignerSettingsKey::ENABLE_DEBUGVIEW)
@@ -410,10 +379,7 @@ QList ViewManager::widgetInfos() const
widgetInfoList.append(d->materialEditorView.widgetInfo());
widgetInfoList.append(d->materialBrowserView.widgetInfo());
widgetInfoList.append(d->textureEditorView.widgetInfo());
- if (useOldStatesEditor())
- widgetInfoList.append(d->statesEditorView.widgetInfo());
- else
- widgetInfoList.append(d->newStatesEditorView.widgetInfo());
+ widgetInfoList.append(d->statesEditorView.widgetInfo());
#ifdef CHECK_LICENSE
if (checkLicense() == FoundLicense::enterprise)
diff --git a/src/plugins/qmldesigner/components/connectioneditor/backendmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/backendmodel.cpp
index 6c970f2646d..5778d8242f7 100644
--- a/src/plugins/qmldesigner/components/connectioneditor/backendmodel.cpp
+++ b/src/plugins/qmldesigner/components/connectioneditor/backendmodel.cpp
@@ -203,7 +203,7 @@ void BackendModel::addNewBackend()
if (dialog.applied()) {
QStringList importSplit = dialog.importString().split(" ");
- if (importSplit.count() != 2) {
+ if (importSplit.size() != 2) {
qWarning() << Q_FUNC_INFO << "invalid import" << importSplit;
QTC_ASSERT(false, return);
}
diff --git a/src/plugins/qmldesigner/components/connectioneditor/bindingmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/bindingmodel.cpp
index e0a8f03e99e..191900d5e9d 100644
--- a/src/plugins/qmldesigner/components/connectioneditor/bindingmodel.cpp
+++ b/src/plugins/qmldesigner/components/connectioneditor/bindingmodel.cpp
@@ -217,7 +217,7 @@ static PropertyName unusedProperty(const ModelNode &modelNode)
void BindingModel::addBindingForCurrentNode()
{
- if (connectionView()->selectedModelNodes().count() == 1) {
+ if (connectionView()->selectedModelNodes().size() == 1) {
const ModelNode modelNode = connectionView()->selectedModelNodes().constFirst();
if (modelNode.isValid()) {
try {
@@ -380,9 +380,9 @@ bool BindingModel::getExpressionStrings(const BindingProperty &bindingProperty,
QString propertyName;
- for (int i=1; i < stringList.count(); i++) {
+ for (int i = 1; i < stringList.size(); i++) {
propertyName += stringList.at(i);
- if (i != stringList.count() - 1)
+ if (i != stringList.size() - 1)
propertyName += QLatin1String(".");
}
*sourceProperty = propertyName;
diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp
index 25a5756c28e..4abb7b21376 100644
--- a/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp
+++ b/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp
@@ -301,7 +301,7 @@ void ConnectionModel::addConnection()
nodeMetaInfo.minorVersion());
QString source = "console.log(\"clicked\")";
- if (connectionView()->selectedModelNodes().count() == 1) {
+ if (connectionView()->selectedModelNodes().size() == 1) {
ModelNode selectedNode = connectionView()->selectedModelNodes().constFirst();
if (QmlItemNode::isValidQmlItemNode(selectedNode))
selectedNode.nodeAbstractProperty("data").reparentHere(newNode);
diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectionview.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectionview.cpp
index 56fcc7ef6bf..d8f84f3e0fc 100644
--- a/src/plugins/qmldesigner/components/connectioneditor/connectionview.cpp
+++ b/src/plugins/qmldesigner/components/connectioneditor/connectionview.cpp
@@ -155,7 +155,7 @@ void ConnectionView::selectedNodesChanged(const QList & selectedNodeL
if (connectionViewWidget()->currentTab() == ConnectionViewWidget::BindingTab
|| connectionViewWidget()->currentTab() == ConnectionViewWidget::DynamicPropertiesTab)
- emit connectionViewWidget()->setEnabledAddButton(selectedNodeList.count() == 1);
+ emit connectionViewWidget()->setEnabledAddButton(selectedNodeList.size() == 1);
}
void ConnectionView::auxiliaryDataChanged([[maybe_unused]] const ModelNode &node,
diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp
index f1b0c3f4cbe..edade6ae400 100644
--- a/src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp
+++ b/src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp
@@ -347,14 +347,14 @@ void ConnectionViewWidget::invalidateButtonStatus()
} else if (currentTab() == BindingTab) {
emit setEnabledRemoveButton(ui->bindingView->selectionModel()->hasSelection());
auto bindingModel = qobject_cast(ui->bindingView->model());
- emit setEnabledAddButton(bindingModel->connectionView()->model() &&
- bindingModel->connectionView()->selectedModelNodes().count() == 1);
+ emit setEnabledAddButton(bindingModel->connectionView()->model()
+ && bindingModel->connectionView()->selectedModelNodes().size() == 1);
} else if (currentTab() == DynamicPropertiesTab) {
emit setEnabledRemoveButton(ui->dynamicPropertiesView->selectionModel()->hasSelection());
auto dynamicPropertiesModel = qobject_cast(ui->dynamicPropertiesView->model());
- emit setEnabledAddButton(dynamicPropertiesModel->view()->model() &&
- dynamicPropertiesModel->selectedNodes().count() == 1);
+ emit setEnabledAddButton(dynamicPropertiesModel->view()->model()
+ && dynamicPropertiesModel->selectedNodes().size() == 1);
} else if (currentTab() == BackendTab) {
emit setEnabledAddButton(true);
emit setEnabledRemoveButton(ui->backendView->selectionModel()->hasSelection());
diff --git a/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.cpp
index 89e08c5441f..4faf5d23f17 100644
--- a/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.cpp
+++ b/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.cpp
@@ -180,7 +180,7 @@ void DynamicPropertiesModel::resetModel()
// Value copying is optional
BindingProperty DynamicPropertiesModel::replaceVariantWithBinding(const PropertyName &name, bool copyValue)
{
- if (selectedNodes().count() == 1) {
+ if (selectedNodes().size() == 1) {
const ModelNode modelNode = selectedNodes().constFirst();
if (modelNode.isValid()) {
if (modelNode.hasVariantProperty(name)) {
@@ -214,7 +214,7 @@ BindingProperty DynamicPropertiesModel::replaceVariantWithBinding(const Property
// If it's a BindingProperty, then replaces it with empty VariantProperty
void DynamicPropertiesModel::resetProperty(const PropertyName &name)
{
- if (selectedNodes().count() == 1) {
+ if (selectedNodes().size() == 1) {
const ModelNode modelNode = selectedNodes().constFirst();
if (modelNode.isValid()) {
if (modelNode.hasProperty(name)) {
@@ -454,7 +454,7 @@ void DynamicPropertiesModel::addDynamicPropertyForCurrentNode()
{
QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_PROPERTY_ADDED);
- if (selectedNodes().count() == 1) {
+ if (selectedNodes().size() == 1) {
const ModelNode modelNode = selectedNodes().constFirst();
if (modelNode.isValid()) {
try {
@@ -839,9 +839,9 @@ bool DynamicPropertiesModel::getExpressionStrings(const BindingProperty &binding
QString propertyName;
- for (int i = 1; i < expressionParts.count(); ++i) {
+ for (int i = 1; i < expressionParts.size(); ++i) {
propertyName += expressionParts.at(i);
- if (i != expressionParts.count() - 1)
+ if (i != expressionParts.size() - 1)
propertyName += QLatin1String(".");
}
*sourceProperty = propertyName;
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffect.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffect.cpp
new file mode 100644
index 00000000000..f572fbe65f4
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffect.cpp
@@ -0,0 +1,78 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "contentlibraryeffect.h"
+
+#include
+
+namespace QmlDesigner {
+
+ContentLibraryEffect::ContentLibraryEffect(QObject *parent,
+ const QString &name,
+ const QString &qml,
+ const TypeName &type,
+ const QUrl &icon,
+ const QStringList &files)
+ : QObject(parent), m_name(name), m_qml(qml), m_type(type), m_icon(icon), m_files(files)
+{
+ m_allFiles = m_files;
+ m_allFiles.push_back(m_qml);
+}
+
+bool ContentLibraryEffect::filter(const QString &searchText)
+{
+ if (m_visible != m_name.contains(searchText, Qt::CaseInsensitive)) {
+ m_visible = !m_visible;
+ emit itemVisibleChanged();
+ }
+
+ return m_visible;
+}
+
+QUrl ContentLibraryEffect::icon() const
+{
+ return m_icon;
+}
+
+QString ContentLibraryEffect::qml() const
+{
+ return m_qml;
+}
+
+TypeName ContentLibraryEffect::type() const
+{
+ return m_type;
+}
+
+QStringList ContentLibraryEffect::files() const
+{
+ return m_files;
+}
+
+bool ContentLibraryEffect::visible() const
+{
+ return m_visible;
+}
+
+bool ContentLibraryEffect::setImported(bool imported)
+{
+ if (m_imported != imported) {
+ m_imported = imported;
+ emit itemImportedChanged();
+ return true;
+ }
+
+ return false;
+}
+
+bool ContentLibraryEffect::imported() const
+{
+ return m_imported;
+}
+
+QStringList ContentLibraryEffect::allFiles() const
+{
+ return m_allFiles;
+}
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffect.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffect.h
new file mode 100644
index 00000000000..fdb302b6139
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffect.h
@@ -0,0 +1,62 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "modelfwd.h"
+
+#include
+#include
+
+namespace QmlDesigner {
+
+class ContentLibraryEffect : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString bundleItemName MEMBER m_name CONSTANT)
+ Q_PROPERTY(QUrl bundleItemIcon MEMBER m_icon CONSTANT)
+ Q_PROPERTY(QStringList bundleItemFiles READ allFiles CONSTANT)
+ Q_PROPERTY(bool bundleItemVisible MEMBER m_visible NOTIFY itemVisibleChanged)
+ Q_PROPERTY(bool bundleItemImported READ imported WRITE setImported NOTIFY itemImportedChanged)
+
+public:
+ ContentLibraryEffect(QObject *parent,
+ const QString &name,
+ const QString &qml,
+ const TypeName &type,
+ const QUrl &icon,
+ const QStringList &files);
+
+ bool filter(const QString &searchText);
+
+ QUrl icon() const;
+ QString qml() const;
+ TypeName type() const;
+ QStringList files() const;
+ bool visible() const;
+ QString qmlFilePath() const;
+
+ bool setImported(bool imported);
+ bool imported() const;
+ QString parentDirPath() const;
+ QStringList allFiles() const;
+
+signals:
+ void itemVisibleChanged();
+ void itemImportedChanged();
+
+private:
+ QString m_name;
+ QString m_qml;
+ TypeName m_type;
+ QUrl m_icon;
+ QStringList m_files;
+
+ bool m_visible = true;
+ bool m_imported = false;
+
+ QStringList m_allFiles;
+};
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectscategory.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectscategory.cpp
new file mode 100644
index 00000000000..38e6eed3dad
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectscategory.cpp
@@ -0,0 +1,63 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "contentlibraryeffectscategory.h"
+
+#include "contentlibraryeffect.h"
+
+namespace QmlDesigner {
+
+ContentLibraryEffectsCategory::ContentLibraryEffectsCategory(QObject *parent, const QString &name)
+ : QObject(parent), m_name(name) {}
+
+void ContentLibraryEffectsCategory::addBundleItem(ContentLibraryEffect *bundleItem)
+{
+ m_categoryItems.append(bundleItem);
+}
+
+bool ContentLibraryEffectsCategory::updateImportedState(const QStringList &importedItems)
+{
+ bool changed = false;
+
+ for (ContentLibraryEffect *item : std::as_const(m_categoryItems))
+ changed |= item->setImported(importedItems.contains(item->qml().chopped(4)));
+
+ return changed;
+}
+
+bool ContentLibraryEffectsCategory::filter(const QString &searchText)
+{
+ bool visible = false;
+ for (ContentLibraryEffect *item : std::as_const(m_categoryItems))
+ visible |= item->filter(searchText);
+
+ if (visible != m_visible) {
+ m_visible = visible;
+ emit categoryVisibleChanged();
+ return true;
+ }
+
+ return false;
+}
+
+QString ContentLibraryEffectsCategory::name() const
+{
+ return m_name;
+}
+
+bool ContentLibraryEffectsCategory::visible() const
+{
+ return m_visible;
+}
+
+bool ContentLibraryEffectsCategory::expanded() const
+{
+ return m_expanded;
+}
+
+QList ContentLibraryEffectsCategory::categoryItems() const
+{
+ return m_categoryItems;
+}
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectscategory.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectscategory.h
new file mode 100644
index 00000000000..79737c1ec24
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectscategory.h
@@ -0,0 +1,47 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include
+
+namespace QmlDesigner {
+
+class ContentLibraryEffect;
+
+class ContentLibraryEffectsCategory : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString bundleCategoryName MEMBER m_name CONSTANT)
+ Q_PROPERTY(bool bundleCategoryVisible MEMBER m_visible NOTIFY categoryVisibleChanged)
+ Q_PROPERTY(bool bundleCategoryExpanded MEMBER m_expanded NOTIFY categoryExpandChanged)
+ Q_PROPERTY(QList bundleCategoryItems MEMBER m_categoryItems
+ NOTIFY categoryItemsChanged)
+
+public:
+ ContentLibraryEffectsCategory(QObject *parent, const QString &name);
+
+ void addBundleItem(ContentLibraryEffect *bundleItem);
+ bool updateImportedState(const QStringList &importedMats);
+ bool filter(const QString &searchText);
+
+ QString name() const;
+ bool visible() const;
+ bool expanded() const;
+ QList categoryItems() const;
+
+signals:
+ void categoryVisibleChanged();
+ void categoryExpandChanged();
+ void categoryItemsChanged();
+
+private:
+ QString m_name;
+ bool m_visible = true;
+ bool m_expanded = true;
+
+ QList m_categoryItems;
+};
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.cpp
new file mode 100644
index 00000000000..3bfd374bd81
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.cpp
@@ -0,0 +1,286 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "contentlibraryeffectsmodel.h"
+
+#include "contentlibrarybundleimporter.h"
+#include "contentlibraryeffect.h"
+#include "contentlibraryeffectscategory.h"
+#include "contentlibrarywidget.h"
+#include "qmldesignerconstants.h"
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+namespace QmlDesigner {
+
+ContentLibraryEffectsModel::ContentLibraryEffectsModel(ContentLibraryWidget *parent)
+ : QAbstractListModel(parent)
+ , m_widget(parent)
+{
+}
+
+int ContentLibraryEffectsModel::rowCount(const QModelIndex &) const
+{
+ return m_bundleCategories.size();
+}
+
+QVariant ContentLibraryEffectsModel::data(const QModelIndex &index, int role) const
+{
+ QTC_ASSERT(index.isValid() && index.row() < m_bundleCategories.count(), return {});
+ QTC_ASSERT(roleNames().contains(role), return {});
+
+ return m_bundleCategories.at(index.row())->property(roleNames().value(role));
+}
+
+bool ContentLibraryEffectsModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if (!index.isValid() || !roleNames().contains(role))
+ return false;
+
+ QByteArray roleName = roleNames().value(role);
+ ContentLibraryEffectsCategory *bundleCategory = m_bundleCategories.at(index.row());
+ QVariant currValue = bundleCategory->property(roleName);
+
+ if (currValue != value) {
+ bundleCategory->setProperty(roleName, value);
+
+ emit dataChanged(index, index, {role});
+ return true;
+ }
+
+ return false;
+}
+
+bool ContentLibraryEffectsModel::isValidIndex(int idx) const
+{
+ return idx > -1 && idx < rowCount();
+}
+
+void ContentLibraryEffectsModel::updateIsEmpty()
+{
+ bool anyCatVisible = Utils::anyOf(m_bundleCategories, [&](ContentLibraryEffectsCategory *cat) {
+ return cat->visible();
+ });
+
+ bool newEmpty = !anyCatVisible || m_bundleCategories.isEmpty() || !hasRequiredQuick3DImport();
+
+ if (newEmpty != m_isEmpty) {
+ m_isEmpty = newEmpty;
+ emit isEmptyChanged();
+ }
+}
+
+QHash ContentLibraryEffectsModel::roleNames() const
+{
+ static const QHash roles {
+ {Qt::UserRole + 1, "bundleCategoryName"},
+ {Qt::UserRole + 2, "bundleCategoryVisible"},
+ {Qt::UserRole + 3, "bundleCategoryExpanded"},
+ {Qt::UserRole + 4, "bundleCategoryItems"}
+ };
+ return roles;
+}
+
+void ContentLibraryEffectsModel::createImporter(const QString &bundlePath, const QString &bundleId,
+ const QStringList &sharedFiles)
+{
+ m_importer = new Internal::ContentLibraryBundleImporter(bundlePath, bundleId, sharedFiles);
+ connect(m_importer, &Internal::ContentLibraryBundleImporter::importFinished, this,
+ [&](const QmlDesigner::NodeMetaInfo &metaInfo) {
+ m_importerRunning = false;
+ emit importerRunningChanged();
+ if (metaInfo.isValid())
+ emit bundleItemImported(metaInfo);
+ });
+
+ connect(m_importer, &Internal::ContentLibraryBundleImporter::unimportFinished, this,
+ [&](const QmlDesigner::NodeMetaInfo &metaInfo) {
+ Q_UNUSED(metaInfo)
+ m_importerRunning = false;
+ emit importerRunningChanged();
+ emit bundleItemUnimported(metaInfo);
+ });
+
+ resetModel();
+ updateIsEmpty();
+}
+
+void ContentLibraryEffectsModel::loadBundle()
+{
+ if (m_bundleExists || m_probeBundleDir)
+ return;
+
+ QDir bundleDir = qEnvironmentVariable("EFFECT_BUNDLE_PATH");
+
+ // search for bundleDir from exec dir and up
+ if (bundleDir.dirName() == ".") {
+ m_probeBundleDir = true; // probe only once
+ bundleDir.setPath(QCoreApplication::applicationDirPath());
+ while (!bundleDir.cd("effect_bundle") && bundleDir.cdUp())
+ ; // do nothing
+
+ if (bundleDir.dirName() != "effect_bundle") // bundlePathDir not found
+ return;
+ }
+
+ QString bundlePath = bundleDir.filePath("effect_bundle.json");
+
+ if (m_bundleObj.isEmpty()) {
+ QFile propsFile(bundlePath);
+
+ if (!propsFile.open(QIODevice::ReadOnly)) {
+ qWarning("Couldn't open effect_bundle.json");
+ return;
+ }
+
+ QJsonDocument bundleJsonDoc = QJsonDocument::fromJson(propsFile.readAll());
+ if (bundleJsonDoc.isNull()) {
+ qWarning("Invalid effect_bundle.json file");
+ return;
+ } else {
+ m_bundleObj = bundleJsonDoc.object();
+ }
+ }
+
+ QString bundleId = m_bundleObj.value("id").toString();
+
+ const QJsonObject catsObj = m_bundleObj.value("categories").toObject();
+ const QStringList categories = catsObj.keys();
+ for (const QString &cat : categories) {
+ auto category = new ContentLibraryEffectsCategory(this, cat);
+
+ const QJsonObject itemsObj = catsObj.value(cat).toObject();
+ const QStringList items = itemsObj.keys();
+ for (const QString &item : items) {
+ const QJsonObject itemObj = itemsObj.value(item).toObject();
+
+ QStringList files;
+ const QJsonArray assetsArr = itemObj.value("files").toArray();
+ for (const auto /*QJson{Const,}ValueRef*/ &asset : assetsArr)
+ files.append(asset.toString());
+
+ QUrl icon = QUrl::fromLocalFile(bundleDir.filePath(itemObj.value("icon").toString()));
+ QString qml = itemObj.value("qml").toString();
+ TypeName type = QLatin1String("%1.%2.%3").arg(
+ QLatin1String(Constants::COMPONENT_BUNDLES_FOLDER).mid(1),
+ bundleId,
+ qml.chopped(4)).toLatin1(); // chopped(4): remove .qml
+
+ auto bundleItem = new ContentLibraryEffect(category, item, qml, type, icon, files);
+
+ category->addBundleItem(bundleItem);
+ }
+ m_bundleCategories.append(category);
+ }
+
+ QStringList sharedFiles;
+ const QJsonArray sharedFilesArr = m_bundleObj.value("sharedFiles").toArray();
+ for (const auto /*QJson{Const,}ValueRef*/ &file : sharedFilesArr)
+ sharedFiles.append(file.toString());
+
+ createImporter(bundleDir.path(), bundleId, sharedFiles);
+
+ m_bundleExists = true;
+ emit bundleExistsChanged();
+}
+
+bool ContentLibraryEffectsModel::hasRequiredQuick3DImport() const
+{
+ return m_widget->hasQuick3DImport() && m_quick3dMajorVersion == 6 && m_quick3dMinorVersion >= 4;
+}
+
+bool ContentLibraryEffectsModel::bundleExists() const
+{
+ return m_bundleExists;
+}
+
+Internal::ContentLibraryBundleImporter *ContentLibraryEffectsModel::bundleImporter() const
+{
+ return m_importer;
+}
+
+void ContentLibraryEffectsModel::setSearchText(const QString &searchText)
+{
+ QString lowerSearchText = searchText.toLower();
+
+ if (m_searchText == lowerSearchText)
+ return;
+
+ m_searchText = lowerSearchText;
+
+ for (int i = 0; i < m_bundleCategories.size(); ++i) {
+ ContentLibraryEffectsCategory *cat = m_bundleCategories.at(i);
+ bool catVisibilityChanged = cat->filter(m_searchText);
+ if (catVisibilityChanged)
+ emit dataChanged(index(i), index(i), {roleNames().keys("bundleCategoryVisible")});
+ }
+
+ updateIsEmpty();
+}
+
+void ContentLibraryEffectsModel::updateImportedState(const QStringList &importedItems)
+{
+ bool changed = false;
+ for (ContentLibraryEffectsCategory *cat : std::as_const(m_bundleCategories))
+ changed |= cat->updateImportedState(importedItems);
+
+ if (changed)
+ resetModel();
+}
+
+void ContentLibraryEffectsModel::setQuick3DImportVersion(int major, int minor)
+{
+ bool oldRequiredImport = hasRequiredQuick3DImport();
+
+ m_quick3dMajorVersion = major;
+ m_quick3dMinorVersion = minor;
+
+ bool newRequiredImport = hasRequiredQuick3DImport();
+
+ if (oldRequiredImport == newRequiredImport)
+ return;
+
+ emit hasRequiredQuick3DImportChanged();
+
+ updateIsEmpty();
+}
+
+void ContentLibraryEffectsModel::resetModel()
+{
+ beginResetModel();
+ endResetModel();
+}
+
+void ContentLibraryEffectsModel::addInstance(ContentLibraryEffect *bundleItem)
+{
+ QString err = m_importer->importComponent(bundleItem->qml(), bundleItem->files());
+
+ if (err.isEmpty()) {
+ m_importerRunning = true;
+ emit importerRunningChanged();
+ } else {
+ qWarning() << __FUNCTION__ << err;
+ }
+}
+
+void ContentLibraryEffectsModel::removeFromProject(ContentLibraryEffect *bundleItem)
+{
+ emit bundleItemAboutToUnimport(bundleItem->type());
+
+ QString err = m_importer->unimportComponent(bundleItem->qml());
+
+ if (err.isEmpty()) {
+ m_importerRunning = true;
+ emit importerRunningChanged();
+ } else {
+ qWarning() << __FUNCTION__ << err;
+ }
+}
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.h
new file mode 100644
index 00000000000..104d34af2d2
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.h
@@ -0,0 +1,90 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "nodemetainfo.h"
+
+#include
+#include
+#include
+
+namespace QmlDesigner {
+
+class ContentLibraryEffect;
+class ContentLibraryEffectsCategory;
+class ContentLibraryWidget;
+
+namespace Internal {
+class ContentLibraryBundleImporter;
+}
+
+class ContentLibraryEffectsModel : public QAbstractListModel
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool bundleExists READ bundleExists NOTIFY bundleExistsChanged)
+ Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged)
+ Q_PROPERTY(bool hasRequiredQuick3DImport READ hasRequiredQuick3DImport NOTIFY hasRequiredQuick3DImportChanged)
+ Q_PROPERTY(bool importerRunning MEMBER m_importerRunning NOTIFY importerRunningChanged)
+
+public:
+ ContentLibraryEffectsModel(ContentLibraryWidget *parent = nullptr);
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ bool setData(const QModelIndex &index, const QVariant &value, int role) override;
+ QHash roleNames() const override;
+
+ void loadBundle();
+ void setSearchText(const QString &searchText);
+ void updateImportedState(const QStringList &importedItems);
+
+ void setQuick3DImportVersion(int major, int minor);
+
+ bool hasRequiredQuick3DImport() const;
+
+ bool bundleExists() const;
+
+ void resetModel();
+ void updateIsEmpty();
+
+ Internal::ContentLibraryBundleImporter *bundleImporter() const;
+
+ Q_INVOKABLE void addInstance(QmlDesigner::ContentLibraryEffect *bundleItem);
+ Q_INVOKABLE void removeFromProject(QmlDesigner::ContentLibraryEffect *bundleItem);
+
+signals:
+ void isEmptyChanged();
+ void hasRequiredQuick3DImportChanged();
+ void bundleItemImported(const QmlDesigner::NodeMetaInfo &metaInfo);
+ void bundleItemAboutToUnimport(const QmlDesigner::TypeName &type);
+ void bundleItemUnimported(const QmlDesigner::NodeMetaInfo &metaInfo);
+ void importerRunningChanged();
+ void bundleExistsChanged();
+
+private:
+ bool isValidIndex(int idx) const;
+ void createImporter(const QString &bundlePath, const QString &bundleId,
+ const QStringList &sharedFiles);
+
+ ContentLibraryWidget *m_widget = nullptr;
+ QString m_searchText;
+ QList m_bundleCategories;
+ QJsonObject m_bundleObj;
+ Internal::ContentLibraryBundleImporter *m_importer = nullptr;
+
+ bool m_isEmpty = true;
+ bool m_bundleExists = false;
+ bool m_probeBundleDir = false;
+ bool m_importerRunning = false;
+
+ int m_quick3dMajorVersion = -1;
+ int m_quick3dMinorVersion = -1;
+
+ QString m_importerBundlePath;
+ QString m_importerBundleId;
+ QStringList m_importerSharedFiles;
+};
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryiconprovider.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryiconprovider.cpp
new file mode 100644
index 00000000000..96102bf8379
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryiconprovider.cpp
@@ -0,0 +1,42 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "contentlibraryiconprovider.h"
+
+#include
+
+namespace QmlDesigner {
+
+namespace Internal {
+
+ContentLibraryIconProvider::ContentLibraryIconProvider()
+ : QQuickImageProvider(Pixmap)
+{
+
+}
+
+QPixmap ContentLibraryIconProvider::requestPixmap(const QString &id,
+ QSize *size,
+ [[maybe_unused]] const QSize &requestedSize)
+{
+ QString realPath = Core::ICore::resourcePath("qmldesigner/contentLibraryImages/" + id).toString();
+
+ QPixmap pixmap{realPath};
+
+ if (size) {
+ size->setWidth(pixmap.width());
+ size->setHeight(pixmap.height());
+ }
+
+ if (pixmap.isNull())
+ return pixmap;
+
+ if (requestedSize.isValid())
+ return pixmap.scaled(requestedSize);
+
+ return pixmap;
+}
+
+} // namespace Internal
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryiconprovider.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryiconprovider.h
new file mode 100644
index 00000000000..56633959d6a
--- /dev/null
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryiconprovider.h
@@ -0,0 +1,17 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include
+
+namespace QmlDesigner::Internal {
+
+class ContentLibraryIconProvider : public QQuickImageProvider
+{
+public:
+ ContentLibraryIconProvider();
+ QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) override;
+};
+
+} // namespace QmlDesigner::Internal
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp
index f272a4121df..e5ee371002e 100644
--- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp
@@ -53,7 +53,7 @@ int ContentLibraryMaterialsModel::rowCount(const QModelIndex &) const
QVariant ContentLibraryMaterialsModel::data(const QModelIndex &index, int role) const
{
- QTC_ASSERT(index.isValid() && index.row() < m_bundleCategories.count(), return {});
+ QTC_ASSERT(index.isValid() && index.row() < m_bundleCategories.size(), return {});
QTC_ASSERT(roleNames().contains(role), return {});
return m_bundleCategories.at(index.row())->property(roleNames().value(role));
@@ -332,14 +332,14 @@ void ContentLibraryMaterialsModel::setSearchText(const QString &searchText)
m_searchText = lowerSearchText;
- bool catVisibilityChanged = false;
- for (ContentLibraryMaterialsCategory *cat : std::as_const(m_bundleCategories))
- catVisibilityChanged |= cat->filter(m_searchText);
+ for (int i = 0; i < m_bundleCategories.size(); ++i) {
+ ContentLibraryMaterialsCategory *cat = m_bundleCategories.at(i);
+ bool catVisibilityChanged = cat->filter(m_searchText);
+ if (catVisibilityChanged)
+ emit dataChanged(index(i), index(i), {roleNames().keys("bundleCategoryVisible")});
+ }
updateIsEmpty();
-
- if (catVisibilityChanged)
- resetModel();
}
void ContentLibraryMaterialsModel::updateImportedState(const QStringList &importedMats)
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.cpp
index fbc5199f989..7ab239aab4e 100644
--- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.cpp
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.cpp
@@ -13,17 +13,23 @@ namespace QmlDesigner {
ContentLibraryTexture::ContentLibraryTexture(QObject *parent, const QFileInfo &iconFileInfo,
const QString &downloadPath, const QUrl &icon,
- const QString &webUrl, const QString &fileExt,
- const QSize &dimensions, const qint64 sizeInBytes)
+ const QString &key, const QString &webTextureUrl,
+ const QString &webIconUrl, const QString &fileExt,
+ const QSize &dimensions, const qint64 sizeInBytes,
+ bool hasUpdate, bool isNew)
: QObject(parent)
, m_iconPath(iconFileInfo.filePath())
, m_downloadPath(downloadPath)
- , m_webUrl(webUrl)
+ , m_webTextureUrl(webTextureUrl)
+ , m_webIconUrl(webIconUrl)
, m_baseName{iconFileInfo.baseName()}
, m_fileExt(fileExt)
+ , m_textureKey(key)
, m_icon(icon)
, m_dimensions(dimensions)
, m_sizeInBytes(sizeInBytes)
+ , m_hasUpdate(hasUpdate)
+ , m_isNew(isNew)
{
doSetDownloaded();
}
@@ -58,7 +64,7 @@ QString ContentLibraryTexture::resolveFileExt()
if (textureFiles.isEmpty())
return {};
- if (textureFiles.count() > 1) {
+ if (textureFiles.size() > 1) {
qWarning() << "Found multiple textures with the same name in the same directories: "
<< Utils::transform(textureFiles, [](const QFileInfo &fi) {
return fi.fileName();
@@ -122,4 +128,22 @@ QString ContentLibraryTexture::parentDirPath() const
return m_downloadPath;
}
+QString ContentLibraryTexture::textureKey() const
+{
+ return m_textureKey;
+}
+
+void ContentLibraryTexture::setHasUpdate(bool value)
+{
+ if (m_hasUpdate != value) {
+ m_hasUpdate = value;
+ emit hasUpdateChanged();
+ }
+}
+
+bool ContentLibraryTexture::hasUpdate() const
+{
+ return m_hasUpdate;
+}
+
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.h
index 074d4abb770..9f5b46630f6 100644
--- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.h
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.h
@@ -19,12 +19,17 @@ class ContentLibraryTexture : public QObject
Q_PROPERTY(QString textureToolTip MEMBER m_toolTip NOTIFY textureToolTipChanged)
Q_PROPERTY(QUrl textureIcon MEMBER m_icon CONSTANT)
Q_PROPERTY(bool textureVisible MEMBER m_visible NOTIFY textureVisibleChanged)
- Q_PROPERTY(QString textureWebUrl MEMBER m_webUrl CONSTANT)
+ Q_PROPERTY(QString textureWebUrl MEMBER m_webTextureUrl CONSTANT)
+ Q_PROPERTY(QString textureWebIconUrl MEMBER m_webIconUrl CONSTANT)
+ Q_PROPERTY(bool textureHasUpdate WRITE setHasUpdate READ hasUpdate NOTIFY hasUpdateChanged)
+ Q_PROPERTY(bool textureIsNew MEMBER m_isNew CONSTANT)
+ Q_PROPERTY(QString textureKey MEMBER m_textureKey CONSTANT)
public:
- ContentLibraryTexture(QObject *parent, const QFileInfo &iconFileInfo,
- const QString &downloadPath, const QUrl &icon, const QString &webUrl,
- const QString &fileExt, const QSize &dimensions, const qint64 sizeInBytes);
+ ContentLibraryTexture(QObject *parent, const QFileInfo &iconFileInfo, const QString &downloadPath,
+ const QUrl &icon, const QString &key, const QString &webTextureUrl,
+ const QString &webIconUrl, const QString &fileExt, const QSize &dimensions,
+ const qint64 sizeInBytes, bool hasUpdate, bool isNew);
Q_INVOKABLE bool isDownloaded() const;
Q_INVOKABLE void setDownloaded();
@@ -35,10 +40,15 @@ public:
QString iconPath() const;
QString downloadedTexturePath() const;
QString parentDirPath() const;
+ QString textureKey() const;
+
+ void setHasUpdate(bool value);
+ bool hasUpdate() const;
signals:
void textureVisibleChanged();
void textureToolTipChanged();
+ void hasUpdateChanged();
private:
QString resolveFileExt();
@@ -47,16 +57,20 @@ private:
QString m_iconPath;
QString m_downloadPath;
- QString m_webUrl;
+ QString m_webTextureUrl;
+ QString m_webIconUrl;
QString m_toolTip;
QString m_baseName;
QString m_fileExt;
+ QString m_textureKey;
QUrl m_icon;
QSize m_dimensions;
qint64 m_sizeInBytes = -1;
bool m_isDownloaded = false;
bool m_visible = true;
+ bool m_hasUpdate = false;
+ bool m_isNew = false;
};
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturescategory.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturescategory.cpp
index eecab425523..77519ad88f6 100644
--- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturescategory.cpp
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturescategory.cpp
@@ -5,6 +5,8 @@
#include "contentlibrarytexture.h"
+#include
+
#include
namespace QmlDesigner {
@@ -13,13 +15,16 @@ ContentLibraryTexturesCategory::ContentLibraryTexturesCategory(QObject *parent,
: QObject(parent), m_name(name) {}
void ContentLibraryTexturesCategory::addTexture(const QFileInfo &tex, const QString &downloadPath,
- const QString &webUrl, const QString &fileExt,
- const QSize &dimensions, const qint64 sizeInBytes)
+ const QString &key, const QString &webTextureUrl,
+ const QString &webIconUrl, const QString &fileExt,
+ const QSize &dimensions, const qint64 sizeInBytes,
+ bool hasUpdate, bool isNew)
{
QUrl icon = QUrl::fromLocalFile(tex.absoluteFilePath());
- m_categoryTextures.append(new ContentLibraryTexture(this, tex, downloadPath, icon, webUrl,
- fileExt, dimensions, sizeInBytes));
+ m_categoryTextures.append(new ContentLibraryTexture(
+ this, tex, downloadPath, icon, key, webTextureUrl, webIconUrl,
+ fileExt, dimensions, sizeInBytes, hasUpdate, isNew));
}
bool ContentLibraryTexturesCategory::filter(const QString &searchText)
@@ -57,4 +62,14 @@ QList ContentLibraryTexturesCategory::categoryTextures(
return m_categoryTextures;
}
+void ContentLibraryTexturesCategory::markTextureHasNoUpdate(const QString &textureKey)
+{
+ auto *texture = Utils::findOrDefault(m_categoryTextures, [&textureKey](ContentLibraryTexture *t) {
+ return t->textureKey() == textureKey;
+ });
+
+ if (texture)
+ texture->setHasUpdate(false);
+}
+
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturescategory.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturescategory.h
index 91ecaaac969..166528f05a8 100644
--- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturescategory.h
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturescategory.h
@@ -27,8 +27,9 @@ class ContentLibraryTexturesCategory : public QObject
public:
ContentLibraryTexturesCategory(QObject *parent, const QString &name);
- void addTexture(const QFileInfo &tex, const QString &subPath, const QString &webUrl,
- const QString &fileExt, const QSize &dimensions, const qint64 sizeInBytes);
+ void addTexture(const QFileInfo &tex, const QString &subPath, const QString &key,
+ const QString &webTextureUrl, const QString &webIconUrl, const QString &fileExt,
+ const QSize &dimensions, const qint64 sizeInBytes, bool hasUpdate, bool isNew);
bool filter(const QString &searchText);
QString name() const;
@@ -36,6 +37,8 @@ public:
bool expanded() const;
QList categoryTextures() const;
+ void markTextureHasNoUpdate(const QString &textureKey);
+
signals:
void categoryVisibleChanged();
void categoryExpandChanged();
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.cpp
index 5cf88ab6fcd..319ca2686f2 100644
--- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.cpp
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.cpp
@@ -36,7 +36,7 @@ int ContentLibraryTexturesModel::rowCount(const QModelIndex &) const
QVariant ContentLibraryTexturesModel::data(const QModelIndex &index, int role) const
{
- QTC_ASSERT(index.isValid() && index.row() < m_bundleCategories.count(), return {});
+ QTC_ASSERT(index.isValid() && index.row() < m_bundleCategories.size(), return {});
QTC_ASSERT(roleNames().contains(role), return {});
return m_bundleCategories.at(index.row())->property(roleNames().value(role));
@@ -98,7 +98,8 @@ QHash ContentLibraryTexturesModel::roleNames() const
* @param bundlePath local path to the bundle folder and icons
* @param metaData bundle textures metadata
*/
-void ContentLibraryTexturesModel::loadTextureBundle(const QString &remoteUrl, const QString &bundleIconPath,
+void ContentLibraryTexturesModel::loadTextureBundle(const QString &remoteUrl, const QString &iconsUrl,
+ const QString &bundleIconPath,
const QVariantMap &metaData)
{
if (!m_bundleCategories.isEmpty())
@@ -117,8 +118,9 @@ void ContentLibraryTexturesModel::loadTextureBundle(const QString &remoteUrl, co
auto category = new ContentLibraryTexturesCategory(this, dir.fileName());
const QFileInfoList texFiles = QDir(dir.filePath()).entryInfoList(QDir::Files);
for (const QFileInfo &tex : texFiles) {
- QString fullRemoteUrl = QString("%1/%2/%3.zip").arg(remoteUrl, dir.fileName(),
- tex.baseName());
+ QString textureUrl = QString("%1/%2/%3.zip").arg(remoteUrl, dir.fileName(), tex.baseName());
+ QString iconUrl = QString("%1/%2/%3.png").arg(iconsUrl, dir.fileName(), tex.baseName());
+
QString localDownloadPath = QString("%1/%2/%3")
.arg(Paths::bundlesPathSetting(),
m_category,
@@ -127,15 +129,20 @@ void ContentLibraryTexturesModel::loadTextureBundle(const QString &remoteUrl, co
QString fileExt;
QSize dimensions;
qint64 sizeInBytes = -1;
+ bool hasUpdate = false;
+ bool isNew = false;
if (imageItems.contains(key)) {
QVariantMap dataMap = imageItems[key].toMap();
fileExt = '.' + dataMap.value("format").toString();
dimensions = QSize(dataMap.value("width").toInt(), dataMap.value("height").toInt());
sizeInBytes = dataMap.value("file_size").toLongLong();
+ hasUpdate = m_modifiedFiles.contains(key);
+ isNew = m_newFiles.contains(key);
}
- category->addTexture(tex, localDownloadPath, fullRemoteUrl, fileExt, dimensions, sizeInBytes);
+ category->addTexture(tex, localDownloadPath, key, textureUrl, iconUrl, fileExt,
+ dimensions, sizeInBytes, hasUpdate, isNew);
}
m_bundleCategories.append(category);
}
@@ -144,6 +151,52 @@ void ContentLibraryTexturesModel::loadTextureBundle(const QString &remoteUrl, co
updateIsEmpty();
}
+void ContentLibraryTexturesModel::setModifiedFileEntries(const QVariantMap &files)
+{
+ m_modifiedFiles.clear();
+
+ const QString prefix = m_category + "/";
+ const QStringList keys = files.keys();
+
+ for (const QString &key : keys) {
+ if (key.startsWith(prefix))
+ m_modifiedFiles[key] = files[key];
+ }
+}
+
+void ContentLibraryTexturesModel::setNewFileEntries(const QStringList &newFiles)
+{
+ const QString prefix = m_category + "/";
+
+ m_newFiles = Utils::filteredCast>(newFiles, [&prefix](const QString &key) {
+ return key.startsWith(prefix);
+ });
+}
+
+QString ContentLibraryTexturesModel::removeModifiedFileEntry(const QString &key)
+{
+ if (m_modifiedFiles.contains(key)) {
+ QVariantMap item = m_modifiedFiles[key].toMap();
+ m_modifiedFiles.remove(key);
+ return item["checksum"].toString();
+ } else {
+ return {};
+ }
+}
+
+void ContentLibraryTexturesModel::markTextureHasNoUpdates(const QString &subcategory,
+ const QString &textureKey)
+{
+ auto *categ = Utils::findOrDefault(m_bundleCategories,
+ [&subcategory](ContentLibraryTexturesCategory *c) {
+ return c->name() == subcategory;
+ });
+ if (!categ)
+ return;
+
+ categ->markTextureHasNoUpdate(textureKey);
+}
+
bool ContentLibraryTexturesModel::texBundleExists() const
{
return !m_bundleCategories.isEmpty();
@@ -172,15 +225,14 @@ void ContentLibraryTexturesModel::setSearchText(const QString &searchText)
m_searchText = lowerSearchText;
- bool catVisibilityChanged = false;
-
- for (ContentLibraryTexturesCategory *cat : std::as_const(m_bundleCategories))
- catVisibilityChanged |= cat->filter(m_searchText);
+ for (int i = 0; i < m_bundleCategories.size(); ++i) {
+ ContentLibraryTexturesCategory *cat = m_bundleCategories.at(i);
+ bool catVisibilityChanged = cat->filter(m_searchText);
+ if (catVisibilityChanged)
+ emit dataChanged(index(i), index(i), {roleNames().keys("bundleCategoryVisible")});
+ }
updateIsEmpty();
-
- if (catVisibilityChanged)
- resetModel();
}
void ContentLibraryTexturesModel::resetModel()
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.h
index 3f7e4d48688..92db4151a84 100644
--- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.h
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.h
@@ -26,6 +26,10 @@ public:
QHash roleNames() const override;
void setSearchText(const QString &searchText);
+ void setModifiedFileEntries(const QVariantMap &files);
+ void setNewFileEntries(const QStringList &newFiles);
+ QString removeModifiedFileEntry(const QString &key);
+ void markTextureHasNoUpdates(const QString &subcategory, const QString &textureKey);
bool texBundleExists() const;
@@ -33,8 +37,8 @@ public:
void setHasSceneEnv(bool b);
void resetModel();
- void loadTextureBundle(const QString &remoteUrl, const QString &bundlePath,
- const QVariantMap &metaData);
+ void loadTextureBundle(const QString &remoteUrl, const QString &iconsUrl,
+ const QString &bundlePath, const QVariantMap &metaData);
signals:
void isEmptyChanged();
@@ -48,6 +52,8 @@ private:
QString m_searchText;
QString m_category;
QList m_bundleCategories;
+ QVariantMap m_modifiedFiles;
+ QSet m_newFiles;
bool m_isEmpty = true;
bool m_hasSceneEnv = false;
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp
index 3bb579273f6..3f64f8d8b4f 100644
--- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp
@@ -4,6 +4,8 @@
#include "contentlibraryview.h"
#include "contentlibrarybundleimporter.h"
+#include "contentlibraryeffect.h"
+#include "contentlibraryeffectsmodel.h"
#include "contentlibrarymaterial.h"
#include "contentlibrarymaterialsmodel.h"
#include "contentlibrarytexture.h"
@@ -26,6 +28,8 @@
#include
#endif
+#include
+
namespace QmlDesigner {
ContentLibraryView::ContentLibraryView(ExternalDependenciesInterface &externalDependencies)
@@ -54,6 +58,10 @@ WidgetInfo ContentLibraryView::widgetInfo()
[&] (QmlDesigner::ContentLibraryTexture *tex) {
m_draggedBundleTexture = tex;
});
+ connect(m_widget, &ContentLibraryWidget::bundleEffectDragStarted, this,
+ [&] (QmlDesigner::ContentLibraryEffect *eff) {
+ m_draggedBundleEffect = eff;
+ });
connect(m_widget, &ContentLibraryWidget::addTextureRequested, this,
[&] (const QString &texPath, AddTextureMode mode) {
@@ -109,6 +117,46 @@ WidgetInfo ContentLibraryView::widgetInfo()
connect(materialsModel, &ContentLibraryMaterialsModel::bundleMaterialUnimported, this,
&ContentLibraryView::updateBundleMaterialsImportedState);
+
+ ContentLibraryEffectsModel *effectsModel = m_widget->effectsModel().data();
+
+ connect(effectsModel, &ContentLibraryEffectsModel::bundleItemImported, this,
+ [&] (const QmlDesigner::NodeMetaInfo &metaInfo) {
+ QTC_ASSERT(metaInfo.isValid(), return);
+
+ if (!m_bundleEffectTarget)
+ m_bundleEffectTarget = active3DSceneNode();
+
+ QTC_ASSERT(m_bundleEffectTarget, return);
+
+ executeInTransaction("ContentLibraryView::widgetInfo", [&] {
+ QVector3D pos = m_bundleEffectPos.value();
+ ModelNode newEffNode = createModelNode(metaInfo.typeName(), metaInfo.majorVersion(),
+ metaInfo.minorVersion(),
+ {{"x", pos.x()}, {"y", pos.y()}, {"z", pos.z()}});
+ m_bundleEffectTarget.defaultNodeListProperty().reparentHere(newEffNode);
+ clearSelectedModelNodes();
+ selectModelNode(newEffNode);
+ });
+
+ updateBundleEffectsImportedState();
+ m_bundleEffectTarget = {};
+ m_bundleEffectPos = {};
+ });
+
+ connect(effectsModel, &ContentLibraryEffectsModel::bundleItemAboutToUnimport, this,
+ [&] (const QmlDesigner::TypeName &type) {
+ // delete instances of the bundle effect that is about to be unimported
+ executeInTransaction("ContentLibraryView::widgetInfo", [&] {
+ NodeMetaInfo metaInfo = model()->metaInfo(type);
+ QList effects = allModelNodesOfType(metaInfo);
+ for (ModelNode &eff : effects)
+ eff.destroy();
+ });
+ });
+
+ connect(effectsModel, &ContentLibraryEffectsModel::bundleItemUnimported, this,
+ &ContentLibraryView::updateBundleEffectsImportedState);
}
return createWidgetInfo(m_widget.data(),
@@ -124,7 +172,7 @@ void ContentLibraryView::modelAttached(Model *model)
m_hasQuick3DImport = model->hasImport("QtQuick3D");
- updateBundleMaterialsQuick3DVersion();
+ updateBundlesQuick3DVersion();
updateBundleMaterialsImportedState();
const bool hasLibrary = materialLibraryNode().isValid();
@@ -134,6 +182,9 @@ void ContentLibraryView::modelAttached(Model *model)
m_sceneId = model->active3DSceneId();
m_widget->clearSearchFilter();
+
+ m_widget->effectsModel()->loadBundle();
+ updateBundleEffectsImportedState();
}
void ContentLibraryView::modelAboutToBeDetached(Model *model)
@@ -149,7 +200,7 @@ void ContentLibraryView::importsChanged(const Imports &addedImports, const Impor
Q_UNUSED(addedImports)
Q_UNUSED(removedImports)
- updateBundleMaterialsQuick3DVersion();
+ updateBundlesQuick3DVersion();
bool hasQuick3DImport = model()->hasImport("QtQuick3D");
@@ -211,6 +262,12 @@ void ContentLibraryView::customNotification(const AbstractView *view, const QStr
m_widget->addTexture(m_draggedBundleTexture);
m_draggedBundleTexture = nullptr;
+ } else if (identifier == "drop_bundle_effect") {
+ QTC_ASSERT(nodeList.size() == 1, return);
+
+ m_bundleEffectPos = data.size() == 1 ? data.first() : QVariant();
+ m_widget->effectsModel()->addInstance(m_draggedBundleEffect);
+ m_bundleEffectTarget = nodeList.first() ? nodeList.first() : active3DSceneNode();
}
}
@@ -349,7 +406,26 @@ void ContentLibraryView::updateBundleMaterialsImportedState()
m_widget->materialsModel()->updateImportedState(importedBundleMats);
}
-void ContentLibraryView::updateBundleMaterialsQuick3DVersion()
+void ContentLibraryView::updateBundleEffectsImportedState()
+{
+ using namespace Utils;
+
+ if (!m_widget->effectsModel()->bundleImporter())
+ return;
+
+ QStringList importedBundleEffs;
+
+ FilePath bundlePath = m_widget->effectsModel()->bundleImporter()->resolveBundleImportPath();
+
+ if (bundlePath.exists()) {
+ importedBundleEffs = transform(bundlePath.dirEntries({{"*.qml"}, QDir::Files}),
+ [](const FilePath &f) { return f.fileName().chopped(4); });
+ }
+
+ m_widget->effectsModel()->updateImportedState(importedBundleEffs);
+}
+
+void ContentLibraryView::updateBundlesQuick3DVersion()
{
bool hasImport = false;
int major = -1;
@@ -382,6 +458,7 @@ void ContentLibraryView::updateBundleMaterialsQuick3DVersion()
}
#endif
m_widget->materialsModel()->setQuick3DImportVersion(major, minor);
+ m_widget->effectsModel()->setQuick3DImportVersion(major, minor);
}
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h
index 137034dd955..741a77759eb 100644
--- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h
@@ -3,8 +3,8 @@
#pragma once
-#include "createtexture.h"
#include "abstractview.h"
+#include "createtexture.h"
#include "nodemetainfo.h"
#include
@@ -12,6 +12,7 @@
namespace QmlDesigner {
+class ContentLibraryEffect;
class ContentLibraryMaterial;
class ContentLibraryTexture;
class ContentLibraryWidget;
@@ -44,16 +45,20 @@ public:
private:
void updateBundleMaterialsImportedState();
- void updateBundleMaterialsQuick3DVersion();
+ void updateBundleEffectsImportedState();
+ void updateBundlesQuick3DVersion();
void applyBundleMaterialToDropTarget(const ModelNode &bundleMat, const NodeMetaInfo &metaInfo = {});
ModelNode getBundleMaterialDefaultInstance(const TypeName &type);
ModelNode createMaterial(const NodeMetaInfo &metaInfo);
QPointer m_widget;
QList m_bundleMaterialTargets;
+ ModelNode m_bundleEffectTarget; // target of the dropped bundle effect
+ QVariant m_bundleEffectPos; // pos of the dropped bundle effect
QList m_selectedModels; // selected 3D model nodes
ContentLibraryMaterial *m_draggedBundleMaterial = nullptr;
ContentLibraryTexture *m_draggedBundleTexture = nullptr;
+ ContentLibraryEffect *m_draggedBundleEffect = nullptr;
bool m_bundleMaterialAddToSelected = false;
bool m_hasQuick3DImport = false;
qint32 m_sceneId = -1;
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp
index 4c15cce8d7a..78bc1f07c3c 100644
--- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp
@@ -3,13 +3,17 @@
#include "contentlibrarywidget.h"
+#include "contentlibraryeffect.h"
+#include "contentlibraryeffectsmodel.h"
#include "contentlibrarymaterial.h"
#include "contentlibrarymaterialsmodel.h"
#include "contentlibrarytexture.h"
#include "contentlibrarytexturesmodel.h"
+#include "contentlibraryiconprovider.h"
#include "utils/filedownloader.h"
#include "utils/fileextractor.h"
+#include "utils/multifiledownloader.h"
#include
#include
@@ -24,13 +28,16 @@
#include
#include
+#include
#include
+#include
#include
#include
#include
#include
#include
#include
+#include
#include
#include
#include
@@ -59,7 +66,20 @@ bool ContentLibraryWidget::eventFilter(QObject *obj, QEvent *event)
Model *model = document->currentModel();
QTC_ASSERT(model, return false);
- if (m_materialToDrag) {
+ if (m_effectToDrag) {
+ QMouseEvent *me = static_cast(event);
+ if ((me->globalPos() - m_dragStartPoint).manhattanLength() > 20) {
+ QByteArray data;
+ QMimeData *mimeData = new QMimeData;
+ QDataStream stream(&data, QIODevice::WriteOnly);
+ stream << m_effectToDrag->type();
+ mimeData->setData(Constants::MIME_TYPE_BUNDLE_EFFECT, data);
+
+ emit bundleEffectDragStarted(m_effectToDrag);
+ model->startDrag(mimeData, m_effectToDrag->icon().toLocalFile());
+ m_effectToDrag = nullptr;
+ }
+ } else if (m_materialToDrag) {
QMouseEvent *me = static_cast(event);
if ((me->globalPosition().toPoint() - m_dragStartPoint).manhattanLength() > 20
&& m_materialToDrag->isDownloaded()) {
@@ -91,6 +111,7 @@ bool ContentLibraryWidget::eventFilter(QObject *obj, QEvent *event)
}
}
} else if (event->type() == QMouseEvent::MouseButtonRelease) {
+ m_effectToDrag = nullptr;
m_materialToDrag = nullptr;
m_textureToDrag = nullptr;
setIsDragging(false);
@@ -104,6 +125,7 @@ ContentLibraryWidget::ContentLibraryWidget()
, m_materialsModel(new ContentLibraryMaterialsModel(this))
, m_texturesModel(new ContentLibraryTexturesModel("Textures", this))
, m_environmentsModel(new ContentLibraryTexturesModel("Environments", this))
+ , m_effectsModel(new ContentLibraryEffectsModel(this))
{
qmlRegisterType("WebFetcher", 1, 0, "FileDownloader");
qmlRegisterType("WebFetcher", 1, 0, "FileExtractor");
@@ -113,6 +135,8 @@ ContentLibraryWidget::ContentLibraryWidget()
m_quickWidget->quickWidget()->setObjectName(Constants::OBJECT_NAME_CONTENT_LIBRARY);
m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
+ m_quickWidget->engine()->addImageProvider(QStringLiteral("contentlibrary"),
+ new Internal::ContentLibraryIconProvider);
m_quickWidget->engine()->addImportPath(propertyEditorResourcesPath() + "/imports");
m_quickWidget->setClearColor(Theme::getColor(Theme::Color::DSpanelBackground));
@@ -121,6 +145,8 @@ ContentLibraryWidget::ContentLibraryWidget()
+ "/textures";
m_texturesUrl = m_baseUrl + "/Textures";
+ m_textureIconsUrl = m_baseUrl + "/icons/Textures";
+ m_environmentIconsUrl = m_baseUrl + "/icons/Environments";
m_environmentsUrl = m_baseUrl + "/Environments";
m_downloadPath = Paths::bundlesPathSetting();
@@ -147,10 +173,11 @@ ContentLibraryWidget::ContentLibraryWidget()
auto map = m_quickWidget->registerPropertyMap("ContentLibraryBackend");
- map->setProperties({{"rootView", QVariant::fromValue(this)},
- {"materialsModel", QVariant::fromValue(m_materialsModel.data())},
- {"texturesModel", QVariant::fromValue(m_texturesModel.data())},
- {"environmentsModel", QVariant::fromValue(m_environmentsModel.data())}});
+ map->setProperties({{"rootView", QVariant::fromValue(this)},
+ {"materialsModel", QVariant::fromValue(m_materialsModel.data())},
+ {"texturesModel", QVariant::fromValue(m_texturesModel.data())},
+ {"environmentsModel", QVariant::fromValue(m_environmentsModel.data())},
+ {"effectsModel", QVariant::fromValue(m_effectsModel.data())}});
reloadQmlSource();
}
@@ -178,8 +205,231 @@ void ContentLibraryWidget::loadTextureBundle()
if (fetchTextureBundleMetadata(bundleDir) && fetchTextureBundleIcons(bundleDir)) {
QString bundleIconPath = m_downloadPath + "/TextureBundleIcons";
QVariantMap metaData = readBundleMetadata();
- m_texturesModel->loadTextureBundle(m_texturesUrl, bundleIconPath, metaData);
- m_environmentsModel->loadTextureBundle(m_environmentsUrl, bundleIconPath, metaData);
+ m_texturesModel->loadTextureBundle(m_texturesUrl, m_textureIconsUrl, bundleIconPath, metaData);
+ m_environmentsModel->loadTextureBundle(m_environmentsUrl, m_environmentIconsUrl,
+ bundleIconPath, metaData);
+ }
+}
+
+std::tuple ContentLibraryWidget::compareTextureMetaFiles(
+ const QString &existingMetaFilePath, const QString downloadedMetaFilePath)
+{
+ QVariantMap existingMeta;
+ QFile existingFile(existingMetaFilePath);
+ if (existingFile.open(QIODeviceBase::ReadOnly | QIODeviceBase::Text))
+ existingMeta = QJsonDocument::fromJson(existingFile.readAll()).toVariant().toMap();
+
+ QVariantMap downloadedMeta;
+ QFile downloadedFile(downloadedMetaFilePath);
+ if (downloadedFile.open(QIODeviceBase::ReadOnly | QIODeviceBase::Text))
+ downloadedMeta = QJsonDocument::fromJson(downloadedFile.readAll()).toVariant().toMap();
+
+ int existingVersion = existingMeta["version"].toInt();
+ int downloadedVersion = downloadedMeta["version"].toInt();
+
+ if (existingVersion != downloadedVersion) {
+ qWarning() << "We're not comparing local vs downloaded textures metadata because they are "
+ "of different versions";
+ return {};
+ }
+
+ QVariantMap existingItems = existingMeta["image_items"].toMap();
+ QVariantMap downloadedItems = downloadedMeta["image_items"].toMap();
+
+ QStringList existingKeys = existingItems.keys();
+ QStringList downloadedKeys = downloadedItems.keys();
+
+ QSet existing(existingKeys.cbegin(), existingKeys.cend());
+ QSet downloaded(downloadedKeys.cbegin(), downloadedKeys.cend());
+
+ const QSet newFiles = downloaded - existing;
+ const QSet commonFiles = downloaded & existing;
+
+ QVariantMap modifiedFileEntries;
+
+ for (const QString &file: commonFiles) {
+ QString existingCsum = existingItems[file].toMap()["checksum"].toString();
+ QString downloadedCsum = downloadedItems[file].toMap()["checksum"].toString();
+
+ if (existingCsum != downloadedCsum)
+ modifiedFileEntries[file] = downloadedItems[file];
+ }
+
+ QVariantMap newFileEntries;
+ for (const QString &path: newFiles)
+ newFileEntries[path] = downloadedItems[path];
+
+ return std::make_tuple(existingItems, newFileEntries, modifiedFileEntries);
+}
+
+void ContentLibraryWidget::fetchNewTextureIcons(const QVariantMap &existingFiles,
+ const QVariantMap &newFiles,
+ const QString &existingMetaFilePath,
+ const QDir &bundleDir)
+{
+ QStringList fileList = Utils::transform(newFiles.keys(), [](const QString &file) -> QString {
+ return file + ".png";
+ });
+
+ auto multidownloader = new MultiFileDownloader(this);
+ multidownloader->setBaseUrl(QString(m_baseUrl + "/icons"));
+ multidownloader->setFiles(fileList);
+ multidownloader->setTargetDirPath(m_downloadPath + "/TextureBundleIcons");
+
+ auto downloader = new FileDownloader(this);
+ downloader->setDownloadEnabled(true);
+ downloader->setProbeUrl(false);
+
+ downloader->setUrl(multidownloader->nextUrl());
+ downloader->setTargetFilePath(multidownloader->nextTargetPath());
+
+ QObject::connect(multidownloader, &MultiFileDownloader::nextUrlChanged, downloader, [=]() {
+ downloader->setUrl(multidownloader->nextUrl());
+ });
+
+ QObject::connect(multidownloader, &MultiFileDownloader::nextTargetPathChanged, downloader, [=]() {
+ downloader->setTargetFilePath(multidownloader->nextTargetPath());
+ });
+
+ multidownloader->setDownloader(downloader);
+
+ QVariantMap files = existingFiles;
+ files.insert(newFiles);
+
+ QObject::connect(multidownloader, &MultiFileDownloader::finishedChanged, this,
+ [multidownloader, files, existingMetaFilePath, this, bundleDir]() {
+ multidownloader->deleteLater();
+
+ QVariantMap newMap;
+ newMap["version"] = TextureBundleMetadataVersion;
+ newMap["image_items"] = files;
+
+ QJsonObject jobj = QJsonObject::fromVariantMap(newMap);
+ QJsonDocument doc(jobj);
+ QByteArray data = doc.toJson();
+
+ QFile existingFile(existingMetaFilePath);
+ if (existingFile.open(QIODeviceBase::WriteOnly | QIODeviceBase::Text)) {
+ existingFile.write(data);
+ existingFile.flush();
+ }
+
+ if (fetchTextureBundleIcons(bundleDir)) {
+ QString bundleIconPath = m_downloadPath + "/TextureBundleIcons";
+ QVariantMap metaData = readBundleMetadata();
+ m_texturesModel->loadTextureBundle(m_texturesUrl, m_textureIconsUrl, bundleIconPath,
+ metaData);
+ m_environmentsModel->loadTextureBundle(m_environmentsUrl, m_environmentIconsUrl,
+ bundleIconPath, metaData);
+ }
+
+ });
+
+ multidownloader->start();
+}
+
+QStringList ContentLibraryWidget::saveNewTextures(const QDir &bundleDir, const QStringList &newFiles)
+{
+ int newFileExpirationDays = QmlDesignerPlugin::settings()
+ .value(DesignerSettingsKey::CONTENT_LIBRARY_NEW_FLAG_EXPIRATION_DAYS)
+ .toInt();
+
+ int newFileExpirationSecs = newFileExpirationDays * 24 * 3600;
+
+ QString newFilesPath = bundleDir.filePath(".new_textures_on_server.json");
+
+ QFile jsonFile(newFilesPath);
+ if (jsonFile.exists()) {
+ jsonFile.open(QFile::ReadOnly | QFile::Text);
+
+ qint64 now = QDateTime::currentSecsSinceEpoch();
+ QByteArray existingData = jsonFile.readAll();
+ QJsonDocument doc = QJsonDocument::fromJson(existingData);
+ jsonFile.close();
+
+ QJsonObject mainObj = doc.object();
+ if (mainObj.value("version").toInt() > TextureBundleMetadataVersion) {
+ qDebug() << "Existing version of cached 'New Items' does not have a known version.";
+
+ // TODO: do simple save new file
+ return newFiles;
+ }
+
+ QJsonValue jsonValue = mainObj.value("image_items");
+ QJsonArray imageItems = jsonValue.toArray();
+
+ // remove those files that are older than N days (configurable via QSettings)
+ imageItems = Utils::filtered(imageItems, [newFileExpirationSecs, now](const QJsonValue &v) {
+ qint64 time = v["time"].toInt();
+ if (now - time >= newFileExpirationSecs)
+ return false;
+
+ return true;
+ });
+
+ QStringList pruned = Utils::transform(imageItems, [](const QJsonValue &value) -> QString {
+ return value.toObject()["file"].toString();
+ });
+
+ // filter out files from newFiles that already exist in the document
+
+ QStringList newFilesNow = Utils::filtered(newFiles, [&imageItems](const QString &file) {
+ bool contains = Utils::anyOf(imageItems, [file](const QJsonValue &v) {
+ if (!v.isObject())
+ return false;
+
+ QJsonObject o = v.toObject();
+ if (!o.contains("file"))
+ return false;
+
+ bool hasFile = (o["file"] == file);
+ return hasFile;
+
+ return false;
+ });
+ return !contains;
+ });
+
+ // add the filtered out files to the doc.
+ for (const QString &file: newFilesNow) {
+ QJsonObject obj({{"file", file}, {"time", now}});
+ imageItems.push_back(obj);
+ }
+
+ mainObj["image_items"] = imageItems;
+
+ // save the json file.
+ doc.setObject(mainObj);
+ QByteArray data = doc.toJson();
+
+ jsonFile.open(QFile::WriteOnly | QFile::Text);
+ jsonFile.write(data);
+ jsonFile.close();
+
+ return newFilesNow + pruned;
+ } else {
+ qint64 now = QDateTime::currentSecsSinceEpoch();
+
+ QJsonArray texturesFoundNow = Utils::transform(newFiles, [now](const QString &file) {
+ QJsonObject obj({{"file", file}, {"time", now}});
+ return QJsonValue(obj);
+ });
+
+ QVariantMap varMap;
+ varMap["version"] = TextureBundleMetadataVersion;
+ varMap["image_items"] = texturesFoundNow;
+
+ QJsonObject mainObj({{"version", TextureBundleMetadataVersion},
+ {"image_items", texturesFoundNow}});
+
+ QJsonDocument doc(mainObj);
+ QByteArray data = doc.toJson();
+
+ jsonFile.open(QFile::WriteOnly | QFile::Text);
+ jsonFile.write(data);
+ jsonFile.close();
+
+ return newFiles;
}
}
@@ -188,8 +438,7 @@ bool ContentLibraryWidget::fetchTextureBundleMetadata(const QDir &bundleDir)
QString filePath = bundleDir.filePath("texture_bundle.json");
QFileInfo fi(filePath);
- if (fi.exists() && fi.size() > 0)
- return true;
+ bool metaFileExists = fi.exists() && fi.size() > 0;
QString metaFileUrl = m_baseUrl + "/texture_bundle.zip";
FileDownloader *downloader = new FileDownloader(this);
@@ -197,11 +446,26 @@ bool ContentLibraryWidget::fetchTextureBundleMetadata(const QDir &bundleDir)
downloader->setProbeUrl(false);
downloader->setDownloadEnabled(true);
+ QObject::connect(downloader, &FileDownloader::downloadFailed, this, [=]() {
+ if (metaFileExists) {
+ if (fetchTextureBundleIcons(bundleDir)) {
+ QString bundleIconPath = m_downloadPath + "/TextureBundleIcons";
+ QVariantMap metaData = readBundleMetadata();
+ m_texturesModel->loadTextureBundle(m_texturesUrl, m_textureIconsUrl, bundleIconPath,
+ metaData);
+ m_environmentsModel->loadTextureBundle(m_environmentsUrl, m_environmentIconsUrl,
+ bundleIconPath, metaData);
+ }
+ }
+ });
+
QObject::connect(downloader, &FileDownloader::finishedChanged, this, [=]() {
FileExtractor *extractor = new FileExtractor(this);
extractor->setArchiveName(downloader->completeBaseName());
extractor->setSourceFile(downloader->outputFile());
- extractor->setTargetPath(bundleDir.absolutePath());
+ if (!metaFileExists)
+ extractor->setTargetPath(bundleDir.absolutePath());
+
extractor->setAlwaysCreateDir(false);
extractor->setClearTargetPathContents(false);
@@ -209,11 +473,35 @@ bool ContentLibraryWidget::fetchTextureBundleMetadata(const QDir &bundleDir)
downloader->deleteLater();
extractor->deleteLater();
+ if (metaFileExists) {
+ QVariantMap newFiles, existing;
+ QVariantMap modifiedFilesEntries;
+
+ std::tie(existing, newFiles, modifiedFilesEntries) =
+ compareTextureMetaFiles(filePath, extractor->targetPath() + "/texture_bundle.json");
+
+ const QStringList newFilesKeys = newFiles.keys();
+ const QStringList actualNewFiles = saveNewTextures(bundleDir, newFilesKeys);
+
+ m_texturesModel->setModifiedFileEntries(modifiedFilesEntries);
+ m_texturesModel->setNewFileEntries(actualNewFiles);
+
+ m_environmentsModel->setModifiedFileEntries(modifiedFilesEntries);
+ m_environmentsModel->setNewFileEntries(actualNewFiles);
+
+ if (newFiles.count() > 0) {
+ fetchNewTextureIcons(existing, newFiles, filePath, bundleDir);
+ return;
+ }
+ }
+
if (fetchTextureBundleIcons(bundleDir)) {
QString bundleIconPath = m_downloadPath + "/TextureBundleIcons";
QVariantMap metaData = readBundleMetadata();
- m_texturesModel->loadTextureBundle(m_texturesUrl, bundleIconPath, metaData);
- m_environmentsModel->loadTextureBundle(m_environmentsUrl, bundleIconPath, metaData);
+ m_texturesModel->loadTextureBundle(m_texturesUrl, m_textureIconsUrl, bundleIconPath,
+ metaData);
+ m_environmentsModel->loadTextureBundle(m_environmentsUrl, m_environmentIconsUrl,
+ bundleIconPath, metaData);
}
});
@@ -253,8 +541,10 @@ bool ContentLibraryWidget::fetchTextureBundleIcons(const QDir &bundleDir)
QString bundleIconPath = m_downloadPath + "/TextureBundleIcons";
QVariantMap metaData = readBundleMetadata();
- m_texturesModel->loadTextureBundle(m_texturesUrl, bundleIconPath, metaData);
- m_environmentsModel->loadTextureBundle(m_environmentsUrl, bundleIconPath, metaData);
+ m_texturesModel->loadTextureBundle(m_texturesUrl, m_textureIconsUrl, bundleIconPath,
+ metaData);
+ m_environmentsModel->loadTextureBundle(m_environmentsUrl, m_environmentIconsUrl,
+ bundleIconPath, metaData);
});
extractor->extract();
@@ -264,6 +554,48 @@ bool ContentLibraryWidget::fetchTextureBundleIcons(const QDir &bundleDir)
return false;
}
+void ContentLibraryWidget::markTextureUpdated(const QString &textureKey)
+{
+ static QRegularExpression re("([^/]+)/([^/]+)/.*");
+ QString category = re.match(textureKey).captured(1);
+ QString subcategory = re.match(textureKey).captured(2);
+
+ QString checksumOnServer;
+ if (category == "Textures")
+ checksumOnServer = m_texturesModel->removeModifiedFileEntry(textureKey);
+ else if (category == "Environments")
+ checksumOnServer = m_environmentsModel->removeModifiedFileEntry(textureKey);
+
+ QJsonObject metaDataObj;
+ QFile jsonFile(m_downloadPath + "/texture_bundle.json");
+ if (jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ metaDataObj = QJsonDocument::fromJson(jsonFile.readAll()).object();
+ jsonFile.close();
+ }
+
+ QJsonObject imageItems = metaDataObj["image_items"].toObject();
+
+ QJsonObject oldImageItem = imageItems[textureKey].toObject();
+ oldImageItem["checksum"] = checksumOnServer;
+ imageItems[textureKey] = oldImageItem;
+
+ metaDataObj["image_items"] = imageItems;
+
+ QJsonDocument outDoc(metaDataObj);
+ QByteArray data = outDoc.toJson();
+
+ QFile outFile(m_downloadPath + "/texture_bundle.json");
+ if (outFile.open(QIODeviceBase::WriteOnly | QIODeviceBase::Text)) {
+ outFile.write(data);
+ outFile.flush();
+ }
+
+ if (category == "Textures")
+ m_texturesModel->markTextureHasNoUpdates(subcategory, textureKey);
+ else if (category == "Environments")
+ m_environmentsModel->markTextureHasNoUpdates(subcategory, textureKey);
+}
+
QList ContentLibraryWidget::createToolBarWidgets()
{
return {};
@@ -311,6 +643,7 @@ void ContentLibraryWidget::setHasQuick3DImport(bool b)
emit hasQuick3DImportChanged();
m_materialsModel->updateIsEmpty();
+ m_effectsModel->updateIsEmpty();
}
bool ContentLibraryWidget::hasMaterialLibrary() const
@@ -341,6 +674,7 @@ void ContentLibraryWidget::reloadQmlSource()
void ContentLibraryWidget::updateSearch()
{
m_materialsModel->setSearchText(m_filterText);
+ m_effectsModel->setSearchText(m_filterText);
m_texturesModel->setSearchText(m_filterText);
m_environmentsModel->setSearchText(m_filterText);
m_quickWidget->update();
@@ -376,6 +710,14 @@ QString ContentLibraryWidget::findTextureBundlePath()
return texBundleDir.path();
}
+void ContentLibraryWidget::startDragEffect(QmlDesigner::ContentLibraryEffect *eff,
+ const QPointF &mousePos)
+{
+ m_effectToDrag = eff;
+ m_dragStartPoint = mousePos.toPoint();
+ setIsDragging(true);
+}
+
void ContentLibraryWidget::startDragMaterial(QmlDesigner::ContentLibraryMaterial *mat,
const QPointF &mousePos)
{
@@ -436,4 +778,9 @@ QPointer ContentLibraryWidget::environmentsModel()
return m_environmentsModel;
}
+QPointer ContentLibraryWidget::effectsModel() const
+{
+ return m_effectsModel;
+}
+
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h
index 6d4ba51a300..9f9fd167c32 100644
--- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h
+++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h
@@ -18,10 +18,12 @@ class StudioQuickWidget;
namespace QmlDesigner {
-class ContentLibraryTexture;
+class ContentLibraryEffect;
+class ContentLibraryEffectsModel;
class ContentLibraryMaterial;
-class ContentLibraryTexturesModel;
class ContentLibraryMaterialsModel;
+class ContentLibraryTexture;
+class ContentLibraryTexturesModel;
class ContentLibraryWidget : public QFrame
{
@@ -54,15 +56,19 @@ public:
QPointer materialsModel() const;
QPointer texturesModel() const;
QPointer environmentsModel() const;
+ QPointer effectsModel() const;
+ Q_INVOKABLE void startDragEffect(QmlDesigner::ContentLibraryEffect *eff, const QPointF &mousePos);
Q_INVOKABLE void startDragMaterial(QmlDesigner::ContentLibraryMaterial *mat, const QPointF &mousePos);
Q_INVOKABLE void startDragTexture(QmlDesigner::ContentLibraryTexture *tex, const QPointF &mousePos);
Q_INVOKABLE void addImage(QmlDesigner::ContentLibraryTexture *tex);
Q_INVOKABLE void addTexture(QmlDesigner::ContentLibraryTexture *tex);
Q_INVOKABLE void addLightProbe(QmlDesigner::ContentLibraryTexture *tex);
Q_INVOKABLE void updateSceneEnvState();
+ Q_INVOKABLE void markTextureUpdated(const QString &textureKey);
signals:
+ void bundleEffectDragStarted(QmlDesigner::ContentLibraryEffect *bundleEff);
void bundleMaterialDragStarted(QmlDesigner::ContentLibraryMaterial *bundleMat);
void bundleTextureDragStarted(QmlDesigner::ContentLibraryTexture *bundleTex);
void addTextureRequested(const QString texPath, QmlDesigner::AddTextureMode mode);
@@ -83,16 +89,23 @@ private:
QVariantMap readBundleMetadata();
bool fetchTextureBundleMetadata(const QDir &bundleDir);
bool fetchTextureBundleIcons(const QDir &bundleDir);
+ void fetchNewTextureIcons(const QVariantMap &existingFiles, const QVariantMap &newFiles,
+ const QString &existingMetaFilePath, const QDir &bundleDir);
+ std::tuple compareTextureMetaFiles(
+ const QString &existingMetaFile, const QString downloadedMetaFile);
+ QStringList saveNewTextures(const QDir &bundleDir, const QStringList &newFiles);
QScopedPointer m_quickWidget;
QPointer m_materialsModel;
QPointer m_texturesModel;
QPointer m_environmentsModel;
+ QPointer m_effectsModel;
QShortcut *m_qmlSourceUpdateShortcut = nullptr;
QString m_filterText;
+ ContentLibraryEffect *m_effectToDrag = nullptr;
ContentLibraryMaterial *m_materialToDrag = nullptr;
ContentLibraryTexture *m_textureToDrag = nullptr;
QPoint m_dragStartPoint;
@@ -102,6 +115,8 @@ private:
bool m_isDragging = false;
QString m_baseUrl;
QString m_texturesUrl;
+ QString m_textureIconsUrl;
+ QString m_environmentIconsUrl;
QString m_environmentsUrl;
QString m_downloadPath;
};
diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp
index 802a75c2bf8..84c8cb56bd8 100644
--- a/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp
@@ -319,7 +319,7 @@ std::vector resolveSmallCurves(const std::vector &frames)
if (frame.hasData() && !out.empty()) {
QEasingCurve curve = frame.data().toEasingCurve();
// One-segment-curve: Since (0,0) is implicit => 3
- if (curve.toCubicSpline().count() == 3) {
+ if (curve.toCubicSpline().size() == 3) {
Keyframe &previous = out.back();
#if 0
// Do not resolve when two adjacent keyframes have the same value.
diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditorstyle.h b/src/plugins/qmldesigner/components/curveeditor/curveeditorstyle.h
index 163f998d7d1..8193bdbf530 100644
--- a/src/plugins/qmldesigner/components/curveeditor/curveeditorstyle.h
+++ b/src/plugins/qmldesigner/components/curveeditor/curveeditorstyle.h
@@ -59,7 +59,7 @@ struct KeyframeItemStyleOption
double size = 10.0;
QColor color = QColor(200, 200, 0);
QColor selectionColor = QColor(200, 200, 200);
- QColor lockedColor = QColor(50, 50, 50);
+ QColor lockedColor = QColor(80, 80, 80);
QColor unifiedColor = QColor(250, 50, 250);
QColor splitColor = QColor(0, 250, 0);
};
@@ -71,7 +71,7 @@ struct CurveItemStyleOption
QColor errorColor = QColor(200, 0, 0);
QColor selectionColor = QColor(200, 200, 200);
QColor easingCurveColor = QColor(200, 0, 200);
- QColor lockedColor = QColor(50, 50, 50);
+ QColor lockedColor = QColor(120, 120, 120);
QColor hoverColor = QColor(200, 0, 200);
};
diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp
index 2a401fc4fb1..1d0b38b3f15 100644
--- a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp
@@ -338,7 +338,7 @@ void CurveEditorView::commitKeyframes(TreeItem *item)
attachEasingCurve(group, pos.x(), segment.easingCurve());
} else if (frame.interpolation() == Keyframe::Interpolation::Easing) {
QVariant data = frame.data();
- if (data.type() == static_cast(QMetaType::QEasingCurve))
+ if (data.typeId() == static_cast(QMetaType::QEasingCurve))
attachEasingCurve(group, pos.x(), data.value());
}
}
diff --git a/src/plugins/qmldesigner/components/curveeditor/curvesegment.cpp b/src/plugins/qmldesigner/components/curveeditor/curvesegment.cpp
index 2608e65144c..76fa2a2ffc2 100644
--- a/src/plugins/qmldesigner/components/curveeditor/curvesegment.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/curvesegment.cpp
@@ -244,7 +244,7 @@ void CurveSegment::extendWithEasingCurve(QPainterPath &path, const QEasingCurve
};
QVector points = curve.toCubicSpline();
- int numSegments = points.count() / 3;
+ int numSegments = points.size() / 3;
for (int i = 0; i < numSegments; i++) {
QPointF p1 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3));
QPointF p2 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3 + 1));
@@ -264,7 +264,7 @@ void CurveSegment::extend(QPainterPath &path) const
extendWithEasingCurve(path, easingCurve());
} else if (interpolation() == Keyframe::Interpolation::Easing) {
QVariant data = m_right.data();
- if (data.isValid() && data.type() == static_cast(QMetaType::QEasingCurve)) {
+ if (data.isValid() && data.typeId() == static_cast(QMetaType::QEasingCurve)) {
extendWithEasingCurve(path, data.value());
}
}
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
index 819a52d2159..b7548020723 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
@@ -252,13 +252,21 @@ void GraphicsView::setPinned(TreeItem *item)
void GraphicsView::setZoomX(double zoom, const QPoint &pivot)
{
- applyZoom(zoom, m_zoomY, pivot);
+ if (pivot.isNull())
+ applyZoom(zoom, m_zoomY, viewportCenter());
+ else
+ applyZoom(zoom, m_zoomY, pivot);
+
viewport()->update();
}
void GraphicsView::setZoomY(double zoom, const QPoint &pivot)
{
- applyZoom(m_zoomX, zoom, pivot);
+ if (pivot.isNull())
+ applyZoom(zoom, m_zoomY, viewportCenter());
+ else
+ applyZoom(zoom, m_zoomY, pivot);
+
viewport()->update();
}
@@ -514,7 +522,14 @@ void GraphicsView::applyZoom(double x, double y, const QPoint &pivot)
m_transform = QTransform::fromScale(scaleX, scaleY);
m_scene->setComponentTransform(m_transform);
- QRectF sr = m_scene->rect().adjusted(
+ QRectF sr = m_scene->rect();
+ if (sr.isNull()) {
+ sr.setLeft(m_scene->animationRangeMin());
+ sr.setRight(m_scene->animationRangeMax());
+ sr = m_transform.mapRect(sr);
+ }
+
+ sr = sr.adjusted(
-m_style.valueAxisWidth - m_style.canvasMargin,
-m_style.timeAxisHeight - m_style.canvasMargin,
m_style.canvasMargin,
@@ -750,4 +765,10 @@ QRectF GraphicsView::rangeMaxHandle(const QRectF &rect)
return QRectF(QPointF(handle, bottom), size);
}
+QPoint GraphicsView::viewportCenter() const
+{
+ QPoint viewCenter = viewport()->rect().center();
+ return viewport()->mapToGlobal(viewCenter);
+}
+
} // End namespace QmlDesigner.
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h
index c292d0203da..120249b605f 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h
@@ -136,6 +136,8 @@ private:
QRectF rangeMaxHandle(const QRectF &rect);
+ QPoint viewportCenter() const;
+
private:
bool m_dragging;
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/treeview.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/treeview.cpp
index c8b99d61c8d..82d8e2dd99d 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/treeview.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/treeview.cpp
@@ -37,6 +37,8 @@ TreeView::TreeView(CurveEditorModel *model, QWidget *parent)
setStyle(model->style());
+ header()->setMinimumSectionSize(20);
+
header()->setSectionResizeMode(0, QHeaderView::Stretch);
header()->setSectionResizeMode(1, QHeaderView::Fixed);
header()->setSectionResizeMode(2, QHeaderView::Fixed);
diff --git a/src/plugins/qmldesigner/components/curveeditor/keyframe.cpp b/src/plugins/qmldesigner/components/curveeditor/keyframe.cpp
index aa698c35da5..8e71e593c3b 100644
--- a/src/plugins/qmldesigner/components/curveeditor/keyframe.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/keyframe.cpp
@@ -149,7 +149,7 @@ void Keyframe::setRightHandle(const QPointF &pos)
void Keyframe::setData(const QVariant &data)
{
- if (data.type() == static_cast(QMetaType::QEasingCurve))
+ if (data.typeId() == static_cast(QMetaType::QEasingCurve))
m_interpolation = Interpolation::Easing;
m_data = data;
diff --git a/src/plugins/qmldesigner/components/edit3d/bakelights.cpp b/src/plugins/qmldesigner/components/edit3d/bakelights.cpp
index 53c7e53df9d..c0ff5de2af3 100644
--- a/src/plugins/qmldesigner/components/edit3d/bakelights.cpp
+++ b/src/plugins/qmldesigner/components/edit3d/bakelights.cpp
@@ -321,11 +321,13 @@ void BakeLights::showSetupDialog()
if (!m_dataModel)
m_dataModel = new BakeLightsDataModel(m_view);
- m_dataModel->reset();
-
- auto data = m_dataModel->view3dNode().auxiliaryData(bakeLightsManualProperty);
- if (data)
- m_manualMode = data->toBool();
+ if (!m_dataModel->reset()) {
+ m_manualMode = true;
+ } else {
+ auto data = m_dataModel->view3dNode().auxiliaryData(bakeLightsManualProperty);
+ if (data)
+ m_manualMode = data->toBool();
+ }
if (!m_setupDialog) {
// Show non-modal progress dialog with cancel button
diff --git a/src/plugins/qmldesigner/components/edit3d/bakelightsconnectionmanager.cpp b/src/plugins/qmldesigner/components/edit3d/bakelightsconnectionmanager.cpp
index 9fb41b46865..e8faa42833d 100644
--- a/src/plugins/qmldesigner/components/edit3d/bakelightsconnectionmanager.cpp
+++ b/src/plugins/qmldesigner/components/edit3d/bakelightsconnectionmanager.cpp
@@ -29,7 +29,7 @@ void BakeLightsConnectionManager::dispatchCommand(const QVariant &command,
{
static const int commandType = QMetaType::type("PuppetToCreatorCommand");
- if (command.userType() == commandType) {
+ if (command.typeId() == commandType) {
auto cmd = command.value();
switch (cmd.type()) {
case PuppetToCreatorCommand::BakeLightsProgress:
diff --git a/src/plugins/qmldesigner/components/edit3d/bakelightsdatamodel.cpp b/src/plugins/qmldesigner/components/edit3d/bakelightsdatamodel.cpp
index 36d192a9244..e812bb6d00e 100644
--- a/src/plugins/qmldesigner/components/edit3d/bakelightsdatamodel.cpp
+++ b/src/plugins/qmldesigner/components/edit3d/bakelightsdatamodel.cpp
@@ -36,7 +36,7 @@ BakeLightsDataModel::~BakeLightsDataModel()
int BakeLightsDataModel::rowCount(const QModelIndex &) const
{
- return m_dataList.count();
+ return m_dataList.size();
}
QHash BakeLightsDataModel::roleNames() const
@@ -57,7 +57,7 @@ QHash BakeLightsDataModel::roleNames() const
QVariant BakeLightsDataModel::data(const QModelIndex &index, int role) const
{
- QTC_ASSERT(index.isValid() && index.row() < m_dataList.count(), return {});
+ QTC_ASSERT(index.isValid() && index.row() < m_dataList.size(), return {});
QTC_ASSERT(roleNames().contains(role), return {});
QByteArray roleName = roleNames().value(role);
@@ -102,7 +102,7 @@ QVariant BakeLightsDataModel::data(const QModelIndex &index, int role) const
bool BakeLightsDataModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
- QTC_ASSERT(index.isValid() && index.row() < m_dataList.count(), return false);
+ QTC_ASSERT(index.isValid() && index.row() < m_dataList.size(), return false);
QTC_ASSERT(roleNames().contains(role), return false);
QByteArray roleName = roleNames().value(role);
@@ -130,10 +130,12 @@ bool BakeLightsDataModel::setData(const QModelIndex &index, const QVariant &valu
return changed;
}
-void BakeLightsDataModel::reset()
+// Return value of false indicates unexpected property assignments were detected, which means manual
+// mode for baking setup should be enforced.
+bool BakeLightsDataModel::reset()
{
if (!m_view || !m_view->model())
- return;
+ return true;
beginResetModel();
m_dataList.clear();
@@ -152,6 +154,8 @@ void BakeLightsDataModel::reset()
QList compLightList;
QList unexposedList;
+ bool forceManualMode = false;
+
// Note: We are always loading base state values for baking. If users want to bake
// differently for different states, they need to setup things manually for now.
// Same goes if they want to use any unusual bindings in baking properties.
@@ -169,23 +173,42 @@ void BakeLightsDataModel::reset()
if (node.hasBindingProperty("bakedLightmap")) {
ModelNode blm = node.bindingProperty("bakedLightmap").resolveToModelNode();
if (blm.isValid()) {
- if (blm.hasVariantProperty("enabled"))
+ if (blm.hasVariantProperty("enabled")) {
data.enabled = blm.variantProperty("enabled").value().toBool();
- else
+ } else {
data.enabled = true;
+ if (blm.hasProperty("enabled"))
+ forceManualMode = true;
+ }
}
+ } else if (node.hasProperty("bakedLightmap")) {
+ forceManualMode = true;
}
if (node.hasVariantProperty("lightmapBaseResolution"))
data.resolution = node.variantProperty("lightmapBaseResolution").value().toInt();
+ else if (node.hasProperty("lightmapBaseResolution"))
+ forceManualMode = true;
+
if (node.hasVariantProperty("usedInBakedLighting"))
data.inUse = node.variantProperty("usedInBakedLighting").value().toBool();
+ else if (node.hasProperty("usedInBakedLighting"))
+ forceManualMode = true;
+
modelList.append(data);
} else if (node.metaInfo().isQtQuick3DLight()) {
if (node.hasVariantProperty("bakeMode")) {
- data.bakeMode = node.variantProperty("bakeMode").value()
- .value().toString();
+ // Enum properties that have binding can still resolve as variant property,
+ // so check if the value is actually valid enum
+ QString bakeModeStr = node.variantProperty("bakeMode").value()
+ .value().toString();
+ if (bakeModeStr.startsWith("Light.BakeMode"))
+ data.bakeMode = bakeModeStr;
+ else
+ forceManualMode = true;
} else {
data.bakeMode = "Light.BakeModeDisabled";
+ if (node.hasProperty("bakeMode"))
+ forceManualMode = true;
}
lightList.append(data);
}
@@ -211,16 +234,29 @@ void BakeLightsDataModel::reset()
if (subName == "bakedLightmap") {
ModelNode blm = prop.toBindingProperty().resolveToModelNode();
if (blm.isValid()) {
- if (blm.hasVariantProperty("enabled"))
+ if (blm.hasVariantProperty("enabled")) {
propData.enabled = blm.variantProperty("enabled").value().toBool();
- else
+ } else {
propData.enabled = true;
+ if (blm.hasProperty("enabled"))
+ forceManualMode = true;
+ }
+ } else {
+ forceManualMode = true;
}
}
- if (subName == "lightmapBaseResolution")
- propData.resolution = prop.toVariantProperty().value().toInt();
- if (subName == "usedInBakedLighting")
- propData.inUse = prop.toVariantProperty().value().toBool();
+ if (subName == "lightmapBaseResolution") {
+ if (prop.isVariantProperty())
+ propData.resolution = prop.toVariantProperty().value().toInt();
+ else
+ forceManualMode = true;
+ }
+ if (subName == "usedInBakedLighting") {
+ if (prop.isVariantProperty())
+ propData.inUse = prop.toVariantProperty().value().toBool();
+ else
+ forceManualMode = true;
+ }
}
}
compModelList.append(propData);
@@ -231,9 +267,17 @@ void BakeLightsDataModel::reset()
if (prop.name().startsWith(dotName)) {
PropertyName subName = prop.name().mid(dotName.size());
if (subName == "bakeMode") {
- propData.bakeMode = prop.toVariantProperty().value()
- .value()
- .toString();
+ if (prop.isVariantProperty()) {
+ QString bakeModeStr = prop.toVariantProperty().value()
+ .value()
+ .toString();
+ if (bakeModeStr.startsWith("Light.BakeMode"))
+ propData.bakeMode = bakeModeStr;
+ else
+ forceManualMode = true;
+ } else {
+ forceManualMode = true;
+ }
}
}
}
@@ -292,6 +336,8 @@ void BakeLightsDataModel::reset()
}
endResetModel();
+
+ return !forceManualMode;
}
void BakeLightsDataModel::apply()
diff --git a/src/plugins/qmldesigner/components/edit3d/bakelightsdatamodel.h b/src/plugins/qmldesigner/components/edit3d/bakelightsdatamodel.h
index 313c09cf459..3ed7bfeed3c 100644
--- a/src/plugins/qmldesigner/components/edit3d/bakelightsdatamodel.h
+++ b/src/plugins/qmldesigner/components/edit3d/bakelightsdatamodel.h
@@ -38,7 +38,7 @@ public:
QHash roleNames() const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
- void reset();
+ bool reset();
void apply();
ModelNode view3dNode() const { return m_view3dNode; }
diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp
index 12d2dd05528..4ffdf0e801c 100644
--- a/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp
+++ b/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp
@@ -98,25 +98,6 @@ bool Edit3DAction::isEnabled(const SelectionContext &selectionContext) const
return isVisible(selectionContext);
}
-Edit3DCameraAction::Edit3DCameraAction(const QByteArray &menuId,
- View3DActionType type,
- const QString &description,
- const QKeySequence &key,
- bool checkable,
- bool checked,
- const QIcon &icon,
- Edit3DView *view,
- SelectionContextOperation selectionAction)
- : Edit3DAction(menuId, type, description, key, checkable, checked, icon, view, selectionAction)
-{
-}
-
-bool Edit3DCameraAction::isEnabled(const SelectionContext &selectionContext) const
-{
- return Utils::anyOf(selectionContext.selectedModelNodes(),
- [](const ModelNode &node) { return node.metaInfo().isQtQuick3DCamera(); });
-}
-
Edit3DParticleSeekerAction::Edit3DParticleSeekerAction(const QByteArray &menuId,
View3DActionType type,
Edit3DView *view)
diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dactions.h b/src/plugins/qmldesigner/components/edit3d/edit3dactions.h
index 4cf1ab837d8..3a451ea40d5 100644
--- a/src/plugins/qmldesigner/components/edit3d/edit3dactions.h
+++ b/src/plugins/qmldesigner/components/edit3d/edit3dactions.h
@@ -91,23 +91,6 @@ private:
View3DActionType m_actionType;
};
-class Edit3DCameraAction : public Edit3DAction
-{
-public:
- Edit3DCameraAction(const QByteArray &menuId,
- View3DActionType type,
- const QString &description,
- const QKeySequence &key,
- bool checkable,
- bool checked,
- const QIcon &icon,
- Edit3DView *view,
- SelectionContextOperation selectionAction = nullptr);
-
-protected:
- bool isEnabled(const SelectionContext &selectionContext) const override;
-};
-
class Edit3DParticleSeekerAction : public Edit3DAction
{
public:
diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp
index 10d62a5dc21..a96ca59cae7 100644
--- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp
+++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp
@@ -106,17 +106,6 @@ Edit3DWidget *Edit3DView::edit3DWidget() const
return m_edit3DWidget.data();
}
-void Edit3DView::selectedNodesChanged([[maybe_unused]] const QList &selectedNodeList,
- [[maybe_unused]] const QList &lastSelectedNodeList)
-{
- SelectionContext selectionContext(this);
- selectionContext.setUpdateMode(SelectionContext::UpdateMode::Fast);
- if (m_alignCamerasAction)
- m_alignCamerasAction->currentContextChanged(selectionContext);
- if (m_alignViewAction)
- m_alignViewAction->currentContextChanged(selectionContext);
-}
-
void Edit3DView::renderImage3DChanged(const QImage &img)
{
edit3DWidget()->canvas()->updateRenderImage(img);
@@ -149,6 +138,7 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState)
qint32 newActiveScene = sceneState[sceneKey].value();
edit3DWidget()->canvas()->updateActiveScene(newActiveScene);
model()->setActive3DSceneId(newActiveScene);
+ updateAlignActionStates();
}
if (sceneState.contains(selectKey))
@@ -298,6 +288,22 @@ void Edit3DView::handleEntriesChanged()
m_edit3DWidget->updateCreateSubMenu(entriesMap.values());
}
+void Edit3DView::updateAlignActionStates()
+{
+ bool enabled = false;
+
+ ModelNode activeScene = active3DSceneNode();
+ if (activeScene.isValid()) {
+ const QList nodes = activeScene.allSubModelNodes();
+ enabled = ::Utils::anyOf(nodes, [](const ModelNode &node) {
+ return node.metaInfo().isQtQuick3DCamera();
+ });
+ }
+
+ m_alignCamerasAction->action()->setEnabled(enabled);
+ m_alignViewAction->action()->setEnabled(enabled);
+}
+
void Edit3DView::modelAboutToBeDetached(Model *model)
{
m_isBakingLightsSupported = false;
@@ -364,6 +370,8 @@ void Edit3DView::nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos
}
} else if (m_nodeAtPosReqType == NodeAtPosReqType::BundleMaterialDrop) {
emitCustomNotification("drop_bundle_material", {modelNode}); // To ContentLibraryView
+ } else if (m_nodeAtPosReqType == NodeAtPosReqType::BundleEffectDrop) {
+ emitCustomNotification("drop_bundle_effect", {modelNode}, {pos3d}); // To ContentLibraryView
} else if (m_nodeAtPosReqType == NodeAtPosReqType::TextureDrop) {
emitCustomNotification("apply_texture_to_model3D", {modelNode, m_droppedModelNode});
} else if (m_nodeAtPosReqType == NodeAtPosReqType::AssetDrop) {
@@ -377,6 +385,21 @@ void Edit3DView::nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos
m_nodeAtPosReqType = NodeAtPosReqType::None;
}
+void Edit3DView::nodeReparented(const ModelNode &,
+ const NodeAbstractProperty &,
+ const NodeAbstractProperty &,
+ PropertyChangeFlags)
+{
+ updateAlignActionStates();
+}
+
+void Edit3DView::nodeRemoved(const ModelNode &,
+ const NodeAbstractProperty &,
+ PropertyChangeFlags)
+{
+ updateAlignActionStates();
+}
+
void Edit3DView::sendInputEvent(QInputEvent *e) const
{
if (nodeInstanceView())
@@ -581,25 +604,27 @@ void Edit3DView::createEdit3DActions()
toolbarIcon(Theme::fitToView_medium),
this);
- m_alignCamerasAction = new Edit3DCameraAction(
+ m_alignCamerasAction = new Edit3DAction(
QmlDesigner::Constants::EDIT3D_ALIGN_CAMERAS,
View3DActionType::AlignCamerasToView,
- QCoreApplication::translate("AlignCamerasToViewAction", "Align Selected Cameras to View"),
+ QCoreApplication::translate("AlignCamerasToViewAction", "Align Cameras to View"),
QKeySequence(),
false,
false,
toolbarIcon(Theme::alignToCam_medium),
this);
+ m_alignCamerasAction->action()->setEnabled(false);
- m_alignViewAction = new Edit3DCameraAction(
+ m_alignViewAction = new Edit3DAction(
QmlDesigner::Constants::EDIT3D_ALIGN_VIEW,
View3DActionType::AlignViewToCamera,
- QCoreApplication::translate("AlignCamerasToViewAction", "Align View to Selected Camera"),
+ QCoreApplication::translate("AlignCamerasToViewAction", "Align View to Camera"),
QKeySequence(),
false,
false,
toolbarIcon(Theme::alignToView_medium),
this);
+ m_alignViewAction->action()->setEnabled(false);
m_cameraModeAction = new Edit3DAction(
QmlDesigner::Constants::EDIT3D_EDIT_CAMERA,
@@ -922,7 +947,7 @@ void Edit3DView::addQuick3DImport()
{
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
if (document && !document->inFileComponentModelActive() && model()
- && Utils::addImportWithCheck(
+ && ModelUtils::addImportWithCheck(
"QtQuick3D",
[](const Import &import) { return !import.hasVersion() || import.majorVersion() >= 6; },
model())) {
@@ -953,6 +978,12 @@ void Edit3DView::dropBundleMaterial(const QPointF &pos)
emitView3DAction(View3DActionType::GetNodeAtPos, pos);
}
+void Edit3DView::dropBundleEffect(const QPointF &pos)
+{
+ m_nodeAtPosReqType = NodeAtPosReqType::BundleEffectDrop;
+ emitView3DAction(View3DActionType::GetNodeAtPos, pos);
+}
+
void Edit3DView::dropTexture(const ModelNode &textureNode, const QPointF &pos)
{
m_nodeAtPosReqType = NodeAtPosReqType::TextureDrop;
diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.h b/src/plugins/qmldesigner/components/edit3d/edit3dview.h
index cd3e686d3bb..6e6b82948e5 100644
--- a/src/plugins/qmldesigner/components/edit3d/edit3dview.h
+++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.h
@@ -26,7 +26,6 @@ class BakeLights;
class Edit3DWidget;
class Edit3DAction;
class Edit3DBakeLightsAction;
-class Edit3DCameraAction;
class QMLDESIGNERCOMPONENTS_EXPORT Edit3DView : public AbstractView
{
@@ -39,14 +38,19 @@ public:
Edit3DWidget *edit3DWidget() const;
- void selectedNodesChanged(const QList &selectedNodeList, const QList &lastSelectedNodeList) override;
void renderImage3DChanged(const QImage &img) override;
void updateActiveScene3D(const QVariantMap &sceneState) override;
void modelAttached(Model *model) override;
void modelAboutToBeDetached(Model *model) override;
void importsChanged(const Imports &addedImports, const Imports &removedImports) override;
- void customNotification(const AbstractView *view, const QString &identifier, const QList &nodeList, const QList &data) override;
+ void customNotification(const AbstractView *view, const QString &identifier,
+ const QList &nodeList, const QList &data) override;
void nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos3d) override;
+ void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent,
+ const NodeAbstractProperty &oldPropertyParent,
+ PropertyChangeFlags propertyChange) override;
+ void nodeRemoved(const ModelNode &removedNode, const NodeAbstractProperty &parentProperty,
+ PropertyChangeFlags propertyChange) override;
void sendInputEvent(QInputEvent *e) const;
void edit3DViewResized(const QSize &size) const;
@@ -65,6 +69,7 @@ public:
void startContextMenu(const QPoint &pos);
void dropMaterial(const ModelNode &matNode, const QPointF &pos);
void dropBundleMaterial(const QPointF &pos);
+ void dropBundleEffect(const QPointF &pos);
void dropTexture(const ModelNode &textureNode, const QPointF &pos);
void dropComponent(const ItemLibraryEntry &entry, const QPointF &pos);
void dropAsset(const QString &file, const QPointF &pos);
@@ -76,6 +81,7 @@ private slots:
private:
enum class NodeAtPosReqType {
+ BundleEffectDrop,
BundleMaterialDrop,
ComponentDrop,
MaterialDrop,
@@ -91,6 +97,7 @@ private:
void checkImports();
void handleEntriesChanged();
void showMaterialPropertiesView();
+ void updateAlignActionStates();
Edit3DAction *createSelectBackgroundColorAction(QAction *syncBackgroundColorAction);
Edit3DAction *createGridColorSelectionAction();
@@ -110,8 +117,8 @@ private:
Edit3DAction *m_rotateToolAction = nullptr;
Edit3DAction *m_scaleToolAction = nullptr;
Edit3DAction *m_fitAction = nullptr;
- Edit3DCameraAction *m_alignCamerasAction = nullptr;
- Edit3DCameraAction *m_alignViewAction = nullptr;
+ Edit3DAction *m_alignCamerasAction = nullptr;
+ Edit3DAction *m_alignViewAction = nullptr;
Edit3DAction *m_cameraModeAction = nullptr;
Edit3DAction *m_orientationModeAction = nullptr;
Edit3DAction *m_editLightAction = nullptr;
diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp
index a217e396d9c..163cfc951ed 100644
--- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp
+++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp
@@ -21,6 +21,7 @@
#include
#include
+#include
#include
#include
#include
@@ -167,6 +168,11 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view)
createContextMenu();
+ m_mcuLabel = new QLabel(this);
+ m_mcuLabel->setText(tr("MCU project does not support Qt Quick 3D."));
+ m_mcuLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
+ fillLayout->addWidget(m_mcuLabel.data());
+
// Onboarding label contains instructions for new users how to get 3D content into the project
m_onboardingLabel = new QLabel(this);
QString labelText =
@@ -413,7 +419,24 @@ void Edit3DWidget::showCanvas(bool show)
m_canvas->updateRenderImage(emptyImage);
}
m_canvas->setVisible(show);
- m_onboardingLabel->setVisible(!show);
+
+ if (show) {
+ m_onboardingLabel->setVisible(false);
+ m_mcuLabel->setVisible(false);
+ } else {
+ bool quick3dAllowed = true;
+ const DesignerMcuManager &mcuManager = DesignerMcuManager::instance();
+ if (mcuManager.isMCUProject()) {
+ const QStringList mcuAllowedList = mcuManager.allowedImports();
+ if (!mcuAllowedList.contains("QtQuick3d"))
+ quick3dAllowed = false;
+ }
+
+ m_onboardingLabel->setVisible(quick3dAllowed);
+ m_mcuLabel->setVisible(!quick3dAllowed);
+ }
+
+
}
QMenu *Edit3DWidget::visibilityTogglesMenu() const
@@ -451,9 +474,8 @@ void Edit3DWidget::showContextMenu(const QPoint &pos, const ModelNode &modelNode
m_contextMenuTarget = modelNode;
m_contextMenuPos3d = pos3d;
- const bool isValid = modelNode.isValid();
const bool isModel = modelNode.metaInfo().isQtQuick3DModel();
- const bool isCamera = isValid && modelNode.metaInfo().isQtQuick3DCamera();
+ const bool allowAlign = view()->edit3DAction(View3DActionType::AlignCamerasToView)->action()->isEnabled();
const bool isSingleComponent = view()->hasSingleSelectedModelNode() && modelNode.isComponent();
const bool anyNodeSelected = view()->hasSelectedModelNodes();
const bool selectionExcludingRoot = anyNodeSelected && !view()->rootModelNode().isSelected();
@@ -468,8 +490,8 @@ void Edit3DWidget::showContextMenu(const QPoint &pos, const ModelNode &modelNode
m_pasteAction->setEnabled(isPasteAvailable());
m_deleteAction->setEnabled(selectionExcludingRoot);
m_fitSelectedAction->setEnabled(anyNodeSelected);
- m_alignCameraAction->setEnabled(isCamera);
- m_alignViewAction->setEnabled(isCamera);
+ m_alignCameraAction->setEnabled(allowAlign);
+ m_alignViewAction->setEnabled(allowAlign);
m_selectParentAction->setEnabled(selectionExcludingRoot);
m_toggleGroupAction->setEnabled(true);
m_bakeLightsAction->setVisible(view()->bakeLightsAction()->action()->isVisible());
@@ -517,6 +539,7 @@ void Edit3DWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent)
} else if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData())
|| dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_MATERIAL)
|| dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL)
+ || dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_BUNDLE_EFFECT)
|| dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_TEXTURE)) {
dragEnterEvent->acceptProposedAction();
} else if (dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_ITEM_LIBRARY_INFO)) {
@@ -560,6 +583,13 @@ void Edit3DWidget::dropEvent(QDropEvent *dropEvent)
return;
}
+ // handle dropping bundle effects
+ if (dropEvent->mimeData()->hasFormat(Constants::MIME_TYPE_BUNDLE_EFFECT)) {
+ m_view->dropBundleEffect(pos);
+ m_view->model()->endDrag();
+ return;
+ }
+
// handle dropping from component view
if (dropEvent->mimeData()->hasFormat(Constants::MIME_TYPE_ITEM_LIBRARY_INFO)) {
if (!m_draggedEntry.name().isEmpty())
diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h
index eecd52345fa..f764f068bf4 100644
--- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h
+++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h
@@ -70,6 +70,7 @@ private:
QPointer m_view;
QPointer m_canvas;
QPointer m_onboardingLabel;
+ QPointer m_mcuLabel;
QPointer m_toolBox;
Core::IContext *m_context = nullptr;
QPointer m_visibilityTogglesMenu;
diff --git a/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp b/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp
index c6cbb8252c4..774b4c0d911 100644
--- a/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp
@@ -260,7 +260,7 @@ void AbstractFormEditorTool::mouseReleaseEvent(const QList & ite
QmlItemNode currentSelectedNode;
- if (view()->selectedModelNodes().count() == 1) {
+ if (view()->selectedModelNodes().size() == 1) {
currentSelectedNode = view()->selectedModelNodes().constFirst();
if (!containsItemNode(itemList, currentSelectedNode)) {
diff --git a/src/plugins/qmldesigner/components/formeditor/anchorindicator.cpp b/src/plugins/qmldesigner/components/formeditor/anchorindicator.cpp
index 7d75c71c229..8a8a3e524ff 100644
--- a/src/plugins/qmldesigner/components/formeditor/anchorindicator.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/anchorindicator.cpp
@@ -64,7 +64,7 @@ void AnchorIndicator::setItems(const QList &itemList)
{
clear();
- if (itemList.count() == 1) {
+ if (itemList.size() == 1) {
m_formEditorItem = itemList.constFirst();
QmlItemNode sourceQmlItemNode = m_formEditorItem->qmlItemNode();
if (!sourceQmlItemNode.modelNode().isRootNode()) {
diff --git a/src/plugins/qmldesigner/components/formeditor/backgroundaction.cpp b/src/plugins/qmldesigner/components/formeditor/backgroundaction.cpp
index a9d72be8ddb..37dfafad9a2 100644
--- a/src/plugins/qmldesigner/components/formeditor/backgroundaction.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/backgroundaction.cpp
@@ -45,7 +45,7 @@ QWidget *BackgroundAction::createWidget(QWidget *parent)
auto comboBox = new QComboBox(parent);
comboBox->setFixedWidth(42);
- for (int i = 0; i < colors().count(); ++i) {
+ for (int i = 0; i < colors().size(); ++i) {
comboBox->addItem(tr(""));
comboBox->setItemIcon(i, iconForColor((colors().at(i))));
}
@@ -62,7 +62,7 @@ QWidget *BackgroundAction::createWidget(QWidget *parent)
void BackgroundAction::emitBackgroundChanged(int index)
{
- if (index < colors().count())
+ if (index < colors().size())
emit backgroundChanged(colors().at(index));
}
diff --git a/src/plugins/qmldesigner/components/formeditor/bindingindicator.cpp b/src/plugins/qmldesigner/components/formeditor/bindingindicator.cpp
index e5a990d1efe..57958416937 100644
--- a/src/plugins/qmldesigner/components/formeditor/bindingindicator.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/bindingindicator.cpp
@@ -91,7 +91,7 @@ void BindingIndicator::setItems(const QList &itemList)
{
clear();
- if (itemList.count() == 1) {
+ if (itemList.size() == 1) {
m_formEditorItem = itemList.constFirst();
const QmlItemNode qmlItemNode = m_formEditorItem->qmlItemNode();
diff --git a/src/plugins/qmldesigner/components/formeditor/movetool.cpp b/src/plugins/qmldesigner/components/formeditor/movetool.cpp
index 449cdd745cd..76b8f9a5f64 100644
--- a/src/plugins/qmldesigner/components/formeditor/movetool.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/movetool.cpp
@@ -94,9 +94,9 @@ void MoveTool::mouseMoveEvent(const QList &itemList,
const FormEditorItem *movingItem = m_movingItems.constFirst();
- if (m_movingItems.count() > 1
- || (movingItem->qmlItemNode().canBereparentedTo(containerItem->qmlItemNode())))
- m_moveManipulator.reparentTo(containerItem, MoveManipulator::EnforceReparent);
+ if (m_movingItems.size() > 1
+ || (movingItem->qmlItemNode().canBereparentedTo(containerItem->qmlItemNode())))
+ m_moveManipulator.reparentTo(containerItem, MoveManipulator::EnforceReparent);
}
}
diff --git a/src/plugins/qmldesigner/components/formeditor/seekerslider.cpp b/src/plugins/qmldesigner/components/formeditor/seekerslider.cpp
index 804f061657a..a6bfd25873f 100644
--- a/src/plugins/qmldesigner/components/formeditor/seekerslider.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/seekerslider.cpp
@@ -97,9 +97,11 @@ QWidget *SeekerSliderAction::createWidget(QWidget *parent)
QObject::connect(m_defaultSlider, &SeekerSlider::valueChanged, slider, &SeekerSlider::setValue);
QObject::connect(slider, &SeekerSlider::valueChanged, m_defaultSlider, &SeekerSlider::setValue);
QObject::connect(m_defaultSlider, &QSlider::rangeChanged, slider, &QSlider::setRange);
+ QObject::connect(this, &QWidgetAction::enabledChanged, slider, &QSlider::setEnabled);
slider->setValue(m_defaultSlider->value());
slider->setMaxValue(m_defaultSlider->maxValue());
+ slider->setEnabled(isEnabled());
return slider;
}
diff --git a/src/plugins/qmldesigner/components/formeditor/snapper.cpp b/src/plugins/qmldesigner/components/formeditor/snapper.cpp
index da50f92a81d..828a7132118 100644
--- a/src/plugins/qmldesigner/components/formeditor/snapper.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/snapper.cpp
@@ -426,7 +426,7 @@ double Snapper::snappingDistance() const
static QLineF mergedHorizontalLine(const QList &lineList)
{
- if (lineList.count() == 1)
+ if (lineList.size() == 1)
return lineList.constFirst();
double minimumX = std::numeric_limits::max();
@@ -444,7 +444,7 @@ static QLineF mergedHorizontalLine(const QList &lineList)
static QLineF mergedVerticalLine(const QList &lineList)
{
- if (lineList.count() == 1)
+ if (lineList.size() == 1)
return lineList.constFirst();
double minimumY = std::numeric_limits::max();
diff --git a/src/plugins/qmldesigner/components/formeditor/toolbox.cpp b/src/plugins/qmldesigner/components/formeditor/toolbox.cpp
index 47a9503b2d3..53da8773eb6 100644
--- a/src/plugins/qmldesigner/components/formeditor/toolbox.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/toolbox.cpp
@@ -34,11 +34,13 @@ ToolBox::ToolBox(QWidget *parentWidget)
Utils::StyleHelper::setPanelWidget(m_leftToolBar, false);
Utils::StyleHelper::setPanelWidgetSingleRow(m_leftToolBar, false);
m_leftToolBar->setFixedHeight(Theme::toolbarSize());
+ m_leftToolBar->setStyleSheet("QToolBarExtension {margin-top: 5px;}");
Utils::StyleHelper::setPanelWidget(m_rightToolBar, false);
Utils::StyleHelper::setPanelWidgetSingleRow(m_rightToolBar, false);
m_rightToolBar->setFixedHeight(Theme::toolbarSize());
m_rightToolBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
+ m_rightToolBar->setStyleSheet("QToolBarExtension {margin-top: 5px;}");
auto stretchToolbar = new QToolBar(this);
Utils::StyleHelper::setPanelWidget(stretchToolbar, false);
diff --git a/src/plugins/qmldesigner/components/integration/designdocument.cpp b/src/plugins/qmldesigner/components/integration/designdocument.cpp
index fecaaefadf3..089efb87cdd 100644
--- a/src/plugins/qmldesigner/components/integration/designdocument.cpp
+++ b/src/plugins/qmldesigner/components/integration/designdocument.cpp
@@ -9,6 +9,7 @@
#include
#include
+#include
#include
#include
#include
@@ -62,7 +63,8 @@ namespace QmlDesigner {
*/
DesignDocument::DesignDocument(ProjectStorage &projectStorage,
ExternalDependenciesInterface &externalDependencies)
- : m_documentModel(Model::create("QtQuick.Item", 1, 0))
+ : m_documentModel(
+ Model::create("QtQuick.Item", 1, 0, nullptr, std::make_unique()))
, m_subComponentManager(new SubComponentManager(m_documentModel.get(), externalDependencies))
, m_rewriterView(new RewriterView(externalDependencies, RewriterView::Amend))
, m_documentLoaded(false)
@@ -149,7 +151,11 @@ const AbstractView *DesignDocument::view() const
ModelPointer DesignDocument::createInFileComponentModel()
{
- auto model = Model::create("QtQuick.Item", 1, 0);
+ auto model = Model::create("QtQuick.Item",
+ 1,
+ 0,
+ nullptr,
+ std::make_unique());
model->setFileUrl(m_documentModel->fileUrl());
model->setMetaInfo(m_documentModel->metaInfo());
@@ -205,8 +211,7 @@ void DesignDocument::moveNodesToPosition(const QList &nodes, const st
targetNode = view.firstSelectedModelNode();
// in case we copy and paste a selection we paste in the parent item
- if ((view.selectedModelNodes().count() == movingNodes.count())
- && targetNode.hasParentProperty()) {
+ if ((view.selectedModelNodes().size() == movingNodes.size()) && targetNode.hasParentProperty()) {
targetNode = targetNode.parentProperty().parentModelNode();
} else if (view.selectedModelNodes().isEmpty()) {
// if selection is empty and copied nodes are all 3D nodes, paste them under the active scene
@@ -366,7 +371,7 @@ void DesignDocument::loadDocument(QPlainTextEdit *edit)
connect(m_documentTextModifier.data(), &TextModifier::textChanged, this, &DesignDocument::updateQrcFiles);
- m_documentModel->setTextModifier(m_documentTextModifier.data());
+ m_rewriterView->setTextModifier(m_documentTextModifier.data());
m_inFileComponentTextModifier.reset();
@@ -386,6 +391,8 @@ void DesignDocument::changeToDocumentModel()
if (edit)
edit->document()->clearUndoRedoStacks();
+ m_rewriterView->setTextModifier(m_documentTextModifier.data());
+
m_inFileComponentModel.reset();
m_inFileComponentTextModifier.reset();
@@ -426,7 +433,8 @@ void DesignDocument::changeToInFileComponentModel(ComponentTextModifier *textMod
edit->document()->clearUndoRedoStacks();
m_inFileComponentModel = createInFileComponentModel();
- m_inFileComponentModel->setTextModifier(m_inFileComponentTextModifier.data());
+
+ m_rewriterView->setTextModifier(m_inFileComponentTextModifier.data());
viewManager().attachRewriterView();
viewManager().attachViewsExceptRewriterAndComponetView();
diff --git a/src/plugins/qmldesigner/components/integration/designdocumentview.cpp b/src/plugins/qmldesigner/components/integration/designdocumentview.cpp
index 4a1c92ad0aa..9d0deef713b 100644
--- a/src/plugins/qmldesigner/components/integration/designdocumentview.cpp
+++ b/src/plugins/qmldesigner/components/integration/designdocumentview.cpp
@@ -227,7 +227,7 @@ void DesignDocumentView::copyModelNodes(const QList &nodesToCopy,
DesignDocumentView view{externalDependencies};
copyModel->attachView(&view);
- if (selectedNodes.count() == 1) {
+ if (selectedNodes.size() == 1) {
const ModelNode &selectedNode = selectedNodes.constFirst();
if (!selectedNode.isValid())
@@ -253,7 +253,6 @@ void DesignDocumentView::copyModelNodes(const QList &nodesToCopy,
view.toClipboard();
}
-
}
}// namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitem.cpp b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitem.cpp
index 6fa6ec4c342..a5d84605dd2 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitem.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitem.cpp
@@ -32,7 +32,7 @@ void AssetImportUpdateTreeItem::clear()
int AssetImportUpdateTreeItem::childCount() const
{
- return m_children.count();
+ return m_children.size();
}
int AssetImportUpdateTreeItem::rowOfItem() const
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.cpp
index 41a9c6b5f4a..66afa19f8b8 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.cpp
@@ -28,12 +28,12 @@ ItemLibraryAddImportModel::~ItemLibraryAddImportModel()
int ItemLibraryAddImportModel::rowCount(const QModelIndex & /*parent*/) const
{
- return m_importList.count();
+ return m_importList.size();
}
QVariant ItemLibraryAddImportModel::data(const QModelIndex &index, int role) const
{
- if (!index.isValid() || index.row() >= m_importList.count())
+ if (!index.isValid() || index.row() >= m_importList.size())
return {};
Import import = m_importList[index.row()];
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp
index 91f403f218a..f8a9fd97718 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp
@@ -109,7 +109,7 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(
connect(ui->buttonBox->button(QDialogButtonBox::Ok), &QPushButton::clicked,
this, &ItemLibraryAssetImportDialog::onImport);
- ui->buttonBox->button(QDialogButtonBox::Close)->setDefault(true);
+ ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
ui->advancedSettingsButton->setStyleSheet(
"QPushButton#advancedSettingsButton {background-color: transparent}");
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp
index d141b88dc85..99f07cb8a8a 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp
@@ -216,7 +216,7 @@ void ItemLibraryAssetImporter::parseFiles(const QStringList &filePaths,
addInfo(progressTitle);
notifyProgress(0, progressTitle);
uint count = 0;
- double quota = 100.0 / filePaths.count();
+ double quota = 100.0 / filePaths.size();
std::function