forked from qt-creator/qt-creator
QmlDesigner: Introduction of PropertyMetaInfo
Because the project storage is integer id based the string based API isn't fitting well for the new approach. PropertyMetaInfo can be easier mapped to the project storage. Task-number: QDS-7197 Change-Id: I49bc650abdaacf4b039d76c2514b5ad05ec84abe Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -28,10 +28,13 @@
|
|||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
using PropertyName = QByteArray;
|
using PropertyName = QByteArray;
|
||||||
using PropertyNameList = QList<PropertyName>;
|
using PropertyNameList = QList<PropertyName>;
|
||||||
|
using PropertyNames = std::vector<PropertyName>;
|
||||||
using TypeName = QByteArray;
|
using TypeName = QByteArray;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -143,6 +143,8 @@ void ActionEditor::setModelNode(const ModelNode &modelNode)
|
|||||||
m_modelNode = modelNode;
|
m_modelNode = modelNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
bool isLiteral(QmlJS::AST::Node *ast)
|
bool isLiteral(QmlJS::AST::Node *ast)
|
||||||
{
|
{
|
||||||
if (QmlJS::AST::cast<QmlJS::AST::StringLiteral *>(ast)
|
if (QmlJS::AST::cast<QmlJS::AST::StringLiteral *>(ast)
|
||||||
@@ -154,6 +156,17 @@ bool isLiteral(QmlJS::AST::Node *ast)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypeName skipCpp(TypeName typeName)
|
||||||
|
{
|
||||||
|
// TODO remove after project storage introduction
|
||||||
|
|
||||||
|
if (typeName.contains("<cpp>."))
|
||||||
|
typeName.remove(0, 6);
|
||||||
|
|
||||||
|
return typeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
void ActionEditor::prepareConnections()
|
void ActionEditor::prepareConnections()
|
||||||
{
|
{
|
||||||
if (!m_modelNode.isValid())
|
if (!m_modelNode.isValid())
|
||||||
@@ -197,17 +210,15 @@ void ActionEditor::prepareConnections()
|
|||||||
|
|
||||||
ActionEditorDialog::ConnectionOption connection(modelNode.id());
|
ActionEditorDialog::ConnectionOption connection(modelNode.id());
|
||||||
|
|
||||||
for (const auto &propertyName : modelNode.metaInfo().propertyNames()) {
|
for (const auto &property : modelNode.metaInfo().properties()) {
|
||||||
if (!typeWhiteList.contains(modelNode.metaInfo().propertyTypeName(propertyName)))
|
const auto &propertyTypeName = property.propertyTypeName();
|
||||||
|
if (!typeWhiteList.contains(propertyTypeName))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const QString name = QString::fromUtf8(propertyName);
|
connection.properties.append(
|
||||||
const bool writeable = modelNode.metaInfo().propertyIsWritable(propertyName);
|
ActionEditorDialog::PropertyOption(QString::fromUtf8(property.name()),
|
||||||
TypeName type = modelNode.metaInfo().propertyTypeName(propertyName);
|
skipCpp(std::move(propertyTypeName)),
|
||||||
if (type.contains("<cpp>."))
|
property.isWritable()));
|
||||||
type.remove(0, 6);
|
|
||||||
|
|
||||||
connection.properties.append(ActionEditorDialog::PropertyOption(name, type, writeable));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const VariantProperty &variantProperty : modelNode.variantProperties()) {
|
for (const VariantProperty &variantProperty : modelNode.variantProperties()) {
|
||||||
@@ -216,12 +227,12 @@ void ActionEditor::prepareConnections()
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
const QString name = QString::fromUtf8(variantProperty.name());
|
const QString name = QString::fromUtf8(variantProperty.name());
|
||||||
const bool writeable = modelNode.metaInfo().propertyIsWritable(variantProperty.name());
|
const bool writeable = modelNode.metaInfo().property(variantProperty.name()).isWritable();
|
||||||
TypeName type = variantProperty.dynamicTypeName();
|
|
||||||
if (type.contains("<cpp>."))
|
|
||||||
type.remove(0, 6);
|
|
||||||
|
|
||||||
connection.properties.append(ActionEditorDialog::PropertyOption(name, type, writeable));
|
connection.properties.append(
|
||||||
|
ActionEditorDialog::PropertyOption(name,
|
||||||
|
skipCpp(variantProperty.dynamicTypeName()),
|
||||||
|
writeable));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,18 +270,16 @@ void ActionEditor::prepareConnections()
|
|||||||
NodeMetaInfo metaInfo = m_modelNode.view()->model()->metaInfo(data.typeName.toUtf8());
|
NodeMetaInfo metaInfo = m_modelNode.view()->model()->metaInfo(data.typeName.toUtf8());
|
||||||
if (metaInfo.isValid()) {
|
if (metaInfo.isValid()) {
|
||||||
ActionEditorDialog::SingletonOption singelton;
|
ActionEditorDialog::SingletonOption singelton;
|
||||||
for (const PropertyName &propertyName : metaInfo.propertyNames()) {
|
for (const auto &property : metaInfo.properties()) {
|
||||||
TypeName type = metaInfo.propertyTypeName(propertyName);
|
const TypeName &typeName = property.propertyTypeName();
|
||||||
|
|
||||||
if (!typeWhiteList.contains(type))
|
if (!typeWhiteList.contains(typeName))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const QString name = QString::fromUtf8(propertyName);
|
singelton.properties.append(
|
||||||
const bool writeable = metaInfo.propertyIsWritable(propertyName);
|
ActionEditorDialog::PropertyOption(QString::fromUtf8(property.name()),
|
||||||
if (type.contains("<cpp>."))
|
skipCpp(typeName),
|
||||||
type.remove(0, 6);
|
property.isWritable()));
|
||||||
|
|
||||||
singelton.properties.append(ActionEditorDialog::PropertyOption(name, type, writeable));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!singelton.properties.isEmpty()) {
|
if (!singelton.properties.isEmpty()) {
|
||||||
|
@@ -113,7 +113,7 @@ void BindingEditor::setBackendValue(const QVariant &backendValue)
|
|||||||
const ModelNode node = propertyEditorValue->modelNode();
|
const ModelNode node = propertyEditorValue->modelNode();
|
||||||
|
|
||||||
if (node.isValid()) {
|
if (node.isValid()) {
|
||||||
m_backendValueTypeName = node.metaInfo().propertyTypeName(propertyEditorValue->name());
|
m_backendValueTypeName = node.metaInfo().property(propertyEditorValue->name()).propertyTypeName();
|
||||||
|
|
||||||
QString nodeId = node.id();
|
QString nodeId = node.id();
|
||||||
if (nodeId.isEmpty())
|
if (nodeId.isEmpty())
|
||||||
@@ -205,14 +205,14 @@ void BindingEditor::prepareBindings()
|
|||||||
|
|
||||||
for (const auto &objnode : allNodes) {
|
for (const auto &objnode : allNodes) {
|
||||||
BindingEditorDialog::BindingOption binding;
|
BindingEditorDialog::BindingOption binding;
|
||||||
for (const auto &propertyName : objnode.metaInfo().propertyNames()) {
|
for (const auto &property : objnode.metaInfo().properties()) {
|
||||||
TypeName propertyTypeName = objnode.metaInfo().propertyTypeName(propertyName);
|
const TypeName &propertyTypeName = property.propertyTypeName();
|
||||||
|
|
||||||
if (skipTypeFiltering
|
if (skipTypeFiltering
|
||||||
|| (m_backendValueTypeName == propertyTypeName)
|
|| (m_backendValueTypeName == propertyTypeName)
|
||||||
|| isVariant(propertyTypeName)
|
|| isVariant(propertyTypeName)
|
||||||
|| (targetTypeIsNumeric && isNumeric(propertyTypeName))) {
|
|| (targetTypeIsNumeric && isNumeric(propertyTypeName))) {
|
||||||
binding.properties.append(QString::fromUtf8(propertyName));
|
binding.properties.append(QString::fromUtf8(property.name()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,15 +259,15 @@ void BindingEditor::prepareBindings()
|
|||||||
if (metaInfo.isValid()) {
|
if (metaInfo.isValid()) {
|
||||||
BindingEditorDialog::BindingOption binding;
|
BindingEditorDialog::BindingOption binding;
|
||||||
|
|
||||||
for (const PropertyName &propertyName : metaInfo.propertyNames()) {
|
for (const auto &property : metaInfo.properties()) {
|
||||||
TypeName propertyTypeName = metaInfo.propertyTypeName(propertyName);
|
TypeName propertyTypeName = property.propertyTypeName();
|
||||||
|
|
||||||
if (skipTypeFiltering
|
if (skipTypeFiltering
|
||||||
|| (m_backendValueTypeName == propertyTypeName)
|
|| (m_backendValueTypeName == propertyTypeName)
|
||||||
|| (isVariant(propertyTypeName))
|
|| (isVariant(propertyTypeName))
|
||||||
|| (targetTypeIsNumeric && isNumeric(propertyTypeName))
|
|| (targetTypeIsNumeric && isNumeric(propertyTypeName))
|
||||||
|| (isColor(m_backendValueTypeName) && isColor(propertyTypeName))) {
|
|| (isColor(m_backendValueTypeName) && isColor(propertyTypeName))) {
|
||||||
binding.properties.append(QString::fromUtf8(propertyName));
|
binding.properties.append(QString::fromUtf8(property.name()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -39,6 +39,8 @@
|
|||||||
#include <qmlitemnode.h>
|
#include <qmlitemnode.h>
|
||||||
#include <nodeabstractproperty.h>
|
#include <nodeabstractproperty.h>
|
||||||
|
|
||||||
|
#include <utils/set_algorithm.h>
|
||||||
|
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
#include <QTableView>
|
#include <QTableView>
|
||||||
@@ -137,6 +139,20 @@ void SignalList::setModelNode(const ModelNode &modelNode)
|
|||||||
m_modelNode = modelNode;
|
m_modelNode = modelNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template<typename Callback>
|
||||||
|
void callOnlyMouseSignalNames(const PropertyNameList &signalNames,
|
||||||
|
const PropertyNameList &mouseSignalNames,
|
||||||
|
const Callback &callback)
|
||||||
|
{
|
||||||
|
std::set_union(signalNames.begin(),
|
||||||
|
signalNames.end(),
|
||||||
|
mouseSignalNames.begin(),
|
||||||
|
mouseSignalNames.end(),
|
||||||
|
Utils::make_iterator(callback));
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void SignalList::prepareSignals()
|
void SignalList::prepareSignals()
|
||||||
{
|
{
|
||||||
if (!m_modelNode.isValid())
|
if (!m_modelNode.isValid())
|
||||||
@@ -145,27 +161,21 @@ void SignalList::prepareSignals()
|
|||||||
QList<QmlConnections> connections = QmlFlowViewNode::getAssociatedConnections(m_modelNode);
|
QList<QmlConnections> connections = QmlFlowViewNode::getAssociatedConnections(m_modelNode);
|
||||||
|
|
||||||
for (ModelNode &node : m_modelNode.view()->allModelNodes()) {
|
for (ModelNode &node : m_modelNode.view()->allModelNodes()) {
|
||||||
// Collect all items which contain at least one of the specified signals
|
callOnlyMouseSignalNames(node.metaInfo().signalNames(),
|
||||||
const PropertyNameList signalNames = node.metaInfo().signalNames();
|
QmlFlowViewNode::mouseSignals(),
|
||||||
// Put the signals into a QSet to avoid duplicates
|
[&](const PropertyName &signal) {
|
||||||
auto signalNamesSet = QSet<PropertyName>(signalNames.begin(), signalNames.end());
|
|
||||||
for (const PropertyName &signal : signalNamesSet) {
|
|
||||||
if (QmlFlowViewNode::st_mouseSignals.contains(signal))
|
|
||||||
appendSignalToModel(connections, node, signal);
|
appendSignalToModel(connections, node, signal);
|
||||||
}
|
});
|
||||||
|
|
||||||
// Gather valid properties and aliases from components
|
// Gather valid properties and aliases from components
|
||||||
for (const PropertyName &property : node.metaInfo().propertyNames()) {
|
for (const auto &property : node.metaInfo().properties()) {
|
||||||
const TypeName propertyType = node.metaInfo().propertyTypeName(property);
|
const NodeMetaInfo info = m_modelNode.model()->metaInfo(property.propertyTypeName());
|
||||||
const NodeMetaInfo info = m_modelNode.model()->metaInfo(propertyType);
|
|
||||||
// Collect all items which contain at least one of the specified signals
|
callOnlyMouseSignalNames(info.signalNames(),
|
||||||
const PropertyNameList signalNames = info.signalNames();
|
QmlFlowViewNode::mouseSignals(),
|
||||||
// Put the signals into a QSet to avoid duplicates
|
[&](const PropertyName &signal) {
|
||||||
auto signalNamesSet = QSet<PropertyName>(signalNames.begin(), signalNames.end());
|
appendSignalToModel(connections, node, signal);
|
||||||
for (const PropertyName &signal : signalNamesSet) {
|
});
|
||||||
if (QmlFlowViewNode::st_mouseSignals.contains(signal))
|
|
||||||
appendSignalToModel(connections, node, signal, property);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -568,11 +568,17 @@ void layoutGridLayout(const SelectionContext &selectionContext)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static PropertyNameList sortedPropertyNameList(const PropertyNameList &nameList)
|
static PropertyNameList sortedPropertyNameList(const PropertyMetaInfos &properties)
|
||||||
{
|
{
|
||||||
PropertyNameList sortedPropertyNameList = nameList;
|
auto propertyNames = Utils::transform<PropertyNameList>(properties, [](const auto &property) {
|
||||||
std::stable_sort(sortedPropertyNameList.begin(), sortedPropertyNameList.end());
|
return property.name();
|
||||||
return sortedPropertyNameList;
|
});
|
||||||
|
|
||||||
|
std::sort(propertyNames.begin(), propertyNames.end());
|
||||||
|
|
||||||
|
propertyNames.erase(std::unique(propertyNames.begin(), propertyNames.end()), propertyNames.end());
|
||||||
|
|
||||||
|
return propertyNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString toUpper(const QString &signal)
|
static QString toUpper(const QString &signal)
|
||||||
@@ -628,12 +634,14 @@ static QStringList getSortedSignalNameList(const ModelNode &modelNode)
|
|||||||
QStringList signalNames;
|
QStringList signalNames;
|
||||||
|
|
||||||
if (metaInfo.isValid()) {
|
if (metaInfo.isValid()) {
|
||||||
const PropertyNameList signalNameList = sortedPropertyNameList(metaInfo.signalNames());
|
// TODO seem to be broken because there can be properties without notifier and the notifier can be even have a different name
|
||||||
|
|
||||||
|
const PropertyNameList signalNameList = metaInfo.signalNames();
|
||||||
for (const PropertyName &signalName : signalNameList)
|
for (const PropertyName &signalName : signalNameList)
|
||||||
if (!signalName.contains("Changed"))
|
if (!signalName.contains("Changed"))
|
||||||
signalNames.append(QString::fromUtf8(signalName));
|
signalNames.append(QString::fromUtf8(signalName));
|
||||||
|
|
||||||
const PropertyNameList propertyNameList = sortedPropertyNameList(metaInfo.propertyNames());
|
const PropertyNameList propertyNameList = sortedPropertyNameList(metaInfo.properties());
|
||||||
for (const PropertyName &propertyName : propertyNameList)
|
for (const PropertyName &propertyName : propertyNameList)
|
||||||
if (!propertyName.contains("."))
|
if (!propertyName.contains("."))
|
||||||
signalNames.append(QString::fromUtf8(propertyName + "Changed"));
|
signalNames.append(QString::fromUtf8(propertyName + "Changed"));
|
||||||
|
@@ -138,14 +138,15 @@ QStringList BindingModel::possibleTargetProperties(const BindingProperty &bindin
|
|||||||
NodeMetaInfo metaInfo = modelNode.metaInfo();
|
NodeMetaInfo metaInfo = modelNode.metaInfo();
|
||||||
|
|
||||||
if (metaInfo.isValid()) {
|
if (metaInfo.isValid()) {
|
||||||
QStringList possibleProperties;
|
const auto properties = metaInfo.properties();
|
||||||
const QList<PropertyName> propertyNames = metaInfo.propertyNames();
|
QStringList writableProperties;
|
||||||
for (const PropertyName &propertyName : propertyNames) {
|
writableProperties.reserve(static_cast<int>(properties.size()));
|
||||||
if (metaInfo.propertyIsWritable(propertyName))
|
for (const auto &property : properties) {
|
||||||
possibleProperties << QString::fromUtf8(propertyName);
|
if (property.isWritable())
|
||||||
|
writableProperties.push_back(QString::fromUtf8(property.name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return possibleProperties;
|
return writableProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
return QStringList();
|
return QStringList();
|
||||||
@@ -159,11 +160,10 @@ QStringList BindingModel::possibleSourceProperties(const BindingProperty &bindin
|
|||||||
|
|
||||||
TypeName typeName;
|
TypeName typeName;
|
||||||
|
|
||||||
if (bindingProperty.parentModelNode().metaInfo().isValid()) {
|
if (auto metaInfo = bindingProperty.parentModelNode().metaInfo(); metaInfo.isValid())
|
||||||
typeName = bindingProperty.parentModelNode().metaInfo().propertyTypeName(bindingProperty.name());
|
typeName = metaInfo.property(bindingProperty.name()).propertyTypeName();
|
||||||
} else {
|
else
|
||||||
qWarning() << " BindingModel::possibleSourcePropertiesForRow no meta info for target node";
|
qWarning() << " BindingModel::possibleSourcePropertiesForRow no meta info for target node";
|
||||||
}
|
|
||||||
|
|
||||||
const QString &id = stringlist.constFirst();
|
const QString &id = stringlist.constFirst();
|
||||||
|
|
||||||
@@ -178,9 +178,9 @@ QStringList BindingModel::possibleSourceProperties(const BindingProperty &bindin
|
|||||||
NodeMetaInfo metaInfo = connectionView()->model()->metaInfo(data.typeName.toUtf8());
|
NodeMetaInfo metaInfo = connectionView()->model()->metaInfo(data.typeName.toUtf8());
|
||||||
|
|
||||||
if (metaInfo.isValid()) {
|
if (metaInfo.isValid()) {
|
||||||
for (const PropertyName &propertyName : metaInfo.propertyNames()) {
|
for (const auto &property : metaInfo.properties()) {
|
||||||
//without check for now
|
//without check for now
|
||||||
possibleProperties << QString::fromUtf8(propertyName);
|
possibleProperties.push_back(QString::fromUtf8(property.name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return possibleProperties;
|
return possibleProperties;
|
||||||
@@ -207,9 +207,9 @@ QStringList BindingModel::possibleSourceProperties(const BindingProperty &bindin
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (metaInfo.isValid()) {
|
if (metaInfo.isValid()) {
|
||||||
for (const PropertyName &propertyName : metaInfo.propertyNames()) {
|
for (const auto &property : metaInfo.properties()) {
|
||||||
if (metaInfo.propertyTypeName(propertyName) == typeName) //### todo proper check
|
if (property.propertyTypeName() == typeName) //### todo proper check
|
||||||
possibleProperties << QString::fromUtf8(propertyName);
|
possibleProperties.push_back(QString::fromUtf8(property.name()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qWarning() << " BindingModel::possibleSourcePropertiesForRow no meta info for source node";
|
qWarning() << " BindingModel::possibleSourcePropertiesForRow no meta info for source node";
|
||||||
@@ -233,10 +233,9 @@ static PropertyName unusedProperty(const ModelNode &modelNode)
|
|||||||
{
|
{
|
||||||
PropertyName propertyName = "none";
|
PropertyName propertyName = "none";
|
||||||
if (modelNode.metaInfo().isValid()) {
|
if (modelNode.metaInfo().isValid()) {
|
||||||
const QList<PropertyName> propertyNames = modelNode.metaInfo().propertyNames();
|
for (const auto &property : modelNode.metaInfo().properties()) {
|
||||||
for (const PropertyName &propertyName : propertyNames) {
|
if (property.isWritable() && !modelNode.hasProperty(propertyName))
|
||||||
if (modelNode.metaInfo().propertyIsWritable(propertyName) && !modelNode.hasProperty(propertyName))
|
return property.name();
|
||||||
return propertyName;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -475,7 +475,7 @@ QStringList ConnectionModel::getPossibleSignalsForConnection(const ModelNode &co
|
|||||||
auto getAliasMetaSignals = [&](QString aliasPart, NodeMetaInfo metaInfo) {
|
auto getAliasMetaSignals = [&](QString aliasPart, NodeMetaInfo metaInfo) {
|
||||||
if (metaInfo.isValid() && metaInfo.hasProperty(aliasPart.toUtf8())) {
|
if (metaInfo.isValid() && metaInfo.hasProperty(aliasPart.toUtf8())) {
|
||||||
NodeMetaInfo propertyMetaInfo = connectionView()->model()->metaInfo(
|
NodeMetaInfo propertyMetaInfo = connectionView()->model()->metaInfo(
|
||||||
metaInfo.propertyTypeName(aliasPart.toUtf8()));
|
metaInfo.property(aliasPart.toUtf8()).propertyTypeName());
|
||||||
if (propertyMetaInfo.isValid()) {
|
if (propertyMetaInfo.isValid()) {
|
||||||
return propertyNameListToStringList(propertyMetaInfo.signalNames());
|
return propertyNameListToStringList(propertyMetaInfo.signalNames());
|
||||||
}
|
}
|
||||||
|
@@ -216,8 +216,9 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
const ModelNode node = property.parentModelNode();
|
const ModelNode node = property.parentModelNode();
|
||||||
const TypeName typeName = property.isDynamic() ? property.dynamicTypeName()
|
const TypeName typeName = property.isDynamic()
|
||||||
: node.metaInfo().propertyTypeName(property.name());
|
? property.dynamicTypeName()
|
||||||
|
: node.metaInfo().property(property.name()).propertyTypeName();
|
||||||
|
|
||||||
const QString targetName = node.displayName() + "." + property.name();
|
const QString targetName = node.displayName() + "." + property.name();
|
||||||
|
|
||||||
|
@@ -298,23 +298,19 @@ QWidget *ConnectionDelegate::createEditor(QWidget *parent, const QStyleOptionVie
|
|||||||
|
|
||||||
auto addMetaInfoProperties = [&](const NodeMetaInfo& itemMetaInfo, QString itemName){
|
auto addMetaInfoProperties = [&](const NodeMetaInfo& itemMetaInfo, QString itemName){
|
||||||
if (itemMetaInfo.isValid()) {
|
if (itemMetaInfo.isValid()) {
|
||||||
for (const PropertyName &propertyName : itemMetaInfo.propertyNames()) {
|
for (const auto &property : itemMetaInfo.properties()) {
|
||||||
TypeName propertyType = itemMetaInfo.propertyTypeName(propertyName);
|
TypeName propertyType = property.propertyTypeName();
|
||||||
if (!propertyType.isEmpty()) {
|
if (!propertyType.isEmpty()) {
|
||||||
//first letter is a reliable item indicator
|
//first letter is a reliable item indicator
|
||||||
QChar firstLetter = QString::fromUtf8(propertyType).at(0);
|
QChar firstLetter = QString::fromUtf8(propertyType).at(0);
|
||||||
if (firstLetter.isLetter() && firstLetter.isUpper()) {
|
if (firstLetter.isLetter() && firstLetter.isUpper()) {
|
||||||
if (!itemMetaInfo.propertyIsEnumType(propertyName)
|
if (!property.isEnumType() && !property.isPrivate()
|
||||||
&& !itemMetaInfo.propertyIsPrivate(propertyName)
|
&& !property.isListProperty() && !property.isPointer()) {
|
||||||
&& !itemMetaInfo.propertyIsListProperty(propertyName)
|
|
||||||
&& !itemMetaInfo.propertyIsPointer(propertyName)) {
|
|
||||||
NodeMetaInfo propertyMetaInfo =
|
NodeMetaInfo propertyMetaInfo =
|
||||||
connectionModel->connectionView()->model()->metaInfo(propertyType);
|
connectionModel->connectionView()->model()->metaInfo(propertyType);
|
||||||
if (propertyMetaInfo.isValid()) {
|
if (propertyMetaInfo.isValid()) {
|
||||||
if (propertyMetaInfo.isQmlItem()) {
|
if (propertyMetaInfo.isQmlItem()) {
|
||||||
connectionComboBox->addItem(itemName
|
connectionComboBox->addItem(itemName + "." + property.name());
|
||||||
+ "."
|
|
||||||
+ propertyName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -36,6 +36,7 @@
|
|||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
#include <qmldesignerconstants.h>
|
#include <qmldesignerconstants.h>
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
@@ -345,10 +346,9 @@ QStringList DynamicPropertiesModel::possibleTargetProperties(const BindingProper
|
|||||||
|
|
||||||
if (metaInfo.isValid()) {
|
if (metaInfo.isValid()) {
|
||||||
QStringList possibleProperties;
|
QStringList possibleProperties;
|
||||||
const QList<PropertyName> propertyNames = metaInfo.propertyNames();
|
for (const auto &property : metaInfo.properties()) {
|
||||||
for (const PropertyName &propertyName : propertyNames) {
|
if (property.isWritable())
|
||||||
if (metaInfo.propertyIsWritable(propertyName))
|
possibleProperties.push_back(QString::fromUtf8(property.name()));
|
||||||
possibleProperties << QString::fromUtf8(propertyName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return possibleProperties;
|
return possibleProperties;
|
||||||
@@ -383,8 +383,8 @@ QStringList DynamicPropertiesModel::possibleSourceProperties(const BindingProper
|
|||||||
|
|
||||||
PropertyName typeName;
|
PropertyName typeName;
|
||||||
|
|
||||||
if (bindingProperty.parentModelNode().metaInfo().isValid()) {
|
if (auto metaInfo = bindingProperty.parentModelNode().metaInfo(); metaInfo.isValid()) {
|
||||||
typeName = bindingProperty.parentModelNode().metaInfo().propertyTypeName(bindingProperty.name());
|
typeName = metaInfo.property(bindingProperty.name()).propertyTypeName();
|
||||||
} else {
|
} else {
|
||||||
qWarning() << " BindingModel::possibleSourcePropertiesForRow no meta info for target node";
|
qWarning() << " BindingModel::possibleSourcePropertiesForRow no meta info for target node";
|
||||||
}
|
}
|
||||||
@@ -402,10 +402,9 @@ QStringList DynamicPropertiesModel::possibleSourceProperties(const BindingProper
|
|||||||
|
|
||||||
if (metaInfo.isValid()) {
|
if (metaInfo.isValid()) {
|
||||||
QStringList possibleProperties;
|
QStringList possibleProperties;
|
||||||
const QList<PropertyName> propertyNames = metaInfo.propertyNames();
|
for (const auto &property : metaInfo.properties()) {
|
||||||
for (const PropertyName &propertyName : propertyNames) {
|
if (property.propertyTypeName() == typeName) //### todo proper check
|
||||||
if (metaInfo.propertyTypeName(propertyName) == typeName) //### todo proper check
|
possibleProperties.push_back(QString::fromUtf8(property.name()));
|
||||||
possibleProperties << QString::fromUtf8(propertyName);
|
|
||||||
}
|
}
|
||||||
return possibleProperties;
|
return possibleProperties;
|
||||||
} else {
|
} else {
|
||||||
|
@@ -658,7 +658,7 @@ void DesignDocument::paste()
|
|||||||
PropertyName defaultProperty(targetNode.metaInfo().defaultPropertyName());
|
PropertyName defaultProperty(targetNode.metaInfo().defaultPropertyName());
|
||||||
|
|
||||||
scatterItem(pastedNode, targetNode);
|
scatterItem(pastedNode, targetNode);
|
||||||
if (targetNode.metaInfo().propertyIsListProperty(defaultProperty))
|
if (targetNode.metaInfo().property(defaultProperty).isListProperty())
|
||||||
targetNode.nodeListProperty(defaultProperty).reparentHere(pastedNode);
|
targetNode.nodeListProperty(defaultProperty).reparentHere(pastedNode);
|
||||||
else
|
else
|
||||||
qWarning() << "Cannot reparent to" << targetNode;
|
qWarning() << "Cannot reparent to" << targetNode;
|
||||||
|
@@ -99,7 +99,8 @@ void MaterialEditorContextObject::changeTypeName(const QString &typeName)
|
|||||||
QTC_ASSERT(metaInfo.isValid(), return);
|
QTC_ASSERT(metaInfo.isValid(), return);
|
||||||
|
|
||||||
// Create a list of properties available for the new type
|
// Create a list of properties available for the new type
|
||||||
PropertyNameList propertiesAndSignals(metaInfo.propertyNames());
|
PropertyNameList propertiesAndSignals = Utils::transform<PropertyNameList>(
|
||||||
|
metaInfo.properties(), [](const auto &property) { return property.name(); });
|
||||||
// Add signals to the list
|
// Add signals to the list
|
||||||
const PropertyNameList signalNames = metaInfo.signalNames();
|
const PropertyNameList signalNames = metaInfo.signalNames();
|
||||||
for (const PropertyName &signal : signalNames) {
|
for (const PropertyName &signal : signalNames) {
|
||||||
|
@@ -270,9 +270,12 @@ void MaterialEditorQmlBackend::setup(const QmlObjectNode &selectedMaterialNode,
|
|||||||
if (selectedMaterialNode.isValid()) {
|
if (selectedMaterialNode.isValid()) {
|
||||||
m_contextObject->setModel(materialEditor->model());
|
m_contextObject->setModel(materialEditor->model());
|
||||||
|
|
||||||
const PropertyNameList propertyNames = selectedMaterialNode.modelNode().metaInfo().propertyNames();
|
for (const auto &property : selectedMaterialNode.modelNode().metaInfo().properties()) {
|
||||||
for (const PropertyName &propertyName : propertyNames)
|
createPropertyEditorValue(selectedMaterialNode,
|
||||||
createPropertyEditorValue(selectedMaterialNode, propertyName, selectedMaterialNode.instanceValue(propertyName), materialEditor);
|
property.name(),
|
||||||
|
selectedMaterialNode.instanceValue(property.name()),
|
||||||
|
materialEditor);
|
||||||
|
}
|
||||||
|
|
||||||
// model node
|
// model node
|
||||||
m_backendModelNode.setup(selectedMaterialNode.modelNode());
|
m_backendModelNode.setup(selectedMaterialNode.modelNode());
|
||||||
|
@@ -125,7 +125,7 @@ void MaterialEditorView::changeValue(const QString &name)
|
|||||||
QVariant castedValue;
|
QVariant castedValue;
|
||||||
|
|
||||||
if (metaInfo.isValid() && metaInfo.hasProperty(propertyName)) {
|
if (metaInfo.isValid() && metaInfo.hasProperty(propertyName)) {
|
||||||
castedValue = metaInfo.propertyCastedValue(propertyName, value->value());
|
castedValue = metaInfo.property(propertyName).castedValue(value->value());
|
||||||
} else {
|
} else {
|
||||||
qWarning() << __FUNCTION__ << propertyName << "cannot be casted (metainfo)";
|
qWarning() << __FUNCTION__ << propertyName << "cannot be casted (metainfo)";
|
||||||
return;
|
return;
|
||||||
@@ -139,8 +139,7 @@ void MaterialEditorView::changeValue(const QString &name)
|
|||||||
bool propertyTypeUrl = false;
|
bool propertyTypeUrl = false;
|
||||||
|
|
||||||
if (metaInfo.isValid() && metaInfo.hasProperty(propertyName)) {
|
if (metaInfo.isValid() && metaInfo.hasProperty(propertyName)) {
|
||||||
if (metaInfo.propertyTypeName(propertyName) == "QUrl"
|
if (metaInfo.property(propertyName).hasPropertyTypeName("QUrl", "url")) {
|
||||||
|| metaInfo.propertyTypeName(propertyName) == "url") {
|
|
||||||
// turn absolute local file paths into relative paths
|
// turn absolute local file paths into relative paths
|
||||||
propertyTypeUrl = true;
|
propertyTypeUrl = true;
|
||||||
QString filePath = castedValue.toUrl().toString();
|
QString filePath = castedValue.toUrl().toString();
|
||||||
@@ -202,13 +201,15 @@ void MaterialEditorView::changeExpression(const QString &propertyName)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_selectedMaterial.metaInfo().isValid() && m_selectedMaterial.metaInfo().hasProperty(name)) {
|
if (auto metaInfo = m_selectedMaterial.metaInfo();
|
||||||
if (m_selectedMaterial.metaInfo().propertyTypeName(name) == "QColor") {
|
metaInfo.isValid() && metaInfo.hasProperty(name)) {
|
||||||
|
auto propertyTypeName = metaInfo.property(name).propertyTypeName();
|
||||||
|
if (propertyTypeName == "QColor") {
|
||||||
if (QColor(value->expression().remove('"')).isValid()) {
|
if (QColor(value->expression().remove('"')).isValid()) {
|
||||||
qmlObjectNode.setVariantProperty(name, QColor(value->expression().remove('"')));
|
qmlObjectNode.setVariantProperty(name, QColor(value->expression().remove('"')));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (m_selectedMaterial.metaInfo().propertyTypeName(name) == "bool") {
|
} else if (propertyTypeName == "bool") {
|
||||||
if (isTrueFalseLiteral(value->expression())) {
|
if (isTrueFalseLiteral(value->expression())) {
|
||||||
if (value->expression().compare("true", Qt::CaseInsensitive) == 0)
|
if (value->expression().compare("true", Qt::CaseInsensitive) == 0)
|
||||||
qmlObjectNode.setVariantProperty(name, true);
|
qmlObjectNode.setVariantProperty(name, true);
|
||||||
@@ -216,21 +217,21 @@ void MaterialEditorView::changeExpression(const QString &propertyName)
|
|||||||
qmlObjectNode.setVariantProperty(name, false);
|
qmlObjectNode.setVariantProperty(name, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (m_selectedMaterial.metaInfo().propertyTypeName(name) == "int") {
|
} else if (propertyTypeName == "int") {
|
||||||
bool ok;
|
bool ok;
|
||||||
int intValue = value->expression().toInt(&ok);
|
int intValue = value->expression().toInt(&ok);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
qmlObjectNode.setVariantProperty(name, intValue);
|
qmlObjectNode.setVariantProperty(name, intValue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (m_selectedMaterial.metaInfo().propertyTypeName(name) == "qreal") {
|
} else if (propertyTypeName == "qreal") {
|
||||||
bool ok;
|
bool ok;
|
||||||
qreal realValue = value->expression().toDouble(&ok);
|
qreal realValue = value->expression().toDouble(&ok);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
qmlObjectNode.setVariantProperty(name, realValue);
|
qmlObjectNode.setVariantProperty(name, realValue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (m_selectedMaterial.metaInfo().propertyTypeName(name) == "QVariant") {
|
} else if (propertyTypeName == "QVariant") {
|
||||||
bool ok;
|
bool ok;
|
||||||
qreal realValue = value->expression().toDouble(&ok);
|
qreal realValue = value->expression().toDouble(&ok);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
@@ -809,7 +810,7 @@ void QmlDesigner::MaterialEditorView::highlightSupportedProperties(bool highligh
|
|||||||
QTC_ASSERT(metaInfo.isValid(), return);
|
QTC_ASSERT(metaInfo.isValid(), return);
|
||||||
|
|
||||||
for (const QString &propName : propNames) {
|
for (const QString &propName : propNames) {
|
||||||
if (metaInfo.propertyTypeName(propName.toLatin1()) == "QtQuick3D.Texture") {
|
if (metaInfo.property(propName.toUtf8()).hasPropertyTypeName("QtQuick3D.Texture")) {
|
||||||
QObject *propEditorValObj = propMap.value(propName).value<QObject *>();
|
QObject *propEditorValObj = propMap.value(propName).value<QObject *>();
|
||||||
PropertyEditorValue *propEditorVal = qobject_cast<PropertyEditorValue *>(propEditorValObj);
|
PropertyEditorValue *propEditorVal = qobject_cast<PropertyEditorValue *>(propEditorValObj);
|
||||||
propEditorVal->setHasActiveDrag(highlight);
|
propEditorVal->setHasActiveDrag(highlight);
|
||||||
|
@@ -65,11 +65,10 @@ ChooseFromPropertyListFilter::ChooseFromPropertyListFilter(const NodeMetaInfo &i
|
|||||||
if (parentInfo.isSubclassOf("QtQuick3D.DefaultMaterial")
|
if (parentInfo.isSubclassOf("QtQuick3D.DefaultMaterial")
|
||||||
|| parentInfo.isSubclassOf("QtQuick3D.PrincipledMaterial")) {
|
|| parentInfo.isSubclassOf("QtQuick3D.PrincipledMaterial")) {
|
||||||
// All texture properties are valid targets
|
// All texture properties are valid targets
|
||||||
const PropertyNameList targetNodeNameList = parentInfo.propertyNames();
|
for (const auto &property : parentInfo.properties()) {
|
||||||
for (const PropertyName &name : targetNodeNameList) {
|
const TypeName &propType = property.propertyTypeName();
|
||||||
TypeName propType = parentInfo.propertyTypeName(name);
|
|
||||||
if (propType == textureType || propType == textureTypeCpp) {
|
if (propType == textureType || propType == textureTypeCpp) {
|
||||||
propertyList.append(QString::fromLatin1(name));
|
propertyList.append(QString::fromUtf8(property.name()));
|
||||||
if (breakOnFirst)
|
if (breakOnFirst)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -168,15 +167,13 @@ ChooseFromPropertyListDialog *ChooseFromPropertyListDialog::createIfNeeded(
|
|||||||
|
|
||||||
// Create dialog for selecting writable properties of exact property type
|
// Create dialog for selecting writable properties of exact property type
|
||||||
ChooseFromPropertyListDialog *ChooseFromPropertyListDialog::createIfNeeded(
|
ChooseFromPropertyListDialog *ChooseFromPropertyListDialog::createIfNeeded(
|
||||||
const ModelNode &targetNode, TypeName type, QWidget *parent)
|
const ModelNode &targetNode, TypeName propertyType, QWidget *parent)
|
||||||
{
|
{
|
||||||
const NodeMetaInfo metaInfo = targetNode.metaInfo();
|
const NodeMetaInfo metaInfo = targetNode.metaInfo();
|
||||||
const PropertyNameList propNames = metaInfo.propertyNames();
|
|
||||||
const TypeName property(type);
|
|
||||||
QStringList matchingNames;
|
QStringList matchingNames;
|
||||||
for (const auto &propName : propNames) {
|
for (const auto &property : metaInfo.properties()) {
|
||||||
if (metaInfo.propertyTypeName(propName) == property && metaInfo.propertyIsWritable(propName))
|
if (property.hasPropertyTypeName(propertyType) && property.isWritable())
|
||||||
matchingNames.append(QString::fromLatin1(propName));
|
matchingNames.append(QString::fromUtf8(property.name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!matchingNames.isEmpty())
|
if (!matchingNames.isEmpty())
|
||||||
|
@@ -725,7 +725,7 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetNode.metaInfo().propertyIsListProperty(selectedProp)) {
|
if (targetNode.metaInfo().property(selectedProp).isListProperty()) {
|
||||||
BindingProperty listProp = targetNode.bindingProperty(selectedProp);
|
BindingProperty listProp = targetNode.bindingProperty(selectedProp);
|
||||||
listProp.addModelNodeToArray(newModelNode);
|
listProp.addModelNodeToArray(newModelNode);
|
||||||
validContainer = true;
|
validContainer = true;
|
||||||
@@ -1105,7 +1105,7 @@ ModelNode NavigatorTreeModel::createTextureNode(const NodeAbstractProperty &targ
|
|||||||
|
|
||||||
TypeName propertyType(const NodeAbstractProperty &property)
|
TypeName propertyType(const NodeAbstractProperty &property)
|
||||||
{
|
{
|
||||||
return property.parentModelNode().metaInfo().propertyTypeName(property.name());
|
return property.parentModelNode().metaInfo().property(property.name()).propertyTypeName();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigatorTreeModel::moveNodesInteractive(NodeAbstractProperty &parentProperty,
|
void NavigatorTreeModel::moveNodesInteractive(NodeAbstractProperty &parentProperty,
|
||||||
|
@@ -220,7 +220,10 @@ void PropertyEditorContextObject::changeTypeName(const QString &typeName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a list of properties available for the new type
|
// Create a list of properties available for the new type
|
||||||
QList<PropertyName> propertiesAndSignals(metaInfo.propertyNames());
|
auto propertiesAndSignals = Utils::transform<PropertyNameList>(metaInfo.properties(),
|
||||||
|
[](const auto &property) {
|
||||||
|
return property.name();
|
||||||
|
});
|
||||||
// Add signals to the list
|
// Add signals to the list
|
||||||
for (const auto &signal : metaInfo.signalNames()) {
|
for (const auto &signal : metaInfo.signalNames()) {
|
||||||
if (signal.isEmpty())
|
if (signal.isEmpty())
|
||||||
|
@@ -25,8 +25,9 @@
|
|||||||
|
|
||||||
#include "propertyeditorqmlbackend.h"
|
#include "propertyeditorqmlbackend.h"
|
||||||
|
|
||||||
#include "propertyeditorvalue.h"
|
|
||||||
#include "propertyeditortransaction.h"
|
#include "propertyeditortransaction.h"
|
||||||
|
#include "propertyeditorvalue.h"
|
||||||
|
#include "propertymetainfo.h"
|
||||||
#include <qmldesignerconstants.h>
|
#include <qmldesignerconstants.h>
|
||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
#include <qmltimeline.h>
|
#include <qmltimeline.h>
|
||||||
@@ -415,10 +416,13 @@ void PropertyEditorQmlBackend::setup(const QmlObjectNode &qmlObjectNode, const Q
|
|||||||
if (propertyEditorBenchmark().isInfoEnabled())
|
if (propertyEditorBenchmark().isInfoEnabled())
|
||||||
time.start();
|
time.start();
|
||||||
|
|
||||||
const QList<PropertyName> propertyNames = qmlObjectNode.modelNode().metaInfo().propertyNames();
|
for (const auto &property : qmlObjectNode.modelNode().metaInfo().properties()) {
|
||||||
for (const PropertyName &propertyName : propertyNames)
|
auto propertyName = property.name();
|
||||||
createPropertyEditorValue(qmlObjectNode, propertyName, qmlObjectNode.instanceValue(propertyName), propertyEditor);
|
createPropertyEditorValue(qmlObjectNode,
|
||||||
|
propertyName,
|
||||||
|
qmlObjectNode.instanceValue(propertyName),
|
||||||
|
propertyEditor);
|
||||||
|
}
|
||||||
setupLayoutAttachedProperties(qmlObjectNode, propertyEditor);
|
setupLayoutAttachedProperties(qmlObjectNode, propertyEditor);
|
||||||
setupAuxiliaryProperties(qmlObjectNode, propertyEditor);
|
setupAuxiliaryProperties(qmlObjectNode, propertyEditor);
|
||||||
|
|
||||||
@@ -514,9 +518,11 @@ void PropertyEditorQmlBackend::initialSetup(const TypeName &typeName, const QUrl
|
|||||||
{
|
{
|
||||||
NodeMetaInfo metaInfo = propertyEditor->model()->metaInfo(typeName);
|
NodeMetaInfo metaInfo = propertyEditor->model()->metaInfo(typeName);
|
||||||
|
|
||||||
const QList<PropertyName> propertyNames = metaInfo.propertyNames();
|
for (const auto &property : metaInfo.properties()) {
|
||||||
for (const PropertyName &propertyName : propertyNames)
|
setupPropertyEditorValue(property.name(),
|
||||||
setupPropertyEditorValue(propertyName, propertyEditor, QString::fromUtf8(metaInfo.propertyTypeName(propertyName)));
|
propertyEditor,
|
||||||
|
QString::fromUtf8(property.propertyTypeName()));
|
||||||
|
}
|
||||||
|
|
||||||
auto valueObject = qobject_cast<PropertyEditorValue *>(variantToQObject(
|
auto valueObject = qobject_cast<PropertyEditorValue *>(variantToQObject(
|
||||||
m_backendValuesPropertyMap.value(Constants::PROPERTY_EDITOR_CLASSNAME_PROPERTY)));
|
m_backendValuesPropertyMap.value(Constants::PROPERTY_EDITOR_CLASSNAME_PROPERTY)));
|
||||||
@@ -579,7 +585,7 @@ inline bool dotPropertyHeuristic(const QmlObjectNode &node, const NodeMetaInfo &
|
|||||||
const PropertyName parentProperty = list.first();
|
const PropertyName parentProperty = list.first();
|
||||||
const PropertyName itemProperty = list.last();
|
const PropertyName itemProperty = list.last();
|
||||||
|
|
||||||
TypeName typeName = type.propertyTypeName(parentProperty);
|
TypeName typeName = type.property(parentProperty).propertyTypeName();
|
||||||
|
|
||||||
NodeMetaInfo itemInfo = node.view()->model()->metaInfo("QtQuick.Item");
|
NodeMetaInfo itemInfo = node.view()->model()->metaInfo("QtQuick.Item");
|
||||||
NodeMetaInfo textInfo = node.view()->model()->metaInfo("QtQuick.Text");
|
NodeMetaInfo textInfo = node.view()->model()->metaInfo("QtQuick.Text");
|
||||||
@@ -596,7 +602,7 @@ inline bool dotPropertyHeuristic(const QmlObjectNode &node, const NodeMetaInfo &
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type,
|
QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &metaType,
|
||||||
const NodeMetaInfo &superType,
|
const NodeMetaInfo &superType,
|
||||||
const QmlObjectNode &node)
|
const QmlObjectNode &node)
|
||||||
{
|
{
|
||||||
@@ -615,20 +621,22 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type,
|
|||||||
allTypes.append(variantToStringList(node->property("typeNames").value));
|
allTypes.append(variantToStringList(node->property("typeNames").value));
|
||||||
}
|
}
|
||||||
|
|
||||||
const QList<PropertyName> allProperties = type.propertyNames();
|
auto propertyMetaInfoCompare = [](const auto &first, const auto &second) {
|
||||||
|
return first.name() < second.name();
|
||||||
QMap<PropertyName, QList<PropertyName>> propertyMap;
|
};
|
||||||
QList<PropertyName> separateSectionProperties;
|
std::map<PropertyMetaInfo, PropertyMetaInfos, decltype(propertyMetaInfoCompare)> propertyMap(
|
||||||
|
propertyMetaInfoCompare);
|
||||||
|
PropertyMetaInfos separateSectionProperties;
|
||||||
|
|
||||||
// Iterate over all properties and isolate the properties which have their own template
|
// Iterate over all properties and isolate the properties which have their own template
|
||||||
for (const PropertyName &propertyName : allProperties) {
|
for (const auto &property : metaType.properties()) {
|
||||||
|
const auto &propertyName = property.name();
|
||||||
if (propertyName.startsWith("__"))
|
if (propertyName.startsWith("__"))
|
||||||
continue; // private API
|
continue; // private API
|
||||||
|
|
||||||
if (!superType.hasProperty(propertyName)
|
if (!superType.hasProperty(propertyName) // TODO add property.isLocalProperty()
|
||||||
&& type.propertyIsWritable(propertyName)
|
&& property.isWritable() && dotPropertyHeuristic(node, metaType, propertyName)) {
|
||||||
&& dotPropertyHeuristic(node, type, propertyName)) {
|
QString typeName = QString::fromUtf8(property.propertyTypeName());
|
||||||
QString typeName = QString::fromLatin1(type.propertyTypeName(propertyName));
|
|
||||||
|
|
||||||
if (typeName == "alias" && node.isValid())
|
if (typeName == "alias" && node.isValid())
|
||||||
typeName = QString::fromLatin1(node.instanceType(propertyName));
|
typeName = QString::fromLatin1(node.instanceType(propertyName));
|
||||||
@@ -636,18 +644,16 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type,
|
|||||||
// Check if a template for the type exists
|
// Check if a template for the type exists
|
||||||
if (allTypes.contains(typeName)) {
|
if (allTypes.contains(typeName)) {
|
||||||
if (separateSectionTypes.contains(typeName)) { // template enforces separate section
|
if (separateSectionTypes.contains(typeName)) { // template enforces separate section
|
||||||
separateSectionProperties.append(propertyName);
|
separateSectionProperties.push_back(property);
|
||||||
} else {
|
} else {
|
||||||
if (propertyName.contains('.')) {
|
if (propertyName.contains('.')) {
|
||||||
const PropertyName parentProperty = propertyName.split('.').first();
|
const PropertyName parentPropertyName = propertyName.split('.').first();
|
||||||
|
const PropertyMetaInfo parentProperty = metaType.property(
|
||||||
|
parentPropertyName);
|
||||||
|
|
||||||
if (propertyMap.contains(parentProperty))
|
propertyMap[parentProperty].push_back(property);
|
||||||
propertyMap[parentProperty].append(propertyName);
|
|
||||||
else
|
|
||||||
propertyMap[parentProperty] = { propertyName };
|
|
||||||
} else {
|
} else {
|
||||||
if (!propertyMap.contains(propertyName))
|
propertyMap[property];
|
||||||
propertyMap[propertyName] = {};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -655,28 +661,29 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Filter out the properties which have a basic type e.g. int, string, bool
|
// Filter out the properties which have a basic type e.g. int, string, bool
|
||||||
QList<PropertyName> basicProperties;
|
PropertyMetaInfos basicProperties;
|
||||||
auto it = propertyMap.begin();
|
auto it = propertyMap.begin();
|
||||||
while (it != propertyMap.end()) {
|
while (it != propertyMap.end()) {
|
||||||
if (it.value().empty()) {
|
if (it->second.empty()) {
|
||||||
basicProperties.append(it.key());
|
basicProperties.push_back(it->first);
|
||||||
it = propertyMap.erase(it);
|
it = propertyMap.erase(it);
|
||||||
} else {
|
} else {
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::sort(basicProperties);
|
Utils::sort(basicProperties, propertyMetaInfoCompare);
|
||||||
|
|
||||||
auto findAndFillTemplate = [&nodes, &node, &type](const PropertyName &label,
|
auto findAndFillTemplate = [&nodes, &node](const PropertyName &label,
|
||||||
const PropertyName &property) {
|
const PropertyMetaInfo &property) {
|
||||||
PropertyName underscoreProperty = property;
|
const auto &propertyName = property.name();
|
||||||
|
PropertyName underscoreProperty = propertyName;
|
||||||
underscoreProperty.replace('.', '_');
|
underscoreProperty.replace('.', '_');
|
||||||
|
|
||||||
TypeName typeName = type.propertyTypeName(property);
|
TypeName typeName = property.propertyTypeName();
|
||||||
// alias resolution only possible with instance
|
// alias resolution only possible with instance
|
||||||
if (typeName == "alias" && node.isValid())
|
if (typeName == "alias" && node.isValid())
|
||||||
typeName = node.instanceType(property);
|
typeName = node.instanceType(propertyName);
|
||||||
|
|
||||||
QString filledTemplate;
|
QString filledTemplate;
|
||||||
for (const QmlJS::SimpleReaderNode::Ptr &n : nodes) {
|
for (const QmlJS::SimpleReaderNode::Ptr &n : nodes) {
|
||||||
@@ -730,8 +737,8 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type,
|
|||||||
qmlInnerTemplate += "bottomPadding: 10\n";
|
qmlInnerTemplate += "bottomPadding: 10\n";
|
||||||
qmlInnerTemplate += "SectionLayout {\n";
|
qmlInnerTemplate += "SectionLayout {\n";
|
||||||
|
|
||||||
for (const auto &p : qAsConst(basicProperties))
|
for (const auto &basicProperty : std::as_const(basicProperties))
|
||||||
qmlInnerTemplate += findAndFillTemplate(p, p);
|
qmlInnerTemplate += findAndFillTemplate(basicProperty.name(), basicProperty);
|
||||||
|
|
||||||
qmlInnerTemplate += "}\n"; // SectionLayout
|
qmlInnerTemplate += "}\n"; // SectionLayout
|
||||||
qmlInnerTemplate += "}\n"; // Column
|
qmlInnerTemplate += "}\n"; // Column
|
||||||
@@ -740,16 +747,17 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type,
|
|||||||
// Second the section containing properties of complex type for which no specific template exists e.g. Button
|
// Second the section containing properties of complex type for which no specific template exists e.g. Button
|
||||||
if (!propertyMap.empty()) {
|
if (!propertyMap.empty()) {
|
||||||
emptyTemplate = false;
|
emptyTemplate = false;
|
||||||
for (auto it = propertyMap.cbegin(); it != propertyMap.cend(); ++it) {
|
for (auto &[property, properties] : propertyMap) {
|
||||||
const auto &key = it.key();
|
// for (auto it = propertyMap.cbegin(); it != propertyMap.cend(); ++it) {
|
||||||
TypeName parentTypeName = type.propertyTypeName(key);
|
TypeName parentTypeName = property.propertyTypeName();
|
||||||
// alias resolution only possible with instance
|
// alias resolution only possible with instance
|
||||||
if (parentTypeName == "alias" && node.isValid())
|
if (parentTypeName == "alias" && node.isValid())
|
||||||
parentTypeName = node.instanceType(key);
|
parentTypeName = node.instanceType(property.name());
|
||||||
|
|
||||||
qmlInnerTemplate += "Section {\n";
|
qmlInnerTemplate += "Section {\n";
|
||||||
qmlInnerTemplate += QStringLiteral("caption: \"%1 - %2\"\n")
|
qmlInnerTemplate += QStringLiteral("caption: \"%1 - %2\"\n")
|
||||||
.arg(QString::fromUtf8(key), QString::fromUtf8(parentTypeName));
|
.arg(QString::fromUtf8(property.name()),
|
||||||
|
QString::fromUtf8(parentTypeName));
|
||||||
qmlInnerTemplate += anchorLeftRight;
|
qmlInnerTemplate += anchorLeftRight;
|
||||||
qmlInnerTemplate += "leftPadding: 8\n";
|
qmlInnerTemplate += "leftPadding: 8\n";
|
||||||
qmlInnerTemplate += "rightPadding: 0\n";
|
qmlInnerTemplate += "rightPadding: 0\n";
|
||||||
@@ -757,12 +765,14 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type,
|
|||||||
qmlInnerTemplate += "level: 1\n";
|
qmlInnerTemplate += "level: 1\n";
|
||||||
qmlInnerTemplate += "SectionLayout {\n";
|
qmlInnerTemplate += "SectionLayout {\n";
|
||||||
|
|
||||||
auto properties = it.value();
|
Utils::sort(properties, propertyMetaInfoCompare);
|
||||||
Utils::sort(properties);
|
|
||||||
|
|
||||||
for (const auto &p : qAsConst(properties)) {
|
for (const auto &subProperty : properties) {
|
||||||
const PropertyName shortName = p.contains('.') ? p.split('.').last() : p;
|
const auto &propertyName = subProperty.name();
|
||||||
qmlInnerTemplate += findAndFillTemplate(shortName, p);
|
auto found = std::find(propertyName.rbegin(), propertyName.rend(), '.');
|
||||||
|
const PropertyName shortName{found.base(),
|
||||||
|
std::distance(found.base(), propertyName.end())};
|
||||||
|
qmlInnerTemplate += findAndFillTemplate(shortName, property);
|
||||||
}
|
}
|
||||||
|
|
||||||
qmlInnerTemplate += "}\n"; // SectionLayout
|
qmlInnerTemplate += "}\n"; // SectionLayout
|
||||||
@@ -773,9 +783,9 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type,
|
|||||||
// Third the section containing properties of complex type for which a specific template exists e.g. Rectangle, Image
|
// Third the section containing properties of complex type for which a specific template exists e.g. Rectangle, Image
|
||||||
if (!separateSectionProperties.empty()) {
|
if (!separateSectionProperties.empty()) {
|
||||||
emptyTemplate = false;
|
emptyTemplate = false;
|
||||||
Utils::sort(separateSectionProperties);
|
Utils::sort(separateSectionProperties, propertyMetaInfoCompare);
|
||||||
for (const auto &p : qAsConst(separateSectionProperties))
|
for (const auto &property : separateSectionProperties)
|
||||||
qmlInnerTemplate += findAndFillTemplate(p, p);
|
qmlInnerTemplate += findAndFillTemplate(property.name(), property);
|
||||||
}
|
}
|
||||||
|
|
||||||
qmlInnerTemplate += "}\n"; // Column
|
qmlInnerTemplate += "}\n"; // Column
|
||||||
|
@@ -60,9 +60,13 @@ PropertyEditorValue::PropertyEditorValue(QObject *parent)
|
|||||||
QVariant PropertyEditorValue::value() const
|
QVariant PropertyEditorValue::value() const
|
||||||
{
|
{
|
||||||
QVariant returnValue = m_value;
|
QVariant returnValue = m_value;
|
||||||
if (modelNode().isValid() && modelNode().metaInfo().isValid() && modelNode().metaInfo().hasProperty(name()))
|
if (modelNode().isValid()) {
|
||||||
if (modelNode().metaInfo().propertyTypeName(name()) == "QUrl")
|
if (auto metaInfo = modelNode().metaInfo();
|
||||||
|
metaInfo.isValid() && metaInfo.hasProperty(name())
|
||||||
|
&& metaInfo.property(name()).hasPropertyTypeName("QUrl", "url")) {
|
||||||
returnValue = returnValue.toUrl().toString();
|
returnValue = returnValue.toUrl().toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,9 +104,9 @@ static void fixAmbigousColorNames(const QmlDesigner::ModelNode &modelNode,
|
|||||||
const QmlDesigner::PropertyName &name,
|
const QmlDesigner::PropertyName &name,
|
||||||
QVariant *value)
|
QVariant *value)
|
||||||
{
|
{
|
||||||
if (modelNode.isValid() && modelNode.metaInfo().isValid()
|
if (modelNode.isValid()) {
|
||||||
&& (modelNode.metaInfo().propertyTypeName(name) == "QColor"
|
if (auto metaInfo = modelNode.metaInfo();
|
||||||
|| modelNode.metaInfo().propertyTypeName(name) == "color")) {
|
metaInfo.isValid() && metaInfo.property(name).hasPropertyTypeName("QColor", "color")) {
|
||||||
if ((value->type() == QVariant::Color)) {
|
if ((value->type() == QVariant::Color)) {
|
||||||
QColor color = value->value<QColor>();
|
QColor color = value->value<QColor>();
|
||||||
int alpha = color.alpha();
|
int alpha = color.alpha();
|
||||||
@@ -113,13 +117,15 @@ static void fixAmbigousColorNames(const QmlDesigner::ModelNode &modelNode,
|
|||||||
*value = QColor(value->toString()).name(QColor::HexArgb);
|
*value = QColor(value->toString()).name(QColor::HexArgb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fixUrl(const QmlDesigner::ModelNode &modelNode, const QmlDesigner::PropertyName &name, QVariant *value)
|
static void fixUrl(const QmlDesigner::ModelNode &modelNode, const QmlDesigner::PropertyName &name, QVariant *value)
|
||||||
{
|
{
|
||||||
if (modelNode.isValid() && modelNode.metaInfo().isValid()
|
if (modelNode.isValid()) {
|
||||||
&& (modelNode.metaInfo().propertyTypeName(name) == "QUrl"
|
if (auto metaInfo = modelNode.metaInfo();
|
||||||
|| modelNode.metaInfo().propertyTypeName(name) == "url")) {
|
metaInfo.isValid() && metaInfo.property(name).hasPropertyTypeName("QUrl", "url"))
|
||||||
|
|
||||||
if (!value->isValid())
|
if (!value->isValid())
|
||||||
*value = QStringLiteral("");
|
*value = QStringLiteral("");
|
||||||
}
|
}
|
||||||
@@ -140,9 +146,13 @@ void PropertyEditorValue::setValueWithEmit(const QVariant &value)
|
|||||||
{
|
{
|
||||||
if (!compareVariants(value, m_value ) || isBound()) {
|
if (!compareVariants(value, m_value ) || isBound()) {
|
||||||
QVariant newValue = value;
|
QVariant newValue = value;
|
||||||
if (modelNode().isValid() && modelNode().metaInfo().isValid() && modelNode().metaInfo().hasProperty(name()))
|
if (modelNode().isValid()) {
|
||||||
if (modelNode().metaInfo().propertyTypeName(name()) == "QUrl")
|
if (auto metaInfo = modelNode().metaInfo();
|
||||||
|
metaInfo.isValid() && metaInfo.hasProperty(name())
|
||||||
|
&& metaInfo.property(name()).hasPropertyTypeName("QUrl")) {
|
||||||
newValue = QUrl(newValue.toString());
|
newValue = QUrl(newValue.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (cleverDoubleCompare(newValue, m_value))
|
if (cleverDoubleCompare(newValue, m_value))
|
||||||
return;
|
return;
|
||||||
@@ -255,12 +265,14 @@ void PropertyEditorValue::setIsValid(bool valid)
|
|||||||
|
|
||||||
bool PropertyEditorValue::isTranslated() const
|
bool PropertyEditorValue::isTranslated() const
|
||||||
{
|
{
|
||||||
if (modelNode().isValid() && modelNode().metaInfo().isValid() && modelNode().metaInfo().hasProperty(name())) {
|
if (modelNode().isValid()) {
|
||||||
if (modelNode().metaInfo().propertyTypeName(name()) == "QString" || modelNode().metaInfo().propertyTypeName(name()) == "string") {
|
if (auto metaInfo = modelNode().metaInfo();
|
||||||
|
metaInfo.isValid() && metaInfo.hasProperty(name())
|
||||||
|
&& metaInfo.property(name()).hasPropertyTypeName("QString", "string")) {
|
||||||
const QmlDesigner::QmlObjectNode objectNode(modelNode());
|
const QmlDesigner::QmlObjectNode objectNode(modelNode());
|
||||||
if (objectNode.isValid() && objectNode.hasBindingProperty(name())) {
|
if (objectNode.isValid() && objectNode.hasBindingProperty(name())) {
|
||||||
const QRegularExpression rx(QRegularExpression::anchoredPattern(
|
const QRegularExpression rx(
|
||||||
"qsTr(|Id|anslate)\\(\".*\"\\)"));
|
QRegularExpression::anchoredPattern("qsTr(|Id|anslate)\\(\".*\"\\)"));
|
||||||
//qsTr()
|
//qsTr()
|
||||||
if (objectNode.propertyAffectedByCurrentState(name())) {
|
if (objectNode.propertyAffectedByCurrentState(name())) {
|
||||||
return expression().contains(rx);
|
return expression().contains(rx);
|
||||||
@@ -268,7 +280,6 @@ bool PropertyEditorValue::isTranslated() const
|
|||||||
return modelNode().bindingProperty(name()).expression().contains(rx);
|
return modelNode().bindingProperty(name()).expression().contains(rx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -424,8 +435,10 @@ void PropertyEditorValue::removeAliasExport()
|
|||||||
|
|
||||||
QString PropertyEditorValue::getTranslationContext() const
|
QString PropertyEditorValue::getTranslationContext() const
|
||||||
{
|
{
|
||||||
if (modelNode().isValid() && modelNode().metaInfo().isValid() && modelNode().metaInfo().hasProperty(name())) {
|
if (modelNode().isValid()) {
|
||||||
if (modelNode().metaInfo().propertyTypeName(name()) == "QString" || modelNode().metaInfo().propertyTypeName(name()) == "string") {
|
if (auto metaInfo = modelNode().metaInfo();
|
||||||
|
metaInfo.isValid() && metaInfo.hasProperty(name())
|
||||||
|
&& metaInfo.property(name()).hasPropertyTypeName("QString", "string")) {
|
||||||
const QmlDesigner::QmlObjectNode objectNode(modelNode());
|
const QmlDesigner::QmlObjectNode objectNode(modelNode());
|
||||||
if (objectNode.isValid() && objectNode.hasBindingProperty(name())) {
|
if (objectNode.isValid() && objectNode.hasBindingProperty(name())) {
|
||||||
const QRegularExpression rx(QRegularExpression::anchoredPattern(
|
const QRegularExpression rx(QRegularExpression::anchoredPattern(
|
||||||
@@ -519,7 +532,7 @@ bool PropertyEditorValue::idListReplace(int idx, const QString &value)
|
|||||||
void PropertyEditorValue::commitDrop(const QString &path)
|
void PropertyEditorValue::commitDrop(const QString &path)
|
||||||
{
|
{
|
||||||
if (m_modelNode.isSubclassOf("QtQuick3D.Material")
|
if (m_modelNode.isSubclassOf("QtQuick3D.Material")
|
||||||
&& m_modelNode.metaInfo().propertyTypeName(m_name) == "QtQuick3D.Texture") {
|
&& m_modelNode.metaInfo().property(m_name).hasPropertyTypeName("QtQuick3D.Texture")) {
|
||||||
// create a texture node
|
// create a texture node
|
||||||
QmlDesigner::NodeMetaInfo metaInfo = m_modelNode.view()->model()->metaInfo("QtQuick3D.Texture");
|
QmlDesigner::NodeMetaInfo metaInfo = m_modelNode.view()->model()->metaInfo("QtQuick3D.Texture");
|
||||||
QmlDesigner::ModelNode texture = m_modelNode.view()->createModelNode("QtQuick3D.Texture",
|
QmlDesigner::ModelNode texture = m_modelNode.view()->createModelNode("QtQuick3D.Texture",
|
||||||
@@ -618,8 +631,12 @@ void PropertyEditorNodeWrapper::add(const QString &type)
|
|||||||
QmlDesigner::TypeName propertyType = type.toUtf8();
|
QmlDesigner::TypeName propertyType = type.toUtf8();
|
||||||
|
|
||||||
if ((m_editorValue && m_editorValue->modelNode().isValid())) {
|
if ((m_editorValue && m_editorValue->modelNode().isValid())) {
|
||||||
if (propertyType.isEmpty())
|
if (propertyType.isEmpty()) {
|
||||||
propertyType = m_editorValue->modelNode().metaInfo().propertyTypeName(m_editorValue->name());
|
propertyType = m_editorValue->modelNode()
|
||||||
|
.metaInfo()
|
||||||
|
.property(m_editorValue->name())
|
||||||
|
.propertyTypeName();
|
||||||
|
}
|
||||||
while (propertyType.contains('*')) //strip star
|
while (propertyType.contains('*')) //strip star
|
||||||
propertyType.chop(1);
|
propertyType.chop(1);
|
||||||
m_modelNode = m_editorValue->modelNode().view()->createModelNode(propertyType, 4, 7);
|
m_modelNode = m_editorValue->modelNode().view()->createModelNode(propertyType, 4, 7);
|
||||||
@@ -681,9 +698,9 @@ void PropertyEditorNodeWrapper::setup()
|
|||||||
m_valuesPropertyMap.clear(propertyName);
|
m_valuesPropertyMap.clear(propertyName);
|
||||||
qDeleteAll(m_valuesPropertyMap.children());
|
qDeleteAll(m_valuesPropertyMap.children());
|
||||||
|
|
||||||
const QList<QmlDesigner::PropertyName> propertyNameList = m_modelNode.metaInfo().propertyNames();
|
|
||||||
for (const QmlDesigner::PropertyName &propertyName : propertyNameList) {
|
|
||||||
if (qmlObjectNode.isValid()) {
|
if (qmlObjectNode.isValid()) {
|
||||||
|
for (const auto &property : m_modelNode.metaInfo().properties()) {
|
||||||
|
const auto &propertyName = property.name();
|
||||||
auto valueObject = new PropertyEditorValue(&m_valuesPropertyMap);
|
auto valueObject = new PropertyEditorValue(&m_valuesPropertyMap);
|
||||||
valueObject->setName(propertyName);
|
valueObject->setName(propertyName);
|
||||||
valueObject->setValue(qmlObjectNode.instanceValue(propertyName));
|
valueObject->setValue(qmlObjectNode.instanceValue(propertyName));
|
||||||
|
@@ -185,7 +185,7 @@ void PropertyEditorView::changeValue(const QString &name)
|
|||||||
QVariant castedValue;
|
QVariant castedValue;
|
||||||
|
|
||||||
if (metaInfo.isValid() && metaInfo.hasProperty(propertyName)) {
|
if (metaInfo.isValid() && metaInfo.hasProperty(propertyName)) {
|
||||||
castedValue = metaInfo.propertyCastedValue(propertyName, value->value());
|
castedValue = metaInfo.property(propertyName).castedValue(value->value());
|
||||||
} else if (propertyIsAttachedLayoutProperty(propertyName)) {
|
} else if (propertyIsAttachedLayoutProperty(propertyName)) {
|
||||||
castedValue = value->value();
|
castedValue = value->value();
|
||||||
} else {
|
} else {
|
||||||
@@ -200,9 +200,8 @@ void PropertyEditorView::changeValue(const QString &name)
|
|||||||
|
|
||||||
bool propertyTypeUrl = false;
|
bool propertyTypeUrl = false;
|
||||||
|
|
||||||
if (metaInfo.isValid() && metaInfo.hasProperty(propertyName)) {
|
if (metaInfo.isValid() && metaInfo.hasProperty(propertyName)
|
||||||
if (metaInfo.propertyTypeName(propertyName) == "QUrl"
|
&& metaInfo.property(propertyName).hasPropertyTypeName("QUrl", "url")) {
|
||||||
|| metaInfo.propertyTypeName(propertyName) == "url") {
|
|
||||||
// turn absolute local file paths into relative paths
|
// turn absolute local file paths into relative paths
|
||||||
propertyTypeUrl = true;
|
propertyTypeUrl = true;
|
||||||
QString filePath = castedValue.toUrl().toString();
|
QString filePath = castedValue.toUrl().toString();
|
||||||
@@ -212,7 +211,6 @@ void PropertyEditorView::changeValue(const QString &name)
|
|||||||
castedValue = QUrl(fileDir.relativeFilePath(filePath));
|
castedValue = QUrl(fileDir.relativeFilePath(filePath));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (name == "state" && castedValue.toString() == "base state")
|
if (name == "state" && castedValue.toString() == "base state")
|
||||||
castedValue = "";
|
castedValue = "";
|
||||||
@@ -272,13 +270,15 @@ void PropertyEditorView::changeExpression(const QString &propertyName)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qmlObjectNode->modelNode().metaInfo().isValid() && qmlObjectNode->modelNode().metaInfo().hasProperty(name)) {
|
if (auto metaInfo = qmlObjectNode->modelNode().metaInfo();
|
||||||
if (qmlObjectNode->modelNode().metaInfo().propertyTypeName(name) == "QColor") {
|
metaInfo.isValid() && metaInfo.hasProperty(name)) {
|
||||||
|
const auto &propertTypeName = metaInfo.property(name).propertyTypeName();
|
||||||
|
if (propertTypeName == "QColor") {
|
||||||
if (QColor(value->expression().remove('"')).isValid()) {
|
if (QColor(value->expression().remove('"')).isValid()) {
|
||||||
qmlObjectNode->setVariantProperty(name, QColor(value->expression().remove('"')));
|
qmlObjectNode->setVariantProperty(name, QColor(value->expression().remove('"')));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (qmlObjectNode->modelNode().metaInfo().propertyTypeName(name) == "bool") {
|
} else if (propertTypeName == "bool") {
|
||||||
if (isTrueFalseLiteral(value->expression())) {
|
if (isTrueFalseLiteral(value->expression())) {
|
||||||
if (value->expression().compare("true", Qt::CaseInsensitive) == 0)
|
if (value->expression().compare("true", Qt::CaseInsensitive) == 0)
|
||||||
qmlObjectNode->setVariantProperty(name, true);
|
qmlObjectNode->setVariantProperty(name, true);
|
||||||
@@ -286,21 +286,21 @@ void PropertyEditorView::changeExpression(const QString &propertyName)
|
|||||||
qmlObjectNode->setVariantProperty(name, false);
|
qmlObjectNode->setVariantProperty(name, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (qmlObjectNode->modelNode().metaInfo().propertyTypeName(name) == "int") {
|
} else if (propertTypeName == "int") {
|
||||||
bool ok;
|
bool ok;
|
||||||
int intValue = value->expression().toInt(&ok);
|
int intValue = value->expression().toInt(&ok);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
qmlObjectNode->setVariantProperty(name, intValue);
|
qmlObjectNode->setVariantProperty(name, intValue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (qmlObjectNode->modelNode().metaInfo().propertyTypeName(name) == "qreal") {
|
} else if (propertTypeName == "qreal") {
|
||||||
bool ok;
|
bool ok;
|
||||||
qreal realValue = value->expression().toDouble(&ok);
|
qreal realValue = value->expression().toDouble(&ok);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
qmlObjectNode->setVariantProperty(name, realValue);
|
qmlObjectNode->setVariantProperty(name, realValue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (qmlObjectNode->modelNode().metaInfo().propertyTypeName(name) == "QVariant") {
|
} else if (propertTypeName == "QVariant") {
|
||||||
bool ok;
|
bool ok;
|
||||||
qreal realValue = value->expression().toDouble(&ok);
|
qreal realValue = value->expression().toDouble(&ok);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
|
@@ -53,15 +53,8 @@ namespace {
|
|||||||
bool modelNodeHasUrlSource(const QmlDesigner::ModelNode &modelNode)
|
bool modelNodeHasUrlSource(const QmlDesigner::ModelNode &modelNode)
|
||||||
{
|
{
|
||||||
QmlDesigner::NodeMetaInfo metaInfo = modelNode.metaInfo();
|
QmlDesigner::NodeMetaInfo metaInfo = modelNode.metaInfo();
|
||||||
if (metaInfo.isValid()) {
|
return metaInfo.isValid() && metaInfo.hasProperty("source")
|
||||||
if (metaInfo.hasProperty("source")) {
|
&& metaInfo.property("source").hasPropertyTypeName("QUrl", "url");
|
||||||
if (metaInfo.propertyTypeName("source") == "QUrl")
|
|
||||||
return true;
|
|
||||||
if (metaInfo.propertyTypeName("source") == "url")
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} //namespace
|
} //namespace
|
||||||
|
@@ -234,8 +234,10 @@ TimelinePropertyItem *TimelinePropertyItem::create(const QmlTimelineKeyframeGrou
|
|||||||
if (!objectNode.isValid())
|
if (!objectNode.isValid())
|
||||||
return item;
|
return item;
|
||||||
|
|
||||||
auto nameOfType = objectNode.modelNode().metaInfo().propertyTypeName(
|
auto nameOfType = objectNode.modelNode()
|
||||||
item->m_frames.propertyName());
|
.metaInfo()
|
||||||
|
.property(item->m_frames.propertyName())
|
||||||
|
.propertyTypeName();
|
||||||
item->m_control = createTimelineControl(nameOfType);
|
item->m_control = createTimelineControl(nameOfType);
|
||||||
if (item->m_control) {
|
if (item->m_control) {
|
||||||
item->m_control->setSize((TimelineConstants::sectionWidth / 2.6) - 10,
|
item->m_control->setSize((TimelineConstants::sectionWidth / 2.6) - 10,
|
||||||
|
@@ -226,7 +226,7 @@ ModelNode TransitionEditorView::addNewTransition()
|
|||||||
if (target.isValid() && target.hasMetaInfo()) {
|
if (target.isValid() && target.hasMetaInfo()) {
|
||||||
const QString targetId = target.id();
|
const QString targetId = target.id();
|
||||||
for (const VariantProperty &property : change.modelNode().variantProperties()) {
|
for (const VariantProperty &property : change.modelNode().variantProperties()) {
|
||||||
TypeName typeName = target.metaInfo().propertyTypeName(property.name());
|
TypeName typeName = target.metaInfo().property(property.name()).propertyTypeName();
|
||||||
if (typeName.startsWith("<cpp>."))
|
if (typeName.startsWith("<cpp>."))
|
||||||
typeName.remove(0, 6);
|
typeName.remove(0, 6);
|
||||||
|
|
||||||
|
@@ -0,0 +1,51 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file 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 file. 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <qmldesignercorelib_global.h>
|
||||||
|
|
||||||
|
#include <QSharedPointer>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class EnumerationMetaInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EnumerationMetaInfo(QSharedPointer<class NodeMetaInfoPrivate> nodeMetaInfoPrivateData,
|
||||||
|
const TypeName &enumeration);
|
||||||
|
~EnumerationMetaInfo();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSharedPointer<class NodeMetaInfoPrivate> m_nodeMetaInfoPrivateData;
|
||||||
|
const TypeName &m_enumeration;
|
||||||
|
};
|
||||||
|
|
||||||
|
using EnumerationMetaInfos = std::vector<EnumerationMetaInfo>;
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -42,6 +42,7 @@ class ItemLibraryInfo;
|
|||||||
namespace Internal {
|
namespace Internal {
|
||||||
class MetaInfoPrivate;
|
class MetaInfoPrivate;
|
||||||
class ModelPrivate;
|
class ModelPrivate;
|
||||||
|
class MetaInfoReader;
|
||||||
class SubComponentManagerPrivate;
|
class SubComponentManagerPrivate;
|
||||||
using MetaInfoPrivatePointer = QSharedPointer<MetaInfoPrivate>;
|
using MetaInfoPrivatePointer = QSharedPointer<MetaInfoPrivate>;
|
||||||
}
|
}
|
||||||
|
@@ -44,8 +44,7 @@ namespace QmlDesigner {
|
|||||||
namespace Internal {
|
namespace Internal {
|
||||||
class ModelPrivate;
|
class ModelPrivate;
|
||||||
class WriteLocker;
|
class WriteLocker;
|
||||||
class NodeMetaInfoPrivate;
|
} //Internal
|
||||||
} // namespace Internal
|
|
||||||
|
|
||||||
class AnchorLine;
|
class AnchorLine;
|
||||||
class ModelNode;
|
class ModelNode;
|
||||||
@@ -70,7 +69,7 @@ class QMLDESIGNERCORE_EXPORT Model : public QObject
|
|||||||
friend AbstractView;
|
friend AbstractView;
|
||||||
friend Internal::ModelPrivate;
|
friend Internal::ModelPrivate;
|
||||||
friend Internal::WriteLocker;
|
friend Internal::WriteLocker;
|
||||||
friend Internal::NodeMetaInfoPrivate;
|
friend class NodeMetaInfoPrivate;
|
||||||
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@@ -141,4 +140,4 @@ private:
|
|||||||
Internal::ModelPrivate *d;
|
Internal::ModelPrivate *d;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
}
|
||||||
|
@@ -174,7 +174,7 @@ public:
|
|||||||
Model *model() const;
|
Model *model() const;
|
||||||
AbstractView *view() const;
|
AbstractView *view() const;
|
||||||
|
|
||||||
const NodeMetaInfo metaInfo() const;
|
NodeMetaInfo metaInfo() const;
|
||||||
bool hasMetaInfo() const;
|
bool hasMetaInfo() const;
|
||||||
|
|
||||||
bool isSelected() const;
|
bool isSelected() const;
|
||||||
|
@@ -25,12 +25,15 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "invalidmetainfoexception.h"
|
||||||
|
#include "propertymetainfo.h"
|
||||||
|
#include "qmldesignercorelib_global.h"
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
|
||||||
#include "qmldesignercorelib_global.h"
|
#include <vector>
|
||||||
#include "invalidmetainfoexception.h"
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QDeclarativeContext;
|
class QDeclarativeContext;
|
||||||
@@ -42,14 +45,6 @@ class MetaInfo;
|
|||||||
class Model;
|
class Model;
|
||||||
class AbstractProperty;
|
class AbstractProperty;
|
||||||
|
|
||||||
namespace Internal {
|
|
||||||
class MetaInfoPrivate;
|
|
||||||
class MetaInfoReader;
|
|
||||||
class SubComponentManagerPrivate;
|
|
||||||
class ItemLibraryEntryData;
|
|
||||||
class NodeMetaInfoPrivate;
|
|
||||||
}
|
|
||||||
|
|
||||||
class QMLDESIGNERCORE_EXPORT NodeMetaInfo
|
class QMLDESIGNERCORE_EXPORT NodeMetaInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -64,20 +59,13 @@ public:
|
|||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
bool isFileComponent() const;
|
bool isFileComponent() const;
|
||||||
bool hasProperty(const PropertyName &propertyName) const;
|
bool hasProperty(const PropertyName &propertyName) const;
|
||||||
PropertyNameList propertyNames() const;
|
PropertyMetaInfos properties() const;
|
||||||
|
PropertyMetaInfos localProperties() const;
|
||||||
|
PropertyMetaInfo property(const PropertyName &propertyName) const;
|
||||||
PropertyNameList signalNames() const;
|
PropertyNameList signalNames() const;
|
||||||
PropertyNameList slotNames() const;
|
PropertyNameList slotNames() const;
|
||||||
PropertyNameList directPropertyNames() const;
|
|
||||||
PropertyName defaultPropertyName() const;
|
PropertyName defaultPropertyName() const;
|
||||||
bool hasDefaultProperty() const;
|
bool hasDefaultProperty() const;
|
||||||
TypeName propertyTypeName(const PropertyName &propertyName) const;
|
|
||||||
bool propertyIsWritable(const PropertyName &propertyName) const;
|
|
||||||
bool propertyIsListProperty(const PropertyName &propertyName) const;
|
|
||||||
bool propertyIsEnumType(const PropertyName &propertyName) const;
|
|
||||||
bool propertyIsPrivate(const PropertyName &propertyName) const;
|
|
||||||
bool propertyIsPointer(const PropertyName &propertyName) const;
|
|
||||||
QStringList propertyKeysForEnum(const PropertyName &propertyName) const;
|
|
||||||
QVariant propertyCastedValue(const PropertyName &propertyName, const QVariant &value) const;
|
|
||||||
|
|
||||||
QList<NodeMetaInfo> classHierarchy() const;
|
QList<NodeMetaInfo> classHierarchy() const;
|
||||||
QList<NodeMetaInfo> superClasses() const;
|
QList<NodeMetaInfo> superClasses() const;
|
||||||
@@ -104,7 +92,9 @@ public:
|
|||||||
QString importDirectoryPath() const;
|
QString importDirectoryPath() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSharedPointer<Internal::NodeMetaInfoPrivate> m_privateData;
|
QSharedPointer<class NodeMetaInfoPrivate> m_privateData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using NodeMetaInfos = std::vector<NodeMetaInfo>;
|
||||||
|
|
||||||
} //QmlDesigner
|
} //QmlDesigner
|
||||||
|
@@ -0,0 +1,69 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file 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 file. 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <qmldesignercorelib_global.h>
|
||||||
|
|
||||||
|
#include <QSharedPointer>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class PropertyMetaInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PropertyMetaInfo(QSharedPointer<class NodeMetaInfoPrivate> nodeMetaInfoPrivateData,
|
||||||
|
const PropertyName &propertyName);
|
||||||
|
~PropertyMetaInfo();
|
||||||
|
|
||||||
|
const TypeName &propertyTypeName() const;
|
||||||
|
class NodeMetaInfo propertyNodeMetaInfo() const;
|
||||||
|
|
||||||
|
bool isWritable() const;
|
||||||
|
bool isListProperty() const;
|
||||||
|
bool isEnumType() const;
|
||||||
|
bool isPrivate() const;
|
||||||
|
bool isPointer() const;
|
||||||
|
QVariant castedValue(const QVariant &value) const;
|
||||||
|
const PropertyName &name() const & { return m_propertyName; }
|
||||||
|
|
||||||
|
template<typename... TypeName>
|
||||||
|
bool hasPropertyTypeName(const TypeName &...typeName) const
|
||||||
|
{
|
||||||
|
auto propertyTypeName_ = propertyTypeName();
|
||||||
|
return ((propertyTypeName_ == typeName) || ...);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSharedPointer<class NodeMetaInfoPrivate> m_nodeMetaInfoPrivateData;
|
||||||
|
PropertyName m_propertyName;
|
||||||
|
};
|
||||||
|
|
||||||
|
using PropertyMetaInfos = std::vector<PropertyMetaInfo>;
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -212,12 +212,14 @@ public:
|
|||||||
void setStartFlowItem(const QmlFlowItemNode &flowItem);
|
void setStartFlowItem(const QmlFlowItemNode &flowItem);
|
||||||
ModelNode createTransition();
|
ModelNode createTransition();
|
||||||
|
|
||||||
static PropertyNameList st_mouseSignals;
|
|
||||||
static QList<QmlConnections> getAssociatedConnections(const ModelNode &node);
|
static QList<QmlConnections> getAssociatedConnections(const ModelNode &node);
|
||||||
|
static const PropertyNameList &mouseSignals() { return s_mouseSignals; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QList<ModelNode> transitionsForProperty(const PropertyName &propertyName, const ModelNode &modelNode);
|
QList<ModelNode> transitionsForProperty(const PropertyName &propertyName, const ModelNode &modelNode);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static PropertyNameList s_mouseSignals;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -46,17 +46,6 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
struct TypeDescription
|
|
||||||
{
|
|
||||||
QString className;
|
|
||||||
int minorVersion{};
|
|
||||||
int majorVersion{};
|
|
||||||
};
|
|
||||||
|
|
||||||
} //Internal
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class QmlDesigner::NodeMetaInfo
|
\class QmlDesigner::NodeMetaInfo
|
||||||
\ingroup CoreModel
|
\ingroup CoreModel
|
||||||
@@ -74,7 +63,14 @@ NodeMetaInfo object will result in an InvalidMetaInfoException being thrown.
|
|||||||
\see QmlDesigner::MetaInfo, QmlDesigner::PropertyMetaInfo, QmlDesigner::EnumeratorMetaInfo
|
\see QmlDesigner::MetaInfo, QmlDesigner::PropertyMetaInfo, QmlDesigner::EnumeratorMetaInfo
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Internal {
|
namespace {
|
||||||
|
|
||||||
|
struct TypeDescription
|
||||||
|
{
|
||||||
|
QString className;
|
||||||
|
int minorVersion{};
|
||||||
|
int majorVersion{};
|
||||||
|
};
|
||||||
|
|
||||||
using namespace QmlJS;
|
using namespace QmlJS;
|
||||||
|
|
||||||
@@ -516,6 +512,9 @@ PropertyNameList getSignals(const ObjectValue *objectValue, const ContextPtr &co
|
|||||||
signalList.append(getSignals(prototype, context, true));
|
signalList.append(getSignals(prototype, context, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::sort(signalList.begin(), signalList.end());
|
||||||
|
signalList.erase(std::unique(signalList.begin(), signalList.end()), signalList.end());
|
||||||
|
|
||||||
return signalList;
|
return signalList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,6 +543,9 @@ PropertyNameList getSlots(const ObjectValue *objectValue, const ContextPtr &cont
|
|||||||
slotList.append(getSlots(prototype, context, true));
|
slotList.append(getSlots(prototype, context, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::sort(slotList.begin(), slotList.end());
|
||||||
|
slotList.erase(std::unique(slotList.begin(), slotList.end()), slotList.end());
|
||||||
|
|
||||||
return slotList;
|
return slotList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -604,6 +606,7 @@ QVector<PropertyInfo> getObjectTypes(const ObjectValue *objectValue, const Conte
|
|||||||
|
|
||||||
return propertyList;
|
return propertyList;
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
class NodeMetaInfoPrivate
|
class NodeMetaInfoPrivate
|
||||||
{
|
{
|
||||||
@@ -614,12 +617,12 @@ public:
|
|||||||
|
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
bool isFileComponent() const;
|
bool isFileComponent() const;
|
||||||
PropertyNameList properties() const;
|
const PropertyNameList &properties() const;
|
||||||
PropertyNameList localProperties() const;
|
const PropertyNameList &localProperties() const;
|
||||||
PropertyNameList signalNames() const;
|
PropertyNameList signalNames() const;
|
||||||
PropertyNameList slotNames() const;
|
PropertyNameList slotNames() const;
|
||||||
PropertyName defaultPropertyName() const;
|
PropertyName defaultPropertyName() const;
|
||||||
TypeName propertyType(const PropertyName &propertyName) const;
|
const TypeName &propertyType(const PropertyName &propertyName) const;
|
||||||
|
|
||||||
void setupPrototypes();
|
void setupPrototypes();
|
||||||
QList<TypeDescription> prototypes() const;
|
QList<TypeDescription> prototypes() const;
|
||||||
@@ -634,7 +637,7 @@ public:
|
|||||||
|
|
||||||
int majorVersion() const;
|
int majorVersion() const;
|
||||||
int minorVersion() const;
|
int minorVersion() const;
|
||||||
TypeName qualfiedTypeName() const;
|
const TypeName &qualfiedTypeName() const;
|
||||||
Model *model() const;
|
Model *model() const;
|
||||||
|
|
||||||
QByteArray cppPackageName() const;
|
QByteArray cppPackageName() const;
|
||||||
@@ -691,14 +694,14 @@ bool NodeMetaInfoPrivate::isFileComponent() const
|
|||||||
return m_isFileComponent;
|
return m_isFileComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyNameList NodeMetaInfoPrivate::properties() const
|
const PropertyNameList &NodeMetaInfoPrivate::properties() const
|
||||||
{
|
{
|
||||||
ensureProperties();
|
ensureProperties();
|
||||||
|
|
||||||
return m_properties;
|
return m_properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyNameList NodeMetaInfoPrivate::localProperties() const
|
const PropertyNameList &NodeMetaInfoPrivate::localProperties() const
|
||||||
{
|
{
|
||||||
ensureProperties();
|
ensureProperties();
|
||||||
|
|
||||||
@@ -741,8 +744,9 @@ static inline TypeName stringIdentifier( const TypeName &type, int maj, int min)
|
|||||||
|
|
||||||
NodeMetaInfoPrivate::Pointer NodeMetaInfoPrivate::create(Model *model, const TypeName &type, int major, int minor)
|
NodeMetaInfoPrivate::Pointer NodeMetaInfoPrivate::create(Model *model, const TypeName &type, int major, int minor)
|
||||||
{
|
{
|
||||||
if (model->d->m_nodeMetaInfoCache.contains(stringIdentifier(type, major, minor)))
|
auto &&cache = model->d->m_nodeMetaInfoCache;
|
||||||
return model->d->m_nodeMetaInfoCache.value(stringIdentifier(type, major, minor));
|
if (auto found = cache.find(stringIdentifier(type, major, minor)); found != cache.end())
|
||||||
|
return *found;
|
||||||
|
|
||||||
Pointer newData(new NodeMetaInfoPrivate(model, type, major, minor));
|
Pointer newData(new NodeMetaInfoPrivate(model, type, major, minor));
|
||||||
if (newData->isValid())
|
if (newData->isValid())
|
||||||
@@ -1144,7 +1148,7 @@ int NodeMetaInfoPrivate::minorVersion() const
|
|||||||
return m_minorVersion;
|
return m_minorVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeName NodeMetaInfoPrivate::qualfiedTypeName() const
|
const TypeName &NodeMetaInfoPrivate::qualfiedTypeName() const
|
||||||
{
|
{
|
||||||
return m_qualfiedTypeName;
|
return m_qualfiedTypeName;
|
||||||
}
|
}
|
||||||
@@ -1248,12 +1252,16 @@ bool NodeMetaInfoPrivate::isValid() const
|
|||||||
return m_isValid && context() && document();
|
return m_isValid && context() && document();
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeName NodeMetaInfoPrivate::propertyType(const PropertyName &propertyName) const
|
namespace {
|
||||||
|
TypeName nonexistingTypeName("Property does not exist...");
|
||||||
|
}
|
||||||
|
|
||||||
|
const TypeName &NodeMetaInfoPrivate::propertyType(const PropertyName &propertyName) const
|
||||||
{
|
{
|
||||||
ensureProperties();
|
ensureProperties();
|
||||||
|
|
||||||
if (!m_properties.contains(propertyName))
|
if (!m_properties.contains(propertyName))
|
||||||
return TypeName("Property does not exist...");
|
return nonexistingTypeName;
|
||||||
return m_propertyTypes.at(m_properties.indexOf(propertyName));
|
return m_propertyTypes.at(m_properties.indexOf(propertyName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1386,14 +1394,14 @@ void NodeMetaInfoPrivate::initialiseProperties()
|
|||||||
m_slots = getSlots(m_objectValue, context());
|
m_slots = getSlots(m_objectValue, context());
|
||||||
}
|
}
|
||||||
|
|
||||||
} //namespace Internal
|
NodeMetaInfo::NodeMetaInfo()
|
||||||
|
: m_privateData(QSharedPointer<NodeMetaInfoPrivate>::create())
|
||||||
NodeMetaInfo::NodeMetaInfo() : m_privateData(new Internal::NodeMetaInfoPrivate())
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeMetaInfo::NodeMetaInfo(Model *model, const TypeName &type, int maj, int min) : m_privateData(Internal::NodeMetaInfoPrivate::create(model, type, maj, min))
|
NodeMetaInfo::NodeMetaInfo(Model *model, const TypeName &type, int maj, int min)
|
||||||
|
: m_privateData(NodeMetaInfoPrivate::create(model, type, maj, min))
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1422,12 +1430,38 @@ bool NodeMetaInfo::isFileComponent() const
|
|||||||
|
|
||||||
bool NodeMetaInfo::hasProperty(const PropertyName &propertyName) const
|
bool NodeMetaInfo::hasProperty(const PropertyName &propertyName) const
|
||||||
{
|
{
|
||||||
return propertyNames().contains(propertyName);
|
return m_privateData->properties().contains(propertyName);
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyNameList NodeMetaInfo::propertyNames() const
|
PropertyMetaInfos NodeMetaInfo::properties() const
|
||||||
{
|
{
|
||||||
return m_privateData->properties();
|
const auto &properties = m_privateData->properties();
|
||||||
|
|
||||||
|
PropertyMetaInfos propertyMetaInfos;
|
||||||
|
propertyMetaInfos.reserve(static_cast<std::size_t>(properties.size()));
|
||||||
|
|
||||||
|
for (const auto &name : properties)
|
||||||
|
propertyMetaInfos.emplace_back(m_privateData, name);
|
||||||
|
|
||||||
|
return propertyMetaInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyMetaInfos NodeMetaInfo::localProperties() const
|
||||||
|
{
|
||||||
|
const auto &properties = m_privateData->localProperties();
|
||||||
|
|
||||||
|
PropertyMetaInfos propertyMetaInfos;
|
||||||
|
propertyMetaInfos.reserve(static_cast<std::size_t>(properties.size()));
|
||||||
|
|
||||||
|
for (const auto &name : properties)
|
||||||
|
propertyMetaInfos.emplace_back(m_privateData, name);
|
||||||
|
|
||||||
|
return propertyMetaInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyMetaInfo NodeMetaInfo::property(const PropertyName &propertyName) const
|
||||||
|
{
|
||||||
|
return PropertyMetaInfo{m_privateData, propertyName};
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyNameList NodeMetaInfo::signalNames() const
|
PropertyNameList NodeMetaInfo::signalNames() const
|
||||||
@@ -1440,11 +1474,6 @@ PropertyNameList NodeMetaInfo::slotNames() const
|
|||||||
return m_privateData->slotNames();
|
return m_privateData->slotNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyNameList NodeMetaInfo::directPropertyNames() const
|
|
||||||
{
|
|
||||||
return m_privateData->localProperties();
|
|
||||||
}
|
|
||||||
|
|
||||||
PropertyName NodeMetaInfo::defaultPropertyName() const
|
PropertyName NodeMetaInfo::defaultPropertyName() const
|
||||||
{
|
{
|
||||||
return m_privateData->defaultPropertyName();
|
return m_privateData->defaultPropertyName();
|
||||||
@@ -1455,84 +1484,6 @@ bool NodeMetaInfo::hasDefaultProperty() const
|
|||||||
return !defaultPropertyName().isEmpty();
|
return !defaultPropertyName().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeName NodeMetaInfo::propertyTypeName(const PropertyName &propertyName) const
|
|
||||||
{
|
|
||||||
return m_privateData->propertyType(propertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NodeMetaInfo::propertyIsWritable(const PropertyName &propertyName) const
|
|
||||||
{
|
|
||||||
return m_privateData->isPropertyWritable(propertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NodeMetaInfo::propertyIsListProperty(const PropertyName &propertyName) const
|
|
||||||
{
|
|
||||||
return m_privateData->isPropertyList(propertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NodeMetaInfo::propertyIsEnumType(const PropertyName &propertyName) const
|
|
||||||
{
|
|
||||||
return m_privateData->isPropertyEnum(propertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NodeMetaInfo::propertyIsPrivate(const PropertyName &propertyName) const
|
|
||||||
{
|
|
||||||
return propertyName.startsWith("__");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NodeMetaInfo::propertyIsPointer(const PropertyName &propertyName) const
|
|
||||||
{
|
|
||||||
return m_privateData->isPropertyPointer(propertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList NodeMetaInfo::propertyKeysForEnum(const PropertyName &propertyName) const
|
|
||||||
{
|
|
||||||
return m_privateData->keysForEnum(QString::fromUtf8(propertyTypeName(propertyName)));
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant NodeMetaInfo::propertyCastedValue(const PropertyName &propertyName, const QVariant &value) const
|
|
||||||
{
|
|
||||||
const QVariant variant = value;
|
|
||||||
QVariant copyVariant = variant;
|
|
||||||
if (propertyIsEnumType(propertyName)
|
|
||||||
|| variant.canConvert<Enumeration>())
|
|
||||||
return variant;
|
|
||||||
|
|
||||||
const TypeName typeName = propertyTypeName(propertyName);
|
|
||||||
|
|
||||||
QVariant::Type typeId = m_privateData->variantTypeId(propertyName);
|
|
||||||
|
|
||||||
if (variant.type() == QVariant::UserType && variant.userType() == ModelNode::variantUserType()) {
|
|
||||||
return variant;
|
|
||||||
} else if (typeId == QVariant::UserType && typeName == "QVariant") {
|
|
||||||
return variant;
|
|
||||||
} else if (typeId == QVariant::UserType && typeName == "variant") {
|
|
||||||
return variant;
|
|
||||||
} else if (typeId == QVariant::UserType && typeName == "var") {
|
|
||||||
return variant;
|
|
||||||
} else if (variant.type() == QVariant::List) {
|
|
||||||
// TODO: check the contents of the list
|
|
||||||
return variant;
|
|
||||||
} else if (typeName == "var" || typeName == "variant") {
|
|
||||||
return variant;
|
|
||||||
} else if (typeName == "alias") {
|
|
||||||
// TODO: The QML compiler resolves the alias type. We probably should do the same.
|
|
||||||
return variant;
|
|
||||||
} else if (typeName == "<cpp>.double") {
|
|
||||||
return variant.toDouble();
|
|
||||||
} else if (typeName == "<cpp>.float") {
|
|
||||||
return variant.toFloat();
|
|
||||||
} else if (typeName == "<cpp>.int") {
|
|
||||||
return variant.toInt();
|
|
||||||
} else if (typeName == "<cpp>.bool") {
|
|
||||||
return variant.toBool();
|
|
||||||
} else if (copyVariant.convert(typeId)) {
|
|
||||||
return copyVariant;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Internal::PropertyParser::variantFromString(variant.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<NodeMetaInfo> NodeMetaInfo::classHierarchy() const
|
QList<NodeMetaInfo> NodeMetaInfo::classHierarchy() const
|
||||||
{
|
{
|
||||||
QList<NodeMetaInfo> hierarchy = {*this};
|
QList<NodeMetaInfo> hierarchy = {*this};
|
||||||
@@ -1543,7 +1494,7 @@ QList<NodeMetaInfo> NodeMetaInfo::classHierarchy() const
|
|||||||
QList<NodeMetaInfo> NodeMetaInfo::superClasses() const
|
QList<NodeMetaInfo> NodeMetaInfo::superClasses() const
|
||||||
{
|
{
|
||||||
Model *model = m_privateData->model();
|
Model *model = m_privateData->model();
|
||||||
return Utils::transform(m_privateData->prototypes(), [model](const Internal::TypeDescription &type) {
|
return Utils::transform(m_privateData->prototypes(), [model](const TypeDescription &type) {
|
||||||
return NodeMetaInfo(model, type.className.toUtf8(), type.majorVersion, type.minorVersion);
|
return NodeMetaInfo(model, type.className.toUtf8(), type.majorVersion, type.minorVersion);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1556,7 +1507,7 @@ NodeMetaInfo NodeMetaInfo::directSuperClass() const
|
|||||||
bool NodeMetaInfo::defaultPropertyIsComponent() const
|
bool NodeMetaInfo::defaultPropertyIsComponent() const
|
||||||
{
|
{
|
||||||
if (hasDefaultProperty())
|
if (hasDefaultProperty())
|
||||||
return propertyTypeName(defaultPropertyName()) == "Component";
|
return property(defaultPropertyName()).hasPropertyTypeName("Component");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1613,21 +1564,24 @@ bool NodeMetaInfo::isSubclassOf(const TypeName &type, int majorVersion, int mino
|
|||||||
if (typeName() == type && availableInVersion(majorVersion, minorVersion))
|
if (typeName() == type && availableInVersion(majorVersion, minorVersion))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (m_privateData->prototypeCachePositives().contains(Internal::stringIdentifier(type, majorVersion, minorVersion)))
|
if (m_privateData->prototypeCachePositives().contains(
|
||||||
|
stringIdentifier(type, majorVersion, minorVersion)))
|
||||||
return true; //take a shortcut - optimization
|
return true; //take a shortcut - optimization
|
||||||
|
|
||||||
if (m_privateData->prototypeCacheNegatives().contains(Internal::stringIdentifier(type, majorVersion, minorVersion)))
|
if (m_privateData->prototypeCacheNegatives().contains(
|
||||||
|
stringIdentifier(type, majorVersion, minorVersion)))
|
||||||
return false; //take a shortcut - optimization
|
return false; //take a shortcut - optimization
|
||||||
|
|
||||||
const QList<NodeMetaInfo> superClassList = superClasses();
|
const QList<NodeMetaInfo> superClassList = superClasses();
|
||||||
for (const NodeMetaInfo &superClass : superClassList) {
|
for (const NodeMetaInfo &superClass : superClassList) {
|
||||||
if (superClass.m_privateData->cleverCheckType(type)
|
if (superClass.m_privateData->cleverCheckType(type)
|
||||||
&& superClass.availableInVersion(majorVersion, minorVersion)) {
|
&& superClass.availableInVersion(majorVersion, minorVersion)) {
|
||||||
m_privateData->prototypeCachePositives().insert(Internal::stringIdentifier(type, majorVersion, minorVersion));
|
m_privateData->prototypeCachePositives().insert(
|
||||||
|
stringIdentifier(type, majorVersion, minorVersion));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_privateData->prototypeCacheNegatives().insert(Internal::stringIdentifier(type, majorVersion, minorVersion));
|
m_privateData->prototypeCacheNegatives().insert(stringIdentifier(type, majorVersion, minorVersion));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1668,4 +1622,90 @@ bool NodeMetaInfo::isTabView() const
|
|||||||
return isSubclassOf("QtQuick.Controls.TabView");
|
return isSubclassOf("QtQuick.Controls.TabView");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PropertyMetaInfo::PropertyMetaInfo(QSharedPointer<NodeMetaInfoPrivate> nodeMetaInfoPrivateData,
|
||||||
|
const PropertyName &propertyName)
|
||||||
|
: m_nodeMetaInfoPrivateData{nodeMetaInfoPrivateData}
|
||||||
|
, m_propertyName{propertyName}
|
||||||
|
|
||||||
|
{}
|
||||||
|
|
||||||
|
PropertyMetaInfo::~PropertyMetaInfo() {}
|
||||||
|
|
||||||
|
const TypeName &PropertyMetaInfo::propertyTypeName() const
|
||||||
|
{
|
||||||
|
return m_nodeMetaInfoPrivateData->propertyType(m_propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeMetaInfo PropertyMetaInfo::propertyNodeMetaInfo() const
|
||||||
|
{
|
||||||
|
return m_nodeMetaInfoPrivateData->model()->metaInfo(propertyTypeName());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PropertyMetaInfo::isWritable() const
|
||||||
|
{
|
||||||
|
return m_nodeMetaInfoPrivateData->isPropertyWritable(m_propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PropertyMetaInfo::isListProperty() const
|
||||||
|
{
|
||||||
|
return m_nodeMetaInfoPrivateData->isPropertyList(m_propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PropertyMetaInfo::isEnumType() const
|
||||||
|
{
|
||||||
|
return m_nodeMetaInfoPrivateData->isPropertyEnum(m_propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PropertyMetaInfo::isPrivate() const
|
||||||
|
{
|
||||||
|
return m_propertyName.startsWith("__");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PropertyMetaInfo::isPointer() const
|
||||||
|
{
|
||||||
|
return m_nodeMetaInfoPrivateData->isPropertyPointer(m_propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant PropertyMetaInfo::castedValue(const QVariant &value) const
|
||||||
|
{
|
||||||
|
const QVariant variant = value;
|
||||||
|
QVariant copyVariant = variant;
|
||||||
|
if (isEnumType() || variant.canConvert<Enumeration>())
|
||||||
|
return variant;
|
||||||
|
|
||||||
|
const TypeName &typeName = propertyTypeName();
|
||||||
|
|
||||||
|
QVariant::Type typeId = m_nodeMetaInfoPrivateData->variantTypeId(m_propertyName);
|
||||||
|
|
||||||
|
if (variant.type() == QVariant::UserType && variant.userType() == ModelNode::variantUserType()) {
|
||||||
|
return variant;
|
||||||
|
} else if (typeId == QVariant::UserType && typeName == "QVariant") {
|
||||||
|
return variant;
|
||||||
|
} else if (typeId == QVariant::UserType && typeName == "variant") {
|
||||||
|
return variant;
|
||||||
|
} else if (typeId == QVariant::UserType && typeName == "var") {
|
||||||
|
return variant;
|
||||||
|
} else if (variant.type() == QVariant::List) {
|
||||||
|
// TODO: check the contents of the list
|
||||||
|
return variant;
|
||||||
|
} else if (typeName == "var" || typeName == "variant") {
|
||||||
|
return variant;
|
||||||
|
} else if (typeName == "alias") {
|
||||||
|
// TODO: The QML compiler resolves the alias type. We probably should do the same.
|
||||||
|
return variant;
|
||||||
|
} else if (typeName == "<cpp>.double") {
|
||||||
|
return variant.toDouble();
|
||||||
|
} else if (typeName == "<cpp>.float") {
|
||||||
|
return variant.toFloat();
|
||||||
|
} else if (typeName == "<cpp>.int") {
|
||||||
|
return variant.toInt();
|
||||||
|
} else if (typeName == "<cpp>.bool") {
|
||||||
|
return variant.toBool();
|
||||||
|
} else if (copyVariant.convert(typeId)) {
|
||||||
|
return copyVariant;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Internal::PropertyParser::variantFromString(variant.toString());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -46,6 +46,7 @@ namespace QmlDesigner {
|
|||||||
class AbstractProperty;
|
class AbstractProperty;
|
||||||
class RewriterView;
|
class RewriterView;
|
||||||
class NodeInstanceView;
|
class NodeInstanceView;
|
||||||
|
class NodeMetaInfoPrivate;
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -85,7 +86,7 @@ class ModelPrivate : public QObject {
|
|||||||
|
|
||||||
friend Model;
|
friend Model;
|
||||||
friend Internal::WriteLocker;
|
friend Internal::WriteLocker;
|
||||||
friend Internal::NodeMetaInfoPrivate;
|
friend NodeMetaInfoPrivate;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ModelPrivate(Model *model);
|
ModelPrivate(Model *model);
|
||||||
|
@@ -855,7 +855,7 @@ bool ModelNode::hasAnySubModelNodes() const
|
|||||||
return !nodeAbstractProperties().isEmpty();
|
return !nodeAbstractProperties().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
const NodeMetaInfo ModelNode::metaInfo() const
|
NodeMetaInfo ModelNode::metaInfo() const
|
||||||
{
|
{
|
||||||
if (!isValid()) {
|
if (!isValid()) {
|
||||||
Q_ASSERT_X(isValid(), Q_FUNC_INFO, "model node is invalid");
|
Q_ASSERT_X(isValid(), Q_FUNC_INFO, "model node is invalid");
|
||||||
|
@@ -33,6 +33,8 @@
|
|||||||
#include "model.h"
|
#include "model.h"
|
||||||
#include "model_p.h"
|
#include "model_p.h"
|
||||||
|
|
||||||
|
#include <nodemetainfo.h>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
NodeAbstractProperty::NodeAbstractProperty() = default;
|
NodeAbstractProperty::NodeAbstractProperty() = default;
|
||||||
@@ -53,10 +55,14 @@ NodeAbstractProperty::NodeAbstractProperty(const Internal::InternalNodeAbstractP
|
|||||||
|
|
||||||
void NodeAbstractProperty::reparentHere(const ModelNode &modelNode)
|
void NodeAbstractProperty::reparentHere(const ModelNode &modelNode)
|
||||||
{
|
{
|
||||||
if (internalNode()->hasProperty(name()) && !internalNode()->property(name())->isNodeAbstractProperty())
|
if (internalNode()->hasProperty(name())
|
||||||
|
&& !internalNode()->property(name())->isNodeAbstractProperty()) {
|
||||||
reparentHere(modelNode, isNodeListProperty());
|
reparentHere(modelNode, isNodeListProperty());
|
||||||
else
|
} else {
|
||||||
reparentHere(modelNode, parentModelNode().metaInfo().propertyIsListProperty(name()) || isDefaultProperty()); //we could use the metasystem instead?
|
reparentHere(modelNode,
|
||||||
|
parentModelNode().metaInfo().property(name()).isListProperty()
|
||||||
|
|| isDefaultProperty()); //we could use the metasystem instead?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeAbstractProperty::reparentHere(const ModelNode &modelNode, bool isNodeList, const TypeName &dynamicTypeName)
|
void NodeAbstractProperty::reparentHere(const ModelNode &modelNode, bool isNodeList, const TypeName &dynamicTypeName)
|
||||||
|
@@ -993,8 +993,14 @@ QList<ModelNode> QmlFlowViewNode::transitionsForProperty(const PropertyName &pro
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyNameList QmlFlowViewNode::st_mouseSignals = { "clicked", "doubleClicked", "pressAndHold",
|
PropertyNameList QmlFlowViewNode::s_mouseSignals = []() {
|
||||||
"pressed", "released", "wheel" };
|
PropertyNameList mouseSignals = {
|
||||||
|
"clicked", "doubleClicked", "pressed", "pressAndHold", "released", "wheel"};
|
||||||
|
|
||||||
|
Q_ASSERT(std::is_sorted(mouseSignals.begin(), mouseSignals.end()));
|
||||||
|
|
||||||
|
return mouseSignals;
|
||||||
|
}();
|
||||||
|
|
||||||
QList<QmlConnections> QmlFlowViewNode::getAssociatedConnections(const ModelNode &node)
|
QList<QmlConnections> QmlFlowViewNode::getAssociatedConnections(const ModelNode &node)
|
||||||
{
|
{
|
||||||
@@ -1020,8 +1026,7 @@ QList<QmlConnections> QmlFlowViewNode::getAssociatedConnections(const ModelNode
|
|||||||
sourceProperty = sourceComponents[1];
|
sourceProperty = sourceComponents[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st_mouseSignals.contains(signalWithoutPrefix)
|
if (mouseSignals().contains(signalWithoutPrefix) && sourceId == node.id()
|
||||||
&& sourceId == node.id()
|
|
||||||
&& sourceProperty == "trigger()")
|
&& sourceProperty == "trigger()")
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -246,8 +246,8 @@ QVariant QmlObjectNode::modelValue(const PropertyName &name) const
|
|||||||
|
|
||||||
bool QmlObjectNode::isTranslatableText(const PropertyName &name) const
|
bool QmlObjectNode::isTranslatableText(const PropertyName &name) const
|
||||||
{
|
{
|
||||||
if (modelNode().metaInfo().isValid() && modelNode().metaInfo().hasProperty(name))
|
if (modelNode().metaInfo().isValid() && modelNode().metaInfo().hasProperty(name)
|
||||||
if (modelNode().metaInfo().propertyTypeName(name) == "QString" || modelNode().metaInfo().propertyTypeName(name) == "string") {
|
&& modelNode().metaInfo().property(name).hasPropertyTypeName("QString", "string")) {
|
||||||
if (modelNode().hasBindingProperty(name)) {
|
if (modelNode().hasBindingProperty(name)) {
|
||||||
static QRegularExpression regularExpressionPattern(
|
static QRegularExpression regularExpressionPattern(
|
||||||
QLatin1String("^qsTr(|Id|anslate)\\(\".*\"\\)$"));
|
QLatin1String("^qsTr(|Id|anslate)\\(\".*\"\\)$"));
|
||||||
|
@@ -213,7 +213,7 @@ TypeName QmlTimelineKeyframeGroup::valueType() const
|
|||||||
TypeName typeName;
|
TypeName typeName;
|
||||||
|
|
||||||
if (targetNode.isValid() && targetNode.hasMetaInfo())
|
if (targetNode.isValid() && targetNode.hasMetaInfo())
|
||||||
typeName = targetNode.metaInfo().propertyTypeName(propertyName());
|
typeName = targetNode.metaInfo().property(propertyName()).propertyTypeName();
|
||||||
|
|
||||||
if (typeName.startsWith("<cpp>."))
|
if (typeName.startsWith("<cpp>."))
|
||||||
typeName.remove(0, 6);
|
typeName.remove(0, 6);
|
||||||
|
@@ -223,7 +223,7 @@ QmlObjectNode QmlVisualNode::createQmlObjectNode(AbstractView *view,
|
|||||||
if (!forceNonDefaultProperty.isEmpty()) {
|
if (!forceNonDefaultProperty.isEmpty()) {
|
||||||
const NodeMetaInfo metaInfo = parentQmlItemNode.modelNode().metaInfo();
|
const NodeMetaInfo metaInfo = parentQmlItemNode.modelNode().metaInfo();
|
||||||
if (metaInfo.hasProperty(forceNonDefaultProperty)) {
|
if (metaInfo.hasProperty(forceNonDefaultProperty)) {
|
||||||
if (!metaInfo.propertyIsListProperty(forceNonDefaultProperty)
|
if (!metaInfo.property(forceNonDefaultProperty).isListProperty()
|
||||||
&& parentQmlItemNode.modelNode().hasNodeProperty(forceNonDefaultProperty)) {
|
&& parentQmlItemNode.modelNode().hasNodeProperty(forceNonDefaultProperty)) {
|
||||||
parentQmlItemNode.removeProperty(forceNonDefaultProperty);
|
parentQmlItemNode.removeProperty(forceNonDefaultProperty);
|
||||||
}
|
}
|
||||||
@@ -324,7 +324,7 @@ QmlObjectNode QmlVisualNode::createQmlObjectNode(AbstractView *view,
|
|||||||
const ModelNode parentNode = parentProperty.parentModelNode();
|
const ModelNode parentNode = parentProperty.parentModelNode();
|
||||||
const NodeMetaInfo metaInfo = parentNode.metaInfo();
|
const NodeMetaInfo metaInfo = parentNode.metaInfo();
|
||||||
|
|
||||||
if (metaInfo.isValid() && !metaInfo.propertyIsListProperty(propertyName)
|
if (metaInfo.isValid() && !metaInfo.property(propertyName).isListProperty()
|
||||||
&& parentProperty.isNodeProperty()) {
|
&& parentProperty.isNodeProperty()) {
|
||||||
parentNode.removeProperty(propertyName);
|
parentNode.removeProperty(propertyName);
|
||||||
}
|
}
|
||||||
|
@@ -337,8 +337,9 @@ bool propertyIsComponentType(const QmlDesigner::NodeAbstractProperty &property,
|
|||||||
if (model->metaInfo(type).isSubclassOf("QtQuick.Component") && !isComponentType(type))
|
if (model->metaInfo(type).isSubclassOf("QtQuick.Component") && !isComponentType(type))
|
||||||
return false; //If the type is already a subclass of Component keep it
|
return false; //If the type is already a subclass of Component keep it
|
||||||
|
|
||||||
return property.parentModelNode().isValid() &&
|
return property.parentModelNode().isValid()
|
||||||
isComponentType(property.parentModelNode().metaInfo().propertyTypeName(property.name()));
|
&& isComponentType(
|
||||||
|
property.parentModelNode().metaInfo().property(property.name()).propertyTypeName());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString extractComponentFromQml(const QString &source)
|
QString extractComponentFromQml(const QString &source)
|
||||||
|
@@ -153,6 +153,7 @@ function(extend_with_qmldesigner_core target_name)
|
|||||||
include/componenttextmodifier.h
|
include/componenttextmodifier.h
|
||||||
include/customnotifications.h
|
include/customnotifications.h
|
||||||
include/documentmessage.h
|
include/documentmessage.h
|
||||||
|
include/enumerationmetainfo.h
|
||||||
include/exception.h
|
include/exception.h
|
||||||
include/forwardview.h
|
include/forwardview.h
|
||||||
include/imagecacheauxiliarydata.h
|
include/imagecacheauxiliarydata.h
|
||||||
@@ -184,6 +185,7 @@ function(extend_with_qmldesigner_core target_name)
|
|||||||
include/notimplementedexception.h
|
include/notimplementedexception.h
|
||||||
include/plaintexteditmodifier.h
|
include/plaintexteditmodifier.h
|
||||||
include/propertycontainer.h
|
include/propertycontainer.h
|
||||||
|
include/propertymetainfo.h
|
||||||
include/propertynode.h
|
include/propertynode.h
|
||||||
include/propertyparser.h
|
include/propertyparser.h
|
||||||
include/qmlanchors.h
|
include/qmlanchors.h
|
||||||
|
@@ -266,6 +266,7 @@ Project {
|
|||||||
"include/bindingproperty.h",
|
"include/bindingproperty.h",
|
||||||
"include/componenttextmodifier.h",
|
"include/componenttextmodifier.h",
|
||||||
"include/customnotifications.h",
|
"include/customnotifications.h",
|
||||||
|
"include/enumerationmetainfo.h",
|
||||||
"include/exception.h",
|
"include/exception.h",
|
||||||
"include/forwardview.h",
|
"include/forwardview.h",
|
||||||
"include/import.h",
|
"include/import.h",
|
||||||
@@ -296,6 +297,7 @@ Project {
|
|||||||
"include/notimplementedexception.h",
|
"include/notimplementedexception.h",
|
||||||
"include/plaintexteditmodifier.h",
|
"include/plaintexteditmodifier.h",
|
||||||
"include/propertycontainer.h",
|
"include/propertycontainer.h",
|
||||||
|
"include/propertymetainfo.h",
|
||||||
"include/propertynode.h",
|
"include/propertynode.h",
|
||||||
"include/propertyparser.h",
|
"include/propertyparser.h",
|
||||||
"include/qmlanchors.h",
|
"include/qmlanchors.h",
|
||||||
|
@@ -130,7 +130,7 @@ public:
|
|||||||
QSize{300, 300},
|
QSize{300, 300},
|
||||||
QSize{1000, 1000},
|
QSize{1000, 1000},
|
||||||
ImageCacheCollectorNullImageHandling::DontCaptureNullImage};
|
ImageCacheCollectorNullImageHandling::DontCaptureNullImage};
|
||||||
TimeStampProvider timeStampProvider;
|
PreviewTimeStampProvider timeStampProvider;
|
||||||
AsynchronousExplicitImageCache cache{storage};
|
AsynchronousExplicitImageCache cache{storage};
|
||||||
AsynchronousImageFactory factory{storage, timeStampProvider, collector};
|
AsynchronousImageFactory factory{storage, timeStampProvider, collector};
|
||||||
};
|
};
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
add_qtc_test(tst_qml_testcore
|
add_qtc_test(tst_qml_testcore
|
||||||
CONDITION TARGET QmlProjectManager
|
CONDITION TARGET QmlProjectManager AND Qt5_VERSION VERSION_GREATER_EQUAL 6.2.0
|
||||||
DEFINES
|
DEFINES
|
||||||
QT_CREATOR
|
QT_CREATOR
|
||||||
QMLDESIGNER_TEST
|
QMLDESIGNER_TEST
|
||||||
|
@@ -4232,6 +4232,17 @@ void tst_TestCore::testCopyModelRewriter2()
|
|||||||
QCOMPARE(stripWhiteSpaces(textEdit2.toPlainText()), stripWhiteSpaces(qmlString1));
|
QCOMPARE(stripWhiteSpaces(textEdit2.toPlainText()), stripWhiteSpaces(qmlString1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
bool contains(const QmlDesigner::PropertyMetaInfos &properties, QUtf8StringView propertyName)
|
||||||
|
{
|
||||||
|
auto found = std::find_if(properties.begin(), properties.end(), [&](const auto &property) {
|
||||||
|
return property.name() == propertyName;
|
||||||
|
});
|
||||||
|
|
||||||
|
return found != properties.end();
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void tst_TestCore::testSubComponentManager()
|
void tst_TestCore::testSubComponentManager()
|
||||||
{
|
{
|
||||||
const QString qmlString("import QtQuick 2.15\n"
|
const QString qmlString("import QtQuick 2.15\n"
|
||||||
@@ -4267,7 +4278,7 @@ void tst_TestCore::testSubComponentManager()
|
|||||||
subComponentManager->update(QUrl::fromLocalFile(fileName), model->imports());
|
subComponentManager->update(QUrl::fromLocalFile(fileName), model->imports());
|
||||||
|
|
||||||
QVERIFY(model->hasNodeMetaInfo("QtQuick.Rectangle", 2, 15));
|
QVERIFY(model->hasNodeMetaInfo("QtQuick.Rectangle", 2, 15));
|
||||||
QVERIFY(model->metaInfo("QtQuick.Rectangle").propertyNames().contains("border.width"));
|
QVERIFY(contains(model->metaInfo("QtQuick.Rectangle").properties(), "border.width"));
|
||||||
|
|
||||||
model->rewriterView()->setTextModifier(&modifier);
|
model->rewriterView()->setTextModifier(&modifier);
|
||||||
|
|
||||||
@@ -4276,14 +4287,14 @@ void tst_TestCore::testSubComponentManager()
|
|||||||
QVERIFY(model->rewriterView()->rootModelNode().isValid());
|
QVERIFY(model->rewriterView()->rootModelNode().isValid());
|
||||||
|
|
||||||
QVERIFY(model->hasNodeMetaInfo("QtQuick.Rectangle", 2, 15));
|
QVERIFY(model->hasNodeMetaInfo("QtQuick.Rectangle", 2, 15));
|
||||||
QVERIFY(model->metaInfo("QtQuick.Rectangle").propertyNames().contains("border.width"));
|
QVERIFY(contains(model->metaInfo("QtQuick.Rectangle").properties(), "border.width"));
|
||||||
|
|
||||||
QVERIFY(model->metaInfo("<cpp>.QQuickPen").isValid());
|
QVERIFY(model->metaInfo("<cpp>.QQuickPen").isValid());
|
||||||
|
|
||||||
QSKIP("File components not working TODO", SkipAll);
|
QSKIP("File components not working TODO", SkipAll);
|
||||||
NodeMetaInfo myButtonMetaInfo = model->metaInfo("MyButton");
|
NodeMetaInfo myButtonMetaInfo = model->metaInfo("MyButton");
|
||||||
QVERIFY(myButtonMetaInfo.isValid());
|
QVERIFY(myButtonMetaInfo.isValid());
|
||||||
QVERIFY(myButtonMetaInfo.propertyNames().contains("border.width"));
|
QVERIFY(contains(myButtonMetaInfo.properties(), "border.width"));
|
||||||
QVERIFY(myButtonMetaInfo.hasProperty("border.width"));
|
QVERIFY(myButtonMetaInfo.hasProperty("border.width"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4638,7 +4649,7 @@ void tst_TestCore::testMetaInfoCustomType()
|
|||||||
QCOMPARE(propertyChangesInfo.superClasses().size(), 3);
|
QCOMPARE(propertyChangesInfo.superClasses().size(), 3);
|
||||||
|
|
||||||
// DeclarativePropertyChanges just has 3 properties
|
// DeclarativePropertyChanges just has 3 properties
|
||||||
QCOMPARE(propertyChangesInfo.propertyNames().size() - stateOperationInfo.propertyNames().size(), 3);
|
QCOMPARE(propertyChangesInfo.properties().size() - stateOperationInfo.properties().size(), 3);
|
||||||
|
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
}
|
}
|
||||||
@@ -4656,15 +4667,13 @@ void tst_TestCore::testMetaInfoEnums()
|
|||||||
|
|
||||||
QVERIFY(view->rootModelNode().metaInfo().hasProperty("transformOrigin"));
|
QVERIFY(view->rootModelNode().metaInfo().hasProperty("transformOrigin"));
|
||||||
|
|
||||||
QVERIFY(view->rootModelNode().metaInfo().propertyIsEnumType("transformOrigin"));
|
QVERIFY(view->rootModelNode().metaInfo().property("transformOrigin").isEnumType());
|
||||||
QCOMPARE(view->rootModelNode().metaInfo().propertyTypeName("transformOrigin"), QmlDesigner::TypeName("TransformOrigin"));
|
QCOMPARE(view->rootModelNode().metaInfo().property("transformOrigin").propertyTypeName(),
|
||||||
QVERIFY(view->rootModelNode().metaInfo().propertyKeysForEnum("transformOrigin").contains(QLatin1String("Bottom")));
|
QmlDesigner::TypeName("TransformOrigin"));
|
||||||
QVERIFY(view->rootModelNode().metaInfo().propertyKeysForEnum("transformOrigin").contains(QLatin1String("Top")));
|
|
||||||
|
|
||||||
QVERIFY(view->rootModelNode().metaInfo().propertyIsEnumType("horizontalAlignment"));
|
QVERIFY(view->rootModelNode().metaInfo().property("horizontalAlignment").isEnumType());
|
||||||
QCOMPARE(view->rootModelNode().metaInfo().propertyTypeName("horizontalAlignment"), QmlDesigner::TypeName("HAlignment"));
|
QCOMPARE(view->rootModelNode().metaInfo().property("horizontalAlignment").propertyTypeName(),
|
||||||
QVERIFY(view->rootModelNode().metaInfo().propertyKeysForEnum("horizontalAlignment").contains(QLatin1String("AlignLeft")));
|
QmlDesigner::TypeName("HAlignment"));
|
||||||
QVERIFY(view->rootModelNode().metaInfo().propertyKeysForEnum("horizontalAlignment").contains(QLatin1String("AlignRight")));
|
|
||||||
|
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
}
|
}
|
||||||
@@ -4743,8 +4752,8 @@ void tst_TestCore::testMetaInfoProperties()
|
|||||||
QVERIFY(textNodeMetaInfo.hasProperty("objectName")); // QtQuick.QObject
|
QVERIFY(textNodeMetaInfo.hasProperty("objectName")); // QtQuick.QObject
|
||||||
QVERIFY(!textNodeMetaInfo.hasProperty("bla"));
|
QVERIFY(!textNodeMetaInfo.hasProperty("bla"));
|
||||||
|
|
||||||
QVERIFY(textNodeMetaInfo.propertyIsWritable("text"));
|
QVERIFY(textNodeMetaInfo.property("text").isWritable());
|
||||||
QVERIFY(textNodeMetaInfo.propertyIsWritable("x"));
|
QVERIFY(textNodeMetaInfo.property("x").isWritable());
|
||||||
|
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
}
|
}
|
||||||
@@ -4761,22 +4770,23 @@ void tst_TestCore::testMetaInfoDotProperties()
|
|||||||
QVERIFY(model->hasNodeMetaInfo("QtQuick.Text"));
|
QVERIFY(model->hasNodeMetaInfo("QtQuick.Text"));
|
||||||
|
|
||||||
QVERIFY(model->metaInfo("QtQuick.Rectangle").hasProperty("border"));
|
QVERIFY(model->metaInfo("QtQuick.Rectangle").hasProperty("border"));
|
||||||
QCOMPARE(model->metaInfo("QtQuick.Rectangle").propertyTypeName("border"), QmlDesigner::TypeName("<cpp>.QQuickPen"));
|
QCOMPARE(model->metaInfo("QtQuick.Rectangle").property("border").propertyTypeName(),
|
||||||
|
QmlDesigner::TypeName("<cpp>.QQuickPen"));
|
||||||
|
|
||||||
QCOMPARE(view->rootModelNode().metaInfo().typeName(), QmlDesigner::TypeName("QtQuick.Text"));
|
QCOMPARE(view->rootModelNode().metaInfo().typeName(), QmlDesigner::TypeName("QtQuick.Text"));
|
||||||
QVERIFY(view->rootModelNode().metaInfo().hasProperty("font"));
|
QVERIFY(view->rootModelNode().metaInfo().hasProperty("font"));
|
||||||
|
|
||||||
QVERIFY(view->rootModelNode().metaInfo().hasProperty("font.bold"));
|
QVERIFY(view->rootModelNode().metaInfo().hasProperty("font.bold"));
|
||||||
QVERIFY(view->rootModelNode().metaInfo().propertyNames().contains("font.bold"));
|
QVERIFY(contains(view->rootModelNode().metaInfo().properties(), "font.bold"));
|
||||||
QVERIFY(view->rootModelNode().metaInfo().propertyNames().contains("font.pointSize"));
|
QVERIFY(contains(view->rootModelNode().metaInfo().properties(), "font.pointSize"));
|
||||||
QVERIFY(view->rootModelNode().metaInfo().hasProperty("font.pointSize"));
|
QVERIFY(view->rootModelNode().metaInfo().hasProperty("font.pointSize"));
|
||||||
|
|
||||||
ModelNode rectNode(addNodeListChild(view->rootModelNode(), "QtQuick.Rectangle", 2, 0, "data"));
|
ModelNode rectNode(addNodeListChild(view->rootModelNode(), "QtQuick.Rectangle", 2, 0, "data"));
|
||||||
|
|
||||||
QVERIFY(rectNode.metaInfo().propertyNames().contains("implicitHeight"));
|
QVERIFY(contains(rectNode.metaInfo().properties(), "implicitHeight"));
|
||||||
QVERIFY(rectNode.metaInfo().propertyNames().contains("implicitWidth"));
|
QVERIFY(contains(rectNode.metaInfo().properties(), "implicitWidth"));
|
||||||
QVERIFY(rectNode.metaInfo().propertyNames().contains("anchors.topMargin"));
|
QVERIFY(contains(rectNode.metaInfo().properties(), "anchors.topMargin"));
|
||||||
QVERIFY(rectNode.metaInfo().propertyNames().contains("border.width"));
|
QVERIFY(contains(rectNode.metaInfo().properties(), "border.width"));
|
||||||
QVERIFY(rectNode.metaInfo().hasProperty("border"));
|
QVERIFY(rectNode.metaInfo().hasProperty("border"));
|
||||||
QVERIFY(rectNode.metaInfo().hasProperty("border.width"));
|
QVERIFY(rectNode.metaInfo().hasProperty("border.width"));
|
||||||
|
|
||||||
@@ -4796,20 +4806,20 @@ void tst_TestCore::testMetaInfoListProperties()
|
|||||||
QCOMPARE(view->rootModelNode().metaInfo().typeName(), QmlDesigner::TypeName("QtQuick.Item"));
|
QCOMPARE(view->rootModelNode().metaInfo().typeName(), QmlDesigner::TypeName("QtQuick.Item"));
|
||||||
|
|
||||||
QVERIFY(view->rootModelNode().metaInfo().hasProperty("states"));
|
QVERIFY(view->rootModelNode().metaInfo().hasProperty("states"));
|
||||||
QVERIFY(view->rootModelNode().metaInfo().propertyIsListProperty("states"));
|
QVERIFY(view->rootModelNode().metaInfo().property("states").isListProperty());
|
||||||
QVERIFY(view->rootModelNode().metaInfo().hasProperty("children"));
|
QVERIFY(view->rootModelNode().metaInfo().hasProperty("children"));
|
||||||
QVERIFY(view->rootModelNode().metaInfo().propertyIsListProperty("children"));
|
QVERIFY(view->rootModelNode().metaInfo().property("children").isListProperty());
|
||||||
QVERIFY(view->rootModelNode().metaInfo().hasProperty("data"));
|
QVERIFY(view->rootModelNode().metaInfo().hasProperty("data"));
|
||||||
QVERIFY(view->rootModelNode().metaInfo().propertyIsListProperty("data"));
|
QVERIFY(view->rootModelNode().metaInfo().property("data").isListProperty());
|
||||||
QVERIFY(view->rootModelNode().metaInfo().hasProperty("resources"));
|
QVERIFY(view->rootModelNode().metaInfo().hasProperty("resources"));
|
||||||
QVERIFY(view->rootModelNode().metaInfo().propertyIsListProperty("resources"));
|
QVERIFY(view->rootModelNode().metaInfo().property("resources").isListProperty());
|
||||||
QVERIFY(view->rootModelNode().metaInfo().hasProperty("transitions"));
|
QVERIFY(view->rootModelNode().metaInfo().hasProperty("transitions"));
|
||||||
QVERIFY(view->rootModelNode().metaInfo().propertyIsListProperty("transitions"));
|
QVERIFY(view->rootModelNode().metaInfo().property("transitions").isListProperty());
|
||||||
QVERIFY(view->rootModelNode().metaInfo().hasProperty("transform"));
|
QVERIFY(view->rootModelNode().metaInfo().hasProperty("transform"));
|
||||||
QVERIFY(view->rootModelNode().metaInfo().propertyIsListProperty("transform"));
|
QVERIFY(view->rootModelNode().metaInfo().property("transform").isListProperty());
|
||||||
|
|
||||||
QVERIFY(view->rootModelNode().metaInfo().hasProperty("parent"));
|
QVERIFY(view->rootModelNode().metaInfo().hasProperty("parent"));
|
||||||
QVERIFY(!view->rootModelNode().metaInfo().propertyIsListProperty("parent"));
|
QVERIFY(!view->rootModelNode().metaInfo().property("parent").isListProperty());
|
||||||
|
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
}
|
}
|
||||||
@@ -4904,8 +4914,8 @@ void tst_TestCore::testQtQuickControls2()
|
|||||||
QVERIFY(rootModelNode.metaInfo().isGraphicalItem());
|
QVERIFY(rootModelNode.metaInfo().isGraphicalItem());
|
||||||
QVERIFY(rootModelNode.isSubclassOf("QtQuick.Window.Window", -1, -1));
|
QVERIFY(rootModelNode.isSubclassOf("QtQuick.Window.Window", -1, -1));
|
||||||
|
|
||||||
QVERIFY(!rootModelNode.metaInfo().directPropertyNames().contains("visible"));
|
QVERIFY(!contains(rootModelNode.metaInfo().localProperties(), "visible"));
|
||||||
QVERIFY(rootModelNode.metaInfo().propertyNames().contains("visible"));
|
QVERIFY(contains(rootModelNode.metaInfo().properties(), "visible"));
|
||||||
|
|
||||||
QVERIFY(!rootModelNode.allSubModelNodes().isEmpty());
|
QVERIFY(!rootModelNode.allSubModelNodes().isEmpty());
|
||||||
ModelNode button = rootModelNode.allSubModelNodes().first();
|
ModelNode button = rootModelNode.allSubModelNodes().first();
|
||||||
|
@@ -25,12 +25,14 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "propertymetainfo.h"
|
||||||
|
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
#include "qmldesignercorelib_global.h"
|
#include <qmldesignercorelib_global.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QDeclarativeContext;
|
class QDeclarativeContext;
|
||||||
@@ -51,19 +53,14 @@ public:
|
|||||||
bool isValid() const { return {}; }
|
bool isValid() const { return {}; }
|
||||||
bool isFileComponent() const { return {}; }
|
bool isFileComponent() const { return {}; }
|
||||||
bool hasProperty(const PropertyName &) const { return {}; }
|
bool hasProperty(const PropertyName &) const { return {}; }
|
||||||
|
PropertyMetaInfos properties() const { return {}; }
|
||||||
|
PropertyMetaInfos localProperties() const { return {}; }
|
||||||
|
PropertyMetaInfo property(const PropertyName &) const { return {}; }
|
||||||
PropertyNameList propertyNames() const { return {}; }
|
PropertyNameList propertyNames() const { return {}; }
|
||||||
PropertyNameList signalNames() const { return {}; }
|
PropertyNameList signalNames() const { return {}; }
|
||||||
PropertyNameList directPropertyNames() const { return {}; }
|
PropertyNameList directPropertyNames() const { return {}; }
|
||||||
PropertyName defaultPropertyName() const { return "data"; }
|
PropertyName defaultPropertyName() const { return "data"; }
|
||||||
bool hasDefaultProperty() const { return {}; }
|
bool hasDefaultProperty() const { return {}; }
|
||||||
TypeName propertyTypeName(const PropertyName &) const { return {}; }
|
|
||||||
bool propertyIsWritable(const PropertyName &) const { return {}; }
|
|
||||||
bool propertyIsListProperty(const PropertyName &) const { return {}; }
|
|
||||||
bool propertyIsEnumType(const PropertyName &) const { return {}; }
|
|
||||||
bool propertyIsPrivate(const PropertyName &) const { return {}; }
|
|
||||||
QString propertyEnumScope(const PropertyName &) const { return {}; }
|
|
||||||
QStringList propertyKeysForEnum(const PropertyName &) const { return {}; }
|
|
||||||
QVariant propertyCastedValue(const PropertyName &, const QVariant &) const { return {}; }
|
|
||||||
|
|
||||||
QList<NodeMetaInfo> classHierarchy() const { return {}; }
|
QList<NodeMetaInfo> classHierarchy() const { return {}; }
|
||||||
QList<NodeMetaInfo> superClasses() const { return {}; }
|
QList<NodeMetaInfo> superClasses() const { return {}; }
|
||||||
|
@@ -0,0 +1,69 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file 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 file. 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <qmldesignercorelib_global.h>
|
||||||
|
|
||||||
|
#include <QSharedPointer>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class PropertyMetaInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PropertyMetaInfo() = default;
|
||||||
|
PropertyMetaInfo(QSharedPointer<class NodeMetaInfoPrivate>, const PropertyName &) {}
|
||||||
|
~PropertyMetaInfo() {}
|
||||||
|
|
||||||
|
const TypeName &propertyTypeName() const
|
||||||
|
{
|
||||||
|
static TypeName foo;
|
||||||
|
return foo;
|
||||||
|
}
|
||||||
|
class NodeMetaInfo propertyNodeMetaInfo() const;
|
||||||
|
|
||||||
|
bool isWritable() const { return {}; }
|
||||||
|
bool isListProperty() const { return {}; }
|
||||||
|
bool isEnumType() const { return {}; }
|
||||||
|
bool isPrivate() const { return {}; }
|
||||||
|
bool isPointer() const { return {}; }
|
||||||
|
QVariant castedValue(const QVariant &) const { return {}; }
|
||||||
|
PropertyName name() const & { return {}; }
|
||||||
|
|
||||||
|
template<typename... TypeName>
|
||||||
|
bool hasPropertyTypeName(const TypeName &...typeName) const
|
||||||
|
{
|
||||||
|
auto propertyTypeName_ = propertyTypeName();
|
||||||
|
return ((propertyTypeName_ == typeName) && ...);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using PropertyMetaInfos = std::vector<PropertyMetaInfo>;
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
Reference in New Issue
Block a user