diff --git a/dist/changes-4.10.0.md b/dist/changes-4.10.0.md new file mode 100644 index 00000000000..f97a83a472d --- /dev/null +++ b/dist/changes-4.10.0.md @@ -0,0 +1,217 @@ +# Qt Creator 4.10 + +Qt Creator version 4.10 contains bug fixes and new features. + +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/4.9..v4.10.0 + +## Editing + +* Removed support for KDE code paster after removal of official API +* Added option for pinning files so they stay open when closing all files (QTCREATORBUG-21899) + +### Language Client + +* Added option for starting server when needed +* Added option for starting one server per project +* Added support for `workspace/workspaceFolders` server request +* Added Locator filter for current document (`.`) +* Added Locator filters for symbols in workspace (`:`, `c`, and `m`) (QTCREATORBUG-21915) +* Added hover information +* Made client settings expand variables for executable and arguments +* Improved completion item tooltip (QTCREATORBUG-22429) + +## Help + +* Added option for scroll wheel zooming (QTCREATORBUG-14154) + +## All Projects + +* Added option for hiding kit settings (QTCREATORBUG-9134) +* Added support for drag & drop in Projects tree (QTCREATORBUG-6446) +* Added option for closing files of project when closing project (QTCREATORBUG-22198) +* Added filtering to `Application Output`, `Compile Output`, and `General Messages` + (QTCREATORBUG-16356) +* Added `Re-detect` and `Remove All` to compiler settings +* Added Locator filter for all files in all project directory trees (`a`) (QTCREATORBUG-19122) +* Added `CurrentRun:WorkingDir` Qt Creator variable +* Added `Tools` > `Parse Build Output` (QTCREATORBUG-16017) +* Added option for not clearing `Issues` pane on build (QTCREATORBUG-22478) +* Moved `Application Output` and `Build Output` options to separate tabs in the + `Build & Run` options +* Improved search for files from `Issues` pane (QTCREATORBUG-13623) + +### Wizards + +* Added build system choice to `Qt Widgets Application` and `C++ Library` wizards +* Added `value('variablename')` to JavaScript context in JSON wizards, adding support for + lists and dictionaries as values +* Fixed that file names were always lower-cased by file wizards (QTCREATORBUG-14711) + +## QMake Projects + +* Added option for adding existing project as sub-project (QTCREATORBUG-5837) +* Added option for running `qmake` on every build (QTCREATORBUG-20888) +* Added completion of paths in project files (QTCREATORBUG-5915) +* Added forced `qmake` run on rebuild +* Fixed building sub-project in case of additional custom make steps (QTCREATORBUG-15794) + +## CMake Projects + +* Removed `Default` from build types (QTCREATORBUG-22013) +* Added support for Android targets +* Added support for building single file (QTCREATORBUG-18898) +* Added completion of paths in project files (QTCREATORBUG-5915) +* Improved text in `Configuration has changed on disk` dialog (QTCREATORBUG-22059) + +## Qbs Projects + +* Added support for Android targets +* Fixed `Build product` for files in groups + +## Python Projects + +* Added support for adding and removing files from project +* Improved wizards + +## Compilation Database Projects + +* Added setting for project header path (QTCREATORBUG-22031) +* Added custom build steps and run configuration (QTCREATORBUG-21727) +* Added option for specifying additional files in `compile_database.json.files` +* Fixed handling of relative paths (QTCREATORBUG-22338) +* Fixed handling of `--sysroot` (QTCREATORBUG-22339) + +## Qt Support + +* Added handling of QtTest messages in compile output (QTCREATORBUG-8091) + +## C++ Support + +* Improved auto-insertion of closing curly brace (QTCREATORBUG-18872) +* Fixed that snippet completion could get in the way (QTCREATORBUG-21767) + +### Clang Format + +* Improved configuration UI +* Fixed that clang format was triggered on save when Beautifier already was as well + +## QML Support + +## Debugging + +* Added pretty printer for `QMargin` + +### CDB + +* Fixed loading of custom debugging helpers (QTCREATORBUG-20481) + +## Perf Profiler + +* Changed format of saved traces +* Added support for multiple attributes per sample +* Added CPU ID for events + +## Qt Quick Designer + +* Added support for `ShapeGradient` (QDS-359) +* Added gradient picker that allows loading and saving of presets +* Updated properties of `Flickable` + +## Version Control Systems + +* Added zoom buttons to `Version Control` output pane + +### Git + +* Added support for different reset types in `Branches` view +* Added choice of build system to `Git Clone` wizard if cloned project supports multiple + build systems (QTCREATORBUG-17828) + +## Test Integration + +* Added basic support for Boost tests +* Added wizard for Boost tests (QTCREATORBUG-21169) +* Added option for automatically opening test results pane +* Improved handling of unexpected test output (QTCREATORBUG-22354) + +## Platform Specific + +### Windows + +* Added `Clone` for MSVC toolchains (QTCREATORBUG-22163) +* Fixed that `mingw32-make`'s warnings were categorized as errors (QTCREATORBUG-22171) +* Fixed bitness detection for MinGW (QTCREATORBUG-22160) + +### Linux + +* Improved auto-detection of toolchains (QTCREATORBUG-19179, QTCREATORBUG-20044, QTCREATORBUG-22081) + +### macOS + +### Android + +* Removed support for MIPS64 + +### Remote Linux + +* Added deployment method that deploys everything that is installed by the build system + in its install step (QTCREATORBUG-21855) +* Added support for opening remote terminal with run environment +* Added option for `rsync` flags for deployment (QTCREATORBUG-22352) + +### Boot to Qt + +### Bare Metal + +* Added include path detection and output parsers for `IAR`, `KEIL` and `SDCC` toolchains + +## Credits for these changes go to: +Aleksei German +Alessandro Ambrosano +Alessandro Portale +Andre Hartmann +André Pönitz +Anton Danielsson +Antonio Di Monaco +Asit Dhal +BogDan Vatra +Christian Gagneraud +Christian Kandeler +Christian Stenger +Cristian Adam +Cristián Maureira-Fredes +Daniel Teske +David Schulz +Denis Shienkov +Denis Vygovskiy +Eike Ziller +Friedemann Kleint +Haxor Leet +illiteratecoder +Ivan Donchevskii +Ivan Komissarov +Joel Smith +Jörg Bornemann +Kavindra Palaraja +Luca Carlon +Marco Bubke +Martin Haase +Mitch Curtis +Nikolai Kosjar +Oliver Wolff +Orgad Shaneh +Przemyslaw Gorszkowski +Robert Löhning +Thomas Hartmann +Thomas Otto +Tim Henning +Tim Jenssen +Tobias Hunger +Tor Arne Vestbø +Ulf Hermann +Ville Nummela diff --git a/doc/images/creator-compilers-custom.png b/doc/images/creator-compilers-custom.png index cadbe17afdf..d090b832593 100644 Binary files a/doc/images/creator-compilers-custom.png and b/doc/images/creator-compilers-custom.png differ diff --git a/doc/images/qtcreator-custom-parser.png b/doc/images/qtcreator-custom-parser.png index 25e38a79afb..ea300583aaf 100644 Binary files a/doc/images/qtcreator-custom-parser.png and b/doc/images/qtcreator-custom-parser.png differ diff --git a/doc/images/qtcreator-kits.png b/doc/images/qtcreator-kits.png index 82dd2df34c1..05e8cc0df35 100644 Binary files a/doc/images/qtcreator-kits.png and b/doc/images/qtcreator-kits.png differ diff --git a/doc/images/qtcreator-parse-build-output.png b/doc/images/qtcreator-parse-build-output.png new file mode 100644 index 00000000000..56d9724ea66 Binary files /dev/null and b/doc/images/qtcreator-parse-build-output.png differ diff --git a/doc/images/qtcreator-qbs-profile-settings.png b/doc/images/qtcreator-qbs-profile-settings.png index e100701bd06..8710ff9ecde 100644 Binary files a/doc/images/qtcreator-qbs-profile-settings.png and b/doc/images/qtcreator-qbs-profile-settings.png differ diff --git a/doc/images/qtcreator-toolchains.png b/doc/images/qtcreator-toolchains.png index 91a6dbc7d72..1e54fe33330 100644 Binary files a/doc/images/qtcreator-toolchains.png and b/doc/images/qtcreator-toolchains.png differ diff --git a/doc/src/howto/creator-sidebar-views.qdoc b/doc/src/howto/creator-sidebar-views.qdoc index 4461c14be75..9140af5f35f 100644 --- a/doc/src/howto/creator-sidebar-views.qdoc +++ b/doc/src/howto/creator-sidebar-views.qdoc @@ -159,6 +159,10 @@ \li To see the absolute path of a file, move the mouse pointer over the file name. + \li To move files from one project to another, drag-and-drop them + in the project tree. \QC makes the necessary changes to project + configuration files. + \endlist \if defined(qtcreator) @@ -188,7 +192,10 @@ \li Expand or collapse the tree view to show or hide all files and folders. \li Close all files in a project. - \li Close projects. + \li Close projects. By default, all files in the project are also + closed. To keep them open, deselect the \uicontrol Tools > + \uicontrol Options > \uicontrol {Build & Run} > \uicontrol General + > \uicontrol {Close source files along with project} check box. \endlist For managing files and directories, the same functions are available as in diff --git a/doc/src/howto/creator-ui.qdoc b/doc/src/howto/creator-ui.qdoc index 2419f499e85..d477eda78de 100644 --- a/doc/src/howto/creator-ui.qdoc +++ b/doc/src/howto/creator-ui.qdoc @@ -487,6 +487,38 @@ You can also reach the options page by clicking the \uicontrol {Open Settings Page} button. + To copy the output from the pane to the clipboard, select + \uicontrol {Select All} in the context menu, and then select + \uicontrol Copy. Save the output as a file if you want to + examine it later without having to build the project again. + This is useful for large projects that take a long time to build. + + \section2 Parsing Existing Compile Output + + You can use \QC's output parsers to parse output from builds done outside + of \QC or stored from previous build runs. By default, the parsers from the + kit selected for the active project are used, but you can select another + kit. + + To parse compile output: + + \list 1 + \li Select \uicontrol Tools > \uicontrol {Parse Build Output}. + \image qtcreator-parse-build-output.png + \li Paste the build output in the \uicontrol {Build Output} field, or + select \uicontrol {Load from File} to load it from a file. + \li Deselect the \uicontrol {Output went to stderr} check box if the + parser expects issues on \c stdout. + \li In the \uicontrol {Use parsers from kit} field, select the kit to + use for parsing the output. Select \uicontrol Manage to view + and modify kit settings. + \li The parser displays the parsed output in the \uicontrol Issues + pane. By default, the pane is cleared before adding the new output. + Deselect the \uicontrol {Clear existing tasks} check box to append + the new output to the old output. + \li Select \uicontrol OK to start parsing. + \endlist + \if defined(qtcreator) \section1 To-Do Entries diff --git a/doc/src/projects/creator-only/creator-projects-compilers.qdoc b/doc/src/projects/creator-only/creator-projects-compilers.qdoc index 6a907233fd2..b91d5b7d9e4 100644 --- a/doc/src/projects/creator-only/creator-projects-compilers.qdoc +++ b/doc/src/projects/creator-only/creator-projects-compilers.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -44,7 +44,12 @@ for and running it on a particular platform. \QC automatically detects the compilers that are registered by your system - or by an installer. You can add compilers to build applications by using other + or by an installer and lists them in \uicontrol Tools > \uicontrol Options > + \uicontrol Kits > \uicontrol Compilers: + + \image qtcreator-toolchains.png + + You can add the following compilers to build applications by using other compilers or by using additional versions of the automatically detected compilers: @@ -94,6 +99,20 @@ \endlist + \section1 Redetecting Compilers + + When \QC finds an x86_64 GCC compiler, it sets up an instance for the native + x86_64 target. If you plan to create also 32-bit x86 binaries without using + a dedicated cross-compiler, select \uicontrol {Auto-detection Settings} > + \uicontrol {Detect x86_64 GCC compilers as x86_64 and x86}. Then select + \uicontrol Re-detect to refresh the list of automatically detected + compilers. + + To remove manually added compilers, select \uicontrol Remove or + \uicontrol {Remove All}. + + \section1 Specifying Compiler Settings + To build an application using GCC, MinGW, Clang, or QCC, specify the path to the directory where the compiler is located and select the application binary interface (ABI) version from the list of available @@ -118,8 +137,6 @@ then select a compiler in the list, and then select \uicontrol C or \uicontrol C++ to add a C or C++ compiler. - \image qtcreator-toolchains.png - To clone the selected compiler, select \uicontrol Clone. \li In the \uicontrol Name field, enter a name for the compiler to diff --git a/doc/src/projects/creator-only/creator-projects-targets.qdoc b/doc/src/projects/creator-only/creator-projects-targets.qdoc index 1d6101b02f6..6438abc42bb 100644 --- a/doc/src/projects/creator-only/creator-projects-targets.qdoc +++ b/doc/src/projects/creator-only/creator-projects-targets.qdoc @@ -73,6 +73,21 @@ \endlist + \section1 Filtering Kit Settings + + Typically, only a subset of the kit settings is relevant for a particular + setup. Therefore, \QC plugins register sets of relevant settings that you + can view and modify in \uicontrol Tools > \uicontrol Options > + \uicontrol Kits >. For example, if you use CMake to build all your projects, + you can hide Qbs and qmake settings by default. + + To hide and show settings in the \uicontrol Kits tab for the + current kit, select \uicontrol {Settings Filter}. To view and + modify the settings displayed when you add a new kit, select + \uicontrol {Default Settings Filter}. + + \section1 Specifying Kit Settings + To add kits: \list 1 @@ -105,13 +120,13 @@ \li In the \uicontrol Device field, select a device. - \li In the \uicontrol {Emulator skin} field, select the skin to use for - the \l {Emulator}{Boot2Qt Emulator Device}. - \li In the \uicontrol Sysroot field, specify the directory where the device image is located. If you are not cross-compiling, leave this field empty. + \li In the \uicontrol {Emulator skin} field, select the skin to use for + the \l {Emulator}{Boot2Qt Emulator Device}. + \li In the \uicontrol {Compiler} field, select the C or C++ compiler that you use to build the project. You can add compilers to the list if they are installed on the development PC, but were not detected @@ -153,6 +168,10 @@ configuration that should be used by qmake. If you leave this field empty, the default mkspec of the selected Qt version is used. + \li In the \uicontrol {Additional Qbs profile settings} field, select + \uicontrol Change to add settings to Qbs build profiles. For more + information, see \l {Editing Qbs Profiles}. + \li In the \uicontrol {CMake Tool} field, select the CMake tool to use for building the project. Select \uicontrol Manage to add installed CMake tools to the list. For more information, see @@ -169,10 +188,6 @@ \uicontrol Change to edit the variables of the CMake configuration for the kit. - \li In the \uicontrol {Additional Qbs profile settings} field, select - \uicontrol Change to add settings to Qbs build profiles. For more - information, see \l {Editing Qbs Profiles}. - \endlist \QC uses the \e {default kit} if it does not have enough information to @@ -194,16 +209,18 @@ \list 1 \li Select \uicontrol Change next to the - \uicontrol {Additional Qbs Profile Settings} field. + \uicontrol {Additional Qbs Profile Settings} field to open the + \uicontrol {Custom Properties} dialog. \image qtcreator-qbs-profile-settings. - \li Select \uicontrol Add. + \li Double-click an empty cell in the \uicontrol Key column to specify + the key to add or modify as: \c .. - \li In the \uicontrol Key column, spefify the key to add or modify as: - \c .. + \li Double-click the cell on the same row in the \uicontrol Value column + to specify a value as a JSON literal. - \li In the \uicontrol Value column, specify a value as a JSON literal. + \li Select \uicontrol Add to add the key-value pair. \li Click \uicontrol OK. diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AdvancedSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AdvancedSection.qml index 3cf02f122eb..6d9c073c77a 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AdvancedSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AdvancedSection.qml @@ -49,13 +49,14 @@ Section { SecondColumnLayout { SpinBox { + sliderIndicatorVisible: true backendValue: backendValues.scale hasSlider: true decimals: 2 minimumValue: 0.01 stepSize: 0.1 maximumValue: 10 - Layout.preferredWidth: 100 + Layout.preferredWidth: 140 } ExpandingSpacer { } @@ -65,12 +66,13 @@ Section { } SecondColumnLayout { SpinBox { + sliderIndicatorVisible: true backendValue: backendValues.rotation hasSlider: true decimals: 2 minimumValue: -360 maximumValue: 360 - Layout.preferredWidth: 100 + Layout.preferredWidth: 140 } ExpandingSpacer { } @@ -80,11 +82,12 @@ Section { } SecondColumnLayout { SpinBox { + sliderIndicatorVisible: true backendValue: backendValues.z hasSlider: true minimumValue: -100 maximumValue: 100 - Layout.preferredWidth: 100 + Layout.preferredWidth: 140 } ExpandingSpacer { } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml index 2dbbbff76bb..0f1e828431f 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml @@ -33,6 +33,10 @@ Rectangle { width: 320 height: 400 color: Theme.qmlDesignerBackgroundColorDarkAlternate() + MouseArea { + anchors.fill: parent + onClicked: forceActiveFocus() + } ScrollView { anchors.fill: parent @@ -117,6 +121,7 @@ Rectangle { placeholderText: qsTr("id") text: backendValues.id.value Layout.fillWidth: true + width: 240 showTranslateCheckBox: false showExtendedFunctionButton: false enabled: !modelNodeBackend.multiSelection @@ -183,6 +188,7 @@ Rectangle { SecondColumnLayout { SpinBox { + sliderIndicatorVisible: true backendValue: backendValues.opacity decimals: 2 diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/TargetComboBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/TargetComboBox.qml index 1e823bdeb02..b500f8c6a7b 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/TargetComboBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/TargetComboBox.qml @@ -26,14 +26,16 @@ import QtQuick 2.0 import HelperWidgets 2.0 import QtQuick.Layouts 1.0 -import QtQuick.Controls 1.0 as Controls +import StudioControls 1.0 as StudioControls import QtQuickDesignerTheme 1.0 -Controls.ComboBox { +StudioControls.ComboBox { property string targetName: anchorBackend.topTarget property color textColor: Theme.color(Theme.PanelTextColorLight) + actionIndicatorVisible: false + id: targetComboBox Connections { @@ -50,8 +52,4 @@ Controls.ComboBox { } model: anchorBackend.possibleTargetItems - - style: CustomComboBoxStyle { - textColor: targetComboBox.textColor - } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/CheckBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/CheckBox.qml index 48d8ffaa53d..8642b9d924c 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/CheckBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/CheckBox.qml @@ -47,8 +47,8 @@ Controls.CheckBox { id: colorLogic backendValue: checkBox.backendValue onValueFromBackendChanged: { - if (checkBox.checked !== valueFromBackend) - checkBox.checked = valueFromBackend; + if (checkBox.checked !== colorLogic.valueFromBackend) + checkBox.checked = colorLogic.valueFromBackend; } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorButton.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorButton.qml index c7d6435ad10..5449f85eb6c 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorButton.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorButton.qml @@ -281,7 +281,7 @@ Item { maximumValue: 255 decimals: 0 - onValueChanged: { + onCompressedValueModified: { if (color.r !== value && !colorButton.block) { color.r = (value / 255.0) colorButton.clicked() @@ -293,7 +293,7 @@ Item { Row { z: 2 spacing: 1 - Controls.Label { + Label { text: "G" width: 16 color: "#eee" @@ -310,7 +310,7 @@ Item { maximumValue: 255 decimals: 0 - onValueChanged: { + onCompressedValueModified: { if (color.g !== value && !colorButton.block) { color.g = (value / 255.0) colorButton.clicked() @@ -322,7 +322,7 @@ Item { Row { z: 1 spacing: 1 - Controls.Label { + Label { text: "B" width: 16 color: "#eee" @@ -338,7 +338,7 @@ Item { maximumValue: 255 decimals: 0 - onValueChanged: { + onCompressedValueModified: { if (color.b !== value && !colorButton.block) { color.b = (value / 255.0) colorButton.clicked() @@ -350,7 +350,7 @@ Item { Row { z: 0 spacing: 1 - Controls.Label { + Label { text: "A" width: 16 color: "#eee" @@ -361,7 +361,7 @@ Item { DoubleSpinBox { id: alphaSlider width: 64 - onValueChanged: { + onCompressedValueModified: { if (colorButton.alpha !== value && !colorButton.block) { colorButton.alpha = value colorButton.clicked() @@ -387,7 +387,7 @@ Item { DoubleSpinBox { id: hueSlider2 width: 64 - onValueChanged: { + onCompressedValueModified: { if (colorButton.hue !== value && !colorButton.block) { colorButton.hue = value colorButton.clicked() @@ -399,7 +399,7 @@ Item { Row { z: 2 spacing: 1 - Controls.Label { + Label { text: "S" width: 16 color: "#eee" @@ -410,7 +410,7 @@ Item { DoubleSpinBox { id: saturationSlider width: 64 - onValueChanged: { + onCompressedValueModified: { if (colorButton.saturation !== value && !colorButton.block) { colorButton.saturation = value colorButton.clicked() @@ -422,7 +422,7 @@ Item { Row { z: 1 spacing: 1 - Controls.Label { + Label { text: "L" width: 16 color: "#eee" @@ -432,7 +432,7 @@ Item { DoubleSpinBox { id: lightnessSlider width: 64 - onValueChanged: { + onCompressedValueModified: { if (colorButton.lightness !== value && !colorButton.block) { colorButton.lightness = value colorButton.clicked() diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml index 8bbb5698efb..39fb95fce14 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml @@ -588,18 +588,8 @@ Column { } } - //empty spacer 2 Item { - height: 6 - } - - Item { - height: 6 - } - - //spacer 3 - Item { - height: 6 + height: 8 } ColorButton { @@ -622,13 +612,17 @@ Column { onClicked: colorEditor.color = colorButton.color } - //empty spacer 4 - Item { height: 2 } - Item { height: 2 } - - //spacer 5 Item { - height: 4 + height: 1 + } + + Item { + height: 2 + visible: checkButton.checked + } + + Item { + height: 1 } Item { @@ -645,7 +639,8 @@ Column { spacing: 2 Column { spacing: 5 - Text { + Label { + width: parent.width text: qsTr("Original") color: "#eee" } @@ -670,7 +665,8 @@ Column { Column { spacing: 5 - Text { + Label { + width: parent.width text: qsTr("New") color: "#eee" } @@ -688,7 +684,8 @@ Column { Column { spacing: 5 - Text { + Label { + width: parent.width text: qsTr("Recent") color: "#eee" elide: Text.ElideRight @@ -705,8 +702,6 @@ Column { } } - ExpandingSpacer { - } } } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComboBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComboBox.qml index 18f30dce1c3..65178606324 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComboBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComboBox.qml @@ -45,6 +45,8 @@ Controls.ComboBox { property bool block: false + property bool showExtendedFunctionButton: true + ExtendedFunctionLogic { id: extFuncLogic backendValue: comboBox.backendValue @@ -54,6 +56,8 @@ Controls.ComboBox { actionIndicator.icon.text: extFuncLogic.glyph actionIndicator.onClicked: extFuncLogic.show() + actionIndicator.visible: showExtendedFunctionButton + ColorLogic { id: colorLogic backendValue: comboBox.backendValue diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DoubleSpinBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DoubleSpinBox.qml index ca789fab43d..5b368565aea 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DoubleSpinBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DoubleSpinBox.qml @@ -24,20 +24,70 @@ ****************************************************************************/ import QtQuick 2.1 -import QtQuick.Controls 1.0 import QtQuickDesignerTheme 1.0 +import StudioControls 1.0 as StudioControls -SpinBox { - id: spinBox - width: 76 - decimals: 2 - stepSize: 0.1 - minimumValue: 0 - maximumValue: 1 +Item { + id: wrapper - property color textColor: Theme.color(Theme.PanelTextColorLight) + property alias decimals: spinBox.decimals + property alias hasSlider: spinBox.hasSlider - style: CustomSpinBoxStyle { + property real minimumValue: 0.0 + property real maximumValue: 1.0 + property real stepSize: 0.1 + + property alias sliderIndicatorVisible: spinBox.sliderIndicatorVisible + + property real value + + onValueChanged: spinBox.value = wrapper.value * spinBox.factor + + signal compressedValueModified + signal valueModified + + width: 90 + implicitHeight: spinBox.height + + onStepSizeChanged: spinBox.convert("stepSize", wrapper.stepSize) + onMinimumValueChanged: spinBox.convert("from", wrapper.minimumValue) + onMaximumValueChanged: spinBox.convert("to", wrapper.maximumValue) + + StudioControls.SpinBox { + id: spinBox + + onValueModified: wrapper.valueModified() + onCompressedValueModified: wrapper.compressedValueModified() + + onValueChanged: { + if (spinBox.__initialized) + wrapper.value = spinBox.value / spinBox.factor + } + + width: wrapper.width + decimals: 2 + + actionIndicatorVisible: false + + property bool __initialized: false + + property bool hasSlider: spinBox.sliderIndicatorVisible + + Component.onCompleted: { + spinBox.__initialized = true + + spinBox.convert("stepSize", wrapper.stepSize) + spinBox.convert("from", wrapper.minimumValue) + spinBox.convert("to", wrapper.maximumValue) + + spinBox.value = wrapper.value * spinBox.factor + } + + function convert(target, value) { + if (!spinBox.__initialized) + return + spinBox[target] = Math.round(value * spinBox.factor) + } } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontComboBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontComboBox.qml index 6cca085da75..16de1a90ef7 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontComboBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontComboBox.qml @@ -26,14 +26,16 @@ import QtQuick 2.1 import HelperWidgets 2.0 import QtQuick.Layouts 1.0 -import QtQuick.Controls 1.0 as Controls +import StudioControls 1.0 as StudioControls -Controls.ComboBox { +StudioControls.ComboBox { id: comboBox property variant backendValue property color textColor: colorLogic.textColor + labelColor: colorLogic.textColor + onTextColorChanged: setColor() editable: true @@ -43,10 +45,19 @@ Controls.ComboBox { editText = comboBox.backendValue.valueToString } - style: CustomComboBoxStyle { - textColor: comboBox.textColor + ExtendedFunctionLogic { + id: extFuncLogic + backendValue: comboBox.backendValue } + actionIndicator.icon.color: extFuncLogic.color + actionIndicator.icon.text: extFuncLogic.glyph + actionIndicator.onClicked: extFuncLogic.show() + + property bool showExtendedFunctionButton: true + + actionIndicator.visible: showExtendedFunctionButton + ColorLogic { id: colorLogic backendValue: comboBox.backendValue @@ -82,13 +93,6 @@ Controls.ComboBox { backendValue.value = indexText; } - ExtendedFunctionButton { - x: 2 - anchors.verticalCenter: parent.verticalCenter - backendValue: comboBox.backendValue - visible: comboBox.enabled - } - Connections { target: modelNodeBackend onSelectionChanged: { diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml index 10d562da158..28621e4be6c 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml @@ -26,7 +26,7 @@ import QtQuick 2.1 import HelperWidgets 2.0 import QtQuick.Layouts 1.0 -import QtQuick.Controls 1.0 as Controls +import StudioControls 1.0 as StudioControls import QtQuickDesignerTheme 1.0 Section { @@ -63,6 +63,7 @@ Section { FontComboBox { backendValue: fontSection.fontFamily Layout.fillWidth: true + width: 160 } Label { @@ -111,11 +112,13 @@ Section { } } - Controls.ComboBox { + StudioControls.ComboBox { id: sizeType model: ["pixels", "points"] property color textColor: Theme.color(Theme.PanelTextColorLight) - onCurrentIndexChanged: { + actionIndicatorVisible: false + + onActivated: { if (sizeWidget.isSetup) return; if (currentText == "pixels") { @@ -128,10 +131,6 @@ Section { } Layout.fillWidth: true - - style: CustomComboBoxStyle { - } - } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/GradientPropertySpinBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/GradientPropertySpinBox.qml index 4ca86b097d3..54483e1598c 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/GradientPropertySpinBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/GradientPropertySpinBox.qml @@ -25,20 +25,20 @@ import QtQuick 2.1 import QtQuick.Layouts 1.0 -import QtQuick.Controls 1.0 as Controls import QtQuickDesignerTheme 1.0 -import QtQuick.Controls.Styles 1.1 +import StudioControls 1.0 as StudioControls -DoubleSpinBox { +StudioControls.SpinBox { id: spinBox width: 82 Layout.minimumWidth: 82 property string propertyName + actionIndicatorVisible: false - minimumValue: -9999 - maximumValue: 9999 + from: -9999 + to: 9999 Component.onCompleted: spinBox.value = gradientLine.model.readGradientProperty(propertyName) - onValueChanged: gradientLine.model.setGradientProperty(propertyName, spinBox.value) + onCompressedValueModified: gradientLine.model.setGradientProperty(propertyName, spinBox.value) stepSize: 1 } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/LineEdit.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/LineEdit.qml index 18b25924b3f..0dfa558c09e 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/LineEdit.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/LineEdit.qml @@ -45,6 +45,8 @@ Controls.TextField { property bool showExtendedFunctionButton: true + actionIndicator.visible: showExtendedFunctionButton + signal commitData property string context diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SimpleColorPalette.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SimpleColorPalette.qml index c6b6acf2429..9cc787bd235 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SimpleColorPalette.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SimpleColorPalette.qml @@ -25,6 +25,7 @@ import QtQuick 2.1 import QtQuick.Controls 2.5 +import StudioControls 1.0 as StudioControls import HelperWidgets 2.0 import QtQuick.Controls.Private 1.0 // showing a ToolTip @@ -79,11 +80,9 @@ Item { contextMenu.popup() } } - Menu { + StudioControls.Menu { id: contextMenu - modal: true - closePolicy: Popup.CloseOnPressOutside | Popup.CloseOnEscape - MenuItem { + StudioControls.MenuItem { text: (backgroundColor.favorite ? qsTr("Remove from Favorites") : qsTr("Add to Favorites")) @@ -91,10 +90,6 @@ Item { paletteModel.toggleFavorite(index) } } - - Overlay.modal: Rectangle { - color: "transparent" - } } } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SpinBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SpinBox.qml index 196974d1038..eb941166fe2 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SpinBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SpinBox.qml @@ -38,6 +38,7 @@ Item { property real stepSize: 1.0 property alias backendValue: spinBox.backendValue + property alias sliderIndicatorVisible: spinBox.sliderIndicatorVisible width: 120 implicitHeight: spinBox.height @@ -67,7 +68,7 @@ Item { property real realValue: value / factor property variant backendValue - property bool hasSlider: false + property bool hasSlider: wrapper.sliderIndicatorVisible from: minimumValue * factor to: maximumValue * factor @@ -90,7 +91,7 @@ Item { } } - textColor: colorLogic.textColor + labelColor: colorLogic.textColor onCompressedValueModified: { if (backendValue.value !== realValue) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ToolTipArea.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ToolTipArea.qml index 9b51f1f4d32..df39546d93c 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ToolTipArea.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ToolTipArea.qml @@ -34,6 +34,8 @@ MouseArea { onExited: Tooltip.hideText() onCanceled: Tooltip.hideText() + onClicked: forceActiveFocus() + hoverEnabled: true property string tooltip diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml index 0c89aa119e2..d4b59a32d9d 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml @@ -25,7 +25,7 @@ import QtQuick 2.1 import HelperWidgets 2.0 -import QtQuick.Controls 1.1 as Controls +import StudioControls 1.0 as StudioControls import QtQuick.Layouts 1.0 import QtQuick.Controls.Styles 1.1 @@ -49,14 +49,16 @@ RowLayout { backendValue: urlChooser.backendValue } - Controls.ComboBox { + StudioControls.ComboBox { id: comboBox - ExtendedFunctionButton { - x: 2 - anchors.verticalCenter: parent.verticalCenter - backendValue: urlChooser.backendValue - visible: urlChooser.enabled + actionIndicator.icon.color: extFuncLogic.color + actionIndicator.icon.text: extFuncLogic.glyph + actionIndicator.onClicked: extFuncLogic.show() + + ExtendedFunctionLogic { + id: extFuncLogic + backendValue: comboBox.backendValue } property bool isComplete: false @@ -86,9 +88,6 @@ RowLayout { Layout.fillWidth: true editable: true - style: CustomComboBoxStyle { - textColor: urlChooser.textColor - } model: fileModel.fileModel diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/qmldir b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/qmldir index 9480f1d9a3a..007fb08d493 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/qmldir +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/qmldir @@ -17,6 +17,7 @@ CustomComboBoxStyle 2.0 CustomComboBoxStyle.qml CustomSpinBoxStyle 2.0 CustomSpinBoxStyle.qml ExpandingSpacer 2.0 ExpandingSpacer.qml ExtendedFunctionButton 2.0 ExtendedFunctionButton.qml +ExtendedFunctionLogic 2.0 ExtendedFunctionLogic.qml FlickableSection 2.0 FlickableSection.qml FontComboBox 2.0 FontComboBox.qml FontSection 2.0 FontSection.qml diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/AbstractButton.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/AbstractButton.qml index 3241eb405d5..6746508be26 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/AbstractButton.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/AbstractButton.qml @@ -40,7 +40,7 @@ T.AbstractButton { height: StudioTheme.Values.height width: StudioTheme.Values.height z: myButton.checked ? 10 : 3 - activeFocusOnTab: false // TODO Decision pending. Focus for AbstractButtons? + activeFocusOnTab: false background: Rectangle { id: buttonBackground diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ActionIndicator.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ActionIndicator.qml index e263f9337aa..c2a660228d1 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ActionIndicator.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ActionIndicator.qml @@ -70,7 +70,7 @@ Rectangle { name: "default" when: myControl.enabled && !actionIndicator.hover && !actionIndicator.pressed && !myControl.hover - && !myControl.activeFocus && !myControl.drag + && !myControl.edit && !myControl.drag PropertyChanges { target: actionIndicator color: StudioTheme.Values.themeControlBackground @@ -80,7 +80,7 @@ Rectangle { State { name: "hovered" when: actionIndicator.hover && !actionIndicator.pressed - && !myControl.activeFocus && !myControl.drag + && !myControl.edit && !myControl.drag PropertyChanges { target: actionIndicatorIcon scale: 1.2 @@ -89,7 +89,7 @@ Rectangle { State { name: "globalHover" when: myControl.hover && !actionIndicator.hover - && !actionIndicator.pressed && !myControl.activeFocus + && !actionIndicator.pressed && !myControl.edit && !myControl.drag PropertyChanges { target: actionIndicator @@ -99,7 +99,7 @@ Rectangle { }, State { name: "edit" - when: myControl.activeFocus + when: myControl.edit PropertyChanges { target: actionIndicator color: StudioTheme.Values.themeFocusEdit diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/CheckBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/CheckBox.qml index 2f122a7b89d..142421ee997 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/CheckBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/CheckBox.qml @@ -32,7 +32,8 @@ T.CheckBox { property alias actionIndicator: actionIndicator - property bool hover: myCheckBox.hovered // TODO two underscores + property bool hover: myCheckBox.hovered + property bool edit: false property alias actionIndicatorVisible: actionIndicator.visible property real __actionIndicatorWidth: StudioTheme.Values.squareComponentWidth @@ -43,21 +44,23 @@ T.CheckBox { font.pixelSize: StudioTheme.Values.myFontSize - height: StudioTheme.Values.height - width: StudioTheme.Values.height * 5 + implicitWidth: Math.max( + implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding + + implicitIndicatorWidth + spacing + actionIndicator.width) + implicitHeight: Math.max( + implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) spacing: StudioTheme.Values.checkBoxSpacing hoverEnabled: true - activeFocusOnTab: false // TODO Decision pending. Focus for CheckBoxes? + activeFocusOnTab: false contentItem: T.Label { id: checkBoxLabel leftPadding: 0 rightPadding: 0 - - width: 20 // TODO Not working - elide: Text.ElideRight - verticalAlignment: Text.AlignVCenter text: myCheckBox.text font: myCheckBox.font @@ -68,9 +71,7 @@ T.CheckBox { id: actionIndicator myControl: myCheckBox // TODO global hover issue. Can be solved with extra property in ActionIndicator - x: checkBoxLabel.visible ? checkBoxLabel.contentWidth - + (myCheckBox.spacing - * StudioTheme.Values.scaleFactor) : 0 // TODO scale factor + x: checkBoxLabel.visible ? checkBoxLabel.contentWidth + myCheckBox.spacing : 0 y: 0 width: actionIndicator.visible ? __actionIndicatorWidth : 0 height: actionIndicator.visible ? __actionIndicatorHeight : 0 @@ -125,6 +126,7 @@ T.CheckBox { State { name: "hovered" when: myCheckBox.hovered && !myCheckBox.pressed + && !actionIndicator.hover PropertyChanges { target: checkBoxBackground color: StudioTheme.Values.themeHoverHighlight diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/CheckIndicator.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/CheckIndicator.qml index 73788710bdb..4c314b9101e 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/CheckIndicator.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/CheckIndicator.qml @@ -73,7 +73,7 @@ Rectangle { name: "default" when: myControl.enabled && !(checkIndicator.hover || myControl.hover) - && !checkIndicator.checked && !myControl.activeFocus + && !checkIndicator.checked && !myControl.edit && !myControl.drag PropertyChanges { target: checkIndicator @@ -84,7 +84,7 @@ Rectangle { State { name: "hovered" when: (checkIndicator.hover || myControl.hover) - && !checkIndicator.checked && !myControl.activeFocus + && !checkIndicator.checked && !myControl.edit && !myControl.drag PropertyChanges { target: checkIndicator @@ -103,7 +103,7 @@ Rectangle { }, State { name: "edit" - when: myControl.activeFocus && !checkIndicator.checked + when: myControl.edit && !checkIndicator.checked && !(checkIndicator.hover && myControl.hover) PropertyChanges { target: checkIndicator diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml index 3ee5a02b7cd..c61e7e0dbf6 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml @@ -32,10 +32,10 @@ T.ComboBox { id: myComboBox property alias actionIndicator: actionIndicator - property alias labelColor: comboBoxInput.color property bool hover: false // This property is used to indicate the global hover state + property bool edit: myComboBox.activeFocus property alias actionIndicatorVisible: actionIndicator.visible property real __actionIndicatorWidth: StudioTheme.Values.squareComponentWidth @@ -203,7 +203,7 @@ T.ComboBox { states: [ State { name: "default" - when: !myComboBox.hover && !myComboBox.activeFocus + when: !myComboBox.hover && !myComboBox.edit PropertyChanges { target: myComboBox wheelEnabled: false @@ -220,7 +220,7 @@ T.ComboBox { }, State { name: "focus" - when: myComboBox.activeFocus && !myComboBox.editable + when: myComboBox.edit && !myComboBox.editable PropertyChanges { target: myComboBox wheelEnabled: true @@ -232,7 +232,7 @@ T.ComboBox { }, State { name: "edit" - when: myComboBox.activeFocus && myComboBox.editable + when: myComboBox.edit && myComboBox.editable PropertyChanges { target: myComboBox wheelEnabled: true diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBoxInput.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBoxInput.qml index 06e6ecb2b68..2ea123f90d2 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBoxInput.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBoxInput.qml @@ -32,7 +32,7 @@ TextInput { property T.Control myControl - property bool edit: false + property bool edit: textInput.activeFocus property bool drag: false z: 2 @@ -99,7 +99,7 @@ TextInput { states: [ State { name: "default" - when: myControl.enabled && !textInput.activeFocus + when: myControl.enabled && !textInput.edit && !mouseArea.containsMouse && !myControl.drag PropertyChanges { target: textInputArea @@ -113,7 +113,7 @@ TextInput { }, State { name: "hovered" - when: myControl.hover && !textInput.activeFocus && !myControl.drag + when: myControl.hover && !textInput.edit && !myControl.drag PropertyChanges { target: textInputArea color: StudioTheme.Values.themeHoverHighlight @@ -122,7 +122,7 @@ TextInput { }, State { name: "focus" - when: textInput.activeFocus && !myControl.editable + when: textInput.edit && !myControl.editable PropertyChanges { target: textInputArea color: StudioTheme.Values.themeFocusEdit @@ -131,7 +131,7 @@ TextInput { }, State { name: "edit" - when: textInput.activeFocus && myControl.editable + when: textInput.edit && myControl.editable extend: "focus" PropertyChanges { target: tapHandler diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ContextMenu.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ContextMenu.qml index ba5fec19e2a..3365751ab61 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ContextMenu.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ContextMenu.qml @@ -51,32 +51,32 @@ Menu { text: "Copy" enabled: myTextEdit.selectedText !== "" onTriggered: myTextEdit.copy() - shortcut: StandardKey.Copy + /* shortcut: StandardKey.Copy Shortcuts in QQC2 seem to override global shortcuts */ } Controls2.Action { text: "Cut" enabled: myTextEdit.selectedText !== "" && !myTextEdit.readOnly onTriggered: myTextEdit.cut() - shortcut: StandardKey.Cut + /* shortcut: StandardKey.Cut Shortcuts in QQC2 seem to override global shortcuts */ } Controls2.Action { text: "Paste" enabled: myTextEdit.canPaste onTriggered: myTextEdit.paste() - shortcut: StandardKey.Paste + /* shortcut: StandardKey.Paste Shortcuts in QQC2 seem to override global shortcuts */ } Controls2.Action { text: "Delete" enabled: myTextEdit.selectedText !== "" onTriggered: myTextEdit.remove(myTextEdit.selectionStart, myTextEdit.selectionEnd) - shortcut: StandardKey.Delete + /* shortcut: StandardKey.Delete Shortcuts in QQC2 seem to override global shortcuts */ } Controls2.Action { text: "Clear" enabled: myTextEdit.text !== "" onTriggered: myTextEdit.clear() - shortcut: StandardKey.DeleteCompleteLine + /* shortcut: StandardKey.DeleteCompleteLine Shortcuts in QQC2 seem to override global shortcuts */ } MenuSeparator { diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Menu.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Menu.qml index f9db27c6ac0..01a86847fc3 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Menu.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Menu.qml @@ -43,6 +43,8 @@ T.Menu { overlap: 1 padding: 0 + closePolicy: T.Popup.CloseOnPressOutside | T.Popup.CloseOnPressOutsideParent | T.Popup.CloseOnEscape + delegate: MenuItem { } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Slider.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Slider.qml index 955d73d6c72..7e111b6851a 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Slider.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Slider.qml @@ -47,6 +47,7 @@ T.Slider { property string __inactiveColor: StudioTheme.Values.themeSliderInactiveTrack property bool hover: false // This property is used to indicate the global hover state + property bool edit: slider.activeFocus property alias actionIndicatorVisible: actionIndicator.visible property real __actionIndicatorWidth: StudioTheme.Values.squareComponentWidth @@ -223,7 +224,7 @@ T.Slider { states: [ State { name: "default" - when: slider.enabled && !slider.hover && !slider.activeFocus + when: slider.enabled && !slider.hover && !slider.edit PropertyChanges { target: slider wheelEnabled: false @@ -231,7 +232,7 @@ T.Slider { }, State { name: "hovered" - when: slider.enabled && slider.hover && !slider.activeFocus + when: slider.enabled && slider.hover && !slider.edit PropertyChanges { target: slider __activeColor: StudioTheme.Values.themeSliderActiveTrackHover @@ -244,7 +245,7 @@ T.Slider { }, State { name: "focus" - when: slider.enabled && slider.activeFocus + when: slider.enabled && slider.edit PropertyChanges { target: slider wheelEnabled: true diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SliderPopup.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SliderPopup.qml index 27e8185da3a..beb6da4a8fb 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SliderPopup.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SliderPopup.qml @@ -33,7 +33,6 @@ T.Popup { property T.Control myControl dim: false - closePolicy: T.Popup.CloseOnEscape | T.Popup.CloseOnPressOutsideParent background: Rectangle { diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBox.qml index ef98c0f9ffd..e10a334bd66 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBox.qml @@ -30,7 +30,7 @@ import StudioTheme 1.0 as StudioTheme T.SpinBox { id: mySpinBox - property alias textColor: spinBoxInput.color + property alias labelColor: spinBoxInput.color property alias actionIndicator: actionIndicator property int decimals: 0 @@ -40,7 +40,7 @@ T.SpinBox { property real minStepSize: 1 property real maxStepSize: 10 - property bool edit: false + property bool edit: spinBoxInput.activeFocus property bool hover: false // This property is used to indicate the global hover state property bool drag: false @@ -91,11 +91,6 @@ T.SpinBox { top: Math.max(mySpinBox.from, mySpinBox.to) } - Connections { - target: spinBoxInput - onActiveFocusChanged: mySpinBox.edit = spinBoxInput.activeFocus - } - ActionIndicator { id: actionIndicator myControl: mySpinBox @@ -188,7 +183,7 @@ T.SpinBox { State { name: "default" when: mySpinBox.enabled && !mySpinBox.hover - && !mySpinBox.activeFocus && !mySpinBox.drag + && !mySpinBox.edit && !mySpinBox.drag PropertyChanges { target: mySpinBox __wheelEnabled: false @@ -205,7 +200,7 @@ T.SpinBox { }, State { name: "edit" - when: spinBoxInput.activeFocus + when: mySpinBox.edit PropertyChanges { target: mySpinBox __wheelEnabled: true @@ -245,7 +240,7 @@ T.SpinBox { // QTBUG-75862 && mySpinBox.focusReason === Qt.TabFocusReason) spinBoxInput.selectAll() - if (sliderPopup.opened && !activeFocus) + if (sliderPopup.opened && !mySpinBox.activeFocus) sliderPopup.close() } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxIndicator.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxIndicator.qml index ab1e90f3860..f75b8b47fd1 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxIndicator.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxIndicator.qml @@ -47,7 +47,10 @@ Rectangle { anchors.fill: parent hoverEnabled: true onContainsMouseChanged: spinBoxIndicator.hover = containsMouse - onPressed: mouse.accepted = false + onPressed: { + myControl.forceActiveFocus() + mouse.accepted = false + } } T.Label { diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxInput.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxInput.qml index 599f6fd5b5f..e2f718176ee 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxInput.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxInput.qml @@ -32,7 +32,7 @@ TextInput { property T.Control myControl - property bool edit: false + property bool edit: textInput.activeFocus property bool drag: false z: 2 @@ -53,7 +53,7 @@ TextInput { activeFocusOnPress: false clip: true - // TextInput foucs needs to be set to activeFocus whenever it changes, + // TextInput focus needs to be set to activeFocus whenever it changes, // otherwise TextInput will get activeFocus whenever the parent SpinBox gets // activeFocus. This will lead to weird side effects. onActiveFocusChanged: textInput.focus = activeFocus @@ -139,7 +139,7 @@ TextInput { states: [ State { name: "default" - when: myControl.enabled && !textInput.activeFocus + when: myControl.enabled && !textInput.edit && !mouseArea.containsMouse && !myControl.drag PropertyChanges { target: textInputArea @@ -161,7 +161,7 @@ TextInput { }, State { name: "hovered" - when: myControl.hover && !textInput.activeFocus && !myControl.drag + when: myControl.hover && !textInput.edit && !myControl.drag PropertyChanges { target: textInputArea color: StudioTheme.Values.themeHoverHighlight @@ -170,7 +170,7 @@ TextInput { }, State { name: "edit" - when: textInput.activeFocus + when: textInput.edit PropertyChanges { target: textInputArea color: StudioTheme.Values.themeFocusEdit diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml index 3525bfa41bc..80ca6fd1c7b 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml @@ -31,10 +31,9 @@ T.TextField { id: myTextField property alias actionIndicator: actionIndicator - property alias translationIndicator: translationIndicator - property bool edit: false + property bool edit: myTextField.activeFocus property bool hover: false // This property is used to indicate the global hover state property alias actionIndicatorVisible: actionIndicator.visible @@ -68,8 +67,6 @@ T.TextField { rightPadding: StudioTheme.Values.inputHorizontalPadding + translationIndicator.width - (translationIndicatorVisible ? StudioTheme.Values.border : 0) - onActiveFocusChanged: myTextField.edit = myTextField.activeFocus - MouseArea { id: mouseArea anchors.fill: parent @@ -126,7 +123,7 @@ T.TextField { State { name: "default" when: myTextField.enabled && !myTextField.hover - && !myTextField.activeFocus + && !myTextField.edit PropertyChanges { target: textFieldBackground color: StudioTheme.Values.themeControlBackground @@ -139,7 +136,7 @@ T.TextField { }, State { name: "hovered" - when: myTextField.hover && !myTextField.activeFocus + when: myTextField.hover && !myTextField.edit PropertyChanges { target: textFieldBackground color: StudioTheme.Values.themeHoverHighlight @@ -148,7 +145,7 @@ T.TextField { }, State { name: "edit" - when: myTextField.activeFocus + when: myTextField.edit PropertyChanges { target: textFieldBackground color: StudioTheme.Values.themeFocusEdit diff --git a/src/app/app.qbs b/src/app/app.qbs index 3ed4eb8fdef..a866a2ecdb5 100644 --- a/src/app/app.qbs +++ b/src/app/app.qbs @@ -26,8 +26,14 @@ QtcProduct { property bool qtcRunnable: true bundle.identifier: qtc.ide_bundle_identifier + + // Some of these are in here only to override the entries added to app-Info.plist with other + // build systems in mind. bundle.infoPlist: ({ - "NSHumanReadableCopyright": qtc.qtcreator_copyright_string + "NSHumanReadableCopyright": qtc.qtcreator_copyright_string, + "CFBundleExecutable": qtc.ide_app_target, + "CFBundleIdentifier": qtc.ide_bundle_identifier, + "CFBundleVersion": version }) cpp.rpaths: qbs.targetOS.contains("macos") ? ["@executable_path/../Frameworks"] diff --git a/src/libs/qmljs/qmljsreformatter.cpp b/src/libs/qmljs/qmljsreformatter.cpp index ce1035c39b9..b2bb503d22e 100644 --- a/src/libs/qmljs/qmljsreformatter.cpp +++ b/src/libs/qmljs/qmljsreformatter.cpp @@ -96,6 +96,7 @@ class Rewriter : protected Visitor int _lastNewlineOffset = -1; bool _hadEmptyLine = false; int _binaryExpDepth = 0; + bool _hasOpenComment = false; public: Rewriter(Document::Ptr doc) @@ -201,6 +202,9 @@ protected: void out(const QString &str, const SourceLocation &lastLoc = SourceLocation()) { + if (_hasOpenComment) { + newLine(); + } if (lastLoc.isValid()) { QList comments = _doc->engine()->comments(); for (; _nextComment < comments.size(); ++_nextComment) { @@ -371,6 +375,7 @@ protected: { // if preceded by a newline, it's an empty line! _hadEmptyLine = _line.trimmed().isEmpty(); + _hasOpenComment = false; // if the preceding line wasn't empty, reindent etc. if (!_hadEmptyLine) { @@ -524,6 +529,7 @@ protected: out(" "); out(toString(nextCommentLoc)); + _hasOpenComment = true; } } } @@ -536,6 +542,37 @@ protected: return false; } + bool visit(UiEnumDeclaration *ast) override + { + out(ast->enumToken); + out(" "); + out(ast->name.toString()); + out(" "); + out("{"); // TODO: out(ast->lbraceToken); + newLine(); + + accept(ast->members); + + out(ast->rbraceToken); + return false; + } + + bool visit(UiEnumMemberList *list) override + { + for (UiEnumMemberList *it = list; it; it = it->next) { + out(it->memberToken); + if (it->valueToken.isValid()) { + out(" = "); + out(it->valueToken); + } + if (it->next) { + out(","); + } + newLine(); + } + return false; + } + bool visit(UiImport *ast) override { out("import ", ast->importToken); @@ -565,9 +602,10 @@ protected: bool visit(UiObjectInitializer *ast) override { out(ast->lbraceToken); - if (ast->members) + if (ast->members) { lnAcceptIndented(ast->members); - newLine(); + newLine(); + } out(ast->rbraceToken); return false; } @@ -679,8 +717,10 @@ protected: bool visit(ObjectPattern *ast) override { out(ast->lbraceToken); - lnAcceptIndented(ast->properties); - newLine(); + if (ast->properties) { + lnAcceptIndented(ast->properties); + newLine(); + } out(ast->rbraceToken); return false; } @@ -916,14 +956,23 @@ protected: bool visit(VariableStatement *ast) override { - out("var ", ast->declarationKindToken); + out(ast->declarationKindToken); + out(" "); accept(ast->declarations); return false; } bool visit(PatternElement *ast) override { - + if (ast->isForDeclaration) { + if (ast->scope == VariableScope::Var) { + out("var "); + } else if (ast->scope == VariableScope::Let) { + out("let "); + } else if (ast->scope == VariableScope::Const) { + out("const "); + } + } out(ast->identifierToken); if (ast->initializer) { if (ast->isVariableDeclaration()) @@ -987,7 +1036,12 @@ protected: out(ast->forToken); out(" "); out(ast->lparenToken); - accept(ast->initialiser); + if (ast->initialiser) { + accept(ast->initialiser); + } else if (ast->declarations) { + out("var "); + accept(ast->declarations); + } out("; ", ast->firstSemicolonToken); accept(ast->condition); out("; ", ast->secondSemicolonToken); @@ -1275,6 +1329,9 @@ protected: { for (FormalParameterList *it = ast; it; it = it->next) { out(it->element->bindingIdentifier.toString()); // TODO + if (it->next) { + out(", "); + } } return false; } diff --git a/src/libs/ssh/sshconnection.cpp b/src/libs/ssh/sshconnection.cpp index 88509d5b62c..b368ccc8efe 100644 --- a/src/libs/ssh/sshconnection.cpp +++ b/src/libs/ssh/sshconnection.cpp @@ -231,7 +231,7 @@ void SshConnection::disconnectFromHost() case Connecting: case Connected: if (!d->sharingEnabled) { - emitDisconnected(); + QTimer::singleShot(0, this, &SshConnection::emitDisconnected); return; } d->state = Disconnecting; diff --git a/src/plugins/autotest/boost/boostcodeparser.cpp b/src/plugins/autotest/boost/boostcodeparser.cpp index 43af677159b..79c612285b1 100644 --- a/src/plugins/autotest/boost/boostcodeparser.cpp +++ b/src/plugins/autotest/boost/boostcodeparser.cpp @@ -112,6 +112,16 @@ void BoostCodeParser::handleIdentifier() handleTestCase(TestCaseType::Fixture); } else if (identifier == "BOOST_DATA_TEST_CASE") { handleTestCase(TestCaseType::Data); + } else if (identifier == "BOOST_DATA_TEST_CASE_F") { + m_currentState.setFlag(BoostTestTreeItem::Fixture); + handleTestCase(TestCaseType::Data); + } else if (identifier == "BOOST_AUTO_TEST_CASE_TEMPLATE") { + m_currentState.setFlag(BoostTestTreeItem::Templated); + handleTestCase(TestCaseType::Auto); + } else if (identifier == "BOOST_FIXTURE_TEST_CASE_TEMPLATE") { + m_currentState.setFlag(BoostTestTreeItem::Fixture); + m_currentState.setFlag(BoostTestTreeItem::Templated); + handleTestCase(TestCaseType::Auto); } else if (identifier == "BOOST_TEST_DECORATOR") { handleDecorator(); } @@ -133,6 +143,7 @@ void BoostCodeParser::handleSuiteBegin(bool isFixture) m_currentSuite.prepend(m_suites.last().fullName + '/'); if (isFixture) { // fixture suites have a (fixture) class name as 2nd parameter + m_currentState.setFlag(BoostTestTreeItem::Fixture); if (!skipCommentsUntil(T_COMMA)) return; if (!skipCommentsUntil(T_IDENTIFIER)) @@ -194,6 +205,12 @@ void BoostCodeParser::handleTestCase(TestCaseType testCaseType) } if (testCaseType == TestCaseType::Parameter) m_currentState |= BoostTestTreeItem::Parameterized; + } else if (m_currentState.testFlag(BoostTestTreeItem::Fixture)) { + // ignore first parameter (fixture) and first comma + if (!skipCommentsUntil(T_IDENTIFIER)) + return; + if (!skipCommentsUntil(T_COMMA)) + return; } if (!skipCommentsUntil(T_IDENTIFIER)) return; @@ -227,7 +244,8 @@ void BoostCodeParser::handleTestCase(TestCaseType testCaseType) m_currentState = BoostTestTreeItem::Enabled; } } else { - handleDecorators(); + if (!m_currentState.testFlag(BoostTestTreeItem::Templated)) + handleDecorators(); locationAndType = locationAndTypeFromToken(token, m_source, m_currentState, m_suites); m_testCases.append(locationAndType); m_currentState = BoostTestTreeItem::Enabled; @@ -279,8 +297,11 @@ void BoostCodeParser::handleDecorators() } else { // FIXME we have a const(expr) bool? currently not easily achievable } + } else if (symbolName == "decorator::fixture" + || (aliasedOrReal && simplifiedName.startsWith("::fixture"))){ + m_currentState.setFlag(BoostTestTreeItem::Fixture); } - // TODO.. fixture, label, depends_on, label, precondition, timeout,... + // TODO.. depends_on, label, precondition, timeout,... skipCommentsUntil(T_LPAREN); skipCommentsUntil(T_RPAREN); diff --git a/src/plugins/autotest/boost/boosttestoutputreader.cpp b/src/plugins/autotest/boost/boosttestoutputreader.cpp index 03699e92dff..3ae5756d3a5 100644 --- a/src/plugins/autotest/boost/boosttestoutputreader.cpp +++ b/src/plugins/autotest/boost/boosttestoutputreader.cpp @@ -107,7 +107,7 @@ void BoostTestOutputReader::sendCompleteInformation() if (m_lineNumber) { result->setLine(m_lineNumber); result->setFileName(m_fileName); - } // else TODO + } result->setDescription(m_description); result->setResult(m_result); @@ -133,6 +133,8 @@ void BoostTestOutputReader::handleMessageMatch(const QRegularExpressionMatch &ma if (m_currentTest.isEmpty() || m_logLevel > LogLevel::UnitScope) m_currentTest = caseFromContent(content); m_result = ResultType::Fail; + if (m_reportLevel == ReportLevel::No) + ++m_summary[ResultType::Fail]; m_description = content; } else if (content.startsWith("fatal error:")) { if (m_currentTest.isEmpty() || m_logLevel > LogLevel::UnitScope) @@ -171,6 +173,8 @@ void BoostTestOutputReader::handleMessageMatch(const QRegularExpressionMatch &ma } else if (content.startsWith("Test case ")) { m_currentTest = match.captured(4); m_result = ResultType::Skip; + if (m_reportLevel == ReportLevel::Confirm || m_reportLevel == ReportLevel::No) + ++m_summary[ResultType::Skip]; m_description = content; } @@ -193,10 +197,10 @@ void BoostTestOutputReader::processOutputLine(const QByteArray &outputLineWithNe static QRegularExpression noAssertion("^Test case (.*) did not check any assertions$"); static QRegularExpression summaryPreamble("^\\s*Test (module|suite|case) \"(.*)\" has " - "(failed|passed) with:$"); + "(failed|passed)( with:)?$"); static QRegularExpression summarySkip("^\\s+Test case \"(.*)\" was skipped$"); static QRegularExpression summaryDetail("^\\s+(\\d+) test cases? out of (\\d+) " - "(failed|passed)$"); + "(failed|passed|skipped)$"); static QRegularExpression summaryAssertion("^\\s+(\\d+) assertions? out of (\\d+) " "(failed|passed)$"); @@ -284,16 +288,34 @@ void BoostTestOutputReader::processOutputLine(const QByteArray &outputLineWithNe return; } - // should summary get reported unconditionally? match = summaryPreamble.match(line); if (match.hasMatch()) { createAndReportResult(match.captured(0), ResultType::MessageInfo); + if (m_reportLevel == ReportLevel::Detailed || match.captured(4).isEmpty()) { + if (match.captured(1) == "case") { + if (match.captured(3) == "passed") + ++m_summary[ResultType::Pass]; + else + ++m_summary[ResultType::Fail]; + } + } return; } match = summaryDetail.match(line); if (match.hasMatch()) { createAndReportResult(match.captured(0), ResultType::MessageInfo); + int report = match.captured(1).toInt(); + QString type = match.captured(3); + if (m_reportLevel != ReportLevel::Detailed) { + if (type == "passed") + m_summary[ResultType::Pass] += report; + else if (type == "failed") + m_summary[ResultType::Fail] += report; + else if (type == "skipped") + m_summary[ResultType::Skip] += report; + } + return; } @@ -306,6 +328,8 @@ void BoostTestOutputReader::processOutputLine(const QByteArray &outputLineWithNe match = summarySkip.match(line); if (match.hasMatch()) { createAndReportResult(match.captured(0), ResultType::MessageInfo); + if (m_reportLevel == ReportLevel::Detailed) + ++m_summary[ResultType::Skip]; return; } @@ -316,11 +340,17 @@ void BoostTestOutputReader::processOutputLine(const QByteArray &outputLineWithNe BoostTestResult *result = new BoostTestResult(id(), m_projectFile, QString()); int failed = match.captured(1).toInt(); QString txt = tr("%1 failures detected in %2.").arg(failed).arg(match.captured(3)); + int passed = (m_testCaseCount != -1) + ? m_testCaseCount - failed - m_summary[ResultType::Skip] : -1; if (m_testCaseCount != -1) - txt.append(' ').append(tr("%1 tests passed.").arg(m_testCaseCount - failed)); + txt.append(' ').append(tr("%1 tests passed.").arg(passed)); result->setDescription(txt); - result->setResult(ResultType::MessageInfo); // TODO report similar to disabled tests + result->setResult(ResultType::MessageInfo); reportResult(TestResultPtr(result)); + if (m_reportLevel == ReportLevel::Confirm) { // for the final summary + m_summary[ResultType::Pass] += passed; + m_summary[ResultType::Fail] += failed; + } m_testCaseCount = -1; return; } @@ -333,8 +363,10 @@ void BoostTestOutputReader::processOutputLine(const QByteArray &outputLineWithNe if (m_testCaseCount != -1) txt.append(' ').append(tr("%1 tests passed.").arg(m_testCaseCount)); result->setDescription(txt); - result->setResult(ResultType::MessageInfo); // TODO report similar to disabled tests + result->setResult(ResultType::MessageInfo); reportResult(TestResultPtr(result)); + if (m_reportLevel == ReportLevel::Confirm) // for the final summary + m_summary.insert(ResultType::Pass, m_testCaseCount); return; } @@ -374,15 +406,17 @@ TestResultPtr BoostTestOutputReader::createDefaultResult() const result->setTestSuite(m_currentSuite); result->setTestCase(m_currentTest); - // TODO find corresponding TestTreeItem and set filename/line return TestResultPtr(result); } void BoostTestOutputReader::onFinished(int exitCode, QProcess::ExitStatus /*exitState*/) { + if (m_reportLevel == ReportLevel::No && m_testCaseCount != -1) { + int reportedFailsAndSkips = m_summary[ResultType::Fail] + m_summary[ResultType::Skip]; + m_summary.insert(ResultType::Pass, m_testCaseCount - reportedFailsAndSkips); + } // boost::exit_success (0), boost::exit_test_failure (201) // or boost::exit_exception_failure (200) // be graceful and do not add a fatal for exit_test_failure - // but exit code 0 can be forced with an option - what todo in that case? if (m_logLevel == LogLevel::Nothing && m_reportLevel == ReportLevel::No) { switch (exitCode) { case 0: diff --git a/src/plugins/autotest/boost/boosttestparser.cpp b/src/plugins/autotest/boost/boosttestparser.cpp index e1e87ab2993..6f953e515a8 100644 --- a/src/plugins/autotest/boost/boosttestparser.cpp +++ b/src/plugins/autotest/boost/boosttestparser.cpp @@ -40,7 +40,9 @@ namespace BoostTestUtils { static const QStringList relevant = { QStringLiteral("BOOST_AUTO_TEST_CASE"), QStringLiteral("BOOST_TEST_CASE"), QStringLiteral("BOOST_DATA_TEST_CASE"), QStringLiteral("BOOST_FIXTURE_TEST_CASE"), - QStringLiteral("BOOST_PARAM_TEST_CASE") + QStringLiteral("BOOST_PARAM_TEST_CASE"), QStringLiteral("BOOST_DATA_TEST_CASE_F"), + QStringLiteral("BOOST_AUTO_TEST_CASE_TEMPLATE"), + QStringLiteral("BOOST_FIXTURE_TEST_CASE_TEMPLATE"), }; bool isBoostTestMacro(const QString ¯o) diff --git a/src/plugins/autotest/boost/boosttesttreeitem.cpp b/src/plugins/autotest/boost/boosttesttreeitem.cpp index ac1e900b47c..e2e58c28aff 100644 --- a/src/plugins/autotest/boost/boosttesttreeitem.cpp +++ b/src/plugins/autotest/boost/boosttesttreeitem.cpp @@ -233,7 +233,10 @@ QList BoostTestTreeItem::getSelectedTestConfigurations() co if (!item->enabled()) // ignore child tests known to be disabled when using run selected return; if (item->checked() == Qt::Checked) { - QString tcName = handleSpecialFunctionNames(item->name()); + QString tcName = item->name(); + if (item->state().testFlag(BoostTestTreeItem::Templated)) + tcName.append("<*"); + tcName = handleSpecialFunctionNames(tcName); testCasesForProjectFile[item->proFile()].testCases.append( item->prependWithParentsSuitePaths(tcName)); testCasesForProjectFile[item->proFile()].internalTargets.unite(item->internalTargets()); @@ -268,12 +271,17 @@ TestConfiguration *BoostTestTreeItem::testConfiguration() const QString tcName = handleSpecialFunctionNames(boostItem->name()); if (boostItem->type() == TestSuite) // execute everything below a suite tcName.append("/*"); + else if (boostItem->state().testFlag(BoostTestTreeItem::Templated)) + tcName.append("<*"); testCases.append(boostItem->prependWithParentsSuitePaths(tcName)); } } }); } else { - testCases.append(prependWithParentsSuitePaths(handleSpecialFunctionNames(name()))); + QString tcName = name(); + if (state().testFlag(BoostTestTreeItem::Templated)) + tcName.append("<*"); + testCases.append(prependWithParentsSuitePaths(handleSpecialFunctionNames(tcName))); } BoostTestConfiguration *config = new BoostTestConfiguration; @@ -297,12 +305,15 @@ TestConfiguration *BoostTestTreeItem::debugConfiguration() const QString BoostTestTreeItem::nameSuffix() const { static QString markups[] = {QCoreApplication::translate("BoostTestTreeItem", "parameterized"), - QCoreApplication::translate("BoostTestTreeItem", "fixture")}; + QCoreApplication::translate("BoostTestTreeItem", "fixture"), + QCoreApplication::translate("BoostTestTreeItem", "templated")}; QString suffix; if (m_state & Parameterized) suffix = QString(" [") + markups[0]; if (m_state & Fixture) suffix += (suffix.isEmpty() ? QString(" [") : QString(", ")) + markups[1]; + if (m_state & Templated) + suffix += (suffix.isEmpty() ? QString(" [") : QString(", ")) + markups[2]; if (!suffix.isEmpty()) suffix += ']'; return suffix; diff --git a/src/plugins/autotest/boost/boosttesttreeitem.h b/src/plugins/autotest/boost/boosttesttreeitem.h index 31d4dd00456..1149720f9d0 100644 --- a/src/plugins/autotest/boost/boosttesttreeitem.h +++ b/src/plugins/autotest/boost/boosttesttreeitem.h @@ -43,6 +43,7 @@ public: Parameterized = 0x10, Fixture = 0x20, + Templated = 0x40, }; Q_FLAGS(TestState) Q_DECLARE_FLAGS(TestStates, TestState) diff --git a/src/plugins/autotest/testoutputreader.h b/src/plugins/autotest/testoutputreader.h index b78f9cbecbd..87216a2570c 100644 --- a/src/plugins/autotest/testoutputreader.h +++ b/src/plugins/autotest/testoutputreader.h @@ -48,6 +48,8 @@ public: void createAndReportResult(const QString &message, ResultType type); bool hadValidOutput() const { return m_hadValidOutput; } int disabledTests() const { return m_disabled; } + bool hasSummary() const { return !m_summary.isEmpty(); } + QHash summary() const { return m_summary; } void setId(const QString &id) { m_id = id; } QString id() const { return m_id; } @@ -64,6 +66,7 @@ protected: QProcess *m_testApplication; // not owned QString m_buildDir; QString m_id; + QHash m_summary; int m_disabled = -1; private: bool m_hadValidOutput = false; diff --git a/src/plugins/autotest/testresultmodel.cpp b/src/plugins/autotest/testresultmodel.cpp index 874e813660e..f07bc5f0085 100644 --- a/src/plugins/autotest/testresultmodel.cpp +++ b/src/plugins/autotest/testresultmodel.cpp @@ -23,10 +23,11 @@ ** ****************************************************************************/ +#include "testresultmodel.h" #include "autotesticons.h" #include "autotestplugin.h" #include "testresultdelegate.h" -#include "testresultmodel.h" +#include "testrunner.h" #include "testsettings.h" #include @@ -220,6 +221,10 @@ QString TestResultItem::resultString() const TestResultModel::TestResultModel(QObject *parent) : Utils::TreeModel(new TestResultItem(TestResultPtr()), parent) { + connect(TestRunner::instance(), &TestRunner::reportSummary, + this, [this](const QString &id, const QHash &summary){ + m_reportedSummary.insert(id, summary); + }); } void TestResultModel::updateParent(const TestResultItem *item) @@ -256,7 +261,7 @@ void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoEx return; } - m_testResultCount[testResult->result()]++; + m_testResultCount[testResult->id()][testResult->result()]++; TestResultItem *newItem = new TestResultItem(testResult); TestResultItem *root = nullptr; @@ -314,6 +319,7 @@ void TestResultModel::clearTestResults() { clear(); m_testResultCount.clear(); + m_reportedSummary.clear(); m_disabled = 0; m_fileNames.clear(); m_maxWidthOfFileName = 0; @@ -363,6 +369,21 @@ int TestResultModel::maxWidthOfLineNumber(const QFont &font) return m_widthOfLineNumber; } +int TestResultModel::resultTypeCount(ResultType type) const +{ + int result = 0; + + for (auto resultsForId : m_testResultCount.values()) + result += resultsForId.value(type, 0); + + for (auto id : m_reportedSummary.keys()) { + if (int counted = m_testResultCount.value(id).value(type)) + result -= counted; + result += m_reportedSummary[id].value(type); + } + return result; +} + TestResultItem *TestResultModel::findParentItemFor(const TestResultItem *item, const TestResultItem *startItem) const { diff --git a/src/plugins/autotest/testresultmodel.h b/src/plugins/autotest/testresultmodel.h index 38c880003b6..6370296ac04 100644 --- a/src/plugins/autotest/testresultmodel.h +++ b/src/plugins/autotest/testresultmodel.h @@ -84,7 +84,7 @@ public: int maxWidthOfFileName(const QFont &font); int maxWidthOfLineNumber(const QFont &font); - int resultTypeCount(ResultType type) const { return m_testResultCount.value(type, 0); } + int resultTypeCount(ResultType type) const; int disabledTests() const { return m_disabled; } void raiseDisabledTests(int amount) { m_disabled += amount; } @@ -94,7 +94,8 @@ private: TestResultItem *findParentItemFor(const TestResultItem *item, const TestResultItem *startItem = nullptr) const; void updateParent(const TestResultItem *item); - QMap m_testResultCount; + QHash> m_testResultCount; + QHash> m_reportedSummary; int m_widthOfLineNumber = 0; int m_maxWidthOfFileName = 0; int m_disabled = 0; diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp index e1f4497580c..cf432870e3a 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -270,6 +270,9 @@ void TestRunner::onProcessFinished() const int disabled = m_currentOutputReader->disabledTests(); if (disabled > 0) emit hadDisabledTests(disabled); + if (m_currentOutputReader->hasSummary()) + emit reportSummary(m_currentOutputReader->id(), m_currentOutputReader->summary()); + resetInternalPointers(); if (!m_fakeFutureInterface) { diff --git a/src/plugins/autotest/testrunner.h b/src/plugins/autotest/testrunner.h index 79e7a8c389c..5628a6d29eb 100644 --- a/src/plugins/autotest/testrunner.h +++ b/src/plugins/autotest/testrunner.h @@ -71,6 +71,7 @@ signals: void requestStopTestRun(); void testResultReady(const TestResultPtr &result); void hadDisabledTests(int disabled); + void reportSummary(const QString &id, const QHash &summary); private: void buildProject(ProjectExplorer::Project *project); diff --git a/src/plugins/clangformat/clangformatplugin.cpp b/src/plugins/clangformat/clangformatplugin.cpp index e82802ab303..49f4fe049f0 100644 --- a/src/plugins/clangformat/clangformatplugin.cpp +++ b/src/plugins/clangformat/clangformatplugin.cpp @@ -152,8 +152,13 @@ bool ClangFormatPlugin::initialize(const QStringList &arguments, QString *errorS openClangFormatConfigAction->setData(doc->filePath().toString()); }); } -#endif return true; +#else + *errorString = "Disabling ClangFormat plugin as it is not built against a suitable version of " + "Clang's libFormat. For more information, see the Qt Creator README at " + "https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/README.md"; + return false; +#endif } } // namespace ClangFormat diff --git a/src/plugins/coreplugin/outputwindow.cpp b/src/plugins/coreplugin/outputwindow.cpp index 2b5de1b2b6f..0ed7542ee16 100644 --- a/src/plugins/coreplugin/outputwindow.cpp +++ b/src/plugins/coreplugin/outputwindow.cpp @@ -119,6 +119,7 @@ OutputWindow::OutputWindow(Context context, const QString &settingsKey, QWidget connect(copyAction, &QAction::triggered, this, &QPlainTextEdit::copy); connect(pasteAction, &QAction::triggered, this, &QPlainTextEdit::paste); connect(selectAllAction, &QAction::triggered, this, &QPlainTextEdit::selectAll); + connect(this, &QPlainTextEdit::blockCountChanged, this, &OutputWindow::filterNewContent); connect(this, &QPlainTextEdit::undoAvailable, undoAction, &QAction::setEnabled); connect(this, &QPlainTextEdit::redoAvailable, redoAction, &QAction::setEnabled); @@ -216,10 +217,8 @@ OutputFormatter *OutputWindow::formatter() const void OutputWindow::setFormatter(OutputFormatter *formatter) { d->formatter = formatter; - if (d->formatter) { + if (d->formatter) d->formatter->setPlainTextEdit(this); - connect(d->formatter, &OutputFormatter::contentChanged, this, &OutputWindow::filterNewContent); - } } void OutputWindow::showEvent(QShowEvent *e) diff --git a/src/plugins/cpptools/builtinindexingsupport.cpp b/src/plugins/cpptools/builtinindexingsupport.cpp index ddde5699a18..3677cefc295 100644 --- a/src/plugins/cpptools/builtinindexingsupport.cpp +++ b/src/plugins/cpptools/builtinindexingsupport.cpp @@ -52,6 +52,7 @@ using namespace CppTools; using namespace CppTools::Internal; static const bool FindErrorsIndexing = qgetenv("QTC_FIND_ERRORS_INDEXING") == "1"; +static Q_LOGGING_CATEGORY(indexerLog, "qtc.cpptools.indexer", QtWarningMsg) namespace { @@ -205,6 +206,8 @@ void index(QFutureInterface &indexingFuture, const ProjectExplorer::HeaderPaths fallbackHeaderPaths = cmm->headerPaths(); const CPlusPlus::LanguageFeatures defaultFeatures = CPlusPlus::LanguageFeatures::defaultFeatures(); + + qCDebug(indexerLog) << "About to index" << files.size() << "files."; for (int i = 0; i < files.size(); ++i) { if (indexingFuture.isCanceled() || superFuture.isCanceled()) break; @@ -225,6 +228,7 @@ void index(QFutureInterface &indexingFuture, processingHeaders = true; } + qCDebug(indexerLog) << " Indexing" << i + 1 << "of" << files.size() << ":" << fileName; ProjectExplorer::HeaderPaths headerPaths = parts.isEmpty() ? fallbackHeaderPaths : parts.first()->headerPaths; @@ -236,6 +240,7 @@ void index(QFutureInterface &indexingFuture, if (isSourceFile) sourceProcessor->resetEnvironment(); } + qCDebug(indexerLog) << "Indexing finished."; } void parse(QFutureInterface &indexingFuture, diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp index ca206d6e178..82bb009cc2d 100644 --- a/src/plugins/debugger/debuggermainwindow.cpp +++ b/src/plugins/debugger/debuggermainwindow.cpp @@ -288,13 +288,12 @@ DebuggerMainWindow::DebuggerMainWindow() cmd->setAttribute(Command::CA_Hide); viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE); - connect(ICore::instance(), &ICore::saveSettingsRequested, this, [this] { + connect(ICore::instance(), &ICore::saveSettingsRequested, this, + [this](ICore::SaveSettingsReason reason) { // There's one saveSettings triggered after plugin loading intentionally. // We do not want to save anything at that time. - static bool firstOne = true; - if (firstOne) { + if (reason == ICore::InitializationDone) { qCDebug(perspectivesLog) << "FIRST SAVE SETTINGS REQUEST IGNORED"; - firstOne = false; } else { qCDebug(perspectivesLog) << "SAVING SETTINGS"; savePersistentSettings(); diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index 245f3a15dad..f68d637e1f2 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -1011,6 +1011,8 @@ void DebuggerRunTool::showMessage(const QString &msg, int channel, int timeout) if (channel == ConsoleOutput) debuggerConsole()->printItem(ConsoleItem::DefaultType, msg); + QTC_ASSERT(m_engine, qDebug() << msg; return); + m_engine->showMessage(msg, channel, timeout); if (m_engine2) m_engine->showMessage(msg, channel, timeout); diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index ebbce08bc4e..31b26645835 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -51,6 +51,18 @@ add_qtc_plugin(componentsplugin SKIP_DEBUG_CMAKE_FILE_CHECK ) +add_qtc_plugin(qmlpreviewplugin + CONDITION TARGET QmlDesigner + DEPENDS Core ProjectExplorer QmlDesigner Utils Qt5::Qml + INCLUDES ${CMAKE_CURRENT_LIST_DIR}/designercore/include + SOURCES + qmlpreviewplugin/qmlpreviewactions.cpp qmlpreviewplugin/qmlpreviewactions.h + qmlpreviewplugin/qmlpreviewplugin.cpp qmlpreviewplugin/qmlpreviewplugin.h + qmlpreviewplugin/qmlpreviewplugin.qrc + PLUGIN_PATH ${QmlDesignerPluginInstallPrefix} + SKIP_DEBUG_CMAKE_FILE_CHECK +) + add_qtc_plugin(qtquickplugin CONDITION TARGET QmlDesigner DEPENDS Core QmlDesigner Utils Qt5::Qml @@ -283,6 +295,9 @@ extend_qtc_plugin(QmlDesigner propertyeditorvalue.cpp propertyeditorvalue.h propertyeditorview.cpp propertyeditorview.h propertyeditorwidget.cpp propertyeditorwidget.h + simplecolorpalette.cpp simplecolorpalette.h + simplecolorpalettemodel.cpp simplecolorpalettemodel.h + simplecolorpalettesingleton.cpp simplecolorpalettesingleton.h qmlanchorbindingproxy.cpp qmlanchorbindingproxy.h qmlmodelnodeproxy.cpp qmlmodelnodeproxy.h quick2propertyeditorview.cpp quick2propertyeditorview.h @@ -305,6 +320,7 @@ extend_qtc_plugin(QmlDesigner extend_qtc_plugin(QmlDesigner SOURCES_PREFIX components/texteditor SOURCES + texteditor.qrc texteditorstatusbar.cpp texteditorstatusbar.h texteditorview.cpp texteditorview.h texteditorwidget.cpp texteditorwidget.h diff --git a/src/plugins/qmldesigner/components/componentcore/layoutingridlayout.cpp b/src/plugins/qmldesigner/components/componentcore/layoutingridlayout.cpp index 5ec3ea557b3..ba520a1ca33 100644 --- a/src/plugins/qmldesigner/components/componentcore/layoutingridlayout.cpp +++ b/src/plugins/qmldesigner/components/componentcore/layoutingridlayout.cpp @@ -185,17 +185,16 @@ void LayoutInGridLayout::doIt() if (qmlItemNode.hasInstanceParentItem()) { ModelNode layoutNode; - { - RewriterTransaction transaction(m_selectionContext.view(), QByteArrayLiteral("LayoutInGridLayout1")); + + m_selectionContext.view()->executeInTransaction("LayoutInGridLayout1",[this, &layoutNode, layoutType](){ QTC_ASSERT(m_selectionContext.view()->model()->hasNodeMetaInfo(layoutType), return); NodeMetaInfo metaInfo = m_selectionContext.view()->model()->metaInfo(layoutType); layoutNode = m_selectionContext.view()->createModelNode(layoutType, metaInfo.majorVersion(), metaInfo.minorVersion()); reparentTo(layoutNode, m_parentNode); - } + }); - { - RewriterTransaction transaction(m_selectionContext.view(), QByteArrayLiteral("LayoutInGridLayout2")); + m_selectionContext.view()->executeInTransaction("LayoutInGridLayout2", [this, layoutNode](){ fillEmptyCells(); @@ -208,7 +207,7 @@ void LayoutInGridLayout::doIt() reparentToNodeAndRemovePositionForModelNodes(layoutNode, sortedSelectedNodes); setSizeAsPreferredSize(sortedSelectedNodes); setSpanning(layoutNode); - } + }); } } } diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index 691c1b6ca51..3c31998576b 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -240,9 +240,7 @@ void changeOrder(const SelectionContext &selectionState, OderAction orderAction) if (!modelNode.parentProperty().isNodeListProperty()) return; - try { - RewriterTransaction transaction(selectionState.view(), QByteArrayLiteral("DesignerActionManager|raise")); - + selectionState.view()->executeInTransaction("DesignerActionManager|raise",[orderAction, selectionState, modelNode](){ ModelNode modelNode = selectionState.currentSingleSelectedNode(); NodeListProperty parentProperty = modelNode.parentProperty().toNodeListProperty(); const int index = parentProperty.indexOf(modelNode); @@ -255,11 +253,7 @@ void changeOrder(const SelectionContext &selectionState, OderAction orderAction) if (index > 0) parentProperty.slide(index, index - 1); } - - transaction.commit(); - } catch (const RewritingException &e) { //better save then sorry - e.showException(); - } + }); } void raise(const SelectionContext &selectionState) @@ -328,16 +322,13 @@ void resetSize(const SelectionContext &selectionState) if (!selectionState.view()) return; - try { - RewriterTransaction transaction(selectionState.view(), QByteArrayLiteral("DesignerActionManager|resetSize")); + selectionState.view()->executeInTransaction("DesignerActionManager|resetSize",[selectionState](){ foreach (ModelNode node, selectionState.selectedModelNodes()) { QmlItemNode itemNode(node); itemNode.removeProperty("width"); itemNode.removeProperty("height"); } - } catch (const RewritingException &e) { //better save then sorry - e.showException(); - } + }); } void resetPosition(const SelectionContext &selectionState) @@ -345,17 +336,13 @@ void resetPosition(const SelectionContext &selectionState) if (!selectionState.view()) return; - try { - RewriterTransaction transaction(selectionState.view(), QByteArrayLiteral("DesignerActionManager|resetPosition")); + selectionState.view()->executeInTransaction("DesignerActionManager|resetPosition",[selectionState](){ foreach (ModelNode node, selectionState.selectedModelNodes()) { QmlItemNode itemNode(node); itemNode.removeProperty("x"); itemNode.removeProperty("y"); } - transaction.commit(); - } catch (const RewritingException &e) { //better save then sorry - e.showException(); - } + }); } void goIntoComponentOperation(const SelectionContext &selectionState) @@ -372,11 +359,12 @@ void resetZ(const SelectionContext &selectionState) if (!selectionState.view()) return; - RewriterTransaction transaction(selectionState.view(), QByteArrayLiteral("DesignerActionManager|resetZ")); - foreach (ModelNode node, selectionState.selectedModelNodes()) { - QmlItemNode itemNode(node); - itemNode.removeProperty("z"); - } + selectionState.view()->executeInTransaction("DesignerActionManager|resetZ",[selectionState](){ + foreach (ModelNode node, selectionState.selectedModelNodes()) { + QmlItemNode itemNode(node); + itemNode.removeProperty("z"); + } + }); } static inline void backupPropertyAndRemove(const ModelNode &node, const PropertyName &propertyName) @@ -404,9 +392,7 @@ void anchorsFill(const SelectionContext &selectionState) if (!selectionState.view()) return; - try { - RewriterTransaction transaction(selectionState.view(), QByteArrayLiteral("DesignerActionManager|anchorsFill")); - + selectionState.view()->executeInTransaction("DesignerActionManager|anchorsFill",[selectionState](){ ModelNode modelNode = selectionState.currentSingleSelectedNode(); QmlItemNode node = modelNode; @@ -417,11 +403,7 @@ void anchorsFill(const SelectionContext &selectionState) backupPropertyAndRemove(modelNode, "width"); backupPropertyAndRemove(modelNode, "height"); } - - transaction.commit(); - } catch (const RewritingException &e) { //better save then sorry - e.showException(); - } + }); } void anchorsReset(const SelectionContext &selectionState) @@ -429,19 +411,19 @@ void anchorsReset(const SelectionContext &selectionState) if (!selectionState.view()) return; - RewriterTransaction transaction(selectionState.view(), QByteArrayLiteral("DesignerActionManager|anchorsReset")); + selectionState.view()->executeInTransaction("DesignerActionManager|anchorsReset",[selectionState](){ + ModelNode modelNode = selectionState.currentSingleSelectedNode(); - ModelNode modelNode = selectionState.currentSingleSelectedNode(); - - QmlItemNode node = modelNode; - if (node.isValid()) { - node.anchors().removeAnchors(); - node.anchors().removeMargins(); - restoreProperty(node, "x"); - restoreProperty(node, "y"); - restoreProperty(node, "width"); - restoreProperty(node, "height"); - } + QmlItemNode node = modelNode; + if (node.isValid()) { + node.anchors().removeAnchors(); + node.anchors().removeMargins(); + restoreProperty(node, "x"); + restoreProperty(node, "y"); + restoreProperty(node, "width"); + restoreProperty(node, "height"); + } + }); } using LessThan = std::function; @@ -481,7 +463,7 @@ bool compareByGrid(const ModelNode &node1, const ModelNode &node2) static void layoutHelperFunction(const SelectionContext &selectionContext, const TypeName &layoutType, - LessThan lessThan) + const LessThan &lessThan) { if (!selectionContext.view() || !selectionContext.hasSingleSelectedModelNode() @@ -492,10 +474,8 @@ static void layoutHelperFunction(const SelectionContext &selectionContext, const QmlItemNode qmlItemNode = QmlItemNode(selectionContext.firstSelectedModelNode()); if (qmlItemNode.hasInstanceParentItem()) { - ModelNode layoutNode; - { - RewriterTransaction transaction(selectionContext.view(), QByteArrayLiteral("DesignerActionManager|layoutHelperFunction1")); + selectionContext.view()->executeInTransaction("DesignerActionManager|layoutHelperFunction1",[=, &layoutNode](){ QmlItemNode parentNode = qmlItemNode.instanceParentItem(); @@ -504,10 +484,9 @@ static void layoutHelperFunction(const SelectionContext &selectionContext, layoutNode = selectionContext.view()->createModelNode(layoutType, metaInfo.majorVersion(), metaInfo.minorVersion()); reparentTo(layoutNode, parentNode); - } + }); - { - RewriterTransaction transaction(selectionContext.view(), QByteArrayLiteral("DesignerActionManager|layoutHelperFunction2")); + selectionContext.view()->executeInTransaction("DesignerActionManager|layoutHelperFunction2",[=](){ QList sortedSelectedNodes = selectionContext.selectedModelNodes(); Utils::sort(sortedSelectedNodes, lessThan); @@ -516,7 +495,7 @@ static void layoutHelperFunction(const SelectionContext &selectionContext, LayoutInGridLayout::reparentToNodeAndRemovePositionForModelNodes(layoutNode, sortedSelectedNodes); if (layoutType.contains("Layout")) LayoutInGridLayout::setSizeAsPreferredSize(sortedSelectedNodes); - } + }); } } } @@ -662,16 +641,9 @@ void addSignalHandlerOrGotoImplementation(const SelectionContext &selectionState if (!qmlObjectNode.isRootModelNode()) { isModelNodeRoot = false; - try { - RewriterTransaction transaction = - qmlObjectNode.view()->beginRewriterTransaction(QByteArrayLiteral("NavigatorTreeModel:exportItem")); - - QmlObjectNode qmlObjectNode(modelNode); + qmlObjectNode.view()->executeInTransaction("NavigatorTreeModel:exportItem", [&qmlObjectNode](){ qmlObjectNode.ensureAliasExport(); - transaction.commit(); - } catch (RewritingException &exception) { //better safe than sorry! There always might be cases where we fail - exception.showException(); - } + }); } QString itemId = modelNode.id(); @@ -708,14 +680,10 @@ void addSignalHandlerOrGotoImplementation(const SelectionContext &selectionState if (dialog->signal().isEmpty()) return; - try { - RewriterTransaction transaction = - qmlObjectNode.view()->beginRewriterTransaction(QByteArrayLiteral("NavigatorTreeModel:exportItem")); + qmlObjectNode.view()->executeInTransaction("NavigatorTreeModel:exportItem", [=](){ addSignal(typeName, itemId, dialog->signal(), isModelNodeRoot); - } catch (RewritingException &exception) { //better safe than sorry! There always might be cases where we fail - exception.showException(); - } + }); addSignal(typeName, itemId, dialog->signal(), isModelNodeRoot); @@ -751,9 +719,7 @@ void removeLayout(const SelectionContext &selectionContext) if (!parent.isValid()) return; - { - RewriterTransaction transaction(selectionContext.view(), QByteArrayLiteral("DesignerActionManager|removeLayout")); - + selectionContext.view()->executeInTransaction("DesignerActionManager|removeLayout", [selectionContext, &layoutItem, parent](){ foreach (const ModelNode &modelNode, selectionContext.currentSingleSelectedNode().directSubModelNodes()) { if (QmlItemNode::isValidQmlItemNode(modelNode)) { @@ -772,7 +738,7 @@ void removeLayout(const SelectionContext &selectionContext) parent.modelNode().defaultNodeListProperty().reparentHere(modelNode); } layoutItem.destroy(); - } + }); } void removePositioner(const SelectionContext &selectionContext) @@ -826,9 +792,7 @@ void addItemToStackedContainer(const SelectionContext &selectionContext) } } - try { - RewriterTransaction transaction = - view->beginRewriterTransaction(QByteArrayLiteral("DesignerActionManager:addItemToStackedContainer")); + view->executeInTransaction("DesignerActionManager:addItemToStackedContainer", [=](){ NodeMetaInfo itemMetaInfo = view->model()->metaInfo("QtQuick.Item", -1, -1); QTC_ASSERT(itemMetaInfo.isValid(), return); @@ -853,11 +817,7 @@ void addItemToStackedContainer(const SelectionContext &selectionContext) } } - - transaction.commit(); - } catch (RewritingException &exception) { //better safe than sorry! There always might be cases where we fail - exception.showException(); - } + }); } PropertyName getIndexPropertyName(const ModelNode &modelNode) @@ -969,9 +929,8 @@ void addTabBarToStackedContainer(const SelectionContext &selectionContext) const PropertyName indexPropertyName = getIndexPropertyName(container); QTC_ASSERT(container.metaInfo().hasProperty(indexPropertyName), return); - try { - RewriterTransaction transaction = - view->beginRewriterTransaction(QByteArrayLiteral("DesignerActionManager:addItemToStackedContainer")); + view->executeInTransaction("DesignerActionManager:addItemToStackedContainer", + [view, container, containerItemNode, tabBarMetaInfo, tabButtonMetaInfo, indexPropertyName](){ ModelNode tabBarNode = view->createModelNode("QtQuick.Controls.TabBar", @@ -1003,11 +962,8 @@ void addTabBarToStackedContainer(const SelectionContext &selectionContext) container.removeProperty(indexPropertyName); const QString expression = id + "." + QString::fromLatin1(indexPropertyName); container.bindingProperty(indexPropertyName).setExpression(expression); + }); - transaction.commit(); - } catch (RewritingException &exception) { //better safe than sorry! There always might be cases where we fail - exception.showException(); - } } bool addImageToProject(const QStringList &fileNames, const QString &defaultDirectory) diff --git a/src/plugins/qmldesigner/components/integration/designdocument.cpp b/src/plugins/qmldesigner/components/integration/designdocument.cpp index a10225cc069..4f23154945d 100644 --- a/src/plugins/qmldesigner/components/integration/designdocument.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocument.cpp @@ -365,18 +365,13 @@ void DesignDocument::deleteSelected() if (!currentModel()) return; - try { - RewriterTransaction transaction(rewriterView(), QByteArrayLiteral("DesignDocument::deleteSelected")); + rewriterView()->executeInTransaction("DesignDocument::deleteSelected", [this](){ QList toDelete = view()->selectedModelNodes(); foreach (ModelNode node, toDelete) { if (node.isValid() && !node.isRootNode() && QmlObjectNode::isValidQmlObjectNode(node)) QmlObjectNode(node).destroy(); } - - transaction.commit(); - } catch (const RewritingException &e) { - e.showException(); - } + }); } void DesignDocument::copySelected() @@ -465,10 +460,8 @@ void DesignDocument::paste() } } - QList pastedNodeList; - - try { - RewriterTransaction transaction(rewriterView(), QByteArrayLiteral("DesignDocument::paste1")); + rewriterView()->executeInTransaction("DesignDocument::paste1", [this, &view, selectedNodes, targetNode](){ + QList pastedNodeList; int offset = double(qrand()) / RAND_MAX * 20 - 10; @@ -481,14 +474,10 @@ void DesignDocument::paste() } view.setSelectedModelNodes(pastedNodeList); - transaction.commit(); - } catch (const RewritingException &e) { - qWarning() << e.description(); //silent error - } - } else { - try { - RewriterTransaction transaction(rewriterView(), QByteArrayLiteral("DesignDocument::paste2")); + }); + } else { + rewriterView()->executeInTransaction("DesignDocument::paste1", [this, &view, selectedNodes, rootNode](){ currentModel()->attachView(&view); ModelNode pastedNode(view.insertModel(rootNode)); ModelNode targetNode; @@ -500,9 +489,9 @@ void DesignDocument::paste() targetNode = view.rootModelNode(); if (targetNode.hasParentProperty() && - (pastedNode.simplifiedTypeName() == targetNode.simplifiedTypeName()) && - (pastedNode.variantProperty("width").value() == targetNode.variantProperty("width").value()) && - (pastedNode.variantProperty("height").value() == targetNode.variantProperty("height").value())) + (pastedNode.simplifiedTypeName() == targetNode.simplifiedTypeName()) && + (pastedNode.variantProperty("width").value() == targetNode.variantProperty("width").value()) && + (pastedNode.variantProperty("height").value() == targetNode.variantProperty("height").value())) targetNode = targetNode.parentProperty().parentModelNode(); @@ -514,15 +503,9 @@ void DesignDocument::paste() } else { qWarning() << "Cannot reparent to" << targetNode; } - - transaction.commit(); - NodeMetaInfo::clearCache(); - view.setSelectedModelNodes({pastedNode}); - transaction.commit(); - } catch (const RewritingException &e) { - qWarning() << e.description(); //silent error - } + }); + NodeMetaInfo::clearCache(); } } diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index 126fed8e68f..4ceb51e985e 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -545,10 +545,9 @@ void NavigatorTreeModel::handleItemLibraryImageDrop(const QMimeData *mimeData, i void NavigatorTreeModel::moveNodesInteractive(NodeAbstractProperty &parentProperty, const QList &modelNodes, int targetIndex) { QTC_ASSERT(m_view, return); - try { - const TypeName propertyQmlType = parentProperty.parentModelNode().metaInfo().propertyTypeName(parentProperty.name()); - RewriterTransaction transaction = m_view->beginRewriterTransaction(QByteArrayLiteral("NavigatorTreeModel::moveNodesInteractive")); + m_view->executeInTransaction("NavigatorTreeModel::moveNodesInteractive",[this, &parentProperty, modelNodes, targetIndex](){ + const TypeName propertyQmlType = parentProperty.parentModelNode().metaInfo().propertyTypeName(parentProperty.name()); foreach (const ModelNode &modelNode, modelNodes) { if (modelNode.isValid() && modelNode != parentProperty.parentModelNode() @@ -565,10 +564,7 @@ void NavigatorTreeModel::moveNodesInteractive(NodeAbstractProperty &parentProper } } } - transaction.commit(); - } catch (const RewritingException &exception) { //better safe than sorry! There always might be cases where we fail - exception.showException(); - } + }); } Qt::DropActions NavigatorTreeModel::supportedDropActions() const diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp index 07434102fce..f43081f14b2 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp @@ -198,16 +198,10 @@ void NavigatorView::handleChangedExport(const ModelNode &modelNode, bool exporte if (rootNode.hasProperty(modelNodeId)) rootNode.removeProperty(modelNodeId); if (exported) { - try { - RewriterTransaction transaction = - beginRewriterTransaction(QByteArrayLiteral("NavigatorTreeModel:exportItem")); - + executeInTransaction("NavigatorTreeModel:exportItem", [this, modelNode](){ QmlObjectNode qmlObjectNode(modelNode); qmlObjectNode.ensureAliasExport(); - transaction.commit(); - } catch (RewritingException &exception) { //better safe than sorry! There always might be cases where we fail - exception.showException(); - } + }); } } diff --git a/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp b/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp index 471ec2abd4d..d4b1f471848 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include @@ -147,18 +147,16 @@ void GradientModel::addGradient() return; if (!m_itemNode.modelNode().hasNodeProperty(gradientPropertyName().toUtf8())) { - try { + if (m_gradientTypeName != "Gradient") + ensureShapesImport(); + + view()->executeInTransaction("GradientModel::addGradient", [this](){ QColor color = m_itemNode.instanceValue("color").value(); if (!color.isValid()) color = QColor(Qt::white); - if (m_gradientTypeName != "Gradient") - ensureShapesImport(); - - QmlDesigner::RewriterTransaction transaction = view()->beginRewriterTransaction(QByteArrayLiteral("GradientModel::addGradient")); - QmlDesigner::ModelNode gradientNode = createGradientNode(); m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).reparentHere(gradientNode); @@ -172,11 +170,7 @@ void GradientModel::addGradient() gradientStopNode.variantProperty("position").setValue(1.0); gradientStopNode.variantProperty("color").setValue(QColor(Qt::black)); gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode); - - } catch (const QmlDesigner::Exception &e) { - e.showException(); - } - + }); } setupModel(); @@ -244,18 +238,18 @@ qreal GradientModel::getPosition(int index) const void GradientModel::removeStop(int index) { if (index < rowCount() - 1 && index != 0) { - QmlDesigner::RewriterTransaction transaction = view()->beginRewriterTransaction(QByteArrayLiteral("GradientModel::removeStop")); - QmlDesigner::ModelNode gradientNode = m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).modelNode(); - QmlDesigner::QmlObjectNode stop = gradientNode.nodeListProperty("stops").at(index); - if (stop.isValid()) { - stop.destroy(); - setupModel(); - } + view()->executeInTransaction("GradientModel::removeStop", [this, index](){ + QmlDesigner::ModelNode gradientNode = m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).modelNode(); + QmlDesigner::QmlObjectNode stop = gradientNode.nodeListProperty("stops").at(index); + if (stop.isValid()) { + stop.destroy(); + setupModel(); + } + }); } qWarning() << Q_FUNC_INFO << "invalid index"; } - void GradientModel::deleteGradient() { if (!m_itemNode.isValid()) @@ -385,7 +379,11 @@ void GradientModel::ensureShapesImport() { if (!hasShapesImport()) { QmlDesigner::Import timelineImport = QmlDesigner::Import::createLibraryImport("QtQuick.Shapes", "1.0"); - model()->changeImports({timelineImport}, {}); + try { + model()->changeImports({timelineImport}, {}); + } catch (const QmlDesigner::Exception &) { + QTC_ASSERT(false, return); + } } } diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp index dc8243e1c81..8fdab5a821e 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp @@ -152,22 +152,14 @@ void PropertyEditorContextObject::toogleExportAlias() PropertyName modelNodeId = selectedNode.id().toUtf8(); ModelNode rootModelNode = rewriterView->rootModelNode(); - try { - RewriterTransaction transaction = - rewriterView->beginRewriterTransaction(QByteArrayLiteral("PropertyEditorContextObject:toogleExportAlias")); - + rewriterView->executeInTransaction("PropertyEditorContextObject:toogleExportAlias", [&objectNode, &rootModelNode, modelNodeId](){ if (!objectNode.isAliasExported()) objectNode.ensureAliasExport(); else if (rootModelNode.hasProperty(modelNodeId)) rootModelNode.removeProperty(modelNodeId); - - transaction.commit(); - } catch (RewritingException &exception) { //better safe than sorry! There always might be cases where we fail - exception.showException(); - } + }); } - } void PropertyEditorContextObject::changeTypeName(const QString &typeName) @@ -181,11 +173,8 @@ void PropertyEditorContextObject::changeTypeName(const QString &typeName) QTC_ASSERT(!rewriterView->selectedModelNodes().isEmpty(), return); - ModelNode selectedNode = rewriterView->selectedModelNodes().constFirst(); - - try { - RewriterTransaction transaction = - rewriterView->beginRewriterTransaction(QByteArrayLiteral("PropertyEditorContextObject:changeTypeName")); + rewriterView->executeInTransaction("PropertyEditorContextObject:changeTypeName", [this, rewriterView, typeName](){ + ModelNode selectedNode = rewriterView->selectedModelNodes().constFirst(); NodeMetaInfo metaInfo = m_model->metaInfo(typeName.toLatin1()); if (!metaInfo.isValid()) { @@ -193,16 +182,10 @@ void PropertyEditorContextObject::changeTypeName(const QString &typeName) return; } if (selectedNode.isRootNode()) - rewriterView->changeRootNodeType(metaInfo.typeName(), metaInfo.majorVersion(), metaInfo.minorVersion()); + rewriterView->changeRootNodeType(metaInfo.typeName(), metaInfo.majorVersion(), metaInfo.minorVersion()); else selectedNode.changeType(metaInfo.typeName(), metaInfo.majorVersion(), metaInfo.minorVersion()); - - transaction.commit(); - } catch (RewritingException &exception) { //better safe than sorry! There always might be cases where we fail - exception.showException(); - } - - + }); } void PropertyEditorContextObject::insertKeyframe(const QString &propertyName) diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp index 40c5cfda6e9..39baecbaadd 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp @@ -481,7 +481,9 @@ static NodeMetaInfo findCommonSuperClass(const NodeMetaInfo &first, const NodeMe NodeMetaInfo PropertyEditorQmlBackend::findCommonAncestor(const ModelNode &node) { - QTC_ASSERT(node.isValid(), return {}); + if (!node.isValid()) + return {}; + QTC_ASSERT(node.metaInfo().isValid(), return {}); AbstractView *view = node.view(); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp index d0c98c896ff..9dd0a2da24b 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp @@ -235,9 +235,7 @@ void PropertyEditorView::changeExpression(const QString &propertyName) if (!m_selectedNode.isValid()) return; - RewriterTransaction transaction = beginRewriterTransaction(QByteArrayLiteral("PropertyEditorView::changeExpression")); - - try { + executeInTransaction("PropertyEditorView::changeExpression", [this, name](){ PropertyName underscoreName(name); underscoreName.replace('.', '_'); @@ -253,7 +251,6 @@ void PropertyEditorView::changeExpression(const QString &propertyName) if (qmlObjectNode.modelNode().metaInfo().propertyTypeName(name) == "QColor") { if (QColor(value->expression().remove('"')).isValid()) { qmlObjectNode.setVariantProperty(name, QColor(value->expression().remove('"'))); - transaction.commit(); //committing in the try block return; } } else if (qmlObjectNode.modelNode().metaInfo().propertyTypeName(name) == "bool") { @@ -263,7 +260,6 @@ void PropertyEditorView::changeExpression(const QString &propertyName) qmlObjectNode.setVariantProperty(name, true); else qmlObjectNode.setVariantProperty(name, false); - transaction.commit(); //committing in the try block return; } } else if (qmlObjectNode.modelNode().metaInfo().propertyTypeName(name) == "int") { @@ -271,7 +267,6 @@ void PropertyEditorView::changeExpression(const QString &propertyName) int intValue = value->expression().toInt(&ok); if (ok) { qmlObjectNode.setVariantProperty(name, intValue); - transaction.commit(); //committing in the try block return; } } else if (qmlObjectNode.modelNode().metaInfo().propertyTypeName(name) == "qreal") { @@ -279,7 +274,6 @@ void PropertyEditorView::changeExpression(const QString &propertyName) qreal realValue = value->expression().toDouble(&ok); if (ok) { qmlObjectNode.setVariantProperty(name, realValue); - transaction.commit(); //committing in the try block return; } } @@ -291,12 +285,7 @@ void PropertyEditorView::changeExpression(const QString &propertyName) if (qmlObjectNode.expression(name) != value->expression() || !qmlObjectNode.propertyAffectedByCurrentState(name)) qmlObjectNode.setBindingProperty(name, value->expression()); - transaction.commit(); //committing in the try block - } - - catch (const RewritingException &e) { - e.showException(); - } + }); /* end of transaction */ } void PropertyEditorView::exportPopertyAsAlias(const QString &name) @@ -310,9 +299,7 @@ void PropertyEditorView::exportPopertyAsAlias(const QString &name) if (!m_selectedNode.isValid()) return; - RewriterTransaction transaction = beginRewriterTransaction(QByteArrayLiteral("PropertyEditorView::exportPopertyAsAlias")); - - try { + executeInTransaction("PropertyEditorView::exportPopertyAsAlias", [this, name](){ const QString id = m_selectedNode.validId(); QString upperCasePropertyName = name; upperCasePropertyName.replace(0, 1, upperCasePropertyName.at(0).toUpper()); @@ -326,11 +313,7 @@ void PropertyEditorView::exportPopertyAsAlias(const QString &name) return; } rootModelNode().bindingProperty(propertyName).setDynamicTypeNameAndExpression("alias", id + "." + name); - - transaction.commit(); //committing in the try block - } catch (const RewritingException &e) { - e.showException(); - } + }); } void PropertyEditorView::removeAliasExport(const QString &name) @@ -344,9 +327,7 @@ void PropertyEditorView::removeAliasExport(const QString &name) if (!m_selectedNode.isValid()) return; - RewriterTransaction transaction = beginRewriterTransaction(QByteArrayLiteral("PropertyEditorView::exportPopertyAsAlias")); - - try { + executeInTransaction("PropertyEditorView::exportPopertyAsAlias", [this, name](){ const QString id = m_selectedNode.validId(); for (const BindingProperty &property : rootModelNode().bindingProperties()) @@ -354,10 +335,7 @@ void PropertyEditorView::removeAliasExport(const QString &name) rootModelNode().removeProperty(property.name()); break; } - transaction.commit(); //committing in the try block - } catch (const RewritingException &e) { - e.showException(); - } + }); } bool PropertyEditorView::locked() const @@ -575,10 +553,11 @@ void PropertyEditorView::modelAttached(Model *model) m_locked = true; if (!m_setupCompleted) { - m_singleShotTimer->setSingleShot(true); - m_singleShotTimer->setInterval(100); - connect(m_singleShotTimer, &QTimer::timeout, this, &PropertyEditorView::setupPanes); - m_singleShotTimer->start(); + QTimer::singleShot(50, this, [this]{ + PropertyEditorView::setupPanes(); + /* workaround for QTBUG-75847 */ + reloadQml(); + }); } m_locked = false; @@ -681,6 +660,9 @@ void PropertyEditorView::instanceInformationsChanged(const QMultiHash informationNameList = informationChangedHash.values(m_selectedNode); if (informationNameList.contains(Anchor) diff --git a/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.cpp b/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.cpp index bc6b4376b66..7a38f74f34e 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.cpp @@ -292,9 +292,9 @@ void QmlAnchorBindingProxy::setDefaultRelativeRightTarget() } } -RewriterTransaction QmlAnchorBindingProxy::beginRewriterTransaction(const QByteArray &identifier) +bool QmlAnchorBindingProxy::executeInTransaction(const QByteArray &identifier, const AbstractView::OperationBlock &lambda) { - return m_qmlItemNode.modelNode().view()->beginRewriterTransaction(identifier); + return m_qmlItemNode.modelNode().view()->executeInTransaction(identifier, lambda); } bool QmlAnchorBindingProxy::hasParent() const @@ -361,20 +361,11 @@ void QmlAnchorBindingProxy::setTopTarget(const QString &target) if (!newTarget.isValid()) return; - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::setTopTarget")); - + executeInTransaction("QmlAnchorBindingProxy::setTopTarget", [this, newTarget](){ m_topTarget = newTarget; - setDefaultRelativeTopTarget(); - anchorTop(); - - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); emit topTargetChanged(); } @@ -393,18 +384,12 @@ void QmlAnchorBindingProxy::setBottomTarget(const QString &target) if (!newTarget.isValid()) return; - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::setBottomTarget")); - + executeInTransaction("QmlAnchorBindingProxy::setBottomTarget", [this, newTarget](){ m_bottomTarget = newTarget; setDefaultRelativeBottomTarget(); anchorBottom(); - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); emit bottomTargetChanged(); } @@ -422,18 +407,11 @@ void QmlAnchorBindingProxy::setLeftTarget(const QString &target) if (!newTarget.isValid()) return; - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::setLeftTarget")); - + executeInTransaction("QmlAnchorBindingProxy::setLeftTarget", [this, newTarget](){ m_leftTarget = newTarget; setDefaultRelativeLeftTarget(); anchorLeft(); - - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); emit leftTargetChanged(); } @@ -451,18 +429,11 @@ void QmlAnchorBindingProxy::setRightTarget(const QString &target) if (!newTarget.isValid()) return; - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::setRightTarget")); - + executeInTransaction("QmlAnchorBindingProxy::setRightTarget", [this, newTarget](){ m_rightTarget = newTarget; setDefaultRelativeRightTarget(); anchorRight(); - - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); emit rightTargetChanged(); } @@ -480,17 +451,10 @@ void QmlAnchorBindingProxy::setVerticalTarget(const QString &target) if (!newTarget.isValid()) return; - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::setVerticalTarget")); - + executeInTransaction("QmlAnchorBindingProxy::setVerticalTarget", [this, newTarget](){ m_verticalTarget = newTarget; anchorVertical(); - - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); emit verticalTargetChanged(); } @@ -508,17 +472,10 @@ void QmlAnchorBindingProxy::setHorizontalTarget(const QString &target) if (!newTarget.isValid()) return; - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::setHorizontalTarget")); - + executeInTransaction("QmlAnchorBindingProxy::setHorizontalTarget", [this, newTarget](){ m_horizontalTarget = newTarget; - anchorHorizontal();\ - - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + anchorHorizontal(); + }); emit horizontalTargetChanged(); } @@ -531,18 +488,10 @@ void QmlAnchorBindingProxy::setRelativeAnchorTargetTop(QmlAnchorBindingProxy::Re if (target == m_relativeTopTarget) return; - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::setRelativeAnchorTargetTop")); - + executeInTransaction("QmlAnchorBindingProxy::setRelativeAnchorTargetTop", [this, target](){ m_relativeTopTarget = target; - anchorTop(); - - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); emit relativeAnchorTargetTopChanged(); } @@ -555,19 +504,10 @@ void QmlAnchorBindingProxy::setRelativeAnchorTargetBottom(QmlAnchorBindingProxy: if (target == m_relativeBottomTarget) return; - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::setRelativeAnchorTargetBottom")); - + executeInTransaction("QmlAnchorBindingProxy::setRelativeAnchorTargetBottom", [this, target](){ m_relativeBottomTarget = target; - - anchorBottom(); - - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); emit relativeAnchorTargetBottomChanged(); } @@ -580,18 +520,11 @@ void QmlAnchorBindingProxy::setRelativeAnchorTargetLeft(QmlAnchorBindingProxy::R if (target == m_relativeLeftTarget) return; - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::setRelativeAnchorTargetLeft")); - + executeInTransaction("QmlAnchorBindingProxy::setRelativeAnchorTargetLeft", [this, target](){ m_relativeLeftTarget = target; - anchorLeft(); - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); emit relativeAnchorTargetLeftChanged(); } @@ -604,18 +537,10 @@ void QmlAnchorBindingProxy::setRelativeAnchorTargetRight(QmlAnchorBindingProxy:: if (target == m_relativeRightTarget) return; - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::setRelativeAnchorTargetRight")); - + executeInTransaction("QmlAnchorBindingProxy::setRelativeAnchorTargetRight", [this, target](){ m_relativeRightTarget = target; - anchorRight(); - - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); emit relativeAnchorTargetRightChanged(); @@ -629,18 +554,11 @@ void QmlAnchorBindingProxy::setRelativeAnchorTargetVertical(QmlAnchorBindingProx if (target == m_relativeVerticalTarget) return; - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::setRelativeAnchorTargetVertical")); + executeInTransaction("QmlAnchorBindingProxy::setRelativeAnchorTargetVertical", [this, target](){ m_relativeVerticalTarget = target; - anchorVertical(); - - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); emit relativeAnchorTargetVerticalChanged(); } @@ -653,18 +571,10 @@ void QmlAnchorBindingProxy::setRelativeAnchorTargetHorizontal(QmlAnchorBindingPr if (target == m_relativeHorizontalTarget) return; - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::setRelativeAnchorTargetHorizontal")); - + executeInTransaction("QmlAnchorBindingProxy::setRelativeAnchorTargetHorizontal", [this, target](){ m_relativeHorizontalTarget = target; - anchorHorizontal(); - - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); emit relativeAnchorTargetHorizontalChanged(); } @@ -709,12 +619,10 @@ int QmlAnchorBindingProxy::indexOfPossibleTargetItem(const QString &targetName) return possibleTargetItems().indexOf(targetName); } -void QmlAnchorBindingProxy::resetLayout() { - - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::resetLayout")); +void QmlAnchorBindingProxy::resetLayout() +{ + executeInTransaction("QmlAnchorBindingProxy::resetLayout", [this](){ m_qmlItemNode.anchors().removeAnchors(); m_qmlItemNode.anchors().removeMargins(); @@ -722,11 +630,7 @@ void QmlAnchorBindingProxy::resetLayout() { restoreProperty(modelNode(), "y"); restoreProperty(modelNode(), "width"); restoreProperty(modelNode(), "height"); - - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); emit topAnchorChanged(); emit bottomAnchorChanged(); @@ -743,10 +647,7 @@ void QmlAnchorBindingProxy::setBottomAnchor(bool anchor) if (bottomAnchored() == anchor) return; - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::setBottomAnchor")); - + executeInTransaction("QmlAnchorBindingProxy::setBottomAnchor", [this, anchor](){ if (!anchor) { removeBottomAnchor(); } else { @@ -756,10 +657,7 @@ void QmlAnchorBindingProxy::setBottomAnchor(bool anchor) backupPropertyAndRemove(modelNode(), "height"); } - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); emit relativeAnchorTargetBottomChanged(); emit bottomAnchorChanged(); @@ -776,10 +674,8 @@ void QmlAnchorBindingProxy::setLeftAnchor(bool anchor) if (leftAnchored() == anchor) return; - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::setLeftAnchor")); + executeInTransaction("QmlAnchorBindingProxy::setLeftAnchor", [this, anchor](){ if (!anchor) { removeLeftAnchor(); } else { @@ -791,10 +687,7 @@ void QmlAnchorBindingProxy::setLeftAnchor(bool anchor) backupPropertyAndRemove(modelNode(), "width"); } - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); emit relativeAnchorTargetLeftChanged(); emit leftAnchorChanged(); @@ -810,10 +703,7 @@ void QmlAnchorBindingProxy::setRightAnchor(bool anchor) if (rightAnchored() == anchor) return; - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::setRightAnchor")); - + executeInTransaction("QmlAnchorBindingProxy::setRightAnchor", [this, anchor](){ if (!anchor) { removeRightAnchor(); } else { @@ -824,10 +714,7 @@ void QmlAnchorBindingProxy::setRightAnchor(bool anchor) backupPropertyAndRemove(modelNode(), "width"); } - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); emit relativeAnchorTargetRightChanged(); emit rightAnchorChanged(); @@ -1026,10 +913,7 @@ void QmlAnchorBindingProxy::setTopAnchor(bool anchor) if (topAnchored() == anchor) return; - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::setTopAnchor")); - + executeInTransaction("QmlAnchorBindingProxy::setTopAnchor", [this, anchor](){ if (!anchor) { removeTopAnchor(); } else { @@ -1040,10 +924,7 @@ void QmlAnchorBindingProxy::setTopAnchor(bool anchor) if (bottomAnchored()) backupPropertyAndRemove(modelNode(), "height"); } - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); emit relativeAnchorTargetTopChanged(); emit topAnchorChanged(); @@ -1052,70 +933,44 @@ void QmlAnchorBindingProxy::setTopAnchor(bool anchor) } void QmlAnchorBindingProxy::removeTopAnchor() { - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::removeTopAnchor")); - + executeInTransaction("QmlAnchorBindingProxy::removeTopAnchor", [this](){ m_qmlItemNode.anchors().removeAnchor(AnchorLineTop); m_qmlItemNode.anchors().removeMargin(AnchorLineTop); restoreProperty(modelNode(), "y"); restoreProperty(modelNode(), "height"); - - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); } -void QmlAnchorBindingProxy::removeBottomAnchor() { - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::removeBottomAnchor")); - +void QmlAnchorBindingProxy::removeBottomAnchor() +{ + executeInTransaction("QmlAnchorBindingProxy::removeBottomAnchor", [this](){ m_qmlItemNode.anchors().removeAnchor(AnchorLineBottom); m_qmlItemNode.anchors().removeMargin(AnchorLineBottom); - restoreProperty(modelNode(), "height"); - - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); } -void QmlAnchorBindingProxy::removeLeftAnchor() { - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::removeLeftAnchor")); - +void QmlAnchorBindingProxy::removeLeftAnchor() +{ + executeInTransaction("QmlAnchorBindingProxy::removeLeftAnchor", [this](){ m_qmlItemNode.anchors().removeAnchor(AnchorLineLeft); m_qmlItemNode.anchors().removeMargin(AnchorLineLeft); restoreProperty(modelNode(), "x"); restoreProperty(modelNode(), "width"); - - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); } -void QmlAnchorBindingProxy::removeRightAnchor() { - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::removeRightAnchor")); - +void QmlAnchorBindingProxy::removeRightAnchor() +{ + executeInTransaction("QmlAnchorBindingProxy::removeRightAnchor", [this](){ m_qmlItemNode.anchors().removeAnchor(AnchorLineRight); m_qmlItemNode.anchors().removeMargin(AnchorLineRight); restoreProperty(modelNode(), "width"); - - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); } void QmlAnchorBindingProxy::setVerticalCentered(bool centered) @@ -1128,10 +983,7 @@ void QmlAnchorBindingProxy::setVerticalCentered(bool centered) m_locked = true; - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::setVerticalCentered")); - + executeInTransaction("QmlAnchorBindingProxy::setVerticalCentered", [this, centered](){ if (!centered) { m_qmlItemNode.anchors().removeAnchor(AnchorLineVerticalCenter); m_qmlItemNode.anchors().removeMargin(AnchorLineVerticalCenter); @@ -1141,10 +993,7 @@ void QmlAnchorBindingProxy::setVerticalCentered(bool centered) anchorVertical(); } - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); m_locked = false; emit relativeAnchorTargetVerticalChanged(); @@ -1161,10 +1010,7 @@ void QmlAnchorBindingProxy::setHorizontalCentered(bool centered) m_locked = true; - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::setHorizontalCentered")); - + executeInTransaction("QmlAnchorBindingProxy::setHorizontalCentered", [this, centered](){ if (!centered) { m_qmlItemNode.anchors().removeAnchor(AnchorLineHorizontalCenter); m_qmlItemNode.anchors().removeMargin(AnchorLineHorizontalCenter); @@ -1173,11 +1019,7 @@ void QmlAnchorBindingProxy::setHorizontalCentered(bool centered) anchorHorizontal(); } - - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); m_locked = false; emit relativeAnchorTargetHorizontalChanged(); @@ -1256,12 +1098,7 @@ bool QmlAnchorBindingProxy::horizontalCentered() void QmlAnchorBindingProxy::fill() { - - try { - RewriterTransaction transaction = beginRewriterTransaction( - QByteArrayLiteral("QmlAnchorBindingProxy::fill")); - - + executeInTransaction("QmlAnchorBindingProxy::fill", [this](){ backupPropertyAndRemove(modelNode(), "x"); backupPropertyAndRemove(modelNode(), "y"); backupPropertyAndRemove(modelNode(), "width"); @@ -1277,10 +1114,7 @@ void QmlAnchorBindingProxy::fill() m_qmlItemNode.anchors().removeMargin(AnchorLineTop); m_qmlItemNode.anchors().removeMargin(AnchorLineBottom); - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); emit topAnchorChanged(); emit bottomAnchorChanged(); diff --git a/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.h b/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.h index cf42ea055ac..0bd562add20 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.h +++ b/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.h @@ -210,7 +210,7 @@ private: void setDefaultRelativeLeftTarget(); void setDefaultRelativeRightTarget(); - RewriterTransaction beginRewriterTransaction(const QByteArray &identifier); + bool executeInTransaction(const QByteArray &identifier, const AbstractView::OperationBlock &lambda); QmlItemNode targetIdToNode(const QString &id) const; QString idForNode(const QmlItemNode &qmlItemNode) const; diff --git a/src/plugins/qmldesigner/designercore/include/abstractview.h b/src/plugins/qmldesigner/designercore/include/abstractview.h index d32a403e5c1..dcbeb5ee74d 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/designercore/include/abstractview.h @@ -39,6 +39,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE class QStyle; class QToolButton; @@ -263,6 +265,9 @@ public: void activateTimelineRecording(const ModelNode &timeline); void deactivateTimelineRecording(); + using OperationBlock = std::function; + bool executeInTransaction(const QByteArray &identifier, const OperationBlock &lambda); + protected: void setModel(Model * model); void removeModel(); diff --git a/src/plugins/qmldesigner/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/designercore/model/abstractview.cpp index 4e3596001c2..eb7ed16b9ab 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractview.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractview.cpp @@ -616,6 +616,20 @@ void AbstractView::deactivateTimelineRecording() model()->d->notifyCurrentTimelineChanged(ModelNode()); } +bool AbstractView::executeInTransaction(const QByteArray &identifier, const AbstractView::OperationBlock &lambda) +{ + try { + RewriterTransaction transaction = beginRewriterTransaction(identifier); + lambda(); + transaction.commit(); + } catch (const Exception &e) { + e.showException(); + return false; + } + + return true; +} + QList AbstractView::allModelNodes() const { return toModelNodeList(model()->d->allNodes()); diff --git a/src/plugins/qmldesigner/designercore/model/modelmerger.cpp b/src/plugins/qmldesigner/designercore/model/modelmerger.cpp index 161cf1f9f52..8517f9cb827 100644 --- a/src/plugins/qmldesigner/designercore/model/modelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelmerger.cpp @@ -178,29 +178,23 @@ void ModelMerger::replaceModel(const ModelNode &modelNode) view()->model()->changeImports(modelNode.model()->imports(), {}); view()->model()->setFileUrl(modelNode.model()->fileUrl()); - try { - RewriterTransaction transaction(view()->beginRewriterTransaction(QByteArrayLiteral("ModelMerger::replaceModel"))); + view()->executeInTransaction("ModelMerger::replaceModel", [this, modelNode](){ + ModelNode rootNode(view()->rootModelNode()); - ModelNode rootNode(view()->rootModelNode()); + foreach (const PropertyName &propertyName, rootNode.propertyNames()) + rootNode.removeProperty(propertyName); - foreach (const PropertyName &propertyName, rootNode.propertyNames()) - rootNode.removeProperty(propertyName); + QHash idRenamingHash; + setupIdRenamingHash(modelNode, idRenamingHash, view()); - QHash idRenamingHash; - setupIdRenamingHash(modelNode, idRenamingHash, view()); - - syncAuxiliaryProperties(rootNode, modelNode); - syncVariantProperties(rootNode, modelNode); - syncBindingProperties(rootNode, modelNode, idRenamingHash); - syncId(rootNode, modelNode, idRenamingHash); - syncNodeProperties(rootNode, modelNode, idRenamingHash, view()); - syncNodeListProperties(rootNode, modelNode, idRenamingHash, view()); - m_view->changeRootNodeType(modelNode.type(), modelNode.majorVersion(), modelNode.minorVersion()); - - transaction.commit(); - } catch (const RewritingException &e) { - qWarning() << e.description(); //silent error - } + syncAuxiliaryProperties(rootNode, modelNode); + syncVariantProperties(rootNode, modelNode); + syncBindingProperties(rootNode, modelNode, idRenamingHash); + syncId(rootNode, modelNode, idRenamingHash); + syncNodeProperties(rootNode, modelNode, idRenamingHash, view()); + syncNodeListProperties(rootNode, modelNode, idRenamingHash, view()); + m_view->changeRootNodeType(modelNode.type(), modelNode.majorVersion(), modelNode.minorVersion()); + }); } } //namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/qmlanchors.cpp b/src/plugins/qmldesigner/designercore/model/qmlanchors.cpp index 7b83330a32a..ba821dd788b 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlanchors.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlanchors.cpp @@ -161,22 +161,23 @@ void QmlAnchors::setAnchor(AnchorLineType sourceAnchorLine, const QmlItemNode &targetQmlItemNode, AnchorLineType targetAnchorLine) { - RewriterTransaction transaction = qmlItemNode().view()->beginRewriterTransaction(QByteArrayLiteral("QmlAnchors::setAnchor")); - if (qmlItemNode().isInBaseState()) { - if ((qmlItemNode().nodeInstance().hasAnchor("anchors.fill") && (sourceAnchorLine & AnchorLineFill)) - || ((qmlItemNode().nodeInstance().hasAnchor("anchors.centerIn") && (sourceAnchorLine & AnchorLineCenter)))) { - removeAnchor(sourceAnchorLine); - } + qmlItemNode().view()->executeInTransaction("QmlAnchors::setAnchor", [this, sourceAnchorLine, targetQmlItemNode, targetAnchorLine](){ + if (qmlItemNode().isInBaseState()) { + if ((qmlItemNode().nodeInstance().hasAnchor("anchors.fill") && (sourceAnchorLine & AnchorLineFill)) + || ((qmlItemNode().nodeInstance().hasAnchor("anchors.centerIn") && (sourceAnchorLine & AnchorLineCenter)))) { + removeAnchor(sourceAnchorLine); + } - const PropertyName propertyName = anchorPropertyName(sourceAnchorLine); - ModelNode targetModelNode = targetQmlItemNode.modelNode(); - QString targetExpression = targetModelNode.validId(); - if (targetQmlItemNode.modelNode() == qmlItemNode().modelNode().parentProperty().parentModelNode()) - targetExpression = QLatin1String("parent"); - if (sourceAnchorLine != AnchorLineCenter && sourceAnchorLine != AnchorLineFill) - targetExpression = targetExpression + QLatin1Char('.') + QString::fromLatin1(lineTypeToString(targetAnchorLine)); - qmlItemNode().modelNode().bindingProperty(propertyName).setExpression(targetExpression); - } + const PropertyName propertyName = anchorPropertyName(sourceAnchorLine); + ModelNode targetModelNode = targetQmlItemNode.modelNode(); + QString targetExpression = targetModelNode.validId(); + if (targetQmlItemNode.modelNode() == qmlItemNode().modelNode().parentProperty().parentModelNode()) + targetExpression = QLatin1String("parent"); + if (sourceAnchorLine != AnchorLineCenter && sourceAnchorLine != AnchorLineFill) + targetExpression = targetExpression + QLatin1Char('.') + QString::fromLatin1(lineTypeToString(targetAnchorLine)); + qmlItemNode().modelNode().bindingProperty(propertyName).setExpression(targetExpression); + } + }); } bool detectHorizontalCycle(const ModelNode &node, QList knownNodeList) @@ -315,47 +316,49 @@ AnchorLine QmlAnchors::instanceAnchor(AnchorLineType sourceAnchorLine) const void QmlAnchors::removeAnchor(AnchorLineType sourceAnchorLine) { - RewriterTransaction transaction = qmlItemNode().view()->beginRewriterTransaction(QByteArrayLiteral("QmlAnchors::removeAnchor")); - if (qmlItemNode().isInBaseState()) { - const PropertyName propertyName = anchorPropertyName(sourceAnchorLine); - if (qmlItemNode().nodeInstance().hasAnchor("anchors.fill") && (sourceAnchorLine & AnchorLineFill)) { - qmlItemNode().modelNode().removeProperty("anchors.fill"); - qmlItemNode().modelNode().bindingProperty("anchors.top").setExpression(QLatin1String("parent.top")); - qmlItemNode().modelNode().bindingProperty("anchors.left").setExpression(QLatin1String("parent.left")); - qmlItemNode().modelNode().bindingProperty("anchors.bottom").setExpression(QLatin1String("parent.bottom")); - qmlItemNode().modelNode().bindingProperty("anchors.right").setExpression(QLatin1String("parent.right")); + qmlItemNode().view()->executeInTransaction("QmlAnchors::removeAnchor", [this, sourceAnchorLine](){ + if (qmlItemNode().isInBaseState()) { + const PropertyName propertyName = anchorPropertyName(sourceAnchorLine); + if (qmlItemNode().nodeInstance().hasAnchor("anchors.fill") && (sourceAnchorLine & AnchorLineFill)) { + qmlItemNode().modelNode().removeProperty("anchors.fill"); + qmlItemNode().modelNode().bindingProperty("anchors.top").setExpression(QLatin1String("parent.top")); + qmlItemNode().modelNode().bindingProperty("anchors.left").setExpression(QLatin1String("parent.left")); + qmlItemNode().modelNode().bindingProperty("anchors.bottom").setExpression(QLatin1String("parent.bottom")); + qmlItemNode().modelNode().bindingProperty("anchors.right").setExpression(QLatin1String("parent.right")); - } else if (qmlItemNode().nodeInstance().hasAnchor("anchors.centerIn") && (sourceAnchorLine & AnchorLineCenter)) { - qmlItemNode().modelNode().removeProperty("anchors.centerIn"); - qmlItemNode().modelNode().bindingProperty("anchors.horizontalCenter").setExpression(QLatin1String("parent.horizontalCenter")); - qmlItemNode().modelNode().bindingProperty("anchors.verticalCenter").setExpression(QLatin1String("parent.verticalCenter")); + } else if (qmlItemNode().nodeInstance().hasAnchor("anchors.centerIn") && (sourceAnchorLine & AnchorLineCenter)) { + qmlItemNode().modelNode().removeProperty("anchors.centerIn"); + qmlItemNode().modelNode().bindingProperty("anchors.horizontalCenter").setExpression(QLatin1String("parent.horizontalCenter")); + qmlItemNode().modelNode().bindingProperty("anchors.verticalCenter").setExpression(QLatin1String("parent.verticalCenter")); + } + + qmlItemNode().modelNode().removeProperty(propertyName); } - - qmlItemNode().modelNode().removeProperty(propertyName); - } + }); } void QmlAnchors::removeAnchors() { - RewriterTransaction transaction = qmlItemNode().view()->beginRewriterTransaction(QByteArrayLiteral("QmlAnchors::removeAnchors")); - if (qmlItemNode().nodeInstance().hasAnchor("anchors.fill")) - qmlItemNode().modelNode().removeProperty("anchors.fill"); - if (qmlItemNode().nodeInstance().hasAnchor("anchors.centerIn")) - qmlItemNode().modelNode().removeProperty("anchors.centerIn"); - if (qmlItemNode().nodeInstance().hasAnchor("anchors.top")) - qmlItemNode().modelNode().removeProperty("anchors.top"); - if (qmlItemNode().nodeInstance().hasAnchor("anchors.left")) - qmlItemNode().modelNode().removeProperty("anchors.left"); - if (qmlItemNode().nodeInstance().hasAnchor("anchors.right")) - qmlItemNode().modelNode().removeProperty("anchors.right"); - if (qmlItemNode().nodeInstance().hasAnchor("anchors.bottom")) - qmlItemNode().modelNode().removeProperty("anchors.bottom"); - if (qmlItemNode().nodeInstance().hasAnchor("anchors.horizontalCenter")) - qmlItemNode().modelNode().removeProperty("anchors.horizontalCenter"); - if (qmlItemNode().nodeInstance().hasAnchor("anchors.verticalCenter")) - qmlItemNode().modelNode().removeProperty("anchors.verticalCenter"); - if (qmlItemNode().nodeInstance().hasAnchor("anchors.baseline")) - qmlItemNode().modelNode().removeProperty("anchors.baseline"); + qmlItemNode().view()->executeInTransaction("QmlAnchors::removeAnchors", [this](){ + if (qmlItemNode().nodeInstance().hasAnchor("anchors.fill")) + qmlItemNode().modelNode().removeProperty("anchors.fill"); + if (qmlItemNode().nodeInstance().hasAnchor("anchors.centerIn")) + qmlItemNode().modelNode().removeProperty("anchors.centerIn"); + if (qmlItemNode().nodeInstance().hasAnchor("anchors.top")) + qmlItemNode().modelNode().removeProperty("anchors.top"); + if (qmlItemNode().nodeInstance().hasAnchor("anchors.left")) + qmlItemNode().modelNode().removeProperty("anchors.left"); + if (qmlItemNode().nodeInstance().hasAnchor("anchors.right")) + qmlItemNode().modelNode().removeProperty("anchors.right"); + if (qmlItemNode().nodeInstance().hasAnchor("anchors.bottom")) + qmlItemNode().modelNode().removeProperty("anchors.bottom"); + if (qmlItemNode().nodeInstance().hasAnchor("anchors.horizontalCenter")) + qmlItemNode().modelNode().removeProperty("anchors.horizontalCenter"); + if (qmlItemNode().nodeInstance().hasAnchor("anchors.verticalCenter")) + qmlItemNode().modelNode().removeProperty("anchors.verticalCenter"); + if (qmlItemNode().nodeInstance().hasAnchor("anchors.baseline")) + qmlItemNode().modelNode().removeProperty("anchors.baseline"); + }); } bool QmlAnchors::instanceHasAnchor(AnchorLineType sourceAnchorLine) const @@ -532,13 +535,14 @@ void QmlAnchors::removeMargin(AnchorLineType sourceAnchorLineType) void QmlAnchors::removeMargins() { - RewriterTransaction transaction = qmlItemNode().view()->beginRewriterTransaction(QByteArrayLiteral("QmlAnchors::removeMargins")); - removeMargin(AnchorLineLeft); - removeMargin(AnchorLineRight); - removeMargin(AnchorLineTop); - removeMargin(AnchorLineBottom); - removeMargin(AnchorLineHorizontalCenter); - removeMargin(AnchorLineVerticalCenter); + qmlItemNode().view()->executeInTransaction("QmlAnchors::removeMargins", [this](){ + removeMargin(AnchorLineLeft); + removeMargin(AnchorLineRight); + removeMargin(AnchorLineTop); + removeMargin(AnchorLineBottom); + removeMargin(AnchorLineHorizontalCenter); + removeMargin(AnchorLineVerticalCenter); + }); } void QmlAnchors::fill() diff --git a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp index f02ca1ead73..ea40b46e8bf 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp @@ -102,9 +102,7 @@ QmlItemNode QmlItemNode::createQmlItemNode(AbstractView *view, const ItemLibrary { QmlItemNode newQmlItemNode; - try { - RewriterTransaction transaction = view->beginRewriterTransaction(QByteArrayLiteral("QmlItemNode::createQmlItemNode")); - + view->executeInTransaction("QmlItemNode::createQmlItemNode", [=, &newQmlItemNode, &parentproperty](){ NodeMetaInfo metaInfo = view->model()->metaInfo(itemLibraryEntry.typeName()); int minorVersion = metaInfo.minorVersion(); @@ -139,7 +137,7 @@ QmlItemNode QmlItemNode::createQmlItemNode(AbstractView *view, const ItemLibrary parentproperty.reparentHere(newQmlItemNode); if (!newQmlItemNode.isValid()) - return newQmlItemNode; + return; newQmlItemNode.setId(view->generateNewId(itemLibraryEntry.name())); @@ -150,10 +148,7 @@ QmlItemNode QmlItemNode::createQmlItemNode(AbstractView *view, const ItemLibrary newQmlItemNode.modelNode().variantProperty(propertyBindingEntry.first).setEnumeration(propertyBindingEntry.second.toUtf8()); Q_ASSERT(newQmlItemNode.isValid()); - } - catch (const RewritingException &e) { - e.showException(); - } + }); Q_ASSERT(newQmlItemNode.isValid()); @@ -174,10 +169,8 @@ QmlItemNode QmlItemNode::createQmlItemNodeFromImage(AbstractView *view, const QS { QmlItemNode newQmlItemNode; - if (parentproperty.isValid()) { - RewriterTransaction transaction = view->beginRewriterTransaction(QByteArrayLiteral("QmlItemNode::createQmlItemNodeFromImage")); - - if (view->model()->hasNodeMetaInfo("QtQuick.Image")) { + if (parentproperty.isValid() && view->model()->hasNodeMetaInfo("QtQuick.Image")) { + view->executeInTransaction("QmlItemNode::createQmlItemNodeFromImage", [=, &newQmlItemNode, &parentproperty](){ NodeMetaInfo metaInfo = view->model()->metaInfo("QtQuick.Image"); QList > propertyPairList; propertyPairList.append({PropertyName("x"), QVariant(qRound(position.x()))}); @@ -200,8 +193,7 @@ QmlItemNode QmlItemNode::createQmlItemNodeFromImage(AbstractView *view, const QS newQmlItemNode.modelNode().variantProperty("fillMode").setEnumeration("Image.PreserveAspectFit"); Q_ASSERT(newQmlItemNode.isValid()); - } - Q_ASSERT(newQmlItemNode.isValid()); + }); } return newQmlItemNode; diff --git a/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/backendmodel.cpp b/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/backendmodel.cpp index f356788a55d..4a004ca5753 100644 --- a/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/backendmodel.cpp +++ b/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/backendmodel.cpp @@ -232,27 +232,24 @@ void BackendModel::addNewBackend() Import import = Import::createLibraryImport(importSplit.constFirst(), importSplit.constLast()); - try { - - /* We cannot add an import and add a node from that import in a single transaction. + /* We cannot add an import and add a node from that import in a single transaction. * We need the import to have the meta info available. */ - if (!model->hasImport(import)) - model->changeImports({import}, {}); + if (!model->hasImport(import)) + model->changeImports({import}, {}); - QString propertyName = m_connectionView->generateNewId(typeName); + QString propertyName = m_connectionView->generateNewId(typeName); - NodeMetaInfo metaInfo = model->metaInfo(typeName.toUtf8()); + NodeMetaInfo metaInfo = model->metaInfo(typeName.toUtf8()); - QTC_ASSERT(metaInfo.isValid(), return); + QTC_ASSERT(metaInfo.isValid(), return); - int minorVersion = metaInfo.minorVersion(); - int majorVersion = metaInfo.majorVersion(); - - /* Add a property for non singleton types. For singletons just adding the import is enough. */ - if (!dialog.isSingleton()) { - RewriterTransaction transaction = m_connectionView->beginRewriterTransaction("BackendModel::addNewBackend"); + /* Add a property for non singleton types. For singletons just adding the import is enough. */ + if (!dialog.isSingleton()) { + m_connectionView->executeInTransaction("BackendModel::addNewBackend", [=, &dialog](){ + int minorVersion = metaInfo.minorVersion(); + int majorVersion = metaInfo.majorVersion(); if (dialog.localDefinition()) { ModelNode newNode = m_connectionView->createModelNode(metaInfo.typeName(), majorVersion, minorVersion); @@ -263,14 +260,9 @@ void BackendModel::addNewBackend() m_connectionView->rootModelNode().bindingProperty( propertyName.toUtf8()).setDynamicTypeNameAndExpression(typeName.toUtf8(), "null"); } - transaction.commit(); - } - - } catch (const Exception &e) { - e.showException(); + }); } } - resetModel(); } @@ -279,11 +271,9 @@ void BackendModel::updatePropertyName(int rowNumber) const PropertyName newName = data(index(rowNumber, 1)).toString().toUtf8(); const PropertyName oldName = data(index(rowNumber, 0), Qt::UserRole + 1).toString().toUtf8(); - ModelNode rootModelNode = m_connectionView->rootModelNode(); - - try { - RewriterTransaction transaction = m_connectionView->beginRewriterTransaction("BackendModel::updatePropertyName"); + m_connectionView->executeInTransaction("BackendModel::updatePropertyName", [this, newName, oldName](){ + ModelNode rootModelNode = m_connectionView->rootModelNode(); if (rootModelNode.property(oldName).isNodeProperty()) { const TypeName typeName = rootModelNode.nodeProperty(oldName).dynamicTypeName(); @@ -306,12 +296,7 @@ void BackendModel::updatePropertyName(int rowNumber) qWarning() << Q_FUNC_INFO << oldName << newName << "failed..."; QTC_ASSERT(false, return); } - - transaction.commit(); - - } catch (const Exception &e) { - e.showException(); - } + }); } void BackendModel::handleDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) diff --git a/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/bindingmodel.cpp b/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/bindingmodel.cpp index cd8c92b82c1..2cff12b044d 100644 --- a/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/bindingmodel.cpp +++ b/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/bindingmodel.cpp @@ -290,8 +290,6 @@ void BindingModel::addModelNode(const ModelNode &modelNode) void BindingModel::updateExpression(int row) { - BindingProperty bindingProperty = bindingPropertyForRow(row); - const QString sourceNode = data(index(row, SourceModelNodeRow)).toString().trimmed(); const QString sourceProperty = data(index(row, SourcePropertyNameRow)).toString().trimmed(); @@ -302,15 +300,10 @@ void BindingModel::updateExpression(int row) expression = sourceNode + QLatin1String(".") + sourceProperty; } - RewriterTransaction transaction = - connectionView()->beginRewriterTransaction(QByteArrayLiteral("BindingModel::updateExpression")); - try { + connectionView()->executeInTransaction("BindingModel::updateExpression", [this, row, expression](){ + BindingProperty bindingProperty = bindingPropertyForRow(row); bindingProperty.setExpression(expression.trimmed()); - transaction.commit(); //committing in the try block - } catch (Exception &e) { - m_exceptionError = e.description(); - QTimer::singleShot(200, this, &BindingModel::handleException); - } + }); } void BindingModel::updatePropertyName(int rowNumber) diff --git a/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/connectionmodel.cpp b/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/connectionmodel.cpp index 8cd297890e9..80caf51ce06 100644 --- a/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/connectionmodel.cpp +++ b/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/connectionmodel.cpp @@ -182,26 +182,21 @@ void ConnectionModel::updateSource(int row) void ConnectionModel::updateSignalName(int rowNumber) { SignalHandlerProperty signalHandlerProperty = signalHandlerPropertyForRow(rowNumber); - - const PropertyName newName = data(index(rowNumber, TargetPropertyNameRow)).toString().toUtf8(); - const QString source = signalHandlerProperty.source(); ModelNode connectionNode = signalHandlerProperty.parentModelNode(); + const PropertyName newName = data(index(rowNumber, TargetPropertyNameRow)).toString().toUtf8(); if (!newName.isEmpty()) { - RewriterTransaction transaction = - connectionView()->beginRewriterTransaction(QByteArrayLiteral("ConnectionModel::updateSignalName")); - try { + connectionView()->executeInTransaction("ConnectionModel::updateSignalName", [=, &connectionNode](){ + + const QString source = signalHandlerProperty.source(); + connectionNode.signalHandlerProperty(newName).setSource(source); connectionNode.removeProperty(signalHandlerProperty.name()); - transaction.commit(); //committing in the try block - } catch (Exception &e) { //better save then sorry - QMessageBox::warning(nullptr, tr("Error"), e.description()); - } + }); QStandardItem* idItem = item(rowNumber, 0); SignalHandlerProperty newSignalHandlerProperty = connectionNode.signalHandlerProperty(newName); updateCustomData(idItem, newSignalHandlerProperty); - } else { qWarning() << "BindingModel::updatePropertyName invalid property name"; } @@ -214,14 +209,9 @@ void ConnectionModel::updateTargetNode(int rowNumber) ModelNode connectionNode = signalHandlerProperty.parentModelNode(); if (!newTarget.isEmpty()) { - RewriterTransaction transaction = - connectionView()->beginRewriterTransaction(QByteArrayLiteral("ConnectionModel::updateTargetNode")); - try { + connectionView()->executeInTransaction("ConnectionModel::updateTargetNode", [= ,&connectionNode](){ connectionNode.bindingProperty("target").setExpression(newTarget); - transaction.commit(); //committing in the try block - } catch (Exception &e) { //better save then sorry - QMessageBox::warning(nullptr, tr("Error"), e.description()); - } + }); QStandardItem* idItem = item(rowNumber, 0); updateCustomData(idItem, signalHandlerProperty); @@ -256,12 +246,10 @@ void ConnectionModel::addConnection() if (rootModelNode.isValid() && rootModelNode.metaInfo().isValid()) { - NodeMetaInfo nodeMetaInfo = connectionView()->model()->metaInfo("QtQuick.Connections"); + NodeMetaInfo nodeMetaInfo = connectionView()->model()->metaInfo("QtQuick.Connections"); if (nodeMetaInfo.isValid()) { - RewriterTransaction transaction = - connectionView()->beginRewriterTransaction(QByteArrayLiteral("ConnectionModel::addConnection")); - try { + connectionView()->executeInTransaction("ConnectionModel::addConnection", [=](){ ModelNode newNode = connectionView()->createModelNode("QtQuick.Connections", nodeMetaInfo.majorVersion(), nodeMetaInfo.minorVersion()); @@ -276,10 +264,7 @@ void ConnectionModel::addConnection() } else { newNode.bindingProperty("target").setExpression(QLatin1String("parent")); } - transaction.commit(); - } catch (Exception &e) { //better save then sorry - QMessageBox::warning(nullptr, tr("Error"), e.description()); - } + }); } } } diff --git a/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/dynamicpropertiesmodel.cpp b/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/dynamicpropertiesmodel.cpp index 8d4186a5b54..0a08e5c8839 100644 --- a/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/dynamicpropertiesmodel.cpp +++ b/src/plugins/qmldesigner/qmldesignerextension/connectioneditor/dynamicpropertiesmodel.cpp @@ -464,19 +464,16 @@ void DynamicPropertiesModel::updatePropertyName(int rowNumber) BindingProperty bindingProperty = bindingPropertyForRow(rowNumber); - if (bindingProperty.isBindingProperty()) { - const QString expression = bindingProperty.expression(); - const PropertyName dynamicPropertyType = bindingProperty.dynamicTypeName(); - ModelNode targetNode = bindingProperty.parentModelNode(); + ModelNode targetNode = bindingProperty.parentModelNode(); + + if (bindingProperty.isBindingProperty()) { + connectionView()->executeInTransaction("DynamicPropertiesModel::updatePropertyName", [bindingProperty, newName, &targetNode](){ + const QString expression = bindingProperty.expression(); + const PropertyName dynamicPropertyType = bindingProperty.dynamicTypeName(); - RewriterTransaction transaction = connectionView()->beginRewriterTransaction(QByteArrayLiteral("DynamicPropertiesModel::updatePropertyName")); - try { targetNode.bindingProperty(newName).setDynamicTypeNameAndExpression(dynamicPropertyType, expression); targetNode.removeProperty(bindingProperty.name()); - transaction.commit(); //committing in the try block - } catch (Exception &e) { //better save then sorry - QMessageBox::warning(nullptr, tr("Error"), e.description()); - } + }); updateCustomData(rowNumber, targetNode.bindingProperty(newName)); return; @@ -489,14 +486,10 @@ void DynamicPropertiesModel::updatePropertyName(int rowNumber) const PropertyName dynamicPropertyType = variantProperty.dynamicTypeName(); ModelNode targetNode = variantProperty.parentModelNode(); - RewriterTransaction transaction = connectionView()->beginRewriterTransaction(QByteArrayLiteral("DynamicPropertiesModel::updatePropertyName")); - try { + connectionView()->executeInTransaction("DynamicPropertiesModel::updatePropertyName", [=](){ targetNode.variantProperty(newName).setDynamicTypeNameAndValue(dynamicPropertyType, value); targetNode.removeProperty(variantProperty.name()); - transaction.commit(); //committing in the try block - } catch (Exception &e) { //better save then sorry - QMessageBox::warning(nullptr, tr("Error"), e.description()); - } + }); updateCustomData(rowNumber, targetNode.variantProperty(newName)); } @@ -519,14 +512,10 @@ void DynamicPropertiesModel::updatePropertyType(int rowNumber) const PropertyName propertyName = bindingProperty.name(); ModelNode targetNode = bindingProperty.parentModelNode(); - RewriterTransaction transaction = connectionView()->beginRewriterTransaction(QByteArrayLiteral("DynamicPropertiesModel::updatePropertyType")); - try { + connectionView()->executeInTransaction("DynamicPropertiesModel::updatePropertyType", [=](){ targetNode.removeProperty(bindingProperty.name()); targetNode.bindingProperty(propertyName).setDynamicTypeNameAndExpression(newType, expression); - transaction.commit(); //committing in the try block - } catch (Exception &e) { //better save then sorry - QMessageBox::warning(nullptr, tr("Error"), e.description()); - } + }); updateCustomData(rowNumber, targetNode.bindingProperty(propertyName)); return; @@ -539,18 +528,14 @@ void DynamicPropertiesModel::updatePropertyType(int rowNumber) ModelNode targetNode = variantProperty.parentModelNode(); const PropertyName propertyName = variantProperty.name(); - RewriterTransaction transaction = connectionView()->beginRewriterTransaction(QByteArrayLiteral("DynamicPropertiesModel::updatePropertyType")); - try { + connectionView()->executeInTransaction("DynamicPropertiesModel::updatePropertyType", [=](){ targetNode.removeProperty(variantProperty.name()); if (newType == "alias") { //alias properties have to be bindings targetNode.bindingProperty(propertyName).setDynamicTypeNameAndExpression(newType, QLatin1String("none.none")); } else { targetNode.variantProperty(propertyName).setDynamicTypeNameAndValue(newType, convertVariantForTypeName(value, newType)); } - transaction.commit(); //committing in the try block - } catch (Exception &e) { //better save then sorry - QMessageBox::warning(nullptr, tr("Error"), e.description()); - } + }); updateCustomData(rowNumber, targetNode.variantProperty(propertyName)); diff --git a/src/plugins/qmldesigner/qmldesignerextension/pathtool/pathitem.cpp b/src/plugins/qmldesigner/qmldesignerextension/pathtool/pathitem.cpp index ad5437f34e9..76fe6f0b90f 100644 --- a/src/plugins/qmldesigner/qmldesignerextension/pathtool/pathitem.cpp +++ b/src/plugins/qmldesigner/qmldesignerextension/pathtool/pathitem.cpp @@ -133,46 +133,7 @@ void PathItem::writePathToProperty() ModelNode pathNode = pathModelNode(formEditorItem()); - RewriterTransaction rewriterTransaction = pathNode.view()->beginRewriterTransaction(QByteArrayLiteral("PathItem::writePathToProperty")); - - QList pathSegmentNodes = pathNode.nodeListProperty("pathElements").toModelNodeList(); - - foreach (ModelNode pathSegment, pathSegmentNodes) - pathSegment.destroy(); - - if (!m_cubicSegments.isEmpty()) { - pathNode.variantProperty("startX").setValue(m_cubicSegments.constFirst().firstControlPoint().coordinate().x()); - pathNode.variantProperty("startY").setValue(m_cubicSegments.constFirst().firstControlPoint().coordinate().y()); - - foreach (const CubicSegment &cubicSegment, m_cubicSegments) { - writePathAttributes(pathNode, cubicSegment.attributes()); - writePathPercent(pathNode, cubicSegment.percent()); - - if (cubicSegment.canBeConvertedToLine()) - writeLinePath(pathNode, cubicSegment); - else if (cubicSegment.canBeConvertedToQuad()) - writeQuadPath(pathNode, cubicSegment); - else - writeCubicPath(pathNode, cubicSegment); - } - - writePathAttributes(pathNode, m_lastAttributes); - writePathPercent(pathNode, m_lastPercent); - } - - rewriterTransaction.commit(); -} - -void PathItem::writePathAsCubicSegmentsOnly() -{ - try { - PathUpdateDisabler pathUpdateDisabler(this); - - ModelNode pathNode = pathModelNode(formEditorItem()); - - RewriterTransaction rewriterTransaction = - pathNode.view()->beginRewriterTransaction(QByteArrayLiteral("PathItem::writePathAsCubicSegmentsOnly")); - + pathNode.view()->executeInTransaction("PathItem::writePathToProperty", [this, &pathNode](){ QList pathSegmentNodes = pathNode.nodeListProperty("pathElements").toModelNodeList(); foreach (ModelNode pathSegment, pathSegmentNodes) @@ -182,21 +143,51 @@ void PathItem::writePathAsCubicSegmentsOnly() pathNode.variantProperty("startX").setValue(m_cubicSegments.constFirst().firstControlPoint().coordinate().x()); pathNode.variantProperty("startY").setValue(m_cubicSegments.constFirst().firstControlPoint().coordinate().y()); - foreach (const CubicSegment &cubicSegment, m_cubicSegments) { writePathAttributes(pathNode, cubicSegment.attributes()); writePathPercent(pathNode, cubicSegment.percent()); - writeCubicPath(pathNode, cubicSegment); + + if (cubicSegment.canBeConvertedToLine()) + writeLinePath(pathNode, cubicSegment); + else if (cubicSegment.canBeConvertedToQuad()) + writeQuadPath(pathNode, cubicSegment); + else + writeCubicPath(pathNode, cubicSegment); } writePathAttributes(pathNode, m_lastAttributes); writePathPercent(pathNode, m_lastPercent); } + }); +} - rewriterTransaction.commit(); - } catch (const RewritingException &e) { - e.showException(); - } +void PathItem::writePathAsCubicSegmentsOnly() +{ + PathUpdateDisabler pathUpdateDisabler(this); + + ModelNode pathNode = pathModelNode(formEditorItem()); + pathNode.view()->executeInTransaction("PathItem::writePathAsCubicSegmentsOnly", [this, &pathNode](){ + + QList pathSegmentNodes = pathNode.nodeListProperty("pathElements").toModelNodeList(); + + foreach (ModelNode pathSegment, pathSegmentNodes) + pathSegment.destroy(); + + if (!m_cubicSegments.isEmpty()) { + pathNode.variantProperty("startX").setValue(m_cubicSegments.constFirst().firstControlPoint().coordinate().x()); + pathNode.variantProperty("startY").setValue(m_cubicSegments.constFirst().firstControlPoint().coordinate().y()); + + + foreach (const CubicSegment &cubicSegment, m_cubicSegments) { + writePathAttributes(pathNode, cubicSegment.attributes()); + writePathPercent(pathNode, cubicSegment.percent()); + writeCubicPath(pathNode, cubicSegment); + } + + writePathAttributes(pathNode, m_lastAttributes); + writePathPercent(pathNode, m_lastPercent); + } + }); } void PathItem::setFormEditorItem(FormEditorItem *formEditorItem) diff --git a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/easingcurvedialog.cpp b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/easingcurvedialog.cpp index 844be8e12fa..a069dc187b6 100644 --- a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/easingcurvedialog.cpp +++ b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/easingcurvedialog.cpp @@ -202,22 +202,13 @@ bool EasingCurveDialog::apply() msgBox.exec(); return false; } + AbstractView *view = m_frames.first().view(); - try { - AbstractView *view = m_frames.first().view(); - RewriterTransaction transaction(view->beginRewriterTransaction("EasingCurveDialog::apply")); - + return view->executeInTransaction("EasingCurveDialog::apply", [this, view](){ auto expression = m_splineEditor->easingCurve().toString(); for (const auto &frame : m_frames) frame.bindingProperty("easing.bezierCurve").setExpression(expression); - - transaction.commit(); - return true; - } catch (const RewritingException &e) { - e.showException(); - } - - return false; + }); } void EasingCurveDialog::textChanged() diff --git a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineactions.cpp b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineactions.cpp index 419e9294a2c..4751765874b 100644 --- a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineactions.cpp +++ b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineactions.cpp @@ -48,28 +48,18 @@ TimelineActions::TimelineActions() = default; void TimelineActions::deleteAllKeyframesForTarget(const ModelNode &targetNode, const QmlTimeline &timeline) { - try { - RewriterTransaction transaction(targetNode.view()->beginRewriterTransaction( - "TimelineActions::deleteAllKeyframesForTarget")); - + targetNode.view()->executeInTransaction("TimelineActions::deleteAllKeyframesForTarget", [=](){ if (timeline.isValid()) { for (auto frames : timeline.keyframeGroupsForTarget(targetNode)) frames.destroy(); } - - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); } void TimelineActions::insertAllKeyframesForTarget(const ModelNode &targetNode, const QmlTimeline &timeline) { - try { - RewriterTransaction transaction(targetNode.view()->beginRewriterTransaction( - "TimelineGraphicsScene::insertAllKeyframesForTarget")); - + targetNode.view()->executeInTransaction("TimelineActions::insertAllKeyframesForTarget", [=](){ auto object = QmlObjectNode(targetNode); if (timeline.isValid() && object.isValid()) { for (auto frames : timeline.keyframeGroupsForTarget(targetNode)) { @@ -78,10 +68,7 @@ void TimelineActions::insertAllKeyframesForTarget(const ModelNode &targetNode, } } - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); } void TimelineActions::copyAllKeyframesForTarget(const ModelNode &targetNode, @@ -117,11 +104,10 @@ void TimelineActions::pasteKeyframesToTarget(const ModelNode &targetNode, pasteModel->detachView(&view); - try { - targetNode.view()->model()->attachView(&view); + view.executeInTransaction("TimelineActions::pasteKeyframesToTarget", [=, &view](){ - RewriterTransaction transaction( - view.beginRewriterTransaction("TimelineActions::pasteKeyframesToTarget")); + + targetNode.view()->model()->attachView(&view); ModelNode nonConstTargetNode = targetNode; nonConstTargetNode.validId(); @@ -144,11 +130,7 @@ void TimelineActions::pasteKeyframesToTarget(const ModelNode &targetNode, timeline.modelNode().defaultNodeListProperty().reparentHere(newNode); } } - - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); } } @@ -296,9 +278,7 @@ void TimelineActions::pasteKeyframes(AbstractView *timelineView, const QmlTimeli ModelNode rootNode = view.rootModelNode(); - try { - RewriterTransaction transaction( - timelineView->beginRewriterTransaction("TimelineActions::pasteKeyframes")); + timelineView->executeInTransaction("TimelineActions::pasteKeyframes", [=](){ if (isKeyframe(rootNode)) pasteKeyframe(currentTime, rootNode, timelineView, timeline); else @@ -308,10 +288,7 @@ void TimelineActions::pasteKeyframes(AbstractView *timelineView, const QmlTimeli timelineView, timeline); - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); } bool TimelineActions::clipboardContainsKeyframes() diff --git a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinegraphicsscene.cpp b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinegraphicsscene.cpp index eb09492397b..99cc4867101 100644 --- a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinegraphicsscene.cpp +++ b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinegraphicsscene.cpp @@ -663,26 +663,16 @@ void TimelineGraphicsScene::deleteKeyframeGroup(const ModelNode &group) if (!QmlTimelineKeyframeGroup::isValidQmlTimelineKeyframeGroup(group)) return; - ModelNode nonConst = group; - - try { - RewriterTransaction transaction(timelineView()->beginRewriterTransaction( - "TimelineGraphicsScene::handleKeyframeGroupDeletion")); - + timelineView()->executeInTransaction("TimelineGraphicsScene::handleKeyframeGroupDeletion", [group](){ + ModelNode nonConst = group; nonConst.destroy(); + }); - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } } void TimelineGraphicsScene::deleteKeyframes(const QList &frames) { - try { - RewriterTransaction transaction(timelineView()->beginRewriterTransaction( - "TimelineGraphicsScene::handleKeyframeDeletion")); - + timelineView()->executeInTransaction("TimelineGraphicsScene::handleKeyframeDeletion", [frames](){ for (auto keyframe : frames) { if (keyframe.isValid()) { ModelNode frame = keyframe; @@ -692,10 +682,7 @@ void TimelineGraphicsScene::deleteKeyframes(const QList &frames) parent.destroy(); } } - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); } void TimelineGraphicsScene::activateLayout() diff --git a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinemovetool.cpp b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinemovetool.cpp index 49d35b781b9..0384d7c0a31 100644 --- a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinemovetool.cpp +++ b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinemovetool.cpp @@ -136,15 +136,12 @@ void TimelineMoveTool::mouseReleaseEvent(TimelineMovableAbstractItem *item, } } - try { - RewriterTransaction transaction(scene()->timelineView()->beginRewriterTransaction( - "TimelineMoveTool::mouseReleaseEvent")); - + scene()->timelineView()->executeInTransaction("TimelineMoveTool::mouseReleaseEvent", [this, current](){ current->commitPosition(mapToItem(current, current->rect().center())); if (current->asTimelineKeyframeItem()) { double frame = std::round( - current->mapFromSceneToFrame(current->rect().center().x())); + current->mapFromSceneToFrame(current->rect().center().x())); scene()->statusBarMessageChanged(QObject::tr("Frame %1").arg(frame)); @@ -152,12 +149,7 @@ void TimelineMoveTool::mouseReleaseEvent(TimelineMovableAbstractItem *item, if (keyframe != current) keyframe->commitPosition(mapToItem(current, keyframe->rect().center())); } - - transaction.commit(); - - } catch (const Exception &e) { - e.showException(); - } + }); } } diff --git a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinepropertyitem.cpp b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinepropertyitem.cpp index d0b89dfef4d..beeca23183b 100644 --- a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinepropertyitem.cpp +++ b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinepropertyitem.cpp @@ -534,15 +534,9 @@ void TimelineKeyframeItem::commitPosition(const QPointF &point) blockUpdates(); - try { - RewriterTransaction transaction( - m_frame.view()->beginRewriterTransaction("TimelineKeyframeItem::commitPosition")); - + m_frame.view()->executeInTransaction("TimelineKeyframeItem::commitPosition", [this, frame](){ m_frame.variantProperty("frame").setValue(frame); - transaction.commit(); - } catch (const RewritingException &e) { - e.showException(); - } + }); enableUpdates(); } diff --git a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinesectionitem.cpp b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinesectionitem.cpp index 32012dd145c..7bd784a7dd8 100644 --- a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinesectionitem.cpp +++ b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinesectionitem.cpp @@ -821,20 +821,15 @@ void TimelineBarItem::commitPosition(const QPointF & /*point*/) { if (sectionItem()->view()) { if (m_handle != Location::Undefined) { - qreal scaleFactor = rect().width() / m_oldRect.width(); + sectionItem()->view()->executeInTransaction("TimelineBarItem::commitPosition", [this](){ + qreal scaleFactor = rect().width() / m_oldRect.width(); - qreal moved = (rect().topLeft().x() - m_oldRect.topLeft().x()) / rulerScaling(); - qreal supposedFirstFrame = qRound(sectionItem()->firstFrame() + moved); + qreal moved = (rect().topLeft().x() - m_oldRect.topLeft().x()) / rulerScaling(); + qreal supposedFirstFrame = qRound(sectionItem()->firstFrame() + moved); - try { - RewriterTransaction transaction(sectionItem()->view()->beginRewriterTransaction( - "TimelineBarItem::commitPosition")); sectionItem()->scaleAllFrames(scaleFactor); sectionItem()->moveAllFrames(supposedFirstFrame - sectionItem()->firstFrame()); - transaction.commit(); - } catch (const RewritingException &e) { - e.showException(); - } + }); } } diff --git a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinesettingsmodel.cpp b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinesettingsmodel.cpp index 47426d97551..f75d1299839 100644 --- a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinesettingsmodel.cpp +++ b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinesettingsmodel.cpp @@ -266,15 +266,13 @@ ModelNode TimelineSettingsModel::animationForTimelineAndState(const QmlTimeline void TimelineSettingsModel::updateTimeline(int row) { - QmlModelState modelState(stateForRow(row)); - QmlTimeline timeline(timelineForRow(row)); - ModelNode animation(animationForRow(row)); - QmlTimeline oldTimeline = timelineView()->timelineForState(modelState); - RewriterTransaction transaction = timelineView()->beginRewriterTransaction( - QByteArrayLiteral("TimelineSettingsModel::updateTimeline")); + timelineView()->executeInTransaction("TimelineSettingsModel::updateTimeline", [this, row](){ + QmlModelState modelState(stateForRow(row)); + QmlTimeline timeline(timelineForRow(row)); + ModelNode animation(animationForRow(row)); + QmlTimeline oldTimeline = timelineView()->timelineForState(modelState); - try { if (modelState.isBaseState()) { if (oldTimeline.isValid()) oldTimeline.modelNode().variantProperty("enabled").setValue(false); @@ -301,27 +299,20 @@ void TimelineSettingsModel::updateTimeline(int row) propertyChanges.modelNode().variantProperty("enabled").setValue(true); } } - - } catch (Exception &e) { - m_exceptionError = e.description(); - QTimer::singleShot(200, this, &TimelineSettingsModel::handleException); - } + }); resetRow(row); } void TimelineSettingsModel::updateAnimation(int row) { - QmlModelState modelState(stateForRow(row)); - QmlTimeline timeline(timelineForRow(row)); - ModelNode animation(animationForRow(row)); - QmlTimeline oldTimeline = timelineView()->timelineForState(modelState); - ModelNode oldAnimation = animationForTimelineAndState(oldTimeline, modelState); + timelineView()->executeInTransaction("TimelineSettingsModel::updateAnimation", [this, row](){ + QmlModelState modelState(stateForRow(row)); + QmlTimeline timeline(timelineForRow(row)); + ModelNode animation(animationForRow(row)); + QmlTimeline oldTimeline = timelineView()->timelineForState(modelState); + ModelNode oldAnimation = animationForTimelineAndState(oldTimeline, modelState); - RewriterTransaction transaction = timelineView()->beginRewriterTransaction( - QByteArrayLiteral("TimelineSettingsModel::updateAnimation")); - - try { if (modelState.isBaseState()) { if (oldAnimation.isValid()) oldAnimation.variantProperty("running").setValue(false); @@ -353,27 +344,20 @@ void TimelineSettingsModel::updateAnimation(int row) propertyChanges.modelNode().variantProperty("running").setValue(true); } } - } catch (Exception &e) { - m_exceptionError = e.description(); - QTimer::singleShot(200, this, &TimelineSettingsModel::handleException); - } - + }); resetRow(row); } void TimelineSettingsModel::updateFixedFrameRow(int row) { - QmlModelState modelState(stateForRow(row)); - QmlTimeline timeline(timelineForRow(row)); + timelineView()->executeInTransaction("TimelineSettingsModel::updateFixedFrameRow", [this, row](){ + QmlModelState modelState(stateForRow(row)); + QmlTimeline timeline(timelineForRow(row)); - ModelNode animation = animationForTimelineAndState(timeline, modelState); + ModelNode animation = animationForTimelineAndState(timeline, modelState); - RewriterTransaction transaction = timelineView()->beginRewriterTransaction( - QByteArrayLiteral("TimelineSettingsModel::updateFixedFrameRow")); + int fixedFrame = fixedFrameForRow(row); - int fixedFrame = fixedFrameForRow(row); - - try { if (modelState.isBaseState()) { if (animation.isValid()) animation.variantProperty("running").setValue(false); @@ -390,10 +374,8 @@ void TimelineSettingsModel::updateFixedFrameRow(int row) if (propertyChanges.isValid()) propertyChanges.modelNode().variantProperty("currentFrame").setValue(fixedFrame); } - } catch (Exception &e) { - m_exceptionError = e.description(); - QTimer::singleShot(200, this, &TimelineSettingsModel::handleException); - } + + }); resetRow(row); } diff --git a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineview.cpp b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineview.cpp index 653ed27ba75..f39a17db2ff 100644 --- a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineview.cpp +++ b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineview.cpp @@ -264,9 +264,7 @@ const QmlTimeline TimelineView::addNewTimeline() ModelNode timelineNode; - try { - RewriterTransaction transaction(beginRewriterTransaction("TimelineView::addNewTimeline")); - + executeInTransaction("TimelineView::addNewTimeline", [=, &timelineNode](){ bool hasTimelines = getTimelines().isEmpty(); timelineNode = createModelNode(timelineType, @@ -279,10 +277,7 @@ const QmlTimeline TimelineView::addNewTimeline() timelineNode.variantProperty("enabled").setValue(hasTimelines); rootModelNode().defaultNodeListProperty().reparentHere(timelineNode); - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); return QmlTimeline(timelineNode); } @@ -300,10 +295,8 @@ ModelNode TimelineView::addAnimation(QmlTimeline timeline) QTC_ASSERT(metaInfo.isValid(), return ModelNode()); ModelNode animationNode; - try { - RewriterTransaction transaction( - beginRewriterTransaction("TimelineSettingsDialog::addAnimation")); + executeInTransaction("TimelineView::addAnimation", [=, &animationNode](){ animationNode = createModelNode(animationType, metaInfo.majorVersion(), metaInfo.minorVersion()); @@ -321,10 +314,7 @@ ModelNode TimelineView::addAnimation(QmlTimeline timeline) if (timeline.modelNode().hasProperty("currentFrame")) timeline.modelNode().removeProperty("currentFrame"); - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); return animationNode; } @@ -390,28 +380,23 @@ void TimelineView::insertKeyframe(const ModelNode &target, const PropertyName &p QmlTimeline timeline = widget()->graphicsScene()->currentTimeline(); ModelNode targetNode = target; if (timeline.isValid() && targetNode.isValid() - && QmlObjectNode::isValidQmlObjectNode(targetNode)) { - try { - RewriterTransaction transaction( - beginRewriterTransaction("TimelineView::insertKeyframe")); + && QmlObjectNode::isValidQmlObjectNode(targetNode)) { + executeInTransaction("TimelineView::insertKeyframe", [=, &timeline, &targetNode](){ targetNode.validId(); QmlTimelineKeyframeGroup timelineFrames( - timeline.keyframeGroup(targetNode, propertyName)); + timeline.keyframeGroup(targetNode, propertyName)); QTC_ASSERT(timelineFrames.isValid(), return ); const qreal frame - = timeline.modelNode().auxiliaryData("currentFrame@NodeInstance").toReal(); + = timeline.modelNode().auxiliaryData("currentFrame@NodeInstance").toReal(); const QVariant value = QmlObjectNode(targetNode).instanceValue(propertyName); timelineFrames.setValue(value, frame); - transaction.commit(); - } catch (const Exception &e) { - e.showException(); - } + }); } } diff --git a/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml b/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml index 09c2e7757e9..fa90cd8a652 100644 --- a/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml +++ b/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml @@ -235,4 +235,18 @@ Image { } } } + + Text { + id: all_rights_reserved1 + x: 15 + y: 75 + color: "#ffffff" + text: qsTr("Community Edition") + font.pixelSize: 13 + font.family: Constants.titilliumWeb_light + visible: projectModel.communityVersion + ProjectModel { + id: projectModel + } + } } diff --git a/src/plugins/studiowelcome/qml/splashscreen/welcome_windows/logo.png b/src/plugins/studiowelcome/qml/splashscreen/welcome_windows/logo.png index f7b6fb1736e..347beb789c4 100644 Binary files a/src/plugins/studiowelcome/qml/splashscreen/welcome_windows/logo.png and b/src/plugins/studiowelcome/qml/splashscreen/welcome_windows/logo.png differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/main.qml b/src/plugins/studiowelcome/qml/welcomepage/main.qml index 3a37cc15987..288321c2d98 100644 --- a/src/plugins/studiowelcome/qml/welcomepage/main.qml +++ b/src/plugins/studiowelcome/qml/welcomepage/main.qml @@ -185,5 +185,20 @@ Item { onClicked: Qt.openUrlExternally("http://blog.qt.io/") } } + + Text { + id: qtDesignStudio1 + x: 891 + y: 171 + color: "#ffffff" + text: qsTr("Community Edition") + anchors.right: parent.right + anchors.rightMargin: 23 + font.weight: Font.Light + font.pixelSize: 14 + font.family: Constants.titilliumWeb_regular + renderType: Text.NativeRendering + visible: projectModel.communityVersion + } } } diff --git a/src/plugins/texteditor/highlighter.cpp b/src/plugins/texteditor/highlighter.cpp index 7fc085bb3dc..d1f7dbc1bf0 100644 --- a/src/plugins/texteditor/highlighter.cpp +++ b/src/plugins/texteditor/highlighter.cpp @@ -274,9 +274,9 @@ void Highlighter::highlightBlock(const QString &text) { if (!definition().isValid()) return; - const QTextBlock block = currentBlock(); + QTextBlock block = currentBlock(); KSyntaxHighlighting::State state; - setCurrentBlockState(qMax(0, previousBlockState())); + TextDocumentLayout::setBraceDepth(block, TextDocumentLayout::braceDepth(block.previous())); if (TextBlockUserData *data = TextDocumentLayout::testUserData(block)) { state = data->syntaxState(); data->setFoldingStartIncluded(false); @@ -298,8 +298,11 @@ void Highlighter::highlightBlock(const QString &text) if (nextBlock.isValid()) { TextBlockUserData *data = TextDocumentLayout::userData(nextBlock); - data->setSyntaxState(state); - data->setFoldingIndent(currentBlockState()); + if (data->syntaxState() != state) { + data->setSyntaxState(state); + setCurrentBlockState(currentBlockState() ^ 1); // force rehighlight of next block + } + data->setFoldingIndent(TextDocumentLayout::braceDepth(block)); } formatSpaces(text); @@ -316,24 +319,24 @@ void Highlighter::applyFolding(int offset, { if (!region.isValid()) return; - const QTextBlock &block = currentBlock(); + QTextBlock block = currentBlock(); const QString &text = block.text(); TextBlockUserData *data = TextDocumentLayout::userData(currentBlock()); const bool fromStart = TabSettings::firstNonSpace(text) == offset; const bool toEnd = (offset + length) == (text.length() - TabSettings::trailingWhitespaces(text)); if (region.type() == KSyntaxHighlighting::FoldingRegion::Begin) { - setCurrentBlockState(currentBlockState() + 1); + TextDocumentLayout::changeBraceDepth(block, 1); // if there is only a folding begin in the line move the current block into the fold if (fromStart && toEnd) { - data->setFoldingIndent(currentBlockState()); + data->setFoldingIndent(TextDocumentLayout::braceDepth(block)); data->setFoldingStartIncluded(true); } } else if (region.type() == KSyntaxHighlighting::FoldingRegion::End) { - setCurrentBlockState(qMax(0, currentBlockState() - 1)); + TextDocumentLayout::changeBraceDepth(block, -1); // if the folding end is at the end of the line move the current block into the fold if (toEnd) data->setFoldingEndIncluded(true); else - data->setFoldingIndent(currentBlockState()); + data->setFoldingIndent(TextDocumentLayout::braceDepth(block)); } } diff --git a/tests/auto/qml/reformatter/comments.qml b/tests/auto/qml/reformatter/comments.qml index 4ced7eb0e89..d2caa1b555e 100644 --- a/tests/auto/qml/reformatter/comments.qml +++ b/tests/auto/qml/reformatter/comments.qml @@ -21,5 +21,13 @@ Item { { console.log("test") } + + var a = 1 + if (a > 0) { + console.log("positive") + } // Final condition + else { + console.log("negative or zero") + } } } diff --git a/tests/auto/qml/reformatter/enum.qml b/tests/auto/qml/reformatter/enum.qml new file mode 100644 index 00000000000..769386494d0 --- /dev/null +++ b/tests/auto/qml/reformatter/enum.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Item { + enum Test { + A, + B + } + + enum TestWithValues { + A = 11.1, + B, + C = 3 + } +} diff --git a/tests/auto/qml/reformatter/jssyntax.js b/tests/auto/qml/reformatter/jssyntax.js index 5ef1a2adcd6..d651cd7822c 100644 --- a/tests/auto/qml/reformatter/jssyntax.js +++ b/tests/auto/qml/reformatter/jssyntax.js @@ -1,6 +1,10 @@ var x var y = 12 +var a_var = 1 +let a_let = 2 +const a_const = 3 + function foo(a, b) { x = 15 x += 4 @@ -28,6 +32,12 @@ while (true) { for (var x in a) { print(a[x]) } + for (let x in a) { + print(a[x]) + } + for (const x in a) { + print(a[x]) + } do { a = x diff --git a/tests/auto/qml/reformatter/objectliteral.js b/tests/auto/qml/reformatter/objectliteral.js index 37f68633746..d260712166d 100644 --- a/tests/auto/qml/reformatter/objectliteral.js +++ b/tests/auto/qml/reformatter/objectliteral.js @@ -10,3 +10,5 @@ var x = { }, "z": 12 } + +var empty_object = {} diff --git a/tests/auto/qml/reformatter/qmlsingleton.qml b/tests/auto/qml/reformatter/qmlsingleton.qml index d64f554097c..05a08e7de40 100644 --- a/tests/auto/qml/reformatter/qmlsingleton.qml +++ b/tests/auto/qml/reformatter/qmlsingleton.qml @@ -2,5 +2,4 @@ pragma Singleton import QtQuick 2.0 -Item { -} +Item {} diff --git a/tests/auto/qml/reformatter/qmlsyntax.qml b/tests/auto/qml/reformatter/qmlsyntax.qml index ded863106a7..8717aba35d5 100644 --- a/tests/auto/qml/reformatter/qmlsyntax.qml +++ b/tests/auto/qml/reformatter/qmlsyntax.qml @@ -45,4 +45,6 @@ Text { function foo(a, b) { x = a + 12 * b } + + value: Rectangle {} } diff --git a/tests/auto/ssh/tst_ssh.cpp b/tests/auto/ssh/tst_ssh.cpp index 5ce94b74623..72260c2c9af 100644 --- a/tests/auto/ssh/tst_ssh.cpp +++ b/tests/auto/ssh/tst_ssh.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -171,8 +172,10 @@ void tst_Ssh::errorHandling() connection.connectToHost(); loop.exec(); QVERIFY(timer.isActive()); - QCOMPARE(connection.state(), SshConnection::Unconnected); - QVERIFY(!connection.errorString().isEmpty()); + const bool expectConnected = !SshSettings::connectionSharingEnabled(); + QCOMPARE(connection.state(), expectConnected ? SshConnection::Connected + : SshConnection::Unconnected); + QCOMPARE(connection.errorString().isEmpty(), expectConnected); QVERIFY(!disconnected); QVERIFY2(dataReceived.isEmpty(), qPrintable(dataReceived)); } @@ -374,7 +377,7 @@ void tst_Ssh::sftp() }; FilesToTransfer filesToUpload; std::srand(QDateTime::currentDateTime().toSecsSinceEpoch()); - for (int i = 0; i < 1000; ++i) { + for (int i = 0; i < 100; ++i) { const QString fileName = "sftptestfile" + QString::number(i + 1); QFile file(dirForFilesToUpload.path() + '/' + fileName); QVERIFY2(file.open(QIODevice::WriteOnly), qPrintable(file.errorString())); @@ -413,7 +416,7 @@ void tst_Ssh::sftp() QTimer timer; QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); timer.setSingleShot(true); - timer.setInterval((params.timeout + 5) * 1000); + timer.setInterval(30 * 1000); timer.start(); upload->start(); loop.exec(); @@ -453,7 +456,7 @@ void tst_Ssh::sftp() // Download the uploaded files to a different location const QStringList allUploadedFileNames = QDir(dirForFilesToUpload.path()).entryList(QDir::Files); - QCOMPARE(allUploadedFileNames.size(), 1001); + QCOMPARE(allUploadedFileNames.size(), 101); for (const QString &fileName : allUploadedFileNames) { const QString localFilePath = dirForFilesToUpload.path() + '/' + fileName; const QString remoteFilePath = getRemoteFilePath(fileName); @@ -462,7 +465,7 @@ void tst_Ssh::sftp() QVERIFY(downloadJob != SftpInvalidJob); jobs << downloadJob; } - QCOMPARE(jobs.size(), 1001); + QCOMPARE(jobs.size(), 101); loop.exec(); QVERIFY(!invalidFinishedSignal); QVERIFY2(jobError.isEmpty(), qPrintable(jobError)); @@ -490,6 +493,7 @@ void tst_Ssh::sftp() } // Remove the uploaded files on the remote system + timer.setInterval((params.timeout + 5) * 1000); for (const QString &fileName : allUploadedFileNames) { const QString remoteFilePath = getRemoteFilePath(fileName); const SftpJobId removeJob = sftpChannel->removeFile(remoteFilePath); diff --git a/tests/manual/proparser/testreader.pro b/tests/manual/proparser/testreader.pro index a7b7d74cd3c..0e10613a1ab 100644 --- a/tests/manual/proparser/testreader.pro +++ b/tests/manual/proparser/testreader.pro @@ -24,7 +24,8 @@ SOURCES += \ qmakebuiltins.cpp \ proitems.cpp \ qmakevfs.cpp \ - ioutils.cpp + ioutils.cpp \ + registry.cpp HEADERS += \ qmake_global.h \ @@ -35,7 +36,8 @@ HEADERS += \ profileevaluator.h \ proitems.h \ qmakevfs.h \ - ioutils.h + ioutils.h \ + registry_p.h RESOURCES += proparser.qrc DEFINES += QMAKE_BUILTIN_PRFS @@ -43,3 +45,5 @@ DEFINES += QMAKE_BUILTIN_PRFS DEFINES += QT_NO_CAST_TO_ASCII QT_RESTRICTED_CAST_FROM_ASCII DEFINES += QT_USE_FAST_OPERATOR_PLUS QT_USE_FAST_CONCATENATION DEFINES += PROEVALUATOR_FULL PROEVALUATOR_CUMULATIVE PROEVALUATOR_INIT_PROPS + +win32: LIBS *= -ladvapi32