Medical Imaging Interaction Toolkit  2016.11.0
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,
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 // Qmitk
18 #include "QmitkRenderWindow.h"
20 
21 #include "mitkIRenderWindowPart.h"
22 
23 // Qt
24 #include <QTimer>
25 #include <QMessageBox>
26 
27 
30 m_PendingSliceChangedEvent(false),
31 m_internalUpdateFlag(false)
32 {
33 }
34 
36 {
37  this->RemoveAllObservers();
38 };
39 
41 {
43  emit SliceChanged();
44 };
45 
46 void
48 {
49  // Taken from QmitkStdMultiWidget::HandleCrosshairPositionEvent().
50  // Since there are always 3 events arriving (one for each render window) every time the slice
51  // or time changes, the slot OnSliceChangedDelayed is triggered - and only if it hasn't been
52  // triggered yet - so it is only executed once for every slice/time change.
54  {
56 
57  QTimer::singleShot(0, this, SLOT(OnSliceChangedDelayed()));
58  }
59 };
60 
61 void QmitkSliceNavigationListener::OnSliceNavigationControllerDeleted(const itk::Object* sender, const itk::EventObject& /*e*/)
62 {
63  const mitk::SliceNavigationController* sendingSlicer =
64  dynamic_cast<const mitk::SliceNavigationController*>(sender);
65 
66  this->RemoveObservers(sendingSlicer);
67 };
68 
70 {
71  if (m_renderWindowPart != renderWindowPart)
72  {
73  m_renderWindowPart = renderWindowPart;
74 
75  if (!InitObservers())
76  {
77  QMessageBox::information(NULL, "Error", "Unable to set up the event observers. The " \
78  "plot will not be triggered on changing the crosshair, " \
79  "position or time step.");
80  }
81  }
82 };
83 
85 {
86  m_renderWindowPart = NULL;
87  this->RemoveAllObservers(renderWindowPart);
88 };
89 
91 {
92  bool result = true;
93 
94  typedef QHash<QString, QmitkRenderWindow*> WindowMapType;
95  WindowMapType windowMap = m_renderWindowPart->GetQmitkRenderWindows();
96 
97  auto i = windowMap.begin();
98 
99  while (i != windowMap.end())
100  {
101  mitk::SliceNavigationController* sliceNavController =
102  i.value()->GetSliceNavigationController();
103 
104  if (sliceNavController)
105  {
108  cmdSliceEvent->SetCallbackFunction(this, &QmitkSliceNavigationListener::OnSliceChangedInternal);
109  int tag = sliceNavController->AddObserver(
111  cmdSliceEvent);
112 
113  m_ObserverMap.insert(std::make_pair(sliceNavController, ObserverInfo(sliceNavController, tag,
114  i.key().toStdString(), m_renderWindowPart)));
115 
118  cmdTimeEvent->SetCallbackFunction(this, &QmitkSliceNavigationListener::OnSliceChangedInternal);
119  tag = sliceNavController->AddObserver(
121  cmdTimeEvent);
122 
123  m_ObserverMap.insert(std::make_pair(sliceNavController, ObserverInfo(sliceNavController, tag,
124  i.key().toStdString(), m_renderWindowPart)));
125 
128  cmdDelEvent->SetCallbackFunction(this,
130  tag = sliceNavController->AddObserver(
131  itk::DeleteEvent(), cmdDelEvent);
132 
133  m_ObserverMap.insert(std::make_pair(sliceNavController, ObserverInfo(sliceNavController, tag,
134  i.key().toStdString(), m_renderWindowPart)));
135  }
136 
137  ++i;
138 
139  result = result && sliceNavController;
140  }
141 
142  return result;
143 };
144 
146 {
147  std::pair < ObserverMapType::const_iterator, ObserverMapType::const_iterator> obsRange =
148  m_ObserverMap.equal_range(deletedSlicer);
149 
150  for (ObserverMapType::const_iterator pos = obsRange.first; pos != obsRange.second; ++pos)
151  {
152  pos->second.controller->RemoveObserver(pos->second.observerTag);
153  }
154 
155  m_ObserverMap.erase(deletedSlicer);
156 };
157 
159 {
160  for (ObserverMapType::const_iterator pos = m_ObserverMap.begin(); pos != m_ObserverMap.end();)
161  {
162  ObserverMapType::const_iterator delPos = pos++;
163 
164  if (deletedPart == NULL || deletedPart == delPos->second.renderWindowPart)
165  {
166  delPos->second.controller->RemoveObserver(delPos->second.observerTag);
167  m_ObserverMap.erase(delPos);
168  }
169  }
170 };
171 
173  const std::string& renderWindowName, mitk::IRenderWindowPart* part) : controller(controller), observerTag(observerTag),
174  renderWindowName(renderWindowName), renderWindowPart(part)
175 {
176 };
itk::SmartPointer< Self > Pointer
void OnSliceChangedInternal(const itk::EventObject &e)
Calls OnSliceChangedDelayed so the event isn't triggered multiple times.
void RemoveAllObservers(mitk::IRenderWindowPart *deletedPart=NULL)
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 &)
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.