Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkDataStorageSelection.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
18 #include <itkCommand.h>
19 #include <mitkBaseProperty.h>
20 #include <mitkPropertyList.h>
21 
22 namespace mitk
23 {
25  : m_DataStorage(nullptr), m_Predicate(nullptr), m_SelfCall(false), m_AutoAddNodes(_AutoAddNodes)
26  {
27  this->SetDataStorage(_DataStorage);
28  }
29 
31  mitk::NodePredicateBase *_Predicate,
32  bool _AutoAddNodes)
33  : m_DataStorage(nullptr), m_Predicate(_Predicate), m_SelfCall(false), m_AutoAddNodes(_AutoAddNodes)
34  {
35  this->SetDataStorage(_DataStorage);
36  }
37 
39  {
40  // kick datastorage and all nodes and all listeners
41  this->SetDataStorage(nullptr);
42  }
43 
46  unsigned int DataStorageSelection::GetSize() const { return m_Nodes.size(); }
49  {
50  return (index < m_Nodes.size()) ? m_Nodes.at(index) : nullptr;
51  }
52 
53  std::vector<mitk::DataNode *> DataStorageSelection::GetNodes() const { return m_Nodes; }
56  {
57  this->RemoveAllNodes();
58  this->AddNode(node);
59  return *this;
60  }
61 
63  {
64  *this = node.GetPointer();
65  return *this;
66  }
67 
69  {
70  // only proceed if we have a new datastorage
71  if (m_DataStorage != _DataStorage)
72  {
73  // if a data storage was set before remove old event listeners
74  if (m_DataStorage != nullptr)
75  {
76  if (m_AutoAddNodes)
79 
83 
84  m_DataStorage->RemoveObserver(m_DataStorageDeletedTag);
86  }
87 
88  // set new data storage
89  m_DataStorage = _DataStorage;
90 
91  // if new storage is not 0 subscribe for events
92  if (m_DataStorage != nullptr)
93  {
94  // subscribe for node added/removed events
95  if (m_AutoAddNodes)
98 
102 
105  ObjectChangedCommand->SetCallbackFunction(this, &DataStorageSelection::ObjectChanged);
106 
107  m_DataStorageDeletedTag = m_DataStorage->AddObserver(itk::DeleteEvent(), ObjectChangedCommand);
108  }
109  // Reset model (even if datastorage is 0->will be checked in Reset())
110  this->Reset();
111  }
112  }
113 
115  {
116  // ensure that a new predicate is set in order to avoid unnecessary changed events
117  if (m_Predicate != _Predicate)
118  {
119  m_Predicate = _Predicate;
120  this->Reset();
121  }
122  }
123 
125  {
126  // garantuee no recursions when a new node event is thrown
127  if (m_SelfCall)
128  return;
129 
130  // if we have a predicate, check node against predicate first
131  if (m_Predicate.IsNotNull() && !m_Predicate->CheckNode(node))
132  return;
133 
134  // no duplicates
135  if (std::find(m_Nodes.begin(), m_Nodes.end(), node) != m_Nodes.end())
136  return;
137 
138  mitk::DataNode *nonConstNode = const_cast<mitk::DataNode *>(node);
139  // add listener
140  this->AddListener(nonConstNode);
141 
142  // add node
143  m_Nodes.push_back(nonConstNode);
144 
145  NodeAdded.Send(node);
146  }
147 
149  {
150  if (m_SelfCall)
151  return;
152 
153  // find corresponding node
154  auto nodeIt = std::find(m_Nodes.begin(), m_Nodes.end(), node);
155 
156  if (nodeIt == m_Nodes.end())
157  return;
158 
159  mitk::DataNode *nonConstNode = const_cast<mitk::DataNode *>(node);
160  // add listener
161  this->RemoveListener(nonConstNode);
162 
163  // remove node
164  m_Nodes.erase(nodeIt);
165 
166  NodeRemoved.Send(node);
167  }
168 
170  {
171  // remove all nodes now (dont use iterators because removing elements
172  // would invalidate the iterator)
173  // start at the last element: first in, last out
174  unsigned int i = m_Nodes.size();
175  while (!m_Nodes.empty())
176  {
177  --i;
178  this->RemoveNode(m_Nodes.at(i));
179  }
180  }
181 
182  void DataStorageSelection::ObjectChanged(const itk::Object *caller, const itk::EventObject & /*event*/)
183  {
184  if (m_SelfCall)
185  return;
186 
187  /*
188  const itk::DeleteEvent* delEvent = 0;
189  const itk::ModifiedEvent* modifiedEvent = dynamic_cast<const itk::ModifiedEvent*>(&event);
190  if(!modifiedEvent)
191  delEvent = dynamic_cast<const itk::DeleteEvent*>(&event);
192  */
193  const mitk::BaseProperty *prop = nullptr;
194  const mitk::PropertyList *propList = nullptr;
195  const mitk::DataNode *node = dynamic_cast<const mitk::DataNode *>(caller);
196  if (!node)
197  {
198  if ((prop = dynamic_cast<const mitk::BaseProperty *>(caller)))
199  {
200  node = this->FindNode(prop);
201  }
202  else if ((propList = dynamic_cast<const mitk::PropertyList *>(caller)))
203  {
204  node = this->FindNode(propList);
205  }
206  else if (dynamic_cast<const mitk::DataStorage *>(caller))
207  {
208  this->SetDataStorage(nullptr);
209  }
210  }
211 
212  if (prop && node)
213  {
214  PropertyChanged.Send(node, prop);
215  }
216  else if (node)
217  {
218  NodeChanged.Send(node);
219  }
220  }
221 
222  //# protected
224  {
225  mitk::DataNode *node = nullptr;
226  for (auto it = m_Nodes.begin(); it != m_Nodes.end(); ++it)
227  {
228  for (auto it2 = (*it)->GetPropertyList()->GetMap()->begin(); it2 != (*it)->GetPropertyList()->GetMap()->end();
229  ++it2)
230  {
231  if (it2->second == prop)
232  {
233  node = *it;
234  break;
235  }
236  }
237  }
238  return node;
239  }
240 
242  {
243  mitk::DataNode *node = nullptr;
244  for (auto it = m_Nodes.begin(); it != m_Nodes.end(); ++it)
245  {
246  if ((*it)->GetPropertyList() == propList)
247  {
248  node = *it;
249  break;
250  }
251  }
252  return node;
253  }
254 
256  {
257  this->RemoveAllNodes();
258  // the whole reset depends on the fact if a data storage is set or not
259  if (m_DataStorage)
260  {
262  if (m_AutoAddNodes && m_Predicate.IsNotNull())
263  // get subset
264  _NodeSet = m_DataStorage->GetSubset(m_Predicate);
265  // if predicate is NULL, select all nodes
266  else if (m_AutoAddNodes)
267  {
268  _NodeSet = m_DataStorage->GetAll();
269  }
270  else
271  return;
272  // finally add all nodes to the model
273  for (auto it = _NodeSet->begin(); it != _NodeSet->end(); it++)
274  {
275  // save node
276  this->AddNode(*it);
277  }
278  }
279  }
280 
282  {
283  // remove node listener
284  node->RemoveObserver(m_NodeModifiedObserverTags[node]);
285  m_NodeModifiedObserverTags.erase(node);
286 
287  // remove propertylist listener
288  mitk::PropertyList *propList = node->GetPropertyList();
289  propList->RemoveObserver(m_PropertyListModifiedObserverTags[propList]);
290  m_PropertyListModifiedObserverTags.erase(propList);
291  propList->RemoveObserver(m_PropertyListDeletedObserverTags[propList]);
292  m_PropertyListDeletedObserverTags.erase(propList);
293 
294  mitk::BaseProperty *prop = nullptr;
295  // do the same for each property
296  for (auto it = propList->GetMap()->begin(); it != propList->GetMap()->end(); ++it)
297  {
298  prop = it->second;
299  prop->RemoveObserver(m_PropertyModifiedObserverTags[prop]);
300  m_PropertyModifiedObserverTags.erase(prop);
301  prop->RemoveObserver(m_PropertyDeletedObserverTags[prop]);
302  m_PropertyDeletedObserverTags.erase(prop);
303  }
304  }
305 
307  {
308  // node listener
311  ObjectChangedCommand->SetCallbackFunction(this, &DataStorageSelection::ObjectChanged);
312 
313  m_NodeModifiedObserverTags[node] = node->AddObserver(itk::ModifiedEvent(), ObjectChangedCommand);
314 
315  // create propertylist listener
316  mitk::PropertyList *propList = node->GetPropertyList();
317  m_PropertyListModifiedObserverTags[propList] = propList->AddObserver(itk::ModifiedEvent(), ObjectChangedCommand);
318  m_PropertyListDeletedObserverTags[propList] = propList->AddObserver(itk::DeleteEvent(), ObjectChangedCommand);
319 
320  mitk::BaseProperty *prop = nullptr;
321  // do the same for each property
322  for (auto it = propList->GetMap()->begin(); it != propList->GetMap()->end(); ++it)
323  {
324  prop = it->second;
325  m_PropertyModifiedObserverTags[prop] = prop->AddObserver(itk::ModifiedEvent(), ObjectChangedCommand);
326  m_PropertyDeletedObserverTags[prop] = prop->AddObserver(itk::ModifiedEvent(), ObjectChangedCommand);
327  }
328  }
329 }
void RemoveListener(const AbstractDelegate &delegate) const
Definition: mitkMessage.h:397
virtual void ObjectChanged(const itk::Object *caller, const itk::EventObject &event)
DataStorageSelection & operator=(mitk::DataNode *node)
virtual void RemoveNode(const mitk::DataNode *node)
void AddListener(const AbstractDelegate &delegate) const
Definition: mitkMessage.h:378
mitk::PropertyList * GetPropertyList(const mitk::BaseRenderer *renderer=nullptr) const
Get the PropertyList of the renderer. If renderer is NULL, the BaseRenderer-independent PropertyList ...
Data management class that handles 'was created by' relations.
itk::SmartPointer< Self > Pointer
void Send(T t)
Definition: mitkMessage.h:606
DataCollection - Class to facilitate loading/accessing structured data.
std::map< mitk::BaseProperty *, unsigned long > m_PropertyDeletedObserverTags
Maps a property to a delete observer tag.
Key-value list holding instances of BaseProperty.
mitk::DataNode::Pointer FindNode(const mitk::BaseProperty *prop) const
itk::SmartPointer< const Self > ConstPointer
void AddListener(mitk::DataNode *node)
std::vector< mitk::DataNode * > GetNodes() const
mitk::DataNode::Pointer GetNode() const
virtual void SetDataStorage(mitk::DataStorage *_DataStorage)
virtual SetOfObjects::ConstPointer GetAll() const =0
returns a set of all data objects that are stored in the data storage
Abstract base class for properties.
mitk::DataStorage::Pointer m_DataStorage
SetOfObjects::ConstPointer GetSubset(const NodePredicateBase *condition) const
returns a set of data objects that meet the given condition(s)
std::map< mitk::BaseProperty *, unsigned long > m_PropertyModifiedObserverTags
Maps a property to a modified observer tag.
DataStorageSelection(mitk::DataStorage *_DataStorage, bool _AutoAddNodes)
std::map< mitk::PropertyList *, unsigned long > m_PropertyListModifiedObserverTags
Maps a propertylist to a modified observer tag.
DataStorageEvent AddNodeEvent
AddEvent is emitted whenever a new node has been added to the DataStorage.
Message2< const mitk::DataNode *, const mitk::BaseProperty * > PropertyChanged
DataStorageEvent RemoveNodeEvent
RemoveEvent is emitted directly before a node is removed from the DataStorage.
mitk::DataStorage::Pointer GetDataStorage() const
virtual void SetPredicate(mitk::NodePredicateBase *_Predicate)
void RemoveListener(mitk::DataNode *node)
Interface for evaluation conditions used in the DataStorage class GetSubset() method.
std::vector< mitk::DataNode * > m_Nodes
virtual void AddNode(const mitk::DataNode *node)
mitk::NodePredicateBase::Pointer m_Predicate
std::map< mitk::DataNode *, unsigned long > m_NodeModifiedObserverTags
Maps a node to a modified observer tag.
std::map< mitk::PropertyList *, unsigned long > m_PropertyListDeletedObserverTags
Maps a propertylist to a delete observer tag.
mitk::NodePredicateBase::Pointer GetPredicate() const
Class for nodes of the DataTree.
Definition: mitkDataNode.h:66
const PropertyMap * GetMap() const
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.