Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
QmitkIGTLDeviceCommandWidget.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 const std::string QmitkIGTLDeviceCommandWidget::VIEW_ID =
37  "org.mitk.views.igtldevicesourcemanagementwidget";
38 
40  QWidget* parent, Qt::WindowFlags f)
41  : QWidget(parent, f), m_IsClient(false), m_MessageReceivedObserverTag(0), m_CommandReceivedObserverTag(0), m_LostConnectionObserverTag(0), m_NewConnectionObserverTag(0), m_StateModifiedObserverTag(0)
42 {
43  m_Controls = nullptr;
44  this->m_IGTLDevice = nullptr;
45  CreateQtPartControl(this);
46 }
47 
48 
50 {
56 }
57 
59 {
60  if (!m_Controls)
61  {
62  // create GUI widgets
63  m_Controls = new Ui::QmitkIGTLDeviceCommandWidgetControls;
64  // setup GUI widgets
65  m_Controls->setupUi(parent);
66  }
67 
68  //connect slots with signals
70 }
71 
73 {
74  if (m_Controls)
75  {
76  // connect the widget items with the methods
77  connect( m_Controls->butSendCommand, SIGNAL(clicked()),
78  this, SLOT(OnSendCommand()));
79  connect( m_Controls->commandsComboBox,
80  SIGNAL(currentIndexChanged(const QString &)),
81  this, SLOT(OnCommandChanged(const QString &)));
82  }
83  //this is used for thread seperation, otherwise the worker thread would change the ui elements
84  //which would cause an exception
85  connect(this, SIGNAL(AdaptGUIToStateSignal()), this, SLOT(AdaptGUIToState()));
86 }
87 
88 
90 {
91  //this->AdaptGUIToState();
92  emit AdaptGUIToStateSignal();
93 }
94 
96 {
97  if (this->m_IGTLDevice.IsNotNull())
98  {
99  //check the state of the device
100  mitk::IGTLDevice::IGTLDeviceState state = this->m_IGTLDevice->GetState();
101 
102  switch (state) {
104  this->m_Controls->commandsComboBox->setEnabled(false);
105  this->m_Controls->butSendCommand->setEnabled(false);
106  this->m_Controls->fpsSpinBox->setEnabled(false);
107  break;
109  this->m_Controls->commandsComboBox->setEnabled(true);
110  this->m_Controls->butSendCommand->setEnabled(true);
111  this->m_Controls->fpsSpinBox->setEnabled(false);
112  break;
114  if ( this->m_IGTLDevice->GetNumberOfConnections() == 0 )
115  {
116  //just a server can run and have 0 connections
117  this->m_Controls->butSendCommand->setEnabled(false);
118  this->m_Controls->fpsSpinBox->setEnabled(false);
119  this->m_Controls->commandsComboBox->setEnabled(false);
120  }
121  else
122  {
123  this->m_Controls->commandsComboBox->setEnabled(true);
124  this->m_Controls->butSendCommand->setEnabled(true);
125  // this->m_Controls->fpsSpinBox->setEnabled(true);
126  }
127  break;
128  default:
129  mitkThrow() << "Invalid Device State";
130  break;
131  }
132  }
133  else
134  {
135  this->DisableSourceControls();
136  }
137 }
138 
139 void QmitkIGTLDeviceCommandWidget::Initialize(mitk::IGTLDevice::Pointer device)
140 {
141  //reset the GUI
143  //reset the observers
144  if ( this->m_IGTLDevice.IsNotNull() )
145  {
146  this->m_IGTLDevice->RemoveObserver(m_MessageReceivedObserverTag);
147  this->m_IGTLDevice->RemoveObserver(m_CommandReceivedObserverTag);
148  this->m_IGTLDevice->RemoveObserver(m_LostConnectionObserverTag);
149  this->m_IGTLDevice->RemoveObserver(m_NewConnectionObserverTag);
150  this->m_IGTLDevice->RemoveObserver(m_StateModifiedObserverTag);
151  }
152 
153  if(device.IsNotNull())
154  {
155  //get the device
156  this->m_IGTLDevice = device;
157 
158  //check if the device is a server or a client
159  if ( dynamic_cast<mitk::IGTLClient*>(
160  this->m_IGTLDevice.GetPointer()) == nullptr )
161  {
162  m_IsClient = false;
163  }
164  else
165  {
166  m_IsClient = true;
167  }
168 
169  typedef itk::SimpleMemberCommand< QmitkIGTLDeviceCommandWidget > CurCommandType;
170 // CurCommandType::Pointer messageReceivedCommand = CurCommandType::New();
171 // messageReceivedCommand->SetCallbackFunction(
172 // this, &QmitkIGTLDeviceCommandWidget::OnMessageReceived );
173 // this->m_MessageReceivedObserverTag =
174 // this->m_IGTLDevice->AddObserver(mitk::MessageReceivedEvent(), messageReceivedCommand);
175 
176 // CurCommandType::Pointer commandReceivedCommand = CurCommandType::New();
177 // commandReceivedCommand->SetCallbackFunction(
178 // this, &QmitkIGTLDeviceCommandWidget::OnCommandReceived );
179 // this->m_CommandReceivedObserverTag =
180 // this->m_IGTLDevice->AddObserver(mitk::CommandReceivedEvent(), commandReceivedCommand);
181 
182  CurCommandType::Pointer connectionLostCommand = CurCommandType::New();
183  connectionLostCommand->SetCallbackFunction(
185  this->m_LostConnectionObserverTag = this->m_IGTLDevice->AddObserver(
186  mitk::LostConnectionEvent(), connectionLostCommand);
187 
188  CurCommandType::Pointer newConnectionCommand = CurCommandType::New();
189  newConnectionCommand->SetCallbackFunction(
191  this->m_NewConnectionObserverTag = this->m_IGTLDevice->AddObserver(
192  mitk::NewClientConnectionEvent(), newConnectionCommand);
193 
194  CurCommandType::Pointer stateModifiedCommand = CurCommandType::New();
195  stateModifiedCommand->SetCallbackFunction(
197  this->m_StateModifiedObserverTag = this->m_IGTLDevice->AddObserver(
198  itk::ModifiedEvent(), stateModifiedCommand);
199 
200  //Fill the commands combo box with all available commands
202  }
203  else
204  {
205  m_IGTLDevice = nullptr;
206  }
207 
208  this->AdaptGUIToState();
209 }
210 
212 {
213  this->m_Controls->commandsComboBox->setEnabled(false);
214  this->m_Controls->butSendCommand->setEnabled(false);
215  this->m_Controls->fpsSpinBox->setEnabled(false);
216 }
217 
218 
219 
220 
222 {
223  //Set the frames per second of the current command in case of a STT_ command
224  if ( std::strcmp( m_CurrentCommand->GetDeviceType(), "STT_BIND" ) == 0 )
225  {
226  ((igtl::StartBindMessage*)this->m_CurrentCommand.GetPointer())->
227  SetResolution(this->m_Controls->fpsSpinBox->value());
228  }
229  else if ( std::strcmp( m_CurrentCommand->GetDeviceType(), "STT_QTDATA" ) == 0 )
230  {
231  ((igtl::StartQuaternionTrackingDataMessage*)m_CurrentCommand.GetPointer())->
232  SetResolution(this->m_Controls->fpsSpinBox->value());
233  }
234  else if ( std::strcmp( m_CurrentCommand->GetDeviceType(), "STT_TDATA" ) == 0 )
235  {
236  ((igtl::StartTrackingDataMessage*)this->m_CurrentCommand.GetPointer())->
237  SetResolution(this->m_Controls->fpsSpinBox->value());
238  }
239 
241 }
242 
244  const QString & curCommand)
245 {
246  if ( curCommand.isEmpty() )
247  return;
248 
249  mitk::IGTLMessageFactory::Pointer msgFactory =
250  this->m_IGTLDevice->GetMessageFactory();
251  //create a new message that fits to the selected get message type command
252  this->m_CurrentCommand = msgFactory->CreateInstance( curCommand.toStdString());
253  //enable/disable the FPS spinbox
254  this->m_Controls->fpsSpinBox->setEnabled(curCommand.contains("STT_"));
255 }
256 
258 {
259  //get the IGTL device that invoked this event
260 // mitk::IGTLDevice* dev = (mitk::IGTLDevice*)caller;
261 
262  //this->AdaptGUIToState();
263  emit AdaptGUIToStateSignal();
264 }
265 
267 {
268  //this->AdaptGUIToState();
269  emit AdaptGUIToStateSignal();
270 }
271 
273 {
274  //load the msg factory from the client (maybe this will be moved later on)
275  mitk::IGTLMessageFactory::Pointer msgFactory =
276  this->m_IGTLDevice->GetMessageFactory();
277  //get the available commands as std::list<std::string>
278  std::list<std::string> commandsList_ =
279  msgFactory->GetAvailableMessageRequestTypes();
280  //create a string list to convert the std::list
281  this->m_Controls->commandsComboBox->clear();
282  while ( commandsList_.size() )
283  {
284  //fill the combo box with life
285  this->m_Controls->commandsComboBox->addItem(
286  QString::fromStdString(commandsList_.front()));
287  commandsList_.pop_front();
288  }
289 }
void AdaptGUIToState()
Adapts the GUI to the state of the device.
void OnNewConnection()
Is called when the current device connected to another device.
mitk::IGTLDevice::Pointer m_IGTLDevice
holds the OpenIGTLink device
void OnCommandChanged(const QString &curCommand)
void OnDeviceStateChanged()
Calls AdaptGUIToState()
virtual void CreateQtPartControl(QWidget *parent)
bool m_IsClient
flag to indicate if the IGTL device is a client or a server
void AdaptGUIToStateSignal()
used for thread seperation, the worker thread must not call AdaptGUIToState directly QT signals are t...
virtual void CreateConnections()
Creation of the connections.
Ui::QmitkIGTLDeviceCommandWidgetControls * m_Controls
void Initialize(mitk::IGTLDevice::Pointer device)
Initializes the widget with the given device.
#define mitkThrow()
IGTLDeviceState
Type for state variable. The IGTLDevice is always in one of these states.
QmitkIGTLDeviceCommandWidget(QWidget *parent=nullptr, Qt::WindowFlags f=nullptr)
static Pointer New()
void FillCommandsComboBox()
Fills the commands combo box with available commands.
igtl::MessageBase::Pointer m_CurrentCommand
void OnLostConnection()
Is called when the current device received a message.