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
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.