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")
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
CONDITION Qt5_VERSION VERSION_GREATER_EQUAL 6.2.0 AND TARGET Qt5::QuickWidgets AND TARGET Qt5::Svg
DEPENDS
@@ -11,6 +20,7 @@ add_qtc_plugin(QmlDesigner
DEFINES
IDE_LIBRARY_BASENAME=\"${IDE_LIBRARY_BASE_PATH}\"
SHARE_QML_PATH="${CMAKE_CURRENT_SOURCE_DIR}/../../../share/qtcreator/qmldesigner"
$<$<BOOL:${USE_PROJECTSTORAGE}>:QDS_USE_PROJECTSTORAGE>
PUBLIC_INCLUDES
"${CMAKE_CURRENT_LIST_DIR}"
"${CMAKE_CURRENT_LIST_DIR}/designercore/include"
@@ -50,10 +60,6 @@ add_qtc_plugin(QmlDesigner
include(qmldesignercore.cmake)
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)
# make the configuration in the build dir
file(MAKE_DIRECTORY ${build_dir}/${name})
@@ -458,6 +464,7 @@ extend_qtc_plugin(QmlDesigner
nonlockingmutex.h
projectstorageinterface.h
projectstorage.cpp projectstorage.h
projectstoragefwd.h
projectstoragepathwatcher.h
projectstoragepathwatcherinterface.h
projectstoragepathwatchernotifierinterface.h

View File

@@ -195,6 +195,10 @@ void ActionEditor::prepareConnections()
constexpr auto typeWhiteList = std::make_tuple(
"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"});
QList<ActionEditorDialog::ConnectionOption> connections;
@@ -210,12 +214,12 @@ void ActionEditor::prepareConnections()
ActionEditorDialog::ConnectionOption connection(modelNode.id());
for (const auto &property : modelNode.metaInfo().properties()) {
if (!property.hasPropertyTypeName(typeWhiteList))
if (isSkippedType(property.propertyType()))
continue;
connection.properties.append(
ActionEditorDialog::PropertyOption(QString::fromUtf8(property.name()),
skipCpp(std::move(property.propertyTypeName())),
skipCpp(property.propertyType().typeName()),
property.isWritable()));
}
@@ -270,12 +274,12 @@ void ActionEditor::prepareConnections()
if (metaInfo.isValid()) {
ActionEditorDialog::SingletonOption singelton;
for (const auto &property : metaInfo.properties()) {
if (!property.hasPropertyTypeName(typeWhiteList))
if (isSkippedType(property.propertyType()))
continue;
singelton.properties.append(
ActionEditorDialog::PropertyOption(QString::fromUtf8(property.name()),
skipCpp(property.propertyTypeName()),
singelton.properties.append(ActionEditorDialog::PropertyOption(
QString::fromUtf8(property.name()),
skipCpp(property.propertyType().typeName()),
property.isWritable()));
}

View File

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

View File

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

View File

@@ -157,10 +157,10 @@ QStringList BindingModel::possibleSourceProperties(const BindingProperty &bindin
const QStringList stringlist = expression.split(QLatin1String("."));
QStringList possibleProperties;
TypeName typeName;
NodeMetaInfo type;
if (auto metaInfo = bindingProperty.parentModelNode().metaInfo(); metaInfo.isValid())
typeName = metaInfo.property(bindingProperty.name()).propertyTypeName();
type = metaInfo.property(bindingProperty.name()).propertyType();
else
qWarning() << " BindingModel::possibleSourcePropertiesForRow no meta info for target node";
@@ -172,8 +172,7 @@ QStringList BindingModel::possibleSourceProperties(const BindingProperty &bindin
//if it's not a valid model node, maybe it's a singleton
if (RewriterView* rv = connectionView()->rewriterView()) {
for (const QmlTypeData &data : rv->getQMLTypes()) {
if (!data.typeName.isEmpty()) {
if (data.typeName == id) {
if (!data.typeName.isEmpty() && data.typeName == id) {
NodeMetaInfo metaInfo = connectionView()->model()->metaInfo(data.typeName.toUtf8());
if (metaInfo.isValid()) {
@@ -187,7 +186,6 @@ QStringList BindingModel::possibleSourceProperties(const BindingProperty &bindin
}
}
}
}
qWarning() << " BindingModel::possibleSourcePropertiesForRow invalid model node";
return QStringList();
@@ -207,7 +205,7 @@ QStringList BindingModel::possibleSourceProperties(const BindingProperty &bindin
if (metaInfo.isValid()) {
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()));
}
} else {

View File

@@ -474,8 +474,7 @@ QStringList ConnectionModel::getPossibleSignalsForConnection(const ModelNode &co
auto getAliasMetaSignals = [&](QString aliasPart, NodeMetaInfo metaInfo) {
if (metaInfo.isValid() && metaInfo.hasProperty(aliasPart.toUtf8())) {
NodeMetaInfo propertyMetaInfo = connectionView()->model()->metaInfo(
metaInfo.property(aliasPart.toUtf8()).propertyTypeName());
NodeMetaInfo propertyMetaInfo = metaInfo.property(aliasPart.toUtf8()).propertyType();
if (propertyMetaInfo.isValid()) {
return propertyNameListToStringList(propertyMetaInfo.signalNames());
}

View File

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

View File

@@ -299,25 +299,17 @@ QWidget *ConnectionDelegate::createEditor(QWidget *parent, const QStyleOptionVie
auto addMetaInfoProperties = [&](const NodeMetaInfo& itemMetaInfo, QString itemName){
if (itemMetaInfo.isValid()) {
for (const auto &property : itemMetaInfo.properties()) {
TypeName propertyType = property.propertyTypeName();
if (!propertyType.isEmpty()) {
//first letter is a reliable item indicator
QChar firstLetter = QString::fromUtf8(propertyType).at(0);
if (firstLetter.isLetter() && firstLetter.isUpper()) {
NodeMetaInfo propertyType = property.propertyType();
if (propertyType.isValid() && propertyType.isFileComponent()) {
if (!property.isEnumType() && !property.isPrivate()
&& !property.isListProperty() && !property.isPointer()) {
NodeMetaInfo propertyMetaInfo =
connectionModel->connectionView()->model()->metaInfo(propertyType);
if (propertyMetaInfo.isValid()) {
if (propertyMetaInfo.isQmlItem()) {
if (propertyType.isQmlItem()) {
connectionComboBox->addItem(itemName + "." + property.name());
}
}
}
}
}
}
}
};
for (const ModelNode &modelNode : connectionModel->connectionView()->allModelNodes()) {

View File

@@ -383,10 +383,10 @@ QStringList DynamicPropertiesModel::possibleSourceProperties(const BindingProper
const QString expression = bindingProperty.expression();
const QStringList stringlist = expression.split(QLatin1String("."));
PropertyName typeName;
NodeMetaInfo type;
if (auto metaInfo = bindingProperty.parentModelNode().metaInfo(); metaInfo.isValid()) {
typeName = metaInfo.property(bindingProperty.name()).propertyTypeName();
type = metaInfo.property(bindingProperty.name()).propertyType();
} else {
qWarning() << " BindingModel::possibleSourcePropertiesForRow no meta info for target node";
}
@@ -405,7 +405,7 @@ QStringList DynamicPropertiesModel::possibleSourceProperties(const BindingProper
if (metaInfo.isValid()) {
QStringList possibleProperties;
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()));
}
return possibleProperties;

View File

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

View File

@@ -617,12 +617,13 @@ void DesignDocument::paste()
const double scatterRange = 20.;
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)) {
PropertyName defaultProperty(targetNode.metaInfo().defaultPropertyName());
ModelNode pastedNode(view.insertModel(node));
pastedNodeList.append(pastedNode);
scatterItem(pastedNode, targetNode, offset);
targetNode.nodeListProperty(defaultProperty).reparentHere(pastedNode);
parentProperty.reparentHere(pastedNode);
}
view.setSelectedModelNodes(pastedNodeList);

View File

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

View File

@@ -145,7 +145,7 @@ void MaterialEditorView::changeValue(const QString &name)
bool propertyTypeUrl = false;
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
propertyTypeUrl = true;
QString filePath = castedValue.toUrl().toString();
@@ -209,7 +209,7 @@ void MaterialEditorView::changeExpression(const QString &propertyName)
if (auto metaInfo = m_selectedMaterial.metaInfo();
metaInfo.isValid() && metaInfo.hasProperty(name)) {
auto propertyTypeName = metaInfo.property(name).propertyTypeName();
auto propertyTypeName = metaInfo.property(name).propertyType().typeName();
if (propertyTypeName == "QColor") {
if (QColor(value->expression().remove('"')).isValid()) {
qmlObjectNode.setVariantProperty(name, QColor(value->expression().remove('"')));
@@ -542,8 +542,7 @@ void MaterialEditorView::setupQmlBackend()
NodeMetaInfo metaInfo = m_selectedMaterial.metaInfo();
if (metaInfo.isValid()) {
diffClassName = metaInfo.typeName();
const QList<NodeMetaInfo> hierarchy = metaInfo.classHierarchy();
for (const NodeMetaInfo &metaInfo : hierarchy) {
for (const NodeMetaInfo &metaInfo : metaInfo.classHierarchy()) {
if (PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsUrl))
break;
qmlSpecificsUrl = PropertyEditorQmlBackend::getQmlFileUrl(metaInfo.typeName()
@@ -1022,7 +1021,7 @@ void QmlDesigner::MaterialEditorView::highlightSupportedProperties(bool highligh
QTC_ASSERT(metaInfo.isValid(), return);
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 *>();
PropertyEditorValue *propEditorVal = qobject_cast<PropertyEditorValue *>(propEditorValObj);
propEditorVal->setHasActiveDrag(highlight);

View File

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

View File

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

View File

@@ -1040,7 +1040,9 @@ bool NavigatorTreeModel::dropAsImage3dTexture(const ModelNode &targetNode,
|| targetNode.isSubclassOf("QtQuick3D.PrincipledMaterial")) {
// if dropping an image on a material, create a texture instead of image
// 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());
if (!dialog)
return false;
@@ -1103,10 +1105,12 @@ ModelNode NavigatorTreeModel::createTextureNode(const NodeAbstractProperty &targ
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,
const QList<ModelNode> &modelNodes,
@@ -1116,17 +1120,16 @@ void NavigatorTreeModel::moveNodesInteractive(NodeAbstractProperty &parentProper
QTC_ASSERT(m_view, return);
auto doMoveNodesInteractive = [&parentProperty, modelNodes, targetIndex]() {
const TypeName propertyQmlType = propertyType(parentProperty);
const auto propertyQmlType = propertyType(parentProperty);
int idx = targetIndex;
for (const ModelNode &modelNode : modelNodes) {
if (modelNode.isValid()
&& modelNode != parentProperty.parentModelNode()
if (modelNode.isValid() && modelNode != parentProperty.parentModelNode()
&& !modelNode.isAncestorOf(parentProperty.parentModelNode())
&& (modelNode.metaInfo().isSubclassOf(propertyQmlType)
|| propertyQmlType == "alias"
&& (modelNode.metaInfo().isSubclassOf(propertyQmlType) || propertyQmlType.isAlias()
|| parentProperty.name() == "data"
|| (parentProperty.parentModelNode().metaInfo().defaultPropertyName() == parentProperty.name()
&& propertyQmlType == "<cpp>.QQmlComponent"))) {
|| (parentProperty.parentModelNode().metaInfo().defaultPropertyName()
== parentProperty.name()
&& propertyQmlType.isQmlComponent()))) {
//### todo: allowing alias is just a heuristic
//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()) {
setupPropertyEditorValue(property.name(),
propertyEditor,
QString::fromUtf8(property.propertyTypeName()));
QString::fromUtf8(property.propertyType().typeName()));
}
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 itemProperty = list.last();
TypeName typeName = type.property(parentProperty).propertyTypeName();
NodeMetaInfo propertyType = type.property(parentProperty).propertyType();
NodeMetaInfo itemInfo = node.view()->model()->metaInfo("QtQuick.Item");
NodeMetaInfo textInfo = node.view()->model()->metaInfo("QtQuick.Text");
NodeMetaInfo rectangleInfo = node.view()->model()->metaInfo("QtQuick.Rectangle");
NodeMetaInfo imageInfo = node.view()->model()->metaInfo("QtQuick.Image");
if (typeName == "font"
|| itemInfo.hasProperty(itemProperty)
|| textInfo.isSubclassOf(typeName)
|| rectangleInfo.isSubclassOf(typeName)
|| imageInfo.isSubclassOf(typeName))
if (propertyType.isFont() || itemInfo.hasProperty(itemProperty)
|| textInfo.isSubclassOf(propertyType) || rectangleInfo.isSubclassOf(propertyType)
|| imageInfo.isSubclassOf(propertyType))
return false;
return true;
@@ -630,10 +628,10 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &metaTyp
if (!superType.hasProperty(propertyName) // TODO add property.isLocalProperty()
&& property.isWritable() && dotPropertyHeuristic(node, metaType, propertyName)) {
QString typeName = QString::fromUtf8(property.propertyTypeName());
QString typeName = QString::fromUtf8(property.propertyType().typeName());
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
if (allTypes.contains(typeName)) {
@@ -674,9 +672,9 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &metaTyp
PropertyName underscoreProperty = propertyName;
underscoreProperty.replace('.', '_');
TypeName typeName = property.propertyTypeName();
TypeName typeName = property.propertyType().typeName();
// alias resolution only possible with instance
if (typeName == "alias" && node.isValid())
if (!useProjectStorage() && typeName == "alias" && node.isValid())
typeName = node.instanceType(propertyName);
QString filledTemplate;
@@ -743,9 +741,9 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &metaTyp
emptyTemplate = false;
for (auto &[property, properties] : propertyMap) {
// for (auto it = propertyMap.cbegin(); it != propertyMap.cend(); ++it) {
TypeName parentTypeName = property.propertyTypeName();
TypeName parentTypeName = property.propertyType().typeName();
// alias resolution only possible with instance
if (parentTypeName == "alias" && node.isValid())
if (!useProjectStorage() && parentTypeName == "alias" && node.isValid())
parentTypeName = node.instanceType(property.name());
qmlInnerTemplate += "Section {\n";
@@ -817,9 +815,10 @@ static NodeMetaInfo findCommonSuperClass(const NodeMetaInfo &first, const NodeMe
NodeMetaInfo PropertyEditorQmlBackend::findCommonAncestor(const ModelNode &node)
{
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();
@@ -910,7 +909,7 @@ void PropertyEditorQmlBackend::setValueforAuxiliaryProperties(const QmlObjectNod
QUrl PropertyEditorQmlBackend::getQmlUrlForMetaInfo(const NodeMetaInfo &metaInfo, TypeName &className)
{
if (metaInfo.isValid()) {
const QList<NodeMetaInfo> hierarchy = metaInfo.classHierarchy();
const NodeMetaInfos hierarchy = metaInfo.classHierarchy();
for (const NodeMetaInfo &info : hierarchy) {
QUrl fileUrl = fileToUrl(locateQmlFile(info, QString::fromUtf8(qmlFileName(info))));
if (fileUrl.isValid()) {

View File

@@ -71,7 +71,7 @@ public:
static QString propertyEditorResourcesPath();
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 bool checkIfUrlExists(const QUrl &url);

View File

@@ -63,7 +63,7 @@ QVariant PropertyEditorValue::value() const
if (modelNode().isValid()) {
if (auto metaInfo = modelNode().metaInfo();
metaInfo.isValid() && metaInfo.hasProperty(name())
&& metaInfo.property(name()).propertyTypeNameIsUrl()) {
&& metaInfo.property(name()).propertyType().isUrl()) {
returnValue = returnValue.toUrl().toString();
}
}
@@ -106,7 +106,7 @@ static void fixAmbigousColorNames(const QmlDesigner::ModelNode &modelNode,
{
if (modelNode.isValid()) {
if (auto metaInfo = modelNode.metaInfo();
metaInfo.isValid() && metaInfo.property(name).propertyTypeNameIsColor()) {
metaInfo.isValid() && metaInfo.property(name).propertyType().isColor()) {
if ((value->type() == QVariant::Color)) {
QColor color = value->value<QColor>();
int alpha = color.alpha();
@@ -124,7 +124,7 @@ static void fixUrl(const QmlDesigner::ModelNode &modelNode, const QmlDesigner::P
{
if (modelNode.isValid()) {
if (auto metaInfo = modelNode.metaInfo();
metaInfo.isValid() && metaInfo.property(name).propertyTypeNameIsUrl())
metaInfo.isValid() && metaInfo.property(name).propertyType().isUrl())
if (!value->isValid())
*value = QStringLiteral("");
@@ -149,7 +149,7 @@ void PropertyEditorValue::setValueWithEmit(const QVariant &value)
if (modelNode().isValid()) {
if (auto metaInfo = modelNode().metaInfo();
metaInfo.isValid() && metaInfo.hasProperty(name())
&& metaInfo.property(name()).propertyTypeNameIsUrl()) {
&& metaInfo.property(name()).propertyType().isUrl()) {
newValue = QUrl(newValue.toString());
}
}
@@ -268,7 +268,7 @@ bool PropertyEditorValue::isTranslated() const
if (modelNode().isValid()) {
if (auto metaInfo = modelNode().metaInfo();
metaInfo.isValid() && metaInfo.hasProperty(name())
&& metaInfo.property(name()).propertyTypeNameIsString()) {
&& metaInfo.property(name()).propertyType().isString()) {
const QmlDesigner::QmlObjectNode objectNode(modelNode());
if (objectNode.isValid() && objectNode.hasBindingProperty(name())) {
const QRegularExpression rx(
@@ -438,7 +438,7 @@ QString PropertyEditorValue::getTranslationContext() const
if (modelNode().isValid()) {
if (auto metaInfo = modelNode().metaInfo();
metaInfo.isValid() && metaInfo.hasProperty(name())
&& metaInfo.property(name()).propertyTypeNameIsString()) {
&& metaInfo.property(name()).propertyType().isString()) {
const QmlDesigner::QmlObjectNode objectNode(modelNode());
if (objectNode.isValid() && objectNode.hasBindingProperty(name())) {
const QRegularExpression rx(QRegularExpression::anchoredPattern(
@@ -532,7 +532,7 @@ bool PropertyEditorValue::idListReplace(int idx, const QString &value)
void PropertyEditorValue::commitDrop(const QString &path)
{
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
QmlDesigner::NodeMetaInfo metaInfo = m_modelNode.view()->model()->metaInfo("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()
.metaInfo()
.property(m_editorValue->name())
.propertyTypeName();
.propertyType()
.typeName();
}
while (propertyType.contains('*')) //strip star
propertyType.chop(1);

View File

@@ -201,7 +201,7 @@ void PropertyEditorView::changeValue(const QString &name)
bool propertyTypeUrl = false;
if (metaInfo.isValid() && metaInfo.hasProperty(propertyName)
&& metaInfo.property(propertyName).propertyTypeNameIsUrl()) {
&& metaInfo.property(propertyName).propertyType().isUrl()) {
// turn absolute local file paths into relative paths
propertyTypeUrl = true;
QString filePath = castedValue.toUrl().toString();
@@ -272,13 +272,13 @@ void PropertyEditorView::changeExpression(const QString &propertyName)
if (auto metaInfo = qmlObjectNode->modelNode().metaInfo();
metaInfo.isValid() && metaInfo.hasProperty(name)) {
const auto &propertTypeName = metaInfo.property(name).propertyTypeName();
if (propertTypeName == "QColor") {
const auto &propertType = metaInfo.property(name).propertyType();
if (propertType.isColor()) {
if (QColor(value->expression().remove('"')).isValid()) {
qmlObjectNode->setVariantProperty(name, QColor(value->expression().remove('"')));
return;
}
} else if (propertTypeName == "bool") {
} else if (propertType.isBool()) {
if (isTrueFalseLiteral(value->expression())) {
if (value->expression().compare("true", Qt::CaseInsensitive) == 0)
qmlObjectNode->setVariantProperty(name, true);
@@ -286,21 +286,21 @@ void PropertyEditorView::changeExpression(const QString &propertyName)
qmlObjectNode->setVariantProperty(name, false);
return;
}
} else if (propertTypeName == "int") {
} else if (propertType.isInteger()) {
bool ok;
int intValue = value->expression().toInt(&ok);
if (ok) {
qmlObjectNode->setVariantProperty(name, intValue);
return;
}
} else if (propertTypeName == "qreal") {
} else if (propertType.isFloat()) {
bool ok;
qreal realValue = value->expression().toDouble(&ok);
if (ok) {
qmlObjectNode->setVariantProperty(name, realValue);
return;
}
} else if (propertTypeName == "QVariant") {
} else if (propertType.isVariant()) {
bool ok;
qreal realValue = value->expression().toDouble(&ok);
if (ok) {
@@ -464,7 +464,7 @@ void PropertyEditorView::setupQmlBackend()
TypeName diffClassName;
if (commonAncestor.isValid()) {
diffClassName = commonAncestor.typeName();
const QList<NodeMetaInfo> hierarchy = commonAncestor.classHierarchy();
const NodeMetaInfos hierarchy = commonAncestor.classHierarchy();
for (const NodeMetaInfo &metaInfo : hierarchy) {
if (PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsFile))
break;

View File

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

View File

@@ -40,11 +40,11 @@
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;
if (name == "QColor" || name == "color")
if (metaInfo.isColor())
return new ColorControl;
return nullptr;

View File

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

View File

@@ -235,11 +235,11 @@ TimelinePropertyItem *TimelinePropertyItem::create(const QmlTimelineKeyframeGrou
if (!objectNode.isValid())
return item;
auto nameOfType = objectNode.modelNode()
auto propertyType = objectNode.modelNode()
.metaInfo()
.property(item->m_frames.propertyName())
.propertyTypeName();
item->m_control = createTimelineControl(nameOfType);
.propertyType();
item->m_control = createTimelineControl(propertyType);
if (item->m_control) {
item->m_control->setSize((TimelineConstants::sectionWidth / 2.6) - 10,
item->size().height() - 2 + 1);

View File

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

View File

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

View File

@@ -29,6 +29,12 @@
#include "propertymetainfo.h"
#include "qmldesignercorelib_global.h"
#include <projectstorage/projectstoragefwd.h>
#include <projectstorage/projectstoragetypes.h>
#include <projectstorageids.h>
#include <utils/optional.h>
#include <QList>
#include <QString>
#include <QIcon>
@@ -48,17 +54,20 @@ class AbstractProperty;
class QMLDESIGNERCORE_EXPORT NodeMetaInfo
{
public:
NodeMetaInfo();
NodeMetaInfo(Model *model, const TypeName &type, int maj, int min);
NodeMetaInfo() = default;
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(const NodeMetaInfo &other);
NodeMetaInfo &operator=(const NodeMetaInfo &other);
bool isValid() const;
bool isFileComponent() const;
bool hasProperty(const PropertyName &propertyName) const;
bool hasProperty(Utils::SmallStringView propertyName) const;
PropertyMetaInfos properties() const;
PropertyMetaInfos localProperties() const;
PropertyMetaInfo property(const PropertyName &propertyName) const;
@@ -67,8 +76,8 @@ public:
PropertyName defaultPropertyName() const;
bool hasDefaultProperty() const;
QList<NodeMetaInfo> classHierarchy() const;
QList<NodeMetaInfo> superClasses() const;
std::vector<NodeMetaInfo> classHierarchy() const;
std::vector<NodeMetaInfo> superClasses() const;
NodeMetaInfo directSuperClass() const;
bool defaultPropertyIsComponent() const;
@@ -82,16 +91,43 @@ public:
bool availableInVersion(int majorVersion, int minorVersion) const;
bool isSubclassOf(const TypeName &type, int majorVersion = -1, int minorVersion = -1) const;
bool isSubclassOf(const NodeMetaInfo &metaInfo) const;
bool isGraphicalItem() const;
bool isQmlItem() const;
bool isLayoutable() const;
bool isView() 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;
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:
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;
};

View File

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

View File

@@ -27,6 +27,12 @@
#include <qmldesignercorelib_global.h>
#include <projectstorage/projectstoragefwd.h>
#include <projectstorage/projectstoragetypes.h>
#include <projectstorageids.h>
#include <utils/optional.h>
#include <QSharedPointer>
#include <QString>
@@ -34,45 +40,39 @@
namespace QmlDesigner {
class NodeMetaInfo;
class QMLDESIGNERCORE_EXPORT PropertyMetaInfo
{
public:
PropertyMetaInfo(QSharedPointer<class NodeMetaInfoPrivate> nodeMetaInfoPrivateData,
const PropertyName &propertyName);
PropertyMetaInfo(PropertyDeclarationId id,
NotNullPointer<const ProjectStorage<Sqlite::Database>> projectStorage)
: m_id{id}
, m_projectStorage{projectStorage}
{}
~PropertyMetaInfo();
const TypeName &propertyTypeName() const;
class NodeMetaInfo propertyNodeMetaInfo() const;
PropertyName name() const;
NodeMetaInfo propertyType() const;
bool isWritable() const;
bool isListProperty() const;
bool isEnumType() const;
bool isPrivate() const;
bool isPointer() const;
QVariant castedValue(const QVariant &value) const;
const PropertyName &name() const & { return m_propertyName; }
template<typename... TypeName>
bool hasPropertyTypeName(const TypeName &...typeName) const
{
auto propertyTypeName_ = propertyTypeName();
return ((propertyTypeName_ == typeName) || ...);
}
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:
const Storage::Info::PropertyDeclaration &propertyData() const;
TypeName propertyTypeName() const;
private:
QSharedPointer<class NodeMetaInfoPrivate> m_nodeMetaInfoPrivateData;
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>;

View File

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

View File

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

View File

@@ -29,8 +29,9 @@
#include "metainfo.h"
#include <enumeration.h>
#include <rewriterview.h>
#include <projectstorage/projectstorage.h>
#include <propertyparser.h>
#include <rewriterview.h>
#include <QDir>
#include <QDebug>
@@ -315,7 +316,7 @@ public:
m_context->viewerContext(), *m_context->snapshot().importDependencies()).toUtf8();
m_properties.append({propertyName, qualifiedTypeName});
} else {
TypeId typeId;
QmlJS::TypeId typeId;
TypeName typeName = typeId(value).toUtf8();
if (typeName == "Function")
@@ -1394,47 +1395,46 @@ void NodeMetaInfoPrivate::initialiseProperties()
m_slots = getSlots(m_objectValue, context());
}
NodeMetaInfo::NodeMetaInfo()
: m_privateData(QSharedPointer<NodeMetaInfoPrivate>::create())
{
}
NodeMetaInfo::NodeMetaInfo(Model *model, const TypeName &type, int maj, int min)
: m_privateData(NodeMetaInfoPrivate::create(model, type, maj, min))
{
}
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
{
return m_privateData->isValid();
if constexpr (useProjectStorage())
return bool(m_typeId);
else
return m_privateData && m_privateData->isValid();
}
bool NodeMetaInfo::isFileComponent() const
{
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
{
if constexpr (useProjectStorage())
return bool(m_projectStorage->propertyDeclarationId(m_typeId, propertyName));
else
return m_privateData->properties().contains(propertyName);
}
PropertyMetaInfos NodeMetaInfo::properties() const
{
if constexpr (useProjectStorage()) {
return Utils::transform<PropertyMetaInfos>(
m_projectStorage->propertyDeclarationIds(m_typeId), [&](auto id) {
return PropertyMetaInfo{id, m_projectStorage};
});
} else {
const auto &properties = m_privateData->properties();
PropertyMetaInfos propertyMetaInfos;
@@ -1445,9 +1445,16 @@ PropertyMetaInfos NodeMetaInfo::properties() const
return propertyMetaInfos;
}
}
PropertyMetaInfos NodeMetaInfo::localProperties() const
{
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;
@@ -1458,56 +1465,96 @@ PropertyMetaInfos NodeMetaInfo::localProperties() const
return propertyMetaInfos;
}
}
PropertyMetaInfo NodeMetaInfo::property(const PropertyName &propertyName) const
{
if constexpr (useProjectStorage()) {
return {m_projectStorage->propertyDeclarationId(m_typeId, propertyName), m_projectStorage};
} else {
return PropertyMetaInfo{m_privateData, propertyName};
}
}
PropertyNameList NodeMetaInfo::signalNames() const
{
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
{
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
{
if constexpr (useProjectStorage()) {
if (auto name = m_projectStorage->propertyName(typeData().defaultPropertyId))
return name->toQByteArray();
return {};
} else {
return m_privateData->defaultPropertyName();
}
}
bool NodeMetaInfo::hasDefaultProperty() const
{
if constexpr (useProjectStorage())
return bool(typeData().defaultPropertyId);
else
return !defaultPropertyName().isEmpty();
}
QList<NodeMetaInfo> NodeMetaInfo::classHierarchy() const
NodeMetaInfos NodeMetaInfo::classHierarchy() const
{
QList<NodeMetaInfo> hierarchy = {*this};
hierarchy.append(superClasses());
NodeMetaInfos hierarchy = {*this};
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;
}
QList<NodeMetaInfo> NodeMetaInfo::superClasses() const
NodeMetaInfos NodeMetaInfo::superClasses() const
{
NodeMetaInfos hierarchy;
Model *model = m_privateData->model();
return Utils::transform(m_privateData->prototypes(), [model](const TypeDescription &type) {
return NodeMetaInfo(model, type.className.toUtf8(), type.majorVersion, type.minorVersion);
});
for (const TypeDescription &type : m_privateData->prototypes())
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
{
if (hasDefaultProperty())
return property(defaultPropertyName()).hasPropertyTypeName("Component");
return property(defaultPropertyName()).propertyType().isQmlComponent();
return false;
}
@@ -1542,13 +1589,24 @@ QString NodeMetaInfo::importDirectoryPath() const
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
{
if (majorVersion == -1 && minorVersion == -1)
return true;
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
@@ -1572,7 +1630,7 @@ bool NodeMetaInfo::isSubclassOf(const TypeName &type, int majorVersion, int mino
stringIdentifier(type, majorVersion, minorVersion)))
return false; //take a shortcut - optimization
const QList<NodeMetaInfo> superClassList = superClasses();
const NodeMetaInfos superClassList = superClasses();
for (const NodeMetaInfo &superClass : superClassList) {
if (superClass.m_privateData->cleverCheckType(type)
&& superClass.availableInVersion(majorVersion, minorVersion)) {
@@ -1585,18 +1643,20 @@ bool NodeMetaInfo::isSubclassOf(const TypeName &type, int majorVersion, int mino
return false;
}
bool NodeMetaInfo::isSubclassOf(const NodeMetaInfo &metaInfo) const
{
return isSubclassOf(metaInfo.typeName(), metaInfo.majorVersion(), metaInfo.minorVersion());
}
bool NodeMetaInfo::isGraphicalItem() const
{
return isSubclassOf("QtQuick.Item")
|| isSubclassOf("QtQuick.Window.Window")
|| isSubclassOf("QtQuick.Dialogs.Dialog")
|| isSubclassOf("QtQuick.Controls.Popup");
return isSubclassOf("QtQuick.Item") || isSubclassOf("QtQuick.Window.Window")
|| isSubclassOf("QtQuick.Dialogs.Dialog") || isSubclassOf("QtQuick.Controls.Popup");
}
bool NodeMetaInfo::isQmlItem() const
{
return isSubclassOf("QtQuick.QtObject")
|| isSubclassOf("QtQml.QtObject");
return isSubclassOf("QtQuick.QtObject") || isSubclassOf("QtQml.QtObject");
}
bool NodeMetaInfo::isLayoutable() const
@@ -1604,17 +1664,15 @@ bool NodeMetaInfo::isLayoutable() const
if (isSubclassOf("<cpp>.QDeclarativeBasePositioner"))
return true; //QtQuick 1
return isSubclassOf("QtQuick.Positioner")
|| isSubclassOf("QtQuick.Layouts.Layout")
return isSubclassOf("QtQuick.Positioner") || isSubclassOf("QtQuick.Layouts.Layout")
|| isSubclassOf("QtQuick.Controls.SplitView");
}
bool NodeMetaInfo::isView() const
{
return isValid() &&
(isSubclassOf("QtQuick.ListView") ||
isSubclassOf("QtQuick.GridView") ||
isSubclassOf("QtQuick.PathView"));
return isValid()
&& (isSubclassOf("QtQuick.ListView") || isSubclassOf("QtQuick.GridView")
|| isSubclassOf("QtQuick.PathView"));
}
bool NodeMetaInfo::isTabView() const
@@ -1622,47 +1680,170 @@ bool NodeMetaInfo::isTabView() const
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,
const PropertyName &propertyName)
: m_nodeMetaInfoPrivateData{nodeMetaInfoPrivateData}
, 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
{
if constexpr (useProjectStorage())
return !(propertyData().traits & Storage::PropertyDeclarationTraits::IsReadOnly);
else
return m_nodeMetaInfoPrivateData->isPropertyWritable(m_propertyName);
}
bool PropertyMetaInfo::isListProperty() const
{
if constexpr (useProjectStorage())
return propertyData().traits & Storage::PropertyDeclarationTraits::IsList;
else
return m_nodeMetaInfoPrivateData->isPropertyList(m_propertyName);
}
bool PropertyMetaInfo::isEnumType() const
{
if constexpr (useProjectStorage())
return propertyType().isEnumeration();
else
return m_nodeMetaInfoPrivateData->isPropertyEnum(m_propertyName);
}
bool PropertyMetaInfo::isPrivate() const
{
if constexpr (useProjectStorage())
return propertyData().name.startsWith("__");
else
return m_propertyName.startsWith("__");
}
bool PropertyMetaInfo::isPointer() const
{
if constexpr (useProjectStorage())
return propertyData().traits & Storage::PropertyDeclarationTraits::IsPointer;
else
return m_nodeMetaInfoPrivateData->isPropertyPointer(m_propertyName);
}
@@ -1708,4 +1889,17 @@ QVariant PropertyMetaInfo::castedValue(const QVariant &value) const
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

View File

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

View File

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

View File

@@ -30,11 +30,7 @@
#include "model_p.h"
#include <modelnode.h>
#include <QFileInfo>
#include <QHashIterator>
#include <QPointer>
#include <utils/algorithm.h>
#include "abstractview.h"
#include "internalnodeabstractproperty.h"
@@ -57,6 +53,8 @@
#include "textmodifier.h"
#include "variantproperty.h"
#include <projectstorage/projectstorage.h>
#ifndef QMLDESIGNER_TEST
#include <qmldesignerplugin.h>
#include <viewmanager.h>
@@ -68,6 +66,9 @@
#include <utils/algorithm.h>
#include <QDrag>
#include <QFileInfo>
#include <QHashIterator>
#include <QPointer>
#include <QRegularExpression>
/*!
@@ -95,8 +96,8 @@ ModelPrivate::ModelPrivate(Model *model,
int major,
int minor,
Model *metaInfoProxyModel)
: m_model{model}
, m_projectStorage{&projectStorage}
: projectStorage{&projectStorage}
, m_model{model}
{
m_metaInfoProxyModel = metaInfoProxyModel;
@@ -1578,6 +1579,11 @@ void Model::endDrag()
d->notifyDragEnded();
}
NotNullPointer<const ProjectStorage<Sqlite::Database>> Model::projectStorage() const
{
return d->projectStorage;
}
QString Model::generateNewId(const QString &prefixName) const
{
return generateNewId(prefixName, QStringLiteral("element"));
@@ -1666,12 +1672,12 @@ void Model::setNodeInstanceView(NodeInstanceView *nodeInstanceView)
\brief Returns the model that is used for metainfo
\return Returns itself if other metaInfoProxyModel does not exist
*/
Model *Model::metaInfoProxyModel()
Model *Model::metaInfoProxyModel() const
{
if (d->m_metaInfoProxyModel)
return d->m_metaInfoProxyModel->metaInfoProxyModel();
return this;
return const_cast<Model *>(this);
}
TextModifier *Model::textModifier() const
@@ -1740,7 +1746,7 @@ const MetaInfo Model::metaInfo() const
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();
}
@@ -1750,10 +1756,34 @@ void Model::setMetaInfo(const MetaInfo &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)
{
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);
}
}
/*!
\brief Returns list of QML types available within the model.

View File

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

View File

@@ -870,7 +870,17 @@ NodeMetaInfo ModelNode::metaInfo() const
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
@@ -948,20 +958,23 @@ bool ModelNode::hasNodeAbstractProperty(const PropertyName &name) const
bool ModelNode::hasDefaultNodeAbstractProperty() const
{
return hasProperty(metaInfo().defaultPropertyName())
&& m_internalNode->property(metaInfo().defaultPropertyName())->isNodeAbstractProperty();
auto defaultPropertyName = metaInfo().defaultPropertyName();
return hasProperty(defaultPropertyName)
&& m_internalNode->property(defaultPropertyName)->isNodeAbstractProperty();
}
bool ModelNode::hasDefaultNodeListProperty() const
{
return hasProperty(metaInfo().defaultPropertyName())
&& m_internalNode->property(metaInfo().defaultPropertyName())->isNodeListProperty();
auto defaultPropertyName = metaInfo().defaultPropertyName();
return hasProperty(defaultPropertyName)
&& m_internalNode->property(defaultPropertyName)->isNodeListProperty();
}
bool ModelNode::hasDefaultNodeProperty() const
{
return hasProperty(metaInfo().defaultPropertyName())
&& m_internalNode->property(metaInfo().defaultPropertyName())->isNodeProperty();
auto defaultPropertyName = metaInfo().defaultPropertyName();
return hasProperty(defaultPropertyName)
&& m_internalNode->property(defaultPropertyName)->isNodeProperty();
}
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
{
if (modelNode().metaInfo().isValid() && modelNode().metaInfo().hasProperty(name)
&& modelNode().metaInfo().property(name).propertyTypeNameIsString()) {
&& modelNode().metaInfo().property(name).propertyType().isString()) {
if (modelNode().hasBindingProperty(name)) {
static QRegularExpression regularExpressionPattern(
QLatin1String("^qsTr(|Id|anslate)\\(\".*\"\\)$"));

View File

@@ -206,21 +206,16 @@ QVariant QmlTimelineKeyframeGroup::value(qreal frame) const
return QVariant();
}
TypeName QmlTimelineKeyframeGroup::valueType() const
NodeMetaInfo QmlTimelineKeyframeGroup::valueType() const
{
QTC_ASSERT(isValid(), return {});
const ModelNode targetNode = target();
TypeName typeName;
if (targetNode.isValid() && targetNode.hasMetaInfo())
typeName = targetNode.metaInfo().property(propertyName()).propertyTypeName();
return targetNode.metaInfo().property(propertyName()).propertyType();
if (typeName.startsWith("<cpp>."))
typeName.remove(0, 6);
return typeName;
return {};
}
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 property.parentModelNode().isValid()
&& isComponentType(
property.parentModelNode().metaInfo().property(property.name()).propertyTypeName());
&& property.parentModelNode().metaInfo().property(property.name()).propertyType().isQmlComponent();
}
QString extractComponentFromQml(const QString &source)

View File

@@ -184,7 +184,7 @@ public:
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>(
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 "projectstorageids.h"
#include "projectstorageinfotypes.h"
#include <utils/smallstring.h>
@@ -34,54 +35,6 @@
#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));
}
using TypeNameString = Utils::BasicSmallString<63>;
} // namespace QmlDesigner::Storage
namespace QmlDesigner::Storage::Synchronization {
enum class TypeNameKind { Exported = 1, QualifiedExported = 2 };
@@ -912,37 +865,3 @@ public:
} // 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 "qmldocumentparserinterface.h"
namespace Sqlite {
class Database;
}
#include <projectstoragefwd.h>
namespace QmlDesigner {
template<typename Database>
class ProjectStorage;
template<typename ProjectStorage, typename Mutex>
class SourcePathCache;

View File

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

View File

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

View File

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

View File

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

View File

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