Merge remote-tracking branch 'origin/4.14'
Change-Id: I70504e096be620434f38cd990c593950da8b24ba
@@ -37,35 +37,36 @@ if (APPLE)
|
|||||||
|
|
||||||
set(_IDE_OUTPUT_PATH "${_IDE_APP_PATH}/${_IDE_APP_TARGET}.app/Contents")
|
set(_IDE_OUTPUT_PATH "${_IDE_APP_PATH}/${_IDE_APP_TARGET}.app/Contents")
|
||||||
|
|
||||||
set(_IDE_PLUGIN_PATH "${_IDE_OUTPUT_PATH}/PlugIns")
|
|
||||||
set(_IDE_LIBRARY_BASE_PATH "Frameworks")
|
set(_IDE_LIBRARY_BASE_PATH "Frameworks")
|
||||||
set(_IDE_LIBRARY_PATH "${_IDE_OUTPUT_PATH}/Frameworks")
|
set(_IDE_LIBRARY_PATH "${_IDE_OUTPUT_PATH}/${_IDE_LIBRARY_BASE_PATH}")
|
||||||
|
set(_IDE_PLUGIN_PATH "${_IDE_OUTPUT_PATH}/PlugIns")
|
||||||
set(_IDE_LIBEXEC_PATH "${_IDE_OUTPUT_PATH}/Resources/libexec")
|
set(_IDE_LIBEXEC_PATH "${_IDE_OUTPUT_PATH}/Resources/libexec")
|
||||||
set(_IDE_DATA_PATH "${_IDE_OUTPUT_PATH}/Resources")
|
set(_IDE_DATA_PATH "${_IDE_OUTPUT_PATH}/Resources")
|
||||||
set(_IDE_DOC_PATH "${_IDE_OUTPUT_PATH}/Resources/doc")
|
set(_IDE_DOC_PATH "${_IDE_OUTPUT_PATH}/Resources/doc")
|
||||||
set(_IDE_BIN_PATH "${_IDE_OUTPUT_PATH}/MacOS")
|
set(_IDE_BIN_PATH "${_IDE_OUTPUT_PATH}/MacOS")
|
||||||
|
elseif(WIN32)
|
||||||
set(QT_DEST_PLUGIN_PATH "${_IDE_PLUGIN_PATH}")
|
|
||||||
set(QT_DEST_QML_PATH "${_IDE_DATA_PATH}/../Imports/qtquick2")
|
|
||||||
else ()
|
|
||||||
set(_IDE_APP_PATH "bin")
|
set(_IDE_APP_PATH "bin")
|
||||||
set(_IDE_APP_TARGET "${IDE_ID}")
|
set(_IDE_APP_TARGET "${IDE_ID}")
|
||||||
|
|
||||||
set(_IDE_LIBRARY_BASE_PATH "lib")
|
set(_IDE_LIBRARY_BASE_PATH "lib")
|
||||||
set(_IDE_LIBRARY_PATH "lib/qtcreator")
|
set(_IDE_LIBRARY_PATH "${_IDE_LIBRARY_BASE_PATH}/qtcreator")
|
||||||
set(_IDE_PLUGIN_PATH "lib/qtcreator/plugins")
|
set(_IDE_PLUGIN_PATH "${_IDE_LIBRARY_BASE_PATH}/qtcreator/plugins")
|
||||||
if (WIN32)
|
|
||||||
set(_IDE_LIBEXEC_PATH "bin")
|
set(_IDE_LIBEXEC_PATH "bin")
|
||||||
set(QT_DEST_PLUGIN_PATH "bin/plugins")
|
|
||||||
set(QT_DEST_QML_PATH "bin/qml")
|
|
||||||
else ()
|
|
||||||
set(_IDE_LIBEXEC_PATH "libexec/qtcreator")
|
|
||||||
set(QT_DEST_PLUGIN_PATH "lib/Qt/plugins")
|
|
||||||
set(QT_DEST_QML_PATH "lib/Qt/qml")
|
|
||||||
endif ()
|
|
||||||
set(_IDE_DATA_PATH "share/qtcreator")
|
set(_IDE_DATA_PATH "share/qtcreator")
|
||||||
set(_IDE_DOC_PATH "share/doc/qtcreator")
|
set(_IDE_DOC_PATH "share/doc/qtcreator")
|
||||||
set(_IDE_BIN_PATH "bin")
|
set(_IDE_BIN_PATH "bin")
|
||||||
|
else ()
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
set(_IDE_APP_PATH "${CMAKE_INSTALL_BINDIR}")
|
||||||
|
set(_IDE_APP_TARGET "${IDE_ID}")
|
||||||
|
|
||||||
|
set(_IDE_LIBRARY_BASE_PATH "${CMAKE_INSTALL_LIBDIR}")
|
||||||
|
set(_IDE_LIBRARY_PATH "${_IDE_LIBRARY_BASE_PATH}/qtcreator")
|
||||||
|
set(_IDE_PLUGIN_PATH "${_IDE_LIBRARY_BASE_PATH}/qtcreator/plugins")
|
||||||
|
set(_IDE_LIBEXEC_PATH "${CMAKE_INSTALL_LIBEXECDIR}/qtcreator")
|
||||||
|
set(_IDE_DATA_PATH "${CMAKE_INSTALL_DATAROOTDIR}/qtcreator")
|
||||||
|
set(_IDE_DOC_PATH "${CMAKE_INSTALL_DATAROOTDIR}/doc/qtcreator")
|
||||||
|
set(_IDE_BIN_PATH "${CMAKE_INSTALL_BINDIR}")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
file(RELATIVE_PATH _PLUGIN_TO_LIB "/${_IDE_PLUGIN_PATH}" "/${_IDE_LIBRARY_PATH}")
|
file(RELATIVE_PATH _PLUGIN_TO_LIB "/${_IDE_PLUGIN_PATH}" "/${_IDE_LIBRARY_PATH}")
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 11 KiB |
@@ -166,7 +166,7 @@
|
|||||||
system to the Clang code model for displaying annotations in the
|
system to the Clang code model for displaying annotations in the
|
||||||
code editor.
|
code editor.
|
||||||
|
|
||||||
\image qtcreator-diagnostics-configuration.png "Diagnostics Configuration dialog"
|
\image qtcreator-clang-tools-diagnostics-configuration.png "Diagnostics Configuration dialog"
|
||||||
|
|
||||||
\li In the \uicontrol {Clang-Tidy Checks} tab, select
|
\li In the \uicontrol {Clang-Tidy Checks} tab, select
|
||||||
\uicontrol {Select Checks} to select the checks to perform.
|
\uicontrol {Select Checks} to select the checks to perform.
|
||||||
|
|||||||
@@ -138,7 +138,10 @@
|
|||||||
edit the value for the \uicontrol {Do not index files greater than}
|
edit the value for the \uicontrol {Do not index files greater than}
|
||||||
check box. To index all files, deselect the check box.
|
check box. To index all files, deselect the check box.
|
||||||
|
|
||||||
\li Select \uicontrol Manage to specify the Clang checks to perform.
|
\li The \uicontrol {Diagnostic Configuration} field shows the Clang
|
||||||
|
checks to perform. Click the value of the field to open the
|
||||||
|
\uicontrol {Diagnostic Configurations} dialog, where you can
|
||||||
|
select and edit the checks to perform.
|
||||||
|
|
||||||
\image qtcreator-diagnostics-configuration.png
|
\image qtcreator-diagnostics-configuration.png
|
||||||
|
|
||||||
@@ -146,26 +149,18 @@
|
|||||||
|
|
||||||
\section1 Clang Checks
|
\section1 Clang Checks
|
||||||
|
|
||||||
The predefined configurations perform the following Clang checks:
|
In addition to using the built-in checks, you can select \uicontrol Copy to
|
||||||
|
create copies of them and edit the copies to fit your needs.
|
||||||
|
|
||||||
\list
|
\uicontrol {Build-system warnings} displays warnings as specified
|
||||||
|
by the build system.
|
||||||
|
|
||||||
\li \uicontrol {Clang-only pedantic checks} uses the \c -Wpendantic
|
\uicontrol {Checks for questionable constructs} combines the \c -Wall and
|
||||||
option that performs checks as required by strict ISO C and ISO C++.
|
\c -Wextra checks for easily avoidable questionable constructions and some
|
||||||
|
additional issues.
|
||||||
|
|
||||||
\li \uicontrol {Clang-only checks for questionable constructs} combines
|
Clang checks begin with \c -W. Each check also has a negative version that
|
||||||
the \c -Wall and \c -Wextra checks for easily avoidable questionable
|
begins with \c -Wno.
|
||||||
constructions and some additional issues.
|
|
||||||
|
|
||||||
\li \uicontrol {Clang-only checks for almost everything} uses the
|
|
||||||
\c -Weverything option with negative options to suppress some
|
|
||||||
warnings.
|
|
||||||
|
|
||||||
\endlist
|
|
||||||
|
|
||||||
You can edit the predefined configurations to perform particular checks
|
|
||||||
beginning with \c -W. Each of these checks also has a negative version
|
|
||||||
that begins with \c -Wno.
|
|
||||||
|
|
||||||
Keep in mind that some options turn on other options. For more information,
|
Keep in mind that some options turn on other options. For more information,
|
||||||
see \l{https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html}
|
see \l{https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html}
|
||||||
|
|||||||
@@ -293,6 +293,13 @@
|
|||||||
|
|
||||||
\image qtquickcontrols2-button-flat.gif "Flat button"
|
\image qtquickcontrols2-button-flat.gif "Flat button"
|
||||||
|
|
||||||
|
\if definded(qtdesignstudio)
|
||||||
|
To create a button that contains an icon, use the wizard template to
|
||||||
|
\l{Creating Custom Controls}{create a custom button} and drag-and-drop
|
||||||
|
the icon to the button background item. For an example of using the
|
||||||
|
wizard template, see \l{Creating a Push Button}.
|
||||||
|
\endif
|
||||||
|
|
||||||
\section2 Delay Button
|
\section2 Delay Button
|
||||||
|
|
||||||
\image qtquickcontrols2-delaybutton.gif "Delay button"
|
\image qtquickcontrols2-delaybutton.gif "Delay button"
|
||||||
|
|||||||
@@ -125,6 +125,7 @@
|
|||||||
\li \l {Lists and Other Data Models}
|
\li \l {Lists and Other Data Models}
|
||||||
\if defined(qtdesignstudio)
|
\if defined(qtdesignstudio)
|
||||||
\li \l {2D Effects}
|
\li \l {2D Effects}
|
||||||
|
\li \l {Logic Helpers}
|
||||||
\endif
|
\endif
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
|
|||||||
BIN
doc/qtdesignstudio/images/icons/lc-and-operator-16px.png
Normal file
|
After Width: | Height: | Size: 238 B |
|
After Width: | Height: | Size: 241 B |
BIN
doc/qtdesignstudio/images/icons/lc-min-max-16px.png
Normal file
|
After Width: | Height: | Size: 291 B |
BIN
doc/qtdesignstudio/images/icons/lc-not-operator-16px.png
Normal file
|
After Width: | Height: | Size: 257 B |
BIN
doc/qtdesignstudio/images/icons/lc-or-operator-16px.png
Normal file
|
After Width: | Height: | Size: 351 B |
BIN
doc/qtdesignstudio/images/icons/lc-range-mapper-16px.png
Normal file
|
After Width: | Height: | Size: 163 B |
BIN
doc/qtdesignstudio/images/icons/lc-string-mapper-16px.png
Normal file
|
After Width: | Height: | Size: 149 B |
BIN
doc/qtdesignstudio/images/studio-bidirectional-binding.gif
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
doc/qtdesignstudio/images/studio-logic-helper-and-checkbox3.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 107 KiB |
BIN
doc/qtdesignstudio/images/studio-logic-helper-and-operator.gif
Normal file
|
After Width: | Height: | Size: 99 KiB |
BIN
doc/qtdesignstudio/images/studio-logic-helper-and.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 17 KiB |
BIN
doc/qtdesignstudio/images/studio-logic-helper-minmax-mapper.gif
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
doc/qtdesignstudio/images/studio-logic-helper-not-check-box.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
doc/qtdesignstudio/images/studio-logic-helper-not-operator.gif
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
doc/qtdesignstudio/images/studio-logic-helper-not.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 16 KiB |
BIN
doc/qtdesignstudio/images/studio-logic-helper-range-mapper.gif
Normal file
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 18 KiB |
BIN
doc/qtdesignstudio/images/studio-logic-helper-string-mapper.gif
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
doc/qtdesignstudio/images/studio-logic-helpers.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
@@ -92,6 +92,7 @@
|
|||||||
\li \l{User Interaction Methods}
|
\li \l{User Interaction Methods}
|
||||||
\li \l{Lists and Other Data Models}
|
\li \l{Lists and Other Data Models}
|
||||||
\li \l{2D Effects}
|
\li \l{2D Effects}
|
||||||
|
\li \l{Logic Helpers}
|
||||||
\li \l{Creating Buttons}
|
\li \l{Creating Buttons}
|
||||||
\li \l{Creating Scalable Buttons and Borders}
|
\li \l{Creating Scalable Buttons and Borders}
|
||||||
\endlist
|
\endlist
|
||||||
|
|||||||
@@ -0,0 +1,300 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Design Studio documentation.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Free Documentation License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Free
|
||||||
|
** Documentation License version 1.3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file included in the packaging of
|
||||||
|
** this file. Please review the following information to ensure
|
||||||
|
** the GNU Free Documentation License version 1.3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\page quick-logic-helpers.html
|
||||||
|
\previouspage quick-2d-effects.html
|
||||||
|
\nextpage quick-buttons.html
|
||||||
|
|
||||||
|
\title Logic Helpers
|
||||||
|
|
||||||
|
To have your UI perform certain operations, you might need to write
|
||||||
|
JavaScript expressions for conditions or convert numbers to strings.
|
||||||
|
\QDS attempts to make this easier by providing a set of components
|
||||||
|
called \e {Qt Quick Studio Logic Helpers} that you can import to your
|
||||||
|
project to make them available in the \uicontrol Library view.
|
||||||
|
|
||||||
|
\image studio-logic-helpers.png "Logic Helper types in Library"
|
||||||
|
|
||||||
|
Logic helpers are available for binding property values using the boolean
|
||||||
|
AND, NOT, and OR operators, as well as for mapping numbers and numerical
|
||||||
|
ranges. In addition, you can synchronize the property values of two
|
||||||
|
components bi-directionally.
|
||||||
|
|
||||||
|
Logic helpers are invisible types that you can use in connection with
|
||||||
|
Qt Quick Controls, such as a \l {slider-control}{Slider} or \l {Check Box}.
|
||||||
|
To use a logic helper, drag-and-drop it from \uicontrol Library >
|
||||||
|
\uicontrol {Studio Logic Helper} to \uicontrol Navigator. The following
|
||||||
|
sections describe the different types of logic helpers in more detail.
|
||||||
|
|
||||||
|
\section1 Boolean Helpers
|
||||||
|
|
||||||
|
You can use logic helpers to bind property values using the boolean AND, OR,
|
||||||
|
and NOT operators.
|
||||||
|
|
||||||
|
\section2 AND Operator
|
||||||
|
|
||||||
|
The \uicontrol {And Operator} type evaluates two boolean inputs.
|
||||||
|
The output is evaluated as \c true if both inputs are \c true.
|
||||||
|
|
||||||
|
For example, we could use the checked state of two check boxes to determine
|
||||||
|
the checked state of a third one. First we drag-and-drop three
|
||||||
|
\uicontrol {Check Box} types and an \uicontrol {And Operator} to
|
||||||
|
\uicontrol Navigator (1). Then we select the \uicontrol {And Operator}
|
||||||
|
component (2) and set its properties in \uicontrol Properties (3).
|
||||||
|
|
||||||
|
We select \inlineimage icons/action-icon.png
|
||||||
|
next to the \uicontrol Input01 field to display the \uicontrol Actions
|
||||||
|
menu, and then \uicontrol {Set Binding} (4) to open the
|
||||||
|
\uicontrol {Binding Editor} (5). There we bind the value of the \c input01
|
||||||
|
property of the AND operator to the value of the \c checked property of the
|
||||||
|
first check box. Then, we do the same in the \uicontrol Input02 field, where
|
||||||
|
we bind the \c input02 property to the \c checked property of the second
|
||||||
|
check box.
|
||||||
|
|
||||||
|
\image studio-logic-helper-and.png "AND operator properties"
|
||||||
|
|
||||||
|
Then, we select the first and second check box, and set their
|
||||||
|
\uicontrol Checked property to \c true in \uicontrol Properties.
|
||||||
|
We can multiselect the controls and make the change simultaneously
|
||||||
|
for both of them.
|
||||||
|
|
||||||
|
\image studio-logic-helper-and-operator-multiselect.gif "Multiselecting check boxes and changing Checked property"
|
||||||
|
|
||||||
|
Finally, we select the third check box and bind its \uicontrol Checked
|
||||||
|
property to the \uicontrol Output property of the AND operator.
|
||||||
|
|
||||||
|
\image studio-logic-helper-and-checkbox3.png "Binding Checked property to Output property."
|
||||||
|
|
||||||
|
When we \l{Previewing on Desktop}{preview} our UI, all the check boxes are
|
||||||
|
initially unchecked. However, when we select the first and second check box,
|
||||||
|
the third one also becomes checked.
|
||||||
|
|
||||||
|
\image studio-logic-helper-and-operator.gif "Previewing AND operator"
|
||||||
|
|
||||||
|
\section2 OR Operator
|
||||||
|
|
||||||
|
The \uicontrol {Or Operator} type does the same as the AND operator, but
|
||||||
|
the output is \c true if one or both inputs are \c true.
|
||||||
|
|
||||||
|
\section2 NOT Operator
|
||||||
|
|
||||||
|
The \uicontrol {Not Operator} type is evaluated to \c true if the condition
|
||||||
|
is not met.
|
||||||
|
|
||||||
|
For example, we could specify that if one check box is checked, another
|
||||||
|
one cannot be checked. First we drag-and-drop two \uicontrol {Check Box}
|
||||||
|
types and a \uicontrol {Not Operator} to \uicontrol Navigator. Then we
|
||||||
|
select \uicontrol {Not Operator} and set its properties in
|
||||||
|
\uicontrol Properties. In the \uicontrol {Binding Editor}, we bind the
|
||||||
|
value of the \c input property of the NOT operator to the value of the
|
||||||
|
\c checked property of the check box.
|
||||||
|
|
||||||
|
\image studio-logic-helper-not.png "NOT operator properties"
|
||||||
|
|
||||||
|
We then select the second check box and bind the value of its
|
||||||
|
\uicontrol Checked field to the value of of \uicontrol Output
|
||||||
|
field of the \uicontrol {Not Operator} component.
|
||||||
|
|
||||||
|
\image studio-logic-helper-not-check-box.png "Check box checked property bound to NOT operator output"
|
||||||
|
|
||||||
|
When we preview our UI, the second check box is initially checked. However,
|
||||||
|
when we select the first check box, the second one is automatically cleared.
|
||||||
|
|
||||||
|
\image studio-logic-helper-not-operator.gif "Previewing two check boxes bound with a NOT operator"
|
||||||
|
|
||||||
|
\section1 Bi-directional Binding
|
||||||
|
|
||||||
|
The \uicontrol {Bi Direct. Binding} type binds the values of two controls
|
||||||
|
together, so that when one value is changed, the other one follows it.
|
||||||
|
This type could be used to synchronize two sliders or a slider and checkbox.
|
||||||
|
Typically, it is used to bind a backend value to a control, such as a
|
||||||
|
slider.
|
||||||
|
|
||||||
|
For example, to synchronize the values of two sliders, drag and drop two
|
||||||
|
\uicontrol Slider components and one \uicontrol {Bi Direct. Binding}
|
||||||
|
component to the same parent component in \uicontrol Navigator. Then select
|
||||||
|
the bi-directional binding and set its properties in \uicontrol Properties.
|
||||||
|
|
||||||
|
\image studio-logic-helper-bidirectional-binding.png "Bi-directional binding properties"
|
||||||
|
|
||||||
|
In the \uicontrol {Target 01} and \uicontrol {Target 02} fields, enter
|
||||||
|
the ids of the components that you want to bind together. In the
|
||||||
|
\uicontrol {Property 01} and \uicontrol {Property 02} fields, enter the
|
||||||
|
names of the properties to synchronize. In our example, we bind the
|
||||||
|
\c value property of two slider components together, so that when we move
|
||||||
|
one slider handle in the preview, the other one moves along with it.
|
||||||
|
|
||||||
|
\image studio-bidirectional-binding.gif "Previewing a bi-directional binding of two sliders"
|
||||||
|
|
||||||
|
If you want to add a text field that displays the value of the slider, you
|
||||||
|
can use a \l {String Mapper} component.
|
||||||
|
|
||||||
|
\section1 String Mapper
|
||||||
|
|
||||||
|
The \uicontrol {String Mapper} type maps numbers to strings. First you
|
||||||
|
\l{Adding Bindings Between Properties}{add a binding} between the string
|
||||||
|
mapper \c input property and the \c value property of the control that you
|
||||||
|
want to fetch the values from. Then, you add a binding between the \c text
|
||||||
|
property of the string mapper and that of the component that will display
|
||||||
|
the string.
|
||||||
|
|
||||||
|
For example, to use a \l Text component to display the value of a
|
||||||
|
slider, we drag and drop \uicontrol Text, \uicontrol Slider, and
|
||||||
|
\uicontrol {String Mapper} components to the same parent item. Then
|
||||||
|
we select \uicontrol {String Mapper} in \uicontrol Navigator to display
|
||||||
|
its properties in \uicontrol Properties. There we bind the value of the
|
||||||
|
\c input property of the string mapper to the value of the \c value
|
||||||
|
property of the slider.
|
||||||
|
|
||||||
|
\image studio-logic-helper-string-mapper-input.png "Binding slider value property to string mapper"
|
||||||
|
|
||||||
|
Next, we bind the value of the \uicontrol Text field of the
|
||||||
|
\uicontrol Text component to the value of the \uicontrol Text
|
||||||
|
field of the \uicontrol {String Mapper} component.
|
||||||
|
|
||||||
|
\image studio-logic-helper-string-mapper-text.png "Binding text property value to string mapper"
|
||||||
|
|
||||||
|
When we move the slider handle in the preview, the value displayed in the
|
||||||
|
text component changes accordingly.
|
||||||
|
|
||||||
|
\image studio-logic-helper-string-mapper.gif "Previewing text property binding to string mapper"
|
||||||
|
|
||||||
|
The value of the \uicontrol Decimal field determines the number of digits
|
||||||
|
after the decimal separator.
|
||||||
|
|
||||||
|
\section1 Minimum-Maximum Mapper
|
||||||
|
|
||||||
|
The \uicontrol {Min Max Mapper} type has output values even if the input
|
||||||
|
value is out of range or too small or big. This enables you to apply
|
||||||
|
actions to values even if they are out of range, such as changing a color
|
||||||
|
in a state.
|
||||||
|
|
||||||
|
To access the values of a control, bind the \c input property of the
|
||||||
|
minimum-maximum mapper to that of the \c value property of the control.
|
||||||
|
|
||||||
|
For example, to restrict the maximum value of a slider to 0.60,
|
||||||
|
regardless of the maximum value set in the slider properties,
|
||||||
|
we drag and drop a \uicontrol {Min Max Mapper} to our example
|
||||||
|
above. We select it to display its properties in \uicontrol Properties.
|
||||||
|
Then, we bind the value of the \c input property of the mapper to
|
||||||
|
the value of the \c value property of the slider and set the value
|
||||||
|
of the \uicontrol Max field to 0.60.
|
||||||
|
|
||||||
|
\image studio-logic-helper-minmax-mapper-input.png "Binding slider value property to string mapper"
|
||||||
|
|
||||||
|
To have the maximum value displayed by the \l Text component, we select
|
||||||
|
the \uicontrol {String Mapper} component and change the binding we set
|
||||||
|
as the value of the \uicontrol Input field from \c slider.value to
|
||||||
|
\c minMaxMapper.value.
|
||||||
|
|
||||||
|
\image studio-logic-helper-minmax-mapper-string-mapper-input.png "Binding string mapper input to min max mapper"
|
||||||
|
|
||||||
|
When we move the slider handle in the preview, it only moves up to the
|
||||||
|
value 0.60.
|
||||||
|
|
||||||
|
\image studio-logic-helper-minmax-mapper.gif "Previewing a minimum-maximum mapper"
|
||||||
|
|
||||||
|
The \uicontrol OutOfRange, \uicontrol MaxClipped and \uicontrol MinClipped
|
||||||
|
check boxes are set to \c true if the value of the \uicontrol Input field
|
||||||
|
is out of range.
|
||||||
|
|
||||||
|
For example, in the context of speed, \uicontrol MaxClipped being \c true
|
||||||
|
would mean \e {too fast}, whereas \uicontrol MinClipped being \c true, would
|
||||||
|
mean \e {too slow}, and \uicontrol OutOfRange being \c true would mean
|
||||||
|
\e {either too fast or too slow}.
|
||||||
|
|
||||||
|
\section1 Range Mapper
|
||||||
|
|
||||||
|
The \uicontrol {Range Mapper} type maps a numerical range to another range,
|
||||||
|
so that the output value of the second range follows the input value of the
|
||||||
|
original range. This is useful when remapping the current frame on the
|
||||||
|
timeline, for example.
|
||||||
|
|
||||||
|
\image studio-logic-helper-range-mapper-properties.png "Range Mapper properties"
|
||||||
|
|
||||||
|
Specify the minimum and maximum input and output values in the
|
||||||
|
\uicontrol InputMin, \uicontrol InputMax, \uicontrol OutputMin,
|
||||||
|
and \uicontrol OutputMax fields and the original value in the
|
||||||
|
\uicontrol Value field.
|
||||||
|
|
||||||
|
For example, we can specify that the values of a slider range from -1 to 1.
|
||||||
|
If we want to display values from 10 to 1000, instead, we can bind the
|
||||||
|
values of the \uicontrol From and \uicontrol To fields of the \l Slider
|
||||||
|
type to the values of the \uicontrol InputMin and \uicontrol InputMax
|
||||||
|
fields of a \uicontrol {Range Mapper} type. We then set the value of the
|
||||||
|
\uicontrol OutputMin field to 10 and the value of the \uicontrol OutputMax
|
||||||
|
field to 1000.
|
||||||
|
|
||||||
|
\image studio-logic-helper-range-mapper-inputmin.png "Binding range mapper minimum input to slider.from property"
|
||||||
|
|
||||||
|
When we move the slider handle in the preview, so that the input value
|
||||||
|
from the \l Slider type changes from -1 to 1, the output value changes
|
||||||
|
from 10 to 1000.
|
||||||
|
|
||||||
|
\image studio-logic-helper-range-mapper.gif "Previewing a range mapper"
|
||||||
|
|
||||||
|
\section1 Summary of Logic Helpers
|
||||||
|
|
||||||
|
The following table summarizes the available effects and contains links to
|
||||||
|
the documentation of the inherited QML type.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Icon
|
||||||
|
\li Qt Quick Studio Effect
|
||||||
|
\li Description
|
||||||
|
\row
|
||||||
|
\li \inlineimage icons/lc-and-operator-16px.png
|
||||||
|
\li And Operator
|
||||||
|
\li Boolean AND.
|
||||||
|
\row
|
||||||
|
\li \inlineimage icons/lc-bidirectional-binding-16px.png
|
||||||
|
\li Bi Direct. Binding
|
||||||
|
\li A bi-directional binding that binds two values in both directions
|
||||||
|
and keeps them in sync.
|
||||||
|
\row
|
||||||
|
\li \inlineimage icons/lc-min-max-16px.png
|
||||||
|
\li Min Max Mapper
|
||||||
|
\li Maps a number to another number with a minimum and maximum value.
|
||||||
|
\row
|
||||||
|
\li \inlineimage icons/lc-not-operator-16px.png
|
||||||
|
\li Not Operator
|
||||||
|
\li Boolean NOT.
|
||||||
|
\row
|
||||||
|
\li \inlineimage icons/lc-or-operator-16px.png
|
||||||
|
\li Or Operator
|
||||||
|
\li Boolean OR.
|
||||||
|
\row
|
||||||
|
\li \inlineimage icons/lc-range-mapper-16px.png
|
||||||
|
\li Range Mapper
|
||||||
|
\li Maps a numerical range to another range, so that the output value
|
||||||
|
of the second range follows the input value of the original range.
|
||||||
|
\row
|
||||||
|
\li \inlineimage icons/lc-string-mapper-16px.png
|
||||||
|
\li String Mapper
|
||||||
|
\li Maps a number to a string with the defined precision.
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
/*!
|
/*!
|
||||||
\page quick-2d-effects.html
|
\page quick-2d-effects.html
|
||||||
\previouspage quick-data-models.html
|
\previouspage quick-data-models.html
|
||||||
\nextpage quick-buttons.html
|
\nextpage quick-logic-helpers.html
|
||||||
|
|
||||||
\title 2D Effects
|
\title 2D Effects
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,15 @@
|
|||||||
|
|
||||||
|
NOTE:
|
||||||
|
|
||||||
While the primary intention of this pretty printing implementation is
|
While the primary intention of this pretty printing implementation is
|
||||||
to provide what Qt Creator needs, it can be used in a plain GDB and LLDB
|
to provide what Qt Creator needs, it can sometimes be used in plain
|
||||||
session, too.
|
GDB and LLDB sessions, too.
|
||||||
|
|
||||||
|
This features is provided as-is. There is no guarantee this works in any
|
||||||
|
way outside Qt Creator, this setup is not officially supported.
|
||||||
|
Bugreports or (better!) patches are welcome.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
With
|
With
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<!DOCTYPE TS><TS>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="hu">
|
||||||
<context>
|
<context>
|
||||||
<name>Application</name>
|
<name>Application</name>
|
||||||
<message>
|
<message>
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ list(APPEND CMAKE_MODULE_PATH \${CMAKE_CURRENT_LIST_DIR})
|
|||||||
|
|
||||||
include(CMakeFindDependencyMacro)
|
include(CMakeFindDependencyMacro)
|
||||||
find_dependency(Qt5 ${IDE_QT_VERSION_MIN}
|
find_dependency(Qt5 ${IDE_QT_VERSION_MIN}
|
||||||
COMPONENTS Concurrent Core Network PrintSupport Qml Quick QuickWidgets Sql REQUIRED
|
COMPONENTS Concurrent Core Gui Widgets Core5Compat Network PrintSupport Qml Quick QuickWidgets Sql REQUIRED
|
||||||
)
|
)
|
||||||
|
|
||||||
if (NOT IDE_VERSION)
|
if (NOT IDE_VERSION)
|
||||||
|
|||||||
178
src/libs/3rdparty/sqlite/carray.c
vendored
@@ -57,21 +57,32 @@ SQLITE_EXTENSION_INIT1
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
/* Allowed values for the mFlags parameter to sqlite3_carray_bind().
|
||||||
|
** Must exactly match the definitions in carray.h.
|
||||||
|
*/
|
||||||
|
#define CARRAY_INT32 0 /* Data is 32-bit signed integers */
|
||||||
|
#define CARRAY_INT64 1 /* Data is 64-bit signed integers */
|
||||||
|
#define CARRAY_DOUBLE 2 /* Data is doubles */
|
||||||
|
#define CARRAY_TEXT 3 /* Data is char* */
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Allowed datatypes
|
** Names of allowed datatypes
|
||||||
*/
|
|
||||||
#define CARRAY_INT32 0
|
|
||||||
#define CARRAY_INT64 1
|
|
||||||
#define CARRAY_DOUBLE 2
|
|
||||||
#define CARRAY_TEXT 3
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Names of types
|
|
||||||
*/
|
*/
|
||||||
static const char *azType[] = { "int32", "int64", "double", "char*" };
|
static const char *azType[] = { "int32", "int64", "double", "char*" };
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Structure used to hold the sqlite3_carray_bind() information
|
||||||
|
*/
|
||||||
|
typedef struct carray_bind carray_bind;
|
||||||
|
struct carray_bind {
|
||||||
|
void *aData; /* The data */
|
||||||
|
int nData; /* Number of elements */
|
||||||
|
int mFlags; /* Control flags */
|
||||||
|
void (*xDel)(void*); /* Destructor for aData */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* carray_cursor is a subclass of sqlite3_vtab_cursor which will
|
/* carray_cursor is a subclass of sqlite3_vtab_cursor which will
|
||||||
** serve as the underlying representation of a cursor that scans
|
** serve as the underlying representation of a cursor that scans
|
||||||
@@ -136,13 +147,10 @@ static int carrayDisconnect(sqlite3_vtab *pVtab){
|
|||||||
/*
|
/*
|
||||||
** Constructor for a new carray_cursor object.
|
** Constructor for a new carray_cursor object.
|
||||||
*/
|
*/
|
||||||
static int carrayOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor)
|
static int carrayOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
|
||||||
{
|
|
||||||
carray_cursor *pCur;
|
carray_cursor *pCur;
|
||||||
|
pCur = sqlite3_malloc( sizeof(*pCur) );
|
||||||
pCur = sqlite3_malloc(sizeof(*pCur));
|
if( pCur==0 ) return SQLITE_NOMEM;
|
||||||
if (pCur == 0)
|
|
||||||
return SQLITE_NOMEM;
|
|
||||||
memset(pCur, 0, sizeof(*pCur));
|
memset(pCur, 0, sizeof(*pCur));
|
||||||
*ppCursor = &pCur->base;
|
*ppCursor = &pCur->base;
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
@@ -242,7 +250,19 @@ static int carrayFilter(
|
|||||||
int argc, sqlite3_value **argv
|
int argc, sqlite3_value **argv
|
||||||
){
|
){
|
||||||
carray_cursor *pCur = (carray_cursor *)pVtabCursor;
|
carray_cursor *pCur = (carray_cursor *)pVtabCursor;
|
||||||
if( idxNum ){
|
pCur->pPtr = 0;
|
||||||
|
pCur->iCnt = 0;
|
||||||
|
switch( idxNum ){
|
||||||
|
case 1: {
|
||||||
|
carray_bind *pBind = sqlite3_value_pointer(argv[0], "carray-bind");
|
||||||
|
if( pBind==0 ) break;
|
||||||
|
pCur->pPtr = pBind->aData;
|
||||||
|
pCur->iCnt = pBind->nData;
|
||||||
|
pCur->eType = pBind->mFlags & 0x03;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
case 3: {
|
||||||
pCur->pPtr = sqlite3_value_pointer(argv[0], "carray");
|
pCur->pPtr = sqlite3_value_pointer(argv[0], "carray");
|
||||||
pCur->iCnt = pCur->pPtr ? sqlite3_value_int64(argv[1]) : 0;
|
pCur->iCnt = pCur->pPtr ? sqlite3_value_int64(argv[1]) : 0;
|
||||||
if( idxNum<3 ){
|
if( idxNum<3 ){
|
||||||
@@ -261,9 +281,8 @@ static int carrayFilter(
|
|||||||
pCur->eType = i;
|
pCur->eType = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
break;
|
||||||
pCur->pPtr = 0;
|
}
|
||||||
pCur->iCnt = 0;
|
|
||||||
}
|
}
|
||||||
pCur->iRowid = 1;
|
pCur->iRowid = 1;
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
@@ -278,9 +297,16 @@ static int carrayFilter(
|
|||||||
** In this implementation idxNum is used to represent the
|
** In this implementation idxNum is used to represent the
|
||||||
** query plan. idxStr is unused.
|
** query plan. idxStr is unused.
|
||||||
**
|
**
|
||||||
** idxNum is 2 if the pointer= and count= constraints exist,
|
** idxNum is:
|
||||||
** 3 if the ctype= constraint also exists, and is 0 otherwise.
|
**
|
||||||
** If idxNum is 0, then carray becomes an empty table.
|
** 1 If only the pointer= constraint exists. In this case, the
|
||||||
|
** parameter must be bound using sqlite3_carray_bind().
|
||||||
|
**
|
||||||
|
** 2 if the pointer= and count= constraints exist.
|
||||||
|
**
|
||||||
|
** 3 if the ctype= constraint also exists.
|
||||||
|
**
|
||||||
|
** idxNum is 0 otherwise and carray becomes an empty table.
|
||||||
*/
|
*/
|
||||||
static int carrayBestIndex(
|
static int carrayBestIndex(
|
||||||
sqlite3_vtab *tab,
|
sqlite3_vtab *tab,
|
||||||
@@ -308,19 +334,22 @@ static int carrayBestIndex(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( ptrIdx>=0 && cntIdx>=0 ){
|
if( ptrIdx>=0 ){
|
||||||
pIdxInfo->aConstraintUsage[ptrIdx].argvIndex = 1;
|
pIdxInfo->aConstraintUsage[ptrIdx].argvIndex = 1;
|
||||||
pIdxInfo->aConstraintUsage[ptrIdx].omit = 1;
|
pIdxInfo->aConstraintUsage[ptrIdx].omit = 1;
|
||||||
pIdxInfo->aConstraintUsage[cntIdx].argvIndex = 2;
|
|
||||||
pIdxInfo->aConstraintUsage[cntIdx].omit = 1;
|
|
||||||
pIdxInfo->estimatedCost = (double)1;
|
pIdxInfo->estimatedCost = (double)1;
|
||||||
pIdxInfo->estimatedRows = 100;
|
pIdxInfo->estimatedRows = 100;
|
||||||
|
pIdxInfo->idxNum = 1;
|
||||||
|
if( cntIdx>=0 ){
|
||||||
|
pIdxInfo->aConstraintUsage[cntIdx].argvIndex = 2;
|
||||||
|
pIdxInfo->aConstraintUsage[cntIdx].omit = 1;
|
||||||
pIdxInfo->idxNum = 2;
|
pIdxInfo->idxNum = 2;
|
||||||
if( ctypeIdx>=0 ){
|
if( ctypeIdx>=0 ){
|
||||||
pIdxInfo->aConstraintUsage[ctypeIdx].argvIndex = 3;
|
pIdxInfo->aConstraintUsage[ctypeIdx].argvIndex = 3;
|
||||||
pIdxInfo->aConstraintUsage[ctypeIdx].omit = 1;
|
pIdxInfo->aConstraintUsage[ctypeIdx].omit = 1;
|
||||||
pIdxInfo->idxNum = 3;
|
pIdxInfo->idxNum = 3;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
pIdxInfo->estimatedCost = (double)2147483647;
|
pIdxInfo->estimatedCost = (double)2147483647;
|
||||||
pIdxInfo->estimatedRows = 2147483647;
|
pIdxInfo->estimatedRows = 2147483647;
|
||||||
@@ -356,6 +385,89 @@ static sqlite3_module carrayModule = {
|
|||||||
0, /* xRename */
|
0, /* xRename */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Destructor for the carray_bind object
|
||||||
|
*/
|
||||||
|
static void carrayBindDel(void *pPtr){
|
||||||
|
carray_bind *p = (carray_bind*)pPtr;
|
||||||
|
if( p->xDel!=SQLITE_STATIC ){
|
||||||
|
p->xDel(p->aData);
|
||||||
|
}
|
||||||
|
sqlite3_free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Invoke this interface in order to bind to the single-argument
|
||||||
|
** version of CARRAY().
|
||||||
|
*/
|
||||||
|
#ifdef _WIN32
|
||||||
|
__declspec(dllexport)
|
||||||
|
#endif
|
||||||
|
int sqlite3_carray_bind(
|
||||||
|
sqlite3_stmt *pStmt,
|
||||||
|
int idx,
|
||||||
|
void *aData,
|
||||||
|
int nData,
|
||||||
|
int mFlags,
|
||||||
|
void (*xDestroy)(void*)
|
||||||
|
){
|
||||||
|
carray_bind *pNew;
|
||||||
|
int i;
|
||||||
|
pNew = sqlite3_malloc64(sizeof(*pNew));
|
||||||
|
if( pNew==0 ){
|
||||||
|
if( xDestroy!=SQLITE_STATIC && xDestroy!=SQLITE_TRANSIENT ){
|
||||||
|
xDestroy(aData);
|
||||||
|
}
|
||||||
|
return SQLITE_NOMEM;
|
||||||
|
}
|
||||||
|
pNew->nData = nData;
|
||||||
|
pNew->mFlags = mFlags;
|
||||||
|
if( xDestroy==SQLITE_TRANSIENT ){
|
||||||
|
sqlite3_int64 sz = nData;
|
||||||
|
switch( mFlags & 0x03 ){
|
||||||
|
case CARRAY_INT32: sz *= 4; break;
|
||||||
|
case CARRAY_INT64: sz *= 8; break;
|
||||||
|
case CARRAY_DOUBLE: sz *= 8; break;
|
||||||
|
case CARRAY_TEXT: sz *= sizeof(char*); break;
|
||||||
|
}
|
||||||
|
if( (mFlags & 0x03)==CARRAY_TEXT ){
|
||||||
|
for(i=0; i<nData; i++){
|
||||||
|
const char *z = ((char**)aData)[i];
|
||||||
|
if( z ) sz += strlen(z) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pNew->aData = sqlite3_malloc64( sz );
|
||||||
|
if( pNew->aData==0 ){
|
||||||
|
sqlite3_free(pNew);
|
||||||
|
return SQLITE_NOMEM;
|
||||||
|
}
|
||||||
|
if( (mFlags & 0x03)==CARRAY_TEXT ){
|
||||||
|
char **az = (char**)pNew->aData;
|
||||||
|
char *z = (char*)&az[nData];
|
||||||
|
for(i=0; i<nData; i++){
|
||||||
|
const char *zData = ((char**)aData)[i];
|
||||||
|
sqlite3_int64 n;
|
||||||
|
if( zData==0 ){
|
||||||
|
az[i] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
az[i] = z;
|
||||||
|
n = strlen(zData);
|
||||||
|
memcpy(z, zData, n+1);
|
||||||
|
z += n+1;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
memcpy(pNew->aData, aData, sz*nData);
|
||||||
|
}
|
||||||
|
pNew->xDel = sqlite3_free;
|
||||||
|
}else{
|
||||||
|
pNew->aData = aData;
|
||||||
|
pNew->xDel = xDestroy;
|
||||||
|
}
|
||||||
|
return sqlite3_bind_pointer(pStmt, idx, pNew, "carray-bind", carrayBindDel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** For testing purpose in the TCL test harness, we need a method for
|
** For testing purpose in the TCL test harness, we need a method for
|
||||||
** setting the pointer value. The inttoptr(X) SQL function accomplishes
|
** setting the pointer value. The inttoptr(X) SQL function accomplishes
|
||||||
@@ -386,16 +498,22 @@ static void inttoptrFunc(
|
|||||||
|
|
||||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||||
|
|
||||||
int sqlite3_carray_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi)
|
#ifdef _WIN32
|
||||||
{
|
__declspec(dllexport)
|
||||||
|
#endif
|
||||||
|
int sqlite3_carray_init(
|
||||||
|
sqlite3 *db,
|
||||||
|
char **pzErrMsg,
|
||||||
|
const sqlite3_api_routines *pApi
|
||||||
|
){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
SQLITE_EXTENSION_INIT2(pApi);
|
SQLITE_EXTENSION_INIT2(pApi);
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
rc = sqlite3_create_module(db, "carray", &carrayModule, 0);
|
rc = sqlite3_create_module(db, "carray", &carrayModule, 0);
|
||||||
|
|
||||||
#ifdef SQLITE_TEST
|
#ifdef SQLITE_TEST
|
||||||
if (rc == SQLITE_OK) {
|
if( rc==SQLITE_OK ){
|
||||||
rc = sqlite3_create_function(db, "inttoptr", 1, SQLITE_UTF8, 0, inttoptrFunc, 0, 0);
|
rc = sqlite3_create_function(db, "inttoptr", 1, SQLITE_UTF8, 0,
|
||||||
|
inttoptrFunc, 0, 0);
|
||||||
}
|
}
|
||||||
#endif /* SQLITE_TEST */
|
#endif /* SQLITE_TEST */
|
||||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||||
|
|||||||
10945
src/libs/3rdparty/sqlite/sqlite3.c
vendored
341
src/libs/3rdparty/sqlite/sqlite3.h
vendored
@@ -123,9 +123,9 @@ extern "C" {
|
|||||||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||||
** [sqlite_version()] and [sqlite_source_id()].
|
** [sqlite_version()] and [sqlite_source_id()].
|
||||||
*/
|
*/
|
||||||
#define SQLITE_VERSION "3.31.1"
|
#define SQLITE_VERSION "3.34.0"
|
||||||
#define SQLITE_VERSION_NUMBER 3031001
|
#define SQLITE_VERSION_NUMBER 3034000
|
||||||
#define SQLITE_SOURCE_ID "2020-01-27 19:55:54 3bfa9cc97da10598521b342961df8f5f68c7388fa117345eeb516eaa837bb4d6"
|
#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089fed5b"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Run-Time Library Version Numbers
|
** CAPI3REF: Run-Time Library Version Numbers
|
||||||
@@ -299,26 +299,22 @@ typedef sqlite_uint64 sqlite3_uint64;
|
|||||||
** the [sqlite3] object is successfully destroyed and all associated
|
** the [sqlite3] object is successfully destroyed and all associated
|
||||||
** resources are deallocated.
|
** resources are deallocated.
|
||||||
**
|
**
|
||||||
** ^If the database connection is associated with unfinalized prepared
|
** Ideally, applications should [sqlite3_finalize | finalize] all
|
||||||
** statements or unfinished sqlite3_backup objects then sqlite3_close()
|
** [prepared statements], [sqlite3_blob_close | close] all [BLOB handles], and
|
||||||
** will leave the database connection open and return [SQLITE_BUSY].
|
|
||||||
** ^If sqlite3_close_v2() is called with unfinalized prepared statements
|
|
||||||
** and/or unfinished sqlite3_backups, then the database connection becomes
|
|
||||||
** an unusable "zombie" which will automatically be deallocated when the
|
|
||||||
** last prepared statement is finalized or the last sqlite3_backup is
|
|
||||||
** finished. The sqlite3_close_v2() interface is intended for use with
|
|
||||||
** host languages that are garbage collected, and where the order in which
|
|
||||||
** destructors are called is arbitrary.
|
|
||||||
**
|
|
||||||
** Applications should [sqlite3_finalize | finalize] all [prepared statements],
|
|
||||||
** [sqlite3_blob_close | close] all [BLOB handles], and
|
|
||||||
** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
|
** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
|
||||||
** with the [sqlite3] object prior to attempting to close the object. ^If
|
** with the [sqlite3] object prior to attempting to close the object.
|
||||||
** sqlite3_close_v2() is called on a [database connection] that still has
|
** ^If the database connection is associated with unfinalized prepared
|
||||||
** outstanding [prepared statements], [BLOB handles], and/or
|
** statements, BLOB handlers, and/or unfinished sqlite3_backup objects then
|
||||||
** [sqlite3_backup] objects then it returns [SQLITE_OK] and the deallocation
|
** sqlite3_close() will leave the database connection open and return
|
||||||
** of resources is deferred until all [prepared statements], [BLOB handles],
|
** [SQLITE_BUSY]. ^If sqlite3_close_v2() is called with unfinalized prepared
|
||||||
** and [sqlite3_backup] objects are also destroyed.
|
** statements, unclosed BLOB handlers, and/or unfinished sqlite3_backups,
|
||||||
|
** it returns [SQLITE_OK] regardless, but instead of deallocating the database
|
||||||
|
** connection immediately, it marks the database connection as an unusable
|
||||||
|
** "zombie" and makes arrangements to automatically deallocate the database
|
||||||
|
** connection after all prepared statements are finalized, all BLOB handles
|
||||||
|
** are closed, and all backups have finished. The sqlite3_close_v2() interface
|
||||||
|
** is intended for use with host languages that are garbage collected, and
|
||||||
|
** where the order in which destructors are called is arbitrary.
|
||||||
**
|
**
|
||||||
** ^If an [sqlite3] object is destroyed while a transaction is open,
|
** ^If an [sqlite3] object is destroyed while a transaction is open,
|
||||||
** the transaction is automatically rolled back.
|
** the transaction is automatically rolled back.
|
||||||
@@ -507,10 +503,13 @@ SQLITE_API int sqlite3_exec(
|
|||||||
#define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8))
|
#define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8))
|
||||||
#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
|
#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
|
||||||
#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
|
#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
|
||||||
|
#define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8))
|
||||||
|
#define SQLITE_IOERR_CORRUPTFS (SQLITE_IOERR | (33<<8))
|
||||||
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
|
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
|
||||||
#define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8))
|
#define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8))
|
||||||
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
|
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
|
||||||
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
|
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
|
||||||
|
#define SQLITE_BUSY_TIMEOUT (SQLITE_BUSY | (3<<8))
|
||||||
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
|
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
|
||||||
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
|
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
|
||||||
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
|
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
|
||||||
@@ -519,6 +518,7 @@ SQLITE_API int sqlite3_exec(
|
|||||||
#define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8))
|
#define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8))
|
||||||
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
|
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
|
||||||
#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
|
#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
|
||||||
|
#define SQLITE_CORRUPT_INDEX (SQLITE_CORRUPT | (3<<8))
|
||||||
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
|
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
|
||||||
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
|
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
|
||||||
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
|
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
|
||||||
@@ -565,7 +565,7 @@ SQLITE_API int sqlite3_exec(
|
|||||||
#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */
|
#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */
|
||||||
#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */
|
#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */
|
||||||
#define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */
|
#define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */
|
||||||
#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
|
#define SQLITE_OPEN_SUPER_JOURNAL 0x00004000 /* VFS only */
|
||||||
#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */
|
#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */
|
||||||
#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
|
#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
|
||||||
#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
|
#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
|
||||||
@@ -574,6 +574,9 @@ SQLITE_API int sqlite3_exec(
|
|||||||
#define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */
|
#define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */
|
||||||
|
|
||||||
/* Reserved: 0x00F00000 */
|
/* Reserved: 0x00F00000 */
|
||||||
|
/* Legacy compatibility: */
|
||||||
|
#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Device Characteristics
|
** CAPI3REF: Device Characteristics
|
||||||
@@ -871,7 +874,7 @@ struct sqlite3_io_methods {
|
|||||||
** of the xSync method. In most cases, the pointer argument passed with
|
** of the xSync method. In most cases, the pointer argument passed with
|
||||||
** this file-control is NULL. However, if the database file is being synced
|
** this file-control is NULL. However, if the database file is being synced
|
||||||
** as part of a multi-database commit, the argument points to a nul-terminated
|
** as part of a multi-database commit, the argument points to a nul-terminated
|
||||||
** string containing the transactions master-journal file name. VFSes that
|
** string containing the transactions super-journal file name. VFSes that
|
||||||
** do not need this signal should silently ignore this opcode. Applications
|
** do not need this signal should silently ignore this opcode. Applications
|
||||||
** should not call [sqlite3_file_control()] with this opcode as doing so may
|
** should not call [sqlite3_file_control()] with this opcode as doing so may
|
||||||
** disrupt the operation of the specialized VFSes that do require it.
|
** disrupt the operation of the specialized VFSes that do require it.
|
||||||
@@ -1087,10 +1090,12 @@ struct sqlite3_io_methods {
|
|||||||
** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
|
** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
|
||||||
**
|
**
|
||||||
** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]]
|
** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]]
|
||||||
** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain
|
** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode is used to configure a VFS
|
||||||
** a file lock using the xLock or xShmLock methods of the VFS to wait
|
** to block for up to M milliseconds before failing when attempting to
|
||||||
** for up to M milliseconds before failing, where M is the single
|
** obtain a file lock using the xLock or xShmLock methods of the VFS.
|
||||||
** unsigned integer parameter.
|
** The parameter is a pointer to a 32-bit signed integer that contains
|
||||||
|
** the value that M is to be set to. Before returning, the 32-bit signed
|
||||||
|
** integer is overwritten with the previous value of M.
|
||||||
**
|
**
|
||||||
** <li>[[SQLITE_FCNTL_DATA_VERSION]]
|
** <li>[[SQLITE_FCNTL_DATA_VERSION]]
|
||||||
** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to
|
** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to
|
||||||
@@ -1112,6 +1117,11 @@ struct sqlite3_io_methods {
|
|||||||
** happen either internally or externally and that are associated with
|
** happen either internally or externally and that are associated with
|
||||||
** a particular attached database.
|
** a particular attached database.
|
||||||
**
|
**
|
||||||
|
** <li>[[SQLITE_FCNTL_CKPT_START]]
|
||||||
|
** The [SQLITE_FCNTL_CKPT_START] opcode is invoked from within a checkpoint
|
||||||
|
** in wal mode before the client starts to copy pages from the wal
|
||||||
|
** file to the database file.
|
||||||
|
**
|
||||||
** <li>[[SQLITE_FCNTL_CKPT_DONE]]
|
** <li>[[SQLITE_FCNTL_CKPT_DONE]]
|
||||||
** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint
|
** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint
|
||||||
** in wal mode after the client has finished copying pages from the wal
|
** in wal mode after the client has finished copying pages from the wal
|
||||||
@@ -1155,6 +1165,8 @@ struct sqlite3_io_methods {
|
|||||||
#define SQLITE_FCNTL_DATA_VERSION 35
|
#define SQLITE_FCNTL_DATA_VERSION 35
|
||||||
#define SQLITE_FCNTL_SIZE_LIMIT 36
|
#define SQLITE_FCNTL_SIZE_LIMIT 36
|
||||||
#define SQLITE_FCNTL_CKPT_DONE 37
|
#define SQLITE_FCNTL_CKPT_DONE 37
|
||||||
|
#define SQLITE_FCNTL_RESERVE_BYTES 38
|
||||||
|
#define SQLITE_FCNTL_CKPT_START 39
|
||||||
|
|
||||||
/* deprecated names */
|
/* deprecated names */
|
||||||
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
|
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
|
||||||
@@ -1259,7 +1271,7 @@ typedef struct sqlite3_api_routines sqlite3_api_routines;
|
|||||||
** <li> [SQLITE_OPEN_TEMP_JOURNAL]
|
** <li> [SQLITE_OPEN_TEMP_JOURNAL]
|
||||||
** <li> [SQLITE_OPEN_TRANSIENT_DB]
|
** <li> [SQLITE_OPEN_TRANSIENT_DB]
|
||||||
** <li> [SQLITE_OPEN_SUBJOURNAL]
|
** <li> [SQLITE_OPEN_SUBJOURNAL]
|
||||||
** <li> [SQLITE_OPEN_MASTER_JOURNAL]
|
** <li> [SQLITE_OPEN_SUPER_JOURNAL]
|
||||||
** <li> [SQLITE_OPEN_WAL]
|
** <li> [SQLITE_OPEN_WAL]
|
||||||
** </ul>)^
|
** </ul>)^
|
||||||
**
|
**
|
||||||
@@ -1637,7 +1649,7 @@ SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
|
|||||||
** by xInit. The pAppData pointer is used as the only parameter to
|
** by xInit. The pAppData pointer is used as the only parameter to
|
||||||
** xInit and xShutdown.
|
** xInit and xShutdown.
|
||||||
**
|
**
|
||||||
** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes
|
** SQLite holds the [SQLITE_MUTEX_STATIC_MAIN] mutex when it invokes
|
||||||
** the xInit method, so the xInit method need not be threadsafe. The
|
** the xInit method, so the xInit method need not be threadsafe. The
|
||||||
** xShutdown method is only called from [sqlite3_shutdown()] so it does
|
** xShutdown method is only called from [sqlite3_shutdown()] so it does
|
||||||
** not need to be threadsafe either. For all other methods, SQLite
|
** not need to be threadsafe either. For all other methods, SQLite
|
||||||
@@ -2275,8 +2287,7 @@ struct sqlite3_mem_methods {
|
|||||||
** [[SQLITE_DBCONFIG_TRUSTED_SCHEMA]]
|
** [[SQLITE_DBCONFIG_TRUSTED_SCHEMA]]
|
||||||
** <dt>SQLITE_DBCONFIG_TRUSTED_SCHEMA</td>
|
** <dt>SQLITE_DBCONFIG_TRUSTED_SCHEMA</td>
|
||||||
** <dd>The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells SQLite to
|
** <dd>The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells SQLite to
|
||||||
** assume that database schemas (the contents of the [sqlite_master] tables)
|
** assume that database schemas are untainted by malicious content.
|
||||||
** are untainted by malicious content.
|
|
||||||
** When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite
|
** When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite
|
||||||
** takes additional defensive steps to protect the application from harm
|
** takes additional defensive steps to protect the application from harm
|
||||||
** including:
|
** including:
|
||||||
@@ -3533,8 +3544,19 @@ SQLITE_API int sqlite3_open_v2(
|
|||||||
** that check if a database file was a URI that contained a specific query
|
** that check if a database file was a URI that contained a specific query
|
||||||
** parameter, and if so obtains the value of that query parameter.
|
** parameter, and if so obtains the value of that query parameter.
|
||||||
**
|
**
|
||||||
** If F is the database filename pointer passed into the xOpen() method of
|
** The first parameter to these interfaces (hereafter referred to
|
||||||
** a VFS implementation or it is the return value of [sqlite3_db_filename()]
|
** as F) must be one of:
|
||||||
|
** <ul>
|
||||||
|
** <li> A database filename pointer created by the SQLite core and
|
||||||
|
** passed into the xOpen() method of a VFS implemention, or
|
||||||
|
** <li> A filename obtained from [sqlite3_db_filename()], or
|
||||||
|
** <li> A new filename constructed using [sqlite3_create_filename()].
|
||||||
|
** </ul>
|
||||||
|
** If the F parameter is not one of the above, then the behavior is
|
||||||
|
** undefined and probably undesirable. Older versions of SQLite were
|
||||||
|
** more tolerant of invalid F parameters than newer versions.
|
||||||
|
**
|
||||||
|
** If F is a suitable filename (as described in the previous paragraph)
|
||||||
** and if P is the name of the query parameter, then
|
** and if P is the name of the query parameter, then
|
||||||
** sqlite3_uri_parameter(F,P) returns the value of the P
|
** sqlite3_uri_parameter(F,P) returns the value of the P
|
||||||
** parameter if it exists or a NULL pointer if P does not appear as a
|
** parameter if it exists or a NULL pointer if P does not appear as a
|
||||||
@@ -3617,6 +3639,78 @@ SQLITE_API const char *sqlite3_filename_database(const char*);
|
|||||||
SQLITE_API const char *sqlite3_filename_journal(const char*);
|
SQLITE_API const char *sqlite3_filename_journal(const char*);
|
||||||
SQLITE_API const char *sqlite3_filename_wal(const char*);
|
SQLITE_API const char *sqlite3_filename_wal(const char*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** CAPI3REF: Database File Corresponding To A Journal
|
||||||
|
**
|
||||||
|
** ^If X is the name of a rollback or WAL-mode journal file that is
|
||||||
|
** passed into the xOpen method of [sqlite3_vfs], then
|
||||||
|
** sqlite3_database_file_object(X) returns a pointer to the [sqlite3_file]
|
||||||
|
** object that represents the main database file.
|
||||||
|
**
|
||||||
|
** This routine is intended for use in custom [VFS] implementations
|
||||||
|
** only. It is not a general-purpose interface.
|
||||||
|
** The argument sqlite3_file_object(X) must be a filename pointer that
|
||||||
|
** has been passed into [sqlite3_vfs].xOpen method where the
|
||||||
|
** flags parameter to xOpen contains one of the bits
|
||||||
|
** [SQLITE_OPEN_MAIN_JOURNAL] or [SQLITE_OPEN_WAL]. Any other use
|
||||||
|
** of this routine results in undefined and probably undesirable
|
||||||
|
** behavior.
|
||||||
|
*/
|
||||||
|
SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** CAPI3REF: Create and Destroy VFS Filenames
|
||||||
|
**
|
||||||
|
** These interfces are provided for use by [VFS shim] implementations and
|
||||||
|
** are not useful outside of that context.
|
||||||
|
**
|
||||||
|
** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of
|
||||||
|
** database filename D with corresponding journal file J and WAL file W and
|
||||||
|
** with N URI parameters key/values pairs in the array P. The result from
|
||||||
|
** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that
|
||||||
|
** is safe to pass to routines like:
|
||||||
|
** <ul>
|
||||||
|
** <li> [sqlite3_uri_parameter()],
|
||||||
|
** <li> [sqlite3_uri_boolean()],
|
||||||
|
** <li> [sqlite3_uri_int64()],
|
||||||
|
** <li> [sqlite3_uri_key()],
|
||||||
|
** <li> [sqlite3_filename_database()],
|
||||||
|
** <li> [sqlite3_filename_journal()], or
|
||||||
|
** <li> [sqlite3_filename_wal()].
|
||||||
|
** </ul>
|
||||||
|
** If a memory allocation error occurs, sqlite3_create_filename() might
|
||||||
|
** return a NULL pointer. The memory obtained from sqlite3_create_filename(X)
|
||||||
|
** must be released by a corresponding call to sqlite3_free_filename(Y).
|
||||||
|
**
|
||||||
|
** The P parameter in sqlite3_create_filename(D,J,W,N,P) should be an array
|
||||||
|
** of 2*N pointers to strings. Each pair of pointers in this array corresponds
|
||||||
|
** to a key and value for a query parameter. The P parameter may be a NULL
|
||||||
|
** pointer if N is zero. None of the 2*N pointers in the P array may be
|
||||||
|
** NULL pointers and key pointers should not be empty strings.
|
||||||
|
** None of the D, J, or W parameters to sqlite3_create_filename(D,J,W,N,P) may
|
||||||
|
** be NULL pointers, though they can be empty strings.
|
||||||
|
**
|
||||||
|
** The sqlite3_free_filename(Y) routine releases a memory allocation
|
||||||
|
** previously obtained from sqlite3_create_filename(). Invoking
|
||||||
|
** sqlite3_free_filename(Y) where Y is a NULL pointer is a harmless no-op.
|
||||||
|
**
|
||||||
|
** If the Y parameter to sqlite3_free_filename(Y) is anything other
|
||||||
|
** than a NULL pointer or a pointer previously acquired from
|
||||||
|
** sqlite3_create_filename(), then bad things such as heap
|
||||||
|
** corruption or segfaults may occur. The value Y should be
|
||||||
|
** used again after sqlite3_free_filename(Y) has been called. This means
|
||||||
|
** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y,
|
||||||
|
** then the corresponding [sqlite3_module.xClose() method should also be
|
||||||
|
** invoked prior to calling sqlite3_free_filename(Y).
|
||||||
|
*/
|
||||||
|
SQLITE_API char *sqlite3_create_filename(
|
||||||
|
const char *zDatabase,
|
||||||
|
const char *zJournal,
|
||||||
|
const char *zWal,
|
||||||
|
int nParam,
|
||||||
|
const char **azParam
|
||||||
|
);
|
||||||
|
SQLITE_API void sqlite3_free_filename(char*);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Error Codes And Messages
|
** CAPI3REF: Error Codes And Messages
|
||||||
@@ -4199,12 +4293,30 @@ typedef struct sqlite3_context sqlite3_context;
|
|||||||
** [sqlite3_bind_parameter_index()] API if desired. ^The index
|
** [sqlite3_bind_parameter_index()] API if desired. ^The index
|
||||||
** for "?NNN" parameters is the value of NNN.
|
** for "?NNN" parameters is the value of NNN.
|
||||||
** ^The NNN value must be between 1 and the [sqlite3_limit()]
|
** ^The NNN value must be between 1 and the [sqlite3_limit()]
|
||||||
** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999).
|
** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 32766).
|
||||||
**
|
**
|
||||||
** ^The third argument is the value to bind to the parameter.
|
** ^The third argument is the value to bind to the parameter.
|
||||||
** ^If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16()
|
** ^If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16()
|
||||||
** or sqlite3_bind_blob() is a NULL pointer then the fourth parameter
|
** or sqlite3_bind_blob() is a NULL pointer then the fourth parameter
|
||||||
** is ignored and the end result is the same as sqlite3_bind_null().
|
** is ignored and the end result is the same as sqlite3_bind_null().
|
||||||
|
** ^If the third parameter to sqlite3_bind_text() is not NULL, then
|
||||||
|
** it should be a pointer to well-formed UTF8 text.
|
||||||
|
** ^If the third parameter to sqlite3_bind_text16() is not NULL, then
|
||||||
|
** it should be a pointer to well-formed UTF16 text.
|
||||||
|
** ^If the third parameter to sqlite3_bind_text64() is not NULL, then
|
||||||
|
** it should be a pointer to a well-formed unicode string that is
|
||||||
|
** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16
|
||||||
|
** otherwise.
|
||||||
|
**
|
||||||
|
** [[byte-order determination rules]] ^The byte-order of
|
||||||
|
** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF)
|
||||||
|
** found in first character, which is removed, or in the absence of a BOM
|
||||||
|
** the byte order is the native byte order of the host
|
||||||
|
** machine for sqlite3_bind_text16() or the byte order specified in
|
||||||
|
** the 6th parameter for sqlite3_bind_text64().)^
|
||||||
|
** ^If UTF16 input text contains invalid unicode
|
||||||
|
** characters, then SQLite might change those invalid characters
|
||||||
|
** into the unicode replacement character: U+FFFD.
|
||||||
**
|
**
|
||||||
** ^(In those routines that have a fourth argument, its value is the
|
** ^(In those routines that have a fourth argument, its value is the
|
||||||
** number of bytes in the parameter. To be clear: the value is the
|
** number of bytes in the parameter. To be clear: the value is the
|
||||||
@@ -4218,7 +4330,7 @@ typedef struct sqlite3_context sqlite3_context;
|
|||||||
** or sqlite3_bind_text16() or sqlite3_bind_text64() then
|
** or sqlite3_bind_text16() or sqlite3_bind_text64() then
|
||||||
** that parameter must be the byte offset
|
** that parameter must be the byte offset
|
||||||
** where the NUL terminator would occur assuming the string were NUL
|
** where the NUL terminator would occur assuming the string were NUL
|
||||||
** terminated. If any NUL characters occur at byte offsets less than
|
** terminated. If any NUL characters occurs at byte offsets less than
|
||||||
** the value of the fourth parameter then the resulting string value will
|
** the value of the fourth parameter then the resulting string value will
|
||||||
** contain embedded NULs. The result of expressions involving strings
|
** contain embedded NULs. The result of expressions involving strings
|
||||||
** with embedded NULs is undefined.
|
** with embedded NULs is undefined.
|
||||||
@@ -5386,7 +5498,7 @@ SQLITE_API void sqlite3_value_free(sqlite3_value*);
|
|||||||
**
|
**
|
||||||
** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is
|
** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is
|
||||||
** determined by the N parameter on first successful call. Changing the
|
** determined by the N parameter on first successful call. Changing the
|
||||||
** value of N in any subsequents call to sqlite3_aggregate_context() within
|
** value of N in any subsequent call to sqlite3_aggregate_context() within
|
||||||
** the same aggregate function instance will not resize the memory
|
** the same aggregate function instance will not resize the memory
|
||||||
** allocation.)^ Within the xFinal callback, it is customary to set
|
** allocation.)^ Within the xFinal callback, it is customary to set
|
||||||
** N=0 in calls to sqlite3_aggregate_context(C,N) so that no
|
** N=0 in calls to sqlite3_aggregate_context(C,N) so that no
|
||||||
@@ -5543,8 +5655,9 @@ typedef void (*sqlite3_destructor_type)(void*);
|
|||||||
** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16()
|
** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16()
|
||||||
** as the text of an error message. ^SQLite interprets the error
|
** as the text of an error message. ^SQLite interprets the error
|
||||||
** message string from sqlite3_result_error() as UTF-8. ^SQLite
|
** message string from sqlite3_result_error() as UTF-8. ^SQLite
|
||||||
** interprets the string from sqlite3_result_error16() as UTF-16 in native
|
** interprets the string from sqlite3_result_error16() as UTF-16 using
|
||||||
** byte order. ^If the third parameter to sqlite3_result_error()
|
** the same [byte-order determination rules] as [sqlite3_bind_text16()].
|
||||||
|
** ^If the third parameter to sqlite3_result_error()
|
||||||
** or sqlite3_result_error16() is negative then SQLite takes as the error
|
** or sqlite3_result_error16() is negative then SQLite takes as the error
|
||||||
** message all text up through the first zero character.
|
** message all text up through the first zero character.
|
||||||
** ^If the third parameter to sqlite3_result_error() or
|
** ^If the third parameter to sqlite3_result_error() or
|
||||||
@@ -5612,6 +5725,25 @@ typedef void (*sqlite3_destructor_type)(void*);
|
|||||||
** then SQLite makes a copy of the result into space obtained
|
** then SQLite makes a copy of the result into space obtained
|
||||||
** from [sqlite3_malloc()] before it returns.
|
** from [sqlite3_malloc()] before it returns.
|
||||||
**
|
**
|
||||||
|
** ^For the sqlite3_result_text16(), sqlite3_result_text16le(), and
|
||||||
|
** sqlite3_result_text16be() routines, and for sqlite3_result_text64()
|
||||||
|
** when the encoding is not UTF8, if the input UTF16 begins with a
|
||||||
|
** byte-order mark (BOM, U+FEFF) then the BOM is removed from the
|
||||||
|
** string and the rest of the string is interpreted according to the
|
||||||
|
** byte-order specified by the BOM. ^The byte-order specified by
|
||||||
|
** the BOM at the beginning of the text overrides the byte-order
|
||||||
|
** specified by the interface procedure. ^So, for example, if
|
||||||
|
** sqlite3_result_text16le() is invoked with text that begins
|
||||||
|
** with bytes 0xfe, 0xff (a big-endian byte-order mark) then the
|
||||||
|
** first two bytes of input are skipped and the remaining input
|
||||||
|
** is interpreted as UTF16BE text.
|
||||||
|
**
|
||||||
|
** ^For UTF16 input text to the sqlite3_result_text16(),
|
||||||
|
** sqlite3_result_text16be(), sqlite3_result_text16le(), and
|
||||||
|
** sqlite3_result_text64() routines, if the text contains invalid
|
||||||
|
** UTF16 characters, the invalid characters might be converted
|
||||||
|
** into the unicode replacement character, U+FFFD.
|
||||||
|
**
|
||||||
** ^The sqlite3_result_value() interface sets the result of
|
** ^The sqlite3_result_value() interface sets the result of
|
||||||
** the application-defined function to be a copy of the
|
** the application-defined function to be a copy of the
|
||||||
** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The
|
** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The
|
||||||
@@ -5817,51 +5949,6 @@ SQLITE_API int sqlite3_collation_needed16(
|
|||||||
void(*)(void*,sqlite3*,int eTextRep,const void*)
|
void(*)(void*,sqlite3*,int eTextRep,const void*)
|
||||||
);
|
);
|
||||||
|
|
||||||
#ifdef SQLITE_HAS_CODEC
|
|
||||||
/*
|
|
||||||
** Specify the key for an encrypted database. This routine should be
|
|
||||||
** called right after sqlite3_open().
|
|
||||||
**
|
|
||||||
** The code to implement this API is not available in the public release
|
|
||||||
** of SQLite.
|
|
||||||
*/
|
|
||||||
SQLITE_API int sqlite3_key(
|
|
||||||
sqlite3 *db, /* Database to be rekeyed */
|
|
||||||
const void *pKey, int nKey /* The key */
|
|
||||||
);
|
|
||||||
SQLITE_API int sqlite3_key_v2(
|
|
||||||
sqlite3 *db, /* Database to be rekeyed */
|
|
||||||
const char *zDbName, /* Name of the database */
|
|
||||||
const void *pKey, int nKey /* The key */
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Change the key on an open database. If the current database is not
|
|
||||||
** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the
|
|
||||||
** database is decrypted.
|
|
||||||
**
|
|
||||||
** The code to implement this API is not available in the public release
|
|
||||||
** of SQLite.
|
|
||||||
*/
|
|
||||||
SQLITE_API int sqlite3_rekey(
|
|
||||||
sqlite3 *db, /* Database to be rekeyed */
|
|
||||||
const void *pKey, int nKey /* The new key */
|
|
||||||
);
|
|
||||||
SQLITE_API int sqlite3_rekey_v2(
|
|
||||||
sqlite3 *db, /* Database to be rekeyed */
|
|
||||||
const char *zDbName, /* Name of the database */
|
|
||||||
const void *pKey, int nKey /* The new key */
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Specify the activation key for a SEE database. Unless
|
|
||||||
** activated, none of the SEE routines will work.
|
|
||||||
*/
|
|
||||||
SQLITE_API void sqlite3_activate_see(
|
|
||||||
const char *zPassPhrase /* Activation phrase */
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SQLITE_ENABLE_CEROD
|
#ifdef SQLITE_ENABLE_CEROD
|
||||||
/*
|
/*
|
||||||
** Specify the activation key for a CEROD database. Unless
|
** Specify the activation key for a CEROD database. Unless
|
||||||
@@ -6100,6 +6187,57 @@ SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
|
|||||||
*/
|
*/
|
||||||
SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
|
SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** CAPI3REF: Determine the transaction state of a database
|
||||||
|
** METHOD: sqlite3
|
||||||
|
**
|
||||||
|
** ^The sqlite3_txn_state(D,S) interface returns the current
|
||||||
|
** [transaction state] of schema S in database connection D. ^If S is NULL,
|
||||||
|
** then the highest transaction state of any schema on database connection D
|
||||||
|
** is returned. Transaction states are (in order of lowest to highest):
|
||||||
|
** <ol>
|
||||||
|
** <li value="0"> SQLITE_TXN_NONE
|
||||||
|
** <li value="1"> SQLITE_TXN_READ
|
||||||
|
** <li value="2"> SQLITE_TXN_WRITE
|
||||||
|
** </ol>
|
||||||
|
** ^If the S argument to sqlite3_txn_state(D,S) is not the name of
|
||||||
|
** a valid schema, then -1 is returned.
|
||||||
|
*/
|
||||||
|
SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** CAPI3REF: Allowed return values from [sqlite3_txn_state()]
|
||||||
|
** KEYWORDS: {transaction state}
|
||||||
|
**
|
||||||
|
** These constants define the current transaction state of a database file.
|
||||||
|
** ^The [sqlite3_txn_state(D,S)] interface returns one of these
|
||||||
|
** constants in order to describe the transaction state of schema S
|
||||||
|
** in [database connection] D.
|
||||||
|
**
|
||||||
|
** <dl>
|
||||||
|
** [[SQLITE_TXN_NONE]] <dt>SQLITE_TXN_NONE</dt>
|
||||||
|
** <dd>The SQLITE_TXN_NONE state means that no transaction is currently
|
||||||
|
** pending.</dd>
|
||||||
|
**
|
||||||
|
** [[SQLITE_TXN_READ]] <dt>SQLITE_TXN_READ</dt>
|
||||||
|
** <dd>The SQLITE_TXN_READ state means that the database is currently
|
||||||
|
** in a read transaction. Content has been read from the database file
|
||||||
|
** but nothing in the database file has changed. The transaction state
|
||||||
|
** will advanced to SQLITE_TXN_WRITE if any changes occur and there are
|
||||||
|
** no other conflicting concurrent write transactions. The transaction
|
||||||
|
** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or
|
||||||
|
** [COMMIT].</dd>
|
||||||
|
**
|
||||||
|
** [[SQLITE_TXN_WRITE]] <dt>SQLITE_TXN_WRITE</dt>
|
||||||
|
** <dd>The SQLITE_TXN_WRITE state means that the database is currently
|
||||||
|
** in a write transaction. Content has been written to the database file
|
||||||
|
** but has not yet committed. The transaction state will change to
|
||||||
|
** to SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].</dd>
|
||||||
|
*/
|
||||||
|
#define SQLITE_TXN_NONE 0
|
||||||
|
#define SQLITE_TXN_READ 1
|
||||||
|
#define SQLITE_TXN_WRITE 2
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Find the next prepared statement
|
** CAPI3REF: Find the next prepared statement
|
||||||
** METHOD: sqlite3
|
** METHOD: sqlite3
|
||||||
@@ -6190,7 +6328,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
|
|||||||
** ^In the case of an update, this is the [rowid] after the update takes place.
|
** ^In the case of an update, this is the [rowid] after the update takes place.
|
||||||
**
|
**
|
||||||
** ^(The update hook is not invoked when internal system tables are
|
** ^(The update hook is not invoked when internal system tables are
|
||||||
** modified (i.e. sqlite_master and sqlite_sequence).)^
|
** modified (i.e. sqlite_sequence).)^
|
||||||
** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified.
|
** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified.
|
||||||
**
|
**
|
||||||
** ^In the current implementation, the update hook
|
** ^In the current implementation, the update hook
|
||||||
@@ -7292,7 +7430,7 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
|
|||||||
** <ul>
|
** <ul>
|
||||||
** <li> SQLITE_MUTEX_FAST
|
** <li> SQLITE_MUTEX_FAST
|
||||||
** <li> SQLITE_MUTEX_RECURSIVE
|
** <li> SQLITE_MUTEX_RECURSIVE
|
||||||
** <li> SQLITE_MUTEX_STATIC_MASTER
|
** <li> SQLITE_MUTEX_STATIC_MAIN
|
||||||
** <li> SQLITE_MUTEX_STATIC_MEM
|
** <li> SQLITE_MUTEX_STATIC_MEM
|
||||||
** <li> SQLITE_MUTEX_STATIC_OPEN
|
** <li> SQLITE_MUTEX_STATIC_OPEN
|
||||||
** <li> SQLITE_MUTEX_STATIC_PRNG
|
** <li> SQLITE_MUTEX_STATIC_PRNG
|
||||||
@@ -7494,7 +7632,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
|
|||||||
*/
|
*/
|
||||||
#define SQLITE_MUTEX_FAST 0
|
#define SQLITE_MUTEX_FAST 0
|
||||||
#define SQLITE_MUTEX_RECURSIVE 1
|
#define SQLITE_MUTEX_RECURSIVE 1
|
||||||
#define SQLITE_MUTEX_STATIC_MASTER 2
|
#define SQLITE_MUTEX_STATIC_MAIN 2
|
||||||
#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */
|
#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */
|
||||||
#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */
|
#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */
|
||||||
#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */
|
#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */
|
||||||
@@ -7509,6 +7647,10 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
|
|||||||
#define SQLITE_MUTEX_STATIC_VFS2 12 /* For use by extension VFS */
|
#define SQLITE_MUTEX_STATIC_VFS2 12 /* For use by extension VFS */
|
||||||
#define SQLITE_MUTEX_STATIC_VFS3 13 /* For use by application VFS */
|
#define SQLITE_MUTEX_STATIC_VFS3 13 /* For use by application VFS */
|
||||||
|
|
||||||
|
/* Legacy compatibility: */
|
||||||
|
#define SQLITE_MUTEX_STATIC_MASTER 2
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Retrieve the mutex for a database connection
|
** CAPI3REF: Retrieve the mutex for a database connection
|
||||||
** METHOD: sqlite3
|
** METHOD: sqlite3
|
||||||
@@ -7604,7 +7746,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
|
|||||||
#define SQLITE_TESTCTRL_PENDING_BYTE 11
|
#define SQLITE_TESTCTRL_PENDING_BYTE 11
|
||||||
#define SQLITE_TESTCTRL_ASSERT 12
|
#define SQLITE_TESTCTRL_ASSERT 12
|
||||||
#define SQLITE_TESTCTRL_ALWAYS 13
|
#define SQLITE_TESTCTRL_ALWAYS 13
|
||||||
#define SQLITE_TESTCTRL_RESERVE 14
|
#define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
|
||||||
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
|
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
|
||||||
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
|
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
|
||||||
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
|
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
|
||||||
@@ -7622,7 +7764,8 @@ SQLITE_API int sqlite3_test_control(int op, ...);
|
|||||||
#define SQLITE_TESTCTRL_RESULT_INTREAL 27
|
#define SQLITE_TESTCTRL_RESULT_INTREAL 27
|
||||||
#define SQLITE_TESTCTRL_PRNG_SEED 28
|
#define SQLITE_TESTCTRL_PRNG_SEED 28
|
||||||
#define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29
|
#define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29
|
||||||
#define SQLITE_TESTCTRL_LAST 29 /* Largest TESTCTRL */
|
#define SQLITE_TESTCTRL_SEEK_COUNT 30
|
||||||
|
#define SQLITE_TESTCTRL_LAST 30 /* Largest TESTCTRL */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: SQL Keyword Checking
|
** CAPI3REF: SQL Keyword Checking
|
||||||
@@ -9102,10 +9245,11 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
|
|||||||
** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
|
** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
|
||||||
**
|
**
|
||||||
** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
|
** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
|
||||||
** method of a [virtual table], then it returns true if and only if the
|
** method of a [virtual table], then it might return true if the
|
||||||
** column is being fetched as part of an UPDATE operation during which the
|
** column is being fetched as part of an UPDATE operation during which the
|
||||||
** column value will not change. Applications might use this to substitute
|
** column value will not change. The virtual table implementation can use
|
||||||
** a return value that is less expensive to compute and that the corresponding
|
** this hint as permission to substitute a return value that is less
|
||||||
|
** expensive to compute and that the corresponding
|
||||||
** [xUpdate] method understands as a "no-change" value.
|
** [xUpdate] method understands as a "no-change" value.
|
||||||
**
|
**
|
||||||
** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
|
** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
|
||||||
@@ -9114,6 +9258,12 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
|
|||||||
** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
|
** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
|
||||||
** In that case, [sqlite3_value_nochange(X)] will return true for the
|
** In that case, [sqlite3_value_nochange(X)] will return true for the
|
||||||
** same column in the [xUpdate] method.
|
** same column in the [xUpdate] method.
|
||||||
|
**
|
||||||
|
** The sqlite3_vtab_nochange() routine is an optimization. Virtual table
|
||||||
|
** implementations should continue to give a correct answer even if the
|
||||||
|
** sqlite3_vtab_nochange() interface were to always return false. In the
|
||||||
|
** current implementation, the sqlite3_vtab_nochange() interface does always
|
||||||
|
** returns false for the enhanced [UPDATE FROM] statement.
|
||||||
*/
|
*/
|
||||||
SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
|
SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
|
||||||
|
|
||||||
@@ -9255,6 +9405,7 @@ SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Flush caches to disk mid-transaction
|
** CAPI3REF: Flush caches to disk mid-transaction
|
||||||
|
** METHOD: sqlite3
|
||||||
**
|
**
|
||||||
** ^If a write-transaction is open on [database connection] D when the
|
** ^If a write-transaction is open on [database connection] D when the
|
||||||
** [sqlite3_db_cacheflush(D)] interface invoked, any dirty
|
** [sqlite3_db_cacheflush(D)] interface invoked, any dirty
|
||||||
@@ -9287,6 +9438,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: The pre-update hook.
|
** CAPI3REF: The pre-update hook.
|
||||||
|
** METHOD: sqlite3
|
||||||
**
|
**
|
||||||
** ^These interfaces are only available if SQLite is compiled using the
|
** ^These interfaces are only available if SQLite is compiled using the
|
||||||
** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option.
|
** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option.
|
||||||
@@ -9304,7 +9456,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
|
|||||||
**
|
**
|
||||||
** ^The preupdate hook only fires for changes to real database tables; the
|
** ^The preupdate hook only fires for changes to real database tables; the
|
||||||
** preupdate hook is not invoked for changes to [virtual tables] or to
|
** preupdate hook is not invoked for changes to [virtual tables] or to
|
||||||
** system tables like sqlite_master or sqlite_stat1.
|
** system tables like sqlite_sequence or sqlite_stat1.
|
||||||
**
|
**
|
||||||
** ^The second parameter to the preupdate callback is a pointer to
|
** ^The second parameter to the preupdate callback is a pointer to
|
||||||
** the [database connection] that registered the preupdate hook.
|
** the [database connection] that registered the preupdate hook.
|
||||||
@@ -9327,7 +9479,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
|
|||||||
** seventh parameter is the final rowid value of the row being inserted
|
** seventh parameter is the final rowid value of the row being inserted
|
||||||
** or updated. The value of the seventh parameter passed to the callback
|
** or updated. The value of the seventh parameter passed to the callback
|
||||||
** function is not defined for operations on WITHOUT ROWID tables, or for
|
** function is not defined for operations on WITHOUT ROWID tables, or for
|
||||||
** INSERT operations on rowid tables.
|
** DELETE operations on rowid tables.
|
||||||
**
|
**
|
||||||
** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()],
|
** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()],
|
||||||
** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces
|
** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces
|
||||||
@@ -9389,6 +9541,7 @@ SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Low-level system error code
|
** CAPI3REF: Low-level system error code
|
||||||
|
** METHOD: sqlite3
|
||||||
**
|
**
|
||||||
** ^Attempt to return the underlying operating system error code or error
|
** ^Attempt to return the underlying operating system error code or error
|
||||||
** number that caused the most recent I/O error or failure to open a file.
|
** number that caused the most recent I/O error or failure to open a file.
|
||||||
|
|||||||
13
src/libs/3rdparty/sqlite/sqlite3ext.h
vendored
@@ -330,6 +330,13 @@ struct sqlite3_api_routines {
|
|||||||
const char *(*filename_database)(const char*);
|
const char *(*filename_database)(const char*);
|
||||||
const char *(*filename_journal)(const char*);
|
const char *(*filename_journal)(const char*);
|
||||||
const char *(*filename_wal)(const char*);
|
const char *(*filename_wal)(const char*);
|
||||||
|
/* Version 3.32.0 and later */
|
||||||
|
char *(*create_filename)(const char*,const char*,const char*,
|
||||||
|
int,const char**);
|
||||||
|
void (*free_filename)(char*);
|
||||||
|
sqlite3_file *(*database_file_object)(const char*);
|
||||||
|
/* Version 3.34.0 and later */
|
||||||
|
int (*txn_state)(sqlite3*,const char*);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -630,6 +637,12 @@ typedef int (*sqlite3_loadext_entry)(
|
|||||||
#define sqlite3_filename_database sqlite3_api->filename_database
|
#define sqlite3_filename_database sqlite3_api->filename_database
|
||||||
#define sqlite3_filename_journal sqlite3_api->filename_journal
|
#define sqlite3_filename_journal sqlite3_api->filename_journal
|
||||||
#define sqlite3_filename_wal sqlite3_api->filename_wal
|
#define sqlite3_filename_wal sqlite3_api->filename_wal
|
||||||
|
/* Version 3.32.0 and later */
|
||||||
|
#define sqlite3_create_filename sqlite3_api->create_filename
|
||||||
|
#define sqlite3_free_filename sqlite3_api->free_filename
|
||||||
|
#define sqlite3_database_file_object sqlite3_api->database_file_object
|
||||||
|
/* Version 3.34.0 and later */
|
||||||
|
#define sqlite3_txn_state sqlite3_api->txn_state
|
||||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||||
|
|
||||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||||
|
|||||||
@@ -479,8 +479,8 @@ void Snapshot::insert(const Document::Ptr &document, bool allowInvalid)
|
|||||||
CoreImport cImport;
|
CoreImport cImport;
|
||||||
cImport.importId = document->importId();
|
cImport.importId = document->importId();
|
||||||
cImport.language = document->language();
|
cImport.language = document->language();
|
||||||
cImport.possibleExports << Export(ImportKey(ImportType::File, fileName),
|
cImport.addPossibleExport(Export(ImportKey(ImportType::File, fileName),
|
||||||
QString(), true, QFileInfo(fileName).baseName());
|
{}, true, QFileInfo(fileName).baseName()));
|
||||||
cImport.fingerprint = document->fingerprint();
|
cImport.fingerprint = document->fingerprint();
|
||||||
_dependencies.addCoreImport(cImport);
|
_dependencies.addCoreImport(cImport);
|
||||||
}
|
}
|
||||||
@@ -526,13 +526,13 @@ void Snapshot::insertLibraryInfo(const QString &path, const LibraryInfo &info)
|
|||||||
break;
|
break;
|
||||||
ImportKey iKey(ImportType::Library, QStringList(myPath.mid(iPath)).join(QLatin1Char('.')),
|
ImportKey iKey(ImportType::Library, QStringList(myPath.mid(iPath)).join(QLatin1Char('.')),
|
||||||
importKey.majorVersion, importKey.minorVersion);
|
importKey.majorVersion, importKey.minorVersion);
|
||||||
cImport.possibleExports.append(Export(iKey, (iPath == 1) ? QLatin1String("/") :
|
cImport.addPossibleExport(Export(iKey, (iPath == 1) ? QLatin1String("/") :
|
||||||
QStringList(myPath.mid(0, iPath)).join(QLatin1Char('/')), true));
|
QStringList(myPath.mid(0, iPath)).join(QLatin1Char('/')), true));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
QString requiredPath = QStringList(splitPath.mid(0, splitPath.size() - importKey.splitPath.size()))
|
QString requiredPath = QStringList(splitPath.mid(0, splitPath.size() - importKey.splitPath.size()))
|
||||||
.join(QLatin1String("/"));
|
.join(QLatin1String("/"));
|
||||||
cImport.possibleExports << Export(importKey, requiredPath, true);
|
cImport.addPossibleExport(Export(importKey, requiredPath, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cImport.possibleExports.isEmpty() && splitPath.size() > 0) {
|
if (cImport.possibleExports.isEmpty() && splitPath.size() > 0) {
|
||||||
@@ -567,7 +567,7 @@ void Snapshot::insertLibraryInfo(const QString &path, const LibraryInfo &info)
|
|||||||
break;
|
break;
|
||||||
ImportKey iKey(ImportType::Library, QStringList(splitPath.mid(iPath)).join(QLatin1Char('.')),
|
ImportKey iKey(ImportType::Library, QStringList(splitPath.mid(iPath)).join(QLatin1Char('.')),
|
||||||
majorVersion, minorVersion);
|
majorVersion, minorVersion);
|
||||||
cImport.possibleExports.append(Export(iKey, (iPath == 1) ? QLatin1String("/") :
|
cImport.addPossibleExport(Export(iKey, (iPath == 1) ? QLatin1String("/") :
|
||||||
QStringList(splitPath.mid(0, iPath)).join(QLatin1Char('/')), true));
|
QStringList(splitPath.mid(0, iPath)).join(QLatin1Char('/')), true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,11 +32,35 @@
|
|||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QCryptographicHash>
|
#include <QCryptographicHash>
|
||||||
|
#include <QElapsedTimer>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
static Q_LOGGING_CATEGORY(importsLog, "qtc.qmljs.imports", QtWarningMsg)
|
static Q_LOGGING_CATEGORY(importsLog, "qtc.qmljs.imports", QtWarningMsg)
|
||||||
|
static Q_LOGGING_CATEGORY(importsBenchmark, "qtc.qmljs.imports.benchmark", QtDebugMsg)
|
||||||
|
|
||||||
|
|
||||||
|
class ImportsBenchmarker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImportsBenchmarker(const QString &functionName)
|
||||||
|
: m_functionName(functionName)
|
||||||
|
{
|
||||||
|
m_timer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
~ImportsBenchmarker()
|
||||||
|
{
|
||||||
|
if (importsBenchmark().isDebugEnabled()) {
|
||||||
|
qCDebug(importsBenchmark).noquote().nospace() << m_functionName << " executed nPossibleExports: " << nPossibleExports << " in " << m_timer.elapsed() << "ms";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int nPossibleExports = 0;
|
||||||
|
|
||||||
|
QElapsedTimer m_timer;
|
||||||
|
QString m_functionName;
|
||||||
|
};
|
||||||
|
|
||||||
namespace QmlJS {
|
namespace QmlJS {
|
||||||
|
|
||||||
@@ -304,7 +328,7 @@ ImportMatchStrength ImportKey::matchImport(const ImportKey &o, const ViewerConte
|
|||||||
return ImportMatchStrength();
|
return ImportMatchStrength();
|
||||||
const QString p1 = splitPath.at(iPath1);
|
const QString p1 = splitPath.at(iPath1);
|
||||||
if (iPath2 < lenPath2) {
|
if (iPath2 < lenPath2) {
|
||||||
const QString p2 = splitPath.at(iPath2);
|
const QString p2 = o.splitPath.at(iPath2);
|
||||||
if (p1 == p2) {
|
if (p1 == p2) {
|
||||||
++iPath1;
|
++iPath1;
|
||||||
++iPath2;
|
++iPath2;
|
||||||
@@ -520,19 +544,6 @@ bool Export::visibleInVContext(const ViewerContext &vContext) const
|
|||||||
return pathRequired.isEmpty() || vContext.paths.contains(pathRequired);
|
return pathRequired.isEmpty() || vContext.paths.contains(pathRequired);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator ==(const Export &i1, const Export &i2)
|
|
||||||
{
|
|
||||||
return i1.exportName == i2.exportName
|
|
||||||
&& i1.pathRequired == i2.pathRequired
|
|
||||||
&& i1.intrinsic == i2.intrinsic
|
|
||||||
&& i1.typeName == i2.typeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator !=(const Export &i1, const Export &i2)
|
|
||||||
{
|
|
||||||
return !(i1 == i2);
|
|
||||||
}
|
|
||||||
|
|
||||||
CoreImport::CoreImport() : language(Dialect::Qml) { }
|
CoreImport::CoreImport() : language(Dialect::Qml) { }
|
||||||
|
|
||||||
CoreImport::CoreImport(const QString &importId, const QList<Export> &possibleExports,
|
CoreImport::CoreImport(const QString &importId, const QList<Export> &possibleExports,
|
||||||
@@ -609,6 +620,7 @@ ImportDependencies::~ImportDependencies()
|
|||||||
|
|
||||||
void ImportDependencies::filter(const ViewerContext &vContext)
|
void ImportDependencies::filter(const ViewerContext &vContext)
|
||||||
{
|
{
|
||||||
|
ImportsBenchmarker benchMark("filter()");
|
||||||
QMap<QString, CoreImport> newCoreImports;
|
QMap<QString, CoreImport> newCoreImports;
|
||||||
QMap<ImportKey, QStringList> newImportCache;
|
QMap<ImportKey, QStringList> newImportCache;
|
||||||
bool hasChanges = false;
|
bool hasChanges = false;
|
||||||
@@ -617,6 +629,7 @@ void ImportDependencies::filter(const ViewerContext &vContext)
|
|||||||
if (languageIsCompatible(vContext.language, cImport.language)) {
|
if (languageIsCompatible(vContext.language, cImport.language)) {
|
||||||
QList<Export> newExports;
|
QList<Export> newExports;
|
||||||
foreach (const Export &e, cImport.possibleExports) {
|
foreach (const Export &e, cImport.possibleExports) {
|
||||||
|
++benchMark.nPossibleExports;
|
||||||
if (e.visibleInVContext(vContext)) {
|
if (e.visibleInVContext(vContext)) {
|
||||||
newExports.append(e);
|
newExports.append(e);
|
||||||
QStringList &candidateImports = newImportCache[e.exportName];
|
QStringList &candidateImports = newImportCache[e.exportName];
|
||||||
@@ -654,6 +667,7 @@ void ImportDependencies::iterateOnCandidateImports(
|
|||||||
std::function<bool (const ImportMatchStrength &,const Export &,const CoreImport &)>
|
std::function<bool (const ImportMatchStrength &,const Export &,const CoreImport &)>
|
||||||
const &iterF) const
|
const &iterF) const
|
||||||
{
|
{
|
||||||
|
ImportsBenchmarker benchMark("iterateOnCandidateImports()");
|
||||||
switch (key.type) {
|
switch (key.type) {
|
||||||
case ImportType::Directory:
|
case ImportType::Directory:
|
||||||
case ImportType::QrcDirectory:
|
case ImportType::QrcDirectory:
|
||||||
@@ -666,6 +680,7 @@ void ImportDependencies::iterateOnCandidateImports(
|
|||||||
CoreImport cImport = coreImport(cImportName);
|
CoreImport cImport = coreImport(cImportName);
|
||||||
if (languageIsCompatible(vContext.language, cImport.language)) {
|
if (languageIsCompatible(vContext.language, cImport.language)) {
|
||||||
foreach (const Export e, cImport.possibleExports) {
|
foreach (const Export e, cImport.possibleExports) {
|
||||||
|
++benchMark.nPossibleExports;
|
||||||
if (e.visibleInVContext(vContext)) {
|
if (e.visibleInVContext(vContext)) {
|
||||||
ImportMatchStrength m = e.exportName.matchImport(key, vContext);
|
ImportMatchStrength m = e.exportName.matchImport(key, vContext);
|
||||||
if (m.hasMatch()) {
|
if (m.hasMatch()) {
|
||||||
@@ -688,6 +703,7 @@ void ImportDependencies::iterateOnCandidateImports(
|
|||||||
CoreImport cImport = coreImport(cImportName);
|
CoreImport cImport = coreImport(cImportName);
|
||||||
if (languageIsCompatible(vContext.language, cImport.language)) {
|
if (languageIsCompatible(vContext.language, cImport.language)) {
|
||||||
foreach (const Export e, cImport.possibleExports) {
|
foreach (const Export e, cImport.possibleExports) {
|
||||||
|
++benchMark.nPossibleExports;
|
||||||
if (e.visibleInVContext(vContext)) {
|
if (e.visibleInVContext(vContext)) {
|
||||||
ImportMatchStrength m = e.exportName.matchImport(key, vContext);
|
ImportMatchStrength m = e.exportName.matchImport(key, vContext);
|
||||||
if (m.hasMatch()) {
|
if (m.hasMatch()) {
|
||||||
@@ -810,13 +826,13 @@ void ImportDependencies::addExport(const QString &importId, const ImportKey &imp
|
|||||||
if (!m_coreImports.contains(importId)) {
|
if (!m_coreImports.contains(importId)) {
|
||||||
CoreImport newImport(importId);
|
CoreImport newImport(importId);
|
||||||
newImport.language = Dialect::AnyLanguage;
|
newImport.language = Dialect::AnyLanguage;
|
||||||
newImport.possibleExports.append(Export(importKey, requiredPath, false, typeName));
|
newImport.addPossibleExport(Export(importKey, requiredPath, false, typeName));
|
||||||
m_coreImports.insert(newImport.importId, newImport);
|
m_coreImports.insert(newImport.importId, newImport);
|
||||||
m_importCache[importKey].append(importId);
|
m_importCache[importKey].append(importId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CoreImport &importValue = m_coreImports[importId];
|
CoreImport &importValue = m_coreImports[importId];
|
||||||
importValue.possibleExports.append(Export(importKey, requiredPath, false, typeName));
|
importValue.addPossibleExport(Export(importKey, requiredPath, false, typeName));
|
||||||
m_importCache[importKey].append(importId);
|
m_importCache[importKey].append(importId);
|
||||||
qCDebug(importsLog) << "added export "<< importKey.toString() << " for id " <<importId
|
qCDebug(importsLog) << "added export "<< importKey.toString() << " for id " <<importId
|
||||||
<< " (" << requiredPath << ")";
|
<< " (" << requiredPath << ")";
|
||||||
@@ -853,6 +869,8 @@ void ImportDependencies::iterateOnLibraryImports(
|
|||||||
const Export &,
|
const Export &,
|
||||||
const CoreImport &)> const &iterF) const
|
const CoreImport &)> const &iterF) const
|
||||||
{
|
{
|
||||||
|
ImportsBenchmarker benchMark("iterateOnLibraryImports()");
|
||||||
|
|
||||||
typedef QMap<ImportKey, QStringList>::const_iterator iter_t;
|
typedef QMap<ImportKey, QStringList>::const_iterator iter_t;
|
||||||
ImportKey firstLib;
|
ImportKey firstLib;
|
||||||
firstLib.type = ImportType::Library;
|
firstLib.type = ImportType::Library;
|
||||||
@@ -864,6 +882,7 @@ void ImportDependencies::iterateOnLibraryImports(
|
|||||||
CoreImport cImport = coreImport(cImportName);
|
CoreImport cImport = coreImport(cImportName);
|
||||||
if (languageIsCompatible(vContext.language, cImport.language)) {
|
if (languageIsCompatible(vContext.language, cImport.language)) {
|
||||||
foreach (const Export &e, cImport.possibleExports) {
|
foreach (const Export &e, cImport.possibleExports) {
|
||||||
|
++benchMark.nPossibleExports;
|
||||||
if (e.visibleInVContext(vContext) && e.exportName.type == ImportType::Library) {
|
if (e.visibleInVContext(vContext) && e.exportName.type == ImportType::Library) {
|
||||||
ImportMatchStrength m = e.exportName.matchImport(i.key(), vContext);
|
ImportMatchStrength m = e.exportName.matchImport(i.key(), vContext);
|
||||||
if (m.hasMatch()) {
|
if (m.hasMatch()) {
|
||||||
@@ -887,6 +906,7 @@ void ImportDependencies::iterateOnSubImports(
|
|||||||
const Export &,
|
const Export &,
|
||||||
const CoreImport &)> const &iterF) const
|
const CoreImport &)> const &iterF) const
|
||||||
{
|
{
|
||||||
|
ImportsBenchmarker benchMark("iterateOnSubImports()");
|
||||||
typedef QMap<ImportKey, QStringList>::const_iterator iter_t;
|
typedef QMap<ImportKey, QStringList>::const_iterator iter_t;
|
||||||
iter_t i = m_importCache.lowerBound(baseKey);
|
iter_t i = m_importCache.lowerBound(baseKey);
|
||||||
iter_t end = m_importCache.constEnd();
|
iter_t end = m_importCache.constEnd();
|
||||||
@@ -898,6 +918,7 @@ void ImportDependencies::iterateOnSubImports(
|
|||||||
CoreImport cImport = coreImport(cImportName);
|
CoreImport cImport = coreImport(cImportName);
|
||||||
if (languageIsCompatible(vContext.language, cImport.language)) {
|
if (languageIsCompatible(vContext.language, cImport.language)) {
|
||||||
foreach (const Export &e, cImport.possibleExports) {
|
foreach (const Export &e, cImport.possibleExports) {
|
||||||
|
++benchMark.nPossibleExports;
|
||||||
if (e.visibleInVContext(vContext)) {
|
if (e.visibleInVContext(vContext)) {
|
||||||
ImportMatchStrength m = e.exportName.matchImport(i.key(), vContext);
|
ImportMatchStrength m = e.exportName.matchImport(i.key(), vContext);
|
||||||
if (m.hasMatch()) {
|
if (m.hasMatch()) {
|
||||||
|
|||||||
@@ -134,9 +134,27 @@ public:
|
|||||||
QString typeName;
|
QString typeName;
|
||||||
bool intrinsic;
|
bool intrinsic;
|
||||||
bool visibleInVContext(const ViewerContext &vContext) const;
|
bool visibleInVContext(const ViewerContext &vContext) const;
|
||||||
|
|
||||||
|
|
||||||
|
friend bool operator==(const Export &i1, const Export &i2)
|
||||||
|
{
|
||||||
|
return i1.exportName == i2.exportName
|
||||||
|
&& i1.pathRequired == i2.pathRequired
|
||||||
|
&& i1.intrinsic == i2.intrinsic
|
||||||
|
&& i1.typeName == i2.typeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const Export &i1, const Export &i2)
|
||||||
|
{
|
||||||
|
return !(i1 == i2);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator<(const Export &i1, const Export &i2)
|
||||||
|
{
|
||||||
|
return std::tie(i1.intrinsic, i1.pathRequired, i1.typeName, i1.exportName)
|
||||||
|
< std::tie(i2.intrinsic, i2.pathRequired, i2.typeName, i2.exportName);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
bool operator ==(const Export &i1, const Export &i2);
|
|
||||||
bool operator !=(const Export &i1, const Export &i2);
|
|
||||||
|
|
||||||
class QMLJS_EXPORT CoreImport
|
class QMLJS_EXPORT CoreImport
|
||||||
{
|
{
|
||||||
@@ -144,6 +162,14 @@ public:
|
|||||||
CoreImport();
|
CoreImport();
|
||||||
CoreImport(const QString &importId, const QList<Export> &possibleExports = QList<Export>(),
|
CoreImport(const QString &importId, const QList<Export> &possibleExports = QList<Export>(),
|
||||||
Dialect language = Dialect::Qml, const QByteArray &fingerprint = QByteArray());
|
Dialect language = Dialect::Qml, const QByteArray &fingerprint = QByteArray());
|
||||||
|
template<typename E>
|
||||||
|
void addPossibleExport(E &&e)
|
||||||
|
{
|
||||||
|
auto found = std::lower_bound(possibleExports.begin(), possibleExports.end(), e);
|
||||||
|
if (found == possibleExports.end() || e != *found)
|
||||||
|
possibleExports.insert(found, std::forward<E>(e));
|
||||||
|
}
|
||||||
|
|
||||||
QString importId;
|
QString importId;
|
||||||
QList<Export> possibleExports;
|
QList<Export> possibleExports;
|
||||||
Dialect language;
|
Dialect language;
|
||||||
|
|||||||
@@ -446,12 +446,10 @@ std::string collectOutput()
|
|||||||
// Add a child to messages for every line.
|
// Add a child to messages for every line.
|
||||||
while (std::getline(pyStdout, line)) {
|
while (std::getline(pyStdout, line)) {
|
||||||
// there are two kinds of messages we want to handle here:
|
// there are two kinds of messages we want to handle here:
|
||||||
if (line.find("bridgemessage=") == 0) { // preformatted gdmi bridgemessages from warn()
|
if (line.find("bridgemessage=") == 0) // preformatted gdmi bridgemessages from warn()
|
||||||
ret << line << ',';
|
ret << line << ',';
|
||||||
} else { // and a line of "normal" python output
|
else // and a line of "normal" python output
|
||||||
replace(line, '"', '$'); // otherwise creators gdbmi parser would fail
|
ret << "line=\"" << gdbmiStringFormat(line) << "\",";
|
||||||
ret << "line=\"" << line << "\",";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ret << "]," << results << "]";
|
ret << "]," << results << "]";
|
||||||
results.clear();
|
results.clear();
|
||||||
|
|||||||
@@ -38,6 +38,14 @@
|
|||||||
# pragma GCC diagnostic ignored "-Wignored-qualifiers"
|
# pragma GCC diagnostic ignored "-Wignored-qualifiers"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define CARRAY_INT32 0 /* Data is 32-bit signed integers */
|
||||||
|
#define CARRAY_INT64 1 /* Data is 64-bit signed integers */
|
||||||
|
#define CARRAY_DOUBLE 2 /* Data is doubles */
|
||||||
|
#define CARRAY_TEXT 3 /* Data is char* */
|
||||||
|
|
||||||
|
extern "C" int sqlite3_carray_bind(
|
||||||
|
sqlite3_stmt *pStmt, int idx, void *aData, int nData, int mFlags, void (*xDestroy)(void *));
|
||||||
|
|
||||||
namespace Sqlite {
|
namespace Sqlite {
|
||||||
|
|
||||||
BaseStatement::BaseStatement(Utils::SmallStringView sqlStatement, Database &database)
|
BaseStatement::BaseStatement(Utils::SmallStringView sqlStatement, Database &database)
|
||||||
@@ -180,6 +188,54 @@ void BaseStatement::bind(int index, void *pointer)
|
|||||||
checkForBindingError(resultCode);
|
checkForBindingError(resultCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BaseStatement::bind(int index, Utils::span<int> values)
|
||||||
|
{
|
||||||
|
int resultCode = sqlite3_carray_bind(m_compiledStatement.get(),
|
||||||
|
index,
|
||||||
|
values.data(),
|
||||||
|
static_cast<int>(values.size()),
|
||||||
|
CARRAY_INT32,
|
||||||
|
SQLITE_STATIC);
|
||||||
|
if (resultCode != SQLITE_OK)
|
||||||
|
checkForBindingError(resultCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseStatement::bind(int index, Utils::span<long long> values)
|
||||||
|
{
|
||||||
|
int resultCode = sqlite3_carray_bind(m_compiledStatement.get(),
|
||||||
|
index,
|
||||||
|
values.data(),
|
||||||
|
static_cast<int>(values.size()),
|
||||||
|
CARRAY_INT64,
|
||||||
|
SQLITE_STATIC);
|
||||||
|
if (resultCode != SQLITE_OK)
|
||||||
|
checkForBindingError(resultCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseStatement::bind(int index, Utils::span<double> values)
|
||||||
|
{
|
||||||
|
int resultCode = sqlite3_carray_bind(m_compiledStatement.get(),
|
||||||
|
index,
|
||||||
|
values.data(),
|
||||||
|
static_cast<int>(values.size()),
|
||||||
|
CARRAY_DOUBLE,
|
||||||
|
SQLITE_STATIC);
|
||||||
|
if (resultCode != SQLITE_OK)
|
||||||
|
checkForBindingError(resultCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseStatement::bind(int index, Utils::span<const char *> values)
|
||||||
|
{
|
||||||
|
int resultCode = sqlite3_carray_bind(m_compiledStatement.get(),
|
||||||
|
index,
|
||||||
|
values.data(),
|
||||||
|
static_cast<int>(values.size()),
|
||||||
|
CARRAY_TEXT,
|
||||||
|
SQLITE_STATIC);
|
||||||
|
if (resultCode != SQLITE_OK)
|
||||||
|
checkForBindingError(resultCode);
|
||||||
|
}
|
||||||
|
|
||||||
void BaseStatement::bind(int index, Utils::SmallStringView text)
|
void BaseStatement::bind(int index, Utils::SmallStringView text)
|
||||||
{
|
{
|
||||||
int resultCode = sqlite3_bind_text(m_compiledStatement.get(),
|
int resultCode = sqlite3_bind_text(m_compiledStatement.get(),
|
||||||
|
|||||||
@@ -77,12 +77,16 @@ public:
|
|||||||
int columnCount() const;
|
int columnCount() const;
|
||||||
|
|
||||||
void bind(int index, NullValue);
|
void bind(int index, NullValue);
|
||||||
void bind(int index, int fetchValue);
|
void bind(int index, int value);
|
||||||
void bind(int index, long long fetchValue);
|
void bind(int index, long long value);
|
||||||
void bind(int index, double fetchValue);
|
void bind(int index, double value);
|
||||||
void bind(int index, void *pointer);
|
void bind(int index, void *pointer);
|
||||||
void bind(int index, Utils::SmallStringView fetchValue);
|
void bind(int index, Utils::span<int> values);
|
||||||
void bind(int index, const Value &fetchValue);
|
void bind(int index, Utils::span<long long> values);
|
||||||
|
void bind(int index, Utils::span<double> values);
|
||||||
|
void bind(int index, Utils::span<const char *> values);
|
||||||
|
void bind(int index, Utils::SmallStringView value);
|
||||||
|
void bind(int index, const Value &value);
|
||||||
void bind(int index, BlobView blobView);
|
void bind(int index, BlobView blobView);
|
||||||
|
|
||||||
void bind(int index, uint value) { bind(index, static_cast<long long>(value)); }
|
void bind(int index, uint value) { bind(index, static_cast<long long>(value)); }
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ DatabaseBackend::~DatabaseBackend()
|
|||||||
closeWithoutException();
|
closeWithoutException();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseBackend::setMmapSize(qint64 defaultSize, qint64 maximumSize)
|
void DatabaseBackend::setRanslatorentriesapSize(qint64 defaultSize, qint64 maximumSize)
|
||||||
{
|
{
|
||||||
int resultCode = sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, defaultSize, maximumSize);
|
int resultCode = sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, defaultSize, maximumSize);
|
||||||
checkMmapSizeIsSet(resultCode);
|
checkMmapSizeIsSet(resultCode);
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public:
|
|||||||
DatabaseBackend(DatabaseBackend &&) = delete;
|
DatabaseBackend(DatabaseBackend &&) = delete;
|
||||||
DatabaseBackend &operator=(DatabaseBackend &&) = delete;
|
DatabaseBackend &operator=(DatabaseBackend &&) = delete;
|
||||||
|
|
||||||
static void setMmapSize(qint64 defaultSize, qint64 maximumSize);
|
static void setRanslatorentriesapSize(qint64 defaultSize, qint64 maximumSize);
|
||||||
static void activateMultiThreading();
|
static void activateMultiThreading();
|
||||||
static void activateLogging();
|
static void activateLogging();
|
||||||
static void initializeSqliteLibrary();
|
static void initializeSqliteLibrary();
|
||||||
|
|||||||
@@ -13,3 +13,8 @@ add_qtc_plugin(ClangFormat
|
|||||||
clangformatsettings.cpp clangformatsettings.h
|
clangformatsettings.cpp clangformatsettings.h
|
||||||
clangformatutils.cpp clangformatutils.h
|
clangformatutils.cpp clangformatutils.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
extend_qtc_plugin(ClangFormat
|
||||||
|
CONDITION UNIX AND NOT APPLE
|
||||||
|
PROPERTIES LINK_FLAGS "-Wl,--exclude-libs,ALL"
|
||||||
|
)
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ void DocumentClangToolRunner::runNext()
|
|||||||
auto [clangIncludeDir, clangVersion] = getClangIncludeDirAndVersion(m_currentRunner.get());
|
auto [clangIncludeDir, clangVersion] = getClangIncludeDirAndVersion(m_currentRunner.get());
|
||||||
qCDebug(LOG) << Q_FUNC_INFO << m_currentRunner->executable() << clangIncludeDir
|
qCDebug(LOG) << Q_FUNC_INFO << m_currentRunner->executable() << clangIncludeDir
|
||||||
<< clangVersion << m_fileInfo.file;
|
<< clangVersion << m_fileInfo.file;
|
||||||
if (clangIncludeDir.isEmpty() || clangVersion.isEmpty()
|
if (m_currentRunner->executable().isEmpty() || clangIncludeDir.isEmpty() || clangVersion.isEmpty()
|
||||||
|| (m_document->isModified() && !m_currentRunner->supportsVFSOverlay())) {
|
|| (m_document->isModified() && !m_currentRunner->supportsVFSOverlay())) {
|
||||||
runNext();
|
runNext();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -4119,10 +4119,7 @@ void GdbEngine::setupInferior()
|
|||||||
if (symbolFile.isEmpty()) {
|
if (symbolFile.isEmpty()) {
|
||||||
showMessage(tr("No symbol file given."), StatusBar);
|
showMessage(tr("No symbol file given."), StatusBar);
|
||||||
callTargetRemote();
|
callTargetRemote();
|
||||||
return;
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
if (!symbolFile.isEmpty()) {
|
|
||||||
runCommand({"-file-exec-and-symbols \"" + symbolFile + '"',
|
runCommand({"-file-exec-and-symbols \"" + symbolFile + '"',
|
||||||
CB(handleFileExecAndSymbols)});
|
CB(handleFileExecAndSymbols)});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,14 +60,8 @@ extend_qtc_plugin(Help
|
|||||||
webenginehelpviewer.h
|
webenginehelpviewer.h
|
||||||
)
|
)
|
||||||
|
|
||||||
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/qlitehtml/litehtml/CMakeLists.txt)
|
find_package(litehtml QUIET)
|
||||||
add_subdirectory(qlitehtml)
|
add_subdirectory(qlitehtml)
|
||||||
else()
|
|
||||||
find_package(litehtml QUIET)
|
|
||||||
if (TARGET litehtml)
|
|
||||||
add_subdirectory(qlitehtml)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
extend_qtc_plugin(Help
|
extend_qtc_plugin(Help
|
||||||
CONDITION TARGET litehtml AND TARGET qlitehtml
|
CONDITION TARGET litehtml AND TARGET qlitehtml
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/litehtml/CMakeLists.txt)
|
find_package(litehtml QUIET)
|
||||||
|
if(NOT TARGET litehtml AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/litehtml/CMakeLists.txt)
|
||||||
set(ORIG_FPIC ${CMAKE_POSITION_INDEPENDENT_CODE})
|
set(ORIG_FPIC ${CMAKE_POSITION_INDEPENDENT_CODE})
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
set(LITEHTML_UTF8 ON CACHE BOOL "")
|
set(LITEHTML_UTF8 ON CACHE BOOL "")
|
||||||
@@ -16,11 +17,10 @@ if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/litehtml/CMakeLists.txt)
|
|||||||
target_compile_options(litehtml PRIVATE -O2)
|
target_compile_options(litehtml PRIVATE -O2)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
else()
|
|
||||||
find_package(litehtml REQUIRED)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_qtc_library(qlitehtml
|
add_qtc_library(qlitehtml
|
||||||
|
CONDITION TARGET litehtml
|
||||||
PUBLIC_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}
|
PUBLIC_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
DEPENDS Qt5::Widgets litehtml
|
DEPENDS Qt5::Widgets litehtml
|
||||||
PROPERTIES
|
PROPERTIES
|
||||||
|
|||||||
@@ -417,6 +417,22 @@ QWidget *MakeStep::createConfigWidget()
|
|||||||
return widget;
|
return widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MakeStep::buildsTarget(const QString &target) const
|
||||||
|
{
|
||||||
|
return m_buildTargetsAspect->value().contains(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakeStep::setBuildTarget(const QString &target, bool on)
|
||||||
|
{
|
||||||
|
QStringList old = m_buildTargetsAspect->value();
|
||||||
|
if (on && !old.contains(target))
|
||||||
|
old << target;
|
||||||
|
else if (!on && old.contains(target))
|
||||||
|
old.removeOne(target);
|
||||||
|
|
||||||
|
m_buildTargetsAspect->setValue(old);
|
||||||
|
}
|
||||||
|
|
||||||
QStringList MakeStep::availableTargets() const
|
QStringList MakeStep::availableTargets() const
|
||||||
{
|
{
|
||||||
return m_buildTargetsAspect->allValues();
|
return m_buildTargetsAspect->allValues();
|
||||||
|
|||||||
@@ -78,6 +78,11 @@ public:
|
|||||||
|
|
||||||
Utils::Environment makeEnvironment() const;
|
Utils::Environment makeEnvironment() const;
|
||||||
|
|
||||||
|
// FIXME: All unused, remove in 4.15.
|
||||||
|
void setBuildTarget(const QString &buildTarget) { setSelectedBuildTarget(buildTarget); }
|
||||||
|
bool buildsTarget(const QString &target) const;
|
||||||
|
void setBuildTarget(const QString &target, bool on);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void supportDisablingForSubdirs() { m_disablingForSubDirsSupported = true; }
|
void supportDisablingForSubdirs() { m_disablingForSubDirsSupported = true; }
|
||||||
virtual QStringList displayArguments() const;
|
virtual QStringList displayArguments() const;
|
||||||
@@ -87,6 +92,7 @@ private:
|
|||||||
QStringList jobArguments() const;
|
QStringList jobArguments() const;
|
||||||
|
|
||||||
Utils::MultiSelectionAspect *m_buildTargetsAspect = nullptr;
|
Utils::MultiSelectionAspect *m_buildTargetsAspect = nullptr;
|
||||||
|
QStringList m_availableTargets; // FIXME: Unused, remove in 4.15.
|
||||||
Utils::StringAspect *m_makeCommandAspect = nullptr;
|
Utils::StringAspect *m_makeCommandAspect = nullptr;
|
||||||
Utils::StringAspect *m_userArgumentsAspect = nullptr;
|
Utils::StringAspect *m_userArgumentsAspect = nullptr;
|
||||||
Utils::AspectContainer *m_jobCountContainer = nullptr;
|
Utils::AspectContainer *m_jobCountContainer = nullptr;
|
||||||
|
|||||||
@@ -497,6 +497,7 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
include/qmlmodelnodefacade.h
|
include/qmlmodelnodefacade.h
|
||||||
include/qmlobjectnode.h
|
include/qmlobjectnode.h
|
||||||
include/qmlstate.h
|
include/qmlstate.h
|
||||||
|
include/qmlconnections.h
|
||||||
include/qmltimeline.h
|
include/qmltimeline.h
|
||||||
include/qmltimelinekeyframegroup.h
|
include/qmltimelinekeyframegroup.h
|
||||||
include/removebasestateexception.h
|
include/removebasestateexception.h
|
||||||
@@ -578,6 +579,7 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
model/qmlmodelnodefacade.cpp
|
model/qmlmodelnodefacade.cpp
|
||||||
model/qmlobjectnode.cpp
|
model/qmlobjectnode.cpp
|
||||||
model/qmlstate.cpp
|
model/qmlstate.cpp
|
||||||
|
model/qmlconnections.cpp
|
||||||
model/qmltextgenerator.cpp model/qmltextgenerator.h
|
model/qmltextgenerator.cpp model/qmltextgenerator.h
|
||||||
model/qmltimeline.cpp
|
model/qmltimeline.cpp
|
||||||
model/qmltimelinekeyframegroup.cpp
|
model/qmltimelinekeyframegroup.cpp
|
||||||
@@ -620,6 +622,9 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
bindingeditordialog.cpp bindingeditordialog.h
|
bindingeditordialog.cpp bindingeditordialog.h
|
||||||
bindingeditorwidget.cpp bindingeditorwidget.h
|
bindingeditorwidget.cpp bindingeditorwidget.h
|
||||||
connectionvisitor.cpp connectionvisitor.h
|
connectionvisitor.cpp connectionvisitor.h
|
||||||
|
signallist.cpp signallist.h
|
||||||
|
signallistdialog.cpp signallistdialog.h
|
||||||
|
signallistdelegate.cpp signallistdelegate.h
|
||||||
)
|
)
|
||||||
|
|
||||||
extend_qtc_plugin(QmlDesigner
|
extend_qtc_plugin(QmlDesigner
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ HEADERS += $$PWD/actioneditordialog.h
|
|||||||
HEADERS += $$PWD/bindingeditordialog.h
|
HEADERS += $$PWD/bindingeditordialog.h
|
||||||
HEADERS += $$PWD/bindingeditorwidget.h
|
HEADERS += $$PWD/bindingeditorwidget.h
|
||||||
HEADERS += $$PWD/connectionvisitor.h
|
HEADERS += $$PWD/connectionvisitor.h
|
||||||
|
HEADERS += $$PWD/signallist.h
|
||||||
|
HEADERS += $$PWD/signallistdialog.h
|
||||||
|
HEADERS += $$PWD/signallistdelegate.h
|
||||||
|
|
||||||
SOURCES += $$PWD/bindingeditor.cpp
|
SOURCES += $$PWD/bindingeditor.cpp
|
||||||
SOURCES += $$PWD/actioneditor.cpp
|
SOURCES += $$PWD/actioneditor.cpp
|
||||||
@@ -13,3 +16,6 @@ SOURCES += $$PWD/actioneditordialog.cpp
|
|||||||
SOURCES += $$PWD/bindingeditordialog.cpp
|
SOURCES += $$PWD/bindingeditordialog.cpp
|
||||||
SOURCES += $$PWD/bindingeditorwidget.cpp
|
SOURCES += $$PWD/bindingeditorwidget.cpp
|
||||||
SOURCES += $$PWD/connectionvisitor.cpp
|
SOURCES += $$PWD/connectionvisitor.cpp
|
||||||
|
SOURCES += $$PWD/signallist.cpp
|
||||||
|
SOURCES += $$PWD/signallistdialog.cpp
|
||||||
|
SOURCES += $$PWD/signallistdelegate.cpp
|
||||||
|
|||||||
328
src/plugins/qmldesigner/components/bindingeditor/signallist.cpp
Normal file
@@ -0,0 +1,328 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "signallist.h"
|
||||||
|
|
||||||
|
#include "signallistdelegate.h"
|
||||||
|
|
||||||
|
#include <qmldesignerplugin.h>
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
|
#include <metainfo.h>
|
||||||
|
|
||||||
|
#include <variantproperty.h>
|
||||||
|
#include <bindingproperty.h>
|
||||||
|
#include <signalhandlerproperty.h>
|
||||||
|
#include <qmldesignerconstants.h>
|
||||||
|
#include <qmlitemnode.h>
|
||||||
|
#include <nodeabstractproperty.h>
|
||||||
|
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
#include <QTableView>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
SignalListModel::SignalListModel(QObject *parent)
|
||||||
|
: QStandardItemModel(0, 3, parent)
|
||||||
|
{
|
||||||
|
setHeaderData(TargetColumn, Qt::Horizontal, tr("Item ID"));
|
||||||
|
setHeaderData(SignalColumn, Qt::Horizontal, tr("Signal"));
|
||||||
|
setHeaderData(ButtonColumn, Qt::Horizontal, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalListModel::setConnected(int row, bool connected)
|
||||||
|
{
|
||||||
|
for (int col = 0; col < columnCount(); ++col) {
|
||||||
|
QModelIndex idx = index(row, col);
|
||||||
|
setData(idx, connected, ConnectedRole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SignalListFilterModel::SignalListFilterModel(QObject *parent)
|
||||||
|
: QSortFilterProxyModel(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SignalListFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
||||||
|
{
|
||||||
|
QModelIndex targetIndex = sourceModel()->index(sourceRow, SignalListModel::TargetColumn, sourceParent);
|
||||||
|
QModelIndex signalIndex = sourceModel()->index(sourceRow, SignalListModel::SignalColumn, sourceParent);
|
||||||
|
|
||||||
|
return (sourceModel()->data(targetIndex).toString().contains(filterRegExp())
|
||||||
|
|| sourceModel()->data(signalIndex).toString().contains(filterRegExp()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PropertyNameList SignalList::st_mouseSignals = { "clicked", "doubleClicked", "pressAndHold",
|
||||||
|
"pressed", "released", "wheel" };
|
||||||
|
|
||||||
|
SignalList::SignalList(QObject *)
|
||||||
|
: m_dialog(QPointer<SignalListDialog>())
|
||||||
|
, m_model(new SignalListModel(this))
|
||||||
|
, m_modelNode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SignalList::~SignalList()
|
||||||
|
{
|
||||||
|
hideWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalList::prepareDialog()
|
||||||
|
{
|
||||||
|
m_dialog = new SignalListDialog(Core::ICore::dialogParent());
|
||||||
|
m_dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
m_dialog->initialize(m_model);
|
||||||
|
m_dialog->setWindowTitle(tr("Signal List for ") + m_modelNode.validId());
|
||||||
|
|
||||||
|
auto *delegate = static_cast<SignalListDelegate *>(m_dialog->tableView()->itemDelegate());
|
||||||
|
connect(delegate, &SignalListDelegate::connectClicked, this, &SignalList::connectClicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalList::showWidget()
|
||||||
|
{
|
||||||
|
prepareDialog();
|
||||||
|
m_dialog->show();
|
||||||
|
m_dialog->raise();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalList::hideWidget()
|
||||||
|
{
|
||||||
|
if (m_dialog)
|
||||||
|
m_dialog->close();
|
||||||
|
|
||||||
|
m_dialog = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SignalList* SignalList::showWidget(const ModelNode &modelNode)
|
||||||
|
{
|
||||||
|
auto signalList = new SignalList();
|
||||||
|
signalList->setModelNode(modelNode);
|
||||||
|
signalList->prepareSignals();
|
||||||
|
signalList->showWidget();
|
||||||
|
|
||||||
|
connect(signalList->m_dialog, &QDialog::destroyed,
|
||||||
|
[signalList]() { signalList->deleteLater(); } );
|
||||||
|
|
||||||
|
return signalList;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalList::setModelNode(const ModelNode &modelNode)
|
||||||
|
{
|
||||||
|
if (modelNode.isValid())
|
||||||
|
m_modelNode = modelNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalList::prepareSignals()
|
||||||
|
{
|
||||||
|
if (!m_modelNode.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
AbstractView *view = m_modelNode.view();
|
||||||
|
QList<QmlConnections> connections = getAssociatedConnections(view->allModelNodes());
|
||||||
|
|
||||||
|
for (ModelNode &node : view->allModelNodes()) {
|
||||||
|
// Collect all items which contain at least one of the specified signals
|
||||||
|
const PropertyNameList signalNames = node.metaInfo().signalNames();
|
||||||
|
// Put the signals into a QSet to avoid duplicates
|
||||||
|
auto signalNamesSet = QSet<PropertyName>(signalNames.begin(), signalNames.end());
|
||||||
|
for (const PropertyName &signal : signalNamesSet) {
|
||||||
|
if (st_mouseSignals.contains(signal))
|
||||||
|
appendSignalToModel(connections, node, signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gather valid properties and aliases from components
|
||||||
|
for (const PropertyName &property : node.metaInfo().propertyNames()) {
|
||||||
|
const TypeName propertyType = node.metaInfo().propertyTypeName(property);
|
||||||
|
const NodeMetaInfo info = m_modelNode.model()->metaInfo(propertyType);
|
||||||
|
// Collect all items which contain at least one of the specified signals
|
||||||
|
const PropertyNameList signalNames = info.signalNames();
|
||||||
|
// Put the signals into a QSet to avoid duplicates
|
||||||
|
auto signalNamesSet = QSet<PropertyName>(signalNames.begin(), signalNames.end());
|
||||||
|
for (const PropertyName &signal : signalNamesSet) {
|
||||||
|
if (st_mouseSignals.contains(signal))
|
||||||
|
appendSignalToModel(connections, node, signal, property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalList::connectClicked(const QModelIndex &modelIndex)
|
||||||
|
{
|
||||||
|
auto proxyModel = static_cast<const SignalListFilterModel *>(modelIndex.model());
|
||||||
|
QModelIndex mappedModelIndex = proxyModel->mapToSource(modelIndex);
|
||||||
|
bool connected = mappedModelIndex.data(SignalListModel::ConnectedRole).toBool();
|
||||||
|
|
||||||
|
if (!connected)
|
||||||
|
addConnection(mappedModelIndex);
|
||||||
|
else
|
||||||
|
removeConnection(mappedModelIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalList::appendSignalToModel(const QList<QmlConnections> &connections,
|
||||||
|
ModelNode &node,
|
||||||
|
const PropertyName &signal,
|
||||||
|
const PropertyName &property)
|
||||||
|
{
|
||||||
|
QStandardItem *idItem = new QStandardItem();
|
||||||
|
QString id(node.validId());
|
||||||
|
if (!property.isEmpty())
|
||||||
|
id += "." + QString::fromLatin1(property);
|
||||||
|
|
||||||
|
idItem->setData(id, Qt::DisplayRole);
|
||||||
|
|
||||||
|
QStandardItem *signalItem = new QStandardItem();
|
||||||
|
signalItem->setData(signal, Qt::DisplayRole);
|
||||||
|
|
||||||
|
QStandardItem *buttonItem = new QStandardItem();
|
||||||
|
|
||||||
|
idItem->setData(false, SignalListModel::ConnectedRole);
|
||||||
|
signalItem->setData(false, SignalListModel::ConnectedRole);
|
||||||
|
buttonItem->setData(false, SignalListModel::ConnectedRole);
|
||||||
|
|
||||||
|
for (const QmlConnections &connection : connections) {
|
||||||
|
if (connection.target() == id) {
|
||||||
|
for (const SignalHandlerProperty &property : connection.signalProperties()) {
|
||||||
|
auto signalWithoutPrefix = SignalHandlerProperty::prefixRemoved(property.name());
|
||||||
|
if (signalWithoutPrefix == signal) {
|
||||||
|
buttonItem->setData(connection.modelNode().internalId(),
|
||||||
|
SignalListModel::ConnectionsInternalIdRole);
|
||||||
|
|
||||||
|
idItem->setData(true, SignalListModel::ConnectedRole);
|
||||||
|
signalItem->setData(true, SignalListModel::ConnectedRole);
|
||||||
|
buttonItem->setData(true, SignalListModel::ConnectedRole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_model->appendRow({idItem, signalItem, buttonItem});
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalList::addConnection(const QModelIndex &modelIndex)
|
||||||
|
{
|
||||||
|
const QModelIndex targetModelIndex = modelIndex.siblingAtColumn(SignalListModel::TargetColumn);
|
||||||
|
const QModelIndex signalModelIndex = modelIndex.siblingAtColumn(SignalListModel::SignalColumn);
|
||||||
|
const QModelIndex buttonModelIndex = modelIndex.siblingAtColumn(SignalListModel::ButtonColumn);
|
||||||
|
const PropertyName signalName = m_model->data(signalModelIndex,
|
||||||
|
Qt::DisplayRole).toByteArray();
|
||||||
|
|
||||||
|
QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_CONNECTION_ADDED);
|
||||||
|
|
||||||
|
AbstractView *view = m_modelNode.view();
|
||||||
|
const ModelNode rootModelNode = view->rootModelNode();
|
||||||
|
|
||||||
|
if (rootModelNode.isValid() && rootModelNode.metaInfo().isValid()) {
|
||||||
|
NodeMetaInfo nodeMetaInfo = view->model()->metaInfo("QtQuick.Connections");
|
||||||
|
if (nodeMetaInfo.isValid()) {
|
||||||
|
view->executeInTransaction("ConnectionModel::addConnection", [=, &rootModelNode](){
|
||||||
|
ModelNode newNode = view->createModelNode("QtQuick.Connections",
|
||||||
|
nodeMetaInfo.majorVersion(),
|
||||||
|
nodeMetaInfo.minorVersion());
|
||||||
|
const QString source = m_modelNode.validId() + ".trigger()";
|
||||||
|
|
||||||
|
if (QmlItemNode::isValidQmlItemNode(m_modelNode))
|
||||||
|
m_modelNode.nodeAbstractProperty("data").reparentHere(newNode);
|
||||||
|
else
|
||||||
|
rootModelNode.nodeAbstractProperty(rootModelNode.metaInfo().defaultPropertyName()).reparentHere(newNode);
|
||||||
|
|
||||||
|
const QString expression = m_model->data(targetModelIndex, Qt::DisplayRole).toString();
|
||||||
|
newNode.bindingProperty("target").setExpression(expression);
|
||||||
|
newNode.signalHandlerProperty(SignalHandlerProperty::prefixAdded(signalName)).setSource(source);
|
||||||
|
|
||||||
|
m_model->setConnected(modelIndex.row(), true);
|
||||||
|
m_model->setData(buttonModelIndex, newNode.internalId(), SignalListModel::ConnectionsInternalIdRole);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalList::removeConnection(const QModelIndex &modelIndex)
|
||||||
|
{
|
||||||
|
const QModelIndex signalModelIndex = modelIndex.siblingAtColumn(SignalListModel::SignalColumn);
|
||||||
|
const QModelIndex buttonModelIndex = modelIndex.siblingAtColumn(SignalListModel::ButtonColumn);
|
||||||
|
const PropertyName signalName = m_model->data(signalModelIndex,
|
||||||
|
Qt::DisplayRole).toByteArray();
|
||||||
|
const int connectionInternalId = m_model->data(buttonModelIndex,
|
||||||
|
SignalListModel::ConnectionsInternalIdRole).toInt();
|
||||||
|
|
||||||
|
AbstractView *view = m_modelNode.view();
|
||||||
|
const ModelNode connectionModelNode = view->modelNodeForInternalId(connectionInternalId);
|
||||||
|
SignalHandlerProperty targetSignal;
|
||||||
|
|
||||||
|
if (connectionModelNode.isValid())
|
||||||
|
targetSignal = connectionModelNode.signalHandlerProperty(signalName);
|
||||||
|
|
||||||
|
ModelNode node = targetSignal.parentModelNode();
|
||||||
|
if (node.isValid()) {
|
||||||
|
view->executeInTransaction("ConnectionModel::removeConnection", [=, &node](){
|
||||||
|
QList<SignalHandlerProperty> allSignals = node.signalProperties();
|
||||||
|
if (allSignals.size() > 1) {
|
||||||
|
const auto targetSignalWithPrefix = SignalHandlerProperty::prefixAdded(targetSignal.name());
|
||||||
|
for (const SignalHandlerProperty &signal : allSignals)
|
||||||
|
if (signal.name() == targetSignalWithPrefix)
|
||||||
|
node.removeProperty(targetSignalWithPrefix);
|
||||||
|
} else {
|
||||||
|
node.destroy();
|
||||||
|
}
|
||||||
|
m_model->setConnected(modelIndex.row(), false);
|
||||||
|
m_model->setData(buttonModelIndex, QVariant(), SignalListModel::ConnectionsInternalIdRole);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QmlConnections> SignalList::getAssociatedConnections(const QList<ModelNode> &nodes)
|
||||||
|
{
|
||||||
|
return Utils::transform<QList<QmlConnections>>(Utils::filtered(nodes, [this](const ModelNode &node) {
|
||||||
|
const QmlConnections connection(node);
|
||||||
|
if (!connection.isValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (const SignalHandlerProperty &property : connection.signalProperties()) {
|
||||||
|
auto signalWithoutPrefix = SignalHandlerProperty::prefixRemoved(property.name());
|
||||||
|
const QStringList sourceComponents = property.source().split(".");
|
||||||
|
QString sourceId;
|
||||||
|
QString sourceProperty;
|
||||||
|
if (sourceComponents.size() > 1) {
|
||||||
|
sourceId = sourceComponents[0];
|
||||||
|
sourceProperty = sourceComponents[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (st_mouseSignals.contains(signalWithoutPrefix)
|
||||||
|
&& sourceId == m_modelNode.validId()
|
||||||
|
&& sourceProperty == "trigger()")
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}), [](const ModelNode &node) {
|
||||||
|
return QmlConnections(node);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // QmlDesigner namespace
|
||||||
108
src/plugins/qmldesigner/components/bindingeditor/signallist.h
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <bindingeditor/signallistdialog.h>
|
||||||
|
#include <qmldesignercorelib_global.h>
|
||||||
|
#include <modelnode.h>
|
||||||
|
#include <qmlconnections.h>
|
||||||
|
|
||||||
|
#include <QtQml>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class SignalListModel : public QStandardItemModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum ColumnRoles : unsigned int {
|
||||||
|
TargetColumn = 0,
|
||||||
|
SignalColumn = 1,
|
||||||
|
ButtonColumn = 2
|
||||||
|
};
|
||||||
|
enum UserRoles : unsigned int {
|
||||||
|
ConnectionsInternalIdRole = Qt::UserRole + 1,
|
||||||
|
ConnectedRole
|
||||||
|
};
|
||||||
|
|
||||||
|
SignalListModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
void setConnected(int row, bool connected);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SignalListFilterModel : public QSortFilterProxyModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
SignalListFilterModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SignalList : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SignalList(QObject *parent = nullptr);
|
||||||
|
~SignalList();
|
||||||
|
|
||||||
|
static SignalList* showWidget(const ModelNode &modelNode);
|
||||||
|
|
||||||
|
void setModelNode(const ModelNode &modelNode);
|
||||||
|
void connectClicked(const QModelIndex &modelIndex);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void prepareDialog();
|
||||||
|
void showWidget();
|
||||||
|
void hideWidget();
|
||||||
|
|
||||||
|
void prepareSignals();
|
||||||
|
|
||||||
|
void appendSignalToModel(const QList<QmlConnections> &connections,
|
||||||
|
ModelNode &node,
|
||||||
|
const PropertyName &signal,
|
||||||
|
const PropertyName &property = "");
|
||||||
|
|
||||||
|
void addConnection(const QModelIndex &modelIndex);
|
||||||
|
void removeConnection(const QModelIndex &modelIndex);
|
||||||
|
|
||||||
|
QList<QmlConnections> getAssociatedConnections(const QList<ModelNode> &nodes);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static PropertyNameList st_mouseSignals;
|
||||||
|
|
||||||
|
QPointer<SignalListDialog> m_dialog;
|
||||||
|
SignalListModel *m_model;
|
||||||
|
ModelNode m_modelNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // QmlDesigner namespace
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "signallistdelegate.h"
|
||||||
|
|
||||||
|
#include "signallist.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QStyleOptionButton>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
SignalListDelegate::SignalListDelegate(QObject *parent)
|
||||||
|
: QStyledItemDelegate(parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
QWidget *SignalListDelegate::createEditor(QWidget *parent,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
if (index.column() == SignalListModel::ButtonColumn)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return QStyledItemDelegate::createEditor(parent, option, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect connectButtonRect(const QStyleOptionViewItem &option)
|
||||||
|
{
|
||||||
|
return option.rect.adjusted(3, 3, -3, -3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalListDelegate::paint(QPainter *painter,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
const bool connected = index.data(SignalListModel::ConnectedRole).toBool();
|
||||||
|
if (connected) {
|
||||||
|
QStyleOptionViewItem opt(option);
|
||||||
|
opt.state = QStyle::State_Selected;
|
||||||
|
QStyledItemDelegate::paint(painter, opt, index);
|
||||||
|
if (index.column() != SignalListModel::ButtonColumn)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (index.column() == SignalListModel::ButtonColumn) {
|
||||||
|
QStyleOptionButton button;
|
||||||
|
button.rect = connectButtonRect(option);
|
||||||
|
button.text = connected ? tr("Release") : tr("Connect");
|
||||||
|
button.state = QStyle::State_Enabled;
|
||||||
|
QApplication::style()->drawControl(QStyle::CE_PushButton, &button, painter);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QStyledItemDelegate::paint(painter, option, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SignalListDelegate::editorEvent(QEvent *event,
|
||||||
|
QAbstractItemModel *model,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index)
|
||||||
|
{
|
||||||
|
Q_UNUSED(model)
|
||||||
|
|
||||||
|
if (index.column() == SignalListModel::ButtonColumn
|
||||||
|
&& event->type() == QEvent::MouseButtonRelease) {
|
||||||
|
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
||||||
|
if (connectButtonRect(option).contains(mouseEvent->pos()))
|
||||||
|
emit connectClicked(index);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // QmlDesigner namespace
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class SignalListDelegate : public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void connectClicked(const QModelIndex &modelIndex) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SignalListDelegate(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QWidget *createEditor(QWidget *parent,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const override;
|
||||||
|
void paint(QPainter *painter,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const override;
|
||||||
|
bool editorEvent(QEvent *event,
|
||||||
|
QAbstractItemModel *model,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // QmlDesigner namespace
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "signallistdialog.h"
|
||||||
|
|
||||||
|
#include "signallist.h"
|
||||||
|
#include "signallistdelegate.h"
|
||||||
|
|
||||||
|
#include <qmldesignerplugin.h>
|
||||||
|
|
||||||
|
#include <theme.h>
|
||||||
|
#include <utils/fancylineedit.h>
|
||||||
|
#include <utils/stylehelper.h>
|
||||||
|
#include <utils/utilsicons.h>
|
||||||
|
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QTableView>
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
QWidget *createFilterWidget(Utils::FancyLineEdit *lineEdit)
|
||||||
|
{
|
||||||
|
const QString unicode = Theme::getIconUnicode(Theme::Icon::search);
|
||||||
|
const QString fontName = "qtds_propertyIconFont.ttf";
|
||||||
|
QIcon icon = Utils::StyleHelper::getIconFromIconFont(fontName, unicode, 28, 28);
|
||||||
|
auto *label = new QLabel;
|
||||||
|
label->setPixmap(icon.pixmap(QSize(24, 24)));
|
||||||
|
label->setAlignment(Qt::AlignCenter);
|
||||||
|
lineEdit->setPlaceholderText(QObject::tr("<Filter>", "Library search input hint text"));
|
||||||
|
lineEdit->setDragEnabled(false);
|
||||||
|
lineEdit->setMinimumWidth(75);
|
||||||
|
lineEdit->setTextMargins(0, 0, 20, 0);
|
||||||
|
lineEdit->setFiltering(true);
|
||||||
|
auto *box = new QHBoxLayout;
|
||||||
|
box->addWidget(label);
|
||||||
|
box->addWidget(lineEdit);
|
||||||
|
auto *widget = new QWidget;
|
||||||
|
widget->setLayout(box);
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
void modifyPalette(QTableView *view, const QColor &selectionColor)
|
||||||
|
{
|
||||||
|
QPalette p = view->palette();
|
||||||
|
p.setColor(QPalette::AlternateBase, p.color(QPalette::Base).lighter(120));
|
||||||
|
p.setColor(QPalette::Highlight, selectionColor);
|
||||||
|
view->setPalette(p);
|
||||||
|
view->setAlternatingRowColors(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SignalListDialog::SignalListDialog(QWidget *parent)
|
||||||
|
: QDialog(parent)
|
||||||
|
, m_table(new QTableView())
|
||||||
|
, m_searchLine(new Utils::FancyLineEdit())
|
||||||
|
{
|
||||||
|
auto *signalListDelegate = new SignalListDelegate(m_table);
|
||||||
|
m_table->setItemDelegate(signalListDelegate);
|
||||||
|
m_table->setFocusPolicy(Qt::NoFocus);
|
||||||
|
m_table->setSelectionMode(QAbstractItemView::NoSelection);
|
||||||
|
m_table->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
|
m_table->verticalHeader()->hide();
|
||||||
|
|
||||||
|
modifyPalette(m_table, QColor("#d87b00"));
|
||||||
|
|
||||||
|
auto *layout = new QVBoxLayout;
|
||||||
|
layout->addWidget(createFilterWidget(m_searchLine));
|
||||||
|
layout->addWidget(m_table);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
setWindowFlag(Qt::Tool, true);
|
||||||
|
setModal(true);
|
||||||
|
resize(600, 480);
|
||||||
|
}
|
||||||
|
|
||||||
|
SignalListDialog::~SignalListDialog()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalListDialog::initialize(QStandardItemModel *model)
|
||||||
|
{
|
||||||
|
m_searchLine->clear();
|
||||||
|
|
||||||
|
auto *proxyModel = new SignalListFilterModel(this);
|
||||||
|
proxyModel->setSourceModel(model);
|
||||||
|
m_table->setModel(proxyModel);
|
||||||
|
|
||||||
|
QHeaderView *header = m_table->horizontalHeader();
|
||||||
|
header->setSectionResizeMode(SignalListModel::TargetColumn, QHeaderView::Stretch);
|
||||||
|
header->setSectionResizeMode(SignalListModel::SignalColumn, QHeaderView::Stretch);
|
||||||
|
header->resizeSection(SignalListModel::ButtonColumn, 120);
|
||||||
|
header->setStretchLastSection(false);
|
||||||
|
|
||||||
|
auto eventFilterFun = [this](const QString &str) {
|
||||||
|
if (auto *fm = qobject_cast<SignalListFilterModel *>(m_table->model()))
|
||||||
|
fm->setFilterFixedString(str);
|
||||||
|
};
|
||||||
|
connect(m_searchLine, &Utils::FancyLineEdit::filterChanged, eventFilterFun);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTableView *SignalListDialog::tableView() const
|
||||||
|
{
|
||||||
|
return m_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // QmlDesigner namespace
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QStandardItemModel;
|
||||||
|
class QTableView;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
namespace Utils {
|
||||||
|
class FancyLineEdit;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class SignalListDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
SignalListDialog(QWidget *parent = nullptr);
|
||||||
|
~SignalListDialog() override;
|
||||||
|
|
||||||
|
void initialize(QStandardItemModel *model);
|
||||||
|
|
||||||
|
QTableView *tableView() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTableView *m_table;
|
||||||
|
Utils::FancyLineEdit *m_searchLine;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // QmlDesigner namespace
|
||||||
@@ -53,6 +53,11 @@ public:
|
|||||||
LowestPriority = ComponentCoreConstants::priorityLast
|
LowestPriority = ComponentCoreConstants::priorityLast
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class TargetView {
|
||||||
|
Undefined,
|
||||||
|
ConnectionEditor
|
||||||
|
};
|
||||||
|
|
||||||
virtual ~ActionInterface() = default;
|
virtual ~ActionInterface() = default;
|
||||||
|
|
||||||
virtual QAction *action() const = 0;
|
virtual QAction *action() const = 0;
|
||||||
@@ -61,6 +66,7 @@ public:
|
|||||||
virtual int priority() const = 0;
|
virtual int priority() const = 0;
|
||||||
virtual Type type() const = 0;
|
virtual Type type() const = 0;
|
||||||
virtual void currentContextChanged(const SelectionContext &selectionState) = 0;
|
virtual void currentContextChanged(const SelectionContext &selectionState) = 0;
|
||||||
|
virtual TargetView targetView() const { return TargetView::Undefined; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -89,6 +89,8 @@ const char fitRootToScreenCommandId[] = "FitRootToScreen";
|
|||||||
const char fitSelectionToScreenCommandId[] = "FitSelectionToScreen";
|
const char fitSelectionToScreenCommandId[] = "FitSelectionToScreen";
|
||||||
const char editAnnotationCommandId[] = "EditAnnotation";
|
const char editAnnotationCommandId[] = "EditAnnotation";
|
||||||
|
|
||||||
|
const char openSignalDialogCommandId[] = "OpenSignalDialog";
|
||||||
|
|
||||||
const char selectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Selection");
|
const char selectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Selection");
|
||||||
const char flowConnectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Connect");
|
const char flowConnectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Connect");
|
||||||
const char selectEffectDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select Effect");
|
const char selectEffectDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select Effect");
|
||||||
@@ -128,6 +130,8 @@ const char addSignalHandlerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContext
|
|||||||
const char moveToComponentDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Move Component into Separate File");
|
const char moveToComponentDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Move Component into Separate File");
|
||||||
const char editAnnotationDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Edit Annotation");
|
const char editAnnotationDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Edit Annotation");
|
||||||
|
|
||||||
|
const char openSignalDialogDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Open Signal Dialog");
|
||||||
|
|
||||||
const char setIdDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Set Id");
|
const char setIdDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Set Id");
|
||||||
|
|
||||||
const char resetZDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reset z Property");
|
const char resetZDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Reset z Property");
|
||||||
|
|||||||
@@ -564,6 +564,7 @@ const char yProperty[] = "y";
|
|||||||
const char zProperty[] = "z";
|
const char zProperty[] = "z";
|
||||||
const char widthProperty[] = "width";
|
const char widthProperty[] = "width";
|
||||||
const char heightProperty[] = "height";
|
const char heightProperty[] = "height";
|
||||||
|
const char triggerSlot[] = "trigger";
|
||||||
|
|
||||||
using namespace SelectionContextFunctors;
|
using namespace SelectionContextFunctors;
|
||||||
|
|
||||||
@@ -644,6 +645,14 @@ bool selectionNotEmptyAndHasXorYProperty(const SelectionContext &context)
|
|||||||
&& selectionHasProperty1or2(context, xProperty, yProperty);
|
&& selectionHasProperty1or2(context, xProperty, yProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool singleSelectionAndHasSlotTrigger(const SelectionContext &context)
|
||||||
|
{
|
||||||
|
if (!singleSelection(context))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return selectionHasSlot(context, triggerSlot);
|
||||||
|
}
|
||||||
|
|
||||||
bool singleSelectionAndInQtQuickLayout(const SelectionContext &context)
|
bool singleSelectionAndInQtQuickLayout(const SelectionContext &context)
|
||||||
{
|
{
|
||||||
if (!singleSelection(context))
|
if (!singleSelection(context))
|
||||||
@@ -1384,6 +1393,16 @@ void DesignerActionManager::createDefaultDesignerActions()
|
|||||||
addDesignerAction(new ChangeStyleAction());
|
addDesignerAction(new ChangeStyleAction());
|
||||||
|
|
||||||
addDesignerAction(new EditListModelAction);
|
addDesignerAction(new EditListModelAction);
|
||||||
|
|
||||||
|
addDesignerAction(new ModelNodeContextMenuAction(
|
||||||
|
openSignalDialogCommandId,
|
||||||
|
openSignalDialogDisplayName,
|
||||||
|
{},
|
||||||
|
rootCategory,
|
||||||
|
QKeySequence(),
|
||||||
|
66,
|
||||||
|
&openSignalDialog,
|
||||||
|
&singleSelectionAndHasSlotTrigger));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignerActionManager::createDefaultAddResourceHandler()
|
void DesignerActionManager::createDefaultAddResourceHandler()
|
||||||
@@ -1459,6 +1478,16 @@ void DesignerActionManager::addCreatorCommand(Core::Command *command, const QByt
|
|||||||
addDesignerAction(new CommandAction(command, category, priority, overrideIcon));
|
addDesignerAction(new CommandAction(command, category, priority, overrideIcon));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<QSharedPointer<ActionInterface> > DesignerActionManager::actionsForTargetView(const ActionInterface::TargetView &target)
|
||||||
|
{
|
||||||
|
QList<QSharedPointer<ActionInterface> > out;
|
||||||
|
for (auto interface : m_designerActions)
|
||||||
|
if (interface->targetView() == target)
|
||||||
|
out << interface;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
QList<ActionInterface* > DesignerActionManager::designerActions() const
|
QList<ActionInterface* > DesignerActionManager::designerActions() const
|
||||||
{
|
{
|
||||||
return Utils::transform(m_designerActions, [](const QSharedPointer<ActionInterface> &pointer) {
|
return Utils::transform(m_designerActions, [](const QSharedPointer<ActionInterface> &pointer) {
|
||||||
|
|||||||
@@ -106,6 +106,9 @@ public:
|
|||||||
void addDesignerAction(ActionInterface *newAction);
|
void addDesignerAction(ActionInterface *newAction);
|
||||||
void addCreatorCommand(Core::Command *command, const QByteArray &category, int priority,
|
void addCreatorCommand(Core::Command *command, const QByteArray &category, int priority,
|
||||||
const QIcon &overrideIcon = QIcon());
|
const QIcon &overrideIcon = QIcon());
|
||||||
|
|
||||||
|
QList<QSharedPointer<ActionInterface>> actionsForTargetView(const ActionInterface::TargetView &target);
|
||||||
|
|
||||||
QList<ActionInterface* > designerActions() const;
|
QList<ActionInterface* > designerActions() const;
|
||||||
|
|
||||||
void createDefaultDesignerActions();
|
void createDefaultDesignerActions();
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "abstractactiongroup.h"
|
#include "abstractactiongroup.h"
|
||||||
#include "qmlitemnode.h"
|
#include "qmlitemnode.h"
|
||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
|
#include <nodemetainfo.h>
|
||||||
|
|
||||||
#include <coreplugin/actionmanager/command.h>
|
#include <coreplugin/actionmanager/command.h>
|
||||||
|
|
||||||
@@ -80,12 +81,24 @@ inline bool singleSelectionNotRoot(const SelectionContext &selectionState)
|
|||||||
|
|
||||||
inline bool selectionHasProperty(const SelectionContext &selectionState, const char *property)
|
inline bool selectionHasProperty(const SelectionContext &selectionState, const char *property)
|
||||||
{
|
{
|
||||||
foreach (const ModelNode &modelNode, selectionState.selectedModelNodes())
|
for (const ModelNode &modelNode : selectionState.selectedModelNodes())
|
||||||
if (modelNode.hasProperty(PropertyName(property)))
|
if (modelNode.hasProperty(PropertyName(property)))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool selectionHasSlot(const SelectionContext &selectionState, const char *property)
|
||||||
|
{
|
||||||
|
for (const ModelNode &modelNode : selectionState.selectedModelNodes()) {
|
||||||
|
for (const PropertyName &slotName : modelNode.metaInfo().slotNames()) {
|
||||||
|
if (slotName == property)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool singleSelectedItem(const SelectionContext &selectionState)
|
inline bool singleSelectedItem(const SelectionContext &selectionState)
|
||||||
{
|
{
|
||||||
QmlItemNode itemNode(selectionState.currentSingleSelectedNode());
|
QmlItemNode itemNode(selectionState.currentSingleSelectedNode());
|
||||||
@@ -94,7 +107,6 @@ inline bool singleSelectedItem(const SelectionContext &selectionState)
|
|||||||
|
|
||||||
bool selectionHasSameParent(const SelectionContext &selectionState);
|
bool selectionHasSameParent(const SelectionContext &selectionState);
|
||||||
bool selectionIsComponent(const SelectionContext &selectionState);
|
bool selectionIsComponent(const SelectionContext &selectionState);
|
||||||
bool selectionIsComponent(const SelectionContext &selectionState);
|
|
||||||
bool singleSelectionItemIsAnchored(const SelectionContext &selectionState);
|
bool singleSelectionItemIsAnchored(const SelectionContext &selectionState);
|
||||||
bool singleSelectionItemIsNotAnchored(const SelectionContext &selectionState);
|
bool singleSelectionItemIsNotAnchored(const SelectionContext &selectionState);
|
||||||
|
|
||||||
|
|||||||
@@ -87,6 +87,8 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
#include <bindingeditor/signallist.h>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
const PropertyName auxDataString("anchors_");
|
const PropertyName auxDataString("anchors_");
|
||||||
@@ -1548,6 +1550,14 @@ QVariant previewImageDataForImageNode(const ModelNode &modelNode)
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void openSignalDialog(const SelectionContext &selectionContext)
|
||||||
|
{
|
||||||
|
if (!selectionContext.view() || !selectionContext.hasSingleSelectedModelNode())
|
||||||
|
return;
|
||||||
|
|
||||||
|
SignalList::showWidget(selectionContext.currentSingleSelectedNode());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ModelNodeOperations
|
} // namespace ModelNodeOperations
|
||||||
|
|
||||||
} //QmlDesigner
|
} //QmlDesigner
|
||||||
|
|||||||
@@ -88,6 +88,8 @@ void mergeWithTemplate(const SelectionContext &selectionContext);
|
|||||||
void removeGroup(const SelectionContext &selectionContext);
|
void removeGroup(const SelectionContext &selectionContext);
|
||||||
void editAnnotation(const SelectionContext &selectionContext);
|
void editAnnotation(const SelectionContext &selectionContext);
|
||||||
|
|
||||||
|
void openSignalDialog(const SelectionContext &selectionContext);
|
||||||
|
|
||||||
// ModelNodePreviewImageOperations
|
// ModelNodePreviewImageOperations
|
||||||
QVariant previewImageDataForGenericNode(const ModelNode &modelNode);
|
QVariant previewImageDataForGenericNode(const ModelNode &modelNode);
|
||||||
QVariant previewImageDataForImageNode(const ModelNode &modelNode);
|
QVariant previewImageDataForImageNode(const ModelNode &modelNode);
|
||||||
|
|||||||
@@ -49,9 +49,9 @@ namespace {
|
|||||||
QStringList propertyNameListToStringList(const QmlDesigner::PropertyNameList &propertyNameList)
|
QStringList propertyNameListToStringList(const QmlDesigner::PropertyNameList &propertyNameList)
|
||||||
{
|
{
|
||||||
QStringList stringList;
|
QStringList stringList;
|
||||||
for (const QmlDesigner::PropertyName &propertyName : propertyNameList) {
|
for (const QmlDesigner::PropertyName &propertyName : propertyNameList)
|
||||||
stringList << QString::fromUtf8(propertyName);
|
stringList << QString::fromUtf8(propertyName);
|
||||||
}
|
|
||||||
stringList.removeDuplicates();
|
stringList.removeDuplicates();
|
||||||
return stringList;
|
return stringList;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,6 +172,19 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event)
|
|||||||
m_connectionEditor->updateWindowName();
|
m_connectionEditor->updateWindowName();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QMap<QString, QVariant> data;
|
||||||
|
data["ModelNode"] = index.siblingAtColumn(ConnectionModel::TargetModelNodeRow).data();
|
||||||
|
data["Signal"] = index.siblingAtColumn(ConnectionModel::TargetPropertyNameRow).data();
|
||||||
|
DesignerActionManager &designerActionManager = QmlDesignerPlugin::instance()->designerActionManager();
|
||||||
|
const auto actions = designerActionManager.actionsForTargetView(
|
||||||
|
ActionInterface::TargetView::ConnectionEditor);
|
||||||
|
|
||||||
|
for (auto actionInterface : actions) {
|
||||||
|
auto *action = actionInterface->action();
|
||||||
|
action->setData(data);
|
||||||
|
menu.addAction(action);
|
||||||
|
}
|
||||||
|
|
||||||
menu.exec(event->globalPos());
|
menu.exec(event->globalPos());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -888,6 +888,7 @@ public:
|
|||||||
, labelFlags(Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextDontClip)
|
, labelFlags(Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextDontClip)
|
||||||
, labelFlipSide(false)
|
, labelFlipSide(false)
|
||||||
, hitTesting(hitTest)
|
, hitTesting(hitTest)
|
||||||
|
, isSelected(false)
|
||||||
, events()
|
, events()
|
||||||
{
|
{
|
||||||
// width
|
// width
|
||||||
@@ -1416,37 +1417,7 @@ void FormEditorTransitionItem::updateGeometry()
|
|||||||
overallBoundingRect = overallBoundingRect.united(connection.fromRect);
|
overallBoundingRect = overallBoundingRect.united(connection.fromRect);
|
||||||
overallBoundingRect = overallBoundingRect.united(connection.toRect);
|
overallBoundingRect = overallBoundingRect.united(connection.toRect);
|
||||||
overallBoundingRect = overallBoundingRect.united(pathBoundingRect);
|
overallBoundingRect = overallBoundingRect.united(pathBoundingRect);
|
||||||
|
drawLabels(&localPainter, connection);
|
||||||
// Calculate bounding rect for label
|
|
||||||
// TODO The calculation should be put into a separate function to avoid code duplication as this
|
|
||||||
// can also be found in drawLabel()
|
|
||||||
if (!connection.config.label.isEmpty()) {
|
|
||||||
const qreal percent = connection.config.labelPosition / 100.0;
|
|
||||||
const QPointF pos = connection.path.pointAtPercent(percent);
|
|
||||||
const qreal angle = connection.path.angleAtPercent(percent);
|
|
||||||
|
|
||||||
QLineF tmp(pos, QPointF(10, 10));
|
|
||||||
tmp.setLength(connection.config.labelOffset);
|
|
||||||
tmp.setAngle(angle + (connection.config.labelFlipSide ? 270 : 90));
|
|
||||||
|
|
||||||
QRectF textRect(0, 0, 100, 50);
|
|
||||||
textRect.moveCenter(tmp.p2());
|
|
||||||
|
|
||||||
QRectF labelRect;
|
|
||||||
|
|
||||||
QTransform transform;
|
|
||||||
transform.translate(textRect.center().x(), textRect.center().y());
|
|
||||||
transform.rotate(-normalizeAngle(angle));
|
|
||||||
transform.translate(-textRect.center().x(), -textRect.center().y());
|
|
||||||
|
|
||||||
localPainter.setTransform(transform);
|
|
||||||
localPainter.drawText(textRect,
|
|
||||||
connection.config.labelFlags,
|
|
||||||
connection.config.label,
|
|
||||||
&labelRect);
|
|
||||||
QRectF labelBoundingBox = transform.mapRect(labelRect);
|
|
||||||
overallBoundingRect = overallBoundingRect.united(labelBoundingBox);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1461,7 +1432,7 @@ QPointF FormEditorTransitionItem::instancePosition() const
|
|||||||
return qmlItemNode().flowPosition();
|
return qmlItemNode().flowPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drawLabel(QPainter *painter, const Connection &connection)
|
void FormEditorTransitionItem::drawLabels(QPainter *painter, const Connection &connection)
|
||||||
{
|
{
|
||||||
// draw label with event ids
|
// draw label with event ids
|
||||||
if (connection.config.isSelected && !connection.config.events.isEmpty())
|
if (connection.config.isSelected && !connection.config.events.isEmpty())
|
||||||
@@ -1469,27 +1440,23 @@ static void drawLabel(QPainter *painter, const Connection &connection)
|
|||||||
qreal offset = connection.config.labelOffset;
|
qreal offset = connection.config.labelOffset;
|
||||||
QStringList events = connection.config.events.split(',');
|
QStringList events = connection.config.events.split(',');
|
||||||
int fontSize = connection.config.fontSize;
|
int fontSize = connection.config.fontSize;
|
||||||
QString output = events[0].trimmed();
|
QString outputText;
|
||||||
qreal minWidth = offset * 12;
|
qreal minWidth = offset * 12.0;
|
||||||
int letterWidth = fontSize * 0.6; // assumption on max letter length
|
qreal letterWidth = fontSize * 0.6; // assumption on max letter width
|
||||||
if (minWidth < output.size() * letterWidth) minWidth = output.size() * letterWidth;
|
|
||||||
int eventCount = events.size();
|
int eventCount = events.size();
|
||||||
for (int i = 1; i < eventCount; ++i)
|
std::for_each(events.begin(), events.end(), [&](auto id) {
|
||||||
{
|
outputText.append(id.trimmed());
|
||||||
output.append('\n');
|
outputText.append('\n');
|
||||||
QString id = events[i].trimmed();
|
|
||||||
output.append(id);
|
|
||||||
if (minWidth < id.size() * letterWidth) minWidth = id.size() * letterWidth;
|
if (minWidth < id.size() * letterWidth) minWidth = id.size() * letterWidth;
|
||||||
}
|
});
|
||||||
const QPointF pos = connection.path.pointAtPercent(0.0);
|
const QPointF pos = connection.path.pointAtPercent(0.0);
|
||||||
painter->save();
|
painter->save();
|
||||||
painter->setBrush(QColor(70, 70, 70, 200));
|
painter->setBrush(QColor(70, 70, 70, 200));
|
||||||
painter->setPen(Qt::lightGray);
|
painter->setPen(Qt::lightGray);
|
||||||
|
painter->drawRoundedRect(pos.x(), pos.y() + offset, minWidth, 1.5 * fontSize * eventCount + offset * 4.0, offset / 2.0, offset / 2.0);
|
||||||
painter->drawRoundedRect(pos.x(), pos.y() + offset, minWidth, 1.5 * fontSize * eventCount + offset * 4, offset / 2, offset / 2);
|
painter->drawText(pos.x(), pos.y() + 2.0 * offset, minWidth, offset * 2.0, Qt::AlignHCenter, QObject::tr("Connected Events"));
|
||||||
painter->drawText(pos.x(), pos.y() + 2 * offset, minWidth, offset * 2, Qt::AlignHCenter, QObject::tr("Connected Events"));
|
painter->drawLine(pos.x() + offset, pos.y() + 4.0 * offset, pos.x() + minWidth - offset, pos.y() + offset * 4.0);
|
||||||
painter->drawLine(pos.x() + offset, pos.y() + 4 * offset, pos.x() + minWidth - offset, pos.y() + offset * 4);
|
painter->drawText(pos.x() + offset, pos.y() + 4.0 * offset, minWidth - offset, 1.5 * fontSize * eventCount, Qt::AlignLeft, outputText);
|
||||||
painter->drawText(pos.x() + offset, pos.y() + 4 * offset, minWidth - offset, 1.5 * fontSize * eventCount, Qt::AlignLeft, output);
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
if (connection.config.label.isEmpty())
|
if (connection.config.label.isEmpty())
|
||||||
@@ -1534,7 +1501,7 @@ static void drawArrow(QPainter *painter,
|
|||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void paintConnection(QPainter *painter, const Connection &connection)
|
void FormEditorTransitionItem::paintConnection(QPainter *painter, const Connection &connection)
|
||||||
{
|
{
|
||||||
const int arrowLength = 4 * connection.config.adjustedWidth;
|
const int arrowLength = 4 * connection.config.adjustedWidth;
|
||||||
const int arrowWidth = 8 * connection.config.adjustedWidth;
|
const int arrowWidth = 8 * connection.config.adjustedWidth;
|
||||||
@@ -1586,8 +1553,8 @@ static void paintConnection(QPainter *painter, const Connection &connection)
|
|||||||
painter->drawEllipse(connection.start, arrowLength / 3, arrowLength / 3);
|
painter->drawEllipse(connection.start, arrowLength / 3, arrowLength / 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw label
|
// Draw labels
|
||||||
drawLabel(painter, connection);
|
drawLabels(painter, connection);
|
||||||
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ namespace QmlDesigner {
|
|||||||
class FormEditorScene;
|
class FormEditorScene;
|
||||||
class FormEditorView;
|
class FormEditorView;
|
||||||
class AbstractFormEditorTool;
|
class AbstractFormEditorTool;
|
||||||
|
class Connection;
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
class GraphicItemResizer;
|
class GraphicItemResizer;
|
||||||
@@ -197,11 +198,12 @@ public:
|
|||||||
QPointF instancePosition() const override;
|
QPointF instancePosition() const override;
|
||||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
|
||||||
bool flowHitTest(const QPointF &point) const override;
|
bool flowHitTest(const QPointF &point) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
FormEditorTransitionItem(const QmlItemNode &qmlItemNode, FormEditorScene *scene)
|
FormEditorTransitionItem(const QmlItemNode &qmlItemNode, FormEditorScene *scene)
|
||||||
: FormEditorItem(qmlItemNode, scene)
|
: FormEditorItem(qmlItemNode, scene)
|
||||||
{}
|
{}
|
||||||
|
void paintConnection(QPainter *painter, const Connection &connection);
|
||||||
|
void drawLabels(QPainter *painter, const Connection &connection);
|
||||||
private:
|
private:
|
||||||
mutable bool m_hitTest = false;
|
mutable bool m_hitTest = false;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -133,8 +133,6 @@ static QRect drawText(QPainter *painter,
|
|||||||
int iconOffset)
|
int iconOffset)
|
||||||
{
|
{
|
||||||
QString displayString = modelIndex.data(Qt::DisplayRole).toString();
|
QString displayString = modelIndex.data(Qt::DisplayRole).toString();
|
||||||
QPoint displayStringOffset;
|
|
||||||
int width = 0;
|
|
||||||
|
|
||||||
// Check text length does not exceed available space
|
// Check text length does not exceed available space
|
||||||
const int extraSpace = 12 + iconOffset;
|
const int extraSpace = 12 + iconOffset;
|
||||||
@@ -142,10 +140,8 @@ static QRect drawText(QPainter *painter,
|
|||||||
displayString = styleOption.fontMetrics.elidedText(displayString,
|
displayString = styleOption.fontMetrics.elidedText(displayString,
|
||||||
Qt::ElideMiddle,
|
Qt::ElideMiddle,
|
||||||
styleOption.rect.width() - extraSpace);
|
styleOption.rect.width() - extraSpace);
|
||||||
displayStringOffset = QPoint(5 + iconOffset, -5 - delegateMargin);
|
const QPoint displayStringOffset = QPoint(5 + iconOffset, -5 - delegateMargin);
|
||||||
|
const int width = styleOption.fontMetrics.horizontalAdvance(displayString);
|
||||||
width = styleOption.fontMetrics.horizontalAdvance(displayString);
|
|
||||||
|
|
||||||
const QPoint textPosition = styleOption.rect.bottomLeft() + displayStringOffset;
|
const QPoint textPosition = styleOption.rect.bottomLeft() + displayStringOffset;
|
||||||
painter->drawText(textPosition, displayString);
|
painter->drawText(textPosition, displayString);
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ SOURCES += $$PWD/model/abstractview.cpp \
|
|||||||
$$PWD/model/qmlmodelnodefacade.cpp \
|
$$PWD/model/qmlmodelnodefacade.cpp \
|
||||||
$$PWD/model/qmlobjectnode.cpp \
|
$$PWD/model/qmlobjectnode.cpp \
|
||||||
$$PWD/model/qmlanchors.cpp \
|
$$PWD/model/qmlanchors.cpp \
|
||||||
|
$$PWD/model/qmlconnections.cpp \
|
||||||
$$PWD/rewritertransaction.cpp \
|
$$PWD/rewritertransaction.cpp \
|
||||||
$$PWD/model/rewriteaction.cpp \
|
$$PWD/model/rewriteaction.cpp \
|
||||||
$$PWD/model/modelnodepositionstorage.cpp \
|
$$PWD/model/modelnodepositionstorage.cpp \
|
||||||
@@ -151,6 +152,7 @@ HEADERS += $$PWD/include/qmldesignercorelib_global.h \
|
|||||||
$$PWD/include/forwardview.h \
|
$$PWD/include/forwardview.h \
|
||||||
$$PWD/include/qmlobjectnode.h \
|
$$PWD/include/qmlobjectnode.h \
|
||||||
$$PWD/include/qmlanchors.h \
|
$$PWD/include/qmlanchors.h \
|
||||||
|
$$PWD/include/qmlconnections.h \
|
||||||
$$PWD/rewritertransaction.h \
|
$$PWD/rewritertransaction.h \
|
||||||
$$PWD/model/rewriteaction.h \
|
$$PWD/model/rewriteaction.h \
|
||||||
$$PWD/include/modelnodepositionstorage.h \
|
$$PWD/include/modelnodepositionstorage.h \
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <qmldesignercorelib_global.h>
|
||||||
|
#include "qmlmodelnodefacade.h"
|
||||||
|
|
||||||
|
#include <signalhandlerproperty.h>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class QMLDESIGNERCORE_EXPORT QmlConnections : public QmlModelNodeFacade
|
||||||
|
{
|
||||||
|
friend class StatesEditorView;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QmlConnections();
|
||||||
|
QmlConnections(const ModelNode &modelNode);
|
||||||
|
|
||||||
|
bool isValid() const override;
|
||||||
|
static bool isValidQmlConnections(const ModelNode &modelNode);
|
||||||
|
void destroy();
|
||||||
|
|
||||||
|
QString target() const;
|
||||||
|
void setTarget(const QString &target);
|
||||||
|
|
||||||
|
ModelNode getTargetNode() const;
|
||||||
|
|
||||||
|
QList<SignalHandlerProperty> signalProperties() const;
|
||||||
|
|
||||||
|
static ModelNode createQmlConnections(AbstractView *view);
|
||||||
|
};
|
||||||
|
|
||||||
|
} //QmlDesigner
|
||||||
@@ -43,6 +43,9 @@ public:
|
|||||||
SignalHandlerProperty();
|
SignalHandlerProperty();
|
||||||
SignalHandlerProperty(const SignalHandlerProperty &property, AbstractView *view);
|
SignalHandlerProperty(const SignalHandlerProperty &property, AbstractView *view);
|
||||||
|
|
||||||
|
static PropertyName prefixAdded(const PropertyName &propertyName);
|
||||||
|
static PropertyName prefixRemoved(const PropertyName &propertyName);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SignalHandlerProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view);
|
SignalHandlerProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -295,7 +295,7 @@ public:
|
|||||||
const TypeName type = resolveTypeName(ref, m_context, dotProperties);
|
const TypeName type = resolveTypeName(ref, m_context, dotProperties);
|
||||||
m_properties.append({propertyName, type});
|
m_properties.append({propertyName, type});
|
||||||
if (!dotProperties.isEmpty()) {
|
if (!dotProperties.isEmpty()) {
|
||||||
foreach (const PropertyInfo &propertyInfo, dotProperties) {
|
for (const PropertyInfo &propertyInfo : qAsConst(dotProperties)) {
|
||||||
PropertyName dotName = propertyInfo.first;
|
PropertyName dotName = propertyInfo.first;
|
||||||
TypeName type = propertyInfo.second;
|
TypeName type = propertyInfo.second;
|
||||||
dotName = propertyName + '.' + dotName;
|
dotName = propertyName + '.' + dotName;
|
||||||
@@ -303,7 +303,6 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (const CppComponentValue * cppComponentValue = value_cast<CppComponentValue>(value)) {
|
if (const CppComponentValue * cppComponentValue = value_cast<CppComponentValue>(value)) {
|
||||||
TypeName qualifiedTypeName = qualifiedTypeNameForContext(cppComponentValue,
|
TypeName qualifiedTypeName = qualifiedTypeNameForContext(cppComponentValue,
|
||||||
m_context->viewerContext(), *m_context->snapshot().importDependencies()).toUtf8();
|
m_context->viewerContext(), *m_context->snapshot().importDependencies()).toUtf8();
|
||||||
@@ -311,13 +310,13 @@ public:
|
|||||||
} else {
|
} else {
|
||||||
TypeId typeId;
|
TypeId typeId;
|
||||||
TypeName typeName = typeId(value).toUtf8();
|
TypeName typeName = typeId(value).toUtf8();
|
||||||
if (typeName == "number") {
|
|
||||||
if (value->asIntValue()) {
|
if (typeName == "Function")
|
||||||
typeName = "int";
|
return processSlot(name, value);
|
||||||
} else {
|
|
||||||
typeName = "real";
|
if (typeName == "number")
|
||||||
}
|
typeName = value->asIntValue() ? "int" : "real";
|
||||||
}
|
|
||||||
m_properties.append({propertyName, typeName});
|
m_properties.append({propertyName, typeName});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -488,7 +487,7 @@ PropertyNameList getSignals(const ObjectValue *objectValue, const ContextPtr &co
|
|||||||
QList<const ObjectValue *> objects = prototypeIterator.all();
|
QList<const ObjectValue *> objects = prototypeIterator.all();
|
||||||
|
|
||||||
if (!local) {
|
if (!local) {
|
||||||
foreach (const ObjectValue *prototype, objects)
|
for (const ObjectValue *prototype : objects)
|
||||||
signalList.append(getSignals(prototype, context, true));
|
signalList.append(getSignals(prototype, context, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,6 +506,9 @@ PropertyNameList getSlots(const ObjectValue *objectValue, const ContextPtr &cont
|
|||||||
PropertyMemberProcessor processor(context);
|
PropertyMemberProcessor processor(context);
|
||||||
objectValue->processMembers(&processor);
|
objectValue->processMembers(&processor);
|
||||||
|
|
||||||
|
if (const ASTObjectValue *astObjectValue = objectValue->asAstObjectValue())
|
||||||
|
astObjectValue->processMembers(&processor);
|
||||||
|
|
||||||
slotList.append(processor.slotList());
|
slotList.append(processor.slotList());
|
||||||
|
|
||||||
PrototypeIterator prototypeIterator(objectValue, context);
|
PrototypeIterator prototypeIterator(objectValue, context);
|
||||||
@@ -534,6 +536,7 @@ QVector<PropertyInfo> getObjectTypes(const ObjectValue *objectValue, const Conte
|
|||||||
|
|
||||||
PropertyMemberProcessor processor(context);
|
PropertyMemberProcessor processor(context);
|
||||||
objectValue->processMembers(&processor);
|
objectValue->processMembers(&processor);
|
||||||
|
|
||||||
const auto props = processor.properties();
|
const auto props = processor.properties();
|
||||||
|
|
||||||
for (const PropertyInfo &property : props) {
|
for (const PropertyInfo &property : props) {
|
||||||
|
|||||||
130
src/plugins/qmldesigner/designercore/model/qmlconnections.cpp
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "qmlconnections.h"
|
||||||
|
|
||||||
|
#include <metainfo.h>
|
||||||
|
#include <abstractview.h>
|
||||||
|
#include <bindingproperty.h>
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
QmlConnections::QmlConnections()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlConnections::QmlConnections(const ModelNode &modelNode)
|
||||||
|
: QmlModelNodeFacade(modelNode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlConnections::isValid() const
|
||||||
|
{
|
||||||
|
return isValidQmlConnections(modelNode());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlConnections::isValidQmlConnections(const ModelNode &modelNode)
|
||||||
|
{
|
||||||
|
return isValidQmlModelNodeFacade(modelNode)
|
||||||
|
&& modelNode.metaInfo().isValid()
|
||||||
|
&& (modelNode.type() == "Connections"
|
||||||
|
|| modelNode.type() == "QtQuick.Connections"
|
||||||
|
|| modelNode.type() == "Qt.Connections"
|
||||||
|
|| modelNode.type() == "QtQml.Connections");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Removes connections node.
|
||||||
|
*/
|
||||||
|
void QmlConnections::destroy()
|
||||||
|
{
|
||||||
|
Q_ASSERT(isValid());
|
||||||
|
modelNode().destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QmlConnections::target() const
|
||||||
|
{
|
||||||
|
if (modelNode().isValid()) {
|
||||||
|
const BindingProperty bindingproperty = modelNode().bindingProperty("target");
|
||||||
|
if (bindingproperty.isValid())
|
||||||
|
return bindingproperty.expression();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlConnections::setTarget(const QString &target)
|
||||||
|
{
|
||||||
|
modelNode().bindingProperty("target").setExpression(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelNode QmlConnections::getTargetNode() const
|
||||||
|
{
|
||||||
|
ModelNode result;
|
||||||
|
|
||||||
|
if (!modelNode().isValid())
|
||||||
|
return result;
|
||||||
|
|
||||||
|
const BindingProperty bindingProperty = modelNode().bindingProperty("target");
|
||||||
|
const QString bindExpression = bindingProperty.expression();
|
||||||
|
|
||||||
|
if (bindingProperty.isValid()) {
|
||||||
|
AbstractView *view = modelNode().view();
|
||||||
|
if (bindExpression.contains(".")) {
|
||||||
|
QStringList substr = bindExpression.split(".");
|
||||||
|
const QString itemId = substr.constFirst();
|
||||||
|
if (substr.size() > 1) {
|
||||||
|
const ModelNode aliasParent = view->modelNodeForId(itemId);
|
||||||
|
substr.removeFirst(); // remove id, only alias pieces left
|
||||||
|
const QString aliasBody = substr.join(".");
|
||||||
|
if (aliasParent.isValid() && aliasParent.hasBindingProperty(aliasBody.toUtf8())) {
|
||||||
|
const BindingProperty binding = aliasParent.bindingProperty(aliasBody.toUtf8());
|
||||||
|
if (binding.isValid() && view->hasId(binding.expression()))
|
||||||
|
result = view->modelNodeForId(binding.expression());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = view->modelNodeForId(bindExpression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<SignalHandlerProperty> QmlConnections::signalProperties() const
|
||||||
|
{
|
||||||
|
return modelNode().signalProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelNode QmlConnections::createQmlConnections(AbstractView *view)
|
||||||
|
{
|
||||||
|
NodeMetaInfo nodeMetaInfo = view->model()->metaInfo("QtQuick.Connections");
|
||||||
|
return view->createModelNode("QtQuick.Connections",
|
||||||
|
nodeMetaInfo.majorVersion(),
|
||||||
|
nodeMetaInfo.minorVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // QmlDesigner
|
||||||
@@ -40,13 +40,11 @@ SignalHandlerProperty::SignalHandlerProperty(const SignalHandlerProperty &proper
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SignalHandlerProperty::SignalHandlerProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view)
|
SignalHandlerProperty::SignalHandlerProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view)
|
||||||
: AbstractProperty(propertyName, internalNode, model, view)
|
: AbstractProperty(propertyName, internalNode, model, view)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SignalHandlerProperty::setSource(const QString &source)
|
void SignalHandlerProperty::setSource(const QString &source)
|
||||||
{
|
{
|
||||||
Internal::WriteLocker locker(model());
|
Internal::WriteLocker locker(model());
|
||||||
@@ -83,4 +81,30 @@ QString SignalHandlerProperty::source() const
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PropertyName SignalHandlerProperty::prefixAdded(const PropertyName &propertyName)
|
||||||
|
{
|
||||||
|
QString nameAsString = QString::fromUtf8(propertyName);
|
||||||
|
if (nameAsString.startsWith("on"))
|
||||||
|
return propertyName;
|
||||||
|
|
||||||
|
QChar firstChar = nameAsString.at(0).toUpper();
|
||||||
|
nameAsString[0] = firstChar;
|
||||||
|
nameAsString.prepend("on");
|
||||||
|
|
||||||
|
return nameAsString.toLatin1();
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyName SignalHandlerProperty::prefixRemoved(const PropertyName &propertyName)
|
||||||
|
{
|
||||||
|
QString nameAsString = QString::fromUtf8(propertyName);
|
||||||
|
if (!nameAsString.startsWith("on"))
|
||||||
|
return propertyName;
|
||||||
|
|
||||||
|
nameAsString.remove(0, 2);
|
||||||
|
QChar firstChar = nameAsString.at(0).toLower();
|
||||||
|
nameAsString[0] = firstChar;
|
||||||
|
|
||||||
|
return nameAsString.toLatin1();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
|||||||
@@ -302,6 +302,7 @@ Project {
|
|||||||
"include/qmlmodelnodefacade.h",
|
"include/qmlmodelnodefacade.h",
|
||||||
"include/qmlobjectnode.h",
|
"include/qmlobjectnode.h",
|
||||||
"include/qmlstate.h",
|
"include/qmlstate.h",
|
||||||
|
"include/qmlconnections.h",
|
||||||
"include/removebasestateexception.h",
|
"include/removebasestateexception.h",
|
||||||
"include/documentmessage.h",
|
"include/documentmessage.h",
|
||||||
"include/rewriterview.h",
|
"include/rewriterview.h",
|
||||||
@@ -391,6 +392,7 @@ Project {
|
|||||||
"model/qmlmodelnodefacade.cpp",
|
"model/qmlmodelnodefacade.cpp",
|
||||||
"model/qmlobjectnode.cpp",
|
"model/qmlobjectnode.cpp",
|
||||||
"model/qmlstate.cpp",
|
"model/qmlstate.cpp",
|
||||||
|
"model/qmlconnections.cpp",
|
||||||
"model/qmltextgenerator.cpp",
|
"model/qmltextgenerator.cpp",
|
||||||
"model/qmltextgenerator.h",
|
"model/qmltextgenerator.h",
|
||||||
"model/rewriteaction.cpp",
|
"model/rewriteaction.cpp",
|
||||||
@@ -739,6 +741,12 @@ Project {
|
|||||||
"bindingeditor/bindingeditorwidget.h",
|
"bindingeditor/bindingeditorwidget.h",
|
||||||
"bindingeditor/connectionvisitor.cpp",
|
"bindingeditor/connectionvisitor.cpp",
|
||||||
"bindingeditor/connectionvisitor.h",
|
"bindingeditor/connectionvisitor.h",
|
||||||
|
"bindingeditor/signallist.cpp",
|
||||||
|
"bindingeditor/signallist.h",
|
||||||
|
"bindingeditor/signallistdialog.cpp",
|
||||||
|
"bindingeditor/signallistdialog.h",
|
||||||
|
"bindingeditor/signallistdelegate.cpp",
|
||||||
|
"bindingeditor/signallistdelegate.h",
|
||||||
"colortool/colortool.cpp",
|
"colortool/colortool.cpp",
|
||||||
"colortool/colortool.h",
|
"colortool/colortool.h",
|
||||||
"connectioneditor/addnewbackenddialog.h",
|
"connectioneditor/addnewbackenddialog.h",
|
||||||
|
|||||||
@@ -70,6 +70,7 @@
|
|||||||
#include <texteditor/texteditoractionhandler.h>
|
#include <texteditor/texteditoractionhandler.h>
|
||||||
#include <texteditor/textmark.h>
|
#include <texteditor/textmark.h>
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
#include <utils/delegates.h>
|
#include <utils/delegates.h>
|
||||||
#include <utils/changeset.h>
|
#include <utils/changeset.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
@@ -373,8 +374,13 @@ void QmlJSEditorWidget::updateUses()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
QList<QTextEdit::ExtraSelection> selections;
|
QList<QTextEdit::ExtraSelection> selections;
|
||||||
foreach (const SourceLocation &loc,
|
QList<SourceLocation> locations
|
||||||
m_qmlJsEditorDocument->semanticInfo().idLocations.value(wordUnderCursor())) {
|
= m_qmlJsEditorDocument->semanticInfo().idLocations.value(wordUnderCursor());
|
||||||
|
// code model may present the locations not in a document order
|
||||||
|
Utils::sort(locations, [](const SourceLocation &lhs, const SourceLocation &rhs) {
|
||||||
|
return lhs.begin() < rhs.begin();
|
||||||
|
});
|
||||||
|
for (const SourceLocation &loc : qAsConst(locations)) {
|
||||||
if (! loc.isValid())
|
if (! loc.isValid())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
@@ -258,6 +258,62 @@ TEST_F(SqliteStatement, BindPointer)
|
|||||||
ASSERT_THAT(statement.fetchIntValue(0), 1);
|
ASSERT_THAT(statement.fetchIntValue(0), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SqliteStatement, BindIntCarray)
|
||||||
|
{
|
||||||
|
SqliteTestStatement statement("SELECT value FROM carray(?)", database);
|
||||||
|
std::vector<int> values{3, 10, 20, 33, 55};
|
||||||
|
|
||||||
|
statement.bind(1, values);
|
||||||
|
statement.next();
|
||||||
|
statement.next();
|
||||||
|
statement.next();
|
||||||
|
statement.next();
|
||||||
|
|
||||||
|
ASSERT_THAT(statement.fetchIntValue(0), 33);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SqliteStatement, BindLongLongCarray)
|
||||||
|
{
|
||||||
|
SqliteTestStatement statement("SELECT value FROM carray(?)", database);
|
||||||
|
std::vector<long long> values{3, 10, 20, 33, 55};
|
||||||
|
|
||||||
|
statement.bind(1, values);
|
||||||
|
statement.next();
|
||||||
|
statement.next();
|
||||||
|
statement.next();
|
||||||
|
statement.next();
|
||||||
|
|
||||||
|
ASSERT_THAT(statement.fetchLongLongValue(0), 33);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SqliteStatement, BindDoubleCarray)
|
||||||
|
{
|
||||||
|
SqliteTestStatement statement("SELECT value FROM carray(?)", database);
|
||||||
|
std::vector<double> values{3.3, 10.2, 20.54, 33.21, 55};
|
||||||
|
|
||||||
|
statement.bind(1, values);
|
||||||
|
statement.next();
|
||||||
|
statement.next();
|
||||||
|
statement.next();
|
||||||
|
statement.next();
|
||||||
|
|
||||||
|
ASSERT_THAT(statement.fetchDoubleValue(0), 33.21);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SqliteStatement, BindTextCarray)
|
||||||
|
{
|
||||||
|
SqliteTestStatement statement("SELECT value FROM carray(?)", database);
|
||||||
|
std::vector<const char *> values{"yi", "er", "san", "se", "wu"};
|
||||||
|
|
||||||
|
statement.bind(1, values);
|
||||||
|
statement.next();
|
||||||
|
statement.next();
|
||||||
|
statement.next();
|
||||||
|
statement.next();
|
||||||
|
|
||||||
|
ASSERT_THAT(statement.fetchSmallStringViewValue(0), Eq("se"));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(SqliteStatement, BindBlob)
|
TEST_F(SqliteStatement, BindBlob)
|
||||||
{
|
{
|
||||||
SqliteTestStatement statement("WITH T(blob) AS (VALUES (?)) SELECT blob FROM T", database);
|
SqliteTestStatement statement("WITH T(blob) AS (VALUES (?)) SELECT blob FROM T", database);
|
||||||
@@ -378,6 +434,47 @@ TEST_F(SqliteStatement, WritePointerValues)
|
|||||||
ASSERT_THAT(statement.template values<int>(5), ElementsAre(1, 1, 2, 3, 5));
|
ASSERT_THAT(statement.template values<int>(5), ElementsAre(1, 1, 2, 3, 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SqliteStatement, WriteIntCarrayValues)
|
||||||
|
{
|
||||||
|
SqliteTestStatement statement("SELECT value FROM carray(?)", database);
|
||||||
|
std::vector<int> values{3, 10, 20, 33, 55};
|
||||||
|
|
||||||
|
statement.write(Utils::span(values));
|
||||||
|
|
||||||
|
ASSERT_THAT(statement.template values<int>(5), ElementsAre(3, 10, 20, 33, 55));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SqliteStatement, WriteLongLongCarrayValues)
|
||||||
|
{
|
||||||
|
SqliteTestStatement statement("SELECT value FROM carray(?)", database);
|
||||||
|
std::vector<long long> values{3, 10, 20, 33, 55};
|
||||||
|
|
||||||
|
statement.write(Utils::span(values));
|
||||||
|
|
||||||
|
ASSERT_THAT(statement.template values<long long>(5), ElementsAre(3, 10, 20, 33, 55));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SqliteStatement, WriteDoubleCarrayValues)
|
||||||
|
{
|
||||||
|
SqliteTestStatement statement("SELECT value FROM carray(?)", database);
|
||||||
|
std::vector<double> values{3.3, 10.2, 20.54, 33.21, 55};
|
||||||
|
|
||||||
|
statement.write(Utils::span(values));
|
||||||
|
|
||||||
|
ASSERT_THAT(statement.template values<double>(5), ElementsAre(3.3, 10.2, 20.54, 33.21, 55));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SqliteStatement, WriteTextCarrayValues)
|
||||||
|
{
|
||||||
|
SqliteTestStatement statement("SELECT value FROM carray(?)", database);
|
||||||
|
std::vector<const char *> values{"yi", "er", "san", "se", "wu"};
|
||||||
|
|
||||||
|
statement.write(Utils::span(values));
|
||||||
|
|
||||||
|
ASSERT_THAT(statement.template values<Utils::SmallString>(5),
|
||||||
|
ElementsAre("yi", "er", "san", "se", "wu"));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(SqliteStatement, WriteNullValues)
|
TEST_F(SqliteStatement, WriteNullValues)
|
||||||
{
|
{
|
||||||
WriteStatement statement("UPDATE test SET name=?, number=? WHERE rowid=?", database);
|
WriteStatement statement("UPDATE test SET name=?, number=? WHERE rowid=?", database);
|
||||||
|
|||||||