Hi Alex,

just an addition to Stefan's comment. He has already pointed you in the right 
direction. Going that path one challenge will be, that the Modified events are 
triggered *after* the modification. So you will know that a node as a changed 
name, but you will only be able to directly query the new name. The old name is 
already lost then. So you would need to somewhere else store the last known 
node names additionally.

Before you following the path let me add some comments/questions:
1. What is the purpose of the name property in your workflow? Why do you need 
to control it? Is it used as an Identifier? If so, wouldn't be the 
Identifiable-Interface a better option?
2. What is the purpose of the Data Manager plugin in in your workflow? Do you 
need it at all (we currently migrating more and more views to work without the 
Data Manager but with DataStorageInspectors and SelectionWidgets)? 

Best Ralf

________________________________
Date: Tue, 1 Sep 2020 07:21:16 +0000
From: "Dinkelacker, Stefan" <s.dinkelac...@dkfz-heidelberg.de>
To: Alex Melville <amelv...@umich.edu>,
        "mitk-users@lists.sourceforge.net" <mitk-users@lists.sourceforge.net>
Subject: Re: [mitk-users] Event to handle Data Manager node renames
Message-ID: <1598944874273.67...@dkfz-heidelberg.de>
Content-Type: text/plain; charset="utf-8"

?Hi Alex,


I do not know your context, e.g. if you want to modify MITK code like the Data 
Manager plugin, do not want to touch MITK code, or want to write your own 
application from scratch based on or not based on BlueBerry. But in general, 
you are on the right track with ITK events. You want to hook into the name 
property which also is an ITK object and which is the actual location the name 
is eventually stored (single source of truth). I didn't check but you should be 
able to also hook into the data storage to easily get notified when a new data 
node was added or removed from the storage. In these cases you want to 
add/remove an observer to that data at least for the modified event of the name 
property.


Best,

Stefan

________________________________
Von: Alex Melville <amelv...@umich.edu>
Gesendet: Montag, 31. August 2020 17:06
An: mitk-users@lists.sourceforge.net
Betreff: Re: [mitk-users] Event to handle Data Manager node renames

Hello, I still haven't been able to find a solution for this. I figured I'd try 
again since there weren't any replies, I'll post my progress on investigating 
this in case this helps somebody.

It looks like if there is a way to do this, it would involve hooking into 
something on the ITK side.

A possible workaround for this would be to have some kind of periodic checker 
function that goes through everything in the treeview and looks for node names 
that changed and roll back invalid / duplicate names, but I would rather not do 
that.

MITK\Modules\Core\src\DataManagement\mitkDataStorage.cpp
void mitk::DataStorage::OnNodeModifiedOrDeleted(const itk::Object *caller, 
const itk::EventObject &event) {  if (m_BlockNodeModifiedEvents) return;

 const mitk::DataNode *_Node = dynamic_cast<const mitk::DataNode *>(caller);  
if (_Node)  { const itk::ModifiedEvent *modEvent = dynamic_cast<const 
itk::ModifiedEvent *>(&event); if (modEvent)  ChangedNodeEvent.Send(_Node); 
else  DeleteNodeEvent.Send(_Node);  }

in MITK\Modules\Core\src\DataManagement\mitkDataStorage.cpp
void mitk::DataStorage::AddListeners(const mitk::DataNode *_Node) {  
itk::MutexLockHolder<itk::SimpleFastMutexLock> locked(m_MutexOne);  // node 
must not be 0 and must not be yet registered  mitk::DataNode *NonConstNode = 
const_cast<mitk::DataNode *>(_Node);  if (_Node && 
m_NodeModifiedObserverTags.find(NonConstNode) == 
m_NodeModifiedObserverTags.end())  { 
itk::MemberCommand<mitk::DataStorage>::Pointer nodeModifiedCommand = 
itk::MemberCommand<mitk::DataStorage>::New();
nodeModifiedCommand->SetCallbackFunction(this, 
nodeModifiedCommand->&mitk::DataStorage::OnNodeModifiedOrDeleted);
m_NodeModifiedObserverTags[NonConstNode] = 
NonConstNode->AddObserver(itk::ModifiedEvent(), nodeModifiedCommand);

itk::MemberCommand<mitk::DataStorage>::Pointer interactorChangedCommand =  
itk::MemberCommand<mitk::DataStorage>::New();
interactorChangedCommand->SetCallbackFunction(this, 
interactorChangedCommand->&mitk::DataStorage::OnNodeInteractorChanged);

m_NodeInteractorChangedObserverTags[NonConstNode] = 
NonConstNode->AddObserver(mitk::DataNode::InteractorChangedEvent(), 
interactorChangedCommand);

// add itk delete listener on datastorage 
itk::MemberCommand<mitk::DataStorage>::Pointer deleteCommand = 
itk::MemberCommand<mitk::DataStorage>::New();
deleteCommand->SetCallbackFunction(this, 
deleteCommand->&mitk::DataStorage::OnNodeModifiedOrDeleted);
// add observer
m_NodeDeleteObserverTags[NonConstNode] = 
NonConstNode->AddObserver(itk::DeleteEvent(), deleteCommand);  } } Now we're 
getting into ITK.

Looks like maybe I should look at itk::ModifiedEvent()

Seems like 
Modules/Core/Common/src/itkEventObject.cxx:70:itkEventMacroDefinition(ModifiedEvent,
 AnyEvent)

#define itkEventMacroDeclaration(classname, super)                   \
 /** \class classname */                                            \
 class ITKEvent_EXPORT classname:public super                       \
 {                                                                  \
public:                                                              \
typedef classname Self;                                          \
typedef super     Superclass;                                    \
classname();                                                     \
classname(const Self &s);                                        \
virtual ~classname();                                            \
virtual const char *GetEventName() const;                        \
virtual bool CheckEvent(const::itk::EventObject * e) const;      \
virtual ::itk::EventObject *MakeObject() const;                   \
private:                                                             \
void operator=(const Self &);                                    \
 };

#define itkEventMacroDefinition(classname, super)                           \
classname::classname() {}                                                   \
classname::classname(const classname &s):super(s){};                        \
classname::~classname() {}                                                  \
const char * classname::GetEventName() const { return #classname; }          \
bool classname::CheckEvent(const::itk::EventObject * e) const               \
 { return ( dynamic_cast< const classname * >( e ) != ITK_NULLPTR ); } \ 
::itk::EventObject *classname::MakeObject() const { return new classname; } \

I guess most of the interesting stuff is in the EventObject class, but it seems 
like this just serves as an intermediary for some other code

ITK_4.9.0>grep ModifiedEvent * -RinF
Modules/Core/Common/include/itkEventObject.h:179:itkEventMacroDeclaration(ModifiedEvent,
 AnyEvent)

Modules/Core/Common/include/itkTreeChangeEvent.h:33:class 
TreeChangeEvent:public ModifiedEvent
Modules/Core/Common/include/itkTreeChangeEvent.h:39:  typedef ModifiedEvent   
Superclass;
Modules/Core/Common/include/itkTreeChangeEvent.h:65:  TreeChangeEvent(const 
Self & s):itk::ModifiedEvent(s) {}

Modules/Core/Common/src/itkEventObject.cxx:70:itkEventMacroDefinition(ModifiedEvent,
 AnyEvent)
Modules/Core/Common/src/itkObject.cxx:390:  InvokeEvent( ModifiedEvent() );
Modules/Core/Common/wrapping/ITKCommonBase.wrap:13:itk_wrap_simple_class("itk::ModifiedEvent")

Modules/Filtering/LabelMap/include/itkLabelMap.h:472:                    bool 
iEmitModifiedEvent );

Modules/Filtering/LabelMap/include/itkLabelMap.hxx:256:        bool 
emitModifiedEvent = ( iLabel == m_BackgroundValue );
Modules/Filtering/LabelMap/include/itkLabelMap.hxx:257:        
this->RemovePixel( tempIt, idx, emitModifiedEvent );
Modules/Filtering/LabelMap/include/itkLabelMap.hxx:326:              bool 
iEmitModifiedEvent )
Modules/Filtering/LabelMap/include/itkLabelMap.hxx:337:      if( 
iEmitModifiedEvent )
Modules/Filtering/LabelMap/include/itkLabelMap.hxx:359:  bool emitModifiedEvent 
= true;
Modules/Filtering/LabelMap/include/itkLabelMap.hxx:360:  RemovePixel( it, idx, 
emitModifiedEvent );

Modules/ThirdParty/GDCM/src/gdcm/Source/Common/gdcmEvent.h:91:gdcmEventMacro( 
ModifiedEvent      , AnyEvent );

Doesn't seem like this is used anywhere. Maybe that's just something that's 
treated as a ModifiedEvent, need to figure out where the event is created.

Let me know if you have any suggestions, thanks,

- Alex

On Wed, Aug 26, 2020 at 11:26 AM Alex Melville 
<amelv...@umich.edu<mailto:amelv...@umich.edu>> wrote:
Hello,

Using the MITK sample project as an example, I would like to add an event 
handler for when a node in the Data Manager is renamed by double clicking on it.

I would like to be able to:
- Have our program do something in response to the node being renamed
- Show a message and cancel the renaming operation if it can't be used (e.g., 
if the name is already in use, or invalid)

I would also like this same behavior to happen when the "name" property of a 
node is edited in the "Properties" window, I notice that they seem to be tied 
together, so this might be the same event.

If this isn't possible, I would also be OK with disabling this double click 
rename functionality completely, and the property tree rename too, and using my 
own custom UI instead for renaming nodes.

I've been looking through the source, and I've seen some things like 
ModifiedEvent in itk that sound promising, but I am having trouble locating 
exactly which object / event to hook into.

Thanks,

- Alex
-------------- next part --------------
An HTML attachment was scrubbed...

------------------------------



------------------------------

Subject: Digest Footer

_______________________________________________
mitk-users mailing list
mitk-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mitk-users


------------------------------

End of mitk-users Digest, Vol 172, Issue 1
******************************************


_______________________________________________
mitk-users mailing list
mitk-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mitk-users

Reply via email to