QmlDesigner: Use ProjectStorage

Task-number: QDS-7379
Change-Id: I50c8a4a527daa7268a723094b6ceec37d10dfaa6
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
Marco Bubke
2022-08-23 16:43:44 +02:00
committed by Thomas Hartmann
parent 84e3ffeaba
commit 35a773b2dc
50 changed files with 741 additions and 395 deletions

View File

@@ -3,6 +3,15 @@ if (APPLE)
set(QmlDesignerPluginInstallPrefix "${IDE_PLUGIN_PATH}/QmlDesigner") set(QmlDesignerPluginInstallPrefix "${IDE_PLUGIN_PATH}/QmlDesigner")
endif() endif()
env_with_default("QDS_USE_PROJECTSTORAGE" ENV_QDS_USE_PROJECTSTORAGE OFF)
option(USE_PROJECTSTORAGE "Build uses ProjectStorage" ${ENV_QDS_USE_PROJECTSTORAGE})
add_feature_info("Build uses ProjectStorage" ${USE_PROJECTSTORAGE} "")
env_with_default("QDS_WITH_QMLDOM" ENV_QDS_WITH_QMLDOM OFF)
option(WITH_QMLDOM "Build with QmlDom" ${ENV_QDS_WITH_QMLDOM})
add_feature_info("Build with QmlDom" ${WITH_QMLDOM} "")
add_qtc_plugin(QmlDesigner add_qtc_plugin(QmlDesigner
CONDITION Qt5_VERSION VERSION_GREATER_EQUAL 6.2.0 AND TARGET Qt5::QuickWidgets AND TARGET Qt5::Svg CONDITION Qt5_VERSION VERSION_GREATER_EQUAL 6.2.0 AND TARGET Qt5::QuickWidgets AND TARGET Qt5::Svg
DEPENDS DEPENDS
@@ -11,6 +20,7 @@ add_qtc_plugin(QmlDesigner
DEFINES DEFINES
IDE_LIBRARY_BASENAME=\"${IDE_LIBRARY_BASE_PATH}\" IDE_LIBRARY_BASENAME=\"${IDE_LIBRARY_BASE_PATH}\"
SHARE_QML_PATH="${CMAKE_CURRENT_SOURCE_DIR}/../../../share/qtcreator/qmldesigner" SHARE_QML_PATH="${CMAKE_CURRENT_SOURCE_DIR}/../../../share/qtcreator/qmldesigner"
$<$<BOOL:${USE_PROJECTSTORAGE}>:QDS_USE_PROJECTSTORAGE>
PUBLIC_INCLUDES PUBLIC_INCLUDES
"${CMAKE_CURRENT_LIST_DIR}" "${CMAKE_CURRENT_LIST_DIR}"
"${CMAKE_CURRENT_LIST_DIR}/designercore/include" "${CMAKE_CURRENT_LIST_DIR}/designercore/include"
@@ -50,10 +60,6 @@ add_qtc_plugin(QmlDesigner
include(qmldesignercore.cmake) include(qmldesignercore.cmake)
extend_with_qmldesigner_core(QmlDesigner) extend_with_qmldesigner_core(QmlDesigner)
env_with_default("QDS_WITH_QMLDOM" ENV_QDS_WITH_QMLDOM OFF)
option(WITH_QMLDOM "Build with QmlDom" ${ENV_QDS_WITH_QMLDOM})
add_feature_info("Build with QmlDom" ${WITH_QMLDOM} "")
function(get_and_add_as_subdirectory name repository git_tag build_dir source_dir source_subdir) function(get_and_add_as_subdirectory name repository git_tag build_dir source_dir source_subdir)
# make the configuration in the build dir # make the configuration in the build dir
file(MAKE_DIRECTORY ${build_dir}/${name}) file(MAKE_DIRECTORY ${build_dir}/${name})
@@ -458,6 +464,7 @@ extend_qtc_plugin(QmlDesigner
nonlockingmutex.h nonlockingmutex.h
projectstorageinterface.h projectstorageinterface.h
projectstorage.cpp projectstorage.h projectstorage.cpp projectstorage.h
projectstoragefwd.h
projectstoragepathwatcher.h projectstoragepathwatcher.h
projectstoragepathwatcherinterface.h projectstoragepathwatcherinterface.h
projectstoragepathwatchernotifierinterface.h projectstoragepathwatchernotifierinterface.h

View File

@@ -195,6 +195,10 @@ void ActionEditor::prepareConnections()
constexpr auto typeWhiteList = std::make_tuple( constexpr auto typeWhiteList = std::make_tuple(
"string", "real", "int", "double", "bool", "QColor", "color", "QtQuick.Item", "QQuickItem"); "string", "real", "int", "double", "bool", "QColor", "color", "QtQuick.Item", "QQuickItem");
auto isSkippedType = [](auto &&type) {
return !(type.isString() || type.isInteger() || type.isBool() || type.isColor()
|| type.isFloat() || type.isQmlItem());
};
static QList<PropertyName> methodBlackList({"toString", "destroy"}); static QList<PropertyName> methodBlackList({"toString", "destroy"});
QList<ActionEditorDialog::ConnectionOption> connections; QList<ActionEditorDialog::ConnectionOption> connections;
@@ -210,12 +214,12 @@ void ActionEditor::prepareConnections()
ActionEditorDialog::ConnectionOption connection(modelNode.id()); ActionEditorDialog::ConnectionOption connection(modelNode.id());
for (const auto &property : modelNode.metaInfo().properties()) { for (const auto &property : modelNode.metaInfo().properties()) {
if (!property.hasPropertyTypeName(typeWhiteList)) if (isSkippedType(property.propertyType()))
continue; continue;
connection.properties.append( connection.properties.append(
ActionEditorDialog::PropertyOption(QString::fromUtf8(property.name()), ActionEditorDialog::PropertyOption(QString::fromUtf8(property.name()),
skipCpp(std::move(property.propertyTypeName())), skipCpp(property.propertyType().typeName()),
property.isWritable())); property.isWritable()));
} }
@@ -270,13 +274,13 @@ void ActionEditor::prepareConnections()
if (metaInfo.isValid()) { if (metaInfo.isValid()) {
ActionEditorDialog::SingletonOption singelton; ActionEditorDialog::SingletonOption singelton;
for (const auto &property : metaInfo.properties()) { for (const auto &property : metaInfo.properties()) {
if (!property.hasPropertyTypeName(typeWhiteList)) if (isSkippedType(property.propertyType()))
continue; continue;
singelton.properties.append( singelton.properties.append(ActionEditorDialog::PropertyOption(
ActionEditorDialog::PropertyOption(QString::fromUtf8(property.name()), QString::fromUtf8(property.name()),
skipCpp(property.propertyTypeName()), skipCpp(property.propertyType().typeName()),
property.isWritable())); property.isWritable()));
} }
if (!singelton.properties.isEmpty()) { if (!singelton.properties.isEmpty()) {

View File

@@ -113,7 +113,10 @@ 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().property(propertyEditorValue->name()).propertyTypeName(); m_backendValueTypeName = node.metaInfo()
.property(propertyEditorValue->name())
.propertyType()
.typeName();
QString nodeId = node.id(); QString nodeId = node.id();
if (nodeId.isEmpty()) if (nodeId.isEmpty())
@@ -206,7 +209,7 @@ void BindingEditor::prepareBindings()
for (const auto &objnode : allNodes) { for (const auto &objnode : allNodes) {
BindingEditorDialog::BindingOption binding; BindingEditorDialog::BindingOption binding;
for (const auto &property : objnode.metaInfo().properties()) { for (const auto &property : objnode.metaInfo().properties()) {
const TypeName &propertyTypeName = property.propertyTypeName(); const TypeName &propertyTypeName = property.propertyType().typeName();
if (skipTypeFiltering if (skipTypeFiltering
|| (m_backendValueTypeName == propertyTypeName) || (m_backendValueTypeName == propertyTypeName)
@@ -260,7 +263,7 @@ void BindingEditor::prepareBindings()
BindingEditorDialog::BindingOption binding; BindingEditorDialog::BindingOption binding;
for (const auto &property : metaInfo.properties()) { for (const auto &property : metaInfo.properties()) {
TypeName propertyTypeName = property.propertyTypeName(); TypeName propertyTypeName = property.propertyType().typeName();
if (skipTypeFiltering if (skipTypeFiltering
|| (m_backendValueTypeName == propertyTypeName) || (m_backendValueTypeName == propertyTypeName)

View File

@@ -169,7 +169,7 @@ void SignalList::prepareSignals()
// Gather valid properties and aliases from components // Gather valid properties and aliases from components
for (const auto &property : node.metaInfo().properties()) { for (const auto &property : node.metaInfo().properties()) {
const NodeMetaInfo info = m_modelNode.model()->metaInfo(property.propertyTypeName()); const NodeMetaInfo info = property.propertyType();
callOnlyMouseSignalNames(info.signalNames(), callOnlyMouseSignalNames(info.signalNames(),
QmlFlowViewNode::mouseSignals(), QmlFlowViewNode::mouseSignals(),

View File

@@ -157,10 +157,10 @@ QStringList BindingModel::possibleSourceProperties(const BindingProperty &bindin
const QStringList stringlist = expression.split(QLatin1String(".")); const QStringList stringlist = expression.split(QLatin1String("."));
QStringList possibleProperties; QStringList possibleProperties;
TypeName typeName; NodeMetaInfo type;
if (auto metaInfo = bindingProperty.parentModelNode().metaInfo(); metaInfo.isValid()) if (auto metaInfo = bindingProperty.parentModelNode().metaInfo(); metaInfo.isValid())
typeName = metaInfo.property(bindingProperty.name()).propertyTypeName(); type = metaInfo.property(bindingProperty.name()).propertyType();
else else
qWarning() << " BindingModel::possibleSourcePropertiesForRow no meta info for target node"; qWarning() << " BindingModel::possibleSourcePropertiesForRow no meta info for target node";
@@ -172,18 +172,16 @@ QStringList BindingModel::possibleSourceProperties(const BindingProperty &bindin
//if it's not a valid model node, maybe it's a singleton //if it's not a valid model node, maybe it's a singleton
if (RewriterView* rv = connectionView()->rewriterView()) { if (RewriterView* rv = connectionView()->rewriterView()) {
for (const QmlTypeData &data : rv->getQMLTypes()) { for (const QmlTypeData &data : rv->getQMLTypes()) {
if (!data.typeName.isEmpty()) { if (!data.typeName.isEmpty() && data.typeName == id) {
if (data.typeName == id) { NodeMetaInfo metaInfo = connectionView()->model()->metaInfo(data.typeName.toUtf8());
NodeMetaInfo metaInfo = connectionView()->model()->metaInfo(data.typeName.toUtf8());
if (metaInfo.isValid()) { if (metaInfo.isValid()) {
for (const auto &property : metaInfo.properties()) { for (const auto &property : metaInfo.properties()) {
//without check for now //without check for now
possibleProperties.push_back(QString::fromUtf8(property.name())); possibleProperties.push_back(QString::fromUtf8(property.name()));
}
return possibleProperties;
} }
return possibleProperties;
} }
} }
} }
@@ -207,7 +205,7 @@ QStringList BindingModel::possibleSourceProperties(const BindingProperty &bindin
if (metaInfo.isValid()) { if (metaInfo.isValid()) {
for (const auto &property : metaInfo.properties()) { for (const auto &property : metaInfo.properties()) {
if (property.propertyTypeName() == typeName) //### todo proper check if (property.propertyType() == type) //### todo proper check
possibleProperties.push_back(QString::fromUtf8(property.name())); possibleProperties.push_back(QString::fromUtf8(property.name()));
} }
} else { } else {

View File

@@ -474,8 +474,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 = metaInfo.property(aliasPart.toUtf8()).propertyType();
metaInfo.property(aliasPart.toUtf8()).propertyTypeName());
if (propertyMetaInfo.isValid()) { if (propertyMetaInfo.isValid()) {
return propertyNameListToStringList(propertyMetaInfo.signalNames()); return propertyNameListToStringList(propertyMetaInfo.signalNames());
} }

View File

@@ -216,9 +216,11 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event)
return; return;
const ModelNode node = property.parentModelNode(); const ModelNode node = property.parentModelNode();
const TypeName typeName = property.isDynamic() const TypeName typeName = property.isDynamic() ? property.dynamicTypeName()
? property.dynamicTypeName() : node.metaInfo()
: node.metaInfo().property(property.name()).propertyTypeName(); .property(property.name())
.propertyType()
.typeName();
const QString targetName = node.displayName() + "." + property.name(); const QString targetName = node.displayName() + "." + property.name();

View File

@@ -299,20 +299,12 @@ 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 auto &property : itemMetaInfo.properties()) { for (const auto &property : itemMetaInfo.properties()) {
TypeName propertyType = property.propertyTypeName(); NodeMetaInfo propertyType = property.propertyType();
if (!propertyType.isEmpty()) { if (propertyType.isValid() && propertyType.isFileComponent()) {
//first letter is a reliable item indicator if (!property.isEnumType() && !property.isPrivate()
QChar firstLetter = QString::fromUtf8(propertyType).at(0); && !property.isListProperty() && !property.isPointer()) {
if (firstLetter.isLetter() && firstLetter.isUpper()) { if (propertyType.isQmlItem()) {
if (!property.isEnumType() && !property.isPrivate() connectionComboBox->addItem(itemName + "." + property.name());
&& !property.isListProperty() && !property.isPointer()) {
NodeMetaInfo propertyMetaInfo =
connectionModel->connectionView()->model()->metaInfo(propertyType);
if (propertyMetaInfo.isValid()) {
if (propertyMetaInfo.isQmlItem()) {
connectionComboBox->addItem(itemName + "." + property.name());
}
}
} }
} }
} }

View File

@@ -383,10 +383,10 @@ QStringList DynamicPropertiesModel::possibleSourceProperties(const BindingProper
const QString expression = bindingProperty.expression(); const QString expression = bindingProperty.expression();
const QStringList stringlist = expression.split(QLatin1String(".")); const QStringList stringlist = expression.split(QLatin1String("."));
PropertyName typeName; NodeMetaInfo type;
if (auto metaInfo = bindingProperty.parentModelNode().metaInfo(); metaInfo.isValid()) { if (auto metaInfo = bindingProperty.parentModelNode().metaInfo(); metaInfo.isValid()) {
typeName = metaInfo.property(bindingProperty.name()).propertyTypeName(); type = metaInfo.property(bindingProperty.name()).propertyType();
} else { } else {
qWarning() << " BindingModel::possibleSourcePropertiesForRow no meta info for target node"; qWarning() << " BindingModel::possibleSourcePropertiesForRow no meta info for target node";
} }
@@ -405,7 +405,7 @@ QStringList DynamicPropertiesModel::possibleSourceProperties(const BindingProper
if (metaInfo.isValid()) { if (metaInfo.isValid()) {
QStringList possibleProperties; QStringList possibleProperties;
for (const auto &property : metaInfo.properties()) { for (const auto &property : metaInfo.properties()) {
if (property.propertyTypeName() == typeName) //### todo proper check if (property.propertyType() == type) //### todo proper check
possibleProperties.push_back(QString::fromUtf8(property.name())); possibleProperties.push_back(QString::fromUtf8(property.name()));
} }
return possibleProperties; return possibleProperties;

View File

@@ -36,6 +36,7 @@
#include <bindingproperty.h> #include <bindingproperty.h>
#include <nodeabstractproperty.h> #include <nodeabstractproperty.h>
#include <nodemetainfo.h>
#include <theme.h> #include <theme.h>
#include <variantproperty.h> #include <variantproperty.h>
@@ -218,17 +219,13 @@ void CurveEditorModel::reset(const std::vector<TreeItem *> &items)
PropertyTreeItem::ValueType typeFrom(const QmlDesigner::QmlTimelineKeyframeGroup &group) PropertyTreeItem::ValueType typeFrom(const QmlDesigner::QmlTimelineKeyframeGroup &group)
{ {
if (group.valueType() == QmlDesigner::TypeName("double") if (group.valueType().isFloat())
|| group.valueType() == QmlDesigner::TypeName("real")
|| group.valueType() == QmlDesigner::TypeName("float"))
return PropertyTreeItem::ValueType::Double; return PropertyTreeItem::ValueType::Double;
if (group.valueType() == QmlDesigner::TypeName("boolean") if (group.valueType().isBool())
|| group.valueType() == QmlDesigner::TypeName("bool"))
return PropertyTreeItem::ValueType::Bool; return PropertyTreeItem::ValueType::Bool;
if (group.valueType() == QmlDesigner::TypeName("integer") if (group.valueType().isInteger())
|| group.valueType() == QmlDesigner::TypeName("int"))
return PropertyTreeItem::ValueType::Integer; return PropertyTreeItem::ValueType::Integer;
// Ignoring: QColor / HAlignment / VAlignment // Ignoring: QColor / HAlignment / VAlignment

View File

@@ -617,12 +617,13 @@ void DesignDocument::paste()
const double scatterRange = 20.; const double scatterRange = 20.;
int offset = QRandomGenerator::global()->generateDouble() * scatterRange - scatterRange / 2; int offset = QRandomGenerator::global()->generateDouble() * scatterRange - scatterRange / 2;
const auto defaultPropertyName = targetNode.metaInfo().defaultPropertyName();
auto parentProperty = targetNode.nodeListProperty(defaultPropertyName);
for (const ModelNode &node : qAsConst(selectedNodes)) { for (const ModelNode &node : qAsConst(selectedNodes)) {
PropertyName defaultProperty(targetNode.metaInfo().defaultPropertyName());
ModelNode pastedNode(view.insertModel(node)); ModelNode pastedNode(view.insertModel(node));
pastedNodeList.append(pastedNode); pastedNodeList.append(pastedNode);
scatterItem(pastedNode, targetNode, offset); scatterItem(pastedNode, targetNode, offset);
targetNode.nodeListProperty(defaultProperty).reparentHere(pastedNode); parentProperty.reparentHere(pastedNode);
} }
view.setSelectedModelNodes(pastedNodeList); view.setSelectedModelNodes(pastedNodeList);

View File

@@ -25,13 +25,13 @@
#pragma once #pragma once
#include <model.h>
#include <rewriterview.h>
#include <basetexteditmodifier.h> #include <basetexteditmodifier.h>
#include <componenttextmodifier.h> #include <componenttextmodifier.h>
#include <subcomponentmanager.h>
#include <coreplugin/icontext.h> #include <coreplugin/icontext.h>
#include <model.h>
#include <projectstorage/projectstoragefwd.h>
#include <rewriterview.h>
#include <subcomponentmanager.h>
#include <QObject> #include <QObject>
#include <QString> #include <QString>
@@ -46,10 +46,6 @@ namespace ProjectExplorer {
class Target; class Target;
} }
namespace Sqlite {
class Database;
}
namespace QmlDesigner { namespace QmlDesigner {
class ModelNode; class ModelNode;
@@ -58,8 +54,6 @@ class QmlObjectNode;
class CrumbleBarInfo; class CrumbleBarInfo;
class ViewManager; class ViewManager;
class AbstractView; class AbstractView;
template<typename Database>
class ProjectStorage;
class QMLDESIGNERCORE_EXPORT DesignDocument: public QObject class QMLDESIGNERCORE_EXPORT DesignDocument: public QObject
{ {

View File

@@ -145,7 +145,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.property(propertyName).propertyTypeNameIsUrl()) { if (metaInfo.property(propertyName).propertyType().isUrl()) {
// 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();
@@ -209,7 +209,7 @@ void MaterialEditorView::changeExpression(const QString &propertyName)
if (auto metaInfo = m_selectedMaterial.metaInfo(); if (auto metaInfo = m_selectedMaterial.metaInfo();
metaInfo.isValid() && metaInfo.hasProperty(name)) { metaInfo.isValid() && metaInfo.hasProperty(name)) {
auto propertyTypeName = metaInfo.property(name).propertyTypeName(); auto propertyTypeName = metaInfo.property(name).propertyType().typeName();
if (propertyTypeName == "QColor") { 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('"')));
@@ -542,8 +542,7 @@ void MaterialEditorView::setupQmlBackend()
NodeMetaInfo metaInfo = m_selectedMaterial.metaInfo(); NodeMetaInfo metaInfo = m_selectedMaterial.metaInfo();
if (metaInfo.isValid()) { if (metaInfo.isValid()) {
diffClassName = metaInfo.typeName(); diffClassName = metaInfo.typeName();
const QList<NodeMetaInfo> hierarchy = metaInfo.classHierarchy(); for (const NodeMetaInfo &metaInfo : metaInfo.classHierarchy()) {
for (const NodeMetaInfo &metaInfo : hierarchy) {
if (PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsUrl)) if (PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsUrl))
break; break;
qmlSpecificsUrl = PropertyEditorQmlBackend::getQmlFileUrl(metaInfo.typeName() qmlSpecificsUrl = PropertyEditorQmlBackend::getQmlFileUrl(metaInfo.typeName()
@@ -1022,7 +1021,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.property(propName.toUtf8()).hasPropertyTypeName("QtQuick3D.Texture")) { if (metaInfo.property(propName.toUtf8()).propertyType().isQtQuick3DTexture()) {
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);

View File

@@ -66,7 +66,7 @@ ChooseFromPropertyListFilter::ChooseFromPropertyListFilter(const NodeMetaInfo &i
|| parentInfo.isSubclassOf("QtQuick3D.PrincipledMaterial")) { || parentInfo.isSubclassOf("QtQuick3D.PrincipledMaterial")) {
// All texture properties are valid targets // All texture properties are valid targets
for (const auto &property : parentInfo.properties()) { for (const auto &property : parentInfo.properties()) {
const TypeName &propType = property.propertyTypeName(); const TypeName &propType = property.propertyType().typeName();
if (propType == textureType || propType == textureTypeCpp) { if (propType == textureType || propType == textureTypeCpp) {
propertyList.append(QString::fromUtf8(property.name())); propertyList.append(QString::fromUtf8(property.name()));
if (breakOnFirst) if (breakOnFirst)
@@ -167,12 +167,12 @@ 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 propertyType, QWidget *parent) const ModelNode &targetNode, const NodeMetaInfo &propertyType, QWidget *parent)
{ {
const NodeMetaInfo metaInfo = targetNode.metaInfo(); const NodeMetaInfo metaInfo = targetNode.metaInfo();
QStringList matchingNames; QStringList matchingNames;
for (const auto &property : metaInfo.properties()) { for (const auto &property : metaInfo.properties()) {
if (property.hasPropertyTypeName(propertyType) && property.isWritable()) if (property.propertyType() == propertyType && property.isWritable())
matchingNames.append(QString::fromUtf8(property.name())); matchingNames.append(QString::fromUtf8(property.name()));
} }

View File

@@ -58,7 +58,7 @@ public:
const ModelNode &newNode, const ModelNode &newNode,
QWidget *parent = 0); QWidget *parent = 0);
static ChooseFromPropertyListDialog *createIfNeeded(const ModelNode &targetNode, static ChooseFromPropertyListDialog *createIfNeeded(const ModelNode &targetNode,
TypeName type, const NodeMetaInfo &propertyType,
QWidget *parent = 0); QWidget *parent = 0);
private: private:

View File

@@ -1040,7 +1040,9 @@ bool NavigatorTreeModel::dropAsImage3dTexture(const ModelNode &targetNode,
|| targetNode.isSubclassOf("QtQuick3D.PrincipledMaterial")) { || targetNode.isSubclassOf("QtQuick3D.PrincipledMaterial")) {
// if dropping an image on a material, create a texture instead of image // if dropping an image on a material, create a texture instead of image
// Show texture property selection dialog // Show texture property selection dialog
auto dialog = ChooseFromPropertyListDialog::createIfNeeded(targetNode, "QtQuick3D.Texture", auto dialog = ChooseFromPropertyListDialog::createIfNeeded(targetNode,
m_view->model()->metaInfo(
"QtQuick3D.Texture"),
Core::ICore::dialogParent()); Core::ICore::dialogParent());
if (!dialog) if (!dialog)
return false; return false;
@@ -1103,10 +1105,12 @@ ModelNode NavigatorTreeModel::createTextureNode(const NodeAbstractProperty &targ
return {}; return {};
} }
TypeName propertyType(const NodeAbstractProperty &property) namespace {
NodeMetaInfo propertyType(const NodeAbstractProperty &property)
{ {
return property.parentModelNode().metaInfo().property(property.name()).propertyTypeName(); return property.parentModelNode().metaInfo().property(property.name()).propertyType();
} }
} // namespace
void NavigatorTreeModel::moveNodesInteractive(NodeAbstractProperty &parentProperty, void NavigatorTreeModel::moveNodesInteractive(NodeAbstractProperty &parentProperty,
const QList<ModelNode> &modelNodes, const QList<ModelNode> &modelNodes,
@@ -1115,18 +1119,17 @@ void NavigatorTreeModel::moveNodesInteractive(NodeAbstractProperty &parentProper
{ {
QTC_ASSERT(m_view, return); QTC_ASSERT(m_view, return);
auto doMoveNodesInteractive = [&parentProperty, modelNodes, targetIndex](){ auto doMoveNodesInteractive = [&parentProperty, modelNodes, targetIndex]() {
const TypeName propertyQmlType = propertyType(parentProperty); const auto propertyQmlType = propertyType(parentProperty);
int idx = targetIndex; int idx = targetIndex;
for (const ModelNode &modelNode : modelNodes) { for (const ModelNode &modelNode : modelNodes) {
if (modelNode.isValid() if (modelNode.isValid() && modelNode != parentProperty.parentModelNode()
&& modelNode != parentProperty.parentModelNode() && !modelNode.isAncestorOf(parentProperty.parentModelNode())
&& !modelNode.isAncestorOf(parentProperty.parentModelNode()) && (modelNode.metaInfo().isSubclassOf(propertyQmlType) || propertyQmlType.isAlias()
&& (modelNode.metaInfo().isSubclassOf(propertyQmlType) || parentProperty.name() == "data"
|| propertyQmlType == "alias" || (parentProperty.parentModelNode().metaInfo().defaultPropertyName()
|| parentProperty.name() == "data" == parentProperty.name()
|| (parentProperty.parentModelNode().metaInfo().defaultPropertyName() == parentProperty.name() && propertyQmlType.isQmlComponent()))) {
&& propertyQmlType == "<cpp>.QQmlComponent"))) {
//### todo: allowing alias is just a heuristic //### todo: allowing alias is just a heuristic
//once the MetaInfo is part of instances we can do this right //once the MetaInfo is part of instances we can do this right

View File

@@ -515,7 +515,7 @@ void PropertyEditorQmlBackend::initialSetup(const TypeName &typeName, const QUrl
for (const auto &property : metaInfo.properties()) { for (const auto &property : metaInfo.properties()) {
setupPropertyEditorValue(property.name(), setupPropertyEditorValue(property.name(),
propertyEditor, propertyEditor,
QString::fromUtf8(property.propertyTypeName())); QString::fromUtf8(property.propertyType().typeName()));
} }
auto valueObject = qobject_cast<PropertyEditorValue *>(variantToQObject( auto valueObject = qobject_cast<PropertyEditorValue *>(variantToQObject(
@@ -579,18 +579,16 @@ 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.property(parentProperty).propertyTypeName(); NodeMetaInfo propertyType = type.property(parentProperty).propertyType();
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");
NodeMetaInfo rectangleInfo = node.view()->model()->metaInfo("QtQuick.Rectangle"); NodeMetaInfo rectangleInfo = node.view()->model()->metaInfo("QtQuick.Rectangle");
NodeMetaInfo imageInfo = node.view()->model()->metaInfo("QtQuick.Image"); NodeMetaInfo imageInfo = node.view()->model()->metaInfo("QtQuick.Image");
if (typeName == "font" if (propertyType.isFont() || itemInfo.hasProperty(itemProperty)
|| itemInfo.hasProperty(itemProperty) || textInfo.isSubclassOf(propertyType) || rectangleInfo.isSubclassOf(propertyType)
|| textInfo.isSubclassOf(typeName) || imageInfo.isSubclassOf(propertyType))
|| rectangleInfo.isSubclassOf(typeName)
|| imageInfo.isSubclassOf(typeName))
return false; return false;
return true; return true;
@@ -630,10 +628,10 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &metaTyp
if (!superType.hasProperty(propertyName) // TODO add property.isLocalProperty() if (!superType.hasProperty(propertyName) // TODO add property.isLocalProperty()
&& property.isWritable() && dotPropertyHeuristic(node, metaType, propertyName)) { && property.isWritable() && dotPropertyHeuristic(node, metaType, propertyName)) {
QString typeName = QString::fromUtf8(property.propertyTypeName()); QString typeName = QString::fromUtf8(property.propertyType().typeName());
if (typeName == "alias" && node.isValid()) if (typeName == "alias" && node.isValid())
typeName = QString::fromLatin1(node.instanceType(propertyName)); typeName = QString::fromUtf8(node.instanceType(propertyName));
// Check if a template for the type exists // Check if a template for the type exists
if (allTypes.contains(typeName)) { if (allTypes.contains(typeName)) {
@@ -674,9 +672,9 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &metaTyp
PropertyName underscoreProperty = propertyName; PropertyName underscoreProperty = propertyName;
underscoreProperty.replace('.', '_'); underscoreProperty.replace('.', '_');
TypeName typeName = property.propertyTypeName(); TypeName typeName = property.propertyType().typeName();
// alias resolution only possible with instance // alias resolution only possible with instance
if (typeName == "alias" && node.isValid()) if (!useProjectStorage() && typeName == "alias" && node.isValid())
typeName = node.instanceType(propertyName); typeName = node.instanceType(propertyName);
QString filledTemplate; QString filledTemplate;
@@ -743,9 +741,9 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &metaTyp
emptyTemplate = false; emptyTemplate = false;
for (auto &[property, properties] : propertyMap) { for (auto &[property, properties] : propertyMap) {
// for (auto it = propertyMap.cbegin(); it != propertyMap.cend(); ++it) { // for (auto it = propertyMap.cbegin(); it != propertyMap.cend(); ++it) {
TypeName parentTypeName = property.propertyTypeName(); TypeName parentTypeName = property.propertyType().typeName();
// alias resolution only possible with instance // alias resolution only possible with instance
if (parentTypeName == "alias" && node.isValid()) if (!useProjectStorage() && parentTypeName == "alias" && node.isValid())
parentTypeName = node.instanceType(property.name()); parentTypeName = node.instanceType(property.name());
qmlInnerTemplate += "Section {\n"; qmlInnerTemplate += "Section {\n";
@@ -817,9 +815,10 @@ static NodeMetaInfo findCommonSuperClass(const NodeMetaInfo &first, const NodeMe
NodeMetaInfo PropertyEditorQmlBackend::findCommonAncestor(const ModelNode &node) NodeMetaInfo PropertyEditorQmlBackend::findCommonAncestor(const ModelNode &node)
{ {
if (!node.isValid()) if (!node.isValid())
return {}; return node.metaInfo();
QTC_ASSERT(node.metaInfo().isValid(), return {}); if (auto metaInfo = node.metaInfo(); metaInfo.isValid())
return metaInfo;
AbstractView *view = node.view(); AbstractView *view = node.view();
@@ -910,7 +909,7 @@ void PropertyEditorQmlBackend::setValueforAuxiliaryProperties(const QmlObjectNod
QUrl PropertyEditorQmlBackend::getQmlUrlForMetaInfo(const NodeMetaInfo &metaInfo, TypeName &className) QUrl PropertyEditorQmlBackend::getQmlUrlForMetaInfo(const NodeMetaInfo &metaInfo, TypeName &className)
{ {
if (metaInfo.isValid()) { if (metaInfo.isValid()) {
const QList<NodeMetaInfo> hierarchy = metaInfo.classHierarchy(); const NodeMetaInfos hierarchy = metaInfo.classHierarchy();
for (const NodeMetaInfo &info : hierarchy) { for (const NodeMetaInfo &info : hierarchy) {
QUrl fileUrl = fileToUrl(locateQmlFile(info, QString::fromUtf8(qmlFileName(info)))); QUrl fileUrl = fileToUrl(locateQmlFile(info, QString::fromUtf8(qmlFileName(info))));
if (fileUrl.isValid()) { if (fileUrl.isValid()) {

View File

@@ -71,7 +71,7 @@ public:
static QString propertyEditorResourcesPath(); static QString propertyEditorResourcesPath();
static QString templateGeneration(const NodeMetaInfo &type, const NodeMetaInfo &superType, const QmlObjectNode &node); static QString templateGeneration(const NodeMetaInfo &type, const NodeMetaInfo &superType, const QmlObjectNode &node);
static QUrl getQmlFileUrl(const TypeName &relativeTypeName, const NodeMetaInfo &info = NodeMetaInfo()); static QUrl getQmlFileUrl(const TypeName &relativeTypeName, const NodeMetaInfo &info);
static QUrl getQmlUrlForMetaInfo(const NodeMetaInfo &modelNode, TypeName &className); static QUrl getQmlUrlForMetaInfo(const NodeMetaInfo &modelNode, TypeName &className);
static bool checkIfUrlExists(const QUrl &url); static bool checkIfUrlExists(const QUrl &url);

View File

@@ -63,7 +63,7 @@ QVariant PropertyEditorValue::value() const
if (modelNode().isValid()) { if (modelNode().isValid()) {
if (auto metaInfo = modelNode().metaInfo(); if (auto metaInfo = modelNode().metaInfo();
metaInfo.isValid() && metaInfo.hasProperty(name()) metaInfo.isValid() && metaInfo.hasProperty(name())
&& metaInfo.property(name()).propertyTypeNameIsUrl()) { && metaInfo.property(name()).propertyType().isUrl()) {
returnValue = returnValue.toUrl().toString(); returnValue = returnValue.toUrl().toString();
} }
} }
@@ -106,7 +106,7 @@ static void fixAmbigousColorNames(const QmlDesigner::ModelNode &modelNode,
{ {
if (modelNode.isValid()) { if (modelNode.isValid()) {
if (auto metaInfo = modelNode.metaInfo(); if (auto metaInfo = modelNode.metaInfo();
metaInfo.isValid() && metaInfo.property(name).propertyTypeNameIsColor()) { metaInfo.isValid() && metaInfo.property(name).propertyType().isColor()) {
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();
@@ -124,7 +124,7 @@ static void fixUrl(const QmlDesigner::ModelNode &modelNode, const QmlDesigner::P
{ {
if (modelNode.isValid()) { if (modelNode.isValid()) {
if (auto metaInfo = modelNode.metaInfo(); if (auto metaInfo = modelNode.metaInfo();
metaInfo.isValid() && metaInfo.property(name).propertyTypeNameIsUrl()) metaInfo.isValid() && metaInfo.property(name).propertyType().isUrl())
if (!value->isValid()) if (!value->isValid())
*value = QStringLiteral(""); *value = QStringLiteral("");
@@ -149,7 +149,7 @@ void PropertyEditorValue::setValueWithEmit(const QVariant &value)
if (modelNode().isValid()) { if (modelNode().isValid()) {
if (auto metaInfo = modelNode().metaInfo(); if (auto metaInfo = modelNode().metaInfo();
metaInfo.isValid() && metaInfo.hasProperty(name()) metaInfo.isValid() && metaInfo.hasProperty(name())
&& metaInfo.property(name()).propertyTypeNameIsUrl()) { && metaInfo.property(name()).propertyType().isUrl()) {
newValue = QUrl(newValue.toString()); newValue = QUrl(newValue.toString());
} }
} }
@@ -268,7 +268,7 @@ bool PropertyEditorValue::isTranslated() const
if (modelNode().isValid()) { if (modelNode().isValid()) {
if (auto metaInfo = modelNode().metaInfo(); if (auto metaInfo = modelNode().metaInfo();
metaInfo.isValid() && metaInfo.hasProperty(name()) metaInfo.isValid() && metaInfo.hasProperty(name())
&& metaInfo.property(name()).propertyTypeNameIsString()) { && metaInfo.property(name()).propertyType().isString()) {
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( const QRegularExpression rx(
@@ -438,7 +438,7 @@ QString PropertyEditorValue::getTranslationContext() const
if (modelNode().isValid()) { if (modelNode().isValid()) {
if (auto metaInfo = modelNode().metaInfo(); if (auto metaInfo = modelNode().metaInfo();
metaInfo.isValid() && metaInfo.hasProperty(name()) metaInfo.isValid() && metaInfo.hasProperty(name())
&& metaInfo.property(name()).propertyTypeNameIsString()) { && metaInfo.property(name()).propertyType().isString()) {
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(
@@ -532,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().property(m_name).hasPropertyTypeName("QtQuick3D.Texture")) { && m_modelNode.metaInfo().property(m_name).propertyType().isQtQuick3DTexture()) {
// 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",
@@ -635,7 +635,8 @@ void PropertyEditorNodeWrapper::add(const QString &type)
propertyType = m_editorValue->modelNode() propertyType = m_editorValue->modelNode()
.metaInfo() .metaInfo()
.property(m_editorValue->name()) .property(m_editorValue->name())
.propertyTypeName(); .propertyType()
.typeName();
} }
while (propertyType.contains('*')) //strip star while (propertyType.contains('*')) //strip star
propertyType.chop(1); propertyType.chop(1);

View File

@@ -201,7 +201,7 @@ void PropertyEditorView::changeValue(const QString &name)
bool propertyTypeUrl = false; bool propertyTypeUrl = false;
if (metaInfo.isValid() && metaInfo.hasProperty(propertyName) if (metaInfo.isValid() && metaInfo.hasProperty(propertyName)
&& metaInfo.property(propertyName).propertyTypeNameIsUrl()) { && metaInfo.property(propertyName).propertyType().isUrl()) {
// 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();
@@ -272,13 +272,13 @@ void PropertyEditorView::changeExpression(const QString &propertyName)
if (auto metaInfo = qmlObjectNode->modelNode().metaInfo(); if (auto metaInfo = qmlObjectNode->modelNode().metaInfo();
metaInfo.isValid() && metaInfo.hasProperty(name)) { metaInfo.isValid() && metaInfo.hasProperty(name)) {
const auto &propertTypeName = metaInfo.property(name).propertyTypeName(); const auto &propertType = metaInfo.property(name).propertyType();
if (propertTypeName == "QColor") { if (propertType.isColor()) {
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 (propertTypeName == "bool") { } else if (propertType.isBool()) {
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 (propertTypeName == "int") { } else if (propertType.isInteger()) {
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 (propertTypeName == "qreal") { } else if (propertType.isFloat()) {
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 (propertTypeName == "QVariant") { } else if (propertType.isVariant()) {
bool ok; bool ok;
qreal realValue = value->expression().toDouble(&ok); qreal realValue = value->expression().toDouble(&ok);
if (ok) { if (ok) {
@@ -464,7 +464,7 @@ void PropertyEditorView::setupQmlBackend()
TypeName diffClassName; TypeName diffClassName;
if (commonAncestor.isValid()) { if (commonAncestor.isValid()) {
diffClassName = commonAncestor.typeName(); diffClassName = commonAncestor.typeName();
const QList<NodeMetaInfo> hierarchy = commonAncestor.classHierarchy(); const NodeMetaInfos hierarchy = commonAncestor.classHierarchy();
for (const NodeMetaInfo &metaInfo : hierarchy) { for (const NodeMetaInfo &metaInfo : hierarchy) {
if (PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsFile)) if (PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsFile))
break; break;

View File

@@ -54,7 +54,7 @@ bool modelNodeHasUrlSource(const QmlDesigner::ModelNode &modelNode)
{ {
QmlDesigner::NodeMetaInfo metaInfo = modelNode.metaInfo(); QmlDesigner::NodeMetaInfo metaInfo = modelNode.metaInfo();
return metaInfo.isValid() && metaInfo.hasProperty("source") return metaInfo.isValid() && metaInfo.hasProperty("source")
&& metaInfo.property("source").propertyTypeNameIsUrl(); && metaInfo.property("source").propertyType().isUrl();
} }
} //namespace } //namespace

View File

@@ -40,11 +40,11 @@
namespace QmlDesigner { namespace QmlDesigner {
TimelineControl *createTimelineControl(const TypeName &name) TimelineControl *createTimelineControl(const NodeMetaInfo &metaInfo)
{ {
if (name == "real" || name == "double" || name == "float") if (metaInfo.isFloat())
return new FloatControl; return new FloatControl;
if (name == "QColor" || name == "color") if (metaInfo.isColor())
return new ColorControl; return new ColorControl;
return nullptr; return nullptr;

View File

@@ -51,7 +51,7 @@ public:
virtual void setSize(int width, int height) = 0; virtual void setSize(int width, int height) = 0;
}; };
TimelineControl *createTimelineControl(const TypeName &name); TimelineControl *createTimelineControl(const NodeMetaInfo &metaInfo);
class FloatControl : public QDoubleSpinBox, public TimelineControl class FloatControl : public QDoubleSpinBox, public TimelineControl
{ {

View File

@@ -235,11 +235,11 @@ TimelinePropertyItem *TimelinePropertyItem::create(const QmlTimelineKeyframeGrou
if (!objectNode.isValid()) if (!objectNode.isValid())
return item; return item;
auto nameOfType = objectNode.modelNode() auto propertyType = objectNode.modelNode()
.metaInfo() .metaInfo()
.property(item->m_frames.propertyName()) .property(item->m_frames.propertyName())
.propertyTypeName(); .propertyType();
item->m_control = createTimelineControl(nameOfType); item->m_control = createTimelineControl(propertyType);
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,
item->size().height() - 2 + 1); item->size().height() - 2 + 1);

View File

@@ -218,8 +218,6 @@ ModelNode TransitionEditorView::addNewTransition()
QHash<QString, QStringList> idPropertyList; QHash<QString, QStringList> idPropertyList;
const QVector<TypeName> validProperties = {"int", "real", "double", "qreal", "color", "QColor", "float"};
for (const QmlModelState &state : qAsConst(states)) { for (const QmlModelState &state : qAsConst(states)) {
for (const QmlPropertyChanges & change : state.propertyChanges()) { for (const QmlPropertyChanges & change : state.propertyChanges()) {
QStringList locList; QStringList locList;
@@ -227,11 +225,9 @@ 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().property(property.name()).propertyTypeName(); auto type = target.metaInfo().property(property.name()).propertyType();
if (typeName.startsWith("<cpp>."))
typeName.remove(0, 6);
if (validProperties.contains(typeName)) if (type.isInteger() || type.isColor() || type.isFloat())
locList.append(QString::fromUtf8(property.name())); locList.append(QString::fromUtf8(property.name()));
} }
if (idPropertyList.contains(targetId)) { if (idPropertyList.contains(targetId)) {
@@ -303,6 +299,8 @@ ModelNode TransitionEditorView::addNewTransition()
}); });
} else { } else {
QString properties; QString properties;
const QVector<TypeName> validProperties = {
"int", "real", "double", "qreal", "color", "QColor", "float"};
for (const PropertyName &property : validProperties) for (const PropertyName &property : validProperties)
properties.append(QString::fromUtf8(property) + ", "); properties.append(QString::fromUtf8(property) + ", ");
if (!properties.isEmpty()) if (!properties.isEmpty())

View File

@@ -28,6 +28,7 @@
#include <qmldesignercorelib_global.h> #include <qmldesignercorelib_global.h>
#include <documentmessage.h> #include <documentmessage.h>
#include <projectstorage/projectstoragefwd.h>
#include <QMimeData> #include <QMimeData>
#include <QObject> #include <QObject>
@@ -40,10 +41,6 @@ class QPixmap;
class QUrl; class QUrl;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Sqlite {
class Database;
}
namespace QmlDesigner { namespace QmlDesigner {
namespace Internal { namespace Internal {
@@ -64,8 +61,6 @@ class AbstractProperty;
class RewriterView; class RewriterView;
class NodeInstanceView; class NodeInstanceView;
class TextModifier; class TextModifier;
template<typename Database>
class ProjectStorage;
using PropertyListType = QList<QPair<PropertyName, QVariant> >; using PropertyListType = QList<QPair<PropertyName, QVariant> >;
@@ -106,8 +101,8 @@ public:
const MetaInfo metaInfo() const; const MetaInfo metaInfo() const;
MetaInfo metaInfo(); MetaInfo metaInfo();
NodeMetaInfo metaInfo(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1); NodeMetaInfo metaInfo(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1) const;
bool hasNodeMetaInfo(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1); bool hasNodeMetaInfo(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1) const;
void setMetaInfo(const MetaInfo &metaInfo); void setMetaInfo(const MetaInfo &metaInfo);
void attachView(AbstractView *view); void attachView(AbstractView *view);
@@ -134,7 +129,7 @@ public:
NodeInstanceView *nodeInstanceView() const; NodeInstanceView *nodeInstanceView() const;
void setNodeInstanceView(NodeInstanceView *nodeInstanceView); void setNodeInstanceView(NodeInstanceView *nodeInstanceView);
Model *metaInfoProxyModel(); Model *metaInfoProxyModel() const;
TextModifier *textModifier() const; TextModifier *textModifier() const;
void setTextModifier(TextModifier *textModifier); void setTextModifier(TextModifier *textModifier);
@@ -154,6 +149,8 @@ public:
void startDrag(QMimeData *mimeData, const QPixmap &icon); void startDrag(QMimeData *mimeData, const QPixmap &icon);
void endDrag(); void endDrag();
NotNullPointer<const ProjectStorage<Sqlite::Database>> projectStorage() const;
private: private:
std::unique_ptr<Internal::ModelPrivate> d; std::unique_ptr<Internal::ModelPrivate> d;
}; };

View File

@@ -29,6 +29,12 @@
#include "propertymetainfo.h" #include "propertymetainfo.h"
#include "qmldesignercorelib_global.h" #include "qmldesignercorelib_global.h"
#include <projectstorage/projectstoragefwd.h>
#include <projectstorage/projectstoragetypes.h>
#include <projectstorageids.h>
#include <utils/optional.h>
#include <QList> #include <QList>
#include <QString> #include <QString>
#include <QIcon> #include <QIcon>
@@ -48,17 +54,20 @@ class AbstractProperty;
class QMLDESIGNERCORE_EXPORT NodeMetaInfo class QMLDESIGNERCORE_EXPORT NodeMetaInfo
{ {
public: public:
NodeMetaInfo(); NodeMetaInfo() = default;
NodeMetaInfo(Model *model, const TypeName &type, int maj, int min); NodeMetaInfo(Model *model, const TypeName &typeName, int majorVersion, int minorVersion);
NodeMetaInfo(TypeId typeId, NotNullPointer<const ProjectStorage<Sqlite::Database>> projectStorage)
: m_typeId{typeId}
, m_projectStorage{projectStorage}
{}
NodeMetaInfo(NotNullPointer<const ProjectStorage<Sqlite::Database>> projectStorage)
: m_projectStorage{projectStorage}
{}
~NodeMetaInfo(); ~NodeMetaInfo();
NodeMetaInfo(const NodeMetaInfo &other);
NodeMetaInfo &operator=(const NodeMetaInfo &other);
bool isValid() const; bool isValid() const;
bool isFileComponent() const; bool isFileComponent() const;
bool hasProperty(const PropertyName &propertyName) const; bool hasProperty(Utils::SmallStringView propertyName) const;
PropertyMetaInfos properties() const; PropertyMetaInfos properties() const;
PropertyMetaInfos localProperties() const; PropertyMetaInfos localProperties() const;
PropertyMetaInfo property(const PropertyName &propertyName) const; PropertyMetaInfo property(const PropertyName &propertyName) const;
@@ -67,8 +76,8 @@ public:
PropertyName defaultPropertyName() const; PropertyName defaultPropertyName() const;
bool hasDefaultProperty() const; bool hasDefaultProperty() const;
QList<NodeMetaInfo> classHierarchy() const; std::vector<NodeMetaInfo> classHierarchy() const;
QList<NodeMetaInfo> superClasses() const; std::vector<NodeMetaInfo> superClasses() const;
NodeMetaInfo directSuperClass() const; NodeMetaInfo directSuperClass() const;
bool defaultPropertyIsComponent() const; bool defaultPropertyIsComponent() const;
@@ -82,16 +91,43 @@ public:
bool availableInVersion(int majorVersion, int minorVersion) const; bool availableInVersion(int majorVersion, int minorVersion) const;
bool isSubclassOf(const TypeName &type, int majorVersion = -1, int minorVersion = -1) const; bool isSubclassOf(const TypeName &type, int majorVersion = -1, int minorVersion = -1) const;
bool isSubclassOf(const NodeMetaInfo &metaInfo) const;
bool isGraphicalItem() const; bool isGraphicalItem() const;
bool isQmlItem() const; bool isQmlItem() const;
bool isLayoutable() const; bool isLayoutable() const;
bool isView() const; bool isView() const;
bool isTabView() const; bool isTabView() const;
bool isAlias() const;
bool isQmlComponent() const;
bool isFont() const;
bool isColor() const;
bool isBool() const;
bool isInteger() const;
bool isFloat() const;
bool isVariant() const;
bool isString() const;
bool isUrl() const;
bool isQtQuick3DTexture() const;
bool isEnumeration() const;
QString importDirectoryPath() const; QString importDirectoryPath() const;
friend bool operator==(const NodeMetaInfo &first, const NodeMetaInfo &second)
{
if constexpr (useProjectStorage())
return first.m_typeId == second.m_typeId;
else
return first.m_privateData == second.m_privateData;
}
private: private:
const Storage::Info::Type &typeData() const;
private:
TypeId m_typeId;
NotNullPointer<const ProjectStorage<Sqlite::Database>> m_projectStorage = {};
mutable Utils::optional<Storage::Info::Type> m_typeData;
QSharedPointer<class NodeMetaInfoPrivate> m_privateData; QSharedPointer<class NodeMetaInfoPrivate> m_privateData;
}; };

View File

@@ -25,7 +25,7 @@
#pragma once #pragma once
#include <sqliteids.h> #include <sqlite/sqliteids.h>
namespace QmlDesigner { namespace QmlDesigner {

View File

@@ -27,6 +27,12 @@
#include <qmldesignercorelib_global.h> #include <qmldesignercorelib_global.h>
#include <projectstorage/projectstoragefwd.h>
#include <projectstorage/projectstoragetypes.h>
#include <projectstorageids.h>
#include <utils/optional.h>
#include <QSharedPointer> #include <QSharedPointer>
#include <QString> #include <QString>
@@ -34,45 +40,39 @@
namespace QmlDesigner { namespace QmlDesigner {
class NodeMetaInfo;
class QMLDESIGNERCORE_EXPORT PropertyMetaInfo class QMLDESIGNERCORE_EXPORT PropertyMetaInfo
{ {
public: public:
PropertyMetaInfo(QSharedPointer<class NodeMetaInfoPrivate> nodeMetaInfoPrivateData, PropertyMetaInfo(QSharedPointer<class NodeMetaInfoPrivate> nodeMetaInfoPrivateData,
const PropertyName &propertyName); const PropertyName &propertyName);
PropertyMetaInfo(PropertyDeclarationId id,
NotNullPointer<const ProjectStorage<Sqlite::Database>> projectStorage)
: m_id{id}
, m_projectStorage{projectStorage}
{}
~PropertyMetaInfo(); ~PropertyMetaInfo();
const TypeName &propertyTypeName() const; PropertyName name() const;
class NodeMetaInfo propertyNodeMetaInfo() const; NodeMetaInfo propertyType() const;
bool isWritable() const; bool isWritable() const;
bool isListProperty() const; bool isListProperty() const;
bool isEnumType() const; bool isEnumType() const;
bool isPrivate() const; bool isPrivate() const;
bool isPointer() const; bool isPointer() const;
QVariant castedValue(const QVariant &value) const; QVariant castedValue(const QVariant &value) const;
const PropertyName &name() const & { return m_propertyName; }
template<typename... TypeName> private:
bool hasPropertyTypeName(const TypeName &...typeName) const const Storage::Info::PropertyDeclaration &propertyData() const;
{ TypeName propertyTypeName() const;
auto propertyTypeName_ = propertyTypeName();
return ((propertyTypeName_ == typeName) || ...);
}
template<typename... TypeName>
bool hasPropertyTypeName(const std::tuple<TypeName...> &typeNames) const
{
return std::apply([&](auto... typeName) { return hasPropertyTypeName(typeName...); },
typeNames);
}
bool propertyTypeNameIsColor() const { return hasPropertyTypeName("QColor", "color"); }
bool propertyTypeNameIsString() const { return hasPropertyTypeName("QString", "string"); }
bool propertyTypeNameIsUrl() const { return hasPropertyTypeName("QUrl", "url"); }
private: private:
QSharedPointer<class NodeMetaInfoPrivate> m_nodeMetaInfoPrivateData; QSharedPointer<class NodeMetaInfoPrivate> m_nodeMetaInfoPrivateData;
PropertyName m_propertyName; PropertyName m_propertyName;
PropertyDeclarationId m_id;
NotNullPointer<const ProjectStorage<Sqlite::Database>> m_projectStorage;
mutable Utils::optional<Storage::Info::PropertyDeclaration> m_propertyData;
}; };
using PropertyMetaInfos = std::vector<PropertyMetaInfo>; using PropertyMetaInfos = std::vector<PropertyMetaInfo>;

View File

@@ -67,4 +67,12 @@ enum AnchorLineType {
AnchorLineAllMask = AnchorLineVerticalMask | AnchorLineHorizontalMask AnchorLineAllMask = AnchorLineVerticalMask | AnchorLineHorizontalMask
}; };
constexpr bool useProjectStorage()
{
#ifdef QDS_USE_PROJECTSTORAGE
return true;
#else
return false;
#endif
}
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -54,7 +54,7 @@ public:
void setValue(const QVariant &value, qreal frame); void setValue(const QVariant &value, qreal frame);
QVariant value(qreal frame) const; QVariant value(qreal frame) const;
TypeName valueType() const; NodeMetaInfo valueType() const;
qreal currentFrame() const; qreal currentFrame() const;

View File

@@ -29,8 +29,9 @@
#include "metainfo.h" #include "metainfo.h"
#include <enumeration.h> #include <enumeration.h>
#include <rewriterview.h> #include <projectstorage/projectstorage.h>
#include <propertyparser.h> #include <propertyparser.h>
#include <rewriterview.h>
#include <QDir> #include <QDir>
#include <QDebug> #include <QDebug>
@@ -315,7 +316,7 @@ public:
m_context->viewerContext(), *m_context->snapshot().importDependencies()).toUtf8(); m_context->viewerContext(), *m_context->snapshot().importDependencies()).toUtf8();
m_properties.append({propertyName, qualifiedTypeName}); m_properties.append({propertyName, qualifiedTypeName});
} else { } else {
TypeId typeId; QmlJS::TypeId typeId;
TypeName typeName = typeId(value).toUtf8(); TypeName typeName = typeId(value).toUtf8();
if (typeName == "Function") if (typeName == "Function")
@@ -1394,120 +1395,166 @@ void NodeMetaInfoPrivate::initialiseProperties()
m_slots = getSlots(m_objectValue, context()); m_slots = getSlots(m_objectValue, context());
} }
NodeMetaInfo::NodeMetaInfo()
: m_privateData(QSharedPointer<NodeMetaInfoPrivate>::create())
{
}
NodeMetaInfo::NodeMetaInfo(Model *model, const TypeName &type, int maj, int min) NodeMetaInfo::NodeMetaInfo(Model *model, const TypeName &type, int maj, int min)
: m_privateData(NodeMetaInfoPrivate::create(model, type, maj, min)) : m_privateData(NodeMetaInfoPrivate::create(model, type, maj, min))
{ {
} }
NodeMetaInfo::~NodeMetaInfo() = default; NodeMetaInfo::~NodeMetaInfo() = default;
NodeMetaInfo::NodeMetaInfo(const NodeMetaInfo &other) = default;
NodeMetaInfo &NodeMetaInfo::operator=(const NodeMetaInfo &other)
{
if (this != &other)
this->m_privateData = other.m_privateData;
return *this;
}
bool NodeMetaInfo::isValid() const bool NodeMetaInfo::isValid() const
{ {
return m_privateData->isValid(); if constexpr (useProjectStorage())
return bool(m_typeId);
else
return m_privateData && m_privateData->isValid();
} }
bool NodeMetaInfo::isFileComponent() const bool NodeMetaInfo::isFileComponent() const
{ {
return m_privateData->isFileComponent(); if constexpr (useProjectStorage())
return bool(typeData().traits & Storage::TypeTraits::IsFileComponent);
else
return m_privateData->isFileComponent();
} }
bool NodeMetaInfo::hasProperty(const PropertyName &propertyName) const bool NodeMetaInfo::hasProperty(Utils::SmallStringView propertyName) const
{ {
return m_privateData->properties().contains(propertyName); if constexpr (useProjectStorage())
return bool(m_projectStorage->propertyDeclarationId(m_typeId, propertyName));
else
return m_privateData->properties().contains(propertyName);
} }
PropertyMetaInfos NodeMetaInfo::properties() const PropertyMetaInfos NodeMetaInfo::properties() const
{ {
const auto &properties = m_privateData->properties(); if constexpr (useProjectStorage()) {
return Utils::transform<PropertyMetaInfos>(
m_projectStorage->propertyDeclarationIds(m_typeId), [&](auto id) {
return PropertyMetaInfo{id, m_projectStorage};
});
PropertyMetaInfos propertyMetaInfos; } else {
propertyMetaInfos.reserve(static_cast<std::size_t>(properties.size())); const auto &properties = m_privateData->properties();
for (const auto &name : properties) PropertyMetaInfos propertyMetaInfos;
propertyMetaInfos.emplace_back(m_privateData, name); propertyMetaInfos.reserve(static_cast<std::size_t>(properties.size()));
return propertyMetaInfos; for (const auto &name : properties)
propertyMetaInfos.emplace_back(m_privateData, name);
return propertyMetaInfos;
}
} }
PropertyMetaInfos NodeMetaInfo::localProperties() const PropertyMetaInfos NodeMetaInfo::localProperties() const
{ {
const auto &properties = m_privateData->localProperties(); if constexpr (useProjectStorage()) {
return Utils::transform<PropertyMetaInfos>(
m_projectStorage->localPropertyDeclarationIds(m_typeId), [&](auto id) {
return PropertyMetaInfo{id, m_projectStorage};
});
} else {
const auto &properties = m_privateData->localProperties();
PropertyMetaInfos propertyMetaInfos; PropertyMetaInfos propertyMetaInfos;
propertyMetaInfos.reserve(static_cast<std::size_t>(properties.size())); propertyMetaInfos.reserve(static_cast<std::size_t>(properties.size()));
for (const auto &name : properties) for (const auto &name : properties)
propertyMetaInfos.emplace_back(m_privateData, name); propertyMetaInfos.emplace_back(m_privateData, name);
return propertyMetaInfos; return propertyMetaInfos;
}
} }
PropertyMetaInfo NodeMetaInfo::property(const PropertyName &propertyName) const PropertyMetaInfo NodeMetaInfo::property(const PropertyName &propertyName) const
{ {
return PropertyMetaInfo{m_privateData, propertyName}; if constexpr (useProjectStorage()) {
return {m_projectStorage->propertyDeclarationId(m_typeId, propertyName), m_projectStorage};
} else {
return PropertyMetaInfo{m_privateData, propertyName};
}
} }
PropertyNameList NodeMetaInfo::signalNames() const PropertyNameList NodeMetaInfo::signalNames() const
{ {
return m_privateData->signalNames(); if constexpr (useProjectStorage()) {
return Utils::transform<PropertyNameList>(m_projectStorage->signalDeclarationNames(m_typeId),
[&](const auto &name) {
return name.toQByteArray();
});
} else {
return m_privateData->signalNames();
}
} }
PropertyNameList NodeMetaInfo::slotNames() const PropertyNameList NodeMetaInfo::slotNames() const
{ {
return m_privateData->slotNames(); if constexpr (useProjectStorage()) {
return Utils::transform<PropertyNameList>(m_projectStorage->functionDeclarationNames(m_typeId),
[&](const auto &name) {
return name.toQByteArray();
});
} else {
return m_privateData->slotNames();
}
} }
PropertyName NodeMetaInfo::defaultPropertyName() const PropertyName NodeMetaInfo::defaultPropertyName() const
{ {
return m_privateData->defaultPropertyName(); if constexpr (useProjectStorage()) {
if (auto name = m_projectStorage->propertyName(typeData().defaultPropertyId))
return name->toQByteArray();
return {};
} else {
return m_privateData->defaultPropertyName();
}
} }
bool NodeMetaInfo::hasDefaultProperty() const bool NodeMetaInfo::hasDefaultProperty() const
{ {
return !defaultPropertyName().isEmpty(); if constexpr (useProjectStorage())
return bool(typeData().defaultPropertyId);
else
return !defaultPropertyName().isEmpty();
} }
QList<NodeMetaInfo> NodeMetaInfo::classHierarchy() const NodeMetaInfos NodeMetaInfo::classHierarchy() const
{ {
QList<NodeMetaInfo> hierarchy = {*this}; NodeMetaInfos hierarchy = {*this};
hierarchy.append(superClasses()); Model *model = m_privateData->model();
for (const TypeDescription &type : m_privateData->prototypes())
hierarchy.emplace_back(model, type.className.toUtf8(), type.majorVersion, type.minorVersion);
return hierarchy; return hierarchy;
} }
QList<NodeMetaInfo> NodeMetaInfo::superClasses() const NodeMetaInfos NodeMetaInfo::superClasses() const
{ {
NodeMetaInfos hierarchy;
Model *model = m_privateData->model(); Model *model = m_privateData->model();
return Utils::transform(m_privateData->prototypes(), [model](const TypeDescription &type) { for (const TypeDescription &type : m_privateData->prototypes())
return NodeMetaInfo(model, type.className.toUtf8(), type.majorVersion, type.minorVersion); hierarchy.emplace_back(model, type.className.toUtf8(), type.majorVersion, type.minorVersion);
});
return hierarchy;
} }
NodeMetaInfo NodeMetaInfo::directSuperClass() const NodeMetaInfo NodeMetaInfo::directSuperClass() const // actually this can be too because their arre extensions
{ {
return superClasses().value(1, NodeMetaInfo()); const auto &protoTypes = m_privateData->prototypes();
Model *model = m_privateData->model();
if (protoTypes.empty())
return NodeMetaInfo{m_projectStorage};
const auto &type = m_privateData->prototypes().front();
return NodeMetaInfo{model, type.className.toUtf8(), type.majorVersion, type.minorVersion};
} }
bool NodeMetaInfo::defaultPropertyIsComponent() const bool NodeMetaInfo::defaultPropertyIsComponent() const
{ {
if (hasDefaultProperty()) if (hasDefaultProperty())
return property(defaultPropertyName()).hasPropertyTypeName("Component"); return property(defaultPropertyName()).propertyType().isQmlComponent();
return false; return false;
} }
@@ -1542,13 +1589,24 @@ QString NodeMetaInfo::importDirectoryPath() const
return m_privateData->importDirectoryPath(); return m_privateData->importDirectoryPath();
} }
#ifdef QDS_USE_PROJECTSTORAGE
const Storage::Info::Type &NodeMetaInfo::typeData() const
{
if (!m_typeData)
m_typeData = m_projectStorage->type(m_typeId);
return *m_typeData;
}
#endif
bool NodeMetaInfo::availableInVersion(int majorVersion, int minorVersion) const bool NodeMetaInfo::availableInVersion(int majorVersion, int minorVersion) const
{ {
if (majorVersion == -1 && minorVersion == -1) if (majorVersion == -1 && minorVersion == -1)
return true; return true;
return (m_privateData->majorVersion() >= majorVersion) return (m_privateData->majorVersion() >= majorVersion)
|| (majorVersion == m_privateData->majorVersion() && m_privateData->minorVersion() >= minorVersion); || (majorVersion == m_privateData->majorVersion()
&& m_privateData->minorVersion() >= minorVersion);
} }
bool NodeMetaInfo::isSubclassOf(const TypeName &type, int majorVersion, int minorVersion) const bool NodeMetaInfo::isSubclassOf(const TypeName &type, int majorVersion, int minorVersion) const
@@ -1572,10 +1630,10 @@ bool NodeMetaInfo::isSubclassOf(const TypeName &type, int majorVersion, int mino
stringIdentifier(type, majorVersion, minorVersion))) stringIdentifier(type, majorVersion, minorVersion)))
return false; //take a shortcut - optimization return false; //take a shortcut - optimization
const QList<NodeMetaInfo> superClassList = superClasses(); const NodeMetaInfos 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( m_privateData->prototypeCachePositives().insert(
stringIdentifier(type, majorVersion, minorVersion)); stringIdentifier(type, majorVersion, minorVersion));
return true; return true;
@@ -1585,18 +1643,20 @@ bool NodeMetaInfo::isSubclassOf(const TypeName &type, int majorVersion, int mino
return false; return false;
} }
bool NodeMetaInfo::isSubclassOf(const NodeMetaInfo &metaInfo) const
{
return isSubclassOf(metaInfo.typeName(), metaInfo.majorVersion(), metaInfo.minorVersion());
}
bool NodeMetaInfo::isGraphicalItem() const bool NodeMetaInfo::isGraphicalItem() const
{ {
return isSubclassOf("QtQuick.Item") return isSubclassOf("QtQuick.Item") || isSubclassOf("QtQuick.Window.Window")
|| isSubclassOf("QtQuick.Window.Window") || isSubclassOf("QtQuick.Dialogs.Dialog") || isSubclassOf("QtQuick.Controls.Popup");
|| isSubclassOf("QtQuick.Dialogs.Dialog")
|| isSubclassOf("QtQuick.Controls.Popup");
} }
bool NodeMetaInfo::isQmlItem() const bool NodeMetaInfo::isQmlItem() const
{ {
return isSubclassOf("QtQuick.QtObject") return isSubclassOf("QtQuick.QtObject") || isSubclassOf("QtQml.QtObject");
|| isSubclassOf("QtQml.QtObject");
} }
bool NodeMetaInfo::isLayoutable() const bool NodeMetaInfo::isLayoutable() const
@@ -1604,17 +1664,15 @@ bool NodeMetaInfo::isLayoutable() const
if (isSubclassOf("<cpp>.QDeclarativeBasePositioner")) if (isSubclassOf("<cpp>.QDeclarativeBasePositioner"))
return true; //QtQuick 1 return true; //QtQuick 1
return isSubclassOf("QtQuick.Positioner") return isSubclassOf("QtQuick.Positioner") || isSubclassOf("QtQuick.Layouts.Layout")
|| isSubclassOf("QtQuick.Layouts.Layout") || isSubclassOf("QtQuick.Controls.SplitView");
|| isSubclassOf("QtQuick.Controls.SplitView");
} }
bool NodeMetaInfo::isView() const bool NodeMetaInfo::isView() const
{ {
return isValid() && return isValid()
(isSubclassOf("QtQuick.ListView") || && (isSubclassOf("QtQuick.ListView") || isSubclassOf("QtQuick.GridView")
isSubclassOf("QtQuick.GridView") || || isSubclassOf("QtQuick.PathView"));
isSubclassOf("QtQuick.PathView"));
} }
bool NodeMetaInfo::isTabView() const bool NodeMetaInfo::isTabView() const
@@ -1622,48 +1680,171 @@ bool NodeMetaInfo::isTabView() const
return isSubclassOf("QtQuick.Controls.TabView"); return isSubclassOf("QtQuick.Controls.TabView");
} }
bool NodeMetaInfo::isAlias() const
{
return m_privateData && m_privateData->qualfiedTypeName() == "alias";
}
bool NodeMetaInfo::isQmlComponent() const
{
auto type = m_privateData->qualfiedTypeName();
return type == "Component" || type == "Qt.Component" || type == "QtQuick.Component"
|| type == "QtQml.Component" || type == "<cpp>.QQmlComponent" || type == "QQmlComponent";
}
bool NodeMetaInfo::isFont() const
{
return m_privateData && m_privateData->qualfiedTypeName() == "font";
}
bool NodeMetaInfo::isColor() const
{
if (!m_privateData)
return false;
auto type = m_privateData->qualfiedTypeName();
return type == "QColor" || type == "color";
}
bool NodeMetaInfo::isBool() const
{
if (!m_privateData)
return false;
auto type = m_privateData->qualfiedTypeName();
return type == "bool" || type == "boolean";
}
bool NodeMetaInfo::isInteger() const
{
if (!m_privateData)
return false;
auto type = m_privateData->qualfiedTypeName();
return type == "int" || type == "integer";
}
bool NodeMetaInfo::isFloat() const
{
if (!m_privateData)
return false;
auto type = m_privateData->qualfiedTypeName();
return type == "qreal" || type == "double" || type == "float";
;
}
bool NodeMetaInfo::isVariant() const
{
return m_privateData && m_privateData->qualfiedTypeName() == "QVariant";
}
bool NodeMetaInfo::isString() const
{
if (!m_privateData)
return false;
auto type = m_privateData->qualfiedTypeName();
return type == "string" || type == "QString";
}
bool NodeMetaInfo::isUrl() const
{
if (!m_privateData)
return false;
auto type = m_privateData->qualfiedTypeName();
return type == "url" || type == "QUrl";
}
bool NodeMetaInfo::isQtQuick3DTexture() const
{
return m_privateData && m_privateData->qualfiedTypeName() == "QtQuick3D.Texture";
}
bool NodeMetaInfo::isEnumeration() const
{
if constexpr (useProjectStorage())
return bool(typeData().traits & Storage::TypeTraits::IsEnum);
return false;
}
PropertyMetaInfo::PropertyMetaInfo(QSharedPointer<NodeMetaInfoPrivate> nodeMetaInfoPrivateData, PropertyMetaInfo::PropertyMetaInfo(QSharedPointer<NodeMetaInfoPrivate> nodeMetaInfoPrivateData,
const PropertyName &propertyName) const PropertyName &propertyName)
: m_nodeMetaInfoPrivateData{nodeMetaInfoPrivateData} : m_nodeMetaInfoPrivateData{nodeMetaInfoPrivateData}
, m_propertyName{propertyName} , m_propertyName{propertyName}
, m_projectStorage{nullptr}
{} {}
PropertyMetaInfo::~PropertyMetaInfo() {} PropertyMetaInfo::~PropertyMetaInfo() = default;
const TypeName &PropertyMetaInfo::propertyTypeName() const NodeMetaInfo PropertyMetaInfo::propertyType() const
{ {
return m_nodeMetaInfoPrivateData->propertyType(m_propertyName); if constexpr (useProjectStorage()) {
return {propertyData().typeId, m_projectStorage};
} else {
return NodeMetaInfo{m_nodeMetaInfoPrivateData->model(),
m_nodeMetaInfoPrivateData->propertyType(m_propertyName),
-1,
-1};
}
} }
NodeMetaInfo PropertyMetaInfo::propertyNodeMetaInfo() const PropertyName PropertyMetaInfo::name() const
{ {
return m_nodeMetaInfoPrivateData->model()->metaInfo(propertyTypeName()); if constexpr (useProjectStorage())
return PropertyName(Utils::SmallStringView(propertyData().name));
else
return m_propertyName;
} }
bool PropertyMetaInfo::isWritable() const bool PropertyMetaInfo::isWritable() const
{ {
return m_nodeMetaInfoPrivateData->isPropertyWritable(m_propertyName); if constexpr (useProjectStorage())
return !(propertyData().traits & Storage::PropertyDeclarationTraits::IsReadOnly);
else
return m_nodeMetaInfoPrivateData->isPropertyWritable(m_propertyName);
} }
bool PropertyMetaInfo::isListProperty() const bool PropertyMetaInfo::isListProperty() const
{ {
return m_nodeMetaInfoPrivateData->isPropertyList(m_propertyName); if constexpr (useProjectStorage())
return propertyData().traits & Storage::PropertyDeclarationTraits::IsList;
else
return m_nodeMetaInfoPrivateData->isPropertyList(m_propertyName);
} }
bool PropertyMetaInfo::isEnumType() const bool PropertyMetaInfo::isEnumType() const
{ {
return m_nodeMetaInfoPrivateData->isPropertyEnum(m_propertyName); if constexpr (useProjectStorage())
return propertyType().isEnumeration();
else
return m_nodeMetaInfoPrivateData->isPropertyEnum(m_propertyName);
} }
bool PropertyMetaInfo::isPrivate() const bool PropertyMetaInfo::isPrivate() const
{ {
return m_propertyName.startsWith("__"); if constexpr (useProjectStorage())
return propertyData().name.startsWith("__");
else
return m_propertyName.startsWith("__");
} }
bool PropertyMetaInfo::isPointer() const bool PropertyMetaInfo::isPointer() const
{ {
return m_nodeMetaInfoPrivateData->isPropertyPointer(m_propertyName); if constexpr (useProjectStorage())
return propertyData().traits & Storage::PropertyDeclarationTraits::IsPointer;
else
return m_nodeMetaInfoPrivateData->isPropertyPointer(m_propertyName);
} }
QVariant PropertyMetaInfo::castedValue(const QVariant &value) const QVariant PropertyMetaInfo::castedValue(const QVariant &value) const
@@ -1708,4 +1889,17 @@ QVariant PropertyMetaInfo::castedValue(const QVariant &value) const
return Internal::PropertyParser::variantFromString(variant.toString()); return Internal::PropertyParser::variantFromString(variant.toString());
} }
const Storage::Info::PropertyDeclaration &PropertyMetaInfo::propertyData() const
{
if (!m_propertyData)
m_propertyData = m_projectStorage->propertyDeclaration(m_id);
return *m_propertyData;
}
TypeName PropertyMetaInfo::propertyTypeName() const
{
return propertyType().typeName();
}
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -998,7 +998,7 @@ static int getMajorVersionFromNode(const ModelNode &modelNode)
static int getMinorVersionFromNode(const ModelNode &modelNode) static int getMinorVersionFromNode(const ModelNode &modelNode)
{ {
if (modelNode.metaInfo().isValid()) { if (modelNode.metaInfo().isValid()) {
const QList<NodeMetaInfo> infos = modelNode.metaInfo().classHierarchy(); const NodeMetaInfos infos = modelNode.metaInfo().classHierarchy();
for (const NodeMetaInfo &info : infos) { for (const NodeMetaInfo &info : infos) {
if (info.typeName() == "QtQuick.QtObject" || info.typeName() == "QtQuick.Item") if (info.typeName() == "QtQuick.QtObject" || info.typeName() == "QtQuick.Item")
return info.minorVersion(); return info.minorVersion();

View File

@@ -34,8 +34,9 @@
#include "internalvariantproperty.h" #include "internalvariantproperty.h"
#include <auxiliarydata.h> #include <auxiliarydata.h>
#include <utils/optional.h> #include <utils/optional.h>
#include <projectstorageids.h>
#include <utils/smallstring.h>
#include <QHash> #include <QHash>
#include <QMap> #include <QMap>
@@ -149,6 +150,9 @@ public:
int nodeSourceType = 0; int nodeSourceType = 0;
QString behaviorPropertyName; QString behaviorPropertyName;
QStringList scriptFunctions; QStringList scriptFunctions;
ModuleId moduleId; // is invalid if type is implicit
Utils::SmallString documentTypeName; // how the type is written in den Document
TypeId typeId;
private: private:
AuxiliaryDatas m_auxiliaryDatas; AuxiliaryDatas m_auxiliaryDatas;

View File

@@ -30,11 +30,7 @@
#include "model_p.h" #include "model_p.h"
#include <modelnode.h> #include <modelnode.h>
#include <QFileInfo>
#include <QHashIterator>
#include <QPointer>
#include <utils/algorithm.h>
#include "abstractview.h" #include "abstractview.h"
#include "internalnodeabstractproperty.h" #include "internalnodeabstractproperty.h"
@@ -57,6 +53,8 @@
#include "textmodifier.h" #include "textmodifier.h"
#include "variantproperty.h" #include "variantproperty.h"
#include <projectstorage/projectstorage.h>
#ifndef QMLDESIGNER_TEST #ifndef QMLDESIGNER_TEST
#include <qmldesignerplugin.h> #include <qmldesignerplugin.h>
#include <viewmanager.h> #include <viewmanager.h>
@@ -68,6 +66,9 @@
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <QDrag> #include <QDrag>
#include <QFileInfo>
#include <QHashIterator>
#include <QPointer>
#include <QRegularExpression> #include <QRegularExpression>
/*! /*!
@@ -95,8 +96,8 @@ ModelPrivate::ModelPrivate(Model *model,
int major, int major,
int minor, int minor,
Model *metaInfoProxyModel) Model *metaInfoProxyModel)
: m_model{model} : projectStorage{&projectStorage}
, m_projectStorage{&projectStorage} , m_model{model}
{ {
m_metaInfoProxyModel = metaInfoProxyModel; m_metaInfoProxyModel = metaInfoProxyModel;
@@ -1578,6 +1579,11 @@ void Model::endDrag()
d->notifyDragEnded(); d->notifyDragEnded();
} }
NotNullPointer<const ProjectStorage<Sqlite::Database>> Model::projectStorage() const
{
return d->projectStorage;
}
QString Model::generateNewId(const QString &prefixName) const QString Model::generateNewId(const QString &prefixName) const
{ {
return generateNewId(prefixName, QStringLiteral("element")); return generateNewId(prefixName, QStringLiteral("element"));
@@ -1666,12 +1672,12 @@ void Model::setNodeInstanceView(NodeInstanceView *nodeInstanceView)
\brief Returns the model that is used for metainfo \brief Returns the model that is used for metainfo
\return Returns itself if other metaInfoProxyModel does not exist \return Returns itself if other metaInfoProxyModel does not exist
*/ */
Model *Model::metaInfoProxyModel() Model *Model::metaInfoProxyModel() const
{ {
if (d->m_metaInfoProxyModel) if (d->m_metaInfoProxyModel)
return d->m_metaInfoProxyModel->metaInfoProxyModel(); return d->m_metaInfoProxyModel->metaInfoProxyModel();
return this; return const_cast<Model *>(this);
} }
TextModifier *Model::textModifier() const TextModifier *Model::textModifier() const
@@ -1740,7 +1746,7 @@ const MetaInfo Model::metaInfo() const
return d->metaInfo(); return d->metaInfo();
} }
bool Model::hasNodeMetaInfo(const TypeName &typeName, int majorVersion, int minorVersion) bool Model::hasNodeMetaInfo(const TypeName &typeName, int majorVersion, int minorVersion) const
{ {
return metaInfo(typeName, majorVersion, minorVersion).isValid(); return metaInfo(typeName, majorVersion, minorVersion).isValid();
} }
@@ -1750,9 +1756,33 @@ void Model::setMetaInfo(const MetaInfo &metaInfo)
d->setMetaInfo(metaInfo); d->setMetaInfo(metaInfo);
} }
NodeMetaInfo Model::metaInfo(const TypeName &typeName, int majorVersion, int minorVersion) namespace {
[[maybe_unused]] std::pair<Utils::SmallStringView, Utils::SmallStringView> moduleTypeName(
const TypeName &typeName)
{ {
return NodeMetaInfo(metaInfoProxyModel(), typeName, majorVersion, minorVersion); auto foundDot = std::find(typeName.begin(), typeName.end(), '.');
if (foundDot == typeName.end())
return {"", typeName};
return {{typeName.begin(), foundDot}, {std::next(foundDot), typeName.end()}};
}
} // namespace
NodeMetaInfo Model::metaInfo(const TypeName &typeName, int majorVersion, int minorVersion) const
{
if constexpr (useProjectStorage()) {
auto [module, componentName] = moduleTypeName(typeName);
ModuleId moduleId = d->projectStorage->moduleId(module);
TypeId typeId = d->projectStorage->typeId(moduleId,
componentName,
Storage::Synchronization::Version{majorVersion,
minorVersion});
return NodeMetaInfo(typeId, d->projectStorage);
} else {
return NodeMetaInfo(metaInfoProxyModel(), typeName, majorVersion, minorVersion);
}
} }
/*! /*!

View File

@@ -268,6 +268,9 @@ public:
void updateEnabledViews(); void updateEnabledViews();
public:
NotNullPointer<ProjectStorage<Sqlite::Database>> projectStorage = nullptr;
private: private:
void removePropertyWithoutNotification(const InternalPropertyPointer &property); void removePropertyWithoutNotification(const InternalPropertyPointer &property);
void removeAllSubNodes(const InternalNodePointer &node); void removeAllSubNodes(const InternalNodePointer &node);
@@ -298,7 +301,6 @@ private:
QPointer<TextModifier> m_textModifier; QPointer<TextModifier> m_textModifier;
QPointer<Model> m_metaInfoProxyModel; QPointer<Model> m_metaInfoProxyModel;
QHash<TypeName, QSharedPointer<NodeMetaInfoPrivate>> m_nodeMetaInfoCache; QHash<TypeName, QSharedPointer<NodeMetaInfoPrivate>> m_nodeMetaInfoCache;
ProjectStorage<Sqlite::Database> *m_projectStorage = nullptr;
bool m_writeLock = false; bool m_writeLock = false;
qint32 m_internalIdCounter = 1; qint32 m_internalIdCounter = 1;
}; };

View File

@@ -870,7 +870,17 @@ NodeMetaInfo ModelNode::metaInfo() const
throw InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); throw InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
} }
return NodeMetaInfo(model()->metaInfoProxyModel(), type(), majorVersion(), minorVersion()); if (!m_internalNode->typeId)
throw InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
if constexpr (useProjectStorage()) {
return NodeMetaInfo(m_internalNode->typeId, m_model->projectStorage());
} else {
return NodeMetaInfo(m_model->metaInfoProxyModel(),
m_internalNode->typeName,
m_internalNode->majorVersion,
m_internalNode->minorVersion);
}
} }
bool ModelNode::hasMetaInfo() const bool ModelNode::hasMetaInfo() const
@@ -948,20 +958,23 @@ bool ModelNode::hasNodeAbstractProperty(const PropertyName &name) const
bool ModelNode::hasDefaultNodeAbstractProperty() const bool ModelNode::hasDefaultNodeAbstractProperty() const
{ {
return hasProperty(metaInfo().defaultPropertyName()) auto defaultPropertyName = metaInfo().defaultPropertyName();
&& m_internalNode->property(metaInfo().defaultPropertyName())->isNodeAbstractProperty(); return hasProperty(defaultPropertyName)
&& m_internalNode->property(defaultPropertyName)->isNodeAbstractProperty();
} }
bool ModelNode::hasDefaultNodeListProperty() const bool ModelNode::hasDefaultNodeListProperty() const
{ {
return hasProperty(metaInfo().defaultPropertyName()) auto defaultPropertyName = metaInfo().defaultPropertyName();
&& m_internalNode->property(metaInfo().defaultPropertyName())->isNodeListProperty(); return hasProperty(defaultPropertyName)
&& m_internalNode->property(defaultPropertyName)->isNodeListProperty();
} }
bool ModelNode::hasDefaultNodeProperty() const bool ModelNode::hasDefaultNodeProperty() const
{ {
return hasProperty(metaInfo().defaultPropertyName()) auto defaultPropertyName = metaInfo().defaultPropertyName();
&& m_internalNode->property(metaInfo().defaultPropertyName())->isNodeProperty(); return hasProperty(defaultPropertyName)
&& m_internalNode->property(defaultPropertyName)->isNodeProperty();
} }
bool ModelNode::hasNodeProperty(const PropertyName &name) const bool ModelNode::hasNodeProperty(const PropertyName &name) const

View File

@@ -252,7 +252,7 @@ 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)
&& modelNode().metaInfo().property(name).propertyTypeNameIsString()) { && modelNode().metaInfo().property(name).propertyType().isString()) {
if (modelNode().hasBindingProperty(name)) { if (modelNode().hasBindingProperty(name)) {
static QRegularExpression regularExpressionPattern( static QRegularExpression regularExpressionPattern(
QLatin1String("^qsTr(|Id|anslate)\\(\".*\"\\)$")); QLatin1String("^qsTr(|Id|anslate)\\(\".*\"\\)$"));

View File

@@ -206,21 +206,16 @@ QVariant QmlTimelineKeyframeGroup::value(qreal frame) const
return QVariant(); return QVariant();
} }
TypeName QmlTimelineKeyframeGroup::valueType() const NodeMetaInfo QmlTimelineKeyframeGroup::valueType() const
{ {
QTC_ASSERT(isValid(), return {}); QTC_ASSERT(isValid(), return {});
const ModelNode targetNode = target(); const ModelNode targetNode = target();
TypeName typeName;
if (targetNode.isValid() && targetNode.hasMetaInfo()) if (targetNode.isValid() && targetNode.hasMetaInfo())
typeName = targetNode.metaInfo().property(propertyName()).propertyTypeName(); return targetNode.metaInfo().property(propertyName()).propertyType();
if (typeName.startsWith("<cpp>.")) return {};
typeName.remove(0, 6);
return typeName;
} }
bool QmlTimelineKeyframeGroup::hasKeyframe(qreal frame) bool QmlTimelineKeyframeGroup::hasKeyframe(qreal frame)

View File

@@ -339,8 +339,7 @@ bool propertyIsComponentType(const QmlDesigner::NodeAbstractProperty &property,
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().property(property.name()).propertyType().isQmlComponent();
property.parentModelNode().metaInfo().property(property.name()).propertyTypeName());
} }
QString extractComponentFromQml(const QString &source) QString extractComponentFromQml(const QString &source)

View File

@@ -184,7 +184,7 @@ public:
propertyDeclarationId); propertyDeclarationId);
} }
Utils::optional<Storage::Info::Type> type(TypeId typeId) Utils::optional<Storage::Info::Type> type(TypeId typeId) const
{ {
return selectInfoTypeByTypeIdStatement.template optionalValueWithTransaction<Storage::Info::Type>( return selectInfoTypeByTypeIdStatement.template optionalValueWithTransaction<Storage::Info::Type>(
typeId); typeId);

View File

@@ -0,0 +1,38 @@
/****************************************************************************
**
** 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
namespace Sqlite {
class Database;
};
namespace QmlDesigner {
template<typename Database>
class ProjectStorage;
template<typename Type>
using NotNullPointer = Type *;
}

View File

@@ -0,0 +1,121 @@
/****************************************************************************
**
** 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 "projectstorageids.h"
#include <utils/smallstring.h>
#include <tuple>
#include <variant>
#include <vector>
namespace QmlDesigner {
template<typename Enumeration>
constexpr std::underlying_type_t<Enumeration> to_underlying(Enumeration enumeration) noexcept
{
static_assert(std::is_enum_v<Enumeration>, "to_underlying expect an enumeration");
return static_cast<std::underlying_type_t<Enumeration>>(enumeration);
}
} // namespace QmlDesigner
namespace QmlDesigner::Storage {
enum class PropertyDeclarationTraits : int {
None = 0,
IsReadOnly = 1 << 0,
IsPointer = 1 << 1,
IsList = 1 << 2
};
constexpr PropertyDeclarationTraits operator|(PropertyDeclarationTraits first,
PropertyDeclarationTraits second)
{
return static_cast<PropertyDeclarationTraits>(static_cast<int>(first) | static_cast<int>(second));
}
constexpr bool operator&(PropertyDeclarationTraits first, PropertyDeclarationTraits second)
{
return static_cast<int>(first) & static_cast<int>(second);
}
enum class TypeTraits : int {
None,
Reference,
Value,
Sequence,
IsEnum = 1 << 8,
IsFileComponent = 1 << 9
};
constexpr TypeTraits operator|(TypeTraits first, TypeTraits second)
{
return static_cast<TypeTraits>(static_cast<int>(first) | static_cast<int>(second));
}
constexpr TypeTraits operator&(TypeTraits first, TypeTraits second)
{
return static_cast<TypeTraits>(static_cast<int>(first) & static_cast<int>(second));
}
using TypeNameString = Utils::BasicSmallString<63>;
} // namespace QmlDesigner::Storage
namespace QmlDesigner::Storage::Info {
class PropertyDeclaration
{
public:
PropertyDeclaration(TypeId typeId,
Utils::SmallStringView name,
PropertyDeclarationTraits traits,
TypeId propertyTypeId)
: typeId{typeId}
, name{name}
, traits{traits}
, propertyTypeId{propertyTypeId}
{}
TypeId typeId;
Utils::SmallString name;
PropertyDeclarationTraits traits;
TypeId propertyTypeId;
};
class Type
{
public:
Type(PropertyDeclarationId defaultPropertyId, TypeTraits traits)
: defaultPropertyId{defaultPropertyId}
, traits{traits}
{}
PropertyDeclarationId defaultPropertyId;
TypeTraits traits;
};
} // namespace QmlDesigner::Storage::Info

View File

@@ -27,6 +27,7 @@
#include "filestatus.h" #include "filestatus.h"
#include "projectstorageids.h" #include "projectstorageids.h"
#include "projectstorageinfotypes.h"
#include <utils/smallstring.h> #include <utils/smallstring.h>
@@ -34,54 +35,6 @@
#include <variant> #include <variant>
#include <vector> #include <vector>
namespace QmlDesigner {
template<typename Enumeration>
constexpr std::underlying_type_t<Enumeration> to_underlying(Enumeration enumeration) noexcept
{
static_assert(std::is_enum_v<Enumeration>, "to_underlying expect an enumeration");
return static_cast<std::underlying_type_t<Enumeration>>(enumeration);
}
} // namespace QmlDesigner
namespace QmlDesigner::Storage {
enum class PropertyDeclarationTraits : int {
None = 0,
IsReadOnly = 1 << 0,
IsPointer = 1 << 1,
IsList = 1 << 2
};
constexpr PropertyDeclarationTraits operator|(PropertyDeclarationTraits first,
PropertyDeclarationTraits second)
{
return static_cast<PropertyDeclarationTraits>(static_cast<int>(first) | static_cast<int>(second));
}
constexpr bool operator&(PropertyDeclarationTraits first, PropertyDeclarationTraits second)
{
return static_cast<int>(first) & static_cast<int>(second);
}
enum class TypeTraits : int {
None,
Reference,
Value,
Sequence,
IsEnum = 1 << 8,
IsFileComponent = 1 << 9
};
constexpr TypeTraits operator|(TypeTraits first, TypeTraits second)
{
return static_cast<TypeTraits>(static_cast<int>(first) | static_cast<int>(second));
}
using TypeNameString = Utils::BasicSmallString<63>;
} // namespace QmlDesigner::Storage
namespace QmlDesigner::Storage::Synchronization { namespace QmlDesigner::Storage::Synchronization {
enum class TypeNameKind { Exported = 1, QualifiedExported = 2 }; enum class TypeNameKind { Exported = 1, QualifiedExported = 2 };
@@ -912,37 +865,3 @@ public:
} // namespace QmlDesigner::Storage::Synchronization } // namespace QmlDesigner::Storage::Synchronization
namespace QmlDesigner::Storage::Info {
class PropertyDeclaration
{
public:
PropertyDeclaration(TypeId typeId,
Utils::SmallStringView name,
PropertyDeclarationTraits traits,
TypeId propertyTypeId)
: typeId{typeId}
, name{name}
, traits{traits}
, propertyTypeId{propertyTypeId}
{}
TypeId typeId;
Utils::SmallString name;
PropertyDeclarationTraits traits;
TypeId propertyTypeId;
};
class Type
{
public:
Type(PropertyDeclarationId defaultPropertyId, TypeTraits traits)
: defaultPropertyId{defaultPropertyId}
, traits{traits}
{}
PropertyDeclarationId defaultPropertyId;
TypeTraits traits;
};
} // namespace QmlDesigner::Storage::Info

View File

@@ -28,15 +28,10 @@
#include "nonlockingmutex.h" #include "nonlockingmutex.h"
#include "qmldocumentparserinterface.h" #include "qmldocumentparserinterface.h"
namespace Sqlite { #include <projectstoragefwd.h>
class Database;
}
namespace QmlDesigner { namespace QmlDesigner {
template<typename Database>
class ProjectStorage;
template<typename ProjectStorage, typename Mutex> template<typename ProjectStorage, typename Mutex>
class SourcePathCache; class SourcePathCache;

View File

@@ -25,6 +25,8 @@
#pragma once #pragma once
#include <projectstoragefwd.h>
#include <QList> #include <QList>
#include <QObject> #include <QObject>
@@ -42,15 +44,8 @@ class Project;
class Target; class Target;
} // namespace ProjectExplorer } // namespace ProjectExplorer
namespace Sqlite {
class Database;
}
namespace QmlDesigner { namespace QmlDesigner {
template<typename Database>
class ProjectStorage;
class QmlDesignerProjectManager : public QObject class QmlDesignerProjectManager : public QObject
{ {
Q_OBJECT Q_OBJECT

View File

@@ -1,4 +1,4 @@
if (${Qt5_VERSION} VERSION_GREATER_EQUAL "6.2.0") if (${Qt5_VERSION} VERSION_GREATER_EQUAL "6.2.0")
add_subdirectory(coretests) # add_subdirectory(coretests)
add_subdirectory(wizard) add_subdirectory(wizard)
endif() endif()

View File

@@ -1,6 +1,7 @@
add_qtc_test(tst_qml_testcore add_qtc_test(tst_qml_testcore
EXCLUDE_FROM_PRECHECK EXCLUDE_FROM_PRECHECK
CONDITION TARGET QmlProjectManager AND Qt5_VERSION VERSION_GREATER_EQUAL 6.2.0 CONDITION TARGET QmlProjectManager AND Qt5_VERSION VERSION_GREATER_EQUAL 6.2.0
DEPENDS Sqlite
DEFINES DEFINES
QT_CREATOR QT_CREATOR
QMLDESIGNER_TEST QMLDESIGNER_TEST

View File

@@ -27,6 +27,9 @@
#include "propertymetainfo.h" #include "propertymetainfo.h"
#include <projectstorage/projectstoragefwd.h>
#include <projectstorageids.h>
#include <QIcon> #include <QIcon>
#include <QList> #include <QList>
#include <QString> #include <QString>
@@ -49,6 +52,8 @@ class NodeMetaInfo
public: public:
NodeMetaInfo() {} NodeMetaInfo() {}
NodeMetaInfo(Model *, const TypeName &, int, int) {} NodeMetaInfo(Model *, const TypeName &, int, int) {}
NodeMetaInfo(TypeId, NotNullPointer<const ProjectStorage<Sqlite::Database>>) {}
NodeMetaInfo(NotNullPointer<const ProjectStorage<Sqlite::Database>>) {}
bool isValid() const { return {}; } bool isValid() const { return {}; }
bool isFileComponent() const { return {}; } bool isFileComponent() const { return {}; }
@@ -62,8 +67,8 @@ public:
PropertyName defaultPropertyName() const { return "data"; } PropertyName defaultPropertyName() const { return "data"; }
bool hasDefaultProperty() const { return {}; } bool hasDefaultProperty() const { return {}; }
QList<NodeMetaInfo> classHierarchy() const { return {}; } std::vector<NodeMetaInfo> classHierarchy() const { return {}; }
QList<NodeMetaInfo> superClasses() const { return {}; } std::vector<NodeMetaInfo> superClasses() const { return {}; }
NodeMetaInfo directSuperClass() const { return {}; } NodeMetaInfo directSuperClass() const { return {}; }
bool defaultPropertyIsComponent() const { return {}; } bool defaultPropertyIsComponent() const { return {}; }
@@ -91,4 +96,6 @@ public:
static void clearCache() {} static void clearCache() {}
}; };
using NodeMetaInfos = std::vector<NodeMetaInfo>;
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -562,14 +562,9 @@ const char *typeTraitsToString(TypeTraits traits)
return ""; return "";
} }
bool operator&(TypeTraits first, TypeTraits second)
{
return static_cast<int>(first) & static_cast<int>(second);
}
const char *typeTraitsFlagsToString(TypeTraits traits) const char *typeTraitsFlagsToString(TypeTraits traits)
{ {
if (traits & TypeTraits::IsEnum) if (bool(traits & TypeTraits::IsEnum))
return "(IsEnum)"; return "(IsEnum)";
return ""; return "";