diff options
Diffstat (limited to 'sw/source/uibase/uiview/view.cxx')
-rw-r--r-- | sw/source/uibase/uiview/view.cxx | 498 |
1 files changed, 375 insertions, 123 deletions
diff --git a/sw/source/uibase/uiview/view.cxx b/sw/source/uibase/uiview/view.cxx index 5f5fd34029af..3df6f2f49c3f 100644 --- a/sw/source/uibase/uiview/view.cxx +++ b/sw/source/uibase/uiview/view.cxx @@ -17,12 +17,19 @@ * 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> @@ -80,10 +87,14 @@ #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> @@ -91,20 +102,30 @@ #include <PostItMgr.hxx> #include <annotsh.hxx> #include <swruler.hxx> - +#include <svx/theme/ThemeColorChangerCommon.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; #define SWVIEWFLAGS SfxViewShellFlags::HAS_PRINTOPTIONS @@ -123,16 +144,17 @@ std::unique_ptr<SearchAttrItemList> SwView::s_xReplaceList; SfxDispatcher &SwView::GetDispatcher() { - return *GetViewFrame()->GetDispatcher(); + return *GetViewFrame().GetDispatcher(); } void SwView::ImpSetVerb( SelectionType nSelType ) { bool bResetVerbs = m_bVerbsActive; - if ( !GetViewFrame()->GetFrame().IsInPlace() && + if ( !GetViewFrame().GetFrame().IsInPlace() && (SelectionType::Ole|SelectionType::Graphic) & nSelType ) { - if ( m_pWrtShell->IsSelObjProtected(FlyProtectFlags::Content) == FlyProtectFlags::NONE ) + FlyProtectFlags eProtectFlags = m_pWrtShell->IsSelObjProtected(FlyProtectFlags::Content); + if (eProtectFlags == FlyProtectFlags::NONE || nSelType & SelectionType::Ole) { if ( nSelType & SelectionType::Ole ) { @@ -173,10 +195,10 @@ void SwView::GotFocus() const const_cast< SwView* >( this )->AttrChangedNotify(nullptr); } } - if( GetWrtShellPtr() ) + if (SwWrtShell* pWrtShell = GetWrtShellPtr()) { SwWrtShell& rWrtShell = GetWrtShell(); - rWrtShell.GetDoc()->getIDocumentLayoutAccess().SetCurrentViewShell( GetWrtShellPtr() ); + rWrtShell.GetDoc()->getIDocumentLayoutAccess().SetCurrentViewShell( pWrtShell ); rWrtShell.GetDoc()->getIDocumentSettingAccess().set( DocumentSettingId::BROWSE_MODE, rWrtShell.GetViewOptions()->getBrowseMode() ); } @@ -227,7 +249,7 @@ uno::Reference<frame::XLayoutManager> getLayoutManager(const SfxViewFrame& rView void SwView::ShowUIElement(const OUString& sElementURL) const { - if (auto xLayoutManager = getLayoutManager(*GetViewFrame())) + if (auto xLayoutManager = getLayoutManager(GetViewFrame())) { if (!xLayoutManager->getElement(sElementURL).is()) { @@ -241,7 +263,8 @@ void SwView::SelectShell() { // Attention: Maintain the SelectShell for the WebView additionally - if(m_bInDtor) + // 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 @@ -257,16 +280,41 @@ void SwView::SelectShell() 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 ); + 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 { @@ -439,7 +487,7 @@ void SwView::SelectShell() } // Show Mail Merge toolbar initially for documents with Database fields - if (!m_bInitOnceCompleted && GetWrtShell().IsAnyDatabaseFieldInDoc()) + if (!m_bInitOnceCompleted && GetWrtShell().IsAnyDatabaseFieldInDoc() && !comphelper::IsFuzzing()) ShowUIElement("private:resource/toolbar/mailmerge"); // Activate the toolbar to the new selection which also was active last time. @@ -489,6 +537,11 @@ 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() ) @@ -501,17 +554,17 @@ IMPL_LINK_NOARG(SwView, AttrChangedNotify, LinkParamNone*, void) { if (m_pWrtShell->ActionPend() || g_bNoInterrupt || GetDispatcher().IsLocked() || //do not confuse the SFX - GetViewFrame()->GetBindings().IsInUpdate() )//do not confuse the SFX + GetViewFrame().GetBindings().IsInUpdate() )//do not confuse the SFX { m_bAttrChgNotified = true; m_aTimer.Start(); - const SfxPoolItem *pItem; - if ( SfxItemState::SET != GetObjectShell()->GetMedium()->GetItemSet()-> - GetItemState( SID_HIDDEN, false, &pItem ) || - !static_cast<const SfxBoolItem*>(pItem)->GetValue() ) + const SfxBoolItem *pItem = + GetObjectShell()->GetMedium()->GetItemSet(). + GetItemIfSet( SID_HIDDEN, false ); + if ( !pItem || !pItem->GetValue() ) { - GetViewFrame()->GetBindings().ENTERREGISTRATIONS(); + GetViewFrame().GetBindings().ENTERREGISTRATIONS(); m_bAttrChgNotifiedWithRegistrations = true; } @@ -530,6 +583,11 @@ IMPL_LINK_NOARG(SwView, AttrChangedNotify, LinkParamNone*, void) } } +void SwView::TriggerAttrChangedNotify() +{ + AttrChangedNotify(nullptr); +} + IMPL_LINK_NOARG(SwView, TimeoutHdl, Timer *, void) { if (m_pWrtShell->ActionPend() || g_bNoInterrupt) @@ -540,7 +598,7 @@ IMPL_LINK_NOARG(SwView, TimeoutHdl, Timer *, void) if ( m_bAttrChgNotifiedWithRegistrations ) { - GetViewFrame()->GetBindings().LEAVEREGISTRATIONS(); + GetViewFrame().GetBindings().LEAVEREGISTRATIONS(); m_bAttrChgNotifiedWithRegistrations = false; } @@ -560,11 +618,11 @@ void SwView::CheckReadonlyState() SfxDispatcher &rDis = GetDispatcher(); // To be able to recognize if it is already disabled! SfxItemState eStateRO, eStateProtAll; - const SfxPoolItem *pItem; + 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, pItem ); - eStateProtAll = rDis.QueryState( FN_EDIT_REGION, pItem ); + eStateRO = rDis.QueryState(FN_INSERT_BOOKMARK, aResult); + eStateProtAll = rDis.QueryState(FN_EDIT_REGION, aResult); bool bChgd = false; if ( !m_pWrtShell->IsCursorReadonly() ) @@ -577,10 +635,13 @@ void SwView::CheckReadonlyState() 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, SID_EMOJI_CONTROL, FN_INSERT_SOFT_HYPHEN, + 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_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, @@ -589,6 +650,7 @@ void SwView::CheckReadonlyState() 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, @@ -640,7 +702,7 @@ void SwView::CheckReadonlyState() rDis.SetSlotFilter(); } if ( bChgd ) - GetViewFrame()->GetBindings().InvalidateAll(true); + GetViewFrame().GetBindings().InvalidateAll(true); } void SwView::CheckReadonlySelection() @@ -694,33 +756,34 @@ void SwView::CheckReadonlySelection() if( nDisableFlags != rDis.GetDisableFlags() ) { rDis.SetDisableFlags( nDisableFlags ); - GetViewFrame()->GetBindings().InvalidateAll( true ); + GetViewFrame().GetBindings().InvalidateAll( true ); } } -SwView::SwView( SfxViewFrame *_pFrame, SfxViewShell* pOldSh ) - : SfxViewShell( _pFrame, SWVIEWFLAGS ), +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( &_pFrame->GetWindow(), *this ) ), + m_pEditWin( VclPtr<SwEditWin>::Create( &_rFrame.GetWindow(), *this ) ), m_pShell(nullptr), m_pFormShell(nullptr), m_pHScrollbar(nullptr), m_pVScrollbar(nullptr), - m_pScrollFill(VclPtr<ScrollBarBox>::Create( &_pFrame->GetWindow(), WB_SIZEABLE )), - m_pVRuler(VclPtr<SvxRuler>::Create(&GetViewFrame()->GetWindow(), m_pEditWin, + m_pVRuler(VclPtr<SvxRuler>::Create(&GetViewFrame().GetWindow(), m_pEditWin, SvxRulerSupportFlags::TABS | SvxRulerSupportFlags::PARAGRAPH_MARGINS_VERTICAL| SvxRulerSupportFlags::BORDERS | SvxRulerSupportFlags::REDUCED_METRIC, - GetViewFrame()->GetBindings(), + 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(OBJ_NONE), + m_eFormObjKind(SdrObjKind::NONE), m_nLastPasteDestination( static_cast<SotExchangeDest>(0xFFFF) ), m_nLeftBorderDistance( 0 ), m_nRightBorderDistance( 0 ), @@ -747,7 +810,10 @@ SwView::SwView( SfxViewFrame *_pFrame, SfxViewShell* pOldSh ) m_bOldShellWasPagePreview(false), m_bIsPreviewDoubleClick(false), m_bMakeSelectionVisible(false), - m_nLOKPageUpDownOffset(0) + m_bForceChangesToolbar(true), + m_nLOKPageUpDownOffset(0), + m_aBringToAttentionBlinkTimer("SwView m_aBringToAttentionBlinkTimer"), + m_nBringToAttentionBlinkTimeOutsRemaining(0) { static bool bRequestDoubleBuffering = getenv("VCL_DOUBLEBUFFERING_ENABLE"); if (bRequestDoubleBuffering) @@ -762,8 +828,13 @@ SwView::SwView( SfxViewFrame *_pFrame, SfxViewShell* pOldSh ) bDocSzUpdated = true; - CreateScrollbar( true ); - CreateScrollbar( false ); + static bool bFuzzing = comphelper::IsFuzzing(); + + if (!bFuzzing) + { + CreateScrollbar( true ); + CreateScrollbar( false ); + } m_pViewImpl.reset(new SwView_Impl(this)); SetName("View"); @@ -771,7 +842,7 @@ SwView::SwView( SfxViewFrame *_pFrame, SfxViewShell* pOldSh ) m_aTimer.SetTimeout( 120 ); - SwDocShell& rDocSh = dynamic_cast<SwDocShell&>(*_pFrame->GetObjectShell()); + SwDocShell& rDocSh = dynamic_cast<SwDocShell&>(*_rFrame.GetObjectShell()); bool bOldModifyFlag = rDocSh.IsEnableSetModified(); if (bOldModifyFlag) rDocSh.EnableSetModified( false ); @@ -867,13 +938,13 @@ SwView::SwView( SfxViewFrame *_pFrame, SfxViewShell* pOldSh ) } } SAL_INFO( "sw.ui", "after create WrtShell" ); - m_pHRuler = VclPtr<SwCommentRuler>::Create(m_pWrtShell.get(), &GetViewFrame()->GetWindow(), m_pEditWin, + 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(), + GetViewFrame().GetBindings(), WB_STDRULER | WB_EXTRAFIELD | WB_BORDER); // assure that modified state of document @@ -898,9 +969,9 @@ SwView::SwView( SfxViewFrame *_pFrame, SfxViewShell* pOldSh ) m_pHRuler->SetActive(); m_pVRuler->SetActive(); - SfxViewFrame* pViewFrame = GetViewFrame(); + SfxViewFrame& rViewFrame = GetViewFrame(); - StartListening(*pViewFrame, DuplicateHandling::Prevent); + StartListening(rViewFrame, DuplicateHandling::Prevent); StartListening(rDocSh, DuplicateHandling::Prevent); // Set Zoom-factor from HRuler @@ -936,7 +1007,7 @@ SwView::SwView( SfxViewFrame *_pFrame, SfxViewShell* pOldSh ) SAL_WARN_IF( officecfg::Office::Common::Undo::Steps::get() <= 0, "sw.ui", "/org.openoffice.Office.Common/Undo/Steps <= 0"); - if (!utl::ConfigManager::IsFuzzing() && 0 < officecfg::Office::Common::Undo::Steps::get()) + if (!bFuzzing && 0 < officecfg::Office::Common::Undo::Steps::get()) { m_pWrtShell->DoUndo(); } @@ -948,7 +1019,8 @@ SwView::SwView( SfxViewFrame *_pFrame, SfxViewShell* pOldSh ) m_bVScrollbarEnabled = aUsrPref.IsViewVScrollBar(); m_bHScrollbarEnabled = aUsrPref.IsViewHScrollBar(); - m_pHScrollbar->SetAuto(bBrowse); + if (m_pHScrollbar) + m_pHScrollbar->SetAuto(bBrowse); if( aUsrPref.IsViewHRuler() ) CreateTab(); if( aUsrPref.IsViewVRuler() ) @@ -956,7 +1028,9 @@ SwView::SwView( SfxViewFrame *_pFrame, SfxViewShell* pOldSh ) m_pWrtShell->SetUIOptions( aUsrPref ); m_pWrtShell->SetReadOnlyAvailable( aUsrPref.IsCursorInProtectedArea() ); - m_pWrtShell->ApplyAccessibilityOptions(SW_MOD()->GetAccessibilityOptions()); +#if !ENABLE_WASM_STRIP_ACCESSIBILITY + m_pWrtShell->ApplyAccessibilityOptions(); +#endif if( m_pWrtShell->GetDoc()->getIDocumentState().IsUpdateExpField() ) { @@ -981,7 +1055,7 @@ SwView::SwView( SfxViewFrame *_pFrame, SfxViewShell* pOldSh ) } // No ResetModified, if there is already a view to this doc. - SfxViewFrame* pVFrame = GetViewFrame(); + 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. @@ -990,7 +1064,7 @@ SwView::SwView( SfxViewFrame *_pFrame, SfxViewShell* pOldSh ) // no reset of modified state, if document // was already modified. if (!m_pWrtShell->GetDoc()->GetIDocumentUndoRedo().IsUndoNoResetModified() && - ( !pFirst || pFirst == pVFrame ) && + ( !pFirst || pFirst == &rVFrame ) && !bIsDocModified ) { m_pWrtShell->ResetModified(); @@ -1000,13 +1074,13 @@ SwView::SwView( SfxViewFrame *_pFrame, SfxViewShell* pOldSh ) // If a new GlobalDoc will be created, the navigator will also be generated. if( dynamic_cast<const SwGlobalDocShell*>(&rDocSh) != nullptr && - !pVFrame->GetChildWindow( SID_NAVIGATOR )) + !rVFrame.GetChildWindow( SID_NAVIGATOR )) { SfxBoolItem aNavi(SID_NAVIGATOR, true); GetDispatcher().ExecuteList(SID_NAVIGATOR, SfxCallMode::ASYNCHRON, { &aNavi }); } - uno::Reference< frame::XFrame > xFrame = pVFrame->GetFrame().GetFrameInterface(); + uno::Reference< frame::XFrame > xFrame = rVFrame.GetFrame().GetFrameInterface(); uno::Reference< frame::XFrame > xBeamerFrame = xFrame->findFrame( "_beamer", frame::FrameSearchFlag::CHILDREN); @@ -1019,24 +1093,40 @@ SwView::SwView( SfxViewFrame *_pFrame, SfxViewShell* pOldSh ) // has anybody calls the attrchanged handler in the constructor? if( m_bAttrChgNotifiedWithRegistrations ) { - GetViewFrame()->GetBindings().LEAVEREGISTRATIONS(); + GetViewFrame().GetBindings().LEAVEREGISTRATIONS(); if( m_aTimer.IsActive() ) m_aTimer.Stop(); } m_aTimer.SetInvokeHandler(LINK(this, SwView, TimeoutHdl)); - m_aTimer.SetDebugName( "sw::SwView m_aTimer" ); m_bAttrChgNotified = m_bAttrChgNotifiedWithRegistrations = false; if (bOldModifyFlag) rDocSh.EnableSetModified(); InvalidateBorder(); - if( !m_pHScrollbar->IsVisible( true ) ) - ShowHScrollbar( false ); - if( !m_pVScrollbar->IsVisible( true ) ) - ShowVScrollbar( false ); + if (!bFuzzing) + { + if (!m_pHScrollbar->IsScrollbarVisible(true)) + ShowHScrollbar( false ); + if (!m_pVScrollbar->IsScrollbarVisible(true)) + ShowVScrollbar( false ); + } + + if (m_pWrtShell->GetViewOptions()->IsShowOutlineContentVisibilityButton()) + m_pWrtShell->InvalidateOutlineContentVisibility(); - GetViewFrame()->GetWindow().AddChildEventListener( LINK( this, SwView, WindowChildEventListener ) ); + 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) @@ -1059,14 +1149,14 @@ SwViewGlueDocShell::~SwViewGlueDocShell() SwView::~SwView() { // Notify other LOK views that we are going away. - SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_VIEW_CURSOR_VISIBLE, "visible", "false"); - SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", ""); - SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_GRAPHIC_VIEW_SELECTION, "selection", "EMPTY"); + 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 ) ); + GetViewFrame().GetWindow().RemoveChildEventListener( LINK( this, SwView, WindowChildEventListener ) ); m_pPostItMgr.reset(); m_bInDtor = true; @@ -1076,20 +1166,30 @@ SwView::~SwView() m_xGlueDocShell.reset(); if( m_aTimer.IsActive() && m_bAttrChgNotifiedWithRegistrations ) - GetViewFrame()->GetBindings().LEAVEREGISTRATIONS(); + GetViewFrame().GetBindings().LEAVEREGISTRATIONS(); // the last view must end the text edit - SdrView *pSdrView = m_pWrtShell ? m_pWrtShell->GetDrawView() : nullptr; + 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(GetViewFrame()); EndListening(*GetDocShell()); - m_pScrollFill.disposeAndClear(); + + // 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(); @@ -1106,9 +1206,31 @@ SwView::~SwView() 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) + { + std::shared_ptr<model::ColorSet> pThemeColors = pDocShell->GetThemeColors(); + std::set<Color> aDocumentColors = pDocShell->GetDocColors(); + svx::theme::notifyLOK(pThemeColors, aDocumentColors); + } +} + SwDocShell* SwView::GetDocShell() { - SfxObjectShell* pDocShell = GetViewFrame()->GetObjectShell(); + SfxObjectShell* pDocShell = GetViewFrame().GetObjectShell(); return dynamic_cast<SwDocShell*>( pDocShell ); } @@ -1140,13 +1262,17 @@ void SwView::WriteUserData( OUString &rUserData, bool bBrowse ) rUserData += OUString::number( static_cast<sal_uInt16>(m_pWrtShell->GetViewOptions()->GetZoomType()));//eZoom; rUserData += ";"; - rUserData += FrameTypeFlags::NONE == m_pWrtShell->GetSelFrameType() ? OUStringLiteral(u"0") : OUStringLiteral(u"1"); + 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 @@ -1154,9 +1280,8 @@ static bool lcl_IsOwnDocument( SwView& rView ) OUString Created = xDocProps->getAuthor(); OUString Changed = xDocProps->getModifiedBy(); OUString FullName = SW_MOD()->GetUserOptions().GetFullName(); - return (!FullName.isEmpty() && - (!Changed.isEmpty() && Changed == FullName )) || - (Changed.isEmpty() && !Created.isEmpty() && Created == FullName ); + return !FullName.isEmpty() + && (Changed == FullName || (Changed.isEmpty() && Created == FullName)); } void SwView::ReadUserData( const OUString &rUserData, bool bBrowse ) @@ -1175,17 +1300,17 @@ void SwView::ReadUserData( const OUString &rUserData, bool bBrowse ) // No it is *not* a good idea to call GetToken within Point constr. immediately, // because which parameter is evaluated first? - tools::Long nX = rUserData.getToken( 0, ';', nPos ).toInt32(), - nY = rUserData.getToken( 0, ';', nPos ).toInt32(); + 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 >( rUserData.getToken(0, ';', nPos ).toInt32() ); + static_cast< sal_uInt16 >( o3tl::toInt32(o3tl::getToken(rUserData, 0, ';', nPos )) ); - tools::Long nLeft = rUserData.getToken(0, ';', nPos ).toInt32(), - nTop = rUserData.getToken(0, ';', nPos ).toInt32(), - nRight = rUserData.getToken(0, ';', nPos ).toInt32(), - nBottom= rUserData.getToken(0, ';', nPos ).toInt32(); + 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) ) @@ -1198,14 +1323,14 @@ void SwView::ReadUserData( const OUString &rUserData, bool bBrowse ) sal_Int32 nOff = 0; SvxZoomType eZoom; if( !m_pWrtShell->GetViewOptions()->getBrowseMode() ) - eZoom = static_cast<SvxZoomType>(static_cast<sal_uInt16>(rUserData.getToken(nOff, ';', nPos ).toInt32())); + eZoom = static_cast<SvxZoomType>(o3tl::narrowing<sal_uInt16>(o3tl::toInt32(o3tl::getToken(rUserData, nOff, ';', nPos )))); else { eZoom = SvxZoomType::PERCENT; ++nOff; } - bool bSelectObj = (0 != rUserData.getToken( nOff, ';', nPos ).toInt32()) + bool bSelectObj = (0 != o3tl::toInt32(o3tl::getToken(rUserData, nOff, ';', nPos ))) && m_pWrtShell->IsObjSelectable( aCursorPos ); // restore editing position @@ -1245,8 +1370,8 @@ void SwView::ReadUserData( const OUString &rUserData, bool bBrowse ) if( !m_sNewCursorPos.isEmpty() ) { sal_Int32 nIdx{ 0 }; - const tools::Long nXTmp = m_sNewCursorPos.getToken( 0, ';', nIdx ).toInt32(); - const tools::Long nYTmp = m_sNewCursorPos.getToken( 0, ';', nIdx ).toInt32(); + 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 ); @@ -1290,8 +1415,6 @@ void SwView::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue > const SwViewOption* pVOpt = m_pWrtShell->GetViewOptions(); sal_Int64 nX = rRect.Left(), nY = rRect.Top(), nLeft = rVis.Left(), nTop = rVis.Top(); - sal_Int64 nRight = nLeft; - sal_Int64 nBottom = LONG_MIN; sal_Int16 nZoomType = static_cast< sal_Int16 >(pVOpt->GetZoomType()); sal_Int16 nZoomFactor = static_cast < sal_Int16 > (pVOpt->GetZoom()); bool bViewLayoutBookMode = pVOpt->IsViewLayoutBookMode(); @@ -1299,48 +1422,38 @@ void SwView::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue > bool bSelectedFrame = ( m_pWrtShell->GetSelFrameType() != FrameTypeFlags::NONE ), bGotVisibleLeft = false, - bGotVisibleTop = false, bGotVisibleRight = false, - bGotVisibleBottom = false, bGotZoomType = 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 = convertMm100ToTwip( nX ); + nX = o3tl::toTwips(nX, o3tl::Length::mm100); } else if ( rValue.Name == "ViewTop" ) { rValue.Value >>= nY; - nY = convertMm100ToTwip( nY ); + nY = o3tl::toTwips(nY, o3tl::Length::mm100); } else if ( rValue.Name == "VisibleLeft" ) { rValue.Value >>= nLeft; - nLeft = convertMm100ToTwip( nLeft ); + nLeft = o3tl::toTwips(nLeft, o3tl::Length::mm100); bGotVisibleLeft = true; } else if ( rValue.Name == "VisibleTop" ) { rValue.Value >>= nTop; - nTop = convertMm100ToTwip( nTop ); + nTop = o3tl::toTwips(nTop, o3tl::Length::mm100); bGotVisibleTop = true; } - else if ( rValue.Name == "VisibleRight" ) - { - rValue.Value >>= nRight; - nRight = convertMm100ToTwip( nRight ); - bGotVisibleRight = true; - } - else if ( rValue.Name == "VisibleBottom" ) - { - rValue.Value >>= nBottom; - nBottom = convertMm100ToTwip( nBottom ); - bGotVisibleBottom = true; - } else if ( rValue.Name == "ZoomType" ) { rValue.Value >>= nZoomType; @@ -1371,6 +1484,11 @@ void SwView::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue > 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); @@ -1383,16 +1501,9 @@ void SwView::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue > SelectShell(); - if (!bGotVisibleBottom) - return; - Point aCursorPos( nX, nY ); - 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 ); SvxZoomType eZoom; if ( !m_pWrtShell->GetViewOptions()->getBrowseMode() ) @@ -1447,6 +1558,14 @@ void SwView::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue > 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 ); @@ -1481,10 +1600,10 @@ void SwView::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue > { if ( bGotVisibleLeft && bGotVisibleTop ) { - Point aTopLeft(aVis.TopLeft()); + Point aTopLeft(nLeft, nTop); // make sure the document is still centered const SwTwips lBorder = IsDocumentBorder() ? DOCUMENTBORDER : 2 * DOCUMENTBORDER; - SwTwips nEditWidth = GetEditWin().GetOutputSize().Width(); + SwTwips nEditWidth = GetEditWin().GetOutDev()->GetOutputSize().Width(); if(nEditWidth > (m_aDocSz.Width() + lBorder )) aTopLeft.setX( ( m_aDocSz.Width() + lBorder - nEditWidth ) / 2 ); else @@ -1496,8 +1615,6 @@ void SwView::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue > } SetVisArea( aTopLeft ); } - else if (bGotVisibleLeft && bGotVisibleTop && bGotVisibleRight && bGotVisibleBottom ) - SetVisArea( aVis ); } m_pWrtShell->LockView( true ); @@ -1514,7 +1631,7 @@ void SwView::WriteUserDataSequence ( uno::Sequence < beans::PropertyValue >& rSe std::vector<beans::PropertyValue> aVector; - sal_uInt16 nViewID( GetViewFrame()->GetCurViewId()); + sal_uInt16 nViewID( GetViewFrame().GetCurViewId()); aVector.push_back(comphelper::makePropertyValue("ViewId", "view" + OUString::number(nViewID))); aVector.push_back(comphelper::makePropertyValue("ViewLeft", convertTwipToMm100 ( rRect.Left() ))); @@ -1527,6 +1644,9 @@ void SwView::WriteUserDataSequence ( uno::Sequence < beans::PropertyValue >& rSe 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)); @@ -1545,6 +1665,9 @@ void SwView::WriteUserDataSequence ( uno::Sequence < beans::PropertyValue >& rSe 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 @@ -1566,9 +1689,9 @@ void SwView::ShowCursor( bool bOn ) m_pWrtShell->LockView( false ); } -ErrCode SwView::DoVerb( tools::Long nVerb ) +ErrCode SwView::DoVerb(sal_Int32 nVerb) { - if ( !GetViewFrame()->GetFrame().IsInPlace() ) + if ( !GetViewFrame().GetFrame().IsInPlace() ) { SwWrtShell &rSh = GetWrtShell(); const SelectionType nSel = rSh.GetSelectionType(); @@ -1586,7 +1709,7 @@ bool SwView::HasSelection( bool bText ) const : GetWrtShell().HasSelection(); } -OUString SwView::GetSelectionText( bool bCompleteWrds ) +OUString SwView::GetSelectionText( bool bCompleteWrds, bool /*bOnlyASample*/ ) { return GetSelectionTextParam( bCompleteWrds, true ); } @@ -1627,13 +1750,14 @@ void SwView::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) 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() ) + if ( &rBC == &GetViewFrame() ) { ResetSubShell(); } @@ -1704,10 +1828,9 @@ void SwView::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) FN_REDLINE_REJECT_ALL, 0 }; - GetViewFrame()->GetBindings().Invalidate(aSlotRedLine); + GetViewFrame().GetBindings().Invalidate(aSlotRedLine); } break; - default: break; } } @@ -1734,15 +1857,15 @@ void SwView::ScannerEventHdl() { const BitmapEx aScanBmp( VCLUnoHelper::GetBitmap( xBitmap ) ); - if( !!aScanBmp ) + if( !aScanBmp.IsEmpty() ) { Graphic aGrf(aScanBmp); - m_pWrtShell->Insert( OUString(), OUString(), aGrf ); + m_pWrtShell->InsertGraphic( OUString(), OUString(), aGrf ); } } } } - SfxBindings& rBind = GetViewFrame()->GetBindings(); + SfxBindings& rBind = GetViewFrame().GetBindings(); rBind.Invalidate( SID_TWAIN_SELECT ); rBind.Invalidate( SID_TWAIN_TRANSFER ); } @@ -1755,7 +1878,7 @@ void SwView::StopShellTimer() m_aTimer.Stop(); if ( m_bAttrChgNotifiedWithRegistrations ) { - GetViewFrame()->GetBindings().LEAVEREGISTRATIONS(); + GetViewFrame().GetBindings().LEAVEREGISTRATIONS(); m_bAttrChgNotifiedWithRegistrations = false; } SelectShell(); @@ -1765,10 +1888,10 @@ void SwView::StopShellTimer() bool SwView::PrepareClose( bool bUI ) { - SfxViewFrame* pVFrame = GetViewFrame(); - pVFrame->SetChildWindow( SwInputChild::GetChildWindowId(), false ); - if( pVFrame->GetDispatcher()->IsLocked() ) - pVFrame->GetDispatcher()->Lock(false); + SfxViewFrame& rVFrame = GetViewFrame(); + rVFrame.SetChildWindow( SwInputChild::GetChildWindowId(), false ); + if( rVFrame.GetDispatcher()->IsLocked() ) + rVFrame.GetDispatcher()->Lock(false); if ( m_pFormShell && !m_pFormShell->PrepareClose( bUI ) ) { @@ -1861,6 +1984,135 @@ 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) |