void ModelToTextMerger::nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange) { if (isInHierarchy(oldPropertyParent) && isInHierarchy(newPropertyParent)) { // the node is moved schedule(new ReparentNodeRewriteAction(node, oldPropertyParent, newPropertyParent, propertyType(newPropertyParent))); } else if (isInHierarchy(oldPropertyParent) && !isInHierarchy(newPropertyParent)) { // the node is removed from hierarchy if (oldPropertyParent.isNodeProperty()) { // ignore, the subsequent remove property will take care of all } else if (oldPropertyParent.isNodeListProperty()) { if (!oldPropertyParent.isDefaultProperty() && oldPropertyParent.toNodeListProperty().toModelNodeList().size() == 0) { schedule(new RemovePropertyRewriteAction(oldPropertyParent)); } else { schedule(new RemoveNodeRewriteAction(node)); } } else { schedule(new RemoveNodeRewriteAction(node)); } } else if (!isInHierarchy(oldPropertyParent) && isInHierarchy(newPropertyParent)) { // the node is inserted into to hierarchy switch (propertyChange) { case AbstractView::PropertiesAdded: schedule(new AddPropertyRewriteAction(newPropertyParent, QmlTextGenerator(getPropertyOrder())(node), propertyType(newPropertyParent), node)); break; case AbstractView::NoAdditionalChanges: schedule(new ChangePropertyRewriteAction(newPropertyParent, QmlTextGenerator(getPropertyOrder())(node), propertyType(newPropertyParent), node)); break; case AbstractView::EmptyPropertiesRemoved: break; default: Q_ASSERT(!"Unknown PropertyChange value"); } } else { // old is outside of hierarchy, new is outside of hierarchy, so who cares? } }
bool NavigatorTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &dropIndex) { if (action == Qt::IgnoreAction) return true; if (action != Qt::LinkAction) return false; if (!data->hasFormat("application/vnd.modelnode.list")) return false; if (column > 1) return false; if (dropIndex.model() != this) return false; QModelIndex parentIndex, parentItemIndex; PropertyName parentPropertyName; int targetIndex; parentIndex = dropIndex.sibling(dropIndex.row(), 0); targetIndex = (row > -1)? row : rowCount(parentIndex); if (this->data(parentIndex, NavigatorRole).isValid()) { parentItemIndex = parentIndex; ModelNode parentNode = nodeForIndex(parentItemIndex); if (!parentNode.metaInfo().hasDefaultProperty()) return false; targetIndex -= visibleProperties(parentNode).count(); parentPropertyName = parentNode.metaInfo().defaultPropertyName(); } else { parentItemIndex = parentIndex.parent(); parentPropertyName = parentIndex.data(Qt::DisplayRole).toByteArray(); } // Disallow dropping items between properties, which are listed first. if (targetIndex < 0) return false; Q_ASSERT(parentItemIndex.isValid()); QByteArray encodedData = data->data("application/vnd.modelnode.list"); QDataStream stream(&encodedData, QIODevice::ReadOnly); QList<ModelNode> nodeList; while (!stream.atEnd()) { uint nodeHash; stream >> nodeHash; if (containsNodeHash(nodeHash)) { ModelNode node(nodeForHash(nodeHash)); nodeList.append(node); } } ModelNode parentNode(nodeForIndex(parentItemIndex)); NodeAbstractProperty parentProperty = parentNode.nodeAbstractProperty(parentPropertyName); if (parentProperty.isNodeProperty() && nodeList.count() > 1) { return false; } moveNodesInteractive(parentProperty, nodeList, targetIndex); propagateInvisible(parentNode, isNodeInvisible(parentNode)); return false; // don't let the view do drag&drop on its own }