summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sfx2/docfile.hxx19
-rw-r--r--include/sfx2/strings.hrc3
-rw-r--r--sfx2/source/doc/docfile.cxx71
-rw-r--r--sfx2/source/view/viewfrm.cxx134
-rw-r--r--uui/inc/strings.hrc3
-rw-r--r--uui/source/iahndl-locking.cxx12
-rw-r--r--uui/source/iahndl.cxx9
-rw-r--r--uui/source/openlocked.cxx14
-rw-r--r--uui/source/openlocked.hxx2
9 files changed, 194 insertions, 73 deletions
diff --git a/include/sfx2/docfile.hxx b/include/sfx2/docfile.hxx
index 822c69b1da4f..06a7f9623764 100644
--- a/include/sfx2/docfile.hxx
+++ b/include/sfx2/docfile.hxx
@@ -162,11 +162,13 @@ public:
bool Commit();
bool IsStorage();
- enum class ShowLockResult { NoLock, Succeeded,Try };
- ShowLockResult ShowLockedDocumentDialog( const LockFileEntry& aData, bool bIsLoading, bool bOwnLock, bool bHandleSysLocked);
- void LockOrigFileOnDemand( bool bLoading, bool bNoUI );
- enum class MessageDlg { LockFileIgnore, LockFileCorrupt };
- bool ShowLockFileProblemDialog(MessageDlg nWhichDlg);
+ enum class LockFileResult
+ {
+ Failed,
+ FailedLockFile, // there was only lock file that prevented success - no syslock or IO error
+ Succeeded,
+ };
+ LockFileResult LockOrigFileOnDemand( bool bLoading, bool bNoUI, bool bTryIgnoreLockFile = false );
void DisableUnlockWebDAV( bool bDisableUnlockWebDAV = true );
void UnlockFile( bool bReleaseLockStream );
/// Lets Transfer_Impl() not fsync the output file.
@@ -275,6 +277,13 @@ public:
static bool SetWritableForUserOnly( const OUString& aURL );
static sal_uInt32 CreatePasswordToModifyHash( const OUString& aPasswd, bool bWriter );
+
+private:
+ enum class ShowLockResult { NoLock, Succeeded, Try };
+ ShowLockResult ShowLockedDocumentDialog(const LockFileEntry& aData, bool bIsLoading, bool bOwnLock, bool bHandleSysLocked);
+ enum class MessageDlg { LockFileIgnore, LockFileCorrupt };
+ bool ShowLockFileProblemDialog(MessageDlg nWhichDlg);
+
};
#endif
diff --git a/include/sfx2/strings.hrc b/include/sfx2/strings.hrc
index 889ccf8ab22b..c36a37b4893a 100644
--- a/include/sfx2/strings.hrc
+++ b/include/sfx2/strings.hrc
@@ -235,6 +235,9 @@
#define STR_CANT_CLOSE NC_("STR_CANT_CLOSE", "The document cannot be closed because a\n print job is being carried out.")
#define STR_ERROR_SEND_MAIL NC_("STR_ERROR_SEND_MAIL", "An error occurred in sending the message. Possible errors could be a missing user account or a defective setup.\nPlease check the %PRODUCTNAME settings or your e-mail program settings.")
#define STR_QUERY_OPENASTEMPLATE NC_("STR_QUERY_OPENASTEMPLATE", "This document cannot be edited, possibly due to missing access rights. Do you want to edit a copy of the document?")
+#define STR_QUERY_OPENASTEMPLATE_ALLOW_IGNORE NC_("STR_QUERY_OPENASTEMPLATE_ALLOW_IGNORE", "This document cannot be edited, because it is locked in another session. Do you want to edit a copy of the document?\n\nYou can also try to ignore the lock and open the file for editing.")
+#define STR_QUERY_OPENASTEMPLATE_OPENCOPY_BTN NC_("STR_QUERY_OPENASTEMPLATE_OPENCOPY_BTN", "Open ~Copy")
+#define STR_QUERY_OPENASTEMPLATE_OPEN_BTN NC_("STR_QUERY_OPENASTEMPLATE_OPEN_BTN", "~Open")
#define STR_REPAIREDDOCUMENT NC_("STR_REPAIREDDOCUMENT", " (repaired document)")
#define STR_NONCHECKEDOUT_DOCUMENT NC_("STR_NONCHECKEDOUT_DOCUMENT", "This document is not checked out on the server.")
#define STR_READONLY_DOCUMENT NC_("STR_READONLY_DOCUMENT", "This document is open in read-only mode.")
diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx
index 055cfa41859d..175ab138c5af 100644
--- a/sfx2/source/doc/docfile.cxx
+++ b/sfx2/source/doc/docfile.cxx
@@ -846,6 +846,8 @@ SfxMedium::ShowLockResult SfxMedium::ShowLockedDocumentDialog( const LockFileEnt
OUString aInfo;
::rtl::Reference< ::ucbhelper::InteractionRequest > xInteractionRequestImpl;
+ sal_Int32 nContinuations = 3;
+
if ( bOwnLock )
{
aInfo = aData[LockFileComponent::EDITTIME];
@@ -869,12 +871,23 @@ SfxMedium::ShowLockResult SfxMedium::ShowLockedDocumentDialog( const LockFileEnt
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( 3 );
+ uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations(nContinuations);
aContinuations[0] = new ::ucbhelper::InteractionAbort( xInteractionRequestImpl.get() );
aContinuations[1] = new ::ucbhelper::InteractionApprove( xInteractionRequestImpl.get() );
aContinuations[2] = new ::ucbhelper::InteractionDisapprove( xInteractionRequestImpl.get() );
+ if (nContinuations > 3)
+ {
+ // We use InteractionRetry to reflect that user wants to
+ // ignore the (stale?) alien lock file and open the document
+ aContinuations[3] = new ::ucbhelper::InteractionRetry(xInteractionRequestImpl.get());
+ }
xInteractionRequestImpl->setContinuations( aContinuations );
xHandler->handle( xInteractionRequestImpl.get() );
@@ -890,14 +903,19 @@ SfxMedium::ShowLockResult SfxMedium::ShowLockedDocumentDialog( const LockFileEnt
// 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 )
+ if ( !bOwnLock ) // bIsLoading implied from outermost condition
{
// means that a copy of the document should be opened
GetItemSet()->Put( SfxBoolItem( SID_TEMPLATE, true ) );
}
- else if ( bOwnLock )
+ else
nResult = ShowLockResult::Succeeded;
}
+ else if (uno::Reference< task::XInteractionRetry >(xSelected.get(), uno::UNO_QUERY).is())
+ {
+ // User decided to ignore the alien (stale?) lock file without filesystem lock
+ nResult = ShowLockResult::Succeeded;
+ }
else // if ( XSelected == aContinuations[1] )
{
// own lock on loading, user has selected to open readonly
@@ -992,12 +1010,16 @@ namespace
// sets SID_DOC_READONLY if the document cannot be opened for editing
// if user cancel the loading the ERROR_ABORT is set
-void SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI )
+SfxMedium::LockFileResult SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI, bool bTryIgnoreLockFile )
{
#if !HAVE_FEATURE_MULTIUSER_ENVIRONMENT
(void) bLoading;
(void) bNoUI;
+ (void) bTryIgnoreLockFile;
+ return LockFileResult::Succeeded;
#else
+ LockFileResult eResult = LockFileResult::Failed;
+
// check if path scheme is http:// or https://
// may be this is better if used always, in Android and iOS as well?
// if this code should be always there, remember to move the relevant code in UnlockFile method as well !
@@ -1069,7 +1091,7 @@ void SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI )
if ( !bResult && !bNoUI )
{
- bUIStatus = ShowLockedDocumentDialog( aLockData, bLoading, false , false );
+ bUIStatus = ShowLockedDocumentDialog( aLockData, bLoading, false , true );
}
}
catch( ucb::InteractiveNetworkWriteException& )
@@ -1108,23 +1130,28 @@ void SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI )
// when the file is locked, get the current file date
if ( bResult && DocNeedsFileDateCheck() )
GetInitFileDate( true );
+
+ if ( bResult )
+ eResult = LockFileResult::Succeeded;
}
catch ( const uno::Exception& )
{
SAL_WARN( "sfx.doc", "Locking exception: WebDAV while trying to lock the file" );
}
- return;
+ return eResult;
}
- if (!IsLockingUsed() || GetURLObject().HasError())
- return;
+ if (!IsLockingUsed())
+ return LockFileResult::Succeeded;
+ if (GetURLObject().HasError())
+ return eResult;
try
{
if ( pImpl->m_bLocked && bLoading
&& GetURLObject().GetProtocol() == INetProtocol::File )
{
- // if the document is already locked the system locking might be temporarely off after storing
+ // if the document is already locked the system locking might be temporarily off after storing
// check whether the system file locking should be taken again
GetLockingStream_Impl();
}
@@ -1176,7 +1203,7 @@ void SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI )
// let the stream be opened to check the system file locking
GetMedium_Impl();
if (GetError() != ERRCODE_NONE) {
- return;
+ return eResult;
}
}
@@ -1202,15 +1229,6 @@ void SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI )
{
bResult = aLockFile.CreateOwnLockFile();
}
- catch (const ucb::InteractiveIOException&)
- {
- if (bLoading && !bNoUI)
- {
- bIoErr = true;
- ShowLockFileProblemDialog(MessageDlg::LockFileIgnore);
- bResult = true; // always delete the defect lock-file
- }
- }
catch (const uno::Exception&)
{
if (bLoading && !bNoUI)
@@ -1270,14 +1288,20 @@ void SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI )
}
}
- if ( !bResult && !bNoUI && !bIoErr)
+ if ( !bResult && !bIoErr)
{
- bUIStatus = ShowLockedDocumentDialog( aData, bLoading, bOwnLock, bHandleSysLocked );
+ if (!bNoUI)
+ bUIStatus = ShowLockedDocumentDialog(aData, bLoading, bOwnLock, bHandleSysLocked);
+ else if (bLoading && bTryIgnoreLockFile && !bHandleSysLocked)
+ bUIStatus = ShowLockResult::Succeeded;
+
if ( bUIStatus == ShowLockResult::Succeeded )
{
// take the ownership over the lock file
bResult = aLockFile.OverwriteOwnLockFile();
}
+ else if (bLoading && !bHandleSysLocked)
+ eResult = LockFileResult::FailedLockFile;
}
}
}
@@ -1311,11 +1335,16 @@ void SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI )
// when the file is locked, get the current file date
if ( bResult && DocNeedsFileDateCheck() )
GetInitFileDate( true );
+
+ if ( bResult )
+ eResult = LockFileResult::Succeeded;
}
catch( const uno::Exception& )
{
SAL_WARN( "sfx.doc", "Locking exception: high probability, that the content has not been created" );
}
+
+ return eResult;
#endif
}
diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx
index 7a5a536bb46e..7fee9f85800f 100644
--- a/sfx2/source/view/viewfrm.cxx
+++ b/sfx2/source/view/viewfrm.cxx
@@ -134,6 +134,7 @@ using ::com::sun::star::container::XIndexContainer;
#include <sfx2/minfitem.hxx>
#include <sfx2/strings.hrc>
#include "impviewframe.hxx"
+#include <vcl/msgbox.hxx>
#define SfxViewFrame
#include <sfxslots.hxx>
@@ -151,6 +152,7 @@ void SfxViewFrame::InitInterface_Impl()
#endif
}
+namespace {
/// Asks the user if editing a read-only document is really wanted.
class SfxEditDocumentDialog : public MessageDialog
{
@@ -183,8 +185,31 @@ void SfxEditDocumentDialog::dispose()
MessageDialog::dispose();
}
+class SfxQueryOpenAsTemplate : public QueryBox
+{
+public:
+ SfxQueryOpenAsTemplate(vcl::Window* pParent, MessBoxStyle nStyle, bool bAllowIgnoreLock);
+};
+
+SfxQueryOpenAsTemplate::SfxQueryOpenAsTemplate(vcl::Window* pParent, MessBoxStyle nStyle, bool bAllowIgnoreLock)
+ : QueryBox(pParent, nStyle, SfxResId(bAllowIgnoreLock ? STR_QUERY_OPENASTEMPLATE_ALLOW_IGNORE : STR_QUERY_OPENASTEMPLATE))
+{
+ AddButton(SfxResId(STR_QUERY_OPENASTEMPLATE_OPENCOPY_BTN), RET_YES,
+ ButtonDialogFlags::Default | ButtonDialogFlags::OK | ButtonDialogFlags::Focus);
+ SetButtonHelpText(RET_YES, OUString());
+
+ if (bAllowIgnoreLock)
+ {
+ AddButton(SfxResId(STR_QUERY_OPENASTEMPLATE_OPEN_BTN), RET_IGNORE);
+ SetButtonHelpText(RET_IGNORE, OUString());
+ }
+
+ AddButton(StandardButtonType::Cancel, RET_CANCEL);
+ SetButtonHelpText(RET_CANCEL, OUString());
+}
+
/// Is this read-only object shell opened via .uno:SignPDF?
-static bool IsSignPDF(const SfxObjectShellRef& xObjSh)
+bool IsSignPDF(const SfxObjectShellRef& xObjSh)
{
if (!xObjSh.is())
return false;
@@ -200,7 +225,7 @@ static bool IsSignPDF(const SfxObjectShellRef& xObjSh)
return false;
}
-static bool AskPasswordToModify_Impl( const uno::Reference< task::XInteractionHandler >& xHandler, const OUString& aPath, const std::shared_ptr<const SfxFilter>& pFilter, sal_uInt32 nPasswordHash, const uno::Sequence< beans::PropertyValue >& aInfo )
+bool AskPasswordToModify_Impl( const uno::Reference< task::XInteractionHandler >& xHandler, const OUString& aPath, const std::shared_ptr<const SfxFilter>& pFilter, sal_uInt32 nPasswordHash, const uno::Sequence< beans::PropertyValue >& aInfo )
{
// TODO/LATER: In future the info should replace the direct hash completely
bool bResult = ( !nPasswordHash && !aInfo.getLength() );
@@ -248,6 +273,7 @@ static bool AskPasswordToModify_Impl( const uno::Reference< task::XInteractionHa
return bResult;
}
+}
void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
{
@@ -263,6 +289,23 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
if( !pSh || !pSh->HasName() || !(pSh->Get_Impl()->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT ))
break;
+ // Only change read-only UI and remove info bar when we succeed
+ struct ReadOnlyUIGuard
+ {
+ SfxViewFrame* m_pFrame;
+ SfxObjectShell* m_pSh;
+ bool m_bSetRO;
+ ~ReadOnlyUIGuard()
+ {
+ if (m_bSetRO != m_pSh->IsReadOnlyUI())
+ {
+ m_pSh->SetReadOnlyUI(m_bSetRO);
+ if (!m_bSetRO)
+ m_pFrame->RemoveInfoBar("readonly");
+ }
+ }
+ } aReadOnlyUIGuard{ this, pSh, pSh->IsReadOnlyUI() };
+
SfxMedium* pMed = pSh->GetMedium();
const SfxBoolItem* pItem = SfxItemSet::GetItem<SfxBoolItem>(pSh->GetMedium()->GetItemSet(), SID_VIEWONLY, false);
@@ -312,7 +355,7 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
}
}
nOpenMode = SFX_STREAM_READONLY;
- pSh->SetReadOnlyUI();
+ aReadOnlyUIGuard.m_bSetRO = true;
}
else
{
@@ -332,10 +375,8 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
pSh->SetModifyPasswordEntered();
}
- // Remove infobar if document was read-only (after password check)
- RemoveInfoBar("readonly");
-
nOpenMode = pSh->IsOriginallyReadOnlyMedium() ? SFX_STREAM_READONLY : SFX_STREAM_READWRITE;
+ aReadOnlyUIGuard.m_bSetRO = false;
// if only the view was in the readonly mode then there is no need to do the reload
if ( !pSh->IsReadOnlyMedium() )
@@ -344,12 +385,8 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
// open mode among other things, so call SetOpenMode before
// SetReadOnlyUI:
pMed->SetOpenMode( nOpenMode );
- pSh->SetReadOnlyUI( false );
return;
}
-
-
- pSh->SetReadOnlyUI( false );
}
if ( rReq.IsAPI() )
@@ -396,31 +433,58 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
// <- tdf#82744
{
bool bOK = false;
- if ( !pVersionItem )
- {
- bool bHasStorage = pMed->HasStorage_Impl();
- // switching edit mode could be possible without reload
- if ( bHasStorage && pMed->GetStorage() == pSh->GetStorage() )
+ bool bRetryIgnoringLock = false;
+ bool bOpenTemplate = false;
+ do {
+ if ( !pVersionItem )
{
- // TODO/LATER: faster creation of copy
- if ( !pSh->ConnectTmpStorage_Impl( pMed->GetStorage(), pMed ) )
- return;
- }
+ if (bRetryIgnoringLock)
+ pMed->ResetError();
- pMed->CloseAndRelease();
- pMed->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, !( nOpenMode & StreamMode::WRITE ) ) );
- pMed->SetOpenMode( nOpenMode );
+ bool bHasStorage = pMed->HasStorage_Impl();
+ // switching edit mode could be possible without reload
+ if ( bHasStorage && pMed->GetStorage() == pSh->GetStorage() )
+ {
+ // TODO/LATER: faster creation of copy
+ if ( !pSh->ConnectTmpStorage_Impl( pMed->GetStorage(), pMed ) )
+ return;
+ }
+
+ pMed->CloseAndRelease();
+ pMed->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, !( nOpenMode & StreamMode::WRITE ) ) );
+ pMed->SetOpenMode( nOpenMode );
- pMed->CompleteReOpen();
- if ( nOpenMode & StreamMode::WRITE )
- pMed->LockOrigFileOnDemand( false, true );
+ pMed->CompleteReOpen();
+ if ( nOpenMode & StreamMode::WRITE )
+ {
+ auto eResult = pMed->LockOrigFileOnDemand( true, true, bRetryIgnoringLock );
+ bRetryIgnoringLock = eResult == SfxMedium::LockFileResult::FailedLockFile;
+ }
+
+ // LockOrigFileOnDemand might set the readonly flag itself, it should be set back
+ pMed->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, !( nOpenMode & StreamMode::WRITE ) ) );
+
+ if ( !pMed->GetErrorCode() )
+ bOK = true;
+ }
- // LockOrigFileOnDemand might set the readonly flag itself, it should be set back
- pMed->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, !( nOpenMode & StreamMode::WRITE ) ) );
+ if( !bOK )
+ {
+ if (nOpenMode == SFX_STREAM_READWRITE && !rReq.IsAPI())
+ {
+ // css::sdbcx::User offering to open it as a template
+ ScopedVclPtrInstance<SfxQueryOpenAsTemplate> aBox(&GetWindow(), MessBoxStyle::NONE, bRetryIgnoringLock);
- if ( !pMed->GetErrorCode() )
- bOK = true;
+ short nUserAnswer = aBox->Execute();
+ bOpenTemplate = RET_YES == nUserAnswer;
+ // Always reset this here to avoid infinite loop
+ bRetryIgnoringLock = RET_IGNORE == nUserAnswer;
+ }
+ else
+ bRetryIgnoringLock = false;
+ }
}
+ while ( !bOK && bRetryIgnoringLock );
if( !bOK )
{
@@ -440,10 +504,7 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
if ( nOpenMode == SFX_STREAM_READWRITE && !rReq.IsAPI() )
{
- // css::sdbcx::User offering to open it as a template
- ScopedVclPtrInstance<MessageDialog> aBox(&GetWindow(), SfxResId(STR_QUERY_OPENASTEMPLATE),
- VclMessageType::Question, VclButtonsType::YesNo);
- if ( RET_YES == aBox->Execute() )
+ if ( bOpenTemplate )
{
SfxApplication* pApp = SfxGetpApp();
SfxAllItemSet aSet( pApp->GetPool() );
@@ -466,10 +527,13 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
GetDispatcher()->Execute( SID_OPENDOC, SfxCallMode::ASYNCHRON, aSet );
return;
}
- else
- nErr = ERRCODE_NONE;
+
+ nErr = ERRCODE_NONE;
}
+ // Keep the read-only UI
+ aReadOnlyUIGuard.m_bSetRO = true;
+
ErrorHandler::HandleError( nErr );
rReq.SetReturnValue(
SfxBoolItem( rReq.GetSlot(), false ) );
diff --git a/uui/inc/strings.hrc b/uui/inc/strings.hrc
index 760402c1d57b..590a582eba06 100644
--- a/uui/inc/strings.hrc
+++ b/uui/inc/strings.hrc
@@ -47,7 +47,8 @@
#define STR_LOCKFAILED_OPENREADONLY_BTN NC_("STR_LOCKFAILED_OPENREADONLY_BTN", "Open ~Read-Only")
#define STR_OPENLOCKED_TITLE NC_("STR_OPENLOCKED_TITLE", "Document in Use")
-#define STR_OPENLOCKED_MSG NC_("STR_OPENLOCKED_MSG", "Document file '$(ARG1)' is locked for editing by:\n\n$(ARG2)\n\nOpen document read-only or open a copy of the document for editing.\n\n")
+#define STR_OPENLOCKED_MSG NC_("STR_OPENLOCKED_MSG", "Document file '$(ARG1)' is locked for editing by:\n\n$(ARG2)\n\nOpen document read-only or open a copy of the document for editing.\n\n$(ARG3)")
+#define STR_OPENLOCKED_ALLOWIGNORE_MSG NC_("STR_OPENLOCKED_ALLOWIGNORE_MSG", "You may also ignore the file locking and open the document for editing.\n\n")
#define STR_OPENLOCKED_OPENREADONLY_BTN NC_("STR_OPENLOCKED_OPENREADONLY_BTN", "Open ~Read-Only")
#define STR_OPENLOCKED_OPENCOPY_BTN NC_("STR_OPENLOCKED_OPENCOPY_BTN", "Open ~Copy")
#define STR_UNKNOWNUSER NC_("STR_UNKNOWNUSER", "Unknown User")
diff --git a/uui/source/iahndl-locking.cxx b/uui/source/iahndl-locking.cxx
index 53b0e6a2fc77..08b5b5c7fd99 100644
--- a/uui/source/iahndl-locking.cxx
+++ b/uui/source/iahndl-locking.cxx
@@ -29,6 +29,7 @@
#include <com/sun/star/task/XInteractionDisapprove.hpp>
#include <com/sun/star/task/XInteractionAbort.hpp>
#include <com/sun/star/task/XInteractionRequest.hpp>
+#include <com/sun/star/task/XInteractionRetry.hpp>
#include <unotools/resmgr.hxx>
#include <vcl/svapp.hxx>
@@ -66,7 +67,9 @@ handleLockedDocumentRequest_(
uno::Reference< task::XInteractionApprove > xApprove;
uno::Reference< task::XInteractionDisapprove > xDisapprove;
uno::Reference< task::XInteractionAbort > xAbort;
- getContinuations(rContinuations, &xApprove, &xDisapprove, &xAbort);
+ // In case an option to ignore lock and open the file is available
+ uno::Reference< task::XInteractionRetry > xRetry;
+ getContinuations(rContinuations, &xApprove, &xDisapprove, &xAbort, &xRetry);
if ( !xApprove.is() || !xDisapprove.is() || !xAbort.is() )
return;
@@ -86,11 +89,14 @@ handleLockedDocumentRequest_(
aArguments.push_back( !aInfo.isEmpty()
? aInfo
: Translate::get( STR_UNKNOWNUSER, aResLocale) );
+ aArguments.push_back( xRetry.is()
+ ? Translate::get( STR_OPENLOCKED_ALLOWIGNORE_MSG, aResLocale )
+ : "" );
aMessage = Translate::get(STR_OPENLOCKED_MSG, aResLocale);
aMessage = UUIInteractionHelper::replaceMessageWithArguments(
aMessage, aArguments );
- ScopedVclPtrInstance< OpenLockedQueryBox > xDialog(pParent, aResLocale, aMessage);
+ ScopedVclPtrInstance< OpenLockedQueryBox > xDialog(pParent, aResLocale, aMessage, xRetry.is());
nResult = xDialog->Execute();
}
else if ( nMode == UUI_DOC_SAVE_LOCK )
@@ -128,6 +134,8 @@ handleLockedDocumentRequest_(
xApprove->select();
else if ( nResult == RET_NO )
xDisapprove->select();
+ else if ( nResult == RET_IGNORE && xRetry.is() )
+ xRetry->select();
else
xAbort->select();
}
diff --git a/uui/source/iahndl.cxx b/uui/source/iahndl.cxx
index 3d9d331476e6..f03372de3f54 100644
--- a/uui/source/iahndl.cxx
+++ b/uui/source/iahndl.cxx
@@ -238,10 +238,11 @@ UUIInteractionHelper::replaceMessageWithArguments(
OUString aMessage = _aMessage;
SAL_WARN_IF(rArguments.size() == 0, "uui", "replaceMessageWithArguments: No arguments passed!");
- if (rArguments.size() > 0)
- aMessage = aMessage.replaceAll("$(ARG1)", rArguments[0]);
- if (rArguments.size() > 1)
- aMessage = aMessage.replaceAll("$(ARG2)", rArguments[1]);
+ for (size_t i = 0; i < rArguments.size(); ++i)
+ {
+ const OUString sReplaceTemplate = "$(ARG" + OUString::number(i+1) + ")";
+ aMessage = aMessage.replaceAll(sReplaceTemplate, rArguments[i]);
+ }
return aMessage;
}
diff --git a/uui/source/openlocked.cxx b/uui/source/openlocked.cxx
index 074242b964b8..3267610b78d1 100644
--- a/uui/source/openlocked.cxx
+++ b/uui/source/openlocked.cxx
@@ -21,7 +21,7 @@
#include "openlocked.hxx"
#include <unotools/resmgr.hxx>
-OpenLockedQueryBox::OpenLockedQueryBox( vcl::Window* pParent, const std::locale& rResLocale, const OUString& aMessage ) :
+OpenLockedQueryBox::OpenLockedQueryBox( vcl::Window* pParent, const std::locale& rResLocale, const OUString& aMessage, bool bEnableOverride ) :
MessBox(pParent, MessBoxStyle::NONE, 0,
Translate::get(STR_OPENLOCKED_TITLE, rResLocale),
aMessage )
@@ -30,13 +30,19 @@ OpenLockedQueryBox::OpenLockedQueryBox( vcl::Window* pParent, const std::locale&
AddButton(Translate::get(STR_OPENLOCKED_OPENREADONLY_BTN, rResLocale), RET_YES,
ButtonDialogFlags::Default | ButtonDialogFlags::OK | ButtonDialogFlags::Focus);
+ SetButtonHelpText(RET_YES, OUString());
AddButton(Translate::get(STR_OPENLOCKED_OPENCOPY_BTN, rResLocale), RET_NO);
+ SetButtonHelpText(RET_NO, OUString());
- AddButton( StandardButtonType::Cancel, RET_CANCEL, ButtonDialogFlags::Cancel );
- SetButtonHelpText( RET_YES, OUString() );
- SetButtonHelpText( RET_NO, OUString() );
+ if (bEnableOverride)
+ {
+ // Present option to ignore the (stale?) lock file and open the document
+ AddButton(Translate::get(STR_ALREADYOPEN_OPEN_BTN, rResLocale), RET_IGNORE);
+ SetButtonHelpText(RET_IGNORE, OUString());
+ }
+ AddButton( StandardButtonType::Cancel, RET_CANCEL, ButtonDialogFlags::Cancel );
}
OpenLockedQueryBox::~OpenLockedQueryBox()
diff --git a/uui/source/openlocked.hxx b/uui/source/openlocked.hxx
index 8584c45c2c7e..bb80a3c64146 100644
--- a/uui/source/openlocked.hxx
+++ b/uui/source/openlocked.hxx
@@ -24,7 +24,7 @@
class OpenLockedQueryBox : public MessBox
{
public:
- OpenLockedQueryBox(vcl::Window* pParent, const std::locale& rResLocale, const OUString& rMessage);
+ OpenLockedQueryBox(vcl::Window* pParent, const std::locale& rResLocale, const OUString& rMessage, bool bEnableOverride);
virtual ~OpenLockedQueryBox() override;
};