Medical Imaging Interaction Toolkit  2018.4.99-389bf124
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 (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 
14 
15 //mitk headers
16 #include <mitkSurface.h>
17 #include <mitkIGTLDeviceSource.h>
18 #include <mitkDataStorage.h>
19 #include <mitkIGTLMessageFactory.h>
20 
21 //qt headers
22 #include <qfiledialog.h>
23 #include <qinputdialog.h>
24 #include <qmessagebox.h>
25 #include <qscrollbar.h>
26 
27 //igtl
28 #include <igtlStringMessage.h>
29 #include <igtlBindMessage.h>
30 #include <igtlQuaternionTrackingDataMessage.h>
31 #include <igtlTrackingDataMessage.h>
32 
33 //poco headers
34 #include <Poco/Path.h>
35 
36 #include <QRegExpValidator>
37 
39 "org.mitk.views.igtldevicesetupconnectionwidget";
40 
42  QWidget* parent, Qt::WindowFlags f)
43  : QWidget(parent, f), m_IsClient(false)
44 {
45  m_Controls = nullptr;
46  this->m_IGTLDevice = nullptr;
47  CreateQtPartControl(this);
50 }
51 
53 {
54  this->RemoveObserver();
55 }
56 
58 {
59  if (this->m_IGTLDevice.IsNotNull())
60  {
61  this->m_IGTLDevice->RemoveObserver(m_MessageReceivedObserverTag);
62  this->m_IGTLDevice->RemoveObserver(m_MessageSentObserverTag);
63  this->m_IGTLDevice->RemoveObserver(m_CommandReceivedObserverTag);
64  this->m_IGTLDevice->RemoveObserver(m_LostConnectionObserverTag);
65  this->m_IGTLDevice->RemoveObserver(m_NewConnectionObserverTag);
66  this->m_IGTLDevice->RemoveObserver(m_StateModifiedObserverTag);
67  }
68 }
69 
71 {
72  if (!m_Controls)
73  {
74  // create GUI widgets
75  m_Controls = new Ui::QmitkIGTLDeviceSetupConnectionWidgetControls;
76  // setup GUI widgets
77  m_Controls->setupUi(parent);
78  }
79 
80  // set the validator for the ip edit box (values must be between 0 and 255 and
81  // there are four of them, seperated with a point
82  QRegExpValidator *v = new QRegExpValidator(this);
83  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})");
84  v->setRegExp(rx);
85  m_Controls->editIP->setValidator(v);
86  // set the validator for the port edit box (values must be between 1 and 65535)
87  m_Controls->editPort->setValidator(new QIntValidator(1, 65535, this));
88 
89  m_FPSCalculationTimer.start(1000);
90 
91  //connect slots with signals
93 }
94 
96 {
97  if (m_Controls)
98  {
99  // connect the widget items with the methods
100  connect(m_Controls->butConnect, SIGNAL(clicked()),
101  this, SLOT(OnConnect()));
102  connect(m_Controls->editPort, SIGNAL(editingFinished()),
103  this, SLOT(OnPortChanged()));
104  connect(m_Controls->editIP, SIGNAL(editingFinished()),
105  this, SLOT(OnHostnameChanged()));
106  connect(m_Controls->bufferInMsgCheckBox, SIGNAL(stateChanged(int)),
107  this, SLOT(OnBufferIncomingMessages(int)));
108  connect(m_Controls->bufferOutMsgCheckBox, SIGNAL(stateChanged(int)),
109  this, SLOT(OnBufferOutgoingMessages(int)));
110  connect(&m_FPSCalculationTimer, SIGNAL(timeout()),
111  this, SLOT(OnUpdateFPSLabel()));
112  connect(m_Controls->logMessageDetailsCheckBox, SIGNAL(clicked()),
113  this, SLOT(OnLogMessageDetailsCheckBoxClicked()));
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->logMessageStatusCheckBox->setChecked(false);
150  this->m_Controls->logMessageDetailsCheckBox->setChecked(false);
151  this->m_Controls->logMessageStatusCheckBox->setEnabled(false);
152  this->m_Controls->logMessageDetailsCheckBox->setEnabled(false);
153  this->m_Controls->bufferInMsgCheckBox->setEnabled(false);
154  this->m_Controls->bufferOutMsgCheckBox->setEnabled(false);
155  this->m_Controls->butConnect->setEnabled(true);
156  this->m_Controls->fpsInLabel->setEnabled(false);
157  this->m_Controls->fpsOutLabel->setEnabled(false);
158  this->m_Controls->fpsInDescrLabel->setEnabled(false);
159  this->m_Controls->fpsOutDescrLabel->setEnabled(false);
160 
161  if( this->m_IGTLDevice.IsNotNull() )
162  {
163  this->m_IGTLDevice->SetLogMessages(false);
164  }
165 
166  break;
168  if (m_IsClient)
169  {
170  this->m_Controls->butConnect->setText("Disconnect");
171  }
172  else
173  {
174  this->m_Controls->butConnect->setText("Go Offline");
175  }
176  this->m_Controls->editIP->setEnabled(false);
177  this->m_Controls->editPort->setEnabled(false);
178  this->m_Controls->logMessageStatusCheckBox->setEnabled(true);
179  this->m_Controls->logMessageDetailsCheckBox->setEnabled(true);
180  this->m_Controls->bufferInMsgCheckBox->setEnabled(true);
181  this->m_Controls->bufferOutMsgCheckBox->setEnabled(true);
182  this->m_Controls->butConnect->setEnabled(true);
183  this->m_Controls->fpsInLabel->setEnabled(true);
184  this->m_Controls->fpsOutLabel->setEnabled(true);
185  this->m_Controls->fpsInDescrLabel->setEnabled(true);
186  this->m_Controls->fpsOutDescrLabel->setEnabled(true);
187  break;
189  if (m_IsClient)
190  {
191  this->m_Controls->butConnect->setText("Disconnect");
192  }
193  else
194  {
195  this->m_Controls->butConnect->setText("Go Offline");
196  }
197  this->m_Controls->editIP->setEnabled(false);
198  this->m_Controls->editPort->setEnabled(false);
199  this->m_Controls->logMessageStatusCheckBox->setEnabled(true);
200  this->m_Controls->logMessageDetailsCheckBox->setEnabled(true);
201  this->m_Controls->bufferInMsgCheckBox->setEnabled(true);
202  this->m_Controls->bufferOutMsgCheckBox->setEnabled(true);
203  this->m_Controls->butConnect->setEnabled(true);
204  this->m_Controls->fpsInLabel->setEnabled(true);
205  this->m_Controls->fpsOutLabel->setEnabled(true);
206  this->m_Controls->fpsInDescrLabel->setEnabled(true);
207  this->m_Controls->fpsOutDescrLabel->setEnabled(true);
208  break;
209  default:
210  mitkThrow() << "Invalid Device State";
211  break;
212  }
213 }
214 
216  mitk::IGTLDevice::Pointer device)
217 {
218  //reset the GUI
220  //reset the observers
221  this->RemoveObserver();
222 
223  if (device.IsNotNull())
224  {
225  this->m_IGTLDevice = device;
226 
227  //check if the device is a server or a client
228  if (dynamic_cast<mitk::IGTLClient*>(
229  this->m_IGTLDevice.GetPointer()) == nullptr)
230  {
231  m_IsClient = false;
232  }
233  else
234  {
235  m_IsClient = true;
236  }
237 
238  this->AdaptGUIToState();
239 
240  typedef itk::SimpleMemberCommand< QmitkIGTLDeviceSetupConnectionWidget > CurCommandType;
241  CurCommandType::Pointer messageSentCommand = CurCommandType::New();
242  messageSentCommand->SetCallbackFunction(
244  this->m_MessageSentObserverTag = this->m_IGTLDevice->AddObserver(
245  mitk::MessageSentEvent(), messageSentCommand);
246 
247  CurCommandType::Pointer messageReceivedCommand = CurCommandType::New();
248  messageReceivedCommand->SetCallbackFunction(
250  this->m_MessageReceivedObserverTag = this->m_IGTLDevice->AddObserver(
251  mitk::MessageReceivedEvent(), messageReceivedCommand);
252 
253  CurCommandType::Pointer commandReceivedCommand = CurCommandType::New();
254  commandReceivedCommand->SetCallbackFunction(
256  this->m_CommandReceivedObserverTag = this->m_IGTLDevice->AddObserver(
257  mitk::CommandReceivedEvent(), commandReceivedCommand);
258 
259  CurCommandType::Pointer connectionLostCommand = CurCommandType::New();
260  connectionLostCommand->SetCallbackFunction(
262  this->m_LostConnectionObserverTag = this->m_IGTLDevice->AddObserver(
263  mitk::LostConnectionEvent(), connectionLostCommand);
264 
265  CurCommandType::Pointer newConnectionCommand = CurCommandType::New();
266  newConnectionCommand->SetCallbackFunction(
268  this->m_NewConnectionObserverTag = this->m_IGTLDevice->AddObserver(
269  mitk::NewClientConnectionEvent(), newConnectionCommand);
270 
271  CurCommandType::Pointer stateModifiedCommand = CurCommandType::New();
272  stateModifiedCommand->SetCallbackFunction(
274  this->m_StateModifiedObserverTag = this->m_IGTLDevice->AddObserver(
275  itk::ModifiedEvent(), stateModifiedCommand);
276 
277  OnBufferIncomingMessages(m_Controls->bufferInMsgCheckBox->isChecked());
278  OnBufferOutgoingMessages(m_Controls->bufferOutMsgCheckBox->isChecked());
279  }
280  else
281  {
282  m_IGTLDevice = nullptr;
283  }
284 }
285 
287 {
288  m_Controls->editIP->setEnabled(false);
289  m_Controls->editPort->setEnabled(false);
290  m_Controls->butConnect->setEnabled(false);
291  m_Controls->bufferInMsgCheckBox->setEnabled(false);
292  m_Controls->bufferOutMsgCheckBox->setEnabled(false);
293  this->m_Controls->logMessageStatusCheckBox->setChecked(false);
294  this->m_Controls->logMessageDetailsCheckBox->setChecked(false);
295  this->m_Controls->logMessageStatusCheckBox->setEnabled(false);
296  this->m_Controls->logMessageDetailsCheckBox->setEnabled(false);
297 
298  if( this->m_IGTLDevice.IsNotNull() )
299  {
300  this->m_IGTLDevice->SetLogMessages(false);
301  }
302 }
303 
305 {
306  if (m_IGTLDevice->GetState() == mitk::IGTLDevice::Setup)
307  {
308  QString port = m_Controls->editPort->text();
309  m_IGTLDevice->SetPortNumber(port.toInt());
310  std::string hostname = m_Controls->editIP->text().toStdString();
311  m_IGTLDevice->SetHostname(hostname);
312  //connect with the other OpenIGTLink device => changes the state from Setup
313  //to Ready
314  if (m_IGTLDevice->OpenConnection())
315  {
316  //starts the communication thread => changes the state from Ready to
317  //Running
318  if (m_IGTLDevice->StartCommunication())
319  {
320  if (this->m_IsClient)
321  {
322  MITK_INFO("IGTLDeviceSourceManagementWidget")
323  << "Successfully connected to " << hostname
324  << " on port " << port.toStdString();
325  }
326  }
327  else
328  {
329  MITK_ERROR("QmitkIGTLDeviceSetupConnectionWidget") <<
330  "Could not start a communication with the"
331  "server because the client is in the wrong state";
332  }
333  }
334  else
335  {
336  MITK_ERROR("QmitkIGTLDeviceSetupConnectionWidget") <<
337  "Could not connect to the server. "
338  "Please check the hostname and port.";
339  }
340  }
341  else if (m_IGTLDevice->GetState() == mitk::IGTLDevice::Ready || m_IGTLDevice->GetState() == mitk::IGTLDevice::Running)
342  {
343  m_IGTLDevice->CloseConnection();
344  MITK_INFO("QmitkIGTLDeviceSetupConnectionWidget") << "Closed connection";
345  }
346  else
347  {
348  mitkThrow() << "Invalid state of IGTLDevice";
349  }
350  this->AdaptGUIToState();
351 }
352 
354 {
355 }
356 
358 {
359 }
360 
362 {
363  emit AdaptGUIToStateSignal();
364 }
365 
367 {
368  emit AdaptGUIToStateSignal();
369 }
370 
372 {
373  if( this->m_Controls->logMessageStatusCheckBox->isChecked() )
374  {
375  MITK_INFO("IGTLDeviceSetupConnectionWidget") << "Received a message.";
376  }
378 }
379 
381 {
382  if( this->m_Controls->logMessageStatusCheckBox->isChecked() )
383  {
384  MITK_INFO("IGTLDeviceSetupConnectionWidget") << "Sent a message.";
385  }
387 }
388 
390 {
391  if( this->m_Controls->logMessageStatusCheckBox->isChecked() )
392  {
393  MITK_INFO("IGTLDeviceSetupConnectionWidget") << "Received a command.";
394  }
395 }
396 
398 {
399  if (this->m_IGTLDevice.IsNotNull())
400  {
401  this->m_IGTLDevice->EnableNoBufferingMode(
402  this->m_IGTLDevice->GetMessageQueue(), (bool)state);
403  }
404 }
405 
407 {
408  if (this->m_IGTLDevice.IsNotNull())
409  {
410  this->m_IGTLDevice->EnableNoBufferingMode(
411  this->m_IGTLDevice->GetMessageQueue(), (bool)state);
412  }
413 }
414 
416 {
417  double fpsIn = m_NumReceivedFramesSinceLastUpdate / 1.0;
418  double fpsOut = m_NumSentFramesSinceLastUpdate / 1.0;
419  this->m_Controls->fpsInLabel->setText(QString::number(fpsIn));
420  this->m_Controls->fpsOutLabel->setText(QString::number(fpsOut));
423 }
424 
426 {
427  if( this->m_IGTLDevice.IsNull() )
428  {
429  MITK_WARN << "Logging information not passed down to Message Provider.";
430  return;
431  }
432  else
433  {
434  this->m_IGTLDevice->SetLogMessages( this->m_Controls->logMessageDetailsCheckBox->isChecked() );
435  }
436 }
#define MITK_INFO
Definition: mitkLogMacros.h:18
QTimer m_FPSCalculationTimer
the timer used to calculate the frames per second
#define MITK_ERROR
Definition: mitkLogMacros.h:20
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 MITK_WARN
Definition: mitkLogMacros.h:19
QmitkIGTLDeviceSetupConnectionWidget(QWidget *parent=nullptr, Qt::WindowFlags f=nullptr)
#define mitkThrow()
void OnLogMessageDetailsCheckBoxClicked()
Enables/Disables the detailed logging of incoming/outgoing messages.
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.
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