diff --git a/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLMessageSourceSelectionWidget.cpp b/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLMessageSourceSelectionWidget.cpp index 234992bc88..27e1848e8a 100644 --- a/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLMessageSourceSelectionWidget.cpp +++ b/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLMessageSourceSelectionWidget.cpp @@ -1,87 +1,106 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkIGTLMessageSourceSelectionWidget.h" //mitk headers #include #include QmitkIGTLMessageSourceSelectionWidget::QmitkIGTLMessageSourceSelectionWidget( QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f) { m_Controls = NULL; m_CurrentIGTLMessageSource = NULL; CreateQtPartControl(this); } QmitkIGTLMessageSourceSelectionWidget::~QmitkIGTLMessageSourceSelectionWidget() { } void QmitkIGTLMessageSourceSelectionWidget::CreateQtPartControl(QWidget *parent) { if ( !m_Controls ) { // create GUI widgets m_Controls = new Ui::QmitkIGTLMessageSourceSelectionWidgetControls; // setup GUI widgets m_Controls->setupUi(parent); } CreateConnections(); } void QmitkIGTLMessageSourceSelectionWidget::CreateConnections() { if ( m_Controls ) { connect( m_Controls->m_ServiceListWidget, SIGNAL(ServiceSelectionChanged(us::ServiceReferenceU)), this, SLOT(IGTLMessageSourceSelected(us::ServiceReferenceU)) ); //initialize service list widget std::string empty = ""; m_Controls->m_ServiceListWidget->Initialize( mitk::IGTLMessageSource::US_PROPKEY_DEVICENAME, empty); } } void QmitkIGTLMessageSourceSelectionWidget::IGTLMessageSourceSelected(us::ServiceReferenceU s) { if (!s) //nothing selected { //reset everything this->m_CurrentIGTLMessageSource = NULL; emit IGTLMessageSourceSelected(this->m_CurrentIGTLMessageSource); return; } // Get storage us::ModuleContext* context = us::GetModuleContext(); this->m_CurrentIGTLMessageSource = context->GetService(s); emit IGTLMessageSourceSelected(this->m_CurrentIGTLMessageSource); } mitk::IGTLMessageSource::Pointer QmitkIGTLMessageSourceSelectionWidget::GetSelectedIGTLMessageSource() { return this->m_CurrentIGTLMessageSource; } + +mitk::IGTLMessageSource::Pointer QmitkIGTLMessageSourceSelectionWidget::AutoSelectFirstIGTLMessageSource() +{ + if( m_Controls->m_ServiceListWidget->GetAllServiceReferences().size() != 0 ) + { + us::ModuleContext* context = us::GetModuleContext(); + this->m_CurrentIGTLMessageSource = + context->GetService( + m_Controls->m_ServiceListWidget->GetAllServiceReferences().at(0) ); + } + else + { + this->m_CurrentIGTLMessageSource = nullptr; + MITK_WARN("CurrentIGTLMessageSource") << "There was no OpenIGTLink message source to select." + << "The OpenIGTLink message source must be selected manually."; + } + + return this->m_CurrentIGTLMessageSource; +} diff --git a/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLMessageSourceSelectionWidget.h b/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLMessageSourceSelectionWidget.h index 96231b70cf..4173bfb508 100644 --- a/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLMessageSourceSelectionWidget.h +++ b/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLMessageSourceSelectionWidget.h @@ -1,87 +1,101 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkIGTLMessageSourceSelectionWidget_H #define QmitkIGTLMessageSourceSelectionWidget_H //QT headers #include //mitk headers #include "MitkOpenIGTLinkUIExports.h" #include "mitkIGTLMessageSource.h" //us #include //ui header #include "ui_QmitkIGTLMessageSourceSelectionWidgetControls.h" /** Documentation: * \brief This widget allows the user to select a OpenIGTLink message source. * * The widget lists all OpenIGTLink message sources which are available * as microservice via the module context. * * A signal is emmited whenever the selection changes. * * \ingroup OpenIGTLinkUI */ class MITKOPENIGTLINKUI_EXPORT QmitkIGTLMessageSourceSelectionWidget : public QWidget { Q_OBJECT public: static const std::string VIEW_ID; QmitkIGTLMessageSourceSelectionWidget(QWidget* parent = 0, Qt::WindowFlags f = 0); ~QmitkIGTLMessageSourceSelectionWidget(); /** @return Returns the currently selected OpenIGTLink message source. * Returns null if no source is selected at the moment. */ mitk::IGTLMessageSource::Pointer GetSelectedIGTLMessageSource(); + /** @brief Automatically selects the first available OpenIGTLink message source + * of the messageSourceSelectionWidget as message source and assigns it to the + * class member m_CurrentIGTLMessageSource. + * If there is no OpenIGTLink message source available, a nullptr will be assigned + * to the m_CurrentIGTLMessageSource. It is important to call this method whenever + * a new OpenIGTLink client connects to the active OpenIGTLink server. Otherwise, + * the connection between PLUS and MITK or between Slicer and MITK won't work + * automatically. + * + * @return The pointer to the automatically selected message source. This might + * be a nullptr, if there is no message source available. + */ + mitk::IGTLMessageSource::Pointer AutoSelectFirstIGTLMessageSource(); + signals: /** @brief This signal is emitted when a new OpenIGTLink message source is * selected. * @param source Holds the new selected OpenIGTLink device source. Is null * if the old source is deselected and no new source is selected. */ void IGTLMessageSourceSelected(mitk::IGTLMessageSource::Pointer source); protected slots: void IGTLMessageSourceSelected(us::ServiceReferenceU s); protected: /// \brief Creation of the connections virtual void CreateConnections(); virtual void CreateQtPartControl(QWidget *parent); Ui::QmitkIGTLMessageSourceSelectionWidgetControls* m_Controls; mitk::IGTLMessageSource::Pointer m_CurrentIGTLMessageSource; }; #endif diff --git a/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLStreamingManagementWidget.cpp b/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLStreamingManagementWidget.cpp index 9e1bba9e12..549f9d3d3f 100644 --- a/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLStreamingManagementWidget.cpp +++ b/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLStreamingManagementWidget.cpp @@ -1,375 +1,376 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkIGTLStreamingManagementWidget.h" //mitk headers #include #include #include #include //qt headers #include #include #include #include //igtl #include #include #include #include //poco headers #include const std::string QmitkIGTLStreamingManagementWidget::VIEW_ID = "org.mitk.views.igtldevicesourcemanagementwidget"; QmitkIGTLStreamingManagementWidget::QmitkIGTLStreamingManagementWidget( QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f), m_IsClient(false) { m_Controls = NULL; this->m_IGTLDevice = NULL; CreateQtPartControl(this); } QmitkIGTLStreamingManagementWidget::~QmitkIGTLStreamingManagementWidget() { this->RemoveObserver(); } void QmitkIGTLStreamingManagementWidget::RemoveObserver() { if (this->m_IGTLDevice.IsNotNull()) { this->m_IGTLDevice->RemoveObserver(m_LostConnectionObserverTag); this->m_IGTLDevice->RemoveObserver(m_NewConnectionObserverTag); this->m_IGTLDevice->RemoveObserver(m_StateModifiedObserverTag); } if (this->m_IGTLMsgProvider.IsNotNull()) { this->m_IGTLMsgProvider->RemoveObserver(m_StartStreamingTimerObserverTag); this->m_IGTLMsgProvider->RemoveObserver(m_StopStreamingTimerObserverTag); } } void QmitkIGTLStreamingManagementWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkIGTLStreamingManagementWidgetControls; // setup GUI widgets m_Controls->setupUi(parent); } //connect slots with signals CreateConnections(); } void QmitkIGTLStreamingManagementWidget::CreateConnections() { if (m_Controls) { connect((QObject*)(m_Controls->messageSourceSelectionWidget), SIGNAL(IGTLMessageSourceSelected(mitk::IGTLMessageSource::Pointer)), this, SLOT(SourceSelected(mitk::IGTLMessageSource::Pointer))); connect(m_Controls->startStreamPushButton, SIGNAL(clicked()), this, SLOT(OnStartStreaming())); connect(m_Controls->stopStreamPushButton, SIGNAL(clicked()), this, SLOT(OnStopStreaming())); } //this is used for thread seperation, otherwise the worker thread would change the ui elements //which would cause an exception connect(this, SIGNAL(AdaptGUIToStateSignal()), this, SLOT(AdaptGUIToState())); connect(this, SIGNAL(SelectSourceAndAdaptGUISignal()), this, SLOT(SelectSourceAndAdaptGUI())); } void QmitkIGTLStreamingManagementWidget::AdaptGUIToState() { if (this->m_IGTLMsgProvider.IsNotNull()) { //get the state of the device mitk::IGTLDevice::IGTLDeviceState state = this->m_IGTLDevice->GetState(); switch (state) { case mitk::IGTLDevice::Setup: case mitk::IGTLDevice::Ready: m_Controls->messageSourceSelectionWidget->setEnabled(false); m_Controls->selectedSourceLabel->setText(""); m_Controls->startStreamPushButton->setEnabled(false); m_Controls->selectedSourceLabel->setEnabled(false); m_Controls->label->setEnabled(false); m_Controls->stopStreamPushButton->setEnabled(false); m_Controls->fpsLabel->setEnabled(false); m_Controls->fpsSpinBox->setEnabled(false); break; case mitk::IGTLDevice::Running: //check the number of connections of the device, a server can be in //the running state even if there is no connected device, this part of //the GUI shall just be available when there is a connection if (this->m_IGTLDevice->GetNumberOfConnections() == 0) { m_Controls->messageSourceSelectionWidget->setEnabled(false); m_Controls->selectedSourceLabel->setText(""); m_Controls->startStreamPushButton->setEnabled(false); m_Controls->selectedSourceLabel->setEnabled(false); m_Controls->label->setEnabled(false); m_Controls->stopStreamPushButton->setEnabled(false); m_Controls->fpsLabel->setEnabled(false); m_Controls->fpsSpinBox->setEnabled(false); } else //there is a connection { //check if the user already selected a source to stream if (this->m_IGTLMsgSource.IsNull()) // he did not so far { m_Controls->messageSourceSelectionWidget->setEnabled(true); m_Controls->selectedSourceLabel->setText(""); m_Controls->startStreamPushButton->setEnabled(false); m_Controls->selectedSourceLabel->setEnabled(false); m_Controls->label->setEnabled(false); m_Controls->stopStreamPushButton->setEnabled(false); m_Controls->fpsLabel->setEnabled(false); m_Controls->fpsSpinBox->setEnabled(false); } else //user already selected a source { QString nameOfSource = QString::fromStdString(m_IGTLMsgSource->GetName()); m_Controls->messageSourceSelectionWidget->setEnabled(true); m_Controls->selectedSourceLabel->setText(nameOfSource); m_Controls->selectedSourceLabel->setEnabled(true); m_Controls->label->setEnabled(true); //check if the streaming is already running if (this->m_IGTLMsgProvider->IsStreaming()) { m_Controls->startStreamPushButton->setEnabled(false); m_Controls->stopStreamPushButton->setEnabled(true); m_Controls->fpsLabel->setEnabled(false); m_Controls->fpsSpinBox->setEnabled(false); } else { m_Controls->startStreamPushButton->setEnabled(true); m_Controls->stopStreamPushButton->setEnabled(false); m_Controls->fpsLabel->setEnabled(true); m_Controls->fpsSpinBox->setEnabled(true); } } } break; default: mitkThrow() << "Invalid Device State"; break; } } else { this->DisableSourceControls(); } } void QmitkIGTLStreamingManagementWidget::LoadSource( mitk::IGTLMessageProvider::Pointer provider) { //reset the GUI DisableSourceControls(); if (provider.IsNull()) return; //reset the observers this->RemoveObserver(); //disconnect the timer disconnect(&this->m_StreamingTimer); this->m_IGTLMsgProvider = provider; //get the device this->m_IGTLDevice = this->m_IGTLMsgProvider->GetIGTLDevice(); //check if the device is a server or a client if (dynamic_cast( this->m_IGTLDevice.GetPointer()) == NULL) { m_IsClient = false; } else { m_IsClient = true; } typedef itk::SimpleMemberCommand< QmitkIGTLStreamingManagementWidget > CurCommandType; // CurCommandType::Pointer messageReceivedCommand = CurCommandType::New(); // messageReceivedCommand->SetCallbackFunction( // this, &QmitkIGTLStreamingManagementWidget::OnMessageReceived ); // this->m_MessageReceivedObserverTag = // this->m_IGTLDevice->AddObserver(mitk::MessageReceivedEvent(), messageReceivedCommand); // CurCommandType::Pointer commandReceivedCommand = CurCommandType::New(); // commandReceivedCommand->SetCallbackFunction( // this, &QmitkIGTLStreamingManagementWidget::OnCommandReceived ); // this->m_CommandReceivedObserverTag = // this->m_IGTLDevice->AddObserver(mitk::CommandReceivedEvent(), commandReceivedCommand); CurCommandType::Pointer connectionLostCommand = CurCommandType::New(); connectionLostCommand->SetCallbackFunction( this, &QmitkIGTLStreamingManagementWidget::OnLostConnection); this->m_LostConnectionObserverTag = this->m_IGTLDevice->AddObserver( mitk::LostConnectionEvent(), connectionLostCommand); CurCommandType::Pointer newConnectionCommand = CurCommandType::New(); newConnectionCommand->SetCallbackFunction( this, &QmitkIGTLStreamingManagementWidget::OnNewConnection); this->m_NewConnectionObserverTag = this->m_IGTLDevice->AddObserver( mitk::NewClientConnectionEvent(), newConnectionCommand); CurCommandType::Pointer stateModifiedCommand = CurCommandType::New(); stateModifiedCommand->SetCallbackFunction( this, &QmitkIGTLStreamingManagementWidget::OnDeviceStateChanged); this->m_StateModifiedObserverTag = this->m_IGTLDevice->AddObserver( itk::ModifiedEvent(), stateModifiedCommand); CurCommandType::Pointer startStreamingTimerCommand = CurCommandType::New(); startStreamingTimerCommand->SetCallbackFunction( this, &QmitkIGTLStreamingManagementWidget::OnStartStreamingTimer); this->m_StartStreamingTimerObserverTag = this->m_IGTLMsgProvider->AddObserver( mitk::StreamingStartRequiredEvent(), startStreamingTimerCommand); CurCommandType::Pointer stopStreamingTimerCommand = CurCommandType::New(); stopStreamingTimerCommand->SetCallbackFunction( this, &QmitkIGTLStreamingManagementWidget::OnStopStreamingTimer); this->m_StopStreamingTimerObserverTag = this->m_IGTLMsgProvider->AddObserver( mitk::StreamingStopRequiredEvent(), stopStreamingTimerCommand); this->AdaptGUIToState(); } void QmitkIGTLStreamingManagementWidget::DisableSourceControls() { m_Controls->selectedSourceLabel->setText(""); m_Controls->startStreamPushButton->setEnabled(false); m_Controls->stopStreamPushButton->setEnabled(false); m_Controls->fpsLabel->setEnabled(false); m_Controls->fpsSpinBox->setEnabled(false); m_Controls->selectedSourceLabel->setEnabled(false); m_Controls->label->setEnabled(false); m_Controls->messageSourceSelectionWidget->setEnabled(false); } void QmitkIGTLStreamingManagementWidget::SourceSelected( mitk::IGTLMessageSource::Pointer source) { //reset everything this->DisableSourceControls(); if (source.IsNotNull()) //no source selected { this->m_IGTLMsgSource = source; m_Controls->selectedSourceLabel->setText(source->GetName().c_str()); m_Controls->selectedSourceLabel->setEnabled(true); } this->AdaptGUIToState(); } void QmitkIGTLStreamingManagementWidget::OnStartStreaming() { unsigned int fps = this->m_Controls->fpsSpinBox->value(); this->m_IGTLMsgProvider->StartStreamingOfSource(this->m_IGTLMsgSource, fps); this->AdaptGUIToState(); } void QmitkIGTLStreamingManagementWidget::OnStopStreaming() { this->m_IGTLMsgProvider->StopStreamingOfSource(this->m_IGTLMsgSource); this->AdaptGUIToState(); } void QmitkIGTLStreamingManagementWidget::OnMessageReceived() { } void QmitkIGTLStreamingManagementWidget::OnCommandReceived() { } void QmitkIGTLStreamingManagementWidget::OnDeviceStateChanged() { emit AdaptGUIToStateSignal(); } void QmitkIGTLStreamingManagementWidget::OnLostConnection() { emit AdaptGUIToStateSignal(); } void QmitkIGTLStreamingManagementWidget::OnNewConnection() { emit SelectSourceAndAdaptGUISignal(); } void QmitkIGTLStreamingManagementWidget::OnStartStreamingTimer() { if (this->m_IGTLMsgProvider.IsNotNull()) { //get the frame rate unsigned int interval = this->m_IGTLMsgProvider->GetStreamingTime(); //connect the update method connect(&m_StreamingTimer, SIGNAL(timeout()), this, SLOT(OnStreamingTimerTimeout())); //start the timer this->m_StreamingTimer.start(interval); } emit AdaptGUIToStateSignal(); } void QmitkIGTLStreamingManagementWidget::OnStopStreamingTimer() { //stop the timer this->m_StreamingTimer.stop(); //if the provider is still valid disconnect from it if (this->m_IGTLMsgProvider.IsNotNull()) { //disconnect the update method disconnect(&m_StreamingTimer, SIGNAL(timeout()), this, SLOT(OnStreamingTimerTimeout())); } emit AdaptGUIToStateSignal(); } void QmitkIGTLStreamingManagementWidget::OnStreamingTimerTimeout() { if (this->m_IGTLMsgSource.IsNotNull()) { this->m_IGTLMsgProvider->Update(); } } void QmitkIGTLStreamingManagementWidget::SelectSourceAndAdaptGUI() { - //get the current selection and call SourceSelected which will call AdaptGUI + //get the current selection (the auto-selected message source) and call + //SourceSelected which will call AdaptGUI mitk::IGTLMessageSource::Pointer curSelSrc = - m_Controls->messageSourceSelectionWidget->GetSelectedIGTLMessageSource(); + m_Controls->messageSourceSelectionWidget->AutoSelectFirstIGTLMessageSource(); SourceSelected(curSelSrc); }