xref: /core/sw/source/uibase/uno/unotxdoc.cxx (revision 0e27158c)
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 <boost/property_tree/json_parser.hpp>
21 
22 #include <sal/config.h>
23 
24 #include <comphelper/string.hxx>
25 #include <AnnotationWin.hxx>
26 #include <o3tl/any.hxx>
27 #include <osl/mutex.hxx>
28 #include <vcl/commandevent.hxx>
29 #include <vcl/image.hxx>
30 #include <vcl/vclevent.hxx>
31 #include <vcl/virdev.hxx>
32 #include <vcl/sysdata.hxx>
33 #include <vcl/svapp.hxx>
34 #include <vcl/print.hxx>
35 #include <sfx2/viewfrm.hxx>
36 #include <sfx2/lokhelper.hxx>
37 #include <sfx2/sfxbasecontroller.hxx>
38 #include <sfx2/docfile.hxx>
39 #include <sfx2/msg.hxx>
40 #include <sfx2/msgpool.hxx>
41 #include <sfx2/printer.hxx>
42 #include <toolkit/helper/vclunohelper.hxx>
43 #include <toolkit/awt/vclxdevice.hxx>
44 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
45 #include <sfx2/lokcharthelper.hxx>
46 #include <sfx2/ipclient.hxx>
47 #include <editeng/svxacorr.hxx>
48 #include <editeng/acorrcfg.hxx>
49 #include <cmdid.h>
50 #include <swtypes.hxx>
51 #include <wdocsh.hxx>
52 #include <wrtsh.hxx>
53 #include <pview.hxx>
54 #include <viewsh.hxx>
55 #include <pvprtdat.hxx>
56 #include <printdata.hxx>
57 #include <pagefrm.hxx>
58 #include <rootfrm.hxx>
59 #include <svl/stritem.hxx>
60 #include <unotxdoc.hxx>
61 #include <svl/numuno.hxx>
62 #include <fldbas.hxx>
63 #include <unomap.hxx>
64 #include <unotextbodyhf.hxx>
65 #include <unotextrange.hxx>
66 #include <unotextcursor.hxx>
67 #include <unosett.hxx>
68 #include <unocoll.hxx>
69 #include <unoredlines.hxx>
70 #include <unosrch.hxx>
71 #include <sfx2/dispatch.hxx>
72 #include <sfx2/request.hxx>
73 #include <sfx2/objsh.hxx>
74 #include <unoprnms.hxx>
75 #include <unostyle.hxx>
76 #include <unodraw.hxx>
77 #include <svl/eitem.hxx>
78 #include <pagedesc.hxx>
79 #include <unotools/datetime.hxx>
80 #include <unotools/textsearch.hxx>
81 #include <unocrsr.hxx>
82 #include <unofieldcoll.hxx>
83 #include <unoidxcoll.hxx>
84 #include <unocrsrhelper.hxx>
85 #include <unotxvw.hxx>
86 #include <poolfmt.hxx>
87 #include <globdoc.hxx>
88 #include <viewopt.hxx>
89 #include <unochart.hxx>
90 #include <charatr.hxx>
91 #include <svx/xmleohlp.hxx>
92 #include <globals.hrc>
93 #include <unomid.h>
94 #include <unotools/printwarningoptions.hxx>
95 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
96 #include <com/sun/star/lang/DisposedException.hpp>
97 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
98 #include <com/sun/star/lang/NoSupportException.hpp>
99 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
100 #include <com/sun/star/beans/PropertyAttribute.hpp>
101 #include <com/sun/star/beans/XFastPropertySet.hpp>
102 #include <com/sun/star/document/RedlineDisplayType.hpp>
103 #include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
104 #include <com/sun/star/frame/XController.hpp>
105 #include <com/sun/star/frame/XFrame.hpp>
106 #include <com/sun/star/script/XInvocation.hpp>
107 #include <sfx2/linkmgr.hxx>
108 #include <svx/unofill.hxx>
109 #include <editeng/unolingu.hxx>
110 #include <sfx2/progress.hxx>
111 #include <swmodule.hxx>
112 #include <docstat.hxx>
113 #include <modcfg.hxx>
114 #include <ndtxt.hxx>
115 #include <strings.hrc>
116 #include <bitmaps.hlst>
117 #include <swcont.hxx>
118 #include "unodefaults.hxx"
119 #include "SwXDocumentSettings.hxx"
120 #include <doc.hxx>
121 #include <IDocumentSettingAccess.hxx>
122 #include <IDocumentDeviceAccess.hxx>
123 #include <IDocumentDrawModelAccess.hxx>
124 #include <IDocumentChartDataProviderAccess.hxx>
125 #include <IDocumentLinksAdministration.hxx>
126 #include <IDocumentRedlineAccess.hxx>
127 #include <IDocumentFieldsAccess.hxx>
128 #include <IDocumentStatistics.hxx>
129 #include <IDocumentStylePoolAccess.hxx>
130 #include <IDocumentLayoutAccess.hxx>
131 #include <IDocumentState.hxx>
132 #include <editeng/forbiddencharacterstable.hxx>
133 #include <svl/zforlist.hxx>
134 #include <drawdoc.hxx>
135 #include <SwStyleNameMapper.hxx>
136 #include <osl/file.hxx>
137 #include <comphelper/lok.hxx>
138 #include <comphelper/storagehelper.hxx>
139 #include <cppuhelper/supportsservice.hxx>
140 #include <unotools/saveopt.hxx>
141 #include <swruler.hxx>
142 #include <docufld.hxx>
143 
144 
145 #include <EnhancedPDFExportHelper.hxx>
146 #include <numrule.hxx>
147 
148 #include <editeng/langitem.hxx>
149 #include <docary.hxx>
150 #include <i18nlangtag/languagetag.hxx>
151 #include <i18nutil/searchopt.hxx>
152 
153 #include <format.hxx>
154 #include <charfmt.hxx>
155 #include <fmtcol.hxx>
156 #include <istyleaccess.hxx>
157 
158 #include <svl/stylepool.hxx>
159 #include <swatrset.hxx>
160 #include <view.hxx>
161 #include <viscrs.hxx>
162 #include <srcview.hxx>
163 #include <edtwin.hxx>
164 #include <swdtflvr.hxx>
165 #include <PostItMgr.hxx>
166 
167 #include <svtools/langtab.hxx>
168 #include <map>
169 #include <set>
170 #include <vector>
171 
172 #include <editeng/eeitem.hxx>
173 #include <editeng/editeng.hxx>
174 #include <editeng/editview.hxx>
175 #include <svx/svdoutl.hxx>
176 #include <svl/languageoptions.hxx>
177 #include <svx/svdview.hxx>
178 #include <comphelper/servicehelper.hxx>
179 #include <SwSpellDialogChildWindow.hxx>
180 #include <memory>
181 #include <fchrfmt.hxx>
182 #include <redline.hxx>
183 #include <DocumentRedlineManager.hxx>
184 
185 #define TWIPS_PER_PIXEL 15
186 
187 using namespace ::com::sun::star;
188 using namespace ::com::sun::star::text;
189 using namespace ::com::sun::star::i18n;
190 using namespace ::com::sun::star::uno;
191 using namespace ::com::sun::star::beans;
192 using namespace ::com::sun::star::lang;
193 using namespace ::com::sun::star::container;
194 using namespace ::com::sun::star::document;
195 using ::osl::FileBase;
196 
197 static std::unique_ptr<SwPrintUIOptions> lcl_GetPrintUIOptions(
198     SwDocShell * pDocShell,
199     const SfxViewShell * pView )
200 {
201     if (!pDocShell)
202         return nullptr;
203 
204     const bool bWebDoc      = nullptr != dynamic_cast< const SwWebDocShell * >(pDocShell);
205     const bool bSwSrcView   = nullptr != dynamic_cast< const SwSrcView * >(pView);
206     const SwView * pSwView = dynamic_cast< const SwView * >(pView);
207     const bool bHasSelection    = pSwView && pSwView->HasSelection( false );  // check for any selection, not just text selection
208     const bool bHasPostIts      = sw_GetPostIts( &pDocShell->GetDoc()->getIDocumentFieldsAccess(), nullptr );
209 
210     // get default values to use in dialog from documents SwPrintData
211     const SwPrintData &rPrintData = pDocShell->GetDoc()->getIDocumentDeviceAccess().getPrintData();
212 
213     // Get current page number
214     sal_uInt16 nCurrentPage = 1;
215     const SwWrtShell* pSh = pDocShell->GetWrtShell();
216     const SwRootFrame *pFrame = nullptr;
217     if (pSh)
218     {
219         SwPaM* pShellCursor = pSh->GetCursor();
220         nCurrentPage = pShellCursor->GetPageNum();
221         pFrame = pSh->GetLayout();
222     }
223     else if (!bSwSrcView)
224     {
225         const SwPagePreview* pPreview = dynamic_cast< const SwPagePreview* >(pView);
226         OSL_ENSURE(pPreview, "Unexpected type of the view shell");
227         if (pPreview)
228         {
229             nCurrentPage = pPreview->GetSelectedPage();
230             pFrame = pPreview->GetViewShell()->GetLayout();
231         }
232     }
233 
234     // If blanks are skipped, account for them in initial page range value
235     if (pFrame && !rPrintData.IsPrintEmptyPages())
236     {
237         sal_uInt16 nMax = nCurrentPage;
238         const SwPageFrame *pPage = dynamic_cast<const SwPageFrame*>(pFrame->Lower());
239         while (pPage && nMax-- > 0)
240         {
241             if (pPage->getFrameArea().Height() == 0)
242                 nCurrentPage--;
243             pPage = static_cast<const SwPageFrame*>(pPage->GetNext());
244         }
245     }
246     return std::make_unique<SwPrintUIOptions>( nCurrentPage, bWebDoc, bSwSrcView, bHasSelection, bHasPostIts, rPrintData );
247 }
248 
249 static SwTextFormatColl *lcl_GetParaStyle(const OUString& rCollName, SwDoc* pDoc)
250 {
251     SwTextFormatColl* pColl = pDoc->FindTextFormatCollByName( rCollName );
252     if( !pColl )
253     {
254         const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(
255             rCollName, SwGetPoolIdFromName::TxtColl );
256         if( USHRT_MAX != nId )
257             pColl = pDoc->getIDocumentStylePoolAccess().GetTextCollFromPool( nId );
258     }
259     return pColl;
260 }
261 
262 static void lcl_DisposeView( SfxViewFrame* pToClose, SwDocShell const * pDocShell )
263 {
264     // check if the view frame still exists
265     SfxViewFrame* pFound = SfxViewFrame::GetFirst( pDocShell, false );
266     while(pFound)
267     {
268         if( pFound == pToClose)
269         {
270             pToClose->DoClose();
271             break;
272         }
273         pFound = SfxViewFrame::GetNext( *pFound, pDocShell, false );
274     }
275 }
276 
277 class SwXTextDocument::Impl
278 {
279 private:
280     ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper2
281 
282 public:
283     ::comphelper::OInterfaceContainerHelper2 m_RefreshListeners;
284 
285     Impl() : m_RefreshListeners(m_Mutex) { }
286 
287 };
288 
289 namespace
290 {
291     class theSwXTextDocumentUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextDocumentUnoTunnelId > {};
292 }
293 
294 const Sequence< sal_Int8 > & SwXTextDocument::getUnoTunnelId()
295 {
296     return theSwXTextDocumentUnoTunnelId::get().getSeq();
297 }
298 
299 sal_Int64 SAL_CALL SwXTextDocument::getSomething( const Sequence< sal_Int8 >& rId )
300 {
301     if( rId.getLength() == 16
302         && 0 == memcmp( getUnoTunnelId().getConstArray(),
303                                         rId.getConstArray(), 16 ) )
304     {
305             return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this ));
306     }
307     if( rId.getLength() == 16
308         && 0 == memcmp( SfxObjectShell::getUnoTunnelId().getConstArray(),
309                                         rId.getConstArray(), 16 ) )
310     {
311         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(pDocShell ));
312     }
313 
314     sal_Int64 nRet = SfxBaseModel::getSomething( rId );
315     if (nRet)
316         return nRet;
317 
318     GetNumberFormatter();
319     if (!xNumFormatAgg.is()) // may happen if not valid or no SwDoc
320         return 0;
321     Any aNumTunnel = xNumFormatAgg->queryAggregation(cppu::UnoType<XUnoTunnel>::get());
322     Reference<XUnoTunnel> xNumTunnel;
323     aNumTunnel >>= xNumTunnel;
324     return (xNumTunnel.is()) ? xNumTunnel->getSomething(rId) : 0;
325 }
326 
327 Any SAL_CALL SwXTextDocument::queryInterface( const uno::Type& rType )
328 {
329     Any aRet = SwXTextDocumentBaseClass::queryInterface(rType);
330     if ( !aRet.hasValue() )
331         aRet = SfxBaseModel::queryInterface(rType);
332     if ( !aRet.hasValue() &&
333         rType == cppu::UnoType<lang::XMultiServiceFactory>::get())
334     {
335         Reference<lang::XMultiServiceFactory> xTmp = this;
336         aRet <<= xTmp;
337     }
338     if ( !aRet.hasValue() &&
339         rType == cppu::UnoType<tiledrendering::XTiledRenderable>::get())
340     {
341         Reference<tiledrendering::XTiledRenderable> xTmp = this;
342         aRet <<= xTmp;
343     }
344 
345     if ( !aRet.hasValue()
346         && rType != cppu::UnoType<css::document::XDocumentEventBroadcaster>::get()
347         && rType != cppu::UnoType<css::frame::XController>::get()
348         && rType != cppu::UnoType<css::frame::XFrame>::get()
349         && rType != cppu::UnoType<css::script::XInvocation>::get()
350         && rType != cppu::UnoType<css::beans::XFastPropertySet>::get()
351         && rType != cppu::UnoType<css::awt::XWindow>::get())
352     {
353         GetNumberFormatter();
354         if(xNumFormatAgg.is())
355             aRet = xNumFormatAgg->queryAggregation(rType);
356     }
357     return aRet;
358 }
359 
360 void SAL_CALL SwXTextDocument::acquire()throw()
361 {
362     SfxBaseModel::acquire();
363 }
364 
365 void SAL_CALL SwXTextDocument::release()throw()
366 {
367     SfxBaseModel::release();
368 }
369 
370 Reference< XAdapter > SwXTextDocument::queryAdapter(  )
371 {
372     return SfxBaseModel::queryAdapter();
373 }
374 
375 Sequence< uno::Type > SAL_CALL SwXTextDocument::getTypes()
376 {
377     Sequence< uno::Type > aNumTypes;
378     GetNumberFormatter();
379     if(xNumFormatAgg.is())
380     {
381         const uno::Type& rProvType = cppu::UnoType<XTypeProvider>::get();
382         Any aNumProv = xNumFormatAgg->queryAggregation(rProvType);
383         Reference<XTypeProvider> xNumProv;
384         if(aNumProv >>= xNumProv)
385         {
386             aNumTypes = xNumProv->getTypes();
387         }
388     }
389     return comphelper::concatSequences(
390             SfxBaseModel::getTypes(),
391             SwXTextDocumentBaseClass::getTypes(),
392             aNumTypes,
393             Sequence {
394                 cppu::UnoType<lang::XMultiServiceFactory>::get(),
395                 cppu::UnoType<tiledrendering::XTiledRenderable>::get()});
396 }
397 
398 SwXTextDocument::SwXTextDocument(SwDocShell* pShell)
399     : SfxBaseModel(pShell)
400     , m_pImpl(new Impl)
401     ,
402     pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_DOCUMENT)),
403 
404     pDocShell(pShell),
405 
406     bObjectValid(pShell != nullptr),
407 
408     pDrawPage(nullptr),
409     mxXDrawPage(),
410     pBodyText(nullptr),
411     mxXNumberingRules(),
412     mxXFootnotes(),
413     mxXFootnoteSettings(),
414     mxXEndnotes(),
415     mxXEndnoteSettings(),
416     mxXReferenceMarks(),
417     mxXTextFieldTypes(),
418     mxXTextFieldMasters(),
419     mxXTextSections(),
420     mxXBookmarks(),
421     mxXTextTables(),
422     mxXTextFrames(),
423     mxXGraphicObjects(),
424     mxXEmbeddedObjects(),
425     mxXStyleFamilies(),
426     mxXAutoStyles(),
427     mxXChapterNumbering(),
428     mxXDocumentIndexes(),
429 
430     mxXLineNumberingProperties(),
431     mxLinkTargetSupplier(),
432     mxXRedlines(),
433     m_pHiddenViewFrame(nullptr),
434     // #i117783#
435     bApplyPagePrintSettingsFromXPagePrintable( false )
436 {
437 }
438 
439 SdrModel& SwXTextDocument::getSdrModelFromUnoModel() const
440 {
441     OSL_ENSURE(pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetOrCreateDrawModel(), "No SdrModel in SwDoc, should not happen");
442     return *pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
443 }
444 
445 SwXTextDocument::~SwXTextDocument()
446 {
447     InitNewDoc();
448     if(xNumFormatAgg.is())
449     {
450         Reference< XInterface >  x0;
451         xNumFormatAgg->setDelegator(x0);
452         xNumFormatAgg = nullptr;
453     }
454     m_pPrintUIOptions.reset();
455     if (m_pRenderData && m_pRenderData->IsViewOptionAdjust())
456     {   // rhbz#827695: this can happen if the last page is not printed
457         // the SwViewShell has been deleted already by SwView::~SwView
458         // FIXME: replace this awful implementation of XRenderable with
459         // something less insane that has its own view
460         m_pRenderData->ViewOptionAdjustCrashPreventionKludge();
461     }
462     m_pRenderData.reset();
463 }
464 
465 SwXDocumentPropertyHelper * SwXTextDocument::GetPropertyHelper ()
466 {
467     if(!mxPropertyHelper.is())
468     {
469         mxPropertyHelper = new SwXDocumentPropertyHelper(*pDocShell->GetDoc());
470     }
471     return mxPropertyHelper.get();
472 }
473 
474 void SwXTextDocument::GetNumberFormatter()
475 {
476     if(IsValid())
477     {
478         if(!xNumFormatAgg.is())
479         {
480             if ( pDocShell->GetDoc() )
481             {
482                 SvNumberFormatsSupplierObj* pNumFormat = new SvNumberFormatsSupplierObj(
483                                     pDocShell->GetDoc()->GetNumberFormatter());
484                 Reference< util::XNumberFormatsSupplier >  xTmp = pNumFormat;
485                 xNumFormatAgg.set(xTmp, UNO_QUERY);
486             }
487             if(xNumFormatAgg.is())
488                 xNumFormatAgg->setDelegator(static_cast<cppu::OWeakObject*>(static_cast<SwXTextDocumentBaseClass*>(this)));
489         }
490         else
491         {
492             const uno::Type& rTunnelType = cppu::UnoType<XUnoTunnel>::get();
493             Any aNumTunnel = xNumFormatAgg->queryAggregation(rTunnelType);
494             SvNumberFormatsSupplierObj* pNumFormat = nullptr;
495             Reference< XUnoTunnel > xNumTunnel;
496             if(aNumTunnel >>= xNumTunnel)
497             {
498                 pNumFormat = reinterpret_cast<SvNumberFormatsSupplierObj*>(
499                         xNumTunnel->getSomething(SvNumberFormatsSupplierObj::getUnoTunnelId()));
500 
501             }
502             OSL_ENSURE(pNumFormat, "No number formatter available");
503             if (pNumFormat && !pNumFormat->GetNumberFormatter())
504                 pNumFormat->SetNumberFormatter(pDocShell->GetDoc()->GetNumberFormatter());
505         }
506     }
507 }
508 
509 Reference< XText >  SwXTextDocument::getText()
510 {
511     SolarMutexGuard aGuard;
512     if(!IsValid())
513         throw DisposedException("", static_cast< XTextDocument* >(this));
514     if(!xBodyText.is())
515     {
516         pBodyText = new SwXBodyText(pDocShell->GetDoc());
517         xBodyText = pBodyText;
518     }
519     return xBodyText;
520 }
521 
522 void SwXTextDocument::reformat()
523 {
524     SolarMutexGuard aGuard;
525     if(!IsValid())
526         throw DisposedException("", static_cast< XTextDocument* >(this));
527 }
528 
529 void SwXTextDocument::lockControllers()
530 {
531     SolarMutexGuard aGuard;
532     if(!IsValid())
533         throw DisposedException("", static_cast< XTextDocument* >(this));
534 
535     maActionArr.emplace_front(new UnoActionContext(pDocShell->GetDoc()));
536 }
537 
538 void SwXTextDocument::unlockControllers()
539 {
540     SolarMutexGuard aGuard;
541     if(maActionArr.empty())
542         throw RuntimeException("Nothing to unlock");
543 
544     maActionArr.pop_front();
545 }
546 
547 sal_Bool SwXTextDocument::hasControllersLocked()
548 {
549     SolarMutexGuard aGuard;
550     return !maActionArr.empty();
551 }
552 
553 Reference< frame::XController >  SwXTextDocument::getCurrentController()
554 {
555     return SfxBaseModel::getCurrentController();
556 }
557 
558 void SwXTextDocument::setCurrentController(const Reference< frame::XController > & xController)
559 {
560     SfxBaseModel::setCurrentController(xController);
561 }
562 
563 Reference< XInterface >  SwXTextDocument::getCurrentSelection()
564 {
565     SolarMutexGuard aGuard;
566     Reference< XInterface >  xRef;
567     if(IsValid())
568     {
569         SwView* pView = static_cast<SwView*>(SfxViewShell::GetFirst(true, checkSfxViewShell<SwView>));
570         while(pView && pView->GetObjectShell() != pDocShell)
571         {
572             pView = static_cast<SwView*>(SfxViewShell::GetNext(*pView, true, checkSfxViewShell<SwView>));
573         }
574         if(pView)
575         {
576             Any aRef = pView->GetUNOObject()->getSelection();
577             aRef >>= xRef;
578         }
579     }
580     return xRef;
581 }
582 
583 sal_Bool SwXTextDocument::attachResource(const OUString& aURL, const Sequence< beans::PropertyValue >& aArgs)
584 {
585     return SfxBaseModel::attachResource(aURL, aArgs);
586 }
587 
588 OUString SwXTextDocument::getURL()
589 {
590     return SfxBaseModel::getURL();
591 }
592 
593 Sequence< beans::PropertyValue > SwXTextDocument::getArgs()
594 {
595     return SfxBaseModel::getArgs();
596 }
597 
598 void SwXTextDocument::connectController(const Reference< frame::XController > & xController)
599 {
600     SfxBaseModel::connectController(xController);
601 }
602 
603 void SwXTextDocument::disconnectController(const Reference< frame::XController > & xController)
604 {
605     SfxBaseModel::disconnectController(xController);
606 }
607 
608 void SwXTextDocument::dispose()
609 {
610     SfxBaseModel::dispose();
611 }
612 
613 void SwXTextDocument::close( sal_Bool bDeliverOwnership )
614 {
615     if(pDocShell)
616     {
617         uno::Sequence< uno::Any > aArgs;
618         pDocShell->CallAutomationDocumentEventSinks( "Close", aArgs );
619     }
620     SolarMutexGuard aGuard;
621     if(IsValid() && m_pHiddenViewFrame)
622         lcl_DisposeView( m_pHiddenViewFrame, pDocShell);
623     SfxBaseModel::close(bDeliverOwnership);
624 }
625 
626 void SwXTextDocument::addEventListener(const Reference< lang::XEventListener > & aListener)
627 {
628     SfxBaseModel::addEventListener(aListener);
629 }
630 
631 void SwXTextDocument::removeEventListener(const Reference< lang::XEventListener > & aListener)
632 {
633     SfxBaseModel::removeEventListener(aListener);
634 }
635 
636 Reference< XPropertySet > SwXTextDocument::getLineNumberingProperties()
637 {
638     SolarMutexGuard aGuard;
639     if(!IsValid())
640         throw DisposedException("", static_cast< XTextDocument* >(this));
641 
642     if(!mxXLineNumberingProperties.is())
643     {
644         mxXLineNumberingProperties = new SwXLineNumberingProperties(pDocShell->GetDoc());
645     }
646     return mxXLineNumberingProperties;
647 }
648 
649 Reference< XIndexReplace >  SwXTextDocument::getChapterNumberingRules()
650 {
651     SolarMutexGuard aGuard;
652     if(!IsValid())
653         throw DisposedException("", static_cast< XTextDocument* >(this));
654     if(!mxXChapterNumbering.is())
655     {
656         mxXChapterNumbering = new SwXChapterNumbering(*pDocShell);
657     }
658     return mxXChapterNumbering;
659 }
660 
661 Reference< XIndexAccess >  SwXTextDocument::getNumberingRules()
662 {
663     SolarMutexGuard aGuard;
664     if(!IsValid())
665         throw DisposedException("", static_cast< XTextDocument* >(this));
666     if(!mxXNumberingRules.is() )
667     {
668         mxXNumberingRules = new SwXNumberingRulesCollection( pDocShell->GetDoc() );
669     }
670     return mxXNumberingRules;
671 }
672 
673 Reference< XIndexAccess >  SwXTextDocument::getFootnotes()
674 {
675     SolarMutexGuard aGuard;
676     if(!IsValid())
677         throw DisposedException("", static_cast< XTextDocument* >(this));
678     if(!mxXFootnotes.is())
679     {
680         mxXFootnotes = new SwXFootnotes(false, pDocShell->GetDoc());
681     }
682     return mxXFootnotes;
683 }
684 
685 Reference< XPropertySet >  SAL_CALL
686         SwXTextDocument::getFootnoteSettings()
687 {
688     SolarMutexGuard aGuard;
689     if(!IsValid())
690         throw DisposedException("", static_cast< XTextDocument* >(this));
691     if(!mxXFootnoteSettings.is())
692     {
693         mxXFootnoteSettings = new SwXFootnoteProperties(pDocShell->GetDoc());
694     }
695     return mxXFootnoteSettings;
696 }
697 
698 Reference< XIndexAccess >  SwXTextDocument::getEndnotes()
699 {
700     SolarMutexGuard aGuard;
701     if(!IsValid())
702         throw DisposedException("", static_cast< XTextDocument* >(this));
703     if(!mxXEndnotes.is())
704     {
705         mxXEndnotes = new SwXFootnotes(true, pDocShell->GetDoc());
706     }
707     return mxXEndnotes;
708 }
709 
710 Reference< XPropertySet >  SwXTextDocument::getEndnoteSettings()
711 {
712     SolarMutexGuard aGuard;
713     if(!IsValid())
714         throw DisposedException("", static_cast< XTextDocument* >(this));
715     if(!mxXEndnoteSettings.is())
716     {
717         mxXEndnoteSettings = new SwXEndnoteProperties(pDocShell->GetDoc());
718     }
719     return mxXEndnoteSettings;
720 }
721 
722 Reference< util::XReplaceDescriptor >  SwXTextDocument::createReplaceDescriptor()
723 {
724     SolarMutexGuard aGuard;
725     Reference< util::XReplaceDescriptor >  xRet = new SwXTextSearch;
726     return xRet;
727 }
728 
729 SwUnoCursor* SwXTextDocument::CreateCursorForSearch(Reference< XTextCursor > & xCursor)
730 {
731     getText();
732     XText *const pText = xBodyText.get();
733     SwXBodyText* pBText = static_cast<SwXBodyText*>(pText);
734     SwXTextCursor *const pXTextCursor = pBText->CreateTextCursor(true);
735     xCursor.set( static_cast<text::XWordCursor*>(pXTextCursor) );
736 
737     auto& rUnoCursor(pXTextCursor->GetCursor());
738     rUnoCursor.SetRemainInSection(false);
739     return &rUnoCursor;
740 }
741 
742 sal_Int32 SwXTextDocument::replaceAll(const Reference< util::XSearchDescriptor > & xDesc)
743 {
744     SolarMutexGuard aGuard;
745     Reference< XUnoTunnel > xDescTunnel(xDesc, UNO_QUERY_THROW);
746     if(!IsValid() || !xDescTunnel->getSomething(SwXTextSearch::getUnoTunnelId()))
747         throw DisposedException("", static_cast< XTextDocument* >(this));
748 
749     Reference< XTextCursor >  xCursor;
750     auto pUnoCursor(CreateCursorForSearch(xCursor));
751 
752     const SwXTextSearch* pSearch = reinterpret_cast<const SwXTextSearch*>(
753             xDescTunnel->getSomething(SwXTextSearch::getUnoTunnelId()));
754 
755     int eRanges(FindRanges::InBody|FindRanges::InSelAll);
756 
757     i18nutil::SearchOptions2 aSearchOpt;
758     pSearch->FillSearchOptions( aSearchOpt );
759 
760     SwDocPositions eStart = pSearch->m_bBack ? SwDocPositions::End : SwDocPositions::Start;
761     SwDocPositions eEnd = pSearch->m_bBack ? SwDocPositions::Start : SwDocPositions::End;
762 
763     // Search should take place anywhere
764     pUnoCursor->SetRemainInSection(false);
765     sal_uInt32 nResult;
766     UnoActionContext aContext(pDocShell->GetDoc());
767     //try attribute search first
768     if(pSearch->HasSearchAttributes()||pSearch->HasReplaceAttributes())
769     {
770         SfxItemSet aSearch(pDocShell->GetDoc()->GetAttrPool(),
771                             svl::Items<RES_CHRATR_BEGIN, RES_CHRATR_END-1,
772                             RES_PARATR_BEGIN, RES_PARATR_END-1,
773                             RES_FRMATR_BEGIN, RES_FRMATR_END-1>{});
774         SfxItemSet aReplace(pDocShell->GetDoc()->GetAttrPool(),
775                             svl::Items<RES_CHRATR_BEGIN, RES_CHRATR_END-1,
776                             RES_PARATR_BEGIN, RES_PARATR_END-1,
777                             RES_FRMATR_BEGIN, RES_FRMATR_END-1>{});
778         pSearch->FillSearchItemSet(aSearch);
779         pSearch->FillReplaceItemSet(aReplace);
780         bool bCancel;
781         nResult = static_cast<sal_Int32>(pUnoCursor->FindAttrs(aSearch, !pSearch->m_bStyles,
782                     eStart, eEnd, bCancel,
783                     static_cast<FindRanges>(eRanges),
784                     !pSearch->m_sSearchText.isEmpty() ? &aSearchOpt : nullptr,
785                     &aReplace ));
786     }
787     else if(pSearch->m_bStyles)
788     {
789         SwTextFormatColl *pSearchColl = lcl_GetParaStyle(pSearch->m_sSearchText, pUnoCursor->GetDoc());
790         SwTextFormatColl *pReplaceColl = lcl_GetParaStyle(pSearch->m_sReplaceText, pUnoCursor->GetDoc());
791 
792         bool bCancel;
793         nResult = pUnoCursor->FindFormat(*pSearchColl,
794                     eStart, eEnd, bCancel,
795                     static_cast<FindRanges>(eRanges), pReplaceColl );
796 
797     }
798     else
799     {
800         //todo/mba: assuming that notes should be omitted
801         bool bCancel;
802         nResult = pUnoCursor->Find_Text(aSearchOpt, false/*bSearchInNotes*/,
803             eStart, eEnd, bCancel,
804             static_cast<FindRanges>(eRanges),
805             true );
806     }
807     return static_cast<sal_Int32>(nResult);
808 
809 }
810 
811 Reference< util::XSearchDescriptor >  SwXTextDocument::createSearchDescriptor()
812 {
813     SolarMutexGuard aGuard;
814     Reference< util::XSearchDescriptor >  xRet = new SwXTextSearch;
815     return xRet;
816 
817 }
818 
819 // Used for findAll/First/Next
820 
821 SwUnoCursor* SwXTextDocument::FindAny(const Reference< util::XSearchDescriptor > & xDesc,
822                                      Reference< XTextCursor > & xCursor,
823                                      bool bAll,
824                                      sal_Int32& nResult,
825                                      Reference< XInterface > const & xLastResult)
826 {
827     Reference< XUnoTunnel > xDescTunnel(xDesc, UNO_QUERY);
828     if(!IsValid() || !xDescTunnel.is() || !xDescTunnel->getSomething(SwXTextSearch::getUnoTunnelId()))
829         return nullptr;
830 
831     auto pUnoCursor(CreateCursorForSearch(xCursor));
832     const SwXTextSearch* pSearch = reinterpret_cast<const SwXTextSearch*>(
833         xDescTunnel->getSomething(SwXTextSearch::getUnoTunnelId()));
834 
835     bool bParentInExtra = false;
836     if(xLastResult.is())
837     {
838         Reference<XUnoTunnel> xCursorTunnel( xLastResult, UNO_QUERY);
839         OTextCursorHelper* pPosCursor = nullptr;
840         if(xCursorTunnel.is())
841         {
842             pPosCursor = reinterpret_cast<OTextCursorHelper*>(xCursorTunnel->getSomething(
843                                     OTextCursorHelper::getUnoTunnelId()));
844         }
845         SwPaM* pCursor = pPosCursor ? pPosCursor->GetPaM() : nullptr;
846         if(pCursor)
847         {
848             *pUnoCursor->GetPoint() = *pCursor->End();
849             pUnoCursor->DeleteMark();
850         }
851         else
852         {
853             SwXTextRange* pRange = nullptr;
854             if(xCursorTunnel.is())
855             {
856                 pRange = reinterpret_cast<SwXTextRange*>(xCursorTunnel->getSomething(
857                                         SwXTextRange::getUnoTunnelId()));
858             }
859             if(!pRange)
860                 return nullptr;
861             pRange->GetPositions(*pUnoCursor);
862             if(pUnoCursor->HasMark())
863             {
864                 if(*pUnoCursor->GetPoint() < *pUnoCursor->GetMark())
865                     pUnoCursor->Exchange();
866                 pUnoCursor->DeleteMark();
867             }
868         }
869         const SwNode& rRangeNode = pUnoCursor->GetNode();
870         bParentInExtra = rRangeNode.FindFlyStartNode() ||
871                             rRangeNode.FindFootnoteStartNode() ||
872                             rRangeNode.FindHeaderStartNode() ||
873                             rRangeNode.FindFooterStartNode() ;
874     }
875 
876     i18nutil::SearchOptions2 aSearchOpt;
877     pSearch->FillSearchOptions( aSearchOpt );
878 
879 /**
880  * The following combinations are allowed:
881  *  - Search in the body:                   -> FindRanges::InBody
882  *  - Search all in the body:               -> FindRanges::InBodyOnly | FindRanges::InSelAll
883  *  - Search in selections: one / all       -> FindRanges::InSel  [ | FindRanges::InSelAll ]
884  *  - Search outside the body: one / all    -> FindRanges::InOther [ | FindRanges::InSelAll ]
885  *  - Search everywhere all:                -> FindRanges::InSelAll
886  */
887     FindRanges eRanges(FindRanges::InBody);
888     if(bParentInExtra)
889         eRanges = FindRanges::InOther;
890     if(bAll) //always - everywhere?
891         eRanges = FindRanges::InSelAll;
892     SwDocPositions eStart = !bAll ? SwDocPositions::Curr : pSearch->m_bBack ? SwDocPositions::End : SwDocPositions::Start;
893     SwDocPositions eEnd = pSearch->m_bBack ? SwDocPositions::Start : SwDocPositions::End;
894 
895     nResult = 0;
896     for (int nSearchProc = 0; nSearchProc < 2; ++nSearchProc)
897     {
898         //try attribute search first
899         if(pSearch->HasSearchAttributes())
900         {
901             SfxItemSet aSearch(
902                 pDocShell->GetDoc()->GetAttrPool(),
903                 svl::Items<
904                     RES_CHRATR_BEGIN, RES_CHRATR_END - 1,
905                     RES_TXTATR_INETFMT, RES_TXTATR_CHARFMT,
906                     RES_PARATR_BEGIN, RES_PARATR_END - 1,
907                     RES_FRMATR_BEGIN, RES_FRMATR_END - 1>{});
908             pSearch->FillSearchItemSet(aSearch);
909             bool bCancel;
910             nResult = static_cast<sal_Int32>(pUnoCursor->FindAttrs(aSearch, !pSearch->m_bStyles,
911                         eStart, eEnd, bCancel,
912                         eRanges,
913                         !pSearch->m_sSearchText.isEmpty() ? &aSearchOpt : nullptr ));
914         }
915         else if(pSearch->m_bStyles)
916         {
917             SwTextFormatColl *pSearchColl = lcl_GetParaStyle(pSearch->m_sSearchText, pUnoCursor->GetDoc());
918             //pSearch->sReplaceText
919             SwTextFormatColl *pReplaceColl = nullptr;
920             bool bCancel;
921             nResult = static_cast<sal_Int32>(pUnoCursor->FindFormat(*pSearchColl,
922                         eStart, eEnd, bCancel,
923                         eRanges, pReplaceColl ));
924         }
925         else
926         {
927             //todo/mba: assuming that notes should be omitted
928             bool bCancel;
929             nResult = static_cast<sal_Int32>(pUnoCursor->Find_Text(aSearchOpt, false/*bSearchInNotes*/,
930                     eStart, eEnd, bCancel,
931                     eRanges ));
932         }
933         if(nResult || (eRanges&(FindRanges::InSelAll|FindRanges::InOther)))
934             break;
935         //second step - find in other
936         eRanges = FindRanges::InOther;
937     }
938     return pUnoCursor;
939 }
940 
941 Reference< XIndexAccess >
942     SwXTextDocument::findAll(const Reference< util::XSearchDescriptor > & xDesc)
943 {
944     SolarMutexGuard aGuard;
945     Reference< XInterface >  xTmp;
946     sal_Int32 nResult = 0;
947     Reference< XTextCursor >  xCursor;
948     auto pResultCursor(FindAny(xDesc, xCursor, true, nResult, xTmp));
949     if(!pResultCursor)
950         throw RuntimeException("No result cursor");
951     Reference< XIndexAccess >  xRet = SwXTextRanges::Create( nResult ? &(*pResultCursor) : nullptr );
952     return xRet;
953 }
954 
955 Reference< XInterface >  SwXTextDocument::findFirst(const Reference< util::XSearchDescriptor > & xDesc)
956 {
957     SolarMutexGuard aGuard;
958     Reference< XInterface >  xTmp;
959     sal_Int32 nResult = 0;
960     Reference< XTextCursor >  xCursor;
961     auto pResultCursor(FindAny(xDesc, xCursor, false, nResult, xTmp));
962     if(!pResultCursor)
963         throw RuntimeException("No result cursor");
964     Reference< XInterface >  xRet;
965     if(nResult)
966     {
967         const uno::Reference< text::XText >  xParent =
968             ::sw::CreateParentXText(*pDocShell->GetDoc(),
969                     *pResultCursor->GetPoint());
970         xRet = *new SwXTextCursor(xParent, *pResultCursor);
971     }
972     return xRet;
973 }
974 
975 Reference< XInterface >  SwXTextDocument::findNext(const Reference< XInterface > & xStartAt,
976             const Reference< util::XSearchDescriptor > & xDesc)
977 {
978     SolarMutexGuard aGuard;
979     sal_Int32 nResult = 0;
980     Reference< XTextCursor >  xCursor;
981     if(!xStartAt.is())
982         throw RuntimeException("xStartAt missing");
983     auto pResultCursor(FindAny(xDesc, xCursor, false, nResult, xStartAt));
984     if(!pResultCursor)
985         throw RuntimeException("No result cursor");
986     Reference< XInterface >  xRet;
987     if(nResult)
988     {
989         const uno::Reference< text::XText >  xParent =
990             ::sw::CreateParentXText(*pDocShell->GetDoc(),
991                     *pResultCursor->GetPoint());
992 
993         xRet = *new SwXTextCursor(xParent, *pResultCursor);
994     }
995     return xRet;
996 }
997 
998 Sequence< beans::PropertyValue > SwXTextDocument::getPagePrintSettings()
999 {
1000     SolarMutexGuard aGuard;
1001     Sequence< beans::PropertyValue > aSeq(9);
1002     if(!IsValid())
1003         throw DisposedException("", static_cast< XTextDocument* >(this));
1004 
1005     beans::PropertyValue* pArray = aSeq.getArray();
1006     SwPagePreviewPrtData aData;
1007     const SwPagePreviewPrtData* pData = pDocShell->GetDoc()->GetPreviewPrtData();
1008     if(pData)
1009         aData = *pData;
1010     Any aVal;
1011     aVal <<= static_cast<sal_Int16>(aData.GetRow());
1012     pArray[0] = beans::PropertyValue("PageRows", -1, aVal, PropertyState_DIRECT_VALUE);
1013     aVal <<= static_cast<sal_Int16>(aData.GetCol());
1014     pArray[1] = beans::PropertyValue("PageColumns", -1, aVal, PropertyState_DIRECT_VALUE);
1015     aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetLeftSpace()));
1016     pArray[2] = beans::PropertyValue("LeftMargin", -1, aVal, PropertyState_DIRECT_VALUE);
1017     aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetRightSpace()));
1018     pArray[3] = beans::PropertyValue("RightMargin", -1, aVal, PropertyState_DIRECT_VALUE);
1019     aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetTopSpace()));
1020     pArray[4] = beans::PropertyValue("TopMargin", -1, aVal, PropertyState_DIRECT_VALUE);
1021     aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetBottomSpace()));
1022     pArray[5] = beans::PropertyValue("BottomMargin", -1, aVal, PropertyState_DIRECT_VALUE);
1023     aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetHorzSpace()));
1024     pArray[6] = beans::PropertyValue("HoriMargin", -1, aVal, PropertyState_DIRECT_VALUE);
1025     aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetVertSpace()));
1026     pArray[7] = beans::PropertyValue("VertMargin", -1, aVal, PropertyState_DIRECT_VALUE);
1027     aVal <<= aData.GetLandscape();
1028     pArray[8] = beans::PropertyValue("IsLandscape", -1, aVal, PropertyState_DIRECT_VALUE);
1029 
1030     return aSeq;
1031 }
1032 
1033 static sal_uInt32 lcl_Any_To_ULONG(const Any& rValue, bool& bException)
1034 {
1035     bException = false;
1036     TypeClass eType = rValue.getValueType().getTypeClass();
1037 
1038     sal_uInt32 nRet = 0;
1039     if( eType == TypeClass_UNSIGNED_LONG )
1040         rValue >>= nRet;
1041     else
1042     {
1043          sal_Int32 nVal=0;
1044          bException = !(rValue >>= nVal);
1045          if( !bException )
1046             nRet = static_cast<sal_uInt32>(nVal);
1047     }
1048 
1049     return nRet;
1050 }
1051 
1052 static OUString lcl_CreateOutlineString( size_t nIndex,
1053             const SwOutlineNodes& rOutlineNodes, const SwNumRule* pOutlRule)
1054 {
1055     OUStringBuffer sEntry;
1056     const SwTextNode * pTextNd = rOutlineNodes[ nIndex ]->GetTextNode();
1057     SwNumberTree::tNumberVector aNumVector = pTextNd->GetNumberVector();
1058     if( pOutlRule && pTextNd->GetNumRule())
1059         for( int nLevel = 0;
1060              nLevel <= pTextNd->GetActualListLevel();
1061              nLevel++ )
1062         {
1063             long nVal = aNumVector[nLevel];
1064             nVal ++;
1065             nVal -= pOutlRule->Get(nLevel).GetStart();
1066             sEntry.append(OUString::number( nVal ));
1067             sEntry.append(".");
1068         }
1069     sEntry.append( rOutlineNodes[ nIndex ]->
1070                     GetTextNode()->GetExpandText(nullptr) );
1071     return sEntry.makeStringAndClear();
1072 }
1073 
1074 void SwXTextDocument::setPagePrintSettings(const Sequence< beans::PropertyValue >& aSettings)
1075 {
1076     SolarMutexGuard aGuard;
1077     if(!IsValid())
1078         throw DisposedException("", static_cast< XTextDocument* >(this));
1079 
1080     SwPagePreviewPrtData aData;
1081     //if only a few properties are coming, then use the current settings
1082     const SwPagePreviewPrtData* pData = pDocShell->GetDoc()->GetPreviewPrtData();
1083     if(pData)
1084         aData = *pData;
1085     const beans::PropertyValue* pProperties = aSettings.getConstArray();
1086     int nCount = aSettings.getLength();
1087     for(int i = 0; i < nCount; i++)
1088     {
1089         OUString sName = pProperties[i].Name;
1090         const Any& rVal = pProperties[i].Value;
1091         bool bException;
1092         sal_uInt32 nVal = lcl_Any_To_ULONG(rVal, bException);
1093         if( sName == "PageRows" )
1094         {
1095             if(!nVal || nVal > 0xff)
1096                 throw RuntimeException("Invalid value");
1097             aData.SetRow(static_cast<sal_uInt8>(nVal));
1098         }
1099         else if(sName == "PageColumns")
1100         {
1101             if(!nVal  || nVal > 0xff)
1102                 throw RuntimeException("Invalid value");
1103             aData.SetCol(static_cast<sal_uInt8>(nVal));
1104         }
1105         else if(sName == "LeftMargin")
1106         {
1107             aData.SetLeftSpace(convertMm100ToTwip(nVal));
1108         }
1109         else if(sName == "RightMargin")
1110         {
1111             aData.SetRightSpace(convertMm100ToTwip(nVal));
1112         }
1113         else if(sName == "TopMargin")
1114         {
1115             aData.SetTopSpace(convertMm100ToTwip(nVal));
1116         }
1117         else if(sName == "BottomMargin")
1118         {
1119             aData.SetBottomSpace(convertMm100ToTwip(nVal));
1120         }
1121         else if(sName == "HoriMargin")
1122         {
1123             aData.SetHorzSpace(convertMm100ToTwip(nVal));
1124         }
1125         else if(sName == "VertMargin")
1126         {
1127             aData.SetVertSpace(convertMm100ToTwip(nVal));
1128         }
1129         else if(sName == "IsLandscape")
1130         {
1131             auto b = o3tl::tryAccess<bool>(rVal);
1132             bException = !b;
1133             if (b)
1134             {
1135                 aData.SetLandscape(*b);
1136             }
1137         }
1138         else
1139             bException = true;
1140         if(bException)
1141             throw RuntimeException();
1142     }
1143     pDocShell->GetDoc()->SetPreviewPrtData(&aData);
1144 
1145 }
1146 
1147 void SwXTextDocument::printPages(const Sequence< beans::PropertyValue >& xOptions)
1148 {
1149     SolarMutexGuard aGuard;
1150     if(!IsValid())
1151         throw DisposedException("", static_cast< XTextDocument* >(this));
1152 
1153     SfxViewFrame* pFrame = SfxViewFrame::LoadHiddenDocument( *pDocShell, SfxInterfaceId(7) );
1154     SfxRequest aReq(FN_PRINT_PAGEPREVIEW, SfxCallMode::SYNCHRON,
1155                                 pDocShell->GetDoc()->GetAttrPool());
1156     aReq.AppendItem(SfxBoolItem(FN_PRINT_PAGEPREVIEW, true));
1157 
1158     for ( int n = 0; n < xOptions.getLength(); ++n )
1159     {
1160         // get Property-Value from options
1161         const beans::PropertyValue &rProp = xOptions.getConstArray()[n];
1162         Any aValue( rProp.Value );
1163 
1164         // FileName-Property?
1165         if ( rProp.Name == UNO_NAME_FILE_NAME )
1166         {
1167             OUString sFileURL;
1168             if ( rProp.Value >>= sFileURL )
1169             {
1170                 // Convert the File URL into a system dependent path, as the SalPrinter expects
1171                 OUString sSystemPath;
1172                 FileBase::getSystemPathFromFileURL ( sFileURL, sSystemPath );
1173                 aReq.AppendItem(SfxStringItem( SID_FILE_NAME, sSystemPath ) );
1174             }
1175             else if ( rProp.Value.getValueType() != cppu::UnoType<void>::get() )
1176                 throw IllegalArgumentException();
1177         }
1178 
1179         // CopyCount-Property
1180         else if ( rProp.Name == UNO_NAME_COPY_COUNT )
1181         {
1182             sal_Int32 nCopies = 0;
1183             aValue >>= nCopies;
1184             aReq.AppendItem(SfxInt16Item( SID_PRINT_COPIES, static_cast<sal_Int16>(nCopies) ) );
1185         }
1186 
1187         // Collate-Property
1188         else if ( rProp.Name == UNO_NAME_COLLATE )
1189         {
1190             auto b = o3tl::tryAccess<bool>(rProp.Value);
1191             if ( !b )
1192                 throw IllegalArgumentException();
1193             aReq.AppendItem(SfxBoolItem( SID_PRINT_COLLATE, *b ) );
1194 
1195         }
1196 
1197         // Sort-Property
1198         else if ( rProp.Name == UNO_NAME_SORT )
1199         {
1200             auto b = o3tl::tryAccess<bool>(rProp.Value);
1201             if ( !b )
1202                 throw IllegalArgumentException();
1203 
1204             aReq.AppendItem(SfxBoolItem( SID_PRINT_SORT, *b ) );
1205         }
1206 
1207         // Pages-Property
1208         else if ( rProp.Name == UNO_NAME_PAGES )
1209         {
1210             OUString sTmp;
1211             if ( !(rProp.Value >>= sTmp) )
1212                 throw IllegalArgumentException();
1213 
1214             aReq.AppendItem( SfxStringItem( SID_PRINT_PAGES, sTmp ) );
1215 
1216         }
1217     }
1218 
1219     // #i117783#
1220     bApplyPagePrintSettingsFromXPagePrintable = true;
1221     pFrame->GetViewShell()->ExecuteSlot(aReq);
1222     // Frame close
1223     pFrame->DoClose();
1224 
1225 }
1226 
1227 Reference< XNameAccess >  SwXTextDocument::getReferenceMarks()
1228 {
1229     SolarMutexGuard aGuard;
1230     if(!IsValid())
1231         throw DisposedException("", static_cast< XTextDocument* >(this));
1232     if(!mxXReferenceMarks.is())
1233     {
1234         mxXReferenceMarks = new SwXReferenceMarks(pDocShell->GetDoc());
1235     }
1236     return mxXReferenceMarks;
1237 }
1238 
1239 Reference< XEnumerationAccess >  SwXTextDocument::getTextFields()
1240 {
1241     SolarMutexGuard aGuard;
1242     if(!IsValid())
1243         throw DisposedException("", static_cast< XTextDocument* >(this));
1244     if(!mxXTextFieldTypes.is())
1245     {
1246         mxXTextFieldTypes = new SwXTextFieldTypes(pDocShell->GetDoc());
1247     }
1248     return mxXTextFieldTypes;
1249 }
1250 
1251 Reference< XNameAccess >  SwXTextDocument::getTextFieldMasters()
1252 {
1253     SolarMutexGuard aGuard;
1254     if(!IsValid())
1255         throw DisposedException("", static_cast< XTextDocument* >(this));
1256     if(!mxXTextFieldMasters.is())
1257     {
1258         mxXTextFieldMasters = new SwXTextFieldMasters(pDocShell->GetDoc());
1259     }
1260     return mxXTextFieldMasters;
1261 }
1262 
1263 Reference< XNameAccess >  SwXTextDocument::getEmbeddedObjects()
1264 {
1265     SolarMutexGuard aGuard;
1266     if(!IsValid())
1267         throw DisposedException("", static_cast< XTextDocument* >(this));
1268     if(!mxXEmbeddedObjects.is())
1269     {
1270         mxXEmbeddedObjects = new SwXTextEmbeddedObjects(pDocShell->GetDoc());
1271     }
1272     return mxXEmbeddedObjects;
1273 }
1274 
1275 Reference< XNameAccess >  SwXTextDocument::getBookmarks()
1276 {
1277     SolarMutexGuard aGuard;
1278     if(!IsValid())
1279         throw DisposedException("", static_cast< XTextDocument* >(this));
1280     if(!mxXBookmarks.is())
1281     {
1282         mxXBookmarks = new SwXBookmarks(pDocShell->GetDoc());
1283     }
1284     return mxXBookmarks;
1285 }
1286 
1287 Reference< XNameAccess >  SwXTextDocument::getTextSections()
1288 {
1289     SolarMutexGuard aGuard;
1290     if(!IsValid())
1291         throw DisposedException("", static_cast< XTextDocument* >(this));
1292     if(!mxXTextSections.is())
1293     {
1294         mxXTextSections = new SwXTextSections(pDocShell->GetDoc());
1295     }
1296     return mxXTextSections;
1297 }
1298 
1299 Reference< XNameAccess >  SwXTextDocument::getTextTables()
1300 {
1301     SolarMutexGuard aGuard;
1302     if(!IsValid())
1303         throw DisposedException("", static_cast< XTextDocument* >(this));
1304     if(!mxXTextTables.is())
1305     {
1306         mxXTextTables = new SwXTextTables(pDocShell->GetDoc());
1307     }
1308     return mxXTextTables;
1309 }
1310 
1311 Reference< XNameAccess >  SwXTextDocument::getGraphicObjects()
1312 {
1313     SolarMutexGuard aGuard;
1314     if(!IsValid())
1315         throw DisposedException("", static_cast< XTextDocument* >(this));
1316     if(!mxXGraphicObjects.is())
1317     {
1318         mxXGraphicObjects = new SwXTextGraphicObjects(pDocShell->GetDoc());
1319     }
1320     return mxXGraphicObjects;
1321 }
1322 
1323 Reference< XNameAccess >  SwXTextDocument::getTextFrames()
1324 {
1325     SolarMutexGuard aGuard;
1326     if(!IsValid())
1327         throw DisposedException("", static_cast< XTextDocument* >(this));
1328     if(!mxXTextFrames.is())
1329     {
1330         mxXTextFrames = new SwXTextFrames(pDocShell->GetDoc());
1331     }
1332     return mxXTextFrames;
1333 }
1334 
1335 Reference< XNameAccess >  SwXTextDocument::getStyleFamilies()
1336 {
1337     SolarMutexGuard aGuard;
1338     if(!IsValid())
1339         throw DisposedException("", static_cast< XTextDocument* >(this));
1340     if(!mxXStyleFamilies.is())
1341     {
1342         mxXStyleFamilies = new SwXStyleFamilies(*pDocShell);
1343     }
1344     return mxXStyleFamilies;
1345 }
1346 
1347 uno::Reference< style::XAutoStyles > SwXTextDocument::getAutoStyles(  )
1348 {
1349     SolarMutexGuard aGuard;
1350     if(!IsValid())
1351         throw DisposedException("", static_cast< XTextDocument* >(this));
1352     if(!mxXAutoStyles.is())
1353     {
1354         mxXAutoStyles = new SwXAutoStyles(*pDocShell);
1355     }
1356     return mxXAutoStyles;
1357 
1358 }
1359 
1360 Reference< drawing::XDrawPage >  SwXTextDocument::getDrawPage()
1361 {
1362     SolarMutexGuard aGuard;
1363     if(!IsValid())
1364         throw DisposedException("", static_cast< XTextDocument* >(this));
1365     if(!mxXDrawPage.is())
1366     {
1367         pDrawPage = new SwXDrawPage(pDocShell->GetDoc());
1368         mxXDrawPage = pDrawPage;
1369         // Create a Reference to trigger the complete initialization of the
1370         // object. Otherwise in some corner cases it would get initialized
1371         // at ::InitNewDoc -> which would get called during
1372         // close() or dispose() -> n#681746
1373         uno::Reference<lang::XComponent> xComp( mxXDrawPage, uno::UNO_QUERY );
1374     }
1375     return mxXDrawPage;
1376 }
1377 
1378 class SwDrawPagesObj : public cppu::WeakImplHelper<
1379     css::drawing::XDrawPages,
1380     css::lang::XServiceInfo>
1381 {
1382 private:
1383     css::uno::Reference< css::drawing::XDrawPageSupplier > m_xDoc;
1384 public:
1385     SwDrawPagesObj(const css::uno::Reference< css::drawing::XDrawPageSupplier >& rxDoc) : m_xDoc(rxDoc) {}
1386 
1387     // XDrawPages
1388     virtual css::uno::Reference< css::drawing::XDrawPage > SAL_CALL
1389         insertNewByIndex(sal_Int32 /*nIndex*/) override { throw css::lang::NoSupportException(); }
1390 
1391     virtual void SAL_CALL remove(const css::uno::Reference< css::drawing::XDrawPage >& /*xPage*/) override
1392     {
1393         throw css::lang::NoSupportException();
1394     }
1395 
1396     // XIndexAccess
1397     virtual sal_Int32 SAL_CALL getCount() override { return 1; }
1398 
1399     virtual css::uno::Any SAL_CALL getByIndex(sal_Int32 Index) override
1400     {
1401         if (Index != 0)
1402             throw css::lang::IndexOutOfBoundsException("Writer documents have only one DrawPage!");
1403         return css::uno::Any(m_xDoc->getDrawPage());
1404     }
1405 
1406     // XElementAccess
1407     virtual css::uno::Type SAL_CALL getElementType() override
1408     {
1409         SolarMutexGuard aGuard;
1410         return cppu::UnoType<drawing::XDrawPage>::get();
1411     }
1412 
1413     virtual sal_Bool SAL_CALL hasElements() override { return true; }
1414 
1415     // XServiceInfo
1416     virtual OUString SAL_CALL getImplementationName() override
1417     {
1418         return OUString("SwDrawPagesObj");
1419     }
1420 
1421     virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override
1422     {
1423         return cppu::supportsService(this, ServiceName);
1424     }
1425 
1426     virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
1427     {
1428         return { "com.sun.star.drawing.DrawPages" };
1429     }
1430 };
1431 
1432 // XDrawPagesSupplier
1433 
1434 uno::Reference<drawing::XDrawPages> SAL_CALL SwXTextDocument::getDrawPages()
1435 {
1436     SolarMutexGuard aGuard;
1437     return new SwDrawPagesObj(this);
1438 }
1439 
1440 void SwXTextDocument::Invalidate()
1441 {
1442     bObjectValid = false;
1443     if(xNumFormatAgg.is())
1444     {
1445         const uno::Type& rTunnelType = cppu::UnoType<XUnoTunnel>::get();
1446         Any aNumTunnel = xNumFormatAgg->queryAggregation(rTunnelType);
1447         SvNumberFormatsSupplierObj* pNumFormat = nullptr;
1448         Reference< XUnoTunnel > xNumTunnel;
1449         if(aNumTunnel >>= xNumTunnel)
1450         {
1451             pNumFormat = reinterpret_cast<SvNumberFormatsSupplierObj*>(
1452                     xNumTunnel->getSomething(SvNumberFormatsSupplierObj::getUnoTunnelId()));
1453             pNumFormat->SetNumberFormatter(nullptr);
1454         }
1455         OSL_ENSURE(pNumFormat, "No number formatter available");
1456     }
1457     InitNewDoc();
1458     pDocShell = nullptr;
1459     lang::EventObject const ev(static_cast<SwXTextDocumentBaseClass &>(*this));
1460     m_pImpl->m_RefreshListeners.disposeAndClear(ev);
1461 }
1462 
1463 void SwXTextDocument::Reactivate(SwDocShell* pNewDocShell)
1464 {
1465     if(pDocShell && pDocShell != pNewDocShell)
1466         Invalidate();
1467     pDocShell = pNewDocShell;
1468     bObjectValid = true;
1469 }
1470 
1471 void    SwXTextDocument::InitNewDoc()
1472 {
1473     // first invalidate all collections, then delete references and Set to zero
1474     if(mxXTextTables.is())
1475     {
1476         XNameAccess* pTables = mxXTextTables.get();
1477         static_cast<SwXTextTables*>(pTables)->Invalidate();
1478         mxXTextTables.clear();
1479     }
1480 
1481     if(mxXTextFrames.is())
1482     {
1483         XNameAccess* pFrames = mxXTextFrames.get();
1484         static_cast<SwXTextFrames*>(pFrames)->Invalidate();
1485         mxXTextFrames.clear();
1486     }
1487 
1488     if(mxXGraphicObjects.is())
1489     {
1490         XNameAccess* pFrames = mxXGraphicObjects.get();
1491         static_cast<SwXTextGraphicObjects*>(pFrames)->Invalidate();
1492         mxXGraphicObjects.clear();
1493     }
1494 
1495     if(mxXEmbeddedObjects.is())
1496     {
1497         XNameAccess* pOLE = mxXEmbeddedObjects.get();
1498         static_cast<SwXTextEmbeddedObjects*>(pOLE)->Invalidate();
1499         mxXEmbeddedObjects.clear();
1500     }
1501 
1502     if(xBodyText.is())
1503     {
1504         xBodyText = nullptr;
1505         pBodyText = nullptr;
1506     }
1507 
1508     if(xNumFormatAgg.is())
1509     {
1510         const uno::Type& rTunnelType = cppu::UnoType<XUnoTunnel>::get();
1511         Any aNumTunnel = xNumFormatAgg->queryAggregation(rTunnelType);
1512         SvNumberFormatsSupplierObj* pNumFormat = nullptr;
1513         Reference< XUnoTunnel > xNumTunnel;
1514         if(aNumTunnel >>= xNumTunnel)
1515         {
1516             pNumFormat = reinterpret_cast<SvNumberFormatsSupplierObj*>(
1517                     xNumTunnel->getSomething(SvNumberFormatsSupplierObj::getUnoTunnelId()));
1518 
1519         }
1520         OSL_ENSURE(pNumFormat, "No number formatter available");
1521         if (pNumFormat)
1522             pNumFormat->SetNumberFormatter(nullptr);
1523     }
1524 
1525     if(mxXTextFieldTypes.is())
1526     {
1527         XEnumerationAccess* pT = mxXTextFieldTypes.get();
1528         static_cast<SwXTextFieldTypes*>(pT)->Invalidate();
1529         mxXTextFieldTypes.clear();
1530     }
1531 
1532     if(mxXTextFieldMasters.is())
1533     {
1534         XNameAccess* pT = mxXTextFieldMasters.get();
1535         static_cast<SwXTextFieldMasters*>(pT)->Invalidate();
1536         mxXTextFieldMasters.clear();
1537     }
1538 
1539     if(mxXTextSections.is())
1540     {
1541         XNameAccess* pSect = mxXTextSections.get();
1542         static_cast<SwXTextSections*>(pSect)->Invalidate();
1543         mxXTextSections.clear();
1544     }
1545 
1546     if(mxXDrawPage.is())
1547     {
1548         // #i91798#, #i91895#
1549         // dispose XDrawPage here. We are the owner and know that it is no longer in a valid condition.
1550         uno::Reference<lang::XComponent> xComp( mxXDrawPage, uno::UNO_QUERY );
1551         xComp->dispose();
1552         pDrawPage->InvalidateSwDoc();
1553         mxXDrawPage.clear();
1554     }
1555 
1556     if ( mxXNumberingRules.is() )
1557     {
1558         XIndexAccess* pNum = mxXNumberingRules.get();
1559         static_cast<SwXNumberingRulesCollection*>(pNum)->Invalidate();
1560         mxXNumberingRules.clear();
1561     }
1562 
1563     if(mxXFootnotes.is())
1564     {
1565         XIndexAccess* pFootnote = mxXFootnotes.get();
1566         static_cast<SwXFootnotes*>(pFootnote)->Invalidate();
1567         mxXFootnotes.clear();
1568     }
1569 
1570     if(mxXEndnotes.is())
1571     {
1572         XIndexAccess* pFootnote = mxXEndnotes.get();
1573         static_cast<SwXFootnotes*>(pFootnote)->Invalidate();
1574         mxXEndnotes.clear();
1575     }
1576 
1577     if(mxXDocumentIndexes.is())
1578     {
1579         XIndexAccess* pIdxs = mxXDocumentIndexes.get();
1580         static_cast<SwXDocumentIndexes*>(pIdxs)->Invalidate();
1581         mxXDocumentIndexes.clear();
1582     }
1583 
1584     if(mxXStyleFamilies.is())
1585     {
1586         XNameAccess* pStyles = mxXStyleFamilies.get();
1587         static_cast<SwXStyleFamilies*>(pStyles)->Invalidate();
1588         mxXStyleFamilies.clear();
1589     }
1590     if(mxXAutoStyles.is())
1591     {
1592         XNameAccess* pStyles = mxXAutoStyles.get();
1593         static_cast<SwXAutoStyles*>(pStyles)->Invalidate();
1594         mxXAutoStyles.clear();
1595     }
1596 
1597     if(mxXBookmarks.is())
1598     {
1599         XNameAccess* pBm = mxXBookmarks.get();
1600         static_cast<SwXBookmarks*>(pBm)->Invalidate();
1601         mxXBookmarks.clear();
1602     }
1603 
1604     if(mxXChapterNumbering.is())
1605     {
1606         XIndexReplace* pCh = mxXChapterNumbering.get();
1607         static_cast<SwXChapterNumbering*>(pCh)->Invalidate();
1608         mxXChapterNumbering.clear();
1609     }
1610 
1611     if(mxXFootnoteSettings.is())
1612     {
1613         XPropertySet* pFntSet = mxXFootnoteSettings.get();
1614         static_cast<SwXFootnoteProperties*>(pFntSet)->Invalidate();
1615         mxXFootnoteSettings.clear();
1616     }
1617 
1618     if(mxXEndnoteSettings.is())
1619     {
1620         XPropertySet* pEndSet = mxXEndnoteSettings.get();
1621         static_cast<SwXEndnoteProperties*>(pEndSet)->Invalidate();
1622         mxXEndnoteSettings.clear();
1623     }
1624 
1625     if(mxXLineNumberingProperties.is())
1626     {
1627         XPropertySet* pLine = mxXLineNumberingProperties.get();
1628         static_cast<SwXLineNumberingProperties*>(pLine)->Invalidate();
1629         mxXLineNumberingProperties.clear();
1630     }
1631     if(mxXReferenceMarks.is())
1632     {
1633         XNameAccess* pMarks = mxXReferenceMarks.get();
1634         static_cast<SwXReferenceMarks*>(pMarks)->Invalidate();
1635         mxXReferenceMarks.clear();
1636     }
1637     if(mxLinkTargetSupplier.is())
1638     {
1639         XNameAccess* pAccess = mxLinkTargetSupplier.get();
1640         static_cast<SwXLinkTargetSupplier*>(pAccess)->Invalidate();
1641         mxLinkTargetSupplier.clear();
1642     }
1643     if(mxXRedlines.is())
1644     {
1645         XEnumerationAccess* pMarks = mxXRedlines.get();
1646         static_cast<SwXRedlines*>(pMarks)->Invalidate();
1647         mxXRedlines.clear();
1648     }
1649     if(mxPropertyHelper.is())
1650     {
1651         mxPropertyHelper->Invalidate();
1652         mxPropertyHelper.clear();
1653     }
1654 }
1655 
1656 css::uno::Reference<css::uno::XInterface> SwXTextDocument::create(
1657     OUString const & rServiceName,
1658     css::uno::Sequence<css::uno::Any> const * arguments)
1659 {
1660     SolarMutexGuard aGuard;
1661     if (!IsValid())
1662         throw DisposedException("", static_cast< XTextDocument* >(this));
1663 
1664     const SwServiceType nType = SwXServiceProvider::GetProviderType(rServiceName);
1665     if (nType != SwServiceType::Invalid)
1666     {
1667         return SwXServiceProvider::MakeInstance(nType, *pDocShell->GetDoc());
1668     }
1669     if (rServiceName == "com.sun.star.drawing.DashTable")
1670     {
1671         return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Dash);
1672     }
1673     if (rServiceName == "com.sun.star.drawing.GradientTable")
1674     {
1675         return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Gradient);
1676     }
1677     if (rServiceName == "com.sun.star.drawing.HatchTable")
1678     {
1679         return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Hatch);
1680     }
1681     if (rServiceName == "com.sun.star.drawing.BitmapTable")
1682     {
1683         return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Bitmap);
1684     }
1685     if (rServiceName == "com.sun.star.drawing.TransparencyGradientTable")
1686     {
1687         return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::TransGradient);
1688     }
1689     if (rServiceName == "com.sun.star.drawing.MarkerTable")
1690     {
1691         return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Marker);
1692     }
1693     if (rServiceName == "com.sun.star.drawing.Defaults")
1694     {
1695         return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Defaults);
1696     }
1697     if (rServiceName == "com.sun.star.document.Settings")
1698     {
1699         return Reference<XInterface>(*new SwXDocumentSettings(this));
1700     }
1701     if (rServiceName == "com.sun.star.document.ImportEmbeddedObjectResolver")
1702     {
1703         return static_cast<cppu::OWeakObject *>(
1704             new SvXMLEmbeddedObjectHelper(
1705                 *pDocShell, SvXMLEmbeddedObjectHelperMode::Read));
1706     }
1707     if (rServiceName == "com.sun.star.text.DocumentSettings")
1708     {
1709         return Reference<XInterface>(*new SwXDocumentSettings(this));
1710     }
1711     if (rServiceName == "com.sun.star.chart2.data.DataProvider")
1712     {
1713         return Reference<XInterface>(
1714             dynamic_cast<chart2::data::XDataProvider *>(
1715                 pDocShell->getIDocumentChartDataProviderAccess().
1716                 GetChartDataProvider()));
1717     }
1718     if (!rServiceName.startsWith("com.sun.star.")
1719         || rServiceName.endsWith(".OLE2Shape"))
1720     {
1721         // We do not want to insert OLE2 Shapes (e.g.,
1722         // "com.sun.star.drawing.OLE2Shape", ...) like this (by creating them
1723         // with the documents factory and adding the shapes to the draw page);
1724         // for inserting OLE objects the proper way is to use
1725         // "com.sun.star.text.TextEmbeddedObject":
1726         throw ServiceNotRegisteredException();
1727     }
1728     // The XML import is allowed to create instances of
1729     // "com.sun.star.drawing.OLE2Shape"; thus, a temporary service name is
1730     // introduced to make this possible:
1731     OUString aTmpServiceName(rServiceName);
1732     if (rServiceName == "com.sun.star.drawing.temporaryForXMLImportOLE2Shape")
1733     {
1734         aTmpServiceName = "com.sun.star.drawing.OLE2Shape";
1735     }
1736     Reference<XInterface> xTmp(
1737         arguments == nullptr
1738         ? SvxFmMSFactory::createInstance(aTmpServiceName)
1739         : SvxFmMSFactory::createInstanceWithArguments(
1740             aTmpServiceName, *arguments));
1741     if (rServiceName == "com.sun.star.drawing.GroupShape"
1742         || rServiceName == "com.sun.star.drawing.Shape3DSceneObject")
1743     {
1744         return *new SwXGroupShape(xTmp, pDocShell->GetDoc());
1745     }
1746     if (rServiceName.startsWith("com.sun.star.drawing."))
1747     {
1748         return *new SwXShape(xTmp, pDocShell->GetDoc());
1749     }
1750     return xTmp;
1751 }
1752 
1753 Reference< XInterface >  SwXTextDocument::createInstance(const OUString& rServiceName)
1754 {
1755     return create(rServiceName, nullptr);
1756 }
1757 
1758 Reference< XInterface >  SwXTextDocument::createInstanceWithArguments(
1759         const OUString& ServiceSpecifier,
1760         const Sequence< Any >& Arguments)
1761 {
1762     return create(ServiceSpecifier, &Arguments);
1763 }
1764 
1765 Sequence< OUString > SwXTextDocument::getAvailableServiceNames()
1766 {
1767     static Sequence< OUString > aServices;
1768     if ( !aServices.hasElements() )
1769     {
1770         Sequence< OUString > aRet =  SvxFmMSFactory::getAvailableServiceNames();
1771         OUString* pRet = aRet.getArray();
1772         for ( sal_Int32 i = 0; i < aRet.getLength(); ++i )
1773         {
1774             if ( pRet[i] == "com.sun.star.drawing.OLE2Shape" )
1775             {
1776                 pRet[i] = pRet[aRet.getLength() - 1];
1777                 aRet.realloc( aRet.getLength() - 1 ); // <pRet> no longer valid.
1778                 break;
1779             }
1780         }
1781         Sequence< OUString > aOwn = SwXServiceProvider::GetAllServiceNames();
1782         aServices = SvxFmMSFactory::concatServiceNames(aRet, aOwn);
1783     }
1784 
1785     return aServices;
1786 }
1787 
1788 OUString SwXTextDocument::getImplementationName()
1789 {
1790     return OUString("SwXTextDocument");
1791     /* // Matching the .component information:
1792        return dynamic_cast<SwGlobalDocShell*>( pDocShell ) != nullptr
1793            ? OUString("com.sun.star.comp.Writer.GlobalDocument")
1794            : dynamic_cast<SwWebDocShell*>( pDocShell ) != nullptr
1795            ? OUString("com.sun.star.comp.Writer.WebDocument")
1796            : OUString("com.sun.star.comp.Writer.TextDocument");
1797     */
1798 }
1799 
1800 sal_Bool SwXTextDocument::supportsService(const OUString& rServiceName)
1801 {
1802     return cppu::supportsService(this, rServiceName);
1803 }
1804 
1805 Sequence< OUString > SwXTextDocument::getSupportedServiceNames()
1806 {
1807     bool bWebDoc    = (dynamic_cast<SwWebDocShell*>(    pDocShell) !=  nullptr );
1808     bool bGlobalDoc = (dynamic_cast<SwGlobalDocShell*>( pDocShell) !=  nullptr );
1809     bool bTextDoc   = (!bWebDoc && !bGlobalDoc);
1810 
1811     Sequence< OUString > aRet (3);
1812     OUString* pArray = aRet.getArray();
1813 
1814     pArray[0] = "com.sun.star.document.OfficeDocument";
1815     pArray[1] = "com.sun.star.text.GenericTextDocument";
1816 
1817     if (bTextDoc)
1818         pArray[2] = "com.sun.star.text.TextDocument";
1819     else if (bWebDoc)
1820         pArray[2] = "com.sun.star.text.WebDocument";
1821     else if (bGlobalDoc)
1822         pArray[2] = "com.sun.star.text.GlobalDocument";
1823 
1824     return aRet;
1825 }
1826 
1827 Reference< XIndexAccess >  SwXTextDocument::getDocumentIndexes()
1828 {
1829     SolarMutexGuard aGuard;
1830     if(!IsValid())
1831         throw DisposedException("", static_cast< XTextDocument* >(this));
1832 
1833     if(!mxXDocumentIndexes.is())
1834     {
1835         mxXDocumentIndexes = new SwXDocumentIndexes(pDocShell->GetDoc());
1836     }
1837     return mxXDocumentIndexes;
1838 }
1839 
1840 Reference< XPropertySetInfo >  SwXTextDocument::getPropertySetInfo()
1841 {
1842     static Reference< XPropertySetInfo >  xRet = pPropSet->getPropertySetInfo();
1843     return xRet;
1844 }
1845 
1846 void SwXTextDocument::setPropertyValue(const OUString& rPropertyName, const Any& aValue)
1847 {
1848     SolarMutexGuard aGuard;
1849     if(!IsValid())
1850         throw DisposedException("", static_cast< XTextDocument* >(this));
1851 
1852     const SfxItemPropertySimpleEntry*  pEntry = pPropSet->getPropertyMap().getByName( rPropertyName);
1853 
1854     if(!pEntry)
1855         throw UnknownPropertyException();
1856     if(pEntry->nFlags & PropertyAttribute::READONLY)
1857         throw PropertyVetoException();
1858     switch(pEntry->nWID)
1859     {
1860         case  WID_DOC_CHAR_COUNT     :
1861         case  WID_DOC_PARA_COUNT     :
1862         case  WID_DOC_WORD_COUNT     :
1863             throw RuntimeException(
1864                 "bad WID",
1865                 static_cast< cppu::OWeakObject * >(
1866                     static_cast< SwXTextDocumentBaseClass * >(this)));
1867         case  WID_DOC_WORD_SEPARATOR :
1868         {
1869             OUString sDelim;
1870             aValue >>= sDelim;
1871             SW_MOD()->GetModuleConfig()->SetWordDelimiter(sDelim);
1872         }
1873         break;
1874         case WID_DOC_CHANGES_RECORD:
1875         case WID_DOC_CHANGES_SHOW:
1876         {
1877             bool bSet = *o3tl::doAccess<bool>(aValue);
1878             RedlineFlags eMode = pDocShell->GetDoc()->getIDocumentRedlineAccess().GetRedlineFlags();
1879             if(WID_DOC_CHANGES_SHOW == pEntry->nWID)
1880             {
1881                 eMode |= RedlineFlags(RedlineFlags::ShowInsert | RedlineFlags::ShowDelete);
1882                 if( !bSet )
1883                     pDocShell->GetDoc()->GetDocumentRedlineManager().SetHideRedlines(true);
1884             }
1885             else if(WID_DOC_CHANGES_RECORD == pEntry->nWID)
1886             {
1887                 eMode = bSet ? eMode|RedlineFlags::On : eMode&~RedlineFlags::On;
1888             }
1889             pDocShell->GetDoc()->getIDocumentRedlineAccess().SetRedlineFlags( eMode );
1890         }
1891         break;
1892         case  WID_DOC_CHANGES_PASSWORD:
1893         {
1894             Sequence <sal_Int8> aNew;
1895             if(aValue >>= aNew)
1896             {
1897                 SwDoc* pDoc = pDocShell->GetDoc();
1898                 pDoc->getIDocumentRedlineAccess().SetRedlinePassword(aNew);
1899                 if(aNew.hasElements())
1900                 {
1901                     RedlineFlags eMode = pDoc->getIDocumentRedlineAccess().GetRedlineFlags();
1902                     eMode |= RedlineFlags::On;
1903                     pDoc->getIDocumentRedlineAccess().SetRedlineFlags( eMode );
1904                 }
1905             }
1906         }
1907         break;
1908         case WID_DOC_AUTO_MARK_URL :
1909         {
1910             OUString sURL;
1911             aValue >>= sURL;
1912             pDocShell->GetDoc()->SetTOIAutoMarkURL(sURL);
1913         }
1914         break;
1915         case WID_DOC_HIDE_TIPS :
1916             SW_MOD()->GetModuleConfig()->SetHideFieldTips(*o3tl::doAccess<bool>(aValue));
1917         break;
1918         case WID_DOC_REDLINE_DISPLAY:
1919         {
1920             RedlineFlags eRedMode = pDocShell->GetDoc()->getIDocumentRedlineAccess().GetRedlineFlags();
1921             eRedMode = eRedMode & (~RedlineFlags::ShowMask);
1922             sal_Int16 nSet = 0;
1923             aValue >>= nSet;
1924             switch(nSet)
1925             {
1926                 case RedlineDisplayType::NONE: break;
1927                 case RedlineDisplayType::INSERTED: eRedMode |= RedlineFlags::ShowInsert; break;
1928                 case RedlineDisplayType::REMOVED: eRedMode |= RedlineFlags::ShowDelete;  break;
1929                 case RedlineDisplayType::
1930                         INSERTED_AND_REMOVED: eRedMode |= RedlineFlags::ShowInsert|RedlineFlags::ShowDelete;
1931                 break;
1932                 default: throw IllegalArgumentException();
1933             }
1934             pDocShell->GetDoc()->getIDocumentRedlineAccess().SetRedlineFlags(eRedMode);
1935         }
1936         break;
1937         case WID_DOC_TWO_DIGIT_YEAR:
1938         {
1939             sal_Int16 nYear = 0;
1940             aValue >>= nYear;
1941             SfxRequest aRequest ( SID_ATTR_YEAR2000, SfxCallMode::SLOT, pDocShell->GetDoc()->GetAttrPool());
1942             aRequest.AppendItem(SfxUInt16Item( SID_ATTR_YEAR2000, static_cast < sal_uInt16 > ( nYear ) ) );
1943             pDocShell->Execute ( aRequest );
1944         }
1945         break;
1946         case WID_DOC_AUTOMATIC_CONTROL_FOCUS:
1947         {
1948             SwDrawModel * pDrawDoc;
1949             bool bAuto = *o3tl::doAccess<bool>(aValue);
1950 
1951             if ( nullptr != ( pDrawDoc = pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel() ) )
1952                 pDrawDoc->SetAutoControlFocus( bAuto );
1953             else if (bAuto)
1954             {
1955                 // if setting to true, and we don't have an
1956                 // SdrModel, then we are changing the default and
1957                 // must thus create an SdrModel, if we don't have an
1958                 // SdrModel and we are leaving the default at false,
1959                 // we don't need to make an SdrModel and can do nothing
1960                 // #i52858# - method name changed
1961                 pDrawDoc = pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetOrCreateDrawModel();
1962                 pDrawDoc->SetAutoControlFocus ( bAuto );
1963             }
1964         }
1965         break;
1966         case WID_DOC_APPLY_FORM_DESIGN_MODE:
1967         {
1968             SwDrawModel * pDrawDoc;
1969             bool bMode = *o3tl::doAccess<bool>(aValue);
1970 
1971             if ( nullptr != ( pDrawDoc = pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel() ) )
1972                 pDrawDoc->SetOpenInDesignMode( bMode );
1973             else if (!bMode)
1974             {
1975                 // if setting to false, and we don't have an
1976                 // SdrModel, then we are changing the default and
1977                 // must thus create an SdrModel, if we don't have an
1978                 // SdrModel and we are leaving the default at true,
1979                 // we don't need to make an SdrModel and can do
1980                 // nothing
1981                 // #i52858# - method name changed
1982                 pDrawDoc = pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetOrCreateDrawModel();
1983                 pDrawDoc->SetOpenInDesignMode ( bMode );
1984             }
1985         }
1986         break;
1987         // #i42634# New property to set the bInReading
1988         // flag at the document, used during binary import
1989         case WID_DOC_LOCK_UPDATES :
1990         {
1991             SwDoc* pDoc = pDocShell->GetDoc();
1992             bool bBool (false);
1993             if( aValue >>= bBool )
1994               pDoc->SetInReading( bBool );
1995         }
1996         break;
1997         case WID_DOC_BUILDID:
1998             aValue >>= maBuildId;
1999         break;
2000 
2001         case WID_DOC_DEFAULT_PAGE_MODE:
2002         {
2003             bool bDefaultPageMode( false );
2004             aValue >>= bDefaultPageMode;
2005             pDocShell->GetDoc()->SetDefaultPageMode( bDefaultPageMode );
2006         }
2007         break;
2008         case WID_DOC_INTEROP_GRAB_BAG:
2009              setGrabBagItem(aValue);
2010         break;
2011 
2012         default:
2013         {
2014             const SfxPoolItem& rItem = pDocShell->GetDoc()->GetDefault(pEntry->nWID);
2015             std::unique_ptr<SfxPoolItem> pNewItem(rItem.Clone());
2016             pNewItem->PutValue(aValue, pEntry->nMemberId);
2017             pDocShell->GetDoc()->SetDefault(*pNewItem);
2018         }
2019     }
2020 }
2021 
2022 Any SwXTextDocument::getPropertyValue(const OUString& rPropertyName)
2023 {
2024     SolarMutexGuard aGuard;
2025     if(!IsValid())
2026         throw DisposedException("", static_cast< XTextDocument* >(this));
2027 
2028     const SfxItemPropertySimpleEntry*  pEntry = pPropSet->getPropertyMap().getByName( rPropertyName);
2029 
2030     if(!pEntry)
2031         throw UnknownPropertyException();
2032     Any aAny;
2033     switch(pEntry->nWID)
2034     {
2035         case WID_DOC_ISTEMPLATEID    :
2036             aAny <<= pDocShell->IsTemplate();
2037             break;
2038         case  WID_DOC_CHAR_COUNT     :
2039         case  WID_DOC_PARA_COUNT     :
2040         case  WID_DOC_WORD_COUNT     :
2041         {
2042             const SwDocStat& rStat(pDocShell->GetDoc()->getIDocumentStatistics().GetUpdatedDocStat( false, true ));
2043             sal_Int32 nValue;
2044             switch(pEntry->nWID)
2045             {
2046                 case  WID_DOC_CHAR_COUNT     :nValue = rStat.nChar;break;
2047                 case  WID_DOC_PARA_COUNT     :nValue = rStat.nPara;break;
2048                 case  WID_DOC_WORD_COUNT     :nValue = rStat.nWord;break;
2049             }
2050             aAny <<= nValue;
2051         }
2052         break;
2053         case  WID_DOC_WORD_SEPARATOR :
2054         {
2055             aAny <<= SW_MOD()->GetDocStatWordDelim();
2056         }
2057         break;
2058         case WID_DOC_CHANGES_RECORD:
2059         case WID_DOC_CHANGES_SHOW:
2060         {
2061             const RedlineFlags eMode = pDocShell->GetDoc()->getIDocumentRedlineAccess().GetRedlineFlags();
2062             bool bSet = false;
2063             if(WID_DOC_CHANGES_SHOW == pEntry->nWID)
2064             {
2065                 bSet = IDocumentRedlineAccess::IsShowChanges(eMode);
2066             }
2067             else if(WID_DOC_CHANGES_RECORD == pEntry->nWID)
2068             {
2069                 bSet = bool(eMode & RedlineFlags::On);
2070             }
2071             aAny <<= bSet;
2072         }
2073         break;
2074         case  WID_DOC_CHANGES_PASSWORD:
2075         {
2076             SwDoc* pDoc = pDocShell->GetDoc();
2077             aAny <<= pDoc->getIDocumentRedlineAccess().GetRedlinePassword();
2078         }
2079         break;
2080         case WID_DOC_AUTO_MARK_URL :
2081             aAny <<= pDocShell->GetDoc()->GetTOIAutoMarkURL();
2082         break;
2083         case WID_DOC_HIDE_TIPS :
2084             aAny <<= SW_MOD()->GetModuleConfig()->IsHideFieldTips();
2085         break;
2086         case WID_DOC_REDLINE_DISPLAY:
2087         {
2088             RedlineFlags eRedMode = pDocShell->GetDoc()->getIDocumentRedlineAccess().GetRedlineFlags();
2089             eRedMode = eRedMode & RedlineFlags::ShowMask;
2090             sal_Int16 nRet = RedlineDisplayType::NONE;
2091             if(RedlineFlags::ShowInsert == eRedMode)
2092                 nRet = RedlineDisplayType::INSERTED;
2093             else if(RedlineFlags::ShowDelete == eRedMode)
2094                 nRet = RedlineDisplayType::REMOVED;
2095             else if(RedlineFlags::ShowMask == eRedMode)
2096                 nRet = RedlineDisplayType::INSERTED_AND_REMOVED;
2097             aAny <<= nRet;
2098         }
2099         break;
2100         case WID_DOC_FORBIDDEN_CHARS:
2101         {
2102             GetPropertyHelper();
2103             Reference<XForbiddenCharacters> xRet(static_cast<cppu::OWeakObject*>(mxPropertyHelper.get()), UNO_QUERY);
2104             aAny <<= xRet;
2105         }
2106         break;
2107         case WID_DOC_TWO_DIGIT_YEAR:
2108         {
2109             aAny <<= static_cast < sal_Int16 > (pDocShell->GetDoc()->GetNumberFormatter ()->GetYear2000());
2110         }
2111         break;
2112         case WID_DOC_AUTOMATIC_CONTROL_FOCUS:
2113         {
2114             SwDrawModel * pDrawDoc;
2115             bool bAuto;
2116             if ( nullptr != ( pDrawDoc = pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel() ) )
2117                 bAuto = pDrawDoc->GetAutoControlFocus();
2118             else
2119                 bAuto = false;
2120             aAny <<= bAuto;
2121         }
2122         break;
2123         case WID_DOC_APPLY_FORM_DESIGN_MODE:
2124         {
2125             SwDrawModel * pDrawDoc;
2126             bool bMode;
2127             if ( nullptr != ( pDrawDoc = pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel() ) )
2128                 bMode = pDrawDoc->GetOpenInDesignMode();
2129             else
2130                 bMode = true;
2131             aAny <<= bMode;
2132         }
2133         break;
2134         case WID_DOC_BASIC_LIBRARIES:
2135             aAny <<= pDocShell->GetBasicContainer();
2136         break;
2137         case WID_DOC_DIALOG_LIBRARIES:
2138             aAny <<= pDocShell->GetDialogContainer();
2139         break;
2140         case WID_DOC_VBA_DOCOBJ:
2141         {
2142             /* #i111553# This property provides the name of the constant that
2143                will be used to store this model in the global Basic manager.
2144                That constant will be equivalent to 'ThisComponent' but for
2145                each application, so e.g. a 'ThisExcelDoc' and a 'ThisWordDoc'
2146                constant can co-exist, as required by VBA. */
2147             aAny <<= OUString( "ThisWordDoc" );
2148         }
2149         break;
2150         case WID_DOC_RUNTIME_UID:
2151             aAny <<= getRuntimeUID();
2152         break;
2153         case WID_DOC_LOCK_UPDATES :
2154             aAny <<= pDocShell->GetDoc()->IsInReading();
2155         break;
2156         case WID_DOC_BUILDID:
2157             aAny <<= maBuildId;
2158         break;
2159         case WID_DOC_HAS_VALID_SIGNATURES:
2160             aAny <<= hasValidSignatures();
2161         break;
2162         case WID_DOC_INTEROP_GRAB_BAG:
2163              getGrabBagItem(aAny);
2164         break;
2165 
2166         default:
2167         {
2168             const SfxPoolItem& rItem = pDocShell->GetDoc()->GetDefault(pEntry->nWID);
2169             rItem.QueryValue(aAny, pEntry->nMemberId);
2170         }
2171     }
2172     return aAny;
2173 }
2174 
2175 void SwXTextDocument::addPropertyChangeListener(const OUString& /*PropertyName*/,
2176     const Reference< XPropertyChangeListener > & /*aListener*/)
2177 {
2178     OSL_FAIL("not implemented");
2179 }
2180 
2181 void SwXTextDocument::removePropertyChangeListener(const OUString& /*PropertyName*/,
2182     const Reference< XPropertyChangeListener > & /*aListener*/)
2183 {
2184     OSL_FAIL("not implemented");
2185 }
2186 
2187 void SwXTextDocument::addVetoableChangeListener(const OUString& /*PropertyName*/,
2188     const Reference< XVetoableChangeListener > & /*aListener*/)
2189 {
2190     OSL_FAIL("not implemented");
2191 }
2192 
2193 void SwXTextDocument::removeVetoableChangeListener(const OUString& /*PropertyName*/,
2194                         const Reference< XVetoableChangeListener > & /*aListener*/)
2195 {
2196     OSL_FAIL("not implemented");
2197 }
2198 
2199 Reference< XNameAccess >  SwXTextDocument::getLinks()
2200 {
2201     if(!mxLinkTargetSupplier.is())
2202     {
2203         mxLinkTargetSupplier = new SwXLinkTargetSupplier(*this);
2204     }
2205     return mxLinkTargetSupplier;
2206 }
2207 
2208 Reference< XEnumerationAccess > SwXTextDocument::getRedlines(  )
2209 {
2210     if(!mxXRedlines.is())
2211     {
2212         mxXRedlines = new SwXRedlines(pDocShell->GetDoc());
2213     }
2214     return mxXRedlines;
2215 }
2216 
2217 void SwXTextDocument::NotifyRefreshListeners()
2218 {
2219     // why does SwBaseShell not just call refresh? maybe because it's rSh is
2220     // (sometimes) a different shell than GetWrtShell()?
2221     lang::EventObject const ev(static_cast<SwXTextDocumentBaseClass &>(*this));
2222     m_pImpl->m_RefreshListeners.notifyEach(
2223             & util::XRefreshListener::refreshed, ev);
2224 }
2225 
2226 void SwXTextDocument::refresh()
2227 {
2228     SolarMutexGuard aGuard;
2229     if(!IsValid())
2230         throw DisposedException("", static_cast< XTextDocument* >(this));
2231 
2232     SwViewShell *pViewShell = pDocShell->GetWrtShell();
2233     NotifyRefreshListeners();
2234     if(pViewShell)
2235         pViewShell->CalcLayout();
2236 }
2237 
2238 void SAL_CALL SwXTextDocument::addRefreshListener(
2239         const Reference<util::XRefreshListener> & xListener)
2240 {
2241     // no need to lock here as m_pImpl is const and container threadsafe
2242     m_pImpl->m_RefreshListeners.addInterface(xListener);
2243 }
2244 
2245 void SAL_CALL SwXTextDocument::removeRefreshListener(
2246         const Reference<util::XRefreshListener> & xListener)
2247 {
2248     // no need to lock here as m_pImpl is const and container threadsafe
2249     m_pImpl->m_RefreshListeners.removeInterface(xListener);
2250 }
2251 
2252 void SwXTextDocument::updateLinks(  )
2253 {
2254     SolarMutexGuard aGuard;
2255     if(!IsValid())
2256         throw DisposedException("", static_cast< XTextDocument* >(this));
2257 
2258     SwDoc* pDoc = pDocShell->GetDoc();
2259     sfx2::LinkManager& rLnkMan = pDoc->getIDocumentLinksAdministration().GetLinkManager();
2260     if( !rLnkMan.GetLinks().empty() )
2261     {
2262         UnoActionContext aAction(pDoc);
2263         rLnkMan.UpdateAllLinks( false, true, nullptr );
2264     }
2265 }
2266 
2267 //XPropertyState
2268 PropertyState SAL_CALL SwXTextDocument::getPropertyState( const OUString& rPropertyName )
2269 {
2270     SolarMutexGuard aGuard;
2271     if(!IsValid())
2272         throw DisposedException("", static_cast< XTextDocument* >(this));
2273 
2274     const SfxItemPropertySimpleEntry*  pEntry = pPropSet->getPropertyMap().getByName( rPropertyName);
2275     if(!pEntry)
2276         throw UnknownPropertyException();
2277     return PropertyState_DIRECT_VALUE;
2278 }
2279 
2280 Sequence< PropertyState > SAL_CALL SwXTextDocument::getPropertyStates( const Sequence< OUString >& rPropertyNames )
2281 {
2282     const sal_Int32 nCount = rPropertyNames.getLength();
2283     const OUString * pNames = rPropertyNames.getConstArray();
2284     Sequence < PropertyState > aRet ( nCount );
2285     PropertyState *pState = aRet.getArray();
2286 
2287     for ( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++)
2288         pState[nIndex] = getPropertyState( pNames[nIndex] );
2289 
2290     return aRet;
2291 }
2292 
2293 void SAL_CALL SwXTextDocument::setPropertyToDefault( const OUString& rPropertyName )
2294 {
2295     SolarMutexGuard aGuard;
2296     if(!IsValid())
2297         throw DisposedException("", static_cast< XTextDocument* >(this));
2298 
2299     const SfxItemPropertySimpleEntry*  pEntry = pPropSet->getPropertyMap().getByName( rPropertyName);
2300     if(!pEntry)
2301         throw UnknownPropertyException();
2302     switch(pEntry->nWID)
2303     {
2304         case 0:default:break;
2305     }
2306 }
2307 
2308 Any SAL_CALL SwXTextDocument::getPropertyDefault( const OUString& rPropertyName )
2309 {
2310     SolarMutexGuard aGuard;
2311     if(!IsValid())
2312         throw DisposedException("", static_cast< XTextDocument* >(this));
2313 
2314     const SfxItemPropertySimpleEntry*  pEntry = pPropSet->getPropertyMap().getByName( rPropertyName);
2315     if(!pEntry)
2316         throw UnknownPropertyException();
2317     Any aAny;
2318     switch(pEntry->nWID)
2319     {
2320         case 0:default:break;
2321     }
2322     return aAny;
2323 }
2324 
2325 static VclPtr< OutputDevice > lcl_GetOutputDevice( const SwPrintUIOptions &rPrintUIOptions )
2326 {
2327     VclPtr< OutputDevice > pOut;
2328 
2329     uno::Any aAny( rPrintUIOptions.getValue( "RenderDevice" ));
2330     uno::Reference< awt::XDevice >  xRenderDevice;
2331     aAny >>= xRenderDevice;
2332     if (xRenderDevice.is())
2333     {
2334         VCLXDevice*     pDevice = VCLXDevice::getImplementation( xRenderDevice );
2335         pOut = pDevice ? pDevice->GetOutputDevice() : VclPtr< OutputDevice >();
2336     }
2337 
2338     return pOut;
2339 }
2340 
2341 static bool lcl_SeqHasProperty(
2342     const uno::Sequence< beans::PropertyValue >& rOptions,
2343     const sal_Char *pPropName )
2344 {
2345     bool bRes = false;
2346     const sal_Int32 nLen = rOptions.getLength();
2347     const beans::PropertyValue *pProps = rOptions.getConstArray();
2348     for (sal_Int32 i = 0;  i < nLen && !bRes;  ++i)
2349     {
2350         if (pProps[i].Name.equalsAscii( pPropName ))
2351             bRes = true;
2352     }
2353     return bRes;
2354 }
2355 
2356 static bool lcl_GetBoolProperty(
2357     const uno::Sequence< beans::PropertyValue >& rOptions,
2358     const sal_Char *pPropName )
2359 {
2360     bool bRes = false;
2361     const sal_Int32 nLen = rOptions.getLength();
2362     const beans::PropertyValue *pProps = rOptions.getConstArray();
2363     for ( sal_Int32 i = 0;  i < nLen;  ++i )
2364     {
2365         if ( pProps[i].Name.equalsAscii( pPropName ) )
2366         {
2367             pProps[i].Value >>= bRes;
2368             break;
2369         }
2370     }
2371     return bRes;
2372 }
2373 
2374 SfxViewShell * SwXTextDocument::GetRenderView(
2375     bool &rbIsSwSrcView,
2376     const uno::Sequence< beans::PropertyValue >& rOptions,
2377     bool bIsPDFExport )
2378 {
2379     // get view shell to use
2380     SfxViewShell *pView = nullptr;
2381     if (bIsPDFExport)
2382         pView = GuessViewShell( rbIsSwSrcView );
2383     else
2384     {
2385         uno::Any aTmp;
2386         const sal_Int32 nLen = rOptions.getLength();
2387         const beans::PropertyValue *pProps = rOptions.getConstArray();
2388         for (sal_Int32 i = 0; i < nLen; ++i)
2389         {
2390             if ( pProps[i].Name == "View" )
2391             {
2392                 aTmp = pProps[i].Value;
2393                 break;
2394             }
2395         }
2396 
2397         uno::Reference< frame::XController > xController;
2398         if (aTmp >>= xController)
2399         {
2400             OSL_ENSURE( xController.is(), "controller is empty!" );
2401             pView = GuessViewShell( rbIsSwSrcView, xController );
2402         }
2403     }
2404     return pView;
2405 }
2406 
2407 /*
2408  *  GetRenderDoc:
2409  *  returns the document to be rendered, usually this will be the 'regular'
2410  *  document but in case of PDF export of (multi-)selection it will
2411  *  be a temporary document that gets created if not already done.
2412  *  The rpView variable will be set (if not already done) to the used
2413  *  SfxViewShell.
2414 */
2415 SwDoc * SwXTextDocument::GetRenderDoc(
2416     SfxViewShell *&rpView,
2417     const uno::Any& rSelection,
2418     bool bIsPDFExport )
2419 {
2420     SwDoc *pDoc = nullptr;
2421 
2422     uno::Reference< frame::XModel > xModel;
2423     rSelection >>= xModel;
2424     if (xModel == pDocShell->GetModel())
2425         pDoc = pDocShell->GetDoc();
2426     else
2427     {
2428         OSL_ENSURE( !xModel.is(), "unexpected model found" );
2429 
2430         if (rSelection.hasValue())     // is anything selected ?
2431         {
2432             // this part should only be called when a temporary document needs to be created,
2433             // for example for PDF export or printing of (multi-)selection only.
2434 
2435             if (!rpView)
2436             {
2437                 bool bIsSwSrcView = false;
2438                 // aside from maybe PDF export the view should always have been provided!
2439                 OSL_ENSURE( bIsPDFExport, "view is missing, guessing one..." );
2440 
2441                 rpView = GuessViewShell( bIsSwSrcView );
2442             }
2443             OSL_ENSURE( rpView, "SwViewShell missing" );
2444             // the view shell should be SwView for documents PDF export.
2445             // for the page preview no selection should be possible
2446             // (the export dialog does not allow for this option)
2447             if (auto pSwView = dynamic_cast<SwView *>( rpView ))
2448             {
2449                 if (!m_pRenderData)
2450                 {
2451                     OSL_FAIL("GetRenderDoc: no renderdata");
2452                     return nullptr;
2453                 }
2454                 SfxObjectShellLock xDocSh(m_pRenderData->GetTempDocShell());
2455                 if (!xDocSh.Is())
2456                 {
2457                     xDocSh = pSwView->CreateTmpSelectionDoc();
2458                     m_pRenderData->SetTempDocShell(xDocSh);
2459                 }
2460                 if (xDocSh.Is())
2461                 {
2462                     pDoc = static_cast<SwDocShell*>(&xDocSh)->GetDoc();
2463                     rpView = pDoc->GetDocShell()->GetView();
2464                 }
2465             }
2466             else
2467             {
2468                 OSL_FAIL("unexpected SwViewShell" );
2469             }
2470         }
2471     }
2472     return pDoc;
2473 }
2474 
2475 static void lcl_SavePrintUIOptionsToDocumentPrintData(
2476     SwDoc &rDoc,
2477     const SwPrintUIOptions &rPrintUIOptions,
2478     bool bIsPDFEXport )
2479 {
2480     SwPrintData aDocPrintData( rDoc.getIDocumentDeviceAccess().getPrintData() );
2481 
2482     aDocPrintData.SetPrintGraphic( rPrintUIOptions.IsPrintGraphics() );
2483     aDocPrintData.SetPrintTable( true ); // for now it was decided that tables should always be printed
2484     aDocPrintData.SetPrintDraw( rPrintUIOptions.IsPrintDrawings() );
2485     aDocPrintData.SetPrintControl( rPrintUIOptions.IsPrintFormControls() );
2486     aDocPrintData.SetPrintLeftPage( rPrintUIOptions.IsPrintLeftPages() );
2487     aDocPrintData.SetPrintRightPage( rPrintUIOptions.IsPrintRightPages() );
2488     aDocPrintData.SetPrintReverse( false ); /*handled by print dialog now*/
2489     aDocPrintData.SetPaperFromSetup( rPrintUIOptions.IsPaperFromSetup() );
2490     aDocPrintData.SetPrintEmptyPages( rPrintUIOptions.IsPrintEmptyPages( bIsPDFEXport ) );
2491     aDocPrintData.SetPrintPostIts( rPrintUIOptions.GetPrintPostItsType() );
2492     aDocPrintData.SetPrintProspect( rPrintUIOptions.IsPrintProspect() );
2493     aDocPrintData.SetPrintProspect_RTL( rPrintUIOptions.IsPrintProspectRTL() );
2494     aDocPrintData.SetPrintPageBackground( rPrintUIOptions.IsPrintPageBackground() );
2495     aDocPrintData.SetPrintBlackFont( rPrintUIOptions.IsPrintWithBlackTextColor() );
2496     // aDocPrintData.SetPrintSingleJobs( b ); handled by File/Print dialog itself
2497     // arDocPrintData.SetFaxName( s ); n/a in File/Print dialog
2498     aDocPrintData.SetPrintHiddenText( rPrintUIOptions.IsPrintHiddenText() );
2499     aDocPrintData.SetPrintTextPlaceholder( rPrintUIOptions.IsPrintTextPlaceholders() );
2500 
2501     rDoc.getIDocumentDeviceAccess().setPrintData( aDocPrintData );
2502 }
2503 
2504 sal_Int32 SAL_CALL SwXTextDocument::getRendererCount(
2505         const uno::Any& rSelection,
2506         const uno::Sequence< beans::PropertyValue >& rxOptions )
2507 {
2508     SolarMutexGuard aGuard;
2509     if(!IsValid())
2510     {
2511         throw DisposedException( OUString(),
2512                 static_cast< XTextDocument* >(this) );
2513     }
2514 
2515     const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" );
2516     bool bIsSwSrcView = false;
2517     SfxViewShell *pView = GetRenderView( bIsSwSrcView, rxOptions, bIsPDFExport );
2518 
2519     if (!bIsSwSrcView && !m_pRenderData)
2520         m_pRenderData.reset(new SwRenderData);
2521     if (!m_pPrintUIOptions)
2522         m_pPrintUIOptions = lcl_GetPrintUIOptions( pDocShell, pView );
2523     bool bFormat = m_pPrintUIOptions->processPropertiesAndCheckFormat( rxOptions );
2524 
2525     SwDoc *pDoc = GetRenderDoc( pView, rSelection, bIsPDFExport );
2526     OSL_ENSURE( pDoc && pView, "doc or view shell missing!" );
2527     if (!pDoc || !pView)
2528         return 0;
2529 
2530     // save current UI options from the print dialog for the next call to that dialog
2531     lcl_SavePrintUIOptionsToDocumentPrintData( *pDoc, *m_pPrintUIOptions, bIsPDFExport );
2532 
2533     sal_Int32 nRet = 0;
2534     if (bIsSwSrcView)
2535     {
2536         SwSrcView& rSwSrcView = dynamic_cast<SwSrcView&>(*pView);
2537         VclPtr< OutputDevice> pOutDev = lcl_GetOutputDevice( *m_pPrintUIOptions );
2538         nRet = rSwSrcView.PrintSource( pOutDev, 1 /* dummy */, true /* get page count only */ );
2539     }
2540     else
2541     {
2542         SwDocShell *pRenderDocShell = pDoc->GetDocShell();
2543 
2544         // TODO/mba: we really need a generic way to get the SwViewShell!
2545         SwViewShell* pViewShell = nullptr;
2546         SwView* pSwView = dynamic_cast<SwView*>( pView );
2547         if ( pSwView )
2548         {
2549             pViewShell = pSwView->GetWrtShellPtr();
2550         }
2551         else
2552         {
2553             if ( bIsPDFExport && bFormat )
2554             {
2555                 //create a hidden view to be able to export as PDF also in print preview
2556                 //pView and pSwView are not changed intentionally!
2557                 m_pHiddenViewFrame = SfxViewFrame::LoadHiddenDocument( *pRenderDocShell, SFX_INTERFACE_SFXDOCSH );
2558                 pViewShell = static_cast<SwView*>(m_pHiddenViewFrame->GetViewShell())->GetWrtShellPtr();
2559             }
2560             else
2561                 pViewShell = static_cast<SwPagePreview*>(pView)->GetViewShell();
2562         }
2563 
2564         if (!pViewShell || !pViewShell->GetLayout())
2565             return 0;
2566 
2567         if (bFormat)
2568         {
2569             // #i38289
2570             if( pViewShell->GetViewOptions()->getBrowseMode() ||
2571                 pViewShell->GetViewOptions()->IsWhitespaceHidden() )
2572             {
2573                 SwViewOption aOpt( *pViewShell->GetViewOptions() );
2574                 aOpt.setBrowseMode( false );
2575                 aOpt.SetHideWhitespaceMode( false );
2576                 pViewShell->ApplyViewOptions( aOpt );
2577                 if (pSwView)
2578                 {
2579                     pSwView->RecheckBrowseMode();
2580                 }
2581             }
2582 
2583             // reformatting the document for printing will show the changes in the view
2584             // which is likely to produce many unwanted and not nice to view actions.
2585             // We don't want that! Thus we disable updating of the view.
2586             pViewShell->StartAction();
2587 
2588             if (pSwView)
2589             {
2590                 if (m_pRenderData && m_pRenderData->NeedNewViewOptionAdjust( *pViewShell ) )
2591                     m_pRenderData->ViewOptionAdjustStop();
2592                 if (m_pRenderData && !m_pRenderData->IsViewOptionAdjust())
2593                 {
2594                     m_pRenderData->ViewOptionAdjustStart(
2595                         *pViewShell, *pViewShell->GetViewOptions() );
2596                 }
2597             }
2598 
2599             m_pRenderData->MakeSwPrtOptions( pRenderDocShell,
2600                     m_pPrintUIOptions.get(), bIsPDFExport );
2601 
2602             if (pSwView)
2603             {
2604                 // PDF export should not make use of the SwPrtOptions
2605                 const SwPrintData *pPrtOptions = bIsPDFExport
2606                     ? nullptr : m_pRenderData->GetSwPrtOptions();
2607                 bool setShowPlaceHoldersInPDF = false;
2608                 if(bIsPDFExport)
2609                     setShowPlaceHoldersInPDF = lcl_GetBoolProperty( rxOptions, "ExportPlaceholders" );
2610                 m_pRenderData->ViewOptionAdjust( pPrtOptions, setShowPlaceHoldersInPDF );
2611             }
2612 
2613             // since printing now also use the API for PDF export this option
2614             // should be set for printing as well ...
2615             pViewShell->SetPDFExportOption( true );
2616 
2617             // there is some redundancy between those two function calls, but right now
2618             // there is no time to sort this out.
2619             //TODO: check what exactly needs to be done and make just one function for that
2620             pViewShell->CalcLayout();
2621             pViewShell->CalcPagesForPrint( pViewShell->GetPageCount() );
2622 
2623 
2624             // #122919# Force field update before PDF export, but after layout init (tdf#121962)
2625             bool bStateChanged = false;
2626             // check configuration: shall update of printing information in DocInfo set the document to "modified"?
2627             if ( pRenderDocShell->IsEnableSetModified() && !SvtPrintWarningOptions().IsModifyDocumentOnPrintingAllowed() )
2628             {
2629                 pRenderDocShell->EnableSetModified( false );
2630                 bStateChanged = true;
2631             }
2632             pViewShell->SwViewShell::UpdateFields(true);
2633             if( bStateChanged )
2634                 pRenderDocShell->EnableSetModified();
2635 
2636             pViewShell->SetPDFExportOption( false );
2637 
2638             // enable view again
2639             pViewShell->EndAction();
2640         }
2641 
2642         const sal_Int32 nPageCount = pViewShell->GetPageCount();
2643 
2644         // get number of pages to be rendered
2645 
2646         const bool bPrintProspect = m_pPrintUIOptions->getBoolValue( "PrintProspect" );
2647         if (bPrintProspect)
2648         {
2649             SwDoc::CalculatePagePairsForProspectPrinting( *pViewShell->GetLayout(), *m_pRenderData, *m_pPrintUIOptions, nPageCount );
2650             nRet = m_pRenderData->GetPagePairsForProspectPrinting().size();
2651         }
2652         else
2653         {
2654             const SwPostItMode nPostItMode = static_cast<SwPostItMode>( m_pPrintUIOptions->getIntValue( "PrintAnnotationMode", 0 ) );
2655             if (nPostItMode != SwPostItMode::NONE)
2656             {
2657                 VclPtr< OutputDevice > pOutDev = lcl_GetOutputDevice( *m_pPrintUIOptions );
2658                 m_pRenderData->CreatePostItData( pDoc, pViewShell->GetViewOptions(), pOutDev );
2659             }
2660 
2661             // get set of valid document pages (according to the current settings)
2662             // and their start frames
2663             SwDoc::CalculatePagesForPrinting( *pViewShell->GetLayout(), *m_pRenderData, *m_pPrintUIOptions, bIsPDFExport, nPageCount );
2664 
2665             if (nPostItMode != SwPostItMode::NONE)
2666             {
2667                 SwDoc::UpdatePagesForPrintingWithPostItData( *m_pRenderData,
2668                         *m_pPrintUIOptions, nPageCount );
2669             }
2670 
2671             nRet = m_pRenderData->GetPagesToPrint().size();
2672         }
2673     }
2674     OSL_ENSURE( nRet >= 0, "negative number of pages???" );
2675 
2676     return nRet;
2677 }
2678 
2679 uno::Sequence< beans::PropertyValue > SAL_CALL SwXTextDocument::getRenderer(
2680         sal_Int32 nRenderer,
2681         const uno::Any& rSelection,
2682         const uno::Sequence< beans::PropertyValue >& rxOptions )
2683 {
2684     SolarMutexGuard aGuard;
2685     if(!IsValid())
2686     {
2687         throw DisposedException("", static_cast< XTextDocument* >(this));
2688     }
2689 
2690     const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" );
2691     bool bIsSwSrcView = false;
2692     SfxViewShell *pView = GetRenderView( bIsSwSrcView, rxOptions, bIsPDFExport );
2693 
2694     // m_pRenderData should NOT be created here!
2695     // That should only be done in getRendererCount. If this function is called before
2696     // getRendererCount was called then the caller will probably just retrieve the extra UI options
2697     // and is not interested in getting valid information about the other data that would
2698     // otherwise be provided here!
2699 //    if( ! m_pRenderData )
2700 //        m_pRenderData = new SwRenderData;
2701     if (!m_pPrintUIOptions)
2702         m_pPrintUIOptions = lcl_GetPrintUIOptions( pDocShell, pView );
2703     m_pPrintUIOptions->processProperties( rxOptions );
2704     const bool bPrintProspect    = m_pPrintUIOptions->getBoolValue( "PrintProspect" );
2705     const bool bIsSkipEmptyPages = !m_pPrintUIOptions->IsPrintEmptyPages( bIsPDFExport );
2706     const bool bPrintPaperFromSetup = m_pPrintUIOptions->getBoolValue( "PrintPaperFromSetup" );
2707 
2708     SwDoc *pDoc = GetRenderDoc( pView, rSelection, bIsPDFExport );
2709     OSL_ENSURE( pDoc && pView, "doc or view shell missing!" );
2710     if (!pDoc || !pView)
2711         return uno::Sequence< beans::PropertyValue >();
2712 
2713     // due to #110067# (document page count changes sometimes during
2714     // PDF export/printing) we can not check for the upper bound properly.
2715     // Thus instead of throwing the exception we silently return.
2716     if (0 > nRenderer)
2717         throw IllegalArgumentException();
2718 
2719     // TODO/mba: we really need a generic way to get the SwViewShell!
2720     SwViewShell* pVwSh = nullptr;
2721     SwView* pSwView = dynamic_cast<SwView*>( pView );
2722     if ( pSwView )
2723         pVwSh = pSwView->GetWrtShellPtr();
2724     else
2725         pVwSh = static_cast<SwPagePreview*>(pView)->GetViewShell();
2726 
2727     sal_Int32 nMaxRenderer = 0;
2728     if (!bIsSwSrcView && m_pRenderData)
2729     {
2730         OSL_ENSURE( m_pRenderData, "m_pRenderData missing!!" );
2731         nMaxRenderer = bPrintProspect?
2732             m_pRenderData->GetPagePairsForProspectPrinting().size() - 1 :
2733             m_pRenderData->GetPagesToPrint().size() - 1;
2734     }
2735     // since SwSrcView::PrintSource is a poor implementation to get the number of pages to print
2736     // we obmit checking of the upper bound in this case.
2737     if (!bIsSwSrcView && m_pRenderData && nRenderer > nMaxRenderer)
2738         return uno::Sequence< beans::PropertyValue >();
2739 
2740     uno::Sequence< beans::PropertyValue > aRenderer;
2741     if (m_pRenderData)
2742     {
2743         // #i114210#
2744         // determine the correct page number from the renderer index
2745         // #i114875
2746         // consider brochure print
2747         const sal_Int32 nPage = bPrintProspect
2748                              ? nRenderer + 1
2749                              : m_pRenderData->GetPagesToPrint()[ nRenderer ];
2750 
2751         // get paper tray to use ...
2752         sal_Int32 nPrinterPaperTray = -1;
2753         if (! bPrintPaperFromSetup)
2754         {
2755             // ... from individual page style (see the page tab in Format/Page dialog)
2756             const std::map< sal_Int32, sal_Int32 > &rPaperTrays = m_pRenderData->GetPrinterPaperTrays();
2757             std::map< sal_Int32, sal_Int32 >::const_iterator aIt( rPaperTrays.find( nPage ) );
2758             if (aIt != rPaperTrays.end())
2759                 nPrinterPaperTray = aIt->second;
2760         }
2761 
2762         awt::Size aPageSize;
2763         awt::Point aPagePos;
2764         awt::Size aPreferredPageSize;
2765         Size aTmpSize;
2766         if (bIsSwSrcView || bPrintProspect)
2767         {
2768             // for printing of HTML source code and prospect printing we should use
2769             // the printers paper size since
2770             // a) HTML source view has no page size
2771             // b) prospect printing has a different page size from the documents page
2772             //    since two document pages will get rendered on one printer page
2773 
2774             // since PageIncludesNonprintableArea will be set to true we can return the
2775             // printers paper size here.
2776             // Sometimes 'getRenderer' is only called to get "ExtraPrintUIOptions", in this
2777             // case we won't get an OutputDevice here, but then the caller also has no need
2778             // for the correct PageSisze right now...
2779             VclPtr< Printer > pPrinter = dynamic_cast< Printer * >(lcl_GetOutputDevice( *m_pPrintUIOptions ).get());
2780             if (pPrinter)
2781             {
2782                 // HTML source view and prospect adapt to the printer's paper size
2783                 aTmpSize = pPrinter->GetPaperSize();
2784                 aTmpSize = OutputDevice::LogicToLogic( aTmpSize,
2785                             pPrinter->GetMapMode(), MapMode( MapUnit::Map100thMM ));
2786                 aPageSize = awt::Size( aTmpSize.Width(), aTmpSize.Height() );
2787                 #if 0
2788                 // #i115048# it seems users didn't like getting double the formatted page size
2789                 // revert to "old" behavior scaling to the current paper size of the printer
2790                 if (bPrintProspect)
2791                 {
2792                     // we just state what output size we would need
2793                     // which may cause vcl to set that page size on the printer
2794                     // (if available and not overridden by the user)
2795                     aTmpSize = pVwSh->GetPageSize( nPage, bIsSkipEmptyPages );
2796                     aPreferredPageSize = awt::Size ( convertTwipToMm100( 2 * aTmpSize.Width() ),
2797                                                      convertTwipToMm100( aTmpSize.Height() ));
2798                 }
2799                 #else
2800                 if( bPrintProspect )
2801                 {
2802                     // just switch to an appropriate portrait/landscape format
2803                     // FIXME: brochure printing with landscape pages puts the
2804                     // pages next to each other, so landscape is currently always
2805                     // the better choice
2806                     if( aPageSize.Width < aPageSize.Height )
2807                     {
2808                         aPreferredPageSize.Width = aPageSize.Height;
2809                         aPreferredPageSize.Height = aPageSize.Width;
2810                     }
2811                 }
2812                 #endif
2813             }
2814         }
2815         else
2816         {
2817             aTmpSize = pVwSh->GetPageSize( nPage, bIsSkipEmptyPages );
2818             aPageSize = awt::Size ( convertTwipToMm100( aTmpSize.Width() ),
2819                                     convertTwipToMm100( aTmpSize.Height() ));
2820             Point aPoint = pVwSh->GetPagePos(nPage);
2821             aPagePos = awt::Point(convertTwipToMm100(aPoint.X()), convertTwipToMm100(aPoint.Y()));
2822         }
2823 
2824         sal_Int32 nLen = 3;
2825         aRenderer.realloc(3);
2826         aRenderer[0].Name  = "PageSize";
2827         aRenderer[0].Value <<= aPageSize;
2828         aRenderer[1].Name  = "PageIncludesNonprintableArea";
2829         aRenderer[1].Value <<= true;
2830         aRenderer[2].Name = "PagePos";
2831         aRenderer[2].Value <<= aPagePos;
2832         if (aPreferredPageSize.Width && aPreferredPageSize.Height)
2833         {
2834             ++nLen;
2835             aRenderer.realloc( nLen );
2836             aRenderer[ nLen - 1 ].Name  = "PreferredPageSize";
2837             aRenderer[ nLen - 1 ].Value <<= aPreferredPageSize;
2838         }
2839         if (nPrinterPaperTray >= 0)
2840         {
2841             ++nLen;
2842             aRenderer.realloc( nLen );
2843             aRenderer[ nLen - 1 ].Name  = "PrinterPaperTray";
2844             aRenderer[ nLen - 1 ].Value <<= nPrinterPaperTray;
2845         }
2846     }
2847 
2848     // #i117783#
2849     if ( bApplyPagePrintSettingsFromXPagePrintable )
2850     {
2851         const SwPagePreviewPrtData* pPagePrintSettings =
2852                                         pDocShell->GetDoc()->GetPreviewPrtData();
2853         if ( pPagePrintSettings &&
2854              ( pPagePrintSettings->GetRow() > 1 ||
2855                pPagePrintSettings->GetCol() > 1 ) )
2856         {
2857             // extend render data by page print settings attributes
2858             sal_Int32 nLen = aRenderer.getLength();
2859             const sal_Int32 nRenderDataIdxStart = nLen;
2860             nLen += 9;
2861             aRenderer.realloc( nLen );
2862             // put page print settings attribute into render data
2863             const sal_Int32 nRow = pPagePrintSettings->GetRow();
2864             aRenderer[ nRenderDataIdxStart + 0 ].Name  = "NUpRows";
2865             aRenderer[ nRenderDataIdxStart + 0 ].Value <<= std::max<sal_Int32>( nRow, 1);
2866             const sal_Int32 nCol = pPagePrintSettings->GetCol();
2867             aRenderer[ nRenderDataIdxStart + 1 ].Name  = "NUpColumns";
2868             aRenderer[ nRenderDataIdxStart + 1 ].Value <<= std::max<sal_Int32>( nCol, 1);
2869             aRenderer[ nRenderDataIdxStart + 2 ].Name  = "NUpPageMarginLeft";
2870             aRenderer[ nRenderDataIdxStart + 2 ].Value <<= pPagePrintSettings->GetLeftSpace();
2871             aRenderer[ nRenderDataIdxStart + 3 ].Name  = "NUpPageMarginRight";
2872             aRenderer[ nRenderDataIdxStart + 3 ].Value <<= pPagePrintSettings->GetRightSpace();
2873             aRenderer[ nRenderDataIdxStart + 4 ].Name  = "NUpPageMarginTop";
2874             aRenderer[ nRenderDataIdxStart + 4 ].Value <<= pPagePrintSettings->GetTopSpace();
2875             aRenderer[ nRenderDataIdxStart + 5 ].Name  = "NUpPageMarginBottom";
2876             aRenderer[ nRenderDataIdxStart + 5 ].Value <<= pPagePrintSettings->GetBottomSpace();
2877             aRenderer[ nRenderDataIdxStart + 6 ].Name  = "NUpHorizontalSpacing";
2878             aRenderer[ nRenderDataIdxStart + 6 ].Value <<= pPagePrintSettings->GetHorzSpace();
2879             aRenderer[ nRenderDataIdxStart + 7 ].Name  = "NUpVerticalSpacing";
2880             aRenderer[ nRenderDataIdxStart + 7 ].Value <<= pPagePrintSettings->GetVertSpace();
2881             {
2882                 Printer* pPrinter = pDocShell->GetDoc()->getIDocumentDeviceAccess().getPrinter( false );
2883                 if ( pPrinter )
2884                 {
2885                     awt::Size aNewPageSize;
2886                     const Size aPageSize = pPrinter->PixelToLogic( pPrinter->GetPaperSizePixel(), MapMode( MapUnit::Map100thMM ) );
2887                     aNewPageSize = awt::Size( aPageSize.Width(), aPageSize.Height() );
2888                     if ( ( pPagePrintSettings->GetLandscape() &&
2889                            aPageSize.Width() < aPageSize.Height() ) ||
2890                          ( !pPagePrintSettings->GetLandscape() &&
2891                            aPageSize.Width() > aPageSize.Height() ) )
2892                     {
2893                         aNewPageSize = awt::Size( aPageSize.Height(), aPageSize.Width() );
2894                     }
2895                     aRenderer[ nRenderDataIdxStart + 8 ].Name  = "NUpPaperSize";
2896                     aRenderer[ nRenderDataIdxStart + 8 ].Value <<= aNewPageSize;
2897                 }
2898             }
2899         }
2900 
2901         bApplyPagePrintSettingsFromXPagePrintable = false;
2902     }
2903 
2904     m_pPrintUIOptions->appendPrintUIOptions( aRenderer );
2905 
2906     return aRenderer;
2907 }
2908 
2909 SfxViewShell * SwXTextDocument::GuessViewShell(
2910     /* out */ bool &rbIsSwSrcView,
2911     const uno::Reference< css::frame::XController >& rController )
2912 {
2913     // #130810# SfxViewShell::Current() / SfxViewShell::GetObjectShell()
2914     // must not be used (see comment from MBA)
2915 
2916     SfxViewShell    *pView = nullptr;
2917     SwView          *pSwView = nullptr;
2918     SwPagePreview   *pSwPagePreview = nullptr;
2919     SwSrcView       *pSwSrcView = nullptr;
2920     SfxViewFrame    *pFrame = SfxViewFrame::GetFirst( pDocShell, false );
2921 
2922     // look for the view shell with the same controller in use,
2923     // otherwise look for a suitable view, preferably a SwView,
2924     // if that one is not found use a SwPagePreview if found.
2925     while (pFrame)
2926     {
2927         pView = pFrame->GetViewShell();
2928         pSwView = dynamic_cast< SwView * >(pView);
2929         pSwSrcView = dynamic_cast< SwSrcView * >(pView);
2930         if (!pSwPagePreview)
2931             pSwPagePreview = dynamic_cast< SwPagePreview * >(pView);
2932         if (rController.is())
2933         {
2934             if (pView && pView->GetController() == rController)
2935                 break;
2936         }
2937         else if (pSwView || pSwSrcView)
2938             break;
2939         pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell,  false );
2940     }
2941 
2942     OSL_ENSURE( pSwView || pSwPagePreview || pSwSrcView, "failed to get view shell" );
2943     if (pView)
2944         rbIsSwSrcView = pSwSrcView != nullptr;
2945     return pView;
2946 }
2947 
2948 void SAL_CALL SwXTextDocument::render(
2949         sal_Int32 nRenderer,
2950         const uno::Any& rSelection,
2951         const uno::Sequence< beans::PropertyValue >& rxOptions )
2952 {
2953     SolarMutexGuard aGuard;
2954     if(!IsValid())
2955     {
2956         throw DisposedException( OUString(),
2957                 static_cast< XTextDocument* >(this) );
2958     }
2959 
2960     // due to #110067# (document page count changes sometimes during
2961     // PDF export/printing) we can not check for the upper bound properly.
2962     // Thus instead of throwing the exception we silently return.
2963     if (0 > nRenderer)
2964         throw IllegalArgumentException();
2965 
2966     const bool bHasPDFExtOutDevData = lcl_SeqHasProperty( rxOptions, "HasPDFExtOutDevData" );
2967     const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" ) || bHasPDFExtOutDevData;
2968     bool bIsSwSrcView = false;
2969     SfxViewShell *pView = GetRenderView( bIsSwSrcView, rxOptions, bIsPDFExport );
2970 
2971     OSL_ENSURE( m_pRenderData, "data should have been created already in getRendererCount..." );
2972     OSL_ENSURE( m_pPrintUIOptions, "data should have been created already in getRendererCount..." );
2973     if (!bIsSwSrcView && !m_pRenderData)
2974         m_pRenderData.reset(new SwRenderData);
2975     if (!m_pPrintUIOptions)
2976         m_pPrintUIOptions = lcl_GetPrintUIOptions( pDocShell, pView );
2977     m_pPrintUIOptions->processProperties( rxOptions );
2978     const bool bPrintProspect   = m_pPrintUIOptions->getBoolValue( "PrintProspect" );
2979     const bool bLastPage        = m_pPrintUIOptions->getBoolValue( "IsLastPage" );
2980 
2981     SwDoc *pDoc = GetRenderDoc( pView, rSelection, bIsPDFExport );
2982     OSL_ENSURE( pDoc && pView, "doc or view shell missing!" );
2983     if (pDoc && pView)
2984     {
2985         sal_Int32 nMaxRenderer = 0;
2986         if (!bIsSwSrcView)
2987         {
2988             OSL_ENSURE( m_pRenderData, "m_pRenderData missing!!" );
2989             nMaxRenderer = bPrintProspect?
2990                 m_pRenderData->GetPagePairsForProspectPrinting().size() - 1 :
2991                 m_pRenderData->GetPagesToPrint().size() - 1;
2992         }
2993         // since SwSrcView::PrintSource is a poor implementation to get the number of pages to print
2994         // we obmit checking of the upper bound in this case.
2995         if (bIsSwSrcView || nRenderer <= nMaxRenderer)
2996         {
2997             if (bIsSwSrcView)
2998             {
2999                 SwSrcView& rSwSrcView = dynamic_cast<SwSrcView&>(*pView);
3000                 VclPtr< OutputDevice > pOutDev = lcl_GetOutputDevice( *m_pPrintUIOptions );
3001                 rSwSrcView.PrintSource(pOutDev, nRenderer + 1, false);
3002             }
3003             else
3004             {
3005                 // the view shell should be SwView for documents PDF export
3006                 // or SwPagePreview for PDF export of the page preview
3007                 SwViewShell* pVwSh = nullptr;
3008                 // TODO/mba: we really need a generic way to get the SwViewShell!
3009                 const SwView* pSwView = dynamic_cast<const SwView*>(pView);
3010                 if (pSwView)
3011                     pVwSh = pSwView->GetWrtShellPtr();
3012                 else
3013                     pVwSh = static_cast<SwPagePreview*>(pView)->GetViewShell();
3014 
3015                 // get output device to use
3016                 VclPtr< OutputDevice > pOut = lcl_GetOutputDevice( *m_pPrintUIOptions );
3017 
3018                 if(pVwSh && pOut && m_pRenderData->HasSwPrtOptions())
3019                 {
3020                     const OUString aPageRange  = m_pPrintUIOptions->getStringValue( "PageRange" );
3021                     const bool bFirstPage           = m_pPrintUIOptions->getBoolValue( "IsFirstPage" );
3022                     bool bIsSkipEmptyPages          = !m_pPrintUIOptions->IsPrintEmptyPages( bIsPDFExport );
3023 
3024                     OSL_ENSURE((pSwView && m_pRenderData->IsViewOptionAdjust())
3025                             || (!pSwView && !m_pRenderData->IsViewOptionAdjust()),
3026                             "SwView / SwViewOptionAdjust_Impl availability mismatch" );
3027 
3028                     // since printing now also use the API for PDF export this option
3029                     // should be set for printing as well ...
3030                     pVwSh->SetPDFExportOption( true );
3031 
3032                     // #i12836# enhanced pdf export
3033 
3034                     // First, we have to export hyperlinks, notes, and outline to pdf.
3035                     // During this process, additional information required for tagging
3036                     // the pdf file are collected, which are evaulated during painting.
3037 
3038                     SwWrtShell* pWrtShell = pSwView ? pSwView->GetWrtShellPtr() : nullptr;
3039 
3040                     SwPrintData const& rSwPrtOptions =
3041                         *m_pRenderData->GetSwPrtOptions();
3042 
3043                     if (bIsPDFExport && (bFirstPage || bHasPDFExtOutDevData) && pWrtShell)
3044                     {
3045                         SwEnhancedPDFExportHelper aHelper( *pWrtShell, *pOut, aPageRange, bIsSkipEmptyPages, false, rSwPrtOptions );
3046                     }
3047 
3048                     if (bPrintProspect)
3049                         pVwSh->PrintProspect( pOut, rSwPrtOptions, nRenderer );
3050                     else    // normal printing and PDF export
3051                         pVwSh->PrintOrPDFExport( pOut, rSwPrtOptions, nRenderer, bIsPDFExport );
3052 
3053                     // #i35176#
3054 
3055                     // After printing the last page, we take care for the links coming
3056                     // from the EditEngine. The links are generated during the painting
3057                     // process, but the destinations are still missing.
3058 
3059                     if (bIsPDFExport && bLastPage && pWrtShell)
3060                     {
3061                         SwEnhancedPDFExportHelper aHelper( *pWrtShell, *pOut, aPageRange, bIsSkipEmptyPages, true, rSwPrtOptions );
3062                     }
3063 
3064                     pVwSh->SetPDFExportOption( false );
3065 
3066                     // last page to be rendered? (not necessarily the last page of the document)
3067                     // -> do clean-up of data
3068                     if (bLastPage)
3069                     {
3070                         // #i96167# haggai: delete ViewOptionsAdjust here because it makes use
3071                         // of the shell, which might get destroyed in lcl_DisposeView!
3072                         if (m_pRenderData->IsViewOptionAdjust())
3073                             m_pRenderData->ViewOptionAdjustStop();
3074 
3075                         if (m_pRenderData->HasPostItData())
3076                             m_pRenderData->DeletePostItData();
3077                         if (m_pHiddenViewFrame)
3078                         {
3079                             lcl_DisposeView( m_pHiddenViewFrame, pDocShell );
3080                             m_pHiddenViewFrame = nullptr;
3081 
3082                             // prevent crash described in #i108805
3083                             SwDocShell *pRenderDocShell = pDoc->GetDocShell();
3084                             SfxItemSet *pSet = pRenderDocShell->GetMedium()->GetItemSet();
3085                             pSet->Put( SfxBoolItem( SID_HIDDEN, false ) );
3086 
3087                         }
3088                     }
3089                 }
3090             }
3091         }
3092     }
3093     if( bLastPage )
3094     {
3095         m_pRenderData.reset();
3096         m_pPrintUIOptions.reset();
3097     }
3098 }
3099 
3100 // xforms::XFormsSupplier
3101 Reference<XNameContainer> SAL_CALL SwXTextDocument::getXForms()
3102 {
3103     SolarMutexGuard aGuard;
3104     if ( !pDocShell )
3105         throw DisposedException( OUString(), static_cast< XTextDocument* >( this ) );
3106     SwDoc* pDoc = pDocShell->GetDoc();
3107     return pDoc->getXForms();
3108 }
3109 
3110 uno::Reference< text::XFlatParagraphIterator > SAL_CALL SwXTextDocument::getFlatParagraphIterator(::sal_Int32 nTextMarkupType, sal_Bool bAutomatic)
3111 {
3112     SolarMutexGuard aGuard;
3113     if (!IsValid())
3114     {
3115         throw DisposedException("SwXTextDocument not valid",
3116                 static_cast<XTextDocument*>(this));
3117     }
3118 
3119     return SwUnoCursorHelper::CreateFlatParagraphIterator(
3120             *pDocShell->GetDoc(), nTextMarkupType, bAutomatic);
3121 }
3122 
3123 uno::Reference< util::XCloneable > SwXTextDocument::createClone(  )
3124 {
3125     SolarMutexGuard aGuard;
3126     if(!IsValid())
3127         throw DisposedException("", static_cast< XTextDocument* >(this));
3128 
3129     // create a new document - hidden - copy the storage and return it
3130     // SfxObjectShellRef is used here, since the model should control object lifetime after creation
3131     // and thus SfxObjectShellLock is not allowed here
3132     // the model holds reference to the shell, so the shell will not destructed at the end of method
3133     SfxObjectShellRef pShell = pDocShell->GetDoc()->CreateCopy(false, false);
3134     uno::Reference< frame::XModel > xNewModel = pShell->GetModel();
3135     uno::Reference< embed::XStorage > xNewStorage = ::comphelper::OStorageHelper::GetTemporaryStorage( );
3136     uno::Sequence< beans::PropertyValue > aTempMediaDescriptor;
3137     storeToStorage( xNewStorage, aTempMediaDescriptor );
3138     uno::Reference< document::XStorageBasedDocument > xStorageDoc( xNewModel, uno::UNO_QUERY );
3139     xStorageDoc->loadFromStorage( xNewStorage, aTempMediaDescriptor );
3140     return uno::Reference< util::XCloneable >( xNewModel, UNO_QUERY );
3141 }
3142 
3143 void SwXTextDocument::addPasteEventListener(const uno::Reference<text::XPasteListener>& xListener)
3144 {
3145     SolarMutexGuard aGuard;
3146 
3147     if (IsValid() && xListener.is())
3148         pDocShell->GetWrtShell()->GetPasteListeners().addInterface(xListener);
3149 }
3150 
3151 void SwXTextDocument::removePasteEventListener(
3152     const uno::Reference<text::XPasteListener>& xListener)
3153 {
3154     SolarMutexGuard aGuard;
3155 
3156     if (IsValid() && xListener.is())
3157         pDocShell->GetWrtShell()->GetPasteListeners().removeInterface(xListener);
3158 }
3159 
3160 void SwXTextDocument::paintTile( VirtualDevice &rDevice,
3161                                  int nOutputWidth, int nOutputHeight,
3162                                  int nTilePosX, int nTilePosY,
3163                                  long nTileWidth, long nTileHeight )
3164 {
3165     SwViewShell* pViewShell = pDocShell->GetWrtShell();
3166     pViewShell->PaintTile(rDevice, nOutputWidth, nOutputHeight,
3167                           nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3168 
3169     LokChartHelper::PaintAllChartsOnTile(rDevice, nOutputWidth, nOutputHeight,
3170                                          nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3171 }
3172 
3173 Size SwXTextDocument::getDocumentSize()
3174 {
3175     SwViewShell* pViewShell = pDocShell->GetWrtShell();
3176     Size aDocSize = pViewShell->GetDocSize();
3177 
3178     return Size(aDocSize.Width()  + 2 * DOCUMENTBORDER,
3179                 aDocSize.Height() + 2 * DOCUMENTBORDER);
3180 }
3181 
3182 void SwXTextDocument::setPart(int nPart)
3183 {
3184     SolarMutexGuard aGuard;
3185 
3186     SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
3187     if (!pWrtShell)
3188         return;
3189 
3190     pWrtShell->GotoPage(nPart + 1, true);
3191 }
3192 
3193 int SwXTextDocument::getParts()
3194 {
3195     SolarMutexGuard aGuard;
3196 
3197     SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
3198     if (!pWrtShell)
3199         return 0;
3200 
3201     return pWrtShell->GetPageCnt();
3202 }
3203 
3204 OUString SwXTextDocument::getPartPageRectangles()
3205 {
3206     SolarMutexGuard aGuard;
3207 
3208     SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
3209     if (!pWrtShell)
3210         return OUString();
3211 
3212     return pWrtShell->getPageRectangles();
3213 }
3214 
3215 void SwXTextDocument::setClipboard(const uno::Reference<datatransfer::clipboard::XClipboard>& xClipboard)
3216 {
3217     SolarMutexGuard aGuard;
3218 
3219     pDocShell->GetView()->GetEditWin().SetClipboard(xClipboard);
3220 }
3221 
3222 bool SwXTextDocument::isMimeTypeSupported()
3223 {
3224     SolarMutexGuard aGuard;
3225 
3226     SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
3227     if (!pWrtShell)
3228         return false;
3229 
3230     TransferableDataHelper aDataHelper(TransferableDataHelper::CreateFromSystemClipboard(&pWrtShell->GetView().GetEditWin()));
3231     if (SdrView* pSdrView = pWrtShell->GetDrawView())
3232     {
3233         if (pSdrView->GetTextEditObject())
3234             // Editing shape text
3235             return EditEngine::HasValidData(aDataHelper.GetTransferable());
3236     }
3237 
3238     return aDataHelper.GetXTransferable().is() && SwTransferable::IsPaste(*pWrtShell, aDataHelper);
3239 }
3240 
3241 void SwXTextDocument::setClientVisibleArea(const tools::Rectangle& rRectangle)
3242 {
3243     if (SwView* pView = pDocShell->GetView())
3244     {
3245         // set the PgUp/PgDown offset
3246         pView->ForcePageUpDownOffset(2 * rRectangle.GetHeight() / 3);
3247     }
3248 
3249     if (SwViewShell* pViewShell = pDocShell->GetWrtShell())
3250     {
3251         pViewShell->setLOKVisibleArea(rRectangle);
3252     }
3253 }
3254 
3255 void SwXTextDocument::setClientZoom(int nTilePixelWidth_, int /*nTilePixelHeight_*/,
3256                                     int nTileTwipWidth_, int /*nTileTwipHeight_*/)
3257 {
3258     // Here we set the zoom value as it has been set by the user in the client.
3259     // This value is used in postMouseEvent and setGraphicSelection methods
3260     // for in place chart editing. We assume that x and y scale is roughly
3261     // the same.
3262     // Indeed we could set mnTilePixelWidth, mnTilePixelHeight, mnTileTwipWidth,
3263     // mnTileTwipHeight data members of this class but they are not very useful
3264     // since we need to be able to retrieve the zoom value for each view shell.
3265     SfxInPlaceClient* pIPClient = pDocShell->GetView()->GetIPClient();
3266     if (pIPClient)
3267     {
3268         SwViewShell* pWrtViewShell = pDocShell->GetWrtShell();
3269         double fScale = nTilePixelWidth_ * TWIPS_PER_PIXEL / (nTileTwipWidth_ * 1.0);
3270         SwViewOption aOption(*(pWrtViewShell->GetViewOptions()));
3271         if (aOption.GetZoom() != fScale * 100)
3272         {
3273             aOption.SetZoom(fScale * 100);
3274             pWrtViewShell->ApplyViewOptions(aOption);
3275 
3276             // Changing the zoom value doesn't always trigger the updating of
3277             // the client ole object area, so we call it directly.
3278             pIPClient->VisAreaChanged();
3279         }
3280     }
3281 }
3282 
3283 PointerStyle SwXTextDocument::getPointer()
3284 {
3285     SolarMutexGuard aGuard;
3286 
3287     SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
3288     if (!pWrtShell)
3289         return PointerStyle::Arrow;
3290 
3291     return pWrtShell->GetView().GetEditWin().GetPointer();
3292 }
3293 
3294 OUString SwXTextDocument::getTrackedChanges()
3295 {
3296     boost::property_tree::ptree aTrackedChanges;
3297 
3298     // Disable since usability is very low beyond some small number of changes.
3299     static bool bDisableRedlineComments = getenv("DISABLE_REDLINE") != nullptr;
3300     if (!bDisableRedlineComments)
3301     {
3302         const SwRedlineTable& rRedlineTable
3303             = pDocShell->GetDoc()->getIDocumentRedlineAccess().GetRedlineTable();
3304         for (SwRedlineTable::size_type i = 0; i < rRedlineTable.size(); ++i)
3305         {
3306             boost::property_tree::ptree aTrackedChange;
3307             aTrackedChange.put("index", rRedlineTable[i]->GetId());
3308             aTrackedChange.put("author", rRedlineTable[i]->GetAuthorString(1).toUtf8().getStr());
3309             aTrackedChange.put("type", SwRedlineTypeToOUString(
3310                                            rRedlineTable[i]->GetRedlineData().GetType())
3311                                            .toUtf8()
3312                                            .getStr());
3313             aTrackedChange.put("comment",
3314                                rRedlineTable[i]->GetRedlineData().GetComment().toUtf8().getStr());
3315             aTrackedChange.put("description", rRedlineTable[i]->GetDescr().toUtf8().getStr());
3316             OUString sDateTime = utl::toISO8601(
3317                 rRedlineTable[i]->GetRedlineData().GetTimeStamp().GetUNODateTime());
3318             aTrackedChange.put("dateTime", sDateTime.toUtf8().getStr());
3319 
3320             SwContentNode* pContentNd = rRedlineTable[i]->GetContentNode();
3321             SwView* pView = dynamic_cast<SwView*>(SfxViewShell::Current());
3322             if (pView && pContentNd)
3323             {
3324                 SwShellCursor aCursor(pView->GetWrtShell(), *(rRedlineTable[i]->Start()));
3325                 aCursor.SetMark();
3326                 aCursor.GetMark()->nNode = *pContentNd;
3327                 aCursor.GetMark()->nContent.Assign(pContentNd,
3328                                                    rRedlineTable[i]->End()->nContent.GetIndex());
3329 
3330                 aCursor.FillRects();
3331 
3332                 SwRects* pRects(&aCursor);
3333                 std::vector<OString> aRects;
3334                 for (SwRect& rNextRect : *pRects)
3335                     aRects.push_back(rNextRect.SVRect().toString());
3336 
3337                 const OString sRects = comphelper::string::join("; ", aRects);
3338                 aTrackedChange.put("textRange", sRects.getStr());
3339             }
3340 
3341             aTrackedChanges.push_back(std::make_pair("", aTrackedChange));
3342         }
3343     }
3344 
3345     boost::property_tree::ptree aTree;
3346     aTree.add_child("redlines", aTrackedChanges);
3347     std::stringstream aStream;
3348     boost::property_tree::write_json(aStream, aTree);
3349 
3350     return OUString::fromUtf8(aStream.str().c_str());
3351 }
3352 
3353 OUString SwXTextDocument::getTrackedChangeAuthors()
3354 {
3355     return SW_MOD()->GetRedlineAuthorInfo();
3356 }
3357 
3358 OUString SwXTextDocument::getRulerState()
3359 {
3360     SwView* pView = pDocShell->GetView();
3361     return OUString::fromUtf8(dynamic_cast<SwCommentRuler&>(pView->GetHRuler()).CreateJsonNotification().c_str());
3362 }
3363 
3364 OUString SwXTextDocument::getPostIts()
3365 {
3366     SolarMutexGuard aGuard;
3367     boost::property_tree::ptree aAnnotations;
3368     for (auto const& sidebarItem : *pDocShell->GetView()->GetPostItMgr())
3369     {
3370         sw::annotation::SwAnnotationWin* pWin = sidebarItem->pPostIt.get();
3371 
3372         const SwPostItField* pField = pWin->GetPostItField();
3373         const SwRect& aRect = pWin->GetAnchorRect();
3374         const tools::Rectangle aSVRect(aRect.Pos().getX(),
3375                                 aRect.Pos().getY(),
3376                                 aRect.Pos().getX() + aRect.SSize().Width(),
3377                                 aRect.Pos().getY() + aRect.SSize().Height());
3378         std::vector<OString> aRects;
3379         for (const basegfx::B2DRange& aRange : pWin->GetAnnotationTextRanges())
3380         {
3381             const SwRect rect(aRange.getMinX(), aRange.getMinY(), aRange.getWidth(), aRange.getHeight());
3382             aRects.push_back(rect.SVRect().toString());
3383         }
3384         const OString sRects = comphelper::string::join("; ", aRects);
3385 
3386         boost::property_tree::ptree aAnnotation;
3387         aAnnotation.put("id", pField->GetPostItId());
3388         aAnnotation.put("parent", pWin->CalcParent());
3389         aAnnotation.put("author", pField->GetPar1().toUtf8().getStr());
3390         aAnnotation.put("text", pField->GetPar2().toUtf8().getStr());
3391         aAnnotation.put("dateTime", utl::toISO8601(pField->GetDateTime().GetUNODateTime()));
3392         aAnnotation.put("anchorPos", aSVRect.toString());
3393         aAnnotation.put("textRange", sRects.getStr());
3394 
3395         aAnnotations.push_back(std::make_pair("", aAnnotation));
3396     }
3397 
3398     boost::property_tree::ptree aTree;
3399     aTree.add_child("comments", aAnnotations);
3400     std::stringstream aStream;
3401     boost::property_tree::write_json(aStream, aTree);
3402 
3403     return OUString::fromUtf8(aStream.str().c_str());
3404 }
3405 
3406 int SwXTextDocument::getPart()
3407 {
3408     SolarMutexGuard aGuard;
3409 
3410     SwView* pView = pDocShell->GetView();
3411     if (!pView)
3412         return 0;
3413 
3414     return pView->getPart();
3415 }
3416 
3417 OUString SwXTextDocument::getPartName(int nPart)
3418 {
3419     SolarMutexGuard aGuard;
3420 
3421     return SwResId(STR_PAGE) + OUString::number(nPart + 1);
3422 }
3423 
3424 OUString SwXTextDocument::getPartHash(int nPart)
3425 {
3426     SolarMutexGuard aGuard;
3427     OUString sPart(SwResId(STR_PAGE) + OUString::number(nPart + 1));
3428 
3429     return OUString::number(sPart.hashCode());
3430 }
3431 
3432 VclPtr<vcl::Window> SwXTextDocument::getDocWindow()
3433 {
3434     SolarMutexGuard aGuard;
3435     VclPtr<vcl::Window> pWindow;
3436     SwView* pView = pDocShell->GetView();
3437     if (pView)
3438         pWindow = &(pView->GetEditWin());
3439 
3440     LokChartHelper aChartHelper(pView);
3441     VclPtr<vcl::Window> pChartWindow = aChartHelper.GetWindow();
3442     if (pChartWindow)
3443         pWindow = pChartWindow;
3444 
3445     return pWindow;
3446 }
3447 
3448 void SwXTextDocument::initializeForTiledRendering(const css::uno::Sequence<css::beans::PropertyValue>& rArguments)
3449 {
3450     SolarMutexGuard aGuard;
3451 
3452     SwViewShell* pViewShell = pDocShell->GetWrtShell();
3453 
3454     SwView* pView = pDocShell->GetView();
3455     if (!pView)
3456         return;
3457 
3458     pView->SetViewLayout(1/*nColumns*/, false/*bBookMode*/, true);
3459 
3460     // Tiled rendering defaults.
3461     SwViewOption aViewOption(*pViewShell->GetViewOptions());
3462     aViewOption.SetHardBlank(false);
3463     for (sal_Int32 i = 0; i < rArguments.getLength(); ++i)
3464     {
3465         const beans::PropertyValue& rValue = rArguments[i];
3466         if (rValue.Name == ".uno:HideWhitespace" && rValue.Value.has<bool>())
3467             aViewOption.SetHideWhitespaceMode(rValue.Value.get<bool>());
3468         else if (rValue.Name == ".uno:ShowBorderShadow" && rValue.Value.has<bool>())
3469             SwViewOption::SetAppearanceFlag(ViewOptFlags::Shadow , rValue.Value.get<bool>());
3470         else if (rValue.Name == ".uno:Author" && rValue.Value.has<OUString>())
3471         {
3472             // Store the author name in the view.
3473             pView->SetRedlineAuthor(rValue.Value.get<OUString>());
3474             // Let the actual author name pick up the value from the current
3475             // view, which would normally happen only during the next view
3476             // switch.
3477             pDocShell->SetView(pView);
3478         }
3479     }
3480 
3481     // Set the initial zoom value to 1; usually it is set in setClientZoom and
3482     // SwViewShell::PaintTile; zoom value is used for chart in place
3483     // editing, see postMouseEvent and setGraphicSelection methods.
3484     aViewOption.SetZoom(1 * 100);
3485 
3486     aViewOption.SetPostIts(comphelper::LibreOfficeKit::isTiledAnnotations());
3487     pViewShell->ApplyViewOptions(aViewOption);
3488 
3489     // position the pages again after setting view options. Eg: if postit
3490     // rendering is false, then there would be no sidebar, so width of the
3491     // document needs to be adjusted
3492     pViewShell->GetLayout()->CheckViewLayout( pViewShell->GetViewOptions(), nullptr );
3493 
3494     // Disable map mode, so that it's possible to send mouse event coordinates
3495     // directly in twips.
3496     SwEditWin& rEditWin = pDocShell->GetView()->GetEditWin();
3497     rEditWin.EnableMapMode(false);
3498 
3499     // when the "This document may contain formatting or content that cannot
3500     // be saved..." dialog appears, it is auto-cancelled with tiled rendering,
3501     // causing 'Save' being disabled; so let's always save to the original
3502     // format
3503     SvtSaveOptions().SetWarnAlienFormat(false);
3504 
3505     // disable word auto-completion suggestions, the tooltips are not visible,
3506     // and the editeng-like auto-completion is annoying
3507     SvxAutoCorrCfg::Get().GetAutoCorrect()->GetSwFlags().bAutoCompleteWords = false;
3508 
3509     // don't change the whitespace at the beginning of paragraphs, this is
3510     // annoying when taking minutes without further formatting
3511     SwEditShell::GetAutoFormatFlags()->bAFormatByInpDelSpacesAtSttEnd = false;
3512 }
3513 
3514 void SwXTextDocument::postKeyEvent(int nType, int nCharCode, int nKeyCode)
3515 {
3516     SolarMutexGuard aGuard;
3517     SfxLokHelper::postKeyEventAsync(getDocWindow(), nType, nCharCode, nKeyCode);
3518 }
3519 
3520 void SwXTextDocument::postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier)
3521 {
3522     SolarMutexGuard aGuard;
3523 
3524     SwViewShell* pWrtViewShell = pDocShell->GetWrtShell();
3525     SwViewOption aOption(*(pWrtViewShell->GetViewOptions()));
3526     double fScale = aOption.GetZoom() / (TWIPS_PER_PIXEL * 100.0);
3527 
3528     // check if user hit a chart which is being edited by him
3529     SfxViewShell* pViewShell = pDocShell->GetView();
3530     LokChartHelper aChartHelper(pViewShell);
3531     if (aChartHelper.postMouseEvent(nType, nX, nY,
3532                                     nCount, nButtons, nModifier,
3533                                     fScale, fScale))
3534         return;
3535 
3536     // check if the user hit a chart which is being edited by someone else
3537     // and, if so, skip current mouse event
3538     if (nType != LOK_MOUSEEVENT_MOUSEMOVE)
3539     {
3540         if (LokChartHelper::HitAny(Point(nX, nY)))
3541             return;
3542     }
3543 
3544     SwEditWin& rEditWin = pDocShell->GetView()->GetEditWin();
3545     SfxLokHelper::postMouseEventAsync(&rEditWin, nType,
3546                                       Point(nX, nY), nCount,
3547                                       MouseEventModifiers::SIMPLECLICK,
3548                                       nButtons, nModifier);
3549 }
3550 
3551 void SwXTextDocument::setTextSelection(int nType, int nX, int nY)
3552 {
3553     SolarMutexGuard aGuard;
3554 
3555     SfxViewShell* pViewShell = pDocShell->GetView();
3556     LokChartHelper aChartHelper(pViewShell);
3557     if (aChartHelper.setTextSelection(nType, nX, nY))
3558         return;
3559 
3560     SwEditWin& rEditWin = pDocShell->GetView()->GetEditWin();
3561     switch (nType)
3562     {
3563     case LOK_SETTEXTSELECTION_START:
3564         rEditWin.SetCursorTwipPosition(Point(nX, nY), /*bPoint=*/false, /*bClearMark=*/false);
3565         break;
3566     case LOK_SETTEXTSELECTION_END:
3567         rEditWin.SetCursorTwipPosition(Point(nX, nY), /*bPoint=*/true, /*bClearMark=*/false);
3568         break;
3569     case LOK_SETTEXTSELECTION_RESET:
3570         rEditWin.SetCursorTwipPosition(Point(nX, nY), /*bPoint=*/true, /*bClearMark=*/true);
3571         break;
3572     default:
3573         assert(false);
3574         break;
3575     }
3576 }
3577 
3578 uno::Reference<datatransfer::XTransferable> SwXTextDocument::getSelection()
3579 {
3580     SolarMutexGuard aGuard;
3581 
3582     uno::Reference<datatransfer::XTransferable> xTransferable;
3583 
3584     SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
3585     if (SdrView* pSdrView = pWrtShell->GetDrawView())
3586     {
3587         if (pSdrView->GetTextEditObject())
3588         {
3589             // Editing shape text
3590             EditView& rEditView = pSdrView->GetTextEditOutlinerView()->GetEditView();
3591             xTransferable = rEditView.GetEditEngine()->CreateTransferable(rEditView.GetSelection());
3592         }
3593     }
3594 
3595     if (SwPostItMgr* pPostItMgr = pDocShell->GetView()->GetPostItMgr())
3596     {
3597         if (sw::annotation::SwAnnotationWin* pWin = pPostItMgr->GetActiveSidebarWin())
3598         {
3599             // Editing postit text.
3600             EditView& rEditView = pWin->GetOutlinerView()->GetEditView();
3601             xTransferable = rEditView.GetEditEngine()->CreateTransferable(rEditView.GetSelection());
3602         }
3603     }
3604 
3605     if (!xTransferable.is())
3606         xTransferable = new SwTransferable(*pWrtShell);
3607 
3608     return xTransferable;
3609 }
3610 
3611 void SwXTextDocument::setGraphicSelection(int nType, int nX, int nY)
3612 {
3613     SolarMutexGuard aGuard;
3614 
3615     SwViewShell* pWrtViewShell = pDocShell->GetWrtShell();
3616     SwViewOption aOption(*(pWrtViewShell->GetViewOptions()));
3617     double fScale = aOption.GetZoom() / (TWIPS_PER_PIXEL * 100.0);
3618 
3619     SfxViewShell* pViewShell = pDocShell->GetView();
3620     LokChartHelper aChartHelper(pViewShell);
3621     if (aChartHelper.setGraphicSelection(nType, nX, nY, fScale, fScale))
3622         return;
3623 
3624     SwEditWin& rEditWin = pDocShell->GetView()->GetEditWin();
3625     switch (nType)
3626     {
3627     case LOK_SETGRAPHICSELECTION_START:
3628         rEditWin.SetGraphicTwipPosition(/*bStart=*/true, Point(nX, nY));
3629         break;
3630     case LOK_SETGRAPHICSELECTION_END:
3631         rEditWin.SetGraphicTwipPosition(/*bStart=*/false, Point(nX, nY));
3632         break;
3633     default:
3634         assert(false);
3635         break;
3636     }
3637 }
3638 
3639 void SwXTextDocument::resetSelection()
3640 {
3641     SolarMutexGuard aGuard;
3642 
3643     SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
3644     pWrtShell->ResetSelect(nullptr, false);
3645 }
3646 
3647 void SAL_CALL SwXTextDocument::paintTile( const ::css::uno::Any& Parent, ::sal_Int32 nOutputWidth, ::sal_Int32 nOutputHeight, ::sal_Int32 nTilePosX, ::sal_Int32 nTilePosY, ::sal_Int32 nTileWidth, ::sal_Int32 nTileHeight )
3648 {
3649     SystemGraphicsData aData;
3650     aData.nSize = sizeof(SystemGraphicsData);
3651     #if defined(_WIN32)
3652     sal_Int64 nWindowHandle;
3653     Parent >>= nWindowHandle;
3654     aData.hWnd = reinterpret_cast<HWND>(nWindowHandle);
3655     ScopedVclPtrInstance<VirtualDevice> xDevice(&aData, Size(1, 1), DeviceFormat::DEFAULT);
3656     paintTile(*xDevice, nOutputWidth, nOutputHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3657     #else
3658     // TODO: support other platforms
3659     (void)Parent;
3660     (void)nOutputWidth;
3661     (void)nOutputHeight;
3662     (void)nTilePosX;
3663     (void)nTilePosY;
3664     (void)nTileWidth;
3665     (void)nTileHeight;
3666     #endif
3667 }
3668 
3669 /**
3670  * retrieve languages already used in current document
3671  */
3672 uno::Sequence< lang::Locale > SAL_CALL SwXTextDocument::getDocumentLanguages(
3673         ::sal_Int16 nScriptTypes,
3674         ::sal_Int16 nMaxCount )
3675 {
3676     SolarMutexGuard aGuard;
3677 
3678     // possible canonical values for nScriptTypes
3679     // any bit wise combination is allowed
3680     const sal_Int16 nLatin   = 0x001;
3681     const sal_Int16 nAsian   = 0x002;
3682     const sal_Int16 nComplex = 0x004;
3683 
3684     // script types for which to get the languages
3685     const bool bLatin   = 0 != (nScriptTypes & nLatin);
3686     const bool bAsian   = 0 != (nScriptTypes & nAsian);
3687     const bool bComplex = 0 != (nScriptTypes & nComplex);
3688 
3689     if (nScriptTypes < nLatin || nScriptTypes > (nLatin | nAsian | nComplex))
3690         throw IllegalArgumentException("nScriptTypes ranges from 1 to 7!", Reference< XInterface >(), 1);
3691     if (!pDocShell)
3692         throw DisposedException();
3693     SwDoc* pDoc = pDocShell->GetDoc();
3694 
3695     // avoid duplicate values
3696     std::set< LanguageType > aAllLangs;
3697 
3698     //USER STYLES
3699 
3700     const SwCharFormats *pFormats = pDoc->GetCharFormats();
3701     for(size_t i = 0; i < pFormats->size(); ++i)
3702     {
3703         const SwAttrSet &rAttrSet = (*pFormats)[i]->GetAttrSet();
3704         LanguageType nLang = LANGUAGE_DONTKNOW;
3705         if (bLatin)
3706         {
3707             nLang = rAttrSet.GetLanguage( false ).GetLanguage();
3708             if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3709                 aAllLangs.insert( nLang );
3710         }
3711         if (bAsian)
3712         {
3713             nLang = rAttrSet.GetCJKLanguage( false ).GetLanguage();
3714             if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3715                 aAllLangs.insert( nLang );
3716         }
3717         if (bComplex)
3718         {
3719             nLang = rAttrSet.GetCTLLanguage( false ).GetLanguage();
3720             if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3721                 aAllLangs.insert( nLang );
3722         }
3723     }
3724 
3725     const SwTextFormatColls *pColls = pDoc->GetTextFormatColls();
3726     for (size_t i = 0; i < pColls->size(); ++i)
3727     {
3728         const SwAttrSet &rAttrSet = (*pColls)[i]->GetAttrSet();
3729         LanguageType nLang = LANGUAGE_DONTKNOW;
3730         if (bLatin)
3731         {
3732             nLang = rAttrSet.GetLanguage( false ).GetLanguage();
3733             if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3734                 aAllLangs.insert( nLang );
3735         }
3736         if (bAsian)
3737         {
3738             nLang = rAttrSet.GetCJKLanguage( false ).GetLanguage();
3739             if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3740                 aAllLangs.insert( nLang );
3741         }
3742         if (bComplex)
3743         {
3744             nLang = rAttrSet.GetCTLLanguage( false ).GetLanguage();
3745             if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3746                 aAllLangs.insert( nLang );
3747         }
3748     }
3749 
3750     //AUTO STYLES
3751     const IStyleAccess::SwAutoStyleFamily aFam[2] =
3752     {
3753       IStyleAccess::AUTO_STYLE_CHAR,
3754       IStyleAccess::AUTO_STYLE_PARA
3755     };
3756     for (IStyleAccess::SwAutoStyleFamily i : aFam)
3757     {
3758         std::vector< std::shared_ptr<SfxItemSet> > rStyles;
3759         pDoc->GetIStyleAccess().getAllStyles(rStyles, i);
3760         while (!rStyles.empty())
3761         {
3762             std::shared_ptr<SfxItemSet> pStyle = rStyles.back();
3763             rStyles.pop_back();
3764             const SfxItemSet *pSet = dynamic_cast< const SfxItemSet * >(pStyle.get());
3765 
3766             LanguageType nLang = LANGUAGE_DONTKNOW;
3767             if (bLatin)
3768             {
3769                 assert(pSet);
3770                 nLang = dynamic_cast< const SvxLanguageItem & >(pSet->Get( RES_CHRATR_LANGUAGE, false )).GetLanguage();
3771                 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3772                     aAllLangs.insert( nLang );
3773             }
3774             if (bAsian)
3775             {
3776                 assert(pSet);
3777                 nLang = dynamic_cast< const SvxLanguageItem & >(pSet->Get( RES_CHRATR_CJK_LANGUAGE, false )).GetLanguage();
3778                 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3779                     aAllLangs.insert( nLang );
3780             }
3781             if (bComplex)
3782             {
3783                 assert(pSet);
3784                 nLang = dynamic_cast< const SvxLanguageItem & >(pSet->Get( RES_CHRATR_CTL_LANGUAGE, false )).GetLanguage();
3785                 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3786                     aAllLangs.insert( nLang );
3787             }
3788         }
3789     }
3790 
3791     //TODO/mba: it's a strange concept that a view is needed to retrieve core data
3792     SwWrtShell *pWrtSh = pDocShell->GetWrtShell();
3793     SdrView *pSdrView = pWrtSh->GetDrawView();
3794 
3795     if( pSdrView )
3796     {
3797         SdrOutliner* pOutliner = pSdrView->GetTextEditOutliner();
3798         if(pOutliner)
3799         {
3800             EditEngine& rEditEng = const_cast<EditEngine&>(pOutliner->GetEditEngine());
3801             sal_Int32 nParCount = pOutliner->GetParagraphCount();
3802             for (sal_Int32 nPar=0; nPar<nParCount; nPar++)
3803             {
3804                 //every paragraph
3805                 std::vector<sal_Int32> aPortions;
3806                 rEditEng.GetPortions( nPar, aPortions );
3807 
3808                 for ( size_t nPos = aPortions.size(); nPos; )
3809                 {
3810                     //every position
3811                     --nPos;
3812                     sal_Int32 nEnd = aPortions[ nPos ];
3813                     sal_Int32 nStart = nPos ? aPortions[ nPos - 1 ] : 0;
3814                     ESelection aSelection( nPar, nStart, nPar, nEnd );
3815                     SfxItemSet aAttr = rEditEng.GetAttribs( aSelection );
3816 
3817                     LanguageType nLang = LANGUAGE_DONTKNOW;
3818                     if (bLatin)
3819                     {
3820                         nLang = dynamic_cast< const SvxLanguageItem & >(aAttr.Get( EE_CHAR_LANGUAGE, false )).GetLanguage();
3821                         if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3822                             aAllLangs.insert( nLang );
3823                     }
3824                     if (bAsian)
3825                     {
3826                         nLang = dynamic_cast< const SvxLanguageItem & >(aAttr.Get( EE_CHAR_LANGUAGE_CJK, false )).GetLanguage();
3827                         if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3828                             aAllLangs.insert( nLang );
3829                     }
3830                     if (bComplex)
3831                     {
3832                         nLang = dynamic_cast< const SvxLanguageItem & >(aAttr.Get( EE_CHAR_LANGUAGE_CTL, false )).GetLanguage();
3833                         if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3834                             aAllLangs.insert( nLang );
3835                     }
3836                 }
3837             }
3838         }
3839     }
3840     // less than nMaxCount languages
3841     if (nMaxCount > static_cast< sal_Int16 >( aAllLangs.size() ))
3842         nMaxCount = static_cast< sal_Int16 >( aAllLangs.size() );
3843 
3844     // build return value
3845     uno::Sequence< lang::Locale > aLanguages( nMaxCount );
3846     lang::Locale* pLanguage = aLanguages.getArray();
3847     if (nMaxCount > 0)
3848     {
3849         sal_Int32 nCount = 0;
3850         for (const auto& rLang : aAllLangs)
3851         {
3852             if (nCount >= nMaxCount)
3853                 break;
3854             if (LANGUAGE_NONE != rLang)
3855             {
3856                 pLanguage[nCount] = LanguageTag::convertToLocale( rLang );
3857                 pLanguage[nCount].Language = SvtLanguageTable::GetLanguageString( rLang );
3858                 nCount += 1;
3859             }
3860         }
3861     }
3862 
3863     return aLanguages;
3864 }
3865 
3866 SwXLinkTargetSupplier::SwXLinkTargetSupplier(SwXTextDocument& rxDoc) :
3867     pxDoc(&rxDoc)
3868 {
3869     sTables     = SwResId(STR_CONTENT_TYPE_TABLE);
3870     sFrames     = SwResId(STR_CONTENT_TYPE_FRAME);
3871     sGraphics   = SwResId(STR_CONTENT_TYPE_GRAPHIC);
3872     sOLEs       = SwResId(STR_CONTENT_TYPE_OLE);
3873     sSections   = SwResId(STR_CONTENT_TYPE_REGION);
3874     sOutlines   = SwResId(STR_CONTENT_TYPE_OUTLINE);
3875     sBookmarks  = SwResId(STR_CONTENT_TYPE_BOOKMARK);
3876 }
3877 
3878 SwXLinkTargetSupplier::~SwXLinkTargetSupplier()
3879 {
3880 }
3881 
3882 Any SwXLinkTargetSupplier::getByName(const OUString& rName)
3883 {
3884     Any aRet;
3885     if(!pxDoc)
3886         throw RuntimeException("No document available");
3887     OUString sSuffix("|");
3888     if(rName == sTables)
3889     {
3890         sSuffix += "table";
3891 
3892         Reference< XNameAccess >  xTables = new SwXLinkNameAccessWrapper(
3893                                         pxDoc->getTextTables(), rName, sSuffix );
3894         aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
3895     }
3896     else if(rName == sFrames)
3897     {
3898         sSuffix += "frame";
3899         Reference< XNameAccess >  xTables = new SwXLinkNameAccessWrapper(
3900                                         pxDoc->getTextFrames(), rName, sSuffix );
3901         aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
3902     }
3903     else if(rName == sSections)
3904     {
3905         sSuffix += "region";
3906         Reference< XNameAccess >  xTables = new SwXLinkNameAccessWrapper(
3907                                         pxDoc->getTextSections(), rName, sSuffix );
3908         aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
3909     }
3910     else if(rName == sGraphics)
3911     {
3912         sSuffix += "graphic";
3913         Reference< XNameAccess >  xTables = new SwXLinkNameAccessWrapper(
3914                                         pxDoc->getGraphicObjects(), rName, sSuffix );
3915         aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
3916     }
3917     else if(rName == sOLEs)
3918     {
3919         sSuffix += "ole";
3920         Reference< XNameAccess >  xTables = new SwXLinkNameAccessWrapper(
3921                                         pxDoc->getEmbeddedObjects(), rName, sSuffix );
3922         aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
3923     }
3924     else if(rName == sOutlines)
3925     {
3926         sSuffix += "outline";
3927         Reference< XNameAccess >  xTables = new SwXLinkNameAccessWrapper(
3928                                         *pxDoc, rName, sSuffix );
3929         aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
3930     }
3931     else if(rName == sBookmarks)
3932     {
3933         sSuffix.clear();
3934         Reference< XNameAccess >  xBkms = new SwXLinkNameAccessWrapper(
3935                                         pxDoc->getBookmarks(), rName, sSuffix );
3936         aRet <<= Reference< XPropertySet >(xBkms, UNO_QUERY);
3937     }
3938     else
3939         throw NoSuchElementException();
3940     return aRet;
3941 }
3942 
3943 Sequence< OUString > SwXLinkTargetSupplier::getElementNames()
3944 {
3945     Sequence< OUString > aRet(7);
3946     OUString* pNames = aRet.getArray();
3947     pNames[0] = sTables;
3948     pNames[1] = sFrames  ;
3949     pNames[2] = sGraphics;
3950     pNames[3] = sOLEs   ;
3951     pNames[4] = sSections;
3952     pNames[5] = sOutlines;
3953     pNames[6] = sBookmarks;
3954     return aRet;
3955 }
3956 
3957 sal_Bool SwXLinkTargetSupplier::hasByName(const OUString& rName)
3958 {
3959     if( rName == sTables  ||
3960         rName == sFrames  ||
3961         rName == sGraphics||
3962         rName == sOLEs   ||
3963         rName == sSections ||
3964         rName == sOutlines ||
3965         rName == sBookmarks    )
3966         return true;
3967     return false;
3968 }
3969 
3970 uno::Type  SwXLinkTargetSupplier::getElementType()
3971 {
3972     return cppu::UnoType<XPropertySet>::get();
3973 
3974 }
3975 
3976 sal_Bool SwXLinkTargetSupplier::hasElements()
3977 {
3978     return nullptr != pxDoc;
3979 }
3980 
3981 OUString SwXLinkTargetSupplier::getImplementationName()
3982 {
3983     return OUString("SwXLinkTargetSupplier");
3984 }
3985 
3986 sal_Bool SwXLinkTargetSupplier::supportsService(const OUString& rServiceName)
3987 {
3988     return cppu::supportsService(this, rServiceName);
3989 }
3990 
3991 Sequence< OUString > SwXLinkTargetSupplier::getSupportedServiceNames()
3992 {
3993     Sequence< OUString > aRet { "com.sun.star.document.LinkTargets" };
3994     return aRet;
3995 }
3996 
3997 SwXLinkNameAccessWrapper::SwXLinkNameAccessWrapper(
3998             Reference< XNameAccess > const & xAccess, const OUString& rLinkDisplayName, const OUString& sSuffix ) :
3999     xRealAccess(xAccess),
4000     pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_LINK_TARGET)),
4001     sLinkSuffix(sSuffix),
4002     sLinkDisplayName(rLinkDisplayName),
4003     pxDoc(nullptr)
4004 {
4005 }
4006 
4007 SwXLinkNameAccessWrapper::SwXLinkNameAccessWrapper(SwXTextDocument& rxDoc,
4008             const OUString& rLinkDisplayName, const OUString& sSuffix) :
4009     pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_LINK_TARGET)),
4010     sLinkSuffix(sSuffix),
4011     sLinkDisplayName(rLinkDisplayName),
4012     pxDoc(&rxDoc)
4013 {
4014 }
4015 
4016 SwXLinkNameAccessWrapper::~SwXLinkNameAccessWrapper()
4017 {
4018 }
4019 
4020 Any SwXLinkNameAccessWrapper::getByName(const OUString& rName)
4021 {
4022     Any aRet;
4023     bool bFound = false;
4024     //cut link extension and call the real NameAccess
4025     OUString sParam = rName;
4026     OUString sSuffix(sLinkSuffix);
4027     if(sParam.getLength() > sSuffix.getLength() )
4028     {
4029         OUString sCmp = sParam.copy(sParam.getLength() - sSuffix.getLength(),
4030                                                     sSuffix.getLength());
4031         if(sCmp == sSuffix)
4032         {
4033             if(pxDoc)
4034             {
4035                 sParam = sParam.copy(0, sParam.getLength() - sSuffix.getLength());
4036                 if(!pxDoc->GetDocShell())
4037                     throw RuntimeException("No document shell available");
4038                 SwDoc* pDoc = pxDoc->GetDocShell()->GetDoc();
4039                 const size_t nOutlineCount = pDoc->GetNodes().GetOutLineNds().size();
4040 
4041                 for (size_t i = 0; i < nOutlineCount && !bFound; ++i)
4042                 {
4043                     const SwOutlineNodes& rOutlineNodes = pDoc->GetNodes().GetOutLineNds();
4044                     const SwNumRule* pOutlRule = pDoc->GetOutlineNumRule();
4045                     if(sParam == lcl_CreateOutlineString(i, rOutlineNodes, pOutlRule))
4046                     {
4047                         Reference< XPropertySet >  xOutline = new SwXOutlineTarget(sParam);
4048                         aRet <<= xOutline;
4049                         bFound = true;
4050                     }
4051                 }
4052             }
4053             else
4054             {
4055                 aRet = xRealAccess->getByName(sParam.copy(0, sParam.getLength() - sSuffix.getLength()));
4056                 Reference< XInterface > xInt;
4057                 if(!(aRet >>= xInt))
4058                     throw RuntimeException("Could not retrieve property");
4059                 Reference< XPropertySet >  xProp(xInt, UNO_QUERY);
4060                 aRet <<= xProp;
4061                 bFound = true;
4062             }
4063         }
4064     }
4065     if(!bFound)
4066         throw NoSuchElementException();
4067     return aRet;
4068 }
4069 
4070 Sequence< OUString > SwXLinkNameAccessWrapper::getElementNames()
4071 {
4072     Sequence< OUString > aRet;
4073     if(pxDoc)
4074     {
4075         if(!pxDoc->GetDocShell())
4076             throw RuntimeException("No document shell available");
4077 
4078         SwDoc* pDoc = pxDoc->GetDocShell()->GetDoc();
4079         const SwOutlineNodes& rOutlineNodes = pDoc->GetNodes().GetOutLineNds();
4080         const size_t nOutlineCount = rOutlineNodes.size();
4081         aRet.realloc(nOutlineCount);
4082         OUString* pResArr = aRet.getArray();
4083         const SwNumRule* pOutlRule = pDoc->GetOutlineNumRule();
4084         for (size_t i = 0; i < nOutlineCount; ++i)
4085         {
4086             OUString sEntry = lcl_CreateOutlineString(i, rOutlineNodes, pOutlRule);
4087             sEntry += "|outline";
4088             pResArr[i] = sEntry;
4089         }
4090     }
4091     else
4092     {
4093         Sequence< OUString > aOrg = xRealAccess->getElementNames();
4094         const OUString* pOrgArr = aOrg.getConstArray();
4095         aRet.realloc(aOrg.getLength());
4096         OUString* pResArr = aRet.getArray();
4097         for(long i = 0; i < aOrg.getLength(); i++)
4098         {
4099             pResArr[i] = pOrgArr[i] + sLinkSuffix;
4100         }
4101     }
4102     return aRet;
4103 }
4104 
4105 sal_Bool SwXLinkNameAccessWrapper::hasByName(const OUString& rName)
4106 {
4107     bool bRet = false;
4108     OUString sParam(rName);
4109     if(sParam.getLength() > sLinkSuffix.getLength() )
4110     {
4111         OUString sCmp = sParam.copy(sParam.getLength() - sLinkSuffix.getLength(),
4112                                                     sLinkSuffix.getLength());
4113         if(sCmp == sLinkSuffix)
4114         {
4115             sParam = sParam.copy(0, sParam.getLength() - sLinkSuffix.getLength());
4116             if(pxDoc)
4117             {
4118                 if(!pxDoc->GetDocShell())
4119                     throw RuntimeException("No document shell available");
4120                 SwDoc* pDoc = pxDoc->GetDocShell()->GetDoc();
4121                 const size_t nOutlineCount = pDoc->GetNodes().GetOutLineNds().size();
4122 
4123                 for (size_t i = 0; i < nOutlineCount && !bRet; ++i)
4124                 {
4125                     const SwOutlineNodes& rOutlineNodes = pDoc->GetNodes().GetOutLineNds();
4126                     const SwNumRule* pOutlRule = pDoc->GetOutlineNumRule();
4127                     if(sParam ==
4128                         lcl_CreateOutlineString(i, rOutlineNodes, pOutlRule))
4129                     {
4130                         bRet = true;
4131                     }
4132                 }
4133             }
4134             else
4135             {
4136                 bRet = xRealAccess->hasByName(sParam);
4137             }
4138         }
4139     }
4140     return bRet;
4141 }
4142 
4143 uno::Type  SwXLinkNameAccessWrapper::getElementType()
4144 {
4145     return cppu::UnoType<XPropertySet>::get();
4146 }
4147 
4148 sal_Bool SwXLinkNameAccessWrapper::hasElements()
4149 {
4150     bool bRet = false;
4151     if(pxDoc)
4152     {
4153         OSL_FAIL("not implemented");
4154     }
4155     else
4156     {
4157         bRet = xRealAccess->hasElements();
4158     }
4159     return bRet;
4160 }
4161 
4162 Reference< XPropertySetInfo >  SwXLinkNameAccessWrapper::getPropertySetInfo()
4163 {
4164     static Reference< XPropertySetInfo >  xRet = pPropSet->getPropertySetInfo();
4165     return xRet;
4166 }
4167 
4168 void SwXLinkNameAccessWrapper::setPropertyValue(
4169     const OUString& , const Any& )
4170 {
4171     throw UnknownPropertyException();
4172 }
4173 
4174 static Any lcl_GetDisplayBitmap(const OUString& _sLinkSuffix)
4175 {
4176     Any aRet;
4177     OUString sLinkSuffix = _sLinkSuffix;
4178     if(!sLinkSuffix.isEmpty())
4179         sLinkSuffix = sLinkSuffix.copy(1);
4180     OUString sImgId;
4181 
4182     if(sLinkSuffix == "outline")
4183         sImgId = RID_BMP_NAVI_OUTLINE;
4184     else if(sLinkSuffix == "table")
4185         sImgId = RID_BMP_NAVI_TABLE;
4186     else if(sLinkSuffix == "frame")
4187         sImgId = RID_BMP_NAVI_FRAME;
4188     else if(sLinkSuffix == "graphic")
4189         sImgId = RID_BMP_NAVI_GRAPHIC;
4190     else if(sLinkSuffix == "ole")
4191         sImgId = RID_BMP_NAVI_OLE;
4192     else if(sLinkSuffix.isEmpty())
4193         sImgId = RID_BMP_NAVI_BOOKMARK;
4194     else if(sLinkSuffix == "region")
4195         sImgId = RID_BMP_NAVI_REGION;
4196 
4197     if (!sImgId.isEmpty())
4198     {
4199         aRet <<= VCLUnoHelper::CreateBitmap(BitmapEx(sImgId));
4200     }
4201     return aRet;
4202 }
4203 
4204 Any SwXLinkNameAccessWrapper::getPropertyValue(const OUString& rPropertyName)
4205 {
4206     Any aRet;
4207     if( rPropertyName == UNO_LINK_DISPLAY_NAME )
4208     {
4209         aRet <<= sLinkDisplayName;
4210     }
4211     else if( rPropertyName == UNO_LINK_DISPLAY_BITMAP )
4212     {
4213         aRet = lcl_GetDisplayBitmap(sLinkSuffix);
4214     }
4215     else
4216         throw UnknownPropertyException();
4217     return aRet;
4218 }
4219 
4220 void SwXLinkNameAccessWrapper::addPropertyChangeListener(
4221     const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
4222 {}
4223 
4224 void SwXLinkNameAccessWrapper::removePropertyChangeListener(
4225     const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
4226 {}
4227 
4228 void SwXLinkNameAccessWrapper::addVetoableChangeListener(
4229     const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
4230 {}
4231 
4232 void SwXLinkNameAccessWrapper::removeVetoableChangeListener(
4233     const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
4234 {}
4235 
4236 Reference< XNameAccess >  SwXLinkNameAccessWrapper::getLinks()
4237 {
4238     return this;
4239 }
4240 
4241 OUString SwXLinkNameAccessWrapper::getImplementationName()
4242 {
4243     return OUString("SwXLinkNameAccessWrapper");
4244 }
4245 
4246 sal_Bool SwXLinkNameAccessWrapper::supportsService(const OUString& rServiceName)
4247 {
4248     return cppu::supportsService(this, rServiceName);
4249 }
4250 
4251 Sequence< OUString > SwXLinkNameAccessWrapper::getSupportedServiceNames()
4252 {
4253     Sequence< OUString > aRet { "com.sun.star.document.LinkTargets" };
4254     return aRet;
4255 }
4256 
4257 SwXOutlineTarget::SwXOutlineTarget(const OUString& rOutlineText) :
4258     pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_LINK_TARGET)),
4259     sOutlineText(rOutlineText)
4260 {
4261 }
4262 
4263 SwXOutlineTarget::~SwXOutlineTarget()
4264 {
4265 }
4266 
4267 Reference< XPropertySetInfo >  SwXOutlineTarget::getPropertySetInfo()
4268 {
4269     static Reference< XPropertySetInfo >  xRet = pPropSet->getPropertySetInfo();
4270     return xRet;
4271 }
4272 
4273 void SwXOutlineTarget::setPropertyValue(
4274     const OUString& /*PropertyName*/, const Any& /*aValue*/)
4275 {
4276     throw UnknownPropertyException();
4277 }
4278 
4279 Any SwXOutlineTarget::getPropertyValue(const OUString& rPropertyName)
4280 {
4281     if(rPropertyName != UNO_LINK_DISPLAY_NAME)
4282         throw UnknownPropertyException();
4283 
4284     return Any(sOutlineText);
4285 }
4286 
4287 void SwXOutlineTarget::addPropertyChangeListener(
4288     const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
4289 {
4290 }
4291 
4292 void SwXOutlineTarget::removePropertyChangeListener(
4293     const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
4294 {
4295 }
4296 
4297 void SwXOutlineTarget::addVetoableChangeListener(
4298     const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
4299 {
4300 }
4301 
4302 void SwXOutlineTarget::removeVetoableChangeListener(
4303     const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
4304 {
4305 }
4306 
4307 OUString SwXOutlineTarget::getImplementationName()
4308 {
4309     return OUString("SwXOutlineTarget");
4310 }
4311 
4312 sal_Bool SwXOutlineTarget::supportsService(const OUString& ServiceName)
4313 {
4314     return cppu::supportsService(this, ServiceName);
4315 }
4316 
4317 Sequence< OUString > SwXOutlineTarget::getSupportedServiceNames()
4318 {
4319     Sequence<OUString> aRet { "com.sun.star.document.LinkTarget" };
4320 
4321     return aRet;
4322 }
4323 
4324 SwXDocumentPropertyHelper::SwXDocumentPropertyHelper(SwDoc& rDoc) :
4325 SvxUnoForbiddenCharsTable ( rDoc.getIDocumentSettingAccess().getForbiddenCharacterTable() )
4326 ,m_pDoc(&rDoc)
4327 {
4328 }
4329 
4330 SwXDocumentPropertyHelper::~SwXDocumentPropertyHelper()
4331 {
4332 }
4333 
4334 Reference<XInterface> SwXDocumentPropertyHelper::GetDrawTable(SwCreateDrawTable nWhich)
4335 {
4336     Reference<XInterface> xRet;
4337     if(m_pDoc)
4338     {
4339         switch(nWhich)
4340         {
4341             // #i52858#
4342             // assure that Draw model is created, if it doesn't exist.
4343             case SwCreateDrawTable::Dash         :
4344                 if(!xDashTable.is())
4345                     xDashTable = SvxUnoDashTable_createInstance( m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
4346                 xRet = xDashTable;
4347             break;
4348             case SwCreateDrawTable::Gradient     :
4349                 if(!xGradientTable.is())
4350                     xGradientTable = SvxUnoGradientTable_createInstance( m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
4351                 xRet = xGradientTable;
4352             break;
4353             case SwCreateDrawTable::Hatch        :
4354                 if(!xHatchTable.is())
4355                     xHatchTable = SvxUnoHatchTable_createInstance( m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
4356                 xRet = xHatchTable;
4357             break;
4358             case SwCreateDrawTable::Bitmap       :
4359                 if(!xBitmapTable.is())
4360                     xBitmapTable = SvxUnoBitmapTable_createInstance( m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
4361                 xRet = xBitmapTable;
4362             break;
4363             case SwCreateDrawTable::TransGradient:
4364                 if(!xTransGradientTable.is())
4365                     xTransGradientTable = SvxUnoTransGradientTable_createInstance( m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
4366                 xRet = xTransGradientTable;
4367             break;
4368             case SwCreateDrawTable::Marker       :
4369                 if(!xMarkerTable.is())
4370                     xMarkerTable = SvxUnoMarkerTable_createInstance( m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
4371                 xRet = xMarkerTable;
4372             break;
4373             case  SwCreateDrawTable::Defaults:
4374                 if(!xDrawDefaults.is())
4375                     xDrawDefaults = static_cast<cppu::OWeakObject*>(new SwSvxUnoDrawPool(m_pDoc));
4376                 xRet = xDrawDefaults;
4377             break;
4378 #if OSL_DEBUG_LEVEL > 0
4379             default: OSL_FAIL("which table?");
4380 #endif
4381         }
4382     }
4383     return xRet;
4384 }
4385 
4386 void SwXDocumentPropertyHelper::Invalidate()
4387 {
4388     xDashTable = nullptr;
4389     xGradientTable = nullptr;
4390     xHatchTable = nullptr;
4391     xBitmapTable = nullptr;
4392     xTransGradientTable = nullptr;
4393     xMarkerTable = nullptr;
4394     xDrawDefaults = nullptr;
4395     m_pDoc = nullptr;
4396     SvxUnoForbiddenCharsTable::mxForbiddenChars.reset();
4397 }
4398 
4399 void SwXDocumentPropertyHelper::onChange()
4400 {
4401     if(m_pDoc)
4402        m_pDoc->getIDocumentState().SetModified();
4403 }
4404 
4405 SwViewOptionAdjust_Impl::SwViewOptionAdjust_Impl(
4406             SwViewShell& rSh, const SwViewOption &rViewOptions)
4407     : m_pShell(&rSh)
4408     , m_aOldViewOptions( rViewOptions )
4409 {
4410 }
4411 
4412 SwViewOptionAdjust_Impl::~SwViewOptionAdjust_Impl()
4413 {
4414     if (m_pShell)
4415     {
4416         m_pShell->ApplyViewOptions( m_aOldViewOptions );
4417     }
4418 }
4419 
4420 void
4421 SwViewOptionAdjust_Impl::AdjustViewOptions(SwPrintData const*const pPrtOptions, bool setShowPlaceHoldersInPDF)
4422 {
4423     // to avoid unnecessary reformatting the view options related to the content
4424     // below should only change if necessary, that is if respective content is present
4425     const bool bContainsHiddenChars         = m_pShell->GetDoc()->ContainsHiddenChars();
4426     const SwFieldType* pFieldType = m_pShell->GetDoc()->getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::HiddenText );
4427     const bool bContainsHiddenFields        = pFieldType && pFieldType->HasWriterListeners();
4428     pFieldType = m_pShell->GetDoc()->getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::HiddenPara );
4429     const bool bContainsHiddenParagraphs    = pFieldType && pFieldType->HasWriterListeners();
4430     pFieldType = m_pShell->GetDoc()->getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::JumpEdit );
4431     const bool bContainsPlaceHolders        = pFieldType && pFieldType->HasWriterListeners();
4432     const bool bContainsFields              = m_pShell->IsAnyFieldInDoc();
4433 
4434     SwViewOption aRenderViewOptions( m_aOldViewOptions );
4435 
4436     // disable anything in the view that should not be printed (or exported to PDF) by default
4437     // (see also dialog "Tools/Options - StarOffice Writer - Formatting Aids"
4438     // in section "Display of ...")
4439     aRenderViewOptions.SetParagraph( false );             // paragraph end
4440     aRenderViewOptions.SetSoftHyph( false );              // aka custom hyphens
4441     aRenderViewOptions.SetBlank( false );                 // spaces
4442     aRenderViewOptions.SetHardBlank( false );             // non-breaking spaces
4443     aRenderViewOptions.SetTab( false );                   // tabs
4444     aRenderViewOptions.SetLineBreak( false );             // breaks (type 1)
4445     aRenderViewOptions.SetPageBreak( false );             // breaks (type 2)
4446     aRenderViewOptions.SetColumnBreak( false );           // breaks (type 3)
4447     bool bVal = pPrtOptions && pPrtOptions->m_bPrintHiddenText;
4448     if (bContainsHiddenChars)
4449         aRenderViewOptions.SetShowHiddenChar( bVal );     // hidden text
4450     if (bContainsHiddenFields)
4451         aRenderViewOptions.SetShowHiddenField( bVal );
4452     if (bContainsHiddenParagraphs)
4453         aRenderViewOptions.SetShowHiddenPara( bVal );
4454 
4455     if (bContainsPlaceHolders)
4456     {
4457         // should always be printed in PDF export!
4458         bVal = !pPrtOptions ? setShowPlaceHoldersInPDF : pPrtOptions->m_bPrintTextPlaceholder;
4459         aRenderViewOptions.SetShowPlaceHolderFields( bVal );
4460     }
4461 
4462     if (bContainsFields)
4463         aRenderViewOptions.SetFieldName( false );
4464 
4465     // we need to set this flag in order to get to see the visible effect of
4466     // some of the above settings (needed for correct rendering)
4467     aRenderViewOptions.SetViewMetaChars( true );
4468 
4469     if (m_aOldViewOptions != aRenderViewOptions)  // check if reformatting is necessary
4470     {
4471         aRenderViewOptions.SetPrinting( pPrtOptions != nullptr );
4472         m_pShell->ApplyViewOptions( aRenderViewOptions );
4473     }
4474 }
4475 
4476 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
4477