From 6c81ba466f2207a443227cec509ae09993300137 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Tue, 30 Nov 2021 07:36:48 -0500 Subject: [PATCH] Add RackWidget::getCompleteCablesOnPort(). Use it in PortWidget and ModuleWidget to prevent crashes when incomplete cables exist. --- include/app/RackWidget.hpp | 1 + src/app/ModuleWidget.cpp | 6 ++---- src/app/PortWidget.cpp | 4 ++-- src/app/RackWidget.cpp | 15 +++++++++++++++ 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/include/app/RackWidget.hpp b/include/app/RackWidget.hpp index 3d2de16d..c3f57fa0 100644 --- a/include/app/RackWidget.hpp +++ b/include/app/RackWidget.hpp @@ -120,6 +120,7 @@ struct RackWidget : widget::OpaqueWidget { std::vector getCompleteCables(); /** Returns all cables attached to port, complete or not. */ std::vector getCablesOnPort(PortWidget* port); + std::vector getCompleteCablesOnPort(PortWidget* port); /** Returns but does not advance the next cable color. */ int getNextCableColorId(); void setNextCableColorId(int id); diff --git a/src/app/ModuleWidget.cpp b/src/app/ModuleWidget.cpp index 26a3b117..f8f70952 100644 --- a/src/app/ModuleWidget.cpp +++ b/src/app/ModuleWidget.cpp @@ -743,9 +743,7 @@ void ModuleWidget::randomizeAction() { void ModuleWidget::appendDisconnectActions(history::ComplexAction* complexAction) { for (PortWidget* pw : getPorts()) { - for (CableWidget* cw : APP->scene->rack->getCablesOnPort(pw)) { - if (!cw->isComplete()) - continue; + for (CableWidget* cw : APP->scene->rack->getCompleteCablesOnPort(pw)) { // history::CableRemove history::CableRemove* h = new history::CableRemove; h->setCable(cw); @@ -811,7 +809,7 @@ void ModuleWidget::cloneAction(bool cloneCables) { if (cloneCables) { // Clone cables attached to input ports for (PortWidget* pw : getInputs()) { - for (CableWidget* cw : APP->scene->rack->getCablesOnPort(pw)) { + for (CableWidget* cw : APP->scene->rack->getCompleteCablesOnPort(pw)) { // Create cable attached to cloned ModuleWidget's input engine::Cable* clonedCable = new engine::Cable; clonedCable->inputModule = clonedModule; diff --git a/src/app/PortWidget.cpp b/src/app/PortWidget.cpp index 8bccc1bb..468a6532 100644 --- a/src/app/PortWidget.cpp +++ b/src/app/PortWidget.cpp @@ -50,7 +50,7 @@ struct PortTooltip : ui::Tooltip { text += string::f("% .3fV", math::normalizeZero(v)); } // Connected to - std::vector cables = APP->scene->rack->getCablesOnPort(portWidget); + std::vector cables = APP->scene->rack->getCompleteCablesOnPort(portWidget); for (auto it = cables.rbegin(); it != cables.rend(); it++) { CableWidget* cable = *it; PortWidget* otherPw = (portWidget->type == engine::Port::INPUT) ? cable->outputPort : cable->inputPort; @@ -226,7 +226,7 @@ void PortWidget::createContextMenu() { assert(portInfo); menu->addChild(createMenuLabel(portInfo->getFullName())); - std::vector cws = APP->scene->rack->getCablesOnPort(this); + std::vector cws = APP->scene->rack->getCompleteCablesOnPort(this); CableWidget* topCw = cws.empty() ? NULL : cws.back(); menu->addChild(createMenuItem("Delete top cable", RACK_MOD_SHIFT_NAME "+click", diff --git a/src/app/RackWidget.cpp b/src/app/RackWidget.cpp index be7679eb..9e167b4f 100644 --- a/src/app/RackWidget.cpp +++ b/src/app/RackWidget.cpp @@ -1398,6 +1398,21 @@ std::vector RackWidget::getCablesOnPort(PortWidget* port) { return cws; } +std::vector RackWidget::getCompleteCablesOnPort(PortWidget* port) { + assert(port); + std::vector cws; + for (widget::Widget* w : internal->cableContainer->children) { + CableWidget* cw = dynamic_cast(w); + assert(cw); + if (!cw->isComplete()) + continue; + if (cw->inputPort == port || cw->outputPort == port) { + cws.push_back(cw); + } + } + return cws; +} + int RackWidget::getNextCableColorId() { return internal->nextCableColorId;