Medical Imaging Interaction Toolkit  2018.4.99-b585543d
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 (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 
13 #include "mitkToolManager.h"
15 #include "mitkCoreObjectFactory.h"
16 
17 #include <itkCommand.h>
18 #include <itkObjectFactoryBase.h>
19 
20 #include <list>
21 
23 #include "mitkSegTool2D.h"
24 
25 #include "usGetModuleContext.h"
26 #include "usModuleContext.h"
27 
29  : m_ActiveTool(nullptr), m_ActiveToolID(-1), m_RegisteredClients(0), m_DataStorage(storage)
30 {
31  CoreObjectFactory::GetInstance(); // to make sure a CoreObjectFactory was instantiated (and in turn, possible tools
32  // are registered) - bug 1029
33  this->InitializeTools();
34 }
35 
37 {
38  for (auto dataIter = m_WorkingData.begin(); dataIter != m_WorkingData.end(); ++dataIter)
39  (*dataIter)->RemoveObserver(m_WorkingDataObserverTags[(*dataIter)]);
40 
41  if (this->GetDataStorage() != nullptr)
44 
45  if (m_ActiveTool)
46  {
48  m_ActiveToolRegistration.Unregister();
49 
50  m_ActiveTool = nullptr;
51  m_ActiveToolID = -1; // no tool active
52 
54  }
55  for (auto observerTagMapIter = m_ReferenceDataObserverTags.begin();
56  observerTagMapIter != m_ReferenceDataObserverTags.end();
57  ++observerTagMapIter)
58  {
59  observerTagMapIter->first->RemoveObserver(observerTagMapIter->second);
60  }
61 }
62 
64 {
65  // clear all previous tool pointers (tools may be still activated from another recently used plugin)
66  if (m_ActiveTool)
67  {
69  m_ActiveToolRegistration.Unregister();
70 
71  m_ActiveTool = nullptr;
72  m_ActiveToolID = -1; // no tool active
73 
75  }
76  m_Tools.clear();
77  // get a list of all known mitk::Tools
78  std::list<itk::LightObject::Pointer> thingsThatClaimToBeATool = itk::ObjectFactoryBase::CreateAllInstance("mitkTool");
79 
80  // remember these tools
81  for (auto iter = thingsThatClaimToBeATool.begin();
82  iter != thingsThatClaimToBeATool.end();
83  ++iter)
84  {
85  if (auto *tool = dynamic_cast<Tool *>(iter->GetPointer()))
86  {
87  tool->InitializeStateMachine();
88  tool->SetToolManager(this); // important to call right after instantiation
90  tool->GeneralMessage +=
92  m_Tools.push_back(tool);
93  }
94  }
95 }
96 
98 {
99  this->ToolErrorMessage(s);
100 }
101 
103 {
104  this->GeneralToolMessage(s);
105 }
106 
108 {
109  ToolVectorTypeConst resultList;
110 
111  for (auto iter = m_Tools.begin(); iter != m_Tools.end(); ++iter)
112  {
113  resultList.push_back(iter->GetPointer());
114  }
115 
116  return resultList;
117 }
118 
120 {
121  try
122  {
123  return m_Tools.at(id);
124  }
125  catch (const std::exception &)
126  {
127  return nullptr;
128  }
129 }
130 
132 {
133  if (id != -1 && !this->GetToolById(id)->CanHandle(this->GetReferenceData(0)->GetData()))
134  return false;
135 
136  if (this->GetDataStorage())
137  {
140  }
141 
142  if (GetToolById(id) == m_ActiveTool)
143  return true; // no change needed
144 
145  static int nextTool = -1;
146  nextTool = id;
147 
148  static bool inActivateTool = false;
149  if (inActivateTool)
150  {
151  return true;
152  }
153  inActivateTool = true;
154 
155  while (nextTool != m_ActiveToolID)
156  {
157  // Deactivate all other active tools to ensure a globally single active tool
158  for (const auto& toolManager : ToolManagerProvider::GetInstance()->GetToolManagers())
159  {
160  if (nullptr != toolManager.second->m_ActiveTool)
161  {
162  toolManager.second->m_ActiveTool->Deactivated();
163  toolManager.second->m_ActiveToolRegistration.Unregister();
164 
165  // The active tool of *this* ToolManager is handled below this loop
166  if (this != toolManager.second)
167  {
168  toolManager.second->m_ActiveTool = nullptr;
169  toolManager.second->m_ActiveToolID = -1;
170  toolManager.second->ActiveToolChanged.Send();
171  }
172  }
173  }
174 
175  m_ActiveTool = GetToolById(nextTool);
176  m_ActiveToolID = m_ActiveTool ? nextTool : -1; // current ID if tool is valid, otherwise -1
177 
179 
180  if (m_ActiveTool)
181  {
182  if (m_RegisteredClients > 0)
183  {
187  }
188  }
189  }
190 
191  inActivateTool = false;
192  return (m_ActiveTool != nullptr);
193 }
194 
196 {
197  if (data != m_ReferenceData)
198  {
199  // remove observers from old nodes
200  for (auto dataIter = m_ReferenceData.begin(); dataIter != m_ReferenceData.end(); ++dataIter)
201  {
202  auto searchIter = m_ReferenceDataObserverTags.find(*dataIter);
203  if (searchIter != m_ReferenceDataObserverTags.end())
204  {
205  (*dataIter)->RemoveObserver(searchIter->second);
206  }
207  }
208 
209  m_ReferenceData = data;
210  // TODO tell active tool?
211 
212  // attach new observers
214  for (auto dataIter = m_ReferenceData.begin(); dataIter != m_ReferenceData.end(); ++dataIter)
215  {
216  itk::MemberCommand<ToolManager>::Pointer command = itk::MemberCommand<ToolManager>::New();
217  command->SetCallbackFunction(this, &ToolManager::OnOneOfTheReferenceDataDeleted);
218  command->SetCallbackFunction(this, &ToolManager::OnOneOfTheReferenceDataDeletedConst);
220  std::pair<DataNode *, unsigned long>((*dataIter), (*dataIter)->AddObserver(itk::DeleteEvent(), command)));
221  }
222 
224  }
225 }
226 
227 void mitk::ToolManager::OnOneOfTheReferenceDataDeletedConst(const itk::Object *caller, const itk::EventObject &e)
228 {
229  OnOneOfTheReferenceDataDeleted(const_cast<itk::Object *>(caller), e);
230 }
231 
232 void mitk::ToolManager::OnOneOfTheReferenceDataDeleted(itk::Object *caller, const itk::EventObject &itkNotUsed(e))
233 {
234  DataVectorType v;
235 
236  for (auto dataIter = m_ReferenceData.begin(); dataIter != m_ReferenceData.end(); ++dataIter)
237  {
238  if ((void *)(*dataIter) != (void *)caller)
239  {
240  v.push_back(*dataIter);
241  }
242  else
243  {
244  m_ReferenceDataObserverTags.erase(*dataIter); // no tag to remove anymore
245  }
246  }
247  this->SetReferenceData(v);
248 }
249 
251 {
252  DataVectorType v;
253  if (data)
254  {
255  v.push_back(data);
256  }
257  SetReferenceData(v);
258 }
259 
261 {
262  if (data != m_WorkingData)
263  {
264  // remove observers from old nodes
265  for (auto dataIter = m_WorkingData.begin(); dataIter != m_WorkingData.end(); ++dataIter)
266  {
267  auto searchIter = m_WorkingDataObserverTags.find(*dataIter);
268  if (searchIter != m_WorkingDataObserverTags.end())
269  {
270  (*dataIter)->RemoveObserver(searchIter->second);
271  }
272  }
273 
274  m_WorkingData = data;
275  // TODO tell active tool?
276 
277  // Quick workaround for bug #16598
278  if (m_WorkingData.empty())
279  this->ActivateTool(-1);
280  // workaround end
281 
282  // attach new observers
284  for (auto dataIter = m_WorkingData.begin(); dataIter != m_WorkingData.end(); ++dataIter)
285  {
286  itk::MemberCommand<ToolManager>::Pointer command = itk::MemberCommand<ToolManager>::New();
287  command->SetCallbackFunction(this, &ToolManager::OnOneOfTheWorkingDataDeleted);
288  command->SetCallbackFunction(this, &ToolManager::OnOneOfTheWorkingDataDeletedConst);
290  std::pair<DataNode *, unsigned long>((*dataIter), (*dataIter)->AddObserver(itk::DeleteEvent(), command)));
291  }
292 
294  }
295 }
296 
297 void mitk::ToolManager::OnOneOfTheWorkingDataDeletedConst(const itk::Object *caller, const itk::EventObject &e)
298 {
299  OnOneOfTheWorkingDataDeleted(const_cast<itk::Object *>(caller), e);
300 }
301 
302 void mitk::ToolManager::OnOneOfTheWorkingDataDeleted(itk::Object *caller, const itk::EventObject &itkNotUsed(e))
303 {
304  DataVectorType v;
305 
306  for (auto dataIter = m_WorkingData.begin(); dataIter != m_WorkingData.end(); ++dataIter)
307  {
308  if ((void *)(*dataIter) != (void *)caller)
309  {
310  v.push_back(*dataIter);
311  }
312  else
313  {
314  m_WorkingDataObserverTags.erase(*dataIter); // no tag to remove anymore
315  }
316  }
317  this->SetWorkingData(v);
318 }
319 
321 {
322  DataVectorType v;
323 
324  if (data) // don't allow for nullptr nodes
325  {
326  v.push_back(data);
327  }
328 
329  SetWorkingData(v);
330 }
331 
333 {
334  if (data != m_RoiData)
335  {
336  // remove observers from old nodes
337  for (auto dataIter = m_RoiData.begin(); dataIter != m_RoiData.end(); ++dataIter)
338  {
339  auto searchIter = m_RoiDataObserverTags.find(*dataIter);
340  if (searchIter != m_RoiDataObserverTags.end())
341  {
342  (*dataIter)->RemoveObserver(searchIter->second);
343  }
344  }
345 
346  m_RoiData = data;
347  // TODO tell active tool?
348 
349  // attach new observers
350  m_RoiDataObserverTags.clear();
351  for (auto dataIter = m_RoiData.begin(); dataIter != m_RoiData.end(); ++dataIter)
352  {
353  itk::MemberCommand<ToolManager>::Pointer command = itk::MemberCommand<ToolManager>::New();
354  command->SetCallbackFunction(this, &ToolManager::OnOneOfTheRoiDataDeleted);
355  command->SetCallbackFunction(this, &ToolManager::OnOneOfTheRoiDataDeletedConst);
356  m_RoiDataObserverTags.insert(
357  std::pair<DataNode *, unsigned long>((*dataIter), (*dataIter)->AddObserver(itk::DeleteEvent(), command)));
358  }
360  }
361 }
362 
364 {
365  DataVectorType v;
366 
367  if (data)
368  {
369  v.push_back(data);
370  }
371  this->SetRoiData(v);
372 }
373 
374 void mitk::ToolManager::OnOneOfTheRoiDataDeletedConst(const itk::Object *caller, const itk::EventObject &e)
375 {
376  OnOneOfTheRoiDataDeleted(const_cast<itk::Object *>(caller), e);
377 }
378 
379 void mitk::ToolManager::OnOneOfTheRoiDataDeleted(itk::Object *caller, const itk::EventObject &itkNotUsed(e))
380 {
381  DataVectorType v;
382 
383  for (auto dataIter = m_RoiData.begin(); dataIter != m_RoiData.end(); ++dataIter)
384  {
385  if ((void *)(*dataIter) != (void *)caller)
386  {
387  v.push_back(*dataIter);
388  }
389  else
390  {
391  m_RoiDataObserverTags.erase(*dataIter); // no tag to remove anymore
392  }
393  }
394  this->SetRoiData(v);
395 }
396 
398 {
399  return m_ReferenceData;
400 }
401 
403 {
404  try
405  {
406  return m_ReferenceData.at(idx);
407  }
408  catch (const std::exception &)
409  {
410  return nullptr;
411  }
412 }
413 
415 {
416  return m_WorkingData;
417 }
418 
420 {
421  return m_RoiData;
422 }
423 
425 {
426  try
427  {
428  return m_RoiData.at(idx);
429  }
430  catch (const std::exception &)
431  {
432  return nullptr;
433  }
434 }
435 
437 {
438  if (!m_DataStorage.IsExpired())
439  {
440  return m_DataStorage.Lock();
441  }
442  else
443  {
444  return nullptr;
445  }
446 }
447 
449 {
450  m_DataStorage = &storage;
451 }
452 
454 {
455  if (m_WorkingData.empty())
456  return nullptr;
457 
458  if (m_WorkingData.size() > idx)
459  return m_WorkingData[idx];
460 
461  return nullptr;
462 }
463 
465 {
466  return m_ActiveToolID;
467 }
468 
470 {
471  return m_ActiveTool;
472 }
473 
475 {
476  if (m_RegisteredClients < 1)
477  {
478  if (m_ActiveTool)
479  {
483  }
484  }
486 }
487 
489 {
490  if (m_RegisteredClients < 1)
491  return;
492 
494  if (m_RegisteredClients < 1)
495  {
496  if (m_ActiveTool)
497  {
499  m_ActiveToolRegistration.Unregister();
500  }
501  }
502 }
503 
505 {
506  int id(0);
507  for (auto iter = m_Tools.begin(); iter != m_Tools.end(); ++iter, ++id)
508  {
509  if (tool == iter->GetPointer())
510  {
511  return id;
512  }
513  }
514  return -1;
515 }
516 
518 {
519  // check all storage vectors
520  OnOneOfTheReferenceDataDeleted(const_cast<mitk::DataNode *>(node), itk::DeleteEvent());
521  OnOneOfTheRoiDataDeleted(const_cast<mitk::DataNode *>(node), itk::DeleteEvent());
522  OnOneOfTheWorkingDataDeleted(const_cast<mitk::DataNode *>(node), itk::DeleteEvent());
523 }
std::vector< Tool::ConstPointer > ToolVectorTypeConst
void SetDataStorage(DataStorage &storage)
Base class of all tools used by mitk::ToolManager.
Definition: mitkTool.h:86
void OnOneOfTheReferenceDataDeletedConst(const itk::Object *caller, const itk::EventObject &e)
Data management class that handles &#39;was created by&#39; relations.
Base class to implement InteractionEventObservers.
DataVectorType m_WorkingData
ServiceRegistrationU RegisterService(const InterfaceMap &service, const ServiceProperties &properties=ServiceProperties())
DataStorage * GetDataStorage()
virtual void Activated()
Called when the tool gets activated.
Definition: mitkTool.cpp:118
Message WorkingDataChanged
void OnToolErrorMessage(std::string s)
std::vector< DataNode * > DataVectorType
Tool * GetToolById(int id)
WeakPointer< DataStorage > m_DataStorage
NodeTagMapType m_RoiDataObserverTags
Message1< std::string > ToolErrorMessage
DataVectorType m_ReferenceData
void OnOneOfTheReferenceDataDeleted(itk::Object *caller, const itk::EventObject &e)
void OnOneOfTheWorkingDataDeleted(itk::Object *caller, const itk::EventObject &e)
DataVectorType GetRoiData()
Message ReferenceDataChanged
bool ActivateTool(int id)
NodeTagMapType m_ReferenceDataObserverTags
void SetReferenceData(DataVectorType)
Message1< std::string > GeneralToolMessage
virtual void Deactivated()
Called when the tool gets deactivated.
Definition: mitkTool.cpp:149
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 AddListener(const AbstractDelegate &delegate) const
Definition: mitkMessage.h:374
void SetWorkingData(DataVectorType)
us::ServiceRegistration< InteractionEventObserver > m_ActiveToolRegistration
int GetToolID(const Tool *tool)
NodeTagMapType m_WorkingDataObserverTags
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)
DataStorageEvent RemoveNodeEvent
RemoveEvent is emitted directly before a node is removed from the DataStorage.
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.
void RemoveListener(const AbstractDelegate &delegate) const
Definition: mitkMessage.h:393
ToolVectorType m_Tools
ToolManager(DataStorage *storage)
void SetRoiData(DataVectorType)
DataVectorType GetReferenceData()
DataVectorType m_RoiData
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:57
DataVectorType GetWorkingData()
static mitk::ToolManagerProvider * GetInstance()
Returns an instance of ToolManagerProvider service.