forked from qt-creator/qt-creator
Merge "Merge remote-tracking branch 'origin/7.0'"
This commit is contained in:
2
.github/workflows/build_cmake.yml
vendored
2
.github/workflows/build_cmake.yml
vendored
@@ -8,7 +8,7 @@ on:
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
QT_VERSION: 6.2.3
|
QT_VERSION: 6.2.3
|
||||||
CLANG_VERSION: 14.0.0
|
CLANG_VERSION: 14.0.3
|
||||||
ELFUTILS_VERSION: 0.175
|
ELFUTILS_VERSION: 0.175
|
||||||
CMAKE_VERSION: 3.21.1
|
CMAKE_VERSION: 3.21.1
|
||||||
NINJA_VERSION: 1.10.2
|
NINJA_VERSION: 1.10.2
|
||||||
|
@@ -107,7 +107,7 @@ set(CRASHPAD_BACKEND_URL "" CACHE STRING "Crashpad backend URL")
|
|||||||
set(BUILD_WITH_CRASHPAD OFF)
|
set(BUILD_WITH_CRASHPAD OFF)
|
||||||
# Linux is not supported for now
|
# Linux is not supported for now
|
||||||
# x86_64;arm64 is not supported for now
|
# x86_64;arm64 is not supported for now
|
||||||
if(CRASHPAD_BACKEND_URL AND (WIN32 OR (APPLE AND NOT "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "x86_64;arm64")))
|
if(CRASHPAD_BACKEND_URL AND (WIN32 OR APPLE)) # Linux is not supported for now
|
||||||
find_package(Crashpad QUIET)
|
find_package(Crashpad QUIET)
|
||||||
if(TARGET Crashpad::Crashpad)
|
if(TARGET Crashpad::Crashpad)
|
||||||
set(BUILD_WITH_CRASHPAD ON)
|
set(BUILD_WITH_CRASHPAD ON)
|
||||||
|
@@ -57,25 +57,9 @@ find_path(CRASHPAD_GEN_DIR
|
|||||||
"${CMAKE_PREFIX_PATH}"
|
"${CMAKE_PREFIX_PATH}"
|
||||||
)
|
)
|
||||||
|
|
||||||
if(APPLE)
|
|
||||||
find_path(CRASHPAD_OBJ_DIR
|
|
||||||
NAMES mig_output.child_portServer.o
|
|
||||||
PATH_SUFFIXES gen/util/mach
|
|
||||||
HINTS
|
|
||||||
"${CRASHPAD_OBJECT_DIR}"
|
|
||||||
"${CRASHPAD_LIB_DIR}/out/Default"
|
|
||||||
"${CMAKE_PREFIX_PATH}"
|
|
||||||
)
|
|
||||||
set(CRASHPAD_APPLE_VARS CRASHPAD_OBJ_DIR CRASHPAD_GEN_DIR)
|
|
||||||
find_library(FWbsm bsm)
|
|
||||||
find_library(FWAppKit AppKit)
|
|
||||||
find_library(FWIOKit IOKit)
|
|
||||||
find_library(FWSecurity Security)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
include(FindPackageHandleStandardArgs)
|
||||||
find_package_handle_standard_args(Crashpad DEFAULT_MSG
|
find_package_handle_standard_args(Crashpad DEFAULT_MSG
|
||||||
CRASHPAD_BIN_DIR CRASHPAD_INCLUDE_DIR CRASHPAD_LIB_DIR ${CRASHPAD_APPLE_VARS}
|
CRASHPAD_BIN_DIR CRASHPAD_INCLUDE_DIR CRASHPAD_LIB_DIR
|
||||||
)
|
)
|
||||||
|
|
||||||
if(Crashpad_FOUND)
|
if(Crashpad_FOUND)
|
||||||
@@ -93,18 +77,16 @@ if(Crashpad_FOUND)
|
|||||||
set_target_properties(Crashpad::Crashpad PROPERTIES
|
set_target_properties(Crashpad::Crashpad PROPERTIES
|
||||||
IMPORTED_LOCATION "${CRASHPAD_LIB_DIR}/client/client.lib")
|
IMPORTED_LOCATION "${CRASHPAD_LIB_DIR}/client/client.lib")
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
|
find_library(FWbsm bsm)
|
||||||
|
find_library(FWAppKit AppKit)
|
||||||
|
find_library(FWIOKit IOKit)
|
||||||
|
find_library(FWSecurity Security)
|
||||||
target_link_libraries(Crashpad::Crashpad INTERFACE
|
target_link_libraries(Crashpad::Crashpad INTERFACE
|
||||||
"${CRASHPAD_LIB_DIR}/third_party/mini_chromium/mini_chromium/base/libbase.a"
|
"${CRASHPAD_LIB_DIR}/third_party/mini_chromium/mini_chromium/base/libbase.a"
|
||||||
"${CRASHPAD_LIB_DIR}/util/libutil.a"
|
"${CRASHPAD_LIB_DIR}/util/libutil.a"
|
||||||
|
"${CRASHPAD_LIB_DIR}/util/libmig_output.a"
|
||||||
"${CRASHPAD_LIB_DIR}/client/libclient.a"
|
"${CRASHPAD_LIB_DIR}/client/libclient.a"
|
||||||
"${CRASHPAD_OBJ_DIR}/mig_output.child_portServer.o"
|
"${CRASHPAD_LIB_DIR}/client/libcommon.a"
|
||||||
"${CRASHPAD_OBJ_DIR}/mig_output.child_portUser.o"
|
|
||||||
"${CRASHPAD_OBJ_DIR}/mig_output.excServer.o"
|
|
||||||
"${CRASHPAD_OBJ_DIR}/mig_output.excUser.o"
|
|
||||||
"${CRASHPAD_OBJ_DIR}/mig_output.mach_excServer.o"
|
|
||||||
"${CRASHPAD_OBJ_DIR}/mig_output.mach_excUser.o"
|
|
||||||
"${CRASHPAD_OBJ_DIR}/mig_output.notifyServer.o"
|
|
||||||
"${CRASHPAD_OBJ_DIR}/mig_output.notifyUser.o"
|
|
||||||
${FWbsm} ${FWAppKit} ${FWIOKit} ${FWSecurity})
|
${FWbsm} ${FWAppKit} ${FWIOKit} ${FWSecurity})
|
||||||
set_target_properties(Crashpad::Crashpad PROPERTIES
|
set_target_properties(Crashpad::Crashpad PROPERTIES
|
||||||
IMPORTED_LOCATION "${CRASHPAD_LIB_DIR}/client/libclient.a")
|
IMPORTED_LOCATION "${CRASHPAD_LIB_DIR}/client/libclient.a")
|
||||||
|
@@ -335,6 +335,10 @@ function(find_dependent_plugins varName)
|
|||||||
set(_RESULT ${ARGN})
|
set(_RESULT ${ARGN})
|
||||||
|
|
||||||
foreach(i ${ARGN})
|
foreach(i ${ARGN})
|
||||||
|
if(NOT TARGET ${i})
|
||||||
|
continue()
|
||||||
|
endif()
|
||||||
|
set(_dep)
|
||||||
get_property(_dep TARGET "${i}" PROPERTY _arg_DEPENDS)
|
get_property(_dep TARGET "${i}" PROPERTY _arg_DEPENDS)
|
||||||
if (_dep)
|
if (_dep)
|
||||||
find_dependent_plugins(_REC ${_dep})
|
find_dependent_plugins(_REC ${_dep})
|
||||||
|
@@ -7,7 +7,7 @@ instructions:
|
|||||||
variableValue: "RelWithDebInfo"
|
variableValue: "RelWithDebInfo"
|
||||||
- type: EnvironmentVariable
|
- type: EnvironmentVariable
|
||||||
variableName: LLVM_BASE_URL
|
variableName: LLVM_BASE_URL
|
||||||
variableValue: http://master.qt.io/development_releases/prebuilt/libclang/libclang-release_14.0.0-based
|
variableValue: http://master.qt.io/development_releases/prebuilt/libclang/libclang-release_14.0.3-based
|
||||||
|
|
||||||
- type: Group
|
- type: Group
|
||||||
instructions:
|
instructions:
|
||||||
|
83
dist/changes-7.0.2.md
vendored
Normal file
83
dist/changes-7.0.2.md
vendored
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
Qt Creator 7.0.2
|
||||||
|
================
|
||||||
|
|
||||||
|
Qt Creator version 7.0.2 contains bug fixes.
|
||||||
|
|
||||||
|
The most important changes are listed in this document. For a complete list of
|
||||||
|
changes, see the Git log for the Qt Creator sources that you can check out from
|
||||||
|
the public Git repository. For example:
|
||||||
|
|
||||||
|
git clone git://code.qt.io/qt-creator/qt-creator.git
|
||||||
|
git log --cherry-pick --pretty=oneline origin/v7.0.1..v7.0.2
|
||||||
|
|
||||||
|
General
|
||||||
|
-------
|
||||||
|
|
||||||
|
### Locator
|
||||||
|
|
||||||
|
* Fixed saving of command history of `Execute` filter
|
||||||
|
|
||||||
|
Editing
|
||||||
|
-------
|
||||||
|
|
||||||
|
* Fixed that actions could be applied to wrong editor after switching split
|
||||||
|
(QTCREATORBUG-27479)
|
||||||
|
|
||||||
|
### C++
|
||||||
|
|
||||||
|
* Fixed wrong `__cplusplus` value for older GCC versions
|
||||||
|
* ClangFormat
|
||||||
|
* Fixed disappearing settings drop down (QTCREATORBUG-26948)
|
||||||
|
|
||||||
|
### Language Client
|
||||||
|
|
||||||
|
* Fixed crash with function argument and quick fix hints (QTCREATORBUG-27404)
|
||||||
|
* Fixed selection in `Outline` view
|
||||||
|
* Fixed `Sort Alphabetically` for outline dropdown
|
||||||
|
|
||||||
|
Projects
|
||||||
|
--------
|
||||||
|
|
||||||
|
* Fixed crash with `Recent Projects` (QTCREATORBUG-27399)
|
||||||
|
* Fixed that `-include` flags were ignored by code model (QTCREATORBUG-27450)
|
||||||
|
|
||||||
|
### CMake
|
||||||
|
|
||||||
|
* Fixed crash when cancelling progress indicator (QTCREATORBUG-27499)
|
||||||
|
* Fixed application of build directory after `Browse` (QTCREATORBUG-27407)
|
||||||
|
|
||||||
|
Debugging
|
||||||
|
---------
|
||||||
|
|
||||||
|
* Fixed pretty printer for `QFile` in Qt 6.3
|
||||||
|
|
||||||
|
Platforms
|
||||||
|
---------
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
|
||||||
|
* Fixed compilier identification of `cc` and `c++` (QTCREATORBUG-27523)
|
||||||
|
|
||||||
|
Credits for these changes go to:
|
||||||
|
--------------------------------
|
||||||
|
Alessandro Portale
|
||||||
|
Artem Sokolovskii
|
||||||
|
Brook Cronin
|
||||||
|
Christian Kandeler
|
||||||
|
Christian Stenger
|
||||||
|
Cristian Adam
|
||||||
|
David Schulz
|
||||||
|
Eike Ziller
|
||||||
|
Henning Gruendl
|
||||||
|
Jaroslaw Kobus
|
||||||
|
Kai Uwe Broulik
|
||||||
|
Knud Dollereder
|
||||||
|
Leena Miettinen
|
||||||
|
Mahmoud Badri
|
||||||
|
Mats Honkamaa
|
||||||
|
Miikka Heikkinen
|
||||||
|
Orgad Shaneh
|
||||||
|
Robert Löhning
|
||||||
|
Thomas Hartmann
|
||||||
|
Tim Jenssen
|
||||||
|
Vikas Pachdha
|
@@ -41,16 +41,14 @@
|
|||||||
|
|
||||||
\title Using QML Modules with Plugins
|
\title Using QML Modules with Plugins
|
||||||
|
|
||||||
QML modules may use plugins to expose components defined in C++ to QML
|
\l{Defining a QML Module}{QML modules} may use \l{Creating C++ Plugins for QML}
|
||||||
applications. \QC cannot load the plugins to determine the details of
|
{C++ plugins} to expose components defined in C++ to QML applications.
|
||||||
the contained components, and therefore, the modules must provide extra type
|
|
||||||
information for code completion and the semantic checks to work correctly.
|
|
||||||
|
|
||||||
To create a QML module
|
To create a QML
|
||||||
\if defined(qtdesignstudio)
|
\if defined(qtdesignstudio)
|
||||||
and make it appear in the \l Components view:
|
module and make it appear in the \l Components view:
|
||||||
\else
|
\else
|
||||||
:
|
module:
|
||||||
\endif
|
\endif
|
||||||
|
|
||||||
\list 1
|
\list 1
|
||||||
@@ -97,26 +95,13 @@
|
|||||||
\c .metainfo file is in place.
|
\c .metainfo file is in place.
|
||||||
\endif
|
\endif
|
||||||
|
|
||||||
\if defined(qtcreator)
|
|
||||||
\section1 Registering QML Types
|
|
||||||
|
|
||||||
When you write a QML module or use QML from a C++ application, and the C++
|
|
||||||
is a part of your qmake project, you typically register new types with the
|
|
||||||
\c qmlRegisterType() function or expose some class instances with
|
|
||||||
\l{QQmlContext::setContextProperty()}. The \QC C++ code model now scans for
|
|
||||||
these calls and tells the QML code model about them. This means that properties
|
|
||||||
are displayed during code completion and the JavaScript code checker does not
|
|
||||||
complain about unknown types. However, this works only when the source code
|
|
||||||
is available, and therefore, you must explicitly generate type information
|
|
||||||
for QML modules with plugins before distributing them.
|
|
||||||
\endif
|
|
||||||
|
|
||||||
\section1 Generating Type Description Files
|
\section1 Generating Type Description Files
|
||||||
|
|
||||||
Ideally, QML modules have a \c{plugins.qmltypes} file in the same directory
|
When \l{Defining QML Types from C++}{registering QML types}, make sure that
|
||||||
as the \c qmldir file. The \c qmltypes file contains a description of the
|
the QML module has a \c{plugins.qmltypes} file. Ideally, it should be located
|
||||||
components exported by the module's plugins and is loaded by \QC when the
|
in the same directory as the \c qmldir file. The \c qmltypes file contains a
|
||||||
module is imported.
|
description of the components exported by the module's plugins and is loaded
|
||||||
|
by \QC when the module is imported.
|
||||||
|
|
||||||
For more information, see \l{Type Description Files}.
|
For more information, see \l{Type Description Files}.
|
||||||
|
|
||||||
@@ -127,7 +112,6 @@
|
|||||||
However, this automatic dumping is a fallback mechanism with many points of
|
However, this automatic dumping is a fallback mechanism with many points of
|
||||||
failure and you cannot rely upon it.
|
failure and you cannot rely upon it.
|
||||||
|
|
||||||
\if defined(qtcreator)
|
|
||||||
\section1 Importing QML Modules
|
\section1 Importing QML Modules
|
||||||
|
|
||||||
By default, \QC will look in the QML import path of Qt for QML modules.
|
By default, \QC will look in the QML import path of Qt for QML modules.
|
||||||
@@ -145,7 +129,7 @@
|
|||||||
|
|
||||||
The import path affects all the targets built by the CMake project.
|
The import path affects all the targets built by the CMake project.
|
||||||
|
|
||||||
\else
|
\if defined(qtdesignstudio)
|
||||||
\section1 Running QML Modules in Design Mode
|
\section1 Running QML Modules in Design Mode
|
||||||
|
|
||||||
A QML emulation layer (also called QML Puppet) is used in the
|
A QML emulation layer (also called QML Puppet) is used in the
|
||||||
@@ -169,7 +153,7 @@
|
|||||||
by an application or edited in the \uicontrol Design mode.
|
by an application or edited in the \uicontrol Design mode.
|
||||||
|
|
||||||
If you want to use a different module in the \uicontrol Design mode
|
If you want to use a different module in the \uicontrol Design mode
|
||||||
than in your actual application for example to mockup C++ items,
|
than in your actual application for example to mockup C++ items,
|
||||||
you can use \c{QML_DESIGNER_IMPORT_PATH}
|
you can use \c{QML_DESIGNER_IMPORT_PATH}
|
||||||
in the \c{.pro} file (for qmake projects), or declare and set the property
|
in the \c{.pro} file (for qmake projects), or declare and set the property
|
||||||
\c qmlDesignerImportPaths in your product (for Qbs projects).
|
\c qmlDesignerImportPaths in your product (for Qbs projects).
|
||||||
|
BIN
doc/qtdesignstudio/images/studio-asset-import.png
Normal file
BIN
doc/qtdesignstudio/images/studio-asset-import.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
Binary file not shown.
Before Width: | Height: | Size: 17 KiB |
Binary file not shown.
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 51 KiB |
@@ -32,8 +32,8 @@
|
|||||||
|
|
||||||
\title Exporting Designs from Figma
|
\title Exporting Designs from Figma
|
||||||
|
|
||||||
You can use \QBF to export designs from Figma to \e {.metadata}
|
You can use \QBF to export designs from Figma to a \e {.qtbridge}
|
||||||
format that you can \l{Importing 2D Assets}{import} to projects in \QDS.
|
archive that you can \l{Importing 2D Assets}{import} to projects in \QDS.
|
||||||
|
|
||||||
\image studio-figma-export.png
|
\image studio-figma-export.png
|
||||||
|
|
||||||
|
@@ -128,9 +128,8 @@
|
|||||||
\li When the exporting is done, select \uicontrol OK.
|
\li When the exporting is done, select \uicontrol OK.
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
\QBF exports everything into a single archive. Before importing the design
|
\QBF exports everything into a .qtbridge archive. You can import the archive
|
||||||
into \QDS, you have to manually extract the archive. Then you can import the
|
into a project in \QDS, as described in \l{Importing 2D Assets}.
|
||||||
\e .metainfo into a project in \QDS, as described in \l{Importing 2D Assets}.
|
|
||||||
|
|
||||||
\section1 Export Settings
|
\section1 Export Settings
|
||||||
|
|
||||||
|
@@ -55,48 +55,47 @@
|
|||||||
\image studio-imported-assets.png "UI imported into Qt Design Studio"
|
\image studio-imported-assets.png "UI imported into Qt Design Studio"
|
||||||
|
|
||||||
\QB enables you to export assets and then import them to a \QDS project
|
\QB enables you to export assets and then import them to a \QDS project
|
||||||
as image and QML files for editing in \l {Form Editor}. If you make changes
|
as images and QML files for editing in \l {Form Editor}. If you make changes
|
||||||
to your design in the design tool that you originally used to create it,
|
to your design in the design tool that you originally used to create it,
|
||||||
you can merge the changes into existing QML files without overwriting the
|
you can merge the changes into existing QML files without overwriting the
|
||||||
changes you have made in \QDS. For more information, see
|
changes you have made in \QDS. For more information, see
|
||||||
\l {Exporting from Design Tools}.
|
\l {Exporting from Design Tools}.
|
||||||
|
|
||||||
\note Attempting to import assets exported on another system might fail.
|
\QB exports the designs either as an archive(.qtbridge) or as images with
|
||||||
|
a .metadata file. \QDS support both formats.
|
||||||
|
|
||||||
The following instructions use an empty project as an example. For more
|
The following instructions use an empty project as an example. For more
|
||||||
information about the options you have, see
|
information about the options you have, see
|
||||||
\l {Creating Projects}.
|
\l {Creating Projects}.
|
||||||
|
|
||||||
To import assets exported in \QB to \QDS projects:
|
To import the exported assets to \QDS projects:
|
||||||
|
|
||||||
\list 1
|
\list 1
|
||||||
\li Select \uicontrol File > \uicontrol {New Project} >
|
\li Select \uicontrol File > \uicontrol {New Project} >
|
||||||
\uicontrol General > \uicontrol {Qt Quick Application - Empty} >
|
\uicontrol General > \uicontrol {Empty}. Add \uicontrol {Details} about
|
||||||
\uicontrol Choose, and follow the instructions of the wizard to
|
the project and select \uicontrol Create.
|
||||||
create an empty project.
|
|
||||||
\li In \uicontrol Projects, double-click \e Screen01.ui.qml to move to
|
\li In \uicontrol Projects, double-click \e Screen01.ui.qml to move to
|
||||||
the Design mode.
|
the Design mode.
|
||||||
\li Select \uicontrol Assets > \inlineimage icons/plus.png
|
\li Select \uicontrol Assets > \inlineimage icons/plus.png
|
||||||
.
|
.
|
||||||
\li Select the folder where you exported the assets.
|
\li Select the folder where you exported the assets.
|
||||||
\li Select \uicontrol {Exported Assets (*.metadata)} in the dropdown
|
\li Select \uicontrol {Compressed Metadata (*.qtbridge)} or
|
||||||
menu to filter \e .metadata files.
|
\uicontrol {Exported Metadata (*.metadata)} in the dropdown menu to
|
||||||
\li Select a \e .metadata file to import, and then select
|
filter the exported files.
|
||||||
\uicontrol Open.
|
\li Select a the file to import and then select \uicontrol Open.
|
||||||
\li Select \uicontrol Details next to the
|
\li Select \uicontrol Details next to the
|
||||||
\uicontrol {Metadata Import Paths} field to display the path where
|
\uicontrol {Import Paths} field to display the path where the exported
|
||||||
the metadata is imported from.
|
assets are imported from.
|
||||||
\image studio-import-metadata.png "Asset Import dialog"
|
\image studio-asset-import.png "Asset Import dialog"
|
||||||
\li Select \uicontrol Details next to the
|
\li Select \uicontrol Details next to the
|
||||||
\uicontrol {QML/Asset Export Paths} field to display the paths to
|
\uicontrol {Export Paths} field to display the paths to
|
||||||
copy the assets to.
|
copy the assets to.
|
||||||
\li In the \uicontrol QML field, you can change the folder to copy the
|
\li In the \uicontrol QML field, you can change the folder to copy the
|
||||||
QML files to.
|
QML files to.
|
||||||
\li In the \uicontrol Assets field, you can change the folder to copy
|
\li In the \uicontrol Assets field, you can change the folder to copy
|
||||||
the image files to.
|
the image files to.
|
||||||
\li Select the \uicontrol {Create sub directory for each metadata}
|
\li Select the \uicontrol {Create sub directory} check box to import the
|
||||||
check box to copy the directory structure from the metadata file
|
assets in a sub directory inside \uicontrol {Export Paths}.
|
||||||
to \QDS.
|
|
||||||
\li Deselect the \uicontrol {Import assets} check box if you only want
|
\li Deselect the \uicontrol {Import assets} check box if you only want
|
||||||
to create QML files.
|
to create QML files.
|
||||||
\li Deselect the \uicontrol {Generate QML} check box if you only
|
\li Deselect the \uicontrol {Generate QML} check box if you only
|
||||||
@@ -104,26 +103,21 @@
|
|||||||
\li Select the \uicontrol {Merge QML} check box if you have imported the
|
\li Select the \uicontrol {Merge QML} check box if you have imported the
|
||||||
assets before and want to merge the changes into existing QML files
|
assets before and want to merge the changes into existing QML files
|
||||||
instead of overwriting the existing files. See \l {Merging QML Files}.
|
instead of overwriting the existing files. See \l {Merging QML Files}.
|
||||||
|
\li Select the \uicontrol {Round off coordinates} check box to round off
|
||||||
|
the position and dimension values to integers in the generated QML files.
|
||||||
|
\li Select the \uicontrol {Save Logs} check box to write the export logs
|
||||||
|
to a text file inside the directory selected in \uicontrol QML export path.
|
||||||
\li Select \uicontrol Import to import the QML files and assets. This
|
\li Select \uicontrol Import to import the QML files and assets. This
|
||||||
might take a little while for complex projects.
|
might take a little while for complex projects.
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
The imported assets are displayed in \uicontrol Assets
|
The imported assets are displayed in \uicontrol Assets as images.
|
||||||
as PNG images. The components that you specified in the design tool are
|
The components that you specified in the design tool are displayed in
|
||||||
displayed in \uicontrol Components > \uicontrol {My Components} as well as
|
\uicontrol Components > \uicontrol {My Components} as well as in the
|
||||||
in the \uicontrol Projects view as separate QML files. To start using them,
|
\uicontrol Projects view as separate QML files. To use them,
|
||||||
drag-and-drop them from \uicontrol Components to \uicontrol {Form Editor} or
|
drag-and-drop them from \uicontrol Components to \uicontrol {Form Editor} or
|
||||||
\l Navigator.
|
\l Navigator.
|
||||||
|
|
||||||
\note The layer that was the bottom layer in the design tool becames the top
|
|
||||||
layer in \uicontrol Navigator to reflect the QML code model. You
|
|
||||||
can view the QML code in \l{Text Editor}.
|
|
||||||
|
|
||||||
After importing the metadata files, wait a few moments to allow all
|
|
||||||
imported assets to appear in your project files before selecting your
|
|
||||||
metadata filename from \uicontrol Assets > \inlineimage icons/plus.png
|
|
||||||
.
|
|
||||||
|
|
||||||
If asset importer conflicts, warnings, and errors are displayed in the
|
If asset importer conflicts, warnings, and errors are displayed in the
|
||||||
\uicontrol {Asset Import} dialog while importing, fix the issues in
|
\uicontrol {Asset Import} dialog while importing, fix the issues in
|
||||||
design tool and export the assets again.
|
design tool and export the assets again.
|
||||||
|
@@ -263,32 +263,44 @@ def qdump__Utils__Environment(d, value):
|
|||||||
qdump__Utils__NameValueDictionary(d, value)
|
qdump__Utils__NameValueDictionary(d, value)
|
||||||
|
|
||||||
|
|
||||||
|
def qdump__Utils__DictKey(d, value):
|
||||||
|
d.putStringValue(value["name"])
|
||||||
|
|
||||||
|
|
||||||
def qdump__Utils__NameValueDictionary(d, value):
|
def qdump__Utils__NameValueDictionary(d, value):
|
||||||
dptr = d.extractPointer(value["m_values"])
|
dptr = d.extractPointer(value)
|
||||||
(ref, n) = d.split('ii', dptr)
|
if d.qtVersion() >= 0x60000:
|
||||||
d.check(0 <= n and n <= 100 * 1000 * 1000)
|
if dptr == 0:
|
||||||
d.check(-1 <= ref and ref < 100000)
|
d.putItemCount(0)
|
||||||
|
return
|
||||||
|
m = value['d']['d']['m']
|
||||||
|
d.putItem(m)
|
||||||
|
d.putBetterType('Utils::NameValueDictionary')
|
||||||
|
else: # Qt5
|
||||||
|
(ref, n) = d.split('ii', dptr)
|
||||||
|
d.check(0 <= n and n <= 100 * 1000 * 1000)
|
||||||
|
d.check(-1 <= ref and ref < 100000)
|
||||||
|
|
||||||
d.putItemCount(n)
|
d.putItemCount(n)
|
||||||
if d.isExpanded():
|
if d.isExpanded():
|
||||||
if n > 10000:
|
if n > 10000:
|
||||||
n = 10000
|
n = 10000
|
||||||
|
|
||||||
typeCode = 'ppp@{%s}@{%s}' % ("Utils::DictKey", "QString")
|
typeCode = 'ppp@{%s}@{%s}' % ("Utils::DictKey", "@QPair<@QString,bool>")
|
||||||
|
|
||||||
def helper(node):
|
def helper(node):
|
||||||
(p, left, right, padding1, key, padding2, value) = d.split(typeCode, node)
|
(p, left, right, padding1, key, padding2, value) = d.split(typeCode, node)
|
||||||
if left:
|
if left:
|
||||||
for res in helper(left):
|
for res in helper(left):
|
||||||
yield res
|
yield res
|
||||||
yield (key["name"], value)
|
yield (key["name"], value)
|
||||||
if right:
|
if right:
|
||||||
for res in helper(right):
|
for res in helper(right):
|
||||||
yield res
|
yield res
|
||||||
|
|
||||||
with Children(d, n):
|
with Children(d, n):
|
||||||
for (pair, i) in zip(helper(dptr + 8), range(n)):
|
for (pair, i) in zip(helper(dptr + 8), range(n)):
|
||||||
d.putPairItem(i, pair, 'key', 'value')
|
d.putPairItem(i, pair, 'key', 'value')
|
||||||
|
|
||||||
|
|
||||||
def qdump__Utf8String(d, value):
|
def qdump__Utf8String(d, value):
|
||||||
|
@@ -39,6 +39,8 @@ Node {
|
|||||||
// Note: Only one instance of HelperGrid is supported, as the geometry names are fixed
|
// Note: Only one instance of HelperGrid is supported, as the geometry names are fixed
|
||||||
|
|
||||||
Model { // Main grid lines
|
Model { // Main grid lines
|
||||||
|
castsShadows: false
|
||||||
|
receivesShadows: false
|
||||||
geometry: GridGeometry {
|
geometry: GridGeometry {
|
||||||
id: gridGeometry
|
id: gridGeometry
|
||||||
name: "3D Edit View Helper Grid"
|
name: "3D Edit View Helper Grid"
|
||||||
@@ -55,6 +57,8 @@ Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Model { // Subdivision lines
|
Model { // Subdivision lines
|
||||||
|
castsShadows: false
|
||||||
|
receivesShadows: false
|
||||||
geometry: GridGeometry {
|
geometry: GridGeometry {
|
||||||
lines: gridGeometry.lines
|
lines: gridGeometry.lines
|
||||||
step: gridGeometry.step
|
step: gridGeometry.step
|
||||||
@@ -73,6 +77,8 @@ Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Model { // Z Axis
|
Model { // Z Axis
|
||||||
|
castsShadows: false
|
||||||
|
receivesShadows: false
|
||||||
geometry: GridGeometry {
|
geometry: GridGeometry {
|
||||||
lines: gridGeometry.lines
|
lines: gridGeometry.lines
|
||||||
step: gridGeometry.step
|
step: gridGeometry.step
|
||||||
@@ -89,6 +95,8 @@ Node {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
Model { // X Axis
|
Model { // X Axis
|
||||||
|
castsShadows: false
|
||||||
|
receivesShadows: false
|
||||||
eulerRotation.z: 90
|
eulerRotation.z: 90
|
||||||
geometry: GridGeometry {
|
geometry: GridGeometry {
|
||||||
lines: gridGeometry.lines
|
lines: gridGeometry.lines
|
||||||
|
@@ -54,6 +54,9 @@ Node {
|
|||||||
|
|
||||||
visible: selectionBox.targetNode && !selectionBoxGeometry.isEmpty
|
visible: selectionBox.targetNode && !selectionBoxGeometry.isEmpty
|
||||||
|
|
||||||
|
castsShadows: false
|
||||||
|
receivesShadows: false
|
||||||
|
|
||||||
materials: [
|
materials: [
|
||||||
DefaultMaterial {
|
DefaultMaterial {
|
||||||
diffuseColor: "#fff600"
|
diffuseColor: "#fff600"
|
||||||
|
@@ -40,6 +40,8 @@ Node {
|
|||||||
|
|
||||||
Model { // Main grid lines
|
Model { // Main grid lines
|
||||||
readonly property bool _edit3dLocked: true // Make this non-pickable
|
readonly property bool _edit3dLocked: true // Make this non-pickable
|
||||||
|
castsShadows: false
|
||||||
|
receivesShadows: false
|
||||||
geometry: GridGeometry {
|
geometry: GridGeometry {
|
||||||
id: gridGeometry
|
id: gridGeometry
|
||||||
name: "3D Edit View Helper Grid"
|
name: "3D Edit View Helper Grid"
|
||||||
@@ -57,6 +59,8 @@ Node {
|
|||||||
|
|
||||||
Model { // Subdivision lines
|
Model { // Subdivision lines
|
||||||
readonly property bool _edit3dLocked: true // Make this non-pickable
|
readonly property bool _edit3dLocked: true // Make this non-pickable
|
||||||
|
castsShadows: false
|
||||||
|
receivesShadows: false
|
||||||
geometry: GridGeometry {
|
geometry: GridGeometry {
|
||||||
lines: gridGeometry.lines
|
lines: gridGeometry.lines
|
||||||
step: gridGeometry.step
|
step: gridGeometry.step
|
||||||
@@ -76,6 +80,8 @@ Node {
|
|||||||
|
|
||||||
Model { // Z Axis
|
Model { // Z Axis
|
||||||
readonly property bool _edit3dLocked: true // Make this non-pickable
|
readonly property bool _edit3dLocked: true // Make this non-pickable
|
||||||
|
castsShadows: false
|
||||||
|
receivesShadows: false
|
||||||
geometry: GridGeometry {
|
geometry: GridGeometry {
|
||||||
lines: gridGeometry.lines
|
lines: gridGeometry.lines
|
||||||
step: gridGeometry.step
|
step: gridGeometry.step
|
||||||
@@ -93,6 +99,8 @@ Node {
|
|||||||
}
|
}
|
||||||
Model { // X Axis
|
Model { // X Axis
|
||||||
readonly property bool _edit3dLocked: true // Make this non-pickable
|
readonly property bool _edit3dLocked: true // Make this non-pickable
|
||||||
|
castsShadows: false
|
||||||
|
receivesShadows: false
|
||||||
eulerRotation.z: 90
|
eulerRotation.z: 90
|
||||||
geometry: GridGeometry {
|
geometry: GridGeometry {
|
||||||
lines: gridGeometry.lines
|
lines: gridGeometry.lines
|
||||||
|
@@ -55,6 +55,9 @@ Node {
|
|||||||
|
|
||||||
visible: selectionBox.targetNode && !selectionBoxGeometry.isEmpty
|
visible: selectionBox.targetNode && !selectionBoxGeometry.isEmpty
|
||||||
|
|
||||||
|
castsShadows: false
|
||||||
|
receivesShadows: false
|
||||||
|
|
||||||
materials: [
|
materials: [
|
||||||
DefaultMaterial {
|
DefaultMaterial {
|
||||||
diffuseColor: "#fff600"
|
diffuseColor: "#fff600"
|
||||||
|
@@ -1610,7 +1610,7 @@ void NodeInstanceServer::addAnimation(QQuickAbstractAnimation *animation)
|
|||||||
m_animations.push_back(animation);
|
m_animations.push_back(animation);
|
||||||
|
|
||||||
QQuickPropertyAnimation *panim = qobject_cast<QQuickPropertyAnimation *>(animation);
|
QQuickPropertyAnimation *panim = qobject_cast<QQuickPropertyAnimation *>(animation);
|
||||||
if (panim) {
|
if (panim && panim->target()) {
|
||||||
QObject *target = panim->target();
|
QObject *target = panim->target();
|
||||||
QString property = panim->property();
|
QString property = panim->property();
|
||||||
QVariant value = target->property(qPrintable(baseProperty(property)));
|
QVariant value = target->property(qPrintable(baseProperty(property)));
|
||||||
|
@@ -534,7 +534,7 @@ void Qt5InformationNodeInstanceServer::handleParticleSystemDeselected()
|
|||||||
for (auto a : anim) {
|
for (auto a : anim) {
|
||||||
a->stop();
|
a->stop();
|
||||||
QQuickPropertyAnimation *panim = qobject_cast<QQuickPropertyAnimation *>(a);
|
QQuickPropertyAnimation *panim = qobject_cast<QQuickPropertyAnimation *>(a);
|
||||||
if (panim)
|
if (panim && panim->target())
|
||||||
panim->target()->setProperty(qPrintable(baseProperty(panim->property())), animationDefaultValue(i));
|
panim->target()->setProperty(qPrintable(baseProperty(panim->property())), animationDefaultValue(i));
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@@ -135,7 +135,7 @@ void Qt5RenderNodeInstanceServer::collectItemChangesAndSendChangeCommands()
|
|||||||
|
|
||||||
if (rootNodeInstance().isSubclassOf("QQuick3DNode") && rootNodeInstance().contentItem()
|
if (rootNodeInstance().isSubclassOf("QQuick3DNode") && rootNodeInstance().contentItem()
|
||||||
&& DesignerSupport::isDirty(rootNodeInstance().contentItem(),
|
&& DesignerSupport::isDirty(rootNodeInstance().contentItem(),
|
||||||
DesignerSupport::ContentUpdateMask)
|
DesignerSupport::AllMask)
|
||||||
&& nodeInstanceClient()->bytesToWrite() < 10000) {
|
&& nodeInstanceClient()->bytesToWrite() < 10000) {
|
||||||
Internal::QuickItemNodeInstance::updateDirtyNode(rootNodeInstance().contentItem());
|
Internal::QuickItemNodeInstance::updateDirtyNode(rootNodeInstance().contentItem());
|
||||||
nodeInstanceClient()->pixmapChanged(createPixmapChangedCommand({rootNodeInstance()}));
|
nodeInstanceClient()->pixmapChanged(createPixmapChangedCommand({rootNodeInstance()}));
|
||||||
|
@@ -59,9 +59,6 @@ Item {
|
|||||||
var complexSuffixes = rootView.supportedAssetSuffixes(true);
|
var complexSuffixes = rootView.supportedAssetSuffixes(true);
|
||||||
for (const u of drag.urls) {
|
for (const u of drag.urls) {
|
||||||
var url = u.toString();
|
var url = u.toString();
|
||||||
if (url.startsWith("file:///")) // remove file scheme (happens on Windows)
|
|
||||||
url = url.substr(8)
|
|
||||||
|
|
||||||
var ext = '*.' + url.slice(url.lastIndexOf('.') + 1).toLowerCase()
|
var ext = '*.' + url.slice(url.lastIndexOf('.') + 1).toLowerCase()
|
||||||
if (simpleSuffixes.includes(ext))
|
if (simpleSuffixes.includes(ext))
|
||||||
root.dropSimpleExtFiles.push(url)
|
root.dropSimpleExtFiles.push(url)
|
||||||
|
@@ -143,7 +143,8 @@ Section {
|
|||||||
PropertyLabel {
|
PropertyLabel {
|
||||||
text: qsTr("Style name")
|
text: qsTr("Style name")
|
||||||
tooltip: qsTr("Font's style.")
|
tooltip: qsTr("Font's style.")
|
||||||
blockedByTemplate: !styleNameComboBox.enabled
|
enabled: styleNameComboBox.model.length
|
||||||
|
blockedByTemplate: !backendValue.isAvailable
|
||||||
}
|
}
|
||||||
|
|
||||||
SecondColumnLayout {
|
SecondColumnLayout {
|
||||||
@@ -156,7 +157,7 @@ Section {
|
|||||||
backendValue: getBackendValue("styleName")
|
backendValue: getBackendValue("styleName")
|
||||||
model: styleNamesForFamily(fontComboBox.familyName)
|
model: styleNamesForFamily(fontComboBox.familyName)
|
||||||
valueType: ComboBox.String
|
valueType: ComboBox.String
|
||||||
enabled: backendValue.isAvailable
|
enabled: backendValue.isAvailable && styleNameComboBox.model.length
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpandingSpacer {}
|
ExpandingSpacer {}
|
||||||
|
@@ -92,7 +92,6 @@ StudioControls.ComboBox {
|
|||||||
onValueFromBackendChanged: colorLogic.invalidate()
|
onValueFromBackendChanged: colorLogic.invalidate()
|
||||||
|
|
||||||
function invalidate() {
|
function invalidate() {
|
||||||
|
|
||||||
if (comboBox.block)
|
if (comboBox.block)
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -140,6 +139,21 @@ StudioControls.ComboBox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
if (!comboBox.__isCompleted)
|
||||||
|
return
|
||||||
|
|
||||||
|
let inputValue = comboBox.editText
|
||||||
|
|
||||||
|
let index = comboBox.find(inputValue)
|
||||||
|
if (index !== -1)
|
||||||
|
inputValue = comboBox.textAt(index)
|
||||||
|
|
||||||
|
comboBox.backendValue.value = inputValue
|
||||||
|
|
||||||
|
comboBox.dirty = false
|
||||||
|
}
|
||||||
|
|
||||||
onCompressedActivated: {
|
onCompressedActivated: {
|
||||||
if (!comboBox.__isCompleted)
|
if (!comboBox.__isCompleted)
|
||||||
return
|
return
|
||||||
|
@@ -131,7 +131,7 @@ Item {
|
|||||||
checkable: true
|
checkable: true
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if (checked)
|
if (checked)
|
||||||
backendValue.exportPopertyAsAlias()
|
backendValue.exportPropertyAsAlias()
|
||||||
else
|
else
|
||||||
backendValue.removeAliasExport()
|
backendValue.removeAliasExport()
|
||||||
}
|
}
|
||||||
|
@@ -29,7 +29,7 @@ import HelperWidgets 2.0
|
|||||||
import StudioControls 1.0 as StudioControls
|
import StudioControls 1.0 as StudioControls
|
||||||
|
|
||||||
StudioControls.ComboBox {
|
StudioControls.ComboBox {
|
||||||
id: comboBox
|
id: root
|
||||||
|
|
||||||
property variant backendValue
|
property variant backendValue
|
||||||
property color textColor: colorLogic.textColor
|
property color textColor: colorLogic.textColor
|
||||||
@@ -39,17 +39,17 @@ StudioControls.ComboBox {
|
|||||||
labelColor: colorLogic.textColor
|
labelColor: colorLogic.textColor
|
||||||
editable: true
|
editable: true
|
||||||
|
|
||||||
onTextColorChanged: setColor()
|
onTextColorChanged: root.setColor()
|
||||||
|
|
||||||
FileResourcesModel {
|
FileResourcesModel {
|
||||||
id: fileModel
|
id: fileModel
|
||||||
modelNodeBackendProperty: modelNodeBackend
|
modelNodeBackendProperty: modelNodeBackend
|
||||||
filter: comboBox.fontFilter
|
filter: root.fontFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
function createFontLoader(fontUrl) {
|
function createFontLoader(fontUrl) {
|
||||||
return Qt.createQmlObject('import QtQuick 2.0; FontLoader { source: "' + fontUrl + '"; }',
|
return Qt.createQmlObject('import QtQuick 2.0; FontLoader { source: "' + fontUrl + '"; }',
|
||||||
comboBox, "dynamicFontLoader")
|
root, "dynamicFontLoader")
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupModel() {
|
function setupModel() {
|
||||||
@@ -63,80 +63,83 @@ StudioControls.ComboBox {
|
|||||||
// Remove duplicate family names
|
// Remove duplicate family names
|
||||||
familyNames = [...new Set(familyNames)]
|
familyNames = [...new Set(familyNames)]
|
||||||
familyNames.sort()
|
familyNames.sort()
|
||||||
comboBox.model = familyNames
|
root.model = familyNames
|
||||||
|
root.currentIndex = root.find(root.backendValue.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
onModelChanged: editText = comboBox.backendValue.valueToString
|
function setColor() {
|
||||||
|
// Hack to style the text input
|
||||||
|
for (var i = 0; i < root.children.length; i++) {
|
||||||
|
if (root.children[i].text !== undefined) {
|
||||||
|
root.children[i].color = root.textColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onModelChanged: root.editText = root.backendValue.valueToString
|
||||||
|
|
||||||
ExtendedFunctionLogic {
|
ExtendedFunctionLogic {
|
||||||
id: extFuncLogic
|
id: extFuncLogic
|
||||||
backendValue: comboBox.backendValue
|
backendValue: root.backendValue
|
||||||
}
|
}
|
||||||
|
|
||||||
actionIndicator.icon.color: extFuncLogic.color
|
actionIndicator.icon.color: extFuncLogic.color
|
||||||
actionIndicator.icon.text: extFuncLogic.glyph
|
actionIndicator.icon.text: extFuncLogic.glyph
|
||||||
actionIndicator.onClicked: extFuncLogic.show()
|
actionIndicator.onClicked: extFuncLogic.show()
|
||||||
actionIndicator.forceVisible: extFuncLogic.menuVisible
|
actionIndicator.forceVisible: extFuncLogic.menuVisible
|
||||||
actionIndicator.visible: comboBox.showExtendedFunctionButton
|
actionIndicator.visible: root.showExtendedFunctionButton
|
||||||
|
|
||||||
ColorLogic {
|
ColorLogic {
|
||||||
id: colorLogic
|
id: colorLogic
|
||||||
property string textValue: comboBox.backendValue.valueToString
|
property string textValue: root.backendValue.valueToString
|
||||||
backendValue: comboBox.backendValue
|
backendValue: root.backendValue
|
||||||
onTextValueChanged: comboBox.editText = colorLogic.textValue
|
onTextValueChanged: root.editText = colorLogic.textValue
|
||||||
}
|
}
|
||||||
|
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
if (backendValue === undefined)
|
if (root.backendValue === undefined)
|
||||||
return
|
return
|
||||||
|
|
||||||
if (editText === "")
|
if (root.editText === "")
|
||||||
return
|
return
|
||||||
|
|
||||||
if (backendValue.value !== editText)
|
if (root.backendValue.value !== root.editText)
|
||||||
backendValue.value = editText;
|
root.backendValue.value = root.editText
|
||||||
}
|
}
|
||||||
|
|
||||||
onActivated: {
|
onCompressedActivated: function(index, reason) { root.handleActivate(index) }
|
||||||
if (backendValue === undefined)
|
|
||||||
|
function handleActivate(index)
|
||||||
|
{
|
||||||
|
if (root.backendValue === undefined)
|
||||||
return
|
return
|
||||||
|
|
||||||
if (editText === "")
|
if (root.editText === "")
|
||||||
return
|
return
|
||||||
|
|
||||||
var indexText = comboBox.textAt(index)
|
var indexText = root.textAt(index)
|
||||||
|
|
||||||
if (backendValue.value !== indexText)
|
if (root.backendValue.value !== indexText)
|
||||||
backendValue.value = indexText
|
root.backendValue.value = indexText
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: modelNodeBackend
|
target: modelNodeBackend
|
||||||
function onSelectionChanged() {
|
function onSelectionChanged() {
|
||||||
comboBox.editText = backendValue.value
|
root.editText = root.backendValue.value
|
||||||
setupModel()
|
root.setupModel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
setupModel()
|
root.setupModel()
|
||||||
// Hack to style the text input
|
// Hack to style the text input
|
||||||
for (var i = 0; i < comboBox.children.length; i++) {
|
for (var i = 0; i < root.children.length; i++) {
|
||||||
if (comboBox.children[i].text !== undefined) {
|
if (root.children[i].text !== undefined) {
|
||||||
comboBox.children[i].color = comboBox.textColor
|
root.children[i].color = root.textColor
|
||||||
comboBox.children[i].anchors.rightMargin = 34
|
root.children[i].anchors.rightMargin = 34
|
||||||
comboBox.children[i].anchors.leftMargin = 18
|
root.children[i].anchors.leftMargin = 18
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setColor() {
|
|
||||||
// Hack to style the text input
|
|
||||||
for (var i = 0; i < comboBox.children.length; i++) {
|
|
||||||
if (comboBox.children[i].text !== undefined) {
|
|
||||||
comboBox.children[i].color = comboBox.textColor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -32,36 +32,43 @@ StudioControls.TextField {
|
|||||||
id: lineEdit
|
id: lineEdit
|
||||||
|
|
||||||
property variant backendValue
|
property variant backendValue
|
||||||
property color borderColor: "#222"
|
|
||||||
property color highlightColor: "orange"
|
|
||||||
color: lineEdit.edit ? StudioTheme.Values.themeTextColor : colorLogic.textColor
|
|
||||||
|
|
||||||
property bool showTranslateCheckBox: true
|
|
||||||
translationIndicatorVisible: showTranslateCheckBox
|
|
||||||
|
|
||||||
property bool writeValueManually: false
|
property bool writeValueManually: false
|
||||||
property bool writeAsExpression: false
|
property bool writeAsExpression: false
|
||||||
|
|
||||||
property bool __dirty: false
|
property bool showTranslateCheckBox: true
|
||||||
|
|
||||||
property bool showExtendedFunctionButton: true
|
property bool showExtendedFunctionButton: true
|
||||||
|
property string context
|
||||||
|
|
||||||
actionIndicator.visible: showExtendedFunctionButton
|
property bool __dirty: false
|
||||||
|
|
||||||
signal commitData
|
signal commitData
|
||||||
|
|
||||||
property string context
|
color: lineEdit.edit ? StudioTheme.Values.themeTextColor : colorLogic.textColor
|
||||||
|
actionIndicator.visible: lineEdit.showExtendedFunctionButton
|
||||||
|
translationIndicatorVisible: lineEdit.showTranslateCheckBox
|
||||||
|
|
||||||
function setTranslateExpression() {
|
function setTranslateExpression() {
|
||||||
if (translateFunction() === "qsTranslate") {
|
if (translateFunction() === "qsTranslate") {
|
||||||
backendValue.expression = translateFunction()
|
lineEdit.backendValue.expression = translateFunction()
|
||||||
+ "(\"" + backendValue.getTranslationContext()
|
+ "(\"" + lineEdit.backendValue.getTranslationContext()
|
||||||
+ "\", " + "\"" + escapeString(text) + "\")"
|
+ "\", " + "\"" + lineEdit.escapeString(lineEdit.text) + "\")"
|
||||||
} else {
|
} else {
|
||||||
backendValue.expression = translateFunction() + "(\"" + escapeString(text) + "\")"
|
lineEdit.backendValue.expression = translateFunction()
|
||||||
|
+ "(\"" + lineEdit.escapeString(lineEdit.text) + "\")"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function escapeString(string) {
|
||||||
|
var str = string
|
||||||
|
str = str.replace(/\\/g, "\\\\")
|
||||||
|
str.replace(/\"/g, "\\\"")
|
||||||
|
str = str.replace(/\t/g, "\\t")
|
||||||
|
str = str.replace(/\r/g, "\\r")
|
||||||
|
str = str.replace(/\n/g, '\\n')
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
ExtendedFunctionLogic {
|
ExtendedFunctionLogic {
|
||||||
id: extFuncLogic
|
id: extFuncLogic
|
||||||
backendValue: lineEdit.backendValue
|
backendValue: lineEdit.backendValue
|
||||||
@@ -79,60 +86,58 @@ StudioControls.TextField {
|
|||||||
if (colorLogic.valueFromBackend === undefined) {
|
if (colorLogic.valueFromBackend === undefined) {
|
||||||
lineEdit.text = ""
|
lineEdit.text = ""
|
||||||
} else {
|
} else {
|
||||||
if (writeValueManually)
|
if (lineEdit.writeValueManually)
|
||||||
lineEdit.text = convertColorToString(colorLogic.valueFromBackend)
|
lineEdit.text = convertColorToString(colorLogic.valueFromBackend)
|
||||||
else
|
else
|
||||||
lineEdit.text = colorLogic.valueFromBackend
|
lineEdit.text = colorLogic.valueFromBackend
|
||||||
}
|
}
|
||||||
__dirty = false
|
lineEdit.__dirty = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onTextChanged: {
|
onTextChanged: lineEdit.__dirty = true
|
||||||
__dirty = true
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: modelNodeBackend
|
target: modelNodeBackend
|
||||||
function onSelectionToBeChanged() {
|
function onSelectionToBeChanged() {
|
||||||
if (__dirty && !writeValueManually) {
|
if (lineEdit.__dirty && !lineEdit.writeValueManually) {
|
||||||
if (writeAsExpression)
|
if (lineEdit.writeAsExpression)
|
||||||
lineEdit.backendValue.expression = text
|
lineEdit.backendValue.expression = lineEdit.text
|
||||||
else
|
else
|
||||||
lineEdit.backendValue.value = text
|
lineEdit.backendValue.value = lineEdit.text
|
||||||
} else if (__dirty) {
|
} else if (lineEdit.__dirty) {
|
||||||
commitData()
|
commitData()
|
||||||
}
|
}
|
||||||
|
|
||||||
__dirty = false
|
lineEdit.__dirty = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onEditingFinished: {
|
onEditingFinished: {
|
||||||
if (writeValueManually)
|
if (lineEdit.writeValueManually)
|
||||||
return
|
return
|
||||||
|
|
||||||
if (!__dirty)
|
if (!lineEdit.__dirty)
|
||||||
return
|
return
|
||||||
|
|
||||||
if (backendValue.isTranslated) {
|
if (lineEdit.backendValue.isTranslated) {
|
||||||
setTranslateExpression()
|
lineEdit.setTranslateExpression()
|
||||||
} else {
|
} else {
|
||||||
if (writeAsExpression) {
|
if (lineEdit.writeAsExpression) {
|
||||||
if (lineEdit.backendValue.expression !== text)
|
if (lineEdit.backendValue.expression !== lineEdit.text)
|
||||||
lineEdit.backendValue.expression = text
|
lineEdit.backendValue.expression = lineEdit.text
|
||||||
} else if (lineEdit.backendValue.value !== text) {
|
} else if (lineEdit.backendValue.value !== lineEdit.text) {
|
||||||
lineEdit.backendValue.value = text
|
lineEdit.backendValue.value = lineEdit.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
__dirty = false
|
lineEdit.__dirty = false
|
||||||
}
|
}
|
||||||
|
|
||||||
property bool isTranslated: colorLogic.backendValue === undefined ? false
|
property bool isTranslated: colorLogic.backendValue === undefined ? false
|
||||||
: colorLogic.backendValue.isTranslated
|
: colorLogic.backendValue.isTranslated
|
||||||
|
|
||||||
translationIndicator.onClicked: {
|
translationIndicator.onClicked: {
|
||||||
if (translationIndicator.checked) {
|
if (lineEdit.translationIndicator.checked) {
|
||||||
setTranslateExpression()
|
setTranslateExpression()
|
||||||
} else {
|
} else {
|
||||||
var textValue = lineEdit.text
|
var textValue = lineEdit.text
|
||||||
@@ -141,7 +146,8 @@ StudioControls.TextField {
|
|||||||
colorLogic.evaluate()
|
colorLogic.evaluate()
|
||||||
}
|
}
|
||||||
|
|
||||||
property variant backendValueValueInternal: backendValue === undefined ? 0 : backendValue.value
|
property variant backendValueValueInternal: lineEdit.backendValue === undefined ? 0
|
||||||
|
: lineEdit.backendValue.value
|
||||||
onBackendValueValueInternalChanged: {
|
onBackendValueValueInternalChanged: {
|
||||||
if (lineEdit.backendValue === undefined)
|
if (lineEdit.backendValue === undefined)
|
||||||
lineEdit.translationIndicator.checked = false
|
lineEdit.translationIndicator.checked = false
|
||||||
@@ -155,15 +161,4 @@ StudioControls.TextField {
|
|||||||
else
|
else
|
||||||
lineEdit.translationIndicator.checked = lineEdit.backendValue.isTranslated
|
lineEdit.translationIndicator.checked = lineEdit.backendValue.isTranslated
|
||||||
}
|
}
|
||||||
|
|
||||||
function escapeString(string) {
|
|
||||||
var str = string
|
|
||||||
str = str.replace(/\\/g, "\\\\")
|
|
||||||
str.replace(/\"/g, "\\\"")
|
|
||||||
str = str.replace(/\t/g, "\\t")
|
|
||||||
str = str.replace(/\r/g, "\\r")
|
|
||||||
str = str.replace(/\n/g, '\\n')
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -32,7 +32,7 @@ import StudioTheme 1.0 as StudioTheme
|
|||||||
import QtQuickDesignerTheme 1.0
|
import QtQuickDesignerTheme 1.0
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: urlChooser
|
id: root
|
||||||
|
|
||||||
property variant backendValue
|
property variant backendValue
|
||||||
property color textColor: colorLogic.highlight ? colorLogic.textColor
|
property color textColor: colorLogic.highlight ? colorLogic.textColor
|
||||||
@@ -47,22 +47,24 @@ Row {
|
|||||||
FileResourcesModel {
|
FileResourcesModel {
|
||||||
id: fileModel
|
id: fileModel
|
||||||
modelNodeBackendProperty: modelNodeBackend
|
modelNodeBackendProperty: modelNodeBackend
|
||||||
filter: urlChooser.filter
|
filter: root.filter
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorLogic {
|
ColorLogic {
|
||||||
id: colorLogic
|
id: colorLogic
|
||||||
backendValue: urlChooser.backendValue
|
backendValue: root.backendValue
|
||||||
}
|
}
|
||||||
|
|
||||||
StudioControls.ComboBox {
|
StudioControls.FilterComboBox {
|
||||||
id: comboBox
|
id: comboBox
|
||||||
|
|
||||||
property ListModel items: ListModel {}
|
property ListModel listModel: ListModel {}
|
||||||
|
|
||||||
implicitWidth: StudioTheme.Values.singleControlColumnWidth
|
implicitWidth: StudioTheme.Values.singleControlColumnWidth
|
||||||
+ StudioTheme.Values.actionIndicatorWidth
|
+ StudioTheme.Values.actionIndicatorWidth
|
||||||
width: implicitWidth
|
width: implicitWidth
|
||||||
|
allowUserInput: true
|
||||||
|
|
||||||
// Note: highlightedIndex property isn't used because it has no setter and it doesn't reset
|
// Note: highlightedIndex property isn't used because it has no setter and it doesn't reset
|
||||||
// when the combobox is closed by focusing on some other control.
|
// when the combobox is closed by focusing on some other control.
|
||||||
property int hoverIndex: -1
|
property int hoverIndex: -1
|
||||||
@@ -70,7 +72,7 @@ Row {
|
|||||||
ToolTip {
|
ToolTip {
|
||||||
id: toolTip
|
id: toolTip
|
||||||
visible: comboBox.hover && toolTip.text !== ""
|
visible: comboBox.hover && toolTip.text !== ""
|
||||||
text: urlChooser.backendValue.valueToString
|
text: root.backendValue.valueToString
|
||||||
delay: StudioTheme.Values.toolTipDelay
|
delay: StudioTheme.Values.toolTipDelay
|
||||||
height: StudioTheme.Values.toolTipHeight
|
height: StudioTheme.Values.toolTipHeight
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
@@ -88,27 +90,39 @@ Row {
|
|||||||
delegate: ItemDelegate {
|
delegate: ItemDelegate {
|
||||||
required property string fullPath
|
required property string fullPath
|
||||||
required property string name
|
required property string name
|
||||||
|
required property int group
|
||||||
required property int index
|
required property int index
|
||||||
|
|
||||||
id: delegateItem
|
id: delegateRoot
|
||||||
width: parent.width
|
width: comboBox.popup.width - comboBox.popup.leftPadding - comboBox.popup.rightPadding
|
||||||
|
- (comboBox.popupScrollBar.visible ? comboBox.popupScrollBar.contentItem.implicitWidth + 2
|
||||||
|
: 0) // TODO Magic number
|
||||||
height: StudioTheme.Values.height - 2 * StudioTheme.Values.border
|
height: StudioTheme.Values.height - 2 * StudioTheme.Values.border
|
||||||
padding: 0
|
padding: 0
|
||||||
highlighted: comboBox.highlightedIndex === index
|
hoverEnabled: true
|
||||||
|
highlighted: comboBox.highlightedIndex === delegateRoot.DelegateModel.itemsIndex
|
||||||
|
|
||||||
|
onHoveredChanged: {
|
||||||
|
if (delegateRoot.hovered && !comboBox.popupMouseArea.active)
|
||||||
|
comboBox.setHighlightedIndexItems(delegateRoot.DelegateModel.itemsIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: comboBox.selectItem(delegateRoot.DelegateModel.itemsIndex)
|
||||||
|
|
||||||
indicator: Item {
|
indicator: Item {
|
||||||
id: itemDelegateIconArea
|
id: itemDelegateIconArea
|
||||||
width: delegateItem.height
|
width: delegateRoot.height
|
||||||
height: delegateItem.height
|
height: delegateRoot.height
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
id: itemDelegateIcon
|
id: itemDelegateIcon
|
||||||
text: StudioTheme.Constants.tickIcon
|
text: StudioTheme.Constants.tickIcon
|
||||||
color: delegateItem.highlighted ? StudioTheme.Values.themeTextSelectedTextColor
|
color: delegateRoot.highlighted ? StudioTheme.Values.themeTextSelectedTextColor
|
||||||
: StudioTheme.Values.themeTextColor
|
: StudioTheme.Values.themeTextColor
|
||||||
font.family: StudioTheme.Constants.iconFont.family
|
font.family: StudioTheme.Constants.iconFont.family
|
||||||
font.pixelSize: StudioTheme.Values.spinControlIconSizeMulti
|
font.pixelSize: StudioTheme.Values.spinControlIconSizeMulti
|
||||||
visible: comboBox.currentIndex === index ? true : false
|
visible: comboBox.currentIndex === delegateRoot.DelegateModel.itemsIndex ? true
|
||||||
|
: false
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
renderType: Text.NativeRendering
|
renderType: Text.NativeRendering
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
@@ -119,7 +133,7 @@ Row {
|
|||||||
contentItem: Text {
|
contentItem: Text {
|
||||||
leftPadding: itemDelegateIconArea.width
|
leftPadding: itemDelegateIconArea.width
|
||||||
text: name
|
text: name
|
||||||
color: delegateItem.highlighted ? StudioTheme.Values.themeTextSelectedTextColor
|
color: delegateRoot.highlighted ? StudioTheme.Values.themeTextSelectedTextColor
|
||||||
: StudioTheme.Values.themeTextColor
|
: StudioTheme.Values.themeTextColor
|
||||||
font: comboBox.font
|
font: comboBox.font
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
@@ -127,17 +141,17 @@ Row {
|
|||||||
}
|
}
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
id: itemDelegateBackground
|
|
||||||
x: 0
|
x: 0
|
||||||
y: 0
|
y: 0
|
||||||
width: delegateItem.width
|
width: delegateRoot.width
|
||||||
height: delegateItem.height
|
height: delegateRoot.height
|
||||||
color: delegateItem.highlighted ? StudioTheme.Values.themeInteraction : "transparent"
|
color: delegateRoot.highlighted ? StudioTheme.Values.themeInteraction
|
||||||
|
: "transparent"
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolTip {
|
ToolTip {
|
||||||
id: itemToolTip
|
id: itemToolTip
|
||||||
visible: delegateItem.hovered && comboBox.highlightedIndex === index
|
visible: delegateRoot.hovered && comboBox.highlightedIndex === index
|
||||||
text: fullPath
|
text: fullPath
|
||||||
delay: StudioTheme.Values.toolTipDelay
|
delay: StudioTheme.Values.toolTipDelay
|
||||||
height: StudioTheme.Values.toolTipHeight
|
height: StudioTheme.Values.toolTipHeight
|
||||||
@@ -161,7 +175,7 @@ Row {
|
|||||||
|
|
||||||
ExtendedFunctionLogic {
|
ExtendedFunctionLogic {
|
||||||
id: extFuncLogic
|
id: extFuncLogic
|
||||||
backendValue: urlChooser.backendValue
|
backendValue: root.backendValue
|
||||||
onReseted: comboBox.editText = ""
|
onReseted: comboBox.editText = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,20 +195,15 @@ Row {
|
|||||||
|
|
||||||
// Takes into account applied bindings
|
// Takes into account applied bindings
|
||||||
property string textValue: {
|
property string textValue: {
|
||||||
if (urlChooser.backendValue.isBound)
|
if (root.backendValue.isBound)
|
||||||
return urlChooser.backendValue.expression
|
return root.backendValue.expression
|
||||||
|
|
||||||
var fullPath = urlChooser.backendValue.valueToString
|
var fullPath = root.backendValue.valueToString
|
||||||
return fullPath.substr(fullPath.lastIndexOf('/') + 1)
|
return fullPath.substr(fullPath.lastIndexOf('/') + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
onTextValueChanged: comboBox.setCurrentText(comboBox.textValue)
|
onTextValueChanged: comboBox.setCurrentText(comboBox.textValue)
|
||||||
|
|
||||||
editable: true
|
|
||||||
textRole: "name"
|
|
||||||
valueRole: "fullPath"
|
|
||||||
model: comboBox.items
|
|
||||||
|
|
||||||
onModelChanged: {
|
onModelChanged: {
|
||||||
if (!comboBox.isComplete)
|
if (!comboBox.isComplete)
|
||||||
return
|
return
|
||||||
@@ -206,20 +215,14 @@ Row {
|
|||||||
if (!comboBox.isComplete)
|
if (!comboBox.isComplete)
|
||||||
return
|
return
|
||||||
|
|
||||||
var inputValue = comboBox.editText
|
let inputValue = comboBox.editText
|
||||||
|
|
||||||
// Check if value set by user matches with a name in the model then pick the full path
|
// Check if value set by user matches with a name in the model then pick the full path
|
||||||
var index = comboBox.find(inputValue)
|
let index = comboBox.find(inputValue)
|
||||||
if (index !== -1)
|
if (index !== -1)
|
||||||
inputValue = comboBox.items.get(index).fullPath
|
inputValue = comboBox.items.get(index).model.fullPath
|
||||||
|
|
||||||
// Get the currently assigned backend value, extract its file name and compare it to the
|
root.backendValue.value = inputValue
|
||||||
// input value. If they differ the new value needs to be set.
|
|
||||||
var currentValue = urlChooser.backendValue.value
|
|
||||||
var fileName = currentValue.substr(currentValue.lastIndexOf('/') + 1);
|
|
||||||
|
|
||||||
if (fileName !== inputValue)
|
|
||||||
urlChooser.backendValue.value = inputValue
|
|
||||||
|
|
||||||
comboBox.dirty = false
|
comboBox.dirty = false
|
||||||
}
|
}
|
||||||
@@ -234,14 +237,16 @@ Row {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleActivate(index) {
|
function handleActivate(index) {
|
||||||
if (urlChooser.backendValue === undefined || !comboBox.isComplete)
|
if (root.backendValue === undefined || !comboBox.isComplete)
|
||||||
return
|
return
|
||||||
|
|
||||||
if (index === -1) // select first item if index is invalid
|
let inputValue = comboBox.editText
|
||||||
index = 0
|
|
||||||
|
|
||||||
if (urlChooser.backendValue.value !== comboBox.items.get(index).fullPath)
|
if (index >= 0)
|
||||||
urlChooser.backendValue.value = comboBox.items.get(index).fullPath
|
inputValue = comboBox.items.get(index).model.fullPath
|
||||||
|
|
||||||
|
if (root.backendValue.value !== inputValue)
|
||||||
|
root.backendValue.value = inputValue
|
||||||
|
|
||||||
comboBox.dirty = false
|
comboBox.dirty = false
|
||||||
}
|
}
|
||||||
@@ -250,7 +255,7 @@ Row {
|
|||||||
// Hack to style the text input
|
// Hack to style the text input
|
||||||
for (var i = 0; i < comboBox.children.length; i++) {
|
for (var i = 0; i < comboBox.children.length; i++) {
|
||||||
if (comboBox.children[i].text !== undefined) {
|
if (comboBox.children[i].text !== undefined) {
|
||||||
comboBox.children[i].color = urlChooser.textColor
|
comboBox.children[i].color = root.textColor
|
||||||
comboBox.children[i].anchors.rightMargin = 34
|
comboBox.children[i].anchors.rightMargin = 34
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -261,36 +266,44 @@ Row {
|
|||||||
|
|
||||||
function createModel() {
|
function createModel() {
|
||||||
// Build the combobox model
|
// Build the combobox model
|
||||||
comboBox.items.clear()
|
comboBox.listModel.clear()
|
||||||
|
// While adding items to the model this binding needs to be interrupted, otherwise the
|
||||||
|
// update function of the SortFilterModel is triggered every time on append() which makes
|
||||||
|
// QtDS very slow. This will happen when selecting different items in the scene.
|
||||||
|
comboBox.model = {}
|
||||||
|
|
||||||
if (urlChooser.defaultItems !== undefined) {
|
if (root.defaultItems !== undefined) {
|
||||||
for (var i = 0; i < urlChooser.defaultItems.length; ++i) {
|
for (var i = 0; i < root.defaultItems.length; ++i) {
|
||||||
comboBox.items.append({
|
comboBox.listModel.append({
|
||||||
fullPath: urlChooser.defaultItems[i],
|
fullPath: root.defaultItems[i],
|
||||||
name: urlChooser.defaultItems[i]
|
name: root.defaultItems[i],
|
||||||
|
group: 0
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var j = 0; j < fileModel.fullPathModel.length; ++j) {
|
for (var j = 0; j < fileModel.fullPathModel.length; ++j) {
|
||||||
comboBox.items.append({
|
comboBox.listModel.append({
|
||||||
fullPath: fileModel.fullPathModel[j],
|
fullPath: fileModel.fullPathModel[j],
|
||||||
name: fileModel.fileNameModel[j]
|
name: fileModel.fileNameModel[j],
|
||||||
|
group: 1
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
comboBox.model = Qt.binding(function() { return comboBox.listModel })
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: fileModel
|
target: fileModel
|
||||||
function onFullPathModelChanged() {
|
function onFullPathModelChanged() {
|
||||||
urlChooser.createModel()
|
root.createModel()
|
||||||
comboBox.setCurrentText(comboBox.textValue)
|
comboBox.setCurrentText(comboBox.textValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onDefaultItemsChanged: urlChooser.createModel()
|
onDefaultItemsChanged: root.createModel()
|
||||||
|
|
||||||
Component.onCompleted: urlChooser.createModel()
|
Component.onCompleted: root.createModel()
|
||||||
|
|
||||||
function indexOf(model, criteria) {
|
function indexOf(model, criteria) {
|
||||||
for (var i = 0; i < model.count; ++i) {
|
for (var i = 0; i < model.count; ++i) {
|
||||||
@@ -305,16 +318,16 @@ Row {
|
|||||||
function onStateChanged(state) {
|
function onStateChanged(state) {
|
||||||
// update currentIndex when the popup opens to override the default behavior in super classes
|
// update currentIndex when the popup opens to override the default behavior in super classes
|
||||||
// that selects currentIndex based on values in the combo box.
|
// that selects currentIndex based on values in the combo box.
|
||||||
if (comboBox.popup.opened && !urlChooser.backendValue.isBound) {
|
if (comboBox.popup.opened && !root.backendValue.isBound) {
|
||||||
var index = urlChooser.indexOf(comboBox.items,
|
var index = root.indexOf(comboBox.items,
|
||||||
function(item) {
|
function(item) {
|
||||||
return item.fullPath === urlChooser.backendValue.value
|
return item.fullPath === root.backendValue.value
|
||||||
})
|
})
|
||||||
|
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
comboBox.currentIndex = index
|
comboBox.currentIndex = index
|
||||||
comboBox.hoverIndex = index
|
comboBox.hoverIndex = index
|
||||||
comboBox.editText = comboBox.items.get(index).name
|
comboBox.editText = comboBox.items.get(index).model.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -324,11 +337,11 @@ Row {
|
|||||||
|
|
||||||
IconIndicator {
|
IconIndicator {
|
||||||
icon: StudioTheme.Constants.addFile
|
icon: StudioTheme.Constants.addFile
|
||||||
iconColor: urlChooser.textColor
|
iconColor: root.textColor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
fileModel.openFileDialog()
|
fileModel.openFileDialog()
|
||||||
if (fileModel.fileName !== "")
|
if (fileModel.fileName !== "")
|
||||||
urlChooser.backendValue.value = fileModel.fileName
|
root.backendValue.value = fileModel.fileName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -50,16 +50,16 @@ Rectangle {
|
|||||||
id: checkIndicatorMouseArea
|
id: checkIndicatorMouseArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onPressed: {
|
onClicked: {
|
||||||
|
if (myControl.activeFocus)
|
||||||
|
myControl.focus = false
|
||||||
|
|
||||||
if (myPopup.opened) {
|
if (myPopup.opened) {
|
||||||
myPopup.close()
|
myPopup.close()
|
||||||
} else {
|
} else {
|
||||||
myPopup.open()
|
myPopup.open()
|
||||||
myPopup.forceActiveFocus()
|
myPopup.forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myControl.activeFocus)
|
|
||||||
myControl.focus = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -65,6 +65,11 @@ T.ComboBox {
|
|||||||
comboBoxPopup.close()
|
comboBoxPopup.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (myComboBox.activeFocus)
|
||||||
|
comboBoxInput.preFocusText = myComboBox.editText
|
||||||
|
}
|
||||||
|
|
||||||
ActionIndicator {
|
ActionIndicator {
|
||||||
id: actionIndicator
|
id: actionIndicator
|
||||||
myControl: myComboBox
|
myControl: myComboBox
|
||||||
@@ -76,19 +81,22 @@ T.ComboBox {
|
|||||||
|
|
||||||
contentItem: ComboBoxInput {
|
contentItem: ComboBoxInput {
|
||||||
id: comboBoxInput
|
id: comboBoxInput
|
||||||
|
|
||||||
|
property string preFocusText: ""
|
||||||
|
|
||||||
myControl: myComboBox
|
myControl: myComboBox
|
||||||
text: myComboBox.editText
|
text: myComboBox.editText
|
||||||
|
|
||||||
onEditingFinished: {
|
onEditingFinished: {
|
||||||
comboBoxInput.deselect()
|
comboBoxInput.deselect()
|
||||||
comboBoxInput.focus = false
|
comboBoxInput.focus = false
|
||||||
|
myComboBox.focus = false
|
||||||
|
|
||||||
// Only trigger the signal, if the value was modified
|
// Only trigger the signal, if the value was modified
|
||||||
if (myComboBox.dirty) {
|
if (myComboBox.dirty) {
|
||||||
myTimer.stop()
|
myTimer.stop()
|
||||||
myComboBox.dirty = false
|
myComboBox.dirty = false
|
||||||
myComboBox.compressedActivated(myComboBox.find(myComboBox.editText),
|
myComboBox.accepted()
|
||||||
ComboBox.ActivatedReason.EditingFinished)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onTextEdited: myComboBox.dirty = true
|
onTextEdited: myComboBox.dirty = true
|
||||||
@@ -276,7 +284,7 @@ T.ComboBox {
|
|||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: comboBoxBackground
|
target: comboBoxBackground
|
||||||
color: StudioTheme.Values.themeControlBackgroundInteraction
|
color: StudioTheme.Values.themeControlBackgroundInteraction
|
||||||
border.color: StudioTheme.Values.themeControlOutline
|
border.color: StudioTheme.Values.themeControlOutlineInteraction
|
||||||
}
|
}
|
||||||
StateChangeScript {
|
StateChangeScript {
|
||||||
script: comboBoxPopup.close()
|
script: comboBoxPopup.close()
|
||||||
@@ -312,7 +320,10 @@ T.ComboBox {
|
|||||||
]
|
]
|
||||||
|
|
||||||
Keys.onPressed: function(event) {
|
Keys.onPressed: function(event) {
|
||||||
if (event.key === Qt.Key_Escape)
|
if (event.key === Qt.Key_Escape) {
|
||||||
|
myComboBox.editText = comboBoxInput.preFocusText
|
||||||
|
myComboBox.dirty = true
|
||||||
myComboBox.focus = false
|
myComboBox.focus = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -73,13 +73,13 @@ TextInput {
|
|||||||
acceptedButtons: Qt.LeftButton
|
acceptedButtons: Qt.LeftButton
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onPressed: function(mouse) {
|
onPressed: function(mouse) {
|
||||||
if (textInput.readOnly) {
|
if (!textInput.myControl.editable) {
|
||||||
if (myControl.popup.opened) {
|
if (myControl.popup.opened) {
|
||||||
myControl.popup.close()
|
myControl.popup.close()
|
||||||
myControl.focus = false
|
myControl.focus = false
|
||||||
} else {
|
} else {
|
||||||
myControl.forceActiveFocus()
|
|
||||||
myControl.popup.open()
|
myControl.popup.open()
|
||||||
|
myControl.forceActiveFocus()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
textInput.forceActiveFocus()
|
textInput.forceActiveFocus()
|
||||||
|
@@ -0,0 +1,752 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Quick 3D.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:GPL$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 or (at your option) any later version
|
||||||
|
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||||
|
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Templates as T
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
enum Interaction { None, TextEdit, Key }
|
||||||
|
|
||||||
|
property int currentInteraction: FilterComboBox.Interaction.None
|
||||||
|
|
||||||
|
property alias model: sortFilterModel.model
|
||||||
|
property alias items: sortFilterModel.items
|
||||||
|
property alias delegate: sortFilterModel.delegate
|
||||||
|
|
||||||
|
property alias font: textInput.font
|
||||||
|
|
||||||
|
// This indicates if the value was committed or the user is still editing
|
||||||
|
property bool editing: false
|
||||||
|
|
||||||
|
// This is the actual filter that is applied on the model
|
||||||
|
property string filter: ""
|
||||||
|
property bool filterActive: root.filter !== ""
|
||||||
|
|
||||||
|
// Accept arbitrary input or only items from the model
|
||||||
|
property bool allowUserInput: false
|
||||||
|
|
||||||
|
property alias editText: textInput.text
|
||||||
|
property int highlightedIndex: -1 // items index
|
||||||
|
property int currentIndex: -1 // items index
|
||||||
|
|
||||||
|
property string autocompleteString: ""
|
||||||
|
|
||||||
|
property bool __isCompleted: false
|
||||||
|
|
||||||
|
property alias actionIndicator: actionIndicator
|
||||||
|
|
||||||
|
// This property is used to indicate the global hover state
|
||||||
|
property bool hover: actionIndicator.hover || textInput.hover || checkIndicator.hover
|
||||||
|
property alias edit: textInput.edit
|
||||||
|
property alias open: popup.visible
|
||||||
|
|
||||||
|
property alias actionIndicatorVisible: actionIndicator.visible
|
||||||
|
property real __actionIndicatorWidth: StudioTheme.Values.actionIndicatorWidth
|
||||||
|
property real __actionIndicatorHeight: StudioTheme.Values.actionIndicatorHeight
|
||||||
|
|
||||||
|
property bool dirty: false // user modification flag
|
||||||
|
|
||||||
|
property bool escapePressed: false
|
||||||
|
|
||||||
|
signal accepted()
|
||||||
|
signal activated(int index)
|
||||||
|
signal compressedActivated(int index, int reason)
|
||||||
|
|
||||||
|
enum ActivatedReason { EditingFinished, Other }
|
||||||
|
|
||||||
|
property alias popup: popup
|
||||||
|
property alias popupScrollBar: popupScrollBar
|
||||||
|
property alias popupMouseArea: popupMouseArea
|
||||||
|
|
||||||
|
width: StudioTheme.Values.defaultControlWidth
|
||||||
|
height: StudioTheme.Values.defaultControlHeight
|
||||||
|
implicitHeight: StudioTheme.Values.defaultControlHeight
|
||||||
|
|
||||||
|
function selectItem(itemsIndex) {
|
||||||
|
textInput.text = sortFilterModel.items.get(itemsIndex).model.name
|
||||||
|
root.currentIndex = itemsIndex
|
||||||
|
root.finishEditing()
|
||||||
|
root.activated(itemsIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitValue() {
|
||||||
|
if (!root.allowUserInput) {
|
||||||
|
// If input isn't according to any item in the model, don't finish editing
|
||||||
|
if (root.highlightedIndex === -1)
|
||||||
|
return
|
||||||
|
|
||||||
|
root.selectItem(root.highlightedIndex)
|
||||||
|
} else {
|
||||||
|
root.currentIndex = -1
|
||||||
|
|
||||||
|
// Only trigger the signal, if the value was modified
|
||||||
|
if (root.dirty) {
|
||||||
|
myTimer.stop()
|
||||||
|
root.dirty = false
|
||||||
|
root.editText = root.editText.trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
root.finishEditing()
|
||||||
|
root.accepted()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishEditing() {
|
||||||
|
root.editing = false
|
||||||
|
root.filter = ""
|
||||||
|
root.autocompleteString = ""
|
||||||
|
textInput.focus = false // Remove focus from text field
|
||||||
|
popup.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
function increaseVisibleIndex() {
|
||||||
|
let numItems = sortFilterModel.visibleGroup.count
|
||||||
|
if (!numItems)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (root.highlightedIndex === -1) // Nothing is selected
|
||||||
|
root.setHighlightedIndexVisible(0)
|
||||||
|
else {
|
||||||
|
let currentVisibleIndex = sortFilterModel.items.get(root.highlightedIndex).visibleIndex
|
||||||
|
++currentVisibleIndex
|
||||||
|
|
||||||
|
if (currentVisibleIndex > numItems - 1)
|
||||||
|
currentVisibleIndex = 0
|
||||||
|
|
||||||
|
root.setHighlightedIndexVisible(currentVisibleIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function decreaseVisibleIndex() {
|
||||||
|
let numItems = sortFilterModel.visibleGroup.count
|
||||||
|
if (!numItems)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (root.highlightedIndex === -1) // Nothing is selected
|
||||||
|
root.setHighlightedIndexVisible(numItems - 1)
|
||||||
|
else {
|
||||||
|
let currentVisibleIndex = sortFilterModel.items.get(root.highlightedIndex).visibleIndex
|
||||||
|
--currentVisibleIndex
|
||||||
|
|
||||||
|
if (currentVisibleIndex < 0)
|
||||||
|
currentVisibleIndex = numItems - 1
|
||||||
|
|
||||||
|
root.setHighlightedIndexVisible(currentVisibleIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateHighlightedIndex() {
|
||||||
|
// Check if current index is still part of the filtered list, if not set it to 0
|
||||||
|
if (root.highlightedIndex !== -1 && !sortFilterModel.items.get(root.highlightedIndex).inVisible) {
|
||||||
|
root.setHighlightedIndexVisible(0)
|
||||||
|
} else {
|
||||||
|
// Needs to be set in order for ListView to keep its currenIndex up to date, so
|
||||||
|
// scroll position gets updated according to the higlighted item
|
||||||
|
root.setHighlightedIndexItems(root.highlightedIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setHighlightedIndexItems(itemsIndex) { // items group index
|
||||||
|
root.highlightedIndex = itemsIndex
|
||||||
|
|
||||||
|
if (itemsIndex === -1)
|
||||||
|
listView.currentIndex = -1
|
||||||
|
else
|
||||||
|
listView.currentIndex = sortFilterModel.items.get(itemsIndex).visibleIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
function setHighlightedIndexVisible(visibleIndex) { // visible group index
|
||||||
|
if (visibleIndex === -1)
|
||||||
|
root.highlightedIndex = -1
|
||||||
|
else
|
||||||
|
root.highlightedIndex = sortFilterModel.visibleGroup.get(visibleIndex).itemsIndex
|
||||||
|
|
||||||
|
listView.currentIndex = visibleIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateAutocomplete() {
|
||||||
|
if (root.highlightedIndex === -1)
|
||||||
|
root.autocompleteString = ""
|
||||||
|
else {
|
||||||
|
let suggestion = sortFilterModel.items.get(root.highlightedIndex).model.name
|
||||||
|
root.autocompleteString = suggestion.substring(textInput.text.length)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO is this already case insensitiv?!
|
||||||
|
function find(text) {
|
||||||
|
for (let i = 0; i < sortFilterModel.items.count; ++i)
|
||||||
|
if (sortFilterModel.items.get(i).model.name === text)
|
||||||
|
return i
|
||||||
|
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: myTimer
|
||||||
|
property int activatedIndex
|
||||||
|
repeat: false
|
||||||
|
running: false
|
||||||
|
interval: 100
|
||||||
|
onTriggered: root.compressedActivated(myTimer.activatedIndex,
|
||||||
|
ComboBox.ActivatedReason.Other)
|
||||||
|
}
|
||||||
|
|
||||||
|
onActivated: function(index) {
|
||||||
|
myTimer.activatedIndex = index
|
||||||
|
myTimer.restart()
|
||||||
|
}
|
||||||
|
|
||||||
|
onHighlightedIndexChanged: {
|
||||||
|
if (root.editing || (root.editText === "" && root.allowUserInput))
|
||||||
|
root.updateAutocomplete()
|
||||||
|
}
|
||||||
|
|
||||||
|
DelegateModel {
|
||||||
|
id: noMatchesModel
|
||||||
|
|
||||||
|
model: ListModel {
|
||||||
|
ListElement { name: "No matches" }
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: ItemDelegate {
|
||||||
|
id: noMatchesDelegate
|
||||||
|
width: popup.width - popup.leftPadding - popup.rightPadding
|
||||||
|
- (popupScrollBar.visible ? popupScrollBar.contentItem.implicitWidth + 2
|
||||||
|
: 0) // TODO Magic number
|
||||||
|
height: StudioTheme.Values.height - 2 * StudioTheme.Values.border
|
||||||
|
padding: 0
|
||||||
|
|
||||||
|
contentItem: Text {
|
||||||
|
leftPadding: StudioTheme.Values.inputHorizontalPadding
|
||||||
|
text: name
|
||||||
|
font.italic: true
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
elide: Text.ElideRight
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
width: noMatchesDelegate.width
|
||||||
|
height: noMatchesDelegate.height
|
||||||
|
color: "transparent"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SortFilterModel {
|
||||||
|
id: sortFilterModel
|
||||||
|
|
||||||
|
filterAcceptsItem: function(item) {
|
||||||
|
return item.name.toLowerCase().startsWith(root.filter.toLowerCase())
|
||||||
|
}
|
||||||
|
|
||||||
|
lessThan: function(left, right) {
|
||||||
|
if (left.group === right.group) {
|
||||||
|
return left.name.toLowerCase().localeCompare(right.name.toLowerCase())
|
||||||
|
}
|
||||||
|
|
||||||
|
return left.group - right.group
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: ItemDelegate {
|
||||||
|
id: delegateRoot
|
||||||
|
width: popup.width - popup.leftPadding - popup.rightPadding
|
||||||
|
- (popupScrollBar.visible ? popupScrollBar.contentItem.implicitWidth + 2
|
||||||
|
: 0) // TODO Magic number
|
||||||
|
height: StudioTheme.Values.height - 2 * StudioTheme.Values.border
|
||||||
|
padding: 0
|
||||||
|
hoverEnabled: true
|
||||||
|
highlighted: root.highlightedIndex === delegateRoot.DelegateModel.itemsIndex
|
||||||
|
|
||||||
|
onHoveredChanged: {
|
||||||
|
if (delegateRoot.hovered && !popupMouseArea.active)
|
||||||
|
root.setHighlightedIndexItems(delegateRoot.DelegateModel.itemsIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: root.selectItem(delegateRoot.DelegateModel.itemsIndex)
|
||||||
|
|
||||||
|
indicator: Item {
|
||||||
|
id: itemDelegateIconArea
|
||||||
|
width: delegateRoot.height
|
||||||
|
height: delegateRoot.height
|
||||||
|
|
||||||
|
T.Label {
|
||||||
|
id: itemDelegateIcon
|
||||||
|
text: StudioTheme.Constants.tickIcon
|
||||||
|
color: delegateRoot.highlighted ? StudioTheme.Values.themeTextSelectedTextColor
|
||||||
|
: StudioTheme.Values.themeTextColor
|
||||||
|
font.family: StudioTheme.Constants.iconFont.family
|
||||||
|
font.pixelSize: StudioTheme.Values.spinControlIconSizeMulti
|
||||||
|
visible: root.currentIndex === delegateRoot.DelegateModel.itemsIndex ? true
|
||||||
|
: false
|
||||||
|
anchors.fill: parent
|
||||||
|
renderType: Text.NativeRendering
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Text {
|
||||||
|
leftPadding: itemDelegateIconArea.width
|
||||||
|
text: name
|
||||||
|
color: delegateRoot.highlighted ? StudioTheme.Values.themeTextSelectedTextColor
|
||||||
|
: StudioTheme.Values.themeTextColor
|
||||||
|
font: textInput.font
|
||||||
|
elide: Text.ElideRight
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
width: delegateRoot.width
|
||||||
|
height: delegateRoot.height
|
||||||
|
color: delegateRoot.highlighted ? StudioTheme.Values.themeInteraction
|
||||||
|
: "transparent"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onUpdated: {
|
||||||
|
if (!root.__isCompleted)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (sortFilterModel.count === 0)
|
||||||
|
root.setHighlightedIndexVisible(-1)
|
||||||
|
else {
|
||||||
|
if (root.highlightedIndex === -1 && !root.allowUserInput)
|
||||||
|
root.setHighlightedIndexVisible(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
ActionIndicator {
|
||||||
|
id: actionIndicator
|
||||||
|
myControl: root
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
width: actionIndicator.visible ? root.__actionIndicatorWidth : 0
|
||||||
|
height: actionIndicator.visible ? root.__actionIndicatorHeight : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
TextInput {
|
||||||
|
id: textInput
|
||||||
|
|
||||||
|
property bool hover: textInputMouseArea.containsMouse && textInput.enabled
|
||||||
|
property bool edit: textInput.activeFocus
|
||||||
|
property string preFocusText: ""
|
||||||
|
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
z: 2
|
||||||
|
width: root.width - actionIndicator.width
|
||||||
|
height: root.height
|
||||||
|
leftPadding: StudioTheme.Values.inputHorizontalPadding
|
||||||
|
rightPadding: StudioTheme.Values.inputHorizontalPadding + checkIndicator.width
|
||||||
|
+ StudioTheme.Values.border
|
||||||
|
horizontalAlignment: Qt.AlignLeft
|
||||||
|
verticalAlignment: Qt.AlignVCenter
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
selectionColor: StudioTheme.Values.themeTextSelectionColor
|
||||||
|
selectedTextColor: StudioTheme.Values.themeTextSelectedTextColor
|
||||||
|
selectByMouse: true
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: textInputBackground
|
||||||
|
z: -1
|
||||||
|
width: textInput.width
|
||||||
|
height: textInput.height
|
||||||
|
color: StudioTheme.Values.themeControlBackground
|
||||||
|
border.color: StudioTheme.Values.themeControlOutline
|
||||||
|
border.width: StudioTheme.Values.border
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: textInputMouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: true
|
||||||
|
hoverEnabled: true
|
||||||
|
propagateComposedEvents: true
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onPressed: function(mouse) {
|
||||||
|
textInput.forceActiveFocus()
|
||||||
|
mouse.accepted = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop scrollable views from scrolling while ComboBox is in edit mode and the mouse
|
||||||
|
// pointer is on top of it. We might add wheel selection in the future.
|
||||||
|
onWheel: function(wheel) {
|
||||||
|
wheel.accepted = root.edit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onEditingFinished: {
|
||||||
|
if (root.escapePressed) {
|
||||||
|
root.escapePressed = false
|
||||||
|
root.editText = textInput.preFocusText
|
||||||
|
} else {
|
||||||
|
if (root.currentInteraction === FilterComboBox.Interaction.TextEdit) {
|
||||||
|
if (root.dirty)
|
||||||
|
root.submitValue()
|
||||||
|
} else if (root.currentInteraction === FilterComboBox.Interaction.Key) {
|
||||||
|
root.selectItem(root.highlightedIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sortFilterModel.update()
|
||||||
|
}
|
||||||
|
|
||||||
|
onTextEdited: {
|
||||||
|
root.currentInteraction = FilterComboBox.Interaction.TextEdit
|
||||||
|
root.editing = true
|
||||||
|
popupMouseArea.active = true
|
||||||
|
root.dirty = true
|
||||||
|
|
||||||
|
if (textInput.text !== "")
|
||||||
|
root.filter = textInput.text
|
||||||
|
else {
|
||||||
|
root.filter = ""
|
||||||
|
root.autocompleteString = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!popup.visible)
|
||||||
|
popup.open()
|
||||||
|
|
||||||
|
sortFilterModel.update()
|
||||||
|
|
||||||
|
if (!root.allowUserInput)
|
||||||
|
root.updateHighlightedIndex()
|
||||||
|
else
|
||||||
|
root.setHighlightedIndexVisible(-1)
|
||||||
|
|
||||||
|
root.updateAutocomplete()
|
||||||
|
}
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (textInput.activeFocus) {
|
||||||
|
popup.open()
|
||||||
|
textInput.preFocusText = textInput.text
|
||||||
|
} else
|
||||||
|
popup.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "default"
|
||||||
|
when: root.enabled && !textInput.edit && !root.hover && !root.open
|
||||||
|
PropertyChanges {
|
||||||
|
target: textInputBackground
|
||||||
|
color: StudioTheme.Values.themeControlBackground
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: textInputMouseArea
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "globalHover"
|
||||||
|
when: root.hover && !textInput.hover && !textInput.edit && !root.open
|
||||||
|
PropertyChanges {
|
||||||
|
target: textInputBackground
|
||||||
|
color: StudioTheme.Values.themeControlBackgroundGlobalHover
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "hover"
|
||||||
|
when: textInput.hover && root.hover && !textInput.edit
|
||||||
|
PropertyChanges {
|
||||||
|
target: textInputBackground
|
||||||
|
color: StudioTheme.Values.themeControlBackgroundHover
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "edit"
|
||||||
|
when: root.edit
|
||||||
|
PropertyChanges {
|
||||||
|
target: textInputBackground
|
||||||
|
color: StudioTheme.Values.themeControlBackgroundInteraction
|
||||||
|
border.color: StudioTheme.Values.themeControlOutlineInteraction
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: textInputMouseArea
|
||||||
|
cursorShape: Qt.IBeamCursor
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "disable"
|
||||||
|
when: !root.enabled
|
||||||
|
PropertyChanges {
|
||||||
|
target: textInputBackground
|
||||||
|
color: StudioTheme.Values.themeControlBackgroundDisabled
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: textInput
|
||||||
|
color: StudioTheme.Values.themeTextColorDisabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
Text {
|
||||||
|
visible: root.autocompleteString !== ""
|
||||||
|
text: root.autocompleteString
|
||||||
|
x: textInput.leftPadding + textMetrics.advanceWidth
|
||||||
|
y: (textInput.height - Math.ceil(textMetrics.height)) / 2
|
||||||
|
color: "gray" // TODO proper color value
|
||||||
|
font: textInput.font
|
||||||
|
renderType: textInput.renderType
|
||||||
|
}
|
||||||
|
|
||||||
|
TextMetrics {
|
||||||
|
id: textMetrics
|
||||||
|
font: textInput.font
|
||||||
|
text: textInput.text
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: checkIndicator
|
||||||
|
|
||||||
|
property bool hover: checkIndicatorMouseArea.containsMouse && checkIndicator.enabled
|
||||||
|
property bool pressed: checkIndicatorMouseArea.containsPress
|
||||||
|
property bool checked: popup.visible
|
||||||
|
|
||||||
|
x: textInput.width - checkIndicator.width - StudioTheme.Values.border
|
||||||
|
y: StudioTheme.Values.border
|
||||||
|
width: StudioTheme.Values.height - StudioTheme.Values.border
|
||||||
|
height: textInput.height - (StudioTheme.Values.border * 2)
|
||||||
|
color: StudioTheme.Values.themeControlBackground
|
||||||
|
border.width: 0
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: checkIndicatorMouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onClicked: {
|
||||||
|
if (popup.visible)
|
||||||
|
popup.close()
|
||||||
|
else
|
||||||
|
popup.open()
|
||||||
|
|
||||||
|
if (!textInput.activeFocus) {
|
||||||
|
textInput.forceActiveFocus()
|
||||||
|
textInput.selectAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
T.Label {
|
||||||
|
id: checkIndicatorIcon
|
||||||
|
anchors.fill: parent
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
text: StudioTheme.Constants.upDownSquare2
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
font.pixelSize: StudioTheme.Values.sliderControlSizeMulti
|
||||||
|
font.family: StudioTheme.Constants.iconFont.family
|
||||||
|
}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "default"
|
||||||
|
when: root.enabled && checkIndicator.enabled && !root.edit
|
||||||
|
&& !checkIndicator.hover && !root.hover
|
||||||
|
&& !checkIndicator.checked
|
||||||
|
PropertyChanges {
|
||||||
|
target: checkIndicator
|
||||||
|
color: StudioTheme.Values.themeControlBackground
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "globalHover"
|
||||||
|
when: root.enabled && checkIndicator.enabled
|
||||||
|
&& !checkIndicator.hover && root.hover && !root.edit
|
||||||
|
&& !checkIndicator.checked
|
||||||
|
PropertyChanges {
|
||||||
|
target: checkIndicator
|
||||||
|
color: StudioTheme.Values.themeControlBackgroundGlobalHover
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "hover"
|
||||||
|
when: root.enabled && checkIndicator.enabled
|
||||||
|
&& checkIndicator.hover && root.hover && !checkIndicator.pressed
|
||||||
|
&& !checkIndicator.checked
|
||||||
|
PropertyChanges {
|
||||||
|
target: checkIndicator
|
||||||
|
color: StudioTheme.Values.themeControlBackgroundHover
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "check"
|
||||||
|
when: checkIndicator.checked
|
||||||
|
PropertyChanges {
|
||||||
|
target: checkIndicatorIcon
|
||||||
|
color: StudioTheme.Values.themeIconColor
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: checkIndicator
|
||||||
|
color: StudioTheme.Values.themeInteraction
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "press"
|
||||||
|
when: root.enabled && checkIndicator.enabled
|
||||||
|
&& checkIndicator.pressed
|
||||||
|
PropertyChanges {
|
||||||
|
target: checkIndicatorIcon
|
||||||
|
color: StudioTheme.Values.themeIconColor
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: checkIndicator
|
||||||
|
color: StudioTheme.Values.themeInteraction
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "disable"
|
||||||
|
when: !root.enabled
|
||||||
|
PropertyChanges {
|
||||||
|
target: checkIndicator
|
||||||
|
color: StudioTheme.Values.themeControlBackgroundDisabled
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: checkIndicatorIcon
|
||||||
|
color: StudioTheme.Values.themeTextColorDisabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
T.Popup {
|
||||||
|
id: popup
|
||||||
|
x: textInput.x + StudioTheme.Values.border
|
||||||
|
y: textInput.height
|
||||||
|
width: textInput.width - (StudioTheme.Values.border * 2)
|
||||||
|
height: Math.min(popup.contentItem.implicitHeight + popup.topPadding + popup.bottomPadding,
|
||||||
|
root.Window.height - popup.topMargin - popup.bottomMargin,
|
||||||
|
StudioTheme.Values.maxComboBoxPopupHeight)
|
||||||
|
padding: StudioTheme.Values.border
|
||||||
|
margins: 0 // If not defined margin will be -1
|
||||||
|
closePolicy: T.Popup.NoAutoClose
|
||||||
|
|
||||||
|
contentItem: ListView {
|
||||||
|
id: listView
|
||||||
|
clip: true
|
||||||
|
implicitHeight: listView.contentHeight
|
||||||
|
highlightMoveVelocity: -1
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
flickDeceleration: 10000
|
||||||
|
|
||||||
|
model: {
|
||||||
|
if (popup.visible)
|
||||||
|
return sortFilterModel.count ? sortFilterModel : noMatchesModel
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollBar.vertical: ScrollBar {
|
||||||
|
id: popupScrollBar
|
||||||
|
visible: listView.height < listView.contentHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: StudioTheme.Values.themePopupBackground
|
||||||
|
border.width: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
onOpened: {
|
||||||
|
// Reset the highlightedIndex of ListView as binding with condition didn't work
|
||||||
|
if (root.highlightedIndex !== -1)
|
||||||
|
root.setHighlightedIndexItems(root.highlightedIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
onAboutToShow: {
|
||||||
|
// Select first item in list
|
||||||
|
if (root.highlightedIndex === -1 && sortFilterModel.count && !root.allowUserInput)
|
||||||
|
root.setHighlightedIndexVisible(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
// This is MouseArea is intended to block the hovered property of an ItemDelegate
|
||||||
|
// when the ListView changes due to Key interaction.
|
||||||
|
|
||||||
|
id: popupMouseArea
|
||||||
|
property bool active: true
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: popup.visible && popupMouseArea.active
|
||||||
|
hoverEnabled: true
|
||||||
|
onPositionChanged: { popupMouseArea.active = false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onDownPressed: {
|
||||||
|
if (!sortFilterModel.visibleGroup.count)
|
||||||
|
return
|
||||||
|
|
||||||
|
root.currentInteraction = FilterComboBox.Interaction.Key
|
||||||
|
root.increaseVisibleIndex()
|
||||||
|
|
||||||
|
popupMouseArea.active = true
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onUpPressed: {
|
||||||
|
if (!sortFilterModel.visibleGroup.count)
|
||||||
|
return
|
||||||
|
|
||||||
|
root.currentInteraction = FilterComboBox.Interaction.Key
|
||||||
|
root.decreaseVisibleIndex()
|
||||||
|
|
||||||
|
popupMouseArea.active = true
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onEscapePressed: {
|
||||||
|
root.escapePressed = true
|
||||||
|
root.finishEditing()
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
let index = root.find(root.editText)
|
||||||
|
root.currentIndex = index
|
||||||
|
root.highlightedIndex = index // TODO might not be intended
|
||||||
|
|
||||||
|
root.__isCompleted = true
|
||||||
|
}
|
||||||
|
}
|
@@ -79,6 +79,8 @@ T.SpinBox {
|
|||||||
|
|
||||||
property alias compressedValueTimer: myTimer
|
property alias compressedValueTimer: myTimer
|
||||||
|
|
||||||
|
property string preFocusText: ""
|
||||||
|
|
||||||
signal realValueModified
|
signal realValueModified
|
||||||
signal compressedRealValueModified
|
signal compressedRealValueModified
|
||||||
signal dragStarted
|
signal dragStarted
|
||||||
@@ -162,6 +164,8 @@ T.SpinBox {
|
|||||||
validator: doubleValidator
|
validator: doubleValidator
|
||||||
|
|
||||||
function handleEditingFinished() {
|
function handleEditingFinished() {
|
||||||
|
mySpinBox.focus = false
|
||||||
|
|
||||||
// Keep the dirty state before calling setValueFromInput(),
|
// Keep the dirty state before calling setValueFromInput(),
|
||||||
// it will be set to false (cleared) internally
|
// it will be set to false (cleared) internally
|
||||||
var valueModified = mySpinBox.dirty
|
var valueModified = mySpinBox.dirty
|
||||||
@@ -174,7 +178,7 @@ T.SpinBox {
|
|||||||
mySpinBox.compressedRealValueModified()
|
mySpinBox.compressedRealValueModified()
|
||||||
}
|
}
|
||||||
|
|
||||||
onEditingFinished: handleEditingFinished()
|
onEditingFinished: spinBoxInput.handleEditingFinished()
|
||||||
onTextEdited: mySpinBox.dirty = true
|
onTextEdited: mySpinBox.dirty = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,7 +285,7 @@ T.SpinBox {
|
|||||||
id: myTimer
|
id: myTimer
|
||||||
repeat: false
|
repeat: false
|
||||||
running: false
|
running: false
|
||||||
interval: 200
|
interval: 400
|
||||||
onTriggered: mySpinBox.compressedRealValueModified()
|
onTriggered: mySpinBox.compressedRealValueModified()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,8 +310,10 @@ T.SpinBox {
|
|||||||
}
|
}
|
||||||
onDisplayTextChanged: spinBoxInput.text = mySpinBox.displayText
|
onDisplayTextChanged: spinBoxInput.text = mySpinBox.displayText
|
||||||
onActiveFocusChanged: {
|
onActiveFocusChanged: {
|
||||||
if (mySpinBox.activeFocus) // QTBUG-75862 && mySpinBox.focusReason === Qt.TabFocusReason)
|
if (mySpinBox.activeFocus) { // QTBUG-75862 && mySpinBox.focusReason === Qt.TabFocusReason)
|
||||||
|
mySpinBox.preFocusText = spinBoxInput.text
|
||||||
spinBoxInput.selectAll()
|
spinBoxInput.selectAll()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys.onPressed: function(event) {
|
Keys.onPressed: function(event) {
|
||||||
@@ -333,8 +339,11 @@ T.SpinBox {
|
|||||||
mySpinBox.realStepSize = currStepSize
|
mySpinBox.realStepSize = currStepSize
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.key === Qt.Key_Escape)
|
if (event.key === Qt.Key_Escape) {
|
||||||
mySpinBox.focus = false
|
spinBoxInput.text = mySpinBox.preFocusText
|
||||||
|
mySpinBox.dirty = true
|
||||||
|
spinBoxInput.handleEditingFinished()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function clamp(v, lo, hi) {
|
function clamp(v, lo, hi) {
|
||||||
|
@@ -0,0 +1,86 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Quick 3D.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:GPL$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 or (at your option) any later version
|
||||||
|
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||||
|
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQml.Models
|
||||||
|
|
||||||
|
DelegateModel {
|
||||||
|
id: delegateModel
|
||||||
|
|
||||||
|
property var visibleGroup: visibleItems
|
||||||
|
|
||||||
|
property var lessThan: function(left, right) { return true }
|
||||||
|
property var filterAcceptsItem: function(item) { return true }
|
||||||
|
|
||||||
|
signal updated()
|
||||||
|
|
||||||
|
function update() {
|
||||||
|
if (delegateModel.items.count > 0) {
|
||||||
|
delegateModel.items.setGroups(0, delegateModel.items.count, "items")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter items
|
||||||
|
var visible = []
|
||||||
|
for (var i = 0; i < delegateModel.items.count; ++i) {
|
||||||
|
var item = delegateModel.items.get(i)
|
||||||
|
if (delegateModel.filterAcceptsItem(item.model)) {
|
||||||
|
visible.push(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the list of visible items
|
||||||
|
visible.sort(function(a, b) {
|
||||||
|
return delegateModel.lessThan(a.model, b.model);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add all items to the visible group
|
||||||
|
for (i = 0; i < visible.length; ++i) {
|
||||||
|
item = visible[i]
|
||||||
|
item.inVisible = true
|
||||||
|
if (item.visibleIndex !== i) {
|
||||||
|
visibleItems.move(item.visibleIndex, i, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delegateModel.updated()
|
||||||
|
}
|
||||||
|
|
||||||
|
items.onChanged: delegateModel.update()
|
||||||
|
onLessThanChanged: delegateModel.update()
|
||||||
|
onFilterAcceptsItemChanged: delegateModel.update()
|
||||||
|
|
||||||
|
groups: DelegateModelGroup {
|
||||||
|
id: visibleItems
|
||||||
|
|
||||||
|
name: "visible"
|
||||||
|
includeByDefault: false
|
||||||
|
}
|
||||||
|
|
||||||
|
filterOnGroup: "visible"
|
||||||
|
}
|
@@ -28,15 +28,15 @@ import QtQuick.Templates 2.15 as T
|
|||||||
import StudioTheme 1.0 as StudioTheme
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
|
||||||
T.TextField {
|
T.TextField {
|
||||||
id: myTextField
|
id: root
|
||||||
|
|
||||||
property alias actionIndicator: actionIndicator
|
property alias actionIndicator: actionIndicator
|
||||||
property alias translationIndicator: translationIndicator
|
property alias translationIndicator: translationIndicator
|
||||||
|
|
||||||
// This property is used to indicate the global hover state
|
// This property is used to indicate the global hover state
|
||||||
property bool hover: (actionIndicator.hover || mouseArea.containsMouse
|
property bool hover: (actionIndicator.hover || mouseArea.containsMouse
|
||||||
|| translationIndicator.hover) && myTextField.enabled
|
|| translationIndicator.hover) && root.enabled
|
||||||
property bool edit: myTextField.activeFocus
|
property bool edit: root.activeFocus
|
||||||
|
|
||||||
property alias actionIndicatorVisible: actionIndicator.visible
|
property alias actionIndicatorVisible: actionIndicator.visible
|
||||||
property real __actionIndicatorWidth: StudioTheme.Values.actionIndicatorWidth
|
property real __actionIndicatorWidth: StudioTheme.Values.actionIndicatorWidth
|
||||||
@@ -46,6 +46,8 @@ T.TextField {
|
|||||||
property real __translationIndicatorWidth: StudioTheme.Values.translationIndicatorWidth
|
property real __translationIndicatorWidth: StudioTheme.Values.translationIndicatorWidth
|
||||||
property real __translationIndicatorHeight: StudioTheme.Values.translationIndicatorHeight
|
property real __translationIndicatorHeight: StudioTheme.Values.translationIndicatorHeight
|
||||||
|
|
||||||
|
property string preFocusText: ""
|
||||||
|
|
||||||
horizontalAlignment: Qt.AlignLeft
|
horizontalAlignment: Qt.AlignLeft
|
||||||
verticalAlignment: Qt.AlignVCenter
|
verticalAlignment: Qt.AlignVCenter
|
||||||
|
|
||||||
@@ -78,7 +80,7 @@ T.TextField {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onPressed: function(mouse) {
|
onPressed: function(mouse) {
|
||||||
if (mouse.button === Qt.RightButton)
|
if (mouse.button === Qt.RightButton)
|
||||||
contextMenu.popup(myTextField)
|
contextMenu.popup(root)
|
||||||
|
|
||||||
mouse.accepted = false
|
mouse.accepted = false
|
||||||
}
|
}
|
||||||
@@ -86,43 +88,50 @@ T.TextField {
|
|||||||
|
|
||||||
onPersistentSelectionChanged: {
|
onPersistentSelectionChanged: {
|
||||||
if (!persistentSelection)
|
if (!persistentSelection)
|
||||||
myTextField.deselect()
|
root.deselect()
|
||||||
}
|
}
|
||||||
|
|
||||||
ContextMenu {
|
ContextMenu {
|
||||||
id: contextMenu
|
id: contextMenu
|
||||||
myTextEdit: myTextField
|
myTextEdit: root
|
||||||
|
}
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (root.activeFocus)
|
||||||
|
root.preFocusText = root.text
|
||||||
}
|
}
|
||||||
|
|
||||||
onEditChanged: {
|
onEditChanged: {
|
||||||
if (myTextField.edit)
|
if (root.edit)
|
||||||
contextMenu.close()
|
contextMenu.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onEditingFinished: root.focus = false
|
||||||
|
|
||||||
ActionIndicator {
|
ActionIndicator {
|
||||||
id: actionIndicator
|
id: actionIndicator
|
||||||
myControl: myTextField
|
myControl: root
|
||||||
x: 0
|
x: 0
|
||||||
y: 0
|
y: 0
|
||||||
width: actionIndicator.visible ? myTextField.__actionIndicatorWidth : 0
|
width: actionIndicator.visible ? root.__actionIndicatorWidth : 0
|
||||||
height: actionIndicator.visible ? myTextField.__actionIndicatorHeight : 0
|
height: actionIndicator.visible ? root.__actionIndicatorHeight : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: placeholder
|
id: placeholder
|
||||||
x: myTextField.leftPadding
|
x: root.leftPadding
|
||||||
y: myTextField.topPadding
|
y: root.topPadding
|
||||||
width: myTextField.width - (myTextField.leftPadding + myTextField.rightPadding)
|
width: root.width - (root.leftPadding + root.rightPadding)
|
||||||
height: myTextField.height - (myTextField.topPadding + myTextField.bottomPadding)
|
height: root.height - (root.topPadding + root.bottomPadding)
|
||||||
|
|
||||||
text: myTextField.placeholderText
|
text: root.placeholderText
|
||||||
font: myTextField.font
|
font: root.font
|
||||||
color: myTextField.placeholderTextColor
|
color: root.placeholderTextColor
|
||||||
verticalAlignment: myTextField.verticalAlignment
|
verticalAlignment: root.verticalAlignment
|
||||||
visible: !myTextField.length && !myTextField.preeditText
|
visible: !root.length && !root.preeditText
|
||||||
&& (!myTextField.activeFocus || myTextField.horizontalAlignment !== Qt.AlignHCenter)
|
&& (!root.activeFocus || root.horizontalAlignment !== Qt.AlignHCenter)
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
renderType: myTextField.renderType
|
renderType: root.renderType
|
||||||
}
|
}
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
@@ -131,14 +140,14 @@ T.TextField {
|
|||||||
border.color: StudioTheme.Values.themeControlOutline
|
border.color: StudioTheme.Values.themeControlOutline
|
||||||
border.width: StudioTheme.Values.border
|
border.width: StudioTheme.Values.border
|
||||||
x: actionIndicator.width
|
x: actionIndicator.width
|
||||||
width: myTextField.width - actionIndicator.width
|
width: root.width - actionIndicator.width
|
||||||
height: myTextField.height
|
height: root.height
|
||||||
}
|
}
|
||||||
|
|
||||||
TranslationIndicator {
|
TranslationIndicator {
|
||||||
id: translationIndicator
|
id: translationIndicator
|
||||||
myControl: myTextField
|
myControl: root
|
||||||
x: myTextField.width - translationIndicator.width
|
x: root.width - translationIndicator.width
|
||||||
width: translationIndicator.visible ? __translationIndicatorWidth : 0
|
width: translationIndicator.visible ? __translationIndicatorWidth : 0
|
||||||
height: translationIndicator.visible ? __translationIndicatorHeight : 0
|
height: translationIndicator.visible ? __translationIndicatorHeight : 0
|
||||||
}
|
}
|
||||||
@@ -146,15 +155,14 @@ T.TextField {
|
|||||||
states: [
|
states: [
|
||||||
State {
|
State {
|
||||||
name: "default"
|
name: "default"
|
||||||
when: myTextField.enabled && !myTextField.hover
|
when: root.enabled && !root.hover && !root.edit
|
||||||
&& !myTextField.edit
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: textFieldBackground
|
target: textFieldBackground
|
||||||
color: StudioTheme.Values.themeControlBackground
|
color: StudioTheme.Values.themeControlBackground
|
||||||
border.color: StudioTheme.Values.themeControlOutline
|
border.color: StudioTheme.Values.themeControlOutline
|
||||||
}
|
}
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: myTextField
|
target: root
|
||||||
color: StudioTheme.Values.themeTextColor
|
color: StudioTheme.Values.themeTextColor
|
||||||
placeholderTextColor: StudioTheme.Values.themePlaceholderTextColor
|
placeholderTextColor: StudioTheme.Values.themePlaceholderTextColor
|
||||||
}
|
}
|
||||||
@@ -165,15 +173,15 @@ T.TextField {
|
|||||||
},
|
},
|
||||||
State {
|
State {
|
||||||
name: "globalHover"
|
name: "globalHover"
|
||||||
when: (actionIndicator.hover || translationIndicator.hover) && !myTextField.edit
|
when: (actionIndicator.hover || translationIndicator.hover) && !root.edit
|
||||||
&& myTextField.enabled
|
&& root.enabled
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: textFieldBackground
|
target: textFieldBackground
|
||||||
color: StudioTheme.Values.themeControlBackgroundGlobalHover
|
color: StudioTheme.Values.themeControlBackgroundGlobalHover
|
||||||
border.color: StudioTheme.Values.themeControlOutline
|
border.color: StudioTheme.Values.themeControlOutline
|
||||||
}
|
}
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: myTextField
|
target: root
|
||||||
color: StudioTheme.Values.themeTextColor
|
color: StudioTheme.Values.themeTextColor
|
||||||
placeholderTextColor: StudioTheme.Values.themePlaceholderTextColor
|
placeholderTextColor: StudioTheme.Values.themePlaceholderTextColor
|
||||||
}
|
}
|
||||||
@@ -181,28 +189,28 @@ T.TextField {
|
|||||||
State {
|
State {
|
||||||
name: "hover"
|
name: "hover"
|
||||||
when: mouseArea.containsMouse && !actionIndicator.hover && !translationIndicator.hover
|
when: mouseArea.containsMouse && !actionIndicator.hover && !translationIndicator.hover
|
||||||
&& !myTextField.edit && myTextField.enabled
|
&& !root.edit && root.enabled
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: textFieldBackground
|
target: textFieldBackground
|
||||||
color: StudioTheme.Values.themeControlBackgroundHover
|
color: StudioTheme.Values.themeControlBackgroundHover
|
||||||
border.color: StudioTheme.Values.themeControlOutline
|
border.color: StudioTheme.Values.themeControlOutline
|
||||||
}
|
}
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: myTextField
|
target: root
|
||||||
color: StudioTheme.Values.themeTextColor
|
color: StudioTheme.Values.themeTextColor
|
||||||
placeholderTextColor: StudioTheme.Values.themePlaceholderTextColor
|
placeholderTextColor: StudioTheme.Values.themePlaceholderTextColor
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
State {
|
State {
|
||||||
name: "edit"
|
name: "edit"
|
||||||
when: myTextField.edit
|
when: root.edit
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: textFieldBackground
|
target: textFieldBackground
|
||||||
color: StudioTheme.Values.themeControlBackgroundInteraction
|
color: StudioTheme.Values.themeControlBackgroundInteraction
|
||||||
border.color: StudioTheme.Values.themeControlOutlineInteraction
|
border.color: StudioTheme.Values.themeControlOutlineInteraction
|
||||||
}
|
}
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: myTextField
|
target: root
|
||||||
color: StudioTheme.Values.themeTextColor
|
color: StudioTheme.Values.themeTextColor
|
||||||
placeholderTextColor: StudioTheme.Values.themePlaceholderTextColorInteraction
|
placeholderTextColor: StudioTheme.Values.themePlaceholderTextColorInteraction
|
||||||
}
|
}
|
||||||
@@ -213,14 +221,14 @@ T.TextField {
|
|||||||
},
|
},
|
||||||
State {
|
State {
|
||||||
name: "disable"
|
name: "disable"
|
||||||
when: !myTextField.enabled
|
when: !root.enabled
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: textFieldBackground
|
target: textFieldBackground
|
||||||
color: StudioTheme.Values.themeControlBackgroundDisabled
|
color: StudioTheme.Values.themeControlBackgroundDisabled
|
||||||
border.color: StudioTheme.Values.themeControlOutlineDisabled
|
border.color: StudioTheme.Values.themeControlOutlineDisabled
|
||||||
}
|
}
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: myTextField
|
target: root
|
||||||
color: StudioTheme.Values.themeTextColorDisabled
|
color: StudioTheme.Values.themeTextColorDisabled
|
||||||
placeholderTextColor: StudioTheme.Values.themeTextColorDisabled
|
placeholderTextColor: StudioTheme.Values.themeTextColorDisabled
|
||||||
}
|
}
|
||||||
@@ -228,7 +236,9 @@ T.TextField {
|
|||||||
]
|
]
|
||||||
|
|
||||||
Keys.onPressed: function(event) {
|
Keys.onPressed: function(event) {
|
||||||
if (event.key === Qt.Key_Escape)
|
if (event.key === Qt.Key_Escape) {
|
||||||
myTextField.focus = false
|
root.text = root.preFocusText
|
||||||
|
root.focus = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@ CheckIndicator 1.0 CheckIndicator.qml
|
|||||||
ComboBox 1.0 ComboBox.qml
|
ComboBox 1.0 ComboBox.qml
|
||||||
ComboBoxInput 1.0 ComboBoxInput.qml
|
ComboBoxInput 1.0 ComboBoxInput.qml
|
||||||
ContextMenu 1.0 ContextMenu.qml
|
ContextMenu 1.0 ContextMenu.qml
|
||||||
|
FilterComboBox 1.0 FilterComboBox.qml
|
||||||
InfinityLoopIndicator 1.0 InfinityLoopIndicator.qml
|
InfinityLoopIndicator 1.0 InfinityLoopIndicator.qml
|
||||||
ItemDelegate 1.0 ItemDelegate.qml
|
ItemDelegate 1.0 ItemDelegate.qml
|
||||||
LinkIndicator2D 1.0 LinkIndicator2D.qml
|
LinkIndicator2D 1.0 LinkIndicator2D.qml
|
||||||
@@ -30,6 +31,7 @@ SectionLabel 1.0 SectionLabel.qml
|
|||||||
SectionLayout 1.0 SectionLayout.qml
|
SectionLayout 1.0 SectionLayout.qml
|
||||||
Slider 1.0 Slider.qml
|
Slider 1.0 Slider.qml
|
||||||
SliderPopup 1.0 SliderPopup.qml
|
SliderPopup 1.0 SliderPopup.qml
|
||||||
|
SortFilterModel 1.0 SortFilterModel.qml
|
||||||
SpinBox 1.0 SpinBox.qml
|
SpinBox 1.0 SpinBox.qml
|
||||||
SpinBoxIndicator 1.0 SpinBoxIndicator.qml
|
SpinBoxIndicator 1.0 SpinBoxIndicator.qml
|
||||||
SpinBoxInput 1.0 SpinBoxInput.qml
|
SpinBoxInput 1.0 SpinBoxInput.qml
|
||||||
|
@@ -406,11 +406,6 @@ QStringList lastSessionArgument()
|
|||||||
#ifdef ENABLE_CRASHPAD
|
#ifdef ENABLE_CRASHPAD
|
||||||
bool startCrashpad(const QString &libexecPath, bool crashReportingEnabled)
|
bool startCrashpad(const QString &libexecPath, bool crashReportingEnabled)
|
||||||
{
|
{
|
||||||
if (QSysInfo::currentCpuArchitecture() == "arm64") {
|
|
||||||
qDebug() << "The crashpad_handler binary does not work on arm64 properly. So it is disabled for now.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
using namespace crashpad;
|
using namespace crashpad;
|
||||||
|
|
||||||
// Cache directory that will store crashpad information and minidumps
|
// Cache directory that will store crashpad information and minidumps
|
||||||
|
@@ -702,7 +702,8 @@ void CMakeBuildSystem::updateFileSystemNodes()
|
|||||||
addCMakeLists(newRoot.get(), std::move(fileNodes));
|
addCMakeLists(newRoot.get(), std::move(fileNodes));
|
||||||
}
|
}
|
||||||
|
|
||||||
addFileSystemNodes(newRoot.get(), m_allFiles);
|
if (m_allFiles)
|
||||||
|
addFileSystemNodes(newRoot.get(), m_allFiles);
|
||||||
setRootProjectNode(std::move(newRoot));
|
setRootProjectNode(std::move(newRoot));
|
||||||
|
|
||||||
m_reader.resetData();
|
m_reader.resetData();
|
||||||
|
@@ -436,6 +436,13 @@ static bool hideAnalyzeMenu()
|
|||||||
.toBool();
|
.toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool hideDebugMenu()
|
||||||
|
{
|
||||||
|
return Core::ICore::settings()
|
||||||
|
->value(ProjectExplorer::Constants::SETTINGS_MENU_HIDE_DEBUG, false)
|
||||||
|
.toBool();
|
||||||
|
}
|
||||||
|
|
||||||
QAction *addAction(const QObject *parent, QMenu *menu, const QString &display, bool on,
|
QAction *addAction(const QObject *parent, QMenu *menu, const QString &display, bool on,
|
||||||
const std::function<void()> &onTriggered)
|
const std::function<void()> &onTriggered)
|
||||||
{
|
{
|
||||||
@@ -922,7 +929,9 @@ DebuggerPluginPrivate::DebuggerPluginPrivate(const QStringList &arguments)
|
|||||||
m_visibleStartAction.setAction(&m_startAction);
|
m_visibleStartAction.setAction(&m_startAction);
|
||||||
|
|
||||||
m_visibleStartAction.setObjectName("Debug"); // used for UI introduction
|
m_visibleStartAction.setObjectName("Debug"); // used for UI introduction
|
||||||
ModeManager::addAction(&m_visibleStartAction, /*priority*/ 90);
|
|
||||||
|
if (!hideDebugMenu())
|
||||||
|
ModeManager::addAction(&m_visibleStartAction, /*priority*/ 90);
|
||||||
|
|
||||||
m_undisturbableAction.setIcon(interruptIcon(false));
|
m_undisturbableAction.setIcon(interruptIcon(false));
|
||||||
m_undisturbableAction.setEnabled(false);
|
m_undisturbableAction.setEnabled(false);
|
||||||
|
@@ -95,6 +95,7 @@ IAssistProposal *LanguageClientQuickFixAssistProcessor::perform(const AssistInte
|
|||||||
handleCodeActionResponse(response);
|
handleCodeActionResponse(response);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m_client->addAssistProcessor(this);
|
||||||
m_client->requestCodeActions(request);
|
m_client->requestCodeActions(request);
|
||||||
m_currentRequest = request.id();
|
m_currentRequest = request.id();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@@ -280,10 +280,15 @@ void MacroManager::startMacro()
|
|||||||
foreach (IMacroHandler *handler, d->handlers)
|
foreach (IMacroHandler *handler, d->handlers)
|
||||||
handler->startRecording(d->currentMacro);
|
handler->startRecording(d->currentMacro);
|
||||||
|
|
||||||
QString endShortcut = Core::ActionManager::command(Constants::END_MACRO)->keySequence().toString();
|
const QString endShortcut = Core::ActionManager::command(Constants::END_MACRO)
|
||||||
QString executeShortcut = Core::ActionManager::command(Constants::EXECUTE_LAST_MACRO)->keySequence().toString();
|
->keySequence()
|
||||||
QString help = tr("Macro mode. Type \"%1\" to stop recording and \"%2\" to play the macro.")
|
.toString(QKeySequence::NativeText);
|
||||||
.arg(endShortcut).arg(executeShortcut);
|
const QString executeShortcut = Core::ActionManager::command(Constants::EXECUTE_LAST_MACRO)
|
||||||
|
->keySequence()
|
||||||
|
.toString(QKeySequence::NativeText);
|
||||||
|
const QString help
|
||||||
|
= tr("Macro mode. Type \"%1\" to stop recording and \"%2\" to play the macro.")
|
||||||
|
.arg(endShortcut, executeShortcut);
|
||||||
Core::EditorManager::showEditorStatusBar(Constants::M_STATUS_BUFFER, help,
|
Core::EditorManager::showEditorStatusBar(Constants::M_STATUS_BUFFER, help,
|
||||||
tr("Stop Recording Macro"),
|
tr("Stop Recording Macro"),
|
||||||
this, [this] { endMacro(); });
|
this, [this] { endMacro(); });
|
||||||
|
@@ -96,8 +96,10 @@ void MacroOptionsWidget::createTable()
|
|||||||
|
|
||||||
Core::Command *command =
|
Core::Command *command =
|
||||||
Core::ActionManager::command(base.withSuffix(macro->displayName()));
|
Core::ActionManager::command(base.withSuffix(macro->displayName()));
|
||||||
if (command && command->action())
|
if (command && command->action()) {
|
||||||
macroItem->setText(2, command->action()->shortcut().toString());
|
macroItem->setText(2,
|
||||||
|
command->action()->shortcut().toString(QKeySequence::NativeText));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1079,12 +1079,19 @@ Toolchains GccToolChainFactory::autoDetect(const ToolchainDetector &detector) co
|
|||||||
Toolchains GccToolChainFactory::detectForImport(const ToolChainDescription &tcd) const
|
Toolchains GccToolChainFactory::detectForImport(const ToolChainDescription &tcd) const
|
||||||
{
|
{
|
||||||
const QString fileName = tcd.compilerPath.completeBaseName();
|
const QString fileName = tcd.compilerPath.completeBaseName();
|
||||||
if ((tcd.language == Constants::C_LANGUAGE_ID && (fileName.startsWith("gcc")
|
const QString resolvedSymlinksFileName = tcd.compilerPath.resolveSymlinks().completeBaseName();
|
||||||
|| fileName.endsWith("gcc")
|
|
||||||
|| fileName == "cc"))
|
const bool isCCompiler = tcd.language == Constants::C_LANGUAGE_ID
|
||||||
|| (tcd.language == Constants::CXX_LANGUAGE_ID && (fileName.startsWith("g++")
|
&& (fileName.startsWith("gcc")
|
||||||
|| fileName.endsWith("g++")
|
|| fileName.endsWith("gcc")
|
||||||
|| fileName == "c++"))) {
|
|| (fileName == "cc" && !resolvedSymlinksFileName.contains("clang")));
|
||||||
|
|
||||||
|
const bool isCxxCompiler = tcd.language == Constants::CXX_LANGUAGE_ID
|
||||||
|
&& (fileName.startsWith("g++")
|
||||||
|
|| fileName.endsWith("g++")
|
||||||
|
|| (fileName == "c++" && !resolvedSymlinksFileName.contains("clang")));
|
||||||
|
|
||||||
|
if (isCCompiler || isCxxCompiler) {
|
||||||
return autoDetectToolChain(tcd, [](const ToolChain *tc) {
|
return autoDetectToolChain(tcd, [](const ToolChain *tc) {
|
||||||
return tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor;
|
return tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor;
|
||||||
});
|
});
|
||||||
@@ -1765,9 +1772,18 @@ Toolchains ClangToolChainFactory::autoDetect(const ToolchainDetector &detector)
|
|||||||
|
|
||||||
Toolchains ClangToolChainFactory::detectForImport(const ToolChainDescription &tcd) const
|
Toolchains ClangToolChainFactory::detectForImport(const ToolChainDescription &tcd) const
|
||||||
{
|
{
|
||||||
const QString fileName = tcd.compilerPath.toString();
|
const QString fileName = tcd.compilerPath.completeBaseName();
|
||||||
if ((tcd.language == Constants::C_LANGUAGE_ID && fileName.startsWith("clang") && !fileName.startsWith("clang++"))
|
const QString resolvedSymlinksFileName = tcd.compilerPath.resolveSymlinks().completeBaseName();
|
||||||
|| (tcd.language == Constants::CXX_LANGUAGE_ID && fileName.startsWith("clang++"))) {
|
|
||||||
|
const bool isCCompiler = tcd.language == Constants::C_LANGUAGE_ID
|
||||||
|
&& ((fileName.startsWith("clang") && !fileName.startsWith("clang++"))
|
||||||
|
|| (fileName == "cc" && resolvedSymlinksFileName.contains("clang")));
|
||||||
|
|
||||||
|
const bool isCxxCompiler = tcd.language == Constants::CXX_LANGUAGE_ID
|
||||||
|
&& (fileName.startsWith("clang++")
|
||||||
|
|| (fileName == "c++" && resolvedSymlinksFileName.contains("clang")));
|
||||||
|
|
||||||
|
if (isCCompiler || isCxxCompiler) {
|
||||||
return autoDetectToolChain(tcd);
|
return autoDetectToolChain(tcd);
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
@@ -2023,7 +2039,7 @@ Toolchains LinuxIccToolChainFactory::autoDetect(const ToolchainDetector &detecto
|
|||||||
|
|
||||||
Toolchains LinuxIccToolChainFactory::detectForImport(const ToolChainDescription &tcd) const
|
Toolchains LinuxIccToolChainFactory::detectForImport(const ToolChainDescription &tcd) const
|
||||||
{
|
{
|
||||||
const QString fileName = tcd.compilerPath.toString();
|
const QString fileName = tcd.compilerPath.completeBaseName();
|
||||||
if ((tcd.language == Constants::CXX_LANGUAGE_ID && fileName.startsWith("icpc")) ||
|
if ((tcd.language == Constants::CXX_LANGUAGE_ID && fileName.startsWith("icpc")) ||
|
||||||
(tcd.language == Constants::C_LANGUAGE_ID && fileName.startsWith("icc"))) {
|
(tcd.language == Constants::C_LANGUAGE_ID && fileName.startsWith("icc"))) {
|
||||||
return autoDetectToolChain(tcd);
|
return autoDetectToolChain(tcd);
|
||||||
|
@@ -1340,7 +1340,8 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
|
|||||||
dd->m_modeBarBuildAction->initialize(cmd->action());
|
dd->m_modeBarBuildAction->initialize(cmd->action());
|
||||||
dd->m_modeBarBuildAction->setAttribute(ProxyAction::UpdateText);
|
dd->m_modeBarBuildAction->setAttribute(ProxyAction::UpdateText);
|
||||||
dd->m_modeBarBuildAction->setAction(cmd->action());
|
dd->m_modeBarBuildAction->setAction(cmd->action());
|
||||||
ModeManager::addAction(dd->m_modeBarBuildAction, Constants::P_ACTION_BUILDPROJECT);
|
if (!hideBuildMenu())
|
||||||
|
ModeManager::addAction(dd->m_modeBarBuildAction, Constants::P_ACTION_BUILDPROJECT);
|
||||||
|
|
||||||
// build for run config
|
// build for run config
|
||||||
dd->m_buildForRunConfigAction = new ParameterAction(
|
dd->m_buildForRunConfigAction = new ParameterAction(
|
||||||
|
@@ -36,19 +36,24 @@
|
|||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
|
#include <utils/filesystemwatcher.h>
|
||||||
|
#include <utils/stylehelper.h>
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
|
#include <QElapsedTimer>
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
#include <QImageReader>
|
#include <QImageReader>
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
#include <QMessageBox>
|
||||||
#include <QMetaProperty>
|
#include <QMetaProperty>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QRawFont>
|
#include <QRawFont>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QCheckBox>
|
static Q_LOGGING_CATEGORY(assetsLibraryBenchmark, "qtc.assetsLibrary.setRoot", QtWarningMsg)
|
||||||
#include <utils/stylehelper.h>
|
|
||||||
#include <utils/filesystemwatcher.h>
|
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
@@ -298,6 +303,12 @@ void AssetsLibraryModel::refresh()
|
|||||||
|
|
||||||
void AssetsLibraryModel::setRootPath(const QString &path)
|
void AssetsLibraryModel::setRootPath(const QString &path)
|
||||||
{
|
{
|
||||||
|
QElapsedTimer time;
|
||||||
|
if (assetsLibraryBenchmark().isInfoEnabled())
|
||||||
|
time.start();
|
||||||
|
|
||||||
|
qCInfo(assetsLibraryBenchmark) << "start:" << time.elapsed();
|
||||||
|
|
||||||
static const QStringList ignoredTopLevelDirs {"imports", "asset_imports"};
|
static const QStringList ignoredTopLevelDirs {"imports", "asset_imports"};
|
||||||
|
|
||||||
m_fileSystemWatcher->clear();
|
m_fileSystemWatcher->clear();
|
||||||
@@ -345,6 +356,8 @@ void AssetsLibraryModel::setRootPath(const QString &path)
|
|||||||
return isEmpty;
|
return isEmpty;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
qCInfo(assetsLibraryBenchmark) << "directories parsed:" << time.elapsed();
|
||||||
|
|
||||||
if (m_assetsDir)
|
if (m_assetsDir)
|
||||||
delete m_assetsDir;
|
delete m_assetsDir;
|
||||||
|
|
||||||
@@ -360,6 +373,8 @@ void AssetsLibraryModel::setRootPath(const QString &path)
|
|||||||
|
|
||||||
m_assetsDir->setDirVisible(!noAssets); // if there are no assets, hide all empty asset folders
|
m_assetsDir->setDirVisible(!noAssets); // if there are no assets, hide all empty asset folders
|
||||||
endResetModel();
|
endResetModel();
|
||||||
|
|
||||||
|
qCInfo(assetsLibraryBenchmark) << "model reset:" << time.elapsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetsLibraryModel::setSearchText(const QString &searchText)
|
void AssetsLibraryModel::setSearchText(const QString &searchText)
|
||||||
|
@@ -87,7 +87,7 @@ bool AssetsLibraryWidget::eventFilter(QObject *obj, QEvent *event)
|
|||||||
auto drag = new QDrag(this);
|
auto drag = new QDrag(this);
|
||||||
drag->setPixmap(m_assetsIconProvider->requestPixmap(m_assetsToDrag[0], nullptr, {128, 128}));
|
drag->setPixmap(m_assetsIconProvider->requestPixmap(m_assetsToDrag[0], nullptr, {128, 128}));
|
||||||
QMimeData *mimeData = new QMimeData;
|
QMimeData *mimeData = new QMimeData;
|
||||||
mimeData->setData("application/vnd.bauhaus.libraryresource", m_assetsToDrag.join(',').toUtf8());
|
mimeData->setData(Constants::MIME_TYPE_ASSETS, m_assetsToDrag.join(',').toUtf8());
|
||||||
drag->setMimeData(mimeData);
|
drag->setMimeData(mimeData);
|
||||||
drag->exec();
|
drag->exec();
|
||||||
drag->deleteLater();
|
drag->deleteLater();
|
||||||
@@ -213,26 +213,32 @@ void AssetsLibraryWidget::handleAddAsset()
|
|||||||
addResources({});
|
addResources({});
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetsLibraryWidget::handleExtFilesDrop(const QStringList &simpleFilesPaths,
|
void AssetsLibraryWidget::handleExtFilesDrop(const QList<QUrl> &simpleFilePaths,
|
||||||
const QStringList &complexFilesPaths,
|
const QList<QUrl> &complexFilePaths,
|
||||||
const QString &targetDirPath)
|
const QString &targetDirPath)
|
||||||
{
|
{
|
||||||
if (!simpleFilesPaths.isEmpty()) {
|
auto toLocalFile = [](const QUrl &url) { return url.toLocalFile(); };
|
||||||
|
|
||||||
|
QStringList simpleFilePathStrings = Utils::transform<QStringList>(simpleFilePaths, toLocalFile);
|
||||||
|
QStringList complexFilePathStrings = Utils::transform<QStringList>(complexFilePaths,
|
||||||
|
toLocalFile);
|
||||||
|
|
||||||
|
if (!simpleFilePathStrings.isEmpty()) {
|
||||||
if (targetDirPath.isEmpty()) {
|
if (targetDirPath.isEmpty()) {
|
||||||
addResources(simpleFilesPaths);
|
addResources(simpleFilePathStrings);
|
||||||
} else {
|
} else {
|
||||||
AddFilesResult result = ModelNodeOperations::addFilesToProject(simpleFilesPaths,
|
AddFilesResult result = ModelNodeOperations::addFilesToProject(simpleFilePathStrings,
|
||||||
targetDirPath);
|
targetDirPath);
|
||||||
if (result == AddFilesResult::Failed) {
|
if (result == AddFilesResult::Failed) {
|
||||||
Core::AsynchronousMessageBox::warning(tr("Failed to Add Files"),
|
Core::AsynchronousMessageBox::warning(tr("Failed to Add Files"),
|
||||||
tr("Could not add %1 to project.")
|
tr("Could not add %1 to project.")
|
||||||
.arg(simpleFilesPaths.join(' ')));
|
.arg(simpleFilePathStrings.join(' ')));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!complexFilesPaths.empty())
|
if (!complexFilePathStrings.empty())
|
||||||
addResources(complexFilesPaths);
|
addResources(complexFilePathStrings);
|
||||||
}
|
}
|
||||||
|
|
||||||
QSet<QString> AssetsLibraryWidget::supportedAssetSuffixes(bool complex)
|
QSet<QString> AssetsLibraryWidget::supportedAssetSuffixes(bool complex)
|
||||||
@@ -301,25 +307,25 @@ QPair<QString, QByteArray> AssetsLibraryWidget::getAssetTypeAndData(const QStrin
|
|||||||
if (!suffix.isEmpty()) {
|
if (!suffix.isEmpty()) {
|
||||||
if (AssetsLibraryModel::supportedImageSuffixes().contains(suffix)) {
|
if (AssetsLibraryModel::supportedImageSuffixes().contains(suffix)) {
|
||||||
// Data: Image format (suffix)
|
// Data: Image format (suffix)
|
||||||
return {"application/vnd.bauhaus.libraryresource.image", suffix.toUtf8()};
|
return {Constants::MIME_TYPE_ASSET_IMAGE, suffix.toUtf8()};
|
||||||
} else if (AssetsLibraryModel::supportedFontSuffixes().contains(suffix)) {
|
} else if (AssetsLibraryModel::supportedFontSuffixes().contains(suffix)) {
|
||||||
// Data: Font family name
|
// Data: Font family name
|
||||||
QRawFont font(assetPath, 10);
|
QRawFont font(assetPath, 10);
|
||||||
QString fontFamily = font.isValid() ? font.familyName() : "";
|
QString fontFamily = font.isValid() ? font.familyName() : "";
|
||||||
return {"application/vnd.bauhaus.libraryresource.font", fontFamily.toUtf8()};
|
return {Constants::MIME_TYPE_ASSET_FONT, fontFamily.toUtf8()};
|
||||||
} else if (AssetsLibraryModel::supportedShaderSuffixes().contains(suffix)) {
|
} else if (AssetsLibraryModel::supportedShaderSuffixes().contains(suffix)) {
|
||||||
// Data: shader type, frament (f) or vertex (v)
|
// Data: shader type, frament (f) or vertex (v)
|
||||||
return {"application/vnd.bauhaus.libraryresource.shader",
|
return {Constants::MIME_TYPE_ASSET_SHADER,
|
||||||
AssetsLibraryModel::supportedFragmentShaderSuffixes().contains(suffix) ? "f" : "v"};
|
AssetsLibraryModel::supportedFragmentShaderSuffixes().contains(suffix) ? "f" : "v"};
|
||||||
} else if (AssetsLibraryModel::supportedAudioSuffixes().contains(suffix)) {
|
} else if (AssetsLibraryModel::supportedAudioSuffixes().contains(suffix)) {
|
||||||
// No extra data for sounds
|
// No extra data for sounds
|
||||||
return {"application/vnd.bauhaus.libraryresource.sound", {}};
|
return {Constants::MIME_TYPE_ASSET_SOUND, {}};
|
||||||
} else if (AssetsLibraryModel::supportedVideoSuffixes().contains(suffix)) {
|
} else if (AssetsLibraryModel::supportedVideoSuffixes().contains(suffix)) {
|
||||||
// No extra data for videos
|
// No extra data for videos
|
||||||
return {"application/vnd.bauhaus.libraryresource.video", {}};
|
return {Constants::MIME_TYPE_ASSET_VIDEO, {}};
|
||||||
} else if (AssetsLibraryModel::supportedTexture3DSuffixes().contains(suffix)) {
|
} else if (AssetsLibraryModel::supportedTexture3DSuffixes().contains(suffix)) {
|
||||||
// Data: Image format (suffix)
|
// Data: Image format (suffix)
|
||||||
return {"application/vnd.bauhaus.libraryresource.texture3d", suffix.toUtf8()};
|
return {Constants::MIME_TYPE_ASSET_TEXTURE3D, suffix.toUtf8()};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
|
@@ -79,8 +79,8 @@ public:
|
|||||||
Q_INVOKABLE void startDragAsset(const QStringList &assetPaths, const QPointF &mousePos);
|
Q_INVOKABLE void startDragAsset(const QStringList &assetPaths, const QPointF &mousePos);
|
||||||
Q_INVOKABLE void handleAddAsset();
|
Q_INVOKABLE void handleAddAsset();
|
||||||
Q_INVOKABLE void handleSearchfilterChanged(const QString &filterText);
|
Q_INVOKABLE void handleSearchfilterChanged(const QString &filterText);
|
||||||
Q_INVOKABLE void handleExtFilesDrop(const QStringList &simpleFilesPaths,
|
Q_INVOKABLE void handleExtFilesDrop(const QList<QUrl> &simpleFilePaths,
|
||||||
const QStringList &complexFilesPaths,
|
const QList<QUrl> &complexFilePaths,
|
||||||
const QString &targetDirPath = {});
|
const QString &targetDirPath = {});
|
||||||
Q_INVOKABLE QSet<QString> supportedAssetSuffixes(bool complex);
|
Q_INVOKABLE QSet<QString> supportedAssetSuffixes(bool complex);
|
||||||
|
|
||||||
|
@@ -214,10 +214,9 @@ QmlTimeline CurveEditorView::activeTimeline() const
|
|||||||
if (node.hasVariantProperty("enabled")
|
if (node.hasVariantProperty("enabled")
|
||||||
&& node.variantProperty("enabled").value().toBool())
|
&& node.variantProperty("enabled").value().toBool())
|
||||||
return QmlTimeline(node);
|
return QmlTimeline(node);
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const ModelNode &node : allModelNodesOfType("QtQuick.Timeline.Timeline")) {
|
for (const ModelNode &node : allModelNodesOfType("QtQuick.Timeline.Timeline")) {
|
||||||
@@ -226,8 +225,9 @@ QmlTimeline CurveEditorView::activeTimeline() const
|
|||||||
if (!propertyChanges.isValid())
|
if (!propertyChanges.isValid())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (node.hasVariantProperty("enabled") && node.variantProperty("enabled").value().toBool())
|
if (propertyChanges.modelNode().hasProperty("enabled") &&
|
||||||
return QmlTimeline(node);
|
propertyChanges.modelNode().variantProperty("enabled").value().toBool())
|
||||||
|
return QmlTimeline(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
|
@@ -169,7 +169,7 @@ void Edit3DCanvas::dragEnterEvent(QDragEnterEvent *e)
|
|||||||
// Allow drop when there is no valid active scene, as the drop goes under the root node of
|
// Allow drop when there is no valid active scene, as the drop goes under the root node of
|
||||||
// the document in that case.
|
// the document in that case.
|
||||||
if (!node.isValid() || !ModelNode::isThisOrAncestorLocked(node)) {
|
if (!node.isValid() || !ModelNode::isThisOrAncestorLocked(node)) {
|
||||||
QByteArray data = e->mimeData()->data(QStringLiteral("application/vnd.bauhaus.itemlibraryinfo"));
|
QByteArray data = e->mimeData()->data(Constants::MIME_TYPE_ITEM_LIBRARY_INFO);
|
||||||
if (!data.isEmpty()) {
|
if (!data.isEmpty()) {
|
||||||
QDataStream stream(data);
|
QDataStream stream(data);
|
||||||
stream >> m_itemLibraryEntry;
|
stream >> m_itemLibraryEntry;
|
||||||
|
@@ -24,12 +24,12 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "abstractformeditortool.h"
|
#include "abstractformeditortool.h"
|
||||||
|
#include "assetslibrarywidget.h"
|
||||||
|
#include "formeditorscene.h"
|
||||||
#include "formeditorview.h"
|
#include "formeditorview.h"
|
||||||
#include "formeditorwidget.h"
|
#include "formeditorwidget.h"
|
||||||
#include "formeditorscene.h"
|
#include "modelnodecontextmenu.h"
|
||||||
#include "assetslibrarywidget.h"
|
#include "qmldesignerconstants.h"
|
||||||
|
|
||||||
#include <modelnodecontextmenu.h>
|
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QGraphicsSceneDragDropEvent>
|
#include <QGraphicsSceneDragDropEvent>
|
||||||
@@ -236,20 +236,20 @@ void AbstractFormEditorTool::dropEvent(const QList<QGraphicsItem*> &/*itemList*/
|
|||||||
void AbstractFormEditorTool::dragEnterEvent(const QList<QGraphicsItem*> &itemList, QGraphicsSceneDragDropEvent *event)
|
void AbstractFormEditorTool::dragEnterEvent(const QList<QGraphicsItem*> &itemList, QGraphicsSceneDragDropEvent *event)
|
||||||
{
|
{
|
||||||
bool hasValidAssets = false;
|
bool hasValidAssets = false;
|
||||||
if (event->mimeData()->hasFormat("application/vnd.bauhaus.libraryresource")) {
|
if (event->mimeData()->hasFormat(Constants::MIME_TYPE_ASSETS)) {
|
||||||
const QStringList assetPaths = QString::fromUtf8(event->mimeData()
|
const QStringList assetPaths = QString::fromUtf8(event->mimeData()
|
||||||
->data("application/vnd.bauhaus.libraryresource")).split(",");
|
->data(Constants::MIME_TYPE_ASSETS)).split(',');
|
||||||
for (const QString &assetPath : assetPaths) {
|
for (const QString &assetPath : assetPaths) {
|
||||||
QString assetType = AssetsLibraryWidget::getAssetTypeAndData(assetPath).first;
|
QString assetType = AssetsLibraryWidget::getAssetTypeAndData(assetPath).first;
|
||||||
if (assetType == "application/vnd.bauhaus.libraryresource.image"
|
if (assetType == Constants::MIME_TYPE_ASSET_IMAGE
|
||||||
|| assetType == "application/vnd.bauhaus.libraryresource.font") {
|
|| assetType == Constants::MIME_TYPE_ASSET_FONT) {
|
||||||
hasValidAssets = true;
|
hasValidAssets = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->mimeData()->hasFormat(QLatin1String("application/vnd.bauhaus.itemlibraryinfo")) || hasValidAssets) {
|
if (event->mimeData()->hasFormat(Constants::MIME_TYPE_ITEM_LIBRARY_INFO) || hasValidAssets) {
|
||||||
event->accept();
|
event->accept();
|
||||||
view()->changeToDragTool();
|
view()->changeToDragTool();
|
||||||
view()->currentTool()->dragEnterEvent(itemList, event);
|
view()->currentTool()->dragEnterEvent(itemList, event);
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
#include <metainfo.h>
|
#include <metainfo.h>
|
||||||
#include <nodehints.h>
|
#include <nodehints.h>
|
||||||
#include <rewritingexception.h>
|
#include <rewritingexception.h>
|
||||||
|
#include "qmldesignerconstants.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QGraphicsSceneMouseEvent>
|
#include <QGraphicsSceneMouseEvent>
|
||||||
@@ -219,9 +220,7 @@ void DragTool::abort()
|
|||||||
|
|
||||||
static ItemLibraryEntry itemLibraryEntryFromMimeData(const QMimeData *mimeData)
|
static ItemLibraryEntry itemLibraryEntryFromMimeData(const QMimeData *mimeData)
|
||||||
{
|
{
|
||||||
QByteArray data = mimeData->data(QStringLiteral("application/vnd.bauhaus.itemlibraryinfo"));
|
QDataStream stream(mimeData->data(Constants::MIME_TYPE_ITEM_LIBRARY_INFO));
|
||||||
|
|
||||||
QDataStream stream(data);
|
|
||||||
|
|
||||||
ItemLibraryEntry itemLibraryEntry;
|
ItemLibraryEntry itemLibraryEntry;
|
||||||
stream >> itemLibraryEntry;
|
stream >> itemLibraryEntry;
|
||||||
@@ -236,7 +235,7 @@ static bool canBeDropped(const QMimeData *mimeData)
|
|||||||
|
|
||||||
static bool hasItemLibraryInfo(const QMimeData *mimeData)
|
static bool hasItemLibraryInfo(const QMimeData *mimeData)
|
||||||
{
|
{
|
||||||
return mimeData->hasFormat(QStringLiteral("application/vnd.bauhaus.itemlibraryinfo"));
|
return mimeData->hasFormat(Constants::MIME_TYPE_ITEM_LIBRARY_INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DragTool::dropEvent(const QList<QGraphicsItem *> &/*itemList*/, QGraphicsSceneDragDropEvent *event)
|
void DragTool::dropEvent(const QList<QGraphicsItem *> &/*itemList*/, QGraphicsSceneDragDropEvent *event)
|
||||||
@@ -326,12 +325,12 @@ void DragTool::createDragNodes(const QMimeData *mimeData, const QPointF &scenePo
|
|||||||
scenePosition);
|
scenePosition);
|
||||||
} else {
|
} else {
|
||||||
const QStringList assetPaths = QString::fromUtf8(mimeData
|
const QStringList assetPaths = QString::fromUtf8(mimeData
|
||||||
->data("application/vnd.bauhaus.libraryresource")).split(",");
|
->data(Constants::MIME_TYPE_ASSETS)).split(',');
|
||||||
for (const QString &assetPath : assetPaths) {
|
for (const QString &assetPath : assetPaths) {
|
||||||
QString assetType = AssetsLibraryWidget::getAssetTypeAndData(assetPath).first;
|
QString assetType = AssetsLibraryWidget::getAssetTypeAndData(assetPath).first;
|
||||||
if (assetType == "application/vnd.bauhaus.libraryresource.image")
|
if (assetType == Constants::MIME_TYPE_ASSET_IMAGE)
|
||||||
createQmlItemNodeFromImage(assetPath, targetContainerQmlItemNode, scenePosition);
|
createQmlItemNodeFromImage(assetPath, targetContainerQmlItemNode, scenePosition);
|
||||||
else if (assetType == "application/vnd.bauhaus.libraryresource.font")
|
else if (assetType == Constants::MIME_TYPE_ASSET_FONT)
|
||||||
createQmlItemNodeFromFont(assetPath, targetContainerQmlItemNode, scenePosition);
|
createQmlItemNodeFromFont(assetPath, targetContainerQmlItemNode, scenePosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -36,6 +36,7 @@
|
|||||||
#include <nodemetainfo.h>
|
#include <nodemetainfo.h>
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
#include <projectexplorer/session.h>
|
#include <projectexplorer/session.h>
|
||||||
|
#include "qmldesignerconstants.h"
|
||||||
#include "qmldesignerplugin.h"
|
#include "qmldesignerplugin.h"
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
@@ -515,9 +516,9 @@ QMimeData *ItemLibraryModel::getMimeData(const ItemLibraryEntry &itemLibraryEntr
|
|||||||
QByteArray data;
|
QByteArray data;
|
||||||
QDataStream stream(&data, QIODevice::WriteOnly);
|
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||||
stream << itemLibraryEntry;
|
stream << itemLibraryEntry;
|
||||||
mimeData->setData(QStringLiteral("application/vnd.bauhaus.itemlibraryinfo"), data);
|
mimeData->setData(Constants::MIME_TYPE_ITEM_LIBRARY_INFO, data);
|
||||||
|
|
||||||
mimeData->removeFormat(QStringLiteral("text/plain"));
|
mimeData->removeFormat("text/plain");
|
||||||
|
|
||||||
return mimeData;
|
return mimeData;
|
||||||
}
|
}
|
||||||
|
@@ -40,7 +40,6 @@
|
|||||||
#include "modelnodeoperations.h"
|
#include "modelnodeoperations.h"
|
||||||
#include <metainfo.h>
|
#include <metainfo.h>
|
||||||
#include <model.h>
|
#include <model.h>
|
||||||
#include <navigatorwidget.h>
|
|
||||||
#include <rewritingexception.h>
|
#include <rewritingexception.h>
|
||||||
#include <qmldesignerconstants.h>
|
#include <qmldesignerconstants.h>
|
||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
@@ -89,6 +88,9 @@ static QString propertyEditorResourcesPath()
|
|||||||
|
|
||||||
bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event)
|
bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event)
|
||||||
{
|
{
|
||||||
|
auto document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||||
|
Model *model = document ? document->documentModel() : nullptr;
|
||||||
|
|
||||||
if (event->type() == QEvent::FocusOut) {
|
if (event->type() == QEvent::FocusOut) {
|
||||||
if (obj == m_itemsWidget.data())
|
if (obj == m_itemsWidget.data())
|
||||||
QMetaObject::invokeMethod(m_itemsWidget->rootObject(), "closeContextMenu");
|
QMetaObject::invokeMethod(m_itemsWidget->rootObject(), "closeContextMenu");
|
||||||
@@ -115,33 +117,19 @@ bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QWidget *view = QmlDesignerPlugin::instance()->viewManager().widget("Navigator");
|
|
||||||
if (view) {
|
if (model) {
|
||||||
NavigatorWidget *navView = qobject_cast<NavigatorWidget *>(view);
|
model->startDrag(m_itemLibraryModel->getMimeData(entry),
|
||||||
if (navView) {
|
Utils::StyleHelper::dpiSpecificImageFile(entry.libraryEntryIconPath()));
|
||||||
navView->setDragType(entry.typeName());
|
|
||||||
navView->update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
auto drag = new QDrag(this);
|
|
||||||
drag->setPixmap(Utils::StyleHelper::dpiSpecificImageFile(entry.libraryEntryIconPath()));
|
|
||||||
drag->setMimeData(m_itemLibraryModel->getMimeData(entry));
|
|
||||||
drag->exec();
|
|
||||||
drag->deleteLater();
|
|
||||||
|
|
||||||
m_itemToDrag = {};
|
m_itemToDrag = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (event->type() == QMouseEvent::MouseButtonRelease) {
|
} else if (event->type() == QMouseEvent::MouseButtonRelease) {
|
||||||
m_itemToDrag = {};
|
m_itemToDrag = {};
|
||||||
QWidget *view = QmlDesignerPlugin::instance()->viewManager().widget("Navigator");
|
if (model)
|
||||||
if (view) {
|
model->endDrag();
|
||||||
NavigatorWidget *navView = qobject_cast<NavigatorWidget *>(view);
|
|
||||||
if (navView) {
|
|
||||||
navView->setDragType("");
|
|
||||||
navView->update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return QObject::eventFilter(obj, event);
|
return QObject::eventFilter(obj, event);
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
#include "navigatorview.h"
|
#include "navigatorview.h"
|
||||||
#include "navigatorwidget.h"
|
#include "navigatorwidget.h"
|
||||||
#include "choosefrompropertylistdialog.h"
|
#include "choosefrompropertylistdialog.h"
|
||||||
|
#include "qmldesignerconstants.h"
|
||||||
#include "qmldesignerplugin.h"
|
#include "qmldesignerplugin.h"
|
||||||
#include "assetslibrarywidget.h"
|
#include "assetslibrarywidget.h"
|
||||||
|
|
||||||
@@ -71,7 +72,7 @@ namespace QmlDesigner {
|
|||||||
|
|
||||||
static QList<ModelNode> modelNodesFromMimeData(const QMimeData *mineData, AbstractView *view)
|
static QList<ModelNode> modelNodesFromMimeData(const QMimeData *mineData, AbstractView *view)
|
||||||
{
|
{
|
||||||
QByteArray encodedModelNodeData = mineData->data(QLatin1String("application/vnd.modelnode.list"));
|
QByteArray encodedModelNodeData = mineData->data(Constants::MIME_TYPE_MODELNODE_LIST);
|
||||||
QDataStream modelNodeStream(&encodedModelNodeData, QIODevice::ReadOnly);
|
QDataStream modelNodeStream(&encodedModelNodeData, QIODevice::ReadOnly);
|
||||||
|
|
||||||
QList<ModelNode> modelNodeList;
|
QList<ModelNode> modelNodeList;
|
||||||
@@ -465,9 +466,9 @@ void NavigatorTreeModel::setView(NavigatorView *view)
|
|||||||
|
|
||||||
QStringList NavigatorTreeModel::mimeTypes() const
|
QStringList NavigatorTreeModel::mimeTypes() const
|
||||||
{
|
{
|
||||||
const static QStringList types({"application/vnd.modelnode.list",
|
const static QStringList types({Constants::MIME_TYPE_MODELNODE_LIST,
|
||||||
"application/vnd.bauhaus.itemlibraryinfo",
|
Constants::MIME_TYPE_ITEM_LIBRARY_INFO,
|
||||||
"application/vnd.bauhaus.libraryresource"});
|
Constants::MIME_TYPE_ASSETS});
|
||||||
|
|
||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
@@ -490,7 +491,7 @@ QMimeData *NavigatorTreeModel::mimeData(const QModelIndexList &modelIndexList) c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mimeData->setData("application/vnd.modelnode.list", encodedModelNodeData);
|
mimeData->setData(Constants::MIME_TYPE_MODELNODE_LIST, encodedModelNodeData);
|
||||||
|
|
||||||
return mimeData;
|
return mimeData;
|
||||||
}
|
}
|
||||||
@@ -560,10 +561,10 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData,
|
|||||||
widget->setDragType("");
|
widget->setDragType("");
|
||||||
|
|
||||||
if (dropModelIndex.model() == this) {
|
if (dropModelIndex.model() == this) {
|
||||||
if (mimeData->hasFormat("application/vnd.bauhaus.itemlibraryinfo")) {
|
if (mimeData->hasFormat(Constants::MIME_TYPE_ITEM_LIBRARY_INFO)) {
|
||||||
handleItemLibraryItemDrop(mimeData, rowNumber, dropModelIndex);
|
handleItemLibraryItemDrop(mimeData, rowNumber, dropModelIndex);
|
||||||
} else if (mimeData->hasFormat("application/vnd.bauhaus.libraryresource")) {
|
} else if (mimeData->hasFormat(Constants::MIME_TYPE_ASSETS)) {
|
||||||
const QStringList assetsPaths = QString::fromUtf8(mimeData->data("application/vnd.bauhaus.libraryresource")).split(",");
|
const QStringList assetsPaths = QString::fromUtf8(mimeData->data(Constants::MIME_TYPE_ASSETS)).split(',');
|
||||||
NodeAbstractProperty targetProperty;
|
NodeAbstractProperty targetProperty;
|
||||||
|
|
||||||
const QModelIndex rowModelIndex = dropModelIndex.sibling(dropModelIndex.row(), 0);
|
const QModelIndex rowModelIndex = dropModelIndex.sibling(dropModelIndex.row(), 0);
|
||||||
@@ -579,9 +580,9 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData,
|
|||||||
QSet<QString> neededImports;
|
QSet<QString> neededImports;
|
||||||
for (const QString &assetPath : assetsPaths) {
|
for (const QString &assetPath : assetsPaths) {
|
||||||
QString assetType = AssetsLibraryWidget::getAssetTypeAndData(assetPath).first;
|
QString assetType = AssetsLibraryWidget::getAssetTypeAndData(assetPath).first;
|
||||||
if (assetType == "application/vnd.bauhaus.libraryresource.shader")
|
if (assetType == Constants::MIME_TYPE_ASSET_SHADER)
|
||||||
neededImports.insert("QtQuick3D");
|
neededImports.insert("QtQuick3D");
|
||||||
else if (assetType == "application/vnd.bauhaus.libraryresource.sound")
|
else if (assetType == Constants::MIME_TYPE_ASSET_SOUND)
|
||||||
neededImports.insert("QtMultimedia");
|
neededImports.insert("QtMultimedia");
|
||||||
|
|
||||||
if (neededImports.size() == 2)
|
if (neededImports.size() == 2)
|
||||||
@@ -598,20 +599,20 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData,
|
|||||||
auto assetTypeAndData = AssetsLibraryWidget::getAssetTypeAndData(assetPath);
|
auto assetTypeAndData = AssetsLibraryWidget::getAssetTypeAndData(assetPath);
|
||||||
QString assetType = assetTypeAndData.first;
|
QString assetType = assetTypeAndData.first;
|
||||||
QString assetData = QString::fromUtf8(assetTypeAndData.second);
|
QString assetData = QString::fromUtf8(assetTypeAndData.second);
|
||||||
if (assetType == "application/vnd.bauhaus.libraryresource.image") {
|
if (assetType == Constants::MIME_TYPE_ASSET_IMAGE) {
|
||||||
currNode = handleItemLibraryImageDrop(assetPath, targetProperty,
|
currNode = handleItemLibraryImageDrop(assetPath, targetProperty,
|
||||||
rowModelIndex, moveNodesAfter);
|
rowModelIndex, moveNodesAfter);
|
||||||
} else if (assetType == "application/vnd.bauhaus.libraryresource.font") {
|
} else if (assetType == Constants::MIME_TYPE_ASSET_FONT) {
|
||||||
currNode = handleItemLibraryFontDrop(assetData, // assetData is fontFamily
|
currNode = handleItemLibraryFontDrop(assetData, // assetData is fontFamily
|
||||||
targetProperty, rowModelIndex);
|
targetProperty, rowModelIndex);
|
||||||
} else if (assetType == "application/vnd.bauhaus.libraryresource.shader") {
|
} else if (assetType == Constants::MIME_TYPE_ASSET_SHADER) {
|
||||||
currNode = handleItemLibraryShaderDrop(assetPath, assetData == "f",
|
currNode = handleItemLibraryShaderDrop(assetPath, assetData == "f",
|
||||||
targetProperty, rowModelIndex,
|
targetProperty, rowModelIndex,
|
||||||
moveNodesAfter);
|
moveNodesAfter);
|
||||||
} else if (assetType == "application/vnd.bauhaus.libraryresource.sound") {
|
} else if (assetType == Constants::MIME_TYPE_ASSET_SOUND) {
|
||||||
currNode = handleItemLibrarySoundDrop(assetPath, targetProperty,
|
currNode = handleItemLibrarySoundDrop(assetPath, targetProperty,
|
||||||
rowModelIndex);
|
rowModelIndex);
|
||||||
} else if (assetType == "application/vnd.bauhaus.libraryresource.texture3d") {
|
} else if (assetType == Constants::MIME_TYPE_ASSET_TEXTURE3D) {
|
||||||
currNode = handleItemLibraryTexture3dDrop(assetPath, targetProperty,
|
currNode = handleItemLibraryTexture3dDrop(assetPath, targetProperty,
|
||||||
rowModelIndex, moveNodesAfter);
|
rowModelIndex, moveNodesAfter);
|
||||||
}
|
}
|
||||||
@@ -627,7 +628,7 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData,
|
|||||||
m_view->setSelectedModelNodes(addedNodes);
|
m_view->setSelectedModelNodes(addedNodes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (mimeData->hasFormat("application/vnd.modelnode.list")) {
|
} else if (mimeData->hasFormat(Constants::MIME_TYPE_MODELNODE_LIST)) {
|
||||||
handleInternalDrop(mimeData, rowNumber, dropModelIndex);
|
handleInternalDrop(mimeData, rowNumber, dropModelIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -673,7 +674,7 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in
|
|||||||
NodeAbstractProperty targetProperty;
|
NodeAbstractProperty targetProperty;
|
||||||
|
|
||||||
const ItemLibraryEntry itemLibraryEntry =
|
const ItemLibraryEntry itemLibraryEntry =
|
||||||
createItemLibraryEntryFromMimeData(mimeData->data("application/vnd.bauhaus.itemlibraryinfo"));
|
createItemLibraryEntryFromMimeData(mimeData->data(Constants::MIME_TYPE_ITEM_LIBRARY_INFO));
|
||||||
|
|
||||||
const NodeHints hints = NodeHints::fromItemLibraryEntry(itemLibraryEntry);
|
const NodeHints hints = NodeHints::fromItemLibraryEntry(itemLibraryEntry);
|
||||||
|
|
||||||
|
@@ -36,6 +36,7 @@
|
|||||||
#include <bindingproperty.h>
|
#include <bindingproperty.h>
|
||||||
#include <designmodecontext.h>
|
#include <designmodecontext.h>
|
||||||
#include <designersettings.h>
|
#include <designersettings.h>
|
||||||
|
#include <itemlibraryinfo.h>
|
||||||
#include <nodeproperty.h>
|
#include <nodeproperty.h>
|
||||||
#include <nodelistproperty.h>
|
#include <nodelistproperty.h>
|
||||||
#include <variantproperty.h>
|
#include <variantproperty.h>
|
||||||
@@ -57,8 +58,9 @@
|
|||||||
#include <utils/stylehelper.h>
|
#include <utils/stylehelper.h>
|
||||||
|
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
#include <QTimer>
|
#include <QMimeData>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
static inline void setScenePos(const QmlDesigner::ModelNode &modelNode,const QPointF &pos)
|
static inline void setScenePos(const QmlDesigner::ModelNode &modelNode,const QPointF &pos)
|
||||||
{
|
{
|
||||||
@@ -263,6 +265,25 @@ void NavigatorView::bindingPropertiesChanged(const QList<BindingProperty> & prop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NavigatorView::dragStarted(QMimeData *mimeData)
|
||||||
|
{
|
||||||
|
if (mimeData->hasFormat(Constants::MIME_TYPE_ITEM_LIBRARY_INFO)) {
|
||||||
|
QByteArray data = mimeData->data(Constants::MIME_TYPE_ITEM_LIBRARY_INFO);
|
||||||
|
QDataStream stream(data);
|
||||||
|
ItemLibraryEntry itemLibraryEntry;
|
||||||
|
stream >> itemLibraryEntry;
|
||||||
|
|
||||||
|
m_widget->setDragType(itemLibraryEntry.typeName());
|
||||||
|
m_widget->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigatorView::dragEnded()
|
||||||
|
{
|
||||||
|
m_widget->setDragType("");
|
||||||
|
m_widget->update();
|
||||||
|
}
|
||||||
|
|
||||||
void NavigatorView::customNotification(const AbstractView *view, const QString &identifier,
|
void NavigatorView::customNotification(const AbstractView *view, const QString &identifier,
|
||||||
const QList<ModelNode> &nodeList, const QList<QVariant> &data)
|
const QList<ModelNode> &nodeList, const QList<QVariant> &data)
|
||||||
{
|
{
|
||||||
|
@@ -92,6 +92,9 @@ public:
|
|||||||
|
|
||||||
void bindingPropertiesChanged(const QList<BindingProperty> &propertyList, PropertyChangeFlags) override;
|
void bindingPropertiesChanged(const QList<BindingProperty> &propertyList, PropertyChangeFlags) override;
|
||||||
|
|
||||||
|
void dragStarted(QMimeData *mimeData) override;
|
||||||
|
void dragEnded() override;
|
||||||
|
|
||||||
void customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
void customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
||||||
|
|
||||||
void handleChangedExport(const ModelNode &modelNode, bool exported);
|
void handleChangedExport(const ModelNode &modelNode, bool exported);
|
||||||
|
@@ -294,7 +294,7 @@ void PropertyEditorQmlBackend::createPropertyEditorValue(const QmlObjectNode &qm
|
|||||||
valueObject = new PropertyEditorValue(&backendValuesPropertyMap());
|
valueObject = new PropertyEditorValue(&backendValuesPropertyMap());
|
||||||
QObject::connect(valueObject, &PropertyEditorValue::valueChanged, &backendValuesPropertyMap(), &DesignerPropertyMap::valueChanged);
|
QObject::connect(valueObject, &PropertyEditorValue::valueChanged, &backendValuesPropertyMap(), &DesignerPropertyMap::valueChanged);
|
||||||
QObject::connect(valueObject, &PropertyEditorValue::expressionChanged, propertyEditor, &PropertyEditorView::changeExpression);
|
QObject::connect(valueObject, &PropertyEditorValue::expressionChanged, propertyEditor, &PropertyEditorView::changeExpression);
|
||||||
QObject::connect(valueObject, &PropertyEditorValue::exportPopertyAsAliasRequested, propertyEditor, &PropertyEditorView::exportPopertyAsAlias);
|
QObject::connect(valueObject, &PropertyEditorValue::exportPropertyAsAliasRequested, propertyEditor, &PropertyEditorView::exportPropertyAsAlias);
|
||||||
QObject::connect(valueObject, &PropertyEditorValue::removeAliasExportRequested, propertyEditor, &PropertyEditorView::removeAliasExport);
|
QObject::connect(valueObject, &PropertyEditorValue::removeAliasExportRequested, propertyEditor, &PropertyEditorView::removeAliasExport);
|
||||||
backendValuesPropertyMap().insert(QString::fromUtf8(propertyName), QVariant::fromValue(valueObject));
|
backendValuesPropertyMap().insert(QString::fromUtf8(propertyName), QVariant::fromValue(valueObject));
|
||||||
}
|
}
|
||||||
|
@@ -367,9 +367,9 @@ void PropertyEditorValue::setEnumeration(const QString &scope, const QString &na
|
|||||||
setValueWithEmit(QVariant::fromValue(newEnumeration));
|
setValueWithEmit(QVariant::fromValue(newEnumeration));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropertyEditorValue::exportPopertyAsAlias()
|
void PropertyEditorValue::exportPropertyAsAlias()
|
||||||
{
|
{
|
||||||
emit exportPopertyAsAliasRequested(nameAsQString());
|
emit exportPropertyAsAliasRequested(nameAsQString());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PropertyEditorValue::hasPropertyAlias() const
|
bool PropertyEditorValue::hasPropertyAlias() const
|
||||||
|
@@ -130,7 +130,7 @@ public:
|
|||||||
|
|
||||||
static void registerDeclarativeTypes();
|
static void registerDeclarativeTypes();
|
||||||
|
|
||||||
Q_INVOKABLE void exportPopertyAsAlias();
|
Q_INVOKABLE void exportPropertyAsAlias();
|
||||||
Q_INVOKABLE bool hasPropertyAlias() const;
|
Q_INVOKABLE bool hasPropertyAlias() const;
|
||||||
Q_INVOKABLE bool isAttachedProperty() const;
|
Q_INVOKABLE bool isAttachedProperty() const;
|
||||||
Q_INVOKABLE void removeAliasExport();
|
Q_INVOKABLE void removeAliasExport();
|
||||||
@@ -153,7 +153,7 @@ signals:
|
|||||||
void valueChangedQml();
|
void valueChangedQml();
|
||||||
|
|
||||||
void expressionChanged(const QString &name);
|
void expressionChanged(const QString &name);
|
||||||
void exportPopertyAsAliasRequested(const QString &name);
|
void exportPropertyAsAliasRequested(const QString &name);
|
||||||
void removeAliasExportRequested(const QString &name);
|
void removeAliasExportRequested(const QString &name);
|
||||||
|
|
||||||
void modelStateChanged();
|
void modelStateChanged();
|
||||||
|
@@ -256,6 +256,9 @@ void PropertyEditorView::changeExpression(const QString &propertyName)
|
|||||||
if (noValidSelection())
|
if (noValidSelection())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
QScopeGuard unlock([&](){ m_locked = false; });
|
||||||
|
m_locked = true;
|
||||||
|
|
||||||
executeInTransaction("PropertyEditorView::changeExpression", [this, name](){
|
executeInTransaction("PropertyEditorView::changeExpression", [this, name](){
|
||||||
PropertyName underscoreName(name);
|
PropertyName underscoreName(name);
|
||||||
underscoreName.replace('.', '_');
|
underscoreName.replace('.', '_');
|
||||||
@@ -317,13 +320,13 @@ void PropertyEditorView::changeExpression(const QString &propertyName)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qmlObjectNode->expression(name) != value->expression() || !qmlObjectNode->propertyAffectedByCurrentState(name))
|
if (qmlObjectNode->expression(name) != value->expression()
|
||||||
|
|| !qmlObjectNode->propertyAffectedByCurrentState(name))
|
||||||
qmlObjectNode->setBindingProperty(name, value->expression());
|
qmlObjectNode->setBindingProperty(name, value->expression());
|
||||||
|
|
||||||
}); /* end of transaction */
|
}); /* end of transaction */
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropertyEditorView::exportPopertyAsAlias(const QString &name)
|
void PropertyEditorView::exportPropertyAsAlias(const QString &name)
|
||||||
{
|
{
|
||||||
if (name.isNull())
|
if (name.isNull())
|
||||||
return;
|
return;
|
||||||
@@ -334,7 +337,7 @@ void PropertyEditorView::exportPopertyAsAlias(const QString &name)
|
|||||||
if (noValidSelection())
|
if (noValidSelection())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
executeInTransaction("PropertyEditorView::exportPopertyAsAlias", [this, name](){
|
executeInTransaction("PropertyEditorView::exportPropertyAsAlias", [this, name](){
|
||||||
const QString id = m_selectedNode.validId();
|
const QString id = m_selectedNode.validId();
|
||||||
QString upperCasePropertyName = name;
|
QString upperCasePropertyName = name;
|
||||||
upperCasePropertyName.replace(0, 1, upperCasePropertyName.at(0).toUpper());
|
upperCasePropertyName.replace(0, 1, upperCasePropertyName.at(0).toUpper());
|
||||||
@@ -362,7 +365,7 @@ void PropertyEditorView::removeAliasExport(const QString &name)
|
|||||||
if (noValidSelection())
|
if (noValidSelection())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
executeInTransaction("PropertyEditorView::exportPopertyAsAlias", [this, name](){
|
executeInTransaction("PropertyEditorView::exportPropertyAsAlias", [this, name](){
|
||||||
const QString id = m_selectedNode.validId();
|
const QString id = m_selectedNode.validId();
|
||||||
|
|
||||||
for (const BindingProperty &property : rootModelNode().bindingProperties())
|
for (const BindingProperty &property : rootModelNode().bindingProperties())
|
||||||
@@ -692,6 +695,9 @@ void PropertyEditorView::variantPropertiesChanged(const QList<VariantProperty>&
|
|||||||
|
|
||||||
void PropertyEditorView::bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags /*propertyChange*/)
|
void PropertyEditorView::bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags /*propertyChange*/)
|
||||||
{
|
{
|
||||||
|
if (locked())
|
||||||
|
return;
|
||||||
|
|
||||||
if (noValidSelection())
|
if (noValidSelection())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@@ -89,7 +89,7 @@ public:
|
|||||||
|
|
||||||
void changeValue(const QString &name);
|
void changeValue(const QString &name);
|
||||||
void changeExpression(const QString &name);
|
void changeExpression(const QString &name);
|
||||||
void exportPopertyAsAlias(const QString &name);
|
void exportPropertyAsAlias(const QString &name);
|
||||||
void removeAliasExport(const QString &name);
|
void removeAliasExport(const QString &name);
|
||||||
|
|
||||||
bool locked() const;
|
bool locked() const;
|
||||||
|
@@ -229,6 +229,9 @@ public:
|
|||||||
virtual void updateImport3DSupport(const QVariantMap &supportMap);
|
virtual void updateImport3DSupport(const QVariantMap &supportMap);
|
||||||
virtual void modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
|
virtual void modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
|
||||||
|
|
||||||
|
virtual void dragStarted(QMimeData *mimeData);
|
||||||
|
virtual void dragEnded();
|
||||||
|
|
||||||
void changeRootNodeType(const TypeName &type, int majorVersion, int minorVersion);
|
void changeRootNodeType(const TypeName &type, int majorVersion, int minorVersion);
|
||||||
|
|
||||||
NodeInstanceView *nodeInstanceView() const;
|
NodeInstanceView *nodeInstanceView() const;
|
||||||
|
@@ -129,6 +129,9 @@ public:
|
|||||||
QString generateNewId(const QString &prefixName) const;
|
QString generateNewId(const QString &prefixName) const;
|
||||||
QString generateNewId(const QString &prefixName, const QString &fallbackPrefix) const;
|
QString generateNewId(const QString &prefixName, const QString &fallbackPrefix) const;
|
||||||
|
|
||||||
|
void startDrag(QMimeData *mimeData, const QString iconPath = {});
|
||||||
|
void endDrag();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Model();
|
Model();
|
||||||
|
|
||||||
|
@@ -396,6 +396,9 @@ void AbstractView::modelNodePreviewPixmapChanged(const ModelNode & /*node*/, con
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AbstractView::dragStarted(QMimeData * /*mimeData*/) {}
|
||||||
|
void AbstractView::dragEnded() {}
|
||||||
|
|
||||||
QList<ModelNode> AbstractView::toModelNodeList(const QList<Internal::InternalNode::Pointer> &nodeList) const
|
QList<ModelNode> AbstractView::toModelNodeList(const QList<Internal::InternalNode::Pointer> &nodeList) const
|
||||||
{
|
{
|
||||||
return QmlDesigner::toModelNodeList(nodeList, const_cast<AbstractView*>(this));
|
return QmlDesigner::toModelNodeList(nodeList, const_cast<AbstractView*>(this));
|
||||||
|
@@ -67,6 +67,7 @@
|
|||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
|
#include <QDrag>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -588,6 +589,16 @@ void ModelPrivate::notifyImport3DSupportChanged(const QVariantMap &supportMap)
|
|||||||
notifyInstanceChanges([&](AbstractView *view) { view->updateImport3DSupport(supportMap); });
|
notifyInstanceChanges([&](AbstractView *view) { view->updateImport3DSupport(supportMap); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelPrivate::notifyDragStarted(QMimeData *mimeData)
|
||||||
|
{
|
||||||
|
notifyInstanceChanges([&](AbstractView *view) { view->dragStarted(mimeData); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelPrivate::notifyDragEnded()
|
||||||
|
{
|
||||||
|
notifyInstanceChanges([&](AbstractView *view) { view->dragEnded(); });
|
||||||
|
}
|
||||||
|
|
||||||
void ModelPrivate::notifyRewriterBeginTransaction()
|
void ModelPrivate::notifyRewriterBeginTransaction()
|
||||||
{
|
{
|
||||||
notifyNodeInstanceViewLast([&](AbstractView *view) { view->rewriterBeginTransaction(); });
|
notifyNodeInstanceViewLast([&](AbstractView *view) { view->rewriterBeginTransaction(); });
|
||||||
@@ -1492,6 +1503,22 @@ QString Model::generateNewId(const QString &prefixName, const QString &fallbackP
|
|||||||
return newId;
|
return newId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Model::startDrag(QMimeData *mimeData, const QString iconPath)
|
||||||
|
{
|
||||||
|
d->notifyDragStarted(mimeData);
|
||||||
|
|
||||||
|
auto drag = new QDrag(this);
|
||||||
|
drag->setPixmap(iconPath);
|
||||||
|
drag->setMimeData(mimeData);
|
||||||
|
drag->exec();
|
||||||
|
drag->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Model::endDrag()
|
||||||
|
{
|
||||||
|
d->notifyDragEnded();
|
||||||
|
}
|
||||||
|
|
||||||
QString Model::generateNewId(const QString &prefixName) const
|
QString Model::generateNewId(const QString &prefixName) const
|
||||||
{
|
{
|
||||||
return generateNewId(prefixName, QStringLiteral("element"));
|
return generateNewId(prefixName, QStringLiteral("element"));
|
||||||
|
@@ -183,6 +183,9 @@ public:
|
|||||||
void notifyModelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
|
void notifyModelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap);
|
||||||
void notifyImport3DSupportChanged(const QVariantMap &supportMap);
|
void notifyImport3DSupportChanged(const QVariantMap &supportMap);
|
||||||
|
|
||||||
|
void notifyDragStarted(QMimeData *mimeData);
|
||||||
|
void notifyDragEnded();
|
||||||
|
|
||||||
void setDocumentMessages(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &warnings);
|
void setDocumentMessages(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &warnings);
|
||||||
|
|
||||||
void notifyRewriterBeginTransaction();
|
void notifyRewriterBeginTransaction();
|
||||||
|
@@ -85,6 +85,16 @@ const char QUICK_3D_ASSET_IMPORT_DATA_OPTIONS_KEY[] = "import_options";
|
|||||||
const char QUICK_3D_ASSET_IMPORT_DATA_SOURCE_KEY[] = "source_scene";
|
const char QUICK_3D_ASSET_IMPORT_DATA_SOURCE_KEY[] = "source_scene";
|
||||||
const char DEFAULT_ASSET_IMPORT_FOLDER[] = "/asset_imports";
|
const char DEFAULT_ASSET_IMPORT_FOLDER[] = "/asset_imports";
|
||||||
|
|
||||||
|
const char MIME_TYPE_ITEM_LIBRARY_INFO[] = "application/vnd.qtdesignstudio.itemlibraryinfo";
|
||||||
|
const char MIME_TYPE_ASSETS[] = "application/vnd.qtdesignstudio.assets";
|
||||||
|
const char MIME_TYPE_ASSET_IMAGE[] = "application/vnd.qtdesignstudio.asset.image";
|
||||||
|
const char MIME_TYPE_ASSET_FONT[] = "application/vnd.qtdesignstudio.asset.font";
|
||||||
|
const char MIME_TYPE_ASSET_SHADER[] = "application/vnd.qtdesignstudio.asset.shader";
|
||||||
|
const char MIME_TYPE_ASSET_SOUND[] = "application/vnd.qtdesignstudio.asset.sound";
|
||||||
|
const char MIME_TYPE_ASSET_VIDEO[] = "application/vnd.qtdesignstudio.asset.video";
|
||||||
|
const char MIME_TYPE_ASSET_TEXTURE3D[] = "application/vnd.qtdesignstudio.asset.texture3d";
|
||||||
|
const char MIME_TYPE_MODELNODE_LIST[] = "application/vnd.qtdesignstudio.modelnode.list";
|
||||||
|
|
||||||
// Menus
|
// Menus
|
||||||
const char M_VIEW_WORKSPACES[] = "QmlDesigner.Menu.View.Workspaces";
|
const char M_VIEW_WORKSPACES[] = "QmlDesigner.Menu.View.Workspaces";
|
||||||
|
|
||||||
|
@@ -91,6 +91,10 @@ QmlProjectItem *QmlProjectFileFormat::parseProjectFile(const Utils::FilePath &fi
|
|||||||
if (mainFileProperty.isValid())
|
if (mainFileProperty.isValid())
|
||||||
projectItem->setMainFile(mainFileProperty.value.toString());
|
projectItem->setMainFile(mainFileProperty.value.toString());
|
||||||
|
|
||||||
|
const auto mainUiFileProperty = rootNode->property(QLatin1String("mainUiFile"));
|
||||||
|
if (mainUiFileProperty.isValid())
|
||||||
|
projectItem->setMainUiFile(mainUiFileProperty.value.toString());
|
||||||
|
|
||||||
const auto importPathsProperty = rootNode->property(QLatin1String("importPaths"));
|
const auto importPathsProperty = rootNode->property(QLatin1String("importPaths"));
|
||||||
if (importPathsProperty.isValid()) {
|
if (importPathsProperty.isValid()) {
|
||||||
QStringList list = importPathsProperty.value.toStringList();
|
QStringList list = importPathsProperty.value.toStringList();
|
||||||
|
@@ -81,6 +81,9 @@ public:
|
|||||||
QString mainFile() const { return m_mainFile; }
|
QString mainFile() const { return m_mainFile; }
|
||||||
void setMainFile(const QString &mainFilePath) { m_mainFile = mainFilePath; }
|
void setMainFile(const QString &mainFilePath) { m_mainFile = mainFilePath; }
|
||||||
|
|
||||||
|
QString mainUiFile() const { return m_mainUiFile; }
|
||||||
|
void setMainUiFile(const QString &mainUiFilePath) { m_mainUiFile = mainUiFilePath; }
|
||||||
|
|
||||||
bool widgetApp() const { return m_widgetApp; }
|
bool widgetApp() const { return m_widgetApp; }
|
||||||
void setWidgetApp(bool widgetApp) { m_widgetApp = widgetApp; }
|
void setWidgetApp(bool widgetApp) { m_widgetApp = widgetApp; }
|
||||||
|
|
||||||
@@ -107,6 +110,7 @@ protected:
|
|||||||
QStringList m_supportedLanguages;
|
QStringList m_supportedLanguages;
|
||||||
QString m_primaryLanguage;
|
QString m_primaryLanguage;
|
||||||
QString m_mainFile;
|
QString m_mainFile;
|
||||||
|
QString m_mainUiFile;
|
||||||
Utils::EnvironmentItems m_environment;
|
Utils::EnvironmentItems m_environment;
|
||||||
QVector<QmlProjectContentItem *> m_content; // content property
|
QVector<QmlProjectContentItem *> m_content; // content property
|
||||||
bool m_forceFreeType = false;
|
bool m_forceFreeType = false;
|
||||||
|
@@ -118,21 +118,38 @@ QmlProject::QmlProject(const Utils::FilePath &fileName)
|
|||||||
disconnect(m_openFileConnection);
|
disconnect(m_openFileConnection);
|
||||||
|
|
||||||
if (target && success) {
|
if (target && success) {
|
||||||
Utils::FilePaths uiFiles = getUiQmlFilesForFolder(projectDirectory()
|
|
||||||
+ "/content");
|
|
||||||
if (uiFiles.isEmpty())
|
|
||||||
uiFiles = getUiQmlFilesForFolder(projectDirectory());
|
|
||||||
|
|
||||||
if (!uiFiles.isEmpty()) {
|
auto target = activeTarget();
|
||||||
Utils::FilePath currentFile;
|
if (!target)
|
||||||
if (auto cd = Core::EditorManager::currentDocument())
|
return;
|
||||||
currentFile = cd->filePath();
|
|
||||||
|
|
||||||
if (currentFile.isEmpty() || !isKnownFile(currentFile))
|
auto qmlBuildSystem = qobject_cast<QmlProjectManager::QmlBuildSystem *>(
|
||||||
QTimer::singleShot(1000, [uiFiles]() {
|
target->buildSystem());
|
||||||
Core::EditorManager::openEditor(uiFiles.first(),
|
|
||||||
|
const Utils::FilePath mainUiFile = qmlBuildSystem->mainUiFilePath();
|
||||||
|
|
||||||
|
if (mainUiFile.completeSuffix() == "qi.qml" && mainUiFile.exists()) {
|
||||||
|
QTimer::singleShot(1000, [mainUiFile]() {
|
||||||
|
Core::EditorManager::openEditor(mainUiFile,
|
||||||
Utils::Id());
|
Utils::Id());
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
Utils::FilePaths uiFiles = getUiQmlFilesForFolder(projectDirectory()
|
||||||
|
+ "/content");
|
||||||
|
if (uiFiles.isEmpty())
|
||||||
|
uiFiles = getUiQmlFilesForFolder(projectDirectory());
|
||||||
|
|
||||||
|
if (!uiFiles.isEmpty()) {
|
||||||
|
Utils::FilePath currentFile;
|
||||||
|
if (auto cd = Core::EditorManager::currentDocument())
|
||||||
|
currentFile = cd->filePath();
|
||||||
|
|
||||||
|
if (currentFile.isEmpty() || !isKnownFile(currentFile))
|
||||||
|
QTimer::singleShot(1000, [uiFiles]() {
|
||||||
|
Core::EditorManager::openEditor(uiFiles.first(),
|
||||||
|
Utils::Id());
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -236,6 +253,58 @@ void QmlBuildSystem::parseProject(RefreshOptions options)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QmlBuildSystem::setFileSettingInProjectFile(const QString &setting, const Utils::FilePath &mainFilePath, const QString &oldFile)
|
||||||
|
{
|
||||||
|
// make sure to change it also in the qmlproject file
|
||||||
|
const Utils::FilePath qmlProjectFilePath = project()->projectFilePath();
|
||||||
|
Core::FileChangeBlocker fileChangeBlocker(qmlProjectFilePath);
|
||||||
|
const QList<Core::IEditor *> editors = Core::DocumentModel::editorsForFilePath(qmlProjectFilePath);
|
||||||
|
TextEditor::TextDocument *document = nullptr;
|
||||||
|
if (!editors.isEmpty()) {
|
||||||
|
document = qobject_cast<TextEditor::TextDocument*>(editors.first()->document());
|
||||||
|
if (document && document->isModified())
|
||||||
|
if (!Core::DocumentManager::saveDocument(document))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString fileContent;
|
||||||
|
QString error;
|
||||||
|
Utils::TextFileFormat textFileFormat;
|
||||||
|
const QTextCodec *codec = QTextCodec::codecForName("UTF-8"); // qml files are defined to be utf-8
|
||||||
|
if (Utils::TextFileFormat::readFile(qmlProjectFilePath, codec, &fileContent, &textFileFormat, &error)
|
||||||
|
!= Utils::TextFileFormat::ReadSuccess) {
|
||||||
|
qWarning() << "Failed to read file" << qmlProjectFilePath << ":" << error;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString settingQmlCode = setting + ":";
|
||||||
|
|
||||||
|
QDir projectDir = project()->projectFilePath().toDir();
|
||||||
|
projectDir.cdUp();
|
||||||
|
const QString relativePath = projectDir.relativeFilePath(mainFilePath.toString());
|
||||||
|
|
||||||
|
if (fileContent.indexOf(settingQmlCode) < 0) {
|
||||||
|
QString addedText = QString("\n %1 \"%2\"\n").arg(settingQmlCode).arg(relativePath);
|
||||||
|
auto index = fileContent.lastIndexOf("}");
|
||||||
|
fileContent.insert(index, addedText);
|
||||||
|
} else {
|
||||||
|
QString originalFileName = oldFile;
|
||||||
|
originalFileName.replace(".", "\\.");
|
||||||
|
const QRegularExpression expression(QString("%1\\s*\"(%2)\"").arg(settingQmlCode).arg(originalFileName));
|
||||||
|
|
||||||
|
const QRegularExpressionMatch match = expression.match(fileContent);
|
||||||
|
|
||||||
|
fileContent.replace(match.capturedStart(1),
|
||||||
|
match.capturedLength(1),
|
||||||
|
relativePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!textFileFormat.writeFile(qmlProjectFilePath, fileContent, &error))
|
||||||
|
qWarning() << "Failed to write file" << qmlProjectFilePath << ":" << error;
|
||||||
|
|
||||||
|
refresh(Everything);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void QmlBuildSystem::refresh(RefreshOptions options)
|
void QmlBuildSystem::refresh(RefreshOptions options)
|
||||||
{
|
{
|
||||||
ParseGuard guard = guardParsingRun();
|
ParseGuard guard = guardParsingRun();
|
||||||
@@ -266,11 +335,68 @@ QString QmlBuildSystem::mainFile() const
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString QmlBuildSystem::mainUiFile() const
|
||||||
|
{
|
||||||
|
if (m_projectItem)
|
||||||
|
return m_projectItem->mainUiFile();
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
Utils::FilePath QmlBuildSystem::mainFilePath() const
|
Utils::FilePath QmlBuildSystem::mainFilePath() const
|
||||||
{
|
{
|
||||||
return projectDirectory().pathAppended(mainFile());
|
return projectDirectory().pathAppended(mainFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Utils::FilePath QmlBuildSystem::mainUiFilePath() const
|
||||||
|
{
|
||||||
|
return projectDirectory().pathAppended(mainUiFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlBuildSystem::setMainFileInProjectFile(const Utils::FilePath &newMainFilePath)
|
||||||
|
{
|
||||||
|
|
||||||
|
return setFileSettingInProjectFile("mainFile", newMainFilePath, mainFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlBuildSystem::setMainUiFileInProjectFile(const Utils::FilePath &newMainUiFilePath)
|
||||||
|
{
|
||||||
|
return setMainUiFileInMainFile(newMainUiFilePath)
|
||||||
|
&& setFileSettingInProjectFile("mainUiFile", newMainUiFilePath, mainUiFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlBuildSystem::setMainUiFileInMainFile(const Utils::FilePath &newMainUiFilePath)
|
||||||
|
{
|
||||||
|
Core::FileChangeBlocker fileChangeBlocker(mainFilePath());
|
||||||
|
const QList<Core::IEditor *> editors = Core::DocumentModel::editorsForFilePath(mainFilePath());
|
||||||
|
TextEditor::TextDocument *document = nullptr;
|
||||||
|
if (!editors.isEmpty()) {
|
||||||
|
document = qobject_cast<TextEditor::TextDocument*>(editors.first()->document());
|
||||||
|
if (document && document->isModified())
|
||||||
|
if (!Core::DocumentManager::saveDocument(document))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString fileContent;
|
||||||
|
QString error;
|
||||||
|
Utils::TextFileFormat textFileFormat;
|
||||||
|
const QTextCodec *codec = QTextCodec::codecForName("UTF-8"); // qml files are defined to be utf-8
|
||||||
|
if (Utils::TextFileFormat::readFile(mainFilePath(), codec, &fileContent, &textFileFormat, &error)
|
||||||
|
!= Utils::TextFileFormat::ReadSuccess) {
|
||||||
|
qWarning() << "Failed to read file" << mainFilePath() << ":" << error;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString currentMain = QString("%1 {").arg(mainUiFilePath().baseName());
|
||||||
|
const QString newMain = QString("%1 {").arg(newMainUiFilePath.baseName());
|
||||||
|
|
||||||
|
if (fileContent.contains(currentMain))
|
||||||
|
fileContent.replace(currentMain, newMain);
|
||||||
|
|
||||||
|
if (!textFileFormat.writeFile(mainFilePath(), fileContent, &error))
|
||||||
|
qWarning() << "Failed to write file" << mainFilePath() << ":" << error;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool QmlBuildSystem::qtForMCUs() const
|
bool QmlBuildSystem::qtForMCUs() const
|
||||||
{
|
{
|
||||||
if (m_projectItem)
|
if (m_projectItem)
|
||||||
@@ -646,43 +772,10 @@ bool QmlBuildSystem::deleteFiles(Node *context, const FilePaths &filePaths)
|
|||||||
bool QmlBuildSystem::renameFile(Node * context, const FilePath &oldFilePath, const FilePath &newFilePath)
|
bool QmlBuildSystem::renameFile(Node * context, const FilePath &oldFilePath, const FilePath &newFilePath)
|
||||||
{
|
{
|
||||||
if (dynamic_cast<QmlProjectNode *>(context)) {
|
if (dynamic_cast<QmlProjectNode *>(context)) {
|
||||||
if (oldFilePath.endsWith(mainFile())) {
|
if (oldFilePath.endsWith(mainFile()))
|
||||||
setMainFile(newFilePath.toString());
|
return setMainFileInProjectFile(newFilePath);
|
||||||
|
if (oldFilePath.endsWith(mainUiFile()))
|
||||||
// make sure to change it also in the qmlproject file
|
return setMainUiFileInProjectFile(newFilePath);
|
||||||
const Utils::FilePath qmlProjectFilePath = project()->projectFilePath();
|
|
||||||
Core::FileChangeBlocker fileChangeBlocker(qmlProjectFilePath);
|
|
||||||
const QList<Core::IEditor *> editors = Core::DocumentModel::editorsForFilePath(qmlProjectFilePath);
|
|
||||||
TextEditor::TextDocument *document = nullptr;
|
|
||||||
if (!editors.isEmpty()) {
|
|
||||||
document = qobject_cast<TextEditor::TextDocument*>(editors.first()->document());
|
|
||||||
if (document && document->isModified())
|
|
||||||
if (!Core::DocumentManager::saveDocument(document))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString fileContent;
|
|
||||||
QString error;
|
|
||||||
Utils::TextFileFormat textFileFormat;
|
|
||||||
const QTextCodec *codec = QTextCodec::codecForName("UTF-8"); // qml files are defined to be utf-8
|
|
||||||
if (Utils::TextFileFormat::readFile(qmlProjectFilePath, codec, &fileContent, &textFileFormat, &error)
|
|
||||||
!= Utils::TextFileFormat::ReadSuccess) {
|
|
||||||
qWarning() << "Failed to read file" << qmlProjectFilePath << ":" << error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// find the mainFile and do the file name with brackets in a capture group and mask the . with \.
|
|
||||||
QString originalFileName = oldFilePath.fileName();
|
|
||||||
originalFileName.replace(".", "\\.");
|
|
||||||
const QRegularExpression expression(QString("mainFile:\\s*\"(%1)\"").arg(originalFileName));
|
|
||||||
const QRegularExpressionMatch match = expression.match(fileContent);
|
|
||||||
|
|
||||||
fileContent.replace(match.capturedStart(1), match.capturedLength(1), newFilePath.fileName());
|
|
||||||
|
|
||||||
if (!textFileFormat.writeFile(qmlProjectFilePath, fileContent, &error))
|
|
||||||
qWarning() << "Failed to write file" << qmlProjectFilePath << ":" << error;
|
|
||||||
|
|
||||||
refresh(Everything);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -77,7 +77,13 @@ public:
|
|||||||
|
|
||||||
Utils::FilePath canonicalProjectDir() const;
|
Utils::FilePath canonicalProjectDir() const;
|
||||||
QString mainFile() const;
|
QString mainFile() const;
|
||||||
|
QString mainUiFile() const;
|
||||||
Utils::FilePath mainFilePath() const;
|
Utils::FilePath mainFilePath() const;
|
||||||
|
Utils::FilePath mainUiFilePath() const;
|
||||||
|
|
||||||
|
bool setMainFileInProjectFile(const Utils::FilePath &newMainFilePath);
|
||||||
|
bool setMainUiFileInProjectFile(const Utils::FilePath &newMainUiFilePath);
|
||||||
|
bool setMainUiFileInMainFile(const Utils::FilePath &newMainUiFilePath);
|
||||||
|
|
||||||
bool qtForMCUs() const;
|
bool qtForMCUs() const;
|
||||||
bool qt6Project() const;
|
bool qt6Project() const;
|
||||||
@@ -116,6 +122,10 @@ public:
|
|||||||
void parseProject(RefreshOptions options);
|
void parseProject(RefreshOptions options);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool setFileSettingInProjectFile(const QString &setting,
|
||||||
|
const Utils::FilePath &mainFilePath,
|
||||||
|
const QString &oldFile);
|
||||||
|
|
||||||
std::unique_ptr<QmlProjectItem> m_projectItem;
|
std::unique_ptr<QmlProjectItem> m_projectItem;
|
||||||
Utils::FilePath m_canonicalProjectDir;
|
Utils::FilePath m_canonicalProjectDir;
|
||||||
bool m_blockFilesUpdate = false;
|
bool m_blockFilesUpdate = false;
|
||||||
|
@@ -30,16 +30,23 @@
|
|||||||
#include "qmlprojectrunconfiguration.h"
|
#include "qmlprojectrunconfiguration.h"
|
||||||
#include "projectfilecontenttools.h"
|
#include "projectfilecontenttools.h"
|
||||||
|
|
||||||
|
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||||
|
#include <coreplugin/actionmanager/actionmanager.h>
|
||||||
#include <coreplugin/coreconstants.h>
|
#include <coreplugin/coreconstants.h>
|
||||||
#include <coreplugin/designmode.h>
|
#include <coreplugin/designmode.h>
|
||||||
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
#include <coreplugin/fileiconprovider.h>
|
#include <coreplugin/fileiconprovider.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/messagebox.h>
|
#include <coreplugin/messagebox.h>
|
||||||
#include <coreplugin/modemanager.h>
|
#include <coreplugin/modemanager.h>
|
||||||
|
|
||||||
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
#include <projectexplorer/projectmanager.h>
|
#include <projectexplorer/projectmanager.h>
|
||||||
|
#include <projectexplorer/projectnodes.h>
|
||||||
|
#include <projectexplorer/projecttree.h>
|
||||||
#include <projectexplorer/runcontrol.h>
|
#include <projectexplorer/runcontrol.h>
|
||||||
#include <projectexplorer/session.h>
|
#include <projectexplorer/session.h>
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
|
||||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||||
|
|
||||||
@@ -54,11 +61,12 @@
|
|||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
#include <utils/qtcprocess.h>
|
#include <utils/qtcprocess.h>
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QPointer>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QPointer>
|
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
|
|
||||||
@@ -230,19 +238,124 @@ void QmlProjectPlugin::openInQDSWithProject(const Utils::FilePath &filePath)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QmlBuildSystem *qmlBuildSystemforFileNode(const FileNode *fileNode)
|
||||||
|
{
|
||||||
|
if (!fileNode)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (QmlProject *qmlProject = qobject_cast<QmlProject*>(fileNode->getProject())) {
|
||||||
|
auto target = qmlProject->activeTarget();
|
||||||
|
if (!target)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return qobject_cast<QmlProjectManager::QmlBuildSystem *>(target->buildSystem());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool QmlProjectPlugin::initialize(const QStringList &, QString *errorMessage)
|
bool QmlProjectPlugin::initialize(const QStringList &, QString *errorMessage)
|
||||||
{
|
{
|
||||||
Q_UNUSED(errorMessage)
|
Q_UNUSED(errorMessage)
|
||||||
|
|
||||||
d = new QmlProjectPluginPrivate;
|
d = new QmlProjectPluginPrivate;
|
||||||
|
|
||||||
if (!qmlDesignerEnabled()) {
|
if (!qmlDesignerEnabled())
|
||||||
initializeQmlLandingPage();
|
initializeQmlLandingPage();
|
||||||
}
|
|
||||||
|
|
||||||
ProjectManager::registerProjectType<QmlProject>(QmlJSTools::Constants::QMLPROJECT_MIMETYPE);
|
ProjectManager::registerProjectType<QmlProject>(QmlJSTools::Constants::QMLPROJECT_MIMETYPE);
|
||||||
Core::FileIconProvider::registerIconOverlayForSuffix(":/qmlproject/images/qmlproject.png",
|
Core::FileIconProvider::registerIconOverlayForSuffix(":/qmlproject/images/qmlproject.png",
|
||||||
"qmlproject");
|
"qmlproject");
|
||||||
|
|
||||||
|
if (QmlProject::isQtDesignStudio()) {
|
||||||
|
Core::ActionContainer *menu = Core::ActionManager::actionContainer(
|
||||||
|
ProjectExplorer::Constants::M_FILECONTEXT);
|
||||||
|
QAction *mainfileAction = new QAction(tr("Set as main .qml file"), this);
|
||||||
|
mainfileAction->setEnabled(false);
|
||||||
|
|
||||||
|
connect(mainfileAction, &QAction::triggered, this, []() {
|
||||||
|
const Node *currentNode = ProjectTree::currentNode();
|
||||||
|
if (!currentNode || !currentNode->asFileNode()
|
||||||
|
|| currentNode->asFileNode()->fileType() != FileType::QML)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const Utils::FilePath file = currentNode->filePath();
|
||||||
|
|
||||||
|
QmlBuildSystem *buildSystem = qmlBuildSystemforFileNode(currentNode->asFileNode());
|
||||||
|
if (buildSystem)
|
||||||
|
buildSystem->setMainFileInProjectFile(file);
|
||||||
|
});
|
||||||
|
|
||||||
|
menu->addAction(Core::ActionManager::registerAction(
|
||||||
|
mainfileAction,
|
||||||
|
"QmlProject.setMainFile",
|
||||||
|
Core::Context(ProjectExplorer::Constants::C_PROJECT_TREE)),
|
||||||
|
ProjectExplorer::Constants::G_FILE_OTHER);
|
||||||
|
mainfileAction->setVisible(false);
|
||||||
|
connect(ProjectTree::instance(),
|
||||||
|
&ProjectTree::currentNodeChanged,
|
||||||
|
mainfileAction,
|
||||||
|
[mainfileAction](Node *node) {
|
||||||
|
const FileNode *fileNode = node ? node->asFileNode() : nullptr;
|
||||||
|
|
||||||
|
const bool isVisible = fileNode && fileNode->fileType() == FileType::QML
|
||||||
|
&& fileNode->filePath().completeSuffix() == "qml";
|
||||||
|
|
||||||
|
mainfileAction->setVisible(isVisible);
|
||||||
|
|
||||||
|
if (!isVisible)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QmlBuildSystem *buildSystem = qmlBuildSystemforFileNode(fileNode);
|
||||||
|
|
||||||
|
if (buildSystem)
|
||||||
|
mainfileAction->setEnabled(buildSystem->mainFilePath()
|
||||||
|
!= fileNode->filePath());
|
||||||
|
});
|
||||||
|
|
||||||
|
QAction *mainUifileAction = new QAction(tr("Set as main .ui.qml file"), this);
|
||||||
|
mainUifileAction->setEnabled(false);
|
||||||
|
|
||||||
|
connect(mainUifileAction, &QAction::triggered, this, []() {
|
||||||
|
const Node *currentNode = ProjectTree::currentNode();
|
||||||
|
if (!currentNode || !currentNode->asFileNode()
|
||||||
|
|| currentNode->asFileNode()->fileType() != FileType::QML)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const Utils::FilePath file = currentNode->filePath();
|
||||||
|
|
||||||
|
QmlBuildSystem *buildSystem = qmlBuildSystemforFileNode(currentNode->asFileNode());
|
||||||
|
if (buildSystem)
|
||||||
|
buildSystem->setMainUiFileInProjectFile(file);
|
||||||
|
});
|
||||||
|
|
||||||
|
menu->addAction(Core::ActionManager::registerAction(
|
||||||
|
mainUifileAction,
|
||||||
|
"QmlProject.setMainUIFile",
|
||||||
|
Core::Context(ProjectExplorer::Constants::C_PROJECT_TREE)),
|
||||||
|
ProjectExplorer::Constants::G_FILE_OTHER);
|
||||||
|
mainUifileAction->setVisible(false);
|
||||||
|
connect(ProjectTree::instance(),
|
||||||
|
&ProjectTree::currentNodeChanged,
|
||||||
|
mainUifileAction,
|
||||||
|
[mainUifileAction](Node *node) {
|
||||||
|
const FileNode *fileNode = node ? node->asFileNode() : nullptr;
|
||||||
|
const bool isVisible = fileNode && fileNode->fileType() == FileType::QML
|
||||||
|
&& fileNode->filePath().completeSuffix() == "ui.qml";
|
||||||
|
|
||||||
|
mainUifileAction->setVisible(isVisible);
|
||||||
|
|
||||||
|
if (!isVisible)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QmlBuildSystem *buildSystem = qmlBuildSystemforFileNode(fileNode);
|
||||||
|
if (buildSystem)
|
||||||
|
mainUifileAction->setEnabled(buildSystem->mainUiFilePath()
|
||||||
|
!= fileNode->filePath());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -196,17 +196,6 @@ void FileDownloader::probeUrl()
|
|||||||
});
|
});
|
||||||
|
|
||||||
QNetworkReply::connect(reply, &QNetworkReply::finished, this, [this, reply]() {
|
QNetworkReply::connect(reply, &QNetworkReply::finished, this, [this, reply]() {
|
||||||
QQmlData *data = QQmlData::get(this, false);
|
|
||||||
if (!data) {
|
|
||||||
qDebug() << Q_FUNC_INFO << "FileDownloader is nullptr.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (QQmlData::wasDeleted(this)) {
|
|
||||||
qDebug() << Q_FUNC_INFO << "FileDownloader was deleted.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reply->error())
|
if (reply->error())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -383,7 +372,6 @@ void FileExtractor::extract()
|
|||||||
|
|
||||||
Utils::Archive *archive = new Utils::Archive(m_sourceFile, m_targetPath);
|
Utils::Archive *archive = new Utils::Archive(m_sourceFile, m_targetPath);
|
||||||
QTC_ASSERT(archive->isValid(), delete archive; return);
|
QTC_ASSERT(archive->isValid(), delete archive; return);
|
||||||
archive->setParent(this);
|
|
||||||
|
|
||||||
m_timer.start();
|
m_timer.start();
|
||||||
qint64 bytesBefore = QStorageInfo(m_targetPath.toFileInfo().dir()).bytesAvailable();
|
qint64 bytesBefore = QStorageInfo(m_targetPath.toFileInfo().dir()).bytesAvailable();
|
||||||
@@ -423,7 +411,8 @@ void FileExtractor::extract()
|
|||||||
emit detailedTextChanged();
|
emit detailedTextChanged();
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(archive, &Utils::Archive::finished, this, [this](bool ret) {
|
QObject::connect(archive, &Utils::Archive::finished, this, [this, archive](bool ret) {
|
||||||
|
delete archive;
|
||||||
m_finished = ret;
|
m_finished = ret;
|
||||||
m_timer.stop();
|
m_timer.stop();
|
||||||
|
|
||||||
@@ -436,3 +425,76 @@ void FileExtractor::extract()
|
|||||||
});
|
});
|
||||||
archive->unarchive();
|
archive->unarchive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Utils::FilePath tempFilePath()
|
||||||
|
{
|
||||||
|
QStandardPaths::StandardLocation location = QStandardPaths::CacheLocation;
|
||||||
|
|
||||||
|
return Utils::FilePath::fromString(QStandardPaths::writableLocation(location))
|
||||||
|
.pathAppended("QtDesignStudio");
|
||||||
|
}
|
||||||
|
|
||||||
|
DataModelDownloader::DataModelDownloader(QObject * /* parent */)
|
||||||
|
{
|
||||||
|
auto fileInfo = targetFolder().toFileInfo();
|
||||||
|
m_birthTime = fileInfo.birthTime();
|
||||||
|
m_exists = fileInfo.exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataModelDownloader::start()
|
||||||
|
{
|
||||||
|
m_fileDownloader.setUrl(QUrl::fromUserInput(
|
||||||
|
"https://download.qt.io/learning/examples/qtdesignstudio/dataImports.zip"));
|
||||||
|
|
||||||
|
connect(&m_fileDownloader, &FileDownloader::availableChanged, this, [this]() {
|
||||||
|
|
||||||
|
m_available = m_fileDownloader.available();
|
||||||
|
|
||||||
|
emit availableChanged();
|
||||||
|
|
||||||
|
if (!m_available) {
|
||||||
|
qWarning() << m_fileDownloader.url() << "failed to download";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_forceDownload && m_fileDownloader.lastModified() < m_birthTime)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_fileDownloader.start();
|
||||||
|
connect(&m_fileDownloader, &FileDownloader::finishedChanged, this, [this]() {
|
||||||
|
if (m_fileDownloader.finished()) {
|
||||||
|
const Utils::FilePath archiveFile = Utils::FilePath::fromString(
|
||||||
|
m_fileDownloader.tempFile());
|
||||||
|
QTC_ASSERT(Utils::Archive::supportsFile(archiveFile), return );
|
||||||
|
auto archive = new Utils::Archive(archiveFile, tempFilePath());
|
||||||
|
QTC_ASSERT(archive->isValid(), delete archive; return );
|
||||||
|
QObject::connect(archive, &Utils::Archive::finished, this, [this, archive](bool ret) {
|
||||||
|
QTC_CHECK(ret);
|
||||||
|
delete archive;
|
||||||
|
emit finished();
|
||||||
|
});
|
||||||
|
archive->unarchive();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DataModelDownloader::exists() const
|
||||||
|
{
|
||||||
|
return m_exists;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DataModelDownloader::available() const
|
||||||
|
{
|
||||||
|
return m_available;
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils::FilePath DataModelDownloader::targetFolder() const
|
||||||
|
{
|
||||||
|
return Utils::FilePath::fromUserInput(tempFilePath().toString() + "/" + "dataImports");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataModelDownloader::setForceDownload(bool b)
|
||||||
|
{
|
||||||
|
m_forceDownload = b;
|
||||||
|
}
|
||||||
|
@@ -154,5 +154,29 @@ private:
|
|||||||
int m_progress = 0;
|
int m_progress = 0;
|
||||||
QFile m_tempFile;
|
QFile m_tempFile;
|
||||||
QDateTime m_lastModified;
|
QDateTime m_lastModified;
|
||||||
bool m_available;
|
bool m_available = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DataModelDownloader : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit DataModelDownloader(QObject *parent = nullptr);
|
||||||
|
void start();
|
||||||
|
bool exists() const;
|
||||||
|
bool available() const;
|
||||||
|
Utils::FilePath targetFolder() const;
|
||||||
|
void setForceDownload(bool b);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finished();
|
||||||
|
void availableChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
FileDownloader m_fileDownloader;
|
||||||
|
QDateTime m_birthTime;
|
||||||
|
bool m_exists = false;
|
||||||
|
bool m_available = false;
|
||||||
|
bool m_forceDownload = false;
|
||||||
};
|
};
|
||||||
|
@@ -447,6 +447,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QQuickWidget *m_modeWidget = nullptr;
|
QQuickWidget *m_modeWidget = nullptr;
|
||||||
|
DataModelDownloader *m_dataModelDownloader = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
void StudioWelcomePlugin::closeSplashScreen()
|
void StudioWelcomePlugin::closeSplashScreen()
|
||||||
@@ -596,6 +597,28 @@ WelcomeMode::WelcomeMode()
|
|||||||
{
|
{
|
||||||
setDisplayName(tr("Welcome"));
|
setDisplayName(tr("Welcome"));
|
||||||
|
|
||||||
|
const QString welcomePagePath = Core::ICore::resourcePath("qmldesigner/welcomepage").toString();
|
||||||
|
|
||||||
|
m_dataModelDownloader = new DataModelDownloader(this);
|
||||||
|
if (!m_dataModelDownloader->exists()) { //Fallback if data cannot be downloaded
|
||||||
|
Utils::FileUtils::copyRecursively(Utils::FilePath::fromUserInput(welcomePagePath
|
||||||
|
+ "/dataImports"),
|
||||||
|
m_dataModelDownloader->targetFolder());
|
||||||
|
m_dataModelDownloader->setForceDownload(true);
|
||||||
|
}
|
||||||
|
Utils::FilePath readme = Utils::FilePath::fromUserInput(welcomePagePath
|
||||||
|
+ "/dataImports/readme.txt");
|
||||||
|
|
||||||
|
if (!readme.exists()) // Only downloads contain the readme
|
||||||
|
m_dataModelDownloader->setForceDownload(true);
|
||||||
|
|
||||||
|
m_dataModelDownloader->start();
|
||||||
|
|
||||||
|
connect(m_dataModelDownloader, &DataModelDownloader::finished, this, [this](){
|
||||||
|
auto source = m_modeWidget->source();
|
||||||
|
m_modeWidget->engine()->clearComponentCache();
|
||||||
|
m_modeWidget->setSource(source);
|
||||||
|
});
|
||||||
const Utils::Icon FLAT({{":/studiowelcome/images/mode_welcome_mask.png",
|
const Utils::Icon FLAT({{":/studiowelcome/images/mode_welcome_mask.png",
|
||||||
Utils::Theme::IconsBaseColor}});
|
Utils::Theme::IconsBaseColor}});
|
||||||
const Utils::Icon FLAT_ACTIVE({{":/studiowelcome/images/mode_welcome_mask.png",
|
const Utils::Icon FLAT_ACTIVE({{":/studiowelcome/images/mode_welcome_mask.png",
|
||||||
@@ -640,8 +663,8 @@ WelcomeMode::WelcomeMode()
|
|||||||
|
|
||||||
m_modeWidget->engine()->addImportPath(Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources/imports").toString());
|
m_modeWidget->engine()->addImportPath(Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources/imports").toString());
|
||||||
|
|
||||||
const QString welcomePagePath = Core::ICore::resourcePath("qmldesigner/welcomepage").toString();
|
|
||||||
m_modeWidget->engine()->addImportPath(welcomePagePath + "/imports");
|
m_modeWidget->engine()->addImportPath(welcomePagePath + "/imports");
|
||||||
|
m_modeWidget->engine()->addImportPath(m_dataModelDownloader->targetFolder().toString());
|
||||||
m_modeWidget->setSource(QUrl::fromLocalFile(welcomePagePath + "/main.qml"));
|
m_modeWidget->setSource(QUrl::fromLocalFile(welcomePagePath + "/main.qml"));
|
||||||
|
|
||||||
QShortcut *updateShortcut = nullptr;
|
QShortcut *updateShortcut = nullptr;
|
||||||
|
@@ -4,29 +4,7 @@ Squish tests inside this folder have several prerequisites to get them running.
|
|||||||
|
|
||||||
First - and most important - you have to own a valid Squish license. At least Squish 6.0 is required.
|
First - and most important - you have to own a valid Squish license. At least Squish 6.0 is required.
|
||||||
|
|
||||||
Second - some of the test suites/test cases expect a build of Qt 4.8.7 to be available:
|
Second - some of the test suites/test cases expect Qt versions to be installed in their default
|
||||||
[ this is optional and if Qt4 is not available some Qt5 will be tried to use instead ]
|
|
||||||
1. Download the source code from:
|
|
||||||
* Windows: https://download.qt.io/archive/qt/4.8/4.8.7/qt-everywhere-opensource-src-4.8.7.zip
|
|
||||||
* Other: https://download.qt.io/archive/qt/4.8/4.8.7/qt-everywhere-opensource-src-4.8.7.tar.gz
|
|
||||||
2. Extract the contents of the archive's directory qt-everywhere-opensource-src-4.8.7 to:
|
|
||||||
* Windows: C:\Qt\Qt4.8.7
|
|
||||||
* Other: $HOME/Qt4.8.7
|
|
||||||
3. Apply the changes from patch.txt next to this README.
|
|
||||||
4. In the directory you extracted the sources to, configure Qt:
|
|
||||||
* Windows (MSVC2013 32 bit):
|
|
||||||
.\configure.exe -opensource -developer-build -confirm-license -debug-and-release -nomake tests -nomake examples -nomake demos -no-webkit -no-phonon
|
|
||||||
* Linux (gcc < 6):
|
|
||||||
./configure -opensource -developer-build -confirm-license -debug-and-release -nomake tests -nomake examples -nomake demos -no-webkit -no-phonon
|
|
||||||
* macOS:
|
|
||||||
./configure -opensource -developer-build -confirm-license -debug-and-release -nomake tests -nomake examples -nomake demos -no-webkit -no-phonon -sdk <PATH_TO_INSTALLED_MACOSX_SDK>
|
|
||||||
5. Make:
|
|
||||||
* Windows (do not use jom):
|
|
||||||
nmake
|
|
||||||
* Other:
|
|
||||||
make -j<number of available cores>
|
|
||||||
|
|
||||||
Third - some of the test suites/test cases expect Qt versions to be installed in their default
|
|
||||||
locations. On Linux/macOS this is ~/Qt5.x.1 and on Windows this is C:\Qt\Qt5.x.1. It's easiest to
|
locations. On Linux/macOS this is ~/Qt5.x.1 and on Windows this is C:\Qt\Qt5.x.1. It's easiest to
|
||||||
use installations of the official opensource Qt packages. Just install the Qt version for the
|
use installations of the official opensource Qt packages. Just install the Qt version for the
|
||||||
respective toolchain with the components (if available):
|
respective toolchain with the components (if available):
|
||||||
@@ -50,7 +28,7 @@ Qt 5.4.1 (gcc)
|
|||||||
Qt 5.10.1 (MSVC2015, 32 bit)
|
Qt 5.10.1 (MSVC2015, 32 bit)
|
||||||
Qt 5.14.1 (MSVC2017, 64 bit)
|
Qt 5.14.1 (MSVC2017, 64 bit)
|
||||||
|
|
||||||
Fourth - you'll have to provide some additional repositories.
|
Third - you'll have to provide some additional repositories.
|
||||||
These additional repositories are located inside ~/squish-data or C:\Users\<user>\squish-data (depending on the OS you're on).
|
These additional repositories are located inside ~/squish-data or C:\Users\<user>\squish-data (depending on the OS you're on).
|
||||||
You can also just provide them inside a different folder and specify the folder with the environment variable SYSTEST_SRCPATH.
|
You can also just provide them inside a different folder and specify the folder with the environment variable SYSTEST_SRCPATH.
|
||||||
This folder must contain the following:
|
This folder must contain the following:
|
||||||
@@ -58,12 +36,12 @@ This folder must contain the following:
|
|||||||
* a subfolder called 'creator-test-data'
|
* a subfolder called 'creator-test-data'
|
||||||
* a speedcrunch 0.11 repository (or source copy) inside 'creator-test-data' named 'speedcrunch'
|
* a speedcrunch 0.11 repository (or source copy) inside 'creator-test-data' named 'speedcrunch'
|
||||||
|
|
||||||
Fifth - you'll have to make sure that some needed tools are available (no matter on which OS you're on).
|
Fourth - you'll have to make sure that some needed tools are available (no matter on which OS you're on).
|
||||||
* cmake 3.14 or newer
|
* cmake 3.14 or newer
|
||||||
* wget or curl, capable of HTTPS
|
* wget or curl, capable of HTTPS
|
||||||
Normally it should be okay to just install them as usual and add their executables' path(s) to the PATH variable.
|
Normally it should be okay to just install them as usual and add their executables' path(s) to the PATH variable.
|
||||||
|
|
||||||
Sixth - Qt Creator must be built on a Qt without Qt WebEngine or Qt WebKit.
|
Fifth - Qt Creator must be built on a Qt without Qt WebEngine or Qt WebKit.
|
||||||
|
|
||||||
On macOS make sure you are using the correct keyboard layout to avoid problems when using keyboard interaction. Tested and known to be
|
On macOS make sure you are using the correct keyboard layout to avoid problems when using keyboard interaction. Tested and known to be
|
||||||
working would be 'U.S. International - PC', while pure 'U.S.' had problems.
|
working would be 'U.S. International - PC', while pure 'U.S.' had problems.
|
||||||
|
@@ -4,31 +4,6 @@
|
|||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>Profile.0</variable>
|
<variable>Profile.0</variable>
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
|
||||||
<valuemap type="QVariantMap" key="PE.Profile.Data">
|
|
||||||
<value type="QString" key="Android.GdbServer.Information"></value>
|
|
||||||
<value type="QString" key="Debugger.Information">{70e26273-2c0b-4534-bbc0-eb6ca670821a}</value>
|
|
||||||
<value type="QString" key="PE.Profile.Device">{7c5a3673-e300-4286-9666-0f86d3e3dc38}</value>
|
|
||||||
<value type="QByteArray" key="PE.Profile.DeviceType">GenericLinuxOsType</value>
|
|
||||||
<value type="QString" key="PE.Profile.SysRoot"></value>
|
|
||||||
<value type="QString" key="PE.Profile.ToolChain">ProjectExplorer.ToolChain.Gcc:{c3f59b87-6997-4bd8-8067-ee04dc536371}</value>
|
|
||||||
<valuemap type="QVariantMap" key="PE.Profile.ToolChains">
|
|
||||||
<value type="QByteArray" key="C">{461bb8dc-22ff-461f-82fe-ebe8b21b697f}</value>
|
|
||||||
<value type="QString" key="Cxx">ProjectExplorer.ToolChain.Gcc:{c3f59b87-6997-4bd8-8067-ee04dc536371}</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="QString" key="QtPM4.mkSpecInformation"></value>
|
|
||||||
<value type="int" key="QtSupport.QtInformation">2</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="QString" key="PE.Profile.Icon">:///DESKTOP///</value>
|
|
||||||
<value type="QString" key="PE.Profile.Id">{f16848fc-b615-43b5-b0cc-16a9f57fb573}</value>
|
|
||||||
<valuelist type="QVariantList" key="PE.Profile.MutableInfo"/>
|
|
||||||
<value type="QString" key="PE.Profile.Name">Embedded Linux</value>
|
|
||||||
<value type="bool" key="PE.Profile.SDK">false</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>Profile.1</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
||||||
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
|
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
|
||||||
@@ -55,32 +30,7 @@
|
|||||||
</valuemap>
|
</valuemap>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>Profile.2</variable>
|
<variable>Profile.1</variable>
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
|
||||||
<valuemap type="QVariantMap" key="PE.Profile.Data">
|
|
||||||
<value type="QString" key="Android.GdbServer.Information"></value>
|
|
||||||
<value type="QString" key="Debugger.Information">{2f514661-b9f7-4f83-8822-a9a9d0699600}</value>
|
|
||||||
<value type="QString" key="PE.Profile.Device">Desktop Device</value>
|
|
||||||
<value type="QByteArray" key="PE.Profile.DeviceType">Desktop</value>
|
|
||||||
<value type="QString" key="PE.Profile.SysRoot"></value>
|
|
||||||
<value type="QString" key="PE.Profile.ToolChain">ProjectExplorer.ToolChain.Gcc:{c3f59b87-6997-4bd8-8067-ee04dc536371}</value>
|
|
||||||
<valuemap type="QVariantMap" key="PE.Profile.ToolChains">
|
|
||||||
<value type="QByteArray" key="C">{461bb8dc-22ff-461f-82fe-ebe8b21b697f}</value>
|
|
||||||
<value type="QString" key="Cxx">ProjectExplorer.ToolChain.Gcc:{c3f59b87-6997-4bd8-8067-ee04dc536371}</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="QString" key="QtPM4.mkSpecInformation"></value>
|
|
||||||
<value type="int" key="QtSupport.QtInformation">2</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="QString" key="PE.Profile.Icon">:///DESKTOP///</value>
|
|
||||||
<value type="QString" key="PE.Profile.Id">{1dcb5509-1670-470d-80a5-8a988f36e4e2}</value>
|
|
||||||
<valuelist type="QVariantList" key="PE.Profile.MutableInfo"/>
|
|
||||||
<value type="QString" key="PE.Profile.Name">Desktop 4.8.7 default</value>
|
|
||||||
<value type="bool" key="PE.Profile.SDK">false</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>Profile.3</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
||||||
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
|
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
|
||||||
@@ -108,7 +58,7 @@
|
|||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>Profile.Count</variable>
|
<variable>Profile.Count</variable>
|
||||||
<value type="int">4</value>
|
<value type="int">2</value>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>Profile.Default</variable>
|
<variable>Profile.Default</variable>
|
||||||
|
@@ -4,16 +4,6 @@
|
|||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>QtVersion.0</variable>
|
<variable>QtVersion.0</variable>
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="int" key="Id">2</value>
|
|
||||||
<value type="QString" key="Name">Desktop Qt 4.8 for GCC</value>
|
|
||||||
<value type="QString" key="QMakePath">~/Qt4.8.7/bin/qmake</value>
|
|
||||||
<value type="QString" key="QtVersion.Type">Qt4ProjectManager.QtVersion.Desktop</value>
|
|
||||||
<value type="bool" key="isAutodetected">false</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>QtVersion.1</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="int" key="Id">9</value>
|
<value type="int" key="Id">9</value>
|
||||||
<value type="QString" key="Name">Qt %{Qt:Version} (SQUISH_DEFAULT_COMPILER)</value>
|
<value type="QString" key="Name">Qt %{Qt:Version} (SQUISH_DEFAULT_COMPILER)</value>
|
||||||
@@ -23,7 +13,7 @@
|
|||||||
</valuemap>
|
</valuemap>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>QtVersion.2</variable>
|
<variable>QtVersion.1</variable>
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="int" key="Id">11</value>
|
<value type="int" key="Id">11</value>
|
||||||
<value type="QString" key="Name">Qt %{Qt:Version} (SQUISH_DEFAULT_COMPILER)</value>
|
<value type="QString" key="Name">Qt %{Qt:Version} (SQUISH_DEFAULT_COMPILER)</value>
|
||||||
|
@@ -4,52 +4,6 @@
|
|||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>Profile.0</variable>
|
<variable>Profile.0</variable>
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
|
||||||
<valuemap type="QVariantMap" key="PE.Profile.Data">
|
|
||||||
<value type="QString" key="Android.GdbServer.Information"></value>
|
|
||||||
<value type="QString" key="Debugger.Information">{70e26273-2c0b-4534-bbc0-eb6ca670821a}</value>
|
|
||||||
<value type="QString" key="PE.Profile.Device">{7c5a3673-e300-4286-9666-0f86d3e3dc38}</value>
|
|
||||||
<value type="QByteArray" key="PE.Profile.DeviceType">GenericLinuxOsType</value>
|
|
||||||
<value type="QString" key="PE.Profile.SysRoot"></value>
|
|
||||||
<value type="QString" key="PE.Profile.ToolChain">ProjectExplorer.ToolChain.Gcc:{c3f59b87-6997-4bd8-8067-ee04dc536371}</value>
|
|
||||||
<valuemap type="QVariantMap" key="PE.Profile.ToolChains">
|
|
||||||
<value type="QByteArray" key="C">{7bfd4fd4-e64a-417f-b10f-20602e1719d1}</value>
|
|
||||||
<value type="QString" key="Cxx">ProjectExplorer.ToolChain.Gcc:{c3f59b87-6997-4bd8-8067-ee04dc536371}</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="QString" key="QtPM4.mkSpecInformation"></value>
|
|
||||||
<value type="int" key="QtSupport.QtInformation">2</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="QString" key="PE.Profile.Icon">:///DESKTOP///</value>
|
|
||||||
<value type="QString" key="PE.Profile.Id">{f16848fc-b615-43b5-b0cc-16a9f57fb573}</value>
|
|
||||||
<valuelist type="QVariantList" key="PE.Profile.MutableInfo"/>
|
|
||||||
<value type="QString" key="PE.Profile.Name">Embedded Linux</value>
|
|
||||||
<value type="bool" key="PE.Profile.SDK">false</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>Profile.1</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
|
||||||
<valuemap type="QVariantMap" key="PE.Profile.Data">
|
|
||||||
<value type="QString" key="Android.GdbServer.Information"></value>
|
|
||||||
<value type="QString" key="Debugger.Information">{70e26273-2c0b-4534-bbc0-eb6ca670821a}</value>
|
|
||||||
<value type="QString" key="PE.Profile.Device">Desktop Device</value>
|
|
||||||
<value type="QByteArray" key="PE.Profile.DeviceType">Desktop</value>
|
|
||||||
<value type="QString" key="PE.Profile.SysRoot"></value>
|
|
||||||
<value type="QString" key="PE.Profile.ToolChain">ProjectExplorer.ToolChain.Gcc:{c3f59b87-6997-4bd8-8067-ee04dc536371}</value>
|
|
||||||
<value type="QString" key="QtPM4.mkSpecInformation"></value>
|
|
||||||
<value type="int" key="QtSupport.QtInformation">2</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="QString" key="PE.Profile.Icon">:///DESKTOP///</value>
|
|
||||||
<value type="QString" key="PE.Profile.Id">{1dcb5509-1670-470d-80a5-8a988f36e4e2}</value>
|
|
||||||
<valuelist type="QVariantList" key="PE.Profile.MutableInfo"/>
|
|
||||||
<value type="QString" key="PE.Profile.Name">Desktop 4.8.7 default</value>
|
|
||||||
<value type="bool" key="PE.Profile.SDK">false</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>Profile.2</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
||||||
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
|
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
|
||||||
@@ -73,7 +27,7 @@
|
|||||||
</valuemap>
|
</valuemap>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>Profile.3</variable>
|
<variable>Profile.1</variable>
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
||||||
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
|
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
|
||||||
@@ -97,7 +51,7 @@
|
|||||||
</valuemap>
|
</valuemap>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>Profile.4</variable>
|
<variable>Profile.2</variable>
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
||||||
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
|
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
|
||||||
@@ -126,7 +80,7 @@
|
|||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>Profile.Count</variable>
|
<variable>Profile.Count</variable>
|
||||||
<value type="int">5</value>
|
<value type="int">3</value>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>Profile.Default</variable>
|
<variable>Profile.Default</variable>
|
||||||
|
@@ -4,16 +4,6 @@
|
|||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>QtVersion.0</variable>
|
<variable>QtVersion.0</variable>
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="int" key="Id">2</value>
|
|
||||||
<value type="QString" key="Name">Desktop Qt 4.8 for GCC</value>
|
|
||||||
<value type="QString" key="QMakePath">~/Qt4.8.7/bin/qmake</value>
|
|
||||||
<value type="QString" key="QtVersion.Type">Qt4ProjectManager.QtVersion.Desktop</value>
|
|
||||||
<value type="bool" key="isAutodetected">false</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>QtVersion.1</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="int" key="Id">13</value>
|
<value type="int" key="Id">13</value>
|
||||||
<value type="QString" key="Name">Qt %{Qt:Version} (SQUISH_DEFAULT_COMPILER)</value>
|
<value type="QString" key="Name">Qt %{Qt:Version} (SQUISH_DEFAULT_COMPILER)</value>
|
||||||
@@ -23,7 +13,7 @@
|
|||||||
</valuemap>
|
</valuemap>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>QtVersion.2</variable>
|
<variable>QtVersion.1</variable>
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="int" key="Id">15</value>
|
<value type="int" key="Id">15</value>
|
||||||
<value type="QString" key="Name">Qt %{Qt:Version} (SQUISH_DEFAULT_COMPILER)</value>
|
<value type="QString" key="Name">Qt %{Qt:Version} (SQUISH_DEFAULT_COMPILER)</value>
|
||||||
@@ -33,7 +23,7 @@
|
|||||||
</valuemap>
|
</valuemap>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>QtVersion.3</variable>
|
<variable>QtVersion.2</variable>
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="int" key="Id">17</value>
|
<value type="int" key="Id">17</value>
|
||||||
<value type="QString" key="Name">Qt %{Qt:Version} (SQUISH_DEFAULT_COMPILER)</value>
|
<value type="QString" key="Name">Qt %{Qt:Version} (SQUISH_DEFAULT_COMPILER)</value>
|
||||||
|
@@ -4,34 +4,6 @@
|
|||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>Profile.0</variable>
|
<variable>Profile.0</variable>
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
|
||||||
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
|
|
||||||
<valuemap type="QVariantMap" key="PE.Profile.Data">
|
|
||||||
<value type="QString" key="Android.GdbServer.Information"></value>
|
|
||||||
<value type="QString" key="Debugger.Information">{1b25f20a-d584-4fb7-85b3-74dd15b82f6f}</value>
|
|
||||||
<value type="QString" key="PE.Profile.Device">Desktop Device</value>
|
|
||||||
<value type="QByteArray" key="PE.Profile.DeviceType">Desktop</value>
|
|
||||||
<valuelist type="QVariantList" key="PE.Profile.Environment"/>
|
|
||||||
<value type="QString" key="PE.Profile.SysRoot"></value>
|
|
||||||
<value type="QString" key="PE.Profile.ToolChain">{7ca0887f-a9a5-4251-aba6-560a15595d20}</value>
|
|
||||||
<valuemap type="QVariantMap" key="PE.Profile.ToolChains">
|
|
||||||
<value type="QByteArray" key="C">{d35e7a1a-5ab8-4fd6-8a2c-634846c669bb}</value>
|
|
||||||
<value type="QString" key="Cxx">{7ca0887f-a9a5-4251-aba6-560a15595d20}</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="QString" key="QtPM4.mkSpecInformation"></value>
|
|
||||||
<value type="int" key="QtSupport.QtInformation">2</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="QString" key="PE.Profile.Icon">:///DESKTOP///</value>
|
|
||||||
<value type="QString" key="PE.Profile.Id">{9b35bbe6-25a7-4cce-ba07-487c795f5265}</value>
|
|
||||||
<valuelist type="QVariantList" key="PE.Profile.MutableInfo"/>
|
|
||||||
<value type="QString" key="PE.Profile.Name">Desktop 4.8.7 default</value>
|
|
||||||
<value type="bool" key="PE.Profile.SDK">false</value>
|
|
||||||
<valuelist type="QVariantList" key="PE.Profile.StickyInfo"/>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>Profile.1</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
||||||
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
|
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
|
||||||
@@ -59,7 +31,7 @@
|
|||||||
</valuemap>
|
</valuemap>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>Profile.2</variable>
|
<variable>Profile.1</variable>
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
||||||
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
|
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
|
||||||
@@ -70,8 +42,7 @@
|
|||||||
<value type="QByteArray" key="PE.Profile.DeviceType">Desktop</value>
|
<value type="QByteArray" key="PE.Profile.DeviceType">Desktop</value>
|
||||||
<valuelist type="QVariantList" key="PE.Profile.Environment"/>
|
<valuelist type="QVariantList" key="PE.Profile.Environment"/>
|
||||||
<value type="QString" key="PE.Profile.SysRoot"></value>
|
<value type="QString" key="PE.Profile.SysRoot"></value>
|
||||||
<value type="QString" key="PE.Profile.ToolChain">{7ca0887f-a9a5-4251-aba6-560a15595d20}</value>
|
<valuemap type="QVariantMap" key="PE.Profile.ToolChainsV3">
|
||||||
<valuemap type="QVariantMap" key="PE.Profile.ToolChains">
|
|
||||||
<value type="QByteArray" key="C">{ce3a8004-e9ae-46f2-b62d-d7daf69435ca}</value>
|
<value type="QByteArray" key="C">{ce3a8004-e9ae-46f2-b62d-d7daf69435ca}</value>
|
||||||
<value type="QByteArray" key="Cxx">{3df7c776-a480-4a04-9099-6c75adac2dca}</value>
|
<value type="QByteArray" key="Cxx">{3df7c776-a480-4a04-9099-6c75adac2dca}</value>
|
||||||
</valuemap>
|
</valuemap>
|
||||||
@@ -87,7 +58,7 @@
|
|||||||
</valuemap>
|
</valuemap>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>Profile.3</variable>
|
<variable>Profile.2</variable>
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
<value type="bool" key="PE.Profile.AutoDetected">false</value>
|
||||||
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
|
<value type="QString" key="PE.Profile.AutoDetectionSource"></value>
|
||||||
@@ -116,7 +87,7 @@
|
|||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>Profile.Count</variable>
|
<variable>Profile.Count</variable>
|
||||||
<value type="int">4</value>
|
<value type="int">3</value>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>Profile.Default</variable>
|
<variable>Profile.Default</variable>
|
||||||
|
@@ -4,16 +4,6 @@
|
|||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>QtVersion.0</variable>
|
<variable>QtVersion.0</variable>
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="int" key="Id">2</value>
|
|
||||||
<value type="QString" key="Name">Qt 4.8 for Desktop - MSVC2013</value>
|
|
||||||
<value type="QString" key="QMakePath">C:/Qt/Qt4.8.7/bin/qmake.exe</value>
|
|
||||||
<value type="QString" key="QtVersion.Type">Qt4ProjectManager.QtVersion.Desktop</value>
|
|
||||||
<value type="bool" key="isAutodetected">false</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>QtVersion.1</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="int" key="Id">22</value>
|
<value type="int" key="Id">22</value>
|
||||||
<value type="QString" key="Name">Qt %{Qt:Version} (mingw491_32)</value>
|
<value type="QString" key="Name">Qt %{Qt:Version} (mingw491_32)</value>
|
||||||
@@ -23,7 +13,7 @@
|
|||||||
</valuemap>
|
</valuemap>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>QtVersion.2</variable>
|
<variable>QtVersion.1</variable>
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="int" key="Id">24</value>
|
<value type="int" key="Id">24</value>
|
||||||
<value type="QString" key="Name">Qt %{Qt:Version} (msvc2017_64)</value>
|
<value type="QString" key="Name">Qt %{Qt:Version} (msvc2017_64)</value>
|
||||||
@@ -33,7 +23,7 @@
|
|||||||
</valuemap>
|
</valuemap>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>QtVersion.3</variable>
|
<variable>QtVersion.2</variable>
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="int" key="Id">26</value>
|
<value type="int" key="Id">26</value>
|
||||||
<value type="QString" key="Name">Qt %{Qt:Version} (msvc2015)</value>
|
<value type="QString" key="Name">Qt %{Qt:Version} (msvc2015)</value>
|
||||||
|
@@ -19,18 +19,6 @@
|
|||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>ToolChain.1</variable>
|
<variable>ToolChain.1</variable>
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="QString" key="ProjectExplorer.MsvcToolChain.SupportedAbi">x86-windows-msvc2013-pe-32bit</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBat">C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/vcvarsall.bat</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBatArg">x86</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.ToolChain.Autodetect">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ToolChain.DisplayName">Microsoft Visual C++ Compiler 12.0 (x86)</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ToolChain.Id">ProjectExplorer.ToolChain.Msvc:{d35e7a1a-5ab8-4fd6-8a2c-634846c669bb}</value>
|
|
||||||
<value type="int" key="ProjectExplorer.ToolChain.Language">1</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ToolChain.2</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="QString" key="ProjectExplorer.GccToolChain.OriginalTargetTriple">i686-w64-mingw32</value>
|
<value type="QString" key="ProjectExplorer.GccToolChain.OriginalTargetTriple">i686-w64-mingw32</value>
|
||||||
<value type="QString" key="ProjectExplorer.GccToolChain.Path">C:/Qt/Qt5.4.1/Tools/mingw491_32/bin/gcc.exe</value>
|
<value type="QString" key="ProjectExplorer.GccToolChain.Path">C:/Qt/Qt5.4.1/Tools/mingw491_32/bin/gcc.exe</value>
|
||||||
@@ -47,12 +35,18 @@
|
|||||||
</valuemap>
|
</valuemap>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>ToolChain.3</variable>
|
<variable>ToolChain.2</variable>
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="QString" key="ProjectExplorer.MsvcToolChain.SupportedAbi">x86-windows-msvc2017-pe-64bit</value>
|
<value type="QString" key="ProjectExplorer.MsvcToolChain.SupportedAbi">x86-windows-msvc2017-pe-64bit</value>
|
||||||
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBat">C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Auxiliary/Build/vcvarsall.bat</value>
|
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBat">C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Auxiliary/Build/vcvarsall.bat</value>
|
||||||
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBatArg">amd64</value>
|
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBatArg">amd64</value>
|
||||||
<value type="bool" key="ProjectExplorer.ToolChain.Autodetect">false</value>
|
<valuelist type="QVariantList" key="ProjectExplorer.MsvcToolChain.environmentModifications">
|
||||||
|
<valuelist type="QVariantList">
|
||||||
|
<value type="QString">PATH</value>
|
||||||
|
<value type="int">0</value>
|
||||||
|
<value type="QString">SQUISH_MSVC2017_PATH</value>
|
||||||
|
</valuelist>
|
||||||
|
</valuelist>
|
||||||
<value type="QString" key="ProjectExplorer.ToolChain.DisplayName">MSVC2017 (amd64)</value>
|
<value type="QString" key="ProjectExplorer.ToolChain.DisplayName">MSVC2017 (amd64)</value>
|
||||||
<value type="QString" key="ProjectExplorer.ToolChain.Id">ProjectExplorer.ToolChain.Msvc:{ce3a8004-e9ae-46f2-b62d-d7daf69435ca}</value>
|
<value type="QString" key="ProjectExplorer.ToolChain.Id">ProjectExplorer.ToolChain.Msvc:{ce3a8004-e9ae-46f2-b62d-d7daf69435ca}</value>
|
||||||
<value type="int" key="ProjectExplorer.ToolChain.Language">1</value>
|
<value type="int" key="ProjectExplorer.ToolChain.Language">1</value>
|
||||||
@@ -60,7 +54,7 @@
|
|||||||
</valuemap>
|
</valuemap>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>ToolChain.4</variable>
|
<variable>ToolChain.3</variable>
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="QString" key="ProjectExplorer.MsvcToolChain.SupportedAbi">x86-windows-msvc2015-pe-32bit</value>
|
<value type="QString" key="ProjectExplorer.MsvcToolChain.SupportedAbi">x86-windows-msvc2015-pe-32bit</value>
|
||||||
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBat">C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/vcvarsall.bat</value>
|
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBat">C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/vcvarsall.bat</value>
|
||||||
@@ -73,7 +67,7 @@
|
|||||||
</valuemap>
|
</valuemap>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>ToolChain.5</variable>
|
<variable>ToolChain.4</variable>
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="QString" key="ProjectExplorer.MsvcToolChain.SupportedAbi">x86-windows-msvc2015-pe-32bit</value>
|
<value type="QString" key="ProjectExplorer.MsvcToolChain.SupportedAbi">x86-windows-msvc2015-pe-32bit</value>
|
||||||
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBat">C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/vcvarsall.bat</value>
|
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBat">C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/vcvarsall.bat</value>
|
||||||
@@ -86,23 +80,18 @@
|
|||||||
</valuemap>
|
</valuemap>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>ToolChain.6</variable>
|
<variable>ToolChain.5</variable>
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="QString" key="ProjectExplorer.MsvcToolChain.SupportedAbi">x86-windows-msvc2013-pe-32bit</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBat">C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/vcvarsall.bat</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBatArg">x86</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.ToolChain.Autodetect">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ToolChain.DisplayName">Microsoft Visual C++ Compiler 12.0 (x86)</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ToolChain.Id">ProjectExplorer.ToolChain.Msvc:{7ca0887f-a9a5-4251-aba6-560a15595d20}</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ToolChain.7</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="QString" key="ProjectExplorer.MsvcToolChain.SupportedAbi">x86-windows-msvc2017-pe-64bit</value>
|
<value type="QString" key="ProjectExplorer.MsvcToolChain.SupportedAbi">x86-windows-msvc2017-pe-64bit</value>
|
||||||
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBat">C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Auxiliary/Build/vcvarsall.bat</value>
|
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBat">C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Auxiliary/Build/vcvarsall.bat</value>
|
||||||
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBatArg">amd64</value>
|
<value type="QString" key="ProjectExplorer.MsvcToolChain.VarsBatArg">amd64</value>
|
||||||
<value type="bool" key="ProjectExplorer.ToolChain.Autodetect">false</value>
|
<valuelist type="QVariantList" key="ProjectExplorer.MsvcToolChain.environmentModifications">
|
||||||
|
<valuelist type="QVariantList">
|
||||||
|
<value type="QString">PATH</value>
|
||||||
|
<value type="int">0</value>
|
||||||
|
<value type="QString">SQUISH_MSVC2017_PATH</value>
|
||||||
|
</valuelist>
|
||||||
|
</valuelist>
|
||||||
<value type="QString" key="ProjectExplorer.ToolChain.DisplayName">MSVC2017 (amd64)</value>
|
<value type="QString" key="ProjectExplorer.ToolChain.DisplayName">MSVC2017 (amd64)</value>
|
||||||
<value type="QString" key="ProjectExplorer.ToolChain.Id">ProjectExplorer.ToolChain.Msvc:{3df7c776-a480-4a04-9099-6c75adac2dca}</value>
|
<value type="QString" key="ProjectExplorer.ToolChain.Id">ProjectExplorer.ToolChain.Msvc:{3df7c776-a480-4a04-9099-6c75adac2dca}</value>
|
||||||
<value type="int" key="ProjectExplorer.ToolChain.Language">2</value>
|
<value type="int" key="ProjectExplorer.ToolChain.Language">2</value>
|
||||||
@@ -111,7 +100,7 @@
|
|||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>ToolChain.Count</variable>
|
<variable>ToolChain.Count</variable>
|
||||||
<value type="int">8</value>
|
<value type="int">6</value>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
<variable>Version</variable>
|
<variable>Version</variable>
|
||||||
|
@@ -190,13 +190,12 @@ def verifyBuildConfig(currentTarget, configName, shouldBeDebug=False, enableShad
|
|||||||
# it will wait here until compilation of the debug libraries has finished.
|
# it will wait here until compilation of the debug libraries has finished.
|
||||||
runCMakeButton = ("{type='QPushButton' text='Run CMake' unnamed='1' "
|
runCMakeButton = ("{type='QPushButton' text='Run CMake' unnamed='1' "
|
||||||
"window=':Qt Creator_Core::Internal::MainWindow'}")
|
"window=':Qt Creator_Core::Internal::MainWindow'}")
|
||||||
if currentTarget not in (Targets.DESKTOP_4_8_7_DEFAULT, Targets.EMBEDDED_LINUX):
|
qmlDebuggingCombo = findObject(':Qt Creator.QML debugging and profiling:_QComboBox')
|
||||||
qmlDebuggingCombo = findObject(':Qt Creator.QML debugging and profiling:_QComboBox')
|
if selectFromCombo(qmlDebuggingCombo, 'Enable'):
|
||||||
if selectFromCombo(qmlDebuggingCombo, 'Enable'):
|
if buildSystem is None or buildSystem == "CMake": # re-run cmake to apply
|
||||||
if buildSystem is None or buildSystem == "CMake": # re-run cmake to apply
|
clickButton(waitForObject(runCMakeButton))
|
||||||
clickButton(waitForObject(runCMakeButton))
|
elif buildSystem == "qmake": # Don't rebuild now
|
||||||
elif buildSystem == "qmake": # Don't rebuild now
|
clickButton(waitForObject(":QML Debugging.No_QPushButton", 5000))
|
||||||
clickButton(waitForObject(":QML Debugging.No_QPushButton", 5000))
|
|
||||||
try:
|
try:
|
||||||
problemFound = waitForObject("{window=':Qt Creator_Core::Internal::MainWindow' "
|
problemFound = waitForObject("{window=':Qt Creator_Core::Internal::MainWindow' "
|
||||||
"type='QLabel' name='problemLabel' visible='1'}", 1000)
|
"type='QLabel' name='problemLabel' visible='1'}", 1000)
|
||||||
@@ -205,14 +204,13 @@ def verifyBuildConfig(currentTarget, configName, shouldBeDebug=False, enableShad
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if currentTarget not in (Targets.DESKTOP_4_8_7_DEFAULT, Targets.EMBEDDED_LINUX):
|
qmlDebuggingCombo = findObject(':Qt Creator.QML debugging and profiling:_QComboBox')
|
||||||
qmlDebuggingCombo = findObject(':Qt Creator.QML debugging and profiling:_QComboBox')
|
if selectFromCombo(qmlDebuggingCombo, "Disable"):
|
||||||
if selectFromCombo(qmlDebuggingCombo, "Disable"):
|
test.log("Qml debugging libraries are available - unchecked qml debugging.")
|
||||||
test.log("Qml debugging libraries are available - unchecked qml debugging.")
|
if buildSystem is None or buildSystem == "CMake": # re-run cmake to apply
|
||||||
if buildSystem is None or buildSystem == "CMake": # re-run cmake to apply
|
clickButton(waitForObject(runCMakeButton))
|
||||||
clickButton(waitForObject(runCMakeButton))
|
elif buildSystem == "qmake": # Don't rebuild now
|
||||||
elif buildSystem == "qmake": # Don't rebuild now
|
clickButton(waitForObject(":QML Debugging.No_QPushButton", 5000))
|
||||||
clickButton(waitForObject(":QML Debugging.No_QPushButton", 5000))
|
|
||||||
clickButton(waitForObject(":scrollArea.Details_Utils::DetailsButton"))
|
clickButton(waitForObject(":scrollArea.Details_Utils::DetailsButton"))
|
||||||
switchViewTo(ViewConstants.EDIT)
|
switchViewTo(ViewConstants.EDIT)
|
||||||
|
|
||||||
|
@@ -30,37 +30,27 @@ except ImportError:
|
|||||||
|
|
||||||
# for easier re-usage (because Python hasn't an enum type)
|
# for easier re-usage (because Python hasn't an enum type)
|
||||||
class Targets:
|
class Targets:
|
||||||
ALL_TARGETS = tuple(range(5))
|
ALL_TARGETS = tuple(range(3))
|
||||||
|
|
||||||
(DESKTOP_4_8_7_DEFAULT,
|
(DESKTOP_5_4_1_GCC,
|
||||||
EMBEDDED_LINUX,
|
|
||||||
DESKTOP_5_4_1_GCC,
|
|
||||||
DESKTOP_5_10_1_DEFAULT,
|
DESKTOP_5_10_1_DEFAULT,
|
||||||
DESKTOP_5_14_1_DEFAULT) = ALL_TARGETS
|
DESKTOP_5_14_1_DEFAULT) = ALL_TARGETS
|
||||||
|
|
||||||
__TARGET_NAME_DICT__ = dict(zip(ALL_TARGETS,
|
__TARGET_NAME_DICT__ = dict(zip(ALL_TARGETS,
|
||||||
["Desktop 4.8.7 default",
|
["Desktop 5.4.1 GCC",
|
||||||
"Embedded Linux",
|
|
||||||
"Desktop 5.4.1 GCC",
|
|
||||||
"Desktop 5.10.1 default",
|
"Desktop 5.10.1 default",
|
||||||
"Desktop 5.14.1 default"]))
|
"Desktop 5.14.1 default"]))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def availableTargetClasses(ignoreValidity=False):
|
def availableTargetClasses(ignoreValidity=False):
|
||||||
availableTargets = set(Targets.ALL_TARGETS)
|
availableTargets = set(Targets.ALL_TARGETS)
|
||||||
if not qt4Available and not ignoreValidity:
|
if platform.system() == 'Darwin':
|
||||||
availableTargets.remove(Targets.DESKTOP_4_8_7_DEFAULT)
|
|
||||||
if not (qt4Available or ignoreValidity) or platform.system() in ('Windows', 'Microsoft'):
|
|
||||||
availableTargets.remove(Targets.EMBEDDED_LINUX)
|
|
||||||
elif platform.system() == 'Darwin':
|
|
||||||
availableTargets.remove(Targets.DESKTOP_5_4_1_GCC)
|
availableTargets.remove(Targets.DESKTOP_5_4_1_GCC)
|
||||||
return availableTargets
|
return availableTargets
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def desktopTargetClasses():
|
def desktopTargetClasses():
|
||||||
desktopTargets = Targets.availableTargetClasses()
|
return Targets.availableTargetClasses()
|
||||||
desktopTargets.discard(Targets.EMBEDDED_LINUX)
|
|
||||||
return desktopTargets
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getStringForTarget(target):
|
def getStringForTarget(target):
|
||||||
|
@@ -161,11 +161,8 @@ def __createProjectHandleQtQuickSelection__(minimumQtVersion):
|
|||||||
# param buildSystem is a string holding the build system selected for the project
|
# param buildSystem is a string holding the build system selected for the project
|
||||||
# param checks turns tests in the function on if set to True
|
# param checks turns tests in the function on if set to True
|
||||||
# param available a list holding the available targets
|
# param available a list holding the available targets
|
||||||
# withoutQt4 if True Qt4 will get unchecked / not selected while checking the targets
|
def __selectQtVersionDesktop__(buildSystem, checks, available=None):
|
||||||
def __selectQtVersionDesktop__(buildSystem, checks, available=None, withoutQt4=False):
|
|
||||||
wanted = Targets.desktopTargetClasses()
|
wanted = Targets.desktopTargetClasses()
|
||||||
if withoutQt4:
|
|
||||||
wanted.discard(Targets.DESKTOP_4_8_7_DEFAULT)
|
|
||||||
checkedTargets = __chooseTargets__(wanted, available)
|
checkedTargets = __chooseTargets__(wanted, available)
|
||||||
if checks:
|
if checks:
|
||||||
for target in checkedTargets:
|
for target in checkedTargets:
|
||||||
@@ -183,9 +180,8 @@ def __selectQtVersionDesktop__(buildSystem, checks, available=None, withoutQt4=F
|
|||||||
objectMap.realName(detailsWidget)))
|
objectMap.realName(detailsWidget)))
|
||||||
verifyChecked(cbObject % ("Minimum Size Release",
|
verifyChecked(cbObject % ("Minimum Size Release",
|
||||||
objectMap.realName(detailsWidget)))
|
objectMap.realName(detailsWidget)))
|
||||||
elif (buildSystem == "qmake"
|
elif buildSystem == "qmake":
|
||||||
and target not in (Targets.DESKTOP_4_8_7_DEFAULT, Targets.EMBEDDED_LINUX)):
|
verifyChecked(cbObject % ("Profile", objectMap.realName(detailsWidget)))
|
||||||
verifyChecked(cbObject % ("Profile", objectMap.realName(detailsWidget)))
|
|
||||||
clickButton(detailsButton)
|
clickButton(detailsButton)
|
||||||
clickButton(waitForObject(":Next_QPushButton"))
|
clickButton(waitForObject(":Next_QPushButton"))
|
||||||
|
|
||||||
@@ -207,11 +203,6 @@ def __verifyFileCreation__(path, expectedFiles):
|
|||||||
def __modifyAvailableTargets__(available, requiredQt, asStrings=False):
|
def __modifyAvailableTargets__(available, requiredQt, asStrings=False):
|
||||||
versionFinder = re.compile("^Desktop (\\d{1}\.\\d{1,2}\.\\d{1,2}).*$")
|
versionFinder = re.compile("^Desktop (\\d{1}\.\\d{1,2}\.\\d{1,2}).*$")
|
||||||
tmp = list(available) # we need a deep copy
|
tmp = list(available) # we need a deep copy
|
||||||
if Qt5Path.toVersionTuple(requiredQt) > (4,8,7) and qt4Available:
|
|
||||||
toBeRemoved = Targets.EMBEDDED_LINUX
|
|
||||||
if asStrings:
|
|
||||||
toBeRemoved = Targets.getStringForTarget(toBeRemoved)
|
|
||||||
available.discard(toBeRemoved)
|
|
||||||
for currentItem in tmp:
|
for currentItem in tmp:
|
||||||
if asStrings:
|
if asStrings:
|
||||||
item = currentItem
|
item = currentItem
|
||||||
@@ -260,7 +251,7 @@ def createProject_Qt_GUI(path, projectName, checks=True, addToVersionControl="<N
|
|||||||
|
|
||||||
clickButton(waitForObject(":Next_QPushButton"))
|
clickButton(waitForObject(":Next_QPushButton"))
|
||||||
__createProjectHandleTranslationSelection__()
|
__createProjectHandleTranslationSelection__()
|
||||||
__selectQtVersionDesktop__(buildSystem, checks, available, True)
|
__selectQtVersionDesktop__(buildSystem, checks, available)
|
||||||
|
|
||||||
expectedFiles = []
|
expectedFiles = []
|
||||||
if checks:
|
if checks:
|
||||||
@@ -540,12 +531,6 @@ def __getSupportedPlatforms__(text, templateName, getAsStrings=False, ignoreVali
|
|||||||
supports = text[text.find('Supported Platforms'):].split(":")[1].strip().split("\n")
|
supports = text[text.find('Supported Platforms'):].split(":")[1].strip().split("\n")
|
||||||
result = set()
|
result = set()
|
||||||
if 'Desktop' in supports:
|
if 'Desktop' in supports:
|
||||||
if (version == None or version < "5.0") and not templateName.startswith("Qt Quick"):
|
|
||||||
neverIgnoreValidity = templateName in ("Qt Custom Designer Widget", "Code Snippet", "Subdirs Project")
|
|
||||||
if qt4Available or ignoreValidity and not neverIgnoreValidity:
|
|
||||||
result.add(Targets.DESKTOP_4_8_7_DEFAULT)
|
|
||||||
if platform.system() in ("Linux", "Darwin"):
|
|
||||||
result.add(Targets.EMBEDDED_LINUX)
|
|
||||||
result = result.union(set([Targets.DESKTOP_5_10_1_DEFAULT, Targets.DESKTOP_5_14_1_DEFAULT]))
|
result = result.union(set([Targets.DESKTOP_5_10_1_DEFAULT, Targets.DESKTOP_5_14_1_DEFAULT]))
|
||||||
if platform.system() != 'Darwin':
|
if platform.system() != 'Darwin':
|
||||||
result.add(Targets.DESKTOP_5_4_1_GCC)
|
result.add(Targets.DESKTOP_5_4_1_GCC)
|
||||||
|
@@ -40,12 +40,6 @@ except ImportError:
|
|||||||
import builtins as __builtin__ # Python 3
|
import builtins as __builtin__ # Python 3
|
||||||
|
|
||||||
|
|
||||||
# ensure global variables are defined before including shared scripts
|
|
||||||
qt4Path = os.path.expanduser("~/Qt4.8.7")
|
|
||||||
if platform.system() in ('Windows', 'Microsoft'):
|
|
||||||
qt4Path = "C:\\Qt\\Qt4.8.7"
|
|
||||||
|
|
||||||
qt4Available = os.path.exists(qt4Path)
|
|
||||||
srcPath = ''
|
srcPath = ''
|
||||||
SettingsPath = []
|
SettingsPath = []
|
||||||
tmpSettingsDir = ''
|
tmpSettingsDir = ''
|
||||||
@@ -237,6 +231,23 @@ def substituteCdb(settingsDir):
|
|||||||
__substitute__(debuggers, "SQUISH_DEBUGGER_BITNESS", bitness)
|
__substitute__(debuggers, "SQUISH_DEBUGGER_BITNESS", bitness)
|
||||||
test.log("Injected architecture '%s' and bitness '%s' in cdb path..." % (architecture, bitness))
|
test.log("Injected architecture '%s' and bitness '%s' in cdb path..." % (architecture, bitness))
|
||||||
|
|
||||||
|
|
||||||
|
def substituteMsvcPaths(settingsDir):
|
||||||
|
for msvcFlavor in ["Community", "BuildTools"]:
|
||||||
|
try:
|
||||||
|
msvc2017Path = os.path.join("C:\\Program Files (x86)", "Microsoft Visual Studio",
|
||||||
|
"2017", msvcFlavor, "VC", "Tools", "MSVC")
|
||||||
|
msvc2017Path = os.path.join(msvc2017Path, os.listdir(msvc2017Path)[0], "bin",
|
||||||
|
"HostX64", "x64")
|
||||||
|
__substitute__(os.path.join(settingsDir, "QtProject", 'qtcreator', 'toolchains.xml'),
|
||||||
|
"SQUISH_MSVC2017_PATH", msvc2017Path)
|
||||||
|
return
|
||||||
|
except:
|
||||||
|
continue
|
||||||
|
test.warning("PATH variable for MSVC2017 could not be set, some tests will fail.",
|
||||||
|
"Please make sure that MSVC2017 is installed correctly.")
|
||||||
|
|
||||||
|
|
||||||
def __guessABI__(supportedABIs, use64Bit):
|
def __guessABI__(supportedABIs, use64Bit):
|
||||||
if platform.system() == 'Linux':
|
if platform.system() == 'Linux':
|
||||||
supportedABIs = filter(lambda x: 'linux' in x, supportedABIs)
|
supportedABIs = filter(lambda x: 'linux' in x, supportedABIs)
|
||||||
@@ -331,6 +342,7 @@ def copySettingsToTmpDir(destination=None, omitFiles=[]):
|
|||||||
substituteDefaultCompiler(tmpSettingsDir)
|
substituteDefaultCompiler(tmpSettingsDir)
|
||||||
elif platform.system() in ('Windows', 'Microsoft'):
|
elif platform.system() in ('Windows', 'Microsoft'):
|
||||||
substituteCdb(tmpSettingsDir)
|
substituteCdb(tmpSettingsDir)
|
||||||
|
substituteMsvcPaths(tmpSettingsDir)
|
||||||
substituteUnchosenTargetABIs(tmpSettingsDir)
|
substituteUnchosenTargetABIs(tmpSettingsDir)
|
||||||
SettingsPath = ['-settingspath', '"%s"' % tmpSettingsDir]
|
SettingsPath = ['-settingspath', '"%s"' % tmpSettingsDir]
|
||||||
|
|
||||||
|
@@ -41,7 +41,6 @@ def main():
|
|||||||
return
|
return
|
||||||
# open example project, supports only Qt 5
|
# open example project, supports only Qt 5
|
||||||
targets = Targets.desktopTargetClasses()
|
targets = Targets.desktopTargetClasses()
|
||||||
targets.discard(Targets.DESKTOP_4_8_7_DEFAULT)
|
|
||||||
targets.discard(Targets.DESKTOP_5_4_1_GCC)
|
targets.discard(Targets.DESKTOP_5_4_1_GCC)
|
||||||
openQmakeProject(examplePath, targets)
|
openQmakeProject(examplePath, targets)
|
||||||
# build and wait until finished - on all build configurations
|
# build and wait until finished - on all build configurations
|
||||||
|
@@ -47,7 +47,6 @@ def main():
|
|||||||
if not startCreatorVerifyingClang(useClang):
|
if not startCreatorVerifyingClang(useClang):
|
||||||
continue
|
continue
|
||||||
createProject_Qt_Console(tempDir(), "SquishProject")
|
createProject_Qt_Console(tempDir(), "SquishProject")
|
||||||
# by default Qt4 is selected, use a Qt5 kit instead
|
|
||||||
selectBuildConfig(Targets.DESKTOP_5_10_1_DEFAULT, "Debug")
|
selectBuildConfig(Targets.DESKTOP_5_10_1_DEFAULT, "Debug")
|
||||||
checkCodeModelSettings(useClang)
|
checkCodeModelSettings(useClang)
|
||||||
selectFromLocator("main.cpp")
|
selectFromLocator("main.cpp")
|
||||||
|
Reference in New Issue
Block a user