summaryrefslogtreecommitdiff
path: root/sfx2/source/view/viewfrm.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sfx2/source/view/viewfrm.cxx')
-rw-r--r--sfx2/source/view/viewfrm.cxx133
1 files changed, 98 insertions, 35 deletions
diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx
index 840ba418e3e7..8d0fb19f3faf 100644
--- a/sfx2/source/view/viewfrm.cxx
+++ b/sfx2/source/view/viewfrm.cxx
@@ -137,6 +137,7 @@ using ::com::sun::star::container::XIndexContainer;
#include <sfx2/minfitem.hxx>
#include "../appl/app.hrc"
#include "impviewframe.hxx"
+#include <vcl/msgbox.hxx>
#define SfxViewFrame
#include "sfxslots.hxx"
@@ -154,6 +155,7 @@ void SfxViewFrame::InitInterface_Impl()
#endif
}
+namespace {
/// Asks the user if editing a read-only document is really wanted.
class SfxEditDocumentDialog : public MessageDialog
{
@@ -186,8 +188,31 @@ void SfxEditDocumentDialog::dispose()
MessageDialog::dispose();
}
+class SfxQueryOpenAsTemplate : public QueryBox
+{
+public:
+ SfxQueryOpenAsTemplate(vcl::Window* pParent, WinBits nStyle, bool bAllowIgnoreLock);
+};
+
+SfxQueryOpenAsTemplate::SfxQueryOpenAsTemplate(vcl::Window* pParent, WinBits 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(SfxObjectShellRef xObjSh)
+bool IsSignPDF(SfxObjectShellRef xObjSh)
{
if (!xObjSh.Is())
return false;
@@ -203,7 +228,7 @@ static bool IsSignPDF(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() );
@@ -251,6 +276,7 @@ static bool AskPasswordToModify_Impl( const uno::Reference< task::XInteractionHa
return bResult;
}
+}
void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
{
@@ -283,6 +309,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);
@@ -332,7 +375,7 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
}
}
nOpenMode = SFX_STREAM_READONLY;
- pSh->SetReadOnlyUI();
+ aReadOnlyUIGuard.m_bSetRO = true;
}
else
{
@@ -352,10 +395,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() )
@@ -364,12 +405,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() )
@@ -416,31 +453,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 )
+ {
+ 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 ) ) );
- pMed->CompleteReOpen();
- if ( nOpenMode & StreamMode::WRITE )
- pMed->LockOrigFileOnDemand( false, true );
+ 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(), 0, 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 )
{
@@ -460,10 +524,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, VCL_BUTTONS_YES_NO);
- if ( RET_YES == aBox->Execute() )
+ if ( bOpenTemplate )
{
SfxApplication* pApp = SfxGetpApp();
SfxAllItemSet aSet( pApp->GetPool() );
@@ -486,10 +547,12 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
GetDispatcher()->Execute( SID_OPENDOC, SfxCallMode::ASYNCHRON, aSet );
return;
}
- else
- nErr = 0;
+ nErr = 0;
}
+ // Keep the read-only UI
+ aReadOnlyUIGuard.m_bSetRO = true;
+
ErrorHandler::HandleError( nErr );
rReq.SetReturnValue(
SfxBoolItem( rReq.GetSlot(), false ) );