Merge remote-tracking branch 'origin/8.0'

Conflicts:
	src/plugins/todo/optionsdialog.cpp
	src/plugins/todo/todoprojectsettingswidget.cpp

Change-Id: I24ca90c2fc2cd707df901d42694df6d0e27d696d
This commit is contained in:
Eike Ziller
2022-07-20 11:53:36 +02:00
77 changed files with 917 additions and 227 deletions

View File

@@ -25,10 +25,10 @@ jobs:
matrix: matrix:
config: config:
- { - {
name: "Windows MSVC 2019", artifact: "Windows-MSVC", name: "Windows Latest MSVC", artifact: "Windows-MSVC",
os: windows-2019, os: windows-latest,
cc: "cl", cxx: "cl", cc: "cl", cxx: "cl",
environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat", environment_script: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat",
is_msvc: true is_msvc: true
} }
- { - {
@@ -121,7 +121,10 @@ jobs:
COMMAND sudo apt update COMMAND sudo apt update
) )
execute_process( execute_process(
COMMAND sudo apt install libgl1-mesa-dev libvulkan-dev libxcb-xinput-dev libxcb-xinerama0-dev libxkbcommon-dev libxkbcommon-x11-dev COMMAND
sudo apt install libgl1-mesa-dev libvulkan-dev libxcb-xinput-dev libxcb-xinerama0-dev libxkbcommon-dev libxkbcommon-x11-dev
libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xkb1 libxcb-randr0 libxcb-icccm4
xvfb
RESULT_VARIABLE result RESULT_VARIABLE result
) )
if (NOT result EQUAL 0) if (NOT result EQUAL 0)
@@ -129,6 +132,18 @@ jobs:
endif() endif()
endif() endif()
if ("${{ runner.os }}" STREQUAL "Windows")
file(MAKE_DIRECTORY build/build/bin)
foreach(retry RANGE 10)
file(DOWNLOAD "https://download.qt.io/development_releases/prebuilt/llvmpipe/windows/opengl32sw-64.7z" ./opengl32sw-64.7z SHOW_PROGRESS)
file(SIZE ./opengl32sw-64.7z fileSize)
if (fileSize GREATER 0)
break()
endif()
endforeach()
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ../../../opengl32sw-64.7z WORKING_DIRECTORY build/build/bin)
endif()
if (NOT "x${{ matrix.config.toolchain }}" STREQUAL "x") if (NOT "x${{ matrix.config.toolchain }}" STREQUAL "x")
foreach(retry RANGE 10) foreach(retry RANGE 10)
file(DOWNLOAD "${{ matrix.config.toolchain }}" ./toolchain.7z SHOW_PROGRESS) file(DOWNLOAD "${{ matrix.config.toolchain }}" ./toolchain.7z SHOW_PROGRESS)
@@ -140,6 +155,12 @@ jobs:
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./toolchain.7z) execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./toolchain.7z)
endif() endif()
# For tests update the docker image
find_program(docker_executable docker)
if (docker_executable)
execute_process(COMMAND ${docker_executable} pull alpine:latest COMMAND_ECHO STDOUT)
endif()
- name: Download Qt - name: Download Qt
id: qt id: qt
shell: cmake -P {0} shell: cmake -P {0}
@@ -593,11 +614,16 @@ jobs:
set(ENV{CTEST_OUTPUT_ON_FAILURE} "ON") set(ENV{CTEST_OUTPUT_ON_FAILURE} "ON")
if ("${{ runner.os }}" STREQUAL "Linux") if ("${{ runner.os }}" STREQUAL "Linux")
set(ENV{QT_QPA_PLATFORM} "offscreen") set(ENV{DISPLAY} ":1")
set(ENV{LIBGL_ALWAYS_SOFTWARE} "1")
set(ctest_launcher xvfb-run --auto-servernum --server-num=1)
elseif ("${{ runner.os }}" STREQUAL "Windows")
set(ENV{QT_OPENGL} "software")
set(ENV{QT_ASSUME_STDERR_HAS_CONSOLE} "1")
endif() endif()
execute_process( execute_process(
COMMAND ctest -j ${N} --timeout 60 --label-exclude exclude_from_precheck --exclude-regex tst_perfdata COMMAND ${ctest_launcher} ctest -j ${N} --timeout 300 --label-exclude exclude_from_precheck --exclude-regex tst_perfdata
WORKING_DIRECTORY build/build WORKING_DIRECTORY build/build
RESULT_VARIABLE result RESULT_VARIABLE result
OUTPUT_VARIABLE output OUTPUT_VARIABLE output

1
.gitignore vendored
View File

@@ -39,6 +39,7 @@ tags
ui_*.h ui_*.h
wrapper.bat wrapper.bat
wrapper.sh wrapper.sh
debug_toolchain.cmake
# qtcreator generated files # qtcreator generated files
*.creator.user* *.creator.user*

View File

@@ -138,15 +138,6 @@ instructions:
property: target.arch property: target.arch
equals_value: X86 equals_value: X86
- type: SignPackage
directory: "{{.AgentWorkingDir}}/qt-creator/qt-creator_build/install/"
maxTimeInSeconds: 1200
maxTimeBetweenOutput: 1200
enable_if:
condition: property
property: host.os
equals_value: Windows
- type: UploadArtifact - type: UploadArtifact
archiveDirectory: "{{.AgentWorkingDir}}/qt-creator/qt-creator_build/build" archiveDirectory: "{{.AgentWorkingDir}}/qt-creator/qt-creator_build/build"
transferType: UploadModuleBuildArtifact transferType: UploadModuleBuildArtifact

View File

@@ -16,7 +16,7 @@ instructions:
variableValue: "http://ci-files02-hki.intra.qt.io/packages/jenkins/archive/qt/6.3/6.3.1-final-released/Qt6.3.1" variableValue: "http://ci-files02-hki.intra.qt.io/packages/jenkins/archive/qt/6.3/6.3.1-final-released/Qt6.3.1"
- type: EnvironmentVariable - type: EnvironmentVariable
variableName: QTC_QT_MODULES variableName: QTC_QT_MODULES
variableValue: "qt5compat qtbase qtdeclarative qtimageformats qtquick3d qtquickcontrols2 qtquicktimeline qtserialport qtshadertools qtsvg qttools qttranslations" variableValue: "qt5compat qtbase qtdeclarative qtimageformats qtquick3d qtquickcontrols2 qtquicktimeline qtserialport qtshadertools qtsvg qttools qttranslations qtwebengine"
- type: EnvironmentVariable - type: EnvironmentVariable
variableName: MACOSX_DEPLOYMENT_TARGET variableName: MACOSX_DEPLOYMENT_TARGET
variableValue: 10.14 variableValue: 10.14

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@@ -122,8 +122,8 @@
\image qtcreator-clang-tools-options-customized.png "Clang Tools customized settings" \image qtcreator-clang-tools-options-customized.png "Clang Tools customized settings"
To restore the global settings, select \uicontrol {Restore Global Settings}. To restore the global settings, select \uicontrol {Restore Global Settings}.
To view and modify the global settings, select To view and modify the global settings, select the link in
\uicontrol {Open Global Settings}. To open the Clang static analyzer, \uicontrol {Use global settings}. To open the Clang static analyzer,
select \uicontrol {Go to Analyzer}. select \uicontrol {Go to Analyzer}.
\section1 Configuring Clang Tools \section1 Configuring Clang Tools
@@ -174,6 +174,8 @@
\li In the \uicontrol {Clang-Tidy Checks} tab, select \li In the \uicontrol {Clang-Tidy Checks} tab, select
\uicontrol {Select Checks} to select the checks to perform. \uicontrol {Select Checks} to select the checks to perform.
To filter the checks, enter a string in the
\uicontrol {Filter by name} field.
\image qtcreator-clang-tidy.png "Clang-Tidy Checks tab" \image qtcreator-clang-tidy.png "Clang-Tidy Checks tab"
@@ -189,8 +191,10 @@
\image qtcreator-clazy.png "Clazy Checks tab" \image qtcreator-clazy.png "Clazy Checks tab"
\li In the \uicontrol {Topic Filter} field, select a topic to view \li In the \uicontrol Filters field, select topics to view
only checks related to that area in the \uicontrol Checks field. only checks related to those areas in the \uicontrol Checks field.
To filter the checks in the selected areas, enter a string in the
\uicontrol {Filter by name} field.
\li To view all checks again, select \uicontrol {Reset Filter}. \li To view all checks again, select \uicontrol {Reset Filter}.

View File

@@ -406,6 +406,15 @@
applications. applications.
\li Select the \uicontrol {Break at "main"} check box to stop the \li Select the \uicontrol {Break at "main"} check box to stop the
debugger at the main function. debugger at the main function.
\li Select the \uicontrol {Use target extended-remote to connect}
check box to create the connection in the
\c {target extended-remote mode}. In this mode, when the debugged
application exits or you detach from it, the debugger remains
connected to the target. You can rerun the application, attach
to a running application, or use monitor commands specific to the
target. For example, GDB does not exit unless it was invoked using
the \c {--once} option, but you can make it exit by using the
\c {monitor exit} command.
\li In the \uicontrol {Override SysRoot} field, specify the path to \li In the \uicontrol {Override SysRoot} field, specify the path to
the \c sysroot to use instead of the default \c sysroot. the \c sysroot to use instead of the default \c sysroot.
\li In the \uicontrol {Init commands} field, enter the commands \li In the \uicontrol {Init commands} field, enter the commands
@@ -430,6 +439,10 @@
to manage the GDB process, see \l{Specifying GDB Settings} and to manage the GDB process, see \l{Specifying GDB Settings} and
\l{Specifying Extended GDB Settings}. \l{Specifying Extended GDB Settings}.
For more informaton about connecting with \c {target extended-remote} mode
in GDB, see \l{https://sourceware.org/gdb/onlinedocs/gdb/Connecting.html}
{Debugging with GDB: Connecting to a Remote Target}.
\section3 Using CDB \section3 Using CDB
In remote mode, the local CDB process talks to a CDB process that runs on In remote mode, the local CDB process talks to a CDB process that runs on
@@ -864,7 +877,7 @@
Debugging helpers are always automatically used. To force a plain C-like Debugging helpers are always automatically used. To force a plain C-like
display of structures, select \uicontrol Edit > \uicontrol Preferences > display of structures, select \uicontrol Edit > \uicontrol Preferences >
\uicontrol Debugger > \uicontrol {Locals & Expressions}, and then deselect \uicontrol Debugger > \uicontrol {Locals & Expressions}, and then deselect
the \uicontrol {Use Debugging Helper} check box. This will still use the the \uicontrol {Use Debugging Helpers} check box. This will still use the
Python scripts, but generate more basic output. To force the plain display Python scripts, but generate more basic output. To force the plain display
for a single object or for all objects of a given type, select the for a single object or for all objects of a given type, select the
corresponding option from the context menu. corresponding option from the context menu.
@@ -893,6 +906,8 @@
\uicontrol Debugger > \uicontrol GDB > \uicontrol {Load system GDB pretty \uicontrol Debugger > \uicontrol GDB > \uicontrol {Load system GDB pretty
printers}. For more information, see \l{Specifying GDB Settings}. printers}. For more information, see \l{Specifying GDB Settings}.
\image qtcreator-gdb-options.png "GDB preferences"
\section2 Customizing Built-In Debugging Helpers \section2 Customizing Built-In Debugging Helpers
You can have commands executed after built-in debugging helpers have You can have commands executed after built-in debugging helpers have
@@ -968,7 +983,7 @@
installation in your file system and specify the location in installation in your file system and specify the location in
\uicontrol Edit > \uicontrol Preferences > \uicontrol Debugger > \uicontrol Edit > \uicontrol Preferences > \uicontrol Debugger >
\uicontrol {Locals & Expressions} > \uicontrol {Locals & Expressions} >
\uicontrol {Extra Debugging Helpers}. \uicontrol {Extra Debugging Helper}.
\endlist \endlist
The custom debugging helpers will be automatically picked up from The custom debugging helpers will be automatically picked up from
@@ -1112,6 +1127,8 @@
selecting \uicontrol Edit > \uicontrol Preferences > \uicontrol Debugger > selecting \uicontrol Edit > \uicontrol Preferences > \uicontrol Debugger >
\uicontrol CDB > \uicontrol {Use Python dumper}. \uicontrol CDB > \uicontrol {Use Python dumper}.
\image qtcreator-cdb-options.png "CDB preferences"
\section3 Dumper Class \section3 Dumper Class
The \c Dumper class contains generic bookkeeping, low-level, and convenience The \c Dumper class contains generic bookkeeping, low-level, and convenience
@@ -1549,6 +1566,8 @@
> \uicontrol Preferences > \uicontrol Debugger > \uicontrol GDB > > \uicontrol Preferences > \uicontrol Debugger > \uicontrol GDB >
\uicontrol {Use automatic symbol cache}. \uicontrol {Use automatic symbol cache}.
\image qtcreator-gdb-options.png "GDB preferences"
Some slowness stems from maintaining breakpoints inside Some slowness stems from maintaining breakpoints inside
the debugger (under some circumstances all breakpoints need to be inserted the debugger (under some circumstances all breakpoints need to be inserted
and removed again for each step) and the evaluation of expressions after and removed again for each step) and the evaluation of expressions after

View File

@@ -148,6 +148,8 @@
To customize, import, or export keyboard shortcuts, select \uicontrol Edit > To customize, import, or export keyboard shortcuts, select \uicontrol Edit >
\uicontrol Preferences > \uicontrol Environment > \uicontrol Keyboard. \uicontrol Preferences > \uicontrol Environment > \uicontrol Keyboard.
\image qtcreator-keyboard-shortcuts.png "Keyboard preferences"
\section1 Run \QC from the command line \section1 Run \QC from the command line
You can launch \QC from the command line using the name of an You can launch \QC from the command line using the name of an
@@ -195,7 +197,8 @@
If an instance of a class is derived from QObject, and you would like to If an instance of a class is derived from QObject, and you would like to
find all other objects connected to one of your object's slots using find all other objects connected to one of your object's slots using
Qt's signals and slots mechanism, select \uicontrol Edit > \uicontrol Preferences Qt's signals and slots mechanism, select \uicontrol Edit > \uicontrol Preferences
> \uicontrol{Debugger} > \uicontrol{Locals} > \uicontrol{Use Debugging Helper}. > \uicontrol {Debugger} > \uicontrol {Locals & Expressions} >
\uicontrol {Use Debugging Helpers}.
In the \uicontrol{Locals} view, expand the object's entry and open In the \uicontrol{Locals} view, expand the object's entry and open
the slot in the \e slots subitem. The objects connected to this slot are the slot in the \e slots subitem. The objects connected to this slot are
@@ -214,9 +217,9 @@
\list 1 \list 1
\li Select \uicontrol Edit > \uicontrol Preferences > \uicontrol Debugger > \li Select \uicontrol Edit > \uicontrol Preferences > \uicontrol Debugger >
\uicontrol{Locals}. \uicontrol {Locals & Expressions}.
\image qtcreator-debugging-helper-options.png "Locals & Expressions preferences"
\li Uncheck the \uicontrol{Use Debugging Helper} checkbox. \li Deselect \uicontrol {Use Debugging Helpers}.
\endlist \endlist
@@ -229,9 +232,8 @@
\li Select \uicontrol Edit > \uicontrol Preferences > \li Select \uicontrol Edit > \uicontrol Preferences >
\uicontrol Debugger > \uicontrol General. \uicontrol Debugger > \uicontrol General.
\image qtcreator-debugger-general-options.png "Debugger General preferences"
\li Select the \uicontrol {Use tooltips in main editor while debugging} check \li Select \uicontrol {Use tooltips in main editor when debugging}.
box.
\endlist \endlist
@@ -253,8 +255,12 @@
create your own locator filters. That way you can locate files in a create your own locator filters. That way you can locate files in a
directory structure you have defined. directory structure you have defined.
\image qtcreator-locator.png "List of locator filters"
To create locator filters, select \uicontrol Edit > \uicontrol Preferences > To create locator filters, select \uicontrol Edit > \uicontrol Preferences >
\uicontrol Locator > \uicontrol Add. \uicontrol Environment > \uicontrol Locator > \uicontrol Add.
\image qtcreator-locator-customize.png "Locator preferences"
For more information, see \l{Creating Locator Filters}. For more information, see \l{Creating Locator Filters}.
@@ -273,9 +279,13 @@
\section1 Add a license header template for C++ code \section1 Add a license header template for C++ code
A file containing a license header for C++ can be specified under Specify a file containing a license header for C++ in \uicontrol Edit >
\uicontrol Edit > \uicontrol Preferences > \uicontrol C++ > \uicontrol Preferences > \uicontrol C++ > \uicontrol {File Naming} >
\uicontrol {License Template}. It may contain special placeholders enclosed \uicontrol {License template}.
\image qtcreator-options-cpp-files.png "File Naming preferences"
The license file may contain special placeholders enclosed
in \c{%%} that are replaced when generating a new file: in \c{%%} that are replaced when generating a new file:
\list 1 \list 1
@@ -306,7 +316,7 @@
\section1 Enclose selected code in curly braces, parentheses, or double quotes \section1 Enclose selected code in curly braces, parentheses, or double quotes
When you have selected code and enter one of the following opening When you have selected code and enter one of the following opening
characters, the appropriate closing character is added automatically characters, the matching closing character is added automatically
at the end of the selection: at the end of the selection:
\list \list
@@ -315,6 +325,12 @@
\li " \li "
\endlist \endlist
To specify whether to automatically insert matching characters,
select \uicontrol Edit > \uicontrol Preferences >
\uicontrol {Text Editor} > \uicontrol Completion.
\image qtcreator-options-texteditor-completion.png "Completion preferences"
\section1 Select the enclosing block in C++ \section1 Select the enclosing block in C++
Press \key {Ctrl+U}. Press \key {Ctrl+U}.
@@ -325,6 +341,8 @@
To open the editor, select \uicontrol Edit > \uicontrol Preferences To open the editor, select \uicontrol Edit > \uicontrol Preferences
> \uicontrol {Text Editor} > \uicontrol Snippets. > \uicontrol {Text Editor} > \uicontrol Snippets.
\image qtcreator-snippet-modifiers.png "Snippets preferences"
For more information, see \l {Adding and Editing Snippets}. For more information, see \l {Adding and Editing Snippets}.
\section1 Quickly write down notes somewhere \section1 Quickly write down notes somewhere
@@ -344,10 +362,12 @@
\section1 Configure the amount of recent files shown \section1 Configure the amount of recent files shown
Select \uicontrol Edit > \uicontrol Preferences, and change the value of the Set the value of \uicontrol Edit > \uicontrol Preferences >
list under \uicontrol Environment > \uicontrol System \uicontrol Environment > \uicontrol System
> \uicontrol {Maximum number of entries in "Recent Files"}. > \uicontrol {Maximum number of entries in "Recent Files"}.
\image qtcreator-options-environment-system.png "System preferences"
\section1 Search and replace across files using a regular expression \section1 Search and replace across files using a regular expression
As an example, say you want to replace equality checks (\c {foo == bar}) As an example, say you want to replace equality checks (\c {foo == bar})

View File

@@ -53,6 +53,11 @@
installed on the device. Text in red color indicates that the information is installed on the device. Text in red color indicates that the information is
missing. missing.
If the build system did not automatically detect the source and target
directories, select \uicontrol {Override deployment data from build system},
and then select \uicontrol Add to enter them manually. To remove the
selected paths from \uicontrol {Files to deploy}, select \uicontrol Remove.
\section1 Adding Missing Files \section1 Adding Missing Files
The process to add files to deploy depends on the build system you use. The process to add files to deploy depends on the build system you use.
@@ -100,29 +105,17 @@
When you run the application on the device, \QC first uploads the When you run the application on the device, \QC first uploads the
necessary files to it, as specified by the deploy steps. necessary files to it, as specified by the deploy steps.
\section2 Finding Configured Devices
The \uicontrol {Check for a configured device} step looks for a device that
is ready for deployment.
\section2 Checking for Free Disk Space
The \uicontrol {Check for free disk space} step is by default the first
deploy step. Use it to find out whether the remote file system has enough
space left to deploy your project. Errors due to lack of disk space can
otherwise be hard to detect.
\note If the SFTP upload fails, make sure that the remote device has SFTP
enabled in its SSH daemon. Some versions of Dropbear that come without SFTP
support will crash when an SFTP upload is being attempted. This is not a bug
in \QC.
\section2 Uploading Files \section2 Uploading Files
By default, \QC copies the application files to the device by By default, \QC copies the application files to the device by
using the SSH file transfer protocol (SFTP), as specified by using the SSH file transfer protocol (SFTP), as specified by
the \uicontrol {Upload files via SFTP} step. the \uicontrol {Upload files via SFTP} step.
\note If the SFTP upload fails, make sure that the remote device has SFTP
enabled in its SSH daemon. Some versions of Dropbear that come without SFTP
support will crash when an SFTP upload is being attempted. This is not a bug
in \QC.
If you have a lot of data to copy, select \uicontrol Details in the If you have a lot of data to copy, select \uicontrol Details in the
\uicontrol {Upload Files via SFTP} step, and then select the \uicontrol {Upload Files via SFTP} step, and then select the
\uicontrol {Incremental deployment} check box. \QC takes note of the \uicontrol {Incremental deployment} check box. \QC takes note of the

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2018 The Qt Company Ltd. ** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -48,7 +48,7 @@
into binaries. Different build configurations allow you to into binaries. Different build configurations allow you to
quickly build the project for different purposes. quickly build the project for different purposes.
By default, \QC creates \e {debug build} and \e {release build} By default, \QC creates \e {debug build} and \e {release build}
configurations for each \l{glossary-buildandrun-kit}{kit} defined for your project. configurations for each \e {kit} defined for your project.
A debug build contains A debug build contains
additional debug symbols that you need for debugging the additional debug symbols that you need for debugging the
application but that you can leave out from the release version. application but that you can leave out from the release version.
@@ -81,20 +81,20 @@
\li Handles the packaging and copying of the necessary files to a \li Handles the packaging and copying of the necessary files to a
location you want to run the executable at. The files can be location you want to run the executable at. The files can be
copied to a location in the file system of the development PC or copied to a location in the file system of the development PC or
a \l{glossary-device}{device}. a \e {device}.
\row \row
\li Device \li Device
\target glossary-device \target glossary-device
\li An embedded device or a mobile device. For more information, see \li An embedded device or a mobile device. For more information, see
\l{Target Platforms}. \l{Embedded Platforms} and \l{Mobile Platforms}.
\row \row
\li Kit \li Kit
\target glossary-buildandrun-kit \target glossary-buildandrun-kit
\li \QC groups build and run specific settings as kits to make \li \QC groups build and run specific settings as kits to make
cross-platform development easier. Each kit consists of a set cross-platform development easier. Each kit consists of a set
of values that define one environment, such as a \l{glossary-device}{device}, of values that define one environment, such as a \e {device},
tool chain, Qt version, and debugger command to use. Configure kits at tool chain, Qt version, and debugger command to use. Configure kits at
\uicontrol Edit > \uicontrol Preferences > \uicontrol Kits. \uicontrol Edit > \uicontrol Preferences > \uicontrol Kits.
@@ -113,7 +113,7 @@
\target glossary-project \target glossary-project
\li Groups together a set of source files, forms, and resource files \li Groups together a set of source files, forms, and resource files
that you can build for, as well as deploy and run on different that you can build for, as well as deploy and run on different
desktop and \l{glossary-device}{device} platforms, as desktop and \e {device} platforms, as
specified by a \e {build configuration}, \e {deploy specified by a \e {build configuration}, \e {deploy
configuration}, and \e {run configuration}. configuration}, and \e {run configuration}.
@@ -129,9 +129,8 @@
\target glossary-run-config \target glossary-run-config
\li Starts the application in the location where it was copied by \li Starts the application in the location where it was copied by
the \e {deploy configuration}. By default, when you run a the \e {deploy configuration}. By default, when you run a
project, \QC builds it, deploys it to the project, \QC builds it, deploys it to the \e {device} specified
\l{glossary-device}{device} specified in the selected in the selected \e {kit},
\l{glossary-buildandrun-kit}{kit},
and runs it there. However, if you have not made any changes to and runs it there. However, if you have not made any changes to
the project since you last built and deployed it, \QC simply the project since you last built and deployed it, \QC simply
runs it again. runs it again.

View File

@@ -117,7 +117,8 @@
\li When debugging executables created by the GNU Compiler version 4.5.0 \li When debugging executables created by the GNU Compiler version 4.5.0
(all platforms), some data types will not be displayed in the (all platforms), some data types will not be displayed in the
\uicontrol{Locals and Expressions} view due to missing debug information. \uicontrol Locals and \uicontrol Expressions views due to missing
debug information.
\li GDB on Windows may not work if the 'Embassy \reg Security Center' \li GDB on Windows may not work if the 'Embassy \reg Security Center'
software by 'Wave \reg Systems' is installed and active (causing software by 'Wave \reg Systems' is installed and active (causing
@@ -131,7 +132,7 @@
\li Setting breakpoints in files that do not have unique absolute \li Setting breakpoints in files that do not have unique absolute
paths may fail. For example, remounting parts of a file system paths may fail. For example, remounting parts of a file system
using the --bind mount option. using the \c {--bind mount} option.
\li Setting breakpoints in files will fail when using LLDB if the file path \li Setting breakpoints in files will fail when using LLDB if the file path
contains symbolic links. contains symbolic links.

View File

@@ -48,4 +48,9 @@
The deployment process is described in more detail in The deployment process is described in more detail in
\l{Deploying Applications to Generic Remote Linux Devices}. \l{Deploying Applications to Generic Remote Linux Devices}.
\section1 Finding Configured Devices
The \uicontrol {Check for a configured device} deployment step looks for a
device that is ready for deployment.
*/ */

View File

@@ -673,10 +673,17 @@
in the \uicontrol {Scanning scope} group. in the \uicontrol {Scanning scope} group.
To exclude files from scanning, select \uicontrol {Project Settings} > To exclude files from scanning, select \uicontrol {Project Settings} >
\uicontrol {To-Do} in the \uicontrol {To-Do} in the \uicontrol Projects mode.
\uicontrol Projects mode. Select \uicontrol Add and enter a regular
expression that matches the path to files to exclude. Use a forward slash \image qtcreator-todo-excluded-files.png "Excluded Files in To-Do preferences"
(/) as a separator in the path also on Windows.
Select \uicontrol Add and double-click the placeholder text in
\uicontrol {Exclude Files} to enter a regular expression that
matches the path to files to exclude. Use a forward slash (/)
as a separator in the path also on Windows.
Select the link in \uicontrol {Use global settings} to open global
To-Do preferences.
The Todo plugin is disabled by default. To enable the plugin, select The Todo plugin is disabled by default. To enable the plugin, select
\uicontrol Help > \uicontrol {About Plugins} > \uicontrol Utilities > \uicontrol Help > \uicontrol {About Plugins} > \uicontrol Utilities >

View File

@@ -345,7 +345,7 @@
the resource file as a source file in the \e CMakeLists.txt file that the the resource file as a source file in the \e CMakeLists.txt file that the
wizard created for you: wizard created for you:
\quotefromfile TextFinder/CMakeLists.txt \quotefromfile textfinder/CMakeLists.txt
\skipto set(PROJECT_SOURCES \skipto set(PROJECT_SOURCES
\printuntil ) \printuntil )

View File

@@ -59,6 +59,11 @@ Project {
directory: "asset_imports" directory: "asset_imports"
} }
Files {
filter: "*.qml"
directory: "asset_imports"
}
Environment { Environment {
QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf" QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf"
QT_AUTO_SCREEN_SCALE_FACTOR: "1" QT_AUTO_SCREEN_SCALE_FACTOR: "1"

View File

@@ -62,8 +62,11 @@ finalOutput() {
local fileInputBuffer local fileInputBuffer
while read fileInputBuffer while read fileInputBuffer
do do
if test -f "$fileInputBuffer.err"; then
cat $fileInputBuffer.err
fi
cat $fileInputBuffer cat $fileInputBuffer
rm $fileInputBuffer rm -f $fileInputBuffer.err $fileInputBuffer
done done
} }
@@ -117,7 +120,7 @@ executeAndMark()
# Mark the app's output streams # Mark the app's output streams
readAndMark $PID 'O' < "$stdoutenc" >> $TMPFILE & readAndMark $PID 'O' < "$stdoutenc" >> $TMPFILE &
readAndMark $PID 'E' < "$stderrenc" >> $TMPFILE & readAndMark $PID 'E' < "$stderrenc" >> $TMPFILE.err &
# Start the app ... # Start the app ...
if [ -z "$INDATA" ] if [ -z "$INDATA" ]

View File

@@ -151,7 +151,8 @@ signals:
void append(const QString &text); void append(const QString &text);
void appendSilently(const QString &text); void appendSilently(const QString &text);
void appendError(const QString &text); void appendError(const QString &text);
void appendCommand(const FilePath &workingDirectory, const CommandLine &command); // TODO: remove Utils:: scope when support for Qt5 is dropped (Creator 9.0)
void appendCommand(const Utils::FilePath &workingDirectory, const Utils::CommandLine &command);
void appendMessage(const QString &text); void appendMessage(const QString &text);
void executedAsync(const QFuture<void> &future); void executedAsync(const QFuture<void> &future);

View File

@@ -267,11 +267,15 @@ bool AndroidAvdManager::startAvdAsync(const QString &avdName) const
{ {
QFileInfo info(m_config.emulatorToolPath().toString()); QFileInfo info(m_config.emulatorToolPath().toString());
if (!info.exists()) { if (!info.exists()) {
const QString emulatorToolPath = m_config.emulatorToolPath().toUserOutput();
QMetaObject::invokeMethod(Core::ICore::mainWindow(), [emulatorToolPath] {
QMessageBox::critical(Core::ICore::dialogParent(), QMessageBox::critical(Core::ICore::dialogParent(),
tr("Emulator Tool Is Missing"), AndroidAvdManager::tr("Emulator Tool Is Missing"),
tr("Install the missing emulator tool (%1) to the" AndroidAvdManager::tr(
"Install the missing emulator tool (%1) to the"
" installed Android SDK.") " installed Android SDK.")
.arg(m_config.emulatorToolPath().toString())); .arg(emulatorToolPath));
});
return false; return false;
} }
@@ -283,10 +287,13 @@ bool AndroidAvdManager::startAvdAsync(const QString &avdName) const
avdProcess->setProcessChannelMode(QProcess::MergedChannels); avdProcess->setProcessChannelMode(QProcess::MergedChannels);
QObject::connect(avdProcess, &QtcProcess::done, avdProcess, [avdProcess] { QObject::connect(avdProcess, &QtcProcess::done, avdProcess, [avdProcess] {
if (avdProcess->exitCode()) { if (avdProcess->exitCode()) {
const QString title = QCoreApplication::translate("Android::Internal::AndroidAvdManager", const QString errorOutput = QString::fromLatin1(avdProcess->readAllStandardOutput());
QMetaObject::invokeMethod(Core::ICore::mainWindow(), [errorOutput] {
const QString title
= QCoreApplication::translate("Android::Internal::AndroidAvdManager",
"AVD Start Error"); "AVD Start Error");
QMessageBox::critical(Core::ICore::dialogParent(), title, QMessageBox::critical(Core::ICore::dialogParent(), title, errorOutput);
QString::fromLatin1(avdProcess->readAllStandardOutput())); });
} }
avdProcess->deleteLater(); avdProcess->deleteLater();
}); });

View File

@@ -146,14 +146,14 @@ ClangdFollowSymbol::ClangdFollowSymbol(ClangdClient *client, const QTextCursor &
openInSplit)) openInSplit))
{ {
// Abort if the user does something else with the document in the meantime. // Abort if the user does something else with the document in the meantime.
connect(document, &TextDocument::contentsChanged, this, &ClangdFollowSymbol::emitDone, connect(document, &TextDocument::contentsChanged, this, [this] { emitDone(); },
Qt::QueuedConnection); Qt::QueuedConnection);
if (editorWidget) { if (editorWidget) {
connect(editorWidget, &CppEditorWidget::cursorPositionChanged, connect(editorWidget, &CppEditorWidget::cursorPositionChanged,
this, &ClangdFollowSymbol::emitDone, Qt::QueuedConnection); this, [this] { emitDone(); }, Qt::QueuedConnection);
} }
d->focusChangedConnection = connect(qApp, &QApplication::focusChanged, d->focusChangedConnection = connect(qApp, &QApplication::focusChanged,
this, &ClangdFollowSymbol::emitDone, Qt::QueuedConnection); this, [this] { emitDone(); }, Qt::QueuedConnection);
// Step 1: Follow the symbol via "Go to Definition". At the same time, request the // Step 1: Follow the symbol via "Go to Definition". At the same time, request the
// AST node corresponding to the cursor position, so we can find out whether // AST node corresponding to the cursor position, so we can find out whether
@@ -195,6 +195,7 @@ ClangdFollowSymbol::~ClangdFollowSymbol()
d->client->cancelRequest(id); d->client->cancelRequest(id);
for (const MessageId &id : qAsConst(d->pendingGotoDefRequests)) for (const MessageId &id : qAsConst(d->pendingGotoDefRequests))
d->client->cancelRequest(id); d->client->cancelRequest(id);
delete d;
} }
void ClangdFollowSymbol::clear() void ClangdFollowSymbol::clear()
@@ -205,12 +206,14 @@ void ClangdFollowSymbol::clear()
d->pendingGotoDefRequests.clear(); d->pendingGotoDefRequests.clear();
} }
void ClangdFollowSymbol::emitDone() void ClangdFollowSymbol::emitDone(const Link &link)
{ {
if (d->done) if (d->done)
return; return;
d->done = true; d->done = true;
if (link.hasValidTarget())
d->callback(link);
emit done(); emit done();
} }
@@ -246,14 +249,12 @@ void ClangdFollowSymbol::Private::handleDocumentInfoResults()
// If something went wrong, we just follow the original link. // If something went wrong, we just follow the original link.
if (symbolsToDisplay.isEmpty()) { if (symbolsToDisplay.isEmpty()) {
callback(defLink); q->emitDone(defLink);
q->emitDone();
return; return;
} }
if (symbolsToDisplay.size() == 1) { if (symbolsToDisplay.size() == 1) {
callback(symbolsToDisplay.first().second); q->emitDone(symbolsToDisplay.first().second);
q->emitDone();
return; return;
} }
@@ -382,8 +383,7 @@ void ClangdFollowSymbol::Private::handleGotoDefinitionResult()
// No dis-ambiguation necessary. Call back with the link and finish. // No dis-ambiguation necessary. Call back with the link and finish.
if (!defLinkIsAmbiguous()) { if (!defLinkIsAmbiguous()) {
callback(defLink); q->emitDone(defLink);
q->emitDone();
return; return;
} }
@@ -416,8 +416,7 @@ void ClangdFollowSymbol::Private::handleGotoImplementationResult(
// We didn't find any further candidates, so jump to the original definition link. // We didn't find any further candidates, so jump to the original definition link.
if (allLinks.size() == 1 && pendingGotoImplRequests.isEmpty()) { if (allLinks.size() == 1 && pendingGotoImplRequests.isEmpty()) {
callback(allLinks.first()); q->emitDone(allLinks.first());
q->emitDone();
return; return;
} }

View File

@@ -55,7 +55,7 @@ signals:
void done(); void done();
private: private:
void emitDone(); void emitDone(const Utils::Link &link = {});
class VirtualFunctionAssistProcessor; class VirtualFunctionAssistProcessor;
class VirtualFunctionAssistProvider; class VirtualFunctionAssistProvider;

View File

@@ -67,6 +67,7 @@ void ClangToolRunner::init(const FilePath &outputDirPath, const Environment &env
QTC_CHECK(!m_outputDirPath.isEmpty()); QTC_CHECK(!m_outputDirPath.isEmpty());
m_process.setEnvironment(environment); m_process.setEnvironment(environment);
m_process.setUseCtrlCStub(true);
m_process.setWorkingDirectory(m_outputDirPath); // Current clang-cl puts log file into working dir. m_process.setWorkingDirectory(m_outputDirPath); // Current clang-cl puts log file into working dir.
connect(&m_process, &QtcProcess::done, this, &ClangToolRunner::onProcessDone); connect(&m_process, &QtcProcess::done, this, &ClangToolRunner::onProcessDone);
} }

View File

@@ -1058,10 +1058,12 @@ void DebuggerEngine::setRunId(const QString &id)
void DebuggerEngine::setRunTool(DebuggerRunTool *runTool) void DebuggerEngine::setRunTool(DebuggerRunTool *runTool)
{ {
d->m_device = runTool->device(); d->m_device = runTool->device();
QTC_ASSERT(d->m_device, d->m_device = DeviceManager::deviceForPath(
d->m_runParameters.inferior.command.executable())); IDevice::ConstPtr debuggerDevice =
if (QTC_GUARD(d->m_device)) DeviceManager::deviceForPath(d->m_runParameters.debugger.command.executable());
d->m_runParameters.dumperPath = d->m_device->debugDumperPath(); if (QTC_GUARD(debuggerDevice))
d->m_runParameters.dumperPath = debuggerDevice->debugDumperPath();
d->m_terminalRunner = runTool->terminalRunner(); d->m_terminalRunner = runTool->terminalRunner();
validateRunParameters(d->m_runParameters); validateRunParameters(d->m_runParameters);

View File

@@ -274,7 +274,7 @@ GitLabOptionsPage::GitLabOptionsPage(GitLabParameters *p, QObject *parent)
: Core::IOptionsPage{parent} : Core::IOptionsPage{parent}
, m_parameters(p) , m_parameters(p)
{ {
setId("GitLab"); setId(Constants::GITLAB_SETTINGS);
setDisplayName(tr("GitLab")); setDisplayName(tr("GitLab"));
setCategory(VcsBase::Constants::VCS_SETTINGS_CATEGORY); setCategory(VcsBase::Constants::VCS_SETTINGS_CATEGORY);
} }

View File

@@ -39,6 +39,10 @@ QT_END_NAMESPACE
namespace GitLab { namespace GitLab {
namespace Constants {
const char GITLAB_SETTINGS[] = "GitLab";
} // namespace Constants
class GitLabServerWidget : public QWidget class GitLabServerWidget : public QWidget
{ {
public: public:

View File

@@ -136,6 +136,7 @@ GitLabProjectSettingsWidget::GitLabProjectSettingsWidget(ProjectExplorer::Projec
{ {
setUseGlobalSettingsCheckBoxVisible(false); setUseGlobalSettingsCheckBoxVisible(false);
setUseGlobalSettingsLabelVisible(true); setUseGlobalSettingsLabelVisible(true);
setGlobalSettingsId(Constants::GITLAB_SETTINGS);
// setup ui // setup ui
auto verticalLayout = new QVBoxLayout(this); auto verticalLayout = new QVBoxLayout(this);
verticalLayout->setContentsMargins(0, 0, 0, 0); verticalLayout->setContentsMargins(0, 0, 0, 0);

View File

@@ -606,8 +606,10 @@ void AppOutputPane::stopRunControl()
QTC_ASSERT(rc, return); QTC_ASSERT(rc, return);
if (rc->isRunning()) { if (rc->isRunning()) {
if (optionallyPromptToStop(rc)) if (optionallyPromptToStop(rc)) {
rc->initiateStop(); rc->initiateStop();
enableButtons(rc);
}
} else { } else {
QTC_CHECK(false); QTC_CHECK(false);
rc->forceStop(); rc->forceStop();

View File

@@ -201,7 +201,6 @@ BuildConfiguration::BuildConfiguration(Target *target, Utils::Id id)
tr("Variables in the build configuration's environment"), tr("Variables in the build configuration's environment"),
[this](const QString &var) { return environment().expandedValueForKey(var); }); [this](const QString &var) { return environment().expandedValueForKey(var); });
updateCacheAndEmitEnvironmentChanged();
connect(Core::ICore::instance(), &Core::ICore::systemEnvironmentChanged, connect(Core::ICore::instance(), &Core::ICore::systemEnvironmentChanged,
this, &BuildConfiguration::updateCacheAndEmitEnvironmentChanged); this, &BuildConfiguration::updateCacheAndEmitEnvironmentChanged);
connect(target, &Target::kitChanged, connect(target, &Target::kitChanged,
@@ -292,6 +291,8 @@ void BuildConfiguration::addConfigWidgets(const std::function<void(NamedWidget *
void BuildConfiguration::doInitialize(const BuildInfo &info) void BuildConfiguration::doInitialize(const BuildInfo &info)
{ {
updateCacheAndEmitEnvironmentChanged();
setDisplayName(info.displayName); setDisplayName(info.displayName);
setDefaultDisplayName(info.displayName); setDefaultDisplayName(info.displayName);
setBuildDirectory(info.buildDirectory); setBuildDirectory(info.buildDirectory);

View File

@@ -164,6 +164,8 @@ MaterialBrowserWidget::MaterialBrowserWidget()
m_qmlSourceUpdateShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_F8), this); m_qmlSourceUpdateShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_F8), this);
connect(m_qmlSourceUpdateShortcut, &QShortcut::activated, this, &MaterialBrowserWidget::reloadQmlSource); connect(m_qmlSourceUpdateShortcut, &QShortcut::activated, this, &MaterialBrowserWidget::reloadQmlSource);
QmlDesignerPlugin::trackWidgetFocusTime(this, Constants::EVENT_MATERIALBROWSER_TIME);
reloadQmlSource(); reloadQmlSource();
} }

View File

@@ -31,18 +31,17 @@
#include "materialeditortransaction.h" #include "materialeditortransaction.h"
#include "assetslibrarywidget.h" #include "assetslibrarywidget.h"
#include <qmldesignerconstants.h> #include <bindingproperty.h>
#include <qmltimeline.h> #include <metainfo.h>
#include <nodeinstanceview.h>
#include <nodelistproperty.h>
#include <nodemetainfo.h> #include <nodemetainfo.h>
#include <nodeproperty.h> #include <nodeproperty.h>
#include <nodelistproperty.h>
#include <nodeinstanceview.h>
#include <metainfo.h>
#include <rewritingexception.h> #include <rewritingexception.h>
#include <variantproperty.h> #include <variantproperty.h>
#include <qmldesignerconstants.h>
#include <bindingproperty.h> #include <qmldesignerplugin.h>
#include <qmltimeline.h>
#include <theme.h> #include <theme.h>
@@ -86,6 +85,7 @@ MaterialEditorView::MaterialEditorView(QWidget *parent)
m_stackedWidget->setStyleSheet(Theme::replaceCssColors( m_stackedWidget->setStyleSheet(Theme::replaceCssColors(
QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css")))); QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css"))));
m_stackedWidget->setMinimumWidth(250); m_stackedWidget->setMinimumWidth(250);
QmlDesignerPlugin::trackWidgetFocusTime(m_stackedWidget, Constants::EVENT_MATERIALEDITOR_TIME);
} }
MaterialEditorView::~MaterialEditorView() MaterialEditorView::~MaterialEditorView()

View File

@@ -116,8 +116,9 @@ public:
int minorVersion, int minorVersion,
const PropertyListType &propertyList = PropertyListType(), const PropertyListType &propertyList = PropertyListType(),
const PropertyListType &auxPropertyList = PropertyListType(), const PropertyListType &auxPropertyList = PropertyListType(),
const QString &nodeSource = QString(), const QString &nodeSource = {},
ModelNode::NodeSourceType nodeSourceType = ModelNode::NodeWithoutSource); ModelNode::NodeSourceType nodeSourceType = ModelNode::NodeWithoutSource,
const QString &behaviorPropertyName = {});
ModelNode rootModelNode() const; ModelNode rootModelNode() const;
ModelNode rootModelNode(); ModelNode rootModelNode();

View File

@@ -238,6 +238,7 @@ public:
bool isComponent() const; bool isComponent() const;
bool isSubclassOf(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1) const; bool isSubclassOf(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1) const;
QIcon typeIcon() const; QIcon typeIcon() const;
QString behaviorPropertyName() const;
friend void swap(ModelNode &first, ModelNode &second) noexcept friend void swap(ModelNode &first, ModelNode &second) noexcept
{ {

View File

@@ -1050,6 +1050,7 @@ CreateSceneCommand NodeInstanceView::createCreateSceneCommand()
nodeMetaType, nodeMetaType,
nodeFlags); nodeFlags);
if (instance.modelNode().behaviorPropertyName().isEmpty())
instanceContainerList.append(container); instanceContainerList.append(container);
} }

View File

@@ -78,6 +78,15 @@ using PropertyInfo = QPair<PropertyName, TypeName>;
QVector<PropertyInfo> getObjectTypes(const ObjectValue *ov, const ContextPtr &context, bool local = false, int rec = 0); QVector<PropertyInfo> getObjectTypes(const ObjectValue *ov, const ContextPtr &context, bool local = false, int rec = 0);
static QByteArray getUnqualifiedName(const QByteArray &name)
{
const QList<QByteArray> nameComponents = name.split('.');
if (nameComponents.size() < 2)
return name;
return nameComponents.constLast();
}
static TypeName resolveTypeName(const ASTPropertyReference *ref, const ContextPtr &context, QVector<PropertyInfo> &dotProperties) static TypeName resolveTypeName(const ASTPropertyReference *ref, const ContextPtr &context, QVector<PropertyInfo> &dotProperties)
{ {
TypeName type = "unknown"; TypeName type = "unknown";
@@ -765,13 +774,16 @@ NodeMetaInfoPrivate::NodeMetaInfoPrivate(Model *model, TypeName type, int maj, i
} else { } else {
m_isFileComponent = true; m_isFileComponent = true;
const Imports *imports = context()->imports(document()); const Imports *imports = context()->imports(document());
const ImportInfo importInfo = imports->info(lookupNameComponent().constLast(), context().data()); const ImportInfo importInfo = imports->info(lookupNameComponent().constLast(),
context().data());
if (importInfo.isValid()) { if (importInfo.isValid()) {
if (importInfo.type() == ImportType::Library) { if (importInfo.type() == ImportType::Library) {
m_majorVersion = importInfo.version().majorVersion(); m_majorVersion = importInfo.version().majorVersion();
m_minorVersion = importInfo.version().minorVersion(); m_minorVersion = importInfo.version().minorVersion();
} }
bool prepandName = (importInfo.type() == ImportType::Library || importInfo.type() == ImportType::Directory) bool prepandName = (importInfo.type() == ImportType::Library
|| importInfo.type() == ImportType::Directory)
&& !m_qualfiedTypeName.contains('.'); && !m_qualfiedTypeName.contains('.');
if (prepandName) if (prepandName)
m_qualfiedTypeName.prepend(importInfo.name().toUtf8() + '.'); m_qualfiedTypeName.prepend(importInfo.name().toUtf8() + '.');
@@ -781,6 +793,30 @@ NodeMetaInfoPrivate::NodeMetaInfoPrivate(Model *model, TypeName type, int maj, i
m_defaultPropertyName = context()->defaultPropertyName(objectValue).toUtf8(); m_defaultPropertyName = context()->defaultPropertyName(objectValue).toUtf8();
m_isValid = true; m_isValid = true;
setupPrototypes(); setupPrototypes();
} else {
// Special case for aliased types for the rewriter
const Imports *imports = context()->imports(document());
const ImportInfo importInfo = imports->info(QString::fromUtf8(m_qualfiedTypeName),
context().data());
if (importInfo.isValid()) {
if (importInfo.type() == ImportType::Library) {
m_majorVersion = importInfo.version().majorVersion();
m_minorVersion = importInfo.version().minorVersion();
}
m_qualfiedTypeName = getUnqualifiedName(m_qualfiedTypeName);
bool prepandName = (importInfo.type() == ImportType::Library
|| importInfo.type() == ImportType::Directory);
if (prepandName)
m_qualfiedTypeName.prepend(importInfo.name().toUtf8() + '.');
}
m_objectValue = getObjectValue();
m_defaultPropertyName = context()->defaultPropertyName(objectValue).toUtf8();
m_isValid = true;
setupPrototypes();
} }
} }
} }
@@ -1009,14 +1045,6 @@ bool NodeMetaInfoPrivate::isPropertyEnum(const PropertyName &propertyName) const
return qmlObjectValue->getEnum(QString::fromUtf8(propertyType(propertyName))).isValid(); return qmlObjectValue->getEnum(QString::fromUtf8(propertyType(propertyName))).isValid();
} }
static QByteArray getUnqualifiedName(const QByteArray &name)
{
const QList<QByteArray> nameComponents = name.split('.');
if (nameComponents.size() < 2)
return name;
return nameComponents.constLast();
}
static QByteArray getPackage(const QByteArray &name) static QByteArray getPackage(const QByteArray &name)
{ {
QList<QByteArray> nameComponents = name.split('.'); QList<QByteArray> nameComponents = name.split('.');

View File

@@ -102,9 +102,10 @@ ModelNode AbstractView::createModelNode(const TypeName &typeName,
const QList<QPair<PropertyName, QVariant>> &propertyList, const QList<QPair<PropertyName, QVariant>> &propertyList,
const QList<QPair<PropertyName, QVariant>> &auxPropertyList, const QList<QPair<PropertyName, QVariant>> &auxPropertyList,
const QString &nodeSource, const QString &nodeSource,
ModelNode::NodeSourceType nodeSourceType) ModelNode::NodeSourceType nodeSourceType,
const QString &behaviorPropertyName)
{ {
return ModelNode(model()->d->createNode(typeName, majorVersion, minorVersion, propertyList, auxPropertyList, nodeSource, nodeSourceType), model(), this); return ModelNode(model()->d->createNode(typeName, majorVersion, minorVersion, propertyList, auxPropertyList, nodeSource, nodeSourceType, behaviorPropertyName), model(), this);
} }

View File

@@ -389,5 +389,15 @@ void InternalNode::setNodeSourceType(int i)
m_nodeSourceType = i; m_nodeSourceType = i;
} }
QString InternalNode::behaviorPropertyName() const
{
return m_behaviorPropertyName;
}
void InternalNode::setBehaviorPropertyName(const QString &name)
{
m_behaviorPropertyName = name;
}
} }
} }

View File

@@ -123,6 +123,9 @@ public:
int nodeSourceType() const; int nodeSourceType() const;
void setNodeSourceType(int i); void setNodeSourceType(int i);
QString behaviorPropertyName() const;
void setBehaviorPropertyName(const QString &name);
protected: protected:
Pointer internalPointer() const; Pointer internalPointer() const;
void setInternalWeakPointer(const Pointer &pointer); void setInternalWeakPointer(const Pointer &pointer);
@@ -149,6 +152,8 @@ private:
QString m_nodeSource; QString m_nodeSource;
int m_nodeSourceType = 0; int m_nodeSourceType = 0;
QString m_behaviorPropertyName;
}; };
size_t qHash(const InternalNodePointer& node); size_t qHash(const InternalNodePointer& node);

View File

@@ -97,9 +97,11 @@ ModelPrivate::ModelPrivate(Model *model)
0, 0,
PropertyListType(), PropertyListType(),
PropertyListType(), PropertyListType(),
QString(), {},
ModelNode::NodeWithoutSource, ModelNode::NodeWithoutSource,
{},
true); true);
m_currentStateNode = m_rootInternalNode; m_currentStateNode = m_rootInternalNode;
m_currentTimelineNode = m_rootInternalNode; m_currentTimelineNode = m_rootInternalNode;
} }
@@ -250,6 +252,7 @@ InternalNodePointer ModelPrivate::createNode(const TypeName &typeName,
const QList<QPair<PropertyName, QVariant>> &auxPropertyList, const QList<QPair<PropertyName, QVariant>> &auxPropertyList,
const QString &nodeSource, const QString &nodeSource,
ModelNode::NodeSourceType nodeSourceType, ModelNode::NodeSourceType nodeSourceType,
const QString &behaviorPropertyName,
bool isRootNode) bool isRootNode)
{ {
if (typeName.isEmpty()) if (typeName.isEmpty())
@@ -263,6 +266,8 @@ InternalNodePointer ModelPrivate::createNode(const TypeName &typeName,
InternalNodePointer newNode = InternalNode::create(typeName, majorVersion, minorVersion, internalId); InternalNodePointer newNode = InternalNode::create(typeName, majorVersion, minorVersion, internalId);
newNode->setNodeSourceType(nodeSourceType); newNode->setNodeSourceType(nodeSourceType);
newNode->setBehaviorPropertyName(behaviorPropertyName);
using PropertyPair = QPair<PropertyName, QVariant>; using PropertyPair = QPair<PropertyName, QVariant>;
for (const PropertyPair &propertyPair : propertyList) { for (const PropertyPair &propertyPair : propertyList) {
@@ -400,7 +405,7 @@ void ModelPrivate::notifyNodeInstanceViewLast(Callable call)
resetModel = true; resetModel = true;
} }
for (QPointer<AbstractView> view : enabledViews()) { for (const QPointer<AbstractView> &view : enabledViews()) {
if (!view->isBlockingNotifications()) if (!view->isBlockingNotifications())
call(view.data()); call(view.data());
} }
@@ -429,7 +434,7 @@ void ModelPrivate::notifyNormalViewsLast(Callable call)
if (nodeInstanceView() && !nodeInstanceView()->isBlockingNotifications()) if (nodeInstanceView() && !nodeInstanceView()->isBlockingNotifications())
call(nodeInstanceView()); call(nodeInstanceView());
for (QPointer<AbstractView> view : enabledViews()) { for (const QPointer<AbstractView> &view : enabledViews()) {
if (!view->isBlockingNotifications()) if (!view->isBlockingNotifications())
call(view.data()); call(view.data());
} }
@@ -441,7 +446,7 @@ void ModelPrivate::notifyNormalViewsLast(Callable call)
template<typename Callable> template<typename Callable>
void ModelPrivate::notifyInstanceChanges(Callable call) void ModelPrivate::notifyInstanceChanges(Callable call)
{ {
for (QPointer<AbstractView> view : enabledViews()) { for (const QPointer<AbstractView> &view : enabledViews()) {
if (!view->isBlockingNotifications()) if (!view->isBlockingNotifications())
call(view.data()); call(view.data());
} }

View File

@@ -104,6 +104,7 @@ public:
const QList<QPair<PropertyName, QVariant> > &auxPropertyList, const QList<QPair<PropertyName, QVariant> > &auxPropertyList,
const QString &nodeSource, const QString &nodeSource,
ModelNode::NodeSourceType nodeSourceType, ModelNode::NodeSourceType nodeSourceType,
const QString &behaviorPropertyName,
bool isRootNode = false); bool isRootNode = false);

View File

@@ -197,7 +197,8 @@ static bool isIdToAvoid(const QString& id)
"shaderInfo", "shaderInfo",
"sprite", "sprite",
"spriteSequence", "spriteSequence",
"baseState" "baseState",
"rect"
}; };
return ids.contains(id); return ids.contains(id);
@@ -1435,4 +1436,12 @@ QIcon ModelNode::typeIcon() const
return QIcon(QStringLiteral(":/ItemLibrary/images/item-invalid-icon.png")); return QIcon(QStringLiteral(":/ItemLibrary/images/item-invalid-icon.png"));
} }
QString ModelNode::behaviorPropertyName() const
{
if (m_internalNode.isNull())
return {};
return m_internalNode->behaviorPropertyName();
}
} }

View File

@@ -218,6 +218,10 @@ QString QmlTextGenerator::toQml(const ModelNode &node, int indentDepth) const
result = alias + '.'; result = alias + '.';
result += type; result += type;
if (!node.behaviorPropertyName().isEmpty()) {
result += " on " + node.behaviorPropertyName();
}
result += QStringLiteral(" {\n"); result += QStringLiteral(" {\n");
const int propertyIndentDepth = indentDepth + m_tabSettings.m_indentSize; const int propertyIndentDepth = indentDepth + m_tabSettings.m_indentSize;

View File

@@ -276,7 +276,7 @@ bool RemoveNodeRewriteAction::execute(QmlRefactoring &refactoring, ModelNodePosi
QString RemoveNodeRewriteAction::info() const QString RemoveNodeRewriteAction::info() const
{ {
return QLatin1String("RemoveNodeRewriteAction"); return QLatin1String("RemoveNodeRewriteAction") + QString::number(m_node.internalId());
} }
bool RemovePropertyRewriteAction::execute(QmlRefactoring &refactoring, ModelNodePositionStorage &positionStore) bool RemovePropertyRewriteAction::execute(QmlRefactoring &refactoring, ModelNodePositionStorage &positionStore)

View File

@@ -40,6 +40,7 @@
#include "propertyparser.h" #include "propertyparser.h"
#include "rewriterview.h" #include "rewriterview.h"
#include "variantproperty.h" #include "variantproperty.h"
#include <rewritingexception.h>
#include <enumeration.h> #include <enumeration.h>
@@ -435,13 +436,14 @@ class ReadingContext
{ {
public: public:
ReadingContext(const Snapshot &snapshot, const Document::Ptr &doc, ReadingContext(const Snapshot &snapshot, const Document::Ptr &doc,
const ViewerContext &vContext) const ViewerContext &vContext, Model *model)
: m_doc(doc) : m_doc(doc)
, m_context( , m_context(
Link(snapshot, vContext, ModelManagerInterface::instance()->builtins(doc)) Link(snapshot, vContext, ModelManagerInterface::instance()->builtins(doc))
(doc, &m_diagnosticLinkMessages)) (doc, &m_diagnosticLinkMessages))
, m_scopeChain(doc, m_context) , m_scopeChain(doc, m_context)
, m_scopeBuilder(&m_scopeChain) , m_scopeBuilder(&m_scopeChain)
, m_model(model)
{ {
} }
@@ -507,6 +509,36 @@ public:
typeName.prepend(name + QLatin1Char('.')); typeName.prepend(name + QLatin1Char('.'));
} }
} }
{
TypeName fullTypeName;
for (AST::UiQualifiedId *iter = astTypeNode; iter; iter = iter->next)
if (!iter->name.isEmpty())
fullTypeName += iter->name.toUtf8() + '.';
if (fullTypeName.endsWith('.'))
fullTypeName.chop(1);
NodeMetaInfo metaInfo = m_model->metaInfo(fullTypeName);
bool ok = metaInfo.typeName() == typeName.toUtf8()
&& metaInfo.majorVersion() == majorVersion
&& metaInfo.minorVersion() == minorVersion;
if (!ok) {
qDebug() << Q_FUNC_INFO;
qDebug() << astTypeNode->name.toString() << typeName;
qDebug() << metaInfo.isValid() << metaInfo.typeName();
qDebug() << metaInfo.directSuperClass().typeName();
if (!typeName.startsWith("..."))
throw RewritingException(__LINE__, __FUNCTION__, __FILE__, "test", "test");
}
typeName = QString::fromUtf8(metaInfo.typeName());
majorVersion = metaInfo.majorVersion();
minorVersion = metaInfo.minorVersion();
}
} }
/// When something is changed here, also change Check::checkScopeObjectMember in /// When something is changed here, also change Check::checkScopeObjectMember in
@@ -759,6 +791,7 @@ private:
ContextPtr m_context; ContextPtr m_context;
ScopeChain m_scopeChain; ScopeChain m_scopeChain;
ScopeBuilder m_scopeBuilder; ScopeBuilder m_scopeBuilder;
Model *m_model;
}; };
} // namespace Internal } // namespace Internal
@@ -1127,7 +1160,7 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH
m_vContext = ModelManagerInterface::instance()->projectVContext(Dialect::Qml, m_document); m_vContext = ModelManagerInterface::instance()->projectVContext(Dialect::Qml, m_document);
ReadingContext ctxt(snapshot, m_document, m_vContext); ReadingContext ctxt(snapshot, m_document, m_vContext, m_rewriterView->model());
m_scopeChain = QSharedPointer<const ScopeChain>( m_scopeChain = QSharedPointer<const ScopeChain>(
new ScopeChain(ctxt.scopeChain())); new ScopeChain(ctxt.scopeChain()));
@@ -1188,6 +1221,15 @@ void TextToModelMerger::syncNode(ModelNode &modelNode,
ReadingContext *context, ReadingContext *context,
DifferenceHandler &differenceHandler) DifferenceHandler &differenceHandler)
{ {
auto binding = AST::cast<AST::UiObjectBinding *>(astNode);
const bool hasOnToken = binding && binding->hasOnToken;
QString onTokenProperty;
if (hasOnToken)
onTokenProperty = toString(binding->qualifiedId);
AST::UiQualifiedId *astObjectType = qualifiedTypeNameId(astNode); AST::UiQualifiedId *astObjectType = qualifiedTypeNameId(astNode);
AST::UiObjectInitializer *astInitializer = initializerOfObject(astNode); AST::UiObjectInitializer *astInitializer = initializerOfObject(astNode);
@@ -1224,10 +1266,10 @@ void TextToModelMerger::syncNode(ModelNode &modelNode,
bool isImplicitComponent = modelNode.hasParentProperty() && propertyIsComponentType(modelNode.parentProperty(), typeName, modelNode.model()); bool isImplicitComponent = modelNode.hasParentProperty() && propertyIsComponentType(modelNode.parentProperty(), typeName, modelNode.model());
if (modelNode.type()
if (modelNode.type() != typeName //If there is no valid parentProperty //the node has just been created. The type is correct then. != typeName //If there is no valid parentProperty //the node has just been created. The type is correct then.
|| modelNode.majorVersion() != majorVersion || modelNode.majorVersion() != majorVersion || modelNode.minorVersion() != minorVersion
|| modelNode.minorVersion() != minorVersion) { || modelNode.behaviorPropertyName() != onTokenProperty) {
const bool isRootNode = m_rewriterView->rootModelNode() == modelNode; const bool isRootNode = m_rewriterView->rootModelNode() == modelNode;
differenceHandler.typeDiffers(isRootNode, modelNode, typeName, differenceHandler.typeDiffers(isRootNode, modelNode, typeName,
majorVersion, minorVersion, majorVersion, minorVersion,
@@ -1294,7 +1336,8 @@ void TextToModelMerger::syncNode(ModelNode &modelNode,
} else if (auto binding = AST::cast<AST::UiObjectBinding *>(member)) { } else if (auto binding = AST::cast<AST::UiObjectBinding *>(member)) {
const QString astPropertyName = toString(binding->qualifiedId); const QString astPropertyName = toString(binding->qualifiedId);
if (binding->hasOnToken) { if (binding->hasOnToken) {
// skip value sources // Store Behaviours in the default property
defaultPropertyItems.append(member);
} else { } else {
const Value *propertyType = nullptr; const Value *propertyType = nullptr;
const ObjectValue *containingObject = nullptr; const ObjectValue *containingObject = nullptr;
@@ -1690,6 +1733,13 @@ ModelNode TextToModelMerger::createModelNode(const TypeName &typeName,
{ {
QString nodeSource; QString nodeSource;
auto binding = AST::cast<AST::UiObjectBinding *>(astNode);
const bool hasOnToken = binding && binding->hasOnToken;
QString onTokenProperty;
if (hasOnToken)
onTokenProperty = toString(binding->qualifiedId);
AST::UiQualifiedId *astObjectType = qualifiedTypeNameId(astNode); AST::UiQualifiedId *astObjectType = qualifiedTypeNameId(astNode);
@@ -1721,7 +1771,8 @@ ModelNode TextToModelMerger::createModelNode(const TypeName &typeName,
PropertyListType(), PropertyListType(),
PropertyListType(), PropertyListType(),
nodeSource, nodeSource,
nodeSourceType); nodeSourceType,
onTokenProperty);
syncNode(newNode, astNode, context, differenceHandler); syncNode(newNode, astNode, context, differenceHandler);
return newNode; return newNode;

View File

@@ -131,6 +131,8 @@ const char EVENT_ITEMLIBRARY_TIME[] = "itemLibrary";
const char EVENT_TRANSLATIONVIEW_TIME[] = "translationView"; const char EVENT_TRANSLATIONVIEW_TIME[] = "translationView";
const char EVENT_NAVIGATORVIEW_TIME[] = "navigatorView"; const char EVENT_NAVIGATORVIEW_TIME[] = "navigatorView";
const char EVENT_DESIGNMODE_TIME[] = "designMode"; const char EVENT_DESIGNMODE_TIME[] = "designMode";
const char EVENT_MATERIALEDITOR_TIME[] = "materialEditor";
const char EVENT_MATERIALBROWSER_TIME[] = "materialBrowser";
const char PROPERTY_EDITOR_CLASSNAME_PROPERTY[] = "__classNamePrivateInternal"; const char PROPERTY_EDITOR_CLASSNAME_PROPERTY[] = "__classNamePrivateInternal";

View File

@@ -90,10 +90,13 @@ void generateMenuEntry(QObject *parent)
Core::Command *cmd = Core::ActionManager::registerAction(action, "QmlProject.CreateCMakeLists"); Core::Command *cmd = Core::ActionManager::registerAction(action, "QmlProject.CreateCMakeLists");
menu->addAction(cmd, Core::Constants::G_FILE_EXPORT); menu->addAction(cmd, Core::Constants::G_FILE_EXPORT);
action->setEnabled(ProjectExplorer::SessionManager::startupProject() != nullptr); action->setEnabled(false);
QObject::connect(ProjectExplorer::SessionManager::instance(), QObject::connect(ProjectExplorer::SessionManager::instance(),
&ProjectExplorer::SessionManager::startupProjectChanged, [action]() { &ProjectExplorer::SessionManager::startupProjectChanged,
action->setEnabled(ProjectExplorer::SessionManager::startupProject() != nullptr); [action]() {
auto qmlProject = qobject_cast<QmlProject *>(
ProjectExplorer::SessionManager::startupProject());
action->setEnabled(qmlProject != nullptr);
}); });
} }

View File

@@ -379,6 +379,7 @@ bool QmlProjectPlugin::initialize(const QStringList &, QString *errorMessage)
} }
GenerateCmake::generateMenuEntry(this); GenerateCmake::generateMenuEntry(this);
if (QmlProject::isQtDesignStudio())
GenerateCmake::CmakeProjectConverter::generateMenuEntry(this); GenerateCmake::CmakeProjectConverter::generateMenuEntry(this);
return true; return true;

View File

@@ -7504,7 +7504,7 @@ QMimeData *TextEditorWidget::createMimeDataFromSelection() const
tempCursor.setCharFormat(range.format); tempCursor.setCharFormat(range.format);
} }
} else { } else {
const int startPosition = current.position() - start.position() const int startPosition = current.position() - selectionStart
- removedCount; - removedCount;
int endPosition = startPosition + current.text().count(); int endPosition = startPosition + current.text().count();
if (current != last) if (current != last)

View File

@@ -31,6 +31,8 @@
namespace Todo { namespace Todo {
namespace Constants { namespace Constants {
const char TODO_SETTINGS[] = "TodoSettings";
// Settings entries // Settings entries
const char SETTINGS_GROUP[] = "TodoPlugin"; const char SETTINGS_GROUP[] = "TodoPlugin";
const char SCANNING_SCOPE[] = "ScanningScope"; const char SCANNING_SCOPE[] = "ScanningScope";

View File

@@ -26,8 +26,9 @@
#include "optionsdialog.h" #include "optionsdialog.h"
#include "keyworddialog.h" #include "constants.h"
#include "keyword.h" #include "keyword.h"
#include "keyworddialog.h"
#include "settings.h" #include "settings.h"
#include "todotr.h" #include "todotr.h"
@@ -267,7 +268,7 @@ void OptionsDialog::apply()
TodoOptionsPage::TodoOptionsPage(Settings *settings, const std::function<void ()> &onApply) TodoOptionsPage::TodoOptionsPage(Settings *settings, const std::function<void ()> &onApply)
{ {
setId("TodoSettings"); setId(Constants::TODO_SETTINGS);
setDisplayName(Tr::tr("To-Do")); setDisplayName(Tr::tr("To-Do"));
setCategory("To-Do"); setCategory("To-Do");
setDisplayCategory(Tr::tr("To-Do")); setDisplayCategory(Tr::tr("To-Do"));

View File

@@ -71,8 +71,11 @@ TodoProjectSettingsWidget::TodoProjectSettingsWidget(ProjectExplorer::Project *p
}.attachTo(this); }.attachTo(this);
setExcludedPatternsButtonsEnabled(); setExcludedPatternsButtonsEnabled();
connect(addExcludedPatternButton, &QPushButton::clicked, setGlobalSettingsId(Constants::TODO_SETTINGS);
this, &TodoProjectSettingsWidget::addExcludedPatternButtonClicked); connect(addExcludedPatternButton,
&QPushButton::clicked,
this,
&TodoProjectSettingsWidget::addExcludedPatternButtonClicked);
connect(m_removeExcludedPatternButton, &QPushButton::clicked, connect(m_removeExcludedPatternButton, &QPushButton::clicked,
this, &TodoProjectSettingsWidget::removeExcludedPatternButtonClicked); this, &TodoProjectSettingsWidget::removeExcludedPatternButtonClicked);
connect(m_excludedPatternsList, &QListWidget::itemChanged, connect(m_excludedPatternsList, &QListWidget::itemChanged,

View File

@@ -33,7 +33,7 @@
# but it is only necessary on the end-user side. It is not necessary to create conan # but it is only necessary on the end-user side. It is not necessary to create conan
# packages, in fact it shouldn't be use for that. Check the project documentation. # packages, in fact it shouldn't be use for that. Check the project documentation.
# version: 0.16.0-dev # version: 0.18.1
include(CMakeParseArguments) include(CMakeParseArguments)
@@ -55,23 +55,14 @@ function(_get_msvc_ide_version result)
set(${result} 15 PARENT_SCOPE) set(${result} 15 PARENT_SCOPE)
elseif(NOT MSVC_VERSION VERSION_LESS 1920 AND MSVC_VERSION VERSION_LESS 1930) elseif(NOT MSVC_VERSION VERSION_LESS 1920 AND MSVC_VERSION VERSION_LESS 1930)
set(${result} 16 PARENT_SCOPE) set(${result} 16 PARENT_SCOPE)
elseif(NOT MSVC_VERSION VERSION_LESS 1930 AND MSVC_VERSION VERSION_LESS 1940)
set(${result} 17 PARENT_SCOPE)
else() else()
message(FATAL_ERROR "Conan: Unknown MSVC compiler version [${MSVC_VERSION}]") message(FATAL_ERROR "Conan: Unknown MSVC compiler version [${MSVC_VERSION}]")
endif() endif()
endfunction() endfunction()
function(conan_cmake_settings result) macro(_conan_detect_build_type)
#message(STATUS "COMPILER " ${CMAKE_CXX_COMPILER})
#message(STATUS "COMPILER " ${CMAKE_CXX_COMPILER_ID})
#message(STATUS "VERSION " ${CMAKE_CXX_COMPILER_VERSION})
#message(STATUS "FLAGS " ${CMAKE_LANG_FLAGS})
#message(STATUS "LIB ARCH " ${CMAKE_CXX_LIBRARY_ARCHITECTURE})
#message(STATUS "BUILD TYPE " ${CMAKE_BUILD_TYPE})
#message(STATUS "GENERATOR " ${CMAKE_GENERATOR})
#message(STATUS "GENERATOR WIN64 " ${CMAKE_CL_64})
message(STATUS "Conan: Automatic detection of conan settings from cmake")
conan_parse_arguments(${ARGV}) conan_parse_arguments(${ARGV})
if(ARGUMENTS_BUILD_TYPE) if(ARGUMENTS_BUILD_TYPE)
@@ -92,10 +83,9 @@ function(conan_cmake_settings result)
elseif(_CONAN_SETTING_BUILD_TYPE_UPPER STREQUAL "MINSIZEREL") elseif(_CONAN_SETTING_BUILD_TYPE_UPPER STREQUAL "MINSIZEREL")
set(_CONAN_SETTING_BUILD_TYPE "MinSizeRel") set(_CONAN_SETTING_BUILD_TYPE "MinSizeRel")
endif() endif()
endmacro()
if(ARGUMENTS_ARCH) macro(_conan_check_system_name)
set(_CONAN_SETTING_ARCH ${ARGUMENTS_ARCH})
endif()
#handle -s os setting #handle -s os setting
if(CMAKE_SYSTEM_NAME AND NOT CMAKE_SYSTEM_NAME STREQUAL "Generic") if(CMAKE_SYSTEM_NAME AND NOT CMAKE_SYSTEM_NAME STREQUAL "Generic")
#use default conan os setting if CMAKE_SYSTEM_NAME is not defined #use default conan os setting if CMAKE_SYSTEM_NAME is not defined
@@ -115,7 +105,9 @@ function(conan_cmake_settings result)
message(FATAL_ERROR "cmake system ${CONAN_SYSTEM_NAME} is not supported by conan. Use one of ${CONAN_SUPPORTED_PLATFORMS}") message(FATAL_ERROR "cmake system ${CONAN_SYSTEM_NAME} is not supported by conan. Use one of ${CONAN_SUPPORTED_PLATFORMS}")
endif() endif()
endif() endif()
endmacro()
macro(_conan_check_language)
get_property(_languages GLOBAL PROPERTY ENABLED_LANGUAGES) get_property(_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
if (";${_languages};" MATCHES ";CXX;") if (";${_languages};" MATCHES ";CXX;")
set(LANGUAGE CXX) set(LANGUAGE CXX)
@@ -126,6 +118,19 @@ function(conan_cmake_settings result)
else () else ()
message(FATAL_ERROR "Conan: Neither C or C++ was detected as a language for the project. Unabled to detect compiler version.") message(FATAL_ERROR "Conan: Neither C or C++ was detected as a language for the project. Unabled to detect compiler version.")
endif() endif()
endmacro()
macro(_conan_detect_compiler)
conan_parse_arguments(${ARGV})
if(ARGUMENTS_ARCH)
set(_CONAN_SETTING_ARCH ${ARGUMENTS_ARCH})
endif()
if(USING_CXX)
set(_CONAN_SETTING_COMPILER_CPPSTD ${CMAKE_CXX_STANDARD})
endif()
if (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL GNU) if (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL GNU)
# using GCC # using GCC
@@ -143,6 +148,17 @@ function(conan_cmake_settings result)
conan_cmake_detect_unix_libcxx(_LIBCXX) conan_cmake_detect_unix_libcxx(_LIBCXX)
set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX})
endif () endif ()
elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL Intel)
string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION})
list(GET VERSION_LIST 0 MAJOR)
list(GET VERSION_LIST 1 MINOR)
set(COMPILER_VERSION ${MAJOR}.${MINOR})
set(_CONAN_SETTING_COMPILER intel)
set(_CONAN_SETTING_COMPILER_VERSION ${COMPILER_VERSION})
if (USING_CXX)
conan_cmake_detect_unix_libcxx(_LIBCXX)
set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX})
endif ()
elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL AppleClang) elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL AppleClang)
# using AppleClang # using AppleClang
string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION})
@@ -154,7 +170,10 @@ function(conan_cmake_settings result)
conan_cmake_detect_unix_libcxx(_LIBCXX) conan_cmake_detect_unix_libcxx(_LIBCXX)
set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX})
endif () endif ()
elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL Clang) elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL Clang
AND NOT "${CMAKE_${LANGUAGE}_COMPILER_FRONTEND_VARIANT}" STREQUAL "MSVC"
AND NOT "${CMAKE_${LANGUAGE}_SIMULATE_ID}" STREQUAL "MSVC")
string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION})
list(GET VERSION_LIST 0 MAJOR) list(GET VERSION_LIST 0 MAJOR)
list(GET VERSION_LIST 1 MINOR) list(GET VERSION_LIST 1 MINOR)
@@ -174,7 +193,11 @@ function(conan_cmake_settings result)
conan_cmake_detect_unix_libcxx(_LIBCXX) conan_cmake_detect_unix_libcxx(_LIBCXX)
set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX})
endif () endif ()
elseif(${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL MSVC) elseif(${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL MSVC
OR (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL Clang
AND "${CMAKE_${LANGUAGE}_COMPILER_FRONTEND_VARIANT}" STREQUAL "MSVC"
AND "${CMAKE_${LANGUAGE}_SIMULATE_ID}" STREQUAL "MSVC"))
set(_VISUAL "Visual Studio") set(_VISUAL "Visual Studio")
_get_msvc_ide_version(_VISUAL_VERSION) _get_msvc_ide_version(_VISUAL_VERSION)
if("${_VISUAL_VERSION}" STREQUAL "") if("${_VISUAL_VERSION}" STREQUAL "")
@@ -197,7 +220,7 @@ function(conan_cmake_settings result)
endif() endif()
endif() endif()
conan_cmake_detect_vs_runtime(_vs_runtime) conan_cmake_detect_vs_runtime(_vs_runtime ${ARGV})
message(STATUS "Conan: Detected VS runtime: ${_vs_runtime}") message(STATUS "Conan: Detected VS runtime: ${_vs_runtime}")
set(_CONAN_SETTING_COMPILER_RUNTIME ${_vs_runtime}) set(_CONAN_SETTING_COMPILER_RUNTIME ${_vs_runtime})
@@ -210,6 +233,30 @@ function(conan_cmake_settings result)
message(FATAL_ERROR "Conan: compiler setup not recognized") message(FATAL_ERROR "Conan: compiler setup not recognized")
endif() endif()
endmacro()
function(conan_cmake_settings result)
#message(STATUS "COMPILER " ${CMAKE_CXX_COMPILER})
#message(STATUS "COMPILER " ${CMAKE_CXX_COMPILER_ID})
#message(STATUS "VERSION " ${CMAKE_CXX_COMPILER_VERSION})
#message(STATUS "FLAGS " ${CMAKE_LANG_FLAGS})
#message(STATUS "LIB ARCH " ${CMAKE_CXX_LIBRARY_ARCHITECTURE})
#message(STATUS "BUILD TYPE " ${CMAKE_BUILD_TYPE})
#message(STATUS "GENERATOR " ${CMAKE_GENERATOR})
#message(STATUS "GENERATOR WIN64 " ${CMAKE_CL_64})
message(STATUS "Conan: Automatic detection of conan settings from cmake")
conan_parse_arguments(${ARGV})
_conan_detect_build_type(${ARGV})
_conan_check_system_name()
_conan_check_language()
_conan_detect_compiler(${ARGV})
# If profile is defined it is used # If profile is defined it is used
if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND ARGUMENTS_DEBUG_PROFILE) if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND ARGUMENTS_DEBUG_PROFILE)
set(_APPLIED_PROFILES ${ARGUMENTS_DEBUG_PROFILE}) set(_APPLIED_PROFILES ${ARGUMENTS_DEBUG_PROFILE})
@@ -346,7 +393,19 @@ function(conan_cmake_detect_unix_libcxx result)
endfunction() endfunction()
function(conan_cmake_detect_vs_runtime result) function(conan_cmake_detect_vs_runtime result)
string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type)
conan_parse_arguments(${ARGV})
if(ARGUMENTS_BUILD_TYPE)
set(build_type "${ARGUMENTS_BUILD_TYPE}")
elseif(CMAKE_BUILD_TYPE)
set(build_type "${CMAKE_BUILD_TYPE}")
else()
message(FATAL_ERROR "Please specify in command line CMAKE_BUILD_TYPE (-DCMAKE_BUILD_TYPE=Release)")
endif()
if(build_type)
string(TOUPPER "${build_type}" build_type)
endif()
set(variables CMAKE_CXX_FLAGS_${build_type} CMAKE_C_FLAGS_${build_type} CMAKE_CXX_FLAGS CMAKE_C_FLAGS) set(variables CMAKE_CXX_FLAGS_${build_type} CMAKE_C_FLAGS_${build_type} CMAKE_CXX_FLAGS CMAKE_C_FLAGS)
foreach(variable ${variables}) foreach(variable ${variables})
if(NOT "${${variable}}" STREQUAL "") if(NOT "${${variable}}" STREQUAL "")
@@ -367,17 +426,39 @@ function(conan_cmake_detect_vs_runtime result)
endif() endif()
endfunction() endfunction()
function(_collect_settings result)
set(ARGUMENTS_PROFILE_AUTO arch build_type compiler compiler.version
compiler.runtime compiler.libcxx compiler.toolset
compiler.cppstd)
foreach(ARG ${ARGUMENTS_PROFILE_AUTO})
string(TOUPPER ${ARG} _arg_name)
string(REPLACE "." "_" _arg_name ${_arg_name})
if(_CONAN_SETTING_${_arg_name})
set(detected_setings ${detected_setings} ${ARG}=${_CONAN_SETTING_${_arg_name}})
endif()
endforeach()
set(${result} ${detected_setings} PARENT_SCOPE)
endfunction()
function(conan_cmake_autodetect detected_settings)
_conan_detect_build_type(${ARGV})
_conan_check_system_name()
_conan_check_language()
_conan_detect_compiler(${ARGV})
_collect_settings(collected_settings)
set(${detected_settings} ${collected_settings} PARENT_SCOPE)
endfunction()
macro(conan_parse_arguments) macro(conan_parse_arguments)
set(options BASIC_SETUP CMAKE_TARGETS UPDATE KEEP_RPATHS NO_LOAD NO_OUTPUT_DIRS OUTPUT_QUIET NO_IMPORTS SKIP_STD) set(options BASIC_SETUP CMAKE_TARGETS UPDATE KEEP_RPATHS NO_LOAD NO_OUTPUT_DIRS OUTPUT_QUIET NO_IMPORTS SKIP_STD)
set(oneValueArgs CONANFILE ARCH BUILD_TYPE INSTALL_FOLDER CONAN_COMMAND) set(oneValueArgs CONANFILE ARCH BUILD_TYPE INSTALL_FOLDER OUTPUT_FOLDER CONAN_COMMAND)
set(multiValueArgs DEBUG_PROFILE RELEASE_PROFILE RELWITHDEBINFO_PROFILE MINSIZEREL_PROFILE set(multiValueArgs DEBUG_PROFILE RELEASE_PROFILE RELWITHDEBINFO_PROFILE MINSIZEREL_PROFILE
PROFILE REQUIRES OPTIONS IMPORTS SETTINGS BUILD ENV GENERATORS PROFILE_AUTO PROFILE REQUIRES OPTIONS IMPORTS SETTINGS BUILD ENV GENERATORS PROFILE_AUTO
INSTALL_ARGS CONFIGURATION_TYPES PROFILE_BUILD) INSTALL_ARGS CONFIGURATION_TYPES PROFILE_BUILD BUILD_REQUIRES)
cmake_parse_arguments(ARGUMENTS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) cmake_parse_arguments(ARGUMENTS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
endmacro() endmacro()
function(conan_cmake_install) function(old_conan_cmake_install)
# Calls "conan install" # Calls "conan install"
# Argument BUILD is equivalant to --build={missing, PkgName,...} or # Argument BUILD is equivalant to --build={missing, PkgName,...} or
# --build when argument is 'BUILD all' (which builds all packages from source) # --build when argument is 'BUILD all' (which builds all packages from source)
@@ -428,6 +509,10 @@ function(conan_cmake_install)
if(ARGUMENTS_INSTALL_FOLDER) if(ARGUMENTS_INSTALL_FOLDER)
set(CONAN_INSTALL_FOLDER -if=${ARGUMENTS_INSTALL_FOLDER}) set(CONAN_INSTALL_FOLDER -if=${ARGUMENTS_INSTALL_FOLDER})
endif() endif()
set(CONAN_OUTPUT_FOLDER "")
if(ARGUMENTS_OUTPUT_FOLDER)
set(CONAN_OUTPUT_FOLDER -of=${ARGUMENTS_OUTPUT_FOLDER})
endif()
foreach(ARG ${ARGUMENTS_GENERATORS}) foreach(ARG ${ARGUMENTS_GENERATORS})
set(CONAN_GENERATORS ${CONAN_GENERATORS} -g=${ARG}) set(CONAN_GENERATORS ${CONAN_GENERATORS} -g=${ARG})
endforeach() endforeach()
@@ -457,6 +542,220 @@ function(conan_cmake_install)
endfunction() endfunction()
function(conan_cmake_install)
if(DEFINED CONAN_COMMAND)
set(CONAN_CMD ${CONAN_COMMAND})
else()
conan_check(REQUIRED)
endif()
set(installOptions UPDATE NO_IMPORTS OUTPUT_QUIET ERROR_QUIET)
set(installOneValueArgs PATH_OR_REFERENCE REFERENCE REMOTE LOCKFILE LOCKFILE_OUT LOCKFILE_NODE_ID INSTALL_FOLDER OUTPUT_FOLDER)
set(installMultiValueArgs GENERATOR BUILD ENV ENV_HOST ENV_BUILD OPTIONS_HOST OPTIONS OPTIONS_BUILD PROFILE
PROFILE_HOST PROFILE_BUILD SETTINGS SETTINGS_HOST SETTINGS_BUILD)
cmake_parse_arguments(ARGS "${installOptions}" "${installOneValueArgs}" "${installMultiValueArgs}" ${ARGN})
foreach(arg ${installOptions})
if(ARGS_${arg})
set(${arg} ${${arg}} ${ARGS_${arg}})
endif()
endforeach()
foreach(arg ${installOneValueArgs})
if(DEFINED ARGS_${arg})
if("${arg}" STREQUAL "REMOTE")
set(flag "--remote")
elseif("${arg}" STREQUAL "LOCKFILE")
set(flag "--lockfile")
elseif("${arg}" STREQUAL "LOCKFILE_OUT")
set(flag "--lockfile-out")
elseif("${arg}" STREQUAL "LOCKFILE_NODE_ID")
set(flag "--lockfile-node-id")
elseif("${arg}" STREQUAL "INSTALL_FOLDER")
set(flag "--install-folder")
elseif("${arg}" STREQUAL "OUTPUT_FOLDER")
set(flag "--output-folder")
endif()
set(${arg} ${${arg}} ${flag} ${ARGS_${arg}})
endif()
endforeach()
foreach(arg ${installMultiValueArgs})
if(DEFINED ARGS_${arg})
if("${arg}" STREQUAL "GENERATOR")
set(flag "--generator")
elseif("${arg}" STREQUAL "BUILD")
set(flag "--build")
elseif("${arg}" STREQUAL "ENV")
set(flag "--env")
elseif("${arg}" STREQUAL "ENV_HOST")
set(flag "--env:host")
elseif("${arg}" STREQUAL "ENV_BUILD")
set(flag "--env:build")
elseif("${arg}" STREQUAL "OPTIONS")
set(flag "--options")
elseif("${arg}" STREQUAL "OPTIONS_HOST")
set(flag "--options:host")
elseif("${arg}" STREQUAL "OPTIONS_BUILD")
set(flag "--options:build")
elseif("${arg}" STREQUAL "PROFILE")
set(flag "--profile")
elseif("${arg}" STREQUAL "PROFILE_HOST")
set(flag "--profile:host")
elseif("${arg}" STREQUAL "PROFILE_BUILD")
set(flag "--profile:build")
elseif("${arg}" STREQUAL "SETTINGS")
set(flag "--settings")
elseif("${arg}" STREQUAL "SETTINGS_HOST")
set(flag "--settings:host")
elseif("${arg}" STREQUAL "SETTINGS_BUILD")
set(flag "--settings:build")
endif()
list(LENGTH ARGS_${arg} numargs)
foreach(item ${ARGS_${arg}})
if(${item} STREQUAL "all" AND ${arg} STREQUAL "BUILD")
set(${arg} "--build")
break()
endif()
set(${arg} ${${arg}} ${flag} ${item})
endforeach()
endif()
endforeach()
if(DEFINED UPDATE)
set(UPDATE --update)
endif()
if(DEFINED NO_IMPORTS)
set(NO_IMPORTS --no-imports)
endif()
set(install_args install ${PATH_OR_REFERENCE} ${REFERENCE} ${UPDATE} ${NO_IMPORTS} ${REMOTE} ${LOCKFILE} ${LOCKFILE_OUT} ${LOCKFILE_NODE_ID} ${INSTALL_FOLDER} ${OUTPUT_FOLDER}
${GENERATOR} ${BUILD} ${ENV} ${ENV_HOST} ${ENV_BUILD} ${OPTIONS} ${OPTIONS_HOST} ${OPTIONS_BUILD}
${PROFILE} ${PROFILE_HOST} ${PROFILE_BUILD} ${SETTINGS} ${SETTINGS_HOST} ${SETTINGS_BUILD})
string(REPLACE ";" " " _install_args "${install_args}")
message(STATUS "Conan executing: ${CONAN_CMD} ${_install_args}")
if(ARGS_OUTPUT_QUIET)
set(OUTPUT_OPT OUTPUT_QUIET)
endif()
if(ARGS_ERROR_QUIET)
set(ERROR_OPT ERROR_QUIET)
endif()
execute_process(COMMAND ${CONAN_CMD} ${install_args}
RESULT_VARIABLE return_code
${OUTPUT_OPT}
${ERROR_OPT}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
if(NOT "${return_code}" STREQUAL "0")
if (ARGS_ERROR_QUIET)
message(WARNING "Conan install failed='${return_code}'")
else()
message(FATAL_ERROR "Conan install failed='${return_code}'")
endif()
endif()
endfunction()
function(conan_cmake_lock_create)
if(DEFINED CONAN_COMMAND)
set(CONAN_CMD ${CONAN_COMMAND})
else()
conan_check(REQUIRED)
endif()
set(lockCreateOptions UPDATE BASE OUTPUT_QUIET ERROR_QUIET)
set(lockCreateOneValueArgs PATH REFERENCE REMOTE LOCKFILE LOCKFILE_OUT)
set(lockCreateMultiValueArgs BUILD ENV ENV_HOST ENV_BUILD OPTIONS_HOST OPTIONS OPTIONS_BUILD PROFILE
PROFILE_HOST PROFILE_BUILD SETTINGS SETTINGS_HOST SETTINGS_BUILD)
cmake_parse_arguments(ARGS "${lockCreateOptions}" "${lockCreateOneValueArgs}" "${lockCreateMultiValueArgs}" ${ARGN})
foreach(arg ${lockCreateOptions})
if(ARGS_${arg})
set(${arg} ${${arg}} ${ARGS_${arg}})
endif()
endforeach()
foreach(arg ${lockCreateOneValueArgs})
if(DEFINED ARGS_${arg})
if("${arg}" STREQUAL "REMOTE")
set(flag "--remote")
elseif("${arg}" STREQUAL "LOCKFILE")
set(flag "--lockfile")
elseif("${arg}" STREQUAL "LOCKFILE_OUT")
set(flag "--lockfile-out")
endif()
set(${arg} ${${arg}} ${flag} ${ARGS_${arg}})
endif()
endforeach()
foreach(arg ${lockCreateMultiValueArgs})
if(DEFINED ARGS_${arg})
if("${arg}" STREQUAL "BUILD")
set(flag "--build")
elseif("${arg}" STREQUAL "ENV")
set(flag "--env")
elseif("${arg}" STREQUAL "ENV_HOST")
set(flag "--env:host")
elseif("${arg}" STREQUAL "ENV_BUILD")
set(flag "--env:build")
elseif("${arg}" STREQUAL "OPTIONS")
set(flag "--options")
elseif("${arg}" STREQUAL "OPTIONS_HOST")
set(flag "--options:host")
elseif("${arg}" STREQUAL "OPTIONS_BUILD")
set(flag "--options:build")
elseif("${arg}" STREQUAL "PROFILE")
set(flag "--profile")
elseif("${arg}" STREQUAL "PROFILE_HOST")
set(flag "--profile:host")
elseif("${arg}" STREQUAL "PROFILE_BUILD")
set(flag "--profile:build")
elseif("${arg}" STREQUAL "SETTINGS")
set(flag "--settings")
elseif("${arg}" STREQUAL "SETTINGS_HOST")
set(flag "--settings:host")
elseif("${arg}" STREQUAL "SETTINGS_BUILD")
set(flag "--settings:build")
endif()
list(LENGTH ARGS_${arg} numargs)
foreach(item ${ARGS_${arg}})
if(${item} STREQUAL "all" AND ${arg} STREQUAL "BUILD")
set(${arg} "--build")
break()
endif()
set(${arg} ${${arg}} ${flag} ${item})
endforeach()
endif()
endforeach()
if(DEFINED UPDATE)
set(UPDATE --update)
endif()
if(DEFINED BASE)
set(BASE --base)
endif()
set(lock_create_Args lock create ${PATH} ${REFERENCE} ${UPDATE} ${BASE} ${REMOTE} ${LOCKFILE} ${LOCKFILE_OUT} ${LOCKFILE_NODE_ID} ${INSTALL_FOLDER}
${GENERATOR} ${BUILD} ${ENV} ${ENV_HOST} ${ENV_BUILD} ${OPTIONS} ${OPTIONS_HOST} ${OPTIONS_BUILD}
${PROFILE} ${PROFILE_HOST} ${PROFILE_BUILD} ${SETTINGS} ${SETTINGS_HOST} ${SETTINGS_BUILD})
string(REPLACE ";" " " _lock_create_Args "${lock_create_Args}")
message(STATUS "Conan executing: ${CONAN_CMD} ${_lock_create_Args}")
if(ARGS_OUTPUT_QUIET)
set(OUTPUT_OPT OUTPUT_QUIET)
endif()
if(ARGS_ERROR_QUIET)
set(ERROR_OPT ERROR_QUIET)
endif()
execute_process(COMMAND ${CONAN_CMD} ${lock_create_Args}
RESULT_VARIABLE return_code
${OUTPUT_OPT}
${ERROR_OPT}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
if(NOT "${return_code}" STREQUAL "0")
if (ARGS_ERROR_QUIET)
message(WARNING "Conan lock create failed='${return_code}'")
else()
message(FATAL_ERROR "Conan lock create failed='${return_code}'")
endif()
endif()
endfunction()
function(conan_cmake_setup_conanfile) function(conan_cmake_setup_conanfile)
conan_parse_arguments(${ARGV}) conan_parse_arguments(${ARGV})
@@ -466,26 +765,64 @@ function(conan_cmake_setup_conanfile)
configure_file(${ARGUMENTS_CONANFILE} ${CMAKE_CURRENT_BINARY_DIR}/${_CONANFILE_NAME}.junk COPYONLY) configure_file(${ARGUMENTS_CONANFILE} ${CMAKE_CURRENT_BINARY_DIR}/${_CONANFILE_NAME}.junk COPYONLY)
file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/${_CONANFILE_NAME}.junk) file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/${_CONANFILE_NAME}.junk)
else() else()
conan_cmake_generate_conanfile(${ARGV}) conan_cmake_generate_conanfile(ON ${ARGV})
endif() endif()
endfunction() endfunction()
function(conan_cmake_generate_conanfile) function(conan_cmake_configure)
conan_cmake_generate_conanfile(OFF ${ARGV})
endfunction()
# Generate, writing in disk a conanfile.txt with the requires, options, and imports # Generate, writing in disk a conanfile.txt with the requires, options, and imports
# specified as arguments # specified as arguments
# This will be considered as temporary file, generated in CMAKE_CURRENT_BINARY_DIR) # This will be considered as temporary file, generated in CMAKE_CURRENT_BINARY_DIR)
function(conan_cmake_generate_conanfile DEFAULT_GENERATOR)
conan_parse_arguments(${ARGV}) conan_parse_arguments(${ARGV})
set(_FN "${CMAKE_CURRENT_BINARY_DIR}/conanfile.txt") set(_FN "${CMAKE_CURRENT_BINARY_DIR}/conanfile.txt")
file(WRITE ${_FN} "")
file(WRITE ${_FN} "[generators]\ncmake\n\n[requires]\n") if(DEFINED ARGUMENTS_REQUIRES)
foreach(ARG ${ARGUMENTS_REQUIRES}) file(APPEND ${_FN} "[requires]\n")
file(APPEND ${_FN} ${ARG} "\n") foreach(REQUIRE ${ARGUMENTS_REQUIRES})
file(APPEND ${_FN} ${REQUIRE} "\n")
endforeach() endforeach()
endif()
file(APPEND ${_FN} ${ARG} "\n[imports]\n") if (DEFAULT_GENERATOR OR DEFINED ARGUMENTS_GENERATORS)
foreach(ARG ${ARGUMENTS_IMPORTS}) file(APPEND ${_FN} "[generators]\n")
file(APPEND ${_FN} ${ARG} "\n") if (DEFAULT_GENERATOR)
file(APPEND ${_FN} "cmake\n")
endif()
if (DEFINED ARGUMENTS_GENERATORS)
foreach(GENERATOR ${ARGUMENTS_GENERATORS})
file(APPEND ${_FN} ${GENERATOR} "\n")
endforeach() endforeach()
endif()
endif()
if(DEFINED ARGUMENTS_BUILD_REQUIRES)
file(APPEND ${_FN} "[build_requires]\n")
foreach(BUILD_REQUIRE ${ARGUMENTS_BUILD_REQUIRES})
file(APPEND ${_FN} ${BUILD_REQUIRE} "\n")
endforeach()
endif()
if(DEFINED ARGUMENTS_IMPORTS)
file(APPEND ${_FN} "[imports]\n")
foreach(IMPORTS ${ARGUMENTS_IMPORTS})
file(APPEND ${_FN} ${IMPORTS} "\n")
endforeach()
endif()
if(DEFINED ARGUMENTS_OPTIONS)
file(APPEND ${_FN} "[options]\n")
foreach(OPTION ${ARGUMENTS_OPTIONS})
file(APPEND ${_FN} ${OPTION} "\n")
endforeach()
endif()
endfunction() endfunction()
@@ -537,12 +874,12 @@ macro(conan_cmake_run)
foreach(CMAKE_BUILD_TYPE ${ARGUMENTS_CONFIGURATION_TYPES}) foreach(CMAKE_BUILD_TYPE ${ARGUMENTS_CONFIGURATION_TYPES})
set(ENV{CONAN_IMPORT_PATH} ${CMAKE_BUILD_TYPE}) set(ENV{CONAN_IMPORT_PATH} ${CMAKE_BUILD_TYPE})
conan_cmake_settings(settings ${ARGV}) conan_cmake_settings(settings ${ARGV})
conan_cmake_install(SETTINGS ${settings} ${ARGV}) old_conan_cmake_install(SETTINGS ${settings} ${ARGV})
endforeach() endforeach()
set(CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE)
else() else()
conan_cmake_settings(settings ${ARGV}) conan_cmake_settings(settings ${ARGV})
conan_cmake_install(SETTINGS ${settings} ${ARGV}) old_conan_cmake_install(SETTINGS ${settings} ${ARGV})
endif() endif()
endif() endif()
@@ -584,10 +921,17 @@ macro(conan_check)
message(STATUS "Conan: Found program ${CONAN_CMD}") message(STATUS "Conan: Found program ${CONAN_CMD}")
endif() endif()
execute_process(COMMAND ${CONAN_CMD} --version execute_process(COMMAND ${CONAN_CMD} --version
RESULT_VARIABLE return_code
OUTPUT_VARIABLE CONAN_VERSION_OUTPUT OUTPUT_VARIABLE CONAN_VERSION_OUTPUT
ERROR_VARIABLE CONAN_VERSION_OUTPUT) ERROR_VARIABLE CONAN_VERSION_OUTPUT)
if(NOT "${return_code}" STREQUAL "0")
message(FATAL_ERROR "Conan --version failed='${return_code}'")
endif()
if(NOT CONAN_DETECT_QUIET) if(NOT CONAN_DETECT_QUIET)
message(STATUS "Conan: Version found ${CONAN_VERSION_OUTPUT}") string(STRIP "${CONAN_VERSION_OUTPUT}" _CONAN_VERSION_OUTPUT)
message(STATUS "Conan: Version found ${_CONAN_VERSION_OUTPUT}")
endif() endif()
if(DEFINED CONAN_VERSION) if(DEFINED CONAN_VERSION)
@@ -617,14 +961,18 @@ function(conan_add_remote)
if(DEFINED CONAN_COMMAND) if(DEFINED CONAN_COMMAND)
set(CONAN_CMD ${CONAN_COMMAND}) set(CONAN_CMD ${CONAN_COMMAND})
else() else()
conan_check(REQUIRED) conan_check(REQUIRED DETECT_QUIET)
endif() endif()
set(CONAN_VERIFY_SSL_ARG "True") set(CONAN_VERIFY_SSL_ARG "True")
if(DEFINED CONAN_VERIFY_SSL) if(DEFINED CONAN_VERIFY_SSL)
set(CONAN_VERIFY_SSL_ARG ${CONAN_VERIFY_SSL}) set(CONAN_VERIFY_SSL_ARG ${CONAN_VERIFY_SSL})
endif() endif()
message(STATUS "Conan: Adding ${CONAN_NAME} remote repository (${CONAN_URL}) verify ssl (${CONAN_VERIFY_SSL_ARG})") message(STATUS "Conan: Adding ${CONAN_NAME} remote repository (${CONAN_URL}) verify ssl (${CONAN_VERIFY_SSL_ARG})")
execute_process(COMMAND ${CONAN_CMD} remote add ${CONAN_NAME} ${CONAN_INDEX_ARG} -f ${CONAN_URL} ${CONAN_VERIFY_SSL_ARG}) execute_process(COMMAND ${CONAN_CMD} remote add ${CONAN_NAME} ${CONAN_INDEX_ARG} -f ${CONAN_URL} ${CONAN_VERIFY_SSL_ARG}
RESULT_VARIABLE return_code)
if(NOT "${return_code}" STREQUAL "0")
message(FATAL_ERROR "Conan remote failed='${return_code}'")
endif()
endfunction() endfunction()
macro(conan_config_install) macro(conan_config_install)
@@ -637,9 +985,10 @@ macro(conan_config_install)
set(multiValueArgs ARGS) set(multiValueArgs ARGS)
cmake_parse_arguments(CONAN "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) cmake_parse_arguments(CONAN "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
find_program(CONAN_CMD conan) if(DEFINED CONAN_COMMAND)
if(NOT CONAN_CMD AND CONAN_REQUIRED) set(CONAN_CMD ${CONAN_COMMAND})
message(FATAL_ERROR "Conan executable not found!") else()
conan_check(REQUIRED)
endif() endif()
if(DEFINED CONAN_VERIFY_SSL) if(DEFINED CONAN_VERIFY_SSL)
@@ -669,5 +1018,9 @@ macro(conan_config_install)
${CONAN_TARGET_ARGS}) ${CONAN_TARGET_ARGS})
message(STATUS "Conan: Installing config from ${CONAN_ITEM}") message(STATUS "Conan: Installing config from ${CONAN_ITEM}")
execute_process(COMMAND ${CONAN_CMD} config install ${CONAN_ITEM} ${CONAN_CONFIG_INSTALL_ARGS}) execute_process(COMMAND ${CONAN_CMD} config install ${CONAN_ITEM} ${CONAN_CONFIG_INSTALL_ARGS}
RESULT_VARIABLE return_code)
if(NOT "${return_code}" STREQUAL "0")
message(FATAL_ERROR "Conan config failed='${return_code}'")
endif()
endmacro() endmacro()

View File

@@ -1248,6 +1248,103 @@ void tst_TestCore::testRewriterReparentToNewNode()
QCOMPARE(testRewriterView->allModelNodes().count(), 8); QCOMPARE(testRewriterView->allModelNodes().count(), 8);
} }
void tst_TestCore::testRewriterBehaivours()
{
const QLatin1String qmlString("\n"
"import QtQuick 2.0\n"
"\n"
"Item {\n"
" Item {}\n"
" Item {}\n"
" Behavior on width {\n"
" NumberAnimation { duration: 1000 }\n"
" }\n"
" Item {}\n"
"}\n");
QPlainTextEdit textEdit;
textEdit.setPlainText(qmlString);
NotIndentingTextEditModifier modifier(&textEdit);
QScopedPointer<Model> model(Model::create("QtQuick.Rectangle"));
QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView(0, RewriterView::Amend));
testRewriterView->setTextModifier(&modifier);
model->attachView(testRewriterView.data());
QVERIFY(testRewriterView->errors().isEmpty());
ModelNode rootModelNode = testRewriterView->rootModelNode();
QVERIFY(rootModelNode.isValid());
const QList<ModelNode> children = rootModelNode.directSubModelNodes();
QCOMPARE(children.count(), 4);
ModelNode behavior;
for (const ModelNode &child : children) {
if (child.type() == "QtQuick.Behavior")
behavior = child;
}
QVERIFY(behavior.isValid());
QVERIFY(!behavior.behaviorPropertyName().isEmpty());
QCOMPARE(behavior.behaviorPropertyName(), "width");
QVERIFY(!behavior.directSubModelNodes().isEmpty());
ModelNode animation = behavior.directSubModelNodes().first();
QVERIFY(animation.isValid());
NodeMetaInfo metaInfo = behavior.metaInfo();
QVERIFY(metaInfo.isValid());
ModelNode newBehavior = testRewriterView->createModelNode("QtQuick.Behavior",
metaInfo.majorVersion(),
metaInfo.minorVersion(),
{},
{},
{},
ModelNode::NodeWithoutSource,
"height");
rootModelNode.defaultNodeListProperty().reparentHere(newBehavior);
QCOMPARE(newBehavior.behaviorPropertyName(), "height");
metaInfo = animation.metaInfo();
QVERIFY(metaInfo.isValid());
ModelNode newAnimation = testRewriterView->createModelNode(metaInfo.typeName(),
metaInfo.majorVersion(),
metaInfo.minorVersion());
newBehavior.defaultNodeListProperty().reparentHere(newAnimation);
newAnimation.variantProperty("duration").setValue(500);
const QLatin1String expextedQmlCode(
"\nimport QtQuick 2.0\n\n"
"Item {\n Item {}\n Item {}\n"
" Behavior on width {\n "
" NumberAnimation { duration: 1000 }\n"
" }\n"
" Item {}\n\n"
" Behavior on height {\n"
" NumberAnimation {\n"
" duration: 500\n"
" }\n }\n}\n");
QCOMPARE(textEdit.toPlainText(), expextedQmlCode);
newBehavior.destroy();
QVERIFY(!newBehavior.isValid());
}
void tst_TestCore::testRewriterForGradientMagic() void tst_TestCore::testRewriterForGradientMagic()
{ {
const QLatin1String qmlString("\n" const QLatin1String qmlString("\n"
@@ -7346,7 +7443,7 @@ void tst_TestCore::testRewriterChangeId()
void tst_TestCore::testRewriterRemoveId() void tst_TestCore::testRewriterRemoveId()
{ {
const char* qmlString = "import QtQuick 2.1\nRectangle { id: rect }"; const char* qmlString = "import QtQuick 2.1\nRectangle { id: myRect }";
QPlainTextEdit textEdit; QPlainTextEdit textEdit;
textEdit.setPlainText(QString::fromUtf8(qmlString)); textEdit.setPlainText(QString::fromUtf8(qmlString));
@@ -7365,7 +7462,7 @@ void tst_TestCore::testRewriterRemoveId()
ModelNode rootModelNode(view->rootModelNode()); ModelNode rootModelNode(view->rootModelNode());
QVERIFY(rootModelNode.isValid()); QVERIFY(rootModelNode.isValid());
QCOMPARE(rootModelNode.id(), QString("rect")); QCOMPARE(rootModelNode.id(), QString("myRect"));
// //
// remove id in text // remove id in text
@@ -8528,7 +8625,7 @@ void tst_TestCore::loadTestFiles()
QCOMPARE(rootModelNode.directSubModelNodes().count(), 4); QCOMPARE(rootModelNode.directSubModelNodes().count(), 4);
QCOMPARE(rootModelNode.variantProperty("width").value().toInt(), 200); QCOMPARE(rootModelNode.variantProperty("width").value().toInt(), 200);
QCOMPARE(rootModelNode.variantProperty("height").value().toInt(), 200); QCOMPARE(rootModelNode.variantProperty("height").value().toInt(), 200);
QCOMPARE(rootModelNode.id(), QLatin1String("rect")); QCOMPARE(rootModelNode.id(), QLatin1String("myRect"));
QVERIFY(rootModelNode.hasProperty("data")); QVERIFY(rootModelNode.hasProperty("data"));
QVERIFY(rootModelNode.property("data").isDefaultProperty()); QVERIFY(rootModelNode.property("data").isDefaultProperty());

View File

@@ -145,6 +145,7 @@ private slots:
void testRewriterUnicodeChars(); void testRewriterUnicodeChars();
void testRewriterTransactionAddingAfterReparenting(); void testRewriterTransactionAddingAfterReparenting();
void testRewriterReparentToNewNode(); void testRewriterReparentToNewNode();
void testRewriterBehaivours();
// //
// unit tests QmlModelNodeFacade/QmlModelState // unit tests QmlModelNodeFacade/QmlModelState

View File

@@ -26,7 +26,7 @@
import QtQuick 2.0 import QtQuick 2.0
Rectangle { Rectangle {
id: rect id: myRect
width: 200 width: 200
height: 200 height: 200
Text { Text {
@@ -39,7 +39,7 @@ Rectangle {
State { State {
name: "State1" name: "State1"
PropertyChanges { PropertyChanges {
target: rect target: myRect
color: "blue" color: "blue"
} }
PropertyChanges { PropertyChanges {
@@ -50,7 +50,7 @@ Rectangle {
State { State {
name: "State2" name: "State2"
PropertyChanges { PropertyChanges {
target: rect target: myRect
color: "gray" color: "gray"
} }
PropertyChanges { PropertyChanges {

View File

@@ -60,9 +60,10 @@ private:
bool testDocker(const FilePath &executable) bool testDocker(const FilePath &executable)
{ {
QtcProcess p; QtcProcess p;
p.setCommand({executable, {"info"}}); p.setCommand({executable, {"info", "--format", "{{.OSType}}"}});
p.runBlocking(); p.runBlocking();
return p.result() == ProcessResult::FinishedWithSuccess; const QString platform = p.cleanedStdOut().trimmed();
return p.result() == ProcessResult::FinishedWithSuccess && platform == "linux";
} }
class tst_DeviceShell : public QObject class tst_DeviceShell : public QObject
@@ -336,10 +337,25 @@ private slots:
QList<int> runs{1,2,3,4,5,6,7,8,9}; QList<int> runs{1,2,3,4,5,6,7,8,9};
QList<QByteArray> results = Utils::mapped<QList>(runs, [&shell](const int i) -> QByteArray{ int maxDepth = 4;
int numMs = 0;
while (true) {
QElapsedTimer t; QElapsedTimer t;
t.start(); t.start();
DeviceShell::RunResult result = shell.outputForRunInShell({"find", {"/usr", "-maxdepth", "4"}}); DeviceShell::RunResult result = shell.outputForRunInShell({"find", {"/usr", "-maxdepth", QString::number(maxDepth)}});
numMs = t.elapsed();
qDebug() << "adjusted maxDepth" << maxDepth << "took" << numMs << "ms";
if (numMs < 100 || maxDepth == 1) {
break;
}
maxDepth--;
}
QList<QByteArray> results = Utils::mapped<QList>(runs, [&shell, maxDepth](const int i) -> QByteArray{
QElapsedTimer t;
t.start();
DeviceShell::RunResult result = shell.outputForRunInShell({"find", {"/usr", "-maxdepth", QString::number(maxDepth)}});
qDebug() << i << "took" << t.elapsed() << "ms"; qDebug() << i << "took" << t.elapsed() << "ms";
return result.stdOut; return result.stdOut;
}); });