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 | 3dfe5a3feda289b66e92f17550e359d6c2460c0d (patch) | |
tree | 2d306b7ef59c57b80ed1b9ffab3224b0d95a83f2 /sfx2 | |
parent | 13e27b36a954d5dac7e1b35e3752656050074c1d (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')
-rw-r--r-- | sfx2/inc/sfx2/docfile.hxx | 8 | ||||
-rw-r--r-- | sfx2/source/doc/docfile.cxx | 424 | ||||
-rw-r--r-- | sfx2/source/doc/objstor.cxx | 23 | ||||
-rw-r--r-- | sfx2/source/view/viewfrm.cxx | 5 |
4 files changed, 371 insertions, 89 deletions
diff --git a/sfx2/inc/sfx2/docfile.hxx b/sfx2/inc/sfx2/docfile.hxx index 50007ce3a35c..75900531a70f 100644 --- a/sfx2/inc/sfx2/docfile.hxx +++ b/sfx2/inc/sfx2/docfile.hxx @@ -35,6 +35,7 @@ #include "sfx2/dllapi.h" #include "sal/types.h" #include <com/sun/star/util/RevisionTag.hpp> +#include <com/sun/star/util/DateTime.hpp> #include <com/sun/star/io/XOutputStream.hpp> #include <com/sun/star/io/XInputStream.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> @@ -180,6 +181,10 @@ public: #else const INetURLObject& GetURLObject() const; #endif + + void CheckFileDate( const ::com::sun::star::util::DateTime& aInitDate ); + ::com::sun::star::util::DateTime GetInitFileDate(); + ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XContent > GetContent() const; const String& GetPhysicalName() const; void SetTemporary( sal_Bool bTemp ); @@ -223,7 +228,8 @@ public: SAL_DLLPRIVATE ErrCode Unpack_Impl( const String& ); sal_Bool IsStorage(); - sal_Bool LockOrigFileOnDemand( sal_Bool bLoading ); + 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(); ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > GetStorage(); diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx index 367dffbc6fa3..dc49ee6b1e2b 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() || pImp->m_bHandleSysLocked ) ) { - if ( !bResult && !IsReadOnly() ) + 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]; + // 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 ( aRequest.UserInfo.getLength() && aData[LOCKFILE_EDITTIME_ID].getLength() ) + 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 > xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny( aRequest ) ); + ::rtl::Reference< ::ucbhelper::InteractionRequest > xIgnoreRequestImpl + = new ::ucbhelper::InteractionRequest( uno::makeAny( document::LockFileIgnoreRequest() ) ); + 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 ); - 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( xIgnoreRequestImpl.get() ); - 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(); diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx index 7745abd8e68a..dff75d14d459 100644 --- a/sfx2/source/doc/objstor.cxx +++ b/sfx2/source/doc/objstor.cxx @@ -637,7 +637,7 @@ sal_Bool SfxObjectShell::DoLoad( SfxMedium *pMed ) EnableSetModified( sal_False ); - pMedium->LockOrigFileOnDemand( sal_True ); + pMedium->LockOrigFileOnDemand( sal_True, sal_False ); if ( GetError() == ERRCODE_NONE && bOwnStorageFormat && ( !pFilter || !( pFilter->GetFilterFlags() & SFX_FILTER_STARONEFILTER ) ) ) { uno::Reference< embed::XStorage > xStorage; @@ -1222,6 +1222,8 @@ sal_Bool SfxObjectShell::SaveTo_Impl { bStoreToSameLocation = sal_True; + rMedium.CheckFileDate( pMedium->GetInitFileDate() ); + if ( bCopyTo && GetCreateMode() != SFX_CREATE_MODE_EMBEDDED ) { // export to the same location is vorbidden @@ -1312,19 +1314,32 @@ sal_Bool SfxObjectShell::SaveTo_Impl } } } + else + { + // This is SaveAs or export action, prepare the target medium + rMedium.CloseAndRelease(); + if ( bStorageBasedTarget ) + { + rMedium.GetOutputStorage(); + } + else + { + rMedium.CreateTempFileNoCopy(); + rMedium.GetOutStream(); + } + } // TODO/LATER: error handling if( rMedium.GetErrorCode() || pMedium->GetErrorCode() || GetErrorCode() ) return sal_False; - rMedium.LockOrigFileOnDemand( sal_False ); + rMedium.LockOrigFileOnDemand( sal_False, sal_False ); + if ( bStorageBasedTarget ) { if ( rMedium.GetErrorCode() ) return sal_False; - rMedium.GetOutputStorage(); - // If the filter is a "cross export" filter ( f.e. a filter for exporting an impress document from // a draw document ), the ClassId of the destination storage is different from the ClassId of this // document. It can be retrieved from the default filter for the desired target format diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx index 12e7cead9e94..5565b3a10f49 100644 --- a/sfx2/source/view/viewfrm.cxx +++ b/sfx2/source/view/viewfrm.cxx @@ -472,9 +472,10 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) pMed->CloseAndRelease(); pMed->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, !( nOpenMode & STREAM_WRITE ) ) ); pMed->SetOpenMode( nOpenMode, pMed->IsDirect() ); + pMed->CompleteReOpen(); if ( nOpenMode & STREAM_WRITE ) - pMed->LockOrigFileOnDemand( sal_False ); + pMed->LockOrigFileOnDemand( sal_False, sal_True ); // LockOrigFileOnDemand might set the readonly flag itself, it should be set back pMed->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, !( nOpenMode & STREAM_WRITE ) ) ); @@ -777,7 +778,7 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) { // back to old medium pMedium->ReOpen(); - pMedium->LockOrigFileOnDemand( sal_True ); + pMedium->LockOrigFileOnDemand( sal_False, sal_True ); xOldObj->DoSaveCompleted( pMedium ); } |