diff --git a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp index 65866ad324a..ac863778162 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp @@ -54,7 +54,7 @@ void ActionEditor::registerDeclarativeType() qmlRegisterType("HelperWidgets", 2, 0, "ActionEditor"); } -void ActionEditor::showWidget(int x, int y) +void ActionEditor::prepareDialog() { if (s_lastActionEditor) s_lastActionEditor->hideWidget(); @@ -70,8 +70,18 @@ void ActionEditor::showWidget(int x, int y) this, &ActionEditor::rejected); m_dialog->setAttribute(Qt::WA_DeleteOnClose); +} + +void ActionEditor::showWidget() +{ + prepareDialog(); + m_dialog->showWidget(); +} + +void ActionEditor::showWidget(int x, int y) +{ + prepareDialog(); m_dialog->showWidget(x, y); - m_dialog->activateWindow(); } void ActionEditor::hideWidget() diff --git a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h index b8133224fc9..7c53dffb603 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h +++ b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h @@ -48,6 +48,7 @@ public: static void registerDeclarativeType(); + Q_INVOKABLE void showWidget(); Q_INVOKABLE void showWidget(int x, int y); Q_INVOKABLE void hideWidget(); @@ -69,6 +70,7 @@ private: QVariant backendValue() const; QVariant modelNodeBackend() const; QVariant stateModelNode() const; + void prepareDialog(); private: QPointer m_dialog; diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp index f9710f1e8d2..2a17c2ec6d1 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp @@ -45,7 +45,7 @@ namespace { QStringList propertyNameListToStringList(const QmlDesigner::PropertyNameList &propertyNameList) { QStringList stringList; - foreach (QmlDesigner::PropertyName propertyName, propertyNameList) { + for (const QmlDesigner::PropertyName propertyName : propertyNameList) { stringList << QString::fromUtf8(propertyName); } stringList.removeDuplicates(); @@ -58,7 +58,6 @@ bool isConnection(const QmlDesigner::ModelNode &modelNode) || modelNode.type() == "QtQuick.Connections" || modelNode.type() == "Qt.Connections" || modelNode.type() == "QtQml.Connections"); - } } //namespace @@ -81,7 +80,7 @@ void ConnectionModel::resetModel() setHorizontalHeaderLabels(QStringList({ tr("Target"), tr("Signal Handler"), tr("Action") })); if (connectionView()->isAttached()) { - foreach (const ModelNode modelNode, connectionView()->allModelNodes()) + for (const ModelNode modelNode : connectionView()->allModelNodes()) addModelNode(modelNode); } @@ -96,8 +95,7 @@ SignalHandlerProperty ConnectionModel::signalHandlerPropertyForRow(int rowNumber const int internalId = data(index(rowNumber, TargetModelNodeRow), Qt::UserRole + 1).toInt(); const QString targetPropertyName = data(index(rowNumber, TargetModelNodeRow), Qt::UserRole + 2).toString(); - ModelNode modelNode = connectionView()->modelNodeForInternalId(internalId); - + ModelNode modelNode = connectionView()->modelNodeForInternalId(internalId); if (modelNode.isValid()) return modelNode.signalHandlerProperty(targetPropertyName.toUtf8()); @@ -112,7 +110,7 @@ void ConnectionModel::addModelNode(const ModelNode &modelNode) void ConnectionModel::addConnection(const ModelNode &modelNode) { - foreach (const AbstractProperty &property, modelNode.properties()) { + for (const AbstractProperty &property : modelNode.properties()) { if (property.isSignalHandlerProperty() && property.name() != "target") { addSignalHandler(property.toSignalHandlerProperty()); } @@ -179,7 +177,6 @@ void ConnectionModel::updateSource(int row) m_exceptionError = e.description(); QTimer::singleShot(200, this, &ConnectionModel::handleException); } - } void ConnectionModel::updateSignalName(int rowNumber) @@ -211,8 +208,14 @@ void ConnectionModel::updateTargetNode(int rowNumber) const QString newTarget = data(index(rowNumber, TargetModelNodeRow)).toString(); ModelNode connectionNode = signalHandlerProperty.parentModelNode(); + const bool isAlias = newTarget.contains("."); + if (!newTarget.isEmpty()) { - const ModelNode parent = connectionView()->modelNodeForId(newTarget); + //if it's an alias, then let's reparent connections to alias property owner: + const ModelNode parent = connectionView()->modelNodeForId(isAlias + ? newTarget.split(".").constFirst() + : newTarget); + if (parent.isValid() && QmlItemNode::isValidQmlItemNode(parent)) parent.nodeListProperty("data").reparentHere(connectionNode); @@ -236,8 +239,28 @@ ModelNode ConnectionModel::getTargetNodeForConnection(const ModelNode &connectio BindingProperty bindingProperty = connection.bindingProperty("target"); if (bindingProperty.isValid()) { + bool isAlias = bindingProperty.expression().contains("."); + if (bindingProperty.expression() == QLatin1String("parent")) return connection.parentProperty().parentModelNode(); + else if (isAlias) { + QStringList substr = bindingProperty.expression().split("."); + if (substr.size() > 1) { + ModelNode aliasParent = connectionView()->modelNodeForId(substr.constFirst()); + QString aliasBody = substr.at(1); + if (aliasParent.hasProperty(aliasBody.toUtf8())) { + AbstractProperty abstractProp = aliasParent.property(aliasBody.toUtf8()); + if (abstractProp.isBindingProperty()) { + BindingProperty binding = abstractProp.toBindingProperty(); + if (connectionView()->hasId(binding.expression())) { + ModelNode resolve = connectionView()->modelNodeForId(binding.expression()); + if (resolve.isValid()) + return resolve; + } + } + } + } + } return connectionView()->modelNodeForId(bindingProperty.expression()); } @@ -376,9 +399,8 @@ QStringList ConnectionModel::getSignalsForRow(int row) const QStringList stringList; SignalHandlerProperty signalHandlerProperty = signalHandlerPropertyForRow(row); - if (signalHandlerProperty.isValid()) { + if (signalHandlerProperty.isValid()) stringList.append(getPossibleSignalsForConnection(signalHandlerProperty.parentModelNode())); - } return stringList; } diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp index 435533c5156..25ea5814a90 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp @@ -161,7 +161,7 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event) menu.addAction(tr("Open Connection Editor"), [&]() { if (index.isValid()) { - m_connectonEditor->showWidget(mapToGlobal(event->pos()).x(), mapToGlobal(event->pos()).y()); + m_connectonEditor->showWidget(); m_connectonEditor->setBindingValue(index.data().toString()); m_connectonEditor->setModelIndex(index); m_connectonEditor->updateWindowName(); diff --git a/src/plugins/qmldesigner/components/connectioneditor/delegates.cpp b/src/plugins/qmldesigner/components/connectioneditor/delegates.cpp index 82e97fae210..8107690cea3 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/delegates.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/delegates.cpp @@ -46,7 +46,7 @@ namespace Internal { QStringList prependOnForSignalHandler(const QStringList &signalNames) { QStringList signalHandlerNames; - foreach (const QString &signalName, signalNames) { + for (const QString &signalName : signalNames) { QString signalHandlerName = signalName; if (!signalHandlerName.isEmpty()) { QChar firstChar = signalHandlerName.at(0).toUpper(); @@ -284,9 +284,19 @@ QWidget *ConnectionDelegate::createEditor(QWidget *parent, const QStyleOptionVie switch (index.column()) { case ConnectionModel::TargetModelNodeRow: { - foreach (const ModelNode &modelNode, connectionModel->connectionView()->allModelNodes()) { + for (const ModelNode &modelNode : connectionModel->connectionView()->allModelNodes()) { if (!modelNode.id().isEmpty()) { connectionComboBox->addItem(modelNode.id()); + + for (const BindingProperty &property : modelNode.bindingProperties()) { + if (property.isValid()) { + if (property.isAlias()) { + connectionComboBox->addItem(modelNode.id() + + "." + + QString::fromUtf8(property.name())); + } + } + } } } } break; diff --git a/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.cpp index cdbc1ee7312..5af183e6b11 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.cpp @@ -399,7 +399,6 @@ QStringList DynamicPropertiesModel::possibleSourceProperties(const BindingProper if (metaInfo.propertyTypeName(propertyName) == typeName) //### todo proper check possibleProperties << QString::fromUtf8(propertyName); } - return possibleProperties; } else { qWarning() << " BindingModel::possibleSourcePropertiesForRow no meta info for source node"; diff --git a/src/plugins/qmldesigner/designercore/include/bindingproperty.h b/src/plugins/qmldesigner/designercore/include/bindingproperty.h index cea09aeb195..c0442a678d2 100644 --- a/src/plugins/qmldesigner/designercore/include/bindingproperty.h +++ b/src/plugins/qmldesigner/designercore/include/bindingproperty.h @@ -56,8 +56,10 @@ public: static void deleteAllReferencesTo(const ModelNode &modelNode); + bool isAlias() const; bool isAliasExport() const; + protected: BindingProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view); }; diff --git a/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp b/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp index a6b332eb6e4..f08c3962ae7 100644 --- a/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp @@ -277,6 +277,18 @@ void BindingProperty::deleteAllReferencesTo(const ModelNode &modelNode) } } +bool BindingProperty::isAlias() const +{ + if (!isValid()) + throw InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); + + return isDynamic() + && dynamicTypeName() == "alias" + && !expression().isNull() + && !expression().isEmpty() + && parentModelNode().view()->modelNodeForId(expression()).isValid(); +} + bool BindingProperty::isAliasExport() const { if (!isValid())