forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/qds-1.59'
Change-Id: I8a5d7d98b4d75379fe3953fe00bdb939d1722676
This commit is contained in:
@@ -121,7 +121,7 @@ View3D {
|
|||||||
pick(mouse);
|
pick(mouse);
|
||||||
if (pickObj) {
|
if (pickObj) {
|
||||||
axisHelperView.editCameraCtrl.focusObject(axisHelperView.selectedNode,
|
axisHelperView.editCameraCtrl.focusObject(axisHelperView.selectedNode,
|
||||||
pickObj.cameraRotation, false);
|
pickObj.cameraRotation, false, false);
|
||||||
} else {
|
} else {
|
||||||
mouse.accepted = false;
|
mouse.accepted = false;
|
||||||
}
|
}
|
||||||
|
@@ -87,14 +87,15 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function focusObject(targetObject, rotation, updateZoom)
|
function focusObject(targetObject, rotation, updateZoom, closeUp)
|
||||||
{
|
{
|
||||||
if (!camera)
|
if (!camera)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
camera.eulerRotation = rotation;
|
camera.eulerRotation = rotation;
|
||||||
var newLookAtAndZoom = _generalHelper.focusObjectToCamera(
|
var newLookAtAndZoom = _generalHelper.focusObjectToCamera(
|
||||||
camera, _defaultCameraLookAtDistance, targetObject, view3d, _zoomFactor, updateZoom);
|
camera, _defaultCameraLookAtDistance, targetObject, view3d, _zoomFactor,
|
||||||
|
updateZoom, closeUp);
|
||||||
_lookAtPoint = newLookAtAndZoom.toVector3d();
|
_lookAtPoint = newLookAtAndZoom.toVector3d();
|
||||||
_zoomFactor = newLookAtAndZoom.w;
|
_zoomFactor = newLookAtAndZoom.w;
|
||||||
storeCameraState(0);
|
storeCameraState(0);
|
||||||
|
@@ -146,7 +146,7 @@ Item {
|
|||||||
if (editView) {
|
if (editView) {
|
||||||
var targetNode = selectionBoxes.length > 0
|
var targetNode = selectionBoxes.length > 0
|
||||||
? selectionBoxes[0].model : null;
|
? selectionBoxes[0].model : null;
|
||||||
cameraControl.focusObject(targetNode, editView.camera.eulerRotation, true);
|
cameraControl.focusObject(targetNode, editView.camera.eulerRotation, true, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -42,7 +42,7 @@ Item {
|
|||||||
|
|
||||||
function fitAndHideBox() : bool
|
function fitAndHideBox() : bool
|
||||||
{
|
{
|
||||||
cameraControl.focusObject(selectionBox.model, viewCamera.eulerRotation, true);
|
cameraControl.focusObject(selectionBox.model, viewCamera.eulerRotation, true, true);
|
||||||
if (cameraControl._zoomFactor < 0.1) {
|
if (cameraControl._zoomFactor < 0.1) {
|
||||||
view3D.importScene.scale = view3D.importScene.scale.times(10);
|
view3D.importScene.scale = view3D.importScene.scale.times(10);
|
||||||
return false;
|
return false;
|
||||||
|
@@ -148,7 +148,7 @@ float GeneralHelper::zoomCamera(QQuick3DCamera *camera, float distance, float de
|
|||||||
// Return value contains new lookAt point (xyz) and zoom factor (w)
|
// Return value contains new lookAt point (xyz) and zoom factor (w)
|
||||||
QVector4D GeneralHelper::focusObjectToCamera(QQuick3DCamera *camera, float defaultLookAtDistance,
|
QVector4D GeneralHelper::focusObjectToCamera(QQuick3DCamera *camera, float defaultLookAtDistance,
|
||||||
QQuick3DNode *targetObject, QQuick3DViewport *viewPort,
|
QQuick3DNode *targetObject, QQuick3DViewport *viewPort,
|
||||||
float oldZoom, bool updateZoom)
|
float oldZoom, bool updateZoom, bool closeUp)
|
||||||
{
|
{
|
||||||
if (!camera)
|
if (!camera)
|
||||||
return QVector4D(0.f, 0.f, 0.f, 1.f);
|
return QVector4D(0.f, 0.f, 0.f, 1.f);
|
||||||
@@ -200,7 +200,9 @@ QVector4D GeneralHelper::focusObjectToCamera(QQuick3DCamera *camera, float defau
|
|||||||
|
|
||||||
camera->setPosition(lookAt + newLookVector);
|
camera->setPosition(lookAt + newLookVector);
|
||||||
|
|
||||||
float newZoomFactor = updateZoom ? qBound(.01f, float(maxExtent / 900.), 100.f) : oldZoom;
|
qreal divisor = closeUp ? 900. : 725.;
|
||||||
|
|
||||||
|
float newZoomFactor = updateZoom ? qBound(.01f, float(maxExtent / divisor), 100.f) : oldZoom;
|
||||||
float cameraZoomFactor = zoomCamera(camera, 0, defaultLookAtDistance, lookAt, newZoomFactor, false);
|
float cameraZoomFactor = zoomCamera(camera, 0, defaultLookAtDistance, lookAt, newZoomFactor, false);
|
||||||
|
|
||||||
return QVector4D(lookAt, cameraZoomFactor);
|
return QVector4D(lookAt, cameraZoomFactor);
|
||||||
|
@@ -66,8 +66,9 @@ public:
|
|||||||
float defaultLookAtDistance, const QVector3D &lookAt,
|
float defaultLookAtDistance, const QVector3D &lookAt,
|
||||||
float zoomFactor, bool relative);
|
float zoomFactor, bool relative);
|
||||||
Q_INVOKABLE QVector4D focusObjectToCamera(QQuick3DCamera *camera, float defaultLookAtDistance,
|
Q_INVOKABLE QVector4D focusObjectToCamera(QQuick3DCamera *camera, float defaultLookAtDistance,
|
||||||
QQuick3DNode *targetObject, QQuick3DViewport *viewPort,
|
QQuick3DNode *targetObject, QQuick3DViewport *viewPort,
|
||||||
float oldZoom, bool updateZoom = true);
|
float oldZoom, bool updateZoom = true,
|
||||||
|
bool closeUp = false);
|
||||||
Q_INVOKABLE void delayedPropertySet(QObject *obj, int delay, const QString &property,
|
Q_INVOKABLE void delayedPropertySet(QObject *obj, int delay, const QString &property,
|
||||||
const QVariant& value);
|
const QVariant& value);
|
||||||
Q_INVOKABLE QQuick3DNode *resolvePick(QQuick3DNode *pickNode);
|
Q_INVOKABLE QQuick3DNode *resolvePick(QQuick3DNode *pickNode);
|
||||||
|
@@ -47,6 +47,8 @@ Item {
|
|||||||
width: itemLibraryIconWidth // to be set in Qml context
|
width: itemLibraryIconWidth // to be set in Qml context
|
||||||
height: itemLibraryIconHeight // to be set in Qml context
|
height: itemLibraryIconHeight // to be set in Qml context
|
||||||
source: itemLibraryIconPath // to be set by model
|
source: itemLibraryIconPath // to be set by model
|
||||||
|
|
||||||
|
cache: false // Allow thumbnail to be dynamically updated
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
@@ -100,14 +100,17 @@ Section {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: "State"
|
text: qsTr("State")
|
||||||
}
|
}
|
||||||
SecondColumnLayout {
|
SecondColumnLayout {
|
||||||
LineEdit {
|
|
||||||
|
ComboBox {
|
||||||
|
Layout.fillWidth: true
|
||||||
backendValue: backendValues.state
|
backendValue: backendValues.state
|
||||||
showTranslateCheckBox: false
|
model: allStateNames
|
||||||
enabled: anchorBackend.hasParent || isBaseState
|
valueType: ComboBox.String
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpandingSpacer {
|
ExpandingSpacer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,5 +161,56 @@ Section {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Focus")
|
||||||
|
tooltip: qsTr("Holds whether the item has focus within the enclosing FocusScope.")
|
||||||
|
disabledState: !backendValues.focus.isAvailable
|
||||||
|
}
|
||||||
|
SecondColumnLayout {
|
||||||
|
CheckBox {
|
||||||
|
backendValue: backendValues.focus
|
||||||
|
text: backendValues.focus.valueToString
|
||||||
|
enabled: backendValues.focus.isAvailable
|
||||||
|
implicitWidth: 180
|
||||||
|
}
|
||||||
|
ExpandingSpacer {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Active focus on tab")
|
||||||
|
tooltip: qsTr("Holds whether the item wants to be in the tab focus chain.")
|
||||||
|
disabledState: !backendValues.activeFocusOnTab.isAvailable
|
||||||
|
}
|
||||||
|
SecondColumnLayout {
|
||||||
|
CheckBox {
|
||||||
|
backendValue: backendValues.activeFocusOnTab
|
||||||
|
text: backendValues.activeFocusOnTab.valueToString
|
||||||
|
enabled: backendValues.activeFocusOnTab.isAvailable
|
||||||
|
implicitWidth: 180
|
||||||
|
}
|
||||||
|
ExpandingSpacer {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Baseline offset")
|
||||||
|
tooltip: qsTr("Specifies the position of the item's baseline in local coordinates.")
|
||||||
|
disabledState: !backendValues.baselineOffset.isAvailable
|
||||||
|
}
|
||||||
|
SecondColumnLayout {
|
||||||
|
SpinBox {
|
||||||
|
sliderIndicatorVisible: true
|
||||||
|
backendValue: backendValues.baselineOffset
|
||||||
|
hasSlider: true
|
||||||
|
decimals: 0
|
||||||
|
minimumValue: -1000
|
||||||
|
maximumValue: 1000
|
||||||
|
Layout.preferredWidth: 140
|
||||||
|
enabled: backendValues.baselineOffset.isAvailable
|
||||||
|
}
|
||||||
|
ExpandingSpacer {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,95 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 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.1
|
||||||
|
import HelperWidgets 2.0
|
||||||
|
import QtQuick.Layouts 1.0
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
ImageSpecifics {
|
||||||
|
}
|
||||||
|
|
||||||
|
Section {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
caption: qsTr("Animated Image")
|
||||||
|
|
||||||
|
SectionLayout {
|
||||||
|
Label {
|
||||||
|
text: qsTr("Speed")
|
||||||
|
disabledState: !backendValues.speed.isAvailable
|
||||||
|
}
|
||||||
|
SecondColumnLayout {
|
||||||
|
SpinBox {
|
||||||
|
sliderIndicatorVisible: true
|
||||||
|
backendValue: backendValues.speed
|
||||||
|
hasSlider: true
|
||||||
|
decimals: 2
|
||||||
|
minimumValue: 0
|
||||||
|
maximumValue: 100
|
||||||
|
Layout.preferredWidth: 140
|
||||||
|
enabled: backendValues.speed.isAvailable
|
||||||
|
}
|
||||||
|
ExpandingSpacer {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Paused")
|
||||||
|
tooltip: qsTr("Holds whether the animated image is paused.")
|
||||||
|
disabledState: !backendValues.paused.isAvailable
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
CheckBox {
|
||||||
|
enabled: backendValues.paused.isAvailable
|
||||||
|
text: backendValues.paused.valueToString
|
||||||
|
backendValue: backendValues.paused
|
||||||
|
implicitWidth: 180
|
||||||
|
}
|
||||||
|
ExpandingSpacer {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Playing")
|
||||||
|
tooltip: qsTr("Holds whether the animated image is playing.")
|
||||||
|
disabledState: !backendValues.playing.isAvailable
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
CheckBox {
|
||||||
|
enabled: backendValues.playing.isAvailable
|
||||||
|
text: backendValues.playing.valueToString
|
||||||
|
backendValue: backendValues.playing
|
||||||
|
implicitWidth: 180
|
||||||
|
}
|
||||||
|
ExpandingSpacer {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -124,7 +124,7 @@ Column {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: qsTr("Horizontal Fill mode")
|
text: qsTr("Horizontal Tile mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
SecondColumnLayout {
|
SecondColumnLayout {
|
||||||
@@ -138,7 +138,7 @@ Column {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: qsTr("Vertical Fill mode")
|
text: qsTr("Vertical Tile mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
SecondColumnLayout {
|
SecondColumnLayout {
|
||||||
@@ -186,6 +186,70 @@ Column {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Mirror")
|
||||||
|
tooltip: qsTr("Specifies whether the image should be horizontally inverted.")
|
||||||
|
disabledState: !backendValues.mirror.isAvailable
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
CheckBox {
|
||||||
|
enabled: backendValues.mirror.isAvailable
|
||||||
|
text: backendValues.mirror.valueToString
|
||||||
|
backendValue: backendValues.mirror
|
||||||
|
implicitWidth: 180
|
||||||
|
}
|
||||||
|
ExpandingSpacer {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Smooth")
|
||||||
|
tooltip: qsTr("Specifies whether the image is smoothly filtered when scaled or transformed.")
|
||||||
|
disabledState: !backendValues.smooth.isAvailable
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
CheckBox {
|
||||||
|
enabled: backendValues.smooth.isAvailable
|
||||||
|
text: backendValues.smooth.valueToString
|
||||||
|
backendValue: backendValues.smooth
|
||||||
|
implicitWidth: 180
|
||||||
|
}
|
||||||
|
ExpandingSpacer {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Cache")
|
||||||
|
tooltip: qsTr("Specifies whether the image should be cached.")
|
||||||
|
disabledState: !backendValues.cache.isAvailable
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
CheckBox {
|
||||||
|
enabled: backendValues.cache.isAvailable
|
||||||
|
text: backendValues.cache.valueToString
|
||||||
|
backendValue: backendValues.cache
|
||||||
|
implicitWidth: 180
|
||||||
|
}
|
||||||
|
ExpandingSpacer {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Asynchronous")
|
||||||
|
tooltip: qsTr("Specifies that images on the local filesystem should be loaded asynchronously in a separate thread.")
|
||||||
|
disabledState: !backendValues.asynchronous.isAvailable
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
CheckBox {
|
||||||
|
enabled: backendValues.asynchronous.isAvailable
|
||||||
|
text: backendValues.asynchronous.valueToString
|
||||||
|
backendValue: backendValues.asynchronous
|
||||||
|
implicitWidth: 180
|
||||||
|
}
|
||||||
|
ExpandingSpacer {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -95,7 +95,32 @@ Column {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
scope: "Qt"
|
scope: "Qt"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Horizontal item alignment")
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
ComboBox {
|
||||||
|
model: ["AlignLeft", "AlignRight" ,"AlignHCenter"]
|
||||||
|
backendValue: backendValues.horizontalItemAlignment
|
||||||
|
Layout.fillWidth: true
|
||||||
|
scope: "Grid"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Vertical item alignment")
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
ComboBox {
|
||||||
|
model: ["AlignTop", "AlignBottom" ,"AlignVCenter"]
|
||||||
|
backendValue: backendValues.verticalItemAlignment
|
||||||
|
Layout.fillWidth: true
|
||||||
|
scope: "Grid"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
|
@@ -58,7 +58,7 @@ Column {
|
|||||||
SecondColumnLayout {
|
SecondColumnLayout {
|
||||||
ComboBox {
|
ComboBox {
|
||||||
scope: "Image"
|
scope: "Image"
|
||||||
model: ["Stretch", "PreserveAspectFit", "PreserveAspectCrop", "Tile", "TileVertically", "TileHorizontally"]
|
model: ["Stretch", "PreserveAspectFit", "PreserveAspectCrop", "Tile", "TileVertically", "TileHorizontally", "Pad"]
|
||||||
backendValue: backendValues.fillMode
|
backendValue: backendValues.fillMode
|
||||||
implicitWidth: 180
|
implicitWidth: 180
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -105,6 +105,136 @@ Column {
|
|||||||
ExpandingSpacer {
|
ExpandingSpacer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Horizontal alignment")
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
ComboBox {
|
||||||
|
scope: "Image"
|
||||||
|
model: ["AlignLeft", "AlignRight", "AlignHCenter"]
|
||||||
|
backendValue: backendValues.horizontalAlignment
|
||||||
|
implicitWidth: 180
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpandingSpacer {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Vertical alignment")
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
ComboBox {
|
||||||
|
scope: "Image"
|
||||||
|
model: ["AlignTop", "AlignBottom", "AlignVCenter"]
|
||||||
|
backendValue: backendValues.verticalAlignment
|
||||||
|
implicitWidth: 180
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpandingSpacer {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Asynchronous")
|
||||||
|
tooltip: qsTr("Specifies that images on the local filesystem should be loaded asynchronously in a separate thread.")
|
||||||
|
disabledState: !backendValues.asynchronous.isAvailable
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
CheckBox {
|
||||||
|
enabled: backendValues.asynchronous.isAvailable
|
||||||
|
text: backendValues.asynchronous.valueToString
|
||||||
|
backendValue: backendValues.asynchronous
|
||||||
|
implicitWidth: 180
|
||||||
|
}
|
||||||
|
ExpandingSpacer {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Auto transform")
|
||||||
|
tooltip: qsTr("Specifies whether the image should automatically apply image transformation metadata such as EXIF orientation.")
|
||||||
|
disabledState: !backendValues.autoTransform.isAvailable
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
CheckBox {
|
||||||
|
enabled: backendValues.autoTransform.isAvailable
|
||||||
|
text: backendValues.autoTransform.valueToString
|
||||||
|
backendValue: backendValues.autoTransform
|
||||||
|
implicitWidth: 180
|
||||||
|
}
|
||||||
|
ExpandingSpacer {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Cache")
|
||||||
|
tooltip: qsTr("Specifies whether the image should be cached.")
|
||||||
|
disabledState: !backendValues.cache.isAvailable
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
CheckBox {
|
||||||
|
enabled: backendValues.cache.isAvailable
|
||||||
|
text: backendValues.cache.valueToString
|
||||||
|
backendValue: backendValues.cache
|
||||||
|
implicitWidth: 180
|
||||||
|
}
|
||||||
|
ExpandingSpacer {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Mipmap")
|
||||||
|
tooltip: qsTr("Specifies whether the image uses mipmap filtering when scaled or transformed.")
|
||||||
|
disabledState: !backendValues.mipmap.isAvailable
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
CheckBox {
|
||||||
|
enabled: backendValues.mipmap.isAvailable
|
||||||
|
text: backendValues.mipmap.valueToString
|
||||||
|
backendValue: backendValues.mipmap
|
||||||
|
implicitWidth: 180
|
||||||
|
}
|
||||||
|
ExpandingSpacer {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Mirror")
|
||||||
|
tooltip: qsTr("Specifies whether the image should be horizontally inverted.")
|
||||||
|
disabledState: !backendValues.mirror.isAvailable
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
CheckBox {
|
||||||
|
enabled: backendValues.mirror.isAvailable
|
||||||
|
text: backendValues.mirror.valueToString
|
||||||
|
backendValue: backendValues.mirror
|
||||||
|
implicitWidth: 180
|
||||||
|
}
|
||||||
|
ExpandingSpacer {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Smooth")
|
||||||
|
tooltip: qsTr("Specifies whether the image is smoothly filtered when scaled or transformed.")
|
||||||
|
disabledState: !backendValues.smooth.isAvailable
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
CheckBox {
|
||||||
|
enabled: backendValues.smooth.isAvailable
|
||||||
|
text: backendValues.smooth.valueToString
|
||||||
|
backendValue: backendValues.smooth
|
||||||
|
implicitWidth: 180
|
||||||
|
}
|
||||||
|
ExpandingSpacer {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -54,7 +54,7 @@ Column {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: qsTr("Hover Enabled")
|
text: qsTr("Hover enabled")
|
||||||
tooltip: qsTr("This property holds whether hover events are handled.")
|
tooltip: qsTr("This property holds whether hover events are handled.")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,6 +68,197 @@ Column {
|
|||||||
ExpandingSpacer {
|
ExpandingSpacer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Accepted buttons")
|
||||||
|
tooltip: qsTr("This property holds the mouse buttons that the mouse area reacts to.")
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
ComboBox {
|
||||||
|
backendValue: backendValues.acceptedButtons
|
||||||
|
model: ["LeftButton", "RightButton", "MiddleButton", "BackButton", "ForwardButton", "AllButtons"]
|
||||||
|
Layout.fillWidth: true
|
||||||
|
scope: "Qt"
|
||||||
|
}
|
||||||
|
ExpandingSpacer {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Press and hold interval")
|
||||||
|
tooltip: qsTr("This property overrides the elapsed time in milliseconds before pressAndHold is emitted.")
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
SpinBox {
|
||||||
|
backendValue: backendValues.pressAndHoldInterval
|
||||||
|
minimumValue: 0
|
||||||
|
maximumValue: 2000
|
||||||
|
decimals: 0
|
||||||
|
}
|
||||||
|
ExpandingSpacer {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Scroll gesture enabled")
|
||||||
|
tooltip: qsTr("This property controls whether this MouseArea responds to scroll gestures from non-mouse devices.")
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
CheckBox {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
backendValue: backendValues.scrollGestureEnabled
|
||||||
|
text: backendValues.scrollGestureEnabled.valueToString
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpandingSpacer {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Cursor shape")
|
||||||
|
tooltip: qsTr("This property holds the cursor shape for this mouse area.")
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
ComboBox {
|
||||||
|
backendValue: backendValues.cursorShape
|
||||||
|
model: ["ArrowCursor", "UpArrowCursor", "CrossCursor", "WaitCursor",
|
||||||
|
"IBeamCursor", "SizeVerCursor", "SizeHorCursor", "SizeBDiagCursor",
|
||||||
|
"SizeFDiagCursor", "SizeAllCursor", "BlankCursor", "SplitVCursor",
|
||||||
|
"SplitHCursor", "PointingHandCursor", "ForbiddenCursor", "WhatsThisCursor",
|
||||||
|
"BusyCursor", "OpenHandCursor", "ClosedHandCursor", "DragCopyCursor",
|
||||||
|
"DragMoveCursor", "DragLinkCursor"]
|
||||||
|
Layout.fillWidth: true
|
||||||
|
scope: "Qt"
|
||||||
|
}
|
||||||
|
ExpandingSpacer {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Prevent stealing")
|
||||||
|
tooltip: qsTr("This property controls whether the mouse events may be stolen from this MouseArea.")
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
CheckBox {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
backendValue: backendValues.preventStealing
|
||||||
|
text: backendValues.preventStealing.valueToString
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpandingSpacer {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Propagate composed events")
|
||||||
|
tooltip: qsTr("This property controls whether composed mouse events will automatically propagate to other MouseAreas.")
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
CheckBox {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
backendValue: backendValues.propagateComposedEvents
|
||||||
|
text: backendValues.propagateComposedEvents.valueToString
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpandingSpacer {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Section {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
caption: qsTr("Drag")
|
||||||
|
|
||||||
|
SectionLayout {
|
||||||
|
Label {
|
||||||
|
text: qsTr("Target")
|
||||||
|
tooltip: qsTr("Sets the id of the item to drag.")
|
||||||
|
}
|
||||||
|
SecondColumnLayout {
|
||||||
|
ItemFilterComboBox {
|
||||||
|
typeFilter: "QtQuick.QtObject"
|
||||||
|
validator: RegExpValidator { regExp: /(^$|^[a-z_]\w*)/ }
|
||||||
|
backendValue: backendValues.drag_target
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpandingSpacer {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Axis")
|
||||||
|
tooltip: qsTr("Specifies whether dragging can be done horizontally, vertically, or both.")
|
||||||
|
}
|
||||||
|
SecondColumnLayout {
|
||||||
|
ComboBox {
|
||||||
|
scope: "Drag"
|
||||||
|
model: ["XAxis", "YAxis", "XAndYAxis"]
|
||||||
|
backendValue: backendValues.drag_axis
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpandingSpacer {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Filter children")
|
||||||
|
tooltip: qsTr("Specifies whether a drag overrides descendant MouseAreas.")
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
CheckBox {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
backendValue: backendValues.drag_filterChildren
|
||||||
|
text: backendValues.drag_filterChildren.valueToString
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpandingSpacer {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Threshold")
|
||||||
|
tooltip: qsTr("Determines the threshold in pixels of when the drag operation should start.")
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
SpinBox {
|
||||||
|
backendValue: backendValues.drag_threshold
|
||||||
|
minimumValue: 0
|
||||||
|
maximumValue: 5000
|
||||||
|
decimals: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpandingSpacer {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Smoothed")
|
||||||
|
tooltip: qsTr("If set to true, the target will be moved only after the drag operation has started.\n"
|
||||||
|
+ "If set to false, the target will be moved straight to the current mouse position.")
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
CheckBox {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
backendValue: backendValues.drag_smoothed
|
||||||
|
text: backendValues.drag_smoothed.valueToString
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpandingSpacer {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -113,6 +113,19 @@ Section {
|
|||||||
minimumValue: -200
|
minimumValue: -200
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
visible: textInputSection.isTextInput
|
||||||
|
text: qsTr("Maximum length")
|
||||||
|
tooltip: qsTr("Sets the maximum permitted length of the text in the TextInput.")
|
||||||
|
}
|
||||||
|
SpinBox {
|
||||||
|
visible: textInputSection.isTextInput
|
||||||
|
Layout.fillWidth: true
|
||||||
|
backendValue: backendValues.maximumLength
|
||||||
|
minimumValue: 0
|
||||||
|
maximumValue: 32767
|
||||||
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: qsTr("Flags")
|
text: qsTr("Flags")
|
||||||
Layout.alignment: Qt.AlignTop
|
Layout.alignment: Qt.AlignTop
|
||||||
|
@@ -47,7 +47,7 @@ Section {
|
|||||||
SecondColumnLayout {
|
SecondColumnLayout {
|
||||||
ComboBox {
|
ComboBox {
|
||||||
backendValue: backendValues.flickableDirection
|
backendValue: backendValues.flickableDirection
|
||||||
model: ["AutoFlickDirection", "HorizontalFlick", "VerticalFlick", "HorizontalAndVerticalFlick"]
|
model: ["AutoFlickDirection", "AutoFlickIfNeeded", "HorizontalFlick", "VerticalFlick", "HorizontalAndVerticalFlick"]
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
scope: "Flickable"
|
scope: "Flickable"
|
||||||
}
|
}
|
||||||
@@ -63,7 +63,7 @@ Section {
|
|||||||
SecondColumnLayout {
|
SecondColumnLayout {
|
||||||
ComboBox {
|
ComboBox {
|
||||||
backendValue: backendValues.boundsBehavior
|
backendValue: backendValues.boundsBehavior
|
||||||
model: ["StopAtBounds", "DragOverBounds", "DragAndOvershootBounds"]
|
model: ["StopAtBounds", "DragOverBounds", "OvershootBounds", "DragAndOvershootBounds"]
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
scope: "Flickable"
|
scope: "Flickable"
|
||||||
}
|
}
|
||||||
@@ -166,6 +166,23 @@ Section {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Synchronous drag")
|
||||||
|
tooltip: qsTr("If set to true, then when the mouse or touchpoint moves far enough to begin dragging\n"
|
||||||
|
+ "the content, the content will jump, such that the content pixel which was under the\n"
|
||||||
|
+ "cursor or touchpoint when pressed remains under that point.")
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
CheckBox {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
backendValue: backendValues.synchronousDrag
|
||||||
|
text: backendValues.synchronousDrag.valueToString
|
||||||
|
}
|
||||||
|
ExpandingSpacer {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: qsTr("Content size")
|
text: qsTr("Content size")
|
||||||
}
|
}
|
||||||
@@ -246,6 +263,45 @@ Section {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Origin")
|
||||||
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
|
Label {
|
||||||
|
text: "X"
|
||||||
|
width: root.labelWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
SpinBox {
|
||||||
|
backendValue: backendValues.originX
|
||||||
|
minimumValue: -8000
|
||||||
|
maximumValue: 8000
|
||||||
|
implicitWidth: root.spinBoxWidth
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: 4
|
||||||
|
height: 4
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: "Y"
|
||||||
|
width: root.labelWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
SpinBox {
|
||||||
|
backendValue: backendValues.originY
|
||||||
|
minimumValue: -8000
|
||||||
|
maximumValue: 8000
|
||||||
|
implicitWidth: root.spinBoxWidth
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
ExpandingSpacer {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: qsTr("Margins")
|
text: qsTr("Margins")
|
||||||
}
|
}
|
||||||
|
@@ -68,9 +68,12 @@ Section {
|
|||||||
text: qsTr("Font")
|
text: qsTr("Font")
|
||||||
}
|
}
|
||||||
FontComboBox {
|
FontComboBox {
|
||||||
|
id: fontComboBox
|
||||||
backendValue: fontSection.fontFamily
|
backendValue: fontSection.fontFamily
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
width: 160
|
width: 160
|
||||||
|
property string familyName: backendValue.value
|
||||||
|
onFamilyNameChanged: print(styleNamesForFamily(familyName))
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
@@ -151,6 +154,7 @@ Section {
|
|||||||
italic: fontSection.italicStyle
|
italic: fontSection.italicStyle
|
||||||
underline: fontSection.underlineStyle
|
underline: fontSection.underlineStyle
|
||||||
strikeout: fontSection.strikeoutStyle
|
strikeout: fontSection.strikeoutStyle
|
||||||
|
enabled: !styleComboBox.styleSet
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
@@ -175,6 +179,21 @@ Section {
|
|||||||
backendValue: getBackendValue("weight")
|
backendValue: getBackendValue("weight")
|
||||||
model: ["Normal", "Light", "ExtraLight", "Thin", "Medium", "DemiBold", "Bold", "ExtraBold", "Black"]
|
model: ["Normal", "Light", "ExtraLight", "Thin", "Medium", "DemiBold", "Bold", "ExtraBold", "Black"]
|
||||||
scope: "Font"
|
scope: "Font"
|
||||||
|
enabled: !styleComboBox.styleSet
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Style name")
|
||||||
|
toolTip: qsTr("Sets the font's style.")
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox {
|
||||||
|
id: styleComboBox
|
||||||
|
property bool styleSet: backendValue.isInModel
|
||||||
|
Layout.fillWidth: true
|
||||||
|
backendValue: getBackendValue("styleName")
|
||||||
|
model: styleNamesForFamily(fontComboBox.familyName)
|
||||||
|
useString: true
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
@@ -257,5 +276,17 @@ Section {
|
|||||||
"Latin script,\n it is merely a cosmetic feature. Setting the preferShaping property to false will disable all such features\nwhen they are not required, which will improve performance in most cases.")
|
"Latin script,\n it is merely a cosmetic feature. Setting the preferShaping property to false will disable all such features\nwhen they are not required, which will improve performance in most cases.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Hinting preference")
|
||||||
|
toolTip: qsTr("Sets the preferred hinting on the text.")
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
backendValue: getBackendValue("hintingPreference")
|
||||||
|
model: ["PreferDefaultHinting", "PreferNoHinting", "PreferVerticalHinting", "PreferFullHinting"]
|
||||||
|
scope: "Font"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -61,7 +61,7 @@ Section {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
backendValue: backendValues.wrapMode
|
backendValue: backendValues.wrapMode
|
||||||
scope: "Text"
|
scope: "Text"
|
||||||
model: ["NoWrap", "WordWrap", "WrapAnywhere", "WrapAtWordBoundaryOrAnywhere"]
|
model: ["NoWrap", "WordWrap", "WrapAnywhere", "Wrap"]
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
@@ -77,6 +77,21 @@ Section {
|
|||||||
model: ["ElideNone", "ElideLeft", "ElideMiddle", "ElideRight"]
|
model: ["ElideNone", "ElideLeft", "ElideMiddle", "ElideRight"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
visible: showElide
|
||||||
|
text: qsTr("Maximum line count")
|
||||||
|
tooltip: qsTr("Limits the number of lines that the text item will show.")
|
||||||
|
}
|
||||||
|
|
||||||
|
SpinBox {
|
||||||
|
visible: showElide
|
||||||
|
Layout.fillWidth: true
|
||||||
|
backendValue: backendValues.maximumLineCount
|
||||||
|
minimumValue: 0
|
||||||
|
maximumValue: 10000
|
||||||
|
decimals: 0
|
||||||
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: qsTr("Alignment")
|
text: qsTr("Alignment")
|
||||||
}
|
}
|
||||||
@@ -124,6 +139,7 @@ Section {
|
|||||||
toolTip: qsTr("Specifies how the font size of the displayed text is determined.")
|
toolTip: qsTr("Specifies how the font size of the displayed text is determined.")
|
||||||
}
|
}
|
||||||
ComboBox {
|
ComboBox {
|
||||||
|
id: fontSizeMode
|
||||||
visible: showFontSizeMode
|
visible: showFontSizeMode
|
||||||
scope: "Text"
|
scope: "Text"
|
||||||
model: ["FixedSize", "HorizontalFit", "VerticalFit", "Fit"]
|
model: ["FixedSize", "HorizontalFit", "VerticalFit", "Fit"]
|
||||||
@@ -131,6 +147,48 @@ Section {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
visible: showFontSizeMode
|
||||||
|
text: qsTr("Minimum size")
|
||||||
|
}
|
||||||
|
SecondColumnLayout {
|
||||||
|
visible: showFontSizeMode
|
||||||
|
|
||||||
|
SpinBox {
|
||||||
|
enabled: fontSizeMode.currentIndex !== 0
|
||||||
|
minimumValue: 0
|
||||||
|
maximumValue: 500
|
||||||
|
decimals: 0
|
||||||
|
backendValue: backendValues.minimumPixelSize
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.minimumWidth: 60
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: qsTr("Pixel")
|
||||||
|
tooltip: qsTr("Specifies the minimum font pixel size of scaled text.")
|
||||||
|
width: 42
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: 4
|
||||||
|
height: 4
|
||||||
|
}
|
||||||
|
|
||||||
|
SpinBox {
|
||||||
|
enabled: fontSizeMode.currentIndex !== 0
|
||||||
|
minimumValue: 0
|
||||||
|
maximumValue: 500
|
||||||
|
decimals: 0
|
||||||
|
backendValue: backendValues.minimumPointSize
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.minimumWidth: 60
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: qsTr("Point")
|
||||||
|
tooltip: qsTr("Specifies the minimum font point size of scaled text.")
|
||||||
|
width: 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
visible: showLineHeight
|
visible: showLineHeight
|
||||||
@@ -148,5 +206,17 @@ Section {
|
|||||||
stepSize: 0.1
|
stepSize: 0.1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
visible: showLineHeight
|
||||||
|
text: qsTr("Line height mode")
|
||||||
|
toolTip: qsTr("Determines how the line height is specified.")
|
||||||
|
}
|
||||||
|
ComboBox {
|
||||||
|
visible: showLineHeight
|
||||||
|
scope: "Text"
|
||||||
|
model: ["ProportionalHeight", "FixedHeight"]
|
||||||
|
backendValue: backendValues.lineHeightMode
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,98 +26,4 @@
|
|||||||
pragma Singleton
|
pragma Singleton
|
||||||
import QtQuick 2.10
|
import QtQuick 2.10
|
||||||
|
|
||||||
QtObject {
|
InternalConstants {}
|
||||||
readonly property int width: 1920
|
|
||||||
readonly property int height: 1080
|
|
||||||
readonly property FontLoader mySystemFont: FontLoader {
|
|
||||||
name: "Arial"
|
|
||||||
}
|
|
||||||
readonly property FontLoader controlIcons: FontLoader {
|
|
||||||
source: "icons.ttf"
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property string actionIcon: "\u0021"
|
|
||||||
readonly property string actionIconBinding: "\u0022"
|
|
||||||
readonly property string addColumnAfter: "\u0023"
|
|
||||||
readonly property string addColumnBefore: "\u0024"
|
|
||||||
readonly property string addFile: "\u0025"
|
|
||||||
readonly property string addRowAfter: "\u0026"
|
|
||||||
readonly property string addRowBefore: "\u0027"
|
|
||||||
readonly property string addTable: "\u0028"
|
|
||||||
readonly property string alignBottom: "\u0029"
|
|
||||||
readonly property string alignCenterHorizontal: "\u002A"
|
|
||||||
readonly property string alignCenterVertical: "\u002B"
|
|
||||||
readonly property string alignLeft: "\u002C"
|
|
||||||
readonly property string alignRight: "\u002D"
|
|
||||||
readonly property string alignTo: "\u002E"
|
|
||||||
readonly property string alignTop: "\u002F"
|
|
||||||
readonly property string anchorBaseline: "\u0030"
|
|
||||||
readonly property string anchorBottom: "\u0031"
|
|
||||||
readonly property string anchorFill: "\u0032"
|
|
||||||
readonly property string anchorLeft: "\u0033"
|
|
||||||
readonly property string anchorRight: "\u0034"
|
|
||||||
readonly property string anchorTop: "\u0035"
|
|
||||||
readonly property string annotationBubble: "\u0036"
|
|
||||||
readonly property string annotationDecal: "\u0037"
|
|
||||||
readonly property string centerHorizontal: "\u0038"
|
|
||||||
readonly property string centerVertical: "\u0039"
|
|
||||||
readonly property string closeCross: "\u003A"
|
|
||||||
readonly property string deleteColumn: "\u003B"
|
|
||||||
readonly property string deleteRow: "\u003C"
|
|
||||||
readonly property string deleteTable: "\u003D"
|
|
||||||
readonly property string distributeBottom: "\u003E"
|
|
||||||
readonly property string distributeCenterHorizontal: "\u003F"
|
|
||||||
readonly property string distributeCenterVertical: "\u0040"
|
|
||||||
readonly property string distributeLeft: "\u0041"
|
|
||||||
readonly property string distributeOriginBottomRight: "\u0042"
|
|
||||||
readonly property string distributeOriginCenter: "\u0043"
|
|
||||||
readonly property string distributeOriginNone: "\u0044"
|
|
||||||
readonly property string distributeOriginTopLeft: "\u0045"
|
|
||||||
readonly property string distributeRight: "\u0046"
|
|
||||||
readonly property string distributeSpacingHorizontal: "\u0047"
|
|
||||||
readonly property string distributeSpacingVertical: "\u0048"
|
|
||||||
readonly property string distributeTop: "\u0049"
|
|
||||||
readonly property string edit: "\u004A"
|
|
||||||
readonly property string fontStyleBold: "\u004B"
|
|
||||||
readonly property string fontStyleItalic: "\u004C"
|
|
||||||
readonly property string fontStyleStrikethrough: "\u004D"
|
|
||||||
readonly property string fontStyleUnderline: "\u004E"
|
|
||||||
readonly property string mergeCells: "\u004F"
|
|
||||||
readonly property string redo: "\u0050"
|
|
||||||
readonly property string splitColumns: "\u0051"
|
|
||||||
readonly property string splitRows: "\u0052"
|
|
||||||
readonly property string testIcon: "\u0053"
|
|
||||||
readonly property string textAlignBottom: "\u0054"
|
|
||||||
readonly property string textAlignCenter: "\u0055"
|
|
||||||
readonly property string textAlignLeft: "\u0056"
|
|
||||||
readonly property string textAlignMiddle: "\u0057"
|
|
||||||
readonly property string textAlignRight: "\u0058"
|
|
||||||
readonly property string textAlignTop: "\u0059"
|
|
||||||
readonly property string textBulletList: "\u005A"
|
|
||||||
readonly property string textFullJustification: "\u005B"
|
|
||||||
readonly property string textNumberedList: "\u005C"
|
|
||||||
readonly property string tickIcon: "\u005D"
|
|
||||||
readonly property string triState: "\u005E"
|
|
||||||
readonly property string undo: "\u005F"
|
|
||||||
readonly property string upDownIcon: "\u0060"
|
|
||||||
readonly property string upDownSquare2: "\u0061"
|
|
||||||
|
|
||||||
readonly property font iconFont: Qt.font({
|
|
||||||
"family": controlIcons.name,
|
|
||||||
"pixelSize": 12
|
|
||||||
})
|
|
||||||
|
|
||||||
readonly property font font: Qt.font({
|
|
||||||
"family": mySystemFont.name,
|
|
||||||
"pointSize": Qt.application.font.pixelSize
|
|
||||||
})
|
|
||||||
|
|
||||||
readonly property font largeFont: Qt.font({
|
|
||||||
"family": mySystemFont.name,
|
|
||||||
"pointSize": Qt.application.font.pixelSize * 1.6
|
|
||||||
})
|
|
||||||
|
|
||||||
readonly property color backgroundColor: "#c2c2c2"
|
|
||||||
|
|
||||||
readonly property bool showActionIndicatorBackground: false
|
|
||||||
}
|
|
||||||
|
@@ -0,0 +1,131 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 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.10
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
readonly property int width: 1920
|
||||||
|
readonly property int height: 1080
|
||||||
|
readonly property FontLoader mySystemFont: FontLoader {
|
||||||
|
name: "Arial"
|
||||||
|
}
|
||||||
|
readonly property FontLoader controlIcons: FontLoader {
|
||||||
|
source: "icons.ttf"
|
||||||
|
}
|
||||||
|
|
||||||
|
objectName: "internalConstantsObject"
|
||||||
|
|
||||||
|
readonly property string actionIcon: "\u0021"
|
||||||
|
readonly property string actionIconBinding: "\u0022"
|
||||||
|
readonly property string addColumnAfter: "\u0023"
|
||||||
|
readonly property string addColumnBefore: "\u0024"
|
||||||
|
readonly property string addFile: "\u0025"
|
||||||
|
readonly property string addRowAfter: "\u0026"
|
||||||
|
readonly property string addRowBefore: "\u0027"
|
||||||
|
readonly property string addTable: "\u0028"
|
||||||
|
readonly property string adsClose: "\u0029"
|
||||||
|
readonly property string adsDetach: "\u002A"
|
||||||
|
readonly property string adsDropDown: "\u002B"
|
||||||
|
readonly property string alignBottom: "\u002C"
|
||||||
|
readonly property string alignCenterHorizontal: "\u002D"
|
||||||
|
readonly property string alignCenterVertical: "\u002E"
|
||||||
|
readonly property string alignLeft: "\u002F"
|
||||||
|
readonly property string alignRight: "\u0030"
|
||||||
|
readonly property string alignTo: "\u0031"
|
||||||
|
readonly property string alignTop: "\u0032"
|
||||||
|
readonly property string anchorBaseline: "\u0033"
|
||||||
|
readonly property string anchorBottom: "\u0034"
|
||||||
|
readonly property string anchorFill: "\u0035"
|
||||||
|
readonly property string anchorLeft: "\u0036"
|
||||||
|
readonly property string anchorRight: "\u0037"
|
||||||
|
readonly property string anchorTop: "\u0038"
|
||||||
|
readonly property string annotationBubble: "\u0039"
|
||||||
|
readonly property string annotationDecal: "\u003A"
|
||||||
|
readonly property string centerHorizontal: "\u003B"
|
||||||
|
readonly property string centerVertical: "\u003C"
|
||||||
|
readonly property string closeCross: "\u003D"
|
||||||
|
readonly property string decisionNode: "\u003E"
|
||||||
|
readonly property string deleteColumn: "\u003F"
|
||||||
|
readonly property string deleteRow: "\u0040"
|
||||||
|
readonly property string deleteTable: "\u0041"
|
||||||
|
readonly property string detach: "\u0042"
|
||||||
|
readonly property string distributeBottom: "\u0043"
|
||||||
|
readonly property string distributeCenterHorizontal: "\u0044"
|
||||||
|
readonly property string distributeCenterVertical: "\u0045"
|
||||||
|
readonly property string distributeLeft: "\u0046"
|
||||||
|
readonly property string distributeOriginBottomRight: "\u0047"
|
||||||
|
readonly property string distributeOriginCenter: "\u0048"
|
||||||
|
readonly property string distributeOriginNone: "\u0049"
|
||||||
|
readonly property string distributeOriginTopLeft: "\u004A"
|
||||||
|
readonly property string distributeRight: "\u004B"
|
||||||
|
readonly property string distributeSpacingHorizontal: "\u004C"
|
||||||
|
readonly property string distributeSpacingVertical: "\u004D"
|
||||||
|
readonly property string distributeTop: "\u004E"
|
||||||
|
readonly property string edit: "\u004F"
|
||||||
|
readonly property string fontStyleBold: "\u0050"
|
||||||
|
readonly property string fontStyleItalic: "\u0051"
|
||||||
|
readonly property string fontStyleStrikethrough: "\u0052"
|
||||||
|
readonly property string fontStyleUnderline: "\u0053"
|
||||||
|
readonly property string mergeCells: "\u0054"
|
||||||
|
readonly property string redo: "\u0055"
|
||||||
|
readonly property string splitColumns: "\u0056"
|
||||||
|
readonly property string splitRows: "\u0057"
|
||||||
|
readonly property string startNode: "\u0058"
|
||||||
|
readonly property string testIcon: "\u0059"
|
||||||
|
readonly property string textAlignBottom: "\u005A"
|
||||||
|
readonly property string textAlignCenter: "\u005B"
|
||||||
|
readonly property string textAlignLeft: "\u005C"
|
||||||
|
readonly property string textAlignMiddle: "\u005D"
|
||||||
|
readonly property string textAlignRight: "\u005E"
|
||||||
|
readonly property string textAlignTop: "\u005F"
|
||||||
|
readonly property string textBulletList: "\u0060"
|
||||||
|
readonly property string textFullJustification: "\u0061"
|
||||||
|
readonly property string textNumberedList: "\u0062"
|
||||||
|
readonly property string tickIcon: "\u0063"
|
||||||
|
readonly property string triState: "\u0064"
|
||||||
|
readonly property string undo: "\u0065"
|
||||||
|
readonly property string upDownIcon: "\u0066"
|
||||||
|
readonly property string upDownSquare2: "\u0067"
|
||||||
|
readonly property string wildcard: "\u0068"
|
||||||
|
|
||||||
|
readonly property font iconFont: Qt.font({
|
||||||
|
"family": controlIcons.name,
|
||||||
|
"pixelSize": 12
|
||||||
|
})
|
||||||
|
|
||||||
|
readonly property font font: Qt.font({
|
||||||
|
"family": mySystemFont.name,
|
||||||
|
"pointSize": Qt.application.font.pixelSize
|
||||||
|
})
|
||||||
|
|
||||||
|
readonly property font largeFont: Qt.font({
|
||||||
|
"family": mySystemFont.name,
|
||||||
|
"pointSize": Qt.application.font.pixelSize * 1.6
|
||||||
|
})
|
||||||
|
|
||||||
|
readonly property color backgroundColor: "#c2c2c2"
|
||||||
|
|
||||||
|
readonly property bool showActionIndicatorBackground: false
|
||||||
|
}
|
Binary file not shown.
@@ -1,2 +1,4 @@
|
|||||||
singleton Values 1.0 Values.qml
|
singleton Values 1.0 Values.qml
|
||||||
singleton Constants 1.0 Constants.qml
|
singleton Constants 1.0 Constants.qml
|
||||||
|
InternalConstants 1.0 InternalConstants.qml
|
||||||
|
|
||||||
|
@@ -107,10 +107,11 @@ enum eDragState {
|
|||||||
* The different icons used in the UI
|
* The different icons used in the UI
|
||||||
*/
|
*/
|
||||||
enum eIcon {
|
enum eIcon {
|
||||||
TabCloseIcon, //!< TabCloseIcon
|
TabCloseIcon, //!< TabCloseIcon
|
||||||
DockAreaMenuIcon, //!< DockAreaMenuIcon
|
DockAreaMenuIcon, //!< DockAreaMenuIcon
|
||||||
DockAreaUndockIcon, //!< DockAreaUndockIcon
|
DockAreaUndockIcon, //!< DockAreaUndockIcon
|
||||||
DockAreaCloseIcon, //!< DockAreaCloseIcon
|
DockAreaCloseIcon, //!< DockAreaCloseIcon
|
||||||
|
FloatingWidgetCloseIcon, //!< FloatingWidgetCloseIcon
|
||||||
|
|
||||||
IconCount, //!< just a delimiter for range checks
|
IconCount, //!< just a delimiter for range checks
|
||||||
};
|
};
|
||||||
|
@@ -132,6 +132,7 @@ namespace ADS
|
|||||||
|
|
||||||
void DockAreaTitleBarPrivate::createButtons()
|
void DockAreaTitleBarPrivate::createButtons()
|
||||||
{
|
{
|
||||||
|
const QSize iconSize(14, 14);
|
||||||
QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
|
QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
|
||||||
// Tabs menu button
|
// Tabs menu button
|
||||||
m_tabsMenuButton = new TitleBarButton(testConfigFlag(DockManager::DockAreaHasTabsMenuButton));
|
m_tabsMenuButton = new TitleBarButton(testConfigFlag(DockManager::DockAreaHasTabsMenuButton));
|
||||||
@@ -149,6 +150,7 @@ namespace ADS
|
|||||||
m_tabsMenuButton->setMenu(tabsMenu);
|
m_tabsMenuButton->setMenu(tabsMenu);
|
||||||
internal::setToolTip(m_tabsMenuButton, QObject::tr("List All Tabs"));
|
internal::setToolTip(m_tabsMenuButton, QObject::tr("List All Tabs"));
|
||||||
m_tabsMenuButton->setSizePolicy(sizePolicy);
|
m_tabsMenuButton->setSizePolicy(sizePolicy);
|
||||||
|
m_tabsMenuButton->setIconSize(iconSize);
|
||||||
m_layout->addWidget(m_tabsMenuButton, 0);
|
m_layout->addWidget(m_tabsMenuButton, 0);
|
||||||
QObject::connect(m_tabsMenuButton->menu(),
|
QObject::connect(m_tabsMenuButton->menu(),
|
||||||
&QMenu::triggered,
|
&QMenu::triggered,
|
||||||
@@ -164,6 +166,7 @@ namespace ADS
|
|||||||
QStyle::SP_TitleBarNormalButton,
|
QStyle::SP_TitleBarNormalButton,
|
||||||
ADS::DockAreaUndockIcon);
|
ADS::DockAreaUndockIcon);
|
||||||
m_undockButton->setSizePolicy(sizePolicy);
|
m_undockButton->setSizePolicy(sizePolicy);
|
||||||
|
m_undockButton->setIconSize(iconSize);
|
||||||
m_layout->addWidget(m_undockButton, 0);
|
m_layout->addWidget(m_undockButton, 0);
|
||||||
QObject::connect(m_undockButton,
|
QObject::connect(m_undockButton,
|
||||||
&QToolButton::clicked,
|
&QToolButton::clicked,
|
||||||
@@ -183,7 +186,7 @@ namespace ADS
|
|||||||
internal::setToolTip(m_closeButton, QObject::tr("Close Group"));
|
internal::setToolTip(m_closeButton, QObject::tr("Close Group"));
|
||||||
}
|
}
|
||||||
m_closeButton->setSizePolicy(sizePolicy);
|
m_closeButton->setSizePolicy(sizePolicy);
|
||||||
m_closeButton->setIconSize(QSize(16, 16));
|
m_closeButton->setIconSize(iconSize);
|
||||||
m_layout->addWidget(m_closeButton, 0);
|
m_layout->addWidget(m_closeButton, 0);
|
||||||
QObject::connect(m_closeButton,
|
QObject::connect(m_closeButton,
|
||||||
&QToolButton::clicked,
|
&QToolButton::clicked,
|
||||||
|
@@ -168,12 +168,18 @@ namespace ADS
|
|||||||
m_titleLabel->setText(m_dockWidget->windowTitle());
|
m_titleLabel->setText(m_dockWidget->windowTitle());
|
||||||
m_titleLabel->setObjectName("dockWidgetTabLabel");
|
m_titleLabel->setObjectName("dockWidgetTabLabel");
|
||||||
m_titleLabel->setAlignment(Qt::AlignCenter);
|
m_titleLabel->setAlignment(Qt::AlignCenter);
|
||||||
QObject::connect(m_titleLabel, &ElidingLabel::elidedChanged, q, &DockWidgetTab::elidedChanged);
|
QObject::connect(m_titleLabel,
|
||||||
|
&ElidingLabel::elidedChanged,
|
||||||
|
q,
|
||||||
|
&DockWidgetTab::elidedChanged);
|
||||||
|
|
||||||
m_closeButton = createCloseButton();
|
m_closeButton = createCloseButton();
|
||||||
m_closeButton->setObjectName("tabCloseButton");
|
m_closeButton->setObjectName("tabCloseButton");
|
||||||
internal::setButtonIcon(m_closeButton, QStyle::SP_TitleBarCloseButton, TabCloseIcon);
|
internal::setButtonIcon(m_closeButton,
|
||||||
|
QStyle::SP_TitleBarCloseButton,
|
||||||
|
TabCloseIcon);
|
||||||
m_closeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
m_closeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
|
m_closeButton->setIconSize(QSize(14, 14));
|
||||||
q->onDockWidgetFeaturesChanged();
|
q->onDockWidgetFeaturesChanged();
|
||||||
internal::setToolTip(m_closeButton, QObject::tr("Close Tab"));
|
internal::setToolTip(m_closeButton, QObject::tr("Close Tab"));
|
||||||
QObject::connect(m_closeButton,
|
QObject::connect(m_closeButton,
|
||||||
@@ -189,11 +195,11 @@ namespace ADS
|
|||||||
boxLayout->setContentsMargins(2 * spacing, 0, 0, 0);
|
boxLayout->setContentsMargins(2 * spacing, 0, 0, 0);
|
||||||
boxLayout->setSpacing(0);
|
boxLayout->setSpacing(0);
|
||||||
q->setLayout(boxLayout);
|
q->setLayout(boxLayout);
|
||||||
boxLayout->addWidget(m_titleLabel, 1);
|
boxLayout->addWidget(m_titleLabel, 1, Qt::AlignVCenter);
|
||||||
boxLayout->addSpacing(spacing);
|
boxLayout->addSpacing(spacing);
|
||||||
boxLayout->addWidget(m_closeButton);
|
boxLayout->addWidget(m_closeButton, 0, Qt::AlignVCenter);
|
||||||
boxLayout->addSpacing(qRound(spacing * 4.0 / 3.0));
|
boxLayout->addSpacing(qRound(spacing * 4.0 / 3.0));
|
||||||
boxLayout->setAlignment(Qt::AlignCenter);
|
boxLayout->setAlignment(Qt::AlignCenter | Qt::AlignVCenter);
|
||||||
|
|
||||||
m_titleLabel->setVisible(true);
|
m_titleLabel->setVisible(true);
|
||||||
}
|
}
|
||||||
|
@@ -51,7 +51,7 @@ namespace ADS {
|
|||||||
*/
|
*/
|
||||||
IconProviderPrivate(IconProvider *parent);
|
IconProviderPrivate(IconProvider *parent);
|
||||||
};
|
};
|
||||||
// struct LedArrayPanelPrivate
|
// struct IconProviderPrivate
|
||||||
|
|
||||||
IconProviderPrivate::IconProviderPrivate(IconProvider *parent)
|
IconProviderPrivate::IconProviderPrivate(IconProvider *parent)
|
||||||
: q(parent)
|
: q(parent)
|
||||||
|
@@ -41,7 +41,7 @@
|
|||||||
namespace ADS {
|
namespace ADS {
|
||||||
|
|
||||||
using TabLabelType = ElidingLabel;
|
using TabLabelType = ElidingLabel;
|
||||||
using tCloseButton = QPushButton;
|
using CloseButtonType = QPushButton;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Private data class of public interface CFloatingWidgetTitleBar
|
* @brief Private data class of public interface CFloatingWidgetTitleBar
|
||||||
@@ -52,7 +52,7 @@ public:
|
|||||||
FloatingWidgetTitleBar *q; ///< public interface class
|
FloatingWidgetTitleBar *q; ///< public interface class
|
||||||
QLabel *m_iconLabel = nullptr;
|
QLabel *m_iconLabel = nullptr;
|
||||||
TabLabelType *m_titleLabel = nullptr;
|
TabLabelType *m_titleLabel = nullptr;
|
||||||
tCloseButton *m_closeButton = nullptr;
|
CloseButtonType *m_closeButton = nullptr;
|
||||||
FloatingDockContainer *m_floatingWidget = nullptr;
|
FloatingDockContainer *m_floatingWidget = nullptr;
|
||||||
eDragState m_dragState = DraggingInactive;
|
eDragState m_dragState = DraggingInactive;
|
||||||
|
|
||||||
@@ -74,22 +74,20 @@ void FloatingWidgetTitleBarPrivate::createLayout()
|
|||||||
m_titleLabel->setObjectName("floatingTitleLabel");
|
m_titleLabel->setObjectName("floatingTitleLabel");
|
||||||
m_titleLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
m_titleLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||||
|
|
||||||
m_closeButton = new tCloseButton();
|
m_closeButton = new CloseButtonType();
|
||||||
m_closeButton->setObjectName("floatingTitleCloseButton");
|
m_closeButton->setObjectName("floatingTitleCloseButton");
|
||||||
m_closeButton->setFlat(true);
|
m_closeButton->setFlat(true);
|
||||||
|
internal::setButtonIcon(m_closeButton,
|
||||||
// The standard icons do does not look good on high DPI screens
|
QStyle::SP_TitleBarCloseButton,
|
||||||
QIcon closeIcon;
|
ADS::FloatingWidgetCloseIcon);
|
||||||
QPixmap normalPixmap = q->style()->standardPixmap(QStyle::SP_TitleBarCloseButton,
|
|
||||||
nullptr,
|
|
||||||
m_closeButton);
|
|
||||||
closeIcon.addPixmap(normalPixmap, QIcon::Normal);
|
|
||||||
closeIcon.addPixmap(internal::createTransparentPixmap(normalPixmap, 0.25), QIcon::Disabled);
|
|
||||||
m_closeButton->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
|
|
||||||
m_closeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
m_closeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
|
m_closeButton->setIconSize(QSize(14, 14));
|
||||||
m_closeButton->setVisible(true);
|
m_closeButton->setVisible(true);
|
||||||
m_closeButton->setFocusPolicy(Qt::NoFocus);
|
m_closeButton->setFocusPolicy(Qt::NoFocus);
|
||||||
q->connect(m_closeButton, &QPushButton::clicked, q, &FloatingWidgetTitleBar::closeRequested);
|
QObject::connect(m_closeButton,
|
||||||
|
&QPushButton::clicked,
|
||||||
|
q,
|
||||||
|
&FloatingWidgetTitleBar::closeRequested);
|
||||||
|
|
||||||
QFontMetrics fontMetrics(m_titleLabel->font());
|
QFontMetrics fontMetrics(m_titleLabel->font());
|
||||||
int spacing = qRound(fontMetrics.height() / 4.0);
|
int spacing = qRound(fontMetrics.height() / 4.0);
|
||||||
|
@@ -22,6 +22,7 @@ add_qtc_library(Sqlite
|
|||||||
sqlitetable.h
|
sqlitetable.h
|
||||||
sqlitetransaction.h
|
sqlitetransaction.h
|
||||||
sqlitewritestatement.cpp sqlitewritestatement.h
|
sqlitewritestatement.cpp sqlitewritestatement.h
|
||||||
|
sqlitevalue.h
|
||||||
sqlstatementbuilder.cpp sqlstatementbuilder.h
|
sqlstatementbuilder.cpp sqlstatementbuilder.h
|
||||||
sqlstatementbuilderexception.h
|
sqlstatementbuilderexception.h
|
||||||
utf8string.cpp utf8string.h
|
utf8string.cpp utf8string.h
|
||||||
|
@@ -32,6 +32,7 @@ HEADERS += \
|
|||||||
$$PWD/sqlitereadstatement.h \
|
$$PWD/sqlitereadstatement.h \
|
||||||
$$PWD/sqlitereadwritestatement.h \
|
$$PWD/sqlitereadwritestatement.h \
|
||||||
$$PWD/sqlitetransaction.h \
|
$$PWD/sqlitetransaction.h \
|
||||||
|
$$PWD/sqlitevalue.h \
|
||||||
$$PWD/sqlitewritestatement.h \
|
$$PWD/sqlitewritestatement.h \
|
||||||
$$PWD/sqlstatementbuilder.h \
|
$$PWD/sqlstatementbuilder.h \
|
||||||
$$PWD/sqlstatementbuilderexception.h \
|
$$PWD/sqlstatementbuilderexception.h \
|
||||||
|
@@ -190,6 +190,21 @@ void BaseStatement::bind(int index, Utils::SmallStringView text)
|
|||||||
checkForBindingError(resultCode);
|
checkForBindingError(resultCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BaseStatement::bind(int index, const Value &value)
|
||||||
|
{
|
||||||
|
switch (value.type()) {
|
||||||
|
case ValueType::Integer:
|
||||||
|
bind(index, value.toInteger());
|
||||||
|
break;
|
||||||
|
case ValueType::Float:
|
||||||
|
bind(index, value.toFloat());
|
||||||
|
break;
|
||||||
|
case ValueType::String:
|
||||||
|
bind(index, value.toStringView());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
void BaseStatement::bind(Utils::SmallStringView name, Type value)
|
void BaseStatement::bind(Utils::SmallStringView name, Type value)
|
||||||
{
|
{
|
||||||
@@ -498,12 +513,34 @@ StringType BaseStatement::fetchValue(int column) const
|
|||||||
return convertToTextForColumn<StringType>(m_compiledStatement.get(), column);
|
return convertToTextForColumn<StringType>(m_compiledStatement.get(), column);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template SQLITE_EXPORT Utils::SmallStringView BaseStatement::fetchValue<Utils::SmallStringView>(
|
||||||
|
int column) const;
|
||||||
|
template SQLITE_EXPORT Utils::SmallString BaseStatement::fetchValue<Utils::SmallString>(
|
||||||
|
int column) const;
|
||||||
|
template SQLITE_EXPORT Utils::PathString BaseStatement::fetchValue<Utils::PathString>(
|
||||||
|
int column) const;
|
||||||
|
|
||||||
Utils::SmallStringView BaseStatement::fetchSmallStringViewValue(int column) const
|
Utils::SmallStringView BaseStatement::fetchSmallStringViewValue(int column) const
|
||||||
{
|
{
|
||||||
return fetchValue<Utils::SmallStringView>(column);
|
return fetchValue<Utils::SmallStringView>(column);
|
||||||
}
|
}
|
||||||
|
|
||||||
template SQLITE_EXPORT Utils::SmallStringView BaseStatement::fetchValue<Utils::SmallStringView>(int column) const;
|
ValueView BaseStatement::fetchValueView(int column) const
|
||||||
template SQLITE_EXPORT Utils::SmallString BaseStatement::fetchValue<Utils::SmallString>(int column) const;
|
{
|
||||||
template SQLITE_EXPORT Utils::PathString BaseStatement::fetchValue<Utils::PathString>(int column) const;
|
int dataType = sqlite3_column_type(m_compiledStatement.get(), column);
|
||||||
|
switch (dataType) {
|
||||||
|
case SQLITE_INTEGER:
|
||||||
|
return ValueView::create(fetchLongLongValue(column));
|
||||||
|
case SQLITE_FLOAT:
|
||||||
|
return ValueView::create(fetchDoubleValue(column));
|
||||||
|
case SQLITE3_TEXT:
|
||||||
|
return ValueView::create(fetchValue<Utils::SmallStringView>(column));
|
||||||
|
case SQLITE_BLOB:
|
||||||
|
case SQLITE_NULL:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValueView::create(0LL);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Sqlite
|
} // namespace Sqlite
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include "sqliteglobal.h"
|
#include "sqliteglobal.h"
|
||||||
|
|
||||||
#include "sqliteexception.h"
|
#include "sqliteexception.h"
|
||||||
|
#include "sqlitevalue.h"
|
||||||
|
|
||||||
#include <utils/smallstringvector.h>
|
#include <utils/smallstringvector.h>
|
||||||
|
|
||||||
@@ -67,6 +68,7 @@ public:
|
|||||||
long long fetchLongLongValue(int column) const;
|
long long fetchLongLongValue(int column) const;
|
||||||
double fetchDoubleValue(int column) const;
|
double fetchDoubleValue(int column) const;
|
||||||
Utils::SmallStringView fetchSmallStringViewValue(int column) const;
|
Utils::SmallStringView fetchSmallStringViewValue(int column) const;
|
||||||
|
ValueView fetchValueView(int column) const;
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
Type fetchValue(int column) const;
|
Type fetchValue(int column) const;
|
||||||
int columnCount() const;
|
int columnCount() const;
|
||||||
@@ -76,11 +78,9 @@ public:
|
|||||||
void bind(int index, long long fetchValue);
|
void bind(int index, long long fetchValue);
|
||||||
void bind(int index, double fetchValue);
|
void bind(int index, double fetchValue);
|
||||||
void bind(int index, Utils::SmallStringView fetchValue);
|
void bind(int index, Utils::SmallStringView fetchValue);
|
||||||
|
void bind(int index, const Value &fetchValue);
|
||||||
|
|
||||||
void bind(int index, uint value)
|
void bind(int index, uint value) { bind(index, static_cast<long long>(value)); }
|
||||||
{
|
|
||||||
bind(index, static_cast<long long>(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
void bind(int index, long value)
|
void bind(int index, long value)
|
||||||
{
|
{
|
||||||
@@ -345,34 +345,16 @@ private:
|
|||||||
struct ValueGetter
|
struct ValueGetter
|
||||||
{
|
{
|
||||||
ValueGetter(StatementImplementation &statement, int column)
|
ValueGetter(StatementImplementation &statement, int column)
|
||||||
: statement(statement),
|
: statement(statement)
|
||||||
column(column)
|
, column(column)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
operator int()
|
operator int() { return statement.fetchIntValue(column); }
|
||||||
{
|
operator long() { return statement.fetchLongValue(column); }
|
||||||
return statement.fetchIntValue(column);
|
operator long long() { return statement.fetchLongLongValue(column); }
|
||||||
}
|
operator double() { return statement.fetchDoubleValue(column); }
|
||||||
|
operator Utils::SmallStringView() { return statement.fetchSmallStringViewValue(column); }
|
||||||
operator long()
|
operator ValueView() { return statement.fetchValueView(column); }
|
||||||
{
|
|
||||||
return statement.fetchLongValue(column);
|
|
||||||
}
|
|
||||||
|
|
||||||
operator long long()
|
|
||||||
{
|
|
||||||
return statement.fetchLongLongValue(column);
|
|
||||||
}
|
|
||||||
|
|
||||||
operator double()
|
|
||||||
{
|
|
||||||
return statement.fetchDoubleValue(column);
|
|
||||||
}
|
|
||||||
|
|
||||||
operator Utils::SmallStringView()
|
|
||||||
{
|
|
||||||
return statement.fetchSmallStringViewValue(column);
|
|
||||||
}
|
|
||||||
|
|
||||||
StatementImplementation &statement;
|
StatementImplementation &statement;
|
||||||
int column;
|
int column;
|
||||||
|
@@ -264,4 +264,12 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CannotConvert : public Exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CannotConvert(const char *whatErrorHasHappen)
|
||||||
|
: Exception(whatErrorHasHappen)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Sqlite
|
} // namespace Sqlite
|
||||||
|
300
src/libs/sqlite/sqlitevalue.h
Normal file
300
src/libs/sqlite/sqlitevalue.h
Normal file
@@ -0,0 +1,300 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 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 "sqliteexception.h"
|
||||||
|
|
||||||
|
#include <utils/smallstring.h>
|
||||||
|
#include <utils/variant.h>
|
||||||
|
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Sqlite {
|
||||||
|
|
||||||
|
enum class ValueType : unsigned char { Integer, Float, String };
|
||||||
|
|
||||||
|
template<typename StringType>
|
||||||
|
class ValueBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using VariantType = Utils::variant<long long, double, StringType>;
|
||||||
|
|
||||||
|
explicit ValueBase(VariantType &&value)
|
||||||
|
: value(value)
|
||||||
|
{}
|
||||||
|
|
||||||
|
explicit ValueBase(const char *value)
|
||||||
|
: value(Utils::SmallStringView{value})
|
||||||
|
{}
|
||||||
|
|
||||||
|
explicit ValueBase(long long value)
|
||||||
|
: value(value)
|
||||||
|
{}
|
||||||
|
explicit ValueBase(int value)
|
||||||
|
: value(static_cast<long long>(value))
|
||||||
|
{}
|
||||||
|
|
||||||
|
explicit ValueBase(uint value)
|
||||||
|
: value(static_cast<long long>(value))
|
||||||
|
{}
|
||||||
|
|
||||||
|
explicit ValueBase(double value)
|
||||||
|
: value(value)
|
||||||
|
{}
|
||||||
|
|
||||||
|
explicit ValueBase(Utils::SmallStringView value)
|
||||||
|
: value(value)
|
||||||
|
|
||||||
|
{}
|
||||||
|
|
||||||
|
long long toInteger() const { return Utils::get<int(ValueType::Integer)>(value); }
|
||||||
|
|
||||||
|
double toFloat() const { return Utils::get<int(ValueType::Float)>(value); }
|
||||||
|
|
||||||
|
Utils::SmallStringView toStringView() const
|
||||||
|
{
|
||||||
|
return Utils::get<int(ValueType::String)>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit operator QVariant() const
|
||||||
|
{
|
||||||
|
switch (type()) {
|
||||||
|
case ValueType::Integer:
|
||||||
|
return QVariant(toInteger());
|
||||||
|
case ValueType::Float:
|
||||||
|
return QVariant(toFloat());
|
||||||
|
case ValueType::String:
|
||||||
|
return QVariant(QString(toStringView()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const ValueBase &first, long long second)
|
||||||
|
{
|
||||||
|
auto maybeInteger = Utils::get_if<int(ValueType::Integer)>(&first.value);
|
||||||
|
|
||||||
|
return maybeInteger && *maybeInteger == second;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(long long first, const ValueBase &second) { return second == first; }
|
||||||
|
|
||||||
|
friend bool operator==(const ValueBase &first, double second)
|
||||||
|
{
|
||||||
|
auto maybeInteger = Utils::get_if<int(ValueType::Float)>(&first.value);
|
||||||
|
|
||||||
|
return maybeInteger && *maybeInteger == second;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const ValueBase &first, int second)
|
||||||
|
{
|
||||||
|
return first == static_cast<long long>(second);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(int first, const ValueBase &second) { return second == first; }
|
||||||
|
|
||||||
|
friend bool operator==(const ValueBase &first, uint second)
|
||||||
|
{
|
||||||
|
return first == static_cast<long long>(second);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(uint first, const ValueBase &second) { return second == first; }
|
||||||
|
|
||||||
|
friend bool operator==(double first, const ValueBase &second) { return second == first; }
|
||||||
|
|
||||||
|
friend bool operator==(const ValueBase &first, Utils::SmallStringView second)
|
||||||
|
{
|
||||||
|
auto maybeInteger = Utils::get_if<int(ValueType::String)>(&first.value);
|
||||||
|
|
||||||
|
return maybeInteger && *maybeInteger == second;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(Utils::SmallStringView first, const ValueBase &second)
|
||||||
|
{
|
||||||
|
return second == first;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const ValueBase &first, const QString &second)
|
||||||
|
{
|
||||||
|
auto maybeInteger = Utils::get_if<int(ValueType::String)>(&first.value);
|
||||||
|
|
||||||
|
return maybeInteger
|
||||||
|
&& second == QLatin1String{maybeInteger->data(), int(maybeInteger->size())};
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const QString &first, const ValueBase &second)
|
||||||
|
{
|
||||||
|
return second == first;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const ValueBase &first, const char *second)
|
||||||
|
{
|
||||||
|
return first == Utils::SmallStringView{second};
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const char *first, const ValueBase &second) { return second == first; }
|
||||||
|
|
||||||
|
friend bool operator==(const ValueBase &first, const ValueBase &second)
|
||||||
|
{
|
||||||
|
return first.value == second.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const ValueBase &first, const ValueBase &second)
|
||||||
|
{
|
||||||
|
return !(first.value == second.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueType type() const
|
||||||
|
{
|
||||||
|
switch (value.index()) {
|
||||||
|
case 0:
|
||||||
|
return ValueType::Integer;
|
||||||
|
case 1:
|
||||||
|
return ValueType::Float;
|
||||||
|
case 2:
|
||||||
|
return ValueType::String;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
VariantType value;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ValueView : public ValueBase<Utils::SmallStringView>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ValueView(ValueBase &&base)
|
||||||
|
: ValueBase(std::move(base))
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
static ValueView create(Type &&value)
|
||||||
|
{
|
||||||
|
return ValueView{ValueBase{value}};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Value : public ValueBase<Utils::SmallString>
|
||||||
|
{
|
||||||
|
using Base = ValueBase<Utils::SmallString>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using Base::Base;
|
||||||
|
|
||||||
|
explicit Value(ValueView view)
|
||||||
|
: ValueBase(convert(view))
|
||||||
|
{}
|
||||||
|
|
||||||
|
explicit Value(const QVariant &value)
|
||||||
|
: ValueBase(convert(value))
|
||||||
|
{}
|
||||||
|
|
||||||
|
explicit Value(Utils::SmallString &&value)
|
||||||
|
: ValueBase(VariantType{std::move(value)})
|
||||||
|
{}
|
||||||
|
|
||||||
|
explicit Value(const Utils::SmallString &value)
|
||||||
|
: ValueBase(Utils::SmallStringView(value))
|
||||||
|
{}
|
||||||
|
|
||||||
|
explicit Value(const QString &value)
|
||||||
|
: ValueBase(VariantType{Utils::SmallString(value)})
|
||||||
|
{}
|
||||||
|
|
||||||
|
friend bool operator!=(const Value &first, const Value &second)
|
||||||
|
{
|
||||||
|
return !(first.value == second.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
friend bool operator!=(const Value &first, const Type &second)
|
||||||
|
{
|
||||||
|
return !(first == second);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
friend bool operator!=(const Type &first, const Value &second)
|
||||||
|
{
|
||||||
|
return !(first == second);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const Value &first, const ValueView &second)
|
||||||
|
{
|
||||||
|
if (first.type() != second.type())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (first.type()) {
|
||||||
|
case ValueType::Integer:
|
||||||
|
return first.toInteger() == second.toInteger();
|
||||||
|
case ValueType::Float:
|
||||||
|
return first.toFloat() == second.toFloat();
|
||||||
|
case ValueType::String:
|
||||||
|
return first.toStringView() == second.toStringView();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const ValueView &first, const Value &second) { return second == first; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Base::VariantType convert(const QVariant &value)
|
||||||
|
{
|
||||||
|
switch (value.type()) {
|
||||||
|
case QVariant::Int:
|
||||||
|
return VariantType{static_cast<long long>(value.toInt())};
|
||||||
|
case QVariant::LongLong:
|
||||||
|
return VariantType{value.toLongLong()};
|
||||||
|
case QVariant::UInt:
|
||||||
|
return VariantType{static_cast<long long>(value.toUInt())};
|
||||||
|
case QVariant::Double:
|
||||||
|
return VariantType{value.toFloat()};
|
||||||
|
case QVariant::String:
|
||||||
|
return VariantType{value.toString()};
|
||||||
|
default:
|
||||||
|
throw CannotConvert("Cannot convert this QVariant to a ValueBase");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Base::VariantType convert(ValueView view)
|
||||||
|
{
|
||||||
|
switch (view.type()) {
|
||||||
|
case ValueType::Integer:
|
||||||
|
return VariantType{view.toInteger()};
|
||||||
|
case ValueType::Float:
|
||||||
|
return VariantType{view.toFloat()};
|
||||||
|
case ValueType::String:
|
||||||
|
return VariantType{view.toStringView()};
|
||||||
|
default:
|
||||||
|
throw CannotConvert("Cannot convert this QVariant to a ValueBase");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using Values = std::vector<Value>;
|
||||||
|
} // namespace Sqlite
|
@@ -28,6 +28,8 @@
|
|||||||
#include "theme/theme.h"
|
#include "theme/theme.h"
|
||||||
#include "hostosinfo.h"
|
#include "hostosinfo.h"
|
||||||
|
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QPixmapCache>
|
#include <QPixmapCache>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
@@ -35,6 +37,7 @@
|
|||||||
#include <QCommonStyle>
|
#include <QCommonStyle>
|
||||||
#include <QStyleOption>
|
#include <QStyleOption>
|
||||||
#include <QWindow>
|
#include <QWindow>
|
||||||
|
#include <QFontDatabase>
|
||||||
#include <qmath.h>
|
#include <qmath.h>
|
||||||
|
|
||||||
// Clamps float color values within (0, 255)
|
// Clamps float color values within (0, 255)
|
||||||
@@ -542,6 +545,48 @@ QLinearGradient StyleHelper::statusBarGradient(const QRect &statusBarRect)
|
|||||||
return grad;
|
return grad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QIcon StyleHelper::getIconFromIconFont(const QString &fontName, const QString &iconSymbol, int fontSize, int iconSize, QColor color)
|
||||||
|
{
|
||||||
|
QFontDatabase a;
|
||||||
|
|
||||||
|
QTC_ASSERT(a.hasFamily(fontName), {});
|
||||||
|
|
||||||
|
if (a.hasFamily(fontName)) {
|
||||||
|
|
||||||
|
QIcon icon;
|
||||||
|
QSize size(iconSize, iconSize);
|
||||||
|
|
||||||
|
const int maxDpr = qRound(qApp->devicePixelRatio());
|
||||||
|
for (int dpr = 1; dpr <= maxDpr; dpr++) {
|
||||||
|
QPixmap pixmap(size * dpr);
|
||||||
|
pixmap.setDevicePixelRatio(dpr);
|
||||||
|
pixmap.fill(Qt::transparent);
|
||||||
|
|
||||||
|
QFont font(fontName);
|
||||||
|
font.setPixelSize(fontSize * dpr);
|
||||||
|
|
||||||
|
QPainter painter(&pixmap);
|
||||||
|
painter.save();
|
||||||
|
painter.setPen(color);
|
||||||
|
painter.setFont(font);
|
||||||
|
painter.drawText(QRectF(QPoint(0, 0), size), iconSymbol);
|
||||||
|
painter.restore();
|
||||||
|
|
||||||
|
icon.addPixmap(pixmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QIcon StyleHelper::getIconFromIconFont(const QString &fontName, const QString &iconSymbol, int fontSize, int iconSize)
|
||||||
|
{
|
||||||
|
QColor penColor = QApplication::palette("QWidget").color(QPalette::Normal, QPalette::ButtonText);
|
||||||
|
return getIconFromIconFont(fontName, iconSymbol, fontSize, iconSize, penColor);
|
||||||
|
}
|
||||||
|
|
||||||
QString StyleHelper::dpiSpecificImageFile(const QString &fileName)
|
QString StyleHelper::dpiSpecificImageFile(const QString &fileName)
|
||||||
{
|
{
|
||||||
// See QIcon::addFile()
|
// See QIcon::addFile()
|
||||||
|
@@ -93,6 +93,9 @@ public:
|
|||||||
static void tintImage(QImage &img, const QColor &tintColor);
|
static void tintImage(QImage &img, const QColor &tintColor);
|
||||||
static QLinearGradient statusBarGradient(const QRect &statusBarRect);
|
static QLinearGradient statusBarGradient(const QRect &statusBarRect);
|
||||||
|
|
||||||
|
static QIcon getIconFromIconFont(const QString &fontName, const QString &iconSymbol, int fontSize, int iconSize, QColor color);
|
||||||
|
static QIcon getIconFromIconFont(const QString &fontName, const QString &iconSymbol, int fontSize, int iconSize);
|
||||||
|
|
||||||
static QString dpiSpecificImageFile(const QString &fileName);
|
static QString dpiSpecificImageFile(const QString &fileName);
|
||||||
static QString imageFileWithResolution(const QString &fileName, int dpr);
|
static QString imageFileWithResolution(const QString &fileName, int dpr);
|
||||||
static QList<int> availableImageResolutions(const QString &fileName);
|
static QList<int> availableImageResolutions(const QString &fileName);
|
||||||
|
@@ -247,6 +247,7 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
snapper.cpp snapper.h
|
snapper.cpp snapper.h
|
||||||
snappinglinecreator.cpp snappinglinecreator.h
|
snappinglinecreator.cpp snappinglinecreator.h
|
||||||
toolbox.cpp toolbox.h
|
toolbox.cpp toolbox.h
|
||||||
|
transitiontool.cpp transitiontool.h
|
||||||
)
|
)
|
||||||
|
|
||||||
extend_qtc_plugin(QmlDesigner
|
extend_qtc_plugin(QmlDesigner
|
||||||
@@ -558,6 +559,7 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
annotationeditordialog.cpp annotationeditordialog.h annotationeditordialog.ui
|
annotationeditordialog.cpp annotationeditordialog.h annotationeditordialog.ui
|
||||||
annotationeditor.cpp annotationeditor.h
|
annotationeditor.cpp annotationeditor.h
|
||||||
annotationtool.cpp annotationtool.h
|
annotationtool.cpp annotationtool.h
|
||||||
|
globalannotationeditor.cpp globalannotationeditor.h
|
||||||
)
|
)
|
||||||
|
|
||||||
extend_qtc_plugin(QmlDesigner
|
extend_qtc_plugin(QmlDesigner
|
||||||
@@ -591,6 +593,13 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
texttool/texttool.cpp texttool/texttool.h
|
texttool/texttool.cpp texttool/texttool.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
extend_qtc_plugin(QmlDesigner
|
||||||
|
SOURCES_PREFIX components/richtexteditor
|
||||||
|
SOURCES
|
||||||
|
hyperlinkdialog.cpp hyperlinkdialog.h hyperlinkdialog.ui
|
||||||
|
richtexteditor.cpp richtexteditor.h hyperlinkdialog.ui
|
||||||
|
)
|
||||||
|
|
||||||
extend_qtc_plugin(QmlDesigner
|
extend_qtc_plugin(QmlDesigner
|
||||||
SOURCES_PREFIX components/timelineeditor
|
SOURCES_PREFIX components/timelineeditor
|
||||||
SOURCES
|
SOURCES
|
||||||
|
@@ -26,6 +26,8 @@
|
|||||||
#include "annotationcommenttab.h"
|
#include "annotationcommenttab.h"
|
||||||
#include "ui_annotationcommenttab.h"
|
#include "ui_annotationcommenttab.h"
|
||||||
|
|
||||||
|
#include "richtexteditor/richtexteditor.h"
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
AnnotationCommentTab::AnnotationCommentTab(QWidget *parent) :
|
AnnotationCommentTab::AnnotationCommentTab(QWidget *parent) :
|
||||||
@@ -34,6 +36,9 @@ AnnotationCommentTab::AnnotationCommentTab(QWidget *parent) :
|
|||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
m_editor = new RichTextEditor;
|
||||||
|
ui->formLayout->setWidget(3, QFormLayout::FieldRole, m_editor);
|
||||||
|
|
||||||
connect(ui->titleEdit, &QLineEdit::textEdited,
|
connect(ui->titleEdit, &QLineEdit::textEdited,
|
||||||
this, &AnnotationCommentTab::commentTitleChanged);
|
this, &AnnotationCommentTab::commentTitleChanged);
|
||||||
}
|
}
|
||||||
@@ -49,7 +54,7 @@ Comment AnnotationCommentTab::currentComment() const
|
|||||||
|
|
||||||
result.setTitle(ui->titleEdit->text().trimmed());
|
result.setTitle(ui->titleEdit->text().trimmed());
|
||||||
result.setAuthor(ui->authorEdit->text().trimmed());
|
result.setAuthor(ui->authorEdit->text().trimmed());
|
||||||
result.setText(ui->textEdit->toPlainText().trimmed());
|
result.setText(m_editor->richText().trimmed());
|
||||||
|
|
||||||
if (m_comment.sameContent(result))
|
if (m_comment.sameContent(result))
|
||||||
result.setTimestamp(m_comment.timestamp());
|
result.setTimestamp(m_comment.timestamp());
|
||||||
@@ -74,7 +79,7 @@ void AnnotationCommentTab::resetUI()
|
|||||||
{
|
{
|
||||||
ui->titleEdit->setText(m_comment.title());
|
ui->titleEdit->setText(m_comment.title());
|
||||||
ui->authorEdit->setText(m_comment.author());
|
ui->authorEdit->setText(m_comment.author());
|
||||||
ui->textEdit->setText(m_comment.text());
|
m_editor->setRichText(m_comment.text());
|
||||||
|
|
||||||
if (m_comment.timestamp() > 0)
|
if (m_comment.timestamp() > 0)
|
||||||
ui->timeLabel->setText(m_comment.timestampStr());
|
ui->timeLabel->setText(m_comment.timestampStr());
|
||||||
|
@@ -35,6 +35,8 @@ namespace Ui {
|
|||||||
class AnnotationCommentTab;
|
class AnnotationCommentTab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RichTextEditor;
|
||||||
|
|
||||||
class AnnotationCommentTab : public QWidget
|
class AnnotationCommentTab : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -59,6 +61,7 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::AnnotationCommentTab *ui;
|
Ui::AnnotationCommentTab *ui;
|
||||||
|
RichTextEditor *m_editor;
|
||||||
|
|
||||||
Comment m_comment;
|
Comment m_comment;
|
||||||
};
|
};
|
||||||
|
@@ -33,13 +33,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QTextEdit" name="textEdit">
|
|
||||||
<property name="tabChangesFocus">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="authorLabel">
|
<widget class="QLabel" name="authorLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -64,7 +57,6 @@
|
|||||||
<tabstops>
|
<tabstops>
|
||||||
<tabstop>titleEdit</tabstop>
|
<tabstop>titleEdit</tabstop>
|
||||||
<tabstop>authorEdit</tabstop>
|
<tabstop>authorEdit</tabstop>
|
||||||
<tabstop>textEdit</tabstop>
|
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
@@ -2,11 +2,13 @@ HEADERS += $$PWD/annotationtool.h
|
|||||||
HEADERS += $$PWD/annotationcommenttab.h
|
HEADERS += $$PWD/annotationcommenttab.h
|
||||||
HEADERS += $$PWD/annotationeditordialog.h
|
HEADERS += $$PWD/annotationeditordialog.h
|
||||||
HEADERS += $$PWD/annotationeditor.h
|
HEADERS += $$PWD/annotationeditor.h
|
||||||
|
HEADERS += $$PWD/globalannotationeditor.h
|
||||||
|
|
||||||
SOURCES += $$PWD/annotationtool.cpp
|
SOURCES += $$PWD/annotationtool.cpp
|
||||||
SOURCES += $$PWD/annotationcommenttab.cpp
|
SOURCES += $$PWD/annotationcommenttab.cpp
|
||||||
SOURCES += $$PWD/annotationeditordialog.cpp
|
SOURCES += $$PWD/annotationeditordialog.cpp
|
||||||
SOURCES += $$PWD/annotationeditor.cpp
|
SOURCES += $$PWD/annotationeditor.cpp
|
||||||
|
SOURCES += $$PWD/globalannotationeditor.cpp
|
||||||
|
|
||||||
FORMS += $$PWD/annotationcommenttab.ui
|
FORMS += $$PWD/annotationcommenttab.ui
|
||||||
FORMS += $$PWD/annotationeditordialog.ui
|
FORMS += $$PWD/annotationeditordialog.ui
|
||||||
|
@@ -40,16 +40,16 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
AnnotationEditorDialog::AnnotationEditorDialog(QWidget *parent, const QString &targetId, const QString &customId, const Annotation &annotation)
|
AnnotationEditorDialog::AnnotationEditorDialog(QWidget *parent, const QString &targetId, const QString &customId, const Annotation &annotation, EditorMode mode)
|
||||||
: QDialog(parent)
|
: QDialog(parent)
|
||||||
, ui(new Ui::AnnotationEditorDialog)
|
, ui(new Ui::AnnotationEditorDialog)
|
||||||
, m_customId(customId)
|
, m_customId(customId)
|
||||||
, m_annotation(annotation)
|
, m_annotation(annotation)
|
||||||
|
, m_editorMode(mode)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
setWindowFlag(Qt::Tool, true);
|
setWindowFlag(Qt::Tool, true);
|
||||||
setWindowTitle(titleString);
|
|
||||||
setModal(true);
|
setModal(true);
|
||||||
|
|
||||||
connect(this, &QDialog::accepted, this, &AnnotationEditorDialog::acceptedClicked);
|
connect(this, &QDialog::accepted, this, &AnnotationEditorDialog::acceptedClicked);
|
||||||
@@ -98,6 +98,7 @@ AnnotationEditorDialog::AnnotationEditorDialog(QWidget *parent, const QString &t
|
|||||||
ui->tabWidget->setCornerWidget(commentCornerWidget, Qt::TopRightCorner);
|
ui->tabWidget->setCornerWidget(commentCornerWidget, Qt::TopRightCorner);
|
||||||
ui->targetIdEdit->setText(targetId);
|
ui->targetIdEdit->setText(targetId);
|
||||||
|
|
||||||
|
changeEditorMode(m_editorMode);
|
||||||
fillFields();
|
fillFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,6 +129,39 @@ QString AnnotationEditorDialog::customId() const
|
|||||||
return m_customId;
|
return m_customId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AnnotationEditorDialog::changeEditorMode(AnnotationEditorDialog::EditorMode mode)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case ItemAnnotation: {
|
||||||
|
ui->customIdEdit->setVisible(true);
|
||||||
|
ui->customIdLabel->setVisible(true);
|
||||||
|
ui->targetIdEdit->setVisible(true);
|
||||||
|
ui->targetIdLabel->setVisible(true);
|
||||||
|
setWindowTitle(annotationEditorTitle);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GlobalAnnotation: {
|
||||||
|
ui->customIdEdit->clear();
|
||||||
|
ui->targetIdEdit->clear();
|
||||||
|
ui->customIdEdit->setVisible(false);
|
||||||
|
ui->customIdLabel->setVisible(false);
|
||||||
|
ui->targetIdEdit->setVisible(false);
|
||||||
|
ui->targetIdLabel->setVisible(false);
|
||||||
|
setWindowTitle(globalEditorTitle);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_editorMode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
AnnotationEditorDialog::EditorMode AnnotationEditorDialog::editorMode() const
|
||||||
|
{
|
||||||
|
return m_editorMode;
|
||||||
|
}
|
||||||
|
|
||||||
void AnnotationEditorDialog::acceptedClicked()
|
void AnnotationEditorDialog::acceptedClicked()
|
||||||
{
|
{
|
||||||
m_customId = ui->customIdEdit->text();
|
m_customId = ui->customIdEdit->text();
|
||||||
|
@@ -40,7 +40,10 @@ class AnnotationEditorDialog : public QDialog
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AnnotationEditorDialog(QWidget *parent, const QString &targetId, const QString &customId, const Annotation &annotation);
|
enum EditorMode { ItemAnnotation, GlobalAnnotation };
|
||||||
|
|
||||||
|
explicit AnnotationEditorDialog(QWidget *parent, const QString &targetId, const QString &customId, const Annotation &annotation,
|
||||||
|
EditorMode mode = EditorMode::ItemAnnotation);
|
||||||
~AnnotationEditorDialog();
|
~AnnotationEditorDialog();
|
||||||
|
|
||||||
void setAnnotation(const Annotation &annotation);
|
void setAnnotation(const Annotation &annotation);
|
||||||
@@ -49,6 +52,9 @@ public:
|
|||||||
void setCustomId(const QString &customId);
|
void setCustomId(const QString &customId);
|
||||||
QString customId() const;
|
QString customId() const;
|
||||||
|
|
||||||
|
void changeEditorMode(EditorMode mode);
|
||||||
|
EditorMode editorMode() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void accepted();
|
void accepted();
|
||||||
|
|
||||||
@@ -68,12 +74,15 @@ private:
|
|||||||
void deleteAllTabs();
|
void deleteAllTabs();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QString titleString = {tr("Annotation Editor")};
|
const QString annotationEditorTitle = {tr("Annotation Editor")};
|
||||||
|
const QString globalEditorTitle = {tr("Global Annotation Editor")};
|
||||||
const QString defaultTabName = {tr("Annotation")};
|
const QString defaultTabName = {tr("Annotation")};
|
||||||
Ui::AnnotationEditorDialog *ui;
|
Ui::AnnotationEditorDialog *ui;
|
||||||
|
|
||||||
QString m_customId;
|
QString m_customId;
|
||||||
Annotation m_annotation;
|
Annotation m_annotation;
|
||||||
|
|
||||||
|
EditorMode m_editorMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
} //namespace QmlDesigner
|
} //namespace QmlDesigner
|
||||||
|
@@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>700</width>
|
<width>1100</width>
|
||||||
<height>487</height>
|
<height>600</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@@ -0,0 +1,148 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 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 "globalannotationeditor.h"
|
||||||
|
|
||||||
|
#include "annotationeditordialog.h"
|
||||||
|
#include "annotation.h"
|
||||||
|
|
||||||
|
#include "qmlmodelnodeproxy.h"
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QToolBar>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
GlobalAnnotationEditor::GlobalAnnotationEditor(QObject *)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalAnnotationEditor::~GlobalAnnotationEditor()
|
||||||
|
{
|
||||||
|
hideWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalAnnotationEditor::showWidget()
|
||||||
|
{
|
||||||
|
m_dialog = new AnnotationEditorDialog(Core::ICore::dialogParent(),
|
||||||
|
modelNode().validId(),
|
||||||
|
"",
|
||||||
|
modelNode().globalAnnotation(),
|
||||||
|
AnnotationEditorDialog::EditorMode::GlobalAnnotation);
|
||||||
|
|
||||||
|
QObject::connect(m_dialog, &AnnotationEditorDialog::accepted,
|
||||||
|
this, &GlobalAnnotationEditor::acceptedClicked);
|
||||||
|
QObject::connect(m_dialog, &AnnotationEditorDialog::rejected,
|
||||||
|
this, &GlobalAnnotationEditor::cancelClicked);
|
||||||
|
|
||||||
|
m_dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
|
m_dialog->show();
|
||||||
|
m_dialog->raise();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalAnnotationEditor::showWidget(int x, int y)
|
||||||
|
{
|
||||||
|
showWidget();
|
||||||
|
m_dialog->move(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalAnnotationEditor::hideWidget()
|
||||||
|
{
|
||||||
|
if (m_dialog)
|
||||||
|
m_dialog->close();
|
||||||
|
m_dialog = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalAnnotationEditor::setModelNode(const ModelNode &modelNode)
|
||||||
|
{
|
||||||
|
m_modelNode = modelNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelNode GlobalAnnotationEditor::modelNode() const
|
||||||
|
{
|
||||||
|
return m_modelNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GlobalAnnotationEditor::hasAnnotation() const
|
||||||
|
{
|
||||||
|
if (m_modelNode.isValid())
|
||||||
|
return m_modelNode.hasGlobalAnnotation();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalAnnotationEditor::removeFullAnnotation()
|
||||||
|
{
|
||||||
|
if (!m_modelNode.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QString dialogTitle = tr("Global Annotation");
|
||||||
|
QMessageBox *deleteDialog = new QMessageBox(Core::ICore::dialogParent());
|
||||||
|
deleteDialog->setWindowTitle(dialogTitle);
|
||||||
|
deleteDialog->setText(tr("Delete this annotation?"));
|
||||||
|
deleteDialog->setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||||
|
deleteDialog->setDefaultButton(QMessageBox::Yes);
|
||||||
|
|
||||||
|
int result = deleteDialog->exec();
|
||||||
|
if (deleteDialog) deleteDialog->deleteLater();
|
||||||
|
|
||||||
|
if (result == QMessageBox::Yes) {
|
||||||
|
m_modelNode.removeGlobalAnnotation();
|
||||||
|
}
|
||||||
|
|
||||||
|
emit annotationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalAnnotationEditor::acceptedClicked()
|
||||||
|
{
|
||||||
|
if (m_dialog) {
|
||||||
|
Annotation annotation = m_dialog->annotation();
|
||||||
|
|
||||||
|
if (annotation.comments().isEmpty())
|
||||||
|
m_modelNode.removeGlobalAnnotation();
|
||||||
|
else
|
||||||
|
m_modelNode.setGlobalAnnotation(annotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
hideWidget();
|
||||||
|
|
||||||
|
emit accepted();
|
||||||
|
|
||||||
|
emit annotationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalAnnotationEditor::cancelClicked()
|
||||||
|
{
|
||||||
|
hideWidget();
|
||||||
|
|
||||||
|
emit canceled();
|
||||||
|
|
||||||
|
emit annotationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
} //namespace QmlDesigner
|
@@ -0,0 +1,75 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 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 <QObject>
|
||||||
|
#include <QtQml>
|
||||||
|
#include <QPointer>
|
||||||
|
|
||||||
|
#include "annotationeditordialog.h"
|
||||||
|
#include "annotation.h"
|
||||||
|
|
||||||
|
#include "modelnode.h"
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class GlobalAnnotationEditor : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit GlobalAnnotationEditor(QObject *parent = nullptr);
|
||||||
|
~GlobalAnnotationEditor();
|
||||||
|
|
||||||
|
Q_INVOKABLE void showWidget();
|
||||||
|
Q_INVOKABLE void showWidget(int x, int y);
|
||||||
|
Q_INVOKABLE void hideWidget();
|
||||||
|
|
||||||
|
void setModelNode(const ModelNode &modelNode);
|
||||||
|
ModelNode modelNode() const;
|
||||||
|
|
||||||
|
Q_INVOKABLE bool hasAnnotation() const;
|
||||||
|
|
||||||
|
Q_INVOKABLE void removeFullAnnotation();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void accepted();
|
||||||
|
void canceled();
|
||||||
|
void modelNodeBackendChanged();
|
||||||
|
|
||||||
|
void annotationChanged();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void acceptedClicked();
|
||||||
|
void cancelClicked();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPointer<AnnotationEditorDialog> m_dialog;
|
||||||
|
|
||||||
|
ModelNode m_modelNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
} //namespace QmlDesigner
|
@@ -41,6 +41,7 @@ const char anchorsCategory[] = "Anchors";
|
|||||||
const char positionCategory[] = "Position";
|
const char positionCategory[] = "Position";
|
||||||
const char layoutCategory[] = "Layout";
|
const char layoutCategory[] = "Layout";
|
||||||
const char flowCategory[] = "Flow";
|
const char flowCategory[] = "Flow";
|
||||||
|
const char flowEffectCategory[] = "FlowEffect";
|
||||||
const char flowConnectionCategory[] = "FlowConnection";
|
const char flowConnectionCategory[] = "FlowConnection";
|
||||||
const char stackedContainerCategory[] = "StackedContainer";
|
const char stackedContainerCategory[] = "StackedContainer";
|
||||||
const char genericToolBarCategory[] = "GenericToolBar";
|
const char genericToolBarCategory[] = "GenericToolBar";
|
||||||
@@ -57,6 +58,7 @@ const char anchorsFillCommandId[] = "AnchorsFill";
|
|||||||
const char anchorsResetCommandId[] = "AnchorsReset";
|
const char anchorsResetCommandId[] = "AnchorsReset";
|
||||||
const char removePositionerCommandId[] = "RemovePositioner";
|
const char removePositionerCommandId[] = "RemovePositioner";
|
||||||
const char createFlowActionAreaCommandId[] = "CreateFlowActionArea";
|
const char createFlowActionAreaCommandId[] = "CreateFlowActionArea";
|
||||||
|
const char setFlowStartCommandId[] = "SetFlowStart";
|
||||||
const char layoutRowPositionerCommandId[] = "LayoutRowPositioner";
|
const char layoutRowPositionerCommandId[] = "LayoutRowPositioner";
|
||||||
const char layoutColumnPositionerCommandId[] = "LayoutColumnPositioner";
|
const char layoutColumnPositionerCommandId[] = "LayoutColumnPositioner";
|
||||||
const char layoutGridPositionerCommandId[] = "LayoutGridPositioner";
|
const char layoutGridPositionerCommandId[] = "LayoutGridPositioner";
|
||||||
@@ -85,6 +87,7 @@ const char anchorsCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextM
|
|||||||
const char positionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Position");
|
const char positionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Position");
|
||||||
const char layoutCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Layout");
|
const char layoutCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Layout");
|
||||||
const char flowCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Flow");
|
const char flowCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Flow");
|
||||||
|
const char flowEffectCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Flow Effects");
|
||||||
const char stackedContainerCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Stacked Container");
|
const char stackedContainerCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Stacked Container");
|
||||||
|
|
||||||
const char cutSelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Cut");
|
const char cutSelectionDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Cut");
|
||||||
@@ -124,6 +127,7 @@ const char layoutGridPositionerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerCon
|
|||||||
const char layoutFlowPositionerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Position in Flow");
|
const char layoutFlowPositionerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Position in Flow");
|
||||||
const char removePositionerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Remove Positioner");
|
const char removePositionerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Remove Positioner");
|
||||||
const char createFlowActionAreaDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Create Flow Action");
|
const char createFlowActionAreaDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Create Flow Action");
|
||||||
|
const char setFlowStartDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Set Flow Start");
|
||||||
const char removeLayoutDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Remove Layout");
|
const char removeLayoutDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Remove Layout");
|
||||||
|
|
||||||
const char addItemToStackedContainerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Add Item");
|
const char addItemToStackedContainerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Add Item");
|
||||||
|
@@ -346,6 +346,12 @@ bool isFlowItem(const SelectionContext &context)
|
|||||||
&& QmlFlowItemNode::isValidQmlFlowItemNode(context.currentSingleSelectedNode());
|
&& QmlFlowItemNode::isValidQmlFlowItemNode(context.currentSingleSelectedNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isFlowTarget(const SelectionContext &context)
|
||||||
|
{
|
||||||
|
return context.singleNodeIsSelected()
|
||||||
|
&& QmlFlowTargetNode::isFlowEditorTarget(context.currentSingleSelectedNode());
|
||||||
|
}
|
||||||
|
|
||||||
bool isFlowTransitionItem(const SelectionContext &context)
|
bool isFlowTransitionItem(const SelectionContext &context)
|
||||||
{
|
{
|
||||||
return context.singleNodeIsSelected()
|
return context.singleNodeIsSelected()
|
||||||
@@ -362,9 +368,9 @@ bool isFlowActionItemItem(const SelectionContext &context)
|
|||||||
|| QmlVisualNode::isFlowWildcard(selectedNode));
|
|| QmlVisualNode::isFlowWildcard(selectedNode));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isFlowItemOrTransition(const SelectionContext &context)
|
bool isFlowTargetOrTransition(const SelectionContext &context)
|
||||||
{
|
{
|
||||||
return isFlowItem(context) || isFlowTransitionItem(context);
|
return isFlowTarget(context) || isFlowTransitionItem(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
class FlowActionConnectAction : public ActionGroup
|
class FlowActionConnectAction : public ActionGroup
|
||||||
@@ -853,15 +859,24 @@ void DesignerActionManager::createDefaultDesignerActions()
|
|||||||
priorityLayoutCategory,
|
priorityLayoutCategory,
|
||||||
&layoutOptionVisible));
|
&layoutOptionVisible));
|
||||||
|
|
||||||
//isFlowTransitionItem
|
|
||||||
|
|
||||||
addDesignerAction(new ActionGroup(
|
addDesignerAction(new ActionGroup(
|
||||||
flowCategoryDisplayName,
|
flowCategoryDisplayName,
|
||||||
flowCategory,
|
flowCategory,
|
||||||
priorityFlowCategory,
|
priorityFlowCategory,
|
||||||
&isFlowItemOrTransition,
|
&isFlowTargetOrTransition,
|
||||||
&flowOptionVisible));
|
&flowOptionVisible));
|
||||||
|
|
||||||
|
|
||||||
|
auto effectMenu = new ActionGroup(
|
||||||
|
flowEffectCategoryDisplayName,
|
||||||
|
flowEffectCategory,
|
||||||
|
priorityFlowCategory,
|
||||||
|
&isFlowTransitionItem,
|
||||||
|
&flowOptionVisible);
|
||||||
|
|
||||||
|
effectMenu->setCategory(flowCategory);
|
||||||
|
addDesignerAction(effectMenu);
|
||||||
|
|
||||||
addDesignerAction(new ModelNodeFormEditorAction(
|
addDesignerAction(new ModelNodeFormEditorAction(
|
||||||
createFlowActionAreaCommandId,
|
createFlowActionAreaCommandId,
|
||||||
createFlowActionAreaDisplayName,
|
createFlowActionAreaDisplayName,
|
||||||
@@ -874,6 +889,17 @@ void DesignerActionManager::createDefaultDesignerActions()
|
|||||||
&isFlowItem,
|
&isFlowItem,
|
||||||
&flowOptionVisible));
|
&flowOptionVisible));
|
||||||
|
|
||||||
|
addDesignerAction(new ModelNodeContextMenuAction(
|
||||||
|
setFlowStartCommandId,
|
||||||
|
setFlowStartDisplayName,
|
||||||
|
{},
|
||||||
|
flowCategory,
|
||||||
|
priorityFirst,
|
||||||
|
{},
|
||||||
|
&setFlowStartItem,
|
||||||
|
&isFlowItem,
|
||||||
|
&flowOptionVisible));
|
||||||
|
|
||||||
addDesignerAction(new FlowActionConnectAction(
|
addDesignerAction(new FlowActionConnectAction(
|
||||||
flowConnectionCategoryDisplayName,
|
flowConnectionCategoryDisplayName,
|
||||||
flowConnectionCategory,
|
flowConnectionCategory,
|
||||||
@@ -1175,7 +1201,7 @@ void DesignerActionManager::addTransitionEffectAction(const TypeName &typeName)
|
|||||||
QByteArray(ComponentCoreConstants::flowAssignEffectCommandId) + typeName,
|
QByteArray(ComponentCoreConstants::flowAssignEffectCommandId) + typeName,
|
||||||
QLatin1String(ComponentCoreConstants::flowAssignEffectDisplayName) + typeName,
|
QLatin1String(ComponentCoreConstants::flowAssignEffectDisplayName) + typeName,
|
||||||
{},
|
{},
|
||||||
ComponentCoreConstants::flowCategory,
|
ComponentCoreConstants::flowEffectCategory,
|
||||||
{},
|
{},
|
||||||
typeName == "None" ? 100 : 140,
|
typeName == "None" ? 100 : 140,
|
||||||
[typeName](const SelectionContext &context)
|
[typeName](const SelectionContext &context)
|
||||||
|
@@ -132,16 +132,22 @@ public:
|
|||||||
|
|
||||||
bool isVisible(const SelectionContext &m_selectionState) const override { return m_visibility(m_selectionState); }
|
bool isVisible(const SelectionContext &m_selectionState) const override { return m_visibility(m_selectionState); }
|
||||||
bool isEnabled(const SelectionContext &m_selectionState) const override { return m_enabled(m_selectionState); }
|
bool isEnabled(const SelectionContext &m_selectionState) const override { return m_enabled(m_selectionState); }
|
||||||
QByteArray category() const override { return QByteArray(); }
|
QByteArray category() const override { return m_category; }
|
||||||
QByteArray menuId() const override { return m_menuId; }
|
QByteArray menuId() const override { return m_menuId; }
|
||||||
int priority() const override { return m_priority; }
|
int priority() const override { return m_priority; }
|
||||||
Type type() const override { return ContextMenu; }
|
Type type() const override { return ContextMenu; }
|
||||||
|
|
||||||
|
void setCategory(const QByteArray &catageoryId)
|
||||||
|
{
|
||||||
|
m_category = catageoryId;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QByteArray m_menuId;
|
const QByteArray m_menuId;
|
||||||
const int m_priority;
|
const int m_priority;
|
||||||
SelectionContextPredicate m_enabled;
|
SelectionContextPredicate m_enabled;
|
||||||
SelectionContextPredicate m_visibility;
|
SelectionContextPredicate m_visibility;
|
||||||
|
QByteArray m_category;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SeperatorDesignerAction : public AbstractAction
|
class SeperatorDesignerAction : public AbstractAction
|
||||||
|
@@ -295,8 +295,10 @@ void resetSize(const SelectionContext &selectionState)
|
|||||||
selectionState.view()->executeInTransaction("DesignerActionManager|resetSize",[selectionState](){
|
selectionState.view()->executeInTransaction("DesignerActionManager|resetSize",[selectionState](){
|
||||||
foreach (ModelNode node, selectionState.selectedModelNodes()) {
|
foreach (ModelNode node, selectionState.selectedModelNodes()) {
|
||||||
QmlItemNode itemNode(node);
|
QmlItemNode itemNode(node);
|
||||||
itemNode.removeProperty("width");
|
if (itemNode.isValid()) {
|
||||||
itemNode.removeProperty("height");
|
itemNode.removeProperty("width");
|
||||||
|
itemNode.removeProperty("height");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -309,8 +311,10 @@ void resetPosition(const SelectionContext &selectionState)
|
|||||||
selectionState.view()->executeInTransaction("DesignerActionManager|resetPosition",[selectionState](){
|
selectionState.view()->executeInTransaction("DesignerActionManager|resetPosition",[selectionState](){
|
||||||
foreach (ModelNode node, selectionState.selectedModelNodes()) {
|
foreach (ModelNode node, selectionState.selectedModelNodes()) {
|
||||||
QmlItemNode itemNode(node);
|
QmlItemNode itemNode(node);
|
||||||
itemNode.removeProperty("x");
|
if (itemNode.isValid()) {
|
||||||
itemNode.removeProperty("y");
|
itemNode.removeProperty("x");
|
||||||
|
itemNode.removeProperty("y");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -332,7 +336,8 @@ void resetZ(const SelectionContext &selectionState)
|
|||||||
selectionState.view()->executeInTransaction("DesignerActionManager|resetZ",[selectionState](){
|
selectionState.view()->executeInTransaction("DesignerActionManager|resetZ",[selectionState](){
|
||||||
foreach (ModelNode node, selectionState.selectedModelNodes()) {
|
foreach (ModelNode node, selectionState.selectedModelNodes()) {
|
||||||
QmlItemNode itemNode(node);
|
QmlItemNode itemNode(node);
|
||||||
itemNode.removeProperty("z");
|
if (itemNode.isValid())
|
||||||
|
itemNode.removeProperty("z");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1079,7 +1084,24 @@ void addFlowEffect(const SelectionContext &selectionContext, const TypeName &typ
|
|||||||
container.nodeProperty("effect").reparentHere(effectNode);
|
container.nodeProperty("effect").reparentHere(effectNode);
|
||||||
view->setSelectedModelNode(effectNode);
|
view->setSelectedModelNode(effectNode);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFlowStartItem(const SelectionContext &selectionContext)
|
||||||
|
{
|
||||||
|
AbstractView *view = selectionContext.view();
|
||||||
|
|
||||||
|
QTC_ASSERT(view && selectionContext.hasSingleSelectedModelNode(), return);
|
||||||
|
ModelNode node = selectionContext.currentSingleSelectedNode();
|
||||||
|
QTC_ASSERT(node.isValid(), return);
|
||||||
|
QTC_ASSERT(node.metaInfo().isValid(), return);
|
||||||
|
QmlFlowItemNode flowItem(node);
|
||||||
|
QTC_ASSERT(flowItem.isValid(), return);
|
||||||
|
QTC_ASSERT(flowItem.flowView().isValid(), return);
|
||||||
|
view->executeInTransaction("DesignerActionManager:setFlowStartItem",
|
||||||
|
[&flowItem](){
|
||||||
|
flowItem.flowView().setStartFlowItem(flowItem);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Mode
|
} // namespace Mode
|
||||||
|
@@ -77,6 +77,7 @@ bool addFontToProject(const QStringList &fileNames, const QString &directory);
|
|||||||
void createFlowActionArea(const SelectionContext &selectionContext);
|
void createFlowActionArea(const SelectionContext &selectionContext);
|
||||||
void addTransition(const SelectionContext &selectionState);
|
void addTransition(const SelectionContext &selectionState);
|
||||||
void addFlowEffect(const SelectionContext &selectionState, const TypeName &typeName);
|
void addFlowEffect(const SelectionContext &selectionState, const TypeName &typeName);
|
||||||
|
void setFlowStartItem(const SelectionContext &selectionContext);
|
||||||
|
|
||||||
} // namespace ModelNodeOperationso
|
} // namespace ModelNodeOperationso
|
||||||
} //QmlDesigner
|
} //QmlDesigner
|
||||||
|
@@ -28,19 +28,46 @@
|
|||||||
|
|
||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
|
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
#include <utils/stylehelper.h>
|
#include <utils/stylehelper.h>
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
#include <QScreen>
|
#include <QScreen>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
#include <QQmlEngine>
|
||||||
|
#include <QQmlComponent>
|
||||||
|
#include <QQmlProperty>
|
||||||
#include <qqml.h>
|
#include <qqml.h>
|
||||||
|
|
||||||
|
static Q_LOGGING_CATEGORY(themeLog, "qtc.qmldesigner.theme", QtWarningMsg)
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
Theme::Theme(Utils::Theme *originTheme, QObject *parent)
|
Theme::Theme(Utils::Theme *originTheme, QObject *parent)
|
||||||
: Utils::Theme(originTheme, parent)
|
: Utils::Theme(originTheme, parent)
|
||||||
|
, m_constants(nullptr)
|
||||||
{
|
{
|
||||||
|
QString constantsPath = Core::ICore::resourcePath() +
|
||||||
|
QStringLiteral("/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml");
|
||||||
|
|
||||||
|
QQmlEngine* engine = new QQmlEngine(this);
|
||||||
|
QQmlComponent component(engine, QUrl::fromLocalFile(constantsPath));
|
||||||
|
|
||||||
|
if (component.status() == QQmlComponent::Ready) {
|
||||||
|
m_constants = component.create();
|
||||||
|
}
|
||||||
|
else if (component.status() == QQmlComponent::Error ) {
|
||||||
|
qCWarning(themeLog) << "Couldn't load" << constantsPath
|
||||||
|
<< "due to the following error(s):";
|
||||||
|
for (QQmlError error : component.errors())
|
||||||
|
qCWarning(themeLog) << error.toString();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qCWarning(themeLog) << "Couldn't load" << constantsPath
|
||||||
|
<< "the status of the QQmlComponent is" << component.status();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor Theme::evaluateColorAtThemeInstance(const QString &themeColorName)
|
QColor Theme::evaluateColorAtThemeInstance(const QString &themeColorName)
|
||||||
@@ -129,6 +156,25 @@ QPixmap Theme::getPixmap(const QString &id)
|
|||||||
return QmlDesignerIconProvider::getPixmap(id);
|
return QmlDesignerIconProvider::getPixmap(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Theme::getIconUnicode(Theme::Icon i)
|
||||||
|
{
|
||||||
|
if (!instance()->m_constants)
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
const QMetaObject *m = instance()->metaObject();
|
||||||
|
const char *enumName = "Icon";
|
||||||
|
int enumIndex = m->indexOfEnumerator(enumName);
|
||||||
|
|
||||||
|
if (enumIndex == -1) {
|
||||||
|
qCWarning(themeLog) << "Couldn't find enum" << enumName;
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QMetaEnum e = m->enumerator(enumIndex);
|
||||||
|
|
||||||
|
return instance()->m_constants->property(e.valueToKey(i)).toString();
|
||||||
|
}
|
||||||
|
|
||||||
QColor Theme::qmlDesignerBackgroundColorDarker() const
|
QColor Theme::qmlDesignerBackgroundColorDarker() const
|
||||||
{
|
{
|
||||||
return getColor(QmlDesigner_BackgroundColorDarker);
|
return getColor(QmlDesigner_BackgroundColorDarker);
|
||||||
|
@@ -41,12 +41,91 @@ namespace QmlDesigner {
|
|||||||
class QMLDESIGNERCORE_EXPORT Theme : public Utils::Theme
|
class QMLDESIGNERCORE_EXPORT Theme : public Utils::Theme
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_ENUMS(Icon)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum Icon {
|
||||||
|
actionIcon,
|
||||||
|
actionIconBinding,
|
||||||
|
addColumnAfter,
|
||||||
|
addColumnBefore,
|
||||||
|
addFile,
|
||||||
|
addRowAfter,
|
||||||
|
addRowBefore,
|
||||||
|
addTable,
|
||||||
|
adsClose,
|
||||||
|
adsDetach,
|
||||||
|
adsDropDown,
|
||||||
|
alignBottom,
|
||||||
|
alignCenterHorizontal,
|
||||||
|
alignCenterVertical,
|
||||||
|
alignLeft,
|
||||||
|
alignRight,
|
||||||
|
alignTo,
|
||||||
|
alignTop,
|
||||||
|
anchorBaseline,
|
||||||
|
anchorBottom,
|
||||||
|
anchorFill,
|
||||||
|
anchorLeft,
|
||||||
|
anchorRight,
|
||||||
|
anchorTop,
|
||||||
|
annotationBubble,
|
||||||
|
annotationDecal,
|
||||||
|
centerHorizontal,
|
||||||
|
centerVertical,
|
||||||
|
closeCross,
|
||||||
|
decisionNode,
|
||||||
|
deleteColumn,
|
||||||
|
deleteRow,
|
||||||
|
deleteTable,
|
||||||
|
detach,
|
||||||
|
distributeBottom,
|
||||||
|
distributeCenterHorizontal,
|
||||||
|
distributeCenterVertical,
|
||||||
|
distributeLeft,
|
||||||
|
distributeOriginBottomRight,
|
||||||
|
distributeOriginCenter,
|
||||||
|
distributeOriginNone,
|
||||||
|
distributeOriginTopLeft,
|
||||||
|
distributeRight,
|
||||||
|
distributeSpacingHorizontal,
|
||||||
|
distributeSpacingVertical,
|
||||||
|
distributeTop,
|
||||||
|
edit,
|
||||||
|
fontStyleBold,
|
||||||
|
fontStyleItalic,
|
||||||
|
fontStyleStrikethrough,
|
||||||
|
fontStyleUnderline,
|
||||||
|
mergeCells,
|
||||||
|
redo,
|
||||||
|
splitColumns,
|
||||||
|
splitRows,
|
||||||
|
startNode,
|
||||||
|
testIcon,
|
||||||
|
textAlignBottom,
|
||||||
|
textAlignCenter,
|
||||||
|
textAlignLeft,
|
||||||
|
textAlignMiddle,
|
||||||
|
textAlignRight,
|
||||||
|
textAlignTop,
|
||||||
|
textBulletList,
|
||||||
|
textFullJustification,
|
||||||
|
textNumberedList,
|
||||||
|
tickIcon,
|
||||||
|
triState,
|
||||||
|
undo,
|
||||||
|
upDownIcon,
|
||||||
|
upDownSquare2,
|
||||||
|
wildcard
|
||||||
|
};
|
||||||
|
|
||||||
static Theme *instance();
|
static Theme *instance();
|
||||||
static QString replaceCssColors(const QString &input);
|
static QString replaceCssColors(const QString &input);
|
||||||
static void setupTheme(QQmlEngine *engine);
|
static void setupTheme(QQmlEngine *engine);
|
||||||
static QColor getColor(Color role);
|
static QColor getColor(Color role);
|
||||||
static QPixmap getPixmap(const QString &id);
|
static QPixmap getPixmap(const QString &id);
|
||||||
|
static QString getIconUnicode(Theme::Icon i);
|
||||||
|
|
||||||
Q_INVOKABLE QColor qmlDesignerBackgroundColorDarker() const;
|
Q_INVOKABLE QColor qmlDesignerBackgroundColorDarker() const;
|
||||||
Q_INVOKABLE QColor qmlDesignerBackgroundColorDarkAlternate() const;
|
Q_INVOKABLE QColor qmlDesignerBackgroundColorDarkAlternate() const;
|
||||||
@@ -58,9 +137,12 @@ public:
|
|||||||
Q_INVOKABLE int smallFontPixelSize() const;
|
Q_INVOKABLE int smallFontPixelSize() const;
|
||||||
Q_INVOKABLE int captionFontPixelSize() const;
|
Q_INVOKABLE int captionFontPixelSize() const;
|
||||||
Q_INVOKABLE bool highPixelDensity() const;
|
Q_INVOKABLE bool highPixelDensity() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Theme(Utils::Theme *originTheme, QObject *parent);
|
Theme(Utils::Theme *originTheme, QObject *parent);
|
||||||
QColor evaluateColorAtThemeInstance(const QString &themeColorName);
|
QColor evaluateColorAtThemeInstance(const QString &themeColorName);
|
||||||
|
|
||||||
|
QObject *m_constants;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -179,6 +179,17 @@ void Edit3DView::importsChanged(const QList<Import> &addedImports,
|
|||||||
checkImports();
|
checkImports();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Edit3DView::customNotification(const AbstractView *view, const QString &identifier,
|
||||||
|
const QList<ModelNode> &nodeList, const QList<QVariant> &data)
|
||||||
|
{
|
||||||
|
Q_UNUSED(view)
|
||||||
|
Q_UNUSED(nodeList)
|
||||||
|
Q_UNUSED(data)
|
||||||
|
|
||||||
|
if (identifier == "asset_import_update")
|
||||||
|
resetPuppet();
|
||||||
|
}
|
||||||
|
|
||||||
void Edit3DView::sendInputEvent(QInputEvent *e) const
|
void Edit3DView::sendInputEvent(QInputEvent *e) const
|
||||||
{
|
{
|
||||||
if (nodeInstanceView())
|
if (nodeInstanceView())
|
||||||
@@ -301,14 +312,16 @@ QVector<Edit3DAction *> Edit3DView::rightActions() const
|
|||||||
|
|
||||||
void Edit3DView::addQuick3DImport()
|
void Edit3DView::addQuick3DImport()
|
||||||
{
|
{
|
||||||
const QList<Import> imports = model()->possibleImports();
|
if (model()) {
|
||||||
for (const auto &import : imports) {
|
const QList<Import> imports = model()->possibleImports();
|
||||||
if (import.url() == "QtQuick3D") {
|
for (const auto &import : imports) {
|
||||||
model()->changeImports({import}, {});
|
if (import.url() == "QtQuick3D") {
|
||||||
|
model()->changeImports({import}, {});
|
||||||
|
|
||||||
// Subcomponent manager update needed to make item library entries appear
|
// Subcomponent manager update needed to make item library entries appear
|
||||||
QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager();
|
QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Core::AsynchronousMessageBox::warning(tr("Failed to Add Import"),
|
Core::AsynchronousMessageBox::warning(tr("Failed to Add Import"),
|
||||||
|
@@ -58,6 +58,7 @@ public:
|
|||||||
void modelAttached(Model *model) override;
|
void modelAttached(Model *model) override;
|
||||||
void modelAboutToBeDetached(Model *model) override;
|
void modelAboutToBeDetached(Model *model) override;
|
||||||
void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override;
|
void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override;
|
||||||
|
void customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
||||||
|
|
||||||
void sendInputEvent(QInputEvent *e) const;
|
void sendInputEvent(QInputEvent *e) const;
|
||||||
void edit3DViewResized(const QSize &size) const;
|
void edit3DViewResized(const QSize &size) const;
|
||||||
|
@@ -106,12 +106,11 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view) :
|
|||||||
// Onboarding label contains instructions for new users how to get 3D content into the project
|
// Onboarding label contains instructions for new users how to get 3D content into the project
|
||||||
m_onboardingLabel = new QLabel(this);
|
m_onboardingLabel = new QLabel(this);
|
||||||
QString labelText =
|
QString labelText =
|
||||||
"No 3D import here yet!<br><br>"
|
tr("Your file does not import Qt Quick 3D.<br><br>"
|
||||||
"To create a 3D View you need to add the QtQuick3D import to your file.<br>"
|
"To create a 3D view, add the QtQuick3D import to your file in the QML Imports tab of the Library view. Or click"
|
||||||
"You can add the import via the QML Imports tab of the Library view, or alternatively click"
|
" <a href=\"#add_import\"><span style=\"text-decoration:none;color:%1\">here</span></a> "
|
||||||
" <a href=\"#add_import\"><span style=\"text-decoration:none;color:%1\">here</span></a> "
|
"here to add it immediately.<br><br>"
|
||||||
"to add it straight away.<br><br>"
|
"To import 3D assets from another tool, click on the \"Add New Assets...\" button in the Assets tab of the Library view.");
|
||||||
"If you want to import 3D assets from another tool, click on the \"Add New Assets...\" button in the Assets tab of the Library view.";
|
|
||||||
m_onboardingLabel->setText(labelText.arg(Utils::creatorTheme()->color(Utils::Theme::TextColorLink).name()));
|
m_onboardingLabel->setText(labelText.arg(Utils::creatorTheme()->color(Utils::Theme::TextColorLink).name()));
|
||||||
m_onboardingLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
m_onboardingLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||||
connect(m_onboardingLabel, &QLabel::linkActivated, this, &Edit3DWidget::linkActivated);
|
connect(m_onboardingLabel, &QLabel::linkActivated, this, &Edit3DWidget::linkActivated);
|
||||||
|
@@ -36,7 +36,8 @@ SOURCES += formeditoritem.cpp \
|
|||||||
contentnoteditableindicator.cpp \
|
contentnoteditableindicator.cpp \
|
||||||
backgroundaction.cpp \
|
backgroundaction.cpp \
|
||||||
formeditortoolbutton.cpp \
|
formeditortoolbutton.cpp \
|
||||||
formeditorannotationicon.cpp
|
formeditorannotationicon.cpp \
|
||||||
|
transitiontool.cpp
|
||||||
|
|
||||||
HEADERS += formeditorscene.h \
|
HEADERS += formeditorscene.h \
|
||||||
formeditorwidget.h \
|
formeditorwidget.h \
|
||||||
@@ -75,6 +76,7 @@ HEADERS += formeditorscene.h \
|
|||||||
contentnoteditableindicator.h \
|
contentnoteditableindicator.h \
|
||||||
backgroundaction.h \
|
backgroundaction.h \
|
||||||
formeditortoolbutton.h \
|
formeditortoolbutton.h \
|
||||||
formeditorannotationicon.h
|
formeditorannotationicon.h \
|
||||||
|
transitiontool.h
|
||||||
|
|
||||||
RESOURCES += formeditor.qrc
|
RESOURCES += formeditor.qrc
|
||||||
|
@@ -339,7 +339,7 @@ QGraphicsItem *FormEditorAnnotationIcon::createCommentBubble(QRectF rect, const
|
|||||||
authorItem->update();
|
authorItem->update();
|
||||||
|
|
||||||
QGraphicsTextItem *textItem = new QGraphicsTextItem(frameItem);
|
QGraphicsTextItem *textItem = new QGraphicsTextItem(frameItem);
|
||||||
textItem->setPlainText(text);
|
textItem->setHtml(text);
|
||||||
textItem->setDefaultTextColor(textColor);
|
textItem->setDefaultTextColor(textColor);
|
||||||
textItem->setTextWidth(rect.width());
|
textItem->setTextWidth(rect.width());
|
||||||
textItem->setPos(authorItem->x(), authorItem->boundingRect().height() + authorItem->y() + 5);
|
textItem->setPos(authorItem->x(), authorItem->boundingRect().height() + authorItem->y() + 5);
|
||||||
|
@@ -32,10 +32,13 @@
|
|||||||
#include <nodehints.h>
|
#include <nodehints.h>
|
||||||
#include <nodemetainfo.h>
|
#include <nodemetainfo.h>
|
||||||
|
|
||||||
|
#include <theme.h>
|
||||||
|
|
||||||
#include <utils/theme/theme.h>
|
#include <utils/theme/theme.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QFontDatabase>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPainterPath>
|
#include <QPainterPath>
|
||||||
#include <QStyleOptionGraphicsItem>
|
#include <QStyleOptionGraphicsItem>
|
||||||
@@ -47,6 +50,36 @@
|
|||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
const int flowBlockSize = 200;
|
const int flowBlockSize = 200;
|
||||||
|
const int blockRadius = 18;
|
||||||
|
const int blockAdjust = 40;
|
||||||
|
|
||||||
|
const char startNodeIcon[] = "\u0055";
|
||||||
|
|
||||||
|
void drawIcon(QPainter *painter,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
const QString &iconSymbol,
|
||||||
|
int fontSize, int iconSize,
|
||||||
|
const QColor &penColor)
|
||||||
|
{
|
||||||
|
static QFontDatabase a;
|
||||||
|
|
||||||
|
const QString fontName = "qtds_propertyIconFont.ttf";
|
||||||
|
|
||||||
|
Q_ASSERT(a.hasFamily(fontName));
|
||||||
|
|
||||||
|
if (a.hasFamily(fontName)) {
|
||||||
|
QFont font(fontName);
|
||||||
|
font.setPixelSize(fontSize);
|
||||||
|
|
||||||
|
painter->save();
|
||||||
|
painter->setPen(penColor);
|
||||||
|
painter->setFont(font);
|
||||||
|
painter->drawText(QRectF(x, y, iconSize, iconSize), iconSymbol);
|
||||||
|
|
||||||
|
painter->restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FormEditorScene *FormEditorItem::scene() const {
|
FormEditorScene *FormEditorItem::scene() const {
|
||||||
return qobject_cast<FormEditorScene*>(QGraphicsItem::scene());
|
return qobject_cast<FormEditorScene*>(QGraphicsItem::scene());
|
||||||
@@ -578,6 +611,7 @@ void FormEditorFlowActionItem::paint(QPainter *painter, const QStyleOptionGraphi
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
painter->save();
|
painter->save();
|
||||||
|
painter->setRenderHint(QPainter::Antialiasing);
|
||||||
|
|
||||||
QPen pen;
|
QPen pen;
|
||||||
pen.setJoinStyle(Qt::MiterJoin);
|
pen.setJoinStyle(Qt::MiterJoin);
|
||||||
@@ -621,10 +655,9 @@ void FormEditorFlowActionItem::paint(QPainter *painter, const QStyleOptionGraphi
|
|||||||
fillColor = qmlItemNode().modelNode().auxiliaryData("fillColor").value<QColor>();
|
fillColor = qmlItemNode().modelNode().auxiliaryData("fillColor").value<QColor>();
|
||||||
|
|
||||||
if (fillColor.alpha() > 0)
|
if (fillColor.alpha() > 0)
|
||||||
painter->fillRect(boundingRect(), fillColor);
|
painter->setBrush(fillColor);
|
||||||
|
|
||||||
painter->drawRect(boundingRect());
|
|
||||||
|
|
||||||
|
painter->drawRoundedRect(boundingRect(), blockRadius, blockRadius);
|
||||||
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
@@ -989,6 +1022,7 @@ void FormEditorTransitionItem::paint(QPainter *painter, const QStyleOptionGraphi
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
painter->save();
|
painter->save();
|
||||||
|
painter->setRenderHint(QPainter::Antialiasing);
|
||||||
|
|
||||||
ResolveConnection resolved(qmlItemNode());
|
ResolveConnection resolved(qmlItemNode());
|
||||||
|
|
||||||
@@ -1021,8 +1055,8 @@ void FormEditorTransitionItem::paint(QPainter *painter, const QStyleOptionGraphi
|
|||||||
toRect.translate(QmlItemNode(resolved.to).flowPosition());
|
toRect.translate(QmlItemNode(resolved.to).flowPosition());
|
||||||
|
|
||||||
if (resolved.isStartLine) {
|
if (resolved.isStartLine) {
|
||||||
fromRect = QRectF(0,0,50,50);
|
fromRect = QRectF(0, 0, 96, 96);
|
||||||
fromRect.translate(QmlItemNode(resolved.to).flowPosition() + QPoint(-120, toRect.height() / 2 - 25));
|
fromRect.translate(QmlItemNode(resolved.to).flowPosition() + QPoint(-180, toRect.height() / 2 - 96 / 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
toRect.translate(-pos());
|
toRect.translate(-pos());
|
||||||
@@ -1075,23 +1109,28 @@ void FormEditorTransitionItem::paint(QPainter *painter, const QStyleOptionGraphi
|
|||||||
if (qmlItemNode().modelNode().hasAuxiliaryData("breakPoint"))
|
if (qmlItemNode().modelNode().hasAuxiliaryData("breakPoint"))
|
||||||
breakOffset = qmlItemNode().modelNode().auxiliaryData("breakPoint").toInt();
|
breakOffset = qmlItemNode().modelNode().auxiliaryData("breakPoint").toInt();
|
||||||
|
|
||||||
|
if (resolved.isStartLine)
|
||||||
|
fromRect.translate(0, inOffset);
|
||||||
|
|
||||||
paintConnection(painter, fromRect, toRect, width, adjustedWidth ,color, dash, outOffset, inOffset, breakOffset);
|
paintConnection(painter, fromRect, toRect, width, adjustedWidth ,color, dash, outOffset, inOffset, breakOffset);
|
||||||
|
|
||||||
if (resolved.isStartLine) {
|
if (resolved.isStartLine) {
|
||||||
|
|
||||||
|
const QString icon = Theme::getIconUnicode(Theme::startNode);
|
||||||
|
|
||||||
QPen pen;
|
QPen pen;
|
||||||
pen.setCosmetic(true);
|
pen.setCosmetic(true);
|
||||||
|
|
||||||
pen.setColor(color);
|
pen.setColor(color);
|
||||||
painter->setPen(pen);
|
painter->setPen(pen);
|
||||||
painter->drawRect(fromRect);
|
|
||||||
|
|
||||||
if (scaleFactor > 0.4) {
|
const int iconAdjust = 48;
|
||||||
painter->drawLine(fromRect.topRight() + QPoint(20,10), fromRect.bottomRight() + QPoint(20,-10));
|
const int offset = 96;
|
||||||
painter->drawLine(fromRect.topRight() + QPoint(25,12), fromRect.bottomRight() + QPoint(25,-12));
|
const int size = fromRect.width();
|
||||||
painter->drawLine(fromRect.topRight() + QPoint(30,15), fromRect.bottomRight() + QPoint(30,-15));
|
const int iconSize = size - iconAdjust;
|
||||||
painter->drawLine(fromRect.topRight() + QPoint(35,17), fromRect.bottomRight() + QPoint(35,-17));
|
const int x = fromRect.topRight().x() - offset;
|
||||||
painter->drawLine(fromRect.topRight() + QPoint(40,20), fromRect.bottomRight() + QPoint(40,-20));
|
const int y = fromRect.topRight().y();
|
||||||
}
|
painter->drawRoundedRect(x, y , size - 10, size, size / 2, iconSize / 2);
|
||||||
|
drawIcon(painter, x + iconAdjust / 2, y + iconAdjust / 2, icon, iconSize, iconSize, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
@@ -1140,6 +1179,9 @@ void FormEditorFlowDecisionItem::paint(QPainter *painter, const QStyleOptionGrap
|
|||||||
|
|
||||||
painter->save();
|
painter->save();
|
||||||
|
|
||||||
|
painter->setRenderHint(QPainter::Antialiasing);
|
||||||
|
painter->setRenderHint(QPainter::SmoothPixmapTransform);
|
||||||
|
|
||||||
QPen pen;
|
QPen pen;
|
||||||
pen.setJoinStyle(Qt::MiterJoin);
|
pen.setJoinStyle(Qt::MiterJoin);
|
||||||
pen.setCosmetic(true);
|
pen.setCosmetic(true);
|
||||||
@@ -1177,20 +1219,37 @@ void FormEditorFlowDecisionItem::paint(QPainter *painter, const QStyleOptionGrap
|
|||||||
if (qmlItemNode().modelNode().hasAuxiliaryData("fillColor"))
|
if (qmlItemNode().modelNode().hasAuxiliaryData("fillColor"))
|
||||||
fillColor = qmlItemNode().modelNode().auxiliaryData("fillColor").value<QColor>();
|
fillColor = qmlItemNode().modelNode().auxiliaryData("fillColor").value<QColor>();
|
||||||
|
|
||||||
|
painter->save();
|
||||||
|
|
||||||
|
if (m_iconType == DecisionIcon) {
|
||||||
|
painter->translate(boundingRect().center());
|
||||||
|
painter->rotate(45);
|
||||||
|
painter->translate(-boundingRect().center());
|
||||||
|
}
|
||||||
|
|
||||||
if (fillColor.alpha() > 0)
|
if (fillColor.alpha() > 0)
|
||||||
painter->fillRect(boundingRect(), fillColor);
|
painter->setBrush(fillColor);
|
||||||
|
|
||||||
painter->drawLine(boundingRect().left(), boundingRect().center().y(),
|
int radius = blockRadius;
|
||||||
boundingRect().center().x(), boundingRect().top());
|
|
||||||
|
|
||||||
painter->drawLine(boundingRect().center().x(), boundingRect().top(),
|
const QRectF adjustedRect = boundingRect().adjusted(blockAdjust,
|
||||||
boundingRect().right(), boundingRect().center().y());
|
blockAdjust,
|
||||||
|
-blockAdjust,
|
||||||
|
-blockAdjust);
|
||||||
|
|
||||||
painter->drawLine(boundingRect().right(), boundingRect().center().y(),
|
painter->drawRoundedRect(adjustedRect, radius, radius);
|
||||||
boundingRect().center().x(), boundingRect().bottom());
|
|
||||||
|
|
||||||
painter->drawLine(boundingRect().center().x(), boundingRect().bottom(),
|
const int iconDecrement = 32;
|
||||||
boundingRect().left(), boundingRect().center().y());
|
const int iconSize = adjustedRect.width() - iconDecrement;
|
||||||
|
const int offset = iconDecrement / 2 + blockAdjust;
|
||||||
|
|
||||||
|
painter->restore();
|
||||||
|
|
||||||
|
const QString icon = (m_iconType ==
|
||||||
|
WildcardIcon) ? Theme::getIconUnicode(Theme::wildcard)
|
||||||
|
: Theme::getIconUnicode(Theme::decisionNode);
|
||||||
|
|
||||||
|
drawIcon(painter, offset, offset, icon, iconSize, iconSize, flowColor);
|
||||||
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
@@ -207,9 +207,17 @@ public:
|
|||||||
bool flowHitTest(const QPointF &point) const override;
|
bool flowHitTest(const QPointF &point) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
FormEditorFlowDecisionItem(const QmlItemNode &qmlItemNode, FormEditorScene* scene)
|
enum IconType {
|
||||||
: FormEditorFlowItem(qmlItemNode, scene)
|
DecisionIcon,
|
||||||
|
WildcardIcon
|
||||||
|
};
|
||||||
|
|
||||||
|
FormEditorFlowDecisionItem(const QmlItemNode &qmlItemNode,
|
||||||
|
FormEditorScene* scene,
|
||||||
|
IconType iconType = DecisionIcon)
|
||||||
|
: FormEditorFlowItem(qmlItemNode, scene), m_iconType(iconType)
|
||||||
{}
|
{}
|
||||||
|
IconType m_iconType;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FormEditorFlowWildcardItem : FormEditorFlowDecisionItem
|
class FormEditorFlowWildcardItem : FormEditorFlowDecisionItem
|
||||||
@@ -221,8 +229,9 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
FormEditorFlowWildcardItem(const QmlItemNode &qmlItemNode, FormEditorScene* scene)
|
FormEditorFlowWildcardItem(const QmlItemNode &qmlItemNode, FormEditorScene* scene)
|
||||||
: FormEditorFlowDecisionItem(qmlItemNode, scene)
|
: FormEditorFlowDecisionItem(qmlItemNode, scene, WildcardIcon)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline int FormEditorItem::type() const
|
inline int FormEditorItem::type() const
|
||||||
|
438
src/plugins/qmldesigner/components/formeditor/transitiontool.cpp
Normal file
438
src/plugins/qmldesigner/components/formeditor/transitiontool.cpp
Normal file
@@ -0,0 +1,438 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 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 "transitiontool.h"
|
||||||
|
|
||||||
|
#include <formeditorscene.h>
|
||||||
|
#include <formeditorview.h>
|
||||||
|
#include <formeditorwidget.h>
|
||||||
|
#include <itemutilfunctions.h>
|
||||||
|
#include <formeditoritem.h>
|
||||||
|
#include <layeritem.h>
|
||||||
|
|
||||||
|
#include <resizehandleitem.h>
|
||||||
|
|
||||||
|
#include <bindingproperty.h>
|
||||||
|
#include <nodeabstractproperty.h>
|
||||||
|
#include <nodelistproperty.h>
|
||||||
|
#include <nodemetainfo.h>
|
||||||
|
#include <qmlitemnode.h>
|
||||||
|
#include <qmldesignerplugin.h>
|
||||||
|
#include <abstractaction.h>
|
||||||
|
#include <designeractionmanager.h>
|
||||||
|
#include <variantproperty.h>
|
||||||
|
#include <rewritingexception.h>
|
||||||
|
#include <rewritertransaction.h>
|
||||||
|
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QGraphicsSceneMouseEvent>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QPair>
|
||||||
|
#include <QGraphicsSceneMouseEvent>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
static bool isTransitionSource(const ModelNode &node)
|
||||||
|
{
|
||||||
|
return QmlFlowTargetNode::isFlowEditorTarget(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isTransitionTarget(const QmlItemNode &node)
|
||||||
|
{
|
||||||
|
return QmlFlowTargetNode::isFlowEditorTarget(node)
|
||||||
|
&& !node.isFlowActionArea()
|
||||||
|
&& !node.isFlowWildcard();
|
||||||
|
}
|
||||||
|
|
||||||
|
class TransitionToolAction : public AbstractAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TransitionToolAction(const QString &name) : AbstractAction(name) {}
|
||||||
|
|
||||||
|
QByteArray category() const override
|
||||||
|
{
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray menuId() const override
|
||||||
|
{
|
||||||
|
return "TransitionTool";
|
||||||
|
}
|
||||||
|
|
||||||
|
int priority() const override
|
||||||
|
{
|
||||||
|
return CustomActionsPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type type() const override
|
||||||
|
{
|
||||||
|
return ContextMenuAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool isVisible(const SelectionContext &selectionContext) const override
|
||||||
|
{
|
||||||
|
if (selectionContext.scenePosition().isNull())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (selectionContext.singleNodeIsSelected())
|
||||||
|
return isTransitionSource(selectionContext.currentSingleSelectedNode());
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isEnabled(const SelectionContext &selectionContext) const override
|
||||||
|
{
|
||||||
|
return isVisible(selectionContext);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TransitionCustomAction : public TransitionToolAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TransitionCustomAction(const QString &name) : TransitionToolAction(name) {}
|
||||||
|
|
||||||
|
QByteArray category() const override
|
||||||
|
{
|
||||||
|
return ComponentCoreConstants::flowCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectionContext selectionContext() const
|
||||||
|
{
|
||||||
|
return AbstractAction::selectionContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
static QRectF paintedBoundingRect(FormEditorItem *item)
|
||||||
|
{
|
||||||
|
QRectF boundingRect = item->qmlItemNode().instanceBoundingRect();
|
||||||
|
if (boundingRect.width() < 4)
|
||||||
|
boundingRect = item->boundingRect();
|
||||||
|
return boundingRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QPointF centerPoint(FormEditorItem *item)
|
||||||
|
{
|
||||||
|
QRectF boundingRect = paintedBoundingRect(item);
|
||||||
|
return QPointF(item->scenePos().x() + boundingRect.width() / 2,
|
||||||
|
item->scenePos().y() + boundingRect.height() / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void static setToBoundingRect(QGraphicsRectItem *rect, FormEditorItem *item)
|
||||||
|
{
|
||||||
|
QPolygonF boundingRectInSceneSpace(item->mapToScene(paintedBoundingRect(item)));
|
||||||
|
rect->setRect(boundingRectInSceneSpace.boundingRect());
|
||||||
|
}
|
||||||
|
|
||||||
|
TransitionTool::TransitionTool()
|
||||||
|
: QObject(), AbstractCustomTool()
|
||||||
|
{
|
||||||
|
|
||||||
|
TransitionToolAction *transitionToolAction = new TransitionToolAction(tr("Add Transition"));
|
||||||
|
QmlDesignerPlugin::instance()->designerActionManager().addDesignerAction(transitionToolAction);
|
||||||
|
|
||||||
|
connect(transitionToolAction->action(), &QAction::triggered,
|
||||||
|
this, &TransitionTool::activateTool);
|
||||||
|
|
||||||
|
TransitionCustomAction *removeAction = new TransitionCustomAction(tr("Remove Transitions"));
|
||||||
|
QmlDesignerPlugin::instance()->designerActionManager().addDesignerAction(removeAction);
|
||||||
|
|
||||||
|
connect(removeAction->action(), &QAction::triggered,
|
||||||
|
this, [removeAction](){
|
||||||
|
|
||||||
|
SelectionContext context = removeAction->selectionContext();
|
||||||
|
QmlFlowTargetNode node = QmlFlowTargetNode(context.currentSingleSelectedNode());
|
||||||
|
|
||||||
|
context.view()->executeInTransaction("Remove Transitions", [&node](){
|
||||||
|
if (node.isValid())
|
||||||
|
node.removeTransitions();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
TransitionCustomAction *removeAllTransitionsAction = new TransitionCustomAction(tr("Remove All Transitions"));
|
||||||
|
QmlDesignerPlugin::instance()->designerActionManager().addDesignerAction(removeAllTransitionsAction);
|
||||||
|
|
||||||
|
connect(removeAllTransitionsAction->action(), &QAction::triggered,
|
||||||
|
this, [removeAllTransitionsAction](){
|
||||||
|
|
||||||
|
if (QMessageBox::question(Core::ICore::dialogParent(),
|
||||||
|
tr("Remove All Transitions"),
|
||||||
|
tr("Do you really want to remove all transitions?"),
|
||||||
|
QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SelectionContext context = removeAllTransitionsAction->selectionContext();
|
||||||
|
QmlFlowTargetNode node = QmlFlowTargetNode(context.currentSingleSelectedNode());
|
||||||
|
|
||||||
|
context.view()->executeInTransaction("Remove All Transitions", [&node](){
|
||||||
|
if (node.isValid() && node.flowView().isValid())
|
||||||
|
node.flowView().removeAllTransitions();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
TransitionCustomAction *removeDanglingTransitionAction = new TransitionCustomAction(tr("Remove Dangling Transitions"));
|
||||||
|
QmlDesignerPlugin::instance()->designerActionManager().addDesignerAction(removeDanglingTransitionAction);
|
||||||
|
|
||||||
|
connect(removeDanglingTransitionAction->action(), &QAction::triggered,
|
||||||
|
this, [removeDanglingTransitionAction](){
|
||||||
|
|
||||||
|
SelectionContext context = removeDanglingTransitionAction->selectionContext();
|
||||||
|
QmlFlowTargetNode node = QmlFlowTargetNode(context.currentSingleSelectedNode());
|
||||||
|
|
||||||
|
context.view()->executeInTransaction("Remove Dangling Transitions", [&node](){
|
||||||
|
if (node.isValid() && node.flowView().isValid())
|
||||||
|
node.flowView().removeDanglingTransitions();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
TransitionTool::~TransitionTool()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransitionTool::clear()
|
||||||
|
{
|
||||||
|
m_lineItem.reset(nullptr);
|
||||||
|
m_rectangleItem1.reset(nullptr);
|
||||||
|
m_rectangleItem2.reset(nullptr);
|
||||||
|
|
||||||
|
AbstractFormEditorTool::clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransitionTool::mousePressEvent(const QList<QGraphicsItem*> &itemList,
|
||||||
|
QGraphicsSceneMouseEvent *event)
|
||||||
|
{
|
||||||
|
if (m_blockEvents)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (event->button() != Qt::LeftButton)
|
||||||
|
return;
|
||||||
|
|
||||||
|
AbstractFormEditorTool::mousePressEvent(itemList, event);
|
||||||
|
TransitionTool::mouseMoveEvent(itemList, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransitionTool::mouseMoveEvent(const QList<QGraphicsItem*> & itemList,
|
||||||
|
QGraphicsSceneMouseEvent * event)
|
||||||
|
{
|
||||||
|
if (!m_lineItem)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QTC_ASSERT(currentFormEditorItem(), return);
|
||||||
|
|
||||||
|
const QPointF pos = centerPoint(m_formEditorItem);
|
||||||
|
lineItem()->setLine(pos.x(),
|
||||||
|
pos.y(),
|
||||||
|
event->scenePos().x(),
|
||||||
|
event->scenePos().y());
|
||||||
|
|
||||||
|
FormEditorItem *formEditorItem = nearestFormEditorItem(event->scenePos(), itemList);
|
||||||
|
|
||||||
|
if (formEditorItem
|
||||||
|
&& formEditorItem->qmlItemNode().isValid()
|
||||||
|
&& isTransitionTarget(formEditorItem->qmlItemNode().modelNode())) {
|
||||||
|
rectangleItem2()->setVisible(true);
|
||||||
|
setToBoundingRect(rectangleItem2(), formEditorItem);
|
||||||
|
} else {
|
||||||
|
rectangleItem2()->setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransitionTool::hoverMoveEvent(const QList<QGraphicsItem*> & itemList,
|
||||||
|
QGraphicsSceneMouseEvent *event)
|
||||||
|
{
|
||||||
|
mouseMoveEvent(itemList, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransitionTool::keyPressEvent(QKeyEvent * /*keyEvent*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransitionTool::keyReleaseEvent(QKeyEvent * /*keyEvent*/)
|
||||||
|
{
|
||||||
|
view()->changeToSelectionTool();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransitionTool::dragLeaveEvent(const QList<QGraphicsItem*> &/*itemList*/, QGraphicsSceneDragDropEvent * /*event*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransitionTool::dragMoveEvent(const QList<QGraphicsItem*> &/*itemList*/, QGraphicsSceneDragDropEvent * /*event*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransitionTool::mouseReleaseEvent(const QList<QGraphicsItem*> &itemList,
|
||||||
|
QGraphicsSceneMouseEvent *event)
|
||||||
|
{
|
||||||
|
if (m_blockEvents)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (event->button() == Qt::LeftButton) {
|
||||||
|
FormEditorItem *formEditorItem = nearestFormEditorItem(event->scenePos(), itemList);
|
||||||
|
|
||||||
|
if (formEditorItem
|
||||||
|
&& QmlFlowTargetNode(formEditorItem->qmlItemNode().modelNode()).isValid())
|
||||||
|
createTransition(m_formEditorItem, formEditorItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
view()->changeToSelectionTool();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TransitionTool::mouseDoubleClickEvent(const QList<QGraphicsItem*> &itemList, QGraphicsSceneMouseEvent *event)
|
||||||
|
{
|
||||||
|
AbstractFormEditorTool::mouseDoubleClickEvent(itemList, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransitionTool::itemsAboutToRemoved(const QList<FormEditorItem*> &)
|
||||||
|
{
|
||||||
|
view()->changeCurrentToolTo(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransitionTool::selectedItemsChanged(const QList<FormEditorItem*> &itemList)
|
||||||
|
{
|
||||||
|
if (!itemList.isEmpty()) {
|
||||||
|
createItems();
|
||||||
|
|
||||||
|
m_formEditorItem = itemList.first();
|
||||||
|
setToBoundingRect(rectangleItem1(), m_formEditorItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransitionTool::instancesCompleted(const QList<FormEditorItem*> & /*itemList*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransitionTool::instancesParentChanged(const QList<FormEditorItem *> & /*itemList*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransitionTool::instancePropertyChange(const QList<QPair<ModelNode, PropertyName> > & /*propertyList*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransitionTool::formEditorItemsChanged(const QList<FormEditorItem*> & /*itemList*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int TransitionTool::wantHandleItem(const ModelNode &modelNode) const
|
||||||
|
{
|
||||||
|
if (isTransitionSource(modelNode))
|
||||||
|
return 10;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString TransitionTool::name() const
|
||||||
|
{
|
||||||
|
return tr("Transition Tool");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransitionTool::activateTool()
|
||||||
|
{
|
||||||
|
view()->changeToCustomTool();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransitionTool::unblock()
|
||||||
|
{
|
||||||
|
m_blockEvents = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGraphicsLineItem *TransitionTool::lineItem()
|
||||||
|
{
|
||||||
|
return m_lineItem.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
QGraphicsRectItem *TransitionTool::rectangleItem1()
|
||||||
|
{
|
||||||
|
return m_rectangleItem1.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
QGraphicsRectItem *TransitionTool::rectangleItem2()
|
||||||
|
{
|
||||||
|
return m_rectangleItem2.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
FormEditorItem *TransitionTool::currentFormEditorItem() const
|
||||||
|
{
|
||||||
|
if (scene()->items().contains(m_formEditorItem))
|
||||||
|
return m_formEditorItem;
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransitionTool::createItems() {
|
||||||
|
m_blockEvents = true;
|
||||||
|
QTimer::singleShot(200, this, [this](){ unblock(); });
|
||||||
|
|
||||||
|
if (!lineItem())
|
||||||
|
m_lineItem.reset(new QGraphicsLineItem(scene()->manipulatorLayerItem()));
|
||||||
|
|
||||||
|
if (!rectangleItem1())
|
||||||
|
m_rectangleItem1.reset(new QGraphicsRectItem(scene()->manipulatorLayerItem()));
|
||||||
|
|
||||||
|
if (!rectangleItem2())
|
||||||
|
m_rectangleItem2.reset(new QGraphicsRectItem(scene()->manipulatorLayerItem()));
|
||||||
|
|
||||||
|
m_rectangleItem2->setVisible(false);
|
||||||
|
|
||||||
|
QPen pen;
|
||||||
|
pen.setColor(QColor(Qt::lightGray));
|
||||||
|
pen.setStyle(Qt::DashLine);
|
||||||
|
pen.setWidth(0);
|
||||||
|
m_lineItem->setPen(pen);
|
||||||
|
|
||||||
|
pen.setColor(QColor(108, 141, 221));
|
||||||
|
pen.setStyle(Qt::SolidLine);
|
||||||
|
pen.setWidth(4);
|
||||||
|
pen.setCosmetic(true);
|
||||||
|
m_rectangleItem1->setPen(pen);
|
||||||
|
|
||||||
|
m_rectangleItem2->setPen(pen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransitionTool::createTransition(FormEditorItem *source, FormEditorItem *target)
|
||||||
|
{
|
||||||
|
QmlFlowTargetNode sourceNode(source->qmlItemNode().modelNode());
|
||||||
|
QmlFlowTargetNode targetNode(target->qmlItemNode().modelNode());
|
||||||
|
|
||||||
|
if (sourceNode.isValid() && targetNode.isValid()
|
||||||
|
&& sourceNode != targetNode
|
||||||
|
&& !targetNode.isFlowActionArea()
|
||||||
|
&& !targetNode.isFlowWildcard()) {
|
||||||
|
view()->executeInTransaction("create transition", [&sourceNode, targetNode](){
|
||||||
|
sourceNode.assignTargetItem(targetNode);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
qWarning() << Q_FUNC_INFO << "nodes invalid";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,98 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 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 "abstractcustomtool.h"
|
||||||
|
#include "selectionindicator.h"
|
||||||
|
|
||||||
|
#include <QGraphicsLineItem>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QPointer>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class TransitionTool : public QObject, public AbstractCustomTool
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
TransitionTool();
|
||||||
|
~TransitionTool();
|
||||||
|
|
||||||
|
void mousePressEvent(const QList<QGraphicsItem*> &itemList,
|
||||||
|
QGraphicsSceneMouseEvent *event) override;
|
||||||
|
void mouseMoveEvent(const QList<QGraphicsItem*> &itemList,
|
||||||
|
QGraphicsSceneMouseEvent *event) override;
|
||||||
|
void mouseReleaseEvent(const QList<QGraphicsItem*> &itemList,
|
||||||
|
QGraphicsSceneMouseEvent *event) override;
|
||||||
|
void mouseDoubleClickEvent(const QList<QGraphicsItem*> &itemList,
|
||||||
|
QGraphicsSceneMouseEvent *event) override;
|
||||||
|
void hoverMoveEvent(const QList<QGraphicsItem*> &itemList,
|
||||||
|
QGraphicsSceneMouseEvent *event) override;
|
||||||
|
void keyPressEvent(QKeyEvent *event) override;
|
||||||
|
void keyReleaseEvent(QKeyEvent *keyEvent) override;
|
||||||
|
|
||||||
|
void dragLeaveEvent(const QList<QGraphicsItem*> &itemList,
|
||||||
|
QGraphicsSceneDragDropEvent * event) override;
|
||||||
|
void dragMoveEvent(const QList<QGraphicsItem*> &itemList,
|
||||||
|
QGraphicsSceneDragDropEvent * event) override;
|
||||||
|
|
||||||
|
void itemsAboutToRemoved(const QList<FormEditorItem*> &itemList) override;
|
||||||
|
|
||||||
|
void selectedItemsChanged(const QList<FormEditorItem*> &itemList) override;
|
||||||
|
|
||||||
|
void instancesCompleted(const QList<FormEditorItem*> &itemList) override;
|
||||||
|
void instancesParentChanged(const QList<FormEditorItem *> &itemList) override;
|
||||||
|
void instancePropertyChange(const QList<QPair<ModelNode, PropertyName> > &propertyList) override;
|
||||||
|
|
||||||
|
void clear() override;
|
||||||
|
|
||||||
|
void formEditorItemsChanged(const QList<FormEditorItem*> &itemList) override;
|
||||||
|
|
||||||
|
int wantHandleItem(const ModelNode &modelNode) const override;
|
||||||
|
|
||||||
|
QString name() const override;
|
||||||
|
|
||||||
|
void activateTool();
|
||||||
|
void unblock();
|
||||||
|
|
||||||
|
QGraphicsLineItem *lineItem();
|
||||||
|
QGraphicsRectItem *rectangleItem1();
|
||||||
|
QGraphicsRectItem *rectangleItem2();
|
||||||
|
|
||||||
|
private:
|
||||||
|
FormEditorItem *currentFormEditorItem() const;
|
||||||
|
void createItems();
|
||||||
|
void createTransition(FormEditorItem *item1, FormEditorItem *item2);
|
||||||
|
|
||||||
|
FormEditorItem* m_formEditorItem;
|
||||||
|
std::unique_ptr<QGraphicsLineItem> m_lineItem;
|
||||||
|
std::unique_ptr<QGraphicsRectItem> m_rectangleItem1;
|
||||||
|
std::unique_ptr<QGraphicsRectItem> m_rectangleItem2;
|
||||||
|
bool m_blockEvents = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
} //QmlDesigner
|
@@ -81,14 +81,16 @@ void ImportManagerView::modelAboutToBeDetached(Model *model)
|
|||||||
|
|
||||||
void ImportManagerView::importsChanged(const QList<Import> &/*addedImports*/, const QList<Import> &/*removedImports*/)
|
void ImportManagerView::importsChanged(const QList<Import> &/*addedImports*/, const QList<Import> &/*removedImports*/)
|
||||||
{
|
{
|
||||||
if (m_importsWidget)
|
if (m_importsWidget) {
|
||||||
m_importsWidget->setImports(model()->imports());
|
m_importsWidget->setImports(model()->imports());
|
||||||
|
// setImports recreates labels, so we need to update used imports, as it is not guaranteed
|
||||||
|
// usedImportsChanged notification will come after this.
|
||||||
|
m_importsWidget->setUsedImports(model()->usedImports());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportManagerView::possibleImportsChanged(const QList<Import> &/*possibleImports*/)
|
void ImportManagerView::possibleImportsChanged(const QList<Import> &/*possibleImports*/)
|
||||||
{
|
{
|
||||||
QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager();
|
|
||||||
|
|
||||||
if (m_importsWidget)
|
if (m_importsWidget)
|
||||||
m_importsWidget->setPossibleImports(model()->possibleImports());
|
m_importsWidget->setPossibleImports(model()->possibleImports());
|
||||||
}
|
}
|
||||||
|
@@ -32,6 +32,9 @@
|
|||||||
#include "utils/outputformatter.h"
|
#include "utils/outputformatter.h"
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
|
|
||||||
|
#include <projectexplorer/project.h>
|
||||||
|
#include <projectexplorer/session.h>
|
||||||
|
|
||||||
#include <QtCore/qfileinfo.h>
|
#include <QtCore/qfileinfo.h>
|
||||||
#include <QtCore/qdir.h>
|
#include <QtCore/qdir.h>
|
||||||
#include <QtCore/qloggingcategory.h>
|
#include <QtCore/qloggingcategory.h>
|
||||||
@@ -97,6 +100,20 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &im
|
|||||||
|
|
||||||
ui->buttonBox->button(QDialogButtonBox::Close)->setDefault(true);
|
ui->buttonBox->button(QDialogButtonBox::Close)->setDefault(true);
|
||||||
|
|
||||||
|
QStringList importPaths;
|
||||||
|
auto doc = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||||
|
if (doc) {
|
||||||
|
Model *model = doc->currentModel();
|
||||||
|
if (model)
|
||||||
|
importPaths = model->importPaths();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString targetDir = defaulTargetDirectory;
|
||||||
|
|
||||||
|
ProjectExplorer::Project *currentProject = ProjectExplorer::SessionManager::projectForFile(doc->fileName());
|
||||||
|
if (currentProject)
|
||||||
|
targetDir = currentProject->projectDirectory().toString();
|
||||||
|
|
||||||
// Import is always done under known folder. The order of preference for folder is:
|
// Import is always done under known folder. The order of preference for folder is:
|
||||||
// 1) An existing QUICK_3D_ASSETS_FOLDER under DEFAULT_ASSET_IMPORT_FOLDER project import path
|
// 1) An existing QUICK_3D_ASSETS_FOLDER under DEFAULT_ASSET_IMPORT_FOLDER project import path
|
||||||
// 2) An existing QUICK_3D_ASSETS_FOLDER under any project import path
|
// 2) An existing QUICK_3D_ASSETS_FOLDER under any project import path
|
||||||
@@ -105,19 +122,11 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &im
|
|||||||
// 5) New QUICK_3D_ASSETS_FOLDER under new DEFAULT_ASSET_IMPORT_FOLDER under project
|
// 5) New QUICK_3D_ASSETS_FOLDER under new DEFAULT_ASSET_IMPORT_FOLDER under project
|
||||||
const QString defaultAssetFolder = QLatin1String(Constants::DEFAULT_ASSET_IMPORT_FOLDER);
|
const QString defaultAssetFolder = QLatin1String(Constants::DEFAULT_ASSET_IMPORT_FOLDER);
|
||||||
const QString quick3DFolder = QLatin1String(Constants::QUICK_3D_ASSETS_FOLDER);
|
const QString quick3DFolder = QLatin1String(Constants::QUICK_3D_ASSETS_FOLDER);
|
||||||
QString candidatePath = defaulTargetDirectory + defaultAssetFolder + quick3DFolder;
|
QString candidatePath = targetDir + defaultAssetFolder + quick3DFolder;
|
||||||
int candidatePriority = 5;
|
int candidatePriority = 5;
|
||||||
QStringList importPaths;
|
|
||||||
|
|
||||||
auto doc = QmlDesignerPlugin::instance()->currentDesignDocument();
|
|
||||||
if (doc) {
|
|
||||||
Model *model = doc->currentModel();
|
|
||||||
if (model)
|
|
||||||
importPaths = model->importPaths();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto importPath : qAsConst(importPaths)) {
|
for (auto importPath : qAsConst(importPaths)) {
|
||||||
if (importPath.startsWith(defaulTargetDirectory)) {
|
if (importPath.startsWith(targetDir)) {
|
||||||
const bool isDefaultFolder = importPath.endsWith(defaultAssetFolder);
|
const bool isDefaultFolder = importPath.endsWith(defaultAssetFolder);
|
||||||
const QString assetFolder = importPath + quick3DFolder;
|
const QString assetFolder = importPath + quick3DFolder;
|
||||||
const bool exists = QFileInfo(assetFolder).exists();
|
const bool exists = QFileInfo(assetFolder).exists();
|
||||||
|
@@ -280,7 +280,16 @@ void ItemLibraryAssetImporter::parseQuick3DAsset(const QString &file, const QVar
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString originalAssetName = assetName;
|
||||||
if (targetDir.exists(assetName)) {
|
if (targetDir.exists(assetName)) {
|
||||||
|
// If we have a file system with case insensitive filenames, assetName may be
|
||||||
|
// different from the existing name. Modify assetName to ensure exact match to
|
||||||
|
// the overwritten old asset capitalization
|
||||||
|
const QStringList assetDirs = targetDir.entryList({assetName}, QDir::Dirs);
|
||||||
|
if (assetDirs.size() == 1) {
|
||||||
|
assetName = assetDirs[0];
|
||||||
|
targetDirPath = targetDir.filePath(assetName);
|
||||||
|
}
|
||||||
if (!confirmAssetOverwrite(assetName)) {
|
if (!confirmAssetOverwrite(assetName)) {
|
||||||
addWarning(tr("Skipped import of existing asset: \"%1\"").arg(assetName));
|
addWarning(tr("Skipped import of existing asset: \"%1\"").arg(assetName));
|
||||||
return;
|
return;
|
||||||
@@ -306,6 +315,16 @@ void ItemLibraryAssetImporter::parseQuick3DAsset(const QString &file, const QVar
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The importer is reset after every import to avoid issues with it caching various things
|
||||||
|
m_quick3DAssetImporter.reset(new QSSGAssetImportManager);
|
||||||
|
|
||||||
|
if (originalAssetName != assetName) {
|
||||||
|
// Fix the generated qml file name
|
||||||
|
const QString assetQml = originalAssetName + ".qml";
|
||||||
|
if (outDir.exists(assetQml))
|
||||||
|
outDir.rename(assetQml, assetName + ".qml");
|
||||||
|
}
|
||||||
|
|
||||||
QHash<QString, QString> assetFiles;
|
QHash<QString, QString> assetFiles;
|
||||||
const int outDirPathSize = outDir.path().size();
|
const int outDirPathSize = outDir.path().size();
|
||||||
auto insertAsset = [&](const QString &filePath) {
|
auto insertAsset = [&](const QString &filePath) {
|
||||||
@@ -512,18 +531,24 @@ void ItemLibraryAssetImporter::finalizeQuick3DImport()
|
|||||||
addInfo(progressTitle);
|
addInfo(progressTitle);
|
||||||
notifyProgress(0, progressTitle);
|
notifyProgress(0, progressTitle);
|
||||||
|
|
||||||
// There is an inbuilt delay before rewriter change actually updates the data model,
|
// First we have to wait a while to ensure qmljs detects new files and updates its
|
||||||
// so we need to wait for a moment to allow the change to take effect.
|
// internal model. Then we make a non-change to the document to trigger qmljs snapshot
|
||||||
|
// update. There is an inbuilt delay before rewriter change actually updates the data
|
||||||
|
// model, so we need to wait for another moment to allow the change to take effect.
|
||||||
// Otherwise subsequent subcomponent manager update won't detect new imports properly.
|
// Otherwise subsequent subcomponent manager update won't detect new imports properly.
|
||||||
QTimer *timer = new QTimer(parent());
|
QTimer *timer = new QTimer(parent());
|
||||||
static int counter;
|
static int counter;
|
||||||
counter = 0;
|
counter = 0;
|
||||||
timer->callOnTimeout([this, timer, progressTitle, model]() {
|
timer->callOnTimeout([this, timer, progressTitle, model, doc]() {
|
||||||
if (!isCancelled()) {
|
if (!isCancelled()) {
|
||||||
notifyProgress(++counter * 10, progressTitle);
|
notifyProgress(++counter * 5, progressTitle);
|
||||||
if (counter >= 10) {
|
if (counter == 10) {
|
||||||
// Trigger underlying qmljs snapshot update by making a non-change to the doc
|
|
||||||
model->rewriterView()->textModifier()->replace(0, 0, {});
|
model->rewriterView()->textModifier()->replace(0, 0, {});
|
||||||
|
} else if (counter == 19) {
|
||||||
|
doc->updateSubcomponentManager();
|
||||||
|
} else if (counter >= 20) {
|
||||||
|
if (!m_overwrittenImports.isEmpty())
|
||||||
|
model->rewriterView()->emitCustomNotification("asset_import_update");
|
||||||
timer->stop();
|
timer->stop();
|
||||||
notifyFinished();
|
notifyFinished();
|
||||||
}
|
}
|
||||||
|
@@ -43,6 +43,7 @@ public:
|
|||||||
virtual void notifyModelNodesRemoved(const QList<ModelNode> &modelNodes) = 0;
|
virtual void notifyModelNodesRemoved(const QList<ModelNode> &modelNodes) = 0;
|
||||||
virtual void notifyModelNodesInserted(const QList<ModelNode> &modelNodes) = 0;
|
virtual void notifyModelNodesInserted(const QList<ModelNode> &modelNodes) = 0;
|
||||||
virtual void notifyModelNodesMoved(const QList<ModelNode> &modelNodes) = 0;
|
virtual void notifyModelNodesMoved(const QList<ModelNode> &modelNodes) = 0;
|
||||||
|
virtual void notifyIconsChanged() = 0;
|
||||||
virtual void setFilter(bool showObjects) = 0;
|
virtual void setFilter(bool showObjects) = 0;
|
||||||
virtual void resetModel() = 0;
|
virtual void resetModel() = 0;
|
||||||
};
|
};
|
||||||
|
@@ -695,6 +695,11 @@ void NavigatorTreeModel::notifyModelNodesMoved(const QList<ModelNode> &modelNode
|
|||||||
emit layoutChanged(indexes);
|
emit layoutChanged(indexes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NavigatorTreeModel::notifyIconsChanged()
|
||||||
|
{
|
||||||
|
emit dataChanged(index(0, 0), index(rowCount(), 0), {Qt::DecorationRole});
|
||||||
|
}
|
||||||
|
|
||||||
void NavigatorTreeModel::setFilter(bool showOnlyVisibleItems)
|
void NavigatorTreeModel::setFilter(bool showOnlyVisibleItems)
|
||||||
{
|
{
|
||||||
m_showOnlyVisibleItems = showOnlyVisibleItems;
|
m_showOnlyVisibleItems = showOnlyVisibleItems;
|
||||||
|
@@ -87,6 +87,7 @@ public:
|
|||||||
void notifyModelNodesRemoved(const QList<ModelNode> &modelNodes) override;
|
void notifyModelNodesRemoved(const QList<ModelNode> &modelNodes) override;
|
||||||
void notifyModelNodesInserted(const QList<ModelNode> &modelNodes) override;
|
void notifyModelNodesInserted(const QList<ModelNode> &modelNodes) override;
|
||||||
void notifyModelNodesMoved(const QList<ModelNode> &modelNodes) override;
|
void notifyModelNodesMoved(const QList<ModelNode> &modelNodes) override;
|
||||||
|
void notifyIconsChanged() override;
|
||||||
void setFilter(bool showOnlyVisibleItems) override;
|
void setFilter(bool showOnlyVisibleItems) override;
|
||||||
void resetModel() override;
|
void resetModel() override;
|
||||||
|
|
||||||
|
@@ -147,6 +147,17 @@ void NavigatorView::bindingPropertiesChanged(const QList<BindingProperty> & prop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NavigatorView::customNotification(const AbstractView *view, const QString &identifier,
|
||||||
|
const QList<ModelNode> &nodeList, const QList<QVariant> &data)
|
||||||
|
{
|
||||||
|
Q_UNUSED(view)
|
||||||
|
Q_UNUSED(nodeList)
|
||||||
|
Q_UNUSED(data)
|
||||||
|
|
||||||
|
if (identifier == "asset_import_update")
|
||||||
|
m_currentModelInterface->notifyIconsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void NavigatorView::handleChangedExport(const ModelNode &modelNode, bool exported)
|
void NavigatorView::handleChangedExport(const ModelNode &modelNode, bool exported)
|
||||||
{
|
{
|
||||||
const ModelNode rootNode = rootModelNode();
|
const ModelNode rootNode = rootModelNode();
|
||||||
@@ -434,7 +445,7 @@ void NavigatorView::updateItemSelection()
|
|||||||
// make sure selected nodes a visible
|
// make sure selected nodes a visible
|
||||||
foreach (const QModelIndex &selectedIndex, itemSelection.indexes()) {
|
foreach (const QModelIndex &selectedIndex, itemSelection.indexes()) {
|
||||||
if (selectedIndex.column() == 0)
|
if (selectedIndex.column() == 0)
|
||||||
expandRecursively(selectedIndex);
|
expandAncestors(selectedIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,9 +469,9 @@ bool NavigatorView::blockSelectionChangedSignal(bool block)
|
|||||||
return oldValue;
|
return oldValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigatorView::expandRecursively(const QModelIndex &index)
|
void NavigatorView::expandAncestors(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
QModelIndex currentIndex = index;
|
QModelIndex currentIndex = index.parent();
|
||||||
while (currentIndex.isValid()) {
|
while (currentIndex.isValid()) {
|
||||||
if (!treeWidget()->isExpanded(currentIndex))
|
if (!treeWidget()->isExpanded(currentIndex))
|
||||||
treeWidget()->expand(currentIndex);
|
treeWidget()->expand(currentIndex);
|
||||||
|
@@ -84,6 +84,8 @@ public:
|
|||||||
|
|
||||||
void bindingPropertiesChanged(const QList<BindingProperty> &propertyList, PropertyChangeFlags) override;
|
void bindingPropertiesChanged(const QList<BindingProperty> &propertyList, PropertyChangeFlags) override;
|
||||||
|
|
||||||
|
void customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
||||||
|
|
||||||
void handleChangedExport(const ModelNode &modelNode, bool exported);
|
void handleChangedExport(const ModelNode &modelNode, bool exported);
|
||||||
bool isNodeInvisible(const ModelNode &modelNode) const;
|
bool isNodeInvisible(const ModelNode &modelNode) const;
|
||||||
|
|
||||||
@@ -108,7 +110,7 @@ protected: //functions
|
|||||||
QTreeView *treeWidget() const;
|
QTreeView *treeWidget() const;
|
||||||
NavigatorTreeModel *treeModel();
|
NavigatorTreeModel *treeModel();
|
||||||
bool blockSelectionChangedSignal(bool block);
|
bool blockSelectionChangedSignal(bool block);
|
||||||
void expandRecursively(const QModelIndex &index);
|
void expandAncestors(const QModelIndex &index);
|
||||||
void reparentAndCatch(NodeAbstractProperty property, const ModelNode &modelNode);
|
void reparentAndCatch(NodeAbstractProperty property, const ModelNode &modelNode);
|
||||||
void setupWidget();
|
void setupWidget();
|
||||||
|
|
||||||
|
@@ -0,0 +1,69 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 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 "hyperlinkdialog.h"
|
||||||
|
#include "ui_hyperlinkdialog.h"
|
||||||
|
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
|
||||||
|
HyperlinkDialog::HyperlinkDialog(QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::HyperlinkDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
connect (ui->linkEdit, &QLineEdit::textChanged, [this] () {
|
||||||
|
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!(ui->linkEdit->text().isEmpty()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
HyperlinkDialog::~HyperlinkDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString HyperlinkDialog::getLink() const
|
||||||
|
{
|
||||||
|
return ui->linkEdit->text().trimmed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HyperlinkDialog::setLink(const QString &link)
|
||||||
|
{
|
||||||
|
ui->linkEdit->setText(link);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString HyperlinkDialog::getAnchor() const
|
||||||
|
{
|
||||||
|
return ui->anchorEdit->text().trimmed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HyperlinkDialog::setAnchor(const QString &anchor)
|
||||||
|
{
|
||||||
|
ui->anchorEdit->setText(anchor);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,54 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 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 <QDialog>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class HyperlinkDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class HyperlinkDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit HyperlinkDialog(QWidget *parent = nullptr);
|
||||||
|
~HyperlinkDialog();
|
||||||
|
|
||||||
|
QString getLink() const;
|
||||||
|
void setLink(const QString &link);
|
||||||
|
|
||||||
|
QString getAnchor() const;
|
||||||
|
void setAnchor(const QString &anchor);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::HyperlinkDialog *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,88 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>QmlDesigner::HyperlinkDialog</class>
|
||||||
|
<widget class="QDialog" name="QmlDesigner::HyperlinkDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>403</width>
|
||||||
|
<height>156</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string notr="true">Dialog</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Link</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="linkEdit"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Anchor</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="anchorEdit"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>QmlDesigner::HyperlinkDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>QmlDesigner::HyperlinkDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
@@ -0,0 +1,684 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 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 "richtexteditor.h"
|
||||||
|
#include "ui_richtexteditor.h"
|
||||||
|
#include "hyperlinkdialog.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include <QToolButton>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QStyle>
|
||||||
|
#include <QStyleFactory>
|
||||||
|
#include <QColorDialog>
|
||||||
|
#include <QWidgetAction>
|
||||||
|
#include <QTextTable>
|
||||||
|
#include <QScopeGuard>
|
||||||
|
#include <QPointer>
|
||||||
|
|
||||||
|
#include <utils/stylehelper.h>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class FontWidgetActions : public QWidgetAction {
|
||||||
|
public:
|
||||||
|
FontWidgetActions(QObject *parent = nullptr)
|
||||||
|
: QWidgetAction(parent) {}
|
||||||
|
|
||||||
|
~FontWidgetActions () override {}
|
||||||
|
|
||||||
|
void setInitializer(std::function<void(T*)> func)
|
||||||
|
{
|
||||||
|
m_initializer = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QWidget *> createdWidgets()
|
||||||
|
{
|
||||||
|
return QWidgetAction::createdWidgets();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QWidget *createWidget(QWidget *parent) override
|
||||||
|
{
|
||||||
|
T *w = new T(parent);
|
||||||
|
if (m_initializer)
|
||||||
|
m_initializer(w);
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deleteWidget(QWidget *widget) override
|
||||||
|
{
|
||||||
|
widget->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::function<void(T*)> m_initializer;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void cursorEditBlock(QTextCursor& cursor, std::function<void()> f) {
|
||||||
|
cursor.beginEditBlock();
|
||||||
|
f();
|
||||||
|
cursor.endEditBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
RichTextEditor::RichTextEditor(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
, ui(new Ui::RichTextEditor)
|
||||||
|
, m_linkDialog(new HyperlinkDialog(this))
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
ui->textEdit->setTextInteractionFlags(Qt::TextEditorInteraction | Qt::LinksAccessibleByMouse);
|
||||||
|
ui->tableBar->setVisible(false);
|
||||||
|
|
||||||
|
setupEditActions();
|
||||||
|
setupTextActions();
|
||||||
|
setupHyperlinkActions();
|
||||||
|
setupAlignActions();
|
||||||
|
setupListActions();
|
||||||
|
setupFontActions();
|
||||||
|
setupTableActions();
|
||||||
|
|
||||||
|
connect(ui->textEdit, &QTextEdit::currentCharFormatChanged,
|
||||||
|
this, &RichTextEditor::currentCharFormatChanged);
|
||||||
|
connect(ui->textEdit, &QTextEdit::cursorPositionChanged,
|
||||||
|
this, &RichTextEditor::cursorPositionChanged);
|
||||||
|
connect(m_linkDialog, &QDialog::accepted, [this]() {
|
||||||
|
QTextCharFormat oldFormat = ui->textEdit->textCursor().charFormat();
|
||||||
|
|
||||||
|
QTextCursor tcursor = ui->textEdit->textCursor();
|
||||||
|
QTextCharFormat charFormat = tcursor.charFormat();
|
||||||
|
|
||||||
|
charFormat.setForeground(QApplication::palette().color(QPalette::Link));
|
||||||
|
charFormat.setFontUnderline(true);
|
||||||
|
|
||||||
|
QString link = m_linkDialog->getLink();
|
||||||
|
QString anchor = m_linkDialog->getAnchor();
|
||||||
|
|
||||||
|
if (anchor.isEmpty())
|
||||||
|
anchor = link;
|
||||||
|
|
||||||
|
charFormat.setAnchor(true);
|
||||||
|
charFormat.setAnchorHref(link);
|
||||||
|
charFormat.setAnchorNames(QStringList(anchor));
|
||||||
|
|
||||||
|
tcursor.insertText(anchor, charFormat);
|
||||||
|
|
||||||
|
tcursor.insertText(" ", oldFormat);
|
||||||
|
|
||||||
|
m_linkDialog->hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
ui->textEdit->setFocus();
|
||||||
|
m_linkDialog->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
RichTextEditor::~RichTextEditor()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::setPlainText(const QString &text)
|
||||||
|
{
|
||||||
|
ui->textEdit->setPlainText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString RichTextEditor::plainText() const
|
||||||
|
{
|
||||||
|
return ui->textEdit->toPlainText();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::setRichText(const QString &text)
|
||||||
|
{
|
||||||
|
ui->textEdit->setHtml(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::setTabChangesFocus(bool change)
|
||||||
|
{
|
||||||
|
ui->textEdit->setTabChangesFocus(change);
|
||||||
|
}
|
||||||
|
|
||||||
|
QIcon RichTextEditor::getIcon(Theme::Icon icon)
|
||||||
|
{
|
||||||
|
const QString fontName = "qtds_propertyIconFont.ttf";
|
||||||
|
|
||||||
|
return Utils::StyleHelper::getIconFromIconFont(fontName, Theme::getIconUnicode(icon), 20, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString RichTextEditor::richText() const
|
||||||
|
{
|
||||||
|
return ui->textEdit->toHtml();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::currentCharFormatChanged(const QTextCharFormat &format)
|
||||||
|
{
|
||||||
|
fontChanged(format.font());
|
||||||
|
colorChanged(format.foreground().color());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::cursorPositionChanged()
|
||||||
|
{
|
||||||
|
alignmentChanged(ui->textEdit->alignment());
|
||||||
|
styleChanged(ui->textEdit->textCursor());
|
||||||
|
tableChanged(ui->textEdit->textCursor());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::mergeFormatOnWordOrSelection(const QTextCharFormat &format)
|
||||||
|
{
|
||||||
|
QTextCursor cursor = ui->textEdit->textCursor();
|
||||||
|
if (!cursor.hasSelection())
|
||||||
|
cursor.select(QTextCursor::WordUnderCursor);
|
||||||
|
cursor.mergeCharFormat(format);
|
||||||
|
ui->textEdit->mergeCurrentCharFormat(format);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::fontChanged(const QFont &f)
|
||||||
|
{
|
||||||
|
for (QWidget* w: m_fontNameAction->createdWidgets() ) {
|
||||||
|
QFontComboBox* box = qobject_cast<QFontComboBox*>(w);
|
||||||
|
if (box)
|
||||||
|
box->setCurrentFont(f);
|
||||||
|
}
|
||||||
|
for (QWidget* w: m_fontSizeAction->createdWidgets() ) {
|
||||||
|
QComboBox* box = qobject_cast<QComboBox*>(w);
|
||||||
|
if (box)
|
||||||
|
box->setCurrentText(QString::number(f.pointSize()));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_actionTextBold->setChecked(f.bold());
|
||||||
|
m_actionTextItalic->setChecked(f.italic());
|
||||||
|
m_actionTextUnderline->setChecked(f.underline());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::colorChanged(const QColor &c)
|
||||||
|
{
|
||||||
|
QPixmap colorBox(ui->tableBar->iconSize());
|
||||||
|
colorBox.fill(c);
|
||||||
|
m_actionTextColor->setIcon(colorBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::alignmentChanged(Qt::Alignment a)
|
||||||
|
{
|
||||||
|
if (a & Qt::AlignLeft)
|
||||||
|
m_actionAlignLeft->setChecked(true);
|
||||||
|
else if (a & Qt::AlignHCenter)
|
||||||
|
m_actionAlignCenter->setChecked(true);
|
||||||
|
else if (a & Qt::AlignRight)
|
||||||
|
m_actionAlignRight->setChecked(true);
|
||||||
|
else if (a & Qt::AlignJustify)
|
||||||
|
m_actionAlignJustify->setChecked(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::styleChanged(const QTextCursor &cursor)
|
||||||
|
{
|
||||||
|
if (!m_actionBulletList || !m_actionNumberedList) return;
|
||||||
|
|
||||||
|
QTextList *currentList = cursor.currentList();
|
||||||
|
|
||||||
|
if (currentList) {
|
||||||
|
if (currentList->format().style() == QTextListFormat::ListDisc) {
|
||||||
|
m_actionBulletList->setChecked(true);
|
||||||
|
m_actionNumberedList->setChecked(false);
|
||||||
|
}
|
||||||
|
else if (currentList->format().style() == QTextListFormat::ListDecimal) {
|
||||||
|
m_actionBulletList->setChecked(false);
|
||||||
|
m_actionNumberedList->setChecked(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_actionBulletList->setChecked(false);
|
||||||
|
m_actionNumberedList->setChecked(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_actionBulletList->setChecked(false);
|
||||||
|
m_actionNumberedList->setChecked(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::tableChanged(const QTextCursor &cursor)
|
||||||
|
{
|
||||||
|
if (!m_actionTableSettings) return;
|
||||||
|
|
||||||
|
QTextTable *currentTable = cursor.currentTable();
|
||||||
|
|
||||||
|
if (currentTable) {
|
||||||
|
m_actionTableSettings->setChecked(true);
|
||||||
|
ui->tableBar->setVisible(true);
|
||||||
|
|
||||||
|
setTableActionsActive(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setTableActionsActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::setupEditActions()
|
||||||
|
{
|
||||||
|
const QIcon undoIcon(getIcon(Theme::Icon::undo));
|
||||||
|
QAction *actionUndo = ui->toolBar->addAction(undoIcon, tr("&Undo"), ui->textEdit, &QTextEdit::undo);
|
||||||
|
actionUndo->setShortcut(QKeySequence::Undo);
|
||||||
|
connect(ui->textEdit->document(), &QTextDocument::undoAvailable,
|
||||||
|
actionUndo, &QAction::setEnabled);
|
||||||
|
|
||||||
|
const QIcon redoIcon(getIcon(Theme::Icon::redo));
|
||||||
|
QAction *actionRedo = ui->toolBar->addAction(redoIcon, tr("&Redo"), ui->textEdit, &QTextEdit::redo);
|
||||||
|
actionRedo->setShortcut(QKeySequence::Redo);
|
||||||
|
connect(ui->textEdit->document(), &QTextDocument::redoAvailable,
|
||||||
|
actionRedo, &QAction::setEnabled);
|
||||||
|
|
||||||
|
actionUndo->setEnabled(ui->textEdit->document()->isUndoAvailable());
|
||||||
|
actionRedo->setEnabled(ui->textEdit->document()->isRedoAvailable());
|
||||||
|
|
||||||
|
ui->toolBar->addSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::setupTextActions()
|
||||||
|
{
|
||||||
|
const QIcon boldIcon(getIcon(Theme::Icon::fontStyleBold));
|
||||||
|
m_actionTextBold = ui->toolBar->addAction(boldIcon, tr("&Bold"),
|
||||||
|
[this](bool checked) {
|
||||||
|
QTextCharFormat fmt;
|
||||||
|
fmt.setFontWeight(checked ? QFont::Bold : QFont::Normal);
|
||||||
|
mergeFormatOnWordOrSelection(fmt);
|
||||||
|
});
|
||||||
|
m_actionTextBold->setShortcut(Qt::CTRL + Qt::Key_B);
|
||||||
|
QFont bold;
|
||||||
|
bold.setBold(true);
|
||||||
|
m_actionTextBold->setFont(bold);
|
||||||
|
m_actionTextBold->setCheckable(true);
|
||||||
|
|
||||||
|
const QIcon italicIcon(getIcon(Theme::Icon::fontStyleItalic));
|
||||||
|
m_actionTextItalic = ui->toolBar->addAction(italicIcon, tr("&Italic"),
|
||||||
|
[this](bool checked) {
|
||||||
|
QTextCharFormat fmt;
|
||||||
|
fmt.setFontItalic(checked);
|
||||||
|
mergeFormatOnWordOrSelection(fmt);
|
||||||
|
});
|
||||||
|
m_actionTextItalic->setShortcut(Qt::CTRL + Qt::Key_I);
|
||||||
|
QFont italic;
|
||||||
|
italic.setItalic(true);
|
||||||
|
m_actionTextItalic->setFont(italic);
|
||||||
|
m_actionTextItalic->setCheckable(true);
|
||||||
|
|
||||||
|
const QIcon underlineIcon(getIcon(Theme::Icon::fontStyleUnderline));
|
||||||
|
m_actionTextUnderline = ui->toolBar->addAction(underlineIcon, tr("&Underline"),
|
||||||
|
[this](bool checked) {
|
||||||
|
QTextCharFormat fmt;
|
||||||
|
fmt.setFontUnderline(checked);
|
||||||
|
mergeFormatOnWordOrSelection(fmt);
|
||||||
|
});
|
||||||
|
m_actionTextUnderline->setShortcut(Qt::CTRL + Qt::Key_U);
|
||||||
|
QFont underline;
|
||||||
|
underline.setUnderline(true);
|
||||||
|
m_actionTextUnderline->setFont(underline);
|
||||||
|
m_actionTextUnderline->setCheckable(true);
|
||||||
|
|
||||||
|
ui->toolBar->addSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::setupHyperlinkActions()
|
||||||
|
{
|
||||||
|
const QIcon bulletIcon(getIcon(Theme::Icon::actionIconBinding));
|
||||||
|
m_actionHyperlink = ui->toolBar->addAction(bulletIcon, tr("Hyperlink Settings"), [this]() {
|
||||||
|
QTextCursor cursor = ui->textEdit->textCursor();
|
||||||
|
QTextCharFormat linkFormat = cursor.charFormat();
|
||||||
|
if (linkFormat.isAnchor()) {
|
||||||
|
m_linkDialog->setLink(linkFormat.anchorHref());
|
||||||
|
m_linkDialog->setAnchor(linkFormat.anchorName());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_linkDialog->setLink("http://");
|
||||||
|
m_linkDialog->setAnchor("");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_linkDialog->show();
|
||||||
|
});
|
||||||
|
m_actionHyperlink->setCheckable(false);
|
||||||
|
|
||||||
|
ui->toolBar->addSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::setupAlignActions()
|
||||||
|
{
|
||||||
|
const QIcon leftIcon(getIcon(Theme::Icon::textAlignLeft));
|
||||||
|
m_actionAlignLeft = ui->toolBar->addAction(leftIcon, tr("&Left"), [this]() { ui->textEdit->setAlignment(Qt::AlignLeft | Qt::AlignAbsolute); });
|
||||||
|
m_actionAlignLeft->setShortcut(Qt::CTRL + Qt::Key_L);
|
||||||
|
m_actionAlignLeft->setCheckable(true);
|
||||||
|
m_actionAlignLeft->setPriority(QAction::LowPriority);
|
||||||
|
|
||||||
|
const QIcon centerIcon(getIcon(Theme::Icon::textAlignCenter));
|
||||||
|
m_actionAlignCenter = ui->toolBar->addAction(centerIcon, tr("C&enter"), [this]() { ui->textEdit->setAlignment(Qt::AlignHCenter); });
|
||||||
|
m_actionAlignCenter->setShortcut(Qt::CTRL + Qt::Key_E);
|
||||||
|
m_actionAlignCenter->setCheckable(true);
|
||||||
|
m_actionAlignCenter->setPriority(QAction::LowPriority);
|
||||||
|
|
||||||
|
const QIcon rightIcon(getIcon(Theme::Icon::textAlignRight));
|
||||||
|
m_actionAlignRight = ui->toolBar->addAction(rightIcon, tr("&Right"), [this]() { ui->textEdit->setAlignment(Qt::AlignRight | Qt::AlignAbsolute); });
|
||||||
|
m_actionAlignRight->setShortcut(Qt::CTRL + Qt::Key_R);
|
||||||
|
m_actionAlignRight->setCheckable(true);
|
||||||
|
m_actionAlignRight->setPriority(QAction::LowPriority);
|
||||||
|
|
||||||
|
const QIcon fillIcon(getIcon(Theme::Icon::textFullJustification));
|
||||||
|
m_actionAlignJustify = ui->toolBar->addAction(fillIcon, tr("&Justify"), [this]() { ui->textEdit->setAlignment(Qt::AlignJustify); });
|
||||||
|
m_actionAlignJustify->setShortcut(Qt::CTRL + Qt::Key_J);
|
||||||
|
m_actionAlignJustify->setCheckable(true);
|
||||||
|
m_actionAlignJustify->setPriority(QAction::LowPriority);
|
||||||
|
|
||||||
|
// Make sure the alignLeft is always left of the alignRight
|
||||||
|
QActionGroup *alignGroup = new QActionGroup(ui->toolBar);
|
||||||
|
|
||||||
|
if (QApplication::isLeftToRight()) {
|
||||||
|
alignGroup->addAction(m_actionAlignLeft);
|
||||||
|
alignGroup->addAction(m_actionAlignCenter);
|
||||||
|
alignGroup->addAction(m_actionAlignRight);
|
||||||
|
} else {
|
||||||
|
alignGroup->addAction(m_actionAlignRight);
|
||||||
|
alignGroup->addAction(m_actionAlignCenter);
|
||||||
|
alignGroup->addAction(m_actionAlignLeft);
|
||||||
|
}
|
||||||
|
alignGroup->addAction(m_actionAlignJustify);
|
||||||
|
|
||||||
|
ui->toolBar->addActions(alignGroup->actions());
|
||||||
|
|
||||||
|
ui->toolBar->addSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::setupListActions()
|
||||||
|
{
|
||||||
|
const QIcon bulletIcon(getIcon(Theme::Icon::textBulletList));
|
||||||
|
m_actionBulletList = ui->toolBar->addAction(bulletIcon, tr("Bullet List"), [this](bool checked) {
|
||||||
|
if (checked) {
|
||||||
|
m_actionNumberedList->setChecked(false);
|
||||||
|
textStyle(QTextListFormat::ListDisc);
|
||||||
|
}
|
||||||
|
else if (!m_actionNumberedList->isChecked()) {
|
||||||
|
textStyle(QTextListFormat::ListStyleUndefined);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
m_actionBulletList->setCheckable(true);
|
||||||
|
|
||||||
|
const QIcon numberedIcon(getIcon(Theme::Icon::textNumberedList));
|
||||||
|
m_actionNumberedList = ui->toolBar->addAction(numberedIcon, tr("Numbered List"), [this](bool checked) {
|
||||||
|
if (checked) {
|
||||||
|
m_actionBulletList->setChecked(false);
|
||||||
|
textStyle(QTextListFormat::ListDecimal);
|
||||||
|
}
|
||||||
|
else if (!m_actionBulletList->isChecked()) {
|
||||||
|
textStyle(QTextListFormat::ListStyleUndefined);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
m_actionNumberedList->setCheckable(true);
|
||||||
|
|
||||||
|
ui->toolBar->addSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::setupFontActions()
|
||||||
|
{
|
||||||
|
QPixmap colorBox(ui->tableBar->iconSize());
|
||||||
|
colorBox.fill(ui->textEdit->textColor());
|
||||||
|
|
||||||
|
m_actionTextColor = ui->toolBar->addAction(colorBox, tr("&Color..."), [this]() {
|
||||||
|
QColor col = QColorDialog::getColor(ui->textEdit->textColor(), this);
|
||||||
|
if (!col.isValid())
|
||||||
|
return;
|
||||||
|
QTextCharFormat fmt;
|
||||||
|
fmt.setForeground(col);
|
||||||
|
mergeFormatOnWordOrSelection(fmt);
|
||||||
|
colorChanged(col);
|
||||||
|
});
|
||||||
|
|
||||||
|
m_fontNameAction = new FontWidgetActions<QFontComboBox>(this);
|
||||||
|
m_fontNameAction->setInitializer([this](QFontComboBox *w) {
|
||||||
|
if (!w) return;
|
||||||
|
|
||||||
|
w->setCurrentIndex(w->findText(ui->textEdit->currentCharFormat().font().family()));
|
||||||
|
connect(w, QOverload<const QString &>::of(&QComboBox::activated), [this](const QString &f) {
|
||||||
|
QTextCharFormat fmt;
|
||||||
|
fmt.setFontFamily(f);
|
||||||
|
mergeFormatOnWordOrSelection(fmt);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
m_fontNameAction->setDefaultWidget(new QFontComboBox);
|
||||||
|
ui->toolBar->addAction(m_fontNameAction);
|
||||||
|
|
||||||
|
m_fontSizeAction = new FontWidgetActions<QComboBox>(this);
|
||||||
|
m_fontSizeAction->setInitializer([this](QComboBox *w) {
|
||||||
|
if (!w) return;
|
||||||
|
|
||||||
|
w->setEditable(true);
|
||||||
|
|
||||||
|
const QList<int> standardSizes = QFontDatabase::standardSizes();
|
||||||
|
foreach (int size, standardSizes)
|
||||||
|
w->addItem(QString::number(size));
|
||||||
|
w->setCurrentText(QString::number(ui->textEdit->currentCharFormat().font().pointSize()));
|
||||||
|
connect(w, QOverload<const QString &>::of(&QComboBox::activated), [this](const QString &p) {
|
||||||
|
qreal pointSize = p.toDouble();
|
||||||
|
if (pointSize > 0.0) {
|
||||||
|
QTextCharFormat fmt;
|
||||||
|
fmt.setFontPointSize(pointSize);
|
||||||
|
mergeFormatOnWordOrSelection(fmt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
m_fontSizeAction->setDefaultWidget(new QComboBox);
|
||||||
|
ui->toolBar->addAction(m_fontSizeAction);
|
||||||
|
|
||||||
|
|
||||||
|
ui->toolBar->addSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::setupTableActions()
|
||||||
|
{
|
||||||
|
const QIcon tableIcon(getIcon(Theme::Icon::addTable));
|
||||||
|
m_actionTableSettings = ui->toolBar->addAction(tableIcon, tr("&Table Settings"), [this](bool checked) {
|
||||||
|
ui->tableBar->setVisible(checked);
|
||||||
|
});
|
||||||
|
m_actionTableSettings->setShortcut(Qt::CTRL + Qt::Key_T);
|
||||||
|
m_actionTableSettings->setCheckable(true);
|
||||||
|
m_actionTableSettings->setPriority(QAction::LowPriority);
|
||||||
|
|
||||||
|
//table bar:
|
||||||
|
|
||||||
|
const QIcon createTableIcon(getIcon(Theme::Icon::addTable));
|
||||||
|
m_actionCreateTable = ui->tableBar->addAction(createTableIcon, tr("Create Table"), [this]() {
|
||||||
|
QTextCursor cursor = ui->textEdit->textCursor();
|
||||||
|
cursorEditBlock(cursor, [&] () {
|
||||||
|
cursor.insertTable(1,1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
m_actionCreateTable->setCheckable(false);
|
||||||
|
|
||||||
|
const QIcon removeTableIcon(getIcon(Theme::Icon::deleteTable));
|
||||||
|
m_actionRemoveTable = ui->tableBar->addAction(removeTableIcon, tr("Remove Table"), [this]() {
|
||||||
|
QTextCursor cursor = ui->textEdit->textCursor();
|
||||||
|
if (QTextTable *currentTable = ui->textEdit->textCursor().currentTable()) {
|
||||||
|
cursorEditBlock(cursor, [&] () {
|
||||||
|
currentTable->removeRows(0, currentTable->rows());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
m_actionRemoveTable->setCheckable(false);
|
||||||
|
|
||||||
|
ui->tableBar->addSeparator();
|
||||||
|
|
||||||
|
const QIcon addRowIcon(getIcon(Theme::Icon::addRowAfter)); //addRowAfter
|
||||||
|
m_actionAddRow = ui->tableBar->addAction(addRowIcon, tr("Add Row"), [this]() {
|
||||||
|
QTextCursor cursor = ui->textEdit->textCursor();
|
||||||
|
if (QTextTable *currentTable = ui->textEdit->textCursor().currentTable()) {
|
||||||
|
cursorEditBlock(cursor, [&] () {
|
||||||
|
currentTable->insertRows(currentTable->cellAt(cursor).row()+1, 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
m_actionAddRow->setCheckable(false);
|
||||||
|
|
||||||
|
const QIcon addColumnIcon(getIcon(Theme::Icon::addColumnAfter)); //addColumnAfter
|
||||||
|
m_actionAddColumn = ui->tableBar->addAction(addColumnIcon, tr("Add Column"), [this]() {
|
||||||
|
QTextCursor cursor = ui->textEdit->textCursor();
|
||||||
|
if (QTextTable *currentTable = ui->textEdit->textCursor().currentTable()) {
|
||||||
|
cursorEditBlock(cursor, [&] () {
|
||||||
|
currentTable->insertColumns(currentTable->cellAt(cursor).column()+1, 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
m_actionAddColumn->setCheckable(false);
|
||||||
|
|
||||||
|
const QIcon removeRowIcon(getIcon(Theme::Icon::deleteRow));
|
||||||
|
m_actionRemoveRow = ui->tableBar->addAction(removeRowIcon, tr("Remove Row"), [this]() {
|
||||||
|
QTextCursor cursor = ui->textEdit->textCursor();
|
||||||
|
if (QTextTable *currentTable = cursor.currentTable()) {
|
||||||
|
cursorEditBlock(cursor, [&] () {
|
||||||
|
currentTable->insertColumns(currentTable->cellAt(cursor).column()+1, 1);
|
||||||
|
|
||||||
|
int firstRow = 0;
|
||||||
|
int numRows = 0;
|
||||||
|
int firstColumn = 0;
|
||||||
|
int numColumns = 0;
|
||||||
|
|
||||||
|
if (cursor.hasSelection())
|
||||||
|
cursor.selectedTableCells(&firstRow, &numRows, &firstColumn, &numColumns);
|
||||||
|
|
||||||
|
if (numRows < 1)
|
||||||
|
currentTable->removeRows(currentTable->cellAt(cursor).row(), 1);
|
||||||
|
else
|
||||||
|
currentTable->removeRows(firstRow, numRows);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
m_actionRemoveRow->setCheckable(false);
|
||||||
|
|
||||||
|
const QIcon removeColumnIcon(getIcon(Theme::Icon::deleteColumn));
|
||||||
|
m_actionRemoveColumn = ui->tableBar->addAction(removeColumnIcon, tr("Remove Column"), [this]() {
|
||||||
|
QTextCursor cursor = ui->textEdit->textCursor();
|
||||||
|
if (QTextTable *currentTable = cursor.currentTable()) {
|
||||||
|
cursorEditBlock(cursor, [&] () {
|
||||||
|
int firstRow = 0;
|
||||||
|
int numRows = 0;
|
||||||
|
int firstColumn = 0;
|
||||||
|
int numColumns = 0;
|
||||||
|
|
||||||
|
if (cursor.hasSelection())
|
||||||
|
cursor.selectedTableCells(&firstRow, &numRows, &firstColumn, &numColumns);
|
||||||
|
|
||||||
|
if (numColumns < 1)
|
||||||
|
currentTable->removeColumns(currentTable->cellAt(cursor).column(), 1);
|
||||||
|
else
|
||||||
|
currentTable->removeColumns(firstColumn, numColumns);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
m_actionRemoveColumn->setCheckable(false);
|
||||||
|
|
||||||
|
ui->tableBar->addSeparator();
|
||||||
|
|
||||||
|
const QIcon mergeCellsIcon(getIcon(Theme::Icon::mergeCells));
|
||||||
|
m_actionMergeCells = ui->tableBar->addAction(mergeCellsIcon, tr("Merge Cells"), [this]() {
|
||||||
|
QTextCursor cursor = ui->textEdit->textCursor();
|
||||||
|
if (QTextTable *currentTable = cursor.currentTable()) {
|
||||||
|
if (cursor.hasSelection()) {
|
||||||
|
cursorEditBlock(cursor, [&] () {
|
||||||
|
currentTable->mergeCells(cursor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
m_actionMergeCells->setCheckable(false);
|
||||||
|
|
||||||
|
const QIcon splitRowIcon(getIcon(Theme::Icon::splitRows));
|
||||||
|
m_actionSplitRow = ui->tableBar->addAction(splitRowIcon, tr("Split Row"), [this]() {
|
||||||
|
QTextCursor cursor = ui->textEdit->textCursor();
|
||||||
|
if (QTextTable *currentTable = cursor.currentTable()) {
|
||||||
|
cursorEditBlock(cursor, [&] () {
|
||||||
|
currentTable->splitCell(currentTable->cellAt(cursor).row(),
|
||||||
|
currentTable->cellAt(cursor).column(),
|
||||||
|
2, 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
m_actionSplitRow->setCheckable(false);
|
||||||
|
|
||||||
|
const QIcon splitColumnIcon(getIcon(Theme::Icon::splitColumns));
|
||||||
|
m_actionSplitColumn = ui->tableBar->addAction(splitRowIcon, tr("Split Column"), [this]() {
|
||||||
|
QTextCursor cursor = ui->textEdit->textCursor();
|
||||||
|
if (QTextTable *currentTable = cursor.currentTable()) {
|
||||||
|
cursorEditBlock(cursor, [&] () {
|
||||||
|
currentTable->splitCell(currentTable->cellAt(cursor).row(),
|
||||||
|
currentTable->cellAt(cursor).column(),
|
||||||
|
1, 2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
m_actionSplitColumn->setCheckable(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::textStyle(QTextListFormat::Style style)
|
||||||
|
{
|
||||||
|
QTextCursor cursor = ui->textEdit->textCursor();
|
||||||
|
cursorEditBlock(cursor, [&] () {
|
||||||
|
if (style != QTextListFormat::ListStyleUndefined) {
|
||||||
|
QTextBlockFormat blockFmt = cursor.blockFormat();
|
||||||
|
QTextListFormat listFmt;
|
||||||
|
|
||||||
|
if (cursor.currentList()) {
|
||||||
|
listFmt = cursor.currentList()->format();
|
||||||
|
} else {
|
||||||
|
listFmt.setIndent(blockFmt.indent() + 1);
|
||||||
|
blockFmt.setIndent(0);
|
||||||
|
cursor.setBlockFormat(blockFmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
listFmt.setStyle(style);
|
||||||
|
|
||||||
|
cursor.createList(listFmt);
|
||||||
|
} else {
|
||||||
|
QTextList* currentList = cursor.currentList();
|
||||||
|
QTextBlock currentBlock = cursor.block();
|
||||||
|
currentList->remove(currentBlock);
|
||||||
|
|
||||||
|
QTextBlockFormat blockFormat = cursor.blockFormat();
|
||||||
|
blockFormat.setIndent(0);
|
||||||
|
cursor.setBlockFormat(blockFormat);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::setTableActionsActive(bool active)
|
||||||
|
{
|
||||||
|
m_actionCreateTable->setEnabled(!active);
|
||||||
|
m_actionRemoveTable->setEnabled(active);
|
||||||
|
|
||||||
|
m_actionAddRow->setEnabled(active);
|
||||||
|
m_actionAddColumn->setEnabled(active);
|
||||||
|
m_actionRemoveRow->setEnabled(active);
|
||||||
|
m_actionRemoveColumn->setEnabled(active);
|
||||||
|
|
||||||
|
m_actionMergeCells->setEnabled(active);
|
||||||
|
m_actionSplitRow->setEnabled(active);
|
||||||
|
m_actionSplitColumn->setEnabled(active);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,130 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 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 <theme.h>
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QToolBar>
|
||||||
|
#include <QList>
|
||||||
|
#include <QTextCharFormat>
|
||||||
|
#include <QTextList>
|
||||||
|
#include <QFontComboBox>
|
||||||
|
#include <QWidgetAction>
|
||||||
|
#include <QPointer>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class RichTextEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class>
|
||||||
|
class FontWidgetActions;
|
||||||
|
|
||||||
|
class HyperlinkDialog;
|
||||||
|
|
||||||
|
class RichTextEditor : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit RichTextEditor(QWidget *parent = nullptr);
|
||||||
|
~RichTextEditor();
|
||||||
|
|
||||||
|
void setPlainText(const QString &text);
|
||||||
|
QString plainText() const;
|
||||||
|
|
||||||
|
void setRichText(const QString &text);
|
||||||
|
QString richText() const;
|
||||||
|
|
||||||
|
void setTabChangesFocus(bool change);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void currentCharFormatChanged(const QTextCharFormat &format);
|
||||||
|
void cursorPositionChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QIcon getIcon(Theme::Icon icon);
|
||||||
|
void mergeFormatOnWordOrSelection(const QTextCharFormat &format);
|
||||||
|
|
||||||
|
void fontChanged(const QFont &f);
|
||||||
|
void colorChanged(const QColor &c);
|
||||||
|
void alignmentChanged(Qt::Alignment a);
|
||||||
|
void styleChanged(const QTextCursor &cursor);
|
||||||
|
void tableChanged(const QTextCursor &cursor);
|
||||||
|
|
||||||
|
void setupEditActions();
|
||||||
|
void setupTextActions();
|
||||||
|
void setupHyperlinkActions();
|
||||||
|
void setupAlignActions();
|
||||||
|
void setupListActions();
|
||||||
|
void setupFontActions();
|
||||||
|
void setupTableActions();
|
||||||
|
|
||||||
|
void textStyle(QTextListFormat::Style style);
|
||||||
|
|
||||||
|
void setTableActionsActive(bool active); //switches between "has table/has no table" ui setup
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<Ui::RichTextEditor> ui;
|
||||||
|
QPointer<HyperlinkDialog> m_linkDialog;
|
||||||
|
|
||||||
|
QAction *m_actionTextBold;
|
||||||
|
QAction *m_actionTextItalic;
|
||||||
|
QAction *m_actionTextUnderline;
|
||||||
|
|
||||||
|
QAction *m_actionHyperlink;
|
||||||
|
|
||||||
|
QAction *m_actionAlignLeft;
|
||||||
|
QAction *m_actionAlignCenter;
|
||||||
|
QAction *m_actionAlignRight;
|
||||||
|
QAction *m_actionAlignJustify;
|
||||||
|
|
||||||
|
QAction *m_actionTextColor;
|
||||||
|
|
||||||
|
QAction *m_actionBulletList;
|
||||||
|
QAction *m_actionNumberedList;
|
||||||
|
|
||||||
|
QAction *m_actionTableSettings;
|
||||||
|
|
||||||
|
QAction *m_actionCreateTable;
|
||||||
|
QAction *m_actionRemoveTable;
|
||||||
|
|
||||||
|
QAction *m_actionAddRow;
|
||||||
|
QAction *m_actionAddColumn;
|
||||||
|
QAction *m_actionRemoveRow;
|
||||||
|
QAction *m_actionRemoveColumn;
|
||||||
|
|
||||||
|
QAction *m_actionMergeCells;
|
||||||
|
QAction *m_actionSplitRow;
|
||||||
|
QAction *m_actionSplitColumn;
|
||||||
|
|
||||||
|
QPointer<FontWidgetActions<QFontComboBox>> m_fontNameAction;
|
||||||
|
QPointer<FontWidgetActions<QComboBox>> m_fontSizeAction;
|
||||||
|
};
|
||||||
|
|
||||||
|
} //namespace QmlDesigner
|
@@ -0,0 +1,8 @@
|
|||||||
|
HEADERS += $$PWD/richtexteditor.h
|
||||||
|
HEADERS += $$PWD/hyperlinkdialog.h
|
||||||
|
|
||||||
|
SOURCES += $$PWD/richtexteditor.cpp
|
||||||
|
SOURCES += $$PWD/hyperlinkdialog.cpp
|
||||||
|
|
||||||
|
FORMS += $$PWD/richtexteditor.ui
|
||||||
|
FORMS += $$PWD/hyperlinkdialog.ui
|
@@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>QmlDesigner::RichTextEditor</class>
|
||||||
|
<widget class="QWidget" name="QmlDesigner::RichTextEditor">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>428</width>
|
||||||
|
<height>283</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>5</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string notr="true">Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QToolBar" name="toolBar">
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolBar" name="tableBar">
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTextEdit" name="textEdit"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@@ -58,6 +58,7 @@
|
|||||||
#include <QSlider>
|
#include <QSlider>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
#include <QSpacerItem>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
@@ -118,6 +119,7 @@ TimelineWidget::TimelineWidget(TimelineView *view)
|
|||||||
, m_timelineView(view)
|
, m_timelineView(view)
|
||||||
, m_graphicsScene(new TimelineGraphicsScene(this))
|
, m_graphicsScene(new TimelineGraphicsScene(this))
|
||||||
, m_addButton(new QPushButton(this))
|
, m_addButton(new QPushButton(this))
|
||||||
|
, m_onboardingContainer(new QWidget(this))
|
||||||
{
|
{
|
||||||
setWindowTitle(tr("Timeline", "Title of timeline view"));
|
setWindowTitle(tr("Timeline", "Title of timeline view"));
|
||||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
@@ -185,6 +187,50 @@ TimelineWidget::TimelineWidget(TimelineView *view)
|
|||||||
m_addButton->setFlat(true);
|
m_addButton->setFlat(true);
|
||||||
m_addButton->setFixedSize(32, 32);
|
m_addButton->setFixedSize(32, 32);
|
||||||
|
|
||||||
|
|
||||||
|
widgetLayout->addWidget(m_onboardingContainer);
|
||||||
|
|
||||||
|
auto *onboardingTopLabel = new QLabel(m_onboardingContainer);
|
||||||
|
auto *onboardingBottomLabel = new QLabel(m_onboardingContainer);
|
||||||
|
auto *onboardingBottomIcon = new QLabel(m_onboardingContainer);
|
||||||
|
|
||||||
|
auto *onboardingLayout = new QVBoxLayout;
|
||||||
|
auto *onboardingSublayout = new QHBoxLayout;
|
||||||
|
auto *leftSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||||
|
auto *rightSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||||
|
auto *topSpacer = new QSpacerItem(40, 20, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||||
|
auto *bottomSpacer = new QSpacerItem(40, 20, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||||
|
|
||||||
|
QString labelText =
|
||||||
|
tr("This file does not contain a timeline. <br><br> \
|
||||||
|
To create an animation, add a timeline by clicking the + button.");
|
||||||
|
onboardingTopLabel->setText(labelText);
|
||||||
|
onboardingTopLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||||
|
|
||||||
|
m_onboardingContainer->setLayout(onboardingLayout);
|
||||||
|
onboardingLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
onboardingLayout->setSpacing(0);
|
||||||
|
onboardingLayout->addSpacerItem(topSpacer);
|
||||||
|
onboardingLayout->addWidget(onboardingTopLabel);
|
||||||
|
onboardingLayout->addLayout(onboardingSublayout);
|
||||||
|
|
||||||
|
onboardingSublayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
onboardingSublayout->setSpacing(0);
|
||||||
|
onboardingSublayout->addSpacerItem(leftSpacer);
|
||||||
|
|
||||||
|
onboardingBottomLabel->setAlignment(Qt::AlignRight | Qt::AlignTop);
|
||||||
|
onboardingBottomLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
|
onboardingSublayout->addWidget(onboardingBottomLabel);
|
||||||
|
onboardingBottomLabel->setText(tr("To edit the timeline settings, click "));
|
||||||
|
|
||||||
|
onboardingBottomIcon->setAlignment(Qt::AlignLeft | Qt::AlignTop);
|
||||||
|
onboardingBottomIcon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
|
onboardingSublayout->addWidget(onboardingBottomIcon);
|
||||||
|
onboardingBottomIcon->setPixmap(TimelineIcons::ANIMATION.pixmap());
|
||||||
|
|
||||||
|
onboardingSublayout->addSpacerItem(rightSpacer);
|
||||||
|
onboardingLayout->addSpacerItem(bottomSpacer);
|
||||||
|
|
||||||
widgetLayout->addLayout(contentLayout);
|
widgetLayout->addLayout(contentLayout);
|
||||||
this->setLayout(widgetLayout);
|
this->setLayout(widgetLayout);
|
||||||
|
|
||||||
@@ -532,6 +578,7 @@ void TimelineWidget::setTimelineActive(bool b)
|
|||||||
m_rulerView->setVisible(true);
|
m_rulerView->setVisible(true);
|
||||||
m_scrollbar->setVisible(true);
|
m_scrollbar->setVisible(true);
|
||||||
m_addButton->setVisible(false);
|
m_addButton->setVisible(false);
|
||||||
|
m_onboardingContainer->setVisible(false);
|
||||||
m_graphicsView->update();
|
m_graphicsView->update();
|
||||||
m_rulerView->update();
|
m_rulerView->update();
|
||||||
} else {
|
} else {
|
||||||
@@ -540,6 +587,7 @@ void TimelineWidget::setTimelineActive(bool b)
|
|||||||
m_rulerView->setVisible(false);
|
m_rulerView->setVisible(false);
|
||||||
m_scrollbar->setVisible(false);
|
m_scrollbar->setVisible(false);
|
||||||
m_addButton->setVisible(true);
|
m_addButton->setVisible(true);
|
||||||
|
m_onboardingContainer->setVisible(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -104,6 +104,8 @@ private:
|
|||||||
TimelineGraphicsScene *m_graphicsScene;
|
TimelineGraphicsScene *m_graphicsScene;
|
||||||
|
|
||||||
QPushButton *m_addButton = nullptr;
|
QPushButton *m_addButton = nullptr;
|
||||||
|
|
||||||
|
QWidget *m_onboardingContainer = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -85,10 +85,25 @@ bool ChangeImportsVisitor::remove(QmlJS::AST::UiProgram *ast, const Import &impo
|
|||||||
|
|
||||||
bool ChangeImportsVisitor::equals(QmlJS::AST::UiImport *ast, const Import &import)
|
bool ChangeImportsVisitor::equals(QmlJS::AST::UiImport *ast, const Import &import)
|
||||||
{
|
{
|
||||||
|
bool equal = false;
|
||||||
if (import.isLibraryImport())
|
if (import.isLibraryImport())
|
||||||
return toString(ast->importUri) == import.url();
|
equal = toString(ast->importUri) == import.url();
|
||||||
else if (import.isFileImport())
|
else if (import.isFileImport())
|
||||||
return ast->fileName == import.file();
|
equal = ast->fileName == import.file();
|
||||||
else
|
|
||||||
return false;
|
if (equal) {
|
||||||
|
equal = (!ast->version || (ast->version->minorVersion == 0 && ast->version->majorVersion == 0))
|
||||||
|
&& import.version().isEmpty();
|
||||||
|
if (!equal && ast->version) {
|
||||||
|
const QStringList versions = import.version().split('.');
|
||||||
|
if (versions.size() >= 1 && versions[0].toInt() == ast->version->majorVersion) {
|
||||||
|
if (versions.size() >= 2)
|
||||||
|
equal = versions[1].toInt() == ast->version->minorVersion;
|
||||||
|
else
|
||||||
|
equal = ast->version->minorVersion == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return equal;
|
||||||
}
|
}
|
||||||
|
@@ -35,6 +35,7 @@ namespace QmlDesigner {
|
|||||||
|
|
||||||
static const PropertyName customIdProperty = {("customId")};
|
static const PropertyName customIdProperty = {("customId")};
|
||||||
static const PropertyName annotationProperty = {("annotation")};
|
static const PropertyName annotationProperty = {("annotation")};
|
||||||
|
static const PropertyName globalAnnotationProperty = {("globalAnnotation")};
|
||||||
|
|
||||||
class Comment
|
class Comment
|
||||||
{
|
{
|
||||||
|
@@ -202,6 +202,11 @@ public:
|
|||||||
void setAnnotation(const Annotation &annotation);
|
void setAnnotation(const Annotation &annotation);
|
||||||
void removeAnnotation();
|
void removeAnnotation();
|
||||||
|
|
||||||
|
Annotation globalAnnotation() const;
|
||||||
|
bool hasGlobalAnnotation() const;
|
||||||
|
void setGlobalAnnotation(const Annotation &annotation);
|
||||||
|
void removeGlobalAnnotation();
|
||||||
|
|
||||||
qint32 internalId() const;
|
qint32 internalId() const;
|
||||||
|
|
||||||
void setNodeSource(const QString&);
|
void setNodeSource(const QString&);
|
||||||
|
@@ -182,8 +182,13 @@ public:
|
|||||||
const QList<ModelNode> wildcards() const;
|
const QList<ModelNode> wildcards() const;
|
||||||
const QList<ModelNode> decicions() const;
|
const QList<ModelNode> decicions() const;
|
||||||
QList<ModelNode> transitionsForTarget(const ModelNode &modelNode);
|
QList<ModelNode> transitionsForTarget(const ModelNode &modelNode);
|
||||||
|
QList<ModelNode> transitionsForSource(const ModelNode &modelNode);
|
||||||
void removeDanglingTransitions();
|
void removeDanglingTransitions();
|
||||||
void removeAllTransitions();
|
void removeAllTransitions();
|
||||||
|
void setStartFlowItem(const QmlFlowItemNode &flowItem);
|
||||||
|
ModelNode createTransition();
|
||||||
|
protected:
|
||||||
|
QList<ModelNode> transitionsForProperty(const PropertyName &propertyName, const ModelNode &modelNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -420,8 +420,7 @@ void SubComponentManager::parseQuick3DAssetDir(const QString &assetPath)
|
|||||||
itemLibraryEntry.addHints(hints);
|
itemLibraryEntry.addHints(hints);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!model()->metaInfo().itemLibraryInfo()->containsEntry(itemLibraryEntry))
|
model()->metaInfo().itemLibraryInfo()->addEntries({itemLibraryEntry}, true);
|
||||||
model()->metaInfo().itemLibraryInfo()->addEntries({itemLibraryEntry});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1150,6 +1150,35 @@ void ModelNode::removeAnnotation()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Annotation ModelNode::globalAnnotation() const
|
||||||
|
{
|
||||||
|
Annotation result;
|
||||||
|
ModelNode root = view()->rootModelNode();
|
||||||
|
|
||||||
|
if (hasGlobalAnnotation())
|
||||||
|
result.fromQString(root.auxiliaryData(globalAnnotationProperty).value<QString>());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ModelNode::hasGlobalAnnotation() const
|
||||||
|
{
|
||||||
|
return view()->rootModelNode().hasAuxiliaryData(globalAnnotationProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelNode::setGlobalAnnotation(const Annotation &annotation)
|
||||||
|
{
|
||||||
|
view()->rootModelNode().setAuxiliaryData(globalAnnotationProperty,
|
||||||
|
QVariant::fromValue<QString>(annotation.toQString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelNode::removeGlobalAnnotation()
|
||||||
|
{
|
||||||
|
if (hasGlobalAnnotation()) {
|
||||||
|
view()->rootModelNode().removeAuxiliaryData(globalAnnotationProperty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ModelNode::setScriptFunctions(const QStringList &scriptFunctionList)
|
void ModelNode::setScriptFunctions(const QStringList &scriptFunctionList)
|
||||||
{
|
{
|
||||||
model()->d->setScriptFunctions(internalNode(), scriptFunctionList);
|
model()->d->setScriptFunctions(internalNode(), scriptFunctionList);
|
||||||
|
@@ -664,9 +664,7 @@ QList<QmlFlowItemNode> QmlFlowViewNode::flowItems() const
|
|||||||
|
|
||||||
ModelNode QmlFlowViewNode::addTransition(const QmlFlowTargetNode &from, const QmlFlowTargetNode &to)
|
ModelNode QmlFlowViewNode::addTransition(const QmlFlowTargetNode &from, const QmlFlowTargetNode &to)
|
||||||
{
|
{
|
||||||
ModelNode transition = view()->createModelNode("FlowView.FlowTransition", 1, 0);
|
ModelNode transition = createTransition();
|
||||||
|
|
||||||
nodeListProperty("flowTransitions").reparentHere(transition);
|
|
||||||
|
|
||||||
QmlFlowTargetNode f = from;
|
QmlFlowTargetNode f = from;
|
||||||
QmlFlowTargetNode t = to;
|
QmlFlowTargetNode t = to;
|
||||||
@@ -684,8 +682,6 @@ const QList<ModelNode> QmlFlowViewNode::transitions() const
|
|||||||
return modelNode().nodeListProperty("flowTransitions").toModelNodeList();
|
return modelNode().nodeListProperty("flowTransitions").toModelNodeList();
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QList<ModelNode> QmlFlowViewNode::wildcards() const
|
const QList<ModelNode> QmlFlowViewNode::wildcards() const
|
||||||
@@ -706,13 +702,12 @@ const QList<ModelNode> QmlFlowViewNode::decicions() const
|
|||||||
|
|
||||||
QList<ModelNode> QmlFlowViewNode::transitionsForTarget(const ModelNode &modelNode)
|
QList<ModelNode> QmlFlowViewNode::transitionsForTarget(const ModelNode &modelNode)
|
||||||
{
|
{
|
||||||
QList<ModelNode> list;
|
return transitionsForProperty("to", modelNode);
|
||||||
for (const ModelNode &transition : transitions()) {
|
}
|
||||||
if (transition.hasBindingProperty("to")
|
|
||||||
&& transition.bindingProperty("to").resolveToModelNode() == modelNode)
|
QList<ModelNode> QmlFlowViewNode::transitionsForSource(const ModelNode &modelNode)
|
||||||
list.append(transition);
|
{
|
||||||
}
|
return transitionsForProperty("from", modelNode);
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlFlowViewNode::removeDanglingTransitions()
|
void QmlFlowViewNode::removeDanglingTransitions()
|
||||||
@@ -830,4 +825,41 @@ void QmlFlowViewNode::removeAllTransitions()
|
|||||||
removeProperty("flowTransitions");
|
removeProperty("flowTransitions");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QmlFlowViewNode::setStartFlowItem(const QmlFlowItemNode &flowItem)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(flowItem.isValid(), return);
|
||||||
|
QmlFlowItemNode item = flowItem;
|
||||||
|
|
||||||
|
ModelNode transition;
|
||||||
|
|
||||||
|
for (const ModelNode &node : transitionsForSource(modelNode()))
|
||||||
|
transition = node;
|
||||||
|
if (!transition.isValid())
|
||||||
|
transition = createTransition();
|
||||||
|
|
||||||
|
transition.bindingProperty("from").setExpression(modelNode().validId());
|
||||||
|
transition.bindingProperty("to").setExpression(item.validId());
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelNode QmlFlowViewNode::createTransition()
|
||||||
|
{
|
||||||
|
ModelNode transition = view()->createModelNode("FlowView.FlowTransition", 1, 0);
|
||||||
|
nodeListProperty("flowTransitions").reparentHere(transition);
|
||||||
|
|
||||||
|
return transition;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<ModelNode> QmlFlowViewNode::transitionsForProperty(const PropertyName &propertyName,
|
||||||
|
const ModelNode &modelNode)
|
||||||
|
{
|
||||||
|
QList<ModelNode> list;
|
||||||
|
for (const ModelNode &transition : transitions()) {
|
||||||
|
if (transition.hasBindingProperty(propertyName)
|
||||||
|
&& transition.bindingProperty(propertyName).resolveToModelNode() == modelNode)
|
||||||
|
list.append(transition);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} //QmlDesigner
|
} //QmlDesigner
|
||||||
|
@@ -91,7 +91,12 @@ QStringList globalQtEnums()
|
|||||||
"Horizontal", "Vertical", "AlignVCenter", "AlignLeft", "LeftToRight", "RightToLeft",
|
"Horizontal", "Vertical", "AlignVCenter", "AlignLeft", "LeftToRight", "RightToLeft",
|
||||||
"AlignHCenter", "AlignRight", "AlignBottom", "AlignBaseline", "AlignTop", "BottomLeft",
|
"AlignHCenter", "AlignRight", "AlignBottom", "AlignBaseline", "AlignTop", "BottomLeft",
|
||||||
"LeftEdge", "RightEdge", "BottomEdge", "TopEdge", "TabFocus", "ClickFocus", "StrongFocus",
|
"LeftEdge", "RightEdge", "BottomEdge", "TopEdge", "TabFocus", "ClickFocus", "StrongFocus",
|
||||||
"WheelFocus", "NoFocus"
|
"WheelFocus", "NoFocus", "ArrowCursor", "UpArrowCursor", "CrossCursor", "WaitCursor",
|
||||||
|
"IBeamCursor", "SizeVerCursor", "SizeHorCursor", "SizeBDiagCursor", "SizeFDiagCursor",
|
||||||
|
"SizeAllCursor", "BlankCursor", "SplitVCursor", "SplitHCursor", "PointingHandCursor",
|
||||||
|
"ForbiddenCursor", "WhatsThisCursor", "BusyCursor", "OpenHandCursor", "ClosedHandCursor",
|
||||||
|
"DragCopyCursor", "DragMoveCursor", "DragLinkCursor", "TopToBottom",
|
||||||
|
"LeftButton", "RightButton", "MiddleButton", "BackButton", "ForwardButton", "AllButtons"
|
||||||
};
|
};
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
@@ -101,7 +106,7 @@ QStringList knownEnumScopes()
|
|||||||
{
|
{
|
||||||
static const QStringList list = {
|
static const QStringList list = {
|
||||||
"TextInput", "TextEdit", "Material", "Universal", "Font", "Shape", "ShapePath",
|
"TextInput", "TextEdit", "Material", "Universal", "Font", "Shape", "ShapePath",
|
||||||
"AbstractButton", "Text", "ShaderEffectSource"
|
"AbstractButton", "Text", "ShaderEffectSource", "Grid"
|
||||||
};
|
};
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
@@ -60,6 +60,7 @@
|
|||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/stylehelper.h>
|
||||||
|
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QToolBar>
|
#include <QToolBar>
|
||||||
@@ -70,6 +71,7 @@
|
|||||||
|
|
||||||
#include <advanceddockingsystem/dockareawidget.h>
|
#include <advanceddockingsystem/dockareawidget.h>
|
||||||
#include <advanceddockingsystem/docksplitter.h>
|
#include <advanceddockingsystem/docksplitter.h>
|
||||||
|
#include <advanceddockingsystem/iconprovider.h>
|
||||||
|
|
||||||
using Core::MiniSplitter;
|
using Core::MiniSplitter;
|
||||||
using Core::IEditor;
|
using Core::IEditor;
|
||||||
@@ -227,6 +229,26 @@ void DesignModeWidget::setup()
|
|||||||
QString sheet = QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/dockwidgets.css"));
|
QString sheet = QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/dockwidgets.css"));
|
||||||
m_dockManager->setStyleSheet(Theme::replaceCssColors(sheet));
|
m_dockManager->setStyleSheet(Theme::replaceCssColors(sheet));
|
||||||
|
|
||||||
|
// Setup icons
|
||||||
|
QColor buttonColor(Theme::getColor(Theme::QmlDesigner_TabLight)); // TODO Use correct color roles
|
||||||
|
QColor tabColor(Theme::getColor(Theme::QmlDesigner_TabDark));
|
||||||
|
|
||||||
|
const QString closeUnicode = Theme::getIconUnicode(Theme::Icon::adsClose);
|
||||||
|
const QString menuUnicode = Theme::getIconUnicode(Theme::Icon::adsDropDown);
|
||||||
|
const QString undockUnicode = Theme::getIconUnicode(Theme::Icon::adsDetach);
|
||||||
|
|
||||||
|
const QString fontName = "qtds_propertyIconFont.ttf";
|
||||||
|
const QIcon tabsCloseIcon = Utils::StyleHelper::getIconFromIconFont(fontName, closeUnicode, 28, 28, tabColor);
|
||||||
|
const QIcon menuIcon = Utils::StyleHelper::getIconFromIconFont(fontName, menuUnicode, 28, 28, buttonColor);
|
||||||
|
const QIcon undockIcon = Utils::StyleHelper::getIconFromIconFont(fontName, undockUnicode, 28, 28, buttonColor);
|
||||||
|
const QIcon closeIcon = Utils::StyleHelper::getIconFromIconFont(fontName, closeUnicode, 28, 28, buttonColor);
|
||||||
|
|
||||||
|
m_dockManager->iconProvider().registerCustomIcon(ADS::TabCloseIcon, tabsCloseIcon);
|
||||||
|
m_dockManager->iconProvider().registerCustomIcon(ADS::DockAreaMenuIcon, menuIcon);
|
||||||
|
m_dockManager->iconProvider().registerCustomIcon(ADS::DockAreaUndockIcon, undockIcon);
|
||||||
|
m_dockManager->iconProvider().registerCustomIcon(ADS::DockAreaCloseIcon, closeIcon);
|
||||||
|
m_dockManager->iconProvider().registerCustomIcon(ADS::FloatingWidgetCloseIcon, closeIcon);
|
||||||
|
|
||||||
// Setup Actions and Menus
|
// Setup Actions and Menus
|
||||||
Core::ActionContainer *mview = Core::ActionManager::actionContainer(Core::Constants::M_VIEW);
|
Core::ActionContainer *mview = Core::ActionManager::actionContainer(Core::Constants::M_VIEW);
|
||||||
// Window > Views
|
// Window > Views
|
||||||
@@ -409,6 +431,19 @@ void DesignModeWidget::setup()
|
|||||||
m_dockManager->openWorkspace(workspaceComboBox->currentText());
|
m_dockManager->openWorkspace(workspaceComboBox->currentText());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const QIcon gaIcon = Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||||
|
Theme::getIconUnicode(Theme::Icon::annotationBubble), 36, 36);
|
||||||
|
toolBar->addAction(gaIcon, tr("Edit global annotation for current file."), [&](){
|
||||||
|
ModelNode node = currentDesignDocument()->rewriterView()->rootModelNode();
|
||||||
|
|
||||||
|
if (node.isValid()) {
|
||||||
|
m_globalAnnotationEditor.setModelNode(node);
|
||||||
|
m_globalAnnotationEditor.showWidget();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
viewManager().enableWidgets();
|
viewManager().enableWidgets();
|
||||||
readSettings();
|
readSettings();
|
||||||
show();
|
show();
|
||||||
|
@@ -36,6 +36,7 @@
|
|||||||
#include <QScopedPointer>
|
#include <QScopedPointer>
|
||||||
|
|
||||||
#include <advanceddockingsystem/dockmanager.h>
|
#include <advanceddockingsystem/dockmanager.h>
|
||||||
|
#include <annotationeditor/globalannotationeditor.h>
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class SideBar;
|
class SideBar;
|
||||||
@@ -120,6 +121,7 @@ private: // variables
|
|||||||
|
|
||||||
ADS::DockManager *m_dockManager = nullptr;
|
ADS::DockManager *m_dockManager = nullptr;
|
||||||
ADS::DockWidget *m_outputPaneDockWidget = nullptr;
|
ADS::DockWidget *m_outputPaneDockWidget = nullptr;
|
||||||
|
GlobalAnnotationEditor m_globalAnnotationEditor;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -38,6 +38,7 @@
|
|||||||
#include <sourcetool/sourcetool.h>
|
#include <sourcetool/sourcetool.h>
|
||||||
#include <colortool/colortool.h>
|
#include <colortool/colortool.h>
|
||||||
#include <annotationeditor/annotationtool.h>
|
#include <annotationeditor/annotationtool.h>
|
||||||
|
#include <formeditor/transitiontool.h>
|
||||||
#include <texttool/texttool.h>
|
#include <texttool/texttool.h>
|
||||||
#include <timelineeditor/timelineview.h>
|
#include <timelineeditor/timelineview.h>
|
||||||
#include <pathtool/pathtool.h>
|
#include <pathtool/pathtool.h>
|
||||||
@@ -216,6 +217,11 @@ bool QmlDesignerPlugin::initialize(const QStringList & /*arguments*/, QString *e
|
|||||||
if (DesignerSettings::getValue(DesignerSettingsKey::STANDALONE_MODE).toBool())
|
if (DesignerSettings::getValue(DesignerSettingsKey::STANDALONE_MODE).toBool())
|
||||||
GenerateResource::generateMenuEntry();
|
GenerateResource::generateMenuEntry();
|
||||||
|
|
||||||
|
QString fontPath = Core::ICore::resourcePath() +
|
||||||
|
QStringLiteral("/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf");
|
||||||
|
if (QFontDatabase::addApplicationFont(fontPath) < 0)
|
||||||
|
qCWarning(qmldesignerLog) << "Could not add font " << fontPath << "to font database";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,6 +248,7 @@ bool QmlDesignerPlugin::delayedInitialize()
|
|||||||
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::AnnotationTool);
|
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::AnnotationTool);
|
||||||
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::TextTool);
|
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::TextTool);
|
||||||
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::PathTool);
|
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::PathTool);
|
||||||
|
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::TransitionTool);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -31,6 +31,7 @@ include(components/connectioneditor/connectioneditor.pri)
|
|||||||
include(components/curveeditor/curveeditor.pri)
|
include(components/curveeditor/curveeditor.pri)
|
||||||
include(components/bindingeditor/bindingeditor.pri)
|
include(components/bindingeditor/bindingeditor.pri)
|
||||||
include(components/annotationeditor/annotationeditor.pri)
|
include(components/annotationeditor/annotationeditor.pri)
|
||||||
|
include(components/richtexteditor/richtexteditor.pri)
|
||||||
|
|
||||||
|
|
||||||
BUILD_PUPPET_IN_CREATOR_BINPATH = $$(BUILD_PUPPET_IN_CREATOR_BINPATH)
|
BUILD_PUPPET_IN_CREATOR_BINPATH = $$(BUILD_PUPPET_IN_CREATOR_BINPATH)
|
||||||
|
@@ -530,6 +530,8 @@ Project {
|
|||||||
"formeditor/toolbox.h",
|
"formeditor/toolbox.h",
|
||||||
"formeditor/formeditortoolbutton.cpp",
|
"formeditor/formeditortoolbutton.cpp",
|
||||||
"formeditor/formeditortoolbutton.h",
|
"formeditor/formeditortoolbutton.h",
|
||||||
|
"formeditor/transitiontool.cpp",
|
||||||
|
"formeditor/transitiontool.h",
|
||||||
"importmanager/importlabel.cpp",
|
"importmanager/importlabel.cpp",
|
||||||
"importmanager/importlabel.h",
|
"importmanager/importlabel.h",
|
||||||
"importmanager/importmanagercombobox.cpp",
|
"importmanager/importmanagercombobox.cpp",
|
||||||
@@ -654,6 +656,8 @@ Project {
|
|||||||
"annotationeditor/annotationcommenttab.ui",
|
"annotationeditor/annotationcommenttab.ui",
|
||||||
"annotationeditor/annotationeditor.cpp",
|
"annotationeditor/annotationeditor.cpp",
|
||||||
"annotationeditor/annotationeditor.h",
|
"annotationeditor/annotationeditor.h",
|
||||||
|
"annotationeditor/globalannotationeditor.cpp",
|
||||||
|
"annotationeditor/globalannotationeditor.h",
|
||||||
"annotationeditor/annotationeditordialog.cpp",
|
"annotationeditor/annotationeditordialog.cpp",
|
||||||
"annotationeditor/annotationeditordialog.h",
|
"annotationeditor/annotationeditordialog.h",
|
||||||
"annotationeditor/annotationeditordialog.ui",
|
"annotationeditor/annotationeditordialog.ui",
|
||||||
@@ -746,6 +750,12 @@ Project {
|
|||||||
"pathtool/pathtool.h",
|
"pathtool/pathtool.h",
|
||||||
"pathtool/pathtoolview.cpp",
|
"pathtool/pathtoolview.cpp",
|
||||||
"pathtool/pathtoolview.h",
|
"pathtool/pathtoolview.h",
|
||||||
|
"richtexteditor/hyperlinkdialog.cpp",
|
||||||
|
"richtexteditor/hyperlinkdialog.h",
|
||||||
|
"richtexteditor/hyperlinkdialog.ui",
|
||||||
|
"richtexteditor/richtexteditor.cpp",
|
||||||
|
"richtexteditor/richtexteditor.h",
|
||||||
|
"richtexteditor/richtexteditor.ui",
|
||||||
"sourcetool/sourcetool.cpp",
|
"sourcetool/sourcetool.cpp",
|
||||||
"sourcetool/sourcetool.h",
|
"sourcetool/sourcetool.h",
|
||||||
"texttool/textedititem.cpp",
|
"texttool/textedititem.cpp",
|
||||||
|
@@ -164,6 +164,14 @@ add_qtc_test(unittest GTEST
|
|||||||
unittest-utility-functions.h
|
unittest-utility-functions.h
|
||||||
usedmacrofilter-test.cpp
|
usedmacrofilter-test.cpp
|
||||||
utf8-test.cpp
|
utf8-test.cpp
|
||||||
|
sqlitecolumn-test.cpp
|
||||||
|
sqlitedatabasebackend-test.cpp
|
||||||
|
sqlitedatabase-test.cpp
|
||||||
|
sqlitestatement-test.cpp
|
||||||
|
sqlitetable-test.cpp
|
||||||
|
sqlstatementbuilder-test.cpp
|
||||||
|
createtablesqlstatementbuilder-test.cpp
|
||||||
|
sqlitevalue-test.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# Do not work on the source directory data
|
# Do not work on the source directory data
|
||||||
@@ -219,7 +227,6 @@ if (TARGET libclang)
|
|||||||
codecompleter-test.cpp
|
codecompleter-test.cpp
|
||||||
codecompletionsextractor-test.cpp
|
codecompletionsextractor-test.cpp
|
||||||
completionchunkstotextconverter-test.cpp
|
completionchunkstotextconverter-test.cpp
|
||||||
createtablesqlstatementbuilder-test.cpp
|
|
||||||
cursor-test.cpp
|
cursor-test.cpp
|
||||||
diagnosticset-test.cpp
|
diagnosticset-test.cpp
|
||||||
diagnostic-test.cpp
|
diagnostic-test.cpp
|
||||||
@@ -228,12 +235,6 @@ if (TARGET libclang)
|
|||||||
skippedsourceranges-test.cpp
|
skippedsourceranges-test.cpp
|
||||||
sourcelocation-test.cpp
|
sourcelocation-test.cpp
|
||||||
sourcerange-test.cpp
|
sourcerange-test.cpp
|
||||||
sqlitecolumn-test.cpp
|
|
||||||
sqlitedatabasebackend-test.cpp
|
|
||||||
sqlitedatabase-test.cpp
|
|
||||||
sqlitestatement-test.cpp
|
|
||||||
sqlitetable-test.cpp
|
|
||||||
sqlstatementbuilder-test.cpp
|
|
||||||
token-test.cpp
|
token-test.cpp
|
||||||
translationunitupdater-test.cpp
|
translationunitupdater-test.cpp
|
||||||
unsavedfiles-test.cpp
|
unsavedfiles-test.cpp
|
||||||
|
@@ -14,11 +14,11 @@ include($$PWD/../../../src/tools/clangpchmanagerbackend/source/clangpchmanagerba
|
|||||||
include($$PWD/../../../src/plugins/clangrefactoring/clangrefactoring-source.pri)
|
include($$PWD/../../../src/plugins/clangrefactoring/clangrefactoring-source.pri)
|
||||||
include($$PWD/../../../src/plugins/clangpchmanager/clangpchmanager-source.pri)
|
include($$PWD/../../../src/plugins/clangpchmanager/clangpchmanager-source.pri)
|
||||||
include($$PWD/../../../src/plugins/cpptools/cpptoolsunittestfiles.pri)
|
include($$PWD/../../../src/plugins/cpptools/cpptoolsunittestfiles.pri)
|
||||||
include($$PWD/../../../src/plugins/clangtools/clangtoolsunittestfiles.pri)
|
|
||||||
include($$PWD/../../../src/plugins/debugger/debuggerunittestfiles.pri)
|
include($$PWD/../../../src/plugins/debugger/debuggerunittestfiles.pri)
|
||||||
include($$PWD/../../../src/plugins/compilationdatabaseprojectmanager/compilationdatabaseunittestfiles.pri)
|
include($$PWD/../../../src/plugins/compilationdatabaseprojectmanager/compilationdatabaseunittestfiles.pri)
|
||||||
include(cplusplus.pri)
|
include(cplusplus.pri)
|
||||||
!isEmpty(LLVM_VERSION) {
|
!isEmpty(LLVM_VERSION) {
|
||||||
|
include($$PWD/../../../src/plugins/clangtools/clangtoolsunittestfiles.pri)
|
||||||
include($$PWD/../../../src/shared/clang/clang_defines.pri)
|
include($$PWD/../../../src/shared/clang/clang_defines.pri)
|
||||||
include($$PWD/../../../src/tools/clangbackend/source/clangbackendclangipc-source.pri)
|
include($$PWD/../../../src/tools/clangbackend/source/clangbackendclangipc-source.pri)
|
||||||
include($$PWD/../../../src/plugins/clangcodemodel/clangcodemodelunittestfiles.pri)
|
include($$PWD/../../../src/plugins/clangcodemodel/clangcodemodelunittestfiles.pri)
|
||||||
|
@@ -37,6 +37,7 @@
|
|||||||
#include <clangcodemodelservermessages.h>
|
#include <clangcodemodelservermessages.h>
|
||||||
#include <clangpathwatcher.h>
|
#include <clangpathwatcher.h>
|
||||||
#include <clangrefactoringmessages.h>
|
#include <clangrefactoringmessages.h>
|
||||||
|
#include <clangtools/clangtoolsdiagnostic.h>
|
||||||
#include <coreplugin/find/searchresultitem.h>
|
#include <coreplugin/find/searchresultitem.h>
|
||||||
#include <coreplugin/locator/ilocatorfilter.h>
|
#include <coreplugin/locator/ilocatorfilter.h>
|
||||||
#include <cpptools/usages.h>
|
#include <cpptools/usages.h>
|
||||||
@@ -57,6 +58,7 @@
|
|||||||
#include <sourcedependency.h>
|
#include <sourcedependency.h>
|
||||||
#include <sourcelocationentry.h>
|
#include <sourcelocationentry.h>
|
||||||
#include <sourcelocationscontainer.h>
|
#include <sourcelocationscontainer.h>
|
||||||
|
#include <sqlitevalue.h>
|
||||||
#include <symbol.h>
|
#include <symbol.h>
|
||||||
#include <symbolentry.h>
|
#include <symbolentry.h>
|
||||||
#include <symbolindexertaskqueue.h>
|
#include <symbolindexertaskqueue.h>
|
||||||
@@ -64,12 +66,6 @@
|
|||||||
#include <tooltipinfo.h>
|
#include <tooltipinfo.h>
|
||||||
#include <usedmacro.h>
|
#include <usedmacro.h>
|
||||||
#include <utils/link.h>
|
#include <utils/link.h>
|
||||||
#include <cpptools/usages.h>
|
|
||||||
#include <projectexplorer/projectmacro.h>
|
|
||||||
#include <projectexplorer/headerpath.h>
|
|
||||||
#include <coreplugin/find/searchresultitem.h>
|
|
||||||
#include <coreplugin/locator/ilocatorfilter.h>
|
|
||||||
#include <clangtools/clangtoolsdiagnostic.h>
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
ClangBackEnd::FilePathCaching *filePathCache = nullptr;
|
ClangBackEnd::FilePathCaching *filePathCache = nullptr;
|
||||||
@@ -306,6 +302,27 @@ void PrintTo(const Utils::PathString &text, ::std::ostream *os)
|
|||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
|
|
||||||
|
namespace Sqlite {
|
||||||
|
std::ostream &operator<<(std::ostream &out, const Value &value)
|
||||||
|
{
|
||||||
|
out << "(";
|
||||||
|
|
||||||
|
switch (value.type()) {
|
||||||
|
case Sqlite::ValueType::Integer:
|
||||||
|
out << value.toInteger();
|
||||||
|
break;
|
||||||
|
case Sqlite::ValueType::Float:
|
||||||
|
out << value.toFloat();
|
||||||
|
break;
|
||||||
|
case Sqlite::ValueType::String:
|
||||||
|
out << "\"" << value.toStringView() << "\"";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out << ")";
|
||||||
|
}
|
||||||
|
} // namespace Sqlite
|
||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &out, const FilePathId &id)
|
std::ostream &operator<<(std::ostream &out, const FilePathId &id)
|
||||||
|
@@ -64,6 +64,12 @@ void PrintTo(const TextRange &range, ::std::ostream *os);
|
|||||||
} // namespace TextPosition
|
} // namespace TextPosition
|
||||||
} // namespace TextPosition
|
} // namespace TextPosition
|
||||||
|
|
||||||
|
namespace Sqlite {
|
||||||
|
class Value;
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const Value &value);
|
||||||
|
} // namespace Sqlite
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
|
|
||||||
enum class MacroType;
|
enum class MacroType;
|
||||||
|
@@ -40,11 +40,12 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using Sqlite::JournalMode;
|
|
||||||
using Sqlite::Exception;
|
|
||||||
using Sqlite::Database;
|
using Sqlite::Database;
|
||||||
|
using Sqlite::Exception;
|
||||||
|
using Sqlite::JournalMode;
|
||||||
using Sqlite::ReadStatement;
|
using Sqlite::ReadStatement;
|
||||||
using Sqlite::ReadWriteStatement;
|
using Sqlite::ReadWriteStatement;
|
||||||
|
using Sqlite::Value;
|
||||||
using Sqlite::WriteStatement;
|
using Sqlite::WriteStatement;
|
||||||
|
|
||||||
MATCHER_P3(HasValues, value1, value2, rowid,
|
MATCHER_P3(HasValues, value1, value2, rowid,
|
||||||
@@ -125,7 +126,7 @@ TEST_F(SqliteStatement, CountRows)
|
|||||||
|
|
||||||
TEST_F(SqliteStatement, Value)
|
TEST_F(SqliteStatement, Value)
|
||||||
{
|
{
|
||||||
SqliteTestStatement statement("SELECT name, number FROM test ORDER BY name", database);
|
SqliteTestStatement statement("SELECT name, number, value FROM test ORDER BY name", database);
|
||||||
statement.next();
|
statement.next();
|
||||||
|
|
||||||
statement.next();
|
statement.next();
|
||||||
@@ -142,6 +143,9 @@ TEST_F(SqliteStatement, Value)
|
|||||||
ASSERT_THAT(statement.fetchValue<Utils::SmallString>(1), "23.3");
|
ASSERT_THAT(statement.fetchValue<Utils::SmallString>(1), "23.3");
|
||||||
ASSERT_THAT(statement.fetchValue<Utils::PathString>(1), "23.3");
|
ASSERT_THAT(statement.fetchValue<Utils::PathString>(1), "23.3");
|
||||||
ASSERT_THAT(statement.fetchSmallStringViewValue(1), "23.3");
|
ASSERT_THAT(statement.fetchSmallStringViewValue(1), "23.3");
|
||||||
|
ASSERT_THAT(statement.fetchValueView(0), Eq("foo"));
|
||||||
|
ASSERT_THAT(statement.fetchValueView(1), Eq(23.3));
|
||||||
|
ASSERT_THAT(statement.fetchValueView(2), Eq(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SqliteStatement, ThrowNoValuesToFetchForNotSteppedStatement)
|
TEST_F(SqliteStatement, ThrowNoValuesToFetchForNotSteppedStatement)
|
||||||
@@ -175,14 +179,14 @@ TEST_F(SqliteStatement, ThrowInvalidColumnFetchedForNotExistingColumn)
|
|||||||
ASSERT_THROW(statement.fetchValue<int>(2), Sqlite::InvalidColumnFetched);
|
ASSERT_THROW(statement.fetchValue<int>(2), Sqlite::InvalidColumnFetched);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SqliteStatement, ToIntergerValue)
|
TEST_F(SqliteStatement, ToIntegerValue)
|
||||||
{
|
{
|
||||||
auto value = ReadStatement::toValue<int>("SELECT number FROM test WHERE name='foo'", database);
|
auto value = ReadStatement::toValue<int>("SELECT number FROM test WHERE name='foo'", database);
|
||||||
|
|
||||||
ASSERT_THAT(value, 23);
|
ASSERT_THAT(value, 23);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SqliteStatement, ToLongIntergerValue)
|
TEST_F(SqliteStatement, ToLongIntegerValue)
|
||||||
{
|
{
|
||||||
ASSERT_THAT(ReadStatement::toValue<qint64>("SELECT number FROM test WHERE name='foo'", database), Eq(23));
|
ASSERT_THAT(ReadStatement::toValue<qint64>("SELECT number FROM test WHERE name='foo'", database), Eq(23));
|
||||||
}
|
}
|
||||||
@@ -319,6 +323,15 @@ TEST_F(SqliteStatement, WriteValues)
|
|||||||
ASSERT_THAT(statement, HasValues("see", "7.23", 1));
|
ASSERT_THAT(statement, HasValues("see", "7.23", 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SqliteStatement, WriteSqliteValues)
|
||||||
|
{
|
||||||
|
WriteStatement statement("UPDATE test SET name=?, number=? WHERE rowid=?", database);
|
||||||
|
|
||||||
|
statement.write(Value{"see"}, Value{7.23}, Value{1});
|
||||||
|
|
||||||
|
ASSERT_THAT(statement, HasValues("see", "7.23", 1));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(SqliteStatement, BindNamedValues)
|
TEST_F(SqliteStatement, BindNamedValues)
|
||||||
{
|
{
|
||||||
SqliteTestStatement statement("UPDATE test SET name=@name, number=@number WHERE rowid=@id", database);
|
SqliteTestStatement statement("UPDATE test SET name=@name, number=@number WHERE rowid=@id", database);
|
||||||
@@ -375,6 +388,31 @@ TEST_F(SqliteStatement, GetSingleValuesWithoutArguments)
|
|||||||
ASSERT_THAT(values, ElementsAre("bar", "foo", "poo"));
|
ASSERT_THAT(values, ElementsAre("bar", "foo", "poo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FooValue
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FooValue(Sqlite::ValueView value)
|
||||||
|
: value(value)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Sqlite::Value value;
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
friend bool operator==(const FooValue &value, const Type &other)
|
||||||
|
{
|
||||||
|
return value.value == other;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(SqliteStatement, GetSingleSqliteValuesWithoutArguments)
|
||||||
|
{
|
||||||
|
ReadStatement statement("SELECT number FROM test", database);
|
||||||
|
|
||||||
|
std::vector<FooValue> values = statement.values<FooValue>(3);
|
||||||
|
|
||||||
|
ASSERT_THAT(values, ElementsAre(Eq("blah"), Eq(23.3), Eq(40)));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(SqliteStatement, GetStructValuesWithoutArguments)
|
TEST_F(SqliteStatement, GetStructValuesWithoutArguments)
|
||||||
{
|
{
|
||||||
ReadStatement statement("SELECT name, number, value FROM test", database);
|
ReadStatement statement("SELECT name, number, value FROM test", database);
|
||||||
|
348
tests/unit/unittest/sqlitevalue-test.cpp
Normal file
348
tests/unit/unittest/sqlitevalue-test.cpp
Normal file
@@ -0,0 +1,348 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 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 "googletest.h"
|
||||||
|
|
||||||
|
#include <sqlitevalue.h>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
TEST(SqliteValue, ConstructLongLong)
|
||||||
|
{
|
||||||
|
Sqlite::Value value{1LL};
|
||||||
|
|
||||||
|
ASSERT_THAT(value.toInteger(), Eq(1LL));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, Construct)
|
||||||
|
{
|
||||||
|
Sqlite::Value value{1};
|
||||||
|
|
||||||
|
ASSERT_THAT(value.toInteger(), Eq(1LL));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, ConstructFloatingPoint)
|
||||||
|
{
|
||||||
|
Sqlite::Value value{1.1};
|
||||||
|
|
||||||
|
ASSERT_THAT(value.toFloat(), Eq(1.1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, ConstructStringFromCString)
|
||||||
|
{
|
||||||
|
Sqlite::Value value{"foo"};
|
||||||
|
|
||||||
|
ASSERT_THAT(value.toStringView(), Eq("foo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, ConstructStringFromUtilsString)
|
||||||
|
{
|
||||||
|
Sqlite::Value value{Utils::SmallString{"foo"}};
|
||||||
|
|
||||||
|
ASSERT_THAT(value.toStringView(), Eq("foo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, ConstructStringFromQString)
|
||||||
|
{
|
||||||
|
Sqlite::Value value{QString{"foo"}};
|
||||||
|
|
||||||
|
ASSERT_THAT(value.toStringView(), Eq("foo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, ConstructStringFromIntQVariant)
|
||||||
|
{
|
||||||
|
QVariant variant{1};
|
||||||
|
|
||||||
|
Sqlite::Value value{variant};
|
||||||
|
|
||||||
|
ASSERT_THAT(value.toInteger(), Eq(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, ConstructStringFromLongLongQVariant)
|
||||||
|
{
|
||||||
|
QVariant variant{1LL};
|
||||||
|
|
||||||
|
Sqlite::Value value{variant};
|
||||||
|
|
||||||
|
ASSERT_THAT(value.toInteger(), Eq(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, ConstructStringFromUintQVariant)
|
||||||
|
{
|
||||||
|
QVariant variant{1u};
|
||||||
|
|
||||||
|
Sqlite::Value value{variant};
|
||||||
|
|
||||||
|
ASSERT_THAT(value.toInteger(), Eq(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, ConstructStringFromFloatQVariant)
|
||||||
|
{
|
||||||
|
QVariant variant{1.};
|
||||||
|
|
||||||
|
Sqlite::Value value{variant};
|
||||||
|
|
||||||
|
ASSERT_THAT(value.toFloat(), Eq(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, ConstructStringFromStringQVariant)
|
||||||
|
{
|
||||||
|
QVariant variant{QString{"foo"}};
|
||||||
|
|
||||||
|
Sqlite::Value value{variant};
|
||||||
|
|
||||||
|
ASSERT_THAT(value.toStringView(), Eq("foo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, ConvertToStringQVariant)
|
||||||
|
{
|
||||||
|
Sqlite::Value value{"foo"};
|
||||||
|
|
||||||
|
auto variant = QVariant{value};
|
||||||
|
|
||||||
|
ASSERT_THAT(variant, Eq("foo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, ConvertToIntegerQVariant)
|
||||||
|
{
|
||||||
|
Sqlite::Value value{1};
|
||||||
|
|
||||||
|
auto variant = QVariant{value};
|
||||||
|
|
||||||
|
ASSERT_THAT(variant, Eq(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, ConvertToFloatQVariant)
|
||||||
|
{
|
||||||
|
Sqlite::Value value{1.1};
|
||||||
|
|
||||||
|
auto variant = QVariant{value};
|
||||||
|
|
||||||
|
ASSERT_THAT(variant, Eq(1.1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, IntegerEquals)
|
||||||
|
{
|
||||||
|
bool isEqual = Sqlite::Value{1} == 1LL;
|
||||||
|
|
||||||
|
ASSERT_TRUE(isEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, IntegerEqualsInverse)
|
||||||
|
{
|
||||||
|
bool isEqual = 1LL == Sqlite::Value{1};
|
||||||
|
|
||||||
|
ASSERT_TRUE(isEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, FloatEquals)
|
||||||
|
{
|
||||||
|
bool isEqual = Sqlite::Value{1.0} == 1.;
|
||||||
|
|
||||||
|
ASSERT_TRUE(isEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, FloatEqualsInverse)
|
||||||
|
{
|
||||||
|
bool isEqual = 1. == Sqlite::Value{1.0};
|
||||||
|
|
||||||
|
ASSERT_TRUE(isEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, StringEquals)
|
||||||
|
{
|
||||||
|
bool isEqual = Sqlite::Value{"foo"} == "foo";
|
||||||
|
|
||||||
|
ASSERT_TRUE(isEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, StringEqualsInverse)
|
||||||
|
{
|
||||||
|
bool isEqual = "foo" == Sqlite::Value{"foo"};
|
||||||
|
|
||||||
|
ASSERT_TRUE(isEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, IntegerAndFloatAreNotEquals)
|
||||||
|
{
|
||||||
|
bool isEqual = Sqlite::Value{1} == 1.;
|
||||||
|
|
||||||
|
ASSERT_FALSE(isEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, IntegerValuesAreEquals)
|
||||||
|
{
|
||||||
|
bool isEqual = Sqlite::Value{1} == Sqlite::Value{1};
|
||||||
|
|
||||||
|
ASSERT_TRUE(isEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, IntegerAndFloatValuesAreNotEquals)
|
||||||
|
{
|
||||||
|
bool isEqual = Sqlite::Value{1} == Sqlite::Value{1.};
|
||||||
|
|
||||||
|
ASSERT_FALSE(isEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, StringAndQStringAreEquals)
|
||||||
|
{
|
||||||
|
bool isEqual = Sqlite::Value{"foo"} == QString{"foo"};
|
||||||
|
|
||||||
|
ASSERT_TRUE(isEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, IntegerAndFloatValuesAreUnequal)
|
||||||
|
{
|
||||||
|
bool isUnequal = Sqlite::Value{1} != Sqlite::Value{1.0};
|
||||||
|
|
||||||
|
ASSERT_TRUE(isUnequal);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, IntegerAndFloatAreUnequal)
|
||||||
|
{
|
||||||
|
bool isUnequal = Sqlite::Value{1} != 1.0;
|
||||||
|
|
||||||
|
ASSERT_TRUE(isUnequal);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, IntegerAndFloatAreUnequalInverse)
|
||||||
|
{
|
||||||
|
bool isUnequal = 1.0 != Sqlite::Value{1};
|
||||||
|
|
||||||
|
ASSERT_TRUE(isUnequal);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, IntegersAreUnequal)
|
||||||
|
{
|
||||||
|
bool isUnequal = Sqlite::Value{1} != 2;
|
||||||
|
|
||||||
|
ASSERT_TRUE(isUnequal);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, IntegersAreUnequalInverse)
|
||||||
|
{
|
||||||
|
bool isUnequal = 2 != Sqlite::Value{1};
|
||||||
|
|
||||||
|
ASSERT_TRUE(isUnequal);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, IntegerType)
|
||||||
|
{
|
||||||
|
auto type = Sqlite::Value{1}.type();
|
||||||
|
|
||||||
|
ASSERT_THAT(type, Sqlite::ValueType::Integer);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, FloatType)
|
||||||
|
{
|
||||||
|
auto type = Sqlite::Value{1.}.type();
|
||||||
|
|
||||||
|
ASSERT_THAT(type, Sqlite::ValueType::Float);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, StringType)
|
||||||
|
{
|
||||||
|
auto type = Sqlite::Value{"foo"}.type();
|
||||||
|
|
||||||
|
ASSERT_THAT(type, Sqlite::ValueType::String);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, StringValueAndValueViewEquals)
|
||||||
|
{
|
||||||
|
bool isEqual = Sqlite::ValueView::create("foo") == Sqlite::Value{"foo"};
|
||||||
|
|
||||||
|
ASSERT_TRUE(isEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, StringValueAndValueViewEqualsInverse)
|
||||||
|
{
|
||||||
|
bool isEqual = Sqlite::Value{"foo"} == Sqlite::ValueView::create("foo");
|
||||||
|
|
||||||
|
ASSERT_TRUE(isEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, IntegerValueAndValueViewEquals)
|
||||||
|
{
|
||||||
|
bool isEqual = Sqlite::ValueView::create(1) == Sqlite::Value{1};
|
||||||
|
|
||||||
|
ASSERT_TRUE(isEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, IntegerValueAndValueViewEqualsInverse)
|
||||||
|
{
|
||||||
|
bool isEqual = Sqlite::Value{2} == Sqlite::ValueView::create(2);
|
||||||
|
|
||||||
|
ASSERT_TRUE(isEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, FloatValueAndValueViewEquals)
|
||||||
|
{
|
||||||
|
bool isEqual = Sqlite::ValueView::create(1.1) == Sqlite::Value{1.1};
|
||||||
|
|
||||||
|
ASSERT_TRUE(isEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, FloatValueAndValueViewEqualsInverse)
|
||||||
|
{
|
||||||
|
bool isEqual = Sqlite::Value{1.1} == Sqlite::ValueView::create(1.1);
|
||||||
|
|
||||||
|
ASSERT_TRUE(isEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, StringValueAndIntergerValueViewAreNotEqual)
|
||||||
|
{
|
||||||
|
bool isEqual = Sqlite::Value{"foo"} == Sqlite::ValueView::create(1);
|
||||||
|
|
||||||
|
ASSERT_FALSE(isEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, ConvertStringValueViewIntoValue)
|
||||||
|
{
|
||||||
|
auto view = Sqlite::ValueView::create("foo");
|
||||||
|
|
||||||
|
Sqlite::Value value{view};
|
||||||
|
|
||||||
|
ASSERT_THAT(value, Eq("foo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, ConvertIntegerValueViewIntoValue)
|
||||||
|
{
|
||||||
|
auto view = Sqlite::ValueView::create(1);
|
||||||
|
|
||||||
|
Sqlite::Value value{view};
|
||||||
|
|
||||||
|
ASSERT_THAT(value, Eq(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SqliteValue, ConvertFloatValueViewIntoValue)
|
||||||
|
{
|
||||||
|
auto view = Sqlite::ValueView::create(1.4);
|
||||||
|
|
||||||
|
Sqlite::Value value{view};
|
||||||
|
|
||||||
|
ASSERT_THAT(value, Eq(1.4));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
@@ -80,6 +80,7 @@ SOURCES += \
|
|||||||
smallstring-test.cpp \
|
smallstring-test.cpp \
|
||||||
sourcerangefilter-test.cpp \
|
sourcerangefilter-test.cpp \
|
||||||
spydummy.cpp \
|
spydummy.cpp \
|
||||||
|
sqlitevalue-test.cpp \
|
||||||
symbolindexer-test.cpp \
|
symbolindexer-test.cpp \
|
||||||
symbolsfindfilter-test.cpp \
|
symbolsfindfilter-test.cpp \
|
||||||
stringcache-test.cpp \
|
stringcache-test.cpp \
|
||||||
@@ -122,7 +123,13 @@ SOURCES += \
|
|||||||
headerpathfilter-test.cpp \
|
headerpathfilter-test.cpp \
|
||||||
toolchainargumentscache-test.cpp \
|
toolchainargumentscache-test.cpp \
|
||||||
modifiedtimechecker-test.cpp \
|
modifiedtimechecker-test.cpp \
|
||||||
readexporteddiagnostics-test.cpp
|
sqlitecolumn-test.cpp \
|
||||||
|
sqlitedatabasebackend-test.cpp \
|
||||||
|
sqlitedatabase-test.cpp \
|
||||||
|
sqlitestatement-test.cpp \
|
||||||
|
sqlitetable-test.cpp \
|
||||||
|
sqlstatementbuilder-test.cpp \
|
||||||
|
createtablesqlstatementbuilder-test.cpp
|
||||||
|
|
||||||
!isEmpty(LIBCLANG_LIBS) {
|
!isEmpty(LIBCLANG_LIBS) {
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
@@ -158,7 +165,6 @@ SOURCES += \
|
|||||||
codecompleter-test.cpp \
|
codecompleter-test.cpp \
|
||||||
codecompletionsextractor-test.cpp \
|
codecompletionsextractor-test.cpp \
|
||||||
completionchunkstotextconverter-test.cpp \
|
completionchunkstotextconverter-test.cpp \
|
||||||
createtablesqlstatementbuilder-test.cpp \
|
|
||||||
cursor-test.cpp \
|
cursor-test.cpp \
|
||||||
diagnosticset-test.cpp \
|
diagnosticset-test.cpp \
|
||||||
diagnostic-test.cpp \
|
diagnostic-test.cpp \
|
||||||
@@ -168,17 +174,12 @@ SOURCES += \
|
|||||||
skippedsourceranges-test.cpp \
|
skippedsourceranges-test.cpp \
|
||||||
sourcelocation-test.cpp \
|
sourcelocation-test.cpp \
|
||||||
sourcerange-test.cpp \
|
sourcerange-test.cpp \
|
||||||
sqlitecolumn-test.cpp \
|
|
||||||
sqlitedatabasebackend-test.cpp \
|
|
||||||
sqlitedatabase-test.cpp \
|
|
||||||
sqlitestatement-test.cpp \
|
|
||||||
sqlitetable-test.cpp \
|
|
||||||
sqlstatementbuilder-test.cpp \
|
|
||||||
token-test.cpp \
|
token-test.cpp \
|
||||||
translationunitupdater-test.cpp \
|
translationunitupdater-test.cpp \
|
||||||
unsavedfiles-test.cpp \
|
unsavedfiles-test.cpp \
|
||||||
unsavedfile-test.cpp \
|
unsavedfile-test.cpp \
|
||||||
utf8positionfromlinecolumn-test.cpp
|
utf8positionfromlinecolumn-test.cpp \
|
||||||
|
readexporteddiagnostics-test.cpp
|
||||||
}
|
}
|
||||||
|
|
||||||
!isEmpty(LIBTOOLING_LIBS) {
|
!isEmpty(LIBTOOLING_LIBS) {
|
||||||
|
Reference in New Issue
Block a user