diff --git a/Core/Code/Interfaces/mitkIPersistenceService.h b/Core/Code/Interfaces/mitkIPersistenceService.h index a75d218964..8abd88010d 100644 --- a/Core/Code/Interfaces/mitkIPersistenceService.h +++ b/Core/Code/Interfaces/mitkIPersistenceService.h @@ -1,344 +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 + /// 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() const = 0; + 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(DataStorage* storage) = 0; + 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/Modules/IGT/Testing/mitkNavigationToolStorageSerializerAndDeserializerTest.cpp b/Modules/IGT/Testing/mitkNavigationToolStorageSerializerAndDeserializerTest.cpp index 0f453eddc7..5f2d174292 100644 --- a/Modules/IGT/Testing/mitkNavigationToolStorageSerializerAndDeserializerTest.cpp +++ b/Modules/IGT/Testing/mitkNavigationToolStorageSerializerAndDeserializerTest.cpp @@ -1,462 +1,466 @@ /*=================================================================== 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 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()+".."+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()+".."+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()+".."+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()+".."+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()+".."+Poco::Path::separator()+"TestStorage.storage").c_str()); std::remove((std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+".."+Poco::Path::separator()+"TestStorageToolReg.storage").c_str()); std::remove((std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+".."+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()+".."+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()+".."+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 ); filename = std::string( MITK_TEST_OUTPUT_DIR )+Poco::Path::separator()+".."+Poco::Path::separator()+"TestStorage.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"); } //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()+".."+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("/Empty.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(); deactivated because of bug 16566 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/Persistence/Testing/mitkPersistenceTest.cpp b/Modules/Persistence/Testing/mitkPersistenceTest.cpp index d24f37fc63..b53004bd18 100644 --- a/Modules/Persistence/Testing/mitkPersistenceTest.cpp +++ b/Modules/Persistence/Testing/mitkPersistenceTest.cpp @@ -1,164 +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(); - MITK_TEST_CONDITION( testObserver.counter == 2, "testObserver.counter == 2" ); + 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/mitkPersistenceService.cpp b/Modules/Persistence/mitkPersistenceService.cpp index 8c8151cbd0..2fa4b531ea 100644 --- a/Modules/Persistence/mitkPersistenceService.cpp +++ b/Modules/Persistence/mitkPersistenceService.cpp @@ -1,329 +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"); -const std::string mitk::PersistenceService::ID_PROPERTY_NAME("id"); - 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 && xmlFile == false) + if( appendChanges ) { - if( itksys::SystemTools::FileExists(theFile.c_str()) ) + 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; + 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; + 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 + else if( xmlFile == false ) { tempDs = mitk::StandaloneDataStorage::New(); - if( xmlFile && appendChanges && itksys::SystemTools::FileExists(theFile.c_str()) ) - { - if( !m_PropertyListsXmlFileReaderAndWriter->ReadLists( theFile, m_PropertyLists ) ) - return false; - } } - DataStorage::SetOfObjects::Pointer rs = DataStorage::SetOfObjects::New(); - if( xmlFile ) { save = m_PropertyListsXmlFileReaderAndWriter->WriteLists(theFile, m_PropertyLists); } + else { - save = m_SceneIO->SaveScene( rs.GetPointer(), tempDs, theFile ); + 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() const +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 ); - node->SetStringProperty(ID_PROPERTY_NAME.c_str(), name.c_str() ); + ds->Add(node); set->push_back( node ); ++it; } return set; } -bool mitk::PersistenceService::RestorePropertyListsFromPersistentDataNodes( DataStorage* storage ) +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 ); - propList->SetStringProperty(ID_PROPERTY_NAME.c_str(), name.c_str()); - 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 index 74caa8ba22..e48775c725 100644 --- a/Modules/Persistence/mitkPersistenceService.h +++ b/Modules/Persistence/mitkPersistenceService.h @@ -1,76 +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 const std::string ID_PROPERTY_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() 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(DataStorage* storage); + 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 index 11abb78043..2685473070 100644 --- a/Modules/Persistence/mitkPropertyListsXmlFileReaderAndWriter.cpp +++ b/Modules/Persistence/mitkPropertyListsXmlFileReaderAndWriter.cpp @@ -1,254 +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("id", id); + 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( "id", &propListId ) == TIXML_SUCCESS; + 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() { } -} \ No newline at end of file +} diff --git a/Modules/Persistence/mitkPropertyListsXmlFileReaderAndWriter.h b/Modules/Persistence/mitkPropertyListsXmlFileReaderAndWriter.h index 79ecc01489..1e78d7c97f 100644 --- a/Modules/Persistence/mitkPropertyListsXmlFileReaderAndWriter.h +++ b/Modules/Persistence/mitkPropertyListsXmlFileReaderAndWriter.h @@ -1,50 +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/Modules/SceneSerialization/mitkSceneIO.cpp b/Modules/SceneSerialization/mitkSceneIO.cpp index c79a276866..e09d70ce79 100644 --- a/Modules/SceneSerialization/mitkSceneIO.cpp +++ b/Modules/SceneSerialization/mitkSceneIO.cpp @@ -1,633 +1,533 @@ /*=================================================================== 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 "mitkSceneIO.h" #include "mitkBaseDataSerializer.h" #include "mitkPropertyListSerializer.h" #include "mitkSceneReader.h" #include "mitkProgressBar.h" #include "mitkBaseRenderer.h" #include "mitkRenderingManager.h" #include "mitkStandaloneDataStorage.h" #include #include #include #include #include #include "itksys/SystemTools.hxx" -#include "mitkIPersistenceService.h" -#include mitk::SceneIO::SceneIO() :m_WorkingDirectory(""), m_UnzipErrors(0) { } mitk::SceneIO::~SceneIO() { } std::string mitk::SceneIO::CreateEmptyTempDirectory() { mitk::UIDGenerator uidGen("UID_",6); //std::string returnValue = mitk::StandardFileLocations::GetInstance()->GetOptionDirectory() + Poco::Path::separator() + "SceneIOTemp" + uidGen.GetUID(); std::string returnValue = Poco::Path::temp() + "SceneIOTemp" + uidGen.GetUID(); std::string uniquename = returnValue + Poco::Path::separator(); Poco::File tempdir( uniquename ); try { bool existsNot = tempdir.createDirectory(); if (!existsNot) { MITK_ERROR << "Warning: Directory already exitsts: " << uniquename << " (choosing another)"; returnValue = mitk::StandardFileLocations::GetInstance()->GetOptionDirectory() + Poco::Path::separator() + "SceneIOTempDirectory" + uidGen.GetUID(); uniquename = returnValue + Poco::Path::separator(); Poco::File tempdir2( uniquename ); if (!tempdir2.createDirectory()) { MITK_ERROR << "Warning: Second directory also already exitsts: " << uniquename; } } } catch( std::exception& e ) { MITK_ERROR << "Could not create temporary directory " << uniquename << ":" << e.what(); return ""; } return returnValue; } mitk::DataStorage::Pointer mitk::SceneIO::LoadScene( const std::string& filename, DataStorage* pStorage, bool clearStorageFirst ) { // prepare data storage DataStorage::Pointer storage = pStorage; if ( storage.IsNull() ) { storage = StandaloneDataStorage::New().GetPointer(); } if ( clearStorageFirst ) { try { storage->Remove( storage->GetAll() ); } catch(...) { MITK_ERROR << "DataStorage cannot be cleared properly."; } } // test input filename if ( filename.empty() ) { MITK_ERROR << "No filename given. Not possible to load scene."; return storage; } // test if filename can be read std::ifstream file( filename.c_str(), std::ios::binary ); if (!file.good()) { MITK_ERROR << "Cannot open '" << filename << "' for reading"; return storage; } // get new temporary directory m_WorkingDirectory = CreateEmptyTempDirectory(); if (m_WorkingDirectory.empty()) { MITK_ERROR << "Could not create temporary directory. Cannot open scene files."; return storage; } // unzip all filenames contents to temp dir m_UnzipErrors = 0; Poco::Zip::Decompress unzipper( file, Poco::Path( m_WorkingDirectory ) ); unzipper.EError += Poco::Delegate >(this, &SceneIO::OnUnzipError); unzipper.EOk += Poco::Delegate >(this, &SceneIO::OnUnzipOk); unzipper.decompressAllFiles(); unzipper.EError -= Poco::Delegate >(this, &SceneIO::OnUnzipError); unzipper.EOk -= Poco::Delegate >(this, &SceneIO::OnUnzipOk); if ( m_UnzipErrors ) { MITK_ERROR << "There were " << m_UnzipErrors << " errors unzipping '" << filename << "'. Will attempt to read whatever could be unzipped."; } // test if index.xml exists // parse index.xml with TinyXML TiXmlDocument document( m_WorkingDirectory + Poco::Path::separator() + "index.xml" ); if (!document.LoadFile()) { MITK_ERROR << "Could not open/read/parse " << m_WorkingDirectory << "/index.xml\nTinyXML reports: " << document.ErrorDesc() << std::endl; return storage; } SceneReader::Pointer reader = SceneReader::New(); if ( !reader->LoadScene( document, m_WorkingDirectory, storage ) ) { MITK_ERROR << "There were errors while loading scene file " << filename << ". Your data may be corrupted"; } // delete temp directory try { Poco::File deleteDir( m_WorkingDirectory ); deleteDir.remove(true); // recursive } catch(...) { MITK_ERROR << "Could not delete temporary directory " << m_WorkingDirectory; } - // muellerm, 11.12.13: added PersistenceService usage (i.e. try to load PropertyLists that are meant for internal Data storage) - us::ModuleContext* context = us::GetModuleContext(); - mitk::IPersistenceService* persistenceService = 0; - if( context ) - { - us::ServiceReference persistenceServiceRef - = context->GetServiceReference(); - if( persistenceServiceRef ) - { - persistenceService - = dynamic_cast ( context->GetService(persistenceServiceRef) ); - } - } - if( persistenceService ) - persistenceService->RestorePropertyListsFromPersistentDataNodes(storage); - else - { - MITK_WARN << "Peristence Service not found. Unable to load persisted PropertyLists from the Scene file"; - } - // muellerm, 11.12.13: end of changed code - // return new data storage, even if empty or uncomplete (return as much as possible but notify calling method) return storage; } -void mitk::SceneIO::RemoveNodes( DataStorage::SetOfObjects::ConstPointer nodesToRemove, DataStorage* storage, DataStorage::SetOfObjects::Pointer sceneNodes ) -{ - if(nodesToRemove.IsNull()) - return; - DataStorage::SetOfObjects::const_iterator it = nodesToRemove->begin(); - while( it != nodesToRemove->end() ) - { - mitk::DataNode* node = *it; - DataStorage::SetOfObjects::iterator it2 = std::find( sceneNodes->begin(), sceneNodes->end(), node ); - if( it2 != sceneNodes->end() ) - sceneNodes->erase(it2); - - storage->Remove(node); - - ++it; - } -} - -bool mitk::SceneIO::SaveScene( DataStorage::SetOfObjects::ConstPointer sceneNodes2, DataStorage* storage, +bool mitk::SceneIO::SaveScene( DataStorage::SetOfObjects::ConstPointer sceneNodes, const DataStorage* storage, const std::string& filename) { - if (!sceneNodes2) + if (!sceneNodes) { MITK_ERROR << "No set of nodes given. Not possible to save scene."; return false; } if (!storage) { MITK_ERROR << "No data storage given. Not possible to save scene."; // \TODO: Technically, it would be possible to save the nodes without their relation return false; } if ( filename.empty() ) { MITK_ERROR << "No filename given. Not possible to save scene."; return false; } - // muellerm, 11.12.13: added logic for importing persistent nodes from the PersistenceService - DataStorage::SetOfObjects::Pointer sceneNodes = DataStorage::SetOfObjects::New(); - DataStorage::SetOfObjects::const_iterator itSceneNodes2 = sceneNodes2->begin(); - while( itSceneNodes2 != sceneNodes2->end() ) - { - mitk::DataNode* node = *itSceneNodes2; - sceneNodes->push_back(node); - ++itSceneNodes2; - } - - DataStorage::SetOfObjects::Pointer persistentNodes; - us::ModuleContext* context = us::GetModuleContext(); - mitk::IPersistenceService* persistenceService = 0; - if( context ) - { - us::ServiceReference persistenceServiceRef - = context->GetServiceReference(); - if( persistenceServiceRef ) - { - persistenceService - = dynamic_cast ( context->GetService(persistenceServiceRef) ); - } - } - if( persistenceService ) - { - DataStorage::SetOfObjects::Pointer persistentNodes = persistenceService->GetDataNodes(); - DataStorage::SetOfObjects::iterator it = persistentNodes->begin(); - while( it != persistentNodes->end() ) - { - mitk::DataNode* node = *it; - if( std::find( sceneNodes->begin(), sceneNodes->end(), node) == sceneNodes->end() ) - { - sceneNodes->push_back(node); - } - if( !storage->Exists(node) ) - { - storage->Add(node); - } - ++it; - } - } - else - { - MITK_ERROR << "Peristence Service not found. Unable to load persisted PropertyLists from the Scene file"; - } - // muellerm, 11.12.13: end of changed code - try { m_FailedNodes = DataStorage::SetOfObjects::New(); m_FailedProperties = PropertyList::New(); // start XML DOM TiXmlDocument document; TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "UTF-8", "" ); // TODO what to write here? encoding? standalone would mean that we provide a DTD somewhere... document.LinkEndChild( decl ); TiXmlElement* version = new TiXmlElement("Version"); version->SetAttribute("Writer", __FILE__ ); version->SetAttribute("Revision", "$Revision: 17055 $" ); version->SetAttribute("FileVersion", 1 ); document.LinkEndChild(version); //DataStorage::SetOfObjects::ConstPointer sceneNodes = storage->GetSubset( predicate ); if ( sceneNodes.IsNull() ) { MITK_WARN << "Saving empty scene to " << filename; } else { if ( sceneNodes->size() == 0 ) { MITK_WARN << "Saving empty scene to " << filename; } MITK_INFO << "Storing scene with " << sceneNodes->size() << " objects to " << filename; m_WorkingDirectory = CreateEmptyTempDirectory(); if (m_WorkingDirectory.empty()) { MITK_ERROR << "Could not create temporary directory. Cannot create scene files."; - // muellerm, 11.12.13: removing PersistenceNodes from DataStorage that were propably added before for saving in scene (tidy up!) - this->RemoveNodes( persistentNodes.GetPointer(), storage, sceneNodes ); return false; } ProgressBar::GetInstance()->AddStepsToDo( sceneNodes->size() ); // find out about dependencies typedef std::map< DataNode*, std::string > UIDMapType; typedef std::map< DataNode*, std::list > SourcesMapType; UIDMapType nodeUIDs; // for dependencies: ID of each node SourcesMapType sourceUIDs; // for dependencies: IDs of a node's parent nodes UIDGenerator nodeUIDGen("OBJECT_"); for (DataStorage::SetOfObjects::const_iterator iter = sceneNodes->begin(); iter != sceneNodes->end(); ++iter) { DataNode* node = iter->GetPointer(); if (!node) continue; // unlikely event that we get a NULL pointer as an object for saving. just ignore // generate UIDs for all source objects DataStorage::SetOfObjects::ConstPointer sourceObjects = storage->GetSources( node ); for ( mitk::DataStorage::SetOfObjects::const_iterator sourceIter = sourceObjects->begin(); sourceIter != sourceObjects->end(); ++sourceIter ) { if ( std::find( sceneNodes->begin(), sceneNodes->end(), *sourceIter ) == sceneNodes->end() ) continue; // source is not saved, so don't generate a UID for this source // create a uid for the parent object if ( nodeUIDs[ *sourceIter ].empty() ) { nodeUIDs[ *sourceIter ] = nodeUIDGen.GetUID(); } // store this dependency for writing sourceUIDs[ node ].push_back( nodeUIDs[*sourceIter] ); } if ( nodeUIDs[ node ].empty() ) { nodeUIDs[ node ] = nodeUIDGen.GetUID(); } } // write out objects, dependencies and properties for (DataStorage::SetOfObjects::const_iterator iter = sceneNodes->begin(); iter != sceneNodes->end(); ++iter) { DataNode* node = iter->GetPointer(); if (node) { TiXmlElement* nodeElement = new TiXmlElement("node"); std::string filenameHint( node->GetName() ); filenameHint = itksys::SystemTools::MakeCindentifier(filenameHint.c_str()); // escape filename <-- only allow [A-Za-z0-9_], replace everything else with _ // store dependencies UIDMapType::iterator searchUIDIter = nodeUIDs.find(node); if ( searchUIDIter != nodeUIDs.end() ) { // store this node's ID nodeElement->SetAttribute("UID", searchUIDIter->second.c_str() ); } SourcesMapType::iterator searchSourcesIter = sourceUIDs.find(node); if ( searchSourcesIter != sourceUIDs.end() ) { // store all source IDs for ( std::list::iterator sourceUIDIter = searchSourcesIter->second.begin(); sourceUIDIter != searchSourcesIter->second.end(); ++sourceUIDIter ) { TiXmlElement* uidElement = new TiXmlElement("source"); uidElement->SetAttribute("UID", sourceUIDIter->c_str() ); nodeElement->LinkEndChild( uidElement ); } } // store basedata if ( BaseData* data = node->GetData() ) { //std::string filenameHint( node->GetName() ); bool error(false); TiXmlElement* dataElement( SaveBaseData( data, filenameHint, error ) ); // returns a reference to a file if (error) { m_FailedNodes->push_back( node ); } // store basedata properties PropertyList* propertyList = data->GetPropertyList(); if (propertyList && !propertyList->IsEmpty() ) { TiXmlElement* baseDataPropertiesElement( SavePropertyList( propertyList, filenameHint + "-data") ); // returns a reference to a file dataElement->LinkEndChild( baseDataPropertiesElement ); } nodeElement->LinkEndChild( dataElement ); } // store all renderwindow specific propertylists const RenderingManager::RenderWindowVector& allRenderWindows( RenderingManager::GetInstance()->GetAllRegisteredRenderWindows() ); for ( RenderingManager::RenderWindowVector::const_iterator rw = allRenderWindows.begin(); rw != allRenderWindows.end(); ++rw) { if (vtkRenderWindow* renderWindow = *rw) { std::string renderWindowName( mitk::BaseRenderer::GetInstance(renderWindow)->GetName() ); BaseRenderer* renderer = mitk::BaseRenderer::GetInstance(renderWindow); PropertyList* propertyList = node->GetPropertyList(renderer); if ( propertyList && !propertyList->IsEmpty() ) { TiXmlElement* renderWindowPropertiesElement( SavePropertyList( propertyList, filenameHint + "-" + renderWindowName) ); // returns a reference to a file renderWindowPropertiesElement->SetAttribute("renderwindow", renderWindowName); nodeElement->LinkEndChild( renderWindowPropertiesElement ); } } } // don't forget the renderwindow independent list PropertyList* propertyList = node->GetPropertyList(); if ( propertyList && !propertyList->IsEmpty() ) { TiXmlElement* propertiesElement( SavePropertyList( propertyList, filenameHint + "-node") ); // returns a reference to a file nodeElement->LinkEndChild( propertiesElement ); } document.LinkEndChild( nodeElement ); } else { MITK_WARN << "Ignoring NULL node during scene serialization."; } ProgressBar::GetInstance()->Progress(); } // end for all nodes } // end if sceneNodes if ( !document.SaveFile( m_WorkingDirectory + Poco::Path::separator() + "index.xml" ) ) { - MITK_ERROR << "Could not write scene to " << m_WorkingDirectory << Poco::Path::separator() << "index.xml" << "\nTinyXML reports '" << document.ErrorDesc() << "'"; - // muellerm, 11.12.13: removing PersistenceNodes from DataStorage that were propably added before for saving in scene (tidy up!) - this->RemoveNodes( persistentNodes.GetPointer(), storage, sceneNodes ); + MITK_ERROR << "Could not write scene to " << m_WorkingDirectory << Poco::Path::separator() << "index.xml" << "\nTinyXML reports '" << document.ErrorDesc() << "'"; return false; } else { try { Poco::File deleteFile( filename.c_str() ); if (deleteFile.exists()) { deleteFile.remove(); } // create zip at filename std::ofstream file( filename.c_str(), std::ios::binary | std::ios::out); if (!file.good()) { MITK_ERROR << "Could not open a zip file for writing: '" << filename << "'"; } else { Poco::Zip::Compress zipper( file, true ); Poco::Path tmpdir( m_WorkingDirectory ); zipper.addRecursive( tmpdir ); zipper.close(); } try { Poco::File deleteDir( m_WorkingDirectory ); deleteDir.remove(true); // recursive } catch(...) { - MITK_ERROR << "Could not delete temporary directory " << m_WorkingDirectory; - // muellerm, 11.12.13: removing PersistenceNodes from DataStorage that were propably added before for saving in scene (tidy up!) - this->RemoveNodes( persistentNodes.GetPointer(), storage, sceneNodes ); + MITK_ERROR << "Could not delete temporary directory " << m_WorkingDirectory; return false; // ok? } } catch(std::exception& e) { - MITK_ERROR << "Could not create ZIP file from " << m_WorkingDirectory << "\nReason: " << e.what(); - // muellerm, 11.12.13: removing PersistenceNodes from DataStorage that were propably added before for saving in scene (tidy up!) - this->RemoveNodes( persistentNodes.GetPointer(), storage, sceneNodes ); + MITK_ERROR << "Could not create ZIP file from " << m_WorkingDirectory << "\nReason: " << e.what(); return false; } - // muellerm, 11.12.13: removing PersistenceNodes from DataStorage that were propably added before for saving in scene (tidy up!) - this->RemoveNodes( persistentNodes.GetPointer(), storage, sceneNodes ); return true; } } catch(std::exception& e) { - MITK_ERROR << "Caught exception during saving temporary files to disk. Error description: '" << e.what() << "'"; - // muellerm, 11.12.13: removing PersistenceNodes from DataStorage that were propably added before for saving in scene (tidy up!) - this->RemoveNodes( persistentNodes.GetPointer(), storage, sceneNodes ); + MITK_ERROR << "Caught exception during saving temporary files to disk. Error description: '" << e.what() << "'"; return false; } } TiXmlElement* mitk::SceneIO::SaveBaseData( BaseData* data, const std::string& filenamehint, bool& error ) { assert(data); error = true; // find correct serializer // the serializer must // - create a file containing all information to recreate the BaseData object --> needs to know where to put this file (and a filename?) // - TODO what to do about writers that creates one file per timestep? TiXmlElement* element = new TiXmlElement("data"); element->SetAttribute( "type", data->GetNameOfClass() ); // construct name of serializer class std::string serializername(data->GetNameOfClass()); serializername += "Serializer"; std::list thingsThatCanSerializeThis = itk::ObjectFactoryBase::CreateAllInstance(serializername.c_str()); if (thingsThatCanSerializeThis.size() < 1) { MITK_ERROR << "No serializer found for " << data->GetNameOfClass() << ". Skipping object"; } for ( std::list::iterator iter = thingsThatCanSerializeThis.begin(); iter != thingsThatCanSerializeThis.end(); ++iter ) { if (BaseDataSerializer* serializer = dynamic_cast( iter->GetPointer() ) ) { serializer->SetData(data); serializer->SetFilenameHint(filenamehint); serializer->SetWorkingDirectory( m_WorkingDirectory ); try { std::string writtenfilename = serializer->Serialize(); element->SetAttribute("file", writtenfilename); error = false; } catch (std::exception& e) { MITK_ERROR << "Serializer " << serializer->GetNameOfClass() << " failed: " << e.what(); } break; } } return element; } TiXmlElement* mitk::SceneIO::SavePropertyList( PropertyList* propertyList, const std::string& filenamehint) { assert(propertyList); // - TODO what to do about shared properties (same object in two lists or behind several keys)? TiXmlElement* element = new TiXmlElement("properties"); // construct name of serializer class PropertyListSerializer::Pointer serializer = PropertyListSerializer::New(); serializer->SetPropertyList(propertyList); serializer->SetFilenameHint(filenamehint); serializer->SetWorkingDirectory( m_WorkingDirectory ); try { std::string writtenfilename = serializer->Serialize(); element->SetAttribute("file", writtenfilename); PropertyList::Pointer failedProperties = serializer->GetFailedProperties(); if (failedProperties.IsNotNull()) { // move failed properties to global list m_FailedProperties->ConcatenatePropertyList( failedProperties, true ); } } catch (std::exception& e) { MITK_ERROR << "Serializer " << serializer->GetNameOfClass() << " failed: " << e.what(); } return element; } const mitk::SceneIO::FailedBaseDataListType* mitk::SceneIO::GetFailedNodes() { return m_FailedNodes.GetPointer(); } const mitk::PropertyList* mitk::SceneIO::GetFailedProperties() { return m_FailedProperties; } void mitk::SceneIO::OnUnzipError(const void* /*pSender*/, std::pair& info) { ++m_UnzipErrors; MITK_ERROR << "Error while unzipping: " << info.second; } void mitk::SceneIO::OnUnzipOk(const void* /*pSender*/, std::pair& /*info*/) { // MITK_INFO << "Unzipped ok: " << info.second.toString(); -} \ No newline at end of file +} diff --git a/Modules/SceneSerialization/mitkSceneIO.h b/Modules/SceneSerialization/mitkSceneIO.h index e39a5baa2e..1706784cbd 100644 --- a/Modules/SceneSerialization/mitkSceneIO.h +++ b/Modules/SceneSerialization/mitkSceneIO.h @@ -1,117 +1,118 @@ /*=================================================================== 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 mitkSceneIO_h_included #define mitkSceneIO_h_included #include "SceneSerializationExports.h" #include "mitkDataStorage.h" #include "mitkNodePredicateBase.h" #include class TiXmlElement; namespace mitk { class BaseData; class PropertyList; class SceneSerialization_EXPORT SceneIO : public itk::Object { public: mitkClassMacro( SceneIO, itk::Object ); itkNewMacro(Self); typedef DataStorage::SetOfObjects FailedBaseDataListType; + /** * \brief Load a scene of objects from file * \return DataStorage with all scene objects and their relations. If loading failed, query GetFailedNodes() and GetFailedProperties() for more detail. * * Attempts to read the provided file and create objects with * parent/child relations into a DataStorage. * * \param filename full filename of the scene file * \param storage If given, this DataStorage is used instead of a newly created one * \param clearStorageFirst If set, the provided DataStorage will be cleared before populating it with the loaded objects */ virtual DataStorage::Pointer LoadScene( const std::string& filename, DataStorage* storage = NULL, bool clearStorageFirst = false ); /** * \brief Save a scene of objects to file * \return True if complete success, false if any problem occurred. Note that a scene file might still be written if false is returned, it just will not contain every node/property. If writing failed, query GetFailedNodes() and GetFailedProperties() for more detail. * * Attempts to write a scene file, which contains the nodes of the * provided DataStorage, their parent/child relations, and properties. * * \param storage a DataStorage containing all nodes that should be saved * \param filename full filename of the scene file * \param predicate defining which items of the datastorage to use and which not */ - virtual bool SaveScene( DataStorage::SetOfObjects::ConstPointer sceneNodes, DataStorage* storage, + virtual bool SaveScene( DataStorage::SetOfObjects::ConstPointer sceneNodes, const DataStorage* storage, const std::string& filename); /** * \brief Get a list of nodes (BaseData containers) that failed to be read/written. * * FailedBaseDataListType hold all those nodes that contain BaseData objects * which could not be read or written during the last call to LoadScene or SaveScene. */ const FailedBaseDataListType* GetFailedNodes(); /** * \brief Get a list of properties that failed to be read/written. * * Each entry corresponds to a property which could not * be (de)serialized. The properties may come from either of *
    *
  • The BaseData's PropertyList *
  • The DataNodes's PropertyList *
  • Any of a DataNodes's render window specific PropertyLists *
*/ const PropertyList* GetFailedProperties(); protected: SceneIO(); virtual ~SceneIO(); std::string CreateEmptyTempDirectory(); TiXmlElement* SaveBaseData( BaseData* data, const std::string& filenamehint, bool& error); TiXmlElement* SavePropertyList( PropertyList* propertyList, const std::string& filenamehint ); void OnUnzipError(const void* pSender, std::pair& info); void OnUnzipOk(const void* pSender, std::pair& info); - void RemoveNodes( DataStorage::SetOfObjects::ConstPointer nodesToRemove, DataStorage* storage, DataStorage::SetOfObjects::Pointer sceneNodes ); + FailedBaseDataListType::Pointer m_FailedNodes; PropertyList::Pointer m_FailedProperties; std::string m_WorkingDirectory; unsigned int m_UnzipErrors; }; } #endif diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.cpp index 43c4eadb4f..d1b68b44bf 100644 --- a/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.cpp +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.cpp @@ -1,125 +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 -#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 6a7e57067a..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,67 +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 -#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() { }