nodeview: fixed pasting/duplicating crash

This commit is contained in:
itsmattkc
2021-07-23 22:09:28 -07:00
parent fac8dbbc19
commit 1c8b1b6006
6 changed files with 87 additions and 6 deletions
+2 -2
View File
@@ -70,7 +70,7 @@ void NodeCopyPasteService::CopyNodesToClipboard(const QVector<Node *> &nodes, vo
writer.writeEndElement(); // contexts
writer.writeStartElement(QStringLiteral("custom"));
CopyNodesToClipboardInternal(&writer, userdata);
CopyNodesToClipboardInternal(&writer, nodes, userdata);
writer.writeEndElement(); // custom
writer.writeEndElement(); // olive
@@ -229,7 +229,7 @@ QVector<Node *> NodeCopyPasteService::PasteNodesFromClipboard(NodeGraph *graph,
return pasted_nodes;
}
void NodeCopyPasteService::CopyNodesToClipboardInternal(QXmlStreamWriter*, void*)
void NodeCopyPasteService::CopyNodesToClipboardInternal(QXmlStreamWriter*, const QVector<Node *> &, void*)
{
}
+1 -1
View File
@@ -39,7 +39,7 @@ protected:
QVector<Node*> PasteNodesFromClipboard(NodeGraph *graph, MultiUndoCommand *command, void* userdata = nullptr);
virtual void CopyNodesToClipboardInternal(QXmlStreamWriter *writer, void* userdata);
virtual void CopyNodesToClipboardInternal(QXmlStreamWriter *writer, const QVector<Node*> &nodes, void* userdata);
virtual void PasteNodesFromClipboardInternal(QXmlStreamReader *reader, XMLNodeData &xml_node_data, void* userdata);
+79 -1
View File
@@ -1264,6 +1264,65 @@ bool NodeView::eventFilter(QObject *object, QEvent *event)
return super::eventFilter(object, event);
}
void NodeView::CopyNodesToClipboardInternal(QXmlStreamWriter *writer, const QVector<Node *> &nodes, void *userdata)
{
writer->writeStartElement(QStringLiteral("pos"));
for (Node *n : nodes) {
NodeViewItem *item = scene_.item_map().value(n);
QPointF pos = item->GetNodePosition();
writer->writeStartElement(QStringLiteral("node"));
writer->writeAttribute(QStringLiteral("ptr"), QString::number(reinterpret_cast<quintptr>(n)));
writer->writeTextElement(QStringLiteral("x"), QString::number(pos.x()));
writer->writeTextElement(QStringLiteral("y"), QString::number(pos.y()));
writer->writeEndElement(); // node
}
writer->writeEndElement(); // pos
}
void NodeView::PasteNodesFromClipboardInternal(QXmlStreamReader *reader, XMLNodeData &xml_node_data, void *userdata)
{
NodeGraph::PositionMap *map = static_cast<NodeGraph::PositionMap *>(userdata);
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("pos")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
Node *n = nullptr;
QPointF pos;
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("ptr")) {
n = xml_node_data.node_ptrs.value(attr.value().toULongLong());
break;
}
}
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("x")) {
pos.setX(reader->readElementText().toDouble());
} else if (reader->name() == QStringLiteral("y")) {
pos.setY(reader->readElementText().toDouble());
} else {
reader->skipCurrentElement();
}
}
if (n) {
map->insert(n, pos);
}
} else {
reader->skipCurrentElement();
}
}
} else {
reader->skipCurrentElement();
}
}
}
void NodeView::ZoomFromKeyboard(double multiplier)
{
QPoint cursor_pos = mapFromGlobal(QCursor::pos());
@@ -1577,14 +1636,33 @@ void NodeView::PasteNodesInternal(const QVector<Node *> &duplicate_nodes)
// If duplicating nodes, duplicate, otherwise paste
QVector<Node*> new_nodes;
NodeGraph::PositionMap map;
if (duplicate_nodes.isEmpty()) {
new_nodes = PasteNodesFromClipboard(graph_, paste_command_);
new_nodes = PasteNodesFromClipboard(graph_, paste_command_, &map);
for (auto it=new_nodes.cbegin(); it!=new_nodes.cend(); it++) {
for (Node *context : qAsConst(filter_nodes_)) {
paste_command_->add_child(new NodeSetPositionCommand(*it, context, map.value(*it), false));
}
}
} else {
new_nodes = Node::CopyDependencyGraph(duplicate_nodes, paste_command_);
for (int i=0; i<duplicate_nodes.size(); i++) {
Node *src = duplicate_nodes.at(i);
Node *copy = new_nodes.at(i);
for (Node *context : qAsConst(filter_nodes_)) {
QPointF p = scene_.item_map().value(src)->GetNodePosition();
paste_command_->add_child(new NodeSetPositionCommand(copy, context, p, false));
}
}
}
// If no nodes were retrieved, do nothing
if (new_nodes.isEmpty()) {
delete paste_command_;
paste_command_ = nullptr;
return;
}
+3
View File
@@ -112,6 +112,9 @@ protected:
virtual bool eventFilter(QObject *object, QEvent *event) override;
virtual void CopyNodesToClipboardInternal(QXmlStreamWriter *writer, const QVector<Node*> &nodes, void* userdata) override;
virtual void PasteNodesFromClipboardInternal(QXmlStreamReader *reader, XMLNodeData &xml_node_data, void* userdata) override;
private:
void AttachNodesToCursor(const QVector<Node *> &nodes);
+1 -1
View File
@@ -296,7 +296,7 @@ void TimelineWidget::DisconnectNodeEvent(ViewerOutput *n)
}
}
void TimelineWidget::CopyNodesToClipboardInternal(QXmlStreamWriter *writer, void* userdata)
void TimelineWidget::CopyNodesToClipboardInternal(QXmlStreamWriter *writer, const QVector<Node *> &nodes, void* userdata)
{
// Cache the earliest in point so all copied clips have a "relative" in point that can be pasted anywhere
QVector<Block*>& selected = *static_cast<QVector<Block*>*>(userdata);
+1 -1
View File
@@ -248,7 +248,7 @@ protected:
virtual void ConnectNodeEvent(ViewerOutput* n) override;
virtual void DisconnectNodeEvent(ViewerOutput* n) override;
virtual void CopyNodesToClipboardInternal(QXmlStreamWriter *writer, void* userdata) override;
virtual void CopyNodesToClipboardInternal(QXmlStreamWriter *writer, const QVector<Node*> &nodes, void* userdata) override;
virtual void PasteNodesFromClipboardInternal(QXmlStreamReader *reader, XMLNodeData &xml_node_data, void* userdata) override;
struct BlockPasteData {