From fc7da7cbd7e40034c77f387427452ad05a5fd69b Mon Sep 17 00:00:00 2001 From: Kyle Sunderland Date: Wed, 27 Feb 2019 11:24:19 -0500 Subject: [PATCH] BUG: Fix issues with sending vtkMRMLTextNode 1. Check to see that the text node is not empty before attempting to store it in a string. 2. Invoke TextModifiedEvent when SetText is called so that messages are sent when text is modified. See https://discourse.slicer.org/t/problem-using-registeroutgoingmrmlnode-in-slicer-4-10/5942 --- .../MRML/vtkMRMLIGTLConnectorNode.cxx | 31 ++++++++-------- OpenIGTLinkIF/MRML/vtkMRMLTextNode.cxx | 35 +++++++++++++++++++ OpenIGTLinkIF/MRML/vtkMRMLTextNode.h | 2 +- 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/OpenIGTLinkIF/MRML/vtkMRMLIGTLConnectorNode.cxx b/OpenIGTLinkIF/MRML/vtkMRMLIGTLConnectorNode.cxx index a165bce..a757569 100644 --- a/OpenIGTLinkIF/MRML/vtkMRMLIGTLConnectorNode.cxx +++ b/OpenIGTLinkIF/MRML/vtkMRMLIGTLConnectorNode.cxx @@ -187,7 +187,12 @@ unsigned int vtkMRMLIGTLConnectorNode::vtkInternal::AssignOutGoingNodeToDevice(v { igtlioStringDevice* stringDevice = static_cast(device.GetPointer()); vtkMRMLTextNode* textNode = vtkMRMLTextNode::SafeDownCast(node); - igtlioStringConverter::ContentData content = { static_cast(textNode->GetEncoding()), textNode->GetText() }; + std::string text; + if (textNode->GetText()) + { + text = textNode->GetText(); + } + igtlioStringConverter::ContentData content = { static_cast(textNode->GetEncoding()), text }; stringDevice->SetContent(content); modifiedEvent = vtkMRMLTextNode::TextModifiedEvent; } @@ -846,11 +851,11 @@ void vtkMRMLIGTLConnectorNode::ProcessMRMLEvents( vtkObject *caller, unsigned lo { return; } - int n = this->GetNumberOfNodeReferences(this->GetOutgoingNodeReferenceRole()); + int n = this->GetNumberOfNodeReferences(this->GetOutgoingNodeReferenceRole()); for (int i = 0; i < n; i ++) { - const char* id = GetNthNodeReferenceID(this->GetOutgoingNodeReferenceRole(), i); + const char* id = this->GetNthNodeReferenceID(this->GetOutgoingNodeReferenceRole(), i); if (strcmp(node->GetID(), id) == 0) { this->PushNode(node); @@ -1236,7 +1241,7 @@ void vtkMRMLIGTLConnectorNode::OnNodeReferenceAdded(vtkMRMLNodeReference *refere { igtlioDeviceKeyType key; key.name = node->GetName(); - std::vector deviceTypes = GetDeviceTypeFromMRMLNodeType(node->GetNodeTagName()); + std::vector deviceTypes = this->GetDeviceTypeFromMRMLNodeType(node->GetNodeTagName()); for (size_t typeIndex = 0; typeIndex < deviceTypes.size(); typeIndex++) { key.type = deviceTypes[typeIndex]; @@ -1268,8 +1273,8 @@ void vtkMRMLIGTLConnectorNode::OnNodeReferenceAdded(vtkMRMLNodeReference *refere return; } device->SetMessageDirection(igtlioDevice::MESSAGE_DIRECTION_OUT); - unsigned int NodeModifiedEvent = this->Internal->AssignOutGoingNodeToDevice(node, device); - node->AddObserver(NodeModifiedEvent, this, &vtkMRMLIGTLConnectorNode::ProcessIOConnectorEvents); + unsigned int nodeModifiedEvent = this->Internal->AssignOutGoingNodeToDevice(node, device); + node->AddObserver(nodeModifiedEvent, this, &vtkMRMLIGTLConnectorNode::ProcessIOConnectorEvents); // Need to update the events here because observed events are not saved in the scene // for each reference and therefore only the role-default event observers are added. @@ -1280,15 +1285,13 @@ void vtkMRMLIGTLConnectorNode::OnNodeReferenceAdded(vtkMRMLNodeReference *refere int n = this->GetNumberOfNodeReferences(this->GetOutgoingNodeReferenceRole()); for (int i = 0; i < n; i ++) { - const char* id = GetNthNodeReferenceID(this->GetOutgoingNodeReferenceRole(), i); + const char* id = this->GetNthNodeReferenceID(this->GetOutgoingNodeReferenceRole(), i); if (strcmp(node->GetID(), id) == 0) { - vtkIntArray* nodeEvents; - nodeEvents = vtkIntArray::New(); - nodeEvents->InsertNextValue(NodeModifiedEvent); + vtkSmartPointer nodeEvents = vtkSmartPointer::New(); + nodeEvents->InsertNextValue(nodeModifiedEvent); this->SetAndObserveNthNodeReferenceID(this->GetOutgoingNodeReferenceRole(), i, node->GetID(),nodeEvents ); - nodeEvents->Delete(); break; } } @@ -1483,7 +1486,7 @@ int vtkMRMLIGTLConnectorNode::RegisterOutgoingMRMLNode(vtkMRMLNode* node, const int n = this->GetNumberOfNodeReferences(this->GetOutgoingNodeReferenceRole()); for (int i = 0; i < n; i ++) { - const char* id = GetNthNodeReferenceID(this->GetOutgoingNodeReferenceRole(), i); + const char* id = this->GetNthNodeReferenceID(this->GetOutgoingNodeReferenceRole(), i); if (strcmp(node->GetID(), id) == 0) { // Alredy on the list. Remove it. @@ -1497,7 +1500,7 @@ int vtkMRMLIGTLConnectorNode::RegisterOutgoingMRMLNode(vtkMRMLNode* node, const igtlioDevicePointer device = NULL; igtlioDeviceKeyType key; key.name = node->GetName(); - std::vector deviceTypes = GetDeviceTypeFromMRMLNodeType(node->GetNodeTagName()); + std::vector deviceTypes = this->GetDeviceTypeFromMRMLNodeType(node->GetNodeTagName()); for (size_t typeIndex = 0; typeIndex < deviceTypes.size(); typeIndex++) { key.type = deviceTypes[typeIndex]; @@ -1528,7 +1531,7 @@ int vtkMRMLIGTLConnectorNode::RegisterOutgoingMRMLNode(vtkMRMLNode* node, const int n = this->GetNumberOfNodeReferences(this->GetOutgoingNodeReferenceRole()); for (int i = 0; i < n; i ++) { - const char* id = GetNthNodeReferenceID(this->GetOutgoingNodeReferenceRole(), i); + const char* id = this->GetNthNodeReferenceID(this->GetOutgoingNodeReferenceRole(), i); if (strcmp(node->GetID(), id) == 0) { // Alredy on the list. Remove it. diff --git a/OpenIGTLinkIF/MRML/vtkMRMLTextNode.cxx b/OpenIGTLinkIF/MRML/vtkMRMLTextNode.cxx index ee5a7bf..ac9933b 100644 --- a/OpenIGTLinkIF/MRML/vtkMRMLTextNode.cxx +++ b/OpenIGTLinkIF/MRML/vtkMRMLTextNode.cxx @@ -18,6 +18,41 @@ vtkMRMLTextNode::~vtkMRMLTextNode() this->SetText(NULL); } +//---------------------------------------------------------------------------- +void vtkMRMLTextNode::SetText(const char* text) +{ + vtkDebugMacro(<< this->GetClassName() << " (" << this << "): setting Text to " << (text ? text : "(null)")); \ + if (this->Text == nullptr && text == nullptr) + { + return; + } + if (this->Text && text && (!strcmp(this->Text, text))) + { + return; + } + + delete[] this->Text; + if (text) + { + size_t n = strlen(text) + 1; + char *cp1 = new char[n]; + const char *cp2 = (text); + this->Text = cp1; + do + { + *cp1++ = *cp2++; + } + while (--n); + } + else + { + this->Text = nullptr; + } + + this->InvokeCustomModifiedEvent(vtkMRMLTextNode::TextModifiedEvent); + this->Modified(); +} + //---------------------------------------------------------------------------- void vtkMRMLTextNode::ReadXMLAttributes(const char** atts) { diff --git a/OpenIGTLinkIF/MRML/vtkMRMLTextNode.h b/OpenIGTLinkIF/MRML/vtkMRMLTextNode.h index 30f6145..1e856bb 100644 --- a/OpenIGTLinkIF/MRML/vtkMRMLTextNode.h +++ b/OpenIGTLinkIF/MRML/vtkMRMLTextNode.h @@ -48,7 +48,7 @@ class VTK_SLICER_OPENIGTLINKIF_MODULE_MRML_EXPORT vtkMRMLTextNode : public vtkM /// /// Set text encoding - vtkSetStringMacro(Text); + virtual void SetText(const char* text); vtkGetStringMacro(Text); ///