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 * Windows 7 or later
* (K)Ubuntu Linux 16.04 (64-bit) or later * (K)Ubuntu Linux 16.04 (64-bit) or later
* macOS 10.12 or later * macOS 10.13 or later
## Contributing ## Contributing
@@ -31,6 +31,7 @@ Prerequisites:
* ActiveState Active Perl * ActiveState Active Perl
* MinGW with g++ 5.3 or Visual Studio 2017 or later * MinGW with g++ 5.3 or Visual Studio 2017 or later
* jom * jom
* Ninja (optional, needed for CMake)
* Python 3.5 or later (optional, needed for the python enabled debug helper) * Python 3.5 or later (optional, needed for the python enabled debug helper)
* On Mac OS X: latest Xcode * On Mac OS X: latest Xcode
* On Linux: g++ 5.3 or later * On Linux: g++ 5.3 or later
@@ -38,7 +39,7 @@ Prerequisites:
Clang PCH Manager and Clang Refactoring plugins, see the section 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, "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.) 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) * Qbs 1.7.x (optional, sources also contain Qbs itself)
The installed toolchains have to match the one Qt was compiled with. 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: 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 cmake \
make install -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: 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 cmake ^
jom install -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 ### 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. 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 ## Third-party Components
Qt Creator includes the following third-party components, Qt Creator includes the following third-party components,

View File

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

View File

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

View File

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

View File

@@ -27,6 +27,7 @@ HEADERS += $$PWD/changeauxiliarycommand.h
HEADERS += $$PWD/removesharedmemorycommand.h HEADERS += $$PWD/removesharedmemorycommand.h
HEADERS += $$PWD/puppetalivecommand.h HEADERS += $$PWD/puppetalivecommand.h
HEADERS += $$PWD/changeselectioncommand.h HEADERS += $$PWD/changeselectioncommand.h
HEADERS += $$PWD/drop3dlibraryitemcommand.h
SOURCES += $$PWD/synchronizecommand.cpp SOURCES += $$PWD/synchronizecommand.cpp
SOURCES += $$PWD/debugoutputcommand.cpp SOURCES += $$PWD/debugoutputcommand.cpp
@@ -55,3 +56,4 @@ SOURCES += $$PWD/changeauxiliarycommand.cpp
SOURCES += $$PWD/removesharedmemorycommand.cpp SOURCES += $$PWD/removesharedmemorycommand.cpp
SOURCES += $$PWD/puppetalivecommand.cpp SOURCES += $$PWD/puppetalivecommand.cpp
SOURCES += $$PWD/changeselectioncommand.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 "debugoutputcommand.h"
#include "puppetalivecommand.h" #include "puppetalivecommand.h"
#include "changeselectioncommand.h" #include "changeselectioncommand.h"
#include "drop3dlibraryitemcommand.h"
namespace QmlDesigner { namespace QmlDesigner {
@@ -139,6 +140,7 @@ bool compareCommands(const QVariant &command, const QVariant &controlCommand)
static const int tokenCommandType = QMetaType::type("TokenCommand"); static const int tokenCommandType = QMetaType::type("TokenCommand");
static const int debugOutputCommandType = QMetaType::type("DebugOutputCommand"); static const int debugOutputCommandType = QMetaType::type("DebugOutputCommand");
static const int changeSelectionCommandType = QMetaType::type("ChangeSelectionCommand"); static const int changeSelectionCommandType = QMetaType::type("ChangeSelectionCommand");
static const int drop3DLibraryItemCommandType = QMetaType::type("Drop3DLibraryItemCommand");
if (command.userType() == controlCommand.userType()) { if (command.userType() == controlCommand.userType()) {
if (command.userType() == informationChangedCommandType) if (command.userType() == informationChangedCommandType)
@@ -163,6 +165,8 @@ bool compareCommands(const QVariant &command, const QVariant &controlCommand)
return command.value<DebugOutputCommand>() == controlCommand.value<DebugOutputCommand>(); return command.value<DebugOutputCommand>() == controlCommand.value<DebugOutputCommand>();
else if (command.userType() == changeSelectionCommandType) else if (command.userType() == changeSelectionCommandType)
return command.value<ChangeSelectionCommand>() == controlCommand.value<ChangeSelectionCommand>(); return command.value<ChangeSelectionCommand>() == controlCommand.value<ChangeSelectionCommand>();
else if (command.userType() == drop3DLibraryItemCommandType)
return command.value<Drop3DLibraryItemCommand>() == controlCommand.value<Drop3DLibraryItemCommand>();
} }
return false; return false;
@@ -250,6 +254,11 @@ void NodeInstanceClientProxy::selectionChanged(const ChangeSelectionCommand &com
writeCommand(QVariant::fromValue(command)); writeCommand(QVariant::fromValue(command));
} }
void NodeInstanceClientProxy::library3DItemDropped(const Drop3DLibraryItemCommand &command)
{
writeCommand(QVariant::fromValue(command));
}
void NodeInstanceClientProxy::flush() void NodeInstanceClientProxy::flush()
{ {
} }

View File

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

View File

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

View File

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

View File

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

View File

@@ -66,9 +66,11 @@ Window {
var component = Qt.createComponent("LightGizmo.qml"); var component = Qt.createComponent("LightGizmo.qml");
if (component.status === Component.Ready) { if (component.status === Component.Ready) {
var gizmo = component.createObject(overlayScene, var gizmo = component.createObject(overlayScene,
{"view3D": overlayView, "targetNode": obj}); {"view3D": overlayView, "targetNode": obj,
"selectedNode": selectedNode});
lightGizmos[lightGizmos.length] = gizmo; 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( var gizmo = component.createObject(
overlayScene, overlayScene,
{"view3D": overlayView, "targetNode": obj, "geometryName": geometryName, {"view3D": overlayView, "targetNode": obj, "geometryName": geometryName,
"viewPortRect": viewPortRect}); "viewPortRect": viewPortRect, "selectedNode": selectedNode});
cameraGizmos[cameraGizmos.length] = gizmo; cameraGizmos[cameraGizmos.length] = gizmo;
gizmo.selected.connect(emitObjectClicked); gizmo.clicked.connect(emitObjectClicked);
gizmo.viewPortRect = Qt.binding(function() {return viewPortRect;}); gizmo.viewPortRect = Qt.binding(function() {return viewPortRect;});
gizmo.selectedNode = Qt.binding(function() {return selectedNode;});
} }
} }
@@ -100,12 +103,15 @@ Window {
PerspectiveCamera { PerspectiveCamera {
id: overlayPerspectiveCamera id: overlayPerspectiveCamera
clipFar: editPerspectiveCamera.clipFar clipFar: editPerspectiveCamera.clipFar
clipNear: editPerspectiveCamera.clipNear
position: editPerspectiveCamera.position position: editPerspectiveCamera.position
rotation: editPerspectiveCamera.rotation rotation: editPerspectiveCamera.rotation
} }
OrthographicCamera { OrthographicCamera {
id: overlayOrthoCamera id: overlayOrthoCamera
clipFar: editOrthoCamera.clipFar
clipNear: editOrthoCamera.clipNear
position: editOrthoCamera.position position: editOrthoCamera.position
rotation: editOrthoCamera.rotation rotation: editOrthoCamera.rotation
} }
@@ -118,7 +124,7 @@ Window {
position: viewWindow.selectedNode ? viewWindow.selectedNode.scenePosition position: viewWindow.selectedNode ? viewWindow.selectedNode.scenePosition
: Qt.vector3d(0, 0, 0) : Qt.vector3d(0, 0, 0)
globalOrientation: globalControl.checked globalOrientation: globalControl.checked
visible: selectedNode && moveToolControl.checked visible: selectedNode && btnMove.selected
view3D: overlayView view3D: overlayView
onPositionCommit: viewWindow.commitObjectProperty(selectedNode, "position") onPositionCommit: viewWindow.commitObjectProperty(selectedNode, "position")
@@ -133,13 +139,28 @@ Window {
position: viewWindow.selectedNode ? viewWindow.selectedNode.scenePosition position: viewWindow.selectedNode ? viewWindow.selectedNode.scenePosition
: Qt.vector3d(0, 0, 0) : Qt.vector3d(0, 0, 0)
globalOrientation: globalControl.checked globalOrientation: globalControl.checked
visible: selectedNode && scaleToolControl.checked visible: selectedNode && btnScale.selected
view3D: overlayView view3D: overlayView
onScaleCommit: viewWindow.commitObjectProperty(selectedNode, "scale") onScaleCommit: viewWindow.commitObjectProperty(selectedNode, "scale")
onScaleChange: viewWindow.changeObjectProperty(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 { AutoScaleHelper {
id: autoScale id: autoScale
view3D: overlayView view3D: overlayView
@@ -161,6 +182,10 @@ Window {
} }
} }
DropArea {
anchors.fill: parent
}
View3D { View3D {
id: editView id: editView
anchors.fill: parent anchors.fill: parent
@@ -169,10 +194,10 @@ Window {
Node { Node {
id: mainSceneHelpers id: mainSceneHelpers
AxisHelper { HelperGrid {
id: axisGrid id: helperGrid
enableXZGrid: true lines: 50
enableAxisLines: false step: 50
} }
PointLight { PointLight {
@@ -186,15 +211,20 @@ Window {
PerspectiveCamera { PerspectiveCamera {
id: editPerspectiveCamera id: editPerspectiveCamera
z: -600
y: 200 y: 200
z: -300 rotation.x: 30
clipFar: 100000 clipFar: 100000
clipNear: 1
} }
OrthographicCamera { OrthographicCamera {
id: editOrthoCamera id: editOrthoCamera
z: -600
y: 200 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 { Column {
y: 8 y: 8
anchors.right: parent.right
CheckBox { CheckBox {
id: editLightCheckbox id: editLightCheckbox
checked: false checked: false
@@ -272,7 +372,19 @@ Window {
id: usePerspectiveCheckbox id: usePerspectiveCheckbox
checked: true checked: true
text: qsTr("Use Perspective Projection") 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 { CheckBox {
@@ -281,19 +393,6 @@ Window {
text: qsTr("Use Global Orientation") text: qsTr("Use Global Orientation")
onCheckedChanged: cameraControl.forceActiveFocus() 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 { 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 View3D view3D
property bool highlightOnHover: true property bool highlightOnHover: true
property Node targetNode: null property Node targetNode: null
property Node selectedNode: null
property alias gizmoModel: gizmoModel property alias gizmoModel: gizmoModel
property alias iconSource: iconImage.source property alias iconSource: iconImage.source
signal positionCommit() signal positionCommit()
signal selected(Node node) signal clicked(Node node)
position: targetNode ? targetNode.scenePosition : Qt.vector3d(0, 0, 0) position: targetNode ? targetNode.scenePosition : Qt.vector3d(0, 0, 0)
rotation: targetNode ? targetNode.sceneRotation : Qt.vector3d(0, 0, 0) rotation: targetNode ? targetNode.sceneRotation : Qt.vector3d(0, 0, 0)
@@ -57,22 +58,27 @@ Node {
parent: view3D parent: view3D
Rectangle { Rectangle {
width: 24 width: iconImage.width
height: 24 height: iconImage.height
x: -width / 2 x: -width / 2
y: -height y: -height
color: "transparent" color: "transparent"
border.color: "#7777ff" border.color: "#7777ff"
border.width: highlightOnHover && iconMouseArea.containsMouse ? 2 : 0 border.width: iconGizmo.selectedNode === iconGizmo.targetNode
|| (iconGizmo.highlightOnHover && iconMouseArea.containsMouse) ? 2 : 0
radius: 5 radius: 5
opacity: iconGizmo.selectedNode === iconGizmo.targetNode ? 0.3 : 1
Image { Image {
id: iconImage id: iconImage
anchors.fill: parent fillMode: Image.Pad
MouseArea { MouseArea {
id: iconMouseArea id: iconMouseArea
anchors.fill: parent anchors.fill: parent
onClicked: selected(targetNode) onClicked: iconGizmo.clicked(iconGizmo.targetNode)
hoverEnabled: highlightOnHover 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 \ HEADERS += $$PWD/cameracontrolhelper.h \
$$PWD/mousearea3d.h \ $$PWD/mousearea3d.h \
$$PWD/camerageometry.h $$PWD/camerageometry.h \
$$PWD/gridgeometry.h
SOURCES += $$PWD/cameracontrolhelper.cpp \ SOURCES += $$PWD/cameracontrolhelper.cpp \
$$PWD/mousearea3d.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 <QtGui/qguiapplication.h>
#include <QtQml/qqmlinfo.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 QmlDesigner {
namespace Internal { namespace Internal {
MouseArea3D *MouseArea3D::s_mouseGrab = nullptr; MouseArea3D *MouseArea3D::s_mouseGrab = nullptr;
static const qreal s_mouseDragMultiplier = .02;
MouseArea3D::MouseArea3D(QQuick3DNode *parent) MouseArea3D::MouseArea3D(QQuick3DNode *parent)
: QQuick3DNode(parent) : QQuick3DNode(parent)
@@ -65,6 +69,21 @@ bool MouseArea3D::active() const
return m_active; 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 qreal MouseArea3D::x() const
{ {
return m_x; return m_x;
@@ -105,7 +124,7 @@ void MouseArea3D::setGrabsMouse(bool grabsMouse)
return; return;
m_grabsMouse = grabsMouse; m_grabsMouse = grabsMouse;
emit grabsMouseChanged(grabsMouse); emit grabsMouseChanged();
} }
void MouseArea3D::setActive(bool active) void MouseArea3D::setActive(bool active)
@@ -114,7 +133,37 @@ void MouseArea3D::setActive(bool active)
return; return;
m_active = active; 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) void MouseArea3D::setX(qreal x)
@@ -123,7 +172,7 @@ void MouseArea3D::setX(qreal x)
return; return;
m_x = x; m_x = x;
emit xChanged(x); emit xChanged();
} }
void MouseArea3D::setY(qreal y) void MouseArea3D::setY(qreal y)
@@ -132,7 +181,7 @@ void MouseArea3D::setY(qreal y)
return; return;
m_y = y; m_y = y;
emit yChanged(y); emit yChanged();
} }
void MouseArea3D::setWidth(qreal width) void MouseArea3D::setWidth(qreal width)
@@ -141,7 +190,7 @@ void MouseArea3D::setWidth(qreal width)
return; return;
m_width = width; m_width = width;
emit widthChanged(width); emit widthChanged();
} }
void MouseArea3D::setHeight(qreal height) void MouseArea3D::setHeight(qreal height)
@@ -150,7 +199,7 @@ void MouseArea3D::setHeight(qreal height)
return; return;
m_height = height; m_height = height;
emit heightChanged(height); emit heightChanged();
} }
void MouseArea3D::setPriority(int level) void MouseArea3D::setPriority(int level)
@@ -159,7 +208,7 @@ void MouseArea3D::setPriority(int level)
return; return;
m_priority = level; m_priority = level;
emit priorityChanged(level); emit priorityChanged();
} }
void MouseArea3D::componentComplete() void MouseArea3D::componentComplete()
@@ -278,6 +327,84 @@ QVector3D MouseArea3D::getNewScale(QQuick3DNode *node, const QVector3D &startSca
return startScale; 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 QVector3D MouseArea3D::getMousePosInPlane(const QPointF &mousePosInView) const
{ {
const QVector3D mousePos1(float(mousePosInView.x()), float(mousePosInView.y()), 0); const QVector3D mousePos1(float(mousePosInView.x()), float(mousePosInView.y()), 0);
@@ -300,12 +427,50 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
return false; return false;
} }
auto mouseOnTopOfMouseArea = [this](const QVector3D &mousePosInPlane) -> bool { qreal pickAngle = 0.;
return !qFuzzyCompare(mousePosInPlane.z(), -1)
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)
&& mousePosInPlane.x() <= float(m_x + m_width) && mousePosInPlane.x() <= float(m_x + m_width)
&& mousePosInPlane.y() >= float(m_y) && mousePosInPlane.y() >= float(m_y)
&& mousePosInPlane.y() <= float(m_y + m_height); && 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()) { switch (event->type()) {
@@ -313,9 +478,9 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
auto const mouseEvent = static_cast<QMouseEvent *>(event); auto const mouseEvent = static_cast<QMouseEvent *>(event);
if (mouseEvent->button() == Qt::LeftButton) { if (mouseEvent->button() == Qt::LeftButton) {
m_mousePosInPlane = getMousePosInPlane(mouseEvent->pos()); m_mousePosInPlane = getMousePosInPlane(mouseEvent->pos());
if (mouseOnTopOfMouseArea(m_mousePosInPlane)) { if (mouseOnTopOfMouseArea(m_mousePosInPlane, mouseEvent->pos())) {
setDragging(true); setDragging(true);
emit pressed(m_mousePosInPlane, mouseEvent->globalPos()); emit pressed(m_mousePosInPlane, mouseEvent->pos(), pickAngle);
if (m_grabsMouse) { if (m_grabsMouse) {
if (s_mouseGrab && s_mouseGrab != this) { if (s_mouseGrab && s_mouseGrab != this) {
s_mouseGrab->setDragging(false); s_mouseGrab->setDragging(false);
@@ -338,13 +503,13 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
if (qFuzzyCompare(mousePosInPlane.z(), -1)) if (qFuzzyCompare(mousePosInPlane.z(), -1))
mousePosInPlane = m_mousePosInPlane; mousePosInPlane = m_mousePosInPlane;
setDragging(false); setDragging(false);
emit released(mousePosInPlane, mouseEvent->globalPos()); emit released(mousePosInPlane, mouseEvent->pos());
if (m_grabsMouse) { if (m_grabsMouse) {
if (s_mouseGrab && s_mouseGrab != this) { if (s_mouseGrab && s_mouseGrab != this) {
s_mouseGrab->setDragging(false); s_mouseGrab->setDragging(false);
s_mouseGrab->setHovering(false); s_mouseGrab->setHovering(false);
} }
if (mouseOnTopOfMouseArea(mousePosInPlane)) { if (mouseOnTopOfMouseArea(mousePosInPlane, mouseEvent->pos())) {
s_mouseGrab = this; s_mouseGrab = this;
setHovering(true); setHovering(true);
} else { } else {
@@ -362,7 +527,7 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
case QEvent::HoverMove: { case QEvent::HoverMove: {
auto const mouseEvent = static_cast<QMouseEvent *>(event); auto const mouseEvent = static_cast<QMouseEvent *>(event);
const QVector3D mousePosInPlane = getMousePosInPlane(mouseEvent->pos()); const QVector3D mousePosInPlane = getMousePosInPlane(mouseEvent->pos());
const bool hasMouse = mouseOnTopOfMouseArea(mousePosInPlane); const bool hasMouse = mouseOnTopOfMouseArea(mousePosInPlane, mouseEvent->pos());
setHovering(hasMouse); setHovering(hasMouse);
@@ -376,9 +541,9 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
s_mouseGrab = nullptr; s_mouseGrab = nullptr;
} }
if (m_dragging && !qFuzzyCompare(mousePosInPlane.z(), -1)) { if (m_dragging && (m_circlePickArea.y() > 0. || !qFuzzyCompare(mousePosInPlane.z(), -1))) {
m_mousePosInPlane = mousePosInPlane; m_mousePosInPlane = mousePosInPlane;
emit dragged(mousePosInPlane, mouseEvent->globalPos()); emit dragged(mousePosInPlane, mouseEvent->pos());
} }
break; break;
@@ -408,6 +573,25 @@ void MouseArea3D::setHovering(bool enable)
emit hoveringChanged(); 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 #ifdef QUICK3D_MODULE
#include <QtGui/qvector3d.h> #include <QtGui/qvector3d.h>
#include <QtCore/qpoint.h>
#include <QtCore/qpointer.h> #include <QtCore/qpointer.h>
#include <QtQuick3D/private/qquick3dnode_p.h> #include <QtQuick3D/private/qquick3dnode_p.h>
#include <QtQuick3D/private/qquick3dmodel_p.h>
#include <QtQuick3D/private/qquick3dviewport_p.h> #include <QtQuick3D/private/qquick3dviewport_p.h>
#include <QtQuick3D/private/qtquick3dglobal_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(bool dragging READ dragging NOTIFY draggingChanged)
Q_PROPERTY(int priority READ priority WRITE setPriority NOTIFY priorityChanged) Q_PROPERTY(int priority READ priority WRITE setPriority NOTIFY priorityChanged)
Q_PROPERTY(int active READ active WRITE setActive NOTIFY activeChanged) 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) Q_INTERFACES(QQmlParserStatus)
@@ -68,11 +73,17 @@ public:
bool dragging() const; bool dragging() const;
bool grabsMouse() const; bool grabsMouse() const;
bool active() const; bool active() const;
QPointF circlePickArea() const;
qreal minAngle() const;
QQuick3DNode *pickNode() const;
public slots: public slots:
void setView3D(QQuick3DViewport *view3D); void setView3D(QQuick3DViewport *view3D);
void setGrabsMouse(bool grabsMouse); void setGrabsMouse(bool grabsMouse);
void setActive(bool active); void setActive(bool active);
void setCirclePickArea(const QPointF &pickArea);
void setMinAngle(qreal angle);
void setPickNode(QQuick3DNode *node);
void setX(qreal x); void setX(qreal x);
void setY(qreal y); void setY(qreal y);
@@ -89,22 +100,35 @@ public slots:
const QVector3D &pressPos, const QVector3D &pressPos,
const QVector3D &sceneRelativeDistance, bool global); 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: signals:
void view3DChanged(); void view3DChanged();
void xChanged(qreal x); void xChanged();
void yChanged(qreal y); void yChanged();
void widthChanged(qreal width); void widthChanged();
void heightChanged(qreal height); void heightChanged();
void priorityChanged(int level); void priorityChanged();
void hoveringChanged(); void hoveringChanged();
void draggingChanged(); void draggingChanged();
void activeChanged(bool active); void activeChanged();
void pressed(const QVector3D &scenePos, const QPoint &screenPos); 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 released(const QVector3D &scenePos, const QPoint &screenPos);
void dragged(const QVector3D &scenePos, const QPoint &screenPos); void dragged(const QVector3D &scenePos, const QPoint &screenPos);
void grabsMouseChanged(bool grabsMouse);
protected: protected:
void classBegin() override {} void classBegin() override {}
@@ -114,6 +138,8 @@ protected:
private: private:
void setDragging(bool enable); void setDragging(bool enable);
void setHovering(bool enable); void setHovering(bool enable);
QVector3D getNormal() const;
QVector3D getCameraToNodeDir(QQuick3DNode *node) const;
Q_DISABLE_COPY(MouseArea3D) Q_DISABLE_COPY(MouseArea3D)
QQuick3DViewport *m_view3D = nullptr; QQuick3DViewport *m_view3D = nullptr;
@@ -133,6 +159,9 @@ private:
static MouseArea3D *s_mouseGrab; static MouseArea3D *s_mouseGrab;
bool m_grabsMouse; bool m_grabsMouse;
QVector3D m_mousePosInPlane; QVector3D m_mousePosInPlane;
QPointF m_circlePickArea;
qreal m_minAngle = 0.;
QQuick3DNode *m_pickNode = nullptr;
}; };
} }

View File

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

View File

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

View File

@@ -27,6 +27,8 @@
#include <QQuickItem> #include <QQuickItem>
#include <QQuickView> #include <QQuickView>
#include <QDropEvent>
#include <QMimeData>
#include "servernodeinstance.h" #include "servernodeinstance.h"
#include "childrenchangeeventfilter.h" #include "childrenchangeeventfilter.h"
@@ -57,11 +59,13 @@
#include "removesharedmemorycommand.h" #include "removesharedmemorycommand.h"
#include "changeselectioncommand.h" #include "changeselectioncommand.h"
#include "objectnodeinstance.h" #include "objectnodeinstance.h"
#include <drop3dlibraryitemcommand.h>
#include "dummycontextobject.h" #include "dummycontextobject.h"
#include "../editor3d/cameracontrolhelper.h" #include "../editor3d/cameracontrolhelper.h"
#include "../editor3d/mousearea3d.h" #include "../editor3d/mousearea3d.h"
#include "../editor3d/camerageometry.h" #include "../editor3d/camerageometry.h"
#include "../editor3d/gridgeometry.h"
#include <designersupportdelegate.h> #include <designersupportdelegate.h>
@@ -79,6 +83,25 @@ static QVariant objectToVariant(QObject *object)
return QVariant::fromValue(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) QObject *Qt5InformationNodeInstanceServer::createEditView3D(QQmlEngine *engine)
{ {
auto helper = new QmlDesigner::Internal::CameraControlHelper(); auto helper = new QmlDesigner::Internal::CameraControlHelper();
@@ -87,6 +110,7 @@ QObject *Qt5InformationNodeInstanceServer::createEditView3D(QQmlEngine *engine)
#ifdef QUICK3D_MODULE #ifdef QUICK3D_MODULE
qmlRegisterType<QmlDesigner::Internal::MouseArea3D>("MouseArea3D", 1, 0, "MouseArea3D"); qmlRegisterType<QmlDesigner::Internal::MouseArea3D>("MouseArea3D", 1, 0, "MouseArea3D");
qmlRegisterType<QmlDesigner::Internal::CameraGeometry>("CameraGeometry", 1, 0, "CameraGeometry"); qmlRegisterType<QmlDesigner::Internal::CameraGeometry>("CameraGeometry", 1, 0, "CameraGeometry");
qmlRegisterType<QmlDesigner::Internal::GridGeometry>("GridGeometry", 1, 0, "GridGeometry");
#endif #endif
QQmlComponent component(engine, QUrl("qrc:/qtquickplugin/mockfiles/EditView3D.qml")); QQmlComponent component(engine, QUrl("qrc:/qtquickplugin/mockfiles/EditView3D.qml"));
@@ -98,6 +122,7 @@ QObject *Qt5InformationNodeInstanceServer::createEditView3D(QQmlEngine *engine)
return nullptr; return nullptr;
} }
window->installEventFilter(this);
QObject::connect(window, SIGNAL(objectClicked(QVariant)), this, SLOT(objectClicked(QVariant))); QObject::connect(window, SIGNAL(objectClicked(QVariant)), this, SLOT(objectClicked(QVariant)));
QObject::connect(window, SIGNAL(commitObjectProperty(QVariant, QVariant)), QObject::connect(window, SIGNAL(commitObjectProperty(QVariant, QVariant)),
this, SLOT(handleObjectPropertyCommit(QVariant, QVariant))); this, SLOT(handleObjectPropertyCommit(QVariant, QVariant)));

View File

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

View File

@@ -15,17 +15,43 @@
<file>mockfiles/LightGizmo.qml</file> <file>mockfiles/LightGizmo.qml</file>
<file>mockfiles/IconGizmo.qml</file> <file>mockfiles/IconGizmo.qml</file>
<file>mockfiles/Overlay2D.qml</file> <file>mockfiles/Overlay2D.qml</file>
<file>mockfiles/HelperGrid.qml</file>
<file>mockfiles/DirectionalDraggable.qml</file> <file>mockfiles/DirectionalDraggable.qml</file>
<file>mockfiles/PlanarDraggable.qml</file> <file>mockfiles/PlanarDraggable.qml</file>
<file>mockfiles/PlanarMoveHandle.qml</file> <file>mockfiles/PlanarMoveHandle.qml</file>
<file>mockfiles/PlanarScaleHandle.qml</file> <file>mockfiles/PlanarScaleHandle.qml</file>
<file>mockfiles/ScaleRod.qml</file> <file>mockfiles/ScaleRod.qml</file>
<file>mockfiles/ScaleGizmo.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/arrow.mesh</file>
<file>mockfiles/meshes/scalerod.mesh</file> <file>mockfiles/meshes/scalerod.mesh</file>
<file>mockfiles/images/camera-pick-icon.png</file> <file>mockfiles/meshes/ring.mesh</file>
<file>mockfiles/images/camera-pick-icon@2x.png</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.png</file>
<file>mockfiles/images/light-pick-icon@2x.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> </qresource>
</RCC> </RCC>

View File

@@ -32,8 +32,7 @@ Column {
anchors.right: parent.right anchors.right: parent.right
StandardTextSection { StandardTextSection {
showIsWrapping: true showVerticalAlignment: true
useLineEdit: true
showFormatProperty: 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 { FontSection {
showStyle: false showStyle: false
} }

View File

@@ -39,6 +39,16 @@ Section {
rows: 4 rows: 4
columns: 2 columns: 2
Label {
text: qsTr("Mouse selection mode")
}
ComboBox {
Layout.fillWidth: true
backendValue: backendValues.mouseSelectionMode
scope: "TextInput"
model: ["SelectCharacters", "SelectWords"]
}
Label { Label {
visible: textInputSection.isTextInput visible: textInputSection.isTextInput
text: qsTr("Input mask") text: qsTr("Input mask")
@@ -48,6 +58,7 @@ Section {
visible: textInputSection.isTextInput visible: textInputSection.isTextInput
backendValue: backendValues.inputMask backendValue: backendValues.inputMask
Layout.fillWidth: true Layout.fillWidth: true
showTranslateCheckBox: false
} }
Label { Label {
@@ -73,6 +84,33 @@ Section {
visible: textInputSection.isTextInput visible: textInputSection.isTextInput
backendValue: backendValues.passwordCharacter backendValue: backendValues.passwordCharacter
Layout.fillWidth: true 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 { Label {
@@ -101,10 +139,36 @@ Section {
} }
CheckBox { CheckBox {
visible: textInputSection.isTextInput
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Auto scroll") text: qsTr("Auto scroll")
backendValue: backendValues.autoScroll 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 anchors.right: parent.right
StandardTextSection { StandardTextSection {
useLineEdit: false showVerticalAlignment: true
showIsWrapping: false
} }
Section { 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 { FontSection {
showStyle: false showStyle: false
} }

View File

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

View File

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

View File

@@ -114,6 +114,7 @@ Rectangle {
var y = root.mapToGlobal(0,0).y - 32 var y = root.mapToGlobal(0,0).y - 32
bindingEditor.showWidget(x, y) bindingEditor.showWidget(x, y)
bindingEditor.text = delegateWhenConditionString bindingEditor.text = delegateWhenConditionString
bindingEditor.prepareBindings()
} }
} }
@@ -205,6 +206,8 @@ Rectangle {
id: bindingEditor id: bindingEditor
stateModelNodeProperty: statesEditorModel.stateModelNode()
onRejected: { onRejected: {
hideWidget() 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", "trDisplayName": "Project Management",
"trShortTitle": "Summary", "trShortTitle": "Summary",
@@ -84,7 +94,8 @@
}, },
{ {
"source": "plugin.cpp", "source": "plugin.cpp",
"target": "%{PluginSrc}" "target": "%{PluginSrc}",
"openInEditor": true
}, },
{ {
"source": "plugin.h", "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) void AndroidConfigurations::setConfig(const AndroidConfig &devConfigs)
{ {
emit m_instance->aboutToUpdate();
m_instance->m_config = devConfigs; m_instance->m_config = devConfigs;
m_instance->save(); m_instance->save();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -34,7 +34,8 @@ namespace GTestUtils {
static const QStringList valid = { static const QStringList valid = {
QStringLiteral("TEST"), QStringLiteral("TEST_F"), QStringLiteral("TEST_P"), 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) bool isGTestMacro(const QString &macro)

View File

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

View File

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

View File

@@ -315,15 +315,11 @@ static ::Utils::FilePath compilerPath(const CppTools::ProjectPart &projectPart)
static ::Utils::FilePath buildDirectory(const ProjectExplorer::Project &project) static ::Utils::FilePath buildDirectory(const ProjectExplorer::Project &project)
{ {
ProjectExplorer::Target *target = project.activeTarget(); if (auto *target = project.activeTarget()) {
if (!target) if (auto *bc = target->activeBuildConfiguration())
return ::Utils::FilePath(); return bc->buildDirectory();
}
ProjectExplorer::BuildConfiguration *buildConfig = target->activeBuildConfiguration(); return {};
if (!buildConfig)
return ::Utils::FilePath();
return buildConfig->buildDirectory();
} }
static QStringList projectPartArguments(const ProjectPart &projectPart) 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); QString msg = tr("%1: Not all files could be analyzed.").arg(toolName);
TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID); TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
Target *target = runControl()->target(); Target *target = runControl()->target();
if (target && !target->activeBuildConfiguration()->buildDirectory().exists() if (target && target->activeBuildConfiguration() && !target->activeBuildConfiguration()->buildDirectory().exists()
&& !m_runSettings.buildBeforeAnalysis()) { && !m_runSettings.buildBeforeAnalysis()) {
msg = tr("%1: You might need to build the project to generate or update source " 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 " "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. // Test that tidy and clazy diagnostics are emitted for the same project.
addTestRow("clangtidy_clazy/clangtidy_clazy.pro", addTestRow("clangtidy_clazy/clangtidy_clazy.pro",
1 /*tidy*/ + 1 /*clazy*/, 1 /*tidy*/ + 1 /*clazy*/,
configFor("misc-unconventional-assign-operator", "base-class-event")); configFor("misc-unconventional-assign-operator", "qgetenv"));
} }
void ClangToolsUnitTests::addTestRow(const QByteArray &relativeFilePath, void ClangToolsUnitTests::addTestRow(const QByteArray &relativeFilePath,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -126,7 +126,7 @@ private:
}; };
void readInformation(QueryType type) const; 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); void parseFunctionDetailsOutput(const QString &output);
QStringList parseVariableOutput(const QString &output); QStringList parseVariableOutput(const QString &output);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -51,7 +51,7 @@ static CommandLine flashAndRunCommand(Target *target)
// TODO: Hack! Implement flash target name handling, properly // TODO: Hack! Implement flash target name handling, properly
const QString targetName = 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").arg(projectName)
: QString("flash_%1_and_bootloader").arg(projectName); : QString("flash_%1_and_bootloader").arg(projectName);

View File

@@ -51,6 +51,11 @@
"source": "main.qml.tpl", "source": "main.qml.tpl",
"target": "%{ProjectDirectory}/%{MainQmlFile}", "target": "%{ProjectDirectory}/%{MainQmlFile}",
"openInEditor": true "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()); ui->kitChooser->setCurrentKitId(target->kit()->id());
ProjectExplorer::BuildConfiguration *buildConfig = target->activeBuildConfiguration(); if (auto *bc = target->activeBuildConfiguration())
if (!buildConfig) ui->executableDirLineEdit->setText(bc->buildDirectory().toString());
return;
ui->executableDirLineEdit->setText(buildConfig->buildDirectory().toString());
} }
} // namespace Internal } // namespace Internal

View File

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

View File

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

View File

@@ -599,7 +599,17 @@ QMakeStepConfigWidget::QMakeStepConfigWidget(QMakeStep *step)
connect(step->qmakeBuildConfiguration(), &QmakeBuildConfiguration::qmakeBuildConfigurationChanged, connect(step->qmakeBuildConfiguration(), &QmakeBuildConfiguration::qmakeBuildConfigurationChanged,
this, &QMakeStepConfigWidget::qmakeBuildConfigChanged); this, &QMakeStepConfigWidget::qmakeBuildConfigChanged);
connect(step->target(), &Target::kitChanged, this, &QMakeStepConfigWidget::qtVersionChanged); 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); auto chooser = new Core::VariableChooser(m_ui->qmakeAdditonalArgumentsLineEdit);
chooser->addMacroExpanderProvider([step] { return step->macroExpander(); }); chooser->addMacroExpanderProvider([step] { return step->macroExpander(); });
chooser->addSupportedWidget(m_ui->qmakeAdditonalArgumentsLineEdit); chooser->addSupportedWidget(m_ui->qmakeAdditonalArgumentsLineEdit);

View File

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

View File

@@ -134,7 +134,7 @@ bool BindingEditorWidget::event(QEvent *event)
TextEditor::AssistInterface *BindingEditorWidget::createAssistInterface( TextEditor::AssistInterface *BindingEditorWidget::createAssistInterface(
TextEditor::AssistKind assistKind, TextEditor::AssistReason assistReason) const TextEditor::AssistKind assistKind, TextEditor::AssistReason assistReason) const
{ {
Q_UNUSED(assistKind); Q_UNUSED(assistKind)
return new QmlJSEditor::QmlJSCompletionAssistInterface( return new QmlJSEditor::QmlJSCompletionAssistInterface(
document(), position(), QString(), document(), position(), QString(),
assistReason, qmljsdocument->semanticInfo()); assistReason, qmljsdocument->semanticInfo());
@@ -489,44 +489,56 @@ void BindingEditor::setModelNodeBackend(const QVariant &modelNodeBackend)
if (!modelNodeBackend.isNull() && modelNodeBackend.isValid()) { if (!modelNodeBackend.isNull() && modelNodeBackend.isValid()) {
m_modelNodeBackend = modelNodeBackend; 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(); 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() void BindingEditor::prepareBindings()
{ {
if (m_backendValue.isNull() || m_modelNodeBackend.isNull()) if (!m_modelNode.isValid() || m_backendValueTypeName.isEmpty())
return; return;
if (!(m_backendValue.isValid() && m_modelNodeBackend.isValid())) const QList<QmlDesigner::ModelNode> allNodes = m_modelNode.view()->allModelNodes();
return;
const auto modelNodeBackendObject = m_modelNodeBackend.value<QObject*>(); QList<BindingEditorDialog::BindingOption> bindings;
const auto backendObjectCasted = for (auto objnode : allNodes) {
qobject_cast<const QmlDesigner::QmlModelNodeProxy *>(modelNodeBackendObject); BindingEditorDialog::BindingOption binding;
for (auto propertyName : objnode.metaInfo().propertyNames())
if (m_backendValueTypeName == objnode.metaInfo().propertyTypeName(propertyName))
binding.properties.append(QString::fromUtf8(propertyName));
if (backendObjectCasted) { if (!binding.properties.isEmpty() && objnode.hasId()) {
const QmlDesigner::ModelNode a = backendObjectCasted->qmlObjectNode().modelNode(); binding.item = objnode.displayName();
const QList<QmlDesigner::ModelNode> allNodes = a.view()->allModelNodes(); bindings.append(binding);
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 (!bindings.isEmpty() && !m_dialog.isNull())
m_dialog->setAllBindings(bindings);
} }
if (!bindings.isEmpty() && !m_dialog.isNull())
m_dialog->setAllBindings(bindings);
} }
QVariant BindingEditor::backendValue() const QVariant BindingEditor::backendValue() const
@@ -539,5 +551,10 @@ QVariant BindingEditor::modelNodeBackend() const
return m_modelNodeBackend; 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(QString text READ bindingValue WRITE setBindingValue)
Q_PROPERTY(QVariant backendValueProperty READ backendValue WRITE setBackendValue NOTIFY backendValueChanged) Q_PROPERTY(QVariant backendValueProperty READ backendValue WRITE setBackendValue NOTIFY backendValueChanged)
Q_PROPERTY(QVariant modelNodeBackendProperty READ modelNodeBackend WRITE setModelNodeBackend NOTIFY modelNodeBackendChanged) Q_PROPERTY(QVariant modelNodeBackendProperty READ modelNodeBackend WRITE setModelNodeBackend NOTIFY modelNodeBackendChanged)
Q_PROPERTY(QVariant stateModelNodeProperty READ stateModelNode WRITE setStateModelNode NOTIFY stateModelNodeChanged)
public: public:
BindingEditor(QObject *parent = nullptr); BindingEditor(QObject *parent = nullptr);
@@ -159,6 +160,7 @@ public:
void setBackendValue(const QVariant &backendValue); void setBackendValue(const QVariant &backendValue);
void setModelNodeBackend(const QVariant &modelNodeBackend); void setModelNodeBackend(const QVariant &modelNodeBackend);
void setStateModelNode(const QVariant &stateModelNode);
Q_INVOKABLE void prepareBindings(); Q_INVOKABLE void prepareBindings();
@@ -167,15 +169,19 @@ signals:
void rejected(); void rejected();
void backendValueChanged(); void backendValueChanged();
void modelNodeBackendChanged(); void modelNodeBackendChanged();
void stateModelNodeChanged();
private: private:
QVariant backendValue() const; QVariant backendValue() const;
QVariant modelNodeBackend() const; QVariant modelNodeBackend() const;
QVariant stateModelNode() const;
private: private:
QPointer<BindingEditorDialog> m_dialog; QPointer<BindingEditorDialog> m_dialog;
QVariant m_backendValue; QVariant m_backendValue;
QVariant m_modelNodeBackend; QVariant m_modelNodeBackend;
QVariant m_stateModelNode;
QmlDesigner::ModelNode m_modelNode;
TypeName m_backendValueTypeName; TypeName m_backendValueTypeName;
}; };

View File

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

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