Merge "Merge remote-tracking branch 'origin/4.11'"
52
README.md
@@ -8,7 +8,7 @@ The standalone binary packages support the following platforms:
|
||||
|
||||
* Windows 7 or later
|
||||
* (K)Ubuntu Linux 16.04 (64-bit) or later
|
||||
* macOS 10.12 or later
|
||||
* macOS 10.13 or later
|
||||
|
||||
## Contributing
|
||||
|
||||
@@ -31,6 +31,7 @@ Prerequisites:
|
||||
* ActiveState Active Perl
|
||||
* MinGW with g++ 5.3 or Visual Studio 2017 or later
|
||||
* jom
|
||||
* Ninja (optional, needed for CMake)
|
||||
* Python 3.5 or later (optional, needed for the python enabled debug helper)
|
||||
* On Mac OS X: latest Xcode
|
||||
* On Linux: g++ 5.3 or later
|
||||
@@ -38,7 +39,7 @@ Prerequisites:
|
||||
Clang PCH Manager and Clang Refactoring plugins, see the section
|
||||
"Get LLVM/Clang for the Clang Code Model". The LLVM C++ API provides no compatibility garantee,
|
||||
so if later versions don't compile we don't support that version.)
|
||||
* CMake (only for manual builds of LLVM/Clang)
|
||||
* CMake (for manual builds of LLVM/Clang, and Qt Creator itself)
|
||||
* Qbs 1.7.x (optional, sources also contain Qbs itself)
|
||||
|
||||
The installed toolchains have to match the one Qt was compiled with.
|
||||
@@ -264,13 +265,24 @@ http://llvm.org/docs/GettingStarted.html#git-mirror:
|
||||
|
||||
For Linux/macOS:
|
||||
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_RTTI=ON -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DCMAKE_INSTALL_PREFIX=<installation location> ../llvm-project/llvm
|
||||
make install
|
||||
cmake \
|
||||
-D CMAKE_BUILD_TYPE=Release \
|
||||
-D LLVM_ENABLE_RTTI=ON \
|
||||
-D LLVM_ENABLE_PROJECTS="clang;clang-tools-extra" \
|
||||
-D CMAKE_INSTALL_PREFIX=<installation location> \
|
||||
../llvm-project/llvm
|
||||
cmake --build . --target install
|
||||
|
||||
For Windows:
|
||||
|
||||
cmake -G "NMake Makefiles JOM" -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_RTTI=ON -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DCMAKE_INSTALL_PREFIX=<installation location> ..\llvm-project\llvm
|
||||
jom install
|
||||
cmake ^
|
||||
-G "NMake Makefiles JOM" ^
|
||||
-D CMAKE_BUILD_TYPE=Release ^
|
||||
-D LLVM_ENABLE_RTTI=ON ^
|
||||
-D LLVM_ENABLE_PROJECTS="clang;clang-tools-extra" ^
|
||||
-D CMAKE_INSTALL_PREFIX=<installation location> ^
|
||||
..\llvm-project\llvm
|
||||
cmake --build . --target install
|
||||
|
||||
### Clang-Format
|
||||
|
||||
@@ -282,6 +294,34 @@ While the plugin builds without it, it will be disabled on start with an error m
|
||||
|
||||
Note that the plugin is disabled by default.
|
||||
|
||||
### Building Qt Creator with CMake
|
||||
|
||||
Qt Creator can also be built with CMake. The main Qt Creator dependencies, Qt and LLVM/Clang, both
|
||||
offer CMake find packages, which reduce the steps of configuring Qt Creator to a minimum.
|
||||
|
||||
Configure and build Qt Creator:
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
For Linux/macOS:
|
||||
|
||||
cmake \
|
||||
-G Ninja \
|
||||
-D CMAKE_BUILD_TYPE=Release \
|
||||
-D CMAKE_PREFIX_PATH=~/Qt/5.12.5/gcc_64;~/llvm \
|
||||
../qt-creator
|
||||
cmake --build .
|
||||
|
||||
For Windows:
|
||||
|
||||
cmake ^
|
||||
-G Ninja ^
|
||||
-D CMAKE_BUILD_TYPE=Release ^
|
||||
-D CMAKE_PREFIX_PATH=c:\Qt\5.12.5\msvc2017_64;c:\llvm ^
|
||||
..\qt-creator
|
||||
cmake --build .
|
||||
|
||||
## Third-party Components
|
||||
|
||||
Qt Creator includes the following third-party components,
|
||||
|
@@ -31,9 +31,14 @@
|
||||
|
||||
/*!
|
||||
\contentspage index.html
|
||||
\previouspage creator-keyboard-shortcuts.html
|
||||
\page creator-editor-external.html
|
||||
\if defined(qtdesignstudio)
|
||||
\previouspage creator-qml-performance-monitor.html
|
||||
\nextpage studio-help.html
|
||||
\else
|
||||
\previouspage creator-keyboard-shortcuts.html
|
||||
\nextpage creator-task-lists.html
|
||||
\endif
|
||||
|
||||
\title Using External Tools
|
||||
|
||||
@@ -69,8 +74,8 @@
|
||||
External > Configure}.
|
||||
|
||||
To open TS files in Qt Linguist, right-click a TS file in the
|
||||
\uicontrol Projects view and select \uicontrol {Open With} >
|
||||
\uicontrol {Qt Linguist} in the context menu.
|
||||
\uicontrol Projects or \uicontrol {File System} view and select
|
||||
\uicontrol {Open With} > \uicontrol {Qt Linguist} in the context menu.
|
||||
For more information about Qt Linguist, see \l{Qt Linguist Manual}.
|
||||
|
||||
\section1 Previewing QML Files
|
||||
@@ -130,17 +135,24 @@
|
||||
\li In the \uicontrol {Error output} field, select how to handle error
|
||||
messages from the tool.
|
||||
|
||||
\if defined(qtcreator)
|
||||
\li In the \uicontrol {Base environment} field, select whether to run
|
||||
the tool in the system environment or the \l{Build Environment}
|
||||
{build environment} or \l {Selecting the Run Environment}
|
||||
{run environment} of the active project. Select the build or run
|
||||
environment if the system environment does not contain the necessary
|
||||
PATH settings to find the tool chain, for example.
|
||||
\else
|
||||
\li In the \uicontrol {Base environment} field, use the default settings.
|
||||
\endif
|
||||
|
||||
\li In the \uicontrol Environment field, select \uicontrol Change to modify
|
||||
environment variable values for build and run environments in
|
||||
the \uicontrol {Edit Environment Changes} dialog. For more information
|
||||
about how to add and remove variable values, see \l{Batch Editing}.
|
||||
the \uicontrol {Edit Environment Changes} dialog.
|
||||
\if defined(qtcreator)
|
||||
For more information about how to add and remove variable values,
|
||||
see \l{Batch Editing}.
|
||||
\endif
|
||||
|
||||
\li Select the \uicontrol {Modifies current document} check box to make sure
|
||||
that if the current document is modified by the tool, it is saved
|
@@ -102,7 +102,7 @@
|
||||
|
||||
\endlist
|
||||
|
||||
\li \macos 10.12 or later with the following:
|
||||
\li \macos 10.13 or later with the following:
|
||||
|
||||
\list
|
||||
|
||||
|
@@ -34,7 +34,7 @@
|
||||
\page creator-qml-performance-monitor.html
|
||||
\if defined(qtdesignstudio)
|
||||
\previouspage creator-qml-debugging-example.html
|
||||
\nextpage studio-help.html
|
||||
\nextpage creator-editor-external.html
|
||||
\else
|
||||
\previouspage creator-analyze-mode.html
|
||||
\nextpage creator-valgrind-overview.html
|
||||
|
@@ -27,6 +27,7 @@ HEADERS += $$PWD/changeauxiliarycommand.h
|
||||
HEADERS += $$PWD/removesharedmemorycommand.h
|
||||
HEADERS += $$PWD/puppetalivecommand.h
|
||||
HEADERS += $$PWD/changeselectioncommand.h
|
||||
HEADERS += $$PWD/drop3dlibraryitemcommand.h
|
||||
|
||||
SOURCES += $$PWD/synchronizecommand.cpp
|
||||
SOURCES += $$PWD/debugoutputcommand.cpp
|
||||
@@ -55,3 +56,4 @@ SOURCES += $$PWD/changeauxiliarycommand.cpp
|
||||
SOURCES += $$PWD/removesharedmemorycommand.cpp
|
||||
SOURCES += $$PWD/puppetalivecommand.cpp
|
||||
SOURCES += $$PWD/changeselectioncommand.cpp
|
||||
SOURCES += $$PWD/drop3dlibraryitemcommand.cpp
|
||||
|
@@ -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
|
@@ -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)
|
@@ -68,6 +68,7 @@
|
||||
#include "debugoutputcommand.h"
|
||||
#include "puppetalivecommand.h"
|
||||
#include "changeselectioncommand.h"
|
||||
#include "drop3dlibraryitemcommand.h"
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
@@ -139,6 +140,7 @@ bool compareCommands(const QVariant &command, const QVariant &controlCommand)
|
||||
static const int tokenCommandType = QMetaType::type("TokenCommand");
|
||||
static const int debugOutputCommandType = QMetaType::type("DebugOutputCommand");
|
||||
static const int changeSelectionCommandType = QMetaType::type("ChangeSelectionCommand");
|
||||
static const int drop3DLibraryItemCommandType = QMetaType::type("Drop3DLibraryItemCommand");
|
||||
|
||||
if (command.userType() == controlCommand.userType()) {
|
||||
if (command.userType() == informationChangedCommandType)
|
||||
@@ -163,6 +165,8 @@ bool compareCommands(const QVariant &command, const QVariant &controlCommand)
|
||||
return command.value<DebugOutputCommand>() == controlCommand.value<DebugOutputCommand>();
|
||||
else if (command.userType() == changeSelectionCommandType)
|
||||
return command.value<ChangeSelectionCommand>() == controlCommand.value<ChangeSelectionCommand>();
|
||||
else if (command.userType() == drop3DLibraryItemCommandType)
|
||||
return command.value<Drop3DLibraryItemCommand>() == controlCommand.value<Drop3DLibraryItemCommand>();
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -250,6 +254,11 @@ void NodeInstanceClientProxy::selectionChanged(const ChangeSelectionCommand &com
|
||||
writeCommand(QVariant::fromValue(command));
|
||||
}
|
||||
|
||||
void NodeInstanceClientProxy::library3DItemDropped(const Drop3DLibraryItemCommand &command)
|
||||
{
|
||||
writeCommand(QVariant::fromValue(command));
|
||||
}
|
||||
|
||||
void NodeInstanceClientProxy::flush()
|
||||
{
|
||||
}
|
||||
|
@@ -57,6 +57,7 @@ class ChangeStateCommand;
|
||||
class ChangeNodeSourceCommand;
|
||||
class EndPuppetCommand;
|
||||
class ChangeSelectionCommand;
|
||||
class Drop3DLibraryItemCommand;
|
||||
|
||||
class NodeInstanceClientProxy : public QObject, public NodeInstanceClientInterface
|
||||
{
|
||||
@@ -76,6 +77,7 @@ public:
|
||||
void debugOutput(const DebugOutputCommand &command) override;
|
||||
void puppetAlive(const PuppetAliveCommand &command);
|
||||
void selectionChanged(const ChangeSelectionCommand &command) override;
|
||||
void library3DItemDropped(const Drop3DLibraryItemCommand &command) override;
|
||||
|
||||
void flush() override;
|
||||
void synchronizeWithClientProcess() override;
|
||||
|
@@ -41,6 +41,7 @@ class RemoveSharedMemoryCommand;
|
||||
class DebugOutputCommand;
|
||||
class PuppetAliveCommand;
|
||||
class ChangeSelectionCommand;
|
||||
class Drop3DLibraryItemCommand;
|
||||
|
||||
class NodeInstanceClientInterface
|
||||
{
|
||||
@@ -55,6 +56,7 @@ public:
|
||||
virtual void token(const TokenCommand &command) = 0;
|
||||
virtual void debugOutput(const DebugOutputCommand &command) = 0;
|
||||
virtual void selectionChanged(const ChangeSelectionCommand &command) = 0;
|
||||
virtual void library3DItemDropped(const Drop3DLibraryItemCommand &command) = 0;
|
||||
|
||||
virtual void flush() {}
|
||||
virtual void synchronizeWithClientProcess() {}
|
||||
|
@@ -46,6 +46,7 @@
|
||||
#include "addimportcontainer.h"
|
||||
#include "changenodesourcecommand.h"
|
||||
#include "changeselectioncommand.h"
|
||||
#include "drop3dlibraryitemcommand.h"
|
||||
|
||||
#include "informationchangedcommand.h"
|
||||
#include "pixmapchangedcommand.h"
|
||||
@@ -107,6 +108,9 @@ void NodeInstanceServerInterface::registerCommands()
|
||||
qRegisterMetaType<ChangeSelectionCommand>("ChangeSelectionCommand");
|
||||
qRegisterMetaTypeStreamOperators<ChangeSelectionCommand>("ChangeSelectionCommand");
|
||||
|
||||
qRegisterMetaType<Drop3DLibraryItemCommand>("Drop3DLibraryItemCommand");
|
||||
qRegisterMetaTypeStreamOperators<Drop3DLibraryItemCommand>("Drop3DLibraryItemCommand");
|
||||
|
||||
qRegisterMetaType<RemovePropertiesCommand>("RemovePropertiesCommand");
|
||||
qRegisterMetaTypeStreamOperators<RemovePropertiesCommand>("RemovePropertiesCommand");
|
||||
|
||||
|
@@ -30,7 +30,7 @@ import CameraGeometry 1.0
|
||||
IconGizmo {
|
||||
id: cameraGizmo
|
||||
|
||||
iconSource: "qrc:///qtquickplugin/mockfiles/images/camera-pick-icon.png"
|
||||
iconSource: "qrc:///qtquickplugin/mockfiles/images/editor_camera.png"
|
||||
gizmoModel.geometry: cameraGeometry
|
||||
property alias geometryName: cameraGeometry.name // Name must be unique for each geometry
|
||||
property alias viewPortRect: cameraGeometry.viewPortRect
|
||||
@@ -43,7 +43,7 @@ IconGizmo {
|
||||
gizmoModel.materials: [
|
||||
DefaultMaterial {
|
||||
id: defaultMaterial
|
||||
emissiveColor: "blue"
|
||||
emissiveColor: cameraGizmo.targetNode === cameraGizmo.selectedNode ? "#FF0000" : "#555555"
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
cullingMode: Material.DisableCulling
|
||||
}
|
||||
|
@@ -66,9 +66,11 @@ Window {
|
||||
var component = Qt.createComponent("LightGizmo.qml");
|
||||
if (component.status === Component.Ready) {
|
||||
var gizmo = component.createObject(overlayScene,
|
||||
{"view3D": overlayView, "targetNode": obj});
|
||||
{"view3D": overlayView, "targetNode": obj,
|
||||
"selectedNode": selectedNode});
|
||||
lightGizmos[lightGizmos.length] = gizmo;
|
||||
gizmo.selected.connect(emitObjectClicked);
|
||||
gizmo.clicked.connect(emitObjectClicked);
|
||||
gizmo.selectedNode = Qt.binding(function() {return selectedNode;});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,10 +82,11 @@ Window {
|
||||
var gizmo = component.createObject(
|
||||
overlayScene,
|
||||
{"view3D": overlayView, "targetNode": obj, "geometryName": geometryName,
|
||||
"viewPortRect": viewPortRect});
|
||||
"viewPortRect": viewPortRect, "selectedNode": selectedNode});
|
||||
cameraGizmos[cameraGizmos.length] = gizmo;
|
||||
gizmo.selected.connect(emitObjectClicked);
|
||||
gizmo.clicked.connect(emitObjectClicked);
|
||||
gizmo.viewPortRect = Qt.binding(function() {return viewPortRect;});
|
||||
gizmo.selectedNode = Qt.binding(function() {return selectedNode;});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,12 +103,15 @@ Window {
|
||||
PerspectiveCamera {
|
||||
id: overlayPerspectiveCamera
|
||||
clipFar: editPerspectiveCamera.clipFar
|
||||
clipNear: editPerspectiveCamera.clipNear
|
||||
position: editPerspectiveCamera.position
|
||||
rotation: editPerspectiveCamera.rotation
|
||||
}
|
||||
|
||||
OrthographicCamera {
|
||||
id: overlayOrthoCamera
|
||||
clipFar: editOrthoCamera.clipFar
|
||||
clipNear: editOrthoCamera.clipNear
|
||||
position: editOrthoCamera.position
|
||||
rotation: editOrthoCamera.rotation
|
||||
}
|
||||
@@ -118,7 +124,7 @@ Window {
|
||||
position: viewWindow.selectedNode ? viewWindow.selectedNode.scenePosition
|
||||
: Qt.vector3d(0, 0, 0)
|
||||
globalOrientation: globalControl.checked
|
||||
visible: selectedNode && moveToolControl.checked
|
||||
visible: selectedNode && btnMove.selected
|
||||
view3D: overlayView
|
||||
|
||||
onPositionCommit: viewWindow.commitObjectProperty(selectedNode, "position")
|
||||
@@ -133,13 +139,28 @@ Window {
|
||||
position: viewWindow.selectedNode ? viewWindow.selectedNode.scenePosition
|
||||
: Qt.vector3d(0, 0, 0)
|
||||
globalOrientation: globalControl.checked
|
||||
visible: selectedNode && scaleToolControl.checked
|
||||
visible: selectedNode && btnScale.selected
|
||||
view3D: overlayView
|
||||
|
||||
onScaleCommit: viewWindow.commitObjectProperty(selectedNode, "scale")
|
||||
onScaleChange: viewWindow.changeObjectProperty(selectedNode, "scale")
|
||||
}
|
||||
|
||||
RotateGizmo {
|
||||
id: rotateGizmo
|
||||
scale: autoScale.getScale(Qt.vector3d(7, 7, 7))
|
||||
highlightOnHover: true
|
||||
targetNode: viewWindow.selectedNode
|
||||
position: viewWindow.selectedNode ? viewWindow.selectedNode.scenePosition
|
||||
: Qt.vector3d(0, 0, 0)
|
||||
globalOrientation: globalControl.checked
|
||||
visible: selectedNode && btnRotate.selected
|
||||
view3D: overlayView
|
||||
|
||||
onRotateCommit: viewWindow.commitObjectProperty(selectedNode, "rotation")
|
||||
onRotateChange: viewWindow.changeObjectProperty(selectedNode, "rotation")
|
||||
}
|
||||
|
||||
AutoScaleHelper {
|
||||
id: autoScale
|
||||
view3D: overlayView
|
||||
@@ -161,6 +182,10 @@ Window {
|
||||
}
|
||||
}
|
||||
|
||||
DropArea {
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
View3D {
|
||||
id: editView
|
||||
anchors.fill: parent
|
||||
@@ -169,10 +194,10 @@ Window {
|
||||
Node {
|
||||
id: mainSceneHelpers
|
||||
|
||||
AxisHelper {
|
||||
id: axisGrid
|
||||
enableXZGrid: true
|
||||
enableAxisLines: false
|
||||
HelperGrid {
|
||||
id: helperGrid
|
||||
lines: 50
|
||||
step: 50
|
||||
}
|
||||
|
||||
PointLight {
|
||||
@@ -186,15 +211,20 @@ Window {
|
||||
|
||||
PerspectiveCamera {
|
||||
id: editPerspectiveCamera
|
||||
z: -600
|
||||
y: 200
|
||||
z: -300
|
||||
rotation.x: 30
|
||||
clipFar: 100000
|
||||
clipNear: 1
|
||||
}
|
||||
|
||||
OrthographicCamera {
|
||||
id: editOrthoCamera
|
||||
z: -600
|
||||
y: 200
|
||||
z: -300
|
||||
rotation.x: 30
|
||||
clipFar: 100000
|
||||
clipNear: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -259,8 +289,78 @@ Window {
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle { // toolbar
|
||||
id: toolbar
|
||||
color: "#9F000000"
|
||||
width: 35
|
||||
height: col.height
|
||||
|
||||
Column {
|
||||
id: col
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing: 5
|
||||
padding: 5
|
||||
|
||||
property var group: [btnSelectItem, btnSelectGroup, btnMove, btnRotate, btnScale]
|
||||
|
||||
ToolBarButton {
|
||||
id: btnSelectItem
|
||||
selected: true
|
||||
tooltip: qsTr("Select Item")
|
||||
shortcut: "Q"
|
||||
currentShortcut: selected ? "" : shortcut
|
||||
tool: "item_selection"
|
||||
buttonsGroup: col.group
|
||||
}
|
||||
|
||||
ToolBarButton {
|
||||
id: btnSelectGroup
|
||||
tooltip: qsTr("Select Group")
|
||||
shortcut: "Q"
|
||||
currentShortcut: btnSelectItem.currentShortcut === shortcut ? "" : shortcut
|
||||
tool: "group_selection"
|
||||
buttonsGroup: col.group
|
||||
}
|
||||
|
||||
Rectangle { // separator
|
||||
width: 25
|
||||
height: 1
|
||||
color: "#f1f1f1"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
ToolBarButton {
|
||||
id: btnMove
|
||||
tooltip: qsTr("Move current selection")
|
||||
shortcut: "M"
|
||||
currentShortcut: shortcut
|
||||
tool: "move"
|
||||
buttonsGroup: col.group
|
||||
}
|
||||
|
||||
ToolBarButton {
|
||||
id: btnRotate
|
||||
tooltip: qsTr("Rotate current selection")
|
||||
shortcut: "E"
|
||||
currentShortcut: shortcut
|
||||
tool: "rotate"
|
||||
buttonsGroup: col.group
|
||||
}
|
||||
|
||||
ToolBarButton {
|
||||
id: btnScale
|
||||
tooltip: qsTr("Scale current selection")
|
||||
shortcut: "T"
|
||||
currentShortcut: shortcut
|
||||
tool: "scale"
|
||||
buttonsGroup: col.group
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
y: 8
|
||||
anchors.right: parent.right
|
||||
CheckBox {
|
||||
id: editLightCheckbox
|
||||
checked: false
|
||||
@@ -272,7 +372,19 @@ Window {
|
||||
id: usePerspectiveCheckbox
|
||||
checked: true
|
||||
text: qsTr("Use Perspective Projection")
|
||||
onCheckedChanged: cameraControl.forceActiveFocus()
|
||||
onCheckedChanged: {
|
||||
// Since WasdController always acts on active camera, we need to update pos/rot
|
||||
// to the other camera when we change
|
||||
if (checked) {
|
||||
editPerspectiveCamera.position = editOrthoCamera.position;
|
||||
editPerspectiveCamera.rotation = editOrthoCamera.rotation;
|
||||
} else {
|
||||
editOrthoCamera.position = editPerspectiveCamera.position;
|
||||
editOrthoCamera.rotation = editPerspectiveCamera.rotation;
|
||||
}
|
||||
designStudioNativeCameraControlHelper.requestOverlayUpdate();
|
||||
cameraControl.forceActiveFocus();
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
@@ -281,19 +393,6 @@ Window {
|
||||
text: qsTr("Use Global Orientation")
|
||||
onCheckedChanged: cameraControl.forceActiveFocus()
|
||||
}
|
||||
Column {
|
||||
x: 8
|
||||
RadioButton {
|
||||
id: moveToolControl
|
||||
checked: true
|
||||
text: qsTr("Move Tool")
|
||||
}
|
||||
RadioButton {
|
||||
id: scaleToolControl
|
||||
checked: false
|
||||
text: qsTr("Scale Tool")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
|
87
share/qtcreator/qml/qmlpuppet/mockfiles/HelperGrid.qml
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@@ -32,12 +32,13 @@ Node {
|
||||
property View3D view3D
|
||||
property bool highlightOnHover: true
|
||||
property Node targetNode: null
|
||||
property Node selectedNode: null
|
||||
|
||||
property alias gizmoModel: gizmoModel
|
||||
property alias iconSource: iconImage.source
|
||||
|
||||
signal positionCommit()
|
||||
signal selected(Node node)
|
||||
signal clicked(Node node)
|
||||
|
||||
position: targetNode ? targetNode.scenePosition : Qt.vector3d(0, 0, 0)
|
||||
rotation: targetNode ? targetNode.sceneRotation : Qt.vector3d(0, 0, 0)
|
||||
@@ -57,22 +58,27 @@ Node {
|
||||
parent: view3D
|
||||
|
||||
Rectangle {
|
||||
width: 24
|
||||
height: 24
|
||||
width: iconImage.width
|
||||
height: iconImage.height
|
||||
x: -width / 2
|
||||
y: -height
|
||||
color: "transparent"
|
||||
border.color: "#7777ff"
|
||||
border.width: highlightOnHover && iconMouseArea.containsMouse ? 2 : 0
|
||||
border.width: iconGizmo.selectedNode === iconGizmo.targetNode
|
||||
|| (iconGizmo.highlightOnHover && iconMouseArea.containsMouse) ? 2 : 0
|
||||
radius: 5
|
||||
opacity: iconGizmo.selectedNode === iconGizmo.targetNode ? 0.3 : 1
|
||||
Image {
|
||||
id: iconImage
|
||||
anchors.fill: parent
|
||||
fillMode: Image.Pad
|
||||
MouseArea {
|
||||
id: iconMouseArea
|
||||
anchors.fill: parent
|
||||
onClicked: selected(targetNode)
|
||||
hoverEnabled: highlightOnHover
|
||||
onClicked: iconGizmo.clicked(iconGizmo.targetNode)
|
||||
hoverEnabled: iconGizmo.highlightOnHover
|
||||
&& iconGizmo.selectedNode !== iconGizmo.targetNode
|
||||
acceptedButtons: iconGizmo.selectedNode !== iconGizmo.targetNode
|
||||
? Qt.LeftButton : Qt.NoButton
|
||||
}
|
||||
}
|
||||
}
|
||||
|
221
share/qtcreator/qml/qmlpuppet/mockfiles/RotateGizmo.qml
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
133
share/qtcreator/qml/qmlpuppet/mockfiles/RotateRing.qml
Normal 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)
|
||||
}
|
||||
}
|
79
share/qtcreator/qml/qmlpuppet/mockfiles/ToolBarButton.qml
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 206 B |
Before Width: | Height: | Size: 279 B |
BIN
share/qtcreator/qml/qmlpuppet/mockfiles/images/editor_camera.png
Normal file
After Width: | Height: | Size: 981 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 404 B |
After Width: | Height: | Size: 779 B |
After Width: | Height: | Size: 438 B |
After Width: | Height: | Size: 904 B |
After Width: | Height: | Size: 353 B |
After Width: | Height: | Size: 657 B |
After Width: | Height: | Size: 355 B |
After Width: | Height: | Size: 661 B |
BIN
share/qtcreator/qml/qmlpuppet/mockfiles/images/move_active.png
Normal file
After Width: | Height: | Size: 294 B |
After Width: | Height: | Size: 303 B |
BIN
share/qtcreator/qml/qmlpuppet/mockfiles/images/move_selected.png
Normal file
After Width: | Height: | Size: 191 B |
After Width: | Height: | Size: 272 B |
BIN
share/qtcreator/qml/qmlpuppet/mockfiles/images/rotate_active.png
Normal file
After Width: | Height: | Size: 451 B |
After Width: | Height: | Size: 869 B |
After Width: | Height: | Size: 478 B |
After Width: | Height: | Size: 906 B |
BIN
share/qtcreator/qml/qmlpuppet/mockfiles/images/scale_active.png
Normal file
After Width: | Height: | Size: 242 B |
After Width: | Height: | Size: 338 B |
After Width: | Height: | Size: 277 B |
After Width: | Height: | Size: 364 B |
BIN
share/qtcreator/qml/qmlpuppet/mockfiles/meshes/ring.mesh
Normal file
BIN
share/qtcreator/qml/qmlpuppet/mockfiles/meshes/ringselect.mesh
Normal file
@@ -1,7 +1,9 @@
|
||||
HEADERS += $$PWD/cameracontrolhelper.h \
|
||||
$$PWD/mousearea3d.h \
|
||||
$$PWD/camerageometry.h
|
||||
$$PWD/camerageometry.h \
|
||||
$$PWD/gridgeometry.h
|
||||
|
||||
SOURCES += $$PWD/cameracontrolhelper.cpp \
|
||||
$$PWD/mousearea3d.cpp \
|
||||
$$PWD/camerageometry.cpp
|
||||
$$PWD/camerageometry.cpp \
|
||||
$$PWD/gridgeometry.cpp
|
||||
|
@@ -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
|
@@ -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
|
@@ -29,11 +29,15 @@
|
||||
|
||||
#include <QtGui/qguiapplication.h>
|
||||
#include <QtQml/qqmlinfo.h>
|
||||
#include <QtQuick3D/private/qquick3dcamera_p.h>
|
||||
#include <QtQuick3D/private/qquick3dorthographiccamera_p.h>
|
||||
#include <QtQuick3DRuntimeRender/private/qssgrendercamera_p.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
namespace Internal {
|
||||
|
||||
MouseArea3D *MouseArea3D::s_mouseGrab = nullptr;
|
||||
static const qreal s_mouseDragMultiplier = .02;
|
||||
|
||||
MouseArea3D::MouseArea3D(QQuick3DNode *parent)
|
||||
: QQuick3DNode(parent)
|
||||
@@ -65,6 +69,21 @@ bool MouseArea3D::active() const
|
||||
return m_active;
|
||||
}
|
||||
|
||||
QPointF MouseArea3D::circlePickArea() const
|
||||
{
|
||||
return m_circlePickArea;
|
||||
}
|
||||
|
||||
qreal MouseArea3D::minAngle() const
|
||||
{
|
||||
return m_minAngle;
|
||||
}
|
||||
|
||||
QQuick3DNode *MouseArea3D::pickNode() const
|
||||
{
|
||||
return m_pickNode;
|
||||
}
|
||||
|
||||
qreal MouseArea3D::x() const
|
||||
{
|
||||
return m_x;
|
||||
@@ -105,7 +124,7 @@ void MouseArea3D::setGrabsMouse(bool grabsMouse)
|
||||
return;
|
||||
|
||||
m_grabsMouse = grabsMouse;
|
||||
emit grabsMouseChanged(grabsMouse);
|
||||
emit grabsMouseChanged();
|
||||
}
|
||||
|
||||
void MouseArea3D::setActive(bool active)
|
||||
@@ -114,7 +133,37 @@ void MouseArea3D::setActive(bool active)
|
||||
return;
|
||||
|
||||
m_active = active;
|
||||
emit activeChanged(active);
|
||||
emit activeChanged();
|
||||
}
|
||||
|
||||
void MouseArea3D::setCirclePickArea(const QPointF &pickArea)
|
||||
{
|
||||
if (m_circlePickArea == pickArea)
|
||||
return;
|
||||
|
||||
m_circlePickArea = pickArea;
|
||||
emit circlePickAreaChanged();
|
||||
}
|
||||
|
||||
// This is the minimum angle for circle picking. At lower angles we fall back to picking on pickNode
|
||||
void MouseArea3D::setMinAngle(qreal angle)
|
||||
{
|
||||
if (qFuzzyCompare(m_minAngle, angle))
|
||||
return;
|
||||
|
||||
m_minAngle = angle;
|
||||
emit minAngleChanged();
|
||||
}
|
||||
|
||||
// This is the fallback pick node when circle picking can't be done due to low angle
|
||||
// Pick node can't be used except in low angles, as long as only bounding box picking is supported
|
||||
void MouseArea3D::setPickNode(QQuick3DNode *node)
|
||||
{
|
||||
if (m_pickNode == node)
|
||||
return;
|
||||
|
||||
m_pickNode = node;
|
||||
emit pickNodeChanged();
|
||||
}
|
||||
|
||||
void MouseArea3D::setX(qreal x)
|
||||
@@ -123,7 +172,7 @@ void MouseArea3D::setX(qreal x)
|
||||
return;
|
||||
|
||||
m_x = x;
|
||||
emit xChanged(x);
|
||||
emit xChanged();
|
||||
}
|
||||
|
||||
void MouseArea3D::setY(qreal y)
|
||||
@@ -132,7 +181,7 @@ void MouseArea3D::setY(qreal y)
|
||||
return;
|
||||
|
||||
m_y = y;
|
||||
emit yChanged(y);
|
||||
emit yChanged();
|
||||
}
|
||||
|
||||
void MouseArea3D::setWidth(qreal width)
|
||||
@@ -141,7 +190,7 @@ void MouseArea3D::setWidth(qreal width)
|
||||
return;
|
||||
|
||||
m_width = width;
|
||||
emit widthChanged(width);
|
||||
emit widthChanged();
|
||||
}
|
||||
|
||||
void MouseArea3D::setHeight(qreal height)
|
||||
@@ -150,7 +199,7 @@ void MouseArea3D::setHeight(qreal height)
|
||||
return;
|
||||
|
||||
m_height = height;
|
||||
emit heightChanged(height);
|
||||
emit heightChanged();
|
||||
}
|
||||
|
||||
void MouseArea3D::setPriority(int level)
|
||||
@@ -159,7 +208,7 @@ void MouseArea3D::setPriority(int level)
|
||||
return;
|
||||
|
||||
m_priority = level;
|
||||
emit priorityChanged(level);
|
||||
emit priorityChanged();
|
||||
}
|
||||
|
||||
void MouseArea3D::componentComplete()
|
||||
@@ -278,6 +327,84 @@ QVector3D MouseArea3D::getNewScale(QQuick3DNode *node, const QVector3D &startSca
|
||||
return startScale;
|
||||
}
|
||||
|
||||
qreal QmlDesigner::Internal::MouseArea3D::getNewRotationAngle(
|
||||
QQuick3DNode *node, const QVector3D &pressPos, const QVector3D ¤tPos,
|
||||
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 ¤tPos)
|
||||
{
|
||||
QVector3D dragVector = currentPos - pressPos;
|
||||
|
||||
if (dragVector.length() < 0.001f)
|
||||
return;
|
||||
|
||||
const float *dataPtr(sceneTransform().data());
|
||||
QVector3D xAxis = QVector3D(-dataPtr[0], -dataPtr[1], -dataPtr[2]).normalized();
|
||||
QVector3D yAxis = QVector3D(-dataPtr[4], -dataPtr[5], -dataPtr[6]).normalized();
|
||||
|
||||
QVector3D finalAxis = (dragVector.x() * yAxis + dragVector.y() * xAxis);
|
||||
|
||||
qreal degrees = qRadiansToDegrees(qreal(finalAxis.length()) * s_mouseDragMultiplier);
|
||||
|
||||
finalAxis.normalize();
|
||||
|
||||
node->setRotation(startRotation);
|
||||
node->rotate(degrees, finalAxis, QQuick3DNode::SceneSpace);
|
||||
}
|
||||
|
||||
QVector3D MouseArea3D::getMousePosInPlane(const QPointF &mousePosInView) const
|
||||
{
|
||||
const QVector3D mousePos1(float(mousePosInView.x()), float(mousePosInView.y()), 0);
|
||||
@@ -300,12 +427,50 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
|
||||
return false;
|
||||
}
|
||||
|
||||
auto mouseOnTopOfMouseArea = [this](const QVector3D &mousePosInPlane) -> bool {
|
||||
return !qFuzzyCompare(mousePosInPlane.z(), -1)
|
||||
qreal pickAngle = 0.;
|
||||
|
||||
auto mouseOnTopOfMouseArea = [this, &pickAngle](
|
||||
const QVector3D &mousePosInPlane, const QPointF &mousePos) -> bool {
|
||||
const bool onPlane = !qFuzzyCompare(mousePosInPlane.z(), -1)
|
||||
&& mousePosInPlane.x() >= float(m_x)
|
||||
&& mousePosInPlane.x() <= float(m_x + m_width)
|
||||
&& mousePosInPlane.y() >= float(m_y)
|
||||
&& mousePosInPlane.y() <= float(m_y + m_height);
|
||||
|
||||
bool onCircle = true;
|
||||
bool pickSuccess = false;
|
||||
if (!qFuzzyIsNull(m_circlePickArea.y()) || !qFuzzyIsNull(m_minAngle)) {
|
||||
|
||||
QVector3D cameraToMouseAreaDir = getCameraToNodeDir(this);
|
||||
const QVector3D mouseAreaDir = getNormal();
|
||||
qreal angle = qreal(QVector3D::dotProduct(cameraToMouseAreaDir, mouseAreaDir));
|
||||
// Do not allow selecting ring that is nearly perpendicular to camera, as dragging along
|
||||
// that plane would be difficult
|
||||
pickAngle = qAcos(angle);
|
||||
pickAngle = pickAngle > M_PI_2 ? pickAngle - M_PI_2 : M_PI_2 - pickAngle;
|
||||
if (pickAngle > m_minAngle) {
|
||||
if (!qFuzzyIsNull(m_circlePickArea.y())) {
|
||||
qreal ringCenter = m_circlePickArea.x();
|
||||
// Thickness is increased according to the angle to camera to keep projected
|
||||
// circle thickness constant at all angles.
|
||||
qreal divisor = qSin(pickAngle) * 2.; // This is never zero
|
||||
qreal thickness = ((m_circlePickArea.y() / divisor));
|
||||
qreal mousePosRadius = qSqrt(qreal(mousePosInPlane.x() * mousePosInPlane.x())
|
||||
+ qreal(mousePosInPlane.y() * mousePosInPlane.y()));
|
||||
onCircle = ringCenter - thickness <= mousePosRadius
|
||||
&& ringCenter + thickness >= mousePosRadius;
|
||||
}
|
||||
} else {
|
||||
// Fall back to picking on the pickNode. At this angle, bounding box pick is not
|
||||
// a problem
|
||||
onCircle = false;
|
||||
if (m_pickNode) {
|
||||
QQuick3DPickResult pr = m_view3D->pick(float(mousePos.x()), float(mousePos.y()));
|
||||
pickSuccess = pr.objectHit() == m_pickNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (onCircle && onPlane) || pickSuccess;
|
||||
};
|
||||
|
||||
switch (event->type()) {
|
||||
@@ -313,9 +478,9 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
|
||||
auto const mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
if (mouseEvent->button() == Qt::LeftButton) {
|
||||
m_mousePosInPlane = getMousePosInPlane(mouseEvent->pos());
|
||||
if (mouseOnTopOfMouseArea(m_mousePosInPlane)) {
|
||||
if (mouseOnTopOfMouseArea(m_mousePosInPlane, mouseEvent->pos())) {
|
||||
setDragging(true);
|
||||
emit pressed(m_mousePosInPlane, mouseEvent->globalPos());
|
||||
emit pressed(m_mousePosInPlane, mouseEvent->pos(), pickAngle);
|
||||
if (m_grabsMouse) {
|
||||
if (s_mouseGrab && s_mouseGrab != this) {
|
||||
s_mouseGrab->setDragging(false);
|
||||
@@ -338,13 +503,13 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
|
||||
if (qFuzzyCompare(mousePosInPlane.z(), -1))
|
||||
mousePosInPlane = m_mousePosInPlane;
|
||||
setDragging(false);
|
||||
emit released(mousePosInPlane, mouseEvent->globalPos());
|
||||
emit released(mousePosInPlane, mouseEvent->pos());
|
||||
if (m_grabsMouse) {
|
||||
if (s_mouseGrab && s_mouseGrab != this) {
|
||||
s_mouseGrab->setDragging(false);
|
||||
s_mouseGrab->setHovering(false);
|
||||
}
|
||||
if (mouseOnTopOfMouseArea(mousePosInPlane)) {
|
||||
if (mouseOnTopOfMouseArea(mousePosInPlane, mouseEvent->pos())) {
|
||||
s_mouseGrab = this;
|
||||
setHovering(true);
|
||||
} else {
|
||||
@@ -362,7 +527,7 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
|
||||
case QEvent::HoverMove: {
|
||||
auto const mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
const QVector3D mousePosInPlane = getMousePosInPlane(mouseEvent->pos());
|
||||
const bool hasMouse = mouseOnTopOfMouseArea(mousePosInPlane);
|
||||
const bool hasMouse = mouseOnTopOfMouseArea(mousePosInPlane, mouseEvent->pos());
|
||||
|
||||
setHovering(hasMouse);
|
||||
|
||||
@@ -376,9 +541,9 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
|
||||
s_mouseGrab = nullptr;
|
||||
}
|
||||
|
||||
if (m_dragging && !qFuzzyCompare(mousePosInPlane.z(), -1)) {
|
||||
if (m_dragging && (m_circlePickArea.y() > 0. || !qFuzzyCompare(mousePosInPlane.z(), -1))) {
|
||||
m_mousePosInPlane = mousePosInPlane;
|
||||
emit dragged(mousePosInPlane, mouseEvent->globalPos());
|
||||
emit dragged(mousePosInPlane, mouseEvent->pos());
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -408,6 +573,25 @@ void MouseArea3D::setHovering(bool enable)
|
||||
emit hoveringChanged();
|
||||
}
|
||||
|
||||
QVector3D MouseArea3D::getNormal() const
|
||||
{
|
||||
const float *dataPtr(sceneTransform().data());
|
||||
return QVector3D(dataPtr[8], dataPtr[9], dataPtr[10]).normalized();
|
||||
}
|
||||
|
||||
QVector3D MouseArea3D::getCameraToNodeDir(QQuick3DNode *node) const
|
||||
{
|
||||
QVector3D dir;
|
||||
if (qobject_cast<QQuick3DOrthographicCamera *>(m_view3D->camera())) {
|
||||
dir = m_view3D->camera()->cameraNode()->getDirection();
|
||||
// Camera direction has x and y flipped
|
||||
dir = QVector3D(-dir.x(), -dir.y(), dir.z());
|
||||
} else {
|
||||
dir = (node->scenePosition() - m_view3D->camera()->scenePosition()).normalized();
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -28,9 +28,11 @@
|
||||
#ifdef QUICK3D_MODULE
|
||||
|
||||
#include <QtGui/qvector3d.h>
|
||||
#include <QtCore/qpoint.h>
|
||||
#include <QtCore/qpointer.h>
|
||||
|
||||
#include <QtQuick3D/private/qquick3dnode_p.h>
|
||||
#include <QtQuick3D/private/qquick3dmodel_p.h>
|
||||
#include <QtQuick3D/private/qquick3dviewport_p.h>
|
||||
#include <QtQuick3D/private/qtquick3dglobal_p.h>
|
||||
|
||||
@@ -50,6 +52,9 @@ class MouseArea3D : public QQuick3DNode
|
||||
Q_PROPERTY(bool dragging READ dragging NOTIFY draggingChanged)
|
||||
Q_PROPERTY(int priority READ priority WRITE setPriority NOTIFY priorityChanged)
|
||||
Q_PROPERTY(int active READ active WRITE setActive NOTIFY activeChanged)
|
||||
Q_PROPERTY(QPointF circlePickArea READ circlePickArea WRITE setCirclePickArea NOTIFY circlePickAreaChanged)
|
||||
Q_PROPERTY(qreal minAngle READ minAngle WRITE setMinAngle NOTIFY minAngleChanged)
|
||||
Q_PROPERTY(QQuick3DNode *pickNode READ pickNode WRITE setPickNode NOTIFY pickNodeChanged)
|
||||
|
||||
Q_INTERFACES(QQmlParserStatus)
|
||||
|
||||
@@ -68,11 +73,17 @@ public:
|
||||
bool dragging() const;
|
||||
bool grabsMouse() const;
|
||||
bool active() const;
|
||||
QPointF circlePickArea() const;
|
||||
qreal minAngle() const;
|
||||
QQuick3DNode *pickNode() const;
|
||||
|
||||
public slots:
|
||||
void setView3D(QQuick3DViewport *view3D);
|
||||
void setGrabsMouse(bool grabsMouse);
|
||||
void setActive(bool active);
|
||||
void setCirclePickArea(const QPointF &pickArea);
|
||||
void setMinAngle(qreal angle);
|
||||
void setPickNode(QQuick3DNode *node);
|
||||
|
||||
void setX(qreal x);
|
||||
void setY(qreal y);
|
||||
@@ -89,22 +100,35 @@ public slots:
|
||||
const QVector3D &pressPos,
|
||||
const QVector3D &sceneRelativeDistance, bool global);
|
||||
|
||||
Q_INVOKABLE qreal getNewRotationAngle(QQuick3DNode *node, const QVector3D &pressPos,
|
||||
const QVector3D ¤tPos, 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 ¤tPos);
|
||||
|
||||
signals:
|
||||
void view3DChanged();
|
||||
|
||||
void xChanged(qreal x);
|
||||
void yChanged(qreal y);
|
||||
void widthChanged(qreal width);
|
||||
void heightChanged(qreal height);
|
||||
void priorityChanged(int level);
|
||||
void xChanged();
|
||||
void yChanged();
|
||||
void widthChanged();
|
||||
void heightChanged();
|
||||
void priorityChanged();
|
||||
|
||||
void hoveringChanged();
|
||||
void draggingChanged();
|
||||
void activeChanged(bool active);
|
||||
void pressed(const QVector3D &scenePos, const QPoint &screenPos);
|
||||
void activeChanged();
|
||||
void grabsMouseChanged();
|
||||
void circlePickAreaChanged();
|
||||
void minAngleChanged();
|
||||
void pickNodeChanged();
|
||||
|
||||
// angle parameter is only set if circlePickArea is specified
|
||||
void pressed(const QVector3D &scenePos, const QPoint &screenPos, qreal angle);
|
||||
void released(const QVector3D &scenePos, const QPoint &screenPos);
|
||||
void dragged(const QVector3D &scenePos, const QPoint &screenPos);
|
||||
void grabsMouseChanged(bool grabsMouse);
|
||||
|
||||
protected:
|
||||
void classBegin() override {}
|
||||
@@ -114,6 +138,8 @@ protected:
|
||||
private:
|
||||
void setDragging(bool enable);
|
||||
void setHovering(bool enable);
|
||||
QVector3D getNormal() const;
|
||||
QVector3D getCameraToNodeDir(QQuick3DNode *node) const;
|
||||
|
||||
Q_DISABLE_COPY(MouseArea3D)
|
||||
QQuick3DViewport *m_view3D = nullptr;
|
||||
@@ -133,6 +159,9 @@ private:
|
||||
static MouseArea3D *s_mouseGrab;
|
||||
bool m_grabsMouse;
|
||||
QVector3D m_mousePosInPlane;
|
||||
QPointF m_circlePickArea;
|
||||
qreal m_minAngle = 0.;
|
||||
QQuick3DNode *m_pickNode = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -67,6 +67,7 @@
|
||||
#include <tokencommand.h>
|
||||
#include <removesharedmemorycommand.h>
|
||||
#include <changeselectioncommand.h>
|
||||
#include <drop3dlibraryitemcommand.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QQmlEngine>
|
||||
@@ -1171,6 +1172,11 @@ ChangeSelectionCommand NodeInstanceServer::createChangeSelectionCommand(const QL
|
||||
return ChangeSelectionCommand(idVector);
|
||||
}
|
||||
|
||||
Drop3DLibraryItemCommand NodeInstanceServer::createDrop3DLibraryItemCommand(const QByteArray &itemData)
|
||||
{
|
||||
return Drop3DLibraryItemCommand(itemData);
|
||||
}
|
||||
|
||||
ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QVector<InstancePropertyPair> &propertyList) const
|
||||
{
|
||||
QVector<PropertyValueContainer> valueVector;
|
||||
|
@@ -70,6 +70,7 @@ class AddImportContainer;
|
||||
class MockupTypeContainer;
|
||||
class IdContainer;
|
||||
class ChangeSelectionCommand;
|
||||
class Drop3DLibraryItemCommand;
|
||||
|
||||
namespace Internal {
|
||||
class ChildrenChangeEventFilter;
|
||||
@@ -180,6 +181,7 @@ protected:
|
||||
ChildrenChangedCommand createChildrenChangedCommand(const ServerNodeInstance &parentInstance, const QList<ServerNodeInstance> &instanceList) const;
|
||||
ComponentCompletedCommand createComponentCompletedCommand(const QList<ServerNodeInstance> &instanceList);
|
||||
ChangeSelectionCommand createChangeSelectionCommand(const QList<ServerNodeInstance> &instanceList);
|
||||
Drop3DLibraryItemCommand createDrop3DLibraryItemCommand(const QByteArray &itemData);
|
||||
|
||||
void addChangedProperty(const InstancePropertyPair &property);
|
||||
|
||||
|
@@ -27,6 +27,8 @@
|
||||
|
||||
#include <QQuickItem>
|
||||
#include <QQuickView>
|
||||
#include <QDropEvent>
|
||||
#include <QMimeData>
|
||||
|
||||
#include "servernodeinstance.h"
|
||||
#include "childrenchangeeventfilter.h"
|
||||
@@ -57,11 +59,13 @@
|
||||
#include "removesharedmemorycommand.h"
|
||||
#include "changeselectioncommand.h"
|
||||
#include "objectnodeinstance.h"
|
||||
#include <drop3dlibraryitemcommand.h>
|
||||
|
||||
#include "dummycontextobject.h"
|
||||
#include "../editor3d/cameracontrolhelper.h"
|
||||
#include "../editor3d/mousearea3d.h"
|
||||
#include "../editor3d/camerageometry.h"
|
||||
#include "../editor3d/gridgeometry.h"
|
||||
|
||||
#include <designersupportdelegate.h>
|
||||
|
||||
@@ -79,6 +83,25 @@ static QVariant objectToVariant(QObject *object)
|
||||
return QVariant::fromValue(object);
|
||||
}
|
||||
|
||||
bool Qt5InformationNodeInstanceServer::eventFilter(QObject *, QEvent *event)
|
||||
{
|
||||
switch (event->type()) {
|
||||
case QEvent::Drop: {
|
||||
QDropEvent *dropEvent = static_cast<QDropEvent *>(event);
|
||||
QByteArray data = dropEvent->mimeData()->data(
|
||||
QStringLiteral("application/vnd.bauhaus.itemlibraryinfo"));
|
||||
if (!data.isEmpty())
|
||||
nodeInstanceClient()->library3DItemDropped(createDrop3DLibraryItemCommand(data));
|
||||
|
||||
} break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QObject *Qt5InformationNodeInstanceServer::createEditView3D(QQmlEngine *engine)
|
||||
{
|
||||
auto helper = new QmlDesigner::Internal::CameraControlHelper();
|
||||
@@ -87,6 +110,7 @@ QObject *Qt5InformationNodeInstanceServer::createEditView3D(QQmlEngine *engine)
|
||||
#ifdef QUICK3D_MODULE
|
||||
qmlRegisterType<QmlDesigner::Internal::MouseArea3D>("MouseArea3D", 1, 0, "MouseArea3D");
|
||||
qmlRegisterType<QmlDesigner::Internal::CameraGeometry>("CameraGeometry", 1, 0, "CameraGeometry");
|
||||
qmlRegisterType<QmlDesigner::Internal::GridGeometry>("GridGeometry", 1, 0, "GridGeometry");
|
||||
#endif
|
||||
|
||||
QQmlComponent component(engine, QUrl("qrc:/qtquickplugin/mockfiles/EditView3D.qml"));
|
||||
@@ -98,6 +122,7 @@ QObject *Qt5InformationNodeInstanceServer::createEditView3D(QQmlEngine *engine)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
window->installEventFilter(this);
|
||||
QObject::connect(window, SIGNAL(objectClicked(QVariant)), this, SLOT(objectClicked(QVariant)));
|
||||
QObject::connect(window, SIGNAL(commitObjectProperty(QVariant, QVariant)),
|
||||
this, SLOT(handleObjectPropertyCommit(QVariant, QVariant)));
|
||||
|
@@ -57,6 +57,7 @@ private slots:
|
||||
|
||||
protected:
|
||||
void collectItemChangesAndSendChangeCommands() override;
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
void sendChildrenChangedCommand(const QList<ServerNodeInstance> &childList);
|
||||
void sendTokenBack();
|
||||
bool isDirtyRecursiveForNonInstanceItems(QQuickItem *item) const;
|
||||
|
@@ -15,17 +15,43 @@
|
||||
<file>mockfiles/LightGizmo.qml</file>
|
||||
<file>mockfiles/IconGizmo.qml</file>
|
||||
<file>mockfiles/Overlay2D.qml</file>
|
||||
<file>mockfiles/HelperGrid.qml</file>
|
||||
<file>mockfiles/DirectionalDraggable.qml</file>
|
||||
<file>mockfiles/PlanarDraggable.qml</file>
|
||||
<file>mockfiles/PlanarMoveHandle.qml</file>
|
||||
<file>mockfiles/PlanarScaleHandle.qml</file>
|
||||
<file>mockfiles/ScaleRod.qml</file>
|
||||
<file>mockfiles/ScaleGizmo.qml</file>
|
||||
<file>mockfiles/ToolBarButton.qml</file>
|
||||
<file>mockfiles/RotateGizmo.qml</file>
|
||||
<file>mockfiles/RotateRing.qml</file>
|
||||
<file>mockfiles/meshes/arrow.mesh</file>
|
||||
<file>mockfiles/meshes/scalerod.mesh</file>
|
||||
<file>mockfiles/images/camera-pick-icon.png</file>
|
||||
<file>mockfiles/images/camera-pick-icon@2x.png</file>
|
||||
<file>mockfiles/meshes/ring.mesh</file>
|
||||
<file>mockfiles/meshes/ringselect.mesh</file>
|
||||
<file>mockfiles/images/editor_camera.png</file>
|
||||
<file>mockfiles/images/editor_camera@2x.png</file>
|
||||
<file>mockfiles/images/light-pick-icon.png</file>
|
||||
<file>mockfiles/images/light-pick-icon@2x.png</file>
|
||||
<file>mockfiles/images/item_selection_active.png</file>
|
||||
<file>mockfiles/images/item_selection_active@2x.png</file>
|
||||
<file>mockfiles/images/item_selection_selected.png</file>
|
||||
<file>mockfiles/images/item_selection_selected@2x.png</file>
|
||||
<file>mockfiles/images/group_selection_selected.png</file>
|
||||
<file>mockfiles/images/group_selection_selected@2x.png</file>
|
||||
<file>mockfiles/images/group_selection_active.png</file>
|
||||
<file>mockfiles/images/group_selection_active@2x.png</file>
|
||||
<file>mockfiles/images/move_active.png</file>
|
||||
<file>mockfiles/images/move_active@2x.png</file>
|
||||
<file>mockfiles/images/move_selected.png</file>
|
||||
<file>mockfiles/images/move_selected@2x.png</file>
|
||||
<file>mockfiles/images/rotate_active.png</file>
|
||||
<file>mockfiles/images/rotate_active@2x.png</file>
|
||||
<file>mockfiles/images/rotate_selected.png</file>
|
||||
<file>mockfiles/images/rotate_selected@2x.png</file>
|
||||
<file>mockfiles/images/scale_active.png</file>
|
||||
<file>mockfiles/images/scale_active@2x.png</file>
|
||||
<file>mockfiles/images/scale_selected.png</file>
|
||||
<file>mockfiles/images/scale_selected@2x.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@@ -32,8 +32,7 @@ Column {
|
||||
anchors.right: parent.right
|
||||
|
||||
StandardTextSection {
|
||||
showIsWrapping: true
|
||||
useLineEdit: true
|
||||
showVerticalAlignment: true
|
||||
showFormatProperty: true
|
||||
}
|
||||
|
||||
@@ -62,6 +61,18 @@ Column {
|
||||
}
|
||||
}
|
||||
|
||||
Section {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
caption: qsTr("Selected Text Color")
|
||||
|
||||
ColorEditor {
|
||||
caption: qsTr("Selected Text Color")
|
||||
backendValue: backendValues.selectedTextColor
|
||||
supportGradient: false
|
||||
}
|
||||
}
|
||||
|
||||
FontSection {
|
||||
showStyle: false
|
||||
}
|
||||
|
@@ -39,6 +39,16 @@ Section {
|
||||
rows: 4
|
||||
columns: 2
|
||||
|
||||
Label {
|
||||
text: qsTr("Mouse selection mode")
|
||||
}
|
||||
ComboBox {
|
||||
Layout.fillWidth: true
|
||||
backendValue: backendValues.mouseSelectionMode
|
||||
scope: "TextInput"
|
||||
model: ["SelectCharacters", "SelectWords"]
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: textInputSection.isTextInput
|
||||
text: qsTr("Input mask")
|
||||
@@ -48,6 +58,7 @@ Section {
|
||||
visible: textInputSection.isTextInput
|
||||
backendValue: backendValues.inputMask
|
||||
Layout.fillWidth: true
|
||||
showTranslateCheckBox: false
|
||||
}
|
||||
|
||||
Label {
|
||||
@@ -73,6 +84,33 @@ Section {
|
||||
visible: textInputSection.isTextInput
|
||||
backendValue: backendValues.passwordCharacter
|
||||
Layout.fillWidth: true
|
||||
showTranslateCheckBox: false
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: !textInputSection.isTextInput
|
||||
text: qsTr("Tab stop distance")
|
||||
tooltip: qsTr("Sets the default distance, in device units, between tab stops.")
|
||||
}
|
||||
SpinBox {
|
||||
visible: !textInputSection.isTextInput
|
||||
Layout.fillWidth: true
|
||||
backendValue: backendValues.tabStopDistance
|
||||
maximumValue: 200
|
||||
minimumValue: 0
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: !textInputSection.isTextInput
|
||||
text: qsTr("Text margin")
|
||||
tooltip: qsTr("Sets the margin, in pixels, around the text in the TextEdit..")
|
||||
}
|
||||
SpinBox {
|
||||
visible: !textInputSection.isTextInput
|
||||
Layout.fillWidth: true
|
||||
backendValue: backendValues.textMargin
|
||||
maximumValue: 200
|
||||
minimumValue: -200
|
||||
}
|
||||
|
||||
Label {
|
||||
@@ -101,10 +139,36 @@ Section {
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
visible: textInputSection.isTextInput
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Auto scroll")
|
||||
backendValue: backendValues.autoScroll
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Overwrite mode")
|
||||
backendValue: backendValues.overwriteMode
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Persistent selection")
|
||||
backendValue: backendValues.persistentSelection
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Select by mouse")
|
||||
backendValue: backendValues.selectByMouse
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
visible: !textInputSection.isTextInput
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Select by keyboard")
|
||||
backendValue: backendValues.selectByKeyboard
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -32,8 +32,7 @@ Column {
|
||||
anchors.right: parent.right
|
||||
|
||||
StandardTextSection {
|
||||
useLineEdit: false
|
||||
showIsWrapping: false
|
||||
showVerticalAlignment: true
|
||||
}
|
||||
|
||||
Section {
|
||||
@@ -61,6 +60,18 @@ Column {
|
||||
}
|
||||
}
|
||||
|
||||
Section {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
caption: qsTr("Selected Text Color")
|
||||
|
||||
ColorEditor {
|
||||
caption: qsTr("Selected Text Color")
|
||||
backendValue: backendValues.selectedTextColor
|
||||
supportGradient: false
|
||||
}
|
||||
}
|
||||
|
||||
FontSection {
|
||||
showStyle: false
|
||||
}
|
||||
|
@@ -32,12 +32,11 @@ Column {
|
||||
anchors.right: parent.right
|
||||
|
||||
StandardTextSection {
|
||||
useLineEdit: true
|
||||
showIsWrapping: true
|
||||
showVerticalAlignment: true
|
||||
showFormatProperty: true
|
||||
showElide: true
|
||||
showFontSizeMode: true
|
||||
showLineHeight: true
|
||||
}
|
||||
|
||||
Section {
|
||||
|
@@ -35,9 +35,10 @@ Section {
|
||||
property bool showIsWrapping: false
|
||||
property bool showElide: false
|
||||
property bool showVerticalAlignment: false
|
||||
property bool useLineEdit: true
|
||||
property bool showFormatProperty: false
|
||||
property bool showFontSizeMode: false
|
||||
property bool showLineHeight: false
|
||||
|
||||
|
||||
SectionLayout {
|
||||
columns: 2
|
||||
@@ -46,7 +47,6 @@ Section {
|
||||
text: qsTr("Text")
|
||||
}
|
||||
LineEdit {
|
||||
//visible: useLineEdit
|
||||
backendValue: backendValues.text
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
@@ -119,10 +119,12 @@ Section {
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: showFontSizeMode
|
||||
text: qsTr("Font size mode")
|
||||
toolTip: qsTr("Specifies how the font size of the displayed text is determined.")
|
||||
}
|
||||
ComboBox {
|
||||
visible: showFontSizeMode
|
||||
scope: "Text"
|
||||
model: ["FixedSize", "HorizontalFit", "VerticalFit", "Fit"]
|
||||
backendValue: backendValues.fontSizeMode
|
||||
@@ -131,11 +133,13 @@ Section {
|
||||
|
||||
|
||||
Label {
|
||||
visible: showLineHeight
|
||||
text: qsTr("Line height")
|
||||
tooltip: qsTr("Sets the line height for the text.")
|
||||
}
|
||||
|
||||
SpinBox {
|
||||
visible: showLineHeight
|
||||
Layout.fillWidth: true
|
||||
backendValue: (backendValues.lineHeight === undefined) ? dummyBackendValue : backendValues.lineHeight
|
||||
maximumValue: 500
|
||||
|
@@ -114,6 +114,7 @@ Rectangle {
|
||||
var y = root.mapToGlobal(0,0).y - 32
|
||||
bindingEditor.showWidget(x, y)
|
||||
bindingEditor.text = delegateWhenConditionString
|
||||
bindingEditor.prepareBindings()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -205,6 +206,8 @@ Rectangle {
|
||||
|
||||
id: bindingEditor
|
||||
|
||||
stateModelNodeProperty: statesEditorModel.stateModelNode()
|
||||
|
||||
onRejected: {
|
||||
hideWidget()
|
||||
}
|
||||
|
@@ -61,6 +61,16 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"trDisplayName": "Kit Selection",
|
||||
"trShortTitle": "Kits",
|
||||
"typeId": "Kits",
|
||||
"enabled": "%{JS: !value('IsSubproject')}",
|
||||
"data": {
|
||||
"projectFilePath": "%{ProjectFile}",
|
||||
"requiredFeatures": [ "QtSupport.Wizards.FeatureQt.5"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"trDisplayName": "Project Management",
|
||||
"trShortTitle": "Summary",
|
||||
@@ -84,7 +94,8 @@
|
||||
},
|
||||
{
|
||||
"source": "plugin.cpp",
|
||||
"target": "%{PluginSrc}"
|
||||
"target": "%{PluginSrc}",
|
||||
"openInEditor": true
|
||||
},
|
||||
{
|
||||
"source": "plugin.h",
|
||||
|
@@ -870,6 +870,7 @@ FilePath AndroidConfig::qtLiveApkPath() const
|
||||
///////////////////////////////////
|
||||
void AndroidConfigurations::setConfig(const AndroidConfig &devConfigs)
|
||||
{
|
||||
emit m_instance->aboutToUpdate();
|
||||
m_instance->m_config = devConfigs;
|
||||
|
||||
m_instance->save();
|
||||
|
@@ -209,6 +209,7 @@ public:
|
||||
static QProcessEnvironment toolsEnvironment(const AndroidConfig &config);
|
||||
|
||||
signals:
|
||||
void aboutToUpdate();
|
||||
void updated();
|
||||
|
||||
private:
|
||||
|
@@ -288,8 +288,8 @@ QJsonObject AndroidManager::deploymentSettings(const Target *target)
|
||||
|
||||
Utils::FilePath AndroidManager::dirPath(const ProjectExplorer::Target *target)
|
||||
{
|
||||
if (target->activeBuildConfiguration())
|
||||
return target->activeBuildConfiguration()->buildDirectory().pathAppended(Constants::ANDROID_BUILDDIRECTORY);
|
||||
if (auto *bc = target->activeBuildConfiguration())
|
||||
return bc->buildDirectory().pathAppended(Constants::ANDROID_BUILDDIRECTORY);
|
||||
return Utils::FilePath();
|
||||
}
|
||||
|
||||
|
@@ -49,7 +49,12 @@ namespace Internal {
|
||||
|
||||
AndroidQtVersion::AndroidQtVersion()
|
||||
: QtSupport::BaseQtVersion()
|
||||
, m_guard(std::make_unique<QObject>())
|
||||
{
|
||||
QObject::connect(AndroidConfigurations::instance(),
|
||||
&AndroidConfigurations::aboutToUpdate,
|
||||
m_guard.get(),
|
||||
[this] { resetCache(); });
|
||||
}
|
||||
|
||||
bool AndroidQtVersion::isValid() const
|
||||
|
@@ -58,6 +58,7 @@ public:
|
||||
protected:
|
||||
void parseMkSpec(ProFileEvaluator *) const override;
|
||||
private:
|
||||
std::unique_ptr<QObject> m_guard;
|
||||
mutable QStringList m_androidAbis;
|
||||
mutable int m_minNdk = -1;
|
||||
};
|
||||
|
@@ -67,7 +67,7 @@ using namespace Utils;
|
||||
namespace Android {
|
||||
namespace Internal {
|
||||
|
||||
static const QString pidScript = "pidof -s \"%1\"";
|
||||
static const QString pidScript = "pidof -s '%1'";
|
||||
static const QString pidScriptPreNougat = QStringLiteral("for p in /proc/[0-9]*; "
|
||||
"do cat <$p/cmdline && echo :${p##*/}; done");
|
||||
static const QString pidPollingScript = QStringLiteral("while [ -d /proc/%1 ]; do sleep 1; done");
|
||||
@@ -288,8 +288,8 @@ bool AndroidRunnerWorker::uploadGdbServer()
|
||||
qCDebug(androidRunWorkerLog) << "Gdbserver copy from temp directory failed";
|
||||
return false;
|
||||
}
|
||||
QTC_ASSERT(runAdb({"shell", "run-as", m_packageName, "chmod", "+x", "./gdbserver"}),
|
||||
qCDebug(androidRunWorkerLog) << "Gdbserver chmod +x failed.");
|
||||
QTC_ASSERT(runAdb({"shell", "run-as", m_packageName, "chmod", "777", "./gdbserver"}),
|
||||
qCDebug(androidRunWorkerLog) << "Gdbserver chmod 777 failed.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -34,7 +34,8 @@ namespace GTestUtils {
|
||||
|
||||
static const QStringList valid = {
|
||||
QStringLiteral("TEST"), QStringLiteral("TEST_F"), QStringLiteral("TEST_P"),
|
||||
QStringLiteral("TYPED_TEST"), QStringLiteral("TYPED_TEST_P")
|
||||
QStringLiteral("TYPED_TEST"), QStringLiteral("TYPED_TEST_P"),
|
||||
QStringLiteral("GTEST_TEST")
|
||||
};
|
||||
|
||||
bool isGTestMacro(const QString ¯o)
|
||||
|
@@ -46,7 +46,9 @@
|
||||
#include <coreplugin/icore.h>
|
||||
#include <projectexplorer/buildmanager.h>
|
||||
#include <projectexplorer/projectexplorer.h>
|
||||
#include <texteditor/fontsettings.h>
|
||||
#include <texteditor/texteditor.h>
|
||||
#include <texteditor/texteditorsettings.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/theme/theme.h>
|
||||
#include <utils/utilsicons.h>
|
||||
@@ -131,9 +133,7 @@ TestResultsPane::TestResultsPane(QObject *parent) :
|
||||
|
||||
m_textOutput = new QPlainTextEdit;
|
||||
m_textOutput->setPalette(pal);
|
||||
QFont font("monospace");
|
||||
font.setStyleHint(QFont::TypeWriter);
|
||||
m_textOutput->setFont(font);
|
||||
m_textOutput->setFont(TextEditor::TextEditorSettings::fontSettings().font());
|
||||
m_textOutput->setWordWrapMode(QTextOption::WordWrap);
|
||||
m_textOutput->setReadOnly(true);
|
||||
new OutputHighlighter(m_textOutput->document());
|
||||
|
@@ -1179,7 +1179,6 @@ QString BinEditorWidget::toolTip(const QHelpEvent *helpEvent) const
|
||||
if (!pos)
|
||||
return QString();
|
||||
selStart = pos.value();
|
||||
selEnd = selStart;
|
||||
byteCount = 1;
|
||||
}
|
||||
|
||||
|
@@ -315,15 +315,11 @@ static ::Utils::FilePath compilerPath(const CppTools::ProjectPart &projectPart)
|
||||
|
||||
static ::Utils::FilePath buildDirectory(const ProjectExplorer::Project &project)
|
||||
{
|
||||
ProjectExplorer::Target *target = project.activeTarget();
|
||||
if (!target)
|
||||
return ::Utils::FilePath();
|
||||
|
||||
ProjectExplorer::BuildConfiguration *buildConfig = target->activeBuildConfiguration();
|
||||
if (!buildConfig)
|
||||
return ::Utils::FilePath();
|
||||
|
||||
return buildConfig->buildDirectory();
|
||||
if (auto *target = project.activeTarget()) {
|
||||
if (auto *bc = target->activeBuildConfiguration())
|
||||
return bc->buildDirectory();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
static QStringList projectPartArguments(const ProjectPart &projectPart)
|
||||
|
@@ -495,7 +495,7 @@ void ClangToolRunWorker::finalize()
|
||||
QString msg = tr("%1: Not all files could be analyzed.").arg(toolName);
|
||||
TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
|
||||
Target *target = runControl()->target();
|
||||
if (target && !target->activeBuildConfiguration()->buildDirectory().exists()
|
||||
if (target && target->activeBuildConfiguration() && !target->activeBuildConfiguration()->buildDirectory().exists()
|
||||
&& !m_runSettings.buildBeforeAnalysis()) {
|
||||
msg = tr("%1: You might need to build the project to generate or update source "
|
||||
"files. To build automatically, enable \"Build the project before starting "
|
||||
|
@@ -159,7 +159,7 @@ void ClangToolsUnitTests::testProject_data()
|
||||
// Test that tidy and clazy diagnostics are emitted for the same project.
|
||||
addTestRow("clangtidy_clazy/clangtidy_clazy.pro",
|
||||
1 /*tidy*/ + 1 /*clazy*/,
|
||||
configFor("misc-unconventional-assign-operator", "base-class-event"));
|
||||
configFor("misc-unconventional-assign-operator", "qgetenv"));
|
||||
}
|
||||
|
||||
void ClangToolsUnitTests::addTestRow(const QByteArray &relativeFilePath,
|
||||
|
@@ -23,19 +23,11 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QByteArray>
|
||||
#include <QtGlobal>
|
||||
|
||||
// -Wclazy-ctor-missing-parent-argument
|
||||
class TestObject : public QObject
|
||||
void test()
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TestObject();
|
||||
|
||||
bool event(QEvent *) override
|
||||
{
|
||||
// -Wclazy-base-class-event
|
||||
return false;
|
||||
// -Wclazy-qgetenv
|
||||
qgetenv("Foo").isEmpty();
|
||||
}
|
||||
};
|
||||
|
@@ -27,6 +27,8 @@
|
||||
|
||||
#include "cmakebuildconfiguration.h"
|
||||
#include "cmakekitinformation.h"
|
||||
#include "cmakeprojectplugin.h"
|
||||
#include "cmakespecificsettings.h"
|
||||
#include "cmaketoolmanager.h"
|
||||
|
||||
#include <projectexplorer/kit.h>
|
||||
@@ -61,6 +63,10 @@ BuildDirParameters::BuildDirParameters(CMakeBuildConfiguration *bc)
|
||||
if (Utils::HostOsInfo::isAnyUnixHost())
|
||||
environment.set("ICECC", "no");
|
||||
|
||||
CMakeSpecificSettings *settings = CMakeProjectPlugin::projectTypeSpecificSettings();
|
||||
if (!settings->ninjaPath().isEmpty())
|
||||
environment.appendOrSetPath(settings->ninjaPath().toString());
|
||||
|
||||
cmakeToolId = CMakeKitAspect::cmakeToolId(k);
|
||||
|
||||
auto tc = ToolChainKitAspect::toolChain(k, Constants::CXX_LANGUAGE_ID);
|
||||
|
@@ -31,20 +31,24 @@ namespace Internal {
|
||||
namespace {
|
||||
static const char SETTINGS_KEY[] = "CMakeSpecificSettings";
|
||||
static const char AFTER_ADD_FILE_ACTION_KEY[] = "ProjectPopupSetting";
|
||||
static const char NINJA_PATH[] = "NinjaPath";
|
||||
}
|
||||
|
||||
void CMakeSpecificSettings::fromSettings(QSettings *settings)
|
||||
{
|
||||
const QString rootKey = QString(SETTINGS_KEY) + '/';
|
||||
afterAddFileToProjectSetting = static_cast<AfterAddFileAction>(
|
||||
m_afterAddFileToProjectSetting = static_cast<AfterAddFileAction>(
|
||||
settings->value(rootKey + AFTER_ADD_FILE_ACTION_KEY,
|
||||
static_cast<int>(AfterAddFileAction::ASK_USER)).toInt());
|
||||
|
||||
m_ninjaPath = Utils::FilePath::fromUserInput(
|
||||
settings->value(rootKey + NINJA_PATH, QString()).toString());
|
||||
}
|
||||
|
||||
void CMakeSpecificSettings::toSettings(QSettings *settings) const
|
||||
{
|
||||
settings->beginGroup(QString(SETTINGS_KEY));
|
||||
settings->setValue(QString(AFTER_ADD_FILE_ACTION_KEY), static_cast<int>(afterAddFileToProjectSetting));
|
||||
settings->setValue(QString(AFTER_ADD_FILE_ACTION_KEY), static_cast<int>(m_afterAddFileToProjectSetting));
|
||||
settings->endGroup();
|
||||
}
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include <utils/fileutils.h>
|
||||
#include <QSettings>
|
||||
|
||||
namespace CMakeProjectManager {
|
||||
@@ -42,11 +43,14 @@ public:
|
||||
void fromSettings(QSettings *settings);
|
||||
void toSettings(QSettings *settings) const;
|
||||
|
||||
void setAfterAddFileSetting(AfterAddFileAction settings) { afterAddFileToProjectSetting = settings; }
|
||||
AfterAddFileAction afterAddFileSetting() const { return afterAddFileToProjectSetting; }
|
||||
void setAfterAddFileSetting(AfterAddFileAction settings) { m_afterAddFileToProjectSetting = settings; }
|
||||
AfterAddFileAction afterAddFileSetting() const { return m_afterAddFileToProjectSetting; }
|
||||
|
||||
Utils::FilePath ninjaPath() const { return m_ninjaPath; }
|
||||
|
||||
private:
|
||||
AfterAddFileAction afterAddFileToProjectSetting;
|
||||
AfterAddFileAction m_afterAddFileToProjectSetting;
|
||||
Utils::FilePath m_ninjaPath;
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -107,7 +107,7 @@ class IntrospectionData
|
||||
{
|
||||
public:
|
||||
bool m_didAttemptToRun = false;
|
||||
bool m_didRun = false;
|
||||
bool m_didRun = true;
|
||||
bool m_hasServerMode = false;
|
||||
|
||||
bool m_queriedServerMode = false;
|
||||
@@ -207,26 +207,17 @@ bool CMakeTool::isValid() const
|
||||
return m_introspection->m_didRun;
|
||||
}
|
||||
|
||||
Utils::SynchronousProcessResponse CMakeTool::run(const QStringList &args, bool mayFail) const
|
||||
Utils::SynchronousProcessResponse CMakeTool::run(const QStringList &args, int timeoutS) const
|
||||
{
|
||||
if (m_introspection->m_didAttemptToRun && !m_introspection->m_didRun) {
|
||||
Utils::SynchronousProcessResponse response;
|
||||
response.result = Utils::SynchronousProcessResponse::StartFailed;
|
||||
return response;
|
||||
}
|
||||
|
||||
Utils::SynchronousProcess cmake;
|
||||
cmake.setTimeoutS(1);
|
||||
cmake.setTimeoutS(timeoutS);
|
||||
cmake.setFlags(Utils::SynchronousProcess::UnixTerminalDisabled);
|
||||
Utils::Environment env = Utils::Environment::systemEnvironment();
|
||||
Utils::Environment::setupEnglishOutput(&env);
|
||||
cmake.setProcessEnvironment(env.toProcessEnvironment());
|
||||
cmake.setTimeOutMessageBoxEnabled(false);
|
||||
|
||||
Utils::SynchronousProcessResponse response = cmake.runBlocking({cmakeExecutable(), args});
|
||||
m_introspection->m_didAttemptToRun = true;
|
||||
m_introspection->m_didRun = mayFail ? true : (response.result == Utils::SynchronousProcessResponse::Finished);
|
||||
return response;
|
||||
return cmake.runBlocking({cmakeExecutable(), args});
|
||||
}
|
||||
|
||||
QVariantMap CMakeTool::toMap() const
|
||||
@@ -298,21 +289,21 @@ QList<CMakeTool::Generator> CMakeTool::supportedGenerators() const
|
||||
|
||||
TextEditor::Keywords CMakeTool::keywords()
|
||||
{
|
||||
if (m_introspection->m_functions.isEmpty()) {
|
||||
if (m_introspection->m_functions.isEmpty() && m_introspection->m_didRun) {
|
||||
Utils::SynchronousProcessResponse response;
|
||||
response = run({"--help-command-list"});
|
||||
response = run({"--help-command-list"}, 5);
|
||||
if (response.result == Utils::SynchronousProcessResponse::Finished)
|
||||
m_introspection->m_functions = response.stdOut().split('\n');
|
||||
|
||||
response = run({"--help-commands"});
|
||||
response = run({"--help-commands"}, 5);
|
||||
if (response.result == Utils::SynchronousProcessResponse::Finished)
|
||||
parseFunctionDetailsOutput(response.stdOut());
|
||||
|
||||
response = run({"--help-property-list"});
|
||||
response = run({"--help-property-list"}, 5);
|
||||
if (response.result == Utils::SynchronousProcessResponse::Finished)
|
||||
m_introspection->m_variables = parseVariableOutput(response.stdOut());
|
||||
|
||||
response = run({"--help-variable-list"});
|
||||
response = run({"--help-variable-list"}, 5);
|
||||
if (response.result == Utils::SynchronousProcessResponse::Finished) {
|
||||
m_introspection->m_variables.append(parseVariableOutput(response.stdOut()));
|
||||
m_introspection->m_variables = Utils::filteredUnique(m_introspection->m_variables);
|
||||
@@ -417,12 +408,16 @@ Utils::FilePath CMakeTool::searchQchFile(const Utils::FilePath &executable)
|
||||
|
||||
void CMakeTool::readInformation(CMakeTool::QueryType type) const
|
||||
{
|
||||
if (!m_introspection->m_didRun && m_introspection->m_didAttemptToRun)
|
||||
return;
|
||||
|
||||
m_introspection->m_didAttemptToRun = true;
|
||||
|
||||
if (!m_introspection->m_triedCapabilities) {
|
||||
fetchFromCapabilities();
|
||||
m_introspection->m_triedCapabilities = true;
|
||||
m_introspection->m_queriedServerMode = true; // Got added after "-E capabilities" support!
|
||||
}
|
||||
|
||||
} else {
|
||||
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()))
|
||||
@@ -438,6 +433,7 @@ void CMakeTool::readInformation(CMakeTool::QueryType type) const
|
||||
QTC_ASSERT(false, return );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static QStringList parseDefinition(const QString &definition)
|
||||
{
|
||||
@@ -533,8 +529,10 @@ QStringList CMakeTool::parseVariableOutput(const QString &output)
|
||||
void CMakeTool::fetchGeneratorsFromHelp() const
|
||||
{
|
||||
Utils::SynchronousProcessResponse response = run({"--help"});
|
||||
if (response.result != Utils::SynchronousProcessResponse::Finished)
|
||||
return;
|
||||
m_introspection->m_didRun = m_introspection->m_didRun
|
||||
&& response.result == Utils::SynchronousProcessResponse::Finished;
|
||||
|
||||
if (response.result == Utils::SynchronousProcessResponse::Finished)
|
||||
parseGeneratorsFromHelp(response.stdOut().split('\n'));
|
||||
}
|
||||
|
||||
@@ -588,9 +586,11 @@ void CMakeTool::parseGeneratorsFromHelp(const QStringList &lines) const
|
||||
void CMakeTool::fetchVersionFromVersionOutput() const
|
||||
{
|
||||
Utils::SynchronousProcessResponse response = run({"--version"});
|
||||
if (response.result != Utils::SynchronousProcessResponse::Finished)
|
||||
return;
|
||||
|
||||
m_introspection->m_didRun = m_introspection->m_didRun
|
||||
&& response.result == Utils::SynchronousProcessResponse::Finished;
|
||||
|
||||
if (response.result == Utils::SynchronousProcessResponse::Finished)
|
||||
parseVersionFormVersionOutput(response.stdOut().split('\n'));
|
||||
}
|
||||
|
||||
@@ -612,10 +612,9 @@ void CMakeTool::parseVersionFormVersionOutput(const QStringList &lines) const
|
||||
|
||||
void CMakeTool::fetchFromCapabilities() const
|
||||
{
|
||||
Utils::SynchronousProcessResponse response = run({"-E", "capabilities"}, true);
|
||||
if (response.result != Utils::SynchronousProcessResponse::Finished)
|
||||
return;
|
||||
Utils::SynchronousProcessResponse response = run({"-E", "capabilities"});
|
||||
|
||||
if (response.result == Utils::SynchronousProcessResponse::Finished)
|
||||
parseFromCapabilities(response.stdOut());
|
||||
}
|
||||
|
||||
|
@@ -126,7 +126,7 @@ private:
|
||||
};
|
||||
void readInformation(QueryType type) const;
|
||||
|
||||
Utils::SynchronousProcessResponse run(const QStringList &args, bool mayFail = false) const;
|
||||
Utils::SynchronousProcessResponse run(const QStringList &args, int timeoutS = 1) const;
|
||||
void parseFunctionDetailsOutput(const QString &output);
|
||||
QStringList parseVariableOutput(const QString &output);
|
||||
|
||||
|
@@ -735,7 +735,7 @@ EditorView *SplitterOrView::takeView()
|
||||
return oldView;
|
||||
}
|
||||
|
||||
void SplitterOrView::split(Qt::Orientation orientation)
|
||||
void SplitterOrView::split(Qt::Orientation orientation, bool activateView)
|
||||
{
|
||||
Q_ASSERT(m_view && m_splitter == nullptr);
|
||||
m_splitter = new MiniSplitter(this);
|
||||
@@ -766,6 +766,7 @@ void SplitterOrView::split(Qt::Orientation orientation)
|
||||
otherView->view()->setCloseSplitIcon(Utils::Icons::CLOSE_SPLIT_BOTTOM.icon());
|
||||
}
|
||||
|
||||
if (activateView)
|
||||
EditorManagerPrivate::activateView(otherView->view());
|
||||
emit splitStateChanged();
|
||||
}
|
||||
@@ -933,7 +934,7 @@ void SplitterOrView::restoreState(const QByteArray &state)
|
||||
qint32 orientation;
|
||||
QByteArray splitter, first, second;
|
||||
stream >> orientation >> splitter >> first >> second;
|
||||
split((Qt::Orientation)orientation);
|
||||
split((Qt::Orientation) orientation, false);
|
||||
m_splitter->restoreState(splitter);
|
||||
static_cast<SplitterOrView*>(m_splitter->widget(0))->restoreState(first);
|
||||
static_cast<SplitterOrView*>(m_splitter->widget(1))->restoreState(second);
|
||||
|
@@ -173,7 +173,7 @@ public:
|
||||
explicit SplitterOrView(EditorView *view);
|
||||
~SplitterOrView() override;
|
||||
|
||||
void split(Qt::Orientation orientation);
|
||||
void split(Qt::Orientation orientation, bool activateView = true);
|
||||
void unsplit();
|
||||
|
||||
inline bool isView() const { return m_view != nullptr; }
|
||||
|
@@ -116,7 +116,7 @@ QString clangIncludeDirectory(const QString &clangVersion, const QString &clangR
|
||||
#else
|
||||
Q_UNUSED(clangVersion)
|
||||
Q_UNUSED(clangResourceDirectory)
|
||||
return CLANG_RESOURCE_DIR;
|
||||
return {CLANG_RESOURCE_DIR};
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -457,33 +457,31 @@ bool StackHandler::contextMenuEvent(const ItemViewEvent &ev)
|
||||
|
||||
void StackHandler::copyContentsToClipboard()
|
||||
{
|
||||
QString str;
|
||||
int n = rowCount();
|
||||
int m = columnCount(QModelIndex());
|
||||
const int m = columnCount(QModelIndex());
|
||||
QVector<int> largestColumnWidths(m, 0);
|
||||
|
||||
// First, find the widths of the largest columns,
|
||||
// so that we can print them out nicely aligned.
|
||||
for (int i = 0; i != n; ++i) {
|
||||
forItemsAtLevel<2>([m, &largestColumnWidths](StackFrameItem *item) {
|
||||
for (int j = 0; j < m; ++j) {
|
||||
const QModelIndex idx = index(i, j);
|
||||
const int columnWidth = data(idx, Qt::DisplayRole).toString().size();
|
||||
const int columnWidth = item->data(j, Qt::DisplayRole).toString().size();
|
||||
if (columnWidth > largestColumnWidths.at(j))
|
||||
largestColumnWidths[j] = columnWidth;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
for (int i = 0; i != n; ++i) {
|
||||
QString str;
|
||||
forItemsAtLevel<2>([m, largestColumnWidths, &str](StackFrameItem *item) {
|
||||
for (int j = 0; j != m; ++j) {
|
||||
QModelIndex idx = index(i, j);
|
||||
const QString columnEntry = data(idx, Qt::DisplayRole).toString();
|
||||
const QString columnEntry = item->data(j, Qt::DisplayRole).toString();
|
||||
str += columnEntry;
|
||||
const int difference = largestColumnWidths.at(j) - columnEntry.size();
|
||||
// Add one extra space between columns.
|
||||
str += QString().fill(' ', difference > 0 ? difference + 1 : 1);
|
||||
str += QString(qMax(difference, 0) + 1, QChar(' '));
|
||||
}
|
||||
str += '\n';
|
||||
}
|
||||
});
|
||||
|
||||
QClipboard *clipboard = QApplication::clipboard();
|
||||
clipboard->setText(str, QClipboard::Selection);
|
||||
clipboard->setText(str, QClipboard::Clipboard);
|
||||
|
@@ -5,7 +5,7 @@ project(QLiteHtml)
|
||||
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/litehtml/CMakeLists.txt)
|
||||
set(ORIG_FPIC ${CMAKE_POSITION_INDEPENDENT_CODE})
|
||||
if (WIN32)
|
||||
set(LITEHTML_UTF8 ON)
|
||||
set(LITEHTML_UTF8 ON CACHE BOOL "")
|
||||
endif()
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
add_subdirectory(litehtml)
|
||||
|
@@ -503,9 +503,9 @@ void LanguageClientManager::findLinkAt(TextEditor::TextDocument *document,
|
||||
}
|
||||
}
|
||||
});
|
||||
for (Client *interface : reachableClients()) {
|
||||
if (interface->findLinkAt(request))
|
||||
m_exclusiveRequests[request.id()] << interface;
|
||||
if (Client *client = clientForUri(uri)) {
|
||||
if (client->reachable())
|
||||
client->findLinkAt(request);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -28,23 +28,15 @@
|
||||
namespace McuSupport {
|
||||
namespace Constants {
|
||||
|
||||
const char TOOLCHAIN_TYPEID[] = "McuSupport.ToolChain.ARM-GCC";
|
||||
const char DEVICE_TYPE[] = "McuSupport.DeviceType";
|
||||
const char DEVICE_ID[] = "McuSupport.Device";
|
||||
const char MCUSUPPORT_QT_VERSION[] = "Qt4ProjectManager.QtVersion.McuSupport";
|
||||
const char RUNCONFIGURATION[] = "McuSupport.RunConfiguration";
|
||||
const char SETTINGS_ID[] = "CC.McuSupport.Configuration";
|
||||
const char KIT_BOARD_VENDOR_KEY[] = "McuSupport.BoardVendor";
|
||||
const char KIT_BOARD_MODEL_KEY[] = "McuSupport.BoardModel";
|
||||
|
||||
const char ENVVAR_ARMGCC_DIR[] = "ARMGCC_DIR";
|
||||
const char ENVVAR_STM32CUBE_FW_F7_SDK_PATH[] = "STM32Cube_FW_F7_SDK_PATH";
|
||||
const char KIT_MCUTARGET_VENDOR_KEY[] = "McuSupport.McuTargetVendor";
|
||||
const char KIT_MCUTARGET_MODEL_KEY[] = "McuSupport.McuTargetModel";
|
||||
|
||||
const char SETTINGS_GROUP[] = "McuSupport";
|
||||
const char SETTINGS_KEY_PACKAGE_PREFIX[] = "package_";
|
||||
const char SETTINGS_KEY_PACKAGE_ARMGCC[] = "ArmGcc";
|
||||
const char SETTINGS_KEY_STM32CUBE_FW_F7_SDK_PATH[] = "STM32Cube_FW_F7_SDK_PATH";
|
||||
const char SETTINGS_KEY_STM32CUBE_PROGRAMMER_PATH[] = "STM32Cube_Cube_Programmer_Path";
|
||||
const char SETTINGS_KEY_PACKAGE_PREFIX[] = "Package_";
|
||||
|
||||
} // namespace McuSupport
|
||||
} // namespace Constants
|
||||
|
@@ -54,7 +54,7 @@
|
||||
namespace McuSupport {
|
||||
namespace Internal {
|
||||
|
||||
PackageOptions::PackageOptions(const QString &label, const QString &defaultPath,
|
||||
McuPackage::McuPackage(const QString &label, const QString &defaultPath,
|
||||
const QString &detectionPath, const QString &settingsKey)
|
||||
: m_label(label)
|
||||
, m_defaultPath(defaultPath)
|
||||
@@ -68,33 +68,28 @@ PackageOptions::PackageOptions(const QString &label, const QString &defaultPath,
|
||||
s->endGroup();
|
||||
}
|
||||
|
||||
QString PackageOptions::path() const
|
||||
QString McuPackage::path() const
|
||||
{
|
||||
return QFileInfo(m_fileChooser->path() + m_relativePathModifier).absoluteFilePath();
|
||||
}
|
||||
|
||||
QString PackageOptions::label() const
|
||||
QString McuPackage::label() const
|
||||
{
|
||||
return m_label;
|
||||
}
|
||||
|
||||
QString PackageOptions::detectionPath() const
|
||||
QString McuPackage::detectionPath() const
|
||||
{
|
||||
return m_detectionPath;
|
||||
}
|
||||
|
||||
QWidget *PackageOptions::widget()
|
||||
QWidget *McuPackage::widget()
|
||||
{
|
||||
if (m_widget)
|
||||
return m_widget;
|
||||
|
||||
m_widget = new QWidget;
|
||||
m_fileChooser = new Utils::PathChooser;
|
||||
QObject::connect(m_fileChooser, &Utils::PathChooser::pathChanged,
|
||||
[this](){
|
||||
updateStatus();
|
||||
emit changed();
|
||||
});
|
||||
|
||||
auto layout = new QGridLayout(m_widget);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
@@ -119,41 +114,49 @@ QWidget *PackageOptions::widget()
|
||||
layout->addWidget(m_statusIcon, 1, 0);
|
||||
layout->addWidget(m_statusLabel, 1, 1, 1, -1);
|
||||
|
||||
m_fileChooser->setPath(m_path); // Triggers updateStatus() call
|
||||
m_fileChooser->setPath(m_path);
|
||||
|
||||
QObject::connect(m_fileChooser, &Utils::PathChooser::pathChanged,
|
||||
[this](){
|
||||
updateStatus();
|
||||
emit changed();
|
||||
});
|
||||
|
||||
updateStatus();
|
||||
return m_widget;
|
||||
}
|
||||
|
||||
PackageOptions::Status PackageOptions::status() const
|
||||
McuPackage::Status McuPackage::status() const
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
|
||||
void PackageOptions::setDownloadUrl(const QString &url)
|
||||
void McuPackage::setDownloadUrl(const QString &url)
|
||||
{
|
||||
m_downloadUrl = url;
|
||||
}
|
||||
|
||||
void PackageOptions::setEnvironmentVariableName(const QString &name)
|
||||
void McuPackage::setEnvironmentVariableName(const QString &name)
|
||||
{
|
||||
m_environmentVariableName = name;
|
||||
}
|
||||
|
||||
QString PackageOptions::environmentVariableName() const
|
||||
QString McuPackage::environmentVariableName() const
|
||||
{
|
||||
return m_environmentVariableName;
|
||||
}
|
||||
|
||||
void PackageOptions::setAddToPath(bool addToPath)
|
||||
void McuPackage::setAddToPath(bool addToPath)
|
||||
{
|
||||
m_addToPath = addToPath;
|
||||
}
|
||||
|
||||
bool PackageOptions::addToPath() const
|
||||
bool McuPackage::addToPath() const
|
||||
{
|
||||
return m_addToPath;
|
||||
}
|
||||
|
||||
void PackageOptions::writeToSettings() const
|
||||
void McuPackage::writeToSettings() const
|
||||
{
|
||||
if (m_path.compare(m_defaultPath) == 0)
|
||||
return;
|
||||
@@ -163,12 +166,12 @@ void PackageOptions::writeToSettings() const
|
||||
s->endGroup();
|
||||
}
|
||||
|
||||
void PackageOptions::setRelativePathModifier(const QString &path)
|
||||
void McuPackage::setRelativePathModifier(const QString &path)
|
||||
{
|
||||
m_relativePathModifier = path;
|
||||
}
|
||||
|
||||
void PackageOptions::updateStatus()
|
||||
void McuPackage::updateStatus()
|
||||
{
|
||||
m_path = m_fileChooser->rawPath();
|
||||
const bool validPath = m_fileChooser->isValid();
|
||||
@@ -198,54 +201,78 @@ void PackageOptions::updateStatus()
|
||||
m_statusLabel->setText(statusText);
|
||||
}
|
||||
|
||||
BoardOptions::BoardOptions(const QString &vendor, const QString &model,
|
||||
const QString &toolChainFileName, const QString &qulPlatform,
|
||||
const QVector<PackageOptions*> &packages)
|
||||
McuTarget::McuTarget(const QString &vendor, const QString &model,
|
||||
const QVector<McuPackage*> &packages)
|
||||
: m_vendor(vendor)
|
||||
, m_model(model)
|
||||
, m_toolChainFile(toolChainFileName)
|
||||
, m_qulPlatform(qulPlatform)
|
||||
, m_packages(packages)
|
||||
{
|
||||
}
|
||||
|
||||
QString BoardOptions::model() const
|
||||
{
|
||||
return m_model;
|
||||
}
|
||||
|
||||
QString BoardOptions::toolChainFile() const
|
||||
{
|
||||
return m_toolChainFile;
|
||||
}
|
||||
|
||||
QString BoardOptions::qulPlatform() const
|
||||
{
|
||||
return m_qulPlatform;
|
||||
}
|
||||
|
||||
QVector<PackageOptions *> BoardOptions::packages() const
|
||||
{
|
||||
return m_packages;
|
||||
}
|
||||
|
||||
QString BoardOptions::vendor() const
|
||||
QString McuTarget::vendor() const
|
||||
{
|
||||
return m_vendor;
|
||||
}
|
||||
|
||||
static PackageOptions *createQulPackage()
|
||||
QString McuTarget::model() const
|
||||
{
|
||||
auto result = new PackageOptions(
|
||||
PackageOptions::tr("Qt MCU SDK"),
|
||||
return m_model;
|
||||
}
|
||||
|
||||
QVector<McuPackage *> McuTarget::packages() const
|
||||
{
|
||||
return m_packages;
|
||||
}
|
||||
|
||||
void McuTarget::setToolChainFile(const QString &toolChainFile)
|
||||
{
|
||||
m_toolChainFile = toolChainFile;
|
||||
}
|
||||
|
||||
QString McuTarget::toolChainFile() const
|
||||
{
|
||||
return m_toolChainFile;
|
||||
}
|
||||
|
||||
void McuTarget::setQulPlatform(const QString &qulPlatform)
|
||||
{
|
||||
m_qulPlatform = qulPlatform;
|
||||
}
|
||||
|
||||
QString McuTarget::qulPlatform() const
|
||||
{
|
||||
return m_qulPlatform;
|
||||
}
|
||||
|
||||
bool McuTarget::isValid() const
|
||||
{
|
||||
return !Utils::anyOf(packages(), [](McuPackage *package) {
|
||||
return package->status() != McuPackage::ValidPackage;
|
||||
});
|
||||
}
|
||||
|
||||
int McuTarget::colorDepth() const
|
||||
{
|
||||
return m_colorDepth;
|
||||
}
|
||||
|
||||
void McuTarget::setColorDepth(int colorDepth)
|
||||
{
|
||||
m_colorDepth = colorDepth;
|
||||
}
|
||||
|
||||
static McuPackage *createQtForMCUsPackage()
|
||||
{
|
||||
auto result = new McuPackage(
|
||||
McuPackage::tr("Qt for MCUs SDK"),
|
||||
QDir::homePath(),
|
||||
Utils::HostOsInfo::withExecutableSuffix("bin/qmltocpp"),
|
||||
"qulSdk");
|
||||
"QtMCUSdk");
|
||||
result->setEnvironmentVariableName("Qul_DIR");
|
||||
return result;
|
||||
}
|
||||
|
||||
static PackageOptions *createArmGccPackage()
|
||||
static McuPackage *createArmGccPackage()
|
||||
{
|
||||
const char envVar[] = "ARMGCC_DIR";
|
||||
|
||||
@@ -267,43 +294,43 @@ static PackageOptions *createArmGccPackage()
|
||||
if (defaultPath.isEmpty())
|
||||
defaultPath = QDir::homePath();
|
||||
|
||||
auto result = new PackageOptions(
|
||||
PackageOptions::tr("GNU Arm Embedded Toolchain"),
|
||||
auto result = new McuPackage(
|
||||
McuPackage::tr("GNU Arm Embedded Toolchain"),
|
||||
defaultPath,
|
||||
Utils::HostOsInfo::withExecutableSuffix("bin/arm-none-eabi-g++"),
|
||||
Constants::SETTINGS_KEY_PACKAGE_ARMGCC);
|
||||
"GNUArmEmbeddedToolchain");
|
||||
result->setDownloadUrl(
|
||||
"https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads");
|
||||
result->setEnvironmentVariableName(envVar);
|
||||
return result;
|
||||
}
|
||||
|
||||
static PackageOptions *createStm32CubeFwF7SdkPackage()
|
||||
static McuPackage *createStm32CubeFwF7SdkPackage()
|
||||
{
|
||||
auto result = new PackageOptions(
|
||||
PackageOptions::tr("STM32Cube SDK"),
|
||||
auto result = new McuPackage(
|
||||
McuPackage::tr("STM32Cube SDK"),
|
||||
"%{Env:STM32Cube_FW_F7_SDK_PATH}",
|
||||
"Drivers/STM32F7xx_HAL_Driver",
|
||||
"stm32CubeFwF7Sdk");
|
||||
"Stm32CubeFwF7Sdk");
|
||||
result->setDownloadUrl(
|
||||
"https://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-mcu-packages/stm32cubef7.html");
|
||||
result->setEnvironmentVariableName("STM32Cube_FW_F7_SDK_PATH");
|
||||
return result;
|
||||
}
|
||||
|
||||
static PackageOptions *createStm32CubeProgrammerPackage()
|
||||
static McuPackage *createStm32CubeProgrammerPackage()
|
||||
{
|
||||
const QString defaultPath =
|
||||
Utils::HostOsInfo::isWindowsHost() ?
|
||||
QDir::fromNativeSeparators(qEnvironmentVariable("ProgramFiles"))
|
||||
+ "/STMicroelectronics/STM32Cube/STM32CubeProgrammer/"
|
||||
: QDir::homePath();
|
||||
auto result = new PackageOptions(
|
||||
PackageOptions::tr("STM32CubeProgrammer"),
|
||||
auto result = new McuPackage(
|
||||
McuPackage::tr("STM32CubeProgrammer"),
|
||||
defaultPath,
|
||||
QLatin1String(Utils::HostOsInfo::isWindowsHost() ? "/bin/STM32_Programmer_CLI.exe"
|
||||
: "/bin/STM32_Programmer.sh"),
|
||||
"stm32CubeProgrammer");
|
||||
"Stm32CubeProgrammer");
|
||||
result->setRelativePathModifier("/bin");
|
||||
result->setDownloadUrl(
|
||||
"https://www.st.com/en/development-tools/stm32cubeprog.html");
|
||||
@@ -311,29 +338,29 @@ static PackageOptions *createStm32CubeProgrammerPackage()
|
||||
return result;
|
||||
}
|
||||
|
||||
static PackageOptions *createEvkbImxrt1050SdkPackage()
|
||||
static McuPackage *createEvkbImxrt1050SdkPackage()
|
||||
{
|
||||
auto result = new PackageOptions(
|
||||
PackageOptions::tr("NXP i.MXRT SDK"),
|
||||
auto result = new McuPackage(
|
||||
McuPackage::tr("NXP i.MXRT SDK"),
|
||||
"%{Env:EVKB_IMXRT1050_SDK_PATH}", // TODO: Try to not use 1050 specifics
|
||||
"EVKB-IMXRT1050_manifest_v3_5.xml",
|
||||
"evkbImxrt1050Sdk");
|
||||
"EvkbImxrt1050Sdk");
|
||||
result->setDownloadUrl("https://mcuxpresso.nxp.com/en/welcome");
|
||||
return result;
|
||||
}
|
||||
|
||||
static PackageOptions *createSeggerJLinkPackage()
|
||||
static McuPackage *createSeggerJLinkPackage()
|
||||
{
|
||||
const QString defaultPath =
|
||||
Utils::HostOsInfo::isWindowsHost() ?
|
||||
QDir::fromNativeSeparators(qEnvironmentVariable("ProgramFiles(x86)"))
|
||||
+ "/SEGGER/JLink"
|
||||
: QString("%{Env:SEGGER_JLINK_SOFTWARE_AND_DOCUMENTATION_PATH}");
|
||||
auto result = new PackageOptions(
|
||||
PackageOptions::tr("SEGGER JLink"),
|
||||
auto result = new McuPackage(
|
||||
McuPackage::tr("SEGGER JLink"),
|
||||
defaultPath,
|
||||
Utils::HostOsInfo::withExecutableSuffix("JLink"),
|
||||
"seggerJLink");
|
||||
"SeggerJLink");
|
||||
result->setDownloadUrl("https://www.segger.com/downloads/jlink");
|
||||
result->setEnvironmentVariableName("SEGGER_JLINK_SOFTWARE_AND_DOCUMENTATION_PATH");
|
||||
return result;
|
||||
@@ -342,38 +369,65 @@ static PackageOptions *createSeggerJLinkPackage()
|
||||
McuSupportOptions::McuSupportOptions(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
PackageOptions* qulPackage = createQulPackage();
|
||||
PackageOptions* armGccPackage = createArmGccPackage();
|
||||
PackageOptions* stm32CubeFwF7SdkPackage = createStm32CubeFwF7SdkPackage();
|
||||
PackageOptions* stm32CubeProgrammerPackage = createStm32CubeProgrammerPackage();
|
||||
PackageOptions* evkbImxrt1050SdkPackage = createEvkbImxrt1050SdkPackage();
|
||||
PackageOptions* seggerJLinkPackage = createSeggerJLinkPackage();
|
||||
qtForMCUsSdkPackage = createQtForMCUsPackage();
|
||||
armGccPackage = createArmGccPackage();
|
||||
McuPackage* stm32CubeFwF7SdkPackage = createStm32CubeFwF7SdkPackage();
|
||||
McuPackage* stm32CubeProgrammerPackage = createStm32CubeProgrammerPackage();
|
||||
McuPackage* evkbImxrt1050SdkPackage = createEvkbImxrt1050SdkPackage();
|
||||
McuPackage* seggerJLinkPackage = createSeggerJLinkPackage();
|
||||
|
||||
toolchainPackage = armGccPackage;
|
||||
|
||||
|
||||
auto stmPackages = {armGccPackage, stm32CubeFwF7SdkPackage, stm32CubeProgrammerPackage,
|
||||
qulPackage};
|
||||
auto nxpPackages = {armGccPackage, evkbImxrt1050SdkPackage, seggerJLinkPackage,
|
||||
qulPackage};
|
||||
auto desktopPackages = {qulPackage};
|
||||
packages = {armGccPackage, stm32CubeFwF7SdkPackage, stm32CubeProgrammerPackage,
|
||||
evkbImxrt1050SdkPackage, seggerJLinkPackage, qulPackage};
|
||||
auto stmEvalPackages = {
|
||||
armGccPackage, stm32CubeProgrammerPackage, qtForMCUsSdkPackage};
|
||||
auto stmEngPackages = {
|
||||
armGccPackage, stm32CubeFwF7SdkPackage, stm32CubeProgrammerPackage, qtForMCUsSdkPackage};
|
||||
auto nxpEvalPackages = {
|
||||
armGccPackage, seggerJLinkPackage, qtForMCUsSdkPackage};
|
||||
auto nxpEngPackages = {
|
||||
armGccPackage, evkbImxrt1050SdkPackage, seggerJLinkPackage, qtForMCUsSdkPackage};
|
||||
auto desktopPackages = {
|
||||
qtForMCUsSdkPackage};
|
||||
packages = {
|
||||
armGccPackage, stm32CubeFwF7SdkPackage, stm32CubeProgrammerPackage, evkbImxrt1050SdkPackage,
|
||||
seggerJLinkPackage, qtForMCUsSdkPackage};
|
||||
|
||||
const QString vendorStm = "STM";
|
||||
const QString vendorNxp = "NXP";
|
||||
const QString vendorQt = "Qt";
|
||||
boards.append(new BoardOptions(vendorStm,
|
||||
"stm32f7508", "CMake/stm32f7508-discovery.cmake", "", stmPackages));
|
||||
boards.append(new BoardOptions(vendorStm,
|
||||
"stm32f769i", "CMake/stm32f769i-discovery.cmake", "", stmPackages));
|
||||
boards.append(new BoardOptions(vendorNxp,
|
||||
"evkbimxrt1050", "CMake/evkbimxrt1050-toolchain.cmake", "", nxpPackages));
|
||||
boards.append(new BoardOptions(vendorQt,
|
||||
"Desktop", "", "Qt", desktopPackages));
|
||||
|
||||
// STM
|
||||
auto mcuTarget = new McuTarget(vendorStm, "stm32f7508", stmEvalPackages);
|
||||
mcuTarget->setToolChainFile("CMake/stm32f7508-discovery.cmake");
|
||||
mcuTarget->setColorDepth(32);
|
||||
mcuTargets.append(mcuTarget);
|
||||
|
||||
mcuTarget = new McuTarget(vendorStm, "stm32f7508", stmEvalPackages);
|
||||
mcuTarget->setToolChainFile("CMake/stm32f7508-discovery.cmake");
|
||||
mcuTarget->setColorDepth(16);
|
||||
mcuTargets.append(mcuTarget);
|
||||
|
||||
mcuTarget = new McuTarget(vendorStm, "stm32f769i", stmEvalPackages);
|
||||
mcuTarget->setToolChainFile("CMake/stm32f769i-discovery.cmake");
|
||||
mcuTargets.append(mcuTarget);
|
||||
|
||||
mcuTarget = new McuTarget(vendorStm, "Engineering", stmEngPackages);
|
||||
mcuTargets.append(mcuTarget);
|
||||
|
||||
// NXP
|
||||
mcuTarget = new McuTarget(vendorNxp, "evkbimxrt1050", nxpEvalPackages);
|
||||
mcuTarget->setToolChainFile("CMake/evkbimxrt1050-toolchain.cmake");
|
||||
mcuTargets.append(mcuTarget);
|
||||
|
||||
mcuTarget = new McuTarget(vendorNxp, "Engineering", nxpEngPackages);
|
||||
mcuTargets.append(mcuTarget);
|
||||
|
||||
// Desktop
|
||||
mcuTarget = new McuTarget(vendorQt, "Desktop", desktopPackages);
|
||||
mcuTarget->setQulPlatform("Qt");
|
||||
mcuTarget->setColorDepth(32);
|
||||
mcuTargets.append(mcuTarget);
|
||||
|
||||
for (auto package : packages)
|
||||
connect(package, &PackageOptions::changed, [this](){
|
||||
connect(package, &McuPackage::changed, [this](){
|
||||
emit changed();
|
||||
});
|
||||
}
|
||||
@@ -382,16 +436,8 @@ McuSupportOptions::~McuSupportOptions()
|
||||
{
|
||||
qDeleteAll(packages);
|
||||
packages.clear();
|
||||
qDeleteAll(boards);
|
||||
boards.clear();
|
||||
}
|
||||
|
||||
QVector<BoardOptions *> McuSupportOptions::validBoards() const
|
||||
{
|
||||
return Utils::filtered(boards, [](BoardOptions *board){
|
||||
return !Utils::anyOf(board->packages(), [](PackageOptions *package){
|
||||
return package->status() != PackageOptions::ValidPackage;});
|
||||
});
|
||||
qDeleteAll(mcuTargets);
|
||||
mcuTargets.clear();
|
||||
}
|
||||
|
||||
static ProjectExplorer::ToolChain* armGccToolchain(const Utils::FilePath &path, Core::Id language)
|
||||
@@ -420,20 +466,24 @@ static ProjectExplorer::ToolChain* armGccToolchain(const Utils::FilePath &path,
|
||||
return toolChain;
|
||||
}
|
||||
|
||||
static bool isDesktop(const BoardOptions* board)
|
||||
static bool mcuTargetIsDesktop(const McuTarget* mcuTarget)
|
||||
{
|
||||
return board->qulPlatform() == "Qt";
|
||||
return mcuTarget->qulPlatform() == "Qt";
|
||||
}
|
||||
|
||||
static void setKitProperties(ProjectExplorer::Kit *k, const BoardOptions* board)
|
||||
static void setKitProperties(const QString &kitName, ProjectExplorer::Kit *k,
|
||||
const McuTarget* mcuTarget)
|
||||
{
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
k->setUnexpandedDisplayName("QtMCU - " + board->model());
|
||||
k->setValue(Constants::KIT_BOARD_VENDOR_KEY, board->vendor());
|
||||
k->setValue(Constants::KIT_BOARD_MODEL_KEY, board->model());
|
||||
k->setAutoDetected(false);
|
||||
if (!isDesktop(board)) {
|
||||
k->setUnexpandedDisplayName(kitName);
|
||||
k->setValue(Constants::KIT_MCUTARGET_VENDOR_KEY, mcuTarget->vendor());
|
||||
k->setValue(Constants::KIT_MCUTARGET_MODEL_KEY, mcuTarget->model());
|
||||
k->setAutoDetected(true);
|
||||
k->makeSticky();
|
||||
if (mcuTargetIsDesktop(mcuTarget)) {
|
||||
k->setDeviceTypeForIcon(Constants::DEVICE_TYPE);
|
||||
} else {
|
||||
k->setIrrelevantAspects({SysRootKitAspect::id(),
|
||||
"QtSupport.QtInformation" // QtKitAspect::id()
|
||||
});
|
||||
@@ -468,7 +518,7 @@ static void setKitDebugger(ProjectExplorer::Kit *k, const QString &armGccPath)
|
||||
DebuggerItem newDebugger;
|
||||
newDebugger.setCommand(command);
|
||||
newDebugger.setUnexpandedDisplayName(
|
||||
PackageOptions::tr("Arm GDB at %1").arg(command.toUserOutput()));
|
||||
McuPackage::tr("Arm GDB at %1").arg(command.toUserOutput()));
|
||||
debuggerId = DebuggerItemManager::registerDebugger(newDebugger);
|
||||
} else {
|
||||
debuggerId = debugger->id();
|
||||
@@ -484,13 +534,13 @@ static void setKitDevice(ProjectExplorer::Kit *k)
|
||||
DeviceTypeKitAspect::setDeviceTypeId(k, Constants::DEVICE_TYPE);
|
||||
}
|
||||
|
||||
static void setKitEnvironment(ProjectExplorer::Kit *k, const BoardOptions* board)
|
||||
static void setKitEnvironment(ProjectExplorer::Kit *k, const McuTarget* mcuTarget)
|
||||
{
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
Utils::EnvironmentItems changes;
|
||||
QStringList pathAdditions;
|
||||
for (auto package : board->packages()) {
|
||||
for (auto package : mcuTarget->packages()) {
|
||||
if (package->addToPath())
|
||||
pathAdditions.append(QDir::toNativeSeparators(package->path()));
|
||||
if (!package->environmentVariableName().isEmpty())
|
||||
@@ -505,55 +555,72 @@ static void setKitEnvironment(ProjectExplorer::Kit *k, const BoardOptions* board
|
||||
EnvironmentKitAspect::setEnvironmentChanges(k, changes);
|
||||
}
|
||||
|
||||
static void setKitCMakeOptions(ProjectExplorer::Kit *k, const BoardOptions* board)
|
||||
static void setKitCMakeOptions(ProjectExplorer::Kit *k, const McuTarget* mcuTarget,
|
||||
const QString &qulDir)
|
||||
{
|
||||
using namespace CMakeProjectManager;
|
||||
|
||||
CMakeConfig config = CMakeConfigurationKitAspect::configuration(k);
|
||||
if (!board->toolChainFile().isEmpty())
|
||||
config.append(CMakeConfigItem("CMAKE_CXX_COMPILER", "%{Compiler:Executable:Cxx}"));
|
||||
config.append(CMakeConfigItem("CMAKE_C_COMPILER", "%{Compiler:Executable:C}"));
|
||||
if (!mcuTarget->toolChainFile().isEmpty())
|
||||
config.append(CMakeConfigItem("CMAKE_TOOLCHAIN_FILE",
|
||||
("%{CurrentBuild:Env:Qul_DIR}/" +
|
||||
board->toolChainFile()).toUtf8()));
|
||||
if (!board->qulPlatform().isEmpty())
|
||||
(qulDir + "/" + mcuTarget->toolChainFile()).toUtf8()));
|
||||
if (!mcuTarget->qulPlatform().isEmpty())
|
||||
config.append(CMakeConfigItem("QUL_PLATFORM",
|
||||
board->qulPlatform().toUtf8()));
|
||||
if (isDesktop(board)) {
|
||||
mcuTarget->qulPlatform().toUtf8()));
|
||||
if (mcuTargetIsDesktop(mcuTarget))
|
||||
config.append(CMakeConfigItem("CMAKE_PREFIX_PATH", "%{Qt:QT_INSTALL_PREFIX}"));
|
||||
// TODO: Hack! Implement color depth variants of all targets
|
||||
config.append(CMakeConfigItem("QUL_COLOR_DEPTH", "32"));
|
||||
}
|
||||
if (mcuTarget->colorDepth() >= 0)
|
||||
config.append(CMakeConfigItem("QUL_COLOR_DEPTH",
|
||||
QString::number(mcuTarget->colorDepth()).toLatin1()));
|
||||
CMakeConfigurationKitAspect::setConfiguration(k, config);
|
||||
if (Utils::HostOsInfo::isWindowsHost())
|
||||
CMakeGeneratorKitAspect::setGenerator(k, "NMake Makefiles JOM");
|
||||
}
|
||||
|
||||
ProjectExplorer::Kit *McuSupportOptions::kit(const BoardOptions* board)
|
||||
QString McuSupportOptions::kitName(const McuTarget *mcuTarget) const
|
||||
{
|
||||
// TODO: get version from qulSdkPackage and insert into name
|
||||
const QString colorDepth = mcuTarget->colorDepth() > 0
|
||||
? QString::fromLatin1(" %1bpp").arg(mcuTarget->colorDepth())
|
||||
: "";
|
||||
return QString::fromLatin1("Qt for MCUs - %1 %2%3")
|
||||
.arg(mcuTarget->vendor(), mcuTarget->model(), colorDepth);
|
||||
}
|
||||
|
||||
QList<ProjectExplorer::Kit *> McuSupportOptions::existingKits(const McuTarget *mcuTargt)
|
||||
{
|
||||
using namespace ProjectExplorer;
|
||||
const QString mcuTargetKitName = kitName(mcuTargt);
|
||||
return Utils::filtered(KitManager::kits(), [&mcuTargetKitName](Kit *kit) {
|
||||
return kit->isAutoDetected() && kit->unexpandedDisplayName() == mcuTargetKitName;
|
||||
});
|
||||
}
|
||||
|
||||
ProjectExplorer::Kit *McuSupportOptions::newKit(const McuTarget *mcuTarget)
|
||||
{
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
Kit *kit = KitManager::kit([board](const Kit *k){
|
||||
return board->model() == k->value(Constants::KIT_BOARD_MODEL_KEY).toString();
|
||||
});
|
||||
if (!kit) {
|
||||
const QString armGccPath = toolchainPackage->path();
|
||||
const auto init = [board, &armGccPath](Kit *k) {
|
||||
const QString armGccPath = armGccPackage->path();
|
||||
const QString qulDir = qtForMCUsSdkPackage->path();
|
||||
const auto init = [this, mcuTarget](Kit *k) {
|
||||
KitGuard kitGuard(k);
|
||||
|
||||
setKitProperties(k, board);
|
||||
if (!isDesktop(board)) {
|
||||
setKitToolchains(k, armGccPath);
|
||||
setKitDebugger(k, armGccPath);
|
||||
setKitProperties(kitName(mcuTarget), k, mcuTarget);
|
||||
if (!mcuTargetIsDesktop(mcuTarget)) {
|
||||
setKitToolchains(k, armGccPackage->path());
|
||||
setKitDebugger(k, armGccPackage->path());
|
||||
setKitDevice(k);
|
||||
}
|
||||
setKitEnvironment(k, board);
|
||||
setKitCMakeOptions(k, board);
|
||||
setKitEnvironment(k, mcuTarget);
|
||||
setKitCMakeOptions(k, mcuTarget, qtForMCUsSdkPackage->path());
|
||||
|
||||
k->setup();
|
||||
k->fix();
|
||||
};
|
||||
kit = KitManager::registerKit(init);
|
||||
}
|
||||
return kit;
|
||||
|
||||
return KitManager::registerKit(init);
|
||||
}
|
||||
|
||||
} // Internal
|
||||
|
@@ -42,7 +42,7 @@ class Kit;
|
||||
namespace McuSupport {
|
||||
namespace Internal {
|
||||
|
||||
class PackageOptions : public QObject
|
||||
class McuPackage : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
ValidPackage
|
||||
};
|
||||
|
||||
PackageOptions(const QString &label, const QString &defaultPath, const QString &detectionPath,
|
||||
McuPackage(const QString &label, const QString &defaultPath, const QString &detectionPath,
|
||||
const QString &settingsKey);
|
||||
|
||||
QString path() const;
|
||||
@@ -96,26 +96,31 @@ private:
|
||||
Status m_status = InvalidPath;
|
||||
};
|
||||
|
||||
class BoardOptions : public QObject
|
||||
class McuTarget : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BoardOptions(const QString &vendor, const QString &model, const QString &toolChainFile,
|
||||
const QString &qulPlatform, const QVector<PackageOptions *> &packages);
|
||||
McuTarget(const QString &vendor, const QString &model, const QVector<McuPackage *> &packages);
|
||||
|
||||
QString vendor() const;
|
||||
QString model() const;
|
||||
QVector<McuPackage *> packages() const;
|
||||
void setToolChainFile(const QString &toolChainFile);
|
||||
QString toolChainFile() const;
|
||||
void setQulPlatform(const QString &qulPlatform);
|
||||
QString qulPlatform() const;
|
||||
QVector<PackageOptions *> packages() const;
|
||||
void setColorDepth(int colorDepth);
|
||||
int colorDepth() const;
|
||||
bool isValid() const;
|
||||
|
||||
private:
|
||||
const QString m_vendor;
|
||||
const QString m_model;
|
||||
const QString m_toolChainFile;
|
||||
const QString m_qulPlatform;
|
||||
const QVector<PackageOptions*> m_packages;
|
||||
const QVector<McuPackage*> m_packages;
|
||||
QString m_toolChainFile;
|
||||
QString m_qulPlatform;
|
||||
int m_colorDepth = -1;
|
||||
};
|
||||
|
||||
class McuSupportOptions : public QObject
|
||||
@@ -126,13 +131,15 @@ public:
|
||||
McuSupportOptions(QObject *parent = nullptr);
|
||||
~McuSupportOptions() override;
|
||||
|
||||
QVector<BoardOptions*> validBoards() const;
|
||||
QVector<McuPackage*> packages;
|
||||
QVector<McuTarget*> mcuTargets;
|
||||
McuPackage *armGccPackage = nullptr;
|
||||
McuPackage *qtForMCUsSdkPackage = nullptr;
|
||||
|
||||
QVector<PackageOptions*> packages;
|
||||
QVector<BoardOptions*> boards;
|
||||
PackageOptions *toolchainPackage = nullptr;
|
||||
QString kitName(const McuTarget* mcuTarget) const;
|
||||
|
||||
ProjectExplorer::Kit *kit(const BoardOptions* board);
|
||||
QList<ProjectExplorer::Kit *> existingKits(const McuTarget *mcuTargt);
|
||||
ProjectExplorer::Kit *newKit(const McuTarget *mcuTarget);
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include "mcusupportoptions.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <projectexplorer/kitmanager.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/qtcassert.h>
|
||||
@@ -49,16 +50,17 @@ public:
|
||||
McuSupportOptionsWidget(const McuSupportOptions *options, QWidget *parent = nullptr);
|
||||
|
||||
void updateStatus();
|
||||
void showBoardPackages(int boardIndex);
|
||||
void showMcuTargetPackages();
|
||||
McuTarget *currentMcuTarget() const;
|
||||
|
||||
private:
|
||||
QString m_armGccPath;
|
||||
const McuSupportOptions *m_options;
|
||||
int m_currentBoardIndex = 0;
|
||||
QMap <PackageOptions*, QWidget*> m_packageWidgets;
|
||||
QMap <BoardOptions*, QWidget*> m_boardPacketWidgets;
|
||||
QMap <McuPackage*, QWidget*> m_packageWidgets;
|
||||
QMap <McuTarget*, QWidget*> m_mcuTargetPacketWidgets;
|
||||
QFormLayout *m_packagesLayout = nullptr;
|
||||
QLabel *m_statusLabel = nullptr;
|
||||
QComboBox *m_mcuTargetComboBox = nullptr;
|
||||
};
|
||||
|
||||
McuSupportOptionsWidget::McuSupportOptionsWidget(const McuSupportOptions *options, QWidget *parent)
|
||||
@@ -67,16 +69,18 @@ McuSupportOptionsWidget::McuSupportOptionsWidget(const McuSupportOptions *option
|
||||
{
|
||||
auto mainLayout = new QVBoxLayout(this);
|
||||
|
||||
auto boardChooserlayout = new QHBoxLayout;
|
||||
auto boardChooserLabel = new QLabel(McuSupportOptionsPage::tr("Target:"));
|
||||
boardChooserlayout->addWidget(boardChooserLabel);
|
||||
auto boardComboBox = new QComboBox;
|
||||
boardChooserLabel->setBuddy(boardComboBox);
|
||||
boardChooserLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
|
||||
boardComboBox->addItems(Utils::transform<QStringList>(m_options->boards, [](BoardOptions *b){
|
||||
return b->model();}));
|
||||
boardChooserlayout->addWidget(boardComboBox);
|
||||
mainLayout->addLayout(boardChooserlayout);
|
||||
auto mcuTargetChooserlayout = new QHBoxLayout;
|
||||
auto mcuTargetChooserLabel = new QLabel(McuSupportOptionsPage::tr("Target:"));
|
||||
mcuTargetChooserlayout->addWidget(mcuTargetChooserLabel);
|
||||
m_mcuTargetComboBox = new QComboBox;
|
||||
mcuTargetChooserLabel->setBuddy(m_mcuTargetComboBox);
|
||||
mcuTargetChooserLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
|
||||
m_mcuTargetComboBox->addItems(
|
||||
Utils::transform<QStringList>(m_options->mcuTargets, [this](McuTarget *t){
|
||||
return m_options->kitName(t);
|
||||
}));
|
||||
mcuTargetChooserlayout->addWidget(m_mcuTargetComboBox);
|
||||
mainLayout->addLayout(mcuTargetChooserlayout);
|
||||
|
||||
auto m_packagesGroupBox = new QGroupBox(McuSupportOptionsPage::tr("Packages"));
|
||||
mainLayout->addWidget(m_packagesGroupBox);
|
||||
@@ -84,57 +88,59 @@ McuSupportOptionsWidget::McuSupportOptionsWidget(const McuSupportOptions *option
|
||||
m_packagesGroupBox->setLayout(m_packagesLayout);
|
||||
|
||||
m_statusLabel = new QLabel;
|
||||
mainLayout->addWidget(m_statusLabel);
|
||||
m_statusLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||
mainLayout->addWidget(m_statusLabel, 2);
|
||||
m_statusLabel->setWordWrap(true);
|
||||
m_statusLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
m_statusLabel->setAlignment(Qt::AlignBottom | Qt::AlignLeft);
|
||||
|
||||
connect(options, &McuSupportOptions::changed, this, &McuSupportOptionsWidget::updateStatus);
|
||||
connect(boardComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &McuSupportOptionsWidget::showBoardPackages);
|
||||
connect(m_mcuTargetComboBox, &QComboBox::currentTextChanged,
|
||||
this, &McuSupportOptionsWidget::showMcuTargetPackages);
|
||||
|
||||
showBoardPackages(m_currentBoardIndex);
|
||||
}
|
||||
|
||||
static QString ulOfBoardModels(const QVector<BoardOptions*> &validBoards)
|
||||
{
|
||||
return "<ul><li>"
|
||||
+ Utils::transform<QStringList>(validBoards,[](BoardOptions* board)
|
||||
{return board->model();}).join("</li><li>")
|
||||
+ "</li></ul>";
|
||||
showMcuTargetPackages();
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
void McuSupportOptionsWidget::updateStatus()
|
||||
{
|
||||
const QVector<BoardOptions*> validBoards = m_options->validBoards();
|
||||
m_statusLabel->setText(validBoards.isEmpty()
|
||||
? McuSupportOptionsPage::tr("No kits can currently be generated. "
|
||||
"Select a target and provide the package paths. "
|
||||
"Afterwards, press Apply to generate a kit for "
|
||||
"your board.")
|
||||
: McuSupportOptionsPage::tr("Kits for the following targets can be generated: "
|
||||
"%1 "
|
||||
"Press Apply to generate a kit for "
|
||||
"your target.").arg(ulOfBoardModels(validBoards)));
|
||||
const McuTarget *mcuTarget = currentMcuTarget();
|
||||
if (!mcuTarget)
|
||||
return;
|
||||
|
||||
m_statusLabel->setText(mcuTarget->isValid()
|
||||
? QString::fromLatin1("A kit <b>%1</b> for the selected target can be generated. "
|
||||
"Press Apply to generate it.").arg(m_options->kitName(
|
||||
mcuTarget))
|
||||
: QString::fromLatin1("Provide the package paths in order to create a kit for "
|
||||
"your target."));
|
||||
}
|
||||
|
||||
void McuSupportOptionsWidget::showBoardPackages(int boardIndex)
|
||||
void McuSupportOptionsWidget::showMcuTargetPackages()
|
||||
{
|
||||
const McuTarget *mcuTarget = currentMcuTarget();
|
||||
if (!mcuTarget)
|
||||
return;
|
||||
|
||||
while (m_packagesLayout->rowCount() > 0) {
|
||||
QFormLayout::TakeRowResult row = m_packagesLayout->takeRow(0);
|
||||
row.labelItem->widget()->hide();
|
||||
row.fieldItem->widget()->hide();
|
||||
}
|
||||
|
||||
const BoardOptions *currentBoard = m_options->boards.at(boardIndex);
|
||||
|
||||
for (auto package : m_options->packages) {
|
||||
QWidget *packageWidget = package->widget();
|
||||
if (!currentBoard->packages().contains(package))
|
||||
if (!mcuTarget->packages().contains(package))
|
||||
continue;
|
||||
m_packagesLayout->addRow(package->label(), packageWidget);
|
||||
packageWidget->show();
|
||||
}
|
||||
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
McuTarget *McuSupportOptionsWidget::currentMcuTarget() const
|
||||
{
|
||||
const int mcuTargetIndex = m_mcuTargetComboBox->currentIndex();
|
||||
return m_options->mcuTargets.isEmpty() ? nullptr : m_options->mcuTargets.at(mcuTargetIndex);
|
||||
}
|
||||
|
||||
McuSupportOptionsPage::McuSupportOptionsPage(QObject* parent)
|
||||
@@ -159,14 +165,18 @@ void McuSupportOptionsPage::apply()
|
||||
for (auto package : m_options->packages)
|
||||
package->writeToSettings();
|
||||
|
||||
QTC_ASSERT(m_options->toolchainPackage, return);
|
||||
QTC_ASSERT(m_options->armGccPackage, return);
|
||||
QTC_ASSERT(m_options->qtForMCUsSdkPackage, return);
|
||||
|
||||
const QVector<BoardOptions*> validBoards = m_options->validBoards();
|
||||
const McuTarget *mcuTarget = m_widget->currentMcuTarget();
|
||||
if (!mcuTarget)
|
||||
return;
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
for (auto board : validBoards)
|
||||
m_options->kit(board);
|
||||
for (auto existingKit : m_options->existingKits(mcuTarget))
|
||||
ProjectExplorer::KitManager::deregisterKit(existingKit);
|
||||
m_options->newKit(mcuTarget);
|
||||
}
|
||||
|
||||
void McuSupportOptionsPage::finish()
|
||||
|
@@ -51,7 +51,7 @@ static CommandLine flashAndRunCommand(Target *target)
|
||||
|
||||
// TODO: Hack! Implement flash target name handling, properly
|
||||
const QString targetName =
|
||||
target->kit()->value(Constants::KIT_BOARD_VENDOR_KEY).toString() == "NXP"
|
||||
target->kit()->value(Constants::KIT_MCUTARGET_VENDOR_KEY).toString() == "NXP"
|
||||
? QString("flash_%1").arg(projectName)
|
||||
: QString("flash_%1_and_bootloader").arg(projectName);
|
||||
|
||||
|
@@ -51,6 +51,11 @@
|
||||
"source": "main.qml.tpl",
|
||||
"target": "%{ProjectDirectory}/%{MainQmlFile}",
|
||||
"openInEditor": true
|
||||
},
|
||||
{
|
||||
"source": "%{IDE:ResourcePath}/templates/wizards/projects/git.ignore",
|
||||
"target": ".gitignore",
|
||||
"condition": "%{JS: !value('IsSubproject') && value('VersionControl') === 'G.Git'}"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -106,11 +106,8 @@ void PerfLoadDialog::chooseDefaults()
|
||||
|
||||
ui->kitChooser->setCurrentKitId(target->kit()->id());
|
||||
|
||||
ProjectExplorer::BuildConfiguration *buildConfig = target->activeBuildConfiguration();
|
||||
if (!buildConfig)
|
||||
return;
|
||||
|
||||
ui->executableDirLineEdit->setText(buildConfig->buildDirectory().toString());
|
||||
if (auto *bc = target->activeBuildConfiguration())
|
||||
ui->executableDirLineEdit->setText(bc->buildDirectory().toString());
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -39,6 +39,7 @@
|
||||
#include <coreplugin/variablechooser.h>
|
||||
#include <ssh/sshconnection.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/elidinglabel.h>
|
||||
#include <utils/environment.h>
|
||||
#include <utils/environmentdialog.h>
|
||||
#include <utils/macroexpander.h>
|
||||
@@ -1129,7 +1130,7 @@ class EnvironmentKitAspectWidget : public KitAspectWidget
|
||||
public:
|
||||
EnvironmentKitAspectWidget(Kit *workingCopy, const KitAspect *ki)
|
||||
: KitAspectWidget(workingCopy, ki),
|
||||
m_summaryLabel(new QLabel),
|
||||
m_summaryLabel(new Utils::ElidingLabel),
|
||||
m_manageButton(new QPushButton),
|
||||
m_mainWidget(new QWidget)
|
||||
{
|
||||
@@ -1153,9 +1154,7 @@ private:
|
||||
void refresh() override
|
||||
{
|
||||
const Utils::EnvironmentItems changes = currentEnvironment();
|
||||
QString shortSummary = Utils::EnvironmentItem::toStringList(changes).join(QLatin1String("; "));
|
||||
QFontMetrics fm(m_summaryLabel->font());
|
||||
shortSummary = fm.elidedText(shortSummary, Qt::ElideRight, m_summaryLabel->width());
|
||||
const QString shortSummary = Utils::EnvironmentItem::toStringList(changes).join("; ");
|
||||
m_summaryLabel->setText(shortSummary.isEmpty() ? tr("No changes to apply.") : shortSummary);
|
||||
}
|
||||
|
||||
@@ -1216,7 +1215,7 @@ private:
|
||||
});
|
||||
}
|
||||
|
||||
QLabel *m_summaryLabel;
|
||||
Utils::ElidingLabel *m_summaryLabel;
|
||||
QPushButton *m_manageButton;
|
||||
QCheckBox *m_vslangCheckbox;
|
||||
QWidget *m_mainWidget;
|
||||
|
@@ -270,6 +270,7 @@ PythonRunConfiguration::PythonRunConfiguration(Target *target, Core::Id id)
|
||||
|
||||
auto argumentsAspect = addAspect<ArgumentsAspect>();
|
||||
|
||||
addAspect<WorkingDirectoryAspect>();
|
||||
addAspect<TerminalAspect>();
|
||||
|
||||
setCommandLineGetter([this, interpreterAspect, argumentsAspect] {
|
||||
@@ -299,6 +300,9 @@ void PythonRunConfiguration::updateLanguageServer()
|
||||
PyLSConfigureAssistant::instance()->openDocumentWithPython(python, document);
|
||||
}
|
||||
}
|
||||
|
||||
aspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(
|
||||
Utils::FilePath::fromString(mainScript()).parentDir());
|
||||
}
|
||||
|
||||
bool PythonRunConfiguration::supportsDebugger() const
|
||||
@@ -324,7 +328,7 @@ QString PythonRunConfiguration::interpreter() const
|
||||
void PythonRunConfiguration::updateTargetInformation()
|
||||
{
|
||||
const BuildTargetInfo bti = buildTargetInfo();
|
||||
const QString script = bti.targetFilePath.toString();
|
||||
const QString script = bti.targetFilePath.toUserOutput();
|
||||
setDefaultDisplayName(tr("Run %1").arg(script));
|
||||
aspect<MainScriptAspect>()->setValue(script);
|
||||
}
|
||||
|
@@ -599,7 +599,17 @@ QMakeStepConfigWidget::QMakeStepConfigWidget(QMakeStep *step)
|
||||
connect(step->qmakeBuildConfiguration(), &QmakeBuildConfiguration::qmakeBuildConfigurationChanged,
|
||||
this, &QMakeStepConfigWidget::qmakeBuildConfigChanged);
|
||||
connect(step->target(), &Target::kitChanged, this, &QMakeStepConfigWidget::qtVersionChanged);
|
||||
connect(m_ui->abisListWidget, &QListWidget::itemChanged, this, &QMakeStepConfigWidget::abisChanged);
|
||||
connect(m_ui->abisListWidget, &QListWidget::itemChanged, this, [this]{
|
||||
abisChanged();
|
||||
QmakeBuildConfiguration *bc = m_step->qmakeBuildConfiguration();
|
||||
if (!bc)
|
||||
return;
|
||||
|
||||
QList<ProjectExplorer::BuildStepList *> stepLists;
|
||||
const Core::Id clean = ProjectExplorer::Constants::BUILDSTEPS_CLEAN;
|
||||
stepLists << bc->stepList(clean);
|
||||
BuildManager::buildLists(stepLists, {ProjectExplorerPlugin::displayNameForStepId(clean)});
|
||||
});
|
||||
auto chooser = new Core::VariableChooser(m_ui->qmakeAdditonalArgumentsLineEdit);
|
||||
chooser->addMacroExpanderProvider([step] { return step->macroExpander(); });
|
||||
chooser->addSupportedWidget(m_ui->qmakeAdditonalArgumentsLineEdit);
|
||||
|
@@ -139,6 +139,7 @@ extend_qtc_plugin(QmlDesigner
|
||||
tokencommand.cpp tokencommand.h
|
||||
valueschangedcommand.cpp valueschangedcommand.h
|
||||
changeselectioncommand.cpp changeselectioncommand.h
|
||||
drop3dlibraryitemcommand.cpp drop3dlibraryitemcommand.h
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
|
@@ -134,7 +134,7 @@ bool BindingEditorWidget::event(QEvent *event)
|
||||
TextEditor::AssistInterface *BindingEditorWidget::createAssistInterface(
|
||||
TextEditor::AssistKind assistKind, TextEditor::AssistReason assistReason) const
|
||||
{
|
||||
Q_UNUSED(assistKind);
|
||||
Q_UNUSED(assistKind)
|
||||
return new QmlJSEditor::QmlJSCompletionAssistInterface(
|
||||
document(), position(), QString(),
|
||||
assistReason, qmljsdocument->semanticInfo());
|
||||
@@ -489,26 +489,39 @@ void BindingEditor::setModelNodeBackend(const QVariant &modelNodeBackend)
|
||||
if (!modelNodeBackend.isNull() && modelNodeBackend.isValid()) {
|
||||
m_modelNodeBackend = modelNodeBackend;
|
||||
|
||||
emit modelNodeBackendChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void BindingEditor::prepareBindings()
|
||||
{
|
||||
if (m_backendValue.isNull() || m_modelNodeBackend.isNull())
|
||||
return;
|
||||
|
||||
if (!(m_backendValue.isValid() && m_modelNodeBackend.isValid()))
|
||||
return;
|
||||
|
||||
const auto modelNodeBackendObject = m_modelNodeBackend.value<QObject*>();
|
||||
|
||||
const auto backendObjectCasted =
|
||||
qobject_cast<const QmlDesigner::QmlModelNodeProxy *>(modelNodeBackendObject);
|
||||
|
||||
if (backendObjectCasted) {
|
||||
const QmlDesigner::ModelNode a = backendObjectCasted->qmlObjectNode().modelNode();
|
||||
const QList<QmlDesigner::ModelNode> allNodes = a.view()->allModelNodes();
|
||||
m_modelNode = backendObjectCasted->qmlObjectNode().modelNode();
|
||||
}
|
||||
|
||||
emit modelNodeBackendChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void BindingEditor::setStateModelNode(const QVariant &stateModelNode)
|
||||
{
|
||||
if (stateModelNode.isValid())
|
||||
{
|
||||
m_stateModelNode = stateModelNode;
|
||||
m_modelNode = m_stateModelNode.value<QmlDesigner::ModelNode>();
|
||||
|
||||
if (m_modelNode.isValid())
|
||||
m_backendValueTypeName = "bool";
|
||||
|
||||
emit stateModelNodeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void BindingEditor::prepareBindings()
|
||||
{
|
||||
if (!m_modelNode.isValid() || m_backendValueTypeName.isEmpty())
|
||||
return;
|
||||
|
||||
const QList<QmlDesigner::ModelNode> allNodes = m_modelNode.view()->allModelNodes();
|
||||
|
||||
QList<BindingEditorDialog::BindingOption> bindings;
|
||||
|
||||
@@ -527,7 +540,6 @@ void BindingEditor::prepareBindings()
|
||||
if (!bindings.isEmpty() && !m_dialog.isNull())
|
||||
m_dialog->setAllBindings(bindings);
|
||||
}
|
||||
}
|
||||
|
||||
QVariant BindingEditor::backendValue() const
|
||||
{
|
||||
@@ -539,5 +551,10 @@ QVariant BindingEditor::modelNodeBackend() const
|
||||
return m_modelNodeBackend;
|
||||
}
|
||||
|
||||
QVariant BindingEditor::stateModelNode() const
|
||||
{
|
||||
return m_stateModelNode;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -144,6 +144,7 @@ class BindingEditor : public QObject
|
||||
Q_PROPERTY(QString text READ bindingValue WRITE setBindingValue)
|
||||
Q_PROPERTY(QVariant backendValueProperty READ backendValue WRITE setBackendValue NOTIFY backendValueChanged)
|
||||
Q_PROPERTY(QVariant modelNodeBackendProperty READ modelNodeBackend WRITE setModelNodeBackend NOTIFY modelNodeBackendChanged)
|
||||
Q_PROPERTY(QVariant stateModelNodeProperty READ stateModelNode WRITE setStateModelNode NOTIFY stateModelNodeChanged)
|
||||
|
||||
public:
|
||||
BindingEditor(QObject *parent = nullptr);
|
||||
@@ -159,6 +160,7 @@ public:
|
||||
|
||||
void setBackendValue(const QVariant &backendValue);
|
||||
void setModelNodeBackend(const QVariant &modelNodeBackend);
|
||||
void setStateModelNode(const QVariant &stateModelNode);
|
||||
|
||||
Q_INVOKABLE void prepareBindings();
|
||||
|
||||
@@ -167,15 +169,19 @@ signals:
|
||||
void rejected();
|
||||
void backendValueChanged();
|
||||
void modelNodeBackendChanged();
|
||||
void stateModelNodeChanged();
|
||||
|
||||
private:
|
||||
QVariant backendValue() const;
|
||||
QVariant modelNodeBackend() const;
|
||||
QVariant stateModelNode() const;
|
||||
|
||||
private:
|
||||
QPointer<BindingEditorDialog> m_dialog;
|
||||
QVariant m_backendValue;
|
||||
QVariant m_modelNodeBackend;
|
||||
QVariant m_stateModelNode;
|
||||
QmlDesigner::ModelNode m_modelNode;
|
||||
TypeName m_backendValueTypeName;
|
||||
};
|
||||
|
||||
|
@@ -145,6 +145,7 @@ void PropertyEditorValue::setValueWithEmit(const QVariant &value)
|
||||
emit valueChanged(nameAsQString(), value);
|
||||
emit valueChangedQml();
|
||||
emit isBoundChanged();
|
||||
emit isExplicitChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,6 +161,8 @@ void PropertyEditorValue::setValue(const QVariant &value)
|
||||
|
||||
if (m_value.isValid())
|
||||
emit valueChangedQml();
|
||||
|
||||
emit isExplicitChanged();
|
||||
emit isBoundChanged();
|
||||
}
|
||||
|
||||
|