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