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