diff options
author | Mikhail Voitenko <mav@openoffice.org> | 2009-12-09 20:51:15 +0000 |
---|---|---|
committer | Mikhail Voitenko <mav@openoffice.org> | 2009-12-09 20:51:15 +0000 |
commit | 89fd6a8f6cd1b27a9c4a22c5254a1ce5184c45d2 (patch) | |
tree | 4c7f7fe4832daf1fc83b916a9f187f0ea6530d9b | |
parent | b3bfaa49dbfe2c7e6c9861766c6dbcb338a1cbfd (diff) |
#i107525# let the original file be locked with the system file locking
-rw-r--r-- | sfx2/inc/sfx2/docfile.hxx | 3 | ||||
-rw-r--r-- | sfx2/source/doc/docfile.cxx | 125 |
2 files changed, 101 insertions, 27 deletions
diff --git a/sfx2/inc/sfx2/docfile.hxx b/sfx2/inc/sfx2/docfile.hxx index e8ae3f5d1d85..6c497bf6cb35 100644 --- a/sfx2/inc/sfx2/docfile.hxx +++ b/sfx2/inc/sfx2/docfile.hxx @@ -229,7 +229,7 @@ public: sal_Int8 ShowLockedDocumentDialog( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aData, sal_Bool bIsLoading, sal_Bool bOwnLock ); sal_Bool LockOrigFileOnDemand( sal_Bool bLoading, sal_Bool bNoUI ); - void UnlockFile(); + void UnlockFile( sal_Bool bReleaseLockStream ); ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > GetStorage( sal_Bool bCreateTempIfNo = sal_True ); ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > GetOutputStorage(); @@ -290,6 +290,7 @@ public: SAL_DLLPRIVATE void Init_Impl(); SAL_DLLPRIVATE void ForceSynchronStream_Impl( sal_Bool bSynchron ); + SAL_DLLPRIVATE void GetLockingStream_Impl(); SAL_DLLPRIVATE void GetMedium_Impl(); SAL_DLLPRIVATE sal_Bool TryDirectTransfer( const ::rtl::OUString& aURL, SfxItemSet& aTargetSet ); SAL_DLLPRIVATE void Transfer_Impl(); diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx index 302233a93ad7..7158be0a6cc2 100644 --- a/sfx2/source/doc/docfile.cxx +++ b/sfx2/source/doc/docfile.cxx @@ -383,6 +383,8 @@ public: Reference < XInputStream > xInputStream; Reference < XStream > xStream; + uno::Reference< io::XStream > m_xLockingStream; + sal_uInt32 nLastStorageError; ::rtl::OUString aCharset; @@ -1122,21 +1124,18 @@ sal_Bool SfxMedium::LockOrigFileOnDemand( sal_Bool bLoading, sal_Bool bNoUI ) if ( !bResult && !IsReadOnly() ) { - // check whether the file is readonly in fs - // the check is only necessary if - // do it only for loading, some contents still might have problems with this property, let them not affect the saving sal_Bool bContentReadonly = sal_False; - if ( bLoading && ::utl::LocalFileHelper::IsLocalFile( aLogicName ) ) + if ( bLoading && ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) ) { - // let the stream be opened to check the possibility to open it for editing - GetMedium_Impl(); + // let the original document be opened to check the possibility to open it for editing + // and to let the writable stream stay open to hold the lock on the document + GetLockingStream_Impl(); } // "IsReadOnly" property does not allow to detect whether the file is readonly always // so we try always to open the file for editing // the file is readonly only in case the read-write stream can not be opened - SFX_ITEMSET_ARG( pSet, pWriteStreamItem, SfxUnoAnyItem, SID_STREAM, sal_False); - if ( bLoading && !pWriteStreamItem ) + if ( bLoading && !pImp->m_xLockingStream.is() ) { try { @@ -2267,6 +2266,45 @@ void SfxMedium::ClearBackup_Impl() } //---------------------------------------------------------------- +void SfxMedium::GetLockingStream_Impl() +{ + if ( ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) + && !pImp->m_xLockingStream.is() ) + { + SFX_ITEMSET_ARG( pSet, pWriteStreamItem, SfxUnoAnyItem, SID_STREAM, sal_False); + if ( pWriteStreamItem ) + pWriteStreamItem->GetValue() >>= pImp->m_xLockingStream; + + if ( !pImp->m_xLockingStream.is() ) + { + // open the original document + uno::Sequence< beans::PropertyValue > xProps; + TransformItems( SID_OPENDOC, *GetItemSet(), xProps ); + comphelper::MediaDescriptor aMedium( xProps ); + + aMedium.addInputStreamOwnLock(); + + uno::Reference< io::XInputStream > xInputStream; + aMedium[comphelper::MediaDescriptor::PROP_STREAM()] >>= pImp->m_xLockingStream; + aMedium[comphelper::MediaDescriptor::PROP_INPUTSTREAM()] >>= xInputStream; + + if ( !pImp->pTempFile && !aName.Len() ) + { + // the medium is still based on the original file, it makes sence to initialize the streams + if ( pImp->m_xLockingStream.is() ) + pImp->xStream = pImp->m_xLockingStream; + + if ( xInputStream.is() ) + pImp->xInputStream = xInputStream; + + if ( !pImp->xInputStream.is() && pImp->xStream.is() ) + pImp->xInputStream = pImp->xStream->getInputStream(); + } + } + } +} + +//---------------------------------------------------------------- void SfxMedium::GetMedium_Impl() { if ( !pInStream ) @@ -2332,27 +2370,36 @@ void SfxMedium::GetMedium_Impl() TransformItems( SID_OPENDOC, *GetItemSet(), xProps ); comphelper::MediaDescriptor aMedium( xProps ); - if ( bFromTempFile ) + if ( pImp->m_xLockingStream.is() && !bFromTemplate ) { - aMedium[comphelper::MediaDescriptor::PROP_URL()] <<= ::rtl::OUString( aFileName ); - aMedium.erase( comphelper::MediaDescriptor::PROP_READONLY() ); - aMedium.addInputStream(); - } - else if ( ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) ) - { - // use the special locking approach only for file URLs - aMedium.addInputStreamOwnLock(); + // the medium is not based on the temporary file, so the original stream can be used + pImp->xStream = pImp->m_xLockingStream; } else - aMedium.addInputStream(); + { + if ( bFromTempFile ) + { + aMedium[comphelper::MediaDescriptor::PROP_URL()] <<= ::rtl::OUString( aFileName ); + aMedium.erase( comphelper::MediaDescriptor::PROP_READONLY() ); + aMedium.addInputStream(); + } + else if ( ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) ) + { + // use the special locking approach only for file URLs + aMedium.addInputStreamOwnLock(); + } + else + aMedium.addInputStream(); + + // the ReadOnly property set in aMedium is ignored + // the check is done in LockOrigFileOnDemand() for file and non-file URLs - // the ReadOnly property set in aMedium is ignored - // the check is done in LockOrigFileOnDemand() for file and non-file URLs + //TODO/MBA: what happens if property is not there?! + aMedium[comphelper::MediaDescriptor::PROP_STREAM()] >>= pImp->xStream; + aMedium[comphelper::MediaDescriptor::PROP_INPUTSTREAM()] >>= pImp->xInputStream; + } - //TODO/MBA: what happens if property is not there?! GetContent(); - aMedium[comphelper::MediaDescriptor::PROP_STREAM()] >>= pImp->xStream; - aMedium[comphelper::MediaDescriptor::PROP_INPUTSTREAM()] >>= pImp->xInputStream; if ( !pImp->xInputStream.is() && pImp->xStream.is() ) pImp->xInputStream = pImp->xStream->getInputStream(); } @@ -2661,7 +2708,7 @@ void SfxMedium::Close() CloseStreams_Impl(); - UnlockFile(); + UnlockFile( sal_False ); } void SfxMedium::CloseAndRelease() @@ -2694,11 +2741,31 @@ void SfxMedium::CloseAndRelease() CloseAndReleaseStreams_Impl(); - UnlockFile(); + UnlockFile( sal_True ); } -void SfxMedium::UnlockFile() +void SfxMedium::UnlockFile( sal_Bool bReleaseLockStream ) { + if ( pImp->m_xLockingStream.is() ) + { + if ( bReleaseLockStream ) + { + try + { + uno::Reference< io::XInputStream > xInStream = pImp->m_xLockingStream->getInputStream(); + uno::Reference< io::XOutputStream > xOutStream = pImp->m_xLockingStream->getOutputStream(); + if ( xInStream.is() ) + xInStream->closeInput(); + if ( xOutStream.is() ) + xOutStream->closeOutput(); + } + catch( uno::Exception& ) + {} + } + + pImp->m_xLockingStream = uno::Reference< io::XStream >(); + } + if ( pImp->m_bLocked ) { try @@ -2720,8 +2787,14 @@ void SfxMedium::CloseAndReleaseStreams_Impl() uno::Reference< io::XInputStream > xInToClose = pImp->xInputStream; uno::Reference< io::XOutputStream > xOutToClose; if ( pImp->xStream.is() ) + { xOutToClose = pImp->xStream->getOutputStream(); + // if the locking stream is closed here the related member should be cleaned + if ( pImp->xStream == pImp->m_xLockingStream ) + pImp->m_xLockingStream = uno::Reference< io::XStream >(); + } + // The probably exsisting SvStream wrappers should be closed first CloseStreams_Impl(); |