Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
QmitkSliceNavigationListener.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 // Qmitk
14 #include "QmitkRenderWindow.h"
16 
17 #include "mitkIRenderWindowPart.h"
18 
19 // Qt
20 #include <QTimer>
21 #include <QMessageBox>
22 
23 
26 m_PendingSliceChangedEvent(false),
27 m_internalUpdateFlag(false)
28 {
29 }
30 
32 {
33  this->RemoveAllObservers();
34 };
35 
37 {
39  emit SliceChanged();
40 };
41 
42 void
44 {
45  // Taken from QmitkStdMultiWidget::HandleCrosshairPositionEvent().
46  // Since there are always 3 events arriving (one for each render window) every time the slice
47  // or time changes, the slot OnSliceChangedDelayed is triggered - and only if it hasn't been
48  // triggered yet - so it is only executed once for every slice/time change.
50  {
52 
53  QTimer::singleShot(0, this, SLOT(OnSliceChangedDelayed()));
54  }
55 };
56 
57 void QmitkSliceNavigationListener::OnSliceNavigationControllerDeleted(const itk::Object* sender, const itk::EventObject& /*e*/)
58 {
59  const mitk::SliceNavigationController* sendingSlicer =
60  dynamic_cast<const mitk::SliceNavigationController*>(sender);
61 
62  this->RemoveObservers(sendingSlicer);
63 };
64 
66 {
67  if (m_renderWindowPart != renderWindowPart)
68  {
69  m_renderWindowPart = renderWindowPart;
70 
71  if (!InitObservers())
72  {
73  QMessageBox::information(nullptr, "Error", "Unable to set up the event observers. The " \
74  "plot will not be triggered on changing the crosshair, " \
75  "position or time step.");
76  }
77  }
78 };
79 
81 {
82  m_renderWindowPart = nullptr;
83  this->RemoveAllObservers(renderWindowPart);
84 };
85 
87 {
88  bool result = true;
89 
90  typedef QHash<QString, QmitkRenderWindow*> WindowMapType;
91  WindowMapType windowMap = m_renderWindowPart->GetQmitkRenderWindows();
92 
93  auto i = windowMap.begin();
94 
95  while (i != windowMap.end())
96  {
97  mitk::SliceNavigationController* sliceNavController =
98  i.value()->GetSliceNavigationController();
99 
100  if (sliceNavController)
101  {
102  itk::ReceptorMemberCommand<QmitkSliceNavigationListener>::Pointer cmdSliceEvent =
103  itk::ReceptorMemberCommand<QmitkSliceNavigationListener>::New();
104  cmdSliceEvent->SetCallbackFunction(this, &QmitkSliceNavigationListener::OnSliceChangedInternal);
105  int tag = sliceNavController->AddObserver(
107  cmdSliceEvent);
108 
109  m_ObserverMap.insert(std::make_pair(sliceNavController, ObserverInfo(sliceNavController, tag,
110  i.key().toStdString(), m_renderWindowPart)));
111 
112  itk::ReceptorMemberCommand<QmitkSliceNavigationListener>::Pointer cmdTimeEvent =
113  itk::ReceptorMemberCommand<QmitkSliceNavigationListener>::New();
114  cmdTimeEvent->SetCallbackFunction(this, &QmitkSliceNavigationListener::OnSliceChangedInternal);
115  tag = sliceNavController->AddObserver(
117  cmdTimeEvent);
118 
119  m_ObserverMap.insert(std::make_pair(sliceNavController, ObserverInfo(sliceNavController, tag,
120  i.key().toStdString(), m_renderWindowPart)));
121 
122  itk::MemberCommand<QmitkSliceNavigationListener>::Pointer cmdDelEvent =
123  itk::MemberCommand<QmitkSliceNavigationListener>::New();
124  cmdDelEvent->SetCallbackFunction(this,
126  tag = sliceNavController->AddObserver(
127  itk::DeleteEvent(), cmdDelEvent);
128 
129  m_ObserverMap.insert(std::make_pair(sliceNavController, ObserverInfo(sliceNavController, tag,
130  i.key().toStdString(), m_renderWindowPart)));
131  }
132 
133  ++i;
134 
135  result = result && sliceNavController;
136  }
137 
138  return result;
139 };
140 
142 {
143  std::pair < ObserverMapType::const_iterator, ObserverMapType::const_iterator> obsRange =
144  m_ObserverMap.equal_range(deletedSlicer);
145 
146  for (ObserverMapType::const_iterator pos = obsRange.first; pos != obsRange.second; ++pos)
147  {
148  pos->second.controller->RemoveObserver(pos->second.observerTag);
149  }
150 
151  m_ObserverMap.erase(deletedSlicer);
152 };
153 
155 {
156  for (ObserverMapType::const_iterator pos = m_ObserverMap.begin(); pos != m_ObserverMap.end();)
157  {
158  ObserverMapType::const_iterator delPos = pos++;
159 
160  if (deletedPart == nullptr || deletedPart == delPos->second.renderWindowPart)
161  {
162  delPos->second.controller->RemoveObserver(delPos->second.observerTag);
163  m_ObserverMap.erase(delPos);
164  }
165  }
166 };
167 
169  const std::string& renderWindowName, mitk::IRenderWindowPart* part) : controller(controller), observerTag(observerTag),
170  renderWindowName(renderWindowName), renderWindowPart(part)
171 {
172 };
void RemoveAllObservers(mitk::IRenderWindowPart *deletedPart=nullptr)
void OnSliceChangedInternal(const itk::EventObject &e)
Calls OnSliceChangedDelayed so the event isn&#39;t triggered multiple times.
Interface for a MITK Workbench Part providing a render window.
ObserverInfo(mitk::SliceNavigationController *controller, int observerTag, const std::string &renderWindowName, mitk::IRenderWindowPart *part)
virtual QHash< QString, QmitkRenderWindow * > GetQmitkRenderWindows() const =0
Controls the selection of the slice the associated BaseRenderer will display.
mitk::IRenderWindowPart * m_renderWindowPart
void RenderWindowPartActivated(mitk::IRenderWindowPart *renderWindowPart)
void RenderWindowPartDeactivated(mitk::IRenderWindowPart *renderWindowPart)
void RemoveObservers(const mitk::SliceNavigationController *deletedSlicer)
void OnSliceNavigationControllerDeleted(const itk::Object *sender, const itk::EventObject &)