QmlDesigner: Implement new asset drags

Drag image to existing image/texture type - Update source property.
Drag image containing multiple frames - Create AnimatedImage.
Drag sound - Create new SoundEffect or update an existing one.
Drag shader - Create new Shader or update an existing one.
Drag font - Create new Text or update font on an existing one.

Fixes: QDS-3389
Change-Id: I62cf964bbba7772ecbf6f1c6fadb0f9e41a86206
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Miikka Heikkinen
2020-12-23 14:58:58 +02:00
parent 178ba90376
commit 1547929037
10 changed files with 352 additions and 37 deletions

View File

@@ -234,8 +234,9 @@ void AbstractFormEditorTool::dropEvent(const QList<QGraphicsItem*> &/*itemList*/
void AbstractFormEditorTool::dragEnterEvent(const QList<QGraphicsItem*> &itemList, QGraphicsSceneDragDropEvent *event)
{
if (event->mimeData()->hasFormat(QLatin1String("application/vnd.bauhaus.itemlibraryinfo")) ||
event->mimeData()->hasFormat(QLatin1String("application/vnd.bauhaus.libraryresource"))) {
if (event->mimeData()->hasFormat(QLatin1String("application/vnd.bauhaus.itemlibraryinfo"))
|| event->mimeData()->hasFormat(QLatin1String("application/vnd.bauhaus.libraryresource.image"))
|| event->mimeData()->hasFormat(QLatin1String("application/vnd.bauhaus.libraryresource.font"))) {
event->accept();
view()->changeToDragTool();
view()->currentTool()->dragEnterEvent(itemList, event);

View File

@@ -136,6 +136,26 @@ void DragTool::createQmlItemNodeFromImage(const QString &imageName,
}
}
void DragTool::createQmlItemNodeFromFont(const QString &fontFamily,
const QmlItemNode &parentNode,
const QPointF &scenePos)
{
if (parentNode.isValid()) {
MetaInfo metaInfo = MetaInfo::global();
FormEditorItem *parentItem = scene()->itemForQmlItemNode(parentNode);
QPointF positonInItemSpace = parentItem->qmlItemNode().instanceSceneContentItemTransform()
.inverted().map(scenePos);
m_dragNode = QmlItemNode::createQmlItemNodeFromFont(view(), fontFamily, positonInItemSpace,
parentNode);
QList<QmlItemNode> nodeList;
nodeList.append(m_dragNode);
m_selectionIndicator.setItems(scene()->itemsForQmlItemNodes(nodeList));
}
}
FormEditorItem *DragTool::targetContainerOrRootItem(const QList<QGraphicsItem *> &itemList, FormEditorItem *currentItem)
{
FormEditorItem *formEditorItem = containerFormEditorItem(itemList, {currentItem});
@@ -208,25 +228,29 @@ static bool canBeDropped(const QMimeData *mimeData)
return NodeHints::fromItemLibraryEntry(itemLibraryEntryFromMimeData(mimeData)).canBeDroppedInFormEditor();
}
static bool canHandleMimeData(const QMimeData *mimeData)
{
return mimeData->hasFormat(QStringLiteral("application/vnd.bauhaus.itemlibraryinfo"))
|| mimeData->hasFormat(QStringLiteral("application/vnd.bauhaus.libraryresource"));
}
static bool dragAndDropPossible(const QMimeData *mimeData)
{
return canHandleMimeData(mimeData) && canBeDropped(mimeData);
}
static bool hasItemLibraryInfo(const QMimeData *mimeData)
{
return mimeData->hasFormat(QStringLiteral("application/vnd.bauhaus.itemlibraryinfo"));
}
static bool hasLibraryResources(const QMimeData *mimeData)
static bool hasImageResource(const QMimeData *mimeData)
{
return mimeData->hasFormat(QStringLiteral("application/vnd.bauhaus.libraryresource"));
return mimeData->hasFormat(QStringLiteral("application/vnd.bauhaus.libraryresource.image"));
}
static bool hasFontResource(const QMimeData *mimeData)
{
return mimeData->hasFormat(QStringLiteral("application/vnd.bauhaus.libraryresource.font"));
}
static bool canHandleMimeData(const QMimeData *mimeData)
{
return hasItemLibraryInfo(mimeData) || hasImageResource(mimeData) || hasFontResource(mimeData);
}
static bool dragAndDropPossible(const QMimeData *mimeData)
{
return canHandleMimeData(mimeData) && canBeDropped(mimeData);
}
void DragTool::dropEvent(const QList<QGraphicsItem *> &/*itemList*/, QGraphicsSceneDragDropEvent *event)
@@ -290,11 +314,16 @@ void DragTool::dragLeaveEvent(const QList<QGraphicsItem *> &/*itemList*/, QGraph
view()->changeToSelectionTool();
}
static QString libraryResourceImageName(const QMimeData *mimeData)
static QString libraryResourceFile(const QMimeData *mimeData)
{
return QString::fromUtf8((mimeData->data(QStringLiteral("application/vnd.bauhaus.libraryresource"))));
}
static QString libraryResourceFont(const QMimeData *mimeData)
{
return QString::fromUtf8((mimeData->data(QStringLiteral("application/vnd.bauhaus.libraryresource.font"))));
}
void DragTool::createDragNode(const QMimeData *mimeData, const QPointF &scenePosition, const QList<QGraphicsItem *> &itemList)
{
if (!m_dragNode.hasModelNode()) {
@@ -306,8 +335,10 @@ void DragTool::createDragNode(const QMimeData *mimeData, const QPointF &scenePos
if (hasItemLibraryInfo(mimeData))
createQmlItemNode(itemLibraryEntryFromMimeData(mimeData), targetContainerQmlItemNode, scenePosition);
else if (hasLibraryResources(mimeData))
createQmlItemNodeFromImage(libraryResourceImageName(mimeData), targetContainerQmlItemNode, scenePosition);
else if (hasImageResource(mimeData))
createQmlItemNodeFromImage(libraryResourceFile(mimeData), targetContainerQmlItemNode, scenePosition);
else if (hasFontResource(mimeData))
createQmlItemNodeFromFont(libraryResourceFont(mimeData), targetContainerQmlItemNode, scenePosition);
m_blockMove = true;
m_startPoint = scenePosition;

View File

@@ -81,6 +81,7 @@ protected:
void abort();
void createQmlItemNode(const ItemLibraryEntry &itemLibraryEntry, const QmlItemNode &parentNode, const QPointF &scenePos);
void createQmlItemNodeFromImage(const QString &imageName, const QmlItemNode &parentNode, const QPointF &scenePos);
void createQmlItemNodeFromFont(const QString &fontFamily, const QmlItemNode &parentNode, const QPointF &scenePos);
FormEditorItem *targetContainerOrRootItem(const QList<QGraphicsItem*> &itemList, FormEditorItem *urrentItem = nullptr);
void begin(QPointF scenePos);
void end();

View File

@@ -53,6 +53,12 @@ static const QStringList &supportedImageSuffixes()
return retList;
}
static const QStringList &supportedFragmentShaderSuffixes()
{
static const QStringList retList {"frag", "glsl", "glslf", "fsh"};
return retList;
}
static const QStringList &supportedShaderSuffixes()
{
static const QStringList retList {"frag", "vert",
@@ -131,6 +137,14 @@ static QPixmap generateFontImage(const QFileInfo &info, const QSize &size)
return fontImageCache[key];
}
QString fontFamily(const QFileInfo &info)
{
QRawFont font(info.absoluteFilePath(), 10);
if (font.isValid())
return font.familyName();
return {};
}
class ItemLibraryFileIconProvider : public QFileIconProvider
{
public:
@@ -147,7 +161,7 @@ public:
if (supportedImageSuffixes().contains(suffix))
pixmap.load(info.absoluteFilePath());
else if (supportedFontSuffixes().contains(suffix))
else if (supportedFontSuffixes().contains(suffix))
pixmap = generateFontImage(info, iconSize);
if (pixmap.isNull())
@@ -162,8 +176,8 @@ public:
return icon;
}
// Generated icon sizes should match ItemLibraryResourceView icon sizes
QList<QSize> iconSizes = {{192, 192}, {96, 96}, {48, 48}, {32, 32}};
// Generated icon sizes should match ItemLibraryResourceView needed icon sizes
QList<QSize> iconSizes = {{192, 192}, {128, 128}, {96, 96}, {48, 48}, {32, 32}};
};
@@ -274,6 +288,29 @@ void CustomFileSystemModel::setSearchFilter(const QString &nameFilterList)
setRootPath(m_fileSystemModel->rootPath());
}
QPair<QString, QByteArray> CustomFileSystemModel::resourceTypeAndData(const QModelIndex &index) const
{
QFileInfo fi = fileInfo(index);
QString suffix = fi.suffix();
if (!suffix.isEmpty()) {
if (supportedImageSuffixes().contains(suffix)) {
// Data: Image format (suffix)
return {"application/vnd.bauhaus.libraryresource.image", suffix.toUtf8()};
} else if (supportedFontSuffixes().contains(suffix)) {
// Data: Font family name
return {"application/vnd.bauhaus.libraryresource.font", fontFamily(fi).toUtf8()};
} else if (supportedShaderSuffixes().contains(suffix)) {
// Data: shader type, frament (f) or vertex (v)
return {"application/vnd.bauhaus.libraryresource.shader",
supportedFragmentShaderSuffixes().contains(suffix) ? "f" : "v"};
} else if (supportedAudioSuffixes().contains(suffix)) {
// No extra data for sounds
return {"application/vnd.bauhaus.libraryresource.sound", {}};
}
}
return {};
}
void CustomFileSystemModel::appendIfNotFiltered(const QString &file)
{
if (filterMetaIcons(file))

View File

@@ -27,6 +27,7 @@
#include <QAbstractTableModel>
#include <QDir>
#include <QPair>
QT_BEGIN_NAMESPACE
class QFileIconProvider;
@@ -60,6 +61,8 @@ public:
Qt::ItemFlags flags(const QModelIndex &index) const override;
void setSearchFilter(const QString &nameFilterList);
QPair<QString, QByteArray> resourceTypeAndData(const QModelIndex &index) const;
private:
QModelIndex updatePath(const QString &newPath);
QModelIndex fileSystemModelIndex(const QModelIndex &index) const;

View File

@@ -108,23 +108,32 @@ void ItemLibraryResourceView::startDrag(Qt::DropActions /* supportedActions */)
{
if (debug)
qDebug() << Q_FUNC_INFO;
QMimeData *mimeData = model()->mimeData(selectedIndexes());
if (!mimeData)
const auto indexes = selectedIndexes();
if (indexes.isEmpty())
return;
const QModelIndex &index = indexes.constFirst();
if (!index.isValid())
return;
auto fileSystemModel = qobject_cast<CustomFileSystemModel*>(model());
Q_ASSERT(fileSystemModel);
QFileInfo fileInfo = fileSystemModel->fileInfo(selectedIndexes().constFirst());
QPixmap pixmap(fileInfo.absoluteFilePath());
if (!pixmap.isNull()) {
auto drag = new QDrag(this);
drag->setPixmap(QIcon(pixmap).pixmap(128, 128));
auto mimeData = new QMimeData;
mimeData->setData(QLatin1String("application/vnd.bauhaus.libraryresource"), fileInfo.absoluteFilePath().toUtf8());
drag->setMimeData(mimeData);
drag->exec();
}
QPair<QString, QByteArray> typeAndData = fileSystemModel->resourceTypeAndData(index);
if (typeAndData.first.isEmpty())
return;
QFileInfo fileInfo = fileSystemModel->fileInfo(index);
auto drag = new QDrag(this);
drag->setPixmap(fileSystemModel->fileIcon(index).pixmap(128, 128));
QMimeData *mimeData = new QMimeData;
mimeData->setData(QLatin1String("application/vnd.bauhaus.libraryresource"),
fileInfo.absoluteFilePath().toUtf8());
mimeData->setData(typeAndData.first, typeAndData.second);
drag->setMimeData(mimeData);
drag->exec();
}
} // namespace QmlDesigner

View File

@@ -41,6 +41,7 @@
#include <rewritingexception.h>
#include <qmlitemnode.h>
#include <designeractionmanager.h>
#include <import.h>
#include <coreplugin/icore.h>
@@ -498,8 +499,14 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData,
if (dropModelIndex.model() == this) {
if (mimeData->hasFormat("application/vnd.bauhaus.itemlibraryinfo")) {
handleItemLibraryItemDrop(mimeData, rowNumber, dropModelIndex);
} else if (mimeData->hasFormat("application/vnd.bauhaus.libraryresource")) {
} else if (mimeData->hasFormat("application/vnd.bauhaus.libraryresource.image")) {
handleItemLibraryImageDrop(mimeData, rowNumber, dropModelIndex);
} else if (mimeData->hasFormat("application/vnd.bauhaus.libraryresource.font")) {
handleItemLibraryFontDrop(mimeData, rowNumber, dropModelIndex);
} else if (mimeData->hasFormat("application/vnd.bauhaus.libraryresource.shader")) {
handleItemLibraryShaderDrop(mimeData, rowNumber, dropModelIndex);
} else if (mimeData->hasFormat("application/vnd.bauhaus.libraryresource.sound")) {
handleItemLibrarySoundDrop(mimeData, rowNumber, dropModelIndex);
} else if (mimeData->hasFormat("application/vnd.modelnode.list")) {
handleInternalDrop(mimeData, rowNumber, dropModelIndex);
}
@@ -772,8 +779,10 @@ void NavigatorTreeModel::handleItemLibraryImageDrop(const QMimeData *mimeData, i
targetNode.bindingProperty("texture").setExpression(newModelNode.validId());
}
});
} else if (targetNode.isSubclassOf("QtQuick3D.Texture")) {
// if dropping an image on a texture, set the texture source
} else if (targetNode.isSubclassOf("QtQuick3D.Texture")
|| targetNode.isSubclassOf("QtQuick.Image")
|| targetNode.isSubclassOf("QtQuick.BorderImage")) {
// if dropping an image on an existing texture or image, set the source
targetNode.variantProperty("source").setValue(imagePath);
} else {
m_view->executeInTransaction("NavigatorTreeModel::handleItemLibraryImageDrop", [&] {
@@ -793,6 +802,162 @@ void NavigatorTreeModel::handleItemLibraryImageDrop(const QMimeData *mimeData, i
}
}
void NavigatorTreeModel::handleItemLibraryFontDrop(const QMimeData *mimeData, int rowNumber,
const QModelIndex &dropModelIndex)
{
QTC_ASSERT(m_view, return);
const QModelIndex rowModelIndex = dropModelIndex.sibling(dropModelIndex.row(), 0);
int targetRowNumber = rowNumber;
NodeAbstractProperty targetProperty;
bool foundTarget = findTargetProperty(rowModelIndex, this, &targetProperty, &targetRowNumber);
if (foundTarget) {
ModelNode targetNode(modelNodeForIndex(rowModelIndex));
const QString fontFamily = QString::fromUtf8(
mimeData->data("application/vnd.bauhaus.libraryresource.font"));
ModelNode newModelNode;
m_view->executeInTransaction("NavigatorTreeModel::handleItemLibraryFontDrop", [&] {
if (targetNode.isSubclassOf("QtQuick.Text")) {
// if dropping into an existing Text, update font
targetNode.variantProperty("font.family").setValue(fontFamily);
} else {
// create a Text node
QmlItemNode newItemNode = QmlItemNode::createQmlItemNodeFromFont(
m_view, fontFamily, QPointF(), targetProperty, false);
if (NodeHints::fromModelNode(targetProperty.parentModelNode()).canBeContainerFor(newItemNode.modelNode()))
newModelNode = newItemNode.modelNode();
else
newItemNode.destroy();
}
});
if (newModelNode.isValid()) {
moveNodesInteractive(targetProperty, {newModelNode}, targetRowNumber);
m_view->setSelectedModelNode(newModelNode);
}
}
}
void NavigatorTreeModel::handleItemLibraryShaderDrop(const QMimeData *mimeData, int rowNumber,
const QModelIndex &dropModelIndex)
{
QTC_ASSERT(m_view, return);
Import import = Import::createLibraryImport(QStringLiteral("QtQuick3D"));
if (!m_view->model()->hasImport(import, true, true))
return;
const QModelIndex rowModelIndex = dropModelIndex.sibling(dropModelIndex.row(), 0);
int targetRowNumber = rowNumber;
NodeAbstractProperty targetProperty;
bool foundTarget = findTargetProperty(rowModelIndex, this, &targetProperty, &targetRowNumber);
if (foundTarget) {
ModelNode targetNode(modelNodeForIndex(rowModelIndex));
ModelNode newModelNode;
const QString shaderSource = QString::fromUtf8(mimeData->data("application/vnd.bauhaus.libraryresource"));
const bool fragShader = mimeData->data("application/vnd.bauhaus.libraryresource.shader").startsWith('f');
const QString relPath = DocumentManager::currentFilePath().toFileInfo().dir().relativeFilePath(shaderSource);
m_view->executeInTransaction("NavigatorTreeModel::handleItemLibraryShaderDrop", [&] {
if (targetNode.isSubclassOf("QtQuick3D.Shader")) {
// if dropping into an existing Shader, update
if (fragShader)
targetNode.variantProperty("stage").setEnumeration("Shader.Fragment");
else
targetNode.variantProperty("stage").setEnumeration("Shader.Vertex");
targetNode.variantProperty("shader").setValue(relPath);
} else {
// create a new Shader
ItemLibraryEntry itemLibraryEntry;
itemLibraryEntry.setName("Shader");
itemLibraryEntry.setType("QtQuick3D.Shader", 1, 0);
// set shader properties
PropertyName prop = "shader";
QString type = "QByteArray";
QVariant val = relPath;
itemLibraryEntry.addProperty(prop, type, val);
prop = "stage";
type = "enum";
val = fragShader ? "Shader.Fragment" : "Shader.Vertex";
itemLibraryEntry.addProperty(prop, type, val);
// create a texture
newModelNode = QmlItemNode::createQmlObjectNode(m_view, itemLibraryEntry, {},
targetProperty, false);
// Rename the node based on shader source
QFileInfo fi(relPath);
newModelNode.setIdWithoutRefactoring(m_view->generateNewId(fi.baseName(),
"shader"));
}
});
if (newModelNode.isValid()) {
moveNodesInteractive(targetProperty, {newModelNode}, targetRowNumber);
m_view->setSelectedModelNode(newModelNode);
}
}
}
void NavigatorTreeModel::handleItemLibrarySoundDrop(const QMimeData *mimeData, int rowNumber,
const QModelIndex &dropModelIndex)
{
QTC_ASSERT(m_view, return);
Import import = Import::createLibraryImport(QStringLiteral("QtMultimedia"));
if (!m_view->model()->hasImport(import, true, true))
return;
const QModelIndex rowModelIndex = dropModelIndex.sibling(dropModelIndex.row(), 0);
int targetRowNumber = rowNumber;
NodeAbstractProperty targetProperty;
bool foundTarget = findTargetProperty(rowModelIndex, this, &targetProperty, &targetRowNumber);
if (foundTarget) {
ModelNode targetNode(modelNodeForIndex(rowModelIndex));
ModelNode newModelNode;
const QString soundSource = QString::fromUtf8(mimeData->data("application/vnd.bauhaus.libraryresource"));
const QString relPath = DocumentManager::currentFilePath().toFileInfo().dir().relativeFilePath(soundSource);
m_view->executeInTransaction("NavigatorTreeModel::handleItemLibrarySoundDrop", [&] {
if (targetNode.isSubclassOf("QtMultimedia.SoundEffect")) {
// if dropping into on an existing SoundEffect, update
targetNode.variantProperty("source").setValue(relPath);
} else {
// create a new SoundEffect
ItemLibraryEntry itemLibraryEntry;
itemLibraryEntry.setName("SoundEffect");
itemLibraryEntry.setType("QtMultimedia.SoundEffect", 1, 0);
// set shader properties
PropertyName prop = "source";
QString type = "QUrl";
QVariant val = relPath;
itemLibraryEntry.addProperty(prop, type, val);
// create a texture
newModelNode = QmlItemNode::createQmlObjectNode(m_view, itemLibraryEntry, {},
targetProperty, false);
// Rename the node based on source
QFileInfo fi(relPath);
newModelNode.setIdWithoutRefactoring(m_view->generateNewId(fi.baseName(),
"soundEffect"));
}
});
if (newModelNode.isValid()) {
moveNodesInteractive(targetProperty, {newModelNode}, targetRowNumber);
m_view->setSelectedModelNode(newModelNode);
}
}
}
TypeName propertyType(const NodeAbstractProperty &property)
{
return property.parentModelNode().metaInfo().propertyTypeName(property.name());

View File

@@ -115,6 +115,9 @@ private:
void handleInternalDrop(const QMimeData *mimeData, int rowNumber, const QModelIndex &dropModelIndex);
void handleItemLibraryItemDrop(const QMimeData *mimeData, int rowNumber, const QModelIndex &dropModelIndex);
void handleItemLibraryImageDrop(const QMimeData *mimeData, int rowNumber, const QModelIndex &dropModelIndex);
void handleItemLibraryFontDrop(const QMimeData *mimeData, int rowNumber, const QModelIndex &dropModelIndex);
void handleItemLibraryShaderDrop(const QMimeData *mimeData, int rowNumber, const QModelIndex &dropModelIndex);
void handleItemLibrarySoundDrop(const QMimeData *mimeData, int rowNumber, const QModelIndex &dropModelIndex);
QList<QPersistentModelIndex> nodesToPersistentIndex(const QList<ModelNode> &modelNodes);
QPointer<NavigatorView> m_view;

View File

@@ -69,6 +69,17 @@ public:
NodeAbstractProperty parentproperty,
bool executeInTransaction = true);
static QmlItemNode createQmlItemNodeFromFont(AbstractView *view,
const QString &fontFamily,
const QPointF &position,
QmlItemNode parentQmlItemNode,
bool executeInTransaction = true);
static QmlItemNode createQmlItemNodeFromFont(AbstractView *view,
const QString &fontFamily,
const QPointF &position,
NodeAbstractProperty parentproperty,
bool executeInTransaction = true);
QList<QmlItemNode> children() const;
QList<QmlObjectNode> resources() const;
QList<QmlObjectNode> allDirectSubNodes() const;

View File

@@ -43,6 +43,7 @@
#include <QPlainTextEdit>
#include <QFileInfo>
#include <QDir>
#include <QImageReader>
#include <utils/qtcassert.h>
@@ -106,7 +107,12 @@ QmlItemNode QmlItemNode::createQmlItemNodeFromImage(AbstractView *view, const QS
propertyPairList.append({PropertyName("source"), QVariant(relativeImageName)});
}
newQmlItemNode = QmlItemNode(view->createModelNode("QtQuick.Image", metaInfo.majorVersion(), metaInfo.minorVersion(), propertyPairList));
TypeName type("QtQuick.Image");
QImageReader reader(imageName);
if (reader.supportsAnimation())
type = "QtQuick.AnimatedImage";
newQmlItemNode = QmlItemNode(view->createModelNode(type, metaInfo.majorVersion(), metaInfo.minorVersion(), propertyPairList));
parentproperty.reparentHere(newQmlItemNode);
QFileInfo fi(relativeImageName);
@@ -125,6 +131,54 @@ QmlItemNode QmlItemNode::createQmlItemNodeFromImage(AbstractView *view, const QS
return newQmlItemNode;
}
QmlItemNode QmlItemNode::createQmlItemNodeFromFont(AbstractView *view,
const QString &fontFamily,
const QPointF &position,
QmlItemNode parentQmlItemNode,
bool executeInTransaction)
{
if (!parentQmlItemNode.isValid())
parentQmlItemNode = QmlItemNode(view->rootModelNode());
NodeAbstractProperty parentProperty = parentQmlItemNode.defaultNodeAbstractProperty();
return QmlItemNode::createQmlItemNodeFromFont(view, fontFamily, position,
parentProperty, executeInTransaction);
}
QmlItemNode QmlItemNode::createQmlItemNodeFromFont(AbstractView *view,
const QString &fontFamily,
const QPointF &position,
NodeAbstractProperty parentproperty,
bool executeInTransaction)
{
QmlItemNode newQmlItemNode;
auto doCreateQmlItemNodeFromFont = [=, &newQmlItemNode, &parentproperty]() {
NodeMetaInfo metaInfo = view->model()->metaInfo("QtQuick.Text");
QList<QPair<PropertyName, QVariant>> propertyPairList;
propertyPairList.append({PropertyName("x"), QVariant(qRound(position.x()))});
propertyPairList.append({PropertyName("y"), QVariant(qRound(position.y()))});
propertyPairList.append({PropertyName("font.family"), QVariant(fontFamily)});
propertyPairList.append({PropertyName("text"), QVariant(fontFamily)});
newQmlItemNode = QmlItemNode(view->createModelNode("QtQuick.Text", metaInfo.majorVersion(),
metaInfo.minorVersion(), propertyPairList));
parentproperty.reparentHere(newQmlItemNode);
newQmlItemNode.setId(view->generateNewId("text", "text"));
Q_ASSERT(newQmlItemNode.isValid());
};
if (executeInTransaction)
view->executeInTransaction("QmlItemNode::createQmlItemNodeFromImage", doCreateQmlItemNodeFromFont);
else
doCreateQmlItemNodeFromFont();
return newQmlItemNode;
}
bool QmlItemNode::isValid() const
{
return isValidQmlItemNode(modelNode());