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