diff --git a/Core/Code/DataManagement/mitkIPersistenceService.h b/Core/Code/DataManagement/mitkIPersistenceService.h index ef6efe85d0..59923f6eca 100644 --- a/Core/Code/DataManagement/mitkIPersistenceService.h +++ b/Core/Code/DataManagement/mitkIPersistenceService.h @@ -1,203 +1,273 @@ /*=================================================================== 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: /// /// Set a default directory for storage /// static std::string CreateDefaultFileName(); /// /// Get the default directory for storage /// static void SetDefaultPersistenceFile(const std::string& defaultPersistenceFile); /// /// Set a default directory for storage /// static std::string GetDefaultPersistenceFile(); /// /// 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; /// /// \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 /// \return vector of DataNodes with the described attributes /// virtual DataStorage::SetOfObjects::Pointer GetDataNodes() 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; /// /// 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. /// *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="") = 0; /// /// Using SetAutoLoadAndSave(true) will cause the service to load/save the property lists at application /// start/stop. /// virtual void SetAutoLoadAndSave(bool autoLoadAndSave) = 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(); private: static std::string m_DefaultPersistenceFile; }; } /// MACROS FOR AUTOMATIC SAVE FUNCTION -#define PERSISTENCE_GET_MODULE_CONTEXT\ - us::ModuleContext* context = GetModuleContext(); - -#define PERSISTENCE_GET_SERVICE\ - PERSISTENCE_GET_MODULE_CONTEXT\ - us::ServiceReference persistenceServiceRef = context->GetServiceReference();\ - mitk::IPersistenceService* persistenceService = dynamic_cast ( context->GetService(persistenceServiceRef) ); - -#define PERSISTENCE_CREATE_SAVE_START(IdMemberName)\ -bool Save(const std::string& fileName="") { \ - PERSISTENCE_GET_SERVICE\ - bool noError = persistenceService != 0;\ - mitk::PropertyList::Pointer propList;\ - if( noError ) {\ - propList = persistenceService->GetPropertyList(IdMemberName); - -#define PERSISTENCE_CREATE_SAVE_END\ - }\ - noError = persistenceService->Save(fileName);\ - return noError;\ -} +#define PERSISTENCE_GET_MODULE_CONTEXT_FUNCTION\ + us::GetModuleContext() -#define PERSISTENCE_CREATE_LOAD_START(IdMemberName)\ -void SetId( const std::string& ____id ) { IdMemberName = ____id; };\ -std::string GetId() { return IdMemberName; };\ -bool Load(const std::string& fileName="") {\ - PERSISTENCE_GET_SERVICE\ - bool noError = persistenceService != 0 && persistenceService->Load(fileName);\ - if( noError ) {\ - mitk::PropertyList::Pointer propList = persistenceService->GetPropertyList(IdMemberName); +#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_CREATE_LOAD_END\ - }\ - return noError;\ -} +#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_CREATE(IdMemberName, ParamMemberName)\ - PERSISTENCE_CREATE_SAVE_START(IdMemberName)\ - propList->Set( #ParamMemberName, ParamMemberName );\ - PERSISTENCE_CREATE_SAVE_END\ - PERSISTENCE_CREATE_LOAD_START(IdMemberName)\ - noError = propList->Get( #ParamMemberName, ParamMemberName );\ - PERSISTENCE_CREATE_LOAD_END - -#define PERSISTENCE_CREATE2(IdMemberName, ParamMemberName, Param2MemberName)\ - PERSISTENCE_CREATE_SAVE_START(IdMemberName)\ - propList->Set( #ParamMemberName, ParamMemberName );\ - propList->Set( #Param2MemberName, Param2MemberName );\ - PERSISTENCE_CREATE_SAVE_END\ - PERSISTENCE_CREATE_LOAD_START(IdMemberName)\ - noError = propList->Get( #ParamMemberName, ParamMemberName );\ - if(noError)\ - noError = propList->Get( #Param2MemberName, Param2MemberName );\ - PERSISTENCE_CREATE_LOAD_END - -#define PERSISTENCE_CREATE3(IdMemberName, ParamMemberName, Param2MemberName, Param3MemberName)\ - PERSISTENCE_CREATE_SAVE_START(IdMemberName)\ - propList->Set( #ParamMemberName, ParamMemberName );\ - propList->Set( #Param2MemberName, Param2MemberName );\ - propList->Set( #Param3MemberName, Param3MemberName );\ - PERSISTENCE_CREATE_SAVE_END\ - PERSISTENCE_CREATE_LOAD_START(IdMemberName)\ - noError = propList->Get( #ParamMemberName, ParamMemberName );\ - if(noError)\ - noError = propList->Get( #Param2MemberName, Param2MemberName );\ - if(noError)\ - noError = propList->Get( #Param3MemberName, Param3MemberName );\ - PERSISTENCE_CREATE_LOAD_END - -#define PERSISTENCE_CREATE4(IdMemberName, ParamMemberName, Param2MemberName, Param3MemberName, Param4MemberName)\ - PERSISTENCE_CREATE_SAVE_START(IdMemberName)\ - propList->Set( #ParamMemberName, ParamMemberName );\ - propList->Set( #Param2MemberName, Param2MemberName );\ - propList->Set( #Param3MemberName, Param3MemberName );\ - propList->Set( #Param4MemberName, Param4MemberName );\ - PERSISTENCE_CREATE_SAVE_END\ - PERSISTENCE_CREATE_LOAD_START(IdMemberName)\ - noError = propList->Get( #ParamMemberName, ParamMemberName );\ - if(noError)\ - noError = propList->Get( #Param2MemberName, Param2MemberName );\ - if(noError)\ - noError = propList->Get( #Param3MemberName, Param3MemberName );\ +#define PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)\ +public:\ + bool Save(const std::string& fileName="")\ + {\ + mitk::IPersistenceService* persistenceService = this->GetPeristenceService();\ + bool noError = persistenceService != 0;\ + if( noError )\ + this->ToPropertyList();\ if(noError)\ - noError = propList->Get( #Param4MemberName, Param4MemberName );\ - PERSISTENCE_CREATE_LOAD_END + noError = persistenceService->Save(fileName);\ + return noError;\ + }\ + bool Load(const std::string& fileName="")\ + {\ + mitk::IPersistenceService* persistenceService = this->GetPeristenceService();\ + bool noError = persistenceService != 0 && persistenceService->Load(fileName);\ + 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);\ + propList->Set(#ID_MEMBER_NAME, 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);\ + propList->Get(#ID_MEMBER_NAME, 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) US_DECLARE_SERVICE_INTERFACE(mitk::IPersistenceService, "org.mitk.services.IPersistenceService") #endif diff --git a/Modules/OpenCVVideoSupport/UI/QmitkOpenCVVideoControls.cpp b/Modules/OpenCVVideoSupport/UI/QmitkOpenCVVideoControls.cpp index 72a65022da..4e4e764134 100644 --- a/Modules/OpenCVVideoSupport/UI/QmitkOpenCVVideoControls.cpp +++ b/Modules/OpenCVVideoSupport/UI/QmitkOpenCVVideoControls.cpp @@ -1,329 +1,373 @@ /*=================================================================== 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 , QmitkStdMultiWidget* _MultiWidget , QWidget * parent, Qt::WindowFlags f) : QWidget(parent, f) , m_VideoBackground(0) , m_MultiWidget(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->SetStdMultiWidget(_MultiWidget); 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_MultiWidget->GetRenderWindow4()->GetRenderWindow() ); this->connect( m_VideoBackground, SIGNAL(NewFrameAvailable(mitk::VideoSource*)) , this, SLOT(NewFrameAvailable(mitk::VideoSource*))); m_MultiWidget->DisableGradientBackground(); 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_MultiWidget) m_MultiWidget->EnableGradientBackground(); if(m_VideoBackground) { m_VideoBackground->Disable(); if(m_MultiWidget) m_VideoBackground->RemoveRenderWindow( m_MultiWidget->GetRenderWindow4()->GetRenderWindow() ); 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::SetStdMultiWidget( QmitkStdMultiWidget* _MultiWidget ) { if(m_MultiWidget == _MultiWidget) return; if(m_MultiWidget != 0) this->disconnect( m_MultiWidget, SIGNAL(destroyed(QObject*)) , this, SLOT(QObjectDestroyed(QObject*))); // In Reset() m_MultiWidget is used, set it to 0 now for avoiding errors if(_MultiWidget == 0) m_MultiWidget = 0; this->Reset(); m_MultiWidget = _MultiWidget; if(m_MultiWidget == 0) { MITK_WARN << "m_MultiWidget is 0"; this->setEnabled(false); } else { this->setEnabled(true); this->connect( m_MultiWidget, SIGNAL(destroyed(QObject*)) , this, SLOT(QObjectDestroyed(QObject*))); } } QmitkStdMultiWidget* QmitkOpenCVVideoControls::GetStdMultiWidget() const { return m_MultiWidget; } 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_MultiWidget == obj) this->SetStdMultiWidget(0); else 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 f967f7bffb..a95f31b1bf 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 QmitkStdMultiWidget; 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, QmitkStdMultiWidget* _MultiWidget , QWidget * parent = 0, Qt::WindowFlags f = 0); /// /// call reset if video playback is enabled here /// virtual ~QmitkOpenCVVideoControls(); /// /// sets the multiwidget for this video player /// void SetStdMultiWidget(QmitkStdMultiWidget* _MultiWidget); /// /// returns the current multiwidget /// QmitkStdMultiWidget* GetStdMultiWidget() 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; QmitkStdMultiWidget* m_MultiWidget; 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/Testing/files.cmake b/Modules/Persistence/Testing/files.cmake index cbf6894db4..0f499835b6 100644 --- a/Modules/Persistence/Testing/files.cmake +++ b/Modules/Persistence/Testing/files.cmake @@ -1,3 +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 index bb36635fa8..c304c4b635 100644 --- a/Modules/Persistence/Testing/mitkPersistenceTest.cpp +++ b/Modules/Persistence/Testing/mitkPersistenceTest.cpp @@ -1,136 +1,109 @@ /*=================================================================== 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 #include "Poco\File.h" -// redefine get module context macro -#define PERSISTENCE_GET_MODULE_CONTEXT\ - us::ModuleContext* context = mitk::PersistenceService::GetModuleContext(); - struct PersistenceTestClass { PersistenceTestClass() : id(""), param1(1), param2(2), param3(false) { } std::string id; int param1; double param2; bool param3; - PERSISTENCE_CREATE3(id, param1, param2, param3) + PERSISTENCE_CREATE3(PersistenceTestClass, id, param1, param2, param3) +}; + + +struct PersistenceTestClass2 +{ }; struct TestPropertyListReplacedObserver: public mitk::PropertyListReplacedObserver { TestPropertyListReplacedObserver(): counter(0) {} virtual void BeforePropertyListReplaced( const std::string& id, mitk::PropertyList* propertyList ) { counter++; } virtual void AfterPropertyListReplaced( const std::string& id, mitk::PropertyList* propertyList ) { counter++; } int counter; }; 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(); + Poco::File testTempFile("Test.mitk"); if( testTempFile.exists() ) testTempFile.remove(false); - PersistenceTestClass testClass; - testClass.id = "testClass"; - testClass.param1 = 100; - testClass.param2 = 200.56; - testClass.param3 = true; - MITK_TEST_CONDITION_REQUIRED( testClass.Save(), "testClass.Save()"); - MITK_TEST_CONDITION_REQUIRED( testClass.Save(testTempFile.path()), "testClass.Save(testTempFile.path())"); + MITK_TEST_BEGIN("PersistenceTest") + PersistenceTestClass testClass; + testClass.id = "testClass"; + testClass.param1 = 100; + testClass.param2 = 200.56; + testClass.param3 = true; + MITK_TEST_CONDITION_REQUIRED( testClass.Save(), "testClass.Save()"); + MITK_TEST_CONDITION_REQUIRED( testClass.Save(testTempFile.path()), "testClass.Save(testTempFile.path())"); - PersistenceTestClass testClass2; - testClass2.id = "testClass"; - MITK_TEST_CONDITION_REQUIRED( testClass2.Load(), "testClass.Load()"); + PersistenceTestClass testClass2; + testClass2.id = "testClass"; + MITK_TEST_CONDITION_REQUIRED( testClass2.Load(), "testClass2.Load()"); - MITK_TEST_CONDITION_REQUIRED( testClass.param1 == testClass2.param1, "testClass.param1 == testClass2.param1" ); - MITK_TEST_CONDITION_REQUIRED( testClass.param2 == testClass2.param2, "testClass.param2 == testClass2.param2" ); - MITK_TEST_CONDITION_REQUIRED( testClass.param3 == testClass2.param3, "testClass.param3 == testClass2.param3" ); + MITK_TEST_CONDITION_REQUIRED( testClass.param1 == testClass2.param1, "testClass.param1 == testClass2.param1" ); + MITK_TEST_CONDITION_REQUIRED( testClass.param2 == testClass2.param2, "testClass.param2 == testClass2.param2" ); + MITK_TEST_CONDITION_REQUIRED( testClass.param3 == testClass2.param3, "testClass.param3 == testClass2.param3" ); - PersistenceTestClass testClass3; - testClass3.id = "testClass"; - MITK_TEST_CONDITION_REQUIRED( testClass3.Load(testTempFile.path()), "testClass3.Load(testTempFile.path())"); + PersistenceTestClass testClass3; + testClass3.id = "testClass"; + MITK_TEST_CONDITION_REQUIRED( testClass3.Load(testTempFile.path()), "testClass3.Load(testTempFile.path())"); - MITK_TEST_CONDITION_REQUIRED( testClass.param1 == testClass3.param1, "testClass.param1 == testClass3.param1" ); - MITK_TEST_CONDITION_REQUIRED( testClass.param2 == testClass3.param2, "testClass.param2 == testClass3.param2" ); - MITK_TEST_CONDITION_REQUIRED( testClass.param3 == testClass3.param3, "testClass.param3 == testClass3.param3" ); + MITK_TEST_CONDITION_REQUIRED( testClass.param1 == testClass3.param1, "testClass.param1 == testClass3.param1" ); + MITK_TEST_CONDITION_REQUIRED( testClass.param2 == testClass3.param2, "testClass.param2 == testClass3.param2" ); + MITK_TEST_CONDITION_REQUIRED( testClass.param3 == testClass3.param3, "testClass.param3 == testClass3.param3" ); - TestPropertyListReplacedObserver testObserver; + TestPropertyListReplacedObserver testObserver; - us::ModuleContext* context = mitk::PersistenceService::GetModuleContext(); - us::ServiceReference persistenceServiceRef = context->GetServiceReference();\ - mitk::IPersistenceService* persistenceService = dynamic_cast ( context->GetService(persistenceServiceRef) ); - persistenceService->AddPropertyListReplacedObserver( &testObserver ); - persistenceService->Load(); + PERSISTENCE_GET_SERVICE_MACRO - MITK_TEST_CONDITION_REQUIRED( testObserver.counter == 2, "testObserver.counter == 2" ); + MITK_TEST_CONDITION_REQUIRED(persistenceService, "IPersistenceService available") - MITK_DEBUG << "Testing AutoSaveAndLoadFeature"; - if( testTempFile.exists() ) - testTempFile.remove(false); - mitk::IPersistenceService::SetDefaultPersistenceFile(testTempFile.path()); - std::string id = "newPropList"; - - { - itk::SmartPointer newService( new mitk::PersistenceService() ); - newService->UnRegister(); - newService->SetAutoLoadAndSave( true ); - - mitk::PropertyList::Pointer newPropList = newService->GetPropertyList(id); - newPropList->Set("testClass.id", testClass.id.c_str()); - newPropList->Set("testClass.param1", testClass.param1); - newPropList->Set("testClass.param2", testClass.param2); - newPropList->Set("testClass.param3", testClass.param3); - } - - { - itk::SmartPointer newService = itk::SmartPointer( new mitk::PersistenceService() ); - newService->UnRegister(); - mitk::PropertyList::Pointer newPropList = newService->GetPropertyList(id); - newPropList->Get("testClass2.id", testClass2.id); - newPropList->Get("testClass2.param1", testClass2.param1); - newPropList->Get("testClass2.param2", testClass2.param2); - newPropList->Get("testClass2.param3", testClass2.param3); - } - - MITK_TEST_CONDITION_REQUIRED( testClass.id == testClass2.id, "testClass.id == testClass2.id" ); - MITK_TEST_CONDITION_REQUIRED( testClass.param1 == testClass2.param1, "testClass.param1 == testClass2.param1" ); - MITK_TEST_CONDITION_REQUIRED( testClass.param2 == testClass2.param2, "testClass.param2 == testClass2.param2" ); - MITK_TEST_CONDITION_REQUIRED( testClass.param3 == testClass2.param3, "testClass.param3 == testClass2.param3" ); - - if( testTempFile.exists() ) + persistenceService->AddPropertyListReplacedObserver( &testObserver ); + persistenceService->Load(); + + MITK_TEST_CONDITION_REQUIRED( testObserver.counter == 4, "testObserver.counter == 4" ); + + if( testTempFile.exists() ) testTempFile.remove(false); - MITK_TEST_END() + MITK_TEST_END() } diff --git a/Modules/Persistence/mitkPersistenceActivator.cpp b/Modules/Persistence/mitkPersistenceActivator.cpp index c828a84b78..d8865e3a9f 100644 --- a/Modules/Persistence/mitkPersistenceActivator.cpp +++ b/Modules/Persistence/mitkPersistenceActivator.cpp @@ -1,66 +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 index 0d9c7b11e6..f2021ffe8c 100644 --- a/Modules/Persistence/mitkPersistenceService.cpp +++ b/Modules/Persistence/mitkPersistenceService.cpp @@ -1,267 +1,247 @@ /*=================================================================== 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 "Poco\File.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( false ), m_SceneIO( SceneIO::New() ) + : m_AutoLoadAndSave( true ), m_SceneIO( SceneIO::New() ) { - { - MITK_DEBUG("mitk::PersistenceService") << "constructing PersistenceService"; - } - - MITK_DEBUG("mitk::PersistenceService") << "loading PersistenceService personal persitent data"; - this->Load( IPersistenceService::GetDefaultPersistenceFile() ); - std::string id = PERSISTENCE_PROPERTYLIST_NAME; - mitk::PropertyList::Pointer propList = this->GetPropertyList( id ); - propList->GetBoolProperty("m_AutoLoadAndSave", m_AutoLoadAndSave); +} - if( m_AutoLoadAndSave == false ) - { - MITK_DEBUG("mitk::PersistenceService") << "autoloading was not wished. clearing data we got so far."; - m_PropertyLists.clear(); - } +void mitk::PersistenceService::Clear() +{ + m_PropertyLists.clear(); } mitk::PersistenceService::~PersistenceService() { MITK_DEBUG("mitk::PersistenceService") << "destructing PersistenceService"; - if(m_AutoLoadAndSave) - this->Save(); } 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 = IPersistenceService::GetDefaultPersistenceFile(); mitk::DataStorage::Pointer tempDs; if(appendChanges) { - if( !Poco::File(theFile).exists() ) + if( !itksys::SystemTools::FileExists(theFile.c_str()) ) return false; + DataStorage::Pointer ds = m_SceneIO->LoadScene( theFile ); bool 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(); - DataStorage::SetOfObjects::Pointer nodes = this->GetDataNodes(); - DataStorage::SetOfObjects::iterator it = nodes->begin(); - while( it != nodes->end() ) - { - mitk::DataNode::Pointer node = *it; - tempDs->Add(node); + DataStorage::SetOfObjects::Pointer rs = DataStorage::SetOfObjects::New(); - ++it; - } - - mitk::NodePredicateProperty::Pointer pred = - mitk::NodePredicateProperty::New(PERSISTENCE_PROPERTY_NAME.c_str(), mitk::BoolProperty::New(true)); - - mitk::DataStorage::SetOfObjects::ConstPointer rs = tempDs->GetSubset(pred); - - return m_SceneIO->SaveScene( rs, tempDs, theFile ); + return m_SceneIO->SaveScene( rs.GetPointer(), tempDs, theFile ); } bool mitk::PersistenceService::Load(const std::string& fileName) { bool load = false; std::string theFile = fileName; if(theFile.empty()) theFile = IPersistenceService::GetDefaultPersistenceFile(); - if( !Poco::File(theFile).exists() ) + + if( !itksys::SystemTools::FileExists(theFile.c_str()) ) return 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 ) { MITK_DEBUG("mitk::PersistenceService") << "loading of scene files failed"; return load; } - this->RestorePropertyListsFromPersistentDataNodes(ds); - 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 { 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() ); set->push_back( node ); ++it; } return set; } bool mitk::PersistenceService::RestorePropertyListsFromPersistentDataNodes( 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; +} diff --git a/Modules/Persistence/mitkPersistenceService.h b/Modules/Persistence/mitkPersistenceService.h index 89720371b3..a251ebe35e 100644 --- a/Modules/Persistence/mitkPersistenceService.h +++ b/Modules/Persistence/mitkPersistenceService.h @@ -1,66 +1,69 @@ /*=================================================================== 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 "PersistenceExports.h" #include #include "mitkSceneIO.h" namespace mitk { /// /// implementation of the IPersistenceService /// \see IPersistenceService - class Persistence_EXPORT PersistenceService: public itk::LightObject, public mitk::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(); mitk::PropertyList::Pointer GetPropertyList( std::string& id, bool* existed=0 ); std::string GetPersistenceNodePropertyName() const; DataStorage::SetOfObjects::Pointer GetDataNodes() const; bool Save(const std::string& fileName="", bool appendChanges=false); bool Load(const std::string& fileName=""); void SetAutoLoadAndSave(bool autoLoadAndSave); + bool GetAutoLoadAndSave() const; + void AddPropertyListReplacedObserver( PropertyListReplacedObserver* observer ); void RemovePropertyListReplacedObserver( PropertyListReplacedObserver* observer ); bool RestorePropertyListsFromPersistentDataNodes(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; }; } #endif diff --git a/Modules/SceneSerialization/mitkSceneIO.cpp b/Modules/SceneSerialization/mitkSceneIO.cpp index 0834675912..c79a276866 100644 --- a/Modules/SceneSerialization/mitkSceneIO.cpp +++ b/Modules/SceneSerialization/mitkSceneIO.cpp @@ -1,613 +1,633 @@ /*=================================================================== 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 -bool mitk::SceneIO::m_SavePersistentDataWithScene(false); -bool mitk::SceneIO::m_LoadPersistentDataWithScene(false); - 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; } - if( m_LoadPersistentDataWithScene ) + // 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::ModuleContext* context = us::GetModuleContext(); us::ServiceReference persistenceServiceRef - = context->GetServiceReference();\ - mitk::IPersistenceService* persistenceService - = dynamic_cast ( context->GetService(persistenceServiceRef) ); - persistenceService->RestorePropertyListsFromPersistentDataNodes(storage); + = 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, const std::string& filename) { if (!sceneNodes2) { 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; - if( m_SavePersistentDataWithScene ) + us::ModuleContext* context = us::GetModuleContext(); + mitk::IPersistenceService* persistenceService = 0; + if( context ) { - us::ModuleContext* context = us::GetModuleContext(); us::ServiceReference persistenceServiceRef - = context->GetServiceReference();\ - mitk::IPersistenceService* persistenceService + = 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; - sceneNodes->push_back(node); - storage->Add(node); + 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() << "'"; + 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 ); 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; + 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 ); return false; // ok? } } catch(std::exception& e) { - MITK_ERROR << "Could not create ZIP file from " << m_WorkingDirectory << "\nReason: " << e.what(); + 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 ); 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() << "'"; + 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 ); 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(); -} - -void mitk::SceneIO::SetSavePersistentDataWithScene( bool savePersistentDataWithScene ) -{ - - m_SavePersistentDataWithScene = savePersistentDataWithScene; -} - -void mitk::SceneIO::SetLoadPersistentDataWithScene( bool loadPersistentDataWithScene ) -{ - m_LoadPersistentDataWithScene = loadPersistentDataWithScene; -} +} \ No newline at end of file diff --git a/Modules/SceneSerialization/mitkSceneIO.h b/Modules/SceneSerialization/mitkSceneIO.h index 0a3c1d7b0c..e39a5baa2e 100644 --- a/Modules/SceneSerialization/mitkSceneIO.h +++ b/Modules/SceneSerialization/mitkSceneIO.h @@ -1,130 +1,117 @@ /*=================================================================== 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 If set and true, SceneIO will query the PersistenceService for Data and insert it into the datastorage temporarily to save them. - * - */ - static void SetSavePersistentDataWithScene(bool savePersistentDataWithScene); - /** - * \brief If set and true, SceneIO will query the PersistenceService and insert the PropertyList of "PersistenceNodes" into the scene - * - */ - static void SetLoadPersistentDataWithScene(bool savePersistentDataWithScene); /** * \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, 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; - static bool m_SavePersistentDataWithScene; - static bool m_LoadPersistentDataWithScene; }; } #endif diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.cpp index 422c2a51cb..79af903c40 100644 --- a/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.cpp +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.cpp @@ -1,172 +1,126 @@ /*=================================================================== 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 #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()); - // muellerm, 11.12.13: added logic for persistent data inclusion - bool sceneFileLoad = false; - for( int i=0; i(berry::IPreferencesService::ID); - berry::IPreferences::Pointer prefs = prefService->GetSystemPreferences()->Node("/General"); - bool loadPersistentDataWithScene = prefs->GetBool("loadPersistentDataWithScene", false); - mitk::SceneIO::SetLoadPersistentDataWithScene(loadPersistentDataWithScene); - bool loadPersistentDataWithSceneUserAlreadyAsked = prefs->GetBool("loadPersistentDataWithSceneUserAlreadyAsked", false); - - if( !loadPersistentDataWithSceneUserAlreadyAsked ) - { - int answer = QMessageBox::question( NULL, "Load additional application data?", "Load additional application data from Scene file?
" + QString("Help: Modules and plugins of the MITK Workbench can store data in an internal database. This database can be included into scene files while saving or restored while loading a scene file. This is useful if the modules you are using support this internal database and you want to save images along with application data (e.g. settings, parameters, etc.).") - + QString::fromStdString("
Your answer will be saved and you will not be asked again. You can change this behavior later in the General Preferences Page."), - QMessageBox::Yes, - QMessageBox::No ); - - if( answer == QMessageBox::No ) - { - loadPersistentDataWithScene = false; - } - else - { - loadPersistentDataWithScene = true; - - } - loadPersistentDataWithSceneUserAlreadyAsked = true; - prefs->PutBool("loadPersistentDataWithSceneUserAlreadyAsked", loadPersistentDataWithSceneUserAlreadyAsked); - prefs->PutBool("loadPersistentDataWithScene", loadPersistentDataWithScene); - prefs->Flush(); - } - // muellerm, 11.12.13: end of changes - } - 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 37a45f69dc..6a7e57067a 100644 --- a/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.cpp +++ b/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.cpp @@ -1,99 +1,67 @@ /*=================================================================== 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); - m_SavePersistentDataWithSceneCheckBox = new QCheckBox("Save Application Data with Scene Files"); - m_LoadPersistentDataWithSceneCheckBox = new QCheckBox("Load Application Data with Scene Files"); - - QLabel* helpLabel = new QLabel("Help: Modules and plugins of the MITK Workbench can store data in an internal database. This database can be included into scene files while saving or restored while loading a scene file. This is useful if the modules you are using support this internal database and you want to save images along with application data (e.g. settings, parameters, etc.)."); - helpLabel->setWordWrap(true); - - QVBoxLayout *layout2 = new QVBoxLayout; - layout2->addWidget(helpLabel); - layout2->addWidget(m_SavePersistentDataWithSceneCheckBox); - layout2->addWidget(m_LoadPersistentDataWithSceneCheckBox); - - QGroupBox* persistentDataGb = new QGroupBox("Persistent Data handling"); - persistentDataGb->setLayout(layout2); QVBoxLayout *layout = new QVBoxLayout; - layout->addWidget(persistentDataGb); layout->addStretch(); m_MainControl->setLayout(layout); - - berry::IPreferencesService::Pointer prefService - = berry::Platform::GetServiceRegistry() - .GetServiceById(berry::IPreferencesService::ID); - - prefs = prefService->GetSystemPreferences()->Node("/General"); - this->Update(); } QWidget* QmitkGeneralPreferencePage::GetQtControl() const { return m_MainControl; } bool QmitkGeneralPreferencePage::PerformOk() { - prefs->PutBool("savePersistentDataWithScene", m_SavePersistentDataWithSceneCheckBox->isChecked()); - prefs->PutBool("loadPersistentDataWithScene", m_LoadPersistentDataWithSceneCheckBox->isChecked()); - - mitk::SceneIO::SetSavePersistentDataWithScene(m_SavePersistentDataWithSceneCheckBox->isChecked()); - mitk::SceneIO::SetLoadPersistentDataWithScene( m_LoadPersistentDataWithSceneCheckBox->isChecked()); - prefs->Flush(); return true; } void QmitkGeneralPreferencePage::PerformCancel() { } void QmitkGeneralPreferencePage::Update() { - bool savePersistentDataWithSceneCheckBox = prefs->GetBool("savePersistentDataWithScene", false); - bool loadPersistentDataWithSceneCheckBox = prefs->GetBool("loadPersistentDataWithScene", false); - - m_SavePersistentDataWithSceneCheckBox->setChecked(savePersistentDataWithSceneCheckBox); - m_LoadPersistentDataWithSceneCheckBox->setChecked(loadPersistentDataWithSceneCheckBox); } 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 b78607d830..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,78 +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; - QCheckBox* m_SavePersistentDataWithSceneCheckBox; - QCheckBox* m_LoadPersistentDataWithSceneCheckBox; - berry::IPreferences::Pointer prefs; }; #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 450a04fa3f..adaddbd4db 100644 --- a/Plugins/org.mitk.gui.qt.ext/src/QmitkExtFileSaveProjectAction.cpp +++ b/Plugins/org.mitk.gui.qt.ext/src/QmitkExtFileSaveProjectAction.cpp @@ -1,199 +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(); - // muellerm, 11.12.13: added logic for persistent data inclusion - berry::IPreferencesService::Pointer prefService - = berry::Platform::GetServiceRegistry() - .GetServiceById(berry::IPreferencesService::ID); - berry::IPreferences::Pointer prefs = prefService->GetSystemPreferences()->Node("/General"); - bool savePersistentDataWithScene = prefs->GetBool("savePersistentDataWithScene", false); - mitk::SceneIO::SetSavePersistentDataWithScene(savePersistentDataWithScene); - bool savePersistentDataWithSceneUserAlreadyAsked = prefs->GetBool("savePersistentDataWithSceneUserAlreadyAsked", false); - - if( !savePersistentDataWithSceneUserAlreadyAsked ) - { - int answer = QMessageBox::question( NULL, "Save additional application data?", "Save additional application data in Scene file?
" + QString("Help: Modules and plugins of the MITK Workbench can store data in an internal database. This database can be included into scene files while saving or restored while loading a scene file. This is useful if the modules you are using support this internal database and you want to save images along with application data (e.g. settings, parameters, etc.).") - + QString::fromStdString("
Your answer will be saved and you will not be asked again. You can change this behavior later in the General Preferences Page."), - QMessageBox::Yes, - QMessageBox::No ); - - if( answer == QMessageBox::No ) - { - savePersistentDataWithScene = false; - } - else - { - savePersistentDataWithScene = true; - - } - savePersistentDataWithSceneUserAlreadyAsked = true; - prefs->PutBool("savePersistentDataWithSceneUserAlreadyAsked", savePersistentDataWithSceneUserAlreadyAsked); - prefs->PutBool("savePersistentDataWithScene", savePersistentDataWithScene); - prefs->Flush(); - } - // muellerm, 11.12.13: end of changes - 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(); } }