forked from qt-creator/qt-creator
QmlDesigner: Support aliases in Connection View
- Allows user to select aliases in connections view - Seeks signals for aliases Task: QDS-2411 Change-Id: I69eb875eb99cbf8cd6a842d5f7e166d9990bb255 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -54,7 +54,7 @@ void ActionEditor::registerDeclarativeType()
|
||||
qmlRegisterType<ActionEditor>("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()
|
||||
|
@@ -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<BindingEditorDialog> m_dialog;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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();
|
||||
|
@@ -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;
|
||||
|
@@ -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";
|
||||
|
@@ -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);
|
||||
};
|
||||
|
@@ -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())
|
||||
|
Reference in New Issue
Block a user