summaryrefslogtreecommitdiffstats
path: root/sw/source/uibase/uiview/view.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/uibase/uiview/view.cxx')
-rw-r--r--sw/source/uibase/uiview/view.cxx2120
1 files changed, 2120 insertions, 0 deletions
diff --git a/sw/source/uibase/uiview/view.cxx b/sw/source/uibase/uiview/view.cxx
new file mode 100644
index 0000000000..2d46cd04f2
--- /dev/null
+++ b/sw/source/uibase/uiview/view.cxx
@@ -0,0 +1,2120 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <config_features.h>
+#include <config_wasm_strip.h>
+
+#include <stdlib.h>
+#include <hintids.hxx>
+#include <comphelper/string.hxx>
+#include <comphelper/lok.hxx>
+#include <o3tl/any.hxx>
+#include <o3tl/string_view.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/inputctx.hxx>
+#include <svl/eitem.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/lingucfg.hxx>
+#include <unotools/useroptions.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/request.hxx>
+#include <svx/ruler.hxx>
+#include <svx/srchdlg.hxx>
+#include <svx/fmshell.hxx>
+#include <svx/extrusionbar.hxx>
+#include <svx/fontworkbar.hxx>
+#include <svx/fmview.hxx>
+#include <unotxvw.hxx>
+#include <cmdid.h>
+#include <svl/hint.hxx>
+#include <swmodule.hxx>
+#include <inputwin.hxx>
+#include <uivwimp.hxx>
+#include <edtwin.hxx>
+#include <textsh.hxx>
+#include <listsh.hxx>
+#include <tabsh.hxx>
+#include <grfsh.hxx>
+#include <mediash.hxx>
+#include <docsh.hxx>
+#include <frmsh.hxx>
+#include <olesh.hxx>
+#include <drawsh.hxx>
+#include <drawbase.hxx>
+#include <drformsh.hxx>
+#include <drwtxtsh.hxx>
+#include <beziersh.hxx>
+#include <navsh.hxx>
+#include <globdoc.hxx>
+#include <scroll.hxx>
+#include <gloshdl.hxx>
+#include <usrpref.hxx>
+#include <srcview.hxx>
+#include <doc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <IDocumentSettingAccess.hxx>
+#include <IDocumentDrawModelAccess.hxx>
+#include <DocumentFieldsManager.hxx>
+#include <IDocumentState.hxx>
+#include <IDocumentLayoutAccess.hxx>
+#include <drawdoc.hxx>
+#include <wdocsh.hxx>
+#include <wrtsh.hxx>
+#include <barcfg.hxx>
+#include <pview.hxx>
+#include <swdtflvr.hxx>
+#include <prtopt.hxx>
+#include <unotxdoc.hxx>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <com/sun/star/scanner/ScannerContext.hpp>
+#include <com/sun/star/scanner/XScannerManager2.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sdb/XDatabaseContext.hpp>
+#include <com/sun/star/sdb/DatabaseContext.hpp>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <sal/log.hxx>
+
+#include <formatclipboard.hxx>
+#include <PostItMgr.hxx>
+#include <annotsh.hxx>
+#include <swruler.hxx>
+#include <svx/theme/ThemeColorPaletteManager.hxx>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <sfx2/lokhelper.hxx>
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <svtools/embedhlp.hxx>
+#include <tools/UnitConversion.hxx>
+
+#include <svx/sdr/overlay/overlayselection.hxx>
+#include <svx/sdr/overlay/overlayobject.hxx>
+#include <svx/sdr/overlay/overlaymanager.hxx>
+#include <svx/sdrpaintwindow.hxx>
+#include <svx/svdview.hxx>
+#include <node2lay.hxx>
+#include <cntfrm.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::scanner;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+
+#define SWVIEWFLAGS SfxViewShellFlags::HAS_PRINTOPTIONS
+
+// Statics. OMG.
+
+bool bDocSzUpdated = true;
+
+SvxSearchItem* SwView::s_pSrchItem = nullptr;
+
+bool SwView::s_bExtra = false;
+bool SwView::s_bFound = false;
+bool SwView::s_bJustOpened = false;
+
+std::unique_ptr<SearchAttrItemList> SwView::s_xSearchList;
+std::unique_ptr<SearchAttrItemList> SwView::s_xReplaceList;
+
+SfxDispatcher &SwView::GetDispatcher()
+{
+ return *GetViewFrame().GetDispatcher();
+}
+
+void SwView::ImpSetVerb( SelectionType nSelType )
+{
+ bool bResetVerbs = m_bVerbsActive;
+ if ( !GetViewFrame().GetFrame().IsInPlace() &&
+ (SelectionType::Ole|SelectionType::Graphic) & nSelType )
+ {
+ FlyProtectFlags eProtectFlags = m_pWrtShell->IsSelObjProtected(FlyProtectFlags::Content);
+ if (eProtectFlags == FlyProtectFlags::NONE || nSelType & SelectionType::Ole)
+ {
+ if ( nSelType & SelectionType::Ole )
+ {
+ SetVerbs( GetWrtShell().GetOLEObject()->getSupportedVerbs() );
+ m_bVerbsActive = true;
+ bResetVerbs = false;
+ }
+ }
+ }
+ if ( bResetVerbs )
+ {
+ SetVerbs( Sequence< embed::VerbDescriptor >() );
+ m_bVerbsActive = false;
+ }
+}
+
+// Called by the SwEditWin when it gets the focus.
+
+void SwView::GotFocus() const
+{
+ // if we got the focus, and the form shell *is* on the top of the dispatcher
+ // stack, then we need to rebuild the stack (the form shell doesn't belong to
+ // the top then)
+ const SfxDispatcher& rDispatcher = const_cast< SwView* >( this )->GetDispatcher();
+ SfxShell* pTopShell = rDispatcher.GetShell( 0 );
+ FmFormShell* pAsFormShell = dynamic_cast<FmFormShell*>( pTopShell );
+ if ( pAsFormShell )
+ {
+ pAsFormShell->ForgetActiveControl();
+ const_cast< SwView* >( this )->AttrChangedNotify(nullptr);
+ }
+ else if ( m_pPostItMgr )
+ {
+ SwAnnotationShell* pAsAnnotationShell = dynamic_cast<SwAnnotationShell*>( pTopShell );
+ if ( pAsAnnotationShell )
+ {
+ m_pPostItMgr->SetActiveSidebarWin(nullptr);
+ const_cast< SwView* >( this )->AttrChangedNotify(nullptr);
+ }
+ }
+ if (SwWrtShell* pWrtShell = GetWrtShellPtr())
+ {
+ SwWrtShell& rWrtShell = GetWrtShell();
+ rWrtShell.GetDoc()->getIDocumentLayoutAccess().SetCurrentViewShell( pWrtShell );
+ rWrtShell.GetDoc()->getIDocumentSettingAccess().set( DocumentSettingId::BROWSE_MODE,
+ rWrtShell.GetViewOptions()->getBrowseMode() );
+ }
+}
+
+// called by the FormShell when a form control is focused. This is
+// a request to put the form shell on the top of the dispatcher stack
+
+IMPL_LINK_NOARG(SwView, FormControlActivated, LinkParamNone*, void)
+{
+ // if a form control has been activated, and the form shell is not on the top
+ // of the dispatcher stack, then we need to activate it
+ const SfxDispatcher& rDispatcher = GetDispatcher();
+ const SfxShell* pTopShell = rDispatcher.GetShell( 0 );
+ const FmFormShell* pAsFormShell = dynamic_cast<const FmFormShell*>( pTopShell );
+ if ( !pAsFormShell )
+ {
+ // if we're editing text currently, cancel this
+ SdrView *pSdrView = m_pWrtShell ? m_pWrtShell->GetDrawView() : nullptr;
+ if ( pSdrView && pSdrView->IsTextEdit() )
+ pSdrView->SdrEndTextEdit( true );
+
+ AttrChangedNotify(nullptr);
+ }
+}
+
+namespace
+{
+uno::Reference<frame::XLayoutManager> getLayoutManager(const SfxViewFrame& rViewFrame)
+{
+ uno::Reference<frame::XLayoutManager> xLayoutManager;
+ uno::Reference<beans::XPropertySet> xPropSet(rViewFrame.GetFrame().GetFrameInterface(),
+ uno::UNO_QUERY);
+ if (xPropSet.is())
+ {
+ try
+ {
+ xLayoutManager.set(xPropSet->getPropertyValue("LayoutManager"), uno::UNO_QUERY);
+ }
+ catch (const Exception& e)
+ {
+ SAL_WARN("sw.ui", "Failure getting layout manager: " + e.Message);
+ }
+ }
+ return xLayoutManager;
+}
+}
+
+void SwView::ShowUIElement(const OUString& sElementURL) const
+{
+ if (auto xLayoutManager = getLayoutManager(GetViewFrame()))
+ {
+ if (!xLayoutManager->getElement(sElementURL).is())
+ {
+ xLayoutManager->createElement(sElementURL);
+ xLayoutManager->showElement(sElementURL);
+ }
+ }
+}
+
+void SwView::SelectShell()
+{
+ // Attention: Maintain the SelectShell for the WebView additionally
+
+ // In case of m_bDying, our SfxShells are already gone, don't try to select a shell at all.
+ if(m_bInDtor || m_bDying)
+ return;
+
+ // Decision if the UpdateTable has to be called
+ bool bUpdateTable = false;
+ const SwFrameFormat* pCurTableFormat = m_pWrtShell->GetTableFormat();
+ if(pCurTableFormat && pCurTableFormat != m_pLastTableFormat)
+ {
+ bUpdateTable = true; // can only be executed later
+ }
+ m_pLastTableFormat = pCurTableFormat;
+
+ //SEL_TBL and SEL_TBL_CELLS can be ORed!
+ SelectionType nNewSelectionType = m_pWrtShell->GetSelectionType()
+ & ~SelectionType::TableCell;
+
+ // Determine if a different fly frame was selected.
+ bool bUpdateFly = false;
+ const SwFrameFormat* pCurFlyFormat = nullptr;
+ if (m_pWrtShell->IsSelFrameMode())
+ {
+ pCurFlyFormat = m_pWrtShell->GetFlyFrameFormat();
+ }
+ if (pCurFlyFormat && m_pLastFlyFormat && pCurFlyFormat != m_pLastFlyFormat)
+ {
+ // Only do an explicit update when switching between flys.
+ bUpdateFly = true;
+ }
+ m_pLastFlyFormat = pCurFlyFormat;
+
+ if ( m_pFormShell && m_pFormShell->IsActiveControl() )
+ nNewSelectionType |= SelectionType::FormControl;
+
+ if ( nNewSelectionType == m_nSelectionType )
+ {
+ GetViewFrame().GetBindings().InvalidateAll( false );
+ if ( m_nSelectionType & SelectionType::Ole ||
+ m_nSelectionType & SelectionType::Graphic )
+ // For graphs and OLE the verb can be modified of course!
+ ImpSetVerb( nNewSelectionType );
+
+ if (bUpdateFly)
+ {
+ SfxViewFrame& rViewFrame = GetViewFrame();
+ uno::Reference<frame::XFrame> xFrame = rViewFrame.GetFrame().GetFrameInterface();
+ if (xFrame.is())
+ {
+ // Invalidate cached dispatch objects.
+ xFrame->contextChanged();
+ }
+ }
+ }
+ else
+ {
+
+ SfxDispatcher &rDispatcher = GetDispatcher();
+ SwToolbarConfigItem *pBarCfg = SW_MOD()->GetToolbarConfig();
+
+ if ( m_pShell )
+ {
+ rDispatcher.Flush(); // Really erase all cached shells
+ //Remember to the old selection which toolbar was visible
+ ToolbarId eId = rDispatcher.GetObjectBarId(SFX_OBJECTBAR_OBJECT);
+ if (eId != ToolbarId::None)
+ pBarCfg->SetTopToolbar(m_nSelectionType, eId);
+
+ for ( sal_uInt16 i = 0; true; ++i )
+ {
+ SfxShell *pSfxShell = rDispatcher.GetShell( i );
+ if ( dynamic_cast< const SwBaseShell *>( pSfxShell ) != nullptr
+ || dynamic_cast< const SwDrawTextShell *>( pSfxShell ) != nullptr
+ || dynamic_cast< const svx::ExtrusionBar*>( pSfxShell ) != nullptr
+ || dynamic_cast< const svx::FontworkBar*>( pSfxShell ) != nullptr
+ || dynamic_cast< const SwAnnotationShell *>( pSfxShell ) != nullptr
+ )
+ {
+ rDispatcher.Pop( *pSfxShell, SfxDispatcherPopFlags::POP_DELETE );
+ }
+ else if ( dynamic_cast< const FmFormShell *>( pSfxShell ) != nullptr )
+ {
+ rDispatcher.Pop( *pSfxShell );
+ }
+ else
+ break;
+ }
+ }
+
+ bool bInitFormShell = false;
+ if (!m_pFormShell)
+ {
+ bInitFormShell = true;
+ m_pFormShell = new FmFormShell( this );
+ m_pFormShell->SetControlActivationHandler( LINK( this, SwView, FormControlActivated ) );
+ StartListening(*m_pFormShell);
+ }
+
+ bool bSetExtInpCntxt = false;
+ m_nSelectionType = nNewSelectionType;
+ ShellMode eShellMode;
+
+ if ( !( m_nSelectionType & SelectionType::FormControl ) )
+ rDispatcher.Push( *m_pFormShell );
+
+ m_pShell = new SwNavigationShell( *this );
+ rDispatcher.Push( *m_pShell );
+
+ if ( m_nSelectionType & SelectionType::Ole )
+ {
+ eShellMode = ShellMode::Object;
+ m_pShell = new SwOleShell( *this );
+ rDispatcher.Push( *m_pShell );
+ }
+ else if ( m_nSelectionType & SelectionType::Frame
+ || m_nSelectionType & SelectionType::Graphic)
+ {
+ eShellMode = ShellMode::Frame;
+ m_pShell = new SwFrameShell( *this );
+ rDispatcher.Push( *m_pShell );
+ if(m_nSelectionType & SelectionType::Graphic )
+ {
+ eShellMode = ShellMode::Graphic;
+ m_pShell = new SwGrfShell( *this );
+ rDispatcher.Push( *m_pShell );
+ }
+ }
+ else if ( m_nSelectionType & SelectionType::DrawObject )
+ {
+ eShellMode = ShellMode::Draw;
+ m_pShell = new SwDrawShell( *this );
+ rDispatcher.Push( *m_pShell );
+
+ if ( m_nSelectionType & SelectionType::Ornament )
+ {
+ eShellMode = ShellMode::Bezier;
+ m_pShell = new SwBezierShell( *this );
+ rDispatcher.Push( *m_pShell );
+ }
+#if HAVE_FEATURE_AVMEDIA
+ else if( m_nSelectionType & SelectionType::Media )
+ {
+ eShellMode = ShellMode::Media;
+ m_pShell = new SwMediaShell( *this );
+ rDispatcher.Push( *m_pShell );
+ }
+#endif
+ if (m_nSelectionType & SelectionType::ExtrudedCustomShape)
+ {
+ eShellMode = ShellMode::ExtrudedCustomShape;
+ m_pShell = new svx::ExtrusionBar(this);
+ rDispatcher.Push( *m_pShell );
+ }
+ if (m_nSelectionType & SelectionType::FontWork)
+ {
+ eShellMode = ShellMode::FontWork;
+ m_pShell = new svx::FontworkBar(this);
+ rDispatcher.Push( *m_pShell );
+ }
+ }
+ else if ( m_nSelectionType & SelectionType::DbForm )
+ {
+ eShellMode = ShellMode::DrawForm;
+ m_pShell = new SwDrawFormShell( *this );
+
+ rDispatcher.Push( *m_pShell );
+ }
+ else if ( m_nSelectionType & SelectionType::DrawObjectEditMode )
+ {
+ bSetExtInpCntxt = true;
+ eShellMode = ShellMode::DrawText;
+ rDispatcher.Push( *(new SwBaseShell( *this )) );
+ m_pShell = new SwDrawTextShell( *this );
+ rDispatcher.Push( *m_pShell );
+ }
+ else if ( m_nSelectionType & SelectionType::PostIt )
+ {
+ eShellMode = ShellMode::PostIt;
+ m_pShell = new SwAnnotationShell( *this );
+ rDispatcher.Push( *m_pShell );
+ }
+ else
+ {
+ bSetExtInpCntxt = true;
+ eShellMode = ShellMode::Text;
+ if ( m_nSelectionType & SelectionType::NumberList )
+ {
+ eShellMode = ShellMode::ListText;
+ m_pShell = new SwListShell( *this );
+ rDispatcher.Push( *m_pShell );
+ }
+ m_pShell = new SwTextShell(*this);
+ rDispatcher.Push( *m_pShell );
+ if ( m_nSelectionType & SelectionType::Table )
+ {
+ eShellMode = eShellMode == ShellMode::ListText ? ShellMode::TableListText
+ : ShellMode::TableText;
+ m_pShell = new SwTableShell( *this );
+ rDispatcher.Push( *m_pShell );
+ }
+ }
+
+ if ( m_nSelectionType & SelectionType::FormControl )
+ rDispatcher.Push( *m_pFormShell );
+
+ m_pViewImpl->SetShellMode(eShellMode);
+ ImpSetVerb( m_nSelectionType );
+
+ if( !GetDocShell()->IsReadOnly() )
+ {
+ if( bSetExtInpCntxt && GetWrtShell().HasReadonlySel() )
+ bSetExtInpCntxt = false;
+
+ InputContext aCntxt( GetEditWin().GetInputContext() );
+ aCntxt.SetOptions( bSetExtInpCntxt
+ ? (aCntxt.GetOptions() |
+ ( InputContextFlags::Text |
+ InputContextFlags::ExtText ))
+ : (aCntxt.GetOptions() & ~
+ InputContextFlags( InputContextFlags::Text |
+ InputContextFlags::ExtText )) );
+ GetEditWin().SetInputContext( aCntxt );
+ }
+
+ // Show Mail Merge toolbar initially for documents with Database fields
+ if (!m_bInitOnceCompleted && GetWrtShell().IsAnyDatabaseFieldInDoc() && !utl::ConfigManager::IsFuzzing())
+ ShowUIElement("private:resource/toolbar/mailmerge");
+
+ // Activate the toolbar to the new selection which also was active last time.
+ // Before a flush () must be, but does not affect the UI according to MBA and
+ // is not a performance problem.
+ // TODO/LATER: maybe now the Flush() command is superfluous?!
+ rDispatcher.Flush();
+
+ Point aPnt = GetEditWin().OutputToScreenPixel(GetEditWin().GetPointerPosPixel());
+ aPnt = GetEditWin().PixelToLogic(aPnt);
+ GetEditWin().UpdatePointer(aPnt);
+
+ SdrView* pDView = GetWrtShell().GetDrawView();
+ if ( bInitFormShell && pDView )
+ m_pFormShell->SetView(dynamic_cast<FmFormView*>( pDView) );
+
+ }
+ // Opportune time for the communication with OLE objects?
+ if ( GetDocShell()->GetDoc()->IsOLEPrtNotifyPending() )
+ GetDocShell()->GetDoc()->PrtOLENotify( false );
+
+ // now the table-update
+ if(bUpdateTable)
+ m_pWrtShell->UpdateTable();
+
+ GetViewImpl()->GetUNOObject_Impl()->NotifySelChanged();
+
+ m_bInitOnceCompleted = true;
+}
+
+// Interaction: AttrChangedNotify() and TimeoutHdl.
+// No Update if actions are still open, since the cursor on the core side
+// can be somewhere in no man's land.
+// But since we can no longer supply status and we want instead lock
+// the dispatcher.
+
+extern "C"
+{
+ static int lcl_CmpIds( const void *pFirst, const void *pSecond)
+ {
+ return *static_cast<sal_uInt16 const *>(pFirst) - *static_cast<sal_uInt16 const *>(pSecond);
+ }
+}
+
+IMPL_LINK_NOARG(SwView, AttrChangedNotify, LinkParamNone*, void)
+{
+ if ( GetEditWin().IsChainMode() )
+ GetEditWin().SetChainMode( false );
+
+ if (!m_pWrtShell || !GetDocShell())
+ {
+ return;
+ }
+
+ //Opt: Not if PaintLocked. During unlock a notify will be once more triggered.
+ if( !m_pWrtShell->IsPaintLocked() && !g_bNoInterrupt &&
+ GetDocShell()->IsReadOnly() )
+ CheckReadonlyState();
+
+ if( !m_pWrtShell->IsPaintLocked() && !g_bNoInterrupt )
+ CheckReadonlySelection();
+
+ if( !m_bAttrChgNotified )
+ {
+ if (m_pWrtShell->ActionPend() || g_bNoInterrupt ||
+ GetDispatcher().IsLocked() || //do not confuse the SFX
+ GetViewFrame().GetBindings().IsInUpdate() )//do not confuse the SFX
+ {
+ m_bAttrChgNotified = true;
+ m_aTimer.Start();
+
+ const SfxBoolItem *pItem =
+ GetObjectShell()->GetMedium()->GetItemSet().
+ GetItemIfSet( SID_HIDDEN, false );
+ if ( !pItem || !pItem->GetValue() )
+ {
+ GetViewFrame().GetBindings().ENTERREGISTRATIONS();
+ m_bAttrChgNotifiedWithRegistrations = true;
+ }
+
+ }
+ else
+ SelectShell();
+
+ }
+
+ // change ui if cursor is at a SwPostItField
+ if (m_pPostItMgr)
+ {
+ // only perform the code that is needed to determine, if at the
+ // actual cursor position is a post-it field
+ m_pPostItMgr->SetShadowState( m_pWrtShell->GetPostItFieldAtCursor() );
+ }
+}
+
+IMPL_LINK_NOARG(SwView, TimeoutHdl, Timer *, void)
+{
+ if (m_pWrtShell->ActionPend() || g_bNoInterrupt)
+ {
+ m_aTimer.Start();
+ return;
+ }
+
+ if ( m_bAttrChgNotifiedWithRegistrations )
+ {
+ GetViewFrame().GetBindings().LEAVEREGISTRATIONS();
+ m_bAttrChgNotifiedWithRegistrations = false;
+ }
+
+ CheckReadonlyState();
+ CheckReadonlySelection();
+
+ bool bOldUndo = m_pWrtShell->DoesUndo();
+ m_pWrtShell->DoUndo( false );
+ SelectShell();
+ m_pWrtShell->DoUndo( bOldUndo );
+ m_bAttrChgNotified = false;
+ GetViewImpl()->GetUNOObject_Impl()->NotifySelChanged();
+}
+
+void SwView::CheckReadonlyState()
+{
+ SfxDispatcher &rDis = GetDispatcher();
+ // To be able to recognize if it is already disabled!
+ SfxItemState eStateRO, eStateProtAll;
+ SfxPoolItemHolder aResult;
+ // Query the status from a slot which is only known to us.
+ // Otherwise the slot is known from other; like the BasicIde
+ eStateRO = rDis.QueryState(FN_INSERT_BOOKMARK, aResult);
+ eStateProtAll = rDis.QueryState(FN_EDIT_REGION, aResult);
+ bool bChgd = false;
+
+ if ( !m_pWrtShell->IsCursorReadonly() )
+ {
+ static sal_uInt16 aROIds[] =
+ {
+ SID_DELETE, FN_BACKSPACE, FN_SHIFT_BACKSPACE,
+ SID_UNDO,
+ SID_REDO, SID_REPEAT, SID_PASTE,
+ SID_PASTE_UNFORMATTED, FN_PASTE_NESTED_TABLE, FN_TABLE_PASTE_ROW_BEFORE,
+ FN_TABLE_PASTE_COL_BEFORE, SID_PASTE_SPECIAL, SID_SBA_BRW_INSERT,
+ SID_BACKGROUND_COLOR, FN_INSERT_BOOKMARK, SID_CHARMAP_CONTROL,
+ SID_CHARMAP, FN_INSERT_SOFT_HYPHEN,
+ FN_INSERT_HARDHYPHEN, FN_INSERT_HARD_SPACE, FN_INSERT_NNBSP,
+ FN_INSERT_BREAK, FN_INSERT_LINEBREAK, FN_INSERT_COLUMN_BREAK,
+ FN_INSERT_BREAK_DLG, FN_INSERT_CONTENT_CONTROL, FN_INSERT_CHECKBOX_CONTENT_CONTROL,
+ FN_INSERT_DROPDOWN_CONTENT_CONTROL, FN_INSERT_PICTURE_CONTENT_CONTROL,
+ FN_INSERT_DATE_CONTENT_CONTROL, FN_INSERT_PLAIN_TEXT_CONTENT_CONTROL,
+ FN_INSERT_COMBO_BOX_CONTENT_CONTROL,
+ FN_DELETE_SENT, FN_DELETE_BACK_SENT, FN_DELETE_WORD,
+ FN_DELETE_BACK_WORD, FN_DELETE_LINE, FN_DELETE_BACK_LINE,
+ FN_DELETE_PARA, FN_DELETE_BACK_PARA, FN_DELETE_WHOLE_LINE,
+ FN_CALCULATE, FN_FORMAT_RESET,
+ FN_POSTIT, FN_JAVAEDIT, SID_ATTR_PARA_ADJUST_LEFT,
+ SID_ATTR_PARA_ADJUST_RIGHT, SID_ATTR_PARA_ADJUST_CENTER,SID_ATTR_PARA_ADJUST_BLOCK,
+ SID_ATTR_PARA_LINESPACE_10, SID_ATTR_PARA_LINESPACE_15, SID_ATTR_PARA_LINESPACE_20,
+ SID_ATTR_CHAR_FONT, SID_ATTR_CHAR_FONTHEIGHT, SID_ATTR_CHAR_COLOR_BACKGROUND,
+ SID_ATTR_CHAR_BACK_COLOR,
+ SID_ATTR_CHAR_COLOR_BACKGROUND_EXT, SID_ATTR_CHAR_COLOR_EXT,
+ SID_ATTR_CHAR_COLOR, SID_ATTR_CHAR_WEIGHT, SID_ATTR_CHAR_POSTURE,
+ SID_ATTR_CHAR_OVERLINE,
+ SID_ATTR_CHAR_UNDERLINE, SID_ATTR_FLASH, SID_ATTR_CHAR_STRIKEOUT,
+ SID_ULINE_VAL_SINGLE, SID_ULINE_VAL_DOUBLE, SID_ULINE_VAL_DOTTED,
+ SID_ATTR_CHAR_CONTOUR, SID_ATTR_CHAR_SHADOWED,
+ SID_ATTR_CHAR_AUTOKERN, SID_ATTR_CHAR_ESCAPEMENT, FN_SET_SUPER_SCRIPT,
+ FN_SET_SUB_SCRIPT, SID_ATTR_CHAR_CASEMAP, SID_ATTR_CHAR_LANGUAGE,
+ SID_ATTR_CHAR_KERNING, SID_CHAR_DLG, SID_ATTR_CHAR_WORDLINEMODE,
+ FN_GROW_FONT_SIZE, FN_SHRINK_FONT_SIZE, FN_TXTATR_INET,
+ FN_FORMAT_DROPCAPS, SID_ATTR_PARA_ADJUST, SID_ATTR_PARA_LINESPACE,
+ SID_ATTR_PARA_SPLIT, SID_ATTR_PARA_KEEP, SID_ATTR_PARA_WIDOWS,
+ SID_ATTR_PARA_ORPHANS,
+ SID_ATTR_PARA_MODEL, SID_PARA_DLG,
+ FN_SELECT_PARA, SID_DEC_INDENT,
+ SID_INC_INDENT
+ };
+ static bool bFirst = true;
+ if ( bFirst )
+ {
+ qsort( static_cast<void*>(aROIds), SAL_N_ELEMENTS(aROIds), sizeof(sal_uInt16), lcl_CmpIds );
+ bFirst = false;
+ }
+ if ( SfxItemState::DISABLED == eStateRO )
+ {
+ rDis.SetSlotFilter( SfxSlotFilterState::ENABLED_READONLY, aROIds );
+ bChgd = true;
+ }
+ }
+ else if( m_pWrtShell->IsAllProtect() )
+ {
+ if ( SfxItemState::DISABLED == eStateProtAll )
+ {
+ static sal_uInt16 aAllProtIds[] = { SID_SAVEDOC, FN_EDIT_REGION };
+ static bool bAllProtFirst = true;
+ if ( bAllProtFirst )
+ {
+ qsort( static_cast<void*>(aAllProtIds), SAL_N_ELEMENTS(aAllProtIds), sizeof(sal_uInt16), lcl_CmpIds );
+ bAllProtFirst = false;
+ }
+ rDis.SetSlotFilter( SfxSlotFilterState::ENABLED_READONLY, aAllProtIds );
+ bChgd = true;
+ }
+ }
+ else if ( SfxItemState::DISABLED != eStateRO ||
+ SfxItemState::DISABLED != eStateProtAll )
+ {
+ bChgd = true;
+ rDis.SetSlotFilter();
+ }
+ if ( bChgd )
+ GetViewFrame().GetBindings().InvalidateAll(true);
+}
+
+void SwView::CheckReadonlySelection()
+{
+ SfxDisableFlags nDisableFlags = SfxDisableFlags::NONE;
+ SfxDispatcher &rDis = GetDispatcher();
+
+ if( m_pWrtShell->HasReadonlySel() &&
+ ( !m_pWrtShell->GetDrawView() ||
+ !m_pWrtShell->GetDrawView()->GetMarkedObjectList().GetMarkCount() ))
+ nDisableFlags |= SfxDisableFlags::SwOnProtectedCursor;
+
+ if( (SfxDisableFlags::SwOnProtectedCursor & nDisableFlags ) !=
+ (SfxDisableFlags::SwOnProtectedCursor & rDis.GetDisableFlags() ) )
+ {
+ // Additionally move at the Window the InputContext, so that
+ // in japanese / chinese versions the external input will be
+ // turned on or off. This but only if the correct shell is on
+ // the stack.
+ switch( m_pViewImpl->GetShellMode() )
+ {
+ case ShellMode::Text:
+ case ShellMode::ListText:
+ case ShellMode::TableText:
+ case ShellMode::TableListText:
+ {
+// Temporary solution!!! Should set the font of the current insertion point
+// at each cursor movement, so outside of this "if". But TH does not
+// evaluates the font at this time and the "purchase" appears to me
+// as too expensive.
+// Moreover, we don't have a font, but only attributes from which the
+// text formatting and the correct font will be build together.
+
+ InputContext aCntxt( GetEditWin().GetInputContext() );
+ aCntxt.SetOptions( SfxDisableFlags::SwOnProtectedCursor & nDisableFlags
+ ? (aCntxt.GetOptions() & ~
+ InputContextFlags( InputContextFlags::Text |
+ InputContextFlags::ExtText ))
+ : (aCntxt.GetOptions() |
+ ( InputContextFlags::Text |
+ InputContextFlags::ExtText )) );
+ GetEditWin().SetInputContext( aCntxt );
+ }
+ break;
+ default:
+ ;
+ }
+
+ }
+
+ if( nDisableFlags != rDis.GetDisableFlags() )
+ {
+ rDis.SetDisableFlags( nDisableFlags );
+ GetViewFrame().GetBindings().InvalidateAll( true );
+ }
+}
+
+SwView::SwView(SfxViewFrame& _rFrame, SfxViewShell* pOldSh)
+ : SfxViewShell(_rFrame, SWVIEWFLAGS),
+ m_aTimer( "sw::SwView m_aTimer" ),
+ m_nNewPage(USHRT_MAX),
+ m_nOldPageNum(0),
+ m_pNumRuleNodeFromDoc(nullptr),
+ m_pEditWin( VclPtr<SwEditWin>::Create( &_rFrame.GetWindow(), *this ) ),
+ m_pShell(nullptr),
+ m_pFormShell(nullptr),
+ m_pHScrollbar(nullptr),
+ m_pVScrollbar(nullptr),
+ m_pVRuler(VclPtr<SvxRuler>::Create(&GetViewFrame().GetWindow(), m_pEditWin,
+ SvxRulerSupportFlags::TABS | SvxRulerSupportFlags::PARAGRAPH_MARGINS_VERTICAL|
+ SvxRulerSupportFlags::BORDERS | SvxRulerSupportFlags::REDUCED_METRIC,
+ GetViewFrame().GetBindings(),
+ WB_VSCROLL | WB_EXTRAFIELD | WB_BORDER )),
+ m_pLastTableFormat(nullptr),
+ m_pLastFlyFormat(nullptr),
+ m_pFormatClipboard(new SwFormatClipboard()),
+ m_nSelectionType( SelectionType::All ),
+ m_nPageCnt(0),
+ m_nDrawSfxId( USHRT_MAX ),
+ m_nFormSfxId( USHRT_MAX ),
+ m_eFormObjKind(SdrObjKind::NONE),
+ m_nLastPasteDestination( static_cast<SotExchangeDest>(0xFFFF) ),
+ m_nLeftBorderDistance( 0 ),
+ m_nRightBorderDistance( 0 ),
+ m_eLastSearchCommand( static_cast<SvxSearchCmd>(0xFFFF) ),
+ m_bWheelScrollInProgress(false),
+ m_bCenterCursor(false),
+ m_bTopCursor(false),
+ m_bTabColFromDoc(false),
+ m_bTabRowFromDoc(false),
+ m_bSetTabColFromDoc(false),
+ m_bSetTabRowFromDoc(false),
+ m_bAttrChgNotified(false),
+ m_bAttrChgNotifiedWithRegistrations(false),
+ m_bVerbsActive(false),
+ m_bDrawRotate(false),
+ m_bDrawSelMode(true),
+ m_bShowAtResize(true),
+ m_bInOuterResizePixel(false),
+ m_bInInnerResizePixel(false),
+ m_bPasteState(false),
+ m_bPasteSpecialState(false),
+ m_bInMailMerge(false),
+ m_bInDtor(false),
+ m_bOldShellWasPagePreview(false),
+ m_bIsPreviewDoubleClick(false),
+ m_bMakeSelectionVisible(false),
+ m_bForceChangesToolbar(true),
+ m_nLOKPageUpDownOffset(0),
+ m_aBringToAttentionBlinkTimer("SwView m_aBringToAttentionBlinkTimer"),
+ m_nBringToAttentionBlinkTimeOutsRemaining(0)
+{
+ static bool bRequestDoubleBuffering = getenv("VCL_DOUBLEBUFFERING_ENABLE");
+ if (bRequestDoubleBuffering)
+ m_pEditWin->RequestDoubleBuffering(true);
+
+ // According to discussion with MBA and further
+ // investigations, no old SfxViewShell will be set as parameter <pOldSh>,
+ // if function "New Window" is performed to open an additional view beside
+ // an already existing one.
+ // If the view is switch from one to another, the 'old' view is given by
+ // parameter <pOldSh>.
+
+ bDocSzUpdated = true;
+
+ static bool bFuzzing = utl::ConfigManager::IsFuzzing();
+
+ if (!bFuzzing)
+ {
+ CreateScrollbar( true );
+ CreateScrollbar( false );
+ }
+
+ m_pViewImpl.reset(new SwView_Impl(this));
+ SetName("View");
+ SetWindow( m_pEditWin );
+
+ m_aTimer.SetTimeout( 120 );
+
+ SwDocShell& rDocSh = dynamic_cast<SwDocShell&>(*_rFrame.GetObjectShell());
+ bool bOldModifyFlag = rDocSh.IsEnableSetModified();
+ if (bOldModifyFlag)
+ rDocSh.EnableSetModified( false );
+ // HACK: SwDocShell has some cached font info, VCL informs about font updates,
+ // but loading of docs with embedded fonts happens after SwDocShell is created
+ // but before SwEditWin (which handles the VCL event) is created. So update
+ // manually.
+ if (rDocSh.GetDoc()->getIDocumentSettingAccess().get( DocumentSettingId::EMBED_FONTS ))
+ rDocSh.UpdateFontList();
+ bool bWebDShell = dynamic_cast<const SwWebDocShell*>(&rDocSh) != nullptr;
+
+ const SwMasterUsrPref *pUsrPref = SW_MOD()->GetUsrPref(bWebDShell);
+ SwViewOption aUsrPref( *pUsrPref);
+
+ //! get lingu options without loading lingu DLL
+ SvtLinguOptions aLinguOpt;
+ SvtLinguConfig().GetOptions( aLinguOpt );
+ aUsrPref.SetOnlineSpell( aLinguOpt.bIsSpellAuto );
+
+ bool bOldShellWasSrcView = false;
+
+ // determine if there is an existing view for
+ // document
+ SfxViewShell* pExistingSh = nullptr;
+ if ( pOldSh )
+ {
+ pExistingSh = pOldSh;
+ // determine type of existing view
+ if (SwPagePreview* pPagePreview = dynamic_cast<SwPagePreview *>(pExistingSh))
+ {
+ m_sSwViewData = pPagePreview->GetPrevSwViewData();
+ m_sNewCursorPos = pPagePreview->GetNewCursorPos();
+ m_nNewPage = pPagePreview->GetNewPage();
+ m_bOldShellWasPagePreview = true;
+ m_bIsPreviewDoubleClick = !m_sNewCursorPos.isEmpty() || m_nNewPage != USHRT_MAX;
+ }
+ else if (dynamic_cast<const SwSrcView *>(pExistingSh) != nullptr)
+ bOldShellWasSrcView = true;
+ }
+
+ SAL_INFO( "sw.ui", "before create WrtShell" );
+ if (SwView *pView = dynamic_cast<SwView*>(pExistingSh))
+ {
+ m_pWrtShell.reset(new SwWrtShell(*pView->m_pWrtShell, m_pEditWin, *this));
+ }
+ else if (SwWrtShell *pWrtShell = dynamic_cast<SwWrtShell*>(rDocSh.GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell()))
+ {
+ m_pWrtShell.reset(new SwWrtShell(*pWrtShell, m_pEditWin, *this));
+ }
+ else
+ {
+ SwDoc& rDoc = *rDocSh.GetDoc();
+
+ if( !bOldShellWasSrcView && bWebDShell && !m_bOldShellWasPagePreview )
+ aUsrPref.setBrowseMode( true );
+ else
+ aUsrPref.setBrowseMode( rDoc.getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE) );
+
+ //For the BrowseMode we do not assume a factor.
+ if( aUsrPref.getBrowseMode() && aUsrPref.GetZoomType() != SvxZoomType::PERCENT )
+ {
+ aUsrPref.SetZoomType( SvxZoomType::PERCENT );
+ aUsrPref.SetZoom( 100 );
+ }
+ if (rDocSh.IsPreview())
+ {
+ aUsrPref.SetZoomType( SvxZoomType::WHOLEPAGE );
+ aUsrPref.SetViewLayoutBookMode( false );
+ aUsrPref.SetViewLayoutColumns( 1 );
+ }
+ m_pWrtShell.reset(new SwWrtShell(rDoc, m_pEditWin, *this, &aUsrPref));
+ // creating an SwView from a SwPagePreview needs to
+ // add the SwViewShell to the ring of the other SwViewShell(s)
+ if(m_bOldShellWasPagePreview)
+ {
+ SwViewShell& rPreviewViewShell = *static_cast<SwPagePreview*>(pExistingSh)->GetViewShell();
+ m_pWrtShell->MoveTo(&rPreviewViewShell);
+ // to update the field command et.al. if necessary
+ const SwViewOption* pPreviewOpt = rPreviewViewShell.GetViewOptions();
+ if( pPreviewOpt->IsFieldName() != aUsrPref.IsFieldName() ||
+ pPreviewOpt->IsShowHiddenField() != aUsrPref.IsShowHiddenField() ||
+ pPreviewOpt->IsShowHiddenPara() != aUsrPref.IsShowHiddenPara() ||
+ pPreviewOpt->IsShowHiddenChar() != aUsrPref.IsShowHiddenChar() )
+ rPreviewViewShell.ApplyViewOptions(aUsrPref);
+ // reset design mode at draw view for form
+ // shell, if needed.
+ if ( static_cast<SwPagePreview*>(pExistingSh)->ResetFormDesignMode() &&
+ m_pWrtShell->HasDrawView() )
+ {
+ SdrView* pDrawView = m_pWrtShell->GetDrawView();
+ pDrawView->SetDesignMode( static_cast<SwPagePreview*>(pExistingSh)->FormDesignModeToReset() );
+ }
+ }
+ }
+ SAL_INFO( "sw.ui", "after create WrtShell" );
+ m_pHRuler = VclPtr<SwCommentRuler>::Create(m_pWrtShell.get(), &GetViewFrame().GetWindow(), m_pEditWin,
+ SvxRulerSupportFlags::TABS |
+ SvxRulerSupportFlags::PARAGRAPH_MARGINS |
+ SvxRulerSupportFlags::BORDERS |
+ SvxRulerSupportFlags::NEGATIVE_MARGINS|
+ SvxRulerSupportFlags::REDUCED_METRIC,
+ GetViewFrame().GetBindings(),
+ WB_STDRULER | WB_EXTRAFIELD | WB_BORDER);
+
+ // assure that modified state of document
+ // isn't reset, if document is already modified.
+ const bool bIsDocModified = m_pWrtShell->GetDoc()->getIDocumentState().IsModified();
+
+ // Thus among other things, the HRuler is not displayed in the read-only case.
+ aUsrPref.SetReadonly( m_pWrtShell->GetViewOptions()->IsReadonly() );
+
+ // no margin for OLE!
+ Size aBrwsBorder;
+ if( SfxObjectCreateMode::EMBEDDED != rDocSh.GetCreateMode() )
+ aBrwsBorder = GetMargin();
+
+ m_pWrtShell->SetBrowseBorder( aBrwsBorder );
+
+ // In CTOR no shell changes may take place, which must be temporarily stored
+ // with the timer. Otherwise, the SFX removes them from the stack!
+ bool bOld = g_bNoInterrupt;
+ g_bNoInterrupt = true;
+
+ m_pHRuler->SetActive();
+ m_pVRuler->SetActive();
+
+ SfxViewFrame& rViewFrame = GetViewFrame();
+
+ StartListening(rViewFrame, DuplicateHandling::Prevent);
+ StartListening(rDocSh, DuplicateHandling::Prevent);
+
+ // Set Zoom-factor from HRuler
+ Fraction aZoomFract( aUsrPref.GetZoom(), 100 );
+ m_pHRuler->SetZoom( aZoomFract );
+ m_pVRuler->SetZoom( aZoomFract );
+ m_pHRuler->SetDoubleClickHdl(LINK( this, SwView, ExecRulerClick ));
+ FieldUnit eMetric = pUsrPref->GetHScrollMetric();
+ m_pHRuler->SetUnit( eMetric );
+
+ eMetric = pUsrPref->GetVScrollMetric();
+ m_pVRuler->SetUnit( eMetric );
+
+ m_pHRuler->SetCharWidth( 371 ); // default character width
+ m_pVRuler->SetLineHeight( 551 ); // default line height
+
+ // Set DocShell
+ m_xGlueDocShell.reset(new SwViewGlueDocShell(*this, rDocSh));
+ m_pPostItMgr.reset(new SwPostItMgr(this));
+
+ // Check and process the DocSize. Via the handler, the shell could not
+ // be found, because the shell is not known in the SFX management
+ // within the CTOR phase.
+ DocSzChgd( m_pWrtShell->GetDocSize() );
+
+ // Set AttrChangedNotify link
+ m_pWrtShell->SetChgLnk(LINK(this, SwView, AttrChangedNotify));
+
+ if (rDocSh.GetCreateMode() == SfxObjectCreateMode::EMBEDDED &&
+ !rDocSh.GetVisArea(ASPECT_CONTENT).IsEmpty())
+ SetVisArea(rDocSh.GetVisArea(ASPECT_CONTENT),false);
+
+ SAL_WARN_IF(
+ officecfg::Office::Common::Undo::Steps::get() <= 0,
+ "sw.ui", "/org.openoffice.Office.Common/Undo/Steps <= 0");
+ if (!bFuzzing && 0 < officecfg::Office::Common::Undo::Steps::get())
+ {
+ m_pWrtShell->DoUndo();
+ }
+
+ const bool bBrowse = m_pWrtShell->GetViewOptions()->getBrowseMode();
+ // Disable "multiple window"
+ SetNewWindowAllowed(!bBrowse);
+ // End of disabled multiple window
+
+ m_bVScrollbarEnabled = aUsrPref.IsViewVScrollBar();
+ m_bHScrollbarEnabled = aUsrPref.IsViewHScrollBar();
+ if (m_pHScrollbar)
+ m_pHScrollbar->SetAuto(bBrowse);
+ if( aUsrPref.IsViewHRuler() )
+ CreateTab();
+ if( aUsrPref.IsViewVRuler() )
+ CreateVRuler();
+
+ m_pWrtShell->SetUIOptions( aUsrPref );
+ m_pWrtShell->SetReadOnlyAvailable( aUsrPref.IsCursorInProtectedArea() );
+#if !ENABLE_WASM_STRIP_ACCESSIBILITY
+ m_pWrtShell->ApplyAccessibilityOptions();
+#endif
+
+ if( m_pWrtShell->GetDoc()->getIDocumentState().IsUpdateExpField() )
+ {
+ if (m_pWrtShell->GetDoc()->GetDocumentFieldsManager().containsUpdatableFields())
+ {
+ CurrShell aCurr(m_pWrtShell.get());
+ m_pWrtShell->StartAction();
+ m_pWrtShell->CalcLayout();
+ m_pWrtShell->GetDoc()->getIDocumentFieldsAccess().UpdateFields(false);
+ m_pWrtShell->EndAction();
+ }
+ m_pWrtShell->GetDoc()->getIDocumentState().SetUpdateExpFieldStat( false );
+ }
+
+ // Update all tables if necessary:
+ if( m_pWrtShell->GetDoc()->IsUpdateTOX() )
+ {
+ SfxRequest aSfxRequest( FN_UPDATE_TOX, SfxCallMode::SLOT, GetPool() );
+ Execute( aSfxRequest );
+ m_pWrtShell->GetDoc()->SetUpdateTOX( false ); // reset again
+ m_pWrtShell->SttEndDoc(true);
+ }
+
+ // No ResetModified, if there is already a view to this doc.
+ SfxViewFrame& rVFrame = GetViewFrame();
+ SfxViewFrame* pFirst = SfxViewFrame::GetFirst(&rDocSh);
+ // Currently(360) the view is registered firstly after the CTOR,
+ // the following expression is also working if this changes.
+ // If the modification cannot be canceled by undo, then do NOT set
+ // the modify back.
+ // no reset of modified state, if document
+ // was already modified.
+ if (!m_pWrtShell->GetDoc()->GetIDocumentUndoRedo().IsUndoNoResetModified() &&
+ ( !pFirst || pFirst == &rVFrame ) &&
+ !bIsDocModified )
+ {
+ m_pWrtShell->ResetModified();
+ }
+
+ g_bNoInterrupt = bOld;
+
+ // If a new GlobalDoc will be created, the navigator will also be generated.
+ if( dynamic_cast<const SwGlobalDocShell*>(&rDocSh) != nullptr &&
+ !rVFrame.GetChildWindow( SID_NAVIGATOR ))
+ {
+ SfxBoolItem aNavi(SID_NAVIGATOR, true);
+ GetDispatcher().ExecuteList(SID_NAVIGATOR, SfxCallMode::ASYNCHRON, { &aNavi });
+ }
+
+ uno::Reference< frame::XFrame > xFrame = rVFrame.GetFrame().GetFrameInterface();
+
+ uno::Reference< frame::XFrame > xBeamerFrame = xFrame->findFrame(
+ "_beamer", frame::FrameSearchFlag::CHILDREN);
+ if(xBeamerFrame.is())
+ {
+ SwDBData aData = m_pWrtShell->GetDBData();
+ SwModule::ShowDBObj( *this, aData );
+ }
+
+ // has anybody calls the attrchanged handler in the constructor?
+ if( m_bAttrChgNotifiedWithRegistrations )
+ {
+ GetViewFrame().GetBindings().LEAVEREGISTRATIONS();
+ if( m_aTimer.IsActive() )
+ m_aTimer.Stop();
+ }
+
+ m_aTimer.SetInvokeHandler(LINK(this, SwView, TimeoutHdl));
+ m_bAttrChgNotified = m_bAttrChgNotifiedWithRegistrations = false;
+ if (bOldModifyFlag)
+ rDocSh.EnableSetModified();
+ InvalidateBorder();
+
+ if (!bFuzzing)
+ {
+ if (!m_pHScrollbar->IsScrollbarVisible(true))
+ ShowHScrollbar( false );
+ if (!m_pVScrollbar->IsScrollbarVisible(true))
+ ShowVScrollbar( false );
+ }
+
+ if (m_pWrtShell->GetViewOptions()->IsShowOutlineContentVisibilityButton())
+ m_pWrtShell->InvalidateOutlineContentVisibility();
+
+ if (!bFuzzing)
+ GetViewFrame().GetWindow().AddChildEventListener(LINK(this, SwView, WindowChildEventListener));
+
+ m_aBringToAttentionBlinkTimer.SetInvokeHandler(
+ LINK(this, SwView, BringToAttentionBlinkTimerHdl));
+ m_aBringToAttentionBlinkTimer.SetTimeout(350);
+
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ SwXTextDocument* pModel = comphelper::getFromUnoTunnel<SwXTextDocument>(GetCurrentDocument());
+ SfxLokHelper::notifyViewRenderState(this, pModel);
+ }
+}
+
+SwViewGlueDocShell::SwViewGlueDocShell(SwView& rView, SwDocShell& rDocSh)
+ : m_rView(rView)
+{
+ // Set DocShell
+ rDocSh.SetView(&m_rView);
+ SW_MOD()->SetView(&m_rView);
+}
+
+SwViewGlueDocShell::~SwViewGlueDocShell()
+{
+ SwDocShell* pDocSh = m_rView.GetDocShell();
+ if (pDocSh && pDocSh->GetView() == &m_rView)
+ pDocSh->SetView(nullptr);
+ if (SW_MOD()->GetView() == &m_rView)
+ SW_MOD()->SetView(nullptr);
+}
+
+SwView::~SwView()
+{
+ // Notify other LOK views that we are going away.
+ SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_VIEW_CURSOR_VISIBLE, "visible", "false"_ostr);
+ SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", ""_ostr);
+ SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_GRAPHIC_VIEW_SELECTION, "selection", "EMPTY"_ostr);
+
+ // Need to remove activated field's button before disposing EditWin.
+ GetWrtShell().getIDocumentMarkAccess()->ClearFieldActivation();
+
+ GetViewFrame().GetWindow().RemoveChildEventListener( LINK( this, SwView, WindowChildEventListener ) );
+ m_pPostItMgr.reset();
+
+ m_bInDtor = true;
+ m_pEditWin->Hide(); // prevent problems with painting
+
+ // Set pointer in SwDocShell to the view again
+ m_xGlueDocShell.reset();
+
+ if( m_aTimer.IsActive() && m_bAttrChgNotifiedWithRegistrations )
+ GetViewFrame().GetBindings().LEAVEREGISTRATIONS();
+
+ // the last view must end the text edit
+ SdrView *pSdrView = m_pWrtShell->GetDrawView();
+ if( pSdrView && pSdrView->IsTextEdit() )
+ pSdrView->SdrEndTextEdit( true );
+ else if (pSdrView)
+ {
+ pSdrView->DisposeUndoManager();
+ }
+
+ SetWindow( nullptr );
+
+ m_pViewImpl->Invalidate();
+ EndListening(GetViewFrame());
+ EndListening(*GetDocShell());
+
+ // tdf#155410 speedup shutdown, prevent unnecessary broadcasting during teardown of draw model
+ auto pDrawModel = GetWrtShell().getIDocumentDrawModelAccess().GetDrawModel();
+ const bool bWasLocked = pDrawModel->isLocked();
+ pDrawModel->setLock(true);
+ m_pWrtShell.reset(); // reset here so that it is not accessible by the following dtors.
+ pDrawModel->setLock(bWasLocked);
+
+ m_pHScrollbar.disposeAndClear();
+ m_pVScrollbar.disposeAndClear();
+ m_pHRuler.disposeAndClear();
+ m_pVRuler.disposeAndClear();
+ m_pGlosHdl.reset();
+ m_pViewImpl.reset();
+
+ // If this was enabled in the ctor for the frame, then disable it here.
+ static bool bRequestDoubleBuffering = getenv("VCL_DOUBLEBUFFERING_ENABLE");
+ if (bRequestDoubleBuffering)
+ m_pEditWin->RequestDoubleBuffering(false);
+ m_pEditWin.disposeAndClear();
+
+ m_pFormatClipboard.reset();
+}
+
+void SwView::SetDying()
+{
+ m_bDying = true;
+}
+
+void SwView::afterCallbackRegistered()
+{
+ if (!comphelper::LibreOfficeKit::isActive())
+ return;
+
+ // common tasks
+ SfxViewShell::afterCallbackRegistered();
+
+ auto* pDocShell = GetDocShell();
+ if (pDocShell)
+ {
+ svx::ThemeColorPaletteManager aManager(pDocShell->GetThemeColors());
+ libreOfficeKitViewCallback(LOK_CALLBACK_COLOR_PALETTES, aManager.generateJSON());
+ }
+}
+
+SwDocShell* SwView::GetDocShell()
+{
+ SfxObjectShell* pDocShell = GetViewFrame().GetObjectShell();
+ return dynamic_cast<SwDocShell*>( pDocShell );
+}
+
+// Remember CursorPos
+
+void SwView::WriteUserData( OUString &rUserData, bool bBrowse )
+{
+ // The browse flag will be passed from Sfx when documents are browsed
+ // (not to be confused with the BrowseMode).
+ // Then that stored data are not persistent!
+
+ const SwRect& rRect = m_pWrtShell->GetCharRect();
+ const tools::Rectangle& rVis = GetVisArea();
+
+ rUserData = OUString::number( rRect.Left() );
+ rUserData += ";";
+ rUserData += OUString::number( rRect.Top() );
+ rUserData += ";";
+ rUserData += OUString::number( m_pWrtShell->GetViewOptions()->GetZoom() );
+ rUserData += ";";
+ rUserData += OUString::number( rVis.Left() );
+ rUserData += ";";
+ rUserData += OUString::number( rVis.Top() );
+ rUserData += ";";
+ rUserData += OUString::number( bBrowse ? SAL_MIN_INT32 : rVis.Right());
+ rUserData += ";";
+ rUserData += OUString::number( bBrowse ? SAL_MIN_INT32 : rVis.Bottom());
+ rUserData += ";";
+ rUserData += OUString::number(
+ static_cast<sal_uInt16>(m_pWrtShell->GetViewOptions()->GetZoomType()));//eZoom;
+ rUserData += ";";
+ rUserData += FrameTypeFlags::NONE == m_pWrtShell->GetSelFrameType() ? std::u16string_view(u"0") : std::u16string_view(u"1");
+}
+
+// Set CursorPos
+
+static bool lcl_IsOwnDocument( SwView& rView )
+{
+ if (::officecfg::Office::Common::Load::ViewPositionForAnyUser::get())
+ {
+ return true;
+ }
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ rView.GetDocShell()->GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps
+ = xDPS->getDocumentProperties();
+ OUString Created = xDocProps->getAuthor();
+ OUString Changed = xDocProps->getModifiedBy();
+ OUString FullName = SW_MOD()->GetUserOptions().GetFullName();
+ return !FullName.isEmpty()
+ && (Changed == FullName || (Changed.isEmpty() && Created == FullName));
+}
+
+void SwView::ReadUserData( const OUString &rUserData, bool bBrowse )
+{
+ if ( !(rUserData.indexOf(';')>=0 && // more than one token
+ // For document without layout only in the onlinelayout or
+ // while forward/backward
+ (!m_pWrtShell->IsNewLayout() || m_pWrtShell->GetViewOptions()->getBrowseMode() || bBrowse)) )
+ return;
+
+ bool bIsOwnDocument = lcl_IsOwnDocument( *this );
+
+ CurrShell aCurr(m_pWrtShell.get());
+
+ sal_Int32 nPos = 0;
+
+ // No it is *not* a good idea to call GetToken within Point constr. immediately,
+ // because which parameter is evaluated first?
+ tools::Long nX = o3tl::toInt32(o3tl::getToken(rUserData, 0, ';', nPos )),
+ nY = o3tl::toInt32(o3tl::getToken(rUserData, 0, ';', nPos ));
+ Point aCursorPos( nX, nY );
+
+ sal_uInt16 nZoomFactor =
+ static_cast< sal_uInt16 >( o3tl::toInt32(o3tl::getToken(rUserData, 0, ';', nPos )) );
+
+ tools::Long nLeft = o3tl::toInt32(o3tl::getToken(rUserData, 0, ';', nPos )),
+ nTop = o3tl::toInt32(o3tl::getToken(rUserData, 0, ';', nPos )),
+ nRight = o3tl::toInt32(o3tl::getToken(rUserData, 0, ';', nPos )),
+ nBottom= o3tl::toInt32(o3tl::getToken(rUserData, 0, ';', nPos ));
+
+ const tools::Long nAdd = m_pWrtShell->GetViewOptions()->getBrowseMode() ? DOCUMENTBORDER : DOCUMENTBORDER*2;
+ if ( nBottom > (m_pWrtShell->GetDocSize().Height()+nAdd) )
+ return;
+
+ m_pWrtShell->EnableSmooth( false );
+
+ const tools::Rectangle aVis( nLeft, nTop, nRight, nBottom );
+
+ sal_Int32 nOff = 0;
+ SvxZoomType eZoom;
+ if( !m_pWrtShell->GetViewOptions()->getBrowseMode() )
+ eZoom = static_cast<SvxZoomType>(o3tl::narrowing<sal_uInt16>(o3tl::toInt32(o3tl::getToken(rUserData, nOff, ';', nPos ))));
+ else
+ {
+ eZoom = SvxZoomType::PERCENT;
+ ++nOff;
+ }
+
+ bool bSelectObj = (0 != o3tl::toInt32(o3tl::getToken(rUserData, nOff, ';', nPos )))
+ && m_pWrtShell->IsObjSelectable( aCursorPos );
+
+ // restore editing position
+ m_pViewImpl->SetRestorePosition(aCursorPos, bSelectObj);
+ // set flag value to avoid macro execution.
+ bool bSavedFlagValue = m_pWrtShell->IsMacroExecAllowed();
+ m_pWrtShell->SetMacroExecAllowed( false );
+// os: changed: The user data has to be read if the view is switched back from page preview
+// go to the last editing position when opening own files
+ if(m_bOldShellWasPagePreview || bIsOwnDocument)
+ {
+ m_pWrtShell->SwCursorShell::SetCursor( aCursorPos, !bSelectObj );
+ if( bSelectObj )
+ {
+ m_pWrtShell->SelectObj( aCursorPos );
+ m_pWrtShell->EnterSelFrameMode( &aCursorPos );
+ }
+ }
+
+ // reset flag value
+ m_pWrtShell->SetMacroExecAllowed( bSavedFlagValue );
+
+ // set visible area before applying
+ // information from print preview. Otherwise, the applied information
+ // is lost.
+// os: changed: The user data has to be read if the view is switched back from page preview
+// go to the last editing position when opening own files
+ if(m_bOldShellWasPagePreview || bIsOwnDocument )
+ {
+ if ( bBrowse )
+ SetVisArea( aVis.TopLeft() );
+ else
+ SetVisArea( aVis );
+ }
+
+ //apply information from print preview - if available
+ if( !m_sNewCursorPos.isEmpty() )
+ {
+ sal_Int32 nIdx{ 0 };
+ const tools::Long nXTmp = o3tl::toInt32(o3tl::getToken(m_sNewCursorPos, 0, ';', nIdx ));
+ const tools::Long nYTmp = o3tl::toInt32(o3tl::getToken(m_sNewCursorPos, 0, ';', nIdx ));
+ Point aCursorPos2( nXTmp, nYTmp );
+ bSelectObj = m_pWrtShell->IsObjSelectable( aCursorPos2 );
+
+ m_pWrtShell->SwCursorShell::SetCursor( aCursorPos2 );
+ if( bSelectObj )
+ {
+ m_pWrtShell->SelectObj( aCursorPos2 );
+ m_pWrtShell->EnterSelFrameMode( &aCursorPos2 );
+ }
+ m_pWrtShell->MakeSelVisible();
+ m_sNewCursorPos.clear();
+ }
+ else if(USHRT_MAX != m_nNewPage)
+ {
+ m_pWrtShell->GotoPage(m_nNewPage, true);
+ m_nNewPage = USHRT_MAX;
+ }
+
+ SelectShell();
+
+ m_pWrtShell->StartAction();
+ const SwViewOption* pVOpt = m_pWrtShell->GetViewOptions();
+ if( pVOpt->GetZoom() != nZoomFactor || pVOpt->GetZoomType() != eZoom )
+ SetZoom( eZoom, nZoomFactor);
+
+ m_pWrtShell->LockView( true );
+ m_pWrtShell->EndAction();
+ m_pWrtShell->LockView( false );
+ m_pWrtShell->EnableSmooth( true );
+}
+
+void SwView::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue >& rSequence )
+{
+ if(GetDocShell()->IsPreview()||m_bIsPreviewDoubleClick)
+ return;
+ bool bIsOwnDocument = lcl_IsOwnDocument( *this );
+
+ CurrShell aCurr(m_pWrtShell.get());
+ const SwRect& rRect = m_pWrtShell->GetCharRect();
+ const tools::Rectangle &rVis = GetVisArea();
+ const SwViewOption* pVOpt = m_pWrtShell->GetViewOptions();
+
+ sal_Int64 nX = rRect.Left(), nY = rRect.Top(), nLeft = rVis.Left(), nTop = rVis.Top();
+ sal_Int16 nZoomType = static_cast< sal_Int16 >(pVOpt->GetZoomType());
+ sal_Int16 nZoomFactor = static_cast < sal_Int16 > (pVOpt->GetZoom());
+ bool bViewLayoutBookMode = pVOpt->IsViewLayoutBookMode();
+ sal_Int16 nViewLayoutColumns = pVOpt->GetViewLayoutColumns();
+
+ bool bSelectedFrame = ( m_pWrtShell->GetSelFrameType() != FrameTypeFlags::NONE ),
+ bGotVisibleLeft = false,
+ bGotVisibleTop = false,
+ bGotZoomType = false,
+ bGotZoomFactor = false, bGotIsSelectedFrame = false,
+ bGotViewLayoutColumns = false, bGotViewLayoutBookMode = false,
+ bBrowseMode = false, bGotBrowseMode = false;
+ bool bKeepRatio = pVOpt->IsKeepRatio();
+ bool bGotKeepRatio = false;
+
+ for (const beans::PropertyValue& rValue : rSequence)
+ {
+ if ( rValue.Name == "ViewLeft" )
+ {
+ rValue.Value >>= nX;
+ nX = o3tl::toTwips(nX, o3tl::Length::mm100);
+ }
+ else if ( rValue.Name == "ViewTop" )
+ {
+ rValue.Value >>= nY;
+ nY = o3tl::toTwips(nY, o3tl::Length::mm100);
+ }
+ else if ( rValue.Name == "VisibleLeft" )
+ {
+ rValue.Value >>= nLeft;
+ nLeft = o3tl::toTwips(nLeft, o3tl::Length::mm100);
+ bGotVisibleLeft = true;
+ }
+ else if ( rValue.Name == "VisibleTop" )
+ {
+ rValue.Value >>= nTop;
+ nTop = o3tl::toTwips(nTop, o3tl::Length::mm100);
+ bGotVisibleTop = true;
+ }
+ else if ( rValue.Name == "ZoomType" )
+ {
+ rValue.Value >>= nZoomType;
+ bGotZoomType = true;
+ }
+ else if ( rValue.Name == "ZoomFactor" )
+ {
+ rValue.Value >>= nZoomFactor;
+ bGotZoomFactor = true;
+ }
+ else if ( rValue.Name == "ViewLayoutColumns" )
+ {
+ rValue.Value >>= nViewLayoutColumns;
+ bGotViewLayoutColumns = true;
+ }
+ else if ( rValue.Name == "ViewLayoutBookMode" )
+ {
+ bViewLayoutBookMode = *o3tl::doAccess<bool>(rValue.Value);
+ bGotViewLayoutBookMode = true;
+ }
+ else if ( rValue.Name == "IsSelectedFrame" )
+ {
+ rValue.Value >>= bSelectedFrame;
+ bGotIsSelectedFrame = true;
+ }
+ else if (rValue.Name == "ShowOnlineLayout")
+ {
+ rValue.Value >>= bBrowseMode;
+ bGotBrowseMode = true;
+ }
+ else if (rValue.Name == "KeepRatio")
+ {
+ rValue.Value >>= bKeepRatio;
+ bGotKeepRatio = true;
+ }
+ // Fallback to common SdrModel processing
+ else
+ GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel()->ReadUserDataSequenceValue(&rValue);
+ }
+ if (bGotBrowseMode)
+ {
+ // delegate further
+ GetViewImpl()->GetUNOObject_Impl()->getViewSettings()->setPropertyValue("ShowOnlineLayout", uno::Any(bBrowseMode));
+ }
+
+ SelectShell();
+
+ Point aCursorPos( nX, nY );
+
+ m_pWrtShell->EnableSmooth( false );
+
+ SvxZoomType eZoom;
+ if ( !m_pWrtShell->GetViewOptions()->getBrowseMode() )
+ eZoom = static_cast < SvxZoomType > ( nZoomType );
+ else
+ {
+ eZoom = SvxZoomType::PERCENT;
+ }
+ if (bGotIsSelectedFrame)
+ {
+ bool bSelectObj = bSelectedFrame && m_pWrtShell->IsObjSelectable( aCursorPos );
+
+ // set flag value to avoid macro execution.
+ bool bSavedFlagValue = m_pWrtShell->IsMacroExecAllowed();
+ m_pWrtShell->SetMacroExecAllowed( false );
+// os: changed: The user data has to be read if the view is switched back from page preview
+// go to the last editing position when opening own files
+ m_pViewImpl->SetRestorePosition(aCursorPos, bSelectObj);
+ if(m_bOldShellWasPagePreview|| bIsOwnDocument)
+ {
+ m_pWrtShell->SwCursorShell::SetCursor( aCursorPos, !bSelectObj );
+
+ // Update the shell to toggle Header/Footer edit if needed
+ bool bInHeader = true;
+ if ( m_pWrtShell->IsInHeaderFooter( &bInHeader ) )
+ {
+ if ( !bInHeader )
+ {
+ m_pWrtShell->SetShowHeaderFooterSeparator( FrameControlType::Footer, true );
+ m_pWrtShell->SetShowHeaderFooterSeparator( FrameControlType::Header, false );
+ }
+ else
+ {
+ m_pWrtShell->SetShowHeaderFooterSeparator( FrameControlType::Header, true );
+ m_pWrtShell->SetShowHeaderFooterSeparator( FrameControlType::Footer, false );
+ }
+
+ // Force repaint
+ m_pWrtShell->GetWin()->Invalidate();
+ }
+ if ( m_pWrtShell->IsInHeaderFooter() != m_pWrtShell->IsHeaderFooterEdit() )
+ m_pWrtShell->ToggleHeaderFooterEdit();
+
+ if( bSelectObj )
+ {
+ m_pWrtShell->SelectObj( aCursorPos );
+ m_pWrtShell->EnterSelFrameMode( &aCursorPos );
+ }
+ }
+
+ // reset flag value
+ m_pWrtShell->SetMacroExecAllowed( bSavedFlagValue );
+ }
+
+ if (bGotKeepRatio && bKeepRatio != pVOpt->IsKeepRatio())
+ {
+ // Got a custom value, then it makes sense to trigger notifications.
+ SwViewOption aUsrPref(*pVOpt);
+ aUsrPref.SetKeepRatio(bKeepRatio);
+ SW_MOD()->ApplyUsrPref(aUsrPref, this);
+ }
+
+ // Set ViewLayoutSettings
+ const bool bSetViewLayoutSettings = bGotViewLayoutColumns && bGotViewLayoutBookMode &&
+ ( pVOpt->GetViewLayoutColumns() != nViewLayoutColumns || pVOpt->IsViewLayoutBookMode() != bViewLayoutBookMode );
+
+ const bool bSetViewSettings = bGotZoomType && bGotZoomFactor &&
+ ( pVOpt->GetZoom() != nZoomFactor || pVOpt->GetZoomType() != eZoom );
+
+ // In case we have a 'fixed' view layout of 2 or more columns,
+ // we have to apply the view options *before* starting the action.
+ // Otherwise the SetZoom function cannot work correctly, because
+ // the view layout hasn't been calculated.
+ const bool bZoomNeedsViewLayout = bSetViewLayoutSettings &&
+ 1 < nViewLayoutColumns &&
+ bSetViewSettings &&
+ eZoom != SvxZoomType::PERCENT;
+
+ if ( !bZoomNeedsViewLayout )
+ m_pWrtShell->StartAction();
+
+ if ( bSetViewLayoutSettings )
+ SetViewLayout( nViewLayoutColumns, bViewLayoutBookMode, true );
+
+ if ( bZoomNeedsViewLayout )
+ m_pWrtShell->StartAction();
+
+ if ( bSetViewSettings )
+ SetZoom( eZoom, nZoomFactor, true );
+
+// os: changed: The user data has to be read if the view is switched back from page preview
+// go to the last editing position when opening own files
+ if(m_bOldShellWasPagePreview||bIsOwnDocument)
+ {
+ if ( bGotVisibleLeft && bGotVisibleTop )
+ {
+ Point aTopLeft(nLeft, nTop);
+ // make sure the document is still centered
+ const SwTwips lBorder = IsDocumentBorder() ? DOCUMENTBORDER : 2 * DOCUMENTBORDER;
+ SwTwips nEditWidth = GetEditWin().GetOutDev()->GetOutputSize().Width();
+ if(nEditWidth > (m_aDocSz.Width() + lBorder ))
+ aTopLeft.setX( ( m_aDocSz.Width() + lBorder - nEditWidth ) / 2 );
+ else
+ {
+ //check if the values are possible
+ tools::Long nXMax = m_pHScrollbar->GetRangeMax() - m_pHScrollbar->GetVisibleSize();
+ if( aTopLeft.X() > nXMax )
+ aTopLeft.setX( nXMax < 0 ? 0 : nXMax );
+ }
+ SetVisArea( aTopLeft );
+ }
+ }
+
+ m_pWrtShell->LockView( true );
+ m_pWrtShell->EndAction();
+ m_pWrtShell->LockView( false );
+ m_pWrtShell->EnableSmooth( true );
+
+}
+
+void SwView::WriteUserDataSequence ( uno::Sequence < beans::PropertyValue >& rSequence )
+{
+ const SwRect& rRect = m_pWrtShell->GetCharRect();
+ const tools::Rectangle& rVis = GetVisArea();
+
+ std::vector<beans::PropertyValue> aVector;
+
+ sal_uInt16 nViewID( GetViewFrame().GetCurViewId());
+ aVector.push_back(comphelper::makePropertyValue("ViewId", "view" + OUString::number(nViewID)));
+
+ aVector.push_back(comphelper::makePropertyValue("ViewLeft", convertTwipToMm100 ( rRect.Left() )));
+
+ aVector.push_back(comphelper::makePropertyValue("ViewTop", convertTwipToMm100 ( rRect.Top() )));
+
+ auto visibleLeft = convertTwipToMm100 ( rVis.Left() );
+ aVector.push_back(comphelper::makePropertyValue("VisibleLeft", visibleLeft));
+
+ auto visibleTop = convertTwipToMm100 ( rVis.Top() );
+ aVector.push_back(comphelper::makePropertyValue("VisibleTop", visibleTop));
+
+ // We don't read VisibleRight and VisibleBottom anymore, but write them,
+ // because older versions rely on their presence to restore position
+
+ auto visibleRight = rVis.IsWidthEmpty() ? visibleLeft : convertTwipToMm100 ( rVis.Right() );
+ aVector.push_back(comphelper::makePropertyValue("VisibleRight", visibleRight));
+
+ auto visibleBottom = rVis.IsHeightEmpty() ? visibleTop : convertTwipToMm100 ( rVis.Bottom() );
+ aVector.push_back(comphelper::makePropertyValue("VisibleBottom", visibleBottom));
+
+ const sal_Int16 nZoomType = static_cast< sal_Int16 >(m_pWrtShell->GetViewOptions()->GetZoomType());
+ aVector.push_back(comphelper::makePropertyValue("ZoomType", nZoomType));
+
+ const sal_Int16 nViewLayoutColumns = static_cast< sal_Int16 >(m_pWrtShell->GetViewOptions()->GetViewLayoutColumns());
+ aVector.push_back(comphelper::makePropertyValue("ViewLayoutColumns", nViewLayoutColumns));
+
+ aVector.push_back(comphelper::makePropertyValue("ViewLayoutBookMode", m_pWrtShell->GetViewOptions()->IsViewLayoutBookMode()));
+
+ aVector.push_back(comphelper::makePropertyValue("ZoomFactor", static_cast < sal_Int16 > (m_pWrtShell->GetViewOptions()->GetZoom())));
+
+ aVector.push_back(comphelper::makePropertyValue("IsSelectedFrame", FrameTypeFlags::NONE != m_pWrtShell->GetSelFrameType()));
+
+ aVector.push_back(
+ comphelper::makePropertyValue("KeepRatio", m_pWrtShell->GetViewOptions()->IsKeepRatio()));
+
+ rSequence = comphelper::containerToSequence(aVector);
+
+ // Common SdrModel processing
+ GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel()->WriteUserDataSequence(rSequence);
+}
+
+void SwView::ShowCursor( bool bOn )
+{
+ //don't scroll the cursor into the visible area
+ bool bUnlockView = !m_pWrtShell->IsViewLocked();
+ m_pWrtShell->LockView( true ); //lock visible section
+
+ if( !bOn )
+ m_pWrtShell->HideCursor();
+ else if( !m_pWrtShell->IsFrameSelected() && !m_pWrtShell->IsObjSelected() )
+ m_pWrtShell->ShowCursor();
+
+ if( bUnlockView )
+ m_pWrtShell->LockView( false );
+}
+
+ErrCode SwView::DoVerb(sal_Int32 nVerb)
+{
+ if ( !GetViewFrame().GetFrame().IsInPlace() )
+ {
+ SwWrtShell &rSh = GetWrtShell();
+ const SelectionType nSel = rSh.GetSelectionType();
+ if ( nSel & SelectionType::Ole )
+ rSh.LaunchOLEObj( nVerb );
+ }
+ return ERRCODE_NONE;
+}
+
+// only return true for a text selection
+
+bool SwView::HasSelection( bool bText ) const
+{
+ return bText ? GetWrtShell().SwCursorShell::HasSelection()
+ : GetWrtShell().HasSelection();
+}
+
+OUString SwView::GetSelectionText( bool bCompleteWrds, bool /*bOnlyASample*/ )
+{
+ return GetSelectionTextParam( bCompleteWrds, true );
+}
+
+OUString SwView::GetSelectionTextParam( bool bCompleteWrds, bool bEraseTrail )
+{
+ OUString sReturn;
+ if( bCompleteWrds && !GetWrtShell().HasSelection() )
+ GetWrtShell().SelWrd();
+
+ GetWrtShell().GetSelectedText( sReturn );
+ if( bEraseTrail )
+ sReturn = comphelper::string::stripEnd(sReturn, ' ');
+ return sReturn;
+}
+
+SwGlossaryHdl* SwView::GetGlosHdl()
+{
+ if(!m_pGlosHdl)
+ m_pGlosHdl.reset(new SwGlossaryHdl(GetViewFrame(), m_pWrtShell.get()));
+ return m_pGlosHdl.get();
+}
+
+void SwView::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ bool bCallBase = true;
+ if(auto pChangedHint = dynamic_cast<const FmDesignModeChangedHint*>(&rHint))
+ {
+ bool bDesignMode = pChangedHint->GetDesignMode();
+ if (!bDesignMode && GetDrawFuncPtr())
+ {
+ GetDrawFuncPtr()->Deactivate();
+ SetDrawFuncPtr(nullptr);
+ LeaveDrawCreate();
+ AttrChangedNotify(nullptr);
+ }
+ }
+ else
+ {
+ SfxHintId nId = rHint.GetId();
+
+ switch ( nId )
+ {
+ // sub shells will be destroyed by the
+ // dispatcher, if the view frame is dying. Thus, reset member <pShell>.
+ case SfxHintId::Dying:
+ {
+ if ( &rBC == &GetViewFrame() )
+ {
+ ResetSubShell();
+ }
+ }
+ break;
+ case SfxHintId::ModeChanged:
+ {
+ // Modal mode change-over?
+ bool bModal = GetDocShell()->IsInModalMode();
+ m_pHRuler->SetActive( !bModal );
+ m_pVRuler->SetActive( !bModal );
+ }
+
+ [[fallthrough]];
+
+ case SfxHintId::TitleChanged:
+ if ( GetDocShell()->IsReadOnly() != GetWrtShell().GetViewOptions()->IsReadonly() )
+ {
+ SwWrtShell &rSh = GetWrtShell();
+ rSh.SetReadonlyOption( GetDocShell()->IsReadOnly() );
+
+ if ( rSh.GetViewOptions()->IsViewVRuler() )
+ CreateVRuler();
+ else
+ KillVRuler();
+ if ( rSh.GetViewOptions()->IsViewHRuler() )
+ CreateTab();
+ else
+ KillTab();
+ bool bReadonly = GetDocShell()->IsReadOnly();
+ // if document is to be opened in alive-mode then this has to be
+ // regarded while switching from readonly-mode to edit-mode
+ if( !bReadonly )
+ {
+ SwDrawModel * pDrawDoc = GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
+ if (pDrawDoc)
+ {
+ if( !pDrawDoc->GetOpenInDesignMode() )
+ break;// don't touch the design mode
+ }
+ }
+ SfxBoolItem aItem( SID_FM_DESIGN_MODE, !bReadonly);
+ GetDispatcher().ExecuteList(SID_FM_DESIGN_MODE,
+ SfxCallMode::ASYNCHRON, { &aItem });
+ }
+ break;
+
+ case SfxHintId::SwDrawViewsCreated:
+ {
+ bCallBase = false;
+ if ( GetFormShell() )
+ {
+ GetFormShell()->SetView(dynamic_cast<FmFormView*>(GetWrtShell().GetDrawView()));
+ SfxBoolItem aItem( SID_FM_DESIGN_MODE, !GetDocShell()->IsReadOnly());
+ GetDispatcher().ExecuteList(SID_FM_DESIGN_MODE,
+ SfxCallMode::SYNCHRON, { &aItem });
+ }
+ }
+ break;
+ case SfxHintId::RedlineChanged:
+ {
+ static sal_uInt16 const aSlotRedLine[] = {
+ FN_REDLINE_ACCEPT_DIRECT,
+ FN_REDLINE_REJECT_DIRECT,
+ FN_REDLINE_NEXT_CHANGE,
+ FN_REDLINE_PREV_CHANGE,
+ FN_REDLINE_ACCEPT_ALL,
+ FN_REDLINE_REJECT_ALL,
+ 0
+ };
+ GetViewFrame().GetBindings().Invalidate(aSlotRedLine);
+ }
+ break;
+ default: break;
+ }
+ }
+
+ if ( bCallBase )
+ SfxViewShell::Notify(rBC, rHint);
+}
+
+#if defined(_WIN32) || defined UNX
+
+void SwView::ScannerEventHdl()
+{
+ uno::Reference< XScannerManager2 > xScanMgr = SW_MOD()->GetScannerManager();
+ if( xScanMgr.is() )
+ {
+ const ScannerContext aContext( xScanMgr->getAvailableScanners().getConstArray()[ 0 ] );
+ const ScanError eError = xScanMgr->getError( aContext );
+
+ if( ScanError_ScanErrorNone == eError )
+ {
+ const uno::Reference< awt::XBitmap > xBitmap( xScanMgr->getBitmap( aContext ) );
+
+ if( xBitmap.is() )
+ {
+ const BitmapEx aScanBmp( VCLUnoHelper::GetBitmap( xBitmap ) );
+
+ if( !aScanBmp.IsEmpty() )
+ {
+ Graphic aGrf(aScanBmp);
+ m_pWrtShell->InsertGraphic( OUString(), OUString(), aGrf );
+ }
+ }
+ }
+ }
+ SfxBindings& rBind = GetViewFrame().GetBindings();
+ rBind.Invalidate( SID_TWAIN_SELECT );
+ rBind.Invalidate( SID_TWAIN_TRANSFER );
+}
+#endif
+
+void SwView::StopShellTimer()
+{
+ if(m_aTimer.IsActive())
+ {
+ m_aTimer.Stop();
+ if ( m_bAttrChgNotifiedWithRegistrations )
+ {
+ GetViewFrame().GetBindings().LEAVEREGISTRATIONS();
+ m_bAttrChgNotifiedWithRegistrations = false;
+ }
+ SelectShell();
+ m_bAttrChgNotified = false;
+ }
+}
+
+bool SwView::PrepareClose( bool bUI )
+{
+ SfxViewFrame& rVFrame = GetViewFrame();
+ rVFrame.SetChildWindow( SwInputChild::GetChildWindowId(), false );
+ if( rVFrame.GetDispatcher()->IsLocked() )
+ rVFrame.GetDispatcher()->Lock(false);
+
+ if ( m_pFormShell && !m_pFormShell->PrepareClose( bUI ) )
+ {
+ return false;
+ }
+ return SfxViewShell::PrepareClose( bUI );
+}
+
+// status methods for clipboard.
+// Status changes now notified from the clipboard.
+bool SwView::IsPasteAllowed()
+{
+ SotExchangeDest nPasteDestination = SwTransferable::GetSotDestination( *m_pWrtShell );
+ if( m_nLastPasteDestination != nPasteDestination )
+ {
+ TransferableDataHelper aDataHelper(
+ TransferableDataHelper::CreateFromSystemClipboard(
+ &GetEditWin()) );
+ if( aDataHelper.GetXTransferable().is() )
+ {
+ m_bPasteState = SwTransferable::IsPaste( *m_pWrtShell, aDataHelper );
+ m_bPasteSpecialState = SwTransferable::IsPasteSpecial(
+ *m_pWrtShell, aDataHelper );
+ }
+ else
+ m_bPasteState = m_bPasteSpecialState = false;
+
+ if( static_cast<SotExchangeDest>(0xFFFF) == m_nLastPasteDestination ) // the init value
+ m_pViewImpl->AddClipboardListener();
+ m_nLastPasteDestination = nPasteDestination;
+ }
+ return m_bPasteState;
+}
+
+bool SwView::IsPasteSpecialAllowed()
+{
+ if ( m_pFormShell && m_pFormShell->IsActiveControl() )
+ return false;
+
+ SotExchangeDest nPasteDestination = SwTransferable::GetSotDestination( *m_pWrtShell );
+ if( m_nLastPasteDestination != nPasteDestination )
+ {
+ TransferableDataHelper aDataHelper(
+ TransferableDataHelper::CreateFromSystemClipboard(
+ &GetEditWin()) );
+ if( aDataHelper.GetXTransferable().is() )
+ {
+ m_bPasteState = SwTransferable::IsPaste( *m_pWrtShell, aDataHelper );
+ m_bPasteSpecialState = SwTransferable::IsPasteSpecial(
+ *m_pWrtShell, aDataHelper );
+ }
+ else
+ m_bPasteState = m_bPasteSpecialState = false;
+
+ if( static_cast<SotExchangeDest>(0xFFFF) == m_nLastPasteDestination ) // the init value
+ m_pViewImpl->AddClipboardListener();
+ }
+ return m_bPasteSpecialState;
+}
+
+bool SwView::IsPasteSpreadsheet(bool bHasOwnTableCopied)
+{
+ TransferableDataHelper aDataHelper(
+ TransferableDataHelper::CreateFromSystemClipboard(
+ &GetEditWin()) );
+ if( aDataHelper.GetXTransferable().is() )
+ {
+ if (bHasOwnTableCopied && SwTransferable::IsPasteOwnFormat( aDataHelper ))
+ return true;
+ return aDataHelper.HasFormat( SotClipboardFormatId::SYLK ) || aDataHelper.HasFormat( SotClipboardFormatId::SYLK_BIGCAPS );
+ }
+ return false;
+}
+
+void SwView::NotifyDBChanged()
+{
+ GetViewImpl()->GetUNOObject_Impl()->NotifyDBChanged();
+}
+
+// Printing
+
+SfxObjectShellLock SwView::CreateTmpSelectionDoc()
+{
+ SwXTextView *const pTempImpl = GetViewImpl()->GetUNOObject_Impl();
+ return pTempImpl->BuildTmpSelectionDoc();
+}
+
+void SwView::AddTransferable(SwTransferable& rTransferable)
+{
+ GetViewImpl()->AddTransferable(rTransferable);
+}
+
+tools::Rectangle SwView::getLOKVisibleArea() const
+{
+ if (SwViewShell* pVwSh = GetWrtShellPtr())
+ return pVwSh->getLOKVisibleArea();
+ else
+ return tools::Rectangle();
+}
+
+void SwView::flushPendingLOKInvalidateTiles()
+{
+ if (SwWrtShell* pSh = GetWrtShellPtr())
+ pSh->FlushPendingLOKInvalidateTiles();
+}
+
+std::optional<OString> SwView::getLOKPayload(int nType, int nViewId) const
+{
+ if (SwWrtShell* pSh = GetWrtShellPtr())
+ return pSh->getLOKPayload(nType, nViewId);
+ else
+ return std::nullopt;
+}
+
+OUString SwView::GetDataSourceName() const
+{
+ uno::Reference<lang::XMultiServiceFactory> xFactory(GetDocShell()->GetModel(), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xSettings(
+ xFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY);
+ OUString sDataSourceName = "";
+ xSettings->getPropertyValue("CurrentDatabaseDataSource") >>= sDataSourceName;
+
+ return sDataSourceName;
+}
+
+bool SwView::IsDataSourceAvailable(const OUString sDataSourceName)
+{
+ uno::Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ Reference< XDatabaseContext> xDatabaseContext = DatabaseContext::create(xContext);
+
+ return xDatabaseContext->hasByName(sDataSourceName);
+}
+
+void SwView::BringToAttention(std::vector<basegfx::B2DRange>&& aRanges)
+{
+ m_nBringToAttentionBlinkTimeOutsRemaining = 0;
+ m_aBringToAttentionBlinkTimer.Stop();
+ if (aRanges.empty())
+ m_xBringToAttentionOverlayObject.reset();
+ else
+ {
+ m_xBringToAttentionOverlayObject.reset(
+ new sdr::overlay::OverlaySelection(sdr::overlay::OverlayType::Invert,
+ Color(), std::move(aRanges),
+ true /*unused for Invert type*/));
+ m_nBringToAttentionBlinkTimeOutsRemaining = 4;
+ m_aBringToAttentionBlinkTimer.Start();
+ }
+}
+
+void SwView::BringToAttention(const tools::Rectangle& rRect)
+{
+ std::vector<basegfx::B2DRange> aRanges{ basegfx::B2DRange(rRect.Left(), rRect.Top(),
+ rRect.Right(), rRect.Bottom()) };
+ BringToAttention(std::move(aRanges));
+}
+
+void SwView::BringToAttention(const SwNode* pNode)
+{
+ if (!pNode)
+ return;
+
+ std::vector<basegfx::B2DRange> aRanges;
+ const SwFrame* pFrame;
+ if (pNode->IsContentNode())
+ {
+ pFrame = pNode->GetContentNode()->getLayoutFrame(GetWrtShell().GetLayout());
+ }
+ else
+ {
+ // section and table nodes
+ SwNode2Layout aTmp(*pNode, pNode->GetIndex() - 1);
+ pFrame = aTmp.NextFrame();
+ }
+ while (pFrame)
+ {
+ const SwRect& rFrameRect = pFrame->getFrameArea();
+ if (!rFrameRect.IsEmpty())
+ aRanges.emplace_back(rFrameRect.Left(), rFrameRect.Top() + pFrame->GetTopMargin(),
+ rFrameRect.Right(), rFrameRect.Bottom());
+ if (!pFrame->IsFlowFrame())
+ break;
+ const SwFlowFrame* pFollow = SwFlowFrame::CastFlowFrame(pFrame)->GetFollow();
+ if (!pFollow)
+ break;
+ pFrame = &pFollow->GetFrame();
+ }
+ BringToAttention(std::move(aRanges));
+}
+
+IMPL_LINK_NOARG(SwView, BringToAttentionBlinkTimerHdl, Timer*, void)
+{
+ if (GetDrawView() && m_xBringToAttentionOverlayObject)
+ {
+ if (SdrView* pView = GetDrawView())
+ {
+ if (SdrPaintWindow* pPaintWindow = pView->GetPaintWindow(0))
+ {
+ const rtl::Reference<sdr::overlay::OverlayManager>& xOverlayManager
+ = pPaintWindow->GetOverlayManager();
+ if (m_nBringToAttentionBlinkTimeOutsRemaining % 2 == 0)
+ xOverlayManager->add(*m_xBringToAttentionOverlayObject);
+ else
+ xOverlayManager->remove(*m_xBringToAttentionOverlayObject);
+ --m_nBringToAttentionBlinkTimeOutsRemaining;
+ }
+ else
+ m_nBringToAttentionBlinkTimeOutsRemaining = 0;
+ }
+ else
+ m_nBringToAttentionBlinkTimeOutsRemaining = 0;
+ }
+ else
+ m_nBringToAttentionBlinkTimeOutsRemaining = 0;
+ if (m_nBringToAttentionBlinkTimeOutsRemaining == 0)
+ {
+ m_xBringToAttentionOverlayObject.reset();
+ m_aBringToAttentionBlinkTimer.Stop();
+ }
+}
+
+namespace sw {
+
+void InitPrintOptionsFromApplication(SwPrintData & o_rData, bool const bWeb)
+{
+ o_rData = *SW_MOD()->GetPrtOptions(bWeb);
+}
+
+} // namespace sw
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */