Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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.