Merge remote-tracking branch 'origin/4.11'

Conflicts:
	src/plugins/autotest/testresultspane.cpp
	src/plugins/cmakeprojectmanager/cmaketool.cpp

Change-Id: Iade695ac9cab8bf3e3a1abd6e2c71f4a19132ac0
This commit is contained in:
Eike Ziller
2019-11-19 17:01:08 +01:00
committed by Orgad Shaneh
125 changed files with 5446 additions and 2030 deletions

View File

@@ -8,7 +8,7 @@ The standalone binary packages support the following platforms:
* Windows 7 or later
* (K)Ubuntu Linux 16.04 (64-bit) or later
* macOS 10.12 or later
* macOS 10.13 or later
## Contributing
@@ -31,6 +31,7 @@ Prerequisites:
* ActiveState Active Perl
* MinGW with g++ 5.3 or Visual Studio 2017 or later
* jom
* Ninja (optional, needed for CMake)
* Python 3.5 or later (optional, needed for the python enabled debug helper)
* On Mac OS X: latest Xcode
* On Linux: g++ 5.3 or later
@@ -38,7 +39,7 @@ Prerequisites:
Clang PCH Manager and Clang Refactoring plugins, see the section
"Get LLVM/Clang for the Clang Code Model". The LLVM C++ API provides no compatibility garantee,
so if later versions don't compile we don't support that version.)
* CMake (only for manual builds of LLVM/Clang)
* CMake (for manual builds of LLVM/Clang, and Qt Creator itself)
* Qbs 1.7.x (optional, sources also contain Qbs itself)
The installed toolchains have to match the one Qt was compiled with.
@@ -264,13 +265,24 @@ http://llvm.org/docs/GettingStarted.html#git-mirror:
For Linux/macOS:
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_RTTI=ON -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DCMAKE_INSTALL_PREFIX=<installation location> ../llvm-project/llvm
make install
cmake \
-D CMAKE_BUILD_TYPE=Release \
-D LLVM_ENABLE_RTTI=ON \
-D LLVM_ENABLE_PROJECTS="clang;clang-tools-extra" \
-D CMAKE_INSTALL_PREFIX=<installation location> \
../llvm-project/llvm
cmake --build . --target install
For Windows:
cmake -G "NMake Makefiles JOM" -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_RTTI=ON -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DCMAKE_INSTALL_PREFIX=<installation location> ..\llvm-project\llvm
jom install
cmake ^
-G "NMake Makefiles JOM" ^
-D CMAKE_BUILD_TYPE=Release ^
-D LLVM_ENABLE_RTTI=ON ^
-D LLVM_ENABLE_PROJECTS="clang;clang-tools-extra" ^
-D CMAKE_INSTALL_PREFIX=<installation location> ^
..\llvm-project\llvm
cmake --build . --target install
### Clang-Format
@@ -282,6 +294,34 @@ While the plugin builds without it, it will be disabled on start with an error m
Note that the plugin is disabled by default.
### Building Qt Creator with CMake
Qt Creator can also be built with CMake. The main Qt Creator dependencies, Qt and LLVM/Clang, both
offer CMake find packages, which reduce the steps of configuring Qt Creator to a minimum.
Configure and build Qt Creator:
mkdir build
cd build
For Linux/macOS:
cmake \
-G Ninja \
-D CMAKE_BUILD_TYPE=Release \
-D CMAKE_PREFIX_PATH=~/Qt/5.12.5/gcc_64;~/llvm \
../qt-creator
cmake --build .
For Windows:
cmake ^
-G Ninja ^
-D CMAKE_BUILD_TYPE=Release ^
-D CMAKE_PREFIX_PATH=c:\Qt\5.12.5\msvc2017_64;c:\llvm ^
..\qt-creator
cmake --build .
## Third-party Components
Qt Creator includes the following third-party components,

View File

@@ -31,9 +31,14 @@
/*!
\contentspage index.html
\previouspage creator-keyboard-shortcuts.html
\page creator-editor-external.html
\if defined(qtdesignstudio)
\previouspage creator-qml-performance-monitor.html
\nextpage studio-help.html
\else
\previouspage creator-keyboard-shortcuts.html
\nextpage creator-task-lists.html
\endif
\title Using External Tools
@@ -69,8 +74,8 @@
External > Configure}.
To open TS files in Qt Linguist, right-click a TS file in the
\uicontrol Projects view and select \uicontrol {Open With} >
\uicontrol {Qt Linguist} in the context menu.
\uicontrol Projects or \uicontrol {File System} view and select
\uicontrol {Open With} > \uicontrol {Qt Linguist} in the context menu.
For more information about Qt Linguist, see \l{Qt Linguist Manual}.
\section1 Previewing QML Files
@@ -130,17 +135,24 @@
\li In the \uicontrol {Error output} field, select how to handle error
messages from the tool.
\if defined(qtcreator)
\li In the \uicontrol {Base environment} field, select whether to run
the tool in the system environment or the \l{Build Environment}
{build environment} or \l {Selecting the Run Environment}
{run environment} of the active project. Select the build or run
environment if the system environment does not contain the necessary
PATH settings to find the tool chain, for example.
\else
\li In the \uicontrol {Base environment} field, use the default settings.
\endif
\li In the \uicontrol Environment field, select \uicontrol Change to modify
environment variable values for build and run environments in
the \uicontrol {Edit Environment Changes} dialog. For more information
about how to add and remove variable values, see \l{Batch Editing}.
the \uicontrol {Edit Environment Changes} dialog.
\if defined(qtcreator)
For more information about how to add and remove variable values,
see \l{Batch Editing}.
\endif
\li Select the \uicontrol {Modifies current document} check box to make sure
that if the current document is modified by the tool, it is saved

View File

@@ -102,7 +102,7 @@
\endlist
\li \macos 10.12 or later with the following:
\li \macos 10.13 or later with the following:
\list

View File

@@ -34,7 +34,7 @@
\page creator-qml-performance-monitor.html
\if defined(qtdesignstudio)
\previouspage creator-qml-debugging-example.html
\nextpage studio-help.html
\nextpage creator-editor-external.html
\else
\previouspage creator-analyze-mode.html
\nextpage creator-valgrind-overview.html

View File

@@ -27,6 +27,7 @@ HEADERS += $$PWD/changeauxiliarycommand.h
HEADERS += $$PWD/removesharedmemorycommand.h
HEADERS += $$PWD/puppetalivecommand.h
HEADERS += $$PWD/changeselectioncommand.h
HEADERS += $$PWD/drop3dlibraryitemcommand.h
SOURCES += $$PWD/synchronizecommand.cpp
SOURCES += $$PWD/debugoutputcommand.cpp
@@ -55,3 +56,4 @@ SOURCES += $$PWD/changeauxiliarycommand.cpp
SOURCES += $$PWD/removesharedmemorycommand.cpp
SOURCES += $$PWD/puppetalivecommand.cpp
SOURCES += $$PWD/changeselectioncommand.cpp
SOURCES += $$PWD/drop3dlibraryitemcommand.cpp

View File

@@ -0,0 +1,56 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "drop3dlibraryitemcommand.h"
#include <QDataStream>
namespace QmlDesigner {
Drop3DLibraryItemCommand::Drop3DLibraryItemCommand(const QByteArray &itemData)
: m_itemData(itemData)
{
}
QDataStream &operator<<(QDataStream &out, const Drop3DLibraryItemCommand &command)
{
out << command.itemData();
return out;
}
QDataStream &operator>>(QDataStream &in, Drop3DLibraryItemCommand &command)
{
in >> command.m_itemData;
return in;
}
bool operator==(const Drop3DLibraryItemCommand &first, const Drop3DLibraryItemCommand &second)
{
return first.m_itemData == second.m_itemData;
}
} // namespace QmlDesigner

View File

@@ -0,0 +1,59 @@
/****************************************************************************
**
** Copyright (C) 2019 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 <QVector>
#include <QDataStream>
#include <QMimeData>
#include "instancecontainer.h"
namespace QmlDesigner {
class Drop3DLibraryItemCommand
{
friend QDataStream &operator>>(QDataStream &in, Drop3DLibraryItemCommand &command);
friend QDebug operator<<(QDebug debug, const Drop3DLibraryItemCommand &command);
friend bool operator==(const Drop3DLibraryItemCommand &first,
const Drop3DLibraryItemCommand &second);
public:
explicit Drop3DLibraryItemCommand(const QByteArray &itemData);
Drop3DLibraryItemCommand() = default;
QByteArray itemData() const { return m_itemData; }
private:
QByteArray m_itemData;
};
QDataStream &operator<<(QDataStream &out, const Drop3DLibraryItemCommand &command);
QDataStream &operator>>(QDataStream &in, Drop3DLibraryItemCommand &command);
bool operator==(const Drop3DLibraryItemCommand &first, const Drop3DLibraryItemCommand &second);
} // namespace QmlDesigner
Q_DECLARE_METATYPE(QmlDesigner::Drop3DLibraryItemCommand)

View File

@@ -68,6 +68,7 @@
#include "debugoutputcommand.h"
#include "puppetalivecommand.h"
#include "changeselectioncommand.h"
#include "drop3dlibraryitemcommand.h"
namespace QmlDesigner {
@@ -139,6 +140,7 @@ bool compareCommands(const QVariant &command, const QVariant &controlCommand)
static const int tokenCommandType = QMetaType::type("TokenCommand");
static const int debugOutputCommandType = QMetaType::type("DebugOutputCommand");
static const int changeSelectionCommandType = QMetaType::type("ChangeSelectionCommand");
static const int drop3DLibraryItemCommandType = QMetaType::type("Drop3DLibraryItemCommand");
if (command.userType() == controlCommand.userType()) {
if (command.userType() == informationChangedCommandType)
@@ -163,6 +165,8 @@ bool compareCommands(const QVariant &command, const QVariant &controlCommand)
return command.value<DebugOutputCommand>() == controlCommand.value<DebugOutputCommand>();
else if (command.userType() == changeSelectionCommandType)
return command.value<ChangeSelectionCommand>() == controlCommand.value<ChangeSelectionCommand>();
else if (command.userType() == drop3DLibraryItemCommandType)
return command.value<Drop3DLibraryItemCommand>() == controlCommand.value<Drop3DLibraryItemCommand>();
}
return false;
@@ -250,6 +254,11 @@ void NodeInstanceClientProxy::selectionChanged(const ChangeSelectionCommand &com
writeCommand(QVariant::fromValue(command));
}
void NodeInstanceClientProxy::library3DItemDropped(const Drop3DLibraryItemCommand &command)
{
writeCommand(QVariant::fromValue(command));
}
void NodeInstanceClientProxy::flush()
{
}

View File

@@ -57,6 +57,7 @@ class ChangeStateCommand;
class ChangeNodeSourceCommand;
class EndPuppetCommand;
class ChangeSelectionCommand;
class Drop3DLibraryItemCommand;
class NodeInstanceClientProxy : public QObject, public NodeInstanceClientInterface
{
@@ -76,6 +77,7 @@ public:
void debugOutput(const DebugOutputCommand &command) override;
void puppetAlive(const PuppetAliveCommand &command);
void selectionChanged(const ChangeSelectionCommand &command) override;
void library3DItemDropped(const Drop3DLibraryItemCommand &command) override;
void flush() override;
void synchronizeWithClientProcess() override;

View File

@@ -41,6 +41,7 @@ class RemoveSharedMemoryCommand;
class DebugOutputCommand;
class PuppetAliveCommand;
class ChangeSelectionCommand;
class Drop3DLibraryItemCommand;
class NodeInstanceClientInterface
{
@@ -55,6 +56,7 @@ public:
virtual void token(const TokenCommand &command) = 0;
virtual void debugOutput(const DebugOutputCommand &command) = 0;
virtual void selectionChanged(const ChangeSelectionCommand &command) = 0;
virtual void library3DItemDropped(const Drop3DLibraryItemCommand &command) = 0;
virtual void flush() {}
virtual void synchronizeWithClientProcess() {}

View File

@@ -46,6 +46,7 @@
#include "addimportcontainer.h"
#include "changenodesourcecommand.h"
#include "changeselectioncommand.h"
#include "drop3dlibraryitemcommand.h"
#include "informationchangedcommand.h"
#include "pixmapchangedcommand.h"
@@ -107,6 +108,9 @@ void NodeInstanceServerInterface::registerCommands()
qRegisterMetaType<ChangeSelectionCommand>("ChangeSelectionCommand");
qRegisterMetaTypeStreamOperators<ChangeSelectionCommand>("ChangeSelectionCommand");
qRegisterMetaType<Drop3DLibraryItemCommand>("Drop3DLibraryItemCommand");
qRegisterMetaTypeStreamOperators<Drop3DLibraryItemCommand>("Drop3DLibraryItemCommand");
qRegisterMetaType<RemovePropertiesCommand>("RemovePropertiesCommand");
qRegisterMetaTypeStreamOperators<RemovePropertiesCommand>("RemovePropertiesCommand");

View File

@@ -30,7 +30,7 @@ import CameraGeometry 1.0
IconGizmo {
id: cameraGizmo
iconSource: "qrc:///qtquickplugin/mockfiles/images/camera-pick-icon.png"
iconSource: "qrc:///qtquickplugin/mockfiles/images/editor_camera.png"
gizmoModel.geometry: cameraGeometry
property alias geometryName: cameraGeometry.name // Name must be unique for each geometry
property alias viewPortRect: cameraGeometry.viewPortRect
@@ -43,7 +43,7 @@ IconGizmo {
gizmoModel.materials: [
DefaultMaterial {
id: defaultMaterial
emissiveColor: "blue"
emissiveColor: cameraGizmo.targetNode === cameraGizmo.selectedNode ? "#FF0000" : "#555555"
lighting: DefaultMaterial.NoLighting
cullingMode: Material.DisableCulling
}

View File

@@ -66,9 +66,11 @@ Window {
var component = Qt.createComponent("LightGizmo.qml");
if (component.status === Component.Ready) {
var gizmo = component.createObject(overlayScene,
{"view3D": overlayView, "targetNode": obj});
{"view3D": overlayView, "targetNode": obj,
"selectedNode": selectedNode});
lightGizmos[lightGizmos.length] = gizmo;
gizmo.selected.connect(emitObjectClicked);
gizmo.clicked.connect(emitObjectClicked);
gizmo.selectedNode = Qt.binding(function() {return selectedNode;});
}
}
@@ -80,10 +82,11 @@ Window {
var gizmo = component.createObject(
overlayScene,
{"view3D": overlayView, "targetNode": obj, "geometryName": geometryName,
"viewPortRect": viewPortRect});
"viewPortRect": viewPortRect, "selectedNode": selectedNode});
cameraGizmos[cameraGizmos.length] = gizmo;
gizmo.selected.connect(emitObjectClicked);
gizmo.clicked.connect(emitObjectClicked);
gizmo.viewPortRect = Qt.binding(function() {return viewPortRect;});
gizmo.selectedNode = Qt.binding(function() {return selectedNode;});
}
}
@@ -100,12 +103,15 @@ Window {
PerspectiveCamera {
id: overlayPerspectiveCamera
clipFar: editPerspectiveCamera.clipFar
clipNear: editPerspectiveCamera.clipNear
position: editPerspectiveCamera.position
rotation: editPerspectiveCamera.rotation
}
OrthographicCamera {
id: overlayOrthoCamera
clipFar: editOrthoCamera.clipFar
clipNear: editOrthoCamera.clipNear
position: editOrthoCamera.position
rotation: editOrthoCamera.rotation
}
@@ -118,7 +124,7 @@ Window {
position: viewWindow.selectedNode ? viewWindow.selectedNode.scenePosition
: Qt.vector3d(0, 0, 0)
globalOrientation: globalControl.checked
visible: selectedNode && moveToolControl.checked
visible: selectedNode && btnMove.selected
view3D: overlayView
onPositionCommit: viewWindow.commitObjectProperty(selectedNode, "position")
@@ -133,13 +139,28 @@ Window {
position: viewWindow.selectedNode ? viewWindow.selectedNode.scenePosition
: Qt.vector3d(0, 0, 0)
globalOrientation: globalControl.checked
visible: selectedNode && scaleToolControl.checked
visible: selectedNode && btnScale.selected
view3D: overlayView
onScaleCommit: viewWindow.commitObjectProperty(selectedNode, "scale")
onScaleChange: viewWindow.changeObjectProperty(selectedNode, "scale")
}
RotateGizmo {
id: rotateGizmo
scale: autoScale.getScale(Qt.vector3d(7, 7, 7))
highlightOnHover: true
targetNode: viewWindow.selectedNode
position: viewWindow.selectedNode ? viewWindow.selectedNode.scenePosition
: Qt.vector3d(0, 0, 0)
globalOrientation: globalControl.checked
visible: selectedNode && btnRotate.selected
view3D: overlayView
onRotateCommit: viewWindow.commitObjectProperty(selectedNode, "rotation")
onRotateChange: viewWindow.changeObjectProperty(selectedNode, "rotation")
}
AutoScaleHelper {
id: autoScale
view3D: overlayView
@@ -161,6 +182,10 @@ Window {
}
}
DropArea {
anchors.fill: parent
}
View3D {
id: editView
anchors.fill: parent
@@ -169,10 +194,10 @@ Window {
Node {
id: mainSceneHelpers
AxisHelper {
id: axisGrid
enableXZGrid: true
enableAxisLines: false
HelperGrid {
id: helperGrid
lines: 50
step: 50
}
PointLight {
@@ -186,15 +211,20 @@ Window {
PerspectiveCamera {
id: editPerspectiveCamera
z: -600
y: 200
z: -300
rotation.x: 30
clipFar: 100000
clipNear: 1
}
OrthographicCamera {
id: editOrthoCamera
z: -600
y: 200
z: -300
rotation.x: 30
clipFar: 100000
clipNear: 1
}
}
}
@@ -259,8 +289,78 @@ Window {
}
}
Rectangle { // toolbar
id: toolbar
color: "#9F000000"
width: 35
height: col.height
Column {
id: col
anchors.horizontalCenter: parent.horizontalCenter
spacing: 5
padding: 5
property var group: [btnSelectItem, btnSelectGroup, btnMove, btnRotate, btnScale]
ToolBarButton {
id: btnSelectItem
selected: true
tooltip: qsTr("Select Item")
shortcut: "Q"
currentShortcut: selected ? "" : shortcut
tool: "item_selection"
buttonsGroup: col.group
}
ToolBarButton {
id: btnSelectGroup
tooltip: qsTr("Select Group")
shortcut: "Q"
currentShortcut: btnSelectItem.currentShortcut === shortcut ? "" : shortcut
tool: "group_selection"
buttonsGroup: col.group
}
Rectangle { // separator
width: 25
height: 1
color: "#f1f1f1"
anchors.horizontalCenter: parent.horizontalCenter
}
ToolBarButton {
id: btnMove
tooltip: qsTr("Move current selection")
shortcut: "M"
currentShortcut: shortcut
tool: "move"
buttonsGroup: col.group
}
ToolBarButton {
id: btnRotate
tooltip: qsTr("Rotate current selection")
shortcut: "E"
currentShortcut: shortcut
tool: "rotate"
buttonsGroup: col.group
}
ToolBarButton {
id: btnScale
tooltip: qsTr("Scale current selection")
shortcut: "T"
currentShortcut: shortcut
tool: "scale"
buttonsGroup: col.group
}
}
}
Column {
y: 8
anchors.right: parent.right
CheckBox {
id: editLightCheckbox
checked: false
@@ -272,7 +372,19 @@ Window {
id: usePerspectiveCheckbox
checked: true
text: qsTr("Use Perspective Projection")
onCheckedChanged: cameraControl.forceActiveFocus()
onCheckedChanged: {
// Since WasdController always acts on active camera, we need to update pos/rot
// to the other camera when we change
if (checked) {
editPerspectiveCamera.position = editOrthoCamera.position;
editPerspectiveCamera.rotation = editOrthoCamera.rotation;
} else {
editOrthoCamera.position = editPerspectiveCamera.position;
editOrthoCamera.rotation = editPerspectiveCamera.rotation;
}
designStudioNativeCameraControlHelper.requestOverlayUpdate();
cameraControl.forceActiveFocus();
}
}
CheckBox {
@@ -281,19 +393,6 @@ Window {
text: qsTr("Use Global Orientation")
onCheckedChanged: cameraControl.forceActiveFocus()
}
Column {
x: 8
RadioButton {
id: moveToolControl
checked: true
text: qsTr("Move Tool")
}
RadioButton {
id: scaleToolControl
checked: false
text: qsTr("Scale Tool")
}
}
}
Text {

View File

@@ -0,0 +1,87 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import GridGeometry 1.0
Node {
id: grid
property alias lines: gridGeometry.lines
property alias step: gridGeometry.step
rotation.x: 90
// Note: Only one instance of HelperGrid is supported, as the geometry names are fixed
Model {
geometry: GridGeometry {
id: gridGeometry
name: "3D Edit View Helper Grid"
}
materials: [
DefaultMaterial {
id: mainGridMaterial
emissiveColor: "#e6e6e6"
lighting: DefaultMaterial.NoLighting
cullingMode: Material.DisableCulling
}
]
}
Model {
geometry: GridGeometry {
lines: gridGeometry.lines
step: gridGeometry.step
isCenterLine: true
name: "3D Edit View Helper Grid Z Axis"
}
materials: [
DefaultMaterial {
id: vCenterLineMaterial
emissiveColor: "#00a1d2"
lighting: DefaultMaterial.NoLighting
cullingMode: Material.DisableCulling
}
]
}
Model {
rotation.z: 90
geometry: GridGeometry {
lines: gridGeometry.lines
step: gridGeometry.step
isCenterLine: true
name: "3D Edit View Helper Grid X Axis"
}
materials: [
DefaultMaterial {
id: hCenterLineMaterial
emissiveColor: "#cb211a"
lighting: DefaultMaterial.NoLighting
cullingMode: Material.DisableCulling
}
]
}
}

View File

@@ -32,12 +32,13 @@ Node {
property View3D view3D
property bool highlightOnHover: true
property Node targetNode: null
property Node selectedNode: null
property alias gizmoModel: gizmoModel
property alias iconSource: iconImage.source
signal positionCommit()
signal selected(Node node)
signal clicked(Node node)
position: targetNode ? targetNode.scenePosition : Qt.vector3d(0, 0, 0)
rotation: targetNode ? targetNode.sceneRotation : Qt.vector3d(0, 0, 0)
@@ -57,22 +58,27 @@ Node {
parent: view3D
Rectangle {
width: 24
height: 24
width: iconImage.width
height: iconImage.height
x: -width / 2
y: -height
color: "transparent"
border.color: "#7777ff"
border.width: highlightOnHover && iconMouseArea.containsMouse ? 2 : 0
border.width: iconGizmo.selectedNode === iconGizmo.targetNode
|| (iconGizmo.highlightOnHover && iconMouseArea.containsMouse) ? 2 : 0
radius: 5
opacity: iconGizmo.selectedNode === iconGizmo.targetNode ? 0.3 : 1
Image {
id: iconImage
anchors.fill: parent
fillMode: Image.Pad
MouseArea {
id: iconMouseArea
anchors.fill: parent
onClicked: selected(targetNode)
hoverEnabled: highlightOnHover
onClicked: iconGizmo.clicked(iconGizmo.targetNode)
hoverEnabled: iconGizmo.highlightOnHover
&& iconGizmo.selectedNode !== iconGizmo.targetNode
acceptedButtons: iconGizmo.selectedNode !== iconGizmo.targetNode
? Qt.LeftButton : Qt.NoButton
}
}
}

View File

@@ -0,0 +1,221 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import MouseArea3D 1.0
Node {
id: rotateGizmo
property View3D view3D
property bool highlightOnHover: true
property Node targetNode: null
property bool globalOrientation: true
readonly property bool dragging: cameraRing.dragging
|| rotRingX.dragging || rotRingY.dragging || rotRingZ.dragging
property real currentAngle
property point currentMousePos
signal rotateCommit()
signal rotateChange()
Rectangle {
id: angleLabel
color: "white"
x: rotateGizmo.currentMousePos.x - (10 + width)
y: rotateGizmo.currentMousePos.y - (10 + height)
width: gizmoLabelText.width + 4
height: gizmoLabelText.height + 4
border.width: 1
visible: rotateGizmo.dragging
parent: rotateGizmo.view3D
Text {
id: gizmoLabelText
text: {
var l = Qt.locale();
if (rotateGizmo.targetNode) {
var degrees = currentAngle * (180 / Math.PI);
return qsTr(Number(degrees).toLocaleString(l, 'f', 1));
} else {
return "";
}
}
anchors.centerIn: parent
}
}
Node {
rotation: globalOrientation || !targetNode ? Qt.vector3d(0, 0, 0) : targetNode.sceneRotation
RotateRing {
id: rotRingX
objectName: "Rotate Ring X"
rotation: Qt.vector3d(0, 90, 0)
targetNode: rotateGizmo.targetNode
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(1, 0, 0, 1))
: Qt.rgba(1, 0, 0, 1)
priority: 40
view3D: rotateGizmo.view3D
active: rotateGizmo.visible
onRotateCommit: rotateGizmo.rotateCommit()
onRotateChange: rotateGizmo.rotateChange()
onCurrentAngleChanged: rotateGizmo.currentAngle = currentAngle
onCurrentMousePosChanged: rotateGizmo.currentMousePos = currentMousePos
}
RotateRing {
id: rotRingY
objectName: "Rotate Ring Y"
rotation: Qt.vector3d(90, 0, 0)
targetNode: rotateGizmo.targetNode
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0.6, 0, 1))
: Qt.rgba(0, 0.6, 0, 1)
// Just a smidge smaller than higher priority rings so that it doesn't obscure them
scale: Qt.vector3d(0.998, 0.998, 0.998)
priority: 30
view3D: rotateGizmo.view3D
active: rotateGizmo.visible
onRotateCommit: rotateGizmo.rotateCommit()
onRotateChange: rotateGizmo.rotateChange()
onCurrentAngleChanged: rotateGizmo.currentAngle = currentAngle
onCurrentMousePosChanged: rotateGizmo.currentMousePos = currentMousePos
}
RotateRing {
id: rotRingZ
objectName: "Rotate Ring Z"
rotation: Qt.vector3d(0, 0, 0)
targetNode: rotateGizmo.targetNode
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0, 1, 1))
: Qt.rgba(0, 0, 1, 1)
// Just a smidge smaller than higher priority rings so that it doesn't obscure them
scale: Qt.vector3d(0.996, 0.996, 0.996)
priority: 20
view3D: rotateGizmo.view3D
active: rotateGizmo.visible
onRotateCommit: rotateGizmo.rotateCommit()
onRotateChange: rotateGizmo.rotateChange()
onCurrentAngleChanged: rotateGizmo.currentAngle = currentAngle
onCurrentMousePosChanged: rotateGizmo.currentMousePos = currentMousePos
}
}
RotateRing {
id: cameraRing
objectName: "cameraRing"
rotation: rotateGizmo.view3D.camera.rotation
targetNode: rotateGizmo.targetNode
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0.5, 0.5, 0.5, 1))
: Qt.rgba(0.5, 0.5, 0.5, 1)
// Just a smidge smaller than higher priority rings so that it doesn't obscure them
scale: Qt.vector3d(0.994, 0.994, 0.994)
priority: 10
view3D: rotateGizmo.view3D
active: rotateGizmo.visible
onRotateCommit: rotateGizmo.rotateCommit()
onRotateChange: rotateGizmo.rotateChange()
onCurrentAngleChanged: rotateGizmo.currentAngle = currentAngle
onCurrentMousePosChanged: rotateGizmo.currentMousePos = currentMousePos
}
Model {
id: freeRotator
source: "#Sphere"
materials: DefaultMaterial {
id: material
emissiveColor: "black"
opacity: mouseAreaFree.hovering ? 0.15 : 0
lighting: DefaultMaterial.NoLighting
}
scale: Qt.vector3d(0.15, 0.15, 0.15)
property vector3d _pointerPosPressed
property vector3d _targetPosOnScreen
property vector3d _startRotation
function handlePressed(screenPos)
{
if (!rotateGizmo.targetNode)
return;
_targetPosOnScreen = view3D.mapFrom3DScene(rotateGizmo.targetNode.scenePosition);
_targetPosOnScreen.z = 0;
_pointerPosPressed = Qt.vector3d(screenPos.x, screenPos.y, 0);
// Recreate vector so we don't follow the changes in targetNode.rotation
_startRotation = Qt.vector3d(rotateGizmo.targetNode.rotation.x,
rotateGizmo.targetNode.rotation.y,
rotateGizmo.targetNode.rotation.z);
}
function handleDragged(screenPos)
{
if (!rotateGizmo.targetNode)
return;
mouseAreaFree.applyFreeRotation(
rotateGizmo.targetNode, _startRotation, _pointerPosPressed,
Qt.vector3d(screenPos.x, screenPos.y, 0), _targetPosOnScreen);
rotateGizmo.rotateChange();
}
function handleReleased(screenPos)
{
if (!rotateGizmo.targetNode)
return;
mouseAreaFree.applyFreeRotation(
rotateGizmo.targetNode, _startRotation, _pointerPosPressed,
Qt.vector3d(screenPos.x, screenPos.y, 0), _targetPosOnScreen);
rotateGizmo.rotateCommit();
}
MouseArea3D {
id: mouseAreaFree
view3D: rotateGizmo.view3D
rotation: rotateGizmo.view3D.camera.rotation
objectName: "Free rotator plane"
x: -50
y: -50
width: 100
height: 100
circlePickArea: Qt.point(25, 50)
grabsMouse: rotateGizmo.targetNode
active: rotateGizmo.visible
onPressed: freeRotator.handlePressed(screenPos)
onDragged: freeRotator.handleDragged(screenPos)
onReleased: freeRotator.handleReleased(screenPos)
}
}
}

View File

@@ -0,0 +1,133 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.0
import QtQuick3D 1.0
import MouseArea3D 1.0
Model {
id: rotateRing
property View3D view3D
property alias color: material.emissiveColor
property Node targetNode: null
property bool dragging: false
property bool active: false
property alias hovering: mouseAreaMain.hovering
property alias priority: mouseAreaMain.priority
property real currentAngle
property point currentMousePos
property vector3d _pointerPosPressed
property vector3d _targetPosOnScreen
property vector3d _startRotation
property bool _trackBall
signal rotateCommit()
signal rotateChange()
source: "meshes/ring.mesh"
Model {
id: pickModel
objectName: "PickModel for " + rotateRing.objectName
source: "meshes/ringselect.mesh"
pickable: true
}
materials: DefaultMaterial {
id: material
emissiveColor: "white"
lighting: DefaultMaterial.NoLighting
}
function applyLocalRotation(screenPos)
{
currentAngle = mouseAreaMain.getNewRotationAngle(targetNode, _pointerPosPressed,
Qt.vector3d(screenPos.x, screenPos.y, 0),
_targetPosOnScreen, currentAngle,
_trackBall);
mouseAreaMain.applyRotationAngleToNode(targetNode, _startRotation, currentAngle);
}
function handlePressed(screenPos, angle)
{
if (!targetNode)
return;
_targetPosOnScreen = view3D.mapFrom3DScene(targetNode.scenePosition);
_targetPosOnScreen.z = 0;
_pointerPosPressed = Qt.vector3d(screenPos.x, screenPos.y, 0);
dragging = true;
_trackBall = angle < 0.1;
// Recreate vector so we don't follow the changes in targetNode.rotation
_startRotation = Qt.vector3d(targetNode.rotation.x,
targetNode.rotation.y,
targetNode.rotation.z);
currentAngle = 0;
currentMousePos = screenPos;
}
function handleDragged(screenPos)
{
if (!targetNode)
return;
applyLocalRotation(screenPos);
currentMousePos = screenPos;
rotateChange();
}
function handleReleased(screenPos)
{
if (!targetNode)
return;
applyLocalRotation(screenPos);
rotateCommit();
dragging = false;
currentAngle = 0;
currentMousePos = screenPos;
}
MouseArea3D {
id: mouseAreaMain
view3D: rotateRing.view3D
objectName: "Main plane of " + rotateRing.objectName
x: -30
y: -30
width: 60
height: 60
circlePickArea: Qt.point(9.2, 1.4)
grabsMouse: targetNode
active: rotateRing.active
pickNode: pickModel
minAngle: 0.05
onPressed: rotateRing.handlePressed(screenPos, angle)
onDragged: rotateRing.handleDragged(screenPos)
onReleased: rotateRing.handleReleased(screenPos)
}
}

View File

@@ -0,0 +1,79 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.12
import QtQuick 2.0
import QtQuick.Controls 2.0
Rectangle {
property bool selected: false
property string tooltip
property string shortcut
property string currentShortcut
property string tool
property variant buttonsGroup: []
id: root
width: img.width + 5
height: img.height + 5
color: root.selected ? "#aa000000" : (mouseArea.containsMouse ? "#44000000" : "#00000000")
radius: 3
ToolTip {
text: root.tooltip + " (" + root.shortcut + ")"
visible: mouseArea.containsMouse
delay: 1000
}
Image {
id: img
anchors.centerIn: parent
source: root.selected ? "qrc:///qtquickplugin/mockfiles/images/" + root.tool + "_selected.png"
: "qrc:///qtquickplugin/mockfiles/images/" + root.tool + "_active.png"
}
Shortcut {
sequence: root.currentShortcut
onActivated: mouseArea.onClicked(null)
}
MouseArea {
id: mouseArea
cursorShape: "PointingHandCursor"
anchors.fill: parent
hoverEnabled: true
onClicked: {
if (!root.selected) {
for (var i = 0; i < root.buttonsGroup.length; ++i)
root.buttonsGroup[i].selected = false;
root.selected = true;
}
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 981 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 779 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 904 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 657 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 661 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 869 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 906 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 B

View File

@@ -1,7 +1,9 @@
HEADERS += $$PWD/cameracontrolhelper.h \
$$PWD/mousearea3d.h \
$$PWD/camerageometry.h
$$PWD/camerageometry.h \
$$PWD/gridgeometry.h
SOURCES += $$PWD/cameracontrolhelper.cpp \
$$PWD/mousearea3d.cpp \
$$PWD/camerageometry.cpp
$$PWD/camerageometry.cpp \
$$PWD/gridgeometry.cpp

View File

@@ -0,0 +1,163 @@
/****************************************************************************
**
** Copyright (C) 2019 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.
**
****************************************************************************/
#ifdef QUICK3D_MODULE
#include "gridgeometry.h"
#include <QtQuick3DRuntimeRender/private/qssgrendergeometry_p.h>
namespace QmlDesigner {
namespace Internal {
GridGeometry::GridGeometry()
: QQuick3DGeometry()
{
}
GridGeometry::~GridGeometry()
{
}
int GridGeometry::lines() const
{
return m_lines;
}
float GridGeometry::step() const
{
return m_step;
}
bool GridGeometry::isCenterLine() const
{
return m_isCenterLine;
}
// Number of lines on each side of the center lines.
// These lines are not drawn if m_isCenterLine is true; lines and step are simply used to calculate
// the length of the center line in that case.
void GridGeometry::setLines(int count)
{
count = qMax(count, 1);
if (m_lines == count)
return;
m_lines = qMax(count, 1);
emit linesChanged();
update();
}
// Space between lines
void GridGeometry::setStep(float step)
{
step = qMax(step, 0.0f);
if (qFuzzyCompare(m_step, step))
return;
m_step = step;
emit stepChanged();
update();
}
void GridGeometry::setIsCenterLine(bool enabled)
{
if (m_isCenterLine == enabled)
return;
m_isCenterLine = enabled;
emit isCenterLineChanged();
update();
}
QSSGRenderGraphObject *GridGeometry::updateSpatialNode(QSSGRenderGraphObject *node)
{
node = QQuick3DGeometry::updateSpatialNode(node);
QSSGRenderGeometry *geometry = static_cast<QSSGRenderGeometry *>(node);
geometry->clear();
QByteArray vertexData;
fillVertexData(vertexData);
geometry->addAttribute(QSSGRenderGeometry::Attribute::PositionSemantic, 0,
QSSGRenderGeometry::Attribute::ComponentType::F32Type);
geometry->setStride(12);
geometry->setVertexData(vertexData);
geometry->setPrimitiveType(QSSGRenderGeometry::Lines);
int lastIndex = (vertexData.size() - 1) / int(sizeof(QVector3D));
auto vertexPtr = reinterpret_cast<QVector3D *>(vertexData.data());
geometry->setBounds(QVector3D(vertexPtr[0][0], vertexPtr[0][1], 0.0),
QVector3D(vertexPtr[lastIndex][0], vertexPtr[lastIndex][1], 0.0));
return node;
}
void GridGeometry::fillVertexData(QByteArray &vertexData)
{
const int size = m_isCenterLine
? int(sizeof(float)) * 3 * 2
: 4 * m_lines * int(sizeof(float)) * 3 * 2;
vertexData.resize(size);
float *dataPtr = reinterpret_cast<float *>(vertexData.data());
float y0 = -float(m_lines) * m_step;
float x0 = -float(m_lines) * m_step;
float y1 = -y0;
float x1 = -x0;
if (m_isCenterLine) {
// start position
dataPtr[0] = 0.f;
dataPtr[1] = y0;
dataPtr[2] = 0.f;
// end position
dataPtr[3] = 0.f;
dataPtr[4] = y1;
dataPtr[5] = 0.f;
} else {
auto generateLines = [this, &dataPtr](float x0, float y0, float x1, float y1, bool vertical) {
for (int i = 0; i < m_lines; ++i) {
// start position
dataPtr[0] = vertical ? x0 + i * m_step : x0;
dataPtr[1] = vertical ? y0 : y0 + i * m_step;
dataPtr[2] = .0f;
// end position
dataPtr[3] = vertical ? x0 + i * m_step : x1;
dataPtr[4] = vertical ? y1 : y0 + i * m_step;
dataPtr[5] = .0f;
dataPtr += 6;
}
};
// Lines are created so that bounding box can later be calculated from first and last vertex
generateLines(x0, y0, x1, y1, true);
generateLines(x0, y0, x1, y1, false);
generateLines(x0, m_step, x1, y1, false);
generateLines(m_step, y0, x1, y1, true);
}
}
}
}
#endif // QUICK3D_MODULE

View File

@@ -0,0 +1,76 @@
/****************************************************************************
**
** Copyright (C) 2019 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
#ifdef QUICK3D_MODULE
#include <QtQuick3D/private/qquick3dgeometry_p.h>
namespace QmlDesigner {
namespace Internal {
class GridGeometry : public QQuick3DGeometry
{
Q_OBJECT
Q_PROPERTY(int lines READ lines WRITE setLines NOTIFY linesChanged)
Q_PROPERTY(float step READ step WRITE setStep NOTIFY stepChanged)
Q_PROPERTY(bool isCenterLine READ isCenterLine WRITE setIsCenterLine NOTIFY isCenterLineChanged)
public:
GridGeometry();
~GridGeometry() override;
int lines() const;
float step() const;
bool isCenterLine() const;
public Q_SLOTS:
void setLines(int count);
void setStep(float step);
void setIsCenterLine(bool enabled);
Q_SIGNALS:
void linesChanged();
void stepChanged();
void isCenterLineChanged();
protected:
QSSGRenderGraphObject *updateSpatialNode(QSSGRenderGraphObject *node) override;
private:
void fillVertexData(QByteArray &vertexData);
int m_lines = 1000;
float m_step = .1f;
bool m_isCenterLine = false;
};
}
}
QML_DECLARE_TYPE(QmlDesigner::Internal::GridGeometry)
#endif // QUICK3D_MODULE

View File

@@ -29,11 +29,15 @@
#include <QtGui/qguiapplication.h>
#include <QtQml/qqmlinfo.h>
#include <QtQuick3D/private/qquick3dcamera_p.h>
#include <QtQuick3D/private/qquick3dorthographiccamera_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrendercamera_p.h>
namespace QmlDesigner {
namespace Internal {
MouseArea3D *MouseArea3D::s_mouseGrab = nullptr;
static const qreal s_mouseDragMultiplier = .02;
MouseArea3D::MouseArea3D(QQuick3DNode *parent)
: QQuick3DNode(parent)
@@ -65,6 +69,21 @@ bool MouseArea3D::active() const
return m_active;
}
QPointF MouseArea3D::circlePickArea() const
{
return m_circlePickArea;
}
qreal MouseArea3D::minAngle() const
{
return m_minAngle;
}
QQuick3DNode *MouseArea3D::pickNode() const
{
return m_pickNode;
}
qreal MouseArea3D::x() const
{
return m_x;
@@ -105,7 +124,7 @@ void MouseArea3D::setGrabsMouse(bool grabsMouse)
return;
m_grabsMouse = grabsMouse;
emit grabsMouseChanged(grabsMouse);
emit grabsMouseChanged();
}
void MouseArea3D::setActive(bool active)
@@ -114,7 +133,37 @@ void MouseArea3D::setActive(bool active)
return;
m_active = active;
emit activeChanged(active);
emit activeChanged();
}
void MouseArea3D::setCirclePickArea(const QPointF &pickArea)
{
if (m_circlePickArea == pickArea)
return;
m_circlePickArea = pickArea;
emit circlePickAreaChanged();
}
// This is the minimum angle for circle picking. At lower angles we fall back to picking on pickNode
void MouseArea3D::setMinAngle(qreal angle)
{
if (qFuzzyCompare(m_minAngle, angle))
return;
m_minAngle = angle;
emit minAngleChanged();
}
// This is the fallback pick node when circle picking can't be done due to low angle
// Pick node can't be used except in low angles, as long as only bounding box picking is supported
void MouseArea3D::setPickNode(QQuick3DNode *node)
{
if (m_pickNode == node)
return;
m_pickNode = node;
emit pickNodeChanged();
}
void MouseArea3D::setX(qreal x)
@@ -123,7 +172,7 @@ void MouseArea3D::setX(qreal x)
return;
m_x = x;
emit xChanged(x);
emit xChanged();
}
void MouseArea3D::setY(qreal y)
@@ -132,7 +181,7 @@ void MouseArea3D::setY(qreal y)
return;
m_y = y;
emit yChanged(y);
emit yChanged();
}
void MouseArea3D::setWidth(qreal width)
@@ -141,7 +190,7 @@ void MouseArea3D::setWidth(qreal width)
return;
m_width = width;
emit widthChanged(width);
emit widthChanged();
}
void MouseArea3D::setHeight(qreal height)
@@ -150,7 +199,7 @@ void MouseArea3D::setHeight(qreal height)
return;
m_height = height;
emit heightChanged(height);
emit heightChanged();
}
void MouseArea3D::setPriority(int level)
@@ -159,7 +208,7 @@ void MouseArea3D::setPriority(int level)
return;
m_priority = level;
emit priorityChanged(level);
emit priorityChanged();
}
void MouseArea3D::componentComplete()
@@ -278,6 +327,84 @@ QVector3D MouseArea3D::getNewScale(QQuick3DNode *node, const QVector3D &startSca
return startScale;
}
qreal QmlDesigner::Internal::MouseArea3D::getNewRotationAngle(
QQuick3DNode *node, const QVector3D &pressPos, const QVector3D &currentPos,
const QVector3D &nodePos, qreal prevAngle, bool trackBall)
{
const QVector3D cameraToNodeDir = getCameraToNodeDir(node);
if (trackBall) {
// Only the distance in plane direction is relevant in trackball drag
QVector3D dragDir = QVector3D::crossProduct(getNormal(), cameraToNodeDir).normalized();
QVector3D screenDragDir = m_view3D->mapFrom3DScene(node->scenePosition() + dragDir);
screenDragDir.setZ(0);
dragDir = (screenDragDir - nodePos).normalized();
const QVector3D pressToCurrent = (currentPos - pressPos);
float magnitude = QVector3D::dotProduct(pressToCurrent, dragDir);
qreal angle = -s_mouseDragMultiplier * qreal(magnitude);
return angle;
} else {
const QVector3D nodeToPress = (pressPos - nodePos).normalized();
const QVector3D nodeToCurrent = (currentPos - nodePos).normalized();
qreal angle = qAcos(qreal(QVector3D::dotProduct(nodeToPress, nodeToCurrent)));
// Determine drag direction left/right
const QVector3D dragNormal = QVector3D::crossProduct(nodeToPress, nodeToCurrent).normalized();
angle *= QVector3D::dotProduct(QVector3D(0.f, 0.f, 1.f), dragNormal) < 0 ? -1.0 : 1.0;
// Determine drag ring orientation relative to camera
angle *= QVector3D::dotProduct(getNormal(), cameraToNodeDir) < 0 ? 1.0 : -1.0;
qreal adjustedPrevAngle = prevAngle;
const qreal PI_2 = M_PI * 2.0;
while (adjustedPrevAngle < -PI_2)
adjustedPrevAngle += PI_2;
while (adjustedPrevAngle > PI_2)
adjustedPrevAngle -= PI_2;
// at M_PI rotation, the angle flips to negative
if (qAbs(angle - adjustedPrevAngle) > M_PI) {
if (angle > adjustedPrevAngle)
return prevAngle - (PI_2 - angle + adjustedPrevAngle);
else
return prevAngle + (PI_2 + angle - adjustedPrevAngle);
} else {
return prevAngle + angle - adjustedPrevAngle;
}
}
}
void QmlDesigner::Internal::MouseArea3D::applyRotationAngleToNode(
QQuick3DNode *node, const QVector3D &startRotation, qreal angle)
{
if (!qFuzzyIsNull(angle)) {
node->setRotation(startRotation);
node->rotate(qRadiansToDegrees(angle), getNormal(), QQuick3DNode::SceneSpace);
}
}
void MouseArea3D::applyFreeRotation(QQuick3DNode *node, const QVector3D &startRotation,
const QVector3D &pressPos, const QVector3D &currentPos)
{
QVector3D dragVector = currentPos - pressPos;
if (dragVector.length() < 0.001f)
return;
const float *dataPtr(sceneTransform().data());
QVector3D xAxis = QVector3D(-dataPtr[0], -dataPtr[1], -dataPtr[2]).normalized();
QVector3D yAxis = QVector3D(-dataPtr[4], -dataPtr[5], -dataPtr[6]).normalized();
QVector3D finalAxis = (dragVector.x() * yAxis + dragVector.y() * xAxis);
qreal degrees = qRadiansToDegrees(qreal(finalAxis.length()) * s_mouseDragMultiplier);
finalAxis.normalize();
node->setRotation(startRotation);
node->rotate(degrees, finalAxis, QQuick3DNode::SceneSpace);
}
QVector3D MouseArea3D::getMousePosInPlane(const QPointF &mousePosInView) const
{
const QVector3D mousePos1(float(mousePosInView.x()), float(mousePosInView.y()), 0);
@@ -300,12 +427,50 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
return false;
}
auto mouseOnTopOfMouseArea = [this](const QVector3D &mousePosInPlane) -> bool {
return !qFuzzyCompare(mousePosInPlane.z(), -1)
qreal pickAngle = 0.;
auto mouseOnTopOfMouseArea = [this, &pickAngle](
const QVector3D &mousePosInPlane, const QPointF &mousePos) -> bool {
const bool onPlane = !qFuzzyCompare(mousePosInPlane.z(), -1)
&& mousePosInPlane.x() >= float(m_x)
&& mousePosInPlane.x() <= float(m_x + m_width)
&& mousePosInPlane.y() >= float(m_y)
&& mousePosInPlane.y() <= float(m_y + m_height);
bool onCircle = true;
bool pickSuccess = false;
if (!qFuzzyIsNull(m_circlePickArea.y()) || !qFuzzyIsNull(m_minAngle)) {
QVector3D cameraToMouseAreaDir = getCameraToNodeDir(this);
const QVector3D mouseAreaDir = getNormal();
qreal angle = qreal(QVector3D::dotProduct(cameraToMouseAreaDir, mouseAreaDir));
// Do not allow selecting ring that is nearly perpendicular to camera, as dragging along
// that plane would be difficult
pickAngle = qAcos(angle);
pickAngle = pickAngle > M_PI_2 ? pickAngle - M_PI_2 : M_PI_2 - pickAngle;
if (pickAngle > m_minAngle) {
if (!qFuzzyIsNull(m_circlePickArea.y())) {
qreal ringCenter = m_circlePickArea.x();
// Thickness is increased according to the angle to camera to keep projected
// circle thickness constant at all angles.
qreal divisor = qSin(pickAngle) * 2.; // This is never zero
qreal thickness = ((m_circlePickArea.y() / divisor));
qreal mousePosRadius = qSqrt(qreal(mousePosInPlane.x() * mousePosInPlane.x())
+ qreal(mousePosInPlane.y() * mousePosInPlane.y()));
onCircle = ringCenter - thickness <= mousePosRadius
&& ringCenter + thickness >= mousePosRadius;
}
} else {
// Fall back to picking on the pickNode. At this angle, bounding box pick is not
// a problem
onCircle = false;
if (m_pickNode) {
QQuick3DPickResult pr = m_view3D->pick(float(mousePos.x()), float(mousePos.y()));
pickSuccess = pr.objectHit() == m_pickNode;
}
}
}
return (onCircle && onPlane) || pickSuccess;
};
switch (event->type()) {
@@ -313,9 +478,9 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
auto const mouseEvent = static_cast<QMouseEvent *>(event);
if (mouseEvent->button() == Qt::LeftButton) {
m_mousePosInPlane = getMousePosInPlane(mouseEvent->pos());
if (mouseOnTopOfMouseArea(m_mousePosInPlane)) {
if (mouseOnTopOfMouseArea(m_mousePosInPlane, mouseEvent->pos())) {
setDragging(true);
emit pressed(m_mousePosInPlane, mouseEvent->globalPos());
emit pressed(m_mousePosInPlane, mouseEvent->pos(), pickAngle);
if (m_grabsMouse) {
if (s_mouseGrab && s_mouseGrab != this) {
s_mouseGrab->setDragging(false);
@@ -338,13 +503,13 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
if (qFuzzyCompare(mousePosInPlane.z(), -1))
mousePosInPlane = m_mousePosInPlane;
setDragging(false);
emit released(mousePosInPlane, mouseEvent->globalPos());
emit released(mousePosInPlane, mouseEvent->pos());
if (m_grabsMouse) {
if (s_mouseGrab && s_mouseGrab != this) {
s_mouseGrab->setDragging(false);
s_mouseGrab->setHovering(false);
}
if (mouseOnTopOfMouseArea(mousePosInPlane)) {
if (mouseOnTopOfMouseArea(mousePosInPlane, mouseEvent->pos())) {
s_mouseGrab = this;
setHovering(true);
} else {
@@ -362,7 +527,7 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
case QEvent::HoverMove: {
auto const mouseEvent = static_cast<QMouseEvent *>(event);
const QVector3D mousePosInPlane = getMousePosInPlane(mouseEvent->pos());
const bool hasMouse = mouseOnTopOfMouseArea(mousePosInPlane);
const bool hasMouse = mouseOnTopOfMouseArea(mousePosInPlane, mouseEvent->pos());
setHovering(hasMouse);
@@ -376,9 +541,9 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
s_mouseGrab = nullptr;
}
if (m_dragging && !qFuzzyCompare(mousePosInPlane.z(), -1)) {
if (m_dragging && (m_circlePickArea.y() > 0. || !qFuzzyCompare(mousePosInPlane.z(), -1))) {
m_mousePosInPlane = mousePosInPlane;
emit dragged(mousePosInPlane, mouseEvent->globalPos());
emit dragged(mousePosInPlane, mouseEvent->pos());
}
break;
@@ -408,6 +573,25 @@ void MouseArea3D::setHovering(bool enable)
emit hoveringChanged();
}
QVector3D MouseArea3D::getNormal() const
{
const float *dataPtr(sceneTransform().data());
return QVector3D(dataPtr[8], dataPtr[9], dataPtr[10]).normalized();
}
QVector3D MouseArea3D::getCameraToNodeDir(QQuick3DNode *node) const
{
QVector3D dir;
if (qobject_cast<QQuick3DOrthographicCamera *>(m_view3D->camera())) {
dir = m_view3D->camera()->cameraNode()->getDirection();
// Camera direction has x and y flipped
dir = QVector3D(-dir.x(), -dir.y(), dir.z());
} else {
dir = (node->scenePosition() - m_view3D->camera()->scenePosition()).normalized();
}
return dir;
}
}
}

View File

@@ -28,9 +28,11 @@
#ifdef QUICK3D_MODULE
#include <QtGui/qvector3d.h>
#include <QtCore/qpoint.h>
#include <QtCore/qpointer.h>
#include <QtQuick3D/private/qquick3dnode_p.h>
#include <QtQuick3D/private/qquick3dmodel_p.h>
#include <QtQuick3D/private/qquick3dviewport_p.h>
#include <QtQuick3D/private/qtquick3dglobal_p.h>
@@ -50,6 +52,9 @@ class MouseArea3D : public QQuick3DNode
Q_PROPERTY(bool dragging READ dragging NOTIFY draggingChanged)
Q_PROPERTY(int priority READ priority WRITE setPriority NOTIFY priorityChanged)
Q_PROPERTY(int active READ active WRITE setActive NOTIFY activeChanged)
Q_PROPERTY(QPointF circlePickArea READ circlePickArea WRITE setCirclePickArea NOTIFY circlePickAreaChanged)
Q_PROPERTY(qreal minAngle READ minAngle WRITE setMinAngle NOTIFY minAngleChanged)
Q_PROPERTY(QQuick3DNode *pickNode READ pickNode WRITE setPickNode NOTIFY pickNodeChanged)
Q_INTERFACES(QQmlParserStatus)
@@ -68,11 +73,17 @@ public:
bool dragging() const;
bool grabsMouse() const;
bool active() const;
QPointF circlePickArea() const;
qreal minAngle() const;
QQuick3DNode *pickNode() const;
public slots:
void setView3D(QQuick3DViewport *view3D);
void setGrabsMouse(bool grabsMouse);
void setActive(bool active);
void setCirclePickArea(const QPointF &pickArea);
void setMinAngle(qreal angle);
void setPickNode(QQuick3DNode *node);
void setX(qreal x);
void setY(qreal y);
@@ -89,22 +100,35 @@ public slots:
const QVector3D &pressPos,
const QVector3D &sceneRelativeDistance, bool global);
Q_INVOKABLE qreal getNewRotationAngle(QQuick3DNode *node, const QVector3D &pressPos,
const QVector3D &currentPos, const QVector3D &nodePos,
qreal prevAngle, bool trackBall);
Q_INVOKABLE void applyRotationAngleToNode(QQuick3DNode *node, const QVector3D &startRotation,
qreal angle);
Q_INVOKABLE void applyFreeRotation(QQuick3DNode *node, const QVector3D &startRotation,
const QVector3D &pressPos, const QVector3D &currentPos);
signals:
void view3DChanged();
void xChanged(qreal x);
void yChanged(qreal y);
void widthChanged(qreal width);
void heightChanged(qreal height);
void priorityChanged(int level);
void xChanged();
void yChanged();
void widthChanged();
void heightChanged();
void priorityChanged();
void hoveringChanged();
void draggingChanged();
void activeChanged(bool active);
void pressed(const QVector3D &scenePos, const QPoint &screenPos);
void activeChanged();
void grabsMouseChanged();
void circlePickAreaChanged();
void minAngleChanged();
void pickNodeChanged();
// angle parameter is only set if circlePickArea is specified
void pressed(const QVector3D &scenePos, const QPoint &screenPos, qreal angle);
void released(const QVector3D &scenePos, const QPoint &screenPos);
void dragged(const QVector3D &scenePos, const QPoint &screenPos);
void grabsMouseChanged(bool grabsMouse);
protected:
void classBegin() override {}
@@ -114,6 +138,8 @@ protected:
private:
void setDragging(bool enable);
void setHovering(bool enable);
QVector3D getNormal() const;
QVector3D getCameraToNodeDir(QQuick3DNode *node) const;
Q_DISABLE_COPY(MouseArea3D)
QQuick3DViewport *m_view3D = nullptr;
@@ -133,6 +159,9 @@ private:
static MouseArea3D *s_mouseGrab;
bool m_grabsMouse;
QVector3D m_mousePosInPlane;
QPointF m_circlePickArea;
qreal m_minAngle = 0.;
QQuick3DNode *m_pickNode = nullptr;
};
}

View File

@@ -67,6 +67,7 @@
#include <tokencommand.h>
#include <removesharedmemorycommand.h>
#include <changeselectioncommand.h>
#include <drop3dlibraryitemcommand.h>
#include <QDebug>
#include <QQmlEngine>
@@ -1171,6 +1172,11 @@ ChangeSelectionCommand NodeInstanceServer::createChangeSelectionCommand(const QL
return ChangeSelectionCommand(idVector);
}
Drop3DLibraryItemCommand NodeInstanceServer::createDrop3DLibraryItemCommand(const QByteArray &itemData)
{
return Drop3DLibraryItemCommand(itemData);
}
ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QVector<InstancePropertyPair> &propertyList) const
{
QVector<PropertyValueContainer> valueVector;

View File

@@ -70,6 +70,7 @@ class AddImportContainer;
class MockupTypeContainer;
class IdContainer;
class ChangeSelectionCommand;
class Drop3DLibraryItemCommand;
namespace Internal {
class ChildrenChangeEventFilter;
@@ -180,6 +181,7 @@ protected:
ChildrenChangedCommand createChildrenChangedCommand(const ServerNodeInstance &parentInstance, const QList<ServerNodeInstance> &instanceList) const;
ComponentCompletedCommand createComponentCompletedCommand(const QList<ServerNodeInstance> &instanceList);
ChangeSelectionCommand createChangeSelectionCommand(const QList<ServerNodeInstance> &instanceList);
Drop3DLibraryItemCommand createDrop3DLibraryItemCommand(const QByteArray &itemData);
void addChangedProperty(const InstancePropertyPair &property);

View File

@@ -27,6 +27,8 @@
#include <QQuickItem>
#include <QQuickView>
#include <QDropEvent>
#include <QMimeData>
#include "servernodeinstance.h"
#include "childrenchangeeventfilter.h"
@@ -57,11 +59,13 @@
#include "removesharedmemorycommand.h"
#include "changeselectioncommand.h"
#include "objectnodeinstance.h"
#include <drop3dlibraryitemcommand.h>
#include "dummycontextobject.h"
#include "../editor3d/cameracontrolhelper.h"
#include "../editor3d/mousearea3d.h"
#include "../editor3d/camerageometry.h"
#include "../editor3d/gridgeometry.h"
#include <designersupportdelegate.h>
@@ -79,6 +83,25 @@ static QVariant objectToVariant(QObject *object)
return QVariant::fromValue(object);
}
bool Qt5InformationNodeInstanceServer::eventFilter(QObject *, QEvent *event)
{
switch (event->type()) {
case QEvent::Drop: {
QDropEvent *dropEvent = static_cast<QDropEvent *>(event);
QByteArray data = dropEvent->mimeData()->data(
QStringLiteral("application/vnd.bauhaus.itemlibraryinfo"));
if (!data.isEmpty())
nodeInstanceClient()->library3DItemDropped(createDrop3DLibraryItemCommand(data));
} break;
default:
break;
}
return false;
}
QObject *Qt5InformationNodeInstanceServer::createEditView3D(QQmlEngine *engine)
{
auto helper = new QmlDesigner::Internal::CameraControlHelper();
@@ -87,6 +110,7 @@ QObject *Qt5InformationNodeInstanceServer::createEditView3D(QQmlEngine *engine)
#ifdef QUICK3D_MODULE
qmlRegisterType<QmlDesigner::Internal::MouseArea3D>("MouseArea3D", 1, 0, "MouseArea3D");
qmlRegisterType<QmlDesigner::Internal::CameraGeometry>("CameraGeometry", 1, 0, "CameraGeometry");
qmlRegisterType<QmlDesigner::Internal::GridGeometry>("GridGeometry", 1, 0, "GridGeometry");
#endif
QQmlComponent component(engine, QUrl("qrc:/qtquickplugin/mockfiles/EditView3D.qml"));
@@ -98,6 +122,7 @@ QObject *Qt5InformationNodeInstanceServer::createEditView3D(QQmlEngine *engine)
return nullptr;
}
window->installEventFilter(this);
QObject::connect(window, SIGNAL(objectClicked(QVariant)), this, SLOT(objectClicked(QVariant)));
QObject::connect(window, SIGNAL(commitObjectProperty(QVariant, QVariant)),
this, SLOT(handleObjectPropertyCommit(QVariant, QVariant)));

View File

@@ -57,6 +57,7 @@ private slots:
protected:
void collectItemChangesAndSendChangeCommands() override;
bool eventFilter(QObject *obj, QEvent *event) override;
void sendChildrenChangedCommand(const QList<ServerNodeInstance> &childList);
void sendTokenBack();
bool isDirtyRecursiveForNonInstanceItems(QQuickItem *item) const;

View File

@@ -15,17 +15,43 @@
<file>mockfiles/LightGizmo.qml</file>
<file>mockfiles/IconGizmo.qml</file>
<file>mockfiles/Overlay2D.qml</file>
<file>mockfiles/HelperGrid.qml</file>
<file>mockfiles/DirectionalDraggable.qml</file>
<file>mockfiles/PlanarDraggable.qml</file>
<file>mockfiles/PlanarMoveHandle.qml</file>
<file>mockfiles/PlanarScaleHandle.qml</file>
<file>mockfiles/ScaleRod.qml</file>
<file>mockfiles/ScaleGizmo.qml</file>
<file>mockfiles/ToolBarButton.qml</file>
<file>mockfiles/RotateGizmo.qml</file>
<file>mockfiles/RotateRing.qml</file>
<file>mockfiles/meshes/arrow.mesh</file>
<file>mockfiles/meshes/scalerod.mesh</file>
<file>mockfiles/images/camera-pick-icon.png</file>
<file>mockfiles/images/camera-pick-icon@2x.png</file>
<file>mockfiles/meshes/ring.mesh</file>
<file>mockfiles/meshes/ringselect.mesh</file>
<file>mockfiles/images/editor_camera.png</file>
<file>mockfiles/images/editor_camera@2x.png</file>
<file>mockfiles/images/light-pick-icon.png</file>
<file>mockfiles/images/light-pick-icon@2x.png</file>
<file>mockfiles/images/item_selection_active.png</file>
<file>mockfiles/images/item_selection_active@2x.png</file>
<file>mockfiles/images/item_selection_selected.png</file>
<file>mockfiles/images/item_selection_selected@2x.png</file>
<file>mockfiles/images/group_selection_selected.png</file>
<file>mockfiles/images/group_selection_selected@2x.png</file>
<file>mockfiles/images/group_selection_active.png</file>
<file>mockfiles/images/group_selection_active@2x.png</file>
<file>mockfiles/images/move_active.png</file>
<file>mockfiles/images/move_active@2x.png</file>
<file>mockfiles/images/move_selected.png</file>
<file>mockfiles/images/move_selected@2x.png</file>
<file>mockfiles/images/rotate_active.png</file>
<file>mockfiles/images/rotate_active@2x.png</file>
<file>mockfiles/images/rotate_selected.png</file>
<file>mockfiles/images/rotate_selected@2x.png</file>
<file>mockfiles/images/scale_active.png</file>
<file>mockfiles/images/scale_active@2x.png</file>
<file>mockfiles/images/scale_selected.png</file>
<file>mockfiles/images/scale_selected@2x.png</file>
</qresource>
</RCC>

View File

@@ -32,8 +32,7 @@ Column {
anchors.right: parent.right
StandardTextSection {
showIsWrapping: true
useLineEdit: true
showVerticalAlignment: true
showFormatProperty: true
}
@@ -62,6 +61,18 @@ Column {
}
}
Section {
anchors.left: parent.left
anchors.right: parent.right
caption: qsTr("Selected Text Color")
ColorEditor {
caption: qsTr("Selected Text Color")
backendValue: backendValues.selectedTextColor
supportGradient: false
}
}
FontSection {
showStyle: false
}

View File

@@ -39,6 +39,16 @@ Section {
rows: 4
columns: 2
Label {
text: qsTr("Mouse selection mode")
}
ComboBox {
Layout.fillWidth: true
backendValue: backendValues.mouseSelectionMode
scope: "TextInput"
model: ["SelectCharacters", "SelectWords"]
}
Label {
visible: textInputSection.isTextInput
text: qsTr("Input mask")
@@ -48,6 +58,7 @@ Section {
visible: textInputSection.isTextInput
backendValue: backendValues.inputMask
Layout.fillWidth: true
showTranslateCheckBox: false
}
Label {
@@ -73,6 +84,33 @@ Section {
visible: textInputSection.isTextInput
backendValue: backendValues.passwordCharacter
Layout.fillWidth: true
showTranslateCheckBox: false
}
Label {
visible: !textInputSection.isTextInput
text: qsTr("Tab stop distance")
tooltip: qsTr("Sets the default distance, in device units, between tab stops.")
}
SpinBox {
visible: !textInputSection.isTextInput
Layout.fillWidth: true
backendValue: backendValues.tabStopDistance
maximumValue: 200
minimumValue: 0
}
Label {
visible: !textInputSection.isTextInput
text: qsTr("Text margin")
tooltip: qsTr("Sets the margin, in pixels, around the text in the TextEdit..")
}
SpinBox {
visible: !textInputSection.isTextInput
Layout.fillWidth: true
backendValue: backendValues.textMargin
maximumValue: 200
minimumValue: -200
}
Label {
@@ -101,10 +139,36 @@ Section {
}
CheckBox {
visible: textInputSection.isTextInput
Layout.fillWidth: true
text: qsTr("Auto scroll")
backendValue: backendValues.autoScroll
}
CheckBox {
Layout.fillWidth: true
text: qsTr("Overwrite mode")
backendValue: backendValues.overwriteMode
}
CheckBox {
Layout.fillWidth: true
text: qsTr("Persistent selection")
backendValue: backendValues.persistentSelection
}
CheckBox {
Layout.fillWidth: true
text: qsTr("Select by mouse")
backendValue: backendValues.selectByMouse
}
CheckBox {
visible: !textInputSection.isTextInput
Layout.fillWidth: true
text: qsTr("Select by keyboard")
backendValue: backendValues.selectByKeyboard
}
}
}
}

View File

@@ -32,8 +32,7 @@ Column {
anchors.right: parent.right
StandardTextSection {
useLineEdit: false
showIsWrapping: false
showVerticalAlignment: true
}
Section {
@@ -61,6 +60,18 @@ Column {
}
}
Section {
anchors.left: parent.left
anchors.right: parent.right
caption: qsTr("Selected Text Color")
ColorEditor {
caption: qsTr("Selected Text Color")
backendValue: backendValues.selectedTextColor
supportGradient: false
}
}
FontSection {
showStyle: false
}

View File

@@ -32,12 +32,11 @@ Column {
anchors.right: parent.right
StandardTextSection {
useLineEdit: true
showIsWrapping: true
showVerticalAlignment: true
showFormatProperty: true
showElide: true
showFontSizeMode: true
showLineHeight: true
}
Section {

View File

@@ -35,9 +35,10 @@ Section {
property bool showIsWrapping: false
property bool showElide: false
property bool showVerticalAlignment: false
property bool useLineEdit: true
property bool showFormatProperty: false
property bool showFontSizeMode: false
property bool showLineHeight: false
SectionLayout {
columns: 2
@@ -46,7 +47,6 @@ Section {
text: qsTr("Text")
}
LineEdit {
//visible: useLineEdit
backendValue: backendValues.text
Layout.fillWidth: true
}
@@ -119,10 +119,12 @@ Section {
}
Label {
visible: showFontSizeMode
text: qsTr("Font size mode")
toolTip: qsTr("Specifies how the font size of the displayed text is determined.")
}
ComboBox {
visible: showFontSizeMode
scope: "Text"
model: ["FixedSize", "HorizontalFit", "VerticalFit", "Fit"]
backendValue: backendValues.fontSizeMode
@@ -131,11 +133,13 @@ Section {
Label {
visible: showLineHeight
text: qsTr("Line height")
tooltip: qsTr("Sets the line height for the text.")
}
SpinBox {
visible: showLineHeight
Layout.fillWidth: true
backendValue: (backendValues.lineHeight === undefined) ? dummyBackendValue : backendValues.lineHeight
maximumValue: 500

View File

@@ -114,6 +114,7 @@ Rectangle {
var y = root.mapToGlobal(0,0).y - 32
bindingEditor.showWidget(x, y)
bindingEditor.text = delegateWhenConditionString
bindingEditor.prepareBindings()
}
}
@@ -205,6 +206,8 @@ Rectangle {
id: bindingEditor
stateModelNodeProperty: statesEditorModel.stateModelNode()
onRejected: {
hideWidget()
}

View File

@@ -61,6 +61,16 @@
}
]
},
{
"trDisplayName": "Kit Selection",
"trShortTitle": "Kits",
"typeId": "Kits",
"enabled": "%{JS: !value('IsSubproject')}",
"data": {
"projectFilePath": "%{ProjectFile}",
"requiredFeatures": [ "QtSupport.Wizards.FeatureQt.5"]
}
},
{
"trDisplayName": "Project Management",
"trShortTitle": "Summary",
@@ -84,7 +94,8 @@
},
{
"source": "plugin.cpp",
"target": "%{PluginSrc}"
"target": "%{PluginSrc}",
"openInEditor": true
},
{
"source": "plugin.h",

File diff suppressed because it is too large Load Diff

View File

@@ -870,6 +870,7 @@ FilePath AndroidConfig::qtLiveApkPath() const
///////////////////////////////////
void AndroidConfigurations::setConfig(const AndroidConfig &devConfigs)
{
emit m_instance->aboutToUpdate();
m_instance->m_config = devConfigs;
m_instance->save();

View File

@@ -209,6 +209,7 @@ public:
static QProcessEnvironment toolsEnvironment(const AndroidConfig &config);
signals:
void aboutToUpdate();
void updated();
private:

View File

@@ -288,8 +288,8 @@ QJsonObject AndroidManager::deploymentSettings(const Target *target)
Utils::FilePath AndroidManager::dirPath(const ProjectExplorer::Target *target)
{
if (target->activeBuildConfiguration())
return target->activeBuildConfiguration()->buildDirectory().pathAppended(Constants::ANDROID_BUILDDIRECTORY);
if (auto *bc = target->activeBuildConfiguration())
return bc->buildDirectory().pathAppended(Constants::ANDROID_BUILDDIRECTORY);
return Utils::FilePath();
}

View File

@@ -49,7 +49,12 @@ namespace Internal {
AndroidQtVersion::AndroidQtVersion()
: QtSupport::BaseQtVersion()
, m_guard(std::make_unique<QObject>())
{
QObject::connect(AndroidConfigurations::instance(),
&AndroidConfigurations::aboutToUpdate,
m_guard.get(),
[this] { resetCache(); });
}
bool AndroidQtVersion::isValid() const

View File

@@ -58,6 +58,7 @@ public:
protected:
void parseMkSpec(ProFileEvaluator *) const override;
private:
std::unique_ptr<QObject> m_guard;
mutable QStringList m_androidAbis;
mutable int m_minNdk = -1;
};

View File

@@ -67,7 +67,7 @@ using namespace Utils;
namespace Android {
namespace Internal {
static const QString pidScript = "pidof -s \"%1\"";
static const QString pidScript = "pidof -s '%1'";
static const QString pidScriptPreNougat = QStringLiteral("for p in /proc/[0-9]*; "
"do cat <$p/cmdline && echo :${p##*/}; done");
static const QString pidPollingScript = QStringLiteral("while [ -d /proc/%1 ]; do sleep 1; done");
@@ -288,8 +288,8 @@ bool AndroidRunnerWorker::uploadGdbServer()
qCDebug(androidRunWorkerLog) << "Gdbserver copy from temp directory failed";
return false;
}
QTC_ASSERT(runAdb({"shell", "run-as", m_packageName, "chmod", "+x", "./gdbserver"}),
qCDebug(androidRunWorkerLog) << "Gdbserver chmod +x failed.");
QTC_ASSERT(runAdb({"shell", "run-as", m_packageName, "chmod", "777", "./gdbserver"}),
qCDebug(androidRunWorkerLog) << "Gdbserver chmod 777 failed.");
return true;
}

View File

@@ -34,7 +34,8 @@ namespace GTestUtils {
static const QStringList valid = {
QStringLiteral("TEST"), QStringLiteral("TEST_F"), QStringLiteral("TEST_P"),
QStringLiteral("TYPED_TEST"), QStringLiteral("TYPED_TEST_P")
QStringLiteral("TYPED_TEST"), QStringLiteral("TYPED_TEST_P"),
QStringLiteral("GTEST_TEST")
};
bool isGTestMacro(const QString &macro)

View File

@@ -46,7 +46,9 @@
#include <coreplugin/icore.h>
#include <projectexplorer/buildmanager.h>
#include <projectexplorer/projectexplorer.h>
#include <texteditor/fontsettings.h>
#include <texteditor/texteditor.h>
#include <texteditor/texteditorsettings.h>
#include <utils/qtcassert.h>
#include <utils/theme/theme.h>
#include <utils/utilsicons.h>
@@ -131,9 +133,7 @@ TestResultsPane::TestResultsPane(QObject *parent) :
m_textOutput = new QPlainTextEdit;
m_textOutput->setPalette(pal);
QFont font("monospace");
font.setStyleHint(QFont::TypeWriter);
m_textOutput->setFont(font);
m_textOutput->setFont(TextEditor::TextEditorSettings::fontSettings().font());
m_textOutput->setWordWrapMode(QTextOption::WordWrap);
m_textOutput->setReadOnly(true);
new OutputHighlighter(m_textOutput->document());

View File

@@ -1179,7 +1179,6 @@ QString BinEditorWidget::toolTip(const QHelpEvent *helpEvent) const
if (!pos)
return QString();
selStart = pos.value();
selEnd = selStart;
byteCount = 1;
}

View File

@@ -315,15 +315,11 @@ static ::Utils::FilePath compilerPath(const CppTools::ProjectPart &projectPart)
static ::Utils::FilePath buildDirectory(const ProjectExplorer::Project &project)
{
ProjectExplorer::Target *target = project.activeTarget();
if (!target)
return ::Utils::FilePath();
ProjectExplorer::BuildConfiguration *buildConfig = target->activeBuildConfiguration();
if (!buildConfig)
return ::Utils::FilePath();
return buildConfig->buildDirectory();
if (auto *target = project.activeTarget()) {
if (auto *bc = target->activeBuildConfiguration())
return bc->buildDirectory();
}
return {};
}
static QStringList projectPartArguments(const ProjectPart &projectPart)

View File

@@ -495,7 +495,7 @@ void ClangToolRunWorker::finalize()
QString msg = tr("%1: Not all files could be analyzed.").arg(toolName);
TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
Target *target = runControl()->target();
if (target && !target->activeBuildConfiguration()->buildDirectory().exists()
if (target && target->activeBuildConfiguration() && !target->activeBuildConfiguration()->buildDirectory().exists()
&& !m_runSettings.buildBeforeAnalysis()) {
msg = tr("%1: You might need to build the project to generate or update source "
"files. To build automatically, enable \"Build the project before starting "

View File

@@ -159,7 +159,7 @@ void ClangToolsUnitTests::testProject_data()
// Test that tidy and clazy diagnostics are emitted for the same project.
addTestRow("clangtidy_clazy/clangtidy_clazy.pro",
1 /*tidy*/ + 1 /*clazy*/,
configFor("misc-unconventional-assign-operator", "base-class-event"));
configFor("misc-unconventional-assign-operator", "qgetenv"));
}
void ClangToolsUnitTests::addTestRow(const QByteArray &relativeFilePath,

View File

@@ -23,19 +23,11 @@
**
****************************************************************************/
#include <QCoreApplication>
#include <QByteArray>
#include <QtGlobal>
// -Wclazy-ctor-missing-parent-argument
class TestObject : public QObject
void test()
{
Q_OBJECT
public:
TestObject();
bool event(QEvent *) override
{
// -Wclazy-base-class-event
return false;
}
};
// -Wclazy-qgetenv
qgetenv("Foo").isEmpty();
}

View File

@@ -27,6 +27,8 @@
#include "cmakebuildconfiguration.h"
#include "cmakekitinformation.h"
#include "cmakeprojectplugin.h"
#include "cmakespecificsettings.h"
#include "cmaketoolmanager.h"
#include <projectexplorer/kit.h>
@@ -61,6 +63,10 @@ BuildDirParameters::BuildDirParameters(CMakeBuildConfiguration *bc)
if (Utils::HostOsInfo::isAnyUnixHost())
environment.set("ICECC", "no");
CMakeSpecificSettings *settings = CMakeProjectPlugin::projectTypeSpecificSettings();
if (!settings->ninjaPath().isEmpty())
environment.appendOrSetPath(settings->ninjaPath().toString());
cmakeToolId = CMakeKitAspect::cmakeToolId(k);
auto tc = ToolChainKitAspect::toolChain(k, Constants::CXX_LANGUAGE_ID);

View File

@@ -31,20 +31,24 @@ namespace Internal {
namespace {
static const char SETTINGS_KEY[] = "CMakeSpecificSettings";
static const char AFTER_ADD_FILE_ACTION_KEY[] = "ProjectPopupSetting";
static const char NINJA_PATH[] = "NinjaPath";
}
void CMakeSpecificSettings::fromSettings(QSettings *settings)
{
const QString rootKey = QString(SETTINGS_KEY) + '/';
afterAddFileToProjectSetting = static_cast<AfterAddFileAction>(
m_afterAddFileToProjectSetting = static_cast<AfterAddFileAction>(
settings->value(rootKey + AFTER_ADD_FILE_ACTION_KEY,
static_cast<int>(AfterAddFileAction::ASK_USER)).toInt());
m_ninjaPath = Utils::FilePath::fromUserInput(
settings->value(rootKey + NINJA_PATH, QString()).toString());
}
void CMakeSpecificSettings::toSettings(QSettings *settings) const
{
settings->beginGroup(QString(SETTINGS_KEY));
settings->setValue(QString(AFTER_ADD_FILE_ACTION_KEY), static_cast<int>(afterAddFileToProjectSetting));
settings->setValue(QString(AFTER_ADD_FILE_ACTION_KEY), static_cast<int>(m_afterAddFileToProjectSetting));
settings->endGroup();
}
}

View File

@@ -24,6 +24,7 @@
****************************************************************************/
#pragma once
#include <utils/fileutils.h>
#include <QSettings>
namespace CMakeProjectManager {
@@ -42,11 +43,14 @@ public:
void fromSettings(QSettings *settings);
void toSettings(QSettings *settings) const;
void setAfterAddFileSetting(AfterAddFileAction settings) { afterAddFileToProjectSetting = settings; }
AfterAddFileAction afterAddFileSetting() const { return afterAddFileToProjectSetting; }
void setAfterAddFileSetting(AfterAddFileAction settings) { m_afterAddFileToProjectSetting = settings; }
AfterAddFileAction afterAddFileSetting() const { return m_afterAddFileToProjectSetting; }
Utils::FilePath ninjaPath() const { return m_ninjaPath; }
private:
AfterAddFileAction afterAddFileToProjectSetting;
AfterAddFileAction m_afterAddFileToProjectSetting;
Utils::FilePath m_ninjaPath;
};
}

View File

@@ -107,7 +107,7 @@ class IntrospectionData
{
public:
bool m_didAttemptToRun = false;
bool m_didRun = false;
bool m_didRun = true;
bool m_hasServerMode = false;
bool m_queriedServerMode = false;
@@ -207,26 +207,17 @@ bool CMakeTool::isValid() const
return m_introspection->m_didRun;
}
Utils::SynchronousProcessResponse CMakeTool::run(const QStringList &args, bool mayFail) const
Utils::SynchronousProcessResponse CMakeTool::run(const QStringList &args, int timeoutS) const
{
if (m_introspection->m_didAttemptToRun && !m_introspection->m_didRun) {
Utils::SynchronousProcessResponse response;
response.result = Utils::SynchronousProcessResponse::StartFailed;
return response;
}
Utils::SynchronousProcess cmake;
cmake.setTimeoutS(1);
cmake.setTimeoutS(timeoutS);
cmake.setFlags(Utils::SynchronousProcess::UnixTerminalDisabled);
Utils::Environment env = Utils::Environment::systemEnvironment();
Utils::Environment::setupEnglishOutput(&env);
cmake.setProcessEnvironment(env.toProcessEnvironment());
cmake.setTimeOutMessageBoxEnabled(false);
Utils::SynchronousProcessResponse response = cmake.runBlocking({cmakeExecutable(), args});
m_introspection->m_didAttemptToRun = true;
m_introspection->m_didRun = mayFail ? true : (response.result == Utils::SynchronousProcessResponse::Finished);
return response;
return cmake.runBlocking({cmakeExecutable(), args});
}
QVariantMap CMakeTool::toMap() const
@@ -298,21 +289,21 @@ QList<CMakeTool::Generator> CMakeTool::supportedGenerators() const
TextEditor::Keywords CMakeTool::keywords()
{
if (m_introspection->m_functions.isEmpty()) {
if (m_introspection->m_functions.isEmpty() && m_introspection->m_didRun) {
Utils::SynchronousProcessResponse response;
response = run({"--help-command-list"});
response = run({"--help-command-list"}, 5);
if (response.result == Utils::SynchronousProcessResponse::Finished)
m_introspection->m_functions = response.stdOut().split('\n');
response = run({"--help-commands"});
response = run({"--help-commands"}, 5);
if (response.result == Utils::SynchronousProcessResponse::Finished)
parseFunctionDetailsOutput(response.stdOut());
response = run({"--help-property-list"});
response = run({"--help-property-list"}, 5);
if (response.result == Utils::SynchronousProcessResponse::Finished)
m_introspection->m_variables = parseVariableOutput(response.stdOut());
response = run({"--help-variable-list"});
response = run({"--help-variable-list"}, 5);
if (response.result == Utils::SynchronousProcessResponse::Finished) {
m_introspection->m_variables.append(parseVariableOutput(response.stdOut()));
m_introspection->m_variables = Utils::filteredUnique(m_introspection->m_variables);
@@ -417,25 +408,30 @@ Utils::FilePath CMakeTool::searchQchFile(const Utils::FilePath &executable)
void CMakeTool::readInformation(CMakeTool::QueryType type) const
{
if (!m_introspection->m_didRun && m_introspection->m_didAttemptToRun)
return;
m_introspection->m_didAttemptToRun = true;
if (!m_introspection->m_triedCapabilities) {
fetchFromCapabilities();
m_introspection->m_triedCapabilities = true;
m_introspection->m_queriedServerMode = true; // Got added after "-E capabilities" support!
}
if ((type == QueryType::GENERATORS && !m_introspection->m_generators.isEmpty())
|| (type == QueryType::SERVER_MODE && m_introspection->m_queriedServerMode)
|| (type == QueryType::VERSION && !m_introspection->m_version.fullVersion.isEmpty()))
return;
if (type == QueryType::GENERATORS) {
fetchGeneratorsFromHelp();
} else if (type == QueryType::SERVER_MODE) {
// Nothing to do...
} else if (type == QueryType::VERSION) {
fetchVersionFromVersionOutput();
} else {
QTC_ASSERT(false, return );
if ((type == QueryType::GENERATORS && !m_introspection->m_generators.isEmpty())
|| (type == QueryType::SERVER_MODE && m_introspection->m_queriedServerMode)
|| (type == QueryType::VERSION && !m_introspection->m_version.fullVersion.isEmpty()))
return;
if (type == QueryType::GENERATORS) {
fetchGeneratorsFromHelp();
} else if (type == QueryType::SERVER_MODE) {
// Nothing to do...
} else if (type == QueryType::VERSION) {
fetchVersionFromVersionOutput();
} else {
QTC_ASSERT(false, return );
}
}
}
@@ -533,9 +529,11 @@ QStringList CMakeTool::parseVariableOutput(const QString &output)
void CMakeTool::fetchGeneratorsFromHelp() const
{
Utils::SynchronousProcessResponse response = run({"--help"});
if (response.result != Utils::SynchronousProcessResponse::Finished)
return;
parseGeneratorsFromHelp(response.stdOut().split('\n'));
m_introspection->m_didRun = m_introspection->m_didRun
&& response.result == Utils::SynchronousProcessResponse::Finished;
if (response.result == Utils::SynchronousProcessResponse::Finished)
parseGeneratorsFromHelp(response.stdOut().split('\n'));
}
void CMakeTool::parseGeneratorsFromHelp(const QStringList &lines) const
@@ -588,10 +586,12 @@ void CMakeTool::parseGeneratorsFromHelp(const QStringList &lines) const
void CMakeTool::fetchVersionFromVersionOutput() const
{
Utils::SynchronousProcessResponse response = run({"--version"});
if (response.result != Utils::SynchronousProcessResponse::Finished)
return;
parseVersionFormVersionOutput(response.stdOut().split('\n'));
m_introspection->m_didRun = m_introspection->m_didRun
&& response.result == Utils::SynchronousProcessResponse::Finished;
if (response.result == Utils::SynchronousProcessResponse::Finished)
parseVersionFormVersionOutput(response.stdOut().split('\n'));
}
void CMakeTool::parseVersionFormVersionOutput(const QStringList &lines) const
@@ -612,11 +612,10 @@ void CMakeTool::parseVersionFormVersionOutput(const QStringList &lines) const
void CMakeTool::fetchFromCapabilities() const
{
Utils::SynchronousProcessResponse response = run({"-E", "capabilities"}, true);
if (response.result != Utils::SynchronousProcessResponse::Finished)
return;
Utils::SynchronousProcessResponse response = run({"-E", "capabilities"});
parseFromCapabilities(response.stdOut());
if (response.result == Utils::SynchronousProcessResponse::Finished)
parseFromCapabilities(response.stdOut());
}
static int getVersion(const QVariantMap &obj, const QString value)

View File

@@ -126,7 +126,7 @@ private:
};
void readInformation(QueryType type) const;
Utils::SynchronousProcessResponse run(const QStringList &args, bool mayFail = false) const;
Utils::SynchronousProcessResponse run(const QStringList &args, int timeoutS = 1) const;
void parseFunctionDetailsOutput(const QString &output);
QStringList parseVariableOutput(const QString &output);

View File

@@ -735,7 +735,7 @@ EditorView *SplitterOrView::takeView()
return oldView;
}
void SplitterOrView::split(Qt::Orientation orientation)
void SplitterOrView::split(Qt::Orientation orientation, bool activateView)
{
Q_ASSERT(m_view && m_splitter == nullptr);
m_splitter = new MiniSplitter(this);
@@ -766,7 +766,8 @@ void SplitterOrView::split(Qt::Orientation orientation)
otherView->view()->setCloseSplitIcon(Utils::Icons::CLOSE_SPLIT_BOTTOM.icon());
}
EditorManagerPrivate::activateView(otherView->view());
if (activateView)
EditorManagerPrivate::activateView(otherView->view());
emit splitStateChanged();
}
@@ -933,7 +934,7 @@ void SplitterOrView::restoreState(const QByteArray &state)
qint32 orientation;
QByteArray splitter, first, second;
stream >> orientation >> splitter >> first >> second;
split((Qt::Orientation)orientation);
split((Qt::Orientation) orientation, false);
m_splitter->restoreState(splitter);
static_cast<SplitterOrView*>(m_splitter->widget(0))->restoreState(first);
static_cast<SplitterOrView*>(m_splitter->widget(1))->restoreState(second);

View File

@@ -173,7 +173,7 @@ public:
explicit SplitterOrView(EditorView *view);
~SplitterOrView() override;
void split(Qt::Orientation orientation);
void split(Qt::Orientation orientation, bool activateView = true);
void unsplit();
inline bool isView() const { return m_view != nullptr; }

View File

@@ -116,7 +116,7 @@ QString clangIncludeDirectory(const QString &clangVersion, const QString &clangR
#else
Q_UNUSED(clangVersion)
Q_UNUSED(clangResourceDirectory)
return CLANG_RESOURCE_DIR;
return {CLANG_RESOURCE_DIR};
#endif
}

View File

@@ -457,33 +457,31 @@ bool StackHandler::contextMenuEvent(const ItemViewEvent &ev)
void StackHandler::copyContentsToClipboard()
{
QString str;
int n = rowCount();
int m = columnCount(QModelIndex());
const int m = columnCount(QModelIndex());
QVector<int> largestColumnWidths(m, 0);
// First, find the widths of the largest columns,
// so that we can print them out nicely aligned.
for (int i = 0; i != n; ++i) {
forItemsAtLevel<2>([m, &largestColumnWidths](StackFrameItem *item) {
for (int j = 0; j < m; ++j) {
const QModelIndex idx = index(i, j);
const int columnWidth = data(idx, Qt::DisplayRole).toString().size();
const int columnWidth = item->data(j, Qt::DisplayRole).toString().size();
if (columnWidth > largestColumnWidths.at(j))
largestColumnWidths[j] = columnWidth;
}
}
});
for (int i = 0; i != n; ++i) {
QString str;
forItemsAtLevel<2>([m, largestColumnWidths, &str](StackFrameItem *item) {
for (int j = 0; j != m; ++j) {
QModelIndex idx = index(i, j);
const QString columnEntry = data(idx, Qt::DisplayRole).toString();
const QString columnEntry = item->data(j, Qt::DisplayRole).toString();
str += columnEntry;
const int difference = largestColumnWidths.at(j) - columnEntry.size();
// Add one extra space between columns.
str += QString().fill(' ', difference > 0 ? difference + 1 : 1);
str += QString(qMax(difference, 0) + 1, QChar(' '));
}
str += '\n';
}
});
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(str, QClipboard::Selection);
clipboard->setText(str, QClipboard::Clipboard);

View File

@@ -5,7 +5,7 @@ project(QLiteHtml)
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/litehtml/CMakeLists.txt)
set(ORIG_FPIC ${CMAKE_POSITION_INDEPENDENT_CODE})
if (WIN32)
set(LITEHTML_UTF8 ON)
set(LITEHTML_UTF8 ON CACHE BOOL "")
endif()
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
add_subdirectory(litehtml)

View File

@@ -503,9 +503,9 @@ void LanguageClientManager::findLinkAt(TextEditor::TextDocument *document,
}
}
});
for (Client *interface : reachableClients()) {
if (interface->findLinkAt(request))
m_exclusiveRequests[request.id()] << interface;
if (Client *client = clientForUri(uri)) {
if (client->reachable())
client->findLinkAt(request);
}
}

View File

@@ -28,23 +28,15 @@
namespace McuSupport {
namespace Constants {
const char TOOLCHAIN_TYPEID[] = "McuSupport.ToolChain.ARM-GCC";
const char DEVICE_TYPE[] = "McuSupport.DeviceType";
const char DEVICE_ID[] = "McuSupport.Device";
const char MCUSUPPORT_QT_VERSION[] = "Qt4ProjectManager.QtVersion.McuSupport";
const char RUNCONFIGURATION[] = "McuSupport.RunConfiguration";
const char SETTINGS_ID[] = "CC.McuSupport.Configuration";
const char KIT_BOARD_VENDOR_KEY[] = "McuSupport.BoardVendor";
const char KIT_BOARD_MODEL_KEY[] = "McuSupport.BoardModel";
const char ENVVAR_ARMGCC_DIR[] = "ARMGCC_DIR";
const char ENVVAR_STM32CUBE_FW_F7_SDK_PATH[] = "STM32Cube_FW_F7_SDK_PATH";
const char KIT_MCUTARGET_VENDOR_KEY[] = "McuSupport.McuTargetVendor";
const char KIT_MCUTARGET_MODEL_KEY[] = "McuSupport.McuTargetModel";
const char SETTINGS_GROUP[] = "McuSupport";
const char SETTINGS_KEY_PACKAGE_PREFIX[] = "package_";
const char SETTINGS_KEY_PACKAGE_ARMGCC[] = "ArmGcc";
const char SETTINGS_KEY_STM32CUBE_FW_F7_SDK_PATH[] = "STM32Cube_FW_F7_SDK_PATH";
const char SETTINGS_KEY_STM32CUBE_PROGRAMMER_PATH[] = "STM32Cube_Cube_Programmer_Path";
const char SETTINGS_KEY_PACKAGE_PREFIX[] = "Package_";
} // namespace McuSupport
} // namespace Constants

View File

@@ -54,8 +54,8 @@
namespace McuSupport {
namespace Internal {
PackageOptions::PackageOptions(const QString &label, const QString &defaultPath,
const QString &detectionPath, const QString &settingsKey)
McuPackage::McuPackage(const QString &label, const QString &defaultPath,
const QString &detectionPath, const QString &settingsKey)
: m_label(label)
, m_defaultPath(defaultPath)
, m_detectionPath(detectionPath)
@@ -68,33 +68,28 @@ PackageOptions::PackageOptions(const QString &label, const QString &defaultPath,
s->endGroup();
}
QString PackageOptions::path() const
QString McuPackage::path() const
{
return QFileInfo(m_fileChooser->path() + m_relativePathModifier).absoluteFilePath();
}
QString PackageOptions::label() const
QString McuPackage::label() const
{
return m_label;
}
QString PackageOptions::detectionPath() const
QString McuPackage::detectionPath() const
{
return m_detectionPath;
}
QWidget *PackageOptions::widget()
QWidget *McuPackage::widget()
{
if (m_widget)
return m_widget;
m_widget = new QWidget;
m_fileChooser = new Utils::PathChooser;
QObject::connect(m_fileChooser, &Utils::PathChooser::pathChanged,
[this](){
updateStatus();
emit changed();
});
auto layout = new QGridLayout(m_widget);
layout->setContentsMargins(0, 0, 0, 0);
@@ -119,41 +114,49 @@ QWidget *PackageOptions::widget()
layout->addWidget(m_statusIcon, 1, 0);
layout->addWidget(m_statusLabel, 1, 1, 1, -1);
m_fileChooser->setPath(m_path); // Triggers updateStatus() call
m_fileChooser->setPath(m_path);
QObject::connect(m_fileChooser, &Utils::PathChooser::pathChanged,
[this](){
updateStatus();
emit changed();
});
updateStatus();
return m_widget;
}
PackageOptions::Status PackageOptions::status() const
McuPackage::Status McuPackage::status() const
{
return m_status;
}
void PackageOptions::setDownloadUrl(const QString &url)
void McuPackage::setDownloadUrl(const QString &url)
{
m_downloadUrl = url;
}
void PackageOptions::setEnvironmentVariableName(const QString &name)
void McuPackage::setEnvironmentVariableName(const QString &name)
{
m_environmentVariableName = name;
}
QString PackageOptions::environmentVariableName() const
QString McuPackage::environmentVariableName() const
{
return m_environmentVariableName;
}
void PackageOptions::setAddToPath(bool addToPath)
void McuPackage::setAddToPath(bool addToPath)
{
m_addToPath = addToPath;
}
bool PackageOptions::addToPath() const
bool McuPackage::addToPath() const
{
return m_addToPath;
}
void PackageOptions::writeToSettings() const
void McuPackage::writeToSettings() const
{
if (m_path.compare(m_defaultPath) == 0)
return;
@@ -163,12 +166,12 @@ void PackageOptions::writeToSettings() const
s->endGroup();
}
void PackageOptions::setRelativePathModifier(const QString &path)
void McuPackage::setRelativePathModifier(const QString &path)
{
m_relativePathModifier = path;
}
void PackageOptions::updateStatus()
void McuPackage::updateStatus()
{
m_path = m_fileChooser->rawPath();
const bool validPath = m_fileChooser->isValid();
@@ -198,54 +201,78 @@ void PackageOptions::updateStatus()
m_statusLabel->setText(statusText);
}
BoardOptions::BoardOptions(const QString &vendor, const QString &model,
const QString &toolChainFileName, const QString &qulPlatform,
const QVector<PackageOptions*> &packages)
McuTarget::McuTarget(const QString &vendor, const QString &model,
const QVector<McuPackage*> &packages)
: m_vendor(vendor)
, m_model(model)
, m_toolChainFile(toolChainFileName)
, m_qulPlatform(qulPlatform)
, m_packages(packages)
{
}
QString BoardOptions::model() const
{
return m_model;
}
QString BoardOptions::toolChainFile() const
{
return m_toolChainFile;
}
QString BoardOptions::qulPlatform() const
{
return m_qulPlatform;
}
QVector<PackageOptions *> BoardOptions::packages() const
{
return m_packages;
}
QString BoardOptions::vendor() const
QString McuTarget::vendor() const
{
return m_vendor;
}
static PackageOptions *createQulPackage()
QString McuTarget::model() const
{
auto result = new PackageOptions(
PackageOptions::tr("Qt MCU SDK"),
return m_model;
}
QVector<McuPackage *> McuTarget::packages() const
{
return m_packages;
}
void McuTarget::setToolChainFile(const QString &toolChainFile)
{
m_toolChainFile = toolChainFile;
}
QString McuTarget::toolChainFile() const
{
return m_toolChainFile;
}
void McuTarget::setQulPlatform(const QString &qulPlatform)
{
m_qulPlatform = qulPlatform;
}
QString McuTarget::qulPlatform() const
{
return m_qulPlatform;
}
bool McuTarget::isValid() const
{
return !Utils::anyOf(packages(), [](McuPackage *package) {
return package->status() != McuPackage::ValidPackage;
});
}
int McuTarget::colorDepth() const
{
return m_colorDepth;
}
void McuTarget::setColorDepth(int colorDepth)
{
m_colorDepth = colorDepth;
}
static McuPackage *createQtForMCUsPackage()
{
auto result = new McuPackage(
McuPackage::tr("Qt for MCUs SDK"),
QDir::homePath(),
Utils::HostOsInfo::withExecutableSuffix("bin/qmltocpp"),
"qulSdk");
"QtMCUSdk");
result->setEnvironmentVariableName("Qul_DIR");
return result;
}
static PackageOptions *createArmGccPackage()
static McuPackage *createArmGccPackage()
{
const char envVar[] = "ARMGCC_DIR";
@@ -267,43 +294,43 @@ static PackageOptions *createArmGccPackage()
if (defaultPath.isEmpty())
defaultPath = QDir::homePath();
auto result = new PackageOptions(
PackageOptions::tr("GNU Arm Embedded Toolchain"),
auto result = new McuPackage(
McuPackage::tr("GNU Arm Embedded Toolchain"),
defaultPath,
Utils::HostOsInfo::withExecutableSuffix("bin/arm-none-eabi-g++"),
Constants::SETTINGS_KEY_PACKAGE_ARMGCC);
"GNUArmEmbeddedToolchain");
result->setDownloadUrl(
"https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads");
result->setEnvironmentVariableName(envVar);
return result;
}
static PackageOptions *createStm32CubeFwF7SdkPackage()
static McuPackage *createStm32CubeFwF7SdkPackage()
{
auto result = new PackageOptions(
PackageOptions::tr("STM32Cube SDK"),
auto result = new McuPackage(
McuPackage::tr("STM32Cube SDK"),
"%{Env:STM32Cube_FW_F7_SDK_PATH}",
"Drivers/STM32F7xx_HAL_Driver",
"stm32CubeFwF7Sdk");
"Stm32CubeFwF7Sdk");
result->setDownloadUrl(
"https://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-mcu-packages/stm32cubef7.html");
result->setEnvironmentVariableName("STM32Cube_FW_F7_SDK_PATH");
return result;
}
static PackageOptions *createStm32CubeProgrammerPackage()
static McuPackage *createStm32CubeProgrammerPackage()
{
const QString defaultPath =
Utils::HostOsInfo::isWindowsHost() ?
QDir::fromNativeSeparators(qEnvironmentVariable("ProgramFiles"))
+ "/STMicroelectronics/STM32Cube/STM32CubeProgrammer/"
: QDir::homePath();
auto result = new PackageOptions(
PackageOptions::tr("STM32CubeProgrammer"),
auto result = new McuPackage(
McuPackage::tr("STM32CubeProgrammer"),
defaultPath,
QLatin1String(Utils::HostOsInfo::isWindowsHost() ? "/bin/STM32_Programmer_CLI.exe"
: "/bin/STM32_Programmer.sh"),
"stm32CubeProgrammer");
"Stm32CubeProgrammer");
result->setRelativePathModifier("/bin");
result->setDownloadUrl(
"https://www.st.com/en/development-tools/stm32cubeprog.html");
@@ -311,29 +338,29 @@ static PackageOptions *createStm32CubeProgrammerPackage()
return result;
}
static PackageOptions *createEvkbImxrt1050SdkPackage()
static McuPackage *createEvkbImxrt1050SdkPackage()
{
auto result = new PackageOptions(
PackageOptions::tr("NXP i.MXRT SDK"),
auto result = new McuPackage(
McuPackage::tr("NXP i.MXRT SDK"),
"%{Env:EVKB_IMXRT1050_SDK_PATH}", // TODO: Try to not use 1050 specifics
"EVKB-IMXRT1050_manifest_v3_5.xml",
"evkbImxrt1050Sdk");
"EvkbImxrt1050Sdk");
result->setDownloadUrl("https://mcuxpresso.nxp.com/en/welcome");
return result;
}
static PackageOptions *createSeggerJLinkPackage()
static McuPackage *createSeggerJLinkPackage()
{
const QString defaultPath =
Utils::HostOsInfo::isWindowsHost() ?
QDir::fromNativeSeparators(qEnvironmentVariable("ProgramFiles(x86)"))
+ "/SEGGER/JLink"
: QString("%{Env:SEGGER_JLINK_SOFTWARE_AND_DOCUMENTATION_PATH}");
auto result = new PackageOptions(
PackageOptions::tr("SEGGER JLink"),
auto result = new McuPackage(
McuPackage::tr("SEGGER JLink"),
defaultPath,
Utils::HostOsInfo::withExecutableSuffix("JLink"),
"seggerJLink");
"SeggerJLink");
result->setDownloadUrl("https://www.segger.com/downloads/jlink");
result->setEnvironmentVariableName("SEGGER_JLINK_SOFTWARE_AND_DOCUMENTATION_PATH");
return result;
@@ -342,38 +369,65 @@ static PackageOptions *createSeggerJLinkPackage()
McuSupportOptions::McuSupportOptions(QObject *parent)
: QObject(parent)
{
PackageOptions* qulPackage = createQulPackage();
PackageOptions* armGccPackage = createArmGccPackage();
PackageOptions* stm32CubeFwF7SdkPackage = createStm32CubeFwF7SdkPackage();
PackageOptions* stm32CubeProgrammerPackage = createStm32CubeProgrammerPackage();
PackageOptions* evkbImxrt1050SdkPackage = createEvkbImxrt1050SdkPackage();
PackageOptions* seggerJLinkPackage = createSeggerJLinkPackage();
qtForMCUsSdkPackage = createQtForMCUsPackage();
armGccPackage = createArmGccPackage();
McuPackage* stm32CubeFwF7SdkPackage = createStm32CubeFwF7SdkPackage();
McuPackage* stm32CubeProgrammerPackage = createStm32CubeProgrammerPackage();
McuPackage* evkbImxrt1050SdkPackage = createEvkbImxrt1050SdkPackage();
McuPackage* seggerJLinkPackage = createSeggerJLinkPackage();
toolchainPackage = armGccPackage;
auto stmPackages = {armGccPackage, stm32CubeFwF7SdkPackage, stm32CubeProgrammerPackage,
qulPackage};
auto nxpPackages = {armGccPackage, evkbImxrt1050SdkPackage, seggerJLinkPackage,
qulPackage};
auto desktopPackages = {qulPackage};
packages = {armGccPackage, stm32CubeFwF7SdkPackage, stm32CubeProgrammerPackage,
evkbImxrt1050SdkPackage, seggerJLinkPackage, qulPackage};
auto stmEvalPackages = {
armGccPackage, stm32CubeProgrammerPackage, qtForMCUsSdkPackage};
auto stmEngPackages = {
armGccPackage, stm32CubeFwF7SdkPackage, stm32CubeProgrammerPackage, qtForMCUsSdkPackage};
auto nxpEvalPackages = {
armGccPackage, seggerJLinkPackage, qtForMCUsSdkPackage};
auto nxpEngPackages = {
armGccPackage, evkbImxrt1050SdkPackage, seggerJLinkPackage, qtForMCUsSdkPackage};
auto desktopPackages = {
qtForMCUsSdkPackage};
packages = {
armGccPackage, stm32CubeFwF7SdkPackage, stm32CubeProgrammerPackage, evkbImxrt1050SdkPackage,
seggerJLinkPackage, qtForMCUsSdkPackage};
const QString vendorStm = "STM";
const QString vendorNxp = "NXP";
const QString vendorQt = "Qt";
boards.append(new BoardOptions(vendorStm,
"stm32f7508", "CMake/stm32f7508-discovery.cmake", "", stmPackages));
boards.append(new BoardOptions(vendorStm,
"stm32f769i", "CMake/stm32f769i-discovery.cmake", "", stmPackages));
boards.append(new BoardOptions(vendorNxp,
"evkbimxrt1050", "CMake/evkbimxrt1050-toolchain.cmake", "", nxpPackages));
boards.append(new BoardOptions(vendorQt,
"Desktop", "", "Qt", desktopPackages));
// STM
auto mcuTarget = new McuTarget(vendorStm, "stm32f7508", stmEvalPackages);
mcuTarget->setToolChainFile("CMake/stm32f7508-discovery.cmake");
mcuTarget->setColorDepth(32);
mcuTargets.append(mcuTarget);
mcuTarget = new McuTarget(vendorStm, "stm32f7508", stmEvalPackages);
mcuTarget->setToolChainFile("CMake/stm32f7508-discovery.cmake");
mcuTarget->setColorDepth(16);
mcuTargets.append(mcuTarget);
mcuTarget = new McuTarget(vendorStm, "stm32f769i", stmEvalPackages);
mcuTarget->setToolChainFile("CMake/stm32f769i-discovery.cmake");
mcuTargets.append(mcuTarget);
mcuTarget = new McuTarget(vendorStm, "Engineering", stmEngPackages);
mcuTargets.append(mcuTarget);
// NXP
mcuTarget = new McuTarget(vendorNxp, "evkbimxrt1050", nxpEvalPackages);
mcuTarget->setToolChainFile("CMake/evkbimxrt1050-toolchain.cmake");
mcuTargets.append(mcuTarget);
mcuTarget = new McuTarget(vendorNxp, "Engineering", nxpEngPackages);
mcuTargets.append(mcuTarget);
// Desktop
mcuTarget = new McuTarget(vendorQt, "Desktop", desktopPackages);
mcuTarget->setQulPlatform("Qt");
mcuTarget->setColorDepth(32);
mcuTargets.append(mcuTarget);
for (auto package : packages)
connect(package, &PackageOptions::changed, [this](){
connect(package, &McuPackage::changed, [this](){
emit changed();
});
}
@@ -382,16 +436,8 @@ McuSupportOptions::~McuSupportOptions()
{
qDeleteAll(packages);
packages.clear();
qDeleteAll(boards);
boards.clear();
}
QVector<BoardOptions *> McuSupportOptions::validBoards() const
{
return Utils::filtered(boards, [](BoardOptions *board){
return !Utils::anyOf(board->packages(), [](PackageOptions *package){
return package->status() != PackageOptions::ValidPackage;});
});
qDeleteAll(mcuTargets);
mcuTargets.clear();
}
static ProjectExplorer::ToolChain* armGccToolchain(const Utils::FilePath &path, Core::Id language)
@@ -420,20 +466,24 @@ static ProjectExplorer::ToolChain* armGccToolchain(const Utils::FilePath &path,
return toolChain;
}
static bool isDesktop(const BoardOptions* board)
static bool mcuTargetIsDesktop(const McuTarget* mcuTarget)
{
return board->qulPlatform() == "Qt";
return mcuTarget->qulPlatform() == "Qt";
}
static void setKitProperties(ProjectExplorer::Kit *k, const BoardOptions* board)
static void setKitProperties(const QString &kitName, ProjectExplorer::Kit *k,
const McuTarget* mcuTarget)
{
using namespace ProjectExplorer;
k->setUnexpandedDisplayName("QtMCU - " + board->model());
k->setValue(Constants::KIT_BOARD_VENDOR_KEY, board->vendor());
k->setValue(Constants::KIT_BOARD_MODEL_KEY, board->model());
k->setAutoDetected(false);
if (!isDesktop(board)) {
k->setUnexpandedDisplayName(kitName);
k->setValue(Constants::KIT_MCUTARGET_VENDOR_KEY, mcuTarget->vendor());
k->setValue(Constants::KIT_MCUTARGET_MODEL_KEY, mcuTarget->model());
k->setAutoDetected(true);
k->makeSticky();
if (mcuTargetIsDesktop(mcuTarget)) {
k->setDeviceTypeForIcon(Constants::DEVICE_TYPE);
} else {
k->setIrrelevantAspects({SysRootKitAspect::id(),
"QtSupport.QtInformation" // QtKitAspect::id()
});
@@ -468,7 +518,7 @@ static void setKitDebugger(ProjectExplorer::Kit *k, const QString &armGccPath)
DebuggerItem newDebugger;
newDebugger.setCommand(command);
newDebugger.setUnexpandedDisplayName(
PackageOptions::tr("Arm GDB at %1").arg(command.toUserOutput()));
McuPackage::tr("Arm GDB at %1").arg(command.toUserOutput()));
debuggerId = DebuggerItemManager::registerDebugger(newDebugger);
} else {
debuggerId = debugger->id();
@@ -484,13 +534,13 @@ static void setKitDevice(ProjectExplorer::Kit *k)
DeviceTypeKitAspect::setDeviceTypeId(k, Constants::DEVICE_TYPE);
}
static void setKitEnvironment(ProjectExplorer::Kit *k, const BoardOptions* board)
static void setKitEnvironment(ProjectExplorer::Kit *k, const McuTarget* mcuTarget)
{
using namespace ProjectExplorer;
Utils::EnvironmentItems changes;
QStringList pathAdditions;
for (auto package : board->packages()) {
for (auto package : mcuTarget->packages()) {
if (package->addToPath())
pathAdditions.append(QDir::toNativeSeparators(package->path()));
if (!package->environmentVariableName().isEmpty())
@@ -505,55 +555,72 @@ static void setKitEnvironment(ProjectExplorer::Kit *k, const BoardOptions* board
EnvironmentKitAspect::setEnvironmentChanges(k, changes);
}
static void setKitCMakeOptions(ProjectExplorer::Kit *k, const BoardOptions* board)
static void setKitCMakeOptions(ProjectExplorer::Kit *k, const McuTarget* mcuTarget,
const QString &qulDir)
{
using namespace CMakeProjectManager;
CMakeConfig config = CMakeConfigurationKitAspect::configuration(k);
if (!board->toolChainFile().isEmpty())
config.append(CMakeConfigItem("CMAKE_CXX_COMPILER", "%{Compiler:Executable:Cxx}"));
config.append(CMakeConfigItem("CMAKE_C_COMPILER", "%{Compiler:Executable:C}"));
if (!mcuTarget->toolChainFile().isEmpty())
config.append(CMakeConfigItem("CMAKE_TOOLCHAIN_FILE",
("%{CurrentBuild:Env:Qul_DIR}/" +
board->toolChainFile()).toUtf8()));
if (!board->qulPlatform().isEmpty())
(qulDir + "/" + mcuTarget->toolChainFile()).toUtf8()));
if (!mcuTarget->qulPlatform().isEmpty())
config.append(CMakeConfigItem("QUL_PLATFORM",
board->qulPlatform().toUtf8()));
if (isDesktop(board)) {
mcuTarget->qulPlatform().toUtf8()));
if (mcuTargetIsDesktop(mcuTarget))
config.append(CMakeConfigItem("CMAKE_PREFIX_PATH", "%{Qt:QT_INSTALL_PREFIX}"));
// TODO: Hack! Implement color depth variants of all targets
config.append(CMakeConfigItem("QUL_COLOR_DEPTH", "32"));
}
if (mcuTarget->colorDepth() >= 0)
config.append(CMakeConfigItem("QUL_COLOR_DEPTH",
QString::number(mcuTarget->colorDepth()).toLatin1()));
CMakeConfigurationKitAspect::setConfiguration(k, config);
if (Utils::HostOsInfo::isWindowsHost())
CMakeGeneratorKitAspect::setGenerator(k, "NMake Makefiles JOM");
}
ProjectExplorer::Kit *McuSupportOptions::kit(const BoardOptions* board)
QString McuSupportOptions::kitName(const McuTarget *mcuTarget) const
{
// TODO: get version from qulSdkPackage and insert into name
const QString colorDepth = mcuTarget->colorDepth() > 0
? QString::fromLatin1(" %1bpp").arg(mcuTarget->colorDepth())
: "";
return QString::fromLatin1("Qt for MCUs - %1 %2%3")
.arg(mcuTarget->vendor(), mcuTarget->model(), colorDepth);
}
QList<ProjectExplorer::Kit *> McuSupportOptions::existingKits(const McuTarget *mcuTargt)
{
using namespace ProjectExplorer;
const QString mcuTargetKitName = kitName(mcuTargt);
return Utils::filtered(KitManager::kits(), [&mcuTargetKitName](Kit *kit) {
return kit->isAutoDetected() && kit->unexpandedDisplayName() == mcuTargetKitName;
});
}
ProjectExplorer::Kit *McuSupportOptions::newKit(const McuTarget *mcuTarget)
{
using namespace ProjectExplorer;
Kit *kit = KitManager::kit([board](const Kit *k){
return board->model() == k->value(Constants::KIT_BOARD_MODEL_KEY).toString();
});
if (!kit) {
const QString armGccPath = toolchainPackage->path();
const auto init = [board, &armGccPath](Kit *k) {
KitGuard kitGuard(k);
const QString armGccPath = armGccPackage->path();
const QString qulDir = qtForMCUsSdkPackage->path();
const auto init = [this, mcuTarget](Kit *k) {
KitGuard kitGuard(k);
setKitProperties(k, board);
if (!isDesktop(board)) {
setKitToolchains(k, armGccPath);
setKitDebugger(k, armGccPath);
setKitDevice(k);
}
setKitEnvironment(k, board);
setKitCMakeOptions(k, board);
setKitProperties(kitName(mcuTarget), k, mcuTarget);
if (!mcuTargetIsDesktop(mcuTarget)) {
setKitToolchains(k, armGccPackage->path());
setKitDebugger(k, armGccPackage->path());
setKitDevice(k);
}
setKitEnvironment(k, mcuTarget);
setKitCMakeOptions(k, mcuTarget, qtForMCUsSdkPackage->path());
k->setup();
k->fix();
};
kit = KitManager::registerKit(init);
}
return kit;
k->setup();
k->fix();
};
return KitManager::registerKit(init);
}
} // Internal

View File

@@ -42,7 +42,7 @@ class Kit;
namespace McuSupport {
namespace Internal {
class PackageOptions : public QObject
class McuPackage : public QObject
{
Q_OBJECT
@@ -53,8 +53,8 @@ public:
ValidPackage
};
PackageOptions(const QString &label, const QString &defaultPath, const QString &detectionPath,
const QString &settingsKey);
McuPackage(const QString &label, const QString &defaultPath, const QString &detectionPath,
const QString &settingsKey);
QString path() const;
QString label() const;
@@ -96,26 +96,31 @@ private:
Status m_status = InvalidPath;
};
class BoardOptions : public QObject
class McuTarget : public QObject
{
Q_OBJECT
public:
BoardOptions(const QString &vendor, const QString &model, const QString &toolChainFile,
const QString &qulPlatform, const QVector<PackageOptions *> &packages);
McuTarget(const QString &vendor, const QString &model, const QVector<McuPackage *> &packages);
QString vendor() const;
QString model() const;
QVector<McuPackage *> packages() const;
void setToolChainFile(const QString &toolChainFile);
QString toolChainFile() const;
void setQulPlatform(const QString &qulPlatform);
QString qulPlatform() const;
QVector<PackageOptions *> packages() const;
void setColorDepth(int colorDepth);
int colorDepth() const;
bool isValid() const;
private:
const QString m_vendor;
const QString m_model;
const QString m_toolChainFile;
const QString m_qulPlatform;
const QVector<PackageOptions*> m_packages;
const QVector<McuPackage*> m_packages;
QString m_toolChainFile;
QString m_qulPlatform;
int m_colorDepth = -1;
};
class McuSupportOptions : public QObject
@@ -126,13 +131,15 @@ public:
McuSupportOptions(QObject *parent = nullptr);
~McuSupportOptions() override;
QVector<BoardOptions*> validBoards() const;
QVector<McuPackage*> packages;
QVector<McuTarget*> mcuTargets;
McuPackage *armGccPackage = nullptr;
McuPackage *qtForMCUsSdkPackage = nullptr;
QVector<PackageOptions*> packages;
QVector<BoardOptions*> boards;
PackageOptions *toolchainPackage = nullptr;
QString kitName(const McuTarget* mcuTarget) const;
ProjectExplorer::Kit *kit(const BoardOptions* board);
QList<ProjectExplorer::Kit *> existingKits(const McuTarget *mcuTargt);
ProjectExplorer::Kit *newKit(const McuTarget *mcuTarget);
signals:
void changed();

View File

@@ -28,6 +28,7 @@
#include "mcusupportoptions.h"
#include <coreplugin/icore.h>
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
@@ -49,16 +50,17 @@ public:
McuSupportOptionsWidget(const McuSupportOptions *options, QWidget *parent = nullptr);
void updateStatus();
void showBoardPackages(int boardIndex);
void showMcuTargetPackages();
McuTarget *currentMcuTarget() const;
private:
QString m_armGccPath;
const McuSupportOptions *m_options;
int m_currentBoardIndex = 0;
QMap <PackageOptions*, QWidget*> m_packageWidgets;
QMap <BoardOptions*, QWidget*> m_boardPacketWidgets;
QMap <McuPackage*, QWidget*> m_packageWidgets;
QMap <McuTarget*, QWidget*> m_mcuTargetPacketWidgets;
QFormLayout *m_packagesLayout = nullptr;
QLabel *m_statusLabel = nullptr;
QComboBox *m_mcuTargetComboBox = nullptr;
};
McuSupportOptionsWidget::McuSupportOptionsWidget(const McuSupportOptions *options, QWidget *parent)
@@ -67,16 +69,18 @@ McuSupportOptionsWidget::McuSupportOptionsWidget(const McuSupportOptions *option
{
auto mainLayout = new QVBoxLayout(this);
auto boardChooserlayout = new QHBoxLayout;
auto boardChooserLabel = new QLabel(McuSupportOptionsPage::tr("Target:"));
boardChooserlayout->addWidget(boardChooserLabel);
auto boardComboBox = new QComboBox;
boardChooserLabel->setBuddy(boardComboBox);
boardChooserLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
boardComboBox->addItems(Utils::transform<QStringList>(m_options->boards, [](BoardOptions *b){
return b->model();}));
boardChooserlayout->addWidget(boardComboBox);
mainLayout->addLayout(boardChooserlayout);
auto mcuTargetChooserlayout = new QHBoxLayout;
auto mcuTargetChooserLabel = new QLabel(McuSupportOptionsPage::tr("Target:"));
mcuTargetChooserlayout->addWidget(mcuTargetChooserLabel);
m_mcuTargetComboBox = new QComboBox;
mcuTargetChooserLabel->setBuddy(m_mcuTargetComboBox);
mcuTargetChooserLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
m_mcuTargetComboBox->addItems(
Utils::transform<QStringList>(m_options->mcuTargets, [this](McuTarget *t){
return m_options->kitName(t);
}));
mcuTargetChooserlayout->addWidget(m_mcuTargetComboBox);
mainLayout->addLayout(mcuTargetChooserlayout);
auto m_packagesGroupBox = new QGroupBox(McuSupportOptionsPage::tr("Packages"));
mainLayout->addWidget(m_packagesGroupBox);
@@ -84,57 +88,59 @@ McuSupportOptionsWidget::McuSupportOptionsWidget(const McuSupportOptions *option
m_packagesGroupBox->setLayout(m_packagesLayout);
m_statusLabel = new QLabel;
mainLayout->addWidget(m_statusLabel);
m_statusLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
mainLayout->addWidget(m_statusLabel, 2);
m_statusLabel->setWordWrap(true);
m_statusLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
m_statusLabel->setAlignment(Qt::AlignBottom | Qt::AlignLeft);
connect(options, &McuSupportOptions::changed, this, &McuSupportOptionsWidget::updateStatus);
connect(boardComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &McuSupportOptionsWidget::showBoardPackages);
connect(m_mcuTargetComboBox, &QComboBox::currentTextChanged,
this, &McuSupportOptionsWidget::showMcuTargetPackages);
showBoardPackages(m_currentBoardIndex);
}
static QString ulOfBoardModels(const QVector<BoardOptions*> &validBoards)
{
return "<ul><li>"
+ Utils::transform<QStringList>(validBoards,[](BoardOptions* board)
{return board->model();}).join("</li><li>")
+ "</li></ul>";
showMcuTargetPackages();
updateStatus();
}
void McuSupportOptionsWidget::updateStatus()
{
const QVector<BoardOptions*> validBoards = m_options->validBoards();
m_statusLabel->setText(validBoards.isEmpty()
? McuSupportOptionsPage::tr("No kits can currently be generated. "
"Select a target and provide the package paths. "
"Afterwards, press Apply to generate a kit for "
"your board.")
: McuSupportOptionsPage::tr("Kits for the following targets can be generated: "
"%1 "
"Press Apply to generate a kit for "
"your target.").arg(ulOfBoardModels(validBoards)));
const McuTarget *mcuTarget = currentMcuTarget();
if (!mcuTarget)
return;
m_statusLabel->setText(mcuTarget->isValid()
? QString::fromLatin1("A kit <b>%1</b> for the selected target can be generated. "
"Press Apply to generate it.").arg(m_options->kitName(
mcuTarget))
: QString::fromLatin1("Provide the package paths in order to create a kit for "
"your target."));
}
void McuSupportOptionsWidget::showBoardPackages(int boardIndex)
void McuSupportOptionsWidget::showMcuTargetPackages()
{
const McuTarget *mcuTarget = currentMcuTarget();
if (!mcuTarget)
return;
while (m_packagesLayout->rowCount() > 0) {
QFormLayout::TakeRowResult row = m_packagesLayout->takeRow(0);
row.labelItem->widget()->hide();
row.fieldItem->widget()->hide();
}
const BoardOptions *currentBoard = m_options->boards.at(boardIndex);
for (auto package : m_options->packages) {
QWidget *packageWidget = package->widget();
if (!currentBoard->packages().contains(package))
if (!mcuTarget->packages().contains(package))
continue;
m_packagesLayout->addRow(package->label(), packageWidget);
packageWidget->show();
}
updateStatus();
}
McuTarget *McuSupportOptionsWidget::currentMcuTarget() const
{
const int mcuTargetIndex = m_mcuTargetComboBox->currentIndex();
return m_options->mcuTargets.isEmpty() ? nullptr : m_options->mcuTargets.at(mcuTargetIndex);
}
McuSupportOptionsPage::McuSupportOptionsPage(QObject* parent)
@@ -159,14 +165,18 @@ void McuSupportOptionsPage::apply()
for (auto package : m_options->packages)
package->writeToSettings();
QTC_ASSERT(m_options->toolchainPackage, return);
QTC_ASSERT(m_options->armGccPackage, return);
QTC_ASSERT(m_options->qtForMCUsSdkPackage, return);
const QVector<BoardOptions*> validBoards = m_options->validBoards();
const McuTarget *mcuTarget = m_widget->currentMcuTarget();
if (!mcuTarget)
return;
using namespace ProjectExplorer;
for (auto board : validBoards)
m_options->kit(board);
for (auto existingKit : m_options->existingKits(mcuTarget))
ProjectExplorer::KitManager::deregisterKit(existingKit);
m_options->newKit(mcuTarget);
}
void McuSupportOptionsPage::finish()

View File

@@ -51,7 +51,7 @@ static CommandLine flashAndRunCommand(Target *target)
// TODO: Hack! Implement flash target name handling, properly
const QString targetName =
target->kit()->value(Constants::KIT_BOARD_VENDOR_KEY).toString() == "NXP"
target->kit()->value(Constants::KIT_MCUTARGET_VENDOR_KEY).toString() == "NXP"
? QString("flash_%1").arg(projectName)
: QString("flash_%1_and_bootloader").arg(projectName);

View File

@@ -51,6 +51,11 @@
"source": "main.qml.tpl",
"target": "%{ProjectDirectory}/%{MainQmlFile}",
"openInEditor": true
},
{
"source": "%{IDE:ResourcePath}/templates/wizards/projects/git.ignore",
"target": ".gitignore",
"condition": "%{JS: !value('IsSubproject') && value('VersionControl') === 'G.Git'}"
}
]
}

View File

@@ -106,11 +106,8 @@ void PerfLoadDialog::chooseDefaults()
ui->kitChooser->setCurrentKitId(target->kit()->id());
ProjectExplorer::BuildConfiguration *buildConfig = target->activeBuildConfiguration();
if (!buildConfig)
return;
ui->executableDirLineEdit->setText(buildConfig->buildDirectory().toString());
if (auto *bc = target->activeBuildConfiguration())
ui->executableDirLineEdit->setText(bc->buildDirectory().toString());
}
} // namespace Internal

View File

@@ -39,6 +39,7 @@
#include <coreplugin/variablechooser.h>
#include <ssh/sshconnection.h>
#include <utils/algorithm.h>
#include <utils/elidinglabel.h>
#include <utils/environment.h>
#include <utils/environmentdialog.h>
#include <utils/macroexpander.h>
@@ -1129,7 +1130,7 @@ class EnvironmentKitAspectWidget : public KitAspectWidget
public:
EnvironmentKitAspectWidget(Kit *workingCopy, const KitAspect *ki)
: KitAspectWidget(workingCopy, ki),
m_summaryLabel(new QLabel),
m_summaryLabel(new Utils::ElidingLabel),
m_manageButton(new QPushButton),
m_mainWidget(new QWidget)
{
@@ -1153,9 +1154,7 @@ private:
void refresh() override
{
const Utils::EnvironmentItems changes = currentEnvironment();
QString shortSummary = Utils::EnvironmentItem::toStringList(changes).join(QLatin1String("; "));
QFontMetrics fm(m_summaryLabel->font());
shortSummary = fm.elidedText(shortSummary, Qt::ElideRight, m_summaryLabel->width());
const QString shortSummary = Utils::EnvironmentItem::toStringList(changes).join("; ");
m_summaryLabel->setText(shortSummary.isEmpty() ? tr("No changes to apply.") : shortSummary);
}
@@ -1216,7 +1215,7 @@ private:
});
}
QLabel *m_summaryLabel;
Utils::ElidingLabel *m_summaryLabel;
QPushButton *m_manageButton;
QCheckBox *m_vslangCheckbox;
QWidget *m_mainWidget;

View File

@@ -270,6 +270,7 @@ PythonRunConfiguration::PythonRunConfiguration(Target *target, Core::Id id)
auto argumentsAspect = addAspect<ArgumentsAspect>();
addAspect<WorkingDirectoryAspect>();
addAspect<TerminalAspect>();
setCommandLineGetter([this, interpreterAspect, argumentsAspect] {
@@ -299,6 +300,9 @@ void PythonRunConfiguration::updateLanguageServer()
PyLSConfigureAssistant::instance()->openDocumentWithPython(python, document);
}
}
aspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(
Utils::FilePath::fromString(mainScript()).parentDir());
}
bool PythonRunConfiguration::supportsDebugger() const
@@ -324,7 +328,7 @@ QString PythonRunConfiguration::interpreter() const
void PythonRunConfiguration::updateTargetInformation()
{
const BuildTargetInfo bti = buildTargetInfo();
const QString script = bti.targetFilePath.toString();
const QString script = bti.targetFilePath.toUserOutput();
setDefaultDisplayName(tr("Run %1").arg(script));
aspect<MainScriptAspect>()->setValue(script);
}

View File

@@ -599,7 +599,17 @@ QMakeStepConfigWidget::QMakeStepConfigWidget(QMakeStep *step)
connect(step->qmakeBuildConfiguration(), &QmakeBuildConfiguration::qmakeBuildConfigurationChanged,
this, &QMakeStepConfigWidget::qmakeBuildConfigChanged);
connect(step->target(), &Target::kitChanged, this, &QMakeStepConfigWidget::qtVersionChanged);
connect(m_ui->abisListWidget, &QListWidget::itemChanged, this, &QMakeStepConfigWidget::abisChanged);
connect(m_ui->abisListWidget, &QListWidget::itemChanged, this, [this]{
abisChanged();
QmakeBuildConfiguration *bc = m_step->qmakeBuildConfiguration();
if (!bc)
return;
QList<ProjectExplorer::BuildStepList *> stepLists;
const Core::Id clean = ProjectExplorer::Constants::BUILDSTEPS_CLEAN;
stepLists << bc->stepList(clean);
BuildManager::buildLists(stepLists, {ProjectExplorerPlugin::displayNameForStepId(clean)});
});
auto chooser = new Core::VariableChooser(m_ui->qmakeAdditonalArgumentsLineEdit);
chooser->addMacroExpanderProvider([step] { return step->macroExpander(); });
chooser->addSupportedWidget(m_ui->qmakeAdditonalArgumentsLineEdit);

View File

@@ -139,6 +139,7 @@ extend_qtc_plugin(QmlDesigner
tokencommand.cpp tokencommand.h
valueschangedcommand.cpp valueschangedcommand.h
changeselectioncommand.cpp changeselectioncommand.h
drop3dlibraryitemcommand.cpp drop3dlibraryitemcommand.h
)
extend_qtc_plugin(QmlDesigner

View File

@@ -134,7 +134,7 @@ bool BindingEditorWidget::event(QEvent *event)
TextEditor::AssistInterface *BindingEditorWidget::createAssistInterface(
TextEditor::AssistKind assistKind, TextEditor::AssistReason assistReason) const
{
Q_UNUSED(assistKind);
Q_UNUSED(assistKind)
return new QmlJSEditor::QmlJSCompletionAssistInterface(
document(), position(), QString(),
assistReason, qmljsdocument->semanticInfo());
@@ -489,44 +489,56 @@ void BindingEditor::setModelNodeBackend(const QVariant &modelNodeBackend)
if (!modelNodeBackend.isNull() && modelNodeBackend.isValid()) {
m_modelNodeBackend = modelNodeBackend;
const auto modelNodeBackendObject = m_modelNodeBackend.value<QObject*>();
const auto backendObjectCasted =
qobject_cast<const QmlDesigner::QmlModelNodeProxy *>(modelNodeBackendObject);
if (backendObjectCasted) {
m_modelNode = backendObjectCasted->qmlObjectNode().modelNode();
}
emit modelNodeBackendChanged();
}
}
void BindingEditor::setStateModelNode(const QVariant &stateModelNode)
{
if (stateModelNode.isValid())
{
m_stateModelNode = stateModelNode;
m_modelNode = m_stateModelNode.value<QmlDesigner::ModelNode>();
if (m_modelNode.isValid())
m_backendValueTypeName = "bool";
emit stateModelNodeChanged();
}
}
void BindingEditor::prepareBindings()
{
if (m_backendValue.isNull() || m_modelNodeBackend.isNull())
if (!m_modelNode.isValid() || m_backendValueTypeName.isEmpty())
return;
if (!(m_backendValue.isValid() && m_modelNodeBackend.isValid()))
return;
const QList<QmlDesigner::ModelNode> allNodes = m_modelNode.view()->allModelNodes();
const auto modelNodeBackendObject = m_modelNodeBackend.value<QObject*>();
QList<BindingEditorDialog::BindingOption> bindings;
const auto backendObjectCasted =
qobject_cast<const QmlDesigner::QmlModelNodeProxy *>(modelNodeBackendObject);
for (auto objnode : allNodes) {
BindingEditorDialog::BindingOption binding;
for (auto propertyName : objnode.metaInfo().propertyNames())
if (m_backendValueTypeName == objnode.metaInfo().propertyTypeName(propertyName))
binding.properties.append(QString::fromUtf8(propertyName));
if (backendObjectCasted) {
const QmlDesigner::ModelNode a = backendObjectCasted->qmlObjectNode().modelNode();
const QList<QmlDesigner::ModelNode> allNodes = a.view()->allModelNodes();
QList<BindingEditorDialog::BindingOption> bindings;
for (auto objnode : allNodes) {
BindingEditorDialog::BindingOption binding;
for (auto propertyName : objnode.metaInfo().propertyNames())
if (m_backendValueTypeName == objnode.metaInfo().propertyTypeName(propertyName))
binding.properties.append(QString::fromUtf8(propertyName));
if (!binding.properties.isEmpty() && objnode.hasId()) {
binding.item = objnode.displayName();
bindings.append(binding);
}
if (!binding.properties.isEmpty() && objnode.hasId()) {
binding.item = objnode.displayName();
bindings.append(binding);
}
if (!bindings.isEmpty() && !m_dialog.isNull())
m_dialog->setAllBindings(bindings);
}
if (!bindings.isEmpty() && !m_dialog.isNull())
m_dialog->setAllBindings(bindings);
}
QVariant BindingEditor::backendValue() const
@@ -539,5 +551,10 @@ QVariant BindingEditor::modelNodeBackend() const
return m_modelNodeBackend;
}
QVariant BindingEditor::stateModelNode() const
{
return m_stateModelNode;
}
}

View File

@@ -144,6 +144,7 @@ class BindingEditor : public QObject
Q_PROPERTY(QString text READ bindingValue WRITE setBindingValue)
Q_PROPERTY(QVariant backendValueProperty READ backendValue WRITE setBackendValue NOTIFY backendValueChanged)
Q_PROPERTY(QVariant modelNodeBackendProperty READ modelNodeBackend WRITE setModelNodeBackend NOTIFY modelNodeBackendChanged)
Q_PROPERTY(QVariant stateModelNodeProperty READ stateModelNode WRITE setStateModelNode NOTIFY stateModelNodeChanged)
public:
BindingEditor(QObject *parent = nullptr);
@@ -159,6 +160,7 @@ public:
void setBackendValue(const QVariant &backendValue);
void setModelNodeBackend(const QVariant &modelNodeBackend);
void setStateModelNode(const QVariant &stateModelNode);
Q_INVOKABLE void prepareBindings();
@@ -167,15 +169,19 @@ signals:
void rejected();
void backendValueChanged();
void modelNodeBackendChanged();
void stateModelNodeChanged();
private:
QVariant backendValue() const;
QVariant modelNodeBackend() const;
QVariant stateModelNode() const;
private:
QPointer<BindingEditorDialog> m_dialog;
QVariant m_backendValue;
QVariant m_modelNodeBackend;
QVariant m_stateModelNode;
QmlDesigner::ModelNode m_modelNode;
TypeName m_backendValueTypeName;
};

View File

@@ -145,6 +145,7 @@ void PropertyEditorValue::setValueWithEmit(const QVariant &value)
emit valueChanged(nameAsQString(), value);
emit valueChangedQml();
emit isBoundChanged();
emit isExplicitChanged();
}
}
@@ -160,6 +161,8 @@ void PropertyEditorValue::setValue(const QVariant &value)
if (m_value.isValid())
emit valueChangedQml();
emit isExplicitChanged();
emit isBoundChanged();
}

Some files were not shown because too many files have changed in this diff Show More