Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
QmitkIGTLStreamingManagementWidget.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 
18 
19 //mitk headers
20 #include <mitkSurface.h>
21 #include <mitkIGTLDeviceSource.h>
22 #include <mitkDataStorage.h>
23 #include <mitkIGTLMessageFactory.h>
24 
25 //qt headers
26 #include <qfiledialog.h>
27 #include <qinputdialog.h>
28 #include <qmessagebox.h>
29 #include <qscrollbar.h>
30 
31 //igtl
32 #include <igtlStringMessage.h>
33 #include <igtlBindMessage.h>
34 #include <igtlQuaternionTrackingDataMessage.h>
35 #include <igtlTrackingDataMessage.h>
36 
37 //poco headers
38 #include <Poco/Path.h>
39 
41 "org.mitk.views.igtldevicesourcemanagementwidget";
42 
44  QWidget* parent, Qt::WindowFlags f)
45  : QWidget(parent, f), m_IsClient(false)
46 {
47  m_Controls = NULL;
48  this->m_IGTLDevice = NULL;
49  CreateQtPartControl(this);
50 }
51 
53 {
54  this->RemoveObserver();
55 }
56 
58 {
59  if (this->m_IGTLDevice.IsNotNull())
60  {
61  this->m_IGTLDevice->RemoveObserver(m_LostConnectionObserverTag);
62  this->m_IGTLDevice->RemoveObserver(m_NewConnectionObserverTag);
63  this->m_IGTLDevice->RemoveObserver(m_StateModifiedObserverTag);
64  }
65  if (this->m_IGTLMsgProvider.IsNotNull())
66  {
69  }
70 }
71 
73 {
74  if (!m_Controls)
75  {
76  // create GUI widgets
77  m_Controls = new Ui::QmitkIGTLStreamingManagementWidgetControls;
78  // setup GUI widgets
79  m_Controls->setupUi(parent);
80  }
81 
82  //connect slots with signals
84 }
85 
87 {
88  if (m_Controls)
89  {
90  connect((QObject*)(m_Controls->messageSourceSelectionWidget),
91  SIGNAL(IGTLMessageSourceSelected(mitk::IGTLMessageSource::Pointer)),
92  this,
94  connect(m_Controls->startStreamPushButton, SIGNAL(clicked()),
95  this, SLOT(OnStartStreaming()));
96  connect(m_Controls->stopStreamPushButton, SIGNAL(clicked()),
97  this, SLOT(OnStopStreaming()));
98  }
99  //this is used for thread seperation, otherwise the worker thread would change the ui elements
100  //which would cause an exception
101  connect(this, SIGNAL(AdaptGUIToStateSignal()), this, SLOT(AdaptGUIToState()));
102  connect(this, SIGNAL(SelectSourceAndAdaptGUISignal()), this, SLOT(SelectSourceAndAdaptGUI()));
103 }
104 
106 {
107  if (this->m_IGTLMsgProvider.IsNotNull())
108  {
109  //get the state of the device
111  this->m_IGTLDevice->GetState();
112 
113  switch (state)
114  {
117  m_Controls->messageSourceSelectionWidget->setEnabled(false);
118  m_Controls->selectedSourceLabel->setText("<none>");
119  m_Controls->startStreamPushButton->setEnabled(false);
120  m_Controls->selectedSourceLabel->setEnabled(false);
121  m_Controls->label->setEnabled(false);
122  m_Controls->stopStreamPushButton->setEnabled(false);
123  m_Controls->fpsLabel->setEnabled(false);
124  m_Controls->fpsSpinBox->setEnabled(false);
125  break;
127  //check the number of connections of the device, a server can be in
128  //the running state even if there is no connected device, this part of
129  //the GUI shall just be available when there is a connection
130  if (this->m_IGTLDevice->GetNumberOfConnections() == 0)
131  {
132  m_Controls->messageSourceSelectionWidget->setEnabled(false);
133  m_Controls->selectedSourceLabel->setText("<none>");
134  m_Controls->startStreamPushButton->setEnabled(false);
135  m_Controls->selectedSourceLabel->setEnabled(false);
136  m_Controls->label->setEnabled(false);
137  m_Controls->stopStreamPushButton->setEnabled(false);
138  m_Controls->fpsLabel->setEnabled(false);
139  m_Controls->fpsSpinBox->setEnabled(false);
140  }
141  else //there is a connection
142  {
143  //check if the user already selected a source to stream
144  if (this->m_IGTLMsgSource.IsNull()) // he did not so far
145  {
146  m_Controls->messageSourceSelectionWidget->setEnabled(true);
147  m_Controls->selectedSourceLabel->setText("<none>");
148  m_Controls->startStreamPushButton->setEnabled(false);
149  m_Controls->selectedSourceLabel->setEnabled(false);
150  m_Controls->label->setEnabled(false);
151  m_Controls->stopStreamPushButton->setEnabled(false);
152  m_Controls->fpsLabel->setEnabled(false);
153  m_Controls->fpsSpinBox->setEnabled(false);
154  }
155  else //user already selected a source
156  {
157  QString nameOfSource =
158  QString::fromStdString(m_IGTLMsgSource->GetName());
159  m_Controls->messageSourceSelectionWidget->setEnabled(true);
160  m_Controls->selectedSourceLabel->setText(nameOfSource);
161  m_Controls->selectedSourceLabel->setEnabled(true);
162  m_Controls->label->setEnabled(true);
163 
164  //check if the streaming is already running
165  if (this->m_IGTLMsgProvider->IsStreaming())
166  {
167  m_Controls->startStreamPushButton->setEnabled(false);
168  m_Controls->stopStreamPushButton->setEnabled(true);
169  m_Controls->fpsLabel->setEnabled(false);
170  m_Controls->fpsSpinBox->setEnabled(false);
171  }
172  else
173  {
174  m_Controls->startStreamPushButton->setEnabled(true);
175  m_Controls->stopStreamPushButton->setEnabled(false);
176  m_Controls->fpsLabel->setEnabled(true);
177  m_Controls->fpsSpinBox->setEnabled(true);
178  }
179  }
180  }
181  break;
182  default:
183  mitkThrow() << "Invalid Device State";
184  break;
185  }
186  }
187  else
188  {
189  this->DisableSourceControls();
190  }
191 }
192 
195 {
196  //reset the GUI
198 
199  if (provider.IsNull())
200  return;
201 
202  //reset the observers
203  this->RemoveObserver();
204 
205  //disconnect the timer
206  disconnect(&this->m_StreamingTimer);
207 
208  this->m_IGTLMsgProvider = provider;
209 
210  //get the device
211  this->m_IGTLDevice = this->m_IGTLMsgProvider->GetIGTLDevice();
212 
213  //check if the device is a server or a client
214  if (dynamic_cast<mitk::IGTLClient*>(
215  this->m_IGTLDevice.GetPointer()) == NULL)
216  {
217  m_IsClient = false;
218  }
219  else
220  {
221  m_IsClient = true;
222  }
223 
224  typedef itk::SimpleMemberCommand< QmitkIGTLStreamingManagementWidget > CurCommandType;
225  // CurCommandType::Pointer messageReceivedCommand = CurCommandType::New();
226  // messageReceivedCommand->SetCallbackFunction(
227  // this, &QmitkIGTLStreamingManagementWidget::OnMessageReceived );
228  // this->m_MessageReceivedObserverTag =
229  // this->m_IGTLDevice->AddObserver(mitk::MessageReceivedEvent(), messageReceivedCommand);
230 
231  // CurCommandType::Pointer commandReceivedCommand = CurCommandType::New();
232  // commandReceivedCommand->SetCallbackFunction(
233  // this, &QmitkIGTLStreamingManagementWidget::OnCommandReceived );
234  // this->m_CommandReceivedObserverTag =
235  // this->m_IGTLDevice->AddObserver(mitk::CommandReceivedEvent(), commandReceivedCommand);
236 
237  CurCommandType::Pointer connectionLostCommand = CurCommandType::New();
238  connectionLostCommand->SetCallbackFunction(
240  this->m_LostConnectionObserverTag = this->m_IGTLDevice->AddObserver(
241  mitk::LostConnectionEvent(), connectionLostCommand);
242 
243  CurCommandType::Pointer newConnectionCommand = CurCommandType::New();
244  newConnectionCommand->SetCallbackFunction(
246  this->m_NewConnectionObserverTag = this->m_IGTLDevice->AddObserver(
247  mitk::NewClientConnectionEvent(), newConnectionCommand);
248 
249  CurCommandType::Pointer stateModifiedCommand = CurCommandType::New();
250  stateModifiedCommand->SetCallbackFunction(
252  this->m_StateModifiedObserverTag = this->m_IGTLDevice->AddObserver(
253  itk::ModifiedEvent(), stateModifiedCommand);
254 
255  CurCommandType::Pointer startStreamingTimerCommand = CurCommandType::New();
256  startStreamingTimerCommand->SetCallbackFunction(
258  this->m_StartStreamingTimerObserverTag = this->m_IGTLMsgProvider->AddObserver(
259  mitk::StreamingStartRequiredEvent(), startStreamingTimerCommand);
260 
261  CurCommandType::Pointer stopStreamingTimerCommand = CurCommandType::New();
262  stopStreamingTimerCommand->SetCallbackFunction(
264  this->m_StopStreamingTimerObserverTag = this->m_IGTLMsgProvider->AddObserver(
265  mitk::StreamingStopRequiredEvent(), stopStreamingTimerCommand);
266 
267  this->AdaptGUIToState();
268 }
269 
271 {
272  m_Controls->selectedSourceLabel->setText("<none>");
273  m_Controls->startStreamPushButton->setEnabled(false);
274  m_Controls->stopStreamPushButton->setEnabled(false);
275  m_Controls->fpsLabel->setEnabled(false);
276  m_Controls->fpsSpinBox->setEnabled(false);
277  m_Controls->selectedSourceLabel->setEnabled(false);
278  m_Controls->label->setEnabled(false);
279  m_Controls->messageSourceSelectionWidget->setEnabled(false);
280 }
281 
284 {
285  //reset everything
286  this->DisableSourceControls();
287 
288  if (source.IsNotNull()) //no source selected
289  {
290  this->m_IGTLMsgSource = source;
291  m_Controls->selectedSourceLabel->setText(source->GetName().c_str());
292  m_Controls->selectedSourceLabel->setEnabled(true);
293  }
294 
295  this->AdaptGUIToState();
296 }
297 
299 {
300  unsigned int fps = this->m_Controls->fpsSpinBox->value();
301  this->m_IGTLMsgProvider->StartStreamingOfSource(this->m_IGTLMsgSource, fps);
302  this->AdaptGUIToState();
303 }
304 
306 {
307  this->m_IGTLMsgProvider->StopStreamingOfSource(this->m_IGTLMsgSource);
308  this->AdaptGUIToState();
309 }
310 
312 {
313 }
314 
316 {
317 }
318 
320 {
321  emit AdaptGUIToStateSignal();
322 }
323 
325 {
326  emit AdaptGUIToStateSignal();
327 }
328 
330 {
332 }
333 
335 {
336  if (this->m_IGTLMsgProvider.IsNotNull())
337  {
338  //get the frame rate
339  unsigned int interval = this->m_IGTLMsgProvider->GetStreamingTime();
340  //connect the update method
341  connect(&m_StreamingTimer, SIGNAL(timeout()), this, SLOT(OnStreamingTimerTimeout()));
342  //start the timer
343  this->m_StreamingTimer.start(interval);
344  }
345  emit AdaptGUIToStateSignal();
346 }
347 
349 {
350  //stop the timer
351  this->m_StreamingTimer.stop();
352  //if the provider is still valid disconnect from it
353  if (this->m_IGTLMsgProvider.IsNotNull())
354  {
355  //disconnect the update method
356  disconnect(&m_StreamingTimer, SIGNAL(timeout()), this, SLOT(OnStreamingTimerTimeout()));
357  }
358  emit AdaptGUIToStateSignal();
359 }
360 
362 {
363  if (this->m_IGTLMsgSource.IsNotNull())
364  {
365  this->m_IGTLMsgProvider->Update();
366  }
367 }
368 
370 {
371  //get the current selection and call SourceSelected which will call AdaptGUI
373  m_Controls->messageSourceSelectionWidget->GetSelectedIGTLMessageSource();
374  SourceSelected(curSelSrc);
375 }
itk::SmartPointer< Self > Pointer
void OnNewConnection()
Is called when the current device connected to another device.
void SourceSelected(mitk::IGTLMessageSource::Pointer source)
Is called when a new source is selected.
void OnMessageReceived()
Is called when the current device received a message.
virtual void CreateConnections()
Creation of the connections.
mitk::IGTLDevice::Pointer m_IGTLDevice
holds the OpenIGTLink device
void AdaptGUIToState()
Adapts the GUI to the state of the device.
void OnCommandReceived()
Is called when the current device received a command.
void OnLostConnection()
Is called when the current device lost a connection to one of its sockets.
#define mitkThrow()
void SelectSourceAndAdaptGUISignal()
used for thread seperation, the worker thread must not call SelectSourceAndAdaptGUI directly...
IGTLDeviceState
Type for state variable. The IGTLDevice is always in one of these states.
void AdaptGUIToStateSignal()
used for thread seperation, the worker thread must not call AdaptGUIToState directly. QT signals are thread safe and seperate the threads
void SelectSourceAndAdaptGUI()
selects the current source and adapts the GUI according to the selection
QmitkIGTLStreamingManagementWidget(QWidget *parent=0, Qt::WindowFlags f=0)
QTimer m_StreamingTimer
the streaming timer that periodically calls the update method of the provider
void LoadSource(mitk::IGTLMessageProvider::Pointer provider)
void OnStartStreamingTimer()
Is called when provider requests the start of the streaming timer.
mitk::IGTLMessageSource::Pointer m_IGTLMsgSource
holds the IGTLDeviceSource we are working with.
mitk::IGTLMessageProvider::Pointer m_IGTLMsgProvider
holds the IGTL Message Provider that will send the stream
Ui::QmitkIGTLStreamingManagementWidgetControls * m_Controls
bool m_IsClient
flag to indicate if the IGTL device is a client or a server
void OnStopStreamingTimer()
Is called when provider requests the stop of the streaming timer.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.