Medical Imaging Interaction Toolkit  2018.4.99-f51274ea
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 (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
14 #include <itkCommand.h>
15 #include <mitkBaseProperty.h>
16 #include <mitkPropertyList.h>
17 
18 namespace mitk
19 {
21  : m_DataStorage(nullptr), m_Predicate(nullptr), m_SelfCall(false), m_AutoAddNodes(_AutoAddNodes)
22  {
23  this->SetDataStorage(_DataStorage);
24  }
25 
27  mitk::NodePredicateBase *_Predicate,
28  bool _AutoAddNodes)
29  : m_DataStorage(nullptr), m_Predicate(_Predicate), m_SelfCall(false), m_AutoAddNodes(_AutoAddNodes)
30  {
31  this->SetDataStorage(_DataStorage);
32  }
33 
35  {
36  // kick datastorage and all nodes and all listeners
37  this->SetDataStorage(nullptr);
38  }
39 
42  unsigned int DataStorageSelection::GetSize() const { return m_Nodes.size(); }
45  {
46  return (index < m_Nodes.size()) ? m_Nodes.at(index) : nullptr;
47  }
48 
49  std::vector<mitk::DataNode *> DataStorageSelection::GetNodes() const { return m_Nodes; }
52  {
53  this->RemoveAllNodes();
54  this->AddNode(node);
55  return *this;
56  }
57 
59  {
60  *this = node.GetPointer();
61  return *this;
62  }
63 
65  {
66  // only proceed if we have a new datastorage
67  if (m_DataStorage != _DataStorage)
68  {
69  // if a data storage was set before remove old event listeners
70  if (m_DataStorage != nullptr)
71  {
72  if (m_AutoAddNodes)
75 
79 
80  m_DataStorage->RemoveObserver(m_DataStorageDeletedTag);
82  }
83 
84  // set new data storage
85  m_DataStorage = _DataStorage;
86 
87  // if new storage is not 0 subscribe for events
88  if (m_DataStorage != nullptr)
89  {
90  // subscribe for node added/removed events
91  if (m_AutoAddNodes)
94 
98 
99  itk::MemberCommand<DataStorageSelection>::Pointer ObjectChangedCommand =
100  itk::MemberCommand<DataStorageSelection>::New();
101  ObjectChangedCommand->SetCallbackFunction(this, &DataStorageSelection::ObjectChanged);
102 
103  m_DataStorageDeletedTag = m_DataStorage->AddObserver(itk::DeleteEvent(), ObjectChangedCommand);
104  }
105  // Reset model (even if datastorage is 0->will be checked in Reset())
106  this->Reset();
107  }
108  }
109 
111  {
112  // ensure that a new predicate is set in order to avoid unnecessary changed events
113  if (m_Predicate != _Predicate)
114  {
115  m_Predicate = _Predicate;
116  this->Reset();
117  }
118  }
119 
121  {
122  // garantuee no recursions when a new node event is thrown
123  if (m_SelfCall)
124  return;
125 
126  // if we have a predicate, check node against predicate first
127  if (m_Predicate.IsNotNull() && !m_Predicate->CheckNode(node))
128  return;
129 
130  // no duplicates
131  if (std::find(m_Nodes.begin(), m_Nodes.end(), node) != m_Nodes.end())
132  return;
133 
134  auto *nonConstNode = const_cast<mitk::DataNode *>(node);
135  // add listener
136  this->AddListener(nonConstNode);
137 
138  // add node
139  m_Nodes.push_back(nonConstNode);
140 
141  NodeAdded.Send(node);
142  }
143 
145  {
146  if (m_SelfCall)
147  return;
148 
149  // find corresponding node
150  auto nodeIt = std::find(m_Nodes.begin(), m_Nodes.end(), node);
151 
152  if (nodeIt == m_Nodes.end())
153  return;
154 
155  auto *nonConstNode = const_cast<mitk::DataNode *>(node);
156  // add listener
157  this->RemoveListener(nonConstNode);
158 
159  // remove node
160  m_Nodes.erase(nodeIt);
161 
162  NodeRemoved.Send(node);
163  }
164 
166  {
167  // remove all nodes now (dont use iterators because removing elements
168  // would invalidate the iterator)
169  // start at the last element: first in, last out
170  unsigned int i = m_Nodes.size();
171  while (!m_Nodes.empty())
172  {
173  --i;
174  this->RemoveNode(m_Nodes.at(i));
175  }
176  }
177 
178  void DataStorageSelection::ObjectChanged(const itk::Object *caller, const itk::EventObject & /*event*/)
179  {
180  if (m_SelfCall)
181  return;
182 
183  /*
184  const itk::DeleteEvent* delEvent = 0;
185  const itk::ModifiedEvent* modifiedEvent = dynamic_cast<const itk::ModifiedEvent*>(&event);
186  if(!modifiedEvent)
187  delEvent = dynamic_cast<const itk::DeleteEvent*>(&event);
188  */
189  const mitk::BaseProperty *prop = nullptr;
190  const mitk::PropertyList *propList = nullptr;
191  const auto *node = dynamic_cast<const mitk::DataNode *>(caller);
192  if (!node)
193  {
194  if ((prop = dynamic_cast<const mitk::BaseProperty *>(caller)))
195  {
196  node = this->FindNode(prop);
197  }
198  else if ((propList = dynamic_cast<const mitk::PropertyList *>(caller)))
199  {
200  node = this->FindNode(propList);
201  }
202  else if (dynamic_cast<const mitk::DataStorage *>(caller))
203  {
204  this->SetDataStorage(nullptr);
205  }
206  }
207 
208  if (prop && node)
209  {
210  PropertyChanged.Send(node, prop);
211  }
212  else if (node)
213  {
214  NodeChanged.Send(node);
215  }
216  }
217 
218  //# protected
220  {
221  mitk::DataNode *node = nullptr;
222  for (auto it = m_Nodes.begin(); it != m_Nodes.end(); ++it)
223  {
224  for (auto it2 = (*it)->GetPropertyList()->GetMap()->begin(); it2 != (*it)->GetPropertyList()->GetMap()->end();
225  ++it2)
226  {
227  if (it2->second == prop)
228  {
229  node = *it;
230  break;
231  }
232  }
233  }
234  return node;
235  }
236 
238  {
239  mitk::DataNode *node = nullptr;
240  for (auto it = m_Nodes.begin(); it != m_Nodes.end(); ++it)
241  {
242  if ((*it)->GetPropertyList() == propList)
243  {
244  node = *it;
245  break;
246  }
247  }
248  return node;
249  }
250 
252  {
253  this->RemoveAllNodes();
254  // the whole reset depends on the fact if a data storage is set or not
255  if (m_DataStorage)
256  {
257  mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = nullptr;
258  if (m_AutoAddNodes && m_Predicate.IsNotNull())
259  // get subset
260  _NodeSet = m_DataStorage->GetSubset(m_Predicate);
261  // if predicate is nullptr, select all nodes
262  else if (m_AutoAddNodes)
263  {
264  _NodeSet = m_DataStorage->GetAll();
265  }
266  else
267  return;
268  // finally add all nodes to the model
269  for (auto it = _NodeSet->begin(); it != _NodeSet->end(); it++)
270  {
271  // save node
272  this->AddNode(*it);
273  }
274  }
275  }
276 
278  {
279  // remove node listener
280  node->RemoveObserver(m_NodeModifiedObserverTags[node]);
281  m_NodeModifiedObserverTags.erase(node);
282 
283  // remove propertylist listener
284  mitk::PropertyList *propList = node->GetPropertyList();
285  propList->RemoveObserver(m_PropertyListModifiedObserverTags[propList]);
286  m_PropertyListModifiedObserverTags.erase(propList);
287  propList->RemoveObserver(m_PropertyListDeletedObserverTags[propList]);
288  m_PropertyListDeletedObserverTags.erase(propList);
289 
290  mitk::BaseProperty *prop = nullptr;
291  // do the same for each property
292  for (auto it = propList->GetMap()->begin(); it != propList->GetMap()->end(); ++it)
293  {
294  prop = it->second;
295  prop->RemoveObserver(m_PropertyModifiedObserverTags[prop]);
296  m_PropertyModifiedObserverTags.erase(prop);
297  prop->RemoveObserver(m_PropertyDeletedObserverTags[prop]);
298  m_PropertyDeletedObserverTags.erase(prop);
299  }
300  }
301 
303  {
304  // node listener
305  itk::MemberCommand<DataStorageSelection>::Pointer ObjectChangedCommand =
306  itk::MemberCommand<DataStorageSelection>::New();
307  ObjectChangedCommand->SetCallbackFunction(this, &DataStorageSelection::ObjectChanged);
308 
309  m_NodeModifiedObserverTags[node] = node->AddObserver(itk::ModifiedEvent(), ObjectChangedCommand);
310 
311  // create propertylist listener
312  mitk::PropertyList *propList = node->GetPropertyList();
313  m_PropertyListModifiedObserverTags[propList] = propList->AddObserver(itk::ModifiedEvent(), ObjectChangedCommand);
314  m_PropertyListDeletedObserverTags[propList] = propList->AddObserver(itk::DeleteEvent(), ObjectChangedCommand);
315 
316  mitk::BaseProperty *prop = nullptr;
317  // do the same for each property
318  for (auto it = propList->GetMap()->begin(); it != propList->GetMap()->end(); ++it)
319  {
320  prop = it->second;
321  m_PropertyModifiedObserverTags[prop] = prop->AddObserver(itk::ModifiedEvent(), ObjectChangedCommand);
322  m_PropertyDeletedObserverTags[prop] = prop->AddObserver(itk::ModifiedEvent(), ObjectChangedCommand);
323  }
324  }
325 }
virtual void ObjectChanged(const itk::Object *caller, const itk::EventObject &event)
DataStorageSelection & operator=(mitk::DataNode *node)
virtual void RemoveNode(const mitk::DataNode *node)
Data management class that handles &#39;was created by&#39; relations.
mitk::DataNode::Pointer FindNode(const mitk::BaseProperty *prop) const
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.
std::vector< mitk::DataNode * > GetNodes() const
void Send(T t, U u)
Definition: mitkMessage.h:630
void AddListener(mitk::DataNode *node)
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
std::map< mitk::BaseProperty *, unsigned long > m_PropertyModifiedObserverTags
Maps a property to a modified observer tag.
DataStorageSelection(mitk::DataStorage *_DataStorage, bool _AutoAddNodes)
SetOfObjects::ConstPointer GetSubset(const NodePredicateBase *condition) const
returns a set of data objects that meet the given condition(s)
void AddListener(const AbstractDelegate &delegate) const
Definition: mitkMessage.h:374
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
mitk::NodePredicateBase::Pointer GetPredicate() const
mitk::PropertyList * GetPropertyList(const mitk::BaseRenderer *renderer=nullptr) const
Get the PropertyList of the renderer. If renderer is nullptr, the BaseRenderer-independent PropertyLi...
DataStorageEvent RemoveNodeEvent
RemoveEvent is emitted directly before a node is removed from the DataStorage.
void RemoveListener(const AbstractDelegate &delegate) const
Definition: mitkMessage.h:393
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.
Class for nodes of the DataTree.
Definition: mitkDataNode.h:57
mitk::DataStorage::Pointer GetDataStorage() const
const PropertyMap * GetMap() const
mitk::DataNode::Pointer GetNode() const