diff --git a/include/history.hpp b/include/history.hpp index a227fe3d..3503f175 100644 --- a/include/history.hpp +++ b/include/history.hpp @@ -142,6 +142,7 @@ struct CableAdd : Action { int outputId; NVGcolor color; void setCable(app::CableWidget* cw); + bool isCable(app::CableWidget* cw) const; void undo() override; void redo() override; CableAdd() { diff --git a/src/app/PortWidget.cpp b/src/app/PortWidget.cpp index f798a127..88412735 100644 --- a/src/app/PortWidget.cpp +++ b/src/app/PortWidget.cpp @@ -476,10 +476,6 @@ void PortWidget::onDragEnd(const DragEndEvent& e) { if (e.button != GLFW_MOUSE_BUTTON_LEFT) return; - // Should never happen since it's created in onDragStart(). - if (!internal->history) - return; - // Remove all incomplete cables for (CableWidget* cw : APP->scene->rack->getIncompleteCables()) { APP->scene->rack->removeCable(cw); @@ -487,7 +483,10 @@ void PortWidget::onDragEnd(const DragEndEvent& e) { } // Push history - if (internal->history->isEmpty()) { + if (!internal->history) { + // This shouldn't happen since it's created in onDragStart() + } + else if (internal->history->isEmpty()) { // No history actions, don't push anything delete internal->history; } @@ -541,11 +540,28 @@ void PortWidget::onDragDrop(const DragDropEvent& e) { } cw->updateCable(); - history::CableAdd* h = new history::CableAdd; - h->setCable(cw); - pwOrigin->internal->history->push(h); - - // TODO Reject history if plugging into same port + // This should always be true since the ComplexAction is created in onDragStart() + history::ComplexAction* history = pwOrigin->internal->history; + if (history) { + // Reject history if plugging into same port + auto& actions = history->actions; + auto it = std::find_if(actions.begin(), actions.end(), [&](history::Action* h) { + history::CableAdd* hca = dynamic_cast(h); + if (!hca) + return false; + return hca->isCable(cw); + }); + + if (it != actions.end()) { + actions.erase(it); + } + else { + // Push CableAdd action + history::CableAdd* h = new history::CableAdd; + h->setCable(cw); + history->push(h); + } + } } } diff --git a/src/history.cpp b/src/history.cpp index b7455f25..8b5473e5 100644 --- a/src/history.cpp +++ b/src/history.cpp @@ -160,6 +160,13 @@ void CableAdd::setCable(app::CableWidget* cw) { color = cw->color; } +bool CableAdd::isCable(app::CableWidget* cw) const { + if (!(cw && cw->cable && cw->cable->id >= 0 && cw->cable->outputModule && cw->cable->inputModule)) + return false; + engine::Cable* c = cw->cable; + return c->inputModule->id == inputModuleId && c->inputId == inputId && c->outputModule->id == outputModuleId && c->outputId == outputId; +} + void CableAdd::undo() { app::CableWidget* cw = APP->scene->rack->getCable(cableId); if (!cw)