desktop/source/lib/init.cxx         |   28 ++++++++++++
 editeng/source/editeng/editview.cxx |    3 -
 editeng/source/editeng/impedit2.cxx |   83 +++++++++++++++++++-----------------
 include/sfx2/viewsh.hxx             |    1 
 sc/source/ui/app/inputhdl.cxx       |    6 +-
 sc/source/ui/view/gridwin.cxx       |    2 
 sfx2/inc/unoctitm.hxx               |    1 
 sfx2/source/control/dispatch.cxx    |   13 +++--
 sfx2/source/control/unoctitm.cxx    |   39 ++++++++++++++++
 sfx2/source/doc/objmisc.cxx         |    3 -
 sfx2/source/view/viewsh.cxx         |    7 +++
 svx/sdi/svx.sdi                     |    2 
 svx/source/svdraw/svdedtv.cxx       |    3 -
 sw/source/uibase/docvw/edtwin.cxx   |   68 +++++++++++++++--------------
 sw/source/uibase/inc/edtwin.hxx     |    2 
 sw/source/uibase/uiview/srcview.cxx |    2 
 16 files changed, 180 insertions(+), 83 deletions(-)

New commits:
commit c60598390725cc23dc1401beec057f1386226ac8
Author:     Gökay Şatır <gokaysa...@gmail.com>
AuthorDate: Thu Feb 22 13:54:06 2024 +0300
Commit:     Gökay ŞATIR <gokaysa...@collabora.com>
CommitDate: Wed Mar 6 11:21:47 2024 +0100

    Moving parts of readonly checks from model to view.
    
    Summary for what's done with this commit:
    init.cxx
        * Add guards for modify commands.
    
    viewsh:
        * Add "IsCurrentLokViewReadOnly" for ease of use.
    
    unocitm:
        * Add guard for modify comamnds
    
    dispatch.cxx
        * Implement readonlyview.
    
    objmisc:
        * Modify IsReadOnlyUI check for LokReadOnly view.
    
    svx.sdi:
        * Disable TableChangeCurrentBorderPosition command for readOnly views.
    
    sw-editwin:
        * Treat mouse moves as readonly when the view is LokReadOnly.
    
    gridwin:
        * For autofilter.
    
    impedit2, inputhdl:
        * For text input.
    
    svdedtc:
        * For sdr object dragging.
    
    Signed-off-by: Gökay Şatır <gokaysa...@gmail.com>
    Change-Id: I71fc353976256bce22042bbb6042ee464b65cc13
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163731
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Gökay ŞATIR <gokaysa...@collabora.com>

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 939fe2afc09f..586d9b4d84cc 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -4726,6 +4726,10 @@ static void 
doc_postWindowExtTextInputEvent(LibreOfficeKitDocument* pThis, unsig
 static void doc_removeTextContext(LibreOfficeKitDocument* pThis, unsigned 
nLOKWindowId, int nCharBefore, int nCharAfter)
 {
     SolarMutexGuard aGuard;
+
+    if (SfxViewShell::IsCurrentLokViewReadOnly())
+        return;
+
     VclPtr<vcl::Window> pWindow;
     if (nLOKWindowId == 0)
     {
@@ -5107,6 +5111,23 @@ void LibLibreOffice_Impl::dumpState(rtl::OStringBuffer 
&rState)
     vcl::lok::dumpState(rState);
 }
 
+// We have special handling for some uno commands and it seems we need to 
check for readonly state.
+static bool isCommandAllowed(OUString& command) {
+    static constexpr OUString nonAllowedList[] = { u".uno:Save"_ustr, 
u".uno:TransformDialog"_ustr, u".uno:SidebarShow"_ustr, 
u".uno:SidebarHide"_ustr };
+
+    if (!SfxViewShell::IsCurrentLokViewReadOnly())
+        return true;
+    else
+    {
+        for (size_t i = 0; i < std::size(nonAllowedList); i++)
+        {
+            if (nonAllowedList[i] == command)
+                return false;
+        }
+        return true;
+    }
+}
+
 static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* 
pCommand, const char* pArguments, bool bNotifyWhenFinished)
 {
     comphelper::ProfileZone aZone("doc_postUnoCommand");
@@ -5116,6 +5137,10 @@ static void doc_postUnoCommand(LibreOfficeKitDocument* 
pThis, const char* pComma
 
     SfxObjectShell* pDocSh = SfxObjectShell::Current();
     OUString aCommand(pCommand, strlen(pCommand), RTL_TEXTENCODING_UTF8);
+
+    if (!isCommandAllowed(aCommand))
+        return;
+
     LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
 
     std::vector<beans::PropertyValue> 
aPropertyValuesVector(jsonToPropertyValuesVector(pArguments));
@@ -7167,6 +7192,9 @@ static void 
doc_sendContentControlEvent(LibreOfficeKitDocument* pThis, const cha
         return;
     }
 
+    if (SfxViewShell::IsCurrentLokViewReadOnly())
+        return;
+
     StringMap aMap(jsdialog::jsonToStringMap(pArguments));
     ITiledRenderable* pDoc = getTiledRenderable(pThis);
     if (!pDoc)
diff --git a/editeng/source/editeng/editview.cxx 
b/editeng/source/editeng/editview.cxx
index a7d52c341bb6..e2f429bc7789 100644
--- a/editeng/source/editeng/editview.cxx
+++ b/editeng/source/editeng/editview.cxx
@@ -155,6 +155,7 @@ EditViewCallbacks::~EditViewCallbacks()
 EditView::EditView( EditEngine* pEng, vcl::Window* pWindow )
 {
     pImpEditView.reset( new ImpEditView( this, pEng, pWindow ) );
+    pImpEditView->bReadOnly = pImpEditView->bReadOnly || 
SfxViewShell::IsCurrentLokViewReadOnly();
 }
 
 EditView::~EditView()
@@ -252,7 +253,7 @@ void EditView::Invalidate()
 
 void EditView::SetReadOnly( bool bReadOnly )
 {
-    pImpEditView->bReadOnly = bReadOnly;
+    pImpEditView->bReadOnly = bReadOnly || 
SfxViewShell::IsCurrentLokViewReadOnly();
 }
 
 bool EditView::IsReadOnly() const
diff --git a/editeng/source/editeng/impedit2.cxx 
b/editeng/source/editeng/impedit2.cxx
index 40f111b72e73..a9d55f0d6afa 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -31,6 +31,7 @@
 #include <editeng/txtrange.hxx>
 #include <sfx2/app.hxx>
 #include <sfx2/mieclip.hxx>
+#include <sfx2/viewsh.hxx>
 #include <svtools/colorcfg.hxx>
 #include <svl/ctloptions.hxx>
 #include <unotools/securityoptions.hxx>
@@ -346,65 +347,71 @@ bool ImpEditEngine::Command( const CommandEvent& rCEvt, 
EditView* pView )
 
     GetSelEngine().SetCurView( pView );
     SetActiveView( pView );
-    if ( rCEvt.GetCommand() == CommandEventId::StartExtTextInput )
+    if ( rCEvt.GetCommand() == CommandEventId::StartExtTextInput)
     {
-        pView->DeleteSelected();
-        mpIMEInfos.reset();
-        EditPaM aPaM = pView->GetImpEditView()->GetEditSelection().Max();
-        OUString aOldTextAfterStartPos = aPaM.GetNode()->Copy( aPaM.GetIndex() 
);
-        sal_Int32 nMax = aOldTextAfterStartPos.indexOf( CH_FEATURE );
-        if ( nMax != -1 )  // don't overwrite features!
-            aOldTextAfterStartPos = aOldTextAfterStartPos.copy( 0, nMax );
-        mpIMEInfos.reset( new ImplIMEInfos( aPaM, aOldTextAfterStartPos ) );
-        mpIMEInfos->bWasCursorOverwrite = !pView->IsInsertMode();
-        UndoActionStart( EDITUNDO_INSERT );
+        if (!pView->IsReadOnly())
+        {
+            pView->DeleteSelected();
+            mpIMEInfos.reset();
+            EditPaM aPaM = pView->GetImpEditView()->GetEditSelection().Max();
+            OUString aOldTextAfterStartPos = aPaM.GetNode()->Copy( 
aPaM.GetIndex() );
+            sal_Int32 nMax = aOldTextAfterStartPos.indexOf( CH_FEATURE );
+            if ( nMax != -1 )  // don't overwrite features!
+                aOldTextAfterStartPos = aOldTextAfterStartPos.copy( 0, nMax );
+            mpIMEInfos.reset( new ImplIMEInfos( aPaM, aOldTextAfterStartPos ) 
);
+            mpIMEInfos->bWasCursorOverwrite = !pView->IsInsertMode();
+            UndoActionStart( EDITUNDO_INSERT );
+        }
     }
     else if ( rCEvt.GetCommand() == CommandEventId::EndExtTextInput )
     {
-        OSL_ENSURE( mpIMEInfos, "CommandEventId::EndExtTextInput => No start 
?" );
-        if( mpIMEInfos )
+        if (!pView->IsReadOnly())
         {
-            // #102812# convert quotes in IME text
-            // works on the last input character, this is especially in Korean 
text often done
-            // quotes that are inside of the string are not replaced!
-            // Borrowed from sw: edtwin.cxx
-            if ( mpIMEInfos->nLen )
+            OSL_ENSURE( mpIMEInfos, "CommandEventId::EndExtTextInput => No 
start ?" );
+            if( mpIMEInfos )
             {
-                EditSelection aSel( mpIMEInfos->aPos );
-                aSel.Min().SetIndex( aSel.Min().GetIndex() + 
mpIMEInfos->nLen-1 );
-                aSel.Max().SetIndex( aSel.Max().GetIndex() + mpIMEInfos->nLen 
);
                 // #102812# convert quotes in IME text
                 // works on the last input character, this is especially in 
Korean text often done
                 // quotes that are inside of the string are not replaced!
-                // See also tdf#155350
-                const sal_Unicode nCharCode = aSel.Min().GetNode()->GetChar( 
aSel.Min().GetIndex() );
-                if ( ( GetStatus().DoAutoCorrect() ) && 
SvxAutoCorrect::IsAutoCorrectChar(nCharCode) )
+                // Borrowed from sw: edtwin.cxx
+                if ( mpIMEInfos->nLen )
                 {
-                    aSel = DeleteSelected( aSel );
-                    aSel = AutoCorrect( aSel, nCharCode, 
mpIMEInfos->bWasCursorOverwrite );
-                    pView->pImpEditView->SetEditSelection( aSel );
+                    EditSelection aSel( mpIMEInfos->aPos );
+                    aSel.Min().SetIndex( aSel.Min().GetIndex() + 
mpIMEInfos->nLen-1 );
+                    aSel.Max().SetIndex( aSel.Max().GetIndex() + 
mpIMEInfos->nLen );
+                    // #102812# convert quotes in IME text
+                    // works on the last input character, this is especially 
in Korean text often done
+                    // quotes that are inside of the string are not replaced!
+                    // See also tdf#155350
+                    const sal_Unicode nCharCode = 
aSel.Min().GetNode()->GetChar( aSel.Min().GetIndex() );
+                    if ( ( GetStatus().DoAutoCorrect() ) && 
SvxAutoCorrect::IsAutoCorrectChar(nCharCode) )
+                    {
+                        aSel = DeleteSelected( aSel );
+                        aSel = AutoCorrect( aSel, nCharCode, 
mpIMEInfos->bWasCursorOverwrite );
+                        pView->pImpEditView->SetEditSelection( aSel );
+                    }
                 }
-            }
 
-            ParaPortion* pPortion = FindParaPortion( 
mpIMEInfos->aPos.GetNode() );
-            if (pPortion)
-                pPortion->MarkSelectionInvalid( mpIMEInfos->aPos.GetIndex() );
+                ParaPortion* pPortion = FindParaPortion( 
mpIMEInfos->aPos.GetNode() );
+                if (pPortion)
+                    pPortion->MarkSelectionInvalid( 
mpIMEInfos->aPos.GetIndex() );
 
-            bool bWasCursorOverwrite = mpIMEInfos->bWasCursorOverwrite;
+                bool bWasCursorOverwrite = mpIMEInfos->bWasCursorOverwrite;
 
-            mpIMEInfos.reset();
+                mpIMEInfos.reset();
 
-            FormatAndLayout( pView );
+                FormatAndLayout( pView );
 
-            pView->SetInsertMode( !bWasCursorOverwrite );
+                pView->SetInsertMode( !bWasCursorOverwrite );
+            }
+            UndoActionEnd();
         }
-        UndoActionEnd();
     }
     else if ( rCEvt.GetCommand() == CommandEventId::ExtTextInput )
     {
-        OSL_ENSURE( mpIMEInfos, "CommandEventId::ExtTextInput => No Start ?" );
-        if( mpIMEInfos )
+        if( mpIMEInfos && !pView->IsReadOnly())
         {
+            OSL_ENSURE( mpIMEInfos, "CommandEventId::ExtTextInput => No Start 
?" );
             const CommandExtTextInputData* pData = rCEvt.GetExtTextInputData();
 
             if ( !pData->IsOnlyCursorChanged() )
diff --git a/include/sfx2/viewsh.hxx b/include/sfx2/viewsh.hxx
index 1875d5c78afd..f1564de3795c 100644
--- a/include/sfx2/viewsh.hxx
+++ b/include/sfx2/viewsh.hxx
@@ -209,6 +209,7 @@ public:
                                          bool bOnlyVisible = true,
                                          const std::function<bool ( const 
SfxViewShell* )>& isViewShell = nullptr );
     SAL_WARN_UNUSED_RESULT static SfxViewShell* Current();
+    SAL_WARN_UNUSED_RESULT static bool IsCurrentLokViewReadOnly();
 
     SAL_WARN_UNUSED_RESULT static SfxViewShell* Get( const 
css::uno::Reference< css::frame::XController>& i_rController );
 
diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx
index 285e1dab8f6f..a580ec911550 100644
--- a/sc/source/ui/app/inputhdl.cxx
+++ b/sc/source/ui/app/inputhdl.cxx
@@ -2517,7 +2517,7 @@ bool ScInputHandler::StartTable( sal_Unicode cTyped, bool 
bFromCommand, bool bIn
             aTester.TestSelectedBlock(
                 rDoc, aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Col(), 
aCursorPos.Row(), rMark );
 
-        bool bStartInputMode = true;
+        bool bStartInputMode = !(pActiveViewSh->GetViewShell() && 
pActiveViewSh->GetViewShell()->IsLokReadOnlyView());
 
         if (!aTester.IsEditable())
         {
@@ -3953,7 +3953,7 @@ bool ScInputHandler::KeyInput( const KeyEvent& rKEvt, 
bool bStartEdit /* = false
         UpdateActiveView();
         bool bNewView = DataChanging( nChar );
 
-        if (bProtected)                             // Protected cell?
+        if (bProtected || (pActiveViewSh->GetViewShell() && 
pActiveViewSh->GetViewShell()->IsLokReadOnlyView())) // Protected cell?
             bUsed = true;                           // Don't forward KeyEvent
         else                                        // Changes allowed
         {
@@ -4187,7 +4187,7 @@ void ScInputHandler::InputCommand( const CommandEvent& 
rCEvt )
         UpdateActiveView();
         bool bNewView = DataChanging( 0, true );
 
-        if (!bProtected)                            // changes allowed
+        if (!bProtected && !(pActiveViewSh->GetViewShell() && 
pActiveViewSh->GetViewShell()->IsLokReadOnlyView())) // changes allowed
         {
             if (bNewView)                           // create new edit view
             {
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 426e0d88cf58..88d64a526e9e 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -1716,7 +1716,7 @@ bool ScGridWindow::TestMouse( const MouseEvent& rMEvt, 
bool bAction )
     SfxInPlaceClient* pClient = mrViewData.GetViewShell()->GetIPClient();
     bool bOleActive = ( pClient && pClient->IsObjectInPlaceActive() );
 
-    if ( mrViewData.IsActive() && !bOleActive )
+    if ( mrViewData.IsActive() && !bOleActive && 
!mrViewData.GetViewShell()->IsLokReadOnlyView())
     {
         ScDocument& rDoc = mrViewData.GetDocument();
         SCTAB nTab = mrViewData.GetTabNo();
diff --git a/sfx2/inc/unoctitm.hxx b/sfx2/inc/unoctitm.hxx
index d23b8c9fd714..f18c4948f774 100644
--- a/sfx2/inc/unoctitm.hxx
+++ b/sfx2/inc/unoctitm.hxx
@@ -138,6 +138,7 @@ public:
     void       dispatch( const css::util::URL& aURL,
                                   const css::uno::Sequence< 
css::beans::PropertyValue >& aArgs,
                                   const css::uno::Reference< 
css::frame::XDispatchResultListener >& rListener );
+
     /// @throws css::uno::RuntimeException
     void       addStatusListener(const css::uno::Reference< 
css::frame::XStatusListener > & xControl, const css::util::URL& aURL);
     void                UnBindController();
diff --git a/sfx2/source/control/dispatch.cxx b/sfx2/source/control/dispatch.cxx
index 461de314d577..8505c5ea8477 100644
--- a/sfx2/source/control/dispatch.cxx
+++ b/sfx2/source/control/dispatch.cxx
@@ -1959,7 +1959,7 @@ void SfxDispatcher::SetReadOnly_Impl( bool bOn )
 
 bool SfxDispatcher::GetReadOnly_Impl() const
 {
-    return xImp->bReadOnly;
+    return xImp->bReadOnly || SfxViewShell::IsCurrentLokViewReadOnly();
 }
 
 /** With 'bOn' the Dispatcher is quasi dead and transfers everything to the
@@ -2021,16 +2021,21 @@ SfxItemState SfxDispatcher::QueryState( sal_uInt16 
nSID, css::uno::Any& rAny )
 
 bool SfxDispatcher::IsReadOnlyShell_Impl( sal_uInt16 nShell ) const
 {
+    bool bResult = true;
     sal_uInt16 nShellCount = xImp->aStack.size();
     if ( nShell < nShellCount )
     {
         SfxShell* pShell = *( xImp->aStack.rbegin() + nShell );
         if( dynamic_cast< const SfxModule *>( pShell ) != nullptr || 
dynamic_cast< const SfxApplication *>( pShell ) != nullptr || dynamic_cast< 
const SfxViewFrame *>( pShell ) !=  nullptr )
-            return false;
+            bResult = false;
         else
-            return xImp->bReadOnly;
+            bResult = xImp->bReadOnly;
     }
-    return true;
+
+    if (!bResult && SfxViewShell::IsCurrentLokViewReadOnly())
+            bResult = true;
+
+    return bResult;
 }
 
 void SfxDispatcher::RemoveShell_Impl( SfxShell& rShell )
diff --git a/sfx2/source/control/unoctitm.cxx b/sfx2/source/control/unoctitm.cxx
index 54c2424ff249..7ddfd50a0796 100644
--- a/sfx2/source/control/unoctitm.cxx
+++ b/sfx2/source/control/unoctitm.cxx
@@ -520,6 +520,39 @@ void collectUIInformation(const util::URL& rURL, const 
css::uno::Sequence< css::
 
 }
 
+// Checks if LOK is active and uno command is allowed for the current LOK view.
+static bool isCommandAllowedForViewType(const OUString& command)
+{
+    if (SfxViewShell::IsCurrentLokViewReadOnly())
+    {
+        // This is a sublist of "sUnoCommands".
+        constexpr OUString allowedCommandList[] = {
+            u"Copy"_ustr,
+            u"SelectAll"_ustr,
+            u"SelectColumn"_ustr,
+            u"SelectRow"_ustr,
+            u"EntireRow"_ustr,
+            u"EntireColumn"_ustr,
+            u"EntireCell"_ustr,
+            u"RowColSelCount"_ustr,
+            u"SpellOnline"_ustr,
+            u"StatePageNumber"_ustr,
+            u"StateWordCount"_ustr,
+            u"StateTableCell"_ustr,
+            u"SelectionMode"_ustr,
+            u"PageStatus"_ustr,
+            u"LayoutStatus"_ustr,
+            u"ToolbarMode"_ustr,
+            u"ChangeTheme"_ustr,
+            u"CopyHyperlinkLocation"_ustr
+        };
+
+        return std::find(std::begin(allowedCommandList), 
std::end(allowedCommandList), command) != std::end(allowedCommandList);
+    }
+
+    return true;
+}
+
 void SfxDispatchController_Impl::dispatch( const css::util::URL& aURL,
         const css::uno::Sequence< css::beans::PropertyValue >& aArgs,
         const css::uno::Reference< css::frame::XDispatchResultListener >& 
rListener )
@@ -546,6 +579,12 @@ void SfxDispatchController_Impl::dispatch( const 
css::util::URL& aURL,
         return;
     }
 
+
+    if (aURL.Protocol == ".uno:" && !isCommandAllowedForViewType(aURL.Path))
+    {
+        return;
+    }
+
     if (
         !(pDispatch &&
         (
diff --git a/sfx2/source/doc/objmisc.cxx b/sfx2/source/doc/objmisc.cxx
index 234ae799caeb..e5a69d717657 100644
--- a/sfx2/source/doc/objmisc.cxx
+++ b/sfx2/source/doc/objmisc.cxx
@@ -106,6 +106,7 @@
 #include <openflag.hxx>
 #include "objstor.hxx"
 #include <appopen.hxx>
+#include <sfx2/viewsh.hxx>
 
 #include <memory>
 
@@ -346,7 +347,7 @@ bool SfxObjectShell::IsReadOnlyUI() const
 */
 
 {
-    return pImpl->bReadOnlyUI;
+    return pImpl->bReadOnlyUI || SfxViewShell::IsCurrentLokViewReadOnly();
 }
 
 
diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx
index 3d4444b56b16..5819cafd83a1 100644
--- a/sfx2/source/view/viewsh.cxx
+++ b/sfx2/source/view/viewsh.cxx
@@ -2847,6 +2847,13 @@ SfxViewShell* SfxViewShell::Current()
     return pCurrent ? pCurrent->GetViewShell() : nullptr;
 }
 
+bool SfxViewShell::IsCurrentLokViewReadOnly()
+{
+    if (!comphelper::LibreOfficeKit::isActive() || Current() == nullptr || 
!Current()->IsLokReadOnlyView())
+        return false;
+    else
+        return true;
+}
 
 SfxViewShell* SfxViewShell::Get( const Reference< XController>& i_rController )
 {
diff --git a/svx/sdi/svx.sdi b/svx/sdi/svx.sdi
index fad6109d6add..182dcaca55c4 100644
--- a/svx/sdi/svx.sdi
+++ b/svx/sdi/svx.sdi
@@ -7472,7 +7472,7 @@ SfxVoidItem TableChangeCurrentBorderPosition 
SID_TABLE_CHANGE_CURRENT_BORDER_POS
 [
     AutoUpdate = FALSE,
     FastCall = TRUE,
-    ReadOnlyDoc = TRUE,
+    ReadOnlyDoc = FALSE,
     Toggle = FALSE,
     Container = FALSE,
     RecordAbsolute = FALSE,
diff --git a/svx/source/svdraw/svdedtv.cxx b/svx/source/svdraw/svdedtv.cxx
index 8c1c60bba681..b62d5fd89af9 100644
--- a/svx/source/svdraw/svdedtv.cxx
+++ b/svx/source/svdraw/svdedtv.cxx
@@ -36,6 +36,7 @@
 #include <svx/scene3d.hxx>
 #include <svx/xfillit0.hxx>
 #include <osl/diagnose.h>
+#include <sfx2/viewsh.hxx>
 
 #include <com/sun/star/lang/XServiceInfo.hpp>
 
@@ -649,7 +650,7 @@ void SdrEditView::CheckPossibilities()
     static_cast<SdrPolyEditView*>(this)->ImpCheckPolyPossibilities();
     m_bPossibilitiesDirty=false;
 
-    if (m_bReadOnly) {
+    if (m_bReadOnly || SfxViewShell::IsCurrentLokViewReadOnly() ) {
         bool bTemp=m_bGrpEnterPossible;
         ImpResetPossibilityFlags();
         m_bReadOnly=true;
diff --git a/sw/source/uibase/docvw/edtwin.cxx 
b/sw/source/uibase/docvw/edtwin.cxx
index 073b6b59649e..24358cf5505a 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -433,8 +433,8 @@ void SwEditWin::UpdatePointer(const Point &rLPt, sal_uInt16 
nModifier )
     bool bPrefSdrPointer = false;
     bool bHitHandle = false;
     bool bCntAtPos = false;
-    bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly() &&
-                          rSh.IsCursorReadonly();
+    bool bIsViewReadOnly = IsViewReadonly();
+
     m_aActHitType = SdrHitKind::NONE;
     PointerStyle eStyle = PointerStyle::Text;
     if ( !pSdrView )
@@ -542,7 +542,7 @@ void SwEditWin::UpdatePointer(const Point &rLPt, sal_uInt16 
nModifier )
     }
     if ( bPrefSdrPointer )
     {
-        if (bIsDocReadOnly || (rSh.IsObjSelected() && 
rSh.IsSelObjProtected(FlyProtectFlags::Content) != FlyProtectFlags::NONE))
+        if (bIsViewReadOnly || (rSh.IsObjSelected() && 
rSh.IsSelObjProtected(FlyProtectFlags::Content) != FlyProtectFlags::NONE))
             SetPointer( PointerStyle::NotAllowed );
         else
         {
@@ -1433,12 +1433,11 @@ void SwEditWin::KeyInput(const KeyEvent &rKEvt)
     // if every key event stopped and started it again.
     comphelper::ScopeGuard keyInputFlushTimerStop([this]() { 
m_aKeyInputFlushTimer.Stop(); });
 
-    bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly() &&
-                          rSh.IsCursorReadonly();
+    bool bIsViewReadOnly = IsViewReadonly();
 
     //if the language changes the buffer must be flushed
     LanguageType eNewLanguage = GetInputLanguage();
-    if(!bIsDocReadOnly && m_eBufferLanguage != eNewLanguage && 
!m_aInBuffer.isEmpty())
+    if(!bIsViewReadOnly && m_eBufferLanguage != eNewLanguage && 
!m_aInBuffer.isEmpty())
     {
         FlushInBuffer();
     }
@@ -1452,7 +1451,7 @@ void SwEditWin::KeyInput(const KeyEvent &rKEvt)
     }
 
     // OS:the DrawView also needs a readonly-Flag as well
-    if ( !bIsDocReadOnly && rSh.GetDrawView() && rSh.GetDrawView()->KeyInput( 
rKEvt, this ) )
+    if ( !bIsViewReadOnly && rSh.GetDrawView() && rSh.GetDrawView()->KeyInput( 
rKEvt, this ) )
     {
         rSh.GetView().GetViewFrame().GetBindings().InvalidateAll( false );
         rSh.SetModified();
@@ -1486,7 +1485,7 @@ void SwEditWin::KeyInput(const KeyEvent &rKEvt)
 
     KeyEvent aKeyEvent( rKEvt );
     // look for vertical mappings
-    if( !bIsDocReadOnly && !rSh.IsSelFrameMode() && !rSh.IsObjSelected() )
+    if( !bIsViewReadOnly && !rSh.IsSelFrameMode() && !rSh.IsObjSelected() )
     {
         if( KEY_UP == nKey || KEY_DOWN == nKey ||
             KEY_LEFT == nKey || KEY_RIGHT == nKey )
@@ -1700,7 +1699,7 @@ void SwEditWin::KeyInput(const KeyEvent &rKEvt)
                        GotoPrevFieldMark,
                        End };
 
-    SwKeyState eKeyState = bIsDocReadOnly ? SwKeyState::CheckDocReadOnlyKeys : 
SwKeyState::CheckKey;
+    SwKeyState eKeyState = bIsViewReadOnly ? SwKeyState::CheckDocReadOnlyKeys 
: SwKeyState::CheckKey;
     SwKeyState eNextKeyState = SwKeyState::End;
     sal_uInt8 nDir = 0;
 
@@ -2407,7 +2406,7 @@ KEYINPUT_CHECKTABLE_INSDEL:
                     rSh.NumOrNoNum();
                 }
 
-                if( !m_aInBuffer.isEmpty() && ( !bNormalChar || bIsDocReadOnly 
))
+                if( !m_aInBuffer.isEmpty() && ( !bNormalChar || 
bIsViewReadOnly ))
                     FlushInBuffer();
 
                 if (rSh.HasReadonlySel()
@@ -2430,7 +2429,7 @@ KEYINPUT_CHECKTABLE_INSDEL:
                     if( rKeyCode.GetFunction() == KeyFuncType::COPY )
                         
GetView().GetViewFrame().GetBindings().Execute(SID_COPY);
 
-                    if( !bIsDocReadOnly && bNormalChar )
+                    if( !bIsViewReadOnly && bNormalChar )
                     {
                         const SelectionType nSelectionType = 
rSh.GetSelectionType();
                         const bool bDrawObject = (nSelectionType & 
SelectionType::DrawObject) &&
@@ -2969,8 +2968,8 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt)
     bool bPageAnchored = false;
     bool bOverHeaderFooterFly = IsOverHeaderFooterFly( aDocPos, eControl, 
bOverFly, bPageAnchored );
 
-    bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly();
-    if (bOverHeaderFooterFly && (!bIsDocReadOnly && rSh.GetCurField()))
+    bool bIsViewReadOnly = m_rView.GetDocShell()->IsReadOnly() || 
(rSh.GetSfxViewShell() && rSh.GetSfxViewShell()->IsLokReadOnlyView());
+    if (bOverHeaderFooterFly && (!bIsViewReadOnly && rSh.GetCurField()))
         // We have a field here, that should have priority over header/footer 
fly.
         bOverHeaderFooterFly = false;
 
@@ -3211,7 +3210,7 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt)
                 if( rSh.IsObjSelected() )
                 {
                     SdrHdl* pHdl;
-                    if( !bIsDocReadOnly &&
+                    if( !bIsViewReadOnly &&
                         !m_pAnchorMarker &&
                         pSdrView &&
                         nullptr != ( pHdl = pSdrView->PickHandle(aDocPos) ) &&
@@ -3368,7 +3367,7 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt)
                     {
                         m_rView.NoRotate();
                         SdrHdl *pHdl;
-                        if( !bIsDocReadOnly && !m_pAnchorMarker && nullptr !=
+                        if( !bIsViewReadOnly && !m_pAnchorMarker && nullptr !=
                             ( pHdl = pSdrView->PickHandle(aDocPos) ) &&
                                 ( pHdl->GetKind() == SdrHdlKind::Anchor ||
                                   pHdl->GetKind() == SdrHdlKind::Anchor_TR ) )
@@ -3434,7 +3433,7 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt)
                     case 2:
                     {
                         g_bFrameDrag = false;
-                        if (!bIsDocReadOnly && rSh.IsInsideSelectedObj(aDocPos)
+                        if (!bIsViewReadOnly && 
rSh.IsInsideSelectedObj(aDocPos)
                             && (FlyProtectFlags::NONE
                                     == 
rSh.IsSelObjProtected(FlyProtectFlags::Content
                                                              | 
FlyProtectFlags::Parent)
@@ -3491,7 +3490,7 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt)
                         SwField *pField;
                         bool bFootnote = false;
 
-                        if( !bIsDocReadOnly &&
+                        if( !bIsViewReadOnly &&
                             (nullptr != (pField = rSh.GetCurField(true)) ||
                               ( bFootnote = rSh.GetCurFootnote() )        ) )
                         {
@@ -4144,7 +4143,7 @@ void SwEditWin::MouseMove(const MouseEvent& _rMEvt)
         m_pShadCursor.reset();
     }
 
-    bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly();
+    bool bIsViewReadOnly = m_rView.GetDocShell()->IsReadOnly() || 
(rSh.GetSfxViewShell() && rSh.GetSfxViewShell()->IsLokReadOnlyView());
 
     CurrShell aCurr( &rSh );
 
@@ -4164,7 +4163,7 @@ void SwEditWin::MouseMove(const MouseEvent& _rMEvt)
     const SwCallMouseEvent aLastCallEvent( m_aSaveCallEvent );
     m_aSaveCallEvent.Clear();
 
-    if ( !bIsDocReadOnly && pSdrView && pSdrView->MouseMove(rMEvt,GetOutDev()) 
)
+    if ( !bIsViewReadOnly && pSdrView && 
pSdrView->MouseMove(rMEvt,GetOutDev()) )
     {
         SetPointer( PointerStyle::Text );
         return; // evaluate SdrView's event
@@ -4256,7 +4255,7 @@ void SwEditWin::MouseMove(const MouseEvent& _rMEvt)
     }
 
     // determine if we only change the mouse pointer and return
-    if (!bIsDocReadOnly && bInsWin && !m_pApplyTempl && !rSh.IsInSelect() && 
changeMousePointer(aDocPt))
+    if (!bIsViewReadOnly && bInsWin && !m_pApplyTempl && !rSh.IsInSelect() && 
changeMousePointer(aDocPt))
     {
         return;
     }
@@ -4398,7 +4397,7 @@ void SwEditWin::MouseMove(const MouseEvent& _rMEvt)
                     }
                     // event processing for resizing
 
-                    if( bIsDocReadOnly )
+                    if( bIsViewReadOnly )
                         break;
 
                     bool bResizeKeepRatio = rSh.GetSelectionType() & 
SelectionType::Graphic ||
@@ -4437,7 +4436,7 @@ void SwEditWin::MouseMove(const MouseEvent& _rMEvt)
                     rSh.Drag( &aDocPt, rMEvt.IsShift() );
                     m_bIsInMove = true;
                 }
-                else if( bIsDocReadOnly )
+                else if( bIsViewReadOnly )
                     break;
 
                 if ( !bInsWin )
@@ -4560,7 +4559,7 @@ void SwEditWin::MouseMove(const MouseEvent& _rMEvt)
                                     aLastCallEvent, true );
                 }
 
-                if( bTstShdwCursor && bInsWin && !bIsDocReadOnly &&
+                if( bTstShdwCursor && bInsWin && !bIsViewReadOnly &&
                     !m_bInsFrame &&
                     !rSh.GetViewOptions()->getBrowseMode() &&
                     rSh.GetViewOptions()->IsShadowCursor() &&
@@ -5564,6 +5563,12 @@ void SwEditWin::LoseFocus()
         s_pQuickHlpData->Stop( m_rView.GetWrtShell() );
 }
 
+bool SwEditWin::IsViewReadonly() const
+{
+    SwWrtShell &rSh = m_rView.GetWrtShell();
+    return (m_rView.GetDocShell()->IsReadOnly() && rSh.IsCursorReadonly()) || 
(rSh.GetSfxViewShell() && rSh.GetSfxViewShell()->IsLokReadOnlyView());
+}
+
 void SwEditWin::Command( const CommandEvent& rCEvt )
 {
     if (isDisposed())
@@ -5703,9 +5708,8 @@ void SwEditWin::Command( const CommandEvent& rCEvt )
 
     case CommandEventId::StartExtTextInput:
     {
-        bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly() &&
-                              rSh.IsCursorReadonly();
-        if(!bIsDocReadOnly)
+        bool bIsViewReadOnly = IsViewReadonly();
+        if(!bIsViewReadOnly)
         {
             if( rSh.HasDrawView() && rSh.GetDrawView()->IsTextEdit() )
             {
@@ -5726,9 +5730,9 @@ void SwEditWin::Command( const CommandEvent& rCEvt )
     }
     case CommandEventId::EndExtTextInput:
     {
-        bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly() &&
-                              rSh.IsCursorReadonly();
-        if(!bIsDocReadOnly)
+        bool bIsViewReadOnly = IsViewReadonly();
+
+        if(!bIsViewReadOnly)
         {
             if( rSh.HasDrawView() && rSh.GetDrawView()->IsTextEdit() )
             {
@@ -5777,9 +5781,9 @@ void SwEditWin::Command( const CommandEvent& rCEvt )
     break;
     case CommandEventId::ExtTextInput:
     {
-        bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly() &&
-                              rSh.IsCursorReadonly();
-        if (!bIsDocReadOnly && !rSh.HasReadonlySel())
+        bool bIsViewReadOnly = IsViewReadonly();
+
+        if (!bIsViewReadOnly && !rSh.HasReadonlySel())
         {
             if( s_pQuickHlpData->m_bIsDisplayed )
                 s_pQuickHlpData->Stop( rSh );
diff --git a/sw/source/uibase/inc/edtwin.hxx b/sw/source/uibase/inc/edtwin.hxx
index ceaa98657fe9..e85229546825 100644
--- a/sw/source/uibase/inc/edtwin.hxx
+++ b/sw/source/uibase/inc/edtwin.hxx
@@ -288,6 +288,8 @@ public:
     /// Allows starting or ending a graphic move or resize action.
     void SetGraphicTwipPosition(bool bStart, const Point& rPosition);
 
+    bool IsViewReadonly() const;
+
     const SwTextFrame* GetSavedOutlineFrame() const { return 
m_pSavedOutlineFrame; }
     void SetSavedOutlineFrame(SwTextFrame* pFrame) { m_pSavedOutlineFrame = 
pFrame; }
     // bSubs set true, sets all sub level outline content to same visibility 
as nOutlinePos.
diff --git a/sw/source/uibase/uiview/srcview.cxx 
b/sw/source/uibase/uiview/srcview.cxx
index 563dd0b46859..713e13b5791a 100644
--- a/sw/source/uibase/uiview/srcview.cxx
+++ b/sw/source/uibase/uiview/srcview.cxx
@@ -438,7 +438,7 @@ void SwSrcView::GetState(SfxItemSet& rSet)
                 SearchOptionFlags nOpt = SRC_SEARCHOPTIONS;
                 SwDocShell* pDocShell = GetDocShell();
                 assert(pDocShell);
-                if (pDocShell->IsReadOnly())
+                if (pDocShell->IsReadOnly() || 
SfxViewShell::IsCurrentLokViewReadOnly())
                     nOpt &= 
~SearchOptionFlags(SearchOptionFlags::REPLACE|SearchOptionFlags::REPLACE_ALL);
 
                 rSet.Put( SfxUInt16Item( SID_SEARCH_OPTIONS,  
static_cast<sal_uInt16>(nOpt) ) );

Reply via email to