forked from qt-creator/qt-creator
QmlDesigner: Extend Connections view support
- Connection view support to components - Connection view support to singletons - Minor reparenting improvements Task: QDS-2411 Change-Id: I337535012dbb3d3a1722d75d89156463eabb8a4c Reviewed-by: Vikas Pachdha <vikas.pachdha@qt.io>
This commit is contained in:
committed by
Thomas Hartmann
parent
3e1d204c32
commit
66122492a6
@@ -221,6 +221,13 @@ void ConnectionModel::updateTargetNode(int rowNumber)
|
|||||||
isSingleton = true;
|
isSingleton = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else if (isAlias) {
|
||||||
|
if (data.typeName == newTarget.split(".").constFirst()) {
|
||||||
|
if (connectionView()->model()->metaInfo(data.typeName.toUtf8()).isValid()) {
|
||||||
|
isSingleton = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -229,7 +236,7 @@ void ConnectionModel::updateTargetNode(int rowNumber)
|
|||||||
if (!newTarget.isEmpty()) {
|
if (!newTarget.isEmpty()) {
|
||||||
//if it's a singleton, then let's reparent connections to rootNode,
|
//if it's a singleton, then let's reparent connections to rootNode,
|
||||||
//if it's an alias, then reparent to alias property owner:
|
//if it's an alias, then reparent to alias property owner:
|
||||||
const ModelNode parent = connectionView()->modelNodeForId(isSingleton
|
const ModelNode parent = connectionView()->modelNodeForId((isSingleton || (isSingleton && isAlias))
|
||||||
? connectionView()->rootModelNode().id()
|
? connectionView()->rootModelNode().id()
|
||||||
: isAlias
|
: isAlias
|
||||||
? newTarget.split(".").constFirst()
|
? newTarget.split(".").constFirst()
|
||||||
@@ -255,35 +262,36 @@ void ConnectionModel::updateCustomData(QStandardItem *item, const SignalHandlerP
|
|||||||
|
|
||||||
ModelNode ConnectionModel::getTargetNodeForConnection(const ModelNode &connection) const
|
ModelNode ConnectionModel::getTargetNodeForConnection(const ModelNode &connection) const
|
||||||
{
|
{
|
||||||
BindingProperty bindingProperty = connection.bindingProperty("target");
|
ModelNode result;
|
||||||
|
|
||||||
|
const BindingProperty bindingProperty = connection.bindingProperty("target");
|
||||||
|
const QString bindExpression = bindingProperty.expression();
|
||||||
|
|
||||||
if (bindingProperty.isValid()) {
|
if (bindingProperty.isValid()) {
|
||||||
bool isAlias = bindingProperty.expression().contains(".");
|
if (bindExpression == QLatin1String("parent")) {
|
||||||
|
result = connection.parentProperty().parentModelNode();
|
||||||
if (bindingProperty.expression() == QLatin1String("parent"))
|
} else if (bindExpression.contains(".")) {
|
||||||
return connection.parentProperty().parentModelNode();
|
QStringList substr = bindExpression.split(".");
|
||||||
else if (isAlias) {
|
const QString itemId = substr.constFirst();
|
||||||
QStringList substr = bindingProperty.expression().split(".");
|
|
||||||
if (substr.size() > 1) {
|
if (substr.size() > 1) {
|
||||||
ModelNode aliasParent = connectionView()->modelNodeForId(substr.constFirst());
|
const ModelNode aliasParent = (itemId == QLatin1String("parent")
|
||||||
QString aliasBody = substr.at(1);
|
? connection.parentProperty().parentModelNode()
|
||||||
if (aliasParent.hasProperty(aliasBody.toUtf8())) {
|
: connectionView()->modelNodeForId(itemId));
|
||||||
AbstractProperty abstractProp = aliasParent.property(aliasBody.toUtf8());
|
substr.removeFirst(); //remove id, only alias pieces left
|
||||||
if (abstractProp.isBindingProperty()) {
|
const QString aliasBody = substr.join(".");
|
||||||
BindingProperty binding = abstractProp.toBindingProperty();
|
if (aliasParent.isValid() && aliasParent.hasBindingProperty(aliasBody.toUtf8())) {
|
||||||
if (connectionView()->hasId(binding.expression())) {
|
const BindingProperty binding = aliasParent.bindingProperty(aliasBody.toUtf8());
|
||||||
ModelNode resolve = connectionView()->modelNodeForId(binding.expression());
|
if (binding.isValid() && connectionView()->hasId(binding.expression())) {
|
||||||
if (resolve.isValid())
|
result = connectionView()->modelNodeForId(binding.expression());
|
||||||
return resolve;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
result = connectionView()->modelNodeForId(bindExpression);
|
||||||
}
|
}
|
||||||
return connectionView()->modelNodeForId(bindingProperty.expression());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ModelNode();
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionModel::addConnection()
|
void ConnectionModel::addConnection()
|
||||||
@@ -355,8 +363,7 @@ void ConnectionModel::deleteConnectionByRow(int currentRow)
|
|||||||
if (allSignals.size() > 1) {
|
if (allSignals.size() > 1) {
|
||||||
if (allSignals.contains(targetSignal))
|
if (allSignals.contains(targetSignal))
|
||||||
node.removeProperty(targetSignal.name());
|
node.removeProperty(targetSignal.name());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
node.destroy();
|
node.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -448,21 +455,44 @@ QStringList ConnectionModel::getPossibleSignalsForConnection(const ModelNode &co
|
|||||||
{
|
{
|
||||||
QStringList stringList;
|
QStringList stringList;
|
||||||
|
|
||||||
if (connection.isValid()) {
|
auto getAliasMetaSignals = [&](QString aliasPart, NodeMetaInfo metaInfo) {
|
||||||
|
if (metaInfo.isValid() && metaInfo.hasProperty(aliasPart.toUtf8())) {
|
||||||
|
NodeMetaInfo propertyMetaInfo = connectionView()->model()->metaInfo(
|
||||||
|
metaInfo.propertyTypeName(aliasPart.toUtf8()));
|
||||||
|
if (propertyMetaInfo.isValid()) {
|
||||||
|
return propertyNameListToStringList(propertyMetaInfo.signalNames());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QStringList();
|
||||||
|
};
|
||||||
|
|
||||||
|
if (connection.isValid()) {
|
||||||
//separate check for singletons
|
//separate check for singletons
|
||||||
if (connection.hasBindingProperty("target")) {
|
if (connection.hasBindingProperty("target")) {
|
||||||
BindingProperty bp = connection.bindingProperty("target");
|
const BindingProperty bp = connection.bindingProperty("target");
|
||||||
|
|
||||||
if (bp.isValid()) {
|
if (bp.isValid()) {
|
||||||
if (RewriterView *rv = connectionView()->rewriterView()) {
|
const QString bindExpression = bp.expression();
|
||||||
|
|
||||||
|
if (const RewriterView * const rv = connectionView()->rewriterView()) {
|
||||||
for (const QmlTypeData &data : rv->getQMLTypes()) {
|
for (const QmlTypeData &data : rv->getQMLTypes()) {
|
||||||
if (!data.typeName.isEmpty()) {
|
if (!data.typeName.isEmpty()) {
|
||||||
if (data.typeName == bp.expression()) {
|
if (data.typeName == bindExpression) {
|
||||||
NodeMetaInfo metaInfo = connectionView()->model()->metaInfo(data.typeName.toUtf8());
|
NodeMetaInfo metaInfo = connectionView()->model()->metaInfo(data.typeName.toUtf8());
|
||||||
if (metaInfo.isValid()) {
|
if (metaInfo.isValid()) {
|
||||||
stringList.append(propertyNameListToStringList(metaInfo.signalNames()));
|
stringList << propertyNameListToStringList(metaInfo.signalNames());
|
||||||
return stringList;
|
break;
|
||||||
|
}
|
||||||
|
} else if (bindExpression.contains(".")) {
|
||||||
|
//if it doesn't fit the same name, maybe it's an alias?
|
||||||
|
QStringList expression = bindExpression.split(".");
|
||||||
|
if ((expression.size() > 1) && (expression.constFirst() == data.typeName)) {
|
||||||
|
expression.removeFirst();
|
||||||
|
|
||||||
|
stringList << getAliasMetaSignals(
|
||||||
|
expression.join("."),
|
||||||
|
connectionView()->model()->metaInfo(data.typeName.toUtf8()));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -474,6 +504,30 @@ QStringList ConnectionModel::getPossibleSignalsForConnection(const ModelNode &co
|
|||||||
ModelNode targetNode = getTargetNodeForConnection(connection);
|
ModelNode targetNode = getTargetNodeForConnection(connection);
|
||||||
if (targetNode.isValid() && targetNode.metaInfo().isValid()) {
|
if (targetNode.isValid() && targetNode.metaInfo().isValid()) {
|
||||||
stringList.append(propertyNameListToStringList(targetNode.metaInfo().signalNames()));
|
stringList.append(propertyNameListToStringList(targetNode.metaInfo().signalNames()));
|
||||||
|
} else {
|
||||||
|
//most likely it's component's internal alias:
|
||||||
|
|
||||||
|
if (connection.hasBindingProperty("target")) {
|
||||||
|
const BindingProperty bp = connection.bindingProperty("target");
|
||||||
|
|
||||||
|
if (bp.isValid()) {
|
||||||
|
const QString bindExpression = bp.expression();
|
||||||
|
QStringList expression = bp.expression().split(".");
|
||||||
|
if (expression.size() > 1) {
|
||||||
|
const QString itemId = expression.constFirst();
|
||||||
|
if (connectionView()->hasId(itemId)) {
|
||||||
|
ModelNode parentItem = connectionView()->modelNodeForId(itemId);
|
||||||
|
if (parentItem.isValid()
|
||||||
|
&& parentItem.hasMetaInfo()
|
||||||
|
&& parentItem.metaInfo().isValid()) {
|
||||||
|
expression.removeFirst();
|
||||||
|
stringList << getAliasMetaSignals(expression.join("."),
|
||||||
|
parentItem.metaInfo());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -295,6 +295,35 @@ QWidget *ConnectionDelegate::createEditor(QWidget *parent, const QStyleOptionVie
|
|||||||
|
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case ConnectionModel::TargetModelNodeRow: {
|
case ConnectionModel::TargetModelNodeRow: {
|
||||||
|
|
||||||
|
auto addMetaInfoProperties = [&](const NodeMetaInfo& itemMetaInfo, QString itemName){
|
||||||
|
if (itemMetaInfo.isValid()) {
|
||||||
|
for (const PropertyName &propertyName : itemMetaInfo.directPropertyNames()) {
|
||||||
|
TypeName propertyType = itemMetaInfo.propertyTypeName(propertyName);
|
||||||
|
if (!propertyType.isEmpty()) {
|
||||||
|
//first letter is a reliable item indicator
|
||||||
|
QChar firstLetter = QString::fromUtf8(propertyType).at(0);
|
||||||
|
if (firstLetter.isLetter() && firstLetter.isUpper()) {
|
||||||
|
if (!itemMetaInfo.propertyIsEnumType(propertyName)
|
||||||
|
&& !itemMetaInfo.propertyIsPrivate(propertyName)
|
||||||
|
&& !itemMetaInfo.propertyIsListProperty(propertyName)
|
||||||
|
&& !itemMetaInfo.propertyIsPointer(propertyName)) {
|
||||||
|
NodeMetaInfo propertyMetaInfo =
|
||||||
|
connectionModel->connectionView()->model()->metaInfo(propertyType);
|
||||||
|
if (propertyMetaInfo.isValid()) {
|
||||||
|
if (propertyMetaInfo.isQmlItem()) {
|
||||||
|
connectionComboBox->addItem(itemName
|
||||||
|
+ "."
|
||||||
|
+ propertyName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
for (const ModelNode &modelNode : connectionModel->connectionView()->allModelNodes()) {
|
for (const ModelNode &modelNode : connectionModel->connectionView()->allModelNodes()) {
|
||||||
if (!modelNode.id().isEmpty()) {
|
if (!modelNode.id().isEmpty()) {
|
||||||
connectionComboBox->addItem(modelNode.id());
|
connectionComboBox->addItem(modelNode.id());
|
||||||
@@ -308,25 +337,24 @@ QWidget *ConnectionDelegate::createEditor(QWidget *parent, const QStyleOptionVie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Components
|
||||||
|
if (modelNode.isComponent()) {
|
||||||
|
NodeMetaInfo componentMetaInfo = modelNode.metaInfo();
|
||||||
|
addMetaInfoProperties(componentMetaInfo, modelNode.id());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//singletons:
|
//singletons:
|
||||||
if (RewriterView* rv = connectionModel->connectionView()->rewriterView()) {
|
if (RewriterView* rv = connectionModel->connectionView()->rewriterView()) {
|
||||||
for (const QmlTypeData &data : rv->getQMLTypes()) {
|
for (const QmlTypeData &data : rv->getQMLTypes()) {
|
||||||
if (!data.typeName.isEmpty()) {
|
if (!data.typeName.isEmpty()) {
|
||||||
|
//singleton itself
|
||||||
connectionComboBox->addItem(data.typeName);
|
connectionComboBox->addItem(data.typeName);
|
||||||
|
|
||||||
|
//its properties, mostly looking for aliases:
|
||||||
NodeMetaInfo metaInfo = connectionModel->connectionView()->model()->metaInfo(data.typeName.toUtf8());
|
NodeMetaInfo metaInfo = connectionModel->connectionView()->model()->metaInfo(data.typeName.toUtf8());
|
||||||
|
addMetaInfoProperties(metaInfo, data.typeName);
|
||||||
if (metaInfo.isValid()) {
|
|
||||||
for (const PropertyName &propertyName : metaInfo.propertyNames()) {
|
|
||||||
if (metaInfo.propertyTypeName(propertyName) == "alias") {
|
|
||||||
connectionComboBox->addItem(data.typeName
|
|
||||||
+ "."
|
|
||||||
+ QString::fromUtf8(propertyName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -75,6 +75,7 @@ public:
|
|||||||
bool propertyIsListProperty(const PropertyName &propertyName) const;
|
bool propertyIsListProperty(const PropertyName &propertyName) const;
|
||||||
bool propertyIsEnumType(const PropertyName &propertyName) const;
|
bool propertyIsEnumType(const PropertyName &propertyName) const;
|
||||||
bool propertyIsPrivate(const PropertyName &propertyName) const;
|
bool propertyIsPrivate(const PropertyName &propertyName) const;
|
||||||
|
bool propertyIsPointer(const PropertyName &propertyName) const;
|
||||||
QString propertyEnumScope(const PropertyName &propertyName) const;
|
QString propertyEnumScope(const PropertyName &propertyName) const;
|
||||||
QStringList propertyKeysForEnum(const PropertyName &propertyName) const;
|
QStringList propertyKeysForEnum(const PropertyName &propertyName) const;
|
||||||
QVariant propertyCastedValue(const PropertyName &propertyName, const QVariant &value) const;
|
QVariant propertyCastedValue(const PropertyName &propertyName, const QVariant &value) const;
|
||||||
@@ -99,6 +100,7 @@ public:
|
|||||||
bool isSubclassOf(const TypeName &type, int majorVersion = -1, int minorVersion = -1) const;
|
bool isSubclassOf(const TypeName &type, int majorVersion = -1, int minorVersion = -1) const;
|
||||||
|
|
||||||
bool isGraphicalItem() const;
|
bool isGraphicalItem() const;
|
||||||
|
bool isQmlItem() const;
|
||||||
bool isLayoutable() const;
|
bool isLayoutable() const;
|
||||||
bool isView() const;
|
bool isView() const;
|
||||||
bool isTabView() const;
|
bool isTabView() const;
|
||||||
|
@@ -427,7 +427,7 @@ QVector<PropertyInfo> getQmlTypes(const CppComponentValue *objectValue, const Co
|
|||||||
PropertyMemberProcessor processor(context);
|
PropertyMemberProcessor processor(context);
|
||||||
objectValue->processMembers(&processor);
|
objectValue->processMembers(&processor);
|
||||||
|
|
||||||
foreach (const PropertyInfo &property, processor.properties()) {
|
for (const PropertyInfo &property : processor.properties()) {
|
||||||
const PropertyName name = property.first;
|
const PropertyName name = property.first;
|
||||||
const QString nameAsString = QString::fromUtf8(name);
|
const QString nameAsString = QString::fromUtf8(name);
|
||||||
if (!objectValue->isWritable(nameAsString) && objectValue->isPointer(nameAsString)) {
|
if (!objectValue->isWritable(nameAsString) && objectValue->isPointer(nameAsString)) {
|
||||||
@@ -1500,6 +1500,11 @@ bool NodeMetaInfo::propertyIsPrivate(const PropertyName &propertyName) const
|
|||||||
return propertyName.startsWith("__");
|
return propertyName.startsWith("__");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NodeMetaInfo::propertyIsPointer(const PropertyName &propertyName) const
|
||||||
|
{
|
||||||
|
return m_privateData->isPropertyPointer(propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
QString NodeMetaInfo::propertyEnumScope(const PropertyName &propertyName) const
|
QString NodeMetaInfo::propertyEnumScope(const PropertyName &propertyName) const
|
||||||
{
|
{
|
||||||
return m_privateData->propertyEnumScope(propertyName);
|
return m_privateData->propertyEnumScope(propertyName);
|
||||||
@@ -1660,6 +1665,12 @@ bool NodeMetaInfo::isGraphicalItem() const
|
|||||||
|| isSubclassOf("QtQuick.Controls.Popup");
|
|| isSubclassOf("QtQuick.Controls.Popup");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NodeMetaInfo::isQmlItem() const
|
||||||
|
{
|
||||||
|
return isSubclassOf("QtQuick.QtObject")
|
||||||
|
|| isSubclassOf("QtQml.QtObject");
|
||||||
|
}
|
||||||
|
|
||||||
void NodeMetaInfo::clearCache()
|
void NodeMetaInfo::clearCache()
|
||||||
{
|
{
|
||||||
Internal::NodeMetaInfoPrivate::clearCache();
|
Internal::NodeMetaInfoPrivate::clearCache();
|
||||||
|
Reference in New Issue
Block a user