diff --git a/Modules/QtWidgets/QmitkServiceListWidget.cpp b/Modules/QtWidgets/QmitkServiceListWidget.cpp index 3611ddc316..38159747fa 100644 --- a/Modules/QtWidgets/QmitkServiceListWidget.cpp +++ b/Modules/QtWidgets/QmitkServiceListWidget.cpp @@ -1,228 +1,237 @@ /*=================================================================== 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. ===================================================================*/ //#define _USE_MATH_DEFINES #include // STL Headers #include //microservices #include #include #include #include const std::string QmitkServiceListWidget::VIEW_ID = "org.mitk.views.QmitkServiceListWidget"; QmitkServiceListWidget::QmitkServiceListWidget(QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f), m_AutomaticallySelectFirstEntry(false), m_Controls(NULL) { CreateQtPartControl(this); } QmitkServiceListWidget::~QmitkServiceListWidget() { m_Context->RemoveServiceListener(this, &QmitkServiceListWidget::OnServiceEvent); } void QmitkServiceListWidget::SetAutomaticallySelectFirstEntry(bool automaticallySelectFirstEntry) { m_AutomaticallySelectFirstEntry = automaticallySelectFirstEntry; } //////////////////// INITIALIZATION ///////////////////// void QmitkServiceListWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkServiceListWidgetControls; m_Controls->setupUi(parent); this->CreateConnections(); } m_Context = us::GetModuleContext(); } void QmitkServiceListWidget::CreateConnections() { if ( m_Controls ) { connect( m_Controls->m_ServiceList, SIGNAL(currentItemChanged( QListWidgetItem *, QListWidgetItem *)), this, SLOT(OnServiceSelectionChanged()) ); } } void QmitkServiceListWidget::InitPrivate(const std::string& namingProperty, const std::string& filter) { if (filter.empty()) m_Filter = "(" + us::ServiceConstants::OBJECTCLASS() + "=" + m_Interface + ")"; else m_Filter = filter; m_NamingProperty = namingProperty; m_Context->RemoveServiceListener(this, &QmitkServiceListWidget::OnServiceEvent); m_Context->AddServiceListener(this, &QmitkServiceListWidget::OnServiceEvent, m_Filter); // Empty ListWidget this->m_ListContent.clear(); m_Controls->m_ServiceList->clear(); // get Services std::vector services = this->GetAllRegisteredServices(); // Transfer them to the List for(std::vector::iterator it = services.begin(); it != services.end(); ++it) AddServiceToList(*it); } ///////////// Methods & Slots Handling Direct Interaction ///////////////// bool QmitkServiceListWidget::GetIsServiceSelected(){ return (this->m_Controls->m_ServiceList->currentItem() != 0); } void QmitkServiceListWidget::OnServiceSelectionChanged(){ us::ServiceReferenceU ref = this->GetServiceForListItem(this->m_Controls->m_ServiceList->currentItem()); if (! ref){ emit (ServiceSelectionChanged(us::ServiceReferenceU())); return; } emit (ServiceSelectionChanged(ref)); } us::ServiceReferenceU QmitkServiceListWidget::GetSelectedServiceReference(){ return this->GetServiceForListItem(this->m_Controls->m_ServiceList->currentItem()); } +std::vector QmitkServiceListWidget::GetAllServiceReferences() +{ + std::vector result; + for (int i = 0; i < m_ListContent.size(); i++){ + result.push_back(m_ListContent[i].service); + } + return result; +} + ///////////////// Methods & Slots Handling Logic ////////////////////////// void QmitkServiceListWidget::OnServiceEvent(const us::ServiceEvent event){ //MITK_INFO << "ServiceEvent" << event.GetType(); switch (event.GetType()) { case us::ServiceEvent::MODIFIED: emit(ServiceModified(event.GetServiceReference())); // Change service; add a new entry if service wasn't on list before if ( ! this->ChangeServiceOnList(event.GetServiceReference()) ) { this->AddServiceToList(event.GetServiceReference()); } break; case us::ServiceEvent::REGISTERED: emit(ServiceRegistered(event.GetServiceReference())); AddServiceToList(event.GetServiceReference()); break; case us::ServiceEvent::UNREGISTERING: emit(ServiceUnregistering(event.GetServiceReference())); RemoveServiceFromList(event.GetServiceReference()); break; case us::ServiceEvent::MODIFIED_ENDMATCH: emit(ServiceModifiedEndMatch(event.GetServiceReference())); RemoveServiceFromList(event.GetServiceReference()); break; } } /////////////////////// HOUSEHOLDING CODE ///////////////////////////////// QListWidgetItem* QmitkServiceListWidget::AddServiceToList(const us::ServiceReferenceU& serviceRef){ QListWidgetItem *newItem = new QListWidgetItem; newItem->setText(this->CreateCaptionForService(serviceRef)); // Add new item to QListWidget m_Controls->m_ServiceList->addItem(newItem); m_Controls->m_ServiceList->sortItems(); // Construct link and add to internal List for reference QmitkServiceListWidget::ServiceListLink link; link.service = serviceRef; link.item = newItem; m_ListContent.push_back(link); // Select first entry and emit corresponding signal if the list was // empty before and this feature is enabled if ( m_AutomaticallySelectFirstEntry && m_Controls->m_ServiceList->selectedItems().isEmpty() ) { m_Controls->m_ServiceList->setCurrentIndex(m_Controls->m_ServiceList->indexAt(QPoint(0, 0))); this->OnServiceSelectionChanged(); } return newItem; } bool QmitkServiceListWidget::RemoveServiceFromList(const us::ServiceReferenceU& serviceRef){ for(std::vector::iterator it = m_ListContent.begin(); it != m_ListContent.end(); ++it){ if ( serviceRef == it->service ) { int row = m_Controls->m_ServiceList->row(it->item); QListWidgetItem* oldItem = m_Controls->m_ServiceList->takeItem(row); delete oldItem; this->m_ListContent.erase(it); return true; } } return false; } bool QmitkServiceListWidget::ChangeServiceOnList(const us::ServiceReferenceU& serviceRef) { for(std::vector::iterator it = m_ListContent.begin(); it != m_ListContent.end(); ++it){ if ( serviceRef == it->service ) { it->item->setText(this->CreateCaptionForService(serviceRef)); return true; } } return false; } us::ServiceReferenceU QmitkServiceListWidget::GetServiceForListItem(QListWidgetItem* item) { for(std::vector::iterator it = m_ListContent.begin(); it != m_ListContent.end(); ++it) if (item == it->item) return it->service; // Return invalid ServiceReference (will evaluate to false in bool expressions) return us::ServiceReferenceU(); } std::vector QmitkServiceListWidget::GetAllRegisteredServices(){ //Get Service References return m_Context->GetServiceReferences(m_Interface, m_Filter); } QString QmitkServiceListWidget::CreateCaptionForService(const us::ServiceReferenceU& serviceRef) { std::string caption; //TODO allow more complex formatting if (m_NamingProperty.empty()) caption = m_Interface; else { us::Any prop = serviceRef.GetProperty(m_NamingProperty); if (prop.Empty()) { MITK_WARN << "QmitkServiceListWidget tried to resolve property '" + m_NamingProperty + "' but failed. Resorting to interface name for display."; caption = m_Interface; } else caption = prop.ToString(); } return QString::fromStdString(caption); } diff --git a/Modules/QtWidgets/QmitkServiceListWidget.h b/Modules/QtWidgets/QmitkServiceListWidget.h index f8b034036d..519c0a75de 100644 --- a/Modules/QtWidgets/QmitkServiceListWidget.h +++ b/Modules/QtWidgets/QmitkServiceListWidget.h @@ -1,261 +1,287 @@ /*=================================================================== 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 _QmitkServiceListWidget_H_INCLUDED #define _QmitkServiceListWidget_H_INCLUDED #include "MitkQtWidgetsExports.h" #include "ui_QmitkServiceListWidgetControls.h" #include //QT headers #include #include //Microservices #include "usServiceReference.h" #include "usModuleContext.h" #include "usServiceEvent.h" #include "mitkServiceInterface.h" /** * \ingroup QmitkModule * * \brief This widget provides abstraction for the handling of MicroServices. * * Place one in your Plugin and set it to look for a certain interface. * One can also specify a filter and / or a property to use for captioning of * the services. It also offers functionality to signal * ServiceEvents and to return the actual classes, so only a minimum of * interaction with the MicroserviceInterface is required. * To get started, just put it in your Plugin or Widget, call the Initialize * Method and optionally connect it's signals. * As QT limits templating possibilities, events only throw ServiceReferences. * You can manually dereference them using TranslateServiceReference() */ class QMITK_EXPORT QmitkServiceListWidget :public QWidget { //this is needed for all Qt objects that should have a MOC object (everything that derives from QObject) Q_OBJECT private: us::ModuleContext* m_Context; /** \brief a filter to further narrow down the list of results*/ std::string m_Filter; /** \brief The name of the ServiceInterface that this class should list */ std::string m_Interface; /** \brief The name of the ServiceProperty that will be displayed in the list to represent the service */ std::string m_NamingProperty; /** \brief Determines if the first entry of the list should be selected automatically if no entry was selected before (default false). */ bool m_AutomaticallySelectFirstEntry; public: static const std::string VIEW_ID; QmitkServiceListWidget(QWidget* p = 0, Qt::WindowFlags f1 = 0); virtual ~QmitkServiceListWidget(); /** \brief Set if the first entry of the list should be selected automatically if no entry was selected before. */ void SetAutomaticallySelectFirstEntry(bool automaticallySelectFirstEntry); /** \brief This method is part of the widget an needs not to be called separately. */ virtual void CreateQtPartControl(QWidget *parent); /** \brief This method is part of the widget an needs not to be called separately. (Creation of the connections of main and control widget.)*/ virtual void CreateConnections(); /** * \brief Will return true, if a service is currently selected and false otherwise. * * Call this before requesting service references to avoid invalid ServiceReferences. */ bool GetIsServiceSelected(); /** * \brief Returns the currently selected Service as a ServiceReference. * * If no Service is selected, the result will probably be a bad pointer. call GetIsServiceSelected() * beforehand to avoid this */ us::ServiceReferenceU GetSelectedServiceReference(); + /** + * @return Returns all service references that are displayed in this widget. + */ + std::vector GetAllServiceReferences(); + + + /** + * \brief Use this function to return the all listed services as a class directly. + * + * Make sure you pass the appropriate type, or else this call will fail. + * Usually, you will pass the class itself, not the SmartPointer, but the function returns a pointer. + */ + template + std::vector GetAllServices() + { + // if (this->m_Controls->m_ServiceList->currentRow()==-1) return NULL; + std::vector refs = GetAllServiceReferences(); + std::vector result; + for (int i = 0; i < refs.size(); i++) + { + result.push_back(m_Context->GetService(us::ServiceReference(refs[i]))); + } + return result; + } + + /** * \brief Use this function to return the currently selected service as a class directly. * * Make sure you pass the appropriate type, or else this call will fail. * Usually, you will pass the class itself, not the SmartPointer, but the function returns a pointer. Example: * \verbatim mitk::USDevice::Pointer device = GetSelectedService(); \endverbatim * @return Returns the current selected device. Returns NULL if no device is selected. */ template T* GetSelectedService() { if (this->m_Controls->m_ServiceList->currentRow()==-1) return NULL; us::ServiceReferenceU ref = GetServiceForListItem( this->m_Controls->m_ServiceList->currentItem() ); return ( m_Context->GetService(us::ServiceReference(ref)) ); } /** * \brief Initializes the Widget with essential parameters. * * The string filter is an LDAP parsable String, compare mitk::ModuleContext for examples on filtering. * Pass class T to tell the widget which class it should filter for - only services of this class will be listed. * NamingProperty is a property that will be used to caption the Items in the list. If no filter is supplied, all * matching interfaces are shown. If no namingProperty is supplied, the interfaceName will be used to caption Items in the list. * For example, this Initialization will filter for all USDevices that are set to active. The USDevice's model will be used to display it in the list: * \verbatim std::string filter = "(&(" + us::ServiceConstants::OBJECTCLASS() + "=" + "org.mitk.services.UltrasoundDevice)(IsActive=true))"; m_Controls.m_ActiveVideoDevices->Initialize(mitk::USDevice::GetPropertyKeys().US_PROPKEY_NAME ,filter); * \endverbatim */ template void Initialize(const std::string& namingProperty = static_cast< std::string >(""),const std::string& filter = static_cast< std::string >("")) { std::string interfaceName ( us_service_interface_iid() ); m_Interface = interfaceName; InitPrivate(namingProperty, filter); } /** * \brief Translates a serviceReference to a class of the given type. * * Use this to translate the signal's parameters. To adhere to the MicroService contract, * only ServiceReferences stemming from the same widget should be used as parameters for this method. * \verbatim mitk::USDevice::Pointer device = TranslateReference(myDeviceReference); \endverbatim */ template T* TranslateReference(const us::ServiceReferenceU& reference) { return m_Context->GetService(us::ServiceReference(reference)); } /** *\brief This Function listens to ServiceRegistry changes and updates the list of services accordingly. * * The user of this widget does not need to call this method, it is instead used to recieve events from the module registry. */ void OnServiceEvent(const us::ServiceEvent event); signals: /** *\brief Emitted when a new Service matching the filter is being registered. * * Be careful if you use a filter: * If a device does not match the filter when registering, but modifies it's properties later to match the filter, * then the first signal you will see this device in will be ServiceModified. */ void ServiceRegistered(us::ServiceReferenceU); /** *\brief Emitted directly before a Service matching the filter is being unregistered. */ void ServiceUnregistering(us::ServiceReferenceU); /** *\brief Emitted when a Service matching the filter changes it's properties, or when a service that formerly not matched the filter * changed it's properties and now matches the filter. */ void ServiceModified(us::ServiceReferenceU); /** *\brief Emitted when a Service matching the filter changes it's properties, * * and the new properties make it fall trough the filter. This effectively means that * the widget will not track the service anymore. Usually, the Service should still be useable though */ void ServiceModifiedEndMatch(us::ServiceReferenceU); /** *\brief Emitted if the user selects a Service from the list. * * If no service is selected, an invalid serviceReference is returned. The user can easily check for this. * if (serviceReference) will evaluate to false, if the reference is invalid and true if valid. */ void ServiceSelectionChanged(us::ServiceReferenceU); public slots: protected slots: /** \brief Called, when the selection in the list of Services changes. */ void OnServiceSelectionChanged(); protected: Ui::QmitkServiceListWidgetControls* m_Controls; ///< member holding the UI elements of this widget /** * \brief Internal structure used to link ServiceReferences to their QListWidgetItems */ struct ServiceListLink { us::ServiceReferenceU service; QListWidgetItem* item; }; /** * \brief Finishes initialization after Initialize has been called. * * This function assumes that m_Interface is set correctly (Which Initialize does). */ void InitPrivate(const std::string& namingProperty, const std::string& filter); /** * \brief Contains a list of currently active services and their entires in the list. This is wiped with every ServiceRegistryEvent. */ std::vector m_ListContent; /** * \brief Constructs a ListItem from the given service, displays it, and locally stores the service. */ QListWidgetItem* AddServiceToList(const us::ServiceReferenceU& serviceRef); /** * \brief Removes the given service from the list and cleans up. Returns true if successful, false if service was not found. */ bool RemoveServiceFromList(const us::ServiceReferenceU& serviceRef); /** * \brief Changes list entry of given service to match the changed service properties. * \return true if successful, false if service was not found */ bool ChangeServiceOnList(const us::ServiceReferenceU& serviceRef); /** * \brief Returns the serviceReference corresponding to the given ListEntry or an invalid one if none was found (will evaluate to false in bool expressions). */ us::ServiceReferenceU GetServiceForListItem(QListWidgetItem* item); /** * \brief Returns a list of ServiceReferences matching the filter criteria by querying the service registry. */ std::vector GetAllRegisteredServices(); /** * \brief Gets string from the naming property of the service. * \return caption string for given us::ServiceReferenceU */ QString CreateCaptionForService(const us::ServiceReferenceU& serviceRef); }; #endif // _QmitkServiceListWidget_H_INCLUDED diff --git a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/UltrasoundSupport.cpp b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/UltrasoundSupport.cpp index d93f01a40d..4648476704 100644 --- a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/UltrasoundSupport.cpp +++ b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/UltrasoundSupport.cpp @@ -1,372 +1,396 @@ /*=================================================================== 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. ===================================================================*/ // Blueberry #include #include //Mitk #include #include #include #include #include // Qmitk #include "UltrasoundSupport.h" // Qt #include #include #include // Ultrasound #include "mitkUSDevice.h" #include "QmitkUSAbstractCustomWidget.h" #include #include #include "usServiceReference.h" #include "internal/org_mitk_gui_qt_ultrasound_Activator.h" const std::string UltrasoundSupport::VIEW_ID = "org.mitk.views.ultrasoundsupport"; void UltrasoundSupport::SetFocus() { } void UltrasoundSupport::CreateQtPartControl( QWidget *parent ) { m_Timer = new QTimer(this); // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi( parent ); connect( m_Controls.m_DeviceManagerWidget, SIGNAL(NewDeviceButtonClicked()), this, SLOT(OnClickedAddNewDevice()) ); // Change Widget Visibilities connect( m_Controls.m_DeviceManagerWidget, SIGNAL(NewDeviceButtonClicked()), this->m_Controls.m_NewVideoDeviceWidget, SLOT(CreateNewDevice()) ); // Init NewDeviceWidget connect( m_Controls.m_ActiveVideoDevices, SIGNAL(ServiceSelectionChanged(us::ServiceReferenceU)), this, SLOT(OnChangedActiveDevice()) ); connect( m_Controls.m_RunImageTimer, SIGNAL(clicked()), this, SLOT(OnChangedActiveDevice()) ); connect( m_Controls.m_ShowImageStream, SIGNAL(clicked()), this, SLOT(OnChangedActiveDevice()) ); connect( m_Controls.m_NewVideoDeviceWidget, SIGNAL(Finished()), this, SLOT(OnNewDeviceWidgetDone()) ); // After NewDeviceWidget finished editing connect( m_Controls.m_FrameRate, SIGNAL(valueChanged(int)), this, SLOT(OnChangedFramerateLimit(int)) ); connect( m_Controls.m_FreezeButton, SIGNAL(clicked()), this, SLOT(OnClickedFreezeButton()) ); connect( m_Timer, SIGNAL(timeout()), this, SLOT(DisplayImage())); // Initializations m_Controls.m_NewVideoDeviceWidget->setVisible(false); std::string filter = "(&(" + us::ServiceConstants::OBJECTCLASS() + "=" + "org.mitk.services.UltrasoundDevice)(" + mitk::USDevice::GetPropertyKeys().US_PROPKEY_ISACTIVE + "=true))"; m_Controls.m_ActiveVideoDevices->Initialize( mitk::USDevice::GetPropertyKeys().US_PROPKEY_LABEL ,filter); m_Controls.m_ActiveVideoDevices->SetAutomaticallySelectFirstEntry(true); m_FrameCounter = 0; // Create Node for US Stream if (m_Node.IsNull()) { m_Node = mitk::DataNode::New(); m_Node->SetName("US Support Viewing Stream"); //create a dummy image (gray values 0..255) for correct initialization of level window, etc. mitk::Image::Pointer dummyImage = mitk::ImageGenerator::GenerateRandomImage(100, 100, 1, 1, 1, 1, 1, 255,0); m_Node->SetData(dummyImage); m_OldGeometry = dynamic_cast(dummyImage->GetGeometry()); } m_Controls.tabWidget->setTabEnabled(1, false); LoadUISettings(); } void UltrasoundSupport::OnClickedAddNewDevice() { m_Controls.m_NewVideoDeviceWidget->setVisible(true); m_Controls.m_DeviceManagerWidget->setVisible(false); m_Controls.m_Headline->setText("Add New Video Device:"); m_Controls.m_WidgetActiveDevices->setVisible(false); } void UltrasoundSupport::DisplayImage() { //Update device m_Device->Modified(); m_Device->Update(); //Only update the view if the image is shown if(m_Controls.m_ShowImageStream->isChecked()) { //Update data node mitk::Image::Pointer curOutput = m_Device->GetOutput(); m_Node->SetData(curOutput); // if the geometry changed: reinitialize the ultrasound image - if(!mitk::Equal(m_OldGeometry.GetPointer(),curOutput->GetGeometry(),0.0001,false)) + if((m_OldGeometry.IsNotNull()) && + (curOutput->GetGeometry() != NULL) && + (!mitk::Equal(m_OldGeometry.GetPointer(),curOutput->GetGeometry(),0.0001,false)) + ) { mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); if ( (renderWindow != NULL) && (curOutput->GetTimeGeometry()->IsValid()) && (m_Controls.m_ShowImageStream->isChecked()) ) { renderWindow->GetRenderingManager()->InitializeViews( curOutput->GetGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); renderWindow->GetRenderingManager()->RequestUpdateAll(); } m_CurrentImageWidth = curOutput->GetDimension(0); m_CurrentImageHeight = curOutput->GetDimension(1); m_OldGeometry = dynamic_cast(curOutput->GetGeometry()); } //if not: only update the view else { this->RequestRenderWindowUpdate(); } } //Update frame counter m_FrameCounter ++; if (m_FrameCounter >= 10) { int nMilliseconds = m_Clock.restart(); int fps = 10000.0f / (nMilliseconds ); m_Controls.m_FramerateLabel->setText("Current Framerate: "+ QString::number(fps) +" FPS"); m_FrameCounter = 0; } } void UltrasoundSupport::OnChangedFramerateLimit(int value) { m_Timer->stop(); m_Timer->setInterval(1000 / value); m_Timer->start(); } void UltrasoundSupport::OnClickedFreezeButton() { if ( m_Device.IsNull() ) { MITK_WARN("UltrasoundSupport") << "Freeze button clicked though no device is selected."; return; } if ( m_Device->GetIsFreezed() ) { m_Device->SetIsFreezed(false); m_Controls.m_FreezeButton->setText("Freeze"); } else { m_Device->SetIsFreezed(true); m_Controls.m_FreezeButton->setText("Start Viewing Again"); } } void UltrasoundSupport::OnChangedActiveDevice() { //clean up and stop timer m_Timer->stop(); this->RemoveControlWidgets(); this->GetDataStorage()->Remove(m_Node); m_Node->ReleaseData(); //get current device, abort if it is invalid m_Device = m_Controls.m_ActiveVideoDevices->GetSelectedService(); if (m_Device.IsNull()) { -MITK_WARN << "Selected device is not valid, aborting"; m_Controls.tabWidget->setTabEnabled(1, false); return; } //create the widgets for this device and enable the widget tab this->CreateControlWidgets(); m_Controls.tabWidget->setTabEnabled(1, true); //show node if the option is enabled if(m_Controls.m_ShowImageStream->isChecked()) {this->GetDataStorage()->Add(m_Node);} //start timer if(m_Controls.m_RunImageTimer->isChecked()) { int interval = (1000 / m_Controls.m_FrameRate->value()); m_Timer->setInterval(interval); m_Timer->start(); m_Controls.m_TimerWidget->setEnabled(true); } else { m_Controls.m_TimerWidget->setEnabled(false); } } void UltrasoundSupport::OnNewDeviceWidgetDone() { m_Controls.m_NewVideoDeviceWidget->setVisible(false); m_Controls.m_DeviceManagerWidget->setVisible(true); m_Controls.m_Headline->setText("Ultrasound Devices:"); m_Controls.m_WidgetActiveDevices->setVisible(true); } void UltrasoundSupport::CreateControlWidgets() { m_ControlProbesWidget = new QmitkUSControlsProbesWidget(m_Device->GetControlInterfaceProbes(), m_Controls.m_ToolBoxControlWidgets); m_Controls.probesWidgetContainer->addWidget(m_ControlProbesWidget); // create b mode widget for current device m_ControlBModeWidget = new QmitkUSControlsBModeWidget(m_Device->GetControlInterfaceBMode(), m_Controls.m_ToolBoxControlWidgets); m_Controls.m_ToolBoxControlWidgets->addItem(m_ControlBModeWidget, "B Mode Controls"); if ( ! m_Device->GetControlInterfaceBMode() ) {m_Controls.m_ToolBoxControlWidgets->setItemEnabled(m_Controls.m_ToolBoxControlWidgets->count()-1, false);} // create doppler widget for current device m_ControlDopplerWidget = new QmitkUSControlsDopplerWidget(m_Device->GetControlInterfaceDoppler(), m_Controls.m_ToolBoxControlWidgets); m_Controls.m_ToolBoxControlWidgets->addItem(m_ControlDopplerWidget, "Doppler Controls"); if ( ! m_Device->GetControlInterfaceDoppler() ) {m_Controls.m_ToolBoxControlWidgets->setItemEnabled(m_Controls.m_ToolBoxControlWidgets->count()-1, false);} ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext(); if ( pluginContext ) { std::string filter = "(ork.mitk.services.UltrasoundCustomWidget.deviceClass=" + m_Device->GetDeviceClass() + ")"; QString interfaceName = QString::fromStdString(us_service_interface_iid() ); m_CustomWidgetServiceReference = pluginContext->getServiceReferences(interfaceName, QString::fromStdString(filter)); if (m_CustomWidgetServiceReference.size() > 0) { m_ControlCustomWidget = pluginContext->getService (m_CustomWidgetServiceReference.at(0))->CloneForQt(m_Controls.tab2); m_ControlCustomWidget->SetDevice(m_Device); m_Controls.m_ToolBoxControlWidgets->addItem(m_ControlCustomWidget, "Custom Controls"); } else { m_Controls.m_ToolBoxControlWidgets->addItem(new QWidget(m_Controls.m_ToolBoxControlWidgets), "Custom Controls"); m_Controls.m_ToolBoxControlWidgets->setItemEnabled(m_Controls.m_ToolBoxControlWidgets->count()-1, false); } } // select first enabled control widget for ( int n = 0; n < m_Controls.m_ToolBoxControlWidgets->count(); ++n) { if ( m_Controls.m_ToolBoxControlWidgets->isItemEnabled(n) ) { m_Controls.m_ToolBoxControlWidgets->setCurrentIndex(n); break; } } } void UltrasoundSupport::RemoveControlWidgets() { if(!m_ControlProbesWidget) {return;} //widgets do not exist... nothing to do // remove all control widgets from the tool box widget while (m_Controls.m_ToolBoxControlWidgets->count() > 0) { m_Controls.m_ToolBoxControlWidgets->removeItem(0); } // remove probes widget (which is not part of the tool box widget) m_Controls.probesWidgetContainer->removeWidget(m_ControlProbesWidget); delete m_ControlProbesWidget; m_ControlProbesWidget = 0; delete m_ControlBModeWidget; m_ControlBModeWidget = 0; delete m_ControlDopplerWidget; m_ControlDopplerWidget = 0; // delete custom widget if it is present if ( m_ControlCustomWidget ) { ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext(); delete m_ControlCustomWidget; m_ControlCustomWidget = 0; if ( m_CustomWidgetServiceReference.size() > 0 ) { pluginContext->ungetService(m_CustomWidgetServiceReference.at(0)); } } } void UltrasoundSupport::OnDeciveServiceEvent(const ctkServiceEvent event) { if ( m_Device.IsNull() || event.getType() != us::ServiceEvent::MODIFIED ) { return; } ctkServiceReference service = event.getServiceReference(); if ( m_Device->GetManufacturer() != service.getProperty(QString::fromStdString(mitk::USDevice::GetPropertyKeys().US_PROPKEY_MANUFACTURER)).toString().toStdString() && m_Device->GetName() != service.getProperty(QString::fromStdString(mitk::USDevice::GetPropertyKeys().US_PROPKEY_NAME)).toString().toStdString() ) { return; } if ( ! m_Device->GetIsActive() && m_Timer->isActive() ) { m_Timer->stop(); } if ( m_CurrentDynamicRange != service.getProperty(QString::fromStdString(mitk::USDevice::GetPropertyKeys().US_PROPKEY_BMODE_DYNAMIC_RANGE)).toDouble() ) { m_CurrentDynamicRange = service.getProperty(QString::fromStdString(mitk::USDevice::GetPropertyKeys().US_PROPKEY_BMODE_DYNAMIC_RANGE)).toDouble(); // update level window for the current dynamic range mitk::LevelWindow levelWindow; m_Node->GetLevelWindow(levelWindow); levelWindow.SetAuto(m_Image, true, true); m_Node->SetLevelWindow(levelWindow); } } UltrasoundSupport::UltrasoundSupport() : m_ControlCustomWidget(0), m_ControlBModeWidget(0), m_ControlProbesWidget(0), m_ImageAlreadySetToNode(false), m_CurrentImageWidth(0), m_CurrentImageHeight(0) { ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext(); if ( pluginContext ) { // to be notified about service event of an USDevice pluginContext->connectServiceListener(this, "OnDeciveServiceEvent", QString::fromStdString("(" + us::ServiceConstants::OBJECTCLASS() + "=" + us_service_interface_iid() + ")")); } } UltrasoundSupport::~UltrasoundSupport() { - StoreUISettings(); + try + { + m_Timer->stop(); + + // Get all active devicesand deactivate them to prevent freeze + std::vector devices = this->m_Controls.m_ActiveVideoDevices->GetAllServices(); + for (int i = 0; i < devices.size(); i ++) + { + mitk::USDevice::Pointer device = devices[i]; + if (device.IsNotNull() && device->GetIsActive()) + { + device->Deactivate(); + device->Disconnect(); + } + } + + StoreUISettings(); + } + catch(std::exception &e) + { + MITK_ERROR << "Exception during call of destructor! Message: " << e.what(); + } + } void UltrasoundSupport::StoreUISettings() { QSettings settings; settings.beginGroup(QString::fromStdString(VIEW_ID)); settings.setValue("DisplayImage", QVariant(m_Controls.m_ShowImageStream->isChecked())); settings.setValue("RunImageTimer", QVariant(m_Controls.m_RunImageTimer->isChecked())); settings.endGroup(); } void UltrasoundSupport::LoadUISettings() { QSettings settings; settings.beginGroup(QString::fromStdString(VIEW_ID)); m_Controls.m_ShowImageStream->setChecked(settings.value("DisplayImage", true).toBool()); m_Controls.m_RunImageTimer->setChecked(settings.value("RunImageTimer", true).toBool()); settings.endGroup(); }