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