diff --git a/Modules/OpenIGTLink/files.cmake b/Modules/OpenIGTLink/files.cmake index c8a685de24..216e1731ad 100644 --- a/Modules/OpenIGTLink/files.cmake +++ b/Modules/OpenIGTLink/files.cmake @@ -1,12 +1,13 @@ set(CPP_FILES mitkIGTLClient.cpp mitkIGTLDevice.cpp mitkIGTLMessageSource.cpp mitkIGTLDeviceSource.cpp mitkIGTLMessage.cpp mitkIGTLMessageCommon.cpp mitkIGTLMessageFactory.cpp mitkIGTLMessageCloneHandler.h mitkIGTLDummyMessage.cpp mitkIGTLMessageQueue.cpp + mitkIGTLMessageProvider.cpp ) diff --git a/Modules/OpenIGTLink/mitkIGTLDeviceSource.cpp b/Modules/OpenIGTLink/mitkIGTLDeviceSource.cpp index bd87f8d381..41954cfb12 100644 --- a/Modules/OpenIGTLink/mitkIGTLDeviceSource.cpp +++ b/Modules/OpenIGTLink/mitkIGTLDeviceSource.cpp @@ -1,180 +1,223 @@ /*=================================================================== 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 "mitkIGTLDeviceSource.h" #include "mitkIGTLDevice.h" #include "mitkIGTLMessage.h" //#include "mitkIGTTimeStamp.h" //#include "mitkIGTException.h" +//Microservices +#include +#include +#include +#include + +//itk +#include + + +const std::string mitk::IGTLDeviceSource::US_PROPKEY_IGTLDEVICENAME = + mitk::IGTLMessageSource::US_INTERFACE_NAME + ".igtldevicename"; + mitk::IGTLDeviceSource::IGTLDeviceSource() : mitk::IGTLMessageSource(), m_IGTLDevice(NULL) { this->SetName("IGTLDeviceSource (no defined type)"); } mitk::IGTLDeviceSource::~IGTLDeviceSource() { if (m_IGTLDevice.IsNotNull()) { if (m_IGTLDevice->GetState() == mitk::IGTLDevice::Running) { this->StopCommunication(); } if (m_IGTLDevice->GetState() == mitk::IGTLDevice::Ready) { this->Disconnect(); } m_IGTLDevice = NULL; } } void mitk::IGTLDeviceSource::GenerateData() { if (m_IGTLDevice.IsNull()) return; /* update output with message from the device */ IGTLMessage* msgOut = this->GetOutput(); assert(msgOut); igtl::MessageBase::Pointer msgIn = m_IGTLDevice->GetLatestMessage(); if ( msgIn.IsNotNull() ) { assert(msgIn); msgOut->SetMessage(msgIn); msgOut->SetName(msgIn->GetDeviceName()); } // else // { // MITK_ERROR("IGTLDeviceSource") << "Could not get the latest message."; // } } void mitk::IGTLDeviceSource::SetIGTLDevice( mitk::IGTLDevice* igtlDevice ) { MITK_DEBUG << "Setting IGTLDevice to " << igtlDevice; if (this->m_IGTLDevice.GetPointer() != igtlDevice) { this->m_IGTLDevice = igtlDevice; this->CreateOutputs(); std::stringstream name; // create a human readable name for the source name << "OIGTL Device Source ( " << igtlDevice->GetName() << " )"; this->SetName(name.str()); + + //setup a observer that listens to new messages + typedef itk::SimpleMemberCommand CurCommandType; + CurCommandType::Pointer messageReceivedCommand = CurCommandType::New(); + messageReceivedCommand->SetCallbackFunction( + this, &IGTLDeviceSource::OnIncomingMessage ); + this->m_IGTLDevice->AddObserver(mitk::MessageReceivedEvent(), + messageReceivedCommand); + } } void mitk::IGTLDeviceSource::CreateOutputs() { //if outputs are set then delete them if (this->GetNumberOfOutputs() > 0) { for (int numOP = this->GetNumberOfOutputs() - 1; numOP >= 0; numOP--) this->RemoveOutput(numOP); this->Modified(); } //fill the outputs if a valid OpenIGTLink device is set if (m_IGTLDevice.IsNull()) return; this->SetNumberOfIndexedOutputs(1); if (this->GetOutput(0) == NULL) { DataObjectPointer newOutput = this->MakeOutput(0); this->SetNthOutput(0, newOutput); this->Modified(); } } void mitk::IGTLDeviceSource::Connect() { if (m_IGTLDevice.IsNull()) { throw std::invalid_argument("mitk::IGTLDeviceSource: " "No OpenIGTLink device set"); } if (this->IsConnected()) { return; } try { m_IGTLDevice->OpenConnection(); } catch (mitk::Exception &e) { throw std::runtime_error(std::string("mitk::IGTLDeviceSource: Could not open" "connection to OpenIGTLink device. Error: ") + e.GetDescription()); } } void mitk::IGTLDeviceSource::StartCommunication() { if (m_IGTLDevice.IsNull()) throw std::invalid_argument("mitk::IGTLDeviceSource: " "No OpenIGTLink device set"); if (m_IGTLDevice->GetState() == mitk::IGTLDevice::Running) return; if (m_IGTLDevice->StartCommunication() == false) throw std::runtime_error("mitk::IGTLDeviceSource: " "Could not start communication"); } void mitk::IGTLDeviceSource::Disconnect() { if (m_IGTLDevice.IsNull()) throw std::invalid_argument("mitk::IGTLDeviceSource: " "No OpenIGTLink device set"); if (m_IGTLDevice->CloseConnection() == false) throw std::runtime_error("mitk::IGTLDeviceSource: Could not close connection" " to OpenIGTLink device"); } void mitk::IGTLDeviceSource::StopCommunication() { if (m_IGTLDevice.IsNull()) throw std::invalid_argument("mitk::IGTLDeviceSource: " "No OpenIGTLink device set"); if (m_IGTLDevice->StopCommunication() == false) throw std::runtime_error("mitk::IGTLDeviceSource: " "Could not stop communicating"); } void mitk::IGTLDeviceSource::UpdateOutputInformation() { this->Modified(); // make sure that we need to be updated Superclass::UpdateOutputInformation(); } bool mitk::IGTLDeviceSource::IsConnected() { if (m_IGTLDevice.IsNull()) return false; return (m_IGTLDevice->GetState() == mitk::IGTLDevice::Ready) || (m_IGTLDevice->GetState() == mitk::IGTLDevice::Running); } bool mitk::IGTLDeviceSource::IsCommunicating() { if (m_IGTLDevice.IsNull()) return false; return m_IGTLDevice->GetState() == mitk::IGTLDevice::Running; } + +void mitk::IGTLDeviceSource::RegisterAsMicroservice() +{ + // Get Context + us::ModuleContext* context = us::GetModuleContext(); + + // Define ServiceProps + us::ServiceProperties props; + mitk::UIDGenerator uidGen = + mitk::UIDGenerator ("org.mitk.services.IGTLDeviceSource.id_", 16); + props[ US_PROPKEY_ID ] = uidGen.GetUID(); + props[ US_PROPKEY_DEVICENAME ] = this->GetName(); + props[ US_PROPKEY_IGTLDEVICENAME ] = m_Name; + m_ServiceRegistration = context->RegisterService(this, props); +} + + +void mitk::IGTLDeviceSource::OnIncomingMessage() +{ + +} diff --git a/Modules/OpenIGTLink/mitkIGTLDeviceSource.h b/Modules/OpenIGTLink/mitkIGTLDeviceSource.h index 3af5cfdbcf..e1f838ba28 100644 --- a/Modules/OpenIGTLink/mitkIGTLDeviceSource.h +++ b/Modules/OpenIGTLink/mitkIGTLDeviceSource.h @@ -1,129 +1,146 @@ /*=================================================================== 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 IGTLDEVICESOURCE_H_HEADER_INCLUDED_ #define IGTLDEVICESOURCE_H_HEADER_INCLUDED_ #include "mitkIGTLDevice.h" #include "mitkIGTLMessageSource.h" namespace mitk { /**Documentation * \brief Connects a mitk::IGTLDevice to a * MITK-OpenIGTLink Message-Filterpipeline * * This class is the source of most OpenIGTLink pipelines. It encapsulates a * mitk::IGTLDevice and provides the information/messages of the connected * OpenIGTLink devices as igtl::MessageBase objects. Note, that there is just * one single output. * */ class MITK_OPENIGTLINK_EXPORT IGTLDeviceSource : public IGTLMessageSource { public: mitkClassMacro(IGTLDeviceSource, IGTLMessageSource); itkFactorylessNewMacro(Self) itkCloneMacro(Self) + /** + *\brief These Constants are used in conjunction with Microservices + */ + static const std::string US_PROPKEY_IGTLDEVICENAME; + /** * \brief sets the OpenIGTLink device that will be used as a data source */ virtual void SetIGTLDevice(mitk::IGTLDevice* td); /** * \brief returns the OpenIGTLink device that is used by this filter */ itkGetObjectMacro(IGTLDevice, mitk::IGTLDevice); + /** + *\brief Registers this object as a Microservice, making it available to every + * module and/or plugin. To unregister, call UnregisterMicroservice(). + */ + virtual void RegisterAsMicroservice(); + /** * \brief Establishes a connection to the OpenIGTLink device. If there is * already a connection the method does nothing. * \warning. Will throw a std::invalid_argument exception if no OpenIGTLink * device was set with SetIGTLDevice(). Will throw a std::runtime_error if * the OpenIGTLink device returns an error. */ void Connect(); /** * \brief Closes the connection to the OpenIGTLink device * \warning. Will throw a std::invalid_argument exception if no OpenIGTLink * device was set with SetIGTLDevice(). Will throw a std::runtime_error if * the OpenIGTLink device returns an error. */ void Disconnect(); /** * \brief starts the communication of the device. * This needs to be called before Update() or GetOutput()->Update(). If the * device is already communicating the method does nothing. * \warning. Will throw a std::invalid_argument exception if no OpenIGTLink * device was set with SetIGTLDevice(). Will throw a std::runtime_error if * the OpenIGTLink device returns an error. */ void StartCommunication(); /** * \brief stops the communication of the device. * \warning. Will throw a std::invalid_argument exception if no OpenIGTLink * device was set with SetIGTLDevice(). Will throw a std::runtime_error if * the OpenIGTLink device returns an error. */ void StopCommunication(); /** * \brief returns true if a connection to the OpenIGTLink device is established * */ virtual bool IsConnected(); /** * \brief returns true if communication is in progress * */ virtual bool IsCommunicating(); /** * \brief Used for pipeline update */ virtual void UpdateOutputInformation(); protected: IGTLDeviceSource(); virtual ~IGTLDeviceSource(); /** * \brief filter execute method * * queries the OpenIGTLink device for new messages and updates its output * igtl::MessageBase objects with it. * \warning Will raise a std::out_of_range exception, if tools were added to * the OpenIGTLink device after it was set as input for this filter */ virtual void GenerateData(); /** * \brief Create the necessary outputs for the m_IGTLDevice * * This Method is called internally whenever outputs need to be reset. Old * Outputs are deleted when called. **/ void CreateOutputs(); + /** + * \brief This method is called when the IGTL device hold by this class + * receives a new message + **/ + virtual void OnIncomingMessage(); + /** the OpenIGTLink device that is used as a source for this filter object*/ mitk::IGTLDevice::Pointer m_IGTLDevice; }; } // namespace mitk #endif /* MITKIGTLDeviceSource_H_HEADER_INCLUDED_ */ diff --git a/Modules/OpenIGTLink/mitkIGTLMessageProvider.cpp b/Modules/OpenIGTLink/mitkIGTLMessageProvider.cpp new file mode 100644 index 0000000000..a8174aab2a --- /dev/null +++ b/Modules/OpenIGTLink/mitkIGTLMessageProvider.cpp @@ -0,0 +1,91 @@ +/*=================================================================== + +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 "mitkIGTLMessageProvider.h" + +#include "mitkIGTLDevice.h" +#include "mitkIGTLMessage.h" + +//#include "mitkIGTTimeStamp.h" +//#include "mitkIGTException.h" + +mitk::IGTLMessageProvider::IGTLMessageProvider() + : mitk::IGTLDeviceSource() +{ + this->SetName("IGTLMessageProvider"); +} + +mitk::IGTLMessageProvider::~IGTLMessageProvider() +{ + +} + +void mitk::IGTLMessageProvider::GenerateData() +{ + if (m_IGTLDevice.IsNull()) + return; + + /* update output with message from the device */ + IGTLMessage* msgOut = this->GetOutput(); + assert(msgOut); + igtl::MessageBase::Pointer msgIn = m_IGTLDevice->GetLatestMessage(); + if ( msgIn.IsNotNull() ) + { + assert(msgIn); + + msgOut->SetMessage(msgIn); + msgOut->SetName(msgIn->GetDeviceName()); + } +} + +void mitk::IGTLMessageProvider::CreateOutputs() +{ + //if outputs are set then delete them + if (this->GetNumberOfOutputs() > 0) + { + for (int numOP = this->GetNumberOfOutputs() - 1; numOP >= 0; numOP--) + this->RemoveOutput(numOP); + this->Modified(); + } + + //fill the outputs if a valid OpenIGTLink device is set + if (m_IGTLDevice.IsNull()) + return; + + this->SetNumberOfIndexedOutputs(1); + if (this->GetOutput(0) == NULL) + { + DataObjectPointer newOutput = this->MakeOutput(0); + this->SetNthOutput(0, newOutput); + this->Modified(); + } +} + +//void mitk::IGTLMessageProvider::UpdateOutputInformation() +//{ +// this->Modified(); // make sure that we need to be updated +// Superclass::UpdateOutputInformation(); +//} + + +void mitk::IGTLMessageProvider::OnIncomingMessage() +{ + //check type of incoming message, it must be a request type (GET_ or STT_) + //otherwise ignore it + //check all microservices if there is a fitting source for the requested type + //if it is a single value return the value + //if it is a stream start streaming +} diff --git a/Modules/OpenIGTLink/mitkIGTLMessageProvider.h b/Modules/OpenIGTLink/mitkIGTLMessageProvider.h new file mode 100644 index 0000000000..0cb4ee11c8 --- /dev/null +++ b/Modules/OpenIGTLink/mitkIGTLMessageProvider.h @@ -0,0 +1,72 @@ +/*=================================================================== + +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 IGTLMESSAGEPROVIDER_H_HEADER_INCLUDED_ +#define IGTLMESSAGEPROVIDER_H_HEADER_INCLUDED_ + +#include "mitkIGTLDevice.h" +#include "mitkIGTLDeviceSource.h" + +namespace mitk { + /**Documentation + * \brief Provides information/objects from a MITK-Pipeline to other OpenIGTLink + * devices + * + * This class is intended as the drain of the pipeline. Other OpenIGTLink + * devices connect with the device hold by this provider. The other device asks + * for a special data. The provider checks if there are other IGTLMessageSources + * available that provide this data type. If yes, they connect with this source + * and send the message to the requesting device. + * + * + */ + class MITK_OPENIGTLINK_EXPORT IGTLMessageProvider : public IGTLDeviceSource + { + public: + mitkClassMacro(IGTLMessageProvider, IGTLDeviceSource); + itkFactorylessNewMacro(Self) + itkCloneMacro(Self) + + protected: + IGTLMessageProvider(); + virtual ~IGTLMessageProvider(); + + /** + * \brief filter execute method + * + * queries the OpenIGTLink device for new messages and updates its output + * igtl::MessageBase objects with it. + * \warning Will raise a std::out_of_range exception, if tools were added to + * the OpenIGTLink device after it was set as input for this filter + */ + virtual void GenerateData(); + + /** + * \brief Create the necessary outputs for the m_IGTLDevice + * + * This Method is called internally whenever outputs need to be reset. Old + * Outputs are deleted when called. + **/ + void CreateOutputs(); + + /** + * \brief This method is called when the IGTL device hold by this class + * receives a new message + **/ + virtual void OnIncomingMessage(); + }; +} // namespace mitk +#endif /* MITKIGTLMESSAGEPROVIDER_H_HEADER_INCLUDED_ */ diff --git a/Modules/OpenIGTLink/mitkIGTLMessageSource.h b/Modules/OpenIGTLink/mitkIGTLMessageSource.h index 95c71f7928..7798328bc1 100644 --- a/Modules/OpenIGTLink/mitkIGTLMessageSource.h +++ b/Modules/OpenIGTLink/mitkIGTLMessageSource.h @@ -1,179 +1,177 @@ /*=================================================================== 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 MITKIGTLMESSAGESOURCE_H_HEADER_INCLUDED_ #define MITKIGTLMESSAGESOURCE_H_HEADER_INCLUDED_ #include #include "mitkPropertyList.h" #include "MitkOpenIGTLinkExports.h" #include "mitkIGTLMessage.h" // Microservices #include #include namespace mitk { /**Documentation * \brief OpenIGTLink message source * * Base class for all OpenIGTLink filters that produce OpenIGTLink message * objects as output. This class defines the output-interface for * OpenIGTLinkMessageFilters. * \warning: if Update() is called on any output object, all IGTLMessage filters * will generate new output data for all outputs, not just the one on which * Update() was called. * */ class MITK_OPENIGTLINK_EXPORT IGTLMessageSource : public itk::ProcessObject { public: mitkClassMacro(IGTLMessageSource, itk::ProcessObject); /** @return Returns a human readable name of this source. There will be a * default name, or you can set the name with the method SetName() if you * want to change it. */ itkGetMacro(Name,std::string); /** @brief Sets the human readable name of this source. There is also a * default name, but you can use this method if you need to define it on your * own. */ itkSetMacro(Name,std::string); /** *\brief return the output (output with id 0) of the filter */ IGTLMessage* GetOutput(void); /** *\brief return the output with id idx of the filter */ IGTLMessage* GetOutput(DataObjectPointerArraySizeType idx); /** *\brief return the output with name messageName of the filter */ IGTLMessage* GetOutput(const std::string& messageName); /** *\brief return the index of the output with name messageName, -1 if no output * with that name was found * * \warning if a subclass has outputs that have different data type than * igtl::MessageBase, they have to overwrite this method */ DataObjectPointerArraySizeType GetOutputIndex(std::string messageName); /** *\brief Registers this object as a Microservice, making it available to every * module and/or plugin. To unregister, call UnregisterMicroservice(). */ virtual void RegisterAsMicroservice(); /** *\brief Registers this object as a Microservice, making it available to every * module and/or plugin. */ virtual void UnRegisterMicroservice(); /** *\brief Returns the id that this device is registered with. The id will only * be valid, if the IGTLMessageSource has been registered using * RegisterAsMicroservice(). */ std::string GetMicroserviceID(); /** *\brief These Constants are used in conjunction with Microservices */ static const std::string US_INTERFACE_NAME; static const std::string US_PROPKEY_DEVICENAME; static const std::string US_PROPKEY_ID; static const std::string US_PROPKEY_ISACTIVE; //NOT IMPLEMENTED YET! /** *\brief Graft the specified DataObject onto this ProcessObject's output. * * See itk::ImageSource::GraftNthOutput for details */ virtual void GraftNthOutput(unsigned int idx, itk::DataObject *graft); /** * \brief Graft the specified DataObject onto this ProcessObject's output. * * See itk::ImageSource::Graft Output for details */ virtual void GraftOutput(itk::DataObject *graft); /** * Allocates a new output object and returns it. Currently the * index idx is not evaluated. * @param idx the index of the output for which an object should be created * @returns the new object */ virtual itk::DataObject::Pointer MakeOutput ( DataObjectPointerArraySizeType idx ); /** * This is a default implementation to make sure we have something. * Once all the subclasses of ProcessObject provide an appopriate * MakeOutput(), then ProcessObject::MakeOutput() can be made pure * virtual. */ virtual itk::DataObject::Pointer MakeOutput(const DataObjectIdentifierType &name); /** * \brief Set all filter parameters as the PropertyList p * * This method allows to set all parameters of a filter with one * method call. For the names of the parameters, take a look at * the GetParameters method of the filter * This method has to be overwritten by each MITK-IGT filter. */ virtual void SetParameters(const mitk::PropertyList*){}; /** * \brief Get all filter parameters as a PropertyList * * This method allows to get all parameters of a filter with one * method call. The returned PropertyList must be assigned to a * SmartPointer immediately, or else it will get destroyed. * Every filter must overwrite this method to create a filter-specific * PropertyList. Note that property names must be unique over all * MITK-IGT filters. Therefore each filter should use its name as a prefix * for each property name. * Secondly, each filter should list the property names and data types * in the method documentation. */ virtual mitk::PropertyList::ConstPointer GetParameters() const; protected: IGTLMessageSource(); virtual ~IGTLMessageSource(); std::string m_Name; - - private: us::ServiceRegistration m_ServiceRegistration; }; } // namespace mitk // This is the microservice declaration. Do not meddle! MITK_DECLARE_SERVICE_INTERFACE(mitk::IGTLMessageSource, "org.mitk.services.IGTLMessageSource") #endif /* MITKIGTLMESSAGESOURCE_H_HEADER_INCLUDED_ */ diff --git a/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLDeviceSourceManagementWidget.cpp b/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLDeviceSourceManagementWidget.cpp index 58d133d10c..ab72e78063 100644 --- a/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLDeviceSourceManagementWidget.cpp +++ b/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLDeviceSourceManagementWidget.cpp @@ -1,557 +1,549 @@ /*=================================================================== 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 "QmitkIGTLDeviceSourceManagementWidget.h" //mitk headers #include #include #include #include //qt headers #include #include #include #include //igtl #include //poco headers #include const std::string QmitkIGTLDeviceSourceManagementWidget::VIEW_ID = "org.mitk.views.igtldevicesourcemanagementwidget"; QmitkIGTLDeviceSourceManagementWidget::QmitkIGTLDeviceSourceManagementWidget( QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f), m_OutputChanged(false) { m_Controls = NULL; m_OutputMutex = itk::FastMutexLock::New(); CreateQtPartControl(this); } QmitkIGTLDeviceSourceManagementWidget::~QmitkIGTLDeviceSourceManagementWidget() { } void QmitkIGTLDeviceSourceManagementWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkIGTLDeviceSourceManagementWidgetControls; // setup GUI widgets m_Controls->setupUi(parent); } //every 100ms the logging window has to be updated m_UpdateLoggingWindowTimer.setInterval(100); // set the validator for the ip edit box (values must be between 0 and 255 and // there are four of them, seperated with a point QRegExpValidator *v = new QRegExpValidator(this); QRegExp rx("((1{0,1}[0-9]{0,2}|2[0-4]{1,1}[0-9]{1,1}|25[0-5]{1,1})\\.){3,3}(1{0,1}[0-9]{0,2}|2[0-4]{1,1}[0-9]{1,1}|25[0-5]{1,1})"); v->setRegExp(rx); m_Controls->editIP->setValidator(v); // set the validator for the port edit box (values must be between 1 and 65535) m_Controls->editPort->setValidator(new QIntValidator(1, 65535, this)); //connect slots with signals CreateConnections(); } void QmitkIGTLDeviceSourceManagementWidget::CreateConnections() { if (m_Controls) { // connect the widget items with the methods connect( m_Controls->butConnectWithServer, SIGNAL(clicked()), this, SLOT(OnConnect())); connect( m_Controls->editPort, SIGNAL(editingFinished()), this, SLOT(OnPortChanged()) ); connect( m_Controls->editIP, SIGNAL(editingFinished()), this, SLOT(OnHostnameChanged()) ); connect( m_Controls->butSend, SIGNAL(clicked()), this, SLOT(OnSendMessage())); connect( m_Controls->butSendCommand, SIGNAL(clicked()), this, SLOT(OnSendCommand())); connect( m_Controls->commandsComboBox, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(OnCommandChanged(const QString &))); connect( &m_UpdateLoggingWindowTimer, SIGNAL(timeout()), this, SLOT(OnUpdateLoggingWindow())); } // //main widget page: // connect( (QObject*)(m_Controls->m_AddTool), SIGNAL(clicked()), this, SLOT(OnAddTool()) ); // connect( (QObject*)(m_Controls->m_DeleteTool), SIGNAL(clicked()), this, SLOT(OnDeleteTool()) ); // connect( (QObject*)(m_Controls->m_EditTool), SIGNAL(clicked()), this, SLOT(OnEditTool()) ); // connect( (QObject*)(m_Controls->m_LoadStorage), SIGNAL(clicked()), this, SLOT(OnLoadStorage()) ); // connect( (QObject*)(m_Controls->m_SaveStorage), SIGNAL(clicked()), this, SLOT(OnSaveStorage()) ); // connect( (QObject*)(m_Controls->m_LoadTool), SIGNAL(clicked()), this, SLOT(OnLoadTool()) ); // connect( (QObject*)(m_Controls->m_SaveTool), SIGNAL(clicked()), this, SLOT(OnSaveTool()) ); // connect( (QObject*)(m_Controls->m_CreateNewStorage), SIGNAL(clicked()), this, SLOT(OnCreateStorage()) ); // //widget page "add tool": // connect( (QObject*)(m_Controls->m_ToolCreationWidget), SIGNAL(Canceled()), this, SLOT(OnAddToolCancel()) ); // connect( (QObject*)(m_Controls->m_ToolCreationWidget), SIGNAL(NavigationToolFinished()), this, SLOT(OnAddToolSave()) ); } //void QmitkIGTLDeviceSourceManagementWidget::OnLoadTool() //{ // if(m_IGTLDeviceSource->isLocked()) // { // MessageBox("Storage is locked, cannot modify it. Maybe the tracking device which uses this storage is connected. If you want to modify the storage please disconnect the device first."); // return; // } // mitk::NavigationToolReader::Pointer myReader = mitk::NavigationToolReader::New(); // std::string filename = QFileDialog::getOpenFileName(NULL,tr("Add Navigation Tool"), "/", "*.IGTTool").toAscii().data(); // if (filename == "") return; // mitk::NavigationTool::Pointer readTool = myReader->DoRead(filename); // if (readTool.IsNull()) MessageBox("Error: " + myReader->GetErrorMessage()); // else // { // if (!m_IGTLDeviceSource->AddTool(readTool)) // { // MessageBox("Error: Can't add tool!"); // m_DataStorage->Remove(readTool->GetDataNode()); // } // UpdateToolTable(); // } //} //void QmitkIGTLDeviceSourceManagementWidget::OnSaveTool() //{ // //if no item is selected, show error message: // if (m_Controls->m_ToolList->currentItem() == NULL) {MessageBox("Error: Please select tool first!");return;} // mitk::NavigationToolWriter::Pointer myWriter = mitk::NavigationToolWriter::New(); // std::string filename = QFileDialog::getSaveFileName(NULL,tr("Save Navigation Tool"), "/", "*.IGTTool").toAscii().data(); // if (filename == "") return; // if (!myWriter->DoWrite(filename,m_IGTLDeviceSource->GetTool(m_Controls->m_ToolList->currentIndex().row()))) // MessageBox("Error: "+ myWriter->GetErrorMessage()); //} void QmitkIGTLDeviceSourceManagementWidget::Initialize( mitk::DataStorage* /*dataStorage*/) { // m_DataStorage = dataStorage; // m_Controls->m_ToolCreationWidget->Initialize(m_DataStorage,"Tool0"); } void QmitkIGTLDeviceSourceManagementWidget::LoadSource( mitk::IGTLDeviceSource::Pointer sourceToLoad) { if(sourceToLoad.IsNotNull()) { this->m_IGTLDeviceSource = sourceToLoad; this->m_IGTLClient = (mitk::IGTLClient*)this->m_IGTLDeviceSource->GetIGTLDevice(); m_Controls->selectedSourceLabel->setText(m_IGTLDeviceSource->GetName().c_str()); //add observer for new message receiving // typedef itk::MemberCommand< QmitkIGTLDeviceSourceManagementWidget > CurCommandType; // CurCommandType::Pointer messageReceivedCommand = CurCommandType::New(); // messageReceivedCommand->SetCallbackFunction( // this, &QmitkIGTLDeviceSourceManagementWidget::OnMessageReceived ); // this->m_IGTLClient->AddObserver(mitk::MessageReceivedEvent(), messageReceivedCommand); typedef itk::MemberCommand< QmitkIGTLDeviceSourceManagementWidget > CurCommandType; m_MessageReceivedCommand = CurCommandType::New(); m_MessageReceivedCommand->SetCallbackFunction( this, &QmitkIGTLDeviceSourceManagementWidget::OnMessageReceived ); this->m_IGTLClient->AddObserver(mitk::MessageReceivedEvent(), m_MessageReceivedCommand); //Fill the commands combo box with all available commands FillCommandsComboBox(); //enable the controls of this widget EnableSourceControls(); //start to update the logging window this->m_UpdateLoggingWindowTimer.start(); } else { m_IGTLDeviceSource = NULL; DisableSourceControls(); } //reset the loggin text edit ResetOutput(); } ////################################################################################## ////############################## slots: main widget ################################ ////################################################################################## //void QmitkIGTLDeviceSourceManagementWidget::OnAddTool() // { // if(m_IGTLDeviceSource->isLocked()) // { // MessageBox("Storage is locked, cannot modify it. Maybe the tracking device which uses this storage is connected. If you want to modify the storage please disconnect the device first."); // return; // } // QString defaultIdentifier = "NavigationTool#"+QString::number(m_IGTLDeviceSource->GetToolCount()); // m_Controls->m_ToolCreationWidget->Initialize(m_DataStorage,defaultIdentifier.toStdString()); // m_edit = false; // m_Controls->m_MainWidgets->setCurrentIndex(1); // } //void QmitkIGTLDeviceSourceManagementWidget::OnDeleteTool() // { // //first: some checks // if(m_IGTLDeviceSource->isLocked()) // { // MessageBox("Storage is locked, cannot modify it. Maybe the tracking device which uses this storage is connected. If you want to modify the storage please disconnect the device first."); // return; // } // else if (m_Controls->m_ToolList->currentItem() == NULL) //if no item is selected, show error message: // { // MessageBox("Error: Please select tool first!"); // return; // } // m_DataStorage->Remove(m_IGTLDeviceSource->GetTool(m_Controls->m_ToolList->currentIndex().row())->GetDataNode()); // m_IGTLDeviceSource->DeleteTool(m_Controls->m_ToolList->currentIndex().row()); // UpdateToolTable(); // } //void QmitkIGTLDeviceSourceManagementWidget::OnEditTool() // { // if(m_IGTLDeviceSource->isLocked()) // { // MessageBox("Storage is locked, cannot modify it. Maybe the tracking device which uses this storage is connected. If you want to modify the storage please disconnect the device first."); // return; // } // else if (m_Controls->m_ToolList->currentItem() == NULL) //if no item is selected, show error message: // { // MessageBox("Error: Please select tool first!"); // return; // } // mitk::NavigationTool::Pointer selectedTool = m_IGTLDeviceSource->GetTool(m_Controls->m_ToolList->currentIndex().row()); // m_Controls->m_ToolCreationWidget->SetDefaultData(selectedTool); // m_edit = true; // m_Controls->m_MainWidgets->setCurrentIndex(1); // } //void QmitkIGTLDeviceSourceManagementWidget::OnCreateStorage() // { // QString storageName = QInputDialog::getText(NULL,"Storage Name","Name of the new tool storage:"); // if (storageName.isNull()) return; // m_IGTLDeviceSource = mitk::NavigationToolStorage::New(this->m_DataStorage); // m_IGTLDeviceSource->SetName(storageName.toStdString()); // m_Controls->m_StorageName->setText(m_IGTLDeviceSource->GetName().c_str()); // EnableStorageControls(); // emit NewStorageAdded(m_IGTLDeviceSource, storageName.toStdString()); // } //void QmitkIGTLDeviceSourceManagementWidget::OnLoadStorage() // { // mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(m_DataStorage); // std::string filename = QFileDialog::getOpenFileName(NULL, tr("Open Navigation Tool Storage"), "/", tr("IGT Tool Storage (*.IGTToolStorage)")).toStdString(); // if (filename == "") return; // try // { // mitk::NavigationToolStorage::Pointer tempStorage = myDeserializer->Deserialize(filename); // if (tempStorage.IsNull()) MessageBox("Error" + myDeserializer->GetErrorMessage()); // else // { // Poco::Path myPath = Poco::Path(filename.c_str()); // tempStorage->SetName(myPath.getFileName()); //set the filename as name for the storage, so the user can identify it // this->LoadStorage(tempStorage); // emit NewStorageAdded(m_IGTLDeviceSource,myPath.getFileName()); // } // } // catch (const mitk::Exception& exception) // { // MessageBox(exception.GetDescription()); // } // } //void QmitkIGTLDeviceSourceManagementWidget::OnSaveStorage() // { // //read in filename // QString filename = QFileDialog::getSaveFileName(NULL, tr("Save Navigation Tool Storage"), "/", tr("IGT Tool Storage (*.IGTToolStorage)")); // if (filename.isEmpty()) return; //canceled by the user // // add file extension if it wasn't added by the file dialog // if ( filename.right(15) != ".IGTToolStorage" ) { filename += ".IGTToolStorage"; } // //serialize tool storage // mitk::NavigationToolStorageSerializer::Pointer mySerializer = mitk::NavigationToolStorageSerializer::New(); // if (!mySerializer->Serialize(filename.toStdString(),m_IGTLDeviceSource)) // { // MessageBox("Error: " + mySerializer->GetErrorMessage()); // return; // } // Poco::Path myPath = Poco::Path(filename.toStdString()); // m_Controls->m_StorageName->setText(QString::fromStdString(myPath.getFileName())); // } ////################################################################################## ////############################## slots: add tool widget ############################ ////################################################################################## //void QmitkIGTLDeviceSourceManagementWidget::OnAddToolSave() // { // mitk::NavigationTool::Pointer newTool = m_Controls->m_ToolCreationWidget->GetCreatedTool(); // if (m_edit) //here we edit a existing tool // { // mitk::NavigationTool::Pointer editedTool = m_IGTLDeviceSource->GetTool(m_Controls->m_ToolList->currentIndex().row()); // editedTool->Graft(newTool); // } // else //here we create a new tool // { // m_IGTLDeviceSource->AddTool(newTool); // } // UpdateToolTable(); // m_Controls->m_MainWidgets->setCurrentIndex(0); // } //void QmitkIGTLDeviceSourceManagementWidget::OnAddToolCancel() // { // m_Controls->m_MainWidgets->setCurrentIndex(0); // } void QmitkIGTLDeviceSourceManagementWidget::MessageBox(std::string s) { QMessageBox msgBox; msgBox.setText(s.c_str()); msgBox.exec(); } void QmitkIGTLDeviceSourceManagementWidget::DisableSourceControls() { m_Controls->selectedSourceLabel->setText(""); m_Controls->editIP->setEnabled(false); m_Controls->editPort->setEnabled(false); m_Controls->editSend->setEnabled(false); m_Controls->butSendCommand->setEnabled(false); // m_Controls->m_AddTool->setEnabled(false); // m_Controls->m_LoadTool->setEnabled(false); // m_Controls->m_selectedLabel->setEnabled(false); // m_Controls->m_DeleteTool->setEnabled(false); // m_Controls->m_EditTool->setEnabled(false); // m_Controls->m_SaveTool->setEnabled(false); // m_Controls->m_ToolList->setEnabled(false); // m_Controls->m_SaveStorage->setEnabled(false); // m_Controls->m_ToolLabel->setEnabled(false); } void QmitkIGTLDeviceSourceManagementWidget::EnableSourceControls() { m_Controls->editIP->setEnabled(true); m_Controls->editPort->setEnabled(true); m_Controls->butConnectWithServer->setEnabled(true); // m_Controls->editSend->setEnabled(false); // m_Controls->m_AddTool->setEnabled(true); // m_Controls->m_LoadTool->setEnabled(true); // m_Controls->m_selectedLabel->setEnabled(true); // m_Controls->m_DeleteTool->setEnabled(true); // m_Controls->m_EditTool->setEnabled(true); // m_Controls->m_SaveTool->setEnabled(true); // m_Controls->m_ToolList->setEnabled(true); // m_Controls->m_SaveStorage->setEnabled(true); // m_Controls->m_ToolLabel->setEnabled(true); } void QmitkIGTLDeviceSourceManagementWidget::OnConnect() { if(m_Controls->butConnectWithServer->text() == "Connect") { QString port = m_Controls->editPort->text(); m_IGTLClient->SetPortNumber(port.toInt()); std::string hostname = m_Controls->editIP->text().toStdString(); m_IGTLClient->SetHostname(hostname); if ( m_IGTLClient->OpenConnection() ) { if ( m_IGTLClient->StartCommunication() ) { this->m_Controls->editIP->setEnabled(false); this->m_Controls->editPort->setEnabled(false); this->m_Controls->editSend->setEnabled(true); this->m_Controls->butSend->setEnabled(true); this->m_Controls->commandsComboBox->setEnabled(true); this->m_Controls->butSendCommand->setEnabled(true); this->m_Controls->butConnectWithServer->setText("Disconnect"); std::stringstream s; s << "
Successfully connected to " << hostname << " on port " << port.toStdString(); this->AddOutput(s.str()); } else { MITK_ERROR("QmitkIGTLDeviceSourceManagementWidget") << "Could not start a communication with the" "server because the client is in the wrong state"; this->AddOutput("
Connection is not working."); } } else { MITK_ERROR("QmitkIGTLDeviceSourceManagementWidget") << "Could not connect to the server. " "Please check the hostname and port."; this->AddOutput("
Connection is not working. Please Check Host and Port."); } } else { m_Controls->editIP->setEnabled(true); m_Controls->editPort->setEnabled(true); m_Controls->editSend->setEnabled(false); m_Controls->butSend->setEnabled(false); m_Controls->butSendCommand->setEnabled(false); m_Controls->commandsComboBox->setEnabled(false); m_Controls->butConnectWithServer->setText("Connect"); m_IGTLClient->CloseConnection(); this->AddOutput("
Closed connection."); } } void QmitkIGTLDeviceSourceManagementWidget::OnPortChanged() { } void QmitkIGTLDeviceSourceManagementWidget::OnHostnameChanged() { } void QmitkIGTLDeviceSourceManagementWidget::OnSendCommand() { m_IGTLClient->SendMessage(m_CurrentCommand.GetPointer()); std::stringstream s; s << "
Sent command with DeviceType: " << m_CurrentCommand->GetDeviceType(); this->AddOutput(s.str()); } void QmitkIGTLDeviceSourceManagementWidget::OnCommandChanged( const QString & curCommand) { mitk::IGTLMessageFactory::Pointer msgFactory = this->m_IGTLClient->GetMessageFactory(); //create a new message that fits to the selected get message type command this->m_CurrentCommand = msgFactory->GetMessageTypeNewPointer( curCommand.toStdString())(); } void QmitkIGTLDeviceSourceManagementWidget::OnSendMessage() { std::string toBeSend = m_Controls->editSend->text().toStdString(); igtl::StringMessage::Pointer msg = igtl::StringMessage::New().GetPointer(); msg->SetString(toBeSend); m_IGTLClient->SendMessage(msg.GetPointer()); std::stringstream s; s << "
Sent message with DeviceType: " << msg->GetDeviceType(); this->AddOutput(s.str()); -// if ( m_IGTLClient->SendMessage(msg.GetPointer()) ) -// { -// MITK_INFO("OpenIGTLinkExample") << "Successfully sent the message."; -// } -// else -// { -// MITK_ERROR("OpenIGTLinkExample") << "Could not send the message."; -// } } void QmitkIGTLDeviceSourceManagementWidget::OnMessageReceived(itk::Object* caller, const itk::EventObject&/*event*/) { //get the IGTL device that invoked this event mitk::IGTLDevice* dev = (mitk::IGTLDevice*)caller; std::stringstream s; s << "
Received a message:
" << dev->GetOldestMessageInformation(); this->AddOutput(s.str()); } void QmitkIGTLDeviceSourceManagementWidget::OnUpdateLoggingWindow() { m_OutputMutex->Lock(); // m_Controls->m_Logging->setHtml(QString(m_Output.str().c_str())); // m_Controls->m_Logging->update(); if ( m_OutputChanged ) { m_Controls->m_Logging->setText(QString(m_Output.str().c_str())); QScrollBar* sb = m_Controls->m_Logging->verticalScrollBar(); sb->setValue(sb->maximum()); m_OutputChanged = false; } m_OutputMutex->Unlock(); } void QmitkIGTLDeviceSourceManagementWidget::FillCommandsComboBox() { //load the msg factory from the client (maybe this will be moved later on) mitk::IGTLMessageFactory::Pointer msgFactory = this->m_IGTLClient->GetMessageFactory(); //get the available commands as std::list std::list commandsList_ = msgFactory->GetAvailableMessageRequestTypes(); //create a string list to convert the std::list QStringList commandsList; while ( commandsList_.size() ) { commandsList.append(QString::fromStdString(commandsList_.front())); commandsList_.pop_front(); } //fill the combo box with life this->m_Controls->commandsComboBox->addItems(commandsList); } void QmitkIGTLDeviceSourceManagementWidget::ResetOutput() { m_OutputMutex->Lock(); m_Output.str(""); m_Output <<"output:"; m_Controls->m_Logging->setHtml(QString(m_Output.str().c_str())); m_OutputMutex->Unlock(); } void QmitkIGTLDeviceSourceManagementWidget::AddOutput(std::string s) { //print output m_OutputMutex->Lock(); m_Output << s; m_OutputChanged = true; m_OutputMutex->Unlock(); } diff --git a/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLDeviceSourceSelectionWidget.cpp b/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLDeviceSourceSelectionWidget.cpp index 80a6c97c55..13a6df754d 100644 --- a/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLDeviceSourceSelectionWidget.cpp +++ b/Modules/OpenIGTLinkUI/Qmitk/QmitkIGTLDeviceSourceSelectionWidget.cpp @@ -1,86 +1,86 @@ /*=================================================================== 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 "QmitkIGTLDeviceSourceSelectionWidget.h" //mitk headers #include #include QmitkIGTLDeviceSourceSelectionWidget::QmitkIGTLDeviceSourceSelectionWidget(QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f) { m_Controls = NULL; CreateQtPartControl(this); } QmitkIGTLDeviceSourceSelectionWidget::~QmitkIGTLDeviceSourceSelectionWidget() { } void QmitkIGTLDeviceSourceSelectionWidget::CreateQtPartControl(QWidget *parent) { if ( !m_Controls ) { // create GUI widgets m_Controls = new Ui::QmitkIGTLDeviceSourceSelectionWidgetControls; // setup GUI widgets m_Controls->setupUi(parent); } CreateConnections(); } void QmitkIGTLDeviceSourceSelectionWidget::CreateConnections() { if ( m_Controls ) { connect( m_Controls->m_ServiceListWidget, SIGNAL(ServiceSelectionChanged(us::ServiceReferenceU)), this, SLOT(IGTLDeviceSourceSelected(us::ServiceReferenceU)) ); //initialize service list widget std::string empty = ""; - m_Controls->m_ServiceListWidget->Initialize( - mitk::IGTLMessageSource::US_PROPKEY_DEVICENAME,empty); + m_Controls->m_ServiceListWidget->Initialize( + mitk::IGTLDeviceSource::US_PROPKEY_IGTLDEVICENAME,empty); } } void QmitkIGTLDeviceSourceSelectionWidget::IGTLDeviceSourceSelected(us::ServiceReferenceU s) { if (!s) //nothing selected { //reset everything this->m_CurrentIGTLDeviceSource = NULL; emit IGTLDeviceSourceSelected(this->m_CurrentIGTLDeviceSource); return; } // Get storage us::ModuleContext* context = us::GetModuleContext(); this->m_CurrentIGTLDeviceSource = - (mitk::IGTLDeviceSource*)context->GetService(s); + context->GetService(s); emit IGTLDeviceSourceSelected(this->m_CurrentIGTLDeviceSource); } mitk::IGTLDeviceSource::Pointer QmitkIGTLDeviceSourceSelectionWidget::GetSelectedIGTLDeviceSource() { return this->m_CurrentIGTLDeviceSource; }