QmlDesigner: Integrate Model::singletonMetaInfos()

THe backend model is removed because it is not anymore used.

Task-number: QDS-13603
Change-Id: I9e9857e8698d450e81246009d6f463c50d4ae392
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Marco Bubke
2024-09-11 17:15:06 +02:00
parent ae1de42093
commit 38b2150970
15 changed files with 256 additions and 484 deletions

View File

@@ -558,7 +558,6 @@ extend_qtc_plugin(QmlDesigner
SOURCES_PREFIX components/connectioneditor
SOURCES
addnewbackenddialog.cpp addnewbackenddialog.h addnewbackenddialog.ui
backendmodel.cpp backendmodel.h
bindingmodel.cpp bindingmodel.h
bindingmodelitem.cpp bindingmodelitem.h
connectioneditor.qrc

View File

@@ -305,6 +305,31 @@ void ActionEditor::prepareConnections()
}
// Singletons
#ifdef QDS_USE_PROJECTSTORAGE
if (auto model = m_modelNode.model()) {
for (const auto &metaInfo : model->singletonMetaInfos()) {
if (metaInfo.isValid()) {
ActionEditorDialog::SingletonOption singelton;
for (const auto &property : metaInfo.properties()) {
if (isSkippedType(property.propertyType()))
continue;
auto exportedTypeName = model
->exportedTypeNameForMetaInfo(property.propertyType())
.name.toQByteArray();
singelton.properties.append(
ActionEditorDialog::PropertyOption(QString::fromUtf8(property.name()),
exportedTypeName,
property.isWritable()));
}
if (!singelton.properties.isEmpty()) {
singelton.item = metaInfo.displayName();
singletons.append(singelton);
}
}
}
}
#else
if (RewriterView *rv = m_modelNode.view()->rewriterView()) {
for (const QmlTypeData &data : rv->getQMLTypes()) {
if (!data.typeName.isEmpty()) {
@@ -314,21 +339,10 @@ void ActionEditor::prepareConnections()
for (const auto &property : metaInfo.properties()) {
if (isSkippedType(property.propertyType()))
continue;
#ifdef QDS_USE_PROJECTSTORAGE
auto exportedTypeName = model
->exportedTypeNameForMetaInfo(
property.propertyType())
.name.toQByteArray();
singelton.properties.append(
ActionEditorDialog::PropertyOption(QString::fromUtf8(property.name()),
exportedTypeName,
property.isWritable()));
#else
singelton.properties.append(ActionEditorDialog::PropertyOption(
QString::fromUtf8(property.name()),
skipCpp(property.propertyType().typeName()),
property.isWritable()));
#endif
}
if (!singelton.properties.isEmpty()) {
@@ -339,6 +353,7 @@ void ActionEditor::prepareConnections()
}
}
}
#endif
// States
for (const QmlModelState &state : QmlItemNode(m_modelNode.view()->rootModelNode()).states().allStates())

View File

@@ -246,6 +246,26 @@ void BindingEditor::prepareBindings()
}
//singletons:
#ifdef QDS_USE_PROJECTSTORAGE
if (auto model = m_modelNode.view()->model()) {
for (const auto &metaInfo : model->singletonMetaInfos()) {
BindingEditorDialog::BindingOption binding;
for (const auto &property : metaInfo.properties()) {
const auto propertyType = property.propertyType();
if (compareTypes(m_backendValueType, propertyType)) {
binding.properties.append(QString::fromUtf8(property.name()));
}
}
if (!binding.properties.isEmpty()) {
binding.item = metaInfo.displayName();
bindings.append(binding);
}
}
}
#else
if (RewriterView *rv = m_modelNode.view()->rewriterView()) {
for (const QmlTypeData &data : rv->getQMLTypes()) {
if (!data.typeName.isEmpty()) {
@@ -270,7 +290,7 @@ void BindingEditor::prepareBindings()
}
}
}
#endif
if (!bindings.isEmpty() && m_dialog)
m_dialog->setAllBindings(bindings, m_backendValueType);
}
@@ -289,7 +309,7 @@ void BindingEditor::updateWindowName()
} else {
#ifdef QDS_USE_PROJECTSTORAGE
targetString = " [" + (m_targetName.isEmpty() ? QString() : (m_targetName + ": "))
+ QString::fromUtf8(m_backendValueType.displayName()) + "]";
+ m_backendValueType.displayName() + "]";
#else
targetString = " [" + (m_targetName.isEmpty() ? QString() : (m_targetName + ": "))
+ QString::fromUtf8(m_backendValueType.simplifiedTypeName()) + "]";

View File

@@ -1,318 +0,0 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <utils/algorithm.h>
#include "backendmodel.h"
#include "bindingproperty.h"
#include "connectioneditorutils.h"
#include "connectionview.h"
#include "exception.h"
#include "nodemetainfo.h"
#include "nodeproperty.h"
#include "rewriterview.h"
#include "addnewbackenddialog.h"
#include <coreplugin/icore.h>
#include <utils/qtcassert.h>
namespace QmlDesigner {
BackendModel::BackendModel(ConnectionView *view)
: m_connectionView(view)
{
connect(this, &QStandardItemModel::dataChanged, this, &BackendModel::handleDataChanged);
}
ConnectionView *BackendModel::connectionView() const
{
return m_connectionView;
}
void BackendModel::resetModel()
{
if (!m_connectionView->model())
return;
RewriterView *rewriterView = m_connectionView->model()->rewriterView();
m_lock = true;
beginResetModel();
clear();
setHorizontalHeaderLabels(QStringList({ tr("Type"), tr("Name"), tr("Singleton"), tr("Local") }));
ModelNode rootNode = connectionView()->rootModelNode();
static const PropertyTypeList simpleTypes = {"int", "real", "color", "string"};
if (rewriterView)
for (const QmlTypeData &cppTypeData : rewriterView->getQMLTypes())
if (cppTypeData.isSingleton) {
NodeMetaInfo metaInfo = m_connectionView->model()->metaInfo(
cppTypeData.typeName.toUtf8());
if (metaInfo.isValid() && !metaInfo.isQtQuickItem()) {
auto type = new QStandardItem(cppTypeData.typeName);
type->setData(cppTypeData.typeName, Qt::UserRole + 1);
type->setData(true, Qt::UserRole + 2);
type->setEditable(false);
auto name = new QStandardItem(cppTypeData.typeName);
name->setEditable(false);
QStandardItem *singletonItem = new QStandardItem("");
singletonItem->setCheckState(Qt::Checked);
singletonItem->setCheckable(true);
singletonItem->setEnabled(false);
QStandardItem *inlineItem = new QStandardItem("");
inlineItem->setCheckState(Qt::Unchecked);
inlineItem->setCheckable(true);
inlineItem->setEnabled(false);
appendRow({type, name, singletonItem, inlineItem});
}
}
if (rootNode.isValid()) {
const QList<AbstractProperty> properties = rootNode.properties();
for (const AbstractProperty &property : properties)
if (property.isDynamic() && !simpleTypes.contains(property.dynamicTypeName())) {
NodeMetaInfo metaInfo = m_connectionView->model()->metaInfo(property.dynamicTypeName());
if (metaInfo.isValid() && !metaInfo.isQtQuickItem()) {
QStandardItem *type = new QStandardItem(QString::fromUtf8(property.dynamicTypeName()));
type->setEditable(false);
type->setData(QString::fromUtf8(property.name()), Qt::UserRole + 1);
type->setData(false, Qt::UserRole + 2);
QStandardItem *name = new QStandardItem(QString::fromUtf8(property.name()));
QStandardItem *singletonItem = new QStandardItem("");
singletonItem->setCheckState(Qt::Unchecked);
singletonItem->setCheckable(true);
singletonItem->setEnabled(false);
QStandardItem *inlineItem = new QStandardItem("");
inlineItem->setCheckState(property.isNodeProperty() ? Qt::Checked : Qt::Unchecked);
inlineItem->setCheckable(true);
inlineItem->setEnabled(false);
appendRow({ type, name, singletonItem, inlineItem });
}
}
}
m_lock = false;
endResetModel();
}
QStringList BackendModel::possibleCppTypes() const
{
RewriterView *rewriterView = m_connectionView->model()->rewriterView();
QStringList list;
if (rewriterView) {
const QList<QmlTypeData> cppTypes = rewriterView->getQMLTypes();
for (const QmlTypeData &cppTypeData : cppTypes)
list.append(cppTypeData.typeName);
}
return list;
}
QmlTypeData BackendModel::cppTypeDataForType(const QString &typeName) const
{
RewriterView *rewriterView = m_connectionView->model()->rewriterView();
if (!rewriterView)
return QmlTypeData();
return Utils::findOr(rewriterView->getQMLTypes(), QmlTypeData(), [&typeName](const QmlTypeData &data) {
return typeName == data.typeName;
});
}
void BackendModel::deletePropertyByRow(int rowNumber)
{
Model *model = m_connectionView->model();
if (!model)
return;
/* singleton case remove the import */
if (data(index(rowNumber, 0), Qt::UserRole + 1).toBool()) {
const QString typeName = data(index(rowNumber, 0), Qt::UserRole + 1).toString();
QmlTypeData cppTypeData = cppTypeDataForType(typeName);
if (cppTypeData.isSingleton) {
Import import = Import::createLibraryImport(cppTypeData.importUrl, cppTypeData.versionString);
try {
if (model->hasImport(import))
model->changeImports({}, {import});
} catch (const Exception &e) {
e.showException();
}
}
} else {
const QString propertyName = data(index(rowNumber, 0), Qt::UserRole + 1).toString();
ModelNode modelNode = connectionView()->rootModelNode();
try {
modelNode.removeProperty(propertyName.toUtf8());
} catch (const Exception &e) {
e.showException();
}
}
resetModel();
}
void BackendModel::addNewBackend()
{
Model *model = m_connectionView->model();
if (!model)
return;
AddNewBackendDialog dialog(Core::ICore::dialogParent());
RewriterView *rewriterView = model->rewriterView();
QStringList availableTypes;
if (rewriterView)
dialog.setupPossibleTypes(Utils::filtered(rewriterView->getQMLTypes(), [model](const QmlTypeData &cppTypeData) {
return !cppTypeData.isSingleton || !model->metaInfo(cppTypeData.typeName.toUtf8()).isValid();
/* Only show singletons if the import is missing */
}));
dialog.exec();
if (dialog.applied()) {
QStringList importSplit = dialog.importString().split(" ");
if (importSplit.size() != 2) {
qCWarning(ConnectionEditorLog) << __FUNCTION__ << "invalid import" << importSplit;
QTC_ASSERT(false, return);
}
QString typeName = dialog.type();
Import import = Import::createLibraryImport(importSplit.constFirst(), importSplit.constLast());
/* We cannot add an import and add a node from that import in a single transaction.
* We need the import to have the meta info available.
*/
if (!model->hasImport(import))
model->changeImports({import}, {});
QString propertyName = m_connectionView->model()->generateNewId(typeName);
NodeMetaInfo metaInfo = model->metaInfo(typeName.toUtf8());
QTC_ASSERT(metaInfo.isValid(), return);
/* Add a property for non singleton types. For singletons just adding the import is enough. */
if (!dialog.isSingleton()) {
m_connectionView->executeInTransaction("BackendModel::addNewBackend",
[this, metaInfo, typeName, propertyName, &dialog] {
if (dialog.localDefinition()) {
#ifdef QDS_USE_PROJECTSTORAGE
ModelNode newNode = m_connectionView->createModelNode(typeName.toUtf8());
#else
int minorVersion = metaInfo.minorVersion();
int majorVersion = metaInfo.majorVersion();
ModelNode newNode = m_connectionView->createModelNode(metaInfo.typeName(),
majorVersion,
minorVersion);
#endif
m_connectionView->rootModelNode().nodeProperty(propertyName.toUtf8()).setDynamicTypeNameAndsetModelNode(
typeName.toUtf8(), newNode);
} else {
m_connectionView->rootModelNode().bindingProperty(
propertyName.toUtf8()).setDynamicTypeNameAndExpression(typeName.toUtf8(), "null");
}
});
}
}
resetModel();
}
void BackendModel::updatePropertyName(int rowNumber)
{
const PropertyName newName = data(index(rowNumber, 1)).toString().toUtf8();
const PropertyName oldName = data(index(rowNumber, 0), Qt::UserRole + 1).toString().toUtf8();
m_connectionView->executeInTransaction("BackendModel::updatePropertyName", [this, newName, oldName](){
ModelNode rootModelNode = m_connectionView->rootModelNode();
if (rootModelNode.property(oldName).isNodeProperty()) {
const TypeName typeName = rootModelNode.nodeProperty(oldName).dynamicTypeName();
const ModelNode targetModelNode = rootModelNode.nodeProperty(oldName).modelNode();
const TypeName fullTypeName = targetModelNode.type();
const int majorVersion = targetModelNode.majorVersion();
const int minorVersion = targetModelNode.minorVersion();
rootModelNode.removeProperty(oldName);
ModelNode newNode = m_connectionView->createModelNode(fullTypeName, majorVersion, minorVersion);
m_connectionView->rootModelNode().nodeProperty(newName).setDynamicTypeNameAndsetModelNode(typeName, newNode);
} else if (rootModelNode.property(oldName).isBindingProperty()) {
const QString expression = rootModelNode.bindingProperty(oldName).expression();
const TypeName typeName = rootModelNode.bindingProperty(oldName).dynamicTypeName();
rootModelNode.removeProperty(oldName);
rootModelNode.bindingProperty(newName).setDynamicTypeNameAndExpression(typeName, expression);
} else {
qCWarning(ConnectionEditorLog) << __FUNCTION__ << oldName << newName << "failed...";
QTC_ASSERT(false, return);
}
});
}
void BackendModel::handleDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
if (m_lock)
return;
if (topLeft != bottomRight) {
qCWarning(ConnectionEditorLog) << __FUNCTION__ << "multi edit?";
return;
}
m_lock = true;
int currentColumn = topLeft.column();
int currentRow = topLeft.row();
switch (currentColumn) {
case 0: {
//updating user data
} break;
case 1: {
updatePropertyName(currentRow);
} break;
default:
qCWarning(ConnectionEditorLog) << __FUNCTION__ << "column" << currentColumn;
}
m_lock = false;
}
} // namespace QmlDesigner

View File

@@ -1,48 +0,0 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include <QStandardItemModel>
#include "rewriterview.h"
namespace QmlDesigner {
class ConnectionView;
class BackendModel : public QStandardItemModel
{
Q_OBJECT
public:
enum ColumnRoles {
TypeNameColumn = 0,
PropertyNameColumn = 1,
IsSingletonColumn = 2,
IsLocalColumn = 3,
};
BackendModel(ConnectionView *view);
ConnectionView *connectionView() const;
void resetModel();
QStringList possibleCppTypes() const;
QmlTypeData cppTypeDataForType(const QString &typeName) const;
void deletePropertyByRow(int rowNumber);
void addNewBackend();
protected:
void updatePropertyName(int rowNumber);
private:
void handleDataChanged(const QModelIndex &topLeft, const QModelIndex& bottomRight);
private:
ConnectionView *m_connectionView;
bool m_lock = false;
};
} // namespace QmlDesigner

View File

@@ -277,12 +277,12 @@ std::pair<QString, QString> splitExpression(const QString &expression)
return {sourceNode, propertyName};
}
#ifndef QDS_USE_PROJECTSTORAGE
QStringList singletonsFromView(AbstractView *view)
{
RewriterView *rv = view->rewriterView();
if (!rv)
return {};
QStringList out;
for (const QmlTypeData &data : rv->getQMLTypes()) {
if (data.isSingleton && !data.typeName.isEmpty())
@@ -301,6 +301,7 @@ std::vector<PropertyMetaInfo> propertiesFromSingleton(const QString &name, Abstr
return {};
}
#endif
QList<AbstractProperty> dynamicPropertiesFromNode(const ModelNode &node)
{
@@ -317,9 +318,30 @@ QList<AbstractProperty> dynamicPropertiesFromNode(const ModelNode &node)
return dynamicProperties;
}
#ifdef QDS_USE_PROJECTSTORAGE
QStringList availableSources(AbstractView *view)
{
if (!view->isAttached())
return {};
QStringList sourceNodes;
for (const auto &metaInfo : view->model()->singletonMetaInfos())
sourceNodes.push_back(metaInfo.displayName());
for (const ModelNode &modelNode : view->allModelNodes()) {
if (auto id = modelNode.id(); !id.isEmpty())
sourceNodes.append(id);
}
std::sort(sourceNodes.begin(), sourceNodes.end());
return sourceNodes;
}
#else
QStringList availableSources(AbstractView *view)
{
QStringList sourceNodes;
for (const ModelNode &modelNode : view->allModelNodes()) {
if (!modelNode.id().isEmpty())
sourceNodes.append(modelNode.id());
@@ -327,6 +349,7 @@ QStringList availableSources(AbstractView *view)
std::sort(sourceNodes.begin(), sourceNodes.end());
return singletonsFromView(view) + sourceNodes;
}
#endif
QStringList availableTargetProperties(const BindingProperty &bindingProperty)
{
@@ -351,6 +374,8 @@ QStringList availableTargetProperties(const BindingProperty &bindingProperty)
return {};
}
namespace {
ModelNode getNodeByIdOrParent(AbstractView *view, const QString &id, const ModelNode &targetNode)
{
if (id != QLatin1String("parent"))
@@ -362,6 +387,35 @@ ModelNode getNodeByIdOrParent(AbstractView *view, const QString &id, const Model
return {};
}
#ifdef QDS_USE_PROJECTSTORAGE
NodeMetaInfo singletonMetaInfoForId(const QString &id, AbstractView *view)
{
using Storage::Info::ExportedTypeName;
const auto model = view->model();
if (!model)
return {};
const Utils::SmallString name = id;
const auto singletonMetaInfos = model->singletonMetaInfos();
const auto sourceId = model->fileUrlSourceId();
auto found = std::ranges::find_if(singletonMetaInfos, [&](const auto &metaInfo) {
auto exportedTypeNames = metaInfo.exportedTypeNamesForSourceId(sourceId);
return std::ranges::find(exportedTypeNames, name, &ExportedTypeName::name)
!= exportedTypeNames.end();
});
if (found == singletonMetaInfos.end())
return {};
return *found;
}
#endif
} // namespace
QStringList availableSourceProperties(const QString &id,
const BindingProperty &targetProperty,
AbstractView *view)
@@ -378,6 +432,15 @@ QStringList availableSourceProperties(const QString &id,
QStringList possibleProperties;
if (!modelNode.isValid()) {
#ifdef QDS_USE_PROJECTSTORAGE
if (auto singletonMetaInfo = singletonMetaInfoForId(id, view)) {
for (const auto &property : singletonMetaInfo.properties()) {
if (metaInfoIsCompatible(targetType, property))
possibleProperties.push_back(QString::fromUtf8(property.name()));
}
return possibleProperties;
}
#else
QStringList singletons = singletonsFromView(view);
if (singletons.contains(id)) {
for (const auto &property : propertiesFromSingleton(id, view)) {
@@ -386,6 +449,7 @@ QStringList availableSourceProperties(const QString &id,
}
return possibleProperties;
}
#endif
qCWarning(ConnectionEditorLog) << __FUNCTION__ << "invalid model node:" << id;
return {};
}

View File

@@ -40,8 +40,10 @@ QVariant defaultValueForType(const TypeName &type);
QString defaultExpressionForType(const TypeName &type);
std::pair<QString, QString> splitExpression(const QString &expression);
#ifndef QDS_USE_PROJECTSTORAGE
QStringList singletonsFromView(AbstractView *view);
std::vector<PropertyMetaInfo> propertiesFromSingleton(const QString &name, AbstractView *view);
#endif
QList<AbstractProperty> dynamicPropertiesFromNode(const ModelNode &node);
QStringList availableSources(AbstractView *view);

View File

@@ -40,10 +40,10 @@ const char defaultCondition[] = "condition";
QStringList propertyNameListToStringList(const QmlDesigner::PropertyNameList &propertyNameList)
{
QStringList stringList;
stringList.reserve(propertyNameList.size());
for (const QmlDesigner::PropertyName &propertyName : propertyNameList)
stringList << QString::fromUtf8(propertyName);
stringList.push_back(QString::fromUtf8(propertyName));
stringList.removeDuplicates();
return stringList;
}
@@ -206,6 +206,62 @@ void ConnectionModel::updateSignalName(int rowNumber)
}
}
namespace {
#ifdef QDS_USE_PROJECTSTORAGE
bool isSingleton(AbstractView *view, bool isAlias, QStringView newTarget)
{
using Storage::Info::ExportedTypeName;
auto model = view->model();
if (!model)
return false;
const auto sourceId = model->fileUrlSourceId();
const Utils::SmallString name = newTarget;
const Utils::SmallString aliasName = newTarget.split(u'.').front();
auto hasTargetExportedTypeName = [&](const auto &metaInfo) {
const auto exportedTypeNames = metaInfo.exportedTypeNamesForSourceId(sourceId);
if (std::ranges::find(exportedTypeNames, name, &ExportedTypeName::name)
!= exportedTypeNames.end())
return true;
if (isAlias) {
if (std::ranges::find(exportedTypeNames, aliasName, &ExportedTypeName::name)
!= exportedTypeNames.end())
return true;
}
return false;
};
auto singletonMetaInfos = model->singletonMetaInfos();
return std::ranges::find_if(singletonMetaInfos, hasTargetExportedTypeName)
!= singletonMetaInfos.end();
}
#else
bool isSingleton(AbstractView *view, bool isAlias, const QString &newTarget)
{
if (RewriterView *rv = view->rewriterView()) {
for (const QmlTypeData &data : rv->getQMLTypes()) {
if (!data.typeName.isEmpty()) {
if (data.typeName == newTarget) {
if (view->model()->metaInfo(data.typeName.toUtf8()).isValid())
return true;
} else if (isAlias) {
if (data.typeName == newTarget.split(".").constFirst()) {
if (view->model()->metaInfo(data.typeName.toUtf8()).isValid())
return true;
}
}
}
}
}
return false;
}
#endif
} // namespace
void ConnectionModel::updateTargetNode(int rowNumber)
{
SignalHandlerProperty signalHandlerProperty = signalHandlerPropertyForRow(rowNumber);
@@ -213,27 +269,7 @@ void ConnectionModel::updateTargetNode(int rowNumber)
ModelNode connectionNode = signalHandlerProperty.parentModelNode();
const bool isAlias = newTarget.contains(".");
bool isSingleton = false;
if (RewriterView* rv = connectionView()->rewriterView()) {
for (const QmlTypeData &data : rv->getQMLTypes()) {
if (!data.typeName.isEmpty()) {
if (data.typeName == newTarget) {
if (connectionView()->model()->metaInfo(data.typeName.toUtf8()).isValid()) {
isSingleton = true;
break;
}
} else if (isAlias) {
if (data.typeName == newTarget.split(".").constFirst()) {
if (connectionView()->model()->metaInfo(data.typeName.toUtf8()).isValid()) {
isSingleton = true;
break;
}
}
}
}
}
}
bool isSingleton = QmlDesigner::isSingleton(m_connectionView, isAlias, newTarget);
if (!newTarget.isEmpty()) {
//if it's a singleton, then let's reparent connections to rootNode,
@@ -595,33 +631,55 @@ QStringList ConnectionModel::getflowActionTriggerForRow(int row) const
return stringList;
}
namespace {}
QStringList ConnectionModel::getPossibleSignalsForConnection(const ModelNode &connection) const
{
if (!connection)
return {};
QStringList stringList;
auto getAliasMetaSignals = [&](QString aliasPart, NodeMetaInfo metaInfo) {
if (metaInfo.isValid() && metaInfo.hasProperty(aliasPart.toUtf8())) {
NodeMetaInfo propertyMetaInfo = metaInfo.property(aliasPart.toUtf8()).propertyType();
if (propertyMetaInfo.isValid()) {
auto getAliasMetaSignals = [&](PropertyNameView aliasPart, NodeMetaInfo metaInfo) -> QStringList {
if (NodeMetaInfo propertyMetaInfo = metaInfo.property(aliasPart).propertyType())
return propertyNameListToStringList(propertyMetaInfo.signalNames());
}
}
return QStringList();
return {};
};
if (connection.isValid()) {
//separate check for singletons
if (connection.hasBindingProperty("target")) {
const BindingProperty bp = connection.bindingProperty("target");
if (const BindingProperty bp = connection.bindingProperty("target")) {
#ifdef QDS_USE_PROJECTSTORAGE
if (auto model = m_connectionView->model()) {
const Utils::SmallString bindExpression = bp.expression();
using Storage::Info::ExportedTypeName;
const auto sourceId = model->fileUrlSourceId();
for (const auto &metaInfo : model->singletonMetaInfos()) {
const auto exportedTypeNames = metaInfo.exportedTypeNamesForSourceId(sourceId);
if (std::ranges::find(exportedTypeNames, bindExpression, &ExportedTypeName::name)
!= exportedTypeNames.end()) {
stringList.append(propertyNameListToStringList(metaInfo.signalNames()));
} else {
std::string_view expression = bindExpression;
auto index = expression.find('.');
if (index == std::string_view::npos)
continue;
if (bp.isValid()) {
expression.remove_prefix(index);
stringList.append(getAliasMetaSignals(expression, metaInfo));
}
}
}
#else
const QString bindExpression = bp.expression();
if (const RewriterView *const rv = connectionView()->rewriterView()) {
for (const QmlTypeData &data : rv->getQMLTypes()) {
if (!data.typeName.isEmpty()) {
if (data.typeName == bindExpression) {
NodeMetaInfo metaInfo = connectionView()->model()->metaInfo(data.typeName.toUtf8());
NodeMetaInfo metaInfo = connectionView()->model()->metaInfo(
data.typeName.toUtf8());
if (metaInfo.isValid()) {
stringList << propertyNameListToStringList(metaInfo.signalNames());
break;
@@ -632,46 +690,42 @@ QStringList ConnectionModel::getPossibleSignalsForConnection(const ModelNode &co
if ((expression.size() > 1) && (expression.constFirst() == data.typeName)) {
expression.removeFirst();
stringList << getAliasMetaSignals(
expression.join("."),
connectionView()->model()->metaInfo(data.typeName.toUtf8()));
stringList << getAliasMetaSignals(expression.join(".").toUtf8(),
connectionView()->model()->metaInfo(
data.typeName.toUtf8()));
break;
}
}
}
}
}
}
#endif
std::ranges::sort(stringList);
stringList.erase(std::ranges::unique(stringList).begin(), stringList.end());
}
ModelNode targetNode = getTargetNodeForConnection(connection);
if (targetNode.isValid() && targetNode.metaInfo().isValid()) {
stringList.append(propertyNameListToStringList(targetNode.metaInfo().signalNames()));
if (auto metaInfo = targetNode.metaInfo()) {
stringList.append(propertyNameListToStringList(metaInfo.signalNames()));
} else {
//most likely it's component's internal alias:
if (connection.hasBindingProperty("target")) {
const BindingProperty bp = connection.bindingProperty("target");
if (bp.isValid()) {
if (const BindingProperty bp = connection.bindingProperty("target")) {
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()
if (parentItem.isValid() && parentItem.hasMetaInfo()
&& parentItem.metaInfo().isValid()) {
expression.removeFirst();
stringList << getAliasMetaSignals(expression.join("."),
stringList << getAliasMetaSignals(expression.join(".").toUtf8(),
parentItem.metaInfo());
}
}
}
}
}
}
}
return stringList;
}

View File

@@ -3,7 +3,6 @@
#include "connectionview.h"
#include "backendmodel.h"
#include "bindingmodel.h"
#include "connectionmodel.h"
#include "dynamicpropertiesmodel.h"
@@ -146,7 +145,6 @@ struct ConnectionView::ConnectionViewData
: connectionModel{view}
, bindingModel{view}
, dynamicPropertiesModel{false, view}
, backendModel{view}
, propertyTreeModel{view}
, connectionViewQuickWidget{Utils::makeUniqueObjectPtr<ConnectionViewQuickWidget>(
view, &connectionModel, &bindingModel, &dynamicPropertiesModel)}
@@ -155,7 +153,6 @@ struct ConnectionView::ConnectionViewData
ConnectionModel connectionModel;
BindingModel bindingModel;
DynamicPropertiesModel dynamicPropertiesModel;
BackendModel backendModel;
PropertyTreeModel propertyTreeModel;
int currentIndex = 0;
@@ -177,7 +174,6 @@ void ConnectionView::modelAttached(Model *model)
d->bindingModel.reset();
d->dynamicPropertiesModel.reset();
d->connectionModel.resetModel();
d->backendModel.resetModel();
}
void ConnectionView::modelAboutToBeDetached(Model *model)
@@ -249,8 +245,6 @@ void ConnectionView::variantPropertiesChanged(const QList<VariantProperty> &prop
for (const VariantProperty &variantProperty : propertyList) {
if (variantProperty.isDynamic())
d->dynamicPropertiesModel.updateItem(variantProperty);
if (variantProperty.isDynamic() && variantProperty.parentModelNode().isRootNode())
d->backendModel.resetModel();
d->connectionModel.variantPropertyChanged(variantProperty);
@@ -265,8 +259,6 @@ void ConnectionView::bindingPropertiesChanged(const QList<BindingProperty> &prop
d->bindingModel.updateItem(bindingProperty);
if (bindingProperty.isDynamic())
d->dynamicPropertiesModel.updateItem(bindingProperty);
if (bindingProperty.isDynamic() && bindingProperty.parentModelNode().isRootNode())
d->backendModel.resetModel();
d->connectionModel.bindingPropertyChanged(bindingProperty);
@@ -288,11 +280,6 @@ void ConnectionView::selectedNodesChanged(const QList<ModelNode> & selectedNodeL
d->dynamicPropertiesModel.reset();
}
void ConnectionView::importsChanged(const Imports & /*addedImports*/, const Imports & /*removedImports*/)
{
d->backendModel.resetModel();
}
void ConnectionView::currentStateChanged(const ModelNode &)
{
d->dynamicPropertiesModel.reset();
@@ -332,11 +319,6 @@ DynamicPropertiesModel *ConnectionView::dynamicPropertiesModel() const
return &d->dynamicPropertiesModel;
}
BackendModel *ConnectionView::backendModel() const
{
return &d->backendModel;
}
int ConnectionView::currentIndex() const
{
return d->currentIndex;

View File

@@ -21,7 +21,6 @@ class ConnectionViewWidget;
class BindingModel;
class ConnectionModel;
class DynamicPropertiesModel;
class BackendModel;
class ConnectionViewQuickWidget;
class PropertyTreeModel;
class PropertyListProxyModel;
@@ -55,8 +54,6 @@ public:
void selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
const QList<ModelNode> &lastSelectedNodeList) override;
void importsChanged(const Imports &addedImports, const Imports &removedImports) override;
void currentStateChanged(const ModelNode &node) override;
WidgetInfo widgetInfo() override;
@@ -67,7 +64,6 @@ public:
ConnectionModel *connectionModel() const;
BindingModel *bindingModel() const;
BackendModel *backendModel() const;
int currentIndex() const;
void setCurrentIndex(int i);

View File

@@ -1208,6 +1208,7 @@ CreateSceneCommand NodeInstanceView::createCreateSceneCommand()
QVector<MockupTypeContainer> mockupTypesVector;
#ifndef QDS_USE_PROJECTSTORAGE
for (const QmlTypeData &cppTypeData : model()->rewriterView()->getQMLTypes()) {
const QString versionString = cppTypeData.versionString;
int majorVersion = -1;
@@ -1242,6 +1243,7 @@ CreateSceneCommand NodeInstanceView::createCreateSceneCommand()
mockupTypesVector.append(mockupType);
}
}
#endif
QString lastUsedLanguage;
if (auto multiLanguageAspect = QmlProjectManager::QmlMultiLanguageAspect::current(m_currentTarget))

View File

@@ -117,7 +117,7 @@ public:
bool defaultPropertyIsComponent() const;
TypeName displayName() const;
QString displayName() const;
DEPRECATED_TYPENAME TypeName typeName() const;
DEPRECATED_TYPENAME TypeName simplifiedTypeName() const;
DEPRECATED_VERSION_NUMBER int majorVersion() const;

View File

@@ -143,7 +143,9 @@ public:
QStringList autoComplete(const QString &text, int pos, bool explicitComplete = true);
#ifndef QDS_USE_PROJECTSTORAGE
QList<QmlTypeData> getQMLTypes() const;
#endif
void setWidgetStatusCallback(std::function<void(bool)> setWidgetStatusCallback);

View File

@@ -2106,7 +2106,7 @@ bool NodeMetaInfo::defaultPropertyIsComponent() const
}
}
TypeName NodeMetaInfo::displayName() const
QString NodeMetaInfo::displayName() const
{
return {};
}

View File

@@ -1102,6 +1102,7 @@ QStringList RewriterView::autoComplete(const QString &text, int pos, bool explic
return list;
}
#ifndef QDS_USE_PROJECTSTORAGE
QList<QmlTypeData> RewriterView::getQMLTypes() const
{
QList<QmlTypeData> qmlDataList;
@@ -1127,6 +1128,7 @@ QList<QmlTypeData> RewriterView::getQMLTypes() const
return qmlDataList;
}
#endif
void RewriterView::setWidgetStatusCallback(std::function<void(bool)> setWidgetStatusCallback)
{