diff --git a/Modules/Persistence/mitkIPersistenceService.cpp b/Core/Code/DataManagement/mitkIPersistenceService.cpp similarity index 88% rename from Modules/Persistence/mitkIPersistenceService.cpp rename to Core/Code/DataManagement/mitkIPersistenceService.cpp index a3702551e2..2bd5d53dc4 100644 --- a/Modules/Persistence/mitkIPersistenceService.cpp +++ b/Core/Code/DataManagement/mitkIPersistenceService.cpp @@ -1,43 +1,40 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkIPersistenceService.h" -#include "Poco\Path.h" - std::string mitk::IPersistenceService::m_DefaultPersistenceFile(CreateDefaultFileName()); mitk::IPersistenceService::~IPersistenceService() { } void mitk::IPersistenceService::SetDefaultPersistenceFile( const std::string& defaultPersistenceFile ) { m_DefaultPersistenceFile = defaultPersistenceFile; } std::string mitk::IPersistenceService::GetDefaultPersistenceFile() { return m_DefaultPersistenceFile; } std::string mitk::IPersistenceService::CreateDefaultFileName() { - std::string homeDir = Poco::Path::home(); - std::string file = /*homeDir +*/ "PersistentData.mitk"; + std::string file = "PersistentData.mitk"; return file; } diff --git a/Modules/Persistence/mitkIPersistenceService.h b/Core/Code/DataManagement/mitkIPersistenceService.h similarity index 88% rename from Modules/Persistence/mitkIPersistenceService.h rename to Core/Code/DataManagement/mitkIPersistenceService.h index a28f995678..ef6efe85d0 100644 --- a/Modules/Persistence/mitkIPersistenceService.h +++ b/Core/Code/DataManagement/mitkIPersistenceService.h @@ -1,187 +1,203 @@ /*=================================================================== 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 Persistence_EXPORT IPersistenceService + 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_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_CREATE_LOAD_END\ }\ return noError;\ } #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 );\ if(noError)\ noError = propList->Get( #Param4MemberName, Param4MemberName );\ PERSISTENCE_CREATE_LOAD_END US_DECLARE_SERVICE_INTERFACE(mitk::IPersistenceService, "org.mitk.services.IPersistenceService") #endif diff --git a/Modules/Persistence/mitkPropertyListReplacedObserver.cpp b/Core/Code/DataManagement/mitkPropertyListReplacedObserver.cpp similarity index 100% rename from Modules/Persistence/mitkPropertyListReplacedObserver.cpp rename to Core/Code/DataManagement/mitkPropertyListReplacedObserver.cpp diff --git a/Modules/Persistence/mitkPropertyListReplacedObserver.h b/Core/Code/DataManagement/mitkPropertyListReplacedObserver.h similarity index 94% rename from Modules/Persistence/mitkPropertyListReplacedObserver.h rename to Core/Code/DataManagement/mitkPropertyListReplacedObserver.h index 489dddaf85..d1407f7f19 100644 --- a/Modules/Persistence/mitkPropertyListReplacedObserver.h +++ b/Core/Code/DataManagement/mitkPropertyListReplacedObserver.h @@ -1,44 +1,44 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef mitkPropertyListReplacedObserver_h #define mitkPropertyListReplacedObserver_h // mitk -#include "PersistenceExports.h" +#include #include "mitkPropertyList.h" #include namespace mitk { /// /// a PropertyListReplacedObserver gets informed as soon as a PropertyList with a given id was replaced during a Load() process /// \see IPersistenceService::AddPropertyListReplacedObserver() /// - class Persistence_EXPORT PropertyListReplacedObserver + class MITK_CORE_EXPORT PropertyListReplacedObserver { public: /// /// will be called *before* the propertyList gets replaced with new contents, i.e. propertyList still contains the old values /// virtual void BeforePropertyListReplaced( const std::string& id, mitk::PropertyList* propertyList ); /// /// will be called *after* the propertyList gets replaced with new contents, i.e. propertyList contains the new values /// virtual void AfterPropertyListReplaced( const std::string& id, mitk::PropertyList* propertyList ); }; } // namespace mitk #endif // mitkPropertyListReplacedObserver_h diff --git a/Core/Code/files.cmake b/Core/Code/files.cmake index 5da2d77692..1437116946 100644 --- a/Core/Code/files.cmake +++ b/Core/Code/files.cmake @@ -1,412 +1,414 @@ set(H_FILES Algorithms/itkImportMitkImageContainer.h Algorithms/itkImportMitkImageContainer.txx Algorithms/itkLocalVariationImageFilter.h Algorithms/itkLocalVariationImageFilter.txx Algorithms/itkMITKScalarImageToHistogramGenerator.h Algorithms/itkMITKScalarImageToHistogramGenerator.txx Algorithms/itkTotalVariationDenoisingImageFilter.h Algorithms/itkTotalVariationDenoisingImageFilter.txx Algorithms/itkTotalVariationSingleIterationImageFilter.h Algorithms/itkTotalVariationSingleIterationImageFilter.txx Algorithms/mitkBilateralFilter.h Algorithms/mitkBilateralFilter.cpp Algorithms/mitkInstantiateAccessFunctions.h Algorithms/mitkPixelTypeList.h Algorithms/mitkPPArithmeticDec.h Algorithms/mitkPPArgCount.h Algorithms/mitkPPCat.h Algorithms/mitkPPConfig.h Algorithms/mitkPPControlExprIIf.h Algorithms/mitkPPControlIf.h Algorithms/mitkPPControlIIf.h Algorithms/mitkPPDebugError.h Algorithms/mitkPPDetailAutoRec.h Algorithms/mitkPPDetailDMCAutoRec.h Algorithms/mitkPPExpand.h Algorithms/mitkPPFacilitiesEmpty.h Algorithms/mitkPPFacilitiesExpand.h Algorithms/mitkPPLogicalBool.h Algorithms/mitkPPRepetitionDetailDMCFor.h Algorithms/mitkPPRepetitionDetailEDGFor.h Algorithms/mitkPPRepetitionDetailFor.h Algorithms/mitkPPRepetitionDetailMSVCFor.h Algorithms/mitkPPRepetitionFor.h Algorithms/mitkPPSeqElem.h Algorithms/mitkPPSeqForEach.h Algorithms/mitkPPSeqForEachProduct.h Algorithms/mitkPPSeq.h Algorithms/mitkPPSeqEnum.h Algorithms/mitkPPSeqSize.h Algorithms/mitkPPSeqToTuple.h Algorithms/mitkPPStringize.h Algorithms/mitkPPTupleEat.h Algorithms/mitkPPTupleElem.h Algorithms/mitkPPTupleRem.h Algorithms/mitkClippedSurfaceBoundsCalculator.h Algorithms/mitkExtractSliceFilter.h Algorithms/mitkConvert2Dto3DImageFilter.h Algorithms/mitkPlaneClipping.h Common/mitkCommon.h Common/mitkExceptionMacro.h Common/mitkServiceBaseObject.h Common/mitkTestCaller.h Common/mitkTestFixture.h Common/mitkTesting.h Common/mitkTestingMacros.h DataManagement/mitkProportionalTimeGeometry.h DataManagement/mitkTimeGeometry.h DataManagement/mitkImageAccessByItk.h DataManagement/mitkImageCast.h DataManagement/mitkImagePixelAccessor.h DataManagement/mitkImagePixelReadAccessor.h DataManagement/mitkImagePixelWriteAccessor.h DataManagement/mitkImageReadAccessor.h DataManagement/mitkImageWriteAccessor.h DataManagement/mitkITKImageImport.h DataManagement/mitkITKImageImport.txx DataManagement/mitkImageToItk.h DataManagement/mitkImageToItk.txx DataManagement/mitkTimeSlicedGeometry.h # Deprecated, empty for compatibilty reasons. + DataManagement/mitkIPersistenceService.cpp + DataManagement/mitkPropertyListReplacedObserver.cpp Interactions/mitkEventMapperAddOn.h Interfaces/mitkIDataNodeReader.h Rendering/mitkLocalStorageHandler.h IO/mitkPixelTypeTraits.h ) set(CPP_FILES Algorithms/mitkBaseDataSource.cpp Algorithms/mitkCompareImageDataFilter.cpp Algorithms/mitkMultiComponentImageDataComparisonFilter.cpp Algorithms/mitkDataNodeSource.cpp Algorithms/mitkGeometry2DDataToSurfaceFilter.cpp Algorithms/mitkHistogramGenerator.cpp Algorithms/mitkImageChannelSelector.cpp Algorithms/mitkImageSliceSelector.cpp Algorithms/mitkImageSource.cpp Algorithms/mitkImageTimeSelector.cpp Algorithms/mitkImageToImageFilter.cpp Algorithms/mitkImageToSurfaceFilter.cpp Algorithms/mitkPointSetSource.cpp Algorithms/mitkPointSetToPointSetFilter.cpp Algorithms/mitkRGBToRGBACastImageFilter.cpp Algorithms/mitkSubImageSelector.cpp Algorithms/mitkSurfaceSource.cpp Algorithms/mitkSurfaceToImageFilter.cpp Algorithms/mitkSurfaceToSurfaceFilter.cpp Algorithms/mitkUIDGenerator.cpp Algorithms/mitkVolumeCalculator.cpp Algorithms/mitkClippedSurfaceBoundsCalculator.cpp Algorithms/mitkExtractSliceFilter.cpp Algorithms/mitkConvert2Dto3DImageFilter.cpp Controllers/mitkBaseController.cpp Controllers/mitkCallbackFromGUIThread.cpp Controllers/mitkCameraController.cpp Controllers/mitkCameraRotationController.cpp Controllers/mitkCoreActivator.cpp Controllers/mitkFocusManager.cpp Controllers/mitkLimitedLinearUndo.cpp Controllers/mitkOperationEvent.cpp Controllers/mitkPlanePositionManager.cpp Controllers/mitkProgressBar.cpp Controllers/mitkRenderingManager.cpp Controllers/mitkSliceNavigationController.cpp Controllers/mitkSlicesCoordinator.cpp Controllers/mitkSlicesRotator.cpp Controllers/mitkSlicesSwiveller.cpp Controllers/mitkStatusBar.cpp Controllers/mitkStepper.cpp Controllers/mitkTestManager.cpp Controllers/mitkUndoController.cpp Controllers/mitkVerboseLimitedLinearUndo.cpp Controllers/mitkVtkInteractorCameraController.cpp Controllers/mitkVtkLayerController.cpp DataManagement/mitkProportionalTimeGeometry.cpp DataManagement/mitkTimeGeometry.cpp DataManagement/mitkAbstractTransformGeometry.cpp DataManagement/mitkAnnotationProperty.cpp DataManagement/mitkApplicationCursor.cpp DataManagement/mitkBaseData.cpp DataManagement/mitkBaseProperty.cpp DataManagement/mitkClippingProperty.cpp DataManagement/mitkChannelDescriptor.cpp DataManagement/mitkColorProperty.cpp DataManagement/mitkDataStorage.cpp # DataManagement/mitkDataTree.cpp DataManagement/mitkDataNode.cpp DataManagement/mitkDataNodeFactory.cpp # DataManagement/mitkDataTreeStorage.cpp DataManagement/mitkDisplayGeometry.cpp DataManagement/mitkEnumerationProperty.cpp DataManagement/mitkGeometry2D.cpp DataManagement/mitkGeometry2DData.cpp DataManagement/mitkGeometry3D.cpp DataManagement/mitkGeometryData.cpp DataManagement/mitkGroupTagProperty.cpp DataManagement/mitkImage.cpp DataManagement/mitkImageAccessorBase.cpp DataManagement/mitkImageCaster.cpp DataManagement/mitkImageCastPart1.cpp DataManagement/mitkImageCastPart2.cpp DataManagement/mitkImageCastPart3.cpp DataManagement/mitkImageCastPart4.cpp DataManagement/mitkImageDataItem.cpp DataManagement/mitkImageDescriptor.cpp DataManagement/mitkImageVtkAccessor.cpp DataManagement/mitkImageStatisticsHolder.cpp DataManagement/mitkLandmarkBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjector.cpp DataManagement/mitkLevelWindow.cpp DataManagement/mitkLevelWindowManager.cpp DataManagement/mitkLevelWindowPreset.cpp DataManagement/mitkLevelWindowProperty.cpp DataManagement/mitkLookupTable.cpp DataManagement/mitkLookupTables.cpp # specializations of GenericLookupTable DataManagement/mitkMemoryUtilities.cpp DataManagement/mitkModalityProperty.cpp DataManagement/mitkModeOperation.cpp DataManagement/mitkNodePredicateAnd.cpp DataManagement/mitkNodePredicateBase.cpp DataManagement/mitkNodePredicateCompositeBase.cpp DataManagement/mitkNodePredicateData.cpp DataManagement/mitkNodePredicateDataType.cpp DataManagement/mitkNodePredicateDimension.cpp DataManagement/mitkNodePredicateFirstLevel.cpp DataManagement/mitkNodePredicateNot.cpp DataManagement/mitkNodePredicateOr.cpp DataManagement/mitkNodePredicateProperty.cpp DataManagement/mitkNodePredicateSource.cpp DataManagement/mitkPlaneOrientationProperty.cpp DataManagement/mitkPlaneGeometry.cpp DataManagement/mitkPlaneOperation.cpp DataManagement/mitkPointOperation.cpp DataManagement/mitkPointSet.cpp DataManagement/mitkProperties.cpp DataManagement/mitkPropertyList.cpp DataManagement/mitkRestorePlanePositionOperation.cpp DataManagement/mitkRotationOperation.cpp DataManagement/mitkSlicedData.cpp DataManagement/mitkSlicedGeometry3D.cpp DataManagement/mitkSmartPointerProperty.cpp DataManagement/mitkStandaloneDataStorage.cpp DataManagement/mitkStateTransitionOperation.cpp DataManagement/mitkStringProperty.cpp DataManagement/mitkSurface.cpp DataManagement/mitkSurfaceOperation.cpp DataManagement/mitkThinPlateSplineCurvedGeometry.cpp DataManagement/mitkTransferFunction.cpp DataManagement/mitkTransferFunctionProperty.cpp DataManagement/mitkTransferFunctionInitializer.cpp DataManagement/mitkVector.cpp DataManagement/mitkVtkInterpolationProperty.cpp DataManagement/mitkVtkRepresentationProperty.cpp DataManagement/mitkVtkResliceInterpolationProperty.cpp DataManagement/mitkVtkScalarModeProperty.cpp DataManagement/mitkVtkVolumeRenderingProperty.cpp DataManagement/mitkWeakPointerProperty.cpp DataManagement/mitkRenderingModeProperty.cpp DataManagement/mitkShaderProperty.cpp DataManagement/mitkResliceMethodProperty.cpp DataManagement/mitkMaterial.cpp DataManagement/mitkPointSetShapeProperty.cpp DataManagement/mitkFloatPropertyExtension.cpp DataManagement/mitkIntPropertyExtension.cpp DataManagement/mitkPropertyExtension.cpp DataManagement/mitkPropertyFilter.cpp DataManagement/mitkPropertyAliases.cpp DataManagement/mitkPropertyDescriptions.cpp DataManagement/mitkPropertyExtensions.cpp DataManagement/mitkPropertyFilters.cpp Interactions/mitkAction.cpp Interactions/mitkAffineInteractor.cpp Interactions/mitkBindDispatcherInteractor.cpp Interactions/mitkCoordinateSupplier.cpp Interactions/mitkDataInteractor.cpp Interactions/mitkDispatcher.cpp Interactions/mitkDisplayCoordinateOperation.cpp Interactions/mitkDisplayInteractor.cpp Interactions/mitkDisplayPositionEvent.cpp # Interactions/mitkDisplayVectorInteractorLevelWindow.cpp # legacy, prob even now unneeded # Interactions/mitkDisplayVectorInteractorScroll.cpp Interactions/mitkEvent.cpp Interactions/mitkEventConfig.cpp Interactions/mitkEventDescription.cpp Interactions/mitkEventFactory.cpp Interactions/mitkInteractionEventHandler.cpp Interactions/mitkEventMapper.cpp Interactions/mitkEventStateMachine.cpp Interactions/mitkGlobalInteraction.cpp Interactions/mitkInteractor.cpp Interactions/mitkInternalEvent.cpp Interactions/mitkInteractionEvent.cpp Interactions/mitkInteractionEventConst.cpp Interactions/mitkInteractionPositionEvent.cpp Interactions/mitkInteractionKeyEvent.cpp Interactions/mitkMousePressEvent.cpp Interactions/mitkMouseMoveEvent.cpp Interactions/mitkMouseReleaseEvent.cpp Interactions/mitkMouseWheelEvent.cpp Interactions/mitkMouseDoubleClickEvent.cpp Interactions/mitkMouseModeSwitcher.cpp Interactions/mitkMouseMovePointSetInteractor.cpp Interactions/mitkMoveBaseDataInteractor.cpp Interactions/mitkNodeDepententPointSetInteractor.cpp Interactions/mitkPointSetDataInteractor.cpp Interactions/mitkPointSetInteractor.cpp Interactions/mitkPositionEvent.cpp Interactions/mitkPositionTracker.cpp Interactions/mitkStateMachineAction.cpp Interactions/mitkStateMachineCondition.cpp Interactions/mitkStateMachineState.cpp Interactions/mitkStateMachineTransition.cpp Interactions/mitkState.cpp Interactions/mitkStateMachineContainer.cpp Interactions/mitkStateEvent.cpp Interactions/mitkStateMachine.cpp Interactions/mitkStateMachineFactory.cpp Interactions/mitkTransition.cpp Interactions/mitkWheelEvent.cpp Interactions/mitkKeyEvent.cpp Interactions/mitkVtkEventAdapter.cpp Interactions/mitkVtkInteractorStyle.cxx Interactions/mitkCrosshairPositionEvent.cpp Interfaces/mitkInteractionEventObserver.cpp Interfaces/mitkIShaderRepository.cpp Interfaces/mitkIPropertyAliases.cpp Interfaces/mitkIPropertyDescriptions.cpp Interfaces/mitkIPropertyExtensions.cpp Interfaces/mitkIPropertyFilters.cpp IO/mitkBaseDataIOFactory.cpp IO/mitkCoreDataNodeReader.cpp IO/mitkDicomSeriesReader.cpp IO/mitkDicomSR_LoadDICOMScalar.cpp IO/mitkDicomSR_LoadDICOMScalar4D.cpp IO/mitkDicomSR_LoadDICOMRGBPixel.cpp IO/mitkDicomSR_LoadDICOMRGBPixel4D.cpp IO/mitkDicomSR_ImageBlockDescriptor.cpp IO/mitkDicomSR_GantryTiltInformation.cpp IO/mitkDicomSR_SliceGroupingResult.cpp IO/mitkFileReader.cpp IO/mitkFileSeriesReader.cpp IO/mitkFileWriter.cpp # IO/mitkIpPicGet.c IO/mitkImageGenerator.cpp IO/mitkImageWriter.cpp IO/mitkImageWriterFactory.cpp IO/mitkItkImageFileIOFactory.cpp IO/mitkItkImageFileReader.cpp IO/mitkItkLoggingAdapter.cpp IO/mitkItkPictureWrite.cpp IO/mitkIOUtil.cpp IO/mitkLookupTableProperty.cpp IO/mitkOperation.cpp # IO/mitkPicFileIOFactory.cpp # IO/mitkPicFileReader.cpp # IO/mitkPicFileWriter.cpp # IO/mitkPicHelper.cpp # IO/mitkPicVolumeTimeSeriesIOFactory.cpp # IO/mitkPicVolumeTimeSeriesReader.cpp IO/mitkPixelType.cpp IO/mitkPointSetIOFactory.cpp IO/mitkPointSetReader.cpp IO/mitkPointSetWriter.cpp IO/mitkPointSetWriterFactory.cpp IO/mitkRawImageFileReader.cpp IO/mitkStandardFileLocations.cpp IO/mitkSTLFileIOFactory.cpp IO/mitkSTLFileReader.cpp IO/mitkSurfaceVtkWriter.cpp IO/mitkSurfaceVtkWriterFactory.cpp IO/mitkVtkLoggingAdapter.cpp IO/mitkVtiFileIOFactory.cpp IO/mitkVtiFileReader.cpp IO/mitkVtkImageIOFactory.cpp IO/mitkVtkImageReader.cpp IO/mitkVtkSurfaceIOFactory.cpp IO/mitkVtkSurfaceReader.cpp IO/vtkPointSetXMLParser.cpp IO/mitkLog.cpp Rendering/mitkBaseRenderer.cpp Rendering/mitkVtkMapper.cpp Rendering/mitkRenderWindowFrame.cpp Rendering/mitkGeometry2DDataMapper2D.cpp Rendering/mitkGeometry2DDataVtkMapper3D.cpp Rendering/mitkGLMapper.cpp Rendering/mitkGradientBackground.cpp Rendering/mitkManufacturerLogo.cpp Rendering/mitkMapper.cpp Rendering/mitkPointSetGLMapper2D.cpp Rendering/mitkPointSetVtkMapper2D.cpp Rendering/mitkPointSetVtkMapper3D.cpp Rendering/mitkPolyDataGLMapper2D.cpp Rendering/mitkSurfaceGLMapper2D.cpp Rendering/mitkSurfaceVtkMapper3D.cpp Rendering/mitkVolumeDataVtkMapper3D.cpp Rendering/mitkVtkPropRenderer.cpp Rendering/mitkVtkWidgetRendering.cpp Rendering/vtkMitkRectangleProp.cpp Rendering/vtkMitkRenderProp.cpp Rendering/mitkVtkEventProvider.cpp Rendering/mitkRenderWindow.cpp Rendering/mitkRenderWindowBase.cpp Rendering/mitkShaderRepository.cpp Rendering/mitkImageVtkMapper2D.cpp Rendering/vtkMitkThickSlicesFilter.cpp Rendering/vtkMitkLevelWindowFilter.cpp Rendering/vtkNeverTranslucentTexture.cpp Rendering/mitkRenderingTestHelper.cpp Rendering/mitkOverlay.cpp Rendering/mitkVtkOverlay.cpp Rendering/mitkVtkOverlay2D.cpp Rendering/mitkVtkOverlay3D.cpp Rendering/mitkOverlayManager.cpp Rendering/mitkAbstractOverlayLayouter.cpp Rendering/mitkTextOverlay2D.cpp Rendering/mitkTextOverlay3D.cpp Rendering/mitkLabelOverlay3D.cpp Rendering/mitkOverlay2DLayouter.cpp Common/mitkException.cpp Common/mitkCommon.h Common/mitkCoreObjectFactoryBase.cpp Common/mitkCoreObjectFactory.cpp Common/mitkCoreServices.cpp ) list(APPEND CPP_FILES ${CppMicroServices_SOURCES}) set(RESOURCE_FILES Interactions/globalConfig.xml Interactions/DisplayInteraction.xml Interactions/DisplayConfig.xml Interactions/DisplayConfigPACS.xml Interactions/DisplayConfigPACSPan.xml Interactions/DisplayConfigPACSScroll.xml Interactions/DisplayConfigPACSZoom.xml Interactions/DisplayConfigPACSLevelWindow.xml Interactions/DisplayConfigMITK.xml Interactions/PointSet.xml Interactions/Legacy/StateMachine.xml Interactions/Legacy/DisplayConfigMITKTools.xml Interactions/PointSetConfig.xml Shaders/mitkShaderLighting.xml mitkLevelWindowPresets.xml ) diff --git a/Modules/Persistence/CMakeLists.txt b/Modules/Persistence/CMakeLists.txt index b132706de7..72f5726d1e 100644 --- a/Modules/Persistence/CMakeLists.txt +++ b/Modules/Persistence/CMakeLists.txt @@ -1,5 +1,6 @@ MITK_CREATE_MODULE( Persistence INCLUDE_DIRS DEPENDS SceneSerialization + AUTOLOAD_WITH SceneSerialization ) add_subdirectory(Testing) \ No newline at end of file diff --git a/Modules/Persistence/files.cmake b/Modules/Persistence/files.cmake index adb46e5f7b..e93bb8fe5a 100644 --- a/Modules/Persistence/files.cmake +++ b/Modules/Persistence/files.cmake @@ -1,6 +1,4 @@ set(CPP_FILES -mitkIPersistenceService.cpp mitkPersistenceService.cpp -mitkPropertyListReplacedObserver.cpp mitkPersistenceActivator.cpp ) diff --git a/Modules/Persistence/mitkPersistenceService.cpp b/Modules/Persistence/mitkPersistenceService.cpp index 8109debba4..0d9c7b11e6 100644 --- a/Modules/Persistence/mitkPersistenceService.cpp +++ b/Modules/Persistence/mitkPersistenceService.cpp @@ -1,247 +1,267 @@ /*=================================================================== 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" 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() ) { { 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(); } } 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 ) +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() ) 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(); - std::map::iterator it = m_PropertyLists.begin(); - while( it != m_PropertyLists.end() ) + DataStorage::SetOfObjects::Pointer nodes = this->GetDataNodes(); + DataStorage::SetOfObjects::iterator it = nodes->begin(); + while( it != nodes->end() ) { - mitk::DataNode::Pointer node; - const std::string& name = (*it).first; - if( appendChanges ) - { - mitk::NodePredicateProperty::Pointer namePred = - mitk::NodePredicateProperty::New("name", mitk::StringProperty::New(name)); - node = tempDs->GetNode(namePred); - } - if(node.IsNull()) - { - node = mitk::DataNode::New(); - tempDs->Add(node); - } - - 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() ); + mitk::DataNode::Pointer node = *it; + tempDs->Add(node); ++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 ); } 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() ) 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; } - DataStorage::SetOfObjects::ConstPointer allNodes = ds->GetAll(); + 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 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(); + return oneFound; } diff --git a/Modules/Persistence/mitkPersistenceService.h b/Modules/Persistence/mitkPersistenceService.h index 23a11be77c..89720371b3 100644 --- a/Modules/Persistence/mitkPersistenceService.h +++ b/Modules/Persistence/mitkPersistenceService.h @@ -1,59 +1,66 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #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 { 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); void AddPropertyListReplacedObserver( PropertyListReplacedObserver* observer ); void RemovePropertyListReplacedObserver( PropertyListReplacedObserver* observer ); + + bool RestorePropertyListsFromPersistentDataNodes(DataStorage* storage); private: - void ClonePropertyList( mitk::PropertyList* from, mitk::PropertyList* to ); + 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 e09d70ce79..0834675912 100644 --- a/Modules/SceneSerialization/mitkSceneIO.cpp +++ b/Modules/SceneSerialization/mitkSceneIO.cpp @@ -1,533 +1,613 @@ /*=================================================================== 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 ) + { + us::ModuleContext* context = us::GetModuleContext(); + us::ServiceReference persistenceServiceRef + = context->GetServiceReference();\ + mitk::IPersistenceService* persistenceService + = dynamic_cast ( context->GetService(persistenceServiceRef) ); + persistenceService->RestorePropertyListsFromPersistentDataNodes(storage); + } + // return new data storage, even if empty or uncomplete (return as much as possible but notify calling method) return storage; } -bool mitk::SceneIO::SaveScene( DataStorage::SetOfObjects::ConstPointer sceneNodes, const DataStorage* 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 (!sceneNodes) + 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(); + us::ServiceReference persistenceServiceRef + = context->GetServiceReference();\ + mitk::IPersistenceService* persistenceService + = dynamic_cast ( context->GetService(persistenceServiceRef) ); + + 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); + ++it; + } + } + 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."; + 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() << "'"; + 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; + 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(); + this->RemoveNodes( persistentNodes.GetPointer(), storage, sceneNodes ); return false; } + 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() << "'"; + 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; +} diff --git a/Modules/SceneSerialization/mitkSceneIO.h b/Modules/SceneSerialization/mitkSceneIO.h index 1706784cbd..0a3c1d7b0c 100644 --- a/Modules/SceneSerialization/mitkSceneIO.h +++ b/Modules/SceneSerialization/mitkSceneIO.h @@ -1,118 +1,130 @@ /*=================================================================== 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, const DataStorage* storage, + 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/CMakeLists.txt b/Plugins/org.mitk.gui.qt.application/CMakeLists.txt index 13f1aa6dff..66a5449134 100644 --- a/Plugins/org.mitk.gui.qt.application/CMakeLists.txt +++ b/Plugins/org.mitk.gui.qt.application/CMakeLists.txt @@ -1,8 +1,8 @@ project(org_mitk_gui_qt_application) MACRO_CREATE_MITK_CTK_PLUGIN( EXPORT_DIRECTIVE MITK_QT_APP EXPORTED_INCLUDE_SUFFIXES src - MODULE_DEPENDENCIES Qmitk + MODULE_DEPENDENCIES Qmitk SceneSerialization SUBPROJECTS MITK-CoreUI ) diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.cpp index f636194686..422c2a51cb 100644 --- a/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.cpp +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkFileOpenAction.cpp @@ -1,123 +1,172 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "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 36bbbf1148..37a45f69dc 100644 --- a/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.cpp +++ b/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.cpp @@ -1,57 +1,99 @@ /*=================================================================== 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 202734dd0e..b78607d830 100644 --- a/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.h +++ b/Plugins/org.mitk.gui.qt.application/src/internal/QmitkGeneralPreferencePage.h @@ -1,74 +1,78 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QMITKGENERALPREFERENCEPAGE_H_ #define QMITKGENERALPREFERENCEPAGE_H_ #include "berryIQtPreferencePage.h" #include class QWidget; +class QCheckBox; class QmitkGeneralPreferencePage : public QObject, public berry::IQtPreferencePage { Q_OBJECT Q_INTERFACES(berry::IPreferencePage) public: /** * Default constructor */ QmitkGeneralPreferencePage(); /** * @see berry::IPreferencePage::Init(berry::IWorkbench::Pointer workbench) */ void Init(berry::IWorkbench::Pointer workbench); /** * @see berry::IPreferencePage::CreateQtControl(void* parent) */ void CreateQtControl(QWidget* widget); /** * @see berry::IPreferencePage::CreateQtControl() */ QWidget* GetQtControl() const; /** * @see berry::IPreferencePage::PerformOk() */ virtual bool PerformOk(); /** * @see berry::IPreferencePage::PerformCancel() */ virtual void PerformCancel(); /** * @see berry::IPreferencePage::Update() */ virtual void Update(); protected: - QWidget* m_MainControl; + QWidget* m_MainControl; + 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 d92b96040a..450a04fa3f 100644 --- a/Plugins/org.mitk.gui.qt.ext/src/QmitkExtFileSaveProjectAction.cpp +++ b/Plugins/org.mitk.gui.qt.ext/src/QmitkExtFileSaveProjectAction.cpp @@ -1,164 +1,199 @@ /*=================================================================== 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(); } } diff --git a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.cpp b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.cpp index 299c8115f1..ce57e1e976 100644 --- a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.cpp +++ b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.cpp @@ -1,252 +1,255 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkCommonExtPlugin.h" #include #include "QmitkAppInstancesPreferencePage.h" #include "QmitkInputDevicesPrefPage.h" #include "QmitkModuleView.h" #include #include #include #include #include #include #include #include #include #include #include +#include +#include "berryPlatform.h" +#include ctkPluginContext* QmitkCommonExtPlugin::_context = 0; void QmitkCommonExtPlugin::start(ctkPluginContext* context) { this->_context = context; QmitkExtRegisterClasses(); BERRY_REGISTER_EXTENSION_CLASS(QmitkAppInstancesPreferencePage, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkInputDevicesPrefPage, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkModuleView, context) if (qApp->metaObject()->indexOfSignal("messageReceived(QByteArray)") > -1) { connect(qApp, SIGNAL(messageReceived(QByteArray)), this, SLOT(handleIPCMessage(QByteArray))); } std::vector args = berry::Platform::GetApplicationArgs(); QStringList qargs; for (std::vector::const_iterator it = args.begin(); it != args.end(); ++it) { qargs << QString::fromStdString(*it); } // This is a potentially long running operation. loadDataFromDisk(qargs, true); } void QmitkCommonExtPlugin::stop(ctkPluginContext* context) { Q_UNUSED(context) this->_context = 0; } ctkPluginContext* QmitkCommonExtPlugin::getContext() { return _context; } void QmitkCommonExtPlugin::loadDataFromDisk(const QStringList &arguments, bool globalReinit) { if (!arguments.empty()) { ctkServiceReference serviceRef = _context->getServiceReference(); if (serviceRef) { mitk::IDataStorageService* dataStorageService = _context->getService(serviceRef); mitk::DataStorage::Pointer dataStorage = dataStorageService->GetDefaultDataStorage()->GetDataStorage(); int argumentsAdded = 0; for (int i = 0; i < arguments.size(); ++i) { if (arguments[i].right(5) == ".mitk") { mitk::SceneIO::Pointer sceneIO = mitk::SceneIO::New(); bool clearDataStorageFirst(false); mitk::ProgressBar::GetInstance()->AddStepsToDo(2); dataStorage = sceneIO->LoadScene( arguments[i].toLocal8Bit().constData(), dataStorage, clearDataStorageFirst ); mitk::ProgressBar::GetInstance()->Progress(2); argumentsAdded++; } else { mitk::DataNodeFactory::Pointer nodeReader = mitk::DataNodeFactory::New(); try { nodeReader->SetFileName(arguments[i].toStdString()); nodeReader->Update(); for (unsigned int j = 0 ; j < nodeReader->GetNumberOfOutputs( ); ++j) { mitk::DataNode::Pointer node = nodeReader->GetOutput(j); if (node->GetData() != 0) { dataStorage->Add(node); argumentsAdded++; } } } catch(...) { MITK_WARN << "Failed to load command line argument: " << arguments[i].toStdString(); } } } // end for each command line argument if (argumentsAdded > 0 && globalReinit) { // calculate bounding geometry mitk::RenderingManager::GetInstance()->InitializeViews(dataStorage->ComputeBoundingGeometry3D()); } } else { MITK_ERROR << "A service reference for mitk::IDataStorageService does not exist"; } } } void QmitkCommonExtPlugin::startNewInstance(const QStringList &args, const QStringList& files) { QStringList newArgs(args); #ifdef Q_OS_UNIX newArgs << QString("--") + QString::fromStdString(berry::Platform::ARG_NEWINSTANCE); #else newArgs << QString("/") + QString::fromStdString(berry::Platform::ARG_NEWINSTANCE); #endif newArgs << files; QProcess::startDetached(qApp->applicationFilePath(), newArgs); } void QmitkCommonExtPlugin::handleIPCMessage(const QByteArray& msg) { QDataStream ds(msg); QString msgType; ds >> msgType; // we only handle messages containing command line arguments if (msgType != "$cmdLineArgs") return; // activate the current workbench window berry::IWorkbenchWindow::Pointer window = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow(); QMainWindow* mainWindow = static_cast (window->GetShell()->GetControl()); mainWindow->setWindowState(mainWindow->windowState() & ~Qt::WindowMinimized); mainWindow->raise(); mainWindow->activateWindow(); // Get the preferences for the instantiation behavior berry::IPreferencesService::Pointer prefService = berry::Platform::GetServiceRegistry() .GetServiceById(berry::IPreferencesService::ID); berry::IPreferences::Pointer prefs = prefService->GetSystemPreferences()->Node("/General"); bool newInstanceAlways = prefs->GetBool("newInstance.always", false); bool newInstanceScene = prefs->GetBool("newInstance.scene", true); QStringList args; ds >> args; QStringList fileArgs; QStringList sceneArgs; Poco::Util::OptionSet os; berry::Platform::GetOptionSet(os); Poco::Util::OptionProcessor processor(os); #if !defined(POCO_OS_FAMILY_UNIX) processor.setUnixStyle(false); #endif args.pop_front(); QStringList::Iterator it = args.begin(); while (it != args.end()) { std::string name; std::string value; if (processor.process(it->toStdString(), name, value)) { ++it; } else { if (it->endsWith(".mitk")) { sceneArgs << *it; } else { fileArgs << *it; } it = args.erase(it); } } if (newInstanceAlways) { if (newInstanceScene) { startNewInstance(args, fileArgs); foreach(QString sceneFile, sceneArgs) { startNewInstance(args, QStringList(sceneFile)); } } else { fileArgs.append(sceneArgs); startNewInstance(args, fileArgs); } } else { loadDataFromDisk(fileArgs, false); if (newInstanceScene) { foreach(QString sceneFile, sceneArgs) { startNewInstance(args, QStringList(sceneFile)); } } else { loadDataFromDisk(sceneArgs, false); } } } Q_EXPORT_PLUGIN2(org_mitk_gui_qt_ext, QmitkCommonExtPlugin)