diff --git a/Core/Code/DataManagement/mitkPropertyList.cpp b/Core/Code/DataManagement/mitkPropertyList.cpp index dea0cbf441..5b69877899 100644 --- a/Core/Code/DataManagement/mitkPropertyList.cpp +++ b/Core/Code/DataManagement/mitkPropertyList.cpp @@ -1,285 +1,358 @@ /*=================================================================== 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 "mitkPropertyList.h" #include "mitkProperties.h" #include "mitkStringProperty.h" #include "mitkVector.h" mitk::BaseProperty* mitk::PropertyList::GetProperty(const std::string& propertyKey) const { PropertyMap::const_iterator it; it=m_Properties.find( propertyKey ); if(it!=m_Properties.end()) return it->second; else return NULL; } void mitk::PropertyList::SetProperty(const std::string& propertyKey, BaseProperty* property) { if (!property) return; //make sure that BaseProperty*, which may have just been created and never been //assigned to a SmartPointer, is registered/unregistered properly. If we do not //do that, it will a) not deleted in case it is identical to the old one or //b) possibly deleted when temporarily added to a smartpointer somewhere below. BaseProperty::Pointer tmpSmartPointerToProperty = property; PropertyMap::iterator it( m_Properties.find( propertyKey ) ); // Is a property with key @a propertyKey contained in the list? if( it != m_Properties.end() ) { // yes //is the property contained in the list identical to the new one? if( it->second->operator==(*property) ) { // yes? do nothing and return. return; } if (it->second->AssignProperty(*property)) { // The assignment was successfull this->Modified(); } else { MITK_ERROR << "In " __FILE__ ", l." << __LINE__ << ": Trying to set existing property " << it->first << " of type " << it->second->GetNameOfClass() << " to a property with different type " << property->GetNameOfClass() << "." << " Use ReplaceProperty() instead." << std::endl; } return; } //no? add it. PropertyMapElementType newProp; newProp.first = propertyKey; newProp.second = property; m_Properties.insert ( newProp ); this->Modified(); } void mitk::PropertyList::ReplaceProperty(const std::string& propertyKey, BaseProperty* property) { if (!property) return; PropertyMap::iterator it( m_Properties.find( propertyKey ) ); // Is a property with key @a propertyKey contained in the list? if( it != m_Properties.end() ) { it->second=NULL; m_Properties.erase(it); } //no? add/replace it. PropertyMapElementType newProp; newProp.first = propertyKey; newProp.second = property; m_Properties.insert ( newProp ); Modified(); } mitk::PropertyList::PropertyList() { } mitk::PropertyList::PropertyList(const mitk::PropertyList& other) : itk::Object() { for (PropertyMap::const_iterator i = other.m_Properties.begin(); i != other.m_Properties.end(); ++i) { m_Properties.insert(std::make_pair(i->first, i->second->Clone())); } } mitk::PropertyList::~PropertyList() { Clear(); } /** * Consider the list as changed when any of the properties has changed recently. */ unsigned long mitk::PropertyList::GetMTime() const { for ( PropertyMap::const_iterator it = m_Properties.begin() ; it != m_Properties.end(); ++it ) { if( it->second.IsNull() ) { itkWarningMacro(<< "Property '" << it->first <<"' contains nothing (NULL)."); continue; } if( Superclass::GetMTime() < it->second->GetMTime() ) { Modified(); break; } } return Superclass::GetMTime(); } bool mitk::PropertyList::DeleteProperty(const std::string& propertyKey) { PropertyMap::iterator it; it=m_Properties.find( propertyKey ); if(it!=m_Properties.end()) { it->second=NULL; m_Properties.erase(it); Modified(); return true; } return false; } void mitk::PropertyList::Clear() { PropertyMap::iterator it = m_Properties.begin(), end = m_Properties.end(); while(it!=end) { it->second = NULL; ++it; } m_Properties.clear(); } itk::LightObject::Pointer mitk::PropertyList::InternalClone() const { itk::LightObject::Pointer result(new Self(*this)); result->UnRegister(); return result; } void mitk::PropertyList::ConcatenatePropertyList(PropertyList *pList, bool replace) { if (pList) { const PropertyMap* propertyMap = pList->GetMap(); for ( PropertyMap::const_iterator iter = propertyMap->begin(); // m_PropertyList is created in the constructor, so we don't check it here iter != propertyMap->end(); ++iter ) { const std::string key = iter->first; BaseProperty* value = iter->second; if (replace) { ReplaceProperty( key.c_str(), value ); } else { SetProperty( key.c_str(), value ); } } } } bool mitk::PropertyList::GetBoolProperty(const char* propertyKey, bool& boolValue) const { BoolProperty *gp = dynamic_cast( GetProperty(propertyKey) ); if ( gp != NULL ) { boolValue = gp->GetValue(); return true; } return false; // Templated Method does not work on Macs //return GetPropertyValue(propertyKey, boolValue); } bool mitk::PropertyList::GetIntProperty(const char* propertyKey, int &intValue) const { IntProperty *gp = dynamic_cast( GetProperty(propertyKey) ); if ( gp != NULL ) { intValue = gp->GetValue(); return true; } return false; // Templated Method does not work on Macs //return GetPropertyValue(propertyKey, intValue); } bool mitk::PropertyList::GetFloatProperty(const char* propertyKey, float &floatValue) const { FloatProperty *gp = dynamic_cast( GetProperty(propertyKey) ); if ( gp != NULL ) { floatValue = gp->GetValue(); return true; } return false; // Templated Method does not work on Macs //return GetPropertyValue(propertyKey, floatValue); } bool mitk::PropertyList::GetStringProperty(const char* propertyKey, std::string& stringValue) const { StringProperty* sp= dynamic_cast(GetProperty(propertyKey)); if ( sp != NULL ) { stringValue = sp->GetValue(); return true; } return false; } void mitk::PropertyList::SetIntProperty(const char* propertyKey, int intValue) { SetProperty(propertyKey, mitk::IntProperty::New(intValue)); } void mitk::PropertyList::SetBoolProperty( const char* propertyKey, bool boolValue) { SetProperty(propertyKey, mitk::BoolProperty::New(boolValue)); } void mitk::PropertyList::SetFloatProperty( const char* propertyKey, float floatValue) { SetProperty(propertyKey, mitk::FloatProperty::New(floatValue)); } void mitk::PropertyList::SetStringProperty( const char* propertyKey, const char* stringValue) { SetProperty(propertyKey, mitk::StringProperty::New(stringValue)); } + +void mitk::PropertyList::Set( const char* propertyKey, bool boolValue ) +{ + this->SetBoolProperty( propertyKey, boolValue ); +} + +void mitk::PropertyList::Set( const char* propertyKey, int intValue ) +{ + this->SetIntProperty(propertyKey, intValue); +} + +void mitk::PropertyList::Set( const char* propertyKey, float floatValue ) +{ + this->SetFloatProperty(propertyKey, floatValue); +} + +void mitk::PropertyList::Set( const char* propertyKey, double doubleValue ) +{ + this->SetDoubleProperty(propertyKey, doubleValue); +} + +void mitk::PropertyList::Set( const char* propertyKey, const char* stringValue ) +{ + this->SetStringProperty(propertyKey, stringValue); +} + +void mitk::PropertyList::Set( const char* propertyKey, const std::string& stringValue ) +{ + this->SetStringProperty(propertyKey, stringValue.c_str()); + +} + +bool mitk::PropertyList::Get( const char* propertyKey, bool& boolValue ) const +{ + return this->GetBoolProperty( propertyKey, boolValue ); +} + +bool mitk::PropertyList::Get( const char* propertyKey, int &intValue ) const +{ + return this->GetIntProperty(propertyKey, intValue); +} + +bool mitk::PropertyList::Get( const char* propertyKey, float &floatValue ) const +{ + return this->GetFloatProperty( propertyKey, floatValue ); +} + +bool mitk::PropertyList::Get( const char* propertyKey, double &doubleValue ) const +{ + return this->GetDoubleProperty( propertyKey, doubleValue ); +} + +bool mitk::PropertyList::Get( const char* propertyKey, std::string& stringValue ) const +{ + return this->GetStringProperty( propertyKey, stringValue ); +} + +bool mitk::PropertyList::GetDoubleProperty( const char* propertyKey, double &doubleValue ) const +{ + DoubleProperty *gp = dynamic_cast( GetProperty(propertyKey) ); + if ( gp != NULL ) + { + doubleValue = gp->GetValue(); + return true; + } + return false; + +} + +void mitk::PropertyList::SetDoubleProperty( const char* propertyKey, double doubleValue ) +{ + SetProperty(propertyKey, mitk::DoubleProperty::New(doubleValue)); +} diff --git a/Core/Code/DataManagement/mitkPropertyList.h b/Core/Code/DataManagement/mitkPropertyList.h index 233fd52e79..0a1aef58cb 100644 --- a/Core/Code/DataManagement/mitkPropertyList.h +++ b/Core/Code/DataManagement/mitkPropertyList.h @@ -1,210 +1,264 @@ /*=================================================================== 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 PROPERTYLIST_H_HEADER_INCLUDED_C1C77D8D #define PROPERTYLIST_H_HEADER_INCLUDED_C1C77D8D #include #include "mitkBaseProperty.h" #include "mitkGenericProperty.h" #include "mitkUIDGenerator.h" #include #include #include namespace mitk { class XMLWriter; /** * @brief Key-value list holding instances of BaseProperty * * This list is meant to hold an arbitrary list of "properties", * which should describe the object associated with this list. * * Usually you will use PropertyList as part of a DataNode * object - in this context the properties describe the data object * held by the DataNode (e.g. whether the object is rendered at * all, which color is used for rendering, what name should be * displayed for the object, etc.) * * The values in the list are not fixed, you may introduce any kind * of property that seems useful - all you have to do is inherit * from BaseProperty. * * The list is organized as a key-value pairs, i.e. * * \li "name" : pointer to a StringProperty * \li "visible" : pointer to a BoolProperty * \li "color" : pointer to a ColorProperty * \li "volume" : pointer to a FloatProperty * * Please see the documentation of SetProperty and ReplaceProperty for two * quite different semantics. Normally SetProperty is what you want - this * method will try to change the value of an existing property and will * not allow you to replace e.g. a ColorProperty with an IntProperty. * * @ingroup DataManagement */ class MITK_CORE_EXPORT PropertyList : public itk::Object { public: mitkClassMacro(PropertyList, itk::Object) /** * Method for creation through the object factory. */ itkNewMacro(Self) /** * Map structure to hold the properties: the map key is a string, * the value consists of the actual property object (BaseProperty). */ typedef std::map< std::string, BaseProperty::Pointer> PropertyMap; typedef std::pair< std::string, BaseProperty::Pointer> PropertyMapElementType; /** * @brief Get a property by its name. */ mitk::BaseProperty* GetProperty(const std::string& propertyKey) const; /** * @brief Set a property in the list/map by value. * * The actual OBJECT holding the value of the property is not replaced, but its value * is modified to match that of @a property. To really replace the object holding the * property - which would make sense if you want to change the type (bool, string) of the property * - call ReplaceProperty. */ void SetProperty(const std::string& propertyKey, BaseProperty* property); /** * @brief Set a property object in the list/map by reference. * * The actual OBJECT holding the value of the property is replaced by this function. * This is useful if you want to change the type of the property, like from BoolProperty to StringProperty. * Another use is to share one and the same property object among several ProperyList/DataNode objects, which * makes them appear synchronized. */ void ReplaceProperty(const std::string& propertyKey, BaseProperty* property); /** * @brief Set a property object in the list/map by reference. */ void ConcatenatePropertyList(PropertyList *pList, bool replace = false); //##Documentation //## @brief Convenience access method for GenericProperty properties //## (T being the type of the second parameter) //## @return @a true property was found template bool GetPropertyValue(const char* propertyKey, T & value) const { GenericProperty* gp= dynamic_cast*>(GetProperty(propertyKey)); if ( gp != NULL ) { value = gp->GetValue(); return true; } return false; } /** * @brief Convenience method to access the value of a BoolProperty */ bool GetBoolProperty(const char* propertyKey, bool& boolValue) const; + /** + * @brief ShortCut for the above method + */ + bool Get(const char* propertyKey, bool& boolValue) const; /** * @brief Convenience method to set the value of a BoolProperty */ void SetBoolProperty( const char* propertyKey, bool boolValue); + /** + * @brief ShortCut for the above method + */ + void Set( const char* propertyKey, bool boolValue); /** * @brief Convenience method to access the value of an IntProperty */ bool GetIntProperty(const char* propertyKey, int &intValue) const; + /** + * @brief ShortCut for the above method + */ + bool Get(const char* propertyKey, int &intValue) const; /** * @brief Convenience method to set the value of an IntProperty */ void SetIntProperty(const char* propertyKey, int intValue); + /** + * @brief ShortCut for the above method + */ + void Set(const char* propertyKey, int intValue); /** * @brief Convenience method to access the value of a FloatProperty */ bool GetFloatProperty(const char* propertyKey, float &floatValue) const; + /** + * @brief ShortCut for the above method + */ + bool Get(const char* propertyKey, float &floatValue) const; /** * @brief Convenience method to set the value of a FloatProperty */ void SetFloatProperty( const char* propertyKey, float floatValue); + /** + * @brief ShortCut for the above method + */ + void Set( const char* propertyKey, float floatValue); + + /** + * @brief Convenience method to access the value of a DoubleProperty + */ + bool GetDoubleProperty(const char* propertyKey, double &doubleValue) const; + /** + * @brief ShortCut for the above method + */ + bool Get(const char* propertyKey, double &doubleValue) const; + + /** + * @brief Convenience method to set the value of a DoubleProperty + */ + void SetDoubleProperty( const char* propertyKey, double doubleValue); + /** + * @brief ShortCut for the above method + */ + void Set( const char* propertyKey, double doubleValue); /** * @brief Convenience method to access the value of a StringProperty */ bool GetStringProperty(const char* propertyKey, std::string& stringValue) const; + /** + * @brief ShortCut for the above method + */ + bool Get(const char* propertyKey, std::string& stringValue) const; /** * @brief Convenience method to set the value of a StringProperty */ void SetStringProperty( const char* propertyKey, const char* stringValue); + /** + * @brief ShortCut for the above method + */ + void Set( const char* propertyKey, const char* stringValue); + /** + * @brief ShortCut for the above method + */ + void Set( const char* propertyKey, const std::string& stringValue); /** * @brief Get the timestamp of the last change of the map or the last change of one of * the properties store in the list (whichever is later). */ virtual unsigned long GetMTime() const; /** * @brief Remove a property from the list/map. */ bool DeleteProperty(const std::string& propertyKey); const PropertyMap* GetMap() const { return &m_Properties; } bool IsEmpty() const { return m_Properties.empty(); } virtual void Clear(); protected: PropertyList(); PropertyList(const PropertyList& other); virtual ~PropertyList(); /** * @brief Map of properties. */ PropertyMap m_Properties; private: virtual itk::LightObject::Pointer InternalClone() const; }; } // namespace mitk #endif /* PROPERTYLIST_H_HEADER_INCLUDED_C1C77D8D */ diff --git a/Core/Code/DataManagement/mitkPropertyListReplacedObserver.cpp b/Core/Code/DataManagement/mitkPropertyListReplacedObserver.cpp new file mode 100644 index 0000000000..78c0302100 --- /dev/null +++ b/Core/Code/DataManagement/mitkPropertyListReplacedObserver.cpp @@ -0,0 +1,25 @@ +/*=================================================================== + +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 "mitkPropertyListReplacedObserver.h" + +void mitk::PropertyListReplacedObserver::BeforePropertyListReplaced( const std::string& id, mitk::PropertyList* propertyList ) +{ +} + +void mitk::PropertyListReplacedObserver::AfterPropertyListReplaced( const std::string& id, mitk::PropertyList* propertyList ) +{ +} diff --git a/Core/Code/DataManagement/mitkPropertyListReplacedObserver.h b/Core/Code/DataManagement/mitkPropertyListReplacedObserver.h new file mode 100644 index 0000000000..d1407f7f19 --- /dev/null +++ b/Core/Code/DataManagement/mitkPropertyListReplacedObserver.h @@ -0,0 +1,44 @@ +/*=================================================================== + +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 mitkPropertyListReplacedObserver_h +#define mitkPropertyListReplacedObserver_h + +// mitk +#include +#include "mitkPropertyList.h" +#include + +namespace mitk +{ + /// + /// a PropertyListReplacedObserver gets informed as soon as a PropertyList with a given id was replaced during a Load() process + /// \see IPersistenceService::AddPropertyListReplacedObserver() + /// + class MITK_CORE_EXPORT PropertyListReplacedObserver + { + public: + /// + /// will be called *before* the propertyList gets replaced with new contents, i.e. propertyList still contains the old values + /// + virtual void BeforePropertyListReplaced( const std::string& id, mitk::PropertyList* propertyList ); + /// + /// will be called *after* the propertyList gets replaced with new contents, i.e. propertyList contains the new values + /// + virtual void AfterPropertyListReplaced( const std::string& id, mitk::PropertyList* propertyList ); + }; +} // namespace mitk + +#endif // mitkPropertyListReplacedObserver_h diff --git a/Core/Code/Interfaces/mitkIPersistenceService.cpp b/Core/Code/Interfaces/mitkIPersistenceService.cpp new file mode 100644 index 0000000000..af4f5d697e --- /dev/null +++ b/Core/Code/Interfaces/mitkIPersistenceService.cpp @@ -0,0 +1,21 @@ +/*=================================================================== + +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 "mitkIPersistenceService.h" + +mitk::IPersistenceService::~IPersistenceService() +{ +} diff --git a/Core/Code/Interfaces/mitkIPersistenceService.h b/Core/Code/Interfaces/mitkIPersistenceService.h new file mode 100644 index 0000000000..8abd88010d --- /dev/null +++ b/Core/Code/Interfaces/mitkIPersistenceService.h @@ -0,0 +1,344 @@ +/*=================================================================== + +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 mitkIPersistenceService_h +#define mitkIPersistenceService_h + +// mitk +#include "mitkPropertyListReplacedObserver.h" +#include "usServiceReference.h" +#include "usModuleContext.h" +#include "usGetModuleContext.h" +//for microservices +#include +#include "mitkDataStorage.h" + +namespace mitk +{ + /// + /// The central service for the persistence module + /// Basic idea is to create PropertyLists with a unique id using AddPropertyList(). A consumer + /// of this interface can write arbitrary information into this propertylist + /// Calling Save() and Load() will cause the Service to save and load the current set of propertlists from + /// a file in the user directory. + /// Using SetAutoLoadAndSave(true) will cause the service to load/save the property lists at application + /// start/stop. + /// Moreover, depending on the backend type, the service is connected to the SceneSerialization module, i.e. + /// the user will be asked whether to save/load the propertlists in/from the current ".mitk" file that is selected + /// by the user. + /// + class MITK_CORE_EXPORT IPersistenceService + { + public: + /// + /// If PropertyList with the given id exists, returns it. Otherwise creates a new one and returns it. + /// If id is empty a UUID will be created and set on the variable + /// If existed was passed, it is true if the PropertyList with that id existed, false otherwise + /// \return a valid PropertyList with a StringProperty "Id" containing the passed id + /// + virtual mitk::PropertyList::Pointer GetPropertyList( std::string& id, bool* existed=0 ) = 0; + /// + /// removes the PropertyList with the given id + /// \return true if PropertyList existed and could be removed, false otherwise + /// + virtual bool RemovePropertyList( std::string& id ) = 0; + /// + /// Get the default name of the PersistenceFile (the one that is loaded at startup) + /// + virtual std::string GetDefaultPersistenceFile() const = 0; + /// + /// \return The name of the Bool Property that specifies whether a DataNode is a Node carrying Persistence PropertyLists + /// + virtual std::string GetPersistenceNodePropertyName() const = 0; + /// + /// Creates a vector of DataNodes that contain all PropertyLists. Additionally, the DataNodes + /// will have the property name set to the PropertyList's id and a BoolProperty equal to GetPersistenceNodePropertyName() set to true. If ds is set the returned DataNodes will also be added to that DS. + /// \return vector of DataNodes with the described attributes + /// + virtual DataStorage::SetOfObjects::Pointer GetDataNodes(DataStorage* ds=0) const = 0; + /// + /// Searches storage for persistent DataNodes, extracts and inserts the appended property lists to this service + /// \return true if at least one node was found from which a PropertyList could be restored + /// + virtual bool RestorePropertyListsFromPersistentDataNodes(const DataStorage* storage) = 0; + /// + /// Save the current PropertyLists to fileName. If fileName is empty, a special file in the users home directory will be used. + /// if appendchanges is true, the file will not replaced but first loaded, then overwritten and then replaced + /// \return false if an error occured (cannot write to file), true otherwise + /// + virtual bool Save(const std::string& fileName="", bool appendChanges=false) = 0; + /// + /// Load PropertyLists from fileName. If fileName is empty, a special file in the users home directory will be used. + /// If enforeReload is false, the service will take care of modified time flags, i.e. it will not load a file + /// that was loaded before and did not change in the meantime or that was modified by the service itself + /// *ATTENTION*: If there are PropertyLists with the same id contained in the file, existing PropertyLists will be overwritten! + /// \see AddPropertyListReplacedObserver() + /// \return false if an error occured (cannot load from file), true otherwise + /// + virtual bool Load(const std::string& fileName="", bool enforeReload=true) = 0; + /// + /// Using SetAutoLoadAndSave(true) will cause the service to load/save the property lists at application + /// start/stop. + /// + virtual void SetAutoLoadAndSave(bool autoLoadAndSave) = 0; + /// + /// \return whether AutoLoading is activated or not + /// + virtual bool GetAutoLoadAndSave() const = 0; + /// + /// adds a observer which is informed if a propertyList gets replaced during a Load() procedure + /// + virtual void AddPropertyListReplacedObserver( PropertyListReplacedObserver* observer ) = 0; + /// + /// removes a specific observer + /// + virtual void RemovePropertyListReplacedObserver( PropertyListReplacedObserver* observer ) = 0; + /// + /// nothing to do here + /// + virtual ~IPersistenceService(); + }; +} + +/// MACROS FOR AUTOMATIC SAVE FUNCTION +#define PERSISTENCE_GET_MODULE_CONTEXT_FUNCTION\ + us::GetModuleContext() + +#define PERSISTENCE_GET_SERVICE_MACRO\ + mitk::IPersistenceService* persistenceService = 0;\ + us::ModuleContext* context = PERSISTENCE_GET_MODULE_CONTEXT_FUNCTION;\ + if( context )\ + {\ + us::ServiceReference persistenceServiceRef = context->GetServiceReference();\ + if( persistenceServiceRef )\ + {\ + persistenceService\ + = dynamic_cast ( context->GetService(persistenceServiceRef) );\ + }\ + } + +#define PERSISTENCE_GET_SERVICE_METHOD_MACRO\ + mitk::IPersistenceService* GetPeristenceService() const\ + {\ + static mitk::IPersistenceService* staticPersistenceService = 0;\ + if( staticPersistenceService == 0 )\ + {\ + PERSISTENCE_GET_SERVICE_MACRO\ + staticPersistenceService = persistenceService;\ + }\ + return staticPersistenceService;\ + } + +#define PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)\ +public:\ + bool Save(const std::string& fileName="", bool appendChanges=false)\ + {\ + mitk::IPersistenceService* persistenceService = this->GetPeristenceService();\ + bool noError = persistenceService != 0;\ + if( noError )\ + this->ToPropertyList();\ + if(noError)\ + noError = persistenceService->Save(fileName, appendChanges);\ + return noError;\ + }\ + bool Load(const std::string& fileName="", bool enforeReload=true)\ + {\ + mitk::IPersistenceService* persistenceService = this->GetPeristenceService();\ + bool noError = persistenceService != 0 && persistenceService->Load(fileName, enforeReload);\ + if( noError )\ + {\ + this->FromPropertyList();\ + }\ + return noError;\ + }\ + void ToPropertyList()\ + {\ + mitk::IPersistenceService* persistenceService = this->GetPeristenceService();\ + this->InitializePropertyListReplacedObserver(persistenceService);\ + if( !persistenceService )\ + return;\ + mitk::PropertyList::Pointer propList = persistenceService->GetPropertyList(ID_MEMBER_NAME); + +#define PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)\ + }\ + void FromPropertyList()\ + {\ + mitk::IPersistenceService* persistenceService = this->GetPeristenceService();\ + this->InitializePropertyListReplacedObserver(persistenceService);\ + if( !persistenceService )\ + return;\ + mitk::PropertyList::Pointer propList = persistenceService->GetPropertyList(ID_MEMBER_NAME); + +#define PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME)\ +}\ +std::string GetId() const\ +{\ + return ID_MEMBER_NAME;\ +}\ +private:\ + PERSISTENCE_GET_SERVICE_METHOD_MACRO\ + struct MyPropertyListReplacedObserver: public mitk::PropertyListReplacedObserver\ + {\ + MyPropertyListReplacedObserver()\ + : m_##THE_CLASS_NAME(0), m_PersistenceService(0)\ + {\ + }\ + ~MyPropertyListReplacedObserver()\ + {\ + if( m_PersistenceService )\ + m_PersistenceService->RemovePropertyListReplacedObserver(this);\ + }\ + void AfterPropertyListReplaced( const std::string& id, mitk::PropertyList* propertyList )\ + {\ + if( m_##THE_CLASS_NAME && m_##THE_CLASS_NAME->GetId() == id )\ + m_##THE_CLASS_NAME->FromPropertyList();\ + }\ + void Initialize( THE_CLASS_NAME * _##THE_CLASS_NAME, mitk::IPersistenceService* persistenceService )\ + {\ + m_##THE_CLASS_NAME = _##THE_CLASS_NAME;\ + m_PersistenceService = persistenceService;\ + if( m_PersistenceService )\ + m_PersistenceService->AddPropertyListReplacedObserver(this);\ + }\ + private:\ + THE_CLASS_NAME * m_##THE_CLASS_NAME;\ + mitk::IPersistenceService* m_PersistenceService;\ + };\ + MyPropertyListReplacedObserver m_MyPropertyListReplacedObserver;\ + void InitializePropertyListReplacedObserver(mitk::IPersistenceService* persistenceService)\ + {\ + static bool observerInitialized = false;\ + if( observerInitialized == false && persistenceService )\ + {\ + m_MyPropertyListReplacedObserver.Initialize( this, persistenceService );\ + observerInitialized = true;\ + }\ + } + +#define PERSISTENCE_CREATE(THE_CLASS_NAME, ID_MEMBER_NAME, PARAM_MEMBER_NAME)\ + PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)\ + propList->Set( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ + PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)\ + propList->Get( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ + PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME) + +#define PERSISTENCE_CREATE2(THE_CLASS_NAME, ID_MEMBER_NAME, PARAM_MEMBER_NAME, PARAM2_MEMBER_NAME)\ + PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)\ + propList->Set( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ + propList->Set( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ + PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)\ + propList->Get( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ + propList->Get( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ + PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME) + +#define PERSISTENCE_CREATE3(THE_CLASS_NAME, ID_MEMBER_NAME, PARAM_MEMBER_NAME, PARAM2_MEMBER_NAME, PARAM3_MEMBER_NAME)\ + PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)\ + propList->Set( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ + propList->Set( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ + propList->Set( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ + PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)\ + propList->Get( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ + propList->Get( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ + propList->Get( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ + PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME) + +#define PERSISTENCE_CREATE4(THE_CLASS_NAME, ID_MEMBER_NAME, PARAM_MEMBER_NAME, PARAM2_MEMBER_NAME, PARAM3_MEMBER_NAME, PARAM4_MEMBER_NAME)\ + PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)\ + propList->Set( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ + propList->Set( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ + propList->Set( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ + propList->Set( #PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME );\ + PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)\ + propList->Get( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ + propList->Get( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ + propList->Get( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ + propList->Get( #PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME );\ + PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME) + +#define PERSISTENCE_CREATE5(THE_CLASS_NAME, ID_MEMBER_NAME, PARAM_MEMBER_NAME, PARAM2_MEMBER_NAME, PARAM3_MEMBER_NAME, PARAM4_MEMBER_NAME, PARAM5_MEMBER_NAME)\ + PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)\ + propList->Set( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ + propList->Set( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ + propList->Set( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ + propList->Set( #PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME );\ + propList->Set( #PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME );\ + PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)\ + propList->Get( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ + propList->Get( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ + propList->Get( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ + propList->Get( #PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME );\ + propList->Get( #PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME );\ + PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME) + +#define PERSISTENCE_CREATE6(THE_CLASS_NAME, ID_MEMBER_NAME, PARAM_MEMBER_NAME, PARAM2_MEMBER_NAME, PARAM3_MEMBER_NAME, PARAM4_MEMBER_NAME, PARAM5_MEMBER_NAME, PARAM6_MEMBER_NAME)\ + PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)\ + propList->Set( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ + propList->Set( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ + propList->Set( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ + propList->Set( #PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME );\ + propList->Set( #PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME );\ + propList->Set( #PARAM6_MEMBER_NAME, PARAM6_MEMBER_NAME );\ + PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)\ + propList->Get( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ + propList->Get( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ + propList->Get( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ + propList->Get( #PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME );\ + propList->Get( #PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME );\ + propList->Get( #PARAM6_MEMBER_NAME, PARAM6_MEMBER_NAME );\ + PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME) + +#define PERSISTENCE_CREATE7(THE_CLASS_NAME, ID_MEMBER_NAME, PARAM_MEMBER_NAME, PARAM2_MEMBER_NAME, PARAM3_MEMBER_NAME, PARAM4_MEMBER_NAME, PARAM5_MEMBER_NAME, PARAM6_MEMBER_NAME, PARAM7_MEMBER_NAME)\ + PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)\ + propList->Set( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ + propList->Set( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ + propList->Set( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ + propList->Set( #PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME );\ + propList->Set( #PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME );\ + propList->Set( #PARAM6_MEMBER_NAME, PARAM6_MEMBER_NAME );\ + propList->Set( #PARAM7_MEMBER_NAME, PARAM7_MEMBER_NAME );\ + PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)\ + propList->Get( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ + propList->Get( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ + propList->Get( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ + propList->Get( #PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME );\ + propList->Get( #PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME );\ + propList->Get( #PARAM6_MEMBER_NAME, PARAM6_MEMBER_NAME );\ + propList->Get( #PARAM7_MEMBER_NAME, PARAM7_MEMBER_NAME );\ + PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME) + +#define PERSISTENCE_CREATE8(THE_CLASS_NAME, ID_MEMBER_NAME, PARAM_MEMBER_NAME, PARAM2_MEMBER_NAME, PARAM3_MEMBER_NAME, PARAM4_MEMBER_NAME, PARAM5_MEMBER_NAME, PARAM6_MEMBER_NAME, PARAM7_MEMBER_NAME, PARAM8_MEMBER_NAME)\ + PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)\ + propList->Set( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ + propList->Set( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ + propList->Set( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ + propList->Set( #PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME );\ + propList->Set( #PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME );\ + propList->Set( #PARAM6_MEMBER_NAME, PARAM6_MEMBER_NAME );\ + propList->Set( #PARAM7_MEMBER_NAME, PARAM7_MEMBER_NAME );\ + propList->Set( #PARAM8_MEMBER_NAME, PARAM8_MEMBER_NAME );\ + PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)\ + propList->Get( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ + propList->Get( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ + propList->Get( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ + propList->Get( #PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME );\ + propList->Get( #PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME );\ + propList->Get( #PARAM6_MEMBER_NAME, PARAM6_MEMBER_NAME );\ + propList->Get( #PARAM7_MEMBER_NAME, PARAM7_MEMBER_NAME );\ + propList->Get( #PARAM8_MEMBER_NAME, PARAM8_MEMBER_NAME );\ + PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME) + +US_DECLARE_SERVICE_INTERFACE(mitk::IPersistenceService, "org.mitk.services.IPersistenceService") + +#endif diff --git a/Core/Code/files.cmake b/Core/Code/files.cmake index c991bfedc4..142cbdaf41 100644 --- a/Core/Code/files.cmake +++ b/Core/Code/files.cmake @@ -1,407 +1,409 @@ set(H_FILES Algorithms/itkImportMitkImageContainer.h Algorithms/itkImportMitkImageContainer.txx Algorithms/itkLocalVariationImageFilter.h Algorithms/itkLocalVariationImageFilter.txx Algorithms/itkMITKScalarImageToHistogramGenerator.h Algorithms/itkMITKScalarImageToHistogramGenerator.txx Algorithms/itkTotalVariationDenoisingImageFilter.h Algorithms/itkTotalVariationDenoisingImageFilter.txx Algorithms/itkTotalVariationSingleIterationImageFilter.h Algorithms/itkTotalVariationSingleIterationImageFilter.txx Algorithms/mitkBilateralFilter.h Algorithms/mitkBilateralFilter.cpp Algorithms/mitkInstantiateAccessFunctions.h Algorithms/mitkPixelTypeList.h Algorithms/mitkPPArithmeticDec.h Algorithms/mitkPPArgCount.h Algorithms/mitkPPCat.h Algorithms/mitkPPConfig.h Algorithms/mitkPPControlExprIIf.h Algorithms/mitkPPControlIf.h Algorithms/mitkPPControlIIf.h Algorithms/mitkPPDebugError.h Algorithms/mitkPPDetailAutoRec.h Algorithms/mitkPPDetailDMCAutoRec.h Algorithms/mitkPPExpand.h Algorithms/mitkPPFacilitiesEmpty.h Algorithms/mitkPPFacilitiesExpand.h Algorithms/mitkPPLogicalBool.h Algorithms/mitkPPRepetitionDetailDMCFor.h Algorithms/mitkPPRepetitionDetailEDGFor.h Algorithms/mitkPPRepetitionDetailFor.h Algorithms/mitkPPRepetitionDetailMSVCFor.h Algorithms/mitkPPRepetitionFor.h Algorithms/mitkPPSeqElem.h Algorithms/mitkPPSeqForEach.h Algorithms/mitkPPSeqForEachProduct.h Algorithms/mitkPPSeq.h Algorithms/mitkPPSeqEnum.h Algorithms/mitkPPSeqSize.h Algorithms/mitkPPSeqToTuple.h Algorithms/mitkPPStringize.h Algorithms/mitkPPTupleEat.h Algorithms/mitkPPTupleElem.h Algorithms/mitkPPTupleRem.h Algorithms/mitkClippedSurfaceBoundsCalculator.h Algorithms/mitkExtractSliceFilter.h Algorithms/mitkConvert2Dto3DImageFilter.h Algorithms/mitkPlaneClipping.h Common/mitkCommon.h Common/mitkExceptionMacro.h DataManagement/mitkProportionalTimeGeometry.h DataManagement/mitkTimeGeometry.h DataManagement/mitkImageAccessByItk.h DataManagement/mitkImageCast.h DataManagement/mitkImagePixelAccessor.h DataManagement/mitkImagePixelReadAccessor.h DataManagement/mitkImagePixelWriteAccessor.h DataManagement/mitkImageReadAccessor.h DataManagement/mitkImageWriteAccessor.h DataManagement/mitkITKImageImport.h DataManagement/mitkITKImageImport.txx DataManagement/mitkImageToItk.h DataManagement/mitkImageToItk.txx DataManagement/mitkTimeSlicedGeometry.h # Deprecated, empty for compatibilty reasons. + DataManagement/mitkPropertyListReplacedObserver.cpp Interactions/mitkEventMapperAddOn.h Interfaces/mitkIDataNodeReader.h Rendering/mitkLocalStorageHandler.h IO/mitkPixelTypeTraits.h ) set(CPP_FILES Algorithms/mitkBaseDataSource.cpp Algorithms/mitkCompareImageDataFilter.cpp Algorithms/mitkMultiComponentImageDataComparisonFilter.cpp Algorithms/mitkDataNodeSource.cpp Algorithms/mitkGeometry2DDataToSurfaceFilter.cpp Algorithms/mitkHistogramGenerator.cpp Algorithms/mitkImageChannelSelector.cpp Algorithms/mitkImageSliceSelector.cpp Algorithms/mitkImageSource.cpp Algorithms/mitkImageTimeSelector.cpp Algorithms/mitkImageToImageFilter.cpp Algorithms/mitkImageToSurfaceFilter.cpp Algorithms/mitkPointSetSource.cpp Algorithms/mitkPointSetToPointSetFilter.cpp Algorithms/mitkRGBToRGBACastImageFilter.cpp Algorithms/mitkSubImageSelector.cpp Algorithms/mitkSurfaceSource.cpp Algorithms/mitkSurfaceToImageFilter.cpp Algorithms/mitkSurfaceToSurfaceFilter.cpp Algorithms/mitkUIDGenerator.cpp Algorithms/mitkVolumeCalculator.cpp Algorithms/mitkClippedSurfaceBoundsCalculator.cpp Algorithms/mitkExtractSliceFilter.cpp Algorithms/mitkConvert2Dto3DImageFilter.cpp Controllers/mitkBaseController.cpp Controllers/mitkCallbackFromGUIThread.cpp Controllers/mitkCameraController.cpp Controllers/mitkCameraRotationController.cpp Controllers/mitkCoreActivator.cpp Controllers/mitkFocusManager.cpp Controllers/mitkLimitedLinearUndo.cpp Controllers/mitkOperationEvent.cpp Controllers/mitkPlanePositionManager.cpp Controllers/mitkProgressBar.cpp Controllers/mitkRenderingManager.cpp Controllers/mitkSliceNavigationController.cpp Controllers/mitkSlicesCoordinator.cpp Controllers/mitkSlicesRotator.cpp Controllers/mitkSlicesSwiveller.cpp Controllers/mitkStatusBar.cpp Controllers/mitkStepper.cpp Controllers/mitkTestManager.cpp Controllers/mitkUndoController.cpp Controllers/mitkVerboseLimitedLinearUndo.cpp Controllers/mitkVtkInteractorCameraController.cpp Controllers/mitkVtkLayerController.cpp DataManagement/mitkProportionalTimeGeometry.cpp DataManagement/mitkTimeGeometry.cpp DataManagement/mitkAbstractTransformGeometry.cpp DataManagement/mitkAnnotationProperty.cpp DataManagement/mitkApplicationCursor.cpp DataManagement/mitkBaseData.cpp DataManagement/mitkBaseProperty.cpp DataManagement/mitkClippingProperty.cpp DataManagement/mitkChannelDescriptor.cpp DataManagement/mitkColorProperty.cpp DataManagement/mitkDataStorage.cpp # DataManagement/mitkDataTree.cpp DataManagement/mitkDataNode.cpp DataManagement/mitkDataNodeFactory.cpp # DataManagement/mitkDataTreeStorage.cpp DataManagement/mitkDisplayGeometry.cpp DataManagement/mitkEnumerationProperty.cpp DataManagement/mitkGeometry2D.cpp DataManagement/mitkGeometry2DData.cpp DataManagement/mitkGeometry3D.cpp DataManagement/mitkGeometryData.cpp DataManagement/mitkGroupTagProperty.cpp DataManagement/mitkImage.cpp DataManagement/mitkImageAccessorBase.cpp DataManagement/mitkImageCaster.cpp DataManagement/mitkImageCastPart1.cpp DataManagement/mitkImageCastPart2.cpp DataManagement/mitkImageCastPart3.cpp DataManagement/mitkImageCastPart4.cpp DataManagement/mitkImageDataItem.cpp DataManagement/mitkImageDescriptor.cpp DataManagement/mitkImageVtkAccessor.cpp DataManagement/mitkImageStatisticsHolder.cpp DataManagement/mitkLandmarkBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjector.cpp DataManagement/mitkLevelWindow.cpp DataManagement/mitkLevelWindowManager.cpp DataManagement/mitkLevelWindowPreset.cpp DataManagement/mitkLevelWindowProperty.cpp DataManagement/mitkLookupTable.cpp DataManagement/mitkLookupTables.cpp # specializations of GenericLookupTable DataManagement/mitkMemoryUtilities.cpp DataManagement/mitkModalityProperty.cpp DataManagement/mitkModeOperation.cpp DataManagement/mitkNodePredicateAnd.cpp DataManagement/mitkNodePredicateBase.cpp DataManagement/mitkNodePredicateCompositeBase.cpp DataManagement/mitkNodePredicateData.cpp DataManagement/mitkNodePredicateDataType.cpp DataManagement/mitkNodePredicateDimension.cpp DataManagement/mitkNodePredicateFirstLevel.cpp DataManagement/mitkNodePredicateNot.cpp DataManagement/mitkNodePredicateOr.cpp DataManagement/mitkNodePredicateProperty.cpp DataManagement/mitkNodePredicateSource.cpp DataManagement/mitkPlaneOrientationProperty.cpp DataManagement/mitkPlaneGeometry.cpp DataManagement/mitkPlaneOperation.cpp DataManagement/mitkPointOperation.cpp DataManagement/mitkPointSet.cpp DataManagement/mitkProperties.cpp DataManagement/mitkPropertyList.cpp DataManagement/mitkPropertyObserver.cpp DataManagement/mitkRestorePlanePositionOperation.cpp DataManagement/mitkApplyTransformMatrixOperation.cpp DataManagement/mitkRotationOperation.cpp DataManagement/mitkSlicedData.cpp DataManagement/mitkSlicedGeometry3D.cpp DataManagement/mitkSmartPointerProperty.cpp DataManagement/mitkStandaloneDataStorage.cpp DataManagement/mitkStateTransitionOperation.cpp DataManagement/mitkStringProperty.cpp DataManagement/mitkSurface.cpp DataManagement/mitkSurfaceOperation.cpp DataManagement/mitkThinPlateSplineCurvedGeometry.cpp DataManagement/mitkTransferFunction.cpp DataManagement/mitkTransferFunctionProperty.cpp DataManagement/mitkTransferFunctionInitializer.cpp DataManagement/mitkVector.cpp DataManagement/mitkVtkInterpolationProperty.cpp DataManagement/mitkVtkRepresentationProperty.cpp DataManagement/mitkVtkResliceInterpolationProperty.cpp DataManagement/mitkVtkScalarModeProperty.cpp DataManagement/mitkVtkVolumeRenderingProperty.cpp DataManagement/mitkWeakPointerProperty.cpp DataManagement/mitkRenderingModeProperty.cpp DataManagement/mitkShaderProperty.cpp DataManagement/mitkResliceMethodProperty.cpp DataManagement/mitkMaterial.cpp DataManagement/mitkPointSetShapeProperty.cpp DataManagement/mitkFloatPropertyExtension.cpp DataManagement/mitkIntPropertyExtension.cpp DataManagement/mitkPropertyExtension.cpp DataManagement/mitkPropertyFilter.cpp DataManagement/mitkPropertyAliases.cpp DataManagement/mitkPropertyDescriptions.cpp DataManagement/mitkPropertyExtensions.cpp DataManagement/mitkPropertyFilters.cpp Interactions/mitkAction.cpp Interactions/mitkAffineInteractor.cpp Interactions/mitkBindDispatcherInteractor.cpp Interactions/mitkCoordinateSupplier.cpp Interactions/mitkDataInteractor.cpp Interactions/mitkDispatcher.cpp Interactions/mitkDisplayCoordinateOperation.cpp Interactions/mitkDisplayInteractor.cpp Interactions/mitkDisplayPositionEvent.cpp # Interactions/mitkDisplayVectorInteractorLevelWindow.cpp # legacy, prob even now unneeded # Interactions/mitkDisplayVectorInteractorScroll.cpp Interactions/mitkEvent.cpp Interactions/mitkEventConfig.cpp Interactions/mitkEventDescription.cpp Interactions/mitkEventFactory.cpp Interactions/mitkInteractionEventHandler.cpp Interactions/mitkEventMapper.cpp Interactions/mitkEventStateMachine.cpp Interactions/mitkGlobalInteraction.cpp Interactions/mitkInteractor.cpp Interactions/mitkInternalEvent.cpp Interactions/mitkInteractionEvent.cpp Interactions/mitkInteractionEventConst.cpp Interactions/mitkInteractionPositionEvent.cpp Interactions/mitkInteractionKeyEvent.cpp Interactions/mitkMousePressEvent.cpp Interactions/mitkMouseMoveEvent.cpp Interactions/mitkMouseReleaseEvent.cpp Interactions/mitkMouseWheelEvent.cpp Interactions/mitkMouseDoubleClickEvent.cpp Interactions/mitkMouseModeSwitcher.cpp Interactions/mitkMouseMovePointSetInteractor.cpp Interactions/mitkMoveBaseDataInteractor.cpp Interactions/mitkNodeDepententPointSetInteractor.cpp Interactions/mitkPointSetDataInteractor.cpp Interactions/mitkPointSetInteractor.cpp Interactions/mitkPositionEvent.cpp Interactions/mitkPositionTracker.cpp Interactions/mitkStateMachineAction.cpp Interactions/mitkStateMachineCondition.cpp Interactions/mitkStateMachineState.cpp Interactions/mitkStateMachineTransition.cpp Interactions/mitkState.cpp Interactions/mitkStateMachineContainer.cpp Interactions/mitkStateEvent.cpp Interactions/mitkStateMachine.cpp Interactions/mitkStateMachineFactory.cpp Interactions/mitkTransition.cpp Interactions/mitkWheelEvent.cpp Interactions/mitkKeyEvent.cpp Interactions/mitkVtkEventAdapter.cpp Interactions/mitkVtkInteractorStyle.cxx Interactions/mitkCrosshairPositionEvent.cpp Interfaces/mitkInteractionEventObserver.cpp Interfaces/mitkIShaderRepository.cpp Interfaces/mitkIPropertyAliases.cpp Interfaces/mitkIPropertyDescriptions.cpp Interfaces/mitkIPropertyExtensions.cpp Interfaces/mitkIPropertyFilters.cpp + Interfaces/mitkIPersistenceService.cpp IO/mitkBaseDataIOFactory.cpp IO/mitkCoreDataNodeReader.cpp IO/mitkDicomSeriesReader.cpp IO/mitkDicomSR_LoadDICOMScalar.cpp IO/mitkDicomSR_LoadDICOMScalar4D.cpp IO/mitkDicomSR_LoadDICOMRGBPixel.cpp IO/mitkDicomSR_LoadDICOMRGBPixel4D.cpp IO/mitkDicomSR_ImageBlockDescriptor.cpp IO/mitkDicomSR_GantryTiltInformation.cpp IO/mitkDicomSR_SliceGroupingResult.cpp IO/mitkFileReader.cpp IO/mitkFileSeriesReader.cpp IO/mitkFileWriter.cpp # IO/mitkIpPicGet.c IO/mitkImageGenerator.cpp IO/mitkImageWriter.cpp IO/mitkImageWriterFactory.cpp IO/mitkItkImageFileIOFactory.cpp IO/mitkItkImageFileReader.cpp IO/mitkItkLoggingAdapter.cpp IO/mitkItkPictureWrite.cpp IO/mitkIOUtil.cpp IO/mitkLookupTableProperty.cpp IO/mitkOperation.cpp # IO/mitkPicFileIOFactory.cpp # IO/mitkPicFileReader.cpp # IO/mitkPicFileWriter.cpp # IO/mitkPicHelper.cpp # IO/mitkPicVolumeTimeSeriesIOFactory.cpp # IO/mitkPicVolumeTimeSeriesReader.cpp IO/mitkPixelType.cpp IO/mitkPointSetIOFactory.cpp IO/mitkPointSetReader.cpp IO/mitkPointSetWriter.cpp IO/mitkPointSetWriterFactory.cpp IO/mitkRawImageFileReader.cpp IO/mitkStandardFileLocations.cpp IO/mitkSTLFileIOFactory.cpp IO/mitkSTLFileReader.cpp IO/mitkSurfaceVtkWriter.cpp IO/mitkSurfaceVtkWriterFactory.cpp IO/mitkVtkLoggingAdapter.cpp IO/mitkVtiFileIOFactory.cpp IO/mitkVtiFileReader.cpp IO/mitkVtkImageIOFactory.cpp IO/mitkVtkImageReader.cpp IO/mitkVtkSurfaceIOFactory.cpp IO/mitkVtkSurfaceReader.cpp IO/vtkPointSetXMLParser.cpp IO/mitkLog.cpp Rendering/mitkBaseRenderer.cpp Rendering/mitkVtkMapper.cpp Rendering/mitkRenderWindowFrame.cpp Rendering/mitkGeometry2DDataMapper2D.cpp Rendering/mitkGeometry2DDataVtkMapper3D.cpp Rendering/mitkGLMapper.cpp Rendering/mitkGradientBackground.cpp Rendering/mitkManufacturerLogo.cpp Rendering/mitkMapper.cpp Rendering/mitkPointSetGLMapper2D.cpp Rendering/mitkPointSetVtkMapper2D.cpp Rendering/mitkPointSetVtkMapper3D.cpp Rendering/mitkPolyDataGLMapper2D.cpp Rendering/mitkSurfaceGLMapper2D.cpp Rendering/mitkSurfaceVtkMapper3D.cpp Rendering/mitkVolumeDataVtkMapper3D.cpp Rendering/mitkVtkPropRenderer.cpp Rendering/mitkVtkWidgetRendering.cpp Rendering/vtkMitkRectangleProp.cpp Rendering/vtkMitkRenderProp.cpp Rendering/mitkVtkEventProvider.cpp Rendering/mitkRenderWindow.cpp Rendering/mitkRenderWindowBase.cpp Rendering/mitkShaderRepository.cpp Rendering/mitkImageVtkMapper2D.cpp Rendering/vtkMitkThickSlicesFilter.cpp Rendering/vtkMitkLevelWindowFilter.cpp Rendering/vtkNeverTranslucentTexture.cpp Rendering/mitkOverlay.cpp Rendering/mitkVtkOverlay.cpp Rendering/mitkVtkOverlay2D.cpp Rendering/mitkVtkOverlay3D.cpp Rendering/mitkOverlayManager.cpp Rendering/mitkAbstractOverlayLayouter.cpp Rendering/mitkTextOverlay2D.cpp Rendering/mitkTextOverlay3D.cpp Rendering/mitkLabelOverlay3D.cpp Rendering/mitkOverlay2DLayouter.cpp Rendering/mitkScaleLegendOverlay Common/mitkException.cpp Common/mitkCommon.h Common/mitkCoreObjectFactoryBase.cpp Common/mitkCoreObjectFactory.cpp Common/mitkCoreServices.cpp ) set(RESOURCE_FILES Interactions/globalConfig.xml Interactions/DisplayInteraction.xml Interactions/DisplayConfig.xml Interactions/DisplayConfigPACS.xml Interactions/DisplayConfigPACSPan.xml Interactions/DisplayConfigPACSScroll.xml Interactions/DisplayConfigPACSZoom.xml Interactions/DisplayConfigPACSLevelWindow.xml Interactions/DisplayConfigMITK.xml Interactions/PointSet.xml Interactions/Legacy/StateMachine.xml Interactions/Legacy/DisplayConfigMITKTools.xml Interactions/PointSetConfig.xml Shaders/mitkShaderLighting.xml mitkLevelWindowPresets.xml ) diff --git a/Modules/CMakeLists.txt b/Modules/CMakeLists.txt index d1cc7b61ed..e8f84835d8 100644 --- a/Modules/CMakeLists.txt +++ b/Modules/CMakeLists.txt @@ -1,76 +1,77 @@ set(LIBPOSTFIX "Ext") # Modules must be listed according to their dependencies set(module_dirs MitkDataTypesExt MitkAlgorithmsExt MitkMapperExt MitkIOExt Qt4Qt5TestModule SceneSerializationBase PlanarFigure ImageExtraction ImageStatistics LegacyAdaptors IpPicSupport MitkExt SceneSerialization GraphAlgorithms ContourModel SurfaceInterpolation Segmentation PlanarFigureSegmentation OpenViewCore QmlMitk Qmitk QmitkExt SegmentationUI DiffusionImaging GPGPU IGTBase IGT CameraCalibration IGTUI RigidRegistration RigidRegistrationUI DeformableRegistration DeformableRegistrationUI OpenCL OpenCVVideoSupport Overlays InputDevices ToFHardware ToFProcessing ToFUI US ClippingTools USUI DicomUI Simulation Remeshing Python + Persistence ) if(MITK_ENABLE_PIC_READER) list(APPEND module_dirs IpPicSupportIO) endif() set(MITK_DEFAULT_SUBPROJECTS MITK-Modules) foreach(module_dir ${module_dirs}) add_subdirectory(${module_dir}) endforeach() if(MITK_PRIVATE_MODULES) file(GLOB all_subdirs RELATIVE ${MITK_PRIVATE_MODULES} ${MITK_PRIVATE_MODULES}/*) foreach(subdir ${all_subdirs}) string(FIND ${subdir} "." _result) if(_result EQUAL -1) if(EXISTS ${MITK_PRIVATE_MODULES}/${subdir}/CMakeLists.txt) message(STATUS "Found private module ${subdir}") add_subdirectory(${MITK_PRIVATE_MODULES}/${subdir} private_modules/${subdir}) endif() endif() endforeach() endif(MITK_PRIVATE_MODULES) diff --git a/Modules/IGT/Testing/mitkNavigationToolStorageSerializerAndDeserializerTest.cpp b/Modules/IGT/Testing/mitkNavigationToolStorageSerializerAndDeserializerTest.cpp index 77aae9d6a5..ebbc2649e5 100644 --- a/Modules/IGT/Testing/mitkNavigationToolStorageSerializerAndDeserializerTest.cpp +++ b/Modules/IGT/Testing/mitkNavigationToolStorageSerializerAndDeserializerTest.cpp @@ -1,471 +1,475 @@ /*=================================================================== 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 "mitkTestingConfig.h" #include #include #include #include #include #include #include #include #include #include //POCO #include #include #include static void TestInstantiationSerializer() { // let's create objects of our classes mitk::NavigationToolStorageSerializer::Pointer testSerializer = mitk::NavigationToolStorageSerializer::New(); MITK_TEST_CONDITION_REQUIRED(testSerializer.IsNotNull(),"Testing instantiation of NavigationToolStorageSerializer"); } static void TestInstantiationDeserializer() { mitk::DataStorage::Pointer tempStorage = dynamic_cast(mitk::StandaloneDataStorage::New().GetPointer()); //needed for deserializer! mitk::NavigationToolStorageDeserializer::Pointer testDeserializer = mitk::NavigationToolStorageDeserializer::New(tempStorage); MITK_TEST_CONDITION_REQUIRED(testDeserializer.IsNotNull(),"Testing instantiation of NavigationToolStorageDeserializer") } static void TestWriteSimpleToolStorage() { //create Tool Storage mitk::NavigationToolStorage::Pointer myStorage = mitk::NavigationToolStorage::New(); //first tool mitk::NavigationTool::Pointer myTool1 = mitk::NavigationTool::New(); myTool1->SetIdentifier("001"); myStorage->AddTool(myTool1); //second tool mitk::NavigationTool::Pointer myTool2 = mitk::NavigationTool::New(); myTool2->SetIdentifier("002"); myStorage->AddTool(myTool2); //third tool mitk::NavigationTool::Pointer myTool3 = mitk::NavigationTool::New(); myTool3->SetIdentifier("003"); myStorage->AddTool(myTool3); //create Serializer mitk::NavigationToolStorageSerializer::Pointer mySerializer = mitk::NavigationToolStorageSerializer::New(); //create filename std::string filename = std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+"TestStorage.storage"; //test serialization bool success = mySerializer->Serialize(filename,myStorage); MITK_TEST_CONDITION_REQUIRED(success,"Testing serialization of simple tool storage"); } static void TestWriteAndReadSimpleToolStorageWithToolLandmarks() { //create Tool Storage mitk::NavigationToolStorage::Pointer myStorage = mitk::NavigationToolStorage::New(); //first tool mitk::NavigationTool::Pointer myTool1 = mitk::NavigationTool::New(); myTool1->SetIdentifier("001"); mitk::PointSet::Pointer CalLandmarks1 = mitk::PointSet::New(); mitk::Point3D testPt1; mitk::FillVector3D(testPt1,1,2,3); CalLandmarks1->SetPoint(0,testPt1); mitk::PointSet::Pointer RegLandmarks1 = mitk::PointSet::New(); mitk::Point3D testPt2; mitk::FillVector3D(testPt2,4,5,6); RegLandmarks1->SetPoint(5,testPt2); myTool1->SetToolCalibrationLandmarks(CalLandmarks1); myTool1->SetToolRegistrationLandmarks(RegLandmarks1); mitk::Point3D toolTipPos; mitk::FillVector3D(toolTipPos,1.3423,2.323,4.332); mitk::Quaternion toolTipRot = mitk::Quaternion(0.1,0.2,0.3,0.4); myTool1->SetToolTipPosition(toolTipPos); myTool1->SetToolTipOrientation(toolTipRot); myStorage->AddTool(myTool1); //create Serializer mitk::NavigationToolStorageSerializer::Pointer mySerializer = mitk::NavigationToolStorageSerializer::New(); //create filename std::string filename = std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+"TestStorageToolReg.storage"; //test serialization bool success = mySerializer->Serialize(filename,myStorage); MITK_TEST_CONDITION_REQUIRED(success,"Testing serialization of tool storage with tool registrations"); mitk::DataStorage::Pointer tempStorage = dynamic_cast(mitk::StandaloneDataStorage::New().GetPointer()); //needed for deserializer! mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(tempStorage); mitk::NavigationToolStorage::Pointer readStorage = myDeserializer->Deserialize(std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+"TestStorageToolReg.storage"); MITK_TEST_CONDITION_REQUIRED(readStorage.IsNotNull(),"Testing deserialization of tool storage with tool registrations"); MITK_TEST_CONDITION_REQUIRED(readStorage->GetToolCount()==1," ..Testing number of tools in storage"); mitk::PointSet::Pointer readRegLandmarks = readStorage->GetTool(0)->GetToolRegistrationLandmarks(); mitk::PointSet::Pointer readCalLandmarks = readStorage->GetTool(0)->GetToolCalibrationLandmarks(); + int val1 = readRegLandmarks->GetPoint(5)[0]; + int val2 = readRegLandmarks->GetPoint(5)[1]; + int val3 = readRegLandmarks->GetPoint(5)[2]; + std::cout << val1 << val2 << val3 << std::endl; MITK_TEST_CONDITION_REQUIRED(((readRegLandmarks->GetPoint(5)[0] == 4)&&(readRegLandmarks->GetPoint(5)[1] == 5)&&(readRegLandmarks->GetPoint(5)[2] == 6)),"..Testing if tool registration landmarks have been stored and loaded correctly."); MITK_TEST_CONDITION_REQUIRED(((readCalLandmarks->GetPoint(0)[0] == 1)&&(readCalLandmarks->GetPoint(0)[1] == 2)&&(readCalLandmarks->GetPoint(0)[2] == 3)),"..Testing if tool calibration landmarks have been stored and loaded correctly."); mitk::Point3D readToolTipPos = readStorage->GetTool(0)->GetToolTipPosition(); mitk::Quaternion readToolTipRot = readStorage->GetTool(0)->GetToolTipOrientation(); MITK_TEST_CONDITION_REQUIRED(((float(readToolTipPos[0]) == float(1.3423))&& (float(readToolTipPos[1]) == float(2.323))&& (float(readToolTipPos[2]) == float(4.332))), "..Testing if tool tip position has been stored and loaded correctly."); MITK_TEST_CONDITION_REQUIRED(((float(readToolTipRot.x()) == float(0.1))&& (float(readToolTipRot.y()) == float(0.2))&& (float(readToolTipRot.z()) == float(0.3))&& (float(readToolTipRot.r()) == float(0.4))), "..Testing if tool tip orientation has been stored and loaded correctly."); } static void TestReadSimpleToolStorage() { mitk::DataStorage::Pointer tempStorage = dynamic_cast(mitk::StandaloneDataStorage::New().GetPointer()); //needed for deserializer! mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(tempStorage); mitk::NavigationToolStorage::Pointer readStorage = myDeserializer->Deserialize(std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+"TestStorage.storage"); MITK_TEST_CONDITION_REQUIRED(readStorage.IsNotNull(),"Testing deserialization of simple tool storage"); MITK_TEST_CONDITION_REQUIRED(readStorage->GetToolCount()==3," ..Testing number of tools in storage"); //TODO: why is the order of tools changed is save/load process?? bool foundtool1 = false; bool foundtool2 = false; bool foundtool3 = false; for(int i=0; i<3; i++) { if ((readStorage->GetTool(i)->GetIdentifier()=="001")) foundtool1 = true; else if ((readStorage->GetTool(i)->GetIdentifier()=="002")) foundtool2 = true; else if ((readStorage->GetTool(i)->GetIdentifier()=="003")) foundtool3 = true; } MITK_TEST_CONDITION_REQUIRED(foundtool1&&foundtool2&&foundtool3," ..Testing if identifiers of tools where saved / loaded successfully"); } static void CleanUp() { try { std::remove((std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+"TestStorage.storage").c_str()); std::remove((std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+"TestStorageToolReg.storage").c_str()); std::remove((std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+"TestStorage2.storage").c_str()); } catch(...) { MITK_INFO << "Warning: Error occured when deleting test file!"; } } static void TestWriteComplexToolStorage() { //create first tool mitk::Surface::Pointer testSurface; std::string toolFileName(MITK_IGT_DATA_DIR); toolFileName.append("/ClaronTool"); mitk::NavigationTool::Pointer myNavigationTool = mitk::NavigationTool::New(); myNavigationTool->SetCalibrationFile(toolFileName); mitk::DataNode::Pointer myNode = mitk::DataNode::New(); myNode->SetName("ClaronTool"); //load an stl File std::string pathToClaronTool(MITK_IGT_DATA_DIR); pathToClaronTool.append("/ClaronTool.stl"); testSurface = mitk::IOUtil::LoadSurface(pathToClaronTool); myNode->SetData(testSurface); myNavigationTool->SetDataNode(myNode); myNavigationTool->SetIdentifier("ClaronTool#1"); myNavigationTool->SetSerialNumber("0815"); myNavigationTool->SetTrackingDeviceType(mitk::ClaronMicron); myNavigationTool->SetType(mitk::NavigationTool::Fiducial); //create second tool mitk::NavigationTool::Pointer myNavigationTool2 = mitk::NavigationTool::New(); mitk::Surface::Pointer testSurface2; mitk::DataNode::Pointer myNode2 = mitk::DataNode::New(); myNode2->SetName("AuroraTool"); //load an stl File std::string pathToEMTool(MITK_IGT_DATA_DIR); pathToEMTool.append("/EMTool.stl"); testSurface2 = mitk::IOUtil::LoadSurface(pathToEMTool); myNode2->SetData(testSurface2); myNavigationTool2->SetDataNode(myNode2); myNavigationTool2->SetIdentifier("AuroraTool#1"); myNavigationTool2->SetSerialNumber("0816"); myNavigationTool2->SetTrackingDeviceType(mitk::NDIAurora); myNavigationTool2->SetType(mitk::NavigationTool::Instrument); //create navigation tool storage mitk::NavigationToolStorage::Pointer myStorage = mitk::NavigationToolStorage::New(); myStorage->AddTool(myNavigationTool); myStorage->AddTool(myNavigationTool2); //create Serializer mitk::NavigationToolStorageSerializer::Pointer mySerializer = mitk::NavigationToolStorageSerializer::New(); //create filename std::string filename = std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+"TestStorage2.storage"; //test serialization bool success = mySerializer->Serialize(filename,myStorage); MITK_TEST_CONDITION_REQUIRED(success,"Testing serialization of complex tool storage"); } static void TestReadComplexToolStorage() { mitk::DataStorage::Pointer tempStorage = dynamic_cast(mitk::StandaloneDataStorage::New().GetPointer()); //needed for deserializer! mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(tempStorage); mitk::NavigationToolStorage::Pointer readStorage = myDeserializer->Deserialize(std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+"TestStorage2.storage"); MITK_TEST_CONDITION_REQUIRED(readStorage.IsNotNull(),"Testing deserialization of complex tool storage"); MITK_TEST_CONDITION_REQUIRED(readStorage->GetToolCount()==2," ..Testing number of tools in storage"); } static void TestReadNotExistingStorage() { mitk::DataStorage::Pointer tempStorage = dynamic_cast(mitk::StandaloneDataStorage::New().GetPointer()); //needed for deserializer! mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(tempStorage); bool exceptionThrown = false; try { mitk::NavigationToolStorage::Pointer readStorage = myDeserializer->Deserialize("noStorage.tfl"); } catch (mitk::IGTException e) { exceptionThrown = true; } MITK_TEST_CONDITION_REQUIRED(exceptionThrown,"Testing if exception is thrown if a non existing storage is given for deserialization."); } static void TestReadStorageWithUnknownFiletype() { mitk::DataStorage::Pointer tempStorage = dynamic_cast(mitk::StandaloneDataStorage::New().GetPointer()); //needed for deserializer! std::string toolFileName(MITK_IGT_DATA_DIR); toolFileName.append("/ClaronTool.stl"); mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(tempStorage); bool exceptionThrown = false; try { mitk::NavigationToolStorage::Pointer readStorage = myDeserializer->Deserialize(toolFileName); } catch (mitk::IGTException e) { exceptionThrown = true; } MITK_TEST_CONDITION_REQUIRED(exceptionThrown,"Testing if exception is thrown if a wrong file type is given for deserialization."); } static void TestReadZipFileWithNoToolstorage() { mitk::DataStorage::Pointer tempStorage = dynamic_cast(mitk::StandaloneDataStorage::New().GetPointer()); //needed for deserializer! std::string toolFileName(MITK_IGT_DATA_DIR); toolFileName.append("/Empty.zip"); MITK_TEST_CONDITION(toolFileName.empty() == false, "Check if tool calibration of claron tool file exists"); mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(tempStorage); bool exceptionThrown = false; try { mitk::NavigationToolStorage::Pointer readStorage = myDeserializer->Deserialize(toolFileName); } catch (mitk::IGTException e) { exceptionThrown = true; } catch (std::exception& e) { MITK_ERROR << "Unexpected exception catched: " << e.what() << " / filename: " << toolFileName; } MITK_TEST_CONDITION_REQUIRED(exceptionThrown,"Testing if exception is thrown if a empty zip file is given for deserialization."); } static void TestWriteStorageToInvalidFile() { //create Tool Storage mitk::NavigationToolStorage::Pointer myStorage = mitk::NavigationToolStorage::New(); //first tool mitk::NavigationTool::Pointer myTool1 = mitk::NavigationTool::New(); myTool1->SetIdentifier("001"); myStorage->AddTool(myTool1); //second tool mitk::NavigationTool::Pointer myTool2 = mitk::NavigationTool::New(); myTool2->SetIdentifier("002"); myStorage->AddTool(myTool2); //third tool mitk::NavigationTool::Pointer myTool3 = mitk::NavigationTool::New(); myTool3->SetIdentifier("003"); myStorage->AddTool(myTool3); //create Serializer mitk::NavigationToolStorageSerializer::Pointer mySerializer = mitk::NavigationToolStorageSerializer::New(); //create filename #ifdef WIN32 std::string filename = "C:\342INVALIDFILE<>.storage"; //invalid filename for windows #else std::string filename = "/dsfdsf:$�$342INVALIDFILE.storage"; //invalid filename for linux #endif //test serialization bool exceptionThrown = false; try { mySerializer->Serialize(filename,myStorage); } catch(mitk::IGTException e) { exceptionThrown = true; } MITK_TEST_CONDITION_REQUIRED(exceptionThrown,"Testing if an exception is thrown if an invalid file is used."); } static void TestWriteEmptyToolStorage() { //create Tool Storage mitk::NavigationToolStorage::Pointer myStorage = mitk::NavigationToolStorage::New(); //create Serializer mitk::NavigationToolStorageSerializer::Pointer mySerializer = mitk::NavigationToolStorageSerializer::New(); std::string filename; std::string optionDirectory; std::string separator; try { //create filename separator = Poco::Path::separator(); optionDirectory = std::string( MITK_TEST_OUTPUT_DIR ); mitk::UIDGenerator myGen = mitk::UIDGenerator(); filename = std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+"TestStorage"+myGen.GetUID()+".storage"; } catch (std::exception& e) { MITK_ERROR << "File access Exception: " << e.what(); MITK_INFO << "separator: " << separator; MITK_INFO << "optionDirectory: " << optionDirectory; MITK_TEST_FAILED_MSG(<<"Could not create filename for Exceptiontest"); } //test serialization bool success = mySerializer->Serialize(filename,myStorage); MITK_TEST_CONDITION_REQUIRED(success,"Testing serialization of simple tool storage"); //clean up Poco::File file = Poco::File(filename); file.remove(); } //new tests for exception throwing of NavigationToolStorageSerializer static void TestSerializerForExceptions() { mitk::NavigationToolStorageSerializer::Pointer testSerializer = mitk::NavigationToolStorageSerializer::New(); mitk::NavigationToolStorage::Pointer myStorage = mitk::NavigationToolStorage::New(); //create an invalid filename std::string filename = std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+""; //now try to serialize an check if an exception is thrown bool ExceptionThrown = false; try { testSerializer->Serialize(filename,myStorage); } catch(mitk::IGTException) { ExceptionThrown = true; } MITK_TEST_CONDITION_REQUIRED(ExceptionThrown, "Testing serializer with invalid filename."); } //new tests for exception throwing of NavigationToolStorageDeserializer static void TestDeserializerForExceptions() { // Desearializing file with invalid name mitk::DataStorage::Pointer tempStorage = dynamic_cast(mitk::StandaloneDataStorage::New().GetPointer()); mitk::NavigationToolStorageDeserializer::Pointer testDeseralizer= mitk::NavigationToolStorageDeserializer::New(tempStorage); bool ExceptionThrown1 = false; try { mitk::NavigationToolStorage::Pointer readStorage = testDeseralizer->Deserialize("InvalidName"); } catch(mitk::IGTException) { ExceptionThrown1 = true; } MITK_TEST_CONDITION_REQUIRED(ExceptionThrown1, "Testing deserializer with invalid filename."); bool ExceptionThrown2 = false; // Deserializing of empty zip file mitk::NavigationToolStorageDeserializer::Pointer testDeseralizer2= mitk::NavigationToolStorageDeserializer::New(tempStorage); try { std::string filename(MITK_IGT_DATA_DIR); filename.append("/Empty2.zip"); mitk::NavigationToolStorage::Pointer readStorage = testDeseralizer2->Deserialize(filename); } catch(mitk::IGTException) { ExceptionThrown2 = true; } MITK_TEST_CONDITION_REQUIRED(ExceptionThrown2, "Testing deserializer method with empty zip file."); } /** This function is testing the TrackingVolume class. */ int mitkNavigationToolStorageSerializerAndDeserializerTest(int /* argc */, char* /*argv*/[]) { MITK_TEST_BEGIN("NavigationToolStorageSerializerAndDeserializer"); try{ TestInstantiationSerializer(); TestInstantiationDeserializer(); TestWriteSimpleToolStorage(); TestWriteAndReadSimpleToolStorageWithToolLandmarks(); TestReadSimpleToolStorage(); TestWriteComplexToolStorage(); TestReadComplexToolStorage(); TestReadNotExistingStorage(); TestReadStorageWithUnknownFiletype(); TestReadZipFileWithNoToolstorage(); TestWriteStorageToInvalidFile(); TestWriteEmptyToolStorage(); TestSerializerForExceptions(); TestDeserializerForExceptions(); } catch (std::exception& e) { MITK_ERROR << "exception:" << e.what(); MITK_TEST_FAILED_MSG(<<"Exception occured, test failed!"); } catch (...) { MITK_ERROR << "Unknown Exception?"; MITK_TEST_FAILED_MSG(<<"Exception occured, test failed!"); } CleanUp(); MITK_TEST_END(); } diff --git a/Modules/OpenCVVideoSupport/UI/QmitkOpenCVVideoControls.cpp b/Modules/OpenCVVideoSupport/UI/QmitkOpenCVVideoControls.cpp index c406341717..9805ec3f1d 100644 --- a/Modules/OpenCVVideoSupport/UI/QmitkOpenCVVideoControls.cpp +++ b/Modules/OpenCVVideoSupport/UI/QmitkOpenCVVideoControls.cpp @@ -1,316 +1,360 @@ /*=================================================================== 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 "QmitkOpenCVVideoControls.h" #include #include #include QmitkOpenCVVideoControls::QmitkOpenCVVideoControls( QmitkVideoBackground* _VideoBackground , QmitkRenderWindow* _RenderWindow , QWidget * parent, Qt::WindowFlags f) : QWidget(parent, f) , m_VideoBackground(0) , m_RenderWindow(0) , m_VideoSource(0) , m_Controls(new Ui::QmitkOpenCVVideoControls) , m_SliderCurrentlyMoved(false) +, m_Id("QmitkOpenCVVideoControls") { m_Controls->setupUi(this); m_Controls->FileChooser->SetFileMustExist(true); m_Controls->FileChooser->SetSelectDir(false); this->SetRenderWindow(_RenderWindow); this->SetVideoBackground(_VideoBackground); + this->FromPropertyList(); + this->GetPeristenceService()->AddPropertyListReplacedObserver(this); } QmitkOpenCVVideoControls::~QmitkOpenCVVideoControls() { if(m_VideoSource != 0 && m_VideoSource->IsCapturingEnabled()) - this->Stop(); // emulate stop + this->Stop(); // emulate stop + this->GetPeristenceService()->RemovePropertyListReplacedObserver(this); + this->ToPropertyList(); } void QmitkOpenCVVideoControls::on_UseGrabbingDeviceButton_clicked( bool /*checked=false*/ ) { m_Controls->GrabbingDevicePanel->setEnabled(true); m_Controls->VideoFilePanel->setEnabled(false); } void QmitkOpenCVVideoControls::on_UseVideoFileButton_clicked( bool /*checked=false*/ ) { m_Controls->GrabbingDevicePanel->setEnabled(false); m_Controls->VideoFilePanel->setEnabled(true); m_Controls->FileChooser->setEnabled(true); } //void QmitkOpenCVVideoControls::on_VideoProgressSlider_sliderMoved( int value ) //{ // MITK_DEBUG << "progress bar slider clicked"; // double progressRatio = static_cast(value)/static_cast(m_Controls->VideoProgressSlider->maximum()); // MITK_DEBUG << "progressRatio" << progressRatio; // m_VideoSource->SetVideoCaptureProperty(CV_CAP_PROP_POS_AVI_RATIO, progressRatio); //} void QmitkOpenCVVideoControls::on_VideoProgressSlider_sliderPressed() { m_SliderCurrentlyMoved = true; // temporary pause the video while sliding if( !m_VideoSource->GetCapturePaused() ) m_VideoSource->PauseCapturing(); MITK_DEBUG << "freezing video with old pos ratio: "<< m_VideoSource->GetVideoCaptureProperty(CV_CAP_PROP_POS_AVI_RATIO); } void QmitkOpenCVVideoControls::on_VideoProgressSlider_sliderReleased() { double progressRatio = static_cast(m_Controls->VideoProgressSlider->value()) /static_cast(m_Controls->VideoProgressSlider->maximum()); m_VideoSource->SetVideoCaptureProperty(CV_CAP_PROP_POS_AVI_RATIO, progressRatio); MITK_DEBUG << "resuming video with new pos ratio: "<< progressRatio; // resume the video ( if it was not paused by the user) if( m_VideoSource->GetCapturePaused() && m_Controls->PlayButton->isChecked() ) m_VideoSource->PauseCapturing(); m_SliderCurrentlyMoved = false; } void QmitkOpenCVVideoControls::on_RepeatVideoButton_clicked( bool checked/*=false */ ) { MITK_INFO << "repeat video clicked"; m_VideoSource->SetRepeatVideo(checked); } void QmitkOpenCVVideoControls::on_PlayButton_clicked( bool checked/*=false*/ ) { MITK_INFO << "play button clicked"; if(checked) { if( m_VideoSource->GetCapturePaused() ) { this->SwitchPlayButton(false); m_VideoSource->PauseCapturing(); } else { if(m_Controls->UseGrabbingDeviceButton->isChecked()) { m_VideoSource->SetVideoCameraInput(m_Controls->GrabbingDeviceNumber->text().toInt(),false); m_Controls->VideoFileControls->setEnabled(false); } else { m_VideoSource->SetVideoFileInput(m_Controls->FileChooser->GetFile().c_str(), m_Controls->RepeatVideoButton->isChecked(), false); m_VideoSource->SetRepeatVideo(m_Controls->RepeatVideoButton->isChecked()); m_Controls->VideoProgressSlider->setValue(0); } m_VideoSource->StartCapturing(); if(!m_VideoSource->IsCapturingEnabled()) { MITK_ERROR << "Video could not be initialized!"; m_Controls->PlayButton->setChecked(false); } else { int hertz = m_Controls->UpdateRate->text().toInt(); int updateTime = itk::Math::Round( 1000.0/hertz ); // resets the whole background m_VideoBackground->SetTimerDelay( updateTime ); m_VideoBackground->AddRenderWindow( m_RenderWindow->GetVtkRenderWindow() ); this->connect( m_VideoBackground, SIGNAL(NewFrameAvailable(mitk::VideoSource*)) , this, SLOT(NewFrameAvailable(mitk::VideoSource*))); m_VideoBackground->Enable(); this->m_Controls->StopButton->setEnabled(true); // show video file controls if(m_Controls->UseVideoFileButton->isChecked()) { m_Controls->VideoFileControls->setEnabled(true); m_Controls->RepeatVideoButton->setEnabled(true); m_Controls->VideoProgressSlider->setEnabled(true); } // show pause button this->SwitchPlayButton(false); // disable other controls m_Controls->GrabbingDevicePanel->setEnabled(false); m_Controls->VideoFilePanel->setEnabled(false); m_Controls->UseGrabbingDeviceButton->setEnabled(false); m_Controls->UseVideoFileButton->setEnabled(false); m_Controls->UpdateRatePanel->setEnabled(false); } } } else { // show pause button this->SwitchPlayButton(true); m_VideoSource->PauseCapturing(); } } void QmitkOpenCVVideoControls::on_StopButton_clicked( bool /*checked=false*/ ) { this->Stop(); } void QmitkOpenCVVideoControls::Stop() { // disable video file controls, stop button and show play button again m_Controls->UseGrabbingDeviceButton->setEnabled(true); m_Controls->UseVideoFileButton->setEnabled(true); if(m_Controls->UseGrabbingDeviceButton->isChecked()) on_UseGrabbingDeviceButton_clicked(true); else on_UseVideoFileButton_clicked(true); m_Controls->UpdateRatePanel->setEnabled(true); m_Controls->VideoFileControls->setEnabled(false); this->m_Controls->StopButton->setEnabled(false); this->SwitchPlayButton(true); if(m_VideoBackground) { m_VideoBackground->Disable(); if(m_RenderWindow) m_VideoBackground->RemoveRenderWindow( m_RenderWindow->GetVtkRenderWindow() ); this->disconnect( m_VideoBackground, SIGNAL(NewFrameAvailable(mitk::VideoSource*)) , this, SLOT(NewFrameAvailable(mitk::VideoSource*))); } if(m_VideoSource != 0) m_VideoSource->StopCapturing(); } void QmitkOpenCVVideoControls::Reset() { this->Stop(); } void QmitkOpenCVVideoControls::SwitchPlayButton(bool paused) { if(paused) { m_Controls->PlayButton->setText("Play"); m_Controls->PlayButton->setIcon( QIcon(":/OpenCVVideoSupportUI/media-playback-start.png") ); m_Controls->PlayButton->setChecked(false); } else { m_Controls->PlayButton->setText("Pause"); m_Controls->PlayButton->setIcon( QIcon(":/OpenCVVideoSupportUI/media-playback-pause.png") ); m_Controls->PlayButton->setChecked(true); } } void QmitkOpenCVVideoControls::NewFrameAvailable( mitk::VideoSource* /*videoSource*/ ) { emit NewOpenCVFrameAvailable( m_VideoSource->GetCurrentFrame() ); if(!m_SliderCurrentlyMoved) m_Controls->VideoProgressSlider->setValue( itk::Math::Round( m_VideoSource->GetVideoCaptureProperty(CV_CAP_PROP_POS_AVI_RATIO) *m_Controls->VideoProgressSlider->maximum() ) ); } void QmitkOpenCVVideoControls::SetRenderWindow( QmitkRenderWindow* _RenderWindow ) { if(m_RenderWindow == _RenderWindow) return; // In Reset() m_MultiWidget is used, set it to 0 now for avoiding errors if(_RenderWindow == 0) m_RenderWindow = 0; this->Reset(); m_RenderWindow = _RenderWindow; if(m_RenderWindow == 0) { this->setEnabled(false); } else { this->setEnabled(true); } } QmitkRenderWindow* QmitkOpenCVVideoControls::GetRenderWindow() const { return m_RenderWindow; } void QmitkOpenCVVideoControls::SetVideoBackground( QmitkVideoBackground* _VideoBackground ) { if(m_VideoBackground == _VideoBackground) return; if(m_VideoBackground != 0) this->disconnect( m_VideoBackground, SIGNAL(destroyed(QObject*)) , this, SLOT(QObjectDestroyed(QObject*))); this->Reset(); m_VideoBackground = _VideoBackground; if(m_VideoBackground == 0) { m_VideoSource = 0; MITK_WARN << "m_MultiWidget is 0"; this->setEnabled(false); } else { this->setEnabled(true); m_VideoSource = dynamic_cast(m_VideoBackground->GetVideoSource()); // preset form entries if(m_VideoSource != 0) { if(!m_VideoSource->GetVideoFileName().empty()) { m_Controls->FileChooser->SetFile( m_VideoSource->GetVideoFileName() ); on_UseGrabbingDeviceButton_clicked( false ); } else if( m_VideoSource->GetGrabbingDeviceNumber() >= 0) m_Controls->GrabbingDeviceNumber->setValue( m_VideoSource->GetGrabbingDeviceNumber() ); m_Controls->UpdateRate->setValue( m_VideoBackground->GetTimerDelay() ); this->connect( m_VideoBackground, SIGNAL(destroyed(QObject*)) , this, SLOT(QObjectDestroyed(QObject*))); } else { MITK_WARN << "m_VideoSource is 0"; this->setEnabled(false); } } } QmitkVideoBackground* QmitkOpenCVVideoControls::GetVideoBackground() const { return m_VideoBackground; } void QmitkOpenCVVideoControls::QObjectDestroyed( QObject * obj /*= 0 */ ) { if(m_VideoBackground == obj) { m_VideoSource = 0; this->SetVideoBackground(0); } } + +void QmitkOpenCVVideoControls::ToPropertyList() +{ + mitk::PropertyList::Pointer propList = this->GetPeristenceService()->GetPropertyList(m_Id); + propList->Set("deviceType", m_Controls->UseGrabbingDeviceButton->isChecked()? 0: 1); + propList->Set("grabbingDeviceNumber", m_Controls->GrabbingDeviceNumber->value()); + propList->Set("updateRate", m_Controls->UpdateRate->value()); + propList->Set("repeatVideo", m_Controls->RepeatVideoButton->isChecked()); +} + +void QmitkOpenCVVideoControls::FromPropertyList() +{ + mitk::PropertyList::Pointer propList = this->GetPeristenceService()->GetPropertyList(m_Id); + + bool repeatVideo = false; + propList->Get("repeatVideo", repeatVideo); + m_Controls->RepeatVideoButton->setChecked(repeatVideo); + + int updateRate = 25; + propList->Get("updateRate", updateRate); + m_Controls->UpdateRate->setValue(updateRate); + + int grabbingDeviceNumber = 0; + propList->Get("grabbingDeviceNumber", grabbingDeviceNumber); + m_Controls->GrabbingDeviceNumber->setValue(grabbingDeviceNumber); + + int deviceType = 0; + propList->Get("deviceType", deviceType); + if( deviceType == 0 ) + m_Controls->UseGrabbingDeviceButton->setChecked(true); + else + m_Controls->UseVideoFileButton->setChecked(true); +} + +void QmitkOpenCVVideoControls::AfterPropertyListReplaced( const std::string& id, mitk::PropertyList* propertyList ) +{ + if( id == m_Id ) + this->FromPropertyList(); +} diff --git a/Modules/OpenCVVideoSupport/UI/QmitkOpenCVVideoControls.h b/Modules/OpenCVVideoSupport/UI/QmitkOpenCVVideoControls.h index 6bd9d6ee63..4ef34105dd 100644 --- a/Modules/OpenCVVideoSupport/UI/QmitkOpenCVVideoControls.h +++ b/Modules/OpenCVVideoSupport/UI/QmitkOpenCVVideoControls.h @@ -1,100 +1,120 @@ /*=================================================================== 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 QmitkOpenCVVideoControls_h #define QmitkOpenCVVideoControls_h #include #include #include +#include class QmitkRenderWindow; class QmitkVideoBackground; namespace mitk { class VideoSource; class OpenCVVideoSource; } /// /// \brief Offers widgets to play/pause/stop a video on a certain render window with /// the use of an !initialized! QmitkVideoBackground. The QmitkVideoBackground should /// contain an OpenCVVideoSource is then owned by this widget (and deleted) /// -class MITK_OPENCVVIDEOSUPPORTUI_EXPORT QmitkOpenCVVideoControls : public QWidget +class MITK_OPENCVVIDEOSUPPORTUI_EXPORT QmitkOpenCVVideoControls : public QWidget, public mitk::PropertyListReplacedObserver { Q_OBJECT public: /// /// Construct the widget with the given render window and the given preset values /// QmitkOpenCVVideoControls(QmitkVideoBackground* _VideoBackground, QmitkRenderWindow* _RenderWindow , QWidget * parent = 0, Qt::WindowFlags f = 0); /// /// call reset if video playback is enabled here /// virtual ~QmitkOpenCVVideoControls(); /// /// sets the render window for this video player /// void SetRenderWindow(QmitkRenderWindow* _RenderWindow); /// /// returns the current render window /// QmitkRenderWindow* GetRenderWindow() const; /// /// sets the qmitkvideobackground for this /// void SetVideoBackground(QmitkVideoBackground* _VideoBackground); /// /// returns the current QmitkVideoBackground /// QmitkVideoBackground* GetVideoBackground() const; + + /// + /// calls FromPropertyList + /// + void AfterPropertyListReplaced( const std::string& id, mitk::PropertyList* propertyList ); + signals: /// /// When playback is started this informs when a new frame was grabbed /// void NewOpenCVFrameAvailable(const IplImage*); protected slots: void on_UseGrabbingDeviceButton_clicked(bool checked=false); void on_UseVideoFileButton_clicked(bool checked=false); void on_VideoProgressSlider_sliderPressed(); void on_VideoProgressSlider_sliderReleased(); void on_RepeatVideoButton_clicked( bool checked=false ); void on_PlayButton_clicked(bool checked=false); void on_StopButton_clicked(bool checked=false); void Stop(); void Reset(); void SwitchPlayButton(bool paused); void QObjectDestroyed( QObject * obj = 0 ); void NewFrameAvailable(mitk::VideoSource* videoSource); protected: QmitkVideoBackground* m_VideoBackground; QmitkRenderWindow* m_RenderWindow; mitk::OpenCVVideoSource* m_VideoSource; Ui::QmitkOpenCVVideoControls* m_Controls; bool m_SliderCurrentlyMoved; + +private: + /// + /// muellerm: persitence service implementation + /// + PERSISTENCE_GET_SERVICE_METHOD_MACRO + /// + /// muellerm: a unique id for the prop list + /// + std::string m_Id; + void ToPropertyList(); + void FromPropertyList(); + }; #endif diff --git a/Modules/Persistence/CMakeLists.txt b/Modules/Persistence/CMakeLists.txt new file mode 100644 index 0000000000..b0e15b403a --- /dev/null +++ b/Modules/Persistence/CMakeLists.txt @@ -0,0 +1,6 @@ +MITK_CREATE_MODULE( Persistence + INCLUDE_DIRS + DEPENDS SceneSerialization + AUTOLOAD_WITH Mitk +) +add_subdirectory(Testing) diff --git a/Modules/Persistence/Testing/CMakeLists.txt b/Modules/Persistence/Testing/CMakeLists.txt new file mode 100644 index 0000000000..153cd81e2e --- /dev/null +++ b/Modules/Persistence/Testing/CMakeLists.txt @@ -0,0 +1 @@ +MITK_CREATE_MODULE_TESTS() diff --git a/Modules/Persistence/Testing/files.cmake b/Modules/Persistence/Testing/files.cmake new file mode 100644 index 0000000000..0f499835b6 --- /dev/null +++ b/Modules/Persistence/Testing/files.cmake @@ -0,0 +1,8 @@ +set(MODULE_TESTS +mitkPersistenceTest.cpp +) +# Create an artificial module initializing class for +# the usServiceListenerTest.cpp +usFunctionGenerateExecutableInit(TEST_CPP_FILES + IDENTIFIER ${MODULE_NAME}TestDriver + ) \ No newline at end of file diff --git a/Modules/Persistence/Testing/mitkPersistenceTest.cpp b/Modules/Persistence/Testing/mitkPersistenceTest.cpp new file mode 100644 index 0000000000..62eb2e9498 --- /dev/null +++ b/Modules/Persistence/Testing/mitkPersistenceTest.cpp @@ -0,0 +1,164 @@ +/*=================================================================== + +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 +#include +#include +#include +#include +#include +//#include +#include + +struct PersistenceTestClass +{ + PersistenceTestClass() + : id(""), param1(1), param2(2), param3(false) + { + } + std::string id; + int param1; + double param2; + bool param3; + + PERSISTENCE_CREATE3(PersistenceTestClass, id, param1, param2, param3) +}; + +struct TestPropertyListReplacedObserver: public mitk::PropertyListReplacedObserver +{ + TestPropertyListReplacedObserver(): counter(0) {} + virtual void BeforePropertyListReplaced( const std::string& id, mitk::PropertyList* propertyList ) + { + if( id == m_Id ) + counter++; + } + + virtual void AfterPropertyListReplaced( const std::string& id, mitk::PropertyList* propertyList ) + { + if( id == m_Id ) + counter++; + } + + int counter; + std::string m_Id; +}; + +std::string testClassId = "testClass"; +int param1 = 100; +double param2 = 201.56; +bool param3 = true; + +void testParams( const PersistenceTestClass& testClass, const std::string& testClassName ) +{ + MITK_INFO << "Testing parameters of " << testClassName; + MITK_TEST_CONDITION( testClass.id == testClassId, "testClass.id (" << testClass.id << ") != testClassId (" << testClassId << ")" ); + MITK_TEST_CONDITION( testClass.param1 == param1, "testClass.param1 (" << testClass.param1 << ") != param1 (" << param1 << ")" ); + MITK_TEST_CONDITION( testClass.param2 == param2, "testClass.param2 (" << testClass.param2 << ") != param2 (" << param2 << ")" ); + MITK_TEST_CONDITION( testClass.param3 == param3, "testClass.param3 (" << testClass.param3 << ") != param3 (" << param3 << ")" ); +} + +int mitkPersistenceTest(int /*argc*/, char* /*argv*/[]) +{ + MITK_TEST_BEGIN("PersistenceTest") + // dummy load of SceneIO, otherwise PersistenceService won't be available + // mitk::SceneIO::Pointer sceneIO = mitk::SceneIO::New(); + + MITK_INFO << "Testing availability of the PersistenceService."; + PERSISTENCE_GET_SERVICE_MACRO + MITK_TEST_CONDITION_REQUIRED(persistenceService, "IPersistenceService available") + + MITK_INFO << "Initialize testable parameter values."; + + Poco::File defaultPersistenceFile(persistenceService->GetDefaultPersistenceFile()); + if( defaultPersistenceFile.exists() && persistenceService->GetAutoLoadAndSave() ) + { + MITK_INFO << "Testing auto load/save of the PersistenceService."; + + PersistenceTestClass autoLoadTestClass; + autoLoadTestClass.id = testClassId; + autoLoadTestClass.FromPropertyList(); + + testParams( autoLoadTestClass, "autoLoadTestClass" ); + } + + MITK_INFO << "Removing left-over test files."; + Poco::File testTempFile("PersistenceTestFile.mitk"); + if( testTempFile.exists() ) + testTempFile.remove(false); + + Poco::File testXmlTempFile("PersistenceTestFile.xml"); + if( testXmlTempFile.exists() ) + testXmlTempFile.remove(false); + + MITK_INFO << "Testing standard write to scene file/xml file."; + PersistenceTestClass testClass; + testClass.id = testClassId; + testClass.param1 = param1; + testClass.param2 = param2; + testClass.param3 = param3; + MITK_TEST_CONDITION_REQUIRED( testClass.Save(testTempFile.path()), "testClass.Save(testTempFile.path())"); + MITK_TEST_CONDITION_REQUIRED( testClass.Save(testXmlTempFile.path()), "testClass.Save(testTempFile.path())"); + + MITK_INFO << "Testing read from scene file."; + MITK_TEST_CONDITION_REQUIRED( persistenceService->RemovePropertyList(testClassId), "persistenceService->RemovePropertyList(testClassId)"); + PersistenceTestClass testClass2; + testClass2.id = testClassId; + MITK_TEST_CONDITION_REQUIRED( testClass2.Load(testTempFile.path()), "testClass2.Load(testTempFile.path())"); + + testParams( testClass2, "testClass2" ); + + MITK_INFO << "Testing read from xml file."; + MITK_TEST_CONDITION_REQUIRED( persistenceService->RemovePropertyList(testClassId), "persistenceService->RemovePropertyList(testClassId)"); + PersistenceTestClass testClass3; + testClass3.id = testClassId; + MITK_TEST_CONDITION_REQUIRED( testClass3.Load(testXmlTempFile.path()), "testClass3.Load(testXmlTempFile.path())"); + + testParams( testClass3, "testClass3" ); + + MITK_INFO << "Testing appendChanges functionality with scene load/write."; + MITK_TEST_CONDITION_REQUIRED( persistenceService->RemovePropertyList(testClassId), "persistenceService->RemovePropertyList(testClassId)"); + MITK_TEST_CONDITION_REQUIRED( persistenceService->Save(testTempFile.path(), true), "persistenceService->Save(testTempFile.path())"); + MITK_TEST_CONDITION_REQUIRED( persistenceService->Load(testTempFile.path()), "persistenceService->Load(testTempFile.path())"); + + PersistenceTestClass testClass4; + testClass4.id = testClassId; + testClass4.FromPropertyList(); + testParams( testClass4, "testClass4" ); + + MITK_INFO << "Testing appendChanges functionality with xml load/write."; + MITK_TEST_CONDITION_REQUIRED( persistenceService->RemovePropertyList(testClassId), "persistenceService->RemovePropertyList(testClassId)"); + MITK_TEST_CONDITION_REQUIRED( persistenceService->Save(testXmlTempFile.path(), true), "persistenceService->Save(testXmlTempFile.path())"); + MITK_TEST_CONDITION_REQUIRED( persistenceService->Load(testXmlTempFile.path()), "persistenceService->Load(testXmlTempFile.path())"); + + PersistenceTestClass testClass5; + testClass5.id = testClassId; + testClass5.FromPropertyList(); + testParams( testClass5, "testClass5" ); + + MITK_INFO << "Testing observer functionality."; + TestPropertyListReplacedObserver testObserver; + testObserver.m_Id = testClassId; + persistenceService->AddPropertyListReplacedObserver( &testObserver ); + persistenceService->Load(testTempFile.path()); + MITK_TEST_CONDITION( testObserver.counter == 2, "testObserver.counter == 2, testObserver.counter is " << testObserver.counter ); + + MITK_INFO << "Cleaning test files."; + if( testXmlTempFile.exists() ) + testXmlTempFile.remove(false); + if( testTempFile.exists() ) + testTempFile.remove(false); + + MITK_TEST_END() +} diff --git a/Modules/Persistence/files.cmake b/Modules/Persistence/files.cmake new file mode 100644 index 0000000000..9604345c04 --- /dev/null +++ b/Modules/Persistence/files.cmake @@ -0,0 +1,5 @@ +set(CPP_FILES +mitkPersistenceService.cpp +mitkPersistenceActivator.cpp +mitkPropertyListsXmlFileReaderAndWriter.cpp +) diff --git a/Modules/Persistence/mitkIPersistable.h b/Modules/Persistence/mitkIPersistable.h new file mode 100644 index 0000000000..e4b4bb483b --- /dev/null +++ b/Modules/Persistence/mitkIPersistable.h @@ -0,0 +1,35 @@ +/*=================================================================== + +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 mitkIPersistable_h +#define mitkIPersistable_h +#include + +namespace mitk +{ + /// + /// Just a base class for persistable classes + /// + class Persistence_EXPORT IPersistable + { + public: + virtual bool Save(const std::string& fileName="") = 0; + virtual bool Load(const std::string& fileName="") = 0; + virtual void SetId(const std::string& id) = 0; + virtual std::string GetId() const = 0; + }; +} + +#endif diff --git a/Modules/Persistence/mitkPersistenceActivator.cpp b/Modules/Persistence/mitkPersistenceActivator.cpp new file mode 100644 index 0000000000..d8865e3a9f --- /dev/null +++ b/Modules/Persistence/mitkPersistenceActivator.cpp @@ -0,0 +1,84 @@ +/*=================================================================== + +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 mitkPersistenceActivator_h +#define mitkPersistenceActivator_h + +// Microservices +#include +#include "mitkPersistenceService.h" +#include + +namespace mitk +{ + /// + /// installs the PersistenceService + /// runs all initial commands (setting env paths etc) + /// + class PersistenceActivator : public us::ModuleActivator + { + public: + + void Load(us::ModuleContext* context) + { + MITK_DEBUG << "PersistenceActivator::Load"; + // Registering PersistenceService as MicroService + m_PersistenceService = itk::SmartPointer(new PersistenceService()); + us::ServiceProperties _PersistenceServiceProps; + _PersistenceServiceProps["Name"] = std::string("PersistenceService"); + + m_PersistenceServiceRegistration = context->RegisterService(m_PersistenceService, _PersistenceServiceProps); + + // Load Default File in any case + m_PersistenceService->Load(); + std::string id = mitk::PersistenceService::PERSISTENCE_PROPERTYLIST_NAME; + mitk::PropertyList::Pointer propList = m_PersistenceService->GetPropertyList( id ); + bool autoLoadAndSave = true; + propList->GetBoolProperty("m_AutoLoadAndSave", autoLoadAndSave); + + if( autoLoadAndSave == false ) + { + MITK_DEBUG("mitk::PersistenceService") << "autoloading was not wished. clearing data we got so far."; + m_PersistenceService->SetAutoLoadAndSave(false); + m_PersistenceService->Clear(); + } + + } + + void Unload(us::ModuleContext* context) + { + MITK_DEBUG("PersistenceActivator") << "PersistenceActivator::Unload"; + MITK_DEBUG("PersistenceActivator") << "m_PersistenceService GetReferenceCount " << m_PersistenceService->GetReferenceCount(); + + if(m_PersistenceService->GetAutoLoadAndSave()) + m_PersistenceService->Save(); + + m_PersistenceServiceRegistration.Unregister(); + m_PersistenceService->Delete(); + MITK_DEBUG("PersistenceActivator") << "m_PersistenceService GetReferenceCount " << m_PersistenceService->GetReferenceCount(); + } + + virtual ~PersistenceActivator() + { + } + + private: + itk::SmartPointer m_PersistenceService; + us::ServiceRegistration m_PersistenceServiceRegistration; + }; +} + +US_EXPORT_MODULE_ACTIVATOR(Persistence, mitk::PersistenceActivator) +#endif diff --git a/Modules/Persistence/mitkPersistenceService.cpp b/Modules/Persistence/mitkPersistenceService.cpp new file mode 100644 index 0000000000..2fa4b531ea --- /dev/null +++ b/Modules/Persistence/mitkPersistenceService.cpp @@ -0,0 +1,340 @@ +/*=================================================================== + +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 "mitkPersistenceService.h" +#include "mitkStandaloneDataStorage.h" +#include "mitkUIDGenerator.h" +#include "mitkNodePredicateProperty.h" +#include "mitkProperties.h" +#include "usModuleContext.h" +#include "usGetModuleContext.h" +#include + +const std::string mitk::PersistenceService::PERSISTENCE_PROPERTY_NAME("PersistenceNode"); + +const std::string mitk::PersistenceService::PERSISTENCE_PROPERTYLIST_NAME("PersistenceService"); + + +mitk::PersistenceService::PersistenceService() +: m_AutoLoadAndSave( true ), m_SceneIO( SceneIO::New() ), m_PropertyListsXmlFileReaderAndWriter( PropertyListsXmlFileReaderAndWriter::New() ) +{ +} + +void mitk::PersistenceService::Clear() +{ + m_PropertyLists.clear(); + m_FileNamesToModifiedTimes.clear(); +} + +mitk::PersistenceService::~PersistenceService() +{ + MITK_DEBUG("mitk::PersistenceService") << "destructing PersistenceService"; +} + +std::string mitk::PersistenceService::GetDefaultPersistenceFile() const +{ + std::string file = "PersistentData.mitk"; + us::ModuleContext* context = us::GetModuleContext(); + std::string contextDataFile = context->GetDataFile("PersistentData.mitk"); + if( !contextDataFile.empty() ) + { + file = contextDataFile; + } + return file; +} + +mitk::PropertyList::Pointer mitk::PersistenceService::GetPropertyList( std::string& id, bool* existed ) +{ + mitk::PropertyList::Pointer propList; + + if( id.empty() ) + { + UIDGenerator uidGen; + id = uidGen.GetUID(); + } + + std::map::iterator it = m_PropertyLists.find( id ); + if( it == m_PropertyLists.end() ) + { + propList = PropertyList::New(); + m_PropertyLists[id] = propList; + if( existed ) + *existed = false; + } + else + { + propList = (*it).second; + if( existed ) + *existed = true; + } + + return propList; +} + +void mitk::PersistenceService::ClonePropertyList( mitk::PropertyList* from, mitk::PropertyList* to ) const +{ + to->Clear(); + + const std::map< std::string, BaseProperty::Pointer>* propMap = from->GetMap(); + std::map< std::string, BaseProperty::Pointer>::const_iterator propMapIt = propMap->begin(); + while( propMapIt != propMap->end() ) + { + mitk::BaseProperty::Pointer clonedProp = (*propMapIt).second->Clone(); + to->SetProperty( (*propMapIt).first, clonedProp ); + ++propMapIt; + } +} + +bool mitk::PersistenceService::Save(const std::string& fileName, bool appendChanges) +{ + bool save = false; + std::string theFile = fileName; + if(theFile.empty()) + theFile = PersistenceService::GetDefaultPersistenceFile(); + + bool xmlFile = false; + if( itksys::SystemTools::GetFilenameLastExtension(theFile.c_str()) == ".xml" ) + xmlFile = true; + + mitk::DataStorage::Pointer tempDs; + if( appendChanges ) + { + if(xmlFile == false) + { + if( itksys::SystemTools::FileExists(theFile.c_str()) ) + { + + bool load = false; + DataStorage::Pointer ds = m_SceneIO->LoadScene( theFile ); + load = (m_SceneIO->GetFailedNodes() == 0 || m_SceneIO->GetFailedNodes()->size() == 0) && (m_SceneIO->GetFailedNodes() == 0 || m_SceneIO->GetFailedProperties()->IsEmpty()); + if( !load ) + return false; + + tempDs = ds; + + } + } + else + { + tempDs = mitk::StandaloneDataStorage::New(); + if( xmlFile && appendChanges && itksys::SystemTools::FileExists(theFile.c_str()) ) + { + if( !m_PropertyListsXmlFileReaderAndWriter->ReadLists( theFile, m_PropertyLists ) ) + return false; + } + } + + this->RestorePropertyListsFromPersistentDataNodes( tempDs ); + } + else if( xmlFile == false ) + { + tempDs = mitk::StandaloneDataStorage::New(); + } + + if( xmlFile ) + { + save = m_PropertyListsXmlFileReaderAndWriter->WriteLists(theFile, m_PropertyLists); + } + + else + { + DataStorage::SetOfObjects::Pointer sceneNodes = this->GetDataNodes(tempDs); + save = m_SceneIO->SaveScene( sceneNodes.GetPointer(), tempDs, theFile ); + } + if( save ) + { + long int currentModifiedTime = itksys::SystemTools::ModifiedTime( theFile.c_str() ); + m_FileNamesToModifiedTimes[theFile] = currentModifiedTime; + } + + return save; +} + +bool mitk::PersistenceService::Load(const std::string& fileName, bool enforceReload) +{ + bool load = false; + + std::string theFile = fileName; + if(theFile.empty()) + theFile = PersistenceService::GetDefaultPersistenceFile(); + + if( !itksys::SystemTools::FileExists(theFile.c_str()) ) + return false; + + bool xmlFile = false; + if( itksys::SystemTools::GetFilenameLastExtension(theFile.c_str()) == ".xml" ) + xmlFile = true; + + if( enforceReload == false ) + { + bool loadTheFile = true; + std::map::iterator it = m_FileNamesToModifiedTimes.find( theFile ); + + long int currentModifiedTime = itksys::SystemTools::ModifiedTime( theFile.c_str() ); + if( it != m_FileNamesToModifiedTimes.end() ) + { + long int knownModifiedTime = (*it).second; + if( knownModifiedTime >= currentModifiedTime ) + { + loadTheFile = false; + } + } + if( loadTheFile ) + m_FileNamesToModifiedTimes[theFile] = currentModifiedTime; + else + return true; + } + + if( xmlFile ) + { + load = m_PropertyListsXmlFileReaderAndWriter->ReadLists(theFile, m_PropertyLists); + } + else + { + DataStorage::Pointer ds = m_SceneIO->LoadScene( theFile ); + load = (m_SceneIO->GetFailedNodes() == 0 || m_SceneIO->GetFailedNodes()->size() == 0) && (m_SceneIO->GetFailedNodes() == 0 || m_SceneIO->GetFailedProperties()->IsEmpty()); + if( load ) + { + this->RestorePropertyListsFromPersistentDataNodes( ds ); + } + } + if( !load ) + { + MITK_DEBUG("mitk::PersistenceService") << "loading of scene files failed"; + return load; + } + + return load; +} + +void mitk::PersistenceService::SetAutoLoadAndSave(bool autoLoadAndSave) +{ + m_AutoLoadAndSave = autoLoadAndSave; + std::string id = PERSISTENCE_PROPERTYLIST_NAME; + mitk::PropertyList::Pointer propList = this->GetPropertyList( id ); + propList->Set("m_AutoLoadAndSave", m_AutoLoadAndSave); + this->Save(); +} + +void mitk::PersistenceService::AddPropertyListReplacedObserver(PropertyListReplacedObserver* observer) +{ + m_PropertyListReplacedObserver.insert( observer ); +} + +void mitk::PersistenceService::RemovePropertyListReplacedObserver(PropertyListReplacedObserver* observer) +{ + m_PropertyListReplacedObserver.erase( observer ); +} + +us::ModuleContext* mitk::PersistenceService::GetModuleContext() +{ + return us::GetModuleContext(); +} + +std::string mitk::PersistenceService::GetPersistenceNodePropertyName() const +{ + return PERSISTENCE_PROPERTY_NAME; +} +mitk::DataStorage::SetOfObjects::Pointer mitk::PersistenceService::GetDataNodes(mitk::DataStorage* ds) const +{ + DataStorage::SetOfObjects::Pointer set = DataStorage::SetOfObjects::New(); + + std::map::const_iterator it = m_PropertyLists.begin(); + while( it != m_PropertyLists.end() ) + { + mitk::DataNode::Pointer node = mitk::DataNode::New(); + const std::string& name = (*it).first; + + this->ClonePropertyList( (*it).second, node->GetPropertyList() ); + + node->SetBoolProperty( PERSISTENCE_PROPERTY_NAME.c_str(), true ); + node->SetName( name ); + + ds->Add(node); + set->push_back( node ); + ++it; + } + + return set; +} + +bool mitk::PersistenceService::RestorePropertyListsFromPersistentDataNodes( const DataStorage* storage ) +{ + bool oneFound = false; + DataStorage::SetOfObjects::ConstPointer allNodes = storage->GetAll(); + for ( mitk::DataStorage::SetOfObjects::const_iterator sourceIter = allNodes->begin(); + sourceIter != allNodes->end(); + ++sourceIter ) + { + mitk::DataNode* node = *sourceIter; + bool isPersistenceNode = false; + node->GetBoolProperty( PERSISTENCE_PROPERTY_NAME.c_str(), isPersistenceNode ); + + if( isPersistenceNode ) + { + oneFound = true; + MITK_DEBUG("mitk::PersistenceService") << "isPersistenceNode was true"; + std::string name = node->GetName(); + + bool existed = false; + mitk::PropertyList::Pointer propList = this->GetPropertyList( name, &existed ); + + if( existed ) + { + MITK_DEBUG("mitk::PersistenceService") << "calling replace observer before replacing values"; + std::set::iterator it = m_PropertyListReplacedObserver.begin(); + while( it != m_PropertyListReplacedObserver.end() ) + { + (*it)->BeforePropertyListReplaced( name, propList ); + ++it; + } + } // if( existed ) + + MITK_DEBUG("mitk::PersistenceService") << "replacing values"; + + this->ClonePropertyList( node->GetPropertyList(), propList ); + + if( existed ) + { + MITK_DEBUG("mitk::PersistenceService") << "calling replace observer before replacing values"; + std::set::iterator it = m_PropertyListReplacedObserver.begin(); + while( it != m_PropertyListReplacedObserver.end() ) + { + (*it)->AfterPropertyListReplaced( name, propList ); + ++it; + } + } // if( existed ) + } // if( isPersistenceNode ) + } // for ( mitk::DataStorage::SetOfObjects::const_iterator sourceIter = allNodes->begin(); ... + + return oneFound; +} + +bool mitk::PersistenceService::GetAutoLoadAndSave() const +{ + return m_AutoLoadAndSave; +} + +bool mitk::PersistenceService::RemovePropertyList( std::string& id ) +{ + std::map::iterator it = m_PropertyLists.find( id ); + if( it != m_PropertyLists.end() ) + { + m_PropertyLists.erase(it); + return true; + } + return false; +} diff --git a/Modules/Persistence/mitkPersistenceService.h b/Modules/Persistence/mitkPersistenceService.h new file mode 100644 index 0000000000..e48775c725 --- /dev/null +++ b/Modules/Persistence/mitkPersistenceService.h @@ -0,0 +1,76 @@ +/*=================================================================== + +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 mitkPersistenceService_h +#define mitkPersistenceService_h + +#include "mitkIPersistenceService.h" +#include "mitkPropertyListsXmlFileReaderAndWriter.h" +#include +#include "mitkSceneIO.h" + +namespace mitk +{ + /// + /// implementation of the IPersistenceService + /// \see IPersistenceService + class PersistenceService: public itk::LightObject, public mitk::IPersistenceService + { + public: + static const std::string PERSISTENCE_PROPERTY_NAME; + static const std::string PERSISTENCE_PROPERTYLIST_NAME; + + static us::ModuleContext* GetModuleContext(); + + PersistenceService(); + + ~PersistenceService(); + + std::string GetDefaultPersistenceFile() const; + + mitk::PropertyList::Pointer GetPropertyList( std::string& id, bool* existed=0 ); + + bool RemovePropertyList( std::string& id ); + + std::string GetPersistenceNodePropertyName() const; + + DataStorage::SetOfObjects::Pointer GetDataNodes(DataStorage* ds=0) const; + + bool Save(const std::string& fileName="", bool appendChanges=false); + + bool Load(const std::string& fileName="", bool enforeReload=true); + + void SetAutoLoadAndSave(bool autoLoadAndSave); + + bool GetAutoLoadAndSave() const; + + void AddPropertyListReplacedObserver( PropertyListReplacedObserver* observer ); + + void RemovePropertyListReplacedObserver( PropertyListReplacedObserver* observer ); + + bool RestorePropertyListsFromPersistentDataNodes(const DataStorage* storage); + + void Clear(); + private: + void ClonePropertyList( mitk::PropertyList* from, mitk::PropertyList* to ) const; + std::map m_PropertyLists; + bool m_AutoLoadAndSave; + std::set m_PropertyListReplacedObserver; + SceneIO::Pointer m_SceneIO; + PropertyListsXmlFileReaderAndWriter::Pointer m_PropertyListsXmlFileReaderAndWriter; + std::map m_FileNamesToModifiedTimes; + }; +} +#endif diff --git a/Modules/Persistence/mitkPropertyListsXmlFileReaderAndWriter.cpp b/Modules/Persistence/mitkPropertyListsXmlFileReaderAndWriter.cpp new file mode 100644 index 0000000000..2685473070 --- /dev/null +++ b/Modules/Persistence/mitkPropertyListsXmlFileReaderAndWriter.cpp @@ -0,0 +1,256 @@ +/*=================================================================== + +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 "mitkPropertyListsXmlFileReaderAndWriter.h" +#include "mitkStandaloneDataStorage.h" +#include "mitkProperties.h" +#include +#include + +namespace mitk +{ + +const std::string mitk::PropertyListsXmlFileReaderAndWriter::PROPERTY_LIST_ID_ELEMENT_NAME("Name"); + +bool PropertyListsXmlFileReaderAndWriter::PropertyFromXmlElem(std::string& name, mitk::BaseProperty::Pointer& prop, TiXmlElement* elem) const +{ + if(!elem) + { + return false; + } + + bool readOp = false; + std::string type = ""; + readOp = elem->QueryStringAttribute("type", &type) == TIXML_SUCCESS; + if( readOp ) + readOp = elem->QueryStringAttribute("name", &name) == TIXML_SUCCESS; + else + MITK_WARN << "type" << " attribute not found in a property"; + + if( readOp ) + { + if( type == "BoolProperty" ) + { + int val = 0; + readOp = elem->QueryIntAttribute("value", &val) == TIXML_SUCCESS; + if( readOp ) + { + prop = mitk::BoolProperty::New(val==1?true: false); + } + } + else if( type == "StringProperty" ) + { + std::string val = ""; + readOp = elem->QueryStringAttribute("value", &val) == TIXML_SUCCESS; + if( readOp ) + { + prop = mitk::StringProperty::New(val); + } + } + else if( type == "IntProperty" ) + { + int val = 0; + readOp = elem->QueryIntAttribute("value", &val) == TIXML_SUCCESS; + if( readOp ) + { + prop = mitk::IntProperty::New(val); + } + } + else if( type == "DoubleProperty" ) + { + double val = 0; + readOp = elem->QueryDoubleAttribute("value", &val) == TIXML_SUCCESS; + if( readOp ) + { + prop = mitk::DoubleProperty::New(val); + } + + } + else if( type == "FloatProperty" ) + { + float val = 0; + readOp = elem->QueryFloatAttribute("value", &val) == TIXML_SUCCESS; + if( readOp ) + { + prop = mitk::FloatProperty::New(val); + } + } + else + { + readOp = false; + MITK_WARN << "type" << " attribute unknown. Only BoolProperty, StringProperty, IntProperty, DoubleProperty or FloatProperty allowed."; + } + } + else + MITK_WARN << "name" << " attribute not found in a property"; + + if( !readOp ) + MITK_WARN << "value" << " attribute not found in a property"; + + return readOp; + +} +bool PropertyListsXmlFileReaderAndWriter::PropertyToXmlElem(const std::string& name, const mitk::BaseProperty* prop, TiXmlElement* elem) const +{ + if(!prop || !elem) + { + return false; + } + + const mitk::IntProperty* intProp = 0; + const mitk::FloatProperty* floatProp = 0; + const mitk::DoubleProperty* doubleProp = 0; + const mitk::BoolProperty* boolProp = 0; + const mitk::StringProperty* stringProp = 0; + bool writeOp = true; + + if( (boolProp = dynamic_cast( prop ) ) ) + { + elem->SetAttribute("name", name); + elem->SetAttribute("value", boolProp->GetValue()? 1: 0); + elem->SetAttribute("type", "BoolProperty"); + } + else if( (stringProp = dynamic_cast( prop ) ) ) + { + elem->SetAttribute("name", name); + elem->SetAttribute("value", stringProp->GetValue()); + elem->SetAttribute("type", "StringProperty"); + } + else if( (intProp = dynamic_cast( prop ) ) ) + { + elem->SetAttribute("name", name); + elem->SetAttribute("value", intProp->GetValue()); + elem->SetAttribute("type", "IntProperty"); + } + else if( (doubleProp = dynamic_cast( prop ) ) ) + { + elem->SetAttribute("name", name); + elem->SetDoubleAttribute("value", doubleProp->GetValue()); + elem->SetAttribute("type", "DoubleProperty"); + } + else if( (floatProp = dynamic_cast( prop ) ) ) + { + elem->SetAttribute("name", name); + elem->SetDoubleAttribute("value", static_cast( floatProp->GetValue() ) ); + elem->SetAttribute("type", "FloatProperty"); + } + else + { + MITK_WARN("PropertyListImportFromXmlFile") << "Base property " << name << " is unknown"; + writeOp = false; + } + return writeOp; +} +bool PropertyListsXmlFileReaderAndWriter::WriteLists( const std::string& fileName, const std::map& _PropertyLists ) const +{ + + TiXmlDocument doc; + + TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" ); + doc.LinkEndChild( decl ); + // create root + TiXmlElement* propertyListsElem = new TiXmlElement( "PropertyLists" ); + + bool allPropsConverted = true; + std::map::const_iterator it = _PropertyLists.begin(); + while( it != _PropertyLists.end() ) + { + const std::string& id = (*it).first; + const PropertyList* propList = (*it).second; + TiXmlElement* propertyListElem = new TiXmlElement( "PropertyList" ); + propertyListElem->SetAttribute(PROPERTY_LIST_ID_ELEMENT_NAME, id); + + const std::map< std::string, BaseProperty::Pointer>* propMap = propList->GetMap(); + std::map< std::string, BaseProperty::Pointer>::const_iterator propMapIt = propMap->begin(); + while( propMapIt != propMap->end() ) + { + const std::string& propName = (*propMapIt).first; + const BaseProperty* prop = (*propMapIt).second; + TiXmlElement* propertyElem = new TiXmlElement( "Property" ); + + if( !this->PropertyToXmlElem(propName, prop, propertyElem) ) + allPropsConverted = false; + + propertyListElem->LinkEndChild(propertyElem); + ++propMapIt; + } + + propertyListsElem->LinkEndChild(propertyListElem); + ++it; + } + + doc.LinkEndChild( propertyListsElem ); + + return ( allPropsConverted && doc.SaveFile( fileName.c_str() ) ); +} +bool PropertyListsXmlFileReaderAndWriter::ReadLists( const std::string& fileName, std::map& _PropertyLists ) const +{ + // reread + TiXmlDocument doc( fileName ); + doc.LoadFile(); + + TiXmlHandle docHandle( &doc ); + TiXmlElement* elem = docHandle.FirstChildElement( "PropertyLists" ).FirstChildElement( "PropertyList" ).ToElement(); + + if(!elem) + { + MITK_WARN("PropertyListFromXml") << "Cannot find a PropertyList element (inside a PropertyLists element)"; + return false; + } + + bool opRead = false; + while(elem) + { + std::string propListId; + opRead = elem->QueryStringAttribute( PROPERTY_LIST_ID_ELEMENT_NAME.c_str(), &propListId ) == TIXML_SUCCESS; + if( !opRead ) + break; + + mitk::PropertyList::Pointer propList = mitk::PropertyList::New(); + + TiXmlElement* propElem = elem->FirstChildElement("Property"); + + while(propElem) + { + std::string name; + mitk::BaseProperty::Pointer prop; + opRead = this->PropertyFromXmlElem( name, prop, propElem ); + if(!opRead) + break; + propList->SetProperty( name, prop ); + propElem = propElem->NextSiblingElement( "Property" ); + } + + if( !opRead ) + break; + _PropertyLists[propListId] = propList; + elem = elem->NextSiblingElement( "PropertyList" ); + } + + return opRead; +} + +PropertyListsXmlFileReaderAndWriter::PropertyListsXmlFileReaderAndWriter() +{ + +} + +PropertyListsXmlFileReaderAndWriter::~PropertyListsXmlFileReaderAndWriter() +{ + +} + +} diff --git a/Modules/Persistence/mitkPropertyListsXmlFileReaderAndWriter.h b/Modules/Persistence/mitkPropertyListsXmlFileReaderAndWriter.h new file mode 100644 index 0000000000..1e78d7c97f --- /dev/null +++ b/Modules/Persistence/mitkPropertyListsXmlFileReaderAndWriter.h @@ -0,0 +1,51 @@ +/*=================================================================== + +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 mitkXmlSceneIO_h_included +#define mitkXmlSceneIO_h_included + +#include "mitkDataStorage.h" + +class TiXmlElement; + +namespace mitk +{ +class PropertyListsXmlFileReaderAndWriter; + +class PropertyListsXmlFileReaderAndWriter : public itk::Object +{ + public: + static const std::string PROPERTY_LIST_ID_ELEMENT_NAME; + + mitkClassMacro( PropertyListsXmlFileReaderAndWriter, itk::Object ); + itkNewMacro(Self); + + bool WriteLists( const std::string& fileName, const std::map& _PropertyLists ) const; + bool ReadLists( const std::string& fileName, std::map& _PropertyLists ) const; + + protected: + + PropertyListsXmlFileReaderAndWriter(); + virtual ~PropertyListsXmlFileReaderAndWriter(); + + bool PropertyFromXmlElem(std::string& name, mitk::BaseProperty::Pointer& prop, TiXmlElement* elem) const; + bool PropertyToXmlElem(const std::string& name, const mitk::BaseProperty* prop, TiXmlElement* elem) const; +}; + +} + +#endif + diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.cpp index f636194686..d1b68b44bf 100644 --- a/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.cpp +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.cpp @@ -1,123 +1,124 @@ /*=================================================================== 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 "QmitkFileOpenAction.h" #include "internal/org_mitk_gui_qt_application_Activator.h" #include #include #include #include #include #include #include #include #include #include #include class QmitkFileOpenActionPrivate { public: void init ( berry::IWorkbenchWindow::Pointer window, QmitkFileOpenAction* action ) { m_Window = window; action->setParent(static_cast(m_Window.Lock()->GetShell()->GetControl())); action->setText("&Open..."); action->setToolTip("Open data files (images, surfaces,...)"); QObject::connect(action, SIGNAL(triggered(bool)), action, SLOT(Run())); } berry::IPreferences::Pointer GetPreferences() const { berry::IPreferencesService::Pointer prefService = mitk::PluginActivator::GetInstance()->GetPreferencesService(); if (prefService.IsNotNull()) { return prefService->GetSystemPreferences()->Node("/General"); } return berry::IPreferences::Pointer(0); } QString getLastFileOpenPath() const { berry::IPreferences::Pointer prefs = GetPreferences(); if(prefs.IsNotNull()) { return QString::fromStdString(prefs->Get("LastFileOpenPath", "")); } return QString(); } void setLastFileOpenPath(const QString& path) const { berry::IPreferences::Pointer prefs = GetPreferences(); if(prefs.IsNotNull()) { prefs->Put("LastFileOpenPath", path.toStdString()); prefs->Flush(); } } bool GetOpenEditor() const { berry::IPreferences::Pointer prefs = GetPreferences(); if(prefs.IsNotNull()) { return prefs->GetBool("OpenEditor", true); } return true; } berry::IWorkbenchWindow::WeakPtr m_Window; }; QmitkFileOpenAction::QmitkFileOpenAction(berry::IWorkbenchWindow::Pointer window) : QAction(0), d(new QmitkFileOpenActionPrivate) { d->init(window, this); } QmitkFileOpenAction::QmitkFileOpenAction(const QIcon & icon, berry::IWorkbenchWindow::Pointer window) : QAction(0), d(new QmitkFileOpenActionPrivate) { d->init(window, this); this->setIcon(icon); } QmitkFileOpenAction::~QmitkFileOpenAction() { } void QmitkFileOpenAction::Run() { // Ask the user for a list of files to open QStringList fileNames = QFileDialog::getOpenFileNames(NULL, "Open", d->getLastFileOpenPath(), mitk::CoreObjectFactory::GetInstance()->GetFileExtensions()); if (fileNames.empty()) return; d->setLastFileOpenPath(fileNames.front()); + mitk::WorkbenchUtil::LoadFiles(fileNames, d->m_Window.Lock(), d->GetOpenEditor()); } diff --git a/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.cpp b/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.cpp index 36bbbf1148..e1bd200264 100644 --- a/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.cpp +++ b/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.cpp @@ -1,57 +1,66 @@ /*=================================================================== 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 "QmitkGeneralPreferencePage.h" #include +#include +#include +#include +#include +#include + QmitkGeneralPreferencePage::QmitkGeneralPreferencePage() : m_MainControl(0) { } void QmitkGeneralPreferencePage::Init(berry::IWorkbench::Pointer ) { } void QmitkGeneralPreferencePage::CreateQtControl(QWidget* parent) { //empty page m_MainControl = new QWidget(parent); + QVBoxLayout *layout = new QVBoxLayout; + layout->addStretch(); m_MainControl->setLayout(layout); + this->Update(); } QWidget* QmitkGeneralPreferencePage::GetQtControl() const { return m_MainControl; } bool QmitkGeneralPreferencePage::PerformOk() { return true; } void QmitkGeneralPreferencePage::PerformCancel() { } void QmitkGeneralPreferencePage::Update() { } diff --git a/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.h b/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.h index 202734dd0e..95f79aa38e 100644 --- a/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.h +++ b/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.h @@ -1,74 +1,75 @@ /*=================================================================== 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 QMITKGENERALPREFERENCEPAGE_H_ #define QMITKGENERALPREFERENCEPAGE_H_ #include "berryIQtPreferencePage.h" #include class QWidget; +class QCheckBox; class QmitkGeneralPreferencePage : public QObject, public berry::IQtPreferencePage { Q_OBJECT Q_INTERFACES(berry::IPreferencePage) public: /** * Default constructor */ QmitkGeneralPreferencePage(); /** * @see berry::IPreferencePage::Init(berry::IWorkbench::Pointer workbench) */ void Init(berry::IWorkbench::Pointer workbench); /** * @see berry::IPreferencePage::CreateQtControl(void* parent) */ void CreateQtControl(QWidget* widget); /** * @see berry::IPreferencePage::CreateQtControl() */ QWidget* GetQtControl() const; /** * @see berry::IPreferencePage::PerformOk() */ virtual bool PerformOk(); /** * @see berry::IPreferencePage::PerformCancel() */ virtual void PerformCancel(); /** * @see berry::IPreferencePage::Update() */ virtual void Update(); protected: - QWidget* m_MainControl; + QWidget* m_MainControl; }; #endif /* QMITKGENERALPREFERENCEPAGE_H_ */ diff --git a/Plugins/org.mitk.gui.qt.ext/src/QmitkExtFileSaveProjectAction.cpp b/Plugins/org.mitk.gui.qt.ext/src/QmitkExtFileSaveProjectAction.cpp index d92b96040a..adaddbd4db 100644 --- a/Plugins/org.mitk.gui.qt.ext/src/QmitkExtFileSaveProjectAction.cpp +++ b/Plugins/org.mitk.gui.qt.ext/src/QmitkExtFileSaveProjectAction.cpp @@ -1,164 +1,167 @@ /*=================================================================== 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 "QmitkExtFileSaveProjectAction.h" #include "internal/QmitkCommonExtPlugin.h" #include #include #include #include #include #include #include #include #include #include #include #include #include +#include +#include "berryPlatform.h" QmitkExtFileSaveProjectAction::QmitkExtFileSaveProjectAction(berry::IWorkbenchWindow::Pointer window) : QAction(0) { m_Window = window; this->setParent(static_cast(m_Window->GetShell()->GetControl())); this->setText("&Save Project..."); this->setToolTip("Save content of Data Manager as a .mitk project file"); m_Window = window; this->connect(this, SIGNAL(triggered(bool)), this, SLOT(Run())); } void QmitkExtFileSaveProjectAction::Run() { try { /** * @brief stores the last path of last saved file */ static QString m_LastPath; mitk::IDataStorageReference::Pointer dsRef; { ctkPluginContext* context = QmitkCommonExtPlugin::getContext(); mitk::IDataStorageService* dss = 0; ctkServiceReference dsServiceRef = context->getServiceReference(); if (dsServiceRef) { dss = context->getService(dsServiceRef); } if (!dss) { QString msg = "IDataStorageService service not available. Unable to open files."; MITK_WARN << msg.toStdString(); QMessageBox::warning(QApplication::activeWindow(), "Unable to open files", msg); return; } // Get the active data storage (or the default one, if none is active) dsRef = dss->GetDataStorage(); context->ungetService(dsServiceRef); } mitk::DataStorage::Pointer storage = dsRef->GetDataStorage(); QString dialogTitle = "Save MITK Scene (%1)"; QString fileName = QFileDialog::getSaveFileName(NULL, dialogTitle.arg(dsRef->GetLabel()), m_LastPath, "MITK scene files (*.mitk)", NULL ); if (fileName.isEmpty() ) return; // remember the location m_LastPath = fileName; if ( fileName.right(5) != ".mitk" ) fileName += ".mitk"; mitk::SceneIO::Pointer sceneIO = mitk::SceneIO::New(); mitk::ProgressBar::GetInstance()->AddStepsToDo(2); /* Build list of nodes that should be saved */ mitk::NodePredicateNot::Pointer isNotHelperObject = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true))); mitk::DataStorage::SetOfObjects::ConstPointer nodesToBeSaved = storage->GetSubset(isNotHelperObject); + if ( !sceneIO->SaveScene( nodesToBeSaved, storage, fileName.toStdString() ) ) { QMessageBox::information(NULL, "Scene saving", "Scene could not be written completely. Please check the log.", QMessageBox::Ok); } mitk::ProgressBar::GetInstance()->Progress(2); mitk::SceneIO::FailedBaseDataListType::ConstPointer failedNodes = sceneIO->GetFailedNodes(); if (!failedNodes->empty()) { std::stringstream ss; ss << "The following nodes could not be serialized:" << std::endl; for ( mitk::SceneIO::FailedBaseDataListType::const_iterator iter = failedNodes->begin(); iter != failedNodes->end(); ++iter ) { ss << " - "; if ( mitk::BaseData* data =(*iter)->GetData() ) { ss << data->GetNameOfClass(); } else { ss << "(NULL)"; } ss << " contained in node '" << (*iter)->GetName() << "'" << std::endl; } MITK_WARN << ss.str(); } mitk::PropertyList::ConstPointer failedProperties = sceneIO->GetFailedProperties(); if (!failedProperties->GetMap()->empty()) { std::stringstream ss; ss << "The following properties could not be serialized:" << std::endl; const mitk::PropertyList::PropertyMap* propmap = failedProperties->GetMap(); for ( mitk::PropertyList::PropertyMap::const_iterator iter = propmap->begin(); iter != propmap->end(); ++iter ) { ss << " - " << iter->second->GetNameOfClass() << " associated to key '" << iter->first << "'" << std::endl; } MITK_WARN << ss.str(); } } catch (std::exception& e) { MITK_ERROR << "Exception caught during scene saving: " << e.what(); } } diff --git a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.cpp b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.cpp index 299c8115f1..ce57e1e976 100644 --- a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.cpp +++ b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.cpp @@ -1,252 +1,255 @@ /*=================================================================== 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 "QmitkCommonExtPlugin.h" #include #include "QmitkAppInstancesPreferencePage.h" #include "QmitkInputDevicesPrefPage.h" #include "QmitkModuleView.h" #include #include #include #include #include #include #include #include #include #include #include +#include +#include "berryPlatform.h" +#include ctkPluginContext* QmitkCommonExtPlugin::_context = 0; void QmitkCommonExtPlugin::start(ctkPluginContext* context) { this->_context = context; QmitkExtRegisterClasses(); BERRY_REGISTER_EXTENSION_CLASS(QmitkAppInstancesPreferencePage, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkInputDevicesPrefPage, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkModuleView, context) if (qApp->metaObject()->indexOfSignal("messageReceived(QByteArray)") > -1) { connect(qApp, SIGNAL(messageReceived(QByteArray)), this, SLOT(handleIPCMessage(QByteArray))); } std::vector args = berry::Platform::GetApplicationArgs(); QStringList qargs; for (std::vector::const_iterator it = args.begin(); it != args.end(); ++it) { qargs << QString::fromStdString(*it); } // This is a potentially long running operation. loadDataFromDisk(qargs, true); } void QmitkCommonExtPlugin::stop(ctkPluginContext* context) { Q_UNUSED(context) this->_context = 0; } ctkPluginContext* QmitkCommonExtPlugin::getContext() { return _context; } void QmitkCommonExtPlugin::loadDataFromDisk(const QStringList &arguments, bool globalReinit) { if (!arguments.empty()) { ctkServiceReference serviceRef = _context->getServiceReference(); if (serviceRef) { mitk::IDataStorageService* dataStorageService = _context->getService(serviceRef); mitk::DataStorage::Pointer dataStorage = dataStorageService->GetDefaultDataStorage()->GetDataStorage(); int argumentsAdded = 0; for (int i = 0; i < arguments.size(); ++i) { if (arguments[i].right(5) == ".mitk") { mitk::SceneIO::Pointer sceneIO = mitk::SceneIO::New(); bool clearDataStorageFirst(false); mitk::ProgressBar::GetInstance()->AddStepsToDo(2); dataStorage = sceneIO->LoadScene( arguments[i].toLocal8Bit().constData(), dataStorage, clearDataStorageFirst ); mitk::ProgressBar::GetInstance()->Progress(2); argumentsAdded++; } else { mitk::DataNodeFactory::Pointer nodeReader = mitk::DataNodeFactory::New(); try { nodeReader->SetFileName(arguments[i].toStdString()); nodeReader->Update(); for (unsigned int j = 0 ; j < nodeReader->GetNumberOfOutputs( ); ++j) { mitk::DataNode::Pointer node = nodeReader->GetOutput(j); if (node->GetData() != 0) { dataStorage->Add(node); argumentsAdded++; } } } catch(...) { MITK_WARN << "Failed to load command line argument: " << arguments[i].toStdString(); } } } // end for each command line argument if (argumentsAdded > 0 && globalReinit) { // calculate bounding geometry mitk::RenderingManager::GetInstance()->InitializeViews(dataStorage->ComputeBoundingGeometry3D()); } } else { MITK_ERROR << "A service reference for mitk::IDataStorageService does not exist"; } } } void QmitkCommonExtPlugin::startNewInstance(const QStringList &args, const QStringList& files) { QStringList newArgs(args); #ifdef Q_OS_UNIX newArgs << QString("--") + QString::fromStdString(berry::Platform::ARG_NEWINSTANCE); #else newArgs << QString("/") + QString::fromStdString(berry::Platform::ARG_NEWINSTANCE); #endif newArgs << files; QProcess::startDetached(qApp->applicationFilePath(), newArgs); } void QmitkCommonExtPlugin::handleIPCMessage(const QByteArray& msg) { QDataStream ds(msg); QString msgType; ds >> msgType; // we only handle messages containing command line arguments if (msgType != "$cmdLineArgs") return; // activate the current workbench window berry::IWorkbenchWindow::Pointer window = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow(); QMainWindow* mainWindow = static_cast (window->GetShell()->GetControl()); mainWindow->setWindowState(mainWindow->windowState() & ~Qt::WindowMinimized); mainWindow->raise(); mainWindow->activateWindow(); // Get the preferences for the instantiation behavior berry::IPreferencesService::Pointer prefService = berry::Platform::GetServiceRegistry() .GetServiceById(berry::IPreferencesService::ID); berry::IPreferences::Pointer prefs = prefService->GetSystemPreferences()->Node("/General"); bool newInstanceAlways = prefs->GetBool("newInstance.always", false); bool newInstanceScene = prefs->GetBool("newInstance.scene", true); QStringList args; ds >> args; QStringList fileArgs; QStringList sceneArgs; Poco::Util::OptionSet os; berry::Platform::GetOptionSet(os); Poco::Util::OptionProcessor processor(os); #if !defined(POCO_OS_FAMILY_UNIX) processor.setUnixStyle(false); #endif args.pop_front(); QStringList::Iterator it = args.begin(); while (it != args.end()) { std::string name; std::string value; if (processor.process(it->toStdString(), name, value)) { ++it; } else { if (it->endsWith(".mitk")) { sceneArgs << *it; } else { fileArgs << *it; } it = args.erase(it); } } if (newInstanceAlways) { if (newInstanceScene) { startNewInstance(args, fileArgs); foreach(QString sceneFile, sceneArgs) { startNewInstance(args, QStringList(sceneFile)); } } else { fileArgs.append(sceneArgs); startNewInstance(args, fileArgs); } } else { loadDataFromDisk(fileArgs, false); if (newInstanceScene) { foreach(QString sceneFile, sceneArgs) { startNewInstance(args, QStringList(sceneFile)); } } else { loadDataFromDisk(sceneArgs, false); } } } Q_EXPORT_PLUGIN2(org_mitk_gui_qt_ext, QmitkCommonExtPlugin)