Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
QmitkIGTLDeviceSetupConnectionWidget.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.igtldevicesetupconnectionwidget";
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);
52 }
53 
55 {
56  this->RemoveObserver();
57 }
58 
60 {
61  if (this->m_IGTLDevice.IsNotNull())
62  {
63  this->m_IGTLDevice->RemoveObserver(m_MessageReceivedObserverTag);
64  this->m_IGTLDevice->RemoveObserver(m_MessageSentObserverTag);
65  this->m_IGTLDevice->RemoveObserver(m_CommandReceivedObserverTag);
66  this->m_IGTLDevice->RemoveObserver(m_LostConnectionObserverTag);
67  this->m_IGTLDevice->RemoveObserver(m_NewConnectionObserverTag);
68  this->m_IGTLDevice->RemoveObserver(m_StateModifiedObserverTag);
69  }
70 }
71 
73 {
74  if (!m_Controls)
75  {
76  // create GUI widgets
77  m_Controls = new Ui::QmitkIGTLDeviceSetupConnectionWidgetControls;
78  // setup GUI widgets
79  m_Controls->setupUi(parent);
80  }
81 
82  // set the validator for the ip edit box (values must be between 0 and 255 and
83  // there are four of them, seperated with a point
84  QRegExpValidator *v = new QRegExpValidator(this);
85  QRegExp rx("((1{0,1}[0-9]{0,2}|2[0-4]{1,1}[0-9]{1,1}|25[0-5]{1,1})\\.){3,3}(1{0,1}[0-9]{0,2}|2[0-4]{1,1}[0-9]{1,1}|25[0-5]{1,1})");
86  v->setRegExp(rx);
87  m_Controls->editIP->setValidator(v);
88  // set the validator for the port edit box (values must be between 1 and 65535)
89  m_Controls->editPort->setValidator(new QIntValidator(1, 65535, this));
90 
91  m_FPSCalculationTimer.start(1000);
92 
93  //connect slots with signals
95 }
96 
98 {
99  if (m_Controls)
100  {
101  // connect the widget items with the methods
102  connect(m_Controls->butConnect, SIGNAL(clicked()),
103  this, SLOT(OnConnect()));
104  connect(m_Controls->editPort, SIGNAL(editingFinished()),
105  this, SLOT(OnPortChanged()));
106  connect(m_Controls->editIP, SIGNAL(editingFinished()),
107  this, SLOT(OnHostnameChanged()));
108  connect(m_Controls->bufferInMsgCheckBox, SIGNAL(stateChanged(int)),
109  this, SLOT(OnBufferIncomingMessages(int)));
110  connect(m_Controls->bufferOutMsgCheckBox, SIGNAL(stateChanged(int)),
111  this, SLOT(OnBufferOutgoingMessages(int)));
112  connect(&m_FPSCalculationTimer, SIGNAL(timeout()),
113  this, SLOT(OnUpdateFPSLabel()));
114  }
115  //this is used for thread seperation, otherwise the worker thread would change the ui elements
116  //which would cause an exception
117  connect(this, SIGNAL(AdaptGUIToStateSignal()), this, SLOT(AdaptGUIToState()));
118 }
119 
121 {
122  emit AdaptGUIToStateSignal();
123 }
124 
126 {
127  //check the validity of the device
128  if (this->m_IGTLDevice.IsNull())
129  {
130  return;
131  }
132 
133  //check the state of the device
134  mitk::IGTLDevice::IGTLDeviceState state = this->m_IGTLDevice->GetState();
135 
136  switch (state) {
138  if (!m_IsClient)
139  {
140  m_Controls->butConnect->setText("Go Online");
141  this->m_Controls->editIP->setEnabled(false);
142  }
143  else
144  {
145  m_Controls->butConnect->setText("Connect");
146  this->m_Controls->editIP->setEnabled(true);
147  }
148  this->m_Controls->editPort->setEnabled(true);
149  this->m_Controls->logIncomingMsg->setEnabled(false);
150  this->m_Controls->logOutgoingMsg->setEnabled(false);
151  this->m_Controls->bufferInMsgCheckBox->setEnabled(false);
152  this->m_Controls->bufferOutMsgCheckBox->setEnabled(false);
153  this->m_Controls->butConnect->setEnabled(true);
154  this->m_Controls->fpsInLabel->setEnabled(false);
155  this->m_Controls->fpsOutLabel->setEnabled(false);
156  this->m_Controls->fpsInDescrLabel->setEnabled(false);
157  this->m_Controls->fpsOutDescrLabel->setEnabled(false);
158  break;
160  if (m_IsClient)
161  {
162  this->m_Controls->butConnect->setText("Disconnect");
163  }
164  else
165  {
166  this->m_Controls->butConnect->setText("Go Offline");
167  }
168  this->m_Controls->editIP->setEnabled(false);
169  this->m_Controls->editPort->setEnabled(false);
170  this->m_Controls->logIncomingMsg->setEnabled(true);
171  this->m_Controls->logOutgoingMsg->setEnabled(true);
172  this->m_Controls->bufferInMsgCheckBox->setEnabled(true);
173  this->m_Controls->bufferOutMsgCheckBox->setEnabled(true);
174  this->m_Controls->butConnect->setEnabled(true);
175  this->m_Controls->fpsInLabel->setEnabled(true);
176  this->m_Controls->fpsOutLabel->setEnabled(true);
177  this->m_Controls->fpsInDescrLabel->setEnabled(true);
178  this->m_Controls->fpsOutDescrLabel->setEnabled(true);
179  break;
181  if (m_IsClient)
182  {
183  this->m_Controls->butConnect->setText("Disconnect");
184  }
185  else
186  {
187  this->m_Controls->butConnect->setText("Go Offline");
188  }
189  this->m_Controls->editIP->setEnabled(false);
190  this->m_Controls->editPort->setEnabled(false);
191  this->m_Controls->logIncomingMsg->setEnabled(true);
192  this->m_Controls->logOutgoingMsg->setEnabled(true);
193  this->m_Controls->bufferInMsgCheckBox->setEnabled(true);
194  this->m_Controls->bufferOutMsgCheckBox->setEnabled(true);
195  this->m_Controls->butConnect->setEnabled(true);
196  this->m_Controls->fpsInLabel->setEnabled(true);
197  this->m_Controls->fpsOutLabel->setEnabled(true);
198  this->m_Controls->fpsInDescrLabel->setEnabled(true);
199  this->m_Controls->fpsOutDescrLabel->setEnabled(true);
200  break;
201  default:
202  mitkThrow() << "Invalid Device State";
203  break;
204  }
205 }
206 
209 {
210  //reset the GUI
212  //reset the observers
213  this->RemoveObserver();
214 
215  if (device.IsNotNull())
216  {
217  this->m_IGTLDevice = device;
218 
219  //check if the device is a server or a client
220  if (dynamic_cast<mitk::IGTLClient*>(
221  this->m_IGTLDevice.GetPointer()) == NULL)
222  {
223  m_IsClient = false;
224  }
225  else
226  {
227  m_IsClient = true;
228  }
229 
230  this->AdaptGUIToState();
231 
232  typedef itk::SimpleMemberCommand< QmitkIGTLDeviceSetupConnectionWidget > CurCommandType;
233  CurCommandType::Pointer messageSentCommand = CurCommandType::New();
234  messageSentCommand->SetCallbackFunction(
236  this->m_MessageSentObserverTag = this->m_IGTLDevice->AddObserver(
237  mitk::MessageSentEvent(), messageSentCommand);
238 
239  CurCommandType::Pointer messageReceivedCommand = CurCommandType::New();
240  messageReceivedCommand->SetCallbackFunction(
242  this->m_MessageReceivedObserverTag = this->m_IGTLDevice->AddObserver(
243  mitk::MessageReceivedEvent(), messageReceivedCommand);
244 
245  CurCommandType::Pointer commandReceivedCommand = CurCommandType::New();
246  commandReceivedCommand->SetCallbackFunction(
248  this->m_CommandReceivedObserverTag = this->m_IGTLDevice->AddObserver(
249  mitk::CommandReceivedEvent(), commandReceivedCommand);
250 
251  CurCommandType::Pointer connectionLostCommand = CurCommandType::New();
252  connectionLostCommand->SetCallbackFunction(
254  this->m_LostConnectionObserverTag = this->m_IGTLDevice->AddObserver(
255  mitk::LostConnectionEvent(), connectionLostCommand);
256 
257  CurCommandType::Pointer newConnectionCommand = CurCommandType::New();
258  newConnectionCommand->SetCallbackFunction(
260  this->m_NewConnectionObserverTag = this->m_IGTLDevice->AddObserver(
261  mitk::NewClientConnectionEvent(), newConnectionCommand);
262 
263  CurCommandType::Pointer stateModifiedCommand = CurCommandType::New();
264  stateModifiedCommand->SetCallbackFunction(
266  this->m_StateModifiedObserverTag = this->m_IGTLDevice->AddObserver(
267  itk::ModifiedEvent(), stateModifiedCommand);
268 
269  OnBufferIncomingMessages(m_Controls->bufferInMsgCheckBox->isChecked());
270  OnBufferOutgoingMessages(m_Controls->bufferOutMsgCheckBox->isChecked());
271  }
272  else
273  {
274  m_IGTLDevice = NULL;
275  }
276 }
277 
279 {
280  m_Controls->editIP->setEnabled(false);
281  m_Controls->editPort->setEnabled(false);
282  m_Controls->butConnect->setEnabled(false);
283  m_Controls->bufferInMsgCheckBox->setEnabled(false);
284  m_Controls->bufferOutMsgCheckBox->setEnabled(false);
285  m_Controls->logIncomingMsg->setEnabled(false);
286  m_Controls->logOutgoingMsg->setEnabled(false);
287 }
288 
290 {
291  if (m_IGTLDevice->GetState() == mitk::IGTLDevice::Setup)
292  {
293  QString port = m_Controls->editPort->text();
294  m_IGTLDevice->SetPortNumber(port.toInt());
295  std::string hostname = m_Controls->editIP->text().toStdString();
296  m_IGTLDevice->SetHostname(hostname);
297  //connect with the other OpenIGTLink device => changes the state from Setup
298  //to Ready
299  if (m_IGTLDevice->OpenConnection())
300  {
301  //starts the communication thread => changes the state from Ready to
302  //Running
303  if (m_IGTLDevice->StartCommunication())
304  {
305  if (this->m_IsClient)
306  {
307  MITK_INFO("IGTLDeviceSourceManagementWidget")
308  << "Successfully connected to " << hostname
309  << " on port " << port.toStdString();
310  }
311  }
312  else
313  {
314  MITK_ERROR("QmitkIGTLDeviceSetupConnectionWidget") <<
315  "Could not start a communication with the"
316  "server because the client is in the wrong state";
317  }
318  }
319  else
320  {
321  MITK_ERROR("QmitkIGTLDeviceSetupConnectionWidget") <<
322  "Could not connect to the server. "
323  "Please check the hostname and port.";
324  }
325  }
326  else if (m_IGTLDevice->GetState() == mitk::IGTLDevice::Ready || m_IGTLDevice->GetState() == mitk::IGTLDevice::Running)
327  {
328  m_IGTLDevice->CloseConnection();
329  MITK_INFO("QmitkIGTLDeviceSetupConnectionWidget") << "Closed connection";
330  }
331  else
332  {
333  mitkThrow() << "Invalid state of IGTLDevice";
334  }
335  this->AdaptGUIToState();
336 }
337 
339 {
340 }
341 
343 {
344 }
345 
347 {
348  emit AdaptGUIToStateSignal();
349 }
350 
352 {
353  emit AdaptGUIToStateSignal();
354 }
355 
357 {
358  if (this->m_Controls->logIncomingMsg->isChecked())
359  {
360  MITK_INFO("IGTLDeviceSetupConnectionWidget") << "Received a message: "
361  << this->m_IGTLDevice->GetMessageQueue()->GetLatestMsgInformationString();
362  }
364 }
365 
367 {
368  if (this->m_Controls->logOutgoingMsg->isChecked())
369  {
370  MITK_INFO("IGTLDeviceSetupConnectionWidget") << "Sent a message.";
371  }
373 }
374 
376 {
377  if (this->m_Controls->logIncomingMsg->isChecked())
378  {
379  MITK_INFO("IGTLDeviceSetupConnectionWidget") << "Received a command: "
380  << this->m_IGTLDevice->GetMessageQueue()->GetLatestMsgInformationString();
381  }
382 }
383 
385 {
386  if (this->m_IGTLDevice.IsNotNull())
387  {
388  this->m_IGTLDevice->EnableInfiniteBufferingMode(
389  this->m_IGTLDevice->GetMessageQueue(), (bool)state);
390  }
391 }
392 
394 {
395  if (this->m_IGTLDevice.IsNotNull())
396  {
397  this->m_IGTLDevice->EnableInfiniteBufferingMode(
398  this->m_IGTLDevice->GetMessageQueue(), (bool)state);
399  }
400 }
401 
403 {
404  double fpsIn = m_NumReceivedFramesSinceLastUpdate / 1.0;
405  double fpsOut = m_NumSentFramesSinceLastUpdate / 1.0;
406  this->m_Controls->fpsInLabel->setText(QString::number(fpsIn));
407  this->m_Controls->fpsOutLabel->setText(QString::number(fpsOut));
410 }
itk::SmartPointer< Self > Pointer
#define MITK_INFO
Definition: mitkLogMacros.h:22
QTimer m_FPSCalculationTimer
the timer used to calculate the frames per second
#define MITK_ERROR
Definition: mitkLogMacros.h:24
void OnMessageReceived()
Is called when the current device received a message.
void OnMessageSent()
Is called when the current device received a message.
Ui::QmitkIGTLDeviceSetupConnectionWidgetControls * m_Controls
void Initialize(mitk::IGTLDevice::Pointer device)
Initializes the widget with the given device.
void OnCommandReceived()
Is called when the current device received a command.
void AdaptGUIToState()
Adapts the GUI to the state of the device.
unsigned int m_NumSentFramesSinceLastUpdate
the number of sent frames (messages) since the last fps calculation update
mitk::IGTLDevice::Pointer m_IGTLDevice
holds the OpenIGTLink device
#define mitkThrow()
void OnLostConnection()
Is called when the current device received a message.
IGTLDeviceState
Type for state variable. The IGTLDevice is always in one of these states.
QmitkIGTLDeviceSetupConnectionWidget(QWidget *parent=0, Qt::WindowFlags f=0)
void OnNewConnection()
Is called when the current device connected to another device.
bool m_IsClient
flag to indicate if the IGTL device is a client or a server
void OnBufferOutgoingMessages(int state)
Enables/Disables the buffering of outgoing messages.
void OnBufferIncomingMessages(int state)
Enables/Disables the buffering of incoming messages.
void AdaptGUIToStateSignal()
used for thread seperation, the worker thread must not call AdaptGUIToState directly. QT signals are thread safe and seperate the threads
virtual void CreateConnections()
Creation of the connections.
unsigned int m_NumReceivedFramesSinceLastUpdate
the number of received frames (messages) since the last fps calculation update
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.