Merge "Merge remote-tracking branch 'origin/5.0'"
@@ -213,9 +213,14 @@ While the plugin builds without it, it might not be fully functional.
|
||||
|
||||
Note that the plugin is disabled by default.
|
||||
|
||||
## Third-party Components
|
||||
# Licenses and Attributions
|
||||
|
||||
Qt Creator includes the following third-party components,
|
||||
Qt Creator is available under commercial licenses from The Qt Company,
|
||||
and under the GNU General Public License version 3,
|
||||
annotated with The Qt Company GPL Exception 1.0.
|
||||
See [LICENSE.GPL-EXCEPT](LICENSE.GPL-EXCEPT) for the details.
|
||||
|
||||
Qt Creator furthermore includes the following third-party components,
|
||||
we thank the authors who made this possible:
|
||||
|
||||
### YAML Parser yaml-cpp (MIT License)
|
||||
|
||||
@@ -22,6 +22,7 @@ Editing
|
||||
* Added menu item and shortcut for editing bookmark comments
|
||||
(QTCREATORBUG-25696)
|
||||
* Fixed folding for Markdown (QTCREATORBUG-25882)
|
||||
* Fixed completion tooltip on secondary display (QTCREATORBUG-26053)
|
||||
|
||||
### C++
|
||||
|
||||
@@ -49,6 +50,7 @@ Editing
|
||||
* Fixed reformatting of functions with default values (QTCREATORBUG-23009)
|
||||
* Fixed wrong warning for types with same name but different namespace
|
||||
(QTCREATORBUG-24615)
|
||||
* Fixed `Tools > External > Qt Quick > QML Utility` (QTCREATORBUG-26137)
|
||||
|
||||
### Language Client
|
||||
|
||||
@@ -56,12 +58,18 @@ Editing
|
||||
* Added support for snippets (QTCREATORBUG-22406)
|
||||
* Fixed completion results for language servers that do not filter results
|
||||
themselves
|
||||
* Fixed that empty responses could be sent (QTCREATORBUG-26116)
|
||||
|
||||
### Beautifier
|
||||
|
||||
* Fixed issue with `clang-format` and multi-byte characters (QTCREATORBUG-21812,
|
||||
QTCREATORBUG-23131)
|
||||
|
||||
### Designer
|
||||
|
||||
* Fixed `Go to Slot` if UI class is referred to as `UI_<class>`
|
||||
(QTCREATORBUG-26013)
|
||||
|
||||
Projects
|
||||
--------
|
||||
|
||||
@@ -76,6 +84,8 @@ Projects
|
||||
* Fixed missing update of run configuration environment (QTCREATORBUG-25947)
|
||||
* Fixed that user files were unnecessarily saved with new time stamp
|
||||
(QTCREATORBUG-25921)
|
||||
* Fixed that toolchain setting was fixed for auto-detected kits
|
||||
(QTCREATORBUG-25839)
|
||||
* Reduced UI freeze after loading projects (QTCREATORBUG-25783)
|
||||
|
||||
### CMake
|
||||
@@ -83,10 +93,15 @@ Projects
|
||||
* Removed option `Auto-create build directories`, making this the default
|
||||
behavior (QTCREATORBUG-25532)
|
||||
* Added CMake output to right side of `Projects` mode (QTCREATORBUG-25522)
|
||||
* Added CMake option `QT_CREATOR_SKIP_PACKAGE_MANAGER_SETUP` for skipping Qt
|
||||
Creator's package manager auto-setup
|
||||
* Fixed `Jump to File` for file names with special characters
|
||||
(QTCREATORBUG-25572)
|
||||
* Fixed updating of available targets (QTCREATORBUG-24914, QTCREATORBUG-25906)
|
||||
* Fixed persistence of CMake tool options (QTCREATORBUG-25911)
|
||||
* Fixed build library search path for CMake 3.20 and later (QTCREATORBUG-26110)
|
||||
* Fixed code model issues with MSVC and CMake 3.20 and later
|
||||
(QTCREATORBUG-26146)
|
||||
|
||||
### Qbs
|
||||
|
||||
@@ -144,6 +159,11 @@ Platforms
|
||||
* Fixed detection of `_prepare_apk_dir` target for CMake projects
|
||||
(QTCREATORBUG-25216)
|
||||
|
||||
### Remote Linux
|
||||
|
||||
* Fixed update of temporary local installation when build path is changed
|
||||
(QTCREATORBUG-26103)
|
||||
|
||||
### QNX
|
||||
|
||||
* Fixed device configuration
|
||||
|
||||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 65 KiB |
@@ -38,9 +38,9 @@
|
||||
the components available on MCUs are displayed in \l Library >
|
||||
\uicontrol Components. Only a subset of properties is supported for the
|
||||
supported components. The properties that are not available on MCUs are
|
||||
marked in the \l Properties view by enclosing them in square brackets.
|
||||
marked in the \l Properties view with strikethrough text.
|
||||
|
||||
\image qmldesigner-mcu-support.png "Components and Image properties supported for MCUs"
|
||||
\image qmldesigner-mcu-support.png "Components and Text properties supported for MCUs"
|
||||
|
||||
For more information about the supported components and their properties,
|
||||
see \l{Qt for MCUs - All QML Types}.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Creator documentation.
|
||||
@@ -93,174 +93,151 @@
|
||||
|
||||
\section1 Selecting Project Type
|
||||
|
||||
You can use wizards to create following types of projects:
|
||||
|
||||
\list
|
||||
|
||||
\li Application (Qt Quick)
|
||||
|
||||
\list
|
||||
\li Qt Quick Application - Empty
|
||||
|
||||
Create an empty \l{Qt Quick} application that uses Qt Quick 2
|
||||
types.
|
||||
|
||||
You can build the application and deploy it to desktop,
|
||||
embedded, and mobile target platforms.
|
||||
|
||||
\li Qt Quick Application - Scroll, Stack, or Swipe
|
||||
|
||||
Create a Qt Quick application that uses \l{Qt Quick Controls} to
|
||||
implement a scrollable list (requires Qt 5.9 or later) or a set
|
||||
of pages with a stack-based or swipe-based navigation model
|
||||
(requires Qt 5.7 or later).
|
||||
\endlist
|
||||
|
||||
\li Application (Qt)
|
||||
|
||||
\list
|
||||
The following table lists the wizard templates for creating projects.
|
||||
|
||||
\table
|
||||
\header
|
||||
\li Category
|
||||
\li Wizard Template
|
||||
\li Purpose
|
||||
\row
|
||||
\li Application (Qt for MCU)
|
||||
\li MCU Support Application
|
||||
\li Creates an application that uses a subset of Qt QML and
|
||||
Qt Quick Controls types (as supported by Qt for MCUs) that
|
||||
you can deploy, run, and debug on MCU boards. For more
|
||||
information, see \l {Connecting MCUs}.
|
||||
\row
|
||||
\li {1,2} Application (Qt)
|
||||
\li Qt Widgets Application
|
||||
|
||||
Use \QD forms to design a Qt widget based user interface for the
|
||||
desktop and C++ to implement the application logic
|
||||
|
||||
\li Uses \QD forms to design a Qt widget based user interface for
|
||||
the desktop and C++ to implement the application logic.
|
||||
\row
|
||||
\li Qt Console Application
|
||||
|
||||
Use a single main.cpp file
|
||||
\endlist
|
||||
|
||||
\li Application (Qt for Python)
|
||||
|
||||
\list
|
||||
|
||||
\li Qt for Python Application - Empty, Window, Window (UI file), or
|
||||
Qt Quick Application (Empty)
|
||||
|
||||
Create a \l{https://doc.qt.io/qtforpython/index.html}
|
||||
\li Uses a single main.cpp file.
|
||||
\row
|
||||
\li {1,4} Application (Qt Quick)
|
||||
\li Qt Quick Application - Empty
|
||||
\li Creates a Qt Quick 2 application project that can contain both
|
||||
QML and C++ code. You can build the application and deploy it
|
||||
to desktop, embedded, and mobile target platforms.
|
||||
\row
|
||||
\li Qt Quick Application - Scroll
|
||||
\li Uses the \l{ScrollView} component to implement a scrollable
|
||||
list view (requires Qt 5.9 or later).
|
||||
\row
|
||||
\li Qt Quick Application - Stack
|
||||
\li Uses the \l{StackView} component to implement a set of pages
|
||||
with a stack-based navigation model (requires Qt 5.7 or later).
|
||||
\row
|
||||
\li Qt Quick Application - Swipe
|
||||
\li Uses the \l{SwipeView} component to implement a set of pages
|
||||
with a swipe-based navigation model (requires Qt 5.7 or later).
|
||||
\row
|
||||
\li {1,4} Application (Qt for Python)
|
||||
\li Qt for Python - Empty
|
||||
\li Creates a \l{https://doc.qt.io/qtforpython/index.html}
|
||||
{Qt for Python} application that contains only the main
|
||||
code for a QApplication or an empty window with or without
|
||||
a widget-based UI. Alternatively, you can create an empty
|
||||
Qt Quick Application.
|
||||
|
||||
\endlist
|
||||
|
||||
\li Application (Qt for MCU)
|
||||
|
||||
\list
|
||||
\li MCU Support Application
|
||||
|
||||
Creates an application that uses a subset of Qt QML and
|
||||
Qt Quick Controls types (as supported by Qt for MCUs) that
|
||||
you can deploy, run, and debug on MCU boards. For more
|
||||
information, see \l {Connecting MCUs}.
|
||||
\endlist
|
||||
|
||||
\li Libraries
|
||||
|
||||
\list
|
||||
|
||||
code for a QApplication.
|
||||
\row
|
||||
\li Qt for Python - Window
|
||||
\li Creates a Qt for Python application that contains an empty
|
||||
window.
|
||||
\row
|
||||
\li Qt for Python - Window (UI file)
|
||||
\li Creates a Qt for Python application that contains an empty
|
||||
window with a widget-based UI.
|
||||
\row
|
||||
\li Qt for Python - Qt Quick Application
|
||||
\li Creates a Python project that contains an empty Qt Quick
|
||||
Application.
|
||||
\row
|
||||
\li {1,3} Library
|
||||
\li C++ Library
|
||||
|
||||
Shared or static C++ library based on qmake
|
||||
|
||||
\li A shared or static C++ library based on qmake.
|
||||
\row
|
||||
\li Qt Quick 2 Extension Plugin
|
||||
|
||||
C++ plugin that makes it possible to offer extensions that can
|
||||
be loaded dynamically into Qt Quick 2 applications by using the
|
||||
QQmlEngine class
|
||||
|
||||
\li Creates a C++ plugin that makes it possible to offer extensions
|
||||
that can be loaded dynamically into Qt Quick 2 applications
|
||||
by using the QQmlEngine class.
|
||||
\row
|
||||
\li \QC Plugin
|
||||
|
||||
|
||||
\endlist
|
||||
|
||||
\li Other Projects
|
||||
|
||||
\list
|
||||
|
||||
\li Auto Test Project
|
||||
|
||||
Projects with boilerplate code for a Qt or Google test. For more
|
||||
information, see \l {Creating Tests}.
|
||||
|
||||
\li Creates a \QC plugin.
|
||||
\row
|
||||
\li {1,6} Other Project
|
||||
\li Qt Custom Designer Widget
|
||||
\li Creates a custom \QD widget or widget collection.
|
||||
\row
|
||||
\li Qt Quick UI Prototype
|
||||
\li Creates a \l{Creating Qt Quick UI Projects}{Qt Quick UI project}
|
||||
with a single QML file that contains the main view. You can
|
||||
preview Qt Quick 2 UI projects in the
|
||||
\l{Validating with Target Hardware}{QML Scene preview tool}.
|
||||
You do not need to build them, because they do not contain any
|
||||
C++ code.
|
||||
|
||||
Use a single QML file that contains the main view. You can
|
||||
review \l{Creating Qt Quick UI Projects}{Qt Quick UI prototypes}
|
||||
in a \l{Previewing QML Files}{preview tool} and you need not
|
||||
build them. Qt Quick UI prototypes cannot be deployed to embedded
|
||||
or mobile target platforms. For those platforms, create a
|
||||
Qt Quick application instead.
|
||||
|
||||
\li Qt Custom Designer Widgets
|
||||
|
||||
Custom \QD widget or widget collection
|
||||
|
||||
\li Empty qmake Project
|
||||
|
||||
Empty qmake project that is based on qmake but does not use any
|
||||
default classes
|
||||
Use this template only if you are prototyping. You cannot create
|
||||
a full application by using this template.
|
||||
|
||||
Qt Quick UI projects cannot be deployed to embedded or mobile
|
||||
target platforms. For those platforms, create a Qt Quick
|
||||
application instead.
|
||||
\row
|
||||
\li Auto Test Project
|
||||
\li Creates a project with boilerplate code for a Qt or Google
|
||||
test. For more information, see \l {Creating Tests}.
|
||||
\row
|
||||
\li Subdirs Project
|
||||
|
||||
Subprojects that enable you to structure your qmake projects as
|
||||
a tree hierarchy
|
||||
|
||||
\li Creates a subproject that enables you to structure your qmake
|
||||
projects as a tree hierarchy.
|
||||
\row
|
||||
\li Empty qmake Project
|
||||
\li Creates an empty qmake project that is based on qmake but does
|
||||
not use any default classes.
|
||||
\row
|
||||
\li Code Snippet
|
||||
|
||||
Creates a qmake project from a code snippet. When fixing bug
|
||||
\li Creates a qmake project from a code snippet. When fixing bug
|
||||
reports that contain a code snippet, you can place the code
|
||||
snippet into a project to compile and check it.
|
||||
|
||||
\endlist
|
||||
|
||||
\li Non-Qt Projects
|
||||
|
||||
\list
|
||||
|
||||
\li Plain C or C++ Application
|
||||
|
||||
Plain C or C++ application that uses qmake, Qbs, or CMake but does
|
||||
not use the Qt library
|
||||
|
||||
\li Nim or Nimble Applications (experimental)
|
||||
|
||||
Nim or Nimble application that uses Nimble, but does not use
|
||||
the Qt library
|
||||
|
||||
For more information, see \l {Setting Up Nimble}.
|
||||
|
||||
\endlist
|
||||
|
||||
\li Import Project
|
||||
|
||||
\list
|
||||
|
||||
\li Project from version control
|
||||
|
||||
Import a project from a supported version control system. For more
|
||||
information on how version control systems are integrated in
|
||||
\QC, see \l{Using Version Control Systems}
|
||||
|
||||
\li Import as qmake Project
|
||||
|
||||
Import an existing project that does not use any of the supported
|
||||
build systems: qmake, Qbs, CMake, or Autotools. The wizard creates
|
||||
a qmake .pro file, which enables you to use \QC as a code editor and
|
||||
as a launcher for debugging and analysis tools. However, if you want
|
||||
to build the project, you might need to edit the generated .pro
|
||||
file.
|
||||
|
||||
\li Import Existing Project
|
||||
|
||||
Import an existing project that does not use any of the supported
|
||||
build systems: qmake, Qbs, CMake, or Autotools. This enables you to
|
||||
use \QC as a code editor
|
||||
|
||||
\endlist
|
||||
|
||||
\endlist
|
||||
\row
|
||||
\li {1,4} Non-Qt Project
|
||||
\li Plain C Application
|
||||
\li Creates a plain C application that uses qmake, Qbs, or CMake
|
||||
but does not use the Qt library.
|
||||
\row
|
||||
\li Plain C++ Application
|
||||
\li Creates a plain C++ application that uses qmake, Qbs, or CMake
|
||||
but does not use the Qt library.
|
||||
\row
|
||||
\li Nim Application (experimental)
|
||||
\li Creates a Nim application that uses Nimble, but does not use the
|
||||
Qt library. For more information, see \l {Setting Up Nimble}.
|
||||
\row
|
||||
\li Nimble Application (experimental)
|
||||
\li Creates a Nimble application that uses Nimble, but does not use
|
||||
the Qt library. For more information, see
|
||||
\l {Setting Up Nimble}.
|
||||
\row
|
||||
\li {1,3} Import Project
|
||||
\li Project from version control
|
||||
\li Imports a project from a supported version control system, such
|
||||
as Bazaar, CVS, Git, Mercurial, or Subversion. For
|
||||
more information on how version control systems are integrated
|
||||
in \QC, see \l{Using Version Control Systems}.
|
||||
\row
|
||||
\li Import as qmake or CMake Project (Limited Functionality)
|
||||
\li Imports an existing project that does not use any of the
|
||||
supported build systems: qmake, Qbs, CMake, or Autotools. The
|
||||
template creates a project file, which enables you to use
|
||||
\QC as a code editor and as a launcher for debugging and
|
||||
analysis tools. However, if you want to build the project,
|
||||
you might need to edit the generated project file.
|
||||
\row
|
||||
\li Import Existing Project
|
||||
\li Imports an existing project that does not use any of the
|
||||
supported build systems: qmake, Qbs, CMake, or Autotools.
|
||||
This enables you to use \QC as a code editor.
|
||||
\endtable
|
||||
|
||||
To create a new project, select \uicontrol File > \uicontrol{New File or Project} and
|
||||
select the type of your project. The contents of the wizard dialogs depend
|
||||
@@ -278,93 +255,118 @@
|
||||
\section1 Adding Files to Projects
|
||||
|
||||
You can use wizards also to add individual files to your projects.
|
||||
You can create the following types of files:
|
||||
The following table lists the wizard templates for creating files.
|
||||
|
||||
\list
|
||||
|
||||
\li C/C++
|
||||
|
||||
C or C++ source and header files
|
||||
|
||||
\li Qt
|
||||
|
||||
\list
|
||||
|
||||
\li Qt item model source and header files that you can use to create
|
||||
classes derived from QAbstractItemModel, QAbstractTableModel, or
|
||||
QAbstractListModel.
|
||||
|
||||
\li \QD forms and \QD form classes, which specify parts of user
|
||||
interfaces in Qt widget based projects
|
||||
|
||||
\li Qt resource files, which allow you to store binary files in the
|
||||
application executable
|
||||
|
||||
\li QML files, which specify items in Qt Quick projects.
|
||||
\uicontrol {QML File (Qt Quick 2)} creates a QML file that imports
|
||||
Qt Quick 2.0, and \uicontrol {Qt Quick UI File} creates a
|
||||
\l{UI Files}{UI file} (\e .ui.qml) and the corresponding
|
||||
implementation file (\e .qml).
|
||||
|
||||
\li JavaScript files that you can use to write the application logic in
|
||||
Qt Quick projects
|
||||
|
||||
\endlist
|
||||
|
||||
\li Models and state charts
|
||||
|
||||
\list
|
||||
|
||||
\li Universal Modeling Language (UML) style models with structured
|
||||
diagrams. However, the model editor uses a variant of UML and
|
||||
\table
|
||||
\header
|
||||
\li Category
|
||||
\li Wizard Template
|
||||
\li Purpose
|
||||
\row
|
||||
\li {1,3} C/C++
|
||||
\li C++ Class
|
||||
\li C++ header and source file for a new class that you can add to
|
||||
a C++ project.
|
||||
\row
|
||||
\li C/C++ Source File
|
||||
\li C++ source file that you can add to a C++ project.
|
||||
\row
|
||||
\li C/C++ Header File
|
||||
\li C++ header file that you can add to a C++ project.
|
||||
\row
|
||||
\li {1,3} Modeling
|
||||
\li State Chart
|
||||
\li State Chart XML (SCXML) file that contains boilerplate
|
||||
code for state machines. You can use the classes in the
|
||||
\l {Qt SCXML} module to embed state machines created from
|
||||
the files in Qt applications.
|
||||
\row
|
||||
\li Model
|
||||
\li Universal Modeling Language (UML) style model with a structured
|
||||
diagram. However, the model editor uses a variant of UML and
|
||||
provides only a subset of properties for specifying the
|
||||
appearance of model elements. For more information, see
|
||||
\l {Modeling}.
|
||||
|
||||
\li State Chart XML (SCXML) files that contain boilerplate code for
|
||||
state machines. You can use the classes in the \l {Qt SCXML}
|
||||
module to embed state machines created from the files in Qt
|
||||
applications.
|
||||
|
||||
\endlist
|
||||
|
||||
\li GLSL
|
||||
|
||||
GLSL files that define fragment and vertex shaders in both Qt Quick
|
||||
projects and Qt widget based projects
|
||||
|
||||
\li General
|
||||
|
||||
\list
|
||||
|
||||
\li Empty files
|
||||
|
||||
\li Scratch buffers that use temporary files. You can create this
|
||||
type of files for temporarily storing information that you do
|
||||
not intend to save
|
||||
|
||||
\endlist
|
||||
|
||||
\li Java
|
||||
|
||||
Java class files that you can use to create Java classes.
|
||||
|
||||
\li Python
|
||||
|
||||
Python class and source files that you can use to create Python
|
||||
classes and scripts with UTF-8 encoding.
|
||||
|
||||
\li Nim (experimental)
|
||||
|
||||
\list
|
||||
|
||||
\li Nim script files.
|
||||
|
||||
\li Nim source files with UTF-8 encoding.
|
||||
|
||||
\endlist
|
||||
|
||||
\endlist
|
||||
\row
|
||||
\li Scratch Model
|
||||
\li Scratch model using a temporary file.
|
||||
\row
|
||||
\li {1,7} Qt
|
||||
\li Qt Item Model
|
||||
\li Source and header files that you can use to create classes
|
||||
derived from QAbstractItemModel, QAbstractTableModel, or
|
||||
QAbstractListModel.
|
||||
\row
|
||||
\li \QD Form Class
|
||||
\li \QD form and a matching class for implementing a UI based
|
||||
on Qt widgets.
|
||||
\row
|
||||
\li \QD Form
|
||||
\li \QD form for Qt widget based projects. This is useful
|
||||
if you already have an existing class for the UI logic.
|
||||
\row
|
||||
\li Qt Resource File
|
||||
\li Resource file for storing binary files in the application
|
||||
executable.
|
||||
\row
|
||||
\li QML File (Qt Quick 2)
|
||||
\li QML file that imports Qt Quick 2.0 for use in Qt Quick projects.
|
||||
\row
|
||||
\li Qt Quick UI File
|
||||
\li \l{UI Files}{UI file} (\e .ui.qml) and the corresponding
|
||||
implementation file (\e .qml) for use in Qt Quick projects.
|
||||
\row
|
||||
\li JS File
|
||||
\li JavaScript file that you can use to write the application logic
|
||||
in Qt Quick projects.
|
||||
\row
|
||||
\li {1,4} GLSL
|
||||
\li Fragment Shader (OpenGL/ES 2.0)
|
||||
\li Fragment shader that generates the final pixel colors for
|
||||
triangles, points, and lines rendered with OpenGL. You can use
|
||||
it in both Qt Quick projects and Qt widget based projects.
|
||||
\row
|
||||
\li Vertex Shader (OpenGL/ES 2.0)
|
||||
\li Vertex shader that transforms the positions, normals, and
|
||||
texture coordinates of triangles, points, and lines rendered
|
||||
with OpenGL. You can use it in both Qt Quick projects and Qt
|
||||
widget based projects.
|
||||
\row
|
||||
\li Fragment Shader (Desktop OpenGL)
|
||||
\li Fragment shader for use in both Qt Quick projects and Qt
|
||||
widget based projects.
|
||||
\row
|
||||
\li Vertex Shader (Desktop OpenGL)
|
||||
\li Vertex shader for use in both Qt Quick projects and Qt
|
||||
widget based projects.
|
||||
\row
|
||||
\li {1,2} General
|
||||
\li Empty File
|
||||
\li Empty file that you can save with any filename extensio.
|
||||
\row
|
||||
\li Scratch Buffer
|
||||
\li Scratch buffer that uses temporary files. You can
|
||||
create this type of files for temporarily storing information
|
||||
that you do not intend to save
|
||||
\row
|
||||
\li Java
|
||||
\li Java File
|
||||
\li Java class files that you can use to create Java classes.
|
||||
\row
|
||||
\li {1,2} Python
|
||||
\li Python Class
|
||||
\li Python class file.
|
||||
\row
|
||||
\li Python File
|
||||
\li Python script file using UTF-8 encoding.
|
||||
\row
|
||||
\li {1,2} Nim (experimental)
|
||||
\li Nim Script File
|
||||
\li Empty Nim script file using UTF-8 encoding.
|
||||
\row
|
||||
\li Nim File
|
||||
\li Empty Nim source file using UTF-8 encoding.
|
||||
\endtable
|
||||
|
||||
\section2 Creating C++ Classes
|
||||
|
||||
|
||||
@@ -132,6 +132,7 @@
|
||||
\li \l{Animations}
|
||||
\li \l{3D Views}
|
||||
\li \l{Group}
|
||||
\li \l{Skeletal Animation}
|
||||
\li \l{3D Models}
|
||||
\li \l{Materials and Shaders}
|
||||
\li \l{Textures}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Creator documentation.
|
||||
@@ -38,55 +38,59 @@
|
||||
|
||||
\image qmldesigner-new-project.png "New File or Project dialog"
|
||||
|
||||
When you create a new Qt Quick project from scratch, you have the following
|
||||
options:
|
||||
The following table lists the wizard templates for creating a new
|
||||
Qt Quick project from scratch.
|
||||
|
||||
\list
|
||||
\li \uicontrol {Application (Qt Quick)}:
|
||||
\table
|
||||
\header
|
||||
\li Category
|
||||
\li Wizard Template
|
||||
\li Purpose
|
||||
\row
|
||||
\li {1,4} Application (Qt Quick)
|
||||
\li Qt Quick Application - Empty
|
||||
\li Creates a Qt Quick 2 application project that can contain both
|
||||
QML and C++ code. You can build the application and deploy it
|
||||
to desktop, embedded, and mobile target platforms.
|
||||
\row
|
||||
\li Qt Quick Application - Scroll
|
||||
\li Uses the \l{ScrollView} component to implement a scrollable
|
||||
list view (requires Qt 5.9 or later).
|
||||
\row
|
||||
\li Qt Quick Application - Stack
|
||||
\li Uses the \l{StackView} component to implement a set of pages
|
||||
with a stack-based navigation model (requires Qt 5.7 or later).
|
||||
\row
|
||||
\li Qt Quick Application - Swipe
|
||||
\li Uses the \l{SwipeView} component to implement a set of pages
|
||||
with a swipe-based navigation model (requires Qt 5.7 or later).
|
||||
\row
|
||||
\li Application (Qt for Python)
|
||||
\li Qt for Python - Qt Quick Application
|
||||
\li Creates a Python project that contains an empty Qt Quick
|
||||
Application.
|
||||
\row
|
||||
\li Other Project
|
||||
\li Qt Quick UI Prototype
|
||||
\li Creates a \l{Creating Qt Quick UI Projects}{Qt Quick UI project}
|
||||
with a single QML file that contains the main view. You can
|
||||
preview Qt Quick 2 UI projects in the
|
||||
\l{Validating with Target Hardware}{QML Scene preview tool}.
|
||||
You do not need to build them, because they do not contain any
|
||||
C++ code.
|
||||
|
||||
\list
|
||||
Use this template only if you are prototyping. You cannot create
|
||||
a full application by using this template.
|
||||
|
||||
\li \uicontrol {Qt Quick Application - Empty} creates a Qt Quick 2
|
||||
application project that can contain both QML and C++ code. You can
|
||||
build the application and deploy it to desktop, embedded, and mobile
|
||||
target platforms.
|
||||
|
||||
\li \uicontrol {Qt Quick Application - Scroll} uses the
|
||||
\l{ScrollView} component to implement a scrollable list view
|
||||
(requires Qt 5.9 or later).
|
||||
|
||||
\li \uicontrol {Qt Quick Application - Stack} uses the
|
||||
\l{StackView} component to implement a set of pages with a stack-based
|
||||
navigation model (requires Qt 5.7 or later).
|
||||
|
||||
\li \uicontrol {Qt Quick Application - Swipe} uses the
|
||||
\l{SwipeView} component to implement a set of pages with a swipe-based
|
||||
navigation model (requires Qt 5.7 or later).
|
||||
|
||||
\endlist
|
||||
|
||||
\li \uicontrol {Application (Qt for Python)} >
|
||||
\uicontrol {Qt for Python - Qt Quick Application - Empty} creates a
|
||||
Python project that contains an empty Qt Quick Application.
|
||||
|
||||
\li \uicontrol {Other Project} > \uicontrol {Qt Quick UI Prototype}
|
||||
creates a \l{Creating Qt Quick UI Projects}{Qt Quick UI project}
|
||||
with a single QML file that
|
||||
contains the main view. You can review Qt Quick 2 UI projects in the
|
||||
\l{Previewing QML Files}{QML Scene preview tool}. You do not need to
|
||||
build them, because they do not contain any C++ code.
|
||||
Use this only if you are prototyping. You cannot create a full application
|
||||
with this.
|
||||
|
||||
Qt Quick UI projects cannot be deployed to embedded or mobile
|
||||
target platforms. For those platforms, create a Qt Quick application
|
||||
instead.
|
||||
|
||||
\li \uicontrol Library > \uicontrol {Qt Quick 2 Extension Plugin}
|
||||
creates C++ plugins that make it possible to offer extensions that
|
||||
can be loaded dynamically into Qt Quick 2 applications.
|
||||
|
||||
\endlist
|
||||
Qt Quick UI projects cannot be deployed to embedded or mobile
|
||||
target platforms. For those platforms, create a Qt Quick
|
||||
application instead.
|
||||
\row
|
||||
\li Library
|
||||
\li Qt Quick 2 Extension Plugin
|
||||
\li Creates C++ plugins that make it possible to offer extensions
|
||||
that can be loaded dynamically into Qt Quick 2 applications.
|
||||
\endtable
|
||||
|
||||
\note The SDK for a particular target platform might install additional
|
||||
templates for that platform. For example, the QNX templates are installed
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
\list
|
||||
\li \l {3D Views}
|
||||
\li \l {Group}
|
||||
\li \l {Skeletal Animation}
|
||||
\li \l {3D Models}
|
||||
\li \l {Materials and Shaders}
|
||||
\li \l {Textures}
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
\li \l Animations
|
||||
\li \l{3D Views}
|
||||
\li \l{Group}
|
||||
\li \l{Skeletal Animation}
|
||||
\li \l{3D Models}
|
||||
\li \l{Materials and Shaders}
|
||||
\li \l{Textures}
|
||||
|
||||
@@ -195,15 +195,32 @@
|
||||
\uicontrol {Distribute spacing} field to determine whether
|
||||
it is distributed evenly within a target area or at
|
||||
specified distances, calculated from a starting point.
|
||||
|
||||
You can select the orientation in which the components are distributed
|
||||
evenly within the target area: horizontally along the x axis or vertically
|
||||
along the y axis.
|
||||
|
||||
Alternatively, you can distribute spacing in pixels by selecting one of the
|
||||
starting point buttons: top-left or bottom-right edge of the target area,
|
||||
or its center. Note that some components might end up outside the target
|
||||
area.
|
||||
starting point buttons: top/left or bottom/right edge of the target area or
|
||||
item, or its center. The edge to use depends on whether the items are
|
||||
distributed horizontally or vertically:
|
||||
|
||||
\list
|
||||
\li Select \inlineimage icons/distribute-origin-top-left.png
|
||||
and \inlineimage icons/distribute-spacing-horizontal.png
|
||||
to use the left edge of the target area or item as the starting
|
||||
point.
|
||||
\li Select \inlineimage icons/distribute-origin-top-left.png
|
||||
and \inlineimage icons/distribute-spacing-vertical.png
|
||||
to use the top edge.
|
||||
\li Select \inlineimage icons/distribute-origin-bottom-right.png
|
||||
and \inlineimage icons/distribute-spacing-horizontal.png
|
||||
to use the right edge.
|
||||
\li Select \inlineimage icons/distribute-origin-bottom-right.png
|
||||
and \inlineimage icons/distribute-spacing-vertical.png
|
||||
to use the bottom edge.
|
||||
\endlist
|
||||
|
||||
\note Some components might end up outside the target area.
|
||||
|
||||
In the \uicontrol {Pixel spacing} field, you can set the space between
|
||||
components in pixels. You can disable the distribution of spacing in
|
||||
@@ -273,16 +290,18 @@
|
||||
\li Disables the distribution of spacing in pixels.
|
||||
\row
|
||||
\li \inlineimage icons/distribute-origin-top-left.png
|
||||
\li Sets the top-left corner of the target area as the starting point
|
||||
for distributing spacing in pixels.
|
||||
\li Sets the top or left edge of the target area or item as the
|
||||
starting point for distributing spacing in pixels depending on
|
||||
the distribution orientation.
|
||||
\row
|
||||
\li \inlineimage icons/distribute-origin-center.png
|
||||
\li Sets the center of the target area as the starting point
|
||||
for distributing spacing in pixels.
|
||||
\row
|
||||
\li \inlineimage icons/distribute-origin-bottom-right.png
|
||||
\li Sets the bottom-right corner of the target area as the starting
|
||||
point for distributing spacing in pixels.
|
||||
\li Sets the bottom or right edge of the target area or item as the
|
||||
starting point for distributing spacing in pixels, depending on
|
||||
the distribution orientation.
|
||||
\endtable
|
||||
|
||||
\section2 Using Positioners
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# GitHub Actions & Workflows
|
||||
|
||||
The `build_cmake.yml` in this directory adds a [GitHub action][1] and workflow that builds
|
||||
your plugin anytime you push commits to GitHub on Windows, Linux and macOS.
|
||||
|
||||
The build artifacts can be downloaded from GitHub and be installed into an existing Qt Creator
|
||||
installation.
|
||||
|
||||
When you push a tag, the workflow also creates a new release on GitHub.
|
||||
|
||||
## Keeping it up to date
|
||||
|
||||
Near the top of the file you find a section starting with `env:`.
|
||||
|
||||
The value for `QT_VERSION` specifies the Qt version to use for building the plugin.
|
||||
|
||||
The value for `QT_CREATOR_VERSION` specifies the Qt Creator version to use for building the plugin.
|
||||
|
||||
The value for `QT_CREATOR_SNAPSHOT` can either be `NO` or `latest` or the build ID of a specific
|
||||
snapshot build for the Qt Creator version that you specified.
|
||||
|
||||
You need to keep these values updated for different versions of your plugin, and take care
|
||||
that the Qt version and Qt Creator version you specify are compatible.
|
||||
|
||||
## What it does
|
||||
|
||||
The build job consists of several steps:
|
||||
|
||||
* Install required packages on the build host
|
||||
* Download, unpack and install the binary for the Qt version
|
||||
* Download and unpack the binary for the Qt Creator version
|
||||
* Build the plugin and upload the plugin libraries to GitHub
|
||||
* If a tag is pushed, create a release on GitHub for the tag, including zipped plugin libraries
|
||||
for download
|
||||
|
||||
## Limitations
|
||||
|
||||
If your plugin requires additional resources besides the plugin library, you need to adapt the
|
||||
script accordingly.
|
||||
|
||||
[1]: https://help.github.com/en/actions/automating-your-workflow-with-github-actions/about-github-actions
|
||||
@@ -0,0 +1,322 @@
|
||||
name: Build plugin
|
||||
|
||||
on: [push]
|
||||
|
||||
env:
|
||||
PLUGIN_NAME: Example
|
||||
QT_VERSION: 6.2.0
|
||||
QT_CREATOR_VERSION: 5.0.0
|
||||
QT_CREATOR_SNAPSHOT: NO
|
||||
CMAKE_VERSION: 3.18.3
|
||||
NINJA_VERSION: 1.10.1
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.config.name }}
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
config:
|
||||
- {
|
||||
name: "Windows Latest MSVC", artifact: "Windows-x64",
|
||||
os: windows-latest,
|
||||
cc: "cl", cxx: "cl",
|
||||
environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat",
|
||||
}
|
||||
- {
|
||||
name: "Ubuntu Latest GCC", artifact: "Linux-x64",
|
||||
os: ubuntu-latest,
|
||||
cc: "gcc", cxx: "g++"
|
||||
}
|
||||
- {
|
||||
name: "macOS Latest Clang", artifact: "macOS-x64",
|
||||
os: macos-latest,
|
||||
cc: "clang", cxx: "clang++"
|
||||
}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
- name: Download Ninja and CMake
|
||||
shell: cmake -P {0}
|
||||
run: |
|
||||
set(cmake_version "$ENV{CMAKE_VERSION}")
|
||||
set(ninja_version "$ENV{NINJA_VERSION}")
|
||||
|
||||
if ("${{ runner.os }}" STREQUAL "Windows")
|
||||
set(ninja_suffix "win.zip")
|
||||
set(cmake_suffix "win64-x64.zip")
|
||||
set(cmake_dir "cmake-${cmake_version}-win64-x64/bin")
|
||||
elseif ("${{ runner.os }}" STREQUAL "Linux")
|
||||
set(ninja_suffix "linux.zip")
|
||||
set(cmake_suffix "Linux-x86_64.tar.gz")
|
||||
set(cmake_dir "cmake-${cmake_version}-Linux-x86_64/bin")
|
||||
elseif ("${{ runner.os }}" STREQUAL "macOS")
|
||||
set(ninja_suffix "mac.zip")
|
||||
set(cmake_suffix "Darwin-x86_64.tar.gz")
|
||||
set(cmake_dir "cmake-${cmake_version}-Darwin-x86_64/CMake.app/Contents/bin")
|
||||
endif()
|
||||
|
||||
set(ninja_url "https://github.com/ninja-build/ninja/releases/download/v${ninja_version}/ninja-${ninja_suffix}")
|
||||
file(DOWNLOAD "${ninja_url}" ./ninja.zip SHOW_PROGRESS)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./ninja.zip)
|
||||
|
||||
set(cmake_url "https://github.com/Kitware/CMake/releases/download/v${cmake_version}/cmake-${cmake_version}-${cmake_suffix}")
|
||||
file(DOWNLOAD "${cmake_url}" ./cmake.zip SHOW_PROGRESS)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./cmake.zip)
|
||||
|
||||
# Add to PATH environment variable
|
||||
file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/${cmake_dir}" cmake_dir)
|
||||
set(path_separator ":")
|
||||
if ("${{ runner.os }}" STREQUAL "Windows")
|
||||
set(path_separator ";")
|
||||
endif()
|
||||
file(APPEND "$ENV{GITHUB_PATH}" "$ENV{GITHUB_WORKSPACE}${path_separator}${cmake_dir}")
|
||||
|
||||
if (NOT "${{ runner.os }}" STREQUAL "Windows")
|
||||
execute_process(
|
||||
COMMAND chmod +x ninja
|
||||
COMMAND chmod +x ${cmake_dir}/cmake
|
||||
)
|
||||
endif()
|
||||
|
||||
- name: Install system libs
|
||||
shell: cmake -P {0}
|
||||
run: |
|
||||
if ("${{ runner.os }}" STREQUAL "Linux")
|
||||
execute_process(
|
||||
COMMAND sudo apt update
|
||||
)
|
||||
execute_process(
|
||||
COMMAND sudo apt install libgl1-mesa-dev
|
||||
RESULT_VARIABLE result
|
||||
)
|
||||
if (NOT result EQUAL 0)
|
||||
message(FATAL_ERROR "Failed to install dependencies")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
- name: Download Qt
|
||||
id: qt
|
||||
shell: cmake -P {0}
|
||||
run: |
|
||||
set(qt_version "$ENV{QT_VERSION}")
|
||||
|
||||
string(REPLACE "." "" qt_version_dotless "${qt_version}")
|
||||
if ("${{ runner.os }}" STREQUAL "Windows")
|
||||
set(url_os "windows_x86")
|
||||
set(qt_package_arch_suffix "win64_msvc2019_64")
|
||||
set(qt_dir_prefix "${qt_version}/msvc2019_64")
|
||||
set(qt_package_suffix "-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86_64")
|
||||
elseif ("${{ runner.os }}" STREQUAL "Linux")
|
||||
set(url_os "linux_x64")
|
||||
set(qt_package_arch_suffix "gcc_64")
|
||||
set(qt_dir_prefix "${qt_version}/gcc_64")
|
||||
set(qt_package_suffix "-Linux-RHEL_7_6-GCC-Linux-RHEL_7_6-X86_64")
|
||||
elseif ("${{ runner.os }}" STREQUAL "macOS")
|
||||
set(url_os "mac_x64")
|
||||
set(qt_package_arch_suffix "clang_64")
|
||||
set(qt_dir_prefix "${qt_version}/clang_64")
|
||||
set(qt_package_suffix "-MacOS-MacOS_10_13-Clang-MacOS-MacOS_10_13-X86_64")
|
||||
endif()
|
||||
|
||||
set(qt_base_url "https://download.qt.io/online/qtsdkrepository/${url_os}/desktop/qt5_${qt_version_dotless}")
|
||||
file(DOWNLOAD "${qt_base_url}/Updates.xml" ./Updates.xml SHOW_PROGRESS)
|
||||
|
||||
file(READ ./Updates.xml updates_xml)
|
||||
string(REGEX MATCH "<Name>qt.qt5.*<Version>([0-9+-.]+)</Version>" updates_xml_output "${updates_xml}")
|
||||
set(qt_package_version ${CMAKE_MATCH_1})
|
||||
|
||||
file(MAKE_DIRECTORY qt5)
|
||||
|
||||
# Save the path for other steps
|
||||
file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/qt5/${qt_dir_prefix}" qt_dir)
|
||||
message("::set-output name=qt_dir::${qt_dir}")
|
||||
|
||||
message("Downloading Qt to ${qt_dir}")
|
||||
function(downloadAndExtract url archive)
|
||||
message("Downloading ${url}")
|
||||
file(DOWNLOAD "${url}" ./${archive} SHOW_PROGRESS)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ../${archive} WORKING_DIRECTORY qt5)
|
||||
endfunction()
|
||||
|
||||
foreach(package qtbase qtdeclarative)
|
||||
downloadAndExtract(
|
||||
"${qt_base_url}/qt.qt5.${qt_version_dotless}.${qt_package_arch_suffix}/${qt_package_version}${package}${qt_package_suffix}.7z"
|
||||
${package}.7z
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# uic depends on libicu56.so
|
||||
if ("${{ runner.os }}" STREQUAL "Linux")
|
||||
downloadAndExtract(
|
||||
"${qt_base_url}/qt.qt5.${qt_version_dotless}.${qt_package_arch_suffix}/${qt_package_version}icu-linux-Rhel7.2-x64.7z"
|
||||
icu.7z
|
||||
)
|
||||
endif()
|
||||
|
||||
- name: Download Qt Creator
|
||||
id: qt_creator
|
||||
shell: cmake -P {0}
|
||||
run: |
|
||||
string(REGEX MATCH "([0-9]+.[0-9]+).[0-9]+" outvar "$ENV{QT_CREATOR_VERSION}")
|
||||
|
||||
set(qtc_base_url "https://download.qt.io/official_releases/qtcreator/${CMAKE_MATCH_1}/$ENV{QT_CREATOR_VERSION}/installer_source")
|
||||
set(qtc_snapshot "$ENV{QT_CREATOR_SNAPSHOT}")
|
||||
if (qtc_snapshot)
|
||||
set(qtc_base_url "https://download.qt.io/snapshots/qtcreator/${CMAKE_MATCH_1}/$ENV{QT_CREATOR_VERSION}/installer_source/${qtc_snapshot}")
|
||||
endif()
|
||||
|
||||
if ("${{ runner.os }}" STREQUAL "Windows")
|
||||
set(qtc_platform "windows_x64")
|
||||
elseif ("${{ runner.os }}" STREQUAL "Linux")
|
||||
set(qtc_platform "linux_x64")
|
||||
elseif ("${{ runner.os }}" STREQUAL "macOS")
|
||||
set(qtc_platform "mac_x64")
|
||||
endif()
|
||||
|
||||
file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/qtcreator" qtc_dir)
|
||||
# Save the path for other steps
|
||||
message("::set-output name=qtc_dir::${qtc_dir}")
|
||||
|
||||
file(MAKE_DIRECTORY qtcreator)
|
||||
|
||||
message("Downloading Qt Creator from ${qtc_base_url}/${qtc_platform}")
|
||||
|
||||
foreach(package qtcreator qtcreator_dev)
|
||||
file(DOWNLOAD
|
||||
"${qtc_base_url}/${qtc_platform}/${package}.7z" ./${package}.7z SHOW_PROGRESS)
|
||||
execute_process(COMMAND
|
||||
${CMAKE_COMMAND} -E tar xvf ../${package}.7z WORKING_DIRECTORY qtcreator)
|
||||
endforeach()
|
||||
|
||||
- name: Build
|
||||
shell: cmake -P {0}
|
||||
run: |
|
||||
set(ENV{CC} ${{ matrix.config.cc }})
|
||||
set(ENV{CXX} ${{ matrix.config.cxx }})
|
||||
set(ENV{MACOSX_DEPLOYMENT_TARGET} "10.13")
|
||||
|
||||
if ("${{ runner.os }}" STREQUAL "Windows" AND NOT "x${{ matrix.config.environment_script }}" STREQUAL "x")
|
||||
execute_process(
|
||||
COMMAND "${{ matrix.config.environment_script }}" && set
|
||||
OUTPUT_FILE environment_script_output.txt
|
||||
)
|
||||
file(STRINGS environment_script_output.txt output_lines)
|
||||
foreach(line IN LISTS output_lines)
|
||||
if (line MATCHES "^([a-zA-Z0-9_-]+)=(.*)$")
|
||||
set(ENV{${CMAKE_MATCH_1}} "${CMAKE_MATCH_2}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set(ENV{NINJA_STATUS} "[%f/%t %o/sec] ")
|
||||
|
||||
set(build_plugin_py "scripts/build_plugin.py")
|
||||
foreach(dir "share/qtcreator/scripts" "Qt Creator.app/Contents/Resources/scripts" "Contents/Resources/scripts")
|
||||
if(EXISTS "${{ steps.qt_creator.outputs.qtc_dir }}/${dir}/build_plugin.py")
|
||||
set(build_plugin_py "${dir}/build_plugin.py")
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
execute_process(
|
||||
COMMAND python
|
||||
-u
|
||||
"${{ steps.qt_creator.outputs.qtc_dir }}/${build_plugin_py}"
|
||||
--name "$ENV{PLUGIN_NAME}-$ENV{QT_CREATOR_VERSION}-${{ matrix.config.artifact }}"
|
||||
--src .
|
||||
--build build
|
||||
--qt-path "${{ steps.qt.outputs.qt_dir }}"
|
||||
--qtc-path "${{ steps.qt_creator.outputs.qtc_dir }}"
|
||||
--output-path "$ENV{GITHUB_WORKSPACE}"
|
||||
RESULT_VARIABLE result
|
||||
)
|
||||
if (NOT result EQUAL 0)
|
||||
string(REGEX MATCH "FAILED:.*$" error_message "${output}")
|
||||
string(REPLACE "\n" "%0A" error_message "${error_message}")
|
||||
message("::error::${error_message}")
|
||||
message(FATAL_ERROR "Build failed")
|
||||
endif()
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
id: upload_artifact
|
||||
with:
|
||||
path: ./${{ env.PLUGIN_NAME }}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }}.7z
|
||||
name: ${{ env.PLUGIN_NAME}}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }}.7z
|
||||
|
||||
release:
|
||||
if: contains(github.ref, 'tags/v')
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
|
||||
steps:
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1.0.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: Release ${{ github.ref }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
- name: Store Release url
|
||||
run: |
|
||||
echo "${{ steps.create_release.outputs.upload_url }}" > ./upload_url
|
||||
|
||||
- uses: actions/upload-artifact@v1
|
||||
with:
|
||||
path: ./upload_url
|
||||
name: upload_url
|
||||
|
||||
publish:
|
||||
if: contains(github.ref, 'tags/v')
|
||||
|
||||
name: ${{ matrix.config.name }}
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
config:
|
||||
- {
|
||||
name: "Windows Latest x64", artifact: "Windows-x64.7z",
|
||||
os: ubuntu-latest
|
||||
}
|
||||
- {
|
||||
name: "Linux Latest x64", artifact: "Linux-x64.7z",
|
||||
os: ubuntu-latest
|
||||
}
|
||||
- {
|
||||
name: "macOS Latest x64", artifact: "macOS-x64.7z",
|
||||
os: macos-latest
|
||||
}
|
||||
needs: release
|
||||
|
||||
steps:
|
||||
- name: Download artifact
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: ${{ env.PLUGIN_NAME }}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }}
|
||||
path: ./
|
||||
|
||||
- name: Download URL
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: upload_url
|
||||
path: ./
|
||||
- id: set_upload_url
|
||||
run: |
|
||||
upload_url=`cat ./upload_url`
|
||||
echo ::set-output name=upload_url::$upload_url
|
||||
|
||||
- name: Upload to Release
|
||||
id: upload_to_release
|
||||
uses: actions/upload-release-asset@v1.0.1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.set_upload_url.outputs.upload_url }}
|
||||
asset_path: ./${{ env.PLUGIN_NAME }}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }}
|
||||
asset_name: ${{ env.PLUGIN_NAME }}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }}
|
||||
asset_content_type: application/x-7z-compressed
|
||||
@@ -0,0 +1,73 @@
|
||||
# This file is used to ignore files which are generated
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
*~
|
||||
*.autosave
|
||||
*.a
|
||||
*.core
|
||||
*.moc
|
||||
*.o
|
||||
*.obj
|
||||
*.orig
|
||||
*.rej
|
||||
*.so
|
||||
*.so.*
|
||||
*_pch.h.cpp
|
||||
*_resource.rc
|
||||
*.qm
|
||||
.#*
|
||||
*.*#
|
||||
core
|
||||
!core/
|
||||
tags
|
||||
.DS_Store
|
||||
.directory
|
||||
*.debug
|
||||
Makefile*
|
||||
*.prl
|
||||
*.app
|
||||
moc_*.cpp
|
||||
ui_*.h
|
||||
qrc_*.cpp
|
||||
Thumbs.db
|
||||
*.res
|
||||
*.rc
|
||||
/.qmake.cache
|
||||
/.qmake.stash
|
||||
|
||||
# qtcreator generated files
|
||||
*.pro.user*
|
||||
|
||||
# xemacs temporary files
|
||||
*.flc
|
||||
|
||||
# Vim temporary files
|
||||
.*.swp
|
||||
|
||||
# Visual Studio generated files
|
||||
*.ib_pdb_index
|
||||
*.idb
|
||||
*.ilk
|
||||
*.pdb
|
||||
*.sln
|
||||
*.suo
|
||||
*.vcproj
|
||||
*vcproj.*.*.user
|
||||
*.ncb
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.vcxproj
|
||||
*vcxproj.*
|
||||
|
||||
# MinGW generated files
|
||||
*.Debug
|
||||
*.Release
|
||||
|
||||
# Python byte code
|
||||
*.pyc
|
||||
|
||||
# Binaries
|
||||
# --------
|
||||
*.dll
|
||||
*.exe
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
#! [1]
|
||||
# Remove when sharing with others.
|
||||
list(APPEND CMAKE_PREFIX_PATH "/Users/example/qt-creator/build")
|
||||
#! [1]
|
||||
|
||||
#! [2]
|
||||
project(Example)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
#! [2]
|
||||
|
||||
#! [3]
|
||||
find_package(QtCreator COMPONENTS Core REQUIRED)
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets REQUIRED)
|
||||
set(QtX Qt${QT_VERSION_MAJOR})
|
||||
#! [3]
|
||||
|
||||
#! [4]
|
||||
add_qtc_plugin(Example
|
||||
PLUGIN_DEPENDS
|
||||
QtCreator::Core
|
||||
DEPENDS
|
||||
${QtX}::Widgets
|
||||
QtCreator::ExtensionSystem
|
||||
QtCreator::Utils
|
||||
SOURCES
|
||||
.github/workflows/build_cmake.yml
|
||||
.github/workflows/README.md
|
||||
README.md
|
||||
example.cpp
|
||||
example.h
|
||||
example_global.h
|
||||
exampleconstants.h
|
||||
)
|
||||
#! [4]
|
||||
@@ -5,12 +5,11 @@
|
||||
\"CompatVersion\" : \"0.0.1\",
|
||||
//! [1]
|
||||
//! [2]
|
||||
\"Vendor\" : \"My Company\",
|
||||
\"Copyright\" : \"(C) My Company\",
|
||||
\"License\" : \"BSD\",
|
||||
\"Category\" : \"Examples\",
|
||||
\"Description\" : \"Minimal plugin example.\",
|
||||
\"Url\" : \"http://www.mycompany.com\",
|
||||
\"Vendor\" : \"MyCompany\",
|
||||
\"Copyright\" : \"(C) MyCompany\",
|
||||
\"License\" : \"Put short license information here\",
|
||||
\"Description\" : \"Put a short description of your plugin here\",
|
||||
\"Url\" : \"https://www.mycompany.com\",
|
||||
//! [2]
|
||||
//! [3]
|
||||
$$dependencyList
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# Example
|
||||
|
||||
## How to Build
|
||||
|
||||
Create a build directory and run
|
||||
|
||||
cmake -DCMAKE_PREFIX_PATH=<path_to_qtcreator> -DCMAKE_BUILD_TYPE=RelWithDebInfo <path_to_plugin_source>
|
||||
cmake --build .
|
||||
|
||||
where `<path_to_qtcreator>` is the relative or absolute path to a Qt Creator build directory, or to a
|
||||
combined binary and development package (Windows / Linux), or to the `Qt Creator.app/Contents/Resources/`
|
||||
directory of a combined binary and development package (macOS), and `<path_to_plugin_source>` is the
|
||||
relative or absolute path to this plugin directory.
|
||||
|
||||
## How to Run
|
||||
|
||||
Run a compatible Qt Creator with the additional command line argument
|
||||
|
||||
-pluginpath <path_to_plugin>
|
||||
|
||||
where `<path_to_plugin>` is the path to the resulting plugin library in the build directory
|
||||
(`<plugin_build>/lib/qtcreator/plugins` on Windows and Linux,
|
||||
`<plugin_build>/Qt Creator.app/Contents/PlugIns` on macOS).
|
||||
|
||||
You might want to add `-temporarycleansettings` (or `-tcs`) to ensure that the opened Qt Creator
|
||||
instance cannot mess with your user-global Qt Creator settings.
|
||||
|
||||
When building and running the plugin from Qt Creator, you can use
|
||||
|
||||
-pluginpath "%{buildDir}/lib/qtcreator/plugins" -tcs
|
||||
|
||||
on Windows and Linux, or
|
||||
|
||||
-pluginpath "%{buildDir}/Qt Creator.app/Contents/PlugIns" -tcs
|
||||
|
||||
for the `Command line arguments` field in the run settings.
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "exampleplugin.h"
|
||||
#include "example.h"
|
||||
#include "exampleconstants.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
@@ -13,8 +13,6 @@
|
||||
#include <QMainWindow>
|
||||
#include <QMenu>
|
||||
|
||||
#include <QtPlugin>
|
||||
|
||||
namespace Example {
|
||||
namespace Internal {
|
||||
|
||||
@@ -42,9 +40,9 @@ bool ExamplePlugin::initialize(const QStringList &arguments, QString *errorStrin
|
||||
Q_UNUSED(errorString)
|
||||
|
||||
//! [add action]
|
||||
QAction *action = new QAction(tr("Example Action"), this);
|
||||
auto action = new QAction(tr("Example Action"), this);
|
||||
Core::Command *cmd = Core::ActionManager::registerAction(action, Constants::ACTION_ID,
|
||||
Core::Context(Core::Constants::C_GLOBAL));
|
||||
Core::Context(Core::Constants::C_GLOBAL));
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+Meta+A")));
|
||||
connect(action, &QAction::triggered, this, &ExamplePlugin::triggerAction);
|
||||
//! [add action]
|
||||
@@ -1,59 +0,0 @@
|
||||
#! [1]
|
||||
DEFINES += EXAMPLE_LIBRARY
|
||||
#! [1]
|
||||
|
||||
# Example files
|
||||
|
||||
#! [2]
|
||||
SOURCES += exampleplugin.cpp
|
||||
|
||||
HEADERS += exampleplugin.h \
|
||||
example_global.h \
|
||||
exampleconstants.h
|
||||
#! [2]
|
||||
|
||||
# Qt Creator linking
|
||||
|
||||
#! [3]
|
||||
## set the QTC_SOURCE environment variable to override the setting here
|
||||
QTCREATOR_SOURCES = $$(QTC_SOURCE)
|
||||
isEmpty(QTCREATOR_SOURCES):QTCREATOR_SOURCES=/Users/example/qtcreator-src
|
||||
|
||||
## set the QTC_BUILD environment variable to override the setting here
|
||||
IDE_BUILD_TREE = $$(QTC_BUILD)
|
||||
isEmpty(IDE_BUILD_TREE):IDE_BUILD_TREE=/Users/example/qtcreator-build
|
||||
#! [3]
|
||||
|
||||
#! [4]
|
||||
## uncomment to build plugin into user config directory
|
||||
## <localappdata>/plugins/<ideversion>
|
||||
## where <localappdata> is e.g.
|
||||
## "%LOCALAPPDATA%\QtProject\qtcreator" on Windows Vista and later
|
||||
## "$XDG_DATA_HOME/data/QtProject/qtcreator" or "~/.local/share/data/QtProject/qtcreator" on Linux
|
||||
## "~/Library/Application Support/QtProject/Qt Creator" on Mac
|
||||
# USE_USER_DESTDIR = yes
|
||||
#! [4]
|
||||
|
||||
#! [5]
|
||||
###### If the plugin can be depended upon by other plugins, this code needs to be outsourced to
|
||||
###### <dirname>_dependencies.pri, where <dirname> is the name of the directory containing the
|
||||
###### plugin's sources.
|
||||
|
||||
QTC_PLUGIN_NAME = Example
|
||||
QTC_LIB_DEPENDS += \
|
||||
# nothing here at this time
|
||||
|
||||
QTC_PLUGIN_DEPENDS += \
|
||||
coreplugin
|
||||
|
||||
QTC_PLUGIN_RECOMMENDS += \
|
||||
# optional plugin dependencies. nothing here at this time
|
||||
|
||||
###### End _dependencies.pri contents ######
|
||||
#! [5]
|
||||
|
||||
#![6]
|
||||
include($$QTCREATOR_SOURCES/src/qtcreatorplugin.pri)
|
||||
|
||||
#![6]
|
||||
|
||||
@@ -1,9 +1,32 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#if defined(EXAMPLE_LIBRARY)
|
||||
# define EXAMPLESHARED_EXPORT Q_DECL_EXPORT
|
||||
# define EXAMPLE_EXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
# define EXAMPLESHARED_EXPORT Q_DECL_IMPORT
|
||||
# define EXAMPLE_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,28 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Example {
|
||||
@@ -6,5 +31,6 @@ namespace Constants {
|
||||
const char ACTION_ID[] = "Example.Action";
|
||||
const char MENU_ID[] = "Example.Menu";
|
||||
|
||||
} // namespace Example
|
||||
} // namespace Constants
|
||||
} // namespace Example
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 18 KiB |
@@ -983,7 +983,7 @@
|
||||
\li \c{#include <stdthing>}
|
||||
\li \c{#include <system.h>}
|
||||
\endlist
|
||||
\li Enclose headers from other plugins in square brackets (<>) rather than
|
||||
\li Enclose headers from other plugins in angle brackets (<>) rather than
|
||||
quotation marks ("") to make it easier to spot external dependencies in
|
||||
the sources.
|
||||
\li Add empty lines between long blocks of \e peer headers and try to
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Creator documentation.
|
||||
@@ -61,9 +61,8 @@
|
||||
\li Give your project a name and specify in which path this project will
|
||||
be created. The actual plugin's name can be different from the
|
||||
project name. You will choose that name later in the wizard.
|
||||
Continue to the next page.
|
||||
|
||||
The \uicontrol {Plugin Information} dialog opens.
|
||||
\li Continue to the \uicontrol {Plugin Information} dialog.
|
||||
|
||||
\image firstplugin-pluginsetup.png "Specify Your Plugin Details"
|
||||
|
||||
@@ -74,7 +73,7 @@
|
||||
\li The values of the following fields are mainly informational, and
|
||||
are shown in the detailed view in \QC's plugin overview
|
||||
(\uicontrol Help > \uicontrol {About Plugins}, or
|
||||
\uicontrol {Qt Creator} > \uicontrol {About Plugins} on Mac).
|
||||
\uicontrol {\QC} > \uicontrol {About Plugins} on \macos).
|
||||
|
||||
\list
|
||||
\li \uicontrol {Vendor name} is a short one-word name of the
|
||||
@@ -94,33 +93,19 @@
|
||||
it.
|
||||
\endlist
|
||||
|
||||
\li Set the \uicontrol {Qt Creator sources} and
|
||||
\uicontrol{Qt Creator build} fields to the source and build
|
||||
directory of the \QC instance you want to use to test your plugin
|
||||
with, respectively. If you don't do that correctly you will get
|
||||
compile errors for your plugin, and your plugin might not show up in
|
||||
\QC at all.
|
||||
\li Set the \uicontrol{\QC build} field to the build directory
|
||||
of the \QC instance you want to use to test your plugin with. If
|
||||
you don't do that correctly, you will get compile errors for your
|
||||
plugin, and your plugin might not show up in \QC at all.
|
||||
|
||||
\li In the \uicontrol {Deploy into} list, select
|
||||
\uicontrol {Qt Creator build}. This sets your \c {.pro} file up to
|
||||
deploy your plugin directly into your \QC build's plugin directory
|
||||
(requires you to have write permissions there). The other option,
|
||||
\uicontrol {Local user settings}, sets your \c {.pro} file up to
|
||||
deploy your plugin into \QC's user plugin path (for example
|
||||
\c {~/.config/QtProject/qtcreator/plugins} on Unix systems). We
|
||||
choose \uicontrol {Qt Creator build} because we use a self-compiled
|
||||
\QC, and want the plugin to be only loaded by that \QC
|
||||
instance. Continue to the next page.
|
||||
|
||||
The \uicontrol {Translation File} dialog opens.
|
||||
\li Continue to the \uicontrol {Translation File} dialog.
|
||||
|
||||
\image firstplugin-translation-file.png "Choose a language to localize your plugin to"
|
||||
|
||||
\li Select a language to localize your plugin to. This sets up
|
||||
translation support for the selected language. Continue to the
|
||||
next page.
|
||||
translation support for the selected language.
|
||||
|
||||
The \uicontrol {Kit Selection} dialog opens.
|
||||
\li Continue to the \uicontrol {Kit Selection} dialog.
|
||||
|
||||
\image firstplugin-kitselection.png "Choose the kit to build and run your project with"
|
||||
|
||||
@@ -129,9 +114,9 @@
|
||||
version that is compatible with the Qt version that your \QC was
|
||||
built with (in the best case the exact same build). If you use an
|
||||
incompatible Qt version to build your plugin, you will get errors
|
||||
while \QC tries to load your plugin. Continue to the next page.
|
||||
while \QC tries to load your plugin.
|
||||
|
||||
The \uicontrol {Project Management} dialog opens.
|
||||
\li Continue to the \uicontrol {Project Management} dialog.
|
||||
|
||||
\image firstplugin-summary.png "Summary of Created Files"
|
||||
|
||||
@@ -142,7 +127,7 @@
|
||||
|
||||
\section1 Building and Running the Plugin
|
||||
|
||||
If you passed the correct \QC source and build paths in the project wizard,
|
||||
If you passed the correct \QC build path in the project wizard,
|
||||
your plugin should just build fine when pressing the build button. Before
|
||||
running the project, select \uicontrol {Build & Run} > \uicontrol Run to
|
||||
specify run settings:
|
||||
@@ -150,9 +135,12 @@
|
||||
\image firstplugin-runsettings.png "Specify the Executable to Run"
|
||||
|
||||
Select the path to the \QC executable from the build that you specified in
|
||||
the \uicontrol {Qt Creator build} setting in the project wizard and click
|
||||
\uicontrol OK. \QC starts up, and you can verify that your plugin
|
||||
successfully loaded by looking for a menu entry \uicontrol Tools >
|
||||
the \uicontrol {\QC build} field in the project wizard and set the value
|
||||
of the \uicontrol {Command line arguments} field to
|
||||
\c {-pluginpath %{buildDir}}.
|
||||
|
||||
When you click \uicontrol OK, \QC starts up, and you can verify that your
|
||||
plugin is successfully loaded by looking for a menu entry \uicontrol Tools >
|
||||
\uicontrol Example and by looking for the plugin in the \uicontrol Help >
|
||||
\uicontrol {About Plugins} dialog.
|
||||
|
||||
@@ -167,17 +155,20 @@
|
||||
\li File
|
||||
|
||||
\li Role
|
||||
\row
|
||||
\li \c {README.md}
|
||||
|
||||
\li Describes how to build and run the plugin.
|
||||
\row
|
||||
\li \c {Example.json.in}
|
||||
|
||||
\li Plugin meta data template. QMake creates an \c {Example.json}
|
||||
\li Plugin meta data template. CMake creates an \c {Example.json}
|
||||
from this file, which is compiled into the plugin as meta data.
|
||||
The meta data is read by \QC to find out about the plugin.
|
||||
\row
|
||||
\li \c {example.pro}
|
||||
\li \c {CMakeLists.txt}
|
||||
|
||||
\li Project file, used by QMake to generate a Makefile that then is used to
|
||||
build the plugin.
|
||||
\li Project file, used by CMake to generate build files and build the plugin.
|
||||
\row
|
||||
\li \c {example_global.h}
|
||||
|
||||
@@ -193,7 +184,7 @@
|
||||
\li C++ header and source files that define the plugin class that will be
|
||||
instantiated and run by \QC's plugin manager.
|
||||
\row
|
||||
\li \c{build_qmake.yml}
|
||||
\li \c{build_cmake.yml}
|
||||
|
||||
\li Adds a
|
||||
\l {https://help.github.com/en/actions/automating-your-workflow-with-github-actions/about-github-actions}
|
||||
@@ -202,71 +193,61 @@
|
||||
information, see \c {.github\workflow\README.md}.
|
||||
\endtable
|
||||
|
||||
\section1 qmake Project
|
||||
\section1 CMake Project
|
||||
|
||||
The qmake project file \c {example.pro} defines how your plugin should be
|
||||
The CMake project file \c {CMakeLists.txt} defines how your plugin should be
|
||||
compiled. \QC plugins need to have a specific setup there, in addition to
|
||||
telling qmake which files need to be compiled (or handled by \c moc or
|
||||
telling CMake which files need to be compiled (or handled by \c moc or
|
||||
\c uic). Let us have a look at what the project wizard generated for you in
|
||||
detail.
|
||||
|
||||
\snippet exampleplugin/example.pro 1
|
||||
\snippet exampleplugin/CMakeLists.txt 1
|
||||
|
||||
The first section of the .pro file lets the compiler pass an
|
||||
\c EXAMPLE_LIBRARY define to the compiled code, which is used in the
|
||||
\c {example_global.h} header, but is not really of interest for now. You
|
||||
should not need to change that section of the \c {.pro} file.
|
||||
The \c{list(APPEND ...)} call tells CMake to include the \QC build path that
|
||||
you specified in the wizard in its search path for dependencies. Since this
|
||||
contains an absolute path on your local machine, you should remove this line
|
||||
when sharing the project with others.
|
||||
|
||||
\snippet exampleplugin/example.pro 2
|
||||
Without this line, you need to explicitly add the path to the \QC
|
||||
build to \c {CMAKE_PREFIX_PATH} when configuring your plugin with CMake.
|
||||
|
||||
This section tells qmake about the files of your project that it should let
|
||||
compile or otherwise handle. You need to expand that section with any files
|
||||
you add to the project.
|
||||
\snippet exampleplugin/CMakeLists.txt 2
|
||||
|
||||
\snippet exampleplugin/example.pro 3
|
||||
This section does some standard setup for Qt/CMake projects. Besides
|
||||
setting a project name and a C++ standard to use, it turns on automatic
|
||||
detection of files that need to be run through \c {moc}, \c {rcc} or \c
|
||||
{uic}.
|
||||
|
||||
To compile and deploy your plugin, the project needs access to the \QC
|
||||
sources and build. This section contains the logic that looks for the
|
||||
information about the location of the sources and build in the
|
||||
\c {QTC_SOURCE} and \c {QTC_BUILD} environment variables. If these are not
|
||||
defined, it uses the defaults you set in the project wizard.
|
||||
\snippet exampleplugin/CMakeLists.txt 3
|
||||
|
||||
So, if someone else opens your plugin project on their machine, they do not
|
||||
need to edit the .pro file, but instead they should set the \c {QTC_SOURCE}
|
||||
and \c {QTC_BUILD} environment variables correctly for the plugin's build
|
||||
environment.
|
||||
This section tells CMake to locate \QC and Qt. If your plugin requires
|
||||
additional Qt modules, you need to add them to the corresponding
|
||||
\c {find_package} call in this section.
|
||||
|
||||
You should not need to change this section, except perhaps to adapt the
|
||||
defaults.
|
||||
To find \QC and Qt, the paths to the \QC and Qt installation must be
|
||||
present in the \c {CMAKE_PREFIX_PATH} when you configure your plugin
|
||||
with CMake.
|
||||
|
||||
\snippet exampleplugin/example.pro 4
|
||||
\snippet exampleplugin/CMakeLists.txt 4
|
||||
|
||||
\QC plugins can either be installed into the \QC installation's plugin
|
||||
directory (requires write access there), or to a user specific plugin
|
||||
directory. The \c USE_USER_DESTDIR switch in the .pro file defines which
|
||||
method is used for building the plugin (which is independent from what you
|
||||
can later use for distributing your plugin to other users).
|
||||
The \c {add_qtc_plugin} call creates a target for your plugin with the
|
||||
specified name.
|
||||
|
||||
\snippet exampleplugin/example.pro 5
|
||||
In the \c {PLUGIN_DEPENDS} sub-section, you need to specify \QC plugins that
|
||||
your plugin depends on. Valid values are a plugin's name prefixed with
|
||||
\c {QtCreator::}.
|
||||
|
||||
This section defines the name and dependencies of your plugin. The
|
||||
\c {QTC_PLUGIN_NAME} variable defines the name of your plugin, and the name
|
||||
of the dynamic library that is created for it. The \c {QTC_LIB_DEPENDS}
|
||||
variable is a list of library names of the \QC utility libraries that your
|
||||
plugin depends on. Typical values would be \c aggregation,
|
||||
\c extensionsystem and \c utils. The \c {QTC_PLUGIN_DEPENDS} variable
|
||||
defines the \QC plugins that your plugin depends on. Almost all \QC plugins
|
||||
will depend on the \c coreplugin. The \c {QTC_PLUGIN_RECOMMENDS} variable
|
||||
defines the \QC plugins that your plugin optionally depends on. For more
|
||||
information, see \l{Optional Dependencies}.
|
||||
In the \c {DEPENDS} sub-section, you need to specify libraries that your
|
||||
plugin depends on. Use a Qt module name prefixed with \c {$\{QtX\}::}
|
||||
to link to additional Qt modules. To link against additional \QC libraries,
|
||||
prefix their name with \c {QtCreator::}. In this subsection you also
|
||||
specify other libraries that your plugin depends on.
|
||||
|
||||
\snippet exampleplugin/example.pro 6
|
||||
|
||||
The included file \c{qtcreatorplugin.pri} makes sure that you build a plugin
|
||||
that is suitable for use in \QC, by using the information you gave above.
|
||||
|
||||
For more information about qmake, and writing \c {.pro} files in general,
|
||||
see the \l{qmake Manual}.
|
||||
In the \c {SOURCES} sub-section, you specify all files that belong to your
|
||||
plugin project. CMake sorts these into source files and header files
|
||||
automatically. Other files in this section are ignored by CMake but appear
|
||||
for example in the project tree that is shown in IDEs like \QC for easier
|
||||
access.
|
||||
|
||||
\section1 Plugin Meta Data Template
|
||||
|
||||
@@ -301,22 +282,22 @@
|
||||
|
||||
\section1 Plugin Class
|
||||
|
||||
The files \c {exampleplugin.h} and \c {exampleplugin.cpp} define the plugin
|
||||
The files \c {example.h} and \c {example.cpp} define the plugin
|
||||
implementation of your little plugin. We'll concentrate on some highlights
|
||||
here, and give pointers to more detailed information for the various parts.
|
||||
|
||||
\section2 Header File
|
||||
|
||||
The header file \c {exampleplugin.h} defines the interface of the plugin
|
||||
The header file \c {example.h} defines the interface of the plugin
|
||||
class.
|
||||
|
||||
\snippet exampleplugin/exampleplugin.h namespaces
|
||||
\snippet exampleplugin/example.h namespaces
|
||||
|
||||
The plugin is defined in a \c {Example::Internal} namespace, which conforms
|
||||
to the coding rules for \l{coding-rules-namespacing}{namespacing}
|
||||
in \QC sources.
|
||||
|
||||
\snippet exampleplugin/exampleplugin.h base class
|
||||
\snippet exampleplugin/example.h base class
|
||||
|
||||
All \QC plugins must be derived from \l{ExtensionSystem::IPlugin} and
|
||||
are QObjects. The \c {Q_PLUGIN_METADATA} macro is necessary to create a
|
||||
@@ -325,13 +306,13 @@
|
||||
\c FILE must point to the plugin's meta data file as described in
|
||||
\l{Plugin Meta Data}.
|
||||
|
||||
\snippet exampleplugin/exampleplugin.h plugin functions
|
||||
\snippet exampleplugin/example.h plugin functions
|
||||
|
||||
The base class defines basic functions that are called during the life cycle
|
||||
of a plugin, which are here implemented for your new plugin. These functions
|
||||
and their roles are described in detail in \l{Plugin Life Cycle}.
|
||||
|
||||
\snippet exampleplugin/exampleplugin.h slot
|
||||
\snippet exampleplugin/example.h slot
|
||||
|
||||
The plugin has an additional custom slot, that is used to pop up a dialog
|
||||
when the user chooses the menu item that this plugin adds.
|
||||
@@ -353,7 +334,7 @@
|
||||
For more information about implementing the plugin interface, see the
|
||||
\l{ExtensionSystem::IPlugin} API documentation and \l{Plugin Life Cycle}.
|
||||
|
||||
\snippet exampleplugin/exampleplugin.cpp add action
|
||||
\snippet exampleplugin/example.cpp add action
|
||||
|
||||
This part of the code creates a new \c QAction, registers it as a new
|
||||
\c Command in the action manager, and connects it to the plugin's slot. The
|
||||
@@ -362,12 +343,12 @@
|
||||
be directed to different plugins under different circumstances, as well as a
|
||||
few other things.
|
||||
|
||||
\snippet exampleplugin/exampleplugin.cpp add menu
|
||||
\snippet exampleplugin/example.cpp add menu
|
||||
|
||||
Here a new menu item is created, the created command added to it, and the
|
||||
menu added to the \uicontrol Tools menu in the menu bar.
|
||||
|
||||
\snippet exampleplugin/exampleplugin.cpp slot implementation
|
||||
\snippet exampleplugin/example.cpp slot implementation
|
||||
|
||||
This part defines the code that is called when the menu item is triggered.
|
||||
It uses the Qt API to open a message box that displays informative text and
|
||||
|
||||
|
After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 36 KiB |
@@ -89,6 +89,7 @@
|
||||
\li \l Animations
|
||||
\li \l{3D Views}
|
||||
\li \l{Group}
|
||||
\li \l{Skeletal Animation}
|
||||
\li \l{3D Models}
|
||||
\li \l{Materials and Shaders}
|
||||
\li \l{Textures}
|
||||
|
||||
@@ -32,8 +32,19 @@
|
||||
|
||||
\title 3D Materials
|
||||
|
||||
\QDS provides a set of pregenerated Qt Quick 3D materials that can be used
|
||||
to create good-looking \l {3D Models}{models} quickly and easily.
|
||||
\QDS provides a set of pregenerated \uicontrol {Qt Quick 3D}
|
||||
materials. If the 3D materials are not displayed in \uicontrol Library,
|
||||
you can add the \uicontrol QtQuick3D.Materials module to your project,
|
||||
as described in \l {Adding and Removing Modules}. However, since using the
|
||||
pregenerated 3D materials may cause performance issues, we advice you to
|
||||
use \uicontrol {Principled Material}, \uicontrol {Default Material}, or
|
||||
\uicontrol {Custom Material} instead. For more information,
|
||||
see \l {Materials and Shaders} and \l {Creating Custom Materials}.
|
||||
|
||||
\note The \uicontrol QtQuick3D.Materials module is not available in
|
||||
\uicontrol {Qt 6}. To use the pregenerated \uicontrol {Qt Quick 3D}
|
||||
materials, you need to select \uicontrol {Qt 5} as the
|
||||
\uicontrol {Target Qt Version} when \l {Creating Projects}{creating your project}.
|
||||
|
||||
To apply a 3D material to a component, you should first delete the default
|
||||
material and then drag-and-drop a new material from \l Library >
|
||||
@@ -46,10 +57,6 @@
|
||||
\uicontrol Materials property, select the \inlineimage plus.png
|
||||
icon, and choose the new material in the dropdown menu.
|
||||
|
||||
If the 3D materials are not displayed in \uicontrol Library, you should add
|
||||
the \uicontrol QtQuick3D.Materials module to your project, as described in
|
||||
\l {Adding and Removing Modules}.
|
||||
|
||||
Each material has its own set of properties that can be used to further
|
||||
define the appearance of the material. For each material the \uicontrol
|
||||
{Environment Map} property specifies whether or not
|
||||
|
||||
@@ -27,18 +27,19 @@
|
||||
|
||||
/*!
|
||||
\page studio-3d-model.html
|
||||
\previouspage studio-3d-node.html
|
||||
\previouspage studio-skeletal-components.html
|
||||
\nextpage studio-3d-materials.html
|
||||
|
||||
\title 3D Models
|
||||
|
||||
\QDS \l Library features some built-in primitive 3D models. This allows you
|
||||
to add cubes, cones, cylinders, and planes (rectangles) to your scene.
|
||||
The \l Library view features some built-in primitive 3D models. This allows
|
||||
you to add cubes, cones, cylinders, and planes (rectangles) to your scene.
|
||||
|
||||
\image studio-3d-models.png
|
||||
\image studio-3d-models.png "Various 3D models in 3D Editor"
|
||||
|
||||
A Model component loads mesh data from a file. You can modify how the
|
||||
component is shaded by adding \l{3D Materials}{materials} to the model.
|
||||
component is shaded by using materials. For more information, see
|
||||
\l {Materials and Shaders} and \l {Creating Custom Materials}.
|
||||
|
||||
You can drag-and-drop a model from \uicontrol Library > \uicontrol Components
|
||||
> \uicontrol {Qt Quick 3D} > \uicontrol {Qt Quick 3D} to \l {3D Editor} or
|
||||
@@ -49,28 +50,66 @@
|
||||
|
||||
\image studio-qtquick-3d-components.png "The Qt Quick 3D section in Library"
|
||||
|
||||
You can change the model type in the \uicontrol Source field in the
|
||||
\uicontrol Properties view. Select the \inlineimage plus.png
|
||||
\section1 Model Properties
|
||||
|
||||
You can change the model type in \uicontrol Properties > \uicontrol Model
|
||||
> \uicontrol Source field. Select the \inlineimage plus.png
|
||||
button to add custom model types to the list.
|
||||
|
||||
\image studio-qtquick-3d-model.png "Model properties"
|
||||
|
||||
To use the geometry of this model when rendering to shadow maps, select the
|
||||
\uicontrol {Casts shadows} check box. To allow casting shadows on the model,
|
||||
select the \uicontrol {Receives shadows} check box.
|
||||
|
||||
To enable picking the model against the scene, select the
|
||||
\uicontrol Pickable check box. Picking transforms the screen
|
||||
space x and y coordinates to a ray cast towards the specified
|
||||
position in scene space.
|
||||
|
||||
To use the geometry of this model when rendering to shadow maps, select the
|
||||
\uicontrol {Casts shadows} check box. To allow casting shadows on the model,
|
||||
select the \uicontrol {Receives shadows} check box.
|
||||
A model can consist of several sub-meshes, each of which can have its own
|
||||
material. Select the material from the list in the \uicontrol {Materials}
|
||||
field. Select the \inlineimage plus.png
|
||||
button to add materials to the list. For more information about materials,
|
||||
see \l {Materials and Shaders}.
|
||||
|
||||
\section1 Tessellation
|
||||
Specify a custom geometry for the model in the \uicontrol Geometry field.
|
||||
The \uicontrol Source field must be empty when custom geometry is used.
|
||||
|
||||
To dynamically generate additional geometry for the model, select the
|
||||
tiling mode in the \uicontrol {Tessellation mode} filed. Tessellation
|
||||
is useful when using a displacement map with geometry, or to generate a
|
||||
smoother silhouette when zooming in. You can select either a Phong or
|
||||
an NPatch tessellation generator.
|
||||
Set the \uicontrol Instancing property to render a number of instances of
|
||||
the model as defined by the instance table.
|
||||
|
||||
Set the \uicontrol {Instance root} property to define the origin of the
|
||||
instance's coordinate system.
|
||||
|
||||
Specify the \uicontrol Skeleton property to define the \uicontrol Skeleton
|
||||
component used for this model. \uicontrol Skeletons are used for skeletal
|
||||
animation.
|
||||
|
||||
Specify \uicontrol {Morph targets} to use for rendering the provided
|
||||
geometry. Meshes should have at least one attribute among positions, normals,
|
||||
tangent, and bitangent for the morph targets. \uicontrol {Quick 3D} supports
|
||||
the maximum of eight \uicontrol {Morph targets}. Any additional targets
|
||||
after the first eight will be ignored. This property is not used when the
|
||||
model is shaded by a \uicontrol {Custom Material}.
|
||||
|
||||
Define the \uicontrol {Depth bias} property to ensure the shadows of your
|
||||
model are displayed correctly.
|
||||
|
||||
\section1 Tessellation Properties Available in Qt 5
|
||||
|
||||
The properties discussed in this section are only available if you selected
|
||||
\uicontrol {Qt 5} as the \uicontrol {Target Qt Version} when creating the
|
||||
project.
|
||||
|
||||
\image studio-qtquick-3d-properties-tessellation.png "Tessellation properties"
|
||||
|
||||
Tessellation refers to additional geometry that resembles tiling, which you
|
||||
can add to your model. To dynamically generate tessellation for the model,
|
||||
select \uicontrol Linear, \uicontrol Phong, or \uicontrol NPatch as the
|
||||
\uicontrol {Tessellation mode}. Tessellation is useful when using a
|
||||
displacement map with geometry, or to generate a smoother silhouette
|
||||
when zooming in.
|
||||
|
||||
Specify an edge multiplier to the tessellation generator in the
|
||||
\uicontrol {Edge tessellation} field and an inner multiplier in
|
||||
@@ -80,11 +119,4 @@
|
||||
the tessellation generator, select the \uicontrol {Enable wireframe mode}
|
||||
check box.
|
||||
|
||||
\section1 Adding Materials to Sub-Meshes
|
||||
|
||||
A model can consist of several sub-meshes, each of which can have its own
|
||||
material. Select the material from the list in the \uicontrol {Materials}
|
||||
field. Select the \inlineimage plus.png
|
||||
button to add materials to the list. For more information about materials,
|
||||
see \l {Materials and Shaders}.
|
||||
*/
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
/*!
|
||||
\page studio-3d-node.html
|
||||
\previouspage quick-animations.html
|
||||
\nextpage studio-3d-model.html
|
||||
\nextpage studio-skeletal-components.html
|
||||
|
||||
\title Group
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Design Studio documentation.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Free Documentation License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Free
|
||||
** Documentation License version 1.3 as published by the Free Software
|
||||
** Foundation and appearing in the file included in the packaging of
|
||||
** this file. Please review the following information to ensure
|
||||
** the GNU Free Documentation License version 1.3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\page studio-skeletal-components.html
|
||||
\previouspage studio-3d-node.html
|
||||
\nextpage studio-3d-model.html
|
||||
|
||||
\title Skeletal Animation
|
||||
|
||||
Skeletal animation is a technique used in computer animation. In skeletal
|
||||
animation, a character is represented in the form of a surface representation
|
||||
(skin or mesh), and a skeleton. This portrays how the character can move,
|
||||
inspired by how a physical skeleton works for vertebrates. The "bones" of the
|
||||
skeleton are represented by a hierarchy of joint nodes.
|
||||
|
||||
The normal workflow is to use an external content creation tool to define
|
||||
the skeleton and the skin (this is sometimes also referred to as rigging),
|
||||
and import them to \QDS. You can then create skeletal animations using
|
||||
\uicontrol Skeleton and \uicontrol Joint components available in
|
||||
\uicontrol Library > \uicontrol Components > \uicontrol {Qt Quick 3D} >
|
||||
\uicontrol {Qt Quick 3D}.
|
||||
|
||||
\section1 Skeleton
|
||||
|
||||
A \uicontrol Skeleton component determines a skeletal animation hierarchy
|
||||
and defines how a model can be animated using skeletal animation.
|
||||
It contains a hierarchy of \uicontrol Joint nodes. Each joint can be
|
||||
transformed for a skinning animation.
|
||||
|
||||
\section1 Joint
|
||||
|
||||
A \uicontrol Joint defines a node in a skeletal animation hierarchy
|
||||
and functions similarly to joints between bones in a human skeleton.
|
||||
It is a transformable node that must be contained inside a
|
||||
\uicontrol Skeleton component.
|
||||
|
||||
Define properties for \uicontrol Joint components in \uicontrol Properties
|
||||
> \uicontrol Joint.
|
||||
|
||||
\image studio-3d-joint-properties.png "Joint properties in the Properties view"
|
||||
|
||||
Use the \uicontrol Index property to define the index of this joint.
|
||||
This index value is used in the \uicontrol {Joint semantic} custom geometry
|
||||
attribute.
|
||||
|
||||
\note The \uicontrol Index values must be unique within the same
|
||||
\uicontrol Skeleton.
|
||||
|
||||
Use the \uicontrol {Skeleton root} property to define the \uicontrol Skeleton
|
||||
that contains the \uicontrol Joint. Do note that all the \uicontrol Joints
|
||||
in the \uicontrol Skeleton must have the same \uicontrol {Skeleton root}
|
||||
for the animation to work properly.
|
||||
*/
|
||||
@@ -90,6 +90,18 @@ if [ -d "$sqldriversSrcDir" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# workaround for Qt 6.2:
|
||||
# - QTBUG-94796 macdeployqt does not deploy /Contents/PlugIns/imageformats/libqsvg.dylib anymore
|
||||
imageformatsDestDir="$app_path/Contents/PlugIns/imageformats"
|
||||
imageformatsSrcDir="$plugin_src/imageformats"
|
||||
if [ -d "$imageformatsSrcDir" ]; then
|
||||
if [ ! -d "$imageformatsDestDir" ]; then
|
||||
echo "- Copying sqlitedriver plugin"
|
||||
mkdir -p "$imageformatsDestDir"
|
||||
cp "$imageformatsSrcDir/libqsvg.dylib" "$imageformatsDestDir/libqsvg.dylib"
|
||||
fi
|
||||
fi
|
||||
|
||||
# copy Qt Quick 2 imports
|
||||
imports2Dir="$app_path/Contents/Imports/qtquick2"
|
||||
if [ -d "$quick2_src" ]; then
|
||||
|
||||
@@ -139,7 +139,7 @@ void CameraGeometry::doUpdateGeometry()
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_camera->cameraNode()) {
|
||||
if (!QQuick3DObjectPrivate::get(m_camera)->spatialNode) {
|
||||
// Doing explicit viewport mapping forces cameraNode creation
|
||||
m_camera->mapToViewport({}, m_viewPortRect.width(), m_viewPortRect.height());
|
||||
}
|
||||
@@ -171,7 +171,7 @@ void CameraGeometry::fillVertexData(QByteArray &vertexData, QByteArray &indexDat
|
||||
auto indexPtr = reinterpret_cast<quint16 *>(indexData.data());
|
||||
|
||||
QMatrix4x4 m;
|
||||
QSSGRenderCamera *camera = m_camera->cameraNode();
|
||||
QSSGRenderCamera *camera = static_cast<QSSGRenderCamera *>(QQuick3DObjectPrivate::get(m_camera)->spatialNode);
|
||||
if (camera) {
|
||||
QRectF rect = m_viewPortRect;
|
||||
if (rect.isNull())
|
||||
|
||||
@@ -818,7 +818,8 @@ QVector3D MouseArea3D::getMousePosInPlane(const MouseArea3D *helper,
|
||||
const DoubleVec3D rayPos0 = m_view3D->mapTo3DScene(mousePos1.toVec3());
|
||||
DoubleVec3D rayPos1;
|
||||
if (qobject_cast<QQuick3DOrthographicCamera *>(m_view3D->camera())) {
|
||||
rayPos1 = rayPos0 - rayPos0.length() * DoubleVec3D(m_view3D->camera()->cameraNode()->getDirection());
|
||||
if (auto cameraNode = static_cast<QSSGRenderCamera *>(QQuick3DObjectPrivate::get(m_view3D->camera())->spatialNode))
|
||||
rayPos1 = rayPos0 - rayPos0.length() * DoubleVec3D(cameraNode->getDirection());
|
||||
} else {
|
||||
DoubleVec3D dir;
|
||||
DoubleVec3D camPos = m_view3D->camera()->scenePosition();
|
||||
@@ -1021,12 +1022,17 @@ QVector3D MouseArea3D::getNormal() const
|
||||
QVector3D MouseArea3D::getCameraToNodeDir(QQuick3DNode *node) const
|
||||
{
|
||||
QVector3D dir;
|
||||
if (qobject_cast<QQuick3DOrthographicCamera *>(m_view3D->camera())) {
|
||||
dir = -m_view3D->camera()->cameraNode()->getDirection();
|
||||
} else {
|
||||
QVector3D camPos = m_view3D->camera()->scenePosition();
|
||||
QVector3D nodePos = pivotScenePosition(node);
|
||||
dir = (nodePos - camPos).normalized();
|
||||
if (m_view3D->camera()) {
|
||||
// We need to do a cast here to be compatible with Qt 5.x.
|
||||
// From Qt 6.2 the type can be read from the node directly.
|
||||
if (qobject_cast<QQuick3DOrthographicCamera *>(m_view3D->camera())) {
|
||||
if (auto renderCamera = QQuick3DObjectPrivate::get(m_view3D->camera())->spatialNode)
|
||||
dir -= static_cast<QSSGRenderCamera *>(renderCamera)->getDirection();
|
||||
} else {
|
||||
QVector3D camPos = m_view3D->camera()->scenePosition();
|
||||
QVector3D nodePos = pivotScenePosition(node);
|
||||
dir = (nodePos - camPos).normalized();
|
||||
}
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
@@ -933,6 +933,9 @@ void NodeInstanceServer::setInstancePropertyBinding(const PropertyBindingContain
|
||||
Internal::QmlPrivateGate::createNewDynamicProperty(instance.internalInstance()->object(), engine(),
|
||||
QString::fromUtf8(name));
|
||||
instance.setPropertyBinding(name, expression);
|
||||
|
||||
if (instance.instanceId() == 0 && (name == "width" || name == "height"))
|
||||
resizeCanvasToRootItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,6 +214,7 @@ public:
|
||||
virtual void handleInstanceHidden(const ServerNodeInstance &instance, bool enable, bool checkAncestors);
|
||||
|
||||
virtual QImage grabWindow() = 0;
|
||||
virtual QImage grabItem(QQuickItem *item) = 0;
|
||||
|
||||
public slots:
|
||||
void refreshLocalFileProperty(const QString &path);
|
||||
|
||||
@@ -761,7 +761,8 @@ void Qt5InformationNodeInstanceServer::updateNodesRecursive(QQuickItem *item)
|
||||
const auto childItems = item->childItems();
|
||||
for (QQuickItem *childItem : childItems)
|
||||
updateNodesRecursive(childItem);
|
||||
if (Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
||||
|
||||
if (Internal::QuickItemNodeInstance::unifiedRenderPathOrQt6()) {
|
||||
if (item->flags() & QQuickItem::ItemHasContents)
|
||||
item->update();
|
||||
} else {
|
||||
@@ -773,7 +774,7 @@ QQuickItem *Qt5InformationNodeInstanceServer::getContentItemForRendering(QQuickI
|
||||
{
|
||||
QQuickItem *contentItem = QQmlProperty::read(rootItem, "contentItem").value<QQuickItem *>();
|
||||
if (contentItem) {
|
||||
if (!Internal::QuickItemNodeInstance::unifiedRenderPath())
|
||||
if (!Internal::QuickItemNodeInstance::unifiedRenderPathOrQt6())
|
||||
designerSupport()->refFromEffectItem(contentItem, false);
|
||||
QmlDesigner::Internal::QmlPrivateGate::disableNativeTextRendering(contentItem);
|
||||
}
|
||||
@@ -899,7 +900,7 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView()
|
||||
instanceObj = instance.internalObject();
|
||||
}
|
||||
QSize renderSize = m_modelNodePreviewImageCommand.size();
|
||||
if (Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
||||
if (Internal::QuickItemNodeInstance::unifiedRenderPathOrQt6()) {
|
||||
// Requested size is already adjusted for target pixel ratio, so we have to adjust
|
||||
// back if ratio is not default for our window.
|
||||
double ratio = m_modelNode3DImageViewData.window->devicePixelRatio();
|
||||
@@ -1106,7 +1107,7 @@ Qt5InformationNodeInstanceServer::~Qt5InformationNodeInstanceServer()
|
||||
if (m_editView3DData.rootItem)
|
||||
QMetaObject::invokeMethod(m_editView3DData.rootItem, "aboutToShutDown", Qt::DirectConnection);
|
||||
|
||||
if (!Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
||||
if (!Internal::QuickItemNodeInstance::unifiedRenderPathOrQt6()) {
|
||||
if (m_editView3DData.contentItem)
|
||||
designerSupport()->derefFromEffectItem(m_editView3DData.contentItem);
|
||||
if (m_modelNode3DImageViewData.contentItem)
|
||||
|
||||
@@ -64,11 +64,11 @@ Qt5NodeInstanceClientProxy::Qt5NodeInstanceClientProxy(QObject *parent) :
|
||||
const bool qt6 = true;
|
||||
#endif
|
||||
|
||||
const bool unifiedRenderPath = qt6 || qEnvironmentVariableIsSet("QMLPUPPET_UNIFIED_RENDER_PATH");
|
||||
const bool unifiedRenderPath = qEnvironmentVariableIsSet("QMLPUPPET_UNIFIED_RENDER_PATH");
|
||||
|
||||
if (unifiedRenderPath)
|
||||
Internal::QuickItemNodeInstance::enableUnifiedRenderPath(true);
|
||||
else
|
||||
else if (!qt6)
|
||||
DesignerSupport::activateDesignerWindowManager();
|
||||
|
||||
if (QCoreApplication::arguments().at(1) == QLatin1String("--readcapturedstream")) {
|
||||
|
||||
@@ -44,10 +44,13 @@
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
#include <QtGui/private/qrhi_p.h>
|
||||
#include <QtQuick/private/qquickwindow_p.h>
|
||||
#include <QtQuick/private/qsgrenderer_p.h>
|
||||
#include <QtQuick/private/qquickitem_p.h>
|
||||
#include <QtQuick/private/qquickrendercontrol_p.h>
|
||||
#include <QtQuick/private/qquickrendertarget_p.h>
|
||||
#include <QtQuick/private/qquickwindow_p.h>
|
||||
#include <QtQuick/private/qsgcontext_p.h>
|
||||
#include <QtQuick/private/qsgrenderer_p.h>
|
||||
#include <QtQuick/private/qsgrhilayer_p.h>
|
||||
#endif
|
||||
|
||||
namespace QmlDesigner {
|
||||
@@ -332,6 +335,80 @@ QImage Qt5NodeInstanceServer::grabWindow()
|
||||
return {};
|
||||
}
|
||||
|
||||
QImage Qt5NodeInstanceServer::grabItem(QQuickItem *item)
|
||||
{
|
||||
QImage renderImage;
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
if (!m_viewData.rootItem || (m_viewData.bufferDirty && !initRhi(m_viewData)))
|
||||
return {};
|
||||
|
||||
QQuickItemPrivate *pItem = QQuickItemPrivate::get(item);
|
||||
pItem->refFromEffectItem(false);
|
||||
|
||||
ServerNodeInstance instance = instanceForObject(item);
|
||||
const auto childInstances = instance.childItems();
|
||||
|
||||
// Hide immediate children that have instances and are QQuickItems so we get only
|
||||
// the parent item's content, as compositing is handled on creator side.
|
||||
for (const auto &childInstance : childInstances) {
|
||||
QQuickItem *childItem = qobject_cast<QQuickItem *>(childInstance.internalObject());
|
||||
if (childItem) {
|
||||
QQuickItemPrivate *pChild = QQuickItemPrivate::get(childItem);
|
||||
pChild->refFromEffectItem(true);
|
||||
}
|
||||
}
|
||||
|
||||
m_viewData.renderControl->polishItems();
|
||||
m_viewData.renderControl->beginFrame();
|
||||
m_viewData.renderControl->sync();
|
||||
|
||||
// Connection to afterRendering is necessary, as this needs to be done before
|
||||
// call to endNextRhiFrame which happens inside QQuickRenderControl::render()
|
||||
QMetaObject::Connection connection = QObject::connect(m_viewData.window.data(),
|
||||
&QQuickWindow::afterRendering,
|
||||
this, [&]() {
|
||||
// To get only the single item, we need to make a layer out of it, which enables
|
||||
// us to render it to a texture that we can grab to an image.
|
||||
QSGRenderContext *rc = QQuickWindowPrivate::get(m_viewData.window.data())->context;
|
||||
QSGLayer *layer = rc->sceneGraphContext()->createLayer(rc);
|
||||
layer->setItem(pItem->itemNode());
|
||||
QSizeF itemSize = QSizeF(item->width(), item->height());
|
||||
layer->setRect(QRectF(0, itemSize.height(), itemSize.width(), -itemSize.height()));
|
||||
const QSize minSize = rc->sceneGraphContext()->minimumFBOSize();
|
||||
layer->setSize(QSize(qMax(minSize.width(), int(itemSize.width())),
|
||||
qMax(minSize.height(), int(itemSize.height()))));
|
||||
layer->scheduleUpdate();
|
||||
|
||||
if (layer->updateTexture())
|
||||
renderImage = layer->toImage();
|
||||
else
|
||||
qWarning() << __FUNCTION__ << "Failed to update layer texture";
|
||||
|
||||
delete layer;
|
||||
layer = nullptr;
|
||||
});
|
||||
|
||||
m_viewData.renderControl->render();
|
||||
|
||||
QObject::disconnect(connection);
|
||||
|
||||
m_viewData.renderControl->endFrame();
|
||||
|
||||
// Restore visibility of immediate children that have instances and are QQuickItems
|
||||
for (const auto &childInstance : childInstances) {
|
||||
QQuickItem *childItem = qobject_cast<QQuickItem *>(childInstance.internalObject());
|
||||
if (childItem) {
|
||||
QQuickItemPrivate *pChild = QQuickItemPrivate::get(childItem);
|
||||
pChild->derefFromEffectItem(true);
|
||||
}
|
||||
}
|
||||
pItem->derefFromEffectItem(false);
|
||||
#else
|
||||
Q_UNUSED(item)
|
||||
#endif
|
||||
return renderImage;
|
||||
}
|
||||
|
||||
void Qt5NodeInstanceServer::refreshBindings()
|
||||
{
|
||||
DesignerSupport::refreshExpressions(context());
|
||||
|
||||
@@ -69,6 +69,7 @@ public:
|
||||
void reparentInstances(const ReparentInstancesCommand &command) override;
|
||||
|
||||
QImage grabWindow() override;
|
||||
QImage grabItem(QQuickItem *item) override;
|
||||
|
||||
protected:
|
||||
void initializeView() override;
|
||||
|
||||
@@ -102,9 +102,6 @@ void Qt5RenderNodeInstanceServer::collectItemChangesAndSendChangeCommands()
|
||||
clearChangedPropertyList();
|
||||
|
||||
if (Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
||||
/* QQuickItem::grabToImage render path */
|
||||
/* TODO implement QQuickItem::grabToImage based rendering */
|
||||
/* sheduleRootItemRender(); */
|
||||
if (windowDirty)
|
||||
nodeInstanceClient()->pixmapChanged(createPixmapChangedCommand({rootNodeInstance()}));
|
||||
} else {
|
||||
|
||||
@@ -171,10 +171,15 @@ void QuickItemNodeInstance::enableUnifiedRenderPath(bool unifiedRenderPath)
|
||||
|
||||
bool QuickItemNodeInstance::checkIfRefFromEffect(qint32 id)
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
if (s_unifiedRenderPath)
|
||||
return false;
|
||||
|
||||
return (s_createEffectItem || id == 0);
|
||||
#else
|
||||
Q_UNUSED(id)
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void QuickItemNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNodeInstance,
|
||||
@@ -267,9 +272,13 @@ QStringList QuickItemNodeInstance::allStates() const
|
||||
|
||||
void QuickItemNodeInstance::updateDirtyNode(QQuickItem *item)
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
if (s_unifiedRenderPath)
|
||||
return;
|
||||
DesignerSupport::updateDirtyNode(item);
|
||||
#else
|
||||
Q_UNUSED(item)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool QuickItemNodeInstance::unifiedRenderPath()
|
||||
@@ -277,6 +286,15 @@ bool QuickItemNodeInstance::unifiedRenderPath()
|
||||
return s_unifiedRenderPath;
|
||||
}
|
||||
|
||||
bool QuickItemNodeInstance::unifiedRenderPathOrQt6()
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
return true;
|
||||
#else
|
||||
return s_unifiedRenderPath;
|
||||
#endif
|
||||
}
|
||||
|
||||
QRectF QuickItemNodeInstance::contentItemBoundingBox() const
|
||||
{
|
||||
if (contentItem()) {
|
||||
@@ -415,16 +433,15 @@ QImage QuickItemNodeInstance::renderImage() const
|
||||
updateDirtyNodesRecursive(quickItem());
|
||||
|
||||
QRectF renderBoundingRect = boundingRect();
|
||||
QImage renderImage;
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
QSize size = renderBoundingRect.size().toSize();
|
||||
static double devicePixelRatio = qgetenv("FORMEDITOR_DEVICE_PIXEL_RATIO").toDouble();
|
||||
if (size.width() * size.height() > 4000 * 4000)
|
||||
size = QSize(0,0);
|
||||
size *= devicePixelRatio;
|
||||
|
||||
QImage renderImage;
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
if (s_unifiedRenderPath) {
|
||||
renderImage = nodeInstanceServer()->quickWindow()->grabWindow();
|
||||
} else {
|
||||
@@ -438,8 +455,12 @@ QImage QuickItemNodeInstance::renderImage() const
|
||||
}
|
||||
renderImage.setDevicePixelRatio(devicePixelRatio);
|
||||
#else
|
||||
renderImage = nodeInstanceServer()->grabWindow();
|
||||
if (s_unifiedRenderPath)
|
||||
renderImage = nodeInstanceServer()->grabWindow();
|
||||
else
|
||||
renderImage = nodeInstanceServer()->grabItem(quickItem());
|
||||
renderImage = renderImage.copy(renderBoundingRect.toRect());
|
||||
|
||||
/* When grabbing an offscren window the device pixel ratio is 1 */
|
||||
renderImage.setDevicePixelRatio(1);
|
||||
#endif
|
||||
|
||||
@@ -104,6 +104,7 @@ public:
|
||||
|
||||
static void updateDirtyNode(QQuickItem *item);
|
||||
static bool unifiedRenderPath();
|
||||
static bool unifiedRenderPathOrQt6();
|
||||
|
||||
protected:
|
||||
explicit QuickItemNodeInstance(QQuickItem*);
|
||||
|
||||
@@ -165,7 +165,8 @@ Item {
|
||||
(assetsView.verticalScrollBarVisible ? assetsView.verticalThickness : 0)
|
||||
height: img.height
|
||||
color: selectedAssets[filePath] ? StudioTheme.Values.themeInteraction
|
||||
: (mouseArea.containsMouse ? "#444444" : "transparent")
|
||||
: (mouseArea.containsMouse ? StudioTheme.Values.themeSectionHeadBackground
|
||||
: "transparent")
|
||||
|
||||
Row {
|
||||
spacing: 5
|
||||
|
||||
@@ -210,7 +210,7 @@ Section {
|
||||
onClicked: alignDistribute.distributeSpacing(AlignDistribute.X,
|
||||
alignToComboBox.currentEnum,
|
||||
keyObjectComboBox.currentText,
|
||||
distanceSpinBox.realValue,
|
||||
distanceSpinBox.value,
|
||||
buttonRow.getDistributeDirection())
|
||||
}
|
||||
|
||||
@@ -220,11 +220,13 @@ Section {
|
||||
onClicked: alignDistribute.distributeSpacing(AlignDistribute.Y,
|
||||
alignToComboBox.currentEnum,
|
||||
keyObjectComboBox.currentText,
|
||||
distanceSpinBox.realValue,
|
||||
distanceSpinBox.value,
|
||||
buttonRow.getDistributeDirection())
|
||||
}
|
||||
}
|
||||
|
||||
Spacer { implicitWidth: 8 }
|
||||
|
||||
StudioControls.ButtonRow {
|
||||
id: buttonRow
|
||||
actionIndicatorVisible: false
|
||||
@@ -250,6 +252,7 @@ Section {
|
||||
buttonIcon: StudioTheme.Constants.distributeOriginNone
|
||||
checkable: true
|
||||
StudioControls.ButtonGroup.group: group
|
||||
tooltip: qsTr("Disables the distribution of spacing in pixels.")
|
||||
}
|
||||
|
||||
AbstractButton {
|
||||
@@ -257,6 +260,8 @@ Section {
|
||||
buttonIcon: StudioTheme.Constants.distributeOriginTopLeft
|
||||
checkable: true
|
||||
StudioControls.ButtonGroup.group: group
|
||||
tooltip: qsTr("Sets the left or top border of the target area or item as the " +
|
||||
"starting point, depending on the distribution orientation.")
|
||||
}
|
||||
|
||||
AbstractButton {
|
||||
@@ -264,6 +269,9 @@ Section {
|
||||
buttonIcon: StudioTheme.Constants.distributeOriginCenter
|
||||
checkable: true
|
||||
StudioControls.ButtonGroup.group: group
|
||||
tooltip: qsTr("Sets the horizontal or vertical center of the target area or " +
|
||||
"item as the starting point, depending on the distribution " +
|
||||
"orientation.")
|
||||
}
|
||||
|
||||
AbstractButton {
|
||||
@@ -271,6 +279,8 @@ Section {
|
||||
buttonIcon: StudioTheme.Constants.distributeOriginBottomRight
|
||||
checkable: true
|
||||
StudioControls.ButtonGroup.group: group
|
||||
tooltip: qsTr("Sets the bottom or right border of the target area or item as " +
|
||||
"the starting point, depending on the distribution orientation.")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -280,12 +290,13 @@ Section {
|
||||
SecondColumnLayout {
|
||||
Spacer { implicitWidth: StudioTheme.Values.actionIndicatorWidth }
|
||||
|
||||
StudioControls.RealSpinBox {
|
||||
DoubleSpinBox {
|
||||
id: distanceSpinBox
|
||||
implicitWidth: StudioTheme.Values.twoControlColumnWidth
|
||||
actionIndicatorVisible: false
|
||||
realFrom: -1000
|
||||
realTo: 1000
|
||||
stepSize: 1
|
||||
minimumValue: -1000
|
||||
maximumValue: 1000
|
||||
decimals: 0
|
||||
enabled: !buttonNone.checked
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,7 +278,7 @@ QtObject {
|
||||
property string themeStateBackground: Theme.color(Theme.DSstateBackgroundColor)
|
||||
property string themeStatePreviewOutline: Theme.color(Theme.DSstatePreviewOutline)
|
||||
|
||||
property string themeUnimportedModuleColor: "#e33c2e"
|
||||
property string themeUnimportedModuleColor: Theme.color(Theme.DSUnimportedModuleColor)
|
||||
|
||||
// Taken out of Constants.js
|
||||
property string themeChangedStateText: Theme.color(Theme.DSchangedStateText)
|
||||
|
||||
@@ -152,6 +152,8 @@ DStoolTipBackground=ff111111
|
||||
DStoolTipOutline=ffdadada
|
||||
DStoolTipText=ffdadada
|
||||
|
||||
DSUnimportedModuleColor=ffe33c2e
|
||||
|
||||
;DS controls theme END
|
||||
|
||||
BackgroundColorAlternate=alternateBackground
|
||||
|
||||
@@ -143,6 +143,8 @@ DStoolTipBackground=ff111111
|
||||
DStoolTipOutline=ffdadada
|
||||
DStoolTipText=ffdadada
|
||||
|
||||
DSUnimportedModuleColor=ffe33c2e
|
||||
|
||||
;DS controls theme END
|
||||
|
||||
BackgroundColorAlternate=ff3d3d3d
|
||||
|
||||
@@ -157,6 +157,8 @@ DStoolTipBackground=ff111111
|
||||
DStoolTipOutline=ffdadada
|
||||
DStoolTipText=ffdadada
|
||||
|
||||
DSUnimportedModuleColor=ffe33c2e
|
||||
|
||||
;DS controls theme END
|
||||
|
||||
BackgroundColorAlternate=alternateBackground
|
||||
|
||||
@@ -154,6 +154,8 @@ DStoolTipBackground=ff111111
|
||||
DStoolTipOutline=ffdadada
|
||||
DStoolTipText=ffdadada
|
||||
|
||||
DSUnimportedModuleColor=ffe33c2e
|
||||
|
||||
;DS controls theme END
|
||||
|
||||
BackgroundColorAlternate=alternateBackground
|
||||
|
||||
@@ -156,6 +156,8 @@ DStoolTipBackground=ff111111
|
||||
DStoolTipOutline=ffdadada
|
||||
DStoolTipText=ffdadada
|
||||
|
||||
DSUnimportedModuleColor=ffe33c2e
|
||||
|
||||
;DS controls theme END
|
||||
|
||||
BackgroundColorAlternate=alternateBackground
|
||||
|
||||
@@ -152,6 +152,8 @@ DStoolTipBackground=ff111111
|
||||
DStoolTipOutline=ffdadada
|
||||
DStoolTipText=ffdadada
|
||||
|
||||
DSUnimportedModuleColor=ffe33c2e
|
||||
|
||||
;DS controls theme END
|
||||
|
||||
BackgroundColorAlternate=alternateBackground
|
||||
|
||||
@@ -150,6 +150,8 @@ DStoolTipBackground=ff111111
|
||||
DStoolTipOutline=ffdadada
|
||||
DStoolTipText=ffdadada
|
||||
|
||||
DSUnimportedModuleColor=ffe33c2e
|
||||
|
||||
;DS controls theme END
|
||||
|
||||
BackgroundColorAlternate=alternateBackground
|
||||
|
||||
@@ -43,8 +43,9 @@ enum class LanguageVersion : unsigned char {
|
||||
CXX11,
|
||||
CXX14,
|
||||
CXX17,
|
||||
CXX2a,
|
||||
LatestCxx = CXX2a,
|
||||
CXX20,
|
||||
CXX2b,
|
||||
LatestCxx = CXX2b,
|
||||
};
|
||||
|
||||
enum class LanguageExtension : unsigned char {
|
||||
|
||||
@@ -391,7 +391,7 @@ void ShellCommand::runSynchronous(QtcProcess &process, const FilePath &workingDi
|
||||
if (d->m_progressParser)
|
||||
d->m_progressParser->parseProgress(text);
|
||||
if (!(d->m_flags & SuppressStdErr))
|
||||
appendError(text);
|
||||
emit appendError(text);
|
||||
if (d->m_progressiveOutput)
|
||||
emit stdErrText(text);
|
||||
});
|
||||
@@ -403,7 +403,7 @@ void ShellCommand::runSynchronous(QtcProcess &process, const FilePath &workingDi
|
||||
if (d->m_progressParser)
|
||||
d->m_progressParser->parseProgress(text);
|
||||
if (d->m_flags & ShowStdOut)
|
||||
append(text);
|
||||
emit append(text);
|
||||
if (d->m_progressiveOutput) {
|
||||
emit stdOutText(text);
|
||||
d->m_hadOutput = true;
|
||||
|
||||
@@ -417,7 +417,9 @@ public:
|
||||
|
||||
DStoolTipBackground,
|
||||
DStoolTipOutline,
|
||||
DStoolTipText
|
||||
DStoolTipText,
|
||||
|
||||
DSUnimportedModuleColor
|
||||
};
|
||||
|
||||
enum Gradient {
|
||||
|
||||
@@ -47,7 +47,13 @@ QUrl urlFromLocalSocket()
|
||||
{
|
||||
QUrl serverUrl;
|
||||
serverUrl.setScheme(urlSocketScheme());
|
||||
TemporaryFile file("qtcreator-freesocket");
|
||||
TemporaryFile file("qtc-socket");
|
||||
// see "man unix" for unix socket file name size limitations
|
||||
if (file.fileName().size() > 104) {
|
||||
qWarning().nospace()
|
||||
<< "Socket file name \"" << file.fileName()
|
||||
<< "\" is larger than 104 characters, which will not work on Darwin/macOS/Linux!";
|
||||
}
|
||||
if (file.open())
|
||||
serverUrl.setPath(file.fileName());
|
||||
return serverUrl;
|
||||
|
||||
@@ -333,7 +333,7 @@ QString AndroidAvdManager::waitForAvd(const QString &avdName,
|
||||
// 60 rounds of 2s sleeping, two minutes for the avd to start
|
||||
QString serialNumber;
|
||||
for (int i = 0; i < 60; ++i) {
|
||||
if (cancelChecker())
|
||||
if (cancelChecker && cancelChecker())
|
||||
return QString();
|
||||
serialNumber = findAvd(avdName);
|
||||
if (!serialNumber.isEmpty())
|
||||
@@ -365,7 +365,7 @@ bool AndroidAvdManager::waitForBooted(const QString &serialNumber,
|
||||
{
|
||||
// found a serial number, now wait until it's done booting...
|
||||
for (int i = 0; i < 60; ++i) {
|
||||
if (cancelChecker())
|
||||
if (cancelChecker && cancelChecker())
|
||||
return false;
|
||||
if (isAvdBooted(serialNumber)) {
|
||||
return true;
|
||||
|
||||
@@ -176,7 +176,8 @@ AndroidBuildApkWidget::AndroidBuildApkWidget(AndroidBuildApkStep *step)
|
||||
|
||||
QWidget *AndroidBuildApkWidget::createApplicationGroup()
|
||||
{
|
||||
const int minApiSupported = AndroidManager::apiLevelRange().first;
|
||||
QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(m_step->target()->kit());
|
||||
const int minApiSupported = AndroidManager::defaultMinimumSDK(qt);
|
||||
QStringList targets = AndroidConfig::apiLevelNamesFor(AndroidConfigurations::sdkManager()->
|
||||
filteredSdkPlatforms(minApiSupported));
|
||||
targets.removeDuplicates();
|
||||
|
||||
@@ -778,12 +778,12 @@ bool AndroidConfig::isValidNdk(const QString &ndkLocation) const
|
||||
|
||||
QString AndroidConfig::bestNdkPlatformMatch(int target, const BaseQtVersion *qtVersion) const
|
||||
{
|
||||
target = std::max(AndroidManager::apiLevelRange().first, target);
|
||||
target = std::max(AndroidManager::defaultMinimumSDK(qtVersion), target);
|
||||
foreach (int apiLevel, availableNdkPlatforms(qtVersion)) {
|
||||
if (apiLevel <= target)
|
||||
return QString::fromLatin1("android-%1").arg(apiLevel);
|
||||
}
|
||||
return QString("android-%1").arg(AndroidManager::apiLevelRange().first);
|
||||
return QString("android-%1").arg(AndroidManager::defaultMinimumSDK(qtVersion));
|
||||
}
|
||||
|
||||
FilePath AndroidConfig::sdkLocation() const
|
||||
@@ -1291,10 +1291,7 @@ void AndroidConfigurations::updateAutomaticKitList()
|
||||
Id deviceTypeId = DeviceTypeKitAspect::deviceTypeId(k);
|
||||
if (k->isAutoDetected() && !k->isSdkProvided()
|
||||
&& deviceTypeId == Constants::ANDROID_DEVICE_TYPE) {
|
||||
if (!QtKitAspect::qtVersion(k))
|
||||
KitManager::deregisterKit(k); // Remove autoDetected kits without Qt.
|
||||
else
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
@@ -1327,6 +1324,7 @@ void AndroidConfigurations::updateAutomaticKitList()
|
||||
&& tc->isValid()
|
||||
&& tc->typeId() == Constants::ANDROID_TOOLCHAIN_TYPEID;
|
||||
});
|
||||
QList<Kit *> unhandledKits = existingKits;
|
||||
for (ToolChain *tc : toolchains) {
|
||||
if (tc->language() != ProjectExplorer::Constants::CXX_LANGUAGE_ID)
|
||||
continue;
|
||||
@@ -1381,12 +1379,18 @@ void AndroidConfigurations::updateAutomaticKitList()
|
||||
k->setValueSilently(Constants::ANDROID_KIT_SDK, currentConfig().sdkLocation().toString());
|
||||
};
|
||||
|
||||
if (existingKit)
|
||||
if (existingKit) {
|
||||
initializeKit(existingKit); // Update the existing kit with new data.
|
||||
else
|
||||
unhandledKits.removeOne(existingKit);
|
||||
} else {
|
||||
KitManager::registerKit(initializeKit);
|
||||
}
|
||||
}
|
||||
}
|
||||
// cleanup any mess that might have existed before, by removing all Android kits that
|
||||
// existed before, but weren't re-used
|
||||
for (Kit *k : unhandledKits)
|
||||
KitManager::deregisterKit(k);
|
||||
}
|
||||
|
||||
bool AndroidConfigurations::force32bitEmulator()
|
||||
|
||||
@@ -399,9 +399,14 @@ void AndroidManager::setDeviceApiLevel(Target *target, int level)
|
||||
target->setNamedSettings(ApiLevelKey, level);
|
||||
}
|
||||
|
||||
QPair<int, int> AndroidManager::apiLevelRange()
|
||||
int AndroidManager::defaultMinimumSDK(const QtSupport::BaseQtVersion *qtVersion)
|
||||
{
|
||||
return qMakePair(16, 29);
|
||||
if (qtVersion && qtVersion->qtVersion() >= QtSupport::QtVersionNumber{6, 0})
|
||||
return 23;
|
||||
else if (qtVersion && qtVersion->qtVersion() >= QtSupport::QtVersionNumber{5, 13})
|
||||
return 21;
|
||||
else
|
||||
return 16;
|
||||
}
|
||||
|
||||
QString AndroidManager::androidNameForApiLevel(int x)
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <QObject>
|
||||
#include <QVersionNumber>
|
||||
|
||||
#include <qtsupport/baseqtversion.h>
|
||||
#include <projectexplorer/abi.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@@ -87,6 +88,7 @@ public:
|
||||
|
||||
static int minimumSDK(const ProjectExplorer::Target *target);
|
||||
static int minimumSDK(const ProjectExplorer::Kit *kit);
|
||||
static int defaultMinimumSDK(const QtSupport::BaseQtVersion *qtVersion);
|
||||
|
||||
static QStringList applicationAbis(const ProjectExplorer::Target *target);
|
||||
static QString archTriplet(const QString &abi);
|
||||
@@ -100,7 +102,6 @@ public:
|
||||
static QString devicePreferredAbi(const QStringList &deviceAbis, const QStringList &appAbis);
|
||||
static ProjectExplorer::Abi androidAbi2Abi(const QString &androidAbi);
|
||||
|
||||
static QPair<int, int> apiLevelRange();
|
||||
static QString androidNameForApiLevel(int x);
|
||||
|
||||
static void installQASIPackage(ProjectExplorer::Target *target, const Utils::FilePath &packagePath);
|
||||
|
||||
@@ -720,18 +720,21 @@ void AndroidManifestEditorWidget::updateInfoBar()
|
||||
|
||||
void AndroidManifestEditorWidget::updateSdkVersions()
|
||||
{
|
||||
QPair<int, int> apiLevels = AndroidManager::apiLevelRange();
|
||||
for (int i = apiLevels.first; i < apiLevels.second + 1; ++i)
|
||||
m_androidMinSdkVersion->addItem(tr("API %1: %2")
|
||||
.arg(i)
|
||||
.arg(AndroidManager::androidNameForApiLevel(i)),
|
||||
i);
|
||||
static const QPair<int, int> sdkPair = qMakePair(16, 31);
|
||||
int minSdk = sdkPair.first;
|
||||
const int targetSdk = sdkPair.second;
|
||||
const Target *target = androidTarget(m_textEditorWidget->textDocument()->filePath());
|
||||
if (target) {
|
||||
const QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(target->kit());
|
||||
minSdk = AndroidManager::defaultMinimumSDK(qt);
|
||||
}
|
||||
|
||||
for (int i = apiLevels.first; i < apiLevels.second + 1; ++i)
|
||||
m_androidTargetSdkVersion->addItem(tr("API %1: %2")
|
||||
.arg(i)
|
||||
.arg(AndroidManager::androidNameForApiLevel(i)),
|
||||
i);
|
||||
for (int i = minSdk; i <= targetSdk; ++i) {
|
||||
const QString apiStr = tr("API %1: %2").arg(i)
|
||||
.arg(AndroidManager::androidNameForApiLevel(i));
|
||||
m_androidMinSdkVersion->addItem(apiStr, i);
|
||||
m_androidTargetSdkVersion->addItem(apiStr, i);
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidManifestEditorWidget::updateInfoBar(const QString &errorMessage, int line, int column)
|
||||
|
||||
@@ -191,12 +191,14 @@ static bool isChildOf(const FilePath &path, const QStringList &prefixes)
|
||||
|
||||
QList<CMakeBuildTarget> generateBuildTargets(const PreprocessedData &input,
|
||||
const FilePath &sourceDirectory,
|
||||
const FilePath &buildDirectory)
|
||||
const FilePath &buildDirectory,
|
||||
bool haveLibrariesRelativeToBuildDirectory)
|
||||
{
|
||||
QDir sourceDir(sourceDirectory.toString());
|
||||
|
||||
const QList<CMakeBuildTarget> result = transform<QList>(input.targetDetails,
|
||||
[&sourceDir, &sourceDirectory, &buildDirectory](const TargetDetails &t) {
|
||||
[&sourceDir, &sourceDirectory, &buildDirectory,
|
||||
&haveLibrariesRelativeToBuildDirectory](const TargetDetails &t) {
|
||||
const FilePath currentBuildDir = buildDirectory.absoluteFilePath(t.buildDir);
|
||||
|
||||
CMakeBuildTarget ct;
|
||||
@@ -271,7 +273,8 @@ QList<CMakeBuildTarget> generateBuildTargets(const PreprocessedData &input,
|
||||
if (part.startsWith("-"))
|
||||
continue;
|
||||
|
||||
FilePath tmp = currentBuildDir.absoluteFilePath(FilePath::fromUserInput(part));
|
||||
const FilePath buildDir = haveLibrariesRelativeToBuildDirectory ? buildDirectory : currentBuildDir;
|
||||
FilePath tmp = buildDir.absoluteFilePath(FilePath::fromUserInput(part));
|
||||
|
||||
if (f.role == "libraries")
|
||||
tmp = tmp.parentDir();
|
||||
@@ -707,7 +710,12 @@ FileApiQtcData extractData(FileApiData &input,
|
||||
return {};
|
||||
}
|
||||
|
||||
result.buildTargets = generateBuildTargets(data, sourceDirectory, buildDirectory);
|
||||
// Ninja generator from CMake version 3.20.5 has libraries relative to build directory
|
||||
const bool haveLibrariesRelativeToBuildDirectory =
|
||||
input.replyFile.generator.startsWith("Ninja")
|
||||
&& input.replyFile.cmakeVersion >= QVersionNumber(3, 20, 5);
|
||||
|
||||
result.buildTargets = generateBuildTargets(data, sourceDirectory, buildDirectory, haveLibrariesRelativeToBuildDirectory);
|
||||
result.cmakeFiles = std::move(data.cmakeFiles);
|
||||
result.projectParts = generateRawProjectParts(data, sourceDirectory);
|
||||
|
||||
|
||||
@@ -147,6 +147,13 @@ static ReplyFileContents readReplyFile(const FilePath &filePath, QString &errorM
|
||||
result.generator = generator.value("name").toString();
|
||||
result.isMultiConfig = generator.value("multiConfig").toBool();
|
||||
}
|
||||
const QJsonObject version = cmakeObject.value("version").toObject();
|
||||
{
|
||||
int major = version.value("major").toInt();
|
||||
int minor = version.value("minor").toInt();
|
||||
int patch = version.value("patch").toInt();
|
||||
result.cmakeVersion = QVersionNumber(major, minor, patch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <QFutureInterface>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
#include <QVersionNumber>
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -65,6 +66,7 @@ public:
|
||||
QString cmakeRoot;
|
||||
|
||||
QVector<ReplyObject> replies;
|
||||
QVersionNumber cmakeVersion;
|
||||
|
||||
Utils::FilePath jsonFile(const QString &kind, const Utils::FilePath &replyDir) const;
|
||||
};
|
||||
|
||||
@@ -164,7 +164,8 @@ QStringList CppcheckTool::additionalArguments(const CppTools::ProjectPart &part)
|
||||
break;
|
||||
case Version::CXX98:
|
||||
case Version::CXX17:
|
||||
case Version::CXX2a:
|
||||
case Version::CXX20:
|
||||
case Version::CXX2b:
|
||||
result.push_back("--language=c++");
|
||||
break;
|
||||
case Version::None:
|
||||
|
||||
@@ -92,15 +92,15 @@ public:
|
||||
filePaths << absoluteFilePath;
|
||||
}
|
||||
|
||||
// Update Code Model
|
||||
QVERIFY(parseFiles(filePaths));
|
||||
|
||||
// Open Editor
|
||||
const QString fileName = temporaryDir.path() + QLatin1String("/file1.h");
|
||||
CppEditor *editor;
|
||||
QVERIFY(openCppEditor(fileName, &editor));
|
||||
closeEditorAtEndOfTestCase(editor);
|
||||
|
||||
// Update Code Model
|
||||
QVERIFY(parseFiles(filePaths));
|
||||
|
||||
// Test model
|
||||
CppIncludeHierarchyModel model;
|
||||
model.buildHierarchy(editor->document()->filePath().toString());
|
||||
|
||||
@@ -472,7 +472,10 @@ void CompilerOptionsBuilder::addLanguageVersionAndExtensions()
|
||||
case LanguageVersion::CXX17:
|
||||
option = "/std:c++17";
|
||||
break;
|
||||
case LanguageVersion::CXX2a:
|
||||
case LanguageVersion::CXX20:
|
||||
option = "/std:c++20";
|
||||
break;
|
||||
case LanguageVersion::CXX2b:
|
||||
option = "/std:c++latest";
|
||||
break;
|
||||
}
|
||||
@@ -517,8 +520,11 @@ void CompilerOptionsBuilder::addLanguageVersionAndExtensions()
|
||||
case LanguageVersion::CXX17:
|
||||
option = (gnuExtensions ? QLatin1String("-std=gnu++17") : QLatin1String("-std=c++17"));
|
||||
break;
|
||||
case LanguageVersion::CXX2a:
|
||||
option = (gnuExtensions ? QLatin1String("-std=gnu++2a") : QLatin1String("-std=c++2a"));
|
||||
case LanguageVersion::CXX20:
|
||||
option = (gnuExtensions ? QLatin1String("-std=gnu++20") : QLatin1String("-std=c++20"));
|
||||
break;
|
||||
case LanguageVersion::CXX2b:
|
||||
option = (gnuExtensions ? QLatin1String("-std=gnu++2b") : QLatin1String("-std=c++2b"));
|
||||
break;
|
||||
case LanguageVersion::None:
|
||||
break;
|
||||
@@ -868,6 +874,14 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
|
||||
theOption[0] = '-';
|
||||
}
|
||||
|
||||
// Clang-cl (as of Clang 12) frontend doesn't know about -std:c++20
|
||||
// but the clang front end knows about -std=c++20
|
||||
// https://github.com/llvm/llvm-project/blob/release/12.x/clang/lib/Driver/ToolChains/Clang.cpp#L5855
|
||||
if (toolChain == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID ||
|
||||
toolChain == ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID) {
|
||||
theOption.replace("-std:c++20", "-clang:-std=c++20");
|
||||
}
|
||||
|
||||
m_compilerFlags.flags.append(theOption);
|
||||
}
|
||||
|
||||
|
||||
@@ -123,7 +123,8 @@ QString Utils::toString(::Utils::LanguageVersion languageVersion)
|
||||
CASE_LANGUAGEVERSION(CXX11);
|
||||
CASE_LANGUAGEVERSION(CXX14);
|
||||
CASE_LANGUAGEVERSION(CXX17);
|
||||
CASE_LANGUAGEVERSION(CXX2a);
|
||||
CASE_LANGUAGEVERSION(CXX20);
|
||||
CASE_LANGUAGEVERSION(CXX2b);
|
||||
// no default to get a compiler warning if anything is added
|
||||
}
|
||||
#undef CASE_LANGUAGEVERSION
|
||||
|
||||
@@ -235,7 +235,7 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const
|
||||
}
|
||||
case Qt::DecorationRole: {
|
||||
if (!folderNode)
|
||||
return Core::FileIconProvider::icon(node->filePath());
|
||||
return node->asFileNode()->icon();
|
||||
if (!project)
|
||||
return folderNode->icon();
|
||||
static QIcon warnIcon = Utils::Icons::WARNING.icon();
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <utils/pointeralgorithm.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/stringutils.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
@@ -252,6 +253,35 @@ bool Node::isEnabled() const
|
||||
return parent ? parent->isEnabled() : true;
|
||||
}
|
||||
|
||||
QIcon FileNode::icon() const
|
||||
{
|
||||
if (hasError())
|
||||
return Utils::Icons::WARNING.icon();
|
||||
if (m_icon.isNull())
|
||||
m_icon = Core::FileIconProvider::icon(filePath());
|
||||
return m_icon;
|
||||
}
|
||||
|
||||
void FileNode::setIcon(const QIcon icon)
|
||||
{
|
||||
m_icon = icon;
|
||||
}
|
||||
|
||||
bool FileNode::hasError() const
|
||||
{
|
||||
return m_hasError;
|
||||
}
|
||||
|
||||
void FileNode::setHasError(bool error)
|
||||
{
|
||||
m_hasError = error;
|
||||
}
|
||||
|
||||
void FileNode::setHasError(bool error) const
|
||||
{
|
||||
m_hasError = error;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns \c true if the file is automatically generated by a compile step.
|
||||
*/
|
||||
|
||||
@@ -218,8 +218,17 @@ public:
|
||||
bool supportsAction(ProjectAction action, const Node *node) const override;
|
||||
QString displayName() const override;
|
||||
|
||||
bool hasError() const;
|
||||
void setHasError(const bool error);
|
||||
void setHasError(const bool error) const;
|
||||
|
||||
QIcon icon() const;
|
||||
void setIcon(const QIcon icon);
|
||||
|
||||
private:
|
||||
FileType m_fileType;
|
||||
mutable QIcon m_icon;
|
||||
mutable bool m_hasError = false;
|
||||
};
|
||||
|
||||
// Documentation inside.
|
||||
|
||||
@@ -10,6 +10,7 @@ add_qtc_plugin(QmlDesigner
|
||||
DEFINES
|
||||
DESIGNER_CORE_LIBRARY
|
||||
IDE_LIBRARY_BASENAME=\"${IDE_LIBRARY_BASE_PATH}\"
|
||||
SHARE_QML_PATH="${CMAKE_CURRENT_SOURCE_DIR}/../../../share/qtcreator/qmldesigner"
|
||||
PUBLIC_INCLUDES
|
||||
"${CMAKE_CURRENT_LIST_DIR}"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/designercore/include"
|
||||
|
||||
@@ -48,6 +48,24 @@ static QString styleConfigFileName(const QString &qmlFileName)
|
||||
|
||||
ChangeStyleWidgetAction::ChangeStyleWidgetAction(QObject *parent) : QWidgetAction(parent)
|
||||
{
|
||||
// The Default style was renamed to Basic in Qt 6. In Qt 6, "Default"
|
||||
// will result in a platform-specific style being chosen.
|
||||
items = {
|
||||
{"Basic", "Basic", {}},
|
||||
{"Default", "Default", {}},
|
||||
{"Fusion", "Fusion", {}},
|
||||
{"Imagine", "Imagine", {}},
|
||||
{"Material Light", "Material", "Light"},
|
||||
{"Material Dark", "Material", "Dark"},
|
||||
{"Universal Light", "Universal", "Light"},
|
||||
{"Universal Dark", "Universal", "Dark"},
|
||||
{"Universal System", "Universal", "System"}
|
||||
};
|
||||
|
||||
if (Utils::HostOsInfo::isMacHost())
|
||||
items.append({"macOS", "macOS", {}});
|
||||
if (Utils::HostOsInfo::isWindowsHost())
|
||||
items.append({"Windows", "Windows", {}});
|
||||
}
|
||||
|
||||
void ChangeStyleWidgetAction::handleModelUpdate(const QString &style)
|
||||
@@ -55,6 +73,48 @@ void ChangeStyleWidgetAction::handleModelUpdate(const QString &style)
|
||||
emit modelUpdated(style);
|
||||
}
|
||||
|
||||
const QList<StyleWidgetEntry> ChangeStyleWidgetAction::styleItems() const
|
||||
{
|
||||
return items;
|
||||
}
|
||||
|
||||
void ChangeStyleWidgetAction::changeStyle(const QString &style)
|
||||
{
|
||||
if (style.isEmpty())
|
||||
return;
|
||||
|
||||
const Utils::FilePath configFileName = Utils::FilePath::fromString(styleConfigFileName(qmlFileName));
|
||||
|
||||
if (configFileName.exists()) {
|
||||
QSettings infiFile(configFileName.toString(), QSettings::IniFormat);
|
||||
|
||||
int contains = -1;
|
||||
|
||||
for (const auto &item : qAsConst(items)) {
|
||||
if (item.displayName == style) {
|
||||
contains = items.indexOf(item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (contains >= 0) {
|
||||
const QString styleName = items.at(contains).styleName;
|
||||
const QString styleTheme = items.at(contains).styleTheme;
|
||||
|
||||
infiFile.setValue("Controls/Style", styleName);
|
||||
|
||||
if (!styleTheme.isEmpty())
|
||||
infiFile.setValue((styleName + "/Theme"), styleTheme);
|
||||
}
|
||||
else {
|
||||
infiFile.setValue("Controls/Style", style);
|
||||
}
|
||||
|
||||
if (view)
|
||||
view->resetPuppet();
|
||||
}
|
||||
}
|
||||
|
||||
const char enabledTooltip[] = QT_TRANSLATE_NOOP("ChangeStyleWidgetAction",
|
||||
"Change style for Qt Quick Controls 2.");
|
||||
const char disbledTooltip[] = QT_TRANSLATE_NOOP("ChangeStyleWidgetAction",
|
||||
@@ -64,18 +124,10 @@ QWidget *ChangeStyleWidgetAction::createWidget(QWidget *parent)
|
||||
{
|
||||
auto comboBox = new QComboBox(parent);
|
||||
comboBox->setToolTip(tr(enabledTooltip));
|
||||
// The Default style was renamed to Basic in Qt 6. In Qt 6, "Default"
|
||||
// will result in a platform-specific style being chosen.
|
||||
comboBox->addItem("Basic");
|
||||
comboBox->addItem("Default");
|
||||
comboBox->addItem("Fusion");
|
||||
comboBox->addItem("Imagine");
|
||||
if (Utils::HostOsInfo::isMacHost())
|
||||
comboBox->addItem("macOS");
|
||||
comboBox->addItem("Material");
|
||||
comboBox->addItem("Universal");
|
||||
if (Utils::HostOsInfo::isWindowsHost())
|
||||
comboBox->addItem("Windows");
|
||||
|
||||
for (const auto &item : qAsConst(items))
|
||||
comboBox->addItem(item.displayName);
|
||||
|
||||
comboBox->setEditable(true);
|
||||
comboBox->setCurrentIndex(0);
|
||||
|
||||
@@ -97,23 +149,8 @@ QWidget *ChangeStyleWidgetAction::createWidget(QWidget *parent)
|
||||
}
|
||||
});
|
||||
|
||||
connect(comboBox,
|
||||
&QComboBox::textActivated,
|
||||
this,
|
||||
[this](const QString &style) {
|
||||
|
||||
if (style.isEmpty())
|
||||
return;
|
||||
|
||||
const Utils::FilePath configFileName = Utils::FilePath::fromString(styleConfigFileName(qmlFileName));
|
||||
|
||||
if (configFileName.exists()) {
|
||||
QSettings infiFile(configFileName.toString(), QSettings::IniFormat);
|
||||
infiFile.setValue("Controls/Style", style);
|
||||
if (view)
|
||||
view->resetPuppet();
|
||||
}
|
||||
});
|
||||
connect(comboBox, &QComboBox::textActivated,
|
||||
this, &ChangeStyleWidgetAction::changeStyle);
|
||||
|
||||
return comboBox;
|
||||
}
|
||||
@@ -135,11 +172,27 @@ void ChangeStyleAction::currentContextChanged(const SelectionContext &selectionC
|
||||
|
||||
if (Utils::FilePath::fromString(confFileName).exists()) {
|
||||
QSettings infiFile(confFileName, QSettings::IniFormat);
|
||||
m_action->handleModelUpdate(infiFile.value("Controls/Style", "Basic").toString());
|
||||
const QString styleName = infiFile.value("Controls/Style", "Basic").toString();
|
||||
const QString styleTheme = infiFile.value(styleName + "/Theme", "").toString();
|
||||
const auto items = m_action->styleItems();
|
||||
|
||||
QString comboBoxEntry = styleName;
|
||||
|
||||
for (const auto &item : items) {
|
||||
if (item.styleName == styleName) {
|
||||
if (!styleTheme.isEmpty() && (item.styleTheme == styleTheme)) {
|
||||
comboBoxEntry.append(" ");
|
||||
comboBoxEntry.append(styleTheme);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_action->handleModelUpdate(comboBoxEntry);
|
||||
} else {
|
||||
m_action->handleModelUpdate("");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,24 @@ namespace QmlDesigner {
|
||||
|
||||
class AbstractView;
|
||||
|
||||
struct StyleWidgetEntry {
|
||||
QString displayName;
|
||||
|
||||
QString styleName;
|
||||
QString styleTheme;
|
||||
|
||||
bool operator==(const StyleWidgetEntry &entry) const {
|
||||
if (displayName != entry.displayName)
|
||||
return false;
|
||||
if (styleName != entry.styleName)
|
||||
return false;
|
||||
if (styleTheme != entry.styleTheme)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
};
|
||||
|
||||
class ChangeStyleWidgetAction : public QWidgetAction
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -46,6 +64,11 @@ public:
|
||||
explicit ChangeStyleWidgetAction(QObject *parent = nullptr);
|
||||
void handleModelUpdate(const QString &style);
|
||||
|
||||
const QList<StyleWidgetEntry> styleItems() const;
|
||||
|
||||
public slots:
|
||||
void changeStyle(const QString &style);
|
||||
|
||||
protected:
|
||||
QWidget *createWidget(QWidget *parent) override;
|
||||
|
||||
@@ -55,6 +78,8 @@ signals:
|
||||
public:
|
||||
QString qmlFileName;
|
||||
QPointer<AbstractView> view;
|
||||
|
||||
QList<StyleWidgetEntry> items;
|
||||
};
|
||||
|
||||
class ChangeStyleAction : public ActionInterface
|
||||
|
||||
@@ -128,7 +128,7 @@ QString Theme::replaceCssColors(const QString &input)
|
||||
void Theme::setupTheme(QQmlEngine *engine)
|
||||
{
|
||||
static const int typeIndex = qmlRegisterSingletonType<Theme>(
|
||||
"QtQuickDesignerTheme", 1, 0, "Theme", [](QQmlEngine *engine, QJSEngine *) {
|
||||
"QtQuickDesignerTheme", 1, 0, "Theme", [](QQmlEngine *, QJSEngine *) {
|
||||
return new Theme(Utils::creatorTheme(), nullptr);
|
||||
});
|
||||
Q_UNUSED(typeIndex)
|
||||
|
||||
@@ -79,6 +79,10 @@ namespace QmlDesigner {
|
||||
|
||||
static QString propertyEditorResourcesPath()
|
||||
{
|
||||
#ifdef SHARE_QML_PATH
|
||||
if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
||||
return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources";
|
||||
#endif
|
||||
return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString();
|
||||
}
|
||||
|
||||
@@ -376,6 +380,10 @@ void ItemLibraryWidget::handleTabChanged(int index)
|
||||
|
||||
QString ItemLibraryWidget::qmlSourcesPath()
|
||||
{
|
||||
#ifdef SHARE_QML_PATH
|
||||
if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
||||
return QLatin1String(SHARE_QML_PATH) + "/itemLibraryQmlSources";
|
||||
#endif
|
||||
return Core::ICore::resourcePath("qmldesigner/itemLibraryQmlSources").toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,10 @@
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <projectexplorer/projectnodes.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/icon.h>
|
||||
#include <utils/utilsicons.h>
|
||||
@@ -169,6 +173,29 @@ void NavigatorView::modelAttached(Model *model)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
clearExplorerWarnings();
|
||||
}
|
||||
|
||||
void NavigatorView::clearExplorerWarnings()
|
||||
{
|
||||
QList<ModelNode> allNodes;
|
||||
addNodeAndSubModelNodesToList(rootModelNode(), allNodes);
|
||||
for (ModelNode node : allNodes) {
|
||||
if (node.metaInfo().isFileComponent()) {
|
||||
const ProjectExplorer::FileNode *fnode = fileNodeForModelNode(node);
|
||||
if (fnode)
|
||||
fnode->setHasError(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NavigatorView::addNodeAndSubModelNodesToList(const ModelNode &node, QList<ModelNode> &nodes)
|
||||
{
|
||||
nodes.append(node);
|
||||
for (ModelNode subNode : node.allSubModelNodes()) {
|
||||
addNodeAndSubModelNodesToList(subNode, nodes);
|
||||
}
|
||||
}
|
||||
|
||||
void NavigatorView::modelAboutToBeDetached(Model *model)
|
||||
@@ -342,8 +369,10 @@ void NavigatorView::auxiliaryDataChanged(const ModelNode &modelNode,
|
||||
|
||||
void NavigatorView::instanceErrorChanged(const QVector<ModelNode> &errorNodeList)
|
||||
{
|
||||
for (const ModelNode &modelNode : errorNodeList)
|
||||
for (const ModelNode &modelNode : errorNodeList) {
|
||||
m_currentModelInterface->notifyDataChanged(modelNode);
|
||||
propagateInstanceErrorToExplorer(modelNode);
|
||||
}
|
||||
}
|
||||
|
||||
void NavigatorView::nodeOrderChanged(const NodeListProperty &listProperty)
|
||||
@@ -374,6 +403,52 @@ QAbstractItemModel *NavigatorView::currentModel() const
|
||||
return treeWidget()->model();
|
||||
}
|
||||
|
||||
const ProjectExplorer::FileNode *NavigatorView::fileNodeForModelNode(const ModelNode &node) const
|
||||
{
|
||||
QString filename = node.metaInfo().componentFileName();
|
||||
Utils::FilePath filePath = Utils::FilePath::fromString(filename);
|
||||
ProjectExplorer::Project *currentProject = ProjectExplorer::SessionManager::projectForFile(
|
||||
filePath);
|
||||
|
||||
if (!currentProject) {
|
||||
filePath = Utils::FilePath::fromString(node.model()->fileUrl().toLocalFile());
|
||||
|
||||
/* If the component does not belong to the project then we can fallback to the current file */
|
||||
currentProject = ProjectExplorer::SessionManager::projectForFile(filePath);
|
||||
}
|
||||
if (!currentProject)
|
||||
return nullptr;
|
||||
|
||||
return currentProject->nodeForFilePath(filePath)->asFileNode();
|
||||
}
|
||||
|
||||
const ProjectExplorer::FileNode *NavigatorView::fileNodeForIndex(const QModelIndex &index) const
|
||||
{
|
||||
if (index.isValid() && currentModel()->data(index, Qt::UserRole).isValid()) {
|
||||
ModelNode node = modelNodeForIndex(index);
|
||||
if (node.metaInfo().isFileComponent()) {
|
||||
return fileNodeForModelNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void NavigatorView::propagateInstanceErrorToExplorer(const ModelNode &modelNode) {
|
||||
QModelIndex index = indexForModelNode(modelNode);;
|
||||
|
||||
do {
|
||||
const ProjectExplorer::FileNode *fnode = fileNodeForIndex(index);
|
||||
if (fnode) {
|
||||
fnode->setHasError(true);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
index = index.parent();
|
||||
}
|
||||
} while (index.isValid());
|
||||
}
|
||||
|
||||
void NavigatorView::leftButtonClicked()
|
||||
{
|
||||
if (selectedModelNodes().count() > 1)
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "navigatormodelinterface.h"
|
||||
|
||||
#include <abstractview.h>
|
||||
#include <projectexplorer/projectnodes.h>
|
||||
|
||||
#include <QPointer>
|
||||
#include <QHash>
|
||||
@@ -108,6 +109,7 @@ private:
|
||||
void changeToComponent(const QModelIndex &index);
|
||||
QModelIndex indexForModelNode(const ModelNode &modelNode) const;
|
||||
QAbstractItemModel *currentModel() const;
|
||||
void propagateInstanceErrorToExplorer(const ModelNode &modelNode);
|
||||
|
||||
void leftButtonClicked();
|
||||
void rightButtonClicked();
|
||||
@@ -123,6 +125,10 @@ protected: //functions
|
||||
void expandAncestors(const QModelIndex &index);
|
||||
void reparentAndCatch(NodeAbstractProperty property, const ModelNode &modelNode);
|
||||
void setupWidget();
|
||||
void addNodeAndSubModelNodesToList(const ModelNode &node, QList<ModelNode> &nodes);
|
||||
void clearExplorerWarnings();
|
||||
const ProjectExplorer::FileNode *fileNodeForModelNode(const ModelNode &node) const;
|
||||
const ProjectExplorer::FileNode *fileNodeForIndex(const QModelIndex &index) const;
|
||||
|
||||
private:
|
||||
bool m_blockSelectionChangedSignal;
|
||||
|
||||
@@ -47,8 +47,9 @@
|
||||
#include <QApplication>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QVector3D>
|
||||
#include <QVector2D>
|
||||
#include <QVector3D>
|
||||
#include <QVector4D>
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
@@ -343,6 +344,18 @@ void PropertyEditorQmlBackend::setValue(const QmlObjectNode & , const PropertyNa
|
||||
if (propertyValue)
|
||||
propertyValue->setValue(QVariant(vecValue[i]));
|
||||
}
|
||||
} else if (value.type() == QVariant::Vector4D) {
|
||||
const char *suffix[4] = {"_x", "_y", "_z", "_w"};
|
||||
auto vecValue = value.value<QVector4D>();
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
PropertyName subPropName(name.size() + 2, '\0');
|
||||
subPropName.replace(0, name.size(), name);
|
||||
subPropName.replace(name.size(), 2, suffix[i]);
|
||||
auto propertyValue = qobject_cast<PropertyEditorValue *>(
|
||||
variantToQObject(m_backendValuesPropertyMap.value(QString::fromUtf8(subPropName))));
|
||||
if (propertyValue)
|
||||
propertyValue->setValue(QVariant(vecValue[i]));
|
||||
}
|
||||
} else {
|
||||
PropertyName propertyName = name;
|
||||
propertyName.replace('.', '_');
|
||||
@@ -532,6 +545,10 @@ void PropertyEditorQmlBackend::initialSetup(const TypeName &typeName, const QUrl
|
||||
|
||||
QString PropertyEditorQmlBackend::propertyEditorResourcesPath()
|
||||
{
|
||||
#ifdef SHARE_QML_PATH
|
||||
if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
||||
return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources";
|
||||
#endif
|
||||
return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -227,14 +227,21 @@ void PropertyEditorView::changeValue(const QString &name)
|
||||
removePropertyFromModel(propertyName);
|
||||
} else {
|
||||
// QVector*D(0, 0, 0) detects as null variant though it is valid value
|
||||
if (castedValue.isValid() && (!castedValue.isNull()
|
||||
|| castedValue.type() == QVariant::Vector2D
|
||||
|| castedValue.type() == QVariant::Vector3D)) {
|
||||
if (castedValue.isValid()
|
||||
&& (!castedValue.isNull() || castedValue.type() == QVariant::Vector2D
|
||||
|| castedValue.type() == QVariant::Vector3D
|
||||
|| castedValue.type() == QVariant::Vector4D)) {
|
||||
commitVariantValueToModel(propertyName, castedValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool isTrueFalseLiteral(const QString &expression)
|
||||
{
|
||||
return (expression.compare("false", Qt::CaseInsensitive) == 0)
|
||||
|| (expression.compare("true", Qt::CaseInsensitive) == 0);
|
||||
}
|
||||
|
||||
void PropertyEditorView::changeExpression(const QString &propertyName)
|
||||
{
|
||||
PropertyName name = propertyName.toUtf8();
|
||||
@@ -267,9 +274,8 @@ void PropertyEditorView::changeExpression(const QString &propertyName)
|
||||
return;
|
||||
}
|
||||
} else if (qmlObjectNode->modelNode().metaInfo().propertyTypeName(name) == "bool") {
|
||||
if (value->expression().compare(QLatin1String("false"), Qt::CaseInsensitive) == 0
|
||||
|| value->expression().compare(QLatin1String("true"), Qt::CaseInsensitive) == 0) {
|
||||
if (value->expression().compare(QLatin1String("true"), Qt::CaseInsensitive) == 0)
|
||||
if (isTrueFalseLiteral(value->expression())) {
|
||||
if (value->expression().compare("true", Qt::CaseInsensitive) == 0)
|
||||
qmlObjectNode->setVariantProperty(name, true);
|
||||
else
|
||||
qmlObjectNode->setVariantProperty(name, false);
|
||||
@@ -289,6 +295,19 @@ void PropertyEditorView::changeExpression(const QString &propertyName)
|
||||
qmlObjectNode->setVariantProperty(name, realValue);
|
||||
return;
|
||||
}
|
||||
} else if (qmlObjectNode->modelNode().metaInfo().propertyTypeName(name) == "QVariant") {
|
||||
bool ok;
|
||||
qreal realValue = value->expression().toDouble(&ok);
|
||||
if (ok) {
|
||||
qmlObjectNode->setVariantProperty(name, realValue);
|
||||
return;
|
||||
} else if (isTrueFalseLiteral(value->expression())) {
|
||||
if (value->expression().compare("true", Qt::CaseInsensitive) == 0)
|
||||
qmlObjectNode->setVariantProperty(name, true);
|
||||
else
|
||||
qmlObjectNode->setVariantProperty(name, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -894,7 +894,8 @@ QmlItemNode QmlAnchorBindingProxy::targetIdToNode(const QString &id) const
|
||||
|
||||
QString QmlAnchorBindingProxy::idForNode(const QmlItemNode &qmlItemNode) const
|
||||
{
|
||||
QTC_ASSERT(qmlItemNode.modelNode().isValid(), return {});
|
||||
if (!qmlItemNode.modelNode().isValid())
|
||||
return {};
|
||||
|
||||
if (!qmlItemNode.isValid())
|
||||
return qmlItemNode.id();
|
||||
|
||||
@@ -58,6 +58,10 @@ namespace QmlDesigner {
|
||||
|
||||
static QString propertyEditorResourcesPath()
|
||||
{
|
||||
#ifdef SHARE_QML_PATH
|
||||
if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
||||
return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources";
|
||||
#endif
|
||||
return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString();
|
||||
}
|
||||
|
||||
@@ -122,6 +126,10 @@ StatesEditorWidget::~StatesEditorWidget() = default;
|
||||
|
||||
QString StatesEditorWidget::qmlSourcesPath()
|
||||
{
|
||||
#ifdef SHARE_QML_PATH
|
||||
if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
||||
return QLatin1String(SHARE_QML_PATH) + "/statesEditorQmlSources";
|
||||
#endif
|
||||
return Core::ICore::resourcePath("qmldesigner/statesEditorQmlSources").toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,8 +32,9 @@
|
||||
|
||||
#include <QDebug>
|
||||
#include <QPainter>
|
||||
#include <QVector3D>
|
||||
#include <QVector2D>
|
||||
#include <QVector3D>
|
||||
#include <QVector4D>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
void qt_blurImage(QPainter *painter, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0);
|
||||
@@ -352,6 +353,28 @@ QVariant NodeInstance::property(const PropertyName &name) const
|
||||
break;
|
||||
}
|
||||
return QVariant(subValue);
|
||||
} else if (varValue.type() == QVariant::Vector4D) {
|
||||
auto value = varValue.value<QVector4D>();
|
||||
char subProp = name.right(1)[0];
|
||||
float subValue = 0.f;
|
||||
switch (subProp) {
|
||||
case 'x':
|
||||
subValue = value.x();
|
||||
break;
|
||||
case 'y':
|
||||
subValue = value.y();
|
||||
break;
|
||||
case 'z':
|
||||
subValue = value.z();
|
||||
break;
|
||||
case 'w':
|
||||
subValue = value.w();
|
||||
break;
|
||||
default:
|
||||
subValue = 0.f;
|
||||
break;
|
||||
}
|
||||
return QVariant(subValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -443,6 +466,24 @@ void NodeInstance::setProperty(const PropertyName &name, const QVariant &value)
|
||||
update = true;
|
||||
}
|
||||
newValueVar = newValue;
|
||||
} else if (oldValue.type() == QVariant::Vector4D) {
|
||||
QVector4D newValue;
|
||||
if (oldValue.type() == QVariant::Vector4D)
|
||||
newValue = oldValue.value<QVector4D>();
|
||||
if (name.endsWith(".x")) {
|
||||
newValue.setX(value.toFloat());
|
||||
update = true;
|
||||
} else if (name.endsWith(".y")) {
|
||||
newValue.setY(value.toFloat());
|
||||
update = true;
|
||||
} else if (name.endsWith(".z")) {
|
||||
newValue.setZ(value.toFloat());
|
||||
update = true;
|
||||
} else if (name.endsWith(".w")) {
|
||||
newValue.setW(value.toFloat());
|
||||
update = true;
|
||||
}
|
||||
newValueVar = newValue;
|
||||
}
|
||||
if (update) {
|
||||
d->propertyValues.insert(parentPropName, newValueVar);
|
||||
|
||||