summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2012-06-01 17:32:07 +0200
committerStephan Bergmann <sbergman@redhat.com>2012-06-01 17:32:07 +0200
commitb9ecec7c74687ed5a9470cffb7d02e0e6e83107e (patch)
tree3d7c4f5a191dc837032b0a094b5316055a3679ec
parent477c2229d2532a11ec8c81b9ef392ce49357f95c (diff)
Allow for editing of read-only documents
When e.g. viewing mail attachments (that have been stored r/o to some download directory by the mail application), it would be nice if the user could easily temporarily modify them (say, play around with a spreadsheet, changing some numbers and triggering recalculation of formulas) by clicking the "Edit File" button and not being asked to create a copy for editing. This patch tries to make editability of a view independent of the r/o status of the medium: * SID_EDITDOC (the "Edit File" button) now only toggles the r/o status of the view. It no longer asks to create a copy for editing if the underlying medium is r/o. * When a modified document is toggled to r/o via SID_EDITDOC, LO still asks the user to save or discard the changes. However, if the underlying medium is physically r/o (see next), saving the document opens the "Save As" dialog, instead of just doing a "Save" operation (which would fail on the r/o file). * A new state of "IsOriginallyReadOnly" needed to be added to the medium, to keep track whether the medium was originally opened r/o (and is thus assumed to be physically r/o), as toggling SID_EDITDOC in the view also changes the open mode of the underlying medium. Instead of trying to fully understand and disentangle that horrible mess, I just added yet another state to the mess... * The title of the document window now contains "(read-only)" if and only if either the view is r/o or the medium is originally r/o (or both). Change-Id: I89d9c6adf0baab411e737a5f4e6f4e770e7a70be
-rw-r--r--sfx2/inc/sfx2/docfile.hxx5
-rw-r--r--sfx2/inc/sfx2/objsh.hxx1
-rw-r--r--sfx2/source/doc/docfile.cxx20
-rw-r--r--sfx2/source/doc/objmisc.cxx12
-rw-r--r--sfx2/source/doc/objstor.cxx6
-rw-r--r--sfx2/source/doc/objxtor.cxx2
-rw-r--r--sfx2/source/view/viewfrm.cxx28
7 files changed, 50 insertions, 24 deletions
diff --git a/sfx2/inc/sfx2/docfile.hxx b/sfx2/inc/sfx2/docfile.hxx
index f7f85d5502c5..ca8ad494f3e3 100644
--- a/sfx2/inc/sfx2/docfile.hxx
+++ b/sfx2/inc/sfx2/docfile.hxx
@@ -213,6 +213,11 @@ public:
GetVersionList( bool _bNoReload = false );
sal_Bool IsReadOnly();
+ // Whether the medium had originally been opened r/o, independent of later
+ // changes via SetOpenMode; used to keep track of the "true" state of the
+ // medium across toggles via SID_EDITDOC (which do change SetOpenMode):
+ bool IsOriginallyReadOnly() const;
+
::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > GetInputStream();
void CreateTempFile( sal_Bool bReplace = sal_True );
diff --git a/sfx2/inc/sfx2/objsh.hxx b/sfx2/inc/sfx2/objsh.hxx
index 3c1837b22187..90acbb7b3c3f 100644
--- a/sfx2/inc/sfx2/objsh.hxx
+++ b/sfx2/inc/sfx2/objsh.hxx
@@ -273,6 +273,7 @@ public:
void SetReadOnly();
sal_Bool IsReadOnly() const;
sal_Bool IsReadOnlyMedium() const;
+ bool IsOriginallyReadOnlyMedium() const;
void SetReadOnlyUI( sal_Bool bReadOnly = sal_True );
sal_Bool IsReadOnlyUI() const;
void SetNoName();
diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx
index 4da155678152..e77992ef2dd6 100644
--- a/sfx2/source/doc/docfile.cxx
+++ b/sfx2/source/doc/docfile.cxx
@@ -312,6 +312,8 @@ public:
uno::Reference< logging::XSimpleLogRing > m_xLogRing;
+ bool m_originallyReadOnly;
+
SfxMedium_Impl( SfxMedium* pAntiImplP );
~SfxMedium_Impl();
};
@@ -339,7 +341,8 @@ SfxMedium_Impl::SfxMedium_Impl( SfxMedium* pAntiImplP )
pTempFile( NULL ),
nLastStorageError( 0 ),
m_bRemoveBackup( sal_False ),
- m_nSignatureState( SIGNATURESTATE_NOSIGNATURES )
+ m_nSignatureState( SIGNATURESTATE_NOSIGNATURES ),
+ m_originallyReadOnly(false)
{
aDoneLink.CreateMutex();
}
@@ -1057,6 +1060,11 @@ sal_Bool SfxMedium::LockOrigFileOnDemand( sal_Bool bLoading, sal_Bool bNoUI )
bContentReadonly = IsReadonlyAccordingACL( aPhysPath.GetBuffer() );
}
#endif
+
+ if ( bContentReadonly )
+ {
+ pImp->m_originallyReadOnly = true;
+ }
}
// do further checks only if the file not readonly in fs
@@ -2874,15 +2882,14 @@ SfxMedium::SfxMedium( const ::com::sun::star::uno::Sequence< ::com::sun::star::b
}
}
- sal_Bool bReadOnly = sal_False;
SFX_ITEMSET_ARG( pSet, pReadOnlyItem, SfxBoolItem, SID_DOC_READONLY, sal_False );
if ( pReadOnlyItem && pReadOnlyItem->GetValue() )
- bReadOnly = sal_True;
+ pImp->m_originallyReadOnly = true;
SFX_ITEMSET_ARG( pSet, pFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False );
if (!pFileNameItem) throw uno::RuntimeException();
aLogicName = pFileNameItem->GetValue();
- nStorOpenMode = bReadOnly ? SFX_STREAM_READONLY : SFX_STREAM_READWRITE;
+ nStorOpenMode = pImp->m_originallyReadOnly ? SFX_STREAM_READONLY : SFX_STREAM_READWRITE;
Init_Impl();
}
@@ -3207,6 +3214,11 @@ sal_Bool SfxMedium::IsReadOnly()
return bReadOnly;
}
+bool SfxMedium::IsOriginallyReadOnly() const
+{
+ return pImp->m_originallyReadOnly;
+}
+
//----------------------------------------------------------------
sal_Bool SfxMedium::SetWritableForUserOnly( const ::rtl::OUString& aURL )
{
diff --git a/sfx2/source/doc/objmisc.cxx b/sfx2/source/doc/objmisc.cxx
index 037f4bcc2504..4c05bdb7ffed 100644
--- a/sfx2/source/doc/objmisc.cxx
+++ b/sfx2/source/doc/objmisc.cxx
@@ -404,6 +404,11 @@ sal_Bool SfxObjectShell::IsReadOnlyMedium() const
return pMedium->IsReadOnly();
}
+bool SfxObjectShell::IsOriginallyReadOnlyMedium() const
+{
+ return pMedium == 0 || pMedium->IsOriginallyReadOnly();
+}
+
//-------------------------------------------------------------------------
void SfxObjectShell::SetReadOnlyUI( sal_Bool bReadOnly )
@@ -415,10 +420,9 @@ void SfxObjectShell::SetReadOnlyUI( sal_Bool bReadOnly )
*/
{
- sal_Bool bWasRO = IsReadOnly();
- pImp->bReadOnlyUI = bReadOnly;
- if ( bWasRO != IsReadOnly() )
+ if ( bReadOnly != pImp->bReadOnlyUI )
{
+ pImp->bReadOnlyUI = bReadOnly;
Broadcast( SfxSimpleHint(SFX_HINT_MODECHANGED) );
}
}
@@ -453,7 +457,7 @@ void SfxObjectShell::SetReadOnly()
sal_Bool SfxObjectShell::IsReadOnly() const
{
- return pImp->bReadOnlyUI || IsReadOnlyMedium();
+ return pImp->bReadOnlyUI || pMedium == 0;
}
//-------------------------------------------------------------------------
diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx
index 313d95d19054..341821cbc960 100644
--- a/sfx2/source/doc/objstor.cxx
+++ b/sfx2/source/doc/objstor.cxx
@@ -688,9 +688,6 @@ sal_Bool SfxObjectShell::DoLoad( SfxMedium *pMed )
SFX_ITEMSET_ARG( pMedium->GetItemSet(), pTemplateItem, SfxBoolItem, SID_TEMPLATE, sal_False);
if ( !pTemplateItem || !pTemplateItem->GetValue() )
bHasName = sal_True;
-
- if ( !IsReadOnly() && IsLoadReadonly() )
- SetReadOnlyUI();
}
else
SetError( ERRCODE_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
@@ -750,6 +747,9 @@ sal_Bool SfxObjectShell::DoLoad( SfxMedium *pMed )
if ( bOk )
{
+ if ( IsReadOnlyMedium() || IsLoadReadonly() )
+ SetReadOnlyUI();
+
try
{
::ucbhelper::Content aContent( pMedium->GetName(), com::sun::star::uno::Reference < XCommandEnvironment >() );
diff --git a/sfx2/source/doc/objxtor.cxx b/sfx2/source/doc/objxtor.cxx
index 9e20d837b85d..dd1dbc18ec1f 100644
--- a/sfx2/source/doc/objxtor.cxx
+++ b/sfx2/source/doc/objxtor.cxx
@@ -661,7 +661,7 @@ sal_uInt16 SfxObjectShell::PrepareClose
{
SfxBoolItem aWarnItem( SID_FAIL_ON_WARNING, bUI );
const SfxPoolItem* ppArgs[] = { &aWarnItem, 0 };
- pPoolItem = pFrame->GetBindings().ExecuteSynchron( SID_SAVEDOC, ppArgs );
+ pPoolItem = pFrame->GetBindings().ExecuteSynchron( IsReadOnlyMedium() ? SID_SAVEASDOC : SID_SAVEDOC, ppArgs );
}
if ( !pPoolItem || pPoolItem->ISA(SfxVoidItem) || ( pPoolItem->ISA(SfxBoolItem) && !( (const SfxBoolItem*) pPoolItem )->GetValue() ) )
diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx
index 0538bce341e0..155c194d05ee 100644
--- a/sfx2/source/view/viewfrm.cxx
+++ b/sfx2/source/view/viewfrm.cxx
@@ -405,6 +405,7 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
}
}
nOpenMode = SFX_STREAM_READONLY;
+ pSh->SetReadOnlyUI(true);
}
else
{
@@ -424,12 +425,20 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
pSh->SetModifyPasswordEntered();
}
- nOpenMode = SFX_STREAM_READWRITE;
- pSh->SetReadOnlyUI( sal_False );
+ nOpenMode = pSh->IsOriginallyReadOnlyMedium() ? SFX_STREAM_READONLY : SFX_STREAM_READWRITE;
// if only the view was in the readonly mode then there is no need to do the reload
- if ( !pSh->IsReadOnly() )
+ if ( !pSh->IsReadOnlyMedium() )
+ {
+ // SetReadOnlyUI causes recomputation of window title, using
+ // open mode among other things, so call SetOpenMode before
+ // SetReadOnlyUI:
+ pMed->SetOpenMode( nOpenMode );
+ pSh->SetReadOnlyUI( sal_False );
return;
+ }
+
+ pSh->SetReadOnlyUI( sal_False );
}
if ( rReq.IsAPI() )
@@ -580,8 +589,6 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
SID_FILE_NAME, sal_False);
// Open as editable?
sal_Bool bForEdit = !pSh->IsReadOnly();
- if ( rReq.GetSlot() == SID_EDITDOC )
- bForEdit = !bForEdit;
// If possible ask the User
sal_Bool bDo = ( GetViewShell()->PrepareClose() != sal_False );
@@ -650,9 +657,9 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
// let the current security settings be checked again
pNewSet->Put( SfxUInt16Item( SID_MACROEXECMODE, document::MacroExecMode::USE_CONFIG ) );
- if ( rReq.GetSlot() == SID_EDITDOC || !bForEdit )
+ if ( pSh->IsOriginallyReadOnlyMedium() )
// edit mode is switched or reload of readonly document
- pNewSet->Put( SfxBoolItem( SID_DOC_READONLY, !bForEdit ) );
+ pNewSet->Put( SfxBoolItem( SID_DOC_READONLY, true ) );
else
// Reload of file opened for writing
pNewSet->ClearItem( SID_DOC_READONLY );
@@ -778,12 +785,9 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq )
xNewObj->SetModifyPasswordEntered( sal_False );
xNewObj->SetReadOnly();
}
- else if ( rReq.GetSlot() == SID_EDITDOC && bForEdit && !xNewObj->IsReadOnlyMedium() )
+ else if ( rReq.GetSlot() == SID_EDITDOC )
{
- // the filter might request setting of the document to readonly state
- // but in case of SID_EDITDOC it should not happen if the document
- // can be opened for editing
- xNewObj->SetReadOnlyUI( sal_False );
+ xNewObj->SetReadOnlyUI( !bForEdit );
}
if ( xNewObj->IsDocShared() )