Medical Imaging Interaction Toolkit  2018.4.99-12ad79a3
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"
14 #include "mitkCoreObjectFactory.h"
15 
16 #include <itkCommand.h>
17 #include <itkObjectFactoryBase.h>
18 
19 #include <list>
20 
22 #include "mitkSegTool2D.h"
23 
24 #include "usGetModuleContext.h"
25 #include "usModuleContext.h"
26 
28  : m_ActiveTool(nullptr), m_ActiveToolID(-1), m_RegisteredClients(0), m_DataStorage(storage)
29 {
30  CoreObjectFactory::GetInstance(); // to make sure a CoreObjectFactory was instantiated (and in turn, possible tools
31  // are registered) - bug 1029
32  this->InitializeTools();
33 }
34 
36 {
37  for (auto dataIter = m_WorkingData.begin(); dataIter != m_WorkingData.end(); ++dataIter)
38  (*dataIter)->RemoveObserver(m_WorkingDataObserverTags[(*dataIter)]);
39 
40  if (this->GetDataStorage() != nullptr)
43 
44  if (m_ActiveTool)
45  {
47  m_ActiveToolRegistration.Unregister();
48 
49  m_ActiveTool = nullptr;
50  m_ActiveToolID = -1; // no tool active
51 
53  }
54  for (auto observerTagMapIter = m_ReferenceDataObserverTags.begin();
55  observerTagMapIter != m_ReferenceDataObserverTags.end();
56  ++observerTagMapIter)
57  {
58  observerTagMapIter->first->RemoveObserver(observerTagMapIter->second);
59  }
60 }
61 
63 {
64  // clear all previous tool pointers (tools may be still activated from another recently used plugin)
65  if (m_ActiveTool)
66  {
68  m_ActiveToolRegistration.Unregister();
69 
70  m_ActiveTool = nullptr;
71  m_ActiveToolID = -1; // no tool active
72 
74  }
75  m_Tools.clear();
76  // get a list of all known mitk::Tools
77  std::list<itk::LightObject::Pointer> thingsThatClaimToBeATool = itk::ObjectFactoryBase::CreateAllInstance("mitkTool");
78 
79  // remember these tools
80  for (auto iter = thingsThatClaimToBeATool.begin();
81  iter != thingsThatClaimToBeATool.end();
82  ++iter)
83  {
84  if (auto *tool = dynamic_cast<Tool *>(iter->GetPointer()))
85  {
86  tool->InitializeStateMachine();
87  tool->SetToolManager(this); // important to call right after instantiation
89  tool->GeneralMessage +=
91  m_Tools.push_back(tool);
92  }
93  }
94 }
95 
97 {
98  this->ToolErrorMessage(s);
99 }
100 
102 {
103  this->GeneralToolMessage(s);
104 }
105 
107 {
108  ToolVectorTypeConst resultList;
109 
110  for (auto iter = m_Tools.begin(); iter != m_Tools.end(); ++iter)
111  {
112  resultList.push_back(iter->GetPointer());
113  }
114 
115  return resultList;
116 }
117 
119 {
120  try
121  {
122  return m_Tools.at(id);
123  }
124  catch (const std::exception &)
125  {
126  return nullptr;
127  }
128 }
129 
131 {
132  if (id != -1 && !this->GetToolById(id)->CanHandle(this->GetReferenceData(0)->GetData()))
133  return false;
134 
135  if (this->GetDataStorage())
136  {
139  }
140 
141  if (GetToolById(id) == m_ActiveTool)
142  return true; // no change needed
143 
144  static int nextTool = -1;
145  nextTool = id;
146 
147  static bool inActivateTool = false;
148  if (inActivateTool)
149  {
150  return true;
151  }
152  inActivateTool = true;
153 
154  while (nextTool != m_ActiveToolID)
155  {
156  if (m_ActiveTool)
157  {
159  m_ActiveToolRegistration.Unregister();
160  }
161 
162  m_ActiveTool = GetToolById(nextTool);
163  m_ActiveToolID = m_ActiveTool ? nextTool : -1; // current ID if tool is valid, otherwise -1
164 
166 
167  if (m_ActiveTool)
168  {
169  if (m_RegisteredClients > 0)
170  {
174  }
175  }
176  }
177 
178  inActivateTool = false;
179  return (m_ActiveTool != nullptr);
180 }
181 
183 {
184  if (data != m_ReferenceData)
185  {
186  // remove observers from old nodes
187  for (auto dataIter = m_ReferenceData.begin(); dataIter != m_ReferenceData.end(); ++dataIter)
188  {
189  auto searchIter = m_ReferenceDataObserverTags.find(*dataIter);
190  if (searchIter != m_ReferenceDataObserverTags.end())
191  {
192  (*dataIter)->RemoveObserver(searchIter->second);
193  }
194  }
195 
196  m_ReferenceData = data;
197  // TODO tell active tool?
198 
199  // attach new observers
201  for (auto dataIter = m_ReferenceData.begin(); dataIter != m_ReferenceData.end(); ++dataIter)
202  {
203  itk::MemberCommand<ToolManager>::Pointer command = itk::MemberCommand<ToolManager>::New();
204  command->SetCallbackFunction(this, &ToolManager::OnOneOfTheReferenceDataDeleted);
205  command->SetCallbackFunction(this, &ToolManager::OnOneOfTheReferenceDataDeletedConst);
207  std::pair<DataNode *, unsigned long>((*dataIter), (*dataIter)->AddObserver(itk::DeleteEvent(), command)));
208  }
209 
211  }
212 }
213 
214 void mitk::ToolManager::OnOneOfTheReferenceDataDeletedConst(const itk::Object *caller, const itk::EventObject &e)
215 {
216  OnOneOfTheReferenceDataDeleted(const_cast<itk::Object *>(caller), e);
217 }
218 
219 void mitk::ToolManager::OnOneOfTheReferenceDataDeleted(itk::Object *caller, const itk::EventObject &itkNotUsed(e))
220 {
221  DataVectorType v;
222 
223  for (auto dataIter = m_ReferenceData.begin(); dataIter != m_ReferenceData.end(); ++dataIter)
224  {
225  if ((void *)(*dataIter) != (void *)caller)
226  {
227  v.push_back(*dataIter);
228  }
229  else
230  {
231  m_ReferenceDataObserverTags.erase(*dataIter); // no tag to remove anymore
232  }
233  }
234  this->SetReferenceData(v);
235 }
236 
238 {
239  DataVectorType v;
240  if (data)
241  {
242  v.push_back(data);
243  }
244  SetReferenceData(v);
245 }
246 
248 {
249  if (data != m_WorkingData)
250  {
251  // remove observers from old nodes
252  for (auto dataIter = m_WorkingData.begin(); dataIter != m_WorkingData.end(); ++dataIter)
253  {
254  auto searchIter = m_WorkingDataObserverTags.find(*dataIter);
255  if (searchIter != m_WorkingDataObserverTags.end())
256  {
257  (*dataIter)->RemoveObserver(searchIter->second);
258  }
259  }
260 
261  m_WorkingData = data;
262  // TODO tell active tool?
263 
264  // Quick workaround for bug #16598
265  if (m_WorkingData.empty())
266  this->ActivateTool(-1);
267  // workaround end
268 
269  // attach new observers
271  for (auto dataIter = m_WorkingData.begin(); dataIter != m_WorkingData.end(); ++dataIter)
272  {
273  itk::MemberCommand<ToolManager>::Pointer command = itk::MemberCommand<ToolManager>::New();
274  command->SetCallbackFunction(this, &ToolManager::OnOneOfTheWorkingDataDeleted);
275  command->SetCallbackFunction(this, &ToolManager::OnOneOfTheWorkingDataDeletedConst);
277  std::pair<DataNode *, unsigned long>((*dataIter), (*dataIter)->AddObserver(itk::DeleteEvent(), command)));
278  }
279 
281  }
282 }
283 
284 void mitk::ToolManager::OnOneOfTheWorkingDataDeletedConst(const itk::Object *caller, const itk::EventObject &e)
285 {
286  OnOneOfTheWorkingDataDeleted(const_cast<itk::Object *>(caller), e);
287 }
288 
289 void mitk::ToolManager::OnOneOfTheWorkingDataDeleted(itk::Object *caller, const itk::EventObject &itkNotUsed(e))
290 {
291  DataVectorType v;
292 
293  for (auto dataIter = m_WorkingData.begin(); dataIter != m_WorkingData.end(); ++dataIter)
294  {
295  if ((void *)(*dataIter) != (void *)caller)
296  {
297  v.push_back(*dataIter);
298  }
299  else
300  {
301  m_WorkingDataObserverTags.erase(*dataIter); // no tag to remove anymore
302  }
303  }
304  this->SetWorkingData(v);
305 }
306 
308 {
309  DataVectorType v;
310 
311  if (data) // don't allow for nullptr nodes
312  {
313  v.push_back(data);
314  }
315 
316  SetWorkingData(v);
317 }
318 
320 {
321  if (data != m_RoiData)
322  {
323  // remove observers from old nodes
324  for (auto dataIter = m_RoiData.begin(); dataIter != m_RoiData.end(); ++dataIter)
325  {
326  auto searchIter = m_RoiDataObserverTags.find(*dataIter);
327  if (searchIter != m_RoiDataObserverTags.end())
328  {
329  (*dataIter)->RemoveObserver(searchIter->second);
330  }
331  }
332 
333  m_RoiData = data;
334  // TODO tell active tool?
335 
336  // attach new observers
337  m_RoiDataObserverTags.clear();
338  for (auto dataIter = m_RoiData.begin(); dataIter != m_RoiData.end(); ++dataIter)
339  {
340  itk::MemberCommand<ToolManager>::Pointer command = itk::MemberCommand<ToolManager>::New();
341  command->SetCallbackFunction(this, &ToolManager::OnOneOfTheRoiDataDeleted);
342  command->SetCallbackFunction(this, &ToolManager::OnOneOfTheRoiDataDeletedConst);
343  m_RoiDataObserverTags.insert(
344  std::pair<DataNode *, unsigned long>((*dataIter), (*dataIter)->AddObserver(itk::DeleteEvent(), command)));
345  }
347  }
348 }
349 
351 {
352  DataVectorType v;
353 
354  if (data)
355  {
356  v.push_back(data);
357  }
358  this->SetRoiData(v);
359 }
360 
361 void mitk::ToolManager::OnOneOfTheRoiDataDeletedConst(const itk::Object *caller, const itk::EventObject &e)
362 {
363  OnOneOfTheRoiDataDeleted(const_cast<itk::Object *>(caller), e);
364 }
365 
366 void mitk::ToolManager::OnOneOfTheRoiDataDeleted(itk::Object *caller, const itk::EventObject &itkNotUsed(e))
367 {
368  DataVectorType v;
369 
370  for (auto dataIter = m_RoiData.begin(); dataIter != m_RoiData.end(); ++dataIter)
371  {
372  if ((void *)(*dataIter) != (void *)caller)
373  {
374  v.push_back(*dataIter);
375  }
376  else
377  {
378  m_RoiDataObserverTags.erase(*dataIter); // no tag to remove anymore
379  }
380  }
381  this->SetRoiData(v);
382 }
383 
385 {
386  return m_ReferenceData;
387 }
388 
390 {
391  try
392  {
393  return m_ReferenceData.at(idx);
394  }
395  catch (const std::exception &)
396  {
397  return nullptr;
398  }
399 }
400 
402 {
403  return m_WorkingData;
404 }
405 
407 {
408  return m_RoiData;
409 }
410 
412 {
413  try
414  {
415  return m_RoiData.at(idx);
416  }
417  catch (const std::exception &)
418  {
419  return nullptr;
420  }
421 }
422 
424 {
425  if (!m_DataStorage.IsExpired())
426  {
427  return m_DataStorage.Lock();
428  }
429  else
430  {
431  return nullptr;
432  }
433 }
434 
436 {
437  m_DataStorage = &storage;
438 }
439 
441 {
442  if (m_WorkingData.empty())
443  return nullptr;
444 
445  if (m_WorkingData.size() > idx)
446  return m_WorkingData[idx];
447 
448  return nullptr;
449 }
450 
452 {
453  return m_ActiveToolID;
454 }
455 
457 {
458  return m_ActiveTool;
459 }
460 
462 {
463  if (m_RegisteredClients < 1)
464  {
465  if (m_ActiveTool)
466  {
470  }
471  }
473 }
474 
476 {
477  if (m_RegisteredClients < 1)
478  return;
479 
481  if (m_RegisteredClients < 1)
482  {
483  if (m_ActiveTool)
484  {
486  m_ActiveToolRegistration.Unregister();
487  }
488  }
489 }
490 
492 {
493  int id(0);
494  for (auto iter = m_Tools.begin(); iter != m_Tools.end(); ++iter, ++id)
495  {
496  if (tool == iter->GetPointer())
497  {
498  return id;
499  }
500  }
501  return -1;
502 }
503 
505 {
506  // check all storage vectors
507  OnOneOfTheReferenceDataDeleted(const_cast<mitk::DataNode *>(node), itk::DeleteEvent());
508  OnOneOfTheRoiDataDeleted(const_cast<mitk::DataNode *>(node), itk::DeleteEvent());
509  OnOneOfTheWorkingDataDeleted(const_cast<mitk::DataNode *>(node), itk::DeleteEvent());
510 }
std::vector< Tool::ConstPointer > ToolVectorTypeConst
void SetDataStorage(DataStorage &storage)
Base class of all tools used by mitk::ToolManager.
Definition: mitkTool.h:88
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:64
DataVectorType GetWorkingData()