Merge "Merge remote-tracking branch 'origin/8.0' into 9.0" into 9.0

This commit is contained in:
The Qt Project
2022-10-04 13:45:23 +00:00
91 changed files with 719 additions and 244 deletions

View File

@@ -0,0 +1,245 @@
/****************************************************************************
**
** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Design Studio documentation.
**
** 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 Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
**
****************************************************************************/
/*!
\page animation-tutorial.html
\ingroup gstutorials
\sa {Creating Timeline Animations}
\title Timeline Animation Tutorial
\brief Illustrates how to create timeline animations and bind them to
properties in \QDS.
\image animation-tutorial.gif
The \e{Timeline Animation} tutorial illustrates how to create timeline animations
and bind them to properties in \QDS. First you create a keyframe animation
which you control the running state of with a switch in the UI. Next, you
create another keyframe animation where you use a slider in the UI to
control the position of the playhead.
The starting point of this tutorial is the Animation Tutorial project,
you can download it from
\l{https://git.qt.io/public-demos/qtdesign-studio/-/tree/master/tutorial%20projects/animation-tutorial/AnimationTutorial/Start}
{here}.
You can download the completed project from
\l{https://git.qt.io/public-demos/qtdesign-studio/-/tree/master/tutorial%20projects/animation-tutorial/AnimationTutorial/Completed}
{here}.
This tutorial requires that you know the basics of \QDS, see
\l{Getting Started}.
\section1 Creating a Timeline Animation
First, you create an animation where the ball bearing continuously rotates
around its Y axis.
\section2 Adding a Timeline and an Animation
To add a timeline to your project:
\list 1
\li In the \uicontrol Timeline view, select
\inlineimage icons/plus.png
.
This creates a timeline and one animation.
\li On the \uicontrol {Animation Settings} tab in the
\uicontrol {Timeline Settings} dialog:
\list
\li Set \uicontrol Duration to 7500.
This sets the duration of the animation in milliseconds.
\li Select \uicontrol {Contiunous}.
This sets the animation to start over again when it reaches the
end.
\endlist
\image animation-tutorial-timeline-1.png
\li Select \uicontrol {Close}.
\endlist
You can see the timeline in the \uicontrol Timeline and
\uicontrol Navigator views.
\section2 Adding Keyframes
Next, you add keyframes to animate the rotation of the ball bearing:
\list 1
\li In the \uicontrol Navigator view, select \e {ballbearing1}.
\li In the \uicontrol Properties view, select
\inlineimage icons/action-icon.png (Actions)
next to \uicontrol Rotation > \uicontrol {Y}.
\li Select \uicontrol {Insert Keyframe}.
\image animation-tutorial-insert-keyframe.png
\li In the \uicontrol Timeline view, select the
\uicontrol {Per Property Recording} button to start recording property
changes.
\image animation-tutorial-per-property-recording.png
\li In the \uicontrol Timeline view, move the playhead to the end of the
animation (frame 1000).
\li In the \uicontrol Properties view, set \uicontrol Rotation >
\uicontrol Z to 360.
This creates a second keyframe.
\li Select the \uicontrol {Per Property Recording} button to end the per
property recording. To preview the animation, drag the playhead along the
timeline.
\endlist
\section2 Controlling the Running State of the Animation
There is a toggle switch in the UI of this project. To use this switch to
control the running state of the animation:
\list 1
\li In the \uicontrol Navigator view, select \e {timelineAnimation}.
\li In the \uicontrol Connections view, go to the \uicontrol Bindings tab.
\li Select \inlineimage icons/plus.png
to create a binding.
\li For the binding you created, set:
\list
\li \uicontrol Property to \e {paused}.
\li \uicontrol {Source Item} to \e {switch1}.
\li \uicontrol {Source Property} to \e {checked}.
\endlist
\image animation-tutorial-binding.png
\endlist
You can preview the animation and try the toggle switch in the live preview.
To run the live preview, select \key Alt + \key{P}.
\section1 Creating a Timeline and Binding it to a Property
Next, you create the exploded view animation of the ball bearing. You don't
want this animation to run automatically but instead you want to control it
with a slider in the UI.
\section2 Adding a Timeline Inside a Component
You create this animation inside the ball bearing component, to do this:
\list 1
\li In the \uicontrol Navigator view, select \e {ballBearing1}.
\li Select \key {F2} to go into the component.
\li In the \uicontrol Timeline view, select
\inlineimage icons/plus.png
to add a timeline and open the \uicontrol {Timeline Settings} dialog.
\li Select \inlineimage icons/minus.png
next to the \uicontrol {Animation Settings} tab to remove the animation
in this timeline.
You do not need an animation when you bind the timeline to a property.
\li Select \uicontrol {Close}.
\endlist
\image animation-tutorial-timeline-2.png
\section2 Adding Keyframes
Now, you add keyframes for the different parts of the ball bearing:
\list 1
\li In the \uicontrol{Navigator} view, select \e{inner_race}.
\li In the \uicontrol Properties view, select
\inlineimage icons/action-icon.png (Actions)
next to \uicontrol Translation > \uicontrol Y.
\li Select \uicontrol {Insert Keyframe}.
\li In the \uicontrol Timeline view, select the
\uicontrol {Per Property Recording} button to start recording property
changes.
\li In the \uicontrol Timeline view, move the playhead to the end of the
animation (frame 1000).
\li In the \uicontrol Properties view, set \uicontrol Translation >
\uicontrol Y to 0,50.
\li Select the \uicontrol {Per Property Recording} button to end the per
property recording.
\li Next, you set the keyframe values for the other parts of the ball
bearing. For the following parts, set the \uicontrol Translation >
\uicontrol Y value for frame 1000:
\list
\li \e balls to 1,00.
\li \e retainer to 1,50.
\li \e shield_left to 1,80.
\li \e shield_right to -0,30.
\endlist
\image animation-tutorial-ballbearing-animation.png
\endlist
You can preview the animation by dragging the playhead in the
\uicontrol Timeline view.
\section2 Controlling the Animation with a Slider
Now, you use the slider on the main screen to control the exploded
view animation that you created.
To do this, you first need to define a property for the slider:
\list 1
\li In the \uicontrol Navigator view, select \e Node.
\li On the \uicontrol Properties tab in the \uicontrol Connections view,
select \inlineimage icons/plus.png
.
\li In the \uicontrol {Property Type} field, enter \e {Item}.
This field is a drop-down list, but you can also type text.
\li In the \uicontrol {Property Value} field, enter \e {null}.
\endlist
\image animation-tutorial-property.png
Next, you set the property you just created to control the timeline
animation:
\list 1
\li In the \uicontrol {Timeline} view, select
\inlineimage icons/animation.png
.
\li In the \uicontrol {Expression binding field}, enter
\c {property0.value}.
\li Select \uicontrol {Close}.
\endlist
Next, you go out from the component back to the main project and bind the
property to the slider:
\list 1
\li In the toolbar, select the \e {Screen01.ui.qml} breadcrumb.
\image animation-tutorial-breadcrumb.png
\li In the \uicontrol {Navigator} view, select \e {ballbearing1}.
\li In the \uicontrol {Connections} view, go to the
\uicontrol {Bindings} tab.
\li Select \inlineimage icons/plus.png
.
\li For the binding you just created:
\list
\li Set \uicontrol {Source Item} to \e {slider}.
\li Remove the value from \uicontrol {Source Property}.
\endlist
\image animation-tutorial-binding-2.png
\endlist
\section1 Previewing
Now, the animations are done. To preview and test your application,
select \key Alt + \key{P}.
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -29,7 +29,7 @@
custom properties on the \uicontrol {Properties} tab in the
\l {Connections} view.
\image qmldesigner-dynamicprops.png "Connections View Properties tab"
For more information, see \l{Specifying Dynamic Properties}.
For more information, see \l{Specifying Custom Properties}.
\li To enable users to interact with the component instances, connect
the instances to signals on the \uicontrol Connections tab in the
\uicontrol {Connections} view. For example, you can specify what

View File

@@ -41,7 +41,7 @@
\uicontrol Navigator or the \uicontrol {2D} view.
\li Edit component properties in the \uicontrol Properties view.
The available properties depend on the component type. You can
\l{Specifying Dynamic Properties}{add properties for
\l{Specifying Custom Properties}{add properties for
components} on the \uicontrol {Properties} tab in the
\uicontrol Connections view.
\li To change the appearance and behavior of the component instances

View File

@@ -139,7 +139,7 @@
When you add a \l{GridView}{Grid View}, \l{ListView}{List View}, or
\l{PathView}{Path View}, the ListModel and the delegate component that
creates an instance for each item in the model are added automatically.
For grid and list views, you can edit the list model in \QC.
For grid and list views, you can edit the list model in \QDS.
\image qtquick-designer-listview-preview.png "Preview of a list view"

View File

@@ -28,7 +28,7 @@
\image qtquick-designer-image-type.png "Image component in different views"
When you drag-and-drop an image file from \uicontrol Assets to \l Navigator
or the \l {2D} view, \QC automatically
or the \l {2D} view, \QDS automatically
creates an instance of the Image component for you with the path to the
image file set as the value of the \uicontrol Source field in
\uicontrol Properties.

View File

@@ -73,7 +73,7 @@
For more information on the JavaScript environment provided, see
\l{Integrating QML and JavaScript}.
Bindings are a black box for \QC and using them might have a
Bindings are a black box for \QDS and using them might have a
negative impact on performance, so consider setting anchors and margins for
components, instead. For example, instead of setting \c {parent.width} for a
component, you could anchor the component to its sibling components on the
@@ -342,7 +342,7 @@
to right and top to bottom. Each component is positioned at the top-left
corner of its cell with position (0, 0).
\QC generates the grid based on the positions of the child components in
\QDS generates the grid based on the positions of the child components in
the \l {2D} view. You can modify the number of rows and columns in the
\uicontrol Rows and \uicontrol Columns fields.

View File

@@ -27,7 +27,7 @@
working Qt 6 application that you can build and run in Qt Creator using
CMake. Therefore, you can open, build, and run the projects with Qt Creator.
\QDS continues to use the \e .qmlproject file format, while \QC uses a
\QDS continues to use the \e .qmlproject file format, while Qt Creator uses a
\e CMakeLists.txt file as the project file. This enables you to share
your project as a fully working C++ application with developers.
@@ -46,9 +46,10 @@
\section1 Converting Project Structure for CMake
\QDS can generate \e CMakeLists.txt and other related files to use with \QC and to compile into
an executable application but only if the project has a certain folder structure. If you have a
\QDS QML project that doesn't have the CMake configuration, follow these steps to convert its
\QDS can generate \e CMakeLists.txt and other related files to use with
Qt Creator and to compile into an executable application but only if the
project has a certain folder structure. If you have a \QDS QML project that
doesn't have the CMake configuration, follow these steps to convert its
file structure to the correct format.
\list 1

View File

@@ -46,7 +46,7 @@
\section2 Timeline and Keyframe Based Animation
Timeline animation is based on \e keyframes. In \QC, keyframes determine the
Timeline animation is based on \e keyframes. In \QDS, keyframes determine the
value of the property of a \l{glossary_component}{component} at a certain
time. Animating properties enables their values to move through intermediate
values instead of immediately changing to the target value.

View File

@@ -114,7 +114,7 @@
\endif
\row
\li Adding custom properties for a particular component type
\li \l{Specifying Dynamic Properties}
\li \l{Specifying Custom Properties}
\omit
\row
\li Adding properties for controlling states

View File

@@ -48,7 +48,7 @@
\section1 Profiling UI Code
You can use \l{Profiling QML Applications}{QML Profiler} that is integrated
into \QC to find causes for typical performance problems in your UI. For
into \QDS to find causes for typical performance problems in your UI. For
example, your UI might be slow, unresponsive, or stuttering. Typically, such
problems are caused by executing too much JavaScript in too few frames. All
JavaScript must return before the GUI thread can proceed, and frames are

View File

@@ -73,7 +73,7 @@
\li \l {Importing 3D Assets}
You can import exported assets into \QC. For a list of formats
You can import exported assets into \QDS. For a list of formats
supported by each \l{Qt Quick 3D} version, see the module
documentation.

View File

@@ -20,14 +20,14 @@
components, and states, you need. Create a descriptive wireframe
and acquire a detailed UI specification before you start to make
the process of creating the UI more efficient.
\QC enables you to turn your UI concept into a wireframe with
\QDS enables you to turn your UI concept into a wireframe with
a scalable layout where all your screens and controls are in
place. You can present your wireframe to developers and other
stakeholders for discussion, review, and approval before
continuing into the prototyping phase.
\endtable
In \QC, you build UIs around the behavior of \l{glossary-component}
In \QDS, you build UIs around the behavior of \l{glossary-component}
{components} and how they connect with one another. You can use preset
components available in the \l Components view or combine them to create
your own components. You can specify values for the \e properties of a

View File

@@ -49,7 +49,7 @@
\li Edit component properties in the \l Properties view.
The available properties depend on the component type. You can
\l{Specifying Dynamic Properties}{add properties for components} on
\l{Specifying Custom Properties}{add properties for components} on
the \uicontrol Properties tab in the {Connections} view.
\endlist

View File

@@ -26,7 +26,7 @@
\li \l{Converting UI Projects to Applications}
\QDS projects are useful for creating UIs. To use them for
application development in \QC, you have to convert
application development in Qt Creator, you have to convert
them to Qt Quick Application projects that contain .pro,
.cpp, and .qrc files.
\li \l{Using External Tools}

View File

@@ -19,7 +19,7 @@
\li \l {FAQ - Assets}{Assets}
\li \l {FAQ - Components}{Components}
\li \l {FAQ - Views}{Views}
\li \l {FAQ - Integration Between \QDS and \QC}{Integration Between \QDS and \QC}
\li \l {FAQ - Integration Between \QDS and Qt Creator}{Integration Between \QDS and Qt Creator}
\li \l {FAQ - Performance}{Performance}
\li \l {FAQ - Data Simulation}{Data Simulation}
\endlist
@@ -67,7 +67,7 @@
\section1 FAQ - Components
\section2 Can custom components be used?
\section2 Can I use custom components?
Yes, you can create custom components and controls by using wizard templates
or move component instances into separate files to turn them into new
@@ -81,7 +81,7 @@
For more information, see \l {Importing 3D Assets}.
\section2 How to integrate custom C++ components into QDS?
\section2 How can I integrate custom C++ components into QDS?
You must create your own QML module that contains the components and
provides additional information about your components. For more information,
@@ -99,21 +99,21 @@
For more information, see the \l {3D} view.
\section1 FAQ - Integration Between \QDS and \QC
\section1 FAQ - Integration Between \QDS and Qt Creator
\section2 Is there a way to automatically propagate name changes between \QDS and \QC?
\section2 Can I automatically propagate name changes between \QDS and Qt Creator?
Unfortunately we do not automate renaming files between tools at the moment.
If you decide to change the name of a property, alias, or signal in \QDS,
you need to manually change the name in \QC to maintain the connection.
you need to manually change the name in Qt Creator to maintain the connection.
However, you can rename symbols in all files within a project. To rename a
QML type in a project, select \uicontrol Tools > \uicontrol QML/JS >
\uicontrol {Rename Symbol Under Cursor} or press \key Ctrl+Shift+R. For more
information, see \l {Renaming Symbols}.
\section2 When turning your \QDS project into application in \QC, what is the best way to add .qml files?
\section2 How can I add .qml files to my project in Qt Creator?
Use the project wizard templates to create an application in \QC and copy
Use the project wizard templates to create an application in \QDS and copy
your .qml files to the project folder. Then make some changes to the project
configuration and source files, as instructed in
\l {Converting UI Projects to Applications}.

View File

@@ -143,7 +143,7 @@
Navigator to add the properties on the \uicontrol Properties tab in the
\l Connections view.
See \l {Specifying Dynamic Properties} for a detailed description of how
See \l {Specifying Custom Properties} for a detailed description of how
to add a custom property. The name of the property and the data type
need to match those of the send or receive property of the Simulink model.

View File

@@ -197,7 +197,7 @@
\li \l{Preset Components}
\li \l{Specifying Component Properties}
\li \l{Adding Bindings Between Properties}
\li \l{Specifying Dynamic Properties}
\li \l{Specifying Custom Properties}
\endlist
\section1 Signal
@@ -294,7 +294,7 @@
deploys it to the \l{glossary-device}{device} specified in the
selected \l{glossary-buildandrun-kit}{kit}, and runs it there. However,
if you have not made any changes to the project since you last deployed
it, \QC simply runs it again.
it, \QDS simply runs it again.
\endomit
*/

View File

@@ -122,7 +122,7 @@
\list
\li\l{Connecting Components to Signals}
\li\l{Adding Bindings Between Properties}
\li\l{Specifying Dynamic Properties}
\li\l{Specifying Custom Properties}
\endlist
\li \l{Adding States}
\endlist

View File

@@ -193,5 +193,5 @@
\image studio-custom-material-uniform-properties.png "Uniforms as properties in Connections view Properties tab"
For more information about adding properties, see
\l{Specifying Dynamic Properties}.
\l{Specifying Custom Properties}.
*/

View File

@@ -12,7 +12,7 @@
\title Creating Optimized 3D Scenes
In \QC, you can use various means to create a 3D scene. Your choice of
In \QDS, you can use various means to create a 3D scene. Your choice of
strategy should always depend on the target platform of your scene.
The way the content of your scene is authored can have dramatic effects on
the runtime performance of your UI. The Optimal 3D Scene described
@@ -88,7 +88,7 @@
The scene graph is the hierarchy of nodes that describe the scene to be
rendered.
In \QC, the scene graph is represented by the tree-like view in
In \QDS, the scene graph is represented by the tree-like view in
\uicontrol Navigator. You can also view the hierarchy of nodes in the
\l {Code} view. By minimizing the size of the scene graph,
you can minimize the effort needed when running the scene. In terms of

View File

@@ -9,10 +9,10 @@
\else
\nextpage quick-connections-backend.html
\endif
\sa {Specifying Component Properties}
\title Specifying Custom Properties
\title Specifying Dynamic Properties
Each preset \l{glossary-component}{component} has a set of preset properties
Each \l{Preset Components}{preset component }has a set of preset properties
that you can specify values for. You can add custom properties that would
not otherwise exist for a particular \l{Component Types}{component type}.
You bind the properties to dynamic expressions to define global properties
@@ -33,50 +33,36 @@
should have an \e int or \e real property for speed to which the UI is
bound.
You can add properties for components on the \uicontrol Properties tab in
in the \l {Connections} view.
\section1 Adding Properties for a Component
\image qmldesigner-dynamicprops.png "Custom properties in the Connections view Custom Properties tab"
To add properties for a component:
To add a custom property for a component:
\list 1
\li Go to the \uicontrol Properties tab in the \l Connections view.
\li Go to the \uicontrol {Local Custom Properties} section in the
\uicontrol Properties view.
\li Select the \inlineimage icons/plus.png
(\uicontrol Add) button to add a dynamic property for the currently
selected component. The component ID is displayed in the \uicontrol Item
column.
\li Double-click the value in the \uicontrol Property column to give a
name to the property. Property names must begin with a lower case
letter and can only contain letters, numbers, and underscores.
JavaScript \e {reserved words} are not valid property names.
\li Double-click the value in the \uicontrol {Property Type} column to
specify the \l{Supported Property Types}{type of the property}.
\li Double-click the value in the \uicontrol {Property Value} column
to specify the value of the property.
(\uicontrol Add) button to add a custom property for the currently
selected component.
\image add-local-custom-property.png
\li Set the \uicontrol Name and \uicontrol Type for the property.
\image add-new-property-dialog.png
\endlist
\section1 Binding a Property Value
To bind the value of the property to that of another one or to data
accessible in the application.
\list 1
\li In the \uicontrol Properties view, select
\inlineimage icons/action-icon.png
next to the property.
\li Select \uicontrol {Set Binding}.
\image qmldesigner-binding-editor.png "Binding Editor"
\endlist
Right-click a property and select \uicontrol {Open Binding Editor} in
the context menu to bind the value of the property to that of another one
or to data accessible in the application in \uicontrol {Binding Editor}.
For more information, see \l{Setting Bindings}.
\image qmldesigner-binding-editor.png "Binding Editor"
The properties you add for a component are displayed in the \l Properties
view when you select a component of that type in the \l Navigator or
\l {2D} view.
\image qtquick-custom-properties.png "Custom properties in Properties view"
For more information about setting property values in the
\l Properties view, see \l{Specifying Component Properties}.
\if defined(qtcreator)
For an example of using custom properties in an application, see
\l{Creating a Mobile Application}.
\endif
\section1 Supported Property Types
The following table describes the supported property types:
@@ -112,6 +98,9 @@
\row
\li string
\li Free form text string
\row
\li TextureInput
\li Specifies a texture exposed to the shaders of a CustomMaterial or Effect.
\row
\li url
\li Resource locator, such as a file name. It can be either absolute,
@@ -122,5 +111,14 @@
\li variant
\li Generic property type. For example, variant properties can store
numbers, strings, objects, arrays, and functions.
\row
\li vector2d
\li Refers to a value with x and y attributes.
\row
\li vector3d
\li Refers to a value with x, y, and z attributes.
\row
\li vector4d
\li Refers to a value with x, y, z, and w attributes.
\endtable
*/

View File

@@ -26,7 +26,7 @@
the value of a property changes, the values of any properties that
are bound to it are automatically updated accordingly.
\li \l{Specifying Dynamic Properties}
\li \l{Specifying Custom Properties}
Each preset component has a set of preset properties that you
can specify values for. You can add custom properties that would

View File

@@ -63,7 +63,7 @@
\li \uicontrol Properties
\li Add custom properties that would not otherwise exist for a
particular preset component or your own custom component.
\li \l{Specifying Dynamic Properties}
\li \l{Specifying Custom Properties}
\if defined(qtcreator)
\row
\li \uicontrol Backends

View File

@@ -107,7 +107,7 @@
\section1 Locking Components
When designing complex applications, it is easy to accidentally modify
the properties of a component in one of the \QC views in ways that lead to
the properties of a component in one of the \QDS views in ways that lead to
surprising results. For example, the \uicontrol {2D} view can become
crowded and other components can get in the way when you are trying to
select or transform a particular component, so that you end up transforming
@@ -115,7 +115,7 @@
To lock components that you are not currently editing and their children,
click \inlineimage icons/lockon.png
in \uicontrol Navigator. Locked components cannot be handled in any \QC
in \uicontrol Navigator. Locked components cannot be handled in any \QDS
views. You can unlock the components when you want to edit them again.
\image qtquick-designer-navigator-lock.gif "Locking components in Navigator"

View File

@@ -22,6 +22,26 @@
\image qmldesigner-element-properties.png "Rectangle and Text properties"
\section1 Custom Properties
Custom Properties are properties that the user has added to the component.
There are two types of custom properties:
\table
\header
\li Custom Property Type
\li Description
\row
\li Local Custom Property
\li A property that has been added for a \l{Preset Components}{preset component}.
\row
\li Exposed Custom Property
\li A property that has been added inside a component.
\endtable
\image custom-properties.png
\section1 Summary of Properties View Buttons
The following table lists the \uicontrol Properties view buttons:

View File

@@ -29,7 +29,7 @@
another preset component in the field.
If you have specified values for properties that are not supported by the
new component type, \QC offers to remove them for you. If you'd rather do
new component type, \QDS offers to remove them for you. If you'd rather do
this yourself, you can select the \inlineimage icons/action-icon.png
(\uicontrol Actions) menu next to the property name, and then select
\uicontrol Reset to remove the property values before trying again.

View File

@@ -8,7 +8,7 @@
\title Managing Workspaces
In the \uicontrol Design mode, you can arrange a set of \QC
In the \uicontrol Design mode, you can arrange a set of \QDS
views as a \e workspace on the screen.
To detach views:
@@ -34,10 +34,10 @@
\section1 Saving Workspaces
The changes you make to a workspace are saved when you exit \QC.
The changes you make to a workspace are saved when you exit \QDS.
Select \uicontrol View > \uicontrol Workspaces >
\uicontrol Manage > \uicontrol {Restore last workspace on startup}
to restore the current workspace the next time you start \QC.
to restore the current workspace the next time you start \QDS.
\image qtcreator-workspace-manager.png "Workspace Manager"

View File

@@ -17,6 +17,7 @@ Item {
property var currentMaterial: null
property int currentMaterialIdx: 0
property var currentBundleMaterial: null
property int copiedMaterialInternalId: -1
property var matSectionsModel: []
@@ -125,15 +126,20 @@ Item {
StudioControls.MenuItem {
text: modelData
enabled: root.currentMaterial
onTriggered: materialBrowserModel.copyMaterialProperties(root.currentMaterialIdx, modelData)
onTriggered: {
root.copiedMaterialInternalId = root.currentMaterial.materialInternalId
materialBrowserModel.copyMaterialProperties(root.currentMaterialIdx, modelData)
}
}
}
}
StudioControls.MenuItem {
text: qsTr("Paste properties")
enabled: root.currentMaterial && root.currentMaterial.materialType
=== materialBrowserModel.copiedMaterialType
enabled: root.currentMaterial
&& root.copiedMaterialInternalId !== root.currentMaterial.materialInternalId
&& root.currentMaterial.materialType === materialBrowserModel.copiedMaterialType
&& materialBrowserModel.isCopiedMaterialValid()
onTriggered: materialBrowserModel.pasteMaterialProperties(root.currentMaterialIdx)
}
@@ -213,7 +219,22 @@ Item {
width: root.width - addMaterialButton.width
onSearchChanged: (searchText) => rootView.handleSearchFilterChanged(searchText)
onSearchChanged: (searchText) => {
rootView.handleSearchFilterChanged(searchText)
// make sure searched categories that have matches are expanded
if (!materialBrowserModel.isEmpty && !userMaterialsSection.expanded)
userMaterialsSection.expanded = true
if (!materialBrowserBundleModel.isEmpty && !bundleMaterialsSection.expanded)
bundleMaterialsSection.expanded = true
for (let i = 0; i < bundleMaterialsSectionRepeater.count; ++i) {
let sec = bundleMaterialsSectionRepeater.itemAt(i)
if (sec.visible && !sec.expanded)
sec.expanded = true
}
}
}
IconButton {
@@ -282,10 +303,8 @@ Item {
height: root.cellHeight
onShowContextMenu: {
if (searchBox.isEmpty()) {
root.currentMaterial = model
cxtMenu.popup()
}
root.currentMaterial = model
cxtMenu.popup()
}
}
}
@@ -312,6 +331,8 @@ Item {
}
Section {
id: bundleMaterialsSection
width: root.width
caption: qsTr("Material Library")
addTopPadding: noMatchText.visible
@@ -319,6 +340,8 @@ Item {
Column {
Repeater {
id: bundleMaterialsSectionRepeater
model: materialBrowserBundleModel
delegate: Section {
@@ -343,10 +366,8 @@ Item {
height: root.cellHeight
onShowContextMenu: {
if (searchBox.isEmpty()) {
root.currentBundleMaterial = modelData
cxtMenuBundle.popup()
}
root.currentBundleMaterial = modelData
cxtMenuBundle.popup()
}
}
}

View File

@@ -303,18 +303,50 @@ Rectangle {
width: Math.min(300, root.width)
onApplied: {
function apply() {
let renamed = statesEditorModel.renameActiveStateGroup(editTextField.text)
if (renamed)
editDialog.close()
}
onApplied: editDialog.accept()
StudioControls.TextField {
id: editTextField
text: statesEditorModel.activeStateGroup
actionIndicatorVisible: false
translationIndicatorVisible: false
anchors.fill: parent
onTextChanged: {
let btn = editDialog.standardButton(Dialog.Apply)
if (!btn)
return
if (editDialog.previousString !== editTextField.text) {
btn.enabled = true
} else {
btn.enabled = false
}
}
onAccepted: editDialog.accept()
onRejected: editDialog.reject()
}
onAccepted: {
let renamed = statesEditorModel.renameActiveStateGroup(editTextField.text)
if (renamed)
editDialog.close()
}
property string previousString
onAboutToShow: {
editTextField.text = statesEditorModel.activeStateGroup
editDialog.previousString = statesEditorModel.activeStateGroup
let btn = editDialog.standardButton(Dialog.Apply)
btn.enabled = false
}
}
@@ -747,8 +779,7 @@ Rectangle {
height: extendGap.portraitOneColumn ? root.innerGridSpacing : Constants.thumbnailSize
+ 2 * root.extend
color: StudioTheme.Values.themeStateHighlight
visible: extendBackground.radius !== 0
&& extendBackground.visible
visible: extendBackground.visible
}
StateThumbnail {

View File

@@ -35,7 +35,7 @@ Section {
id: root
anchors.left: parent.left
anchors.right: parent.right
caption: qsTr("User Added Properties")
caption: qsTr("Local Custom Properties")
property DynamicPropertiesModel propertiesModel: null

View File

@@ -11,8 +11,6 @@ import StudioTheme 1.0 as StudioTheme
StudioControls.TextField {
id: textField
signal rejected
translationIndicator.visible: false
actionIndicator.visible: false
@@ -136,6 +134,11 @@ StudioControls.TextField {
onPressed: listView.model = null
onRejected: {
if (textField.completionActive)
listView.model = null
}
Keys.priority: Keys.BeforeItem
Keys.onPressed: function(event) {
var text = textField.text
@@ -222,15 +225,6 @@ StudioControls.TextField {
}
}
Keys.onEscapePressed: function(event) {
event.accepted = true
if (textField.completionActive) {
listView.model = null
} else {
textField.rejected()
}
}
Keys.onUpPressed: function(event) {
listView.decrementCurrentIndex()
event.accepted = false

View File

@@ -60,7 +60,7 @@ T.Button {
states: [
State {
name: "default"
when: !root.down && !root.hovered && !root.checked
when: root.enabled && !root.down && !root.hovered && !root.checked
PropertyChanges {
target: background
@@ -75,7 +75,7 @@ T.Button {
},
State {
name: "hover"
when: root.hovered && !root.checked && !root.down
when: root.enabled && root.hovered && !root.checked && !root.down
PropertyChanges {
target: background
@@ -88,8 +88,8 @@ T.Button {
}
},
State {
name: "pressed"
when: root.checked || root.down
name: "press"
when: root.enabled && (root.checked || root.down)
PropertyChanges {
target: background
@@ -100,6 +100,19 @@ T.Button {
target: textItem
color: StudioTheme.Values.themeTextColor
}
},
State {
name: "disable"
when: !root.enabled
PropertyChanges {
target: background
color: StudioTheme.Values.themeControlBackgroundDisabled
border.color: StudioTheme.Values.themeControlOutlineDisabled
}
PropertyChanges {
target: textItem
color: StudioTheme.Values.themeTextColorDisabled
}
}
]
}

View File

@@ -30,6 +30,8 @@ T.TextField {
property bool contextMenuAboutToShow: false
signal rejected
horizontalAlignment: Qt.AlignLeft
verticalAlignment: Qt.AlignVCenter
@@ -225,10 +227,10 @@ T.TextField {
}
]
Keys.onPressed: function(event) {
if (event.key === Qt.Key_Escape) {
root.text = root.preFocusText
root.focus = false
}
Keys.onEscapePressed: function(event) {
event.accepted = true
root.text = root.preFocusText
root.rejected()
root.focus = false
}
}

View File

@@ -567,14 +567,16 @@ bool AndroidBuildApkStep::init()
if (m_buildAAB)
arguments << "--aab" << "--jarsigner";
if (buildType() == BuildConfiguration::Release) {
arguments << "--release";
}
QStringList argumentsPasswordConcealed = arguments;
if (m_signPackage) {
arguments << "--release"
<< "--sign" << m_keystorePath.toString() << m_certificateAlias
arguments << "--sign" << m_keystorePath.toString() << m_certificateAlias
<< "--storepass" << m_keystorePasswd;
argumentsPasswordConcealed << "--release"
<< "--sign" << "******"
argumentsPasswordConcealed << "--sign" << "******"
<< "--storepass" << "******";
if (!m_certificatePasswd.isEmpty()) {
arguments << "--keypass" << m_certificatePasswd;

View File

@@ -240,6 +240,9 @@ bool AndroidDeployQtStep::init()
m_androiddeployqtArgs.addArg("--gradle");
if (buildType() == BuildConfiguration::Release)
m_androiddeployqtArgs.addArgs({"--release"});
if (androidBuildApkStep && androidBuildApkStep->signPackage()) {
// The androiddeployqt tool is not really written to do stand-alone installations.
// This hack forces it to use the correct filename for the apk file when installing

View File

@@ -576,6 +576,8 @@ public:
{
menu()->clear();
menu()->setEnabled(true);
const auto selection = selectionContext();
if (!selection.isValid())
return;
@@ -585,11 +587,19 @@ public:
return;
ModelNode currentNode = selection.currentSingleSelectedNode();
if (!currentNode.isValid())
return;
QmlObjectNode currentObjectNode(currentNode);
QStringList signalsList = getSignalsList(currentNode);
QList<SlotEntry> slotsList = getSlotsLists(currentNode);
currentNode.validId();
if (!currentNode.hasId()) {
menu()->setEnabled(false);
return;
}
for (const ModelNode &connectionNode : currentObjectNode.getAllConnections()) {
for (const AbstractProperty &property : connectionNode.properties()) {

View File

@@ -1631,6 +1631,7 @@ void addMouseAreaFill(const SelectionContext &selectionContext)
QmlDesigner::ModelNode mouseAreaNode =
selectionContext.view()->createModelNode("QtQuick.MouseArea", itemMetaInfo.majorVersion(), itemMetaInfo.minorVersion());
mouseAreaNode.validId();
modelNode.defaultNodeListProperty().reparentHere(mouseAreaNode);
QmlItemNode mouseAreaItemNode(mouseAreaNode);

View File

@@ -315,6 +315,8 @@ void Edit3DWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent)
void Edit3DWidget::dropEvent(QDropEvent *dropEvent)
{
const QPointF pos = m_canvas->mapFrom(this, dropEvent->position());
// handle dropping materials
if (dropEvent->mimeData()->hasFormat(Constants::MIME_TYPE_MATERIAL)) {
QByteArray data = dropEvent->mimeData()->data(Constants::MIME_TYPE_MATERIAL);
@@ -323,13 +325,13 @@ void Edit3DWidget::dropEvent(QDropEvent *dropEvent)
stream >> internalId;
if (ModelNode matNode = m_view->modelNodeForInternalId(internalId))
m_view->dropMaterial(matNode, dropEvent->position());
m_view->dropMaterial(matNode, pos);
return;
}
// handle dropping bundle materials
if (dropEvent->mimeData()->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL)) {
m_view->dropBundleMaterial(dropEvent->position());
m_view->dropBundleMaterial(pos);
return;
}

View File

@@ -7,7 +7,8 @@
#include <designmodewidget.h>
#include <qmldesignerplugin.h>
#include <qmlobjectnode.h>
#include "variantproperty.h"
#include <variantproperty.h>
#include <qmltimelinekeyframegroup.h>
#include "utils/qtcassert.h"
namespace QmlDesigner {
@@ -326,40 +327,84 @@ void MaterialBrowserModel::duplicateMaterial(int idx)
void MaterialBrowserModel::copyMaterialProperties(int idx, const QString &section)
{
ModelNode mat = m_materialList.at(idx);
QString matType = QString::fromLatin1(mat.type());
m_copiedMaterial = m_materialList.at(idx);
QTC_ASSERT(m_copiedMaterial.isValid(), return);
QString matType = QString::fromLatin1(m_copiedMaterial.type());
if (matType.startsWith("QtQuick3D."))
matType.remove("QtQuick3D.");
setCopiedMaterialType(matType);
m_allPropsCopied = section == "All";
QmlObjectNode mat(m_copiedMaterial);
QSet<PropertyName> validProps;
PropertyNameList copiedProps;
// Base state properties are always valid
const auto baseProps = m_copiedMaterial.propertyNames();
for (const auto &baseProp : baseProps)
validProps.insert(baseProp);
if (!mat.isInBaseState()) {
QmlPropertyChanges changes = mat.propertyChangeForCurrentState();
if (changes.isValid()) {
const QList<AbstractProperty> changedProps = changes.targetProperties();
for (const auto &changedProp : changedProps)
validProps.insert(changedProp.name());
}
}
if (mat.timelineIsActive()) {
const QList<QmlTimelineKeyframeGroup> keyframeGroups
= mat.currentTimeline().keyframeGroupsForTarget(m_copiedMaterial);
for (const auto &kfg : keyframeGroups)
validProps.insert(kfg.propertyName());
}
if (m_allPropsCopied || m_propertyGroupsObj.empty()) {
m_copiedMaterialProps = mat.properties();
copiedProps = validProps.values();
} else {
QJsonObject propsSpecObj = m_propertyGroupsObj.value(m_copiedMaterialType).toObject();
if (propsSpecObj.contains(section)) { // should always be true
m_copiedMaterialProps.clear();
const QJsonArray propNames = propsSpecObj.value(section).toArray();
// auto == QJsonValueConstRef after 04dc959d49e5e3 / Qt 6.4, QJsonValueRef before
for (const auto &propName : propNames)
m_copiedMaterialProps.append(mat.property(propName.toString().toLatin1()));
copiedProps.append(propName.toString().toLatin1());
if (section == "Base") { // add QtQuick3D.Material base props as well
QJsonObject propsMatObj = m_propertyGroupsObj.value("Material").toObject();
const QJsonArray propNames = propsMatObj.value("Base").toArray();
// auto == QJsonValueConstRef after 04dc959d49e5e3 / Qt 6.4, QJsonValueRef before
for (const auto &propName : propNames)
m_copiedMaterialProps.append(mat.property(propName.toString().toLatin1()));
copiedProps.append(propName.toString().toLatin1());
}
}
}
m_copiedMaterialProps.clear();
for (const auto &propName : copiedProps) {
PropertyCopyData data;
data.name = propName;
data.isValid = m_allPropsCopied || validProps.contains(propName);
data.isBinding = mat.hasBindingProperty(propName);
if (data.isValid) {
if (data.isBinding)
data.value = mat.expression(propName);
else
data.value = mat.modelValue(propName);
}
m_copiedMaterialProps.append(data);
}
}
void MaterialBrowserModel::pasteMaterialProperties(int idx)
{
emit pasteMaterialPropertiesTriggered(m_materialList.at(idx), m_copiedMaterialProps, m_allPropsCopied);
ModelNode targetMat = m_materialList.at(idx);
if (targetMat.isValid() && m_copiedMaterial.isValid() && targetMat != m_copiedMaterial)
emit pasteMaterialPropertiesTriggered(targetMat, m_copiedMaterialProps, m_allPropsCopied);
}
void MaterialBrowserModel::deleteMaterial(int idx)
@@ -396,4 +441,11 @@ void MaterialBrowserModel::openMaterialEditor()
QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialEditor", true);
}
// This is provided as invokable instead of property, as it is difficult to know when ModelNode
// becomes invalid. Much simpler to evaluate this on demand.
bool MaterialBrowserModel::isCopiedMaterialValid() const
{
return m_copiedMaterial.isValid();
}
} // namespace QmlDesigner

View File

@@ -70,6 +70,15 @@ public:
Q_INVOKABLE void addNewMaterial();
Q_INVOKABLE void applyToSelected(qint64 internalId, bool add = false);
Q_INVOKABLE void openMaterialEditor();
Q_INVOKABLE bool isCopiedMaterialValid() const;
struct PropertyCopyData
{
PropertyName name;
QVariant value;
bool isBinding = false;
bool isValid = false;
};
signals:
void isEmptyChanged();
@@ -83,9 +92,10 @@ signals:
void applyToSelectedTriggered(const QmlDesigner::ModelNode &material, bool add = false);
void addNewMaterialTriggered();
void duplicateMaterialTriggered(const QmlDesigner::ModelNode &material);
void pasteMaterialPropertiesTriggered(const QmlDesigner::ModelNode &material,
const QList<QmlDesigner::AbstractProperty> &props,
bool all);
void pasteMaterialPropertiesTriggered(
const QmlDesigner::ModelNode &material,
const QList<QmlDesigner::MaterialBrowserModel::PropertyCopyData> &props,
bool all);
private:
bool isMaterialVisible(int idx) const;
@@ -96,7 +106,8 @@ private:
QStringList m_defaultMaterialSections;
QStringList m_principledMaterialSections;
QStringList m_customMaterialSections;
QList<AbstractProperty> m_copiedMaterialProps;
ModelNode m_copiedMaterial;
QList<PropertyCopyData> m_copiedMaterialProps;
QHash<qint32, int> m_materialIndexHash; // internalId -> index
QJsonObject m_propertyGroupsObj;

View File

@@ -72,29 +72,43 @@ WidgetInfo MaterialBrowserView::widgetInfo()
});
connect(matBrowserModel, &MaterialBrowserModel::pasteMaterialPropertiesTriggered, this,
[&] (const ModelNode &material, const QList<AbstractProperty> &props, bool all) {
[&] (const ModelNode &material,
const QList<QmlDesigner::MaterialBrowserModel::PropertyCopyData> &propDatas,
bool all) {
QmlObjectNode mat(material);
executeInTransaction(__FUNCTION__, [&] {
if (all) { // all material properties copied
// remove current properties
const PropertyNameList propNames = material.propertyNames();
for (const PropertyName &propName : propNames) {
PropertyNameList propNames;
if (mat.isInBaseState()) {
propNames = material.propertyNames();
} else {
QmlPropertyChanges changes = mat.propertyChangeForCurrentState();
if (changes.isValid()) {
const QList<AbstractProperty> changedProps = changes.targetProperties();
for (const auto &changedProp : changedProps)
propNames.append(changedProp.name());
}
}
for (const PropertyName &propName : qAsConst(propNames)) {
if (propName != "objectName")
mat.removeProperty(propName);
}
}
// apply pasted properties
for (const AbstractProperty &prop : props) {
if (prop.name() == "objectName")
for (const QmlDesigner::MaterialBrowserModel::PropertyCopyData &propData : propDatas) {
if (propData.name == "objectName")
continue;
if (prop.isVariantProperty())
mat.setVariantProperty(prop.name(), prop.toVariantProperty().value());
else if (prop.isBindingProperty())
mat.setBindingProperty(prop.name(), prop.toBindingProperty().expression());
else if (!all)
mat.removeProperty(prop.name());
if (propData.isValid) {
if (propData.isBinding)
mat.setBindingProperty(propData.name, propData.value.toString());
else
mat.setVariantProperty(propData.name, propData.value);
} else {
mat.removeProperty(propData.name);
}
}
});
});
@@ -164,7 +178,8 @@ void MaterialBrowserView::applyBundleMaterialToDropTarget(const ModelNode &bundl
newMatNode = bundleMat;
}
if (m_bundleMaterialDropTarget.isValid()) {
if (m_bundleMaterialDropTarget.isValid()
&& m_bundleMaterialDropTarget.metaInfo().isQtQuick3DModel()) {
QmlObjectNode qmlObjNode(m_bundleMaterialDropTarget);
if (m_bundleMaterialAddToSelected) {
// TODO: unify this logic as it exist elsewhere also
@@ -211,12 +226,12 @@ void MaterialBrowserView::modelAttached(Model *model)
rootModelNode().metaInfo().isQtQuick3DMaterial());
m_hasQuick3DImport = model->hasImport("QtQuick3D");
loadPropertyGroups();
// Project load is already very busy and may even trigger puppet reset, so let's wait a moment
// before refreshing the model
QTimer::singleShot(1000, this, [this]() {
refreshModel(true);
loadPropertyGroups(); // Needs the delay because it uses metaInfo
});
}
@@ -429,7 +444,6 @@ void MaterialBrowserView::customNotification(const AbstractView *view,
} else if (identifier == "drop_bundle_material") {
m_bundleMaterialDropTarget = nodeList.first();
ModelNode defaultMat = getBundleMaterialDefaultInstance(m_draggedBundleMaterial->type());
if (defaultMat.isValid())
applyBundleMaterialToDropTarget(defaultMat);

View File

@@ -110,15 +110,21 @@ bool MaterialBrowserWidget::eventFilter(QObject *obj, QEvent *event)
} else if (m_bundleMaterialToDrag != nullptr) {
QMouseEvent *me = static_cast<QMouseEvent *>(event);
if ((me->globalPos() - m_dragStartPoint).manhattanLength() > 20) {
QByteArray data;
QMimeData *mimeData = new QMimeData;
mimeData->setData(Constants::MIME_TYPE_BUNDLE_MATERIAL, {});
QDataStream stream(&data, QIODevice::WriteOnly);
stream << m_bundleMaterialToDrag->type();
mimeData->setData(Constants::MIME_TYPE_BUNDLE_MATERIAL, data);
mimeData->removeFormat("text/plain");
model->startDrag(mimeData, m_bundleMaterialToDrag->icon().toLocalFile());
emit bundleMaterialDragStarted(m_bundleMaterialToDrag);
model->startDrag(mimeData, m_bundleMaterialToDrag->icon().toLocalFile());
m_bundleMaterialToDrag = {};
}
}
} else if (event->type() == QMouseEvent::MouseButtonRelease) {
m_materialToDrag = {};
m_bundleMaterialToDrag = {};
}
return QObject::eventFilter(obj, event);

View File

@@ -36,6 +36,8 @@ ChooseFromPropertyListFilter::ChooseFromPropertyListFilter(const NodeMetaInfo &i
// -> Attractor3D
// Material
// -> Model
// BundleMaterial
// -> Model
if (insertInfo.isQtQuick3DTexture()) {
if (parentInfo.isQtQuick3DDefaultMaterial() || parentInfo.isQtQuick3DPrincipledMaterial()) {
@@ -83,6 +85,9 @@ ChooseFromPropertyListFilter::ChooseFromPropertyListFilter(const NodeMetaInfo &i
} else if (insertInfo.isQtQuick3DMaterial()) {
if (parentInfo.isQtQuick3DParticles3DModel())
propertyList.append("materials");
// TODO merge conflict between Change-Id: If3c58f82797beabe76baf99ea2dddc59032729df and Change-Id: Iff2dea66e253b412105427134bd49cb16ed76193
// } else if (insertInfo.typeName().startsWith("ComponentBundles.MaterialBundle")) {
// if (parentInfo.isSubclassOf("QtQuick3D.Model"))
}
}

View File

@@ -443,6 +443,7 @@ QStringList NavigatorTreeModel::mimeTypes() const
const static QStringList types({Constants::MIME_TYPE_MODELNODE_LIST,
Constants::MIME_TYPE_ITEM_LIBRARY_INFO,
Constants::MIME_TYPE_MATERIAL,
Constants::MIME_TYPE_BUNDLE_MATERIAL,
Constants::MIME_TYPE_ASSETS});
return types;
@@ -540,6 +541,10 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData,
handleItemLibraryItemDrop(mimeData, rowNumber, dropModelIndex);
} else if (mimeData->hasFormat(Constants::MIME_TYPE_MATERIAL)) {
handleMaterialDrop(mimeData, rowNumber, dropModelIndex);
} else if (mimeData->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL)) {
ModelNode targetNode(modelNodeForIndex(dropModelIndex));
if (targetNode.isValid())
m_view->emitCustomNotification("drop_bundle_material", {targetNode}); // To MaterialBrowserView
} else if (mimeData->hasFormat(Constants::MIME_TYPE_ASSETS)) {
const QStringList assetsPaths = QString::fromUtf8(mimeData->data(Constants::MIME_TYPE_ASSETS)).split(',');
NodeAbstractProperty targetProperty;

View File

@@ -260,6 +260,14 @@ void NavigatorView::dragStarted(QMimeData *mimeData)
m_widget->setDragType(matNode.metaInfo().typeName());
m_widget->update();
} else if (mimeData->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL)) {
QByteArray data = mimeData->data(Constants::MIME_TYPE_BUNDLE_MATERIAL);
QDataStream stream(data);
TypeName bundleMatType;
stream >> bundleMatType;
m_widget->setDragType(bundleMatType);
m_widget->update();
}
}

View File

@@ -335,7 +335,8 @@ void DynamicPropertyRow::commitValue(const QVariant &value)
QByteArrayLiteral("DynamicPropertiesModel::commitValue"));
try {
QmlObjectNode objectNode = variantProperty.parentQmlObjectNode();
if (view->currentState().isBaseState() && !objectNode.timelineIsActive()) {
if (view->currentState().isBaseState()
&& !(objectNode.timelineIsActive() && objectNode.currentTimeline().isRecording())) {
if (variantProperty.value() != value)
variantProperty.setDynamicTypeNameAndValue(variantProperty.dynamicTypeName(), value);
} else {

View File

@@ -446,7 +446,7 @@ QmlDesigner::AbstractView *GradientModel::view() const
void GradientModel::resetPuppet()
{
QTimer::singleShot(1000, [this]() { view()->resetPuppet(); });
QTimer::singleShot(1000, view(), &QmlDesigner::AbstractView::resetPuppet);
}
QmlDesigner::ModelNode GradientModel::createGradientNode()

View File

@@ -704,7 +704,7 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &metaTyp
QString qmlInnerTemplate = "";
qmlInnerTemplate += "Section {\n";
qmlInnerTemplate += "caption: \""+ QObject::tr("User Added Properties") + "\"\n";
qmlInnerTemplate += "caption: \"" + QObject::tr("Exposed Custom Properties") + "\"\n";
qmlInnerTemplate += anchorLeftRight;
qmlInnerTemplate += "leftPadding: 0\n";
qmlInnerTemplate += "rightPadding: 0\n";

View File

@@ -95,6 +95,7 @@ void StatesEditorModel::reset()
QAbstractListModel::endResetModel();
evaluateExtend();
emit baseStateChanged();
}
QVariant StatesEditorModel::data(const QModelIndex &index, int role) const

View File

@@ -122,7 +122,6 @@ public slots:
void removeState(int nodeId);
private:
StatesEditorWidget *statesEditorWidget() const;
void resetModel();
void resetPropertyChangesModels();
void resetExtend();

View File

@@ -34,9 +34,8 @@ void DesignerSettings::insert(const QHash<QByteArray, QVariant> &settingsHash)
QVariant DesignerSettings::value(const QByteArray &key, const QVariant &defaultValue) const
{
Q_UNUSED(defaultValue)
QMutexLocker locker(&m_mutex);
return m_cache.value(key);
return m_cache.value(key, defaultValue);
}
void DesignerSettings::restoreValue(QSettings *settings, const QByteArray &key, const QVariant &defaultValue)

View File

@@ -11,7 +11,7 @@ namespace Internal {
DebugMessagesModel::DebugMessagesModel(QmlProfilerModelManager *manager,
Timeline::TimelineModelAggregator *parent) :
QmlProfilerTimelineModel(manager, DebugMessage, MaximumRangeType, ProfileDebugMessages, parent),
QmlProfilerTimelineModel(manager, DebugMessage, UndefinedRangeType, ProfileDebugMessages, parent),
m_maximumMsgType(-1)
{
}

View File

@@ -17,7 +17,7 @@ namespace Internal {
InputEventsModel::InputEventsModel(QmlProfilerModelManager *manager,
Timeline::TimelineModelAggregator *parent) :
QmlProfilerTimelineModel(manager, Event, MaximumRangeType, ProfileInputEvents, parent),
QmlProfilerTimelineModel(manager, Event, UndefinedRangeType, ProfileInputEvents, parent),
m_keyTypeId(-1), m_mouseTypeId(-1)
{
}
@@ -128,6 +128,8 @@ int InputEventsModel::collapsedRow(int index) const
void InputEventsModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
{
if (type.detailType() >= MaximumInputEventType)
return;
m_data.insert(insert(event.timestamp(), 0, type.detailType()),
Item(static_cast<InputEventType>(event.number<qint32>(0)),
event.number<qint32>(1), event.number<qint32>(2)));

View File

@@ -14,7 +14,7 @@ class InputEventsModel : public QmlProfilerTimelineModel
public:
struct Item {
Item(InputEventType type = MaximumInputEventType, int a = 0, int b = 0);
Item(InputEventType type = UndefinedInputEventType, int a = 0, int b = 0);
InputEventType type;
int a;
int b;

View File

@@ -13,7 +13,7 @@ namespace Internal {
MemoryUsageModel::MemoryUsageModel(QmlProfilerModelManager *manager,
Timeline::TimelineModelAggregator *parent) :
QmlProfilerTimelineModel(manager, MemoryAllocation, MaximumRangeType, ProfileMemory, parent)
QmlProfilerTimelineModel(manager, MemoryAllocation, UndefinedRangeType, ProfileMemory, parent)
{
// Register additional features. The base class already registers the main feature.
// Don't register initializer, finalizer, or clearer as the base class has done so already.
@@ -121,7 +121,7 @@ QVariantMap MemoryUsageModel::details(int index) const
void MemoryUsageModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
{
if (type.message() != MemoryAllocation) {
if (type.rangeType() != MaximumRangeType) {
if (type.rangeType() != UndefinedRangeType) {
m_continuation = ContinueNothing;
if (event.rangeStage() == RangeStart)
m_rangeStack.push(RangeStackFrame(event.typeIndex(), event.timestamp()));

View File

@@ -13,7 +13,7 @@ namespace Internal {
PixmapCacheModel::PixmapCacheModel(QmlProfilerModelManager *manager,
Timeline::TimelineModelAggregator *parent) :
QmlProfilerTimelineModel(manager, PixmapCacheEvent, MaximumRangeType, ProfilePixmapCache,
QmlProfilerTimelineModel(manager, PixmapCacheEvent, UndefinedRangeType, ProfilePixmapCache,
parent)
{
}

View File

@@ -17,7 +17,7 @@ static ProfileFeature qmlFeatureFromType(Message message, RangeType rangeType, i
case AnimationFrame:
return ProfileAnimations;
default:
return MaximumProfileFeature;
return UndefinedProfileFeature;
}
}
case PixmapCacheEvent:
@@ -29,7 +29,11 @@ static ProfileFeature qmlFeatureFromType(Message message, RangeType rangeType, i
case DebugMessage:
return ProfileDebugMessages;
case Quick3DEvent:
return ProfileQuick3D;
// Check if it's actually Quick3DEvent since old traces used MaximumMessage
// (whose value is now Quick3DEvent value) as undefined value
if (rangeType == UndefinedRangeType)
return ProfileQuick3D;
return featureFromRangeType(rangeType);
default:
return featureFromRangeType(rangeType);
}
@@ -46,6 +50,9 @@ QDataStream &operator>>(QDataStream &stream, QmlEventType &type)
type.m_message = static_cast<Message>(message);
type.m_rangeType = static_cast<RangeType>(rangeType);
type.setFeature(qmlFeatureFromType(type.m_message, type.m_rangeType, type.m_detailType));
// Update message if qmlFeatureFromType determined it is not Quick3D event
if (type.m_message == Quick3DEvent && type.feature() != ProfileQuick3D)
type.m_message = UndefinedMessage;
return stream;
}

View File

@@ -17,7 +17,7 @@ class QmlEventType : public Timeline::TraceEventType {
public:
static const qint32 staticClassId = 0x716d6c74; // 'qmlt';
QmlEventType(Message message = MaximumMessage, RangeType rangeType = MaximumRangeType,
QmlEventType(Message message = UndefinedMessage, RangeType rangeType = UndefinedRangeType,
int detailType = -1, const QmlEventLocation &location = QmlEventLocation(),
const QString &data = QString(), const QString &displayName = QString());

View File

@@ -21,7 +21,7 @@ namespace Internal {
QmlProfilerAnimationsModel::QmlProfilerAnimationsModel(QmlProfilerModelManager *manager,
Timeline::TimelineModelAggregator *parent) :
QmlProfilerTimelineModel(manager, Event, MaximumRangeType, ProfileAnimations, parent)
QmlProfilerTimelineModel(manager, Event, UndefinedRangeType, ProfileAnimations, parent)
{
m_minNextStartTimes[0] = m_minNextStartTimes[1] = 0;
}

View File

@@ -8,7 +8,8 @@
namespace QmlProfiler {
enum Message {
Event,
UndefinedMessage = 0xff,
Event = 0,
RangeStart,
RangeData,
RangeLocation,
@@ -24,7 +25,8 @@ enum Message {
};
enum EventType {
FramePaint, // unused
UndefinedEventType = 0xff,
FramePaint = 0, // unused
Mouse,
Key,
AnimationFrame, // new Qt5 paint events
@@ -35,7 +37,8 @@ enum EventType {
};
enum Quick3DEventType {
Quick3DRenderFrame,
UndefinedQuick3DEventType = 0xff,
Quick3DRenderFrame = 0,
Quick3DSynchronizeFrame,
Quick3DPrepareFrame,
Quick3DMeshLoad,
@@ -50,7 +53,8 @@ enum Quick3DEventType {
};
enum RangeType {
Painting, // old Qt4 paint events
UndefinedRangeType = 0xff,
Painting = 0, // old Qt4 paint events
Compiling,
Creating,
Binding,
@@ -61,7 +65,8 @@ enum RangeType {
};
enum BindingType {
QmlBinding,
UndefinedBindingType = 0xff,
QmlBinding = 0,
V8Binding,
OptimizedBinding,
QPainterEvent,
@@ -70,7 +75,8 @@ enum BindingType {
};
enum PixmapEventType {
PixmapSizeKnown,
UndefinedPixmapEventType = 0xff,
PixmapSizeKnown = 0,
PixmapReferenceCountChanged,
PixmapCacheCountChanged,
PixmapLoadingStarted,
@@ -81,7 +87,8 @@ enum PixmapEventType {
};
enum InputEventType {
InputKeyPress,
UndefinedInputEventType = 0xff,
InputKeyPress = 0,
InputKeyRelease,
InputKeyUnknown,
@@ -96,7 +103,8 @@ enum InputEventType {
};
enum SceneGraphFrameType {
SceneGraphRendererFrame, // Render Thread
UndefinedSceheGraphFrameType = 0xff,
SceneGraphRendererFrame = 0, // Render Thread
SceneGraphAdaptationLayerFrame, // Render Thread
SceneGraphContextFrame, // Render Thread
SceneGraphRenderLoopFrame, // Render Thread
@@ -111,7 +119,8 @@ enum SceneGraphFrameType {
};
enum MemoryType {
HeapPage,
UndefinedMemoryType = 0xff,
HeapPage = 0,
LargeItem,
SmallItem,
@@ -119,14 +128,16 @@ enum MemoryType {
};
enum AnimationThread {
GuiThread,
UndefinedAnimationThread = 0xff,
GuiThread = 0,
RenderThread,
MaximumAnimationThread
};
enum ProfileFeature {
ProfileJavaScript,
UndefinedProfileFeature = 0xff,
ProfileJavaScript = 0,
ProfileMemory,
ProfilePixmapCache,
ProfileSceneGraph,
@@ -159,7 +170,7 @@ inline ProfileFeature featureFromRangeType(RangeType range)
case Javascript:
return ProfileJavaScript;
default:
return MaximumProfileFeature;
return UndefinedProfileFeature;
}
}

View File

@@ -377,7 +377,7 @@ QmlProfilerModelManager::rangeFilter(qint64 rangeStart, qint64 rangeEnd) const
// Double-check if rangeStart has been crossed. Some versions of Qt send dirty data.
qint64 adjustedTimestamp = event.timestamp();
if (event.timestamp() < rangeStart && !crossedRangeStart) {
if (type.rangeType() != MaximumRangeType) {
if (type.rangeType() != UndefinedRangeType) {
if (event.rangeStage() == RangeStart)
stack.push(event);
else if (event.rangeStage() == RangeEnd && !stack.isEmpty())
@@ -398,7 +398,7 @@ QmlProfilerModelManager::rangeFilter(qint64 rangeStart, qint64 rangeEnd) const
crossedRangeStart = true;
}
if (event.timestamp() > rangeEnd) {
if (type.rangeType() != MaximumRangeType) {
if (type.rangeType() != UndefinedRangeType) {
if (event.rangeStage() == RangeEnd) {
if (stack.isEmpty()) {
QmlEvent endEvent(event);

View File

@@ -23,7 +23,7 @@ namespace Internal {
QmlProfilerRangeModel::QmlProfilerRangeModel(QmlProfilerModelManager *manager, RangeType range,
Timeline::TimelineModelAggregator *parent) :
QmlProfilerTimelineModel(manager, MaximumMessage, range, featureFromRangeType(range), parent)
QmlProfilerTimelineModel(manager, UndefinedMessage, range, featureFromRangeType(range), parent)
{
m_expandedRowTypes << -1;
}

View File

@@ -148,7 +148,7 @@ void QmlProfilerTraceClientPrivate::processCurrentEvent()
// all ranges are perfectly nested. This is why we can defer the type resolution until either
// the range ends or a child range starts. With only the information in RangeStart we wouldn't
// be able to uniquely identify the event type.
Message rangeStage = currentEvent.type.rangeType() == MaximumRangeType ?
Message rangeStage = currentEvent.type.rangeType() == UndefinedRangeType ?
currentEvent.type.message() : currentEvent.event.rangeStage();
switch (rangeStage) {
case RangeStart:
@@ -311,7 +311,7 @@ void QmlProfilerTraceClient::setRequestedFeatures(quint64 features)
d->currentEvent.event.setTimestamp(context.timestamp > 0 ? context.timestamp : 0);
d->currentEvent.event.setTypeIndex(-1);
d->currentEvent.event.setString(text);
d->currentEvent.type = QmlEventType(DebugMessage, MaximumRangeType, type,
d->currentEvent.type = QmlEventType(DebugMessage, UndefinedRangeType, type,
QmlEventLocation(context.file, context.line, 1));
d->currentEvent.serverTypeId = 0;
d->processCurrentEvent();
@@ -328,6 +328,8 @@ void QmlProfilerTraceClient::setFlushInterval(quint32 flushInterval)
bool QmlProfilerTraceClientPrivate::updateFeatures(quint8 feature)
{
if (feature == UndefinedProfileFeature)
return true;
quint64 flag = 1ULL << feature;
if (!(requestedFeatures & flag))
return false;

View File

@@ -59,7 +59,7 @@ Q_STATIC_ASSERT(sizeof(MESSAGE_STRINGS) == MaximumMessage * sizeof(const char *)
static QPair<Message, RangeType> qmlTypeAsEnum(const QString &typeString)
{
QPair<Message, RangeType> ret(MaximumMessage, MaximumRangeType);
QPair<Message, RangeType> ret(UndefinedMessage, UndefinedRangeType);
for (int i = 0; i < MaximumMessage; ++i) {
if (typeString == _(MESSAGE_STRINGS[i])) {
@@ -75,7 +75,7 @@ static QPair<Message, RangeType> qmlTypeAsEnum(const QString &typeString)
}
}
if (ret.first == MaximumMessage && ret.second == MaximumRangeType) {
if (ret.first == UndefinedMessage && ret.second == UndefinedRangeType) {
bool isNumber = false;
int type = typeString.toUInt(&isNumber);
if (isNumber && type < MaximumRangeType)
@@ -288,7 +288,7 @@ void QmlProfilerTraceFile::loadEventTypes(QXmlStreamReader &stream)
int typeIndex = -1;
QPair<Message, RangeType> messageAndRange(MaximumMessage, MaximumRangeType);
QPair<Message, RangeType> messageAndRange(UndefinedMessage, UndefinedRangeType);
int detailType = -1;
QString displayName;
QString data;
@@ -296,7 +296,7 @@ void QmlProfilerTraceFile::loadEventTypes(QXmlStreamReader &stream)
int line = 0, column = 0;
auto clearType = [&](){
messageAndRange = QPair<Message, RangeType>(MaximumMessage, MaximumRangeType);
messageAndRange = QPair<Message, RangeType>(UndefinedMessage, UndefinedRangeType);
detailType = -1;
displayName.clear();
data.clear();
@@ -368,7 +368,7 @@ void QmlProfilerTraceFile::loadEventTypes(QXmlStreamReader &stream)
// confusing), even though they clearly aren't ranges. Convert that to something
// sane here.
if (detailType == 4) {
messageAndRange = QPair<Message, RangeType>(Event, MaximumRangeType);
messageAndRange = QPair<Message, RangeType>(Event, UndefinedRangeType);
detailType = AnimationFrame;
}
}
@@ -674,13 +674,13 @@ void QmlProfilerTraceFile::saveQtd(QIODevice *device)
QStack<QmlEvent> stack;
qint64 lastProgressTimestamp = traceStart();
modelManager()->replayQmlEvents([&](const QmlEvent &event, const QmlEventType &type) {
if (type.rangeType() != MaximumRangeType && event.rangeStage() == RangeStart) {
if (type.rangeType() != UndefinedRangeType && event.rangeStage() == RangeStart) {
stack.push(event);
return;
}
stream.writeStartElement(_("range"));
if (type.rangeType() != MaximumRangeType && event.rangeStage() == RangeEnd) {
if (type.rangeType() != UndefinedRangeType && event.rangeStage() == RangeEnd) {
QmlEvent start = stack.pop();
stream.writeAttribute(_("startTime"), QString::number(start.timestamp()));
stream.writeAttribute(_("duration"),

View File

@@ -14,10 +14,10 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
stream >> time >> messageType;
if (messageType < 0 || messageType > MaximumMessage)
messageType = MaximumMessage;
if (messageType < 0 || messageType >= MaximumMessage)
messageType = UndefinedMessage;
RangeType rangeType = MaximumRangeType;
RangeType rangeType = UndefinedRangeType;
if (!stream.atEnd()) {
stream >> subtype;
if (subtype >= 0 && subtype < MaximumRangeType)
@@ -32,7 +32,9 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
switch (messageType) {
case Event: {
event.type = QmlEventType(static_cast<Message>(messageType), MaximumRangeType, subtype);
if (subtype >= MaximumEventType)
subtype = UndefinedEventType;
event.type = QmlEventType(static_cast<Message>(messageType), UndefinedRangeType, subtype);
switch (subtype) {
case StartTrace:
case EndTrace: {
@@ -76,7 +78,7 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
break;
}
case Complete: {
event.type = QmlEventType(static_cast<Message>(messageType), MaximumRangeType, subtype);
event.type = QmlEventType(static_cast<Message>(messageType), UndefinedRangeType, subtype);
break;
}
case SceneGraphFrame: {
@@ -88,7 +90,7 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
params.push_back(param);
}
event.type = QmlEventType(static_cast<Message>(messageType), MaximumRangeType, subtype);
event.type = QmlEventType(static_cast<Message>(messageType), UndefinedRangeType, subtype);
event.event.setNumbers<QVarLengthArray<qint64>, qint64>(params);
break;
}
@@ -103,7 +105,7 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
refcount = 1;
}
event.type = QmlEventType(static_cast<Message>(messageType), MaximumRangeType, subtype,
event.type = QmlEventType(static_cast<Message>(messageType), UndefinedRangeType, subtype,
QmlEventLocation(filename, 0, 0));
event.event.setNumbers<qint32>({width, height, refcount});
break;
@@ -112,7 +114,7 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
qint64 delta;
stream >> delta;
event.type = QmlEventType(static_cast<Message>(messageType), MaximumRangeType, subtype);
event.type = QmlEventType(static_cast<Message>(messageType), UndefinedRangeType, subtype);
event.event.setNumbers<qint64>({delta});
break;
}
@@ -125,7 +127,7 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
// otherwise it's the old binding type of 4 bytes
}
event.type = QmlEventType(MaximumMessage, rangeType, -1);
event.type = QmlEventType(UndefinedMessage, rangeType, -1);
event.event.setRangeStage(RangeStart);
break;
}
@@ -133,7 +135,7 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
QString data;
stream >> data;
event.type = QmlEventType(MaximumMessage, rangeType, -1, QmlEventLocation(), data);
event.type = QmlEventType(UndefinedMessage, rangeType, -1, QmlEventLocation(), data);
event.event.setRangeStage(RangeData);
if (!stream.atEnd())
stream >> event.serverTypeId;
@@ -151,13 +153,13 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
stream >> event.serverTypeId;
}
event.type = QmlEventType(MaximumMessage, rangeType, -1,
event.type = QmlEventType(UndefinedMessage, rangeType, -1,
QmlEventLocation(filename, line, column));
event.event.setRangeStage(RangeLocation);
break;
}
case RangeEnd: {
event.type = QmlEventType(MaximumMessage, rangeType, -1);
event.type = QmlEventType(UndefinedMessage, rangeType, -1);
event.event.setRangeStage(RangeEnd);
break;
}
@@ -170,13 +172,13 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
stream >> param;
params.push_back(param);
}
event.type = QmlEventType(static_cast<Message>(messageType), MaximumRangeType, subtype);
event.type = QmlEventType(static_cast<Message>(messageType), UndefinedRangeType, subtype);
event.event.setNumbers<QVarLengthArray<qint64>, qint64>(params);
break;
}
default:
event.event.setNumbers<char>({});
event.type = QmlEventType(static_cast<Message>(messageType), MaximumRangeType, subtype);
event.type = QmlEventType(static_cast<Message>(messageType), UndefinedRangeType, subtype);
break;
}

View File

@@ -12,7 +12,7 @@ namespace Internal {
Quick3DModel::Quick3DModel(QmlProfilerModelManager *manager,
Timeline::TimelineModelAggregator *parent) :
QmlProfilerTimelineModel(manager, Quick3DEvent, MaximumRangeType, ProfileQuick3D, parent),
QmlProfilerTimelineModel(manager, Quick3DEvent, UndefinedRangeType, ProfileQuick3D, parent),
m_maximumMsgType(-1)
{
}
@@ -135,7 +135,9 @@ int Quick3DModel::collapsedRow(int index) const
void Quick3DModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
{
auto detailType = type.detailType();
int detailType = type.detailType();
if (detailType >= MaximumQuick3DFrameType)
return;
qint64 eventDuration = event.number<qint64>(0);
qint64 eventTime = event.timestamp() - eventDuration;
QVector<quint64> numbers = event.numbers<QVector<quint64>>();

View File

@@ -56,7 +56,7 @@ Q_STATIC_ASSERT(sizeof(StageLabels) ==
SceneGraphTimelineModel::SceneGraphTimelineModel(QmlProfilerModelManager *manager,
Timeline::TimelineModelAggregator *parent) :
QmlProfilerTimelineModel(manager, SceneGraphFrame, MaximumRangeType, ProfileSceneGraph, parent)
QmlProfilerTimelineModel(manager, SceneGraphFrame, UndefinedRangeType, ProfileSceneGraph, parent)
{
}

View File

@@ -24,7 +24,7 @@ void DebugMessagesModelTest::initTestCase()
QmlEvent event;
event.setTimestamp(i);
event.setString(QString::fromLatin1("message %1").arg(i));
QmlEventType type(DebugMessage, MaximumRangeType, i % (QtMsgType::QtInfoMsg + 1),
QmlEventType type(DebugMessage, UndefinedRangeType, i % (QtMsgType::QtInfoMsg + 1),
QmlEventLocation("somefile.js", i, 10 - i));
event.setTypeIndex(manager.numEventTypes());
manager.appendEventType(std::move(type));

View File

@@ -34,7 +34,7 @@ int FlameGraphModelTest::generateData(QmlProfilerModelManager *manager,
QmlEvent event;
if (i < 5) {
typeIndex = manager->appendEventType(
QmlEventType(MaximumMessage,
QmlEventType(UndefinedMessage,
static_cast<RangeType>(static_cast<int>(Javascript) - i), -1,
QmlEventLocation("somefile.js", i, 20 - i),
QString("funcfunc")));

View File

@@ -20,8 +20,8 @@ static InputEventType inputType(int i)
InputEventsModelTest::InputEventsModelTest(QObject *parent) :
QObject(parent), model(&manager, &aggregator)
{
keyTypeId = manager.appendEventType(QmlEventType(Event, MaximumRangeType, Key));
mouseTypeId = manager.appendEventType(QmlEventType(Event, MaximumRangeType, Mouse));
keyTypeId = manager.appendEventType(QmlEventType(Event, UndefinedRangeType, Key));
mouseTypeId = manager.appendEventType(QmlEventType(Event, UndefinedRangeType, Mouse));
}
void InputEventsModelTest::initTestCase()

View File

@@ -20,11 +20,11 @@ void MemoryUsageModelTest::initTestCase()
heapPageTypeId = manager.numEventTypes();
manager.appendEventType(QmlEventType(MemoryAllocation, MaximumRangeType, HeapPage));
manager.appendEventType(QmlEventType(MemoryAllocation, UndefinedRangeType, HeapPage));
smallItemTypeId = manager.numEventTypes();
manager.appendEventType(QmlEventType(MemoryAllocation, MaximumRangeType, SmallItem));
manager.appendEventType(QmlEventType(MemoryAllocation, UndefinedRangeType, SmallItem));
largeItemTypeId = manager.numEventTypes();
manager.appendEventType(QmlEventType(MemoryAllocation, MaximumRangeType, LargeItem));
manager.appendEventType(QmlEventType(MemoryAllocation, UndefinedRangeType, LargeItem));
auto addMemoryEvents = [&]() {
QmlEvent event;
@@ -53,7 +53,7 @@ void MemoryUsageModelTest::initTestCase()
addMemoryEvents();
rangeTypeId = manager.numEventTypes();
manager.appendEventType(QmlEventType(MaximumMessage, Javascript, -1,
manager.appendEventType(QmlEventType(UndefinedMessage, Javascript, -1,
QmlEventLocation(QString("somefile.js"), 10, 20),
QString("funcfunc")));

View File

@@ -22,7 +22,7 @@ void PixmapCacheModelTest::initTestCase()
for (int i = 0; i < MaximumPixmapEventType; ++i) {
eventTypeIndices[i] = manager.numEventTypes();
manager.appendEventType(QmlEventType(PixmapCacheEvent, MaximumRangeType, i,
manager.appendEventType(QmlEventType(PixmapCacheEvent, UndefinedRangeType, i,
QmlEventLocation("dings.png", 0, 0)));
}
@@ -37,7 +37,7 @@ void PixmapCacheModelTest::initTestCase()
for (int i = 0; i < MaximumPixmapEventType; ++i) {
eventTypeIndices[i + MaximumPixmapEventType] = manager.numEventTypes();
manager.appendEventType(QmlEventType(PixmapCacheEvent, MaximumRangeType, i,
manager.appendEventType(QmlEventType(PixmapCacheEvent, UndefinedRangeType, i,
QmlEventLocation("blah.png", 0, 0)));
}

View File

@@ -15,13 +15,13 @@ QmlEventTypeTest::QmlEventTypeTest(QObject *parent) : QObject(parent)
void QmlEventTypeTest::testAccessors()
{
QmlEventType type;
QCOMPARE(type.message(), MaximumMessage);
QCOMPARE(type.rangeType(), MaximumRangeType);
QCOMPARE(type.message(), UndefinedMessage);
QCOMPARE(type.rangeType(), UndefinedMessage);
QCOMPARE(type.detailType(), -1);
QVERIFY(!type.location().isValid());
QVERIFY(type.data().isEmpty());
QVERIFY(type.displayName().isEmpty());
QCOMPARE(static_cast<ProfileFeature>(type.feature()), MaximumProfileFeature);
QCOMPARE(static_cast<ProfileFeature>(type.feature()), UndefinedProfileFeature);
type.setLocation(QmlEventLocation("blah.js", 12, 13));
QCOMPARE(type.location().filename(), QString("blah.js"));
@@ -34,9 +34,9 @@ void QmlEventTypeTest::testAccessors()
type.setDisplayName("disdis");
QCOMPARE(type.displayName(), QString("disdis"));
QmlEventType type2(MaximumMessage, Javascript, 12, QmlEventLocation("lala.js", 2, 3), "nehhh",
QmlEventType type2(UndefinedMessage, Javascript, 12, QmlEventLocation("lala.js", 2, 3), "nehhh",
"brbr");
QCOMPARE(type2.message(), MaximumMessage);
QCOMPARE(type2.message(), UndefinedMessage);
QCOMPARE(type2.rangeType(), Javascript);
QCOMPARE(type2.detailType(), 12);
QCOMPARE(type2.location(), QmlEventLocation("lala.js", 2, 3));
@@ -49,23 +49,23 @@ void QmlEventTypeTest::testFeature()
{
const quint8 features[][MaximumEventType] = {
// Event
{MaximumProfileFeature, ProfileInputEvents, ProfileInputEvents,
ProfileAnimations, MaximumProfileFeature, MaximumProfileFeature},
{UndefinedProfileFeature, ProfileInputEvents, ProfileInputEvents,
ProfileAnimations, UndefinedProfileFeature, UndefinedProfileFeature},
// RangeStart
{MaximumProfileFeature, MaximumProfileFeature, MaximumProfileFeature,
MaximumProfileFeature, MaximumProfileFeature, MaximumProfileFeature},
{UndefinedProfileFeature, UndefinedProfileFeature, UndefinedProfileFeature,
UndefinedProfileFeature, UndefinedProfileFeature, UndefinedProfileFeature},
// RangeData
{MaximumProfileFeature, MaximumProfileFeature, MaximumProfileFeature,
MaximumProfileFeature, MaximumProfileFeature, MaximumProfileFeature},
{UndefinedProfileFeature, UndefinedProfileFeature, UndefinedProfileFeature,
UndefinedProfileFeature, UndefinedProfileFeature, UndefinedProfileFeature},
// RangeLocation
{MaximumProfileFeature, MaximumProfileFeature, MaximumProfileFeature,
MaximumProfileFeature, MaximumProfileFeature, MaximumProfileFeature},
{UndefinedProfileFeature, UndefinedProfileFeature, UndefinedProfileFeature,
UndefinedProfileFeature, UndefinedProfileFeature, UndefinedProfileFeature},
// RangeEnd
{MaximumProfileFeature, MaximumProfileFeature, MaximumProfileFeature,
MaximumProfileFeature, MaximumProfileFeature, MaximumProfileFeature},
{UndefinedProfileFeature, UndefinedProfileFeature, UndefinedProfileFeature,
UndefinedProfileFeature, UndefinedProfileFeature, UndefinedProfileFeature},
// Complete
{MaximumProfileFeature, MaximumProfileFeature, MaximumProfileFeature,
MaximumProfileFeature, MaximumProfileFeature, MaximumProfileFeature},
{UndefinedProfileFeature, UndefinedProfileFeature, UndefinedProfileFeature,
UndefinedProfileFeature, UndefinedProfileFeature, UndefinedProfileFeature},
// PixmapCacheEvent
{ProfilePixmapCache, ProfilePixmapCache, ProfilePixmapCache,
ProfilePixmapCache, ProfilePixmapCache, ProfilePixmapCache},
@@ -85,13 +85,13 @@ void QmlEventTypeTest::testFeature()
for (int i = 0; i < MaximumMessage; ++i) {
for (int j = 0; j < MaximumEventType; ++j) {
QmlEventType type(static_cast<Message>(i), MaximumRangeType, j);
QmlEventType type(static_cast<Message>(i), UndefinedRangeType, j);
QCOMPARE(type.feature(), features[i][j]);
}
}
for (int i = 0; i < MaximumRangeType; ++i) {
QmlEventType type(MaximumMessage, static_cast<RangeType>(i));
QmlEventType type(UndefinedMessage, static_cast<RangeType>(i));
QCOMPARE(static_cast<ProfileFeature>(type.feature()),
featureFromRangeType(static_cast<RangeType>(i)));
}
@@ -99,7 +99,7 @@ void QmlEventTypeTest::testFeature()
void QmlEventTypeTest::testStreamOps()
{
QmlEventType type(MaximumMessage, Javascript, -1, QmlEventLocation("socken.js", 12, 13),
QmlEventType type(UndefinedMessage, Javascript, -1, QmlEventLocation("socken.js", 12, 13),
"lalala", "lelele");
QBuffer wbuffer;

View File

@@ -25,7 +25,7 @@ void QmlProfilerAnimationsModelTest::initTestCase()
QmlEvent event;
event.setTypeIndex(manager.appendEventType(
QmlEventType(Event, MaximumRangeType, AnimationFrame)));
QmlEventType(Event, UndefinedRangeType, AnimationFrame)));
for (int i = 0; i < 10; ++i) {
event.setTimestamp(i);

View File

@@ -27,7 +27,7 @@ DummyModel::DummyModel(QmlProfilerModelManager *manager,
void DummyModel::loadData()
{
QmlEventType type(MaximumMessage, Binding);
QmlEventType type(UndefinedMessage, Binding);
const int typeIndex = modelManager()->appendEventType(QmlEventType(type));
QCOMPARE(typeIndex, 0);

View File

@@ -57,9 +57,13 @@ void QmlProfilerTraceClientTest::testMessageReceived()
modelManager.replayQmlEvents([&](const QmlEvent &event, const QmlEventType &type) {
qint64 timestamp;
qint32 message;
qint32 rangeType;
quint8 message;
quint8 rangeType;
checkStream >> timestamp >> message >> rangeType;
QVERIFY(message != MaximumMessage);
QVERIFY(rangeType != MaximumRangeType);
QVERIFY(type.message() != MaximumMessage);
QVERIFY(type.rangeType() != MaximumRangeType);
QCOMPARE(event.timestamp(), timestamp);
QCOMPARE(type.message(), static_cast<Message>(message));
QCOMPARE(type.rangeType(), static_cast<RangeType>(rangeType));

View File

@@ -120,7 +120,8 @@ void UpdateInfoPlugin::doAutoCheckForUpdates()
void UpdateInfoPlugin::startCheckForUpdates()
{
stopCheckForUpdates();
if (d->m_maintenanceToolProcess)
return; // do not trigger while update task is already running
QFutureInterface<void> futureIf;
FutureProgress *futureProgress