diff --git a/doc/qtcreator/examples/transitions/CMakeLists.txt b/doc/qtcreator/examples/transitions/CMakeLists.txt index bf543f34ffe..ef3ac640cd0 100644 --- a/doc/qtcreator/examples/transitions/CMakeLists.txt +++ b/doc/qtcreator/examples/transitions/CMakeLists.txt @@ -1,59 +1,24 @@ -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.16) project(transitions VERSION 0.1 LANGUAGES CXX) -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) - -set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) -find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Quick REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Quick REQUIRED) +find_package(Qt6 6.2 COMPONENTS Quick REQUIRED) -set(PROJECT_SOURCES - main.cpp - qml.qrc +qt_add_executable(transitionsexample + main.cpp ) -if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) - qt_add_executable(transitions - MANUAL_FINALIZATION - ${PROJECT_SOURCES} - ) -# Define target properties for Android with Qt 6 as: -# set_property(TARGET transitions APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR -# ${CMAKE_CURRENT_SOURCE_DIR}/android) -# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation -else() - if(ANDROID) - add_library(transitions SHARED - ${PROJECT_SOURCES} - ) -# Define properties for Android with Qt 5 after find_package() calls as: -# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android") - else() - add_executable(transitions - ${PROJECT_SOURCES} - ) - endif() -endif() - -target_compile_definitions(transitions - PRIVATE $<$,$>:QT_QML_DEBUG>) -target_link_libraries(transitions - PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Quick) - -set_target_properties(transitions PROPERTIES - MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com - MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} - MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} +qt_add_qml_module(transitionsexample + URI transitions + VERSION 1.0 + QML_FILES main.qml Page.qml + RESOURCES qt-logo.png ) -if(QT_VERSION_MAJOR EQUAL 6) - qt_import_qml_plugins(transitions) - qt_finalize_executable(transitions) -endif() +target_compile_definitions(transitionsexample + PRIVATE $<$,$>:QT_QML_DEBUG>) +target_link_libraries(transitionsexample + PRIVATE Qt6::Quick) diff --git a/doc/qtcreator/examples/transitions/Page.qml b/doc/qtcreator/examples/transitions/Page.qml index 932a29cd029..610b1302367 100644 --- a/doc/qtcreator/examples/transitions/Page.qml +++ b/doc/qtcreator/examples/transitions/Page.qml @@ -48,19 +48,18 @@ ** ****************************************************************************/ -import QtQuick 2.15 -import QtQuick.Window 2.15 +import QtQuick Rectangle { id: page - state: "State1" + anchors.fill: parent + color: "#ffffff" Image { id: icon x: 20 y: 20 - source: "images/qt-logo.png" - fillMode: Image.PreserveAspectFit + source: "qt-logo.png" } Rectangle { @@ -88,7 +87,6 @@ Rectangle { } } - Rectangle { id: middleRightRect width: 55 @@ -112,7 +110,6 @@ Rectangle { } } - Rectangle { id: bottomLeftRect width: 55 @@ -160,6 +157,7 @@ Rectangle { } } ] + transitions: [ Transition { id: toState1 @@ -202,7 +200,7 @@ Rectangle { PropertyAnimation { target: icon property: "y" - easing.bezierCurve: [0.233,0.161,0.264,0.997,0.393,0.997,0.522,0.997,0.555,0.752,0.61,0.75,0.664,0.748,0.736,1,0.775,1,0.814,0.999,0.861,0.901,0.888,0.901,0.916,0.901,0.923,0.995,1,1] + easing.type: Easing.OutBounce duration: 1006 } } @@ -215,7 +213,7 @@ Rectangle { PropertyAnimation { target: icon property: "x" - easing.bezierCurve: [0.233,0.161,0.264,0.997,0.393,0.997,0.522,0.997,0.555,0.752,0.61,0.75,0.664,0.748,0.736,1,0.775,1,0.814,0.999,0.861,0.901,0.888,0.901,0.916,0.901,0.923,0.995,1,1] + easing.type: Easing.OutBounce duration: 1006 } } @@ -234,7 +232,7 @@ Rectangle { PropertyAnimation { target: icon property: "y" - easing.bezierCurve: [0.455,0.03,0.515,0.955,1,1] + easing.type: Easing.InOutQuad duration: 2000 } } @@ -247,7 +245,7 @@ Rectangle { PropertyAnimation { target: icon property: "x" - easing.bezierCurve: [0.455,0.03,0.515,0.955,1,1] + easing.type: Easing.InOutQuad duration: 2000 } } @@ -257,10 +255,3 @@ Rectangle { } ] } - -/*##^## -Designer { - D{i:0;height:480;width:640}D{i:1}D{i:16;transitionDuration:2000}D{i:24;transitionDuration:2000} -D{i:32;transitionDuration:2000} -} -##^##*/ diff --git a/doc/qtcreator/examples/transitions/images/qt-logo.png b/doc/qtcreator/examples/transitions/images/qt-logo.png deleted file mode 100644 index f465822ed08..00000000000 Binary files a/doc/qtcreator/examples/transitions/images/qt-logo.png and /dev/null differ diff --git a/doc/qtcreator/examples/transitions/main.cpp b/doc/qtcreator/examples/transitions/main.cpp index c43b030e92a..b9a717a80f8 100644 --- a/doc/qtcreator/examples/transitions/main.cpp +++ b/doc/qtcreator/examples/transitions/main.cpp @@ -54,19 +54,10 @@ int main(int argc, char *argv[]) { - if (qEnvironmentVariableIsEmpty("QTGLESSTREAM_DISPLAY")) { - qputenv("QT_QPA_EGLFS_PHYSICAL_WIDTH", QByteArray("213")); - qputenv("QT_QPA_EGLFS_PHYSICAL_HEIGHT", QByteArray("120")); - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); -#endif - } - QGuiApplication app(argc, argv); QQmlApplicationEngine engine; - const QUrl url(QStringLiteral("qrc:/main.qml")); + const QUrl url(u"qrc:/transitions/main.qml"_qs); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) diff --git a/doc/qtcreator/examples/transitions/main.qml b/doc/qtcreator/examples/transitions/main.qml index bb93d70fe90..ba4821c361e 100644 --- a/doc/qtcreator/examples/transitions/main.qml +++ b/doc/qtcreator/examples/transitions/main.qml @@ -48,24 +48,16 @@ ** ****************************************************************************/ -import QtQuick 2.15 -import QtQuick.Window 2.15 +import QtQuick Window { width: 640 height: 480 visible: true - title: qsTr("Hello World") + title: qsTr("Transitions") Page { id: page anchors.fill: parent - color: "#ffffff" } } - -/*##^## -Designer { - D{i:0;formeditorZoom:0.75} -} -##^##*/ diff --git a/doc/qtcreator/examples/transitions/qml.qrc b/doc/qtcreator/examples/transitions/qml.qrc deleted file mode 100644 index f046cc30b36..00000000000 --- a/doc/qtcreator/examples/transitions/qml.qrc +++ /dev/null @@ -1,7 +0,0 @@ - - - main.qml - images/qt-logo.png - Page.qml - - diff --git a/doc/qtcreator/examples/transitions/qt-logo.png b/doc/qtcreator/examples/transitions/qt-logo.png new file mode 100644 index 00000000000..e8eba475646 Binary files /dev/null and b/doc/qtcreator/examples/transitions/qt-logo.png differ diff --git a/doc/qtcreator/images/qml-toolbar-animation.png b/doc/qtcreator/images/qml-toolbar-animation.png index 28bb9a3a4f4..c0d4278b161 100644 Binary files a/doc/qtcreator/images/qml-toolbar-animation.png and b/doc/qtcreator/images/qml-toolbar-animation.png differ diff --git a/doc/qtcreator/images/qml-toolbar-image-preview.png b/doc/qtcreator/images/qml-toolbar-image-preview.png index 3f6e02d200e..a2b28b97a2f 100644 Binary files a/doc/qtcreator/images/qml-toolbar-image-preview.png and b/doc/qtcreator/images/qml-toolbar-image-preview.png differ diff --git a/doc/qtcreator/images/qml-toolbar-image.png b/doc/qtcreator/images/qml-toolbar-image.png index 43e79f55825..75cb2b4417a 100644 Binary files a/doc/qtcreator/images/qml-toolbar-image.png and b/doc/qtcreator/images/qml-toolbar-image.png differ diff --git a/doc/qtcreator/images/qml-toolbar-rectangle.png b/doc/qtcreator/images/qml-toolbar-rectangle.png index 296fb798158..c7ce5602d57 100644 Binary files a/doc/qtcreator/images/qml-toolbar-rectangle.png and b/doc/qtcreator/images/qml-toolbar-rectangle.png differ diff --git a/doc/qtcreator/images/qml-toolbar-text.png b/doc/qtcreator/images/qml-toolbar-text.png index 3cbc055434e..f6c5df586cb 100644 Binary files a/doc/qtcreator/images/qml-toolbar-text.png and b/doc/qtcreator/images/qml-toolbar-text.png differ diff --git a/doc/qtdesignstudio/images/qmldesigner-new-project.png b/doc/qtcreator/images/qmldesigner-new-project.png similarity index 100% rename from doc/qtdesignstudio/images/qmldesigner-new-project.png rename to doc/qtcreator/images/qmldesigner-new-project.png diff --git a/doc/qtcreator/images/qtquick-tutorial.gif b/doc/qtcreator/images/qtquick-tutorial.gif new file mode 100644 index 00000000000..d15b3806c23 Binary files /dev/null and b/doc/qtcreator/images/qtquick-tutorial.gif differ diff --git a/doc/qtcreator/src/qtcreator-toc.qdoc b/doc/qtcreator/src/qtcreator-toc.qdoc index c1ce9e2f2f5..f1e06156fd0 100644 --- a/doc/qtcreator/src/qtcreator-toc.qdoc +++ b/doc/qtcreator/src/qtcreator-toc.qdoc @@ -43,7 +43,6 @@ \li \l{File System} \li \l{Open Documents} \endlist - \li \l{Managing Workspaces} \li \l{Viewing Output} \endlist \li \l{Configuring Qt Creator} diff --git a/doc/qtcreator/src/qtquick/creator-only/qtquick-app-tutorial.qdoc b/doc/qtcreator/src/qtquick/creator-only/qtquick-app-tutorial.qdoc index be4a66a01c5..75495477244 100644 --- a/doc/qtcreator/src/qtquick/creator-only/qtquick-app-tutorial.qdoc +++ b/doc/qtcreator/src/qtquick/creator-only/qtquick-app-tutorial.qdoc @@ -30,33 +30,29 @@ \title Creating a Qt Quick Application - This tutorial uses preset components and illustrates basic concepts of - \l{Qt Quick}. - For more information about the UI choices you have, see \l{User Interfaces}. + This tutorial illustrates basic concepts of \l{Qt Quick}. For more + information about the UI choices you have, see \l{User Interfaces}. - This tutorial describes how to use \QC to implement states and - transitions. We create an application that displays a Qt logo that moves - between three rectangles on the page when you click them. + This tutorial describes how to use \QC to implement \l{Qt Quick States} + {states} and \l{Animation and Transitions in Qt Quick}{transitions} + when using Qt 6 as the minimum Qt version and CMake as the build system. - \image qmldesigner-tutorial.png "States and transitions example" + We use the \l{Working in Edit Mode}{Edit mode} to create an application + that moves a Qt logo between three rectangles when you click them. - For more information about developing Qt Quick applications in the Design - mode, see \l{Developing Qt Quick Applications}. + \image qtquick-tutorial.gif "Transitions example" - For examples of using Qt Quick Controls, see \l{Qt Quick Controls Examples}. + For more examples, see \l{Qt Quick Examples and Tutorials}. + + You can develop Qt Quick applications also in \QDS. For more information, + see \l{Qt Design Studio Manual}. \include qtquick-tutorial-create-empty-project.qdocinc qtquick empty application \QC generates a component file, \e main.qml, and opens it in the - \l {Text Editor} view. Select \uicontrol Design to open the file in - the \l {Form Editor} view. + \uicontrol Edit mode. - \note The visibility of Design views depends on the selected workspace. - To open hidden views, select \uicontrol View > \uicontrol Views - in the \uicontrol Design mode. For more information about moving - views around, see \l {Managing Workspaces}. - - \section1 Creating the Main View + \section1 Deploying Applications The main view of the application displays a Qt logo inside a rectangle in the top left corner of the view and two empty rectangles. @@ -64,256 +60,122 @@ We use the \e qt-logo.png image in this tutorial, but you can also use any other image or a component, instead. + For the image to appear when you run the application, you must specify it + as a resource in the \c RESOURCES section of \e CMakeLists.txt file that + the wizard created for you: + + \quotefromfile transitions/CMakeLists.txt + \skipto qt_add_qml_module + \printuntil ) + + \section1 Creating Custom QML Types + + Because the \l Window QML type requires states to be added into child + components, we use the wizard to create a custom QML type called + \e Page that we will refer to from \e main.qml. + + To create a custom QML type: + \list 1 - - \li In \uicontrol Library > \uicontrol Components > - \uicontrol {Default Components} > \uicontrol Basic, select - \uicontrol Rectangle and drag and drop it to \e Window in - \uicontrol Navigator. - - \li Select the \uicontrol Rectangle instance in \l Navigator, and enter - \e page in the \uicontrol ID field in \l Properties. - - \li In \uicontrol Layout, select the - \inlineimage icons/anchor-fill.png "Fill anchor button" - fill anchor button to anchor the rectangle to the window on all - sides. - - \li Select \uicontrol Library > \uicontrol Assets > \inlineimage plus.png - to locate qt-logo.png (or your own image) and add it to the - project folder. - - \li Drag and drop the image from \uicontrol Assets to \e page in - \uicontrol Navigator. \QC automatically generates an instance - of the \l{Images}{Image} component for you, with the image as - the source image. - - \image qmldesigner-tutorial-user-icon.png "Image properties" - - \li In \uicontrol Properties, edit the properties of the Image - component instance: - - \list a - - \li In the \uicontrol ID field, enter \e icon. - - \li In the \uicontrol Position field, set \uicontrol X and - \uicontrol Y to \e 20. - - \endlist - - \li In \uicontrol Library > \uicontrol Components > - \uicontrol {Default Components} > \uicontrol Basic, select - \uicontrol Rectangle and drag and drop it to \e page in - \uicontrol Navigator. - - \image qmldesigner-tutorial-topleftrect.png "Rectangle properties" - - \li In \uicontrol Properties, edit the properties of the Rectangle - component instance: - - \list a - - \li In the \uicontrol ID field, enter \e topLeftRect. - - \li In the \uicontrol Size field, set \uicontrol W and - \uicontrol H to values that match the image size - (\e 55 and \e 41). - - \li Select the \uicontrol Color field, and then select the - \inlineimage icons/transparent.png "Transparent button" - button in the \l{Picking colors}{color picker} to make - the rectangle transparent. - - \li In the \uicontrol {Border color} field, set the border - color to \e #808080 to make the rectangle visible on - the background. - - \li Click \uicontrol {Layout}, and then click the - \inlineimage icons/anchor-top.png "Top anchor button" - top and \inlineimage icons/anchor-left.png "Left anchor button" - left anchor buttons to anchor the rectangle to the top left - corner of the page. - - \li In the \uicontrol Margin field, select \e 20 for both anchors. - - \image qmldesigner-tutorial-topleftrect-layout.png "Anchor margins" - - \endlist - - \li Drag and drop a \uicontrol {Mouse Area} component from the - \uicontrol Library to \e topLeftRect in \uicontrol Navigator. - - \li Click \uicontrol {Layout}, and then click the - \inlineimage icons/anchor-fill.png "Fill anchor button" - button to anchor the mouse area to its parent. - - \li In the \uicontrol Navigator, copy \e topLeftRect (by pressing - \key {Ctrl+C}) and paste it to \e page in \uicontrol Navigator - twice (by pressing \key {Ctrl+V}). \QC renames the new instances - of the component \e topLeftRect1 and \e topLeftRect2. - - \li Select \e topLeftRect1 and edit its properties: - - \list a - - \li In the \uicontrol ID field, enter \e middleRightRect. - - \li In \uicontrol {Layout}, select the - \inlineimage icons/anchor-center-vertical.png "Vertical center anchor button" - vertical center anchor button and then the - \inlineimage icons/anchor-right.png "Right anchor button" - right anchor button to anchor the rectangle - to the middle right margin of its parent. - - \li In the \uicontrol Margin field, select \e 20 for the right - anchor and \e 0 for the vertical center anchor. - - \endlist - - \li Select \e topLeftRect2 and edit its properties: - - \list a - - \li In the \uicontrol ID field, enter \e bottomLeftRect. - - \li In \uicontrol {Layout}, select the - \inlineimage icons/anchor-bottom.png - (\uicontrol Bottom) and \inlineimage icons/anchor-left.png - (\uicontrol Left) anchor buttons to anchor the rectangle - to the bottom left margin of its parent. - - \li In the \uicontrol Margin field, select \e 20 for both anchors. - - \endlist - - \li Press \key {Ctrl+S} to save the changes. - + \li Select \uicontrol File > \uicontrol {New File or Project} > + \uicontrol {Files and Classes} > \uicontrol Qt > + \uicontrol {QML File (Qt Quick 2)}. + \li Select \uicontrol Choose to open the \uicontrol Location dialog. + \li In the \uicontrol {File name} field, enter a name for the custom + QML type. In this example, we call the type \e Page. + \li Select \uicontrol Next to open the \uicontrol {Project Management} + dialog. + \li Select \uicontrol Finish to create \e Page.qml. \endlist - To check your code, you can view your \e {main.qml} file in the - \uicontrol {Text Editor} and compare it with the \e {main.qml} - example file. + \QC opens \e Page.qml in the \uicontrol Edit mode. It contains a root item + of the type \l Item that we replace with a \l Rectangle type. We give the + type the ID \e page, anchor it to the parent item on all sides, and set + its color to white: - The UI design is now ready. + \quotefromfile transitions/Page.qml + \skipto import + \printuntil color - \image qmldesigner-tutorial-ui-ready.png "Transitions UI" + Because we develop with Qt 6, where version numbers are not used with + modules, we remove the version number from the import statement. - For more information about the views you used, see: + When you start typing the QML type name, \QC suggests available types + and properties to \l{Completing Code}{complete the code}. - \list - \li \l {Form Editor} - \li \l Library - \li \l Navigator - \li \l Properties - \endlist + Select the light bulb icon \inlineimage refactormarker.png + next to the type name to open the \l{Editing Rectangles} + {Qt Quick Toolbar for rectangles}. You can use it to specify + rectangle properties, such as color, transparency, and gradients. + + \image qml-toolbar-rectangle.png "Qt Quick Toolbar for rectangles" + + Next, we add an \l Image type with \e qt-logo.png as the source. We + position the image in the top-left corner of the rectangle: + + \printuntil } + + You can use the \l{Previewing Images}{Qt Quick Toolbar for images} to + specify image properties, such as source file and fill mode. + + \image qml-toolbar-image.png "Logo visible in Qt Quick Toolbar for images" + + We now create the rectangles that the image will move between. Their size + should match the image size and they should be transparent, so that the + image is visible. We set the border color to light gray to make the + rectangles visible: + + \printuntil border.color + + We anchor the rectangles to their parent to position them in its + top-left and and bottom-left corners, as well as the vertical center + of its right edge. The following code snippet anchors a rectangle to + the top-left corner of its parent: + + \printuntil anchors.topMargin + + We add a \l MouseArea type to make the rectangle clickable by users: + + \printuntil anchors.fill + + To check your code, you can compare it with the \e {Page.qml} example file. Next, we will make the image move between the rectangles when users click - them by \l{Adding States}{adding states} and by connecting mouse clicks - to state changes. - - Because the Window component requires states to be added into child - components, we must first move \e page into a separate component. - - \section1 Turning Page into a Custom Component - - To turn \e page into a custom component, right-click it - in \uicontrol Navigator or \uicontrol {Form Editor}, and select - \uicontrol {Move Component into Separate File} in the context menu. - - \image qmldesigner-tutorial-page-component.png "Move page component instance into a separate file" - - \list 1 - \li In \uicontrol {Component name}, enter \e Page. - \li In \uicontrol {Property assignments for main.qml} select both - check boxes to preserve the appearance of the UI. - \li Select \uicontrol OK to create a file called \e Page.qml that - defines the Page custom component and to add an instance of it - into \e main.qml. - \endlist + them, by adding states and by connecting mouse clicks to state changes. \section1 Connecting Mouse Clicks to State Changes To make the image move between the rectangles when users click them, we add states to the Page component, where we change the values of the \c x and - \c y properties of - \e icon to match those of the middle right and top left rectangles. Then, - we connect the \c onClicked signals of the mouse areas to the state changes. + \c y properties of \e icon to match those of the middle right and top left + rectangles. To make sure that the image is displayed within the rectangle + when the view is scaled on different sizes of screens, we \e bind the values + of the \c x and \c y properties of \e icon to those of the rectangles: - To make sure that the image is displayed within the rectangle when the view - is scaled on different sizes of screens, we bind the values of the \c x and - \c y properties of \e icon to those of the rectangles. + \dots + \skipto states: + \printuntil ] - \list 1 - \li Right-click \e page in \uicontrol Navigator, and select - \uicontrol {Go into Component} in the context menu to open - \e Page.qml in \uicontrol {Form Editor}. - \li In the \uicontrol States view, select \uicontrol {Create New State} - three times to create \e State1, \e State2, and \e State3. - \li Select \e State1 in \uicontrol States. - \li Select \inlineimage icons/action-icon.png - to open the \uicontrol Actions menu, and then select - \uicontrol {Set as Default} to display \e State1 when - the application starts. - \li Select \e State2 in \uicontrol States. - \li Select \e icon in \uicontrol Navigator to display its properties - in \uicontrol Properties. - \li In \uicontrol {Geometry - 2D} > \uicontrol Position > \uicontrol X, - select \inlineimage icons/action-icon.png "Actions button" - , and then select \uicontrol {Set Binding} to open - \uicontrol {Binding Editor}. - \li Select the \e middleRightRect component and the \e x property - to bind the \e x property value of \e icon to that of - \e middleRightRect. - \image qmldesigner-tutorial-bindings.png "Binding Editor" - \li Select \uicontrol OK to create the binding. - \li Repeat for \uicontrol Y, but set the binding as - \e middleRightRect.y. - \li Select \e State3 in \uicontrol States, and bind the \e x and \e y - property values of \e icon to those of \e bottomLeftRect - (\e bottomLeftRect.x and \e bottomLeftRect.y). - \li In \l {Connection View} > \uicontrol Connections, click the - \inlineimage plus.png - button to create a new connection. - \image qmldesigner-tutorial-connections.png "Connections tab" - \li Double-click the value in the \uicontrol Target column, and select - \e mouseArea in the list. - \li In the \uicontrol {Signal Handler} column, select \e onClicked. - \li In the \uicontrol Action column, select \e {page.state = 'State1'}. - \li Create two more connections to connect the \c onClicked signal of - \uicontrol mouseArea1 to State2, and that of \uicontrol mouseArea2 - to State3. - \li Press \key {Ctrl+R} to run the application. - \endlist + Then, we connect the \c onClicked signals of the mouse areas to the state + changes: - Click the rectangles to move the Qt logo from one rectangle to another. + \quotefromfile transitions/Page.qml + \skipto Connections { + \printuntil } - If you develop with Qt 6, you must specify the connections as - functions. This is currently not supported in \uicontrol {Connections}, - so you must do it in \uicontrol {Text Editor}. For example: + Because we develop with Qt 6, we must specify the connections as functions. - \code - MouseArea { - id: mouseArea - anchors.fill: parent + \section1 Adding Page to the Main View - Connections { - target: mouseArea - function onClicked() - { - page.state = "State1" - } - } - } - \endcode + We now open \e main.qml for editing and add an instance of the Page custom + component to it: - For more information about the views you used, see: + \quotefromfile transitions/main.qml + \skipto import + \printuntil /^\ {0}\}/ - \list - \li \l States - \li \l{Setting Bindings} - \li \l{Connecting Components to Signals} - \endlist + Press \key {Ctrl+R} to run the application, and click the rectangles to + move the Qt logo from one rectangle to another. \section1 Animating Transitions @@ -321,56 +183,29 @@ the image bounces back when it moves to \e middleRightRect and eases into \e bottomLeftRect. - \list 1 - \li In the \uicontrol {Transition Editor} view, click the - \inlineimage plus.png - button to create a new transition. - \li Click the \inlineimage animation.png - button to specify transitions for switching to each state. - \image qmldesigner-tutorial-transition-settings.png "Transition Settings dialog" - \li In the \uicontrol {Transition ID} field, enter \e toState1. - \li In the \uicontrol From field, select \e State2 and \e State3. - \li In the \uicontrol To field, select \e State1. - \li Click \inlineimage plus.png - to add transitions for switching to \e State2 and \e State3, with - the IDs \e toState2 and \e toState3. - \li Select \uicontrol Close to save the settings and return to - \uicontrol {Transition Editor}. - \li Select \e toState2 in the list of transitions. - \image qmldesigner-tutorial-transitions.png "Transition Editor view" - \li Pull the right edge of the blue bar next to \e icon to frame 1000 - to specify that the x and y coordinates of the image change - linearly over a duration of 1 second. - \li Select the \uicontrol x property, and click - \inlineimage curve_editor.png - to change the easing curve type from linear to easeOutBounce - (\c{[0.233,0.161,0.264,0.997,0.393,0.997,0.522,0.997,0.555,0.752, - 0.61,0.75,0.664,0.748,0.736,1,0.775,1,0.814,0.999,0.861,0.901,0.888, - 0.901,0.916,0.901,0.923,0.995,1,1]}) - in \uicontrol {Easing Curve Editor}. - \image qmldesigner-tutorial-easing-curves.png "Easing Curve Editor" - \li Select the \uicontrol y property and set the easing curve for it, - too. - \li Close \uicontrol {Easing Curve Editor} to return to - \uicontrol {Transition Editor}, and select \e toState3 - in the list of transitions. - \li Pull the right edge of the blue bar next to \e icon to frame 2000 - to specify that the x and y coordinates of the image change - linearly over a duration of 2 seconds. - \li In \uicontrol {Easing Curve Editor}, change the easing curve type - from linear to easeInOutQuad (\c{[0.455,0.03,0.515,0.955,1,1]}). - \li Select \e toState1 in the list of transitions, and pull the blue - bar to frame 200 to specify that the x and y coordinates of the - image change linearly over a duration of 200 milliseconds. - \li Press \key {Ctrl+R} to run the application. - \endlist + We specify transitions for switching from each state to the other two + states: - For more information about the views you used, see: + \quotefromfile transitions/Page.qml + \skipto transitions: + \printuntil }, - \list - \li \l{Editing Easing Curves} - \li \l{Transition Editor} - \endlist + We change the easing curve type for transitions to \e State2 from linear to + \c Easing.OutBounce to create the bounce effect: - Click the rectangles to view the animated transitions. + \printuntil }, + + \note You can use the \l{Previewing Animation} + {Qt Quick Toolbar for animation} to specify the + easing curve type and animation duration. + + \image qml-toolbar-animation.png "Qt Quick Toolbar for animation" + + Then, we change the easing curve type for transitions to \e State2 from + linear to \c Easing.InOutQuad to create the easing effect: + + \printuntil /^\ {0}\}/ + + Press \key {Ctrl+R} to run the application, and click the rectangles to + view the animated transitions. */ diff --git a/doc/qtcreator/src/qtquick/creator-only/qtquick-tutorial-create-empty-project.qdocinc b/doc/qtcreator/src/qtquick/creator-only/qtquick-tutorial-create-empty-project.qdocinc index fad9db2bab4..3eb7e5401fb 100644 --- a/doc/qtcreator/src/qtquick/creator-only/qtquick-tutorial-create-empty-project.qdocinc +++ b/doc/qtcreator/src/qtquick/creator-only/qtquick-tutorial-create-empty-project.qdocinc @@ -46,16 +46,18 @@ \li Select \uicontrol Next (or \uicontrol Continue on \macos) to open the \uicontrol {Define Build System} dialog. - \li In the \uicontrol {Build system} field, select the build system to - use for building and running the project: \l qmake, - \l {Setting Up CMake}{CMake}, or \l {Setting Up Qbs}{Qbs}. + \li In the \uicontrol {Build system} field, select \l {Setting Up CMake} + {CMake} as the build system to use for building and running the + project. + + \note If you select \l qmake, the instructions for configuring the + project won't apply. \li Select \uicontrol Next to open the \uicontrol {Define Project Details} dialog. - \li In the \uicontrol {Screen resolution} field, select the initial - size of the UI. You can easily change the screen size later - in \l Properties. + \li In the \uicontrol {Minimal required Qt version} field, select + Qt 6.2. \li Select \uicontrol Next to open the \uicontrol {Translation File} dialog. @@ -63,9 +65,10 @@ \li Select \uicontrol Next to use the default settings and to open the \uicontrol {Kit Selection} dialog. - \li Select \l{glossary-buildandrun-kit}{kits} for the platforms that - you want to build the application for. To build applications for - mobile devices, select kits for Android ARM and iPhone OS. + \li Select Qt 6.2 or later \l{glossary-buildandrun-kit}{kits} for the + platforms that you want to build the application for. To build + applications for mobile devices, select kits also for Android and + iOS. \note Kits are listed if they have been specified in \uicontrol Tools > \uicontrol Options > \uicontrol Kits (on Windows and Linux) @@ -82,8 +85,7 @@ \endlist For more information about the settings that you skipped and the other - templates available, see \l{Creating Qt Quick Applications}. + wizard templates available, see \l{Creating Qt Quick Applications}. //! [qtquick empty application] */ -Con diff --git a/doc/qtcreator/src/user-interface/creator-open-documents-view.qdoc b/doc/qtcreator/src/user-interface/creator-open-documents-view.qdoc index c64809d8f2b..261c3406136 100644 --- a/doc/qtcreator/src/user-interface/creator-open-documents-view.qdoc +++ b/doc/qtcreator/src/user-interface/creator-open-documents-view.qdoc @@ -26,7 +26,7 @@ /*! \page creator-open-documents-view.html \previouspage creator-file-system-view.html - \nextpage creator-project-managing-workspaces.html + \nextpage creator-output-panes.html \title Open Documents diff --git a/doc/qtcreator/src/user-interface/creator-ui.qdoc b/doc/qtcreator/src/user-interface/creator-ui.qdoc index 7711dbd01f6..e2f31b0c787 100644 --- a/doc/qtcreator/src/user-interface/creator-ui.qdoc +++ b/doc/qtcreator/src/user-interface/creator-ui.qdoc @@ -93,7 +93,6 @@ \li \l{Selecting Modes}{Mode selector} \li \l{Working with Sidebars}{Sidebars} \li \l{Browsing Project Contents}{Views} - \li \l{Managing Workspaces}{Workspaces} \li \l{Viewing Output}{Output panes} \endlist @@ -350,7 +349,7 @@ \previouspage creator-views.html \nextpage creator-highlighting.html \else - \previouspage creator-project-managing-workspaces.html + \previouspage creator-open-documents-view.html \nextpage creator-configuring.html \endif diff --git a/doc/qtcreator/src/user-interface/creator-views.qdoc b/doc/qtcreator/src/user-interface/creator-views.qdoc index 65e44a03a91..65d41d0bbf1 100644 --- a/doc/qtcreator/src/user-interface/creator-views.qdoc +++ b/doc/qtcreator/src/user-interface/creator-views.qdoc @@ -35,7 +35,12 @@ \title Browsing Project Contents You can organize \QC views in \l {Working with Sidebars}{sidebars} or as - \l {Managing Workspaces}{workspaces}, depending on the \l{Selecting Modes} + \if defined(qtdesignstudio) + \l {Managing Workspaces}{workspaces}, + \else + workspaces + \endif + depending on the \l{Selecting Modes} {mode} you are working in. Only views that are relevant to a mode are available in it. diff --git a/doc/qtdesignstudio/images/qmldesigner-tutorial-bindings.png b/doc/qtdesignstudio/images/qmldesigner-tutorial-bindings.png deleted file mode 100644 index ab9e72cd9ee..00000000000 Binary files a/doc/qtdesignstudio/images/qmldesigner-tutorial-bindings.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/qmldesigner-tutorial-connections.png b/doc/qtdesignstudio/images/qmldesigner-tutorial-connections.png deleted file mode 100644 index 7a2eab87362..00000000000 Binary files a/doc/qtdesignstudio/images/qmldesigner-tutorial-connections.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/qmldesigner-tutorial-easing-curves.png b/doc/qtdesignstudio/images/qmldesigner-tutorial-easing-curves.png deleted file mode 100644 index 96cf5687c59..00000000000 Binary files a/doc/qtdesignstudio/images/qmldesigner-tutorial-easing-curves.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/qmldesigner-tutorial-page-component.png b/doc/qtdesignstudio/images/qmldesigner-tutorial-page-component.png deleted file mode 100644 index e73e8370857..00000000000 Binary files a/doc/qtdesignstudio/images/qmldesigner-tutorial-page-component.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/qmldesigner-tutorial-states.png b/doc/qtdesignstudio/images/qmldesigner-tutorial-states.png deleted file mode 100644 index 7c4d44f0ec7..00000000000 Binary files a/doc/qtdesignstudio/images/qmldesigner-tutorial-states.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/qmldesigner-tutorial-topleftrect-layout.png b/doc/qtdesignstudio/images/qmldesigner-tutorial-topleftrect-layout.png deleted file mode 100644 index d05ac96a4dc..00000000000 Binary files a/doc/qtdesignstudio/images/qmldesigner-tutorial-topleftrect-layout.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/qmldesigner-tutorial-topleftrect.png b/doc/qtdesignstudio/images/qmldesigner-tutorial-topleftrect.png deleted file mode 100644 index e935213744f..00000000000 Binary files a/doc/qtdesignstudio/images/qmldesigner-tutorial-topleftrect.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/qmldesigner-tutorial-transition-settings.png b/doc/qtdesignstudio/images/qmldesigner-tutorial-transition-settings.png deleted file mode 100644 index 8bae83bd047..00000000000 Binary files a/doc/qtdesignstudio/images/qmldesigner-tutorial-transition-settings.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/qmldesigner-tutorial-transitions.png b/doc/qtdesignstudio/images/qmldesigner-tutorial-transitions.png deleted file mode 100644 index 548f7ab2d32..00000000000 Binary files a/doc/qtdesignstudio/images/qmldesigner-tutorial-transitions.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/qmldesigner-tutorial-ui-ready.png b/doc/qtdesignstudio/images/qmldesigner-tutorial-ui-ready.png deleted file mode 100644 index e87bfd6b877..00000000000 Binary files a/doc/qtdesignstudio/images/qmldesigner-tutorial-ui-ready.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/qmldesigner-tutorial.png b/doc/qtdesignstudio/images/qmldesigner-tutorial.png deleted file mode 100644 index 1885b4af5b4..00000000000 Binary files a/doc/qtdesignstudio/images/qmldesigner-tutorial.png and /dev/null differ diff --git a/doc/qtcreator/images/qtcreator-workspace-attaching-views.png b/doc/qtdesignstudio/images/qtcreator-workspace-attaching-views.png similarity index 100% rename from doc/qtcreator/images/qtcreator-workspace-attaching-views.png rename to doc/qtdesignstudio/images/qtcreator-workspace-attaching-views.png diff --git a/doc/qtcreator/images/qtcreator-workspace-manager.png b/doc/qtdesignstudio/images/qtcreator-workspace-manager.png similarity index 100% rename from doc/qtcreator/images/qtcreator-workspace-manager.png rename to doc/qtdesignstudio/images/qtcreator-workspace-manager.png diff --git a/doc/qtcreator/images/qtcreator-workspace-new.png b/doc/qtdesignstudio/images/qtcreator-workspace-new.png similarity index 100% rename from doc/qtcreator/images/qtcreator-workspace-new.png rename to doc/qtdesignstudio/images/qtcreator-workspace-new.png diff --git a/doc/qtdesignstudio/images/qtquick-mobile-app-tutorial-binding-editor.png b/doc/qtdesignstudio/images/qtquick-mobile-app-tutorial-binding-editor.png deleted file mode 100644 index 2f759e125fa..00000000000 Binary files a/doc/qtdesignstudio/images/qtquick-mobile-app-tutorial-binding-editor.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/qtquick-mobile-app-tutorial-binding-editor1.png b/doc/qtdesignstudio/images/qtquick-mobile-app-tutorial-binding-editor1.png deleted file mode 100644 index 2b0b4082ef3..00000000000 Binary files a/doc/qtdesignstudio/images/qtquick-mobile-app-tutorial-binding-editor1.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/qtquick-mobile-app-tutorial-bubble-component.png b/doc/qtdesignstudio/images/qtquick-mobile-app-tutorial-bubble-component.png deleted file mode 100644 index 877cc8cdabb..00000000000 Binary files a/doc/qtdesignstudio/images/qtquick-mobile-app-tutorial-bubble-component.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/qtquick-mobile-app-tutorial-custom-properties.png b/doc/qtdesignstudio/images/qtquick-mobile-app-tutorial-custom-properties.png deleted file mode 100644 index 0368c4f8c0d..00000000000 Binary files a/doc/qtdesignstudio/images/qtquick-mobile-app-tutorial-custom-properties.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/qtquick-mobile-app-tutorial-image.png b/doc/qtdesignstudio/images/qtquick-mobile-app-tutorial-image.png deleted file mode 100644 index 3901fb4b0f8..00000000000 Binary files a/doc/qtdesignstudio/images/qtquick-mobile-app-tutorial-image.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/qtquick-mobile-app-tutorial-main-view.png b/doc/qtdesignstudio/images/qtquick-mobile-app-tutorial-main-view.png deleted file mode 100644 index 532bc7330bb..00000000000 Binary files a/doc/qtdesignstudio/images/qtquick-mobile-app-tutorial-main-view.png and /dev/null differ diff --git a/doc/qtcreator/src/user-interface/creator-workspaces.qdoc b/doc/qtdesignstudio/src/views/studio-workspaces.qdoc similarity index 95% rename from doc/qtcreator/src/user-interface/creator-workspaces.qdoc rename to doc/qtdesignstudio/src/views/studio-workspaces.qdoc index 85a4fb78549..444aca6b81d 100644 --- a/doc/qtcreator/src/user-interface/creator-workspaces.qdoc +++ b/doc/qtdesignstudio/src/views/studio-workspaces.qdoc @@ -26,15 +26,11 @@ /*! \page creator-project-managing-workspaces.html \previouspage creator-open-documents-view.html - \if defined(qtdesignstudio) \nextpage creator-project-managing-sessions.html - \else - \nextpage creator-output-panes.html - \endif \title Managing Workspaces - In the Design and Debug modes, you can arrange a set of \QC + In the \uicontrol Design mode, you can arrange a set of \QC views as a \e workspace on the screen. To detach views: diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp index bb80c2e2e1c..bd3994400ba 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp @@ -1221,7 +1221,15 @@ ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QVecto if (instance.isValid()) { QVariant propertyValue = instance.property(propertyName); - if (QMetaType::isRegistered(propertyValue.userType()) && supportedVariantType(propertyValue.type())) { + bool isValid = QMetaType::isRegistered(propertyValue.userType()) + && supportedVariantType(propertyValue.type()); + if (!isValid && propertyValue.userType() == 0) { + // If the property is QVariant type, invalid variant can be a valid value + const QMetaObject *mo = instance.internalObject()->metaObject(); + const int idx = mo->indexOfProperty(propertyName); + isValid = idx >= 0 && mo->property(idx).userType() == QMetaType::QVariant; + } + if (isValid) { valueVector.append(PropertyValueContainer(instance.instanceId(), propertyName, propertyValue, PropertyName())); } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/LineEdit.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/LineEdit.qml index 4e2b1a2c1af..93a0878d377 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/LineEdit.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/LineEdit.qml @@ -76,13 +76,13 @@ StudioControls.TextField { id: colorLogic backendValue: lineEdit.backendValue onValueFromBackendChanged: { - if (colorLogic.valueFromBackend === undefined) - return - - if (writeValueManually) { - lineEdit.text = convertColorToString(colorLogic.valueFromBackend) + if (colorLogic.valueFromBackend === undefined) { + lineEdit.text = "" } else { - lineEdit.text = colorLogic.valueFromBackend + if (writeValueManually) + lineEdit.text = convertColorToString(colorLogic.valueFromBackend) + else + lineEdit.text = colorLogic.valueFromBackend } __dirty = false } diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.6.x.txt b/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.6.x.txt index 66c34759f37..63e7b2e30d9 100644 --- a/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.6.x.txt +++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.6.x.txt @@ -7,17 +7,17 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Qt6 6.2 COMPONENTS Quick REQUIRED) -qt_add_executable(%{ProjectName} +qt_add_executable(%{TargetName} main.cpp ) -qt_add_qml_module(%{ProjectName} +qt_add_qml_module(%{TargetName} URI %{ProjectName} VERSION 1.0 QML_FILES main.qml %{AdditionalQmlFiles} ) -target_compile_definitions(%{ProjectName} +target_compile_definitions(%{TargetName} PRIVATE $<$,$>:QT_QML_DEBUG>) -target_link_libraries(%{ProjectName} +target_link_libraries(%{TargetName} PRIVATE Qt6::Quick) diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/empty/wizard.json b/share/qtcreator/templates/wizards/projects/qtquickapplication/empty/wizard.json index 401fb21e16c..a6f538e1be1 100644 --- a/share/qtcreator/templates/wizards/projects/qtquickapplication/empty/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/empty/wizard.json @@ -27,7 +27,8 @@ { "key": "HasTranslation", "value": "%{JS: value('TsFileName') !== ''}" }, { "key": "SetQPAPhysicalSize", "value": "%{UseVirtualKeyboardByDefault}" }, { "key": "AdditionalQmlFiles", "value": "" }, - { "key": "AdditionalQmlFilesQbs", "value": "" } + { "key": "AdditionalQmlFilesQbs", "value": "" }, + { "key": "TargetName", "value": "%{JS: 'app' + value('ProjectName')}" } ], "pages": diff --git a/src/libs/3rdparty/cplusplus/Control.cpp b/src/libs/3rdparty/cplusplus/Control.cpp index 1c0994604a8..7a40cbba311 100644 --- a/src/libs/3rdparty/cplusplus/Control.cpp +++ b/src/libs/3rdparty/cplusplus/Control.cpp @@ -25,6 +25,9 @@ #include "CoreTypes.h" #include "Symbols.h" #include "Names.h" + +#include + #include #include #include @@ -844,3 +847,15 @@ void Control::addSymbol(Symbol *symbol) { d->symbols.push_back(symbol); } + +const Name *Control::toName(const QList &names) +{ + const Name *n = nullptr; + for (int i = names.size() - 1; i >= 0; --i) { + if (! n) + n = names.at(i); + else + n = qualifiedNameId(names.at(i), n); + } + return n; +} diff --git a/src/libs/3rdparty/cplusplus/Control.h b/src/libs/3rdparty/cplusplus/Control.h index 4a2388f7262..62e51c435cd 100644 --- a/src/libs/3rdparty/cplusplus/Control.h +++ b/src/libs/3rdparty/cplusplus/Control.h @@ -218,6 +218,8 @@ public: bool hasSymbol(Symbol *symbol) const; void addSymbol(Symbol *symbol); + const Name *toName(const QList &names); + private: class Data; friend class Data; diff --git a/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.pro b/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.pro index e9354a2f69a..2c2567c37a0 100644 --- a/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.pro +++ b/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.pro @@ -22,7 +22,6 @@ HEADERS += \ src/lib/format_p.h \ src/lib/htmlhighlighter.h \ src/lib/keywordlist_p.h \ - src/lib/ksyntaxhighlighting_export.h \ src/lib/matchresult_p.h \ src/lib/repository.h \ src/lib/repository_p.h \ diff --git a/src/libs/cplusplus/CppRewriter.cpp b/src/libs/cplusplus/CppRewriter.cpp index ac5b763aec7..14d738da791 100644 --- a/src/libs/cplusplus/CppRewriter.cpp +++ b/src/libs/cplusplus/CppRewriter.cpp @@ -283,8 +283,21 @@ public: number->size())); } } - temps.append(control()->templateNameId(identifier(name->identifier()), name->isSpecialization(), - args.data(), args.size())); + + const FullySpecifiedType ty = rewrite->env->apply(name->identifier(), rewrite); + const Name * const minName = ty->isNamedType() ? ty->asNamedType()->name() : name; + const TemplateNameId * const newTemplateNameId = control()->templateNameId( + identifier(minName->identifier()), name->isSpecialization(), args.data(), + args.size()); + const QList names = disassembledName(minName); + if (names.size() == 1) { + temps.append(newTemplateNameId); + } else { + const Name * const newBaseName = control()->toName(names.mid(0, names.size() - 1)); + const Name * const fullName = control()->qualifiedNameId(newBaseName, + newTemplateNameId); + temps.append(fullName); + } } void visit(const DestructorNameId *name) override @@ -317,6 +330,36 @@ public: // attributes SubstitutionEnvironment *env; RewriteType rewriteType; RewriteName rewriteName; + +private: + static QList disassembledName(const Name *name) + { + class NameDisassembler : public NameVisitor + { + public: + QList names() const { return m_names; } + + void visit(const AnonymousNameId *n) override { m_names << n; } + virtual void visit(const Identifier *n) override { m_names << n; } + virtual void visit(const TemplateNameId *n) override { m_names << n; } + virtual void visit(const DestructorNameId *n) override { m_names << n; } + virtual void visit(const OperatorNameId *n) override { m_names << n; } + virtual void visit(const ConversionNameId *n) override { m_names << n; } + virtual void visit(const SelectorNameId *n) override { m_names << n; } + virtual void visit(const QualifiedNameId *n) override + { + if (n->base()) + n->base()->accept(this); + n->name()->accept(this); + } + private: + QList m_names; + }; + + NameDisassembler nd; + nd.accept(name); + return nd.names(); + } }; SubstitutionEnvironment::SubstitutionEnvironment() diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 3f7e791115c..7fcb3f4caa2 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -241,19 +241,6 @@ static bool symbolIdentical(Symbol *s1, Symbol *s2) return QByteArray(s1->fileName()) == QByteArray(s2->fileName()); } -static const Name *toName(const QList &names, Control *control) -{ - const Name *n = nullptr; - for (int i = names.size() - 1; i >= 0; --i) { - if (! n) - n = names.at(i); - else - n = control->qualifiedNameId(names.at(i), n); - } - - return n; -} - static bool isInlineNamespace(ClassOrNamespace *con, const Name *name) { const QList items = con->find(name); @@ -282,12 +269,12 @@ const Name *LookupContext::minimalName(Symbol *symbol, ClassOrNamespace *target, // eliminate inline namespaces QList minimal = names; for (int i = minimal.size() - 2; i >= 0; --i) { - const Name *candidate = toName(minimal.mid(0, i + 1), control); + const Name *candidate = control->toName(minimal.mid(0, i + 1)); if (isInlineNamespace(target, candidate)) minimal.removeAt(i); } - return toName(minimal, control); + return control->toName(minimal); } return nullptr; diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp index dadf791a61e..e17f140868d 100644 --- a/src/libs/utils/filepath.cpp +++ b/src/libs/utils/filepath.cpp @@ -819,15 +819,6 @@ FilePath FilePath::symLinkTarget() const return FilePath::fromString(info.symLinkTarget()); } -FilePath FilePath::mapToGlobalPath() const -{ - if (needsDevice()) { - QTC_ASSERT(s_deviceHooks.mapToGlobalPath, return {}); - return s_deviceHooks.mapToGlobalPath(*this); - } - return *this; -} - QString FilePath::mapToDevicePath() const { if (needsDevice()) { @@ -1182,11 +1173,11 @@ QString FilePath::calcRelativePath(const QString &absolutePath, const QString &a */ FilePath FilePath::onDevice(const FilePath &deviceTemplate) const { - if (!deviceTemplate.needsDevice()) - return mapToGlobalPath(); const bool sameDevice = m_scheme == deviceTemplate.m_scheme && m_host == deviceTemplate.m_host; + if (sameDevice) + return *this; // TODO: converting paths between different non local devices is still unsupported - QTC_CHECK(!needsDevice() || sameDevice); + QTC_CHECK(!needsDevice()); FilePath res; res.m_scheme = deviceTemplate.m_scheme; res.m_host = deviceTemplate.m_host; diff --git a/src/libs/utils/filepath.h b/src/libs/utils/filepath.h index a83c0aa5177..7cb5b9f2b84 100644 --- a/src/libs/utils/filepath.h +++ b/src/libs/utils/filepath.h @@ -162,9 +162,6 @@ public: QDir::Filters filters = QDir::NoFilter, QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags) const; - [[nodiscard]] FilePath mapToGlobalPath() const; - [[nodiscard]] QString mapToDevicePath() const; - // makes sure that capitalization of directories is canonical // on Windows and macOS. This is rarely needed. [[nodiscard]] FilePath normalizedPathName() const; @@ -194,6 +191,7 @@ private: friend class ::tst_fileutils; static QString calcRelativePath(const QString &absolutePath, const QString &absoluteAnchorPath); void setFromString(const QString &filepath); + [[nodiscard]] QString mapToDevicePath() const; QString m_scheme; QString m_host; diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index c65d8ee95c9..0c6b16e2bc9 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -359,49 +359,89 @@ public: } }; -static QList getAstPath(const AstNode &root, const Range &range) +class AstPathCollector { - QList path; - QList queue{root}; - bool isRoot = true; +public: + AstPathCollector(const AstNode &root, const Range &range) : m_root(root), m_range(range) {} - while (!queue.isEmpty()) { - AstNode curNode = queue.takeFirst(); - if (!isRoot && !curNode.hasRange()) - continue; - if (curNode.range() == range) - return path << curNode; - if (isRoot || curNode.range().contains(range)) { - path << curNode; - const auto children = curNode.children(); - if (!children) - break; - if (curNode.kind() == "Function" || curNode.role() == "expression") { - // Functions and expressions can contain implicit nodes that make the list unsorted. - // They cannot be ignored, as we need to consider them in certain contexts. - // Therefore, the binary search cannot be used here. - queue = *children; - } else { - queue.clear(); + QList collectPath() + { + if (!m_root.isValid()) + return {}; + visitNode(m_root, true); + return m_done ? m_path : m_longestSubPath; + } - // Class and struct nodes can contain implicit constructors, destructors and - // operators, which appear at the end of the list, but whose range is the same - // as the class name. Therefore, we must force them not to compare less to - // anything else. - static const auto leftOfRange = [](const AstNode &node, const Range &range) { - return node.range().isLeftOf(range) && !node.arcanaContains(" implicit "); - }; +private: + void visitNode(const AstNode &node, bool isRoot = false) + { + if (!isRoot && (!node.hasRange() || !node.range().contains(m_range))) + return; + m_path << node; - for (auto it = std::lower_bound(children->cbegin(), children->cend(), range, - leftOfRange); - it != children->cend() && !range.isLeftOf(it->range()); ++it) { - queue << *it; - } + class PathDropper { + public: + PathDropper(AstPathCollector &collector) : m_collector(collector) {}; + ~PathDropper() { + if (m_collector.m_done) + return; + if (m_collector.m_path.size() > m_collector.m_longestSubPath.size()) + m_collector.m_longestSubPath = m_collector.m_path; + m_collector.m_path.removeLast(); + } + private: + AstPathCollector &m_collector; + } pathDropper(*this); + + // Still traverse the children, because they could have the same range. + if (node.range() == m_range) + m_done = true; + + const auto children = node.children(); + if (!children) + return; + + QList childrenToCheck; + if (node.kind() == "Function" || node.role() == "expression") { + // Functions and expressions can contain implicit nodes that make the list unsorted. + // They cannot be ignored, as we need to consider them in certain contexts. + // Therefore, the binary search cannot be used here. + childrenToCheck = *children; + } else { + for (auto it = std::lower_bound(children->cbegin(), children->cend(), m_range, + leftOfRange); + it != children->cend() && !m_range.isLeftOf(it->range()); ++it) { + childrenToCheck << *it; } } - isRoot = false; + + const bool wasDone = m_done; + for (const AstNode &child : qAsConst(childrenToCheck)) { + visitNode(child); + if (m_done && !wasDone) + break; + } } - return path; + + static bool leftOfRange(const AstNode &node, const Range &range) + { + // Class and struct nodes can contain implicit constructors, destructors and + // operators, which appear at the end of the list, but whose range is the same + // as the class name. Therefore, we must force them not to compare less to + // anything else. + return node.range().isLeftOf(range) && !node.arcanaContains(" implicit "); + }; + + const AstNode &m_root; + const Range &m_range; + QList m_path; + QList m_longestSubPath; + bool m_done = false; +}; + +static QList getAstPath(const AstNode &root, const Range &range) +{ + return AstPathCollector(root, range).collectPath(); } static QList getAstPath(const AstNode &root, const Position &pos) @@ -521,8 +561,10 @@ static BaseClientInterface *clientInterface(Project *project, const Utils::FileP const CppEditor::ClangdSettings settings(CppEditor::ClangdProjectSettings(project).settings()); if (!settings.indexingEnabled()) indexingOption += "=0"; - Utils::CommandLine cmd{settings.clangdFilePath(), {indexingOption, "--limit-results=0", - "--clang-tidy=0"}}; + const QString headerInsertionOption = QString("--header-insertion=") + + (settings.autoIncludeHeaders() ? "iwyu" : "never"); + Utils::CommandLine cmd{settings.clangdFilePath(), {indexingOption, headerInsertionOption, + "--limit-results=0", "--clang-tidy=0"}}; if (settings.workerThreadLimit() != 0) cmd.addArg("-j=" + QString::number(settings.workerThreadLimit())); if (!jsonDbDir.isEmpty()) @@ -2332,7 +2374,7 @@ static void semanticHighlighter(QFutureInterface &future, return false; for (auto it = path.rbegin() + 1; it != path.rend(); ++it) { if (it->kind() == "Call" || it->kind() == "CXXConstruct" - || it->kind() == "MemberInitializer") { + || it->kind() == "MemberInitializer" || it->kind() == "CXXOperatorCall") { return true; } if (it->kind().endsWith("Cast") && it->hasConstType()) diff --git a/src/plugins/clangcodemodel/test/clangdtests.cpp b/src/plugins/clangcodemodel/test/clangdtests.cpp index e31cc4d6f55..82e64fad787 100644 --- a/src/plugins/clangcodemodel/test/clangdtests.cpp +++ b/src/plugins/clangcodemodel/test/clangdtests.cpp @@ -1040,7 +1040,7 @@ void ClangdTestHighlighting::test_data() QTest::newRow("typedef as underlying type in enum declaration") << 424 << 21 << 424 << 39 << QList{C_TYPE} << 0; QTest::newRow("argument to user-defined subscript operator") << 434 << 12 << 434 << 17 - << QList{C_PARAMETER} << 0; + << QList{C_PARAMETER, C_OUTPUT_ARGUMENT} << 0; QTest::newRow("partial class template specialization") << 553 << 25 << 553 << 28 << QList{C_TYPE, C_DECLARATION} << 0; QTest::newRow("using declaration for function") << 556 << 10 << 556 << 13 @@ -1237,6 +1237,14 @@ void ClangdTestHighlighting::test_data() << QList{C_LOCAL, C_OUTPUT_ARGUMENT} << 0; QTest::newRow("override attribute") << 186 << 28 << 186 << 36 << QList{C_KEYWORD} << 0; QTest::newRow("final attribute") << 187 << 33 << 187 << 38 << QList{C_KEYWORD} << 0; + QTest::newRow("non-const argument to named lambda") << 827 << 10 << 827 << 13 + << QList{C_LOCAL, C_OUTPUT_ARGUMENT} << 0; + QTest::newRow("const argument to named lambda") << 828 << 10 << 828 << 13 + << QList{C_LOCAL} << 0; + QTest::newRow("non-const argument to unnamed lambda") << 829 << 18 << 829 << 21 + << QList{C_LOCAL, C_OUTPUT_ARGUMENT} << 0; + QTest::newRow("const argument to unnamed lambda") << 830 << 16 << 830 << 19 + << QList{C_LOCAL} << 0; } void ClangdTestHighlighting::test() diff --git a/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp b/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp index d9b08689f12..6e0ed1c8ec8 100644 --- a/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp +++ b/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp @@ -818,3 +818,14 @@ void staticMemberFuncTest() { int i; s.staticFunc(i); } + +void lambdaArgTest() +{ + const auto foo1 = [](int &) {}; + const auto foo2 = [](int) {}; + int val; + foo1(val); + foo2(val); + [](int &) {}(val); + [](int) {}(val); +} diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index f201ab523be..aa78dd534e7 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -144,7 +144,7 @@ MakeInstallCommand CMakeProject::makeInstallCommand(const Target *target, if (bc) buildDirectory = bc->buildDirectory(); - cmd.arguments << "--build" << buildDirectory.onDevice(cmd.command).mapToDevicePath() + cmd.arguments << "--build" << buildDirectory.onDevice(cmd.command).path() << "--target" << installTarget << config; cmd.environment.set("DESTDIR", QDir::toNativeSeparators(installRoot)); diff --git a/src/plugins/cppeditor/cppcodemodelsettings.cpp b/src/plugins/cppeditor/cppcodemodelsettings.cpp index 66c07bed7a1..f6c4629d0c7 100644 --- a/src/plugins/cppeditor/cppcodemodelsettings.cpp +++ b/src/plugins/cppeditor/cppcodemodelsettings.cpp @@ -69,6 +69,7 @@ static QString clangdSettingsKey() { return QLatin1String("ClangdSettings"); } static QString useClangdKey() { return QLatin1String("UseClangd"); } static QString clangdPathKey() { return QLatin1String("ClangdPath"); } static QString clangdIndexingKey() { return QLatin1String("ClangdIndexing"); } +static QString clangdHeaderInsertionKey() { return QLatin1String("ClangdHeaderInsertion"); } static QString clangdThreadLimitKey() { return QLatin1String("ClangdThreadLimit"); } static QString clangdDocumentThresholdKey() { return QLatin1String("ClangdDocumentThreshold"); } static QString clangdUseGlobalSettingsKey() { return QLatin1String("useGlobalSettings"); } @@ -405,6 +406,7 @@ QVariantMap ClangdSettings::Data::toMap() const if (executableFilePath != fallbackClangdFilePath()) map.insert(clangdPathKey(), executableFilePath.toString()); map.insert(clangdIndexingKey(), enableIndexing); + map.insert(clangdHeaderInsertionKey(), autoIncludeHeaders); map.insert(clangdThreadLimitKey(), workerThreadLimit); map.insert(clangdDocumentThresholdKey(), documentUpdateThreshold); return map; @@ -415,6 +417,7 @@ void ClangdSettings::Data::fromMap(const QVariantMap &map) useClangd = map.value(useClangdKey(), false).toBool(); executableFilePath = FilePath::fromString(map.value(clangdPathKey()).toString()); enableIndexing = map.value(clangdIndexingKey(), true).toBool(); + autoIncludeHeaders = map.value(clangdHeaderInsertionKey(), false).toBool(); workerThreadLimit = map.value(clangdThreadLimitKey(), 0).toInt(); documentUpdateThreshold = map.value(clangdDocumentThresholdKey(), 500).toInt(); } diff --git a/src/plugins/cppeditor/cppcodemodelsettings.h b/src/plugins/cppeditor/cppcodemodelsettings.h index c3ae5b72491..5f4f4622c7a 100644 --- a/src/plugins/cppeditor/cppcodemodelsettings.h +++ b/src/plugins/cppeditor/cppcodemodelsettings.h @@ -110,6 +110,7 @@ public: int workerThreadLimit = 0; bool useClangd = false; bool enableIndexing = true; + bool autoIncludeHeaders = false; int documentUpdateThreshold = 500; }; @@ -121,6 +122,7 @@ public: static void setDefaultClangdPath(const Utils::FilePath &filePath); Utils::FilePath clangdFilePath() const; bool indexingEnabled() const { return m_data.enableIndexing; } + bool autoIncludeHeaders() const { return m_data.autoIncludeHeaders; } int workerThreadLimit() const { return m_data.workerThreadLimit; } int documentUpdateThreshold() const { return m_data.documentUpdateThreshold; } @@ -150,6 +152,7 @@ inline bool operator==(const ClangdSettings::Data &s1, const ClangdSettings::Dat && s1.executableFilePath == s2.executableFilePath && s1.workerThreadLimit == s2.workerThreadLimit && s1.enableIndexing == s2.enableIndexing + && s1.autoIncludeHeaders == s2.autoIncludeHeaders && s1.documentUpdateThreshold == s2.documentUpdateThreshold; } inline bool operator!=(const ClangdSettings::Data &s1, const ClangdSettings::Data &s2) diff --git a/src/plugins/cppeditor/cppcodemodelsettingspage.cpp b/src/plugins/cppeditor/cppcodemodelsettingspage.cpp index 1c6621e070b..7a850df329f 100644 --- a/src/plugins/cppeditor/cppcodemodelsettingspage.cpp +++ b/src/plugins/cppeditor/cppcodemodelsettingspage.cpp @@ -197,6 +197,7 @@ class ClangdSettingsWidget::Private public: QCheckBox useClangdCheckBox; QCheckBox indexingCheckBox; + QCheckBox autoIncludeHeadersCheckBox; QSpinBox threadLimitSpinBox; QSpinBox documentUpdateThreshold; Utils::PathChooser clangdChooser; @@ -217,6 +218,9 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD "If background indexing is enabled, global symbol searches will yield\n" "more accurate results, at the cost of additional CPU load when\n" "the project is first opened.")); + d->autoIncludeHeadersCheckBox.setChecked(settings.autoIncludeHeaders()); + d->autoIncludeHeadersCheckBox.setToolTip(tr( + "Controls whether clangd may insert header files as part of symbol completion.")); d->threadLimitSpinBox.setValue(settings.workerThreadLimit()); d->threadLimitSpinBox.setSpecialValueText("Automatic"); d->documentUpdateThreshold.setMinimum(50); @@ -237,6 +241,8 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD formLayout->addRow(QString(), &d->versionWarningLabel); const auto indexingLabel = new QLabel(tr("Enable background indexing:")); formLayout->addRow(indexingLabel, &d->indexingCheckBox); + const auto autoIncludeHeadersLabel = new QLabel(tr("Insert header files on completion:")); + formLayout->addRow(autoIncludeHeadersLabel, &d->autoIncludeHeadersCheckBox); const auto threadLimitLayout = new QHBoxLayout; threadLimitLayout->addWidget(&d->threadLimitSpinBox); threadLimitLayout->addStretch(1); @@ -255,6 +261,8 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD d->clangdChooser.setEnabled(checked); indexingLabel->setEnabled(checked); d->indexingCheckBox.setEnabled(checked); + autoIncludeHeadersLabel->setEnabled(checked); + d->autoIncludeHeadersCheckBox.setEnabled(checked); d->threadLimitSpinBox.setEnabled(checked); d->versionWarningLabel.setEnabled(checked); }; @@ -312,6 +320,8 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD this, &ClangdSettingsWidget::settingsDataChanged); connect(&d->indexingCheckBox, &QCheckBox::toggled, this, &ClangdSettingsWidget::settingsDataChanged); + connect(&d->autoIncludeHeadersCheckBox, &QCheckBox::toggled, + this, &ClangdSettingsWidget::settingsDataChanged); connect(&d->threadLimitSpinBox, qOverload(&QSpinBox::valueChanged), this, &ClangdSettingsWidget::settingsDataChanged); connect(&d->clangdChooser, &Utils::PathChooser::pathChanged, @@ -329,6 +339,7 @@ ClangdSettings::Data ClangdSettingsWidget::settingsData() const data.useClangd = d->useClangdCheckBox.isChecked(); data.executableFilePath = d->clangdChooser.filePath(); data.enableIndexing = d->indexingCheckBox.isChecked(); + data.autoIncludeHeaders = d->autoIncludeHeadersCheckBox.isChecked(); data.workerThreadLimit = d->threadLimitSpinBox.value(); data.documentUpdateThreshold = d->documentUpdateThreshold.value(); return data; diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index 7cfe3206915..5a0e21ad693 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -4707,6 +4707,43 @@ N::S N::foo(const S &s) QuickFixOperationTest(testDocuments, &factory); } +void QuickfixTest::testInsertDefFromDeclAliasTemplateAsReturnType() +{ + QList testDocuments; + + QByteArray original; + QByteArray expected; + + // Header File + original = R"( +struct foo { + struct foo2 { + template using MyType = T; + MyType @bar(); + }; +}; +)"; + expected = original; + testDocuments << CppTestDocument::create("file.h", original, expected); + + // Source File + original = R"( +#include "file.h" +)"; + expected = R"( +#include "file.h" + +foo::foo2::MyType foo::foo2::bar() +{ + +} +)"; + testDocuments << CppTestDocument::create("file.cpp", original, expected); + + InsertDefFromDecl factory; + QuickFixOperationTest(testDocuments, &factory); +} + void QuickfixTest::testInsertDefsFromDecls_data() { QTest::addColumn("headers"); diff --git a/src/plugins/cppeditor/cppquickfix_test.h b/src/plugins/cppeditor/cppquickfix_test.h index 4131c20faf4..0201c5b3bb9 100644 --- a/src/plugins/cppeditor/cppquickfix_test.h +++ b/src/plugins/cppeditor/cppquickfix_test.h @@ -155,6 +155,7 @@ private slots: void testInsertDefFromDeclTemplateFunction(); void testInsertDefFromDeclNotTriggeredForFriendFunc(); void testInsertDefFromDeclMinimalFunctionParameterType(); + void testInsertDefFromDeclAliasTemplateAsReturnType(); void testInsertDefsFromDecls_data(); void testInsertDefsFromDecls(); diff --git a/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp b/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp index c5e1c70ea67..80678ba841e 100644 --- a/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp +++ b/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp @@ -25,32 +25,10 @@ #include "customexecutablerunconfiguration.h" -#include "abi.h" -#include "buildconfiguration.h" #include "devicesupport/devicemanager.h" -#include "environmentaspect.h" #include "localenvironmentaspect.h" -#include "project.h" -#include "runcontrol.h" #include "target.h" -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - using namespace Utils; namespace ProjectExplorer { @@ -86,9 +64,9 @@ CustomExecutableRunConfiguration::CustomExecutableRunConfiguration(Target *targe setDefaultDisplayName(defaultDisplayName()); } -QString CustomExecutableRunConfiguration::rawExecutable() const +FilePath CustomExecutableRunConfiguration::executable() const { - return aspect()->executable().toString(); + return aspect()->executable(); } bool CustomExecutableRunConfiguration::isEnabled() const @@ -116,16 +94,15 @@ Runnable CustomExecutableRunConfiguration::runnable() const QString CustomExecutableRunConfiguration::defaultDisplayName() const { - if (rawExecutable().isEmpty()) + if (executable().isEmpty()) return tr("Custom Executable"); - else - return tr("Run %1").arg(QDir::toNativeSeparators(rawExecutable())); + return tr("Run %1").arg(executable().toUserOutput()); } Tasks CustomExecutableRunConfiguration::checkForIssues() const { Tasks tasks; - if (rawExecutable().isEmpty()) { + if (executable().isEmpty()) { tasks << createConfigurationIssue(tr("You need to set an executable in the custom run " "configuration.")); } diff --git a/src/plugins/projectexplorer/customexecutablerunconfiguration.h b/src/plugins/projectexplorer/customexecutablerunconfiguration.h index d7d90193bc5..c504658796a 100644 --- a/src/plugins/projectexplorer/customexecutablerunconfiguration.h +++ b/src/plugins/projectexplorer/customexecutablerunconfiguration.h @@ -46,7 +46,7 @@ private: Tasks checkForIssues() const override; void configurationDialogFinished(); - QString rawExecutable() const; + Utils::FilePath executable() const; }; class CustomExecutableRunConfigurationFactory : public FixedRunConfigurationFactory diff --git a/src/plugins/projectexplorer/devicesupport/desktopdeviceprocess.cpp b/src/plugins/projectexplorer/devicesupport/desktopdeviceprocess.cpp index 559696e0e8a..0bb27f3435d 100644 --- a/src/plugins/projectexplorer/devicesupport/desktopdeviceprocess.cpp +++ b/src/plugins/projectexplorer/devicesupport/desktopdeviceprocess.cpp @@ -54,7 +54,8 @@ DesktopDeviceProcess::DesktopDeviceProcess(const QSharedPointer & void DesktopDeviceProcess::start(const Runnable &runnable) { QTC_ASSERT(m_process.state() == QProcess::NotRunning, return); - m_process.setEnvironment(runnable.environment); + if (runnable.environment.size()) + m_process.setEnvironment(runnable.environment); m_process.setWorkingDirectory(runnable.workingDirectory); m_process.setCommand(runnable.command); m_process.start(); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp index 6602cf36317..c37549e074a 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp @@ -167,7 +167,7 @@ void PropertyEditorValue::setValue(const QVariant &value) fixAmbigousColorNames(modelNode(), name(), &m_value); fixUrl(modelNode(), name(), &m_value); - if (m_value.isValid() && !colorsEqual) + if (!colorsEqual) emit valueChangedQml(); emit isExplicitChanged(); diff --git a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h index f237bcf0d41..0bb481d22ce 100644 --- a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h +++ b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h @@ -225,6 +225,8 @@ private: // functions void updateWatcher(const QString &path); void updateRotationBlocks(); + void maybeResetOnPropertyChange(const PropertyName &name, const ModelNode &node, + PropertyChangeFlags flags); private: QHash m_imageDataMap; diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index 078a74a534d..3032ac12d94 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -473,8 +473,9 @@ void NodeInstanceView::propertiesAboutToBeRemoved(const QList& resetVerticalAnchors(property.parentModelNode()); } else if (name == "anchors.baseline") { resetVerticalAnchors(property.parentModelNode()); - } else if (name == "shader" && property.parentModelNode().isSubclassOf("QtQuick3D.Shader")) { - m_resetTimer.start(); + } else { + maybeResetOnPropertyChange(name, property.parentModelNode(), + AbstractView::EmptyPropertiesRemoved); } } @@ -503,10 +504,14 @@ void NodeInstanceView::nodeTypeChanged(const ModelNode &, const TypeName &, int, restartProcess(); } -void NodeInstanceView::bindingPropertiesChanged(const QList& propertyList, PropertyChangeFlags /*propertyChange*/) +void NodeInstanceView::bindingPropertiesChanged(const QList& propertyList, + PropertyChangeFlags propertyChange) { QTC_ASSERT(m_nodeInstanceServer, return); m_nodeInstanceServer->changePropertyBindings(createChangeBindingCommand(propertyList)); + + for (const auto &property : propertyList) + maybeResetOnPropertyChange(property.name(), property.parentModelNode(), propertyChange); } /*! @@ -518,18 +523,15 @@ void NodeInstanceView::bindingPropertiesChanged(const QList& pr \sa AbstractProperty, NodeInstance, ModelNode */ -void NodeInstanceView::variantPropertiesChanged(const QList& propertyList, PropertyChangeFlags /*propertyChange*/) +void NodeInstanceView::variantPropertiesChanged(const QList& propertyList, + PropertyChangeFlags propertyChange) { QTC_ASSERT(m_nodeInstanceServer, return); updatePosition(propertyList); m_nodeInstanceServer->changePropertyValues(createChangeValueCommand(propertyList)); - for (const auto &property : propertyList) { - if (property.name() == "shader" && property.parentModelNode().isSubclassOf("QtQuick3D.Shader")) { - m_resetTimer.start(); - break; - } - } + for (const auto &property : propertyList) + maybeResetOnPropertyChange(property.name(), property.parentModelNode(), propertyChange); } /*! Notifies the view that the property parent of the model node \a node has @@ -1908,4 +1910,22 @@ void NodeInstanceView::updateRotationBlocks() } } +void NodeInstanceView::maybeResetOnPropertyChange(const PropertyName &name, const ModelNode &node, + PropertyChangeFlags flags) +{ + bool reset = false; + if (flags & AbstractView::PropertiesAdded + && name == "model" && (node.isSubclassOf("QtQuick.Repeater") + || node.isSubclassOf("QtQuick3D.Repeater3D"))) { + // TODO: This is a workaround for QTBUG-97583 (2D) and QTBUG-97586 (3D): + // Reset puppet when repeater model is first added, if there is already a delegate + if (node.hasProperty("delegate")) + reset = true; + } else if (name == "shader" && node.isSubclassOf("QtQuick3D.Shader")) { + reset = true; + } + if (reset) + resetPuppet(); +} + } diff --git a/src/plugins/remotelinux/abstractpackagingstep.cpp b/src/plugins/remotelinux/abstractpackagingstep.cpp index de41be4da51..2c31b8aa75f 100644 --- a/src/plugins/remotelinux/abstractpackagingstep.cpp +++ b/src/plugins/remotelinux/abstractpackagingstep.cpp @@ -32,9 +32,9 @@ #include #include -#include using namespace ProjectExplorer; +using namespace Utils; namespace RemoteLinux { namespace Internal { @@ -42,8 +42,8 @@ namespace Internal { class AbstractPackagingStepPrivate { public: - QString cachedPackageFilePath; - QString cachedPackageDirectory; + FilePath cachedPackageFilePath; + FilePath cachedPackageDirectory; bool deploymentDataModified = false; }; @@ -67,37 +67,37 @@ AbstractPackagingStep::~AbstractPackagingStep() delete d; } -QString AbstractPackagingStep::cachedPackageFilePath() const +FilePath AbstractPackagingStep::cachedPackageFilePath() const { return d->cachedPackageFilePath; } -QString AbstractPackagingStep::packageFilePath() const +FilePath AbstractPackagingStep::packageFilePath() const { if (packageDirectory().isEmpty()) - return QString(); - return packageDirectory() + QLatin1Char('/') + packageFileName(); + return {}; + return packageDirectory().pathAppended(packageFileName()); } -QString AbstractPackagingStep::cachedPackageDirectory() const +FilePath AbstractPackagingStep::cachedPackageDirectory() const { return d->cachedPackageDirectory; } -QString AbstractPackagingStep::packageDirectory() const +FilePath AbstractPackagingStep::packageDirectory() const { - return buildDirectory().toString(); + return buildDirectory(); } bool AbstractPackagingStep::isPackagingNeeded() const { - QFileInfo packageInfo(packageFilePath()); - if (!packageInfo.exists() || d->deploymentDataModified) + const FilePath packagePath = packageFilePath(); + if (!packagePath.exists() || d->deploymentDataModified) return true; const DeploymentData &dd = target()->deploymentData(); for (int i = 0; i < dd.fileCount(); ++i) { - if (dd.fileAt(i).localFilePath().isNewerThan(packageInfo.lastModified())) + if (dd.fileAt(i).localFilePath().isNewerThan(packagePath.lastModified())) return true; } diff --git a/src/plugins/remotelinux/abstractpackagingstep.h b/src/plugins/remotelinux/abstractpackagingstep.h index f7b2bef28de..681ba70ac00 100644 --- a/src/plugins/remotelinux/abstractpackagingstep.h +++ b/src/plugins/remotelinux/abstractpackagingstep.h @@ -41,8 +41,8 @@ public: explicit AbstractPackagingStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id); ~AbstractPackagingStep() override; - QString packageFilePath() const; - QString cachedPackageFilePath() const; + Utils::FilePath packageFilePath() const; + Utils::FilePath cachedPackageFilePath() const; bool init() override; signals: @@ -54,8 +54,8 @@ protected: void raiseError(const QString &errorMessage); void raiseWarning(const QString &warningMessage); - QString cachedPackageDirectory() const; - QString packageDirectory() const; + Utils::FilePath cachedPackageDirectory() const; + Utils::FilePath packageDirectory() const; virtual bool isPackagingNeeded() const; diff --git a/src/plugins/remotelinux/abstractuploadandinstallpackageservice.cpp b/src/plugins/remotelinux/abstractuploadandinstallpackageservice.cpp index af3a23df947..d02dc82e54a 100644 --- a/src/plugins/remotelinux/abstractuploadandinstallpackageservice.cpp +++ b/src/plugins/remotelinux/abstractuploadandinstallpackageservice.cpp @@ -71,9 +71,9 @@ AbstractUploadAndInstallPackageService::~AbstractUploadAndInstallPackageService( delete d; } -void AbstractUploadAndInstallPackageService::setPackageFilePath(const QString &filePath) +void AbstractUploadAndInstallPackageService::setPackageFilePath(const FilePath &filePath) { - d->packageFilePath = FilePath::fromString(filePath); + d->packageFilePath = filePath; } QString AbstractUploadAndInstallPackageService::uploadDir() const diff --git a/src/plugins/remotelinux/abstractuploadandinstallpackageservice.h b/src/plugins/remotelinux/abstractuploadandinstallpackageservice.h index 2ca0a3dc626..1fedd8686af 100644 --- a/src/plugins/remotelinux/abstractuploadandinstallpackageservice.h +++ b/src/plugins/remotelinux/abstractuploadandinstallpackageservice.h @@ -38,7 +38,7 @@ class REMOTELINUX_EXPORT AbstractUploadAndInstallPackageService : public Abstrac Q_OBJECT public: - void setPackageFilePath(const QString &filePath); + void setPackageFilePath(const Utils::FilePath &filePath); protected: AbstractUploadAndInstallPackageService(); diff --git a/src/plugins/remotelinux/tarpackagecreationstep.cpp b/src/plugins/remotelinux/tarpackagecreationstep.cpp index ef3647d6c58..ed89fb6564f 100644 --- a/src/plugins/remotelinux/tarpackagecreationstep.cpp +++ b/src/plugins/remotelinux/tarpackagecreationstep.cpp @@ -87,11 +87,11 @@ TarPackageCreationStep::TarPackageCreationStep(BuildStepList *bsl, Utils::Id id) m_incrementalDeploymentAspect->setSettingsKey(IncrementalDeploymentKey); setSummaryUpdater([this] { - QString path = packageFilePath(); + FilePath path = packageFilePath(); if (path.isEmpty()) return QString("" + tr("Tarball creation not possible.") + ""); - return QString("" + tr("Create tarball:") + " " + path); + return QString("" + tr("Create tarball:") + " " + path.toUserOutput()); }); } @@ -148,11 +148,12 @@ bool TarPackageCreationStep::doPackage() } // TODO: Optimization: Only package changed files - QFile tarFile(cachedPackageFilePath()); + const FilePath tarFilePath = cachedPackageFilePath(); + QFile tarFile(tarFilePath.toString()); if (!tarFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { raiseError(tr("Error: tar file %1 cannot be opened (%2).") - .arg(QDir::toNativeSeparators(cachedPackageFilePath()), tarFile.errorString())); + .arg(tarFilePath.toUserOutput(), tarFile.errorString())); return false; } @@ -311,7 +312,7 @@ bool TarPackageCreationStep::writeHeader(QFile &tarFile, const QFileInfo &fileIn header.chksum[sizeof header.chksum-1] = 0; if (!tarFile.write(reinterpret_cast(&header), sizeof header)) { raiseError(tr("Error writing tar file \"%1\": %2") - .arg(QDir::toNativeSeparators(cachedPackageFilePath()), tarFile.errorString())); + .arg(cachedPackageFilePath().toUserOutput(), tarFile.errorString())); return false; } return true; diff --git a/src/plugins/updateinfo/updateinfoplugin.cpp b/src/plugins/updateinfo/updateinfoplugin.cpp index 4137848c582..4d393a298bb 100644 --- a/src/plugins/updateinfo/updateinfoplugin.cpp +++ b/src/plugins/updateinfo/updateinfoplugin.cpp @@ -129,16 +129,17 @@ void UpdateInfoPlugin::startCheckForUpdates() { stopCheckForUpdates(); - Utils::Environment env = Utils::Environment::systemEnvironment(); - env.set("QT_LOGGING_RULES", "*=false"); - d->m_checkUpdatesCommand = new ShellCommand({}, env); + d->m_checkUpdatesCommand = new ShellCommand({}, Utils::Environment::systemEnvironment()); d->m_checkUpdatesCommand->setDisplayName(tr("Checking for Updates")); connect(d->m_checkUpdatesCommand, &ShellCommand::stdOutText, this, &UpdateInfoPlugin::collectCheckForUpdatesOutput); connect(d->m_checkUpdatesCommand, &ShellCommand::finished, this, &UpdateInfoPlugin::checkForUpdatesFinished); - d->m_checkUpdatesCommand->addJob({Utils::FilePath::fromString(d->m_maintenanceTool), {"--checkupdates"}}, + d->m_checkUpdatesCommand->addJob({Utils::FilePath::fromString(d->m_maintenanceTool), + {"ch", "-g", "*=false,ifw.package.*=true"}}, 60 * 3, // 3 minutes timeout /*workingDirectory=*/{}, - [](int /*exitCode*/) { return Utils::QtcProcess::FinishedWithSuccess; }); + [](int /*exitCode*/) { + return Utils::QtcProcess::FinishedWithSuccess; + }); d->m_checkUpdatesCommand->execute(); d->m_progress = d->m_checkUpdatesCommand->futureProgress(); if (d->m_progress) { diff --git a/src/shared/clang/clang_installation.pri b/src/shared/clang/clang_installation.pri index 2811f0b2c14..b8055c7b51c 100644 --- a/src/shared/clang/clang_installation.pri +++ b/src/shared/clang/clang_installation.pri @@ -252,8 +252,7 @@ isEmpty(LLVM_VERSION) { # It is not intended for cross compiler linking. LLVM_CXXFLAGS *= $$system($$llvm_config --cxxflags, lines) LLVM_CXXFLAGS ~= s,-fno-exceptions, - LLVM_CXXFLAGS ~= s,-std=c++11, - LLVM_CXXFLAGS ~= s,-std=c++0x, + LLVM_CXXFLAGS ~= s,-std.c\+\+.., LLVM_CXXFLAGS ~= s,-O\S*, LLVM_CXXFLAGS ~= s,/O\S*, LLVM_CXXFLAGS ~= s,/W4, diff --git a/tests/system/objects.map b/tests/system/objects.map index 01e364285d2..60d760a6817 100644 --- a/tests/system/objects.map +++ b/tests/system/objects.map @@ -96,7 +96,7 @@ :New.comboBox_QComboBox {name='comboBox' type='QComboBox' visible='1' window=':New_Core::Internal::NewDialog'} :New.frame_QFrame {name='frame' type='QFrame' visible='1' window=':New_Core::Internal::NewDialog'} :New.templateCategoryView_QTreeView {name='templateCategoryView' type='QTreeView' visible='1' window=':New_Core::Internal::NewDialog'} -:New_Core::Internal::NewDialog {name='Core__Internal__NewDialog' type='Core::Internal::NewDialog' visible='1' windowTitle?='New*'} +:New_Core::Internal::NewDialog {name='Core__Internal__NewDialog' type='Core::Internal::NewDialogWidget' visible='1' windowTitle?='New*'} :New_ProjectExplorer::JsonWizard {type='ProjectExplorer::JsonWizard' unnamed='1' visible='1'} :Next_QPushButton {text~='(Next.*|Continue)' type='QPushButton' visible='1'} :No valid kits found._QLabel {text?='*No suitable kits found.*' type='QLabel' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} @@ -154,7 +154,7 @@ :Qt Creator_Core::Internal::NavComboBox {type='Core::Internal::NavComboBox' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_Core::Internal::ProgressBar {type='Core::Internal::ProgressBar' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_Core::OutputWindow {type='Core::OutputWindow' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} -:Qt Creator_CppEditor::Internal::CPPEditorWidget {type='CppEditor::Internal::CppEditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} +:Qt Creator_CppEditor::Internal::CPPEditorWidget {type='CppEditor::CppEditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_DiffEditor::Internal::DescriptionEditorWidget {type='DiffEditor::Internal::DescriptionEditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_DiffEditor::SideDiffEditorWidget {type='DiffEditor::Internal::SideDiffEditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_DiffEditor::SideDiffEditorWidget2 {occurrence='2' type='DiffEditor::Internal::SideDiffEditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} diff --git a/tests/system/shared/project.py b/tests/system/shared/project.py index ecc1ae98756..e8ee09bda9d 100644 --- a/tests/system/shared/project.py +++ b/tests/system/shared/project.py @@ -276,11 +276,12 @@ def createProject_Qt_Console(path, projectName, checks = True, buildSystem = Non if checks: __verifyFileCreation__(path, expectedFiles) + def createNewQtQuickApplication(workingDir, projectName=None, targets=Targets.desktopTargetClasses(), minimumQtVersion="5.12", - template="Qt Quick Application - Empty", fromWelcome=False, + template="Qt Quick Application", fromWelcome=False, buildSystem=None): - available = __createProjectOrFileSelectType__(" Application (Qt Quick)", template, fromWelcome) + available = __createProjectOrFileSelectType__(" Application (Qt)", template, fromWelcome) projectName = __createProjectSetNameAndPath__(workingDir, projectName) __handleBuildSystem__(buildSystem) requiredQt = __createProjectHandleQtQuickSelection__(minimumQtVersion) diff --git a/tests/system/shared/utils.py b/tests/system/shared/utils.py index dedd43179c2..71427adb03d 100644 --- a/tests/system/shared/utils.py +++ b/tests/system/shared/utils.py @@ -172,6 +172,7 @@ def cleanUpUserFiles(pathsToProFiles=None): doneWithoutErrors = False return doneWithoutErrors + def invokeMenuItem(menu, item, *subItems): if platform.system() == "Darwin": try: @@ -191,10 +192,9 @@ def invokeMenuItem(menu, item, *subItems): activateItem(itemObject) numberedPrefix = "(&\\d \| )?" for subItem in subItems: - sub = itemObject.menu() - waitFor("sub.visible", 1000) # we might have numbered sub items (e.g. "Recent Files") - these have this special prefix if subItem.startswith(numberedPrefix): + # TODO: Find fix for Qt 6 actions = sub.actions() triggered = False for i in range(actions.count()): @@ -211,9 +211,10 @@ def invokeMenuItem(menu, item, *subItems): "Function arguments: '%s', '%s', %s" % (menu, item, str(subItems))) break # we failed to trigger - no need to process subItems further else: - itemObject = waitForObjectItem(sub, subItem) + itemObject = waitForObjectItem(itemObject, subItem) activateItem(itemObject) + def logApplicationOutput(): # make sure application output is shown ensureChecked(":Qt Creator_AppOutput_Core::Internal::OutputPaneToggleButton")