Merge remote-tracking branch 'origin/6.0'

Change-Id: I71b19dd8ecd96a7a2a58622f68283b8635264e48
This commit is contained in:
Eike Ziller
2021-12-01 09:24:05 +01:00
106 changed files with 754 additions and 425 deletions

View File

@@ -1,6 +1,10 @@
name: CMake Build Matrix name: CMake Build Matrix
on: [push, pull_request] on:
push:
paths-ignore:
- 'dist/**'
- 'doc/**'
env: env:
QT_VERSION: 6.2.1 QT_VERSION: 6.2.1
@@ -350,34 +354,58 @@ jobs:
message("::set-output name=elfutils_dir::${elfutils_dir}") message("::set-output name=elfutils_dir::${elfutils_dir}")
- name: Download ccache - name: Download ccache
id: ccache
shell: cmake -P {0} shell: cmake -P {0}
run: | run: |
set(ccache_url "https://github.com/cristianadam/ccache/releases/download/v$ENV{CCACHE_VERSION}/${{ runner.os }}.tar.xz") set(ccache_url "https://github.com/cristianadam/ccache/releases/download/v$ENV{CCACHE_VERSION}/${{ runner.os }}.tar.xz")
file(DOWNLOAD "${ccache_url}" ./ccache.tar.xz SHOW_PROGRESS) file(DOWNLOAD "${ccache_url}" ./ccache.tar.xz SHOW_PROGRESS)
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./ccache.tar.xz) execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./ccache.tar.xz)
- name: Prepare ccache timestamp - name: Prepare ccache archive name
id: ccache_cache_timestamp id: ccache
shell: cmake -P {0} shell: cmake -P {0}
run: | run: |
string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC)
message("::set-output name=timestamp::${current_date}")
file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}" github_workspace) file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}" github_workspace)
include(${github_workspace}/cmake/QtCreatorIDEBranding.cmake) include(${github_workspace}/cmake/QtCreatorIDEBranding.cmake)
string(REPLACE "." ";" IDE_VERSION_LIST ${IDE_VERSION_DISPLAY}) string(REPLACE "." ";" IDE_VERSION_LIST ${IDE_VERSION_DISPLAY})
list(GET IDE_VERSION_LIST 0 IDE_VERSION_MAJOR) list(GET IDE_VERSION_LIST 0 IDE_VERSION_MAJOR)
message("::set-output name=ide_major_version::${IDE_VERSION_MAJOR}") message("::set-output name=archive_name::ccache-${{ matrix.config.os }}-${{ matrix.config.cc }}-qtc${IDE_VERSION_MAJOR}")
- name: Download ccache archive
shell: cmake -P {0}
run: |
file(WRITE $ENV{GITHUB_WORKSPACE}/netrc.txt
"default login runneradmin password ${{ secrets.GITHUB_TOKEN }}")
- name: ccache cache files foreach(page_id RANGE 1 10)
uses: actions/cache@v1 file(
with: DOWNLOAD "https://api.github.com/repos/${{ github.repository }}/actions/artifacts?per_page=100&page=${page_id}"
path: .ccache HTTPHEADER "Accept: application/vnd.github.v3+json"
key: ${{ matrix.config.name }}-ccache-${{ steps.ccache_cache_timestamp.outputs.ide_major_version }}-${{ steps.ccache_cache_timestamp.outputs.timestamp }} NETRC_FILE "$ENV{GITHUB_WORKSPACE}/netrc.txt"
restore-keys: | NETRC REQUIRED
${{ matrix.config.name }}-ccache-${{ steps.ccache_cache_timestamp.outputs.ide_major_version }} SHOW_PROGRESS
artifacts.json)
file(READ artifacts.json artifacts_json)
string(JSON artifacts_length LENGTH "${artifacts_json}" "artifacts")
math(EXPR artifacts_length "${artifacts_length} - 1")
foreach(idx RANGE 0 ${artifacts_length})
string(JSON artifact_js GET "${artifacts_json}" "artifacts" ${idx})
string(JSON name GET "${artifact_js}" "name")
if ("${name}" STREQUAL "${{ steps.ccache.outputs.archive_name }}")
string(JSON download_url GET "${artifact_js}" "archive_download_url")
file(DOWNLOAD "${download_url}"
"${{ steps.ccache.outputs.archive_name }}.zip"
NETRC_FILE "$ENV{GITHUB_WORKSPACE}/netrc.txt"
NETRC REQUIRED
SHOW_PROGRESS)
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf "${{ steps.ccache.outputs.archive_name }}.zip")
file(MAKE_DIRECTORY .ccache)
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "../${{ steps.ccache.outputs.archive_name }}.tar" WORKING_DIRECTORY .ccache)
return()
endif()
endforeach()
endforeach()
- name: Install system libs - name: Install system libs
shell: cmake -P {0} shell: cmake -P {0}
@@ -455,8 +483,10 @@ jobs:
string(REPLACE "x86" "x64" Python3_EXECUTABLE "${Python3_EXECUTABLE}") string(REPLACE "x86" "x64" Python3_EXECUTABLE "${Python3_EXECUTABLE}")
set(WITH_TESTS "--with-tests") set(WITH_TESTS "--with-tests")
set(NO_DMG "--no-dmg")
if (${{github.ref}} MATCHES "tags/v") if (${{github.ref}} MATCHES "tags/v")
unset(WITH_TESTS) unset(WITH_TESTS)
unset(NO_DMG)
endif() endif()
execute_process( execute_process(
@@ -472,6 +502,7 @@ jobs:
${WITH_TESTS} ${WITH_TESTS}
${CDB_OPTION} ${CDB_OPTION}
${ELFUTILS_OPTION} ${ELFUTILS_OPTION}
${NO_DMG}
--add-config=-DCMAKE_C_COMPILER_LAUNCHER=ccache --add-config=-DCMAKE_C_COMPILER_LAUNCHER=ccache
--add-config=-DCMAKE_CXX_COMPILER_LAUNCHER=ccache --add-config=-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
--add-config=-DIDE_REVISION_URL=https://github.com/$ENV{GITHUB_REPOSITORY}/commits/$ENV{GITHUB_SHA} --add-config=-DIDE_REVISION_URL=https://github.com/$ENV{GITHUB_REPOSITORY}/commits/$ENV{GITHUB_SHA}
@@ -534,38 +565,48 @@ jobs:
endif() endif()
- name: Upload - name: Upload
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v2
with: with:
path: build/qtcreator-${{ matrix.config.artifact }}-${{ github.run_id }}.7z path: build/qtcreator-${{ matrix.config.artifact }}-${{ github.run_id }}.7z
name: qtcreator-${{ matrix.config.artifact }}-${{ github.run_id }}.7z name: qtcreator-${{ matrix.config.artifact }}-${{ github.run_id }}.7z
- name: Upload Devel - name: Upload Devel
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v2
with: with:
path: build/qtcreator-${{ matrix.config.artifact }}-${{ github.run_id }}_dev.7z path: build/qtcreator-${{ matrix.config.artifact }}-${{ github.run_id }}_dev.7z
name: qtcreator-${{ matrix.config.artifact }}-${{ github.run_id }}_dev.7z name: qtcreator-${{ matrix.config.artifact }}-${{ github.run_id }}_dev.7z
- name: Upload wininterrupt - name: Upload wininterrupt
if: runner.os == 'Windows' if: runner.os == 'Windows'
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v2
with: with:
path: build/wininterrupt-${{ matrix.config.artifact }}-${{ github.run_id }}.7z path: build/wininterrupt-${{ matrix.config.artifact }}-${{ github.run_id }}.7z
name: wininterrupt-${{ matrix.config.artifact }}-${{ github.run_id }}.7z name: wininterrupt-${{ matrix.config.artifact }}-${{ github.run_id }}.7z
- name: Upload qtcreatorcdbext - name: Upload qtcreatorcdbext
if: runner.os == 'Windows' && matrix.config.is_msvc if: runner.os == 'Windows' && matrix.config.is_msvc
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v2
with: with:
path: build/qtcreatorcdbext-${{ matrix.config.artifact }}-${{ github.run_id }}.7z path: build/qtcreatorcdbext-${{ matrix.config.artifact }}-${{ github.run_id }}.7z
name: qtcreatorcdbext-${{ matrix.config.artifact }}-${{ github.run_id }}.7z name: qtcreatorcdbext-${{ matrix.config.artifact }}-${{ github.run_id }}.7z
- name: Upload disk image - name: Upload disk image
if: runner.os == 'macOS' if: runner.os == 'macOS' && contains(github.ref, 'tags/v')
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v2
with: with:
path: build/qt-creator-${{ matrix.config.artifact }}-${{ github.run_id }}.dmg path: build/qt-creator-${{ matrix.config.artifact }}-${{ github.run_id }}.dmg
name: qt-creator-${{ matrix.config.artifact }}-${{ github.run_id }}.dmg name: qt-creator-${{ matrix.config.artifact }}-${{ github.run_id }}.dmg
- name: Create ccache archive
working-directory: .ccache
run: cmake -E tar cf ../${{ steps.ccache.outputs.archive_name }}.tar .
- name: Upload ccache archive
uses: actions/upload-artifact@v2
with:
path: ./${{ steps.ccache.outputs.archive_name }}.tar
name: ${{ steps.ccache.outputs.archive_name }}
release: release:
if: contains(github.ref, 'tags/v') if: contains(github.ref, 'tags/v')
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -587,7 +628,7 @@ jobs:
run: | run: |
echo "${{ steps.create_release.outputs.upload_url }}" > ./upload_url echo "${{ steps.create_release.outputs.upload_url }}" > ./upload_url
- uses: actions/upload-artifact@v1 - uses: actions/upload-artifact@v2
with: with:
path: ./upload_url path: ./upload_url
name: upload_url name: upload_url
@@ -620,40 +661,40 @@ jobs:
steps: steps:
- name: Download artifact - name: Download artifact
uses: actions/download-artifact@v1 uses: actions/download-artifact@v2
with: with:
name: qtcreator-${{ matrix.config.artifact }}-${{ github.run_id }}.7z name: qtcreator-${{ matrix.config.artifact }}-${{ github.run_id }}.7z
path: ./ path: ./
- name: Download Devel artifact - name: Download Devel artifact
uses: actions/download-artifact@v1 uses: actions/download-artifact@v2
with: with:
name: qtcreator-${{ matrix.config.artifact }}-${{ github.run_id }}_dev.7z name: qtcreator-${{ matrix.config.artifact }}-${{ github.run_id }}_dev.7z
path: ./ path: ./
- name: Download wininterrupt artifact - name: Download wininterrupt artifact
if: contains(matrix.config.artifact, 'Windows') if: contains(matrix.config.artifact, 'Windows')
uses: actions/download-artifact@v1 uses: actions/download-artifact@v2
with: with:
name: wininterrupt-${{ matrix.config.artifact }}-${{ github.run_id }}.7z name: wininterrupt-${{ matrix.config.artifact }}-${{ github.run_id }}.7z
path: ./ path: ./
- name: Download qtcreatorcdbext artifact - name: Download qtcreatorcdbext artifact
if: matrix.config.artifact == 'Windows-MSVC' if: matrix.config.artifact == 'Windows-MSVC'
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v2
with: with:
name: qtcreatorcdbext-${{ matrix.config.artifact }}-${{ github.run_id }}.7z name: qtcreatorcdbext-${{ matrix.config.artifact }}-${{ github.run_id }}.7z
path: ./ path: ./
- name: Download disk image artifact - name: Download disk image artifact
if: matrix.config.artifact == 'macOS' if: matrix.config.artifact == 'macOS'
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v2
with: with:
name: qt-creator-${{ matrix.config.artifact }}-${{ github.run_id }}.dmg name: qt-creator-${{ matrix.config.artifact }}-${{ github.run_id }}.dmg
path: ./ path: ./
- name: Download URL - name: Download URL
uses: actions/download-artifact@v1 uses: actions/download-artifact@v2
with: with:
name: upload_url name: upload_url
path: ./ path: ./

19
dist/changes-6.0.0.md vendored
View File

@@ -47,6 +47,16 @@ Editing
* Added option for `Insert header files on completion` * Added option for `Insert header files on completion`
* Improved location of generated `compile_commands.json` (QTCREATORBUG-26431) * Improved location of generated `compile_commands.json` (QTCREATORBUG-26431)
* Fixed missing reparsing after refactorings (QTCREATORBUG-26523) * Fixed missing reparsing after refactorings (QTCREATORBUG-26523)
* Fixed that parameters were incorrectly highlighted as output parameters
* Fixed highlighting of string literals in macros (QTCREATORBUG-26553)
* Fixed icon of signals and slots in completion list (QTCREATORBUG-26555)
* Fixed header completion for Qt headers (QTCREATORBUG-26482)
* Fixed code model update after UI header change
* Fixed that `Find References` could show results for deleted files
(QTCREATORBUG-26574)
* Fixed that highlighting of current symbol could vanish (QTCREATORBUG-26339)
* Fixed that nested items were not synchronized with cursor position in
outline (QTCREATORBUG-26509)
### QML ### QML
@@ -75,6 +85,7 @@ Projects
* Fixed that re-detecting compilers removed compilers from kits * Fixed that re-detecting compilers removed compilers from kits
(QTCREATORBUG-25697) (QTCREATORBUG-25697)
* Fixed GitHub action created by Qt Creator plugin wizard for Qt 6 * Fixed GitHub action created by Qt Creator plugin wizard for Qt 6
* Fixed crash when canceling device test dialog (QTCREATORBUG-26285)
### CMake ### CMake
@@ -155,10 +166,16 @@ Platforms
* Added details to device settings (QTCREATORBUG-23991) * Added details to device settings (QTCREATORBUG-23991)
* Added filter field for Android SDK manager * Added filter field for Android SDK manager
* Fixed that NDK 22 and later could not be added * Fixed that NDK 22 and later could not be added
* Fixed creation of Android template files (QTCREATORBUG-26580)
### iOS
* Fixed that no tasks were created for build issues (QTCREATORBUG-26541)
### WebAssembly ### WebAssembly
* Fixed running applications (QTCREATORBUG-25905, QTCREATORBUG-26189) * Fixed running applications (QTCREATORBUG-25905, QTCREATORBUG-26189,
QTCREATORBUG-26562)
### MCU ### MCU

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2019 The Qt Company Ltd. ** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -72,7 +72,9 @@
\li Select the \li Select the
\inlineimage qtcreator-analyze-start-button.png \inlineimage qtcreator-analyze-start-button.png
(\uicontrol Start) button to start the application from the (\uicontrol Start) button to start the application from the
Performance Analyzer. \uicontrol {Performance Analyzer}.
\inlineimage qtcreator-performance-analyzer-toolbar.png "Performance Analyzer toolbar"
\endlist \endlist
@@ -101,9 +103,21 @@
To create trace points for profiling memory usage on a target device, select To create trace points for profiling memory usage on a target device, select
\uicontrol Analyze > \uicontrol {Performance Analyzer Options} > \uicontrol Analyze > \uicontrol {Performance Analyzer Options} >
\uicontrol {Create Memory Trace Points}. \uicontrol {Create Memory Trace Points} or select
\inlineimage icons/create-tracepoint.png
on the \uicontrol {Performance Analyzer} toolbar.
To add events for the trace points, see \l{Choosing Event Types} In the \uicontrol {Create Memory Trace Points} dialog, you can modify the
script to run.
\image qtcreator-performance-analyzer-create-memory-trace-points.png "Create Memory Trace Points dialog"
If you need root privileges to run scripts as root, select the privileges to
use in the \uicontrol {Elevate privileges using} field.
Select \uicontrol OK to run the script.
To add events for the trace points, see \l{Choosing Event Types}.
You can record a memory trace to view usage graphs in the samples rows of You can record a memory trace to view usage graphs in the samples rows of
the timeline and to view memory allocations, peaks, and releases in the the timeline and to view memory allocations, peaks, and releases in the
@@ -418,8 +432,8 @@
You can load any \c perf.data files generated by recent versions of the You can load any \c perf.data files generated by recent versions of the
Linux Perf tool and view them in \QC. Select \uicontrol Analyze > Linux Perf tool and view them in \QC. Select \uicontrol Analyze >
\uicontrol {Performance Analyzer Options} > \uicontrol {Load perf.data} to \uicontrol {Performance Analyzer Options} > \uicontrol {Load perf.data File}
load a file. to load a file.
\image qtcreator-cpu-usage-analyzer-load-perf-trace.png \image qtcreator-cpu-usage-analyzer-load-perf-trace.png

View File

@@ -433,7 +433,8 @@
By default, the splash screen is hidden automatically By default, the splash screen is hidden automatically
when an activity is drawn. To keep it visible until when an activity is drawn. To keep it visible until
\l{QNativeInterface::QAndroidApplication::hideSplashScreen()} is \l{https://doc.qt.io/qt-6/qnativeinterface-qandroidapplication.html#hideSplashScreen}
{QNativeInterface::QAndroidApplication::hideSplashScreen()} is
called, select the \uicontrol {Sticky splash screen} check box. called, select the \uicontrol {Sticky splash screen} check box.
In \uicontrol {Image show mode}, select whether to center the splash screen In \uicontrol {Image show mode}, select whether to center the splash screen

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2019 The Qt Company Ltd. ** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -118,6 +118,8 @@
for particular plugins, select \uicontrol Tools > \uicontrol Options > for particular plugins, select \uicontrol Tools > \uicontrol Options >
\uicontrol FakeVim > \uicontrol General > \uicontrol {Plugin Emulation}. \uicontrol FakeVim > \uicontrol General > \uicontrol {Plugin Emulation}.
\image qtcreator-fakevim-options-general-plugin-emulation.png "FakeVim Plugin Emulation options"
Currently emulated plugins: Currently emulated plugins:
\list \list
\li \l{https://github.com/tpope/vim-commentary}{vim-commentary}: \c gc \li \l{https://github.com/tpope/vim-commentary}{vim-commentary}: \c gc
@@ -129,9 +131,10 @@
register \c x. register \c x.
\li ["x]grr to replace the current line. \li ["x]grr to replace the current line.
\endlist \endlist
\li \l{https://github.com/tommcdo/vim-exchange}{vim-exchange}
\li \l{https://github.com/vim-scripts/argtextobj.vim}{argtextobj.vim}: \li \l{https://github.com/vim-scripts/argtextobj.vim}{argtextobj.vim}:
Defines the \c ia and \c aa text objects for function parameters. Defines the \c ia and \c aa text objects for function parameters.
\li \l{https://github.com/tommcdo/vim-exchange}{vim-exchange}:
A text exchange operator for vim.
\li \l{https://github.com/tpope/vim-surround}{vim-surround}: \li \l{https://github.com/tpope/vim-surround}{vim-surround}:
Adds mappings for deleting, adding and changing surroundings. Adds mappings for deleting, adding and changing surroundings.
\endlist \endlist
@@ -287,15 +290,29 @@
\section1 Mapping FakeVim Commands \section1 Mapping FakeVim Commands
To map commands entered on the \uicontrol FakeVim command line to actions To map commands entered on the \uicontrol FakeVim command line to
of the \QC core, select \uicontrol Tools > \uicontrol Options > \QC functions, select \uicontrol Tools > \uicontrol Options >
\uicontrol FakeVim > \uicontrol {Ex Command Mapping}. \uicontrol FakeVim > \uicontrol {Ex Command Mapping}.
Enter a string in the \uicontrol Filter field to search for a specific
\QC function.
\image qtcreator-fakevim-options-ex-command-mapping.png "FakeVim Ex Command Mapping options"
Select a function in the list, and enter a string that will trigger the
function in the \uicontrol {Regular expression} field. You can view the
trigger expression in the \uicontrol {Ex Trigger Expression} field. To
remove the trigger expression, select \uicontrol Reset.
To reset the trigger expressions for all functions, select
\uicontrol {Reset All}.
To map \e {user commands} to keyboard shortcuts, select \uicontrol Tools > To map \e {user commands} to keyboard shortcuts, select \uicontrol Tools >
\uicontrol Options > \uicontrol FakeVim > \uicontrol Options > \uicontrol FakeVim >
\uicontrol {User Command Mapping}. The user command mapped to the shortcut \uicontrol {User Command Mapping}. The user command mapped to the shortcut
is executed by FakeVim as if you were typing it (as when replaying a macro). is executed by FakeVim as if you were typing it (as when replaying a macro).
\image qtcreator-fakevim-options-user-command-mapping.png "FakeVim User Command Mapping options"
\section1 Specifying FakeVim Options \section1 Specifying FakeVim Options
To make changes to the Vim-style settings, select \uicontrol Tools > To make changes to the Vim-style settings, select \uicontrol Tools >
@@ -319,5 +336,6 @@
\uicontrol FakeVim > \uicontrol {Use FakeVim} or press \key {Alt+V,Alt+V}. \uicontrol FakeVim > \uicontrol {Use FakeVim} or press \key {Alt+V,Alt+V}.
You can temporarily escape FakeVim mode to access the normal \QC keyboard You can temporarily escape FakeVim mode to access the normal \QC keyboard
shortcuts like \key {Ctrl-R} for \uicontrol Run by pressing \key {,} first. shortcuts like \key {Ctrl-R} for \uicontrol Run by first pressing the comma
key (\key {,}).
*/ */

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2018 The Qt Company Ltd. ** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -75,6 +75,11 @@
\li In \uicontrol {MIME Type}, select a MIME type. \li In \uicontrol {MIME Type}, select a MIME type.
\li In \uicontrol Handler, double-click the editor name to display a
context-menu where you can select another editor to open the file
in by default. The menu is available only if alternative suitable
editors are available.
\li In \uicontrol Patterns, add the filename extension for the type of files \li In \uicontrol Patterns, add the filename extension for the type of files
that you want to identify as having this MIME type. that you want to identify as having this MIME type.
@@ -96,12 +101,7 @@
\note You are recommended not to change the range and priority, \note You are recommended not to change the range and priority,
because it might cause problems when opening files in \QC. because it might cause problems when opening files in \QC.
\li In \uicontrol Handler, double-click the editor name to display a \li Click \uicontrol OK to return to the \uicontrol {MIME Types} tab.
context-menu where you can select another editor to open the file
in by default. The menu is available only if alternative suitable
editors are available.
\li Click \uicontrol OK.
\endlist \endlist
@@ -119,8 +119,8 @@
select \uicontrol {Reset MIME Types}. To revert the changes you have select \uicontrol {Reset MIME Types}. To revert the changes you have
made to the default editors, select \uicontrol {Reset Handlers}. made to the default editors, select \uicontrol {Reset Handlers}.
\note If you now select \uicontrol OK or \uicontrol Apply, you permanently lose all \note If you select \uicontrol OK or \uicontrol Apply after reverting
your own patterns and magic headers. The changes are reverted the next changes, you permanently lose all your own patterns and magic headers.
time you start \QC. They are removed the next time you start \QC.
*/ */

View File

@@ -109,3 +109,7 @@
\externalpage https://doc.qt.io/qt/qtqml-syntax-imports.html#qml-import-path \externalpage https://doc.qt.io/qt/qtqml-syntax-imports.html#qml-import-path
\title QML Import Path \title QML Import Path
*/ */
/*!
\externalpage https://doc.qt.io/QtApplicationManager/
\title Qt Application Manager
*/

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2019 The Qt Company Ltd. ** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -111,35 +111,30 @@
\section1 Find a specific setting \section1 Find a specific setting
To find specific settings you require in \uicontrol{Tools} > \uicontrol{Options} To find specific settings in \uicontrol Tools > \uicontrol Options,
use the filter located at the top left of the \uicontrol Options dialog box. use the filter located at the top left of the \uicontrol Options dialog box.
\section1 Open output panes \section1 Open output panes
The output panes provide a list of errors and warnings encountered during The \l{Viewing Output}{output panes} provide a list of errors and warnings
a build, detailed output from the compiler, status of a program when it is encountered during a build, detailed output from the compiler, status of a
executed and debug output, as well as search results. program when it is executed, debug output, and search results.
To open output panes, use the following shortcuts: To open output panes, use the following shortcuts:
\list \list
\li \uicontrol{Issues} pane Alt+1 (Cmd+1 on \macos) \li \uicontrol{Issues} - \key Alt+1 (\key Cmd+1 on \macos)
\li \uicontrol{Search Results} pane Alt+2 (Cmd+2 on \macos) \li \uicontrol{Search Results} - \key Alt+2 (\key Cmd+2 on \macos)
\li \uicontrol{Application Output} pane Alt+3 (Cmd+3 on \macos) \li \uicontrol{Application Output} - \key Alt+3 (\key Cmd+3 on \macos)
\li \uicontrol{Compile Output} pane Alt+4 (Cmd+4 on \macos) \li \uicontrol{Compile Output} - \key Alt+4 (\key Cmd+4 on \macos)
\endlist \endlist
To open the other output panes, such as \uicontrol{General Messages} and For additional ways to open all output panes, see \l{Viewing Output}.
\uicontrol{Version Control}, select \uicontrol View >
\uicontrol {Output Panes}. The menu items also display
the keyboard shortcuts that you can use.
For more information about output panes, see \l{Viewing Output}.
\section1 Find keyboard shortcuts \section1 Find keyboard shortcuts
@@ -147,17 +142,17 @@
You can see the keyboard shortcut for a menu command in the menu You can see the keyboard shortcut for a menu command in the menu
or the tooltip for a button. or the tooltip for a button.
To customize, import or export keyboard shortcuts, select \uicontrol Tools > To customize, import, or export keyboard shortcuts, select \uicontrol Tools >
\uicontrol Options > \uicontrol Environment > \uicontrol Keyboard. \uicontrol Options > \uicontrol Environment > \uicontrol Keyboard.
\section1 Run \QC from the command line \section1 Run \QC from the command line
You can launch \QC from command line using the name of an You can launch \QC from the command line using the name of an
existing session or \c .pro file by giving the name as the command existing \l{Managing Sessions}{session} or project file by entering
argument. the name as the command argument.
For example, running \tt{qtcreator somesession}, launches \QC and For example, running \c {qtcreator somesession}, launches \QC and
loads session somesession. loads the session called \e somesession.
For more information, see \l{Using Command Line Options}. For more information, see \l{Using Command Line Options}.
@@ -210,7 +205,7 @@
If special debugging of Qt objects fails due to data corruption within the If special debugging of Qt objects fails due to data corruption within the
debugged objects, you can switch off the debugging helpers. When debugging debugged objects, you can switch off the debugging helpers. When debugging
helpers are switched off low-level structures become visible. helpers are switched off, low-level structures become visible.
To switch off the debugging helpers: To switch off the debugging helpers:
\list 1 \list 1
@@ -250,7 +245,7 @@
\section1 Quickly locate files using the keyboard \section1 Quickly locate files using the keyboard
The \uicontrol Locator provides one of the easiest ways in \QC to browse The \uicontrol Locator provides one of the easiest ways in \QC to browse
through projects, files, classes, functions, documentation and file systems. through projects, files, classes, functions, documentation, and file systems.
To quickly access files not directly mentioned in your project, you can To quickly access files not directly mentioned in your project, you can
create your own locator filters. That way you can locate files in a create your own locator filters. That way you can locate files in a
directory structure you have defined. directory structure you have defined.
@@ -307,12 +302,14 @@
\section1 Enclose selected code in curly braces, parentheses, or double quotes \section1 Enclose selected code in curly braces, parentheses, or double quotes
Press \key {Shift} and then the opening character. When you have selected code and enter one of the following opening
characters, the appropriate closing character is added automatically
at the end of the selection:
\list \list
\li Curly braces: \key {Shift+\{} \li {
\li Parentheses: \key {Shift+(} \li (
\li Double quotes: \key {Shift+"} \li "
\endlist \endlist
\section1 Select the enclosing block in C++ \section1 Select the enclosing block in C++

View File

@@ -123,6 +123,10 @@
The QNX Neutrino RTOS should provide a few additional command line tools The QNX Neutrino RTOS should provide a few additional command line tools
and services, as described in \l {Qt Creator Target Requirements}. and services, as described in \l {Qt Creator Target Requirements}.
\note In Qt 6, Qt for QNX is a part of
\l{https://doc.qt.io/QtForDeviceCreation/index.html}{Qt for Device Creation},
and the \QC support is considered experimental.
The following topics contain more information about developing applications The following topics contain more information about developing applications
for QNX devices: for QNX devices:

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2020 The Qt Company Ltd. ** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -87,7 +87,7 @@
\li To deploy applications and run them remotely on devices, specify \li To deploy applications and run them remotely on devices, specify
parameters for accessing the devices: parameters for accessing the devices:
\list 1 \list a
\li Select \uicontrol Tools > \uicontrol Options > \li Select \uicontrol Tools > \uicontrol Options >
\uicontrol Devices > \uicontrol Devices > \uicontrol Add > \uicontrol Devices > \uicontrol Devices > \uicontrol Add >
@@ -108,14 +108,23 @@
application as. application as.
This value will be available in the variable \c %{Device:UserName}. This value will be available in the variable \c %{Device:UserName}.
\li In the \uicontrol {The authentication type} field, select \li Select \uicontrol {Next} to open the
\uicontrol Default to use the currently displayed private \uicontrol {Key Deployment} dialog.
key file for authentication. Select \uicontrol {Specific Key}
to use some other key, and enter the path to the file that
contains the private key in the field below. This value will
be available in the variable \c %{Device:PrivateKeyFile}.
\li Click \uicontrol {Next} to create the connection. \image qtcreator-generic-linux-device-key-deployment.png "Key Deployment dialog"
\li In \uicontrol {Private key file}, select a private key file
to use for authentication. This value will be available in
the variable \c %{Device:PrivateKeyFile}.
\li If you do not have a public-private key pair, select
\uicontrol {Create New Key Pair}. For more information,
see \l{Generating SSH Keys}.
\li Select \uicontrol {Deploy Public Key} to copy the public
key to the device.
\li Select \uicontrol {Next} to create the connection.
\endlist \endlist

View File

@@ -55,10 +55,12 @@
\image qtcreator-build-environment.png "Build Environment" \image qtcreator-build-environment.png "Build Environment"
\note The changes are stored in the local project specific \c{.pro.user} The changes are stored in the local project specific \c{CMakeLists.txt.user}
file. Therefore, they are not suitable for sharing between developers or or \c{.pro.user} file, depending on the build system you use. Therefore,
development PCs. To share settings, incorporate them into the build system. they are not suitable for sharing between developers or development PCs. To
For example, if you use qmake, make the changes in the \c{.pro} file. share settings, incorporate them into the build system. For example, if you
use CMake, make the changes in the \c {CMakeLists.txt} file, and if you use
qmake, make the changes in the \c{.pro} file.
\section1 Batch Editing \section1 Batch Editing

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2020 The Qt Company Ltd. ** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -65,6 +65,18 @@
\endlist \endlist
If your project has several run targets defined, such as
\l{Running Autotests}{tests}, you can select them in the kit selector.
\image qtcreator-kit-selector-run-targets.png "Run targets in the kit selector"
If you have connected \l{Mobile Platforms}{mobile devices} or
\l{Embedded Platforms}{embedded devices} to the development PC
or added virtual devices, such as \l{Managing Android Virtual Devices (AVD)}
{Android Virtual Devices (AVD)}, you can select them in the kit selector.
Select \uicontrol Manage to manage device settings. For example, you can add
AVDs or manually start disconnected AVDs.
The \uicontrol {Application Output} pane displays the status of the The \uicontrol {Application Output} pane displays the status of the
application while it is running. You can select the \uicontrol Run button application while it is running. You can select the \uicontrol Run button
in the pane to re-run applications without building them first. This is in the pane to re-run applications without building them first. This is

View File

@@ -1,13 +1,13 @@
/**************************************************************************** /****************************************************************************
** **
** This file is part of Qt Creator
**
** Copyright (C) 2018 Blackberry ** Copyright (C) 2018 Blackberry
**
** Contact: Blackberry (qt@blackberry.com) ** Contact: Blackberry (qt@blackberry.com)
** Contact: KDAB (info@kdab.com) ** Contact: KDAB (info@kdab.com)
** **
** This file is part of Qt Creator. ** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
** **
** Commercial License Usage ** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in ** Licensees holding valid commercial Qt licenses may use this file in
@@ -40,6 +40,10 @@
a few additional command line tools and services, as described in a few additional command line tools and services, as described in
\l {Qt Creator Target Requirements}. \l {Qt Creator Target Requirements}.
\note In Qt 6, Qt for QNX is a part of
\l{https://doc.qt.io/QtForDeviceCreation/index.html}{Qt for Device Creation},
and the \QC support is considered experimental.
\section1 Adding a QNX Neutrino Device in \QC \section1 Adding a QNX Neutrino Device in \QC
Adding a QNX Neutrino device is very similar to Adding a QNX Neutrino device is very similar to

View File

@@ -89,7 +89,7 @@
\note At the time of this writing, \macos is not supported as a development \note At the time of this writing, \macos is not supported as a development
host for Qt for Device Creation. This means that you cannot preview UIs on host for Qt for Device Creation. This means that you cannot preview UIs on
devices if you are using \QDS on \macos. For more information about devices if you are using \QC on \macos. For more information about
supported development hosts, see supported development hosts, see
\l {https://doc.qt.io/QtForDeviceCreation/qtdc-supported-platforms.html#supported-development-hosts} \l {https://doc.qt.io/QtForDeviceCreation/qtdc-supported-platforms.html#supported-development-hosts}
{Supported Development Hosts}. {Supported Development Hosts}.

View File

@@ -96,7 +96,7 @@
\endif \endif
\note To profile applications on \l{glossary-device}{devices}, you \note To profile applications on \l{glossary-device}{devices}, you
must install Qt 4.7.4 or later libraries on them. must install Qt libraries on them.
\li Select \uicontrol Analyze > \uicontrol {QML Profiler} to profile the \li Select \uicontrol Analyze > \uicontrol {QML Profiler} to profile the
current application. current application.
@@ -131,8 +131,8 @@
application is launched. Data collection starts when you select the button application is launched. Data collection starts when you select the button
again. again.
To save all the collected data, right-click any QML Profiler view to open To save all the collected data, select \uicontrol Analyze >
the context menu, and then select \uicontrol {Save QML Trace}. To view the saved \uicontrol {QML Profiler Options} > \uicontrol {Save QML Trace}. To view the saved
data, select \uicontrol {Load QML Trace}. You can also deliver the saved data to data, select \uicontrol {Load QML Trace}. You can also deliver the saved data to
others for examination or load data saved by them. others for examination or load data saved by them.
@@ -167,13 +167,21 @@
\section1 Attaching to Running Qt Quick Applications \section1 Attaching to Running Qt Quick Applications
To profile Qt Quick applications that are not launched by \QC, select You can profile Qt Quick applications that are not launched by \QC.
\uicontrol Analyze > \uicontrol {QML Profiler (External)}. You must enable However, you must enable QML debugging and profiling for the application
QML debugging and profiling for the application in the project build in the project build settings. For more information, see
settings. For more information, see \l{Setting Up QML Debugging}. \l{Setting Up QML Debugging}.
In the \uicontrol {QML Profiler} dialog, \uicontrol Port field, specify the port to To attach to waiting applications:
listen to.
\list 1
\li Select \uicontrol Analyze >
\uicontrol {QML Profiler (Attach to Waiting Application)}.
\image qml-profiler-start-dialog.png "Start QML Profiler dialog"
\li In \uicontrol Kit, select the kit used to build the application.
\li In \uicontrol Port, specify the port to listen to.
\li Select \uicontrol OK.
\endlist
\section1 Analyzing Collected Data \section1 Analyzing Collected Data
@@ -578,21 +586,19 @@
\section2 Visualizing Statistics as Flame Graphs \section2 Visualizing Statistics as Flame Graphs
The \uicontrol {Flame Graph} view shows a more concise statistical overview The \uicontrol {Flame Graph} view shows a more concise statistical overview
of QML and JavaScript execution. In the \uicontrol {Visualize Total Time} of QML and JavaScript execution. In the \uicontrol {Total Time} view, the
view, the horizontal bars show the amount of horizontal bars show the amount of
time all invocations of a certain function took together, relative to the time all invocations of a certain function took together, relative to the
total runtime of all JavaScript and QML events. The nesting shows which total runtime of all JavaScript and QML events. The nesting shows which
functions were called by which other ones. functions were called by which other ones.
\image qml-profiler-flamegraph.png "Flame Graph View" \image qml-profiler-flamegraph.png "Flame Graph View"
To view the total amount of memory allocated by the functions in the To view the total amount of memory allocated by the functions, select
\uicontrol {Visualize Memory} view, select \uicontrol Memory in the \uicontrol Memory in the drop-down menu.
drop-down menu (1).
To view the the number of memory allocations performed by the functions in To view the the number of memory allocations performed by the functions,
the \uicontrol {Visualize Allocations} view, select \uicontrol Allocations select \uicontrol Allocations.
in the drop-down menu.
Double-click an item in a view to zoom into it. Double-click an empty Double-click an item in a view to zoom into it. Double-click an empty
area in the view to zoom out again. area in the view to zoom out again.

View File

@@ -384,9 +384,24 @@
\endlist \endlist
Output panes are available in all \l{Selecting Modes}{modes}. Click the name Output panes are available on the taskbar in all \l{Selecting Modes}{modes}.
of an output pane to open the pane. To maximize an open output pane, click
the \uicontrol {Maximize Output Pane} button or press \key {Alt+9}. \image qtcreator-output-panes-taskbar.png "Output panes on the taskbar"
You can open output panes in the following ways:
\list
\li Select the output pane on the taskbar.
\li Select \key Alt (\key Cmd on \macos) and the number of the pane on
the taskbar.
\li Select \inlineimage icons/output-pane-menu.png
, and then select the pane to open.
\li Select \uicontrol View > \uicontrol {Output Panes}.
The menu items also display the keyboard shortcuts that you can use.
\endlist
To maximize an open output pane, select the \inlineimage arrowup.png
(\uicontrol {Maximize Output Pane}) button or press \key {Alt+Shift+9}.
To increase or decrease the output text size, select \inlineimage plus.png To increase or decrease the output text size, select \inlineimage plus.png

View File

@@ -55,7 +55,7 @@
To create a project: To create a project:
\list 1 \list 1
\li Select \uicontrol File > \uicontrol {New File or Project} > \li Select \uicontrol File > \uicontrol {New Project} >
\uicontrol General > \uicontrol {Qt Quick Application - Empty} > \uicontrol General > \uicontrol {Qt Quick Application - Empty} >
\uicontrol Choose. \uicontrol Choose.
\li In the \uicontrol Name field, enter the project name: \e {loginui1}. \li In the \uicontrol Name field, enter the project name: \e {loginui1}.
@@ -308,8 +308,8 @@
To create a push button by using the wizard template: To create a push button by using the wizard template:
\list 1 \list 1
\li Select \uicontrol File > \uicontrol {New File or Project} > \li Select \uicontrol File > \uicontrol {New File} >
\uicontrol {Files and Classes} > \uicontrol {Qt Quick Controls} > \uicontrol {Qt Quick Controls} >
\uicontrol {Custom Button} > \uicontrol Choose. \uicontrol {Custom Button} > \uicontrol Choose.
\li In the \uicontrol {Component name} field, enter a name for your \li In the \uicontrol {Component name} field, enter a name for your
button component: \e {EntryField}. button component: \e {EntryField}.

View File

@@ -46,8 +46,8 @@
\section1 Creating Reusable Buttons \section1 Creating Reusable Buttons
We select \uicontrol File > \uicontrol {New File or Project} > We select \uicontrol File > \uicontrol {New File} >
\uicontrol {Files and Classes} > \uicontrol {Qt Quick Controls} > \uicontrol {Qt Quick Controls} >
\uicontrol {Custom Button} to create a reusable menu bar button \uicontrol {Custom Button} to create a reusable menu bar button
that we call \e CustomButton. that we call \e CustomButton.

View File

@@ -63,7 +63,7 @@
We use the \uicontrol {Qt for MCUs Application} project template to create We use the \uicontrol {Qt for MCUs Application} project template to create
an application for MCUs, which support only a subset of the preset an application for MCUs, which support only a subset of the preset
\l{glossary-component}{components}. We select \uicontrol File > \l{glossary-component}{components}. We select \uicontrol File >
\uicontrol {New File or Project} > \uicontrol {Qt for MCUs Application} > \uicontrol {New Project} > \uicontrol {Qt for MCUs Application} >
\uicontrol Choose, and follow the instructions of the wizard to create our \uicontrol Choose, and follow the instructions of the wizard to create our
project. project.
@@ -100,7 +100,7 @@
that we use to indicate that a button is pressed. that we use to indicate that a button is pressed.
Alternatively, you could create the screens from scratch in \QDS Alternatively, you could create the screens from scratch in \QDS
by selecting \uicontrol File > \uicontrol {New File or Project} > by selecting \uicontrol File > \uicontrol {New File} >
\uicontrol {Qt Quick Files}. While designing the screens, you can \uicontrol {Qt Quick Files}. While designing the screens, you can
move reusable components into separate files. For more information, move reusable components into separate files. For more information,
see \l{Components}. see \l{Components}.

View File

@@ -40,7 +40,7 @@
\list 1 \list 1
\li Select \uicontrol File > \uicontrol {New File or Project} > \li Select \uicontrol File > \uicontrol {New File} >
\if defined(qtcreator) \if defined(qtcreator)
\uicontrol Qt > \uicontrol {Qt Quick UI File} > \uicontrol Qt > \uicontrol {Qt Quick UI File} >
\else \else
@@ -124,7 +124,6 @@
information, see \l{Creating Scalable Buttons and Borders}. information, see \l{Creating Scalable Buttons and Borders}.
*/ */
/*! /*!
\previouspage quick-buttons.html \previouspage quick-buttons.html
\page quick-scalable-image.html \page quick-scalable-image.html
@@ -158,7 +157,7 @@
\section1 Creating the Button Component \section1 Creating the Button Component
To create a button component, select \uicontrol File > To create a button component, select \uicontrol File >
\uicontrol {New File or Project} > \uicontrol {New File} >
\if defined(qtcreator) \if defined(qtcreator)
\uicontrol Qt > \uicontrol {Qt Quick UI File} > \uicontrol Qt > \uicontrol {Qt Quick UI File} >
\else \else

View File

@@ -47,7 +47,7 @@
To use wizard templates to create custom components: To use wizard templates to create custom components:
\list 1 \list 1
\li Select \uicontrol File > \uicontrol {New File or Project} > \li Select \uicontrol File > \uicontrol {New File} >
\if defined(qtcreator) \if defined(qtcreator)
\uicontrol Qt > \uicontrol {Qt Quick UI File} > \uicontrol Qt > \uicontrol {Qt Quick UI File} >
\else \else

View File

@@ -43,31 +43,12 @@
\QBPS is delivered as an Adobe extension (ZXP) \QBPS is delivered as an Adobe extension (ZXP)
package and requires Adobe Photoshop version 20.0.0, or later package and requires Adobe Photoshop version 20.0.0, or later
to be installed. The \QBPS installation process differs depending to be installed. The \QBPS installation process differs depending
on whether you use ZXPInstaller and whether you are installing on on whether you are installing on
Windows or \macos. Windows or \macos.
\section1 Installing with ZXPInstaller \section1 Installing on Windows
To use ZXPInstaller to install \QBPS: To install \QBPS on Windows:
\list 1
\li Download and install \l{http://zxpinstaller.com/}{ZXPInstaller}.
\li Start ZXPInstaller.
\li Drag and drop the \QBPS ZXP package from
\c {Qt\Tools\QtDesignStudio\photoshop_bridge} on Windows
or \c {Qt/QtDesignStudio/photoshop_bridge} on \macos
to ZXPInstaller.
\li Follow the instructions of the installation program.
\endlist
\section1 Installing Without ZXPInstaller
The \QBPS installation process differs depending on the platform you
are installing on.
\section2 Installing on Windows
To install \QBPS on Windows without using ZXPInstaller:
\list 1 \list 1
\li Copy the \QBPS ZXP package from \li Copy the \QBPS ZXP package from
@@ -83,9 +64,9 @@
\endcode \endcode
\endlist \endlist
\section2 Installing on \macos \section1 Installing on \macos
To install \QBPS on \macos without using ZXPInstaller: To install \QBPS on \macos:
\list 1 \list 1
\li Copy the \QBPS ZXP package from \li Copy the \QBPS ZXP package from

View File

@@ -92,7 +92,7 @@
for it, as described in \l {Creating Projects}. for it, as described in \l {Creating Projects}.
To create the flow view, select \uicontrol File > To create the flow view, select \uicontrol File >
\uicontrol {New File or Project} > \uicontrol {Files and Classes} > \uicontrol {New File} >
\uicontrol {Qt Quick Files} > \uicontrol {Flow View} \uicontrol {Qt Quick Files} > \uicontrol {Flow View}
and follow the instructions of the wizard. and follow the instructions of the wizard.
@@ -197,8 +197,8 @@
To add flow items: To add flow items:
\list 1 \list 1
\li Select \uicontrol File > \uicontrol {New File or Project} > \li Select \uicontrol File > \uicontrol {New File} >
\uicontrol {Files and Classes} > \uicontrol {Qt Quick Files} > \uicontrol {Qt Quick Files} >
\uicontrol {Flow Item} and follow the instructions of the wizard \uicontrol {Flow Item} and follow the instructions of the wizard
to create flow items for each screen in the UI. to create flow items for each screen in the UI.
\li Add content to the flow item in one of the following ways: \li Add content to the flow item in one of the following ways:
@@ -649,8 +649,8 @@
\uicontrol Components > \uicontrol {Flow View}. \uicontrol Components > \uicontrol {Flow View}.
\list 1 \list 1
\li Select \uicontrol File > \uicontrol {New File or Project} > \li Select \uicontrol File > \uicontrol {New File} >
\uicontrol {Files and Classes} > \uicontrol {Qt Quick Files} > \uicontrol {Qt Quick Files} >
\uicontrol {Flow Item} to create a flow item. \uicontrol {Flow Item} to create a flow item.
\li In \l States, add states to the flow item. \li In \l States, add states to the flow item.
\li Open the .ui.qml file that contains the \l{Adding Flow Views} \li Open the .ui.qml file that contains the \l{Adding Flow Views}

View File

@@ -70,7 +70,7 @@
To import assets exported in \QB to \QDS projects: To import assets exported in \QB to \QDS projects:
\list 1 \list 1
\li Select \uicontrol File > \uicontrol {New File or Project} > \li Select \uicontrol File > \uicontrol {New Project} >
\uicontrol General > \uicontrol {Qt Quick Application - Empty} > \uicontrol General > \uicontrol {Qt Quick Application - Empty} >
\uicontrol Choose, and follow the instructions of the wizard to \uicontrol Choose, and follow the instructions of the wizard to
create an empty project. create an empty project.

View File

@@ -66,8 +66,8 @@
\code \code
importPaths: [ "imports", "backend" ] importPaths: [ "imports", "backend" ]
\endcode \endcode
\li Select \uicontrol File > \uicontrol {New File or Project} > \li Select \uicontrol File > \uicontrol {New File} >
\uicontrol {Files and Classes} > \uicontrol {Qt Quick Files} > \uicontrol {Qt Quick Files} >
\uicontrol {Qt Quick File} > \uicontrol Choose to add a Qt \uicontrol {Qt Quick File} > \uicontrol Choose to add a Qt
Quick file that will specify the API of the UI. Quick file that will specify the API of the UI.
\li Follow the instructions of the wizard to create the Qt Quick file \li Follow the instructions of the wizard to create the Qt Quick file
@@ -75,8 +75,8 @@
\e Values.qml. \e Values.qml.
\note Make sure to capitalize the filename, because it will become \note Make sure to capitalize the filename, because it will become
a custom component. a custom component.
\li Select \uicontrol File > \uicontrol {New File or Project} > \li Select \uicontrol File > \uicontrol {New File} >
\uicontrol {Files and Classes} > \uicontrol {JavaScript} > \uicontrol {JavaScript} >
\uicontrol {JavaScript File} > \uicontrol Choose to create a \uicontrol {JavaScript File} > \uicontrol Choose to create a
JavaScript file that generates mock data for the UI. JavaScript file that generates mock data for the UI.
\li Follow the instructions of the wizard to create the JavaScript file \li Follow the instructions of the wizard to create the JavaScript file

View File

@@ -111,7 +111,7 @@
\section1 Using Project Wizards \section1 Using Project Wizards
\list 1 \list 1
\li Select \uicontrol File > \uicontrol {New File or Project}. \li Select \uicontrol File > \uicontrol {New Project}.
\li Select a wizard template, and then select \uicontrol Choose. \li Select a wizard template, and then select \uicontrol Choose.
\li In the \uicontrol Name field, enter a name for the project. \li In the \uicontrol Name field, enter a name for the project.
Keep in mind that projects cannot be easily renamed later. Keep in mind that projects cannot be easily renamed later.

View File

@@ -193,7 +193,7 @@
example, if you create a 3D project, preset 3D components are added to it. example, if you create a 3D project, preset 3D components are added to it.
You can add more preset components in \uicontrol Library. You can add more preset components in \uicontrol Library.
\image studio-project-wizards.png "New File or Project dialog" \image studio-project-wizards.png "New Project dialog"
Read more about projects: Read more about projects:

View File

@@ -36,9 +36,9 @@
and dynamic behavior. You can test, preview, and fine-tune your designs to and dynamic behavior. You can test, preview, and fine-tune your designs to
pixel-perfection live on the desktop or target device. pixel-perfection live on the desktop or target device.
View \l{All Topics}{all topics} or select a topic from below.
\table \table
\row
\li {4,1} \b {\l{All Topics}}
\row \row
\li \inlineimage front-gs.png \li \inlineimage front-gs.png
\li \inlineimage front-ui.png \li \inlineimage front-ui.png

View File

@@ -154,7 +154,8 @@ def package(args, paths):
common.check_print_call(['7z', 'a', '-mmt2', common.check_print_call(['7z', 'a', '-mmt2',
os.path.join(paths.result, args.name + '_dev.7z'), '*'], os.path.join(paths.result, args.name + '_dev.7z'), '*'],
paths.dev_install) paths.dev_install)
if args.with_debug_info: # check for existence - the DebugInfo install target doesn't work for telemetry plugin
if args.with_debug_info and os.path.exists(paths.debug_install):
common.check_print_call(['7z', 'a', '-mmt2', common.check_print_call(['7z', 'a', '-mmt2',
os.path.join(paths.result, args.name + '-debug.7z'), '*'], os.path.join(paths.result, args.name + '-debug.7z'), '*'],
paths.debug_install) paths.debug_install)

View File

@@ -102,11 +102,6 @@ Item {
} }
} }
View3D {
// Dummy view to hold the context
// TODO remove when QTBUG-87678 is fixed
}
Item { Item {
id: contentItem id: contentItem
anchors.fill: parent anchors.fill: parent

View File

@@ -998,18 +998,17 @@ void Qt5InformationNodeInstanceServer::doRenderModelNodeImageView()
void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView() void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView()
{ {
#ifdef QUICK3D_MODULE #ifdef QUICK3D_MODULE
m_modelNode3DImageViewAsyncData.cleanup();
if (m_modelNode3DImageViewData.rootItem) { if (m_modelNode3DImageViewData.rootItem) {
QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "destroyView");
if (!m_modelNode3DImageViewData.contentItem) if (!m_modelNode3DImageViewData.contentItem)
m_modelNode3DImageViewData.contentItem = getContentItemForRendering(m_modelNode3DImageViewData.rootItem); m_modelNode3DImageViewData.contentItem = getContentItemForRendering(m_modelNode3DImageViewData.rootItem);
// Key number is selected so that it is unlikely to conflict other ImageContainer use.
auto imgContainer = ImageContainer(m_modelNodePreviewImageCommand.instanceId(), {}, 2100000001);
QImage renderImage;
if (m_modelNodePreviewImageCache.contains(m_modelNodePreviewImageCommand.componentPath())) { if (m_modelNodePreviewImageCache.contains(m_modelNodePreviewImageCommand.componentPath())) {
renderImage = m_modelNodePreviewImageCache[m_modelNodePreviewImageCommand.componentPath()]; m_modelNode3DImageViewAsyncData.renderImage
= m_modelNodePreviewImageCache[m_modelNodePreviewImageCommand.componentPath()];
modelNode3DImageViewSendImageToCreator();
} else { } else {
QObject *instanceObj = nullptr;
bool createdFromComponent = false;
ServerNodeInstance instance = instanceForId(m_modelNodePreviewImageCommand.instanceId()); ServerNodeInstance instance = instanceForId(m_modelNodePreviewImageCommand.instanceId());
if (!m_modelNodePreviewImageCommand.componentPath().isEmpty() if (!m_modelNodePreviewImageCommand.componentPath().isEmpty()
&& instance.isSubclassOf("QQuick3DNode")) { && instance.isSubclassOf("QQuick3DNode")) {
@@ -1018,14 +1017,15 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView()
// wouldn't want the children of the Node to appear in the preview. // wouldn't want the children of the Node to appear in the preview.
QQmlComponent component(engine()); QQmlComponent component(engine());
component.loadUrl(QUrl::fromLocalFile(m_modelNodePreviewImageCommand.componentPath())); component.loadUrl(QUrl::fromLocalFile(m_modelNodePreviewImageCommand.componentPath()));
instanceObj = qobject_cast<QQuick3DObject *>(component.create()); m_modelNode3DImageViewAsyncData.instanceObj = qobject_cast<QQuick3DObject *>(component.create());
if (!instanceObj) { if (!m_modelNode3DImageViewAsyncData.instanceObj) {
qWarning() << "Could not create preview component: " << component.errors(); qWarning() << "Could not create preview component: " << component.errors();
m_modelNode3DImageViewAsyncData.cleanup();
return; return;
} }
createdFromComponent = true; m_modelNode3DImageViewAsyncData.createdFromComponent = true;
} else { } else {
instanceObj = instance.internalObject(); m_modelNode3DImageViewAsyncData.instanceObj = instance.internalObject();
} }
QSize renderSize = m_modelNodePreviewImageCommand.size(); QSize renderSize = m_modelNodePreviewImageCommand.size();
if (Internal::QuickItemNodeInstance::unifiedRenderPathOrQt6()) { if (Internal::QuickItemNodeInstance::unifiedRenderPathOrQt6()) {
@@ -1044,16 +1044,43 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView()
m_modelNode3DImageViewData.window->resize(renderSize); m_modelNode3DImageViewData.window->resize(renderSize);
m_modelNode3DImageViewData.rootItem->setSize(renderSize); m_modelNode3DImageViewData.rootItem->setSize(renderSize);
QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "createViewForObject", QMetaObject::invokeMethod(
Q_ARG(QVariant, objectToVariant(instanceObj))); m_modelNode3DImageViewData.rootItem, "createViewForObject",
Q_ARG(QVariant, objectToVariant(m_modelNode3DImageViewAsyncData.instanceObj)));
// Selection box geometry updates have an asynchronous step, so we need to do rendering
// in asynchronous steps as well, since we are adjusting the selection box geometry
// while finding correct zoom level.
m_modelNode3DImageViewAsyncData.timer.start();
}
}
#endif
}
void Qt5InformationNodeInstanceServer::modelNode3DImageViewSendImageToCreator()
{
if (!m_modelNode3DImageViewAsyncData.renderImage.isNull()) {
// Key number is selected so that it is unlikely to conflict other ImageContainer use.
ImageContainer imgContainer(m_modelNodePreviewImageCommand.instanceId(), {}, 2100000001);
imgContainer.setImage(m_modelNode3DImageViewAsyncData.renderImage);
// send the rendered image to creator process
nodeInstanceClient()->handlePuppetToCreatorCommand(
{PuppetToCreatorCommand::RenderModelNodePreviewImage,
QVariant::fromValue(imgContainer)});
m_modelNode3DImageViewAsyncData.cleanup();
}
}
void Qt5InformationNodeInstanceServer::modelNode3DImageViewRenderStep()
{
++m_modelNode3DImageViewAsyncData.count;
bool ready = false;
int count = 0; // Ensure we don't ever get stuck in an infinite loop
while (!ready && ++count < 10) {
updateNodesRecursive(m_modelNode3DImageViewData.contentItem); updateNodesRecursive(m_modelNode3DImageViewData.contentItem);
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
if (Internal::QuickItemNodeInstance::unifiedRenderPath()) { if (Internal::QuickItemNodeInstance::unifiedRenderPath()) {
renderImage = m_modelNode3DImageViewData.window->grabWindow(); m_modelNode3DImageViewAsyncData.renderImage = m_modelNode3DImageViewData.window->grabWindow();
} else { } else {
// Fake render loop signaling to update things like QML items as 3D textures // Fake render loop signaling to update things like QML items as 3D textures
m_modelNode3DImageViewData.window->beforeSynchronizing(); m_modelNode3DImageViewData.window->beforeSynchronizing();
@@ -1061,34 +1088,27 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView()
QSizeF size = qobject_cast<QQuickItem *>(m_modelNode3DImageViewData.contentItem)->size(); QSizeF size = qobject_cast<QQuickItem *>(m_modelNode3DImageViewData.contentItem)->size();
QRectF renderRect(QPointF(0., 0.), size); QRectF renderRect(QPointF(0., 0.), size);
renderImage = designerSupport()->renderImageForItem(m_modelNode3DImageViewData.contentItem, m_modelNode3DImageViewAsyncData.renderImage
= designerSupport()->renderImageForItem(m_modelNode3DImageViewData.contentItem,
renderRect, size.toSize()); renderRect, size.toSize());
m_modelNode3DImageViewData.window->afterRendering(); m_modelNode3DImageViewData.window->afterRendering();
} }
#else #else
renderImage = grabRenderControl(m_modelNode3DImageViewData); m_modelNode3DImageViewAsyncData.renderImage = grabRenderControl(m_modelNode3DImageViewData);
#endif #endif
QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "afterRender"); QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "afterRender");
ready = QQmlProperty::read(m_modelNode3DImageViewData.rootItem, "ready").value<bool>(); const bool ready = QQmlProperty::read(m_modelNode3DImageViewData.rootItem, "ready").value<bool>();
} if (ready || m_modelNode3DImageViewAsyncData.count >= 10) {
QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "destroyView"); QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "destroyView");
if (createdFromComponent) { if (m_modelNode3DImageViewAsyncData.createdFromComponent) {
// If component changes, puppet will need a reset anyway, so we can cache the image // If component changes, puppet will need a reset anyway, so we can cache the image
m_modelNodePreviewImageCache.insert(m_modelNodePreviewImageCommand.componentPath(), renderImage); m_modelNodePreviewImageCache.insert(m_modelNodePreviewImageCommand.componentPath(),
delete instanceObj; m_modelNode3DImageViewAsyncData.renderImage);
} }
modelNode3DImageViewSendImageToCreator();
} else {
m_modelNode3DImageViewAsyncData.timer.start();
} }
if (!renderImage.isNull()) {
imgContainer.setImage(renderImage);
// send the rendered image to creator process
nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::RenderModelNodePreviewImage,
QVariant::fromValue(imgContainer)});
}
}
#endif
} }
static QRectF itemBoundingRect(QQuickItem *item) static QRectF itemBoundingRect(QQuickItem *item)
@@ -1205,6 +1225,7 @@ Qt5InformationNodeInstanceServer::Qt5InformationNodeInstanceServer(NodeInstanceC
m_render3DEditViewTimer.setSingleShot(true); m_render3DEditViewTimer.setSingleShot(true);
m_inputEventTimer.setSingleShot(true); m_inputEventTimer.setSingleShot(true);
m_renderModelNodeImageViewTimer.setSingleShot(true); m_renderModelNodeImageViewTimer.setSingleShot(true);
m_modelNode3DImageViewAsyncData.timer.setSingleShot(true);
#ifdef FPS_COUNTER #ifdef FPS_COUNTER
if (!_fpsTimer) { if (!_fpsTimer) {
@@ -1224,11 +1245,12 @@ Qt5InformationNodeInstanceServer::~Qt5InformationNodeInstanceServer()
{ {
m_editView3DSetupDone = false; m_editView3DSetupDone = false;
m_propertyChangeTimer.stop();
m_propertyChangeTimer.stop(); m_propertyChangeTimer.stop();
m_selectionChangeTimer.stop(); m_selectionChangeTimer.stop();
m_render3DEditViewTimer.stop(); m_render3DEditViewTimer.stop();
m_inputEventTimer.stop(); m_inputEventTimer.stop();
m_renderModelNodeImageViewTimer.stop();
m_modelNode3DImageViewAsyncData.timer.stop();
if (m_editView3DData.rootItem) if (m_editView3DData.rootItem)
m_editView3DData.rootItem->disconnect(this); m_editView3DData.rootItem->disconnect(this);
@@ -1621,6 +1643,8 @@ void Qt5InformationNodeInstanceServer::setup3DEditView(const QList<ServerNodeIns
this, &Qt5InformationNodeInstanceServer::doRender3DEditView); this, &Qt5InformationNodeInstanceServer::doRender3DEditView);
QObject::connect(&m_inputEventTimer, &QTimer::timeout, QObject::connect(&m_inputEventTimer, &QTimer::timeout,
this, &Qt5InformationNodeInstanceServer::handleInputEvents); this, &Qt5InformationNodeInstanceServer::handleInputEvents);
QObject::connect(&m_modelNode3DImageViewAsyncData.timer, &QTimer::timeout,
this, &Qt5InformationNodeInstanceServer::modelNode3DImageViewRenderStep);
QString lastSceneId; QString lastSceneId;
auto helper = qobject_cast<QmlDesigner::Internal::GeneralHelper *>(m_3dHelper); auto helper = qobject_cast<QmlDesigner::Internal::GeneralHelper *>(m_3dHelper);
@@ -2089,6 +2113,7 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c
void Qt5InformationNodeInstanceServer::requestModelNodePreviewImage(const RequestModelNodePreviewImageCommand &command) void Qt5InformationNodeInstanceServer::requestModelNodePreviewImage(const RequestModelNodePreviewImageCommand &command)
{ {
m_modelNode3DImageViewAsyncData.timer.stop();
m_modelNodePreviewImageCommand = command; m_modelNodePreviewImageCommand = command;
renderModelNodeImageView(); renderModelNodeImageView();
} }

View File

@@ -138,6 +138,8 @@ private:
void renderModelNodeImageView(); void renderModelNodeImageView();
void doRenderModelNodeImageView(); void doRenderModelNodeImageView();
void doRenderModelNode3DImageView(); void doRenderModelNode3DImageView();
void modelNode3DImageViewSendImageToCreator();
void modelNode3DImageViewRenderStep();
void doRenderModelNode2DImageView(); void doRenderModelNode2DImageView();
void updateLockedAndHiddenStates(const QSet<ServerNodeInstance> &instances); void updateLockedAndHiddenStates(const QSet<ServerNodeInstance> &instances);
void handleInputEvents(); void handleInputEvents();
@@ -184,6 +186,26 @@ private:
QList<InputEventCommand> m_pendingInputEventCommands; QList<InputEventCommand> m_pendingInputEventCommands;
QObject *m_3dHelper = nullptr; QObject *m_3dHelper = nullptr;
int m_need3DEditViewRender = 0; int m_need3DEditViewRender = 0;
struct ModelNode3DImageViewAsyncData {
QTimer timer;
QImage renderImage;
int count = 0;
bool createdFromComponent = false;
QObject *instanceObj = nullptr;
void cleanup()
{
timer.stop();
count = 0;
renderImage = {};
if (createdFromComponent)
delete instanceObj;
instanceObj = nullptr;
createdFromComponent = false;
}
};
ModelNode3DImageViewAsyncData m_modelNode3DImageViewAsyncData;
}; };
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -417,7 +417,7 @@ QImage Qt5NodeInstanceServer::grabItem(QQuickItem *item)
if (instance.isValid()) if (instance.isValid())
renderBoundingRect = instance.boundingRect(); renderBoundingRect = instance.boundingRect();
else else
renderBoundingRect = item->boundingRect(); renderBoundingRect = ServerNodeInstance::effectAdjustedBoundingRect(item);
// Hide immediate children that have instances and are QQuickItems so we get only // Hide immediate children that have instances and are QQuickItems so we get only
// the parent item's content, as compositing is handled on creator side. // the parent item's content, as compositing is handled on creator side.

View File

@@ -329,11 +329,23 @@ QRectF QuickItemNodeInstance::contentItemBoundingBox() const
return QRectF(); return QRectF();
} }
static bool layerEnabledAndEffect(QQuickItem *item)
{
QQuickItemPrivate *pItem = QQuickItemPrivate::get(item);
if (pItem && pItem->layer() && pItem->layer()->enabled() && pItem->layer()->effect())
return true;
return false;
}
QRectF QuickItemNodeInstance::boundingRect() const QRectF QuickItemNodeInstance::boundingRect() const
{ {
if (quickItem()) { if (quickItem()) {
if (quickItem()->clip()) { if (quickItem()->clip()) {
return quickItem()->boundingRect(); return quickItem()->boundingRect();
} else if (layerEnabledAndEffect(quickItem())) {
return ServerNodeInstance::effectAdjustedBoundingRect(quickItem());
} else { } else {
QSize maximumSize(4000, 4000); QSize maximumSize(4000, 4000);
auto isValidSize = [maximumSize] (const QRectF& rect) { auto isValidSize = [maximumSize] (const QRectF& rect) {

View File

@@ -135,6 +135,13 @@ bool ServerNodeInstance::isSubclassOf(QObject *object, const QByteArray &superTy
return Internal::QmlPrivateGate::isSubclassOf(object, superTypeName); return Internal::QmlPrivateGate::isSubclassOf(object, superTypeName);
} }
QRectF ServerNodeInstance::effectAdjustedBoundingRect(QQuickItem *item)
{
if (item)
return item->boundingRect().adjusted(-40, -40, 40, 40);
return {};
}
void ServerNodeInstance::setModifiedFlag(bool b) void ServerNodeInstance::setModifiedFlag(bool b)
{ {
m_nodeInstance->setModifiedFlag(b); m_nodeInstance->setModifiedFlag(b);

View File

@@ -180,6 +180,7 @@ public:
QStringList allStates() const; QStringList allStates() const;
static bool isSubclassOf(QObject *object, const QByteArray &superTypeName); static bool isSubclassOf(QObject *object, const QByteArray &superTypeName);
static QRectF effectAdjustedBoundingRect(QQuickItem *item);
void setModifiedFlag(bool b); void setModifiedFlag(bool b);
void updateDirtyNodeRecursive(); void updateDirtyNodeRecursive();

View File

@@ -57,7 +57,7 @@ QtObject {
readonly property string darkPaneColor: StudioTheme.Values.themeBackgroundColorNormal readonly property string darkPaneColor: StudioTheme.Values.themeBackgroundColorNormal
readonly property string lightPaneColor: StudioTheme.Values.themeBackgroundColorAlternate readonly property string lightPaneColor: StudioTheme.Values.themeBackgroundColorAlternate
readonly property string textColor: StudioTheme.Values.themeTabInactiveText readonly property string textColor: StudioTheme.Values.themeTextColor
readonly property string textColorInteraction: StudioTheme.Values.themeInteraction readonly property string textColorInteraction: StudioTheme.Values.themeInteraction
readonly property string dividerlineColor: StudioTheme.Values.themeTextColorDisabled readonly property string dividerlineColor: StudioTheme.Values.themeTextColorDisabled
readonly property string textError: StudioTheme.Values.themeError readonly property string textError: StudioTheme.Values.themeError

View File

@@ -35,67 +35,58 @@ GridView {
required property Item loader required property Item loader
header: TabBar { readonly property int animDur: 500
id: tabBar
header: Rectangle {
width: parent.width width: parent.width
height: DialogValues.projectViewHeaderHeight height: DialogValues.projectViewHeaderHeight
background: Rectangle {
color: DialogValues.lightPaneColor color: DialogValues.lightPaneColor
}
Row {
id: row
spacing: 20
property int currIndex: 0
Repeater { Repeater {
model: categoryModel model: categoryModel
TabButton {
padding: 0
width: headerText.contentWidth + 36
background: Item { // TabButton background
Rectangle { // bottom strip
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
width: headerText.contentWidth
height: 6
radius: 10
color: tabBar.currentIndex === index ? DialogValues.textColorInteraction
: "transparent"
}
} // TabButton background
implicitHeight: headerText.height + DialogValues.defaultPadding - 7
contentItem: Item {
Column {
anchors.fill: parent
Text { Text {
id: headerText
color: tabBar.currentIndex == index ? DialogValues.textColorInteraction
: DialogValues.textColor
text: name text: name
width: parent.width
font.weight: Font.DemiBold font.weight: Font.DemiBold
font.pixelSize: DialogValues.viewHeaderPixelSize font.pixelSize: DialogValues.viewHeaderPixelSize
lineHeight: DialogValues.viewHeaderLineHeight
lineHeightMode: Text.FixedHeight
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
} color: row.currIndex === index ? DialogValues.textColorInteraction
: DialogValues.textColor
Item { width: parent.width; height: 11; } Behavior on color { ColorAnimation { duration: animDur } }
} // Column
} // Item
MouseArea {
anchors.fill: parent
onClicked: { onClicked: {
row.currIndex = index
projectModel.setPage(index) projectModel.setPage(index)
projectView.currentIndex = 0 projectView.currentIndex = 0
projectView.currentIndexChanged() projectView.currentIndexChanged()
strip.x = parent.x
strip.width = parent.width
} }
} // TabButton }
} // Text
} // Repeater } // Repeater
} // Header - TabBar } // Row
Rectangle {
id: strip
width: row.children[0].width
height: 5
radius: 2
color: DialogValues.textColorInteraction
anchors.bottom: parent.bottom
Behavior on x { SmoothedAnimation { duration: animDur } }
Behavior on width { SmoothedAnimation { duration: strip.width === 0 ? 0 : animDur } } // do not animate initial width
}
} // Rectangle
cellWidth: DialogValues.projectItemWidth cellWidth: DialogValues.projectItemWidth
cellHeight: DialogValues.projectItemHeight cellHeight: DialogValues.projectItemHeight

View File

@@ -110,7 +110,7 @@ DStitleBarIcon=ffffffff
DStitleBarButtonHover=40ffffff DStitleBarButtonHover=40ffffff
DStitleBarButtonPress=60ffffff DStitleBarButtonPress=60ffffff
DStabContainerBackground=ff0000ff DStabContainerBackground=ff1f1f1f
DStabSplitter=ff595959 DStabSplitter=ff595959
DStabInactiveBackground=ff1f1f1f DStabInactiveBackground=ff1f1f1f

View File

@@ -101,7 +101,7 @@ DStitleBarIcon=ff4f5052
DStitleBarButtonHover=40ffffff DStitleBarButtonHover=40ffffff
DStitleBarButtonPress=60ffffff DStitleBarButtonPress=60ffffff
DStabContainerBackground=ff0000ff DStabContainerBackground=ff999999
DStabSplitter=ff595959 DStabSplitter=ff595959
DStabInactiveBackground=ff999999 DStabInactiveBackground=ff999999

View File

@@ -115,7 +115,7 @@ DStitleBarIcon=ff4f5052
DStitleBarButtonHover=40ffffff DStitleBarButtonHover=40ffffff
DStitleBarButtonPress=60ffffff DStitleBarButtonPress=60ffffff
DStabContainerBackground=ff0000ff DStabContainerBackground=ffdadada
DStabSplitter=ff595959 DStabSplitter=ff595959
DStabInactiveBackground=ff999999 DStabInactiveBackground=ff999999

View File

@@ -112,7 +112,7 @@ DStitleBarIcon=ffffffff
DStitleBarButtonHover=40ffffff DStitleBarButtonHover=40ffffff
DStitleBarButtonPress=60ffffff DStitleBarButtonPress=60ffffff
DStabContainerBackground=ff0000ff DStabContainerBackground=ff1f1f1f
DStabSplitter=ff595959 DStabSplitter=ff595959
DStabInactiveBackground=ff1f1f1f DStabInactiveBackground=ff1f1f1f

View File

@@ -114,7 +114,7 @@ DStitleBarIcon=ffffffff
DStitleBarButtonHover=40ffffff DStitleBarButtonHover=40ffffff
DStitleBarButtonPress=60ffffff DStitleBarButtonPress=60ffffff
DStabContainerBackground=ff0000ff DStabContainerBackground=ff1f1f1f
DStabSplitter=ff595959 DStabSplitter=ff595959
DStabInactiveBackground=ff1f1f1f DStabInactiveBackground=ff1f1f1f

View File

@@ -110,7 +110,7 @@ DStitleBarIcon=ff4f5052
DStitleBarButtonHover=40ffffff DStitleBarButtonHover=40ffffff
DStitleBarButtonPress=60ffffff DStitleBarButtonPress=60ffffff
DStabContainerBackground=ff0000ff DStabContainerBackground=ffdadada
DStabSplitter=ff595959 DStabSplitter=ff595959
DStabInactiveBackground=ff999999 DStabInactiveBackground=ff999999

View File

@@ -31,6 +31,7 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/qlitehtml/src/CMakeLists.txt)
set(QLITEHTML_DEVEL_EXCLUDE_FROM_ALL ON) set(QLITEHTML_DEVEL_EXCLUDE_FROM_ALL ON)
set(QLITEHTML_HEADER_PATH "${IDE_HEADER_INSTALL_PATH}/src/lib/qlitehtml") set(QLITEHTML_HEADER_PATH "${IDE_HEADER_INSTALL_PATH}/src/lib/qlitehtml")
set(QT_VERSION_MAJOR ${Qt5_VERSION_MAJOR}) set(QT_VERSION_MAJOR ${Qt5_VERSION_MAJOR})
set(BUILD_TESTING OFF) # otherwise litehtml downloads googletest
add_subdirectory(qlitehtml/src) add_subdirectory(qlitehtml/src)
endif() endif()
if(TARGET qlitehtml) if(TARGET qlitehtml)

View File

@@ -31,6 +31,13 @@
#include <QThread> #include <QThread>
#include <QTimer> #include <QTimer>
#ifdef Q_OS_WIN
#ifdef QTCREATOR_PCH_H
#define CALLBACK WINAPI
#endif
#include <qt_windows.h>
#endif
using namespace Utils; using namespace Utils;
namespace Utils { namespace Utils {
@@ -83,6 +90,26 @@ bool Reaper::isFinished() const
return !m_process; return !m_process;
} }
#ifdef Q_OS_WIN
static BOOL sendMessage(UINT message, HWND hwnd, LPARAM lParam)
{
DWORD dwProcessID;
GetWindowThreadProcessId(hwnd, &dwProcessID);
if ((DWORD)lParam == dwProcessID) {
SendNotifyMessage(hwnd, message, 0, 0);
return FALSE;
}
return TRUE;
}
BOOL CALLBACK sendShutDownMessageToAllWindowsOfProcess_enumWnd(HWND hwnd, LPARAM lParam)
{
static UINT uiShutDownMessage = RegisterWindowMessage(L"qtcctrlcstub_shutdown");
return sendMessage(uiShutDownMessage, hwnd, lParam);
}
#endif
void Reaper::nextIteration() void Reaper::nextIteration()
{ {
QProcess::ProcessState state = m_process ? m_process->state() : QProcess::NotRunning; QProcess::ProcessState state = m_process ? m_process->state() : QProcess::NotRunning;
@@ -96,11 +123,16 @@ void Reaper::nextIteration()
if (m_lastState == QProcess::Starting) if (m_lastState == QProcess::Starting)
m_process->kill(); m_process->kill();
} else if (state == QProcess::Running) { } else if (state == QProcess::Running) {
if (m_lastState == QProcess::Running) if (m_lastState == QProcess::Running) {
m_process->kill(); m_process->kill();
else } else if (m_process->program().endsWith(QLatin1String("qtcreator_ctrlc_stub.exe"))) {
#ifdef Q_OS_WIN
EnumWindows(sendShutDownMessageToAllWindowsOfProcess_enumWnd, m_process->processId());
#endif
} else {
m_process->terminate(); m_process->terminate();
} }
}
m_lastState = state; m_lastState = state;
m_iterationTimer.start(); m_iterationTimer.start();
@@ -149,10 +181,7 @@ void ProcessReaper::reap(QProcess *process, int timeoutMs)
if (process->state() == QProcess::NotRunning) { if (process->state() == QProcess::NotRunning) {
process->deleteLater(); process->deleteLater();
return; return;
} else {
process->kill();
} }
// Neither can move object with a parent into a different thread // Neither can move object with a parent into a different thread
// nor reaping the process with a parent makes any sense. // nor reaping the process with a parent makes any sense.
process->setParent(nullptr); process->setParent(nullptr);

View File

@@ -3703,7 +3703,13 @@ void ExtraHighlightingResultsCollector::visitNode(const AstNode &node)
bool ClangdClient::FollowSymbolData::defLinkIsAmbiguous() const bool ClangdClient::FollowSymbolData::defLinkIsAmbiguous() const
{ {
// If we have up-to-date highlighting info, we can give a definite answer. // Even if the call is to a virtual function, it might not be ambiguous:
// class A { virtual void f(); }; class B : public A { void f() override { A::f(); } };
if (!cursorNode->mightBeAmbiguousVirtualCall() && !cursorNode->isPureVirtualDeclaration())
return false;
// If we have up-to-date highlighting info, we know whether we are dealing with
// a virtual call.
if (editorWidget) { if (editorWidget) {
const auto virtualRanges = q->d->virtualRanges.constFind(editorWidget->textDocument()); const auto virtualRanges = q->d->virtualRanges.constFind(editorWidget->textDocument());
if (virtualRanges != q->d->virtualRanges.constEnd() if (virtualRanges != q->d->virtualRanges.constEnd()
@@ -3715,8 +3721,9 @@ bool ClangdClient::FollowSymbolData::defLinkIsAmbiguous() const
} }
} }
// Otherwise, we have to rely on AST-based heuristics. // Otherwise, we accept potentially doing more work than needed rather than not catching
return cursorNode->mightBeAmbiguousVirtualCall() || cursorNode->isPureVirtualDeclaration(); // possible overrides.
return true;
} }
class MemoryTree : public JsonObject class MemoryTree : public JsonObject

View File

@@ -149,6 +149,7 @@ void CMakeManager::updateCmakeActions(Node *node)
auto project = qobject_cast<CMakeProject *>(SessionManager::startupProject()); auto project = qobject_cast<CMakeProject *>(SessionManager::startupProject());
const bool visible = project && !BuildManager::isBuilding(project); const bool visible = project && !BuildManager::isBuilding(project);
m_runCMakeAction->setVisible(visible); m_runCMakeAction->setVisible(visible);
m_runCMakeActionContextMenu->setEnabled(visible);
m_clearCMakeCacheAction->setVisible(visible); m_clearCMakeCacheAction->setVisible(visible);
m_rescanProjectAction->setVisible(visible); m_rescanProjectAction->setVisible(visible);
enableBuildFileMenus(node); enableBuildFileMenus(node);

View File

@@ -607,7 +607,7 @@ QList<IDocument *> DocumentManager::modifiedDocuments()
} }
/*! /*!
Treats any subsequent change to \a fileName as an expected file change. Treats any subsequent change to \a filePath as an expected file change.
\sa unexpectFileChange() \sa unexpectFileChange()
*/ */
@@ -631,7 +631,7 @@ static void updateExpectedState(const FilePath &filePathKey)
} }
/*! /*!
Considers all changes to \a fileName unexpected again. Considers all changes to \a filePath unexpected again.
\sa expectFileChange() \sa expectFileChange()
*/ */

View File

@@ -258,29 +258,13 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *)
*/ */
/*! /*!
\class EditorManager::FilePathInfo \fn void Core::EditorManager::currentEditorChanged(Core::IEditor *editor)
\inheaderfile coreplugin/editormanager/editormanager.h
\inmodule QtCreator
\brief The FilePathInfo class contains information about a file path's
special segments.
File names can have an additional postfix, optionally specifying a line and
column number, when opening a file in \QC from the command line or locator.
The FilePathInfo class contains the file name, the complete postfix string,
and the parsed line and column numbers.
\sa EditorManager::splitLineAndColumnNumber()
*/
/*!
\fn void EditorManager::currentEditorChanged(IEditor *editor)
This signal is emitted after the current editor changed to \a editor. This signal is emitted after the current editor changed to \a editor.
*/ */
/*! /*!
\fn void EditorManager::currentDocumentStateChanged() \fn void Core::EditorManager::currentDocumentStateChanged()
This signal is emitted when the meta data of the current document, for This signal is emitted when the meta data of the current document, for
example file name or modified state, changed. example file name or modified state, changed.
@@ -289,7 +273,7 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *)
*/ */
/*! /*!
\fn void EditorManager::documentStateChanged(IDocument *document) \fn void Core::EditorManager::documentStateChanged(Core::IDocument *document)
This signal is emitted when the meta data of the \a document, for This signal is emitted when the meta data of the \a document, for
example file name or modified state, changed. example file name or modified state, changed.
@@ -298,13 +282,13 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *)
*/ */
/*! /*!
\fn void EditorManager::editorCreated(IEditor *editor, const QString &fileName) \fn void Core::EditorManager::editorCreated(Core::IEditor *editor, const QString &fileName)
This signal is emitted after an \a editor was created for \a fileName, but This signal is emitted after an \a editor was created for \a fileName, but
before it was opened in an editor view. before it was opened in an editor view.
*/ */
/*! /*!
\fn void EditorManager::editorOpened(IEditor *editor) \fn void Core::EditorManager::editorOpened(Core::IEditor *editor)
This signal is emitted after a new \a editor was opened in an editor view. This signal is emitted after a new \a editor was opened in an editor view.
@@ -312,14 +296,14 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *)
*/ */
/*! /*!
\fn void EditorManager::documentOpened(IDocument *document) \fn void Core::EditorManager::documentOpened(Core::IDocument *document)
This signal is emitted after the first editor for \a document opened in an This signal is emitted after the first editor for \a document opened in an
editor view. editor view.
*/ */
/*! /*!
\fn void EditorManager::editorAboutToClose(IEditor *editor) \fn void Core::EditorManager::editorAboutToClose(Core::IEditor *editor)
This signal is emitted before \a editor is closed. This can be used to free This signal is emitted before \a editor is closed. This can be used to free
resources that were allocated for the editor separately from the editor resources that were allocated for the editor separately from the editor
@@ -332,7 +316,7 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *)
*/ */
/*! /*!
\fn void EditorManager::editorsClosed(QList<IEditor *> editors) \fn void Core::EditorManager::editorsClosed(QList<Core::IEditor *> editors)
This signal is emitted after the \a editors closed, but before they are This signal is emitted after the \a editors closed, but before they are
deleted. deleted.
@@ -341,7 +325,7 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *)
*/ */
/*! /*!
\fn void EditorManager::documentClosed(IDocument *document) \fn void Core::EditorManager::documentClosed(Core::IDocument *document)
This signal is emitted after the \a document closed, but before it is deleted. This signal is emitted after the \a document closed, but before it is deleted.
*/ */
@@ -351,22 +335,22 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *)
\internal \internal
*/ */
/*! /*!
\fn void EditorManager::aboutToSave(IDocument *document) \fn void Core::EditorManager::aboutToSave(Core::IDocument *document)
This signal is emitted before the \a document is saved. This signal is emitted before the \a document is saved.
*/ */
/*! /*!
\fn void EditorManager::saved(IDocument *document) \fn void Core::EditorManager::saved(Core::IDocument *document)
This signal is emitted after the \a document was saved. This signal is emitted after the \a document was saved.
*/ */
/*! /*!
\fn void EditorManager::autoSaved() \fn void Core::EditorManager::autoSaved()
This signal is emitted after auto-save was triggered. This signal is emitted after auto-save was triggered.
*/ */
/*! /*!
\fn void EditorManager::currentEditorAboutToChange(IEditor *editor) \fn void Core::EditorManager::currentEditorAboutToChange(Core::IEditor *editor)
This signal is emitted before the current editor changes to \a editor. This signal is emitted before the current editor changes to \a editor.
*/ */
@@ -3092,10 +3076,10 @@ IEditor *EditorManager::openEditor(const FilePath &filePath, Id editorId,
} }
/*! /*!
Opens the document specified by \a filePath using the editor type \a Opens the document specified by \a link using the editor type \a
editorId and the specified \a flags. editorId and the specified \a flags.
Moves the text cursor to the \a line and \a column. Moves the text cursor to the \e line and \e column specified in \a link.
If \a editorId is \c Id(), the editor type is derived from the file's MIME If \a editorId is \c Id(), the editor type is derived from the file's MIME
type. type.
@@ -3157,7 +3141,7 @@ void EditorManager::openEditorAtSearchResult(const SearchResultItem &item,
} }
/*! /*!
Returns whether \a fileName is an auto-save file created by \QC. Returns whether \a filePath is an auto-save file created by \QC.
*/ */
bool EditorManager::isAutoSaveFile(const QString &filePath) bool EditorManager::isAutoSaveFile(const QString &filePath)
{ {
@@ -3209,7 +3193,7 @@ void EditorManager::addCloseEditorListener(const std::function<bool (IEditor *)>
/*! /*!
Asks the user for a list of files to open and returns the choice. Asks the user for a list of files to open and returns the choice.
\sa DocumentManager::getOpenFilePaths() \sa DocumentManager::getOpenFileNames()
*/ */
FilePaths EditorManager::getOpenFilePaths() FilePaths EditorManager::getOpenFilePaths()
{ {

View File

@@ -162,7 +162,7 @@ const EditorFactoryList IEditorFactory::defaultEditorFactories(const Utils::Mime
} }
/*! /*!
Returns the available editor factories for \a fileName in order of Returns the available editor factories for \a filePath in order of
preference. That is the default order for the document's MIME type but with preference. That is the default order for the document's MIME type but with
a user overridden default editor first, and the binary editor as the very a user overridden default editor first, and the binary editor as the very
first item if a text document is too large to be opened as a text file. first item if a text document is too large to be opened as a text file.

View File

@@ -55,8 +55,7 @@ namespace Core {
*/ */
/*! /*!
\fn bool Core::IExternalEditor::startEditor(const Utils::FilePath &fileName, QString *errorMessage)
\fn bool Core::IExternalEditor::startEditor(const QString &fileName, QString *errorMessage) = 0;
Opens the editor with \a fileName. Returns \c true on success or \c false Opens the editor with \a fileName. Returns \c true on success or \c false
on failure along with the error in \a errorMessage. on failure along with the error in \a errorMessage.

View File

@@ -186,7 +186,7 @@ QIcon FileIconProviderImplementation::icon(const FilePath &filePath) const
} }
/*! /*!
Returns the icon associated with the file suffix in \a info. If there is none, Returns the icon associated with the file suffix in \a filePath. If there is none,
the default icon of the operating system is returned. the default icon of the operating system is returned.
*/ */

View File

@@ -859,7 +859,7 @@ void SearchResult::setTextToReplace(const QString &textToReplace)
} }
/*! /*!
Sets whether replace is enabled and can be triggered by the user Sets whether replace is \a enabled and can be triggered by the user.
*/ */
void SearchResult::setReplaceEnabled(bool enabled) void SearchResult::setReplaceEnabled(bool enabled)
{ {

View File

@@ -426,7 +426,7 @@ static QString pathHelper(const QString &rel)
return '/' + rel; return '/' + rel;
} }
/*! /*!
Returns the absolute path that is used for resources like Returns the absolute path for the relative path \a rel that is used for resources like
project templates and the debugger macros. project templates and the debugger macros.
This abstraction is needed to avoid platform-specific code all over This abstraction is needed to avoid platform-specific code all over
@@ -443,7 +443,7 @@ FilePath ICore::resourcePath(const QString &rel)
} }
/*! /*!
Returns the absolute path in the users directory that is used for Returns the absolute path for the relative path \a rel in the users directory that is used for
resources like project templates. resources like project templates.
Use this function for finding the place for resources that the user may Use this function for finding the place for resources that the user may
@@ -468,7 +468,7 @@ FilePath ICore::userResourcePath(const QString &rel)
} }
/*! /*!
Returns a writable path that can be used for persistent cache files. Returns a writable path for the relative path \a rel that can be used for persistent cache files.
*/ */
FilePath ICore::cacheResourcePath(const QString &rel) FilePath ICore::cacheResourcePath(const QString &rel)
{ {
@@ -477,8 +477,8 @@ FilePath ICore::cacheResourcePath(const QString &rel)
} }
/*! /*!
Returns the path to resources written by the installer, for example Returns the path, based on the relative path \a rel, to resources written by the installer,
pre-defined kits and toolchains. for example pre-defined kits and toolchains.
*/ */
FilePath ICore::installerResourcePath(const QString &rel) FilePath ICore::installerResourcePath(const QString &rel)
{ {
@@ -516,8 +516,8 @@ QString ICore::userPluginPath()
} }
/*! /*!
Returns the path to the command line tools that are included in the \QC Returns the path, based on the relative path \a rel, to the command line tools that are
installation. included in the \QC installation.
*/ */
FilePath ICore::libexecPath(const QString &rel) FilePath ICore::libexecPath(const QString &rel)
{ {

View File

@@ -61,11 +61,11 @@
*/ */
/*! /*!
\fn Core::IVersionControl::TopicCache::trackFile(const QString &repository) \fn Utils::FilePath Core::IVersionControl::TopicCache::trackFile(const Utils::FilePath &repository)
Returns the path to the file that invalidates the cache for \a repository when Returns the path to the file that invalidates the cache for \a repository when
the file is modified. the file is modified.
\fn Core::IVersionControl::TopicCache::refreshTopic(const QString &repository) \fn QString Core::IVersionControl::TopicCache::refreshTopic(const Utils::FilePath &repository)
Returns the current topic for \a repository. Returns the current topic for \a repository.
*/ */

View File

@@ -180,7 +180,7 @@ static QString defaultCommand()
return "locate"; return "locate";
} }
/*! /*
For the tools es [1] and locate [2], interpret space as AND operator. For the tools es [1] and locate [2], interpret space as AND operator.
Currently doesn't support fine picking a file with a space in the path by escaped space. Currently doesn't support fine picking a file with a space in the path by escaped space.

View File

@@ -81,6 +81,7 @@ public:
} }
} }
Range range() const { return m_range; }
Position pos() const { return m_range.start(); } Position pos() const { return m_range.start(); }
bool contains(const Position &pos) const { return m_range.contains(pos); } bool contains(const Position &pos) const { return m_range.contains(pos); }
@@ -345,8 +346,14 @@ void OutlineComboBox::updateModel(const DocumentUri &resultUri, const DocumentSy
void OutlineComboBox::updateEntry() void OutlineComboBox::updateEntry()
{ {
const Position pos(m_editorWidget->textCursor()); const Position pos(m_editorWidget->textCursor());
LanguageClientOutlineItem *itemForCursor = m_model.findNonRootItem( LanguageClientOutlineItem *itemForCursor = nullptr;
[&](const LanguageClientOutlineItem *item) { return item->contains(pos); }); m_model.forAllItems([&](LanguageClientOutlineItem *candidate){
if (!candidate->contains(pos))
return;
if (itemForCursor && candidate->range().contains(itemForCursor->range()))
return; // skip item if the range is equal or bigger than the previous found range
itemForCursor = candidate;
});
if (itemForCursor) if (itemForCursor)
setCurrentIndex(m_model.indexForItem(itemForCursor)); setCurrentIndex(m_model.indexForItem(itemForCursor));
} }

View File

@@ -60,6 +60,7 @@ SemanticTokenSupport::SemanticTokenSupport(Client *client)
void SemanticTokenSupport::refresh() void SemanticTokenSupport::refresh()
{ {
qCDebug(LOGLSPHIGHLIGHT) << "refresh all semantic highlights for" << m_client->name();
m_tokens.clear(); m_tokens.clear();
for (Core::IEditor *editor : Core::EditorManager::visibleEditors()) for (Core::IEditor *editor : Core::EditorManager::visibleEditors())
onCurrentEditorChanged(editor); onCurrentEditorChanged(editor);
@@ -95,6 +96,8 @@ void SemanticTokenSupport::reloadSemanticTokens(TextDocument *textDocument)
params.setTextDocument(docId); params.setTextDocument(docId);
SemanticTokensFullRequest request(params); SemanticTokensFullRequest request(params);
request.setResponseCallback(responseCallback); request.setResponseCallback(responseCallback);
qCDebug(LOGLSPHIGHLIGHT) << "Requesting all tokens for" << filePath << "with version"
<< m_client->documentVersion(filePath);
m_client->sendContent(request); m_client->sendContent(request);
} }
} }
@@ -107,19 +110,22 @@ void SemanticTokenSupport::updateSemanticTokens(TextDocument *textDocument)
const VersionedTokens versionedToken = m_tokens.value(filePath); const VersionedTokens versionedToken = m_tokens.value(filePath);
const QString &previousResultId = versionedToken.tokens.resultId().value_or(QString()); const QString &previousResultId = versionedToken.tokens.resultId().value_or(QString());
if (!previousResultId.isEmpty()) { if (!previousResultId.isEmpty()) {
if (m_client->documentVersion(filePath) == versionedToken.version) const int documentVersion = m_client->documentVersion(filePath);
if (documentVersion == versionedToken.version)
return; return;
SemanticTokensDeltaParams params; SemanticTokensDeltaParams params;
params.setTextDocument(TextDocumentIdentifier(DocumentUri::fromFilePath(filePath))); params.setTextDocument(TextDocumentIdentifier(DocumentUri::fromFilePath(filePath)));
params.setPreviousResultId(previousResultId); params.setPreviousResultId(previousResultId);
SemanticTokensFullDeltaRequest request(params); SemanticTokensFullDeltaRequest request(params);
request.setResponseCallback( request.setResponseCallback(
[this, filePath, documentVersion = m_client->documentVersion(filePath)]( [this, filePath, documentVersion](
const SemanticTokensFullDeltaRequest::Response &response) { const SemanticTokensFullDeltaRequest::Response &response) {
handleSemanticTokensDelta(filePath, handleSemanticTokensDelta(filePath,
response.result().value_or(nullptr), response.result().value_or(nullptr),
documentVersion); documentVersion);
}); });
qCDebug(LOGLSPHIGHLIGHT)
<< "Requesting delta for" << filePath << "with version" << documentVersion;
m_client->sendContent(request); m_client->sendContent(request);
return; return;
} }
@@ -288,8 +294,10 @@ void SemanticTokenSupport::handleSemanticTokensDelta(
const LanguageServerProtocol::SemanticTokensDeltaResult &result, const LanguageServerProtocol::SemanticTokensDeltaResult &result,
int documentVersion) int documentVersion)
{ {
qCDebug(LOGLSPHIGHLIGHT) << "Handle Tokens for " << filePath;
if (auto tokens = Utils::get_if<SemanticTokens>(&result)) { if (auto tokens = Utils::get_if<SemanticTokens>(&result)) {
m_tokens[filePath] = {*tokens, documentVersion}; m_tokens[filePath] = {*tokens, documentVersion};
qCDebug(LOGLSPHIGHLIGHT) << "New Data " << tokens->data();
} else if (auto tokensDelta = Utils::get_if<SemanticTokensDelta>(&result)) { } else if (auto tokensDelta = Utils::get_if<SemanticTokensDelta>(&result)) {
m_tokens[filePath].version = documentVersion; m_tokens[filePath].version = documentVersion;
QList<SemanticTokensEdit> edits = tokensDelta->edits(); QList<SemanticTokensEdit> edits = tokensDelta->edits();
@@ -311,7 +319,7 @@ void SemanticTokenSupport::handleSemanticTokensDelta(
auto it = data.begin(); auto it = data.begin();
const auto end = data.end(); const auto end = data.end();
qCDebug(LOGLSPHIGHLIGHT) << "Edit Tokens for " << filePath; qCDebug(LOGLSPHIGHLIGHT) << "Edit Tokens";
qCDebug(LOGLSPHIGHLIGHT) << "Data before edit " << data; qCDebug(LOGLSPHIGHLIGHT) << "Data before edit " << data;
for (const SemanticTokensEdit &edit : qAsConst(edits)) { for (const SemanticTokensEdit &edit : qAsConst(edits)) {
if (edit.start() > data.size()) // prevent edits after the previously reported data if (edit.start() > data.size()) // prevent edits after the previously reported data
@@ -346,6 +354,7 @@ void SemanticTokenSupport::handleSemanticTokensDelta(
tokens.setResultId(tokensDelta->resultId()); tokens.setResultId(tokensDelta->resultId());
} else { } else {
m_tokens.remove(filePath); m_tokens.remove(filePath);
qCDebug(LOGLSPHIGHLIGHT) << "Data cleared";
return; return;
} }
highlight(filePath); highlight(filePath);
@@ -353,6 +362,7 @@ void SemanticTokenSupport::handleSemanticTokensDelta(
void SemanticTokenSupport::highlight(const Utils::FilePath &filePath, bool force) void SemanticTokenSupport::highlight(const Utils::FilePath &filePath, bool force)
{ {
qCDebug(LOGLSPHIGHLIGHT) << "highlight" << filePath;
TextDocument *doc = TextDocument::textDocumentForFilePath(filePath); TextDocument *doc = TextDocument::textDocumentForFilePath(filePath);
if (!doc || LanguageClientManager::clientForDocument(doc) != m_client) if (!doc || LanguageClientManager::clientForDocument(doc) != m_client)
return; return;
@@ -363,6 +373,7 @@ void SemanticTokenSupport::highlight(const Utils::FilePath &filePath, bool force
const QList<SemanticToken> tokens = versionedTokens.tokens const QList<SemanticToken> tokens = versionedTokens.tokens
.toTokens(m_tokenTypes, m_tokenModifiers); .toTokens(m_tokenTypes, m_tokenModifiers);
if (m_tokensHandler) { if (m_tokensHandler) {
qCDebug(LOGLSPHIGHLIGHT) << "use tokens handler" << filePath;
int line = 1; int line = 1;
int column = 1; int column = 1;
QList<ExpandedSemanticToken> expandedTokens; QList<ExpandedSemanticToken> expandedTokens;

View File

@@ -50,8 +50,8 @@ static const QHash<QString, QString> &envVarToCMakeVarMapping()
{"IMXRT595_FREERTOS_DIR","FREERTOS_DIR"}, {"IMXRT595_FREERTOS_DIR","FREERTOS_DIR"},
{"STM32F7_FREERTOS_DIR", "FREERTOS_DIR"}, {"STM32F7_FREERTOS_DIR", "FREERTOS_DIR"},
{"eFlashLoad_PATH","eFlashLoad_PATH"}, {"eFlashLoad_PATH","eFlashLoad_PATH"},
{"RenesasFlashProgrammer_PATH", "RenesasFlashProgrammer_PATH"}, {"RenesasFlashProgrammer_PATH", "RENESAS_FLASH_PROGRAMMER_PATH"},
{"MCUXpressoIDE_PATH", "MCUXpressoIDE_PATH"}, {"MCUXpressoIDE_PATH", "MCUXPRESSO_IDE_PATH"},
{"JLINK_PATH", "JLINK_PATH"}, {"JLINK_PATH", "JLINK_PATH"},
{"TVII_GRAPHICS_DRIVER_DIR", "TVII_GRAPHICS_DRIVER_DIR"}, {"TVII_GRAPHICS_DRIVER_DIR", "TVII_GRAPHICS_DRIVER_DIR"},
{"CYPRESS_AUTO_FLASH_UTILITY_DIR", "CYPRESS_AUTO_FLASH_UTILITY_DIR"}, {"CYPRESS_AUTO_FLASH_UTILITY_DIR", "CYPRESS_AUTO_FLASH_UTILITY_DIR"},

View File

@@ -104,8 +104,6 @@ static McuToolChainPackage *createArmGccPackage()
defaultPath = subDirs.first(); defaultPath = subDirs.first();
} }
} }
if (defaultPath.isEmpty())
defaultPath = FileUtils::homePath();
const QString detectionPath = Utils::HostOsInfo::withExecutableSuffix("bin/arm-none-eabi-g++"); const QString detectionPath = Utils::HostOsInfo::withExecutableSuffix("bin/arm-none-eabi-g++");
const auto versionDetector = new McuPackageExecutableVersionDetector( const auto versionDetector = new McuPackageExecutableVersionDetector(
@@ -129,8 +127,7 @@ static McuToolChainPackage *createGhsToolchainPackage()
{ {
const char envVar[] = "GHS_COMPILER_DIR"; const char envVar[] = "GHS_COMPILER_DIR";
const FilePath defaultPath = qEnvironmentVariableIsSet(envVar) const FilePath defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar));
? FilePath::fromUserInput(qEnvironmentVariable(envVar)) : FileUtils::homePath();
const auto versionDetector = new McuPackageExecutableVersionDetector( const auto versionDetector = new McuPackageExecutableVersionDetector(
Utils::HostOsInfo::withExecutableSuffix("as850"), Utils::HostOsInfo::withExecutableSuffix("as850"),
@@ -153,8 +150,7 @@ static McuToolChainPackage *createGhsArmToolchainPackage()
{ {
const char envVar[] = "GHS_ARM_COMPILER_DIR"; const char envVar[] = "GHS_ARM_COMPILER_DIR";
const FilePath defaultPath = qEnvironmentVariableIsSet(envVar) const FilePath defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar));
? FilePath::fromUserInput(qEnvironmentVariable(envVar)) : FileUtils::homePath();
const auto versionDetector = new McuPackageExecutableVersionDetector( const auto versionDetector = new McuPackageExecutableVersionDetector(
Utils::HostOsInfo::withExecutableSuffix("asarm"), Utils::HostOsInfo::withExecutableSuffix("asarm"),
@@ -189,8 +185,6 @@ static McuToolChainPackage *createIarToolChainPackage()
const FilePath compilerExecPath = tc->compilerCommand(); const FilePath compilerExecPath = tc->compilerCommand();
defaultPath = compilerExecPath.parentDir().parentDir(); defaultPath = compilerExecPath.parentDir().parentDir();
} }
else
defaultPath = FileUtils::homePath();
} }
const QString detectionPath = Utils::HostOsInfo::withExecutableSuffix("bin/iccarm"); const QString detectionPath = Utils::HostOsInfo::withExecutableSuffix("bin/iccarm");
@@ -219,8 +213,9 @@ static McuPackage *createRGLPackage()
if (qEnvironmentVariableIsSet(envVar)) { if (qEnvironmentVariableIsSet(envVar)) {
defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar)); defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar));
} else if (Utils::HostOsInfo::isWindowsHost()) { } else if (Utils::HostOsInfo::isWindowsHost()) {
defaultPath = FilePath::fromUserInput(QDir::rootPath() + "Renesas_Electronics/D1x_RGL"); const FilePath rglPath = FilePath::fromString(QDir::rootPath()) / "Renesas_Electronics/D1x_RGL";
if (defaultPath.exists()) { if (rglPath.exists()) {
defaultPath = rglPath;
const FilePaths subDirs = const FilePaths subDirs =
defaultPath.dirEntries({QLatin1String("rgl_ghs_D1Mx_*")}, defaultPath.dirEntries({QLatin1String("rgl_ghs_D1Mx_*")},
QDir::Dirs | QDir::NoDotAndDotDot); QDir::Dirs | QDir::NoDotAndDotDot);
@@ -240,7 +235,7 @@ static McuPackage *createRGLPackage()
static McuPackage *createStm32CubeProgrammerPackage() static McuPackage *createStm32CubeProgrammerPackage()
{ {
FilePath defaultPath = FileUtils::homePath(); FilePath defaultPath;
const QString cubePath = "STMicroelectronics/STM32Cube/STM32CubeProgrammer"; const QString cubePath = "STMicroelectronics/STM32Cube/STM32CubeProgrammer";
if (HostOsInfo::isWindowsHost()) { if (HostOsInfo::isWindowsHost()) {
const FilePath programPath = findInProgramFiles(cubePath); const FilePath programPath = findInProgramFiles(cubePath);
@@ -272,8 +267,9 @@ static McuPackage *createMcuXpressoIdePackage()
if (qEnvironmentVariableIsSet(envVar)) { if (qEnvironmentVariableIsSet(envVar)) {
defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar)); defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar));
} else if (HostOsInfo::isWindowsHost()) { } else if (HostOsInfo::isWindowsHost()) {
defaultPath = FilePath::fromString(QDir::rootPath() + "nxp"); const FilePath programPath = FilePath::fromString(QDir::rootPath()) / "nxp";
if (defaultPath.exists()) { if (programPath.exists()) {
defaultPath = programPath;
// If default dir has exactly one sub dir that could be the IDE path, pre-select that. // If default dir has exactly one sub dir that could be the IDE path, pre-select that.
const FilePaths subDirs = const FilePaths subDirs =
defaultPath.dirEntries({QLatin1String("MCUXpressoIDE*")}, defaultPath.dirEntries({QLatin1String("MCUXpressoIDE*")},
@@ -282,7 +278,9 @@ static McuPackage *createMcuXpressoIdePackage()
defaultPath = subDirs.first(); defaultPath = subDirs.first();
} }
} else { } else {
defaultPath = "/usr/local/mcuxpressoide/"; const FilePath programPath = FilePath::fromString("/usr/local/mcuxpressoide/");
if (programPath.exists())
defaultPath = programPath;
} }
auto result = new McuPackage( auto result = new McuPackage(
@@ -303,16 +301,10 @@ static McuPackage *createCypressProgrammerPackage()
if (qEnvironmentVariableIsSet(envVar)) { if (qEnvironmentVariableIsSet(envVar)) {
defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar)); defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar));
} else if (HostOsInfo::isWindowsHost()) { } else if (HostOsInfo::isWindowsHost()) {
FilePath candidate = findInProgramFiles("Cypress/Cypress Auto Flash Utility 1.0"); const FilePath candidate = findInProgramFiles("Cypress/Cypress Auto Flash Utility 1.0");
if (candidate.exists()) { if (candidate.exists())
defaultPath = candidate; defaultPath = candidate;
} }
} else {
defaultPath = "/usr";
}
if (defaultPath.isEmpty())
defaultPath = FileUtils::homePath();
auto result = new McuPackage( auto result = new McuPackage(
"Cypress Auto Flash Utility", "Cypress Auto Flash Utility",
@@ -393,7 +385,7 @@ static McuPackage *createBoardSdkPackage(const McuTargetDescription& desc)
if (defaultPath.exists()) if (defaultPath.exists())
return defaultPath; return defaultPath;
} }
return FileUtils::homePath(); return FilePath();
}(); }();
const auto versionDetector = generatePackageVersionDetector(desc.boardSdk.envVar); const auto versionDetector = generatePackageVersionDetector(desc.boardSdk.envVar);
@@ -418,8 +410,6 @@ static McuPackage *createFreeRTOSSourcesPackage(const QString &envVar, const Fil
defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar.toLatin1())); defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar.toLatin1()));
else if (!boardSdkDir.isEmpty() && !freeRTOSBoardSdkSubDir.isEmpty()) else if (!boardSdkDir.isEmpty() && !freeRTOSBoardSdkSubDir.isEmpty())
defaultPath = boardSdkDir / freeRTOSBoardSdkSubDir; defaultPath = boardSdkDir / freeRTOSBoardSdkSubDir;
else
defaultPath = FileUtils::homePath();
auto result = new McuPackage( auto result = new McuPackage(
QString::fromLatin1("FreeRTOS Sources (%1)").arg(envVarPrefix), QString::fromLatin1("FreeRTOS Sources (%1)").arg(envVarPrefix),
@@ -634,7 +624,7 @@ static QVector<McuTarget *> targetsFromDescriptions(const QList<McuTargetDescrip
Utils::FilePath kitsPath(const Utils::FilePath &dir) Utils::FilePath kitsPath(const Utils::FilePath &dir)
{ {
return dir + "/kits/"; return dir / "kits/";
} }
static QFileInfoList targetDescriptionFiles(const Utils::FilePath &dir) static QFileInfoList targetDescriptionFiles(const Utils::FilePath &dir)

View File

@@ -255,8 +255,10 @@ void DeviceSettingsWidget::testDevice()
{ {
const IDevice::ConstPtr &device = currentDevice(); const IDevice::ConstPtr &device = currentDevice();
QTC_ASSERT(device && device->hasDeviceTester(), return); QTC_ASSERT(device && device->hasDeviceTester(), return);
DeviceTestDialog dlg(m_deviceManager->mutableDevice(device->id()), this); auto dlg = new DeviceTestDialog(m_deviceManager->mutableDevice(device->id()), this);
dlg.exec(); dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->setModal(true);
dlg->show();
} }
void DeviceSettingsWidget::handleDeviceUpdated(Id id) void DeviceSettingsWidget::handleDeviceUpdated(Id id)

View File

@@ -521,6 +521,19 @@ void JsonWizardFactory::registerGeneratorFactory(JsonWizardGeneratorFactory *fac
s_generatorFactories.append(factory); s_generatorFactories.append(factory);
} }
static QString qmlProjectName(const FilePath &folder)
{
FilePath currentFolder = folder;
while (!currentFolder.isEmpty()) {
const QList<FilePath> fileList = currentFolder.dirEntries({"*.qmlproject"});
if (!fileList.isEmpty())
return fileList.first().baseName();
currentFolder = currentFolder.parentDir();
}
return {};
}
Wizard *JsonWizardFactory::runWizardImpl(const FilePath &path, QWidget *parent, Wizard *JsonWizardFactory::runWizardImpl(const FilePath &path, QWidget *parent,
Id platform, Id platform,
const QVariantMap &variables, bool showWizard) const QVariantMap &variables, bool showWizard)
@@ -545,6 +558,7 @@ Wizard *JsonWizardFactory::runWizardImpl(const FilePath &path, QWidget *parent,
wizard->setValue(i.key(), i.value()); wizard->setValue(i.key(), i.value());
wizard->setValue(QStringLiteral("InitialPath"), path.toString()); wizard->setValue(QStringLiteral("InitialPath"), path.toString());
wizard->setValue(QStringLiteral("QmlProjectName"), qmlProjectName(path));
wizard->setValue(QStringLiteral("Platform"), platform.toString()); wizard->setValue(QStringLiteral("Platform"), platform.toString());
QString kindStr = QLatin1String(Core::Constants::WIZARD_KIND_UNKNOWN); QString kindStr = QLatin1String(Core::Constants::WIZARD_KIND_UNKNOWN);

View File

@@ -83,9 +83,18 @@ bool Navigation2dFilter::gestureEvent(QGestureEvent *event)
bool Navigation2dFilter::wheelEvent(QWheelEvent *event) bool Navigation2dFilter::wheelEvent(QWheelEvent *event)
{ {
if (event->source() == Qt::MouseEventSynthesizedBySystem) { if (event->source() == Qt::MouseEventSynthesizedBySystem) {
if (event->modifiers().testFlag(Qt::ControlModifier)) {
if (QPointF delta = event->pixelDelta(); !delta.isNull()) {
double dist = std::abs(delta.x()) > std::abs(delta.y()) ? -delta.x() : delta.y();
emit zoomChanged(dist/200.0, event->position());
event->accept();
return true;
}
} else {
emit panChanged(QPointF(event->pixelDelta())); emit panChanged(QPointF(event->pixelDelta()));
event->accept(); event->accept();
return true; return true;
}
} else if (event->source() == Qt::MouseEventNotSynthesized) { } else if (event->source() == Qt::MouseEventNotSynthesized) {
auto zoomInSignal = QMetaMethod::fromSignal(&Navigation2dFilter::zoomIn); auto zoomInSignal = QMetaMethod::fromSignal(&Navigation2dFilter::zoomIn);

View File

@@ -279,7 +279,10 @@ bool DesignDocument::isDocumentLoaded() const
void DesignDocument::resetToDocumentModel() void DesignDocument::resetToDocumentModel()
{ {
plainTextEdit()->document()->clearUndoRedoStacks(); const QPlainTextEdit *edit = plainTextEdit();
if (edit)
edit->document()->clearUndoRedoStacks();
m_inFileComponentModel.reset(); m_inFileComponentModel.reset();
} }
@@ -311,7 +314,9 @@ void DesignDocument::changeToDocumentModel()
viewManager().detachRewriterView(); viewManager().detachRewriterView();
viewManager().detachViewsExceptRewriterAndComponetView(); viewManager().detachViewsExceptRewriterAndComponetView();
plainTextEdit()->document()->clearUndoRedoStacks(); const QPlainTextEdit *edit = plainTextEdit();
if (edit)
edit->document()->clearUndoRedoStacks();
m_inFileComponentModel.reset(); m_inFileComponentModel.reset();
m_inFileComponentTextModifier.reset(); m_inFileComponentTextModifier.reset();
@@ -348,7 +353,9 @@ void DesignDocument::changeToInFileComponentModel(ComponentTextModifier *textMod
viewManager().detachRewriterView(); viewManager().detachRewriterView();
viewManager().detachViewsExceptRewriterAndComponetView(); viewManager().detachViewsExceptRewriterAndComponetView();
plainTextEdit()->document()->clearUndoRedoStacks(); const QPlainTextEdit *edit = plainTextEdit();
if (edit)
edit->document()->clearUndoRedoStacks();
m_inFileComponentModel.reset(createInFileComponentModel()); m_inFileComponentModel.reset(createInFileComponentModel());
m_inFileComponentModel->setTextModifier(m_inFileComponentTextModifier.data()); m_inFileComponentModel->setTextModifier(m_inFileComponentTextModifier.data());

View File

@@ -102,11 +102,15 @@ bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event)
// For drag to be handled correctly, we must have the component properly imported // For drag to be handled correctly, we must have the component properly imported
// beforehand, so we import the module immediately when the drag starts // beforehand, so we import the module immediately when the drag starts
if (!entry.requiredImport().isEmpty()) { if (!entry.requiredImport().isEmpty()) {
Import import = Import::createLibraryImport(entry.requiredImport()); // We don't know if required import is library of file import, so try both.
if (!m_model->hasImport(import, true, true)) { Import libImport = Import::createLibraryImport(entry.requiredImport());
Import fileImport = Import::createFileImport(entry.requiredImport());
if (!m_model->hasImport(libImport, true, true)
&& !m_model->hasImport(fileImport, true, true)) {
const QList<Import> possImports = m_model->possibleImports(); const QList<Import> possImports = m_model->possibleImports();
for (const auto &possImport : possImports) { for (const auto &possImport : possImports) {
if (possImport.url() == import.url()) { if ((!possImport.url().isEmpty() && possImport.url() == libImport.url())
|| (!possImport.file().isEmpty() && possImport.file() == fileImport.file())) {
m_model->changeImports({possImport}, {}); m_model->changeImports({possImport}, {});
break; break;
} }

View File

@@ -28,6 +28,7 @@
#include "navigatorwidget.h" #include "navigatorwidget.h"
#include "qmldesignerconstants.h" #include "qmldesignerconstants.h"
#include "qmldesignericons.h" #include "qmldesignericons.h"
#include "qmldesignerplugin.h"
#include "nameitemdelegate.h" #include "nameitemdelegate.h"
#include "iconcheckboxitemdelegate.h" #include "iconcheckboxitemdelegate.h"
@@ -166,9 +167,14 @@ void NavigatorView::modelAttached(Model *model)
const QHash<QString, bool> localExpandMap = m_expandMap[AbstractView::model()->fileUrl()]; const QHash<QString, bool> localExpandMap = m_expandMap[AbstractView::model()->fileUrl()];
auto it = localExpandMap.constBegin(); auto it = localExpandMap.constBegin();
while (it != localExpandMap.constEnd()) { while (it != localExpandMap.constEnd()) {
const QModelIndex index = indexForModelNode(modelNodeForId(it.key())); const ModelNode node = modelNodeForId(it.key());
// When editing subcomponent, the current root node may be marked collapsed in the
// full file view, but we never want to actually collapse it, so skip it.
if (!node.isRootNode()) {
const QModelIndex index = indexForModelNode(node);
if (index.isValid()) if (index.isValid())
treeWidget()->setExpanded(index, it.value()); treeWidget()->setExpanded(index, it.value());
}
++it; ++it;
} }
} }
@@ -200,11 +206,18 @@ void NavigatorView::addNodeAndSubModelNodesToList(const ModelNode &node, QList<M
void NavigatorView::modelAboutToBeDetached(Model *model) void NavigatorView::modelAboutToBeDetached(Model *model)
{ {
m_expandMap.remove(model->fileUrl()); QHash<QString, bool> &localExpandMap = m_expandMap[model->fileUrl()];
// If detaching full document model, recreate expand map from scratch to remove stale entries.
// Otherwise just update it (subcomponent edit case).
bool fullUpdate = true;
if (DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument())
fullUpdate = !document->inFileComponentModelActive();
if (fullUpdate)
localExpandMap.clear();
if (currentModel()) { if (currentModel()) {
// Store expand state of the navigator tree // Store expand state of the navigator tree
QHash<QString, bool> localExpandMap;
const ModelNode rootNode = rootModelNode(); const ModelNode rootNode = rootModelNode();
const QModelIndex rootIndex = indexForModelNode(rootNode); const QModelIndex rootIndex = indexForModelNode(rootNode);
@@ -215,15 +228,18 @@ void NavigatorView::modelAboutToBeDetached(Model *model)
for (int i = 0; i < rowCount; ++i) { for (int i = 0; i < rowCount; ++i) {
const QModelIndex childIndex = currentModel()->index(i, 0, index); const QModelIndex childIndex = currentModel()->index(i, 0, index);
const ModelNode node = modelNodeForIndex(childIndex); const ModelNode node = modelNodeForIndex(childIndex);
if (node.isValid()) {
// Just store collapsed states as everything is expanded by default // Just store collapsed states as everything is expanded by default
if (node.isValid() && !treeWidget()->isExpanded(childIndex)) if (!treeWidget()->isExpanded(childIndex))
localExpandMap.insert(node.id(), false); localExpandMap.insert(node.id(), false);
else if (!fullUpdate)
localExpandMap.remove(node.id());
}
gatherExpandedState(childIndex); gatherExpandedState(childIndex);
} }
} }
}; };
gatherExpandedState(rootIndex); gatherExpandedState(rootIndex);
m_expandMap[model->fileUrl()] = localExpandMap;
} }
AbstractView::modelAboutToBeDetached(model); AbstractView::modelAboutToBeDetached(model);

View File

@@ -63,13 +63,14 @@ enum ProjectDirectoryError {
NoError = 0, NoError = 0,
MissingContentDir = 1<<1, MissingContentDir = 1<<1,
MissingImportDir = 1<<2, MissingImportDir = 1<<2,
MissingCppDir = 1<<3, MissingAssetImportDir = 1<<3,
MissingMainCMake = 1<<4, MissingCppDir = 1<<4,
MissingMainQml = 1<<5, MissingMainCMake = 1<<5,
MissingAppMainQml = 1<<6, MissingMainQml = 1<<6,
MissingQmlModules = 1<<7, MissingAppMainQml = 1<<7,
MissingMainCpp = 1<<8, MissingQmlModules = 1<<8,
MissingMainCppHeader = 1<<9 MissingMainCpp = 1<<9,
MissingMainCppHeader = 1<<10
}; };
QVector<GeneratableFile> queuedFiles; QVector<GeneratableFile> queuedFiles;
@@ -131,6 +132,8 @@ int isProjectCorrectlyFormed(const FilePath &rootDir)
if (!rootDir.pathAppended(DIRNAME_IMPORT).exists()) if (!rootDir.pathAppended(DIRNAME_IMPORT).exists())
errors |= MissingImportDir; errors |= MissingImportDir;
if (!rootDir.pathAppended(DIRNAME_ASSET).exists())
errors |= MissingAssetImportDir;
if (!rootDir.pathAppended(DIRNAME_CPP).exists()) if (!rootDir.pathAppended(DIRNAME_CPP).exists())
errors |= MissingCppDir; errors |= MissingCppDir;
@@ -159,7 +162,7 @@ void removeUnconfirmedQueuedFiles(const Utils::FilePaths confirmedFiles)
const QString WARNING_MISSING_STRUCTURE_FATAL = QCoreApplication::translate("QmlDesigner::GenerateCmake", const QString WARNING_MISSING_STRUCTURE_FATAL = QCoreApplication::translate("QmlDesigner::GenerateCmake",
"The project is not properly structured for automatically generating CMake files.\n\nAborting process.\n\nThe following files or directories are missing:\n\n%1"); "The project is not properly structured for automatically generating CMake files.\n\nAborting process.\n\nThe following files or directories are missing:\n\n%1");
const QString WARNING_MISSING_STRUCTURE_NONFATAL = QCoreApplication::translate("QmlDesigner::GenerateCmake", const QString WARNING_MISSING_STRUCTURE_NONFATAL = QCoreApplication::translate("QmlDesigner::GenerateCmake",
"The project is not properly structured for automatically generating CMake files.\n\nThe following files will be created:\n\n%1"); "The project is not properly structured for automatically generating CMake files.\n\nThe following files or directories are missing and may be created:\n\n%1");
const QString WARNING_TITLE_FATAL = QCoreApplication::translate("QmlDesigner::GenerateCmake", const QString WARNING_TITLE_FATAL = QCoreApplication::translate("QmlDesigner::GenerateCmake",
"Cannot Generate CMake Files"); "Cannot Generate CMake Files");
const QString WARNING_TITLE_NONFATAL = QCoreApplication::translate("QmlDesigner::GenerateCmake", const QString WARNING_TITLE_NONFATAL = QCoreApplication::translate("QmlDesigner::GenerateCmake",
@@ -182,6 +185,8 @@ void showProjectDirErrorDialog(int error)
if (error & MissingImportDir) if (error & MissingImportDir)
fatalList.append(QString(DIRNAME_IMPORT) + "\n"); fatalList.append(QString(DIRNAME_IMPORT) + "\n");
if (error & MissingAssetImportDir)
nonFatalList.append(QString(DIRNAME_ASSET) + "\n");
if (error & MissingMainCMake) if (error & MissingMainCMake)
nonFatalList.append(QString(FILENAME_CMAKELISTS) + "\n"); nonFatalList.append(QString(FILENAME_CMAKELISTS) + "\n");
if (error & MissingQmlModules) if (error & MissingQmlModules)
@@ -290,16 +295,21 @@ bool generateCmakes(const FilePath &rootDir)
{ {
moduleNames.clear(); moduleNames.clear();
FilePath contentDir = rootDir.pathAppended("content"); FilePath contentDir = rootDir.pathAppended(DIRNAME_CONTENT);
FilePath importDir = rootDir.pathAppended("imports"); FilePath importDir = rootDir.pathAppended(DIRNAME_IMPORT);
FilePath assetDir = rootDir.pathAppended(DIRNAME_ASSET);
generateModuleCmake(contentDir); generateModuleCmake(contentDir);
generateImportCmake(importDir); generateImportCmake(importDir);
generateImportCmake(assetDir);
generateMainCmake(rootDir); generateMainCmake(rootDir);
return true; return true;
} }
const char DO_NOT_EDIT_FILE_COMMENT[] = "### This file is automatically generated by Qt Design Studio.\n### Do not change\n\n";
const char ADD_SUBDIR[] = "add_subdirectory(%1)\n";
void generateMainCmake(const FilePath &rootDir) void generateMainCmake(const FilePath &rootDir)
{ {
//TODO startupProject() may be a terrible way to try to get "current project". It's not necessarily the same thing at all. //TODO startupProject() may be a terrible way to try to get "current project". It's not necessarily the same thing at all.
@@ -309,27 +319,47 @@ void generateMainCmake(const FilePath &rootDir)
QString cmakeFileContent = GenerateCmake::readTemplate(MAIN_CMAKEFILE_TEMPLATE_PATH).arg(appName); QString cmakeFileContent = GenerateCmake::readTemplate(MAIN_CMAKEFILE_TEMPLATE_PATH).arg(appName);
queueCmakeFile(rootDir, cmakeFileContent); queueCmakeFile(rootDir, cmakeFileContent);
QString subdirIncludes;
subdirIncludes.append(QString(ADD_SUBDIR).arg(DIRNAME_CONTENT));
subdirIncludes.append(QString(ADD_SUBDIR).arg(DIRNAME_IMPORT));
if (rootDir.pathAppended(DIRNAME_ASSET).exists())
subdirIncludes.append(QString(ADD_SUBDIR).arg(DIRNAME_ASSET));
QString modulesAsPlugins; QString modulesAsPlugins;
for (const QString &moduleName : moduleNames) for (const QString &moduleName : moduleNames)
modulesAsPlugins.append(" " + moduleName + "plugin\n"); modulesAsPlugins.append(" " + moduleName + "plugin\n");
QString moduleFileContent = GenerateCmake::readTemplate(QMLMODULES_FILE_TEMPLATE_PATH).arg(appName).arg(modulesAsPlugins); QString moduleFileContent = GenerateCmake::readTemplate(QMLMODULES_FILE_TEMPLATE_PATH)
.arg(appName)
.arg(subdirIncludes)
.arg(modulesAsPlugins);
GenerateCmake::queueFile(rootDir.pathAppended(FILENAME_MODULES), moduleFileContent); GenerateCmake::queueFile(rootDir.pathAppended(FILENAME_MODULES), moduleFileContent);
} }
const char DO_NOT_EDIT_FILE_COMMENT[] = "### This file is automatically generated by Qt Design Studio.\n### Do not change\n\n"; void generateImportCmake(const FilePath &dir, const QString &modulePrefix)
const char ADD_SUBDIR[] = "add_subdirectory(%1)\n";
void generateImportCmake(const FilePath &dir)
{ {
if (!dir.exists())
return;
QString fileContent; QString fileContent;
fileContent.append(DO_NOT_EDIT_FILE_COMMENT); fileContent.append(DO_NOT_EDIT_FILE_COMMENT);
FilePaths subDirs = dir.dirEntries(DIRS_ONLY); FilePaths subDirs = dir.dirEntries(DIRS_ONLY);
for (FilePath &subDir : subDirs) { for (FilePath &subDir : subDirs) {
if (isDirBlacklisted(subDir))
continue;
if (getDirectoryTreeQmls(subDir).isEmpty() && getDirectoryTreeResources(subDir).isEmpty())
continue;
fileContent.append(QString(ADD_SUBDIR).arg(subDir.fileName())); fileContent.append(QString(ADD_SUBDIR).arg(subDir.fileName()));
generateModuleCmake(subDir); QString prefix = modulePrefix.isEmpty() ?
modulePrefix % subDir.fileName() :
QString(modulePrefix + '.') + subDir.fileName();
if (getDirectoryQmls(subDir).isEmpty()) {
generateImportCmake(subDir, prefix);
} else {
generateModuleCmake(subDir, prefix);
}
} }
queueCmakeFile(dir, fileContent); queueCmakeFile(dir, fileContent);
@@ -339,13 +369,12 @@ const char MODULEFILE_PROPERTY_SINGLETON[] = "QT_QML_SINGLETON_TYPE";
const char MODULEFILE_PROPERTY_SET[] = "set_source_files_properties(%1\n PROPERTIES\n %2 %3\n)\n\n"; const char MODULEFILE_PROPERTY_SET[] = "set_source_files_properties(%1\n PROPERTIES\n %2 %3\n)\n\n";
const char MODULEFILE_TEMPLATE_PATH[] = ":/boilerplatetemplates/qmlprojectmodulecmakelists.tpl"; const char MODULEFILE_TEMPLATE_PATH[] = ":/boilerplatetemplates/qmlprojectmodulecmakelists.tpl";
void generateModuleCmake(const FilePath &dir) void generateModuleCmake(const FilePath &dir, const QString &uri)
{ {
QString fileTemplate = GenerateCmake::readTemplate(MODULEFILE_TEMPLATE_PATH); QString fileTemplate = GenerateCmake::readTemplate(MODULEFILE_TEMPLATE_PATH);
const QStringList qmldirFilesOnly(FILENAME_QMLDIR);
QString singletonContent; QString singletonContent;
FilePaths qmldirFileList = dir.dirEntries(qmldirFilesOnly, FILES_ONLY); FilePaths qmldirFileList = dir.dirEntries(QStringList(FILENAME_QMLDIR), FILES_ONLY);
if (!qmldirFileList.isEmpty()) { if (!qmldirFileList.isEmpty()) {
QStringList singletons = getSingletonsFromQmldirFile(qmldirFileList.first()); QStringList singletons = getSingletonsFromQmldirFile(qmldirFileList.first());
for (QString &singleton : singletons) { for (QString &singleton : singletons) {
@@ -371,12 +400,14 @@ void generateModuleCmake(const FilePath &dir)
moduleContent.append(QString(" RESOURCES\n%1").arg(resourceFiles)); moduleContent.append(QString(" RESOURCES\n%1").arg(resourceFiles));
} }
QString moduleName = dir.fileName(); QString moduleUri = uri.isEmpty() ?
dir.fileName() :
uri;
QString moduleName = QString(moduleUri).remove('.');
moduleNames.append(moduleName); moduleNames.append(moduleName);
QString fileContent; QString fileContent;
fileContent.append(fileTemplate.arg(singletonContent).arg(moduleName).arg(moduleContent)); fileContent.append(fileTemplate.arg(singletonContent, moduleName, moduleUri, moduleContent));
queueCmakeFile(dir, fileContent); queueCmakeFile(dir, fileContent);
} }
@@ -403,6 +434,22 @@ QStringList getSingletonsFromQmldirFile(const FilePath &filePath)
return singletons; return singletons;
} }
FilePaths getDirectoryQmls(const FilePath &dir)
{
const QStringList qmlFilesOnly("*.qml");
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
FilePaths allFiles = dir.dirEntries(qmlFilesOnly, FILES_ONLY);
FilePaths moduleFiles;
for (FilePath &file : allFiles) {
if (!isFileBlacklisted(file.fileName()) &&
project->isKnownFile(file)) {
moduleFiles.append(file);
}
}
return moduleFiles;
}
QStringList getDirectoryTreeQmls(const FilePath &dir) QStringList getDirectoryTreeQmls(const FilePath &dir)
{ {
const QStringList qmlFilesOnly("*.qml"); const QStringList qmlFilesOnly("*.qml");
@@ -419,6 +466,8 @@ QStringList getDirectoryTreeQmls(const FilePath &dir)
FilePaths subDirsList = dir.dirEntries(DIRS_ONLY); FilePaths subDirsList = dir.dirEntries(DIRS_ONLY);
for (FilePath &subDir : subDirsList) { for (FilePath &subDir : subDirsList) {
if (isDirBlacklisted(subDir))
continue;
QStringList subDirQmlFiles = getDirectoryTreeQmls(subDir); QStringList subDirQmlFiles = getDirectoryTreeQmls(subDir);
for (QString &qmlFile : subDirQmlFiles) { for (QString &qmlFile : subDirQmlFiles) {
qmlFileList.append(subDir.fileName().append('/').append(qmlFile)); qmlFileList.append(subDir.fileName().append('/').append(qmlFile));
@@ -444,6 +493,8 @@ QStringList getDirectoryTreeResources(const FilePath &dir)
FilePaths subDirsList = dir.dirEntries(DIRS_ONLY); FilePaths subDirsList = dir.dirEntries(DIRS_ONLY);
for (FilePath &subDir : subDirsList) { for (FilePath &subDir : subDirsList) {
if (isDirBlacklisted(subDir))
continue;
QStringList subDirResources = getDirectoryTreeResources(subDir); QStringList subDirResources = getDirectoryTreeResources(subDir);
for (QString &resource : subDirResources) { for (QString &resource : subDirResources) {
resourceFileList.append(subDir.fileName().append('/').append(resource)); resourceFileList.append(subDir.fileName().append('/').append(resource));
@@ -466,6 +517,11 @@ bool isFileBlacklisted(const QString &fileName)
!fileName.compare(FILENAME_CMAKELISTS)); !fileName.compare(FILENAME_CMAKELISTS));
} }
bool isDirBlacklisted(const FilePath &dir)
{
return (!dir.fileName().compare(DIRNAME_DESIGNER));
}
} }
namespace GenerateEntryPoints { namespace GenerateEntryPoints {

View File

@@ -54,13 +54,15 @@ QString readTemplate(const QString &templatePath);
namespace GenerateCmakeLists { namespace GenerateCmakeLists {
bool generateCmakes(const Utils::FilePath &rootDir); bool generateCmakes(const Utils::FilePath &rootDir);
void generateMainCmake(const Utils::FilePath &rootDir); void generateMainCmake(const Utils::FilePath &rootDir);
void generateImportCmake(const Utils::FilePath &dir); void generateImportCmake(const Utils::FilePath &dir, const QString &modulePrefix = QString());
void generateModuleCmake(const Utils::FilePath &dir); void generateModuleCmake(const Utils::FilePath &dir, const QString &moduleUri = QString());
Utils::FilePaths getDirectoryQmls(const Utils::FilePath &dir);
QStringList getSingletonsFromQmldirFile(const Utils::FilePath &filePath); QStringList getSingletonsFromQmldirFile(const Utils::FilePath &filePath);
QStringList getDirectoryTreeQmls(const Utils::FilePath &dir); QStringList getDirectoryTreeQmls(const Utils::FilePath &dir);
QStringList getDirectoryTreeResources(const Utils::FilePath &dir); QStringList getDirectoryTreeResources(const Utils::FilePath &dir);
void queueCmakeFile(const Utils::FilePath &filePath, const QString &content); void queueCmakeFile(const Utils::FilePath &filePath, const QString &content);
bool isFileBlacklisted(const QString &fileName); bool isFileBlacklisted(const QString &fileName);
bool isDirBlacklisted(const Utils::FilePath &dir);
} }
namespace GenerateEntryPoints { namespace GenerateEntryPoints {
bool generateEntryPointFiles(const Utils::FilePath &dir); bool generateEntryPointFiles(const Utils::FilePath &dir);

View File

@@ -34,7 +34,9 @@ namespace Constants {
const char DIRNAME_CONTENT[] = "content"; const char DIRNAME_CONTENT[] = "content";
const char DIRNAME_IMPORT[] = "imports"; const char DIRNAME_IMPORT[] = "imports";
const char DIRNAME_ASSET[] = "asset_imports";
const char DIRNAME_CPP[] = "src"; const char DIRNAME_CPP[] = "src";
const char DIRNAME_DESIGNER[] = "designer";
const char FILENAME_CMAKELISTS[] = "CMakeLists.txt"; const char FILENAME_CMAKELISTS[] = "CMakeLists.txt";
const char FILENAME_APPMAINQML[] = "App.qml"; const char FILENAME_APPMAINQML[] = "App.qml";

View File

@@ -5,7 +5,7 @@
qt_add_library(%2 STATIC) qt_add_library(%2 STATIC)
qt6_add_qml_module(%2 qt6_add_qml_module(%2
URI "%2" URI "%3"
VERSION 1.0 VERSION 1.0
%3 %4
) )

Some files were not shown because too many files have changed in this diff Show More