Merge remote-tracking branch 'origin/4.15'
Change-Id: I528bff4d19dc4dfcb600e1e18b0d375c232eb417
@@ -94,7 +94,7 @@ function(qtc_output_binary_dir varName)
|
|||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(add_qtc_library name)
|
function(add_qtc_library name)
|
||||||
cmake_parse_arguments(_arg "STATIC;OBJECT;SKIP_TRANSLATION;ALLOW_ASCII_CASTS;UNVERSIONED"
|
cmake_parse_arguments(_arg "STATIC;OBJECT;SKIP_TRANSLATION;ALLOW_ASCII_CASTS;UNVERSIONED;FEATURE_INFO"
|
||||||
"DESTINATION;COMPONENT;SOURCES_PREFIX;BUILD_DEFAULT"
|
"DESTINATION;COMPONENT;SOURCES_PREFIX;BUILD_DEFAULT"
|
||||||
"CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;PUBLIC_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PROPERTIES" ${ARGN}
|
"CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;PUBLIC_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PROPERTIES" ${ARGN}
|
||||||
)
|
)
|
||||||
@@ -110,6 +110,7 @@ function(add_qtc_library name)
|
|||||||
|
|
||||||
update_cached_list(__QTC_LIBRARIES "${name}")
|
update_cached_list(__QTC_LIBRARIES "${name}")
|
||||||
|
|
||||||
|
condition_info(_extra_text _arg_CONDITION)
|
||||||
if (NOT _arg_CONDITION)
|
if (NOT _arg_CONDITION)
|
||||||
set(_arg_CONDITION ON)
|
set(_arg_CONDITION ON)
|
||||||
endif()
|
endif()
|
||||||
@@ -131,6 +132,9 @@ function(add_qtc_library name)
|
|||||||
set(_library_enabled OFF)
|
set(_library_enabled OFF)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(DEFINED _arg_FEATURE_INFO)
|
||||||
|
add_feature_info("Library ${name}" _library_enabled "${_extra_text}")
|
||||||
|
endif()
|
||||||
if (NOT _library_enabled)
|
if (NOT _library_enabled)
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
BIN
doc/qtcreator/images/qmldesigner-form-editor-move-cursor.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 15 KiB |
BIN
doc/qtcreator/images/qmldesigner-transition-editor-startup.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 6.6 KiB |
@@ -96,6 +96,7 @@
|
|||||||
\li \l{Library}
|
\li \l{Library}
|
||||||
\li \l{Navigator}
|
\li \l{Navigator}
|
||||||
\li \l{Properties}
|
\li \l{Properties}
|
||||||
|
\li \l{Transition Editor}
|
||||||
\endlist
|
\endlist
|
||||||
\li \l {Creating UIs}
|
\li \l {Creating UIs}
|
||||||
\list
|
\list
|
||||||
|
@@ -101,7 +101,7 @@
|
|||||||
actions.
|
actions.
|
||||||
\li \l{Adding States}
|
\li \l{Adding States}
|
||||||
\row
|
\row
|
||||||
\li \l{Animating Transitions Between States}{Transition Editor}
|
\li \l{Transition Editor}
|
||||||
\li Enables you to make movement between states smooth by animating
|
\li Enables you to make movement between states smooth by animating
|
||||||
the changes between states.
|
the changes between states.
|
||||||
\li \l{Animating Transitions Between States}
|
\li \l{Animating Transitions Between States}
|
||||||
|
@@ -33,47 +33,129 @@
|
|||||||
You design applications in the \uicontrol {Form Editor} view by placing
|
You design applications in the \uicontrol {Form Editor} view by placing
|
||||||
\l{Component Types}{2D components} and \l{Assets}{assets} into it.
|
\l{Component Types}{2D components} and \l{Assets}{assets} into it.
|
||||||
|
|
||||||
When you select items in \uicontrol {Form Editor}, markers
|
|
||||||
appear around their edges and in their corners. Depending on the shape of
|
|
||||||
the cursor, you can move, resize, or rotate the item by dragging it.
|
|
||||||
The following image shows the move cursor.
|
|
||||||
|
|
||||||
\image qmldesigner-form-editor.png "Form Editor view"
|
\image qmldesigner-form-editor.png "Form Editor view"
|
||||||
|
|
||||||
\section1 Resizing 2D Items
|
When you select components in \uicontrol {Form Editor}, markers appear
|
||||||
|
around their edges and in their corners. Depending on the shape of the
|
||||||
|
cursor, you can apply the following actions on the components by dragging
|
||||||
|
them:
|
||||||
|
|
||||||
When the resize cursor is displayed, you can drag the selection handles
|
\list
|
||||||
to resize items.
|
\li \l{Moving Components}{Move components}
|
||||||
|
\li \l{Resizing 2D Components}{Resize components}
|
||||||
|
\li \l{Rotating 2D Components}{Rotate components}
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
\section1 Summary of Form Editor Buttons
|
||||||
|
|
||||||
|
The \uicontrol {Form Editor} toolbar contains the following buttons and
|
||||||
|
fields.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Button/Field
|
||||||
|
\li Tooltip
|
||||||
|
\li Read More
|
||||||
|
\row
|
||||||
|
\li \inlineimage no_snapping.png
|
||||||
|
\li Disables snapping.
|
||||||
|
\li \l{Snapping to Parent and Sibling Components}
|
||||||
|
\row
|
||||||
|
\li \inlineimage snapping_and_anchoring.png
|
||||||
|
\li Anchors the component to the components that it is snapped to.
|
||||||
|
\li \l{Snapping to Parent and Sibling Components}
|
||||||
|
\row
|
||||||
|
\li \inlineimage snapping.png
|
||||||
|
\li Snaps components to their parent or sibling components when you
|
||||||
|
align them.
|
||||||
|
\li \l{Snapping to Parent and Sibling Components}
|
||||||
|
\row
|
||||||
|
\li \inlineimage boundingrect.png
|
||||||
|
\li Hides and shows component boundaries.
|
||||||
|
\li \l{Hiding Component Boundaries}
|
||||||
|
\row
|
||||||
|
\li \uicontrol {Override Width}
|
||||||
|
\li Shows a preview of the component using the specified width.
|
||||||
|
\li \l{Previewing Component Size}
|
||||||
|
\row
|
||||||
|
\li \uicontrol {Override Height}
|
||||||
|
\li Shows a preview of the component using the specified height.
|
||||||
|
\li \l{Previewing Component Size}
|
||||||
|
\row
|
||||||
|
\li \inlineimage icons/canvas-color.png
|
||||||
|
\li Sets the color of the \uicontrol {Form Editor} working area.
|
||||||
|
\li \l{Setting Canvas Color}
|
||||||
|
\row
|
||||||
|
\li \inlineimage icons/zoomIn.png
|
||||||
|
\li Zooms in.
|
||||||
|
\li \l{Zooming}
|
||||||
|
\row
|
||||||
|
\li \inlineimage icons/zoomOut.png
|
||||||
|
\li Zooms out.
|
||||||
|
\li \l{Zooming}
|
||||||
|
\row
|
||||||
|
\li Zoom level
|
||||||
|
\li Sets the zoom level that you select from the list.
|
||||||
|
\li \l{Zooming}
|
||||||
|
\row
|
||||||
|
\li \inlineimage icons/zoomAll.png
|
||||||
|
\li Zooms to fit all content.
|
||||||
|
\li \l{Zooming}
|
||||||
|
\row
|
||||||
|
\li \inlineimage icons/zoomSelection.png
|
||||||
|
\li Zooms to fit the current selection.
|
||||||
|
\li \l{Zooming}
|
||||||
|
\row
|
||||||
|
\li \inlineimage reset.png
|
||||||
|
\li Refreshes the contents of \uicontrol {Form Editor}.
|
||||||
|
\li \l{Refreshing Form Editor Contents}
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Moving Components
|
||||||
|
|
||||||
|
When the move cursor is displayed, you can move the selected component to
|
||||||
|
any position in \uicontrol {Form Editor}.
|
||||||
|
|
||||||
|
\image qmldesigner-form-editor-move-cursor.png "Move cursor in Form Editor view"
|
||||||
|
|
||||||
|
For more information about alternative ways of positioning components in
|
||||||
|
UIs, see \l{Positioning Items}.
|
||||||
|
|
||||||
|
\section1 Resizing 2D Components
|
||||||
|
|
||||||
|
When the resize cursor is displayed, you can drag the markers to resize
|
||||||
|
components.
|
||||||
|
|
||||||
\image qtquick-designer-scaling-items.png "Form Editor view"
|
\image qtquick-designer-scaling-items.png "Form Editor view"
|
||||||
|
|
||||||
\if defined(qtdesignstudio)
|
To have the resizing done from the center of the selected component rather
|
||||||
To have the resizing done from the center of the selected item instead from
|
than from its edges, press \key Alt (or the option key on \macos).
|
||||||
its edges, press \key Alt.
|
|
||||||
|
|
||||||
To preserve the image aspect ratio while resizing when using the corner
|
To preserve the image aspect ratio while resizing when using the corner
|
||||||
handles, press \key Shift. This also works on items that are anchored
|
markers, press \key Shift. This also works on components that are anchored
|
||||||
using left, right, top, or bottom anchors.
|
using left, right, top, or bottom anchors.
|
||||||
|
|
||||||
To both resize from the center of the item and preserve the aspect ratio,
|
To both resize from the center of the component and preserve the aspect
|
||||||
press \key Alt+Shift.
|
ratio, press \key Alt+Shift (or the option key + \key Shift on \macos).
|
||||||
\endif
|
|
||||||
|
|
||||||
\section1 Rotating 2D Items
|
For more information about alternative ways to specify the size of a
|
||||||
|
component in a UI, see \l{2D Geometry}.
|
||||||
|
|
||||||
|
\section1 Rotating 2D Components
|
||||||
|
|
||||||
When the rotation cursor \inlineimage icons/rotation-cursor.png
|
When the rotation cursor \inlineimage icons/rotation-cursor.png
|
||||||
is displayed in one of the corners of an item, you can drag
|
is displayed in one of the corners of a component, you can drag
|
||||||
clockwise or counter-clockwise to freely rotate the item around
|
clockwise or counter-clockwise to freely rotate the component around
|
||||||
its origin in \uicontrol {Form Editor}.
|
its origin.
|
||||||
|
|
||||||
\image qtquick-designer-rotating-items.png "2D rotation tool"
|
\image qtquick-designer-rotating-items.png "2D rotation tool"
|
||||||
|
|
||||||
Additionally, press \key Shift or \key Alt to rotate items in steps of 5 or
|
Additionally, press \key Shift or \key Alt (or the option key on \macos)
|
||||||
45 degrees, respectively.
|
to rotate components in steps of 5 or 45 degrees, respectively.
|
||||||
|
|
||||||
You can set the \l{Managing 2D Transformations}{origin} in the
|
You can set the \l{Managing 2D Transformations}{origin} in the
|
||||||
\uicontrol Origin field in the \uicontrol Advanced tab in the
|
\uicontrol Origin field in the \uicontrol Advanced tab in the
|
||||||
\uicontrol Properties view. There, you can also enter the value
|
\l Properties view. There, you can also enter the value
|
||||||
of the \uicontrol Rotation property in degrees.
|
of the \uicontrol Rotation property in degrees.
|
||||||
|
|
||||||
\section1 Zooming
|
\section1 Zooming
|
||||||
@@ -85,43 +167,23 @@
|
|||||||
|
|
||||||
\image qmldesigner-zooming.gif "Zooming in Form Editor"
|
\image qmldesigner-zooming.gif "Zooming in Form Editor"
|
||||||
|
|
||||||
The following table lists the zoom buttons:
|
\section1 Snapping to Parent and Sibling Components
|
||||||
|
|
||||||
\table
|
You can use snapping to align components in \uicontrol {Form Editor}.
|
||||||
\header
|
Click the \inlineimage snapping.png
|
||||||
\li Icon
|
button to have the components snap to their parent or sibling components.
|
||||||
\li Tooltip
|
Snapping lines automatically appear to help you position the components.
|
||||||
\row
|
|
||||||
\li \inlineimage icons/zoomIn.png
|
|
||||||
\li Zoom in
|
|
||||||
\row
|
|
||||||
\li \inlineimage icons/zoomOut.png
|
|
||||||
\li Zoom out
|
|
||||||
\row
|
|
||||||
\li \inlineimage icons/zoomAll.png
|
|
||||||
\li Zoom to fit all content
|
|
||||||
\row
|
|
||||||
\li \inlineimage icons/zoomSelection.png
|
|
||||||
\li Zoom to fit the current selection
|
|
||||||
\endtable
|
|
||||||
|
|
||||||
\section1 Snapping to Parent and Sibling Items
|
|
||||||
|
|
||||||
When you are working on a design, you can use snapping to align
|
|
||||||
items in \uicontrol {Form Editor}. Click the \inlineimage snapping.png
|
|
||||||
button to have the items snap to their parent or sibling items. Snapping
|
|
||||||
lines automatically appear to help you position the items.
|
|
||||||
Click the \inlineimage snapping_and_anchoring.png
|
Click the \inlineimage snapping_and_anchoring.png
|
||||||
button to anchor the item to the items that you snap to.
|
button to anchor the component to the components that you snap to.
|
||||||
Only one snapping button can be selected at the time. Selecting
|
Only one snapping button can be selected at the time. Selecting
|
||||||
one snapping button automatically deselects the others.
|
one snapping button automatically deselects the others.
|
||||||
|
|
||||||
Choose \uicontrol Tools > \uicontrol Options > \uicontrol {Qt Quick} >
|
Choose \uicontrol Tools > \uicontrol Options > \uicontrol {Qt Quick} >
|
||||||
\uicontrol {Qt Quick Designer} to specify settings for snapping. In the
|
\uicontrol {Qt Quick Designer} to specify settings for snapping. In the
|
||||||
\uicontrol {Parent item padding} field, specify the
|
\uicontrol {Parent item padding} field, specify the
|
||||||
distance in pixels between the parent item and the snapping lines. In the
|
distance in pixels between the parent component and the snapping lines. In
|
||||||
\uicontrol {Sibling item spacing} field, specify the distance in pixels between
|
the \uicontrol {Sibling item spacing} field, specify the distance in pixels
|
||||||
sibling items and the snapping lines.
|
between sibling components and the snapping lines.
|
||||||
|
|
||||||
\image qtquick-designer-options.png "Qt Quick Designer options"
|
\image qtquick-designer-options.png "Qt Quick Designer options"
|
||||||
|
|
||||||
@@ -130,33 +192,36 @@
|
|||||||
|
|
||||||
\image qmldesigner-snap-margins.png "Snapping lines on canvas"
|
\image qmldesigner-snap-margins.png "Snapping lines on canvas"
|
||||||
|
|
||||||
\section1 Hiding Item Boundaries
|
For alternative ways of aligning and distributing components by using the
|
||||||
|
\l Properties view, see \l{Aligning and Distributing Items}.
|
||||||
|
|
||||||
\uicontrol {Form Editor} displays the boundaries of items.
|
\section1 Hiding Component Boundaries
|
||||||
|
|
||||||
|
\uicontrol {Form Editor} displays the boundaries of components.
|
||||||
To hide them, select the \inlineimage boundingrect.png
|
To hide them, select the \inlineimage boundingrect.png
|
||||||
button.
|
button.
|
||||||
|
|
||||||
\section1 Previewing Component Size
|
\section1 Previewing Component Size
|
||||||
|
|
||||||
The width and height of the root item in a QML file determine the size of
|
The width and height of the root component in a UI file determine the size
|
||||||
the component. You can reuse components, such as buttons, in different
|
of the component. You can reuse components, such as buttons, in different
|
||||||
sizes in other QML files and design UIs for use with different device
|
sizes in other UI files and design UIs for use with different device
|
||||||
profiles, screen resolution, or screen orientation. The component size
|
profiles, screen resolution, or screen orientation. The component size
|
||||||
might also be zero (0,0) if its final size is determined by property
|
might also be zero (0,0) if its final size is determined by
|
||||||
bindings.
|
\l{Setting Bindings}{property bindings}.
|
||||||
|
|
||||||
To experiment with different component sizes, enter values in the
|
To experiment with different component sizes, enter values in the
|
||||||
\uicontrol {Override Width} and \uicontrol {Override Height} fields (1) on
|
\uicontrol {Override Width} and \uicontrol {Override Height} fields (1) on
|
||||||
the canvas toolbar. The changes are displayed in the \uicontrol {Form Editor}
|
the toolbar. The changes are displayed in the \uicontrol {Form Editor}
|
||||||
view (2) and in the \uicontrol States view (3), but the property
|
view (2) and in the \uicontrol States view (3), but the property
|
||||||
values are not changed permanently in the QML file. You can permanently
|
values are not changed permanently in the UI file. You can permanently
|
||||||
change the property values in the \uicontrol Properties view (4).
|
change the property values in the \uicontrol Properties view (4).
|
||||||
|
|
||||||
\image qmldesigner-preview-size.png "Canvas width and height"
|
\image qmldesigner-preview-size.png "Component width and height"
|
||||||
|
|
||||||
To set the initial size of the root item, select \uicontrol Tools >
|
To set the initial size of the root component, select \uicontrol Tools >
|
||||||
\uicontrol Options > \uicontrol {Qt Quick} > \uicontrol {Qt Quick Designer} and
|
\uicontrol Options > \uicontrol {Qt Quick} > \uicontrol {Qt Quick Designer} and
|
||||||
specify the item width and height in the \uicontrol {Root Item Init Size}
|
specify the component width and height in the \uicontrol {Root Item Init Size}
|
||||||
group.
|
group.
|
||||||
|
|
||||||
\section1 Specifying Canvas Size
|
\section1 Specifying Canvas Size
|
||||||
@@ -167,8 +232,8 @@
|
|||||||
|
|
||||||
\section1 Setting Canvas Color
|
\section1 Setting Canvas Color
|
||||||
|
|
||||||
If you set the background of the root item of your component transparent,
|
If you set the background of the root component transparent, the color of
|
||||||
the canvas color can make it difficult to see the component you are working
|
the working area can make it difficult to see the component you are working
|
||||||
on. To make components more visible, you can select the canvas color in
|
on. To make components more visible, you can select the canvas color in
|
||||||
the \inlineimage icons/canvas-color.png
|
the \inlineimage icons/canvas-color.png
|
||||||
list. By default, the color is transparent. Setting the canvas color does
|
list. By default, the color is transparent. Setting the canvas color does
|
||||||
@@ -176,13 +241,14 @@
|
|||||||
|
|
||||||
\image qmldesigner-canvas-color.png "Transparent canvas color for a transparent component"
|
\image qmldesigner-canvas-color.png "Transparent canvas color for a transparent component"
|
||||||
|
|
||||||
\section1 Refreshing the Form Editor Contents
|
\section1 Refreshing Form Editor Contents
|
||||||
|
|
||||||
When you open QML files in the Design mode, the items in the file are drawn
|
When you open a UI file, the components in the file are drawn in
|
||||||
in \uicontrol {Form Editor}. When you edit the item properties, the QML
|
\uicontrol {Form Editor}. When you edit component properties in
|
||||||
file and the contents of the editor might get out of sync. For example, when
|
\l Properties, the code and its representation in \uicontrol {Form Editor}
|
||||||
you change the position of an item within a column or a row, the new
|
might get out of sync. For example, when you change the position of a
|
||||||
position might not be displayed correctly in \uicontrol {Form Editor}.
|
component within a column or a row, the new position might not be displayed
|
||||||
|
correctly in \uicontrol {Form Editor}.
|
||||||
|
|
||||||
To refresh the contents of \uicontrol {Form Editor}, press \key R or
|
To refresh the contents of \uicontrol {Form Editor}, press \key R or
|
||||||
select the \inlineimage reset.png
|
select the \inlineimage reset.png
|
||||||
|
@@ -71,7 +71,7 @@
|
|||||||
The value of the \uicontrol {Custom ID} field specifies the name of an
|
The value of the \uicontrol {Custom ID} field specifies the name of an
|
||||||
\l{Annotating Designs}{annotation}.
|
\l{Annotating Designs}{annotation}.
|
||||||
|
|
||||||
\section2 Geometry
|
\section2 2D Geometry
|
||||||
|
|
||||||
In the \uicontrol Position group, you can set the position of a component on
|
In the \uicontrol Position group, you can set the position of a component on
|
||||||
the x and y axis. The position of a component in the UI can be either
|
the x and y axis. The position of a component in the UI can be either
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
it in the \uicontrol Z field in the \uicontrol Advanced tab.
|
it in the \uicontrol Z field in the \uicontrol Advanced tab.
|
||||||
|
|
||||||
In the \uicontrol Size group, you can set the width and height of a
|
In the \uicontrol Size group, you can set the width and height of a
|
||||||
component. You can also use the resize cursor to \l{Resizing 2D Items}
|
component. You can also use the resize cursor to \l{Resizing 2D Components}
|
||||||
{resize 2D components} in \uicontrol {Form Editor} or the scaling gizmo
|
{resize 2D components} in \uicontrol {Form Editor} or the scaling gizmo
|
||||||
to \l{Scaling Items}{scale 3D components} in \uicontrol {3D Editor}.
|
to \l{Scaling Items}{scale 3D components} in \uicontrol {3D Editor}.
|
||||||
The values in the \uicontrol X and \uicontrol Y fields change accordingly.
|
The values in the \uicontrol X and \uicontrol Y fields change accordingly.
|
||||||
|
@@ -61,6 +61,8 @@
|
|||||||
\li Show a different view.
|
\li Show a different view.
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
|
You can animate transitions between states in \l{Transition Editor}.
|
||||||
|
|
||||||
\section1 Creating States
|
\section1 Creating States
|
||||||
|
|
||||||
To open the \uicontrol States view, select \uicontrol View >
|
To open the \uicontrol States view, select \uicontrol View >
|
||||||
@@ -208,6 +210,4 @@
|
|||||||
\if defined(qtcreator)
|
\if defined(qtcreator)
|
||||||
\include qtquick-states-scxml.qdocinc scxml state machines
|
\include qtquick-states-scxml.qdocinc scxml state machines
|
||||||
\endif
|
\endif
|
||||||
|
|
||||||
\include qtquick-transition-editor.qdocinc transition editor
|
|
||||||
*/
|
*/
|
||||||
|
143
doc/qtcreator/src/qtquick/qtquick-transition-editor.qdoc
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Creator documentation.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** 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 qtquick-transition-editor.html
|
||||||
|
\previouspage qtquick-states-view.html
|
||||||
|
\nextpage qtquick-timeline-view.html
|
||||||
|
|
||||||
|
\title Transition Editor
|
||||||
|
|
||||||
|
To make movement between states smooth, you can use
|
||||||
|
\uicontrol {Transition Editor} to animate the changes between
|
||||||
|
states.
|
||||||
|
|
||||||
|
First, you need to \l{Adding States}{add states} in the \l States view
|
||||||
|
and \l{Specifying Component Properties}{edit some properties} that can be
|
||||||
|
animated, such as colors or numbers, in the \l Properties view. For example,
|
||||||
|
you can animate the changes in the position of a component.
|
||||||
|
|
||||||
|
\image qtquick-transition-editor-view.png "Transition Editor view"
|
||||||
|
|
||||||
|
In \uicontrol {Transition Editor}, you can set the start frame, end
|
||||||
|
frame, and duration for the transition of each property. You can also
|
||||||
|
set an \l{Editing Easing Curves}{easing curve} for each animation and
|
||||||
|
the maximum duration of the whole transition.
|
||||||
|
|
||||||
|
\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
|
||||||
|
buttons to zoom out of or into the view.
|
||||||
|
|
||||||
|
\section1 Summary of Transition Editor Toolbar Actions
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Button/Field
|
||||||
|
\li Action
|
||||||
|
\li Read More
|
||||||
|
\row
|
||||||
|
\li \inlineimage animation.png
|
||||||
|
\li Opens \uicontrol {Transition Settings} dialog for editing
|
||||||
|
transition settings.
|
||||||
|
\li \l{Specifying Transition Settings}
|
||||||
|
\row
|
||||||
|
\li Transition ID
|
||||||
|
\li Displays a list of transitions that you can open in
|
||||||
|
\uicontrol {Transition Editor}.
|
||||||
|
\li \l{Animating Transitions Between States}
|
||||||
|
\row
|
||||||
|
\li \inlineimage 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 \uicontrol {Zoom Out} (\key Ctrl+-): zooms out of the view.
|
||||||
|
\li \l{Zooming in Transition Editor}
|
||||||
|
\row
|
||||||
|
\li Slider
|
||||||
|
\li Sets the zooming level.
|
||||||
|
\li \l{Zooming in Transition Editor}
|
||||||
|
\row
|
||||||
|
\li \inlineimage zoom_big.png
|
||||||
|
\li \uicontrol {Zoom In} (\key Ctrl++): zooms into the view.
|
||||||
|
\li \l{Zooming in Transition Editor}
|
||||||
|
\row
|
||||||
|
\li Maximum Duration
|
||||||
|
\li Specifies the maximum duration of the transition.
|
||||||
|
\li
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Animating Transitions Between States
|
||||||
|
|
||||||
|
To animate transitions:
|
||||||
|
|
||||||
|
\list 1
|
||||||
|
\li Select \uicontrol View > \uicontrol Views >
|
||||||
|
\uicontrol {Transition Editor}.
|
||||||
|
\image qmldesigner-transition-editor-startup.png "Empty Transition Editor"
|
||||||
|
\li Select the \inlineimage plus.png
|
||||||
|
(\uicontrol {Add Transition}) button to add a transition. This
|
||||||
|
works only if you have added at least one state and modified at
|
||||||
|
least one property in it.
|
||||||
|
\image qtquick-transition-editor-view.png "Transition Editor view"
|
||||||
|
\li Move the blue bar next to the component or property name to set
|
||||||
|
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
|
||||||
|
(\uicontrol {Easing Curve Editor (C)}) button.
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
\section1 Specifying Transition Settings
|
||||||
|
|
||||||
|
To modify transition settings, select the \inlineimage animation.png
|
||||||
|
(\uicontrol {Transition Settings (S)}) button in
|
||||||
|
\uicontrol {Transition Editor}.
|
||||||
|
|
||||||
|
\image qtquick-transition-editor-settings.png "Transition settings"
|
||||||
|
|
||||||
|
To add transitions:
|
||||||
|
|
||||||
|
\list 1
|
||||||
|
\li Select the \inlineimage plus.png
|
||||||
|
(\uicontrol {Add Transition}) button.
|
||||||
|
\li In the \uicontrol {Transition ID} field, enter an ID for the
|
||||||
|
transition.
|
||||||
|
\li In the \uicontrol From field, select the state to transition from.
|
||||||
|
\li In the \uicontrol To field, select the state to transition to.
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
To remove the current transition, select the \inlineimage minus.png
|
||||||
|
(\uicontrol {Remove Transition}) button.
|
||||||
|
|
||||||
|
\if defined(qtcreator)
|
||||||
|
For an example of animating transitions between states, see
|
||||||
|
\l {Creating a Qt Quick Application}.
|
||||||
|
\endif
|
||||||
|
*/
|
@@ -1,73 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2020 The Qt Company Ltd.
|
|
||||||
** Contact: https://www.qt.io/licensing/
|
|
||||||
**
|
|
||||||
** This file is part of the Qt Creator 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.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
//! [transition editor]
|
|
||||||
|
|
||||||
\section1 Animating Transitions Between States
|
|
||||||
|
|
||||||
To make movement between states smooth, you can use
|
|
||||||
\uicontrol {Transition Editor} to animate the changes between
|
|
||||||
states. First, you need to \l{Creating States}{add states} in
|
|
||||||
the \uicontrol States view and \l{Specifying Component Properties}
|
|
||||||
{edit some properties} that can be animated, such as colors or
|
|
||||||
numbers, in the \uicontrol Properties view. For example, you
|
|
||||||
can animate the changes in the position of an object.
|
|
||||||
|
|
||||||
In \uicontrol {Transition Editor}, you can set the start frame, end
|
|
||||||
frame, and duration for the transition of each property. You can also
|
|
||||||
set an easing curve for each transition.
|
|
||||||
|
|
||||||
Use the slider on the menu bar to the zooming level in the view.
|
|
||||||
|
|
||||||
To add transitions:
|
|
||||||
|
|
||||||
\list 1
|
|
||||||
\li Select \uicontrol View > \uicontrol Views >
|
|
||||||
\uicontrol {Transition Editor} to display the view.
|
|
||||||
\li Select the \inlineimage plus.png
|
|
||||||
(\uicontrol {Add Transition}) button to add a transition. This
|
|
||||||
works only if you have added at least one state and modified at
|
|
||||||
least one property in it.
|
|
||||||
\image qtquick-transition-editor-view.png "Transition Editor view"
|
|
||||||
\li Move the blue bar next to the component or property name to set
|
|
||||||
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 easing curve to a transition, select
|
|
||||||
\inlineimage curve_editor.png
|
|
||||||
(\uicontrol {Easing Curve Editor (C)}) on the toolbar. For more
|
|
||||||
information, see \l{Editing Easing Curves}.
|
|
||||||
\li To modify transition settings, select the \inlineimage animation.png
|
|
||||||
(\uicontrol {Transition Settings (S)}) button on the toolbar.
|
|
||||||
\image qtquick-transition-editor-settings.png "Transition settings"
|
|
||||||
\endlist
|
|
||||||
|
|
||||||
\if defined(qtcreator)
|
|
||||||
For an example of animating transitions between states, see
|
|
||||||
\l {Creating a Qt Quick Application}.
|
|
||||||
\endif
|
|
||||||
|
|
||||||
//! [transition editor]
|
|
||||||
*/
|
|
@@ -62,6 +62,7 @@
|
|||||||
\li \l{Library}
|
\li \l{Library}
|
||||||
\li \l{Navigator}
|
\li \l{Navigator}
|
||||||
\li \l{Properties}
|
\li \l{Properties}
|
||||||
|
\li \l{Transition Editor}
|
||||||
\endlist
|
\endlist
|
||||||
\li \l{Managing Workspaces}
|
\li \l{Managing Workspaces}
|
||||||
\li \l{Managing Sessions}
|
\li \l{Managing Sessions}
|
||||||
|
@@ -787,8 +787,6 @@ class Dumper(DumperBase):
|
|||||||
def removeTypePrefix(self, name):
|
def removeTypePrefix(self, name):
|
||||||
return re.sub('^(struct|class|union|enum|typedef) ', '', name)
|
return re.sub('^(struct|class|union|enum|typedef) ', '', name)
|
||||||
|
|
||||||
__funcSignature_Regex__ = re.compile(r'^.+\(.*\)')
|
|
||||||
|
|
||||||
def lookupNativeType(self, name):
|
def lookupNativeType(self, name):
|
||||||
#DumperBase.warn('LOOKUP TYPE NAME: %s' % name)
|
#DumperBase.warn('LOOKUP TYPE NAME: %s' % name)
|
||||||
typeobj = self.typeCache.get(name)
|
typeobj = self.typeCache.get(name)
|
||||||
@@ -809,7 +807,7 @@ class Dumper(DumperBase):
|
|||||||
# Note that specifying a prefix like enum or typedef or class will make the call fail to
|
# Note that specifying a prefix like enum or typedef or class will make the call fail to
|
||||||
# find the type, thus the prefix is stripped.
|
# find the type, thus the prefix is stripped.
|
||||||
nonPrefixedName = self.canonicalTypeName(self.removeTypePrefix(name))
|
nonPrefixedName = self.canonicalTypeName(self.removeTypePrefix(name))
|
||||||
if __funcSignature_Regex__.match(nonPrefixedName) is not None:
|
if re.match(r'^.+\(.*\)', nonPrefixedName) is not None:
|
||||||
return lldb.SBType()
|
return lldb.SBType()
|
||||||
|
|
||||||
typeobjlist = self.target.FindTypes(nonPrefixedName)
|
typeobjlist = self.target.FindTypes(nonPrefixedName)
|
||||||
@@ -851,7 +849,7 @@ class Dumper(DumperBase):
|
|||||||
def lookupNativeTypeInAllModules(self, name):
|
def lookupNativeTypeInAllModules(self, name):
|
||||||
needle = self.canonicalTypeName(name)
|
needle = self.canonicalTypeName(name)
|
||||||
#DumperBase.warn('NEEDLE: %s ' % needle)
|
#DumperBase.warn('NEEDLE: %s ' % needle)
|
||||||
self.warn('Searching for type %s across all target modules, this could be very slow' % name)
|
DumperBase.warn('Searching for type %s across all target modules, this could be very slow' % name)
|
||||||
for i in range(self.target.GetNumModules()):
|
for i in range(self.target.GetNumModules()):
|
||||||
module = self.target.GetModuleAtIndex(i)
|
module = self.target.GetModuleAtIndex(i)
|
||||||
# SBModule.GetType is new somewhere after early 300.x
|
# SBModule.GetType is new somewhere after early 300.x
|
||||||
|
@@ -13,7 +13,6 @@ versionAtLeast(QT_VERSION, 5.15.0) {
|
|||||||
|
|
||||||
HEADERS += $$PWD/qt5nodeinstanceserver.h \
|
HEADERS += $$PWD/qt5nodeinstanceserver.h \
|
||||||
$$PWD/capturenodeinstanceserverdispatcher.h \
|
$$PWD/capturenodeinstanceserverdispatcher.h \
|
||||||
$$PWD/capturescenecreatedcommand.h \
|
|
||||||
$$PWD/nodeinstanceserverdispatcher.h \
|
$$PWD/nodeinstanceserverdispatcher.h \
|
||||||
$$PWD/qt5captureimagenodeinstanceserver.h \
|
$$PWD/qt5captureimagenodeinstanceserver.h \
|
||||||
$$PWD/qt5capturepreviewnodeinstanceserver.h \
|
$$PWD/qt5capturepreviewnodeinstanceserver.h \
|
||||||
|
@@ -29,6 +29,9 @@ import QtQuickDesignerTheme 1.0
|
|||||||
import HelperWidgets 2.0
|
import HelperWidgets 2.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
id: delegateRoot
|
||||||
|
signal showContextMenu()
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.rightMargin: 1
|
anchors.rightMargin: 1
|
||||||
anchors.topMargin: 1
|
anchors.topMargin: 1
|
||||||
@@ -71,11 +74,12 @@ Item {
|
|||||||
|
|
||||||
ImagePreviewTooltipArea {
|
ImagePreviewTooltipArea {
|
||||||
id: mouseRegion
|
id: mouseRegion
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onShowContextMenu: delegateRoot.showContextMenu()
|
||||||
onPressed: {
|
onPressed: {
|
||||||
rootView.startDragAndDrop(itemLibraryEntry)
|
if (mouse.button === Qt.LeftButton)
|
||||||
|
rootView.startDragAndDrop(itemLibraryEntry, mapToGlobal(mouse.x, mouse.y))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -77,11 +77,14 @@ ScrollView {
|
|||||||
id: itemsView
|
id: itemsView
|
||||||
|
|
||||||
property string importToRemove: ""
|
property string importToRemove: ""
|
||||||
|
property string importToAdd: ""
|
||||||
|
property var currentItem: null
|
||||||
|
|
||||||
// called from C++ to close context menu on focus out
|
// called from C++ to close context menu on focus out
|
||||||
function closeContextMenu()
|
function closeContextMenu()
|
||||||
{
|
{
|
||||||
contextMenu.close()
|
importContextMenu.close()
|
||||||
|
itemContextMenu.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
@@ -99,11 +102,11 @@ ScrollView {
|
|||||||
2 * cellVerticalMargin + cellVerticalSpacing
|
2 * cellVerticalMargin + cellVerticalSpacing
|
||||||
|
|
||||||
StudioControls.Menu {
|
StudioControls.Menu {
|
||||||
id: contextMenu
|
id: importContextMenu
|
||||||
|
|
||||||
StudioControls.MenuItem {
|
StudioControls.MenuItem {
|
||||||
text: qsTr("Remove Module")
|
text: qsTr("Remove Module")
|
||||||
enabled: importToRemove !== "" && importToRemove !== "QtQuick"
|
enabled: importToRemove !== ""
|
||||||
onTriggered: rootView.removeImport(importToRemove)
|
onTriggered: rootView.removeImport(importToRemove)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,6 +122,19 @@ ScrollView {
|
|||||||
onTriggered: itemLibraryModel.collapseAll()
|
onTriggered: itemLibraryModel.collapseAll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StudioControls.Menu {
|
||||||
|
id: itemContextMenu
|
||||||
|
// Workaround for menu item implicit width not properly propagating to menu
|
||||||
|
width: importMenuItem.implicitWidth
|
||||||
|
|
||||||
|
StudioControls.MenuItem {
|
||||||
|
id: importMenuItem
|
||||||
|
text: qsTr("Import Module: ") + importToAdd
|
||||||
|
enabled: currentItem
|
||||||
|
onTriggered: rootView.addImportForItem(currentItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
@@ -144,8 +160,8 @@ ScrollView {
|
|||||||
importExpanded = !importExpanded
|
importExpanded = !importExpanded
|
||||||
}
|
}
|
||||||
onShowContextMenu: {
|
onShowContextMenu: {
|
||||||
importToRemove = importUsed ? "" : importUrl
|
importToRemove = importRemovable ? importUrl : ""
|
||||||
contextMenu.popup()
|
importContextMenu.popup()
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
@@ -180,6 +196,15 @@ ScrollView {
|
|||||||
visible: itemVisible
|
visible: itemVisible
|
||||||
width: styleConstants.cellWidth + itemGrid.flexibleWidth
|
width: styleConstants.cellWidth + itemGrid.flexibleWidth
|
||||||
height: styleConstants.cellHeight
|
height: styleConstants.cellHeight
|
||||||
|
onShowContextMenu: {
|
||||||
|
if (!itemUsable) {
|
||||||
|
importToAdd = itemRequiredImport
|
||||||
|
if (importToAdd !== "") {
|
||||||
|
currentItem = itemLibraryEntry
|
||||||
|
itemContextMenu.popup()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -30,12 +30,19 @@ import QtQuick.Layouts 1.0
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
|
|
||||||
|
signal showContextMenu()
|
||||||
|
|
||||||
onExited: tooltipBackend.hideTooltip()
|
onExited: tooltipBackend.hideTooltip()
|
||||||
onCanceled: tooltipBackend.hideTooltip()
|
onCanceled: tooltipBackend.hideTooltip()
|
||||||
onClicked: forceActiveFocus()
|
|
||||||
onPositionChanged: tooltipBackend.reposition()
|
onPositionChanged: tooltipBackend.reposition()
|
||||||
|
onClicked: {
|
||||||
|
forceActiveFocus()
|
||||||
|
if (mouse.button === Qt.RightButton)
|
||||||
|
showContextMenu()
|
||||||
|
}
|
||||||
|
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
interval: 1000
|
interval: 1000
|
||||||
|
@@ -17,3 +17,11 @@ add_qtc_library(ExtensionSystem
|
|||||||
pluginmanager_p.h
|
pluginmanager_p.h
|
||||||
SKIP_AUTOMOC pluginmanager.cpp
|
SKIP_AUTOMOC pluginmanager.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
find_package(Qt5 COMPONENTS Test QUIET)
|
||||||
|
|
||||||
|
extend_qtc_library(ExtensionSystem
|
||||||
|
CONDITION TARGET Qt5::Test
|
||||||
|
DEPENDS Qt5::Test
|
||||||
|
DEFINES WITH_TESTS
|
||||||
|
)
|
||||||
|
@@ -1474,7 +1474,7 @@ void PluginManagerPrivate::loadPlugin(PluginSpec *spec, PluginSpec::State destSt
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
std::unique_ptr<LockFile> lockFile;
|
std::unique_ptr<LockFile> lockFile;
|
||||||
if (enableCrashCheck)
|
if (enableCrashCheck && destState < PluginSpec::Stopped)
|
||||||
lockFile.reset(new LockFile(this, spec));
|
lockFile.reset(new LockFile(this, spec));
|
||||||
|
|
||||||
switch (destState) {
|
switch (destState) {
|
||||||
|
@@ -5,6 +5,8 @@ if (WITH_TESTS)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_qtc_library(Tracing
|
add_qtc_library(Tracing
|
||||||
|
CONDITION Qt5_VERSION VERSION_LESS 6.0.0
|
||||||
|
FEATURE_INFO
|
||||||
DEPENDS Utils Qt5::Qml Qt5::Quick
|
DEPENDS Utils Qt5::Qml Qt5::Quick
|
||||||
PUBLIC_DEPENDS Qt5::Widgets
|
PUBLIC_DEPENDS Qt5::Widgets
|
||||||
SOURCES ${TEST_SOURCES}
|
SOURCES ${TEST_SOURCES}
|
||||||
|
@@ -1131,6 +1131,8 @@ void StringAspect::update()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (d->m_textEditDisplay) {
|
if (d->m_textEditDisplay) {
|
||||||
|
const QString old = d->m_textEditDisplay->document()->toPlainText();
|
||||||
|
if (displayedString != old)
|
||||||
d->m_textEditDisplay->setText(displayedString);
|
d->m_textEditDisplay->setText(displayedString);
|
||||||
d->updateWidgetFromCheckStatus(d->m_textEditDisplay.data());
|
d->updateWidgetFromCheckStatus(d->m_textEditDisplay.data());
|
||||||
}
|
}
|
||||||
|
@@ -519,15 +519,14 @@ void CMakeBuildSettingsWidget::updateButtonState()
|
|||||||
break;
|
break;
|
||||||
case CMakeProjectManager::ConfigModel::DataItem::UNKNOWN:
|
case CMakeProjectManager::ConfigModel::DataItem::UNKNOWN:
|
||||||
default:
|
default:
|
||||||
ni.type = CMakeConfigItem::INTERNAL;
|
ni.type = CMakeConfigItem::UNINITIALIZED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return ni;
|
return ni;
|
||||||
});
|
});
|
||||||
|
|
||||||
m_resetButton->setEnabled(m_configModel->hasChanges() && !isParsing);
|
m_resetButton->setEnabled(m_configModel->hasChanges() && !isParsing);
|
||||||
m_reconfigureButton->setEnabled((!configChanges.isEmpty() || m_configModel->hasCMakeChanges())
|
m_reconfigureButton->setEnabled(!configChanges.isEmpty() && !isParsing);
|
||||||
&& !isParsing);
|
|
||||||
m_buildConfiguration->setConfigurationChanges(configChanges);
|
m_buildConfiguration->setConfigurationChanges(configChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -56,6 +56,7 @@
|
|||||||
|
|
||||||
#include <utils/checkablemessagebox.h>
|
#include <utils/checkablemessagebox.h>
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
|
#include <utils/macroexpander.h>
|
||||||
#include <utils/mimetypes/mimetype.h>
|
#include <utils/mimetypes/mimetype.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
@@ -283,8 +284,7 @@ void CMakeBuildSystem::triggerParsing()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((0 == (reparseParameters & REPARSE_FORCE_EXTRA_CONFIGURATION))
|
if ((0 == (reparseParameters & REPARSE_FORCE_EXTRA_CONFIGURATION))
|
||||||
&& !m_parameters.extraCMakeArguments.isEmpty()) {
|
&& mustApplyExtraArguments(m_parameters)) {
|
||||||
if (mustApplyExtraArguments())
|
|
||||||
reparseParameters |= REPARSE_FORCE_CMAKE_RUN | REPARSE_FORCE_EXTRA_CONFIGURATION;
|
reparseParameters |= REPARSE_FORCE_CMAKE_RUN | REPARSE_FORCE_EXTRA_CONFIGURATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,6 +372,27 @@ QString CMakeBuildSystem::reparseParametersString(int reparseFlags)
|
|||||||
return result.trimmed();
|
return result.trimmed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMakeBuildSystem::writeConfigurationIntoBuildDirectory()
|
||||||
|
{
|
||||||
|
const Utils::MacroExpander *expander = cmakeBuildConfiguration()->macroExpander();
|
||||||
|
const FilePath buildDir = workDirectory(m_parameters);
|
||||||
|
QTC_ASSERT(buildDir.exists(), return );
|
||||||
|
|
||||||
|
const FilePath settingsFile = buildDir.pathAppended("qtcsettings.cmake");
|
||||||
|
|
||||||
|
QByteArray contents;
|
||||||
|
contents.append("# This file is managed by Qt Creator, do not edit!\n\n");
|
||||||
|
contents.append(
|
||||||
|
transform(cmakeBuildConfiguration()->configurationChanges(),
|
||||||
|
[expander](const CMakeConfigItem &item) { return item.toCMakeSetLine(expander); })
|
||||||
|
.join('\n')
|
||||||
|
.toUtf8());
|
||||||
|
|
||||||
|
QFile file(settingsFile.toString());
|
||||||
|
QTC_ASSERT(file.open(QFile::WriteOnly | QFile::Truncate), return );
|
||||||
|
file.write(contents);
|
||||||
|
}
|
||||||
|
|
||||||
void CMakeBuildSystem::setParametersAndRequestParse(const BuildDirParameters ¶meters,
|
void CMakeBuildSystem::setParametersAndRequestParse(const BuildDirParameters ¶meters,
|
||||||
const int reparseParameters)
|
const int reparseParameters)
|
||||||
{
|
{
|
||||||
@@ -405,6 +426,8 @@ void CMakeBuildSystem::setParametersAndRequestParse(const BuildDirParameters &pa
|
|||||||
|
|
||||||
m_reader.setParameters(m_parameters);
|
m_reader.setParameters(m_parameters);
|
||||||
|
|
||||||
|
writeConfigurationIntoBuildDirectory();
|
||||||
|
|
||||||
if (reparseParameters & REPARSE_URGENT) {
|
if (reparseParameters & REPARSE_URGENT) {
|
||||||
qCDebug(cmakeBuildSystemLog) << "calling requestReparse";
|
qCDebug(cmakeBuildSystemLog) << "calling requestReparse";
|
||||||
requestParse();
|
requestParse();
|
||||||
@@ -414,15 +437,15 @@ void CMakeBuildSystem::setParametersAndRequestParse(const BuildDirParameters &pa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMakeBuildSystem::mustApplyExtraArguments() const
|
bool CMakeBuildSystem::mustApplyExtraArguments(const BuildDirParameters ¶meters) const
|
||||||
{
|
{
|
||||||
if (m_parameters.extraCMakeArguments.isEmpty())
|
if (parameters.extraCMakeArguments.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto answer = QMessageBox::question(Core::ICore::mainWindow(),
|
auto answer = QMessageBox::question(Core::ICore::mainWindow(),
|
||||||
tr("Apply configuration changes?"),
|
tr("Apply configuration changes?"),
|
||||||
tr("Run CMake with \"%1\"?")
|
tr("Run CMake with \"%1\"?")
|
||||||
.arg(m_parameters.extraCMakeArguments.join(" ")),
|
.arg(parameters.extraCMakeArguments.join(" ")),
|
||||||
QMessageBox::Apply | QMessageBox::Discard,
|
QMessageBox::Apply | QMessageBox::Discard,
|
||||||
QMessageBox::Apply);
|
QMessageBox::Apply);
|
||||||
return answer == QMessageBox::Apply;
|
return answer == QMessageBox::Apply;
|
||||||
@@ -482,12 +505,10 @@ bool CMakeBuildSystem::persistCMakeState()
|
|||||||
qCDebug(cmakeBuildSystemLog) << "Checking whether build system needs to be persisted:"
|
qCDebug(cmakeBuildSystemLog) << "Checking whether build system needs to be persisted:"
|
||||||
<< "workdir:" << parameters.workDirectory
|
<< "workdir:" << parameters.workDirectory
|
||||||
<< "buildDir:" << parameters.buildDirectory
|
<< "buildDir:" << parameters.buildDirectory
|
||||||
<< "Has extraargs:" << !parameters.extraCMakeArguments.isEmpty()
|
<< "Has extraargs:" << !parameters.extraCMakeArguments.isEmpty();
|
||||||
<< "must apply extra Args:"
|
|
||||||
<< mustApplyExtraArguments();
|
|
||||||
|
|
||||||
if (parameters.workDirectory == parameters.buildDirectory
|
if (parameters.workDirectory == parameters.buildDirectory
|
||||||
&& !parameters.extraCMakeArguments.isEmpty() && mustApplyExtraArguments()) {
|
&& mustApplyExtraArguments(parameters)) {
|
||||||
reparseFlags = REPARSE_FORCE_EXTRA_CONFIGURATION;
|
reparseFlags = REPARSE_FORCE_EXTRA_CONFIGURATION;
|
||||||
qCDebug(cmakeBuildSystemLog) << " -> must run CMake with extra arguments.";
|
qCDebug(cmakeBuildSystemLog) << " -> must run CMake with extra arguments.";
|
||||||
}
|
}
|
||||||
|
@@ -29,7 +29,6 @@
|
|||||||
#include "cmakebuildtarget.h"
|
#include "cmakebuildtarget.h"
|
||||||
#include "cmakeprojectnodes.h"
|
#include "cmakeprojectnodes.h"
|
||||||
#include "fileapireader.h"
|
#include "fileapireader.h"
|
||||||
#include "utils/macroexpander.h"
|
|
||||||
|
|
||||||
#include <projectexplorer/buildsystem.h>
|
#include <projectexplorer/buildsystem.h>
|
||||||
|
|
||||||
@@ -117,7 +116,7 @@ private:
|
|||||||
void setParametersAndRequestParse(const BuildDirParameters ¶meters,
|
void setParametersAndRequestParse(const BuildDirParameters ¶meters,
|
||||||
const int reparseParameters);
|
const int reparseParameters);
|
||||||
|
|
||||||
bool mustApplyExtraArguments() const;
|
bool mustApplyExtraArguments(const BuildDirParameters ¶meters) const;
|
||||||
|
|
||||||
// State handling:
|
// State handling:
|
||||||
// Parser states:
|
// Parser states:
|
||||||
@@ -155,6 +154,8 @@ private:
|
|||||||
|
|
||||||
void runCTest();
|
void runCTest();
|
||||||
|
|
||||||
|
void writeConfigurationIntoBuildDirectory();
|
||||||
|
|
||||||
ProjectExplorer::TreeScanner m_treeScanner;
|
ProjectExplorer::TreeScanner m_treeScanner;
|
||||||
QHash<QString, bool> m_mimeBinaryCache;
|
QHash<QString, bool> m_mimeBinaryCache;
|
||||||
QList<const ProjectExplorer::FileNode *> m_allFiles;
|
QList<const ProjectExplorer::FileNode *> m_allFiles;
|
||||||
|
@@ -145,9 +145,11 @@ CMakeConfigItem::Type CMakeConfigItem::typeStringToType(const QByteArray &type)
|
|||||||
return CMakeConfigItem::PATH;
|
return CMakeConfigItem::PATH;
|
||||||
if (type == "STATIC")
|
if (type == "STATIC")
|
||||||
return CMakeConfigItem::STATIC;
|
return CMakeConfigItem::STATIC;
|
||||||
|
if (type == "INTERNAL")
|
||||||
QTC_CHECK(type == "INTERNAL" || type == "UNINITIALIZED");
|
|
||||||
return CMakeConfigItem::INTERNAL;
|
return CMakeConfigItem::INTERNAL;
|
||||||
|
|
||||||
|
QTC_CHECK(type == "UNINITIALIZED");
|
||||||
|
return CMakeConfigItem::UNINITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CMakeConfigItem::typeToTypeString(const CMakeConfigItem::Type t)
|
QString CMakeConfigItem::typeToTypeString(const CMakeConfigItem::Type t)
|
||||||
@@ -163,8 +165,10 @@ QString CMakeConfigItem::typeToTypeString(const CMakeConfigItem::Type t)
|
|||||||
return {"INTERNAL"};
|
return {"INTERNAL"};
|
||||||
case CMakeProjectManager::CMakeConfigItem::STATIC:
|
case CMakeProjectManager::CMakeConfigItem::STATIC:
|
||||||
return {"STATIC"};
|
return {"STATIC"};
|
||||||
case CMakeConfigItem::BOOL:
|
case CMakeProjectManager::CMakeConfigItem::BOOL:
|
||||||
return {"BOOL"};
|
return {"BOOL"};
|
||||||
|
case CMakeProjectManager::CMakeConfigItem::UNINITIALIZED:
|
||||||
|
return {"UNINITIALIZED"};
|
||||||
}
|
}
|
||||||
QTC_CHECK(false);
|
QTC_CHECK(false);
|
||||||
return {};
|
return {};
|
||||||
@@ -418,6 +422,9 @@ QString CMakeConfigItem::toString(const Utils::MacroExpander *expander) const
|
|||||||
case CMakeProjectManager::CMakeConfigItem::INTERNAL:
|
case CMakeProjectManager::CMakeConfigItem::INTERNAL:
|
||||||
typeStr = QLatin1String("INTERNAL");
|
typeStr = QLatin1String("INTERNAL");
|
||||||
break;
|
break;
|
||||||
|
case CMakeProjectManager::CMakeConfigItem::UNINITIALIZED:
|
||||||
|
typeStr = QLatin1String("UNINITIALIZED");
|
||||||
|
break;
|
||||||
case CMakeProjectManager::CMakeConfigItem::STRING:
|
case CMakeProjectManager::CMakeConfigItem::STRING:
|
||||||
default:
|
default:
|
||||||
typeStr = QLatin1String("STRING");
|
typeStr = QLatin1String("STRING");
|
||||||
|
@@ -45,7 +45,7 @@ namespace CMakeProjectManager {
|
|||||||
|
|
||||||
class CMAKE_EXPORT CMakeConfigItem {
|
class CMAKE_EXPORT CMakeConfigItem {
|
||||||
public:
|
public:
|
||||||
enum Type { FILEPATH, PATH, BOOL, STRING, INTERNAL, STATIC };
|
enum Type { FILEPATH, PATH, BOOL, STRING, INTERNAL, STATIC, UNINITIALIZED };
|
||||||
CMakeConfigItem();
|
CMakeConfigItem();
|
||||||
CMakeConfigItem(const QByteArray &k, Type t, const QByteArray &d, const QByteArray &v, const QStringList &s = {});
|
CMakeConfigItem(const QByteArray &k, Type t, const QByteArray &d, const QByteArray &v, const QStringList &s = {});
|
||||||
CMakeConfigItem(const QByteArray &k, const QByteArray &v);
|
CMakeConfigItem(const QByteArray &k, const QByteArray &v);
|
||||||
|
@@ -46,7 +46,9 @@ CMakeInputsNode::CMakeInputsNode(const Utils::FilePath &cmakeLists) :
|
|||||||
{
|
{
|
||||||
setPriority(Node::DefaultPriority - 10); // Bottom most!
|
setPriority(Node::DefaultPriority - 10); // Bottom most!
|
||||||
setDisplayName(QCoreApplication::translate("CMakeFilesProjectNode", "CMake Modules"));
|
setDisplayName(QCoreApplication::translate("CMakeFilesProjectNode", "CMake Modules"));
|
||||||
setIcon(QIcon(":/projectexplorer/images/session.png")); // TODO: Use a better icon!
|
static const QIcon modulesIcon = Core::FileIconProvider::directoryIcon(
|
||||||
|
ProjectExplorer::Constants::FILEOVERLAY_MODULES);
|
||||||
|
setIcon(modulesIcon);
|
||||||
setListInProject(false);
|
setListInProject(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -123,11 +123,6 @@ bool ConfigModel::hasChanges() const
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigModel::hasCMakeChanges() const
|
|
||||||
{
|
|
||||||
return Utils::contains(m_configuration, [](const InternalDataItem &i) { return i.isCMakeChanged; });
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConfigModel::canForceTo(const QModelIndex &idx, const ConfigModel::DataItem::Type type) const
|
bool ConfigModel::canForceTo(const QModelIndex &idx, const ConfigModel::DataItem::Type type) const
|
||||||
{
|
{
|
||||||
if (idx.model() != const_cast<ConfigModel *>(this) || idx.column() != 1)
|
if (idx.model() != const_cast<ConfigModel *>(this) || idx.column() != 1)
|
||||||
@@ -264,7 +259,6 @@ void ConfigModel::setConfiguration(const QList<ConfigModel::InternalDataItem> &c
|
|||||||
// merge old/new entry:
|
// merge old/new entry:
|
||||||
InternalDataItem item(*newIt);
|
InternalDataItem item(*newIt);
|
||||||
item.newValue = (newIt->value != oldIt->newValue) ? oldIt->newValue : QString();
|
item.newValue = (newIt->value != oldIt->newValue) ? oldIt->newValue : QString();
|
||||||
item.isCMakeChanged = (oldIt->value != newIt->value);
|
|
||||||
item.isUserChanged = !item.newValue.isEmpty() && (item.newValue != item.value);
|
item.isUserChanged = !item.newValue.isEmpty() && (item.newValue != item.value);
|
||||||
result << item;
|
result << item;
|
||||||
++newIt;
|
++newIt;
|
||||||
@@ -390,7 +384,6 @@ QVariant ConfigModelTreeItem::data(int column, int role) const
|
|||||||
return toolTip();
|
return toolTip();
|
||||||
case Qt::FontRole: {
|
case Qt::FontRole: {
|
||||||
QFont font;
|
QFont font;
|
||||||
font.setItalic(dataItem->isCMakeChanged);
|
|
||||||
font.setBold(dataItem->isUserNew);
|
font.setBold(dataItem->isUserNew);
|
||||||
font.setStrikeOut((!dataItem->inCMakeCache && !dataItem->isUserNew) || dataItem->isUnset);
|
font.setStrikeOut((!dataItem->inCMakeCache && !dataItem->isUserNew) || dataItem->isUnset);
|
||||||
return font;
|
return font;
|
||||||
@@ -414,7 +407,6 @@ QVariant ConfigModelTreeItem::data(int column, int role) const
|
|||||||
case Qt::FontRole: {
|
case Qt::FontRole: {
|
||||||
QFont font;
|
QFont font;
|
||||||
font.setBold((dataItem->isUserChanged || dataItem->isUserNew) && !dataItem->isUnset);
|
font.setBold((dataItem->isUserChanged || dataItem->isUserNew) && !dataItem->isUnset);
|
||||||
font.setItalic(dataItem->isCMakeChanged);
|
|
||||||
font.setStrikeOut((!dataItem->inCMakeCache && !dataItem->isUserNew) || dataItem->isUnset);
|
font.setStrikeOut((!dataItem->inCMakeCache && !dataItem->isUserNew) || dataItem->isUnset);
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
@@ -101,7 +101,7 @@ public:
|
|||||||
cmi.type = CMakeConfigItem::STRING;
|
cmi.type = CMakeConfigItem::STRING;
|
||||||
break;
|
break;
|
||||||
case DataItem::UNKNOWN:
|
case DataItem::UNKNOWN:
|
||||||
cmi.type = CMakeConfigItem::INTERNAL;
|
cmi.type = CMakeConfigItem::UNINITIALIZED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cmi.isUnset = isUnset;
|
cmi.isUnset = isUnset;
|
||||||
@@ -144,7 +144,6 @@ public:
|
|||||||
void resetAllChanges();
|
void resetAllChanges();
|
||||||
|
|
||||||
bool hasChanges() const;
|
bool hasChanges() const;
|
||||||
bool hasCMakeChanges() const;
|
|
||||||
|
|
||||||
bool canForceTo(const QModelIndex &idx, const DataItem::Type type) const;
|
bool canForceTo(const QModelIndex &idx, const DataItem::Type type) const;
|
||||||
void forceTo(const QModelIndex &idx, const DataItem::Type type);
|
void forceTo(const QModelIndex &idx, const DataItem::Type type);
|
||||||
@@ -168,7 +167,6 @@ private:
|
|||||||
|
|
||||||
bool isUserChanged = false;
|
bool isUserChanged = false;
|
||||||
bool isUserNew = false;
|
bool isUserNew = false;
|
||||||
bool isCMakeChanged = false;
|
|
||||||
QString newValue;
|
QString newValue;
|
||||||
QString kitValue;
|
QString kitValue;
|
||||||
};
|
};
|
||||||
|
@@ -179,6 +179,14 @@ QVector<FolderNode::LocationInfo> extractBacktraceInformation(const BacktraceInf
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isChildOf(const FilePath &path, const QStringList &prefixes)
|
||||||
|
{
|
||||||
|
for (const QString &prefix : prefixes)
|
||||||
|
if (path.isChildOf(FilePath::fromString(prefix)))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QList<CMakeBuildTarget> generateBuildTargets(const PreprocessedData &input,
|
QList<CMakeBuildTarget> generateBuildTargets(const PreprocessedData &input,
|
||||||
const FilePath &sourceDirectory,
|
const FilePath &sourceDirectory,
|
||||||
const FilePath &buildDirectory)
|
const FilePath &buildDirectory)
|
||||||
@@ -269,8 +277,19 @@ QList<CMakeBuildTarget> generateBuildTargets(const PreprocessedData &input,
|
|||||||
if (f.role == "libraries")
|
if (f.role == "libraries")
|
||||||
tmp = tmp.parentDir();
|
tmp = tmp.parentDir();
|
||||||
|
|
||||||
if (!tmp.isEmpty()
|
if (!tmp.isEmpty() && tmp.isDir()) {
|
||||||
&& tmp.isDir()) { // f.role is libraryPath or frameworkPath
|
// f.role is libraryPath or frameworkPath
|
||||||
|
// On Linux, exclude sub-paths from "/lib(64)", "/usr/lib(64)" and
|
||||||
|
// "/usr/local/lib" since these are usually in the standard search
|
||||||
|
// paths. There probably are more, but the naming schemes are arbitrary
|
||||||
|
// so we'd need to ask the linker ("ld --verbose | grep SEARCH_DIR").
|
||||||
|
if (!HostOsInfo::isLinuxHost()
|
||||||
|
|| !isChildOf(tmp,
|
||||||
|
{"/lib",
|
||||||
|
"/lib64",
|
||||||
|
"/usr/lib",
|
||||||
|
"/usr/lib64",
|
||||||
|
"/usr/local/lib"})) {
|
||||||
librarySeachPaths.append(tmp);
|
librarySeachPaths.append(tmp);
|
||||||
// Libraries often have their import libs in ../lib and the
|
// Libraries often have their import libs in ../lib and the
|
||||||
// actual dll files in ../bin on windows. Qt is one example of that.
|
// actual dll files in ../bin on windows. Qt is one example of that.
|
||||||
@@ -283,6 +302,7 @@ QList<CMakeBuildTarget> generateBuildTargets(const PreprocessedData &input,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ct.libraryDirectories = filteredUnique(librarySeachPaths);
|
ct.libraryDirectories = filteredUnique(librarySeachPaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -892,7 +892,9 @@ FileApiData FileApiParser::parseData(const QFileInfo &replyFileInfo, const QStri
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto it = std::find_if(codeModels.cbegin(), codeModels.cend(),
|
auto it = std::find_if(codeModels.cbegin(), codeModels.cend(),
|
||||||
[cmakeBuildType](const Configuration& cfg) { return cfg.name == cmakeBuildType; });
|
[cmakeBuildType](const Configuration& cfg) {
|
||||||
|
return QString::compare(cfg.name, cmakeBuildType, Qt::CaseInsensitive) == 0;
|
||||||
|
});
|
||||||
if (it == codeModels.cend()) {
|
if (it == codeModels.cend()) {
|
||||||
errorMessage = QString("No '%1' CMake configuration found!").arg(cmakeBuildType);
|
errorMessage = QString("No '%1' CMake configuration found!").arg(cmakeBuildType);
|
||||||
qWarning() << errorMessage;
|
qWarning() << errorMessage;
|
||||||
|
@@ -321,6 +321,7 @@ void FileApiReader::makeBackupConfiguration(bool store)
|
|||||||
if (!store)
|
if (!store)
|
||||||
std::swap(cmakeCacheTxt, cmakeCacheTxtPrev);
|
std::swap(cmakeCacheTxt, cmakeCacheTxtPrev);
|
||||||
|
|
||||||
|
if (cmakeCacheTxt.exists())
|
||||||
if (!FileUtils::copyIfDifferent(cmakeCacheTxt, cmakeCacheTxtPrev))
|
if (!FileUtils::copyIfDifferent(cmakeCacheTxt, cmakeCacheTxtPrev))
|
||||||
Core::MessageManager::writeFlashing(tr("Failed to copy %1 to %2.")
|
Core::MessageManager::writeFlashing(tr("Failed to copy %1 to %2.")
|
||||||
.arg(cmakeCacheTxt.toString(), cmakeCacheTxtPrev.toString()));
|
.arg(cmakeCacheTxt.toString(), cmakeCacheTxtPrev.toString()));
|
||||||
|
@@ -57,7 +57,7 @@ IWelcomePage::~IWelcomePage()
|
|||||||
g_welcomePages.removeOne(this);
|
g_welcomePages.removeOne(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QPalette buttonPalette(bool isActive, bool isCursorInside, bool forText)
|
QPalette WelcomePageFrame::buttonPalette(bool isActive, bool isCursorInside, bool forText)
|
||||||
{
|
{
|
||||||
QPalette pal;
|
QPalette pal;
|
||||||
Theme *theme = Utils::creatorTheme();
|
Theme *theme = Utils::creatorTheme();
|
||||||
@@ -174,8 +174,8 @@ bool WelcomePageButtonPrivate::isActive() const
|
|||||||
void WelcomePageButtonPrivate::doUpdate(bool cursorInside)
|
void WelcomePageButtonPrivate::doUpdate(bool cursorInside)
|
||||||
{
|
{
|
||||||
const bool active = isActive();
|
const bool active = isActive();
|
||||||
q->setPalette(buttonPalette(active, cursorInside, false));
|
q->setPalette(WelcomePageFrame::buttonPalette(active, cursorInside, false));
|
||||||
const QPalette lpal = buttonPalette(active, cursorInside, true);
|
const QPalette lpal = WelcomePageFrame::buttonPalette(active, cursorInside, true);
|
||||||
m_label->setPalette(lpal);
|
m_label->setPalette(lpal);
|
||||||
if (m_icon)
|
if (m_icon)
|
||||||
m_icon->setPalette(lpal);
|
m_icon->setPalette(lpal);
|
||||||
|
@@ -68,6 +68,8 @@ public:
|
|||||||
WelcomePageFrame(QWidget *parent);
|
WelcomePageFrame(QWidget *parent);
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *event) override;
|
void paintEvent(QPaintEvent *event) override;
|
||||||
|
|
||||||
|
static QPalette buttonPalette(bool isActive, bool isCursorInside, bool forText);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CORE_EXPORT WelcomePageButton : public WelcomePageFrame
|
class CORE_EXPORT WelcomePageButton : public WelcomePageFrame
|
||||||
|
@@ -171,6 +171,12 @@ ThemeChooser::~ThemeChooser()
|
|||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QString defaultThemeId()
|
||||||
|
{
|
||||||
|
return Theme::systemUsesDarkMode() ? QString(Constants::DEFAULT_DARK_THEME)
|
||||||
|
: QString(Constants::DEFAULT_THEME);
|
||||||
|
}
|
||||||
|
|
||||||
void ThemeChooser::apply()
|
void ThemeChooser::apply()
|
||||||
{
|
{
|
||||||
const int index = d->m_themeComboBox->currentIndex();
|
const int index = d->m_themeComboBox->currentIndex();
|
||||||
@@ -181,9 +187,7 @@ void ThemeChooser::apply()
|
|||||||
const QString currentThemeId = ThemeEntry::themeSetting().toString();
|
const QString currentThemeId = ThemeEntry::themeSetting().toString();
|
||||||
if (currentThemeId != themeId) {
|
if (currentThemeId != themeId) {
|
||||||
// save filename of selected theme in global config
|
// save filename of selected theme in global config
|
||||||
settings->setValueWithDefault(Constants::SETTINGS_THEME,
|
settings->setValueWithDefault(Constants::SETTINGS_THEME, themeId, defaultThemeId());
|
||||||
themeId,
|
|
||||||
QString(Constants::DEFAULT_THEME));
|
|
||||||
RestartDialog restartDialog(ICore::dialogParent(),
|
RestartDialog restartDialog(ICore::dialogParent(),
|
||||||
tr("The theme change will take effect after restart."));
|
tr("The theme change will take effect after restart."));
|
||||||
restartDialog.exec();
|
restartDialog.exec();
|
||||||
@@ -225,10 +229,8 @@ QList<ThemeEntry> ThemeEntry::availableThemes()
|
|||||||
|
|
||||||
Id ThemeEntry::themeSetting()
|
Id ThemeEntry::themeSetting()
|
||||||
{
|
{
|
||||||
auto defaultId = Theme::systemUsesDarkMode() ? Constants::DEFAULT_DARK_THEME
|
|
||||||
: Constants::DEFAULT_THEME;
|
|
||||||
const Id setting = Id::fromSetting(
|
const Id setting = Id::fromSetting(
|
||||||
ICore::settings()->value(Constants::SETTINGS_THEME, defaultId));
|
ICore::settings()->value(Constants::SETTINGS_THEME, defaultThemeId()));
|
||||||
|
|
||||||
const QList<ThemeEntry> themes = availableThemes();
|
const QList<ThemeEntry> themes = availableThemes();
|
||||||
if (themes.empty())
|
if (themes.empty())
|
||||||
|
@@ -57,15 +57,17 @@ static QFont sizedFont(int size, const QWidget *widget)
|
|||||||
SearchBox::SearchBox(QWidget *parent)
|
SearchBox::SearchBox(QWidget *parent)
|
||||||
: WelcomePageFrame(parent)
|
: WelcomePageFrame(parent)
|
||||||
{
|
{
|
||||||
QPalette pal;
|
QPalette pal = buttonPalette(false, false, true);
|
||||||
pal.setColor(QPalette::Base, themeColor(Theme::Welcome_BackgroundColor));
|
pal.setColor(QPalette::Base, themeColor(Theme::Welcome_BackgroundColor));
|
||||||
|
// for macOS dark mode
|
||||||
|
pal.setColor(QPalette::Text, themeColor(Theme::Welcome_TextColor));
|
||||||
|
setPalette(pal);
|
||||||
|
|
||||||
m_lineEdit = new FancyLineEdit;
|
m_lineEdit = new FancyLineEdit;
|
||||||
m_lineEdit->setFiltering(true);
|
m_lineEdit->setFiltering(true);
|
||||||
m_lineEdit->setFrame(false);
|
m_lineEdit->setFrame(false);
|
||||||
m_lineEdit->setFont(sizedFont(14, this));
|
m_lineEdit->setFont(sizedFont(14, this));
|
||||||
m_lineEdit->setAttribute(Qt::WA_MacShowFocusRect, false);
|
m_lineEdit->setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||||
m_lineEdit->setPalette(pal);
|
|
||||||
|
|
||||||
auto box = new QHBoxLayout(this);
|
auto box = new QHBoxLayout(this);
|
||||||
box->setContentsMargins(10, 3, 3, 3);
|
box->setContentsMargins(10, 3, 3, 3);
|
||||||
@@ -84,6 +86,7 @@ GridView::GridView(QWidget *parent)
|
|||||||
setSelectionMode(QAbstractItemView::NoSelection);
|
setSelectionMode(QAbstractItemView::NoSelection);
|
||||||
setFrameShape(QFrame::NoFrame);
|
setFrameShape(QFrame::NoFrame);
|
||||||
setGridStyle(Qt::NoPen);
|
setGridStyle(Qt::NoPen);
|
||||||
|
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
|
||||||
QPalette pal;
|
QPalette pal;
|
||||||
pal.setColor(QPalette::Base, themeColor(Theme::Welcome_BackgroundColor));
|
pal.setColor(QPalette::Base, themeColor(Theme::Welcome_BackgroundColor));
|
||||||
|
@@ -421,6 +421,7 @@ static void addSearchResults(CppTools::Usages usages, SearchResult &search, cons
|
|||||||
item.setFilePath(FilePath::fromString(usage.path));
|
item.setFilePath(FilePath::fromString(usage.path));
|
||||||
item.setLineText(lineContent);
|
item.setLineText(lineContent);
|
||||||
item.setMainRange(range);
|
item.setMainRange(range);
|
||||||
|
item.setUseTextEditorFont(true);
|
||||||
search.addResult(item);
|
search.addResult(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -636,6 +636,7 @@ static void displayResults(SearchResult *search, QFutureWatcher<CPlusPlus::Usage
|
|||||||
item.setLineText(result.lineText);
|
item.setLineText(result.lineText);
|
||||||
item.setUserData(int(result.type));
|
item.setUserData(int(result.type));
|
||||||
item.setStyle(colorStyleForUsageType(result.type));
|
item.setStyle(colorStyleForUsageType(result.type));
|
||||||
|
item.setUseTextEditorFont(true);
|
||||||
search->addResult(item);
|
search->addResult(item);
|
||||||
|
|
||||||
if (parameters.prettySymbolName.isEmpty())
|
if (parameters.prettySymbolName.isEmpty())
|
||||||
@@ -831,6 +832,7 @@ void CppFindReferences::findMacroUses(const CPlusPlus::Macro ¯o, const QStri
|
|||||||
item.setFilePath(Utils::FilePath::fromString(macro.fileName()));
|
item.setFilePath(Utils::FilePath::fromString(macro.fileName()));
|
||||||
item.setLineText(line);
|
item.setLineText(line);
|
||||||
item.setMainRange(macro.line(), column, macro.nameToQString().length());
|
item.setMainRange(macro.line(), column, macro.nameToQString().length());
|
||||||
|
item.setUseTextEditorFont(true);
|
||||||
search->addResult(item);
|
search->addResult(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
#include <texteditor/textdocument.h>
|
#include <texteditor/textdocument.h>
|
||||||
#include <texteditor/textdocumentlayout.h>
|
#include <texteditor/textdocumentlayout.h>
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
@@ -45,6 +46,8 @@ static Q_LOGGING_CATEGORY(log, "qtc.cpptools.semantichighlighter", QtWarningMsg)
|
|||||||
|
|
||||||
namespace CppTools {
|
namespace CppTools {
|
||||||
|
|
||||||
|
static Utils::Id parenSource() { return "CppTools"; }
|
||||||
|
|
||||||
static const QList<std::pair<HighlightingResult, QTextBlock>>
|
static const QList<std::pair<HighlightingResult, QTextBlock>>
|
||||||
splitRawStringLiteral(const HighlightingResult &result, const QTextBlock &startBlock)
|
splitRawStringLiteral(const HighlightingResult &result, const QTextBlock &startBlock)
|
||||||
{
|
{
|
||||||
@@ -147,6 +150,13 @@ void SemanticHighlighter::run()
|
|||||||
m_watcher->setFuture(m_highlightingRunner());
|
m_watcher->setFuture(m_highlightingRunner());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Parentheses getClearedParentheses(const QTextBlock &block)
|
||||||
|
{
|
||||||
|
return Utils::filtered(TextDocumentLayout::parentheses(block), [](const Parenthesis &p) {
|
||||||
|
return p.source != parenSource();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void SemanticHighlighter::onHighlighterResultAvailable(int from, int to)
|
void SemanticHighlighter::onHighlighterResultAvailable(int from, int to)
|
||||||
{
|
{
|
||||||
if (documentRevision() != m_revision)
|
if (documentRevision() != m_revision)
|
||||||
@@ -169,6 +179,9 @@ void SemanticHighlighter::onHighlighterResultAvailable(int from, int to)
|
|||||||
const HighlightingResult &result = m_watcher->future().resultAt(i);
|
const HighlightingResult &result = m_watcher->future().resultAt(i);
|
||||||
if (result.kind != AngleBracketOpen && result.kind != AngleBracketClose
|
if (result.kind != AngleBracketOpen && result.kind != AngleBracketClose
|
||||||
&& result.kind != TernaryIf && result.kind != TernaryElse) {
|
&& result.kind != TernaryIf && result.kind != TernaryElse) {
|
||||||
|
const QTextBlock block =
|
||||||
|
m_baseTextDocument->document()->findBlockByNumber(result.line - 1);
|
||||||
|
TextDocumentLayout::setParentheses(block, getClearedParentheses(block));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (parentheses.first.isValid() && result.line - 1 > parentheses.first.blockNumber()) {
|
if (parentheses.first.isValid() && result.line - 1 > parentheses.first.blockNumber()) {
|
||||||
@@ -177,16 +190,20 @@ void SemanticHighlighter::onHighlighterResultAvailable(int from, int to)
|
|||||||
}
|
}
|
||||||
if (!parentheses.first.isValid()) {
|
if (!parentheses.first.isValid()) {
|
||||||
parentheses.first = m_baseTextDocument->document()->findBlockByNumber(result.line - 1);
|
parentheses.first = m_baseTextDocument->document()->findBlockByNumber(result.line - 1);
|
||||||
parentheses.second = TextDocumentLayout::parentheses(parentheses.first);
|
parentheses.second = getClearedParentheses(parentheses.first);
|
||||||
}
|
}
|
||||||
|
Parenthesis paren;
|
||||||
if (result.kind == AngleBracketOpen)
|
if (result.kind == AngleBracketOpen)
|
||||||
parentheses.second << Parenthesis(Parenthesis::Opened, '<', result.column - 1);
|
paren = {Parenthesis::Opened, '<', result.column - 1};
|
||||||
else if (result.kind == AngleBracketClose)
|
else if (result.kind == AngleBracketClose)
|
||||||
parentheses.second << Parenthesis(Parenthesis::Closed, '>', result.column - 1);
|
paren = {Parenthesis::Closed, '>', result.column - 1};
|
||||||
else if (result.kind == TernaryIf)
|
else if (result.kind == TernaryIf)
|
||||||
parentheses.second << Parenthesis(Parenthesis::Opened, '?', result.column - 1);
|
paren = {Parenthesis::Opened, '?', result.column - 1};
|
||||||
else if (result.kind == TernaryElse)
|
else if (result.kind == TernaryElse)
|
||||||
parentheses.second << Parenthesis(Parenthesis::Closed, ':', result.column - 1);
|
paren = {Parenthesis::Closed, ':', result.column - 1};
|
||||||
|
QTC_ASSERT(paren.pos != -1, continue);
|
||||||
|
paren.source = parenSource();
|
||||||
|
parentheses.second << paren;
|
||||||
}
|
}
|
||||||
if (parentheses.first.isValid())
|
if (parentheses.first.isValid())
|
||||||
TextDocumentLayout::setParentheses(parentheses.first, parentheses.second);
|
TextDocumentLayout::setParentheses(parentheses.first, parentheses.second);
|
||||||
@@ -202,6 +219,27 @@ void SemanticHighlighter::onHighlighterFinished()
|
|||||||
clearExtraAdditionalFormatsUntilEnd(highlighter, m_watcher->future());
|
clearExtraAdditionalFormatsUntilEnd(highlighter, m_watcher->future());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear out previous "semantic parentheses".
|
||||||
|
QTextBlock firstResultBlock;
|
||||||
|
QTextBlock lastResultBlock;
|
||||||
|
if (m_watcher->future().resultCount() == 0) {
|
||||||
|
firstResultBlock = lastResultBlock = m_baseTextDocument->document()->lastBlock();
|
||||||
|
} else {
|
||||||
|
firstResultBlock = m_baseTextDocument->document()->findBlockByNumber(
|
||||||
|
m_watcher->resultAt(0).line - 1);
|
||||||
|
lastResultBlock = m_baseTextDocument->document()->findBlockByNumber(
|
||||||
|
m_watcher->future().resultAt(m_watcher->future().resultCount() - 1).line - 1);
|
||||||
|
}
|
||||||
|
for (QTextBlock currentBlock = m_baseTextDocument->document()->firstBlock();
|
||||||
|
currentBlock != firstResultBlock; currentBlock = currentBlock.next()) {
|
||||||
|
TextDocumentLayout::setParentheses(currentBlock, getClearedParentheses(currentBlock));
|
||||||
|
}
|
||||||
|
for (QTextBlock currentBlock = lastResultBlock.next(); currentBlock.isValid();
|
||||||
|
currentBlock = currentBlock.next()) {
|
||||||
|
TextDocumentLayout::setParentheses(currentBlock, getClearedParentheses(currentBlock));
|
||||||
|
}
|
||||||
|
|
||||||
m_watcher.reset();
|
m_watcher.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
add_qtc_plugin(CtfVisualizer
|
add_qtc_plugin(CtfVisualizer
|
||||||
|
CONDITION TARGET Tracing
|
||||||
DEPENDS Tracing Qt5::QuickWidgets
|
DEPENDS Tracing Qt5::QuickWidgets
|
||||||
INCLUDES ${PROJECT_SOURCE_DIR}/src
|
INCLUDES ${PROJECT_SOURCE_DIR}/src
|
||||||
PLUGIN_DEPENDS Core Debugger ProjectExplorer
|
PLUGIN_DEPENDS Core Debugger ProjectExplorer
|
||||||
|
@@ -79,6 +79,7 @@ constexpr char executableKey[] = "executable";
|
|||||||
constexpr char argumentsKey[] = "arguments";
|
constexpr char argumentsKey[] = "arguments";
|
||||||
constexpr char settingsGroupKey[] = "LanguageClient";
|
constexpr char settingsGroupKey[] = "LanguageClient";
|
||||||
constexpr char clientsKey[] = "clients";
|
constexpr char clientsKey[] = "clients";
|
||||||
|
constexpr char typedClientsKey[] = "typedClients";
|
||||||
constexpr char mimeType[] = "application/language.client.setting";
|
constexpr char mimeType[] = "application/language.client.setting";
|
||||||
|
|
||||||
namespace LanguageClient {
|
namespace LanguageClient {
|
||||||
@@ -615,16 +616,21 @@ QList<BaseSettings *> LanguageClientSettings::fromSettings(QSettings *settingsIn
|
|||||||
{
|
{
|
||||||
settingsIn->beginGroup(settingsGroupKey);
|
settingsIn->beginGroup(settingsGroupKey);
|
||||||
QList<BaseSettings *> result;
|
QList<BaseSettings *> result;
|
||||||
for (const QVariant& var : settingsIn->value(clientsKey).toList()) {
|
|
||||||
|
for (auto varList :
|
||||||
|
{settingsIn->value(clientsKey).toList(), settingsIn->value(typedClientsKey).toList()}) {
|
||||||
|
for (const QVariant &var : varList) {
|
||||||
const QMap<QString, QVariant> &map = var.toMap();
|
const QMap<QString, QVariant> &map = var.toMap();
|
||||||
Utils::Id typeId = Utils::Id::fromSetting(map.value(typeIdKey));
|
Utils::Id typeId = Utils::Id::fromSetting(map.value(typeIdKey));
|
||||||
if (!typeId.isValid())
|
if (!typeId.isValid())
|
||||||
typeId = Constants::LANGUAGECLIENT_STDIO_SETTINGS_ID;
|
typeId = Constants::LANGUAGECLIENT_STDIO_SETTINGS_ID;
|
||||||
if (BaseSettings *settings = generateSettings(typeId)) {
|
if (BaseSettings *settings = generateSettings(typeId)) {
|
||||||
settings->fromMap(var.toMap());
|
settings->fromMap(map);
|
||||||
result << settings;
|
result << settings;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
settingsIn->endGroup();
|
settingsIn->endGroup();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -659,10 +665,16 @@ void LanguageClientSettings::toSettings(QSettings *settings,
|
|||||||
const QList<BaseSettings *> &languageClientSettings)
|
const QList<BaseSettings *> &languageClientSettings)
|
||||||
{
|
{
|
||||||
settings->beginGroup(settingsGroupKey);
|
settings->beginGroup(settingsGroupKey);
|
||||||
settings->setValue(clientsKey, Utils::transform(languageClientSettings,
|
auto transform = [](const QList<BaseSettings *> &settings) {
|
||||||
[](const BaseSettings *setting){
|
return Utils::transform(settings, [](const BaseSettings *setting) {
|
||||||
return QVariant(setting->toMap());
|
return QVariant(setting->toMap());
|
||||||
}));
|
});
|
||||||
|
};
|
||||||
|
auto isStdioSetting = Utils::equal(&BaseSettings::m_settingsTypeId,
|
||||||
|
Utils::Id(Constants::LANGUAGECLIENT_STDIO_SETTINGS_ID));
|
||||||
|
auto [stdioSettings, typedSettings] = Utils::partition(languageClientSettings, isStdioSetting);
|
||||||
|
settings->setValue(clientsKey, transform(stdioSettings));
|
||||||
|
settings->setValue(typedClientsKey, transform(typedSettings));
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
add_qtc_plugin(PerfProfiler
|
add_qtc_plugin(PerfProfiler
|
||||||
|
CONDITION TARGET Tracing
|
||||||
DEPENDS Tracing Qt5::QuickWidgets
|
DEPENDS Tracing Qt5::QuickWidgets
|
||||||
PLUGIN_DEPENDS Core Debugger ProjectExplorer QtSupport
|
PLUGIN_DEPENDS Core Debugger ProjectExplorer QtSupport
|
||||||
SOURCES
|
SOURCES
|
||||||
|
BIN
src/plugins/projectexplorer/images/fileoverlay_modules.png
Normal file
After Width: | Height: | Size: 461 B |
BIN
src/plugins/projectexplorer/images/fileoverlay_modules@2x.png
Normal file
After Width: | Height: | Size: 792 B |
Before Width: | Height: | Size: 583 B |
@@ -24,7 +24,6 @@
|
|||||||
<file>images/debugger_overlay_small@2x.png</file>
|
<file>images/debugger_overlay_small@2x.png</file>
|
||||||
<file>images/analyzer_overlay_small.png</file>
|
<file>images/analyzer_overlay_small.png</file>
|
||||||
<file>images/analyzer_overlay_small@2x.png</file>
|
<file>images/analyzer_overlay_small@2x.png</file>
|
||||||
<file>images/session.png</file>
|
|
||||||
<file>images/BuildSettings.png</file>
|
<file>images/BuildSettings.png</file>
|
||||||
<file>images/CodeStyleSettings.png</file>
|
<file>images/CodeStyleSettings.png</file>
|
||||||
<file>images/RunSettings.png</file>
|
<file>images/RunSettings.png</file>
|
||||||
@@ -67,6 +66,8 @@
|
|||||||
<file>images/fileoverlay_product@2x.png</file>
|
<file>images/fileoverlay_product@2x.png</file>
|
||||||
<file>images/fileoverlay_group.png</file>
|
<file>images/fileoverlay_group.png</file>
|
||||||
<file>images/fileoverlay_group@2x.png</file>
|
<file>images/fileoverlay_group@2x.png</file>
|
||||||
|
<file>images/fileoverlay_modules.png</file>
|
||||||
|
<file>images/fileoverlay_modules@2x.png</file>
|
||||||
<file>images/fileoverlay_ui.png</file>
|
<file>images/fileoverlay_ui.png</file>
|
||||||
<file>images/fileoverlay_ui@2x.png</file>
|
<file>images/fileoverlay_ui@2x.png</file>
|
||||||
<file>images/fileoverlay_scxml.png</file>
|
<file>images/fileoverlay_scxml.png</file>
|
||||||
|
@@ -215,6 +215,7 @@ const char PROJECTTREE_ID[] = "Projects";
|
|||||||
const char FILEOVERLAY_QT[]=":/projectexplorer/images/fileoverlay_qt.png";
|
const char FILEOVERLAY_QT[]=":/projectexplorer/images/fileoverlay_qt.png";
|
||||||
const char FILEOVERLAY_GROUP[] = ":/projectexplorer/images/fileoverlay_group.png";
|
const char FILEOVERLAY_GROUP[] = ":/projectexplorer/images/fileoverlay_group.png";
|
||||||
const char FILEOVERLAY_PRODUCT[] = ":/projectexplorer/images/fileoverlay_product.png";
|
const char FILEOVERLAY_PRODUCT[] = ":/projectexplorer/images/fileoverlay_product.png";
|
||||||
|
const char FILEOVERLAY_MODULES[] = ":/projectexplorer/images/fileoverlay_modules.png";
|
||||||
const char FILEOVERLAY_QML[]=":/projectexplorer/images/fileoverlay_qml.png";
|
const char FILEOVERLAY_QML[]=":/projectexplorer/images/fileoverlay_qml.png";
|
||||||
const char FILEOVERLAY_UI[]=":/projectexplorer/images/fileoverlay_ui.png";
|
const char FILEOVERLAY_UI[]=":/projectexplorer/images/fileoverlay_ui.png";
|
||||||
const char FILEOVERLAY_QRC[]=":/projectexplorer/images/fileoverlay_qrc.png";
|
const char FILEOVERLAY_QRC[]=":/projectexplorer/images/fileoverlay_qrc.png";
|
||||||
|
@@ -6,7 +6,7 @@ endif()
|
|||||||
add_qtc_plugin(QmlDesigner
|
add_qtc_plugin(QmlDesigner
|
||||||
DEPENDS
|
DEPENDS
|
||||||
QmlJS LanguageUtils QmlEditorWidgets AdvancedDockingSystem
|
QmlJS LanguageUtils QmlEditorWidgets AdvancedDockingSystem
|
||||||
Qt5::QuickWidgets Qt5::CorePrivate Sqlite
|
Qt5::QuickWidgets Qt5::CorePrivate Sqlite Threads::Threads
|
||||||
DEFINES
|
DEFINES
|
||||||
DESIGNER_CORE_LIBRARY
|
DESIGNER_CORE_LIBRARY
|
||||||
IDE_LIBRARY_BASENAME=\"${IDE_LIBRARY_BASE_PATH}\"
|
IDE_LIBRARY_BASENAME=\"${IDE_LIBRARY_BASE_PATH}\"
|
||||||
|
@@ -100,7 +100,9 @@ QToolBar *CurveEditor::createToolBar(CurveEditorModel *model)
|
|||||||
auto setLinearInterpolation = [this]() {
|
auto setLinearInterpolation = [this]() {
|
||||||
m_view->setInterpolation(Keyframe::Interpolation::Linear);
|
m_view->setInterpolation(Keyframe::Interpolation::Linear);
|
||||||
};
|
};
|
||||||
auto setStepInterpolation = [this]() { m_view->setInterpolation(Keyframe::Interpolation::Step); };
|
auto setStepInterpolation = [this]() {
|
||||||
|
m_view->setInterpolation(Keyframe::Interpolation::Step);
|
||||||
|
};
|
||||||
auto setSplineInterpolation = [this]() {
|
auto setSplineInterpolation = [this]() {
|
||||||
m_view->setInterpolation(Keyframe::Interpolation::Bezier);
|
m_view->setInterpolation(Keyframe::Interpolation::Bezier);
|
||||||
};
|
};
|
||||||
|
@@ -338,7 +338,8 @@ void CurveEditorView::commitKeyframes(TreeItem *item)
|
|||||||
group.setValue(QVariant(pos.y()), pos.x());
|
group.setValue(QVariant(pos.y()), pos.x());
|
||||||
|
|
||||||
if (previous.isValid()) {
|
if (previous.isValid()) {
|
||||||
if (frame.interpolation() == Keyframe::Interpolation::Bezier) {
|
if (frame.interpolation() == Keyframe::Interpolation::Bezier ||
|
||||||
|
frame.interpolation() == Keyframe::Interpolation::Step ) {
|
||||||
CurveSegment segment(previous, frame);
|
CurveSegment segment(previous, frame);
|
||||||
if (segment.isValid())
|
if (segment.isValid())
|
||||||
attachEasingCurve(group, pos.x(), segment.easingCurve());
|
attachEasingCurve(group, pos.x(), segment.easingCurve());
|
||||||
@@ -346,8 +347,6 @@ void CurveEditorView::commitKeyframes(TreeItem *item)
|
|||||||
QVariant data = frame.data();
|
QVariant data = frame.data();
|
||||||
if (data.type() == static_cast<int>(QMetaType::QEasingCurve))
|
if (data.type() == static_cast<int>(QMetaType::QEasingCurve))
|
||||||
attachEasingCurve(group, pos.x(), data.value<QEasingCurve>());
|
attachEasingCurve(group, pos.x(), data.value<QEasingCurve>());
|
||||||
} else if (frame.interpolation() == Keyframe::Interpolation::Step) {
|
|
||||||
// Warning: Keyframe::Interpolation::Step not yet implemented
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -294,6 +294,13 @@ void CurveSegment::extend(QPainterPath &path) const
|
|||||||
|
|
||||||
QEasingCurve CurveSegment::easingCurve() const
|
QEasingCurve CurveSegment::easingCurve() const
|
||||||
{
|
{
|
||||||
|
if (interpolation() == Keyframe::Interpolation::Step) {
|
||||||
|
QEasingCurve curve;
|
||||||
|
curve.addCubicBezierSegment(QPointF(0.1, 0.0), QPointF(0.9, 0.0), QPointF(1.0, 0.0));
|
||||||
|
curve.addCubicBezierSegment(QPointF(1.0, 0.1), QPointF(1.0, 0.9), QPointF(1.0, 1.0));
|
||||||
|
return curve;
|
||||||
|
}
|
||||||
|
|
||||||
auto mapPosition = [this](const QPointF &position) {
|
auto mapPosition = [this](const QPointF &position) {
|
||||||
QPointF min = m_left.position();
|
QPointF min = m_left.position();
|
||||||
QPointF max = m_right.position();
|
QPointF max = m_right.position();
|
||||||
|
@@ -370,7 +370,8 @@ void DesignDocument::close()
|
|||||||
void DesignDocument::updateSubcomponentManager()
|
void DesignDocument::updateSubcomponentManager()
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_subComponentManager);
|
Q_ASSERT(m_subComponentManager);
|
||||||
m_subComponentManager->update(QUrl::fromLocalFile(fileName().toString()), currentModel()->imports());
|
m_subComponentManager->update(QUrl::fromLocalFile(fileName().toString()),
|
||||||
|
currentModel()->imports() + currentModel()->possibleImports());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignDocument::deleteSelected()
|
void DesignDocument::deleteSelected()
|
||||||
|
@@ -40,6 +40,7 @@ ItemLibraryAddImportModel::ItemLibraryAddImportModel(QObject *parent)
|
|||||||
// add role names
|
// add role names
|
||||||
m_roleNames.insert(Qt::UserRole + 1, "importUrl");
|
m_roleNames.insert(Qt::UserRole + 1, "importUrl");
|
||||||
m_roleNames.insert(Qt::UserRole + 2, "importVisible");
|
m_roleNames.insert(Qt::UserRole + 2, "importVisible");
|
||||||
|
m_roleNames.insert(Qt::UserRole + 3, "isSeparator");
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemLibraryAddImportModel::~ItemLibraryAddImportModel()
|
ItemLibraryAddImportModel::~ItemLibraryAddImportModel()
|
||||||
@@ -63,7 +64,10 @@ QVariant ItemLibraryAddImportModel::data(const QModelIndex &index, int role) con
|
|||||||
return importUrl;
|
return importUrl;
|
||||||
|
|
||||||
if (m_roleNames[role] == "importVisible")
|
if (m_roleNames[role] == "importVisible")
|
||||||
return m_searchText.isEmpty() || m_importFilterList.contains(importUrl);
|
return m_searchText.isEmpty() || importUrl.isEmpty() || m_importFilterList.contains(importUrl);
|
||||||
|
|
||||||
|
if (m_roleNames[role] == "isSeparator")
|
||||||
|
return importUrl.isEmpty();
|
||||||
|
|
||||||
qWarning() << Q_FUNC_INFO << "invalid role requested";
|
qWarning() << Q_FUNC_INFO << "invalid role requested";
|
||||||
|
|
||||||
@@ -83,9 +87,9 @@ void ItemLibraryAddImportModel::update(const QList<Import> &possibleImports)
|
|||||||
const DesignerMcuManager &mcuManager = DesignerMcuManager::instance();
|
const DesignerMcuManager &mcuManager = DesignerMcuManager::instance();
|
||||||
const bool isQtForMCUs = mcuManager.isMCUProject();
|
const bool isQtForMCUs = mcuManager.isMCUProject();
|
||||||
QList<Import> filteredImports;
|
QList<Import> filteredImports;
|
||||||
|
if (isQtForMCUs) {
|
||||||
const QStringList mcuAllowedList = mcuManager.allowedImports();
|
const QStringList mcuAllowedList = mcuManager.allowedImports();
|
||||||
const QStringList mcuBannedList = mcuManager.bannedImports();
|
const QStringList mcuBannedList = mcuManager.bannedImports();
|
||||||
if (isQtForMCUs) {
|
|
||||||
filteredImports = Utils::filtered(possibleImports,
|
filteredImports = Utils::filtered(possibleImports,
|
||||||
[&](const Import &import) {
|
[&](const Import &import) {
|
||||||
return (mcuAllowedList.contains(import.url())
|
return (mcuAllowedList.contains(import.url())
|
||||||
@@ -96,7 +100,7 @@ void ItemLibraryAddImportModel::update(const QList<Import> &possibleImports)
|
|||||||
filteredImports = possibleImports;
|
filteredImports = possibleImports;
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::sort(filteredImports, [](const Import &firstImport, const Import &secondImport) {
|
Utils::sort(filteredImports, [this](const Import &firstImport, const Import &secondImport) {
|
||||||
if (firstImport.url() == secondImport.url())
|
if (firstImport.url() == secondImport.url())
|
||||||
return firstImport.toString() < secondImport.toString();
|
return firstImport.toString() < secondImport.toString();
|
||||||
|
|
||||||
@@ -106,6 +110,10 @@ void ItemLibraryAddImportModel::update(const QList<Import> &possibleImports)
|
|||||||
if (secondImport.url() == "QtQuick")
|
if (secondImport.url() == "QtQuick")
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
const bool firstPriority = m_priorityImports.contains(firstImport.url());
|
||||||
|
if (firstPriority != m_priorityImports.contains(secondImport.url()))
|
||||||
|
return firstPriority;
|
||||||
|
|
||||||
if (firstImport.isLibraryImport() && secondImport.isFileImport())
|
if (firstImport.isLibraryImport() && secondImport.isFileImport())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -122,9 +130,15 @@ void ItemLibraryAddImportModel::update(const QList<Import> &possibleImports)
|
|||||||
});
|
});
|
||||||
|
|
||||||
// create import sections
|
// create import sections
|
||||||
|
bool previousIsPriority = false;
|
||||||
for (const Import &import : std::as_const(filteredImports)) {
|
for (const Import &import : std::as_const(filteredImports)) {
|
||||||
if (import.isLibraryImport())
|
if (import.isLibraryImport()) {
|
||||||
|
bool currentIsPriority = m_priorityImports.contains(import.url());
|
||||||
|
if (previousIsPriority && !currentIsPriority)
|
||||||
|
m_importList.append(Import::empty()); // empty import acts as a separator
|
||||||
m_importList.append(import);
|
m_importList.append(import);
|
||||||
|
previousIsPriority = currentIsPriority;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
endResetModel();
|
endResetModel();
|
||||||
@@ -153,4 +167,9 @@ Import ItemLibraryAddImportModel::getImportAt(int index) const
|
|||||||
return m_importList.at(index);
|
return m_importList.at(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ItemLibraryAddImportModel::setPriorityImports(const QSet<QString> &priorityImports)
|
||||||
|
{
|
||||||
|
m_priorityImports = priorityImports;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -50,11 +50,14 @@ public:
|
|||||||
void setSearchText(const QString &searchText);
|
void setSearchText(const QString &searchText);
|
||||||
Import getImportAt(int index) const;
|
Import getImportAt(int index) const;
|
||||||
|
|
||||||
|
void setPriorityImports(const QSet<QString> &priorityImports);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_searchText;
|
QString m_searchText;
|
||||||
QList<Import> m_importList;
|
QList<Import> m_importList;
|
||||||
QSet<QString> m_importFilterList;
|
QSet<QString> m_importFilterList;
|
||||||
QHash<int, QByteArray> m_roleNames;
|
QHash<int, QByteArray> m_roleNames;
|
||||||
|
QSet<QString> m_priorityImports;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -664,7 +664,12 @@ void ItemLibraryAssetImporter::finalizeQuick3DImport()
|
|||||||
timer->callOnTimeout([this, timer, progressTitle, model, doc]() {
|
timer->callOnTimeout([this, timer, progressTitle, model, doc]() {
|
||||||
if (!isCancelled()) {
|
if (!isCancelled()) {
|
||||||
notifyProgress(++counter * 5, progressTitle);
|
notifyProgress(++counter * 5, progressTitle);
|
||||||
if (counter == 10) {
|
if (counter < 10) {
|
||||||
|
// Do not proceed while application isn't active as the filesystem
|
||||||
|
// watcher qmljs uses won't trigger unless application is active
|
||||||
|
if (QApplication::applicationState() != Qt::ApplicationActive)
|
||||||
|
--counter;
|
||||||
|
} else if (counter == 10) {
|
||||||
model->rewriterView()->textModifier()->replace(0, 0, {});
|
model->rewriterView()->textModifier()->replace(0, 0, {});
|
||||||
} else if (counter == 19) {
|
} else if (counter == 19) {
|
||||||
try {
|
try {
|
||||||
|
@@ -127,6 +127,9 @@ void ItemLibraryCategoriesModel::sortCategorySections()
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::sort(m_categoryList.begin(), m_categoryList.end(), categorySort);
|
std::sort(m_categoryList.begin(), m_categoryList.end(), categorySort);
|
||||||
|
|
||||||
|
for (const auto &category : qAsConst(m_categoryList))
|
||||||
|
category->sortItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLibraryCategoriesModel::resetModel()
|
void ItemLibraryCategoriesModel::resetModel()
|
||||||
|
@@ -70,6 +70,8 @@ bool ItemLibraryCategory::updateItemVisibility(const QString &searchText, bool *
|
|||||||
bool itemVisible = item->itemName().toLower().contains(searchText)
|
bool itemVisible = item->itemName().toLower().contains(searchText)
|
||||||
|| item->typeName().toLower().contains(searchText);
|
|| item->typeName().toLower().contains(searchText);
|
||||||
|
|
||||||
|
if (searchText.isEmpty() && !item->isUsable())
|
||||||
|
itemVisible = false;
|
||||||
bool itemChanged = item->setVisible(itemVisible);
|
bool itemChanged = item->setVisible(itemVisible);
|
||||||
|
|
||||||
*changed |= itemChanged;
|
*changed |= itemChanged;
|
||||||
|
@@ -28,18 +28,22 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
ItemLibraryImport::ItemLibraryImport(const Import &import, QObject *parent, bool isUserSection)
|
ItemLibraryImport::ItemLibraryImport(const Import &import, QObject *parent, SectionType sectionType)
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
m_import(import),
|
m_import(import),
|
||||||
m_isUserSection(isUserSection)
|
m_sectionType(sectionType)
|
||||||
{
|
{
|
||||||
|
updateRemovable();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ItemLibraryImport::importName() const
|
QString ItemLibraryImport::importName() const
|
||||||
{
|
{
|
||||||
if (m_isUserSection)
|
if (m_sectionType == SectionType::User)
|
||||||
return userComponentsTitle();
|
return userComponentsTitle();
|
||||||
|
|
||||||
|
if (m_sectionType == SectionType::Unimported)
|
||||||
|
return unimportedComponentsTitle();
|
||||||
|
|
||||||
if (importUrl() == "QtQuick")
|
if (importUrl() == "QtQuick")
|
||||||
return tr("Default Components");
|
return tr("Default Components");
|
||||||
|
|
||||||
@@ -48,9 +52,12 @@ QString ItemLibraryImport::importName() const
|
|||||||
|
|
||||||
QString ItemLibraryImport::importUrl() const
|
QString ItemLibraryImport::importUrl() const
|
||||||
{
|
{
|
||||||
if (m_isUserSection)
|
if (m_sectionType == SectionType::User)
|
||||||
return userComponentsTitle();
|
return userComponentsTitle();
|
||||||
|
|
||||||
|
if (m_sectionType == SectionType::Unimported)
|
||||||
|
return unimportedComponentsTitle();
|
||||||
|
|
||||||
return m_import.url();
|
return m_import.url();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,11 +68,14 @@ bool ItemLibraryImport::importExpanded() const
|
|||||||
|
|
||||||
QString ItemLibraryImport::sortingName() const
|
QString ItemLibraryImport::sortingName() const
|
||||||
{
|
{
|
||||||
if (m_isUserSection) // user components always come first
|
if (m_sectionType == SectionType::User)
|
||||||
return "_";
|
return "_"; // user components always come first
|
||||||
|
|
||||||
|
if (m_sectionType == SectionType::Unimported)
|
||||||
|
return "zzzzzz"; // Unimported components always come last
|
||||||
|
|
||||||
if (!hasCategories()) // imports with no categories are at the bottom of the list
|
if (!hasCategories()) // imports with no categories are at the bottom of the list
|
||||||
return "zzzzz" + importName();
|
return "zzzzz_" + importName();
|
||||||
|
|
||||||
return importName();
|
return importName();
|
||||||
}
|
}
|
||||||
@@ -113,6 +123,7 @@ bool ItemLibraryImport::setVisible(bool isVisible)
|
|||||||
{
|
{
|
||||||
if (isVisible != m_isVisible) {
|
if (isVisible != m_isVisible) {
|
||||||
m_isVisible = isVisible;
|
m_isVisible = isVisible;
|
||||||
|
emit importVisibleChanged();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +137,11 @@ bool ItemLibraryImport::importVisible() const
|
|||||||
|
|
||||||
void ItemLibraryImport::setImportUsed(bool importUsed)
|
void ItemLibraryImport::setImportUsed(bool importUsed)
|
||||||
{
|
{
|
||||||
|
if (importUsed != m_importUsed) {
|
||||||
m_importUsed = importUsed;
|
m_importUsed = importUsed;
|
||||||
|
updateRemovable();
|
||||||
|
emit importUsedChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ItemLibraryImport::importUsed() const
|
bool ItemLibraryImport::importUsed() const
|
||||||
@@ -134,6 +149,11 @@ bool ItemLibraryImport::importUsed() const
|
|||||||
return m_importUsed;
|
return m_importUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ItemLibraryImport::importRemovable() const
|
||||||
|
{
|
||||||
|
return m_importRemovable;
|
||||||
|
}
|
||||||
|
|
||||||
bool ItemLibraryImport::hasCategories() const
|
bool ItemLibraryImport::hasCategories() const
|
||||||
{
|
{
|
||||||
return m_categoryModel.rowCount() > 0;
|
return m_categoryModel.rowCount() > 0;
|
||||||
@@ -146,7 +166,10 @@ void ItemLibraryImport::sortCategorySections()
|
|||||||
|
|
||||||
void ItemLibraryImport::setImportExpanded(bool expanded)
|
void ItemLibraryImport::setImportExpanded(bool expanded)
|
||||||
{
|
{
|
||||||
|
if (expanded != m_importExpanded) {
|
||||||
m_importExpanded = expanded;
|
m_importExpanded = expanded;
|
||||||
|
emit importExpandChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemLibraryCategory *ItemLibraryImport::getCategorySection(const QString &categoryName) const
|
ItemLibraryCategory *ItemLibraryImport::getCategorySection(const QString &categoryName) const
|
||||||
@@ -159,15 +182,30 @@ ItemLibraryCategory *ItemLibraryImport::getCategorySection(const QString &catego
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ItemLibraryImport::isUserSection() const
|
|
||||||
{
|
|
||||||
return m_isUserSection;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
QString ItemLibraryImport::userComponentsTitle()
|
QString ItemLibraryImport::userComponentsTitle()
|
||||||
{
|
{
|
||||||
return tr("My Components");
|
return tr("My Components");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString ItemLibraryImport::unimportedComponentsTitle()
|
||||||
|
{
|
||||||
|
return tr("All Other Components");
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemLibraryImport::SectionType ItemLibraryImport::sectionType() const
|
||||||
|
{
|
||||||
|
return m_sectionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemLibraryImport::updateRemovable()
|
||||||
|
{
|
||||||
|
bool importRemovable = !m_importUsed && m_sectionType == SectionType::Default
|
||||||
|
&& m_import.url() != "QtQuick";
|
||||||
|
if (importRemovable != m_importRemovable) {
|
||||||
|
m_importRemovable = importRemovable;
|
||||||
|
emit importRemovableChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -41,10 +41,18 @@ class ItemLibraryImport : public QObject
|
|||||||
Q_PROPERTY(bool importVisible READ importVisible NOTIFY importVisibleChanged FINAL)
|
Q_PROPERTY(bool importVisible READ importVisible NOTIFY importVisibleChanged FINAL)
|
||||||
Q_PROPERTY(bool importUsed READ importUsed NOTIFY importUsedChanged FINAL)
|
Q_PROPERTY(bool importUsed READ importUsed NOTIFY importUsedChanged FINAL)
|
||||||
Q_PROPERTY(bool importExpanded READ importExpanded WRITE setImportExpanded NOTIFY importExpandChanged FINAL)
|
Q_PROPERTY(bool importExpanded READ importExpanded WRITE setImportExpanded NOTIFY importExpandChanged FINAL)
|
||||||
|
Q_PROPERTY(bool importRemovable READ importRemovable NOTIFY importRemovableChanged FINAL)
|
||||||
Q_PROPERTY(QObject *categoryModel READ categoryModel NOTIFY categoryModelChanged FINAL)
|
Q_PROPERTY(QObject *categoryModel READ categoryModel NOTIFY categoryModelChanged FINAL)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ItemLibraryImport(const Import &import, QObject *parent = nullptr, bool isUserSection = false);
|
enum class SectionType {
|
||||||
|
Default,
|
||||||
|
User,
|
||||||
|
Unimported
|
||||||
|
};
|
||||||
|
|
||||||
|
ItemLibraryImport(const Import &import, QObject *parent = nullptr,
|
||||||
|
SectionType sectionType = SectionType::Default);
|
||||||
|
|
||||||
QString importName() const;
|
QString importName() const;
|
||||||
QString importUrl() const;
|
QString importUrl() const;
|
||||||
@@ -53,6 +61,7 @@ public:
|
|||||||
Import importEntry() const;
|
Import importEntry() const;
|
||||||
bool importVisible() const;
|
bool importVisible() const;
|
||||||
bool importUsed() const;
|
bool importUsed() const;
|
||||||
|
bool importRemovable() const;
|
||||||
bool hasCategories() const;
|
bool hasCategories() const;
|
||||||
ItemLibraryCategory *getCategorySection(const QString &categoryName) const;
|
ItemLibraryCategory *getCategorySection(const QString &categoryName) const;
|
||||||
|
|
||||||
@@ -66,21 +75,26 @@ public:
|
|||||||
void expandCategories(bool expand = true);
|
void expandCategories(bool expand = true);
|
||||||
|
|
||||||
static QString userComponentsTitle();
|
static QString userComponentsTitle();
|
||||||
|
static QString unimportedComponentsTitle();
|
||||||
|
|
||||||
bool isUserSection() const;
|
SectionType sectionType() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void categoryModelChanged();
|
void categoryModelChanged();
|
||||||
void importVisibleChanged();
|
void importVisibleChanged();
|
||||||
void importUsedChanged();
|
void importUsedChanged();
|
||||||
void importExpandChanged();
|
void importExpandChanged();
|
||||||
|
void importRemovableChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void updateRemovable();
|
||||||
|
|
||||||
Import m_import;
|
Import m_import;
|
||||||
bool m_importExpanded = true;
|
bool m_importExpanded = true;
|
||||||
bool m_isVisible = true;
|
bool m_isVisible = true;
|
||||||
bool m_importUsed = false;
|
bool m_importUsed = false;
|
||||||
bool m_isUserSection = false; // user components import section
|
bool m_importRemovable = false;
|
||||||
|
SectionType m_sectionType = SectionType::Default;
|
||||||
ItemLibraryCategoriesModel m_categoryModel;
|
ItemLibraryCategoriesModel m_categoryModel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -27,9 +27,10 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
ItemLibraryItem::ItemLibraryItem(const ItemLibraryEntry &itemLibraryEntry, QObject *parent)
|
ItemLibraryItem::ItemLibraryItem(const ItemLibraryEntry &itemLibraryEntry, bool isUsable, QObject *parent)
|
||||||
: QObject(parent),
|
: QObject(parent)
|
||||||
m_itemLibraryEntry(itemLibraryEntry)
|
, m_itemLibraryEntry(itemLibraryEntry)
|
||||||
|
, m_isUsable(isUsable)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,6 +62,11 @@ QString ItemLibraryItem::componentPath() const
|
|||||||
return m_itemLibraryEntry.customComponentSource();
|
return m_itemLibraryEntry.customComponentSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString ItemLibraryItem::requiredImport() const
|
||||||
|
{
|
||||||
|
return m_itemLibraryEntry.requiredImport();
|
||||||
|
}
|
||||||
|
|
||||||
bool ItemLibraryItem::setVisible(bool isVisible)
|
bool ItemLibraryItem::setVisible(bool isVisible)
|
||||||
{
|
{
|
||||||
if (isVisible != m_isVisible) {
|
if (isVisible != m_isVisible) {
|
||||||
@@ -77,6 +83,11 @@ bool ItemLibraryItem::isVisible() const
|
|||||||
return m_isVisible;
|
return m_isVisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ItemLibraryItem::isUsable() const
|
||||||
|
{
|
||||||
|
return m_isUsable;
|
||||||
|
}
|
||||||
|
|
||||||
QVariant ItemLibraryItem::itemLibraryEntry() const
|
QVariant ItemLibraryItem::itemLibraryEntry() const
|
||||||
{
|
{
|
||||||
return QVariant::fromValue(m_itemLibraryEntry);
|
return QVariant::fromValue(m_itemLibraryEntry);
|
||||||
|
@@ -43,18 +43,22 @@ class ItemLibraryItem: public QObject
|
|||||||
Q_PROPERTY(QString itemLibraryIconPath READ itemLibraryIconPath FINAL)
|
Q_PROPERTY(QString itemLibraryIconPath READ itemLibraryIconPath FINAL)
|
||||||
Q_PROPERTY(bool itemVisible READ isVisible NOTIFY visibilityChanged FINAL)
|
Q_PROPERTY(bool itemVisible READ isVisible NOTIFY visibilityChanged FINAL)
|
||||||
Q_PROPERTY(QString componentPath READ componentPath FINAL)
|
Q_PROPERTY(QString componentPath READ componentPath FINAL)
|
||||||
|
Q_PROPERTY(bool itemUsable READ isUsable FINAL)
|
||||||
|
Q_PROPERTY(QString itemRequiredImport READ requiredImport FINAL)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ItemLibraryItem(const ItemLibraryEntry &itemLibraryEntry, QObject *parent);
|
ItemLibraryItem(const ItemLibraryEntry &itemLibraryEntry, bool isImported, QObject *parent);
|
||||||
~ItemLibraryItem() override;
|
~ItemLibraryItem() override;
|
||||||
|
|
||||||
QString itemName() const;
|
QString itemName() const;
|
||||||
QString typeName() const;
|
QString typeName() const;
|
||||||
QString itemLibraryIconPath() const;
|
QString itemLibraryIconPath() const;
|
||||||
QString componentPath() const;
|
QString componentPath() const;
|
||||||
|
QString requiredImport() const;
|
||||||
|
|
||||||
bool setVisible(bool isVisible);
|
bool setVisible(bool isVisible);
|
||||||
bool isVisible() const;
|
bool isVisible() const;
|
||||||
|
bool isUsable() const;
|
||||||
|
|
||||||
QVariant itemLibraryEntry() const;
|
QVariant itemLibraryEntry() const;
|
||||||
|
|
||||||
@@ -64,6 +68,7 @@ signals:
|
|||||||
private:
|
private:
|
||||||
ItemLibraryEntry m_itemLibraryEntry;
|
ItemLibraryEntry m_itemLibraryEntry;
|
||||||
bool m_isVisible = true;
|
bool m_isVisible = true;
|
||||||
|
bool m_isUsable = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -70,7 +70,7 @@ void ItemLibraryItemsModel::addItem(ItemLibraryItem *element)
|
|||||||
{
|
{
|
||||||
m_itemList.append(element);
|
m_itemList.append(element);
|
||||||
|
|
||||||
element->setVisible(true);
|
element->setVisible(element->isUsable());
|
||||||
}
|
}
|
||||||
|
|
||||||
const QList<QPointer<ItemLibraryItem>> &ItemLibraryItemsModel::items() const
|
const QList<QPointer<ItemLibraryItem>> &ItemLibraryItemsModel::items() const
|
||||||
|
@@ -167,7 +167,7 @@ void ItemLibraryModel::setSearchText(const QString &searchText)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Import entryToImport(const ItemLibraryEntry &entry)
|
Import ItemLibraryModel::entryToImport(const ItemLibraryEntry &entry)
|
||||||
{
|
{
|
||||||
if (entry.majorVersion() == -1 && entry.minorVersion() == -1)
|
if (entry.majorVersion() == -1 && entry.minorVersion() == -1)
|
||||||
return Import::createFileImport(entry.requiredImport());
|
return Import::createFileImport(entry.requiredImport());
|
||||||
@@ -177,6 +177,28 @@ Import entryToImport(const ItemLibraryEntry &entry)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true if first import version is higher or equal to second import version
|
||||||
|
static bool compareVersions(const QString &version1, const QString &version2)
|
||||||
|
{
|
||||||
|
if (version2.isEmpty() || version1 == version2)
|
||||||
|
return true;
|
||||||
|
const QStringList version1List = version1.split(QLatin1Char('.'));
|
||||||
|
const QStringList version2List = version2.split(QLatin1Char('.'));
|
||||||
|
if (version1List.count() == 2 && version2List.count() == 2) {
|
||||||
|
int major1 = version1List.constFirst().toInt();
|
||||||
|
int major2 = version2List.constFirst().toInt();
|
||||||
|
if (major1 > major2) {
|
||||||
|
return true;
|
||||||
|
} else if (major1 == major2) {
|
||||||
|
int minor1 = version1List.constLast().toInt();
|
||||||
|
int minor2 = version2List.constLast().toInt();
|
||||||
|
if (minor1 >= minor2)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model)
|
void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model)
|
||||||
{
|
{
|
||||||
if (!model)
|
if (!model)
|
||||||
@@ -190,12 +212,28 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model)
|
|||||||
QString projectName = project ? project->displayName() : "";
|
QString projectName = project ? project->displayName() : "";
|
||||||
|
|
||||||
// create import sections
|
// create import sections
|
||||||
|
QHash<QString, ItemLibraryImport *> importHash;
|
||||||
for (const Import &import : model->imports()) {
|
for (const Import &import : model->imports()) {
|
||||||
if (import.isLibraryImport() && import.url() != projectName) {
|
if (import.isLibraryImport() && import.url() != projectName) {
|
||||||
ItemLibraryImport *itemLibImport = new ItemLibraryImport(import, this);
|
bool addNew = true;
|
||||||
m_importList.append(itemLibImport);
|
ItemLibraryImport *oldImport = importHash.value(import.url());
|
||||||
itemLibImport->setImportExpanded(loadExpandedState(import.url()));
|
if (oldImport && oldImport->importEntry().url() == import.url()) {
|
||||||
|
// Retain the higher version if multiples exist
|
||||||
|
if (compareVersions(oldImport->importEntry().version(), import.version()))
|
||||||
|
addNew = false;
|
||||||
|
else
|
||||||
|
delete oldImport;
|
||||||
}
|
}
|
||||||
|
if (addNew) {
|
||||||
|
ItemLibraryImport *itemLibImport = new ItemLibraryImport(import, this);
|
||||||
|
importHash.insert(import.url(), itemLibImport);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto itemLibImport : qAsConst(importHash)) {
|
||||||
|
m_importList.append(itemLibImport);
|
||||||
|
itemLibImport->setImportExpanded(loadExpandedState(itemLibImport->importEntry().url()));
|
||||||
}
|
}
|
||||||
|
|
||||||
const QList<ItemLibraryEntry> itemLibEntries = itemLibraryInfo->entries();
|
const QList<ItemLibraryEntry> itemLibEntries = itemLibraryInfo->entries();
|
||||||
@@ -204,46 +242,61 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model)
|
|||||||
|
|
||||||
bool valid = metaInfo.isValid() && metaInfo.majorVersion() == entry.majorVersion();
|
bool valid = metaInfo.isValid() && metaInfo.majorVersion() == entry.majorVersion();
|
||||||
bool isItem = valid && metaInfo.isSubclassOf("QtQuick.Item");
|
bool isItem = valid && metaInfo.isSubclassOf("QtQuick.Item");
|
||||||
bool forceVisiblity = valid && NodeHints::fromItemLibraryEntry(entry).visibleInLibrary();
|
bool forceVisibility = valid && NodeHints::fromItemLibraryEntry(entry).visibleInLibrary();
|
||||||
|
|
||||||
if (m_flowMode && metaInfo.isValid()) {
|
if (m_flowMode && metaInfo.isValid()) {
|
||||||
isItem = metaInfo.isSubclassOf("FlowView.FlowItem")
|
isItem = metaInfo.isSubclassOf("FlowView.FlowItem")
|
||||||
|| metaInfo.isSubclassOf("FlowView.FlowWildcard")
|
|| metaInfo.isSubclassOf("FlowView.FlowWildcard")
|
||||||
|| metaInfo.isSubclassOf("FlowView.FlowDecision");
|
|| metaInfo.isSubclassOf("FlowView.FlowDecision");
|
||||||
forceVisiblity = isItem;
|
forceVisibility = isItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool blocked = false;
|
||||||
const DesignerMcuManager &mcuManager = DesignerMcuManager::instance();
|
const DesignerMcuManager &mcuManager = DesignerMcuManager::instance();
|
||||||
if (mcuManager.isMCUProject()) {
|
if (mcuManager.isMCUProject()) {
|
||||||
const QSet<QString> blockTypes = mcuManager.bannedItems();
|
const QSet<QString> blockTypes = mcuManager.bannedItems();
|
||||||
|
|
||||||
if (blockTypes.contains(QString::fromUtf8(entry.typeName())))
|
if (blockTypes.contains(QString::fromUtf8(entry.typeName())))
|
||||||
valid = false;
|
blocked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid && (isItem || forceVisiblity) // We can change if the navigator does support pure QObjects
|
Import import = entryToImport(entry);
|
||||||
&& (entry.requiredImport().isEmpty()
|
bool hasImport = model->hasImport(import, true, true);
|
||||||
|| model->hasImport(entryToImport(entry), true, true))) {
|
bool isImportPossible = false;
|
||||||
|
if (!hasImport)
|
||||||
|
isImportPossible = model->isImportPossible(import, true, true);
|
||||||
|
bool isUsable = (valid && (isItem || forceVisibility))
|
||||||
|
&& (entry.requiredImport().isEmpty() || hasImport);
|
||||||
|
if (!blocked && (isUsable || isImportPossible)) {
|
||||||
ItemLibraryImport *importSection = nullptr;
|
ItemLibraryImport *importSection = nullptr;
|
||||||
|
|
||||||
QString catName = entry.category();
|
QString catName = entry.category();
|
||||||
|
if (isUsable) {
|
||||||
if (catName == ItemLibraryImport::userComponentsTitle()) {
|
if (catName == ItemLibraryImport::userComponentsTitle()) {
|
||||||
// create an import section for user components
|
// create an import section for user components
|
||||||
importSection = importByUrl(ItemLibraryImport::userComponentsTitle());
|
importSection = importByUrl(ItemLibraryImport::userComponentsTitle());
|
||||||
if (!importSection) {
|
if (!importSection) {
|
||||||
importSection = new ItemLibraryImport({}, this, true);
|
importSection = new ItemLibraryImport(
|
||||||
|
{}, this, ItemLibraryImport::SectionType::User);
|
||||||
m_importList.append(importSection);
|
m_importList.append(importSection);
|
||||||
importSection->setImportExpanded(loadExpandedState(catName));
|
importSection->setImportExpanded(loadExpandedState(catName));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (catName.startsWith("Qt Quick - "))
|
if (catName.startsWith("Qt Quick - "))
|
||||||
catName = catName.mid(11); // remove "Qt Quick - "
|
catName = catName.mid(11); // remove "Qt Quick - "
|
||||||
|
|
||||||
importSection = importByUrl(entry.requiredImport());
|
importSection = importByUrl(entry.requiredImport());
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
catName = ItemLibraryImport::unimportedComponentsTitle();
|
||||||
|
importSection = importByUrl(catName);
|
||||||
|
if (!importSection) {
|
||||||
|
importSection = new ItemLibraryImport(
|
||||||
|
{}, this, ItemLibraryImport::SectionType::Unimported);
|
||||||
|
m_importList.append(importSection);
|
||||||
|
importSection->setImportExpanded(loadExpandedState(catName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!importSection) { // should not happen, but just in case
|
if (!importSection) {
|
||||||
qWarning() << __FUNCTION__ << "No import section found! skipping entry: " << entry.name();
|
qWarning() << __FUNCTION__ << "No import section found! skipping entry: " << entry.name();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -253,12 +306,12 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model)
|
|||||||
if (!categorySection) {
|
if (!categorySection) {
|
||||||
categorySection = new ItemLibraryCategory(catName, importSection);
|
categorySection = new ItemLibraryCategory(catName, importSection);
|
||||||
importSection->addCategory(categorySection);
|
importSection->addCategory(categorySection);
|
||||||
if (!importSection->isUserSection())
|
if (importSection->sectionType() == ItemLibraryImport::SectionType::Default)
|
||||||
categorySection->setExpanded(loadExpandedState(categorySection->categoryName()));
|
categorySection->setExpanded(loadExpandedState(categorySection->categoryName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// create item
|
// create item
|
||||||
auto item = new ItemLibraryItem(entry, categorySection);
|
auto item = new ItemLibraryItem(entry, isUsable, categorySection);
|
||||||
categorySection->addItem(item);
|
categorySection->addItem(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -300,7 +353,9 @@ ItemLibraryImport *ItemLibraryModel::importByUrl(const QString &importUrl) const
|
|||||||
if (itemLibraryImport->importUrl() == importUrl
|
if (itemLibraryImport->importUrl() == importUrl
|
||||||
|| (importUrl.isEmpty() && itemLibraryImport->importUrl() == "QtQuick")
|
|| (importUrl.isEmpty() && itemLibraryImport->importUrl() == "QtQuick")
|
||||||
|| (importUrl == ItemLibraryImport::userComponentsTitle()
|
|| (importUrl == ItemLibraryImport::userComponentsTitle()
|
||||||
&& itemLibraryImport->isUserSection())) {
|
&& itemLibraryImport->sectionType() == ItemLibraryImport::SectionType::User)
|
||||||
|
|| (importUrl == ItemLibraryImport::unimportedComponentsTitle()
|
||||||
|
&& itemLibraryImport->sectionType() == ItemLibraryImport::SectionType::Unimported)) {
|
||||||
return itemLibraryImport;
|
return itemLibraryImport;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -324,9 +379,11 @@ void ItemLibraryModel::updateVisibility(bool *changed)
|
|||||||
for (ItemLibraryImport *import : std::as_const(m_importList)) {
|
for (ItemLibraryImport *import : std::as_const(m_importList)) {
|
||||||
bool categoryChanged = false;
|
bool categoryChanged = false;
|
||||||
bool hasVisibleItems = import->updateCategoryVisibility(m_searchText, &categoryChanged);
|
bool hasVisibleItems = import->updateCategoryVisibility(m_searchText, &categoryChanged);
|
||||||
|
|
||||||
*changed |= categoryChanged;
|
*changed |= categoryChanged;
|
||||||
|
|
||||||
|
if (import->sectionType() == ItemLibraryImport::SectionType::Unimported)
|
||||||
|
*changed |= import->setVisible(!m_searchText.isEmpty());
|
||||||
|
|
||||||
// expand import if it has an item matching search criteria
|
// expand import if it has an item matching search criteria
|
||||||
if (hasVisibleItems && !import->importExpanded())
|
if (hasVisibleItems && !import->importExpanded())
|
||||||
import->setImportExpanded();
|
import->setImportExpanded();
|
||||||
|
@@ -69,6 +69,8 @@ public:
|
|||||||
Q_INVOKABLE void expandAll();
|
Q_INVOKABLE void expandAll();
|
||||||
Q_INVOKABLE void collapseAll();
|
Q_INVOKABLE void collapseAll();
|
||||||
|
|
||||||
|
Import entryToImport(const ItemLibraryEntry &entry);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateVisibility(bool *changed);
|
void updateVisibility(bool *changed);
|
||||||
void addRoleNames();
|
void addRoleNames();
|
||||||
|
@@ -86,7 +86,24 @@ bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event)
|
|||||||
QMetaObject::invokeMethod(m_itemViewQuickWidget->rootObject(), "closeContextMenu");
|
QMetaObject::invokeMethod(m_itemViewQuickWidget->rootObject(), "closeContextMenu");
|
||||||
} else if (event->type() == QMouseEvent::MouseMove) {
|
} else if (event->type() == QMouseEvent::MouseMove) {
|
||||||
if (m_itemToDrag.isValid()) {
|
if (m_itemToDrag.isValid()) {
|
||||||
|
QMouseEvent *me = static_cast<QMouseEvent *>(event);
|
||||||
|
if ((me->globalPos() - m_dragStartPoint).manhattanLength() > 10) {
|
||||||
ItemLibraryEntry entry = m_itemToDrag.value<ItemLibraryEntry>();
|
ItemLibraryEntry entry = m_itemToDrag.value<ItemLibraryEntry>();
|
||||||
|
// For drag to be handled correctly, we must have the component properly imported
|
||||||
|
// beforehand, so we import the module immediately when the drag starts
|
||||||
|
if (!entry.requiredImport().isEmpty()) {
|
||||||
|
Import import = Import::createLibraryImport(entry.requiredImport());
|
||||||
|
if (!m_model->hasImport(import, true, true)) {
|
||||||
|
const QList<Import> possImports = m_model->possibleImports();
|
||||||
|
for (const auto &possImport : possImports) {
|
||||||
|
if (possImport.url() == import.url()) {
|
||||||
|
m_model->changeImports({possImport}, {});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto drag = new QDrag(this);
|
auto drag = new QDrag(this);
|
||||||
drag->setPixmap(Utils::StyleHelper::dpiSpecificImageFile(entry.libraryEntryIconPath()));
|
drag->setPixmap(Utils::StyleHelper::dpiSpecificImageFile(entry.libraryEntryIconPath()));
|
||||||
drag->setMimeData(m_itemLibraryModel->getMimeData(entry));
|
drag->setMimeData(m_itemLibraryModel->getMimeData(entry));
|
||||||
@@ -96,6 +113,9 @@ bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event)
|
|||||||
m_itemToDrag = {};
|
m_itemToDrag = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (event->type() == QMouseEvent::MouseButtonRelease) {
|
||||||
|
m_itemToDrag = {};
|
||||||
|
}
|
||||||
|
|
||||||
return QObject::eventFilter(obj, event);
|
return QObject::eventFilter(obj, event);
|
||||||
}
|
}
|
||||||
@@ -229,11 +249,16 @@ void ItemLibraryWidget::setItemLibraryInfo(ItemLibraryInfo *itemLibraryInfo)
|
|||||||
if (m_itemLibraryInfo) {
|
if (m_itemLibraryInfo) {
|
||||||
disconnect(m_itemLibraryInfo.data(), &ItemLibraryInfo::entriesChanged,
|
disconnect(m_itemLibraryInfo.data(), &ItemLibraryInfo::entriesChanged,
|
||||||
this, &ItemLibraryWidget::delayedUpdateModel);
|
this, &ItemLibraryWidget::delayedUpdateModel);
|
||||||
|
disconnect(m_itemLibraryInfo.data(), &ItemLibraryInfo::priorityImportsChanged,
|
||||||
|
this, &ItemLibraryWidget::handlePriorityImportsChanged);
|
||||||
}
|
}
|
||||||
m_itemLibraryInfo = itemLibraryInfo;
|
m_itemLibraryInfo = itemLibraryInfo;
|
||||||
if (itemLibraryInfo) {
|
if (itemLibraryInfo) {
|
||||||
connect(m_itemLibraryInfo.data(), &ItemLibraryInfo::entriesChanged,
|
connect(m_itemLibraryInfo.data(), &ItemLibraryInfo::entriesChanged,
|
||||||
this, &ItemLibraryWidget::delayedUpdateModel);
|
this, &ItemLibraryWidget::delayedUpdateModel);
|
||||||
|
connect(m_itemLibraryInfo.data(), &ItemLibraryInfo::priorityImportsChanged,
|
||||||
|
this, &ItemLibraryWidget::handlePriorityImportsChanged);
|
||||||
|
m_itemLibraryAddImportModel->setPriorityImports(m_itemLibraryInfo->priorityImports());
|
||||||
}
|
}
|
||||||
delayedUpdateModel();
|
delayedUpdateModel();
|
||||||
}
|
}
|
||||||
@@ -344,6 +369,7 @@ void ItemLibraryWidget::updateModel()
|
|||||||
void ItemLibraryWidget::updatePossibleImports(const QList<Import> &possibleImports)
|
void ItemLibraryWidget::updatePossibleImports(const QList<Import> &possibleImports)
|
||||||
{
|
{
|
||||||
m_itemLibraryAddImportModel->update(possibleImports);
|
m_itemLibraryAddImportModel->update(possibleImports);
|
||||||
|
delayedUpdateModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLibraryWidget::updateUsedImports(const QList<Import> &usedImports)
|
void ItemLibraryWidget::updateUsedImports(const QList<Import> &usedImports)
|
||||||
@@ -365,6 +391,14 @@ void ItemLibraryWidget::updateSearch()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ItemLibraryWidget::handlePriorityImportsChanged()
|
||||||
|
{
|
||||||
|
if (!m_itemLibraryInfo.isNull()) {
|
||||||
|
m_itemLibraryAddImportModel->setPriorityImports(m_itemLibraryInfo->priorityImports());
|
||||||
|
m_itemLibraryAddImportModel->update(m_model->possibleImports());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ItemLibraryWidget::setResourcePath(const QString &resourcePath)
|
void ItemLibraryWidget::setResourcePath(const QString &resourcePath)
|
||||||
{
|
{
|
||||||
if (m_resourcesView->model() == m_resourcesFileSystemModel.data()) {
|
if (m_resourcesView->model() == m_resourcesFileSystemModel.data()) {
|
||||||
@@ -374,12 +408,13 @@ void ItemLibraryWidget::setResourcePath(const QString &resourcePath)
|
|||||||
updateSearch();
|
updateSearch();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLibraryWidget::startDragAndDrop(const QVariant &itemLibEntry)
|
void ItemLibraryWidget::startDragAndDrop(const QVariant &itemLibEntry, const QPointF &mousePos)
|
||||||
{
|
{
|
||||||
// Actual drag is created after mouse has moved to avoid a QDrag bug that causes drag to stay
|
// Actual drag is created after mouse has moved to avoid a QDrag bug that causes drag to stay
|
||||||
// active (and blocks mouse release) if mouse is released at the same spot of the drag start.
|
// active (and blocks mouse release) if mouse is released at the same spot of the drag start.
|
||||||
// This doesn't completely eliminate the bug but makes it significantly harder to produce.
|
// This doesn't completely eliminate the bug but makes it significantly harder to produce.
|
||||||
m_itemToDrag = itemLibEntry;
|
m_itemToDrag = itemLibEntry;
|
||||||
|
m_dragStartPoint = mousePos.toPoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLibraryWidget::setFlowMode(bool b)
|
void ItemLibraryWidget::setFlowMode(bool b)
|
||||||
@@ -396,6 +431,15 @@ void ItemLibraryWidget::removeImport(const QString &importUrl)
|
|||||||
m_model->changeImports({}, {importSection->importEntry()});
|
m_model->changeImports({}, {importSection->importEntry()});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ItemLibraryWidget::addImportForItem(const QVariant &entry)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_itemLibraryModel, return);
|
||||||
|
QTC_ASSERT(m_model, return);
|
||||||
|
|
||||||
|
Import import = m_itemLibraryModel->entryToImport(entry.value<ItemLibraryEntry>());
|
||||||
|
m_model->changeImports({import}, {});
|
||||||
|
}
|
||||||
|
|
||||||
void ItemLibraryWidget::addResources(const QStringList &files)
|
void ItemLibraryWidget::addResources(const QStringList &files)
|
||||||
{
|
{
|
||||||
auto document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
auto document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||||
|
@@ -39,6 +39,7 @@
|
|||||||
#include <QQuickWidget>
|
#include <QQuickWidget>
|
||||||
#include <QQmlPropertyMap>
|
#include <QQmlPropertyMap>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QPointF>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -87,8 +88,9 @@ public:
|
|||||||
void setModel(Model *model);
|
void setModel(Model *model);
|
||||||
void setFlowMode(bool b);
|
void setFlowMode(bool b);
|
||||||
|
|
||||||
Q_INVOKABLE void startDragAndDrop(const QVariant &itemLibEntry);
|
Q_INVOKABLE void startDragAndDrop(const QVariant &itemLibEntry, const QPointF &mousePos);
|
||||||
Q_INVOKABLE void removeImport(const QString &importUrl);
|
Q_INVOKABLE void removeImport(const QString &importUrl);
|
||||||
|
Q_INVOKABLE void addImportForItem(const QVariant &entry);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void itemActivated(const QString& itemName);
|
void itemActivated(const QString& itemName);
|
||||||
@@ -102,6 +104,7 @@ private:
|
|||||||
void addResources(const QStringList &files);
|
void addResources(const QStringList &files);
|
||||||
void importDroppedFiles(const QList<Utils::DropSupport::FileSpec> &files);
|
void importDroppedFiles(const QList<Utils::DropSupport::FileSpec> &files);
|
||||||
void updateSearch();
|
void updateSearch();
|
||||||
|
void handlePriorityImportsChanged();
|
||||||
|
|
||||||
QTimer m_compressionTimer;
|
QTimer m_compressionTimer;
|
||||||
QSize m_itemIconSize;
|
QSize m_itemIconSize;
|
||||||
@@ -126,6 +129,7 @@ private:
|
|||||||
QVariant m_itemToDrag;
|
QVariant m_itemToDrag;
|
||||||
bool m_updateRetry = false;
|
bool m_updateRetry = false;
|
||||||
QString m_filterText;
|
QString m_filterText;
|
||||||
|
QPoint m_dragStartPoint;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleTabChanged(int index);
|
void handleTabChanged(int index);
|
||||||
|
@@ -57,8 +57,10 @@ Column {
|
|||||||
|
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
width: listView.width
|
width: listView.width
|
||||||
height: 25
|
height: isSeparator ? 4 : 25
|
||||||
color: mouseArea.containsMouse ? Qt.lighter(Theme.qmlDesignerButtonColor(), 1.3)
|
color: isSeparator ? Theme.color(Theme.BackgroundColorNormal)
|
||||||
|
: mouseArea.containsMouse
|
||||||
|
? Qt.lighter(Theme.qmlDesignerButtonColor(), 1.3)
|
||||||
: Theme.qmlDesignerButtonColor()
|
: Theme.qmlDesignerButtonColor()
|
||||||
visible: importVisible
|
visible: importVisible
|
||||||
|
|
||||||
@@ -77,6 +79,7 @@ Column {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onClicked: addImport(index)
|
onClicked: addImport(index)
|
||||||
|
enabled: !isSeparator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,23 +24,25 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "richtexteditorproxy.h"
|
#include "richtexteditorproxy.h"
|
||||||
|
#include "richtexteditor.h"
|
||||||
|
|
||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
#include <qmldesignerconstants.h>
|
#include <qmldesignerconstants.h>
|
||||||
|
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
|
|
||||||
#include "richtexteditor.h"
|
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
RichTextEditorProxy::RichTextEditorProxy(QObject *parent)
|
RichTextEditorProxy::RichTextEditorProxy(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_dialog(new QDialog{})
|
, m_dialog(new QDialog(Core::ICore::dialogParent()))
|
||||||
, m_widget(new RichTextEditor{})
|
, m_widget(new RichTextEditor{})
|
||||||
{
|
{
|
||||||
|
m_dialog->setModal(true);
|
||||||
QGridLayout *layout = new QGridLayout{};
|
QGridLayout *layout = new QGridLayout{};
|
||||||
|
|
||||||
layout->addWidget(m_widget);
|
layout->addWidget(m_widget);
|
||||||
|
@@ -110,7 +110,7 @@ void TransitionEditorView::nodeReparented(const ModelNode &node,
|
|||||||
|
|
||||||
const ModelNode parent = newPropertyParent.parentModelNode();
|
const ModelNode parent = newPropertyParent.parentModelNode();
|
||||||
|
|
||||||
qDebug() << Q_FUNC_INFO << parent;
|
// qDebug() << Q_FUNC_INFO << parent;
|
||||||
if (parent.isValid() && parent.metaInfo().isValid()
|
if (parent.isValid() && parent.metaInfo().isValid()
|
||||||
&& parent.metaInfo().isSubclassOf("QtQuick.Transition")) {
|
&& parent.metaInfo().isSubclassOf("QtQuick.Transition")) {
|
||||||
asyncUpdate(parent);
|
asyncUpdate(parent);
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include "propertycontainer.h"
|
#include "propertycontainer.h"
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
#include <QSet>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
@@ -108,11 +109,14 @@ public:
|
|||||||
void clearEntries();
|
void clearEntries();
|
||||||
|
|
||||||
QStringList blacklistImports() const;
|
QStringList blacklistImports() const;
|
||||||
|
QSet<QString> priorityImports() const;
|
||||||
|
|
||||||
void addBlacklistImports(const QStringList &list);
|
void addBlacklistImports(const QStringList &list);
|
||||||
|
void addPriorityImports(const QSet<QString> &set);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void entriesChanged();
|
void entriesChanged();
|
||||||
|
void priorityImportsChanged();
|
||||||
|
|
||||||
private: // functions
|
private: // functions
|
||||||
ItemLibraryInfo(QObject *parent = nullptr);
|
ItemLibraryInfo(QObject *parent = nullptr);
|
||||||
@@ -123,6 +127,7 @@ private: // variables
|
|||||||
QPointer<ItemLibraryInfo> m_baseInfo;
|
QPointer<ItemLibraryInfo> m_baseInfo;
|
||||||
|
|
||||||
QStringList m_blacklistImports;
|
QStringList m_blacklistImports;
|
||||||
|
QSet<QString> m_priorityImports;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -344,11 +344,27 @@ QStringList ItemLibraryInfo::blacklistImports() const
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QSet<QString> ItemLibraryInfo::priorityImports() const
|
||||||
|
{
|
||||||
|
QSet<QString> set = m_priorityImports;
|
||||||
|
if (m_baseInfo)
|
||||||
|
set.unite(m_baseInfo->m_priorityImports);
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
void ItemLibraryInfo::addBlacklistImports(const QStringList &list)
|
void ItemLibraryInfo::addBlacklistImports(const QStringList &list)
|
||||||
{
|
{
|
||||||
m_blacklistImports.append(list);
|
m_blacklistImports.append(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ItemLibraryInfo::addPriorityImports(const QSet<QString> &set)
|
||||||
|
{
|
||||||
|
if (!set.isEmpty()) {
|
||||||
|
m_priorityImports.unite(set);
|
||||||
|
emit priorityImportsChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ItemLibraryInfo::setBaseInfo(ItemLibraryInfo *baseInfo)
|
void ItemLibraryInfo::setBaseInfo(ItemLibraryInfo *baseInfo)
|
||||||
{
|
{
|
||||||
m_baseInfo = baseInfo;
|
m_baseInfo = baseInfo;
|
||||||
|
@@ -26,6 +26,8 @@
|
|||||||
#include "metainforeader.h"
|
#include "metainforeader.h"
|
||||||
#include "metainfo.h"
|
#include "metainfo.h"
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@@ -230,8 +232,10 @@ void MetaInfoReader::readImportsProperty(const QString &name, const QVariant &va
|
|||||||
|
|
||||||
if (name == "blacklistImports" && !values.isEmpty()) {
|
if (name == "blacklistImports" && !values.isEmpty()) {
|
||||||
m_metaInfo.itemLibraryInfo()->addBlacklistImports(values);
|
m_metaInfo.itemLibraryInfo()->addBlacklistImports(values);
|
||||||
} else if (name == "showTagsForImports" && !values.isEmpty()) {
|
} else if ((name == "priorityImports" || name == "showTagsForImports") && !values.isEmpty()) {
|
||||||
// Flow tags removed, but keeping this for now to avoid errors parsing old metadata files
|
// Flow tags are no longer shown, but the old property is still supported for prioritizing
|
||||||
|
// imports to keep compatibility with old metainfo files.
|
||||||
|
m_metaInfo.itemLibraryInfo()->addPriorityImports(Utils::toSet(values));
|
||||||
} else {
|
} else {
|
||||||
addError(tr("Unknown property for Imports %1").arg(name), currentSourceLocation());
|
addError(tr("Unknown property for Imports %1").arg(name), currentSourceLocation());
|
||||||
setParserState(Error);
|
setParserState(Error);
|
||||||
|
@@ -45,8 +45,6 @@
|
|||||||
#include <transitioneditor/transitioneditorview.h>
|
#include <transitioneditor/transitioneditorview.h>
|
||||||
#include <pathtool/pathtool.h>
|
#include <pathtool/pathtool.h>
|
||||||
|
|
||||||
#include <app/app_version.h>
|
|
||||||
|
|
||||||
#include <qmljseditor/qmljseditor.h>
|
#include <qmljseditor/qmljseditor.h>
|
||||||
#include <qmljseditor/qmljseditorconstants.h>
|
#include <qmljseditor/qmljseditorconstants.h>
|
||||||
#include <qmljseditor/qmljseditordocument.h>
|
#include <qmljseditor/qmljseditordocument.h>
|
||||||
@@ -62,6 +60,7 @@
|
|||||||
#include <coreplugin/messagebox.h>
|
#include <coreplugin/messagebox.h>
|
||||||
#include <coreplugin/modemanager.h>
|
#include <coreplugin/modemanager.h>
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
|
#include <extensionsystem/pluginmanager.h>
|
||||||
#include <extensionsystem/pluginspec.h>
|
#include <extensionsystem/pluginspec.h>
|
||||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||||
#include <projectexplorer/projectexplorerconstants.h>
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
@@ -71,6 +70,7 @@
|
|||||||
|
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
@@ -232,12 +232,13 @@ bool QmlDesignerPlugin::initialize(const QStringList & /*arguments*/, QString *e
|
|||||||
bool QmlDesignerPlugin::delayedInitialize()
|
bool QmlDesignerPlugin::delayedInitialize()
|
||||||
{
|
{
|
||||||
// adding default path to item library plugins
|
// adding default path to item library plugins
|
||||||
const QString pluginPath = Utils::HostOsInfo::isMacHost()
|
const QString postfix = Utils::HostOsInfo::isMacHost() ? QString("/QmlDesigner")
|
||||||
? QString(QCoreApplication::applicationDirPath() + "/../PlugIns/QmlDesigner")
|
: QString("/qmldesigner");
|
||||||
: QString(QCoreApplication::applicationDirPath() + "/../"
|
const QStringList pluginPaths =
|
||||||
+ QLatin1String(IDE_LIBRARY_BASENAME) + "/" + Core::Constants::IDE_ID
|
Utils::transform(ExtensionSystem::PluginManager::pluginPaths(), [postfix](const QString &p) {
|
||||||
+ "/plugins/qmldesigner");
|
return QString(p + postfix);
|
||||||
MetaInfo::setPluginPaths(QStringList(pluginPath));
|
});
|
||||||
|
MetaInfo::setPluginPaths(pluginPaths);
|
||||||
|
|
||||||
d->settings.fromSettings(Core::ICore::settings());
|
d->settings.fromSettings(Core::ICore::settings());
|
||||||
|
|
||||||
|
@@ -1012,6 +1012,7 @@ void FindReferences::displayResults(int first, int last)
|
|||||||
item.setFilePath(Utils::FilePath::fromString(result.path));
|
item.setFilePath(Utils::FilePath::fromString(result.path));
|
||||||
item.setLineText(result.lineText);
|
item.setLineText(result.lineText);
|
||||||
item.setMainRange(result.line, result.col, result.len);
|
item.setMainRange(result.line, result.col, result.len);
|
||||||
|
item.setUseTextEditorFont(true);
|
||||||
m_currentSearch->addResult(item);
|
m_currentSearch->addResult(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
add_qtc_plugin(QmlProfiler
|
add_qtc_plugin(QmlProfiler
|
||||||
|
CONDITION TARGET Tracing
|
||||||
DEPENDS QmlDebug QmlJS Tracing Qt5::QuickWidgets
|
DEPENDS QmlDebug QmlJS Tracing Qt5::QuickWidgets
|
||||||
PLUGIN_DEPENDS Core Debugger ProjectExplorer QtSupport TextEditor
|
PLUGIN_DEPENDS Core Debugger ProjectExplorer QtSupport TextEditor
|
||||||
SOURCES
|
SOURCES
|
||||||
|
@@ -287,6 +287,10 @@ public:
|
|||||||
m_searcher->setPlaceholderText(ExamplesWelcomePage::tr("Search in Examples..."));
|
m_searcher->setPlaceholderText(ExamplesWelcomePage::tr("Search in Examples..."));
|
||||||
|
|
||||||
auto exampleSetSelector = new QComboBox(this);
|
auto exampleSetSelector = new QComboBox(this);
|
||||||
|
QPalette pal = exampleSetSelector->palette();
|
||||||
|
// for macOS dark mode
|
||||||
|
pal.setColor(QPalette::Text, Utils::creatorTheme()->color(Theme::Welcome_TextColor));
|
||||||
|
exampleSetSelector->setPalette(pal);
|
||||||
exampleSetSelector->setMinimumWidth(GridProxyModel::GridItemWidth);
|
exampleSetSelector->setMinimumWidth(GridProxyModel::GridItemWidth);
|
||||||
exampleSetSelector->setMaximumWidth(GridProxyModel::GridItemWidth);
|
exampleSetSelector->setMaximumWidth(GridProxyModel::GridItemWidth);
|
||||||
ExampleSetModel *exampleSetModel = m_examplesModel->exampleSetModel();
|
ExampleSetModel *exampleSetModel = m_examplesModel->exampleSetModel();
|
||||||
|
@@ -159,8 +159,19 @@ void RsyncDeployService::deployNextFile()
|
|||||||
}
|
}
|
||||||
const DeployableFile file = m_deployableFiles.takeFirst();
|
const DeployableFile file = m_deployableFiles.takeFirst();
|
||||||
const RsyncCommandLine cmdLine = RsyncDeployStep::rsyncCommand(*connection(), m_flags);
|
const RsyncCommandLine cmdLine = RsyncDeployStep::rsyncCommand(*connection(), m_flags);
|
||||||
|
QString localFilePath = file.localFilePath().toString();
|
||||||
|
|
||||||
|
// On Windows, rsync is either from msys or cygwin. Neither work with the other's ssh.exe.
|
||||||
|
if (HostOsInfo::isWindowsHost()) {
|
||||||
|
localFilePath = '/' + localFilePath.at(0) + localFilePath.mid(2);
|
||||||
|
if (anyOf(cmdLine.options, [](const QString &opt) {
|
||||||
|
return opt.contains("cygwin", Qt::CaseInsensitive); })) {
|
||||||
|
localFilePath.prepend("/cygdrive");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const QStringList args = QStringList(cmdLine.options)
|
const QStringList args = QStringList(cmdLine.options)
|
||||||
<< (file.localFilePath().toString() + (file.localFilePath().isDir() ? "/" : QString()))
|
<< (localFilePath + (file.localFilePath().isDir() ? "/" : QString()))
|
||||||
<< (cmdLine.remoteHostSpec + ':' + file.remoteFilePath());
|
<< (cmdLine.remoteHostSpec + ':' + file.remoteFilePath());
|
||||||
m_rsync.start("rsync", args); // TODO: Get rsync location from settings?
|
m_rsync.start("rsync", args); // TODO: Get rsync location from settings?
|
||||||
}
|
}
|
||||||
@@ -228,7 +239,7 @@ RsyncCommandLine RsyncDeployStep::rsyncCommand(const SshConnection &sshConnectio
|
|||||||
{
|
{
|
||||||
const QString sshCmdLine = QtcProcess::joinArgs(
|
const QString sshCmdLine = QtcProcess::joinArgs(
|
||||||
QStringList{SshSettings::sshFilePath().toUserOutput()}
|
QStringList{SshSettings::sshFilePath().toUserOutput()}
|
||||||
<< sshConnection.connectionOptions(SshSettings::sshFilePath()));
|
<< sshConnection.connectionOptions(SshSettings::sshFilePath()), OsTypeLinux);
|
||||||
const SshConnectionParameters sshParams = sshConnection.connectionParameters();
|
const SshConnectionParameters sshParams = sshConnection.connectionParameters();
|
||||||
return RsyncCommandLine(QStringList{"-e", sshCmdLine, flags},
|
return RsyncCommandLine(QStringList{"-e", sshCmdLine, flags},
|
||||||
sshParams.userName() + '@' + sshParams.host());
|
sshParams.userName() + '@' + sshParams.host());
|
||||||
|
@@ -4,6 +4,7 @@ add_qtc_plugin(StudioWelcome
|
|||||||
DEFINES STUDIO_QML_PATH="${CMAKE_CURRENT_SOURCE_DIR}/qml/"
|
DEFINES STUDIO_QML_PATH="${CMAKE_CURRENT_SOURCE_DIR}/qml/"
|
||||||
SOURCES
|
SOURCES
|
||||||
studiowelcomeplugin.cpp studiowelcomeplugin.h
|
studiowelcomeplugin.cpp studiowelcomeplugin.h
|
||||||
|
examplecheckout.cpp examplecheckout.h
|
||||||
studiowelcome_global.h
|
studiowelcome_global.h
|
||||||
studiowelcome.qrc
|
studiowelcome.qrc
|
||||||
"${PROJECT_SOURCE_DIR}/src/share/3rdparty/studiofonts/studiofonts.qrc"
|
"${PROJECT_SOURCE_DIR}/src/share/3rdparty/studiofonts/studiofonts.qrc"
|
||||||
|
347
src/plugins/studiowelcome/examplecheckout.cpp
Normal file
@@ -0,0 +1,347 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
#include "examplecheckout.h"
|
||||||
|
|
||||||
|
#include <coreplugin/documentmanager.h>
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
|
#include <utils/archive.h>
|
||||||
|
#include <utils/networkaccessmanager.h>
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QNetworkRequest>
|
||||||
|
#include <QQuickItem>
|
||||||
|
#include <QQuickWidget>
|
||||||
|
|
||||||
|
ExampleCheckout::ExampleCheckout(QObject *) {}
|
||||||
|
|
||||||
|
void ExampleCheckout::checkoutExample(const QUrl &url)
|
||||||
|
{
|
||||||
|
FileDownloader::registerQmlType();
|
||||||
|
static bool once = []() {
|
||||||
|
FileDownloader::registerQmlType();
|
||||||
|
FileExtractor::registerQmlType();
|
||||||
|
return true;
|
||||||
|
}();
|
||||||
|
|
||||||
|
QTC_ASSERT(once, ;);
|
||||||
|
|
||||||
|
m_dialog.reset(new QDialog(Core::ICore::dialogParent()));
|
||||||
|
m_dialog->setModal(true);
|
||||||
|
m_dialog->setFixedSize(620, 300);
|
||||||
|
QHBoxLayout *layout = new QHBoxLayout(m_dialog.get());
|
||||||
|
layout->setContentsMargins(2, 2, 2, 2);
|
||||||
|
|
||||||
|
auto widget = new QQuickWidget(m_dialog.get());
|
||||||
|
|
||||||
|
layout->addWidget(widget);
|
||||||
|
widget->engine()->addImportPath("qrc:/studiofonts");
|
||||||
|
|
||||||
|
widget->engine()->addImportPath(Core::ICore::resourcePath()
|
||||||
|
+ "/qmldesigner/propertyEditorQmlSources/imports");
|
||||||
|
|
||||||
|
widget->setSource(QUrl("qrc:/qml/downloaddialog/main.qml"));
|
||||||
|
|
||||||
|
m_dialog->setWindowFlag(Qt::Tool, true);
|
||||||
|
widget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||||
|
|
||||||
|
rootObject = widget->rootObject();
|
||||||
|
|
||||||
|
QTC_ASSERT(rootObject, qWarning() << "QML error"; return );
|
||||||
|
|
||||||
|
rootObject->setProperty("url", url);
|
||||||
|
|
||||||
|
m_dialog->show();
|
||||||
|
|
||||||
|
rootObject = widget->rootObject();
|
||||||
|
|
||||||
|
connect(rootObject, SIGNAL(canceled()), this, SLOT(handleCancel()));
|
||||||
|
connect(rootObject, SIGNAL(accepted()), this, SLOT(handleAccepted()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ExampleCheckout::extractionFolder() const
|
||||||
|
{
|
||||||
|
return m_extrationFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExampleCheckout::~ExampleCheckout() {}
|
||||||
|
|
||||||
|
void ExampleCheckout::handleCancel()
|
||||||
|
{
|
||||||
|
m_dialog->close();
|
||||||
|
m_dialog.release()->deleteLater();
|
||||||
|
deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExampleCheckout::handleAccepted()
|
||||||
|
{
|
||||||
|
QQmlProperty property(rootObject, "path");
|
||||||
|
m_extrationFolder = property.read().toString();
|
||||||
|
m_dialog->close();
|
||||||
|
emit finishedSucessfully();
|
||||||
|
m_dialog.release()->deleteLater();
|
||||||
|
deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileDownloader::registerQmlType()
|
||||||
|
{
|
||||||
|
qmlRegisterType<FileDownloader>("ExampleCheckout", 1, 0, "FileDownloader");
|
||||||
|
}
|
||||||
|
|
||||||
|
FileDownloader::FileDownloader(QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
FileDownloader::~FileDownloader()
|
||||||
|
{
|
||||||
|
m_tempFile.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileDownloader::start()
|
||||||
|
{
|
||||||
|
m_tempFile.setFileName(QDir::tempPath() + "/" + name() + ".XXXXXX" + ".zip");
|
||||||
|
|
||||||
|
m_tempFile.open(QIODevice::WriteOnly);
|
||||||
|
|
||||||
|
auto request = QNetworkRequest(m_url);
|
||||||
|
request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, true);
|
||||||
|
QNetworkReply *reply = Utils::NetworkAccessManager::instance()->get(request);
|
||||||
|
|
||||||
|
QNetworkReply::connect(reply, &QNetworkReply::readyRead, [this, reply]() {
|
||||||
|
m_tempFile.write(reply->readAll());
|
||||||
|
});
|
||||||
|
|
||||||
|
QNetworkReply::connect(reply,
|
||||||
|
&QNetworkReply::downloadProgress,
|
||||||
|
this,
|
||||||
|
[this](qint64 current, qint64 max) {
|
||||||
|
if (max == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_progress = current * 100 / max;
|
||||||
|
emit progressChanged();
|
||||||
|
});
|
||||||
|
|
||||||
|
QNetworkReply::connect(reply, &QNetworkReply::finished, [this, reply]() {
|
||||||
|
if (reply->error()) {
|
||||||
|
m_tempFile.remove();
|
||||||
|
if (m_url != reply->url()) {
|
||||||
|
m_url = reply->url();
|
||||||
|
start();
|
||||||
|
} else {
|
||||||
|
emit downloadFailed();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_tempFile.flush();
|
||||||
|
m_tempFile.close();
|
||||||
|
m_finished = true;
|
||||||
|
emit finishedChanged();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileDownloader::setUrl(const QUrl &url)
|
||||||
|
{
|
||||||
|
m_url = url;
|
||||||
|
|
||||||
|
emit nameChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl FileDownloader::url() const
|
||||||
|
{
|
||||||
|
return m_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileDownloader::finished() const
|
||||||
|
{
|
||||||
|
return m_finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileDownloader::error() const
|
||||||
|
{
|
||||||
|
return m_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FileDownloader::name() const
|
||||||
|
{
|
||||||
|
const QFileInfo fileInfo(m_url.path());
|
||||||
|
return fileInfo.baseName();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FileDownloader::completeBaseName() const
|
||||||
|
{
|
||||||
|
const QFileInfo fileInfo(m_url.path());
|
||||||
|
return fileInfo.completeBaseName();
|
||||||
|
}
|
||||||
|
|
||||||
|
int FileDownloader::progress() const
|
||||||
|
{
|
||||||
|
return m_progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FileDownloader::tempFile() const
|
||||||
|
{
|
||||||
|
return QFileInfo(m_tempFile).canonicalFilePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
FileExtractor::FileExtractor(QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
if (Core::DocumentManager::instance())
|
||||||
|
m_targetPath = Core::DocumentManager::projectsDirectory();
|
||||||
|
else
|
||||||
|
m_targetPath = Utils::FilePath::fromString("/temp/");
|
||||||
|
|
||||||
|
m_timer.setInterval(500);
|
||||||
|
m_timer.setSingleShot(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileExtractor::~FileExtractor() {}
|
||||||
|
|
||||||
|
void FileExtractor::registerQmlType()
|
||||||
|
{
|
||||||
|
qmlRegisterType<FileExtractor>("ExampleCheckout", 1, 0, "FileExtractor");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FileExtractor::targetPath() const
|
||||||
|
{
|
||||||
|
return m_targetPath.toUserOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileExtractor::browse()
|
||||||
|
{
|
||||||
|
const QString path = QFileDialog::getExistingDirectory(Core::ICore::dialogParent(),
|
||||||
|
(tr("Choose Directory")),
|
||||||
|
m_targetPath.toString());
|
||||||
|
|
||||||
|
if (!path.isEmpty())
|
||||||
|
m_targetPath = Utils::FilePath::fromString(path);
|
||||||
|
|
||||||
|
emit targetPathChanged();
|
||||||
|
emit targetFolderExistsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileExtractor::setSourceFile(QString &sourceFilePath)
|
||||||
|
{
|
||||||
|
m_sourceFile = Utils::FilePath::fromString(sourceFilePath);
|
||||||
|
emit targetFolderExistsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileExtractor::setArchiveName(QString &filePath)
|
||||||
|
{
|
||||||
|
m_archiveName = filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString FileExtractor::detailedText()
|
||||||
|
{
|
||||||
|
return m_detailedText;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileExtractor::finished() const
|
||||||
|
{
|
||||||
|
return m_finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FileExtractor::currentFile() const
|
||||||
|
{
|
||||||
|
return m_currentFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FileExtractor::size() const
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FileExtractor::count() const
|
||||||
|
{
|
||||||
|
return m_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileExtractor::targetFolderExists() const
|
||||||
|
{
|
||||||
|
const QString targetFolder = m_targetPath.toString() + "/" + m_archiveName;
|
||||||
|
return QFileInfo(targetFolder).exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FileExtractor::archiveName() const
|
||||||
|
{
|
||||||
|
return m_archiveName;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FileExtractor::sourceFile() const
|
||||||
|
{
|
||||||
|
return m_sourceFile.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileExtractor::extract()
|
||||||
|
{
|
||||||
|
Utils::Archive *archive = Utils::Archive::unarchive(m_sourceFile, m_targetPath);
|
||||||
|
archive->setParent(this);
|
||||||
|
QTC_ASSERT(archive, return );
|
||||||
|
|
||||||
|
m_timer.start();
|
||||||
|
const QString targetFolder = m_targetPath.toString() + "/" + m_archiveName;
|
||||||
|
qint64 bytesBefore = QStorageInfo(m_targetPath.toFileInfo().dir()).bytesAvailable();
|
||||||
|
|
||||||
|
QTimer::connect(&m_timer, &QTimer::timeout, [this, bytesBefore, targetFolder]() {
|
||||||
|
static QHash<QString, int> hash;
|
||||||
|
QDirIterator it(targetFolder, {"*.*"}, QDir::Files, QDirIterator::Subdirectories);
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
while (it.hasNext()) {
|
||||||
|
if (!hash.contains(it.fileName())) {
|
||||||
|
m_currentFile = it.fileName();
|
||||||
|
hash.insert(m_currentFile, 0);
|
||||||
|
emit currentFileChanged();
|
||||||
|
}
|
||||||
|
it.next();
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_size = QString::number(bytesBefore
|
||||||
|
- QStorageInfo(m_targetPath.toFileInfo().dir()).bytesAvailable());
|
||||||
|
|
||||||
|
m_count = QString::number(count);
|
||||||
|
emit sizeChanged();
|
||||||
|
});
|
||||||
|
|
||||||
|
QObject::connect(archive, &Utils::Archive::outputReceived, this, [this](const QString &output) {
|
||||||
|
m_detailedText += output;
|
||||||
|
emit detailedTextChanged();
|
||||||
|
});
|
||||||
|
|
||||||
|
QObject::connect(archive, &Utils::Archive::finished, [this](bool ret) {
|
||||||
|
m_finished = ret;
|
||||||
|
m_timer.stop();
|
||||||
|
emit finishedChanged();
|
||||||
|
QTC_ASSERT(ret, ;);
|
||||||
|
});
|
||||||
|
}
|
163
src/plugins/studiowelcome/examplecheckout.h
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <utils/fileutils.h>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QtQml>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QDialog;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
class ExampleCheckout : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ExampleCheckout(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
Q_INVOKABLE void checkoutExample(const QUrl &url);
|
||||||
|
|
||||||
|
QString extractionFolder() const;
|
||||||
|
|
||||||
|
~ExampleCheckout();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void handleCancel();
|
||||||
|
void handleAccepted();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finishedSucessfully();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<QDialog> m_dialog;
|
||||||
|
QObject *rootObject = nullptr;
|
||||||
|
QString m_extrationFolder;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FileExtractor : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(QString targetPath READ targetPath NOTIFY targetPathChanged)
|
||||||
|
Q_PROPERTY(QString archiveName READ archiveName WRITE setArchiveName)
|
||||||
|
Q_PROPERTY(QString detailedText READ detailedText NOTIFY detailedTextChanged)
|
||||||
|
Q_PROPERTY(QString currentFile READ currentFile NOTIFY currentFileChanged)
|
||||||
|
Q_PROPERTY(QString size READ size NOTIFY sizeChanged)
|
||||||
|
Q_PROPERTY(QString count READ count NOTIFY sizeChanged)
|
||||||
|
Q_PROPERTY(QString sourceFile READ sourceFile WRITE setSourceFile)
|
||||||
|
Q_PROPERTY(bool finished READ finished NOTIFY finishedChanged)
|
||||||
|
Q_PROPERTY(bool targetFolderExists READ targetFolderExists NOTIFY targetFolderExistsChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit FileExtractor(QObject *parent = nullptr);
|
||||||
|
~FileExtractor();
|
||||||
|
|
||||||
|
static void registerQmlType();
|
||||||
|
|
||||||
|
QString targetPath() const;
|
||||||
|
void setSourceFile(QString &sourceFilePath);
|
||||||
|
void setArchiveName(QString &filePath);
|
||||||
|
const QString detailedText();
|
||||||
|
bool finished() const;
|
||||||
|
QString currentFile() const;
|
||||||
|
QString size() const;
|
||||||
|
QString count() const;
|
||||||
|
bool targetFolderExists() const;
|
||||||
|
|
||||||
|
QString sourceFile() const;
|
||||||
|
QString archiveName() const;
|
||||||
|
|
||||||
|
Q_INVOKABLE void browse();
|
||||||
|
Q_INVOKABLE void extract();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void targetPathChanged();
|
||||||
|
void detailedTextChanged();
|
||||||
|
void finishedChanged();
|
||||||
|
void currentFileChanged();
|
||||||
|
void sizeChanged();
|
||||||
|
void targetFolderExistsChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Utils::FilePath m_targetPath;
|
||||||
|
Utils::FilePath m_sourceFile;
|
||||||
|
QString m_detailedText;
|
||||||
|
bool m_finished = false;
|
||||||
|
QTimer m_timer;
|
||||||
|
QString m_currentFile;
|
||||||
|
QString m_size;
|
||||||
|
QString m_count;
|
||||||
|
QString m_archiveName;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FileDownloader : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(QUrl url READ url WRITE setUrl)
|
||||||
|
Q_PROPERTY(bool finished READ finished NOTIFY finishedChanged)
|
||||||
|
Q_PROPERTY(bool error READ error NOTIFY errorChanged)
|
||||||
|
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
|
||||||
|
Q_PROPERTY(QString completeBaseName READ completeBaseName NOTIFY nameChanged)
|
||||||
|
Q_PROPERTY(int progress READ progress NOTIFY progressChanged)
|
||||||
|
Q_PROPERTY(QString tempFile READ tempFile NOTIFY finishedChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit FileDownloader(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
~FileDownloader();
|
||||||
|
|
||||||
|
void setUrl(const QUrl &url);
|
||||||
|
QUrl url() const;
|
||||||
|
bool finished() const;
|
||||||
|
bool error() const;
|
||||||
|
static void registerQmlType();
|
||||||
|
QString name() const;
|
||||||
|
QString completeBaseName() const;
|
||||||
|
int progress() const;
|
||||||
|
QString tempFile() const;
|
||||||
|
|
||||||
|
Q_INVOKABLE void start();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finishedChanged();
|
||||||
|
void errorChanged();
|
||||||
|
void nameChanged();
|
||||||
|
void progressChanged();
|
||||||
|
void downloadFailed();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QUrl m_url;
|
||||||
|
bool m_finished = false;
|
||||||
|
bool m_error = false;
|
||||||
|
int m_progress = 0;
|
||||||
|
QFile m_tempFile;
|
||||||
|
};
|
249
src/plugins/studiowelcome/qml/downloaddialog/ArcItem.qml
Normal file
@@ -0,0 +1,249 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.9
|
||||||
|
import QtQuick.Shapes 1.0
|
||||||
|
|
||||||
|
Shape {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
implicitWidth: 100
|
||||||
|
implicitHeight: 100
|
||||||
|
|
||||||
|
property alias gradient: path.fillGradient
|
||||||
|
property alias strokeStyle: path.strokeStyle
|
||||||
|
property alias strokeWidth: path.strokeWidth
|
||||||
|
property alias strokeColor: path.strokeColor
|
||||||
|
property alias dashPattern: path.dashPattern
|
||||||
|
property alias joinStyle: path.joinStyle
|
||||||
|
property alias fillColor: path.fillColor
|
||||||
|
property alias capStyle: path.capStyle
|
||||||
|
property alias dashOffset: path.dashOffset
|
||||||
|
|
||||||
|
property real begin: 0
|
||||||
|
property real end: 90
|
||||||
|
|
||||||
|
property real arcWidth: 10
|
||||||
|
|
||||||
|
property real arcWidthBegin: arcWidth
|
||||||
|
property real arcWidthEnd: arcWidth
|
||||||
|
|
||||||
|
property real radiusInnerAdjust: 0
|
||||||
|
property real radiusOuterAdjust: 0
|
||||||
|
|
||||||
|
property real alpha: clamp(sortedEnd() - sortedBegin(),0, 359.9)
|
||||||
|
|
||||||
|
layer.enabled: antialiasing
|
||||||
|
layer.smooth: antialiasing
|
||||||
|
layer.textureSize: Qt.size(width * 2, height * 2)
|
||||||
|
property bool outlineArc: false
|
||||||
|
|
||||||
|
property bool round: false
|
||||||
|
|
||||||
|
property bool roundEnd: round
|
||||||
|
property bool roundBegin: round
|
||||||
|
|
||||||
|
function clamp(num, min, max) {
|
||||||
|
return num <= min ? min : num >= max ? max : num;
|
||||||
|
}
|
||||||
|
|
||||||
|
function myCos(angleInDegrees) {
|
||||||
|
var angleInRadians = angleInDegrees * Math.PI / 180.0;
|
||||||
|
return Math.cos(angleInRadians)
|
||||||
|
}
|
||||||
|
|
||||||
|
function mySin(angleInDegrees) {
|
||||||
|
var angleInRadians = angleInDegrees * Math.PI / 180.0;
|
||||||
|
return Math.sin(angleInRadians)
|
||||||
|
}
|
||||||
|
|
||||||
|
function polarToCartesianX(centerX, centerY, radius, angleInDegrees) {
|
||||||
|
var angleInRadians = angleInDegrees * Math.PI / 180.0;
|
||||||
|
var x = centerX + radius * Math.cos(angleInRadians)
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
function polarToCartesianY(centerX, centerY, radius, angleInDegrees) {
|
||||||
|
var angleInRadians = angleInDegrees * Math.PI / 180.0;
|
||||||
|
var y = centerY + radius * Math.sin(angleInRadians);
|
||||||
|
return y
|
||||||
|
}
|
||||||
|
|
||||||
|
function calc()
|
||||||
|
{
|
||||||
|
path.__xRadius = root.width / 2 - root.strokeWidth / 2
|
||||||
|
path.__yRadius = root.height / 2 - root.strokeWidth / 2
|
||||||
|
|
||||||
|
path.__Xcenter = root.width / 2
|
||||||
|
path.__Ycenter = root.height / 2
|
||||||
|
|
||||||
|
path.startX = root.polarToCartesianX(path.__Xcenter, path.__Ycenter, path.__xRadius, root.sortedBegin() - 90) + root.__beginOff * myCos(root.sortedBegin() + 90)
|
||||||
|
path.startY = root.polarToCartesianY(path.__Xcenter, path.__Ycenter, path.__yRadius, root.sortedBegin() - 90) + root.__beginOff * mySin(root.sortedBegin() + 90)
|
||||||
|
|
||||||
|
arc1.x = root.polarToCartesianX(path.__Xcenter, path.__Ycenter, path.__xRadius, root.sortedEnd() - 90) + root.__endOff * myCos(root.sortedEnd() + 90)
|
||||||
|
arc1.y = root.polarToCartesianY(path.__Xcenter, path.__Ycenter, path.__yRadius, root.sortedEnd() - 90) + root.__endOff * mySin(root.sortedEnd() + 90)
|
||||||
|
|
||||||
|
arc1.radiusX = path.__xRadius - root.__endOff / 2 -root.__beginOff / 2 + root.radiusOuterAdjust
|
||||||
|
arc1.radiusY = path.__yRadius - root.__endOff / 2 -root.__beginOff / 2 + root.radiusOuterAdjust
|
||||||
|
|
||||||
|
arc1.useLargeArc = root.alpha > 180
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortedBegin()
|
||||||
|
{
|
||||||
|
return(Math.min(root.begin, root.end))
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortedEnd()
|
||||||
|
{
|
||||||
|
return(Math.max(root.begin, root.end))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onWidthChanged: calc()
|
||||||
|
onHeightChanged: calc()
|
||||||
|
onBeginChanged: calc()
|
||||||
|
onEndChanged: calc()
|
||||||
|
onAlphaChanged: calc()
|
||||||
|
|
||||||
|
ShapePath {
|
||||||
|
id: path
|
||||||
|
|
||||||
|
property real __xRadius
|
||||||
|
property real __yRadius
|
||||||
|
|
||||||
|
property real __Xcenter
|
||||||
|
property real __Ycenter
|
||||||
|
|
||||||
|
strokeColor: "red"
|
||||||
|
strokeWidth: 4
|
||||||
|
capStyle: ShapePath.FlatCap
|
||||||
|
}
|
||||||
|
|
||||||
|
property real __beginOff: {
|
||||||
|
|
||||||
|
if (root.arcWidthEnd > root.arcWidthBegin)
|
||||||
|
return (root.arcWidthEnd - root.arcWidthBegin) / 2
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
property real __endOff: {
|
||||||
|
|
||||||
|
if (root.arcWidthBegin > root.arcWidthEnd)
|
||||||
|
return (root.arcWidthBegin - root.arcWidthEnd) / 2
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
property real __startP: root.arcWidthBegin + __beginOff
|
||||||
|
property real __endP: root.arcWidthEnd + __endOff
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: shapes
|
||||||
|
PathArc {
|
||||||
|
id: arc1
|
||||||
|
property bool add: true
|
||||||
|
}
|
||||||
|
|
||||||
|
PathLine {
|
||||||
|
relativeX: root.arcWidthEnd * myCos(root.sortedEnd())
|
||||||
|
relativeY: root.arcWidthEnd * mySin(root.sortedEnd())
|
||||||
|
property bool add: !root.roundEnd && (root.outlineArc && root.alpha < 359.8)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
PathArc {
|
||||||
|
relativeX: root.arcWidthEnd * myCos(root.sortedEnd())
|
||||||
|
relativeY: root.arcWidthEnd * mySin(root.sortedEnd())
|
||||||
|
radiusX: root.arcWidthEnd /2
|
||||||
|
radiusY: root.arcWidthEnd /2
|
||||||
|
property bool add: root.roundEnd && (root.outlineArc && root.alpha < 359.8)
|
||||||
|
}
|
||||||
|
|
||||||
|
PathMove {
|
||||||
|
relativeX: root.arcWidthEnd * myCos(root.sortedEnd())
|
||||||
|
relativeY: root.arcWidthEnd * mySin(root.sortedEnd())
|
||||||
|
property bool add: root.outlineArc && root.alpha > 359.7
|
||||||
|
}
|
||||||
|
|
||||||
|
PathArc {
|
||||||
|
id: arc2
|
||||||
|
useLargeArc: arc1.useLargeArc
|
||||||
|
|
||||||
|
radiusX: path.__xRadius - root.arcWidthBegin + root.__beginOff / 2 + root.__endOff / 2 + root.radiusInnerAdjust
|
||||||
|
radiusY:path.__yRadius - root.arcWidthBegin + root.__beginOff / 2 + root.__endOff / 2 + root.radiusInnerAdjust
|
||||||
|
|
||||||
|
x: path.startX + root.arcWidthBegin * myCos(root.sortedBegin())
|
||||||
|
y: path.startY + root.arcWidthBegin * mySin(root.sortedBegin())
|
||||||
|
|
||||||
|
direction: PathArc.Counterclockwise
|
||||||
|
|
||||||
|
property bool add: root.outlineArc
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PathLine {
|
||||||
|
x: path.startX
|
||||||
|
y: path.startY
|
||||||
|
property bool add: !root.roundBegin && root.outlineArc && root.alpha < 359.8
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
PathArc {
|
||||||
|
x: path.startX
|
||||||
|
y: path.startY
|
||||||
|
radiusX: root.arcWidthEnd /2
|
||||||
|
radiusY: root.arcWidthEnd /2
|
||||||
|
property bool add: root.roundBegin && root.outlineArc && root.alpha < 359.8
|
||||||
|
}
|
||||||
|
|
||||||
|
PathMove {
|
||||||
|
x: path.startX
|
||||||
|
y: path.startY
|
||||||
|
property bool add: root.outlineArc && root.alpha == 360
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function invalidatePaths() {
|
||||||
|
if (!root.__completed)
|
||||||
|
return
|
||||||
|
|
||||||
|
for (var i = 0; i < shapes.resources.length; i++) {
|
||||||
|
var s = shapes.resources[i];
|
||||||
|
if (s.add)
|
||||||
|
path.pathElements.push(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
property bool __completed: false
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
root.__completed = true
|
||||||
|
invalidatePaths()
|
||||||
|
calc()
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,129 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.12
|
||||||
|
import QtQuick.Timeline 1.0
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle
|
||||||
|
width: 60
|
||||||
|
height: 60
|
||||||
|
color: "#8c8c8c"
|
||||||
|
radius: 50
|
||||||
|
property alias inputMax: rangeMapper.inputMax
|
||||||
|
property alias inputMin: rangeMapper.inputMin
|
||||||
|
property alias value: minMaxMapper.input
|
||||||
|
|
||||||
|
ArcItem {
|
||||||
|
id: arc
|
||||||
|
x: -1
|
||||||
|
y: -1
|
||||||
|
width: 62
|
||||||
|
height: 62
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
end: rangeMapper.value
|
||||||
|
antialiasing: true
|
||||||
|
strokeWidth: 8
|
||||||
|
strokeColor: "#ffffff"
|
||||||
|
capStyle: 32
|
||||||
|
fillColor: "#00000000"
|
||||||
|
}
|
||||||
|
|
||||||
|
RangeMapper {
|
||||||
|
id: rangeMapper
|
||||||
|
outputMax: 358
|
||||||
|
input: minMaxMapper.value
|
||||||
|
}
|
||||||
|
|
||||||
|
MinMaxMapper {
|
||||||
|
id: minMaxMapper
|
||||||
|
input: 95
|
||||||
|
max: rangeMapper.inputMax
|
||||||
|
min: rangeMapper.inputMin
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle1
|
||||||
|
width: 60
|
||||||
|
height: 60
|
||||||
|
color: "#ffffff"
|
||||||
|
radius: 40
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
scale: 1
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Timeline {
|
||||||
|
id: timeline
|
||||||
|
currentFrame: rangeMapper.value
|
||||||
|
enabled: true
|
||||||
|
endFrame: 360
|
||||||
|
startFrame: 0
|
||||||
|
|
||||||
|
KeyframeGroup {
|
||||||
|
target: rectangle1
|
||||||
|
property: "opacity"
|
||||||
|
Keyframe {
|
||||||
|
frame: 0
|
||||||
|
value: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Keyframe {
|
||||||
|
frame: 360
|
||||||
|
value: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyframeGroup {
|
||||||
|
target: rectangle1
|
||||||
|
property: "scale"
|
||||||
|
Keyframe {
|
||||||
|
frame: 360
|
||||||
|
value: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Keyframe {
|
||||||
|
frame: 0
|
||||||
|
value: 0.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyframeGroup {
|
||||||
|
target: arc
|
||||||
|
property: "opacity"
|
||||||
|
Keyframe {
|
||||||
|
value: 0
|
||||||
|
frame: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Keyframe {
|
||||||
|
value: 1
|
||||||
|
frame: 40
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,193 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.12
|
||||||
|
import QtQuick.Timeline 1.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: coolProgressBar
|
||||||
|
width: 605
|
||||||
|
height: 16
|
||||||
|
property alias value: timeline.currentFrame
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Timeline {
|
||||||
|
id: timeline
|
||||||
|
enabled: true
|
||||||
|
endFrame: 100
|
||||||
|
startFrame: 0
|
||||||
|
|
||||||
|
KeyframeGroup {
|
||||||
|
target: rectangle
|
||||||
|
property: "width"
|
||||||
|
Keyframe {
|
||||||
|
value: 0
|
||||||
|
frame: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Keyframe {
|
||||||
|
value: 150
|
||||||
|
frame: 25
|
||||||
|
}
|
||||||
|
|
||||||
|
Keyframe {
|
||||||
|
value: 300
|
||||||
|
frame: 50
|
||||||
|
}
|
||||||
|
|
||||||
|
Keyframe {
|
||||||
|
value: 450
|
||||||
|
frame: 75
|
||||||
|
}
|
||||||
|
|
||||||
|
Keyframe {
|
||||||
|
value: 600
|
||||||
|
frame: 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyframeGroup {
|
||||||
|
target: rectangle1
|
||||||
|
property: "width"
|
||||||
|
Keyframe {
|
||||||
|
value: 0
|
||||||
|
frame: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Keyframe {
|
||||||
|
value: 300
|
||||||
|
frame: 25
|
||||||
|
}
|
||||||
|
|
||||||
|
Keyframe {
|
||||||
|
value: 450
|
||||||
|
frame: 50
|
||||||
|
}
|
||||||
|
|
||||||
|
Keyframe {
|
||||||
|
value: 600
|
||||||
|
frame: 75
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyframeGroup {
|
||||||
|
target: rectangle2
|
||||||
|
property: "width"
|
||||||
|
Keyframe {
|
||||||
|
value: 0
|
||||||
|
frame: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Keyframe {
|
||||||
|
value: 450
|
||||||
|
frame: 25
|
||||||
|
}
|
||||||
|
|
||||||
|
Keyframe {
|
||||||
|
value: 600
|
||||||
|
frame: 50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyframeGroup {
|
||||||
|
target: rectangle3
|
||||||
|
property: "width"
|
||||||
|
Keyframe {
|
||||||
|
value: 0
|
||||||
|
frame: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Keyframe {
|
||||||
|
value: 600
|
||||||
|
frame: 25
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyframeGroup {
|
||||||
|
target: content
|
||||||
|
property: "opacity"
|
||||||
|
Keyframe {
|
||||||
|
value: 0
|
||||||
|
frame: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Keyframe {
|
||||||
|
value: 1
|
||||||
|
frame: 50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: content
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle
|
||||||
|
y: 0
|
||||||
|
width: 80
|
||||||
|
height: 16
|
||||||
|
color: "#ffffff"
|
||||||
|
radius: 12
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle1
|
||||||
|
y: 0
|
||||||
|
width: 80
|
||||||
|
height: 16
|
||||||
|
opacity: 0.6
|
||||||
|
color: "#ffffff"
|
||||||
|
radius: 12
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle2
|
||||||
|
y: 0
|
||||||
|
width: 80
|
||||||
|
height: 16
|
||||||
|
opacity: 0.4
|
||||||
|
color: "#ffffff"
|
||||||
|
radius: 12
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle3
|
||||||
|
y: 0
|
||||||
|
width: 80
|
||||||
|
height: 16
|
||||||
|
opacity: 0.2
|
||||||
|
color: "#ffffff"
|
||||||
|
radius: 12
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*##^##
|
||||||
|
Designer {
|
||||||
|
D{i:0;height:16;width:590}D{i:1}
|
||||||
|
}
|
||||||
|
##^##*/
|
@@ -0,0 +1,91 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.10
|
||||||
|
import QtQuick.Templates 2.1 as T
|
||||||
|
|
||||||
|
T.Button {
|
||||||
|
id: control
|
||||||
|
|
||||||
|
implicitWidth: Math.max(buttonBackground ? buttonBackground.implicitWidth : 0,
|
||||||
|
textItem.implicitWidth + leftPadding + rightPadding)
|
||||||
|
implicitHeight: Math.max(buttonBackground ? buttonBackground.implicitHeight : 0,
|
||||||
|
textItem.implicitHeight + topPadding + bottomPadding)
|
||||||
|
leftPadding: 4
|
||||||
|
rightPadding: 4
|
||||||
|
|
||||||
|
text: "My Button"
|
||||||
|
|
||||||
|
property color defaultColor: "#b9b9ba"
|
||||||
|
property color checkedColor: "#ffffff"
|
||||||
|
|
||||||
|
background: buttonBackground
|
||||||
|
Rectangle {
|
||||||
|
id: buttonBackground
|
||||||
|
color: control.defaultColor
|
||||||
|
implicitWidth: 100
|
||||||
|
implicitHeight: 40
|
||||||
|
opacity: enabled ? 1 : 0.3
|
||||||
|
radius: 0
|
||||||
|
border.width: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: textItem
|
||||||
|
Text {
|
||||||
|
id: textItem
|
||||||
|
text: control.text
|
||||||
|
|
||||||
|
opacity: enabled ? 1.0 : 0.3
|
||||||
|
color: "#bababa"
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "normal"
|
||||||
|
when: !control.down && !control.checked
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonBackground
|
||||||
|
color: "#2d2e30"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "down"
|
||||||
|
when: control.down || control.checked
|
||||||
|
PropertyChanges {
|
||||||
|
target: textItem
|
||||||
|
color: control.checkedColor
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonBackground
|
||||||
|
color: "#545456"
|
||||||
|
border.color: "#70a2f5"
|
||||||
|
border.width: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
37
src/plugins/studiowelcome/qml/downloaddialog/DialogLabel.qml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.0
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
|
||||||
|
import ExampleCheckout 1.0
|
||||||
|
import QtQuick.Layouts 1.11
|
||||||
|
|
||||||
|
import StudioFonts 1.0
|
||||||
|
|
||||||
|
Text {
|
||||||
|
font.family: StudioFonts.titilliumWeb_light
|
||||||
|
color: root.textColor
|
||||||
|
}
|
@@ -0,0 +1,54 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Quick Designer Components.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:GPL$
|
||||||
|
** 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 or (at your option) any later version
|
||||||
|
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||||
|
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.10
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: object
|
||||||
|
|
||||||
|
|
||||||
|
property real input
|
||||||
|
|
||||||
|
property bool minClipped: object.input < object.min
|
||||||
|
property bool maxClipped: object.input > object.max
|
||||||
|
property bool outOfRage: object.maxClipped ||object.minClipped
|
||||||
|
|
||||||
|
property real value: {
|
||||||
|
if (object.maxClipped)
|
||||||
|
return object.max
|
||||||
|
|
||||||
|
if (object.minClipped)
|
||||||
|
return object.min
|
||||||
|
|
||||||
|
return object.input
|
||||||
|
}
|
||||||
|
|
||||||
|
property real min: 0
|
||||||
|
property real max: 100
|
||||||
|
}
|
48
src/plugins/studiowelcome/qml/downloaddialog/RangeMapper.qml
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Quick Designer Components.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:GPL$
|
||||||
|
** 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 or (at your option) any later version
|
||||||
|
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||||
|
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.10
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: object
|
||||||
|
|
||||||
|
|
||||||
|
property real input
|
||||||
|
|
||||||
|
property real value: {
|
||||||
|
var slope = (object.outputMax - object.outputMin) / (object.inputMax - object.inputMin)
|
||||||
|
return object.outputMin + slope * (object.input - object.inputMin)
|
||||||
|
}
|
||||||
|
|
||||||
|
property real inputMin: 0
|
||||||
|
property real inputMax: 100
|
||||||
|
property real outputMin: 0
|
||||||
|
property real outputMax: 100
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,47 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2019 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 QmlProject 1.1
|
||||||
|
|
||||||
|
Project {
|
||||||
|
mainFile: "main.qml"
|
||||||
|
|
||||||
|
/* Include .qml, .js, and image files from current directory and subdirectories */
|
||||||
|
QmlFiles {
|
||||||
|
directory: "."
|
||||||
|
}
|
||||||
|
JavaScriptFiles {
|
||||||
|
directory: "."
|
||||||
|
}
|
||||||
|
ImageFiles {
|
||||||
|
directory: "."
|
||||||
|
}
|
||||||
|
/* List of plugin directories passed to QML runtime */
|
||||||
|
importPaths: [ "mockData", "../../../../share/3rdparty/studiofonts", "../../../../../share/qtcreator/qmldesigner/propertyEditorQmlSources/imports" ]
|
||||||
|
|
||||||
|
Environment {
|
||||||
|
QT_AUTO_SCREEN_SCALE_FACTOR: "1"
|
||||||
|
}
|
||||||
|
}
|
312
src/plugins/studiowelcome/qml/downloaddialog/main.qml
Normal file
@@ -0,0 +1,312 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.0
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
|
||||||
|
import ExampleCheckout 1.0
|
||||||
|
import QtQuick.Layouts 1.11
|
||||||
|
|
||||||
|
import StudioFonts 1.0
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
property alias url: downloader.url
|
||||||
|
property string path: fileExtractor.targetPath
|
||||||
|
width: 620
|
||||||
|
height: 300
|
||||||
|
|
||||||
|
color: "#2d2e30"
|
||||||
|
|
||||||
|
property color textColor: "#b9b9ba"
|
||||||
|
|
||||||
|
signal canceled
|
||||||
|
signal accepted
|
||||||
|
|
||||||
|
StackLayout {
|
||||||
|
id: stackLayout
|
||||||
|
anchors.fill: parent
|
||||||
|
currentIndex: 0
|
||||||
|
|
||||||
|
FileExtractor {
|
||||||
|
id: fileExtractor
|
||||||
|
sourceFile: downloader.tempFile
|
||||||
|
archiveName: downloader.completeBaseName
|
||||||
|
}
|
||||||
|
|
||||||
|
FileDownloader {
|
||||||
|
id: downloader
|
||||||
|
//onNameChanged: start()
|
||||||
|
onFinishedChanged: {
|
||||||
|
button.enabled = downloader.finished
|
||||||
|
if (!downloader.finished)
|
||||||
|
stackLayout.currentIndex = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
onDownloadFailed: stackLayout.currentIndex = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: download
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
DialogButton {
|
||||||
|
id: button
|
||||||
|
x: 532
|
||||||
|
y: 432
|
||||||
|
text: qsTr("Continue")
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: 20
|
||||||
|
anchors.rightMargin: 20
|
||||||
|
enabled: false
|
||||||
|
onClicked: stackLayout.currentIndex = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
CoolProgressBar {
|
||||||
|
id: coolProgressBar
|
||||||
|
width: 605
|
||||||
|
anchors.top: parent.top
|
||||||
|
value: downloader.progress
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.topMargin: 69
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogLabel {
|
||||||
|
x: 201
|
||||||
|
text: "Downloading Example " + downloader.completeBaseName
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 22
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogButton {
|
||||||
|
id: downloadbutton
|
||||||
|
y: 420
|
||||||
|
enabled: !button.enabled
|
||||||
|
text: qsTr("Start Download")
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.leftMargin: 20
|
||||||
|
anchors.bottomMargin: 20
|
||||||
|
onClicked: {
|
||||||
|
downloadbutton.enabled = false
|
||||||
|
downloader.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CircularIndicator {
|
||||||
|
id: circularIndicator
|
||||||
|
x: 304
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.horizontalCenterOffset: 0
|
||||||
|
value: downloader.progress
|
||||||
|
anchors.topMargin: 120
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: destiationfolder
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
DialogButton {
|
||||||
|
id: nextPageDestination
|
||||||
|
x: 532
|
||||||
|
y: 432
|
||||||
|
text: qsTr("Continue")
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
enabled: !fileExtractor.targetFolderExists
|
||||||
|
anchors.bottomMargin: 20
|
||||||
|
anchors.rightMargin: 20
|
||||||
|
onClicked: {
|
||||||
|
stackLayout.currentIndex = 2
|
||||||
|
fileExtractor.extract()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
y: 114
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 104
|
||||||
|
anchors.leftMargin: 67
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: textField
|
||||||
|
text: fileExtractor.targetPath
|
||||||
|
Layout.fillWidth: true
|
||||||
|
font.family: StudioFonts.titilliumWeb_light
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
selectByMouse: true
|
||||||
|
readOnly: true
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogButton {
|
||||||
|
id: browse
|
||||||
|
text: qsTr("Browse")
|
||||||
|
onClicked: fileExtractor.browse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogLabel {
|
||||||
|
id: label
|
||||||
|
y: 436
|
||||||
|
text: qsTr("Folder ") + downloader.completeBaseName + (" already exists")
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.leftMargin: 20
|
||||||
|
anchors.bottomMargin: 20
|
||||||
|
visible: !nextPageDestination.enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogButton {
|
||||||
|
id: button5
|
||||||
|
x: 400
|
||||||
|
y: 420
|
||||||
|
text: qsTr("Cancel")
|
||||||
|
anchors.right: nextPageDestination.left
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: 20
|
||||||
|
anchors.rightMargin: 20
|
||||||
|
onClicked: root.canceled()
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogLabel {
|
||||||
|
text: "Choose installation folder"
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 22
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
x: 8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: extraction
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
|
||||||
|
DialogButton {
|
||||||
|
id: done
|
||||||
|
x: 532
|
||||||
|
y: 432
|
||||||
|
text: qsTr("Open")
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: 20
|
||||||
|
anchors.rightMargin: 20
|
||||||
|
enabled: fileExtractor.finished
|
||||||
|
onClicked: root.accepted()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DialogLabel {
|
||||||
|
id: text2
|
||||||
|
text: fileExtractor.count + " files " + (fileExtractor.size / 1024 / 1024).toFixed(2) + " MB "+ fileExtractor.currentFile
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
font.pixelSize: 12
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
anchors.leftMargin: 20
|
||||||
|
anchors.bottomMargin: 20
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DialogButton {
|
||||||
|
id: details
|
||||||
|
x: 8
|
||||||
|
text: qsTr("Details")
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 66
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
checkable: true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DialogLabel {
|
||||||
|
x: 8
|
||||||
|
text: "Extracting Example " + downloader.completeBaseName
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 22
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Flickable {
|
||||||
|
visible: details.checked
|
||||||
|
clip: true
|
||||||
|
anchors.bottomMargin: 60
|
||||||
|
anchors.rightMargin: 20
|
||||||
|
anchors.leftMargin: 20
|
||||||
|
anchors.topMargin: 120
|
||||||
|
anchors.fill: parent
|
||||||
|
id: flickable
|
||||||
|
interactive: false
|
||||||
|
|
||||||
|
DialogLabel {
|
||||||
|
onHeightChanged: flickable.contentY = text1.implicitHeight - flickable.height
|
||||||
|
id: text1
|
||||||
|
|
||||||
|
text: fileExtractor.detailedText
|
||||||
|
|
||||||
|
font.pixelSize: 12
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
|
||||||
|
width: flickable.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: failed
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
DialogButton {
|
||||||
|
id: finish
|
||||||
|
x: 532
|
||||||
|
y: 432
|
||||||
|
text: qsTr("Finish")
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: 20
|
||||||
|
anchors.rightMargin: 20
|
||||||
|
onClicked: root.canceled()
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogLabel {
|
||||||
|
x: 8
|
||||||
|
text: qsTr("Download failed")
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 22
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,59 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
signal downloadFailed
|
||||||
|
|
||||||
|
property bool finished: false
|
||||||
|
|
||||||
|
property bool url
|
||||||
|
|
||||||
|
property int progress: 55
|
||||||
|
Behavior on progress { PropertyAnimation {
|
||||||
|
duration: 2000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function start() {
|
||||||
|
timer.start()
|
||||||
|
root.progress = 100
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
property Timer timer: Timer {
|
||||||
|
interval: 2000
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
root.finished
|
||||||
|
root.progress = 1000
|
||||||
|
finished = true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,41 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
signal finished
|
||||||
|
|
||||||
|
property string sourceFile: "SomeExample.zip"
|
||||||
|
property string archiveName: "SomeExample"
|
||||||
|
|
||||||
|
property string targetPath: "/extract/here"
|
||||||
|
|
||||||
|
property string detailedText: "Start" +
|
||||||
|
"\n1 Some detailed info about extraction\nSome detailed info about extraction\nSome detailed info about extractionSome detailed info about extractionSome detailed info about extraction" +
|
||||||
|
"\n2 Some detailed info about extraction\nSome detailed info about extraction\nSome detailed info about extractionSome detailed info about extractionSome detailed info about extraction" +
|
||||||
|
"\n3 Some detailed info about extraction\nSome detailed info about extraction\nSome detailed info about extractionSome detailed info about extractionSome detailed info about extraction" +
|
||||||
|
"\nend"
|
||||||
|
}
|
@@ -0,0 +1,2 @@
|
|||||||
|
FileDownloader 1.0 FileDownloader.qml
|
||||||
|
FileExtractor 1.0 FileExtractor.qml
|
@@ -74,4 +74,13 @@ ListModel {
|
|||||||
thumbnail: "images/washingmachinedemo_thumbnail.png"
|
thumbnail: "images/washingmachinedemo_thumbnail.png"
|
||||||
displayName: "Washing Machine"
|
displayName: "Washing Machine"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ListElement {
|
||||||
|
projectName: "highendivisystem"
|
||||||
|
qmlFileName: "Screen01.ui.qml"
|
||||||
|
thumbnail: "images/highendivi_thumbnail.png"
|
||||||
|
displayName: "Highend IVI System"
|
||||||
|
url: "https://download.qt.io/learning/examples/qtdesignstudio/highendivisystem.zip"
|
||||||
|
showDownload: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -35,6 +35,8 @@ Item {
|
|||||||
property alias imageSource: image.source
|
property alias imageSource: image.source
|
||||||
property alias labelText: label.text
|
property alias labelText: label.text
|
||||||
|
|
||||||
|
property alias downloadIcon: downloadCloud.visible
|
||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
animateOpacity.start()
|
animateOpacity.start()
|
||||||
animateScale.start()
|
animateScale.start()
|
||||||
@@ -89,6 +91,19 @@ Item {
|
|||||||
rectangle.color = "#262728"
|
rectangle.color = "#262728"
|
||||||
label.color = "#686868"
|
label.color = "#686868"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: downloadCloud
|
||||||
|
x: 210
|
||||||
|
y: 118
|
||||||
|
width: 60
|
||||||
|
height: 60
|
||||||
|
source: "images/downloadCloud.svg"
|
||||||
|
sourceSize.height: 60
|
||||||
|
sourceSize.width: 60
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,3 +202,9 @@ Item {
|
|||||||
font.family: StudioFonts.titilliumWeb_regular
|
font.family: StudioFonts.titilliumWeb_regular
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*##^##
|
||||||
|
Designer {
|
||||||
|
D{i:0;formeditorZoom:1.3300000429153442}D{i:8}
|
||||||
|
}
|
||||||
|
##^##*/
|
||||||
|
@@ -39,6 +39,7 @@ GridView {
|
|||||||
id: hoverOverDesaturate
|
id: hoverOverDesaturate
|
||||||
imageSource: typeof(thumbnail) === "undefined" ? "images/thumbnail_test.png" : thumbnail;
|
imageSource: typeof(thumbnail) === "undefined" ? "images/thumbnail_test.png" : thumbnail;
|
||||||
labelText: displayName
|
labelText: displayName
|
||||||
|
downloadIcon: typeof(showDownload) === "undefined" ? false : showDownload;
|
||||||
|
|
||||||
SequentialAnimation {
|
SequentialAnimation {
|
||||||
id: animation
|
id: animation
|
||||||
|
@@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<svg version="1.1" baseProfile="tiny" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
x="0px" y="0px" viewBox="0 0 128 128" overflow="visible" xml:space="preserve">
|
||||||
|
<g transform="translate(0.000000,2000.000000) scale(0.100000,-0.100000)">
|
||||||
|
<path fill="#686868" d="M764,19815.1c-12.5-0.6-28.9-2.1-38.4-3.5c-30-4.3-73-22.5-107.4-45.4c-19.9-13.2-34.6-25.2-51.1-41.6
|
||||||
|
c-18.6-18.6-30.1-33.4-43.2-55.8l-5.8-9.9l-6.7,3.2c-44.8,21.1-105.6,27.1-154.5,15.3c-35.4-8.5-75.1-30-104.5-56.5
|
||||||
|
c-3.4-3.1-6.8-6-7.5-6.5c-2.2-1.6-17.1-17.9-22.3-24.5c-7.4-9.3-16.5-23.4-21.7-33.8c-13.5-26.7-25.2-66.5-26.7-91l-0.4-7
|
||||||
|
l-15.9-7.9c-26.7-13.3-44.8-26.6-66.8-49.2c-18.9-19.3-31.4-36.4-41.9-57c-22.4-44.3-29.9-95.3-20.8-142.8
|
||||||
|
c8.4-44.1,29.1-83.5,61.5-117.1c35.2-36.5,62.1-52.4,108.2-64c24-6,47.3-7.8,115.4-8.9c12.4-0.2,29.7-0.4,38.4-0.6
|
||||||
|
c78.9-1.6,573.8-2.5,615.8-1.1c54,1.7,79,3.6,101.9,7.4c21.4,3.6,36.6,8.4,59.7,18.8c31.7,14.3,49.3,26.2,71,48
|
||||||
|
c22.6,22.7,38,46.4,49.6,76.8c14.6,38.2,19.8,83.7,13.7,121.3c-5.2,31.9-19.8,67.7-38.7,94.4c-10.5,14.7-28.8,34.7-42.7,46.2
|
||||||
|
c-28.8,24.1-58.1,39.7-90.8,48.4c-7.5,2-9.1,2.7-9.1,3.6c0,0.6,0.8,6.8,1.7,13.7c1.6,11.5,1.7,14.2,1.7,32.8
|
||||||
|
c0,21.9-0.9,31.7-4.4,49.8c-9.2,46.3-30,91.8-59.8,130.6c-21.3,27.8-49.5,53.4-77,69.9c-31.4,18.8-83.2,39.1-108.8,42.6
|
||||||
|
C819.9,19815.7,790.2,19816.3,764,19815.1z M828,19778.4c13-1.8,27.2-6.1,48.6-14.6c24-9.6,42.8-19,56.8-28.3
|
||||||
|
c57.9-38.7,101.4-106.8,113.6-178c3.9-22.6,4.1-43.6,0.6-69.7c-1.1-8.4-2.2-19-2.3-23.5c-0.3-7.6-0.3-8.5,1.1-11.6
|
||||||
|
c0.9-2.1,2.6-4.4,4.6-6.1c3.6-3.2,4.9-3.7,23.6-8.6c19.7-5.2,28.8-8.4,42.2-15.2c32.3-16.2,62.4-42.8,82-72.5
|
||||||
|
c14.5-22,26.1-52.4,29.9-78.6c0.8-5.6,1.1-11.6,1.1-22.8c-0.1-55-19.5-104.3-55.1-140.1c-18.5-18.6-39.9-32.1-71-44.9
|
||||||
|
c-32.4-13.4-63.1-16.9-162.9-18.8c-36.3-0.7-402.6-0.4-440.8,0.4c-8.2,0.2-43.7,0.4-78.9,0.6c-93.9,0.5-151.4,1.6-178.1,3.5
|
||||||
|
c-14.9,1.1-24.2,2.5-36.8,5.7c-39,9.9-59.1,21.9-89.9,53.6c-26,26.7-44.1,60-51.4,94.6c-8.9,42.1-3.2,84.4,16.8,124.7
|
||||||
|
c11.5,23.2,33.3,48.7,58.8,69c10.2,8.2,20.3,14.4,34.3,21.2c21.2,10.4,27.7,15.3,32,24.5c2.4,5,3.5,10.5,3.5,17.2
|
||||||
|
c0,12.4,5.9,37,14,59.1c4.4,11.9,12.1,27.5,18.3,36.7c18.9,28.3,49.9,55,83.7,71.9c29.5,14.8,54.5,20.2,89.4,19.4
|
||||||
|
c15-0.3,24.8-1.4,38-4c18.7-3.7,30.7-8,51.1-18.1c17-8.6,19.2-9.1,25.8-7.2c6.1,1.8,8.7,4.9,18.6,22.2c10.8,19,14.4,24.8,20.7,33.2
|
||||||
|
c28.7,38.1,74.9,72.8,121.8,91.3c23.8,9.4,36.1,12.1,62.8,13.9c5.6,0.4,11.6,0.8,13.3,0.9C774.9,19779.8,823.3,19779.1,828,19778.4
|
||||||
|
z"/>
|
||||||
|
</g>
|
||||||
|
<path fill="#686868" d="M82.4,65.7L70.2,78.7c0,0-0.1,0-0.1,0l0-33.5c0-1.6-1.2-3.1-2.9-3.2c-1.7-0.1-3.1,1.3-3.1,3v33.7c0,0,0,0-0.1,0L52,65.7
|
||||||
|
c-0.9-1-2.5-1.1-3.6-0.1h0c-1,0.9-1.1,2.5-0.1,3.6l16.7,18c1.2,1.3,3.2,1.3,4.3,0l16.7-18c0.9-1,0.9-2.6-0.1-3.6h0
|
||||||
|
C84.9,64.6,83.3,64.6,82.4,65.7z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 47 KiB |
@@ -60,7 +60,7 @@ Item {
|
|||||||
ScrollView {
|
ScrollView {
|
||||||
ProjectsGrid {
|
ProjectsGrid {
|
||||||
model: ExamplesModel {}
|
model: ExamplesModel {}
|
||||||
onItemSelected: projectModel.openExample(item.projectName, item.qmlFileName)
|
onItemSelected: projectModel.openExample(item.projectName, item.qmlFileName, item.url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|