Merge remote-tracking branch 'origin/6.0'

Change-Id: I405e3f95b0cdcd7b2686f31baae16c03c787f007
This commit is contained in:
Eike Ziller
2022-01-06 10:46:57 +01:00
145 changed files with 2686 additions and 472 deletions
@@ -7,26 +7,26 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt6 6.2 COMPONENTS Quick Sensors Svg Xml REQUIRED)
qt_add_executable(accelbubbleexample
qt_add_executable(appaccelbubble
main.cpp
MANUAL_FINALIZATION
)
set_target_properties(accelbubbleexample PROPERTIES
set_target_properties(appaccelbubble PROPERTIES
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist"
)
set_property(TARGET accelbubbleexample APPEND PROPERTY
set_property(TARGET appaccelbubble APPEND PROPERTY
QT_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/android
)
qt_add_qml_module(accelbubbleexample
qt_add_qml_module(appaccelbubble
URI accelbubble
VERSION 1.0
QML_FILES main.qml
RESOURCES Bluebubble.svg
)
target_compile_definitions(accelbubbleexample
target_compile_definitions(appaccelbubble
PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
target_link_libraries(accelbubbleexample
target_link_libraries(appaccelbubble
PRIVATE Qt6::Quick Qt6::Sensors Qt6::Svg Qt6::Xml)
qt_finalize_executable(accelbubbleexample)
qt_finalize_executable(appaccelbubble)
@@ -7,18 +7,18 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt6 6.2 COMPONENTS Quick REQUIRED)
qt_add_executable(transitionsexample
qt_add_executable(apptransitions
main.cpp
)
qt_add_qml_module(transitionsexample
qt_add_qml_module(apptransitions
URI transitions
VERSION 1.0
QML_FILES main.qml Page.qml
RESOURCES qt-logo.png
)
target_compile_definitions(transitionsexample
target_compile_definitions(apptransitions
PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
target_link_libraries(transitionsexample
target_link_libraries(apptransitions
PRIVATE Qt6::Quick)
@@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
@@ -200,7 +200,7 @@
arguments to the linker and makes sure that the appropriate include
directories and compiler definitions are passed to the C++ compiler.
\skipto target_link_libraries(accelbubble
\skipto target_link_libraries(appaccelbubble
\printuntil Qt6
After adding the dependencies, select \uicontrol Build >
@@ -24,11 +24,7 @@ imagedirs = ../images \
../../../src/libs/qmleditorwidgets/images \
../../../src/plugins/qmldesigner/components/componentcore/images \
../../../src/plugins/qmldesigner/components/edit3d/images \
../../../src/plugins/qmldesigner/components/formeditor \
../../../src/plugins/qmldesigner/components/navigator \
../../../src/plugins/qmldesigner/components/timelineeditor/images \
../../../src/plugins/qmldesigner/componentsplugin/images \
../../../src/plugins/qmldesigner/qmlpreviewplugin/images \
../../../src/plugins/qmldesigner/qtquickplugin/images \
include(../../qtcreator/images/extraimages/qtdesignstudio-extraimages.qdocconf)
@@ -159,7 +159,7 @@
\c {"settings"} and \c {"selection"} states.
We then return to the \uicontrol Timeline view and select
\inlineimage animation.png "Timeline Settings button"
\inlineimage icons/animation.png "Timeline Settings button"
to open the \uicontrol {Timeline Settings} dialog. We select
the \uicontrol Add button to create animations for each part
of the timeline. Therefore, the start and end frame of each
@@ -114,7 +114,7 @@
ToBig, and FromBig.
We then return to the \uicontrol Timeline view and select
\inlineimage animation.png "Timeline Settings button"
\inlineimage icons/animation.png "Timeline Settings button"
to open the \uicontrol {Timeline Settings} dialog. We select
the \uicontrol Add button to create animations for each part
of the timeline. Therefore, the start and end frame of each
@@ -169,7 +169,7 @@
\endlist
To preview the changes that you make to the UI while you make
them, select the \inlineimage live_preview.png
them, select the \inlineimage icons/live_preview.png
(\uicontrol {Show Live Preview}) button on the \uicontrol {Form Editor}
view toolbar or press \key {Alt+P}.
@@ -63,7 +63,7 @@
adjust the margins to align it with \e qt_logo_green_128x128px on the page.
To preview the changes that you make to the UI while you make
them, select the \inlineimage live_preview.png
them, select the \inlineimage icons/live_preview.png
(\uicontrol {Show Live Preview}) button on the \l {Form Editor}
toolbar or press \key {Alt+P}.
@@ -63,7 +63,7 @@
this section from previous parts of the tutorial.
To preview the changes that you make to the UI while you make
them, select the \inlineimage live_preview.png
them, select the \inlineimage icons/live_preview.png
(\uicontrol {Show Live Preview}) button on the \l {Form Editor}
toolbar or press \key {Alt+P}.
@@ -73,7 +73,7 @@
column component and anchor them to the rectangle and to each other instead.
To preview the changes that you make to the UI while you make
them, select the \inlineimage live_preview.png
them, select the \inlineimage icons/live_preview.png
(\uicontrol {Show Live Preview}) button on the \uicontrol Design
mode \l {Summary of Main Toolbar Actions}{toolbar} or press \key {Alt+P}.
@@ -88,7 +88,7 @@
\inlineimage icons/close.png
to remove the state. Repeat for the \e createAccount state.
\li Select \e username in \l Navigator, and then select
\inlineimage arrowleft.png
\inlineimage icons/arrowleft.png
to move it into the parent rectangle to prepare for
deleting the \e fields column component instance.
\li Select \inlineimage icons/navigator-arrowup.png
@@ -275,7 +275,7 @@
for \e login to open the \uicontrol Actions menu, and then
select \uicontrol {Set as Default} to determine that the \e login
state is applied when the application starts.
\li In \uicontrol Timeline, select the \inlineimage animation.png
\li In \uicontrol Timeline, select the \inlineimage icons/animation.png
(\uicontrol {Timeline Settings (S)}) button on the toolbar (or press
\key S) to open the \uicontrol {Timeline Settings} dialog.
\image loginui4-timeline-settings-states.png
@@ -187,7 +187,7 @@
X coordinate -424. We then move the playhead to frame 1000 and set the X
coordinate to 0.
We select \inlineimage animation.png "Timeline Settings button"
We select \inlineimage icons/animation.png "Timeline Settings button"
to open the \uicontrol {Timeline Settings} dialog. In the
\uicontrol {Transitions to states} field, we select the state to
apply when the animation finishes. In the lower part of the
Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

Before

Width:  |  Height:  |  Size: 173 B

After

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 521 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 379 B

@@ -151,7 +151,7 @@
(\uicontrol Paused) check box.
To attach an \l{Editing Easing Curves}{easing curve} to
the animation, select the \inlineimage curve_editor.png
the animation, select the \inlineimage icons/curve_editor.png
(\uicontrol {Easing Curve Editor}) button in the
\uicontrol {Easing Curve} field.
@@ -261,7 +261,7 @@
pressed down.
\image qmldesigner-borderimage-bindings1.png "Inactive state when condition"
\li Press \key {Ctrl+S} to save the button.
\li Select the \inlineimage live_preview.png
\li Select the \inlineimage icons/live_preview.png
(\uicontrol {Show Live Preview}) button to check how the
button behaves when you click it. You can drag the preview
window borders to see what happens when you resize the
@@ -729,12 +729,12 @@
\row
\li \inlineimage icons/button-icon16.png
\li \l [QtQuickControls]{Button}
\li \inlineimage ok
\li \inlineimage ok.png
\li A push button that you can associate with an action.
\row
\li \inlineimage icons/checkbox-icon16.png
\li \l [QtQuickControls]{CheckBox}{Check Box}
\li \inlineimage ok
\li \inlineimage ok.png
\li An option button that can be toggled on (checked) or off
(unchecked).
\row
@@ -757,7 +757,7 @@
\row
\li \inlineimage icons/dial-icon16.png
\li \l [QtQuickControls]{Dial}
\li \inlineimage ok
\li \inlineimage ok.png
\li A circular dial that is rotated to set a value.
\row
\li \inlineimage icons/pageindicator-icon16.png
@@ -768,12 +768,12 @@
\row
\li \inlineimage icons/progressbar-icon16.png
\li \l [QtQuickControls]{ProgressBar}{Progress Bar}
\li \inlineimage ok
\li \inlineimage ok.png
\li Indicates the progress of an operation.
\row
\li \inlineimage icons/radiobutton-icon16.png
\li \l [QtQuickControls]{RadioButton}{Radio Button}
\li \inlineimage ok
\li \inlineimage ok.png
\li An option button that can be switched on (checked) or off
(unchecked).
\row
@@ -797,7 +797,7 @@
\row
\li \inlineimage icons/slider-icon16.png
\li \l [QtQuickControls]{Slider}
\li \inlineimage ok
\li \inlineimage ok.png
\li Enables users to select a value by sliding a handle along a track.
\row
\li \inlineimage icons/spinbox-icon16.png
@@ -809,7 +809,7 @@
\row
\li \inlineimage icons/switch-icon16.png
\li \l [QtQuickControls]{Switch}
\li \inlineimage ok
\li \inlineimage ok.png
\li An option button that can be toggled on or off.
\row
\li \inlineimage icons/switch-icon16.png
@@ -224,7 +224,7 @@
\li \inlineimage listview-icon16.png
\li \l{ListView}{List View}
\li Default Components - Views
\li \inlineimage ok
\li \inlineimage ok.png
\li A list vizualization of a model.
\row
\li \inlineimage pathview-icon16.png
@@ -265,7 +265,7 @@
\li \inlineimage icons/swipeview-icon16.png
\li \l[QtQuickControls] {SwipeView}{Swipe View}
\li Qt Quick Controls
\li \inlineimage ok
\li \inlineimage ok.png
\li Enables users to navigate pages by swiping sideways.
\endtable
*/
@@ -256,13 +256,13 @@
\li \inlineimage border-image-icon16.png
\li \l [QtQuick]{BorderImage}{Border Image}
\li Default Components - Basic
\li \inlineimage ok
\li \inlineimage ok.png
\li An image that is used as a border or background.
\row
\li \inlineimage image-icon16.png
\li \l [QtQuick]{Image}
\li Default Components - Basic
\li \inlineimage ok
\li \inlineimage ok.png
\li An image in one of the supported formats, including bitmap formats
such as PNG and JPEG and vector graphics formats such as SVG.
\if defined(qtdesignstudio)
@@ -85,7 +85,7 @@
\l{Completing Code}.
When a binding is set, the \uicontrol Actions menu icon changes to
\inlineimage icons/action-icon-binding
\inlineimage icons/action-icon-binding.png
. To remove bindings, select \uicontrol Actions > \uicontrol Reset.
You can set bindings also in \l {Connection View} > \uicontrol Bindings.
@@ -281,7 +281,7 @@
\li \inlineimage rect-icon16.png
\li \l Rectangle
\li Default Components - Basic
\li \inlineimage ok
\li \inlineimage ok.png
\li A rectangle that is painted with a solid fill color or linear
gradient and an optional border. You can use the radius property
to draw circles.
@@ -442,7 +442,7 @@
\li \inlineimage text-icon16.png
\li \l [QtQuick]{Text}
\li Default Components - Basic
\li \inlineimage ok
\li \inlineimage ok.png
\li Formatted read-only text.
\row
\li \inlineimage icons/textarea-icon16.png
@@ -331,7 +331,7 @@
\row
\li \inlineimage flickable-icon16.png
\li \l [QML]{Flickable}
\li \inlineimage ok
\li \inlineimage ok.png
\li Enables flicking components horizontally or vertically.
\row
\li \inlineimage focusscope-icon16.png
@@ -342,7 +342,7 @@
\row
\li \inlineimage mouse-area-icon16.png
\li \l [QtQuick]{MouseArea}{Mouse Area}
\li \inlineimage ok
\li \inlineimage ok.png
\li Enables simple mouse handling.
\endtable
*/
@@ -304,7 +304,7 @@
and transition line.
\endlist
To preview the flow, select the \inlineimage live_preview.png
To preview the flow, select the \inlineimage icons/live_preview.png
(\uicontrol {Show Live Preview}) button on the Design mode
\l{Summary of Main Toolbar Actions}{toolbar} or press \key {Alt+P}.
@@ -456,7 +456,7 @@
\list
\li In the \uicontrol Duration field, specify the duration of the
effect.
\li Select the \inlineimage curve_editor.png
\li Select the \inlineimage icons/curve_editor.png
button to open \uicontrol {Easing Curve Editor} for attaching an
\l{Editing Easing Curves}{easing curve} to the effect.
\endlist
@@ -37,7 +37,7 @@
To run an example project:
\list 1
\li Select the example.
\li Select the \inlineimage live_preview.png
\li Select the \inlineimage icons/live_preview.png
(\uicontrol {Show Live Preview}) button to preview the example.
\endlist
@@ -168,7 +168,7 @@
We can now start playing with the particle system component properties to
achieve the artistic effect that we want. To see how the changes in property
values affect the simulation, we will open the live preview by selecting
\inlineimage live_preview.png
\inlineimage icons/live_preview.png
on the main toolbar (or by pressing \key {Alt+P}).
First, we will specify property values for the \uicontrol {Particle System}
@@ -183,7 +183,7 @@
\li \key Ctrl+W (\key Cmd+W on \macos)
\li
\row
\li \inlineimage live_preview.png
\li \inlineimage icons/live_preview.png
\li \uicontrol {Show Live Preview} shows a preview of the current file
or the entire UI. The changes you make to the UI are instantly
visible to you in the preview.
@@ -210,13 +210,13 @@
\li
\li
\row
\li \inlineimage qtcreator-reset-position-icon.png
\li \inlineimage icons/qtcreator-reset-position-icon.png
\li Returns a component to its \e {implicit position} after
being moved.
\li \key Ctrl+D (\key Cmd+D on \macos)
\li \l{Resetting Component Position and Size}
\row
\li \inlineimage qtcreator-reset-size-icon.png
\li \inlineimage icons/qtcreator-reset-size-icon.png
\li Returns a component to its implicit size after it was scaled.
\li \key Shift+S
\li \l{Resetting Component Position and Size}
@@ -110,7 +110,7 @@
To attach easing curves to transitions:
\list 1
\li In \l{Transition Editor}, select the \inlineimage curve_editor.png
\li In \l{Transition Editor}, select the \inlineimage icons/curve_editor.png
(\uicontrol {Easing Curve Editor}) button.
\li Select an easing curve, as described in \l{Selecting Easing Curves}.
\endlist
@@ -122,7 +122,7 @@
\list 1
\li In \l Navigator, select an \l{Animations}{Animation} component
instance.
\li In \l Properties, select the \inlineimage curve_editor.png
\li In \l Properties, select the \inlineimage icons/curve_editor.png
(\uicontrol {Easing Curve Editor}) button.
\li Select an easing curve, as described in \l{Selecting Easing Curves}.
\endlist
@@ -58,16 +58,16 @@
\li Tooltip
\li Read More
\row
\li \inlineimage no_snapping.png
\li \inlineimage icons/no_snapping.png
\li Disables snapping.
\li \l{Snapping to Parent and Sibling Components}
\row
\li \inlineimage snapping_and_anchoring.png
\li \inlineimage icons/snapping_and_anchoring.png
\li Anchors the component instance to the component instances that it
is snapped to.
\li \l{Snapping to Parent and Sibling Components}
\row
\li \inlineimage snapping.png
\li \inlineimage icons/snapping.png
\li Snaps component instances to their parent or siblings when you
align them.
\li \l{Snapping to Parent and Sibling Components}
@@ -171,10 +171,10 @@
\section1 Snapping to Parent and Sibling Components
You can use snapping to align component instances in
\uicontrol {Form Editor}. Select the \inlineimage snapping.png
\uicontrol {Form Editor}. Select the \inlineimage icons/snapping.png
button to have the component instances snap to their parent or siblings.
Snapping lines automatically appear to help you position the component
instances. Click the \inlineimage snapping_and_anchoring.png
instances. Click the \inlineimage icons/snapping_and_anchoring.png
button to anchor the selected component instance to those that you snap to.
Only one snapping button can be selected at the time. Selecting
one snapping button automatically deselects the others.
@@ -68,12 +68,12 @@
\li Tooltip
\li Read More
\row
\li \inlineimage arrowleft.png
\li \inlineimage icons/arrowleft.png
\li Moves the component one level up in the component tree, so that
it becomes the last sibling of its current parent.
\li \l{Arranging Components}
\row
\li \inlineimage arrowright.png
\li \inlineimage icons/arrowright.png
\li Moves the component one level down in the component tree, so that it
becomes the child of its last sibling.
\li \l{Arranging Components}
@@ -112,10 +112,10 @@
\section2 Resetting Component Position and Size
To return a component to its default position after moving it,
select the \inlineimage qtcreator-reset-position-icon.png
select the \inlineimage icons/qtcreator-reset-position-icon.png
(\uicontrol {Reset Position}) button on the \l{Design Views}
{Design mode toolbar}. To return it to its default size, select
\inlineimage qtcreator-reset-size-icon.png
\inlineimage icons/qtcreator-reset-size-icon.png
(\uicontrol {Reset Size}) button.
\section2 Managing 2D Transformations
@@ -59,7 +59,7 @@
\image studio-timeline-with-empty-tracks.png "Timeline view with a property"
You can now select \inlineimage local_record_keyframes.png
You can now select \inlineimage icons/local_record_keyframes.png
to \l{Setting Keyframe Values}{record changes} in component properties
while you \l{Navigating in Timeline}{navigate the timeline}.
@@ -99,8 +99,8 @@
\section1 Zooming in Timeline
Use the slider on the toolbar to set the zooming level in the
\uicontrol Timeline view. Select the \inlineimage zoom_small.png
and \inlineimage zoom_big.png
\uicontrol Timeline view. Select the \inlineimage icons/zoom_small.png
and \inlineimage icons/zoom_big.png
buttons to zoom out of or into the view.
\section1 Setting Keyframe Track Color
@@ -121,7 +121,7 @@
\li Action
\li Read More
\row
\li \inlineimage animation.png
\li \inlineimage icons/animation.png
\li Opens the \uicontrol {Timeline Settings} dialog for editing
timeline settings.
\li \l{Creating Timelines}
@@ -130,25 +130,25 @@
\li Displays the ID of the current timeline.
\li \l{Creating Timelines}
\row
\li \inlineimage to_first_frame.png
\li \inlineimage icons/to_first_frame.png
\li \uicontrol {To Start (Home)} moves to the first frame on the
timeline.
\li \l{Navigating in Timeline}
\row
\li \inlineimage back_one_frame.png
\li \inlineimage icons/back_one_frame.png
\li \uicontrol {Previous (,)} moves to the previous frame on the
timeline.
\li \l{Navigating in Timeline}
\row
\li \inlineimage start_playback.png
\li \inlineimage icons/start_playback.png
\li \uicontrol {Play (Space)} previews the animation.
\li \l{Viewing the Animation}
\row
\li \inlineimage forward_one_frame.png
\li \inlineimage icons/forward_one_frame.png
\li \uicontrol {Next (.)} moves to the next frame on the timeline.
\li \l{Navigating in Timeline}
\row
\li \inlineimage to_last_frame.png
\li \inlineimage icons/to_last_frame.png
\li \uicontrol {To End (End)} moves to the last frame on the timeline.
\li \l{Navigating in Timeline}
\row
@@ -157,11 +157,11 @@
number in the field to move the playhead to the respective frame.
\li \l{Navigating in Timeline}
\row
\li \inlineimage global_record_keyframes.png
\li \inlineimage icons/global_record_keyframes.png
\li Records changes in keyframe values.
\li \l {Setting Keyframe Values}
\row
\li \inlineimage curve_editor.png
\li \inlineimage icons/curve_editor.png
\li Opens \uicontrol {Easing Curve Editor} for attaching an easing
curve to the selected transition.
\li \l{Editing Easing Curves}
@@ -172,7 +172,7 @@
determines the duration of the animation.
\li \l{Creating Timelines}
\row
\li \inlineimage zoom_small.png
\li \inlineimage icons/zoom_small.png
\li \uicontrol {Zoom Out} (\key Ctrl+-) zooms out of the view.
\li \l{Zooming in Timeline}
\row
@@ -180,7 +180,7 @@
\li Sets the zooming level.
\li \l{Zooming in Timeline}
\row
\li \inlineimage zoom_big.png
\li \inlineimage icons/zoom_big.png
\li \uicontrol {Zoom In} (\key Ctrl++) zooms into the view.
\li \l{Zooming in Timeline}
\row
@@ -206,20 +206,20 @@
\li Action
\li Read More
\row
\li \inlineimage previous_keyframe.png
\li \inlineimage icons/previous_keyframe.png
\li Jumps to the previous frame on the timeline.
\li \l{Setting Keyframe Values}
\row
\li \inlineimage next_keyframe.png
\li \inlineimage icons/next_keyframe.png
\li Jumps to the next frame on the timeline.
\li \l{Setting Keyframe Values}
\row
\li \inlineimage local_record_keyframes.png
\li \inlineimage icons/local_record_keyframes.png
\li Records changes in keyframe values for a particular property.
\li \l {Setting Keyframe Values}
\target keyframe_marker
\row
\li \inlineimage keyframe.png
\li \inlineimage icons/keyframe.png
\li Indicates the type of easing curve attached to the keyframe.
When a keyframe track is selected, the keyframe markers on it turn
gray, and when a keyframe itself is selected, its marker turns
@@ -94,7 +94,7 @@
frames or for running the animation backwards from the last frame to the
first.
To modify the settings, select the \inlineimage animation.png
To modify the settings, select the \inlineimage icons/animation.png
(\uicontrol {Timeline Settings (S)}) button on the \l{Timeline Toolbar}
{toolbar} (or press \key S) in the \l Timeline view.
@@ -119,7 +119,7 @@
You can insert keyframes for all the properties of all the components that
you want to animate first, and then record the changes in their values by
selecting the \inlineimage local_record_keyframes.png
selecting the \inlineimage icons/local_record_keyframes.png
(\uicontrol {Per Property Recording}) button for one property at a time.
For example, you can hide and show components by turning their visibility
off and on or by setting their opacity to 0 or 1.
@@ -194,7 +194,7 @@
To preview the animation, select the \uicontrol {Play (Space)}
button or press \key Space. To preview the whole UI, select the
\inlineimage live_preview.png
\inlineimage icons/live_preview.png
(\uicontrol {Show Live Preview}) button on the canvas toolbar
or press \key {Alt+P}.
@@ -49,8 +49,8 @@
\section1 Zooming in Transition Editor
Use the slider on the toolbar to set the zooming level in
\uicontrol {Transition Editor}. Select the \inlineimage zoom_small.png
and \inlineimage zoom_big.png
\uicontrol {Transition Editor}. Select the \inlineimage icons/zoom_small.png
and \inlineimage icons/zoom_big.png
buttons to zoom out of or into the view.
\section1 Summary of Transition Editor Toolbar Actions
@@ -61,7 +61,7 @@
\li Action
\li Read More
\row
\li \inlineimage animation.png
\li \inlineimage icons/animation.png
\li Opens \uicontrol {Transition Settings} dialog for editing
transition settings.
\li \l{Specifying Transition Settings}
@@ -71,12 +71,12 @@
\uicontrol {Transition Editor}.
\li \l{Animating Transitions Between States}
\row
\li \inlineimage curve_editor.png
\li \inlineimage icons/curve_editor.png
\li Opens \uicontrol {Easing Curve Editor} for attaching an easing
curve to the selected transition.
\li \l{Editing Easing Curves}
\row
\li \inlineimage zoom_small.png
\li \inlineimage icons/zoom_small.png
\li \uicontrol {Zoom Out} (\key Ctrl+-): zooms out of the view.
\li \l{Zooming in Transition Editor}
\row
@@ -84,7 +84,7 @@
\li Sets the zooming level.
\li \l{Zooming in Transition Editor}
\row
\li \inlineimage zoom_big.png
\li \inlineimage icons/zoom_big.png
\li \uicontrol {Zoom In} (\key Ctrl++): zooms into the view.
\li \l{Zooming in Transition Editor}
\row
@@ -110,13 +110,13 @@
the start and end frame of the animation of the property. Pull its
left and right edges to set the duration of the animation.
\li To attach an \l{Editing Easing Curves}{easing curve} to the
selected transition, select the \inlineimage curve_editor.png
selected transition, select the \inlineimage icons/curve_editor.png
(\uicontrol {Easing Curve Editor (C)}) button.
\endlist
\section1 Specifying Transition Settings
To modify transition settings, select the \inlineimage animation.png
To modify transition settings, select the \inlineimage icons/animation.png
(\uicontrol {Transition Settings (S)}) button in
\uicontrol {Transition Editor}.
+4
View File
@@ -109,6 +109,10 @@ def build(args, paths):
# TODO this works around a CMake bug https://gitlab.kitware.com/cmake/cmake/issues/20119
cmake_args += ['-DBUILD_WITH_PCH=OFF']
# work around QTBUG-89754
# Qt otherwise adds dependencies on libGLX and libOpenGL
cmake_args += ['-DOpenGL_GL_PREFERENCE=LEGACY']
if args.with_docs:
cmake_args += ['-DWITH_DOCS=ON']
@@ -77,33 +77,8 @@ Item {
boundsBehavior: Flickable.StopAtBounds
clip: true
ScrollBar.vertical: ScrollBar {
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
implicitContentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
implicitContentHeight + topPadding + bottomPadding)
property bool scrollBarVisible: parent.childrenRect.height > parent.height
minimumSize: orientation == Qt.Horizontal ? height / width : width / height
orientation: Qt.Vertical
policy: scrollBarVisible ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
x: parent.width - width
y: 0
height: parent.availableHeight
- (parent.bothVisible ? parent.horizontalThickness : 0)
padding: 0
background: Rectangle {
color: StudioTheme.Values.themeScrollBarTrack
}
contentItem: Rectangle {
implicitWidth: StudioTheme.Values.scrollBarThickness
color: StudioTheme.Values.themeScrollBarHandle
}
} // ScrollBar
ScrollBar.vertical: SC.VerticalScrollBar {
}
Column {
id: scrollContent
@@ -30,6 +30,7 @@ import QtQuick
import QtQuick.Layouts
import StudioControls as SC
import StudioTheme as StudioTheme
Item {
width: DialogValues.stylesPaneWidth
@@ -55,8 +56,8 @@ Item {
radius: 6
Item {
x: DialogValues.stylesPanePadding // left padding
width: parent.width - DialogValues.stylesPanePadding * 2 // right padding
x: DialogValues.stylesPanePadding
width: parent.width - DialogValues.stylesPanePadding * 2 + styleScrollBar.width
height: parent.height
ColumnLayout {
@@ -100,6 +101,8 @@ Item {
}
} // Style Filter ComboBox
Item { implicitWidth: 1; implicitHeight: 9 }
ListView {
id: stylesList
Layout.fillWidth: true
@@ -107,11 +110,26 @@ Item {
clip: true
model: styleModel
MouseArea {
id: listViewMouseArea
anchors.fill: parent
hoverEnabled: true
propagateComposedEvents: true
}
focus: true
boundsBehavior: Flickable.StopAtBounds
highlightFollowsCurrentItem: false
ScrollBar.vertical: SC.VerticalScrollBar {
id: styleScrollBar
property int extraPadding: 0
bottomInset: extraPadding
bottomPadding: bottomInset + 16
viewMouseArea: listViewMouseArea
} // ScrollBar
onCurrentIndexChanged: {
if (styleModel.rowCount() > 0)
dialogBox.styleIndex = stylesList.currentIndex;
@@ -120,7 +138,11 @@ Item {
delegate: ItemDelegate {
id: delegateId
height: styleImage.height + DialogValues.styleImageBorderWidth + styleText.height + extraPadding.height + 1
width: stylesList.width
width: stylesList.width - styleScrollBar.width
Component.onCompleted: {
styleScrollBar.extraPadding = styleText.height + extraPadding.height
}
Rectangle {
anchors.fill: parent
@@ -37,7 +37,12 @@ Row {
property variant backendValue
property color textColor: colorLogic.highlight ? colorLogic.textColor
: StudioTheme.Values.themeTextColor
property string filter: "*.png *.gif *.jpg *.bmp *.jpeg *.svg *.pbm *.pgm *.ppm *.xbm *.xpm *.hdr *.webp"
property string filter: "*.png *.gif *.jpg *.bmp *.jpeg *.svg *.pbm *.pgm *.ppm *.xbm *.xpm *.hdr *.ktx *.webp"
// This property takes an array of strings which define default items that should be added
// to the ComboBox model in addition to the items from the FileResourcesModel. This is used
// by QtQuick3D to add built-in primitives to the model.
property var defaultItems
FileResourcesModel {
id: fileModel
@@ -53,6 +58,8 @@ Row {
StudioControls.ComboBox {
id: comboBox
property ListModel items: ListModel {}
implicitWidth: StudioTheme.Values.singleControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth
width: implicitWidth
@@ -62,7 +69,7 @@ Row {
ToolTip {
id: toolTip
visible: comboBox.hovered && toolTip.text !== ""
visible: comboBox.hover && toolTip.text !== ""
text: urlChooser.backendValue.valueToString
delay: StudioTheme.Values.toolTipDelay
height: StudioTheme.Values.toolTipHeight
@@ -79,6 +86,10 @@ Row {
}
delegate: ItemDelegate {
required property string fullPath
required property string name
required property int index
id: delegateItem
width: parent.width
height: StudioTheme.Values.height - 2 * StudioTheme.Values.border
@@ -107,7 +118,7 @@ Row {
contentItem: Text {
leftPadding: itemDelegateIconArea.width
text: modelData
text: name
color: delegateItem.highlighted ? StudioTheme.Values.themeTextSelectedTextColor
: StudioTheme.Values.themeTextColor
font: comboBox.font
@@ -127,7 +138,7 @@ Row {
ToolTip {
id: itemToolTip
visible: delegateItem.hovered && comboBox.highlightedIndex === index
text: fileModel.fullPathModel[index]
text: fullPath
delay: StudioTheme.Values.toolTipDelay
height: StudioTheme.Values.toolTipHeight
background: Rectangle {
@@ -151,6 +162,7 @@ Row {
ExtendedFunctionLogic {
id: extFuncLogic
backendValue: urlChooser.backendValue
onReseted: comboBox.editText = ""
}
property bool isComplete: false
@@ -161,26 +173,27 @@ Row {
function setCurrentText(text) {
var index = comboBox.find(text)
if (index === -1)
currentIndex = -1
comboBox.currentIndex = -1
comboBox.editText = text
comboBox.dirty = false
}
// Takes into account applied bindings
property string textValue: {
if (urlChooser.backendValue.isBound)
return urlChooser.backendValue.expression
var fullPath = urlChooser.backendValue.valueToString;
var fileName = fullPath.substr(fullPath.lastIndexOf('/') + 1);
return fileName;
var fullPath = urlChooser.backendValue.valueToString
return fullPath.substr(fullPath.lastIndexOf('/') + 1)
}
onTextValueChanged: comboBox.setCurrentText(comboBox.textValue)
editable: true
model: fileModel.fileNameModel
textRole: "name"
valueRole: "fullPath"
model: comboBox.items
onModelChanged: {
if (!comboBox.isComplete)
@@ -193,8 +206,20 @@ Row {
if (!comboBox.isComplete)
return
if (comboBox.backendValue.value !== comboBox.editText)
comboBox.backendValue.value = comboBox.editText
var inputValue = comboBox.editText
// Check if value set by user matches with a name in the model then pick the full path
var index = comboBox.find(inputValue)
if (index !== -1)
inputValue = comboBox.items.get(index).fullPath
// Get the currently assigned backend value, extract its file name and compare it to the
// input value. If they differ the new value needs to be set.
var currentValue = urlChooser.backendValue.value
var fileName = currentValue.substr(currentValue.lastIndexOf('/') + 1);
if (fileName !== inputValue)
urlChooser.backendValue.value = inputValue
comboBox.dirty = false
}
@@ -204,20 +229,19 @@ Row {
comboBox.handleActivate(comboBox.currentIndex)
}
onCompressedActivated: comboBox.handleActivate(index)
onCompressedActivated: function (index) {
comboBox.handleActivate(index)
}
function handleActivate(index) {
if (urlChooser.backendValue === undefined)
return
if (!comboBox.isComplete)
if (urlChooser.backendValue === undefined || !comboBox.isComplete)
return
if (index === -1) // select first item if index is invalid
index = 0
if (urlChooser.backendValue.value !== fileModel.fullPathModel[index])
urlChooser.backendValue.value = fileModel.fullPathModel[index]
if (urlChooser.backendValue.value !== comboBox.items.get(index).fullPath)
urlChooser.backendValue.value = comboBox.items.get(index).fullPath
comboBox.dirty = false
}
@@ -235,16 +259,60 @@ Row {
}
}
function createModel() {
// Build the combobox model
comboBox.items.clear()
for (var i = 0; i < urlChooser.defaultItems.length; ++i) {
comboBox.items.append({
fullPath: urlChooser.defaultItems[i],
name: urlChooser.defaultItems[i]
})
}
for (var j = 0; j < fileModel.fullPathModel.length; ++j) {
comboBox.items.append({
fullPath: fileModel.fullPathModel[j],
name: fileModel.fileNameModel[j]
})
}
}
Connections {
target: fileModel
function onFullPathModelChanged() {
urlChooser.createModel()
comboBox.setCurrentText(comboBox.textValue)
}
}
onDefaultItemsChanged: urlChooser.createModel()
Component.onCompleted: urlChooser.createModel()
function indexOf(model, criteria) {
for (var i = 0; i < model.count; ++i) {
if (criteria(model.get(i)))
return i
}
return -1
}
Connections {
target: comboBox
function onStateChanged(state) {
// update currentIndex when the popup opens to override the default behavior in super classes
// that selects currentIndex based on values in the combo box.
if (comboBox.popup.opened) {
var index = fileModel.fullPathModel.indexOf(urlChooser.backendValue.value)
if (comboBox.popup.opened && !urlChooser.backendValue.isBound) {
var index = urlChooser.indexOf(comboBox.items,
function(item) {
return item.fullPath === urlChooser.backendValue.value
})
if (index !== -1) {
comboBox.currentIndex = index
comboBox.hoverIndex = index
comboBox.editText = comboBox.items.get(index).name
}
}
}
@@ -80,6 +80,9 @@ T.ComboBox {
text: myComboBox.editText
onEditingFinished: {
comboBoxInput.deselect()
comboBoxInput.focus = false
// Only trigger the signal, if the value was modified
if (myComboBox.dirty) {
myTimer.stop()
@@ -0,0 +1,71 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.15
import QtQuick.Controls 2.15
import StudioTheme 1.0 as StudioTheme
ScrollBar {
id: scrollBar
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
implicitContentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
implicitContentHeight + topPadding + bottomPadding)
property bool scrollBarVisible: parent.childrenRect.height > parent.height
// viewMouseArea: if set, the scrollbar will be visible only on hover over the view containing
// the mouse area item.
property MouseArea viewMouseArea: null
minimumSize: orientation == Qt.Horizontal ? height / width : width / height
orientation: Qt.Vertical
policy: computePolicy()
x: parent.width - width
y: 0
height: parent.availableHeight
- (parent.bothVisible ? parent.horizontalThickness : 0)
padding: 0
background: Rectangle {
color: StudioTheme.Values.themeScrollBarTrack
}
contentItem: Rectangle {
implicitWidth: StudioTheme.Values.scrollBarThickness
color: StudioTheme.Values.themeScrollBarHandle
}
function computePolicy() {
if (!scrollBar.scrollBarVisible)
return ScrollBar.AlwaysOff;
if (scrollBar.viewMouseArea)
return scrollBar.viewMouseArea.containsMouse ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
else
return ScrollBar.AlwaysOn;
}
}
@@ -38,3 +38,4 @@ TabButton 1.0 TabButton.qml
TextArea 1.0 TextArea.qml
TextField 1.0 TextField.qml
TranslationIndicator 1.0 TranslationIndicator.qml
VerticalScrollBar 1.0 VerticalScrollBar.qml
@@ -205,6 +205,8 @@ QtObject {
// Theme Colors
property bool isLightTheme: themeControlBackground.hsvValue > themeTextColor.hsvValue
property string themePanelBackground: Theme.color(Theme.DSpanelBackground)
property string themeInteraction: Theme.color(Theme.DSinteraction)
@@ -215,7 +217,7 @@ QtObject {
property string themeAliasIconChecked: Theme.color(Theme.DSnavigatorAliasIconChecked)
// Control colors
property string themeControlBackground: Theme.color(Theme.DScontrolBackground)
property color themeControlBackground: Theme.color(Theme.DScontrolBackground)
property string themeControlBackgroundInteraction: Theme.color(Theme.DScontrolBackgroundInteraction)
property string themeControlBackgroundDisabled: Theme.color(Theme.DScontrolBackgroundDisabled)
property string themeControlBackgroundGlobalHover: Theme.color(Theme.DScontrolBackgroundGlobalHover)
@@ -230,7 +232,7 @@ QtObject {
property string themeBackgroundColorAlternate: Theme.color(Theme.DSBackgroundColorAlternate)
// Text colors
property string themeTextColor: Theme.color(Theme.DStextColor)
property color themeTextColor: Theme.color(Theme.DStextColor)
property string themeTextColorDisabled: Theme.color(Theme.DStextColorDisabled)
property string themeTextSelectionColor: Theme.color(Theme.DStextSelectionColor)
property string themeTextSelectedTextColor: Theme.color(Theme.DStextSelectedTextColor)
+11 -13
View File
@@ -36,8 +36,6 @@
#include <QProcess>
#include <QThread>
using namespace Utils;
namespace ClangBackEnd {
ConnectionClient::ConnectionClient(const QString &connectionName)
@@ -161,7 +159,7 @@ void ConnectionClient::restartProcessIfTimerIsNotResettedAndSocketIsEmpty()
restartProcessAsynchronously();
}
void ConnectionClient::endProcess(QtcProcess *process)
void ConnectionClient::endProcess(QProcess *process)
{
if (isProcessRunning(process) && isConnected()) {
sendEndMessage();
@@ -169,15 +167,15 @@ void ConnectionClient::endProcess(QtcProcess *process)
}
}
void ConnectionClient::terminateProcess(QtcProcess *process)
void ConnectionClient::terminateProcess(QProcess *process)
{
if (!HostOsInfo::isWindowsHost() && isProcessRunning()) {
if (!Utils::HostOsInfo::isWindowsHost() && isProcessRunning()) {
process->terminate();
process->waitForFinished(1000);
}
}
void ConnectionClient::killProcess(QtcProcess *process)
void ConnectionClient::killProcess(QProcess *process)
{
if (isProcessRunning(process)) {
process->kill();
@@ -215,7 +213,7 @@ void ConnectionClient::resetTemporaryDirectory()
m_processCreator.resetTemporaryDirectory();
}
void ConnectionClient::initializeProcess(QtcProcess *process)
void ConnectionClient::initializeProcess(QProcess *process)
{
connectStandardOutputAndError(process);
@@ -301,7 +299,7 @@ bool ConnectionClient::waitForConnected()
}
QtcProcess *ConnectionClient::processForTestOnly()
QProcess *ConnectionClient::processForTestOnly()
{
getProcessFromFuture();
@@ -313,15 +311,15 @@ QIODevice *ConnectionClient::ioDevice()
return m_localSocket;
}
bool ConnectionClient::isProcessRunning(QtcProcess *process)
bool ConnectionClient::isProcessRunning(QProcess *process)
{
return process && process->isRunning();
return process && process->state() == QProcess::Running;
}
void ConnectionClient::connectStandardOutputAndError(QtcProcess *process) const
void ConnectionClient::connectStandardOutputAndError(QProcess *process) const
{
connect(process, &QtcProcess::readyReadStandardOutput, this, &ConnectionClient::printStandardOutput);
connect(process, &QtcProcess::readyReadStandardError, this, &ConnectionClient::printStandardError);
connect(process, &QProcess::readyReadStandardOutput, this, &ConnectionClient::printStandardOutput);
connect(process, &QProcess::readyReadStandardError, this, &ConnectionClient::printStandardError);
}
void ConnectionClient::connectLocalSocketError() const
+10 -9
View File
@@ -28,7 +28,6 @@
#include "clangcodemodelserverproxy.h"
#include "lineprefixer.h"
#include "processcreator.h"
#include "processhandle.h"
#include <QLocalServer>
#include <QLocalSocket>
@@ -38,7 +37,9 @@
#include <future>
#include <memory>
namespace Utils { class QtcProcess; }
QT_BEGIN_NAMESPACE
class QProcess;
QT_END_NAMESPACE
class Utf8String;
class Utf8StringVector;
@@ -76,7 +77,7 @@ public:
bool waitForEcho();
bool waitForConnected();
Utils::QtcProcess *processForTestOnly();
QProcess *processForTestOnly();
signals:
void connectedToLocalSocket();
@@ -102,22 +103,22 @@ protected:
virtual void newConnectedServer(QLocalSocket *localSocket) = 0;
private:
static bool isProcessRunning(Utils::QtcProcess *process);
static bool isProcessRunning(QProcess *process);
void finishProcess(QProcessUniquePointer &&process);
void endProcess(Utils::QtcProcess *process);
void terminateProcess(Utils::QtcProcess *process);
void killProcess(Utils::QtcProcess *process);
void endProcess(QProcess *process);
void terminateProcess(QProcess *process);
void killProcess(QProcess *process);
void finishConnection();
void printLocalSocketError(QLocalSocket::LocalSocketError socketError);
void printStandardOutput();
void printStandardError();
void initializeProcess(Utils::QtcProcess *process);
void initializeProcess(QProcess *process);
void resetTemporaryDirectory();
void connectLocalSocketDisconnected();
void disconnectLocalSocketDisconnected();
void connectStandardOutputAndError(Utils::QtcProcess *process) const;
void connectStandardOutputAndError(QProcess *process) const;
void connectLocalSocketError() const;
void connectAliveTimer();
void connectNewConnection();
+15 -21
View File
@@ -28,15 +28,10 @@
#include "processexception.h"
#include "processstartedevent.h"
#include <utils/commandline.h>
#include <utils/qtcprocess.h>
#include <QCoreApplication>
#include <QFileInfo>
#include <QTemporaryDir>
using namespace Utils;
namespace ClangBackEnd {
using namespace std::chrono_literals;
@@ -61,7 +56,7 @@ void ProcessCreator::setArguments(const QStringList &arguments)
m_arguments = arguments;
}
void ProcessCreator::setEnvironment(const Environment &environment)
void ProcessCreator::setEnvironment(const Utils::Environment &environment)
{
m_environment = environment;
}
@@ -70,11 +65,10 @@ std::future<QProcessUniquePointer> ProcessCreator::createProcess() const
{
return std::async(std::launch::async, [&] {
checkIfProcessPathExists();
auto process = QProcessUniquePointer(new QtcProcess(ProcessMode::Writer));
process->setProcessChannelMode(QProcess::ForwardedChannels);
process->setEnvironment(processEnvironment());
process->setCommand(CommandLine(FilePath::fromString(m_processPath), m_arguments));
process->start();
auto process = QProcessUniquePointer(new QProcess);
process->setProcessChannelMode(QProcess::QProcess::ForwardedChannels);
process->setProcessEnvironment(processEnvironment());
process->start(m_processPath, m_arguments);
process->waitForStarted(5000);
checkIfProcessWasStartingSuccessful(process.get());
@@ -101,13 +95,13 @@ void ProcessCreator::checkIfProcessPathExists() const
}
}
void ProcessCreator::checkIfProcessWasStartingSuccessful(QtcProcess *process) const
void ProcessCreator::checkIfProcessWasStartingSuccessful(QProcess *process) const
{
if (process->exitStatus() == QProcess::CrashExit || process->exitCode() != 0)
dispatchProcessError(process);
}
void ProcessCreator::dispatchProcessError(QtcProcess *process) const
void ProcessCreator::dispatchProcessError(QProcess *process) const
{
switch (process->error()) {
case QProcess::UnknownError: {
@@ -164,24 +158,24 @@ const QTemporaryDir &ProcessCreator::temporaryDirectory() const
void ProcessCreator::resetTemporaryDirectory()
{
m_temporaryDirectory = std::make_unique<TemporaryDirectory>(m_temporaryDirectoryPattern);
m_temporaryDirectory = std::make_unique<Utils::TemporaryDirectory>(m_temporaryDirectoryPattern);
}
Environment ProcessCreator::processEnvironment() const
QProcessEnvironment ProcessCreator::processEnvironment() const
{
auto processEnvironment = Environment::systemEnvironment();
auto processEnvironment = QProcessEnvironment::systemEnvironment();
if (temporaryDirectory().isValid()) {
const QString temporaryDirectoryPath = temporaryDirectory().path();
processEnvironment.appendOrSet("TMPDIR", temporaryDirectoryPath);
processEnvironment.appendOrSet("TMP", temporaryDirectoryPath);
processEnvironment.appendOrSet("TEMP", temporaryDirectoryPath);
processEnvironment.insert("TMPDIR", temporaryDirectoryPath);
processEnvironment.insert("TMP", temporaryDirectoryPath);
processEnvironment.insert("TEMP", temporaryDirectoryPath);
}
const Environment &env = m_environment;
const Utils::Environment &env = m_environment;
for (auto it = env.constBegin(); it != env.constEnd(); ++it) {
if (env.isEnabled(it))
processEnvironment.appendOrSet(env.key(it), env.expandedValueForKey(env.key(it)));
processEnvironment.insert(env.key(it), env.expandedValueForKey(env.key(it)));
}
return processEnvironment;
+4 -8
View File
@@ -39,13 +39,9 @@
QT_BEGIN_NAMESPACE
class QTemporaryDir;
class QProcessEnvironment;
QT_END_NAMESPACE
namespace Utils {
class Environment;
class QtcProcess;
}
namespace ClangBackEnd {
class CLANGSUPPORT_EXPORT ProcessCreator
@@ -66,12 +62,12 @@ public:
private:
void checkIfProcessPathExists() const;
void checkIfProcessWasStartingSuccessful(Utils::QtcProcess *process) const;
[[noreturn]] void dispatchProcessError(Utils::QtcProcess *process) const;
void checkIfProcessWasStartingSuccessful(QProcess *process) const;
[[noreturn]] void dispatchProcessError(QProcess *process) const;
void postProcessStartedEvent() const;
[[noreturn]] void throwProcessException(const QString &message) const;
Utils::Environment processEnvironment() const;
QProcessEnvironment processEnvironment() const;
private:
std::unique_ptr<Utils::TemporaryDirectory> m_temporaryDirectory;
+3 -3
View File
@@ -25,7 +25,7 @@
#pragma once
#include <utils/qtcprocess.h>
#include <QProcess>
#include <memory>
@@ -34,7 +34,7 @@ namespace ClangBackEnd {
class QProcessUniquePointerDeleter
{
public:
void operator()(Utils::QtcProcess* process)
void operator()(QProcess* process)
{
process->kill();
process->waitForFinished();
@@ -42,6 +42,6 @@ public:
}
};
using QProcessUniquePointer = std::unique_ptr<Utils::QtcProcess, QProcessUniquePointerDeleter>;
using QProcessUniquePointer = std::unique_ptr<QProcess, QProcessUniquePointerDeleter>;
} // namespace ClangBackEnd
@@ -71,16 +71,16 @@ public:
signals:
void beginResetAllDiagrams();
void endResetAllDiagrams();
void beginResetDiagram(const MDiagram *diagram);
void endResetDiagram(const MDiagram *diagram);
void beginUpdateElement(int row, const MDiagram *diagram);
void endUpdateElement(int row, const MDiagram *diagram);
void beginInsertElement(int row, const MDiagram *diagram);
void endInsertElement(int row, const MDiagram *diagram);
void beginRemoveElement(int row, const MDiagram *diagram);
void endRemoveElement(int row, const MDiagram *diagram);
void modified(const MDiagram *diagram);
void diagramAboutToBeRemoved(const MDiagram *diagram);
void beginResetDiagram(const qmt::MDiagram *diagram);
void endResetDiagram(const qmt::MDiagram *diagram);
void beginUpdateElement(int row, const qmt::MDiagram *diagram);
void endUpdateElement(int row, const qmt::MDiagram *diagram);
void beginInsertElement(int row, const qmt::MDiagram *diagram);
void endInsertElement(int row, const qmt::MDiagram *diagram);
void beginRemoveElement(int row, const qmt::MDiagram *diagram);
void endRemoveElement(int row, const qmt::MDiagram *diagram);
void modified(const qmt::MDiagram *diagram);
void diagramAboutToBeRemoved(const qmt::MDiagram *diagram);
public:
ModelController *modelController() const { return m_modelController; }
@@ -80,8 +80,8 @@ public:
~DiagramSceneModel() override;
signals:
void diagramSceneActivated(const MDiagram *diagram);
void selectionHasChanged(const MDiagram *diagram);
void diagramSceneActivated(const qmt::MDiagram *diagram);
void selectionHasChanged(const qmt::MDiagram *diagram);
void sceneRectChanged(const QRectF &sceneRect);
public:
@@ -61,8 +61,8 @@ public:
signals:
void someDiagramOpened(bool);
void diagramActivated(const MDiagram *diagram);
void diagramSelectionChanged(const MDiagram *diagram);
void diagramActivated(const qmt::MDiagram *diagram);
void diagramSelectionChanged(const qmt::MDiagram *diagram);
public:
void setModel(TreeModel *model);
@@ -50,8 +50,8 @@ public:
~DiagramsView() override;
signals:
void currentDiagramChanged(const MDiagram *diagram);
void diagramCloseRequested(const MDiagram *diagram);
void currentDiagramChanged(const qmt::MDiagram *diagram);
void diagramCloseRequested(const qmt::MDiagram *diagram);
void someDiagramOpened(bool);
public:
@@ -49,8 +49,8 @@ public:
~StackedDiagramsView() override;
signals:
void currentDiagramChanged(const MDiagram *diagram);
void diagramCloseRequested(const MDiagram *diagram);
void currentDiagramChanged(const qmt::MDiagram *diagram);
void diagramCloseRequested(const qmt::MDiagram *diagram);
void someDiagramOpened(bool);
public:
@@ -72,3 +72,6 @@ private:
};
} // namespace qmt
Q_DECLARE_METATYPE(qmt::MDiagram *)
Q_DECLARE_METATYPE(const qmt::MDiagram *)
@@ -72,8 +72,8 @@ public:
~DiagramSceneController() override;
signals:
void newElementCreated(DElement *element, MDiagram *diagram);
void elementAdded(DElement *element, MDiagram *diagram);
void newElementCreated(DElement *element, qmt::MDiagram *diagram);
void elementAdded(DElement *element, qmt::MDiagram *diagram);
public:
ModelController *modelController() const { return m_modelController; }
-1
View File
@@ -4,7 +4,6 @@ VPATH += $$PWD
SOURCES += \
columndefinition.cpp \
createtablecommand.cpp \
createtablesqlstatementbuilder.cpp \
sqlitedatabasebackend.cpp \
sqlitedatabaseconnection.cpp \
sqlitedatabaseconnectionproxy.cpp \
+6
View File
@@ -40,6 +40,12 @@ public:
return first.value == second.value;
}
friend bool operator!=(TimeStamp first, TimeStamp second) { return !(first == second); }
bool isValid() const { return value >= 0; }
long long operator*() { return value; }
public:
long long value = -1;
};
+2
View File
@@ -39,6 +39,7 @@ namespace Utils {
using std::get;
using std::get_if;
using std::holds_alternative;
using std::monostate;
using std::variant;
using std::variant_alternative_t;
using std::visit;
@@ -51,6 +52,7 @@ namespace Utils {
using mpark::get;
using mpark::get_if;
using mpark::holds_alternative;
using mpark::monostate;
using mpark::variant;
using mpark::variant_alternative_t;
using mpark::visit;
@@ -34,7 +34,8 @@
#include "uicontroller.h"
#include "actionhandler.h"
#include "qmt/infrastructure/uid.h"
#include <qmt/infrastructure/uid.h>
#include <qmt/model/mdiagram.h>
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
@@ -70,6 +71,8 @@ ModelEditorPlugin::ModelEditorPlugin()
pluginInstance = this;
qRegisterMetaType<QItemSelection>("QItemSelection");
qRegisterMetaType<qmt::Uid>("qmt::Uid");
qRegisterMetaType<qmt::MDiagram *>();
qRegisterMetaType<const qmt::MDiagram *>();
}
ModelEditorPlugin::~ModelEditorPlugin()
@@ -605,9 +605,10 @@ void AppOutputPane::stopRunControl()
RunControl *rc = m_runControlTabs.at(index).runControl;
QTC_ASSERT(rc, return);
if (rc->isRunning() && optionallyPromptToStop(rc))
rc->initiateStop();
else {
if (rc->isRunning()) {
if (optionallyPromptToStop(rc))
rc->initiateStop();
} else {
QTC_CHECK(false);
rc->forceStop();
}
+1 -1
View File
@@ -518,7 +518,7 @@ void openPythonRepl(const FilePath &file, ReplType type)
return project->projectDirectory();
return FilePath::fromString(QDir::currentPath());
}
return file;
return file.absolutePath();
};
const auto args = QStringList{"-i"} + replImportArgs(file, type);
+10
View File
@@ -36,6 +36,7 @@ add_qtc_plugin(QmlDesigner
qmldesignerconstants.h
qmldesignericons.h
qmldesignerplugin.cpp qmldesignerplugin.h
qmldesignerprojectmanager.cpp qmldesignerprojectmanager.h
settingspage.cpp settingspage.h settingspage.ui
shortcutmanager.cpp shortcutmanager.h
designermcumanager.cpp designermcumanager.h
@@ -340,6 +341,7 @@ extend_qtc_plugin(QmlDesigner
include/propertybinding.h
include/qml3dnode.h
include/qmlvisualnode.h
)
extend_qtc_plugin(QmlDesigner
@@ -349,6 +351,14 @@ extend_qtc_plugin(QmlDesigner
interactiveconnectionmanager.cpp interactiveconnectionmanager.h
)
extend_qtc_plugin(QmlDesigner
SOURCES_PREFIX designercore/imagecache
SOURCES
explicitimagecacheimageprovider.cpp
explicitimagecacheimageprovider.h
)
extend_qtc_plugin(QmlDesigner
SOURCES_PREFIX designercore
PUBLIC_INCLUDES designercore
@@ -1553,6 +1553,7 @@ void DesignerActionManager::createDefaultAddResourceHandler()
auto transformer = [](const QByteArray& format) -> QString { return QString("*.") + format; };
auto imageFormats = Utils::transform(QImageReader::supportedImageFormats(), transformer);
imageFormats.push_back("*.hdr");
imageFormats.push_back("*.ktx");
// The filters will be displayed in reverse order to these lists in file dialog,
// so declare most common types last
@@ -84,6 +84,12 @@ ConnectionViewWidget::ConnectionViewWidget(QWidget *parent) :
ui->tabBar->addTab(tr("Bindings", "Title of connection view"));
ui->tabBar->addTab(tr("Properties", "Title of dynamic properties view"));
const Qt::Alignment headerAlignment = Qt::AlignLeft | Qt::AlignVCenter;
ui->connectionView->horizontalHeader()->setDefaultAlignment(headerAlignment);
ui->bindingView->horizontalHeader()->setDefaultAlignment(headerAlignment);
ui->dynamicPropertiesView->horizontalHeader()->setDefaultAlignment(headerAlignment);
ui->backendView->horizontalHeader()->setDefaultAlignment(headerAlignment);
const QList<QToolButton*> buttons = createToolBarWidgets();
for (auto toolButton : buttons)
@@ -28,14 +28,15 @@ QTableView::item:focus {
}
QTableView::item:selected {
border: none
border: none;
}
QHeaderView::section {
background-color: creatorTheme.DSheaderViewBackground;
border: 0px;
color: creatorTheme.DStextColor;
margin-right: 1px
margin-right: 1px;
padding-left: 6px;
}
QTableView {
@@ -859,8 +859,10 @@ bool FormEditorView::isMoveToolAvailable() const
void FormEditorView::resetNodeInstanceView()
{
ModelNode currentStateNode = currentState().modelNode();
setCurrentStateNode(rootModelNode());
resetPuppet();
setCurrentStateNode(currentStateNode);
}
void FormEditorView::addOrRemoveFormEditorItem(const ModelNode &node)
@@ -180,7 +180,7 @@ const QStringList &ItemLibraryAssetsModel::supportedVideoSuffixes()
const QStringList &ItemLibraryAssetsModel::supportedTexture3DSuffixes()
{
// These are file types only supported by 3D textures
static QStringList retList {"*.hdr"};
static QStringList retList {"*.hdr", "*.ktx"};
return retList;
}
@@ -36,15 +36,22 @@
#include <QDirIterator>
#include <qmlmodelnodeproxy.h>
#include <projectexplorer/project.h>
#include <projectexplorer/session.h>
static QString s_lastBrowserPath;
FileResourcesModel::FileResourcesModel(QObject *parent)
: QObject(parent)
, m_filter(QLatin1String("(*.*)"))
, m_fileSystemWatcher(new Utils::FileSystemWatcher(this))
{
connect(m_fileSystemWatcher, &Utils::FileSystemWatcher::directoryChanged,
this, &FileResourcesModel::refreshModel);
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::projectForFile(
QmlDesigner::DocumentManager::currentFilePath());
if (project) {
connect(project, &ProjectExplorer::Project::fileListChanged,
this, &FileResourcesModel::refreshModel);
}
}
void FileResourcesModel::setModelNodeBackend(const QVariant &modelNodeBackend)
@@ -195,12 +202,7 @@ bool filterMetaIcons(const QString &fileName)
void FileResourcesModel::setupModel()
{
m_dirPath = QDir(m_path.toLocalFile());
refreshModel();
m_fileSystemWatcher->removeDirectories(m_fileSystemWatcher->directories());
m_fileSystemWatcher->addDirectory(m_dirPath.absolutePath(),
Utils::FileSystemWatcher::WatchAllChanges);
}
void FileResourcesModel::refreshModel()
@@ -27,8 +27,6 @@
#include <qmlitemnode.h>
#include <utils/filesystemwatcher.h>
#include <QDir>
#include <QObject>
#include <QStringList>
@@ -87,7 +85,6 @@ private:
QString m_lastResourcePath;
QStringList m_fullPathModel;
QStringList m_fileNameModel;
Utils::FileSystemWatcher *m_fileSystemWatcher;
};
QML_DECLARE_TYPE(FileResourcesModel)
@@ -300,6 +300,44 @@ TimelineWidget *TimelineView::widget() const
return m_timelineWidget;
}
QList<QmlModelState> getAllStates(TimelineView* view)
{
QmlVisualNode visNode(view->rootModelNode());
if (visNode.isValid()) {
return visNode.states().allStates();
}
return {};
}
QString getStateName(TimelineView* view, bool& enableInBaseState)
{
QString currentStateName;
if (QmlModelState state = view->currentState(); state.isValid()) {
if (!state.isBaseState()) {
enableInBaseState = false;
return state.name();
}
}
return QString();
}
void enableInCurrentState(
TimelineView* view, const QString& stateName,
const ModelNode& node, const PropertyName& propertyName)
{
if (!stateName.isEmpty()) {
for (auto& state : getAllStates(view)) {
if (state.isValid()) {
QmlPropertyChanges propertyChanges(state.propertyChanges(node));
if (state.name() == stateName)
propertyChanges.modelNode().variantProperty(propertyName).setValue(true);
else
propertyChanges.modelNode().variantProperty(propertyName).setValue(false);
}
}
}
}
const QmlTimeline TimelineView::addNewTimeline()
{
const TypeName timelineType = "QtQuick.Timeline.Timeline";
@@ -322,6 +360,7 @@ const QmlTimeline TimelineView::addNewTimeline()
executeInTransaction("TimelineView::addNewTimeline", [=, &timelineNode]() {
bool hasTimelines = getTimelines().isEmpty();
QString currentStateName = getStateName(this, hasTimelines);
timelineNode = createModelNode(timelineType,
metaInfo.majorVersion(),
@@ -333,6 +372,8 @@ const QmlTimeline TimelineView::addNewTimeline()
timelineNode.variantProperty("enabled").setValue(hasTimelines);
rootModelNode().defaultNodeListProperty().reparentHere(timelineNode);
enableInCurrentState(this, currentStateName, timelineNode, "enabled");
});
return QmlTimeline(timelineNode);
@@ -353,6 +394,9 @@ ModelNode TimelineView::addAnimation(QmlTimeline timeline)
ModelNode animationNode;
executeInTransaction("TimelineView::addAnimation", [=, &animationNode]() {
bool hasAnimations = getAnimations(timeline).isEmpty();
QString currentStateName = getStateName(this, hasAnimations);
animationNode = createModelNode(animationType,
metaInfo.majorVersion(),
metaInfo.minorVersion());
@@ -364,12 +408,14 @@ ModelNode TimelineView::addAnimation(QmlTimeline timeline)
animationNode.variantProperty("loops").setValue(1);
animationNode.variantProperty("running").setValue(getAnimations(timeline).isEmpty());
animationNode.variantProperty("running").setValue(hasAnimations);
timeline.modelNode().nodeListProperty("animations").reparentHere(animationNode);
if (timeline.modelNode().hasProperty("currentFrame"))
timeline.modelNode().removeProperty("currentFrame");
enableInCurrentState(this, currentStateName, animationNode, "running");
});
return animationNode;
@@ -568,11 +568,20 @@ void TimelineWidget::setupScrollbar(int min, int max, int current)
void TimelineWidget::setTimelineId(const QString &id)
{
auto currentState = m_timelineView->currentState();
auto timelineOfState = m_timelineView->timelineForState(currentState.modelNode());
bool active = false;
if (auto node = timelineOfState.modelNode(); node.isValid())
active = node.id() == id;
const bool empty = m_timelineView->getTimelines().isEmpty();
setTimelineActive(!empty);
if (m_timelineView->isAttached() && !empty) {
m_toolbar->setCurrentTimeline(m_timelineView->modelNodeForId(id));
m_toolbar->setCurrentState(m_timelineView->currentState().name());
const bool valid = active && !empty;
setTimelineActive(valid);
if (m_timelineView->isAttached() && valid) {
m_toolbar->setCurrentTimeline(timelineOfState);
m_toolbar->setCurrentState(currentState.name());
} else {
m_toolbar->setCurrentTimeline({});
m_toolbar->setCurrentState({});
@@ -92,7 +92,10 @@ SOURCES += $$PWD/model/abstractview.cpp \
$$PWD/imagecache/synchronousimagecache.cpp \
$$PWD/imagecache/imagecacheconnectionmanager.cpp \
$$PWD/imagecache/imagecachegenerator.cpp \
$$PWD/imagecache/timestampprovider.cpp
$$PWD/imagecache/timestampprovider.cpp \
$$PWD/imagecache/explicitimagecacheimageprovider.cpp \
$$PWD/imagecache/asynchronousimagefactory.cpp \
$$PWD/imagecache/asynchronousexplicitimagecache.cpp
HEADERS += $$PWD/include/qmldesignercorelib_global.h \
@@ -185,7 +188,10 @@ HEADERS += $$PWD/include/qmldesignercorelib_global.h \
$$PWD/imagecache/imagecachegenerator.h \
$$PWD/imagecache/imagecachestorage.h \
$$PWD/imagecache/timestampprovider.h \
$$PWD/imagecache/timestampproviderinterface.h
$$PWD/imagecache/timestampproviderinterface.h \
$$PWD/imagecache/explicitimagecacheimageprovider.h \
$$PWD/imagecache/asynchronousimagefactory.h \
$$PWD/include/asynchronousexplicitimagecache.h
FORMS += \
@@ -0,0 +1,173 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "asynchronousexplicitimagecache.h"
#include "imagecachestorage.h"
#include <thread>
namespace QmlDesigner {
AsynchronousExplicitImageCache::AsynchronousExplicitImageCache(ImageCacheStorageInterface &storage)
: m_storage(storage)
{
m_backgroundThread = std::thread{[this] {
while (isRunning()) {
if (auto entry = getEntry(); entry) {
request(entry->name,
entry->extraId,
entry->requestType,
std::move(entry->captureCallback),
std::move(entry->abortCallback),
m_storage);
}
waitForEntries();
}
}};
}
AsynchronousExplicitImageCache::~AsynchronousExplicitImageCache()
{
clean();
wait();
}
void AsynchronousExplicitImageCache::request(Utils::SmallStringView name,
Utils::SmallStringView extraId,
AsynchronousExplicitImageCache::RequestType requestType,
ImageCache::CaptureImageCallback captureCallback,
ImageCache::AbortCallback abortCallback,
ImageCacheStorageInterface &storage)
{
const auto id = extraId.empty() ? Utils::PathString{name}
: Utils::PathString::join({name, "+", extraId});
const auto entry = requestType == RequestType::Image
? storage.fetchImage(id, Sqlite::TimeStamp{})
: storage.fetchSmallImage(id, Sqlite::TimeStamp{});
if (entry && !entry->isNull())
captureCallback(*entry);
else
abortCallback(ImageCache::AbortReason::Failed);
}
void AsynchronousExplicitImageCache::wait()
{
stopThread();
m_condition.notify_all();
if (m_backgroundThread.joinable())
m_backgroundThread.join();
}
void AsynchronousExplicitImageCache::requestImage(Utils::PathString name,
ImageCache::CaptureImageCallback captureCallback,
ImageCache::AbortCallback abortCallback,
Utils::SmallString extraId)
{
addEntry(std::move(name),
std::move(extraId),
std::move(captureCallback),
std::move(abortCallback),
RequestType::Image);
m_condition.notify_all();
}
void AsynchronousExplicitImageCache::requestSmallImage(Utils::PathString name,
ImageCache::CaptureImageCallback captureCallback,
ImageCache::AbortCallback abortCallback,
Utils::SmallString extraId)
{
addEntry(std::move(name),
std::move(extraId),
std::move(captureCallback),
std::move(abortCallback),
RequestType::SmallImage);
m_condition.notify_all();
}
void AsynchronousExplicitImageCache::clean()
{
clearEntries();
}
std::optional<AsynchronousExplicitImageCache::RequestEntry> AsynchronousExplicitImageCache::getEntry()
{
std::unique_lock lock{m_mutex};
if (m_requestEntries.empty())
return {};
RequestEntry entry = m_requestEntries.front();
m_requestEntries.pop_front();
return {entry};
}
void AsynchronousExplicitImageCache::addEntry(Utils::PathString &&name,
Utils::SmallString &&extraId,
ImageCache::CaptureImageCallback &&captureCallback,
ImageCache::AbortCallback &&abortCallback,
RequestType requestType)
{
std::unique_lock lock{m_mutex};
m_requestEntries.emplace_back(std::move(name),
std::move(extraId),
std::move(captureCallback),
std::move(abortCallback),
requestType);
}
void AsynchronousExplicitImageCache::clearEntries()
{
std::unique_lock lock{m_mutex};
for (RequestEntry &entry : m_requestEntries)
entry.abortCallback(ImageCache::AbortReason::Abort);
m_requestEntries.clear();
}
void AsynchronousExplicitImageCache::waitForEntries()
{
std::unique_lock lock{m_mutex};
if (m_requestEntries.empty())
m_condition.wait(lock, [&] { return m_requestEntries.size() || m_finishing; });
}
void AsynchronousExplicitImageCache::stopThread()
{
std::unique_lock lock{m_mutex};
m_finishing = true;
}
bool AsynchronousExplicitImageCache::isRunning()
{
std::unique_lock lock{m_mutex};
return !m_finishing || m_requestEntries.size();
}
} // namespace QmlDesigner
@@ -42,13 +42,13 @@ AsynchronousImageCache::AsynchronousImageCache(ImageCacheStorageInterface &stora
{
m_backgroundThread = std::thread{[this] {
while (isRunning()) {
if (auto [hasEntry, entry] = getEntry(); hasEntry) {
request(entry.name,
entry.extraId,
entry.requestType,
std::move(entry.captureCallback),
std::move(entry.abortCallback),
std::move(entry.auxiliaryData),
if (auto entry = getEntry(); entry) {
request(entry->name,
entry->extraId,
entry->requestType,
std::move(entry->captureCallback),
std::move(entry->abortCallback),
std::move(entry->auxiliaryData),
m_storage,
m_generator,
m_timeStampProvider);
@@ -82,11 +82,11 @@ void AsynchronousImageCache::request(Utils::SmallStringView name,
const auto entry = requestType == RequestType::Image ? storage.fetchImage(id, timeStamp)
: storage.fetchSmallImage(id, timeStamp);
if (entry.hasEntry) {
if (entry.image.isNull())
if (entry) {
if (entry->isNull())
abortCallback(ImageCache::AbortReason::Failed);
else
captureCallback(entry.image);
captureCallback(*entry);
} else {
auto callback = [captureCallback = std::move(captureCallback),
requestType](const QImage &image, const QImage &smallImage) {
@@ -145,17 +145,17 @@ void AsynchronousImageCache::clean()
m_generator.clean();
}
std::tuple<bool, AsynchronousImageCache::Entry> AsynchronousImageCache::getEntry()
std::optional<AsynchronousImageCache::Entry> AsynchronousImageCache::getEntry()
{
std::unique_lock lock{m_mutex};
if (m_entries.empty())
return {false, Entry{}};
return {};
Entry entry = m_entries.front();
m_entries.pop_front();
return {true, entry};
return {entry};
}
void AsynchronousImageCache::addEntry(Utils::PathString &&name,
@@ -0,0 +1,155 @@
/****************************************************************************
**
** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "asynchronousimagefactory.h"
#include "imagecachegenerator.h"
#include "imagecachestorage.h"
#include "timestampprovider.h"
namespace QmlDesigner {
AsynchronousImageFactory::AsynchronousImageFactory(ImageCacheStorageInterface &storage,
ImageCacheGeneratorInterface &generator,
TimeStampProviderInterface &timeStampProvider)
: m_storage(storage)
, m_generator(generator)
, m_timeStampProvider(timeStampProvider)
{
m_backgroundThread = std::thread{[this] {
while (isRunning()) {
if (auto entry = getEntry(); entry) {
request(entry->name,
entry->extraId,
std::move(entry->auxiliaryData),
m_storage,
m_generator,
m_timeStampProvider);
}
waitForEntries();
}
}};
}
AsynchronousImageFactory::~AsynchronousImageFactory()
{
clean();
wait();
}
void AsynchronousImageFactory::generate(Utils::PathString name,
Utils::SmallString extraId,
ImageCache::AuxiliaryData auxiliaryData)
{
addEntry(std::move(name), std::move(extraId), std::move(auxiliaryData));
m_condition.notify_all();
}
void AsynchronousImageFactory::addEntry(Utils::PathString &&name,
Utils::SmallString &&extraId,
ImageCache::AuxiliaryData &&auxiliaryData)
{
std::unique_lock lock{m_mutex};
m_entries.emplace_back(std::move(name), std::move(extraId), std::move(auxiliaryData));
}
bool AsynchronousImageFactory::isRunning()
{
std::unique_lock lock{m_mutex};
return !m_finishing || m_entries.size();
}
void AsynchronousImageFactory::waitForEntries()
{
std::unique_lock lock{m_mutex};
if (m_entries.empty())
m_condition.wait(lock, [&] { return m_entries.size() || m_finishing; });
}
std::optional<AsynchronousImageFactory::Entry> AsynchronousImageFactory::getEntry()
{
std::unique_lock lock{m_mutex};
if (m_entries.empty())
return {};
Entry entry = m_entries.front();
m_entries.pop_front();
return {entry};
}
void AsynchronousImageFactory::request(Utils::SmallStringView name,
Utils::SmallStringView extraId,
ImageCache::AuxiliaryData auxiliaryData,
ImageCacheStorageInterface &storage,
ImageCacheGeneratorInterface &generator,
TimeStampProviderInterface &timeStampProvider)
{
const auto id = extraId.empty() ? Utils::PathString{name}
: Utils::PathString::join({name, "+", extraId});
const auto currentModifiedTime = timeStampProvider.timeStamp(name);
const auto storageModifiedTime = storage.fetchModifiedImageTime(id);
if (currentModifiedTime != storageModifiedTime) {
generator.generateImage(name,
extraId,
currentModifiedTime,
ImageCache::CaptureImageWithSmallImageCallback{},
ImageCache::AbortCallback{},
std::move(auxiliaryData));
}
}
void AsynchronousImageFactory::clean()
{
clearEntries();
m_generator.clean();
}
void AsynchronousImageFactory::wait()
{
stopThread();
m_condition.notify_all();
if (m_backgroundThread.joinable())
m_backgroundThread.join();
}
void AsynchronousImageFactory::clearEntries()
{
std::unique_lock lock{m_mutex};
m_entries.clear();
}
void AsynchronousImageFactory::stopThread()
{
std::unique_lock lock{m_mutex};
m_finishing = true;
}
} // namespace QmlDesigner
@@ -0,0 +1,103 @@
/****************************************************************************
**
** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "imagecacheauxiliarydata.h"
#include <utils/smallstring.h>
#include <condition_variable>
#include <deque>
#include <mutex>
#include <optional>
#include <thread>
namespace QmlDesigner {
class TimeStampProviderInterface;
class ImageCacheStorageInterface;
class ImageCacheGeneratorInterface;
class ImageCacheCollectorInterface;
class AsynchronousImageFactory
{
public:
AsynchronousImageFactory(ImageCacheStorageInterface &storage,
ImageCacheGeneratorInterface &generator,
TimeStampProviderInterface &timeStampProvider);
~AsynchronousImageFactory();
void generate(Utils::PathString name,
Utils::SmallString extraId = {},
ImageCache::AuxiliaryData auxiliaryData = {});
void clean();
private:
struct Entry
{
Entry() = default;
Entry(Utils::PathString name,
Utils::SmallString extraId,
ImageCache::AuxiliaryData &&auxiliaryData)
: name{std::move(name)}
, extraId{std::move(extraId)}
, auxiliaryData{std::move(auxiliaryData)}
{}
Utils::PathString name;
Utils::SmallString extraId;
ImageCache::AuxiliaryData auxiliaryData;
};
void addEntry(Utils::PathString &&name,
Utils::SmallString &&extraId,
ImageCache::AuxiliaryData &&auxiliaryData);
bool isRunning();
void waitForEntries();
std::optional<Entry> getEntry();
void request(Utils::SmallStringView name,
Utils::SmallStringView extraId,
ImageCache::AuxiliaryData auxiliaryData,
ImageCacheStorageInterface &storage,
ImageCacheGeneratorInterface &generator,
TimeStampProviderInterface &timeStampProvider);
void wait();
void clearEntries();
void stopThread();
private:
std::deque<Entry> m_entries;
std::mutex m_mutex;
std::condition_variable m_condition;
std::thread m_backgroundThread;
ImageCacheStorageInterface &m_storage;
ImageCacheGeneratorInterface &m_generator;
TimeStampProviderInterface &m_timeStampProvider;
bool m_finishing{false};
};
} // namespace QmlDesigner
@@ -0,0 +1,96 @@
/****************************************************************************
**
** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "explicitimagecacheimageprovider.h"
#include <asynchronousexplicitimagecache.h>
#include <QMetaObject>
#include <QQuickImageResponse>
namespace QmlDesigner {
class ImageRespose : public QQuickImageResponse
{
public:
ImageRespose(const QImage &defaultImage)
: m_image(defaultImage)
{}
QQuickTextureFactory *textureFactory() const override
{
return QQuickTextureFactory::textureFactoryForImage(m_image);
}
void setImage(const QImage &image)
{
m_image = image;
emit finished();
}
void abort() { emit finished(); }
private:
QImage m_image;
};
QQuickImageResponse *ExplicitImageCacheImageProvider::requestImageResponse(const QString &id,
const QSize &)
{
auto response = std::make_unique<ImageRespose>(m_defaultImage);
m_cache.requestImage(
id,
[response = QPointer<ImageRespose>(response.get())](const QImage &image) {
QMetaObject::invokeMethod(
response,
[response, image] {
if (response)
response->setImage(image);
},
Qt::QueuedConnection);
},
[response = QPointer<ImageRespose>(response.get())](ImageCache::AbortReason abortReason) {
QMetaObject::invokeMethod(
response,
[response, abortReason] {
switch (abortReason) {
case ImageCache::AbortReason::Failed:
if (response)
response->abort();
break;
case ImageCache::AbortReason::Abort:
response->cancel();
break;
}
},
Qt::QueuedConnection);
});
return response.release();
}
} // namespace QmlDesigner

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