MITK-IGT
IGT Extension of MITK
Loading...
Searching...
No Matches
QmitkIGTLDeviceSetupConnectionWidget.cpp
Go to the documentation of this file.
1/*============================================================================
2
3The Medical Imaging Interaction Toolkit (MITK)
4
5Copyright (c) German Cancer Research Center (DKFZ)
6All rights reserved.
7
8Use of this source code is governed by a 3-clause BSD license that can be
9found in the LICENSE file.
10
11============================================================================*/
12
14
15//mitk headers
16#include <mitkSurface.h>
18#include <mitkDataStorage.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 <QRegularExpressionValidator>
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;
50}
51
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 auto v = new QRegularExpressionValidator(this);
83 QRegularExpression 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->setRegularExpression(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()),
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
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
356
360
365
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}
void AdaptGUIToState()
Adapts the GUI to the state of the device.
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 OnBufferIncomingMessages(int state)
Enables/Disables the buffering of incoming messages.
QTimer m_FPSCalculationTimer
the timer used to calculate the frames per second
mitk::IGTLDevice::Pointer m_IGTLDevice
holds the OpenIGTLink device
unsigned int m_NumSentFramesSinceLastUpdate
the number of sent frames (messages) since the last fps calculation update
virtual void CreateConnections()
Creation of the connections.
void OnMessageSent()
Is called when the current device received a message.
void AdaptGUIToStateSignal()
used for thread seperation, the worker thread must not call AdaptGUIToState directly....
void OnLostConnection()
Is called when the current device received a message.
void Initialize(mitk::IGTLDevice::Pointer device)
Initializes the widget with the given device.
void OnLogMessageDetailsCheckBoxClicked()
Enables/Disables the detailed logging of incoming/outgoing messages.
void OnCommandReceived()
Is called when the current device received a command.
void OnMessageReceived()
Is called when the current device received a message.
Ui::QmitkIGTLDeviceSetupConnectionWidgetControls * m_Controls
void OnBufferOutgoingMessages(int state)
Enables/Disables the buffering of outgoing messages.
QmitkIGTLDeviceSetupConnectionWidget(QWidget *parent=nullptr, Qt::WindowFlags f={})
unsigned int m_NumReceivedFramesSinceLastUpdate
the number of received frames (messages) since the last fps calculation update
Superclass for OpenIGTLink clients.
IGTLDeviceState
Type for state variable. The IGTLDevice is always in one of these states.