示例#1
0
void TestPropertyEditor::createSubNode()
{
    std::auto_ptr<QWidget> widget(new QWidget());

    QScopedPointer<Model> model(Model::create("import Qt 4.6\n Item {}"));
    QVERIFY(model.data());

    QScopedPointer<TestView> view(new TestView);
    QVERIFY(view.data());
    model->attachView(view.data());

    setupPropertyEditor(widget.get(), model.data());
    QVERIFY(view->rootModelNode().isValid());
    selectThrough(view->rootModelNode());

    ModelNode childNode = view->createModelNode("Qt/Rectangle", 4, 6);
    view->rootModelNode().nodeListProperty("data").reparentHere(childNode);

    QVERIFY(childNode.isValid());
    QVERIFY(view->rootModelNode().allDirectSubModelNodes().contains(childNode));
    QVERIFY(childNode.parentProperty().parentModelNode() == view->rootModelNode());
    QCOMPARE(childNode.type(), QString("Qt/Rectangle"));

    selectThrough(childNode);

    QVERIFY(childNode.id().isEmpty());

    childNode.setId("Blah");
    QCOMPARE(childNode.id(), QString("Blah"));


    QCOMPARE(childNode.id(), QString("Blah"));
}
示例#2
0
void ComponentView::searchForComponentAndAddToList(const ModelNode &node)
{
    QList<ModelNode> nodeList;
    nodeList.append(node);
    nodeList.append(node.allSubModelNodes());


    foreach (const ModelNode &node, nodeList) {
        if (node.nodeSourceType() == ModelNode::ComponentSource) {
            if (!node.id().isEmpty()) {
                QStandardItem *item = new QStandardItem(node.id());
                item->setData(QVariant::fromValue(node), ModelNodeRole);
                item->setEditable(false);
                removeSingleNodeFromList(node); //remove node if already present
                m_standardItemModel->appendRow(item);
            } else {
                QString description;
                ModelNode parentNode = node.parentProperty().parentModelNode();
                if (parentNode.isValid())
                    if (!parentNode.id().isEmpty())
                        description = node.parentProperty().parentModelNode().id() + QLatin1Char(' ');
                    else
                        description = node.parentProperty().parentModelNode().simplifiedTypeName() + QLatin1Char(' ');
                description += node.parentProperty().name();
                QStandardItem *item = new QStandardItem(description);
                item->setData(QVariant::fromValue(node), ModelNodeRole);
                item->setEditable(false);
                removeSingleNodeFromList(node); //remove node if already present
                m_standardItemModel->appendRow(item);
            }
        }
    }
}
示例#3
0
/*!
    Returns the node instance for \a node, which must be valid.

    Returns an invalid node instance if no node instance for this model node
    exists.

    \sa NodeInstance
*/
NodeInstance NodeInstanceView::instanceForModelNode(const ModelNode &node) const
{
    Q_ASSERT(node.isValid());
    Q_ASSERT(m_nodeInstanceHash.contains(node));
    Q_ASSERT(m_nodeInstanceHash.value(node).modelNode() == node);
    return m_nodeInstanceHash.value(node);
}
示例#4
0
void QmlDesignerPlugin::selectModelNodeUnderTextCursor()
{
    const int cursorPos = currentDesignDocument()->plainTextEdit()->textCursor().position();
    ModelNode node = currentDesignDocument()->rewriterView()->nodeAtTextCursorPosition(cursorPos);
    if (currentDesignDocument()->rewriterView() && node.isValid())
        currentDesignDocument()->rewriterView()->setSelectedModelNodes(QList<ModelNode>() << node);
}
void GradientLineQmlAdaptor::setupGradient()
{
    if (!active())
        return;

    ModelNode modelNode = m_itemNode.modelNode();
    QLinearGradient newGradient;
    QVector<QGradientStop> stops;

    if (!modelNode.isValid())
        return;

    if (modelNode.hasBindingProperty(gradientName()))
        return;

    if (modelNode.hasProperty(gradientName())) { //gradient exists

        ModelNode gradientNode = modelNode.nodeProperty(gradientName()).modelNode();
        QList<ModelNode> stopList = gradientNode.nodeListProperty("stops").toModelNodeList();

        foreach (const ModelNode &stopNode, stopList) {
            QmlObjectNode stopObjectNode = stopNode;
            if (stopObjectNode.isValid()) {
                qreal position = stopObjectNode.modelValue("position").toReal();
                QColor color = stopObjectNode.modelValue("color").value<QColor>();
                stops.append( QPair<qreal, QColor>(position, color));
            }
        }
示例#6
0
void ModelToTextMerger::nodeSlidAround(const ModelNode &movingNode, const ModelNode &inFrontOfNode)
{
    if (!inFrontOfNode.isValid() || movingNode.parentProperty() == inFrontOfNode.parentProperty())
        schedule(new MoveNodeRewriteAction(movingNode, inFrontOfNode));
    else
        Q_ASSERT(!"Nodes do not belong to the same containing property");
}
示例#7
0
static ModelNode resolveBinding(const QString &binding, ModelNode currentNode, AbstractView* view)
{
    int i = 0;
    QString element = binding.split(QLatin1Char('.')).at(0);
    while (!element.isEmpty())
    {
        if (element == "parent") {
            if (currentNode.hasParentProperty())
                currentNode = currentNode.parentProperty().toNodeAbstractProperty().parentModelNode();
            else
                return ModelNode(); //binding not valid
        } else if (currentNode.hasProperty(element)) {
            if (currentNode.property(element).isNodeProperty()) {
                currentNode = currentNode.nodeProperty(element).modelNode();
            } else {
                currentNode = view->modelNodeForId(element); //id
                if (!currentNode.isValid())
                    return ModelNode(); //binding not valid
            }
        } else {
            currentNode = view->modelNodeForId(element); //id
        }
        i++;
        if (i < binding.split(QLatin1Char('.')).count())
            element = binding.split(QLatin1Char('.')).at(i);
        else
            element.clear();
    }
    return currentNode;

}
// TODO: this need to e updated for states
static bool compareTree(const ModelNode &node1, const ModelNode &node2)
{
    if (!node1.isValid() || !node2.isValid()) {
        return false;
    }

    if (node1.type() != node2.type()) {
        return false;
    }

    // Compare properties
    {
        const QList<AbstractProperty> propList1 = node1.properties();
        const QList<AbstractProperty> propList2 = node2.properties();

        QList<AbstractProperty>::const_iterator iter1 = propList1.constBegin();
        QList<AbstractProperty>::const_iterator iter2 = propList2.constBegin();
        for (;
             iter1 != propList1.constEnd() && iter2 != propList2.constEnd();
             iter1++, iter2++) {
            if (!compareProperty(*iter1, *iter2))
                return false;
        }

        if (iter1 != propList1.constEnd() || iter2 != propList2.constEnd())
            return false;
    }

    // Compare list of children
    {
        const QList<ModelNode> childList1 = node1.allDirectSubModelNodes();
        const QList<ModelNode> childList2 = node2.allDirectSubModelNodes();

        QList<ModelNode>::const_iterator iter1;
        QList<ModelNode>::const_iterator iter2;
        for (iter1 = childList1.constBegin(), iter2 = childList2.constBegin();
             iter1 != childList1.constEnd() && iter2 != childList2.constEnd();
             iter1++, iter2++) {
            if (!compareTree((*iter1), (*iter2)))
                return false;
        }

        if (iter1 != childList1.constEnd() || iter2 != childList2.constEnd())
            return false;
    }
    return true;
}
QVariant StatesEditorModel::data(const QModelIndex &index, int role) const
{
    if (index.parent().isValid() || index.column() != 0 || m_statesEditorView.isNull() || !m_statesEditorView->hasModelNodeForInternalId(index.internalId()))
        return QVariant();

    ModelNode stateNode;

    if (index.internalId() > 0)
        stateNode = m_statesEditorView->modelNodeForInternalId(index.internalId());

    switch (role) {
    case StateNameRole: {
            if (index.row() == 0) {
                return QString(tr("base state", "Implicit default state"));
            } else {
                if (stateNode.hasVariantProperty("name"))
                    return stateNode.variantProperty("name").value();
                else
                    return QVariant();
            }

        }
    case StateImageSourceRole: {
        static int randomNumber = 0;
        randomNumber++;
        if (index.row() == 0)
            return QString("image://qmldesigner_stateseditor/baseState-%1").arg(randomNumber);
        else
            return QString("image://qmldesigner_stateseditor/%1-%2").arg(index.internalId()).arg(randomNumber);
    }
    case InternalNodeId: return index.internalId();

    case HasWhenCondition: return stateNode.isValid() && stateNode.hasProperty("when");

    case WhenConditionString: {
        if (stateNode.isValid() && stateNode.hasBindingProperty("when"))
            return stateNode.bindingProperty("when").expression();
        else
            return QString();
    }

    }

    return QVariant();
}
示例#10
0
static bool isFileComponent(const ModelNode &node)
{
    if (node.isValid()
            && node.metaInfo().isValid()
            && node.metaInfo().isFileComponent())
        return true;

    return false;
}
示例#11
0
void NameItemDelegate::paint(QPainter *painter,
               const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    if (option.state & QStyle::State_Selected)
        drawSelectionBackground(painter, option);

    QString displayString;
    QPoint displayStringOffset;

    painter->save();
    QFontMetrics fm(option.font);
    int width = 0;
    if (index.data(Qt::UserRole).isValid()) {

        int pixmapSide = 16;

        if (m_TreeModel->isNodeInvisible( index ))
            painter->setOpacity(0.5);

        ModelNode node = m_TreeModel->nodeForIndex(index);

        QIcon icon;
        if (node.isValid()) {
            // if node has no own icon, search for it in the itemlibrary
            const ItemLibraryInfo *libraryInfo = node.model()->metaInfo().itemLibraryInfo();
            QList <ItemLibraryEntry> infoList = libraryInfo->entriesForType(node.type(),
                                                                            node.majorVersion(),
                                                                            node.minorVersion());
            foreach (const ItemLibraryEntry &entry, infoList) {
                if (icon.isNull()) {
                    icon = entry.icon();
                    break;
                }
            }
        }
        // if the library was also empty, use the default icon
        if (icon.isNull())
            icon = QIcon(QLatin1String(":/ItemLibrary/images/item-default-icon.png"));
        if (!node.metaInfo().isValid())
            icon = QIcon(QLatin1String(":/ItemLibrary/images/item-invalid-icon.png"));

        // If no icon is present, leave an empty space of 24 pixels anyway
        QPixmap pixmap = icon.pixmap(pixmapSide, pixmapSide);
        painter->drawPixmap(option.rect.x()+1,option.rect.y()+2,pixmap);

        displayString = node.id();
        if (displayString.isEmpty())
            displayString = node.simplifiedTypeName();

        // Check text length does not exceed available space
        int extraSpace=12+pixmapSide;

        displayString = fm.elidedText(displayString,Qt::ElideMiddle,option.rect.width()-extraSpace);
        displayStringOffset = QPoint(5+pixmapSide,-5);
        width = fm.width(displayString);
    }
示例#12
0
static bool hasSourceWithFileComponent(const ModelNode &modelNode)
{
    if (modelNode.isValid()
            && modelNode.metaInfo().isValid()
            && modelNode.metaInfo().isSubclassOf("QtQuick.Loader")
            && modelNode.hasVariantProperty("source"))
        return true;

    return false;
}
示例#13
0
void TestPropertyEditor::removeNode()
{
    std::auto_ptr<QWidget> widget(new QWidget());

    QScopedPointer<Model> model(Model::create("import Qt 4.6\n Item {}"));
    QVERIFY(model.data());

    QScopedPointer<TestView> view(new TestView);
    QVERIFY(view.data());
    model->attachView(view.data());

    setupPropertyEditor(widget.get(), model.data());

    QCOMPARE(view->rootModelNode().allDirectSubModelNodes().count(), 0);

    selectThrough(view->rootModelNode());

    ModelNode childNode = view->createModelNode("Qt/Rectangle", 4, 6);
    view->rootModelNode().nodeListProperty("data").reparentHere(childNode);
    QVERIFY(childNode.isValid());
    QCOMPARE(view->rootModelNode().allDirectSubModelNodes().count(), 1);
    QVERIFY(view->rootModelNode().allDirectSubModelNodes().contains(childNode));
    QVERIFY(childNode.parentProperty().parentModelNode() == view->rootModelNode());

    selectThrough(childNode);

    ModelNode subChildNode = view->createModelNode("Qt/Rectangle", 4, 6);
    childNode.nodeListProperty("data").reparentHere(subChildNode);
    QVERIFY(subChildNode.isValid());
    QCOMPARE(childNode.allDirectSubModelNodes().count(), 1);
    QVERIFY(childNode.allDirectSubModelNodes().contains(subChildNode));
    QVERIFY(subChildNode.parentProperty().parentModelNode() == childNode);

    selectThrough(subChildNode);

    childNode.destroy();

    QCOMPARE(view->rootModelNode().allDirectSubModelNodes().count(), 0);
    QVERIFY(!view->rootModelNode().allDirectSubModelNodes().contains(childNode));
    QVERIFY(!childNode.isValid());
    QVERIFY(!subChildNode.isValid());
}
示例#14
0
static bool hasDelegateWithFileComponent(const ModelNode &node)
{
    if (node.isValid()
            && node.metaInfo().isValid()
            && node.metaInfo().isView()
            && node.hasNodeProperty("delegate")
            && node.nodeProperty("delegate").modelNode().metaInfo().isFileComponent())
        return true;

    return false;
}
VariantProperty DynamicPropertiesModel::variantPropertyForRow(int rowNumber) const
{
    const int internalId = data(index(rowNumber, TargetModelNodeRow), Qt::UserRole + 1).toInt();
    const QString targetPropertyName = data(index(rowNumber, TargetModelNodeRow), Qt::UserRole + 2).toString();

    ModelNode  modelNode = connectionView()->modelNodeForInternalId(internalId);

    if (modelNode.isValid())
        return modelNode.variantProperty(targetPropertyName.toLatin1());

    return VariantProperty();
}
void ModelNodePositionStorage::cleanupInvalidOffsets()
{
    QHash<ModelNode, RewriterData> validModelNodes;

    QHashIterator<ModelNode, RewriterData> iter(m_rewriterData);
    while (iter.hasNext()) {
        iter.next();
        const ModelNode modelNode = iter.key();
        if (modelNode.isValid())
            validModelNodes.insert(modelNode, iter.value());
    }
    m_rewriterData = validModelNodes;
}
bool detectVerticalCycle(const ModelNode &node, QList<ModelNode> knownNodeList)
{
    if (!node.isValid())
        return false;

    if (knownNodeList.contains(node))
        return true;

    knownNodeList.append(node);

    static QStringList validAnchorLines(QStringList() << "top" << "bottom" << "verticalCenter" << "baseline");
    static QStringList anchorNames(QStringList() << "anchors.top" << "anchors.bottom" << "anchors.verticalCenter" << "anchors.baseline");

    foreach (const QString &anchorName, anchorNames) {
        if (node.hasBindingProperty(anchorName)) {
            AbstractProperty targetProperty = node.bindingProperty(anchorName).resolveToProperty();
            if (targetProperty.isValid()) {
                if (!validAnchorLines.contains(targetProperty.name()))
                    return true;

                if (detectVerticalCycle(targetProperty.parentModelNode(), knownNodeList))
                    return true;
            }
        }

    }

    static QStringList anchorShortcutNames(QStringList() << "anchors.fill" << "anchors.centerIn");
    foreach (const QString &anchorName, anchorShortcutNames) {
        if (node.hasBindingProperty(anchorName)) {
            ModelNode targetNode = node.bindingProperty(anchorName).resolveToModelNode();

            if (targetNode.isValid() && detectVerticalCycle(targetNode, knownNodeList))
                return true;
        }
    }

    return false;
}
示例#18
0
static bool isLoaderWithSourceComponent(const ModelNode &modelNode)
{
    if (modelNode.isValid()
            && modelNode.metaInfo().isValid()
            && modelNode.metaInfo().isSubclassOf("QtQuick.Loader")) {

        if (modelNode.hasNodeProperty("sourceComponent"))
            return true;
        if (modelNode.hasNodeListProperty("component"))
            return true;
    }

    return false;
}
示例#19
0
static bool isInEditedPath(const NodeAbstractProperty &propertyParent, const ModelNode &editingPathViewModelNode)
{
    if (editingPathViewModelNode.isValid()) {
        if (editingPathViewModelNode.hasNodeProperty("path")) {
            ModelNode pathModelNode = editingPathViewModelNode.nodeProperty("path").modelNode();
            if (pathModelNode.metaInfo().isSubclassOf("QtQuick.Path")) {
                if (propertyParent.name() == "pathElements" && propertyParent.parentModelNode() == pathModelNode)
                    return true;
            }
        }
    }

    return false;
}
示例#20
0
void TestPropertyEditor::createRect()
{
    try {

        std::auto_ptr<QWidget> widget(new QWidget());

        QScopedPointer<Model> model(Model::create("import Qt 4.6\n Item {}"));
        QVERIFY(model.data());

        QScopedPointer<TestView> view(new TestView);
        QVERIFY(view.data());
        model->attachView(view.data());

        setupPropertyEditor(widget.get(), model.data());

        QVERIFY(view->rootModelNode().isValid());

        //selectThrough(view->rootModelNode());

        ModelNode childNode = view->createModelNode("Qt/Rectangle", 4, 6);
        view->rootModelNode().nodeListProperty("data").reparentHere(childNode);

        QVERIFY(childNode.isValid());
        QVERIFY(view->rootModelNode().allDirectSubModelNodes().contains(childNode));
        QVERIFY(childNode.parentProperty().parentModelNode() == view->rootModelNode());
        QCOMPARE(childNode.type(), QString("Qt/Rectangle"));

        QVERIFY(childNode.id().isEmpty());

        childNode.setId("Rect01");
        QCOMPARE(childNode.id(), QString("Rect01"));

        childNode.variantProperty("x") = 100;
        QCOMPARE(QmlObjectNode(childNode).instanceValue("x").toInt(), 100);
        childNode.variantProperty("y") = 100;
        QCOMPARE(QmlObjectNode(childNode).instanceValue("y").toInt(), 100);
        childNode.variantProperty("width") = 100;
        QCOMPARE(QmlObjectNode(childNode).instanceValue("width").toInt(), 100);
        childNode.variantProperty("height") = 100;
        QCOMPARE(QmlObjectNode(childNode).instanceValue("height").toInt(), 100);

        selectThrough(childNode);

        QCOMPARE(childNode.propertyNames().count(), 4);
        QCOMPARE(childNode.variantProperty("scale").value(), QVariant());

    } catch (Exception &) {
        QFAIL("Exception thrown");
    }
}
示例#21
0
static bool nodeOrParentInSet(const ModelNode &node, const QSet<ModelNode> &nodeSet)
{
    ModelNode n = node;
    while (n.isValid()) {
        if (nodeSet.contains(n))
            return true;

        if (!n.hasParentProperty())
            return false;

        n = n.parentProperty().parentModelNode();
    }

    return false;
}
示例#22
0
bool QmlObjectNode::isAliasExported() const
{

    if (modelNode().isValid() && !modelNode().id().isEmpty()) {
         PropertyName modelNodeId = modelNode().id().toUtf8();
         ModelNode rootModelNode = view()->rootModelNode();
         Q_ASSERT(rootModelNode.isValid());
         if (rootModelNode.hasBindingProperty(modelNodeId)
                 && rootModelNode.bindingProperty(modelNodeId).isDynamic()
                 && rootModelNode.bindingProperty(modelNodeId).expression().toUtf8() == modelNodeId)
             return true;
    }

    return false;
}
static bool nodeOrParentInSet(const ModelNode &modelNode, const QSet<ModelNode> &nodeSet)
{
    ModelNode currentModelnode = modelNode;
    while (currentModelnode.isValid()) {
        if (nodeSet.contains(currentModelnode))
            return true;

        if (!currentModelnode.hasParentProperty())
            return false;

        currentModelnode = currentModelnode.parentProperty().parentModelNode();
    }

    return false;
}
示例#24
0
void DocumentManager::goIntoComponent(const ModelNode &modelNode)
{
    if (modelNode.isValid() && modelNode.isComponent()) {
        QmlDesignerPlugin::instance()->viewManager().setComponentNode(modelNode);
        if (isFileComponent(modelNode))
            openFileComponent(modelNode);
        else if (hasDelegateWithFileComponent(modelNode))
            openFileComponentForDelegate(modelNode);
        else if (hasSourceWithFileComponent(modelNode))
            openSourcePropertyOfLoader(modelNode);
        else if (isLoaderWithSourceComponent(modelNode))
            openComponentSourcePropertyOfLoader(modelNode);
        else
            openInlineComponent(modelNode);
    }
}
示例#25
0
void NodeInstanceView::modelAttached(Model *model)
{
    AbstractView::modelAttached(model);
    m_nodeInstanceServer = new NodeInstanceServerProxy(this, m_runModus, m_currentKit);
    m_lastCrashTime.start();
    connect(m_nodeInstanceServer.data(), SIGNAL(processCrashed()), this, SLOT(handleChrash()));

    if (!isSkippedRootNode(rootModelNode()))
        nodeInstanceServer()->createScene(createCreateSceneCommand());

    ModelNode stateNode = currentStateNode();
    if (stateNode.isValid() && stateNode.metaInfo().isSubclassOf("QtQuick.State", 1, 0)) {
        NodeInstance newStateInstance = instanceForModelNode(stateNode);
        activateState(newStateInstance);
    }

}
NavigatorTreeModel::ItemRow NavigatorTreeModel::createItemRow(const ModelNode &node)
{
    Q_ASSERT(node.isValid());

    uint hash = node.internalId();

    const bool dropEnabled = node.metaInfo().isValid();

    QStandardItem *idItem = new QStandardItem;
    idItem->setDragEnabled(true);
    idItem->setDropEnabled(dropEnabled);
    idItem->setEditable(true);
    idItem->setData(hash, NavigatorRole);
    if (node.metaInfo().isValid())
        idItem->setToolTip(node.type());
    else
        idItem->setToolTip(msgUnknownItem(node.type()));
#    ifdef _LOCK_ITEMS_
    QStandardItem *lockItem = new QStandardItem;
    lockItem->setDragEnabled(true);
    lockItem->setDropEnabled(dropEnabled);
    lockItem->setEditable(false);
    lockItem->setCheckable(true);
    lockItem->setData(hash, NavigatorRole);
#    endif

    QStandardItem *visibilityItem = new QStandardItem;
    visibilityItem->setDropEnabled(dropEnabled);
    visibilityItem->setCheckable(true);
    visibilityItem->setEditable(false);
    visibilityItem->setData(hash, NavigatorRole);
    if (node.isRootNode())
        visibilityItem->setCheckable(false);

    QMap<QString, QStandardItem *> propertyItems;
    foreach (const QString &propertyName, visibleProperties(node)) {
        QStandardItem *propertyItem = new QStandardItem;
        propertyItem->setSelectable(false);
        propertyItem->setDragEnabled(false);
        propertyItem->setDropEnabled(dropEnabled);
        propertyItem->setEditable(false);
        propertyItem->setData(propertyName, Qt::DisplayRole);
        propertyItems.insert(propertyName, propertyItem);
        idItem->appendRow(propertyItem);
    }
示例#27
0
static void removeAliasExports(const QmlObjectNode &node)
{

    PropertyName propertyName = node.id().toUtf8();

    ModelNode rootNode = node.view()->rootModelNode();
    bool hasAliasExport = !propertyName.isEmpty()
            && rootNode.isValid()
            && rootNode.hasBindingProperty(propertyName)
            && rootNode.bindingProperty(propertyName).isAliasExport();

    if (hasAliasExport)
        rootNode.removeProperty(propertyName);

    foreach (const ModelNode &childNode, node.modelNode().directSubModelNodes()) {
        removeAliasExports(childNode);
    }

}
示例#28
0
void DocumentManager::goIntoComponent(const ModelNode &modelNode)
{
    if (modelNode.isValid() && modelNode.isComponent() && designDocument()) {
        QmlDesignerPlugin::instance()->viewManager().setComponentNode(modelNode);
        QHash<PropertyName, QVariant> oldProperties = getProperties(modelNode);
        if (isFileComponent(modelNode))
            openFileComponent(modelNode);
        else if (hasDelegateWithFileComponent(modelNode))
            openFileComponentForDelegate(modelNode);
        else if (hasSourceWithFileComponent(modelNode))
            openSourcePropertyOfLoader(modelNode);
        else if (isLoaderWithSourceComponent(modelNode))
            openComponentSourcePropertyOfLoader(modelNode);
        else
            openInlineComponent(modelNode);
        ModelNode rootModelNode = designDocument()->rewriterView()->rootModelNode();
        applyProperties(rootModelNode, oldProperties);
    }
}
示例#29
0
static inline void openInlineComponent(const ModelNode &modelNode)
{

    if (!modelNode.isValid() || !modelNode.metaInfo().isValid())
        return;

    if (!currentDesignDocument())
        return;

    QHash<PropertyName, QVariant> propertyHash;

    getProperties(modelNode, propertyHash);

    handleComponent(modelNode);
    handleDelegate(modelNode);
    handleTabComponent(modelNode);

    ModelNode rootModelNode = currentDesignDocument()->rewriterView()->rootModelNode();
    applyProperties(rootModelNode, propertyHash);
}
void QmlDesignerPlugin::jumpTextCursorToSelectedModelNode()
{
    // visual editor -> text editor
    ModelNode selectedNode;
    if (!currentDesignDocument()->rewriterView()->selectedModelNodes().isEmpty())
        selectedNode = currentDesignDocument()->rewriterView()->selectedModelNodes().first();

    if (selectedNode.isValid()) {
        const int nodeOffset = currentDesignDocument()->rewriterView()->nodeOffset(selectedNode);
        if (nodeOffset > 0) {
            const ModelNode currentSelectedNode
                    = currentDesignDocument()->rewriterView()->nodeAtTextCursorPosition(currentDesignDocument()->plainTextEdit()->textCursor().position());
            if (currentSelectedNode != selectedNode) {
                int line, column;
                currentDesignDocument()->textEditor()->convertPosition(nodeOffset, &line, &column);
                currentDesignDocument()->textEditor()->gotoLine(line, column);
            }
        }
    }
}