Kaydet (Commit) a30f8c4d authored tarafından Mike Kaganski's avatar Mike Kaganski

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/50371Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarMike Kaganski <mike.kaganski@collabora.com>
üst 5a1fabb9
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <com/sun/star/container/XChild.hpp> #include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/document/XDocumentRevisionListPersistence.hpp> #include <com/sun/star/document/XDocumentRevisionListPersistence.hpp>
#include <com/sun/star/document/LockedDocumentRequest.hpp> #include <com/sun/star/document/LockedDocumentRequest.hpp>
#include <com/sun/star/document/LockedOnSavingRequest.hpp>
#include <com/sun/star/document/OwnLockOnDocumentRequest.hpp> #include <com/sun/star/document/OwnLockOnDocumentRequest.hpp>
#include <com/sun/star/document/LockFileIgnoreRequest.hpp> #include <com/sun/star/document/LockFileIgnoreRequest.hpp>
#include <com/sun/star/document/LockFileCorruptRequest.hpp> #include <com/sun/star/document/LockFileCorruptRequest.hpp>
...@@ -65,6 +66,7 @@ ...@@ -65,6 +66,7 @@
#include <com/sun/star/beans/PropertyValue.hpp> #include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/security/DocumentSignatureInformation.hpp> #include <com/sun/star/security/DocumentSignatureInformation.hpp>
#include <com/sun/star/security/DocumentDigitalSignatures.hpp> #include <com/sun/star/security/DocumentDigitalSignatures.hpp>
#include <o3tl/make_unique.hxx>
#include <tools/urlobj.hxx> #include <tools/urlobj.hxx>
#include <unotools/configmgr.hxx> #include <unotools/configmgr.hxx>
#include <unotools/tempfile.hxx> #include <unotools/tempfile.hxx>
...@@ -840,7 +842,7 @@ SfxMedium::ShowLockResult SfxMedium::ShowLockedDocumentDialog( const LockFileEnt ...@@ -840,7 +842,7 @@ SfxMedium::ShowLockResult SfxMedium::ShowLockedDocumentDialog( const LockFileEnt
// show the interaction regarding the document opening // show the interaction regarding the document opening
uno::Reference< task::XInteractionHandler > xHandler = GetInteractionHandler(); 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 aDocumentURL = GetURLObject().GetLastName();
OUString aInfo; OUString aInfo;
...@@ -855,27 +857,32 @@ SfxMedium::ShowLockResult SfxMedium::ShowLockedDocumentDialog( const LockFileEnt ...@@ -855,27 +857,32 @@ SfxMedium::ShowLockResult SfxMedium::ShowLockedDocumentDialog( const LockFileEnt
xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny( xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny(
document::OwnLockOnDocumentRequest( OUString(), uno::Reference< uno::XInterface >(), aDocumentURL, aInfo, !bIsLoading ) ) ); 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() ) if ( !aData[LockFileComponent::OOOUSERNAME].isEmpty() )
aInfo = aData[LockFileComponent::OOOUSERNAME]; aInfo = aData[LockFileComponent::OOOUSERNAME];
else else
aInfo = aData[LockFileComponent::SYSUSERNAME]; aInfo = aData[LockFileComponent::SYSUSERNAME];
if ( !aInfo.isEmpty() && !aData[LockFileComponent::EDITTIME].isEmpty() ) if ( !aInfo.isEmpty() && !aData[LockFileComponent::EDITTIME].isEmpty() )
aInfo += " ( " + aData[LockFileComponent::EDITTIME] + " )";
if (!bIsLoading) // so, !bHandleSysLocked
{ {
aInfo += " ( " ; xInteractionRequestImpl = new ::ucbhelper::InteractionRequest(uno::makeAny(
aInfo += aData[LockFileComponent::EDITTIME]; document::LockedOnSavingRequest(OUString(), uno::Reference< uno::XInterface >(), aDocumentURL, aInfo)));
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); uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations(nContinuations);
...@@ -885,7 +892,7 @@ SfxMedium::ShowLockResult SfxMedium::ShowLockedDocumentDialog( const LockFileEnt ...@@ -885,7 +892,7 @@ SfxMedium::ShowLockResult SfxMedium::ShowLockedDocumentDialog( const LockFileEnt
if (nContinuations > 3) if (nContinuations > 3)
{ {
// We use InteractionRetry to reflect that user wants to // 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()); aContinuations[3] = new ::ucbhelper::InteractionRetry(xInteractionRequestImpl.get());
} }
xInteractionRequestImpl->setContinuations( aContinuations ); xInteractionRequestImpl->setContinuations( aContinuations );
...@@ -1216,6 +1223,22 @@ SfxMedium::LockFileResult SfxMedium::LockOrigFileOnDemand( bool bLoading, bool b ...@@ -1216,6 +1223,22 @@ SfxMedium::LockFileResult SfxMedium::LockOrigFileOnDemand( bool bLoading, bool b
// if system lock is used the writeable stream should be available // if system lock is used the writeable stream should be available
bool bHandleSysLocked = ( bLoading && bUseSystemLock && !pImpl->xStream.is() && !pImpl->m_pOutStream ); 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<osl::File> 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<osl::File>(aDestURL);
auto rc = pFileLock->open(osl_File_OpenFlag_Write);
if (rc == osl::FileBase::E_ACCES)
bHandleSysLocked = true;
}
}
do do
{ {
try try
......
...@@ -59,6 +59,7 @@ ...@@ -59,6 +59,7 @@
#define STR_TRYLATER_TITLE NC_("STR_TRYLATER_TITLE", "Document in Use") #define STR_TRYLATER_TITLE NC_("STR_TRYLATER_TITLE", "Document in Use")
#define STR_TRYLATER_MSG NC_("STR_TRYLATER_MSG", "Document file '$(ARG1)' is locked for editing by:\n\n$(ARG2)\n\nTry again later to save document or save a copy of that document.\n\n") #define STR_TRYLATER_MSG NC_("STR_TRYLATER_MSG", "Document file '$(ARG1)' is locked for editing by:\n\n$(ARG2)\n\nTry again later to save document or save a copy of that document.\n\n")
#define STR_OVERWRITE_IGNORELOCK_MSG NC_("STR_OVERWRITE_IGNORELOCK_MSG", "Document file '$(ARG1)' is locked for editing by:\n\n$(ARG2)\n\nYou may try to ignore the file locking and overwrite the existing document.\n\n")
#define STR_TRYLATER_RETRYSAVING_BTN NC_("STR_TRYLATER_RETRYSAVING_BTN", "~Retry Saving") #define STR_TRYLATER_RETRYSAVING_BTN NC_("STR_TRYLATER_RETRYSAVING_BTN", "~Retry Saving")
#define STR_TRYLATER_SAVEAS_BTN NC_("STR_TRYLATER_SAVEAS_BTN", "~Save As...") #define STR_TRYLATER_SAVEAS_BTN NC_("STR_TRYLATER_SAVEAS_BTN", "~Save As...")
......
...@@ -105,11 +105,12 @@ handleLockedDocumentRequest_( ...@@ -105,11 +105,12 @@ handleLockedDocumentRequest_(
? aInfo ? aInfo
: Translate::get( STR_UNKNOWNUSER, : Translate::get( STR_UNKNOWNUSER,
aResLocale ) ); aResLocale ) );
aMessage = Translate::get(STR_TRYLATER_MSG, aResLocale); aMessage = Translate::get(xRetry.is() ? STR_OVERWRITE_IGNORELOCK_MSG : STR_TRYLATER_MSG,
aResLocale);
aMessage = UUIInteractionHelper::replaceMessageWithArguments( aMessage = UUIInteractionHelper::replaceMessageWithArguments(
aMessage, aArguments ); aMessage, aArguments );
ScopedVclPtrInstance< TryLaterQueryBox > xDialog(pParent, aResLocale, aMessage); ScopedVclPtrInstance< TryLaterQueryBox > xDialog(pParent, aResLocale, aMessage, xRetry.is());
nResult = xDialog->Execute(); nResult = xDialog->Execute();
} }
else if ( nMode == UUI_DOC_OWN_LOAD_LOCK || else if ( nMode == UUI_DOC_OWN_LOAD_LOCK ||
......
...@@ -21,18 +21,33 @@ ...@@ -21,18 +21,33 @@
#include <strings.hrc> #include <strings.hrc>
#include "trylater.hxx" #include "trylater.hxx"
TryLaterQueryBox::TryLaterQueryBox(vcl::Window* pParent, const std::locale& rResLocale, const OUString& aMessage) TryLaterQueryBox::TryLaterQueryBox(vcl::Window* pParent, const std::locale& rResLocale, const OUString& aMessage, bool bEnableOverride)
: MessBox(pParent, MessBoxStyle::NONE, 0, Translate::get(STR_TRYLATER_TITLE, rResLocale), aMessage) : MessBox(pParent, MessBoxStyle::NONE, 0, Translate::get(STR_TRYLATER_TITLE, rResLocale), aMessage)
{ {
SetImage(GetStandardQueryBoxImage()); SetImage(GetStandardQueryBoxImage());
AddButton(Translate::get(STR_TRYLATER_RETRYSAVING_BTN, rResLocale), RET_YES, // Currently we don't have the retry/save-as functionality implemented for cases when file is locked.
ButtonDialogFlags::Default | ButtonDialogFlags::OK | ButtonDialogFlags::Focus); // So threat them mutually exclusive with overwrite here. TODO/LATER: just add the overwrite option
AddButton(Translate::get(STR_TRYLATER_SAVEAS_BTN, rResLocale), RET_NO); // as third option when retrying and saving with another name would be possible along with overwriting
AddButton( StandardButtonType::Cancel, RET_CANCEL, ButtonDialogFlags::Cancel ); if (bEnableOverride)
{
AddButton(Translate::get(STR_FILECHANGED_SAVEANYWAY_BTN, rResLocale), RET_IGNORE,
ButtonDialogFlags::OK);
AddButton(StandardButtonType::Cancel, RET_CANCEL,
ButtonDialogFlags::Default | ButtonDialogFlags::Cancel | ButtonDialogFlags::Focus);
SetButtonHelpText( RET_YES, OUString() ); SetButtonHelpText(RET_IGNORE, OUString());
SetButtonHelpText( RET_NO, OUString() ); }
else
{
AddButton(Translate::get(STR_TRYLATER_RETRYSAVING_BTN, rResLocale), RET_YES,
ButtonDialogFlags::Default | ButtonDialogFlags::OK | ButtonDialogFlags::Focus);
AddButton(Translate::get(STR_TRYLATER_SAVEAS_BTN, rResLocale), RET_NO);
AddButton( StandardButtonType::Cancel, RET_CANCEL, ButtonDialogFlags::Cancel );
SetButtonHelpText( RET_YES, OUString() );
SetButtonHelpText( RET_NO, OUString() );
}
} }
TryLaterQueryBox::~TryLaterQueryBox() TryLaterQueryBox::~TryLaterQueryBox()
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
class TryLaterQueryBox : public MessBox class TryLaterQueryBox : public MessBox
{ {
public: public:
TryLaterQueryBox(vcl::Window* pParent, const std::locale& rLocale, const OUString& aMessage); TryLaterQueryBox(vcl::Window* pParent, const std::locale& rLocale, const OUString& aMessage, bool bEnableOverride);
virtual ~TryLaterQueryBox() override; virtual ~TryLaterQueryBox() override;
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment