From a30f8c4daaab5bfc850c18b2b0bce3fdb2281a1f Mon Sep 17 00:00:00 2001 From: Mike Kaganski Date: Wed, 21 Feb 2018 00:45:04 +0300 Subject: tdf#115742: allow ignoring stale lockfile on save This change reuses TryLaterQueryBox, but only uses the new option to ignore the lock and save. Other options ("Try Again" and "Save As") are not used, because this functionality is not implemented currently (TODO/LATER). Change-Id: Idf825be23cf97d2b338c0cf5d532f8460843bf48 Reviewed-on: https://gerrit.libreoffice.org/50371 Tested-by: Jenkins Reviewed-by: Mike Kaganski --- sfx2/source/doc/docfile.cxx | 51 ++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 14 deletions(-) (limited to 'sfx2') diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx index 466372c28bb2..9635f872b210 100644 --- a/sfx2/source/doc/docfile.cxx +++ b/sfx2/source/doc/docfile.cxx @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -65,6 +66,7 @@ #include #include #include +#include #include #include #include @@ -840,7 +842,7 @@ SfxMedium::ShowLockResult SfxMedium::ShowLockedDocumentDialog( const LockFileEnt // show the interaction regarding the document opening uno::Reference< task::XInteractionHandler > xHandler = GetInteractionHandler(); - if ( ::svt::DocumentLockFile::IsInteractionAllowed() && xHandler.is() && ( bIsLoading || bOwnLock ) ) + if ( ::svt::DocumentLockFile::IsInteractionAllowed() && xHandler.is() && ( bIsLoading || !bHandleSysLocked || bOwnLock ) ) { OUString aDocumentURL = GetURLObject().GetLastName(); OUString aInfo; @@ -855,27 +857,32 @@ SfxMedium::ShowLockResult SfxMedium::ShowLockedDocumentDialog( const LockFileEnt xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny( document::OwnLockOnDocumentRequest( OUString(), uno::Reference< uno::XInterface >(), aDocumentURL, aInfo, !bIsLoading ) ) ); } - else /*logically therefore bIsLoading is set */ + else { + // Use a fourth continuation in case there's no filesystem lock: + // "Ignore lock file and open/replace the document" + if (!bHandleSysLocked) + nContinuations = 4; + if ( !aData[LockFileComponent::OOOUSERNAME].isEmpty() ) aInfo = aData[LockFileComponent::OOOUSERNAME]; else aInfo = aData[LockFileComponent::SYSUSERNAME]; if ( !aInfo.isEmpty() && !aData[LockFileComponent::EDITTIME].isEmpty() ) + aInfo += " ( " + aData[LockFileComponent::EDITTIME] + " )"; + + if (!bIsLoading) // so, !bHandleSysLocked { - aInfo += " ( " ; - aInfo += aData[LockFileComponent::EDITTIME]; - aInfo += " )"; + xInteractionRequestImpl = new ::ucbhelper::InteractionRequest(uno::makeAny( + document::LockedOnSavingRequest(OUString(), uno::Reference< uno::XInterface >(), aDocumentURL, aInfo))); + // Currently, only the last "Retry" continuation (meaning ignore the lock and try overwriting) can be returned. + } + else /*logically therefore bIsLoading is set */ + { + xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny( + document::LockedDocumentRequest( OUString(), uno::Reference< uno::XInterface >(), aDocumentURL, aInfo ) ) ); } - - xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny( - document::LockedDocumentRequest( OUString(), uno::Reference< uno::XInterface >(), aDocumentURL, aInfo ) ) ); - - // Use a fourth continuation in case there's no filesystem lock: - // "Ignore lock file and open the document" - if (!bHandleSysLocked) - nContinuations = 4; } uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations(nContinuations); @@ -885,7 +892,7 @@ SfxMedium::ShowLockResult SfxMedium::ShowLockedDocumentDialog( const LockFileEnt if (nContinuations > 3) { // We use InteractionRetry to reflect that user wants to - // ignore the (stale?) alien lock file and open the document + // ignore the (stale?) alien lock file and open/overwrite the document aContinuations[3] = new ::ucbhelper::InteractionRetry(xInteractionRequestImpl.get()); } xInteractionRequestImpl->setContinuations( aContinuations ); @@ -1216,6 +1223,22 @@ SfxMedium::LockFileResult SfxMedium::LockOrigFileOnDemand( bool bLoading, bool b // if system lock is used the writeable stream should be available bool bHandleSysLocked = ( bLoading && bUseSystemLock && !pImpl->xStream.is() && !pImpl->m_pOutStream ); + // The file is attempted to get locked for the duration of lockfile creation on save + std::unique_ptr pFileLock; + if (!bLoading && bUseSystemLock && pImpl->pTempFile) + { + INetURLObject aDest(GetURLObject()); + OUString aDestURL(aDest.GetMainURL(INetURLObject::DecodeMechanism::NONE)); + + if (comphelper::isFileUrl(aDestURL) || !aDest.removeSegment()) + { + pFileLock = o3tl::make_unique(aDestURL); + auto rc = pFileLock->open(osl_File_OpenFlag_Write); + if (rc == osl::FileBase::E_ACCES) + bHandleSysLocked = true; + } + } + do { try -- cgit