xref: /core/sw/source/uibase/uiview/view.cxx (revision 40ddb619)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <sal/config.h>
21 
22 #include <string_view>
23 
24 #include <config_features.h>
25 #include <config_wasm_strip.h>
26 
27 #include <stdlib.h>
28 #include <hintids.hxx>
29 #include <comphelper/string.hxx>
30 #include <comphelper/lok.hxx>
31 #include <o3tl/any.hxx>
32 #include <o3tl/string_view.hxx>
33 #include <officecfg/Office/Common.hxx>
34 #include <vcl/graph.hxx>
35 #include <vcl/inputctx.hxx>
36 #include <svl/eitem.hxx>
37 #include <unotools/configmgr.hxx>
38 #include <unotools/lingucfg.hxx>
39 #include <unotools/useroptions.hxx>
40 #include <sfx2/dispatch.hxx>
41 #include <sfx2/docfile.hxx>
42 #include <sfx2/objface.hxx>
43 #include <sfx2/request.hxx>
44 #include <svx/ruler.hxx>
45 #include <svx/srchdlg.hxx>
46 #include <svx/fmshell.hxx>
47 #include <svx/extrusionbar.hxx>
48 #include <svx/fontworkbar.hxx>
49 #include <svx/fmview.hxx>
50 #include <unotxvw.hxx>
51 #include <cmdid.h>
52 #include <svl/hint.hxx>
53 #include <swmodule.hxx>
54 #include <inputwin.hxx>
55 #include <uivwimp.hxx>
56 #include <edtwin.hxx>
57 #include <textsh.hxx>
58 #include <listsh.hxx>
59 #include <tabsh.hxx>
60 #include <grfsh.hxx>
61 #include <mediash.hxx>
62 #include <docsh.hxx>
63 #include <frmsh.hxx>
64 #include <olesh.hxx>
65 #include <drawsh.hxx>
66 #include <drawbase.hxx>
67 #include <drformsh.hxx>
68 #include <drwtxtsh.hxx>
69 #include <beziersh.hxx>
70 #include <navsh.hxx>
71 #include <globdoc.hxx>
72 #include <scroll.hxx>
73 #include <gloshdl.hxx>
74 #include <usrpref.hxx>
75 #include <srcview.hxx>
76 #include <doc.hxx>
77 #include <IDocumentUndoRedo.hxx>
78 #include <IDocumentSettingAccess.hxx>
79 #include <IDocumentDrawModelAccess.hxx>
80 #include <DocumentFieldsManager.hxx>
81 #include <IDocumentState.hxx>
82 #include <IDocumentLayoutAccess.hxx>
83 #include <drawdoc.hxx>
84 #include <wdocsh.hxx>
85 #include <wrtsh.hxx>
86 #include <barcfg.hxx>
87 #include <pview.hxx>
88 #include <swdtflvr.hxx>
89 #include <prtopt.hxx>
90 #include <unotxdoc.hxx>
91 #include <com/sun/star/frame/FrameSearchFlag.hpp>
92 #include <com/sun/star/frame/XLayoutManager.hpp>
93 #include <com/sun/star/scanner/ScannerContext.hpp>
94 #include <com/sun/star/scanner/XScannerManager2.hpp>
95 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
96 #include <com/sun/star/sdb/XDatabaseContext.hpp>
97 #include <com/sun/star/sdb/DatabaseContext.hpp>
98 #include <toolkit/helper/vclunohelper.hxx>
99 #include <sal/log.hxx>
100 
101 #include <formatclipboard.hxx>
102 #include <PostItMgr.hxx>
103 #include <annotsh.hxx>
104 #include <swruler.hxx>
105 #include <svx/theme/ThemeColorChangerCommon.hxx>
106 #include <com/sun/star/document/XDocumentProperties.hpp>
107 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
108 
109 #include <comphelper/propertyvalue.hxx>
110 #include <comphelper/servicehelper.hxx>
111 #include <sfx2/lokhelper.hxx>
112 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
113 #include <svtools/embedhlp.hxx>
114 #include <tools/UnitConversion.hxx>
115 
116 #include <svx/sdr/overlay/overlayselection.hxx>
117 #include <svx/sdr/overlay/overlayobject.hxx>
118 #include <svx/sdr/overlay/overlaymanager.hxx>
119 #include <svx/sdrpaintwindow.hxx>
120 #include <svx/svdview.hxx>
121 #include <node2lay.hxx>
122 #include <cntfrm.hxx>
123 
124 using namespace ::com::sun::star;
125 using namespace ::com::sun::star::uno;
126 using namespace ::com::sun::star::lang;
127 using namespace ::com::sun::star::scanner;
128 using namespace ::com::sun::star::sdb;
129 
130 #define SWVIEWFLAGS SfxViewShellFlags::HAS_PRINTOPTIONS
131 
132 // Statics. OMG.
133 
134 bool bDocSzUpdated = true;
135 
136 SvxSearchItem*  SwView::s_pSrchItem   = nullptr;
137 
138 bool            SwView::s_bExtra      = false;
139 bool            SwView::s_bFound      = false;
140 bool            SwView::s_bJustOpened = false;
141 
142 std::unique_ptr<SearchAttrItemList>  SwView::s_xSearchList;
143 std::unique_ptr<SearchAttrItemList>  SwView::s_xReplaceList;
144 
GetDispatcher()145 SfxDispatcher &SwView::GetDispatcher()
146 {
147     return *GetViewFrame().GetDispatcher();
148 }
149 
ImpSetVerb(SelectionType nSelType)150 void SwView::ImpSetVerb( SelectionType nSelType )
151 {
152     bool bResetVerbs = m_bVerbsActive;
153     if ( !GetViewFrame().GetFrame().IsInPlace() &&
154          (SelectionType::Ole|SelectionType::Graphic) & nSelType )
155     {
156         FlyProtectFlags eProtectFlags = m_pWrtShell->IsSelObjProtected(FlyProtectFlags::Content);
157         if (eProtectFlags == FlyProtectFlags::NONE || nSelType & SelectionType::Ole)
158         {
159             if ( nSelType & SelectionType::Ole )
160             {
161                 SetVerbs( GetWrtShell().GetOLEObject()->getSupportedVerbs() );
162                 m_bVerbsActive = true;
163                 bResetVerbs = false;
164             }
165         }
166     }
167     if ( bResetVerbs )
168     {
169         SetVerbs( Sequence< embed::VerbDescriptor >() );
170         m_bVerbsActive = false;
171     }
172 }
173 
174 // Called by the SwEditWin when it gets the focus.
175 
GotFocus() const176 void SwView::GotFocus() const
177 {
178     // if we got the focus, and the form shell *is* on the top of the dispatcher
179     // stack, then we need to rebuild the stack (the form shell doesn't belong to
180     // the top then)
181     const SfxDispatcher& rDispatcher = const_cast< SwView* >( this )->GetDispatcher();
182     SfxShell* pTopShell = rDispatcher.GetShell( 0 );
183     FmFormShell* pAsFormShell = dynamic_cast<FmFormShell*>( pTopShell  );
184     if ( pAsFormShell )
185     {
186         pAsFormShell->ForgetActiveControl();
187         const_cast< SwView* >( this )->AttrChangedNotify(nullptr);
188     }
189     else if ( m_pPostItMgr )
190     {
191         SwAnnotationShell* pAsAnnotationShell = dynamic_cast<SwAnnotationShell*>( pTopShell  );
192         if ( pAsAnnotationShell )
193         {
194             m_pPostItMgr->SetActiveSidebarWin(nullptr);
195             const_cast< SwView* >( this )->AttrChangedNotify(nullptr);
196         }
197     }
198     if (SwWrtShell* pWrtShell = GetWrtShellPtr())
199     {
200         SwWrtShell& rWrtShell = GetWrtShell();
201         rWrtShell.GetDoc()->getIDocumentLayoutAccess().SetCurrentViewShell( pWrtShell );
202         rWrtShell.GetDoc()->getIDocumentSettingAccess().set( DocumentSettingId::BROWSE_MODE,
203                                  rWrtShell.GetViewOptions()->getBrowseMode() );
204     }
205 }
206 
207 // called by the FormShell when a form control is focused. This is
208 // a request to put the form shell on the top of the dispatcher stack
209 
IMPL_LINK_NOARG(SwView,FormControlActivated,LinkParamNone *,void)210 IMPL_LINK_NOARG(SwView, FormControlActivated, LinkParamNone*, void)
211 {
212     // if a form control has been activated, and the form shell is not on the top
213     // of the dispatcher stack, then we need to activate it
214     const SfxDispatcher& rDispatcher = GetDispatcher();
215     const SfxShell* pTopShell = rDispatcher.GetShell( 0 );
216     const FmFormShell* pAsFormShell = dynamic_cast<const FmFormShell*>( pTopShell  );
217     if ( !pAsFormShell )
218     {
219         // if we're editing text currently, cancel this
220         SdrView *pSdrView = m_pWrtShell ? m_pWrtShell->GetDrawView() : nullptr;
221         if ( pSdrView && pSdrView->IsTextEdit() )
222             pSdrView->SdrEndTextEdit( true );
223 
224         AttrChangedNotify(nullptr);
225     }
226 }
227 
228 namespace
229 {
getLayoutManager(const SfxViewFrame & rViewFrame)230 uno::Reference<frame::XLayoutManager> getLayoutManager(const SfxViewFrame& rViewFrame)
231 {
232     uno::Reference<frame::XLayoutManager> xLayoutManager;
233     uno::Reference<beans::XPropertySet> xPropSet(rViewFrame.GetFrame().GetFrameInterface(),
234                                                  uno::UNO_QUERY);
235     if (xPropSet.is())
236     {
237         try
238         {
239             xLayoutManager.set(xPropSet->getPropertyValue(u"LayoutManager"_ustr), uno::UNO_QUERY);
240         }
241         catch (const Exception& e)
242         {
243             SAL_WARN("sw.ui", "Failure getting layout manager: " + e.Message);
244         }
245     }
246     return xLayoutManager;
247 }
248 }
249 
ShowUIElement(const OUString & sElementURL) const250 void SwView::ShowUIElement(const OUString& sElementURL) const
251 {
252     if (auto xLayoutManager = getLayoutManager(GetViewFrame()))
253     {
254         if (!xLayoutManager->getElement(sElementURL).is())
255         {
256             xLayoutManager->createElement(sElementURL);
257             xLayoutManager->showElement(sElementURL);
258         }
259     }
260 }
261 
SelectShell()262 void SwView::SelectShell()
263 {
264     // Attention: Maintain the SelectShell for the WebView additionally
265 
266     // In case of m_bDying, our SfxShells are already gone, don't try to select a shell at all.
267     if(m_bInDtor || m_bDying)
268         return;
269 
270     // Decision if the UpdateTable has to be called
271     bool bUpdateTable = false;
272     const SwFrameFormat* pCurTableFormat = m_pWrtShell->GetTableFormat();
273     if(pCurTableFormat && pCurTableFormat != m_pLastTableFormat)
274     {
275         bUpdateTable = true; // can only be executed later
276     }
277     m_pLastTableFormat = pCurTableFormat;
278 
279     //SEL_TBL and SEL_TBL_CELLS can be ORed!
280     SelectionType nNewSelectionType = m_pWrtShell->GetSelectionType()
281                                 & ~SelectionType::TableCell;
282 
283     // Determine if a different fly frame was selected.
284     bool bUpdateFly = false;
285     const SwFrameFormat* pCurFlyFormat = nullptr;
286     if (m_pWrtShell->IsSelFrameMode())
287     {
288         pCurFlyFormat = m_pWrtShell->GetFlyFrameFormat();
289     }
290     if (pCurFlyFormat && m_pLastFlyFormat && pCurFlyFormat != m_pLastFlyFormat)
291     {
292         // Only do an explicit update when switching between flys.
293         bUpdateFly = true;
294     }
295     m_pLastFlyFormat = pCurFlyFormat;
296 
297     if ( m_pFormShell && m_pFormShell->IsActiveControl() )
298         nNewSelectionType |= SelectionType::FormControl;
299 
300     if ( nNewSelectionType == m_nSelectionType )
301     {
302         GetViewFrame().GetBindings().InvalidateAll( false );
303         if ( m_nSelectionType & SelectionType::Ole ||
304              m_nSelectionType & SelectionType::Graphic )
305             // For graphs and OLE the verb can be modified of course!
306             ImpSetVerb( nNewSelectionType );
307 
308         if (bUpdateFly)
309         {
310             SfxViewFrame& rViewFrame = GetViewFrame();
311             uno::Reference<frame::XFrame> xFrame = rViewFrame.GetFrame().GetFrameInterface();
312             if (xFrame.is())
313             {
314                 // Invalidate cached dispatch objects.
315                 xFrame->contextChanged();
316             }
317         }
318     }
319     else
320     {
321 
322         SfxDispatcher &rDispatcher = GetDispatcher();
323         SwToolbarConfigItem *pBarCfg = SW_MOD()->GetToolbarConfig();
324 
325         if ( m_pShell )
326         {
327             rDispatcher.Flush();        // Really erase all cached shells
328             //Remember to the old selection which toolbar was visible
329             ToolbarId eId = rDispatcher.GetObjectBarId(SFX_OBJECTBAR_OBJECT);
330             if (eId != ToolbarId::None)
331                 pBarCfg->SetTopToolbar(m_nSelectionType, eId);
332 
333             for ( sal_uInt16 i = 0; true; ++i )
334             {
335                 SfxShell *pSfxShell = rDispatcher.GetShell( i );
336                 if  (  dynamic_cast< const SwBaseShell *>( pSfxShell ) !=  nullptr
337                     || dynamic_cast< const SwDrawTextShell *>( pSfxShell ) !=  nullptr
338                     || dynamic_cast< const svx::ExtrusionBar*>( pSfxShell ) !=  nullptr
339                     || dynamic_cast< const svx::FontworkBar*>( pSfxShell ) !=  nullptr
340                     || dynamic_cast< const SwAnnotationShell *>( pSfxShell ) !=  nullptr
341                     )
342                 {
343                     rDispatcher.Pop( *pSfxShell, SfxDispatcherPopFlags::POP_DELETE );
344                 }
345                 else if ( dynamic_cast< const FmFormShell *>( pSfxShell ) !=  nullptr )
346                 {
347                     rDispatcher.Pop( *pSfxShell );
348                 }
349                 else
350                     break;
351             }
352         }
353 
354         bool bInitFormShell = false;
355         if (!m_pFormShell)
356         {
357             bInitFormShell = true;
358             m_pFormShell = new FmFormShell( this );
359             m_pFormShell->SetControlActivationHandler( LINK( this, SwView, FormControlActivated ) );
360             StartListening(*m_pFormShell);
361         }
362 
363         bool bSetExtInpCntxt = false;
364         m_nSelectionType = nNewSelectionType;
365         ShellMode eShellMode;
366 
367         if ( !( m_nSelectionType & SelectionType::FormControl ) )
368             rDispatcher.Push( *m_pFormShell );
369 
370         m_pShell = new SwNavigationShell( *this );
371         rDispatcher.Push( *m_pShell );
372 
373         if ( m_nSelectionType & SelectionType::Ole )
374         {
375             eShellMode = ShellMode::Object;
376             m_pShell = new SwOleShell( *this );
377             rDispatcher.Push( *m_pShell );
378         }
379         else if ( m_nSelectionType & SelectionType::Frame
380             || m_nSelectionType & SelectionType::Graphic)
381         {
382             eShellMode = ShellMode::Frame;
383             m_pShell = new SwFrameShell( *this );
384             rDispatcher.Push( *m_pShell );
385             if(m_nSelectionType & SelectionType::Graphic )
386             {
387                 eShellMode = ShellMode::Graphic;
388                 m_pShell = new SwGrfShell( *this );
389                 rDispatcher.Push( *m_pShell );
390             }
391         }
392         else if ( m_nSelectionType & SelectionType::DrawObject )
393         {
394             eShellMode = ShellMode::Draw;
395             m_pShell = new SwDrawShell( *this );
396             rDispatcher.Push( *m_pShell );
397 
398             if ( m_nSelectionType & SelectionType::Ornament )
399             {
400                 eShellMode = ShellMode::Bezier;
401                 m_pShell = new SwBezierShell( *this );
402                 rDispatcher.Push( *m_pShell );
403             }
404 #if HAVE_FEATURE_AVMEDIA
405             else if( m_nSelectionType & SelectionType::Media )
406             {
407                 eShellMode = ShellMode::Media;
408                 m_pShell = new SwMediaShell( *this );
409                 rDispatcher.Push( *m_pShell );
410             }
411 #endif
412             if (m_nSelectionType & SelectionType::ExtrudedCustomShape)
413             {
414                 eShellMode = ShellMode::ExtrudedCustomShape;
415                 m_pShell = new svx::ExtrusionBar(this);
416                 rDispatcher.Push( *m_pShell );
417             }
418             if (m_nSelectionType & SelectionType::FontWork)
419             {
420                 eShellMode = ShellMode::FontWork;
421                 m_pShell = new svx::FontworkBar(this);
422                 rDispatcher.Push( *m_pShell );
423             }
424         }
425         else if ( m_nSelectionType & SelectionType::DbForm )
426         {
427             eShellMode = ShellMode::DrawForm;
428             m_pShell = new SwDrawFormShell( *this );
429 
430             rDispatcher.Push( *m_pShell );
431         }
432         else if ( m_nSelectionType & SelectionType::DrawObjectEditMode )
433         {
434             bSetExtInpCntxt = true;
435             eShellMode = ShellMode::DrawText;
436             rDispatcher.Push( *(new SwBaseShell( *this )) );
437             m_pShell = new SwDrawTextShell( *this );
438             rDispatcher.Push( *m_pShell );
439         }
440         else if ( m_nSelectionType & SelectionType::PostIt )
441         {
442             eShellMode = ShellMode::PostIt;
443             m_pShell = new SwAnnotationShell( *this );
444             rDispatcher.Push( *m_pShell );
445         }
446         else
447         {
448             bSetExtInpCntxt = true;
449             eShellMode = ShellMode::Text;
450             if ( m_nSelectionType & SelectionType::NumberList )
451             {
452                 eShellMode = ShellMode::ListText;
453                 m_pShell = new SwListShell( *this );
454                 rDispatcher.Push( *m_pShell );
455             }
456             m_pShell = new SwTextShell(*this);
457             rDispatcher.Push( *m_pShell );
458             if ( m_nSelectionType & SelectionType::Table )
459             {
460                 eShellMode = eShellMode == ShellMode::ListText ? ShellMode::TableListText
461                                                         : ShellMode::TableText;
462                 m_pShell = new SwTableShell( *this );
463                 rDispatcher.Push( *m_pShell );
464             }
465         }
466 
467         if ( m_nSelectionType & SelectionType::FormControl )
468             rDispatcher.Push( *m_pFormShell );
469 
470         m_pViewImpl->SetShellMode(eShellMode);
471         ImpSetVerb( m_nSelectionType );
472 
473         if( !GetDocShell()->IsReadOnly() )
474         {
475             if( bSetExtInpCntxt && GetWrtShell().HasReadonlySel() )
476                 bSetExtInpCntxt = false;
477 
478             InputContext aCntxt( GetEditWin().GetInputContext() );
479             aCntxt.SetOptions( bSetExtInpCntxt
480                                 ? (aCntxt.GetOptions() |
481                                         ( InputContextFlags::Text |
482                                             InputContextFlags::ExtText ))
483                                 : (aCntxt.GetOptions() & ~
484                                         InputContextFlags( InputContextFlags::Text |
485                                             InputContextFlags::ExtText )) );
486             GetEditWin().SetInputContext( aCntxt );
487         }
488 
489         // Show Mail Merge toolbar initially for documents with Database fields
490         if (!m_bInitOnceCompleted && GetWrtShell().IsAnyDatabaseFieldInDoc() && !comphelper::IsFuzzing())
491             ShowUIElement(u"private:resource/toolbar/mailmerge"_ustr);
492 
493         // Activate the toolbar to the new selection which also was active last time.
494         // Before a flush () must be, but does not affect the UI according to MBA and
495         // is not a performance problem.
496         // TODO/LATER: maybe now the Flush() command is superfluous?!
497         rDispatcher.Flush();
498 
499         Point aPnt = GetEditWin().OutputToScreenPixel(GetEditWin().GetPointerPosPixel());
500         aPnt = GetEditWin().PixelToLogic(aPnt);
501         GetEditWin().UpdatePointer(aPnt);
502 
503         SdrView* pDView = GetWrtShell().GetDrawView();
504         if ( bInitFormShell && pDView )
505             m_pFormShell->SetView(dynamic_cast<FmFormView*>( pDView) );
506 
507     }
508     // Opportune time for the communication with OLE objects?
509     if ( GetDocShell()->GetDoc()->IsOLEPrtNotifyPending() )
510         GetDocShell()->GetDoc()->PrtOLENotify( false );
511 
512     // now the table-update
513     if(bUpdateTable)
514         m_pWrtShell->UpdateTable();
515 
516     GetViewImpl()->GetUNOObject_Impl()->NotifySelChanged();
517 
518     m_bInitOnceCompleted = true;
519 }
520 
521 // Interaction: AttrChangedNotify() and TimeoutHdl.
522 // No Update if actions are still open, since the cursor on the core side
523 // can be somewhere in no man's land.
524 // But since we can no longer supply status and we want instead lock
525 // the dispatcher.
526 
527 extern "C"
528 {
lcl_CmpIds(const void * pFirst,const void * pSecond)529     static int lcl_CmpIds( const void *pFirst, const void *pSecond)
530     {
531         return *static_cast<sal_uInt16 const *>(pFirst) - *static_cast<sal_uInt16 const *>(pSecond);
532     }
533 }
534 
IMPL_LINK_NOARG(SwView,AttrChangedNotify,LinkParamNone *,void)535 IMPL_LINK_NOARG(SwView, AttrChangedNotify, LinkParamNone*, void)
536 {
537     if ( GetEditWin().IsChainMode() )
538         GetEditWin().SetChainMode( false );
539 
540     if (!m_pWrtShell || !GetDocShell())
541     {
542         return;
543     }
544 
545     //Opt: Not if PaintLocked. During unlock a notify will be once more triggered.
546     if( !m_pWrtShell->IsPaintLocked() && !g_bNoInterrupt &&
547         GetDocShell()->IsReadOnly() )
548         CheckReadonlyState();
549 
550     if( !m_pWrtShell->IsPaintLocked() && !g_bNoInterrupt )
551         CheckReadonlySelection();
552 
553     if( !m_bAttrChgNotified )
554     {
555         if (m_pWrtShell->ActionPend() || g_bNoInterrupt ||
556              GetDispatcher().IsLocked() ||               //do not confuse the SFX
557              GetViewFrame().GetBindings().IsInUpdate() )//do not confuse the SFX
558         {
559             m_bAttrChgNotified = true;
560             m_aTimer.Start();
561 
562             const SfxBoolItem *pItem =
563                 GetObjectShell()->GetMedium()->GetItemSet().
564                                     GetItemIfSet( SID_HIDDEN, false );
565             if ( !pItem || !pItem->GetValue() )
566             {
567                 GetViewFrame().GetBindings().ENTERREGISTRATIONS();
568                 m_bAttrChgNotifiedWithRegistrations = true;
569             }
570 
571         }
572         else
573             SelectShell();
574 
575     }
576 
577     // change ui if cursor is at a SwPostItField
578     if (m_pPostItMgr)
579     {
580         // only perform the code that is needed to determine, if at the
581         // actual cursor position is a post-it field
582         m_pPostItMgr->SetShadowState( m_pWrtShell->GetPostItFieldAtCursor() );
583     }
584 }
585 
IMPL_LINK_NOARG(SwView,TimeoutHdl,Timer *,void)586 IMPL_LINK_NOARG(SwView, TimeoutHdl, Timer *, void)
587 {
588     if (m_pWrtShell->ActionPend() || g_bNoInterrupt)
589     {
590         m_aTimer.Start();
591         return;
592     }
593 
594     if ( m_bAttrChgNotifiedWithRegistrations )
595     {
596         GetViewFrame().GetBindings().LEAVEREGISTRATIONS();
597         m_bAttrChgNotifiedWithRegistrations = false;
598     }
599 
600     CheckReadonlyState();
601     CheckReadonlySelection();
602 
603     bool bOldUndo = m_pWrtShell->DoesUndo();
604     m_pWrtShell->DoUndo( false );
605     SelectShell();
606     m_pWrtShell->DoUndo( bOldUndo );
607     m_bAttrChgNotified = false;
608     GetViewImpl()->GetUNOObject_Impl()->NotifySelChanged();
609 }
610 
CheckReadonlyState()611 void SwView::CheckReadonlyState()
612 {
613     SfxDispatcher &rDis = GetDispatcher();
614     // To be able to recognize if it is already disabled!
615     SfxItemState eStateRO, eStateProtAll;
616     SfxPoolItemHolder aResult;
617     // Query the status from a slot which is only known to us.
618     // Otherwise the slot is known from other; like the BasicIde
619     eStateRO = rDis.QueryState(FN_INSERT_BOOKMARK, aResult);
620     eStateProtAll = rDis.QueryState(FN_EDIT_REGION, aResult);
621     bool bChgd = false;
622 
623     if ( !m_pWrtShell->IsCursorReadonly() )
624     {
625         static sal_uInt16 aROIds[] =
626         {
627             SID_DELETE,                 FN_BACKSPACE,               FN_SHIFT_BACKSPACE,
628             SID_UNDO,
629             SID_REDO,                   SID_REPEAT,                 SID_PASTE,
630             SID_PASTE_UNFORMATTED,      FN_PASTE_NESTED_TABLE,      FN_TABLE_PASTE_ROW_BEFORE,
631             FN_TABLE_PASTE_COL_BEFORE,  SID_PASTE_SPECIAL,          SID_SBA_BRW_INSERT,
632             SID_BACKGROUND_COLOR,       FN_INSERT_BOOKMARK,         SID_CHARMAP_CONTROL,
633             SID_CHARMAP,                                            FN_INSERT_SOFT_HYPHEN,
634             FN_INSERT_HARDHYPHEN,       FN_INSERT_HARD_SPACE,       FN_INSERT_NNBSP,
635             FN_INSERT_BREAK,            FN_INSERT_LINEBREAK,        FN_INSERT_COLUMN_BREAK,
636             FN_INSERT_BREAK_DLG,        FN_INSERT_CONTENT_CONTROL,  FN_INSERT_CHECKBOX_CONTENT_CONTROL,
637             FN_INSERT_DROPDOWN_CONTENT_CONTROL, FN_INSERT_PICTURE_CONTENT_CONTROL,
638             FN_INSERT_DATE_CONTENT_CONTROL, FN_INSERT_PLAIN_TEXT_CONTENT_CONTROL,
639             FN_INSERT_COMBO_BOX_CONTENT_CONTROL,
640             FN_DELETE_SENT,             FN_DELETE_BACK_SENT,        FN_DELETE_WORD,
641             FN_DELETE_BACK_WORD,        FN_DELETE_LINE,             FN_DELETE_BACK_LINE,
642             FN_DELETE_PARA,             FN_DELETE_BACK_PARA,        FN_DELETE_WHOLE_LINE,
643             FN_CALCULATE,               FN_FORMAT_RESET,
644             FN_POSTIT,                  FN_JAVAEDIT,                SID_ATTR_PARA_ADJUST_LEFT,
645             SID_ATTR_PARA_ADJUST_RIGHT, SID_ATTR_PARA_ADJUST_CENTER,SID_ATTR_PARA_ADJUST_BLOCK,
646             SID_ATTR_PARA_LINESPACE_10, SID_ATTR_PARA_LINESPACE_15, SID_ATTR_PARA_LINESPACE_20,
647             SID_ATTR_CHAR_FONT,         SID_ATTR_CHAR_FONTHEIGHT,   SID_ATTR_CHAR_COLOR_BACKGROUND,
648             SID_ATTR_CHAR_BACK_COLOR,
649             SID_ATTR_CHAR_COLOR_BACKGROUND_EXT,                     SID_ATTR_CHAR_COLOR_EXT,
650             SID_ATTR_CHAR_COLOR,        SID_ATTR_CHAR_WEIGHT,       SID_ATTR_CHAR_POSTURE,
651             SID_ATTR_CHAR_OVERLINE,
652             SID_ATTR_CHAR_UNDERLINE,    SID_ATTR_FLASH,             SID_ATTR_CHAR_STRIKEOUT,
653             SID_ULINE_VAL_SINGLE,       SID_ULINE_VAL_DOUBLE,       SID_ULINE_VAL_DOTTED,
654             SID_ATTR_CHAR_CONTOUR,      SID_ATTR_CHAR_SHADOWED,
655             SID_ATTR_CHAR_AUTOKERN,     SID_ATTR_CHAR_ESCAPEMENT,   FN_SET_SUPER_SCRIPT,
656             FN_SET_SUB_SCRIPT,          SID_ATTR_CHAR_CASEMAP,      SID_ATTR_CHAR_LANGUAGE,
657             SID_ATTR_CHAR_KERNING,      SID_CHAR_DLG,               SID_ATTR_CHAR_WORDLINEMODE,
658             FN_GROW_FONT_SIZE,          FN_SHRINK_FONT_SIZE,        FN_TXTATR_INET,
659             FN_FORMAT_DROPCAPS,         SID_ATTR_PARA_ADJUST,       SID_ATTR_PARA_LINESPACE,
660             SID_ATTR_PARA_SPLIT,        SID_ATTR_PARA_KEEP,         SID_ATTR_PARA_WIDOWS,
661             SID_ATTR_PARA_ORPHANS,
662             SID_ATTR_PARA_MODEL,        SID_PARA_DLG,
663             FN_SELECT_PARA,             SID_DEC_INDENT,
664             SID_INC_INDENT
665         };
666         static bool bFirst = true;
667         if ( bFirst )
668         {
669             qsort( static_cast<void*>(aROIds), SAL_N_ELEMENTS(aROIds), sizeof(sal_uInt16), lcl_CmpIds );
670             bFirst = false;
671         }
672         if ( SfxItemState::DISABLED == eStateRO )
673         {
674             rDis.SetSlotFilter( SfxSlotFilterState::ENABLED_READONLY, aROIds );
675             bChgd = true;
676         }
677     }
678     else if( m_pWrtShell->IsAllProtect() )
679     {
680         if ( SfxItemState::DISABLED == eStateProtAll )
681         {
682             static sal_uInt16 aAllProtIds[] = { SID_SAVEDOC, FN_EDIT_REGION };
683             static bool bAllProtFirst = true;
684             if ( bAllProtFirst )
685             {
686                 qsort( static_cast<void*>(aAllProtIds), SAL_N_ELEMENTS(aAllProtIds), sizeof(sal_uInt16), lcl_CmpIds );
687                 bAllProtFirst = false;
688             }
689             rDis.SetSlotFilter( SfxSlotFilterState::ENABLED_READONLY, aAllProtIds );
690             bChgd = true;
691         }
692     }
693     else if ( SfxItemState::DISABLED != eStateRO ||
694                 SfxItemState::DISABLED != eStateProtAll )
695     {
696         bChgd = true;
697         rDis.SetSlotFilter();
698     }
699     if ( bChgd )
700         GetViewFrame().GetBindings().InvalidateAll(true);
701 }
702 
CheckReadonlySelection()703 void SwView::CheckReadonlySelection()
704 {
705     SfxDisableFlags nDisableFlags = SfxDisableFlags::NONE;
706     SfxDispatcher &rDis = GetDispatcher();
707 
708     if( m_pWrtShell->HasReadonlySel() &&
709         ( !m_pWrtShell->GetDrawView() ||
710             !m_pWrtShell->GetDrawView()->GetMarkedObjectList().GetMarkCount() ))
711         nDisableFlags |= SfxDisableFlags::SwOnProtectedCursor;
712 
713     if( (SfxDisableFlags::SwOnProtectedCursor & nDisableFlags ) !=
714         (SfxDisableFlags::SwOnProtectedCursor & rDis.GetDisableFlags() ) )
715     {
716         // Additionally move at the Window the InputContext, so that
717         // in japanese / chinese versions the external input will be
718         // turned on or off. This but only if the correct shell is on
719         // the stack.
720         switch( m_pViewImpl->GetShellMode() )
721         {
722         case ShellMode::Text:
723         case ShellMode::ListText:
724         case ShellMode::TableText:
725         case ShellMode::TableListText:
726             {
727 // Temporary solution!!! Should set the font of the current insertion point
728 //         at each cursor movement, so outside of this "if". But TH does not
729 //         evaluates the font at this time and the "purchase" appears to me
730 //         as too expensive.
731 //         Moreover, we don't have a font, but only attributes from which the
732 //         text formatting and the correct font will be build together.
733 
734                 InputContext aCntxt( GetEditWin().GetInputContext() );
735                 aCntxt.SetOptions( SfxDisableFlags::SwOnProtectedCursor & nDisableFlags
736                                     ? (aCntxt.GetOptions() & ~
737                                             InputContextFlags( InputContextFlags::Text |
738                                                 InputContextFlags::ExtText ))
739                                     : (aCntxt.GetOptions() |
740                                             ( InputContextFlags::Text |
741                                                 InputContextFlags::ExtText )) );
742                 GetEditWin().SetInputContext( aCntxt );
743             }
744             break;
745         default:
746             ;
747         }
748 
749     }
750 
751     if( nDisableFlags != rDis.GetDisableFlags() )
752     {
753         rDis.SetDisableFlags( nDisableFlags );
754         GetViewFrame().GetBindings().InvalidateAll( true );
755     }
756 }
757 
SwView(SfxViewFrame & _rFrame,SfxViewShell * pOldSh)758 SwView::SwView(SfxViewFrame& _rFrame, SfxViewShell* pOldSh)
759     : SfxViewShell(_rFrame, SWVIEWFLAGS),
760     m_aTimer( "sw::SwView m_aTimer" ),
761     m_nNewPage(USHRT_MAX),
762     m_nOldPageNum(0),
763     m_pNumRuleNodeFromDoc(nullptr),
764     m_pEditWin( VclPtr<SwEditWin>::Create( &_rFrame.GetWindow(), *this ) ),
765     m_pShell(nullptr),
766     m_pFormShell(nullptr),
767     m_pHScrollbar(nullptr),
768     m_pVScrollbar(nullptr),
769     m_pLastTableFormat(nullptr),
770     m_pLastFlyFormat(nullptr),
771     m_pFormatClipboard(new SwFormatClipboard()),
772     m_nSelectionType( SelectionType::All ),
773     m_nPageCnt(0),
774     m_nDrawSfxId( USHRT_MAX ),
775     m_nFormSfxId( USHRT_MAX ),
776     m_eFormObjKind(SdrObjKind::NONE),
777     m_nLastPasteDestination( static_cast<SotExchangeDest>(0xFFFF) ),
778     m_nLeftBorderDistance( 0 ),
779     m_nRightBorderDistance( 0 ),
780     m_eLastSearchCommand( static_cast<SvxSearchCmd>(0xFFFF) ),
781     m_bWheelScrollInProgress(false),
782     m_bCenterCursor(false),
783     m_bTopCursor(false),
784     m_bTabColFromDoc(false),
785     m_bTabRowFromDoc(false),
786     m_bSetTabColFromDoc(false),
787     m_bSetTabRowFromDoc(false),
788     m_bAttrChgNotified(false),
789     m_bAttrChgNotifiedWithRegistrations(false),
790     m_bVerbsActive(false),
791     m_bDrawRotate(false),
792     m_bDrawSelMode(true),
793     m_bShowAtResize(true),
794     m_bInOuterResizePixel(false),
795     m_bInInnerResizePixel(false),
796     m_bPasteState(false),
797     m_bPasteSpecialState(false),
798     m_bInMailMerge(false),
799     m_bInDtor(false),
800     m_bOldShellWasPagePreview(false),
801     m_bIsPreviewDoubleClick(false),
802     m_bMakeSelectionVisible(false),
803     m_bForceChangesToolbar(true),
804     m_nLOKPageUpDownOffset(0),
805     m_aBringToAttentionBlinkTimer("SwView m_aBringToAttentionBlinkTimer"),
806     m_nBringToAttentionBlinkTimeOutsRemaining(0)
807 {
808     static bool bRequestDoubleBuffering = getenv("VCL_DOUBLEBUFFERING_ENABLE");
809     if (bRequestDoubleBuffering)
810         m_pEditWin->RequestDoubleBuffering(true);
811 
812     // According to discussion with MBA and further
813     // investigations, no old SfxViewShell will be set as parameter <pOldSh>,
814     // if function "New Window" is performed to open an additional view beside
815     // an already existing one.
816     // If the view is switch from one to another, the 'old' view is given by
817     // parameter <pOldSh>.
818 
819     bDocSzUpdated = true;
820 
821     static bool bFuzzing = comphelper::IsFuzzing();
822 
823     if (!bFuzzing)
824     {
825         CreateScrollbar( true );
826         CreateScrollbar( false );
827     }
828 
829     m_pViewImpl.reset(new SwView_Impl(this));
830     SetName(u"View"_ustr);
831     SetWindow( m_pEditWin );
832 
833     m_aTimer.SetTimeout( 120 );
834 
835     SwDocShell& rDocSh = dynamic_cast<SwDocShell&>(*_rFrame.GetObjectShell());
836     bool bOldModifyFlag = rDocSh.IsEnableSetModified();
837     if (bOldModifyFlag)
838         rDocSh.EnableSetModified( false );
839     // HACK: SwDocShell has some cached font info, VCL informs about font updates,
840     // but loading of docs with embedded fonts happens after SwDocShell is created
841     // but before SwEditWin (which handles the VCL event) is created. So update
842     // manually.
843     if (rDocSh.GetDoc()->getIDocumentSettingAccess().get( DocumentSettingId::EMBED_FONTS ))
844         rDocSh.UpdateFontList();
845     bool bWebDShell = dynamic_cast<const SwWebDocShell*>(&rDocSh) !=  nullptr;
846 
847     const SwMasterUsrPref *pUsrPref = SW_MOD()->GetUsrPref(bWebDShell);
848     SwViewOption aUsrPref( *pUsrPref);
849 
850     //! get lingu options without loading lingu DLL
851     SvtLinguOptions aLinguOpt;
852     SvtLinguConfig().GetOptions( aLinguOpt );
853     aUsrPref.SetOnlineSpell( aLinguOpt.bIsSpellAuto );
854 
855     bool bOldShellWasSrcView = false;
856 
857     // determine if there is an existing view for
858     // document
859     SfxViewShell* pExistingSh = nullptr;
860     if ( pOldSh )
861     {
862         pExistingSh = pOldSh;
863         // determine type of existing view
864         if (SwPagePreview* pPagePreview = dynamic_cast<SwPagePreview *>(pExistingSh))
865         {
866             m_sSwViewData = pPagePreview->GetPrevSwViewData();
867             m_sNewCursorPos = pPagePreview->GetNewCursorPos();
868             m_nNewPage = pPagePreview->GetNewPage();
869             m_bOldShellWasPagePreview = true;
870             m_bIsPreviewDoubleClick = !m_sNewCursorPos.isEmpty() || m_nNewPage != USHRT_MAX;
871         }
872         else if (dynamic_cast<const SwSrcView *>(pExistingSh) != nullptr)
873             bOldShellWasSrcView = true;
874     }
875 
876     SAL_INFO( "sw.ui", "before create WrtShell" );
877     if (SwView *pView = dynamic_cast<SwView*>(pExistingSh))
878     {
879         m_pWrtShell.reset(new SwWrtShell(*pView->m_pWrtShell, m_pEditWin, *this));
880     }
881     else if (SwWrtShell *pWrtShell = dynamic_cast<SwWrtShell*>(rDocSh.GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell()))
882     {
883         m_pWrtShell.reset(new SwWrtShell(*pWrtShell, m_pEditWin, *this));
884     }
885     else
886     {
887         SwDoc& rDoc = *rDocSh.GetDoc();
888 
889         if( !bOldShellWasSrcView && bWebDShell && !m_bOldShellWasPagePreview )
890             aUsrPref.setBrowseMode( true );
891         else
892             aUsrPref.setBrowseMode( rDoc.getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE) );
893 
894         //For the BrowseMode we do not assume a factor.
895         if( aUsrPref.getBrowseMode() && aUsrPref.GetZoomType() != SvxZoomType::PERCENT )
896         {
897             aUsrPref.SetZoomType( SvxZoomType::PERCENT );
898             aUsrPref.SetZoom( 100 );
899         }
900         if (rDocSh.IsPreview())
901         {
902             aUsrPref.SetZoomType( SvxZoomType::WHOLEPAGE );
903             aUsrPref.SetViewLayoutBookMode( false );
904             aUsrPref.SetViewLayoutColumns( 1 );
905         }
906         m_pWrtShell.reset(new SwWrtShell(rDoc, m_pEditWin, *this, &aUsrPref));
907         // creating an SwView from a SwPagePreview needs to
908         // add the SwViewShell to the ring of the other SwViewShell(s)
909         if(m_bOldShellWasPagePreview)
910         {
911             SwViewShell& rPreviewViewShell = *static_cast<SwPagePreview*>(pExistingSh)->GetViewShell();
912             m_pWrtShell->MoveTo(&rPreviewViewShell);
913             // to update the field command et.al. if necessary
914             const SwViewOption* pPreviewOpt = rPreviewViewShell.GetViewOptions();
915             if( pPreviewOpt->IsFieldName() != aUsrPref.IsFieldName() ||
916                     pPreviewOpt->IsShowHiddenField() != aUsrPref.IsShowHiddenField() ||
917                     pPreviewOpt->IsShowHiddenPara() != aUsrPref.IsShowHiddenPara() ||
918                     pPreviewOpt->IsShowHiddenChar() != aUsrPref.IsShowHiddenChar() )
919                 rPreviewViewShell.ApplyViewOptions(aUsrPref);
920             // reset design mode at draw view for form
921             // shell, if needed.
922             if ( static_cast<SwPagePreview*>(pExistingSh)->ResetFormDesignMode() &&
923                  m_pWrtShell->HasDrawView() )
924             {
925                 SdrView* pDrawView = m_pWrtShell->GetDrawView();
926                 pDrawView->SetDesignMode( static_cast<SwPagePreview*>(pExistingSh)->FormDesignModeToReset() );
927             }
928         }
929     }
930     SAL_INFO( "sw.ui", "after create WrtShell" );
931     m_pHRuler = VclPtr<SwCommentRuler>::Create(m_pWrtShell.get(), &GetViewFrame().GetWindow(), m_pEditWin,
932                 SvxRulerSupportFlags::TABS |
933                 SvxRulerSupportFlags::PARAGRAPH_MARGINS |
934                 SvxRulerSupportFlags::BORDERS |
935                 SvxRulerSupportFlags::NEGATIVE_MARGINS|
936                 SvxRulerSupportFlags::REDUCED_METRIC,
937                 GetViewFrame().GetBindings(),
938                 WB_STDRULER | WB_EXTRAFIELD | WB_BORDER);
939 
940     m_pVRuler = VclPtr<SvxRuler>::Create(&GetViewFrame().GetWindow(), m_pEditWin,
941                 SvxRulerSupportFlags::TABS |
942                 SvxRulerSupportFlags::PARAGRAPH_MARGINS_VERTICAL |
943                 SvxRulerSupportFlags::BORDERS |
944                 SvxRulerSupportFlags::NEGATIVE_MARGINS|
945                 SvxRulerSupportFlags::REDUCED_METRIC,
946                 GetViewFrame().GetBindings(),
947                 WB_VSCROLL | WB_EXTRAFIELD | WB_BORDER);
948 
949     // assure that modified state of document
950     // isn't reset, if document is already modified.
951     const bool bIsDocModified = m_pWrtShell->GetDoc()->getIDocumentState().IsModified();
952 
953     // Thus among other things, the HRuler is not displayed in the read-only case.
954     aUsrPref.SetReadonly( m_pWrtShell->GetViewOptions()->IsReadonly() );
955 
956     // no margin for OLE!
957     Size aBrwsBorder;
958     if( SfxObjectCreateMode::EMBEDDED != rDocSh.GetCreateMode() )
959         aBrwsBorder = GetMargin();
960 
961     m_pWrtShell->SetBrowseBorder( aBrwsBorder );
962 
963     // In CTOR no shell changes may take place, which must be temporarily stored
964     // with the timer. Otherwise, the SFX removes them from the stack!
965     bool bOld = g_bNoInterrupt;
966     g_bNoInterrupt = true;
967 
968     m_pHRuler->SetActive();
969     m_pVRuler->SetActive();
970 
971     SfxViewFrame& rViewFrame = GetViewFrame();
972 
973     StartListening(rViewFrame, DuplicateHandling::Prevent);
974     StartListening(rDocSh, DuplicateHandling::Prevent);
975 
976     // Set Zoom-factor from HRuler
977     Fraction aZoomFract( aUsrPref.GetZoom(), 100 );
978     m_pHRuler->SetZoom( aZoomFract );
979     m_pVRuler->SetZoom( aZoomFract );
980     m_pHRuler->SetDoubleClickHdl(LINK( this, SwView, ExecRulerClick ));
981     FieldUnit eMetric = pUsrPref->GetHScrollMetric();
982     m_pHRuler->SetUnit( eMetric );
983 
984     eMetric = pUsrPref->GetVScrollMetric();
985     m_pVRuler->SetUnit( eMetric );
986 
987     m_pHRuler->SetCharWidth( 371 );  // default character width
988     m_pVRuler->SetLineHeight( 551 );  // default line height
989 
990     // Set DocShell
991     m_xGlueDocShell.reset(new SwViewGlueDocShell(*this, rDocSh));
992     m_pPostItMgr.reset(new SwPostItMgr(this));
993 
994     // Check and process the DocSize. Via the handler, the shell could not
995     // be found, because the shell is not known in the SFX management
996     // within the CTOR phase.
997     DocSzChgd( m_pWrtShell->GetDocSize() );
998 
999         // Set AttrChangedNotify link
1000     m_pWrtShell->SetChgLnk(LINK(this, SwView, AttrChangedNotify));
1001 
1002     if (rDocSh.GetCreateMode() == SfxObjectCreateMode::EMBEDDED &&
1003         !rDocSh.GetVisArea(ASPECT_CONTENT).IsEmpty())
1004         SetVisArea(rDocSh.GetVisArea(ASPECT_CONTENT),false);
1005 
1006     SAL_WARN_IF(
1007         officecfg::Office::Common::Undo::Steps::get() <= 0,
1008         "sw.ui", "/org.openoffice.Office.Common/Undo/Steps <= 0");
1009     if (!bFuzzing && 0 < officecfg::Office::Common::Undo::Steps::get())
1010     {
1011         m_pWrtShell->DoUndo();
1012     }
1013 
1014     const bool bBrowse = m_pWrtShell->GetViewOptions()->getBrowseMode();
1015     // Disable "multiple window"
1016     SetNewWindowAllowed(!bBrowse);
1017     // End of disabled multiple window
1018 
1019     m_bVScrollbarEnabled = aUsrPref.IsViewVScrollBar();
1020     m_bHScrollbarEnabled = aUsrPref.IsViewHScrollBar();
1021     if (m_pHScrollbar)
1022         m_pHScrollbar->SetAuto(bBrowse);
1023     if( aUsrPref.IsViewHRuler() )
1024         CreateTab();
1025     if( aUsrPref.IsViewVRuler() )
1026         CreateVRuler();
1027 
1028     m_pWrtShell->SetUIOptions( aUsrPref );
1029     m_pWrtShell->SetReadOnlyAvailable( aUsrPref.IsCursorInProtectedArea() );
1030 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
1031     m_pWrtShell->ApplyAccessibilityOptions();
1032 #endif
1033 
1034     if( m_pWrtShell->GetDoc()->getIDocumentState().IsUpdateExpField() )
1035     {
1036         if (m_pWrtShell->GetDoc()->GetDocumentFieldsManager().containsUpdatableFields())
1037         {
1038             CurrShell aCurr(m_pWrtShell.get());
1039             m_pWrtShell->StartAction();
1040             m_pWrtShell->CalcLayout();
1041             m_pWrtShell->GetDoc()->getIDocumentFieldsAccess().UpdateFields(false);
1042             m_pWrtShell->EndAction();
1043         }
1044         m_pWrtShell->GetDoc()->getIDocumentState().SetUpdateExpFieldStat( false );
1045     }
1046 
1047     // Update all tables if necessary:
1048     if( m_pWrtShell->GetDoc()->IsUpdateTOX() )
1049     {
1050         SfxRequest aSfxRequest( FN_UPDATE_TOX, SfxCallMode::SLOT, GetPool() );
1051         Execute( aSfxRequest );
1052         m_pWrtShell->GetDoc()->SetUpdateTOX( false );     // reset again
1053         m_pWrtShell->SttEndDoc(true);
1054     }
1055 
1056     // No ResetModified, if there is already a view to this doc.
1057     SfxViewFrame& rVFrame = GetViewFrame();
1058     SfxViewFrame* pFirst = SfxViewFrame::GetFirst(&rDocSh);
1059     // Currently(360) the view is registered firstly after the CTOR,
1060     // the following expression is also working if this changes.
1061     // If the modification cannot be canceled by undo, then do NOT set
1062     // the modify back.
1063     // no reset of modified state, if document
1064     // was already modified.
1065     if (!m_pWrtShell->GetDoc()->GetIDocumentUndoRedo().IsUndoNoResetModified() &&
1066          ( !pFirst || pFirst == &rVFrame ) &&
1067          !bIsDocModified )
1068     {
1069         m_pWrtShell->ResetModified();
1070     }
1071 
1072     g_bNoInterrupt = bOld;
1073 
1074     // If a new GlobalDoc will be created, the navigator will also be generated.
1075     if( dynamic_cast<const SwGlobalDocShell*>(&rDocSh) != nullptr &&
1076         !rVFrame.GetChildWindow( SID_NAVIGATOR ))
1077     {
1078         SfxBoolItem aNavi(SID_NAVIGATOR, true);
1079         GetDispatcher().ExecuteList(SID_NAVIGATOR, SfxCallMode::ASYNCHRON, { &aNavi });
1080     }
1081 
1082     uno::Reference< frame::XFrame >  xFrame = rVFrame.GetFrame().GetFrameInterface();
1083 
1084     uno::Reference< frame::XFrame >  xBeamerFrame = xFrame->findFrame(
1085             u"_beamer"_ustr, frame::FrameSearchFlag::CHILDREN);
1086     if(xBeamerFrame.is())
1087     {
1088         SwDBData aData = m_pWrtShell->GetDBData();
1089         SwModule::ShowDBObj( *this, aData );
1090     }
1091 
1092     // has anybody calls the attrchanged handler in the constructor?
1093     if( m_bAttrChgNotifiedWithRegistrations )
1094     {
1095         GetViewFrame().GetBindings().LEAVEREGISTRATIONS();
1096         if( m_aTimer.IsActive() )
1097             m_aTimer.Stop();
1098     }
1099 
1100     m_aTimer.SetInvokeHandler(LINK(this, SwView, TimeoutHdl));
1101     m_bAttrChgNotified = m_bAttrChgNotifiedWithRegistrations = false;
1102     if (bOldModifyFlag)
1103         rDocSh.EnableSetModified();
1104     InvalidateBorder();
1105 
1106     if (!bFuzzing)
1107     {
1108         if (!m_pHScrollbar->IsScrollbarVisible(true))
1109             ShowHScrollbar( false );
1110         if (!m_pVScrollbar->IsScrollbarVisible(true))
1111             ShowVScrollbar( false );
1112     }
1113 
1114     if (m_pWrtShell->GetViewOptions()->IsShowOutlineContentVisibilityButton())
1115         m_pWrtShell->InvalidateOutlineContentVisibility();
1116 
1117     if (!bFuzzing)
1118         GetViewFrame().GetWindow().AddChildEventListener(LINK(this, SwView, WindowChildEventListener));
1119 
1120     m_aBringToAttentionBlinkTimer.SetInvokeHandler(
1121                 LINK(this, SwView, BringToAttentionBlinkTimerHdl));
1122     m_aBringToAttentionBlinkTimer.SetTimeout(350);
1123 
1124     if (comphelper::LibreOfficeKit::isActive())
1125     {
1126         SwXTextDocument* pModel = comphelper::getFromUnoTunnel<SwXTextDocument>(GetCurrentDocument());
1127         SfxLokHelper::notifyViewRenderState(this, pModel);
1128     }
1129 }
1130 
SwViewGlueDocShell(SwView & rView,SwDocShell & rDocSh)1131 SwViewGlueDocShell::SwViewGlueDocShell(SwView& rView, SwDocShell& rDocSh)
1132     : m_rView(rView)
1133 {
1134     // Set DocShell
1135     rDocSh.SetView(&m_rView);
1136     SW_MOD()->SetView(&m_rView);
1137 }
1138 
~SwViewGlueDocShell()1139 SwViewGlueDocShell::~SwViewGlueDocShell()
1140 {
1141     SwDocShell* pDocSh = m_rView.GetDocShell();
1142     if (pDocSh && pDocSh->GetView() == &m_rView)
1143         pDocSh->SetView(nullptr);
1144     if (SW_MOD()->GetView() == &m_rView)
1145         SW_MOD()->SetView(nullptr);
1146 }
1147 
~SwView()1148 SwView::~SwView()
1149 {
1150     // Notify other LOK views that we are going away.
1151     SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_VIEW_CURSOR_VISIBLE, "visible", "false"_ostr);
1152     SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", ""_ostr);
1153     SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_GRAPHIC_VIEW_SELECTION, "selection", "EMPTY"_ostr);
1154 
1155     // Need to remove activated field's button before disposing EditWin.
1156     GetWrtShell().getIDocumentMarkAccess()->ClearFieldActivation();
1157 
1158     GetViewFrame().GetWindow().RemoveChildEventListener( LINK( this, SwView, WindowChildEventListener ) );
1159     m_pPostItMgr.reset();
1160 
1161     m_bInDtor = true;
1162     m_pEditWin->Hide(); // prevent problems with painting
1163 
1164     // Set pointer in SwDocShell to the view again
1165     m_xGlueDocShell.reset();
1166 
1167     if( m_aTimer.IsActive() && m_bAttrChgNotifiedWithRegistrations )
1168         GetViewFrame().GetBindings().LEAVEREGISTRATIONS();
1169 
1170     // the last view must end the text edit
1171     SdrView *pSdrView = m_pWrtShell->GetDrawView();
1172     if( pSdrView && pSdrView->IsTextEdit() )
1173         pSdrView->SdrEndTextEdit( true );
1174     else if (pSdrView)
1175     {
1176         pSdrView->DisposeUndoManager();
1177     }
1178 
1179     SetWindow( nullptr );
1180 
1181     m_pViewImpl->Invalidate();
1182     EndListening(GetViewFrame());
1183     EndListening(*GetDocShell());
1184 
1185     // tdf#155410 speedup shutdown, prevent unnecessary broadcasting during teardown of draw model
1186     auto pDrawModel = GetWrtShell().getIDocumentDrawModelAccess().GetDrawModel();
1187     const bool bWasLocked = pDrawModel->isLocked();
1188     pDrawModel->setLock(true);
1189     m_pWrtShell.reset(); // reset here so that it is not accessible by the following dtors.
1190     pDrawModel->setLock(bWasLocked);
1191 
1192     m_pHScrollbar.disposeAndClear();
1193     m_pVScrollbar.disposeAndClear();
1194     m_pHRuler.disposeAndClear();
1195     m_pVRuler.disposeAndClear();
1196     m_pGlosHdl.reset();
1197     m_pViewImpl.reset();
1198 
1199     // If this was enabled in the ctor for the frame, then disable it here.
1200     static bool bRequestDoubleBuffering = getenv("VCL_DOUBLEBUFFERING_ENABLE");
1201     if (bRequestDoubleBuffering)
1202         m_pEditWin->RequestDoubleBuffering(false);
1203     m_pEditWin.disposeAndClear();
1204 
1205     m_pFormatClipboard.reset();
1206 }
1207 
SetDying()1208 void SwView::SetDying()
1209 {
1210     m_bDying = true;
1211 }
1212 
afterCallbackRegistered()1213 void SwView::afterCallbackRegistered()
1214 {
1215     if (!comphelper::LibreOfficeKit::isActive())
1216         return;
1217 
1218     // common tasks
1219     SfxViewShell::afterCallbackRegistered();
1220 
1221     auto* pDocShell = GetDocShell();
1222     if (pDocShell)
1223     {
1224         std::shared_ptr<model::ColorSet> pThemeColors = pDocShell->GetThemeColors();
1225         std::set<Color> aDocumentColors = pDocShell->GetDocColors();
1226         svx::theme::notifyLOK(pThemeColors, aDocumentColors);
1227     }
1228 }
1229 
GetDocShell()1230 SwDocShell* SwView::GetDocShell()
1231 {
1232     SfxObjectShell* pDocShell = GetViewFrame().GetObjectShell();
1233     return dynamic_cast<SwDocShell*>( pDocShell );
1234 }
1235 
1236 // Remember CursorPos
1237 
WriteUserData(OUString & rUserData,bool bBrowse)1238 void SwView::WriteUserData( OUString &rUserData, bool bBrowse )
1239 {
1240     // The browse flag will be passed from Sfx when documents are browsed
1241     // (not to be confused with the BrowseMode).
1242     // Then that stored data are not persistent!
1243 
1244     const SwRect& rRect = m_pWrtShell->GetCharRect();
1245     const tools::Rectangle& rVis = GetVisArea();
1246 
1247     rUserData = OUString::number( rRect.Left() );
1248     rUserData += ";";
1249     rUserData += OUString::number( rRect.Top() );
1250     rUserData += ";";
1251     rUserData += OUString::number( m_pWrtShell->GetViewOptions()->GetZoom() );
1252     rUserData += ";";
1253     rUserData += OUString::number( rVis.Left() );
1254     rUserData += ";";
1255     rUserData += OUString::number( rVis.Top() );
1256     rUserData += ";";
1257     rUserData += OUString::number( bBrowse ? SAL_MIN_INT32 : rVis.Right());
1258     rUserData += ";";
1259     rUserData += OUString::number( bBrowse ? SAL_MIN_INT32 : rVis.Bottom());
1260     rUserData += ";";
1261     rUserData += OUString::number(
1262             static_cast<sal_uInt16>(m_pWrtShell->GetViewOptions()->GetZoomType()));//eZoom;
1263     rUserData += ";";
1264     rUserData += FrameTypeFlags::NONE == m_pWrtShell->GetSelFrameType() ? std::u16string_view(u"0") : std::u16string_view(u"1");
1265 }
1266 
1267 // Set CursorPos
1268 
lcl_IsOwnDocument(SwView & rView)1269 static bool lcl_IsOwnDocument( SwView& rView )
1270 {
1271     if (::officecfg::Office::Common::Load::ViewPositionForAnyUser::get())
1272     {
1273         return true;
1274     }
1275     uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
1276         rView.GetDocShell()->GetModel(), uno::UNO_QUERY_THROW);
1277     uno::Reference<document::XDocumentProperties> xDocProps
1278         = xDPS->getDocumentProperties();
1279     OUString Created = xDocProps->getAuthor();
1280     OUString Changed = xDocProps->getModifiedBy();
1281     OUString FullName = SW_MOD()->GetUserOptions().GetFullName();
1282     return !FullName.isEmpty()
1283            && (Changed == FullName || (Changed.isEmpty() && Created == FullName));
1284 }
1285 
ReadUserData(const OUString & rUserData,bool bBrowse)1286 void SwView::ReadUserData( const OUString &rUserData, bool bBrowse )
1287 {
1288     if ( !(rUserData.indexOf(';')>=0 && // more than one token
1289         // For document without layout only in the onlinelayout or
1290         // while forward/backward
1291          (!m_pWrtShell->IsNewLayout() || m_pWrtShell->GetViewOptions()->getBrowseMode() || bBrowse)) )
1292         return;
1293 
1294     bool bIsOwnDocument = lcl_IsOwnDocument( *this );
1295 
1296     CurrShell aCurr(m_pWrtShell.get());
1297 
1298     sal_Int32 nPos = 0;
1299 
1300     // No it is *not* a good idea to call GetToken within Point constr. immediately,
1301     // because which parameter is evaluated first?
1302     tools::Long nX = o3tl::toInt32(o3tl::getToken(rUserData, 0, ';', nPos )),
1303          nY = o3tl::toInt32(o3tl::getToken(rUserData, 0, ';', nPos ));
1304     Point aCursorPos( nX, nY );
1305 
1306     sal_uInt16 nZoomFactor =
1307         static_cast< sal_uInt16 >( o3tl::toInt32(o3tl::getToken(rUserData, 0, ';', nPos )) );
1308 
1309     tools::Long nLeft  = o3tl::toInt32(o3tl::getToken(rUserData, 0, ';', nPos )),
1310          nTop   = o3tl::toInt32(o3tl::getToken(rUserData, 0, ';', nPos )),
1311          nRight = o3tl::toInt32(o3tl::getToken(rUserData, 0, ';', nPos )),
1312          nBottom= o3tl::toInt32(o3tl::getToken(rUserData, 0, ';', nPos ));
1313 
1314     const tools::Long nAdd = m_pWrtShell->GetViewOptions()->getBrowseMode() ? DOCUMENTBORDER : DOCUMENTBORDER*2;
1315     if ( nBottom > (m_pWrtShell->GetDocSize().Height()+nAdd) )
1316         return;
1317 
1318     m_pWrtShell->EnableSmooth( false );
1319 
1320     const tools::Rectangle aVis( nLeft, nTop, nRight, nBottom );
1321 
1322     sal_Int32 nOff = 0;
1323     SvxZoomType eZoom;
1324     if( !m_pWrtShell->GetViewOptions()->getBrowseMode() )
1325         eZoom = static_cast<SvxZoomType>(o3tl::narrowing<sal_uInt16>(o3tl::toInt32(o3tl::getToken(rUserData, nOff, ';', nPos ))));
1326     else
1327     {
1328         eZoom = SvxZoomType::PERCENT;
1329         ++nOff;
1330     }
1331 
1332     bool bSelectObj = (0 != o3tl::toInt32(o3tl::getToken(rUserData, nOff, ';', nPos )))
1333                         && m_pWrtShell->IsObjSelectable( aCursorPos );
1334 
1335     // restore editing position
1336     m_pViewImpl->SetRestorePosition(aCursorPos, bSelectObj);
1337     // set flag value to avoid macro execution.
1338     bool bSavedFlagValue = m_pWrtShell->IsMacroExecAllowed();
1339     m_pWrtShell->SetMacroExecAllowed( false );
1340 // os: changed: The user data has to be read if the view is switched back from page preview
1341 // go to the last editing position when opening own files
1342     if(m_bOldShellWasPagePreview || bIsOwnDocument)
1343     {
1344         m_pWrtShell->SwCursorShell::SetCursor( aCursorPos, !bSelectObj );
1345         if( bSelectObj )
1346         {
1347             m_pWrtShell->SelectObj( aCursorPos );
1348             m_pWrtShell->EnterSelFrameMode( &aCursorPos );
1349         }
1350     }
1351 
1352     // reset flag value
1353     m_pWrtShell->SetMacroExecAllowed( bSavedFlagValue );
1354 
1355     // set visible area before applying
1356     // information from print preview. Otherwise, the applied information
1357     // is lost.
1358 // os: changed: The user data has to be read if the view is switched back from page preview
1359 // go to the last editing position when opening own files
1360     if(m_bOldShellWasPagePreview || bIsOwnDocument )
1361     {
1362         if ( bBrowse )
1363             SetVisArea( aVis.TopLeft() );
1364         else
1365             SetVisArea( aVis );
1366     }
1367 
1368     //apply information from print preview - if available
1369     if( !m_sNewCursorPos.isEmpty() )
1370     {
1371         sal_Int32 nIdx{ 0 };
1372         const tools::Long nXTmp = o3tl::toInt32(o3tl::getToken(m_sNewCursorPos, 0, ';', nIdx ));
1373         const tools::Long nYTmp = o3tl::toInt32(o3tl::getToken(m_sNewCursorPos, 0, ';', nIdx ));
1374         Point aCursorPos2( nXTmp, nYTmp );
1375         bSelectObj = m_pWrtShell->IsObjSelectable( aCursorPos2 );
1376 
1377         m_pWrtShell->SwCursorShell::SetCursor( aCursorPos2 );
1378         if( bSelectObj )
1379         {
1380             m_pWrtShell->SelectObj( aCursorPos2 );
1381             m_pWrtShell->EnterSelFrameMode( &aCursorPos2 );
1382         }
1383         m_pWrtShell->MakeSelVisible();
1384         m_sNewCursorPos.clear();
1385     }
1386     else if(USHRT_MAX != m_nNewPage)
1387     {
1388         m_pWrtShell->GotoPage(m_nNewPage, true);
1389         m_nNewPage = USHRT_MAX;
1390     }
1391 
1392     SelectShell();
1393 
1394     m_pWrtShell->StartAction();
1395     const SwViewOption* pVOpt = m_pWrtShell->GetViewOptions();
1396     if( pVOpt->GetZoom() != nZoomFactor || pVOpt->GetZoomType() != eZoom )
1397         SetZoom( eZoom, nZoomFactor);
1398 
1399     m_pWrtShell->LockView( true );
1400     m_pWrtShell->EndAction();
1401     m_pWrtShell->LockView( false );
1402     m_pWrtShell->EnableSmooth( true );
1403 }
1404 
ReadUserDataSequence(const uno::Sequence<beans::PropertyValue> & rSequence)1405 void SwView::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue >& rSequence )
1406 {
1407     if(GetDocShell()->IsPreview()||m_bIsPreviewDoubleClick)
1408         return;
1409     bool bIsOwnDocument = lcl_IsOwnDocument( *this );
1410 
1411     CurrShell aCurr(m_pWrtShell.get());
1412     const SwRect& rRect = m_pWrtShell->GetCharRect();
1413     const tools::Rectangle &rVis = GetVisArea();
1414     const SwViewOption* pVOpt = m_pWrtShell->GetViewOptions();
1415 
1416     sal_Int64 nX = rRect.Left(), nY = rRect.Top(), nLeft = rVis.Left(), nTop = rVis.Top();
1417     sal_Int16 nZoomType = static_cast< sal_Int16 >(pVOpt->GetZoomType());
1418     sal_Int16 nZoomFactor = static_cast < sal_Int16 > (pVOpt->GetZoom());
1419     bool bViewLayoutBookMode = pVOpt->IsViewLayoutBookMode();
1420     sal_Int16 nViewLayoutColumns = pVOpt->GetViewLayoutColumns();
1421 
1422     bool bSelectedFrame = ( m_pWrtShell->GetSelFrameType() != FrameTypeFlags::NONE ),
1423              bGotVisibleLeft = false,
1424              bGotVisibleTop = false,
1425              bGotZoomType = false,
1426              bGotZoomFactor = false, bGotIsSelectedFrame = false,
1427              bGotViewLayoutColumns = false, bGotViewLayoutBookMode = false,
1428              bBrowseMode = false, bGotBrowseMode = false;
1429     bool bKeepRatio = pVOpt->IsKeepRatio();
1430     bool bGotKeepRatio = false;
1431 
1432     for (const beans::PropertyValue& rValue : rSequence)
1433     {
1434         if ( rValue.Name == "ViewLeft" )
1435         {
1436            rValue.Value >>= nX;
1437            nX = o3tl::convertSaturate(nX, o3tl::Length::mm100, o3tl::Length::twip);
1438         }
1439         else if ( rValue.Name == "ViewTop" )
1440         {
1441            rValue.Value >>= nY;
1442            nY = o3tl::convertSaturate(nY, o3tl::Length::mm100, o3tl::Length::twip);
1443         }
1444         else if ( rValue.Name == "VisibleLeft" )
1445         {
1446            rValue.Value >>= nLeft;
1447            nLeft = o3tl::convertSaturate(nLeft, o3tl::Length::mm100, o3tl::Length::twip);
1448            bGotVisibleLeft = true;
1449         }
1450         else if ( rValue.Name == "VisibleTop" )
1451         {
1452            rValue.Value >>= nTop;
1453            nTop = o3tl::convertSaturate(nTop, o3tl::Length::mm100, o3tl::Length::twip);
1454            bGotVisibleTop = true;
1455         }
1456         else if ( rValue.Name == "ZoomType" )
1457         {
1458            rValue.Value >>= nZoomType;
1459            bGotZoomType = true;
1460         }
1461         else if ( rValue.Name == "ZoomFactor" )
1462         {
1463            rValue.Value >>= nZoomFactor;
1464            bGotZoomFactor = true;
1465         }
1466         else if ( rValue.Name == "ViewLayoutColumns" )
1467         {
1468            rValue.Value >>= nViewLayoutColumns;
1469            bGotViewLayoutColumns = true;
1470         }
1471         else if ( rValue.Name == "ViewLayoutBookMode" )
1472         {
1473            bViewLayoutBookMode = *o3tl::doAccess<bool>(rValue.Value);
1474            bGotViewLayoutBookMode = true;
1475         }
1476         else if ( rValue.Name == "IsSelectedFrame" )
1477         {
1478            rValue.Value >>= bSelectedFrame;
1479            bGotIsSelectedFrame = true;
1480         }
1481         else if (rValue.Name == "ShowOnlineLayout")
1482         {
1483            rValue.Value >>= bBrowseMode;
1484            bGotBrowseMode = true;
1485         }
1486         else if (rValue.Name == "KeepRatio")
1487         {
1488             rValue.Value >>= bKeepRatio;
1489             bGotKeepRatio = true;
1490         }
1491         // Fallback to common SdrModel processing
1492         else
1493            GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel()->ReadUserDataSequenceValue(&rValue);
1494     }
1495     if (bGotBrowseMode)
1496     {
1497         // delegate further
1498         GetViewImpl()->GetUNOObject_Impl()->getViewSettings()->setPropertyValue(u"ShowOnlineLayout"_ustr, uno::Any(bBrowseMode));
1499     }
1500 
1501     SelectShell();
1502 
1503     Point aCursorPos( nX, nY );
1504 
1505     m_pWrtShell->EnableSmooth( false );
1506 
1507     SvxZoomType eZoom;
1508     if ( !m_pWrtShell->GetViewOptions()->getBrowseMode() )
1509         eZoom = static_cast < SvxZoomType > ( nZoomType );
1510     else
1511     {
1512         eZoom = SvxZoomType::PERCENT;
1513     }
1514     if (bGotIsSelectedFrame)
1515     {
1516         bool bSelectObj = bSelectedFrame && m_pWrtShell->IsObjSelectable( aCursorPos );
1517 
1518         // set flag value to avoid macro execution.
1519         bool bSavedFlagValue = m_pWrtShell->IsMacroExecAllowed();
1520         m_pWrtShell->SetMacroExecAllowed( false );
1521 // os: changed: The user data has to be read if the view is switched back from page preview
1522 // go to the last editing position when opening own files
1523         m_pViewImpl->SetRestorePosition(aCursorPos, bSelectObj);
1524         if(m_bOldShellWasPagePreview|| bIsOwnDocument)
1525         {
1526             m_pWrtShell->SwCursorShell::SetCursor( aCursorPos, !bSelectObj );
1527 
1528             // Update the shell to toggle Header/Footer edit if needed
1529             bool bInHeader = true;
1530             if ( m_pWrtShell->IsInHeaderFooter( &bInHeader ) )
1531             {
1532                 if ( !bInHeader )
1533                 {
1534                     m_pWrtShell->SetShowHeaderFooterSeparator( FrameControlType::Footer, true );
1535                     m_pWrtShell->SetShowHeaderFooterSeparator( FrameControlType::Header, false );
1536                 }
1537                 else
1538                 {
1539                     m_pWrtShell->SetShowHeaderFooterSeparator( FrameControlType::Header, true );
1540                     m_pWrtShell->SetShowHeaderFooterSeparator( FrameControlType::Footer, false );
1541                 }
1542 
1543                 // Force repaint
1544                 m_pWrtShell->GetWin()->Invalidate();
1545             }
1546             if ( m_pWrtShell->IsInHeaderFooter() != m_pWrtShell->IsHeaderFooterEdit() )
1547                 m_pWrtShell->ToggleHeaderFooterEdit();
1548 
1549             if( bSelectObj )
1550             {
1551                 m_pWrtShell->SelectObj( aCursorPos );
1552                 m_pWrtShell->EnterSelFrameMode( &aCursorPos );
1553             }
1554         }
1555 
1556         // reset flag value
1557         m_pWrtShell->SetMacroExecAllowed( bSavedFlagValue );
1558     }
1559 
1560     if (bGotKeepRatio && bKeepRatio != pVOpt->IsKeepRatio())
1561     {
1562         // Got a custom value, then it makes sense to trigger notifications.
1563         SwViewOption aUsrPref(*pVOpt);
1564         aUsrPref.SetKeepRatio(bKeepRatio);
1565         SW_MOD()->ApplyUsrPref(aUsrPref, this);
1566     }
1567 
1568     // Set ViewLayoutSettings
1569     const bool bSetViewLayoutSettings = bGotViewLayoutColumns && bGotViewLayoutBookMode &&
1570                                         ( pVOpt->GetViewLayoutColumns() != nViewLayoutColumns || pVOpt->IsViewLayoutBookMode() != bViewLayoutBookMode );
1571 
1572     const bool bSetViewSettings = bGotZoomType && bGotZoomFactor &&
1573                                   ( pVOpt->GetZoom() != nZoomFactor || pVOpt->GetZoomType() != eZoom );
1574 
1575     // In case we have a 'fixed' view layout of 2 or more columns,
1576     // we have to apply the view options *before* starting the action.
1577     // Otherwise the SetZoom function cannot work correctly, because
1578     // the view layout hasn't been calculated.
1579     const bool bZoomNeedsViewLayout = bSetViewLayoutSettings &&
1580                                       1 < nViewLayoutColumns &&
1581                                       bSetViewSettings &&
1582                                       eZoom != SvxZoomType::PERCENT;
1583 
1584     if ( !bZoomNeedsViewLayout )
1585         m_pWrtShell->StartAction();
1586 
1587     if ( bSetViewLayoutSettings )
1588         SetViewLayout( nViewLayoutColumns, bViewLayoutBookMode, true );
1589 
1590     if ( bZoomNeedsViewLayout )
1591         m_pWrtShell->StartAction();
1592 
1593     if ( bSetViewSettings )
1594         SetZoom( eZoom, nZoomFactor, true );
1595 
1596 // os: changed: The user data has to be read if the view is switched back from page preview
1597 // go to the last editing position when opening own files
1598     if(m_bOldShellWasPagePreview||bIsOwnDocument)
1599     {
1600         if ( bGotVisibleLeft && bGotVisibleTop )
1601         {
1602             Point aTopLeft(nLeft, nTop);
1603             // make sure the document is still centered
1604             const SwTwips lBorder = IsDocumentBorder() ? DOCUMENTBORDER : 2 * DOCUMENTBORDER;
1605             SwTwips nEditWidth = GetEditWin().GetOutDev()->GetOutputSize().Width();
1606             if(nEditWidth > (m_aDocSz.Width() + lBorder ))
1607                 aTopLeft.setX( ( m_aDocSz.Width() + lBorder - nEditWidth  ) / 2 );
1608             else
1609             {
1610                 //check if the values are possible
1611                 tools::Long nXMax = m_pHScrollbar->GetRangeMax() - m_pHScrollbar->GetVisibleSize();
1612                 if( aTopLeft.X() > nXMax )
1613                     aTopLeft.setX( nXMax < 0 ? 0 : nXMax );
1614             }
1615             SetVisArea( aTopLeft );
1616         }
1617     }
1618 
1619     m_pWrtShell->LockView( true );
1620     m_pWrtShell->EndAction();
1621     m_pWrtShell->LockView( false );
1622     m_pWrtShell->EnableSmooth( true );
1623 
1624 }
1625 
WriteUserDataSequence(uno::Sequence<beans::PropertyValue> & rSequence)1626 void SwView::WriteUserDataSequence ( uno::Sequence < beans::PropertyValue >& rSequence )
1627 {
1628     const SwRect& rRect = m_pWrtShell->GetCharRect();
1629     const tools::Rectangle& rVis = GetVisArea();
1630 
1631     std::vector<beans::PropertyValue> aVector;
1632 
1633     sal_uInt16 nViewID( GetViewFrame().GetCurViewId());
1634     aVector.push_back(comphelper::makePropertyValue(u"ViewId"_ustr, "view" + OUString::number(nViewID)));
1635 
1636     aVector.push_back(comphelper::makePropertyValue(u"ViewLeft"_ustr, convertTwipToMm100 ( rRect.Left() )));
1637 
1638     aVector.push_back(comphelper::makePropertyValue(u"ViewTop"_ustr, convertTwipToMm100 ( rRect.Top() )));
1639 
1640     auto visibleLeft = convertTwipToMm100 ( rVis.Left() );
1641     aVector.push_back(comphelper::makePropertyValue(u"VisibleLeft"_ustr, visibleLeft));
1642 
1643     auto visibleTop = convertTwipToMm100 ( rVis.Top() );
1644     aVector.push_back(comphelper::makePropertyValue(u"VisibleTop"_ustr, visibleTop));
1645 
1646     // We don't read VisibleRight and VisibleBottom anymore, but write them,
1647     // because older versions rely on their presence to restore position
1648 
1649     auto visibleRight = rVis.IsWidthEmpty() ? visibleLeft : convertTwipToMm100 ( rVis.Right() );
1650     aVector.push_back(comphelper::makePropertyValue(u"VisibleRight"_ustr, visibleRight));
1651 
1652     auto visibleBottom = rVis.IsHeightEmpty() ? visibleTop : convertTwipToMm100 ( rVis.Bottom() );
1653     aVector.push_back(comphelper::makePropertyValue(u"VisibleBottom"_ustr, visibleBottom));
1654 
1655     const sal_Int16 nZoomType = static_cast< sal_Int16 >(m_pWrtShell->GetViewOptions()->GetZoomType());
1656     aVector.push_back(comphelper::makePropertyValue(u"ZoomType"_ustr, nZoomType));
1657 
1658     const sal_Int16 nViewLayoutColumns = static_cast< sal_Int16 >(m_pWrtShell->GetViewOptions()->GetViewLayoutColumns());
1659     aVector.push_back(comphelper::makePropertyValue(u"ViewLayoutColumns"_ustr, nViewLayoutColumns));
1660 
1661     aVector.push_back(comphelper::makePropertyValue(u"ViewLayoutBookMode"_ustr, m_pWrtShell->GetViewOptions()->IsViewLayoutBookMode()));
1662 
1663     aVector.push_back(comphelper::makePropertyValue(u"ZoomFactor"_ustr, static_cast < sal_Int16 > (m_pWrtShell->GetViewOptions()->GetZoom())));
1664 
1665     aVector.push_back(comphelper::makePropertyValue(u"IsSelectedFrame"_ustr, FrameTypeFlags::NONE != m_pWrtShell->GetSelFrameType()));
1666 
1667     aVector.push_back(
1668         comphelper::makePropertyValue(u"KeepRatio"_ustr, m_pWrtShell->GetViewOptions()->IsKeepRatio()));
1669 
1670     rSequence = comphelper::containerToSequence(aVector);
1671 
1672     // Common SdrModel processing
1673     GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel()->WriteUserDataSequence(rSequence);
1674 }
1675 
ShowCursor(bool bOn)1676 void SwView::ShowCursor( bool bOn )
1677 {
1678     //don't scroll the cursor into the visible area
1679     bool bUnlockView = !m_pWrtShell->IsViewLocked();
1680     m_pWrtShell->LockView( true );    //lock visible section
1681 
1682     if( !bOn )
1683         m_pWrtShell->HideCursor();
1684     else if( !m_pWrtShell->IsFrameSelected() && !m_pWrtShell->IsObjSelected() )
1685         m_pWrtShell->ShowCursor();
1686 
1687     if( bUnlockView )
1688         m_pWrtShell->LockView( false );
1689 }
1690 
DoVerb(sal_Int32 nVerb)1691 ErrCode SwView::DoVerb(sal_Int32 nVerb)
1692 {
1693     if ( !GetViewFrame().GetFrame().IsInPlace() )
1694     {
1695         SwWrtShell &rSh = GetWrtShell();
1696         const SelectionType nSel = rSh.GetSelectionType();
1697         if ( nSel & SelectionType::Ole )
1698             rSh.LaunchOLEObj( nVerb );
1699     }
1700     return ERRCODE_NONE;
1701 }
1702 
1703 //   only return true for a text selection
1704 
HasSelection(bool bText) const1705 bool SwView::HasSelection( bool  bText ) const
1706 {
1707     return bText ? GetWrtShell().SwCursorShell::HasSelection()
1708                  : GetWrtShell().HasSelection();
1709 }
1710 
GetSelectionText(bool bCompleteWrds,bool)1711 OUString SwView::GetSelectionText( bool bCompleteWrds, bool /*bOnlyASample*/ )
1712 {
1713     return GetSelectionTextParam( bCompleteWrds, true );
1714 }
1715 
GetSelectionTextParam(bool bCompleteWrds,bool bEraseTrail)1716 OUString SwView::GetSelectionTextParam( bool bCompleteWrds, bool bEraseTrail )
1717 {
1718     OUString sReturn;
1719     if( bCompleteWrds && !GetWrtShell().HasSelection() )
1720         GetWrtShell().SelWrd();
1721 
1722     GetWrtShell().GetSelectedText( sReturn );
1723     if( bEraseTrail )
1724         sReturn = comphelper::string::stripEnd(sReturn, ' ');
1725     return sReturn;
1726 }
1727 
GetGlosHdl()1728 SwGlossaryHdl* SwView::GetGlosHdl()
1729 {
1730     if(!m_pGlosHdl)
1731         m_pGlosHdl.reset(new SwGlossaryHdl(GetViewFrame(), m_pWrtShell.get()));
1732     return m_pGlosHdl.get();
1733 }
1734 
Notify(SfxBroadcaster & rBC,const SfxHint & rHint)1735 void SwView::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1736 {
1737     bool bCallBase = true;
1738     SfxHintId nId = rHint.GetId();
1739     switch ( nId )
1740     {
1741         case SfxHintId::FmDesignModeChanged:
1742         {
1743             auto pChangedHint = static_cast<const FmDesignModeChangedHint*>(&rHint);
1744             bool bDesignMode = pChangedHint->GetDesignMode();
1745             if (!bDesignMode && GetDrawFuncPtr())
1746             {
1747                 GetDrawFuncPtr()->Deactivate();
1748                 SetDrawFuncPtr(nullptr);
1749                 LeaveDrawCreate();
1750                 AttrChangedNotify(nullptr);
1751             }
1752             break;
1753         }
1754         // sub shells will be destroyed by the
1755         // dispatcher, if the view frame is dying. Thus, reset member <pShell>.
1756         case SfxHintId::Dying:
1757             {
1758                 if ( &rBC == &GetViewFrame() )
1759                 {
1760                     ResetSubShell();
1761                 }
1762             }
1763             break;
1764         case SfxHintId::ModeChanged:
1765             {
1766                 // Modal mode change-over?
1767                 bool bModal = GetDocShell()->IsInModalMode();
1768                 m_pHRuler->SetActive( !bModal );
1769                 m_pVRuler->SetActive( !bModal );
1770             }
1771 
1772             [[fallthrough]];
1773 
1774         case SfxHintId::TitleChanged:
1775             if ( GetDocShell()->IsReadOnly() != GetWrtShell().GetViewOptions()->IsReadonly() )
1776             {
1777                 SwWrtShell &rSh = GetWrtShell();
1778                 rSh.SetReadonlyOption( GetDocShell()->IsReadOnly() );
1779 
1780                 if ( rSh.GetViewOptions()->IsViewVRuler() )
1781                     CreateVRuler();
1782                 else
1783                     KillVRuler();
1784                 if ( rSh.GetViewOptions()->IsViewHRuler() )
1785                     CreateTab();
1786                 else
1787                     KillTab();
1788                 bool bReadonly = GetDocShell()->IsReadOnly();
1789                 // if document is to be opened in alive-mode then this has to be
1790                 // regarded while switching from readonly-mode to edit-mode
1791                 if( !bReadonly )
1792                 {
1793                     SwDrawModel * pDrawDoc = GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
1794                     if (pDrawDoc)
1795                     {
1796                         if( !pDrawDoc->GetOpenInDesignMode() )
1797                             break;// don't touch the design mode
1798                     }
1799                 }
1800                 SfxBoolItem aItem( SID_FM_DESIGN_MODE, !bReadonly);
1801                 GetDispatcher().ExecuteList(SID_FM_DESIGN_MODE,
1802                         SfxCallMode::ASYNCHRON, { &aItem });
1803             }
1804             break;
1805 
1806         case SfxHintId::SwDrawViewsCreated:
1807             {
1808                 bCallBase = false;
1809                 if ( GetFormShell() )
1810                 {
1811                     GetFormShell()->SetView(dynamic_cast<FmFormView*>(GetWrtShell().GetDrawView()));
1812                     SfxBoolItem aItem( SID_FM_DESIGN_MODE, !GetDocShell()->IsReadOnly());
1813                     GetDispatcher().ExecuteList(SID_FM_DESIGN_MODE,
1814                             SfxCallMode::SYNCHRON, { &aItem });
1815                 }
1816             }
1817             break;
1818         case SfxHintId::RedlineChanged:
1819             {
1820                 static sal_uInt16 const aSlotRedLine[] = {
1821                     FN_REDLINE_ACCEPT_DIRECT,
1822                     FN_REDLINE_REJECT_DIRECT,
1823                     FN_REDLINE_NEXT_CHANGE,
1824                     FN_REDLINE_PREV_CHANGE,
1825                     FN_REDLINE_ACCEPT_ALL,
1826                     FN_REDLINE_REJECT_ALL,
1827                     0
1828                 };
1829                 GetViewFrame().GetBindings().Invalidate(aSlotRedLine);
1830             }
1831             break;
1832         default: break;
1833     }
1834 
1835     if ( bCallBase )
1836         SfxViewShell::Notify(rBC, rHint);
1837 }
1838 
1839 #if defined(_WIN32) || defined UNX
1840 
ScannerEventHdl()1841 void SwView::ScannerEventHdl()
1842 {
1843     uno::Reference< XScannerManager2 > xScanMgr = SW_MOD()->GetScannerManager();
1844     if( xScanMgr.is() )
1845     {
1846         const ScannerContext    aContext( xScanMgr->getAvailableScanners().getConstArray()[ 0 ] );
1847         const ScanError         eError = xScanMgr->getError( aContext );
1848 
1849         if( ScanError_ScanErrorNone == eError )
1850         {
1851             const uno::Reference< awt::XBitmap > xBitmap( xScanMgr->getBitmap( aContext ) );
1852 
1853             if( xBitmap.is() )
1854             {
1855                 const BitmapEx aScanBmp( VCLUnoHelper::GetBitmap( xBitmap ) );
1856 
1857                 if( !aScanBmp.IsEmpty() )
1858                 {
1859                     Graphic aGrf(aScanBmp);
1860                     m_pWrtShell->InsertGraphic( OUString(), OUString(), aGrf );
1861                 }
1862             }
1863         }
1864     }
1865     SfxBindings& rBind = GetViewFrame().GetBindings();
1866     rBind.Invalidate( SID_TWAIN_SELECT );
1867     rBind.Invalidate( SID_TWAIN_TRANSFER );
1868 }
1869 #endif
1870 
StopShellTimer()1871 void    SwView::StopShellTimer()
1872 {
1873     if(m_aTimer.IsActive())
1874     {
1875         m_aTimer.Stop();
1876         if ( m_bAttrChgNotifiedWithRegistrations )
1877         {
1878             GetViewFrame().GetBindings().LEAVEREGISTRATIONS();
1879             m_bAttrChgNotifiedWithRegistrations = false;
1880         }
1881         SelectShell();
1882         m_bAttrChgNotified = false;
1883     }
1884 }
1885 
PrepareClose(bool bUI)1886 bool SwView::PrepareClose( bool bUI )
1887 {
1888     SfxViewFrame& rVFrame = GetViewFrame();
1889     rVFrame.SetChildWindow( SwInputChild::GetChildWindowId(), false );
1890     if( rVFrame.GetDispatcher()->IsLocked() )
1891         rVFrame.GetDispatcher()->Lock(false);
1892 
1893     if ( m_pFormShell && !m_pFormShell->PrepareClose( bUI ) )
1894     {
1895         return false;
1896     }
1897     return SfxViewShell::PrepareClose( bUI );
1898 }
1899 
1900 // status methods for clipboard.
1901 // Status changes now notified from the clipboard.
IsPasteAllowed()1902 bool SwView::IsPasteAllowed()
1903 {
1904     SotExchangeDest nPasteDestination = SwTransferable::GetSotDestination( *m_pWrtShell );
1905     if( m_nLastPasteDestination != nPasteDestination )
1906     {
1907         TransferableDataHelper aDataHelper(
1908                         TransferableDataHelper::CreateFromSystemClipboard(
1909                                                         &GetEditWin()) );
1910         if( aDataHelper.GetXTransferable().is() )
1911         {
1912             m_bPasteState = SwTransferable::IsPaste( *m_pWrtShell, aDataHelper );
1913             m_bPasteSpecialState = SwTransferable::IsPasteSpecial(
1914                                                     *m_pWrtShell, aDataHelper );
1915         }
1916         else
1917             m_bPasteState = m_bPasteSpecialState = false;
1918 
1919         if( static_cast<SotExchangeDest>(0xFFFF) == m_nLastPasteDestination )  // the init value
1920             m_pViewImpl->AddClipboardListener();
1921         m_nLastPasteDestination = nPasteDestination;
1922     }
1923     return m_bPasteState;
1924 }
1925 
IsPasteSpecialAllowed()1926 bool SwView::IsPasteSpecialAllowed()
1927 {
1928     if ( m_pFormShell && m_pFormShell->IsActiveControl() )
1929         return false;
1930 
1931     SotExchangeDest nPasteDestination = SwTransferable::GetSotDestination( *m_pWrtShell );
1932     if( m_nLastPasteDestination != nPasteDestination )
1933     {
1934         TransferableDataHelper aDataHelper(
1935                         TransferableDataHelper::CreateFromSystemClipboard(
1936                                                         &GetEditWin()) );
1937         if( aDataHelper.GetXTransferable().is() )
1938         {
1939             m_bPasteState = SwTransferable::IsPaste( *m_pWrtShell, aDataHelper );
1940             m_bPasteSpecialState = SwTransferable::IsPasteSpecial(
1941                                                     *m_pWrtShell, aDataHelper );
1942         }
1943         else
1944             m_bPasteState = m_bPasteSpecialState = false;
1945 
1946         if( static_cast<SotExchangeDest>(0xFFFF) == m_nLastPasteDestination )  // the init value
1947             m_pViewImpl->AddClipboardListener();
1948     }
1949     return m_bPasteSpecialState;
1950 }
1951 
IsPasteSpreadsheet(bool bHasOwnTableCopied)1952 bool SwView::IsPasteSpreadsheet(bool bHasOwnTableCopied)
1953 {
1954     TransferableDataHelper aDataHelper(
1955                         TransferableDataHelper::CreateFromSystemClipboard(
1956                                                         &GetEditWin()) );
1957     if( aDataHelper.GetXTransferable().is() )
1958     {
1959         if (bHasOwnTableCopied && SwTransferable::IsPasteOwnFormat( aDataHelper ))
1960             return true;
1961         return aDataHelper.HasFormat( SotClipboardFormatId::SYLK ) || aDataHelper.HasFormat( SotClipboardFormatId::SYLK_BIGCAPS );
1962     }
1963     return false;
1964 }
1965 
NotifyDBChanged()1966 void SwView::NotifyDBChanged()
1967 {
1968     GetViewImpl()->GetUNOObject_Impl()->NotifyDBChanged();
1969 }
1970 
1971 // Printing
1972 
CreateTmpSelectionDoc()1973 SfxObjectShellLock SwView::CreateTmpSelectionDoc()
1974 {
1975     SwXTextView *const pTempImpl = GetViewImpl()->GetUNOObject_Impl();
1976     return pTempImpl->BuildTmpSelectionDoc();
1977 }
1978 
AddTransferable(SwTransferable & rTransferable)1979 void SwView::AddTransferable(SwTransferable& rTransferable)
1980 {
1981     GetViewImpl()->AddTransferable(rTransferable);
1982 }
1983 
getLOKVisibleArea() const1984 tools::Rectangle SwView::getLOKVisibleArea() const
1985 {
1986     if (SwViewShell* pVwSh = GetWrtShellPtr())
1987         return pVwSh->getLOKVisibleArea();
1988     else
1989         return tools::Rectangle();
1990 }
1991 
flushPendingLOKInvalidateTiles()1992 void SwView::flushPendingLOKInvalidateTiles()
1993 {
1994     if (SwWrtShell* pSh = GetWrtShellPtr())
1995         pSh->FlushPendingLOKInvalidateTiles();
1996 }
1997 
getLOKPayload(int nType,int nViewId) const1998 std::optional<OString> SwView::getLOKPayload(int nType, int nViewId) const
1999 {
2000     if (SwWrtShell* pSh = GetWrtShellPtr())
2001         return pSh->getLOKPayload(nType, nViewId);
2002     else
2003         return std::nullopt;
2004 }
2005 
GetDataSourceName() const2006 OUString SwView::GetDataSourceName() const
2007 {
2008     uno::Reference<lang::XMultiServiceFactory> xFactory(GetDocShell()->GetModel(), uno::UNO_QUERY);
2009     uno::Reference<beans::XPropertySet> xSettings(
2010         xFactory->createInstance(u"com.sun.star.document.Settings"_ustr), uno::UNO_QUERY);
2011     OUString sDataSourceName = u""_ustr;
2012     xSettings->getPropertyValue(u"CurrentDatabaseDataSource"_ustr) >>= sDataSourceName;
2013 
2014     return sDataSourceName;
2015 }
2016 
IsDataSourceAvailable(const OUString sDataSourceName)2017 bool SwView::IsDataSourceAvailable(const OUString sDataSourceName)
2018 {
2019     uno::Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
2020     Reference< XDatabaseContext> xDatabaseContext = DatabaseContext::create(xContext);
2021 
2022     return xDatabaseContext->hasByName(sDataSourceName);
2023 }
2024 
BringToAttention(std::vector<basegfx::B2DRange> && aRanges)2025 void SwView::BringToAttention(std::vector<basegfx::B2DRange>&& aRanges)
2026 {
2027     m_nBringToAttentionBlinkTimeOutsRemaining = 0;
2028     m_aBringToAttentionBlinkTimer.Stop();
2029     if (aRanges.empty())
2030         m_xBringToAttentionOverlayObject.reset();
2031     else
2032     {
2033         m_xBringToAttentionOverlayObject.reset(
2034                     new sdr::overlay::OverlaySelection(sdr::overlay::OverlayType::Invert,
2035                                                        Color(), std::move(aRanges),
2036                                                        true /*unused for Invert type*/));
2037         m_nBringToAttentionBlinkTimeOutsRemaining = 4;
2038         m_aBringToAttentionBlinkTimer.Start();
2039     }
2040 }
2041 
BringToAttention(const tools::Rectangle & rRect)2042 void SwView::BringToAttention(const tools::Rectangle& rRect)
2043 {
2044     std::vector<basegfx::B2DRange> aRanges{ basegfx::B2DRange(rRect.Left(), rRect.Top(),
2045                                                               rRect.Right(), rRect.Bottom()) };
2046     BringToAttention(std::move(aRanges));
2047 }
2048 
BringToAttention(const SwNode * pNode)2049 void SwView::BringToAttention(const SwNode* pNode)
2050 {
2051     if (!pNode)
2052         return;
2053 
2054     std::vector<basegfx::B2DRange> aRanges;
2055     const SwFrame* pFrame;
2056     if (pNode->IsContentNode())
2057     {
2058         pFrame = pNode->GetContentNode()->getLayoutFrame(GetWrtShell().GetLayout());
2059     }
2060     else
2061     {
2062         // section and table nodes
2063         SwNode2Layout aTmp(*pNode, pNode->GetIndex() - 1);
2064         pFrame = aTmp.NextFrame();
2065     }
2066     while (pFrame)
2067     {
2068         const SwRect& rFrameRect = pFrame->getFrameArea();
2069         if (!rFrameRect.IsEmpty())
2070             aRanges.emplace_back(rFrameRect.Left(), rFrameRect.Top() + pFrame->GetTopMargin(),
2071                                  rFrameRect.Right(), rFrameRect.Bottom());
2072         if (!pFrame->IsFlowFrame())
2073             break;
2074         const SwFlowFrame* pFollow = SwFlowFrame::CastFlowFrame(pFrame)->GetFollow();
2075         if (!pFollow)
2076             break;
2077         pFrame = &pFollow->GetFrame();
2078     }
2079     BringToAttention(std::move(aRanges));
2080 }
2081 
IMPL_LINK_NOARG(SwView,BringToAttentionBlinkTimerHdl,Timer *,void)2082 IMPL_LINK_NOARG(SwView, BringToAttentionBlinkTimerHdl, Timer*, void)
2083 {
2084     if (GetDrawView() && m_xBringToAttentionOverlayObject)
2085     {
2086         if (SdrView* pView = GetDrawView())
2087         {
2088             if (SdrPaintWindow* pPaintWindow = pView->GetPaintWindow(0))
2089             {
2090                 const rtl::Reference<sdr::overlay::OverlayManager>& xOverlayManager
2091                     = pPaintWindow->GetOverlayManager();
2092                 if (m_nBringToAttentionBlinkTimeOutsRemaining % 2 == 0)
2093                     xOverlayManager->add(*m_xBringToAttentionOverlayObject);
2094                 else
2095                     xOverlayManager->remove(*m_xBringToAttentionOverlayObject);
2096                 --m_nBringToAttentionBlinkTimeOutsRemaining;
2097             }
2098             else
2099                 m_nBringToAttentionBlinkTimeOutsRemaining = 0;
2100         }
2101         else
2102             m_nBringToAttentionBlinkTimeOutsRemaining = 0;
2103     }
2104     else
2105         m_nBringToAttentionBlinkTimeOutsRemaining = 0;
2106     if (m_nBringToAttentionBlinkTimeOutsRemaining == 0)
2107     {
2108         m_xBringToAttentionOverlayObject.reset();
2109         m_aBringToAttentionBlinkTimer.Stop();
2110     }
2111 }
2112 
2113 namespace sw {
2114 
InitPrintOptionsFromApplication(SwPrintData & o_rData,bool const bWeb)2115 void InitPrintOptionsFromApplication(SwPrintData & o_rData, bool const bWeb)
2116 {
2117     o_rData = *SW_MOD()->GetPrtOptions(bWeb);
2118 }
2119 
2120 } // namespace sw
2121 
2122 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
2123