diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2009-01-06 16:18:24 +0000 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2009-01-06 16:18:24 +0000 |
commit | 1241d00182a55452ed40527c9d0e8db217aab198 (patch) | |
tree | 1eaf902adcbd37c4378b0a577ec5cc64cead096b /sfx2/source/doc/docfile.cxx | |
parent | 6d63ea11360a7afdd8f767848e516eb2e39ff261 (diff) |
CWS-TOOLING: integrate CWS mav43
2008-12-17 14:42:56 +0100 tbo r265602 : #i97269# changed hid.lst and etab.win
2008-12-15 15:36:04 +0100 mav r265508 : #i95809# remove the stream as well
2008-12-12 13:20:09 +0100 mav r265411 : #i95809# small fixes
2008-12-12 13:12:07 +0100 mav r265410 : #i95809# fix streams handling
2008-12-12 10:45:29 +0100 mav r265397 : #i95809# close the stream if there is no storage
2008-12-12 10:24:38 +0100 mav r265396 : #i95809# close the stream if there is no temporary file
2008-12-12 00:56:13 +0100 mav r265383 : #i95809# adopt for linux
2008-12-12 00:51:25 +0100 mav r265382 : #i95809# adopt for linux
2008-12-12 00:38:31 +0100 mav r265381 : #i95809# check timestamp only if fs locking not active
2008-12-12 00:35:32 +0100 mav r265380 : #i95809# small fixes
2008-12-12 00:29:33 +0100 mav r265379 : #i95809# small fixes
2008-12-11 22:30:15 +0100 mav r265374 : #i97092# allow to use default master password
2008-12-11 22:20:56 +0100 mav r265372 : #i95809# avoid storage closing
2008-12-11 21:11:37 +0100 mav r265368 : #i97092# do not publish for now
2008-12-11 21:08:22 +0100 mav r265366 : #i95809# fix typo
2008-12-11 21:06:49 +0100 mav r265364 : #i95809# small fixes
2008-12-11 21:05:13 +0100 mav r265363 : #i95809# small fixes
2008-12-11 20:40:05 +0100 mav r265360 : #i95809# show warning if the document was touched
2008-12-11 20:39:44 +0100 mav r265359 : #i95809# show warning if the document was touched
2008-12-11 19:54:45 +0100 mav r265355 : #i95809# small fixes
2008-12-11 19:42:52 +0100 mav r265353 : #i95809# small fixes
2008-12-11 19:30:30 +0100 mav r265351 : #i95809# small fixes
2008-12-11 19:16:40 +0100 mav r265349 : #i95809# small fixes
2008-12-11 19:05:56 +0100 mav r265348 : #i95809# small fixes
2008-12-11 18:26:03 +0100 mav r265346 : #i95809# ignore the exception
2008-12-11 18:19:28 +0100 mav r265345 : #i95809# pure imput stream in case of local file URL means opening of document readonly
2008-12-11 17:41:56 +0100 mav r265341 : #i95809# unfortunately SfxMedium can not take the decision
2008-12-11 17:37:07 +0100 mav r265340 : #i95809# fix typo
2008-12-11 17:33:47 +0100 mav r265339 : #i95809# pure imput stream in case of local file URL means opening of document readonly
2008-12-11 16:12:26 +0100 mav r265330 : #i95809# let dialogs look better
2008-12-11 15:50:43 +0100 mav r265322 : #i97092# allow to use default master password
2008-12-11 13:35:39 +0100 mav r265295 : #i97092# allow to use default master password
2008-12-11 13:04:28 +0100 mav r265290 : #i97092# allow to use default master password
2008-12-11 12:34:52 +0100 mav r265284 : #i97092# allow to use default master password
2008-12-11 11:21:33 +0100 mav r265267 : #i95809# adopt for linux
2008-12-11 10:25:22 +0100 mav r265255 : #i97092# allow to use default master password
2008-12-11 10:24:35 +0100 mav r265254 : #i97092# allow to use default master password
2008-12-10 17:02:32 +0100 pb r265207 : fix: #i97092# more info text
2008-12-10 16:40:53 +0100 mav r265205 : #i95809# integrate new file locking UI in sfx workflow
2008-12-10 16:38:55 +0100 mav r265204 : #i95809# allow to ignore own lock on saving
2008-12-10 14:52:12 +0100 pb r265192 : fix: #i97092# new master password behavior
2008-12-10 14:51:22 +0100 pb r265191 : fix: #i97092# new master password bahavior
2008-12-10 14:49:46 +0100 pb r265189 : fix: #i97092# new master password bahavior
2008-12-10 10:55:19 +0100 mav r265155 : #i95809# allow to ignore own lock on saving
2008-12-09 17:47:51 +0100 mav r265124 : #i95809# allow to ignore own lock on saving
2008-12-07 11:24:57 +0100 mav r264949 : #i95809# let the request be derived from IOException
2008-12-05 18:31:35 +0100 mav r264915 : #i95809# use the locking related dialogs from InteractionHandler
2008-12-04 18:33:36 +0100 mav r264867 : #i95809# the requests for the new locking UI
2008-12-04 10:26:52 +0100 pb r264822 : fix: #i95809# new message boxes for locking
2008-12-04 10:23:51 +0100 pb r264821 : fix: #i95809# STR_OPENLOCKED_UNKNOWNUSER replaced by STR_UNKNOWNUSER
2008-12-04 10:18:23 +0100 pb r264820 : fix: #i95809# new message boxes for locking
2008-12-04 10:15:56 +0100 pb r264819 : fix: #i95809# new message boxes for locking
2008-12-03 16:06:46 +0100 mav r264796 : #i95809# system file locking support
2008-12-02 16:19:30 +0100 mav r264717 : #i95809# system file locking support
2008-12-02 16:07:10 +0100 mav r264716 : #i95809# system file locking support
2008-12-02 15:58:53 +0100 mav r264714 : #i95809# change the name
2008-12-02 15:58:06 +0100 mav r264713 : #i95809# do not allow to change ReadOnly flag in TypeDetection
2008-12-02 15:56:00 +0100 mav r264712 : #i95809# system file locking support
2008-12-02 15:43:20 +0100 mav r264708 : #i95809# change the name
2008-12-02 15:38:08 +0100 mav r264706 : #i95809# an options to control system file locking usage
Diffstat (limited to 'sfx2/source/doc/docfile.cxx')
-rw-r--r-- | sfx2/source/doc/docfile.cxx | 428 |
1 files changed, 344 insertions, 84 deletions
diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx index 3302e945c0..875d4f69b2 100644 --- a/sfx2/source/doc/docfile.cxx +++ b/sfx2/source/doc/docfile.cxx @@ -39,6 +39,10 @@ #include <com/sun/star/ucb/XContent.hpp> #include <com/sun/star/document/XDocumentRevisionListPersistence.hpp> #include <com/sun/star/document/LockedDocumentRequest.hpp> +#include <com/sun/star/document/OwnLockOnDocumentRequest.hpp> +#include <com/sun/star/document/LockedOnSavingRequest.hpp> +#include <com/sun/star/document/LockFileIgnoreRequest.hpp> +#include <com/sun/star/document/ChangedByOthersRequest.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/embed/XTransactedObject.hpp> #include <com/sun/star/embed/ElementModes.hpp> @@ -108,6 +112,7 @@ using namespace ::com::sun::star::io; #include <comphelper/storagehelper.hxx> #include <comphelper/mediadescriptor.hxx> +#include <comphelper/configurationhelper.hxx> #include <tools/urlobj.hxx> #include <tools/inetmime.hxx> #include <unotools/ucblockbytes.hxx> @@ -144,6 +149,12 @@ using namespace ::com::sun::star::io; #define MAX_REDIRECT 5 +namespace { + static const sal_Int8 LOCK_UI_NOLOCK = 0; + static const sal_Int8 LOCK_UI_SUCCEEDED = 1; + static const sal_Int8 LOCK_UI_TRY = 2; +} + class SfxMediumHandler_Impl : public ::cppu::WeakImplHelper1< com::sun::star::task::XInteractionHandler > { com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > m_xInter; @@ -272,6 +283,9 @@ public: sal_Bool m_bSalvageMode: 1; sal_Bool m_bVersionsAlreadyLoaded: 1; sal_Bool m_bLocked: 1; + sal_Bool m_bHandleSysLocked: 1; + sal_Bool m_bGotDateTime: 1; + uno::Reference < embed::XStorage > xStorage; SfxPoolCancelManager_ImplRef xCancelManager; @@ -312,6 +326,8 @@ public: // in this case the member will hold this information sal_uInt16 m_nSignatureState; + util::DateTime m_aDateTime; + SfxPoolCancelManager_Impl* GetCancelManager(); SfxMedium_Impl( SfxMedium* pAntiImplP ); @@ -362,6 +378,8 @@ SfxMedium_Impl::SfxMedium_Impl( SfxMedium* pAntiImplP ) m_bSalvageMode( sal_False ), m_bVersionsAlreadyLoaded( sal_False ), m_bLocked( sal_False ), + m_bHandleSysLocked( sal_False ), + m_bGotDateTime( sal_False ), pAntiImpl( pAntiImplP ), nFileVersion( 0 ), pOrigFilter( 0 ), @@ -453,6 +471,86 @@ long SfxMedium::GetFileVersion() const } //------------------------------------------------------------------ +void SfxMedium::CheckFileDate( const util::DateTime& aInitDate ) +{ + GetInitFileDate(); + if ( pImp->m_aDateTime.Seconds != aInitDate.Seconds + || pImp->m_aDateTime.Minutes != aInitDate.Minutes + || pImp->m_aDateTime.Hours != aInitDate.Hours + || pImp->m_aDateTime.Day != aInitDate.Day + || pImp->m_aDateTime.Month != aInitDate.Month + || pImp->m_aDateTime.Year != aInitDate.Year ) + { + // check whether system file locking has been used, the default value is false + sal_Bool bUseSystemLock = sal_False; + try + { + + uno::Reference< uno::XInterface > xCommonConfig = ::comphelper::ConfigurationHelper::openConfig( + ::comphelper::getProcessServiceFactory(), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common" ) ), + ::comphelper::ConfigurationHelper::E_STANDARD ); + if ( !xCommonConfig.is() ) + throw uno::RuntimeException(); + + ::comphelper::ConfigurationHelper::readRelativeKey( + xCommonConfig, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Misc/" ) ), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseDocumentSystemFileLocking" ) ) ) >>= bUseSystemLock; + } + catch( const uno::Exception& ) + { + } + + if ( !bUseSystemLock ) + { + uno::Reference< task::XInteractionHandler > xHandler = GetInteractionHandler(); + + if ( xHandler.is() ) + { + try + { + ::rtl::Reference< ::ucbhelper::InteractionRequest > xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny( + document::ChangedByOthersRequest() ) ); + uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( 3 ); + aContinuations[0] = new ::ucbhelper::InteractionAbort( xInteractionRequestImpl.get() ); + aContinuations[1] = new ::ucbhelper::InteractionApprove( xInteractionRequestImpl.get() ); + xInteractionRequestImpl->setContinuations( aContinuations ); + + xHandler->handle( xInteractionRequestImpl.get() ); + + ::rtl::Reference< ::ucbhelper::InteractionContinuation > xSelected = xInteractionRequestImpl->getSelection(); + if ( uno::Reference< task::XInteractionAbort >( xSelected.get(), uno::UNO_QUERY ).is() ) + { + SetError( ERRCODE_ABORT ); + } + } + catch ( uno::Exception& ) + {} + } + } + } +} + +//------------------------------------------------------------------ +util::DateTime SfxMedium::GetInitFileDate() +{ + if ( !pImp->m_bGotDateTime && GetContent().is() ) + { + try + { + pImp->aContent.getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "DateModified" )) ) >>= pImp->m_aDateTime; + pImp->m_bGotDateTime = sal_True; + } + catch ( ::com::sun::star::uno::Exception& ) + { + } + } + + return pImp->m_aDateTime; +} + +//------------------------------------------------------------------ Reference < XContent > SfxMedium::GetContent() const { if ( !pImp->aContent.get().is() ) @@ -692,9 +790,17 @@ sal_Bool SfxMedium::Commit() Transfer_Impl(); } + sal_Bool bResult = ( GetError() == SVSTREAM_OK ); + + if ( bResult ) + { + pImp->m_bGotDateTime = sal_False; + GetInitFileDate(); + } + // remove truncation mode from the flags - nStorOpenMode &= ( ~STREAM_TRUNC ); - return GetError() == SVSTREAM_OK; + nStorOpenMode &= (~STREAM_TRUNC); + return bResult; } //------------------------------------------------------------------ @@ -924,7 +1030,116 @@ void SfxMedium::SetPasswordToStorage_Impl() } //------------------------------------------------------------------ -sal_Bool SfxMedium::LockOrigFileOnDemand( sal_Bool bLoading ) +sal_Int8 SfxMedium::ShowLockedDocumentDialog( const uno::Sequence< ::rtl::OUString >& aData, sal_Bool bIsLoading, sal_Bool bOwnLock ) +{ + sal_Int8 nResult = LOCK_UI_NOLOCK; + + // show the interaction regarding the document opening + uno::Reference< task::XInteractionHandler > xHandler = GetInteractionHandler(); + + if ( ::svt::DocumentLockFile::IsInteractionAllowed() && xHandler.is() && ( bIsLoading || bOwnLock ) ) + { + ::rtl::OUString aDocumentURL = GetURLObject().GetLastName(); + ::rtl::OUString aInfo; + ::rtl::Reference< ::ucbhelper::InteractionRequest > xInteractionRequestImpl; + + if ( bOwnLock ) + { + if ( aData.getLength() > LOCKFILE_EDITTIME_ID ) + aInfo = aData[LOCKFILE_EDITTIME_ID]; + + xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny( + document::OwnLockOnDocumentRequest( ::rtl::OUString(), uno::Reference< uno::XInterface >(), aDocumentURL, aInfo, !bIsLoading ) ) ); + } + else + { + if ( aData.getLength() > LOCKFILE_EDITTIME_ID ) + { + if ( aData[LOCKFILE_OOOUSERNAME_ID].getLength() ) + aInfo = aData[LOCKFILE_OOOUSERNAME_ID]; + else + aInfo = aData[LOCKFILE_SYSUSERNAME_ID]; + + if ( aInfo.getLength() && aData[LOCKFILE_EDITTIME_ID].getLength() ) + { + aInfo += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " ( " ) ); + aInfo += aData[LOCKFILE_EDITTIME_ID]; + aInfo += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " )" ) ); + } + } + + if ( bIsLoading ) + { + xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny( + document::LockedDocumentRequest( ::rtl::OUString(), uno::Reference< uno::XInterface >(), aDocumentURL, aInfo ) ) ); + } + else + { + xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny( + document::LockedOnSavingRequest( ::rtl::OUString(), uno::Reference< uno::XInterface >(), aDocumentURL, aInfo ) ) ); + + } + } + + uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( 3 ); + aContinuations[0] = new ::ucbhelper::InteractionAbort( xInteractionRequestImpl.get() ); + aContinuations[1] = new ::ucbhelper::InteractionApprove( xInteractionRequestImpl.get() ); + aContinuations[2] = new ::ucbhelper::InteractionDisapprove( xInteractionRequestImpl.get() ); + xInteractionRequestImpl->setContinuations( aContinuations ); + + xHandler->handle( xInteractionRequestImpl.get() ); + + ::rtl::Reference< ::ucbhelper::InteractionContinuation > xSelected = xInteractionRequestImpl->getSelection(); + if ( uno::Reference< task::XInteractionAbort >( xSelected.get(), uno::UNO_QUERY ).is() ) + { + SetError( ERRCODE_ABORT ); + } + else if ( uno::Reference< task::XInteractionDisapprove >( xSelected.get(), uno::UNO_QUERY ).is() ) + { + // own lock on loading, user has selected to ignore the lock + // own lock on saving, user has selected to ignore the lock + // alien lock on loading, user has selected to edit a copy of document + // TODO/LATER: alien lock on saving, user has selected to do SaveAs to different location + if ( bIsLoading && !bOwnLock ) + { + // means that a copy of the document should be opened + GetItemSet()->Put( SfxBoolItem( SID_TEMPLATE, sal_True ) ); + } + else if ( bOwnLock ) + nResult = LOCK_UI_SUCCEEDED; + } + else // if ( XSelected == aContinuations[1] ) + { + // own lock on loading, user has selected to open readonly + // own lock on saving, user has selected to open readonly + // alien lock on loading, user has selected to retry saving + // TODO/LATER: alien lock on saving, user has selected to retry saving + + if ( bIsLoading ) + GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) ); + else + nResult = LOCK_UI_TRY; + } + } + else + { + if ( bIsLoading ) + { + // if no interaction handler is provided the default answer is open readonly + // that usually happens in case the document is loaded per API + // so the document must be opened readonly for backward compatibility + GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) ); + } + else + SetError( ERRCODE_IO_ACCESSDENIED ); + + } + + return nResult; +} + +//------------------------------------------------------------------ +sal_Bool SfxMedium::LockOrigFileOnDemand( sal_Bool bLoading, sal_Bool bNoUI ) { // returns true if the document can be opened for editing ( even if it should be a copy ) // otherwise the document should be opened readonly @@ -936,103 +1151,141 @@ sal_Bool SfxMedium::LockOrigFileOnDemand( sal_Bool bLoading ) { // the special file locking should be used only for file URLs + // in case of storing the document should request the output before locking + if ( bLoading ) + { + // let the stream be opened to check the system file locking + GetMedium_Impl(); + } + + SFX_ITEMSET_ARG( GetItemSet(), pReadOnlyItem, SfxBoolItem, SID_DOC_READONLY, sal_False); + // no locking is necessary on loading if the document is explicitly opened as copy SFX_ITEMSET_ARG( GetItemSet(), pTemplateItem, SfxBoolItem, SID_TEMPLATE, sal_False); bResult = ( bLoading && pTemplateItem && pTemplateItem->GetValue() ); - try - { - if ( !bResult && !IsReadOnly() ) + if ( !bResult && ( !IsReadOnly() || pImp->m_bHandleSysLocked ) ) + { + sal_Int8 bUIStatus = LOCK_UI_NOLOCK; + + // check whether system file locking has been used, the default value is false + sal_Bool bUseSystemLock = sal_False; + try { - ::svt::DocumentLockFile aLockFile( aLogicName ); - bResult = aLockFile.CreateOwnLockFile(); - pImp->m_bLocked = bResult; - if ( !bResult ) - { - uno::Sequence< ::rtl::OUString > aData = aLockFile.GetLockData(); - uno::Sequence< ::rtl::OUString > aOwnData = aLockFile.GenerateOwnEntry(); - - if ( aData.getLength() > LOCKFILE_USERURL_ID - && aOwnData.getLength() > LOCKFILE_USERURL_ID - && aOwnData[LOCKFILE_SYSUSERNAME_ID].equals( aData[LOCKFILE_SYSUSERNAME_ID] ) - && aOwnData[LOCKFILE_LOCALHOST_ID].equals( aData[LOCKFILE_LOCALHOST_ID] ) - && aOwnData[LOCKFILE_USERURL_ID].equals( aData[LOCKFILE_USERURL_ID] ) ) - { - // this is own lock, it could remain because of crash - pImp->m_bLocked = bResult = sal_True; - } + uno::Reference< uno::XInterface > xCommonConfig = ::comphelper::ConfigurationHelper::openConfig( + ::comphelper::getProcessServiceFactory(), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common" ) ), + ::comphelper::ConfigurationHelper::E_STANDARD ); + if ( !xCommonConfig.is() ) + throw uno::RuntimeException(); - if ( !bResult ) + ::comphelper::ConfigurationHelper::readRelativeKey( + xCommonConfig, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Misc/" ) ), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseDocumentSystemFileLocking" ) ) ) >>= bUseSystemLock; + } + catch( const uno::Exception& ) + { + } + + // TODO/LATER: This implementation does not allow to detect the system lock on saving here, actually this is no big problem + if ( bUseSystemLock && !pImp->xStream.is() && !pOutStream ) + pImp->m_bHandleSysLocked = sal_True; // if system lock is used the writeable stream should be available + + do + { + try + { + ::svt::DocumentLockFile aLockFile( aLogicName ); + if ( !pImp->m_bHandleSysLocked ) { - if ( bLoading ) + try { - // show the interaction regarding the document opening - uno::Reference< task::XInteractionHandler > xHandler = GetInteractionHandler(); - if ( ::svt::DocumentLockFile::IsInteractionAllowed() && xHandler.is() ) + bResult = aLockFile.CreateOwnLockFile(); + } + catch ( ucb::InteractiveIOException& e ) + { + if ( e.Code == IOErrorCode_INVALID_PARAMETER ) { - document::LockedDocumentRequest aRequest; - aRequest.DocumentURL = GetURLObject().GetLastName(); - if ( aData.getLength() > LOCKFILE_EDITTIME_ID ) + // it looks like the lock file name is not accepted by the content + if ( !bUseSystemLock ) { - if ( aData[LOCKFILE_OOOUSERNAME_ID].getLength() ) - aRequest.UserInfo += aData[LOCKFILE_OOOUSERNAME_ID]; - else - aRequest.UserInfo += aData[LOCKFILE_SYSUSERNAME_ID]; - - if ( aRequest.UserInfo.getLength() && aData[LOCKFILE_EDITTIME_ID].getLength() ) + // system file locking is not active, ask user whether he wants to open the document without any locking + uno::Reference< task::XInteractionHandler > xHandler = GetInteractionHandler(); + + if ( xHandler.is() ) { - aRequest.UserInfo += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " ( " ) ); - aRequest.UserInfo += aData[LOCKFILE_EDITTIME_ID]; - aRequest.UserInfo += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " )" ) ); - } - } + ::rtl::Reference< ::ucbhelper::InteractionRequest > xIgnoreRequestImpl + = new ::ucbhelper::InteractionRequest( uno::makeAny( document::LockFileIgnoreRequest() ) ); - ::rtl::Reference< ::ucbhelper::InteractionRequest > xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny( aRequest ) ); + uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( 2 ); + aContinuations[0] = new ::ucbhelper::InteractionAbort( xIgnoreRequestImpl.get() ); + aContinuations[1] = new ::ucbhelper::InteractionApprove( xIgnoreRequestImpl.get() ); + xIgnoreRequestImpl->setContinuations( aContinuations ); + xHandler->handle( xIgnoreRequestImpl.get() ); - uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( 3 ); - aContinuations[0] = new ::ucbhelper::InteractionAbort( xInteractionRequestImpl.get() ); - aContinuations[1] = new ::ucbhelper::InteractionApprove( xInteractionRequestImpl.get() ); - aContinuations[2] = new ::ucbhelper::InteractionDisapprove( xInteractionRequestImpl.get() ); - xInteractionRequestImpl->setContinuations( aContinuations ); - - xHandler->handle( xInteractionRequestImpl.get() ); - - ::rtl::Reference< ::ucbhelper::InteractionContinuation > xSelected = xInteractionRequestImpl->getSelection(); - if ( uno::Reference< task::XInteractionAbort >( xSelected.get(), uno::UNO_QUERY ).is() ) - { - SetError( ERRCODE_ABORT ); + ::rtl::Reference< ::ucbhelper::InteractionContinuation > xSelected = xIgnoreRequestImpl->getSelection(); + bResult = ( uno::Reference< task::XInteractionApprove >( xSelected.get(), uno::UNO_QUERY ).is() ); + } } - else if ( uno::Reference< task::XInteractionDisapprove >( xSelected.get(), uno::UNO_QUERY ).is() ) - { - // means that a copy of the document should be opened - GetItemSet()->Put( SfxBoolItem( SID_TEMPLATE, sal_True ) ); + else bResult = sal_True; - } - // Approve means open readonly here, do not need to do anything - // else if ( XSelected == aContinuations[1] ) } else + throw; + } + } + + + if ( !bResult ) + { + uno::Sequence< ::rtl::OUString > aData; + try + { + // impossibility to get data is no real problem + aData = aLockFile.GetLockData(); + } + catch( uno::Exception ) {} + + sal_Bool bOwnLock = sal_False; + + if ( !pImp->m_bHandleSysLocked ) + { + uno::Sequence< ::rtl::OUString > aOwnData = aLockFile.GenerateOwnEntry(); + bOwnLock = ( aData.getLength() > LOCKFILE_USERURL_ID + && aOwnData.getLength() > LOCKFILE_USERURL_ID + && aOwnData[LOCKFILE_SYSUSERNAME_ID].equals( aData[LOCKFILE_SYSUSERNAME_ID] ) ); + + if ( bOwnLock + && aOwnData[LOCKFILE_LOCALHOST_ID].equals( aData[LOCKFILE_LOCALHOST_ID] ) + && aOwnData[LOCKFILE_USERURL_ID].equals( aData[LOCKFILE_USERURL_ID] ) ) { - // if no interaction handler is provided the default answer is yes - // that usually happens in case the document is loaded per API - // so the document must be opened readonly for backward compatibility - GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) ); + // this is own lock from the same installation, it could remain because of crash + bResult = sal_True; } } - else + + if ( !bResult && !bNoUI ) { - // TODO/LATER: introduce a new interaction for this - // this is saving, show just an error - SetError( ERRCODE_IO_ACCESSDENIED ); + bUIStatus = ShowLockedDocumentDialog( aData, bLoading, bOwnLock ); + if ( bUIStatus == LOCK_UI_SUCCEEDED ) + { + // take the ownership over the lock file + bResult = aLockFile.OverwriteOwnLockFile(); + } } + + pImp->m_bHandleSysLocked = sal_False; } } - } - } - catch( uno::Exception& ) - { + catch( uno::Exception& ) + { + } + } while( !bResult && bUIStatus == LOCK_UI_TRY ); + + pImp->m_bLocked = bResult; } if ( !bResult && GetError() == ERRCODE_NONE ) @@ -1787,7 +2040,6 @@ void SfxMedium::Transfer_Impl() SFX_ITEMSET_ARG( pSet, pOutStreamItem, SfxUnoAnyItem, SID_OUTPUTSTREAM, sal_False); if( pOutStreamItem && ( pOutStreamItem->GetValue() >>= rOutStream ) ) { - // write directly to the stream if ( pImp->xStorage.is() ) CloseStorage(); @@ -1983,10 +2235,6 @@ void SfxMedium::Transfer_Impl() CloseStreams_Impl(); - // don't create content before Close(), because if the storage was opened in direct mode, it will be flushed - // in Close() and this leads to a transfer command executed in the package, which currently is implemented as - // remove+move in the file FCP. The "remove" is notified to the ::ucbhelper::Content, that clears its URL and its - // content reference in this notification and thus will never get back any URL, so my transfer will fail! ::ucbhelper::Content::create( aSource.GetMainURL( INetURLObject::NO_DECODE ), xEnv, aSourceContent ); // check for external parameters that may customize the handling of NameClash situations @@ -2269,6 +2517,7 @@ void SfxMedium::GetMedium_Impl() { TransformItems( SID_OPENDOC, *GetItemSet(), xProps ); comphelper::MediaDescriptor aMedium( xProps ); + sal_Bool bRequestedReadOnly = aMedium.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_READONLY(), sal_False ); if ( bFromTempFile ) { @@ -2279,15 +2528,24 @@ void SfxMedium::GetMedium_Impl() else if ( ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) ) ) { // use the special locking approach only for file URLs - aMedium.addInputStreamNoLock(); + aMedium.addInputStreamOwnLock(); } else aMedium.addInputStream(); + // the warning is shown if the user wants to edit the document, but it is not possible + pImp->m_bHandleSysLocked = ( !bRequestedReadOnly && aMedium.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_READONLY(), sal_False ) ); + sal_Bool bReadOnly = sal_False; aMedium[comphelper::MediaDescriptor::PROP_READONLY()] >>= bReadOnly; if ( bReadOnly ) + { + SFX_ITEMSET_ARG( GetItemSet(), pROItem, SfxBoolItem, SID_DOC_READONLY, sal_False); + BOOL bForceWritable = ( pROItem && !pROItem->GetValue() ); GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) ); + if( bForceWritable ) + SetError( ERRCODE_IO_ACCESSDENIED ); + } //TODO/MBA: what happens if property is not there?! GetContent(); @@ -2319,6 +2577,8 @@ void SfxMedium::GetMedium_Impl() pInStream = utl::UcbStreamHelper::CreateStream( pImp->xInputStream ); } + GetInitFileDate(); + pImp->bDownloadDone = sal_True; pImp->aDoneLink.ClearPendingCall(); pImp->aDoneLink.Call( (void*) GetError() ); @@ -2680,10 +2940,10 @@ void SfxMedium::UnlockFile() { try { + pImp->m_bLocked = sal_False; ::svt::DocumentLockFile aLockFile( aLogicName ); - // TODO/LATER: A worning could be shown in case the file is not the own one + // TODO/LATER: A warning could be shown in case the file is not the own one aLockFile.RemoveFile(); - pImp->m_bLocked = sal_False; } catch( uno::Exception& ) {} @@ -3871,7 +4131,7 @@ BOOL SfxMedium::IsOpen() const GetItemSet()->ClearItem( SID_DOC_READONLY ); GetMedium_Impl(); - LockOrigFileOnDemand( sal_False ); + LockOrigFileOnDemand( sal_False, sal_False ); CreateTempFile(); GetMedium_Impl(); @@ -3929,7 +4189,7 @@ sal_Bool SfxMedium::SwitchDocumentToFile( ::rtl::OUString aURL ) // open the temporary file based document GetMedium_Impl(); - LockOrigFileOnDemand( sal_False ); + LockOrigFileOnDemand( sal_False, sal_False ); CreateTempFile(); GetMedium_Impl(); |