Merge remote-tracking branch 'origin/6.0'
Conflicts: src/plugins/coreplugin/editormanager/editormanager.cpp Change-Id: I80fe565749ad5c06dfe99436f2dc6ab4b66a2537
4
.github/workflows/build_cmake.yml
vendored
@@ -709,14 +709,14 @@ jobs:
|
||||
|
||||
- name: Download qtcreatorcdbext artifact
|
||||
if: matrix.config.artifact == 'Windows-MSVC'
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: qtcreatorcdbext-${{ matrix.config.artifact }}-${{ github.run_id }}.7z
|
||||
path: ./
|
||||
|
||||
- name: Download disk image artifact
|
||||
if: matrix.config.artifact == 'macOS'
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: qt-creator-${{ matrix.config.artifact }}-${{ github.run_id }}.dmg
|
||||
path: ./
|
||||
|
||||
@@ -100,6 +100,7 @@ if(Googletest_FOUND AND NOT TARGET Googletest)
|
||||
GTEST_HAS_PARAM_TEST
|
||||
GTEST_HAS_DEATH_TEST
|
||||
)
|
||||
set_target_properties(Googletest PROPERTIES AUTOMOC OFF AUTOUIC OFF)
|
||||
|
||||
target_link_libraries(Googletest Threads::Threads)
|
||||
endif()
|
||||
|
||||
@@ -26,6 +26,7 @@ else()
|
||||
INCLUDES ${YAML_SOURCE_DIR}/include
|
||||
PUBLIC_DEFINES YAML_CPP_DLL
|
||||
PUBLIC_INCLUDES ${YAML_SOURCE_DIR}/include
|
||||
PROPERTIES AUTOMOC OFF AUTOUIC OFF
|
||||
SOURCES
|
||||
${YAML_SOURCE_DIR}/include/yaml-cpp
|
||||
${YAML_SOURCE_DIR}/include/yaml-cpp/anchor.h
|
||||
|
||||
@@ -869,7 +869,7 @@ function(finalize_qtc_gtest test_name exclude_sources_regex)
|
||||
list(FILTER test_sources EXCLUDE REGEX "${exclude_sources_regex}")
|
||||
endif()
|
||||
include(GoogleTest)
|
||||
gtest_add_tests(TARGET ${test_name} SOURCES ${test_sources} TEST_LIST test_list)
|
||||
gtest_add_tests(TARGET ${test_name} SOURCES ${test_sources} TEST_LIST test_list SKIP_DEPENDENCY)
|
||||
|
||||
foreach(test IN LISTS test_list)
|
||||
finalize_test_setup(${test})
|
||||
@@ -1021,6 +1021,7 @@ function(qtc_add_resources target resourceName)
|
||||
|
||||
target_sources(${target} PRIVATE "${generatedSourceCode}")
|
||||
set_property(SOURCE "${generatedSourceCode}" PROPERTY SKIP_AUTOGEN ON)
|
||||
set_property(SOURCE "${generatedResourceFile}.in" PROPERTY SKIP_AUTOGEN ON)
|
||||
endfunction()
|
||||
|
||||
function(qtc_add_public_header header)
|
||||
|
||||
118
dist/changes-6.0.1.md
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
Qt Creator 6.0.1
|
||||
================
|
||||
|
||||
Qt Creator version 6.0.1 contains bug fixes.
|
||||
|
||||
The most important changes are listed in this document. For a complete list of
|
||||
changes, see the Git log for the Qt Creator sources that you can check out from
|
||||
the public Git repository. For example:
|
||||
|
||||
git clone git://code.qt.io/qt-creator/qt-creator.git
|
||||
git log --cherry-pick --pretty=oneline origin/v6.0.0..v6.0.1
|
||||
|
||||
Editing
|
||||
-------
|
||||
|
||||
* Fixed cursor position after pasting and moving (QTCREATORBUG-26635)
|
||||
* Fixed deletion of start or end of word when camel case navigation is off
|
||||
(QTCREATORBUG-26646)
|
||||
* Fixed crash when removing built-in snippets (QTCREATORBUG-26648)
|
||||
|
||||
### C++
|
||||
|
||||
* Clangd
|
||||
* Improved indexing performance on macOS
|
||||
* Fixed issues with refactoring (QTCREATORBUG-26649)
|
||||
* Fixed warnings for multiple `/Tx` options with MSVC (QTCREATORBUG-26664)
|
||||
|
||||
### Language Client
|
||||
|
||||
* Fixed sending of `textDocument/didChange` notifications (QTCREATORBUG-26651)
|
||||
|
||||
Projects
|
||||
--------
|
||||
|
||||
* Fixed canceling GUI processes as build steps (QTCREATORBUG-26687)
|
||||
|
||||
### CMake
|
||||
|
||||
* Fixed initial CMake arguments for Windows ARM targets (QTCREATORBUG-26636)
|
||||
|
||||
### Qbs
|
||||
|
||||
* Fixed support for C++23 with MSVC (QTCREATORBUG-26663)
|
||||
|
||||
Debugging
|
||||
---------
|
||||
|
||||
* Fixed interrupting console applications
|
||||
|
||||
### GDB
|
||||
|
||||
* Fixed `PATH` for debugging MinGW applications (QTCREATORBUG-26670)
|
||||
|
||||
Test Integration
|
||||
----------------
|
||||
|
||||
### Google Test
|
||||
|
||||
* Fixed that application arguments could change order
|
||||
|
||||
Platforms
|
||||
---------
|
||||
|
||||
### Linux
|
||||
|
||||
* Removed dependency of prebuilt packages on libGLX and libOpenGL
|
||||
(QTCREATORBUG-26652)
|
||||
|
||||
### macOS
|
||||
|
||||
* Fixed running applications that access Bluetooth (QTCREATORBUG-26666)
|
||||
* Fixed saving of file system case sensitivity setting
|
||||
|
||||
### Android
|
||||
|
||||
* Fixed keystore handling on Windows (QTCREATORBUG-26647)
|
||||
|
||||
### Boot2Qt
|
||||
|
||||
* Fixed flashing wizard on Windows
|
||||
|
||||
### QNX
|
||||
|
||||
* Fixed codemodel issues (QTCREATORBUG-23483)
|
||||
|
||||
Credits for these changes go to:
|
||||
--------------------------------
|
||||
Aleksei German
|
||||
Alessandro Portale
|
||||
André Pönitz
|
||||
Antti Määttä
|
||||
BogDan Vatra
|
||||
Christiaan Janssen
|
||||
Christian Kandeler
|
||||
Christian Stenger
|
||||
Cristian Adam
|
||||
David Schulz
|
||||
Dawid Śliwa
|
||||
Eike Ziller
|
||||
Henning Gruendl
|
||||
Jaroslaw Kobus
|
||||
Joni Poikelin
|
||||
Kai Köhne
|
||||
Kaj Grönholm
|
||||
Knud Dollereder
|
||||
Leena Miettinen
|
||||
Mahmoud Badri
|
||||
Marco Bubke
|
||||
Miikka Heikkinen
|
||||
Oliver Wolff
|
||||
Petar Perisin
|
||||
Robert Löhning
|
||||
Samuel Ghinet
|
||||
Sergey Levin
|
||||
Tapani Mattila
|
||||
Thomas Hartmann
|
||||
Vikas Pachdha
|
||||
Youri Westerman
|
||||
|
Before Width: | Height: | Size: 966 B After Width: | Height: | Size: 434 B |
|
Before Width: | Height: | Size: 147 B After Width: | Height: | Size: 272 B |
|
Before Width: | Height: | Size: 123 B |
@@ -132,8 +132,18 @@
|
||||
\li Build the application by using the appropriate configuration
|
||||
parameters (if you build the application with \QC, it automatically
|
||||
uses the correct configuration):
|
||||
\list
|
||||
\li When using CMake, the
|
||||
\l{CMake: target_compile_definitions command}
|
||||
{target_compile_definitions} command is defined
|
||||
in the CMakeLists.txt file:
|
||||
\c {target_compile_definitions(myapp PRIVATE QT_QML_DEBUG)}
|
||||
|
||||
Where \e myapp is the application to debug.
|
||||
\li When using qmake, the following value is defined for the
|
||||
\l CONFIG property in the .pro file:
|
||||
\c {CONFIG += qml_debug}
|
||||
\endlist
|
||||
\endif
|
||||
|
||||
\li Start the application with the following arguments:
|
||||
|
||||
@@ -121,6 +121,14 @@
|
||||
\externalpage https://cmake.org/cmake/help/latest/command/set_property.html
|
||||
\title CMake: set_property command
|
||||
*/
|
||||
/*!
|
||||
\externalpage https://cmake.org/cmake/help/latest/command/target_compile_definitions.html
|
||||
\title CMake: target_compile_definitions command
|
||||
*/
|
||||
/*!
|
||||
\externalpage https://cmake.org/cmake/help/latest/command/target_link_libraries.html
|
||||
\title CMake: target_link_libraries command
|
||||
*/
|
||||
/*!
|
||||
\externalpage https://cmake.org/cmake/help/latest/command/target_sources.html
|
||||
\title CMake: target_sources command
|
||||
|
||||
@@ -197,7 +197,8 @@
|
||||
|
||||
\section1 Supported Qt for MCUs SDKs
|
||||
|
||||
Since version 4.12.4, \QC supports version 1.3 and later of the Qt for MCUs SDK.
|
||||
Since version 4.12.4, \QC supports versions 1.3 through 1.9 of the Qt for MCUs SDK.
|
||||
Since version 6.0.0, \QC adds support for versions 2.0 and later of the Qt for MCUs SDK.
|
||||
For older versions refer to the following table.
|
||||
|
||||
\table
|
||||
@@ -205,8 +206,11 @@
|
||||
\li \QC version
|
||||
\li Qt for MCUs SDK version
|
||||
\row
|
||||
\li 4.12.4 or later
|
||||
\li 1.3 or later
|
||||
\li 6.0.0 or later
|
||||
\li 1.3 or later, including 2.0 or later
|
||||
\row
|
||||
\li 4.12.4 up to 5.0.3
|
||||
\li 1.3 up to 1.9
|
||||
\row
|
||||
\li 4.12.2 or 4.12.3
|
||||
\li 1.2
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Creator documentation.
|
||||
@@ -59,7 +59,8 @@
|
||||
|
||||
Specify whether the library is statically or dynamically linked. For a
|
||||
statically linked internal library, \QC adds dependencies
|
||||
(PRE_TARGETDEPS) in the project file.
|
||||
(\l{CMake: target_link_libraries command}{target_link_libraries} when using
|
||||
CMake or \l PRE_TARGETDEPS when using qmake) in the project file.
|
||||
|
||||
Depending on the development platform, some options might be detected
|
||||
automatically. For example, on \macos, the library type (\uicontrol Library or
|
||||
@@ -128,22 +129,29 @@
|
||||
\li In the \uicontrol Library field, select \b mylib, and then select
|
||||
\uicontrol Next.
|
||||
|
||||
\li Select \uicontrol Finish to add the following library declaration to the
|
||||
project file:
|
||||
\li Select \uicontrol Finish to add the library declaration to the
|
||||
project file.
|
||||
|
||||
\code
|
||||
\endlist
|
||||
|
||||
When using CMake, the \c target_link_libraries command is added to the
|
||||
CMakeLists.txt file:
|
||||
|
||||
\badcode
|
||||
target_link_libraries(myapp PRIVATE mylib)
|
||||
\endcode
|
||||
|
||||
When using qmake, the following library declaration is added to the .pro
|
||||
file:
|
||||
|
||||
\badcode
|
||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../../projects/mylib/release/ -lmylib
|
||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../../projects/mylib/debug/ -lmylib
|
||||
else:unix: LIBS += -L$$OUT_PWD/../../../projects/mylib/ -lmylib
|
||||
|
||||
INCLUDEPATH += $$PWD/../../../projects/mylib
|
||||
DEPENDPATH += $$PWD/../../../projects/mylib
|
||||
|
||||
win32:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../../projects/mylib/release/mylib.lib
|
||||
else:win32:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../../projects/mylib/debug/mylib.lib
|
||||
else:unix: PRE_TARGETDEPS += $$OUT_PWD/../../../projects/mylib/libmylib.a
|
||||
\endcode
|
||||
|
||||
\endlist
|
||||
|
||||
*/
|
||||
|
||||
@@ -19,7 +19,6 @@ sourcedirs = ../src \
|
||||
imagedirs = ../images \
|
||||
../examples/doc/images \
|
||||
../../qtcreator/images \
|
||||
../../../plugins/qmldesigner/qmlpreviewplugin/images \
|
||||
../../../share/qtcreator/qml/qmlpuppet/mockfiles/images \
|
||||
../../../share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/images \
|
||||
../../../src/libs/qmleditorwidgets/images \
|
||||
|
||||
@@ -122,14 +122,14 @@
|
||||
\image coffee-machine-timeline.png
|
||||
|
||||
Our viewport contains 200 frames, so we select the
|
||||
\inlineimage plus.png "Plus button"
|
||||
\inlineimage icons/plus.png "Plus button"
|
||||
button to add a 1200-frame timeline to the root component.
|
||||
We use the default values for all other fields.
|
||||
|
||||
To start recording the transition from the startup screen to the coffee
|
||||
selection screen on the timeline, we select \e choosingCoffee in
|
||||
\l Navigator. We check that the playhead is at frame 0, and then
|
||||
select the \inlineimage recordfill.png
|
||||
select the \inlineimage icons/recordfill.png
|
||||
(\uicontrol {Auto Key (K)}) button (or press \key k).
|
||||
|
||||
At frame 0, we set the X coordinate to 0 in \l Properties >
|
||||
|
||||
@@ -55,14 +55,14 @@
|
||||
the screens in \e {Screen01.ui.qml}.
|
||||
|
||||
Our viewport contains 1000 frames, so we select the
|
||||
\inlineimage plus.png "Plus button"
|
||||
\inlineimage icons/plus.png "Plus button"
|
||||
button to add a 5000-frame timeline to the root component.
|
||||
We use the default values for all other fields.
|
||||
|
||||
To start recording the transitions between the Standard screen and the
|
||||
Trip and Navigator screens on the timeline, we select \e screenCanvas in
|
||||
the \l Navigator view. We check that the playhead is at frame 0, and then
|
||||
select the \inlineimage recordfill.png
|
||||
select the \inlineimage icons/recordfill.png
|
||||
(\uicontrol {Auto Key (K)}) button (or press \key k).
|
||||
|
||||
\image ebikedesign-timeline.png "Timeline view"
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
To add the assets to \l Library:
|
||||
\list 1
|
||||
\li Select \uicontrol Library > \uicontrol Assets
|
||||
> \inlineimage plus.png
|
||||
> \inlineimage icons/plus.png
|
||||
.
|
||||
\li Select the asset files, and then select \uicontrol Open.
|
||||
\li Select the location where the files will be saved in the
|
||||
@@ -281,7 +281,7 @@
|
||||
The \l {Images}{Image} component is used for adding images to the UI in several
|
||||
supported formats, including bitmap formats such as PNG and JPEG and vector
|
||||
graphics formats such as SVG. To add an image to \uicontrol Library, select
|
||||
\uicontrol Assets > \inlineimage plus.png
|
||||
\uicontrol Assets > \inlineimage icons/plus.png
|
||||
, and then select the image file.
|
||||
|
||||
If you need to display animated images, use the \l {Animated Image}
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
\li Select \uicontrol View > \uicontrol Views >
|
||||
\uicontrol {Connection View} to open the \uicontrol Connections tab.
|
||||
\li Select \e createAccount in \uicontrol Navigator.
|
||||
\li In the \uicontrol Connections tab, select the \inlineimage plus.png
|
||||
\li In the \uicontrol Connections tab, select the \inlineimage icons/plus.png
|
||||
button to add the action that the \c onClicked signal handler of
|
||||
\e createAccount should apply.
|
||||
\li Double-click the value \uicontrol Action column and select
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
\li Double-click \e Screen01.ui.qml in \l Projects to open it
|
||||
in \l {Form Editor}.
|
||||
\li In the \l States view, select \e login, and then select
|
||||
\inlineimage close.png
|
||||
\inlineimage icons/close.png
|
||||
to remove the state. Repeat for the \e createAccount state.
|
||||
\li Select \e username in \l Navigator, and then select
|
||||
\inlineimage arrowleft.png
|
||||
@@ -143,7 +143,7 @@
|
||||
\list 1
|
||||
\li Select \uicontrol View > \uicontrol Views >
|
||||
\uicontrol Timeline to open the \l Timeline view.
|
||||
\li In \uicontrol Timeline, select \inlineimage plus.png
|
||||
\li In \uicontrol Timeline, select \inlineimage icons/plus.png
|
||||
to add a 1000-frame timeline and settings for running the animation.
|
||||
\image loginui4-timeline-settings.png
|
||||
\li In the \uicontrol {Animation ID} field, enter
|
||||
@@ -172,7 +172,7 @@
|
||||
opacity property of the component.
|
||||
\image loginui4-keyframe-opacity.png "Inserting keyframe for opacity property"
|
||||
\li In \uicontrol Timeline, check that the playhead is in
|
||||
frame 0, and select the \inlineimage recordfill.png
|
||||
frame 0, and select the \inlineimage icons/recordfill.png
|
||||
(\uicontrol {Per Property Recording}) button for the
|
||||
\uicontrol opacity property of \e repeatPassword to start
|
||||
recording property changes.
|
||||
@@ -183,7 +183,7 @@
|
||||
to show the button.
|
||||
|
||||
To fine-tune the value of a keyframe, you can also right-click the
|
||||
keyframe marker \inlineimage keyframe_linear_inactive.png
|
||||
keyframe marker \inlineimage icons/keyframe_linear_active.png
|
||||
, and select \uicontrol {Edit Keyframe}.
|
||||
\li Select the record button again to stop recording property changes.
|
||||
If you forget this, all the following changes will be recorded, and
|
||||
@@ -236,7 +236,7 @@
|
||||
margin animation that will make the transition seem smoother:
|
||||
|
||||
\list 1
|
||||
\li Click the keyframe marker \inlineimage keyframe_linear_inactive.png
|
||||
\li Click the keyframe marker \inlineimage icons/keyframe_linear_active.png
|
||||
for the \e anchors.topMargin property at frame 1000 on the
|
||||
timeline to select it.
|
||||
\image loginui4-easing-curve-top-anchor-margin.png "Top anchor margin keyframe marker"
|
||||
@@ -249,8 +249,8 @@
|
||||
\endlist
|
||||
|
||||
When you attach easing curves to keyframes, the shape of the keyframe
|
||||
marker changes from \inlineimage keyframe_linear_inactive.png
|
||||
to \inlineimage keyframe_manualbezier_inactive.png
|
||||
marker changes from \inlineimage icons/keyframe_linear_active.png
|
||||
to \inlineimage icons/keyframe_manualbezier_active.png
|
||||
.
|
||||
|
||||
Your timeline should now look something like this:
|
||||
|
||||
@@ -90,14 +90,14 @@
|
||||
\section2 Adding Color Animation
|
||||
|
||||
First, we add a color animation to the \e root component in the \e Root.qml
|
||||
file. We select the \inlineimage plus.png
|
||||
file. We select the \inlineimage icons/plus.png
|
||||
button to add a 100-frame timeline to root. You can use the default
|
||||
values for all other fields.
|
||||
|
||||
\image progressbar-timeline-settings.png "Timeline settings"
|
||||
|
||||
To start recording a color animation on the timeline, we check that the
|
||||
playhead is at frame 0 and then select the \inlineimage recordfill.png
|
||||
playhead is at frame 0 and then select the \inlineimage icons/recordfill.png
|
||||
(\uicontrol {Auto Key (K)}) button (or press \key k).
|
||||
|
||||
\image progressbar-timeline.png "Color animation timeline"
|
||||
@@ -194,7 +194,7 @@
|
||||
use a column layout to lay out the progress bar instances.
|
||||
|
||||
We can now add timelines for each progress bar instance, with different
|
||||
settings. We select the \inlineimage plus.png
|
||||
settings. We select the \inlineimage icons/plus.png
|
||||
button to add a 4000-frame timeline to the first progress bar instance
|
||||
(\e root). We select the \uicontrol Continuous check box so that the
|
||||
animation will loop.
|
||||
@@ -236,8 +236,8 @@
|
||||
\image studio-easing-curve-editor.png "Easing Curve Editor"
|
||||
|
||||
When we apply easing curves to animations, the shape of the keyframe
|
||||
marker changes from \inlineimage keyframe_linear_inactive.png
|
||||
to \inlineimage keyframe_manualbezier_inactive.png
|
||||
marker changes from \inlineimage icons/keyframe_linear_active.png
|
||||
to \inlineimage icons/keyframe_manualbezier_active.png
|
||||
.
|
||||
|
||||
For more information, see \l{Editing Easing Curves}.
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
In addition, we set the \uicontrol Checked property to \c true for the
|
||||
first button instance on the menu bar to make it appear selected.
|
||||
|
||||
We can now select the \inlineimage run_small.png "Run button"
|
||||
We can now select the \inlineimage icons/run_small.png "Run button"
|
||||
(\uicontrol Run) button to run the application and test our menu bar.
|
||||
|
||||
\section1 Creating a Side Menu
|
||||
@@ -153,7 +153,7 @@
|
||||
|
||||
\image sidemenu-states.png "Side menu states"
|
||||
|
||||
We then select the \inlineimage plus.png
|
||||
We then select the \inlineimage icons/plus.png
|
||||
button in the \l Timeline view to add animation
|
||||
for transitions to the \e open and \e close states:
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
We want to change the position of the outline and background images. To
|
||||
start recording the transition from the closed state to the open state,
|
||||
we select \e imageOutline in \uicontrol Navigator. We check that the
|
||||
playhead is at frame 0, and then select the \inlineimage recordfill.png
|
||||
playhead is at frame 0, and then select the \inlineimage icons/recordfill.png
|
||||
(\uicontrol {Auto Key (K)}) button (or press \key k).
|
||||
|
||||
At frame 0, we set the X coordinate to -423 in \uicontrol Properties >
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
text into \l{Text Edit} or \l{Text Input} components. For more information
|
||||
about using it, see \l{User Guide}{Virtual Keyboard: User Guide}.
|
||||
|
||||
To test the virtual keyboard, you need to select the \inlineimage run_small.png
|
||||
To test the virtual keyboard, you need to select the \inlineimage icons/run_small.png
|
||||
(\uicontrol Run) button to run the example on the desktop or a device.
|
||||
The keyboard is not available during preview.
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
|
||||
We can now add a timeline animation to make the arc move around the button
|
||||
when the button is pressed. In the \uicontrol Timeline view, we select the
|
||||
\inlineimage plus.png
|
||||
\inlineimage icons/plus.png
|
||||
button to add a 1000-frame timeline to the \e root of the component.
|
||||
We'll use the default values for all other fields.
|
||||
|
||||
@@ -150,7 +150,7 @@
|
||||
\image washingmachineui-insert-keyframe.png "Inserting keyframe for Rotation property"
|
||||
|
||||
To start recording a rotation animation on the timeline, we check that the
|
||||
playhead is at frame 0 and then select the \inlineimage recordfill.png
|
||||
playhead is at frame 0 and then select the \inlineimage icons/recordfill.png
|
||||
(\uicontrol {Auto Key (K)}) button (or press \key k).
|
||||
|
||||
First, we set the rotation at frame 0 to -90 in \uicontrol Properties >
|
||||
@@ -214,7 +214,7 @@
|
||||
|
||||
Then, we select the mouse area for the start button, \e startMA,
|
||||
in \uicontrol Navigator. In \l {Connection View} > \uicontrol Connections,
|
||||
we select the \inlineimage plus.png
|
||||
we select the \inlineimage icons/plus.png
|
||||
(\uicontrol Add) button to connect the \c onClicked() signal handler
|
||||
of the button to the \c startClicked() signal.
|
||||
|
||||
|
||||
BIN
doc/qtdesignstudio/images/icons/boundingrect.png
Normal file
|
After Width: | Height: | Size: 108 B |
BIN
doc/qtdesignstudio/images/icons/close.png
Normal file
|
After Width: | Height: | Size: 165 B |
BIN
doc/qtdesignstudio/images/icons/eye_open.png
Normal file
|
After Width: | Height: | Size: 165 B |
BIN
doc/qtdesignstudio/images/icons/keyframe_autobezier_active.png
Normal file
|
After Width: | Height: | Size: 268 B |
BIN
doc/qtdesignstudio/images/icons/keyframe_linear_active.png
Normal file
|
After Width: | Height: | Size: 327 B |
|
After Width: | Height: | Size: 204 B |
BIN
doc/qtdesignstudio/images/icons/keyframe_manualbezier_active.png
Normal file
|
After Width: | Height: | Size: 336 B |
BIN
doc/qtdesignstudio/images/icons/live_preview.png
Normal file
|
After Width: | Height: | Size: 198 B |
BIN
doc/qtdesignstudio/images/icons/unlocked.png
Normal file
|
After Width: | Height: | Size: 179 B |
|
Before Width: | Height: | Size: 367 B |
|
Before Width: | Height: | Size: 289 B |
|
Before Width: | Height: | Size: 434 B |
@@ -176,7 +176,7 @@
|
||||
|
||||
\list 1
|
||||
\li Click \uicontrol {Design} to edit the UI file in \l {Form Editor}.
|
||||
\li Select \l Library > \uicontrol Assets > \inlineimage plus.png
|
||||
\li Select \l Library > \uicontrol Assets > \inlineimage icons/plus.png
|
||||
to copy the image files you want to use to the project folder.
|
||||
\li In \l Navigator, select the root component and set the
|
||||
width (\uicontrol W) and height (\uicontrol H) of the button in the
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
first add them to \l Library:
|
||||
\list 1
|
||||
\li Select \uicontrol Library > \uicontrol Assets
|
||||
> \inlineimage plus.png
|
||||
> \inlineimage icons/plus.png
|
||||
.
|
||||
\li Select the image file, and then select \uicontrol Open.
|
||||
\li Select the location where the image will be saved in the
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
|
||||
For convenience, you can click the \inlineimage icons/anchor-fill.png
|
||||
(\uicontrol {Fill to Parent}) toolbar button to apply fill anchors to a
|
||||
component and the \inlineimage qtcreator-anchors-reset-icon.png
|
||||
component and the \inlineimage icons/qtcreator-anchors-reset-icon.png
|
||||
(\uicontrol {Reset Anchors}) button to reset the anchors to their saved
|
||||
state.
|
||||
|
||||
@@ -484,10 +484,10 @@
|
||||
\image qtquick-designer-stacked-view.png
|
||||
|
||||
To add components to a \uicontrol {Stack Layout}, select the
|
||||
\inlineimage plus.png
|
||||
\inlineimage icons/plus.png
|
||||
button next to the component name in \l {Form Editor}.
|
||||
To move between components, select the \inlineimage prev.png
|
||||
(\uicontrol Previous) and \inlineimage next.png
|
||||
To move between components, select the \inlineimage icons/prev.png
|
||||
(\uicontrol Previous) and \inlineimage icons/next.png
|
||||
(\uicontrol Next) buttons.
|
||||
|
||||
To add a tab bar to a stack layout, right-click on the
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
\title Preset Components
|
||||
|
||||
To use preset components, add the modules that contain them to your project
|
||||
by selecting \l Library > \uicontrol Components > \inlineimage plus.png
|
||||
by selecting \l Library > \uicontrol Components > \inlineimage icons/plus.png
|
||||
. For more information, see \l{Adding and Removing Modules}. You can then
|
||||
create instances of the components by dragging-and-dropping them from
|
||||
\uicontrol Library to \l {Form Editor}, \l {3D Editor}, or \l Navigator.
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
|
||||
\list 1
|
||||
\li Select \uicontrol Library > \l Assets
|
||||
> \inlineimage plus.png
|
||||
> \inlineimage icons/plus.png
|
||||
.
|
||||
\li Select the font file, and then select \uicontrol Open.
|
||||
\li Select the location where the file will be saved in the
|
||||
|
||||
@@ -77,10 +77,10 @@
|
||||
\li Select \uicontrol OK.
|
||||
\endlist
|
||||
|
||||
To add more comments about the component, select the \inlineimage plus.png
|
||||
To add more comments about the component, select the \inlineimage icons/plus.png
|
||||
(\uicontrol {Add Comment}) button.
|
||||
|
||||
To remove the active comment, select the \inlineimage minus.png
|
||||
To remove the active comment, select the \inlineimage icons/minus.png
|
||||
(\uicontrol {Remove Comment}) button. To remove the annotation, right-click
|
||||
the annotation icon, and then select \uicontrol {Remove Annotation}.
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
\list 1
|
||||
\li Select \uicontrol Library > \l Assets
|
||||
> \inlineimage plus.png
|
||||
> \inlineimage icons/plus.png
|
||||
.
|
||||
\li Browse to the folder that contains the font files and select them,
|
||||
and then select \uicontrol Open.
|
||||
|
||||
@@ -510,7 +510,7 @@
|
||||
\li Select the \inlineimage icons/edit.png
|
||||
(\uicontrol {Show Event List}) button on the Design mode
|
||||
\l{Summary of Main Toolbar Actions}{toolbar}, or press \key {Alt+E}.
|
||||
\li In the \uicontrol {Event List} dialog, select \inlineimage plus.png
|
||||
\li In the \uicontrol {Event List} dialog, select \inlineimage icons/plus.png
|
||||
to add a keyboard shortcut for triggering an event to the list.
|
||||
\image studio-flow-event-list.png "Event List dialog"
|
||||
\li In the \uicontrol {Event ID} field, enter an identifier for the
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
To import an asset, drag-and-drop the external file containing the asset from,
|
||||
for example, File Explorer on Windows, to \uicontrol {Form Editor},
|
||||
\uicontrol Navigator, or \uicontrol {Text Editor}. Alternatively, select
|
||||
\l Library > \uicontrol Assets > \inlineimage plus.png
|
||||
\l Library > \uicontrol Assets > \inlineimage icons/plus.png
|
||||
and follow the instructions in the \uicontrol {Asset Import} dialog. You can
|
||||
also multiselect several external asset files to drag-and-drop them to
|
||||
\QDS simultaneously.
|
||||
@@ -76,7 +76,7 @@
|
||||
create an empty project.
|
||||
\li In \uicontrol Projects, double-click \e Screen01.ui.qml to move to
|
||||
the Design mode.
|
||||
\li Select \l Library > \uicontrol Assets > \inlineimage plus.png
|
||||
\li Select \l Library > \uicontrol Assets > \inlineimage icons/plus.png
|
||||
.
|
||||
\li Select the folder where you exported the assets.
|
||||
\li Select \uicontrol {Exported Assets (*.metadata)} in the dropdown
|
||||
@@ -121,7 +121,7 @@
|
||||
|
||||
After importing the metadata files, wait a few moments to allow all
|
||||
imported assets to appear in your project files before selecting your
|
||||
metadata filename from \uicontrol Assets > \inlineimage plus.png
|
||||
metadata filename from \uicontrol Assets > \inlineimage icons/plus.png
|
||||
.
|
||||
|
||||
If asset importer conflicts, warnings, and errors are displayed in the
|
||||
|
||||
@@ -169,7 +169,7 @@
|
||||
\endlist
|
||||
|
||||
To use JavaScript and image files in the UI, select \uicontrol Library >
|
||||
\uicontrol Assets > \inlineimage plus.png
|
||||
\uicontrol Assets > \inlineimage icons/plus.png
|
||||
.
|
||||
|
||||
\section1 Adding Files to Projects
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
|
||||
To integrate the Simulink model into \QDS, you first need to add the
|
||||
Simulink connector module to your project. In the \l Library view, select
|
||||
\uicontrol Components > \inlineimage plus.png
|
||||
\uicontrol Components > \inlineimage icons/plus.png
|
||||
> \uicontrol SimulinkConnector. \QDS is now ready to communicate with the
|
||||
Simulink model.
|
||||
|
||||
@@ -156,7 +156,7 @@
|
||||
\uicontrol SimulinkConnector item in \l Navigator and set the IP address
|
||||
and/or port in the \l Properties view. If you cannot see
|
||||
\uicontrol SimulinkConnector in \uicontrol Navigator, you need to click
|
||||
\inlineimage filtericon.png
|
||||
\inlineimage icons/filtericon.png
|
||||
(\uicontrol {Filter Tree}) and unselect \uicontrol {Show only visible items}.
|
||||
|
||||
To communicate with a specific model in Simulink, you need to create
|
||||
|
||||
@@ -166,7 +166,7 @@
|
||||
|
||||
\section2 Importing Assets
|
||||
\list 1
|
||||
\li Select \uicontrol Library > \uicontrol Assets > \inlineimage plus.png
|
||||
\li Select \uicontrol Library > \uicontrol Assets > \inlineimage icons/plus.png
|
||||
.
|
||||
\image exporting-from-qt3ds/09-add-new-assets.png
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
|
||||
The \uicontrol Passes property contains a list of render passes
|
||||
implemented by the effect. You can add more entry fields to the list
|
||||
by selecting \inlineimage plus.png
|
||||
by selecting \inlineimage icons/plus.png
|
||||
. For more information, see \l {Custom Effects and Materials}.
|
||||
|
||||
\row
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
\l{Lights}{light}, \l{3D Models}{model}, and
|
||||
\l {Materials and Shaders}{materials}. If your scene did not contain
|
||||
them, you can add the corresponding \l {3D Components}{Qt Quick 3D}
|
||||
components from \l Library > \uicontrol Components > \inlineimage plus.png
|
||||
components from \l Library > \uicontrol Components > \inlineimage icons/plus.png
|
||||
> \uicontrol {Qt Quick 3D} > \uicontrol {Qt Quick 3D}.
|
||||
|
||||
You can use the \l{Summary of the 3D Editor Toolbar Buttons}{toolbar buttons}
|
||||
@@ -71,7 +71,7 @@
|
||||
grid.
|
||||
|
||||
To refresh the contents of \uicontrol {3D Editor}, press \key P or
|
||||
select the \inlineimage reset.png
|
||||
select the \inlineimage icons/reset.png
|
||||
(\uicontrol {Reset View}) button.
|
||||
|
||||
\image studio-3d-editor.png "3D Editor"
|
||||
@@ -297,7 +297,7 @@
|
||||
\li \key G
|
||||
\li
|
||||
\row
|
||||
\li \inlineimage reset.png
|
||||
\li \inlineimage icons/reset.png
|
||||
\li Reset View
|
||||
\li \key R
|
||||
\li
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
\list 1
|
||||
\li In the \l{Design Views}{Design mode}, select \l Library >
|
||||
\uicontrol Assets > \inlineimage plus.png
|
||||
\uicontrol Assets > \inlineimage icons/plus.png
|
||||
.
|
||||
\li Select \uicontrol {3D Assets} in the dropdown menu to filter 3D
|
||||
graphics files.
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
\uicontrol Instances, select each \uicontrol {Instance List Entry}
|
||||
you wish to include in the \uicontrol {Instance List} by using
|
||||
the dropdown menu. You can add more fields for the property by
|
||||
clicking the \inlineimage plus.png
|
||||
clicking the \inlineimage icons/plus.png
|
||||
icon.
|
||||
\li To define an \uicontrol {Instance List Entry}, select it in
|
||||
\uicontrol Navigator, and specify its properties in
|
||||
|
||||
@@ -227,6 +227,6 @@
|
||||
You can apply the same material to another component as well. Again,
|
||||
delete the default material first. You should then select the component and
|
||||
go to the \uicontrol Properties view. Find the \uicontrol Materials property,
|
||||
select the \inlineimage plus.png
|
||||
select the \inlineimage icons/plus.png
|
||||
icon, and choose the new material in the dropdown menu.
|
||||
*/
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
\l Properties view. You can apply the same material to another component as
|
||||
well. Again, delete the default material first. You should then select the
|
||||
component and go to the \uicontrol Properties view. Find the
|
||||
\uicontrol Materials property, select the \inlineimage plus.png
|
||||
\uicontrol Materials property, select the \inlineimage icons/plus.png
|
||||
icon, and choose the new material in the dropdown menu.
|
||||
|
||||
Each material has its own set of properties that can be used to further
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
\section1 Model Properties
|
||||
|
||||
You can change the model type in \uicontrol Properties > \uicontrol Model
|
||||
> \uicontrol Source field. Select the \inlineimage plus.png
|
||||
> \uicontrol Source field. Select the \inlineimage icons/plus.png
|
||||
button to add custom model types to the list.
|
||||
|
||||
\image studio-qtquick-3d-model.png "Model properties"
|
||||
@@ -69,7 +69,7 @@
|
||||
|
||||
A model can consist of several sub-meshes, each of which can have its own
|
||||
material. Select the material from the list in the \uicontrol {Materials}
|
||||
field. Select the \inlineimage plus.png
|
||||
field. Select the \inlineimage icons/plus.png
|
||||
button to add materials to the list. For more information about materials,
|
||||
see \l {Materials and Shaders}.
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
To add a particle system that emits sprite particles:
|
||||
|
||||
\list 1
|
||||
\li Select \uicontrol Library > \uicontrol Assets > \inlineimage plus.png
|
||||
\li Select \uicontrol Library > \uicontrol Assets > \inlineimage icons/plus.png
|
||||
to add your sprites, 3D models, textures, and other graphical
|
||||
\l{Assets}{assets} to the project.
|
||||
\li Drag-and-drop an instance of the \uicontrol {Particle System}
|
||||
@@ -1016,7 +1016,7 @@
|
||||
\uicontrol System.
|
||||
|
||||
To only affect some of the particles in the particle system, select
|
||||
them in \uicontrol Particles. Select \inlineimage plus.png
|
||||
them in \uicontrol Particles. Select \inlineimage icons/plus.png
|
||||
to add logical particles to the list.
|
||||
|
||||
Deselect \uicontrol Enabled to turn the affector off. Usually, this
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
\list 1
|
||||
\li Select \uicontrol View > \uicontrol Views >
|
||||
\l {Connection View} > \uicontrol {Bindings}.
|
||||
\li Select the \inlineimage plus.png
|
||||
\li Select the \inlineimage icons/plus.png
|
||||
(\uicontrol Add) button to add a binding for the currently selected
|
||||
component. The component ID is displayed in the \uicontrol Item
|
||||
column.
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
\list 1
|
||||
\li Select \uicontrol View > \uicontrol Views >
|
||||
\uicontrol {Connection View} > \uicontrol {Properties}.
|
||||
\li Select the \inlineimage plus.png
|
||||
\li Select the \inlineimage icons/plus.png
|
||||
(\uicontrol Add) button to add a dynamic property for the currently
|
||||
selected component. The component ID is displayed in the \uicontrol Item
|
||||
column.
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
\list 1
|
||||
\li Select \uicontrol View > \uicontrol Views >
|
||||
\l {Connection View} > \uicontrol {Connections}.
|
||||
\li Select the \inlineimage plus.png
|
||||
\li Select the \inlineimage icons/plus.png
|
||||
(\uicontrol Add) button to add a connection.
|
||||
\li Double-click the value in the \uicontrol Target column to add the
|
||||
component to connect to a signal.
|
||||
|
||||
@@ -148,19 +148,19 @@
|
||||
\li Keyboard Shortcut
|
||||
\li Read More
|
||||
\row
|
||||
\li \inlineimage prev.png
|
||||
\li \inlineimage icons/prev.png
|
||||
\li \uicontrol {Go Back}: moves a step backwards in your location history.
|
||||
That is, returns the focus to the last location in the last file it
|
||||
was on.
|
||||
\li \key Alt+< (\key Opt+Cmd+< on \macos)
|
||||
\li \l{Navigating Between Open Files and Symbols}
|
||||
\row
|
||||
\li \inlineimage next.png
|
||||
\li \inlineimage icons/next.png
|
||||
\li \uicontrol {Go Forward}: moves a step forward in your location history.
|
||||
\li \key Alt+> (\key Opt+Cmd+> on \macos)
|
||||
\li \l{Navigating Between Open Files and Symbols}
|
||||
\row
|
||||
\li \inlineimage unlocked.png
|
||||
\li \inlineimage icons/unlocked.png
|
||||
\li File is writable: the currently open file can be modified and saved.
|
||||
\li
|
||||
\li \l{Open Documents}
|
||||
@@ -178,7 +178,7 @@
|
||||
\li
|
||||
\li \l{Open Documents}
|
||||
\row
|
||||
\li \inlineimage close.png
|
||||
\li \inlineimage icons/close.png
|
||||
\li \uicontrol {Close Document}: closes the current file.
|
||||
\li \key Ctrl+W (\key Cmd+W on \macos)
|
||||
\li
|
||||
@@ -226,7 +226,7 @@
|
||||
\li \key Shift+F
|
||||
\li \l{Setting Anchors and Margins}
|
||||
\row
|
||||
\li \inlineimage qtcreator-anchors-reset-icon.png
|
||||
\li \inlineimage icons/qtcreator-anchors-reset-icon.png
|
||||
\li Resets anchors to their saved state for the selected component.
|
||||
\li \key Ctrl+Shift+R (\key Shift+Cmd+R on \macos)
|
||||
\li \l{Setting Anchors and Margins}
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
|
||||
When you attach easing curves to keyframes, the shape of the
|
||||
\l{keyframe_marker}{keyframe marker} on a keyframe track in
|
||||
\l Timeline changes from \inlineimage keyframe_linear_inactive.png
|
||||
\l Timeline changes from \inlineimage icons/keyframe_linear_active.png
|
||||
to a marker that describes the type of the selected easing curve.
|
||||
|
||||
\section1 Attaching Easing Curves to Transitions
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
align them.
|
||||
\li \l{Snapping to Parent and Sibling Components}
|
||||
\row
|
||||
\li \inlineimage boundingrect.png
|
||||
\li \inlineimage icons/boundingrect.png
|
||||
\li Hides and shows component instance boundaries.
|
||||
\li \l{Hiding Component Boundaries}
|
||||
\row
|
||||
@@ -108,7 +108,7 @@
|
||||
\li Zooms to fit the current selection.
|
||||
\li \l{Zooming}
|
||||
\row
|
||||
\li \inlineimage reset.png
|
||||
\li \inlineimage icons/reset.png
|
||||
\li Refreshes the contents of \uicontrol {Form Editor}.
|
||||
\li \l{Refreshing Form Editor Contents}
|
||||
\endtable
|
||||
@@ -199,7 +199,7 @@
|
||||
\section1 Hiding Component Boundaries
|
||||
|
||||
\uicontrol {Form Editor} displays the boundaries of component instances.
|
||||
To hide them, select the \inlineimage boundingrect.png
|
||||
To hide them, select the \inlineimage icons/boundingrect.png
|
||||
button.
|
||||
|
||||
\section1 Previewing Component Size
|
||||
@@ -254,7 +254,7 @@
|
||||
\uicontrol {Form Editor}.
|
||||
|
||||
To refresh the contents of \uicontrol {Form Editor}, press \key R or
|
||||
select the \inlineimage reset.png
|
||||
select the \inlineimage icons/reset.png
|
||||
(\uicontrol {Reset View}) button.
|
||||
|
||||
\include qtquick-component-context-menu.qdocinc context-menu
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
contains basic components and UI controls, while a 3D application project
|
||||
contains additional 3D components.
|
||||
|
||||
To view the list of available modules, select \inlineimage plus.png
|
||||
To view the list of available modules, select \inlineimage icons/plus.png
|
||||
. Most commonly used modules are placed at the top of the list in
|
||||
alphabetical order. You can search for components and modules by entering
|
||||
search criteria in the \uicontrol Search field.
|
||||
@@ -120,7 +120,7 @@
|
||||
|
||||
\uicontrol Library > \uicontrol {Assets} displays the images and other files
|
||||
that you add to the project folder by dragging-and-dropping external asset
|
||||
files to \QDS or by selecting \inlineimage plus.png
|
||||
files to \QDS or by selecting \inlineimage icons/plus.png
|
||||
. For more information about importing assets to \QDS, see
|
||||
\l {Importing 2D Assets} and \l {Importing 3D Assets}.
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
\li Moves the component up within its parent.
|
||||
\li \l{Arranging Components}
|
||||
\row
|
||||
\li \inlineimage filtericon.png
|
||||
\li \inlineimage icons/filtericon.png
|
||||
\li Shows and hides invisible components in \uicontrol Navigator.
|
||||
\li \l{Showing and Hiding Components}
|
||||
\row
|
||||
@@ -122,7 +122,7 @@
|
||||
parent component.
|
||||
|
||||
To hide invisible components in \uicontrol Navigator, click
|
||||
\inlineimage filtericon.png
|
||||
\inlineimage icons/filtericon.png
|
||||
(\uicontrol {Filter Tree}) and select
|
||||
\uicontrol {Show Only Visible Components}.
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
the bottom of the \uicontrol Navigator tree and behind overlapping
|
||||
components in \uicontrol {Form Editor}. To list the components in the order
|
||||
in which they appear in the file, as some other tools do, click
|
||||
\inlineimage filtericon.png
|
||||
\inlineimage icons/filtericon.png
|
||||
(\uicontrol {Filter Tree}), and select \uicontrol {Reverse Component Order}.
|
||||
|
||||
To move a component to the top or bottom of the tree within its parent,
|
||||
|
||||
@@ -178,7 +178,7 @@
|
||||
\list 1
|
||||
\li In the base state, add all components you will need in the
|
||||
application (1). While you work on one view, you can click the
|
||||
\inlineimage eye_open.png
|
||||
\inlineimage icons/eye_open.png
|
||||
icon in \l Navigator to hide components on the canvas that are
|
||||
not part of a view.
|
||||
\li In \uicontrol States, select \uicontrol {Create New State} to create
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
\image studio-timeline-empty.png "Empty Timeline view"
|
||||
|
||||
Select the \inlineimage plus.png
|
||||
Select the \inlineimage icons/plus.png
|
||||
(\uicontrol {Add Timeline}) button to \l{Creating Timelines}
|
||||
{create a timeline} and specify settings for it in the
|
||||
\uicontrol {Timeline Settings} dialog.
|
||||
@@ -225,13 +225,13 @@
|
||||
gray, and when a keyframe itself is selected, its marker turns
|
||||
brown:
|
||||
\list
|
||||
\li \inlineimage keyframe_linear_inactive.png
|
||||
\li \inlineimage icons/keyframe_linear_active.png
|
||||
- linear easing curve
|
||||
\li \inlineimage keyframe_manualbezier_inactive.png
|
||||
\li \inlineimage icons/keyframe_manualbezier_active.png
|
||||
- manually set Bezier curve
|
||||
\li \inlineimage keyframe_autobezier_inactive.png
|
||||
\li \inlineimage icons/keyframe_autobezier_active.png
|
||||
- automatically set Bezier curve
|
||||
\li \inlineimage keyframe_lineartobezier_inactive.png
|
||||
\li \inlineimage icons/keyframe_lineartobezier_active.png
|
||||
- linear-to-Bezier curve
|
||||
\endlist
|
||||
\li \l {Editing Easing Curves}
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
To create a timeline to animate a UI component:
|
||||
|
||||
\list 1
|
||||
\li In the \l Timeline view, select the \inlineimage plus.png
|
||||
\li In the \l Timeline view, select the \inlineimage icons/plus.png
|
||||
(\uicontrol {Add Timeline}) button to specify settings
|
||||
for the timeline and running the animation
|
||||
in the \uicontrol {Timeline Settings} dialog.
|
||||
@@ -82,12 +82,12 @@
|
||||
\li Select \uicontrol Close to close the dialog and save the settings.
|
||||
\endlist
|
||||
|
||||
To create additional timelines, select the \inlineimage plus.png
|
||||
To create additional timelines, select the \inlineimage icons/plus.png
|
||||
(\uicontrol {Add Timeline}) button next to the
|
||||
\uicontrol {Timeline Settings} tab.
|
||||
|
||||
To specify settings for running timeline animations, select the
|
||||
\inlineimage plus.png
|
||||
\inlineimage icons/plus.png
|
||||
(\uicontrol {Add Animation}) button next to the
|
||||
\uicontrol {Animation Settings} tab. For example, you could create
|
||||
settings for running a part of the timeline animation between specified
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
\li Select \uicontrol View > \uicontrol Views >
|
||||
\uicontrol {Transition Editor}.
|
||||
\image qmldesigner-transition-editor-startup.png "Empty Transition Editor"
|
||||
\li Select the \inlineimage plus.png
|
||||
\li Select the \inlineimage icons/plus.png
|
||||
(\uicontrol {Add Transition}) button to add a transition. This
|
||||
works only if you have added at least one state and modified at
|
||||
least one property in it.
|
||||
@@ -125,7 +125,7 @@
|
||||
To add transitions:
|
||||
|
||||
\list 1
|
||||
\li Select the \inlineimage plus.png
|
||||
\li Select the \inlineimage icons/plus.png
|
||||
(\uicontrol {Add Transition}) button.
|
||||
\li In the \uicontrol {Transition ID} field, enter an ID for the
|
||||
transition.
|
||||
@@ -133,7 +133,7 @@
|
||||
\li In the \uicontrol To field, select the state to transition to.
|
||||
\endlist
|
||||
|
||||
To remove the current transition, select the \inlineimage minus.png
|
||||
To remove the current transition, select the \inlineimage icons/minus.png
|
||||
(\uicontrol {Remove Transition}) button.
|
||||
|
||||
\if defined(qtcreator)
|
||||
|
||||
@@ -49,6 +49,8 @@ def get_arguments():
|
||||
parser.add_argument('--output-path', help='Output path for resulting 7zip files')
|
||||
parser.add_argument('--add-path', help='Prepends a CMAKE_PREFIX_PATH to the build',
|
||||
action='append', dest='prefix_paths', default=[])
|
||||
parser.add_argument('--add-module-path', help='Prepends a CMAKE_MODULE_PATH to the build',
|
||||
action='append', dest='module_paths', default=[])
|
||||
parser.add_argument('--add-make-arg', help='Passes the argument to the make tool.',
|
||||
action='append', dest='make_args', default=[])
|
||||
parser.add_argument('--add-config', help=('Adds the argument to the CMake configuration call. '
|
||||
@@ -93,6 +95,10 @@ def build(args, paths):
|
||||
'-DCMAKE_INSTALL_PREFIX=' + common.to_posix_path(paths.install),
|
||||
'-G', 'Ninja']
|
||||
|
||||
if args.module_paths:
|
||||
module_paths = [common.to_posix_path(os.path.abspath(fp)) for fp in args.module_paths]
|
||||
cmake_args += ['-DCMAKE_MODULE_PATH=' + ';'.join(module_paths)]
|
||||
|
||||
# force MSVC on Windows, because it looks for GCC in the PATH first,
|
||||
# even if MSVC is first mentioned in the PATH...
|
||||
# TODO would be nicer if we only did this if cl.exe is indeed first in the PATH
|
||||
|
||||
@@ -360,6 +360,14 @@ bool GeneralHelper::isPickable(QQuick3DNode *node) const
|
||||
if (!node)
|
||||
return false;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
|
||||
// Instancing doesn't hide child nodes, so only check for instancing on the requested node
|
||||
if (auto model = qobject_cast<QQuick3DModel *>(node)) {
|
||||
if (model->instancing())
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
QQuick3DNode *n = node;
|
||||
while (n) {
|
||||
if (!n->visible() || isLocked(n) || isHidden(n))
|
||||
|
||||
@@ -100,6 +100,7 @@
|
||||
#include <QtQuick3D/private/qquick3dviewport_p.h>
|
||||
#include <QtQuick3D/private/qquick3dscenerootnode_p.h>
|
||||
#include <QtQuick3D/private/qquick3drepeater_p.h>
|
||||
#include <QtQuick3D/private/qquick3dloader_p.h>
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
#include "../editor3d/qt5compat/qquick3darealight_p.h"
|
||||
#endif
|
||||
@@ -1227,7 +1228,7 @@ Qt5InformationNodeInstanceServer::Qt5InformationNodeInstanceServer(NodeInstanceC
|
||||
m_inputEventTimer.setSingleShot(true);
|
||||
m_renderModelNodeImageViewTimer.setSingleShot(true);
|
||||
m_modelNode3DImageViewAsyncData.timer.setSingleShot(true);
|
||||
m_repeaterAddObjectTimer.setSingleShot(true);
|
||||
m_dynamicAddObjectTimer.setSingleShot(true);
|
||||
|
||||
#ifdef FPS_COUNTER
|
||||
if (!_fpsTimer) {
|
||||
@@ -1253,7 +1254,7 @@ Qt5InformationNodeInstanceServer::~Qt5InformationNodeInstanceServer()
|
||||
m_inputEventTimer.stop();
|
||||
m_renderModelNodeImageViewTimer.stop();
|
||||
m_modelNode3DImageViewAsyncData.timer.stop();
|
||||
m_repeaterAddObjectTimer.stop();
|
||||
m_dynamicAddObjectTimer.stop();
|
||||
|
||||
if (m_editView3DData.rootItem)
|
||||
m_editView3DData.rootItem->disconnect(this);
|
||||
@@ -1397,20 +1398,27 @@ void Qt5InformationNodeInstanceServer::handleSelectionChangeTimeout()
|
||||
changeSelection(m_lastSelectionChangeCommand);
|
||||
}
|
||||
|
||||
void Qt5InformationNodeInstanceServer::handleRepeaterAddObjectTimeout()
|
||||
void Qt5InformationNodeInstanceServer::handleDynamicAddObjectTimeout()
|
||||
{
|
||||
#ifdef QUICK3D_MODULE
|
||||
for (auto obj : std::as_const(m_addObjectRepeaters)) {
|
||||
if (auto repObj = qobject_cast<QQuick3DRepeater *>(obj)) {
|
||||
if (hasInstanceForObject(repObj)) {
|
||||
ServerNodeInstance instance = instanceForObject(repObj);
|
||||
for (auto obj : std::as_const(m_dynamicObjectConstructors)) {
|
||||
auto handleHiding = [this](QQuick3DNode *node) -> bool {
|
||||
if (node && hasInstanceForObject(node)) {
|
||||
ServerNodeInstance instance = instanceForObject(node);
|
||||
handleInstanceHidden(instance, instance.internalInstance()->isHiddenInEditor(),
|
||||
false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
auto nodeObj = qobject_cast<QQuick3DNode *>(obj);
|
||||
if (!handleHiding(nodeObj)) {
|
||||
if (auto pickTarget = obj->property("_pickTarget").value<QQuick3DNode *>())
|
||||
handleHiding(pickTarget);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
m_addObjectRepeaters.clear();
|
||||
m_dynamicObjectConstructors.clear();
|
||||
}
|
||||
|
||||
void Qt5InformationNodeInstanceServer::createCameraAndLightGizmos(
|
||||
@@ -1664,8 +1672,8 @@ void Qt5InformationNodeInstanceServer::setup3DEditView(const QList<ServerNodeIns
|
||||
this, &Qt5InformationNodeInstanceServer::handleInputEvents);
|
||||
QObject::connect(&m_modelNode3DImageViewAsyncData.timer, &QTimer::timeout,
|
||||
this, &Qt5InformationNodeInstanceServer::modelNode3DImageViewRenderStep);
|
||||
QObject::connect(&m_repeaterAddObjectTimer, &QTimer::timeout,
|
||||
this, &Qt5InformationNodeInstanceServer::handleRepeaterAddObjectTimeout);
|
||||
QObject::connect(&m_dynamicAddObjectTimer, &QTimer::timeout,
|
||||
this, &Qt5InformationNodeInstanceServer::handleDynamicAddObjectTimeout);
|
||||
|
||||
QString lastSceneId;
|
||||
auto helper = qobject_cast<QmlDesigner::Internal::GeneralHelper *>(m_3dHelper);
|
||||
@@ -1824,7 +1832,7 @@ void Qt5InformationNodeInstanceServer::clearScene(const ClearSceneCommand &comma
|
||||
|
||||
m_parentChangedSet.clear();
|
||||
m_completedComponentList.clear();
|
||||
m_addObjectRepeaters.clear();
|
||||
m_dynamicObjectConstructors.clear();
|
||||
}
|
||||
|
||||
void Qt5InformationNodeInstanceServer::createScene(const CreateSceneCommand &command)
|
||||
@@ -2296,6 +2304,23 @@ void Qt5InformationNodeInstanceServer::handleInstanceHidden(const ServerNodeInst
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 2, 1)
|
||||
checkModel->setPickable(!edit3dHidden);
|
||||
#endif
|
||||
} else {
|
||||
auto checkRepeater = qobject_cast<QQuick3DRepeater *>(checkNode);
|
||||
auto checkLoader = qobject_cast<QQuick3DLoader *>(checkNode);
|
||||
if (checkRepeater || checkLoader) {
|
||||
// Repeaters/loaders may not yet have created their children, so we set
|
||||
// _pickTarget on them and connect the notifier.
|
||||
if (checkNode->property("_pickTarget").isNull()) {
|
||||
if (checkRepeater) {
|
||||
QObject::connect(checkRepeater, &QQuick3DRepeater::objectAdded,
|
||||
this, &Qt5InformationNodeInstanceServer::handleDynamicAddObject);
|
||||
} else {
|
||||
QObject::connect(checkLoader, &QQuick3DLoader::loaded,
|
||||
this, &Qt5InformationNodeInstanceServer::handleDynamicAddObject);
|
||||
}
|
||||
}
|
||||
checkNode->setProperty("_pickTarget", QVariant::fromValue(node));
|
||||
}
|
||||
}
|
||||
};
|
||||
if (auto childNode = qobject_cast<QQuick3DNode *>(childItem))
|
||||
@@ -2315,10 +2340,12 @@ bool Qt5InformationNodeInstanceServer::isInformationServer() const
|
||||
return true;
|
||||
}
|
||||
|
||||
void Qt5InformationNodeInstanceServer::handleRepeaterAddObject()
|
||||
// This method should be connected to signals indicating a new object has been constructed outside
|
||||
// normal scene creation. E.g. QQuick3DRepeater::objectAdded.
|
||||
void Qt5InformationNodeInstanceServer::handleDynamicAddObject()
|
||||
{
|
||||
m_addObjectRepeaters.insert(sender());
|
||||
m_repeaterAddObjectTimer.start();
|
||||
m_dynamicObjectConstructors.insert(sender());
|
||||
m_dynamicAddObjectTimer.start();
|
||||
}
|
||||
|
||||
// update 3D view size when it changes in creator side
|
||||
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
void handleInstanceHidden(const ServerNodeInstance &instance, bool enable, bool checkAncestors) override;
|
||||
|
||||
bool isInformationServer() const override;
|
||||
void handleRepeaterAddObject();
|
||||
void handleDynamicAddObject();
|
||||
|
||||
private slots:
|
||||
void handleSelectionChanged(const QVariant &objs);
|
||||
@@ -109,7 +109,7 @@ protected:
|
||||
private:
|
||||
void handleObjectPropertyChangeTimeout();
|
||||
void handleSelectionChangeTimeout();
|
||||
void handleRepeaterAddObjectTimeout();
|
||||
void handleDynamicAddObjectTimeout();
|
||||
void createEditView3D();
|
||||
void create3DPreviewView();
|
||||
void setup3DEditView(const QList<ServerNodeInstance> &instanceList,
|
||||
@@ -176,7 +176,7 @@ private:
|
||||
QTimer m_render3DEditViewTimer;
|
||||
QTimer m_renderModelNodeImageViewTimer;
|
||||
QTimer m_inputEventTimer;
|
||||
QTimer m_repeaterAddObjectTimer;
|
||||
QTimer m_dynamicAddObjectTimer;
|
||||
#ifdef QUICK3D_PARTICLES_MODULE
|
||||
bool m_particleAnimationPlaying = true;
|
||||
AnimationDriver *m_particleAnimationDriver = nullptr;
|
||||
@@ -189,7 +189,7 @@ private:
|
||||
QList<InputEventCommand> m_pendingInputEventCommands;
|
||||
QObject *m_3dHelper = nullptr;
|
||||
int m_need3DEditViewRender = 0;
|
||||
QSet<QObject *> m_addObjectRepeaters;
|
||||
QSet<QObject *> m_dynamicObjectConstructors;
|
||||
|
||||
struct ModelNode3DImageViewAsyncData {
|
||||
QTimer timer;
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <private/qquick3dmodel_p.h>
|
||||
#include <private/qquick3dnode_p_p.h>
|
||||
#include <private/qquick3drepeater_p.h>
|
||||
#include <private/qquick3dloader_p.h>
|
||||
#endif
|
||||
|
||||
namespace QmlDesigner {
|
||||
@@ -59,10 +60,18 @@ void Quick3DNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNo
|
||||
InstanceContainer::NodeFlags flags)
|
||||
{
|
||||
#ifdef QUICK3D_MODULE
|
||||
if (auto repObj = qobject_cast<QQuick3DRepeater *>(object())) {
|
||||
QObject *obj = object();
|
||||
auto repObj = qobject_cast<QQuick3DRepeater *>(obj);
|
||||
auto loadObj = qobject_cast<QQuick3DLoader *>(obj);
|
||||
if (repObj || loadObj) {
|
||||
if (auto infoServer = qobject_cast<Qt5InformationNodeInstanceServer *>(nodeInstanceServer())) {
|
||||
if (repObj) {
|
||||
QObject::connect(repObj, &QQuick3DRepeater::objectAdded,
|
||||
infoServer, &Qt5InformationNodeInstanceServer::handleRepeaterAddObject);
|
||||
infoServer, &Qt5InformationNodeInstanceServer::handleDynamicAddObject);
|
||||
} else {
|
||||
QObject::connect(loadObj, &QQuick3DLoader::loaded,
|
||||
infoServer, &Qt5InformationNodeInstanceServer::handleDynamicAddObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
#include "qmlprivategate.h"
|
||||
|
||||
#include "metaobject.h"
|
||||
#include "designercustomobjectdata.h"
|
||||
|
||||
#include <objectnodeinstance.h>
|
||||
|
||||
@@ -121,27 +121,27 @@ Item {
|
||||
}
|
||||
|
||||
StudioControls.MenuSeparator {
|
||||
visible: itemsView.currentCategory === null
|
||||
height: StudioTheme.Values.border
|
||||
visible: itemsView.currentCategory === null && !rootView.searchActive
|
||||
height: visible ? StudioTheme.Values.border : 0
|
||||
}
|
||||
|
||||
StudioControls.MenuItem {
|
||||
text: qsTr("Expand All")
|
||||
visible: itemsView.currentCategory === null
|
||||
visible: itemsView.currentCategory === null && !rootView.searchActive
|
||||
height: visible ? implicitHeight : 0
|
||||
onTriggered: itemLibraryModel.expandAll()
|
||||
}
|
||||
|
||||
StudioControls.MenuItem {
|
||||
text: qsTr("Collapse All")
|
||||
visible: itemsView.currentCategory === null
|
||||
visible: itemsView.currentCategory === null && !rootView.searchActive
|
||||
height: visible ? implicitHeight : 0
|
||||
onTriggered: itemLibraryModel.collapseAll()
|
||||
}
|
||||
|
||||
StudioControls.MenuSeparator {
|
||||
visible: itemsView.currentCategory === null
|
||||
height: StudioTheme.Values.border
|
||||
visible: itemsView.currentCategory === null && !rootView.searchActive
|
||||
height: visible ? StudioTheme.Values.border : 0
|
||||
}
|
||||
|
||||
StudioControls.MenuItem {
|
||||
@@ -154,18 +154,22 @@ Item {
|
||||
|
||||
StudioControls.MenuSeparator {
|
||||
visible: itemsView.currentCategory
|
||||
height: StudioTheme.Values.border
|
||||
height: visible ? StudioTheme.Values.border : 0
|
||||
}
|
||||
|
||||
StudioControls.MenuItem {
|
||||
text: qsTr("Show Module Hidden Categories")
|
||||
visible: !rootView.searchActive
|
||||
enabled: itemsView.currentImport && !itemsView.currentImport.allCategoriesVisible
|
||||
height: visible ? implicitHeight : 0
|
||||
onTriggered: itemLibraryModel.showImportHiddenCategories(itemsView.currentImport.importUrl)
|
||||
}
|
||||
|
||||
StudioControls.MenuItem {
|
||||
text: qsTr("Show All Hidden Categories")
|
||||
visible: !rootView.searchActive
|
||||
enabled: itemLibraryModel.isAnyCategoryHidden
|
||||
height: visible ? implicitHeight : 0
|
||||
onTriggered: itemLibraryModel.showAllHiddenCategories()
|
||||
}
|
||||
}
|
||||
@@ -230,7 +234,6 @@ Item {
|
||||
itemsView.importToRemove = importRemovable ? importUrl : ""
|
||||
itemsView.currentImport = model
|
||||
itemsView.currentCategory = null
|
||||
if (!rootView.isSearchActive())
|
||||
moduleContextMenu.popup()
|
||||
}
|
||||
|
||||
@@ -257,11 +260,12 @@ Item {
|
||||
onToggleExpand: categoryExpanded = !categoryExpanded
|
||||
useDefaulContextMenu: false
|
||||
onShowContextMenu: {
|
||||
if (!rootView.searchActive) {
|
||||
itemsView.currentCategory = model
|
||||
itemsView.currentImport = parent.currentImportModel
|
||||
if (!rootView.isSearchActive())
|
||||
moduleContextMenu.popup()
|
||||
}
|
||||
}
|
||||
|
||||
Grid {
|
||||
id: itemGrid
|
||||
@@ -344,7 +348,6 @@ Item {
|
||||
itemsView.importToRemove = importRemovable ? importUrl : ""
|
||||
itemsView.currentImport = model
|
||||
itemsView.currentCategory = null
|
||||
if (!rootView.isSearchActive())
|
||||
moduleContextMenu.popup()
|
||||
}
|
||||
|
||||
@@ -385,7 +388,9 @@ Item {
|
||||
onClicked: (mouse) => {
|
||||
itemLibraryModel.selectImportCategory(parent.parent.currentImportModel.importUrl, model.index)
|
||||
|
||||
if (mouse.button === Qt.RightButton && !rootView.isSearchActive() && categoryModel.rowCount() !== 1) {
|
||||
if (mouse.button === Qt.RightButton
|
||||
&& categoryModel.rowCount() !== 1
|
||||
&& !rootView.searchActive) {
|
||||
itemsView.currentCategory = model
|
||||
itemsView.currentImport = parent.parent.currentImportModel
|
||||
moduleContextMenu.popup()
|
||||
|
||||
@@ -58,41 +58,66 @@ Item {
|
||||
anchors.fill: parent
|
||||
|
||||
Item { width: parent.width; implicitHeight: 20 } // spacer
|
||||
|
||||
Row {
|
||||
width: parent.width
|
||||
height: DialogValues.dialogTitleTextHeight
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
Item { width: DialogValues.dialogLeftPadding; height: 1 } // horizontal spacer
|
||||
|
||||
Image {
|
||||
asynchronous: false
|
||||
source: "image://newprojectdialog_library/logo"
|
||||
width: DialogValues.logoWidth
|
||||
height: DialogValues.logoHeight
|
||||
}
|
||||
|
||||
Item { width: 10; height: 1 }
|
||||
|
||||
Text {
|
||||
text: qsTr("Welcome to ")
|
||||
text: qsTr("Let's create something wonderful with ")
|
||||
font.pixelSize: DialogValues.dialogTitlePixelSize
|
||||
font.family: "Titillium Web"
|
||||
height: DialogValues.dialogTitleTextHeight
|
||||
lineHeight: DialogValues.dialogTitleLineHeight
|
||||
lineHeightMode: Text.FixedHeight
|
||||
color: DialogValues.textColor
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
Text {
|
||||
text: qsTr("Qt Design Studio")
|
||||
text: qsTr("Qt Design Studio!")
|
||||
font.pixelSize: DialogValues.dialogTitlePixelSize
|
||||
font.family: "Titillium Web"
|
||||
height: DialogValues.dialogTitleTextHeight
|
||||
lineHeight: DialogValues.dialogTitleLineHeight
|
||||
lineHeightMode: Text.FixedHeight
|
||||
color: DialogValues.textColorInteraction
|
||||
}
|
||||
color: DialogValues.brandTextColor
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
} // Row
|
||||
|
||||
Item { width: 1; height: 11 } // spacer
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: DialogValues.paneTitleLineHeight
|
||||
Row {
|
||||
width: parent.width
|
||||
height: DialogValues.paneTitleLineHeight
|
||||
|
||||
Item { width: DialogValues.dialogLeftPadding; height: 1} // spacer
|
||||
|
||||
Text {
|
||||
width: parent.width
|
||||
width: parent.width - DialogValues.dialogLeftPadding
|
||||
text: qsTr("Create new project by selecting a suitable Preset and then adjust details.")
|
||||
color: DialogValues.textColor
|
||||
font.pixelSize: DialogValues.paneTitlePixelSize
|
||||
lineHeight: DialogValues.paneTitleLineHeight
|
||||
lineHeightMode: Text.FixedHeight
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Item { width: parent.width; Layout.fillHeight: true} // spacer
|
||||
} // ColumnLayout
|
||||
} // Header Item
|
||||
@@ -102,7 +127,7 @@ Item {
|
||||
Layout.fillHeight: true
|
||||
|
||||
RowLayout {
|
||||
x: 35
|
||||
x: DialogValues.dialogLeftPadding
|
||||
width: parent.width - 70
|
||||
height: parent.height
|
||||
spacing: 0
|
||||
@@ -113,6 +138,7 @@ Item {
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumWidth: 379 // figured out this number visually
|
||||
Layout.minimumHeight: 261 // figured out this number visually
|
||||
radius: 6
|
||||
|
||||
Column {
|
||||
x: DialogValues.defaultPadding // left padding
|
||||
@@ -294,7 +320,7 @@ Item {
|
||||
} // RowLayout
|
||||
} // Dialog Button Box
|
||||
|
||||
Item { implicitWidth: 35 - DialogValues.defaultPadding }
|
||||
Item { implicitWidth: DialogValues.dialogLeftPadding - DialogValues.defaultPadding }
|
||||
} // RowLayout
|
||||
} // Footer
|
||||
} // ColumnLayout
|
||||
|
||||
BIN
share/qtcreator/qmldesigner/newprojectdialog/image/logo.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
share/qtcreator/qmldesigner/newprojectdialog/image/logo@2x.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
@@ -58,7 +58,7 @@ Item {
|
||||
Text {
|
||||
id: detailsHeading
|
||||
text: qsTr("Details")
|
||||
height: DialogValues.dialogTitleTextHeight
|
||||
height: DialogValues.paneTitleTextHeight
|
||||
width: parent.width;
|
||||
font.weight: Font.DemiBold
|
||||
font.pixelSize: DialogValues.paneTitlePixelSize
|
||||
@@ -388,6 +388,7 @@ Item {
|
||||
width: parent.width
|
||||
height: orientationButton.height / 2
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
radius: 3
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,6 +402,7 @@ Item {
|
||||
width: orientationButton.width / 4
|
||||
height: orientationButton.height
|
||||
color: "white"
|
||||
radius: 3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,11 @@ QtObject {
|
||||
readonly property int dialogContentHeight: projectViewHeight + 300 // i.e. dialog without header and footer
|
||||
readonly property int loadedPanesWidth: detailsPaneWidth + stylesPaneWidth
|
||||
readonly property int detailsPaneWidth: 330 + detailsPanePadding * 2
|
||||
readonly property int dialogTitleTextHeight: 47
|
||||
readonly property int dialogTitleTextHeight: 85
|
||||
readonly property int paneTitleTextHeight: 47
|
||||
readonly property int logoWidth: 85
|
||||
readonly property int logoHeight: 85
|
||||
|
||||
/* detailsScrollableContentHeight - the full height that may need to be scrolled to be fully
|
||||
visible, if the dialog box is too small. */
|
||||
readonly property int detailsScrollableContentHeight: 428
|
||||
@@ -44,6 +48,7 @@ QtObject {
|
||||
readonly property int detailsPanePadding: 18
|
||||
readonly property int stylesPanePadding: 18
|
||||
readonly property int defaultPadding: 18
|
||||
readonly property int dialogLeftPadding: 35
|
||||
|
||||
readonly property int styleImageWidth: 200
|
||||
readonly property int styleImageBorderWidth: 2
|
||||
@@ -73,9 +78,11 @@ QtObject {
|
||||
readonly property real viewHeaderLineHeight: 24
|
||||
readonly property real paneTitlePixelSize: 18
|
||||
readonly property real paneTitleLineHeight: 27
|
||||
readonly property int dialogTitlePixelSize: 32
|
||||
readonly property int dialogTitlePixelSize: 38
|
||||
readonly property int dialogTitleLineHeight: 49
|
||||
|
||||
readonly property string brandTextColor: "#2e769e"
|
||||
|
||||
// for a spacer item
|
||||
function narrowSpacing(value, layoutSpacing = DialogValues.defaultPadding) {
|
||||
/* e.g. if we want narrow spacing value = 11, then for the spacer item residing inside a
|
||||
|
||||
@@ -52,6 +52,7 @@ Item {
|
||||
Rectangle {
|
||||
color: DialogValues.lightPaneColor
|
||||
anchors.fill: parent
|
||||
radius: 6
|
||||
|
||||
Item {
|
||||
x: DialogValues.stylesPanePadding // left padding
|
||||
@@ -65,7 +66,7 @@ Item {
|
||||
Text {
|
||||
id: styleTitleText
|
||||
text: qsTr("Style")
|
||||
Layout.minimumHeight: DialogValues.dialogTitleTextHeight
|
||||
Layout.minimumHeight: DialogValues.paneTitleTextHeight
|
||||
font.weight: Font.DemiBold
|
||||
font.pixelSize: DialogValues.paneTitlePixelSize
|
||||
lineHeight: DialogValues.paneTitleLineHeight
|
||||
@@ -118,7 +119,7 @@ Item {
|
||||
|
||||
delegate: ItemDelegate {
|
||||
id: delegateId
|
||||
height: styleImage.height + DialogValues.styleImageBorderWidth + styleText.height + 1
|
||||
height: styleImage.height + DialogValues.styleImageBorderWidth + styleText.height + extraPadding.height + 1
|
||||
width: stylesList.width
|
||||
|
||||
Rectangle {
|
||||
@@ -134,7 +135,7 @@ Item {
|
||||
border.width: index == stylesList.currentIndex ? DialogValues.styleImageBorderWidth : 0
|
||||
color: "transparent"
|
||||
width: parent.width
|
||||
height: parent.height - styleText.height
|
||||
height: parent.height - styleText.height - extraPadding.height
|
||||
|
||||
Image {
|
||||
id: styleImage
|
||||
@@ -158,6 +159,8 @@ Item {
|
||||
width: parent.width
|
||||
color: DialogValues.textColor
|
||||
}
|
||||
|
||||
Item { id: extraPadding; width: 1; height: 10 }
|
||||
} // Column
|
||||
} // Rectangle
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ Section {
|
||||
SpinBox {
|
||||
implicitWidth: StudioTheme.Values.twoControlColumnWidth
|
||||
+ StudioTheme.Values.actionIndicatorWidth
|
||||
backendValue: (backendValues.%2_lineHeight === undefined) ? dummyBackendValue : backendValues.lineHeight
|
||||
backendValue: (backendValues.%2_lineHeight === undefined) ? 1.0 : backendValues.lineHeight
|
||||
maximumValue: 500
|
||||
minimumValue: 0
|
||||
decimals: 2
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import HelperWidgets 2.0
|
||||
import StudioControls 1.0 as StudioControls
|
||||
import StudioTheme 1.0 as StudioTheme
|
||||
|
||||
Section {
|
||||
caption: qsTr("Audio")
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
SectionLayout {
|
||||
PropertyLabel { text: qsTr("Volume") }
|
||||
|
||||
SecondColumnLayout {
|
||||
SpinBox {
|
||||
implicitWidth: StudioTheme.Values.twoControlColumnWidth
|
||||
+ StudioTheme.Values.actionIndicatorWidth
|
||||
backendValue: backendValues.volume
|
||||
decimals: 1
|
||||
minimumValue: 0.0
|
||||
maximumValue: 1.0
|
||||
}
|
||||
|
||||
ExpandingSpacer {}
|
||||
}
|
||||
|
||||
PropertyLabel { text: qsTr("Muted") }
|
||||
|
||||
SecondColumnLayout {
|
||||
CheckBox {
|
||||
implicitWidth: StudioTheme.Values.twoControlColumnWidth
|
||||
+ StudioTheme.Values.actionIndicatorWidth
|
||||
backendValue: backendValues.muted
|
||||
text: backendValues.muted.valueToString
|
||||
}
|
||||
|
||||
ExpandingSpacer {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,11 +30,15 @@ import StudioControls 1.0 as StudioControls
|
||||
import StudioTheme 1.0 as StudioTheme
|
||||
|
||||
Section {
|
||||
id: root
|
||||
caption: qsTr("Media Player")
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
property bool showAudioOutput: false
|
||||
property bool showVideoOutput: false
|
||||
|
||||
// TODO position property, what should be the range?!
|
||||
|
||||
SectionLayout {
|
||||
@@ -54,11 +58,14 @@ Section {
|
||||
}
|
||||
|
||||
PropertyLabel {
|
||||
visible: root.showAudioOutput
|
||||
text: qsTr("Audio Output")
|
||||
tooltip: qsTr("Holds the target audio output.")
|
||||
}
|
||||
|
||||
SecondColumnLayout {
|
||||
visible: root.showAudioOutput
|
||||
|
||||
ItemFilterComboBox {
|
||||
implicitWidth: StudioTheme.Values.singleControlColumnWidth
|
||||
+ StudioTheme.Values.actionIndicatorWidth
|
||||
@@ -72,11 +79,14 @@ Section {
|
||||
}
|
||||
|
||||
PropertyLabel {
|
||||
visible: root.showVideoOutput
|
||||
text: qsTr("Video Output")
|
||||
tooltip: qsTr("Holds the target video output.")
|
||||
}
|
||||
|
||||
SecondColumnLayout {
|
||||
visible: root.showVideoOutput
|
||||
|
||||
ItemFilterComboBox {
|
||||
implicitWidth: StudioTheme.Values.singleControlColumnWidth
|
||||
+ StudioTheme.Values.actionIndicatorWidth
|
||||
|
||||
@@ -33,5 +33,8 @@ Column {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
MediaPlayerSection {}
|
||||
MediaPlayerSection {
|
||||
showAudioOutput: true
|
||||
showVideoOutput: true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ Section {
|
||||
id: checkBox
|
||||
implicitWidth: StudioTheme.Values.twoControlColumnWidth
|
||||
+ StudioTheme.Values.actionIndicatorWidth
|
||||
text: backendValue.valueToString
|
||||
text: (checkBox.backendValue === undefined) ? "" : checkBox.backendValue.valueToString
|
||||
}
|
||||
|
||||
ExpandingSpacer {}
|
||||
|
||||
@@ -41,7 +41,6 @@ Column {
|
||||
|
||||
TextExtrasSection {
|
||||
showWrapMode: true
|
||||
showFormatProperty: true
|
||||
}
|
||||
|
||||
FontExtrasSection {
|
||||
|
||||
@@ -353,13 +353,14 @@ Section {
|
||||
id: lineHeightSpinBox
|
||||
implicitWidth: StudioTheme.Values.twoControlColumnWidth
|
||||
+ StudioTheme.Values.actionIndicatorWidth
|
||||
backendValue: (backendValues.lineHeight === undefined) ? dummyBackendValue
|
||||
backendValue: (backendValues.lineHeight === undefined) ? 1.0
|
||||
: backendValues.lineHeight
|
||||
decimals: 2
|
||||
minimumValue: 0
|
||||
maximumValue: 500
|
||||
stepSize: 0.1
|
||||
enabled: backendValue.isAvailable
|
||||
enabled: (backendValues.lineHeight === undefined) ? false
|
||||
: backendValue.isAvailable
|
||||
}
|
||||
|
||||
ExpandingSpacer {}
|
||||
|
||||
@@ -42,6 +42,13 @@ Section {
|
||||
return backendValues[root.fontName + "_" + name]
|
||||
}
|
||||
|
||||
function isBackendValueAvailable(name) {
|
||||
if (backendValues[name] !== undefined)
|
||||
return backendValues[name].isAvailable
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
SectionLayout {
|
||||
PropertyLabel {
|
||||
text: qsTr("Capitalization")
|
||||
@@ -89,11 +96,11 @@ Section {
|
||||
|
||||
PropertyLabel {
|
||||
text: qsTr("Style color")
|
||||
visible: backendValues.styleColor.isAvailable
|
||||
visible: root.isBackendValueAvailable("styleColor")
|
||||
}
|
||||
|
||||
ColorEditor {
|
||||
visible: backendValues.styleColor.isAvailable
|
||||
visible: root.isBackendValueAvailable("styleColor")
|
||||
backendValue: backendValues.styleColor
|
||||
supportGradient: false
|
||||
}
|
||||
|
||||
@@ -326,13 +326,14 @@ Section {
|
||||
id: lineHeightSpinBox
|
||||
implicitWidth: StudioTheme.Values.twoControlColumnWidth
|
||||
+ StudioTheme.Values.actionIndicatorWidth
|
||||
backendValue: (backendValues.lineHeight === undefined) ? dummyBackendValue
|
||||
backendValue: (backendValues.lineHeight === undefined) ? 1.0
|
||||
: backendValues.lineHeight
|
||||
decimals: 2
|
||||
minimumValue: 0
|
||||
maximumValue: 500
|
||||
stepSize: 0.1
|
||||
enabled: backendValue.isAvailable
|
||||
enabled: (backendValues.lineHeight === undefined) ? false
|
||||
: backendValue.isAvailable
|
||||
}
|
||||
|
||||
ExpandingSpacer {}
|
||||
|
||||
@@ -41,11 +41,20 @@ Section {
|
||||
property bool showFontSizeMode: false
|
||||
property bool showLineHeight: false
|
||||
|
||||
function isBackendValueAvailable(name) {
|
||||
if (backendValues[name] !== undefined)
|
||||
return backendValues[name].isAvailable
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
SectionLayout {
|
||||
id: sectionLayout
|
||||
|
||||
PropertyLabel {
|
||||
visible: root.showWrapMode
|
||||
text: qsTr("Wrap mode")
|
||||
blockedByTemplate: !backendValues.wrapMode.isAvailable
|
||||
blockedByTemplate: !root.isBackendValueAvailable("wrapMode")
|
||||
}
|
||||
|
||||
SecondColumnLayout {
|
||||
@@ -58,7 +67,7 @@ Section {
|
||||
backendValue: backendValues.wrapMode
|
||||
scope: "Text"
|
||||
model: ["NoWrap", "WordWrap", "WrapAnywhere", "Wrap"]
|
||||
enabled: backendValue.isAvailable
|
||||
enabled: root.isBackendValueAvailable("wrapMode")
|
||||
}
|
||||
|
||||
ExpandingSpacer {}
|
||||
@@ -67,7 +76,7 @@ Section {
|
||||
PropertyLabel {
|
||||
visible: root.showElide
|
||||
text: qsTr("Elide")
|
||||
blockedByTemplate: !backendValues.elide.isAvailable
|
||||
blockedByTemplate: !root.isBackendValueAvailable("elide")
|
||||
}
|
||||
|
||||
SecondColumnLayout {
|
||||
@@ -80,7 +89,7 @@ Section {
|
||||
backendValue: backendValues.elide
|
||||
scope: "Text"
|
||||
model: ["ElideNone", "ElideLeft", "ElideMiddle", "ElideRight"]
|
||||
enabled: backendValue.isAvailable
|
||||
enabled: root.isBackendValueAvailable("elide")
|
||||
}
|
||||
|
||||
ExpandingSpacer {}
|
||||
@@ -89,7 +98,7 @@ Section {
|
||||
PropertyLabel {
|
||||
visible: root.showFormatProperty
|
||||
text: qsTr("Format")
|
||||
blockedByTemplate: !backendValues.textFormat.isAvailable
|
||||
blockedByTemplate: !root.isBackendValueAvailable("textFormat")
|
||||
}
|
||||
|
||||
SecondColumnLayout {
|
||||
@@ -100,9 +109,9 @@ Section {
|
||||
+ StudioTheme.Values.actionIndicatorWidth
|
||||
width: implicitWidth
|
||||
scope: "Text"
|
||||
model: ["PlainText", "RichText", "AutoText"]
|
||||
model: ["PlainText", "RichText", "AutoText", "StyledText", "MarkdownText"]
|
||||
backendValue: backendValues.textFormat
|
||||
enabled: backendValue.isAvailable
|
||||
enabled: root.isBackendValueAvailable("textFormat")
|
||||
}
|
||||
|
||||
ExpandingSpacer {}
|
||||
@@ -111,7 +120,7 @@ Section {
|
||||
PropertyLabel {
|
||||
text: qsTr("Render type")
|
||||
tooltip: qsTr("Overrides the default rendering type for this component.")
|
||||
blockedByTemplate: !backendValues.renderType.isAvailable
|
||||
blockedByTemplate: !root.isBackendValueAvailable("renderType")
|
||||
}
|
||||
|
||||
SecondColumnLayout {
|
||||
@@ -122,7 +131,7 @@ Section {
|
||||
scope: "Text"
|
||||
model: ["QtRendering", "NativeRendering"]
|
||||
backendValue: backendValues.renderType
|
||||
enabled: backendValue.isAvailable
|
||||
enabled: root.isBackendValueAvailable("renderType")
|
||||
}
|
||||
|
||||
ExpandingSpacer {}
|
||||
@@ -132,7 +141,7 @@ Section {
|
||||
visible: root.showLineHeight
|
||||
text: qsTr("Line height mode")
|
||||
tooltip: qsTr("Determines how the line height is specified.")
|
||||
blockedByTemplate: !backendValues.lineHeightMode.isAvailable
|
||||
blockedByTemplate: !root.isBackendValueAvailable("lineHeightMode")
|
||||
}
|
||||
|
||||
SecondColumnLayout {
|
||||
@@ -145,7 +154,7 @@ Section {
|
||||
implicitWidth: StudioTheme.Values.singleControlColumnWidth
|
||||
+ StudioTheme.Values.actionIndicatorWidth
|
||||
width: implicitWidth
|
||||
enabled: backendValue.isAvailable
|
||||
enabled: root.isBackendValueAvailable("lineHeightMode")
|
||||
}
|
||||
|
||||
ExpandingSpacer {}
|
||||
@@ -155,7 +164,7 @@ Section {
|
||||
visible: root.showFontSizeMode
|
||||
text: qsTr("Size mode")
|
||||
tooltip: qsTr("Specifies how the font size of the displayed text is determined.")
|
||||
blockedByTemplate: !backendValues.fontSizeMode.isAvailable
|
||||
blockedByTemplate: !root.isBackendValueAvailable("fontSizeMode")
|
||||
}
|
||||
|
||||
SecondColumnLayout {
|
||||
@@ -169,7 +178,7 @@ Section {
|
||||
scope: "Text"
|
||||
model: ["FixedSize", "HorizontalFit", "VerticalFit", "Fit"]
|
||||
backendValue: backendValues.fontSizeMode
|
||||
enabled: backendValue.isAvailable
|
||||
enabled: root.isBackendValueAvailable("fontSizeMode")
|
||||
}
|
||||
|
||||
ExpandingSpacer {}
|
||||
@@ -178,15 +187,16 @@ Section {
|
||||
PropertyLabel {
|
||||
visible: root.showFontSizeMode
|
||||
text: qsTr("Min size")
|
||||
blockedByTemplate: !backendValues.minimumPixelSize.isAvailable
|
||||
&& !backendValues.minimumPointSize.isAvailable
|
||||
blockedByTemplate: !root.isBackendValueAvailable("minimumPixelSize")
|
||||
&& !root.isBackendValueAvailable("minimumPointSize")
|
||||
}
|
||||
|
||||
SecondColumnLayout {
|
||||
visible: root.showFontSizeMode
|
||||
|
||||
SpinBox {
|
||||
enabled: (fontSizeMode.currentIndex !== 0) || backendValue.isAvailable
|
||||
enabled: (fontSizeMode.currentIndex !== 0)
|
||||
|| root.isBackendValueAvailable("minimumPixelSize")
|
||||
minimumValue: 0
|
||||
maximumValue: 500
|
||||
decimals: 0
|
||||
@@ -200,13 +210,14 @@ Section {
|
||||
ControlLabel {
|
||||
text: "px"
|
||||
tooltip: qsTr("Minimum font pixel size of scaled text.")
|
||||
enabled: backendValues.minimumPixelSize.isAvailable
|
||||
enabled: root.isBackendValueAvailable("minimumPixelSize")
|
||||
}
|
||||
|
||||
Spacer { implicitWidth: StudioTheme.Values.controlGap }
|
||||
|
||||
SpinBox {
|
||||
enabled: (fontSizeMode.currentIndex !== 0) || backendValue.isAvailable
|
||||
enabled: (fontSizeMode.currentIndex !== 0)
|
||||
|| root.isBackendValueAvailable("minimumPointSize")
|
||||
minimumValue: 0
|
||||
maximumValue: 500
|
||||
decimals: 0
|
||||
@@ -220,7 +231,7 @@ Section {
|
||||
ControlLabel {
|
||||
text: "pt"
|
||||
tooltip: qsTr("Minimum font point size of scaled text.")
|
||||
enabled: backendValues.minimumPointSize.isAvailable
|
||||
enabled: root.isBackendValueAvailable("minimumPointSize")
|
||||
}
|
||||
|
||||
ExpandingSpacer {}
|
||||
@@ -230,7 +241,7 @@ Section {
|
||||
visible: root.showElide
|
||||
text: qsTr("Max line count")
|
||||
tooltip: qsTr("Limits the number of lines that the text component will show.")
|
||||
blockedByTemplate: !backendValues.maximumLineCount.isAvailable
|
||||
blockedByTemplate: !root.isBackendValueAvailable("maximumLineCount")
|
||||
}
|
||||
|
||||
SecondColumnLayout {
|
||||
@@ -243,7 +254,7 @@ Section {
|
||||
minimumValue: 0
|
||||
maximumValue: 10000
|
||||
decimals: 0
|
||||
enabled: backendValue.isAvailable
|
||||
enabled: root.isBackendValueAvailable("maximumLineCount")
|
||||
}
|
||||
|
||||
ExpandingSpacer {}
|
||||
|
||||
@@ -40,7 +40,6 @@ Rectangle {
|
||||
property color baseColor
|
||||
property string delegateStateName
|
||||
property string delegateStateImageSource
|
||||
property int delegateStateImageSize
|
||||
property bool delegateHasWhenCondition
|
||||
property string delegateWhenConditionString
|
||||
property bool hasAnnotation: checkAnnotation()
|
||||
@@ -70,7 +69,6 @@ Rectangle {
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onClicked: {
|
||||
focus = true
|
||||
root.currentStateInternalId = internalNodeId
|
||||
@@ -168,7 +166,7 @@ Rectangle {
|
||||
}
|
||||
|
||||
|
||||
Rectangle {
|
||||
Rectangle { // highlight for default state
|
||||
anchors.margins: (isDefaultState || (isBaseState && !modelHasDefaultState)) ? -myRoot.highlightBorderWidth : 0
|
||||
anchors.fill: column
|
||||
color: StudioTheme.Values.themeStateSeparator
|
||||
@@ -176,7 +174,6 @@ Rectangle {
|
||||
border.width: (isDefaultState || (isBaseState && !modelHasDefaultState)) ? myRoot.highlightBorderWidth : 0
|
||||
}
|
||||
|
||||
|
||||
Column {
|
||||
id: column
|
||||
|
||||
@@ -185,7 +182,6 @@ Rectangle {
|
||||
spacing: expanded ? myRoot.columnSpacing : 0
|
||||
|
||||
Rectangle {
|
||||
|
||||
width: myRoot.width - 2 * myRoot.stateMargin
|
||||
height: myRoot.topAreaHeight
|
||||
|
||||
@@ -261,13 +257,12 @@ Rectangle {
|
||||
font.pixelSize: StudioTheme.Values.myFontSize
|
||||
font.family: StudioTheme.Constants.font
|
||||
|
||||
visible: (isDefaultState || (isBaseState && !modelHasDefaultState))
|
||||
visible: isDefaultState || (isBaseState && !modelHasDefaultState)
|
||||
|
||||
text: qsTr("Default")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Rectangle {
|
||||
id: stateImageArea
|
||||
width: myRoot.width - 2 * myRoot.stateMargin
|
||||
@@ -297,8 +292,6 @@ Rectangle {
|
||||
anchors.centerIn: parent
|
||||
anchors.fill: parent
|
||||
source: delegateStateImageSource
|
||||
sourceSize.width: delegateStateImageSize
|
||||
sourceSize.height: delegateStateImageSize
|
||||
fillMode: Image.PreserveAspectFit
|
||||
}
|
||||
}
|
||||
@@ -329,5 +322,4 @@ Rectangle {
|
||||
hideWidget()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,20 +34,18 @@ FocusScope {
|
||||
id: root
|
||||
|
||||
property int delegateTopAreaHeight: StudioTheme.Values.height + 8
|
||||
property int delegateBottomAreaHeight: 200
|
||||
property int delegateBottomAreaHeight: delegateHeight - 2 * delegateStateMargin - delegateTopAreaHeight - delegateColumnSpacing
|
||||
property int delegateColumnSpacing: 2
|
||||
property int delegateStateMargin: 16
|
||||
property int delegatePreviewMargin: 16
|
||||
property int effectiveHeight: root.expanded ? 287 : 85 // height of the states area
|
||||
property int delegatePreviewMargin: 10
|
||||
property int effectiveHeight: root.expanded ? Math.max(85, Math.min(287, root.height)) : 85 // height of the states area
|
||||
|
||||
signal createNewState
|
||||
signal deleteState(int internalNodeId)
|
||||
signal duplicateCurrentState
|
||||
|
||||
property int stateImageSize: 200
|
||||
property int padding: 2
|
||||
property int delegateWidth: root.stateImageSize
|
||||
+ 2 * (root.delegateStateMargin + root.delegatePreviewMargin)
|
||||
property int delegateWidth: 264
|
||||
property int delegateHeight: effectiveHeight
|
||||
- StudioTheme.Values.scrollBarThickness
|
||||
- 2 * (root.padding + StudioTheme.Values.border)
|
||||
@@ -102,8 +100,8 @@ FocusScope {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 8
|
||||
y: (Math.min(effectiveHeight, root.height) - height) / 2
|
||||
width: Math.max(root.delegateHeight / 2 - 8, 18)
|
||||
height: root.expanded ? 60 : width
|
||||
width: root.expanded ? 140 : 18
|
||||
height: root.expanded ? 60 : 18
|
||||
|
||||
onClicked: {
|
||||
contextMenu.dismiss()
|
||||
@@ -144,7 +142,6 @@ FocusScope {
|
||||
baseColor: isCurrentState ? StudioTheme.Values.themeInteraction : background.color
|
||||
delegateStateName: stateName
|
||||
delegateStateImageSource: stateImageSource
|
||||
delegateStateImageSize: stateImageSize
|
||||
delegateHasWhenCondition: hasWhenCondition
|
||||
delegateWhenConditionString: whenConditionString
|
||||
onDelegateInteraction: contextMenu.dismiss()
|
||||
|
||||
@@ -14,7 +14,7 @@ add_qtc_library(Sqlite
|
||||
../3rdparty/sqlite/config.h
|
||||
../3rdparty/sqlite/sqlite.h
|
||||
constraints.h
|
||||
createtablesqlstatementbuilder.cpp createtablesqlstatementbuilder.h
|
||||
createtablesqlstatementbuilder.h
|
||||
lastchangedrowid.h
|
||||
sqlitealgorithms.h
|
||||
sqlitebasestatement.cpp sqlitebasestatement.h
|
||||
|
||||
@@ -1,308 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 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 "createtablesqlstatementbuilder.h"
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
CreateTableSqlStatementBuilder::CreateTableSqlStatementBuilder()
|
||||
: m_sqlStatementBuilder("CREATE $temporaryTABLE $ifNotExits$table($columnDefinitions)$withoutRowId")
|
||||
{
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::setTableName(Utils::SmallString &&tableName)
|
||||
{
|
||||
m_sqlStatementBuilder.clear();
|
||||
|
||||
this->m_tableName = std::move(tableName);
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::addColumn(Utils::SmallStringView columnName,
|
||||
ColumnType columnType,
|
||||
Constraints &&constraints)
|
||||
{
|
||||
m_sqlStatementBuilder.clear();
|
||||
|
||||
m_columns.emplace_back(Utils::SmallStringView{}, columnName, columnType, std::move(constraints));
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::addConstraint(TableConstraint &&constraint)
|
||||
{
|
||||
m_tableConstraints.push_back(std::move(constraint));
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::setConstraints(TableConstraints constraints)
|
||||
{
|
||||
m_tableConstraints = std::move(constraints);
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::setColumns(SqliteColumns columns)
|
||||
{
|
||||
m_sqlStatementBuilder.clear();
|
||||
|
||||
m_columns = std::move(columns);
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::setUseWithoutRowId(bool useWithoutRowId)
|
||||
{
|
||||
m_useWithoutRowId = useWithoutRowId;
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::setUseIfNotExists(bool useIfNotExists)
|
||||
{
|
||||
m_useIfNotExits = useIfNotExists;
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::setUseTemporaryTable(bool useTemporaryTable)
|
||||
{
|
||||
m_useTemporaryTable = useTemporaryTable;
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::clear()
|
||||
{
|
||||
m_sqlStatementBuilder.clear();
|
||||
m_columns.clear();
|
||||
m_tableName.clear();
|
||||
m_useWithoutRowId = false;
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::clearColumns()
|
||||
{
|
||||
m_sqlStatementBuilder.clear();
|
||||
m_columns.clear();
|
||||
}
|
||||
|
||||
Utils::SmallStringView CreateTableSqlStatementBuilder::sqlStatement() const
|
||||
{
|
||||
if (!m_sqlStatementBuilder.isBuild())
|
||||
bindAll();
|
||||
|
||||
return m_sqlStatementBuilder.sqlStatement();
|
||||
}
|
||||
|
||||
bool CreateTableSqlStatementBuilder::isValid() const
|
||||
{
|
||||
return m_tableName.hasContent() && !m_columns.empty();
|
||||
}
|
||||
|
||||
namespace {
|
||||
Utils::SmallStringView actionToText(ForeignKeyAction action)
|
||||
{
|
||||
switch (action) {
|
||||
case ForeignKeyAction::NoAction:
|
||||
return "NO ACTION";
|
||||
case ForeignKeyAction::Restrict:
|
||||
return "RESTRICT";
|
||||
case ForeignKeyAction::SetNull:
|
||||
return "SET NULL";
|
||||
case ForeignKeyAction::SetDefault:
|
||||
return "SET DEFAULT";
|
||||
case ForeignKeyAction::Cascade:
|
||||
return "CASCADE";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
class ContraintsVisiter
|
||||
{
|
||||
public:
|
||||
ContraintsVisiter(Utils::SmallString &columnDefinitionString)
|
||||
: columnDefinitionString(columnDefinitionString)
|
||||
{}
|
||||
|
||||
void operator()(const Unique &) { columnDefinitionString.append(" UNIQUE"); }
|
||||
|
||||
void operator()(const PrimaryKey &primaryKey)
|
||||
{
|
||||
columnDefinitionString.append(" PRIMARY KEY");
|
||||
if (primaryKey.autoincrement == AutoIncrement::Yes)
|
||||
columnDefinitionString.append(" AUTOINCREMENT");
|
||||
}
|
||||
|
||||
void operator()(const ForeignKey &foreignKey)
|
||||
{
|
||||
columnDefinitionString.append(" REFERENCES ");
|
||||
columnDefinitionString.append(foreignKey.table);
|
||||
|
||||
if (foreignKey.column.hasContent()) {
|
||||
columnDefinitionString.append("(");
|
||||
columnDefinitionString.append(foreignKey.column);
|
||||
columnDefinitionString.append(")");
|
||||
}
|
||||
|
||||
if (foreignKey.updateAction != ForeignKeyAction::NoAction) {
|
||||
columnDefinitionString.append(" ON UPDATE ");
|
||||
columnDefinitionString.append(actionToText(foreignKey.updateAction));
|
||||
}
|
||||
|
||||
if (foreignKey.deleteAction != ForeignKeyAction::NoAction) {
|
||||
columnDefinitionString.append(" ON DELETE ");
|
||||
columnDefinitionString.append(actionToText(foreignKey.deleteAction));
|
||||
}
|
||||
|
||||
if (foreignKey.enforcement == Enforment::Deferred)
|
||||
columnDefinitionString.append(" DEFERRABLE INITIALLY DEFERRED");
|
||||
}
|
||||
|
||||
void operator()(const NotNull &) { columnDefinitionString.append(" NOT NULL"); }
|
||||
|
||||
void operator()(const Check &check)
|
||||
{
|
||||
columnDefinitionString.append(" CHECK (");
|
||||
columnDefinitionString.append(check.expression);
|
||||
columnDefinitionString.append(")");
|
||||
}
|
||||
|
||||
void operator()(const DefaultValue &defaultValue)
|
||||
{
|
||||
columnDefinitionString.append(" DEFAULT ");
|
||||
switch (defaultValue.value.type()) {
|
||||
case Sqlite::ValueType::Integer:
|
||||
columnDefinitionString.append(
|
||||
Utils::SmallString::number(defaultValue.value.toInteger()));
|
||||
break;
|
||||
case Sqlite::ValueType::Float:
|
||||
columnDefinitionString.append(Utils::SmallString::number(defaultValue.value.toFloat()));
|
||||
break;
|
||||
case Sqlite::ValueType::String:
|
||||
columnDefinitionString.append("'");
|
||||
columnDefinitionString.append(defaultValue.value.toStringView());
|
||||
columnDefinitionString.append("'");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(const DefaultExpression &defaultexpression)
|
||||
{
|
||||
columnDefinitionString.append(" DEFAULT (");
|
||||
columnDefinitionString.append(defaultexpression.expression);
|
||||
columnDefinitionString.append(")");
|
||||
}
|
||||
|
||||
void operator()(const Collate &collate)
|
||||
{
|
||||
columnDefinitionString.append(" COLLATE ");
|
||||
columnDefinitionString.append(collate.collation);
|
||||
}
|
||||
|
||||
void operator()(const GeneratedAlways &generatedAlways)
|
||||
{
|
||||
columnDefinitionString.append(" GENERATED ALWAYS AS (");
|
||||
columnDefinitionString.append(generatedAlways.expression);
|
||||
columnDefinitionString.append(")");
|
||||
|
||||
if (generatedAlways.storage == Sqlite::GeneratedAlwaysStorage::Virtual)
|
||||
columnDefinitionString.append(" VIRTUAL");
|
||||
else
|
||||
columnDefinitionString.append(" STORED");
|
||||
}
|
||||
|
||||
Utils::SmallString &columnDefinitionString;
|
||||
};
|
||||
|
||||
class TableContraintsVisiter
|
||||
{
|
||||
public:
|
||||
TableContraintsVisiter(Utils::SmallString &columnDefinitionString)
|
||||
: columnDefinitionString(columnDefinitionString)
|
||||
{}
|
||||
|
||||
void operator()(const TablePrimaryKey &primaryKey)
|
||||
{
|
||||
columnDefinitionString.append("PRIMARY KEY(");
|
||||
columnDefinitionString.append(primaryKey.columns.join(", "));
|
||||
columnDefinitionString.append(")");
|
||||
}
|
||||
|
||||
Utils::SmallString &columnDefinitionString;
|
||||
};
|
||||
} // namespace
|
||||
void CreateTableSqlStatementBuilder::bindColumnDefinitionsAndTableConstraints() const
|
||||
{
|
||||
Utils::SmallStringVector columnDefinitionStrings;
|
||||
columnDefinitionStrings.reserve(m_columns.size());
|
||||
|
||||
for (const Column &column : m_columns) {
|
||||
auto columnDefinitionString = Utils::SmallString::join(
|
||||
{column.name, SqlStatementBuilder::columnTypeToString(column.type)});
|
||||
|
||||
ContraintsVisiter visiter{columnDefinitionString};
|
||||
|
||||
for (const Constraint &constraint : column.constraints)
|
||||
Utils::visit(visiter, constraint);
|
||||
|
||||
columnDefinitionStrings.push_back(std::move(columnDefinitionString));
|
||||
}
|
||||
|
||||
for (const TableConstraint &constraint : m_tableConstraints) {
|
||||
Utils::SmallString columnDefinitionString;
|
||||
|
||||
TableContraintsVisiter visiter{columnDefinitionString};
|
||||
Utils::visit(visiter, constraint);
|
||||
|
||||
columnDefinitionStrings.push_back(std::move(columnDefinitionString));
|
||||
}
|
||||
|
||||
m_sqlStatementBuilder.bind("$columnDefinitions", columnDefinitionStrings);
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::bindAll() const
|
||||
{
|
||||
m_sqlStatementBuilder.bind("$table", m_tableName.clone());
|
||||
|
||||
bindTemporary();
|
||||
bindIfNotExists();
|
||||
bindColumnDefinitionsAndTableConstraints();
|
||||
bindWithoutRowId();
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::bindWithoutRowId() const
|
||||
{
|
||||
if (m_useWithoutRowId)
|
||||
m_sqlStatementBuilder.bind("$withoutRowId", " WITHOUT ROWID");
|
||||
else
|
||||
m_sqlStatementBuilder.bindEmptyText("$withoutRowId");
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::bindIfNotExists() const
|
||||
{
|
||||
if (m_useIfNotExits)
|
||||
m_sqlStatementBuilder.bind("$ifNotExits", "IF NOT EXISTS ");
|
||||
else
|
||||
m_sqlStatementBuilder.bindEmptyText("$ifNotExits");
|
||||
}
|
||||
|
||||
void CreateTableSqlStatementBuilder::bindTemporary() const
|
||||
{
|
||||
if (m_useTemporaryTable)
|
||||
m_sqlStatementBuilder.bind("$temporary", "TEMPORARY ");
|
||||
else
|
||||
m_sqlStatementBuilder.bindEmptyText("$temporary");
|
||||
}
|
||||
|
||||
} // namespace Sqlite
|
||||
@@ -29,43 +29,326 @@
|
||||
#include "sqlstatementbuilder.h"
|
||||
#include "tableconstraints.h"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
template<typename ColumnType>
|
||||
class SQLITE_EXPORT CreateTableSqlStatementBuilder
|
||||
{
|
||||
public:
|
||||
CreateTableSqlStatementBuilder();
|
||||
CreateTableSqlStatementBuilder()
|
||||
: m_sqlStatementBuilder(templateText())
|
||||
{}
|
||||
|
||||
void setTableName(Utils::SmallString &&tableName);
|
||||
void setTableName(Utils::SmallString &&tableName)
|
||||
{
|
||||
m_sqlStatementBuilder.clear();
|
||||
|
||||
this->m_tableName = std::move(tableName);
|
||||
}
|
||||
|
||||
void addColumn(Utils::SmallStringView columnName,
|
||||
ColumnType columnType,
|
||||
Constraints &&constraints = {});
|
||||
void addConstraint(TableConstraint &&constraint);
|
||||
void setConstraints(TableConstraints constraints);
|
||||
void setColumns(SqliteColumns columns);
|
||||
void setUseWithoutRowId(bool useWithoutRowId);
|
||||
void setUseIfNotExists(bool useIfNotExists);
|
||||
void setUseTemporaryTable(bool useTemporaryTable);
|
||||
Constraints &&constraints = {})
|
||||
{
|
||||
m_sqlStatementBuilder.clear();
|
||||
|
||||
void clear();
|
||||
void clearColumns();
|
||||
m_columns.emplace_back(Utils::SmallStringView{}, columnName, columnType, std::move(constraints));
|
||||
}
|
||||
void addConstraint(TableConstraint &&constraint)
|
||||
{
|
||||
m_tableConstraints.push_back(std::move(constraint));
|
||||
}
|
||||
void setConstraints(TableConstraints constraints)
|
||||
{
|
||||
m_tableConstraints = std::move(constraints);
|
||||
}
|
||||
void setColumns(BasicColumns<ColumnType> columns)
|
||||
{
|
||||
m_sqlStatementBuilder.clear();
|
||||
|
||||
Utils::SmallStringView sqlStatement() const;
|
||||
m_columns = std::move(columns);
|
||||
}
|
||||
|
||||
bool isValid() const;
|
||||
void setUseWithoutRowId(bool useWithoutRowId) { m_useWithoutRowId = useWithoutRowId; }
|
||||
|
||||
protected:
|
||||
void bindColumnDefinitionsAndTableConstraints() const;
|
||||
void bindAll() const;
|
||||
void bindWithoutRowId() const;
|
||||
void bindIfNotExists() const;
|
||||
void bindTemporary() const;
|
||||
void setUseIfNotExists(bool useIfNotExists) { m_useIfNotExits = useIfNotExists; }
|
||||
|
||||
void setUseTemporaryTable(bool useTemporaryTable) { m_useTemporaryTable = useTemporaryTable; }
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_sqlStatementBuilder.clear();
|
||||
m_columns.clear();
|
||||
m_tableName.clear();
|
||||
m_useWithoutRowId = false;
|
||||
}
|
||||
|
||||
void clearColumns()
|
||||
{
|
||||
m_sqlStatementBuilder.clear();
|
||||
m_columns.clear();
|
||||
}
|
||||
|
||||
Utils::SmallStringView sqlStatement() const
|
||||
{
|
||||
if (!m_sqlStatementBuilder.isBuild())
|
||||
bindAll();
|
||||
|
||||
return m_sqlStatementBuilder.sqlStatement();
|
||||
}
|
||||
|
||||
bool isValid() const { return m_tableName.hasContent() && !m_columns.empty(); }
|
||||
|
||||
private:
|
||||
static Utils::SmallStringView templateText()
|
||||
{
|
||||
if constexpr (std::is_same_v<ColumnType, ::Sqlite::ColumnType>) {
|
||||
return "CREATE $temporaryTABLE $ifNotExits$table($columnDefinitions)$withoutRowId";
|
||||
}
|
||||
|
||||
return "CREATE $temporaryTABLE $ifNotExits$table($columnDefinitions)$withoutRowId STRICT";
|
||||
}
|
||||
|
||||
static Utils::SmallString columnTypeToString(ColumnType columnType)
|
||||
{
|
||||
if constexpr (std::is_same_v<ColumnType, ::Sqlite::ColumnType>) {
|
||||
switch (columnType) {
|
||||
case ColumnType::Numeric:
|
||||
return " NUMERIC";
|
||||
case ColumnType::Integer:
|
||||
return " INTEGER";
|
||||
case ColumnType::Real:
|
||||
return " REAL";
|
||||
case ColumnType::Text:
|
||||
return " TEXT";
|
||||
case ColumnType::Blob:
|
||||
return " BLOB";
|
||||
case ColumnType::None:
|
||||
return {};
|
||||
}
|
||||
} else {
|
||||
switch (columnType) {
|
||||
case ColumnType::Any:
|
||||
return " ANY";
|
||||
case ColumnType::Int:
|
||||
return " INT";
|
||||
case ColumnType::Integer:
|
||||
return " INTEGER";
|
||||
case ColumnType::Real:
|
||||
return " REAL";
|
||||
case ColumnType::Text:
|
||||
return " TEXT";
|
||||
case ColumnType::Blob:
|
||||
return " BLOB";
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
static Utils::SmallStringView actionToText(ForeignKeyAction action)
|
||||
{
|
||||
switch (action) {
|
||||
case ForeignKeyAction::NoAction:
|
||||
return "NO ACTION";
|
||||
case ForeignKeyAction::Restrict:
|
||||
return "RESTRICT";
|
||||
case ForeignKeyAction::SetNull:
|
||||
return "SET NULL";
|
||||
case ForeignKeyAction::SetDefault:
|
||||
return "SET DEFAULT";
|
||||
case ForeignKeyAction::Cascade:
|
||||
return "CASCADE";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
class ContraintsVisiter
|
||||
{
|
||||
public:
|
||||
ContraintsVisiter(Utils::SmallString &columnDefinitionString)
|
||||
: columnDefinitionString(columnDefinitionString)
|
||||
{}
|
||||
|
||||
void operator()(const Unique &) { columnDefinitionString.append(" UNIQUE"); }
|
||||
|
||||
void operator()(const PrimaryKey &primaryKey)
|
||||
{
|
||||
columnDefinitionString.append(" PRIMARY KEY");
|
||||
if (primaryKey.autoincrement == AutoIncrement::Yes)
|
||||
columnDefinitionString.append(" AUTOINCREMENT");
|
||||
}
|
||||
|
||||
void operator()(const ForeignKey &foreignKey)
|
||||
{
|
||||
columnDefinitionString.append(" REFERENCES ");
|
||||
columnDefinitionString.append(foreignKey.table);
|
||||
|
||||
if (foreignKey.column.hasContent()) {
|
||||
columnDefinitionString.append("(");
|
||||
columnDefinitionString.append(foreignKey.column);
|
||||
columnDefinitionString.append(")");
|
||||
}
|
||||
|
||||
if (foreignKey.updateAction != ForeignKeyAction::NoAction) {
|
||||
columnDefinitionString.append(" ON UPDATE ");
|
||||
columnDefinitionString.append(actionToText(foreignKey.updateAction));
|
||||
}
|
||||
|
||||
if (foreignKey.deleteAction != ForeignKeyAction::NoAction) {
|
||||
columnDefinitionString.append(" ON DELETE ");
|
||||
columnDefinitionString.append(actionToText(foreignKey.deleteAction));
|
||||
}
|
||||
|
||||
if (foreignKey.enforcement == Enforment::Deferred)
|
||||
columnDefinitionString.append(" DEFERRABLE INITIALLY DEFERRED");
|
||||
}
|
||||
|
||||
void operator()(const NotNull &) { columnDefinitionString.append(" NOT NULL"); }
|
||||
|
||||
void operator()(const Check &check)
|
||||
{
|
||||
columnDefinitionString.append(" CHECK (");
|
||||
columnDefinitionString.append(check.expression);
|
||||
columnDefinitionString.append(")");
|
||||
}
|
||||
|
||||
void operator()(const DefaultValue &defaultValue)
|
||||
{
|
||||
columnDefinitionString.append(" DEFAULT ");
|
||||
switch (defaultValue.value.type()) {
|
||||
case Sqlite::ValueType::Integer:
|
||||
columnDefinitionString.append(
|
||||
Utils::SmallString::number(defaultValue.value.toInteger()));
|
||||
break;
|
||||
case Sqlite::ValueType::Float:
|
||||
columnDefinitionString.append(Utils::SmallString::number(defaultValue.value.toFloat()));
|
||||
break;
|
||||
case Sqlite::ValueType::String:
|
||||
columnDefinitionString.append("'");
|
||||
columnDefinitionString.append(defaultValue.value.toStringView());
|
||||
columnDefinitionString.append("'");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(const DefaultExpression &defaultexpression)
|
||||
{
|
||||
columnDefinitionString.append(" DEFAULT (");
|
||||
columnDefinitionString.append(defaultexpression.expression);
|
||||
columnDefinitionString.append(")");
|
||||
}
|
||||
|
||||
void operator()(const Collate &collate)
|
||||
{
|
||||
columnDefinitionString.append(" COLLATE ");
|
||||
columnDefinitionString.append(collate.collation);
|
||||
}
|
||||
|
||||
void operator()(const GeneratedAlways &generatedAlways)
|
||||
{
|
||||
columnDefinitionString.append(" GENERATED ALWAYS AS (");
|
||||
columnDefinitionString.append(generatedAlways.expression);
|
||||
columnDefinitionString.append(")");
|
||||
|
||||
if (generatedAlways.storage == Sqlite::GeneratedAlwaysStorage::Virtual)
|
||||
columnDefinitionString.append(" VIRTUAL");
|
||||
else
|
||||
columnDefinitionString.append(" STORED");
|
||||
}
|
||||
|
||||
Utils::SmallString &columnDefinitionString;
|
||||
};
|
||||
|
||||
class TableContraintsVisiter
|
||||
{
|
||||
public:
|
||||
TableContraintsVisiter(Utils::SmallString &columnDefinitionString)
|
||||
: columnDefinitionString(columnDefinitionString)
|
||||
{}
|
||||
|
||||
void operator()(const TablePrimaryKey &primaryKey)
|
||||
{
|
||||
columnDefinitionString.append("PRIMARY KEY(");
|
||||
columnDefinitionString.append(primaryKey.columns.join(", "));
|
||||
columnDefinitionString.append(")");
|
||||
}
|
||||
|
||||
Utils::SmallString &columnDefinitionString;
|
||||
};
|
||||
|
||||
void bindColumnDefinitionsAndTableConstraints() const
|
||||
{
|
||||
Utils::SmallStringVector columnDefinitionStrings;
|
||||
columnDefinitionStrings.reserve(m_columns.size());
|
||||
|
||||
for (const BasicColumn<ColumnType> &column : m_columns) {
|
||||
auto columnDefinitionString = Utils::SmallString::join(
|
||||
{column.name, columnTypeToString(column.type)});
|
||||
|
||||
ContraintsVisiter visiter{columnDefinitionString};
|
||||
|
||||
for (const Constraint &constraint : column.constraints)
|
||||
Utils::visit(visiter, constraint);
|
||||
|
||||
columnDefinitionStrings.push_back(std::move(columnDefinitionString));
|
||||
}
|
||||
|
||||
for (const TableConstraint &constraint : m_tableConstraints) {
|
||||
Utils::SmallString columnDefinitionString;
|
||||
|
||||
TableContraintsVisiter visiter{columnDefinitionString};
|
||||
Utils::visit(visiter, constraint);
|
||||
|
||||
columnDefinitionStrings.push_back(std::move(columnDefinitionString));
|
||||
}
|
||||
|
||||
m_sqlStatementBuilder.bind("$columnDefinitions", columnDefinitionStrings);
|
||||
}
|
||||
|
||||
void bindAll() const
|
||||
{
|
||||
m_sqlStatementBuilder.bind("$table", m_tableName.clone());
|
||||
|
||||
bindTemporary();
|
||||
bindIfNotExists();
|
||||
bindColumnDefinitionsAndTableConstraints();
|
||||
bindWithoutRowId();
|
||||
}
|
||||
|
||||
void bindWithoutRowId() const
|
||||
{
|
||||
if (m_useWithoutRowId)
|
||||
m_sqlStatementBuilder.bind("$withoutRowId", " WITHOUT ROWID");
|
||||
else
|
||||
m_sqlStatementBuilder.bindEmptyText("$withoutRowId");
|
||||
}
|
||||
|
||||
void bindIfNotExists() const
|
||||
{
|
||||
if (m_useIfNotExits)
|
||||
m_sqlStatementBuilder.bind("$ifNotExits", "IF NOT EXISTS ");
|
||||
else
|
||||
m_sqlStatementBuilder.bindEmptyText("$ifNotExits");
|
||||
}
|
||||
|
||||
void bindTemporary() const
|
||||
{
|
||||
if (m_useTemporaryTable)
|
||||
m_sqlStatementBuilder.bind("$temporary", "TEMPORARY ");
|
||||
else
|
||||
m_sqlStatementBuilder.bindEmptyText("$temporary");
|
||||
}
|
||||
|
||||
private:
|
||||
mutable SqlStatementBuilder m_sqlStatementBuilder;
|
||||
Utils::SmallString m_tableName;
|
||||
SqliteColumns m_columns;
|
||||
BasicColumns<ColumnType> m_columns;
|
||||
TableConstraints m_tableConstraints;
|
||||
bool m_useWithoutRowId = false;
|
||||
bool m_useIfNotExits = false;
|
||||
|
||||
@@ -51,12 +51,8 @@ namespace Sqlite {
|
||||
BaseStatement::BaseStatement(Utils::SmallStringView sqlStatement, Database &database)
|
||||
: m_compiledStatement(nullptr, deleteCompiledStatement)
|
||||
, m_database(database)
|
||||
, m_bindingParameterCount(0)
|
||||
, m_columnCount(0)
|
||||
{
|
||||
prepare(sqlStatement);
|
||||
setBindingParameterCount();
|
||||
setColumnCount();
|
||||
}
|
||||
|
||||
void BaseStatement::deleteCompiledStatement(sqlite3_stmt *compiledStatement)
|
||||
@@ -141,11 +137,6 @@ void BaseStatement::step() const
|
||||
next();
|
||||
}
|
||||
|
||||
int BaseStatement::columnCount() const
|
||||
{
|
||||
return m_columnCount;
|
||||
}
|
||||
|
||||
void BaseStatement::bind(int index, NullValue)
|
||||
{
|
||||
int resultCode = sqlite3_bind_null(m_compiledStatement.get(), index);
|
||||
@@ -512,34 +503,16 @@ void BaseStatement::checkForBindingError(int resultCode) const
|
||||
throwUnknowError("SqliteStatement::bind: unknown error has happened");
|
||||
}
|
||||
|
||||
void BaseStatement::checkBindingParameterCount(int bindingParameterCount) const
|
||||
{
|
||||
if (bindingParameterCount != sqlite3_bind_parameter_count(m_compiledStatement.get()))
|
||||
throw WrongBindingParameterCount{"Sqlite: wrong binding parameter count!"};
|
||||
}
|
||||
|
||||
void BaseStatement::checkColumnCount(int columnCount) const
|
||||
{
|
||||
if (columnCount != m_columnCount)
|
||||
throw ColumnCountDoesNotMatch("SqliteStatement::values: column count does not match!");
|
||||
}
|
||||
|
||||
void BaseStatement::checkBindingName(int index) const
|
||||
{
|
||||
if (index <= 0 || index > m_bindingParameterCount)
|
||||
throwWrongBingingName("SqliteStatement::bind: binding name are not exists in this statement!");
|
||||
}
|
||||
|
||||
void BaseStatement::setBindingParameterCount()
|
||||
{
|
||||
m_bindingParameterCount = sqlite3_bind_parameter_count(m_compiledStatement.get());
|
||||
}
|
||||
|
||||
Utils::SmallStringView chopFirstLetter(const char *rawBindingName)
|
||||
{
|
||||
if (rawBindingName != nullptr)
|
||||
return Utils::SmallStringView(++rawBindingName);
|
||||
|
||||
return Utils::SmallStringView("");
|
||||
}
|
||||
|
||||
void BaseStatement::setColumnCount()
|
||||
{
|
||||
m_columnCount = sqlite3_column_count(m_compiledStatement.get());
|
||||
if (columnCount != sqlite3_column_count(m_compiledStatement.get()))
|
||||
throw WrongColumnCount{"Sqlite: wrong column count!"};
|
||||
}
|
||||
|
||||
bool BaseStatement::isReadOnlyStatement() const
|
||||
@@ -582,11 +555,6 @@ void BaseStatement::throwBindingIndexIsOutOfRange(const char *whatHasHappened) c
|
||||
throw BindingIndexIsOutOfRange(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle()));
|
||||
}
|
||||
|
||||
void BaseStatement::throwWrongBingingName(const char *whatHasHappened) const
|
||||
{
|
||||
throw WrongBindingName(whatHasHappened);
|
||||
}
|
||||
|
||||
void BaseStatement::throwUnknowError(const char *whatHasHappened) const
|
||||
{
|
||||
if (sqliteDatabaseHandle())
|
||||
|
||||
@@ -59,6 +59,8 @@ enum class Type : char { Invalid, Integer, Float, Text, Blob, Null };
|
||||
class SQLITE_EXPORT BaseStatement
|
||||
{
|
||||
public:
|
||||
using Database = ::Sqlite::Database;
|
||||
|
||||
explicit BaseStatement(Utils::SmallStringView sqlStatement, Database &database);
|
||||
|
||||
BaseStatement(const BaseStatement &) = delete;
|
||||
@@ -80,7 +82,6 @@ public:
|
||||
BlobView fetchBlobValue(int column) const;
|
||||
template<typename Type>
|
||||
Type fetchValue(int column) const;
|
||||
int columnCount() const;
|
||||
|
||||
void bind(int index, NullValue);
|
||||
void bind(int index, int value);
|
||||
@@ -112,10 +113,9 @@ public:
|
||||
[[noreturn]] void checkForPrepareError(int resultCode) const;
|
||||
[[noreturn]] void checkForBindingError(int resultCode) const;
|
||||
void setIfIsReadyToFetchValues(int resultCode) const;
|
||||
void checkColumnCount(int columnCount) const;
|
||||
void checkBindingName(int index) const;
|
||||
void setBindingParameterCount();
|
||||
void setColumnCount();
|
||||
void checkBindingParameterCount(int bindingParameterCount) const;
|
||||
void checkColumnCount(int columnCount) const;
|
||||
bool isReadOnlyStatement() const;
|
||||
[[noreturn]] void throwStatementIsBusy(const char *whatHasHappened) const;
|
||||
[[noreturn]] void throwStatementHasError(const char *whatHasHappened) const;
|
||||
@@ -149,8 +149,6 @@ protected:
|
||||
private:
|
||||
std::unique_ptr<sqlite3_stmt, void (*)(sqlite3_stmt *)> m_compiledStatement;
|
||||
Database &m_database;
|
||||
int m_bindingParameterCount;
|
||||
int m_columnCount;
|
||||
};
|
||||
|
||||
template <> SQLITE_EXPORT int BaseStatement::fetchValue<int>(int column) const;
|
||||
@@ -161,7 +159,7 @@ extern template SQLITE_EXPORT Utils::SmallStringView BaseStatement::fetchValue<U
|
||||
extern template SQLITE_EXPORT Utils::SmallString BaseStatement::fetchValue<Utils::SmallString>(int column) const;
|
||||
extern template SQLITE_EXPORT Utils::PathString BaseStatement::fetchValue<Utils::PathString>(int column) const;
|
||||
|
||||
template<typename BaseStatement, int ResultCount>
|
||||
template<typename BaseStatement, int ResultCount, int BindParameterCount>
|
||||
class StatementImplementation : public BaseStatement
|
||||
{
|
||||
struct Resetter;
|
||||
@@ -175,11 +173,11 @@ public:
|
||||
BaseStatement::next();
|
||||
}
|
||||
|
||||
void bindValues() {}
|
||||
|
||||
template<typename... ValueType>
|
||||
void bindValues(const ValueType &...values)
|
||||
{
|
||||
static_assert(BindParameterCount == sizeof...(values), "Wrong binding parameter count!");
|
||||
|
||||
int index = 0;
|
||||
(BaseStatement::bind(++index, values), ...);
|
||||
}
|
||||
@@ -344,10 +342,9 @@ public:
|
||||
using const_iterator = iterator;
|
||||
|
||||
template<typename... QueryTypes>
|
||||
BaseSqliteResultRange(StatementImplementation &statement, const QueryTypes &...queryValues)
|
||||
BaseSqliteResultRange(StatementImplementation &statement)
|
||||
: m_statement{statement}
|
||||
{
|
||||
statement.bindValues(queryValues...);
|
||||
}
|
||||
|
||||
BaseSqliteResultRange(BaseSqliteResultRange &) = delete;
|
||||
@@ -376,7 +373,6 @@ public:
|
||||
SqliteResultRange(StatementImplementation &statement, const QueryTypes &...queryValues)
|
||||
: BaseSqliteResultRange<ResultType>{statement}
|
||||
, resetter{&statement}
|
||||
|
||||
{
|
||||
statement.bindValues(queryValues...);
|
||||
}
|
||||
@@ -409,7 +405,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
DeferredTransaction m_transaction;
|
||||
DeferredTransaction<typename BaseStatement::Database> m_transaction;
|
||||
Resetter resetter;
|
||||
};
|
||||
|
||||
|
||||
@@ -28,18 +28,19 @@
|
||||
#include "constraints.h"
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
|
||||
class Column
|
||||
template<typename ColumnType>
|
||||
class BasicColumn
|
||||
{
|
||||
public:
|
||||
Column() = default;
|
||||
BasicColumn() = default;
|
||||
|
||||
Column(Utils::SmallStringView tableName,
|
||||
BasicColumn(Utils::SmallStringView tableName,
|
||||
Utils::SmallStringView name,
|
||||
ColumnType type = ColumnType::None,
|
||||
ColumnType type = {},
|
||||
Constraints &&constraints = {})
|
||||
: constraints(std::move(constraints))
|
||||
, name(name)
|
||||
@@ -50,12 +51,13 @@ public:
|
||||
void clear()
|
||||
{
|
||||
name.clear();
|
||||
type = ColumnType::Numeric;
|
||||
type = {};
|
||||
constraints = {};
|
||||
}
|
||||
|
||||
Utils::SmallString typeString() const
|
||||
{
|
||||
if constexpr (std::is_same_v<ColumnType, ::Sqlite::ColumnType>) {
|
||||
switch (type) {
|
||||
case ColumnType::None:
|
||||
return {};
|
||||
@@ -70,11 +72,25 @@ public:
|
||||
case ColumnType::Blob:
|
||||
return "BLOB";
|
||||
}
|
||||
|
||||
Q_UNREACHABLE();
|
||||
} else {
|
||||
switch (type) {
|
||||
case ColumnType::Any:
|
||||
return "ANY";
|
||||
case ColumnType::Int:
|
||||
return "INT";
|
||||
case ColumnType::Integer:
|
||||
return "INTEGER";
|
||||
case ColumnType::Real:
|
||||
return "REAL";
|
||||
case ColumnType::Text:
|
||||
return "TEXT";
|
||||
case ColumnType::Blob:
|
||||
return "BLOB";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
friend bool operator==(const Column &first, const Column &second)
|
||||
friend bool operator==(const BasicColumn &first, const BasicColumn &second)
|
||||
{
|
||||
return first.name == second.name && first.type == second.type
|
||||
&& first.constraints == second.constraints && first.tableName == second.tableName;
|
||||
@@ -84,11 +100,24 @@ public:
|
||||
Constraints constraints;
|
||||
Utils::SmallString name;
|
||||
Utils::SmallString tableName;
|
||||
ColumnType type = ColumnType::Numeric;
|
||||
ColumnType type = {};
|
||||
}; // namespace Sqlite
|
||||
|
||||
using SqliteColumns = std::vector<Column>;
|
||||
using SqliteColumnConstReference = std::reference_wrapper<const Column>;
|
||||
using SqliteColumnConstReferences = std::vector<SqliteColumnConstReference>;
|
||||
using Column = BasicColumn<ColumnType>;
|
||||
using StrictColumn = BasicColumn<StrictColumnType>;
|
||||
|
||||
using Columns = std::vector<Column>;
|
||||
using StrictColumns = std::vector<StrictColumn>;
|
||||
using ColumnConstReference = std::reference_wrapper<const Column>;
|
||||
using StrictColumnConstReference = std::reference_wrapper<const StrictColumn>;
|
||||
using ColumnConstReferences = std::vector<Column>;
|
||||
using StrictColumnConstReferences = std::vector<StrictColumn>;
|
||||
|
||||
template<typename ColumnType>
|
||||
using BasicColumns = std::vector<BasicColumn<ColumnType>>;
|
||||
template<typename ColumnType>
|
||||
using BasicColumnConstReference = std::reference_wrapper<const BasicColumn<ColumnType>>;
|
||||
template<typename ColumnType>
|
||||
using BasicColumnConstReferences = std::vector<BasicColumn<ColumnType>>;
|
||||
|
||||
} // namespace Sqlite
|
||||
|
||||
@@ -45,10 +45,11 @@ namespace Sqlite {
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
template<int ResultCount>
|
||||
template<int ResultCount, int BindParameterCount>
|
||||
class ReadStatement;
|
||||
template<int BindParameterCount>
|
||||
class WriteStatement;
|
||||
template<int ResultCount>
|
||||
template<int ResultCount, int BindParameterCount>
|
||||
class ReadWriteStatement;
|
||||
|
||||
class SQLITE_EXPORT Database final : public TransactionInterface, public DatabaseInterface
|
||||
@@ -59,11 +60,12 @@ class SQLITE_EXPORT Database final : public TransactionInterface, public Databas
|
||||
|
||||
public:
|
||||
using MutexType = std::mutex;
|
||||
template<int ResultCount>
|
||||
using ReadStatement = Sqlite::ReadStatement<ResultCount>;
|
||||
using WriteStatement = Sqlite::WriteStatement;
|
||||
template<int ResultCount = 0>
|
||||
using ReadWriteStatement = Sqlite::ReadWriteStatement<ResultCount>;
|
||||
template<int ResultCount, int BindParameterCount = 0>
|
||||
using ReadStatement = Sqlite::ReadStatement<ResultCount, BindParameterCount>;
|
||||
template<int BindParameterCount>
|
||||
using WriteStatement = Sqlite::WriteStatement<BindParameterCount>;
|
||||
template<int ResultCount = 0, int BindParameterCount = 0>
|
||||
using ReadWriteStatement = Sqlite::ReadWriteStatement<ResultCount, BindParameterCount>;
|
||||
using BusyHandler = DatabaseBackend::BusyHandler;
|
||||
|
||||
Database();
|
||||
@@ -161,7 +163,6 @@ public:
|
||||
void lock() override;
|
||||
void unlock() override;
|
||||
|
||||
private:
|
||||
void deferredBegin() override;
|
||||
void immediateBegin() override;
|
||||
void exclusiveBegin() override;
|
||||
@@ -171,6 +172,7 @@ private:
|
||||
void sessionCommit() override;
|
||||
void sessionRollback() override;
|
||||
|
||||
private:
|
||||
void initializeTables();
|
||||
void registerTransactionStatements();
|
||||
void deleteTransactionStatements();
|
||||
|
||||
@@ -297,7 +297,7 @@ void DatabaseBackend::checkDatabaseCouldBeOpened(int resultCode)
|
||||
return;
|
||||
default:
|
||||
closeWithoutException();
|
||||
throw Exception(
|
||||
throw UnknowError(
|
||||
"SqliteDatabaseBackend::SqliteDatabaseBackend: database cannot be opened:",
|
||||
sqlite3_errmsg(sqliteDatabaseHandle()));
|
||||
}
|
||||
@@ -473,7 +473,7 @@ void DatabaseBackend::throwExceptionStatic(const char *whatHasHappens)
|
||||
void DatabaseBackend::throwException(const char *whatHasHappens) const
|
||||
{
|
||||
if (m_databaseHandle)
|
||||
throw Exception(whatHasHappens, sqlite3_errmsg(m_databaseHandle));
|
||||
throw ExceptionWithMessage(whatHasHappens, sqlite3_errmsg(m_databaseHandle));
|
||||
else
|
||||
throw Exception(whatHasHappens);
|
||||
}
|
||||
|
||||
@@ -31,12 +31,9 @@
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
void Exception::printWarning() const
|
||||
void ExceptionWithMessage::printWarning() const
|
||||
{
|
||||
if (!m_sqliteErrorMessage.isEmpty())
|
||||
qWarning() << m_whatErrorHasHappen << m_sqliteErrorMessage;
|
||||
else
|
||||
qWarning() << m_whatErrorHasHappen;
|
||||
qWarning() << what() << m_sqliteErrorMessage;
|
||||
}
|
||||
|
||||
} // namespace Sqlite
|
||||
|
||||