Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkToolManager.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 
17 #include "mitkToolManager.h"
18 #include "mitkCoreObjectFactory.h"
19 
20 #include <itkCommand.h>
21 #include <itkObjectFactoryBase.h>
22 
23 #include <list>
24 
26 #include "mitkSegTool2D.h"
27 
28 #include "usGetModuleContext.h"
29 #include "usModuleContext.h"
30 
32  : m_ActiveTool(nullptr), m_ActiveToolID(-1), m_RegisteredClients(0), m_DataStorage(storage)
33 {
34  CoreObjectFactory::GetInstance(); // to make sure a CoreObjectFactory was instantiated (and in turn, possible tools
35  // are registered) - bug 1029
36  this->InitializeTools();
37 }
38 
40 {
41  for (DataVectorType::iterator dataIter = m_WorkingData.begin(); dataIter != m_WorkingData.end(); ++dataIter)
42  (*dataIter)->RemoveObserver(m_WorkingDataObserverTags[(*dataIter)]);
43 
44  if (this->GetDataStorage() != nullptr)
45  this->GetDataStorage()->RemoveNodeEvent.RemoveListener(
47 
48  if (m_ActiveTool)
49  {
50  m_ActiveTool->Deactivated();
51  m_ActiveToolRegistration.Unregister();
52 
53  m_ActiveTool = nullptr;
54  m_ActiveToolID = -1; // no tool active
55 
56  ActiveToolChanged.Send();
57  }
58  for (NodeTagMapType::iterator observerTagMapIter = m_ReferenceDataObserverTags.begin();
59  observerTagMapIter != m_ReferenceDataObserverTags.end();
60  ++observerTagMapIter)
61  {
62  observerTagMapIter->first->RemoveObserver(observerTagMapIter->second);
63  }
64 }
65 
67 {
68  m_Tools.resize(0);
69  // get a list of all known mitk::Tools
70  std::list<itk::LightObject::Pointer> thingsThatClaimToBeATool = itk::ObjectFactoryBase::CreateAllInstance("mitkTool");
71 
72  // remember these tools
73  for (std::list<itk::LightObject::Pointer>::iterator iter = thingsThatClaimToBeATool.begin();
74  iter != thingsThatClaimToBeATool.end();
75  ++iter)
76  {
77  if (Tool *tool = dynamic_cast<Tool *>(iter->GetPointer()))
78  {
79  tool->InitializeStateMachine();
80  tool->SetToolManager(this); // important to call right after instantiation
82  tool->GeneralMessage +=
84  m_Tools.push_back(tool);
85  }
86  }
87 }
88 
90 {
91  this->ToolErrorMessage(s);
92 }
93 
95 {
96  this->GeneralToolMessage(s);
97 }
98 
100 {
101  ToolVectorTypeConst resultList;
102 
103  for (ToolVectorType::iterator iter = m_Tools.begin(); iter != m_Tools.end(); ++iter)
104  {
105  resultList.push_back(iter->GetPointer());
106  }
107 
108  return resultList;
109 }
110 
112 {
113  try
114  {
115  return m_Tools.at(id);
116  }
117  catch (const std::exception &)
118  {
119  return nullptr;
120  }
121 }
122 
124 {
125  if (id != -1 && !this->GetToolById(id)->CanHandle(this->GetReferenceData(0)->GetData()))
126  return false;
127 
128  if (this->GetDataStorage())
129  {
130  this->GetDataStorage()->RemoveNodeEvent.AddListener(
132  }
133 
134  if (GetToolById(id) == m_ActiveTool)
135  return true; // no change needed
136 
137  static int nextTool = -1;
138  nextTool = id;
139 
140  static bool inActivateTool = false;
141  if (inActivateTool)
142  {
143  return true;
144  }
145  inActivateTool = true;
146 
147  while (nextTool != m_ActiveToolID)
148  {
149  if (m_ActiveTool)
150  {
151  m_ActiveTool->Deactivated();
152  m_ActiveToolRegistration.Unregister();
153  }
154 
155  m_ActiveTool = GetToolById(nextTool);
156  m_ActiveToolID = m_ActiveTool ? nextTool : -1; // current ID if tool is valid, otherwise -1
157 
158  ActiveToolChanged.Send();
159 
160  if (m_ActiveTool)
161  {
162  if (m_RegisteredClients > 0)
163  {
164  m_ActiveTool->Activated();
165  m_ActiveToolRegistration =
167  }
168  }
169  }
170 
171  inActivateTool = false;
172  return (m_ActiveTool != nullptr);
173 }
174 
176 {
177  if (data != m_ReferenceData)
178  {
179  // remove observers from old nodes
180  for (DataVectorType::iterator dataIter = m_ReferenceData.begin(); dataIter != m_ReferenceData.end(); ++dataIter)
181  {
182  NodeTagMapType::iterator searchIter = m_ReferenceDataObserverTags.find(*dataIter);
183  if (searchIter != m_ReferenceDataObserverTags.end())
184  {
185  (*dataIter)->RemoveObserver(searchIter->second);
186  }
187  }
188 
189  m_ReferenceData = data;
190  // TODO tell active tool?
191 
192  // attach new observers
193  m_ReferenceDataObserverTags.clear();
194  for (DataVectorType::iterator dataIter = m_ReferenceData.begin(); dataIter != m_ReferenceData.end(); ++dataIter)
195  {
197  command->SetCallbackFunction(this, &ToolManager::OnOneOfTheReferenceDataDeleted);
198  command->SetCallbackFunction(this, &ToolManager::OnOneOfTheReferenceDataDeletedConst);
199  m_ReferenceDataObserverTags.insert(
200  std::pair<DataNode *, unsigned long>((*dataIter), (*dataIter)->AddObserver(itk::DeleteEvent(), command)));
201  }
202 
203  ReferenceDataChanged.Send();
204  }
205 }
206 
207 void mitk::ToolManager::OnOneOfTheReferenceDataDeletedConst(const itk::Object *caller, const itk::EventObject &e)
208 {
209  OnOneOfTheReferenceDataDeleted(const_cast<itk::Object *>(caller), e);
210 }
211 
212 void mitk::ToolManager::OnOneOfTheReferenceDataDeleted(itk::Object *caller, const itk::EventObject &itkNotUsed(e))
213 {
214  DataVectorType v;
215 
216  for (DataVectorType::iterator dataIter = m_ReferenceData.begin(); dataIter != m_ReferenceData.end(); ++dataIter)
217  {
218  if ((void *)(*dataIter) != (void *)caller)
219  {
220  v.push_back(*dataIter);
221  }
222  else
223  {
224  m_ReferenceDataObserverTags.erase(*dataIter); // no tag to remove anymore
225  }
226  }
227  this->SetReferenceData(v);
228 }
229 
231 {
232  DataVectorType v;
233  if (data)
234  {
235  v.push_back(data);
236  }
237  SetReferenceData(v);
238 }
239 
241 {
242  if (data != m_WorkingData)
243  {
244  // remove observers from old nodes
245  for (DataVectorType::iterator dataIter = m_WorkingData.begin(); dataIter != m_WorkingData.end(); ++dataIter)
246  {
247  NodeTagMapType::iterator searchIter = m_WorkingDataObserverTags.find(*dataIter);
248  if (searchIter != m_WorkingDataObserverTags.end())
249  {
250  (*dataIter)->RemoveObserver(searchIter->second);
251  }
252  }
253 
254  m_WorkingData = data;
255  // TODO tell active tool?
256 
257  // Quick workaround for bug #16598
258  if (m_WorkingData.empty())
259  this->ActivateTool(-1);
260  // workaround end
261 
262  // attach new observers
263  m_WorkingDataObserverTags.clear();
264  for (DataVectorType::iterator dataIter = m_WorkingData.begin(); dataIter != m_WorkingData.end(); ++dataIter)
265  {
267  command->SetCallbackFunction(this, &ToolManager::OnOneOfTheWorkingDataDeleted);
268  command->SetCallbackFunction(this, &ToolManager::OnOneOfTheWorkingDataDeletedConst);
269  m_WorkingDataObserverTags.insert(
270  std::pair<DataNode *, unsigned long>((*dataIter), (*dataIter)->AddObserver(itk::DeleteEvent(), command)));
271  }
272 
273  WorkingDataChanged.Send();
274  }
275 }
276 
277 void mitk::ToolManager::OnOneOfTheWorkingDataDeletedConst(const itk::Object *caller, const itk::EventObject &e)
278 {
279  OnOneOfTheWorkingDataDeleted(const_cast<itk::Object *>(caller), e);
280 }
281 
282 void mitk::ToolManager::OnOneOfTheWorkingDataDeleted(itk::Object *caller, const itk::EventObject &itkNotUsed(e))
283 {
284  DataVectorType v;
285 
286  for (DataVectorType::iterator dataIter = m_WorkingData.begin(); dataIter != m_WorkingData.end(); ++dataIter)
287  {
288  if ((void *)(*dataIter) != (void *)caller)
289  {
290  v.push_back(*dataIter);
291  }
292  else
293  {
294  m_WorkingDataObserverTags.erase(*dataIter); // no tag to remove anymore
295  }
296  }
297  this->SetWorkingData(v);
298 }
299 
301 {
302  DataVectorType v;
303 
304  if (data) // don't allow for NULL nodes
305  {
306  v.push_back(data);
307  }
308 
309  SetWorkingData(v);
310 }
311 
313 {
314  if (data != m_RoiData)
315  {
316  // remove observers from old nodes
317  for (DataVectorType::iterator dataIter = m_RoiData.begin(); dataIter != m_RoiData.end(); ++dataIter)
318  {
319  NodeTagMapType::iterator searchIter = m_RoiDataObserverTags.find(*dataIter);
320  if (searchIter != m_RoiDataObserverTags.end())
321  {
322  (*dataIter)->RemoveObserver(searchIter->second);
323  }
324  }
325 
326  m_RoiData = data;
327  // TODO tell active tool?
328 
329  // attach new observers
330  m_RoiDataObserverTags.clear();
331  for (DataVectorType::iterator dataIter = m_RoiData.begin(); dataIter != m_RoiData.end(); ++dataIter)
332  {
334  command->SetCallbackFunction(this, &ToolManager::OnOneOfTheRoiDataDeleted);
335  command->SetCallbackFunction(this, &ToolManager::OnOneOfTheRoiDataDeletedConst);
336  m_RoiDataObserverTags.insert(
337  std::pair<DataNode *, unsigned long>((*dataIter), (*dataIter)->AddObserver(itk::DeleteEvent(), command)));
338  }
339  RoiDataChanged.Send();
340  }
341 }
342 
344 {
345  DataVectorType v;
346 
347  if (data)
348  {
349  v.push_back(data);
350  }
351  this->SetRoiData(v);
352 }
353 
354 void mitk::ToolManager::OnOneOfTheRoiDataDeletedConst(const itk::Object *caller, const itk::EventObject &e)
355 {
356  OnOneOfTheRoiDataDeleted(const_cast<itk::Object *>(caller), e);
357 }
358 
359 void mitk::ToolManager::OnOneOfTheRoiDataDeleted(itk::Object *caller, const itk::EventObject &itkNotUsed(e))
360 {
361  DataVectorType v;
362 
363  for (DataVectorType::iterator dataIter = m_RoiData.begin(); dataIter != m_RoiData.end(); ++dataIter)
364  {
365  if ((void *)(*dataIter) != (void *)caller)
366  {
367  v.push_back(*dataIter);
368  }
369  else
370  {
371  m_RoiDataObserverTags.erase(*dataIter); // no tag to remove anymore
372  }
373  }
374  this->SetRoiData(v);
375 }
376 
378 {
379  return m_ReferenceData;
380 }
381 
383 {
384  try
385  {
386  return m_ReferenceData.at(idx);
387  }
388  catch (const std::exception &)
389  {
390  return nullptr;
391  }
392 }
393 
395 {
396  return m_WorkingData;
397 }
398 
400 {
401  return m_RoiData;
402 }
403 
405 {
406  try
407  {
408  return m_RoiData.at(idx);
409  }
410  catch (const std::exception &)
411  {
412  return nullptr;
413  }
414 }
415 
417 {
418  if (m_DataStorage.IsNotNull())
419  {
420  return m_DataStorage;
421  }
422  else
423  {
424  return nullptr;
425  }
426 }
427 
429 {
430  m_DataStorage = &storage;
431 }
432 
434 {
435  try
436  {
437  return m_WorkingData.at(idx);
438  }
439  catch (const std::exception &)
440  {
441  return nullptr;
442  }
443 }
444 
446 {
447  return m_ActiveToolID;
448 }
449 
451 {
452  return m_ActiveTool;
453 }
454 
456 {
457  if (m_RegisteredClients < 1)
458  {
459  if (m_ActiveTool)
460  {
461  m_ActiveTool->Activated();
462  m_ActiveToolRegistration =
464  }
465  }
466  ++m_RegisteredClients;
467 }
468 
470 {
471  if (m_RegisteredClients < 1)
472  return;
473 
474  --m_RegisteredClients;
475  if (m_RegisteredClients < 1)
476  {
477  if (m_ActiveTool)
478  {
479  m_ActiveTool->Deactivated();
480  m_ActiveToolRegistration.Unregister();
481  }
482  }
483 }
484 
486 {
487  int id(0);
488  for (ToolVectorType::iterator iter = m_Tools.begin(); iter != m_Tools.end(); ++iter, ++id)
489  {
490  if (tool == iter->GetPointer())
491  {
492  return id;
493  }
494  }
495  return -1;
496 }
497 
499 {
500  // check all storage vectors
501  OnOneOfTheReferenceDataDeleted(const_cast<mitk::DataNode *>(node), itk::DeleteEvent());
502  OnOneOfTheRoiDataDeleted(const_cast<mitk::DataNode *>(node), itk::DeleteEvent());
503  OnOneOfTheWorkingDataDeleted(const_cast<mitk::DataNode *>(node), itk::DeleteEvent());
504 }
std::vector< Tool::ConstPointer > ToolVectorTypeConst
void SetDataStorage(DataStorage &storage)
Base class of all tools used by mitk::ToolManager.
Definition: mitkTool.h:92
void OnOneOfTheReferenceDataDeletedConst(const itk::Object *caller, const itk::EventObject &e)
Data management class that handles 'was created by' relations.
Base class to implement InteractionEventObservers.
itk::SmartPointer< Self > Pointer
ServiceRegistrationU RegisterService(const InterfaceMap &service, const ServiceProperties &properties=ServiceProperties())
DataStorage * GetDataStorage()
void OnToolErrorMessage(std::string s)
std::vector< DataNode * > DataVectorType
Tool * GetToolById(int id)
static mitk::DataStorage::Pointer GetDataStorage()
void OnOneOfTheReferenceDataDeleted(itk::Object *caller, const itk::EventObject &e)
void OnOneOfTheWorkingDataDeleted(itk::Object *caller, const itk::EventObject &e)
DataVectorType GetRoiData()
bool ActivateTool(int id)
T::Pointer GetData(const std::string &name)
void SetReferenceData(DataVectorType)
void OnNodeRemoved(const mitk::DataNode *node)
Callback for NodeRemove events.
mitk::DataStorage::Pointer m_DataStorage
void OnOneOfTheRoiDataDeleted(itk::Object *caller, const itk::EventObject &e)
void SetWorkingData(DataVectorType)
int GetToolID(const Tool *tool)
US_UNORDERED_MAP_TYPE< std::string, Any > ServiceProperties
void InitializeTools()
Initialize all classes derived from mitk::Tool by itkObjectFactoy.
void OnOneOfTheRoiDataDeletedConst(const itk::Object *caller, const itk::EventObject &e)
void OnOneOfTheWorkingDataDeletedConst(const itk::Object *caller, const itk::EventObject &e)
const ToolVectorTypeConst GetTools()
Gives you a list of all tools. This is const on purpose.
ToolManager(DataStorage *storage)
void SetRoiData(DataVectorType)
DataVectorType GetReferenceData()
void OnGeneralToolMessage(std::string s)
static ModuleContext * GetModuleContext()
Returns the module context of the calling module.
Class for nodes of the DataTree.
Definition: mitkDataNode.h:66
DataVectorType GetWorkingData()
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.