sfx2/inc/sfx2/docfile.hxx    |    5 +++++
 sfx2/inc/sfx2/objsh.hxx      |    1 +
 sfx2/source/doc/docfile.cxx  |   20 ++++++++++++++++----
 sfx2/source/doc/objmisc.cxx  |   12 ++++++++----
 sfx2/source/doc/objstor.cxx  |    6 +++---
 sfx2/source/doc/objxtor.cxx  |    2 +-
 sfx2/source/view/viewfrm.cxx |   28 ++++++++++++++++------------
 7 files changed, 50 insertions(+), 24 deletions(-)

New commits:
commit b9ecec7c74687ed5a9470cffb7d02e0e6e83107e
Author: Stephan Bergmann <sberg...@redhat.com>
Date:   Fri Jun 1 17:32:07 2012 +0200

    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

diff --git a/sfx2/inc/sfx2/docfile.hxx b/sfx2/inc/sfx2/docfile.hxx
index f7f85d5..ca8ad49 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 3c1837b..90acbb7 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 4da1556..e77992e 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 037f4bc..4c05bdb 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 313d95d..341821c 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 9e20d83..dd1dbc1 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 0538bce..155c194 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() )
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to