forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/qds-1.50' into qds-1.59
Change-Id: I45983a470a275f7eb173ed4ce34a2350e23cc625
This commit is contained in:
@@ -229,7 +229,11 @@ function(set_public_includes target includes)
|
||||
if (NOT IS_ABSOLUTE ${inc_dir})
|
||||
set(inc_dir "${CMAKE_CURRENT_SOURCE_DIR}/${inc_dir}")
|
||||
endif()
|
||||
target_include_directories(${target} PUBLIC $<BUILD_INTERFACE:${inc_dir}>)
|
||||
file(RELATIVE_PATH include_dir_relative_path ${PROJECT_SOURCE_DIR} ${inc_dir})
|
||||
target_include_directories(${target} PUBLIC
|
||||
$<BUILD_INTERFACE:${inc_dir}>
|
||||
$<INSTALL_INTERFACE:include/${include_dir_relative_path}>
|
||||
)
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 13 KiB |
@@ -64,7 +64,7 @@
|
||||
|
||||
The \uicontrol {Qt Quick Application} wizards for a particular platform add
|
||||
the import statements automatically. You can remove import statements in
|
||||
\uicontrol {QML Imports}
|
||||
\uicontrol {QML Imports}.
|
||||
|
||||
\uicontrol {Assets} displays the images and other files that you copy
|
||||
to the project folder (to the same subfolder as the QML files).
|
||||
@@ -85,6 +85,8 @@
|
||||
\li Add states to apply sets of changes to the properties of one or
|
||||
several components in the \uicontrol States view (6). For more
|
||||
information, see \l{Adding States}.
|
||||
\li Animate component properties in the \uicontrol Timeline view (7).
|
||||
For more information, see \l{Creating Animations}.
|
||||
\endlist
|
||||
|
||||
\section1 Using Basic QML Types
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Creator documentation.
|
||||
@@ -52,17 +52,9 @@
|
||||
{here}.
|
||||
|
||||
\if defined(qtcreator)
|
||||
\section1 Enabling the Timeline Editor
|
||||
|
||||
The \uicontrol Timeline view is not visible in \QC by default. To enable
|
||||
it, select \uicontrol Tools > \uicontrol Options > \uicontrol {Qt Quick} >
|
||||
\uicontrol {Qt Quick Designer} > \uicontrol {Enable Timeline editor}.
|
||||
Select \uicontrol {Restart Now} to restart \QC with the \uicontrol Timeline
|
||||
view visible.
|
||||
|
||||
To be able to create timelines, you also need the \l {Qt Quick Timeline}
|
||||
module, which is delivered with Qt 5.14, and later. For more
|
||||
information about adding the module to an older Qt version, see
|
||||
add-on module, which you can install with Qt 5.14, and later. For more
|
||||
information about adding the module to an older Qt version, see
|
||||
\l{Adding Qt Quick Timeline Module to Qt Installations}.
|
||||
\endif
|
||||
|
||||
@@ -77,9 +69,7 @@
|
||||
|
||||
\list 1
|
||||
\li In the \uicontrol Navigator, select the item to animate.
|
||||
\li Select the \uicontrol Timeline tab to open the \uicontrol Timeline
|
||||
view.
|
||||
\li Select the \inlineimage plus.png
|
||||
\li In the \uicontrol Timeline view, select the \inlineimage plus.png
|
||||
(\uicontrol {Add Timeline (A)}) button, or press \key {A} to
|
||||
specify settings for the timeline and running the animation
|
||||
in the \uicontrol {Timeline Settings} dialog.
|
||||
@@ -144,7 +134,7 @@
|
||||
\section1 Managing Keyframes
|
||||
|
||||
To animate components in the \uicontrol Timeline view, move to a frame
|
||||
on the timeline and specify changes in the values of a property. \QDS
|
||||
on the timeline and specify changes in the values of a property. \QC
|
||||
automatically adds keyframes between two keyframes, and sets their values
|
||||
evenly to create an appearance of movement or transformation.
|
||||
|
||||
@@ -160,7 +150,8 @@
|
||||
\li Select the \uicontrol {To Start (Home)}, \uicontrol {Previous (,)},
|
||||
or \uicontrol {Next (.)} buttons (3), or use the keyboard shortcuts
|
||||
to move to the first, previous, or next frame on the timeline.
|
||||
\li Enter the number of a frame in the field (4) to move to that frame.
|
||||
\li Enter the number of a frame in the current keyframe field (4) to
|
||||
move to that frame.
|
||||
\li Select the \uicontrol Previous and \uicontrol Next buttons next to
|
||||
a property name on the timeline (5) to move to the previous or next
|
||||
keyframe for that property.
|
||||
@@ -231,13 +222,11 @@
|
||||
You can view the animation on the canvas by moving the playhead along the
|
||||
timeline.
|
||||
|
||||
\if defined(qtdesignstudio)
|
||||
To preview the animation, select the \uicontrol {Play (Space)}
|
||||
button or press \key Space. To preview the whole UI, select the
|
||||
\inlineimage live_preview.png
|
||||
(\uicontrol {Show Live Preview}) button on the canvas toolbar
|
||||
or press \key {Alt+P}.
|
||||
\endif
|
||||
|
||||
\section1 Editing Easing Curves
|
||||
|
||||
@@ -247,7 +236,7 @@
|
||||
timeline are \e linear, which means that they move from the beginning to
|
||||
the end at a constant speed. You can use the \uicontrol {Easing Curve Editor}
|
||||
to edit the easing curve between two keyframes. You can also use the more
|
||||
advanced \uicontrol {Curve Editor (C)} to edit the curves for the whole
|
||||
advanced \uicontrol {Animation Curve Editor} to edit the curves for the whole
|
||||
animation.
|
||||
|
||||
\section2 Attaching Easing Curves to Keyframes
|
||||
@@ -306,23 +295,24 @@
|
||||
|
||||
\section1 Editing Animation Curves
|
||||
|
||||
In the curve editor, you can view and modify the whole animation curve. You
|
||||
In the animation curve editor, you can view and modify the whole animation
|
||||
curve. You
|
||||
can insert keyframes to the curve and drag them and the point handlers to
|
||||
modify the curve. You can modify the appearance of the curve in the style
|
||||
editor.
|
||||
|
||||
You can also edit easing curves that you added with the easing curve editor.
|
||||
|
||||
\image studio-curve-editor.png "Curve Editor"
|
||||
\image studio-curve-editor.png "Animation Curve Editor"
|
||||
|
||||
To edit animation curves:
|
||||
|
||||
\list 1
|
||||
\li In the \uicontrol Timeline view, insert at least one keyframe.
|
||||
\li Select \inlineimage curveGraphIcon.png
|
||||
(\uicontrol {Curve Editor (C)} on the toolbar or press \key C
|
||||
to open the curve editor.
|
||||
\li Right-click in the curve editor, and select
|
||||
(\uicontrol {Animation Curve Editor}) on the toolbar or press \key C
|
||||
to open the animation curve editor.
|
||||
\li Right-click in the animation curve editor, and select
|
||||
\uicontrol {Insert Keyframe} to add a keyframe.
|
||||
\li Select keyframes to display the easing curves attached to them.
|
||||
To select multiple keyframes, press and hold \key Ctrl.
|
||||
|
@@ -8,8 +8,6 @@ headerdirs =
|
||||
sourcedirs = ../src \
|
||||
../examples/doc \
|
||||
../../qtcreator/src
|
||||
# The image folders also need to added by packaging scripts, so inform your
|
||||
# local release team about any changes you make.
|
||||
imagedirs = ../images \
|
||||
../examples/doc/images \
|
||||
../../qtcreator/images \
|
||||
@@ -23,6 +21,7 @@ imagedirs = ../images \
|
||||
../../../src/plugins/help/images \
|
||||
../../../src/plugins/projectexplorer/images \
|
||||
../../../src/plugins/qmldesigner/components/componentcore/images \
|
||||
../../../src/plugins/qmldesigner/components/edit3d/images \
|
||||
../../../src/plugins/qmldesigner/components/formeditor \
|
||||
../../../src/plugins/qmldesigner/components/navigator \
|
||||
../../../src/plugins/qmldesigner/components/timelineeditor/images \
|
||||
|
@@ -67,23 +67,7 @@ source_include_patterns = [
|
||||
r"^doc/.*$", # include everything under doc/
|
||||
r"^.*\.pri$", # .pri files in all directories that are looked into
|
||||
r"^.*\.h$", # .h files in all directories that are looked into
|
||||
r"^.*\.hpp$", # .hpp files in all directories that are looked into
|
||||
# qtdesignstudio docs are build against dev package, so we need to include some image directories
|
||||
r"^share/qtcreator/qml/qmlpuppet/mockfiles/images/.*$",
|
||||
r"^share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/images/.*$",
|
||||
r"^src/libs/qmleditorwidgets/images/.*$",
|
||||
r"^src/libs/utils/images/.*$",
|
||||
r"^src/plugins/debugger/images/.*$",
|
||||
r"^src/plugins/diffeditor/images/.*$",
|
||||
r"^src/plugins/help/images/.*$",
|
||||
r"^src/plugins/projectexplorer/images/.*$",
|
||||
r"^src/plugins/qmldesigner/components/componentcore/images/.*$",
|
||||
r"^src/plugins/qmldesigner/components/timelineeditor/images/.*$",
|
||||
r"^src/plugins/qmldesigner/qmlpreviewplugin/images/.*$",
|
||||
r"^src/plugins/texteditor/images/.*$",
|
||||
# also some single files
|
||||
r"^src/plugins/qmldesigner/components/formeditor/.*\.png$",
|
||||
r"^src/plugins/qmldesigner/components/navigator/.*\.png$"
|
||||
r"^.*\.hpp$" # .hpp files in all directories that are looked into
|
||||
]
|
||||
|
||||
build_include_patterns = [
|
||||
|
@@ -800,7 +800,10 @@ def qdump__std____1__shared_ptr(d, value):
|
||||
|
||||
|
||||
def qdump__std__unique_ptr(d, value):
|
||||
p = d.extractPointer(value)
|
||||
if value.type.size() == d.ptrSize():
|
||||
p = d.extractPointer(value)
|
||||
else:
|
||||
_, p = value.split("pp"); # For custom deleters.
|
||||
if p == 0:
|
||||
d.putValue("(null)")
|
||||
d.putNumChild(0)
|
||||
|
@@ -121,7 +121,7 @@ View3D {
|
||||
pick(mouse);
|
||||
if (pickObj) {
|
||||
axisHelperView.editCameraCtrl.focusObject(axisHelperView.selectedNode,
|
||||
pickObj.cameraRotation, false);
|
||||
pickObj.cameraRotation, false, false);
|
||||
} else {
|
||||
mouse.accepted = false;
|
||||
}
|
||||
|
@@ -87,14 +87,15 @@ Item {
|
||||
}
|
||||
|
||||
|
||||
function focusObject(targetObject, rotation, updateZoom)
|
||||
function focusObject(targetObject, rotation, updateZoom, closeUp)
|
||||
{
|
||||
if (!camera)
|
||||
return;
|
||||
|
||||
camera.eulerRotation = rotation;
|
||||
var newLookAtAndZoom = _generalHelper.focusObjectToCamera(
|
||||
camera, _defaultCameraLookAtDistance, targetObject, view3d, _zoomFactor, updateZoom);
|
||||
camera, _defaultCameraLookAtDistance, targetObject, view3d, _zoomFactor,
|
||||
updateZoom, closeUp);
|
||||
_lookAtPoint = newLookAtAndZoom.toVector3d();
|
||||
_zoomFactor = newLookAtAndZoom.w;
|
||||
storeCameraState(0);
|
||||
|
@@ -146,7 +146,7 @@ Item {
|
||||
if (editView) {
|
||||
var targetNode = selectionBoxes.length > 0
|
||||
? 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
|
||||
{
|
||||
cameraControl.focusObject(selectionBox.model, viewCamera.eulerRotation, true);
|
||||
cameraControl.focusObject(selectionBox.model, viewCamera.eulerRotation, true, true);
|
||||
if (cameraControl._zoomFactor < 0.1) {
|
||||
view3D.importScene.scale = view3D.importScene.scale.times(10);
|
||||
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)
|
||||
QVector4D GeneralHelper::focusObjectToCamera(QQuick3DCamera *camera, float defaultLookAtDistance,
|
||||
QQuick3DNode *targetObject, QQuick3DViewport *viewPort,
|
||||
float oldZoom, bool updateZoom)
|
||||
float oldZoom, bool updateZoom, bool closeUp)
|
||||
{
|
||||
if (!camera)
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
return QVector4D(lookAt, cameraZoomFactor);
|
||||
|
@@ -66,8 +66,9 @@ public:
|
||||
float defaultLookAtDistance, const QVector3D &lookAt,
|
||||
float zoomFactor, bool relative);
|
||||
Q_INVOKABLE QVector4D focusObjectToCamera(QQuick3DCamera *camera, float defaultLookAtDistance,
|
||||
QQuick3DNode *targetObject, QQuick3DViewport *viewPort,
|
||||
float oldZoom, bool updateZoom = true);
|
||||
QQuick3DNode *targetObject, QQuick3DViewport *viewPort,
|
||||
float oldZoom, bool updateZoom = true,
|
||||
bool closeUp = false);
|
||||
Q_INVOKABLE void delayedPropertySet(QObject *obj, int delay, const QString &property,
|
||||
const QVariant& value);
|
||||
Q_INVOKABLE QQuick3DNode *resolvePick(QQuick3DNode *pickNode);
|
||||
|
@@ -47,6 +47,8 @@ Item {
|
||||
width: itemLibraryIconWidth // to be set in Qml context
|
||||
height: itemLibraryIconHeight // to be set in Qml context
|
||||
source: itemLibraryIconPath // to be set by model
|
||||
|
||||
cache: false // Allow thumbnail to be dynamically updated
|
||||
}
|
||||
|
||||
Text {
|
||||
|
@@ -51,6 +51,8 @@ Rectangle {
|
||||
property real __actionIndicatorWidth: StudioTheme.Values.squareComponentWidth
|
||||
property real __actionIndicatorHeight: StudioTheme.Values.height
|
||||
|
||||
property string typeFilter: "QtQuick3D.Material"
|
||||
|
||||
color: "transparent"
|
||||
border.color: StudioTheme.Values.themeControlOutline
|
||||
border.width: StudioTheme.Values.border
|
||||
@@ -69,7 +71,7 @@ Rectangle {
|
||||
validator: RegExpValidator { regExp: /(^[a-z_]\w*|^[A-Z]\w*\.{1}([a-z_]\w*\.?)+)/ }
|
||||
|
||||
actionIndicatorVisible: false
|
||||
typeFilter: "QtQuick3D.Material"
|
||||
typeFilter: editableListView.typeFilter
|
||||
editText: modelData
|
||||
initialModelData: modelData
|
||||
|
||||
|
@@ -68,9 +68,12 @@ Section {
|
||||
text: qsTr("Font")
|
||||
}
|
||||
FontComboBox {
|
||||
id: fontComboBox
|
||||
backendValue: fontSection.fontFamily
|
||||
Layout.fillWidth: true
|
||||
width: 160
|
||||
property string familyName: backendValue.value
|
||||
onFamilyNameChanged: print(styleNamesForFamily(familyName))
|
||||
}
|
||||
|
||||
Label {
|
||||
@@ -151,6 +154,7 @@ Section {
|
||||
italic: fontSection.italicStyle
|
||||
underline: fontSection.underlineStyle
|
||||
strikeout: fontSection.strikeoutStyle
|
||||
enabled: !styleComboBox.styleSet
|
||||
}
|
||||
|
||||
Label {
|
||||
@@ -175,6 +179,21 @@ Section {
|
||||
backendValue: getBackendValue("weight")
|
||||
model: ["Normal", "Light", "ExtraLight", "Thin", "Medium", "DemiBold", "Bold", "ExtraBold", "Black"]
|
||||
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 {
|
||||
|
@@ -73,8 +73,12 @@ bool ComponentVersion::isValid() const
|
||||
|
||||
QString ComponentVersion::toString() const
|
||||
{
|
||||
return QString::fromLatin1("%1.%2").arg(QString::number(_major),
|
||||
QString::number(_minor));
|
||||
QByteArray temp;
|
||||
QByteArray result;
|
||||
result += temp.setNum(_major);
|
||||
result += '.';
|
||||
result += temp.setNum(_minor);
|
||||
return QString::fromLatin1(result);
|
||||
}
|
||||
|
||||
void ComponentVersion::addToHash(QCryptographicHash &hash) const
|
||||
|
@@ -7,6 +7,7 @@ add_qtc_library(QmlJS
|
||||
parser/qmljsast.cpp parser/qmljsast_p.h
|
||||
parser/qmljsastfwd_p.h
|
||||
parser/qmljsastvisitor.cpp parser/qmljsastvisitor_p.h
|
||||
parser/qmljsdiagnosticmessage_p.h
|
||||
parser/qmljsengine_p.cpp parser/qmljsengine_p.h
|
||||
parser/qmljsglobal_p.h
|
||||
parser/qmljsgrammar.cpp parser/qmljsgrammar_p.h
|
||||
|
@@ -872,6 +872,7 @@ int Lexer::scanString(ScanStringMode mode)
|
||||
{
|
||||
QChar quote = (mode == TemplateContinuation) ? QChar(TemplateHead) : QChar(mode);
|
||||
bool multilineStringLiteral = false;
|
||||
bool escaped = false;
|
||||
|
||||
const QChar *startCode = _codePtr - 1;
|
||||
// in case we just parsed a \r, we need to reset this flag to get things working
|
||||
@@ -880,6 +881,12 @@ int Lexer::scanString(ScanStringMode mode)
|
||||
|
||||
if (_engine) {
|
||||
while (_codePtr <= _endPtr) {
|
||||
if (escaped) { // former char started an escape sequence
|
||||
escaped = false;
|
||||
_char = *_codePtr++;
|
||||
++_currentColumnNumber;
|
||||
continue;
|
||||
}
|
||||
if (isLineTerminator()) {
|
||||
if ((quote == QLatin1Char('`') || qmlMode()))
|
||||
break;
|
||||
@@ -887,7 +894,10 @@ int Lexer::scanString(ScanStringMode mode)
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Stray newline in string literal");
|
||||
return T_ERROR;
|
||||
} else if (_char == QLatin1Char('\\')) {
|
||||
break;
|
||||
if (mode != DoubleQuote && mode != SingleQuote)
|
||||
break;
|
||||
else // otherwise we need to handle an escape sequence
|
||||
escaped = true;
|
||||
} else if (_char == '$' && quote == QLatin1Char('`')) {
|
||||
break;
|
||||
} else if (_char == quote) {
|
||||
|
@@ -395,6 +395,8 @@ const Value *CppComponentValue::valueForCppName(const QString &typeName) const
|
||||
return valueOwner()->realValue();
|
||||
} else if (typeName == QLatin1String("QFont")) {
|
||||
return valueOwner()->qmlFontObject();
|
||||
} else if (typeName == QLatin1String("QPalette")) {
|
||||
return valueOwner()->qmlPaletteObject();
|
||||
} else if (typeName == QLatin1String("QPoint")
|
||||
|| typeName == QLatin1String("QPointF")
|
||||
|| typeName == QLatin1String("QVector2D")) {
|
||||
|
@@ -95,6 +95,7 @@ public:
|
||||
ObjectValue *_mathObject;
|
||||
ObjectValue *_qtObject;
|
||||
ObjectValue *_qmlFontObject;
|
||||
ObjectValue *_qmlPaletteObject;
|
||||
ObjectValue *_qmlPointObject;
|
||||
ObjectValue *_qmlSizeObject;
|
||||
ObjectValue *_qmlRectObject;
|
||||
@@ -496,6 +497,28 @@ SharedValueOwner::SharedValueOwner(SharedValueOwnerKind kind)
|
||||
_qmlFontObject->setMember(QLatin1String("kerning"), booleanValue());
|
||||
_qmlFontObject->setMember(QLatin1String("preferShaping"), booleanValue());
|
||||
|
||||
_qmlPaletteObject = newObject(/* prototype = */ nullptr);
|
||||
_qmlPaletteObject->setClassName(QLatin1String("palette"));
|
||||
_qmlPaletteObject->setMember(QLatin1String("alternateBase"), colorValue());
|
||||
_qmlPaletteObject->setMember(QLatin1String("base"), colorValue());
|
||||
_qmlPaletteObject->setMember(QLatin1String("brightText"), colorValue());
|
||||
_qmlPaletteObject->setMember(QLatin1String("button"), colorValue());
|
||||
_qmlPaletteObject->setMember(QLatin1String("buttonText"), colorValue());
|
||||
_qmlPaletteObject->setMember(QLatin1String("dark"), colorValue());
|
||||
_qmlPaletteObject->setMember(QLatin1String("highlight"), colorValue());
|
||||
_qmlPaletteObject->setMember(QLatin1String("highlightedText"), colorValue());
|
||||
_qmlPaletteObject->setMember(QLatin1String("light"), colorValue());
|
||||
_qmlPaletteObject->setMember(QLatin1String("link"), colorValue());
|
||||
_qmlPaletteObject->setMember(QLatin1String("linkVisited"), colorValue());
|
||||
_qmlPaletteObject->setMember(QLatin1String("mid"), colorValue());
|
||||
_qmlPaletteObject->setMember(QLatin1String("midlight"), colorValue());
|
||||
_qmlPaletteObject->setMember(QLatin1String("shadow"), colorValue());
|
||||
_qmlPaletteObject->setMember(QLatin1String("text"), colorValue());
|
||||
_qmlPaletteObject->setMember(QLatin1String("toolTipBase"), colorValue());
|
||||
_qmlPaletteObject->setMember(QLatin1String("toolTipText"), colorValue());
|
||||
_qmlPaletteObject->setMember(QLatin1String("window"), colorValue());
|
||||
_qmlPaletteObject->setMember(QLatin1String("windowText"), colorValue());
|
||||
|
||||
_qmlPointObject = newObject(/*prototype =*/ nullptr);
|
||||
_qmlPointObject->setClassName(QLatin1String("Point"));
|
||||
_qmlPointObject->setMember(QLatin1String("x"), numberValue());
|
||||
@@ -896,6 +919,11 @@ const ObjectValue *ValueOwner::qmlFontObject()
|
||||
return _shared->_qmlFontObject;
|
||||
}
|
||||
|
||||
const ObjectValue *ValueOwner::qmlPaletteObject()
|
||||
{
|
||||
return _shared->_qmlPaletteObject;
|
||||
}
|
||||
|
||||
const ObjectValue *ValueOwner::qmlPointObject()
|
||||
{
|
||||
return _shared->_qmlPointObject;
|
||||
|
@@ -82,6 +82,7 @@ public:
|
||||
|
||||
// QML objects
|
||||
const ObjectValue *qmlFontObject();
|
||||
const ObjectValue *qmlPaletteObject();
|
||||
const ObjectValue *qmlPointObject();
|
||||
const ObjectValue *qmlSizeObject();
|
||||
const ObjectValue *qmlRectObject();
|
||||
|
@@ -160,7 +160,7 @@ static const CommandDescription commandDescriptions[] = {
|
||||
{"assign","Assigns a value to a variable in current symbol group.",
|
||||
"[-t token] [-h] <iname=value>\n"
|
||||
"-h Data are hex-encoded, binary data\n"
|
||||
"-u Data are hex-encoded, UTF16 data"
|
||||
"-e iname is an hex-encoded expression to be evaluated "
|
||||
},
|
||||
{"threads","Lists threads in GDBMI format.","[-t token]"},
|
||||
{"registers","Lists registers in GDBMI format","[-t token]"},
|
||||
@@ -819,57 +819,77 @@ extern "C" HRESULT CALLBACK assign(CIDebugClient *client, PCSTR argsIn)
|
||||
ExtensionCommandContext exc(client);
|
||||
|
||||
std::string errorMessage;
|
||||
bool success = false;
|
||||
bool encoded = false;
|
||||
bool evaluateExpression = false;
|
||||
int token = 0;
|
||||
do {
|
||||
StringList tokens = commandTokens<StringList>(argsIn, &token);
|
||||
if (tokens.empty()) {
|
||||
errorMessage = singleLineUsage(commandDescriptions[CmdAssign]);
|
||||
break;
|
||||
}
|
||||
|
||||
StringList tokens = commandTokens<StringList>(argsIn, &token);
|
||||
while (!tokens.empty()) {
|
||||
if (tokens.front() == "-h") {
|
||||
encoded = true;
|
||||
tokens.pop_front();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tokens.empty()) {
|
||||
errorMessage = singleLineUsage(commandDescriptions[CmdAssign]);
|
||||
break;
|
||||
if (tokens.front() == "-e") {
|
||||
evaluateExpression = true;
|
||||
tokens.pop_front();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
};
|
||||
|
||||
// Parse 'assign locals.x=5'
|
||||
const std::string::size_type equalsPos = tokens.front().find('=');
|
||||
if (equalsPos == std::string::npos) {
|
||||
errorMessage = singleLineUsage(commandDescriptions[CmdAssign]);
|
||||
break;
|
||||
}
|
||||
const std::string iname = tokens.front().substr(0, equalsPos);
|
||||
const std::string value = tokens.front().substr(equalsPos + 1, tokens.front().size() - equalsPos - 1);
|
||||
// get the symbolgroup
|
||||
int currentFrame = ExtensionContext::instance().symbolGroupFrame();
|
||||
if (currentFrame < 0) {
|
||||
CIDebugControl *control = ExtensionCommandContext::instance()->control();
|
||||
DEBUG_STACK_FRAME frame;
|
||||
if (FAILED(control->GetStackTrace(0, 0, 0, &frame, 1, NULL))) {
|
||||
errorMessage = "No current frame.";
|
||||
break;
|
||||
// Parse 'assign locals.x=5'
|
||||
const std::string::size_type equalsPos = tokens.empty() ? std::string::npos
|
||||
: tokens.front().find('=');
|
||||
if (equalsPos == std::string::npos) {
|
||||
errorMessage = singleLineUsage(commandDescriptions[CmdAssign]);
|
||||
} else {
|
||||
std::string iname = tokens.front().substr(0, equalsPos);
|
||||
const std::string value = tokens.front().substr(equalsPos + 1,
|
||||
tokens.front().size() - equalsPos - 1);
|
||||
SymbolGroup *symGroup = nullptr;
|
||||
if (evaluateExpression) {
|
||||
WatchesSymbolGroup *watchesSymGroup
|
||||
= ExtensionContext::instance().watchesSymbolGroup(exc.symbols(), &errorMessage);
|
||||
std::string tempAssignIname = "watch.tmpassign";
|
||||
if (watchesSymGroup) {
|
||||
if (watchesSymGroup->addWatch(exc.symbols(),
|
||||
tempAssignIname,
|
||||
stringFromHex(iname),
|
||||
&errorMessage)) {
|
||||
iname = tempAssignIname;
|
||||
symGroup = watchesSymGroup;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// get the symbolgroup
|
||||
int currentFrame = ExtensionContext::instance().symbolGroupFrame();
|
||||
if (currentFrame < 0) {
|
||||
CIDebugControl *control = ExtensionCommandContext::instance()->control();
|
||||
DEBUG_STACK_FRAME frame;
|
||||
if (FAILED(control->GetStackTrace(0, 0, 0, &frame, 1, NULL)))
|
||||
errorMessage = "No current frame.";
|
||||
else
|
||||
currentFrame = frame.FrameNumber;
|
||||
}
|
||||
if (currentFrame >= 0) {
|
||||
symGroup = ExtensionContext::instance().symbolGroup(exc.symbols(),
|
||||
exc.threadId(),
|
||||
currentFrame,
|
||||
&errorMessage);
|
||||
}
|
||||
currentFrame = frame.FrameNumber;
|
||||
}
|
||||
SymbolGroup *symGroup = ExtensionContext::instance().symbolGroup(exc.symbols(), exc.threadId(), currentFrame, &errorMessage);
|
||||
if (!symGroup)
|
||||
break;
|
||||
success = symGroup->assign(iname, encoded ? stringFromHex(value) : value,
|
||||
SymbolGroupValueContext(exc.dataSpaces(), exc.symbols()),
|
||||
&errorMessage);
|
||||
} while (false);
|
||||
if (symGroup
|
||||
&& symGroup->assign(iname,
|
||||
encoded ? stringFromHex(value) : value,
|
||||
SymbolGroupValueContext(exc.dataSpaces(), exc.symbols()),
|
||||
&errorMessage)) {
|
||||
ExtensionContext::instance().report('R', token, 0, "assign", "Ok");
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
ExtensionContext::instance().report('R', token, 0, "assign", "Ok");
|
||||
else
|
||||
ExtensionContext::instance().report('N', token, 0, "assign", errorMessage.c_str());
|
||||
ExtensionContext::instance().report('N', token, 0, "assign", errorMessage.c_str());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@@ -698,6 +698,7 @@ void ClangTool::startTool(ClangTool::FileSelection fileSelection,
|
||||
connect(m_runWorker, &ClangToolRunWorker::started, this, &ClangTool::onStarted);
|
||||
connect(m_runWorker, &ClangToolRunWorker::runnerFinished,
|
||||
this, &ClangTool::updateForCurrentState);
|
||||
connect(m_runControl, &RunControl::destroyed, [this](){ m_runWorker = nullptr; });
|
||||
|
||||
// More init and UI update
|
||||
m_diagnosticFilterModel->setProject(project);
|
||||
@@ -1038,6 +1039,8 @@ void ClangTool::onRunControlStopped()
|
||||
void ClangTool::update()
|
||||
{
|
||||
updateForInitialState();
|
||||
if (!m_runWorker)
|
||||
return;
|
||||
updateForCurrentState();
|
||||
}
|
||||
|
||||
|
@@ -33,10 +33,12 @@
|
||||
#include <app/app_version.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/variablechooser.h>
|
||||
#include <projectexplorer/task.h>
|
||||
#include <projectexplorer/toolchain.h>
|
||||
#include <projectexplorer/kit.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/projectexplorer.h>
|
||||
#include <projectexplorer/projectexplorersettings.h>
|
||||
#include <projectexplorer/task.h>
|
||||
#include <projectexplorer/toolchain.h>
|
||||
#include <qtsupport/baseqtversion.h>
|
||||
#include <qtsupport/qtkitinformation.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
@@ -643,6 +645,21 @@ QVariant CMakeGeneratorKitAspect::defaultValue(const Kit *k) const
|
||||
return g.matches("NMake Makefiles", extraGenerator)
|
||||
|| g.matches("NMake Makefiles JOM", extraGenerator);
|
||||
});
|
||||
if (ProjectExplorerPlugin::projectExplorerSettings().useJom) {
|
||||
it = std::find_if(known.constBegin(),
|
||||
known.constEnd(),
|
||||
[extraGenerator](const CMakeTool::Generator &g) {
|
||||
return g.matches("NMake Makefiles JOM", extraGenerator);
|
||||
});
|
||||
}
|
||||
|
||||
if (it == known.constEnd()) {
|
||||
it = std::find_if(known.constBegin(),
|
||||
known.constEnd(),
|
||||
[extraGenerator](const CMakeTool::Generator &g) {
|
||||
return g.matches("NMake Makefiles", extraGenerator);
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Unix-oid OSes:
|
||||
@@ -770,6 +787,16 @@ KitAspectWidget *CMakeGeneratorKitAspect::createConfigWidget(Kit *k) const
|
||||
return new CMakeGeneratorKitAspectWidget(k, this);
|
||||
}
|
||||
|
||||
void CMakeGeneratorKitAspect::addToEnvironment(const Kit *k, Utils::Environment &env) const
|
||||
{
|
||||
GeneratorInfo info = generatorInfo(k);
|
||||
if (info.generator == "NMake Makefiles JOM") {
|
||||
if (env.searchInPath("jom.exe").exists())
|
||||
return;
|
||||
env.appendOrSetPath(QCoreApplication::applicationDirPath());
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// CMakeConfigurationKitAspect:
|
||||
// --------------------------------------------------------------------
|
||||
|
@@ -83,6 +83,7 @@ public:
|
||||
void upgrade(ProjectExplorer::Kit *k) final;
|
||||
ItemList toUserOutput(const ProjectExplorer::Kit *k) const final;
|
||||
ProjectExplorer::KitAspectWidget *createConfigWidget(ProjectExplorer::Kit *k) const final;
|
||||
void addToEnvironment(const ProjectExplorer::Kit *k, Utils::Environment &env) const final;
|
||||
|
||||
private:
|
||||
QVariant defaultValue(const ProjectExplorer::Kit *k) const;
|
||||
|
@@ -170,7 +170,7 @@ static FilePath jsonObjectFilename(const QJsonObject &object)
|
||||
const QString workingDir = QDir::fromNativeSeparators(object["directory"].toString());
|
||||
FilePath fileName = FilePath::fromString(QDir::fromNativeSeparators(object["file"].toString()));
|
||||
if (fileName.toFileInfo().isRelative())
|
||||
fileName = FilePath::fromString(workingDir + "/" + fileName.toString()).canonicalPath();
|
||||
fileName = FilePath::fromString(QDir::cleanPath(workingDir + "/" + fileName.toString()));
|
||||
return fileName;
|
||||
}
|
||||
|
||||
|
@@ -929,8 +929,15 @@ void CdbEngine::assignValueInDebugger(WatchItem *w, const QString &expr, const Q
|
||||
qWarning("Internal error: assignValueInDebugger: Invalid state or no stack frame.");
|
||||
return;
|
||||
}
|
||||
runCommand({m_extensionCommandPrefix + "assign -h " + w->iname + '=' + toHex(value.toString()),
|
||||
NoFlags});
|
||||
if (m_pythonVersion > 0x030000 && w->isWatcher()) {
|
||||
runCommand({m_extensionCommandPrefix + "assign -h -e " + toHex(w->expression()) + '='
|
||||
+ toHex(value.toString()),
|
||||
NoFlags});
|
||||
} else {
|
||||
runCommand({m_extensionCommandPrefix + "assign -h " + w->iname + '=' + toHex(value.toString()),
|
||||
NoFlags});
|
||||
}
|
||||
|
||||
// Update all locals in case we change a union or something pointed to
|
||||
// that affects other variables, too.
|
||||
updateLocals();
|
||||
|
@@ -500,8 +500,13 @@ void QmakeBuildSystem::startAsyncTimer(QmakeProFile::AsyncUpdateDelay delay)
|
||||
|
||||
void QmakeBuildSystem::incrementPendingEvaluateFutures()
|
||||
{
|
||||
if (m_pendingEvaluateFuturesCount == 0)
|
||||
m_guard = guardParsingRun();
|
||||
if (m_pendingEvaluateFuturesCount == 0) {
|
||||
// The guard actually might already guard the project if this
|
||||
// here is the re-start of a previously aborted parse due to e.g.
|
||||
// changing build directories while parsing.
|
||||
if (!m_guard.guardsProject())
|
||||
m_guard = guardParsingRun();
|
||||
}
|
||||
++m_pendingEvaluateFuturesCount;
|
||||
m_asyncUpdateFutureInterface.setProgressRange(m_asyncUpdateFutureInterface.progressMinimum(),
|
||||
m_asyncUpdateFutureInterface.progressMaximum() + 1);
|
||||
|
@@ -144,6 +144,7 @@ extend_qtc_plugin(QmlDesigner
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
SOURCES_PREFIX ../../../share/qtcreator/qml/qmlpuppet/interfaces
|
||||
PUBLIC_INCLUDES ../../../share/qtcreator/qml/qmlpuppet/interfaces
|
||||
SOURCES
|
||||
nodeinstanceserverinterface.cpp
|
||||
commondefines.h
|
||||
@@ -202,6 +203,7 @@ extend_qtc_plugin(QmlDesigner
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
SOURCES_PREFIX components/formeditor
|
||||
PUBLIC_INCLUDES components/formeditor
|
||||
SOURCES
|
||||
abstractcustomtool.cpp abstractcustomtool.h
|
||||
abstractformeditortool.cpp abstractformeditortool.h
|
||||
@@ -243,6 +245,7 @@ extend_qtc_plugin(QmlDesigner
|
||||
snapper.cpp snapper.h
|
||||
snappinglinecreator.cpp snappinglinecreator.h
|
||||
toolbox.cpp toolbox.h
|
||||
transitiontool.cpp transitiontool.h
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
@@ -257,6 +260,7 @@ extend_qtc_plugin(QmlDesigner
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
SOURCES_PREFIX components/integration
|
||||
PUBLIC_INCLUDES components/integration
|
||||
SOURCES
|
||||
componentaction.cpp componentaction.h
|
||||
componentview.cpp componentview.h
|
||||
@@ -470,6 +474,7 @@ extend_qtc_plugin(QmlDesigner
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
SOURCES_PREFIX designercore
|
||||
PUBLIC_INCLUDES designercore
|
||||
SOURCES
|
||||
metainfo/itemlibraryinfo.cpp
|
||||
metainfo/metainfo.cpp
|
||||
|
@@ -41,6 +41,7 @@ const char anchorsCategory[] = "Anchors";
|
||||
const char positionCategory[] = "Position";
|
||||
const char layoutCategory[] = "Layout";
|
||||
const char flowCategory[] = "Flow";
|
||||
const char flowEffectCategory[] = "FlowEffect";
|
||||
const char flowConnectionCategory[] = "FlowConnection";
|
||||
const char stackedContainerCategory[] = "StackedContainer";
|
||||
const char genericToolBarCategory[] = "GenericToolBar";
|
||||
@@ -57,6 +58,7 @@ const char anchorsFillCommandId[] = "AnchorsFill";
|
||||
const char anchorsResetCommandId[] = "AnchorsReset";
|
||||
const char removePositionerCommandId[] = "RemovePositioner";
|
||||
const char createFlowActionAreaCommandId[] = "CreateFlowActionArea";
|
||||
const char setFlowStartCommandId[] = "SetFlowStart";
|
||||
const char layoutRowPositionerCommandId[] = "LayoutRowPositioner";
|
||||
const char layoutColumnPositionerCommandId[] = "LayoutColumnPositioner";
|
||||
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 layoutCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Layout");
|
||||
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 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 removePositionerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Remove Positioner");
|
||||
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 addItemToStackedContainerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Add Item");
|
||||
|
@@ -346,6 +346,12 @@ bool isFlowItem(const SelectionContext &context)
|
||||
&& QmlFlowItemNode::isValidQmlFlowItemNode(context.currentSingleSelectedNode());
|
||||
}
|
||||
|
||||
bool isFlowTarget(const SelectionContext &context)
|
||||
{
|
||||
return context.singleNodeIsSelected()
|
||||
&& QmlFlowTargetNode::isFlowEditorTarget(context.currentSingleSelectedNode());
|
||||
}
|
||||
|
||||
bool isFlowTransitionItem(const SelectionContext &context)
|
||||
{
|
||||
return context.singleNodeIsSelected()
|
||||
@@ -362,9 +368,9 @@ bool isFlowActionItemItem(const SelectionContext &context)
|
||||
|| 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
|
||||
@@ -853,15 +859,24 @@ void DesignerActionManager::createDefaultDesignerActions()
|
||||
priorityLayoutCategory,
|
||||
&layoutOptionVisible));
|
||||
|
||||
//isFlowTransitionItem
|
||||
|
||||
addDesignerAction(new ActionGroup(
|
||||
flowCategoryDisplayName,
|
||||
flowCategory,
|
||||
priorityFlowCategory,
|
||||
&isFlowItemOrTransition,
|
||||
&isFlowTargetOrTransition,
|
||||
&flowOptionVisible));
|
||||
|
||||
|
||||
auto effectMenu = new ActionGroup(
|
||||
flowEffectCategoryDisplayName,
|
||||
flowEffectCategory,
|
||||
priorityFlowCategory,
|
||||
&isFlowTransitionItem,
|
||||
&flowOptionVisible);
|
||||
|
||||
effectMenu->setCategory(flowCategory);
|
||||
addDesignerAction(effectMenu);
|
||||
|
||||
addDesignerAction(new ModelNodeFormEditorAction(
|
||||
createFlowActionAreaCommandId,
|
||||
createFlowActionAreaDisplayName,
|
||||
@@ -874,6 +889,17 @@ void DesignerActionManager::createDefaultDesignerActions()
|
||||
&isFlowItem,
|
||||
&flowOptionVisible));
|
||||
|
||||
addDesignerAction(new ModelNodeContextMenuAction(
|
||||
setFlowStartCommandId,
|
||||
setFlowStartDisplayName,
|
||||
{},
|
||||
flowCategory,
|
||||
priorityFirst,
|
||||
{},
|
||||
&setFlowStartItem,
|
||||
&isFlowItem,
|
||||
&flowOptionVisible));
|
||||
|
||||
addDesignerAction(new FlowActionConnectAction(
|
||||
flowConnectionCategoryDisplayName,
|
||||
flowConnectionCategory,
|
||||
@@ -1175,7 +1201,7 @@ void DesignerActionManager::addTransitionEffectAction(const TypeName &typeName)
|
||||
QByteArray(ComponentCoreConstants::flowAssignEffectCommandId) + typeName,
|
||||
QLatin1String(ComponentCoreConstants::flowAssignEffectDisplayName) + typeName,
|
||||
{},
|
||||
ComponentCoreConstants::flowCategory,
|
||||
ComponentCoreConstants::flowEffectCategory,
|
||||
{},
|
||||
typeName == "None" ? 100 : 140,
|
||||
[typeName](const SelectionContext &context)
|
||||
|
@@ -132,16 +132,22 @@ public:
|
||||
|
||||
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); }
|
||||
QByteArray category() const override { return QByteArray(); }
|
||||
QByteArray category() const override { return m_category; }
|
||||
QByteArray menuId() const override { return m_menuId; }
|
||||
int priority() const override { return m_priority; }
|
||||
Type type() const override { return ContextMenu; }
|
||||
|
||||
void setCategory(const QByteArray &catageoryId)
|
||||
{
|
||||
m_category = catageoryId;
|
||||
}
|
||||
|
||||
private:
|
||||
const QByteArray m_menuId;
|
||||
const int m_priority;
|
||||
SelectionContextPredicate m_enabled;
|
||||
SelectionContextPredicate m_visibility;
|
||||
QByteArray m_category;
|
||||
};
|
||||
|
||||
class SeperatorDesignerAction : public AbstractAction
|
||||
|
@@ -311,8 +311,10 @@ void resetSize(const SelectionContext &selectionState)
|
||||
selectionState.view()->executeInTransaction("DesignerActionManager|resetSize",[selectionState](){
|
||||
foreach (ModelNode node, selectionState.selectedModelNodes()) {
|
||||
QmlItemNode itemNode(node);
|
||||
itemNode.removeProperty("width");
|
||||
itemNode.removeProperty("height");
|
||||
if (itemNode.isValid()) {
|
||||
itemNode.removeProperty("width");
|
||||
itemNode.removeProperty("height");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -325,8 +327,10 @@ void resetPosition(const SelectionContext &selectionState)
|
||||
selectionState.view()->executeInTransaction("DesignerActionManager|resetPosition",[selectionState](){
|
||||
foreach (ModelNode node, selectionState.selectedModelNodes()) {
|
||||
QmlItemNode itemNode(node);
|
||||
itemNode.removeProperty("x");
|
||||
itemNode.removeProperty("y");
|
||||
if (itemNode.isValid()) {
|
||||
itemNode.removeProperty("x");
|
||||
itemNode.removeProperty("y");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -348,7 +352,8 @@ void resetZ(const SelectionContext &selectionState)
|
||||
selectionState.view()->executeInTransaction("DesignerActionManager|resetZ",[selectionState](){
|
||||
foreach (ModelNode node, selectionState.selectedModelNodes()) {
|
||||
QmlItemNode itemNode(node);
|
||||
itemNode.removeProperty("z");
|
||||
if (itemNode.isValid())
|
||||
itemNode.removeProperty("z");
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1095,7 +1100,24 @@ void addFlowEffect(const SelectionContext &selectionContext, const TypeName &typ
|
||||
container.nodeProperty("effect").reparentHere(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
|
||||
|
@@ -77,6 +77,7 @@ bool addFontToProject(const QStringList &fileNames, const QString &directory);
|
||||
void createFlowActionArea(const SelectionContext &selectionContext);
|
||||
void addTransition(const SelectionContext &selectionState);
|
||||
void addFlowEffect(const SelectionContext &selectionState, const TypeName &typeName);
|
||||
void setFlowStartItem(const SelectionContext &selectionContext);
|
||||
|
||||
} // namespace ModelNodeOperationso
|
||||
} //QmlDesigner
|
||||
|
@@ -179,6 +179,17 @@ void Edit3DView::importsChanged(const QList<Import> &addedImports,
|
||||
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
|
||||
{
|
||||
if (nodeInstanceView())
|
||||
@@ -301,14 +312,16 @@ QVector<Edit3DAction *> Edit3DView::rightActions() const
|
||||
|
||||
void Edit3DView::addQuick3DImport()
|
||||
{
|
||||
const QList<Import> imports = model()->possibleImports();
|
||||
for (const auto &import : imports) {
|
||||
if (import.url() == "QtQuick3D") {
|
||||
model()->changeImports({import}, {});
|
||||
if (model()) {
|
||||
const QList<Import> imports = model()->possibleImports();
|
||||
for (const auto &import : imports) {
|
||||
if (import.url() == "QtQuick3D") {
|
||||
model()->changeImports({import}, {});
|
||||
|
||||
// Subcomponent manager update needed to make item library entries appear
|
||||
QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager();
|
||||
return;
|
||||
// Subcomponent manager update needed to make item library entries appear
|
||||
QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
Core::AsynchronousMessageBox::warning(tr("Failed to Add Import"),
|
||||
|
@@ -58,6 +58,7 @@ public:
|
||||
void modelAttached(Model *model) override;
|
||||
void modelAboutToBeDetached(Model *model) 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 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
|
||||
m_onboardingLabel = new QLabel(this);
|
||||
QString labelText =
|
||||
"No 3D import here yet!<br><br>"
|
||||
"To create a 3D View you need to add the QtQuick3D import to your file.<br>"
|
||||
"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> "
|
||||
"to add it straight away.<br><br>"
|
||||
"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.";
|
||||
tr("Your file does not import Qt Quick 3D.<br><br>"
|
||||
"To create a 3D view, add the QtQuick3D import to your file in the QML Imports tab of the Library view. Or click"
|
||||
" <a href=\"#add_import\"><span style=\"text-decoration:none;color:%1\">here</span></a> "
|
||||
"here to add it immediately.<br><br>"
|
||||
"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->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
connect(m_onboardingLabel, &QLabel::linkActivated, this, &Edit3DWidget::linkActivated);
|
||||
|
@@ -36,7 +36,8 @@ SOURCES += formeditoritem.cpp \
|
||||
contentnoteditableindicator.cpp \
|
||||
backgroundaction.cpp \
|
||||
formeditortoolbutton.cpp \
|
||||
formeditorannotationicon.cpp
|
||||
formeditorannotationicon.cpp \
|
||||
transitiontool.cpp
|
||||
|
||||
HEADERS += formeditorscene.h \
|
||||
formeditorwidget.h \
|
||||
@@ -75,6 +76,7 @@ HEADERS += formeditorscene.h \
|
||||
contentnoteditableindicator.h \
|
||||
backgroundaction.h \
|
||||
formeditortoolbutton.h \
|
||||
formeditorannotationicon.h
|
||||
formeditorannotationicon.h \
|
||||
transitiontool.h
|
||||
|
||||
RESOURCES += formeditor.qrc
|
||||
|
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_block)
|
||||
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_block)
|
||||
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_block = 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_block = 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_block = true;
|
||||
};
|
||||
|
||||
} //QmlDesigner
|
@@ -81,14 +81,16 @@ void ImportManagerView::modelAboutToBeDetached(Model *model)
|
||||
|
||||
void ImportManagerView::importsChanged(const QList<Import> &/*addedImports*/, const QList<Import> &/*removedImports*/)
|
||||
{
|
||||
if (m_importsWidget)
|
||||
if (m_importsWidget) {
|
||||
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*/)
|
||||
{
|
||||
QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager();
|
||||
|
||||
if (m_importsWidget)
|
||||
m_importsWidget->setPossibleImports(model()->possibleImports());
|
||||
}
|
||||
|
@@ -32,6 +32,9 @@
|
||||
#include "utils/outputformatter.h"
|
||||
#include "theme.h"
|
||||
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/session.h>
|
||||
|
||||
#include <QtCore/qfileinfo.h>
|
||||
#include <QtCore/qdir.h>
|
||||
#include <QtCore/qloggingcategory.h>
|
||||
@@ -97,6 +100,20 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &im
|
||||
|
||||
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:
|
||||
// 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
|
||||
@@ -105,19 +122,11 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &im
|
||||
// 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 quick3DFolder = QLatin1String(Constants::QUICK_3D_ASSETS_FOLDER);
|
||||
QString candidatePath = defaulTargetDirectory + defaultAssetFolder + quick3DFolder;
|
||||
QString candidatePath = targetDir + defaultAssetFolder + quick3DFolder;
|
||||
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)) {
|
||||
if (importPath.startsWith(defaulTargetDirectory)) {
|
||||
if (importPath.startsWith(targetDir)) {
|
||||
const bool isDefaultFolder = importPath.endsWith(defaultAssetFolder);
|
||||
const QString assetFolder = importPath + quick3DFolder;
|
||||
const bool exists = QFileInfo(assetFolder).exists();
|
||||
|
@@ -280,7 +280,16 @@ void ItemLibraryAssetImporter::parseQuick3DAsset(const QString &file, const QVar
|
||||
return;
|
||||
}
|
||||
|
||||
QString originalAssetName = 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)) {
|
||||
addWarning(tr("Skipped import of existing asset: \"%1\"").arg(assetName));
|
||||
return;
|
||||
@@ -306,6 +315,16 @@ void ItemLibraryAssetImporter::parseQuick3DAsset(const QString &file, const QVar
|
||||
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;
|
||||
const int outDirPathSize = outDir.path().size();
|
||||
auto insertAsset = [&](const QString &filePath) {
|
||||
@@ -512,18 +531,24 @@ void ItemLibraryAssetImporter::finalizeQuick3DImport()
|
||||
addInfo(progressTitle);
|
||||
notifyProgress(0, progressTitle);
|
||||
|
||||
// There is an inbuilt delay before rewriter change actually updates the data model,
|
||||
// so we need to wait for a moment to allow the change to take effect.
|
||||
// First we have to wait a while to ensure qmljs detects new files and updates its
|
||||
// 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.
|
||||
QTimer *timer = new QTimer(parent());
|
||||
static int counter;
|
||||
counter = 0;
|
||||
timer->callOnTimeout([this, timer, progressTitle, model]() {
|
||||
timer->callOnTimeout([this, timer, progressTitle, model, doc]() {
|
||||
if (!isCancelled()) {
|
||||
notifyProgress(++counter * 10, progressTitle);
|
||||
if (counter >= 10) {
|
||||
// Trigger underlying qmljs snapshot update by making a non-change to the doc
|
||||
notifyProgress(++counter * 5, progressTitle);
|
||||
if (counter == 10) {
|
||||
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();
|
||||
notifyFinished();
|
||||
}
|
||||
|
@@ -238,11 +238,6 @@ QMimeData *ItemLibraryModel::getMimeData(const ItemLibraryEntry &itemLibraryEntr
|
||||
return mimeData;
|
||||
}
|
||||
|
||||
QList<ItemLibrarySection *> ItemLibraryModel::sections() const
|
||||
{
|
||||
return m_sections;
|
||||
}
|
||||
|
||||
void ItemLibraryModel::clearSections()
|
||||
{
|
||||
qDeleteAll(m_sections);
|
||||
|
@@ -58,17 +58,8 @@ public:
|
||||
|
||||
QMimeData *getMimeData(const ItemLibraryEntry &itemLibraryEntry);
|
||||
|
||||
QList<ItemLibrarySection*> sections() const;
|
||||
|
||||
void clearSections();
|
||||
|
||||
static void registerQmlTypes();
|
||||
|
||||
int visibleSectionCount() const;
|
||||
QList<ItemLibrarySection*> visibleSections() const;
|
||||
|
||||
ItemLibrarySection *sectionByName(const QString §ionName);
|
||||
|
||||
void setSearchText(const QString &searchText);
|
||||
|
||||
void setExpanded(bool, const QString §ion);
|
||||
@@ -80,13 +71,15 @@ signals:
|
||||
void searchTextChanged();
|
||||
|
||||
private: // functions
|
||||
ItemLibrarySection *sectionByName(const QString §ionName);
|
||||
void updateVisibility(bool *changed);
|
||||
void addRoleNames();
|
||||
void sortSections();
|
||||
void clearSections();
|
||||
|
||||
|
||||
private: // variables
|
||||
QList<ItemLibrarySection*> m_sections;
|
||||
QList<QPointer<ItemLibrarySection>> m_sections;
|
||||
QHash<int, QByteArray> m_roleNames;
|
||||
|
||||
QString m_searchText;
|
||||
|
@@ -101,13 +101,15 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
|
||||
m_itemViewQuickWidget->engine()->addImportPath(propertyEditorResourcesPath() + "/imports");
|
||||
m_itemLibraryModel = new ItemLibraryModel(this);
|
||||
|
||||
QQmlContext *rootContext = m_itemViewQuickWidget->rootContext();
|
||||
rootContext->setContextProperty(QStringLiteral("itemLibraryModel"), m_itemLibraryModel.data());
|
||||
rootContext->setContextProperty(QStringLiteral("itemLibraryIconWidth"), m_itemIconSize.width());
|
||||
rootContext->setContextProperty(QStringLiteral("itemLibraryIconHeight"), m_itemIconSize.height());
|
||||
rootContext->setContextProperty(QStringLiteral("rootView"), this);
|
||||
|
||||
m_itemViewQuickWidget->rootContext()->setContextProperty(QStringLiteral("highlightColor"), Utils::StyleHelper::notTooBrightHighlightColor());
|
||||
m_itemViewQuickWidget->rootContext()->setContextProperties(
|
||||
QVector<QQmlContext::PropertyPair>{
|
||||
{"itemLibraryModel", QVariant::fromValue(m_itemLibraryModel.data())},
|
||||
{"itemLibraryIconWidth", m_itemIconSize.width()},
|
||||
{"itemLibraryIconHeight", m_itemIconSize.height()},
|
||||
{"rootView", QVariant::fromValue(this)},
|
||||
{"highlightColor", Utils::StyleHelper::notTooBrightHighlightColor()}
|
||||
}
|
||||
);
|
||||
|
||||
/* create Resources view and its model */
|
||||
m_resourcesFileSystemModel = new CustomFileSystemModel(this);
|
||||
|
@@ -43,6 +43,7 @@ public:
|
||||
virtual void notifyModelNodesRemoved(const QList<ModelNode> &modelNodes) = 0;
|
||||
virtual void notifyModelNodesInserted(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 resetModel() = 0;
|
||||
};
|
||||
|
@@ -695,6 +695,11 @@ void NavigatorTreeModel::notifyModelNodesMoved(const QList<ModelNode> &modelNode
|
||||
emit layoutChanged(indexes);
|
||||
}
|
||||
|
||||
void NavigatorTreeModel::notifyIconsChanged()
|
||||
{
|
||||
emit dataChanged(index(0, 0), index(rowCount(), 0), {Qt::DecorationRole});
|
||||
}
|
||||
|
||||
void NavigatorTreeModel::setFilter(bool showOnlyVisibleItems)
|
||||
{
|
||||
m_showOnlyVisibleItems = showOnlyVisibleItems;
|
||||
|
@@ -87,6 +87,7 @@ public:
|
||||
void notifyModelNodesRemoved(const QList<ModelNode> &modelNodes) override;
|
||||
void notifyModelNodesInserted(const QList<ModelNode> &modelNodes) override;
|
||||
void notifyModelNodesMoved(const QList<ModelNode> &modelNodes) override;
|
||||
void notifyIconsChanged() override;
|
||||
void setFilter(bool showOnlyVisibleItems) 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)
|
||||
{
|
||||
const ModelNode rootNode = rootModelNode();
|
||||
@@ -431,7 +442,7 @@ void NavigatorView::updateItemSelection()
|
||||
// make sure selected nodes a visible
|
||||
foreach (const QModelIndex &selectedIndex, itemSelection.indexes()) {
|
||||
if (selectedIndex.column() == 0)
|
||||
expandRecursively(selectedIndex);
|
||||
expandAncestors(selectedIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,9 +466,9 @@ bool NavigatorView::blockSelectionChangedSignal(bool block)
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
void NavigatorView::expandRecursively(const QModelIndex &index)
|
||||
void NavigatorView::expandAncestors(const QModelIndex &index)
|
||||
{
|
||||
QModelIndex currentIndex = index;
|
||||
QModelIndex currentIndex = index.parent();
|
||||
while (currentIndex.isValid()) {
|
||||
if (!treeWidget()->isExpanded(currentIndex))
|
||||
treeWidget()->expand(currentIndex);
|
||||
|
@@ -84,6 +84,8 @@ public:
|
||||
|
||||
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);
|
||||
bool isNodeInvisible(const ModelNode &modelNode) const;
|
||||
|
||||
@@ -108,7 +110,7 @@ protected: //functions
|
||||
QTreeView *treeWidget() const;
|
||||
NavigatorTreeModel *treeModel();
|
||||
bool blockSelectionChangedSignal(bool block);
|
||||
void expandRecursively(const QModelIndex &index);
|
||||
void expandAncestors(const QModelIndex &index);
|
||||
void reparentAndCatch(NodeAbstractProperty property, const ModelNode &modelNode);
|
||||
void setupWidget();
|
||||
|
||||
|
@@ -379,9 +379,12 @@ void PropertyEditorQmlBackend::setup(const QmlObjectNode &qmlObjectNode, const Q
|
||||
|
||||
// anchors
|
||||
m_backendAnchorBinding.setup(qmlObjectNode.modelNode());
|
||||
context()->setContextProperty(QLatin1String("anchorBackend"), &m_backendAnchorBinding);
|
||||
|
||||
context()->setContextProperty(QLatin1String("transaction"), m_propertyEditorTransaction.data());
|
||||
context()->setContextProperties(
|
||||
QVector<QQmlContext::PropertyPair>{
|
||||
{{"anchorBackend"}, QVariant::fromValue(&m_backendAnchorBinding)},
|
||||
{{"transaction"}, QVariant::fromValue(m_propertyEditorTransaction.data())}
|
||||
}
|
||||
);
|
||||
|
||||
qCInfo(propertyEditorBenchmark) << "anchors:" << time.elapsed();
|
||||
|
||||
@@ -457,9 +460,13 @@ void PropertyEditorQmlBackend::initialSetup(const TypeName &typeName, const QUrl
|
||||
QObject::connect(valueObject, &PropertyEditorValue::valueChanged, &backendValuesPropertyMap(), &DesignerPropertyMap::valueChanged);
|
||||
m_backendValuesPropertyMap.insert(QLatin1String("id"), QVariant::fromValue(valueObject));
|
||||
|
||||
context()->setContextProperty(QLatin1String("anchorBackend"), &m_backendAnchorBinding);
|
||||
context()->setContextProperty(QLatin1String("modelNodeBackend"), &m_backendModelNode);
|
||||
context()->setContextProperty(QLatin1String("transaction"), m_propertyEditorTransaction.data());
|
||||
context()->setContextProperties(
|
||||
QVector<QQmlContext::PropertyPair>{
|
||||
{{"anchorBackend"}, QVariant::fromValue(&m_backendAnchorBinding)},
|
||||
{{"modelNodeBackend"}, QVariant::fromValue(&m_backendModelNode)},
|
||||
{{"transaction"}, QVariant::fromValue(m_propertyEditorTransaction.data())}
|
||||
}
|
||||
);
|
||||
|
||||
contextObject()->setSpecificsUrl(qmlSpecificsFile);
|
||||
|
||||
|
@@ -102,9 +102,12 @@ StatesEditorWidget::StatesEditorWidget(StatesEditorView *statesEditorView, State
|
||||
setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
rootContext()->setContextProperty(QStringLiteral("statesEditorModel"), statesEditorModel);
|
||||
|
||||
rootContext()->setContextProperty(QLatin1String("canAddNewStates"), true);
|
||||
rootContext()->setContextProperties(
|
||||
QVector<QQmlContext::PropertyPair>{
|
||||
{{"statesEditorModel"}, QVariant::fromValue(statesEditorModel)},
|
||||
{{"canAddNewStates"}, true}
|
||||
}
|
||||
);
|
||||
|
||||
Theme::setupTheme(engine());
|
||||
|
||||
|
@@ -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 equal = false;
|
||||
if (import.isLibraryImport())
|
||||
return toString(ast->importUri) == import.url();
|
||||
equal = toString(ast->importUri) == import.url();
|
||||
else if (import.isFileImport())
|
||||
return ast->fileName == import.file();
|
||||
else
|
||||
return false;
|
||||
equal = ast->fileName == import.file();
|
||||
|
||||
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;
|
||||
}
|
||||
|
@@ -182,8 +182,13 @@ public:
|
||||
const QList<ModelNode> wildcards() const;
|
||||
const QList<ModelNode> decicions() const;
|
||||
QList<ModelNode> transitionsForTarget(const ModelNode &modelNode);
|
||||
QList<ModelNode> transitionsForSource(const ModelNode &modelNode);
|
||||
void removeDanglingTransitions();
|
||||
void removeAllTransitions();
|
||||
void setStartFlowItem(const QmlFlowItemNode &flowItem);
|
||||
ModelNode createTransition();
|
||||
protected:
|
||||
QList<ModelNode> transitionsForProperty(const PropertyName &propertyName, const ModelNode &modelNode);
|
||||
};
|
||||
|
||||
|
||||
|
@@ -650,7 +650,7 @@ PropertyName NodeMetaInfoPrivate::defaultPropertyName() const
|
||||
|
||||
static inline TypeName stringIdentifier( const TypeName &type, int maj, int min)
|
||||
{
|
||||
return type + QString::number(maj).toLatin1() + '_' + QString::number(min).toLatin1();
|
||||
return type + QByteArray::number(maj) + '_' + QByteArray::number(min);
|
||||
}
|
||||
|
||||
NodeMetaInfoPrivate::Pointer NodeMetaInfoPrivate::create(Model *model, const TypeName &type, int major, int minor)
|
||||
|
@@ -420,8 +420,7 @@ void SubComponentManager::parseQuick3DAssetDir(const QString &assetPath)
|
||||
itemLibraryEntry.addHints(hints);
|
||||
}
|
||||
|
||||
if (!model()->metaInfo().itemLibraryInfo()->containsEntry(itemLibraryEntry))
|
||||
model()->metaInfo().itemLibraryInfo()->addEntries({itemLibraryEntry});
|
||||
model()->metaInfo().itemLibraryInfo()->addEntries({itemLibraryEntry}, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -664,9 +664,7 @@ QList<QmlFlowItemNode> QmlFlowViewNode::flowItems() const
|
||||
|
||||
ModelNode QmlFlowViewNode::addTransition(const QmlFlowTargetNode &from, const QmlFlowTargetNode &to)
|
||||
{
|
||||
ModelNode transition = view()->createModelNode("FlowView.FlowTransition", 1, 0);
|
||||
|
||||
nodeListProperty("flowTransitions").reparentHere(transition);
|
||||
ModelNode transition = createTransition();
|
||||
|
||||
QmlFlowTargetNode f = from;
|
||||
QmlFlowTargetNode t = to;
|
||||
@@ -684,8 +682,6 @@ const QList<ModelNode> QmlFlowViewNode::transitions() const
|
||||
return modelNode().nodeListProperty("flowTransitions").toModelNodeList();
|
||||
|
||||
return {};
|
||||
|
||||
|
||||
}
|
||||
|
||||
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> list;
|
||||
for (const ModelNode &transition : transitions()) {
|
||||
if (transition.hasBindingProperty("to")
|
||||
&& transition.bindingProperty("to").resolveToModelNode() == modelNode)
|
||||
list.append(transition);
|
||||
}
|
||||
return list;
|
||||
return transitionsForProperty("to", modelNode);
|
||||
}
|
||||
|
||||
QList<ModelNode> QmlFlowViewNode::transitionsForSource(const ModelNode &modelNode)
|
||||
{
|
||||
return transitionsForProperty("from", modelNode);
|
||||
}
|
||||
|
||||
void QmlFlowViewNode::removeDanglingTransitions()
|
||||
@@ -830,4 +825,41 @@ void QmlFlowViewNode::removeAllTransitions()
|
||||
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
|
||||
|
@@ -381,11 +381,21 @@ void QmlObjectNode::destroy()
|
||||
timeline.destroyKeyframesForTarget(subNode);
|
||||
}
|
||||
|
||||
if (QmlFlowActionAreaNode::isValidQmlFlowActionAreaNode(modelNode()))
|
||||
QmlFlowActionAreaNode(modelNode()).destroyTarget();
|
||||
bool wasFlowEditorTarget = false;
|
||||
if (QmlFlowTargetNode::isFlowEditorTarget(modelNode())) {
|
||||
QmlFlowTargetNode(modelNode()).destroyTargets();
|
||||
wasFlowEditorTarget = true;
|
||||
}
|
||||
|
||||
removeStateOperationsForChildren(modelNode());
|
||||
BindingProperty::deleteAllReferencesTo(modelNode());
|
||||
|
||||
QmlFlowViewNode root(view()->rootModelNode());
|
||||
|
||||
modelNode().destroy();
|
||||
|
||||
if (wasFlowEditorTarget && root.isValid())
|
||||
root.removeDanglingTransitions();
|
||||
}
|
||||
|
||||
void QmlObjectNode::ensureAliasExport()
|
||||
|
@@ -84,6 +84,7 @@ void DesignerSettings::fromSettings(QSettings *settings)
|
||||
);
|
||||
restoreValue(settings, DesignerSettingsKey::SIMPLE_COLOR_PALETTE_CONTENT, QStringList());
|
||||
restoreValue(settings, DesignerSettingsKey::ALWAYS_DESIGN_MODE, true);
|
||||
restoreValue(settings, DesignerSettingsKey::DISABLE_ITEM_LIBRARY_UPDATE_TIMER, true);
|
||||
|
||||
settings->endGroup();
|
||||
settings->endGroup();
|
||||
|
@@ -38,6 +38,7 @@
|
||||
#include <sourcetool/sourcetool.h>
|
||||
#include <colortool/colortool.h>
|
||||
#include <annotationeditor/annotationtool.h>
|
||||
#include <formeditor/transitiontool.h>
|
||||
#include <texttool/texttool.h>
|
||||
#include <timelineeditor/timelineview.h>
|
||||
#include <pathtool/pathtool.h>
|
||||
@@ -247,6 +248,7 @@ bool QmlDesignerPlugin::delayedInitialize()
|
||||
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::AnnotationTool);
|
||||
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::TextTool);
|
||||
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::PathTool);
|
||||
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::TransitionTool);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -530,6 +530,8 @@ Project {
|
||||
"formeditor/toolbox.h",
|
||||
"formeditor/formeditortoolbutton.cpp",
|
||||
"formeditor/formeditortoolbutton.h",
|
||||
"formeditor/transitiontool.cpp",
|
||||
"formeditor/transitiontool.h",
|
||||
"importmanager/importlabel.cpp",
|
||||
"importmanager/importlabel.h",
|
||||
"importmanager/importmanagercombobox.cpp",
|
||||
|
@@ -791,7 +791,7 @@ void QmlJSEditorWidget::findLinkAt(const QTextCursor &cursor,
|
||||
const QString relative = QString::fromLatin1("%1/%2").arg(
|
||||
semanticInfo.document->path(),
|
||||
text);
|
||||
if (semanticInfo.snapshot.document(relative)) {
|
||||
if (QFileInfo::exists(relative)) {
|
||||
link.targetFileName = relative;
|
||||
processLinkCallback(link);
|
||||
return;
|
||||
|
@@ -2034,6 +2034,9 @@ FilePaths BaseQtVersionPrivate::qtCorePaths()
|
||||
else if (file.endsWith(".dll")
|
||||
|| file.endsWith(QString::fromLatin1(".so.") + versionString)
|
||||
|| file.endsWith(".so")
|
||||
#if defined(Q_OS_OPENBSD)
|
||||
|| file.contains(QRegularExpression("\\.so\\.[0-9]+\\.[0-9]+$")) // QTCREATORBUG-23818
|
||||
#endif
|
||||
|| file.endsWith(QLatin1Char('.') + versionString + ".dylib"))
|
||||
dynamicLibs.append(FilePath::fromFileInfo(info));
|
||||
}
|
||||
|
@@ -107,6 +107,7 @@
|
||||
#include <QPropertyAnimation>
|
||||
#include <QDrag>
|
||||
#include <QSequentialAnimationGroup>
|
||||
#include <QScreen>
|
||||
#include <QScrollBar>
|
||||
#include <QShortcut>
|
||||
#include <QStyle>
|
||||
@@ -1199,7 +1200,11 @@ void TextEditorWidgetPrivate::print(QPrinter *printer)
|
||||
QAbstractTextDocumentLayout *layout = doc->documentLayout();
|
||||
layout->setPaintDevice(p.device());
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
int dpiy = p.device()->logicalDpiY();
|
||||
#else
|
||||
int dpiy = qRound(QGuiApplication::primaryScreen()->logicalDotsPerInchY());
|
||||
#endif
|
||||
int margin = int((2/2.54)*dpiy); // 2 cm margins
|
||||
|
||||
QTextFrameFormat fmt = doc->rootFrame()->frameFormat();
|
||||
|
@@ -4706,14 +4706,19 @@ void tst_Dumpers::dumper_data()
|
||||
|
||||
QTest::newRow("StdUniquePtr")
|
||||
<< Data("#include <memory>\n"
|
||||
"#include <string>\n" + fooData,
|
||||
"#include <string>\n" + fooData +
|
||||
|
||||
"static Foo *alloc_foo() { return new Foo; }\n"
|
||||
"static void free_foo(Foo *f) { delete f; }\n",
|
||||
|
||||
"std::unique_ptr<int> p0;\n\n"
|
||||
"std::unique_ptr<int> p1(new int(32));\n\n"
|
||||
"std::unique_ptr<Foo> p2(new Foo);\n\n"
|
||||
"std::unique_ptr<std::string> p3(new std::string(\"ABC\"));",
|
||||
"std::unique_ptr<std::string> p3(new std::string(\"ABC\"));\n"
|
||||
|
||||
"&p0, &p1, &p2, &p3")
|
||||
"std::unique_ptr<Foo, void(*)(Foo*)> p4{alloc_foo(), free_foo};",
|
||||
|
||||
"&p0, &p1, &p2, &p3, &p4")
|
||||
|
||||
+ CoreProfile()
|
||||
+ Cxx11Profile()
|
||||
@@ -4722,7 +4727,8 @@ void tst_Dumpers::dumper_data()
|
||||
+ Check("p0", "(null)", "std::unique_ptr<int, std::default_delete<int> >")
|
||||
+ Check("p1", "32", "std::unique_ptr<int, std::default_delete<int> >")
|
||||
+ Check("p2", Pointer(), "std::unique_ptr<Foo, std::default_delete<Foo> >")
|
||||
+ Check("p3", "\"ABC\"", "std::unique_ptr<std::string, std::default_delete<std::string> >");
|
||||
+ Check("p3", "\"ABC\"", "std::unique_ptr<std::string, std::default_delete<std::string> >")
|
||||
+ Check("p4.b", "2", "int");
|
||||
|
||||
|
||||
QTest::newRow("StdOnce")
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user