android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / source / uibase / uno / unotxdoc.cxx
blob603ce43210a006b58e702627dea5e7cc5166c89e
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/string.hxx>
23 #include <AnnotationWin.hxx>
24 #include <o3tl/any.hxx>
25 #include <utility>
26 #include <vcl/virdev.hxx>
27 #include <vcl/sysdata.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/print.hxx>
30 #include <sfx2/bindings.hxx>
31 #include <sfx2/viewfrm.hxx>
32 #include <sfx2/lokhelper.hxx>
33 #include <sfx2/LokControlHandler.hxx>
34 #include <sfx2/docfile.hxx>
35 #include <sfx2/printer.hxx>
36 #include <toolkit/helper/vclunohelper.hxx>
37 #include <toolkit/awt/vclxdevice.hxx>
38 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
39 #include <sfx2/lokcomponenthelpers.hxx>
40 #include <sfx2/ipclient.hxx>
41 #include <editeng/svxacorr.hxx>
42 #include <editeng/acorrcfg.hxx>
43 #include <cmdid.h>
44 #include <swtypes.hxx>
45 #include <wdocsh.hxx>
46 #include <wrtsh.hxx>
47 #include <pview.hxx>
48 #include <viewsh.hxx>
49 #include <pvprtdat.hxx>
50 #include <printdata.hxx>
51 #include <pagefrm.hxx>
52 #include <rootfrm.hxx>
53 #include <svl/stritem.hxx>
54 #include <unotxdoc.hxx>
55 #include <svl/numformat.hxx>
56 #include <svl/numuno.hxx>
57 #include <fldbas.hxx>
58 #include <unomap.hxx>
59 #include <unotextbodyhf.hxx>
60 #include <unotextrange.hxx>
61 #include <unotextcursor.hxx>
62 #include <unosett.hxx>
63 #include <unocoll.hxx>
64 #include <unoredlines.hxx>
65 #include <unosrch.hxx>
66 #include <sfx2/request.hxx>
67 #include <sfx2/objsh.hxx>
68 #include <unoprnms.hxx>
69 #include <unostyle.hxx>
70 #include <unodraw.hxx>
71 #include <svl/eitem.hxx>
72 #include <unotools/configmgr.hxx>
73 #include <unotools/datetime.hxx>
74 #include <unocrsr.hxx>
75 #include <unofieldcoll.hxx>
76 #include <unoidxcoll.hxx>
77 #include <unocrsrhelper.hxx>
78 #include <globdoc.hxx>
79 #include <viewopt.hxx>
80 #include <unochart.hxx>
81 #include <charatr.hxx>
82 #include <svx/xmleohlp.hxx>
83 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
84 #include <com/sun/star/lang/DisposedException.hpp>
85 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
86 #include <com/sun/star/lang/NoSupportException.hpp>
87 #include <com/sun/star/beans/PropertyAttribute.hpp>
88 #include <com/sun/star/beans/XFastPropertySet.hpp>
89 #include <com/sun/star/beans/XPropertyAccess.hpp>
90 #include <com/sun/star/document/RedlineDisplayType.hpp>
91 #include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
92 #include <com/sun/star/frame/XController.hpp>
93 #include <com/sun/star/frame/XFrame.hpp>
94 #include <com/sun/star/script/XInvocation.hpp>
95 #include <com/sun/star/view/XSelectionSupplier.hpp>
96 #include <sfx2/linkmgr.hxx>
97 #include <svx/unofill.hxx>
98 #include <swmodule.hxx>
99 #include <docstat.hxx>
100 #include <modcfg.hxx>
101 #include <ndtxt.hxx>
102 #include <strings.hrc>
103 #include <bitmaps.hlst>
104 #include "unodefaults.hxx"
105 #include "SwXDocumentSettings.hxx"
106 #include <doc.hxx>
107 #include <IDocumentSettingAccess.hxx>
108 #include <IDocumentDeviceAccess.hxx>
109 #include <IDocumentDrawModelAccess.hxx>
110 #include <IDocumentChartDataProviderAccess.hxx>
111 #include <IDocumentLinksAdministration.hxx>
112 #include <IDocumentRedlineAccess.hxx>
113 #include <IDocumentFieldsAccess.hxx>
114 #include <IDocumentStatistics.hxx>
115 #include <IDocumentStylePoolAccess.hxx>
116 #include <IDocumentState.hxx>
117 #include <drawdoc.hxx>
118 #include <SwStyleNameMapper.hxx>
119 #include <osl/file.hxx>
120 #include <comphelper/lok.hxx>
121 #include <comphelper/propertyvalue.hxx>
122 #include <comphelper/storagehelper.hxx>
123 #include <cppuhelper/supportsservice.hxx>
124 #include <sfx2/dispatch.hxx>
125 #include <swruler.hxx>
126 #include <docufld.hxx>
128 #include <EnhancedPDFExportHelper.hxx>
129 #include <numrule.hxx>
131 #include <editeng/langitem.hxx>
132 #include <docary.hxx>
133 #include <i18nlangtag/languagetag.hxx>
134 #include <i18nutil/searchopt.hxx>
136 #include <charfmt.hxx>
137 #include <fmtcol.hxx>
138 #include <istyleaccess.hxx>
140 #include <swatrset.hxx>
141 #include <view.hxx>
142 #include <viscrs.hxx>
143 #include <srcview.hxx>
144 #include <edtwin.hxx>
145 #include <swdtflvr.hxx>
146 #include <PostItMgr.hxx>
148 #include <svtools/langtab.hxx>
149 #include <map>
150 #include <set>
151 #include <vector>
153 #include <editeng/eeitem.hxx>
154 #include <editeng/editeng.hxx>
155 #include <editeng/editview.hxx>
156 #include <svx/svdoutl.hxx>
157 #include <svx/svdview.hxx>
158 #include <comphelper/interfacecontainer4.hxx>
159 #include <comphelper/servicehelper.hxx>
160 #include <memory>
161 #include <redline.hxx>
162 #include <DocumentRedlineManager.hxx>
163 #include <xmloff/odffields.hxx>
164 #include <tools/json_writer.hxx>
165 #include <tools/UnitConversion.hxx>
167 #include <svx/svdpage.hxx>
168 #include <o3tl/string_view.hxx>
169 #include <comphelper/sequenceashashmap.hxx>
171 #include <IDocumentOutlineNodes.hxx>
172 #include <SearchResultLocator.hxx>
173 #include <textcontentcontrol.hxx>
174 #include <unocontentcontrol.hxx>
176 using namespace ::com::sun::star;
177 using namespace ::com::sun::star::text;
178 using namespace ::com::sun::star::i18n;
179 using namespace ::com::sun::star::uno;
180 using namespace ::com::sun::star::beans;
181 using namespace ::com::sun::star::lang;
182 using namespace ::com::sun::star::container;
183 using namespace ::com::sun::star::document;
184 using ::osl::FileBase;
186 static std::unique_ptr<SwPrintUIOptions> lcl_GetPrintUIOptions(
187 SwDocShell * pDocShell,
188 const SfxViewShell * pView )
190 if (!pDocShell)
191 return nullptr;
193 const bool bWebDoc = nullptr != dynamic_cast< const SwWebDocShell * >(pDocShell);
194 const bool bSwSrcView = nullptr != dynamic_cast< const SwSrcView * >(pView);
195 const SwView * pSwView = dynamic_cast< const SwView * >(pView);
196 const bool bHasSelection = pSwView && pSwView->HasSelection( false ); // check for any selection, not just text selection
197 const bool bHasPostIts = sw_GetPostIts(pDocShell->GetDoc()->getIDocumentFieldsAccess(), nullptr);
199 // get default values to use in dialog from documents SwPrintData
200 const SwPrintData &rPrintData = pDocShell->GetDoc()->getIDocumentDeviceAccess().getPrintData();
202 // Get current page number
203 sal_uInt16 nCurrentPage = 1;
204 const SwWrtShell* pSh = pDocShell->GetWrtShell();
205 const SwRootFrame *pFrame = nullptr;
206 if (pSh)
208 SwPaM* pShellCursor = pSh->GetCursor();
209 nCurrentPage = pShellCursor->GetPageNum();
210 pFrame = pSh->GetLayout();
212 else if (!bSwSrcView)
214 const SwPagePreview* pPreview = dynamic_cast< const SwPagePreview* >(pView);
215 OSL_ENSURE(pPreview, "Unexpected type of the view shell");
216 if (pPreview)
218 nCurrentPage = pPreview->GetSelectedPage();
219 pFrame = pPreview->GetViewShell()->GetLayout();
223 // If blanks are skipped, account for them in initial page range value
224 if (pFrame && !rPrintData.IsPrintEmptyPages())
226 sal_uInt16 nMax = nCurrentPage;
227 const SwPageFrame *pPage = dynamic_cast<const SwPageFrame*>(pFrame->Lower());
228 while (pPage && nMax-- > 0)
230 if (pPage->getFrameArea().Height() == 0)
231 nCurrentPage--;
232 pPage = static_cast<const SwPageFrame*>(pPage->GetNext());
235 return std::make_unique<SwPrintUIOptions>( nCurrentPage, bWebDoc, bSwSrcView, bHasSelection, bHasPostIts, rPrintData );
238 static SwTextFormatColl *lcl_GetParaStyle(const OUString& rCollName, SwDoc& rDoc)
240 SwTextFormatColl* pColl = rDoc.FindTextFormatCollByName( rCollName );
241 if( !pColl )
243 const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(
244 rCollName, SwGetPoolIdFromName::TxtColl );
245 if( USHRT_MAX != nId )
246 pColl = rDoc.getIDocumentStylePoolAccess().GetTextCollFromPool( nId );
248 return pColl;
251 static void lcl_DisposeView( SfxViewFrame* pToClose, SwDocShell const * pDocShell )
253 // check if the view frame still exists
254 SfxViewFrame* pFound = SfxViewFrame::GetFirst( pDocShell, false );
255 while(pFound)
257 if( pFound == pToClose)
259 pToClose->DoClose();
260 break;
262 pFound = SfxViewFrame::GetNext( *pFound, pDocShell, false );
266 class SwXTextDocument::Impl
268 public:
269 std::mutex m_Mutex; // just for OInterfaceContainerHelper4
270 ::comphelper::OInterfaceContainerHelper4<css::util::XRefreshListener> m_RefreshListeners;
273 const Sequence< sal_Int8 > & SwXTextDocument::getUnoTunnelId()
275 static const comphelper::UnoIdInit theSwXTextDocumentUnoTunnelId;
276 return theSwXTextDocumentUnoTunnelId.getSeq();
279 sal_Int64 SAL_CALL SwXTextDocument::getSomething( const Sequence< sal_Int8 >& rId )
281 if( comphelper::isUnoTunnelId<SwXTextDocument>(rId) )
283 return comphelper::getSomething_cast(this);
285 if( comphelper::isUnoTunnelId<SfxObjectShell>(rId) )
287 return comphelper::getSomething_cast(m_pDocShell);
290 sal_Int64 nRet = SfxBaseModel::getSomething( rId );
291 if (nRet)
292 return nRet;
294 GetNumberFormatter();
295 if (!m_xNumFormatAgg.is()) // may happen if not valid or no SwDoc
296 return 0;
297 Any aNumTunnel = m_xNumFormatAgg->queryAggregation(cppu::UnoType<XUnoTunnel>::get());
298 Reference<XUnoTunnel> xNumTunnel;
299 aNumTunnel >>= xNumTunnel;
300 return (xNumTunnel.is()) ? xNumTunnel->getSomething(rId) : 0;
303 Any SAL_CALL SwXTextDocument::queryInterface( const uno::Type& rType )
305 Any aRet = SwXTextDocumentBaseClass::queryInterface(rType);
306 if ( !aRet.hasValue() )
307 aRet = SfxBaseModel::queryInterface(rType);
308 if ( !aRet.hasValue() &&
309 rType == cppu::UnoType<lang::XMultiServiceFactory>::get())
311 Reference<lang::XMultiServiceFactory> xTmp = this;
312 aRet <<= xTmp;
314 if ( !aRet.hasValue() &&
315 rType == cppu::UnoType<tiledrendering::XTiledRenderable>::get())
317 Reference<tiledrendering::XTiledRenderable> xTmp = this;
318 aRet <<= xTmp;
321 if ( !aRet.hasValue()
322 && rType != cppu::UnoType<css::document::XDocumentEventBroadcaster>::get()
323 && rType != cppu::UnoType<css::frame::XController>::get()
324 && rType != cppu::UnoType<css::frame::XFrame>::get()
325 && rType != cppu::UnoType<css::script::XInvocation>::get()
326 && rType != cppu::UnoType<css::beans::XFastPropertySet>::get()
327 && rType != cppu::UnoType<css::awt::XWindow>::get())
329 GetNumberFormatter();
330 if(m_xNumFormatAgg.is())
331 aRet = m_xNumFormatAgg->queryAggregation(rType);
333 return aRet;
336 void SAL_CALL SwXTextDocument::acquire()noexcept
338 SfxBaseModel::acquire();
341 void SAL_CALL SwXTextDocument::release()noexcept
343 SfxBaseModel::release();
346 Sequence< uno::Type > SAL_CALL SwXTextDocument::getTypes()
348 Sequence< uno::Type > aNumTypes;
349 GetNumberFormatter();
350 if(m_xNumFormatAgg.is())
352 const uno::Type& rProvType = cppu::UnoType<XTypeProvider>::get();
353 Any aNumProv = m_xNumFormatAgg->queryAggregation(rProvType);
354 Reference<XTypeProvider> xNumProv;
355 if(aNumProv >>= xNumProv)
357 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_bObjectValid(pShell != nullptr),
376 m_pHiddenViewFrame(nullptr),
377 // #i117783#
378 m_bApplyPagePrintSettingsFromXPagePrintable( false )
382 SdrModel& SwXTextDocument::getSdrModelFromUnoModel() const
384 OSL_ENSURE(m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetOrCreateDrawModel(), "No SdrModel in SwDoc, should not happen");
385 return *m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
388 SwXTextDocument::~SwXTextDocument()
390 InitNewDoc();
391 if(m_xNumFormatAgg.is())
393 Reference< XInterface > x0;
394 m_xNumFormatAgg->setDelegator(x0);
395 m_xNumFormatAgg = nullptr;
397 m_pPrintUIOptions.reset();
398 if (m_pRenderData && m_pRenderData->IsViewOptionAdjust())
399 { // rhbz#827695: this can happen if the last page is not printed
400 // the SwViewShell has been deleted already by SwView::~SwView
401 // FIXME: replace this awful implementation of XRenderable with
402 // something less insane that has its own view
403 m_pRenderData->ViewOptionAdjustCrashPreventionKludge();
405 m_pRenderData.reset();
408 SwXDocumentPropertyHelper * SwXTextDocument::GetPropertyHelper ()
410 if(!mxPropertyHelper.is())
412 mxPropertyHelper = new SwXDocumentPropertyHelper(*m_pDocShell->GetDoc());
414 return mxPropertyHelper.get();
417 void SwXTextDocument::GetNumberFormatter()
419 if(!IsValid())
420 return;
422 if(!m_xNumFormatAgg.is())
424 if ( m_pDocShell->GetDoc() )
426 rtl::Reference<SvNumberFormatsSupplierObj> pNumFormat = new SvNumberFormatsSupplierObj(
427 m_pDocShell->GetDoc()->GetNumberFormatter());
428 m_xNumFormatAgg = pNumFormat;
430 if(m_xNumFormatAgg.is())
431 m_xNumFormatAgg->setDelegator(static_cast<cppu::OWeakObject*>(static_cast<SwXTextDocumentBaseClass*>(this)));
433 else
435 const uno::Type& rTunnelType = cppu::UnoType<XUnoTunnel>::get();
436 Any aNumTunnel = m_xNumFormatAgg->queryAggregation(rTunnelType);
437 Reference< XUnoTunnel > xNumTunnel;
438 aNumTunnel >>= xNumTunnel;
439 SvNumberFormatsSupplierObj* pNumFormat
440 = comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>(xNumTunnel);
441 OSL_ENSURE(pNumFormat, "No number formatter available");
442 if (pNumFormat && !pNumFormat->GetNumberFormatter())
443 pNumFormat->SetNumberFormatter(m_pDocShell->GetDoc()->GetNumberFormatter());
447 Reference< XText > SwXTextDocument::getText()
449 return getBodyText();
452 rtl::Reference< SwXBodyText > SwXTextDocument::getBodyText()
454 SolarMutexGuard aGuard;
455 if(!IsValid())
456 throw DisposedException("", static_cast< XTextDocument* >(this));
457 if(!m_xBodyText.is())
459 m_xBodyText = new SwXBodyText(m_pDocShell->GetDoc());
461 return m_xBodyText;
464 void SwXTextDocument::reformat()
466 SolarMutexGuard aGuard;
467 if(!IsValid())
468 throw DisposedException("", static_cast< XTextDocument* >(this));
471 void SwXTextDocument::lockControllers()
473 SolarMutexGuard aGuard;
474 if(!IsValid())
475 throw DisposedException("", static_cast< XTextDocument* >(this));
477 maActionArr.emplace_front(new UnoActionContext(m_pDocShell->GetDoc()));
480 void SwXTextDocument::unlockControllers()
482 SolarMutexGuard aGuard;
483 if(maActionArr.empty())
484 throw RuntimeException("Nothing to unlock");
486 maActionArr.pop_front();
489 sal_Bool SwXTextDocument::hasControllersLocked()
491 SolarMutexGuard aGuard;
492 return !maActionArr.empty();
495 Reference< frame::XController > SwXTextDocument::getCurrentController()
497 return SfxBaseModel::getCurrentController();
500 void SwXTextDocument::setCurrentController(const Reference< frame::XController > & xController)
502 SfxBaseModel::setCurrentController(xController);
505 Reference< XInterface > SwXTextDocument::getCurrentSelection()
507 SolarMutexGuard aGuard;
508 Reference< XInterface > xRef;
509 if(IsValid())
511 SwView* pView = static_cast<SwView*>(SfxViewShell::GetFirst(true, checkSfxViewShell<SwView>));
512 while(pView && pView->GetObjectShell() != m_pDocShell)
514 pView = static_cast<SwView*>(SfxViewShell::GetNext(*pView, true, checkSfxViewShell<SwView>));
516 if(pView)
518 Any aRef = pView->GetUNOObject()->getSelection();
519 aRef >>= xRef;
522 return xRef;
525 sal_Bool SwXTextDocument::attachResource(const OUString& aURL, const Sequence< beans::PropertyValue >& aArgs)
527 return SfxBaseModel::attachResource(aURL, aArgs);
530 OUString SwXTextDocument::getURL()
532 return SfxBaseModel::getURL();
535 Sequence< beans::PropertyValue > SwXTextDocument::getArgs()
537 return SfxBaseModel::getArgs();
540 void SwXTextDocument::connectController(const Reference< frame::XController > & xController)
542 SfxBaseModel::connectController(xController);
545 void SwXTextDocument::disconnectController(const Reference< frame::XController > & xController)
547 SfxBaseModel::disconnectController(xController);
550 void SwXTextDocument::dispose()
552 // Delete UnoActionContexts before deleting the SwDoc, as the first has unowned pointers to the
553 // second.
554 maActionArr.clear();
556 SfxBaseModel::dispose();
559 void SwXTextDocument::close( sal_Bool bDeliverOwnership )
561 if(m_pDocShell)
563 uno::Sequence< uno::Any > aArgs;
564 m_pDocShell->CallAutomationDocumentEventSinks( "Close", aArgs );
566 SolarMutexGuard aGuard;
567 if(IsValid() && m_pHiddenViewFrame)
568 lcl_DisposeView( m_pHiddenViewFrame, m_pDocShell);
569 SfxBaseModel::close(bDeliverOwnership);
572 void SwXTextDocument::addEventListener(const Reference< lang::XEventListener > & aListener)
574 SfxBaseModel::addEventListener(aListener);
577 void SwXTextDocument::removeEventListener(const Reference< lang::XEventListener > & aListener)
579 SfxBaseModel::removeEventListener(aListener);
582 Reference< XPropertySet > SwXTextDocument::getLineNumberingProperties()
584 SolarMutexGuard aGuard;
585 if(!IsValid())
586 throw DisposedException("", static_cast< XTextDocument* >(this));
588 if(!mxXLineNumberingProperties.is())
590 mxXLineNumberingProperties = new SwXLineNumberingProperties(m_pDocShell->GetDoc());
592 return mxXLineNumberingProperties;
595 Reference< XIndexReplace > SwXTextDocument::getChapterNumberingRules()
597 SolarMutexGuard aGuard;
598 if(!IsValid())
599 throw DisposedException("", static_cast< XTextDocument* >(this));
600 if(!mxXChapterNumbering.is())
602 mxXChapterNumbering = new SwXChapterNumbering(*m_pDocShell);
604 return mxXChapterNumbering;
607 Reference< XIndexAccess > SwXTextDocument::getNumberingRules()
609 SolarMutexGuard aGuard;
610 if(!IsValid())
611 throw DisposedException("", static_cast< XTextDocument* >(this));
612 if(!mxXNumberingRules.is() )
614 mxXNumberingRules = new SwXNumberingRulesCollection( m_pDocShell->GetDoc() );
616 return mxXNumberingRules;
619 Reference< XIndexAccess > SwXTextDocument::getFootnotes()
621 SolarMutexGuard aGuard;
622 if(!IsValid())
623 throw DisposedException("", static_cast< XTextDocument* >(this));
624 if(!mxXFootnotes.is())
626 mxXFootnotes = new SwXFootnotes(false, m_pDocShell->GetDoc());
628 return mxXFootnotes;
631 Reference< XPropertySet > SAL_CALL
632 SwXTextDocument::getFootnoteSettings()
634 SolarMutexGuard aGuard;
635 if(!IsValid())
636 throw DisposedException("", static_cast< XTextDocument* >(this));
637 if(!mxXFootnoteSettings.is())
639 mxXFootnoteSettings = new SwXFootnoteProperties(m_pDocShell->GetDoc());
641 return mxXFootnoteSettings;
644 Reference< XIndexAccess > SwXTextDocument::getEndnotes()
646 SolarMutexGuard aGuard;
647 if(!IsValid())
648 throw DisposedException("", static_cast< XTextDocument* >(this));
649 if(!mxXEndnotes.is())
651 mxXEndnotes = new SwXFootnotes(true, m_pDocShell->GetDoc());
653 return mxXEndnotes;
656 Reference< XPropertySet > SwXTextDocument::getEndnoteSettings()
658 SolarMutexGuard aGuard;
659 if(!IsValid())
660 throw DisposedException("", static_cast< XTextDocument* >(this));
661 if(!mxXEndnoteSettings.is())
663 mxXEndnoteSettings = new SwXEndnoteProperties(m_pDocShell->GetDoc());
665 return mxXEndnoteSettings;
668 Reference< XIndexAccess > SwXTextDocument::getContentControls()
670 SolarMutexGuard aGuard;
671 if(!IsValid())
672 throw DisposedException("", static_cast< XTextDocument* >(this));
673 if(!mxXContentControls.is())
675 mxXContentControls = new SwXContentControls(m_pDocShell->GetDoc());
677 return mxXContentControls;
680 Reference< util::XReplaceDescriptor > SwXTextDocument::createReplaceDescriptor()
682 return new SwXTextSearch;
685 SwUnoCursor* SwXTextDocument::CreateCursorForSearch(Reference< XTextCursor > & xCursor)
687 getText();
688 XText *const pText = m_xBodyText.get();
689 SwXBodyText* pBText = static_cast<SwXBodyText*>(pText);
690 rtl::Reference<SwXTextCursor> pXTextCursor = pBText->CreateTextCursor(true);
691 xCursor.set( static_cast<text::XWordCursor*>(pXTextCursor.get()) );
693 auto& rUnoCursor(pXTextCursor->GetCursor());
694 rUnoCursor.SetRemainInSection(false);
695 return &rUnoCursor;
698 sal_Int32 SwXTextDocument::replaceAll(const Reference< util::XSearchDescriptor > & xDesc)
700 SolarMutexGuard aGuard;
701 SwXTextSearch* pSearch;
702 if (!IsValid() || !(pSearch = dynamic_cast<SwXTextSearch*>(xDesc.get())))
703 throw DisposedException("", static_cast< XTextDocument* >(this));
705 Reference< XTextCursor > xCursor;
706 auto pUnoCursor(CreateCursorForSearch(xCursor));
707 int eRanges(FindRanges::InBody|FindRanges::InSelAll);
709 i18nutil::SearchOptions2 aSearchOpt;
710 pSearch->FillSearchOptions( aSearchOpt );
712 SwDocPositions eStart = pSearch->m_bBack ? SwDocPositions::End : SwDocPositions::Start;
713 SwDocPositions eEnd = pSearch->m_bBack ? SwDocPositions::Start : SwDocPositions::End;
715 // Search should take place anywhere
716 pUnoCursor->SetRemainInSection(false);
717 sal_Int32 nResult;
718 UnoActionContext aContext(m_pDocShell->GetDoc());
719 //try attribute search first
720 if(pSearch->HasSearchAttributes()||pSearch->HasReplaceAttributes())
722 SfxItemSetFixed<RES_CHRATR_BEGIN, RES_CHRATR_END-1,
723 RES_PARATR_BEGIN, RES_PARATR_END-1,
724 RES_FRMATR_BEGIN, RES_FRMATR_END-1> aSearch(m_pDocShell->GetDoc()->GetAttrPool());
725 SfxItemSetFixed<RES_CHRATR_BEGIN, RES_CHRATR_END-1,
726 RES_PARATR_BEGIN, RES_PARATR_END-1,
727 RES_FRMATR_BEGIN, RES_FRMATR_END-1> aReplace(m_pDocShell->GetDoc()->GetAttrPool());
728 pSearch->FillSearchItemSet(aSearch);
729 pSearch->FillReplaceItemSet(aReplace);
730 bool bCancel;
731 nResult = pUnoCursor->FindAttrs(aSearch, !pSearch->m_bStyles,
732 eStart, eEnd, bCancel,
733 static_cast<FindRanges>(eRanges),
734 !pSearch->m_sSearchText.isEmpty() ? &aSearchOpt : nullptr,
735 &aReplace );
737 else if(pSearch->m_bStyles)
739 SwTextFormatColl *pSearchColl = lcl_GetParaStyle(pSearch->m_sSearchText, pUnoCursor->GetDoc());
740 SwTextFormatColl *pReplaceColl = lcl_GetParaStyle(pSearch->m_sReplaceText, pUnoCursor->GetDoc());
742 bool bCancel;
743 nResult = pUnoCursor->FindFormat(*pSearchColl,
744 eStart, eEnd, bCancel,
745 static_cast<FindRanges>(eRanges), pReplaceColl );
748 else
750 //todo/mba: assuming that notes should be omitted
751 bool bCancel;
752 nResult = pUnoCursor->Find_Text(aSearchOpt, false/*bSearchInNotes*/,
753 eStart, eEnd, bCancel,
754 static_cast<FindRanges>(eRanges),
755 true );
757 return nResult;
761 Reference< util::XSearchDescriptor > SwXTextDocument::createSearchDescriptor()
763 return new SwXTextSearch;
766 // Used for findAll/First/Next
768 SwUnoCursor* SwXTextDocument::FindAny(const Reference< util::XSearchDescriptor > & xDesc,
769 Reference< XTextCursor > & xCursor,
770 bool bAll,
771 sal_Int32& nResult,
772 Reference< XInterface > const & xLastResult)
774 const auto pSearch = dynamic_cast<SwXTextSearch*>(xDesc.get());
775 if(!IsValid() || !pSearch)
776 return nullptr;
778 auto pUnoCursor(CreateCursorForSearch(xCursor));
780 bool bParentInExtra = false;
781 if(xLastResult.is())
783 OTextCursorHelper* pPosCursor = dynamic_cast<OTextCursorHelper*>(xLastResult.get());
784 SwPaM* pCursor = pPosCursor ? pPosCursor->GetPaM() : nullptr;
785 if(pCursor)
787 *pUnoCursor->GetPoint() = *pCursor->End();
788 pUnoCursor->DeleteMark();
790 else
792 SwXTextRange* pRange = dynamic_cast<SwXTextRange*>(xLastResult.get());
793 if(!pRange)
794 return nullptr;
795 pRange->GetPositions(*pUnoCursor);
796 if(pUnoCursor->HasMark())
798 if(*pUnoCursor->GetPoint() < *pUnoCursor->GetMark())
799 pUnoCursor->Exchange();
800 pUnoCursor->DeleteMark();
803 const SwNode& rRangeNode = pUnoCursor->GetPointNode();
804 bParentInExtra = rRangeNode.FindFlyStartNode() ||
805 rRangeNode.FindFootnoteStartNode() ||
806 rRangeNode.FindHeaderStartNode() ||
807 rRangeNode.FindFooterStartNode() ;
810 i18nutil::SearchOptions2 aSearchOpt;
811 pSearch->FillSearchOptions( aSearchOpt );
814 * The following combinations are allowed:
815 * - Search in the body: -> FindRanges::InBody
816 * - Search all in the body: -> FindRanges::InBodyOnly | FindRanges::InSelAll
817 * - Search in selections: one / all -> FindRanges::InSel [ | FindRanges::InSelAll ]
818 * - Search outside the body: one / all -> FindRanges::InOther [ | FindRanges::InSelAll ]
819 * - Search everywhere all: -> FindRanges::InSelAll
821 FindRanges eRanges(FindRanges::InBody);
822 if(bParentInExtra)
823 eRanges = FindRanges::InOther;
824 if(bAll) //always - everywhere?
825 eRanges = FindRanges::InSelAll;
826 SwDocPositions eStart = !bAll ? SwDocPositions::Curr : pSearch->m_bBack ? SwDocPositions::End : SwDocPositions::Start;
827 SwDocPositions eEnd = pSearch->m_bBack ? SwDocPositions::Start : SwDocPositions::End;
829 nResult = 0;
830 for (int nSearchProc = 0; nSearchProc < 2; ++nSearchProc)
832 //try attribute search first
833 if(pSearch->HasSearchAttributes())
835 SfxItemSetFixed<
836 RES_CHRATR_BEGIN, RES_CHRATR_END - 1,
837 RES_TXTATR_INETFMT, RES_TXTATR_CHARFMT,
838 RES_PARATR_BEGIN, RES_PARATR_END - 1,
839 RES_FRMATR_BEGIN, RES_FRMATR_END - 1>
840 aSearch( m_pDocShell->GetDoc()->GetAttrPool() );
841 pSearch->FillSearchItemSet(aSearch);
842 bool bCancel;
843 nResult = pUnoCursor->FindAttrs(aSearch, !pSearch->m_bStyles,
844 eStart, eEnd, bCancel,
845 eRanges,
846 !pSearch->m_sSearchText.isEmpty() ? &aSearchOpt : nullptr );
848 else if(pSearch->m_bStyles)
850 SwTextFormatColl *pSearchColl = lcl_GetParaStyle(pSearch->m_sSearchText, pUnoCursor->GetDoc());
851 //pSearch->sReplaceText
852 SwTextFormatColl *pReplaceColl = nullptr;
853 bool bCancel;
854 nResult = pUnoCursor->FindFormat(*pSearchColl,
855 eStart, eEnd, bCancel,
856 eRanges, pReplaceColl );
858 else
860 //todo/mba: assuming that notes should be omitted
861 bool bCancel;
862 nResult = pUnoCursor->Find_Text(aSearchOpt, false/*bSearchInNotes*/,
863 eStart, eEnd, bCancel,
864 eRanges );
866 if(nResult || (eRanges&(FindRanges::InSelAll|FindRanges::InOther)))
867 break;
868 //second step - find in other
869 eRanges = FindRanges::InOther;
871 return pUnoCursor;
874 Reference< XIndexAccess >
875 SwXTextDocument::findAll(const Reference< util::XSearchDescriptor > & xDesc)
877 SolarMutexGuard aGuard;
878 Reference< XInterface > xTmp;
879 sal_Int32 nResult = 0;
880 Reference< XTextCursor > xCursor;
881 auto pResultCursor(FindAny(xDesc, xCursor, true, nResult, xTmp));
882 if(!pResultCursor)
883 throw RuntimeException("No result cursor");
884 Reference< XIndexAccess > xRet = SwXTextRanges::Create( nResult ? &(*pResultCursor) : nullptr );
885 return xRet;
888 Reference< XInterface > SwXTextDocument::findFirst(const Reference< util::XSearchDescriptor > & xDesc)
890 SolarMutexGuard aGuard;
891 Reference< XInterface > xTmp;
892 sal_Int32 nResult = 0;
893 Reference< XTextCursor > xCursor;
894 auto pResultCursor(FindAny(xDesc, xCursor, false, nResult, xTmp));
895 if(!pResultCursor)
896 throw RuntimeException("No result cursor");
897 Reference< XInterface > xRet;
898 if(nResult)
900 const uno::Reference< text::XText > xParent =
901 ::sw::CreateParentXText(*m_pDocShell->GetDoc(),
902 *pResultCursor->GetPoint());
903 xRet = *new SwXTextCursor(xParent, *pResultCursor);
905 return xRet;
908 Reference< XInterface > SwXTextDocument::findNext(const Reference< XInterface > & xStartAt,
909 const Reference< util::XSearchDescriptor > & xDesc)
911 SolarMutexGuard aGuard;
912 sal_Int32 nResult = 0;
913 Reference< XTextCursor > xCursor;
914 if(!xStartAt.is())
915 throw RuntimeException("xStartAt missing");
916 auto pResultCursor(FindAny(xDesc, xCursor, false, nResult, xStartAt));
917 if(!pResultCursor)
918 throw RuntimeException("No result cursor");
919 Reference< XInterface > xRet;
920 if(nResult)
922 const uno::Reference< text::XText > xParent =
923 ::sw::CreateParentXText(*m_pDocShell->GetDoc(),
924 *pResultCursor->GetPoint());
926 xRet = *new SwXTextCursor(xParent, *pResultCursor);
928 return xRet;
931 Sequence< beans::PropertyValue > SwXTextDocument::getPagePrintSettings()
933 SolarMutexGuard aGuard;
934 Sequence< beans::PropertyValue > aSeq(9);
935 if(!IsValid())
936 throw DisposedException("", static_cast< XTextDocument* >(this));
938 beans::PropertyValue* pArray = aSeq.getArray();
939 SwPagePreviewPrtData aData;
940 const SwPagePreviewPrtData* pData = m_pDocShell->GetDoc()->GetPreviewPrtData();
941 if(pData)
942 aData = *pData;
943 Any aVal;
944 aVal <<= aData.GetRow();
945 pArray[0] = beans::PropertyValue("PageRows", -1, aVal, PropertyState_DIRECT_VALUE);
946 aVal <<= aData.GetCol();
947 pArray[1] = beans::PropertyValue("PageColumns", -1, aVal, PropertyState_DIRECT_VALUE);
948 aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetLeftSpace()));
949 pArray[2] = beans::PropertyValue("LeftMargin", -1, aVal, PropertyState_DIRECT_VALUE);
950 aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetRightSpace()));
951 pArray[3] = beans::PropertyValue("RightMargin", -1, aVal, PropertyState_DIRECT_VALUE);
952 aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetTopSpace()));
953 pArray[4] = beans::PropertyValue("TopMargin", -1, aVal, PropertyState_DIRECT_VALUE);
954 aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetBottomSpace()));
955 pArray[5] = beans::PropertyValue("BottomMargin", -1, aVal, PropertyState_DIRECT_VALUE);
956 aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetHorzSpace()));
957 pArray[6] = beans::PropertyValue("HoriMargin", -1, aVal, PropertyState_DIRECT_VALUE);
958 aVal <<= static_cast<sal_Int32>(convertTwipToMm100(aData.GetVertSpace()));
959 pArray[7] = beans::PropertyValue("VertMargin", -1, aVal, PropertyState_DIRECT_VALUE);
960 aVal <<= aData.GetLandscape();
961 pArray[8] = beans::PropertyValue("IsLandscape", -1, aVal, PropertyState_DIRECT_VALUE);
963 return aSeq;
966 static sal_uInt32 lcl_Any_To_ULONG(const Any& rValue, bool& bException)
968 bException = false;
969 TypeClass eType = rValue.getValueType().getTypeClass();
971 sal_uInt32 nRet = 0;
972 if( eType == TypeClass_UNSIGNED_LONG )
973 rValue >>= nRet;
974 else
976 sal_Int32 nVal=0;
977 bException = !(rValue >>= nVal);
978 if( !bException )
979 nRet = static_cast<sal_uInt32>(nVal);
982 return nRet;
985 static OUString lcl_CreateOutlineString(const size_t nIndex, const SwDoc* pDoc)
987 OUStringBuffer sEntry;
988 const SwOutlineNodes& rOutlineNodes = pDoc->GetNodes().GetOutLineNds();
989 const SwNumRule* pOutlRule = pDoc->GetOutlineNumRule();
990 const SwTextNode * pTextNd = rOutlineNodes[ nIndex ]->GetTextNode();
991 SwNumberTree::tNumberVector aNumVector = pTextNd->GetNumberVector();
992 if( pOutlRule && pTextNd->GetNumRule())
993 for( int nLevel = 0;
994 nLevel <= pTextNd->GetActualListLevel();
995 nLevel++ )
997 tools::Long nVal = aNumVector[nLevel];
998 nVal ++;
999 nVal -= pOutlRule->Get(nLevel).GetStart();
1000 sEntry.append( OUString::number(nVal) + ".");
1002 OUString sOutlineText = pDoc->getIDocumentOutlineNodes().getOutlineText(
1003 nIndex, pDoc->GetDocShell()->GetWrtShell()->GetLayout(), false);
1004 sEntry.append(sOutlineText);
1005 return sEntry.makeStringAndClear();
1008 void SwXTextDocument::setPagePrintSettings(const Sequence< beans::PropertyValue >& aSettings)
1010 SolarMutexGuard aGuard;
1011 if(!IsValid())
1012 throw DisposedException("", static_cast< XTextDocument* >(this));
1014 SwPagePreviewPrtData aData;
1015 //if only a few properties are coming, then use the current settings
1016 const SwPagePreviewPrtData* pData = m_pDocShell->GetDoc()->GetPreviewPrtData();
1017 if(pData)
1018 aData = *pData;
1019 for(const beans::PropertyValue& rProperty : aSettings)
1021 OUString sName = rProperty.Name;
1022 const Any& rVal = rProperty.Value;
1023 bool bException;
1024 sal_uInt32 nVal = lcl_Any_To_ULONG(rVal, bException);
1025 if( sName == "PageRows" )
1027 if(!nVal || nVal > 0xff)
1028 throw RuntimeException("Invalid value");
1029 aData.SetRow(nVal);
1031 else if(sName == "PageColumns")
1033 if(!nVal || nVal > 0xff)
1034 throw RuntimeException("Invalid value");
1035 aData.SetCol(nVal);
1037 else if(sName == "LeftMargin")
1039 aData.SetLeftSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
1041 else if(sName == "RightMargin")
1043 aData.SetRightSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
1045 else if(sName == "TopMargin")
1047 aData.SetTopSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
1049 else if(sName == "BottomMargin")
1051 aData.SetBottomSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
1053 else if(sName == "HoriMargin")
1055 aData.SetHorzSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
1057 else if(sName == "VertMargin")
1059 aData.SetVertSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
1061 else if(sName == "IsLandscape")
1063 auto b = o3tl::tryAccess<bool>(rVal);
1064 bException = !b;
1065 if (b)
1067 aData.SetLandscape(*b);
1070 else
1071 bException = true;
1072 if(bException)
1073 throw RuntimeException();
1075 m_pDocShell->GetDoc()->SetPreviewPrtData(&aData);
1079 void SwXTextDocument::printPages(const Sequence< beans::PropertyValue >& xOptions)
1081 SolarMutexGuard aGuard;
1082 if(!IsValid())
1083 throw DisposedException("", static_cast< XTextDocument* >(this));
1085 SfxViewFrame* pFrame = SfxViewFrame::LoadHiddenDocument( *m_pDocShell, SfxInterfaceId(7) );
1086 SfxRequest aReq(FN_PRINT_PAGEPREVIEW, SfxCallMode::SYNCHRON,
1087 m_pDocShell->GetDoc()->GetAttrPool());
1088 aReq.AppendItem(SfxBoolItem(FN_PRINT_PAGEPREVIEW, true));
1090 for ( const beans::PropertyValue &rProp : xOptions )
1092 // get Property-Value from options
1093 Any aValue( rProp.Value );
1095 // FileName-Property?
1096 if ( rProp.Name == UNO_NAME_FILE_NAME )
1098 OUString sFileURL;
1099 if ( rProp.Value >>= sFileURL )
1101 // Convert the File URL into a system dependent path, as the SalPrinter expects
1102 OUString sSystemPath;
1103 FileBase::getSystemPathFromFileURL ( sFileURL, sSystemPath );
1104 aReq.AppendItem(SfxStringItem( SID_FILE_NAME, sSystemPath ) );
1106 else if ( rProp.Value.getValueType() != cppu::UnoType<void>::get() )
1107 throw IllegalArgumentException();
1110 // CopyCount-Property
1111 else if ( rProp.Name == UNO_NAME_COPY_COUNT )
1113 sal_Int32 nCopies = 0;
1114 aValue >>= nCopies;
1115 aReq.AppendItem(SfxInt16Item( SID_PRINT_COPIES, static_cast<sal_Int16>(nCopies) ) );
1118 // Collate-Property
1119 else if ( rProp.Name == UNO_NAME_COLLATE )
1121 auto b = o3tl::tryAccess<bool>(rProp.Value);
1122 if ( !b )
1123 throw IllegalArgumentException();
1124 aReq.AppendItem(SfxBoolItem( SID_PRINT_COLLATE, *b ) );
1128 // Sort-Property
1129 else if ( rProp.Name == UNO_NAME_SORT )
1131 auto b = o3tl::tryAccess<bool>(rProp.Value);
1132 if ( !b )
1133 throw IllegalArgumentException();
1135 aReq.AppendItem(SfxBoolItem( SID_PRINT_SORT, *b ) );
1138 // Pages-Property
1139 else if ( rProp.Name == UNO_NAME_PAGES )
1141 OUString sTmp;
1142 if ( !(rProp.Value >>= sTmp) )
1143 throw IllegalArgumentException();
1145 aReq.AppendItem( SfxStringItem( SID_PRINT_PAGES, sTmp ) );
1150 // #i117783#
1151 m_bApplyPagePrintSettingsFromXPagePrintable = true;
1152 pFrame->GetViewShell()->ExecuteSlot(aReq);
1153 // Frame close
1154 pFrame->DoClose();
1158 Reference< XNameAccess > SwXTextDocument::getReferenceMarks()
1160 SolarMutexGuard aGuard;
1161 if(!IsValid())
1162 throw DisposedException("", static_cast< XTextDocument* >(this));
1163 if(!mxXReferenceMarks.is())
1165 mxXReferenceMarks = new SwXReferenceMarks(m_pDocShell->GetDoc());
1167 return mxXReferenceMarks;
1170 Reference< XEnumerationAccess > SwXTextDocument::getTextFields()
1172 SolarMutexGuard aGuard;
1173 if(!IsValid())
1174 throw DisposedException("", static_cast< XTextDocument* >(this));
1175 if(!mxXTextFieldTypes.is())
1177 mxXTextFieldTypes = new SwXTextFieldTypes(m_pDocShell->GetDoc());
1179 return mxXTextFieldTypes;
1182 Reference< XNameAccess > SwXTextDocument::getTextFieldMasters()
1184 SolarMutexGuard aGuard;
1185 if(!IsValid())
1186 throw DisposedException("", static_cast< XTextDocument* >(this));
1187 if(!mxXTextFieldMasters.is())
1189 mxXTextFieldMasters = new SwXTextFieldMasters(m_pDocShell->GetDoc());
1191 return mxXTextFieldMasters;
1194 Reference< XNameAccess > SwXTextDocument::getEmbeddedObjects()
1196 SolarMutexGuard aGuard;
1197 if(!IsValid())
1198 throw DisposedException("", static_cast< XTextDocument* >(this));
1199 if(!mxXEmbeddedObjects.is())
1201 mxXEmbeddedObjects = new SwXTextEmbeddedObjects(m_pDocShell->GetDoc());
1203 return mxXEmbeddedObjects;
1206 Reference< XNameAccess > SwXTextDocument::getBookmarks()
1208 SolarMutexGuard aGuard;
1209 if(!IsValid())
1210 throw DisposedException("", static_cast< XTextDocument* >(this));
1211 if(!mxXBookmarks.is())
1213 mxXBookmarks = new SwXBookmarks(m_pDocShell->GetDoc());
1215 return mxXBookmarks;
1218 Reference< XNameAccess > SwXTextDocument::getTextSections()
1220 SolarMutexGuard aGuard;
1221 if(!IsValid())
1222 throw DisposedException("", static_cast< XTextDocument* >(this));
1223 if(!mxXTextSections.is())
1225 mxXTextSections = new SwXTextSections(m_pDocShell->GetDoc());
1227 return mxXTextSections;
1230 Reference< XNameAccess > SwXTextDocument::getTextTables()
1232 SolarMutexGuard aGuard;
1233 if(!IsValid())
1234 throw DisposedException("", static_cast< XTextDocument* >(this));
1235 if(!mxXTextTables.is())
1237 mxXTextTables = new SwXTextTables(m_pDocShell->GetDoc());
1239 return mxXTextTables;
1242 Reference< XNameAccess > SwXTextDocument::getGraphicObjects()
1244 SolarMutexGuard aGuard;
1245 if(!IsValid())
1246 throw DisposedException("", static_cast< XTextDocument* >(this));
1247 if(!mxXGraphicObjects.is())
1249 mxXGraphicObjects = new SwXTextGraphicObjects(m_pDocShell->GetDoc());
1251 return mxXGraphicObjects;
1254 Reference< XNameAccess > SwXTextDocument::getTextFrames()
1256 SolarMutexGuard aGuard;
1257 if(!IsValid())
1258 throw DisposedException("", static_cast< XTextDocument* >(this));
1259 if(!mxXTextFrames.is())
1261 mxXTextFrames = new SwXTextFrames(m_pDocShell->GetDoc());
1263 return mxXTextFrames;
1266 Reference< XNameAccess > SwXTextDocument::getStyleFamilies()
1268 SolarMutexGuard aGuard;
1269 if(!IsValid())
1270 throw DisposedException("", static_cast< XTextDocument* >(this));
1271 if(!mxXStyleFamilies.is())
1273 mxXStyleFamilies = new SwXStyleFamilies(*m_pDocShell);
1275 return mxXStyleFamilies;
1278 uno::Reference< style::XAutoStyles > SwXTextDocument::getAutoStyles( )
1280 SolarMutexGuard aGuard;
1281 if(!IsValid())
1282 throw DisposedException("", static_cast< XTextDocument* >(this));
1283 if(!mxXAutoStyles.is())
1285 mxXAutoStyles = new SwXAutoStyles(*m_pDocShell);
1287 return mxXAutoStyles;
1291 Reference< drawing::XDrawPage > SwXTextDocument::getDrawPage()
1293 SolarMutexGuard aGuard;
1294 if(!IsValid())
1295 throw DisposedException("", static_cast< XTextDocument* >(this));
1296 if(!m_xDrawPage.is())
1298 SwDoc* pDoc = m_pDocShell->GetDoc();
1299 // #i52858#
1300 SwDrawModel* pModel = pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel();
1301 SdrPage* pPage = pModel->GetPage( 0 );
1302 m_xDrawPage = new SwFmDrawPage(pDoc, pPage);
1304 return m_xDrawPage;
1307 namespace {
1309 class SwDrawPagesObj : public cppu::WeakImplHelper<
1310 css::drawing::XDrawPages,
1311 css::lang::XServiceInfo>
1313 private:
1314 css::uno::Reference< css::drawing::XDrawPageSupplier > m_xDoc;
1315 public:
1316 SwDrawPagesObj(css::uno::Reference< css::drawing::XDrawPageSupplier > xDoc) : m_xDoc(std::move(xDoc)) {}
1318 // XDrawPages
1319 virtual css::uno::Reference< css::drawing::XDrawPage > SAL_CALL
1320 insertNewByIndex(sal_Int32 /*nIndex*/) override { throw css::lang::NoSupportException(); }
1322 virtual void SAL_CALL remove(const css::uno::Reference< css::drawing::XDrawPage >& /*xPage*/) override
1324 throw css::lang::NoSupportException();
1327 // XIndexAccess
1328 virtual sal_Int32 SAL_CALL getCount() override { return 1; }
1330 virtual css::uno::Any SAL_CALL getByIndex(sal_Int32 Index) override
1332 if (Index != 0)
1333 throw css::lang::IndexOutOfBoundsException("Writer documents have only one DrawPage!");
1334 return css::uno::Any(m_xDoc->getDrawPage());
1337 // XElementAccess
1338 virtual css::uno::Type SAL_CALL getElementType() override
1340 return cppu::UnoType<drawing::XDrawPage>::get();
1343 virtual sal_Bool SAL_CALL hasElements() override { return true; }
1345 // XServiceInfo
1346 virtual OUString SAL_CALL getImplementationName() override
1348 return "SwDrawPagesObj";
1351 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override
1353 return cppu::supportsService(this, ServiceName);
1356 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
1358 return { "com.sun.star.drawing.DrawPages" };
1364 // XDrawPagesSupplier
1366 uno::Reference<drawing::XDrawPages> SAL_CALL SwXTextDocument::getDrawPages()
1368 SolarMutexGuard aGuard;
1369 return new SwDrawPagesObj(this);
1372 void SwXTextDocument::Invalidate()
1374 m_bObjectValid = false;
1375 if(m_xNumFormatAgg.is())
1377 const uno::Type& rTunnelType = cppu::UnoType<XUnoTunnel>::get();
1378 Any aNumTunnel = m_xNumFormatAgg->queryAggregation(rTunnelType);
1379 Reference< XUnoTunnel > xNumTunnel;
1380 aNumTunnel >>= xNumTunnel;
1381 SvNumberFormatsSupplierObj* pNumFormat
1382 = comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>(xNumTunnel);
1383 OSL_ENSURE(pNumFormat, "No number formatter available");
1384 if (pNumFormat)
1385 pNumFormat->SetNumberFormatter(nullptr);
1386 OSL_ENSURE(pNumFormat, "No number formatter available");
1388 InitNewDoc();
1389 m_pDocShell = nullptr;
1390 lang::EventObject const ev(static_cast<SwXTextDocumentBaseClass &>(*this));
1391 std::unique_lock aGuard(m_pImpl->m_Mutex);
1392 m_pImpl->m_RefreshListeners.disposeAndClear(aGuard, ev);
1395 void SwXTextDocument::Reactivate(SwDocShell* pNewDocShell)
1397 if(m_pDocShell && m_pDocShell != pNewDocShell)
1398 Invalidate();
1399 m_pDocShell = pNewDocShell;
1400 m_bObjectValid = true;
1403 void SwXTextDocument::InitNewDoc()
1405 // first invalidate all collections, then delete references and Set to zero
1406 if(mxXTextTables.is())
1408 XNameAccess* pTables = mxXTextTables.get();
1409 static_cast<SwXTextTables*>(pTables)->Invalidate();
1410 mxXTextTables.clear();
1413 if(mxXTextFrames.is())
1415 XNameAccess* pFrames = mxXTextFrames.get();
1416 static_cast<SwXTextFrames*>(pFrames)->Invalidate();
1417 mxXTextFrames.clear();
1420 if(mxXGraphicObjects.is())
1422 XNameAccess* pFrames = mxXGraphicObjects.get();
1423 static_cast<SwXTextGraphicObjects*>(pFrames)->Invalidate();
1424 mxXGraphicObjects.clear();
1427 if(mxXEmbeddedObjects.is())
1429 XNameAccess* pOLE = mxXEmbeddedObjects.get();
1430 static_cast<SwXTextEmbeddedObjects*>(pOLE)->Invalidate();
1431 mxXEmbeddedObjects.clear();
1434 m_xBodyText = nullptr;
1436 if(m_xNumFormatAgg.is())
1438 const uno::Type& rTunnelType = cppu::UnoType<XUnoTunnel>::get();
1439 Any aNumTunnel = m_xNumFormatAgg->queryAggregation(rTunnelType);
1440 Reference< XUnoTunnel > xNumTunnel;
1441 aNumTunnel >>= xNumTunnel;
1442 SvNumberFormatsSupplierObj* pNumFormat
1443 = comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>(xNumTunnel);
1444 OSL_ENSURE(pNumFormat, "No number formatter available");
1445 if (pNumFormat)
1446 pNumFormat->SetNumberFormatter(nullptr);
1449 if(mxXTextFieldTypes.is())
1451 XEnumerationAccess* pT = mxXTextFieldTypes.get();
1452 static_cast<SwXTextFieldTypes*>(pT)->Invalidate();
1453 mxXTextFieldTypes.clear();
1456 if(mxXTextFieldMasters.is())
1458 XNameAccess* pT = mxXTextFieldMasters.get();
1459 static_cast<SwXTextFieldMasters*>(pT)->Invalidate();
1460 mxXTextFieldMasters.clear();
1463 if(mxXTextSections.is())
1465 XNameAccess* pSect = mxXTextSections.get();
1466 static_cast<SwXTextSections*>(pSect)->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 Reference<XComponent>(static_cast<cppu::OWeakObject*>(m_xDrawPage.get()), UNO_QUERY_THROW)->dispose();
1475 m_xDrawPage->InvalidateSwDoc();
1476 m_xDrawPage.clear();
1479 if ( mxXNumberingRules.is() )
1481 XIndexAccess* pNum = mxXNumberingRules.get();
1482 static_cast<SwXNumberingRulesCollection*>(pNum)->Invalidate();
1483 mxXNumberingRules.clear();
1486 if(mxXFootnotes.is())
1488 XIndexAccess* pFootnote = mxXFootnotes.get();
1489 static_cast<SwXFootnotes*>(pFootnote)->Invalidate();
1490 mxXFootnotes.clear();
1493 if(mxXEndnotes.is())
1495 XIndexAccess* pFootnote = mxXEndnotes.get();
1496 static_cast<SwXFootnotes*>(pFootnote)->Invalidate();
1497 mxXEndnotes.clear();
1500 if(mxXContentControls.is())
1502 XIndexAccess* pContentControls = mxXContentControls.get();
1503 static_cast<SwXContentControls*>(pContentControls)->Invalidate();
1504 mxXContentControls.clear();
1507 if(mxXDocumentIndexes.is())
1509 XIndexAccess* pIdxs = mxXDocumentIndexes.get();
1510 static_cast<SwXDocumentIndexes*>(pIdxs)->Invalidate();
1511 mxXDocumentIndexes.clear();
1514 if(mxXStyleFamilies.is())
1516 XNameAccess* pStyles = mxXStyleFamilies.get();
1517 static_cast<SwXStyleFamilies*>(pStyles)->Invalidate();
1518 mxXStyleFamilies.clear();
1520 if(mxXAutoStyles.is())
1522 XNameAccess* pStyles = mxXAutoStyles.get();
1523 static_cast<SwXAutoStyles*>(pStyles)->Invalidate();
1524 mxXAutoStyles.clear();
1527 if(mxXBookmarks.is())
1529 XNameAccess* pBm = mxXBookmarks.get();
1530 static_cast<SwXBookmarks*>(pBm)->Invalidate();
1531 mxXBookmarks.clear();
1534 if(mxXChapterNumbering.is())
1536 XIndexReplace* pCh = mxXChapterNumbering.get();
1537 static_cast<SwXChapterNumbering*>(pCh)->Invalidate();
1538 mxXChapterNumbering.clear();
1541 if(mxXFootnoteSettings.is())
1543 XPropertySet* pFntSet = mxXFootnoteSettings.get();
1544 static_cast<SwXFootnoteProperties*>(pFntSet)->Invalidate();
1545 mxXFootnoteSettings.clear();
1548 if(mxXEndnoteSettings.is())
1550 XPropertySet* pEndSet = mxXEndnoteSettings.get();
1551 static_cast<SwXEndnoteProperties*>(pEndSet)->Invalidate();
1552 mxXEndnoteSettings.clear();
1555 if(mxXLineNumberingProperties.is())
1557 XPropertySet* pLine = mxXLineNumberingProperties.get();
1558 static_cast<SwXLineNumberingProperties*>(pLine)->Invalidate();
1559 mxXLineNumberingProperties.clear();
1561 if(mxXReferenceMarks.is())
1563 XNameAccess* pMarks = mxXReferenceMarks.get();
1564 static_cast<SwXReferenceMarks*>(pMarks)->Invalidate();
1565 mxXReferenceMarks.clear();
1567 if(mxLinkTargetSupplier.is())
1569 XNameAccess* pAccess = mxLinkTargetSupplier.get();
1570 static_cast<SwXLinkTargetSupplier*>(pAccess)->Invalidate();
1571 mxLinkTargetSupplier.clear();
1573 if(mxXRedlines.is())
1575 XEnumerationAccess* pMarks = mxXRedlines.get();
1576 static_cast<SwXRedlines*>(pMarks)->Invalidate();
1577 mxXRedlines.clear();
1579 if(mxPropertyHelper.is())
1581 mxPropertyHelper->Invalidate();
1582 mxPropertyHelper.clear();
1586 css::uno::Reference<css::uno::XInterface> SwXTextDocument::create(
1587 OUString const & rServiceName,
1588 css::uno::Sequence<css::uno::Any> const * arguments)
1590 SolarMutexGuard aGuard;
1591 if (!IsValid())
1592 throw DisposedException("", static_cast< XTextDocument* >(this));
1594 const SwServiceType nType = SwXServiceProvider::GetProviderType(rServiceName);
1595 if (nType != SwServiceType::Invalid)
1597 return SwXServiceProvider::MakeInstance(nType, *m_pDocShell->GetDoc());
1599 if (rServiceName == "com.sun.star.drawing.DashTable")
1601 return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Dash);
1603 if (rServiceName == "com.sun.star.drawing.GradientTable")
1605 return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Gradient);
1607 if (rServiceName == "com.sun.star.drawing.HatchTable")
1609 return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Hatch);
1611 if (rServiceName == "com.sun.star.drawing.BitmapTable")
1613 return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Bitmap);
1615 if (rServiceName == "com.sun.star.drawing.TransparencyGradientTable")
1617 return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::TransGradient);
1619 if (rServiceName == "com.sun.star.drawing.MarkerTable")
1621 return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Marker);
1623 if (rServiceName == "com.sun.star.drawing.Defaults")
1625 return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Defaults);
1627 if (rServiceName == "com.sun.star.document.Settings")
1629 return Reference<XInterface>(*new SwXDocumentSettings(this));
1631 if (rServiceName == "com.sun.star.document.ImportEmbeddedObjectResolver")
1633 return static_cast<cppu::OWeakObject *>(
1634 new SvXMLEmbeddedObjectHelper(
1635 *m_pDocShell, SvXMLEmbeddedObjectHelperMode::Read));
1637 if (rServiceName == "com.sun.star.text.DocumentSettings")
1639 return Reference<XInterface>(*new SwXDocumentSettings(this));
1641 if (rServiceName == "com.sun.star.chart2.data.DataProvider")
1643 return Reference<XInterface>(
1644 static_cast<chart2::data::XDataProvider *>(
1645 m_pDocShell->getIDocumentChartDataProviderAccess().
1646 GetChartDataProvider()));
1648 if (!rServiceName.startsWith("com.sun.star.")
1649 || rServiceName.endsWith(".OLE2Shape"))
1651 // We do not want to insert OLE2 Shapes (e.g.,
1652 // "com.sun.star.drawing.OLE2Shape", ...) like this (by creating them
1653 // with the documents factory and adding the shapes to the draw page);
1654 // for inserting OLE objects the proper way is to use
1655 // "com.sun.star.text.TextEmbeddedObject":
1656 throw ServiceNotRegisteredException();
1658 // The XML import is allowed to create instances of
1659 // "com.sun.star.drawing.OLE2Shape"; thus, a temporary service name is
1660 // introduced to make this possible:
1661 OUString aTmpServiceName(rServiceName);
1662 if (rServiceName == "com.sun.star.drawing.temporaryForXMLImportOLE2Shape")
1664 aTmpServiceName = "com.sun.star.drawing.OLE2Shape";
1666 Reference<XInterface> xTmp(
1667 arguments == nullptr
1668 ? SvxFmMSFactory::createInstance(aTmpServiceName)
1669 : SvxFmMSFactory::createInstanceWithArguments(
1670 aTmpServiceName, *arguments));
1671 if (rServiceName == "com.sun.star.drawing.GroupShape"
1672 || rServiceName == "com.sun.star.drawing.Shape3DSceneObject")
1674 return *new SwXGroupShape(xTmp, m_pDocShell->GetDoc());
1676 if (rServiceName.startsWith("com.sun.star.drawing."))
1678 return *new SwXShape(xTmp, m_pDocShell->GetDoc());
1680 return xTmp;
1683 Reference< XInterface > SwXTextDocument::createInstance(const OUString& rServiceName)
1685 return create(rServiceName, nullptr);
1688 Reference< XInterface > SwXTextDocument::createInstanceWithArguments(
1689 const OUString& ServiceSpecifier,
1690 const Sequence< Any >& Arguments)
1692 return create(ServiceSpecifier, &Arguments);
1695 Sequence< OUString > SwXTextDocument::getAvailableServiceNames()
1697 static Sequence< OUString > aServices;
1698 if ( !aServices.hasElements() )
1700 Sequence< OUString > aRet = SvxFmMSFactory::getAvailableServiceNames();
1701 auto i = comphelper::findValue(aRet, "com.sun.star.drawing.OLE2Shape");
1702 if (i != -1)
1704 auto nLength = aRet.getLength();
1705 aRet.getArray()[i] = aRet[nLength - 1];
1706 aRet.realloc( nLength - 1 );
1708 Sequence< OUString > aOwn = SwXServiceProvider::GetAllServiceNames();
1709 aServices = comphelper::concatSequences(aRet, aOwn);
1712 return aServices;
1715 OUString SwXTextDocument::getImplementationName()
1717 return "SwXTextDocument";
1718 /* // Matching the .component information:
1719 return dynamic_cast<SwGlobalDocShell*>( pDocShell ) != nullptr
1720 ? OUString("com.sun.star.comp.Writer.GlobalDocument")
1721 : dynamic_cast<SwWebDocShell*>( pDocShell ) != nullptr
1722 ? OUString("com.sun.star.comp.Writer.WebDocument")
1723 : OUString("com.sun.star.comp.Writer.TextDocument");
1727 sal_Bool SwXTextDocument::supportsService(const OUString& rServiceName)
1729 return cppu::supportsService(this, rServiceName);
1732 Sequence< OUString > SwXTextDocument::getSupportedServiceNames()
1734 bool bWebDoc = (dynamic_cast<SwWebDocShell*>( m_pDocShell) != nullptr );
1735 bool bGlobalDoc = (dynamic_cast<SwGlobalDocShell*>( m_pDocShell) != nullptr );
1736 bool bTextDoc = (!bWebDoc && !bGlobalDoc);
1738 Sequence< OUString > aRet (3);
1739 OUString* pArray = aRet.getArray();
1741 pArray[0] = "com.sun.star.document.OfficeDocument";
1742 pArray[1] = "com.sun.star.text.GenericTextDocument";
1744 if (bTextDoc)
1745 pArray[2] = "com.sun.star.text.TextDocument";
1746 else if (bWebDoc)
1747 pArray[2] = "com.sun.star.text.WebDocument";
1748 else if (bGlobalDoc)
1749 pArray[2] = "com.sun.star.text.GlobalDocument";
1751 return aRet;
1754 Reference< XIndexAccess > SwXTextDocument::getDocumentIndexes()
1756 SolarMutexGuard aGuard;
1757 if(!IsValid())
1758 throw DisposedException("", static_cast< XTextDocument* >(this));
1760 if(!mxXDocumentIndexes.is())
1762 mxXDocumentIndexes = new SwXDocumentIndexes(m_pDocShell->GetDoc());
1764 return mxXDocumentIndexes;
1767 Reference< XPropertySetInfo > SwXTextDocument::getPropertySetInfo()
1769 static Reference< XPropertySetInfo > xRet = m_pPropSet->getPropertySetInfo();
1770 return xRet;
1773 void SwXTextDocument::setPropertyValue(const OUString& rPropertyName, const Any& aValue)
1775 SolarMutexGuard aGuard;
1776 if(!IsValid())
1777 throw DisposedException("", static_cast< XTextDocument* >(this));
1779 const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName);
1781 if(!pEntry)
1782 throw UnknownPropertyException(rPropertyName);
1783 if(pEntry->nFlags & PropertyAttribute::READONLY)
1784 throw PropertyVetoException();
1785 switch(pEntry->nWID)
1787 case WID_DOC_CHAR_COUNT :
1788 case WID_DOC_PARA_COUNT :
1789 case WID_DOC_WORD_COUNT :
1790 throw RuntimeException(
1791 "bad WID",
1792 static_cast< cppu::OWeakObject * >(
1793 static_cast< SwXTextDocumentBaseClass * >(this)));
1794 case WID_DOC_WORD_SEPARATOR :
1796 OUString sDelim;
1797 aValue >>= sDelim;
1798 SW_MOD()->GetModuleConfig()->SetWordDelimiter(sDelim);
1800 break;
1801 case WID_DOC_CHANGES_RECORD:
1802 case WID_DOC_CHANGES_SHOW:
1804 bool bSet = *o3tl::doAccess<bool>(aValue);
1805 RedlineFlags eMode = m_pDocShell->GetDoc()->getIDocumentRedlineAccess().GetRedlineFlags();
1806 if(WID_DOC_CHANGES_SHOW == pEntry->nWID)
1808 eMode |= RedlineFlags(RedlineFlags::ShowInsert | RedlineFlags::ShowDelete);
1809 if( !bSet )
1810 m_pDocShell->GetDoc()->GetDocumentRedlineManager().SetHideRedlines(true);
1812 else if(WID_DOC_CHANGES_RECORD == pEntry->nWID)
1814 eMode = bSet ? eMode|RedlineFlags::On : eMode&~RedlineFlags::On;
1816 m_pDocShell->GetDoc()->getIDocumentRedlineAccess().SetRedlineFlags( eMode );
1818 break;
1819 case WID_DOC_CHANGES_PASSWORD:
1821 Sequence <sal_Int8> aNew;
1822 if(aValue >>= aNew)
1824 SwDoc* pDoc = m_pDocShell->GetDoc();
1825 pDoc->getIDocumentRedlineAccess().SetRedlinePassword(aNew);
1826 if(aNew.hasElements())
1828 RedlineFlags eMode = pDoc->getIDocumentRedlineAccess().GetRedlineFlags();
1829 eMode |= RedlineFlags::On;
1830 pDoc->getIDocumentRedlineAccess().SetRedlineFlags( eMode );
1834 break;
1835 case WID_DOC_AUTO_MARK_URL :
1837 OUString sURL;
1838 aValue >>= sURL;
1839 m_pDocShell->GetDoc()->SetTOIAutoMarkURL(sURL);
1841 break;
1842 case WID_DOC_HIDE_TIPS :
1843 SW_MOD()->GetModuleConfig()->SetHideFieldTips(*o3tl::doAccess<bool>(aValue));
1844 break;
1845 case WID_DOC_REDLINE_DISPLAY:
1847 RedlineFlags eRedMode = m_pDocShell->GetDoc()->getIDocumentRedlineAccess().GetRedlineFlags();
1848 eRedMode = eRedMode & (~RedlineFlags::ShowMask);
1849 sal_Int16 nSet = 0;
1850 aValue >>= nSet;
1851 switch(nSet)
1853 case RedlineDisplayType::NONE: break;
1854 case RedlineDisplayType::INSERTED: eRedMode |= RedlineFlags::ShowInsert; break;
1855 case RedlineDisplayType::REMOVED: eRedMode |= RedlineFlags::ShowDelete; break;
1856 case RedlineDisplayType::
1857 INSERTED_AND_REMOVED: eRedMode |= RedlineFlags::ShowInsert|RedlineFlags::ShowDelete;
1858 break;
1859 default: throw IllegalArgumentException();
1861 m_pDocShell->GetDoc()->getIDocumentRedlineAccess().SetRedlineFlags(eRedMode);
1863 break;
1864 case WID_DOC_TWO_DIGIT_YEAR:
1866 sal_Int16 nYear = 0;
1867 aValue >>= nYear;
1868 SfxRequest aRequest ( SID_ATTR_YEAR2000, SfxCallMode::SLOT, m_pDocShell->GetDoc()->GetAttrPool());
1869 aRequest.AppendItem(SfxUInt16Item( SID_ATTR_YEAR2000, static_cast < sal_uInt16 > ( nYear ) ) );
1870 m_pDocShell->Execute ( aRequest );
1872 break;
1873 case WID_DOC_AUTOMATIC_CONTROL_FOCUS:
1875 SwDrawModel * pDrawDoc = m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
1876 bool bAuto = *o3tl::doAccess<bool>(aValue);
1878 if ( nullptr != pDrawDoc )
1879 pDrawDoc->SetAutoControlFocus( bAuto );
1880 else if (bAuto)
1882 // if setting to true, and we don't have an
1883 // SdrModel, then we are changing the default and
1884 // must thus create an SdrModel, if we don't have an
1885 // SdrModel and we are leaving the default at false,
1886 // we don't need to make an SdrModel and can do nothing
1887 // #i52858# - method name changed
1888 pDrawDoc = m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetOrCreateDrawModel();
1889 pDrawDoc->SetAutoControlFocus ( bAuto );
1892 break;
1893 case WID_DOC_APPLY_FORM_DESIGN_MODE:
1895 SwDrawModel * pDrawDoc = m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
1896 bool bMode = *o3tl::doAccess<bool>(aValue);
1898 if ( nullptr != pDrawDoc )
1899 pDrawDoc->SetOpenInDesignMode( bMode );
1900 else if (!bMode)
1902 // if setting to false, and we don't have an
1903 // SdrModel, then we are changing the default and
1904 // must thus create an SdrModel, if we don't have an
1905 // SdrModel and we are leaving the default at true,
1906 // we don't need to make an SdrModel and can do
1907 // nothing
1908 // #i52858# - method name changed
1909 pDrawDoc = m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetOrCreateDrawModel();
1910 pDrawDoc->SetOpenInDesignMode ( bMode );
1913 break;
1914 // #i42634# New property to set the bInReading
1915 // flag at the document, used during binary import
1916 case WID_DOC_LOCK_UPDATES :
1918 SwDoc* pDoc = m_pDocShell->GetDoc();
1919 bool bBool (false);
1920 if( aValue >>= bBool )
1922 pDoc->SetInReading( bBool );
1925 break;
1926 case WID_DOC_WRITERFILTER:
1928 SwDoc* pDoc = m_pDocShell->GetDoc();
1929 bool bBool = {};
1930 if (aValue >>= bBool)
1931 { // HACK: writerfilter has to use API to set this :(
1932 bool bOld = pDoc->IsInWriterfilterImport();
1933 pDoc->SetInWriterfilterImport(bBool);
1934 if (bOld && !bBool)
1936 pDoc->getIDocumentFieldsAccess().SetFieldsDirty(false, nullptr, SwNodeOffset(0));
1940 break;
1941 case WID_DOC_BUILDID:
1942 aValue >>= maBuildId;
1943 break;
1945 case WID_DOC_DEFAULT_PAGE_MODE:
1947 bool bDefaultPageMode( false );
1948 aValue >>= bDefaultPageMode;
1949 m_pDocShell->GetDoc()->SetDefaultPageMode( bDefaultPageMode );
1951 break;
1952 case WID_DOC_INTEROP_GRAB_BAG:
1953 setGrabBagItem(aValue);
1954 break;
1956 default:
1958 const SfxPoolItem& rItem = m_pDocShell->GetDoc()->GetDefault(pEntry->nWID);
1959 std::unique_ptr<SfxPoolItem> pNewItem(rItem.Clone());
1960 pNewItem->PutValue(aValue, pEntry->nMemberId);
1961 m_pDocShell->GetDoc()->SetDefault(*pNewItem);
1966 Any SwXTextDocument::getPropertyValue(const OUString& rPropertyName)
1968 SolarMutexGuard aGuard;
1969 if(!IsValid())
1970 throw DisposedException("", static_cast< XTextDocument* >(this));
1972 if (rPropertyName == "ODFExport_ListNodes")
1974 // A hack to avoid writing random list ids to ODF when they are not referred later
1975 // see XMLTextParagraphExport::DocumentListNodes ctor
1977 // Sequence of nodes, each of them represented by three-element sequence:
1978 // [ index, styleIntPtr, list_id ]
1979 std::vector<css::uno::Sequence<css::uno::Any>> nodes;
1981 const SwDoc& rDoc = *m_pDocShell->GetDoc();
1982 for (const SwNumRule* pNumRule : rDoc.GetNumRuleTable())
1984 SwNumRule::tTextNodeList textNodes;
1985 pNumRule->GetTextNodeList(textNodes);
1986 css::uno::Any styleIntPtr(reinterpret_cast<sal_uInt64>(pNumRule));
1988 for (const SwTextNode* pTextNode : textNodes)
1990 css::uno::Any index(pTextNode->GetIndex().get());
1991 css::uno::Any list_id(pTextNode->GetListId());
1993 nodes.push_back({ index, styleIntPtr, list_id });
1996 return css::uno::Any(comphelper::containerToSequence(nodes));
1999 const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName);
2001 if(!pEntry)
2002 throw UnknownPropertyException(rPropertyName);
2003 Any aAny;
2004 switch(pEntry->nWID)
2006 case WID_DOC_ISTEMPLATEID :
2007 aAny <<= m_pDocShell->IsTemplate();
2008 break;
2009 case WID_DOC_CHAR_COUNT :
2010 case WID_DOC_PARA_COUNT :
2011 case WID_DOC_WORD_COUNT :
2013 const SwDocStat& rStat(m_pDocShell->GetDoc()->getIDocumentStatistics().GetUpdatedDocStat( false, true ));
2014 sal_Int32 nValue;
2015 switch(pEntry->nWID)
2017 case WID_DOC_CHAR_COUNT :nValue = rStat.nChar;break;
2018 case WID_DOC_PARA_COUNT :nValue = rStat.nPara;break;
2019 case WID_DOC_WORD_COUNT :nValue = rStat.nWord;break;
2021 aAny <<= nValue;
2023 break;
2024 case WID_DOC_WORD_SEPARATOR :
2026 aAny <<= SW_MOD()->GetDocStatWordDelim();
2028 break;
2029 case WID_DOC_CHANGES_RECORD:
2030 case WID_DOC_CHANGES_SHOW:
2032 const RedlineFlags eMode = m_pDocShell->GetDoc()->getIDocumentRedlineAccess().GetRedlineFlags();
2033 bool bSet = false;
2034 if(WID_DOC_CHANGES_SHOW == pEntry->nWID)
2036 bSet = IDocumentRedlineAccess::IsShowChanges(eMode);
2038 else if(WID_DOC_CHANGES_RECORD == pEntry->nWID)
2040 bSet = bool(eMode & RedlineFlags::On);
2042 aAny <<= bSet;
2044 break;
2045 case WID_DOC_CHANGES_PASSWORD:
2047 SwDoc* pDoc = m_pDocShell->GetDoc();
2048 aAny <<= pDoc->getIDocumentRedlineAccess().GetRedlinePassword();
2050 break;
2051 case WID_DOC_AUTO_MARK_URL :
2052 aAny <<= m_pDocShell->GetDoc()->GetTOIAutoMarkURL();
2053 break;
2054 case WID_DOC_HIDE_TIPS :
2055 aAny <<= SW_MOD()->GetModuleConfig()->IsHideFieldTips();
2056 break;
2057 case WID_DOC_REDLINE_DISPLAY:
2059 RedlineFlags eRedMode = m_pDocShell->GetDoc()->getIDocumentRedlineAccess().GetRedlineFlags();
2060 eRedMode = eRedMode & RedlineFlags::ShowMask;
2061 sal_Int16 nRet = RedlineDisplayType::NONE;
2062 if(RedlineFlags::ShowInsert == eRedMode)
2063 nRet = RedlineDisplayType::INSERTED;
2064 else if(RedlineFlags::ShowDelete == eRedMode)
2065 nRet = RedlineDisplayType::REMOVED;
2066 else if(RedlineFlags::ShowMask == eRedMode)
2067 nRet = RedlineDisplayType::INSERTED_AND_REMOVED;
2068 aAny <<= nRet;
2070 break;
2071 case WID_DOC_FORBIDDEN_CHARS:
2073 GetPropertyHelper();
2074 Reference<XForbiddenCharacters> xRet = mxPropertyHelper;
2075 aAny <<= xRet;
2077 break;
2078 case WID_DOC_TWO_DIGIT_YEAR:
2080 aAny <<= static_cast < sal_Int16 > (m_pDocShell->GetDoc()->GetNumberFormatter ()->GetYear2000());
2082 break;
2083 case WID_DOC_AUTOMATIC_CONTROL_FOCUS:
2085 SwDrawModel * pDrawDoc = m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
2086 bool bAuto;
2087 if ( nullptr != pDrawDoc )
2088 bAuto = pDrawDoc->GetAutoControlFocus();
2089 else
2090 bAuto = false;
2091 aAny <<= bAuto;
2093 break;
2094 case WID_DOC_APPLY_FORM_DESIGN_MODE:
2096 SwDrawModel * pDrawDoc = m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
2097 bool bMode;
2098 if ( nullptr != pDrawDoc )
2099 bMode = pDrawDoc->GetOpenInDesignMode();
2100 else
2101 bMode = true;
2102 aAny <<= bMode;
2104 break;
2105 case WID_DOC_BASIC_LIBRARIES:
2106 aAny <<= m_pDocShell->GetBasicContainer();
2107 break;
2108 case WID_DOC_DIALOG_LIBRARIES:
2109 aAny <<= m_pDocShell->GetDialogContainer();
2110 break;
2111 case WID_DOC_VBA_DOCOBJ:
2113 /* #i111553# This property provides the name of the constant that
2114 will be used to store this model in the global Basic manager.
2115 That constant will be equivalent to 'ThisComponent' but for
2116 each application, so e.g. a 'ThisExcelDoc' and a 'ThisWordDoc'
2117 constant can co-exist, as required by VBA. */
2118 aAny <<= OUString( "ThisWordDoc" );
2120 break;
2121 case WID_DOC_RUNTIME_UID:
2122 aAny <<= getRuntimeUID();
2123 break;
2124 case WID_DOC_LOCK_UPDATES :
2125 aAny <<= m_pDocShell->GetDoc()->IsInReading();
2126 break;
2127 case WID_DOC_BUILDID:
2128 aAny <<= maBuildId;
2129 break;
2130 case WID_DOC_HAS_VALID_SIGNATURES:
2131 aAny <<= hasValidSignatures();
2132 break;
2133 case WID_DOC_INTEROP_GRAB_BAG:
2134 getGrabBagItem(aAny);
2135 break;
2137 default:
2139 const SfxPoolItem& rItem = m_pDocShell->GetDoc()->GetDefault(pEntry->nWID);
2140 rItem.QueryValue(aAny, pEntry->nMemberId);
2143 return aAny;
2146 void SwXTextDocument::addPropertyChangeListener(const OUString& /*PropertyName*/,
2147 const Reference< XPropertyChangeListener > & /*aListener*/)
2149 OSL_FAIL("not implemented");
2152 void SwXTextDocument::removePropertyChangeListener(const OUString& /*PropertyName*/,
2153 const Reference< XPropertyChangeListener > & /*aListener*/)
2155 OSL_FAIL("not implemented");
2158 void SwXTextDocument::addVetoableChangeListener(const OUString& /*PropertyName*/,
2159 const Reference< XVetoableChangeListener > & /*aListener*/)
2161 OSL_FAIL("not implemented");
2164 void SwXTextDocument::removeVetoableChangeListener(const OUString& /*PropertyName*/,
2165 const Reference< XVetoableChangeListener > & /*aListener*/)
2167 OSL_FAIL("not implemented");
2170 Reference< XNameAccess > SwXTextDocument::getLinks()
2172 if(!mxLinkTargetSupplier.is())
2174 mxLinkTargetSupplier = new SwXLinkTargetSupplier(*this);
2176 return mxLinkTargetSupplier;
2179 Reference< XEnumerationAccess > SwXTextDocument::getRedlines( )
2181 if(!mxXRedlines.is())
2183 mxXRedlines = new SwXRedlines(m_pDocShell->GetDoc());
2185 return mxXRedlines;
2188 void SwXTextDocument::NotifyRefreshListeners()
2190 // why does SwBaseShell not just call refresh? maybe because it's rSh is
2191 // (sometimes) a different shell than GetWrtShell()?
2192 lang::EventObject const ev(static_cast<SwXTextDocumentBaseClass &>(*this));
2193 std::unique_lock aGuard(m_pImpl->m_Mutex);
2194 m_pImpl->m_RefreshListeners.notifyEach(aGuard,
2195 & util::XRefreshListener::refreshed, ev);
2198 void SwXTextDocument::refresh()
2200 SolarMutexGuard aGuard;
2201 if(!IsValid())
2202 throw DisposedException("", static_cast< XTextDocument* >(this));
2204 SwViewShell *pViewShell = m_pDocShell->GetWrtShell();
2205 NotifyRefreshListeners();
2206 if(pViewShell)
2207 pViewShell->Reformat();
2210 void SAL_CALL SwXTextDocument::addRefreshListener(
2211 const Reference<util::XRefreshListener> & xListener)
2213 if (xListener)
2215 std::unique_lock aGuard(m_pImpl->m_Mutex);
2216 m_pImpl->m_RefreshListeners.addInterface(aGuard, xListener);
2220 void SAL_CALL SwXTextDocument::removeRefreshListener(
2221 const Reference<util::XRefreshListener> & xListener)
2223 if (xListener)
2225 std::unique_lock aGuard(m_pImpl->m_Mutex);
2226 m_pImpl->m_RefreshListeners.removeInterface(aGuard, xListener);
2230 void SwXTextDocument::updateLinks( )
2232 SolarMutexGuard aGuard;
2233 if(!IsValid())
2234 throw DisposedException("", static_cast< XTextDocument* >(this));
2236 SwDoc* pDoc = m_pDocShell->GetDoc();
2237 sfx2::LinkManager& rLnkMan = pDoc->getIDocumentLinksAdministration().GetLinkManager();
2238 if( !rLnkMan.GetLinks().empty() )
2240 UnoActionContext aAction(pDoc);
2241 rLnkMan.UpdateAllLinks( false, true, nullptr );
2245 //XPropertyState
2246 PropertyState SAL_CALL SwXTextDocument::getPropertyState( const OUString& rPropertyName )
2248 SolarMutexGuard aGuard;
2249 if(!IsValid())
2250 throw DisposedException("", static_cast< XTextDocument* >(this));
2252 const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName);
2253 if(!pEntry)
2254 throw UnknownPropertyException(rPropertyName);
2255 return PropertyState_DIRECT_VALUE;
2258 Sequence< PropertyState > SAL_CALL SwXTextDocument::getPropertyStates( const Sequence< OUString >& rPropertyNames )
2260 const sal_Int32 nCount = rPropertyNames.getLength();
2261 Sequence < PropertyState > aRet ( nCount );
2263 std::transform(rPropertyNames.begin(), rPropertyNames.end(), aRet.getArray(),
2264 [this](const OUString& rName) -> PropertyState { return getPropertyState(rName); });
2266 return aRet;
2269 void SAL_CALL SwXTextDocument::setPropertyToDefault( const OUString& rPropertyName )
2271 SolarMutexGuard aGuard;
2272 if(!IsValid())
2273 throw DisposedException("", static_cast< XTextDocument* >(this));
2275 const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName);
2276 if(!pEntry)
2277 throw UnknownPropertyException(rPropertyName);
2278 switch(pEntry->nWID)
2280 case 0:default:break;
2284 Any SAL_CALL SwXTextDocument::getPropertyDefault( const OUString& rPropertyName )
2286 SolarMutexGuard aGuard;
2287 if(!IsValid())
2288 throw DisposedException("", static_cast< XTextDocument* >(this));
2290 const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName);
2291 if(!pEntry)
2292 throw UnknownPropertyException(rPropertyName);
2293 Any aAny;
2294 switch(pEntry->nWID)
2296 case 0:default:break;
2298 return aAny;
2301 static VclPtr< OutputDevice > lcl_GetOutputDevice( const SwPrintUIOptions &rPrintUIOptions )
2303 VclPtr< OutputDevice > pOut;
2305 uno::Any aAny( rPrintUIOptions.getValue( "RenderDevice" ));
2306 uno::Reference< awt::XDevice > xRenderDevice;
2307 aAny >>= xRenderDevice;
2308 if (xRenderDevice.is())
2310 VCLXDevice* pDevice = dynamic_cast<VCLXDevice*>( xRenderDevice.get() );
2311 pOut = pDevice ? pDevice->GetOutputDevice() : VclPtr< OutputDevice >();
2314 return pOut;
2317 static bool lcl_SeqHasProperty(
2318 const uno::Sequence< beans::PropertyValue >& rOptions,
2319 const char *pPropName )
2321 return std::any_of(rOptions.begin(), rOptions.end(),
2322 [&pPropName](const beans::PropertyValue& rProp) {
2323 return rProp.Name.equalsAscii( pPropName ); });
2326 static bool lcl_GetBoolProperty(
2327 const uno::Sequence< beans::PropertyValue >& rOptions,
2328 const char *pPropName )
2330 bool bRes = false;
2331 auto pOption = std::find_if(rOptions.begin(), rOptions.end(),
2332 [&pPropName](const beans::PropertyValue& rProp) {
2333 return rProp.Name.equalsAscii( pPropName ); });
2334 if (pOption != rOptions.end())
2335 pOption->Value >>= bRes;
2336 return bRes;
2339 SfxViewShell * SwXTextDocument::GetRenderView(
2340 bool &rbIsSwSrcView,
2341 const uno::Sequence< beans::PropertyValue >& rOptions,
2342 bool bIsPDFExport )
2344 // get view shell to use
2345 SfxViewShell *pView = nullptr;
2346 if (bIsPDFExport)
2347 pView = GuessViewShell( rbIsSwSrcView );
2348 else
2350 uno::Any aTmp;
2351 auto pOption = std::find_if(rOptions.begin(), rOptions.end(),
2352 [](const beans::PropertyValue& rProp) { return rProp.Name == "View"; });
2353 if (pOption != rOptions.end())
2354 aTmp = pOption->Value;
2356 uno::Reference< frame::XController > xController;
2357 if (aTmp >>= xController)
2359 OSL_ENSURE( xController.is(), "controller is empty!" );
2360 pView = GuessViewShell( rbIsSwSrcView, xController );
2363 return pView;
2367 * GetRenderDoc:
2368 * returns the document to be rendered, usually this will be the 'regular'
2369 * document but in case of PDF export of (multi-)selection it will
2370 * be a temporary document that gets created if not already done.
2371 * The rpView variable will be set (if not already done) to the used
2372 * SfxViewShell.
2374 SwDoc * SwXTextDocument::GetRenderDoc(
2375 SfxViewShell *&rpView,
2376 const uno::Any& rSelection,
2377 bool bIsPDFExport )
2379 SwDoc *pDoc = nullptr;
2381 uno::Reference< frame::XModel > xModel;
2382 rSelection >>= xModel;
2383 if (xModel == m_pDocShell->GetModel())
2384 pDoc = m_pDocShell->GetDoc();
2385 else
2387 OSL_ENSURE( !xModel.is(), "unexpected model found" );
2389 if (rSelection.hasValue()) // is anything selected ?
2391 // this part should only be called when a temporary document needs to be created,
2392 // for example for PDF export or printing of (multi-)selection only.
2394 if (!rpView)
2396 bool bIsSwSrcView = false;
2397 // aside from maybe PDF export the view should always have been provided!
2398 OSL_ENSURE( bIsPDFExport, "view is missing, guessing one..." );
2400 rpView = GuessViewShell( bIsSwSrcView );
2402 OSL_ENSURE( rpView, "SwViewShell missing" );
2403 // the view shell should be SwView for documents PDF export.
2404 // for the page preview no selection should be possible
2405 // (the export dialog does not allow for this option)
2406 if (auto pSwView = dynamic_cast<SwView *>( rpView ))
2408 if (!m_pRenderData)
2410 OSL_FAIL("GetRenderDoc: no renderdata");
2411 return nullptr;
2413 SfxObjectShellLock xDocSh(m_pRenderData->GetTempDocShell());
2414 if (!xDocSh.Is())
2416 xDocSh = pSwView->CreateTmpSelectionDoc();
2417 m_pRenderData->SetTempDocShell(xDocSh);
2419 if (xDocSh.Is())
2421 pDoc = static_cast<SwDocShell*>(&xDocSh)->GetDoc();
2422 rpView = pDoc->GetDocShell()->GetView();
2425 else
2427 OSL_FAIL("unexpected SwViewShell" );
2431 return pDoc;
2434 static void lcl_SavePrintUIOptionsToDocumentPrintData(
2435 SwDoc &rDoc,
2436 const SwPrintUIOptions &rPrintUIOptions,
2437 bool bIsPDFEXport )
2439 SwPrintData aDocPrintData( rDoc.getIDocumentDeviceAccess().getPrintData() );
2441 aDocPrintData.SetPrintGraphic( rPrintUIOptions.IsPrintGraphics() );
2442 aDocPrintData.SetPrintTable( true ); // for now it was decided that tables should always be printed
2443 aDocPrintData.SetPrintDraw( rPrintUIOptions.IsPrintDrawings() );
2444 aDocPrintData.SetPrintControl( rPrintUIOptions.IsPrintFormControls() );
2445 aDocPrintData.SetPrintLeftPage( rPrintUIOptions.IsPrintLeftPages() );
2446 aDocPrintData.SetPrintRightPage( rPrintUIOptions.IsPrintRightPages() );
2447 aDocPrintData.SetPrintReverse( false ); /*handled by print dialog now*/
2448 aDocPrintData.SetPaperFromSetup( rPrintUIOptions.IsPaperFromSetup() );
2449 aDocPrintData.SetPrintEmptyPages( rPrintUIOptions.IsPrintEmptyPages( bIsPDFEXport ) );
2450 aDocPrintData.SetPrintPostIts( rPrintUIOptions.GetPrintPostItsType() );
2451 aDocPrintData.SetPrintProspect( rPrintUIOptions.IsPrintProspect() );
2452 aDocPrintData.SetPrintProspect_RTL( rPrintUIOptions.IsPrintProspectRTL() );
2453 aDocPrintData.SetPrintPageBackground( rPrintUIOptions.IsPrintPageBackground() );
2454 aDocPrintData.SetPrintBlackFont( rPrintUIOptions.IsPrintWithBlackTextColor() );
2455 // aDocPrintData.SetPrintSingleJobs( b ); handled by File/Print dialog itself
2456 // arDocPrintData.SetFaxName( s ); n/a in File/Print dialog
2457 aDocPrintData.SetPrintHiddenText( rPrintUIOptions.IsPrintHiddenText() );
2458 aDocPrintData.SetPrintTextPlaceholder( rPrintUIOptions.IsPrintTextPlaceholders() );
2460 rDoc.getIDocumentDeviceAccess().setPrintData( aDocPrintData );
2463 sal_Int32 SAL_CALL SwXTextDocument::getRendererCount(
2464 const uno::Any& rSelection,
2465 const uno::Sequence< beans::PropertyValue >& rxOptions )
2467 SolarMutexGuard aGuard;
2468 if(!IsValid())
2470 throw DisposedException( OUString(),
2471 static_cast< XTextDocument* >(this) );
2474 const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" );
2475 bool bIsSwSrcView = false;
2476 SfxViewShell *pView = GetRenderView( bIsSwSrcView, rxOptions, bIsPDFExport );
2478 if (!bIsSwSrcView && !m_pRenderData)
2479 m_pRenderData.reset(new SwRenderData);
2480 if (!m_pPrintUIOptions)
2481 m_pPrintUIOptions = lcl_GetPrintUIOptions( m_pDocShell, pView );
2482 bool bFormat = m_pPrintUIOptions->processPropertiesAndCheckFormat( rxOptions );
2484 SwDoc *pDoc = GetRenderDoc( pView, rSelection, bIsPDFExport );
2485 OSL_ENSURE( pDoc && pView, "doc or view shell missing!" );
2486 if (!pDoc || !pView)
2487 return 0;
2489 // save current UI options from the print dialog for the next call to that dialog
2490 lcl_SavePrintUIOptionsToDocumentPrintData( *pDoc, *m_pPrintUIOptions, bIsPDFExport );
2492 sal_Int32 nRet = 0;
2493 if (bIsSwSrcView)
2495 SwSrcView& rSwSrcView = dynamic_cast<SwSrcView&>(*pView);
2496 VclPtr< OutputDevice> pOutDev = lcl_GetOutputDevice( *m_pPrintUIOptions );
2497 nRet = rSwSrcView.PrintSource( pOutDev, 1 /* dummy */, true /* get page count only */ );
2499 else
2501 SwDocShell *pRenderDocShell = pDoc->GetDocShell();
2503 // TODO/mba: we really need a generic way to get the SwViewShell!
2504 SwViewShell* pViewShell = nullptr;
2505 SwView* pSwView = dynamic_cast<SwView*>( pView );
2506 if ( pSwView )
2508 pViewShell = pSwView->GetWrtShellPtr();
2510 else
2512 if ( bIsPDFExport && bFormat )
2514 //create a hidden view to be able to export as PDF also in print preview
2515 //pView and pSwView are not changed intentionally!
2516 m_pHiddenViewFrame = SfxViewFrame::LoadHiddenDocument( *pRenderDocShell, SFX_INTERFACE_SFXDOCSH );
2517 pViewShell = static_cast<SwView*>(m_pHiddenViewFrame->GetViewShell())->GetWrtShellPtr();
2519 else
2520 pViewShell = static_cast<SwPagePreview*>(pView)->GetViewShell();
2523 if (!pViewShell || !pViewShell->GetLayout())
2524 return 0;
2526 if (bFormat)
2528 // #i38289
2529 if( pViewShell->GetViewOptions()->getBrowseMode() ||
2530 pViewShell->GetViewOptions()->IsWhitespaceHidden() )
2532 SwViewOption aOpt( *pViewShell->GetViewOptions() );
2533 aOpt.setBrowseMode( false );
2534 aOpt.SetHideWhitespaceMode( false );
2535 pViewShell->ApplyViewOptions( aOpt );
2536 if (pSwView)
2538 pSwView->RecheckBrowseMode();
2542 // reformatting the document for printing will show the changes in the view
2543 // which is likely to produce many unwanted and not nice to view actions.
2544 // We don't want that! Thus we disable updating of the view.
2545 pViewShell->StartAction();
2547 if (pSwView)
2549 if (m_pRenderData && m_pRenderData->NeedNewViewOptionAdjust( *pViewShell ) )
2550 m_pRenderData->ViewOptionAdjustStop();
2551 if (m_pRenderData && !m_pRenderData->IsViewOptionAdjust())
2553 m_pRenderData->ViewOptionAdjustStart(
2554 *pViewShell, *pViewShell->GetViewOptions() );
2558 m_pRenderData->MakeSwPrtOptions( pRenderDocShell,
2559 m_pPrintUIOptions.get(), bIsPDFExport );
2561 if (pSwView)
2563 // PDF export should not make use of the SwPrtOptions
2564 const SwPrintData *pPrtOptions = bIsPDFExport
2565 ? nullptr : m_pRenderData->GetSwPrtOptions();
2566 bool setShowPlaceHoldersInPDF = false;
2567 if(bIsPDFExport)
2568 setShowPlaceHoldersInPDF = lcl_GetBoolProperty( rxOptions, "ExportPlaceholders" );
2569 m_pRenderData->ViewOptionAdjust( pPrtOptions, setShowPlaceHoldersInPDF );
2572 // since printing now also use the API for PDF export this option
2573 // should be set for printing as well ...
2574 pViewShell->SetPDFExportOption( true );
2576 // there is some redundancy between those two function calls, but right now
2577 // there is no time to sort this out.
2578 //TODO: check what exactly needs to be done and make just one function for that
2579 pViewShell->CalcLayout();
2581 // #122919# Force field update before PDF export, but after layout init (tdf#121962)
2582 bool bStateChanged = false;
2583 // check configuration: shall update of printing information in DocInfo set the document to "modified"?
2584 if (pRenderDocShell->IsEnableSetModified() && !utl::ConfigManager::IsFuzzing() && !officecfg::Office::Common::Print::PrintingModifiesDocument::get())
2586 pRenderDocShell->EnableSetModified( false );
2587 bStateChanged = true;
2589 pViewShell->SwViewShell::UpdateFields(true);
2590 if( bStateChanged )
2591 pRenderDocShell->EnableSetModified();
2593 pViewShell->CalcPagesForPrint( pViewShell->GetPageCount() );
2595 pViewShell->SetPDFExportOption( false );
2597 // enable view again
2598 pViewShell->EndAction();
2601 const sal_Int32 nPageCount = pViewShell->GetPageCount();
2603 // get number of pages to be rendered
2605 const bool bPrintProspect = m_pPrintUIOptions->getBoolValue( "PrintProspect" );
2606 if (bPrintProspect)
2608 SwDoc::CalculatePagePairsForProspectPrinting( *pViewShell->GetLayout(), *m_pRenderData, *m_pPrintUIOptions, nPageCount );
2609 nRet = m_pRenderData->GetPagePairsForProspectPrinting().size();
2611 else
2613 const SwPostItMode nPostItMode = static_cast<SwPostItMode>( m_pPrintUIOptions->getIntValue( "PrintAnnotationMode", 0 ) );
2614 if (nPostItMode != SwPostItMode::NONE)
2616 VclPtr< OutputDevice > pOutDev = lcl_GetOutputDevice( *m_pPrintUIOptions );
2617 m_pRenderData->CreatePostItData(*pDoc, pViewShell->GetViewOptions(), pOutDev);
2620 // get set of valid document pages (according to the current settings)
2621 // and their start frames
2622 SwDoc::CalculatePagesForPrinting( *pViewShell->GetLayout(), *m_pRenderData, *m_pPrintUIOptions, bIsPDFExport, nPageCount );
2624 if (nPostItMode != SwPostItMode::NONE)
2626 SwDoc::UpdatePagesForPrintingWithPostItData( *m_pRenderData,
2627 *m_pPrintUIOptions, nPageCount );
2630 nRet = m_pRenderData->GetPagesToPrint().size();
2633 OSL_ENSURE( nRet >= 0, "negative number of pages???" );
2634 // tdf#144989 the layout is complete now - prevent DoIdleJobs() from
2635 // messing it up, particulary SwDocUpdateField::MakeFieldList_() unhiding
2636 // sections
2637 pDoc->getIDocumentTimerAccess().BlockIdling();
2639 return nRet;
2642 uno::Sequence< beans::PropertyValue > SAL_CALL SwXTextDocument::getRenderer(
2643 sal_Int32 nRenderer,
2644 const uno::Any& rSelection,
2645 const uno::Sequence< beans::PropertyValue >& rxOptions )
2647 SolarMutexGuard aGuard;
2648 if(!IsValid())
2650 throw DisposedException("", static_cast< XTextDocument* >(this));
2653 const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" );
2654 bool bIsSwSrcView = false;
2655 SfxViewShell *pView = GetRenderView( bIsSwSrcView, rxOptions, bIsPDFExport );
2657 // m_pRenderData should NOT be created here!
2658 // That should only be done in getRendererCount. If this function is called before
2659 // getRendererCount was called then the caller will probably just retrieve the extra UI options
2660 // and is not interested in getting valid information about the other data that would
2661 // otherwise be provided here!
2662 // if( ! m_pRenderData )
2663 // m_pRenderData = new SwRenderData;
2664 if (!m_pPrintUIOptions)
2665 m_pPrintUIOptions = lcl_GetPrintUIOptions( m_pDocShell, pView );
2666 m_pPrintUIOptions->processProperties( rxOptions );
2667 const bool bPrintProspect = m_pPrintUIOptions->getBoolValue( "PrintProspect" );
2668 const bool bIsSkipEmptyPages = !m_pPrintUIOptions->IsPrintEmptyPages( bIsPDFExport );
2669 const bool bPrintPaperFromSetup = m_pPrintUIOptions->getBoolValue( "PrintPaperFromSetup" );
2671 SwDoc *pDoc = GetRenderDoc( pView, rSelection, bIsPDFExport );
2672 OSL_ENSURE( pDoc && pView, "doc or view shell missing!" );
2673 if (!pDoc || !pView)
2674 return uno::Sequence< beans::PropertyValue >();
2676 // due to #110067# (document page count changes sometimes during
2677 // PDF export/printing) we can not check for the upper bound properly.
2678 // Thus instead of throwing the exception we silently return.
2679 if (0 > nRenderer)
2680 throw IllegalArgumentException();
2682 sal_Int32 nMaxRenderer = 0;
2683 if (!bIsSwSrcView && m_pRenderData)
2685 OSL_ENSURE( m_pRenderData, "m_pRenderData missing!!" );
2686 nMaxRenderer = bPrintProspect?
2687 m_pRenderData->GetPagePairsForProspectPrinting().size() - 1 :
2688 m_pRenderData->GetPagesToPrint().size() - 1;
2690 // since SwSrcView::PrintSource is a poor implementation to get the number of pages to print
2691 // we obmit checking of the upper bound in this case.
2692 if (!bIsSwSrcView && m_pRenderData && nRenderer > nMaxRenderer)
2693 return uno::Sequence< beans::PropertyValue >();
2695 uno::Sequence< beans::PropertyValue > aRenderer;
2696 if (m_pRenderData)
2698 // #i114210#
2699 // determine the correct page number from the renderer index
2700 // #i114875
2701 // consider brochure print
2702 const sal_Int32 nPage = bPrintProspect
2703 ? nRenderer + 1
2704 : m_pRenderData->GetPagesToPrint()[ nRenderer ];
2706 // get paper tray to use ...
2707 sal_Int32 nPrinterPaperTray = -1;
2708 if (! bPrintPaperFromSetup)
2710 // ... from individual page style (see the page tab in Format/Page dialog)
2711 const std::map< sal_Int32, sal_Int32 > &rPaperTrays = m_pRenderData->GetPrinterPaperTrays();
2712 std::map< sal_Int32, sal_Int32 >::const_iterator aIt( rPaperTrays.find( nPage ) );
2713 if (aIt != rPaperTrays.end())
2714 nPrinterPaperTray = aIt->second;
2717 awt::Size aPageSize;
2718 awt::Point aPagePos;
2719 awt::Size aPreferredPageSize;
2720 Size aTmpSize;
2721 if (bIsSwSrcView || bPrintProspect)
2723 // for printing of HTML source code and prospect printing we should use
2724 // the printers paper size since
2725 // a) HTML source view has no page size
2726 // b) prospect printing has a different page size from the documents page
2727 // since two document pages will get rendered on one printer page
2729 // since PageIncludesNonprintableArea will be set to true we can return the
2730 // printers paper size here.
2731 // Sometimes 'getRenderer' is only called to get "ExtraPrintUIOptions", in this
2732 // case we won't get an OutputDevice here, but then the caller also has no need
2733 // for the correct PageSize right now...
2734 VclPtr< Printer > pPrinter = dynamic_cast< Printer * >(lcl_GetOutputDevice( *m_pPrintUIOptions ).get());
2735 if (pPrinter)
2737 // HTML source view and prospect adapt to the printer's paper size
2738 aTmpSize = pPrinter->GetPaperSize();
2739 aTmpSize = OutputDevice::LogicToLogic( aTmpSize,
2740 pPrinter->GetMapMode(), MapMode( MapUnit::Map100thMM ));
2741 aPageSize = awt::Size( aTmpSize.Width(), aTmpSize.Height() );
2742 #if 0
2743 // #i115048# it seems users didn't like getting double the formatted page size
2744 // revert to "old" behavior scaling to the current paper size of the printer
2745 if (bPrintProspect)
2747 // we just state what output size we would need
2748 // which may cause vcl to set that page size on the printer
2749 // (if available and not overridden by the user)
2750 aTmpSize = pVwSh->GetPageSize( nPage, bIsSkipEmptyPages );
2751 aPreferredPageSize = awt::Size ( convertTwipToMm100( 2 * aTmpSize.Width() ),
2752 convertTwipToMm100( aTmpSize.Height() ));
2754 #else
2755 if( bPrintProspect )
2757 // just switch to an appropriate portrait/landscape format
2758 // FIXME: brochure printing with landscape pages puts the
2759 // pages next to each other, so landscape is currently always
2760 // the better choice
2761 if( aPageSize.Width < aPageSize.Height )
2763 aPreferredPageSize.Width = aPageSize.Height;
2764 aPreferredPageSize.Height = aPageSize.Width;
2767 #endif
2770 else
2772 // TODO/mba: we really need a generic way to get the SwViewShell!
2773 SwViewShell* pVwSh = nullptr;
2774 SwView* pSwView = dynamic_cast<SwView*>( pView );
2775 if ( pSwView )
2776 pVwSh = pSwView->GetWrtShellPtr();
2777 else
2778 pVwSh = static_cast<SwPagePreview*>(pView)->GetViewShell();
2780 if (pVwSh)
2782 aTmpSize = pVwSh->GetPageSize( nPage, bIsSkipEmptyPages );
2783 aPageSize = awt::Size ( convertTwipToMm100( aTmpSize.Width() ),
2784 convertTwipToMm100( aTmpSize.Height() ));
2785 Point aPoint = pVwSh->GetPagePos(nPage);
2786 aPagePos = awt::Point(convertTwipToMm100(aPoint.X()), convertTwipToMm100(aPoint.Y()));
2790 sal_Int32 nLen = 3;
2791 aRenderer = { comphelper::makePropertyValue("PageSize", aPageSize),
2792 comphelper::makePropertyValue("PageIncludesNonprintableArea", true),
2793 comphelper::makePropertyValue("PagePos", aPagePos) };
2794 if (aPreferredPageSize.Width && aPreferredPageSize.Height)
2796 ++nLen;
2797 aRenderer.realloc( nLen );
2798 auto pRenderer = aRenderer.getArray();
2799 pRenderer[ nLen - 1 ].Name = "PreferredPageSize";
2800 pRenderer[ nLen - 1 ].Value <<= aPreferredPageSize;
2802 if (nPrinterPaperTray >= 0)
2804 ++nLen;
2805 aRenderer.realloc( nLen );
2806 auto pRenderer = aRenderer.getArray();
2807 pRenderer[ nLen - 1 ].Name = "PrinterPaperTray";
2808 pRenderer[ nLen - 1 ].Value <<= nPrinterPaperTray;
2812 // #i117783#
2813 if ( m_bApplyPagePrintSettingsFromXPagePrintable )
2815 const SwPagePreviewPrtData* pPagePrintSettings =
2816 m_pDocShell->GetDoc()->GetPreviewPrtData();
2817 if ( pPagePrintSettings &&
2818 ( pPagePrintSettings->GetRow() > 1 ||
2819 pPagePrintSettings->GetCol() > 1 ) )
2821 // extend render data by page print settings attributes
2822 sal_Int32 nLen = aRenderer.getLength();
2823 const sal_Int32 nRenderDataIdxStart = nLen;
2824 nLen += 9;
2825 aRenderer.realloc( nLen );
2826 auto pRenderer = aRenderer.getArray();
2827 // put page print settings attribute into render data
2828 const sal_Int32 nRow = pPagePrintSettings->GetRow();
2829 pRenderer[ nRenderDataIdxStart + 0 ].Name = "NUpRows";
2830 pRenderer[ nRenderDataIdxStart + 0 ].Value <<= std::max<sal_Int32>( nRow, 1);
2831 const sal_Int32 nCol = pPagePrintSettings->GetCol();
2832 pRenderer[ nRenderDataIdxStart + 1 ].Name = "NUpColumns";
2833 pRenderer[ nRenderDataIdxStart + 1 ].Value <<= std::max<sal_Int32>( nCol, 1);
2834 pRenderer[ nRenderDataIdxStart + 2 ].Name = "NUpPageMarginLeft";
2835 pRenderer[ nRenderDataIdxStart + 2 ].Value <<= pPagePrintSettings->GetLeftSpace();
2836 pRenderer[ nRenderDataIdxStart + 3 ].Name = "NUpPageMarginRight";
2837 pRenderer[ nRenderDataIdxStart + 3 ].Value <<= pPagePrintSettings->GetRightSpace();
2838 pRenderer[ nRenderDataIdxStart + 4 ].Name = "NUpPageMarginTop";
2839 pRenderer[ nRenderDataIdxStart + 4 ].Value <<= pPagePrintSettings->GetTopSpace();
2840 pRenderer[ nRenderDataIdxStart + 5 ].Name = "NUpPageMarginBottom";
2841 pRenderer[ nRenderDataIdxStart + 5 ].Value <<= pPagePrintSettings->GetBottomSpace();
2842 pRenderer[ nRenderDataIdxStart + 6 ].Name = "NUpHorizontalSpacing";
2843 pRenderer[ nRenderDataIdxStart + 6 ].Value <<= pPagePrintSettings->GetHorzSpace();
2844 pRenderer[ nRenderDataIdxStart + 7 ].Name = "NUpVerticalSpacing";
2845 pRenderer[ nRenderDataIdxStart + 7 ].Value <<= pPagePrintSettings->GetVertSpace();
2847 Printer* pPrinter = m_pDocShell->GetDoc()->getIDocumentDeviceAccess().getPrinter( false );
2848 if ( pPrinter )
2850 awt::Size aNewPageSize;
2851 const Size aPageSize = pPrinter->PixelToLogic( pPrinter->GetPaperSizePixel(), MapMode( MapUnit::Map100thMM ) );
2852 aNewPageSize = awt::Size( aPageSize.Width(), aPageSize.Height() );
2853 if ( ( pPagePrintSettings->GetLandscape() &&
2854 aPageSize.Width() < aPageSize.Height() ) ||
2855 ( !pPagePrintSettings->GetLandscape() &&
2856 aPageSize.Width() > aPageSize.Height() ) )
2858 aNewPageSize = awt::Size( aPageSize.Height(), aPageSize.Width() );
2860 pRenderer[ nRenderDataIdxStart + 8 ].Name = "NUpPaperSize";
2861 pRenderer[ nRenderDataIdxStart + 8 ].Value <<= aNewPageSize;
2866 m_bApplyPagePrintSettingsFromXPagePrintable = false;
2869 m_pPrintUIOptions->appendPrintUIOptions( aRenderer );
2871 return aRenderer;
2874 SfxViewShell * SwXTextDocument::GuessViewShell(
2875 /* out */ bool &rbIsSwSrcView,
2876 const uno::Reference< css::frame::XController >& rController )
2878 // #130810# SfxViewShell::Current() / SfxViewShell::GetObjectShell()
2879 // must not be used (see comment from MBA)
2881 SfxViewShell *pView = nullptr;
2882 SwView *pSwView = nullptr;
2883 SwPagePreview *pSwPagePreview = nullptr;
2884 SwSrcView *pSwSrcView = nullptr;
2885 SfxViewFrame *pFrame = SfxViewFrame::GetFirst( m_pDocShell, false );
2887 // look for the view shell with the same controller in use,
2888 // otherwise look for a suitable view, preferably a SwView,
2889 // if that one is not found use a SwPagePreview if found.
2890 while (pFrame)
2892 pView = pFrame->GetViewShell();
2893 pSwView = dynamic_cast< SwView * >(pView);
2894 pSwSrcView = dynamic_cast< SwSrcView * >(pView);
2895 if (!pSwPagePreview)
2896 pSwPagePreview = dynamic_cast< SwPagePreview * >(pView);
2897 if (rController.is())
2899 if (pView && pView->GetController() == rController)
2900 break;
2902 else if (pSwView || pSwSrcView)
2903 break;
2904 pFrame = SfxViewFrame::GetNext( *pFrame, m_pDocShell, false );
2907 OSL_ENSURE( pSwView || pSwPagePreview || pSwSrcView, "failed to get view shell" );
2908 if (pView)
2909 rbIsSwSrcView = pSwSrcView != nullptr;
2910 return pView;
2913 void SAL_CALL SwXTextDocument::render(
2914 sal_Int32 nRenderer,
2915 const uno::Any& rSelection,
2916 const uno::Sequence< beans::PropertyValue >& rxOptions )
2918 SolarMutexGuard aGuard;
2919 if(!IsValid())
2921 throw DisposedException( OUString(),
2922 static_cast< XTextDocument* >(this) );
2925 // due to #110067# (document page count changes sometimes during
2926 // PDF export/printing) we can not check for the upper bound properly.
2927 // Thus instead of throwing the exception we silently return.
2928 if (0 > nRenderer)
2929 throw IllegalArgumentException();
2931 // tdf#135244: prevent jumping to cursor at any temporary modification
2932 auto aLock = m_pDocShell->LockAllViews();
2934 const bool bHasPDFExtOutDevData = lcl_SeqHasProperty( rxOptions, "HasPDFExtOutDevData" );
2935 const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" ) || bHasPDFExtOutDevData;
2936 bool bIsSwSrcView = false;
2937 SfxViewShell *pView = GetRenderView( bIsSwSrcView, rxOptions, bIsPDFExport );
2939 OSL_ENSURE( m_pRenderData, "data should have been created already in getRendererCount..." );
2940 OSL_ENSURE( m_pPrintUIOptions, "data should have been created already in getRendererCount..." );
2941 if (!bIsSwSrcView && !m_pRenderData)
2942 m_pRenderData.reset(new SwRenderData);
2943 if (!m_pPrintUIOptions)
2944 m_pPrintUIOptions = lcl_GetPrintUIOptions( m_pDocShell, pView );
2945 m_pPrintUIOptions->processProperties( rxOptions );
2946 const bool bPrintProspect = m_pPrintUIOptions->getBoolValue( "PrintProspect" );
2947 const bool bLastPage = m_pPrintUIOptions->getBoolValue( "IsLastPage" );
2949 SwDoc *pDoc = GetRenderDoc( pView, rSelection, bIsPDFExport );
2950 OSL_ENSURE( pDoc && pView, "doc or view shell missing!" );
2951 if (pDoc && pView)
2953 sal_Int32 nMaxRenderer = 0;
2954 if (!bIsSwSrcView)
2956 OSL_ENSURE( m_pRenderData, "m_pRenderData missing!!" );
2957 nMaxRenderer = bPrintProspect?
2958 m_pRenderData->GetPagePairsForProspectPrinting().size() - 1 :
2959 m_pRenderData->GetPagesToPrint().size() - 1;
2961 // since SwSrcView::PrintSource is a poor implementation to get the number of pages to print
2962 // we obmit checking of the upper bound in this case.
2963 if (bIsSwSrcView || nRenderer <= nMaxRenderer)
2965 if (bIsSwSrcView)
2967 SwSrcView& rSwSrcView = dynamic_cast<SwSrcView&>(*pView);
2968 VclPtr< OutputDevice > pOutDev = lcl_GetOutputDevice( *m_pPrintUIOptions );
2969 rSwSrcView.PrintSource(pOutDev, nRenderer + 1, false);
2971 else
2973 // the view shell should be SwView for documents PDF export
2974 // or SwPagePreview for PDF export of the page preview
2975 SwViewShell* pVwSh = nullptr;
2976 // TODO/mba: we really need a generic way to get the SwViewShell!
2977 const SwView* pSwView = dynamic_cast<const SwView*>(pView);
2978 if (pSwView)
2979 pVwSh = pSwView->GetWrtShellPtr();
2980 else
2981 pVwSh = static_cast<SwPagePreview*>(pView)->GetViewShell();
2983 // get output device to use
2984 VclPtr< OutputDevice > pOut = lcl_GetOutputDevice( *m_pPrintUIOptions );
2986 if(pVwSh && pOut && m_pRenderData->HasSwPrtOptions())
2988 const OUString aPageRange = m_pPrintUIOptions->getStringValue( "PageRange" );
2989 const bool bFirstPage = m_pPrintUIOptions->getBoolValue( "IsFirstPage" );
2990 bool bIsSkipEmptyPages = !m_pPrintUIOptions->IsPrintEmptyPages( bIsPDFExport );
2992 OSL_ENSURE((pSwView && m_pRenderData->IsViewOptionAdjust())
2993 || (!pSwView && !m_pRenderData->IsViewOptionAdjust()),
2994 "SwView / SwViewOptionAdjust_Impl availability mismatch" );
2996 // since printing now also use the API for PDF export this option
2997 // should be set for printing as well ...
2998 pVwSh->SetPDFExportOption( true );
3000 // #i12836# enhanced pdf export
3002 // First, we have to export hyperlinks, notes, and outline to pdf.
3003 // During this process, additional information required for tagging
3004 // the pdf file are collected, which are evaluated during painting.
3006 SwWrtShell* pWrtShell = pSwView ? pSwView->GetWrtShellPtr() : nullptr;
3008 SwPrintData rSwPrtOptions = *m_pRenderData->GetSwPrtOptions();
3009 if (bIsPDFExport)
3011 rSwPrtOptions.SetPrintPostIts(
3012 lcl_GetBoolProperty(rxOptions, "ExportNotesInMargin")
3013 ? SwPostItMode::InMargins
3014 : SwPostItMode::NONE);
3017 if (bIsPDFExport && (bFirstPage || bHasPDFExtOutDevData) && pWrtShell)
3019 SwEnhancedPDFExportHelper aHelper( *pWrtShell, *pOut, aPageRange, bIsSkipEmptyPages, false, rSwPrtOptions );
3022 if (bPrintProspect)
3023 pVwSh->PrintProspect( pOut, rSwPrtOptions, nRenderer );
3024 else // normal printing and PDF export
3025 pVwSh->PrintOrPDFExport( pOut, rSwPrtOptions, nRenderer, bIsPDFExport );
3027 // #i35176#
3029 // After printing the last page, we take care for the links coming
3030 // from the EditEngine. The links are generated during the painting
3031 // process, but the destinations are still missing.
3033 if (bIsPDFExport && bLastPage && pWrtShell)
3035 SwEnhancedPDFExportHelper aHelper( *pWrtShell, *pOut, aPageRange, bIsSkipEmptyPages, true, rSwPrtOptions );
3038 pVwSh->SetPDFExportOption( false );
3040 // last page to be rendered? (not necessarily the last page of the document)
3041 // -> do clean-up of data
3042 if (bLastPage)
3044 // #i96167# haggai: delete ViewOptionsAdjust here because it makes use
3045 // of the shell, which might get destroyed in lcl_DisposeView!
3046 if (m_pRenderData->IsViewOptionAdjust())
3047 m_pRenderData->ViewOptionAdjustStop();
3049 if (m_pRenderData->HasPostItData())
3050 m_pRenderData->DeletePostItData();
3051 if (m_pHiddenViewFrame)
3053 lcl_DisposeView( m_pHiddenViewFrame, m_pDocShell );
3054 m_pHiddenViewFrame = nullptr;
3056 // prevent crash described in #i108805
3057 SwDocShell *pRenderDocShell = pDoc->GetDocShell();
3058 SfxItemSet *pSet = pRenderDocShell->GetMedium()->GetItemSet();
3059 pSet->Put( SfxBoolItem( SID_HIDDEN, false ) );
3067 if( bLastPage )
3069 // tdf#144989 enable DoIdleJobs() again after last page
3070 pDoc->getIDocumentTimerAccess().UnblockIdling();
3071 m_pRenderData.reset();
3072 m_pPrintUIOptions.reset();
3076 // xforms::XFormsSupplier
3077 Reference<XNameContainer> SAL_CALL SwXTextDocument::getXForms()
3079 SolarMutexGuard aGuard;
3080 if ( !m_pDocShell )
3081 throw DisposedException( OUString(), static_cast< XTextDocument* >( this ) );
3082 SwDoc* pDoc = m_pDocShell->GetDoc();
3083 return pDoc->getXForms();
3086 uno::Reference< text::XFlatParagraphIterator > SAL_CALL SwXTextDocument::getFlatParagraphIterator(::sal_Int32 nTextMarkupType, sal_Bool bAutomatic)
3088 SolarMutexGuard aGuard;
3089 if (!IsValid())
3091 throw DisposedException("SwXTextDocument not valid",
3092 static_cast<XTextDocument*>(this));
3095 return SwUnoCursorHelper::CreateFlatParagraphIterator(
3096 *m_pDocShell->GetDoc(), nTextMarkupType, bAutomatic);
3099 uno::Reference< util::XCloneable > SwXTextDocument::createClone( )
3101 SolarMutexGuard aGuard;
3102 if(!IsValid())
3103 throw DisposedException("", static_cast< XTextDocument* >(this));
3105 // create a new document - hidden - copy the storage and return it
3106 // SfxObjectShellRef is used here, since the model should control object lifetime after creation
3107 // and thus SfxObjectShellLock is not allowed here
3108 // the model holds reference to the shell, so the shell will not destructed at the end of method
3109 SfxObjectShellRef pShell = m_pDocShell->GetDoc()->CreateCopy(false, false);
3110 uno::Reference< frame::XModel > xNewModel = pShell->GetModel();
3111 uno::Reference< embed::XStorage > xNewStorage = ::comphelper::OStorageHelper::GetTemporaryStorage( );
3112 uno::Sequence< beans::PropertyValue > aTempMediaDescriptor;
3113 storeToStorage( xNewStorage, aTempMediaDescriptor );
3114 uno::Reference< document::XStorageBasedDocument > xStorageDoc( xNewModel, uno::UNO_QUERY );
3115 xStorageDoc->loadFromStorage( xNewStorage, aTempMediaDescriptor );
3116 return uno::Reference< util::XCloneable >( xNewModel, UNO_QUERY );
3119 void SwXTextDocument::addPasteEventListener(const uno::Reference<text::XPasteListener>& xListener)
3121 SolarMutexGuard aGuard;
3123 if (IsValid() && xListener.is())
3124 m_pDocShell->GetWrtShell()->GetPasteListeners().addInterface(xListener);
3127 void SwXTextDocument::removePasteEventListener(
3128 const uno::Reference<text::XPasteListener>& xListener)
3130 SolarMutexGuard aGuard;
3132 if (IsValid() && xListener.is())
3133 m_pDocShell->GetWrtShell()->GetPasteListeners().removeInterface(xListener);
3136 void SwXTextDocument::paintTile( VirtualDevice &rDevice,
3137 int nOutputWidth, int nOutputHeight,
3138 int nTilePosX, int nTilePosY,
3139 tools::Long nTileWidth, tools::Long nTileHeight )
3141 SwViewShell* pViewShell = m_pDocShell->GetWrtShell();
3142 pViewShell->PaintTile(rDevice, nOutputWidth, nOutputHeight,
3143 nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3145 LokChartHelper::PaintAllChartsOnTile(rDevice, nOutputWidth, nOutputHeight,
3146 nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3148 // Draw Form controls
3149 comphelper::LibreOfficeKit::setTiledPainting(true);
3150 SwDrawModel* pDrawLayer = m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
3151 SdrPage* pPage = pDrawLayer->GetPage(sal_uInt16(0));
3152 SdrView* pDrawView = pViewShell->GetDrawView();
3153 SwEditWin& rEditWin = m_pDocShell->GetView()->GetEditWin();
3154 tools::Rectangle aTileRect(Point(nTilePosX, nTilePosY), Size(nTileWidth, nTileHeight));
3155 Size aOutputSize(nOutputWidth, nOutputHeight);
3156 LokControlHandler::paintControlTile(pPage, pDrawView, rEditWin, rDevice, aOutputSize, aTileRect);
3157 comphelper::LibreOfficeKit::setTiledPainting(false);
3160 Size SwXTextDocument::getDocumentSize()
3162 SwViewShell* pViewShell = m_pDocShell->GetWrtShell();
3163 Size aDocSize = pViewShell->GetDocSize();
3165 return Size(aDocSize.Width() + 2 * DOCUMENTBORDER,
3166 aDocSize.Height() + 2 * DOCUMENTBORDER);
3169 void SwXTextDocument::setPart(int nPart, bool /*bAllowChangeFocus*/)
3171 SolarMutexGuard aGuard;
3173 SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
3174 if (!pWrtShell)
3175 return;
3177 pWrtShell->GotoPage(nPart + 1, true);
3180 int SwXTextDocument::getParts()
3182 SolarMutexGuard aGuard;
3184 SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
3185 if (!pWrtShell)
3186 return 0;
3188 return pWrtShell->GetPageCnt();
3191 OUString SwXTextDocument::getPartPageRectangles()
3193 SolarMutexGuard aGuard;
3195 SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
3196 if (!pWrtShell)
3197 return OUString();
3199 return pWrtShell->getPageRectangles();
3202 void SwXTextDocument::setClipboard(const uno::Reference<datatransfer::clipboard::XClipboard>& xClipboard)
3204 SolarMutexGuard aGuard;
3206 SwView* pView = m_pDocShell->GetView();
3207 if (pView)
3208 pView->GetEditWin().SetClipboard(xClipboard);
3211 bool SwXTextDocument::isMimeTypeSupported()
3213 SolarMutexGuard aGuard;
3215 SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
3216 if (!pWrtShell)
3217 return false;
3219 TransferableDataHelper aDataHelper(TransferableDataHelper::CreateFromSystemClipboard(&pWrtShell->GetView().GetEditWin()));
3220 if (SdrView* pSdrView = pWrtShell->GetDrawView())
3222 if (pSdrView->GetTextEditObject())
3223 // Editing shape text
3224 return EditEngine::HasValidData(aDataHelper.GetTransferable());
3227 return aDataHelper.GetXTransferable().is() && SwTransferable::IsPaste(*pWrtShell, aDataHelper);
3230 void SwXTextDocument::setClientVisibleArea(const tools::Rectangle& rRectangle)
3232 if (SwView* pView = m_pDocShell->GetView())
3234 // set the PgUp/PgDown offset
3235 pView->ForcePageUpDownOffset(2 * rRectangle.GetHeight() / 3);
3238 if (SwViewShell* pViewShell = m_pDocShell->GetWrtShell())
3240 pViewShell->setLOKVisibleArea(rRectangle);
3244 void SwXTextDocument::setClientZoom(int nTilePixelWidth_, int /*nTilePixelHeight_*/,
3245 int nTileTwipWidth_, int /*nTileTwipHeight_*/)
3247 // Here we set the zoom value as it has been set by the user in the client.
3248 // This value is used in postMouseEvent and setGraphicSelection methods
3249 // for in place chart editing. We assume that x and y scale is roughly
3250 // the same.
3251 SfxInPlaceClient* pIPClient = m_pDocShell->GetView()->GetIPClient();
3252 if (!pIPClient)
3253 return;
3255 SwViewShell* pWrtViewShell = m_pDocShell->GetWrtShell();
3256 double fScale = 100.0 * nTilePixelWidth_ / nTileTwipWidth_
3257 * o3tl::convert(1.0, o3tl::Length::px, o3tl::Length::twip);
3258 SwViewOption aOption(*(pWrtViewShell->GetViewOptions()));
3259 if (aOption.GetZoom() != fScale)
3261 aOption.SetZoom(fScale);
3262 pWrtViewShell->ApplyViewOptions(aOption);
3264 // Changing the zoom value doesn't always trigger the updating of
3265 // the client ole object area, so we call it directly.
3266 pIPClient->VisAreaChanged();
3270 PointerStyle SwXTextDocument::getPointer()
3272 SolarMutexGuard aGuard;
3274 SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
3275 if (!pWrtShell)
3276 return PointerStyle::Arrow;
3278 return pWrtShell->GetView().GetEditWin().GetPointer();
3281 void SwXTextDocument::getTrackedChanges(tools::JsonWriter& rJson)
3283 auto redlinesNode = rJson.startArray("redlines");
3285 // Disable since usability is very low beyond some small number of changes.
3286 static bool bDisableRedlineComments = getenv("DISABLE_REDLINE") != nullptr;
3287 if (bDisableRedlineComments)
3288 return;
3290 const SwRedlineTable& rRedlineTable
3291 = m_pDocShell->GetDoc()->getIDocumentRedlineAccess().GetRedlineTable();
3292 for (SwRedlineTable::size_type i = 0; i < rRedlineTable.size(); ++i)
3294 auto redlineNode = rJson.startStruct();
3295 rJson.put("index", rRedlineTable[i]->GetId());
3296 rJson.put("author", rRedlineTable[i]->GetAuthorString(1));
3297 rJson.put("type", SwRedlineTypeToOUString(
3298 rRedlineTable[i]->GetRedlineData().GetType()));
3299 rJson.put("comment",
3300 rRedlineTable[i]->GetRedlineData().GetComment());
3301 rJson.put("description", rRedlineTable[i]->GetDescr());
3302 OUString sDateTime = utl::toISO8601(
3303 rRedlineTable[i]->GetRedlineData().GetTimeStamp().GetUNODateTime());
3304 rJson.put("dateTime", sDateTime);
3306 SwContentNode* pContentNd = rRedlineTable[i]->GetPointContentNode();
3307 SwView* pView = dynamic_cast<SwView*>(SfxViewShell::Current());
3308 if (pView && pContentNd)
3310 SwShellCursor aCursor(pView->GetWrtShell(), *(rRedlineTable[i]->Start()));
3311 aCursor.SetMark();
3312 aCursor.GetMark()->Assign(*pContentNd, rRedlineTable[i]->End()->GetContentIndex());
3314 aCursor.FillRects();
3316 SwRects* pRects(&aCursor);
3317 std::vector<OString> aRects;
3318 for (const SwRect& rNextRect : *pRects)
3319 aRects.push_back(rNextRect.SVRect().toString());
3321 const OString sRects = comphelper::string::join("; ", aRects);
3322 rJson.put("textRange", sRects);
3327 void SwXTextDocument::getTrackedChangeAuthors(tools::JsonWriter& rJsonWriter)
3329 SW_MOD()->GetRedlineAuthorInfo(rJsonWriter);
3332 void SwXTextDocument::getRulerState(tools::JsonWriter& rJsonWriter)
3334 SwView* pView = m_pDocShell->GetView();
3335 dynamic_cast<SwCommentRuler&>(pView->GetHRuler()).CreateJsonNotification(rJsonWriter);
3338 void SwXTextDocument::getPostIts(tools::JsonWriter& rJsonWriter)
3340 SolarMutexGuard aGuard;
3341 auto commentsNode = rJsonWriter.startArray("comments");
3342 for (auto const& sidebarItem : *m_pDocShell->GetView()->GetPostItMgr())
3344 sw::annotation::SwAnnotationWin* pWin = sidebarItem->mpPostIt.get();
3346 if (!pWin)
3348 continue;
3351 const SwPostItField* pField = pWin->GetPostItField();
3352 const SwRect& aRect = pWin->GetAnchorRect();
3353 tools::Rectangle aSVRect(aRect.Pos().getX(),
3354 aRect.Pos().getY(),
3355 aRect.Pos().getX() + aRect.SSize().Width(),
3356 aRect.Pos().getY() + aRect.SSize().Height());
3358 if (!sidebarItem->maLayoutInfo.mPositionFromCommentAnchor)
3360 // Comments on frames: anchor position is the corner position, not the whole frame.
3361 aSVRect.SetSize(Size(0, 0));
3364 std::vector<OString> aRects;
3365 for (const basegfx::B2DRange& aRange : pWin->GetAnnotationTextRanges())
3367 const SwRect rect(aRange.getMinX(), aRange.getMinY(), aRange.getWidth(), aRange.getHeight());
3368 aRects.push_back(rect.SVRect().toString());
3370 const OString sRects = comphelper::string::join("; ", aRects);
3372 auto commentNode = rJsonWriter.startStruct();
3373 rJsonWriter.put("id", pField->GetPostItId());
3374 rJsonWriter.put("parent", pWin->CalcParent());
3375 rJsonWriter.put("paraIdParent", pField->GetParentId());
3376 rJsonWriter.put("author", pField->GetPar1());
3377 rJsonWriter.put("text", pField->GetPar2());
3378 rJsonWriter.put("resolved", pField->GetResolved() ? "true" : "false");
3379 rJsonWriter.put("dateTime", utl::toISO8601(pField->GetDateTime().GetUNODateTime()));
3380 rJsonWriter.put("anchorPos", aSVRect.toString());
3381 rJsonWriter.put("textRange", sRects);
3385 void SwXTextDocument::executeFromFieldEvent(const StringMap& aArguments)
3387 auto aIter = aArguments.find("type");
3388 if (aIter == aArguments.end() || aIter->second != "drop-down")
3389 return;
3391 aIter = aArguments.find("cmd");
3392 if (aIter == aArguments.end() || aIter->second != "selected")
3393 return;
3395 aIter = aArguments.find("data");
3396 if (aIter == aArguments.end())
3397 return;
3399 sal_Int32 nSelection = aIter->second.toInt32();
3400 SwPosition aPos(*m_pDocShell->GetWrtShell()->GetCursor()->GetPoint());
3401 sw::mark::IFieldmark* pFieldBM = m_pDocShell->GetWrtShell()->getIDocumentMarkAccess()->getInnerFieldmarkFor(aPos);
3402 if ( !pFieldBM )
3404 aPos.AdjustContent(-1);
3405 pFieldBM = m_pDocShell->GetWrtShell()->getIDocumentMarkAccess()->getInnerFieldmarkFor(aPos);
3407 if (pFieldBM && pFieldBM->GetFieldname() == ODF_FORMDROPDOWN)
3409 if (nSelection >= 0)
3411 (*pFieldBM->GetParameters())[ODF_FORMDROPDOWN_RESULT] <<= nSelection;
3412 pFieldBM->Invalidate();
3413 m_pDocShell->GetWrtShell()->SetModified();
3414 m_pDocShell->GetView()->GetEditWin().LogicInvalidate(nullptr);
3419 std::vector<basegfx::B2DRange>
3420 SwXTextDocument::getSearchResultRectangles(const char* pPayload)
3422 SwDoc* pDoc = m_pDocShell->GetDoc();
3423 if (!pDoc)
3424 return std::vector<basegfx::B2DRange>();
3426 sw::search::SearchResultLocator aLocator(pDoc);
3427 sw::search::LocationResult aResult = aLocator.findForPayload(pPayload);
3428 if (aResult.mbFound)
3430 return aResult.maRectangles;
3432 return std::vector<basegfx::B2DRange>();
3435 OString SwXTextDocument::getViewRenderState()
3437 OStringBuffer aState;
3438 SwView* pView = m_pDocShell->GetView();
3439 if (pView && pView->GetWrtShellPtr())
3441 const SwViewOption* pVOpt = pView->GetWrtShell().GetViewOptions();
3442 if (pVOpt)
3444 if (pVOpt->IsViewMetaChars())
3445 aState.append('P');
3446 if (pVOpt->IsOnlineSpell())
3447 aState.append('S');
3448 aState.append(';');
3450 OString aThemeName = OUStringToOString(pVOpt->GetThemeName(), RTL_TEXTENCODING_UTF8);
3451 aState.append(aThemeName);
3454 return aState.makeStringAndClear();
3457 namespace
3459 inline constexpr OUStringLiteral SELECTED_DATE_FORMAT = u"YYYY-MM-DD";
3462 void SwXTextDocument::executeContentControlEvent(const StringMap& rArguments)
3464 auto it = rArguments.find("type");
3465 if (it == rArguments.end())
3467 return;
3470 if (it->second == "drop-down")
3472 SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
3473 const SwPosition* pStart = pWrtShell->GetCursor()->Start();
3474 SwTextNode* pTextNode = pStart->GetNode().GetTextNode();
3475 if (!pTextNode)
3477 return;
3480 SwTextAttr* pAttr = pTextNode->GetTextAttrAt(pStart->GetContentIndex(),
3481 RES_TXTATR_CONTENTCONTROL, ::sw::GetTextAttrMode::Parent);
3482 if (!pAttr)
3484 return;
3487 auto pTextContentControl = static_txtattr_cast<SwTextContentControl*>(pAttr);
3488 const SwFormatContentControl& rFormatContentControl = pTextContentControl->GetContentControl();
3489 std::shared_ptr<SwContentControl> pContentControl = rFormatContentControl.GetContentControl();
3490 if (!pContentControl->GetComboBox() && !pContentControl->GetDropDown())
3492 return;
3495 it = rArguments.find("selected");
3496 if (it == rArguments.end())
3498 return;
3501 sal_Int32 nSelection = it->second.toInt32();
3502 pContentControl->SetSelectedListItem(nSelection);
3503 pWrtShell->GotoContentControl(rFormatContentControl);
3505 else if (it->second == "picture")
3507 it = rArguments.find("changed");
3508 if (it == rArguments.end())
3510 return;
3513 SwView* pView = m_pDocShell->GetView();
3514 if (!pView)
3516 return;
3519 // The current placeholder is selected, so this will replace, not insert.
3520 SfxStringItem aItem(SID_INSERT_GRAPHIC, it->second);
3521 pView->GetViewFrame().GetDispatcher()->ExecuteList(SID_CHANGE_PICTURE,
3522 SfxCallMode::SYNCHRON, { &aItem });
3524 else if (it->second == "date")
3526 SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
3527 const SwPosition* pStart = pWrtShell->GetCursor()->Start();
3528 SwTextNode* pTextNode = pStart->GetNode().GetTextNode();
3529 if (!pTextNode)
3531 return;
3534 SwTextAttr* pAttr = pTextNode->GetTextAttrAt(pStart->GetContentIndex(),
3535 RES_TXTATR_CONTENTCONTROL, ::sw::GetTextAttrMode::Parent);
3536 if (!pAttr)
3538 return;
3541 auto pTextContentControl = static_txtattr_cast<SwTextContentControl*>(pAttr);
3542 const SwFormatContentControl& rFormatContentControl
3543 = pTextContentControl->GetContentControl();
3544 std::shared_ptr<SwContentControl> pContentControl
3545 = rFormatContentControl.GetContentControl();
3546 if (!pContentControl->GetDate())
3548 return;
3551 it = rArguments.find("selected");
3552 if (it == rArguments.end())
3554 return;
3557 OUString aSelectedDate = it->second.replaceAll("T00:00:00Z", "");
3558 SwDoc& rDoc = pTextNode->GetDoc();
3559 SvNumberFormatter* pNumberFormatter = rDoc.GetNumberFormatter();
3560 sal_uInt32 nFormat
3561 = pNumberFormatter->GetEntryKey(SELECTED_DATE_FORMAT, LANGUAGE_ENGLISH_US);
3562 if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
3564 sal_Int32 nCheckPos = 0;
3565 SvNumFormatType nType;
3566 OUString sFormat = SELECTED_DATE_FORMAT;
3567 pNumberFormatter->PutEntry(sFormat, nCheckPos, nType, nFormat, LANGUAGE_ENGLISH_US);
3570 if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
3572 return;
3575 double dCurrentDate = 0;
3576 pNumberFormatter->IsNumberFormat(aSelectedDate, nFormat, dCurrentDate);
3577 pContentControl->SetSelectedDate(dCurrentDate);
3578 pWrtShell->GotoContentControl(rFormatContentControl);
3582 int SwXTextDocument::getPart()
3584 SolarMutexGuard aGuard;
3586 SwView* pView = m_pDocShell->GetView();
3587 if (!pView)
3588 return 0;
3590 return pView->getPart();
3593 OUString SwXTextDocument::getPartName(int nPart)
3595 return SwResId(STR_PAGE) + OUString::number(nPart + 1);
3598 OUString SwXTextDocument::getPartHash(int nPart)
3600 OUString sPart(SwResId(STR_PAGE) + OUString::number(nPart + 1));
3602 return OUString::number(sPart.hashCode());
3605 VclPtr<vcl::Window> SwXTextDocument::getDocWindow()
3607 SolarMutexGuard aGuard;
3608 SwView* pView = m_pDocShell->GetView();
3609 if (!pView)
3610 return {};
3612 if (VclPtr<vcl::Window> pWindow = SfxLokHelper::getInPlaceDocWindow(pView))
3613 return pWindow;
3615 return &(pView->GetEditWin());
3618 void SwXTextDocument::initializeForTiledRendering(const css::uno::Sequence<css::beans::PropertyValue>& rArguments)
3620 SolarMutexGuard aGuard;
3622 SwViewShell* pViewShell = m_pDocShell->GetWrtShell();
3624 SwView* pView = m_pDocShell->GetView();
3625 if (!pView)
3626 return;
3628 pView->SetViewLayout(1/*nColumns*/, false/*bBookMode*/, true);
3630 // Tiled rendering defaults.
3631 SwViewOption aViewOption(*pViewShell->GetViewOptions());
3632 aViewOption.SetHardBlank(false);
3634 // Disable field shadings: the result would depend on the cursor position.
3635 aViewOption.SetAppearanceFlag(ViewOptFlags::FieldShadings, false);
3636 // The fancy header/footer controls don't work in tiled mode anyway, so
3637 // explicitly disable them to enable skipping invalidating the view for
3638 // the case of clicking in the header area of a document with no headers
3639 aViewOption.SetUseHeaderFooterMenu(false);
3641 OUString sOrigAuthor = SW_MOD()->GetRedlineAuthor(SW_MOD()->GetRedlineAuthor());
3642 OUString sAuthor;
3644 for (const beans::PropertyValue& rValue : rArguments)
3646 if (rValue.Name == ".uno:HideWhitespace" && rValue.Value.has<bool>())
3647 aViewOption.SetHideWhitespaceMode(rValue.Value.get<bool>());
3648 else if (rValue.Name == ".uno:ShowBorderShadow" && rValue.Value.has<bool>())
3649 aViewOption.SetAppearanceFlag(ViewOptFlags::Shadow , rValue.Value.get<bool>());
3650 else if (rValue.Name == ".uno:Author" && rValue.Value.has<OUString>())
3652 sAuthor = rValue.Value.get<OUString>();
3653 // Store the author name in the view.
3654 pView->SetRedlineAuthor(sAuthor);
3655 // Let the actual author name pick up the value from the current
3656 // view, which would normally happen only during the next view
3657 // switch.
3658 m_pDocShell->SetView(pView);
3660 else if (rValue.Name == ".uno:SpellOnline" && rValue.Value.has<bool>())
3661 aViewOption.SetOnlineSpell(rValue.Value.get<bool>());
3664 if (!sAuthor.isEmpty() && sAuthor != sOrigAuthor)
3666 SwView* pFirstView = static_cast<SwView*>(SfxViewShell::GetFirst());
3667 if (pFirstView && SfxViewShell::GetNext(*pFirstView) == nullptr)
3669 if (SwEditShell* pShell = &pFirstView->GetWrtShell())
3671 pShell->SwViewShell::UpdateFields(true);
3672 pShell->ResetModified();
3677 // Set the initial zoom value to 1; usually it is set in setClientZoom and
3678 // SwViewShell::PaintTile; zoom value is used for chart in place
3679 // editing, see postMouseEvent and setGraphicSelection methods.
3680 aViewOption.SetZoom(1 * 100);
3682 aViewOption.SetPostIts(comphelper::LibreOfficeKit::isTiledAnnotations());
3683 pViewShell->ApplyViewOptions(aViewOption);
3685 // position the pages again after setting view options. Eg: if postit
3686 // rendering is false, then there would be no sidebar, so width of the
3687 // document needs to be adjusted
3688 pViewShell->GetLayout()->CheckViewLayout( pViewShell->GetViewOptions(), nullptr );
3690 // Disable map mode, so that it's possible to send mouse event coordinates
3691 // directly in twips.
3692 SwEditWin& rEditWin = m_pDocShell->GetView()->GetEditWin();
3693 rEditWin.EnableMapMode(false);
3695 // when the "This document may contain formatting or content that cannot
3696 // be saved..." dialog appears, it is auto-cancelled with tiled rendering,
3697 // causing 'Save' being disabled; so let's always save to the original
3698 // format
3699 auto xChanges = comphelper::ConfigurationChanges::create();
3700 officecfg::Office::Common::Save::Document::WarnAlienFormat::set(false, xChanges);
3701 xChanges->commit();
3703 // disable word auto-completion suggestions, the tooltips are not visible,
3704 // and the editeng-like auto-completion is annoying
3705 SvxAutoCorrCfg::Get().GetAutoCorrect()->GetSwFlags().bAutoCompleteWords = false;
3707 // don't change the whitespace at the beginning of paragraphs, this is
3708 // annoying when taking minutes without further formatting
3709 SwEditShell::GetAutoFormatFlags()->bAFormatByInpDelSpacesAtSttEnd = false;
3712 void SwXTextDocument::postKeyEvent(int nType, int nCharCode, int nKeyCode)
3714 SolarMutexGuard aGuard;
3715 SfxLokHelper::postKeyEventAsync(getDocWindow(), nType, nCharCode, nKeyCode);
3718 void SwXTextDocument::postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier)
3720 SolarMutexGuard aGuard;
3722 SwViewShell* pWrtViewShell = m_pDocShell->GetWrtShell();
3723 if (!pWrtViewShell)
3725 return;
3728 SwViewOption aOption(*(pWrtViewShell->GetViewOptions()));
3729 double fScale = aOption.GetZoom() / o3tl::convert(100.0, o3tl::Length::px, o3tl::Length::twip);
3731 if (SfxLokHelper::testInPlaceComponentMouseEventHit(
3732 m_pDocShell->GetView(), nType, nX, nY, nCount, nButtons, nModifier, fScale, fScale))
3733 return;
3735 // try to forward mouse event to controls
3736 SwDrawModel* pDrawLayer = m_pDocShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
3737 SdrPage* pPage = pDrawLayer->GetPage(sal_uInt16(0));
3738 SdrView* pDrawView = pWrtViewShell->GetDrawView();
3739 SwEditWin& rEditWin = m_pDocShell->GetView()->GetEditWin();
3740 Point aPointTwip(nX, nY);
3741 Point aPointHMMDraw = o3tl::convert(aPointTwip, o3tl::Length::twip, o3tl::Length::mm100);
3742 if (LokControlHandler::postMouseEvent(pPage, pDrawView, rEditWin, nType, aPointHMMDraw, nCount, nButtons, nModifier))
3743 return;
3745 LokMouseEventData aMouseEventData(nType, Point(nX, nY), nCount,
3746 MouseEventModifiers::SIMPLECLICK,
3747 nButtons, nModifier);
3748 SfxLokHelper::postMouseEventAsync(&rEditWin, aMouseEventData);
3751 void SwXTextDocument::setTextSelection(int nType, int nX, int nY)
3753 SolarMutexGuard aGuard;
3755 SfxViewShell* pViewShell = m_pDocShell->GetView();
3756 LokChartHelper aChartHelper(pViewShell);
3757 if (aChartHelper.setTextSelection(nType, nX, nY))
3758 return;
3760 SwEditWin& rEditWin = m_pDocShell->GetView()->GetEditWin();
3761 switch (nType)
3763 case LOK_SETTEXTSELECTION_START:
3764 rEditWin.SetCursorTwipPosition(Point(nX, nY), /*bPoint=*/false, /*bClearMark=*/false);
3765 break;
3766 case LOK_SETTEXTSELECTION_END:
3767 rEditWin.SetCursorTwipPosition(Point(nX, nY), /*bPoint=*/true, /*bClearMark=*/false);
3768 break;
3769 case LOK_SETTEXTSELECTION_RESET:
3770 rEditWin.SetCursorTwipPosition(Point(nX, nY), /*bPoint=*/true, /*bClearMark=*/true);
3771 break;
3772 default:
3773 assert(false);
3774 break;
3778 uno::Reference<datatransfer::XTransferable> SwXTextDocument::getSelection()
3780 SolarMutexGuard aGuard;
3782 uno::Reference<datatransfer::XTransferable> xTransferable;
3784 SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
3785 if (SdrView* pSdrView = pWrtShell ? pWrtShell->GetDrawView() : nullptr)
3787 if (pSdrView->GetTextEditObject())
3789 // Editing shape text
3790 EditView& rEditView = pSdrView->GetTextEditOutlinerView()->GetEditView();
3791 xTransferable = rEditView.GetEditEngine()->CreateTransferable(rEditView.GetSelection());
3795 if (SwPostItMgr* pPostItMgr = m_pDocShell->GetView()->GetPostItMgr())
3797 if (sw::annotation::SwAnnotationWin* pWin = pPostItMgr->GetActiveSidebarWin())
3799 // Editing postit text.
3800 EditView& rEditView = pWin->GetOutlinerView()->GetEditView();
3801 xTransferable = rEditView.GetEditEngine()->CreateTransferable(rEditView.GetSelection());
3805 if (!xTransferable.is() && pWrtShell)
3806 xTransferable = new SwTransferable(*pWrtShell);
3808 return xTransferable;
3811 void SwXTextDocument::setGraphicSelection(int nType, int nX, int nY)
3813 SolarMutexGuard aGuard;
3815 SwViewShell* pWrtViewShell = m_pDocShell->GetWrtShell();
3816 SwViewOption aOption(*(pWrtViewShell->GetViewOptions()));
3817 double fScale = aOption.GetZoom() / o3tl::convert(100.0, o3tl::Length::px, o3tl::Length::twip);
3819 SfxViewShell* pViewShell = m_pDocShell->GetView();
3820 LokChartHelper aChartHelper(pViewShell);
3821 if (aChartHelper.setGraphicSelection(nType, nX, nY, fScale, fScale))
3822 return;
3824 SwEditWin& rEditWin = m_pDocShell->GetView()->GetEditWin();
3825 switch (nType)
3827 case LOK_SETGRAPHICSELECTION_START:
3828 rEditWin.SetGraphicTwipPosition(/*bStart=*/true, Point(nX, nY));
3829 break;
3830 case LOK_SETGRAPHICSELECTION_END:
3831 rEditWin.SetGraphicTwipPosition(/*bStart=*/false, Point(nX, nY));
3832 break;
3833 default:
3834 assert(false);
3835 break;
3839 void SwXTextDocument::resetSelection()
3841 SolarMutexGuard aGuard;
3843 SwWrtShell* pWrtShell = m_pDocShell->GetWrtShell();
3844 pWrtShell->ResetSelect(nullptr, false);
3847 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 )
3849 SystemGraphicsData aData;
3850 aData.nSize = sizeof(SystemGraphicsData);
3851 #if defined(_WIN32)
3852 sal_Int64 nWindowHandle;
3853 Parent >>= nWindowHandle;
3854 aData.hWnd = reinterpret_cast<HWND>(nWindowHandle);
3855 ScopedVclPtrInstance<VirtualDevice> xDevice(aData, Size(1, 1), DeviceFormat::WITHOUT_ALPHA);
3856 paintTile(*xDevice, nOutputWidth, nOutputHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3857 #else
3858 // TODO: support other platforms
3859 (void)Parent;
3860 (void)nOutputWidth;
3861 (void)nOutputHeight;
3862 (void)nTilePosX;
3863 (void)nTilePosY;
3864 (void)nTileWidth;
3865 (void)nTileHeight;
3866 #endif
3870 * retrieve languages already used in current document
3872 uno::Sequence< lang::Locale > SAL_CALL SwXTextDocument::getDocumentLanguages(
3873 ::sal_Int16 nScriptTypes,
3874 ::sal_Int16 nMaxCount )
3876 SolarMutexGuard aGuard;
3878 // possible canonical values for nScriptTypes
3879 // any bit wise combination is allowed
3880 const sal_Int16 nLatin = 0x001;
3881 const sal_Int16 nAsian = 0x002;
3882 const sal_Int16 nComplex = 0x004;
3884 // script types for which to get the languages
3885 const bool bLatin = 0 != (nScriptTypes & nLatin);
3886 const bool bAsian = 0 != (nScriptTypes & nAsian);
3887 const bool bComplex = 0 != (nScriptTypes & nComplex);
3889 if (nScriptTypes < nLatin || nScriptTypes > (nLatin | nAsian | nComplex))
3890 throw IllegalArgumentException("nScriptTypes ranges from 1 to 7!", Reference< XInterface >(), 1);
3891 if (!m_pDocShell)
3892 throw DisposedException();
3893 SwDoc* pDoc = m_pDocShell->GetDoc();
3895 // avoid duplicate values
3896 std::set< LanguageType > aAllLangs;
3898 //USER STYLES
3900 const SwCharFormats *pFormats = pDoc->GetCharFormats();
3901 for(size_t i = 0; i < pFormats->size(); ++i)
3903 const SwAttrSet &rAttrSet = (*pFormats)[i]->GetAttrSet();
3904 LanguageType nLang = LANGUAGE_DONTKNOW;
3905 if (bLatin)
3907 nLang = rAttrSet.GetLanguage( false ).GetLanguage();
3908 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3909 aAllLangs.insert( nLang );
3911 if (bAsian)
3913 nLang = rAttrSet.GetCJKLanguage( false ).GetLanguage();
3914 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3915 aAllLangs.insert( nLang );
3917 if (bComplex)
3919 nLang = rAttrSet.GetCTLLanguage( false ).GetLanguage();
3920 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3921 aAllLangs.insert( nLang );
3925 const SwTextFormatColls *pColls = pDoc->GetTextFormatColls();
3926 for (size_t i = 0; i < pColls->size(); ++i)
3928 const SwAttrSet &rAttrSet = (*pColls)[i]->GetAttrSet();
3929 LanguageType nLang = LANGUAGE_DONTKNOW;
3930 if (bLatin)
3932 nLang = rAttrSet.GetLanguage( false ).GetLanguage();
3933 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3934 aAllLangs.insert( nLang );
3936 if (bAsian)
3938 nLang = rAttrSet.GetCJKLanguage( false ).GetLanguage();
3939 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3940 aAllLangs.insert( nLang );
3942 if (bComplex)
3944 nLang = rAttrSet.GetCTLLanguage( false ).GetLanguage();
3945 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3946 aAllLangs.insert( nLang );
3950 //AUTO STYLES
3951 const IStyleAccess::SwAutoStyleFamily aFam[2] =
3953 IStyleAccess::AUTO_STYLE_CHAR,
3954 IStyleAccess::AUTO_STYLE_PARA
3956 for (IStyleAccess::SwAutoStyleFamily i : aFam)
3958 std::vector< std::shared_ptr<SfxItemSet> > rStyles;
3959 pDoc->GetIStyleAccess().getAllStyles(rStyles, i);
3960 while (!rStyles.empty())
3962 std::shared_ptr<SfxItemSet> pStyle = rStyles.back();
3963 rStyles.pop_back();
3964 const SfxItemSet *pSet = pStyle.get();
3966 LanguageType nLang = LANGUAGE_DONTKNOW;
3967 if (bLatin)
3969 assert(pSet);
3970 nLang = pSet->Get( RES_CHRATR_LANGUAGE, false ).GetLanguage();
3971 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3972 aAllLangs.insert( nLang );
3974 if (bAsian)
3976 assert(pSet);
3977 nLang = pSet->Get( RES_CHRATR_CJK_LANGUAGE, false ).GetLanguage();
3978 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3979 aAllLangs.insert( nLang );
3981 if (bComplex)
3983 assert(pSet);
3984 nLang = pSet->Get( RES_CHRATR_CTL_LANGUAGE, false ).GetLanguage();
3985 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
3986 aAllLangs.insert( nLang );
3991 //TODO/mba: it's a strange concept that a view is needed to retrieve core data
3992 SwWrtShell *pWrtSh = m_pDocShell->GetWrtShell();
3993 SdrView *pSdrView = pWrtSh->GetDrawView();
3995 if( pSdrView )
3997 SdrOutliner* pOutliner = pSdrView->GetTextEditOutliner();
3998 if(pOutliner)
4000 EditEngine& rEditEng = const_cast<EditEngine&>(pOutliner->GetEditEngine());
4001 sal_Int32 nParCount = pOutliner->GetParagraphCount();
4002 for (sal_Int32 nPar=0; nPar<nParCount; nPar++)
4004 //every paragraph
4005 std::vector<sal_Int32> aPortions;
4006 rEditEng.GetPortions( nPar, aPortions );
4008 for ( size_t nPos = aPortions.size(); nPos; )
4010 //every position
4011 --nPos;
4012 sal_Int32 nEnd = aPortions[ nPos ];
4013 sal_Int32 nStart = nPos ? aPortions[ nPos - 1 ] : 0;
4014 ESelection aSelection( nPar, nStart, nPar, nEnd );
4015 SfxItemSet aAttr = rEditEng.GetAttribs( aSelection );
4017 LanguageType nLang = LANGUAGE_DONTKNOW;
4018 if (bLatin)
4020 nLang = aAttr.Get( EE_CHAR_LANGUAGE, false ).GetLanguage();
4021 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
4022 aAllLangs.insert( nLang );
4024 if (bAsian)
4026 nLang = aAttr.Get( EE_CHAR_LANGUAGE_CJK, false ).GetLanguage();
4027 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
4028 aAllLangs.insert( nLang );
4030 if (bComplex)
4032 nLang = aAttr.Get( EE_CHAR_LANGUAGE_CTL, false ).GetLanguage();
4033 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
4034 aAllLangs.insert( nLang );
4040 // less than nMaxCount languages
4041 if (nMaxCount > static_cast< sal_Int16 >( aAllLangs.size() ))
4042 nMaxCount = static_cast< sal_Int16 >( aAllLangs.size() );
4044 // build return value
4045 uno::Sequence< lang::Locale > aLanguages( nMaxCount );
4046 lang::Locale* pLanguage = aLanguages.getArray();
4047 if (nMaxCount > 0)
4049 sal_Int32 nCount = 0;
4050 for (const auto& rLang : aAllLangs)
4052 if (nCount >= nMaxCount)
4053 break;
4054 if (LANGUAGE_NONE != rLang)
4056 pLanguage[nCount] = LanguageTag::convertToLocale( rLang );
4057 pLanguage[nCount].Language = SvtLanguageTable::GetLanguageString( rLang );
4058 nCount += 1;
4063 return aLanguages;
4066 SwXLinkTargetSupplier::SwXLinkTargetSupplier(SwXTextDocument& rxDoc) :
4067 m_pxDoc(&rxDoc)
4069 m_sTables = SwResId(STR_CONTENT_TYPE_TABLE);
4070 m_sFrames = SwResId(STR_CONTENT_TYPE_FRAME);
4071 m_sGraphics = SwResId(STR_CONTENT_TYPE_GRAPHIC);
4072 m_sOLEs = SwResId(STR_CONTENT_TYPE_OLE);
4073 m_sSections = SwResId(STR_CONTENT_TYPE_REGION);
4074 m_sOutlines = SwResId(STR_CONTENT_TYPE_OUTLINE);
4075 m_sBookmarks = SwResId(STR_CONTENT_TYPE_BOOKMARK);
4076 m_sDrawingObjects = SwResId(STR_CONTENT_TYPE_DRAWOBJECT);
4079 SwXLinkTargetSupplier::~SwXLinkTargetSupplier()
4083 Any SwXLinkTargetSupplier::getByName(const OUString& rName)
4085 Any aRet;
4086 if(!m_pxDoc)
4087 throw RuntimeException("No document available");
4088 OUString sSuffix("|");
4089 if(rName == m_sTables)
4091 sSuffix += "table";
4093 Reference< XNameAccess > xTables = new SwXLinkNameAccessWrapper(
4094 m_pxDoc->getTextTables(), rName, sSuffix );
4095 aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
4097 else if(rName == m_sFrames)
4099 sSuffix += "frame";
4100 Reference< XNameAccess > xTables = new SwXLinkNameAccessWrapper(
4101 m_pxDoc->getTextFrames(), rName, sSuffix );
4102 aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
4104 else if(rName == m_sSections)
4106 sSuffix += "region";
4107 Reference< XNameAccess > xTables = new SwXLinkNameAccessWrapper(
4108 m_pxDoc->getTextSections(), rName, sSuffix );
4109 aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
4111 else if(rName == m_sGraphics)
4113 sSuffix += "graphic";
4114 Reference< XNameAccess > xTables = new SwXLinkNameAccessWrapper(
4115 m_pxDoc->getGraphicObjects(), rName, sSuffix );
4116 aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
4118 else if(rName == m_sOLEs)
4120 sSuffix += "ole";
4121 Reference< XNameAccess > xTables = new SwXLinkNameAccessWrapper(
4122 m_pxDoc->getEmbeddedObjects(), rName, sSuffix );
4123 aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
4125 else if(rName == m_sOutlines)
4127 sSuffix += "outline";
4128 Reference< XNameAccess > xTables = new SwXLinkNameAccessWrapper(
4129 *m_pxDoc, rName, sSuffix );
4130 aRet <<= Reference< XPropertySet >(xTables, UNO_QUERY);
4132 else if(rName == m_sBookmarks)
4134 sSuffix.clear();
4135 Reference< XNameAccess > xBkms = new SwXLinkNameAccessWrapper(
4136 m_pxDoc->getBookmarks(), rName, sSuffix );
4137 aRet <<= Reference< XPropertySet >(xBkms, UNO_QUERY);
4139 else if(rName == m_sDrawingObjects)
4141 sSuffix += "drawingobject";
4142 Reference<XNameAccess> xDrawingObjects = new SwXLinkNameAccessWrapper(
4143 *m_pxDoc, rName, sSuffix);
4144 aRet <<= Reference<XPropertySet>(xDrawingObjects, UNO_QUERY);
4146 else
4147 throw NoSuchElementException();
4148 return aRet;
4151 Sequence< OUString > SwXLinkTargetSupplier::getElementNames()
4153 return { m_sTables,
4154 m_sFrames,
4155 m_sGraphics,
4156 m_sOLEs,
4157 m_sSections,
4158 m_sOutlines,
4159 m_sBookmarks,
4160 m_sDrawingObjects };
4163 sal_Bool SwXLinkTargetSupplier::hasByName(const OUString& rName)
4165 if( rName == m_sTables ||
4166 rName == m_sFrames ||
4167 rName == m_sGraphics||
4168 rName == m_sOLEs ||
4169 rName == m_sSections ||
4170 rName == m_sOutlines ||
4171 rName == m_sBookmarks ||
4172 rName == m_sDrawingObjects )
4173 return true;
4174 return false;
4177 uno::Type SwXLinkTargetSupplier::getElementType()
4179 return cppu::UnoType<XPropertySet>::get();
4183 sal_Bool SwXLinkTargetSupplier::hasElements()
4185 return nullptr != m_pxDoc;
4188 OUString SwXLinkTargetSupplier::getImplementationName()
4190 return "SwXLinkTargetSupplier";
4193 sal_Bool SwXLinkTargetSupplier::supportsService(const OUString& rServiceName)
4195 return cppu::supportsService(this, rServiceName);
4198 Sequence< OUString > SwXLinkTargetSupplier::getSupportedServiceNames()
4200 Sequence< OUString > aRet { "com.sun.star.document.LinkTargets" };
4201 return aRet;
4204 SwXLinkNameAccessWrapper::SwXLinkNameAccessWrapper(
4205 Reference< XNameAccess > const & xAccess, OUString aLinkDisplayName, OUString sSuffix ) :
4206 m_xRealAccess(xAccess),
4207 m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_LINK_TARGET)),
4208 m_sLinkSuffix(std::move(sSuffix)),
4209 m_sLinkDisplayName(std::move(aLinkDisplayName)),
4210 m_pxDoc(nullptr)
4214 SwXLinkNameAccessWrapper::SwXLinkNameAccessWrapper(SwXTextDocument& rxDoc,
4215 OUString aLinkDisplayName, OUString sSuffix) :
4216 m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_LINK_TARGET)),
4217 m_sLinkSuffix(std::move(sSuffix)),
4218 m_sLinkDisplayName(std::move(aLinkDisplayName)),
4219 m_pxDoc(&rxDoc)
4223 SwXLinkNameAccessWrapper::~SwXLinkNameAccessWrapper()
4227 Any SwXLinkNameAccessWrapper::getByName(const OUString& rName)
4229 Any aRet;
4230 bool bFound = false;
4231 //cut link extension and call the real NameAccess
4232 OUString sParam = rName;
4233 OUString sSuffix(m_sLinkSuffix);
4234 if(sParam.getLength() > sSuffix.getLength() )
4236 std::u16string_view sCmp = sParam.subView(sParam.getLength() - sSuffix.getLength(),
4237 sSuffix.getLength());
4238 if(sCmp == sSuffix)
4240 if(m_pxDoc)
4242 sParam = sParam.copy(0, sParam.getLength() - sSuffix.getLength());
4243 if(!m_pxDoc->GetDocShell())
4244 throw RuntimeException("No document shell available");
4245 SwDoc* pDoc = m_pxDoc->GetDocShell()->GetDoc();
4247 if (sSuffix == "|outline")
4249 const size_t nOutlineCount = pDoc->GetNodes().GetOutLineNds().size();
4251 for (size_t i = 0; i < nOutlineCount && !bFound; ++i)
4253 if(sParam == lcl_CreateOutlineString(i, pDoc))
4255 OUString sOutlineText =
4256 pDoc->getIDocumentOutlineNodes().getOutlineText(
4257 i, pDoc->GetDocShell()->GetWrtShell()->GetLayout());
4258 sal_Int32 nOutlineLevel = pDoc->getIDocumentOutlineNodes().getOutlineLevel(i);
4259 Reference<XPropertySet> xOutline =
4260 new SwXOutlineTarget(sParam, sOutlineText, nOutlineLevel);
4261 aRet <<= xOutline;
4262 bFound = true;
4266 else if (sSuffix == "|drawingobject")
4268 SwDrawModel* pModel = pDoc->getIDocumentDrawModelAccess().GetDrawModel();
4269 if (pModel)
4271 SdrPage* pPage = pModel->GetPage(0);
4272 for (size_t i = 0; i < pPage->GetObjCount() && !bFound; ++i)
4274 SdrObject* pObj = pPage->GetObj(i);
4275 if (sParam == pObj->GetName())
4277 Reference<XPropertySet> xDrawingObject = new SwXDrawingObjectTarget(sParam);
4278 aRet <<= xDrawingObject;
4279 bFound = true;
4285 else
4287 aRet = m_xRealAccess->getByName(sParam.copy(0, sParam.getLength() - sSuffix.getLength()));
4288 Reference< XInterface > xInt;
4289 if(!(aRet >>= xInt))
4290 throw RuntimeException("Could not retrieve property");
4291 Reference< XPropertySet > xProp(xInt, UNO_QUERY);
4292 aRet <<= xProp;
4293 bFound = true;
4297 if(!bFound)
4298 throw NoSuchElementException();
4299 return aRet;
4302 Sequence< OUString > SwXLinkNameAccessWrapper::getElementNames()
4304 Sequence< OUString > aRet;
4305 if(m_pxDoc)
4307 if(!m_pxDoc->GetDocShell())
4308 throw RuntimeException("No document shell available");
4309 SwDoc* pDoc = m_pxDoc->GetDocShell()->GetDoc();
4310 if (m_sLinkSuffix == "|outline")
4312 const SwOutlineNodes& rOutlineNodes = pDoc->GetNodes().GetOutLineNds();
4313 const size_t nOutlineCount = rOutlineNodes.size();
4314 aRet.realloc(nOutlineCount);
4315 OUString* pResArr = aRet.getArray();
4316 for (size_t i = 0; i < nOutlineCount; ++i)
4318 OUString sEntry = lcl_CreateOutlineString(i, pDoc) + "|outline";
4319 pResArr[i] = sEntry;
4322 else if (m_sLinkSuffix == "|drawingobject")
4324 SwDrawModel* pModel = pDoc->getIDocumentDrawModelAccess().GetDrawModel();
4325 if(pModel)
4327 SdrPage* pPage = pModel->GetPage(0);
4328 const size_t nObjCount = pPage->GetObjCount();
4329 aRet.realloc(nObjCount);
4330 OUString* pResArr = aRet.getArray();
4331 auto j = 0;
4332 for (size_t i = 0; i < nObjCount; ++i)
4334 SdrObject* pObj = pPage->GetObj(i);
4335 if (!pObj->GetName().isEmpty())
4336 pResArr[j++] = pObj->GetName() + "|drawingobject";
4341 else
4343 const Sequence< OUString > aOrg = m_xRealAccess->getElementNames();
4344 aRet.realloc(aOrg.getLength());
4345 std::transform(aOrg.begin(), aOrg.end(), aRet.getArray(),
4346 [this](const OUString& rOrg) -> OUString { return rOrg + m_sLinkSuffix; });
4348 return aRet;
4351 sal_Bool SwXLinkNameAccessWrapper::hasByName(const OUString& rName)
4353 bool bRet = false;
4354 OUString sParam(rName);
4355 if(sParam.getLength() > m_sLinkSuffix.getLength() )
4357 std::u16string_view sCmp = sParam.subView(sParam.getLength() - m_sLinkSuffix.getLength(),
4358 m_sLinkSuffix.getLength());
4359 if(sCmp == m_sLinkSuffix)
4361 sParam = sParam.copy(0, sParam.getLength() - m_sLinkSuffix.getLength());
4362 if(m_pxDoc)
4364 if(!m_pxDoc->GetDocShell())
4365 throw RuntimeException("No document shell available");
4366 SwDoc* pDoc = m_pxDoc->GetDocShell()->GetDoc();
4367 if (m_sLinkSuffix == "|outline")
4369 const size_t nOutlineCount = pDoc->GetNodes().GetOutLineNds().size();
4371 for (size_t i = 0; i < nOutlineCount && !bRet; ++i)
4373 if(sParam == lcl_CreateOutlineString(i, pDoc))
4375 bRet = true;
4379 else if (m_sLinkSuffix == "|drawingobject")
4381 SwDrawModel* pModel = pDoc->getIDocumentDrawModelAccess().GetDrawModel();
4382 if (pModel)
4384 SdrPage* pPage = pModel->GetPage(0);
4385 const size_t nObjCount = pPage->GetObjCount();
4386 for (size_t i = 0; i < nObjCount && !bRet; ++i)
4388 if (sParam == pPage->GetObj(i)->GetName())
4389 bRet = true;
4394 else
4396 bRet = m_xRealAccess->hasByName(sParam);
4400 return bRet;
4403 uno::Type SwXLinkNameAccessWrapper::getElementType()
4405 return cppu::UnoType<XPropertySet>::get();
4408 sal_Bool SwXLinkNameAccessWrapper::hasElements()
4410 bool bRet = false;
4411 if(m_pxDoc)
4413 OSL_FAIL("not implemented");
4415 else
4417 bRet = m_xRealAccess->hasElements();
4419 return bRet;
4422 Reference< XPropertySetInfo > SwXLinkNameAccessWrapper::getPropertySetInfo()
4424 static Reference< XPropertySetInfo > xRet = m_pPropSet->getPropertySetInfo();
4425 return xRet;
4428 void SwXLinkNameAccessWrapper::setPropertyValue(
4429 const OUString& rPropName, const Any& )
4431 throw UnknownPropertyException(rPropName);
4434 static Any lcl_GetDisplayBitmap(std::u16string_view sLinkSuffix)
4436 Any aRet;
4437 if(!sLinkSuffix.empty())
4438 sLinkSuffix = sLinkSuffix.substr(1);
4439 OUString sImgId;
4441 if(sLinkSuffix == u"outline")
4442 sImgId = RID_BMP_NAVI_OUTLINE;
4443 else if(sLinkSuffix == u"table")
4444 sImgId = RID_BMP_NAVI_TABLE;
4445 else if(sLinkSuffix == u"frame")
4446 sImgId = RID_BMP_NAVI_FRAME;
4447 else if(sLinkSuffix == u"graphic")
4448 sImgId = RID_BMP_NAVI_GRAPHIC;
4449 else if(sLinkSuffix == u"ole")
4450 sImgId = RID_BMP_NAVI_OLE;
4451 else if(sLinkSuffix.empty())
4452 sImgId = RID_BMP_NAVI_BOOKMARK;
4453 else if(sLinkSuffix == u"region")
4454 sImgId = RID_BMP_NAVI_REGION;
4455 else if(sLinkSuffix == u"drawingobject")
4456 sImgId = RID_BMP_NAVI_DRAWOBJECT;
4458 if (!sImgId.isEmpty())
4460 aRet <<= VCLUnoHelper::CreateBitmap(BitmapEx(sImgId));
4462 return aRet;
4465 Any SwXLinkNameAccessWrapper::getPropertyValue(const OUString& rPropertyName)
4467 Any aRet;
4468 if( rPropertyName == UNO_LINK_DISPLAY_NAME )
4470 aRet <<= m_sLinkDisplayName;
4472 else if( rPropertyName == UNO_LINK_DISPLAY_BITMAP )
4474 aRet = lcl_GetDisplayBitmap(m_sLinkSuffix);
4476 else
4477 throw UnknownPropertyException(rPropertyName);
4478 return aRet;
4481 void SwXLinkNameAccessWrapper::addPropertyChangeListener(
4482 const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
4485 void SwXLinkNameAccessWrapper::removePropertyChangeListener(
4486 const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
4489 void SwXLinkNameAccessWrapper::addVetoableChangeListener(
4490 const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
4493 void SwXLinkNameAccessWrapper::removeVetoableChangeListener(
4494 const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
4497 Reference< XNameAccess > SwXLinkNameAccessWrapper::getLinks()
4499 return this;
4502 OUString SwXLinkNameAccessWrapper::getImplementationName()
4504 return "SwXLinkNameAccessWrapper";
4507 sal_Bool SwXLinkNameAccessWrapper::supportsService(const OUString& rServiceName)
4509 return cppu::supportsService(this, rServiceName);
4512 Sequence< OUString > SwXLinkNameAccessWrapper::getSupportedServiceNames()
4514 Sequence< OUString > aRet { "com.sun.star.document.LinkTargets" };
4515 return aRet;
4518 SwXOutlineTarget::SwXOutlineTarget(OUString aOutlineText, OUString aActualText,
4519 const sal_Int32 nOutlineLevel) :
4520 m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_LINK_TARGET)),
4521 m_sOutlineText(std::move(aOutlineText)),
4522 m_sActualText(std::move(aActualText)),
4523 m_nOutlineLevel(nOutlineLevel)
4527 SwXOutlineTarget::~SwXOutlineTarget()
4531 Reference< XPropertySetInfo > SwXOutlineTarget::getPropertySetInfo()
4533 static Reference< XPropertySetInfo > xRet = m_pPropSet->getPropertySetInfo();
4534 return xRet;
4537 void SwXOutlineTarget::setPropertyValue(
4538 const OUString& rPropertyName, const Any& /*aValue*/)
4540 throw UnknownPropertyException(rPropertyName);
4543 Any SwXOutlineTarget::getPropertyValue(const OUString& rPropertyName)
4545 if (rPropertyName != UNO_LINK_DISPLAY_NAME && rPropertyName != "ActualOutlineName" &&
4546 rPropertyName != "OutlineLevel")
4547 throw UnknownPropertyException(rPropertyName);
4549 if (rPropertyName == "ActualOutlineName")
4550 return Any(m_sActualText);
4552 if (rPropertyName == "OutlineLevel")
4553 return Any(m_nOutlineLevel);
4555 return Any(m_sOutlineText);
4558 void SwXOutlineTarget::addPropertyChangeListener(
4559 const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
4563 void SwXOutlineTarget::removePropertyChangeListener(
4564 const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
4568 void SwXOutlineTarget::addVetoableChangeListener(
4569 const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
4573 void SwXOutlineTarget::removeVetoableChangeListener(
4574 const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
4578 OUString SwXOutlineTarget::getImplementationName()
4580 return "SwXOutlineTarget";
4583 sal_Bool SwXOutlineTarget::supportsService(const OUString& ServiceName)
4585 return cppu::supportsService(this, ServiceName);
4588 Sequence< OUString > SwXOutlineTarget::getSupportedServiceNames()
4590 Sequence<OUString> aRet { "com.sun.star.document.LinkTarget" };
4592 return aRet;
4595 SwXDrawingObjectTarget::SwXDrawingObjectTarget(OUString aDrawingObjectText) :
4596 m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_LINK_TARGET)),
4597 m_sDrawingObjectText(std::move(aDrawingObjectText))
4601 SwXDrawingObjectTarget::~SwXDrawingObjectTarget()
4605 Reference< XPropertySetInfo > SwXDrawingObjectTarget::getPropertySetInfo()
4607 static Reference< XPropertySetInfo > xRet = m_pPropSet->getPropertySetInfo();
4608 return xRet;
4611 void SwXDrawingObjectTarget::setPropertyValue(
4612 const OUString& rPropertyName, const Any& /*aValue*/)
4614 throw UnknownPropertyException(rPropertyName);
4617 Any SwXDrawingObjectTarget::getPropertyValue(const OUString& rPropertyName)
4619 if(rPropertyName != UNO_LINK_DISPLAY_NAME)
4620 throw UnknownPropertyException(rPropertyName);
4622 return Any(m_sDrawingObjectText);
4625 void SwXDrawingObjectTarget::addPropertyChangeListener(
4626 const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
4630 void SwXDrawingObjectTarget::removePropertyChangeListener(
4631 const OUString& /*PropertyName*/, const Reference< XPropertyChangeListener > & /*aListener*/)
4635 void SwXDrawingObjectTarget::addVetoableChangeListener(
4636 const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
4640 void SwXDrawingObjectTarget::removeVetoableChangeListener(
4641 const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener > & /*aListener*/)
4645 OUString SwXDrawingObjectTarget::getImplementationName()
4647 return "SwXDrawingObjectTarget";
4650 sal_Bool SwXDrawingObjectTarget::supportsService(const OUString& ServiceName)
4652 return cppu::supportsService(this, ServiceName);
4655 Sequence< OUString > SwXDrawingObjectTarget::getSupportedServiceNames()
4657 Sequence<OUString> aRet { "com.sun.star.document.LinkTarget" };
4659 return aRet;
4662 SwXDocumentPropertyHelper::SwXDocumentPropertyHelper(SwDoc& rDoc) :
4663 SvxUnoForbiddenCharsTable ( rDoc.getIDocumentSettingAccess().getForbiddenCharacterTable() )
4664 ,m_pDoc(&rDoc)
4668 SwXDocumentPropertyHelper::~SwXDocumentPropertyHelper()
4672 Reference<XInterface> SwXDocumentPropertyHelper::GetDrawTable(SwCreateDrawTable nWhich)
4674 Reference<XInterface> xRet;
4675 if(m_pDoc)
4677 switch(nWhich)
4679 // #i52858#
4680 // assure that Draw model is created, if it doesn't exist.
4681 case SwCreateDrawTable::Dash :
4682 if(!m_xDashTable.is())
4683 m_xDashTable = SvxUnoDashTable_createInstance( m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
4684 xRet = m_xDashTable;
4685 break;
4686 case SwCreateDrawTable::Gradient :
4687 if(!m_xGradientTable.is())
4688 m_xGradientTable = SvxUnoGradientTable_createInstance( m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
4689 xRet = m_xGradientTable;
4690 break;
4691 case SwCreateDrawTable::Hatch :
4692 if(!m_xHatchTable.is())
4693 m_xHatchTable = SvxUnoHatchTable_createInstance( m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
4694 xRet = m_xHatchTable;
4695 break;
4696 case SwCreateDrawTable::Bitmap :
4697 if(!m_xBitmapTable.is())
4698 m_xBitmapTable = SvxUnoBitmapTable_createInstance( m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
4699 xRet = m_xBitmapTable;
4700 break;
4701 case SwCreateDrawTable::TransGradient:
4702 if(!m_xTransGradientTable.is())
4703 m_xTransGradientTable = SvxUnoTransGradientTable_createInstance( m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
4704 xRet = m_xTransGradientTable;
4705 break;
4706 case SwCreateDrawTable::Marker :
4707 if(!m_xMarkerTable.is())
4708 m_xMarkerTable = SvxUnoMarkerTable_createInstance( m_pDoc->getIDocumentDrawModelAccess().GetOrCreateDrawModel() );
4709 xRet = m_xMarkerTable;
4710 break;
4711 case SwCreateDrawTable::Defaults:
4712 if(!m_xDrawDefaults.is())
4713 m_xDrawDefaults = static_cast<cppu::OWeakObject*>(new SwSvxUnoDrawPool(*m_pDoc));
4714 xRet = m_xDrawDefaults;
4715 break;
4716 #if OSL_DEBUG_LEVEL > 0
4717 default: OSL_FAIL("which table?");
4718 #endif
4721 return xRet;
4724 void SwXDocumentPropertyHelper::Invalidate()
4726 m_xDashTable = nullptr;
4727 m_xGradientTable = nullptr;
4728 m_xHatchTable = nullptr;
4729 m_xBitmapTable = nullptr;
4730 m_xTransGradientTable = nullptr;
4731 m_xMarkerTable = nullptr;
4732 m_xDrawDefaults = nullptr;
4733 m_pDoc = nullptr;
4734 SvxUnoForbiddenCharsTable::mxForbiddenChars.reset();
4737 void SwXDocumentPropertyHelper::onChange()
4739 if(m_pDoc)
4740 m_pDoc->getIDocumentState().SetModified();
4743 SwViewOptionAdjust_Impl::SwViewOptionAdjust_Impl(
4744 SwViewShell& rSh, const SwViewOption &rViewOptions)
4745 : m_pShell(&rSh)
4746 , m_aOldViewOptions( rViewOptions )
4750 SwViewOptionAdjust_Impl::~SwViewOptionAdjust_Impl()
4752 if (m_pShell)
4754 m_pShell->ApplyViewOptions( m_aOldViewOptions );
4758 void
4759 SwViewOptionAdjust_Impl::AdjustViewOptions(SwPrintData const*const pPrtOptions, bool setShowPlaceHoldersInPDF)
4761 // to avoid unnecessary reformatting the view options related to the content
4762 // below should only change if necessary, that is if respective content is present
4763 const bool bContainsHiddenChars = m_pShell->GetDoc()->ContainsHiddenChars();
4764 const SwFieldType* pFieldType = m_pShell->GetDoc()->getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::HiddenText );
4765 const bool bContainsHiddenFields = pFieldType && pFieldType->HasWriterListeners();
4766 pFieldType = m_pShell->GetDoc()->getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::HiddenPara );
4767 const bool bContainsHiddenParagraphs = pFieldType && pFieldType->HasWriterListeners();
4768 pFieldType = m_pShell->GetDoc()->getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::JumpEdit );
4769 const bool bContainsPlaceHolders = pFieldType && pFieldType->HasWriterListeners();
4770 const bool bContainsFields = m_pShell->IsAnyFieldInDoc();
4772 SwViewOption aRenderViewOptions( m_aOldViewOptions );
4774 // disable anything in the view that should not be printed (or exported to PDF) by default
4775 // (see also dialog "Tools/Options - StarOffice Writer - Formatting Aids"
4776 // in section "Display of ...")
4777 aRenderViewOptions.SetParagraph( false ); // paragraph end
4778 aRenderViewOptions.SetSoftHyph( false ); // aka custom hyphens
4779 aRenderViewOptions.SetBlank( false ); // spaces
4780 aRenderViewOptions.SetHardBlank( false ); // non-breaking spaces
4781 aRenderViewOptions.SetTab( false ); // tabs
4782 aRenderViewOptions.SetShowBookmarks( false ); // bookmarks
4783 aRenderViewOptions.SetLineBreak( false ); // breaks (type 1)
4784 aRenderViewOptions.SetPageBreak( false ); // breaks (type 2)
4785 aRenderViewOptions.SetColumnBreak( false ); // breaks (type 3)
4786 bool bVal = pPrtOptions && pPrtOptions->m_bPrintHiddenText;
4787 if (bContainsHiddenChars)
4788 aRenderViewOptions.SetShowHiddenChar( bVal ); // hidden text
4789 if (bContainsHiddenFields)
4790 aRenderViewOptions.SetShowHiddenField( bVal );
4791 if (bContainsHiddenParagraphs)
4792 aRenderViewOptions.SetShowHiddenPara( bVal );
4794 if (bContainsPlaceHolders)
4796 // should always be printed in PDF export!
4797 bVal = !pPrtOptions ? setShowPlaceHoldersInPDF : pPrtOptions->m_bPrintTextPlaceholder;
4798 aRenderViewOptions.SetShowPlaceHolderFields( bVal );
4801 if (bContainsFields)
4802 aRenderViewOptions.SetFieldName( false );
4804 // we need to set this flag in order to get to see the visible effect of
4805 // some of the above settings (needed for correct rendering)
4806 aRenderViewOptions.SetViewMetaChars( true );
4808 if (m_aOldViewOptions != aRenderViewOptions) // check if reformatting is necessary
4810 aRenderViewOptions.SetPrinting( pPrtOptions != nullptr );
4811 m_pShell->ApplyViewOptions( aRenderViewOptions );
4815 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */