Merge remote-tracking branch 'origin/8.0'

Conflicts:
	src/libs/qmljs/qmljsmodelmanagerinterface.cpp
	src/plugins/clangcodemodel/clangdclient.cpp
	src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp
	src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp
	src/plugins/qmldesigner/designercore/include/modelnode.h
	src/plugins/qmldesigner/designercore/model/modelnode.cpp
	src/plugins/qmldesigner/designercore/model/rewriterview.cpp

Change-Id: I93c57879b79f27325321bfc045ca618bd835af93
This commit is contained in:
Eike Ziller
2022-08-26 08:40:23 +02:00
57 changed files with 379 additions and 219 deletions

View File

@@ -456,16 +456,16 @@
The installation folder contains the CDB command line executable
(\c cdb.exe).
\li Copy the \QC CDB extension library from the Qt installation
directory to the a new folder on the remote machine (32 or 64 bit
\li Copy the \QC CDB extension library and the dependencies from the Qt installation
directory to a new folder on the remote machine (32 or 64 bit
version depending on the version of the Debugging Tools for Windows
used):
\list
\li \c {\lib\qtcreatorcdbext32\qtcreatorcdbext.dll} (32 bit)
\li \c {\lib\qtcreatorcdbext32} (32 bit)
\li \c {\lib\qtcreatorcdbext64\qtcreatorcdbext.dll} (64 bit)
\li \c {\lib\qtcreatorcdbext64} (64 bit)
\endlist

View File

@@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
@@ -154,7 +154,7 @@
\li Start the application with the following arguments:
\c {qmljsdebugger=port:<port>[,host:<ip address>][,block]}
\c {-qmljsdebugger=port:<port>[,host:<ip address>][,block]}
Where \c port (mandatory) specifies the debugging port,
\c {ip address} (optional) specifies the IP address of the host

View File

@@ -165,15 +165,16 @@
To disable the Python language server, deselect
\uicontrol {Use Python Language Server}.
\section2 Qml Language Server
\section2 QML Language Server
Qt 6.4 ships with the qmlls language server that provides completions and warnings for QML.
It can be set up as a \l {Generic StdIO Language Server}, selecting \c {text/x-qml} and
\c {application/x-qt.ui+qml} as MIME Types, and \c {<Qt Installation>/bin/qmlls} as executable.
Qt 6.4 ships with the \c qmlls language server that provides completion and
warnings for QML. To set it up as a \l {Generic StdIO Language Server},
select \c {text/x-qml} and \c {application/x-qt.ui+qml} as MIME types, and
\c {<Qt Installation>/bin/qmlls} as executable.
If the language server is used together with the QmlJSEditor plugin duplicate suggestions and
warnings might be shown. To avoid this you might want to disable it as described in
\l {Enabling and Disabling Plugins}.
If the language server is used together with the \c QmlJSEditor plugin,
duplicate suggestions and warnings might be shown. To avoid this, disable
the editor plugin as described in \l {Enabling and Disabling Plugins}.
\section1 Supported Locator Filters

View File

@@ -363,7 +363,7 @@ Item {
}
}
function handleObjectClicked(object, multi)
function handleObjectClicked(object, button, multi)
{
if (object instanceof View3D) {
// View3D can be the resolved pick target in case the 3D editor is showing content
@@ -393,7 +393,14 @@ Item {
// Null object always clears entire selection
var newSelection = [];
if (clickedObject) {
if (multi && selectedNodes.length > 0) {
if (button === Qt.RightButton) {
// Right-clicking does only single selection (when clickedObject is unselected)
// This is needed for selecting a target for the context menu
if (!selectedNodes.includes(clickedObject))
newSelection[0] = clickedObject;
else
newSelection = selectedNodes;
} else if (multi && selectedNodes.length > 0) {
var deselect = false;
for (var i = 0; i < selectedNodes.length; ++i) {
// Multiselecting already selected object clears that object from selection
@@ -697,10 +704,10 @@ Item {
view3D: overlayView
dragHelper: gizmoDragHelper
onPropertyValueCommit: (propName)=> {
onPropertyValueCommit: (propName) => {
viewRoot.commitObjectProperty([targetNode], [propName]);
}
onPropertyValueChange: (propName)=> {
onPropertyValueChange: (propName) => {
viewRoot.changeObjectProperty([targetNode], [propName]);
}
}
@@ -772,17 +779,17 @@ Item {
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton
acceptedButtons: Qt.LeftButton | Qt.RightButton
hoverEnabled: false
property MouseArea3D freeDraggerArea
property point pressPoint
property bool initialMoveBlock: false
onPressed: (mouse)=> {
onPressed: (mouse) => {
if (viewRoot.editView) {
var pickResult = viewRoot.editView.pick(mouse.x, mouse.y);
handleObjectClicked(_generalHelper.resolvePick(pickResult.objectHit),
handleObjectClicked(_generalHelper.resolvePick(pickResult.objectHit), mouse.button,
mouse.modifiers & Qt.ControlModifier);
if (pickResult.objectHit && pickResult.objectHit instanceof Node) {
@@ -800,7 +807,7 @@ Item {
}
}
}
onPositionChanged: (mouse)=> {
onPositionChanged: (mouse) => {
if (freeDraggerArea) {
if (initialMoveBlock && Math.abs(pressPoint.x - mouse.x) + Math.abs(pressPoint.y - mouse.y) > 10) {
// Don't force press event at actual press, as that puts the gizmo
@@ -825,10 +832,10 @@ Item {
}
}
onReleased: (mouse)=> {
onReleased: (mouse) => {
handleRelease(mouse);
}
onCanceled: (mouse)=> {
onCanceled: (mouse) => {
handleRelease(mouse);
}
}

View File

@@ -363,7 +363,7 @@ Item {
}
}
function handleObjectClicked(object, multi)
function handleObjectClicked(object, button, multi)
{
if (object instanceof View3D) {
// View3D can be the resolved pick target in case the 3D editor is showing content
@@ -393,7 +393,14 @@ Item {
// Null object always clears entire selection
var newSelection = [];
if (clickedObject) {
if (multi && selectedNodes.length > 0) {
if (button === Qt.RightButton) {
// Right-clicking does only single selection (when clickedObject is unselected)
// This is needed for selecting a target for the context menu
if (!selectedNodes.includes(clickedObject))
newSelection[0] = clickedObject;
else
newSelection = selectedNodes;
} else if (multi && selectedNodes.length > 0) {
var deselect = false;
for (var i = 0; i < selectedNodes.length; ++i) {
// Multiselecting already selected object clears that object from selection
@@ -841,10 +848,10 @@ Item {
view3D: overlayView
dragHelper: gizmoDragHelper
onPropertyValueCommit: (propName)=> {
onPropertyValueCommit: (propName) => {
viewRoot.commitObjectProperty([targetNode], [propName]);
}
onPropertyValueChange: (propName)=> {
onPropertyValueChange: (propName) => {
viewRoot.changeObjectProperty([targetNode], [propName]);
}
}
@@ -917,14 +924,14 @@ Item {
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton
acceptedButtons: Qt.LeftButton | Qt.RightButton
hoverEnabled: false
property MouseArea3D freeDraggerArea
property point pressPoint
property bool initialMoveBlock: false
onPressed: (mouse)=> {
onPressed: (mouse) => {
if (viewRoot.editView) {
// First pick overlay to check for hits there
var pickResult = _generalHelper.pickViewAt(overlayView, mouse.x, mouse.y);
@@ -935,7 +942,7 @@ Item {
resolvedResult = _generalHelper.resolvePick(pickResult.objectHit);
}
handleObjectClicked(resolvedResult, mouse.modifiers & Qt.ControlModifier);
handleObjectClicked(resolvedResult, mouse.button, mouse.modifiers & Qt.ControlModifier);
if (pickResult.objectHit && pickResult.objectHit instanceof Node) {
if (transformMode === EditView3D.TransformMode.Move)
@@ -952,7 +959,7 @@ Item {
}
}
}
onPositionChanged: (mouse)=> {
onPositionChanged: (mouse) => {
if (freeDraggerArea) {
if (initialMoveBlock && Math.abs(pressPoint.x - mouse.x) + Math.abs(pressPoint.y - mouse.y) > 10) {
// Don't force press event at actual press, as that puts the gizmo
@@ -977,10 +984,10 @@ Item {
}
}
onReleased: (mouse)=> {
onReleased: (mouse) => {
handleRelease(mouse);
}
onCanceled: (mouse)=> {
onCanceled: (mouse) => {
handleRelease(mouse);
}
}

View File

@@ -67,11 +67,6 @@ View3D {
id: model
source: _generalHelper.resolveAbsoluteSourceUrl(sourceModel)
geometry: sourceModel.geometry
materials: [
DefaultMaterial {
diffuseColor: "#999999"
}
]
materials: sourceModel.materials
}
}

View File

@@ -1050,6 +1050,21 @@ ServerNodeInstance NodeInstanceServer::rootNodeInstance() const
return m_rootNodeInstance;
}
QList<ServerNodeInstance> NodeInstanceServer::allGroupStateInstances() const
{
QList<ServerNodeInstance> groups;
std::copy_if(nodeInstances().cbegin(),
nodeInstances().cend(),
std::back_inserter(groups),
[](const ServerNodeInstance &instance) {
return instance.isValid() && instance.internalObject()->metaObject()
&& instance.internalObject()->metaObject()->className()
== QByteArrayLiteral("QQuickStateGroup");
});
return groups;
}
void NodeInstanceServer::setStateInstance(const ServerNodeInstance &stateInstance)
{
m_activeStateInstance = stateInstance;

View File

@@ -200,6 +200,8 @@ public:
ServerNodeInstance rootNodeInstance() const;
QList<ServerNodeInstance> allGroupStateInstances() const;
void notifyPropertyChange(qint32 instanceid, const PropertyName &propertyName);
QByteArray importCode() const;

View File

@@ -46,6 +46,10 @@
#include <QLibraryInfo>
#include <QJSValue>
#include <private/qquickstategroup_p.h>
#include <qquickitem.h>
static bool isSimpleExpression(const QString &expression)
{
if (expression.startsWith(QStringLiteral("{")))
@@ -456,6 +460,10 @@ QVariant ObjectNodeInstance::convertEnumToValue(const QVariant &value, const Pro
void ObjectNodeInstance::setPropertyVariant(const PropertyName &name, const QVariant &value)
{
if (name == "state" && object() && object()->metaObject()
&& object()->metaObject()->className() == QByteArrayLiteral("QQuickStateGroup"))
return;
if (ignoredProperties().contains(name))
return;
@@ -652,8 +660,18 @@ QList<QQuickItem *> ObjectNodeInstance::allItemsRecursive() const
return QList<QQuickItem *>();
}
QList<ServerNodeInstance> ObjectNodeInstance::stateInstances() const
QList<ServerNodeInstance> ObjectNodeInstance::stateInstances() const
{
if (auto group = qobject_cast<QQuickStateGroup*>(object())) {
QList<ServerNodeInstance> instanceList;
const QList<QQuickState *> stateList = group->states();
for (QQuickState *state : stateList) {
if (state && nodeInstanceServer()->hasInstanceForObject(state))
instanceList.append(nodeInstanceServer()->instanceForObject(state));
}
return instanceList;
}
return QList<ServerNodeInstance>();
}

View File

@@ -87,8 +87,7 @@ void QmlStateNodeInstance::deactivateState()
void QmlStateNodeInstance::setPropertyVariant(const PropertyName &name, const QVariant &value)
{
bool isStateOfTheRootModelNode = parentInstance() && parentInstance()->isRootNodeInstance();
if (name == "when" && (isStateOfTheRootModelNode))
if (name == "when")
return;
ObjectNodeInstance::setPropertyVariant(name, value);

View File

@@ -285,12 +285,16 @@ void Qt5InformationNodeInstanceServer::handleInputEvents()
continue;
}
}
auto me = new QMouseEvent(command.type(), command.pos(), command.button(),
command.buttons(), command.modifiers());
QMouseEvent me(command.type(), command.pos(), command.button(), command.buttons(),
command.modifiers());
// We must use sendEvent in Qt 6, as using postEvent allows the associated position
// data stored internally in QMutableEventPoint to potentially be updated by system
// before the event is delivered.
QGuiApplication::sendEvent(m_editView3DData.window, me);
QGuiApplication::sendEvent(m_editView3DData.window, &me);
// Context menu requested
if (command.button() == Qt::RightButton && command.modifiers() == Qt::NoModifier)
getModelAtPos(command.pos());
}
}
@@ -405,6 +409,30 @@ void Qt5InformationNodeInstanceServer::removeRotationBlocks(
#endif
}
void Qt5InformationNodeInstanceServer::getModelAtPos(const QPointF &pos)
{
#ifdef QUICK3D_MODULE
// pick a Quick3DModel at view position
auto helper = qobject_cast<QmlDesigner::Internal::GeneralHelper *>(m_3dHelper);
if (!helper)
return;
QQmlProperty editViewProp(m_editView3DData.rootItem, "editView", context());
QObject *obj = qvariant_cast<QObject *>(editViewProp.read());
QQuick3DViewport *editView = qobject_cast<QQuick3DViewport *>(obj);
QQuick3DModel *hitModel = helper->pickViewAt(editView, pos.x(), pos.y()).objectHit();
// filter out picks of models created dynamically or inside components
QQuick3DModel *resolvedPick = qobject_cast<QQuick3DModel *>(helper->resolvePick(hitModel));
QVariant instance = resolvedPick ? instanceForObject(resolvedPick).instanceId() : -1;
nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::ModelAtPos, instance});
#else
Q_UNUSED(pos)
#endif
}
void Qt5InformationNodeInstanceServer::createEditView3D()
{
#ifdef QUICK3D_MODULE
@@ -2383,26 +2411,7 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c
#endif
#ifdef QUICK3D_MODULE
case View3DActionCommand::GetModelAtPos: {
// pick a Quick3DModel at view position
auto helper = qobject_cast<QmlDesigner::Internal::GeneralHelper *>(m_3dHelper);
if (!helper)
return;
QQmlProperty editViewProp(m_editView3DData.rootItem, "editView", context());
QObject *obj = qvariant_cast<QObject *>(editViewProp.read());
QQuick3DViewport *editView = qobject_cast<QQuick3DViewport *>(obj);
QPointF pos = command.value().toPointF();
QQuick3DModel *hitModel = helper->pickViewAt(editView, pos.x(), pos.y()).objectHit();
// filter out picks of models created dynamically or inside components
QQuick3DModel *resolvedPick = qobject_cast<QQuick3DModel *>(helper->resolvePick(hitModel));
if (resolvedPick) {
ServerNodeInstance instance = instanceForObject(resolvedPick);
nodeInstanceClient()->handlePuppetToCreatorCommand(
{PuppetToCreatorCommand::ModelAtPos, QVariant(instance.instanceId())});
}
getModelAtPos(command.value().toPointF());
return;
}
#endif

View File

@@ -148,6 +148,7 @@ private:
void updateMaterialPreviewData(const QVector<PropertyValueContainer> &valueChanges);
void updateRotationBlocks(const QVector<PropertyValueContainer> &valueChanges);
void removeRotationBlocks(const QVector<qint32> &instanceIds);
void getModelAtPos(const QPointF &pos);
void createAuxiliaryQuickView(const QUrl &url, RenderViewData &viewData);
#ifdef QUICK3D_PARTICLES_MODULE

View File

@@ -77,13 +77,23 @@ void Qt5PreviewNodeInstanceServer::collectItemChangesAndSendChangeCommands()
QVector<ImageContainer> imageContainerVector;
imageContainerVector.append(ImageContainer(0, renderPreviewImage(), -1));
foreach (ServerNodeInstance instance, rootNodeInstance().stateInstances()) {
instance.activateState();
QImage previewImage = renderPreviewImage();
if (!previewImage.isNull())
imageContainerVector.append(ImageContainer(instance.instanceId(), renderPreviewImage(), instance.instanceId()));
instance.deactivateState();
}
QList<ServerNodeInstance> stateInstances = rootNodeInstance().stateInstances();
const QList<ServerNodeInstance> groupInstances = allGroupStateInstances();
for (ServerNodeInstance instance : groupInstances) {
stateInstances.append(instance.stateInstances());
}
for (ServerNodeInstance instance : qAsConst(stateInstances)) {
instance.activateState();
QImage previewImage = renderPreviewImage();
if (!previewImage.isNull())
imageContainerVector.append(ImageContainer(instance.instanceId(),
renderPreviewImage(),
instance.instanceId()));
instance.deactivateState();
}
nodeInstanceClient()->statePreviewImagesChanged(
StatePreviewImageChangedCommand(imageContainerVector));

View File

@@ -111,6 +111,7 @@ ModelManagerInterface::ModelManagerInterface(QObject *parent)
m_defaultImportPaths(environmentImportPaths()),
m_pluginDumper(new PluginDumper(this))
{
m_threadPool.setMaxThreadCount(4);
m_futureSynchronizer.setCancelOnWait(false);
m_indexerDisabled = qEnvironmentVariableIsSet("QTC_NO_CODE_INDEXER");
@@ -325,6 +326,11 @@ Snapshot ModelManagerInterface::newestSnapshot() const
return m_newestSnapshot;
}
QThreadPool *ModelManagerInterface::threadPool()
{
return &m_threadPool;
}
void ModelManagerInterface::updateSourceFiles(const QList<Utils::FilePath> &files,
bool emitDocumentOnDiskChanged)
{
@@ -339,7 +345,8 @@ QFuture<void> ModelManagerInterface::refreshSourceFiles(const QList<Utils::FileP
if (sourceFiles.isEmpty())
return QFuture<void>();
QFuture<void> result = Utils::runAsync(&ModelManagerInterface::parse,
QFuture<void> result = Utils::runAsync(&m_threadPool,
&ModelManagerInterface::parse,
workingCopyInternal(), sourceFiles,
this, Dialect(Dialect::Qml),
emitDocumentOnDiskChanged);
@@ -366,7 +373,8 @@ QFuture<void> ModelManagerInterface::refreshSourceFiles(const QList<Utils::FileP
void ModelManagerInterface::fileChangedOnDisk(const Utils::FilePath &path)
{
addFuture(Utils::runAsync(&ModelManagerInterface::parse,
addFuture(Utils::runAsync(&m_threadPool,
&ModelManagerInterface::parse,
workingCopyInternal(),
FilePaths({path}),
this,
@@ -1199,7 +1207,8 @@ void ModelManagerInterface::maybeScan(const PathsAndLanguages &importPaths)
}
if (pathToScan.length() >= 1) {
QFuture<void> result = Utils::runAsync(&ModelManagerInterface::importScan,
QFuture<void> result = Utils::runAsync(&m_threadPool,
&ModelManagerInterface::importScan,
workingCopyInternal(), pathToScan,
this, true, true, false);
addFuture(result);

View File

@@ -41,6 +41,7 @@
#include <QObject>
#include <QPointer>
#include <QStringList>
#include <QThreadPool>
QT_FORWARD_DECLARE_CLASS(QTimer)
@@ -133,6 +134,7 @@ public:
QmlJS::Snapshot snapshot() const;
QmlJS::Snapshot newestSnapshot() const;
QThreadPool *threadPool();
void activateScan();
void updateSourceFiles(const QList<Utils::FilePath> &files, bool emitDocumentOnDiskChanged);
@@ -292,6 +294,7 @@ private:
Utils::FutureSynchronizer m_futureSynchronizer;
bool m_indexerDisabled = false;
QThreadPool m_threadPool;
};
} // namespace QmlJS

View File

@@ -296,7 +296,8 @@ void PluginDumper::qmlPluginTypeDumpDone(QtcProcess *process)
QStringList dependencies;
};
auto future = Utils::runAsync([output, libraryPath](QFutureInterface<CppQmlTypesInfo>& future)
auto future = Utils::runAsync(m_modelManager->threadPool(),
[output, libraryPath](QFutureInterface<CppQmlTypesInfo>& future)
{
CppQmlTypesInfo infos;
CppQmlTypesLoader::parseQmlTypeDescriptions(output, &infos.objectsList, &infos.moduleApis, &infos.dependencies,
@@ -349,7 +350,7 @@ void PluginDumper::pluginChanged(const QString &pluginLibrary)
QFuture<PluginDumper::QmlTypeDescription> PluginDumper::loadQmlTypeDescription(const FilePaths &paths) const
{
auto future = Utils::runAsync([=](QFutureInterface<PluginDumper::QmlTypeDescription> &future)
auto future = Utils::runAsync(m_modelManager->threadPool(), [=](QFutureInterface<PluginDumper::QmlTypeDescription> &future)
{
PluginDumper::QmlTypeDescription result;

View File

@@ -69,6 +69,7 @@
#include <texteditor/codeassist/textdocumentmanipulatorinterface.h>
#include <texteditor/texteditor.h>
#include <utils/algorithm.h>
#include <utils/environment.h>
#include <utils/fileutils.h>
#include <utils/itemviews.h>
#include <utils/runextensions.h>

View File

@@ -815,7 +815,11 @@ void addNewSignalHandler(const SelectionContext &selectionState)
// Open a model's material in the material editor
void editMaterial(const SelectionContext &selectionContext)
{
ModelNode modelNode = selectionContext.currentSingleSelectedNode();
ModelNode modelNode = selectionContext.targetNode();
if (!modelNode.isValid())
modelNode = selectionContext.currentSingleSelectedNode();
QTC_ASSERT(modelNode.isValid(), return);
BindingProperty prop = modelNode.bindingProperty("materials");

View File

@@ -71,10 +71,6 @@ CurveEditor::CurveEditor(CurveEditorModel *model, QWidget *parent)
box->addWidget(m_statusLine);
setLayout(box);
connect(m_toolbar, &CurveEditorToolBar::defaultClicked, [this]() {
m_view->setDefaultInterpolation();
});
connect(m_toolbar, &CurveEditorToolBar::unifyClicked, [this]() {
m_view->toggleUnified();
});
@@ -99,6 +95,13 @@ CurveEditor::CurveEditor(CurveEditorModel *model, QWidget *parent)
m_view->viewport()->update();
});
connect(m_toolbar, &CurveEditorToolBar::zoomChanged, [this](double zoom) {
const bool wasBlocked = m_view->blockSignals(true);
m_view->setZoomX(zoom);
m_view->blockSignals(wasBlocked);
m_view->viewport()->update();
});
connect(
m_view, &GraphicsView::currentFrameChanged,
m_toolbar, &CurveEditorToolBar::setCurrentFrame);
@@ -110,6 +113,11 @@ CurveEditor::CurveEditor(CurveEditorModel *model, QWidget *parent)
m_tree->selectionModel(), &SelectionModel::curvesSelected,
m_view, &GraphicsView::updateSelection);
connect(m_view, &GraphicsView::zoomChanged, [this](double x, double y) {
Q_UNUSED(y);
m_toolbar->setZoom(x);
});
auto updateTimeline = [this, model](bool validTimeline) {
if (validTimeline) {
updateStatusLine();

View File

@@ -67,7 +67,6 @@ CurveEditorToolBar::CurveEditorToolBar(CurveEditorModel *model, QWidget* parent)
QAction *tangentSplineAction = addAction(
QIcon(":/curveeditor/images/tangetToolsSplineIcon.png"), "Spline");
QAction *tangentDefaultAction = addAction(tr("Set Default"));
QAction *tangentUnifyAction = addAction(tr("Unify"));
auto setLinearInterpolation = [this]() {
@@ -79,9 +78,6 @@ CurveEditorToolBar::CurveEditorToolBar(CurveEditorModel *model, QWidget* parent)
auto setSplineInterpolation = [this]() {
emit interpolationClicked(Keyframe::Interpolation::Bezier);
};
auto setDefaultKeyframe = [this]() {
emit defaultClicked();
};
auto toggleUnifyKeyframe = [this]() {
emit unifyClicked();
};
@@ -89,7 +85,6 @@ CurveEditorToolBar::CurveEditorToolBar(CurveEditorModel *model, QWidget* parent)
connect(tangentLinearAction, &QAction::triggered, setLinearInterpolation);
connect(tangentStepAction, &QAction::triggered, setStepInterpolation);
connect(tangentSplineAction, &QAction::triggered, setSplineInterpolation);
connect(tangentDefaultAction, &QAction::triggered, setDefaultKeyframe);
connect(tangentUnifyAction, &QAction::triggered, toggleUnifyKeyframe);
auto validateStart = [this](int val) -> bool {
@@ -100,6 +95,7 @@ CurveEditorToolBar::CurveEditorToolBar(CurveEditorModel *model, QWidget* parent)
m_startSpin = new ValidatableSpinBox(validateStart);
m_startSpin->setRange(std::numeric_limits<int>::lowest(), std::numeric_limits<int>::max());
m_startSpin->setValue(model->minimumTime());
m_startSpin->setFixedWidth(70);
connect(m_startSpin, &QSpinBox::valueChanged, this, &CurveEditorToolBar::startFrameChanged);
connect(model, &CurveEditorModel::commitStartFrame,
@@ -113,6 +109,7 @@ CurveEditorToolBar::CurveEditorToolBar(CurveEditorModel *model, QWidget* parent)
m_endSpin = new ValidatableSpinBox(validateEnd);
m_endSpin->setRange(std::numeric_limits<int>::lowest(), std::numeric_limits<int>::max());
m_endSpin->setValue(model->maximumTime());
m_endSpin->setFixedWidth(70);
connect(m_endSpin, &QSpinBox::valueChanged, this, &CurveEditorToolBar::endFrameChanged);
connect(model, &CurveEditorModel::commitEndFrame,
@@ -120,6 +117,7 @@ CurveEditorToolBar::CurveEditorToolBar(CurveEditorModel *model, QWidget* parent)
m_currentSpin->setMinimum(0);
m_currentSpin->setMaximum(std::numeric_limits<int>::max());
m_currentSpin->setFixedWidth(70);
connect(m_currentSpin, &QSpinBox::valueChanged, this, &CurveEditorToolBar::currentFrameChanged);
@@ -140,6 +138,19 @@ CurveEditorToolBar::CurveEditorToolBar(CurveEditorModel *model, QWidget* parent)
auto *positionWidget = new QWidget;
positionWidget->setLayout(positionBox);
addWidget(positionWidget);
m_zoomSlider = new QSlider(Qt::Horizontal);
m_zoomSlider->setRange(0, 100);
connect(m_zoomSlider, &QSlider::valueChanged, [this](int value) {
emit zoomChanged(static_cast<double>(value)/100.0f);
});
addWidget(m_zoomSlider);
}
void CurveEditorToolBar::setZoom(double zoom)
{
QSignalBlocker blocker(m_zoomSlider);
m_zoomSlider->setValue( static_cast<int>(zoom*100));
}
void CurveEditorToolBar::setCurrentFrame(int current, bool notify)

View File

@@ -26,6 +26,7 @@
#pragma once
#include <QSpinBox>
#include <QSlider>
#include <QToolBar>
#include <QValidator>
#include <QWidget>
@@ -53,8 +54,6 @@ class CurveEditorToolBar : public QToolBar
Q_OBJECT
signals:
void defaultClicked();
void unifyClicked();
void interpolationClicked(Keyframe::Interpolation interpol);
@@ -65,9 +64,13 @@ signals:
void currentFrameChanged(int current);
void zoomChanged(double zoom);
public:
CurveEditorToolBar(CurveEditorModel *model, QWidget* parent = nullptr);
void setZoom(double zoom);
void setCurrentFrame(int current, bool notify);
void updateBoundsSilent(int start, int end);
@@ -76,6 +79,7 @@ private:
ValidatableSpinBox *m_startSpin;
ValidatableSpinBox *m_endSpin;
QSpinBox *m_currentSpin;
QSlider *m_zoomSlider;
};
} // End namespace QmlDesigner.

View File

@@ -458,18 +458,6 @@ void CurveItem::setInterpolation(Keyframe::Interpolation interpolation)
emit curveChanged(id(), curve(true));
}
void CurveItem::setDefaultInterpolation()
{
if (m_keyframes.empty())
return;
for (auto *frame : qAsConst(m_keyframes)) {
if (frame->selected())
frame->setDefaultInterpolation();
}
emit curveChanged(id(), curve(true));
}
void CurveItem::toggleUnified()
{
if (m_keyframes.empty())

View File

@@ -125,8 +125,6 @@ public:
void setInterpolation(Keyframe::Interpolation interpolation);
void setDefaultInterpolation();
void toggleUnified();
void connect(GraphicsScene *scene);

View File

@@ -336,18 +336,6 @@ void GraphicsView::setInterpolation(Keyframe::Interpolation interpol)
viewport()->update();
}
void GraphicsView::setDefaultInterpolation()
{
const auto selectedCurves = m_scene->selectedCurves();
for (auto *curve : selectedCurves)
curve->setDefaultInterpolation();
m_scene->setDirty(true);
applyZoom(m_zoomX, m_zoomY);
viewport()->update();
}
void GraphicsView::toggleUnified()
{
const auto selectedCurves = m_scene->selectedCurves();
@@ -569,7 +557,10 @@ void GraphicsView::applyZoom(double x, double y, const QPoint &pivot)
}
m_scene->doNotMoveItems(false);
this->update();
viewport()->update();
emit zoomChanged(m_zoomX, m_zoomY);
}
void GraphicsView::drawGrid(QPainter *painter)

View File

@@ -49,6 +49,8 @@ class GraphicsView : public QGraphicsView
signals:
void currentFrameChanged(int frame, bool notify);
void zoomChanged(double x, double y);
public:
GraphicsView(CurveEditorModel *model, QWidget *parent = nullptr);
@@ -112,8 +114,6 @@ public:
void setInterpolation(Keyframe::Interpolation interpol);
void setDefaultInterpolation();
void toggleUnified();
protected:

View File

@@ -249,18 +249,6 @@ void KeyframeItem::setKeyframe(const Keyframe &keyframe)
setPos(m_transform.map(m_frame.position()));
}
void KeyframeItem::setDefaultInterpolation()
{
if (!m_left || !m_right)
return;
m_frame.setDefaultInterpolation();
setKeyframe(m_frame);
emit redrawCurve();
}
void KeyframeItem::toggleUnified()
{
if (!m_left || !m_right)

View File

@@ -92,8 +92,6 @@ public:
void setKeyframe(const Keyframe &keyframe);
void setDefaultInterpolation();
void toggleUnified();
void setActivated(bool active, HandleItem::Slot slot);

View File

@@ -154,15 +154,6 @@ void Keyframe::setPosition(const QPointF &pos)
m_position = pos;
}
void Keyframe::setDefaultInterpolation()
{
auto leftToRight = QLineF(m_leftHandle, m_rightHandle);
leftToRight.translate(m_position - leftToRight.center());
m_leftHandle = leftToRight.p1();
m_rightHandle = leftToRight.p2();
}
void Keyframe::setUnified(bool unified)
{
m_unified = unified;

View File

@@ -68,8 +68,6 @@ public:
Interpolation interpolation() const;
void setDefaultInterpolation();
void setUnified(bool unified);
void setPosition(const QPointF &pos);

View File

@@ -102,6 +102,9 @@ QWidget *Edit3DCanvas::busyIndicator() const
void Edit3DCanvas::mousePressEvent(QMouseEvent *e)
{
if (e->button() == Qt::RightButton && e->modifiers() == Qt::NoModifier)
m_parent->view()->startContextMenu(e->pos());
m_parent->view()->sendInputEvent(e);
QWidget::mousePressEvent(e);
}

View File

@@ -235,14 +235,29 @@ void Edit3DView::customNotification([[maybe_unused]] const AbstractView *view,
resetPuppet();
}
/**
* @brief get model at position from puppet process
*
* Response from puppet process for the model at requested position
*
* @param modelNode 3D model picked at the requested position, invalid node if no model exists
*/
void Edit3DView::modelAtPosReady(const ModelNode &modelNode)
{
if (!m_droppedMaterial.isValid() || !modelNode.isValid())
return;
executeInTransaction(__FUNCTION__, [&] {
assignMaterialTo3dModel(modelNode, m_droppedMaterial);
});
if (m_modelAtPosReqType == ModelAtPosReqType::ContextMenu) {
// Make sure right-clicked item is selected. Due to a bug in puppet side right-clicking an item
// while the context-menu is shown doesn't select the item.
if (modelNode.isValid() && !modelNode.isSelected())
setSelectedModelNode(modelNode);
m_edit3DWidget->showContextMenu(m_contextMenuPos, modelNode);
} else if (m_modelAtPosReqType == ModelAtPosReqType::MaterialDrop) {
if (m_droppedMaterial.isValid() && modelNode.isValid()) {
executeInTransaction(__FUNCTION__, [&] {
assignMaterialTo3dModel(modelNode, m_droppedMaterial);
});
}
}
m_modelAtPosReqType = ModelAtPosReqType::None;
}
void Edit3DView::sendInputEvent(QInputEvent *e) const
@@ -627,8 +642,17 @@ void Edit3DView::addQuick3DImport()
tr("Could not add QtQuick3D import to project."));
}
// This method is called upon right-clicking the view to prepare for context-menu creation. The actual
// context menu is created when modelAtPosReady() is received from puppet
void Edit3DView::startContextMenu(const QPoint &pos)
{
m_contextMenuPos = pos;
m_modelAtPosReqType = ModelAtPosReqType::ContextMenu;
}
void Edit3DView::dropMaterial(const ModelNode &matNode, const QPointF &pos)
{
m_modelAtPosReqType = ModelAtPosReqType::MaterialDrop;
m_droppedMaterial = matNode;
QmlDesignerPlugin::instance()->viewManager().nodeInstanceView()->view3DAction({View3DActionCommand::GetModelAtPos, pos});
}

View File

@@ -79,9 +79,16 @@ public:
void setSeeker(SeekerSlider *slider);
void addQuick3DImport();
void startContextMenu(const QPoint &pos);
void dropMaterial(const ModelNode &matNode, const QPointF &pos);
private:
enum class ModelAtPosReqType {
MaterialDrop,
ContextMenu,
None
};
void createEdit3DWidget();
void checkImports();
@@ -120,6 +127,8 @@ private:
int particlemode;
ModelCache<QImage> m_canvasCache;
ModelNode m_droppedMaterial;
ModelAtPosReqType m_modelAtPosReqType;
QPoint m_contextMenuPos;
};
} // namespace QmlDesigner

View File

@@ -30,6 +30,7 @@
#include "edit3dwidget.h"
#include "edit3dvisibilitytogglesmenu.h"
#include "metainfo.h"
#include "modelnodeoperations.h"
#include "qmldesignerconstants.h"
#include "qmldesignerplugin.h"
#include "qmlvisualnode.h"
@@ -49,8 +50,8 @@
namespace QmlDesigner {
Edit3DWidget::Edit3DWidget(Edit3DView *view) :
m_view(view)
Edit3DWidget::Edit3DWidget(Edit3DView *view)
: m_view(view)
{
setAcceptDrops(true);
@@ -146,6 +147,8 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view) :
handleActions(view->backgroundColorActions(), m_backgroundColorMenu, false);
createContextMenu();
view->setSeeker(seeker);
seeker->setToolTip(QLatin1String("Seek particle system time when paused."));
@@ -173,6 +176,23 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view) :
showCanvas(false);
}
void Edit3DWidget::createContextMenu()
{
m_contextMenu = new QMenu(this);
m_editMaterialAction = m_contextMenu->addAction(tr("Edit Material"), [&] {
SelectionContext selCtx(m_view);
selCtx.setTargetNode(m_contextMenuTarget);
ModelNodeOperations::editMaterial(selCtx);
});
m_deleteAction = m_contextMenu->addAction(tr("Delete"), [&] {
view()->executeInTransaction("Edit3DWidget::createContextMenu", [&] {
for (ModelNode &node : m_view->selectedModelNodes())
node.destroy();
});
});
}
void Edit3DWidget::contextHelp(const Core::IContext::HelpCallback &callback) const
{
if (m_view)
@@ -221,6 +241,16 @@ void Edit3DWidget::showBackgroundColorMenu(bool show, const QPoint &pos)
m_backgroundColorMenu->close();
}
void Edit3DWidget::showContextMenu(const QPoint &pos, const ModelNode &modelNode)
{
m_contextMenuTarget = modelNode;
m_editMaterialAction->setEnabled(modelNode.isValid());
m_deleteAction->setEnabled(modelNode.isValid());
m_contextMenu->popup(mapToGlobal(pos));
}
void Edit3DWidget::linkActivated([[maybe_unused]] const QString &link)
{
if (m_view)

View File

@@ -24,11 +24,13 @@
****************************************************************************/
#pragma once
#include <QtWidgets/qwidget.h>
#include <QtWidgets/qlabel.h>
#include <QtWidgets/qmenu.h>
#include <QtCore/qpointer.h>
#include <QLabel>
#include <QMenu>
#include <QPointer>
#include <QWidget>
#include <coreplugin/icontext.h>
#include <modelnode.h>
namespace QmlDesigner {
@@ -54,12 +56,15 @@ public:
QMenu *backgroundColorMenu() const;
void showBackgroundColorMenu(bool show, const QPoint &pos);
void showContextMenu(const QPoint &pos, const ModelNode &modelNode);
protected:
void dragEnterEvent(QDragEnterEvent *dragEnterEvent) override;
void dropEvent(QDropEvent *dropEvent) override;
private:
void linkActivated(const QString &link);
void createContextMenu();
QPointer<Edit3DView> m_edit3DView;
QPointer<Edit3DView> m_view;
@@ -69,6 +74,10 @@ private:
Core::IContext *m_context = nullptr;
QPointer<QMenu> m_visibilityTogglesMenu;
QPointer<QMenu> m_backgroundColorMenu;
QPointer<QMenu> m_contextMenu;
QPointer<QAction> m_editMaterialAction;
QPointer<QAction> m_deleteAction;
ModelNode m_contextMenuTarget;
};
} // namespace QmlDesigner

View File

@@ -95,8 +95,9 @@ bool MaterialBrowserModel::isValidIndex(int idx) const
* propertyGroups.json contains lists of QtQuick3D objects' properties grouped by sections
*
* @param path path to propertyGroups.json file
* @return load successful
*/
void MaterialBrowserModel::loadPropertyGroups(const QString &path)
bool MaterialBrowserModel::loadPropertyGroups(const QString &path)
{
bool ok = true;
@@ -131,6 +132,8 @@ void MaterialBrowserModel::loadPropertyGroups(const QString &path)
m_customMaterialSections.append(customMatSections);
}
emit materialSectionsChanged();
return ok;
}
QHash<int, QByteArray> MaterialBrowserModel::roleNames() const

View File

@@ -79,7 +79,7 @@ public:
void updateSelectedMaterial();
int materialIndex(const ModelNode &material) const;
ModelNode materialAt(int idx) const;
void loadPropertyGroups(const QString &path);
bool loadPropertyGroups(const QString &path);
void resetModel();

View File

@@ -128,14 +128,12 @@ void MaterialBrowserView::modelAttached(Model *model)
{
AbstractView::modelAttached(model);
QString matPropsPath = model->metaInfo("QtQuick3D.Material").importDirectoryPath()
+ "/designer/propertyGroups.json";
m_widget->materialBrowserModel()->loadPropertyGroups(matPropsPath);
m_widget->clearSearchFilter();
m_widget->materialBrowserModel()->setHasMaterialRoot(rootModelNode().isSubclassOf("QtQuick3D.Material"));
m_hasQuick3DImport = model->hasImport("QtQuick3D");
loadPropertyGroups();
// Project load is already very busy and may even trigger puppet reset, so let's wait a moment
// before refreshing the model
QTimer::singleShot(1000, this, [this]() {
@@ -286,6 +284,16 @@ void MaterialBrowserView::nodeRemoved([[maybe_unused]] const ModelNode &removedN
m_widget->materialBrowserModel()->updateSelectedMaterial();
}
void QmlDesigner::MaterialBrowserView::loadPropertyGroups()
{
if (!m_hasQuick3DImport || m_propertyGroupsLoaded)
return;
QString matPropsPath = model()->metaInfo("QtQuick3D.Material").importDirectoryPath()
+ "/designer/propertyGroups.json";
m_propertyGroupsLoaded = m_widget->materialBrowserModel()->loadPropertyGroups(matPropsPath);
}
void MaterialBrowserView::importsChanged([[maybe_unused]] const QList<Import> &addedImports,
[[maybe_unused]] const QList<Import> &removedImports)
{
@@ -296,6 +304,8 @@ void MaterialBrowserView::importsChanged([[maybe_unused]] const QList<Import> &a
m_hasQuick3DImport = hasQuick3DImport;
loadPropertyGroups();
// Import change will trigger puppet reset, so we don't want to update previews immediately
refreshModel(false);
}

View File

@@ -70,6 +70,8 @@ private:
bool m_hasQuick3DImport = false;
bool m_autoSelectModelMaterial = false; // TODO: wire this to some action
bool m_puppetResetPending = false;
bool m_propertyGroupsLoaded = false;
void loadPropertyGroups();
};
} // namespace QmlDesigner

View File

@@ -28,12 +28,14 @@
#include <model.h>
#include <modelnode.h>
#include <QObject>
#include <QUrl>
#include <QQmlPropertyMap>
#include <QQmlComponent>
#include <QColor>
#include <QObject>
#include <QPoint>
#include <QPointer>
#include <QQmlComponent>
#include <QQmlPropertyMap>
#include <QUrl>
#include <QMouseEvent>
namespace QmlDesigner {
@@ -183,7 +185,7 @@ private:
QPoint m_lastPos;
Model *m_model = nullptr;
QPointer<Model> m_model;
bool m_aliasExport = false;

View File

@@ -207,7 +207,8 @@ void StatesEditorView::createNewState()
void StatesEditorView::addState()
{
// can happen when root node is e.g. a ListModel
if (!QmlVisualNode::isValidQmlVisualNode(acitveStatesGroupNode()))
if (!QmlVisualNode::isValidQmlVisualNode(acitveStatesGroupNode())
&& m_activeStatesGroupNode.type() != "QtQuick.StateGroup")
return;
QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_STATE_ADDED);
@@ -508,7 +509,7 @@ void StatesEditorView::modelAboutToBeDetached(Model *model)
void StatesEditorView::propertiesRemoved(const QList<AbstractProperty>& propertyList)
{
for (const AbstractProperty &property : propertyList) {
if (property.name() == "states" && property.parentModelNode().isRootNode())
if (property.name() == "states" && property.parentModelNode() == activeStateGroup().modelNode())
resetModel();
if (property.name() == "when" && QmlModelState::isValidQmlModelState(property.parentModelNode()))
resetModel();
@@ -519,7 +520,7 @@ void StatesEditorView::nodeAboutToBeRemoved(const ModelNode &removedNode)
{
if (removedNode.hasParentProperty()) {
const NodeAbstractProperty propertyParent = removedNode.parentProperty();
if (propertyParent.parentModelNode().isRootNode() && propertyParent.name() == "states")
if (propertyParent.parentModelNode() == activeStateGroup().modelNode() && propertyParent.name() == "states")
m_lastIndex = propertyParent.indexOf(removedNode);
}
if (currentState().isValid() && removedNode == currentState())
@@ -528,7 +529,7 @@ void StatesEditorView::nodeAboutToBeRemoved(const ModelNode &removedNode)
void StatesEditorView::nodeRemoved(const ModelNode & /*removedNode*/, const NodeAbstractProperty &parentProperty, PropertyChangeFlags /*propertyChange*/)
{
if (parentProperty.isValid() && parentProperty.parentModelNode().isRootNode() && parentProperty.name() == "states") {
if (parentProperty.isValid() && parentProperty.parentModelNode() == activeStateGroup().modelNode() && parentProperty.name() == "states") {
m_statesEditorModel->removeState(m_lastIndex);
m_lastIndex = -1;
}
@@ -536,19 +537,25 @@ void StatesEditorView::nodeRemoved(const ModelNode & /*removedNode*/, const Node
void StatesEditorView::nodeAboutToBeReparented(const ModelNode &node, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags /*propertyChange*/)
{
if (oldPropertyParent.isValid() && oldPropertyParent.parentModelNode().isRootNode() && oldPropertyParent.name() == "states")
if (oldPropertyParent.isValid()
&& oldPropertyParent.parentModelNode() == activeStateGroup().modelNode()
&& oldPropertyParent.name() == "states")
m_lastIndex = oldPropertyParent.indexOf(node);
}
void StatesEditorView::nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags /*propertyChange*/)
{
if (oldPropertyParent.isValid() && oldPropertyParent.parentModelNode().isRootNode() && oldPropertyParent.name() == "states")
if (oldPropertyParent.isValid()
&& oldPropertyParent.parentModelNode() == activeStateGroup().modelNode()
&& oldPropertyParent.name() == "states")
m_statesEditorModel->removeState(m_lastIndex);
m_lastIndex = -1;
if (newPropertyParent.isValid() && newPropertyParent.parentModelNode().isRootNode() && newPropertyParent.name() == "states") {
if (newPropertyParent.isValid()
&& newPropertyParent.parentModelNode() == activeStateGroup().modelNode()
&& newPropertyParent.name() == "states") {
int index = newPropertyParent.indexOf(node);
m_statesEditorModel->insertState(index);
}
@@ -556,7 +563,8 @@ void StatesEditorView::nodeReparented(const ModelNode &node, const NodeAbstractP
void StatesEditorView::nodeOrderChanged(const NodeListProperty &listProperty)
{
if (listProperty.isValid() && listProperty.parentModelNode().isRootNode() && listProperty.name() == "states")
if (listProperty.isValid() && listProperty.parentModelNode() == activeStateGroup().modelNode()
&& listProperty.name() == "states")
resetModel();
}
@@ -582,7 +590,8 @@ void StatesEditorView::variantPropertiesChanged(const QList<VariantProperty> &pr
for (const VariantProperty &property : propertyList) {
if (property.name() == "name" && QmlModelState::isValidQmlModelState(property.parentModelNode()))
resetModel();
else if (property.name() == "state" && property.parentModelNode().isRootNode())
else if (property.name() == "state"
&& property.parentModelNode() == activeStateGroup().modelNode())
resetModel();
}
}

View File

@@ -39,6 +39,7 @@
#include <QElapsedTimer>
#include <QHash>
#include <QImage>
#include <QPointer>
#include <QRectF>
#include <QTime>
#include <QTimer>
@@ -279,7 +280,7 @@ private:
std::unique_ptr<NodeInstanceServerProxy> m_nodeInstanceServer;
QImage m_baseStatePreviewImage;
QElapsedTimer m_lastCrashTime;
ProjectExplorer::Target *m_currentTarget = nullptr;
QPointer<ProjectExplorer::Target> m_currentTarget;
int m_restartProcessTimerId;
RewriterTransaction m_puppetTransaction;

View File

@@ -131,6 +131,8 @@ public:
QList<QmlModelState> allDefinedStates() const;
QList<QmlModelStateOperation> allInvalidStateOperations() const;
QmlModelStateGroup states() const;
protected:
NodeInstance nodeInstance() const;
QmlObjectNode nodeForInstance(const NodeInstance &instance) const;

View File

@@ -73,7 +73,6 @@ public:
static bool isValidQmlVisualNode(const ModelNode &modelNode);
bool isRootNode() const;
QmlModelStateGroup states() const;
QList<QmlVisualNode> children() const;
QList<QmlObjectNode> resources() const;
QList<QmlObjectNode> allDirectSubNodes() const;
@@ -123,7 +122,7 @@ private:
class QMLDESIGNERCORE_EXPORT QmlModelStateGroup
{
friend class QmlVisualNode;
friend class QmlObjectNode;
friend class StatesEditorView;
public:

View File

@@ -1759,8 +1759,7 @@ void NodeInstanceView::handlePuppetToCreatorCommand(const PuppetToCreatorCommand
emitImport3DSupportChanged(supportMap);
} else if (command.type() == PuppetToCreatorCommand::ModelAtPos) {
ModelNode modelNode = modelNodeForInternalId(command.data().toUInt());
if (modelNode.isValid())
emitModelAtPosResult(modelNode);
emitModelAtPosResult(modelNode);
}
}

View File

@@ -587,6 +587,13 @@ QList<QmlModelStateOperation> QmlObjectNode::allInvalidStateOperations() const
return result;
}
QmlModelStateGroup QmlObjectNode::states() const
{
if (isValid())
return QmlModelStateGroup(modelNode());
else
return QmlModelStateGroup();
}
/*!
Removes a variant property of the object specified by \a name from the

View File

@@ -274,9 +274,6 @@ QmlModelState QmlModelState::duplicate(const QString &name) const
if (!isValid())
throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
if (!QmlVisualNode::isValidQmlVisualNode(modelNode().parentProperty().parentModelNode()))
throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
// QmlModelState newState(stateGroup().addState(name));
QmlModelState newState(createQmlState(view(), {{PropertyName("name"), QVariant(name)}}));
const QList<ModelNode> nodes = modelNode().nodeListProperty("changes").toModelNodeList();
@@ -298,7 +295,7 @@ QmlModelState QmlModelState::duplicate(const QString &name) const
QmlModelStateGroup QmlModelState::stateGroup() const
{
QmlVisualNode parentNode(modelNode().parentProperty().parentModelNode());
QmlObjectNode parentNode(modelNode().parentProperty().parentModelNode());
return parentNode.states();
}
@@ -319,15 +316,15 @@ ModelNode QmlModelState::createQmlState(AbstractView *view, const PropertyListTy
void QmlModelState::setAsDefault()
{
if ((!isBaseState()) && (modelNode().isValid())) {
view()->rootModelNode().variantProperty("state").setValue(name());
stateGroup().modelNode().variantProperty("state").setValue(name());
}
}
bool QmlModelState::isDefault() const
{
if ((!isBaseState()) && (modelNode().isValid())) {
if (view()->rootModelNode().hasProperty("state")) {
return (view()->rootModelNode().variantProperty("state").value() == name());
if (stateGroup().modelNode().hasProperty("state")) {
return (stateGroup().modelNode().variantProperty("state").value() == name());
}
}

View File

@@ -191,14 +191,6 @@ void QmlVisualNode::initializePosition(const QmlVisualNode::Position &position)
}
}
QmlModelStateGroup QmlVisualNode::states() const
{
if (isValid())
return QmlModelStateGroup(modelNode());
else
return QmlModelStateGroup();
}
QmlObjectNode QmlVisualNode::createQmlObjectNode(AbstractView *view,
const ItemLibraryEntry &itemLibraryEntry,
const Position &position,

View File

@@ -122,11 +122,10 @@ PublicKeyDeploymentDialog::PublicKeyDeploymentDialog(const IDevice::ConstPtr &de
args << params.host();
cmd.addArgs(args);
CommandLine execCmd;
execCmd.addArg("exec");
execCmd.addCommandLineAsArgs({"/bin/sh", {"-c", command}}, CommandLine::Raw);
QString execCommandString("exec /bin/sh -c");
ProcessArgs::addArg(&execCommandString, command, OsType::OsTypeLinux);
cmd.addArg(execCommandString);
cmd.addArg(execCmd.arguments());
d->m_process.setCommand(cmd);
SshParameters::setupSshEnvironment(&d->m_process);
d->m_process.start();

View File

@@ -64,15 +64,18 @@ ConnectableItem::~ConnectableItem()
{
setBlockUpdates(true);
for (ConnectableItem *item : qAsConst(m_overlappedItems))
const QVector<ConnectableItem *> overlappedItems = m_overlappedItems;
for (ConnectableItem *item : overlappedItems)
item->removeOverlappingItem(this);
m_overlappedItems.clear();
for (TransitionItem *transition : qAsConst(m_outputTransitions))
const QVector<TransitionItem *> outputTransitions = m_outputTransitions;
for (TransitionItem *transition : outputTransitions)
transition->disconnectItem(this);
m_outputTransitions.clear();
for (TransitionItem *transition : qAsConst(m_inputTransitions))
const QVector<TransitionItem *> inputTransitions = m_inputTransitions;
for (TransitionItem *transition : inputTransitions)
transition->disconnectItem(this);
m_inputTransitions.clear();
@@ -310,7 +313,8 @@ void ConnectableItem::updateTransitions(bool allChildren)
updateInputTransitions();
if (allChildren) {
for (QGraphicsItem *it : childItems()) {
const QList<QGraphicsItem *> items = childItems();
for (QGraphicsItem *it : items) {
auto item = static_cast<ConnectableItem*>(it);
if (item && item->type() >= InitialStateType)
item->updateTransitions(allChildren);

View File

@@ -80,7 +80,7 @@ void SCAttributeItemDelegate::setEditorData(QWidget *editor, const QModelIndex &
combo->clear();
const QStringList values = index.data(DataRole).toString().split(";");
for (QString val : values)
for (const QString &val : values)
combo->addItem(val);
combo->setCurrentText(index.data().toString());

View File

@@ -13,7 +13,6 @@
\"\",
\"Alternatively, this plugin 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 plugin. 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.\"
],
\"Category\" : \"Qt Quick\",
\"Description\" : \"Qt Design Studio Welcome Page.\",
\"Url\" : \"http://www.qt.io\",
$$dependencyList

View File

@@ -424,7 +424,7 @@ void FileExtractor::extract()
});
QObject::connect(archive, &Utils::Archive::finished, this, [this, archive](bool ret) {
delete archive;
archive->deleteLater();
m_finished = ret;
m_timer.stop();
@@ -503,7 +503,7 @@ bool DataModelDownloader::start()
QTC_ASSERT(archive->isValid(), delete archive; return );
QObject::connect(archive, &Utils::Archive::finished, this, [this, archive](bool ret) {
QTC_CHECK(ret);
delete archive;
archive->deleteLater();
emit finished();
});
archive->unarchive();

View File

@@ -32,7 +32,8 @@ import QtQuick.Shapes 1.0
Rectangle {
id: welcome_splash
anchors.fill: parent
width: 600
height: 720
clip: true
gradient: Gradient {
@@ -55,8 +56,6 @@ Rectangle {
property bool doNotShowAgain: true
property bool loadingPlugins: true
width: 600
height: 720
visible: true
color: "#1d212a"

View File

@@ -27,8 +27,13 @@ import QtQuick 2.0
Item {
id: root
width: 600
height: 720
width: 600 * root.mainScale
height: 720 * root.mainScale
property int maxHeight: Screen.desktopAvailableHeight - 100
property real mainScale: root.maxHeight > 720 ? 1 : root.maxHeight / 720
signal closeClicked
signal checkBoxToggled
@@ -42,9 +47,10 @@ Item {
}
Welcome_splash {
scale: root.mainScale
id: welcome_splash
x: 0
y: 0
transformOrigin: Item.TopLeft
antialiasing: true
onCloseClicked: root.closeClicked()
onConfigureClicked: root.configureClicked()

View File

@@ -650,8 +650,6 @@ WelcomeMode::WelcomeMode()
m_quickWidget->rootObject()->setProperty("loadingProgress", m_dataModelDownloader->progress());
});
m_quickWidget->setEnabled(false);
connect(m_dataModelDownloader, &DataModelDownloader::finished, this, [this, welcomePagePath]() {
delete m_quickWidget;
createQuickWidget();

View File

@@ -12,8 +12,8 @@ find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Gui Network Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Gui Network Widgets)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Script Webkit WebkitWidgets QUIET)
find_package(Boost QUIET)
find_package(Eigen2 NO_MODULE QUIET)
find_package(Eigen3 NO_MODULE QUIET)
find_package(Eigen2 QUIET)
find_package(Eigen3 QUIET)
if (${QT_VERSION_MAJOR} LESS 6)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Xml)