diff --git a/Modules/OpenIGTLink/mitkIGTLMessageSource.cpp b/Modules/OpenIGTLink/mitkIGTLMessageSource.cpp index 5a9a1bbfa3..a127c17e19 100644 --- a/Modules/OpenIGTLink/mitkIGTLMessageSource.cpp +++ b/Modules/OpenIGTLink/mitkIGTLMessageSource.cpp @@ -1,200 +1,202 @@ /*=================================================================== 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 "mitkIGTLMessageSource.h" #include "mitkUIDGenerator.h" //Microservices #include #include #include #include const std::string mitk::IGTLMessageSource::US_INTERFACE_NAME = "org.mitk.services.IGTLMessageSource"; const std::string mitk::IGTLMessageSource::US_PROPKEY_DEVICENAME = US_INTERFACE_NAME + ".devicename"; const std::string mitk::IGTLMessageSource::US_PROPKEY_DEVICETYPE = US_INTERFACE_NAME + ".devicetype"; const std::string mitk::IGTLMessageSource::US_PROPKEY_ID = US_INTERFACE_NAME + ".id"; const std::string mitk::IGTLMessageSource::US_PROPKEY_ISACTIVE = US_INTERFACE_NAME + ".isActive"; mitk::IGTLMessageSource::IGTLMessageSource() : itk::ProcessObject(), m_Name("IGTLMessageSource (no defined type)"), m_Type("NONE"), m_StreamingFPS(0) { m_StreamingFPSMutex = itk::FastMutexLock::New(); } mitk::IGTLMessageSource::~IGTLMessageSource() { //this->UnRegisterMicroservice(); } mitk::IGTLMessage* mitk::IGTLMessageSource::GetOutput() { if (this->GetNumberOfIndexedOutputs() < 1) { MITK_WARN << "IGTLMessageSource contained no outputs. Returning nullptr."; return nullptr; } return static_cast(this->ProcessObject::GetPrimaryOutput()); } mitk::IGTLMessage* mitk::IGTLMessageSource::GetOutput( DataObjectPointerArraySizeType idx) { IGTLMessage* out = dynamic_cast( this->ProcessObject::GetOutput(idx) ); if ( out == nullptr && this->ProcessObject::GetOutput(idx) != nullptr ) { itkWarningMacro (<< "Unable to convert output number " << idx << " to type " << typeid( IGTLMessage ).name () ); } return out; } mitk::IGTLMessage* mitk::IGTLMessageSource::GetOutput( const std::string& messageName) { DataObjectPointerArray outputs = this->GetOutputs(); for (DataObjectPointerArray::iterator it = outputs.begin(); it != outputs.end(); ++it) { if (messageName == (static_cast(it->GetPointer()))->GetName()) { return static_cast(it->GetPointer()); } } return nullptr; } itk::ProcessObject::DataObjectPointerArraySizeType mitk::IGTLMessageSource::GetOutputIndex( std::string messageName ) { DataObjectPointerArray outputs = this->GetOutputs(); for (DataObjectPointerArray::size_type i = 0; i < outputs.size(); ++i) { if (messageName == (static_cast(outputs.at(i).GetPointer()))->GetName()) { return i; } } throw std::invalid_argument("output name does not exist"); } void mitk::IGTLMessageSource::RegisterAsMicroservice() { // Get Context us::ModuleContext* context = us::GetModuleContext(); // Define ServiceProps us::ServiceProperties props; mitk::UIDGenerator uidGen = mitk::UIDGenerator ("org.mitk.services.IGTLMessageSource.id_", 16); props[ US_PROPKEY_ID ] = uidGen.GetUID(); props[ US_PROPKEY_DEVICENAME ] = m_Name; props[ US_PROPKEY_DEVICETYPE ] = m_Type; m_ServiceRegistration = context->RegisterService(this, props); } void mitk::IGTLMessageSource::UnRegisterMicroservice() { if (m_ServiceRegistration != nullptr) - m_ServiceRegistration.Unregister(); + { + m_ServiceRegistration.Unregister(); + } m_ServiceRegistration = 0; } std::string mitk::IGTLMessageSource::GetMicroserviceID() { us::Any referenceProperty = this->m_ServiceRegistration.GetReference().GetProperty(US_PROPKEY_ID); return referenceProperty.ToString(); } void mitk::IGTLMessageSource::GraftOutput(itk::DataObject *graft) { this->GraftNthOutput(0, graft); } void mitk::IGTLMessageSource::GraftNthOutput(unsigned int idx, itk::DataObject *graft) { if ( idx >= this->GetNumberOfIndexedOutputs() ) { itkExceptionMacro(<<"Requested to graft output " << idx << " but this filter" "only has " << this->GetNumberOfIndexedOutputs() << " Outputs."); } if ( !graft ) { itkExceptionMacro(<<"Requested to graft output with a nullptr pointer object" ); } itk::DataObject* output = this->GetOutput(idx); if ( !output ) { itkExceptionMacro(<<"Requested to graft output that is a nullptr pointer" ); } // Call Graft on IGTLMessage to copy member data output->Graft( graft ); } itk::DataObject::Pointer mitk::IGTLMessageSource::MakeOutput ( DataObjectPointerArraySizeType /*idx*/ ) { return IGTLMessage::New().GetPointer(); } itk::DataObject::Pointer mitk::IGTLMessageSource::MakeOutput( const DataObjectIdentifierType & name ) { itkDebugMacro("MakeOutput(" << name << ")"); if( this->IsIndexedOutputName(name) ) { return this->MakeOutput( this->MakeIndexFromOutputName(name) ); } return static_cast(IGTLMessage::New().GetPointer()); } mitk::PropertyList::ConstPointer mitk::IGTLMessageSource::GetParameters() const { mitk::PropertyList::Pointer p = mitk::PropertyList::New(); // add properties to p like this: //p->SetProperty("MyFilter_MyParameter", mitk::PropertyDataType::New(m_MyParameter)); return mitk::PropertyList::ConstPointer(p); } void mitk::IGTLMessageSource::SetFPS(unsigned int fps) { this->m_StreamingFPSMutex->Lock(); this->m_StreamingFPS = fps; this->m_StreamingFPSMutex->Unlock(); } unsigned int mitk::IGTLMessageSource::GetFPS() { unsigned int fps = 0; this->m_StreamingFPSMutex->Lock(); fps = this->m_StreamingFPS; this->m_StreamingFPSMutex->Unlock(); return fps; } diff --git a/Modules/US/USModel/mitkUSDevice.h b/Modules/US/USModel/mitkUSDevice.h index 0e3ac90b83..aaffa7ee38 100644 --- a/Modules/US/USModel/mitkUSDevice.h +++ b/Modules/US/USModel/mitkUSDevice.h @@ -1,488 +1,534 @@ /*=================================================================== 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 MITKUSDevice_H_HEADER_INCLUDED_ #define MITKUSDevice_H_HEADER_INCLUDED_ // STL #include // MitkUS #include "mitkUSProbe.h" #include #include "mitkUSImageSource.h" // MitkIGTL #include "mitkIGTLMessageProvider.h" #include "mitkIGTLServer.h" #include "mitkIGTLDeviceSource.h" #include "mitkImageToIGTLMessageFilter.h" // MITK #include #include #include // ITK #include #include // Microservices #include #include #include // DEPRECATED #include "mitkUSImageMetadata.h" namespace itk { template class SmartPointer; } namespace mitk { class USAbstractControlInterface; class USControlInterfaceBMode; class USControlInterfaceProbes; class USControlInterfaceDoppler; /** * \brief A device holds information about it's model, make and the connected probes. It is the * common super class for all devices and acts as an image source for mitkUSImages. It is the base class * for all US Devices, and every new device should extend it. * * US Devices support output of calibrated images, i.e. images that include a specific geometry. * To achieve this, call SetCalibration, and make sure that the subclass also calls apply * transformation at some point (The USDevice does not automatically apply the transformation to the image) * * Note that USDevices will be removed from micro servive when their * destructor is called. Registering into micro service is done when * mitk::USDevice::Initialize() is called. * * \ingroup US */ class MITKUS_EXPORT USDevice : public mitk::ImageSource { public: enum DeviceStates { State_NoState, State_Initialized, State_Connected, State_Activated }; mitkClassMacro(USDevice, mitk::ImageSource); itkSetMacro(SpawnAcquireThread, bool); itkGetMacro(SpawnAcquireThread, bool); struct USImageCropArea { int cropLeft; int cropRight; int cropBottom; int cropTop; }; /** * \brief These constants are used in conjunction with Microservices. * The constants aren't defined as static member attributes to avoid the * "static initialization order fiasco", which would occur when objects of * this class are used in module activators (for restoring stored device, * for example). */ struct PropertyKeys { const std::string US_INTERFACE_NAME; // Common Interface name of all US Devices. Used to refer to this device via Microservices const std::string US_PROPKEY_MANUFACTURER; const std::string US_PROPKEY_NAME; const std::string US_PROPKEY_COMMENT; const std::string US_PROPKEY_LABEL; // Human readable text represntation of this device const std::string US_PROPKEY_ISCONNECTED; // Whether this device is connected or not. const std::string US_PROPKEY_ISACTIVE; // Whether this device is active or not. const std::string US_PROPKEY_CLASS; // Class Name of this Object const std::string US_PROPKEY_PROBES_SELECTED; const std::string US_PROPKEY_BMODE_FREQUENCY; const std::string US_PROPKEY_BMODE_POWER; const std::string US_PROPKEY_BMODE_DEPTH; const std::string US_PROPKEY_BMODE_GAIN; const std::string US_PROPKEY_BMODE_REJECTION; const std::string US_PROPKEY_BMODE_DYNAMIC_RANGE; PropertyKeys() : US_INTERFACE_NAME("org.mitk.services.UltrasoundDevice"), US_PROPKEY_MANUFACTURER(US_INTERFACE_NAME + ".manufacturer"), US_PROPKEY_NAME(US_INTERFACE_NAME + ".name"), US_PROPKEY_COMMENT(US_INTERFACE_NAME + ".comment"), US_PROPKEY_LABEL(US_INTERFACE_NAME + ".label"), US_PROPKEY_ISCONNECTED(US_INTERFACE_NAME + ".isConnected"), US_PROPKEY_ISACTIVE(US_INTERFACE_NAME + ".isActive"), US_PROPKEY_CLASS(US_INTERFACE_NAME + ".class"), US_PROPKEY_PROBES_SELECTED(US_INTERFACE_NAME + ".probes.selected"), US_PROPKEY_BMODE_FREQUENCY(US_INTERFACE_NAME + ".bmode.frequency"), US_PROPKEY_BMODE_POWER(US_INTERFACE_NAME + ".bmode.power"), US_PROPKEY_BMODE_DEPTH(US_INTERFACE_NAME + ".bmode.depth"), US_PROPKEY_BMODE_GAIN(US_INTERFACE_NAME + ".bmode.gain"), US_PROPKEY_BMODE_REJECTION(US_INTERFACE_NAME + ".bmode.rejection"), US_PROPKEY_BMODE_DYNAMIC_RANGE(US_INTERFACE_NAME + ".bmode.dynamicRange") {} }; /** * \brief Event for being notified about changes of the micro service properties. * This event can be used if no micro service context is available. */ mitkNewMessage2Macro(PropertyChanged, const std::string&, const std::string&) /** * \return keys for the microservice properties of ultrasound devices */ static mitk::USDevice::PropertyKeys GetPropertyKeys(); /** * \brief Default getter for the custom control interface. * Has to be implemented in a subclass if a custom control interface is * available. Default implementation returns null. * * \return null pointer */ virtual itk::SmartPointer GetControlInterfaceCustom(); /** * \brief Default getter for the b mode control interface. * Has to be implemented in a subclass if a b mode control interface is * available. Default implementation returns null. * * \return null pointer */ virtual itk::SmartPointer GetControlInterfaceBMode(); /** * \brief Default getter for the probes control interface. * Has to be implemented in a subclass if a probes control interface is * available. Default implementation returns null. * * \return null pointer */ virtual itk::SmartPointer GetControlInterfaceProbes(); /** * \brief Default getter for the doppler control interface. * Has to be implemented in a subclass if a doppler control interface is * available. Default implementation returns null. * * \return null pointer */ virtual itk::SmartPointer GetControlInterfaceDoppler(); /** * \brief Changes device state to mitk::USDevice::State_Initialized. * During initialization the virtual method * mitk::USDevice::OnInitialization will be called. If this method * returns false the initialization process will be canceled. Otherwise * the mitk::USDevice is registered in a micro service. */ bool Initialize(); /** * \brief Connects this device. A connected device is ready to deliver images (i.e. be Activated). A Connected Device can be active. A disconnected Device cannot be active. * Internally calls onConnect and then registers the device with the service. A device usually should * override the OnConnection() method, but never the Connect() method, since this will possibly exclude the device * from normal service management. The exact flow of events is: * 0. Check if the device is already connected. If yes, return true anyway, but don't do anything. * 1. Call OnConnection() Here, a device should establish it's connection with the hardware Afterwards, it should be ready to start transmitting images at any time. * 2. If OnConnection() returns true ("successful"), then the device is registered with the service. * 3. if not, it the method itself returns false or may throw an expection, depeneding on the device implementation. * */ bool Connect(); void ConnectAsynchron(); /** * \brief Works analogously to mitk::USDevice::Connect(). Don't override this Method, but onDisconnection instead. */ bool Disconnect(); /** * \brief Activates this device. * After the activation process, the device will start to produce images. * This Method will fail, if the device is not connected. */ bool Activate(); /** * \brief Deactivates this device. * After the deactivation process, the device will no longer produce * images, but still be connected. */ void Deactivate(); /** * \brief Can toggle if ultrasound image is currently updated or freezed. * * \param freeze true to stop updating the ultrasound image, false to start updating again */ virtual void SetIsFreezed(bool freeze); /** * \return true if device is currently freezed (no image update is done), false otherwise */ virtual bool GetIsFreezed(); void PushFilter(AbstractOpenCVImageFilter::Pointer filter); void PushFilterIfNotPushedBefore(AbstractOpenCVImageFilter::Pointer filter); bool RemoveFilter(AbstractOpenCVImageFilter::Pointer filter); /** * @brief To be called when the used probe changed. Will update the service properties * @param probename of the now used probe */ void ProbeChanged(std::string probename); /** * @brief To be called when the scanning depth of the probe changed. Will update the service properties * @param depth that is now used */ void DepthChanged(double depth); /** * \brief Given property is updated in the device micro service. * This method is mainly for being used by the control interface * superclasses. You do not need to call it by yoursefs in your * concrete control interface classes. */ void UpdateServiceProperty(std::string key, std::string value); void UpdateServiceProperty(std::string key, double value); void UpdateServiceProperty(std::string key, bool value); //########### GETTER & SETTER ##################// /** * \brief Returns the Class of the Device. This Method must be reimplemented by every Inheriting Class. */ virtual std::string GetDeviceClass() = 0; /** * \brief True, if the device object is created and initialized, false otherwise. */ bool GetIsInitialized(); /** * \brief True, if the device is currently generating image data, false otherwise. */ bool GetIsActive(); /** * \brief True, if the device is currently ready to start transmitting image data or is already * transmitting image data. A disconnected device cannot be activated. */ bool GetIsConnected(); /* @return Returns the area that will be cropped from the US image. Is disabled / [0,0,0,0] by default. */ mitk::USDevice::USImageCropArea GetCropArea(); /* @return Returns the size of the m_ImageVector of the ultrasound device.*/ unsigned int GetSizeOfImageVector(); /** @return Returns the current image source of this device. */ virtual USImageSource::Pointer GetUSImageSource() = 0; /** \brief Deprecated -> use GetManufacturer() instead */ DEPRECATED(std::string GetDeviceManufacturer()); /** \brief Deprecated -> use GetName() instead */ DEPRECATED(std::string GetDeviceModel()); /** \brief Deprecated -> use GetCommend() instead */ DEPRECATED(std::string GetDeviceComment()); itkGetMacro(Manufacturer, std::string); itkGetMacro(Name, std::string); itkGetMacro(Comment, std::string); void SetManufacturer(std::string manufacturer); void SetName(std::string name); void SetComment(std::string comment); itkGetMacro(DeviceState, DeviceStates) itkGetMacro(ServiceProperties, us::ServiceProperties) void GrabImage(); + /** + * \brief Returns all probes for this device or an empty vector it no probes were set + * Returns a std::vector of all probes that exist for this device if there were probes set while creating or modifying this USVideoDevice. + * Otherwise it returns an empty vector. Therefore always check if vector is filled, before using it! + */ + virtual std::vector GetAllProbes() = 0; + + /** + * \brief Cleans the std::vector containing all configured probes. + */ + virtual void DeleteAllProbes() {}; + + /** + * \brief Return current active probe for this USDevice + * Returns a pointer to the probe that is currently in use. If there were probes set while creating or modifying this USDevice. + * Returns null otherwise + */ + virtual mitk::USProbe::Pointer GetCurrentProbe() = 0; + + /** + \brief adds a new probe to the device + */ + virtual void AddNewProbe(mitk::USProbe::Pointer probe) {}; + + /** + * \brief get the probe by its name + * Returns a pointer to the probe identified by the given name. If no probe of given name exists for this Device 0 is returned. + */ + virtual mitk::USProbe::Pointer GetProbeByName(std::string name) = 0; + + /** + * \brief Removes the Probe with the given name + */ + virtual void RemoveProbeByName(std::string name) {}; + + /** + * \brief Sets the first existing probe or the default probe of the ultrasound device + * as the current probe of it. + */ + virtual void SetDefaultProbeAsCurrentProbe() {}; + + /** + * \brief Sets the probe with the given name as current probe if the named probe exists. + */ + virtual void SetCurrentProbe(std::string probename) {}; + virtual void SetSpacing(double xSpacing, double ySpacing); protected: // Threading-Related itk::ConditionVariable::Pointer m_FreezeBarrier; itk::SimpleMutexLock m_FreezeMutex; itk::MultiThreader::Pointer m_MultiThreader; ///< itk::MultiThreader used for thread handling itk::FastMutexLock::Pointer m_ImageMutex; ///< mutex for images provided by the image source int m_ThreadID; ///< ID of the started thread virtual void SetImageVector(std::vector vec) { if (this->m_ImageVector != vec) { this->m_ImageVector = vec; this->Modified(); } } static ITK_THREAD_RETURN_TYPE Acquire(void* pInfoStruct); static ITK_THREAD_RETURN_TYPE ConnectThread(void* pInfoStruct); std::vector m_ImageVector; // Variables to determine if spacing was calibrated and needs to be applied to the incoming images mitk::Vector3D m_Spacing; /** * \brief Registers an OpenIGTLink device as a microservice so that we can send the images of * this device via the network. */ void ProvideViaOIGTL(); /** * \brief Deregisters the microservices for OpenIGTLink. */ void DisableOIGTL(); mitk::IGTLServer::Pointer m_IGTLServer; mitk::IGTLMessageProvider::Pointer m_IGTLMessageProvider; mitk::ImageToIGTLMessageFilter::Pointer m_ImageToIGTLMsgFilter; bool m_IsFreezed; DeviceStates m_DeviceState; /* @brief defines the area that should be cropped from the US image */ USImageCropArea m_CropArea; /** * \brief This Method constructs the service properties which can later be used to * register the object with the Microservices * Return service properties */ us::ServiceProperties ConstructServiceProperties(); /** * \brief Remove this device from the micro service. */ void UnregisterOnService(); /** * \brief Is called during the initialization process. * Override this method in a subclass to handle the actual initialization. * If it returns false, the initialization process will be canceled. * * \return true if successful and false if unsuccessful * \throw mitk::Exception implementation may throw an exception to clarify what went wrong */ virtual bool OnInitialization() = 0; /** * \brief Is called during the connection process. * Override this method in a subclass to handle the actual connection. * If it returns false, the connection process will be canceled. * * \return true if successful and false if unsuccessful * \throw mitk::Exception implementation may throw an exception to clarify what went wrong */ virtual bool OnConnection() = 0; /** * \brief Is called during the disconnection process. * Override this method in a subclass to handle the actual disconnection. * If it returns false, the disconnection process will be canceled. * * \return true if successful and false if unsuccessful * \throw mitk::Exception implementation may throw an exception to clarify what went wrong */ virtual bool OnDisconnection() = 0; /** * \brief Is called during the activation process. * After this method is finished, the device should be generating images. * If it returns false, the activation process will be canceled. * * \return true if successful and false if unsuccessful * \throw mitk::Exception implementation may throw an exception to clarify what went wrong */ virtual bool OnActivation() = 0; /** * \brief Is called during the deactivation process. * After a call to this method the device should still be connected, * but not producing images anymore. * * \return true if successful and false if unsuccessful * \throw mitk::Exception implementation may throw an exception to clarify what went wrong */ virtual bool OnDeactivation() = 0; /** * \brief Called when mitk::USDevice::SetIsFreezed() is called. * Subclasses can overwrite this method to do additional actions. Default * implementation does noting. */ virtual void OnFreeze(bool) { } /** * \brief Enforces minimal Metadata to be set. */ USDevice(std::string manufacturer, std::string model); /** * \brief Constructs a device with the given Metadata. Make sure the Metadata contains meaningful content! * \deprecated Use USDevice(std::string manufacturer, std::string model) instead. */ USDevice(mitk::USImageMetadata::Pointer metadata); ~USDevice() override; /** * \brief Grabs the next frame from the Video input. * This method is called internally, whenever Update() is invoked by an Output. */ void GenerateData() override; std::string GetServicePropertyLabel(); unsigned int m_NumberOfOutputs; /** * \brief Properties of the device's Microservice. */ us::ServiceProperties m_ServiceProperties; /** * \brief The device's ServiceRegistration object that allows to modify it's Microservice registraton details. */ us::ServiceRegistration m_ServiceRegistration; private: std::string m_Manufacturer; std::string m_Name; std::string m_Comment; bool m_SpawnAcquireThread; bool m_UnregisteringStarted; }; } // namespace mitk // This is the microservice declaration. Do not meddle! MITK_DECLARE_SERVICE_INTERFACE(mitk::USDevice, "org.mitk.services.UltrasoundDevice") #endif // MITKUSDevice_H_HEADER_INCLUDED_ diff --git a/Modules/US/USModel/mitkUSIGTLDevice.cpp b/Modules/US/USModel/mitkUSIGTLDevice.cpp index 17afb40fcd..4ebef36f7f 100644 --- a/Modules/US/USModel/mitkUSIGTLDevice.cpp +++ b/Modules/US/USModel/mitkUSIGTLDevice.cpp @@ -1,72 +1,172 @@ /*=================================================================== 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 mitk::USIGTLDevice::USIGTLDevice(std::string manufacturer, std::string model, std::string host, int port, bool server) : mitk::USDevice(manufacturer, model), m_Host(host), m_Port(port) { if (server) { m_Device = mitk::IGTLServer::New(true); } else { m_Device = mitk::IGTLClient::New(true); } m_Device->SetPortNumber(m_Port); m_Device->SetHostname(m_Host); m_Device->SetName(manufacturer + " - " + model); m_TransformDeviceSource = mitk::IGTLTrackingDataDeviceSource::New(); m_TransformDeviceSource->SetIGTLDevice(m_Device); m_TransformDeviceSource->RegisterAsMicroservice(); m_DeviceSource = mitk::IGTL2DImageDeviceSource::New(); m_DeviceSource->SetIGTLDevice(m_Device); m_DeviceSource->RegisterAsMicroservice(); m_Filter = mitk::IGTLMessageToUSImageFilter::New(); m_Filter->SetNumberOfExpectedOutputs(1); m_Filter->ConnectTo(m_DeviceSource); } std::string mitk::USIGTLDevice::GetDeviceClass() { return "IGTL Client"; } mitk::USImageSource::Pointer mitk::USIGTLDevice::GetUSImageSource() { return m_Filter.GetPointer(); } +void mitk::USIGTLDevice::UnregisterOnService() +{ + m_DeviceSource->UnRegisterMicroservice(); + m_TransformDeviceSource->UnRegisterMicroservice(); + mitk::USDevice::UnregisterOnService(); +} + +std::vector mitk::USIGTLDevice::GetAllProbes() +{ + if (m_Probes.empty()) + { + MITK_INFO << "No probes exist for this USVideDevice. Empty vector is returned"; + } + return m_Probes; +} + +void mitk::USIGTLDevice::DeleteAllProbes() +{ + m_Probes.clear(); +} + +mitk::USProbe::Pointer mitk::USIGTLDevice::GetCurrentProbe() +{ + if (m_CurrentProbe.IsNotNull()) + { + return m_CurrentProbe; + } + else + { + return nullptr; + } +} + +void mitk::USIGTLDevice::AddNewProbe(mitk::USProbe::Pointer probe) +{ + m_Probes.push_back(probe); +} + +mitk::USProbe::Pointer mitk::USIGTLDevice::GetProbeByName(std::string name) +{ + for (std::vector::iterator it = m_Probes.begin(); it != m_Probes.end(); it++) + { + if (name.compare((*it)->GetName()) == 0) + return (*it); + } + MITK_INFO << "No probe with given name " << name << " was found."; + return nullptr; //no matching probe was found so 0 is returned +} + +void mitk::USIGTLDevice::RemoveProbeByName(std::string name) +{ + for (std::vector::iterator it = m_Probes.begin(); it != m_Probes.end(); it++) + { + if (name.compare((*it)->GetName()) == 0) + { + m_Probes.erase(it); + return; + } + } + MITK_INFO << "No Probe with given name " << name << " was found"; +} + +void mitk::USIGTLDevice::SetDefaultProbeAsCurrentProbe() +{ + if (m_Probes.size() == 0) + { + std::string name = "default"; + mitk::USProbe::Pointer defaultProbe = mitk::USProbe::New(name); + m_Probes.push_back(defaultProbe); + } + + m_CurrentProbe = m_Probes.at(0); + MITK_INFO << "SetDefaultProbeAsCurrentProbe()"; + this->ProbeChanged(m_CurrentProbe->GetName()); +} + +void mitk::USIGTLDevice::SetCurrentProbe(std::string probename) +{ + m_CurrentProbe = this->GetProbeByName(probename); + MITK_INFO << "SetCurrentProbe() " << probename; +} + +void mitk::USIGTLDevice::SetSpacing(double xSpacing, double ySpacing) +{ + mitk::Vector3D spacing; + spacing[0] = xSpacing; + spacing[1] = ySpacing; + spacing[2] = 1; + MITK_INFO << "Spacing: " << spacing; + + if (m_CurrentProbe.IsNotNull()) + { + m_CurrentProbe->SetSpacingForGivenDepth(m_CurrentProbe->GetCurrentDepth(), spacing); + } + else + { + MITK_WARN << "Cannot set spacing. Current ultrasound probe not set."; + } +} + bool mitk::USIGTLDevice::OnInitialization() { return true; } bool mitk::USIGTLDevice::OnConnection() { return m_Device->OpenConnection(); } bool mitk::USIGTLDevice::OnDisconnection() { return m_Device->CloseConnection(); } bool mitk::USIGTLDevice::OnActivation() { return m_Device->StartCommunication(); } bool mitk::USIGTLDevice::OnDeactivation() { return m_Device->StopCommunication(); } diff --git a/Modules/US/USModel/mitkUSIGTLDevice.h b/Modules/US/USModel/mitkUSIGTLDevice.h index afa03c94f5..584d7f538d 100644 --- a/Modules/US/USModel/mitkUSIGTLDevice.h +++ b/Modules/US/USModel/mitkUSIGTLDevice.h @@ -1,69 +1,138 @@ /*=================================================================== 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 MITKIGTLDevice_H_HEADER_INCLUDED_ #define MITKIGTLDevice_H_HEADER_INCLUDED_ #include #include #include +#include #include #include #include #include #include namespace mitk { /** * \brief A mitk::USIGTLDevice is a USDevice to receive images over an OpenIGTLink * connection. It registers an OIGTL device as a Microservice to receive image messages * and transforms them to mitk::Images. It can act both as a server (listening for * incoming connections) and as a client (connecting to an existing OIGTL server). * * \ingroup US */ class MITKUS_EXPORT USIGTLDevice : public mitk::USDevice { public: mitkClassMacro(USIGTLDevice, mitk::USDevice); // To open a device (Manufacturer, Model, Hostname, Port, IsServer) mitkNewMacro5Param(Self, std::string, std::string, std::string, int, bool); std::string GetDeviceClass() override; USImageSource::Pointer GetUSImageSource() override; USIGTLDevice(std::string manufacturer, std::string model, std::string host, int port, bool server); + /** + * \brief Remove the IGTLDevice from the micro service. + */ + void UnregisterOnService(); + + // Neu hinzugefügt: + /** + * \brief Return all probes for this USVideoDevice or an empty vector it no probes were set + * Returns a std::vector of all probes that exist for this USVideoDevice if there were probes set while creating or modifying this USVideoDevice. + * Otherwise it returns an empty vector. Therefore always check if vector is filled, before using it! + */ + virtual std::vector GetAllProbes() override; + + /** + * \brief Cleans the std::vector containing all configured probes. + */ + virtual void DeleteAllProbes() override; + + /** + * \brief Return current active probe for this USDevice + * Returns a pointer to the probe that is currently in use. If there were probes set while creating or modifying this USDevice. + * Returns null otherwise + */ + virtual mitk::USProbe::Pointer GetCurrentProbe() override; + + /** + \brief adds a new probe to the device + */ + virtual void AddNewProbe(mitk::USProbe::Pointer probe) override; + + /** + * \brief get the probe by its name + * Returns a pointer to the probe identified by the given name. If no probe of given name exists for this Device 0 is returned. + */ + virtual mitk::USProbe::Pointer GetProbeByName(std::string name) override; + + /** + * \brief Removes the Probe with the given name + */ + virtual void RemoveProbeByName(std::string name) override; + + /** + * \brief Sets the first existing probe or the default probe of the video device + * as the current probe of it. + */ + virtual void SetDefaultProbeAsCurrentProbe() override; + + /** + * \brief Sets the probe with the given name as current probe if the named probe exists. + */ + virtual void SetCurrentProbe(std::string probename) override; + + /** + * \brief Sets the given spacing of the current depth of the current probe. + */ + void SetSpacing(double xSpacing, double ySpacing) override; + + protected: bool OnInitialization() override; bool OnConnection() override; bool OnDisconnection() override; bool OnActivation() override; bool OnDeactivation() override; private: std::string m_Host; int m_Port; mitk::IGTLDevice::Pointer m_Device; mitk::IGTL2DImageDeviceSource::Pointer m_DeviceSource; mitk::IGTLTrackingDataDeviceSource::Pointer m_TransformDeviceSource; mitk::IGTLMessageToUSImageFilter::Pointer m_Filter; + + /** + * \brief probes for this USVideoDevice + */ + std::vector < mitk::USProbe::Pointer > m_Probes; + + /** + \brief probe that is currently in use + */ + mitk::USProbe::Pointer m_CurrentProbe; }; } // namespace mitk #endif // MITKIGTLDevice_H_HEADER_INCLUDED_ diff --git a/Modules/US/USModel/mitkUSVideoDevice.h b/Modules/US/USModel/mitkUSVideoDevice.h index df205dd6c0..cb989d82ca 100644 --- a/Modules/US/USModel/mitkUSVideoDevice.h +++ b/Modules/US/USModel/mitkUSVideoDevice.h @@ -1,252 +1,252 @@ /*=================================================================== 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 MITKUSVideoDevice_H_HEADER_INCLUDED_ #define MITKUSVideoDevice_H_HEADER_INCLUDED_ #include #include #include "mitkUSDevice.h" #include "mitkUSImageVideoSource.h" #include "mitkUSProbe.h" #include namespace itk { template class SmartPointer; } namespace mitk { class USVideoDeviceCustomControls; class USAbstractControlInterface; /** * \brief A mitk::USVideoDevice is the common class for video only devices. * They capture video input either from a file or from a device and * transform the output into an mitk::USImage with attached metadata. * This simple implementation does only capture and display 2d images without * registration for example. * * \ingroup US */ class MITKUS_EXPORT USVideoDevice : public mitk::USDevice { public: mitkClassMacro(USVideoDevice, mitk::USDevice); // To open a device (DeviceID, Manufacturer, Model) mitkNewMacro3Param(Self, int, std::string, std::string); // To open A VideoFile (Path, Manufacturer, Model) mitkNewMacro3Param(Self, std::string, std::string, std::string); // To open a device (DeviceID, Metadata) mitkNewMacro2Param(Self, int, mitk::USImageMetadata::Pointer); // To open A VideoFile (Path, Metadata) mitkNewMacro2Param(Self, std::string, mitk::USImageMetadata::Pointer); /** * \return the qualified name of this class (as returned by GetDeviceClassStatic()) */ std::string GetDeviceClass() override; /** * This methode is necessary instead of a static member attribute to avoid * "static initialization order fiasco" when an instance of this class is * used in a module activator. * * \return the qualified name of this class */ static std::string GetDeviceClassStatic(); /** * Getter for the custom control interface which was created during the * construction process of mitk::USVideoDevice. * * \return custom control interface of the video device */ itk::SmartPointer GetControlInterfaceCustom() override; /** * \brief Remove this device from the micro service. * This method is public for mitk::USVideoDevice, because this devices * can be completly removed. This is not possible for API devices, which * should be available while their sub module is loaded. */ void UnregisterOnService(); /** * \return mitk::USImageSource connected to this device */ USImageSource::Pointer GetUSImageSource() override; /** * \brief Return all probes for this USVideoDevice or an empty vector it no probes were set * Returns a std::vector of all probes that exist for this USVideoDevice if there were probes set while creating or modifying this USVideoDevice. * Otherwise it returns an empty vector. Therefore always check if vector is filled, before using it! */ - std::vector GetAllProbes(); + virtual std::vector GetAllProbes() override; /** * \brief Cleans the std::vector containing all configured probes. */ - void DeleteAllProbes(); + virtual void DeleteAllProbes() override; /** * \brief Return current active probe for this USVideoDevice * Returns a pointer to the probe that is currently in use. If there were probes set while creating or modifying this USVideoDevice. * Returns null otherwise */ - mitk::USProbe::Pointer GetCurrentProbe(); + virtual mitk::USProbe::Pointer GetCurrentProbe() override; /** \brief adds a new probe to the device */ - void AddNewProbe(mitk::USProbe::Pointer probe); + virtual void AddNewProbe(mitk::USProbe::Pointer probe) override; /** * \brief get the probe by its name * Returns a pointer to the probe identified by the given name. If no probe of given name exists for this Device 0 is returned. */ - mitk::USProbe::Pointer GetProbeByName(std::string name); + virtual mitk::USProbe::Pointer GetProbeByName(std::string name) override; /** * \brief Removes the Probe with the given name */ - void RemoveProbeByName(std::string name); + virtual void RemoveProbeByName(std::string name) override; /** \brief True, if this Device plays back a file, false if it recieves data from a device */ bool GetIsSourceFile(); /** * \brief Sets the first existing probe or the default probe of the video device * as the current probe of it. */ - void SetDefaultProbeAsCurrentProbe(); + virtual void SetDefaultProbeAsCurrentProbe() override; /** * \brief Sets the probe with the given name as current probe if the named probe exists. */ - void SetCurrentProbe( std::string probename ); + virtual void SetCurrentProbe( std::string probename ) override; /** * \brief Sets the given spacing of the current depth of the current probe. */ void SetSpacing( double xSpacing, double ySpacing ) override; itkGetMacro(ImageVector, std::vector); itkGetMacro(DeviceID, int); itkGetMacro(FilePath, std::string); protected: /** * \brief Creates a new device that will deliver USImages taken from a video device. * under windows, try -1 for device number, which will grab the first available one * (Open CV functionality) */ USVideoDevice(int videoDeviceNumber, std::string manufacturer, std::string model); /** * \brief Creates a new device that will deliver USImages taken from a video file. */ USVideoDevice(std::string videoFilePath, std::string manufacturer, std::string model); /** * \brief Creates a new device that will deliver USImages taken from a video device. * under windows, try -1 for device number, which will grab the first available one * (Open CV functionality) */ USVideoDevice(int videoDeviceNumber, mitk::USImageMetadata::Pointer metadata); /** * \brief Creates a new device that will deliver USImages taken from a video file. */ USVideoDevice(std::string videoFilePath, mitk::USImageMetadata::Pointer metadata); ~USVideoDevice() override; /** * \brief Initializes common properties for all constructors. */ void Init(); /** * \brief Is called during the initialization process. * Returns true if successful and false if unsuccessful. Additionally, you may throw an exception to clarify what went wrong. */ bool OnInitialization() override; /** * \brief Is called during the connection process. * Returns true if successful and false if unsuccessful. Additionally, you may throw an exception to clarify what went wrong. */ bool OnConnection() override; /** * \brief Is called during the disconnection process. * Returns true if successful and false if unsuccessful. Additionally, you may throw an exception to clarify what went wrong. */ bool OnDisconnection() override; /** * \brief Is called during the activation process. After this method is finsihed, the device should be generating images */ bool OnActivation() override; /** * \brief Is called during the deactivation process. After a call to this method the device should still be connected, but not producing images anymore. */ bool OnDeactivation() override; /** * \brief Grabs the next frame from the Video input. * This method is called internally, whenever Update() is invoked by an Output. */ virtual void GenerateData() override; /** * \brief The image source that we use to aquire data */ mitk::USImageVideoSource::Pointer m_Source; /** * \brief True, if this source plays back a file, false if it recieves data from a device */ bool m_SourceIsFile; /** * \brief The device id to connect to. Undefined, if m_SourceIsFile == true; */ int m_DeviceID; /** * \brief The Filepath id to connect to. Undefined, if m_SourceIsFile == false; */ std::string m_FilePath; /** * \brief custom control interface for us video device */ itk::SmartPointer m_ControlInterfaceCustom; /** * \brief probes for this USVideoDevice */ std::vector < mitk::USProbe::Pointer > m_Probes; /** \brief probe that is currently in use */ mitk::USProbe::Pointer m_CurrentProbe; }; } // namespace mitk #endif // MITKUSVideoDevice_H_HEADER_INCLUDED_ diff --git a/Modules/USUI/Qmitk/QmitkUSDeviceManagerWidget.cpp b/Modules/USUI/Qmitk/QmitkUSDeviceManagerWidget.cpp index b1619bc1b6..f29a71c53f 100644 --- a/Modules/USUI/Qmitk/QmitkUSDeviceManagerWidget.cpp +++ b/Modules/USUI/Qmitk/QmitkUSDeviceManagerWidget.cpp @@ -1,237 +1,253 @@ /*=================================================================== 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 #include #include #include #include "mitkUSVideoDevice.h" +#include const std::string QmitkUSDeviceManagerWidget::VIEW_ID = "org.mitk.views.QmitkUSDeviceManagerWidget"; QmitkUSDeviceManagerWidget::QmitkUSDeviceManagerWidget(QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f) { m_Controls = nullptr; CreateQtPartControl(this); } QmitkUSDeviceManagerWidget::~QmitkUSDeviceManagerWidget() {} //////////////////// INITIALIZATION ///////////////////// void QmitkUSDeviceManagerWidget::CreateQtPartControl(QWidget* parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkUSDeviceManagerWidgetControls; m_Controls->setupUi(parent); this->CreateConnections(); m_Controls->m_ConnectedDevices->SetAutomaticallySelectFirstEntry(true); } // Initializations std::string empty = ""; m_Controls->m_ConnectedDevices->Initialize( mitk::USDevice::GetPropertyKeys().US_PROPKEY_LABEL, empty); } void QmitkUSDeviceManagerWidget::CreateConnections() { if (m_Controls) { connect(m_Controls->m_BtnActivate, SIGNAL(clicked()), this, SLOT(OnClickedActivateDevice())); // connect( m_Controls->m_BtnDisconnect, SIGNAL( clicked() ), this, // SLOT(OnClickedDisconnectDevice()) ); connect(m_Controls->m_BtnRemove, SIGNAL(clicked()), this, SLOT(OnClickedRemoveDevice())); connect(m_Controls->m_BtnNewDevice, SIGNAL(clicked()), this, SLOT(OnClickedNewDevice())); connect(m_Controls->m_ConnectedDevices, SIGNAL(ServiceSelectionChanged(us::ServiceReferenceU)), this, SLOT(OnDeviceSelectionChanged(us::ServiceReferenceU))); connect(m_Controls->m_BtnEdit, SIGNAL(clicked()), this, SLOT(OnClickedEditDevice())); } } ///////////// Methods & Slots Handling Direct Interaction ///////////////// void QmitkUSDeviceManagerWidget::OnClickedActivateDevice() { mitk::USDevice::Pointer device = m_Controls->m_ConnectedDevices->GetSelectedService(); if (device.IsNull()) { return; } if (device->GetIsActive()) { device->Deactivate(); device->Disconnect(); } else { QApplication::setOverrideCursor(Qt::WaitCursor); if (device->GetDeviceState() < mitk::USDevice::State_Connected) { device->Connect(); } if (device->GetIsConnected()) { device->Activate(); } QApplication::restoreOverrideCursor(); if (!device->GetIsActive()) { QMessageBox::warning( this, "Activation failed", "Could not activate device. Check logging for details."); } else { emit DeviceActivated(); } } // Manually reevaluate Button logic OnDeviceSelectionChanged( m_Controls->m_ConnectedDevices->GetSelectedServiceReference()); } void QmitkUSDeviceManagerWidget::OnClickedDisconnectDevice() { mitk::USDevice::Pointer device = m_Controls->m_ConnectedDevices->GetSelectedService(); if (device.IsNull()) { return; } if (device->GetIsConnected()) { device->Disconnect(); } else { if (!device->Connect()) { QMessageBox::warning( this, "Connecting failed", "Could not connect to device. Check logging for details."); } } } void QmitkUSDeviceManagerWidget::OnClickedRemoveDevice() { mitk::USDevice::Pointer device = m_Controls->m_ConnectedDevices->GetSelectedService(); + if (device.IsNull()) { return; } if (device->GetDeviceClass() == "org.mitk.modules.us.USVideoDevice") { if (device->GetIsActive()) { device->Deactivate(); } if (device->GetIsConnected()) { device->Disconnect(); } dynamic_cast(device.GetPointer()) ->UnregisterOnService(); } + else if (device->GetDeviceClass() == "IGTL Client") + { + mitk::USIGTLDevice::Pointer ultrasoundIGTLDevice = dynamic_cast(device.GetPointer()); + if (ultrasoundIGTLDevice->GetIsActive()) + { + ultrasoundIGTLDevice->Deactivate(); + } + if (ultrasoundIGTLDevice->GetIsConnected()) + { + ultrasoundIGTLDevice->Disconnect(); + } + ultrasoundIGTLDevice->UnregisterOnService(); + } } void QmitkUSDeviceManagerWidget::OnClickedNewDevice() { emit NewDeviceButtonClicked(); } void QmitkUSDeviceManagerWidget::OnClickedEditDevice() { mitk::USDevice::Pointer device = m_Controls->m_ConnectedDevices->GetSelectedService(); emit EditDeviceButtonClicked(device); } void QmitkUSDeviceManagerWidget::OnDeviceSelectionChanged( us::ServiceReferenceU reference) { if (!reference) { m_Controls->m_BtnActivate->setEnabled(false); m_Controls->m_BtnRemove->setEnabled(false); m_Controls->m_BtnEdit->setEnabled(false); return; } std::string isConnected = reference.GetProperty( mitk::USDevice::GetPropertyKeys().US_PROPKEY_ISCONNECTED) .ToString(); std::string isActive = reference.GetProperty( mitk::USDevice::GetPropertyKeys().US_PROPKEY_ISACTIVE) .ToString(); if (isActive.compare("false") == 0) { m_Controls->m_BtnActivate->setEnabled(true); m_Controls->m_BtnActivate->setText("Activate"); } else { m_Controls->m_BtnActivate->setEnabled(true); m_Controls->m_BtnActivate->setText("Deactivate"); } std::string deviceClass = reference.GetProperty(mitk::USDevice::GetPropertyKeys().US_PROPKEY_CLASS) .ToString(); m_Controls->m_BtnRemove->setEnabled(deviceClass == - "org.mitk.modules.us.USVideoDevice"); - m_Controls->m_BtnEdit->setEnabled((deviceClass == "org.mitk.modules.us.USVideoDevice") && (isActive.compare("false") == 0)); + "org.mitk.modules.us.USVideoDevice" || deviceClass == "IGTL Client"); + m_Controls->m_BtnEdit->setEnabled((deviceClass == "org.mitk.modules.us.USVideoDevice") && (isActive.compare("false") == 0) || + (deviceClass == "IGTL Client") && (isActive.compare("false") == 0)); } void QmitkUSDeviceManagerWidget::DisconnectAllDevices() { // at the moment disconnects ALL devices. Maybe we only want to disconnect the // devices handled by this widget? us::ModuleContext* thisContext = us::GetModuleContext(); std::vector > services = thisContext->GetServiceReferences(); for (std::vector >::iterator it = services.begin(); it != services.end(); ++it) { mitk::USDevice* currentDevice = thisContext->GetService(*it); currentDevice->Disconnect(); } MITK_INFO << "Disconnected ALL US devises!"; } diff --git a/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidget.cpp b/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidget.cpp index c88d5bff0a..3ce7a91120 100644 --- a/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidget.cpp +++ b/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidget.cpp @@ -1,812 +1,808 @@ /*=================================================================== 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 // QT headers #include #include // mitk headers // itk headers #include #include const std::string QmitkUSNewVideoDeviceWidget::VIEW_ID = "org.mitk.views.QmitkUSNewVideoDeviceWidget"; QmitkUSNewVideoDeviceWidget::QmitkUSNewVideoDeviceWidget(QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f) { m_Controls = nullptr; CreateQtPartControl(this); } QmitkUSNewVideoDeviceWidget::~QmitkUSNewVideoDeviceWidget() {} //////////////////// INITIALIZATION ///////////////////// void QmitkUSNewVideoDeviceWidget::CreateQtPartControl(QWidget* parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkUSNewVideoDeviceWidgetControls; m_Controls->setupUi(parent); this->CreateConnections(); } } void QmitkUSNewVideoDeviceWidget::CreateConnections() { if (m_Controls) { // connect(m_Controls->m_BtnDone, SIGNAL(clicked()), this, // SLOT(OnClickedDone())); connect(m_Controls->m_BtnCancel, SIGNAL(clicked()), this, SLOT(OnClickedCancel())); connect(m_Controls->m_RadioDeviceSource, SIGNAL(clicked()), this, SLOT(OnDeviceTypeSelection())); connect(m_Controls->m_RadioFileSource, SIGNAL(clicked()), this, SLOT(OnDeviceTypeSelection())); connect(m_Controls->m_RadioOIGTLClientSource, SIGNAL(clicked()), this, SLOT(OnDeviceTypeSelection())); connect(m_Controls->m_RadioOIGTLServerSource, SIGNAL(clicked()), this, SLOT(OnDeviceTypeSelection())); connect(m_Controls->m_OpenFileButton, SIGNAL(clicked()), this, SLOT(OnOpenFileButtonClicked())); connect(m_Controls->m_BtnSave, SIGNAL(clicked()), this, SLOT(OnSaveButtonClicked())); connect(m_Controls->m_BtnLoadConfiguration, SIGNAL(clicked()), this, SLOT(OnLoadConfigurationButtonClicked())); //Connect buttons and functions for editing of probes connect(m_Controls->m_AddNewProbePushButton, SIGNAL(clicked()), this, SLOT(OnAddNewProbeClicked())); connect(m_Controls->m_BtnRemoveProbe, SIGNAL(clicked()), this, SLOT(OnClickedRemoveProbe())); connect(m_Controls->m_BtnRemoveDepth, SIGNAL(clicked()), this, SLOT(OnClickedRemoveDepth())); connect(m_Controls->m_BtnAddDepths, SIGNAL(clicked()), this, SLOT(OnClickedAddDepths())); connect(m_Controls->m_Probes, SIGNAL(currentTextChanged(const QString &)), this, SLOT(OnProbeChanged(const QString &))); connect(m_Controls->m_Depths, SIGNAL(currentTextChanged(const QString &)), this, SLOT(OnDepthChanged(const QString &))); connect(m_Controls->m_XSpacingSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnXSpacingSpinBoxChanged(double))); connect(m_Controls->m_YSpacingSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnYSpacingSpinBoxChanged(double))); connect(m_Controls->m_CroppingTopSpinBox, SIGNAL(valueChanged(int)), this, SLOT(OnCroppingTopSpinBoxChanged(int))); connect(m_Controls->m_CroppingRightSpinBox, SIGNAL(valueChanged(int)), this, SLOT(OnCroppingRightSpinBoxChanged(int))); connect(m_Controls->m_CroppingBottomSpinBox, SIGNAL(valueChanged(int)), this, SLOT(OnCroppingBottomSpinBoxChanged(int))); connect(m_Controls->m_CroppingLeftSpinBox, SIGNAL(valueChanged(int)), this, SLOT(OnCroppingLeftSpinBoxChanged(int))); } } ///////////// Methods & Slots Handling Direct Interaction ///////////////// void QmitkUSNewVideoDeviceWidget::OnClickedDone() { m_Active = false; // Create Device - mitk::USVideoDevice::Pointer newDevice; + mitk::USDevice::Pointer newDevice; if (m_Controls->m_RadioDeviceSource->isChecked()) { newDevice = mitk::USVideoDevice::New( m_Controls->m_DeviceSelector->value(), m_Controls->m_Manufacturer->text().toStdString(), m_Controls->m_Model->text().toStdString()); newDevice->SetComment(m_Controls->m_Comment->text().toStdString()); } else if (m_Controls->m_RadioFileSource->isChecked()) { newDevice = mitk::USVideoDevice::New( m_Controls->m_FilePathSelector->text().toStdString(), m_Controls->m_Manufacturer->text().toStdString(), m_Controls->m_Model->text().toStdString()); newDevice->SetComment(m_Controls->m_Comment->text().toStdString()); } else if (m_Controls->m_RadioOIGTLClientSource->isChecked()) { std::string host = m_Controls->m_OIGTLClientHost->text().toStdString(); int port = m_Controls->m_OIGTLClientPort->value(); // Create a new USIGTLDevice. The last parameter tells the device that it should be a client. - mitk::USIGTLDevice::Pointer device = - mitk::USIGTLDevice::New(m_Controls->m_Manufacturer->text().toStdString(), - m_Controls->m_Model->text().toStdString(), host, port, false); - device->Initialize(); - emit Finished(); - // The rest of this method does stuff that is specific to USVideoDevices, - // which we don't need. So we return directly. - return; + newDevice = mitk::USIGTLDevice::New(m_Controls->m_Manufacturer->text().toStdString(), + m_Controls->m_Model->text().toStdString(), host, port, false); + //New behavior at this position: do not return immediately as it was done in earlier MITK-versions + // The IGTL Device can have different probe configurations, as well. } else { std::string host = m_Controls->m_OIGTLServerHost->text().toStdString(); int port = m_Controls->m_OIGTLServerPort->value(); // Create a new USIGTLDevice. The last parameter tells the device that it should be a server. - mitk::USIGTLDevice::Pointer device = - mitk::USIGTLDevice::New(m_Controls->m_Manufacturer->text().toStdString(), - m_Controls->m_Model->text().toStdString(), host, port, true); - device->Initialize(); - emit Finished(); - // The rest of this method does stuff that is specific to USVideoDevices, - // which we don't need. So we return directly. - return; + newDevice = mitk::USIGTLDevice::New(m_Controls->m_Manufacturer->text().toStdString(), + m_Controls->m_Model->text().toStdString(), host, port, true); + //New behavior at this position: do not return immediately as it was done in earlier MITK-versions + // The IGTL Device can have different probe configurations, as well. } - // get USImageVideoSource from new device + //At first: only ckeck, whether it is a USImageVideoSource or not (--> if it a IGTL Client) + // Later: perhaps it would be helpful, if the IGTLMessageToUSImageFilter have a region of interest, as well. mitk::USImageVideoSource::Pointer imageSource = dynamic_cast( - newDevice->GetUSImageSource().GetPointer()); - if (!imageSource) + newDevice->GetUSImageSource().GetPointer()); + if (imageSource.IsNotNull()) { - MITK_ERROR << "There is no USImageVideoSource at the current device."; - mitkThrow() << "There is no USImageVideoSource at the current device."; - } - // Set Video Options - imageSource->SetColorOutput(!m_Controls->m_CheckGreyscale->isChecked()); + // Set Video Options + imageSource->SetColorOutput(!m_Controls->m_CheckGreyscale->isChecked()); - // If Resolution override is activated, apply it - if (m_Controls->m_CheckResolutionOverride->isChecked()) - { - int width = m_Controls->m_ResolutionWidth->value(); - int height = m_Controls->m_ResolutionHeight->value(); - imageSource->OverrideResolution(width, height); - imageSource->SetResolutionOverride(true); + // If Resolution override is activated, apply it + if (m_Controls->m_CheckResolutionOverride->isChecked()) + { + int width = m_Controls->m_ResolutionWidth->value(); + int height = m_Controls->m_ResolutionHeight->value(); + imageSource->OverrideResolution(width, height); + imageSource->SetResolutionOverride(true); + } } + if (m_Controls->m_Probes->count() != 0 ) //there are informations about the probes of the device, so create the probes { this->AddProbesToDevice(newDevice); } else //no information about the probes of the device, so set default value { mitk::USProbe::Pointer probe = mitk::USProbe::New("default"); probe->SetDepth(0); newDevice->DeleteAllProbes(); newDevice->AddNewProbe(probe); } newDevice->Initialize(); CleanUpAfterCreatingNewDevice(); emit Finished(); } void QmitkUSNewVideoDeviceWidget::OnClickedFinishedEditing() { m_Active = false; m_TargetDevice->SetManufacturer(m_Controls->m_Manufacturer->text().toStdString()); m_TargetDevice->SetName(m_Controls->m_Model->text().toStdString()); m_TargetDevice->SetComment(m_Controls->m_Comment->text().toStdString()); if (m_Controls->m_Probes->count() != 0) //there are informations about the probes of the device, so create the probes { this->AddProbesToDevice(m_TargetDevice); } else //no information about the probes of the device, so set default value { mitk::USProbe::Pointer probe = mitk::USProbe::New("default"); probe->SetDepth(0); m_TargetDevice->DeleteAllProbes(); m_TargetDevice->AddNewProbe(probe); } + //At first: only ckeck, whether it is a USImageVideoSource or not (--> if it a IGTL Client) + // Later: perhaps it would be helpful, if the IGTLMessageToUSImageFilter have a region of interest, as well. mitk::USImageVideoSource::Pointer imageSource = dynamic_cast( m_TargetDevice->GetUSImageSource().GetPointer()); - if (!imageSource) + if (imageSource.IsNotNull()) { - MITK_ERROR << "There is no USImageVideoSource at the current device."; - mitkThrow() << "There is no USImageVideoSource at the current device."; - } + // Set Video Options + imageSource->SetColorOutput(!m_Controls->m_CheckGreyscale->isChecked()); - // Set Video Options - imageSource->SetColorOutput(!m_Controls->m_CheckGreyscale->isChecked()); - - // If Resolution override is activated, apply it - if (m_Controls->m_CheckResolutionOverride->isChecked()) - { - int width = m_Controls->m_ResolutionWidth->value(); - int height = m_Controls->m_ResolutionHeight->value(); - imageSource->OverrideResolution(width, height); - imageSource->SetResolutionOverride(true); + // If Resolution override is activated, apply it + if (m_Controls->m_CheckResolutionOverride->isChecked()) + { + int width = m_Controls->m_ResolutionWidth->value(); + int height = m_Controls->m_ResolutionHeight->value(); + imageSource->OverrideResolution(width, height); + imageSource->SetResolutionOverride(true); + } } CleanUpAfterEditingOfDevice(); MITK_INFO << "Finished Editing"; emit Finished(); } void QmitkUSNewVideoDeviceWidget::OnClickedCancel() { m_TargetDevice = nullptr; m_Active = false; CleanUpAfterCreatingNewDevice(); CleanUpAfterEditingOfDevice(); emit Finished(); } void QmitkUSNewVideoDeviceWidget::OnDeviceTypeSelection() { m_Controls->m_FilePathSelector->setEnabled( m_Controls->m_RadioFileSource->isChecked()); m_Controls->m_DeviceSelector->setEnabled( m_Controls->m_RadioDeviceSource->isChecked()); m_Controls->m_OIGTLClientHost->setEnabled( m_Controls->m_RadioOIGTLClientSource->isChecked()); m_Controls->m_OIGTLClientPort->setEnabled( m_Controls->m_RadioOIGTLClientSource->isChecked()); m_Controls->m_OIGTLServerHost->setEnabled( m_Controls->m_RadioOIGTLServerSource->isChecked()); m_Controls->m_OIGTLServerPort->setEnabled( m_Controls->m_RadioOIGTLServerSource->isChecked()); } void QmitkUSNewVideoDeviceWidget::OnOpenFileButtonClicked() { QString fileName = QFileDialog::getOpenFileName(nullptr, "Open Video File"); if (fileName.isNull()) { return; } // user pressed cancel m_Controls->m_FilePathSelector->setText(fileName); m_Controls->m_RadioFileSource->setChecked(true); this->OnDeviceTypeSelection(); } ///////////////// Methods & Slots Handling Logic ////////////////////////// void QmitkUSNewVideoDeviceWidget::EditDevice(mitk::USDevice::Pointer device) { + MITK_WARN << "EditDevice() called()"; // If no VideoDevice is given, throw an exception - if (device->GetDeviceClass().compare("org.mitk.modules.us.USVideoDevice") != - 0) + if (device->GetDeviceClass().compare("org.mitk.modules.us.USVideoDevice") != 0 && + device->GetDeviceClass().compare("IGTL Client") != 0) { // TODO Alert if bad path mitkThrow() << "NewVideoDeviceWidget recieved an incompatible device type " "to edit. Type was: " << device->GetDeviceClass(); } - m_TargetDevice = static_cast(device.GetPointer()); + + m_TargetDevice = device; m_Active = true; m_ConfigProbes.clear(); m_ConfigProbes = m_TargetDevice->GetAllProbes(); ChangeUIEditingUSVideoDevice(); } void QmitkUSNewVideoDeviceWidget::CreateNewDevice() { + + //Prevent multiple calls of OnClickedDone() + disconnect(m_Controls->m_BtnDone, SIGNAL(clicked()), this, SLOT(OnClickedDone())); //Toggle functionality of Btn_Done connect(m_Controls->m_BtnDone, SIGNAL(clicked()), this, SLOT(OnClickedDone())); m_Controls->m_BtnDone->setText("Add Video Device"); //Fill Metadata with default information m_Controls->m_Manufacturer->setText("Unknown Manufacturer"); m_Controls->m_Model->setText("Unknown Model"); m_Controls->m_Comment->setText("None"); m_TargetDevice = nullptr; m_ConfigProbes.clear(); m_ConfigProbes.clear(); m_Active = true; } /////////////////////// HOUSEHOLDING CODE /////////////////////////////// QListWidgetItem* QmitkUSNewVideoDeviceWidget::ConstructItemFromDevice( mitk::USDevice::Pointer device) { QListWidgetItem* result = new QListWidgetItem; std::string text = device->GetManufacturer() + "|" + device->GetName(); result->setText(text.c_str()); return result; } void QmitkUSNewVideoDeviceWidget::ChangeUIEditingUSVideoDevice() { for (std::vector::iterator it = m_ConfigProbes.begin(); it != m_ConfigProbes.end(); it++) { std::string probeName = (*it)->GetName(); m_Controls->m_Probes->addItem(QString::fromUtf8(probeName.data(), probeName.size())); } OnProbeChanged(m_Controls->m_Probes->currentText()); //Toggle functionality of Btn_Done m_Controls->m_BtnDone->setText("Apply Changes"); connect(m_Controls->m_BtnDone, SIGNAL(clicked()), this, SLOT(OnClickedFinishedEditing())); //Fill Metadata with Information provided by the Device selected to edit m_Controls->m_Manufacturer->setText(m_TargetDevice->GetManufacturer().c_str()); m_Controls->m_Model->setText(m_TargetDevice->GetName().c_str()); m_Controls->m_Comment->setText(m_TargetDevice->GetComment().c_str()); } void QmitkUSNewVideoDeviceWidget::OnClickedAddDepths() { if (!m_Controls->m_Probes->currentText().isEmpty()) { QString depths = m_Controls->m_AddDepths->text(); if( depths.isEmpty() ) return; std::string probename = m_Controls->m_Probes->currentText().toStdString(); mitk::USProbe::Pointer currentProbe = this->CheckIfProbeExistsAlready(probename); QStringList singleDepths = depths.split(','); for (int i = 0; i < singleDepths.size(); i++) { currentProbe->SetDepth(singleDepths.at(i).toInt()); } m_Controls->m_AddDepths->clear(); m_Controls->m_Depths->setEnabled(true); m_Controls->m_BtnRemoveDepth->setEnabled(true); OnProbeChanged(m_Controls->m_Probes->currentText()); } } void QmitkUSNewVideoDeviceWidget::OnClickedRemoveDepth() { if (!m_Controls->m_Probes->currentText().isEmpty() && !m_Controls->m_Depths->currentText().isEmpty()) { std::string probename = m_Controls->m_Probes->currentText().toStdString(); int indexOfDepthToRemove = m_Controls->m_Depths->currentIndex(); mitk::USProbe::Pointer currentProbe = this->CheckIfProbeExistsAlready(probename); currentProbe->RemoveDepth(m_Controls->m_Depths->currentText().toInt()); m_Controls->m_Depths->removeItem(indexOfDepthToRemove); if (m_Controls->m_Depths->count() == 0) { m_Controls->m_Depths->setEnabled(false); m_Controls->m_BtnRemoveDepth->setEnabled(false); this->EnableDisableSpacingAndCropping(false); } } } void QmitkUSNewVideoDeviceWidget::OnClickedRemoveProbe() { if (!m_Controls->m_Probes->currentText().isEmpty()) { std::string probename = m_Controls->m_Probes->currentText().toStdString(); int indexOfProbeToRemove = m_Controls->m_Probes->currentIndex(); m_ConfigProbes.erase(m_ConfigProbes.begin() + indexOfProbeToRemove); m_Controls->m_Probes->removeItem(indexOfProbeToRemove); if( m_Controls->m_Probes->count() == 0 ) { m_Controls->m_Probes->setEnabled(false); m_Controls->m_BtnRemoveProbe->setEnabled(false); m_Controls->m_BtnAddDepths->setEnabled(false); m_Controls->m_AddDepths->setEnabled(false); m_Controls->m_Depths->setEnabled(false); m_Controls->m_BtnRemoveDepth->setEnabled(false); this->EnableDisableSpacingAndCropping(false); } } } void QmitkUSNewVideoDeviceWidget::OnProbeChanged(const QString & probename) { if (!probename.isEmpty()) { std::string name = probename.toStdString(); mitk::USProbe::Pointer probe = this->CheckIfProbeExistsAlready(name); if( probe.IsNotNull() ) { std::map depths = probe->GetDepthsAndSpacing(); m_Controls->m_Depths->clear(); for (std::map::iterator it = depths.begin(); it != depths.end(); it++) { m_Controls->m_Depths->addItem(QString::number(it->first)); } this->OnDepthChanged(m_Controls->m_Depths->currentText().toInt(), probe); } } else { m_Controls->m_Depths->clear(); m_Controls->m_Depths->setEnabled(false); m_Controls->m_BtnRemoveDepth->setEnabled(false); } } void QmitkUSNewVideoDeviceWidget::OnDepthChanged(int depth, mitk::USProbe::Pointer probe) { if (m_Controls->m_Depths->count() == 0) { m_Controls->m_Depths->setEnabled(false); m_Controls->m_BtnRemoveDepth->setEnabled(false); this->EnableDisableSpacingAndCropping(false); return; } if (probe.IsNotNull()) { mitk::Vector3D spacing = probe->GetSpacingForGivenDepth(depth); m_Controls->m_XSpacingSpinBox->setValue(spacing[0]); m_Controls->m_YSpacingSpinBox->setValue(spacing[1]); mitk::USProbe::USProbeCropping cropping = probe->GetProbeCropping(); m_Controls->m_CroppingTopSpinBox->setValue(cropping.top); m_Controls->m_CroppingRightSpinBox->setValue(cropping.right); m_Controls->m_CroppingBottomSpinBox->setValue(cropping.bottom); m_Controls->m_CroppingLeftSpinBox->setValue(cropping.left); this->EnableDisableSpacingAndCropping(true); m_Controls->m_Depths->setEnabled(true); m_Controls->m_BtnRemoveDepth->setEnabled(true); m_Controls->m_AddDepths->setEnabled(true); m_Controls->m_BtnAddDepths->setEnabled(true); m_Controls->m_Probes->setEnabled(true); m_Controls->m_BtnRemoveProbe->setEnabled(true); } } void QmitkUSNewVideoDeviceWidget::OnDepthChanged(const QString &depth) { MITK_INFO << "OnDepthChanged(int, mitk::USProbe)"; if( depth.isEmpty() ) { this->EnableDisableSpacingAndCropping(false); return; } QString probeName = m_Controls->m_Probes->currentText(); this->OnDepthChanged(depth.toInt(), this->CheckIfProbeExistsAlready(probeName.toStdString()) ); } void QmitkUSNewVideoDeviceWidget::OnSaveButtonClicked() { QString fileName = QFileDialog::getSaveFileName(nullptr, "Save Configuration ...", "", "XML files (*.xml)"); if( fileName.isNull() ) { return; } // user pressed cancel mitk::USDeviceWriterXML deviceWriter; deviceWriter.SetFilename(fileName.toStdString()); mitk::USDeviceReaderXML::USVideoDeviceConfigData config; this->CollectUltrasoundVideoDeviceConfigInformation(config); if (!deviceWriter.WriteUltrasoundVideoDeviceConfiguration(config)) { QMessageBox msgBox; msgBox.setText("Error when writing the configuration to the selected file. Could not write device information."); msgBox.exec(); return; } } void QmitkUSNewVideoDeviceWidget::OnLoadConfigurationButtonClicked() { QString fileName = QFileDialog::getOpenFileName(this, "Open ultrasound device configuration ..."); if (fileName.isNull()) { return; } // user pressed cancel mitk::USDeviceReaderXML deviceReader; deviceReader.SetFilename(fileName.toStdString()); if (!deviceReader.ReadUltrasoundDeviceConfiguration()) { QMessageBox msgBox; msgBox.setText("Error when parsing the selected file. Could not load stored device information."); msgBox.exec(); return; } mitk::USDeviceReaderXML::USVideoDeviceConfigData config = deviceReader.GetUSVideoDeviceConfigData(); if( config.fileversion == 1.0 ) { if (config.deviceType.compare("video") == 0) { //Fill info in metadata groupbox: m_Controls->m_DeviceName->setText(QString::fromStdString(config.deviceName)); m_Controls->m_Manufacturer->setText(QString::fromStdString(config.manufacturer)); m_Controls->m_Model->setText(QString::fromStdString(config.model)); m_Controls->m_Comment->setText(QString::fromStdString(config.comment)); //Fill info about video source: m_Controls->m_DeviceSelector->setValue(config.sourceID); m_Controls->m_FilePathSelector->setText(QString::fromStdString(config.filepathVideoSource)); //Fill video options: m_Controls->m_CheckGreyscale->setChecked(config.useGreyscale); //Fill override options: m_Controls->m_CheckResolutionOverride->setChecked(config.useResolutionOverride); m_Controls->m_ResolutionWidth->setValue(config.resolutionWidth); m_Controls->m_ResolutionHeight->setValue(config.resolutionHeight); //Fill information about probes: m_ConfigProbes.clear(); m_ConfigProbes = config.probes; m_Controls->m_Probes->clear(); m_Controls->m_ProbeNameLineEdit->clear(); m_Controls->m_AddDepths->clear(); m_Controls->m_Depths->clear(); for( size_t index = 0; index < m_ConfigProbes.size(); ++index) { m_Controls->m_Probes->addItem(QString::fromStdString(config.probes.at(index)->GetName())); } this->OnProbeChanged(m_Controls->m_Probes->currentText()); } else { MITK_WARN << "Unknown device type detected. The device type must be of type |video|"; } } else { MITK_WARN << "Unknown fileversion. Only fileversion 1.0 is known to the system."; } } void QmitkUSNewVideoDeviceWidget::OnAddNewProbeClicked() { QString probeName = m_Controls->m_ProbeNameLineEdit->text(); probeName = probeName.trimmed(); if (probeName.isEmpty()) { m_Controls->m_ProbeNameLineEdit->clear(); return; } if( this->CheckIfProbeExistsAlready(probeName.toStdString() ) != nullptr ) { QMessageBox msgBox; msgBox.setText("Probe name already exists. Please choose another name for the probe."); msgBox.exec(); m_Controls->m_ProbeNameLineEdit->clear(); } else { mitk::USProbe::Pointer newProbe = mitk::USProbe::New(probeName.toStdString()); m_ConfigProbes.push_back(newProbe); m_Controls->m_Probes->addItem(QString::fromStdString(probeName.toStdString())); m_Controls->m_Probes->setEnabled(true); m_Controls->m_BtnRemoveProbe->setEnabled(true); m_Controls->m_BtnAddDepths->setEnabled(true); m_Controls->m_AddDepths->setEnabled(true); m_Controls->m_ProbeNameLineEdit->clear(); } } void QmitkUSNewVideoDeviceWidget::OnXSpacingSpinBoxChanged(double value) { MITK_INFO << "Changing x-spacing to: " << value; QString probeName = m_Controls->m_Probes->currentText(); int depth = m_Controls->m_Depths->currentText().toInt(); mitk::USProbe::Pointer probe = this->CheckIfProbeExistsAlready(probeName.toStdString()); if (probe.IsNull()) { QMessageBox msgBox; msgBox.setText("An error occurred when changing the spacing. \ The specified probe does not exist. \ Please restart the configuration process."); msgBox.exec(); return; } mitk::Vector3D spacing = probe->GetSpacingForGivenDepth(depth); spacing[0] = value; probe->SetSpacingForGivenDepth(depth, spacing); } void QmitkUSNewVideoDeviceWidget::OnYSpacingSpinBoxChanged(double value) { MITK_INFO << "Changing y-spacing to: " << value; QString probeName = m_Controls->m_Probes->currentText(); int depth = m_Controls->m_Depths->currentText().toInt(); mitk::USProbe::Pointer probe = this->CheckIfProbeExistsAlready(probeName.toStdString()); if (probe.IsNull()) { QMessageBox msgBox; msgBox.setText("An error occurred when changing the spacing. \ The specified probe does not exist. \ Please restart the configuration process."); msgBox.exec(); return; } mitk::Vector3D spacing = probe->GetSpacingForGivenDepth(depth); spacing[1] = value; probe->SetSpacingForGivenDepth(depth, spacing); } void QmitkUSNewVideoDeviceWidget::OnCroppingTopSpinBoxChanged(int value) { MITK_INFO << "Changing cropping top to: " << value; QString probeName = m_Controls->m_Probes->currentText(); mitk::USProbe::Pointer probe = this->CheckIfProbeExistsAlready(probeName.toStdString()); if (probe.IsNull()) { QMessageBox msgBox; msgBox.setText("An error occurred when changing the probe cropping. \ The specified probe does not exist. \ Please restart the configuration process."); msgBox.exec(); return; } mitk::USProbe::USProbeCropping cropping = probe->GetProbeCropping(); probe->SetProbeCropping(value, cropping.bottom, cropping.left, cropping.right); } void QmitkUSNewVideoDeviceWidget::OnCroppingRightSpinBoxChanged(int value) { MITK_INFO << "Changing cropping right to: " << value; QString probeName = m_Controls->m_Probes->currentText(); mitk::USProbe::Pointer probe = this->CheckIfProbeExistsAlready(probeName.toStdString()); if (probe.IsNull()) { QMessageBox msgBox; msgBox.setText("An error occurred when changing the probe cropping. \ The specified probe does not exist. \ Please restart the configuration process."); msgBox.exec(); return; } mitk::USProbe::USProbeCropping cropping = probe->GetProbeCropping(); probe->SetProbeCropping(cropping.top, cropping.bottom, cropping.left, value); } void QmitkUSNewVideoDeviceWidget::OnCroppingBottomSpinBoxChanged(int value) { MITK_INFO << "Changing cropping bottom to: " << value; QString probeName = m_Controls->m_Probes->currentText(); mitk::USProbe::Pointer probe = this->CheckIfProbeExistsAlready(probeName.toStdString()); if (probe.IsNull()) { QMessageBox msgBox; msgBox.setText("An error occurred when changing the probe cropping. \ The specified probe does not exist. \ Please restart the configuration process."); msgBox.exec(); return; } mitk::USProbe::USProbeCropping cropping = probe->GetProbeCropping(); probe->SetProbeCropping(cropping.top, value, cropping.left, cropping.right); } void QmitkUSNewVideoDeviceWidget::OnCroppingLeftSpinBoxChanged(int value) { MITK_INFO << "Changing cropping left to: " << value; QString probeName = m_Controls->m_Probes->currentText(); mitk::USProbe::Pointer probe = this->CheckIfProbeExistsAlready(probeName.toStdString()); if (probe.IsNull()) { QMessageBox msgBox; msgBox.setText("An error occurred when changing the probe cropping. \ The specified probe does not exist. \ Please restart the configuration process."); msgBox.exec(); return; } mitk::USProbe::USProbeCropping cropping = probe->GetProbeCropping(); probe->SetProbeCropping(cropping.top, cropping.bottom, value, cropping.right); } void QmitkUSNewVideoDeviceWidget::CleanUpAfterCreatingNewDevice() { disconnect(m_Controls->m_BtnDone, SIGNAL(clicked()), this, SLOT(OnClickedDone())); m_Controls->m_Probes->clear(); m_Controls->m_Depths->clear(); m_Controls->m_AddDepths->clear(); m_Controls->m_ProbeNameLineEdit->clear(); m_ConfigProbes.clear(); } void QmitkUSNewVideoDeviceWidget::CleanUpAfterEditingOfDevice() { disconnect(m_Controls->m_BtnDone, SIGNAL(clicked()), this, SLOT(OnClickedFinishedEditing())); m_Controls->m_Probes->clear(); m_Controls->m_Depths->clear(); m_Controls->m_AddDepths->clear(); m_ConfigProbes.clear(); } -void QmitkUSNewVideoDeviceWidget::AddProbesToDevice(mitk::USVideoDevice::Pointer device) +void QmitkUSNewVideoDeviceWidget::AddProbesToDevice(mitk::USDevice::Pointer device) { device->DeleteAllProbes(); for( std::vector::iterator it = m_ConfigProbes.begin(); it != m_ConfigProbes.end(); it++) { if ((*it)->IsDepthAndSpacingEmpty()) { (*it)->SetDepth(0); } device->AddNewProbe((*it)); } } mitk::USProbe::Pointer QmitkUSNewVideoDeviceWidget::CheckIfProbeExistsAlready(const std::string &probeName) { for( std::vector::iterator it = m_ConfigProbes.begin(); it != m_ConfigProbes.end(); it++ ) { if( probeName.compare((*it)->GetName()) == 0) return (*it); } return nullptr; //no matching probe was found so nullptr is returned } void QmitkUSNewVideoDeviceWidget::CollectUltrasoundVideoDeviceConfigInformation(mitk::USDeviceReaderXML::USVideoDeviceConfigData &config) { config.fileversion = 1.0; config.deviceType = "video"; //Fill info in metadata groupbox: config.deviceName = m_Controls->m_DeviceName->text().toStdString(); config.manufacturer = m_Controls->m_Manufacturer->text().toStdString(); config.model = m_Controls->m_Model->text().toStdString(); config.comment = m_Controls->m_Comment->text().toStdString(); //Fill info about video source: config.sourceID = m_Controls->m_DeviceSelector->value(); config.filepathVideoSource = m_Controls->m_FilePathSelector->text().toStdString(); //Fill video options: config.useGreyscale = m_Controls->m_CheckGreyscale->isChecked(); //Fill override options: config.useResolutionOverride = m_Controls->m_CheckResolutionOverride->isChecked(); config.resolutionWidth = m_Controls->m_ResolutionWidth->value(); config.resolutionHeight = m_Controls->m_ResolutionHeight->value(); //Fill information about probes: config.probes = m_ConfigProbes; } void QmitkUSNewVideoDeviceWidget::EnableDisableSpacingAndCropping(bool enable) { m_Controls->m_XSpacingSpinBox->setEnabled(enable); m_Controls->m_YSpacingSpinBox->setEnabled(enable); m_Controls->m_XSpacingLabel->setEnabled(enable); m_Controls->m_YSpacingLabel->setEnabled(enable); m_Controls->m_CroppingTopSpinBox->setEnabled(enable); m_Controls->m_CroppingRightSpinBox->setEnabled(enable); m_Controls->m_CroppingBottomSpinBox->setEnabled(enable); m_Controls->m_CroppingLeftSpinBox->setEnabled(enable); m_Controls->m_CroppingTopLabel->setEnabled(enable); m_Controls->m_CroppingBottomLabel->setEnabled(enable); m_Controls->m_CroppingLeftLabel->setEnabled(enable); m_Controls->m_CroppingRightLabel->setEnabled(enable); } diff --git a/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidget.h b/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidget.h index 6c7aef6b49..00bfdaf60c 100644 --- a/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidget.h +++ b/Modules/USUI/Qmitk/QmitkUSNewVideoDeviceWidget.h @@ -1,169 +1,169 @@ /*=================================================================== 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 _QmitkUSNewVideoDeviceWidget_H_INCLUDED #define _QmitkUSNewVideoDeviceWidget_H_INCLUDED #include "MitkUSUIExports.h" #include "ui_QmitkUSNewVideoDeviceWidgetControls.h" #include "mitkUSVideoDevice.h" #include "mitkUSIGTLDevice.h" #include "mitkUSDeviceReaderXML.h" //QT headers #include #include //mitk header /** * @brief This Widget enables the USer to create and connect Video Devices. * * @ingroup USUI */ class MITKUSUI_EXPORT QmitkUSNewVideoDeviceWidget :public QWidget { //this is needed for all Qt objects that should have a MOC object (everything that derives from QObject) Q_OBJECT public: static const std::string VIEW_ID; QmitkUSNewVideoDeviceWidget(QWidget* p = nullptr, Qt::WindowFlags f1 = nullptr); ~QmitkUSNewVideoDeviceWidget() override; /* @brief This method is part of the widget an needs not to be called seperately. */ virtual void CreateQtPartControl(QWidget *parent); /* @brief This method is part of the widget an needs not to be called seperately. (Creation of the connections of main and control widget.)*/ virtual void CreateConnections(); signals: void Finished(); public slots: /* \brief Activates the widget and displays the given device's Data to edit. */ void EditDevice(mitk::USDevice::Pointer device); /* \brief Activates the widget with fields empty. */ void CreateNewDevice(); protected slots: /* \brief Called, when the the user clicks the "Done" button (Labeled either "Add Device" or "Edit Device", depending on the situation. */ void OnClickedDone(); void OnClickedFinishedEditing(); /* \brief Called, when the button "Cancel" was clicked */ void OnClickedCancel(); /* \brief Called, when the Use selects one of the Radiobuttons */ void OnDeviceTypeSelection(); void OnOpenFileButtonClicked(); void OnClickedRemoveProbe(); void OnClickedRemoveDepth(); void OnClickedAddDepths(); void OnProbeChanged(const QString & probename); void OnDepthChanged(int depth, mitk::USProbe::Pointer probe); void OnDepthChanged(const QString &depth); void OnSaveButtonClicked(); void OnLoadConfigurationButtonClicked(); void OnAddNewProbeClicked(); void OnXSpacingSpinBoxChanged(double value); void OnYSpacingSpinBoxChanged(double value); void OnCroppingTopSpinBoxChanged(int value); void OnCroppingRightSpinBoxChanged(int value); void OnCroppingBottomSpinBoxChanged(int value); void OnCroppingLeftSpinBoxChanged(int value); protected: Ui::QmitkUSNewVideoDeviceWidgetControls* m_Controls; ///< member holding the UI elements of this widget /* \brief Constructs a ListItem from the given device for display in the list of active devices */ QListWidgetItem* ConstructItemFromDevice(mitk::USDevice::Pointer device); void ChangeUIEditingUSVideoDevice(); void CleanUpAfterEditingOfDevice(); void CleanUpAfterCreatingNewDevice(); - void AddProbesToDevice(mitk::USVideoDevice::Pointer device); + void AddProbesToDevice(mitk::USDevice::Pointer device); mitk::USProbe::Pointer CheckIfProbeExistsAlready(const std::string &probe); void CollectUltrasoundVideoDeviceConfigInformation(mitk::USDeviceReaderXML::USVideoDeviceConfigData &config); /** * \brief Enables or disables the GUI elements of the spacing and cropping options. * \param enable If true: the GUI elements are enabled. If false: elements are disabled. */ void EnableDisableSpacingAndCropping(bool enable); /* \brief Displays whether this widget is active or not. It gets activated by either sending a Signal to * the "CreateNewDevice" Slot or to the "EditDevice" Slot. If the user finishes editing the device, a * "EditingComplete" Signal is sent, and the widget is set to inactive again. Clicking Cancel also * deactivates it. */ bool m_Active; /** * \brief This is the device to edit. It is either the device transmitted in the "EditDevice" signal, or a new one - * if the "CreateNewDevice slot was called. + * if the "CreateNewDevice slot was called. As device type: either mitkUSVideoDevice or mitkUSIGTLDevice */ - mitk::USVideoDevice::Pointer m_TargetDevice; + mitk::USDevice::Pointer m_TargetDevice; /** * \brief The config probes are used to have a possibility to configure ultrasound probes without having an existing * created USVideoDevice yet. */ std::vector m_ConfigProbes; }; #endif // _QmitkUSNewVideoDeviceWidget_H_INCLUDED