finished refactoring copy/paste code
This commit is contained in:
@@ -47,7 +47,6 @@ NodeView::NodeView(QWidget *parent) :
|
||||
create_edge_(nullptr),
|
||||
create_edge_output_item_(nullptr),
|
||||
create_edge_input_item_(nullptr),
|
||||
paste_command_(nullptr),
|
||||
scale_(1.0)
|
||||
{
|
||||
setScene(&scene_);
|
||||
@@ -283,14 +282,6 @@ void NodeView::keyPressEvent(QKeyEvent *event)
|
||||
case Qt::Key_Escape:
|
||||
if (!attached_items_.isEmpty()) {
|
||||
DetachItemsFromCursor();
|
||||
|
||||
// We undo the last action which SHOULD be adding the node
|
||||
if (paste_command_) {
|
||||
paste_command_->undo_now();
|
||||
delete paste_command_;
|
||||
paste_command_ = nullptr;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -573,23 +564,18 @@ void NodeView::mouseReleaseEvent(QMouseEvent *event)
|
||||
}
|
||||
|
||||
if (context) {
|
||||
if (paste_command_) {
|
||||
// We've already "done" this command, but MultiUndoCommand prevents "redoing" twice, so we
|
||||
// add it to this command (which may have extra commands added too) so that it all gets undone
|
||||
// in the same action
|
||||
command->add_child(paste_command_);
|
||||
paste_command_ = nullptr;
|
||||
}
|
||||
|
||||
{
|
||||
MultiUndoCommand *add_command = new MultiUndoCommand();
|
||||
|
||||
foreach (const AttachedItem &ai, attached_items_) {
|
||||
// Add node to the same graph that the context is in
|
||||
add_command->add_child(new NodeAddCommand(context->parent(), ai.item->GetNode()));
|
||||
add_command->add_child(new NodeAddCommand(context->parent(), ai.node));
|
||||
|
||||
// Add node to the context
|
||||
add_command->add_child(new NodeSetPositionCommand(ai.item->GetNode(), context, scene_.context_map().value(context)->MapScenePosToNodePosInContext(ai.item->pos())));
|
||||
if (ai.item) {
|
||||
qDebug() << "Placing an item!";
|
||||
add_command->add_child(new NodeSetPositionCommand(ai.node, context, scene_.context_map().value(context)->MapScenePosToNodePosInContext(ai.item->pos())));
|
||||
}
|
||||
}
|
||||
|
||||
if (add_command->child_count()) {
|
||||
@@ -604,9 +590,16 @@ void NodeView::mouseReleaseEvent(QMouseEvent *event)
|
||||
// Dropped attached item onto an edge, connect it between them
|
||||
MultiUndoCommand *drop_edge_command = new MultiUndoCommand();
|
||||
if (attached_items_.size() == 1) {
|
||||
Node* dropping_node = attached_items_.first().item->GetNode();
|
||||
Node* dropping_node = nullptr;
|
||||
|
||||
if (drop_edge_) {
|
||||
foreach (const AttachedItem &ai, attached_items_) {
|
||||
if (ai.item) {
|
||||
dropping_node = ai.node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dropping_node && drop_edge_) {
|
||||
// Remove old edge
|
||||
drop_edge_command->add_child(new NodeEdgeRemoveCommand(drop_edge_->output(), drop_edge_->input()));
|
||||
|
||||
@@ -625,7 +618,7 @@ void NodeView::mouseReleaseEvent(QMouseEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
DetachItemsFromCursor();
|
||||
DetachItemsFromCursor(false);
|
||||
} else {
|
||||
QToolTip::showText(QCursor::pos(), tr("Nodes must be placed inside a context."));
|
||||
}
|
||||
@@ -809,7 +802,8 @@ void NodeView::CreateNodeSlot(QAction *action)
|
||||
NodeViewItem *new_item = new NodeViewItem(new_node, nullptr);
|
||||
new_item->SetFlowDirection(scene_.GetFlowDirection());
|
||||
scene_.addItem(new_item);
|
||||
AttachItemsToCursor({new_item});
|
||||
|
||||
SetAttachedItems({{new_item, new_node, QPointF(0, 0)}});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -899,23 +893,14 @@ void NodeView::NodeRemovedFromGraph()
|
||||
contexts_.removeOne(context);
|
||||
}
|
||||
|
||||
void NodeView::AttachItemsToCursor(const QVector<NodeViewItem*>& items)
|
||||
{
|
||||
DetachItemsFromCursor();
|
||||
|
||||
if (!items.isEmpty()) {
|
||||
for (NodeViewItem* i : items) {
|
||||
attached_items_.append({i, i->pos() - items.first()->pos()});
|
||||
}
|
||||
|
||||
MoveAttachedNodesToCursor(mapFromGlobal(QCursor::pos()));
|
||||
}
|
||||
}
|
||||
|
||||
void NodeView::DetachItemsFromCursor()
|
||||
void NodeView::DetachItemsFromCursor(bool delete_nodes_too)
|
||||
{
|
||||
foreach (const AttachedItem &ai, attached_items_) {
|
||||
delete ai.item;
|
||||
|
||||
if (delete_nodes_too) {
|
||||
delete ai.node;
|
||||
}
|
||||
}
|
||||
|
||||
attached_items_.clear();
|
||||
@@ -931,7 +916,9 @@ void NodeView::MoveAttachedNodesToCursor(const QPoint& p)
|
||||
QPointF item_pos = mapToScene(p);
|
||||
|
||||
for (const AttachedItem& i : qAsConst(attached_items_)) {
|
||||
i.item->setPos(item_pos + i.original_pos);
|
||||
if (i.item) {
|
||||
i.item->setPos(item_pos + i.original_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -990,14 +977,18 @@ void NodeView::CopyNodesToClipboardInternal(QXmlStreamWriter *writer, const QVec
|
||||
writer->writeStartElement(QStringLiteral("pos"));
|
||||
|
||||
for (Node *n : nodes) {
|
||||
Node::Position pos = GetAssumedPositionForSelectedNode(n);
|
||||
NodeViewItem *item = GetAssumedItemForSelectedNode(n);
|
||||
|
||||
writer->writeStartElement(QStringLiteral("node"));
|
||||
writer->writeAttribute(QStringLiteral("ptr"), QString::number(reinterpret_cast<quintptr>(n)));
|
||||
writer->writeTextElement(QStringLiteral("x"), QString::number(pos.position.x()));
|
||||
writer->writeTextElement(QStringLiteral("y"), QString::number(pos.position.y()));
|
||||
writer->writeTextElement(QStringLiteral("expanded"), QString::number(pos.expanded));
|
||||
writer->writeEndElement(); // node
|
||||
if (item) {
|
||||
Node::Position pos = item->GetNodePositionData();
|
||||
|
||||
writer->writeStartElement(QStringLiteral("node"));
|
||||
writer->writeAttribute(QStringLiteral("ptr"), QString::number(reinterpret_cast<quintptr>(n)));
|
||||
writer->writeTextElement(QStringLiteral("x"), QString::number(pos.position.x()));
|
||||
writer->writeTextElement(QStringLiteral("y"), QString::number(pos.position.y()));
|
||||
writer->writeTextElement(QStringLiteral("expanded"), QString::number(pos.expanded));
|
||||
writer->writeEndElement(); // node
|
||||
}
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // pos
|
||||
@@ -1077,19 +1068,27 @@ QPointF NodeView::GetEstimatedPositionForContext(NodeViewItem *item, Node *conte
|
||||
return item->GetNodePosition() - context_offsets_.value(context);
|
||||
}
|
||||
|
||||
Node::Position NodeView::GetAssumedPositionForSelectedNode(Node *node)
|
||||
NodeViewItem *NodeView::GetAssumedItemForSelectedNode(Node *node)
|
||||
{
|
||||
// Try to find corresponding selected item
|
||||
foreach (NodeViewContext *ctx, scene_.context_map()) {
|
||||
NodeViewItem *item = ctx->GetItemFromMap(node);
|
||||
if (item && item->isSelected()) {
|
||||
if (item && item->GetNode() == node && item->isSelected()) {
|
||||
// Good enough
|
||||
return Node::Position(item->GetNodePosition(), item->IsExpanded());
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback
|
||||
return Node::Position();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Node::Position NodeView::GetAssumedPositionForSelectedNode(Node *node)
|
||||
{
|
||||
if (NodeViewItem *item = GetAssumedItemForSelectedNode(node)) {
|
||||
return item->GetNodePositionData();
|
||||
} else {
|
||||
return Node::Position();
|
||||
}
|
||||
}
|
||||
|
||||
Menu *NodeView::CreateAddMenu(Menu *parent)
|
||||
@@ -1338,19 +1337,44 @@ void NodeView::PasteNodesInternal(const QVector<Node *> &duplicate_nodes)
|
||||
|
||||
// If no nodes were retrieved, do nothing
|
||||
if (!new_nodes.isEmpty()) {
|
||||
QVector<NodeViewItem*> items(new_nodes.size());
|
||||
QVector<AttachedItem> new_attached;
|
||||
|
||||
NodeViewItem *first_item = nullptr;
|
||||
|
||||
for (int i=0; i<new_nodes.size(); i++) {
|
||||
Node *node = new_nodes.at(i);
|
||||
NodeViewItem *new_item = new NodeViewItem(node, nullptr);
|
||||
new_item->SetFlowDirection(scene_.GetFlowDirection());
|
||||
new_item->SetNodePosition(map.value(node));
|
||||
scene_.addItem(new_item);
|
||||
items[i] = new_item;
|
||||
|
||||
// Determine if item had a position, if not don't create an item for it
|
||||
NodeViewItem *new_item;
|
||||
|
||||
if (map.contains(node)) {
|
||||
new_item = new NodeViewItem(node, nullptr);
|
||||
new_item->SetFlowDirection(scene_.GetFlowDirection());
|
||||
new_item->SetNodePosition(map.value(node));
|
||||
scene_.addItem(new_item);
|
||||
|
||||
if (!first_item) {
|
||||
first_item = new_item;
|
||||
}
|
||||
} else {
|
||||
new_item = nullptr;
|
||||
}
|
||||
|
||||
new_attached.append({new_item, node, QPointF(0, 0)});
|
||||
}
|
||||
|
||||
// Attach nodes to cursor
|
||||
AttachItemsToCursor(items);
|
||||
// Correct positions
|
||||
if (first_item) {
|
||||
for (int i=0; i<new_attached.size(); i++) {
|
||||
AttachedItem &ai = new_attached[i];
|
||||
|
||||
if (ai.item) {
|
||||
ai.original_pos = first_item->pos() - ai.item->pos();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetAttachedItems(new_attached);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1389,4 +1413,15 @@ void NodeView::CollapseItem(NodeViewItem *item)
|
||||
item->setZValue(0);
|
||||
}
|
||||
|
||||
void NodeView::SetAttachedItems(const QVector<AttachedItem> &items)
|
||||
{
|
||||
// Detach anything currently attached
|
||||
DetachItemsFromCursor();
|
||||
|
||||
attached_items_ = items;
|
||||
|
||||
// Move to cursor
|
||||
MoveAttachedNodesToCursor(mapFromGlobal(QCursor::pos()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user