diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index 39bb74a8dff..e65a45b87a6 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -25,10 +25,10 @@ jobs: matrix: config: - { - name: "Windows MSVC 2019", artifact: "Windows-MSVC", - os: windows-2019, + name: "Windows Latest MSVC", artifact: "Windows-MSVC", + os: windows-latest, 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 } - { @@ -121,7 +121,10 @@ jobs: COMMAND sudo apt update ) 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 ) if (NOT result EQUAL 0) @@ -129,6 +132,18 @@ jobs: 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") foreach(retry RANGE 10) file(DOWNLOAD "${{ matrix.config.toolchain }}" ./toolchain.7z SHOW_PROGRESS) @@ -140,6 +155,12 @@ jobs: execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./toolchain.7z) 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 id: qt shell: cmake -P {0} @@ -593,11 +614,16 @@ jobs: set(ENV{CTEST_OUTPUT_ON_FAILURE} "ON") 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() 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 RESULT_VARIABLE result OUTPUT_VARIABLE output diff --git a/.gitignore b/.gitignore index 0bfdb066a7e..de76458a885 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ tags ui_*.h wrapper.bat wrapper.sh +debug_toolchain.cmake # qtcreator generated files *.creator.user* diff --git a/coin/instructions/build.yaml b/coin/instructions/build.yaml index a4bd50a0590..43e2e15b39f 100644 --- a/coin/instructions/build.yaml +++ b/coin/instructions/build.yaml @@ -138,15 +138,6 @@ instructions: property: target.arch 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 archiveDirectory: "{{.AgentWorkingDir}}/qt-creator/qt-creator_build/build" transferType: UploadModuleBuildArtifact diff --git a/coin/instructions/common_environment.yaml b/coin/instructions/common_environment.yaml index 2df7ad16e38..51b8654adeb 100644 --- a/coin/instructions/common_environment.yaml +++ b/coin/instructions/common_environment.yaml @@ -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" - type: EnvironmentVariable 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 variableName: MACOSX_DEPLOYMENT_TARGET variableValue: 10.14 diff --git a/doc/qtcreator/images/qtcreator-baremetal-kit.png b/doc/qtcreator/images/qtcreator-baremetal-kit.png index 7f83bf6691f..b723dc54c56 100644 Binary files a/doc/qtcreator/images/qtcreator-baremetal-kit.png and b/doc/qtcreator/images/qtcreator-baremetal-kit.png differ diff --git a/doc/qtcreator/images/qtcreator-boot2qt-deployment-steps.png b/doc/qtcreator/images/qtcreator-boot2qt-deployment-steps.png index a1e6741a68e..1e8a355c5b8 100644 Binary files a/doc/qtcreator/images/qtcreator-boot2qt-deployment-steps.png and b/doc/qtcreator/images/qtcreator-boot2qt-deployment-steps.png differ diff --git a/doc/qtcreator/images/qtcreator-build-settings-ios.png b/doc/qtcreator/images/qtcreator-build-settings-ios.png index eb14112004b..145731d1dd3 100644 Binary files a/doc/qtcreator/images/qtcreator-build-settings-ios.png and b/doc/qtcreator/images/qtcreator-build-settings-ios.png differ diff --git a/doc/qtcreator/images/qtcreator-clang-tidy.png b/doc/qtcreator/images/qtcreator-clang-tidy.png index 4e1f234380e..4f7baf1549a 100644 Binary files a/doc/qtcreator/images/qtcreator-clang-tidy.png and b/doc/qtcreator/images/qtcreator-clang-tidy.png differ diff --git a/doc/qtcreator/images/qtcreator-clang-tools-options-customized.png b/doc/qtcreator/images/qtcreator-clang-tools-options-customized.png index 7484117db5f..5e4a397853d 100644 Binary files a/doc/qtcreator/images/qtcreator-clang-tools-options-customized.png and b/doc/qtcreator/images/qtcreator-clang-tools-options-customized.png differ diff --git a/doc/qtcreator/images/qtcreator-clazy.png b/doc/qtcreator/images/qtcreator-clazy.png index 258bcb6ae62..15dfb0aeb6b 100644 Binary files a/doc/qtcreator/images/qtcreator-clazy.png and b/doc/qtcreator/images/qtcreator-clazy.png differ diff --git a/doc/qtcreator/images/qtcreator-debugger-attach-to-running-debug-server.png b/doc/qtcreator/images/qtcreator-debugger-attach-to-running-debug-server.png index 296d4e6e6f2..6d8292818be 100644 Binary files a/doc/qtcreator/images/qtcreator-debugger-attach-to-running-debug-server.png and b/doc/qtcreator/images/qtcreator-debugger-attach-to-running-debug-server.png differ diff --git a/doc/qtcreator/images/qtcreator-debugging-helper-options.png b/doc/qtcreator/images/qtcreator-debugging-helper-options.png index a73e6144bd4..43a106aed5c 100644 Binary files a/doc/qtcreator/images/qtcreator-debugging-helper-options.png and b/doc/qtcreator/images/qtcreator-debugging-helper-options.png differ diff --git a/doc/qtcreator/images/qtcreator-embedded-linux-deployment-details.png b/doc/qtcreator/images/qtcreator-embedded-linux-deployment-details.png index 6f7886894d9..f667daf545a 100644 Binary files a/doc/qtcreator/images/qtcreator-embedded-linux-deployment-details.png and b/doc/qtcreator/images/qtcreator-embedded-linux-deployment-details.png differ diff --git a/doc/qtcreator/images/qtcreator-image-viewer.png b/doc/qtcreator/images/qtcreator-image-viewer.png index ea3ee88a83a..d953d15aa62 100644 Binary files a/doc/qtcreator/images/qtcreator-image-viewer.png and b/doc/qtcreator/images/qtcreator-image-viewer.png differ diff --git a/doc/qtcreator/images/qtcreator-ios-add-kit.png b/doc/qtcreator/images/qtcreator-ios-add-kit.png index bbf7742769e..b4312c6c3f0 100644 Binary files a/doc/qtcreator/images/qtcreator-ios-add-kit.png and b/doc/qtcreator/images/qtcreator-ios-add-kit.png differ diff --git a/doc/qtcreator/images/qtcreator-ios-device-configurations.png b/doc/qtcreator/images/qtcreator-ios-device-configurations.png index da6b6a4f01d..6612e68597a 100644 Binary files a/doc/qtcreator/images/qtcreator-ios-device-configurations.png and b/doc/qtcreator/images/qtcreator-ios-device-configurations.png differ diff --git a/doc/qtcreator/images/qtcreator-ios-preferences.png b/doc/qtcreator/images/qtcreator-ios-preferences.png index b6ad26f268b..935a528d6cb 100644 Binary files a/doc/qtcreator/images/qtcreator-ios-preferences.png and b/doc/qtcreator/images/qtcreator-ios-preferences.png differ diff --git a/doc/qtcreator/images/qtcreator-ios-simulator-deploy.png b/doc/qtcreator/images/qtcreator-ios-simulator-deploy.png index e2fc146a395..dbc720bdd33 100644 Binary files a/doc/qtcreator/images/qtcreator-ios-simulator-deploy.png and b/doc/qtcreator/images/qtcreator-ios-simulator-deploy.png differ diff --git a/doc/qtcreator/images/qtcreator-link-with-qt.png b/doc/qtcreator/images/qtcreator-link-with-qt.png index 5173be111d6..f84311e7ee7 100644 Binary files a/doc/qtcreator/images/qtcreator-link-with-qt.png and b/doc/qtcreator/images/qtcreator-link-with-qt.png differ diff --git a/doc/qtcreator/images/qtcreator-mcu-kit.png b/doc/qtcreator/images/qtcreator-mcu-kit.png index 112707e22a1..c218ad647e8 100644 Binary files a/doc/qtcreator/images/qtcreator-mcu-kit.png and b/doc/qtcreator/images/qtcreator-mcu-kit.png differ diff --git a/doc/qtcreator/images/qtcreator-mcu-options.png b/doc/qtcreator/images/qtcreator-mcu-options.png index eafc35d51c9..a7234466e42 100644 Binary files a/doc/qtcreator/images/qtcreator-mcu-options.png and b/doc/qtcreator/images/qtcreator-mcu-options.png differ diff --git a/doc/qtcreator/images/qtcreator-open-documents-view.png b/doc/qtcreator/images/qtcreator-open-documents-view.png index ca8d619da62..a05eb4e84de 100644 Binary files a/doc/qtcreator/images/qtcreator-open-documents-view.png and b/doc/qtcreator/images/qtcreator-open-documents-view.png differ diff --git a/doc/qtcreator/images/qtcreator-options-texteditor-completion.png b/doc/qtcreator/images/qtcreator-options-texteditor-completion.png index b501035e836..a891ed6365c 100644 Binary files a/doc/qtcreator/images/qtcreator-options-texteditor-completion.png and b/doc/qtcreator/images/qtcreator-options-texteditor-completion.png differ diff --git a/doc/qtcreator/images/qtcreator-qnx-deployment.png b/doc/qtcreator/images/qtcreator-qnx-deployment.png index 6608e121b67..e338e48f311 100644 Binary files a/doc/qtcreator/images/qtcreator-qnx-deployment.png and b/doc/qtcreator/images/qtcreator-qnx-deployment.png differ diff --git a/doc/qtcreator/images/qtcreator-qt-versions.png b/doc/qtcreator/images/qtcreator-qt-versions.png index 8d456039e30..4e33e55b996 100644 Binary files a/doc/qtcreator/images/qtcreator-qt-versions.png and b/doc/qtcreator/images/qtcreator-qt-versions.png differ diff --git a/doc/qtcreator/images/qtcreator-sidebar.png b/doc/qtcreator/images/qtcreator-sidebar.png index d7f6dea0f86..47d4e5e1f85 100644 Binary files a/doc/qtcreator/images/qtcreator-sidebar.png and b/doc/qtcreator/images/qtcreator-sidebar.png differ diff --git a/doc/qtcreator/images/qtcreator-todo-excluded-files.png b/doc/qtcreator/images/qtcreator-todo-excluded-files.png new file mode 100644 index 00000000000..faa347fdce8 Binary files /dev/null and b/doc/qtcreator/images/qtcreator-todo-excluded-files.png differ diff --git a/doc/qtcreator/images/qtcreator-valgrind-remote-settings.png b/doc/qtcreator/images/qtcreator-valgrind-remote-settings.png index 0b9e6146180..5ded5055e76 100644 Binary files a/doc/qtcreator/images/qtcreator-valgrind-remote-settings.png and b/doc/qtcreator/images/qtcreator-valgrind-remote-settings.png differ diff --git a/doc/qtcreator/src/analyze/creator-clang-static-analyzer.qdoc b/doc/qtcreator/src/analyze/creator-clang-static-analyzer.qdoc index da2f197bf4f..43459d767c5 100644 --- a/doc/qtcreator/src/analyze/creator-clang-static-analyzer.qdoc +++ b/doc/qtcreator/src/analyze/creator-clang-static-analyzer.qdoc @@ -122,8 +122,8 @@ \image qtcreator-clang-tools-options-customized.png "Clang Tools customized settings" To restore the global settings, select \uicontrol {Restore Global Settings}. - To view and modify the global settings, select - \uicontrol {Open Global Settings}. To open the Clang static analyzer, + To view and modify the global settings, select the link in + \uicontrol {Use global settings}. To open the Clang static analyzer, select \uicontrol {Go to Analyzer}. \section1 Configuring Clang Tools @@ -174,6 +174,8 @@ \li In the \uicontrol {Clang-Tidy Checks} tab, select \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" @@ -189,8 +191,10 @@ \image qtcreator-clazy.png "Clazy Checks tab" - \li In the \uicontrol {Topic Filter} field, select a topic to view - only checks related to that area in the \uicontrol Checks field. + \li In the \uicontrol Filters field, select topics to view + 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}. diff --git a/doc/qtcreator/src/debugger/creator-only/creator-debugger.qdoc b/doc/qtcreator/src/debugger/creator-only/creator-debugger.qdoc index c755cb90679..12495c11d25 100644 --- a/doc/qtcreator/src/debugger/creator-only/creator-debugger.qdoc +++ b/doc/qtcreator/src/debugger/creator-only/creator-debugger.qdoc @@ -406,6 +406,15 @@ applications. \li Select the \uicontrol {Break at "main"} check box to stop the 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 the \c sysroot to use instead of the default \c sysroot. \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 \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 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 display of structures, select \uicontrol Edit > \uicontrol Preferences > \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 for a single object or for all objects of a given type, select the corresponding option from the context menu. @@ -893,6 +906,8 @@ \uicontrol Debugger > \uicontrol GDB > \uicontrol {Load system GDB pretty printers}. For more information, see \l{Specifying GDB Settings}. + \image qtcreator-gdb-options.png "GDB preferences" + \section2 Customizing Built-In Debugging Helpers 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 \uicontrol Edit > \uicontrol Preferences > \uicontrol Debugger > \uicontrol {Locals & Expressions} > - \uicontrol {Extra Debugging Helpers}. + \uicontrol {Extra Debugging Helper}. \endlist The custom debugging helpers will be automatically picked up from @@ -1112,6 +1127,8 @@ selecting \uicontrol Edit > \uicontrol Preferences > \uicontrol Debugger > \uicontrol CDB > \uicontrol {Use Python dumper}. + \image qtcreator-cdb-options.png "CDB preferences" + \section3 Dumper Class The \c Dumper class contains generic bookkeeping, low-level, and convenience @@ -1549,6 +1566,8 @@ > \uicontrol Preferences > \uicontrol Debugger > \uicontrol GDB > \uicontrol {Use automatic symbol cache}. + \image qtcreator-gdb-options.png "GDB preferences" + Some slowness stems from maintaining breakpoints inside the debugger (under some circumstances all breakpoints need to be inserted and removed again for each step) and the evaluation of expressions after diff --git a/doc/qtcreator/src/howto/creator-only/creator-how-tos.qdoc b/doc/qtcreator/src/howto/creator-only/creator-how-tos.qdoc index 678e7b02cb8..b4f0c52fb78 100644 --- a/doc/qtcreator/src/howto/creator-only/creator-how-tos.qdoc +++ b/doc/qtcreator/src/howto/creator-only/creator-how-tos.qdoc @@ -148,6 +148,8 @@ To customize, import, or export keyboard shortcuts, select \uicontrol Edit > \uicontrol Preferences > \uicontrol Environment > \uicontrol Keyboard. + \image qtcreator-keyboard-shortcuts.png "Keyboard preferences" + \section1 Run \QC from the command line 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 find all other objects connected to one of your object's slots using 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 the slot in the \e slots subitem. The objects connected to this slot are @@ -214,9 +217,9 @@ \list 1 \li Select \uicontrol Edit > \uicontrol Preferences > \uicontrol Debugger > - \uicontrol{Locals}. - - \li Uncheck the \uicontrol{Use Debugging Helper} checkbox. + \uicontrol {Locals & Expressions}. + \image qtcreator-debugging-helper-options.png "Locals & Expressions preferences" + \li Deselect \uicontrol {Use Debugging Helpers}. \endlist @@ -229,9 +232,8 @@ \li Select \uicontrol Edit > \uicontrol Preferences > \uicontrol Debugger > \uicontrol General. - - \li Select the \uicontrol {Use tooltips in main editor while debugging} check - box. + \image qtcreator-debugger-general-options.png "Debugger General preferences" + \li Select \uicontrol {Use tooltips in main editor when debugging}. \endlist @@ -253,8 +255,12 @@ create your own locator filters. That way you can locate files in a directory structure you have defined. + \image qtcreator-locator.png "List of locator filters" + 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}. @@ -273,9 +279,13 @@ \section1 Add a license header template for C++ code - A file containing a license header for C++ can be specified under - \uicontrol Edit > \uicontrol Preferences > \uicontrol C++ > - \uicontrol {License Template}. It may contain special placeholders enclosed + Specify a file containing a license header for C++ in \uicontrol Edit > + \uicontrol Preferences > \uicontrol C++ > \uicontrol {File Naming} > + \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: \list 1 @@ -306,7 +316,7 @@ \section1 Enclose selected code in curly braces, parentheses, or double quotes 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: \list @@ -315,6 +325,12 @@ \li " \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++ Press \key {Ctrl+U}. @@ -325,6 +341,8 @@ To open the editor, select \uicontrol Edit > \uicontrol Preferences > \uicontrol {Text Editor} > \uicontrol Snippets. + \image qtcreator-snippet-modifiers.png "Snippets preferences" + For more information, see \l {Adding and Editing Snippets}. \section1 Quickly write down notes somewhere @@ -344,10 +362,12 @@ \section1 Configure the amount of recent files shown - Select \uicontrol Edit > \uicontrol Preferences, and change the value of the - list under \uicontrol Environment > \uicontrol System + Set the value of \uicontrol Edit > \uicontrol Preferences > + \uicontrol Environment > \uicontrol System > \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 As an example, say you want to replace equality checks (\c {foo == bar}) diff --git a/doc/qtcreator/src/linux-mobile/creator-deployment-embedded-linux.qdoc b/doc/qtcreator/src/linux-mobile/creator-deployment-embedded-linux.qdoc index c0b67b7f28e..f26efa1e7bc 100644 --- a/doc/qtcreator/src/linux-mobile/creator-deployment-embedded-linux.qdoc +++ b/doc/qtcreator/src/linux-mobile/creator-deployment-embedded-linux.qdoc @@ -53,6 +53,11 @@ installed on the device. Text in red color indicates that the information is 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 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 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 By default, \QC copies the application files to the device by using the SSH file transfer protocol (SFTP), as specified by 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 \uicontrol {Upload Files via SFTP} step, and then select the \uicontrol {Incremental deployment} check box. \QC takes note of the diff --git a/doc/qtcreator/src/overview/creator-only/creator-glossary.qdoc b/doc/qtcreator/src/overview/creator-only/creator-glossary.qdoc index f6f7aea53f8..98fbb2f7a67 100644 --- a/doc/qtcreator/src/overview/creator-only/creator-glossary.qdoc +++ b/doc/qtcreator/src/overview/creator-only/creator-glossary.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2022 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -48,7 +48,7 @@ into binaries. Different build configurations allow you to quickly build the project for different purposes. 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 additional debug symbols that you need for debugging the 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 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 - a \l{glossary-device}{device}. + a \e {device}. \row \li Device \target glossary-device \li An embedded device or a mobile device. For more information, see - \l{Target Platforms}. + \l{Embedded Platforms} and \l{Mobile Platforms}. \row \li Kit \target glossary-buildandrun-kit \li \QC groups build and run specific settings as kits to make 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 \uicontrol Edit > \uicontrol Preferences > \uicontrol Kits. @@ -113,7 +113,7 @@ \target glossary-project \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 - desktop and \l{glossary-device}{device} platforms, as + desktop and \e {device} platforms, as specified by a \e {build configuration}, \e {deploy configuration}, and \e {run configuration}. @@ -129,9 +129,8 @@ \target glossary-run-config \li Starts the application in the location where it was copied by the \e {deploy configuration}. By default, when you run a - project, \QC builds it, deploys it to the - \l{glossary-device}{device} specified in the selected - \l{glossary-buildandrun-kit}{kit}, + project, \QC builds it, deploys it to the \e {device} specified + in the selected \e {kit}, and runs it there. However, if you have not made any changes to the project since you last built and deployed it, \QC simply runs it again. diff --git a/doc/qtcreator/src/overview/creator-only/creator-issues.qdoc b/doc/qtcreator/src/overview/creator-only/creator-issues.qdoc index 250551f442f..66e09433157 100644 --- a/doc/qtcreator/src/overview/creator-only/creator-issues.qdoc +++ b/doc/qtcreator/src/overview/creator-only/creator-issues.qdoc @@ -117,7 +117,8 @@ \li When debugging executables created by the GNU Compiler version 4.5.0 (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' 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 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 contains symbolic links. diff --git a/doc/qtcreator/src/qnx/creator-deployment-qnx.qdoc b/doc/qtcreator/src/qnx/creator-deployment-qnx.qdoc index 5ec84643126..9580c4cfa0d 100644 --- a/doc/qtcreator/src/qnx/creator-deployment-qnx.qdoc +++ b/doc/qtcreator/src/qnx/creator-deployment-qnx.qdoc @@ -48,4 +48,9 @@ The deployment process is described in more detail in \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. */ diff --git a/doc/qtcreator/src/user-interface/creator-ui.qdoc b/doc/qtcreator/src/user-interface/creator-ui.qdoc index d4f52e4eea5..3a701dc6c86 100644 --- a/doc/qtcreator/src/user-interface/creator-ui.qdoc +++ b/doc/qtcreator/src/user-interface/creator-ui.qdoc @@ -673,10 +673,17 @@ in the \uicontrol {Scanning scope} group. To exclude files from scanning, select \uicontrol {Project Settings} > - \uicontrol {To-Do} in the - \uicontrol Projects mode. Select \uicontrol Add and 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. + \uicontrol {To-Do} in the \uicontrol Projects mode. + + \image qtcreator-todo-excluded-files.png "Excluded Files in To-Do preferences" + + Select \uicontrol Add and double-click the placeholder text in + \uicontrol {Exclude Files} to enter a regular expression that + 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 \uicontrol Help > \uicontrol {About Plugins} > \uicontrol Utilities > diff --git a/doc/qtcreator/src/widgets/qtdesigner-app-tutorial.qdoc b/doc/qtcreator/src/widgets/qtdesigner-app-tutorial.qdoc index 84133a9f48d..50b20ad7369 100644 --- a/doc/qtcreator/src/widgets/qtdesigner-app-tutorial.qdoc +++ b/doc/qtcreator/src/widgets/qtdesigner-app-tutorial.qdoc @@ -345,7 +345,7 @@ the resource file as a source file in the \e CMakeLists.txt file that the wizard created for you: - \quotefromfile TextFinder/CMakeLists.txt + \quotefromfile textfinder/CMakeLists.txt \skipto set(PROJECT_SOURCES \printuntil ) diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl index 6b2195d6d1c..2dc38e566a2 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl @@ -59,6 +59,11 @@ Project { directory: "asset_imports" } + Files { + filter: "*.qml" + directory: "asset_imports" + } + Environment { QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf" QT_AUTO_SCREEN_SCALE_FACTOR: "1" diff --git a/src/libs/utils/deviceshell.cpp b/src/libs/utils/deviceshell.cpp index 2d6227be688..75a8cbb2604 100644 --- a/src/libs/utils/deviceshell.cpp +++ b/src/libs/utils/deviceshell.cpp @@ -62,8 +62,11 @@ finalOutput() { local fileInputBuffer while read fileInputBuffer do + if test -f "$fileInputBuffer.err"; then + cat $fileInputBuffer.err + fi cat $fileInputBuffer - rm $fileInputBuffer + rm -f $fileInputBuffer.err $fileInputBuffer done } @@ -117,7 +120,7 @@ executeAndMark() # Mark the app's output streams readAndMark $PID 'O' < "$stdoutenc" >> $TMPFILE & - readAndMark $PID 'E' < "$stderrenc" >> $TMPFILE & + readAndMark $PID 'E' < "$stderrenc" >> $TMPFILE.err & # Start the app ... if [ -z "$INDATA" ] diff --git a/src/libs/utils/shellcommand.h b/src/libs/utils/shellcommand.h index 5f347dd38ab..a766f6a05b0 100644 --- a/src/libs/utils/shellcommand.h +++ b/src/libs/utils/shellcommand.h @@ -151,7 +151,8 @@ signals: void append(const QString &text); void appendSilently(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 executedAsync(const QFuture &future); diff --git a/src/plugins/android/androidavdmanager.cpp b/src/plugins/android/androidavdmanager.cpp index 48a3a7e30b9..611efa666ee 100644 --- a/src/plugins/android/androidavdmanager.cpp +++ b/src/plugins/android/androidavdmanager.cpp @@ -267,11 +267,15 @@ bool AndroidAvdManager::startAvdAsync(const QString &avdName) const { QFileInfo info(m_config.emulatorToolPath().toString()); if (!info.exists()) { - QMessageBox::critical(Core::ICore::dialogParent(), - tr("Emulator Tool Is Missing"), - tr("Install the missing emulator tool (%1) to the" - " installed Android SDK.") - .arg(m_config.emulatorToolPath().toString())); + const QString emulatorToolPath = m_config.emulatorToolPath().toUserOutput(); + QMetaObject::invokeMethod(Core::ICore::mainWindow(), [emulatorToolPath] { + QMessageBox::critical(Core::ICore::dialogParent(), + AndroidAvdManager::tr("Emulator Tool Is Missing"), + AndroidAvdManager::tr( + "Install the missing emulator tool (%1) to the" + " installed Android SDK.") + .arg(emulatorToolPath)); + }); return false; } @@ -283,10 +287,13 @@ bool AndroidAvdManager::startAvdAsync(const QString &avdName) const avdProcess->setProcessChannelMode(QProcess::MergedChannels); QObject::connect(avdProcess, &QtcProcess::done, avdProcess, [avdProcess] { if (avdProcess->exitCode()) { - const QString title = QCoreApplication::translate("Android::Internal::AndroidAvdManager", - "AVD Start Error"); - QMessageBox::critical(Core::ICore::dialogParent(), title, - QString::fromLatin1(avdProcess->readAllStandardOutput())); + const QString errorOutput = QString::fromLatin1(avdProcess->readAllStandardOutput()); + QMetaObject::invokeMethod(Core::ICore::mainWindow(), [errorOutput] { + const QString title + = QCoreApplication::translate("Android::Internal::AndroidAvdManager", + "AVD Start Error"); + QMessageBox::critical(Core::ICore::dialogParent(), title, errorOutput); + }); } avdProcess->deleteLater(); }); diff --git a/src/plugins/clangcodemodel/clangdfollowsymbol.cpp b/src/plugins/clangcodemodel/clangdfollowsymbol.cpp index 102e49acf4e..a0e6aae6108 100644 --- a/src/plugins/clangcodemodel/clangdfollowsymbol.cpp +++ b/src/plugins/clangcodemodel/clangdfollowsymbol.cpp @@ -146,14 +146,14 @@ ClangdFollowSymbol::ClangdFollowSymbol(ClangdClient *client, const QTextCursor & openInSplit)) { // 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); if (editorWidget) { connect(editorWidget, &CppEditorWidget::cursorPositionChanged, - this, &ClangdFollowSymbol::emitDone, Qt::QueuedConnection); + this, [this] { emitDone(); }, Qt::QueuedConnection); } 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 // AST node corresponding to the cursor position, so we can find out whether @@ -195,6 +195,7 @@ ClangdFollowSymbol::~ClangdFollowSymbol() d->client->cancelRequest(id); for (const MessageId &id : qAsConst(d->pendingGotoDefRequests)) d->client->cancelRequest(id); + delete d; } void ClangdFollowSymbol::clear() @@ -205,12 +206,14 @@ void ClangdFollowSymbol::clear() d->pendingGotoDefRequests.clear(); } -void ClangdFollowSymbol::emitDone() +void ClangdFollowSymbol::emitDone(const Link &link) { if (d->done) return; d->done = true; + if (link.hasValidTarget()) + d->callback(link); emit done(); } @@ -246,14 +249,12 @@ void ClangdFollowSymbol::Private::handleDocumentInfoResults() // If something went wrong, we just follow the original link. if (symbolsToDisplay.isEmpty()) { - callback(defLink); - q->emitDone(); + q->emitDone(defLink); return; } if (symbolsToDisplay.size() == 1) { - callback(symbolsToDisplay.first().second); - q->emitDone(); + q->emitDone(symbolsToDisplay.first().second); return; } @@ -382,8 +383,7 @@ void ClangdFollowSymbol::Private::handleGotoDefinitionResult() // No dis-ambiguation necessary. Call back with the link and finish. if (!defLinkIsAmbiguous()) { - callback(defLink); - q->emitDone(); + q->emitDone(defLink); return; } @@ -416,8 +416,7 @@ void ClangdFollowSymbol::Private::handleGotoImplementationResult( // We didn't find any further candidates, so jump to the original definition link. if (allLinks.size() == 1 && pendingGotoImplRequests.isEmpty()) { - callback(allLinks.first()); - q->emitDone(); + q->emitDone(allLinks.first()); return; } diff --git a/src/plugins/clangcodemodel/clangdfollowsymbol.h b/src/plugins/clangcodemodel/clangdfollowsymbol.h index fffe2c42b9f..09094bbed5e 100644 --- a/src/plugins/clangcodemodel/clangdfollowsymbol.h +++ b/src/plugins/clangcodemodel/clangdfollowsymbol.h @@ -55,7 +55,7 @@ signals: void done(); private: - void emitDone(); + void emitDone(const Utils::Link &link = {}); class VirtualFunctionAssistProcessor; class VirtualFunctionAssistProvider; diff --git a/src/plugins/clangtools/clangtoolrunner.cpp b/src/plugins/clangtools/clangtoolrunner.cpp index 12fe0aede06..afad727e7c8 100644 --- a/src/plugins/clangtools/clangtoolrunner.cpp +++ b/src/plugins/clangtools/clangtoolrunner.cpp @@ -67,6 +67,7 @@ void ClangToolRunner::init(const FilePath &outputDirPath, const Environment &env QTC_CHECK(!m_outputDirPath.isEmpty()); m_process.setEnvironment(environment); + m_process.setUseCtrlCStub(true); m_process.setWorkingDirectory(m_outputDirPath); // Current clang-cl puts log file into working dir. connect(&m_process, &QtcProcess::done, this, &ClangToolRunner::onProcessDone); } diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index e985d4a08f6..859eb05a32a 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -1058,10 +1058,12 @@ void DebuggerEngine::setRunId(const QString &id) void DebuggerEngine::setRunTool(DebuggerRunTool *runTool) { d->m_device = runTool->device(); - QTC_ASSERT(d->m_device, d->m_device = DeviceManager::deviceForPath( - d->m_runParameters.inferior.command.executable())); - if (QTC_GUARD(d->m_device)) - d->m_runParameters.dumperPath = d->m_device->debugDumperPath(); + + IDevice::ConstPtr debuggerDevice = + DeviceManager::deviceForPath(d->m_runParameters.debugger.command.executable()); + if (QTC_GUARD(debuggerDevice)) + d->m_runParameters.dumperPath = debuggerDevice->debugDumperPath(); + d->m_terminalRunner = runTool->terminalRunner(); validateRunParameters(d->m_runParameters); diff --git a/src/plugins/gitlab/gitlaboptionspage.cpp b/src/plugins/gitlab/gitlaboptionspage.cpp index 4f5f20b2ec8..6f9790d643c 100644 --- a/src/plugins/gitlab/gitlaboptionspage.cpp +++ b/src/plugins/gitlab/gitlaboptionspage.cpp @@ -274,7 +274,7 @@ GitLabOptionsPage::GitLabOptionsPage(GitLabParameters *p, QObject *parent) : Core::IOptionsPage{parent} , m_parameters(p) { - setId("GitLab"); + setId(Constants::GITLAB_SETTINGS); setDisplayName(tr("GitLab")); setCategory(VcsBase::Constants::VCS_SETTINGS_CATEGORY); } diff --git a/src/plugins/gitlab/gitlaboptionspage.h b/src/plugins/gitlab/gitlaboptionspage.h index 4779028fbd9..a2b41168bac 100644 --- a/src/plugins/gitlab/gitlaboptionspage.h +++ b/src/plugins/gitlab/gitlaboptionspage.h @@ -39,6 +39,10 @@ QT_END_NAMESPACE namespace GitLab { +namespace Constants { +const char GITLAB_SETTINGS[] = "GitLab"; +} // namespace Constants + class GitLabServerWidget : public QWidget { public: diff --git a/src/plugins/gitlab/gitlabprojectsettings.cpp b/src/plugins/gitlab/gitlabprojectsettings.cpp index 29b23381d73..d6eec012872 100644 --- a/src/plugins/gitlab/gitlabprojectsettings.cpp +++ b/src/plugins/gitlab/gitlabprojectsettings.cpp @@ -136,6 +136,7 @@ GitLabProjectSettingsWidget::GitLabProjectSettingsWidget(ProjectExplorer::Projec { setUseGlobalSettingsCheckBoxVisible(false); setUseGlobalSettingsLabelVisible(true); + setGlobalSettingsId(Constants::GITLAB_SETTINGS); // setup ui auto verticalLayout = new QVBoxLayout(this); verticalLayout->setContentsMargins(0, 0, 0, 0); diff --git a/src/plugins/projectexplorer/appoutputpane.cpp b/src/plugins/projectexplorer/appoutputpane.cpp index bf37e7ce8d6..11674508b0f 100644 --- a/src/plugins/projectexplorer/appoutputpane.cpp +++ b/src/plugins/projectexplorer/appoutputpane.cpp @@ -606,8 +606,10 @@ void AppOutputPane::stopRunControl() QTC_ASSERT(rc, return); if (rc->isRunning()) { - if (optionallyPromptToStop(rc)) + if (optionallyPromptToStop(rc)) { rc->initiateStop(); + enableButtons(rc); + } } else { QTC_CHECK(false); rc->forceStop(); diff --git a/src/plugins/projectexplorer/buildconfiguration.cpp b/src/plugins/projectexplorer/buildconfiguration.cpp index f867cc8bdd2..0a5abd65d19 100644 --- a/src/plugins/projectexplorer/buildconfiguration.cpp +++ b/src/plugins/projectexplorer/buildconfiguration.cpp @@ -201,7 +201,6 @@ BuildConfiguration::BuildConfiguration(Target *target, Utils::Id id) tr("Variables in the build configuration's environment"), [this](const QString &var) { return environment().expandedValueForKey(var); }); - updateCacheAndEmitEnvironmentChanged(); connect(Core::ICore::instance(), &Core::ICore::systemEnvironmentChanged, this, &BuildConfiguration::updateCacheAndEmitEnvironmentChanged); connect(target, &Target::kitChanged, @@ -292,6 +291,8 @@ void BuildConfiguration::addConfigWidgets(const std::function -#include +#include +#include +#include +#include #include #include -#include -#include -#include - #include #include - -#include +#include +#include +#include #include @@ -86,6 +85,7 @@ MaterialEditorView::MaterialEditorView(QWidget *parent) m_stackedWidget->setStyleSheet(Theme::replaceCssColors( QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css")))); m_stackedWidget->setMinimumWidth(250); + QmlDesignerPlugin::trackWidgetFocusTime(m_stackedWidget, Constants::EVENT_MATERIALEDITOR_TIME); } MaterialEditorView::~MaterialEditorView() diff --git a/src/plugins/qmldesigner/designercore/include/abstractview.h b/src/plugins/qmldesigner/designercore/include/abstractview.h index 3c4eca04413..e41e93960c4 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/designercore/include/abstractview.h @@ -112,12 +112,13 @@ public: ModelNode createModelNode(const TypeName &typeName); ModelNode createModelNode(const TypeName &typeName, - int majorVersion, - int minorVersion, - const PropertyListType &propertyList = PropertyListType(), - const PropertyListType &auxPropertyList = PropertyListType(), - const QString &nodeSource = QString(), - ModelNode::NodeSourceType nodeSourceType = ModelNode::NodeWithoutSource); + int majorVersion, + int minorVersion, + const PropertyListType &propertyList = PropertyListType(), + const PropertyListType &auxPropertyList = PropertyListType(), + const QString &nodeSource = {}, + ModelNode::NodeSourceType nodeSourceType = ModelNode::NodeWithoutSource, + const QString &behaviorPropertyName = {}); ModelNode rootModelNode() const; ModelNode rootModelNode(); diff --git a/src/plugins/qmldesigner/designercore/include/modelnode.h b/src/plugins/qmldesigner/designercore/include/modelnode.h index 5517336fdb8..534eccfd540 100644 --- a/src/plugins/qmldesigner/designercore/include/modelnode.h +++ b/src/plugins/qmldesigner/designercore/include/modelnode.h @@ -238,6 +238,7 @@ public: bool isComponent() const; bool isSubclassOf(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1) const; QIcon typeIcon() const; + QString behaviorPropertyName() const; friend void swap(ModelNode &first, ModelNode &second) noexcept { diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index f92df89a9db..4522c14a54f 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -1050,7 +1050,8 @@ CreateSceneCommand NodeInstanceView::createCreateSceneCommand() nodeMetaType, nodeFlags); - instanceContainerList.append(container); + if (instance.modelNode().behaviorPropertyName().isEmpty()) + instanceContainerList.append(container); } QVector reparentContainerList; diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp index 1c0a9ca41ce..8d53d410b09 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp @@ -78,6 +78,15 @@ using PropertyInfo = QPair; QVector getObjectTypes(const ObjectValue *ov, const ContextPtr &context, bool local = false, int rec = 0); + +static QByteArray getUnqualifiedName(const QByteArray &name) +{ + const QList nameComponents = name.split('.'); + if (nameComponents.size() < 2) + return name; + return nameComponents.constLast(); +} + static TypeName resolveTypeName(const ASTPropertyReference *ref, const ContextPtr &context, QVector &dotProperties) { TypeName type = "unknown"; @@ -765,22 +774,49 @@ NodeMetaInfoPrivate::NodeMetaInfoPrivate(Model *model, TypeName type, int maj, i } else { m_isFileComponent = true; 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.type() == ImportType::Library) { m_majorVersion = importInfo.version().majorVersion(); m_minorVersion = importInfo.version().minorVersion(); } - bool prepandName = (importInfo.type() == ImportType::Library || importInfo.type() == ImportType::Directory) - && !m_qualfiedTypeName.contains('.'); + bool prepandName = (importInfo.type() == ImportType::Library + || importInfo.type() == ImportType::Directory) + && !m_qualfiedTypeName.contains('.'); if (prepandName) - m_qualfiedTypeName.prepend(importInfo.name().toUtf8() + '.'); + m_qualfiedTypeName.prepend(importInfo.name().toUtf8() + '.'); } } m_objectValue = objectValue; m_defaultPropertyName = context()->defaultPropertyName(objectValue).toUtf8(); m_isValid = true; 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(); } -static QByteArray getUnqualifiedName(const QByteArray &name) -{ - const QList nameComponents = name.split('.'); - if (nameComponents.size() < 2) - return name; - return nameComponents.constLast(); -} - static QByteArray getPackage(const QByteArray &name) { QList nameComponents = name.split('.'); diff --git a/src/plugins/qmldesigner/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/designercore/model/abstractview.cpp index 310dcdcdab1..f3c757e81db 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractview.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractview.cpp @@ -97,14 +97,15 @@ ModelNode AbstractView::createModelNode(const TypeName &typeName) } ModelNode AbstractView::createModelNode(const TypeName &typeName, - int majorVersion, - int minorVersion, - const QList > &propertyList, - const QList > &auxPropertyList, - const QString &nodeSource, - ModelNode::NodeSourceType nodeSourceType) + int majorVersion, + int minorVersion, + const QList> &propertyList, + const QList> &auxPropertyList, + const QString &nodeSource, + 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); } diff --git a/src/plugins/qmldesigner/designercore/model/internalnode.cpp b/src/plugins/qmldesigner/designercore/model/internalnode.cpp index 624abb5b648..96b632eb3fb 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalnode.cpp @@ -389,5 +389,15 @@ void InternalNode::setNodeSourceType(int i) m_nodeSourceType = i; } +QString InternalNode::behaviorPropertyName() const +{ + return m_behaviorPropertyName; +} + +void InternalNode::setBehaviorPropertyName(const QString &name) +{ + m_behaviorPropertyName = name; +} + } } diff --git a/src/plugins/qmldesigner/designercore/model/internalnode_p.h b/src/plugins/qmldesigner/designercore/model/internalnode_p.h index f6b1f3fe5a5..679f85fe8f5 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnode_p.h +++ b/src/plugins/qmldesigner/designercore/model/internalnode_p.h @@ -123,6 +123,9 @@ public: int nodeSourceType() const; void setNodeSourceType(int i); + QString behaviorPropertyName() const; + void setBehaviorPropertyName(const QString &name); + protected: Pointer internalPointer() const; void setInternalWeakPointer(const Pointer &pointer); @@ -149,6 +152,8 @@ private: QString m_nodeSource; int m_nodeSourceType = 0; + + QString m_behaviorPropertyName; }; size_t qHash(const InternalNodePointer& node); diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 772149a33d9..3dad31a40b6 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -97,9 +97,11 @@ ModelPrivate::ModelPrivate(Model *model) 0, PropertyListType(), PropertyListType(), - QString(), + {}, ModelNode::NodeWithoutSource, + {}, true); + m_currentStateNode = m_rootInternalNode; m_currentTimelineNode = m_rootInternalNode; } @@ -250,6 +252,7 @@ InternalNodePointer ModelPrivate::createNode(const TypeName &typeName, const QList> &auxPropertyList, const QString &nodeSource, ModelNode::NodeSourceType nodeSourceType, + const QString &behaviorPropertyName, bool isRootNode) { if (typeName.isEmpty()) @@ -263,6 +266,8 @@ InternalNodePointer ModelPrivate::createNode(const TypeName &typeName, InternalNodePointer newNode = InternalNode::create(typeName, majorVersion, minorVersion, internalId); newNode->setNodeSourceType(nodeSourceType); + newNode->setBehaviorPropertyName(behaviorPropertyName); + using PropertyPair = QPair; for (const PropertyPair &propertyPair : propertyList) { @@ -400,7 +405,7 @@ void ModelPrivate::notifyNodeInstanceViewLast(Callable call) resetModel = true; } - for (QPointer view : enabledViews()) { + for (const QPointer &view : enabledViews()) { if (!view->isBlockingNotifications()) call(view.data()); } @@ -429,7 +434,7 @@ void ModelPrivate::notifyNormalViewsLast(Callable call) if (nodeInstanceView() && !nodeInstanceView()->isBlockingNotifications()) call(nodeInstanceView()); - for (QPointer view : enabledViews()) { + for (const QPointer &view : enabledViews()) { if (!view->isBlockingNotifications()) call(view.data()); } @@ -441,7 +446,7 @@ void ModelPrivate::notifyNormalViewsLast(Callable call) template void ModelPrivate::notifyInstanceChanges(Callable call) { - for (QPointer view : enabledViews()) { + for (const QPointer &view : enabledViews()) { if (!view->isBlockingNotifications()) call(view.data()); } diff --git a/src/plugins/qmldesigner/designercore/model/model_p.h b/src/plugins/qmldesigner/designercore/model/model_p.h index 9cd1bceeded..e19995e7b88 100644 --- a/src/plugins/qmldesigner/designercore/model/model_p.h +++ b/src/plugins/qmldesigner/designercore/model/model_p.h @@ -104,6 +104,7 @@ public: const QList > &auxPropertyList, const QString &nodeSource, ModelNode::NodeSourceType nodeSourceType, + const QString &behaviorPropertyName, bool isRootNode = false); diff --git a/src/plugins/qmldesigner/designercore/model/modelnode.cpp b/src/plugins/qmldesigner/designercore/model/modelnode.cpp index 97c1ddfcba9..2b6c0f025cf 100644 --- a/src/plugins/qmldesigner/designercore/model/modelnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelnode.cpp @@ -197,7 +197,8 @@ static bool isIdToAvoid(const QString& id) "shaderInfo", "sprite", "spriteSequence", - "baseState" + "baseState", + "rect" }; return ids.contains(id); @@ -1435,4 +1436,12 @@ QIcon ModelNode::typeIcon() const return QIcon(QStringLiteral(":/ItemLibrary/images/item-invalid-icon.png")); } +QString ModelNode::behaviorPropertyName() const +{ + if (m_internalNode.isNull()) + return {}; + + return m_internalNode->behaviorPropertyName(); +} + } diff --git a/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp b/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp index 3481724d7bb..4c9311a4cf5 100644 --- a/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp @@ -218,6 +218,10 @@ QString QmlTextGenerator::toQml(const ModelNode &node, int indentDepth) const result = alias + '.'; result += type; + if (!node.behaviorPropertyName().isEmpty()) { + result += " on " + node.behaviorPropertyName(); + } + result += QStringLiteral(" {\n"); const int propertyIndentDepth = indentDepth + m_tabSettings.m_indentSize; diff --git a/src/plugins/qmldesigner/designercore/model/rewriteaction.cpp b/src/plugins/qmldesigner/designercore/model/rewriteaction.cpp index 38e9427892e..6b6f1f8a886 100644 --- a/src/plugins/qmldesigner/designercore/model/rewriteaction.cpp +++ b/src/plugins/qmldesigner/designercore/model/rewriteaction.cpp @@ -276,7 +276,7 @@ bool RemoveNodeRewriteAction::execute(QmlRefactoring &refactoring, ModelNodePosi QString RemoveNodeRewriteAction::info() const { - return QLatin1String("RemoveNodeRewriteAction"); + return QLatin1String("RemoveNodeRewriteAction") + QString::number(m_node.internalId()); } bool RemovePropertyRewriteAction::execute(QmlRefactoring &refactoring, ModelNodePositionStorage &positionStore) diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index e497c1d62e7..3cc2202ad44 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -40,6 +40,7 @@ #include "propertyparser.h" #include "rewriterview.h" #include "variantproperty.h" +#include #include @@ -435,13 +436,14 @@ class ReadingContext { public: ReadingContext(const Snapshot &snapshot, const Document::Ptr &doc, - const ViewerContext &vContext) + const ViewerContext &vContext, Model *model) : m_doc(doc) , m_context( Link(snapshot, vContext, ModelManagerInterface::instance()->builtins(doc)) (doc, &m_diagnosticLinkMessages)) , m_scopeChain(doc, m_context) , m_scopeBuilder(&m_scopeChain) + , m_model(model) { } @@ -507,6 +509,36 @@ public: 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 @@ -759,6 +791,7 @@ private: ContextPtr m_context; ScopeChain m_scopeChain; ScopeBuilder m_scopeBuilder; + Model *m_model; }; } // namespace Internal @@ -1127,7 +1160,7 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH 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( new ScopeChain(ctxt.scopeChain())); @@ -1188,6 +1221,15 @@ void TextToModelMerger::syncNode(ModelNode &modelNode, ReadingContext *context, DifferenceHandler &differenceHandler) { + auto binding = AST::cast(astNode); + + const bool hasOnToken = binding && binding->hasOnToken; + + QString onTokenProperty; + + if (hasOnToken) + onTokenProperty = toString(binding->qualifiedId); + AST::UiQualifiedId *astObjectType = qualifiedTypeNameId(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()); - - if (modelNode.type() != typeName //If there is no valid parentProperty //the node has just been created. The type is correct then. - || modelNode.majorVersion() != majorVersion - || modelNode.minorVersion() != minorVersion) { + if (modelNode.type() + != typeName //If there is no valid parentProperty //the node has just been created. The type is correct then. + || modelNode.majorVersion() != majorVersion || modelNode.minorVersion() != minorVersion + || modelNode.behaviorPropertyName() != onTokenProperty) { const bool isRootNode = m_rewriterView->rootModelNode() == modelNode; differenceHandler.typeDiffers(isRootNode, modelNode, typeName, majorVersion, minorVersion, @@ -1294,7 +1336,8 @@ void TextToModelMerger::syncNode(ModelNode &modelNode, } else if (auto binding = AST::cast(member)) { const QString astPropertyName = toString(binding->qualifiedId); if (binding->hasOnToken) { - // skip value sources + // Store Behaviours in the default property + defaultPropertyItems.append(member); } else { const Value *propertyType = nullptr; const ObjectValue *containingObject = nullptr; @@ -1690,6 +1733,13 @@ ModelNode TextToModelMerger::createModelNode(const TypeName &typeName, { QString nodeSource; + auto binding = AST::cast(astNode); + + const bool hasOnToken = binding && binding->hasOnToken; + + QString onTokenProperty; + if (hasOnToken) + onTokenProperty = toString(binding->qualifiedId); AST::UiQualifiedId *astObjectType = qualifiedTypeNameId(astNode); @@ -1721,7 +1771,8 @@ ModelNode TextToModelMerger::createModelNode(const TypeName &typeName, PropertyListType(), PropertyListType(), nodeSource, - nodeSourceType); + nodeSourceType, + onTokenProperty); syncNode(newNode, astNode, context, differenceHandler); return newNode; diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h index 486faeaa267..cf657bca537 100644 --- a/src/plugins/qmldesigner/qmldesignerconstants.h +++ b/src/plugins/qmldesigner/qmldesignerconstants.h @@ -131,6 +131,8 @@ const char EVENT_ITEMLIBRARY_TIME[] = "itemLibrary"; const char EVENT_TRANSLATIONVIEW_TIME[] = "translationView"; const char EVENT_NAVIGATORVIEW_TIME[] = "navigatorView"; 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"; diff --git a/src/plugins/qmlprojectmanager/cmakegen/generatecmakelists.cpp b/src/plugins/qmlprojectmanager/cmakegen/generatecmakelists.cpp index 5dde651ded2..613b6b03b4b 100644 --- a/src/plugins/qmlprojectmanager/cmakegen/generatecmakelists.cpp +++ b/src/plugins/qmlprojectmanager/cmakegen/generatecmakelists.cpp @@ -90,11 +90,14 @@ void generateMenuEntry(QObject *parent) Core::Command *cmd = Core::ActionManager::registerAction(action, "QmlProject.CreateCMakeLists"); menu->addAction(cmd, Core::Constants::G_FILE_EXPORT); - action->setEnabled(ProjectExplorer::SessionManager::startupProject() != nullptr); + action->setEnabled(false); QObject::connect(ProjectExplorer::SessionManager::instance(), - &ProjectExplorer::SessionManager::startupProjectChanged, [action]() { - action->setEnabled(ProjectExplorer::SessionManager::startupProject() != nullptr); - }); + &ProjectExplorer::SessionManager::startupProjectChanged, + [action]() { + auto qmlProject = qobject_cast( + ProjectExplorer::SessionManager::startupProject()); + action->setEnabled(qmlProject != nullptr); + }); } void onGenerateCmakeLists() diff --git a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp index cd8698fc999..83e8fe4c479 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp @@ -379,7 +379,8 @@ bool QmlProjectPlugin::initialize(const QStringList &, QString *errorMessage) } GenerateCmake::generateMenuEntry(this); - GenerateCmake::CmakeProjectConverter::generateMenuEntry(this); + if (QmlProject::isQtDesignStudio()) + GenerateCmake::CmakeProjectConverter::generateMenuEntry(this); return true; } diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index fcc9d7475b4..d24a5a6e41a 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -7504,7 +7504,7 @@ QMimeData *TextEditorWidget::createMimeDataFromSelection() const tempCursor.setCharFormat(range.format); } } else { - const int startPosition = current.position() - start.position() + const int startPosition = current.position() - selectionStart - removedCount; int endPosition = startPosition + current.text().count(); if (current != last) diff --git a/src/plugins/todo/constants.h b/src/plugins/todo/constants.h index d693c503d82..d07f8ef9710 100644 --- a/src/plugins/todo/constants.h +++ b/src/plugins/todo/constants.h @@ -31,6 +31,8 @@ namespace Todo { namespace Constants { +const char TODO_SETTINGS[] = "TodoSettings"; + // Settings entries const char SETTINGS_GROUP[] = "TodoPlugin"; const char SCANNING_SCOPE[] = "ScanningScope"; diff --git a/src/plugins/todo/optionsdialog.cpp b/src/plugins/todo/optionsdialog.cpp index 7ca9821f583..dee4b15c13f 100644 --- a/src/plugins/todo/optionsdialog.cpp +++ b/src/plugins/todo/optionsdialog.cpp @@ -26,8 +26,9 @@ #include "optionsdialog.h" -#include "keyworddialog.h" +#include "constants.h" #include "keyword.h" +#include "keyworddialog.h" #include "settings.h" #include "todotr.h" @@ -267,7 +268,7 @@ void OptionsDialog::apply() TodoOptionsPage::TodoOptionsPage(Settings *settings, const std::function &onApply) { - setId("TodoSettings"); + setId(Constants::TODO_SETTINGS); setDisplayName(Tr::tr("To-Do")); setCategory("To-Do"); setDisplayCategory(Tr::tr("To-Do")); diff --git a/src/plugins/todo/todoprojectsettingswidget.cpp b/src/plugins/todo/todoprojectsettingswidget.cpp index 07e185852c2..3851390fb9c 100644 --- a/src/plugins/todo/todoprojectsettingswidget.cpp +++ b/src/plugins/todo/todoprojectsettingswidget.cpp @@ -71,8 +71,11 @@ TodoProjectSettingsWidget::TodoProjectSettingsWidget(ProjectExplorer::Project *p }.attachTo(this); setExcludedPatternsButtonsEnabled(); - connect(addExcludedPatternButton, &QPushButton::clicked, - this, &TodoProjectSettingsWidget::addExcludedPatternButtonClicked); + setGlobalSettingsId(Constants::TODO_SETTINGS); + connect(addExcludedPatternButton, + &QPushButton::clicked, + this, + &TodoProjectSettingsWidget::addExcludedPatternButtonClicked); connect(m_removeExcludedPatternButton, &QPushButton::clicked, this, &TodoProjectSettingsWidget::removeExcludedPatternButtonClicked); connect(m_excludedPatternsList, &QListWidget::itemChanged, diff --git a/src/share/3rdparty/package-manager/conan.cmake b/src/share/3rdparty/package-manager/conan.cmake index 18fb62a8863..4f5f67e74ca 100644 --- a/src/share/3rdparty/package-manager/conan.cmake +++ b/src/share/3rdparty/package-manager/conan.cmake @@ -33,7 +33,7 @@ # 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. -# version: 0.16.0-dev +# version: 0.18.1 include(CMakeParseArguments) @@ -55,23 +55,14 @@ function(_get_msvc_ide_version result) set(${result} 15 PARENT_SCOPE) elseif(NOT MSVC_VERSION VERSION_LESS 1920 AND MSVC_VERSION VERSION_LESS 1930) set(${result} 16 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1930 AND MSVC_VERSION VERSION_LESS 1940) + set(${result} 17 PARENT_SCOPE) else() message(FATAL_ERROR "Conan: Unknown MSVC compiler version [${MSVC_VERSION}]") endif() endfunction() -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") - +macro(_conan_detect_build_type) conan_parse_arguments(${ARGV}) if(ARGUMENTS_BUILD_TYPE) @@ -92,10 +83,9 @@ function(conan_cmake_settings result) elseif(_CONAN_SETTING_BUILD_TYPE_UPPER STREQUAL "MINSIZEREL") set(_CONAN_SETTING_BUILD_TYPE "MinSizeRel") endif() +endmacro() - if(ARGUMENTS_ARCH) - set(_CONAN_SETTING_ARCH ${ARGUMENTS_ARCH}) - endif() +macro(_conan_check_system_name) #handle -s os setting if(CMAKE_SYSTEM_NAME AND NOT CMAKE_SYSTEM_NAME STREQUAL "Generic") #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}") endif() endif() +endmacro() +macro(_conan_check_language) get_property(_languages GLOBAL PROPERTY ENABLED_LANGUAGES) if (";${_languages};" MATCHES ";CXX;") set(LANGUAGE CXX) @@ -126,6 +118,19 @@ function(conan_cmake_settings result) else () message(FATAL_ERROR "Conan: Neither C or C++ was detected as a language for the project. Unabled to detect compiler version.") 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) # using GCC @@ -143,6 +148,17 @@ function(conan_cmake_settings result) conan_cmake_detect_unix_libcxx(_LIBCXX) set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) 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) # using AppleClang string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) @@ -154,7 +170,10 @@ function(conan_cmake_settings result) conan_cmake_detect_unix_libcxx(_LIBCXX) set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) 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}) list(GET VERSION_LIST 0 MAJOR) list(GET VERSION_LIST 1 MINOR) @@ -174,7 +193,11 @@ function(conan_cmake_settings result) conan_cmake_detect_unix_libcxx(_LIBCXX) set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) 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") _get_msvc_ide_version(_VISUAL_VERSION) if("${_VISUAL_VERSION}" STREQUAL "") @@ -197,7 +220,7 @@ function(conan_cmake_settings result) 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}") set(_CONAN_SETTING_COMPILER_RUNTIME ${_vs_runtime}) @@ -206,10 +229,34 @@ function(conan_cmake_settings result) elseif(CMAKE_VS_PLATFORM_TOOLSET AND (CMAKE_GENERATOR STREQUAL "Ninja")) set(_CONAN_SETTING_COMPILER_TOOLSET ${CMAKE_VS_PLATFORM_TOOLSET}) endif() - else() + else() message(FATAL_ERROR "Conan: compiler setup not recognized") 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(CMAKE_BUILD_TYPE STREQUAL "Debug" AND ARGUMENTS_DEBUG_PROFILE) set(_APPLIED_PROFILES ${ARGUMENTS_DEBUG_PROFILE}) @@ -346,7 +393,19 @@ function(conan_cmake_detect_unix_libcxx result) endfunction() 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) foreach(variable ${variables}) if(NOT "${${variable}}" STREQUAL "") @@ -367,17 +426,39 @@ function(conan_cmake_detect_vs_runtime result) endif() 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) 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 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}) endmacro() -function(conan_cmake_install) +function(old_conan_cmake_install) # Calls "conan install" # Argument BUILD is equivalant to --build={missing, PkgName,...} or # --build when argument is 'BUILD all' (which builds all packages from source) @@ -428,6 +509,10 @@ function(conan_cmake_install) if(ARGUMENTS_INSTALL_FOLDER) set(CONAN_INSTALL_FOLDER -if=${ARGUMENTS_INSTALL_FOLDER}) endif() + set(CONAN_OUTPUT_FOLDER "") + if(ARGUMENTS_OUTPUT_FOLDER) + set(CONAN_OUTPUT_FOLDER -of=${ARGUMENTS_OUTPUT_FOLDER}) + endif() foreach(ARG ${ARGUMENTS_GENERATORS}) set(CONAN_GENERATORS ${CONAN_GENERATORS} -g=${ARG}) endforeach() @@ -457,6 +542,220 @@ function(conan_cmake_install) 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) 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) file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/${_CONANFILE_NAME}.junk) else() - conan_cmake_generate_conanfile(${ARGV}) + conan_cmake_generate_conanfile(ON ${ARGV}) endif() endfunction() -function(conan_cmake_generate_conanfile) - # Generate, writing in disk a conanfile.txt with the requires, options, and imports - # specified as arguments - # This will be considered as temporary file, generated in CMAKE_CURRENT_BINARY_DIR) - conan_parse_arguments(${ARGV}) - set(_FN "${CMAKE_CURRENT_BINARY_DIR}/conanfile.txt") +function(conan_cmake_configure) + conan_cmake_generate_conanfile(OFF ${ARGV}) +endfunction() - file(WRITE ${_FN} "[generators]\ncmake\n\n[requires]\n") - foreach(ARG ${ARGUMENTS_REQUIRES}) - file(APPEND ${_FN} ${ARG} "\n") - endforeach() +# Generate, writing in disk a conanfile.txt with the requires, options, and imports +# specified as arguments +# This will be considered as temporary file, generated in CMAKE_CURRENT_BINARY_DIR) +function(conan_cmake_generate_conanfile DEFAULT_GENERATOR) + + conan_parse_arguments(${ARGV}) + + set(_FN "${CMAKE_CURRENT_BINARY_DIR}/conanfile.txt") + file(WRITE ${_FN} "") + + if(DEFINED ARGUMENTS_REQUIRES) + file(APPEND ${_FN} "[requires]\n") + foreach(REQUIRE ${ARGUMENTS_REQUIRES}) + file(APPEND ${_FN} ${REQUIRE} "\n") + endforeach() + endif() + + if (DEFAULT_GENERATOR OR DEFINED ARGUMENTS_GENERATORS) + file(APPEND ${_FN} "[generators]\n") + if (DEFAULT_GENERATOR) + file(APPEND ${_FN} "cmake\n") + endif() + if (DEFINED ARGUMENTS_GENERATORS) + foreach(GENERATOR ${ARGUMENTS_GENERATORS}) + file(APPEND ${_FN} ${GENERATOR} "\n") + 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() - file(APPEND ${_FN} ${ARG} "\n[imports]\n") - foreach(ARG ${ARGUMENTS_IMPORTS}) - file(APPEND ${_FN} ${ARG} "\n") - endforeach() endfunction() @@ -537,12 +874,12 @@ macro(conan_cmake_run) foreach(CMAKE_BUILD_TYPE ${ARGUMENTS_CONFIGURATION_TYPES}) set(ENV{CONAN_IMPORT_PATH} ${CMAKE_BUILD_TYPE}) conan_cmake_settings(settings ${ARGV}) - conan_cmake_install(SETTINGS ${settings} ${ARGV}) + old_conan_cmake_install(SETTINGS ${settings} ${ARGV}) endforeach() set(CMAKE_BUILD_TYPE) else() conan_cmake_settings(settings ${ARGV}) - conan_cmake_install(SETTINGS ${settings} ${ARGV}) + old_conan_cmake_install(SETTINGS ${settings} ${ARGV}) endif() endif() @@ -584,10 +921,17 @@ macro(conan_check) message(STATUS "Conan: Found program ${CONAN_CMD}") endif() execute_process(COMMAND ${CONAN_CMD} --version + RESULT_VARIABLE return_code OUTPUT_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) - 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() if(DEFINED CONAN_VERSION) @@ -617,14 +961,18 @@ function(conan_add_remote) if(DEFINED CONAN_COMMAND) set(CONAN_CMD ${CONAN_COMMAND}) else() - conan_check(REQUIRED) + conan_check(REQUIRED DETECT_QUIET) endif() set(CONAN_VERIFY_SSL_ARG "True") if(DEFINED CONAN_VERIFY_SSL) set(CONAN_VERIFY_SSL_ARG ${CONAN_VERIFY_SSL}) endif() 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() macro(conan_config_install) @@ -637,37 +985,42 @@ macro(conan_config_install) set(multiValueArgs ARGS) cmake_parse_arguments(CONAN "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - find_program(CONAN_CMD conan) - if(NOT CONAN_CMD AND CONAN_REQUIRED) - message(FATAL_ERROR "Conan executable not found!") + if(DEFINED CONAN_COMMAND) + set(CONAN_CMD ${CONAN_COMMAND}) + else() + conan_check(REQUIRED) endif() if(DEFINED CONAN_VERIFY_SSL) - set(CONAN_VERIFY_SSL_ARG "--verify-ssl=${CONAN_VERIFY_SSL}") + set(CONAN_VERIFY_SSL_ARG "--verify-ssl=${CONAN_VERIFY_SSL}") endif() if(DEFINED CONAN_TYPE) - set(CONAN_TYPE_ARG "--type=${CONAN_TYPE}") + set(CONAN_TYPE_ARG "--type=${CONAN_TYPE}") endif() if(DEFINED CONAN_ARGS) - set(CONAN_ARGS_ARGS "--args=\"${CONAN_ARGS}\"") + set(CONAN_ARGS_ARGS "--args=\"${CONAN_ARGS}\"") endif() if(DEFINED CONAN_SOURCE) - set(CONAN_SOURCE_ARGS "--source-folder=${CONAN_SOURCE}") + set(CONAN_SOURCE_ARGS "--source-folder=${CONAN_SOURCE}") endif() if(DEFINED CONAN_TARGET) - set(CONAN_TARGET_ARGS "--target-folder=${CONAN_TARGET}") + set(CONAN_TARGET_ARGS "--target-folder=${CONAN_TARGET}") endif() - set (CONAN_CONFIG_INSTALL_ARGS ${CONAN_VERIFY_SSL_ARG} - ${CONAN_TYPE_ARG} - ${CONAN_ARGS_ARGS} - ${CONAN_SOURCE_ARGS} - ${CONAN_TARGET_ARGS}) + set (CONAN_CONFIG_INSTALL_ARGS ${CONAN_VERIFY_SSL_ARG} + ${CONAN_TYPE_ARG} + ${CONAN_ARGS_ARGS} + ${CONAN_SOURCE_ARGS} + ${CONAN_TARGET_ARGS}) 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() diff --git a/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp b/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp index e9aaa624b55..b902b0c6e07 100644 --- a/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp +++ b/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp @@ -1248,6 +1248,103 @@ void tst_TestCore::testRewriterReparentToNewNode() 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::create("QtQuick.Rectangle")); + + QScopedPointer 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 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() { const QLatin1String qmlString("\n" @@ -7346,7 +7443,7 @@ void tst_TestCore::testRewriterChangeId() 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; textEdit.setPlainText(QString::fromUtf8(qmlString)); @@ -7365,7 +7462,7 @@ void tst_TestCore::testRewriterRemoveId() ModelNode rootModelNode(view->rootModelNode()); QVERIFY(rootModelNode.isValid()); - QCOMPARE(rootModelNode.id(), QString("rect")); + QCOMPARE(rootModelNode.id(), QString("myRect")); // // remove id in text @@ -8528,7 +8625,7 @@ void tst_TestCore::loadTestFiles() QCOMPARE(rootModelNode.directSubModelNodes().count(), 4); QCOMPARE(rootModelNode.variantProperty("width").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.property("data").isDefaultProperty()); diff --git a/tests/auto/qml/qmldesigner/coretests/tst_testcore.h b/tests/auto/qml/qmldesigner/coretests/tst_testcore.h index 5248763fef9..d55bb2a1961 100644 --- a/tests/auto/qml/qmldesigner/coretests/tst_testcore.h +++ b/tests/auto/qml/qmldesigner/coretests/tst_testcore.h @@ -145,6 +145,7 @@ private slots: void testRewriterUnicodeChars(); void testRewriterTransactionAddingAfterReparenting(); void testRewriterReparentToNewNode(); + void testRewriterBehaivours(); // // unit tests QmlModelNodeFacade/QmlModelState diff --git a/tests/auto/qml/qmldesigner/data/fx/states.qml b/tests/auto/qml/qmldesigner/data/fx/states.qml index b0dd3f3d386..a37db5b2d4d 100644 --- a/tests/auto/qml/qmldesigner/data/fx/states.qml +++ b/tests/auto/qml/qmldesigner/data/fx/states.qml @@ -26,7 +26,7 @@ import QtQuick 2.0 Rectangle { - id: rect + id: myRect width: 200 height: 200 Text { @@ -39,7 +39,7 @@ Rectangle { State { name: "State1" PropertyChanges { - target: rect + target: myRect color: "blue" } PropertyChanges { @@ -50,7 +50,7 @@ Rectangle { State { name: "State2" PropertyChanges { - target: rect + target: myRect color: "gray" } PropertyChanges { diff --git a/tests/auto/utils/deviceshell/tst_deviceshell.cpp b/tests/auto/utils/deviceshell/tst_deviceshell.cpp index 2c209b94a1f..399a76e1ca6 100644 --- a/tests/auto/utils/deviceshell/tst_deviceshell.cpp +++ b/tests/auto/utils/deviceshell/tst_deviceshell.cpp @@ -60,9 +60,10 @@ private: bool testDocker(const FilePath &executable) { QtcProcess p; - p.setCommand({executable, {"info"}}); + p.setCommand({executable, {"info", "--format", "{{.OSType}}"}}); 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 @@ -336,10 +337,25 @@ private slots: QList runs{1,2,3,4,5,6,7,8,9}; - QList results = Utils::mapped(runs, [&shell](const int i) -> QByteArray{ + int maxDepth = 4; + int numMs = 0; + + while (true) { QElapsedTimer t; 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 results = Utils::mapped(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"; return result.stdOut; });