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