diff options
author | Gökay Şatır <gokaysatir@gmail.com> | 2024-02-22 13:54:06 +0300 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2024-03-21 16:32:09 +0100 |
commit | 1de1c47471278db2344c986e9d597d6a05e559e9 (patch) | |
tree | 14494bf30d8bac21fe058b98030c69df2db688c3 | |
parent | 9adcf67c9b164d019eebe45279bcaa91b0ce471a (diff) |
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.
Change-Id: I71fc353976256bce22042bbb6042ee464b65cc13
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165093
Tested-by: Jenkins
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
-rw-r--r-- | desktop/source/lib/init.cxx | 28 | ||||
-rw-r--r-- | editeng/source/editeng/editview.cxx | 3 | ||||
-rw-r--r-- | editeng/source/editeng/impedit2.cxx | 81 | ||||
-rw-r--r-- | include/sfx2/viewsh.hxx | 1 | ||||
-rw-r--r-- | sc/source/ui/app/inputhdl.cxx | 6 | ||||
-rw-r--r-- | sc/source/ui/view/gridwin.cxx | 2 | ||||
-rw-r--r-- | sfx2/inc/unoctitm.hxx | 1 | ||||
-rw-r--r-- | sfx2/source/control/dispatch.cxx | 13 | ||||
-rw-r--r-- | sfx2/source/control/unoctitm.cxx | 39 | ||||
-rw-r--r-- | sfx2/source/doc/objmisc.cxx | 3 | ||||
-rw-r--r-- | sfx2/source/view/viewsh.cxx | 7 | ||||
-rw-r--r-- | svx/sdi/svx.sdi | 2 | ||||
-rw-r--r-- | svx/source/svdraw/svdedtv.cxx | 3 | ||||
-rw-r--r-- | sw/source/uibase/docvw/edtwin.cxx | 68 | ||||
-rw-r--r-- | sw/source/uibase/inc/edtwin.hxx | 2 | ||||
-rw-r--r-- | sw/source/uibase/uiview/srcview.cxx | 2 |
16 files changed, 179 insertions, 82 deletions
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 25ba3ade88c4..6eba39cc32f3 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -4686,6 +4686,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) { @@ -5067,6 +5071,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"); @@ -5076,6 +5097,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)); @@ -7133,6 +7158,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 7f20f65cb0bb..81fbd2d10b39 100644 --- a/editeng/source/editeng/editview.cxx +++ b/editeng/source/editeng/editview.cxx @@ -156,6 +156,7 @@ EditView::EditView(EditEngine* pEditEngine, vcl::Window* pWindow) : mpImpEditView(new ImpEditView(this, pEditEngine, pWindow)) { assert(pEditEngine); + getImpl().mbReadOnly = getImpl().mbReadOnly || SfxViewShell::IsCurrentLokViewReadOnly(); } EditView::~EditView() @@ -253,7 +254,7 @@ void EditView::Invalidate() void EditView::SetReadOnly( bool bReadOnly ) { - getImpl().mbReadOnly = bReadOnly; + getImpl().mbReadOnly = bReadOnly || SfxViewShell::IsCurrentLokViewReadOnly(); } bool EditView::IsReadOnly() const diff --git a/editeng/source/editeng/impedit2.cxx b/editeng/source/editeng/impedit2.cxx index 8707986ab2fb..6ab1041d378e 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> @@ -349,63 +350,69 @@ bool ImpEditEngine::Command( const CommandEvent& rCEvt, EditView* pView ) SetActiveView( pView ); if ( rCEvt.GetCommand() == CommandEventId::StartExtTextInput ) { - pView->DeleteSelected(); - mpIMEInfos.reset(); - EditPaM aPaM = pView->getImpl().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->getImpl().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->getImpl().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->getImpl().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 adecc4e1a968..ea7d345b29c4 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 62bd2a3c66cf..293b4199eb42 100644 --- a/sc/source/ui/app/inputhdl.cxx +++ b/sc/source/ui/app/inputhdl.cxx @@ -2501,7 +2501,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()) { @@ -3937,7 +3937,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 { @@ -4171,7 +4171,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 c24435aaa903..013a994500df 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 a780892b6940..ef59094293b9 100644 --- a/sfx2/source/control/dispatch.cxx +++ b/sfx2/source/control/dispatch.cxx @@ -1958,7 +1958,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 @@ -2020,16 +2020,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 28097661bb7e..f1af18fe672b 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 d7f417a9bcad..e2d86cac0993 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 8c54bd049acb..f0ec042ef4d6 100644 --- a/sfx2/source/view/viewsh.cxx +++ b/sfx2/source/view/viewsh.cxx @@ -2843,6 +2843,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 c91f57bcb448..bc53f325914c 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 872e7539abbe..2a97a6dbc02d 100644 --- a/svx/source/svdraw/svdedtv.cxx +++ b/svx/source/svdraw/svdedtv.cxx @@ -35,6 +35,7 @@ #include <svx/svdogrp.hxx> #include <svx/xfillit0.hxx> #include <osl/diagnose.h> +#include <sfx2/viewsh.hxx> #include <com/sun/star/lang/XServiceInfo.hpp> @@ -648,7 +649,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 b3f8c6855e43..03b8e6f66a9a 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) && @@ -3012,8 +3011,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; @@ -3254,7 +3253,7 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt) if( rSh.IsObjSelected() ) { SdrHdl* pHdl; - if( !bIsDocReadOnly && + if( !bIsViewReadOnly && !m_pAnchorMarker && pSdrView && nullptr != ( pHdl = pSdrView->PickHandle(aDocPos) ) && @@ -3411,7 +3410,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 ) ) @@ -3477,7 +3476,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) @@ -3534,7 +3533,7 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt) SwField *pField; bool bFootnote = false; - if( !bIsDocReadOnly && + if( !bIsViewReadOnly && (nullptr != (pField = rSh.GetCurField(true)) || ( bFootnote = rSh.GetCurFootnote() ) ) ) { @@ -4192,7 +4191,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 ); @@ -4212,7 +4211,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 @@ -4304,7 +4303,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; } @@ -4446,7 +4445,7 @@ void SwEditWin::MouseMove(const MouseEvent& _rMEvt) } // event processing for resizing - if( bIsDocReadOnly ) + if( bIsViewReadOnly ) break; bool bResizeKeepRatio = rSh.GetSelectionType() & SelectionType::Graphic || @@ -4485,7 +4484,7 @@ void SwEditWin::MouseMove(const MouseEvent& _rMEvt) rSh.Drag( &aDocPt, rMEvt.IsShift() ); m_bIsInMove = true; } - else if( bIsDocReadOnly ) + else if( bIsViewReadOnly ) break; if ( !bInsWin ) @@ -4608,7 +4607,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() && @@ -5623,6 +5622,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()) @@ -5762,9 +5767,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() ) { @@ -5785,9 +5789,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() ) { @@ -5836,9 +5840,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 5f054024d1d4..4419cd9a446e 100644 --- a/sw/source/uibase/inc/edtwin.hxx +++ b/sw/source/uibase/inc/edtwin.hxx @@ -291,6 +291,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) ) ); |