tdf#149907: sc: Add UItest
[LibreOffice.git] / sw / source / uibase / uno / unotxdoc.cxx
blob865c789be815790f7fbd2c45dde7e2ea9f4c2c61
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
21 #include <officecfg/Office/Common.hxx>
22 #include <comphelper/dispatchcommand.hxx>
23 #include <comphelper/propertysequence.hxx>
24 #include <comphelper/string.hxx>
25 #include <comphelper/uno3.hxx>
26 #include <AnnotationWin.hxx>
27 #include <o3tl/any.hxx>
28 #include <utility>
29 #include <vcl/virdev.hxx>
30 #include <vcl/sysdata.hxx>
31 #include <vcl/svapp.hxx>
32 #include <vcl/print.hxx>
33 #include <sfx2/bindings.hxx>
34 #include <sfx2/viewfrm.hxx>
35 #include <sfx2/lokhelper.hxx>
36 #include <sfx2/LokControlHandler.hxx>
37 #include <sfx2/docfile.hxx>
38 #include <sfx2/printer.hxx>
39 #include <toolkit/helper/vclunohelper.hxx>
40 #include <toolkit/awt/vclxdevice.hxx>
41 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
42 #include <sfx2/lokcomponenthelpers.hxx>
43 #include <sfx2/ipclient.hxx>
44 #include <editeng/svxacorr.hxx>
45 #include <editeng/acorrcfg.hxx>
46 #include <cmdid.h>
47 #include <swtypes.hxx>
48 #include <wdocsh.hxx>
49 #include <wrtsh.hxx>
50 #include <pview.hxx>
51 #include <viewsh.hxx>
52 #include <pvprtdat.hxx>
53 #include <printdata.hxx>
54 #include <pagefrm.hxx>
55 #include <rootfrm.hxx>
56 #include <svl/stritem.hxx>
57 #include <unotxdoc.hxx>
58 #include <svl/numformat.hxx>
59 #include <svl/numuno.hxx>
60 #include <fldbas.hxx>
61 #include <unomap.hxx>
62 #include <unotextbodyhf.hxx>
63 #include <unotextrange.hxx>
64 #include <unotextcursor.hxx>
65 #include <unosett.hxx>
66 #include <unocoll.hxx>
67 #include <unoredlines.hxx>
68 #include <unosrch.hxx>
69 #include <sfx2/request.hxx>
70 #include <sfx2/objsh.hxx>
71 #include <unoprnms.hxx>
72 #include <unostyle.hxx>
73 #include <unodraw.hxx>
74 #include <svl/eitem.hxx>
75 #include <unotools/datetime.hxx>
76 #include <unocrsr.hxx>
77 #include <unofieldcoll.hxx>
78 #include <unoidxcoll.hxx>
79 #include <unocrsrhelper.hxx>
80 #include <globdoc.hxx>
81 #include <viewopt.hxx>
82 #include <unochart.hxx>
83 #include <charatr.hxx>
84 #include <svx/xmleohlp.hxx>
85 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
86 #include <com/sun/star/lang/DisposedException.hpp>
87 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
88 #include <com/sun/star/lang/NoSupportException.hpp>
89 #include <com/sun/star/lang/NotInitializedException.hpp>
90 #include <com/sun/star/beans/PropertyAttribute.hpp>
91 #include <com/sun/star/beans/XFastPropertySet.hpp>
92 #include <com/sun/star/beans/XPropertyAccess.hpp>
93 #include <com/sun/star/document/RedlineDisplayType.hpp>
94 #include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
95 #include <com/sun/star/frame/XController.hpp>
96 #include <com/sun/star/frame/XFrame.hpp>
97 #include <com/sun/star/script/XInvocation.hpp>
98 #include <com/sun/star/view/PaperOrientation.hpp>
99 #include <com/sun/star/view/XSelectionSupplier.hpp>
100 #include <sfx2/linkmgr.hxx>
101 #include <svx/unofill.hxx>
102 #include <swmodule.hxx>
103 #include <docstat.hxx>
104 #include <modcfg.hxx>
105 #include <ndtxt.hxx>
106 #include <strings.hrc>
107 #include <bitmaps.hlst>
108 #include "unodefaults.hxx"
109 #include "SwXDocumentSettings.hxx"
110 #include <doc.hxx>
111 #include <IDocumentSettingAccess.hxx>
112 #include <IDocumentDeviceAccess.hxx>
113 #include <IDocumentDrawModelAccess.hxx>
114 #include <IDocumentChartDataProviderAccess.hxx>
115 #include <IDocumentLinksAdministration.hxx>
116 #include <IDocumentRedlineAccess.hxx>
117 #include <IDocumentFieldsAccess.hxx>
118 #include <IDocumentStatistics.hxx>
119 #include <IDocumentStylePoolAccess.hxx>
120 #include <IDocumentState.hxx>
121 #include <drawdoc.hxx>
122 #include <SwStyleNameMapper.hxx>
123 #include <osl/file.hxx>
124 #include <comphelper/lok.hxx>
125 #include <comphelper/propertyvalue.hxx>
126 #include <comphelper/storagehelper.hxx>
127 #include <cppuhelper/supportsservice.hxx>
128 #include <sfx2/dispatch.hxx>
129 #include <swruler.hxx>
130 #include <docufld.hxx>
132 #include <EnhancedPDFExportHelper.hxx>
133 #include <numrule.hxx>
135 #include <editeng/langitem.hxx>
136 #include <docary.hxx>
137 #include <i18nlangtag/languagetag.hxx>
138 #include <i18nutil/searchopt.hxx>
140 #include <charfmt.hxx>
141 #include <fmtcol.hxx>
142 #include <istyleaccess.hxx>
144 #include <swatrset.hxx>
145 #include <view.hxx>
146 #include <viscrs.hxx>
147 #include <srcview.hxx>
148 #include <edtwin.hxx>
149 #include <swdtflvr.hxx>
150 #include <PostItMgr.hxx>
152 #include <svtools/langtab.hxx>
153 #include <map>
154 #include <set>
155 #include <vector>
157 #include <editeng/eeitem.hxx>
158 #include <editeng/editeng.hxx>
159 #include <editeng/editview.hxx>
160 #include <svx/svdoutl.hxx>
161 #include <svx/svdview.hxx>
162 #include <comphelper/interfacecontainer4.hxx>
163 #include <comphelper/servicehelper.hxx>
164 #include <memory>
165 #include <redline.hxx>
166 #include <DocumentRedlineManager.hxx>
167 #include <xmloff/odffields.hxx>
168 #include <tools/json_writer.hxx>
169 #include <tools/UnitConversion.hxx>
171 #include <svx/svdpage.hxx>
172 #include <o3tl/string_view.hxx>
173 #include <comphelper/sequenceashashmap.hxx>
175 #include <IDocumentOutlineNodes.hxx>
176 #include <SearchResultLocator.hxx>
177 #include <textcontentcontrol.hxx>
178 #include <unocontentcontrol.hxx>
179 #include <unoport.hxx>
180 #include <unobookmark.hxx>
181 #include <unosection.hxx>
182 #include <unofield.hxx>
183 #include <unoframe.hxx>
184 #include <unoxstyle.hxx>
185 #include <SwXTextDefaults.hxx>
187 using namespace ::com::sun::star;
188 using namespace ::com::sun::star::text;
189 using namespace ::com::sun::star::i18n;
190 using namespace ::com::sun::star::uno;
191 using namespace ::com::sun::star::beans;
192 using namespace ::com::sun::star::lang;
193 using namespace ::com::sun::star::container;
194 using namespace ::com::sun::star::document;
195 using ::osl::FileBase;
197 static std::unique_ptr<SwPrintUIOptions> lcl_GetPrintUIOptions(
198 SwDocShell * pDocShell,
199 const SfxViewShell * pView )
201 if (!pDocShell)
202 return nullptr;
204 const bool bWebDoc = nullptr != dynamic_cast< const SwWebDocShell * >(pDocShell);
205 const bool bSwSrcView = nullptr != dynamic_cast< const SwSrcView * >(pView);
206 const SwView * pSwView = dynamic_cast< const SwView * >(pView);
207 const bool bHasSelection = pSwView && pSwView->HasSelection( false ); // check for any selection, not just text selection
208 const bool bHasPostIts = sw_GetPostIts(pDocShell->GetDoc()->getIDocumentFieldsAccess(), nullptr);
210 // get default values to use in dialog from documents SwPrintData
211 const SwPrintData &rPrintData = pDocShell->GetDoc()->getIDocumentDeviceAccess().getPrintData();
213 // Get current page number
214 sal_uInt16 nCurrentPage = 1;
215 const SwWrtShell* pSh = pDocShell->GetWrtShell();
216 const SwRootFrame *pFrame = nullptr;
217 if (pSh)
219 SwPaM* pShellCursor = pSh->GetCursor();
220 nCurrentPage = pShellCursor->GetPageNum();
221 pFrame = pSh->GetLayout();
223 else if (!bSwSrcView)
225 const SwPagePreview* pPreview = dynamic_cast< const SwPagePreview* >(pView);
226 OSL_ENSURE(pPreview, "Unexpected type of the view shell");
227 if (pPreview)
229 nCurrentPage = pPreview->GetSelectedPage();
230 pFrame = pPreview->GetViewShell()->GetLayout();
234 // If blanks are skipped, account for them in initial page range value
235 if (pFrame && !rPrintData.IsPrintEmptyPages())
237 sal_uInt16 nMax = nCurrentPage;
238 const SwPageFrame *pPage = dynamic_cast<const SwPageFrame*>(pFrame->Lower());
239 while (pPage && nMax > 0)
241 nMax--;
242 if (pPage->getFrameArea().Height() == 0)
243 nCurrentPage--;
244 pPage = static_cast<const SwPageFrame*>(pPage->GetNext());
247 return std::make_unique<SwPrintUIOptions>( nCurrentPage, bWebDoc, bSwSrcView, bHasSelection, bHasPostIts, rPrintData );
250 static SwTextFormatColl *lcl_GetParaStyle(const OUString& rCollName, SwDoc& rDoc)
252 SwTextFormatColl* pColl = rDoc.FindTextFormatCollByName( rCollName );
253 if( !pColl )
255 const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(
256 rCollName, SwGetPoolIdFromName::TxtColl );
257 if( USHRT_MAX != nId )
258 pColl = rDoc.getIDocumentStylePoolAccess().GetTextCollFromPool( nId );
260 return pColl;
263 static void lcl_DisposeView( SfxViewFrame* pToClose, SwDocShell const * pDocShell )
265 // check if the view frame still exists
266 SfxViewFrame* pFound = SfxViewFrame::GetFirst( pDocShell, false );
267 while(pFound)
269 if( pFound == pToClose)
271 pToClose->DoClose();
272 break;
274 pFound = SfxViewFrame::GetNext( *pFound, pDocShell, false );
278 class SwXTextDocument::Impl
280 public:
281 std::mutex m_Mutex; // just for OInterfaceContainerHelper4
282 ::comphelper::OInterfaceContainerHelper4<css::util::XRefreshListener> m_RefreshListeners;
285 const Sequence< sal_Int8 > & SwXTextDocument::getUnoTunnelId()
287 static const comphelper::UnoIdInit theSwXTextDocumentUnoTunnelId;
288 return theSwXTextDocumentUnoTunnelId.getSeq();
291 sal_Int64 SAL_CALL SwXTextDocument::getSomething( const Sequence< sal_Int8 >& rId )
293 if( comphelper::isUnoTunnelId<SwXTextDocument>(rId) )
295 return comphelper::getSomething_cast(this);
297 if( comphelper::isUnoTunnelId<SfxObjectShell>(rId) )
299 return comphelper::getSomething_cast(m_pDocShell);
302 sal_Int64 nRet = SfxBaseModel::getSomething( rId );
303 if (nRet)
304 return nRet;
306 GetNumberFormatter();
307 auto xNumTunnel = comphelper::query_aggregation<XUnoTunnel>(m_xNumFormatAgg);
308 return (xNumTunnel.is()) ? xNumTunnel->getSomething(rId) : 0;
311 Any SAL_CALL SwXTextDocument::queryInterface( const uno::Type& rType )
313 Any aRet = SwXTextDocumentBaseClass::queryInterface(rType);
314 if ( !aRet.hasValue() )
315 aRet = SfxBaseModel::queryInterface(rType);
316 if ( !aRet.hasValue() &&
317 rType == cppu::UnoType<lang::XMultiServiceFactory>::get())
319 Reference<lang::XMultiServiceFactory> xTmp = this;
320 aRet <<= xTmp;
322 if ( !aRet.hasValue() &&
323 rType == cppu::UnoType<tiledrendering::XTiledRenderable>::get())
325 Reference<tiledrendering::XTiledRenderable> xTmp = this;
326 aRet <<= xTmp;
329 if ( !aRet.hasValue()
330 && rType != cppu::UnoType<css::document::XDocumentEventBroadcaster>::get()
331 && rType != cppu::UnoType<css::frame::XController>::get()
332 && rType != cppu::UnoType<css::frame::XFrame>::get()
333 && rType != cppu::UnoType<css::script::XInvocation>::get()
334 && rType != cppu::UnoType<css::beans::XFastPropertySet>::get()
335 && rType != cppu::UnoType<css::awt::XWindow>::get())
337 GetNumberFormatter();
338 if(m_xNumFormatAgg.is())
339 aRet = m_xNumFormatAgg->queryAggregation(rType);
341 return aRet;
344 void SAL_CALL SwXTextDocument::acquire()noexcept
346 SfxBaseModel::acquire();
349 void SAL_CALL SwXTextDocument::release()noexcept
351 SfxBaseModel::release();
354 Sequence< uno::Type > SAL_CALL SwXTextDocument::getTypes()
356 Sequence< uno::Type > aNumTypes;
357 GetNumberFormatter();
358 if (auto xNumProv = comphelper::query_aggregation<XTypeProvider>(m_xNumFormatAgg))
359 aNumTypes = xNumProv->getTypes();
360 return comphelper::concatSequences(
361 SfxBaseModel::getTypes(),
362 SwXTextDocumentBaseClass::getTypes(),
363 aNumTypes,
364 Sequence {
365 cppu::UnoType<lang::XMultiServiceFactory>::get(),
366 cppu::UnoType<tiledrendering::XTiledRenderable>::get()});
369 SwXTextDocument::SwXTextDocument(SwDocShell* pShell)
370 : SwXTextDocumentBaseClass(pShell)
371 , m_pImpl(new Impl)
373 m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_DOCUMENT)),
374 m_pDocShell(pShell),
375 m_pHiddenViewFrame(nullptr),
376 // #i117783#
377 m_bApplyPagePrintSettingsFromXPagePrintable( false )
381 void SwXTextDocument::ThrowIfInvalid() const
383 if (!m_pDocShell)
384 throw DisposedException(u"SwXTextDocument not valid"_ustr,
385 const_cast<SwXTextDocument*>(this)->getXWeak());
388 SwDoc& SwXTextDocument::GetDocOrThrow() const
390 ThrowIfInvalid();
391 if (SwDoc* pDoc = m_pDocShell->GetDoc())
392 return *pDoc;
393 throw css::lang::NotInitializedException(
394 u"Document not initialized by a call to attachResource() or load()"_ustr,
395 const_cast<SwXTextDocument*>(this)->getXWeak());
398 SdrModel& SwXTextDocument::getSdrModelFromUnoModel() const
400 return *GetDocOrThrow().getIDocumentDrawModelAccess().GetDrawModel();
403 SwXTextDocument::~SwXTextDocument()
405 InitNewDoc();
406 if(m_xNumFormatAgg.is())
408 m_xNumFormatAgg->setDelegator({});
409 m_xNumFormatAgg.clear();
411 m_pPrintUIOptions.reset();
412 if (m_pRenderData && m_pRenderData->IsViewOptionAdjust())
413 { // rhbz#827695: this can happen if the last page is not printed
414 // the SwViewShell has been deleted already by SwView::~SwView
415 // FIXME: replace this awful implementation of XRenderable with
416 // something less insane that has its own view
417 m_pRenderData->ViewOptionAdjustCrashPreventionKludge();
419 m_pRenderData.reset();
422 SwXDocumentPropertyHelper * SwXTextDocument::GetPropertyHelper ()
424 if(!mxPropertyHelper.is())
426 mxPropertyHelper = new SwXDocumentPropertyHelper(GetDocOrThrow());
428 return mxPropertyHelper.get();
431 void SwXTextDocument::GetNumberFormatter()
433 if (!m_pDocShell)
434 return;
436 if(!m_xNumFormatAgg.is())
438 if ( m_pDocShell->GetDoc() )
440 m_xNumFormatAgg = new SvNumberFormatsSupplierObj(
441 m_pDocShell->GetDoc()->GetNumberFormatter());
443 if(m_xNumFormatAgg.is())
444 m_xNumFormatAgg->setDelegator(getXWeak());
446 else
448 auto xNumTunnel = comphelper::query_aggregation<XUnoTunnel>(m_xNumFormatAgg);
449 auto pNumFormat = comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>(xNumTunnel);
450 OSL_ENSURE(pNumFormat, "No number formatter available");
451 if (pNumFormat && !pNumFormat->GetNumberFormatter())
452 pNumFormat->SetNumberFormatter(GetDocOrThrow().GetNumberFormatter());
456 Reference< XText > SwXTextDocument::getText()
458 return getBodyText();
461 rtl::Reference< SwXBodyText > SwXTextDocument::getBodyText()
463 SolarMutexGuard aGuard;
464 ThrowIfInvalid();
465 if(!m_xBodyText.is())
467 m_xBodyText = new SwXBodyText(m_pDocShell->GetDoc());
469 return m_xBodyText;
472 void SwXTextDocument::reformat()
474 SolarMutexGuard aGuard;
475 ThrowIfInvalid();
478 void SwXTextDocument::lockControllers()
480 SolarMutexGuard aGuard;
481 ThrowIfInvalid();
483 maActionArr.emplace_front(new UnoActionContext(m_pDocShell->GetDoc()));
486 void SwXTextDocument::unlockControllers()
488 SolarMutexGuard aGuard;
489 if(maActionArr.empty())
490 throw RuntimeException(u"Nothing to unlock"_ustr);
492 maActionArr.pop_front();
495 sal_Bool SwXTextDocument::hasControllersLocked()
497 SolarMutexGuard aGuard;
498 return !maActionArr.empty();
501 Reference< frame::XController > SwXTextDocument::getCurrentController()
503 return SfxBaseModel::getCurrentController();
506 void SwXTextDocument::setCurrentController(const Reference< frame::XController > & xController)
508 SfxBaseModel::setCurrentController(xController);
511 Reference< XInterface > SwXTextDocument::getCurrentSelection()
513 SolarMutexGuard aGuard;
514 Reference< XInterface > xRef;
515 if (m_pDocShell)
517 SwView* pView = static_cast<SwView*>(SfxViewShell::GetFirst(true, checkSfxViewShell<SwView>));
518 while(pView && pView->GetObjectShell() != m_pDocShell)
520 pView = static_cast<SwView*>(SfxViewShell::GetNext(*pView, true, checkSfxViewShell<SwView>));
522 if(pView)
524 Any aRef = pView->GetUNOObject()->getSelection();
525 aRef >>= xRef;
528 return xRef;
531 sal_Bool SwXTextDocument::attachResource(const OUString& aURL, const Sequence< beans::PropertyValue >& aArgs)
533 return SfxBaseModel::attachResource(aURL, aArgs);
536 OUString SwXTextDocument::getURL()
538 return SfxBaseModel::getURL();
541 Sequence< beans::PropertyValue > SwXTextDocument::getArgs()
543 return SfxBaseModel::getArgs();
546 void SwXTextDocument::connectController(const Reference< frame::XController > & xController)
548 SfxBaseModel::connectController(xController);
551 void SwXTextDocument::disconnectController(const Reference< frame::XController > & xController)
553 SfxBaseModel::disconnectController(xController);
556 void SwXTextDocument::dispose()
558 // Delete UnoActionContexts before deleting the SwDoc, as the first has unowned pointers to the
559 // second.
560 maActionArr.clear();
562 SfxBaseModel::dispose();
565 void SwXTextDocument::close( sal_Bool bDeliverOwnership )
567 if(m_pDocShell)
569 uno::Sequence< uno::Any > aArgs;
570 m_pDocShell->CallAutomationDocumentEventSinks( u"Close"_ustr, aArgs );
572 SolarMutexGuard aGuard;
573 if (m_pDocShell && m_pHiddenViewFrame)
574 lcl_DisposeView( m_pHiddenViewFrame, m_pDocShell);
575 SfxBaseModel::close(bDeliverOwnership);
578 void SwXTextDocument::addEventListener(const Reference< lang::XEventListener > & aListener)
580 SfxBaseModel::addEventListener(aListener);
583 void SwXTextDocument::removeEventListener(const Reference< lang::XEventListener > & aListener)
585 SfxBaseModel::removeEventListener(aListener);
588 Reference< XPropertySet > SwXTextDocument::getLineNumberingProperties()
590 SolarMutexGuard aGuard;
591 ThrowIfInvalid();
593 if(!mxXLineNumberingProperties.is())
595 mxXLineNumberingProperties = new SwXLineNumberingProperties(m_pDocShell->GetDoc());
597 return mxXLineNumberingProperties;
600 Reference< XIndexReplace > SwXTextDocument::getChapterNumberingRules()
602 SolarMutexGuard aGuard;
603 ThrowIfInvalid();
604 if(!mxXChapterNumbering.is())
606 mxXChapterNumbering = new SwXChapterNumbering(*m_pDocShell);
608 return mxXChapterNumbering;
611 Reference< XIndexAccess > SwXTextDocument::getNumberingRules()
613 SolarMutexGuard aGuard;
614 ThrowIfInvalid();
615 if(!mxXNumberingRules.is() )
617 mxXNumberingRules = new SwXNumberingRulesCollection( m_pDocShell->GetDoc() );
619 return mxXNumberingRules;
622 Reference< XIndexAccess > SwXTextDocument::getFootnotes()
624 return getSwXFootnotes();
627 rtl::Reference< SwXFootnotes > SwXTextDocument::getSwXFootnotes()
629 SolarMutexGuard aGuard;
630 ThrowIfInvalid();
631 if(!mxXFootnotes.is())
633 mxXFootnotes = new SwXFootnotes(false, m_pDocShell->GetDoc());
635 return mxXFootnotes;
638 Reference< XPropertySet > SAL_CALL
639 SwXTextDocument::getFootnoteSettings()
641 SolarMutexGuard aGuard;
642 ThrowIfInvalid();
643 if(!mxXFootnoteSettings.is())
645 mxXFootnoteSettings = new SwXFootnoteProperties(m_pDocShell->GetDoc());
647 return mxXFootnoteSettings;
650 Reference< XIndexAccess > SwXTextDocument::getEndnotes()
652 return getSwXEndnotes();
655 rtl::Reference< SwXFootnotes > SwXTextDocument::getSwXEndnotes()
657 SolarMutexGuard aGuard;
658 ThrowIfInvalid();
659 if(!mxXEndnotes.is())
661 mxXEndnotes = new SwXFootnotes(true, m_pDocShell->GetDoc());
663 return mxXEndnotes;
666 Reference< XPropertySet > SwXTextDocument::getEndnoteSettings()
668 SolarMutexGuard aGuard;
669 ThrowIfInvalid();
670 if(!mxXEndnoteSettings.is())
672 mxXEndnoteSettings = new SwXEndnoteProperties(m_pDocShell->GetDoc());
674 return mxXEndnoteSettings;
677 Reference< XIndexAccess > SwXTextDocument::getContentControls()
679 SolarMutexGuard aGuard;
680 ThrowIfInvalid();
681 if(!mxXContentControls.is())
683 mxXContentControls = new SwXContentControls(m_pDocShell->GetDoc());
685 return mxXContentControls;
688 Reference< util::XReplaceDescriptor > SwXTextDocument::createReplaceDescriptor()
690 return new SwXTextSearch;
693 SwUnoCursor* SwXTextDocument::CreateCursorForSearch(Reference< XTextCursor > & xCursor)
695 rtl::Reference<SwXTextCursor> pXTextCursor = getBodyText()->CreateTextCursor(true);
696 xCursor.set( static_cast<text::XWordCursor*>(pXTextCursor.get()) );
698 auto& rUnoCursor(pXTextCursor->GetCursor());
699 rUnoCursor.SetRemainInSection(false);
700 return &rUnoCursor;
703 sal_Int32 SwXTextDocument::replaceAll(const Reference< util::XSearchDescriptor > & xDesc)
705 SolarMutexGuard aGuard;
706 ThrowIfInvalid();
707 auto* pSearch = dynamic_cast<SwXTextSearch*>(xDesc.get());
708 if (!pSearch)
709 throw DisposedException(u""_ustr, getXWeak());
711 Reference< XTextCursor > xCursor;
712 auto pUnoCursor(CreateCursorForSearch(xCursor));
713 FindRanges eRanges(FindRanges::InBody|FindRanges::InSelAll);
715 i18nutil::SearchOptions2 aSearchOpt;
716 pSearch->FillSearchOptions( aSearchOpt );
718 SwDocPositions eStart = pSearch->m_bBack ? SwDocPositions::End : SwDocPositions::Start;
719 SwDocPositions eEnd = pSearch->m_bBack ? SwDocPositions::Start : SwDocPositions::End;
721 // Search should take place anywhere
722 pUnoCursor->SetRemainInSection(false);
723 sal_Int32 nResult;
724 UnoActionContext aContext(m_pDocShell->GetDoc());
725 //try attribute search first
726 if(pSearch->HasSearchAttributes()||pSearch->HasReplaceAttributes())
728 auto& pool = GetDocOrThrow().GetAttrPool();
729 SfxItemSetFixed<RES_CHRATR_BEGIN, RES_CHRATR_END-1,
730 RES_PARATR_BEGIN, RES_PARATR_END-1,
731 RES_FRMATR_BEGIN, RES_FRMATR_END-1> aSearch(pool);
732 SfxItemSetFixed<RES_CHRATR_BEGIN, RES_CHRATR_END-1,
733 RES_PARATR_BEGIN, RES_PARATR_END-1,
734 RES_FRMATR_BEGIN, RES_FRMATR_END-1> aReplace(pool);
735 pSearch->FillSearchItemSet(aSearch);
736 pSearch->FillReplaceItemSet(aReplace);
737 bool bCancel;
738 nResult = pUnoCursor->FindAttrs(aSearch, !pSearch->m_bStyles,
739 eStart, eEnd, bCancel,
740 eRanges,
741 !pSearch->m_sSearchText.isEmpty() ? &aSearchOpt : nullptr,
742 &aReplace );
744 else if(pSearch->m_bStyles)
746 SwTextFormatColl *pSearchColl = lcl_GetParaStyle(pSearch->m_sSearchText, pUnoCursor->GetDoc());
747 SwTextFormatColl *pReplaceColl = lcl_GetParaStyle(pSearch->m_sReplaceText, pUnoCursor->GetDoc());
749 bool bCancel;
750 nResult = pUnoCursor->FindFormat(*pSearchColl,
751 eStart, eEnd, bCancel,
752 eRanges, pReplaceColl );
755 else
757 //todo/mba: assuming that notes should be omitted
758 bool bCancel;
759 nResult = pUnoCursor->Find_Text(aSearchOpt, false/*bSearchInNotes*/,
760 eStart, eEnd, bCancel,
761 eRanges,
762 true );
764 return nResult;
768 Reference< util::XSearchDescriptor > SwXTextDocument::createSearchDescriptor()
770 return new SwXTextSearch;
773 // Used for findAll/First/Next
775 SwUnoCursor* SwXTextDocument::FindAny(const Reference< util::XSearchDescriptor > & xDesc,
776 Reference< XTextCursor > & xCursor,
777 bool bAll,
778 sal_Int32& nResult,
779 Reference< XInterface > const & xLastResult)
781 ThrowIfInvalid();
782 const auto pSearch = dynamic_cast<SwXTextSearch*>(xDesc.get());
783 if (!pSearch)
784 return nullptr;
786 auto pUnoCursor(CreateCursorForSearch(xCursor));
788 bool bParentInExtra = false;
789 if(xLastResult.is())
791 OTextCursorHelper* pPosCursor = dynamic_cast<OTextCursorHelper*>(xLastResult.get());
792 SwPaM* pCursor = pPosCursor ? pPosCursor->GetPaM() : nullptr;
793 if(pCursor)
795 *pUnoCursor->GetPoint() = *pCursor->End();
796 pUnoCursor->DeleteMark();
798 else
800 SwXTextRange* pRange = dynamic_cast<SwXTextRange*>(xLastResult.get());
801 if(!pRange)
802 return nullptr;
803 pRange->GetPositions(*pUnoCursor);
804 if(pUnoCursor->HasMark())
806 if(*pUnoCursor->GetPoint() < *pUnoCursor->GetMark())
807 pUnoCursor->Exchange();
808 pUnoCursor->DeleteMark();
811 const SwNode& rRangeNode = pUnoCursor->GetPointNode();
812 bParentInExtra = rRangeNode.FindFlyStartNode() ||
813 rRangeNode.FindFootnoteStartNode() ||
814 rRangeNode.FindHeaderStartNode() ||
815 rRangeNode.FindFooterStartNode() ;
818 i18nutil::SearchOptions2 aSearchOpt;
819 pSearch->FillSearchOptions( aSearchOpt );
822 * The following combinations are allowed:
823 * - Search in the body: -> FindRanges::InBody
824 * - Search all in the body: -> FindRanges::InBodyOnly | FindRanges::InSelAll
825 * - Search in selections: one / all -> FindRanges::InSel [ | FindRanges::InSelAll ]
826 * - Search outside the body: one / all -> FindRanges::InOther [ | FindRanges::InSelAll ]
827 * - Search everywhere all: -> FindRanges::InSelAll
829 FindRanges eRanges(FindRanges::InBody);
830 if(bParentInExtra)
831 eRanges = FindRanges::InOther;
832 if(bAll) //always - everywhere?
833 eRanges = FindRanges::InSelAll;
834 SwDocPositions eStart = !bAll ? SwDocPositions::Curr : pSearch->m_bBack ? SwDocPositions::End : SwDocPositions::Start;
835 SwDocPositions eEnd = pSearch->m_bBack ? SwDocPositions::Start : SwDocPositions::End;
837 nResult = 0;
838 for (int nSearchProc = 0; nSearchProc < 2; ++nSearchProc)
840 //try attribute search first
841 if(pSearch->HasSearchAttributes())
843 SfxItemSetFixed<
844 RES_CHRATR_BEGIN, RES_CHRATR_END - 1,
845 RES_TXTATR_INETFMT, RES_TXTATR_CHARFMT,
846 RES_PARATR_BEGIN, RES_PARATR_END - 1,
847 RES_FRMATR_BEGIN, RES_FRMATR_END - 1>
848 aSearch( GetDocOrThrow().GetAttrPool() );
849 pSearch->FillSearchItemSet(aSearch);
850 bool bCancel;
851 nResult = pUnoCursor->FindAttrs(aSearch, !pSearch->m_bStyles,
852 eStart, eEnd, bCancel,
853 eRanges,
854 !pSearch->m_sSearchText.isEmpty() ? &aSearchOpt : nullptr );
856 else if(pSearch->m_bStyles)
858 SwTextFormatColl *pSearchColl = lcl_GetParaStyle(pSearch->m_sSearchText, pUnoCursor->GetDoc());
859 //pSearch->sReplaceText
860 SwTextFormatColl *pReplaceColl = nullptr;
861 bool bCancel;
862 nResult = pUnoCursor->FindFormat(*pSearchColl,
863 eStart, eEnd, bCancel,
864 eRanges, pReplaceColl );
866 else
868 //todo/mba: assuming that notes should be omitted
869 bool bCancel;
870 nResult = pUnoCursor->Find_Text(aSearchOpt, false/*bSearchInNotes*/,
871 eStart, eEnd, bCancel,
872 eRanges );
874 if(nResult || (eRanges&(FindRanges::InSelAll|FindRanges::InOther)))
875 break;
876 //second step - find in other
877 eRanges = FindRanges::InOther;
879 return pUnoCursor;
882 Reference< XIndexAccess >
883 SwXTextDocument::findAll(const Reference< util::XSearchDescriptor > & xDesc)
885 SolarMutexGuard aGuard;
886 Reference< XInterface > xTmp;
887 sal_Int32 nResult = 0;
888 Reference< XTextCursor > xCursor;
889 auto pResultCursor(FindAny(xDesc, xCursor, true, nResult, xTmp));
890 if(!pResultCursor)
891 throw RuntimeException(u"No result cursor"_ustr);
892 Reference< XIndexAccess > xRet = SwXTextRanges::Create( nResult ? &(*pResultCursor) : nullptr );
893 return xRet;
896 Reference< XInterface > SwXTextDocument::findFirst(const Reference< util::XSearchDescriptor > & xDesc)
898 SolarMutexGuard aGuard;
899 Reference< XInterface > xTmp;
900 sal_Int32 nResult = 0;
901 Reference< XTextCursor > xCursor;
902 auto pResultCursor(FindAny(xDesc, xCursor, false, nResult, xTmp));
903 if(!pResultCursor)
904 throw RuntimeException(u"No result cursor"_ustr);
905 Reference< XInterface > xRet;
906 if(nResult)
908 const uno::Reference< text::XText > xParent =
909 ::sw::CreateParentXText(GetDocOrThrow(),
910 *pResultCursor->GetPoint());
911 xRet = *new SwXTextCursor(xParent, *pResultCursor);
913 return xRet;
916 Reference< XInterface > SwXTextDocument::findNext(const Reference< XInterface > & xStartAt,
917 const Reference< util::XSearchDescriptor > & xDesc)
919 SolarMutexGuard aGuard;
920 sal_Int32 nResult = 0;
921 Reference< XTextCursor > xCursor;
922 if(!xStartAt.is())
923 throw RuntimeException(u"xStartAt missing"_ustr);
924 auto pResultCursor(FindAny(xDesc, xCursor, false, nResult, xStartAt));
925 if(!pResultCursor)
926 throw RuntimeException(u"No result cursor"_ustr);
927 Reference< XInterface > xRet;
928 if(nResult)
930 const uno::Reference< text::XText > xParent =
931 ::sw::CreateParentXText(GetDocOrThrow(),
932 *pResultCursor->GetPoint());
934 xRet = *new SwXTextCursor(xParent, *pResultCursor);
936 return xRet;
939 Sequence< beans::PropertyValue > SwXTextDocument::getPagePrintSettings()
941 SolarMutexGuard aGuard;
942 Sequence< beans::PropertyValue > aSeq(9);
943 ThrowIfInvalid();
945 beans::PropertyValue* pArray = aSeq.getArray();
946 SwPagePreviewPrtData aData;
947 const SwPagePreviewPrtData* pData = GetDocOrThrow().GetPreviewPrtData();
948 if(pData)
949 aData = *pData;
950 Any aVal;
951 aVal <<= aData.GetRow();
952 pArray[0] = beans::PropertyValue(u"PageRows"_ustr, -1, aVal, PropertyState_DIRECT_VALUE);
953 aVal <<= aData.GetCol();
954 pArray[1] = beans::PropertyValue(u"PageColumns"_ustr, -1, aVal, PropertyState_DIRECT_VALUE);
955 aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetLeftSpace()));
956 pArray[2] = beans::PropertyValue(u"LeftMargin"_ustr, -1, aVal, PropertyState_DIRECT_VALUE);
957 aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetRightSpace()));
958 pArray[3] = beans::PropertyValue(u"RightMargin"_ustr, -1, aVal, PropertyState_DIRECT_VALUE);
959 aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetTopSpace()));
960 pArray[4] = beans::PropertyValue(u"TopMargin"_ustr, -1, aVal, PropertyState_DIRECT_VALUE);
961 aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetBottomSpace()));
962 pArray[5] = beans::PropertyValue(u"BottomMargin"_ustr, -1, aVal, PropertyState_DIRECT_VALUE);
963 aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetHorzSpace()));
964 pArray[6] = beans::PropertyValue(u"HoriMargin"_ustr, -1, aVal, PropertyState_DIRECT_VALUE);
965 aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetVertSpace()));
966 pArray[7] = beans::PropertyValue(u"VertMargin"_ustr, -1, aVal, PropertyState_DIRECT_VALUE);
967 aVal <<= aData.GetLandscape();
968 pArray[8] = beans::PropertyValue(u"IsLandscape"_ustr, -1, aVal, PropertyState_DIRECT_VALUE);
970 return aSeq;
973 static sal_uInt32 lcl_Any_To_ULONG(const Any& rValue, bool& bException)
975 bException = false;
976 TypeClass eType = rValue.getValueTypeClass();
978 sal_uInt32 nRet = 0;
979 if( eType == TypeClass_UNSIGNED_LONG )
980 rValue >>= nRet;
981 else
983 sal_Int32 nVal=0;
984 bException = !(rValue >>= nVal);
985 if( !bException )
986 nRet = static_cast<sal_uInt32>(nVal);
989 return nRet;
992 static OUString lcl_CreateOutlineString(const size_t nIndex, const SwDoc* pDoc)
994 OUStringBuffer sEntry;
995 const SwOutlineNodes& rOutlineNodes = pDoc->GetNodes().GetOutLineNds();
996 const SwNumRule* pOutlRule = pDoc->GetOutlineNumRule();
997 const SwTextNode * pTextNd = rOutlineNodes[ nIndex ]->GetTextNode();
998 SwNumberTree::tNumberVector aNumVector = pTextNd->GetNumberVector();
999 if( pOutlRule && pTextNd->GetNumRule())
1000 for( int nLevel = 0;
1001 nLevel <= pTextNd->GetActualListLevel();
1002 nLevel++ )
1004 tools::Long nVal = aNumVector[nLevel];
1005 nVal ++;
1006 nVal -= pOutlRule->Get(nLevel).GetStart();
1007 sEntry.append( OUString::number(nVal) + ".");
1009 if (const SwDocShell* pShell = pDoc->GetDocShell())
1011 OUString sOutlineText = pDoc->getIDocumentOutlineNodes().getOutlineText(
1012 nIndex, pShell->GetWrtShell()->GetLayout(), false);
1013 sEntry.append(sOutlineText);
1015 return sEntry.makeStringAndClear();
1018 void SwXTextDocument::setPagePrintSettings(const Sequence< beans::PropertyValue >& aSettings)
1020 SolarMutexGuard aGuard;
1021 ThrowIfInvalid();
1023 SwPagePreviewPrtData aData;
1024 SwDoc& rDoc = GetDocOrThrow();
1025 //if only a few properties are coming, then use the current settings
1026 const SwPagePreviewPrtData* pData = rDoc.GetPreviewPrtData();
1027 if(pData)
1028 aData = *pData;
1029 for(const beans::PropertyValue& rProperty : aSettings)
1031 OUString sName = rProperty.Name;
1032 const Any& rVal = rProperty.Value;
1033 bool bException;
1034 sal_uInt32 nVal = lcl_Any_To_ULONG(rVal, bException);
1035 if( sName == "PageRows" )
1037 if(!nVal || nVal > 0xff)
1038 throw RuntimeException(u"Invalid value"_ustr);
1039 aData.SetRow(nVal);
1041 else if(sName == "PageColumns")
1043 if(!nVal || nVal > 0xff)
1044 throw RuntimeException(u"Invalid value"_ustr);
1045 aData.SetCol(nVal);
1047 else if(sName == "LeftMargin")
1049 aData.SetLeftSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
1051 else if(sName == "RightMargin")
1053 aData.SetRightSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
1055 else if(sName == "TopMargin")
1057 aData.SetTopSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
1059 else if(sName == "BottomMargin")
1061 aData.SetBottomSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
1063 else if(sName == "HoriMargin")
1065 aData.SetHorzSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
1067 else if(sName == "VertMargin")
1069 aData.SetVertSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
1071 else if(sName == "IsLandscape")
1073 std::optional<const bool> b = o3tl::tryAccess<bool>(rVal);
1074 bException = !b.has_value();
1075 if (b)
1077 aData.SetLandscape(*b);
1080 else
1081 bException = true;
1082 if(bException)
1083 throw RuntimeException();
1085 rDoc.SetPreviewPrtData(&aData);
1089 void SwXTextDocument::printPages(const Sequence< beans::PropertyValue >& xOptions)
1091 SolarMutexGuard aGuard;
1092 ThrowIfInvalid();
1094 SfxViewFrame* pFrame = SfxViewFrame::LoadHiddenDocument( *m_pDocShell, SfxInterfaceId(7) );
1095 SfxRequest aReq(FN_PRINT_PAGEPREVIEW, SfxCallMode::SYNCHRON,
1096 GetDocOrThrow().GetAttrPool());
1097 aReq.AppendItem(SfxBoolItem(FN_PRINT_PAGEPREVIEW, true));
1099 for ( const beans::PropertyValue &rProp : xOptions )
1101 // get Property-Value from options
1102 Any aValue( rProp.Value );
1104 // FileName-Property?
1105 if ( rProp.Name == UNO_NAME_FILE_NAME )
1107 OUString sFileURL;
1108 if ( rProp.Value >>= sFileURL )
1110 // Convert the File URL into a system dependent path, as the SalPrinter expects
1111 OUString sSystemPath;
1112 FileBase::getSystemPathFromFileURL ( sFileURL, sSystemPath );
1113 aReq.AppendItem(SfxStringItem( SID_FILE_NAME, sSystemPath ) );
1115 else if ( rProp.Value.getValueType() != cppu::UnoType<void>::get() )
1116 throw IllegalArgumentException();
1119 // CopyCount-Property
1120 else if ( rProp.Name == UNO_NAME_COPY_COUNT )
1122 sal_Int32 nCopies = 0;
1123 aValue >>= nCopies;
1124 aReq.AppendItem(SfxInt16Item( SID_PRINT_COPIES, static_cast<sal_Int16>(nCopies) ) );
1127 // Collate-Property
1128 else if ( rProp.Name == UNO_NAME_COLLATE )
1130 std::optional<const bool> b = o3tl::tryAccess<bool>(rProp.Value);
1131 if ( !b.has_value() )
1132 throw IllegalArgumentException();
1133 aReq.AppendItem(SfxBoolItem( SID_PRINT_COLLATE, *b ) );
1137 // Sort-Property
1138 else if ( rProp.Name == UNO_NAME_SORT )
1140 std::optional<const bool> b = o3tl::tryAccess<bool>(rProp.Value);
1141 if ( !b.has_value() )
1142 throw IllegalArgumentException();
1144 aReq.AppendItem(SfxBoolItem( SID_PRINT_SORT, *b ) );
1147 // Pages-Property
1148 else if ( rProp.Name == UNO_NAME_PAGES )
1150 OUString sTmp;
1151 if ( !(rProp.Value >>= sTmp) )
1152 throw IllegalArgumentException();
1154 aReq.AppendItem( SfxStringItem( SID_PRINT_PAGES, sTmp ) );
1159 // #i117783#
1160 m_bApplyPagePrintSettingsFromXPagePrintable = true;
1161 pFrame->GetViewShell()->ExecuteSlot(aReq);
1162 // Frame close
1163 pFrame->DoClose();
1167 Reference< XNameAccess > SwXTextDocument::getReferenceMarks()
1169 SolarMutexGuard aGuard;
1170 ThrowIfInvalid();
1171 if(!mxXReferenceMarks.is())
1173 mxXReferenceMarks = new SwXReferenceMarks(m_pDocShell->GetDoc());
1175 return mxXReferenceMarks;
1178 Reference< XEnumerationAccess > SwXTextDocument::getTextFields()
1180 return getSwTextFields();
1183 rtl::Reference< SwXTextFieldTypes > SwXTextDocument::getSwTextFields()
1185 SolarMutexGuard aGuard;
1186 ThrowIfInvalid();
1187 if(!mxXTextFieldTypes.is())
1189 mxXTextFieldTypes = new SwXTextFieldTypes(m_pDocShell->GetDoc());
1191 return mxXTextFieldTypes;
1194 Reference< XNameAccess > SwXTextDocument::getTextFieldMasters()
1196 return getSwXTextFieldMasters();
1199 rtl::Reference< SwXTextFieldMasters > SwXTextDocument::getSwXTextFieldMasters()
1201 SolarMutexGuard aGuard;
1202 ThrowIfInvalid();
1203 if(!mxXTextFieldMasters.is())
1205 mxXTextFieldMasters = new SwXTextFieldMasters(m_pDocShell->GetDoc());
1207 return mxXTextFieldMasters;
1210 Reference< XNameAccess > SwXTextDocument::getEmbeddedObjects()
1212 SolarMutexGuard aGuard;
1213 ThrowIfInvalid();
1214 if(!mxXEmbeddedObjects.is())
1216 mxXEmbeddedObjects = new SwXTextEmbeddedObjects(m_pDocShell->GetDoc());
1218 return mxXEmbeddedObjects;
1221 Reference< XNameAccess > SwXTextDocument::getBookmarks()
1223 SolarMutexGuard aGuard;
1224 ThrowIfInvalid();
1225 if(!mxXBookmarks.is())
1227 mxXBookmarks = new SwXBookmarks(m_pDocShell->GetDoc());
1229 return mxXBookmarks;
1232 Reference< XNameAccess > SwXTextDocument::getTextSections()
1234 SolarMutexGuard aGuard;
1235 ThrowIfInvalid();
1236 if(!mxXTextSections.is())
1238 mxXTextSections = new SwXTextSections(m_pDocShell->GetDoc());
1240 return mxXTextSections;
1243 Reference< XNameAccess > SwXTextDocument::getTextTables()
1245 return getSwTextTables();
1248 rtl::Reference<SwXTextTables> SwXTextDocument::getSwTextTables()
1250 SolarMutexGuard aGuard;
1251 ThrowIfInvalid();
1252 if(!mxXTextTables.is())
1254 mxXTextTables = new SwXTextTables(m_pDocShell->GetDoc());
1256 return mxXTextTables;
1259 Reference< XNameAccess > SwXTextDocument::getGraphicObjects()
1261 SolarMutexGuard aGuard;
1262 ThrowIfInvalid();
1263 if(!mxXGraphicObjects.is())
1265 mxXGraphicObjects = new SwXTextGraphicObjects(m_pDocShell->GetDoc());
1267 return mxXGraphicObjects;
1270 Reference< XNameAccess > SwXTextDocument::getTextFrames()
1272 return getSwTextFrames();
1275 rtl::Reference< SwXTextFrames > SwXTextDocument::getSwTextFrames()
1277 SolarMutexGuard aGuard;
1278 ThrowIfInvalid();
1279 if(!mxXTextFrames.is())
1281 mxXTextFrames = new SwXTextFrames(m_pDocShell->GetDoc());
1283 return mxXTextFrames;
1286 Reference< XNameAccess > SwXTextDocument::getStyleFamilies()
1288 return getSwStyleFamilies();
1291 rtl::Reference< SwXStyleFamilies > SwXTextDocument::getSwStyleFamilies()
1293 SolarMutexGuard aGuard;
1294 ThrowIfInvalid();
1295 if(!mxXStyleFamilies.is())
1297 mxXStyleFamilies = new SwXStyleFamilies(*m_pDocShell);
1299 return mxXStyleFamilies;
1302 uno::Reference< style::XAutoStyles > SwXTextDocument::getAutoStyles( )
1304 SolarMutexGuard aGuard;
1305 ThrowIfInvalid();
1306 if(!mxXAutoStyles.is())
1308 mxXAutoStyles = new SwXAutoStyles(*m_pDocShell);
1310 return mxXAutoStyles;
1314 Reference< drawing::XDrawPage > SwXTextDocument::getDrawPage()
1316 return getSwDrawPage();
1319 rtl::Reference< SwFmDrawPage > SwXTextDocument::getSwDrawPage()
1321 SolarMutexGuard aGuard;
1322 ThrowIfInvalid();
1323 if(!m_xDrawPage.is())
1325 SwDoc& rDoc = GetDocOrThrow();
1326 // #i52858#
1327 SwDrawModel& rModel = rDoc.getIDocumentDrawModelAccess().GetOrCreateDrawModel();
1328 SdrPage* pPage = rModel.GetPage( 0 );
1329 m_xDrawPage = new SwFmDrawPage(&rDoc, pPage);
1331 return m_xDrawPage;
1334 namespace {
1336 class SwDrawPagesObj : public cppu::WeakImplHelper<
1337 css::drawing::XDrawPages,
1338 css::lang::XServiceInfo>
1340 private:
1341 css::uno::Reference< css::drawing::XDrawPageSupplier > m_xDoc;
1342 public:
1343 SwDrawPagesObj(css::uno::Reference< css::drawing::XDrawPageSupplier > xDoc) : m_xDoc(std::move(xDoc)) {}
1345 // XDrawPages
1346 virtual css::uno::Reference< css::drawing::XDrawPage > SAL_CALL
1347 insertNewByIndex(sal_Int32 /*nIndex*/) override { throw css::lang::NoSupportException(); }
1349 virtual void SAL_CALL remove(const css::uno::Reference< css::drawing::XDrawPage >& /*xPage*/) override
1351 throw css::lang::NoSupportException();
1354 // XIndexAccess
1355 virtual sal_Int32 SAL_CALL getCount() override { return 1; }
1357 virtual css::uno::Any SAL_CALL getByIndex(sal_Int32 Index) override
1359 if (Index != 0)
1360 throw css::lang::IndexOutOfBoundsException(u"Writer documents have only one DrawPage!"_ustr);
1361 return css::uno::Any(m_xDoc->getDrawPage());
1364 // XElementAccess
1365 virtual css::uno::Type SAL_CALL getElementType() override
1367 return cppu::UnoType<drawing::XDrawPage>::get();
1370 virtual sal_Bool SAL_CALL hasElements() override { return true; }
1372 // XServiceInfo
1373 virtual OUString SAL_CALL getImplementationName() override
1375 return u"SwDrawPagesObj"_ustr;
1378 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override
1380 return cppu::supportsService(this, ServiceName);
1383 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
1385 return { u"com.sun.star.drawing.DrawPages"_ustr };
1391 // XDrawPagesSupplier
1393 uno::Reference<drawing::XDrawPages> SAL_CALL SwXTextDocument::getDrawPages()
1395 SolarMutexGuard aGuard;
1396 return new SwDrawPagesObj(this);
1399 void SwXTextDocument::Invalidate()
1401 m_pDocShell = nullptr;
1402 InitNewDoc();
1403 lang::EventObject const ev(getXWeak());
1404 std::unique_lock aGuard(m_pImpl->m_Mutex);
1405 m_pImpl->m_RefreshListeners.disposeAndClear(aGuard, ev);
1408 void SwXTextDocument::Reactivate(SwDocShell* pNewDocShell)
1410 if(m_pDocShell && m_pDocShell != pNewDocShell)
1411 Invalidate();
1412 m_pDocShell = pNewDocShell;
1415 void SwXTextDocument::InitNewDoc()
1417 if (auto xNumTunnel = comphelper::query_aggregation<XUnoTunnel>(m_xNumFormatAgg))
1419 auto pNumFormat = comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>(xNumTunnel);
1420 OSL_ENSURE(pNumFormat, "No number formatter available");
1421 if (pNumFormat)
1422 pNumFormat->SetNumberFormatter(nullptr);
1425 // first invalidate all collections, then delete references and Set to zero
1426 if(mxXTextTables.is())
1428 mxXTextTables->Invalidate();
1429 mxXTextTables.clear();
1432 if(mxXTextFrames.is())
1434 mxXTextFrames->Invalidate();
1435 mxXTextFrames.clear();
1438 if(mxXGraphicObjects.is())
1440 mxXGraphicObjects->Invalidate();
1441 mxXGraphicObjects.clear();
1444 if(mxXEmbeddedObjects.is())
1446 mxXEmbeddedObjects->Invalidate();
1447 mxXEmbeddedObjects.clear();
1450 m_xBodyText.clear();
1452 if(mxXTextFieldTypes.is())
1454 mxXTextFieldTypes->Invalidate();
1455 mxXTextFieldTypes.clear();
1458 if(mxXTextFieldMasters.is())
1460 mxXTextFieldMasters->Invalidate();
1461 mxXTextFieldMasters.clear();
1464 if(mxXTextSections.is())
1466 mxXTextSections->Invalidate();
1467 mxXTextSections.clear();
1470 if(m_xDrawPage.is())
1472 // #i91798#, #i91895#
1473 // dispose XDrawPage here. We are the owner and know that it is no longer in a valid condition.
1474 m_xDrawPage->dispose();
1475 m_xDrawPage->InvalidateSwDoc();
1476 m_xDrawPage.clear();
1479 if ( mxXNumberingRules.is() )
1481 mxXNumberingRules->Invalidate();
1482 mxXNumberingRules.clear();
1485 if(mxXFootnotes.is())
1487 mxXFootnotes->Invalidate();
1488 mxXFootnotes.clear();
1491 if(mxXEndnotes.is())
1493 mxXEndnotes->Invalidate();
1494 mxXEndnotes.clear();
1497 if(mxXContentControls.is())
1499 mxXContentControls->Invalidate();
1500 mxXContentControls.clear();
1503 if(mxXDocumentIndexes.is())
1505 mxXDocumentIndexes->Invalidate();
1506 mxXDocumentIndexes.clear();
1509 if(mxXStyleFamilies.is())
1511 mxXStyleFamilies->Invalidate();
1512 mxXStyleFamilies.clear();
1514 if(mxXAutoStyles.is())
1516 mxXAutoStyles->Invalidate();
1517 mxXAutoStyles.clear();
1520 if(mxXBookmarks.is())
1522 mxXBookmarks->Invalidate();
1523 mxXBookmarks.clear();
1526 if(mxXChapterNumbering.is())
1528 mxXChapterNumbering->Invalidate();
1529 mxXChapterNumbering.clear();
1532 if(mxXFootnoteSettings.is())
1534 mxXFootnoteSettings->Invalidate();
1535 mxXFootnoteSettings.clear();
1538 if(mxXEndnoteSettings.is())
1540 mxXEndnoteSettings->Invalidate();
1541 mxXEndnoteSettings.clear();
1544 if(mxXLineNumberingProperties.is())
1546 mxXLineNumberingProperties->Invalidate();
1547 mxXLineNumberingProperties.clear();
1549 if(mxXReferenceMarks.is())
1551 mxXReferenceMarks->Invalidate();
1552 mxXReferenceMarks.clear();
1554 if(mxLinkTargetSupplier.is())
1556 mxLinkTargetSupplier->Invalidate();
1557 mxLinkTargetSupplier.clear();
1559 if(mxXRedlines.is())
1561 mxXRedlines->Invalidate();
1562 mxXRedlines.clear();
1564 if(mxPropertyHelper.is())
1566 mxPropertyHelper->Invalidate();
1567 mxPropertyHelper.clear();
1571 css::uno::Reference<css::uno::XInterface> SwXTextDocument::create(
1572 OUString const & rServiceName,
1573 css::uno::Sequence<css::uno::Any> const * arguments)
1575 SolarMutexGuard aGuard;
1576 ThrowIfInvalid();
1578 const SwServiceType nType = SwXServiceProvider::GetProviderType(rServiceName);
1579 if (nType != SwServiceType::Invalid)
1581 return SwXServiceProvider::MakeInstance(nType, GetDocOrThrow());
1583 if (rServiceName == "com.sun.star.drawing.DashTable")
1585 return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Dash);
1587 if (rServiceName == "com.sun.star.drawing.GradientTable")
1589 return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Gradient);
1591 if (rServiceName == "com.sun.star.drawing.HatchTable")
1593 return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Hatch);
1595 if (rServiceName == "com.sun.star.drawing.BitmapTable")
1597 return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Bitmap);
1599 if (rServiceName == "com.sun.star.drawing.TransparencyGradientTable")
1601 return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::TransGradient);
1603 if (rServiceName == "com.sun.star.drawing.MarkerTable")
1605 return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Marker);
1607 if (rServiceName == "com.sun.star.drawing.Defaults")
1609 return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Defaults);
1611 if (rServiceName == "com.sun.star.document.Settings")
1613 return Reference<XInterface>(*new SwXDocumentSettings(this));
1615 if (rServiceName == "com.sun.star.document.ImportEmbeddedObjectResolver")
1617 return cppu::getXWeak(
1618 new SvXMLEmbeddedObjectHelper(
1619 *m_pDocShell, SvXMLEmbeddedObjectHelperMode::Read));
1621 if (rServiceName == "com.sun.star.text.DocumentSettings")
1623 return Reference<XInterface>(*new SwXDocumentSettings(this));
1625 if (rServiceName == "com.sun.star.chart2.data.DataProvider")
1627 return Reference<XInterface>(
1628 cppu::getXWeak(
1629 m_pDocShell->getIDocumentChartDataProviderAccess().
1630 GetChartDataProvider()));
1632 if (!rServiceName.startsWith("com.sun.star.")
1633 || rServiceName.endsWith(".OLE2Shape"))
1635 // We do not want to insert OLE2 Shapes (e.g.,
1636 // "com.sun.star.drawing.OLE2Shape", ...) like this (by creating them
1637 // with the documents factory and adding the shapes to the draw page);
1638 // for inserting OLE objects the proper way is to use
1639 // "com.sun.star.text.TextEmbeddedObject":
1640 throw ServiceNotRegisteredException();
1642 // The XML import is allowed to create instances of
1643 // "com.sun.star.drawing.OLE2Shape"; thus, a temporary service name is
1644 // introduced to make this possible:
1645 OUString aTmpServiceName(rServiceName);
1646 if (rServiceName == "com.sun.star.drawing.temporaryForXMLImportOLE2Shape")
1648 aTmpServiceName = "com.sun.star.drawing.OLE2Shape";
1650 Reference<XInterface> xTmp(
1651 arguments == nullptr
1652 ? SvxFmMSFactory::createInstance(aTmpServiceName)
1653 : SvxFmMSFactory::createInstanceWithArguments(
1654 aTmpServiceName, *arguments));
1655 if (rServiceName == "com.sun.star.drawing.GroupShape"
1656 || rServiceName == "com.sun.star.drawing.Shape3DSceneObject")
1658 return *new SwXGroupShape(xTmp, m_pDocShell->GetDoc());
1660 if (rServiceName.startsWith("com.sun.star.drawing."))
1662 return *new SwXShape(xTmp, m_pDocShell->GetDoc());
1664 return xTmp;
1667 rtl::Reference<SwXTextField> SwXTextDocument::createTextField(
1668 std::u16string_view rServiceName)
1670 SolarMutexGuard aGuard;
1671 ThrowIfInvalid();
1673 const SwServiceType nType = SwXServiceProvider::GetProviderType(rServiceName);
1674 assert(nType != SwServiceType::Invalid);
1675 uno::Reference<uno::XInterface> xTmp = SwXServiceProvider::MakeInstance(nType, GetDocOrThrow());
1676 rtl::Reference<SwXTextField> xTextField = dynamic_cast<SwXTextField*>(xTmp.get());
1677 assert(xTextField);
1678 return xTextField;
1681 rtl::Reference<SwXFieldmark> SwXTextDocument::createFieldmark(
1682 std::u16string_view rServiceName)
1684 SolarMutexGuard aGuard;
1685 ThrowIfInvalid();
1687 const SwServiceType nType = SwXServiceProvider::GetProviderType(rServiceName);
1688 assert(nType != SwServiceType::Invalid);
1689 uno::Reference<uno::XInterface> xTmp = SwXServiceProvider::MakeInstance(nType, GetDocOrThrow());
1690 rtl::Reference<SwXFieldmark> xTextField = dynamic_cast<SwXFieldmark*>(xTmp.get());
1691 assert(xTextField);
1692 return xTextField;
1695 rtl::Reference< SwXSection > SwXTextDocument::createSection(std::u16string_view rObjectType)
1697 SolarMutexGuard aGuard;
1698 ThrowIfInvalid();
1699 const SwServiceType nType = SwXServiceProvider::GetProviderType(rObjectType);
1700 assert(nType != SwServiceType::Invalid);
1701 auto xTmp = SwXServiceProvider::MakeInstance(nType, GetDocOrThrow());
1702 assert(!xTmp || dynamic_cast<SwXDocumentIndex*>(xTmp.get()) || dynamic_cast<SwXTextSection*>(xTmp.get()));
1703 return dynamic_cast<SwXSection*>(xTmp.get());
1706 rtl::Reference<SwXFieldMaster> SwXTextDocument::createFieldMaster(
1707 std::u16string_view rServiceName)
1709 SolarMutexGuard aGuard;
1710 ThrowIfInvalid();
1712 const SwServiceType nType = SwXServiceProvider::GetProviderType(rServiceName);
1713 assert(nType != SwServiceType::Invalid);
1714 uno::Reference<uno::XInterface> xTmp = SwXServiceProvider::MakeInstance(nType, GetDocOrThrow());
1715 rtl::Reference<SwXFieldMaster> xTextField = dynamic_cast<SwXFieldMaster*>(xTmp.get());
1716 assert(xTextField);
1717 return xTextField;
1720 rtl::Reference< SwXDocumentSettings > SwXTextDocument::createDocumentSettings()
1722 SolarMutexGuard aGuard;
1723 ThrowIfInvalid();
1724 return new SwXDocumentSettings(this);
1727 rtl::Reference< SwXTextDefaults > SwXTextDocument::createTextDefaults()
1729 SolarMutexGuard aGuard;
1730 ThrowIfInvalid();
1731 return new SwXTextDefaults(&GetDocOrThrow());
1734 rtl::Reference< SwXBookmark > SwXTextDocument::createBookmark()
1736 SolarMutexGuard aGuard;
1737 ThrowIfInvalid();
1738 return SwXBookmark::CreateXBookmark(GetDocOrThrow(), nullptr);
1741 rtl::Reference< SwXFieldmark > SwXTextDocument::createFieldmark()
1743 SolarMutexGuard aGuard;
1744 ThrowIfInvalid();
1745 return SwXFieldmark::CreateXFieldmark(GetDocOrThrow(), nullptr);
1748 rtl::Reference< SwXTextSection > SwXTextDocument::createTextSection()
1750 SolarMutexGuard aGuard;
1751 ThrowIfInvalid();
1752 return SwXTextSection::CreateXTextSection(nullptr, false);
1755 rtl::Reference< SwXTextField > SwXTextDocument::createFieldAnnotation()
1757 SolarMutexGuard aGuard;
1758 ThrowIfInvalid();
1759 return SwXTextField::CreateXTextField(&GetDocOrThrow(), nullptr, SwServiceType::FieldTypeAnnotation);
1762 rtl::Reference< SwXLineBreak > SwXTextDocument::createLineBreak()
1764 SolarMutexGuard aGuard;
1765 ThrowIfInvalid();
1766 return SwXLineBreak::CreateXLineBreak(nullptr);
1769 rtl::Reference< SwXTextFrame > SwXTextDocument::createTextFrame()
1771 SolarMutexGuard aGuard;
1772 ThrowIfInvalid();
1773 return SwXTextFrame::CreateXTextFrame(GetDocOrThrow(), nullptr);
1776 rtl::Reference< SwXTextGraphicObject > SwXTextDocument::createTextGraphicObject()
1778 SolarMutexGuard aGuard;
1779 ThrowIfInvalid();
1780 return SwXTextGraphicObject::CreateXTextGraphicObject(GetDocOrThrow(), nullptr);
1783 rtl::Reference< SwXStyle > SwXTextDocument::createNumberingStyle()
1785 SolarMutexGuard aGuard;
1786 ThrowIfInvalid();
1787 return SwXStyleFamilies::CreateStyleCharOrParaOrPseudo(SfxStyleFamily::Pseudo, GetDocOrThrow());
1790 rtl::Reference< SwXStyle > SwXTextDocument::createCharacterStyle()
1792 SolarMutexGuard aGuard;
1793 ThrowIfInvalid();
1794 return SwXStyleFamilies::CreateStyleCharOrParaOrPseudo(SfxStyleFamily::Char, GetDocOrThrow());
1797 rtl::Reference< SwXStyle > SwXTextDocument::createParagraphStyle()
1799 SolarMutexGuard aGuard;
1800 ThrowIfInvalid();
1801 return SwXStyleFamilies::CreateStyleCharOrParaOrPseudo(SfxStyleFamily::Para, GetDocOrThrow());
1804 rtl::Reference< SwXPageStyle > SwXTextDocument::createPageStyle()
1806 SolarMutexGuard aGuard;
1807 ThrowIfInvalid();
1808 return SwXStyleFamilies::CreateStylePage(GetDocOrThrow());
1811 rtl::Reference< SwXContentControl > SwXTextDocument::createContentControl()
1813 SolarMutexGuard aGuard;
1814 ThrowIfInvalid();
1815 return SwXContentControl::CreateXContentControl(GetDocOrThrow());
1818 rtl::Reference< SwXFootnote > SwXTextDocument::createFootnote()
1820 SolarMutexGuard aGuard;
1821 ThrowIfInvalid();
1822 return SwXFootnote::CreateXFootnote(GetDocOrThrow(), nullptr);
1825 rtl::Reference< SwXFootnote > SwXTextDocument::createEndnote()
1827 SolarMutexGuard aGuard;
1828 ThrowIfInvalid();
1829 return SwXFootnote::CreateXFootnote(GetDocOrThrow(), nullptr, true);
1832 rtl::Reference< SwXTextEmbeddedObject > SwXTextDocument::createTextEmbeddedObject()
1834 SolarMutexGuard aGuard;
1835 ThrowIfInvalid();
1836 return SwXTextEmbeddedObject::CreateXTextEmbeddedObject(GetDocOrThrow(), nullptr);
1839 rtl::Reference< SvXMLEmbeddedObjectHelper > SwXTextDocument::createEmbeddedObjectResolver()
1841 SolarMutexGuard aGuard;
1842 ThrowIfInvalid();
1843 return new SvXMLEmbeddedObjectHelper(*m_pDocShell, SvXMLEmbeddedObjectHelperMode::Read);
1846 Reference< XInterface > SwXTextDocument::createInstance(const OUString& rServiceName)
1848 return create(rServiceName, nullptr);
1851 Reference< XInterface > SwXTextDocument::createInstanceWithArguments(
1852 const OUString& ServiceSpecifier,
1853 const Sequence< Any >& Arguments)
1855 return create(ServiceSpecifier, &Arguments);
1858 Sequence< OUString > SwXTextDocument::getAvailableServiceNames()
1860 static Sequence< OUString > aServices;
1861 if ( !aServices.hasElements() )
1863 Sequence< OUString > aRet = SvxFmMSFactory::getAvailableServiceNames();
1864 auto i = comphelper::findValue(aRet, "com.sun.star.drawing.OLE2Shape");
1865 if (i != -1)
1867 auto nLength = aRet.getLength();
1868 aRet.getArray()[i] = aRet[nLength - 1];
1869 aRet.realloc( nLength - 1 );
1871 Sequence< OUString > aOwn = SwXServiceProvider::GetAllServiceNames();
1872 aServices = comphelper::concatSequences(aRet, aOwn);
1875 return aServices;
1878 OUString SwXTextDocument::getImplementationName()
1880 return u"SwXTextDocument"_ustr;
1881 /* // Matching the .component information:
1882 return dynamic_cast<SwGlobalDocShell*>( pDocShell ) != nullptr
1883 ? OUString("com.sun.star.comp.Writer.GlobalDocument")
1884 : dynamic_cast<SwWebDocShell*>( pDocShell ) != nullptr
1885 ? OUString("com.sun.star.comp.Writer.WebDocument")
1886 : OUString("com.sun.star.comp.Writer.TextDocument");
1890 sal_Bool SwXTextDocument::supportsService(const OUString& rServiceName)
1892 return cppu::supportsService(this, rServiceName);
1895 Sequence< OUString > SwXTextDocument::getSupportedServiceNames()
1897 bool bWebDoc = (dynamic_cast<SwWebDocShell*>( m_pDocShell) != nullptr );
1898 bool bGlobalDoc = (dynamic_cast<SwGlobalDocShell*>( m_pDocShell) != nullptr );
1899 bool bTextDoc = (!bWebDoc && !bGlobalDoc);
1901 Sequence< OUString > aRet (3);
1902 OUString* pArray = aRet.getArray();
1904 pArray[0] = "com.sun.star.document.OfficeDocument";
1905 pArray[1] = "com.sun.star.text.GenericTextDocument";
1907 if (bTextDoc)
1908 pArray[2] = "com.sun.star.text.TextDocument";
1909 else if (bWebDoc)
1910 pArray[2] = "com.sun.star.text.WebDocument";
1911 else if (bGlobalDoc)
1912 pArray[2] = "com.sun.star.text.GlobalDocument";
1914 return aRet;
1917 Reference< XIndexAccess > SwXTextDocument::getDocumentIndexes()
1919 return getSwDocumentIndexes();
1922 rtl::Reference< SwXDocumentIndexes > SwXTextDocument::getSwDocumentIndexes()
1924 SolarMutexGuard aGuard;
1925 ThrowIfInvalid();
1927 if(!mxXDocumentIndexes.is())
1929 mxXDocumentIndexes = new SwXDocumentIndexes(m_pDocShell->GetDoc());
1931 return mxXDocumentIndexes;
1934 Reference< XPropertySetInfo > SwXTextDocument::getPropertySetInfo()
1936 static Reference< XPropertySetInfo > xRet = m_pPropSet->getPropertySetInfo();
1937 return xRet;
1940 void SwXTextDocument::setPropertyValue(const OUString& rPropertyName, const Any& aValue)
1942 SolarMutexGuard aGuard;
1943 ThrowIfInvalid();
1945 const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName);
1947 if(!pEntry)
1948 throw UnknownPropertyException(rPropertyName);
1949 if(pEntry->nFlags & PropertyAttribute::READONLY)
1950 throw PropertyVetoException();
1951 switch(pEntry->nWID)
1953 case WID_DOC_CHAR_COUNT :
1954 case WID_DOC_PARA_COUNT :
1955 case WID_DOC_WORD_COUNT :
1956 throw RuntimeException(
1957 u"bad WID"_ustr,
1958 getXWeak());
1959 case WID_DOC_WORD_SEPARATOR :
1961 OUString sDelim;
1962 aValue >>= sDelim;
1963 SwModule::get()->GetModuleConfig()->SetWordDelimiter(sDelim);
1965 break;
1966 case WID_DOC_CHANGES_RECORD:
1967 case WID_DOC_CHANGES_SHOW:
1969 SwDoc& rDoc = GetDocOrThrow();
1970 sw::DocumentRedlineManager& rRedlineManager = rDoc.GetDocumentRedlineManager();
1971 bool bSet = *o3tl::doAccess<bool>(aValue);
1972 RedlineFlags eMode = rRedlineManager.GetRedlineFlags();
1973 if(WID_DOC_CHANGES_SHOW == pEntry->nWID)
1975 eMode |= RedlineFlags(RedlineFlags::ShowInsert | RedlineFlags::ShowDelete);
1976 if( !bSet )
1977 rRedlineManager.SetHideRedlines(true);
1979 else if(WID_DOC_CHANGES_RECORD == pEntry->nWID)
1981 eMode = bSet ? eMode|RedlineFlags::On : eMode&~RedlineFlags::On;
1983 rRedlineManager.SetRedlineFlags(eMode);
1985 break;
1986 case WID_DOC_CHANGES_PASSWORD:
1988 Sequence <sal_Int8> aNew;
1989 if(aValue >>= aNew)
1991 auto& rRedlineAccess = GetDocOrThrow().getIDocumentRedlineAccess();
1992 rRedlineAccess.SetRedlinePassword(aNew);
1993 if(aNew.hasElements())
1995 RedlineFlags eMode = rRedlineAccess.GetRedlineFlags();
1996 eMode |= RedlineFlags::On;
1997 rRedlineAccess.SetRedlineFlags(eMode);
2001 break;
2002 case WID_DOC_AUTO_MARK_URL :
2004 OUString sURL;
2005 aValue >>= sURL;
2006 GetDocOrThrow().SetTOIAutoMarkURL(sURL);
2008 break;
2009 case WID_DOC_HIDE_TIPS :
2010 SwModule::get()->GetModuleConfig()->SetHideFieldTips(*o3tl::doAccess<bool>(aValue));
2011 break;
2012 case WID_DOC_REDLINE_DISPLAY:
2014 auto& rRedlineAccess = GetDocOrThrow().getIDocumentRedlineAccess();
2015 RedlineFlags eRedMode = rRedlineAccess.GetRedlineFlags();
2016 eRedMode = eRedMode & (~RedlineFlags::ShowMask);
2017 sal_Int16 nSet = 0;
2018 aValue >>= nSet;
2019 switch(nSet)
2021 case RedlineDisplayType::NONE: break;
2022 case RedlineDisplayType::INSERTED: eRedMode |= RedlineFlags::ShowInsert; break;
2023 case RedlineDisplayType::REMOVED: eRedMode |= RedlineFlags::ShowDelete; break;
2024 case RedlineDisplayType::
2025 INSERTED_AND_REMOVED: eRedMode |= RedlineFlags::ShowInsert|RedlineFlags::ShowDelete;
2026 break;
2027 default: throw IllegalArgumentException();
2029 rRedlineAccess.SetRedlineFlags(eRedMode);
2031 break;
2032 case WID_DOC_TWO_DIGIT_YEAR:
2034 sal_Int16 nYear = 0;
2035 aValue >>= nYear;
2036 SfxRequest aRequest ( SID_ATTR_YEAR2000, SfxCallMode::SLOT, GetDocOrThrow().GetAttrPool());
2037 aRequest.AppendItem(SfxUInt16Item( SID_ATTR_YEAR2000, static_cast < sal_uInt16 > ( nYear ) ) );
2038 m_pDocShell->Execute ( aRequest );
2040 break;
2041 case WID_DOC_AUTOMATIC_CONTROL_FOCUS:
2043 auto& rDrawModelAccess = GetDocOrThrow().getIDocumentDrawModelAccess();
2044 bool bAuto = *o3tl::doAccess<bool>(aValue);
2045 // if setting to true, and we don't have an
2046 // SdrModel, then we are changing the default and
2047 // must thus create an SdrModel, if we don't have an
2048 // SdrModel and we are leaving the default at false,
2049 // we don't need to make an SdrModel and can do nothing
2050 // #i52858# - method name changed
2051 SwDrawModel* pDrawDoc
2052 = bAuto ? &rDrawModelAccess.GetOrCreateDrawModel() : rDrawModelAccess.GetDrawModel();
2054 if ( nullptr != pDrawDoc )
2055 pDrawDoc->SetAutoControlFocus( bAuto );
2057 break;
2058 case WID_DOC_APPLY_FORM_DESIGN_MODE:
2060 auto& rDrawModelAccess = GetDocOrThrow().getIDocumentDrawModelAccess();
2061 bool bMode = *o3tl::doAccess<bool>(aValue);
2062 // if setting to false, and we don't have an
2063 // SdrModel, then we are changing the default and
2064 // must thus create an SdrModel, if we don't have an
2065 // SdrModel and we are leaving the default at true,
2066 // we don't need to make an SdrModel and can do
2067 // nothing
2068 // #i52858# - method name changed
2069 SwDrawModel* pDrawDoc
2070 = bMode ? rDrawModelAccess.GetDrawModel() : &rDrawModelAccess.GetOrCreateDrawModel();
2072 if ( nullptr != pDrawDoc )
2073 pDrawDoc->SetOpenInDesignMode( bMode );
2075 break;
2076 // #i42634# New property to set the bInReading
2077 // flag at the document, used during binary import
2078 case WID_DOC_LOCK_UPDATES :
2080 bool bBool (false);
2081 if( aValue >>= bBool )
2083 GetDocOrThrow().SetInReading( bBool );
2086 break;
2087 case WID_DOC_WRITERFILTER:
2089 SwDoc& rDoc = GetDocOrThrow();
2090 bool bBool = {};
2091 if (aValue >>= bBool)
2092 { // HACK: writerfilter has to use API to set this :(
2093 bool bOld = rDoc.IsInWriterfilterImport();
2094 rDoc.SetInWriterfilterImport(bBool);
2095 if (bOld && !bBool)
2097 rDoc.getIDocumentFieldsAccess().SetFieldsDirty(false, nullptr, SwNodeOffset(0));
2101 break;
2102 case WID_DOC_BUILDID:
2103 aValue >>= maBuildId;
2104 break;
2106 case WID_DOC_DEFAULT_PAGE_MODE:
2108 bool bDefaultPageMode( false );
2109 aValue >>= bDefaultPageMode;
2110 GetDocOrThrow().SetDefaultPageMode( bDefaultPageMode );
2112 break;
2113 case WID_DOC_INTEROP_GRAB_BAG:
2114 setGrabBagItem(aValue);
2115 break;
2117 default:
2119 SwDoc& rDoc = GetDocOrThrow();
2120 const SfxPoolItem& rItem = rDoc.GetDefault(pEntry->nWID);
2121 std::unique_ptr<SfxPoolItem> pNewItem(rItem.Clone());
2122 pNewItem->PutValue(aValue, pEntry->nMemberId);
2123 rDoc.SetDefault(*pNewItem);
2128 Any SwXTextDocument::getPropertyValue(const OUString& rPropertyName)
2130 SolarMutexGuard aGuard;
2131 ThrowIfInvalid();
2133 if (rPropertyName == "ODFExport_ListNodes")
2135 // A hack to avoid writing random list ids to ODF when they are not referred later
2136 // see XMLTextParagraphExport::DocumentListNodes ctor
2138 // Sequence of nodes, each of them represented by three-element sequence:
2139 // [ index, styleIntPtr, list_id ]
2140 std::vector<css::uno::Sequence<css::uno::Any>> nodes;
2142 const SwDoc& rDoc = GetDocOrThrow();
2143 for (const SwNumRule* pNumRule : rDoc.GetNumRuleTable())
2145 SwNumRule::tTextNodeList textNodes;
2146 pNumRule->GetTextNodeList(textNodes);
2147 css::uno::Any styleIntPtr(reinterpret_cast<sal_uInt64>(pNumRule));
2149 for (const SwTextNode* pTextNode : textNodes)
2151 css::uno::Any index(pTextNode->GetIndex().get());
2152 css::uno::Any list_id(pTextNode->GetListId());
2154 nodes.push_back({ index, styleIntPtr, list_id });
2157 return css::uno::Any(comphelper::containerToSequence(nodes));
2160 const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName);
2162 if(!pEntry)
2163 throw UnknownPropertyException(rPropertyName);
2164 Any aAny;
2165 switch(pEntry->nWID)
2167 case WID_DOC_ISTEMPLATEID :
2168 aAny <<= m_pDocShell->IsTemplate();
2169 break;
2170 case WID_DOC_CHAR_COUNT :
2171 case WID_DOC_PARA_COUNT :
2172 case WID_DOC_WORD_COUNT :
2174 const SwDocStat& rStat(GetDocOrThrow().getIDocumentStatistics().GetUpdatedDocStat( false, true ));
2175 sal_Int32 nValue;
2176 switch(pEntry->nWID)
2178 case WID_DOC_CHAR_COUNT :nValue = rStat.nChar;break;
2179 case WID_DOC_PARA_COUNT :nValue = rStat.nPara;break;
2180 case WID_DOC_WORD_COUNT :nValue = rStat.nWord;break;
2182 aAny <<= nValue;
2184 break;
2185 case WID_DOC_WORD_SEPARATOR :
2186 aAny <<= SwModule::get()->GetDocStatWordDelim();
2187 break;
2188 case WID_DOC_CHANGES_RECORD:
2189 case WID_DOC_CHANGES_SHOW:
2191 const RedlineFlags eMode = GetDocOrThrow().getIDocumentRedlineAccess().GetRedlineFlags();
2192 bool bSet = false;
2193 if(WID_DOC_CHANGES_SHOW == pEntry->nWID)
2195 bSet = IDocumentRedlineAccess::IsShowChanges(eMode);
2197 else if(WID_DOC_CHANGES_RECORD == pEntry->nWID)
2199 bSet = bool(eMode & RedlineFlags::On);
2201 aAny <<= bSet;
2203 break;
2204 case WID_DOC_CHANGES_PASSWORD:
2205 aAny <<= GetDocOrThrow().getIDocumentRedlineAccess().GetRedlinePassword();
2206 break;
2207 case WID_DOC_AUTO_MARK_URL :
2208 aAny <<= GetDocOrThrow().GetTOIAutoMarkURL();
2209 break;
2210 case WID_DOC_HIDE_TIPS :
2211 aAny <<= SwModule::get()->GetModuleConfig()->IsHideFieldTips();
2212 break;
2213 case WID_DOC_REDLINE_DISPLAY:
2215 RedlineFlags eRedMode = GetDocOrThrow().getIDocumentRedlineAccess().GetRedlineFlags();
2216 eRedMode = eRedMode & RedlineFlags::ShowMask;
2217 sal_Int16 nRet = RedlineDisplayType::NONE;
2218 if(RedlineFlags::ShowInsert == eRedMode)
2219 nRet = RedlineDisplayType::INSERTED;
2220 else if(RedlineFlags::ShowDelete == eRedMode)
2221 nRet = RedlineDisplayType::REMOVED;
2222 else if(RedlineFlags::ShowMask == eRedMode)
2223 nRet = RedlineDisplayType::INSERTED_AND_REMOVED;
2224 aAny <<= nRet;
2226 break;
2227 case WID_DOC_FORBIDDEN_CHARS:
2229 GetPropertyHelper();
2230 Reference<XForbiddenCharacters> xRet = mxPropertyHelper;
2231 aAny <<= xRet;
2233 break;
2234 case WID_DOC_TWO_DIGIT_YEAR:
2236 aAny <<= static_cast < sal_Int16 > (GetDocOrThrow().GetNumberFormatter ()->GetYear2000());
2238 break;
2239 case WID_DOC_AUTOMATIC_CONTROL_FOCUS:
2241 SwDrawModel * pDrawDoc = GetDocOrThrow().getIDocumentDrawModelAccess().GetDrawModel();
2242 bool bAuto;
2243 if ( nullptr != pDrawDoc )
2244 bAuto = pDrawDoc->GetAutoControlFocus();
2245 else
2246 bAuto = false;
2247 aAny <<= bAuto;
2249 break;
2250 case WID_DOC_APPLY_FORM_DESIGN_MODE:
2252 SwDrawModel * pDrawDoc = GetDocOrThrow().getIDocumentDrawModelAccess().GetDrawModel();
2253 bool bMode;
2254 if ( nullptr != pDrawDoc )
2255 bMode = pDrawDoc->GetOpenInDesignMode();
2256 else
2257 bMode = true;
2258 aAny <<= bMode;
2260 break;
2261 case WID_DOC_BASIC_LIBRARIES:
2262 aAny <<= m_pDocShell->GetBasicContainer();
2263 break;
2264 case WID_DOC_DIALOG_LIBRARIES:
2265 aAny <<= m_pDocShell->GetDialogContainer();
2266 break;
2267 case WID_DOC_VBA_DOCOBJ:
2269 /* #i111553# This property provides the name of the constant that
2270 will be used to store this model in the global Basic manager.
2271 That constant will be equivalent to 'ThisComponent' but for
2272 each application, so e.g. a 'ThisExcelDoc' and a 'ThisWordDoc'
2273 constant can co-exist, as required by VBA. */
2274 aAny <<= u"ThisWordDoc"_ustr;
2276 break;
2277 case WID_DOC_RUNTIME_UID:
2278 aAny <<= getRuntimeUID();
2279 break;
2280 case WID_DOC_LOCK_UPDATES :
2281 aAny <<= GetDocOrThrow().IsInReading();
2282 break;
2283 case WID_DOC_BUILDID:
2284 aAny <<= maBuildId;
2285 break;
2286 case WID_DOC_HAS_VALID_SIGNATURES:
2287 aAny <<= hasValidSignatures();
2288 break;
2289 case WID_DOC_INTEROP_GRAB_BAG:
2290 getGrabBagItem(aAny);
2291 break;
2292 case WID_DOC_ALLOW_LINK_UPDATE:
2294 comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = m_pDocShell->getEmbeddedObjectContainer();
2295 aAny <<= rEmbeddedObjectContainer.getUserAllowsLinkUpdate();
2297 break;
2299 default:
2301 const SfxPoolItem& rItem = GetDocOrThrow().GetDefault(pEntry->nWID);
2302 rItem.QueryValue(aAny, pEntry->nMemberId);
2305 return aAny;
2308 void SwXTextDocument::addPropertyChangeListener(const OUString& /*PropertyName*/,
2309 const Reference< XPropertyChangeListener > & /*aListener*/)
2311 OSL_FAIL("not implemented");
2314 void SwXTextDocument::removePropertyChangeListener(const OUString& /*PropertyName*/,
2315 const Reference< XPropertyChangeListener > & /*aListener*/)
2317 OSL_FAIL("not implemented");
2320 void SwXTextDocument::addVetoableChangeListener(const OUString& /*PropertyName*/,
2321 const Reference< XVetoableChangeListener > & /*aListener*/)
2323 OSL_FAIL("not implemented");
2326 void SwXTextDocument::removeVetoableChangeListener(const OUString& /*PropertyName*/,
2327 const Reference< XVetoableChangeListener > & /*aListener*/)
2329 OSL_FAIL("not implemented");
2332 Reference< XNameAccess > SwXTextDocument::getLinks()
2334 if(!mxLinkTargetSupplier.is())
2336 mxLinkTargetSupplier = new SwXLinkTargetSupplier(*this);
2338 return mxLinkTargetSupplier;
2341 Reference< XEnumerationAccess > SwXTextDocument::getRedlines( )
2343 return getSwRedlines();
2346 rtl::Reference< SwXRedlines > SwXTextDocument::getSwRedlines( )
2348 if(!mxXRedlines.is())
2350 mxXRedlines = new SwXRedlines(m_pDocShell->GetDoc());
2352 return mxXRedlines;
2355 void SwXTextDocument::NotifyRefreshListeners()
2357 // why does SwBaseShell not just call refresh? maybe because it's rSh is
2358 // (sometimes) a different shell than GetWrtShell()?
2359 lang::EventObject const ev(getXWeak());
2360 std::unique_lock aGuard(m_pImpl->m_Mutex);
2361 m_pImpl->m_RefreshListeners.notifyEach(aGuard,
2362 & util::XRefreshListener::refreshed, ev);
2365 void SwXTextDocument::refresh()
2367 SolarMutexGuard aGuard;
2368 ThrowIfInvalid();
2370 SwViewShell *pViewShell = m_pDocShell->GetWrtShell();
2371 NotifyRefreshListeners();
2372 if(pViewShell)
2373 pViewShell->Reformat();
2376 void SAL_CALL SwXTextDocument::addRefreshListener(
2377 const Reference<util::XRefreshListener> & xListener)
2379 if (xListener)
2381 std::unique_lock aGuard(m_pImpl->m_Mutex);
2382 m_pImpl->m_RefreshListeners.addInterface(aGuard, xListener);
2386 void SAL_CALL SwXTextDocument::removeRefreshListener(
2387 const Reference<util::XRefreshListener> & xListener)
2389 if (xListener)
2391 std::unique_lock aGuard(m_pImpl->m_Mutex);
2392 m_pImpl->m_RefreshListeners.removeInterface(aGuard, xListener);
2396 void SwXTextDocument::updateLinks( )
2398 SolarMutexGuard aGuard;
2399 ThrowIfInvalid();
2401 SwDoc& rDoc = GetDocOrThrow();
2402 sfx2::LinkManager& rLnkMan = rDoc.getIDocumentLinksAdministration().GetLinkManager();
2403 if( !rLnkMan.GetLinks().empty() )
2405 UnoActionContext aAction(&rDoc);
2406 rLnkMan.UpdateAllLinks( false, true, nullptr, u""_ustr );
2410 //XPropertyState
2411 PropertyState SAL_CALL SwXTextDocument::getPropertyState( const OUString& rPropertyName )
2413 SolarMutexGuard aGuard;
2414 ThrowIfInvalid();
2416 const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName);
2417 if(!pEntry)
2418 throw UnknownPropertyException(rPropertyName);
2419 return PropertyState_DIRECT_VALUE;
2422 Sequence< PropertyState > SAL_CALL SwXTextDocument::getPropertyStates( const Sequence< OUString >& rPropertyNames )
2424 const sal_Int32 nCount = rPropertyNames.getLength();
2425 Sequence < PropertyState > aRet ( nCount );
2427 std::transform(rPropertyNames.begin(), rPropertyNames.end(), aRet.getArray(),
2428 [this](const OUString& rName) -> PropertyState { return getPropertyState(rName); });
2430 return aRet;
2433 void SAL_CALL SwXTextDocument::setPropertyToDefault( const OUString& rPropertyName )
2435 SolarMutexGuard aGuard;
2436 ThrowIfInvalid();
2438 const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName);
2439 if(!pEntry)
2440 throw UnknownPropertyException(rPropertyName);
2441 switch(pEntry->nWID)
2443 case 0:default:break;
2447 Any SAL_CALL SwXTextDocument::getPropertyDefault( const OUString& rPropertyName )
2449 SolarMutexGuard aGuard;
2450 ThrowIfInvalid();
2452 const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName);
2453 if(!pEntry)
2454 throw UnknownPropertyException(rPropertyName);
2455 Any aAny;
2456 switch(pEntry->nWID)
2458 case 0:default:break;
2460 return aAny;
2463 static VclPtr< OutputDevice > lcl_GetOutputDevice( const SwPrintUIOptions &rPrintUIOptions )
2465 VclPtr< OutputDevice > pOut;
2467 uno::Any aAny( rPrintUIOptions.getValue( u"RenderDevice"_ustr ));
2468 uno::Reference< awt::XDevice > xRenderDevice;
2469 aAny >>= xRenderDevice;
2470 if (xRenderDevice.is())
2472 VCLXDevice* pDevice = dynamic_cast<VCLXDevice*>( xRenderDevice.get() );
2473 pOut = pDevice ? pDevice->GetOutputDevice() : VclPtr< OutputDevice >();
2476 return pOut;
2479 static bool lcl_SeqHasProperty(
2480 const uno::Sequence< beans::PropertyValue >& rOptions,
2481 const char *pPropName )
2483 return std::any_of(rOptions.begin(), rOptions.end(),
2484 [&pPropName](const beans::PropertyValue& rProp) {
2485 return rProp.Name.equalsAscii( pPropName ); });
2488 static bool lcl_GetBoolProperty(
2489 const uno::Sequence< beans::PropertyValue >& rOptions,
2490 const char *pPropName )
2492 bool bRes = false;
2493 auto pOption = std::find_if(rOptions.begin(), rOptions.end(),
2494 [&pPropName](const beans::PropertyValue& rProp) {
2495 return rProp.Name.equalsAscii( pPropName ); });
2496 if (pOption != rOptions.end())
2497 pOption->Value >>= bRes;
2498 return bRes;
2501 SfxViewShell * SwXTextDocument::GetRenderView(
2502 bool &rbIsSwSrcView,
2503 const uno::Sequence< beans::PropertyValue >& rOptions,
2504 bool bIsPDFExport )
2506 // get view shell to use
2507 SfxViewShell *pView = nullptr;
2508 if (bIsPDFExport)
2509 pView = GuessViewShell( rbIsSwSrcView );
2510 else
2512 uno::Any aTmp;
2513 auto pOption = std::find_if(rOptions.begin(), rOptions.end(),
2514 [](const beans::PropertyValue& rProp) { return rProp.Name == "View"; });
2515 if (pOption != rOptions.end())
2516 aTmp = pOption->Value;
2518 uno::Reference< frame::XController > xController;
2519 if (aTmp >>= xController)
2521 OSL_ENSURE( xController.is(), "controller is empty!" );
2522 pView = GuessViewShell( rbIsSwSrcView, xController );
2525 return pView;
2529 * GetRenderDoc:
2530 * returns the document to be rendered, usually this will be the 'regular'
2531 * document but in case of PDF export of (multi-)selection it will
2532 * be a temporary document that gets created if not already done.
2533 * The rpView variable will be set (if not already done) to the used
2534 * SfxViewShell.
2536 SwDoc * SwXTextDocument::GetRenderDoc(
2537 SfxViewShell *&rpView,
2538 const uno::Any& rSelection,
2539 bool bIsPDFExport )
2541 SwDoc *pDoc = nullptr;
2543 uno::Reference< frame::XModel > xModel;
2544 rSelection >>= xModel;
2545 if (xModel == m_pDocShell->GetModel())
2546 pDoc = m_pDocShell->GetDoc();
2547 else
2549 OSL_ENSURE( !xModel.is(), "unexpected model found" );
2551 if (rSelection.hasValue()) // is anything selected ?
2553 // this part should only be called when a temporary document needs to be created,
2554 // for example for PDF export or printing of (multi-)selection only.
2556 if (!rpView)
2558 bool bIsSwSrcView = false;
2559 // aside from maybe PDF export the view should always have been provided!
2560 OSL_ENSURE( bIsPDFExport, "view is missing, guessing one..." );
2562 rpView = GuessViewShell( bIsSwSrcView );
2564 OSL_ENSURE( rpView, "SwViewShell missing" );
2565 // the view shell should be SwView for documents PDF export.
2566 // for the page preview no selection should be possible
2567 // (the export dialog does not allow for this option)
2568 if (auto pSwView = dynamic_cast<SwView *>( rpView ))
2570 if (!m_pRenderData)
2572 OSL_FAIL("GetRenderDoc: no renderdata");
2573 return nullptr;
2575 SfxObjectShellLock xDocSh(m_pRenderData->GetTempDocShell());
2576 if (!xDocSh.Is())
2578 xDocSh = pSwView->CreateTmpSelectionDoc();
2579 m_pRenderData->SetTempDocShell(xDocSh);
2581 if (xDocSh.Is())
2583 pDoc = static_cast<SwDocShell*>(&xDocSh)->GetDoc();
2584 rpView = pDoc->GetDocShell()->GetView();
2587 else
2589 OSL_FAIL("unexpected SwViewShell" );
2593 return pDoc;
2596 static void lcl_SavePrintUIOptionsToDocumentPrintData(
2597 SwDoc &rDoc,
2598 const SwPrintUIOptions &rPrintUIOptions,
2599 bool bIsPDFEXport )
2601 SwPrintData aDocPrintData( rDoc.getIDocumentDeviceAccess().getPrintData() );
2603 aDocPrintData.SetPrintGraphic( rPrintUIOptions.IsPrintGraphics() );
2604 aDocPrintData.SetPrintControl( rPrintUIOptions.IsPrintFormControls() );
2605 aDocPrintData.SetPrintLeftPage( rPrintUIOptions.IsPrintLeftPages() );
2606 aDocPrintData.SetPrintRightPage( rPrintUIOptions.IsPrintRightPages() );
2607 aDocPrintData.SetPaperFromSetup( rPrintUIOptions.IsPaperFromSetup() );
2608 aDocPrintData.SetPrintEmptyPages( rPrintUIOptions.IsPrintEmptyPages( bIsPDFEXport ) );
2609 aDocPrintData.SetPrintPostIts( rPrintUIOptions.GetPrintPostItsType() );
2610 aDocPrintData.SetPrintProspect( rPrintUIOptions.IsPrintProspect() );
2611 aDocPrintData.SetPrintProspect_RTL( rPrintUIOptions.IsPrintProspectRTL() );
2612 aDocPrintData.SetPrintPageBackground( rPrintUIOptions.IsPrintPageBackground() );
2613 aDocPrintData.SetPrintBlackFont( rPrintUIOptions.IsPrintWithBlackTextColor() );
2614 // arDocPrintData.SetFaxName( s ); n/a in File/Print dialog
2615 aDocPrintData.SetPrintHiddenText( rPrintUIOptions.IsPrintHiddenText() );
2616 aDocPrintData.SetPrintTextPlaceholder( rPrintUIOptions.IsPrintTextPlaceholders() );
2618 rDoc.getIDocumentDeviceAccess().setPrintData( aDocPrintData );
2621 sal_Int32 SAL_CALL SwXTextDocument::getRendererCount(
2622 const uno::Any& rSelection,
2623 const uno::Sequence< beans::PropertyValue >& rxOptions )
2625 SolarMutexGuard aGuard;
2626 ThrowIfInvalid();
2628 const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" );
2629 bool bIsSwSrcView = false;
2630 SfxViewShell *pView = GetRenderView( bIsSwSrcView, rxOptions, bIsPDFExport );
2632 if (!bIsSwSrcView && !m_pRenderData)
2633 m_pRenderData.reset(new SwRenderData);
2634 if (!m_pPrintUIOptions)
2635 m_pPrintUIOptions = lcl_GetPrintUIOptions( m_pDocShell, pView );
2636 bool bFormat = m_pPrintUIOptions->processPropertiesAndCheckFormat( rxOptions );
2638 SwDoc *pDoc = GetRenderDoc( pView, rSelection, bIsPDFExport );
2639 OSL_ENSURE( pDoc && pView, "doc or view shell missing!" );
2640 if (!pDoc || !pView)
2641 return 0;
2643 // save current UI options from the print dialog for the next call to that dialog
2644 lcl_SavePrintUIOptionsToDocumentPrintData( *pDoc, *m_pPrintUIOptions, bIsPDFExport );
2646 sal_Int32 nRet = 0;
2647 if (bIsSwSrcView)
2649 SwSrcView& rSwSrcView = dynamic_cast<SwSrcView&>(*pView);
2650 VclPtr< OutputDevice> pOutDev = lcl_GetOutputDevice( *m_pPrintUIOptions );
2651 nRet = rSwSrcView.PrintSource( pOutDev, 1 /* dummy */, true /* get page count only */ );
2653 else
2655 SwDocShell *pRenderDocShell = pDoc->GetDocShell();
2657 // TODO/mba: we really need a generic way to get the SwViewShell!
2658 SwViewShell* pViewShell = nullptr;
2659 SwView* pSwView = dynamic_cast<SwView*>( pView );
2660 if ( pSwView )
2662 pViewShell = pSwView->GetWrtShellPtr();
2664 else
2666 if ( bIsPDFExport && bFormat )
2668 //create a hidden view to be able to export as PDF also in print preview
2669 //pView and pSwView are not changed intentionally!
2670 m_pHiddenViewFrame = SfxViewFrame::LoadHiddenDocument( *pRenderDocShell, SFX_INTERFACE_SFXDOCSH );
2671 pViewShell = static_cast<SwView*>(m_pHiddenViewFrame->GetViewShell())->GetWrtShellPtr();
2673 else
2674 pViewShell = static_cast<SwPagePreview*>(pView)->GetViewShell();
2677 if (!pViewShell || !pViewShell->GetLayout())
2678 return 0;
2680 if (bFormat)
2682 // #i38289
2683 if( pViewShell->GetViewOptions()->getBrowseMode() ||
2684 pViewShell->GetViewOptions()->IsWhitespaceHidden() )
2686 SwViewOption aOpt( *pViewShell->GetViewOptions() );
2687 aOpt.setBrowseMode( false );
2688 aOpt.SetHideWhitespaceMode( false );
2689 pViewShell->ApplyViewOptions( aOpt );
2690 if (pSwView)
2692 pSwView->RecheckBrowseMode();
2696 // reformatting the document for printing will show the changes in the view
2697 // which is likely to produce many unwanted and not nice to view actions.
2698 // We don't want that! Thus we disable updating of the view.
2699 pViewShell->StartAction();
2701 if (pSwView)
2703 if (m_pRenderData && m_pRenderData->NeedNewViewOptionAdjust( *pViewShell ) )
2704 m_pRenderData->ViewOptionAdjustStop();
2705 if (m_pRenderData && !m_pRenderData->IsViewOptionAdjust())
2707 m_pRenderData->ViewOptionAdjustStart(
2708 *pViewShell, *pViewShell->GetViewOptions() );
2712 m_pRenderData->MakeSwPrtOptions( pRenderDocShell,
2713 m_pPrintUIOptions.get(), bIsPDFExport );
2715 if (pSwView)
2717 // PDF export should not make use of the SwPrtOptions
2718 const SwPrintData *pPrtOptions = bIsPDFExport
2719 ? nullptr : m_pRenderData->GetSwPrtOptions();
2720 bool setShowPlaceHoldersInPDF = false;
2721 if(bIsPDFExport)
2722 setShowPlaceHoldersInPDF = lcl_GetBoolProperty( rxOptions, "ExportPlaceholders" );
2723 m_pRenderData->ViewOptionAdjust( pPrtOptions, setShowPlaceHoldersInPDF );
2726 // since printing now also use the API for PDF export this option
2727 // should be set for printing as well ...
2728 pViewShell->SetPDFExportOption( true );
2730 // there is some redundancy between those two function calls, but right now
2731 // there is no time to sort this out.
2732 //TODO: check what exactly needs to be done and make just one function for that
2733 pViewShell->CalcLayout();
2735 // #122919# Force field update before PDF export, but after layout init (tdf#121962)
2736 bool bStateChanged = false;
2737 // check configuration: shall update of printing information in DocInfo set the document to "modified"?
2738 if (pRenderDocShell->IsEnableSetModified() && !officecfg::Office::Common::Print::PrintingModifiesDocument::get())
2740 pRenderDocShell->EnableSetModified( false );
2741 bStateChanged = true;
2743 pViewShell->SwViewShell::UpdateFields(true);
2744 if( bStateChanged )
2745 pRenderDocShell->EnableSetModified();
2747 pViewShell->CalcPagesForPrint( pViewShell->GetPageCount() );
2749 pViewShell->SetPDFExportOption( false );
2751 // enable view again
2752 pViewShell->EndAction();
2755 const sal_Int32 nPageCount = pViewShell->GetPageCount();
2757 // get number of pages to be rendered
2759 const bool bPrintProspect = m_pPrintUIOptions->getBoolValue( "PrintProspect" );
2760 if (bPrintProspect)
2762 SwDoc::CalculatePagePairsForProspectPrinting( *pViewShell->GetLayout(), *m_pRenderData, *m_pPrintUIOptions, nPageCount );
2763 nRet = m_pRenderData->GetPagePairsForProspectPrinting().size();
2765 else
2767 const SwPostItMode nPostItMode = static_cast<SwPostItMode>( m_pPrintUIOptions->getIntValue( "PrintAnnotationMode", 0 ) );
2768 if (nPostItMode != SwPostItMode::NONE)
2770 VclPtr< OutputDevice > pOutDev = lcl_GetOutputDevice( *m_pPrintUIOptions );
2771 m_pRenderData->CreatePostItData(*pDoc, pViewShell->GetViewOptions(), pOutDev);
2774 // get set of valid document pages (according to the current settings)
2775 // and their start frames
2776 SwDoc::CalculatePagesForPrinting( *pViewShell->GetLayout(), *m_pRenderData, *m_pPrintUIOptions, bIsPDFExport, nPageCount );
2778 if (nPostItMode != SwPostItMode::NONE)
2780 SwDoc::UpdatePagesForPrintingWithPostItData( *m_pRenderData,
2781 *m_pPrintUIOptions, nPageCount );
2784 nRet = m_pRenderData->GetPagesToPrint().size();
2787 OSL_ENSURE( nRet >= 0, "negative number of pages???" );
2788 // tdf#144989 the layout is complete now - prevent DoIdleJobs() from
2789 // messing it up, particularly SwDocUpdateField::MakeFieldList_() unhiding
2790 // sections
2791 pDoc->getIDocumentTimerAccess().BlockIdling();
2793 return nRet;
2796 uno::Sequence< beans::PropertyValue > SAL_CALL SwXTextDocument::getRenderer(
2797 sal_Int32 nRenderer,
2798 const uno::Any& rSelection,
2799 const uno::Sequence< beans::PropertyValue >& rxOptions )
2801 SolarMutexGuard aGuard;
2802 ThrowIfInvalid();
2804 const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" );
2805 bool bIsSwSrcView = false;
2806 SfxViewShell *pView = GetRenderView( bIsSwSrcView, rxOptions, bIsPDFExport );
2808 // m_pRenderData should NOT be created here!
2809 // That should only be done in getRendererCount. If this function is called before
2810 // getRendererCount was called then the caller will probably just retrieve the extra UI options
2811 // and is not interested in getting valid information about the other data that would
2812 // otherwise be provided here!
2813 // if( ! m_pRenderData )
2814 // m_pRenderData = new SwRenderData;
2815 if (!m_pPrintUIOptions)
2816 m_pPrintUIOptions = lcl_GetPrintUIOptions( m_pDocShell, pView );
2817 m_pPrintUIOptions->processProperties( rxOptions );
2818 const bool bPrintProspect = m_pPrintUIOptions->getBoolValue( "PrintProspect" );
2819 const bool bIsSkipEmptyPages = !m_pPrintUIOptions->IsPrintEmptyPages( bIsPDFExport );
2820 const bool bPrintPaperFromSetup = m_pPrintUIOptions->getBoolValue( "PrintPaperFromSetup" );
2822 SwDoc *pDoc = GetRenderDoc( pView, rSelection, bIsPDFExport );
2823 OSL_ENSURE( pDoc && pView, "doc or view shell missing!" );
2824 if (!pDoc || !pView)
2825 return uno::Sequence< beans::PropertyValue >();
2827 // due to #110067# (document page count changes sometimes during
2828 // PDF export/printing) we can not check for the upper bound properly.
2829 // Thus instead of throwing the exception we silently return.
2830 if (0 > nRenderer)
2831 throw IllegalArgumentException();
2833 sal_Int32 nMaxRenderer = 0;
2834 if (!bIsSwSrcView && m_pRenderData)
2836 OSL_ENSURE( m_pRenderData, "m_pRenderData missing!!" );
2837 nMaxRenderer = bPrintProspect?
2838 m_pRenderData->GetPagePairsForProspectPrinting().size() - 1 :
2839 m_pRenderData->GetPagesToPrint().size() - 1;
2841 // since SwSrcView::PrintSource is a poor implementation to get the number of pages to print
2842 // we obmit checking of the upper bound in this case.
2843 if (!bIsSwSrcView && m_pRenderData && nRenderer > nMaxRenderer)
2844 return uno::Sequence< beans::PropertyValue >();
2846 uno::Sequence< beans::PropertyValue > aRenderer;
2847 if (m_pRenderData)
2849 // #i114210#
2850 // determine the correct page number from the renderer index
2851 // #i114875
2852 // consider brochure print
2853 const sal_Int32 nPage = bPrintProspect
2854 ? nRenderer + 1
2855 : m_pRenderData->GetPagesToPrint()[ nRenderer ];
2857 // get paper tray to use ...
2858 sal_Int32 nPrinterPaperTray = -1;
2859 if (! bPrintPaperFromSetup)
2861 // ... from individual page style (see the page tab in Format/Page dialog)
2862 const std::map< sal_Int32, sal_Int32 > &rPaperTrays = m_pRenderData->GetPrinterPaperTrays();
2863 std::map< sal_Int32, sal_Int32 >::const_iterator aIt( rPaperTrays.find( nPage ) );
2864 if (aIt != rPaperTrays.end())
2865 nPrinterPaperTray = aIt->second;
2868 // TODO/mba: we really need a generic way to get the SwViewShell!
2869 SwViewShell* pVwSh = nullptr;
2870 SwView* pSwView = dynamic_cast<SwView*>( pView );
2871 if ( pSwView )
2872 pVwSh = pSwView->GetWrtShellPtr();
2873 else
2874 pVwSh = static_cast<SwPagePreview*>(pView)->GetViewShell();
2876 awt::Size aPageSize;
2877 awt::Point aPagePos;
2878 awt::Size aPreferredPageSize;
2879 Size aTmpSize;
2880 #ifdef MACOSX
2881 bool bChangeOrientation = false;
2882 css::view::PaperOrientation nNewOrientation = css::view::PaperOrientation::PaperOrientation_PORTRAIT;
2883 #endif
2884 if (bIsSwSrcView || bPrintProspect)
2886 // for printing of HTML source code and prospect printing we should use
2887 // the printers paper size since
2888 // a) HTML source view has no page size
2889 // b) prospect printing has a different page size from the documents page
2890 // since two document pages will get rendered on one printer page
2892 // since PageIncludesNonprintableArea will be set to true we can return the
2893 // printers paper size here.
2894 // Sometimes 'getRenderer' is only called to get "ExtraPrintUIOptions", in this
2895 // case we won't get an OutputDevice here, but then the caller also has no need
2896 // for the correct PageSize right now...
2897 VclPtr< Printer > pPrinter = dynamic_cast< Printer * >(lcl_GetOutputDevice( *m_pPrintUIOptions ).get());
2898 if (pPrinter)
2900 // HTML source view and prospect adapt to the printer's paper size
2901 aTmpSize = pPrinter->GetPaperSize();
2902 aTmpSize = OutputDevice::LogicToLogic( aTmpSize,
2903 pPrinter->GetMapMode(), MapMode( MapUnit::Map100thMM ));
2904 aPageSize = awt::Size( aTmpSize.Width(), aTmpSize.Height() );
2905 #ifdef MACOSX
2906 // Related: tdf#163126 when brochure printing on macOS, set the
2907 // printer's page size to match the preferred page size. Unlike
2908 // most other platforms, the native print dialog is always
2909 // displayed on macOS and it displays a preview of the print
2910 // output which the user can make layout changes to. The user
2911 // can also change the printer or even send the print output
2912 // to PDF instead of a printer from within the native print
2913 // dialog so set the printer's paper to the preferred size so
2914 // that the initial preview more closely matches the page size
2915 // and rotation that LibreOffice expects.
2916 if (bPrintProspect)
2918 // we just state what output size we would need
2919 // which may cause vcl to set that page size on the printer
2920 // (if available and not overridden by the user)
2921 if( pVwSh )
2922 aTmpSize = pVwSh->GetPageSize( nPage, bIsSkipEmptyPages );
2924 // Related: tdf#163126 set both page size properties as
2925 // they do two different things. The preferred page size
2926 // tells the printer to set its paper size. But the page
2927 // size is the size that LibreOffice will actually draw.
2928 // Fortunately on macOS, there is a good chance that the
2929 // print output will closely match the preferred page size
2930 // since there is no problem printing to a page size not
2931 // supported by an underlying physical printer. In such
2932 // cases, the native print dialog will display at the
2933 // requested paper size as will saving to PDF or opening
2934 // in the Preview application.
2935 aPreferredPageSize = aPageSize = awt::Size( convertTwipToMm100( 2 * aTmpSize.Width() ),
2936 convertTwipToMm100( aTmpSize.Height() ));
2938 // Related: tdf#163126 try to match any paper rotations in
2939 // the native printing code in vcl.
2940 bChangeOrientation = true;
2941 if( aPageSize.Width < aPageSize.Height )
2942 nNewOrientation = css::view::PaperOrientation::PaperOrientation_PORTRAIT;
2943 else
2944 nNewOrientation = css::view::PaperOrientation::PaperOrientation_LANDSCAPE;
2946 #else
2947 // #i115048# it seems users didn't like getting double the formatted page size
2948 // revert to "old" behavior scaling to the current paper size of the printer
2949 if( bPrintProspect )
2951 // just switch to an appropriate portrait/landscape format
2952 // FIXME: brochure printing with landscape pages puts the
2953 // pages next to each other, so landscape is currently always
2954 // the better choice
2955 if( aPageSize.Width < aPageSize.Height )
2957 aPreferredPageSize.Width = aPageSize.Height;
2958 aPreferredPageSize.Height = aPageSize.Width;
2961 #endif
2964 else
2966 if (pVwSh)
2968 aTmpSize = pVwSh->GetPageSize( nPage, bIsSkipEmptyPages );
2969 aPageSize = awt::Size ( convertTwipToMm100( aTmpSize.Width() ),
2970 convertTwipToMm100( aTmpSize.Height() ));
2971 Point aPoint = pVwSh->GetPagePos(nPage);
2972 aPagePos = awt::Point(convertTwipToMm100(aPoint.X()), convertTwipToMm100(aPoint.Y()));
2976 sal_Int32 nLen = 3;
2977 aRenderer = { comphelper::makePropertyValue(u"PageSize"_ustr, aPageSize),
2978 comphelper::makePropertyValue(u"PageIncludesNonprintableArea"_ustr, true),
2979 comphelper::makePropertyValue(u"PagePos"_ustr, aPagePos) };
2980 if (aPreferredPageSize.Width && aPreferredPageSize.Height)
2982 ++nLen;
2983 aRenderer.realloc( nLen );
2984 auto pRenderer = aRenderer.getArray();
2985 pRenderer[ nLen - 1 ].Name = "PreferredPageSize";
2986 pRenderer[ nLen - 1 ].Value <<= aPreferredPageSize;
2988 if (nPrinterPaperTray >= 0)
2990 ++nLen;
2991 aRenderer.realloc( nLen );
2992 auto pRenderer = aRenderer.getArray();
2993 pRenderer[ nLen - 1 ].Name = "PrinterPaperTray";
2994 pRenderer[ nLen - 1 ].Value <<= nPrinterPaperTray;
2996 #ifdef MACOSX
2997 if (bChangeOrientation)
2999 ++nLen;
3000 aRenderer.realloc( nLen );
3001 auto pRenderer = aRenderer.getArray();
3002 pRenderer[ nLen - 1 ].Name = "PaperOrientation";
3003 pRenderer[ nLen - 1 ].Value <<= nNewOrientation;
3005 #endif
3008 // #i117783#
3009 if ( m_bApplyPagePrintSettingsFromXPagePrintable )
3011 SwDoc& rDoc = GetDocOrThrow();
3012 const SwPagePreviewPrtData* pPagePrintSettings = rDoc.GetPreviewPrtData();
3013 if ( pPagePrintSettings &&
3014 ( pPagePrintSettings->GetRow() > 1 ||
3015 pPagePrintSettings->GetCol() > 1 ) )
3017 // extend render data by page print settings attributes
3018 sal_Int32 nLen = aRenderer.getLength();
3019 const sal_Int32 nRenderDataIdxStart = nLen;
3020 nLen += 9;
3021 aRenderer.realloc( nLen );
3022 auto pRenderer = aRenderer.getArray();
3023 // put page print settings attribute into render data
3024 const sal_Int32 nRow = pPagePrintSettings->GetRow();
3025 pRenderer[ nRenderDataIdxStart + 0 ].Name = "NUpRows";
3026 pRenderer[ nRenderDataIdxStart + 0 ].Value <<= std::max<sal_Int32>( nRow, 1);
3027 const sal_Int32 nCol = pPagePrintSettings->GetCol();
3028 pRenderer[ nRenderDataIdxStart + 1 ].Name = "NUpColumns";
3029 pRenderer[ nRenderDataIdxStart + 1 ].Value <<= std::max<sal_Int32>( nCol, 1);
3030 pRenderer[ nRenderDataIdxStart + 2 ].Name = "NUpPageMarginLeft";
3031 pRenderer[ nRenderDataIdxStart + 2 ].Value <<= pPagePrintSettings->GetLeftSpace();
3032 pRenderer[ nRenderDataIdxStart + 3 ].Name = "NUpPageMarginRight";
3033 pRenderer[ nRenderDataIdxStart + 3 ].Value <<= pPagePrintSettings->GetRightSpace();
3034 pRenderer[ nRenderDataIdxStart + 4 ].Name = "NUpPageMarginTop";
3035 pRenderer[ nRenderDataIdxStart + 4 ].Value <<= pPagePrintSettings->GetTopSpace();
3036 pRenderer[ nRenderDataIdxStart + 5 ].Name = "NUpPageMarginBottom";
3037 pRenderer[ nRenderDataIdxStart + 5 ].Value <<= pPagePrintSettings->GetBottomSpace();
3038 pRenderer[ nRenderDataIdxStart + 6 ].Name = "NUpHorizontalSpacing";
3039 pRenderer[ nRenderDataIdxStart + 6 ].Value <<= pPagePrintSettings->GetHorzSpace();
3040 pRenderer[ nRenderDataIdxStart + 7 ].Name = "NUpVerticalSpacing";
3041 pRenderer[ nRenderDataIdxStart + 7 ].Value <<= pPagePrintSettings->GetVertSpace();
3042 if (Printer* pPrinter = rDoc.getIDocumentDeviceAccess().getPrinter(false))
3044 awt::Size aNewPageSize;
3045 const Size aPageSize = pPrinter->PixelToLogic( pPrinter->GetPaperSizePixel(), MapMode( MapUnit::Map100thMM ) );
3046 aNewPageSize = awt::Size( aPageSize.Width(), aPageSize.Height() );
3047 if ( ( pPagePrintSettings->GetLandscape() &&
3048 aPageSize.Width() < aPageSize.Height() ) ||
3049 ( !pPagePrintSettings->GetLandscape() &&
3050 aPageSize.Width() > aPageSize.Height() ) )
3052 aNewPageSize = awt::Size( aPageSize.Height(), aPageSize.Width() );
3054 pRenderer[ nRenderDataIdxStart + 8 ].Name = "NUpPaperSize";
3055 pRenderer[ nRenderDataIdxStart + 8 ].Value <<= aNewPageSize;
3059 m_bApplyPagePrintSettingsFromXPagePrintable = false;
3062 m_pPrintUIOptions->appendPrintUIOptions( aRenderer );
3064 return aRenderer;
3067 SfxViewShell * SwXTextDocument::GuessViewShell(
3068 /* out */ bool &rbIsSwSrcView,
3069 const uno::Reference< css::frame::XController >& rController )
3071 // #130810# SfxViewShell::Current() / SfxViewShell::GetObjectShell()
3072 // must not be used (see comment from MBA)
3074 SfxViewShell *pView = nullptr;
3075 SwView *pSwView = nullptr;
3076 SwPagePreview *pSwPagePreview = nullptr;
3077 SwSrcView *pSwSrcView = nullptr;
3078 SfxViewFrame *pFrame = SfxViewFrame::GetFirst( m_pDocShell, false );
3080 // look for the view shell with the same controller in use,
3081 // otherwise look for a suitable view, preferably a SwView,
3082 // if that one is not found use a SwPagePreview if found.
3083 while (pFrame)
3085 pView = pFrame->GetViewShell();
3086 pSwView = dynamic_cast< SwView * >(pView);
3087 pSwSrcView = dynamic_cast< SwSrcView * >(pView);
3088 if (!pSwPagePreview)
3089 pSwPagePreview = dynamic_cast< SwPagePreview * >(pView);
3090 if (rController.is())
3092 if (pView && pView->GetController() == rController)
3093 break;
3095 else if (pSwView || pSwSrcView)
3096 break;
3097 pFrame = SfxViewFrame::GetNext( *pFrame, m_pDocShell, false );
3100 OSL_ENSURE( pSwView || pSwPagePreview || pSwSrcView, "failed to get view shell" );
3101 if (pView)
3102 rbIsSwSrcView = pSwSrcView != nullptr;
3103 return pView;
3106 void SAL_CALL SwXTextDocument::render(
3107 sal_Int32 nRenderer,
3108 const uno::Any& rSelection,
3109 const uno::Sequence< beans::PropertyValue >& rxOptions )
3111 SolarMutexGuard aGuard;
3112 ThrowIfInvalid();
3114 // due to #110067# (document page count changes sometimes during
3115 // PDF export/printing) we can not check for the upper bound properly.
3116 // Thus instead of throwing the exception we silently return.
3117 if (0 > nRenderer)
3118 throw IllegalArgumentException();
3120 // tdf#135244: prevent jumping to cursor at any temporary modification
3121 auto aLock = m_pDocShell->LockAllViews();
3123 const bool bHasPDFExtOutDevData = lcl_SeqHasProperty( rxOptions, "HasPDFExtOutDevData" );
3124 const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" ) || bHasPDFExtOutDevData;
3125 bool bIsSwSrcView = false;
3126 SfxViewShell *pView = GetRenderView( bIsSwSrcView, rxOptions, bIsPDFExport );
3128 OSL_ENSURE( m_pRenderData, "data should have been created already in getRendererCount..." );
3129 OSL_ENSURE( m_pPrintUIOptions, "data should have been created already in getRendererCount..." );
3130 if (!bIsSwSrcView && !m_pRenderData)
3131 m_pRenderData.reset(new SwRenderData);
3132 if (!m_pPrintUIOptions)
3133 m_pPrintUIOptions = lcl_GetPrintUIOptions( m_pDocShell, pView );
3134 m_pPrintUIOptions->processProperties( rxOptions );
3135 const bool bPrintProspect = m_pPrintUIOptions->getBoolValue( "PrintProspect" );
3136 const bool bLastPage = m_pPrintUIOptions->getBoolValue( "IsLastPage" );
3138 SwDoc *pDoc = GetRenderDoc( pView, rSelection, bIsPDFExport );
3139 OSL_ENSURE( pDoc && pView, "doc or view shell missing!" );
3140 if (pDoc && pView)
3142 sal_Int32 nMaxRenderer = 0;
3143 if (!bIsSwSrcView)
3145 OSL_ENSURE( m_pRenderData, "m_pRenderData missing!!" );
3146 nMaxRenderer = bPrintProspect?
3147 m_pRenderData->GetPagePairsForProspectPrinting().size() - 1 :
3148 m_pRenderData->GetPagesToPrint().size() - 1;
3150 // since SwSrcView::PrintSource is a poor implementation to get the number of pages to print
3151 // we obmit checking of the upper bound in this case.
3152 if (bIsSwSrcView || nRenderer <= nMaxRenderer)
3154 if (bIsSwSrcView)
3156 SwSrcView& rSwSrcView = dynamic_cast<SwSrcView&>(*pView);
3157 VclPtr< OutputDevice > pOutDev = lcl_GetOutputDevice( *m_pPrintUIOptions );
3158 rSwSrcView.PrintSource(pOutDev, nRenderer + 1, false);
3160 else
3162 // the view shell should be SwView for documents PDF export
3163 // or SwPagePreview for PDF export of the page preview
3164 SwViewShell* pVwSh = nullptr;
3165 // TODO/mba: we really need a generic way to get the SwViewShell!
3166 const SwView* pSwView = dynamic_cast<const SwView*>(pView);
3167 if (pSwView)
3168 pVwSh = pSwView->GetWrtShellPtr();
3169 else
3170 pVwSh = static_cast<SwPagePreview*>(pView)->GetViewShell();
3172 // get output device to use
3173 VclPtr< OutputDevice > pOut = lcl_GetOutputDevice( *m_pPrintUIOptions );
3175 if(pVwSh && pOut && m_pRenderData->HasSwPrtOptions())
3177 const OUString aPageRange = m_pPrintUIOptions->getStringValue( "PageRange" );
3178 const bool bFirstPage = m_pPrintUIOptions->getBoolValue( "IsFirstPage" );
3179 bool bIsSkipEmptyPages = !m_pPrintUIOptions->IsPrintEmptyPages( bIsPDFExport );
3181 OSL_ENSURE((pSwView && m_pRenderData->IsViewOptionAdjust())
3182 || (!pSwView && !m_pRenderData->IsViewOptionAdjust()),
3183 "SwView / SwViewOptionAdjust_Impl availability mismatch" );
3185 // since printing now also use the API for PDF export this option
3186 // should be set for printing as well ...
3187 pVwSh->SetPDFExportOption( true );
3189 // #i12836# enhanced pdf export
3191 // First, we have to export hyperlinks, notes, and outline to pdf.
3192 // During this process, additional information required for tagging
3193 // the pdf file are collected, which are evaluated during painting.
3195 SwWrtShell* pWrtShell = pSwView ? pSwView->GetWrtShellPtr() : nullptr;
3197 SwPrintData rSwPrtOptions = *m_pRenderData->GetSwPrtOptions();
3198 if (bIsPDFExport)
3200 rSwPrtOptions.SetPrintPostIts(
3201 lcl_GetBoolProperty(rxOptions, "ExportNotesInMargin")
3202 ? SwPostItMode::InMargins
3203 : SwPostItMode::NONE);
3206 if (bIsPDFExport && (bFirstPage || bHasPDFExtOutDevData) && pWrtShell)
3208 SwEnhancedPDFExportHelper aHelper( *pWrtShell, *pOut, aPageRange, bIsSkipEmptyPages, false, rSwPrtOptions );
3211 if (bPrintProspect)
3212 pVwSh->PrintProspect( pOut, rSwPrtOptions, nRenderer );
3213 else // normal printing and PDF export
3214 pVwSh->PrintOrPDFExport( pOut, rSwPrtOptions, nRenderer, bIsPDFExport );
3216 // #i35176#
3218 // After printing the last page, we take care for the links coming
3219 // from the EditEngine. The links are generated during the painting
3220 // process, but the destinations are still missing.
3222 if (bIsPDFExport && bLastPage && pWrtShell)
3224 SwEnhancedPDFExportHelper aHelper( *pWrtShell, *pOut, aPageRange, bIsSkipEmptyPages, true, rSwPrtOptions );
3227 pVwSh->SetPDFExportOption( false );
3229 // last page to be rendered? (not necessarily the last page of the document)
3230 // -> do clean-up of data
3231 if (bLastPage)
3233 // #i96167# haggai: delete ViewOptionsAdjust here because it makes use
3234 // of the shell, which might get destroyed in lcl_DisposeView!
3235 if (m_pRenderData->IsViewOptionAdjust())
3236 m_pRenderData->ViewOptionAdjustStop();
3238 if (m_pRenderData->HasPostItData())
3239 m_pRenderData->DeletePostItData();
3240 if (m_pHiddenViewFrame)
3242 lcl_DisposeView( m_pHiddenViewFrame, m_pDocShell );
3243 m_pHiddenViewFrame = nullptr;
3245 // prevent crash described in #i108805
3246 if (SwDocShell *pRenderDocShell = pDoc->GetDocShell())
3247 pRenderDocShell->GetMedium()->GetItemSet().Put( SfxBoolItem( SID_HIDDEN, false ) );
3255 if( bLastPage )
3257 // tdf#144989 enable DoIdleJobs() again after last page
3258 // Related: tdf#163126 on macOS, if the "print selection only"
3259 // checkbox is changed and then the restarted print dialog is
3260 // cancelled, idling will have already been unblocked so check
3261 // if it is blocked before unblocking it.
3262 if( pDoc->getIDocumentTimerAccess().IsIdlingBlocked() )
3263 pDoc->getIDocumentTimerAccess().UnblockIdling();
3264 m_pRenderData.reset();
3265 m_pPrintUIOptions.reset();
3269 // xforms::XFormsSupplier
3270 Reference<XNameContainer> SAL_CALL SwXTextDocument::getXForms()
3272 SolarMutexGuard aGuard;
3273 if ( !m_pDocShell )
3274 throw DisposedException(OUString(), getXWeak());
3275 return GetDocOrThrow().getXForms();
3278 uno::Reference< text::XFlatParagraphIterator > SAL_CALL SwXTextDocument::getFlatParagraphIterator(::sal_Int32 nTextMarkupType, sal_Bool bAutomatic)
3280 SolarMutexGuard aGuard;
3281 ThrowIfInvalid();
3283 return SwUnoCursorHelper::CreateFlatParagraphIterator(
3284 GetDocOrThrow(), nTextMarkupType, bAutomatic);
3287 uno::Reference< util::XCloneable > SwXTextDocument::createClone( )
3289 SolarMutexGuard aGuard;
3290 ThrowIfInvalid();
3292 // create a new document - hidden - copy the storage and return it
3293 // SfxObjectShellRef is used here, since the model should control object lifetime after creation
3294 // and thus SfxObjectShellLock is not allowed here
3295 // the model holds reference to the shell, so the shell will not destructed at the end of method
3296 SfxObjectShellRef pShell = GetDocOrThrow().CreateCopy(false, false);
3297 uno::Reference< frame::XModel > xNewModel = pShell->GetModel();
3298 uno::Reference< embed::XStorage > xNewStorage = ::comphelper::OStorageHelper::GetTemporaryStorage( );
3299 uno::Sequence< beans::PropertyValue > aTempMediaDescriptor;
3300 storeToStorage( xNewStorage, aTempMediaDescriptor );
3301 uno::Reference< document::XStorageBasedDocument > xStorageDoc( xNewModel, uno::UNO_QUERY );
3302 xStorageDoc->loadFromStorage( xNewStorage, aTempMediaDescriptor );
3303 return uno::Reference< util::XCloneable >( xNewModel, UNO_QUERY );
3306 void SwXTextDocument::addPasteEventListener(const uno::Reference<text::XPasteListener>& xListener)
3308 SolarMutexGuard aGuard;
3310 if (m_pDocShell && xListener.is())
3311 m_pDocShell->GetWrtShell()->GetPasteListeners().addInterface(xListener);
3314 void SwXTextDocument::removePasteEventListener(
3315 const uno::Reference<text::XPasteListener>& xListener)
3317 SolarMutexGuard aGuard;
3319 if (m_pDocShell && xListener.is())
3320 m_pDocShell->GetWrtShell()->GetPasteListeners().removeInterface(xListener);
3323 void SwXTextDocument::paintTile( VirtualDevice &rDevice,
3324 int nOutputWidth, int nOutputHeight,
3325 int nTilePosX, int nTilePosY,
3326 tools::Long nTileWidth, tools::Long nTileHeight )
3328 SwViewShell* pViewShell = m_pDocShell->GetWrtShell();
3329 pViewShell->PaintTile(rDevice, nOutputWidth, nOutputHeight,
3330 nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3332 LokChartHelper::PaintAllChartsOnTile(rDevice, nOutputWidth, nOutputHeight,
3333 nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3335 // Draw Form controls
3336 comphelper::LibreOfficeKit::setTiledPainting(true);
3337 SwDrawModel* pDrawLayer = GetDocOrThrow().getIDocumentDrawModelAccess().GetDrawModel();
3338 SdrPage* pPage = pDrawLayer->GetPage(sal_uInt16(0));
3339 SdrView* pDrawView = pViewShell->GetDrawView();
3340 SwEditWin& rEditWin = m_pDocShell->GetView()->GetEditWin();
3341 tools::Rectangle aTileRect(Point(nTilePosX, nTilePosY), Size(nTileWidth, nTileHeight));
3342 Size aOutputSize(nOutputWidth, nOutputHeight);
3343 LokControlHandler::paintControlTile(pPage, pDrawView, rEditWin, rDevice, aOutputSize, aTileRect);
3344 comphelper::LibreOfficeKit::setTiledPainting(false);
3347 Size SwXTextDocument::getDocumentSize()
3349 SwViewShell* pViewShell = m_pDocShell->GetWrtShell();
3350 Size aDocSize = pViewShell->GetDocSize();
3352 return Size(aDocSize.Width() + 2 * DOCUMENTBORDER,
3353 aDocSize.Height() + 2 * DOCUMENTBORDER);
3356 void SwXTextDocument::setPart(int nPart, bool /*bAllowChangeFocus*/)
3358 SolarMutexGuard aGuard;
3360 SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
3361 if (!pWrtShell)
3362 return;
3364 pWrtShell->GotoPage(nPart + 1, true);
3367 int SwXTextDocument::getParts()
3369 SolarMutexGuard aGuard;
3371 SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
3372 if (!pWrtShell)
3373 return 0;
3375 return pWrtShell->GetPageCnt();
3378 OUString SwXTextDocument::getPartPageRectangles()
3380 SolarMutexGuard aGuard;
3382 SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
3383 if (!pWrtShell)
3384 return OUString();
3386 return pWrtShell->getPageRectangles();
3389 void SwXTextDocument::setClipboard(const uno::Reference<datatransfer::clipboard::XClipboard>& xClipboard)
3391 SolarMutexGuard aGuard;
3393 if (!m_pDocShell)
3395 SAL_WARN("sw.uno", "no DocShell when attempting to setClipboard");
3396 return;
3399 SwView* pView = m_pDocShell->GetView();
3400 if (pView)
3401 pView->GetEditWin().SetClipboard(xClipboard);
3404 bool SwXTextDocument::isMimeTypeSupported()
3406 SolarMutexGuard aGuard;
3408 SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
3409 if (!pWrtShell)
3410 return false;
3412 TransferableDataHelper aDataHelper(TransferableDataHelper::CreateFromSystemClipboard(&pWrtShell->GetView().GetEditWin()));
3413 if (SdrView* pSdrView = pWrtShell->GetDrawView())
3415 if (pSdrView->GetTextEditObject())
3416 // Editing shape text
3417 return EditEngine::HasValidData(aDataHelper.GetTransferable());
3420 return aDataHelper.GetXTransferable().is() && SwTransferable::IsPaste(*pWrtShell, aDataHelper);
3423 void SwXTextDocument::setClientVisibleArea(const tools::Rectangle& rRectangle)
3425 if (SwView* pView = m_pDocShell->GetView())
3427 // set the PgUp/PgDown offset
3428 pView->ForcePageUpDownOffset(2 * rRectangle.GetHeight() / 3);
3431 if (SwViewShell* pViewShell = m_pDocShell->GetWrtShell())
3433 pViewShell->setLOKVisibleArea(rRectangle);
3437 void SwXTextDocument::setClientZoom(int nTilePixelWidth_, int /*nTilePixelHeight_*/,
3438 int nTileTwipWidth_, int /*nTileTwipHeight_*/)
3440 // Here we set the zoom value as it has been set by the user in the client.
3441 // This value is used in postMouseEvent and setGraphicSelection methods
3442 // for in place chart editing. We assume that x and y scale is roughly
3443 // the same.
3444 SfxInPlaceClient* pIPClient = m_pDocShell->GetView()->GetIPClient();
3445 if (!pIPClient)
3446 return;
3448 SwViewShell* pWrtViewShell = m_pDocShell->GetWrtShell();
3449 double fScale = 100.0 * nTilePixelWidth_ / nTileTwipWidth_
3450 * o3tl::convert(1.0, o3tl::Length::px, o3tl::Length::twip);
3451 SwViewOption aOption(*(pWrtViewShell->GetViewOptions()));
3452 if (aOption.GetZoom() != fScale)
3454 aOption.SetZoom(fScale);
3455 pWrtViewShell->ApplyViewOptions(aOption);
3457 // Changing the zoom value doesn't always trigger the updating of
3458 // the client ole object area, so we call it directly.
3459 pIPClient->VisAreaChanged();
3463 PointerStyle SwXTextDocument::getPointer()
3465 SolarMutexGuard aGuard;
3467 SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
3468 if (!pWrtShell)
3469 return PointerStyle::Arrow;
3471 return pWrtShell->GetView().GetEditWin().GetPointer();
3474 void SwXTextDocument::getTrackedChanges(tools::JsonWriter& rJson)
3476 auto redlinesNode = rJson.startArray("redlines");
3478 // Disable since usability is very low beyond some small number of changes.
3479 static bool bDisableRedlineComments = getenv("DISABLE_REDLINE") != nullptr;
3480 if (bDisableRedlineComments)
3481 return;
3483 const SwRedlineTable& rRedlineTable
3484 = GetDocOrThrow().getIDocumentRedlineAccess().GetRedlineTable();
3485 for (SwRedlineTable::size_type i = 0; i < rRedlineTable.size(); ++i)
3487 auto redlineNode = rJson.startStruct();
3488 rJson.put("index", rRedlineTable[i]->GetId());
3489 rJson.put("author", rRedlineTable[i]->GetAuthorString(1));
3490 rJson.put("type", SwRedlineTypeToOUString(
3491 rRedlineTable[i]->GetRedlineData().GetType()));
3492 rJson.put("comment",
3493 rRedlineTable[i]->GetRedlineData().GetComment());
3494 rJson.put("description", rRedlineTable[i]->GetDescr());
3495 OUString sDateTime = utl::toISO8601(
3496 rRedlineTable[i]->GetRedlineData().GetTimeStamp().GetUNODateTime());
3497 rJson.put("dateTime", sDateTime);
3499 SwContentNode* pContentNd = rRedlineTable[i]->GetPointContentNode();
3500 SwView* pView = dynamic_cast<SwView*>(SfxViewShell::Current());
3501 if (pView && pContentNd)
3503 SwShellCursor aCursor(pView->GetWrtShell(), *(rRedlineTable[i]->Start()));
3504 aCursor.SetMark();
3505 aCursor.GetMark()->Assign(*pContentNd, rRedlineTable[i]->End()->GetContentIndex());
3507 aCursor.FillRects();
3509 SwRects* pRects(&aCursor);
3510 std::vector<OString> aRects;
3511 for (const SwRect& rNextRect : *pRects)
3512 aRects.push_back(rNextRect.SVRect().toString());
3514 const OString sRects = comphelper::string::join("; ", aRects);
3515 rJson.put("textRange", sRects);
3520 void SwXTextDocument::getTrackedChangeAuthors(tools::JsonWriter& rJsonWriter)
3522 SwModule::get()->GetRedlineAuthorInfo(rJsonWriter);
3525 void SwXTextDocument::getRulerState(tools::JsonWriter& rJsonWriter)
3527 SwView* pView = m_pDocShell->GetView();
3528 dynamic_cast<SwCommentRuler&>(pView->GetHRuler()).CreateJsonNotification(rJsonWriter);
3531 void SwXTextDocument::getPostIts(tools::JsonWriter& rJsonWriter)
3533 SolarMutexGuard aGuard;
3534 auto commentsNode = rJsonWriter.startArray("comments");
3535 if (!m_pDocShell)
3536 return;
3537 for (auto const& sidebarItem : *m_pDocShell->GetView()->GetPostItMgr())
3539 sw::annotation::SwAnnotationWin* pWin = sidebarItem->mpPostIt.get();
3541 if (!pWin)
3543 continue;
3546 const SwPostItField* pField = pWin->GetPostItField();
3547 const SwRect& aRect = pWin->GetAnchorRect();
3548 tools::Rectangle aSVRect(aRect.Pos().getX(),
3549 aRect.Pos().getY(),
3550 aRect.Pos().getX() + aRect.SSize().Width(),
3551 aRect.Pos().getY() + aRect.SSize().Height());
3553 if (!sidebarItem->maLayoutInfo.mPositionFromCommentAnchor)
3555 // Comments on frames: anchor position is the corner position, not the whole frame.
3556 aSVRect.SetSize(Size(0, 0));
3559 std::vector<OString> aRects;
3560 for (const basegfx::B2DRange& aRange : pWin->GetAnnotationTextRanges())
3562 const SwRect rect(aRange.getMinX(), aRange.getMinY(), aRange.getWidth(), aRange.getHeight());
3563 aRects.push_back(rect.SVRect().toString());
3565 const OString sRects = comphelper::string::join("; ", aRects);
3567 auto commentNode = rJsonWriter.startStruct();
3568 rJsonWriter.put("id", pField->GetPostItId());
3569 rJsonWriter.put("parentId", pField->GetParentPostItId());
3570 rJsonWriter.put("author", pField->GetPar1());
3571 // Note, for just plain text we could use "text" populated by pField->GetPar2()
3572 rJsonWriter.put("html", pWin->GetSimpleHtml());
3573 rJsonWriter.put("resolved", pField->GetResolved() ? "true" : "false");
3574 rJsonWriter.put("dateTime", utl::toISO8601(pField->GetDateTime().GetUNODateTime()));
3575 rJsonWriter.put("anchorPos", aSVRect.toString());
3576 rJsonWriter.put("textRange", sRects);
3577 rJsonWriter.put("layoutStatus", static_cast< sal_Int16 >(pWin->GetLayoutStatus()));
3581 void SwXTextDocument::executeFromFieldEvent(const StringMap& aArguments)
3583 auto aIter = aArguments.find(u"type"_ustr);
3584 if (aIter == aArguments.end() || aIter->second != "drop-down")
3585 return;
3587 aIter = aArguments.find(u"cmd"_ustr);
3588 if (aIter == aArguments.end() || aIter->second != "selected")
3589 return;
3591 aIter = aArguments.find(u"data"_ustr);
3592 if (aIter == aArguments.end())
3593 return;
3595 sal_Int32 nSelection = aIter->second.toInt32();
3596 SwPosition aPos(*m_pDocShell->GetWrtShell()->GetCursor()->GetPoint());
3597 sw::mark::Fieldmark* pFieldBM = m_pDocShell->GetWrtShell()->getIDocumentMarkAccess()->getInnerFieldmarkFor(aPos);
3598 if ( !pFieldBM )
3600 aPos.AdjustContent(-1);
3601 pFieldBM = m_pDocShell->GetWrtShell()->getIDocumentMarkAccess()->getInnerFieldmarkFor(aPos);
3603 if (pFieldBM && pFieldBM->GetFieldname() == ODF_FORMDROPDOWN)
3605 if (nSelection >= 0)
3607 (*pFieldBM->GetParameters())[ODF_FORMDROPDOWN_RESULT] <<= nSelection;
3608 pFieldBM->Invalidate();
3609 m_pDocShell->GetWrtShell()->SetModified();
3610 m_pDocShell->GetView()->GetEditWin().LogicInvalidate(nullptr);
3615 std::vector<basegfx::B2DRange>
3616 SwXTextDocument::getSearchResultRectangles(const char* pPayload)
3618 SwDoc* pDoc = m_pDocShell->GetDoc();
3619 if (!pDoc)
3620 return std::vector<basegfx::B2DRange>();
3622 sw::search::SearchResultLocator aLocator(pDoc);
3623 sw::search::LocationResult aResult = aLocator.findForPayload(pPayload);
3624 if (aResult.mbFound)
3626 return aResult.maRectangles;
3628 return std::vector<basegfx::B2DRange>();
3631 OString SwXTextDocument::getViewRenderState(SfxViewShell* pViewShell)
3633 if (!m_pDocShell)
3634 return OString();
3636 OStringBuffer aState;
3637 SwView* pView = pViewShell ? dynamic_cast<SwView*>(pViewShell) : m_pDocShell->GetView();
3638 if (pView && pView->GetWrtShellPtr())
3640 const SwViewOption* pVOpt = pView->GetWrtShell().GetViewOptions();
3641 if (pVOpt)
3643 if (pVOpt->IsViewMetaChars())
3644 aState.append('P');
3645 if (pVOpt->IsOnlineSpell())
3646 aState.append('S');
3647 if (pVOpt->GetDocColor() == svtools::ColorConfig::GetDefaultColor(svtools::DOCCOLOR, 1))
3648 aState.append('D');
3650 if (pView->IsSpotlightParaStyles() || pView->IsSpotlightCharStyles())
3652 aState.append('H');
3653 if (pView->IsSpotlightParaStyles())
3654 aState.append('P');
3655 if (pView->IsSpotlightCharStyles())
3656 aState.append('C');
3659 aState.append(';');
3661 OString aThemeName = OUStringToOString(pVOpt->GetThemeName(), RTL_TEXTENCODING_UTF8);
3662 aState.append(aThemeName);
3665 return aState.makeStringAndClear();
3668 namespace
3670 inline constexpr OUString SELECTED_DATE_FORMAT = u"YYYY-MM-DD"_ustr;
3673 void SwXTextDocument::executeContentControlEvent(const StringMap& rArguments)
3675 auto it = rArguments.find(u"type"_ustr);
3676 if (it == rArguments.end())
3678 return;
3681 if (it->second == "drop-down")
3683 SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
3684 const SwPosition* pStart = pWrtShell->GetCursor()->Start();
3685 SwTextNode* pTextNode = pStart->GetNode().GetTextNode();
3686 if (!pTextNode)
3688 return;
3691 SwTextAttr* pAttr = pTextNode->GetTextAttrAt(pStart->GetContentIndex(),
3692 RES_TXTATR_CONTENTCONTROL, ::sw::GetTextAttrMode::Parent);
3693 if (!pAttr)
3695 return;
3698 auto pTextContentControl = static_txtattr_cast<SwTextContentControl*>(pAttr);
3699 const SwFormatContentControl& rFormatContentControl = pTextContentControl->GetContentControl();
3700 std::shared_ptr<SwContentControl> pContentControl = rFormatContentControl.GetContentControl();
3701 if (!pContentControl->GetComboBox() && !pContentControl->GetDropDown())
3703 return;
3706 it = rArguments.find(u"selected"_ustr);
3707 if (it == rArguments.end())
3709 return;
3712 sal_Int32 nSelection = it->second.toInt32();
3713 pContentControl->SetSelectedListItem(nSelection);
3714 pWrtShell->GotoContentControl(rFormatContentControl);
3716 else if (it->second == "picture")
3718 it = rArguments.find(u"changed"_ustr);
3719 if (it == rArguments.end())
3721 return;
3724 SwView* pView = m_pDocShell->GetView();
3725 if (!pView)
3727 return;
3730 // The current placeholder is selected, so this will replace, not insert.
3731 SfxStringItem aItem(SID_INSERT_GRAPHIC, it->second);
3732 pView->GetViewFrame().GetDispatcher()->ExecuteList(SID_CHANGE_PICTURE,
3733 SfxCallMode::SYNCHRON, { &aItem });
3735 else if (it->second == "date")
3737 SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
3738 const SwPosition* pStart = pWrtShell->GetCursor()->Start();
3739 SwTextNode* pTextNode = pStart->GetNode().GetTextNode();
3740 if (!pTextNode)
3742 return;
3745 SwTextAttr* pAttr = pTextNode->GetTextAttrAt(pStart->GetContentIndex(),
3746 RES_TXTATR_CONTENTCONTROL, ::sw::GetTextAttrMode::Parent);
3747 if (!pAttr)
3749 return;
3752 auto pTextContentControl = static_txtattr_cast<SwTextContentControl*>(pAttr);
3753 const SwFormatContentControl& rFormatContentControl
3754 = pTextContentControl->GetContentControl();
3755 std::shared_ptr<SwContentControl> pContentControl
3756 = rFormatContentControl.GetContentControl();
3757 if (!pContentControl->GetDate())
3759 return;
3762 it = rArguments.find(u"selected"_ustr);
3763 if (it == rArguments.end())
3765 return;
3768 OUString aSelectedDate = it->second.replaceAll("T00:00:00Z", "");
3769 SwDoc& rDoc = pTextNode->GetDoc();
3770 SvNumberFormatter* pNumberFormatter = rDoc.GetNumberFormatter();
3771 sal_uInt32 nFormat
3772 = pNumberFormatter->GetEntryKey(SELECTED_DATE_FORMAT, LANGUAGE_ENGLISH_US);
3773 if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
3775 sal_Int32 nCheckPos = 0;
3776 SvNumFormatType nType;
3777 OUString sFormat = SELECTED_DATE_FORMAT;
3778 pNumberFormatter->PutEntry(sFormat, nCheckPos, nType, nFormat, LANGUAGE_ENGLISH_US);
3781 if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
3783 return;
3786 double dCurrentDate = 0;
3787 pNumberFormatter->IsNumberFormat(aSelectedDate, nFormat, dCurrentDate);
3788 pContentControl->SetSelectedDate(dCurrentDate);
3789 pWrtShell->GotoContentControl(rFormatContentControl);
3793 int SwXTextDocument::getPart()
3795 SolarMutexGuard aGuard;
3797 SwView* pView = m_pDocShell->GetView();
3798 if (!pView)
3799 return 0;
3801 return pView->getPart();
3804 OUString SwXTextDocument::getPartName(int nPart)
3806 return SwResId(STR_PAGE) + OUString::number(nPart + 1);
3809 OUString SwXTextDocument::getPartHash(int nPart)
3811 OUString sPart(SwResId(STR_PAGE) + OUString::number(nPart + 1));
3813 return OUString::number(sPart.hashCode());
3816 VclPtr<vcl::Window> SwXTextDocument::getDocWindow()
3818 SolarMutexGuard aGuard;
3819 SwView* pView = m_pDocShell->GetView();
3820 if (!pView)
3821 return {};
3823 if (VclPtr<vcl::Window> pWindow = SfxLokHelper::getInPlaceDocWindow(pView))
3824 return pWindow;
3826 return &(pView->GetEditWin());
3829 void SwXTextDocument::initializeForTiledRendering(const css::uno::Sequence<css::beans::PropertyValue>& rArguments)
3831 SolarMutexGuard aGuard;
3833 if (!m_pDocShell)
3835 SAL_WARN("sw.uno", "no DocShell when attempting to initialize for tiled rendering");
3836 return;
3839 SwView* pView = m_pDocShell->GetView();
3840 if (!pView)
3841 return;
3843 SwViewShell* pViewShell = m_pDocShell->GetWrtShell();
3845 pView->SetViewLayout(1/*nColumns*/, false/*bBookMode*/, true);
3847 // Tiled rendering defaults.
3848 SwViewOption aViewOption(*pViewShell->GetViewOptions());
3849 aViewOption.SetHardBlank(false);
3851 // Disable field shadings: the result would depend on the cursor position.
3852 aViewOption.SetAppearanceFlag(ViewOptFlags::FieldShadings, false);
3853 // The fancy header/footer controls don't work in tiled mode anyway, so
3854 // explicitly disable them to enable skipping invalidating the view for
3855 // the case of clicking in the header area of a document with no headers
3856 aViewOption.SetUseHeaderFooterMenu(false);
3858 OUString sThemeName;
3859 OUString sBackgroundThemeName;
3860 OUString sOrigAuthor = SwModule::get()->GetRedlineAuthor(SwModule::get()->GetRedlineAuthor());
3861 OUString sAuthor;
3863 for (const beans::PropertyValue& rValue : rArguments)
3865 if (rValue.Name == ".uno:HideWhitespace" && rValue.Value.has<bool>())
3866 aViewOption.SetHideWhitespaceMode(rValue.Value.get<bool>());
3867 else if (rValue.Name == ".uno:ShowBorderShadow" && rValue.Value.has<bool>())
3868 aViewOption.SetAppearanceFlag(ViewOptFlags::Shadow , rValue.Value.get<bool>());
3869 else if (rValue.Name == ".uno:Author" && rValue.Value.has<OUString>())
3871 sAuthor = rValue.Value.get<OUString>();
3872 // Store the author name in the view.
3873 pView->SetRedlineAuthor(sAuthor);
3874 // Let the actual author name pick up the value from the current
3875 // view, which would normally happen only during the next view
3876 // switch.
3877 m_pDocShell->SetView(pView);
3879 else if (rValue.Name == ".uno:SpellOnline" && rValue.Value.has<bool>())
3880 aViewOption.SetOnlineSpell(rValue.Value.get<bool>());
3881 else if (rValue.Name == ".uno:ChangeTheme" && rValue.Value.has<OUString>())
3882 sThemeName = rValue.Value.get<OUString>();
3883 else if (rValue.Name == ".uno:InvertBackground" && rValue.Value.has<OUString>())
3884 sBackgroundThemeName = rValue.Value.get<OUString>();
3887 if (!sAuthor.isEmpty() && sAuthor != sOrigAuthor)
3889 SwView* pFirstView = static_cast<SwView*>(SfxViewShell::GetFirst());
3890 if (pFirstView && SfxViewShell::GetNext(*pFirstView) == nullptr)
3892 if (SwEditShell* pShell = &pFirstView->GetWrtShell())
3894 pShell->SwViewShell::UpdateFields(true, /*bSetModified=*/false);
3899 // Set the initial zoom value to 1; usually it is set in setClientZoom and
3900 // SwViewShell::PaintTile; zoom value is used for chart in place
3901 // editing, see postMouseEvent and setGraphicSelection methods.
3902 aViewOption.SetZoom(1 * 100);
3904 aViewOption.SetPostIts(comphelper::LibreOfficeKit::isTiledAnnotations());
3905 pViewShell->ApplyViewOptions(aViewOption);
3907 // position the pages again after setting view options. Eg: if postit
3908 // rendering is false, then there would be no sidebar, so width of the
3909 // document needs to be adjusted
3910 pViewShell->GetLayout()->CheckViewLayout( pViewShell->GetViewOptions(), nullptr );
3912 // Disable map mode, so that it's possible to send mouse event coordinates
3913 // directly in twips.
3914 SwEditWin& rEditWin = m_pDocShell->GetView()->GetEditWin();
3915 rEditWin.EnableMapMode(false);
3917 // when the "This document may contain formatting or content that cannot
3918 // be saved..." dialog appears, it is auto-cancelled with tiled rendering,
3919 // causing 'Save' being disabled; so let's always save to the original
3920 // format
3921 auto xChanges = comphelper::ConfigurationChanges::create();
3922 officecfg::Office::Common::Save::Document::WarnAlienFormat::set(false, xChanges);
3923 xChanges->commit();
3925 // disable word auto-completion suggestions, the tooltips are not visible,
3926 // and the editeng-like auto-completion is annoying
3927 SvxAutoCorrCfg::Get().GetAutoCorrect()->GetSwFlags().bAutoCompleteWords = false;
3929 // don't change the whitespace at the beginning of paragraphs, this is
3930 // annoying when taking minutes without further formatting
3931 SwEditShell::GetAutoFormatFlags()->bAFormatByInpDelSpacesAtSttEnd = false;
3933 // if we know what theme the user wants, then we can dispatch that now early
3934 if (!sThemeName.isEmpty())
3936 css::uno::Sequence<css::beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
3938 { "NewTheme", uno::Any(sThemeName) }
3939 }));
3940 comphelper::dispatchCommand(u".uno:ChangeTheme"_ustr, aPropertyValues);
3942 if (!sBackgroundThemeName.isEmpty())
3944 css::uno::Sequence<css::beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
3946 { "NewTheme", uno::Any(sBackgroundThemeName) }
3947 }));
3948 comphelper::dispatchCommand(".uno:InvertBackground", aPropertyValues);
3952 void SwXTextDocument::postKeyEvent(int nType, int nCharCode, int nKeyCode)
3954 SolarMutexGuard aGuard;
3955 SfxLokHelper::postKeyEventAsync(getDocWindow(), nType, nCharCode, nKeyCode);
3958 void SwXTextDocument::postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier)
3960 SolarMutexGuard aGuard;
3962 SwViewShell* pWrtViewShell = m_pDocShell->GetWrtShell();
3963 if (!pWrtViewShell)
3965 return;
3968 SwViewOption aOption(*(pWrtViewShell->GetViewOptions()));
3969 double fScale = aOption.GetZoom() / o3tl::convert(100.0, o3tl::Length::px, o3tl::Length::twip);
3971 if (SfxLokHelper::testInPlaceComponentMouseEventHit(
3972 m_pDocShell->GetView(), nType, nX, nY, nCount, nButtons, nModifier, fScale, fScale))
3973 return;
3975 // try to forward mouse event to controls
3976 SwDrawModel* pDrawLayer = GetDocOrThrow().getIDocumentDrawModelAccess().GetDrawModel();
3977 SdrPage* pPage = pDrawLayer->GetPage(sal_uInt16(0));
3978 SdrView* pDrawView = pWrtViewShell->GetDrawView();
3979 SwEditWin& rEditWin = m_pDocShell->GetView()->GetEditWin();
3980 Point aPointTwip(nX, nY);
3981 Point aPointHMMDraw = o3tl::convert(aPointTwip, o3tl::Length::twip, o3tl::Length::mm100);
3982 if (LokControlHandler::postMouseEvent(pPage, pDrawView, rEditWin, nType, aPointHMMDraw, nCount, nButtons, nModifier))
3983 return;
3985 LokMouseEventData aMouseEventData(nType, Point(nX, nY), nCount,
3986 MouseEventModifiers::SIMPLECLICK,
3987 nButtons, nModifier);
3988 SfxLokHelper::postMouseEventAsync(&rEditWin, aMouseEventData);
3991 void SwXTextDocument::setTextSelection(int nType, int nX, int nY)
3993 SolarMutexGuard aGuard;
3995 SfxViewShell* pViewShell = m_pDocShell->GetView();
3996 LokChartHelper aChartHelper(pViewShell);
3997 if (aChartHelper.setTextSelection(nType, nX, nY))
3998 return;
4000 SwEditWin& rEditWin = m_pDocShell->GetView()->GetEditWin();
4001 switch (nType)
4003 case LOK_SETTEXTSELECTION_START:
4004 rEditWin.SetCursorTwipPosition(Point(nX, nY), /*bPoint=*/false, /*bClearMark=*/false);
4005 break;
4006 case LOK_SETTEXTSELECTION_END:
4007 rEditWin.SetCursorTwipPosition(Point(nX, nY), /*bPoint=*/true, /*bClearMark=*/false);
4008 break;
4009 case LOK_SETTEXTSELECTION_RESET:
4010 rEditWin.SetCursorTwipPosition(Point(nX, nY), /*bPoint=*/true, /*bClearMark=*/true);
4011 break;
4012 default:
4013 assert(false);
4014 break;
4018 uno::Reference<datatransfer::XTransferable> SwXTextDocument::getSelection()
4020 SolarMutexGuard aGuard;
4022 uno::Reference<datatransfer::XTransferable> xTransferable;
4024 SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
4025 if (SdrView* pSdrView = pWrtShell ? pWrtShell->GetDrawView() : nullptr)
4027 if (pSdrView->GetTextEditObject())
4029 // Editing shape text
4030 EditView& rEditView = pSdrView->GetTextEditOutlinerView()->GetEditView();
4031 xTransferable = rEditView.getEditEngine().CreateTransferable(rEditView.GetSelection());
4035 if (SwPostItMgr* pPostItMgr = m_pDocShell->GetView()->GetPostItMgr())
4037 if (sw::annotation::SwAnnotationWin* pWin = pPostItMgr->GetActiveSidebarWin())
4039 // Editing postit text.
4040 EditView& rEditView = pWin->GetOutlinerView()->GetEditView();
4041 xTransferable = rEditView.getEditEngine().CreateTransferable(rEditView.GetSelection());
4045 if (!xTransferable.is() && pWrtShell)
4046 xTransferable = new SwTransferable(*pWrtShell);
4048 return xTransferable;
4051 void SwXTextDocument::setGraphicSelection(int nType, int nX, int nY)
4053 SolarMutexGuard aGuard;
4055 SwViewShell* pWrtViewShell = m_pDocShell->GetWrtShell();
4056 SwViewOption aOption(*(pWrtViewShell->GetViewOptions()));
4057 double fScale = aOption.GetZoom() / o3tl::convert(100.0, o3tl::Length::px, o3tl::Length::twip);
4059 SfxViewShell* pViewShell = m_pDocShell->GetView();
4060 LokChartHelper aChartHelper(pViewShell);
4061 if (aChartHelper.setGraphicSelection(nType, nX, nY, fScale, fScale))
4062 return;
4064 SwEditWin& rEditWin = m_pDocShell->GetView()->GetEditWin();
4065 switch (nType)
4067 case LOK_SETGRAPHICSELECTION_START:
4068 rEditWin.SetGraphicTwipPosition(/*bStart=*/true, Point(nX, nY));
4069 break;
4070 case LOK_SETGRAPHICSELECTION_END:
4071 rEditWin.SetGraphicTwipPosition(/*bStart=*/false, Point(nX, nY));
4072 break;
4073 default:
4074 assert(false);
4075 break;
4079 void SwXTextDocument::resetSelection()
4081 SolarMutexGuard aGuard;
4083 SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
4084 pWrtShell->ResetSelect(nullptr, false, ScrollSizeMode::ScrollSizeDefault);
4087 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 )
4089 SystemGraphicsData aData;
4090 aData.nSize = sizeof(SystemGraphicsData);
4091 #if defined(_WIN32)
4092 sal_Int64 nWindowHandle;
4093 Parent >>= nWindowHandle;
4094 aData.hWnd = reinterpret_cast<HWND>(nWindowHandle);
4095 ScopedVclPtrInstance<VirtualDevice> xDevice(aData, Size(1, 1), DeviceFormat::WITHOUT_ALPHA);
4096 paintTile(*xDevice, nOutputWidth, nOutputHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
4097 #else
4098 // TODO: support other platforms
4099 (void)Parent;
4100 (void)nOutputWidth;
4101 (void)nOutputHeight;
4102 (void)nTilePosX;
4103 (void)nTilePosY;
4104 (void)nTileWidth;
4105 (void)nTileHeight;
4106 #endif
4110 * retrieve languages already used in current document
4112 uno::Sequence< lang::Locale > SAL_CALL SwXTextDocument::getDocumentLanguages(
4113 ::sal_Int16 nScriptTypes,
4114 ::sal_Int16 nMaxCount )
4116 SolarMutexGuard aGuard;
4118 // possible canonical values for nScriptTypes
4119 // any bit wise combination is allowed
4120 const sal_Int16 nLatin = 0x001;
4121 const sal_Int16 nAsian = 0x002;
4122 const sal_Int16 nComplex = 0x004;
4124 // script types for which to get the languages
4125 const bool bLatin = 0 != (nScriptTypes & nLatin);
4126 const bool bAsian = 0 != (nScriptTypes & nAsian);
4127 const bool bComplex = 0 != (nScriptTypes & nComplex);
4129 if (nScriptTypes < nLatin || nScriptTypes > (nLatin | nAsian | nComplex))
4130 throw IllegalArgumentException(u"nScriptTypes ranges from 1 to 7!"_ustr, Reference< XInterface >(), 1);
4131 if (!m_pDocShell)
4132 throw DisposedException();
4133 SwDoc& rDoc = GetDocOrThrow();
4135 // avoid duplicate values
4136 std::set< LanguageType > aAllLangs;
4138 //USER STYLES
4140 const SwCharFormats *pFormats = rDoc.GetCharFormats();
4141 for(size_t i = 0; i < pFormats->size(); ++i)
4143 const SwAttrSet &rAttrSet = (*pFormats)[i]->GetAttrSet();
4144 LanguageType nLang = LANGUAGE_DONTKNOW;
4145 if (bLatin)
4147 nLang = rAttrSet.GetLanguage( false ).GetLanguage();
4148 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
4149 aAllLangs.insert( nLang );
4151 if (bAsian)
4153 nLang = rAttrSet.GetCJKLanguage( false ).GetLanguage();
4154 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
4155 aAllLangs.insert( nLang );
4157 if (bComplex)
4159 nLang = rAttrSet.GetCTLLanguage( false ).GetLanguage();
4160 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
4161 aAllLangs.insert( nLang );
4165 const SwTextFormatColls *pColls = rDoc.GetTextFormatColls();
4166 for (size_t i = 0; i < pColls->size(); ++i)
4168 const SwAttrSet &rAttrSet = (*pColls)[i]->GetAttrSet();
4169 LanguageType nLang = LANGUAGE_DONTKNOW;
4170 if (bLatin)
4172 nLang = rAttrSet.GetLanguage( false ).GetLanguage();
4173 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
4174 aAllLangs.insert( nLang );
4176 if (bAsian)
4178 nLang = rAttrSet.GetCJKLanguage( false ).GetLanguage();
4179 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
4180 aAllLangs.insert( nLang );
4182 if (bComplex)
4184 nLang = rAttrSet.GetCTLLanguage( false ).GetLanguage();
4185 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
4186 aAllLangs.insert( nLang );
4190 //AUTO STYLES
4191 const IStyleAccess::SwAutoStyleFamily aFam[2] =
4193 IStyleAccess::AUTO_STYLE_CHAR,
4194 IStyleAccess::AUTO_STYLE_PARA
4196 for (IStyleAccess::SwAutoStyleFamily i : aFam)
4198 std::vector< std::shared_ptr<SfxItemSet> > rStyles;
4199 rDoc.GetIStyleAccess().getAllStyles(rStyles, i);
4200 while (!rStyles.empty())
4202 std::shared_ptr<SfxItemSet> pStyle = rStyles.back();
4203 rStyles.pop_back();
4204 const SfxItemSet *pSet = pStyle.get();
4206 LanguageType nLang = LANGUAGE_DONTKNOW;
4207 if (bLatin)
4209 assert(pSet);
4210 nLang = pSet->Get( RES_CHRATR_LANGUAGE, false ).GetLanguage();
4211 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
4212 aAllLangs.insert( nLang );
4214 if (bAsian)
4216 assert(pSet);
4217 nLang = pSet->Get( RES_CHRATR_CJK_LANGUAGE, false ).GetLanguage();
4218 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
4219 aAllLangs.insert( nLang );
4221 if (bComplex)
4223 assert(pSet);
4224 nLang = pSet->Get( RES_CHRATR_CTL_LANGUAGE, false ).GetLanguage();
4225 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
4226 aAllLangs.insert( nLang );
4231 //TODO/mba: it's a strange concept that a view is needed to retrieve core data
4232 SwWrtShell *pWrtSh = m_pDocShell->GetWrtShell();
4233 SdrView *pSdrView = pWrtSh->GetDrawView();
4235 if( pSdrView )
4237 SdrOutliner* pOutliner = pSdrView->GetTextEditOutliner();
4238 if(pOutliner)
4240 EditEngine& rEditEng = const_cast<EditEngine&>(pOutliner->GetEditEngine());
4241 sal_Int32 nParCount = pOutliner->GetParagraphCount();
4242 for (sal_Int32 nPar=0; nPar<nParCount; nPar++)
4244 //every paragraph
4245 std::vector<sal_Int32> aPortions;
4246 rEditEng.GetPortions( nPar, aPortions );
4248 for ( size_t nPos = aPortions.size(); nPos; )
4250 //every position
4251 --nPos;
4252 sal_Int32 nEnd = aPortions[ nPos ];
4253 sal_Int32 nStart = nPos ? aPortions[ nPos - 1 ] : 0;
4254 ESelection aSelection( nPar, nStart, nPar, nEnd );
4255 SfxItemSet aAttr = rEditEng.GetAttribs( aSelection );
4257 LanguageType nLang = LANGUAGE_DONTKNOW;
4258 if (bLatin)
4260 nLang = aAttr.Get( EE_CHAR_LANGUAGE, false ).GetLanguage();
4261 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
4262 aAllLangs.insert( nLang );
4264 if (bAsian)
4266 nLang = aAttr.Get( EE_CHAR_LANGUAGE_CJK, false ).GetLanguage();
4267 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
4268 aAllLangs.insert( nLang );
4270 if (bComplex)
4272 nLang = aAttr.Get( EE_CHAR_LANGUAGE_CTL, false ).GetLanguage();
4273 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
4274 aAllLangs.insert( nLang );
4280 // less than nMaxCount languages
4281 if (nMaxCount > static_cast< sal_Int16 >( aAllLangs.size() ))
4282 nMaxCount = static_cast< sal_Int16 >( aAllLangs.size() );
4284 // build return value
4285 uno::Sequence< lang::Locale > aLanguages( nMaxCount );
4286 lang::Locale* pLanguage = aLanguages.getArray();
4287 if (nMaxCount > 0)
4289 sal_Int32 nCount = 0;
4290 for (const auto& rLang : aAllLangs)
4292 if (nCount >= nMaxCount)
4293 break;
4294 if (LANGUAGE_NONE != rLang)
4296 pLanguage[nCount] = LanguageTag::convertToLocale( rLang );
4297 pLanguage[nCount].Language = SvtLanguageTable::GetLanguageString( rLang );
4298 nCount += 1;
4303 return aLanguages;
4306 SwXLinkTargetSupplier::SwXLinkTargetSupplier(SwXTextDocument& rxDoc) :
4307 m_pxDoc(&rxDoc)
4309 m_sTables = SwResId(STR_CONTENT_TYPE_TABLE);
4310 m_sFrames = SwResId(STR_CONTENT_TYPE_FRAME);
4311 m_sGraphics = SwResId(STR_CONTENT_TYPE_GRAPHIC);
4312 m_sOLEs = SwResId(STR_CONTENT_TYPE_OLE);
4313 m_sSections = SwResId(STR_CONTENT_TYPE_REGION);
4314 m_sOutlines = SwResId(STR_CONTENT_TYPE_OUTLINE);
4315 m_sBookmarks = SwResId(STR_CONTENT_TYPE_BOOKMARK);
4316 m_sDrawingObjects = SwResId(STR_CONTENT_TYPE_DRAWOBJECT);
4319 SwXLinkTargetSupplier::~SwXLinkTargetSupplier()
4323 Any SwXLinkTargetSupplier::getByName(const OUString& rName)
4325 Any aRet;
4326 if(!m_pxDoc)
4327 throw RuntimeException(u"No document available"_ustr);
4328 OUString sSuffix(u"|"_ustr);
4329 if(rName == m_sTables)
4331 sSuffix += "table";
4333 Reference< XNameAccess > xTables = new SwXLinkNameAccessWrapper(
4334 m_pxDoc->getTextTables(), rName, sSuffix );
4335 aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
4337 else if(rName == m_sFrames)
4339 sSuffix += "frame";
4340 Reference< XNameAccess > xTables = new SwXLinkNameAccessWrapper(
4341 m_pxDoc->getTextFrames(), rName, sSuffix );
4342 aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
4344 else if(rName == m_sSections)
4346 sSuffix += "region";
4347 Reference< XNameAccess > xTables = new SwXLinkNameAccessWrapper(
4348 m_pxDoc->getTextSections(), rName, sSuffix );
4349 aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
4351 else if(rName == m_sGraphics)
4353 sSuffix += "graphic";
4354 Reference< XNameAccess > xTables = new SwXLinkNameAccessWrapper(
4355 m_pxDoc->getGraphicObjects(), rName, sSuffix );
4356 aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
4358 else if(rName == m_sOLEs)
4360 sSuffix += "ole";
4361 Reference< XNameAccess > xTables = new SwXLinkNameAccessWrapper(
4362 m_pxDoc->getEmbeddedObjects(), rName, sSuffix );
4363 aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
4365 else if(rName == m_sOutlines)
4367 sSuffix += "outline";
4368 Reference< XNameAccess > xTables = new SwXLinkNameAccessWrapper(
4369 *m_pxDoc, rName, sSuffix );
4370 aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
4372 else if(rName == m_sBookmarks)
4374 sSuffix.clear();
4375 Reference< XNameAccess > xBkms = new SwXLinkNameAccessWrapper(
4376 m_pxDoc->getBookmarks(), rName, sSuffix );
4377 aRet <<= Reference< XPropertySet >(xBkms, UNO_QUERY);
4379 else if(rName == m_sDrawingObjects)
4381 sSuffix += "drawingobject";
4382 Reference<XNameAccess> xDrawingObjects = new SwXLinkNameAccessWrapper(
4383 *m_pxDoc, rName, sSuffix);
4384 aRet <<= Reference<XPropertySet>(xDrawingObjects, UNO_QUERY);
4386 else
4387 throw NoSuchElementException();
4388 return aRet;
4391 Sequence< OUString > SwXLinkTargetSupplier::getElementNames()
4393 return { m_sTables,
4394 m_sFrames,
4395 m_sGraphics,
4396 m_sOLEs,
4397 m_sSections,
4398 m_sOutlines,
4399 m_sBookmarks,
4400 m_sDrawingObjects };
4403 sal_Bool SwXLinkTargetSupplier::hasByName(const OUString& rName)
4405 if( rName == m_sTables ||
4406 rName == m_sFrames ||
4407 rName == m_sGraphics||
4408 rName == m_sOLEs ||
4409 rName == m_sSections ||
4410 rName == m_sOutlines ||
4411 rName == m_sBookmarks ||
4412 rName == m_sDrawingObjects )
4413 return true;
4414 return false;
4417 uno::Type SwXLinkTargetSupplier::getElementType()
4419 return cppu::UnoType<XPropertySet>::get();
4423 sal_Bool SwXLinkTargetSupplier::hasElements()
4425 return nullptr != m_pxDoc;
4428 OUString SwXLinkTargetSupplier::getImplementationName()
4430 return u"SwXLinkTargetSupplier"_ustr;
4433 sal_Bool SwXLinkTargetSupplier::supportsService(const OUString& rServiceName)
4435 return cppu::supportsService(this, rServiceName);
4438 Sequence< OUString > SwXLinkTargetSupplier::getSupportedServiceNames()
4440 Sequence< OUString > aRet { u"com.sun.star.document.LinkTargets"_ustr };
4441 return aRet;
4444 SwXLinkNameAccessWrapper::SwXLinkNameAccessWrapper(
4445 Reference< XNameAccess > const & xAccess, OUString aLinkDisplayName, OUString sSuffix ) :
4446 m_xRealAccess(xAccess),
4447 m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_LINK_TARGET)),
4448 m_sLinkSuffix(std::move(sSuffix)),
4449 m_sLinkDisplayName(std::move(aLinkDisplayName)),
4450 m_pxDoc(nullptr)
4454 SwXLinkNameAccessWrapper::SwXLinkNameAccessWrapper(SwXTextDocument& rxDoc,
4455 OUString aLinkDisplayName, OUString sSuffix) :
4456 m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_LINK_TARGET)),
4457 m_sLinkSuffix(std::move(sSuffix)),
4458 m_sLinkDisplayName(std::move(aLinkDisplayName)),
4459 m_pxDoc(&rxDoc)
4463 SwXLinkNameAccessWrapper::~SwXLinkNameAccessWrapper()
4467 Any SwXLinkNameAccessWrapper::getByName(const OUString& rName)
4469 Any aRet;
4470 bool bFound = false;
4471 //cut link extension and call the real NameAccess
4472 OUString sParam = rName;
4473 OUString sSuffix(m_sLinkSuffix);
4474 if(sParam.getLength() > sSuffix.getLength() )
4476 std::u16string_view sCmp = sParam.subView(sParam.getLength() - sSuffix.getLength(),
4477 sSuffix.getLength());
4478 if(sCmp == sSuffix)
4480 if(m_pxDoc)
4482 sParam = sParam.copy(0, sParam.getLength() - sSuffix.getLength());
4483 if(!m_pxDoc->GetDocShell())
4484 throw RuntimeException(u"No document shell available"_ustr);
4485 SwDoc* pDoc = m_pxDoc->GetDocShell()->GetDoc();
4487 if (sSuffix == "|outline")
4489 const size_t nOutlineCount = pDoc->GetNodes().GetOutLineNds().size();
4491 for (size_t i = 0; i < nOutlineCount && !bFound; ++i)
4493 if(sParam == lcl_CreateOutlineString(i, pDoc))
4495 OUString sOutlineText =
4496 pDoc->getIDocumentOutlineNodes().getOutlineText(
4497 i, pDoc->GetDocShell()->GetWrtShell()->GetLayout());
4498 sal_Int32 nOutlineLevel = pDoc->getIDocumentOutlineNodes().getOutlineLevel(i);
4499 Reference<XPropertySet> xOutline =
4500 new SwXOutlineTarget(sParam, sOutlineText, nOutlineLevel);
4501 aRet <<= xOutline;
4502 bFound = true;
4506 else if (sSuffix == "|drawingobject")
4508 SwDrawModel* pModel = pDoc->getIDocumentDrawModelAccess().GetDrawModel();
4509 if (pModel)
4511 SdrPage* pPage = pModel->GetPage(0);
4512 for (const rtl::Reference<SdrObject>& pObj : *pPage)
4514 if (sParam == pObj->GetName())
4516 Reference<XPropertySet> xDrawingObject = new SwXDrawingObjectTarget(sParam);
4517 aRet <<= xDrawingObject;
4518 bFound = true;
4519 break;
4525 else
4527 aRet = m_xRealAccess->getByName(sParam.copy(0, sParam.getLength() - sSuffix.getLength()));
4528 Reference< XInterface > xInt;
4529 if(!(aRet >>= xInt))
4530 throw RuntimeException(u"Could not retrieve property"_ustr);
4531 Reference< XPropertySet > xProp(xInt, UNO_QUERY);
4532 aRet <<= xProp;
4533 bFound = true;
4537 if(!bFound)
4538 throw NoSuchElementException();
4539 return aRet;
4542 Sequence< OUString > SwXLinkNameAccessWrapper::getElementNames()
4544 Sequence< OUString > aRet;
4545 if(m_pxDoc)
4547 if(!m_pxDoc->GetDocShell())
4548 throw RuntimeException(u"No document shell available"_ustr);
4549 SwDoc* pDoc = m_pxDoc->GetDocShell()->GetDoc();
4550 if (m_sLinkSuffix == "|outline")
4552 const SwOutlineNodes& rOutlineNodes = pDoc->GetNodes().GetOutLineNds();
4553 const size_t nOutlineCount = rOutlineNodes.size();
4554 aRet.realloc(nOutlineCount);
4555 OUString* pResArr = aRet.getArray();
4556 for (size_t i = 0; i < nOutlineCount; ++i)
4558 pResArr[i] = lcl_CreateOutlineString(i, pDoc) + "|outline";
4561 else if (m_sLinkSuffix == "|drawingobject")
4563 SwDrawModel* pModel = pDoc->getIDocumentDrawModelAccess().GetDrawModel();
4564 if(pModel)
4566 SdrPage* pPage = pModel->GetPage(0);
4567 const size_t nObjCount = pPage->GetObjCount();
4568 aRet.realloc(nObjCount);
4569 OUString* pResArr = aRet.getArray();
4570 auto j = 0;
4571 for (const rtl::Reference<SdrObject>& pObj : *pPage)
4573 if (!pObj->GetName().isEmpty())
4574 pResArr[j++] = pObj->GetName() + "|drawingobject";
4579 else
4581 const Sequence< OUString > aOrg = m_xRealAccess->getElementNames();
4582 aRet.realloc(aOrg.getLength());
4583 std::transform(aOrg.begin(), aOrg.end(), aRet.getArray(),
4584 [this](const OUString& rOrg) -> OUString { return rOrg + m_sLinkSuffix; });
4586 return aRet;
4589 sal_Bool SwXLinkNameAccessWrapper::hasByName(const OUString& rName)
4591 bool bRet = false;
4592 OUString sParam(rName);
4593 if(sParam.getLength() > m_sLinkSuffix.getLength() )
4595 std::u16string_view sCmp = sParam.subView(sParam.getLength() - m_sLinkSuffix.getLength(),
4596 m_sLinkSuffix.getLength());
4597 if(sCmp == m_sLinkSuffix)
4599 sParam = sParam.copy(0, sParam.getLength() - m_sLinkSuffix.getLength());
4600 if(m_pxDoc)
4602 if(!m_pxDoc->GetDocShell())
4603 throw RuntimeException(u"No document shell available"_ustr);
4604 SwDoc* pDoc = m_pxDoc->GetDocShell()->GetDoc();
4605 if (m_sLinkSuffix == "|outline")
4607 const size_t nOutlineCount = pDoc->GetNodes().GetOutLineNds().size();
4609 for (size_t i = 0; i < nOutlineCount && !bRet; ++i)
4611 if(sParam == lcl_CreateOutlineString(i, pDoc))
4613 bRet = true;
4617 else if (m_sLinkSuffix == "|drawingobject")
4619 SwDrawModel* pModel = pDoc->getIDocumentDrawModelAccess().GetDrawModel();
4620 if (pModel)
4622 SdrPage* pPage = pModel->GetPage(0);
4623 for (const rtl::Reference<SdrObject>& pObj : *pPage)
4625 if (sParam == pObj->GetName())
4627 bRet = true;
4628 break;
4634 else
4636 bRet = m_xRealAccess->hasByName(sParam);
4640 return bRet;
4643 uno::Type SwXLinkNameAccessWrapper::getElementType()
4645 return cppu::UnoType<XPropertySet>::get();
4648 sal_Bool SwXLinkNameAccessWrapper::hasElements()
4650 bool bRet = false;
4651 if(m_pxDoc)
4653 OSL_FAIL("not implemented");
4655 else
4657 bRet = m_xRealAccess->hasElements();
4659 return bRet;
4662 Reference< XPropertySetInfo > SwXLinkNameAccessWrapper::getPropertySetInfo()
4664 static Reference< XPropertySetInfo > xRet = m_pPropSet->getPropertySetInfo();
4665 return xRet;
4668 void SwXLinkNameAccessWrapper::setPropertyValue(
4669 const OUString& rPropName, const Any& )
4671 throw UnknownPropertyException(rPropName);
4674 static Any lcl_GetDisplayBitmap(std::u16string_view sLinkSuffix)
4676 Any aRet;
4677 if(!sLinkSuffix.empty())
4678 sLinkSuffix = sLinkSuffix.substr(1);
4679 OUString sImgId;
4681 if(sLinkSuffix == u"outline")
4682 sImgId = RID_BMP_NAVI_OUTLINE;
4683 else if(sLinkSuffix == u"table")
4684 sImgId = RID_BMP_NAVI_TABLE;
4685 else if(sLinkSuffix == u"frame")
4686 sImgId = RID_BMP_NAVI_FRAME;
4687 else if(sLinkSuffix == u"graphic")
4688 sImgId = RID_BMP_NAVI_GRAPHIC;
4689 else if(sLinkSuffix == u"ole")
4690 sImgId = RID_BMP_NAVI_OLE;
4691 else if(sLinkSuffix.empty())
4692 sImgId = RID_BMP_NAVI_BOOKMARK;
4693 else if(sLinkSuffix == u"region")
4694 sImgId = RID_BMP_NAVI_REGION;
4695 else if(sLinkSuffix == u"drawingobject")
4696 sImgId = RID_BMP_NAVI_DRAWOBJECT;
4698 if (!sImgId.isEmpty())
4700 aRet <<= VCLUnoHelper::CreateBitmap(BitmapEx(sImgId));
4702 return aRet;
4705 Any SwXLinkNameAccessWrapper::getPropertyValue(const OUString& rPropertyName)
4707 Any aRet;
4708 if( rPropertyName == UNO_LINK_DISPLAY_NAME )
4710 aRet <<= m_sLinkDisplayName;
4712 else if( rPropertyName == UNO_LINK_DISPLAY_BITMAP )
4714 aRet = lcl_GetDisplayBitmap(m_sLinkSuffix);
4716 else
4717 throw UnknownPropertyException(rPropertyName);
4718 return aRet;
4721 void SwXLinkNameAccessWrapper::addPropertyChangeListener(
4722 const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
4725 void SwXLinkNameAccessWrapper::removePropertyChangeListener(
4726 const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
4729 void SwXLinkNameAccessWrapper::addVetoableChangeListener(
4730 const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
4733 void SwXLinkNameAccessWrapper::removeVetoableChangeListener(
4734 const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
4737 Reference< XNameAccess > SwXLinkNameAccessWrapper::getLinks()
4739 return this;
4742 OUString SwXLinkNameAccessWrapper::getImplementationName()
4744 return u"SwXLinkNameAccessWrapper"_ustr;
4747 sal_Bool SwXLinkNameAccessWrapper::supportsService(const OUString& rServiceName)
4749 return cppu::supportsService(this, rServiceName);
4752 Sequence< OUString > SwXLinkNameAccessWrapper::getSupportedServiceNames()
4754 Sequence< OUString > aRet { u"com.sun.star.document.LinkTargets"_ustr };
4755 return aRet;
4758 SwXOutlineTarget::SwXOutlineTarget(OUString aOutlineText, OUString aActualText,
4759 const sal_Int32 nOutlineLevel) :
4760 m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_LINK_TARGET)),
4761 m_sOutlineText(std::move(aOutlineText)),
4762 m_sActualText(std::move(aActualText)),
4763 m_nOutlineLevel(nOutlineLevel)
4767 SwXOutlineTarget::~SwXOutlineTarget()
4771 Reference< XPropertySetInfo > SwXOutlineTarget::getPropertySetInfo()
4773 static Reference< XPropertySetInfo > xRet = m_pPropSet->getPropertySetInfo();
4774 return xRet;
4777 void SwXOutlineTarget::setPropertyValue(
4778 const OUString& rPropertyName, const Any& /*aValue*/)
4780 throw UnknownPropertyException(rPropertyName);
4783 Any SwXOutlineTarget::getPropertyValue(const OUString& rPropertyName)
4785 if (rPropertyName != UNO_LINK_DISPLAY_NAME && rPropertyName != "ActualOutlineName" &&
4786 rPropertyName != "OutlineLevel")
4787 throw UnknownPropertyException(rPropertyName);
4789 if (rPropertyName == "ActualOutlineName")
4790 return Any(m_sActualText);
4792 if (rPropertyName == "OutlineLevel")
4793 return Any(m_nOutlineLevel);
4795 return Any(m_sOutlineText);
4798 void SwXOutlineTarget::addPropertyChangeListener(
4799 const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
4803 void SwXOutlineTarget::removePropertyChangeListener(
4804 const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
4808 void SwXOutlineTarget::addVetoableChangeListener(
4809 const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
4813 void SwXOutlineTarget::removeVetoableChangeListener(
4814 const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
4818 OUString SwXOutlineTarget::getImplementationName()
4820 return u"SwXOutlineTarget"_ustr;
4823 sal_Bool SwXOutlineTarget::supportsService(const OUString& ServiceName)
4825 return cppu::supportsService(this, ServiceName);
4828 Sequence< OUString > SwXOutlineTarget::getSupportedServiceNames()
4830 Sequence<OUString> aRet { u"com.sun.star.document.LinkTarget"_ustr };
4832 return aRet;
4835 SwXDrawingObjectTarget::SwXDrawingObjectTarget(OUString aDrawingObjectText) :
4836 m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_LINK_TARGET)),
4837 m_sDrawingObjectText(std::move(aDrawingObjectText))
4841 SwXDrawingObjectTarget::~SwXDrawingObjectTarget()
4845 Reference< XPropertySetInfo > SwXDrawingObjectTarget::getPropertySetInfo()
4847 static Reference< XPropertySetInfo > xRet = m_pPropSet->getPropertySetInfo();
4848 return xRet;
4851 void SwXDrawingObjectTarget::setPropertyValue(
4852 const OUString& rPropertyName, const Any& /*aValue*/)
4854 throw UnknownPropertyException(rPropertyName);
4857 Any SwXDrawingObjectTarget::getPropertyValue(const OUString& rPropertyName)
4859 if(rPropertyName != UNO_LINK_DISPLAY_NAME)
4860 throw UnknownPropertyException(rPropertyName);
4862 return Any(m_sDrawingObjectText);
4865 void SwXDrawingObjectTarget::addPropertyChangeListener(
4866 const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
4870 void SwXDrawingObjectTarget::removePropertyChangeListener(
4871 const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
4875 void SwXDrawingObjectTarget::addVetoableChangeListener(
4876 const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
4880 void SwXDrawingObjectTarget::removeVetoableChangeListener(
4881 const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
4885 OUString SwXDrawingObjectTarget::getImplementationName()
4887 return u"SwXDrawingObjectTarget"_ustr;
4890 sal_Bool SwXDrawingObjectTarget::supportsService(const OUString& ServiceName)
4892 return cppu::supportsService(this, ServiceName);
4895 Sequence< OUString > SwXDrawingObjectTarget::getSupportedServiceNames()
4897 Sequence<OUString> aRet { u"com.sun.star.document.LinkTarget"_ustr };
4899 return aRet;
4902 SwXDocumentPropertyHelper::SwXDocumentPropertyHelper(SwDoc& rDoc) :
4903 SvxUnoForbiddenCharsTable ( rDoc.getIDocumentSettingAccess().getForbiddenCharacterTable() )
4904 ,m_pDoc(&rDoc)
4908 SwXDocumentPropertyHelper::~SwXDocumentPropertyHelper()
4912 Reference<XInterface> SwXDocumentPropertyHelper::GetDrawTable(SwCreateDrawTable nWhich)
4914 Reference<XInterface> xRet;
4915 if(m_pDoc)
4917 switch(nWhich)
4919 // #i52858#
4920 // assure that Draw model is created, if it doesn't exist.
4921 case SwCreateDrawTable::Dash :
4922 if(!m_xDashTable.is())
4923 m_xDashTable = SvxUnoDashTable_createInstance( &m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
4924 xRet = m_xDashTable;
4925 break;
4926 case SwCreateDrawTable::Gradient :
4927 if(!m_xGradientTable.is())
4928 m_xGradientTable = SvxUnoGradientTable_createInstance( &m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
4929 xRet = m_xGradientTable;
4930 break;
4931 case SwCreateDrawTable::Hatch :
4932 if(!m_xHatchTable.is())
4933 m_xHatchTable = SvxUnoHatchTable_createInstance( &m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
4934 xRet = m_xHatchTable;
4935 break;
4936 case SwCreateDrawTable::Bitmap :
4937 if(!m_xBitmapTable.is())
4938 m_xBitmapTable = SvxUnoBitmapTable_createInstance( &m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
4939 xRet = m_xBitmapTable;
4940 break;
4941 case SwCreateDrawTable::TransGradient:
4942 if(!m_xTransGradientTable.is())
4943 m_xTransGradientTable = SvxUnoTransGradientTable_createInstance( &m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
4944 xRet = m_xTransGradientTable;
4945 break;
4946 case SwCreateDrawTable::Marker :
4947 if(!m_xMarkerTable.is())
4948 m_xMarkerTable = SvxUnoMarkerTable_createInstance( &m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
4949 xRet = m_xMarkerTable;
4950 break;
4951 case SwCreateDrawTable::Defaults:
4952 if(!m_xDrawDefaults.is())
4953 m_xDrawDefaults = cppu::getXWeak(new SwSvxUnoDrawPool(*m_pDoc));
4954 xRet = m_xDrawDefaults;
4955 break;
4956 #if OSL_DEBUG_LEVEL > 0
4957 default: OSL_FAIL("which table?");
4958 #endif
4961 return xRet;
4964 void SwXDocumentPropertyHelper::Invalidate()
4966 m_xDashTable = nullptr;
4967 m_xGradientTable = nullptr;
4968 m_xHatchTable = nullptr;
4969 m_xBitmapTable = nullptr;
4970 m_xTransGradientTable = nullptr;
4971 m_xMarkerTable = nullptr;
4972 m_xDrawDefaults = nullptr;
4973 m_pDoc = nullptr;
4974 SvxUnoForbiddenCharsTable::mxForbiddenChars.reset();
4977 void SwXDocumentPropertyHelper::onChange()
4979 if(m_pDoc)
4980 m_pDoc->getIDocumentState().SetModified();
4983 SwViewOptionAdjust_Impl::SwViewOptionAdjust_Impl(
4984 SwViewShell& rSh, const SwViewOption &rViewOptions)
4985 : m_pShell(&rSh)
4986 , m_aOldViewOptions( rViewOptions )
4990 SwViewOptionAdjust_Impl::~SwViewOptionAdjust_Impl()
4992 if (m_pShell)
4994 m_pShell->ApplyViewOptions( m_aOldViewOptions );
4998 void
4999 SwViewOptionAdjust_Impl::AdjustViewOptions(SwPrintData const*const pPrtOptions, bool setShowPlaceHoldersInPDF)
5001 // to avoid unnecessary reformatting the view options related to the content
5002 // below should only change if necessary, that is if respective content is present
5003 const bool bContainsHiddenChars = m_pShell->GetDoc()->ContainsHiddenChars();
5004 const SwFieldType* pFieldType = m_pShell->GetDoc()->getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::HiddenText );
5005 const bool bContainsHiddenFields = pFieldType && pFieldType->HasWriterListeners();
5006 pFieldType = m_pShell->GetDoc()->getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::HiddenPara );
5007 const bool bContainsHiddenParagraphs = pFieldType && pFieldType->HasWriterListeners();
5008 pFieldType = m_pShell->GetDoc()->getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::JumpEdit );
5009 const bool bContainsPlaceHolders = pFieldType && pFieldType->HasWriterListeners();
5010 const bool bContainsFields = m_pShell->IsAnyFieldInDoc();
5012 SwViewOption aRenderViewOptions( m_aOldViewOptions );
5014 // disable anything in the view that should not be printed (or exported to PDF) by default
5015 // (see also dialog "Tools/Options - StarOffice Writer - Formatting Aids"
5016 // in section "Display of ...")
5017 aRenderViewOptions.SetParagraph( false ); // paragraph end
5018 aRenderViewOptions.SetSoftHyph( false ); // aka custom hyphens
5019 aRenderViewOptions.SetBlank( false ); // spaces
5020 aRenderViewOptions.SetHardBlank( false ); // non-breaking spaces
5021 aRenderViewOptions.SetTab( false ); // tabs
5022 aRenderViewOptions.SetShowBookmarks( false ); // bookmarks
5023 aRenderViewOptions.SetLineBreak( false ); // breaks (type 1)
5024 aRenderViewOptions.SetPageBreak( false ); // breaks (type 2)
5025 aRenderViewOptions.SetColumnBreak( false ); // breaks (type 3)
5026 bool bVal = pPrtOptions && pPrtOptions->m_bPrintHiddenText;
5027 if (bContainsHiddenChars)
5028 aRenderViewOptions.SetShowHiddenChar( bVal ); // hidden text
5029 if (bContainsHiddenFields)
5030 aRenderViewOptions.SetShowHiddenField( bVal );
5031 if (bContainsHiddenParagraphs)
5032 aRenderViewOptions.SetShowHiddenPara( bVal );
5034 if (bContainsPlaceHolders)
5036 // should always be printed in PDF export!
5037 bVal = !pPrtOptions ? setShowPlaceHoldersInPDF : pPrtOptions->m_bPrintTextPlaceholder;
5038 aRenderViewOptions.SetShowPlaceHolderFields( bVal );
5041 if (bContainsFields)
5042 aRenderViewOptions.SetFieldName( false );
5044 // we need to set this flag in order to get to see the visible effect of
5045 // some of the above settings (needed for correct rendering)
5046 aRenderViewOptions.SetViewMetaChars( true );
5048 if (m_aOldViewOptions != aRenderViewOptions) // check if reformatting is necessary
5050 aRenderViewOptions.SetPrinting( pPrtOptions != nullptr );
5051 m_pShell->ApplyViewOptions( aRenderViewOptions );
5055 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */