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 <libxml/xmlwriter.h>
21 
22 #include "PageListWatcher.hxx"
23 #include <com/sun/star/document/PrinterIndependentLayout.hpp>
24 #include <com/sun/star/i18n/ScriptType.hpp>
25 #include <com/sun/star/beans/XPropertyContainer.hpp>
26 #include <com/sun/star/beans/PropertyAttribute.hpp>
27 #include <com/sun/star/document/XDocumentProperties.hpp>
28 #include <com/sun/star/frame/XModel.hpp>
29 #include <editeng/forbiddencharacterstable.hxx>
30 
31 #include <svl/srchitem.hxx>
32 #include <editeng/eeitem.hxx>
33 #include <editeng/scriptspaceitem.hxx>
34 #include <tools/debug.hxx>
35 
36 #include <unotools/configmgr.hxx>
37 #include <unotools/useroptions.hxx>
38 #include <officecfg/Office/Impress.hxx>
39 
40 #include <sfx2/linkmgr.hxx>
41 #include <Outliner.hxx>
42 #include <sdmod.hxx>
43 #include <editeng/editstat.hxx>
44 #include <svx/svdotext.hxx>
45 #include <editeng/unolingu.hxx>
46 #include <svl/itempool.hxx>
47 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
48 #include <com/sun/star/beans/XPropertySet.hpp>
49 #include <editeng/outlobj.hxx>
50 #include <comphelper/getexpandeduri.hxx>
51 #include <i18nlangtag/mslangid.hxx>
52 #include <i18nlangtag/languagetag.hxx>
53 #include <unotools/charclass.hxx>
54 #include <comphelper/processfactory.hxx>
55 #include <unotools/lingucfg.hxx>
56 #include <com/sun/star/uno/Reference.hxx>
57 #include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
58 #include <com/sun/star/xml/dom/XDocument.hpp>
59 #include <com/sun/star/xml/dom/XNodeList.hpp>
60 #include <com/sun/star/xml/dom/DocumentBuilder.hpp>
61 #include <com/sun/star/uno/XComponentContext.hpp>
62 #include <rtl/ustring.hxx>
63 
64 #include <editeng/outliner.hxx>
65 #include <drawdoc.hxx>
66 #include <sdpage.hxx>
67 #include <strings.hrc>
68 #include <glob.hxx>
69 #include <stlpool.hxx>
70 #include <sdresid.hxx>
71 #include <customshowlist.hxx>
72 #include <DrawDocShell.hxx>
73 #include <GraphicDocShell.hxx>
74 #include <sdxfer.hxx>
75 #include <optsitem.hxx>
76 #include <FrameView.hxx>
77 #include <undo/undomanager.hxx>
78 #include <sdundogr.hxx>
79 #include <undopage.hxx>
80 #include <vcl/settings.hxx>
81 #include <vcl/svapp.hxx>
82 #include <unokywds.hxx>
83 
84 namespace com::sun::star::linguistic2 { class XHyphenator; }
85 namespace com::sun::star::linguistic2 { class XSpellChecker1; }
86 
87 using namespace ::sd;
88 using namespace ::com::sun::star;
89 using namespace ::com::sun::star::uno;
90 using namespace ::com::sun::star::lang;
91 using namespace ::com::sun::star::linguistic2;
92 
93 using namespace com::sun::star::xml::dom;
94 using ::com::sun::star::uno::Reference;
95 using ::com::sun::star::lang::XMultiServiceFactory;
96 
97 
98 SdDrawDocument* SdDrawDocument::s_pDocLockedInsertingLinks = nullptr;
99 
PresentationSettings()100 PresentationSettings::PresentationSettings()
101 :   mbAll( true ),
102     mbEndless( false ),
103     mbCustomShow(false),
104     mbManual( false ),
105     mbMouseVisible( false ),
106     mbMouseAsPen( false ),
107     mbLockedPages( false ),
108     mbAlwaysOnTop( false ),
109     mbFullScreen( true ),
110     mbAnimationAllowed( true ),
111     mnPauseTimeout( 0 ),
112     mbShowPauseLogo( false ),
113     mbStartCustomShow( false )
114 {
115 }
116 
SdDrawDocument(DocumentType eType,SfxObjectShell * pDrDocSh)117 SdDrawDocument::SdDrawDocument(DocumentType eType, SfxObjectShell* pDrDocSh)
118 :   FmFormModel(
119         nullptr,
120         pDrDocSh)
121 , mpDocSh(static_cast< ::sd::DrawDocShell*>(pDrDocSh))
122 , mpCreatingTransferable( nullptr )
123 , mbHasOnlineSpellErrors(false)
124 , mbInitialOnlineSpellingEnabled(true)
125 , mbNewOrLoadCompleted(false)
126 , mbOnlineSpell(false)
127 , mbStartWithPresentation( false )
128 , mbExitAfterPresenting( false )
129 , meLanguage( LANGUAGE_SYSTEM )
130 , meLanguageCJK( LANGUAGE_SYSTEM )
131 , meLanguageCTL( LANGUAGE_SYSTEM )
132 , mePageNumType(SVX_NUM_ARABIC)
133 , mbAllocDocSh(false)
134 , meDocType(eType)
135 , mbEmbedFonts(false)
136 , mbEmbedUsedFontsOnly(false)
137 , mbEmbedFontScriptLatin(true)
138 , mbEmbedFontScriptAsian(true)
139 , mbEmbedFontScriptComplex(true)
140 {
141     mpDrawPageListWatcher.reset(new ImpDrawPageListWatcher(*this));
142     mpMasterPageListWatcher.reset(new ImpMasterPageListWatcher(*this));
143 
144     InitLayoutVector();
145     InitObjectVector();
146     SetObjectShell(pDrDocSh);       // for VCDrawModel
147 
148     if (mpDocSh)
149     {
150         SetSwapGraphics();
151     }
152 
153     // Set measuring unit (of the application) and scale (of SdMod)
154     sal_Int32 nX, nY;
155     SdOptions* pOptions = SD_MOD()->GetSdOptions(meDocType);
156     pOptions->GetScale( nX, nY );
157 
158     // Allow UI scale only for draw documents.
159     if( eType == DocumentType::Draw )
160         SetUIUnit( static_cast<FieldUnit>(pOptions->GetMetric()), Fraction( nX, nY ) );  // user-defined
161     else
162         SetUIUnit( static_cast<FieldUnit>(pOptions->GetMetric()), Fraction( 1, 1 ) );    // default
163 
164     SetScaleUnit(MapUnit::Map100thMM);
165     SetScaleFraction(Fraction(1, 1));
166     SetDefaultFontHeight(847);     // 24p
167 
168     m_pItemPool->SetDefaultMetric(MapUnit::Map100thMM);
169     m_pItemPool->FreezeIdRanges();
170     SetTextDefaults();
171 
172     // DrawingEngine has to know where it is...
173     FmFormModel::SetStyleSheetPool( new SdStyleSheetPool( GetPool(), this ) );
174 
175     // Set StyleSheetPool for DrawOutliner, so text objects can be read correctly.
176     // The link to the StyleRequest handler of the document is set later, in
177     // NewOrLoadCompleted, because only then do all the templates exist.
178     SdrOutliner& rOutliner = GetDrawOutliner();
179     rOutliner.SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
180     SetCalcFieldValueHdl( &rOutliner );
181 
182     // set linguistic options
183     if (!utl::ConfigManager::IsFuzzing())
184     {
185         const SvtLinguConfig    aLinguConfig;
186         SvtLinguOptions         aOptions;
187         aLinguConfig.GetOptions( aOptions );
188 
189         SetLanguage( MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage,
190             css::i18n::ScriptType::LATIN), EE_CHAR_LANGUAGE );
191         SetLanguage( MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage_CJK,
192             css::i18n::ScriptType::ASIAN), EE_CHAR_LANGUAGE_CJK );
193         SetLanguage( MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage_CTL,
194             css::i18n::ScriptType::COMPLEX), EE_CHAR_LANGUAGE_CTL );
195 
196         mbOnlineSpell = aOptions.bIsSpellAuto;
197     }
198 
199     LanguageType eRealLanguage = MsLangId::getRealLanguage( meLanguage );
200     LanguageTag aLanguageTag( eRealLanguage);
201     mpCharClass.reset(new CharClass( aLanguageTag ));
202 
203     // If the current application language is a language that uses right-to-left text...
204     LanguageType eRealCTLLanguage = Application::GetSettings().GetLanguageTag().getLanguageType();
205 
206     // for korean and japanese languages we have a different default for apply spacing between asian, latin and ctl text
207     if (MsLangId::isKorean(eRealCTLLanguage) || (LANGUAGE_JAPANESE == eRealCTLLanguage))
208     {
209         GetPool().GetSecondaryPool()->SetPoolDefaultItem( SvxScriptSpaceItem( false, EE_PARA_ASIANCJKSPACING ) );
210     }
211 
212     // Set DefTab and SpellOptions for the SD module
213     sal_uInt16 nDefTab = pOptions->GetDefTab();
214     SetDefaultTabulator( nDefTab );
215 
216     try
217     {
218         Reference< XSpellChecker1 > xSpellChecker( LinguMgr::GetSpellChecker() );
219         if ( xSpellChecker.is() )
220             rOutliner.SetSpeller( xSpellChecker );
221 
222         Reference< XHyphenator > xHyphenator( LinguMgr::GetHyphenator() );
223         if( xHyphenator.is() )
224             rOutliner.SetHyphenator( xHyphenator );
225 
226         SetForbiddenCharsTable(SvxForbiddenCharactersTable::makeForbiddenCharactersTable(::comphelper::getProcessComponentContext()));
227     }
228     catch(...)
229     {
230         OSL_FAIL("Can't get SpellChecker");
231     }
232 
233     rOutliner.SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
234 
235     if (mpDocSh)
236     {
237         SetLinkManager( new sfx2::LinkManager(mpDocSh) );
238     }
239 
240     EEControlBits nCntrl = rOutliner.GetControlWord();
241     nCntrl |= EEControlBits::ALLOWBIGOBJS;
242 
243     if (mbOnlineSpell)
244         nCntrl |= EEControlBits::ONLINESPELLING;
245     else
246         nCntrl &= ~EEControlBits::ONLINESPELLING;
247 
248     nCntrl &= ~ EEControlBits::ULSPACESUMMATION;
249     if ( meDocType != DocumentType::Impress )
250         SetSummationOfParagraphs( false );
251     else
252     {
253         SetSummationOfParagraphs( pOptions->IsSummationOfParagraphs() );
254         if ( pOptions->IsSummationOfParagraphs() )
255             nCntrl |= EEControlBits::ULSPACESUMMATION;
256     }
257     rOutliner.SetControlWord(nCntrl);
258 
259     // Initialize the printer independent layout mode
260     SetPrinterIndependentLayout (pOptions->GetPrinterIndependentLayout());
261 
262     // Set the StyleSheetPool for HitTestOutliner.
263     // The link to the StyleRequest handler of the document is set later, in
264     // NewOrLoadCompleted, because only then do all the templates exist.
265     m_pHitTestOutliner->SetStyleSheetPool( static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()) );
266 
267     SetCalcFieldValueHdl( m_pHitTestOutliner.get() );
268 
269     try
270     {
271         Reference< XSpellChecker1 > xSpellChecker( LinguMgr::GetSpellChecker() );
272         if ( xSpellChecker.is() )
273             m_pHitTestOutliner->SetSpeller( xSpellChecker );
274 
275         Reference< XHyphenator > xHyphenator( LinguMgr::GetHyphenator() );
276         if( xHyphenator.is() )
277             m_pHitTestOutliner->SetHyphenator( xHyphenator );
278     }
279     catch(...)
280     {
281         OSL_FAIL("Can't get SpellChecker");
282     }
283 
284     m_pHitTestOutliner->SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
285 
286     EEControlBits nCntrl2 = m_pHitTestOutliner->GetControlWord();
287     nCntrl2 |= EEControlBits::ALLOWBIGOBJS;
288     nCntrl2 &= ~EEControlBits::ONLINESPELLING;
289 
290     nCntrl2 &= ~ EEControlBits::ULSPACESUMMATION;
291     if ( pOptions->IsSummationOfParagraphs() )
292         nCntrl2 |= EEControlBits::ULSPACESUMMATION;
293 
294     m_pHitTestOutliner->SetControlWord( nCntrl2 );
295 
296     /** Create layers
297       *
298       * We create the following default layers on all pages and master pages:
299       *
300       * sUNO_LayerName_layout; "layout": default layer for drawing objects of normal pages
301       * localized by SdResId(STR_LAYER_LAYOUT)
302       *
303       * sUNO_LayerName_background; "background": background of the master page
304       * localized by SdResId(STR_LAYER_BCKGRND)
305       *           (currently unused within normal pages and not visible to users)
306       *
307       * sUNO_LayerName_background_objects; "backgroundobjects": objects on the background of master pages
308       * localized by SdResId(STR_LAYER_BCKGRNDOBJ)
309       *           (currently unused within normal pages)
310       *
311       * sUNO_LayerName_controls; "controls": default layer for controls
312       * localized by SdResId(STR_LAYER_CONTROLS)
313       *           (currently special handling in regard to z-order)
314       *
315       * sUNO_LayerName_measurelines; "measurelines" : default layer for measure lines
316       * localized by SdResId(STR_LAYER_MEASURELINES)
317       */
318 
319     {
320         SdrLayerAdmin& rLayerAdmin = GetLayerAdmin();
321         rLayerAdmin.NewLayer( sUNO_LayerName_layout );
322         rLayerAdmin.NewLayer( sUNO_LayerName_background );
323         rLayerAdmin.NewLayer( sUNO_LayerName_background_objects );
324         rLayerAdmin.NewLayer( sUNO_LayerName_controls);
325         rLayerAdmin.NewLayer( sUNO_LayerName_measurelines );
326 
327         rLayerAdmin.SetControlLayerName(sUNO_LayerName_controls);
328     }
329 
330 }
331 
332 // Destructor
~SdDrawDocument()333 SdDrawDocument::~SdDrawDocument()
334 {
335     Broadcast(SdrHint(SdrHintKind::ModelCleared));
336 
337     if (mpWorkStartupTimer)
338     {
339         if ( mpWorkStartupTimer->IsActive() )
340             mpWorkStartupTimer->Stop();
341 
342         mpWorkStartupTimer.reset();
343     }
344 
345     StopOnlineSpelling();
346     mpOnlineSearchItem.reset();
347 
348     CloseBookmarkDoc();
349     SetAllocDocSh(false);
350 
351     ClearModel(true);
352 
353     if (m_pLinkManager)
354     {
355         // Release BaseLinks
356         if ( !m_pLinkManager->GetLinks().empty() )
357         {
358             m_pLinkManager->Remove( 0, m_pLinkManager->GetLinks().size() );
359         }
360 
361         delete m_pLinkManager;
362         m_pLinkManager = nullptr;
363     }
364 
365     maFrameViewList.clear();
366     mpCustomShowList.reset();
367     mpOutliner.reset();
368     mpInternalOutliner.reset();
369     mpCharClass.reset();
370 }
371 
adaptSizeAndBorderForAllPages(const Size & rNewSize,::tools::Long nLeft,::tools::Long nRight,::tools::Long nUpper,::tools::Long nLower)372 void SdDrawDocument::adaptSizeAndBorderForAllPages(
373     const Size& rNewSize,
374     ::tools::Long nLeft,
375     ::tools::Long nRight,
376     ::tools::Long nUpper,
377     ::tools::Long nLower)
378 {
379     const sal_uInt16 nMasterPageCnt(GetMasterSdPageCount(PageKind::Standard));
380     const sal_uInt16 nPageCnt(GetSdPageCount(PageKind::Standard));
381 
382     if(0 == nMasterPageCnt && 0 == nPageCnt)
383     {
384         return;
385     }
386 
387     SdPage* pPage(0 != nPageCnt ? GetSdPage(0, PageKind::Standard) : GetMasterSdPage(0, PageKind::Standard));
388 
389     // call fully implemented local version, including getting
390     // some more information from one of the Pages (1st one)
391     AdaptPageSizeForAllPages(
392         rNewSize,
393         PageKind::Standard,
394         nullptr,
395         nLeft,
396         nRight,
397         nUpper,
398         nLower,
399         true,
400         pPage->GetOrientation(),
401         pPage->GetPaperBin(),
402         pPage->IsBackgroundFullSize());
403 
404     // adjust handout page to new format of the standard page
405     if(0 != nPageCnt)
406     {
407         GetSdPage(0, PageKind::Handout)->CreateTitleAndLayout(true);
408     }
409 }
410 
AdaptPageSizeForAllPages(const Size & rNewSize,PageKind ePageKind,SdUndoGroup * pUndoGroup,::tools::Long nLeft,::tools::Long nRight,::tools::Long nUpper,::tools::Long nLower,bool bScaleAll,Orientation eOrientation,sal_uInt16 nPaperBin,bool bBackgroundFullSize)411 void SdDrawDocument::AdaptPageSizeForAllPages(
412     const Size& rNewSize,
413     PageKind ePageKind,
414     SdUndoGroup* pUndoGroup,
415     ::tools::Long nLeft,
416     ::tools::Long nRight,
417     ::tools::Long nUpper,
418     ::tools::Long nLower,
419     bool bScaleAll,
420     Orientation eOrientation,
421     sal_uInt16 nPaperBin,
422     bool bBackgroundFullSize)
423 {
424     sal_uInt16 i;
425     const sal_uInt16 nMasterPageCnt(GetMasterSdPageCount(ePageKind));
426     const sal_uInt16 nPageCnt(GetSdPageCount(ePageKind));
427 
428     if(0 == nMasterPageCnt && 0 == nPageCnt)
429     {
430         return;
431     }
432 
433     for (i = 0; i < nMasterPageCnt; i++)
434     {
435         // first, handle all master pages
436         SdPage* pPage(GetMasterSdPage(i, ePageKind));
437 
438         if(pUndoGroup)
439         {
440             SdUndoAction* pUndo(
441                 new SdPageFormatUndoAction(
442                     this,
443                     pPage,
444                     pPage->GetSize(),
445                     pPage->GetLeftBorder(), pPage->GetRightBorder(),
446                     pPage->GetUpperBorder(), pPage->GetLowerBorder(),
447                     pPage->GetOrientation(),
448                     pPage->GetPaperBin(),
449                     pPage->IsBackgroundFullSize(),
450                     rNewSize,
451                     nLeft, nRight,
452                     nUpper, nLower,
453                     bScaleAll,
454                     eOrientation,
455                     nPaperBin,
456                     bBackgroundFullSize));
457             pUndoGroup->AddAction(pUndo);
458         }
459 
460         if (rNewSize.Width() > 0 || nLeft  >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0)
461         {
462             ::tools::Rectangle aNewBorderRect(nLeft, nUpper, nRight, nLower);
463             pPage->ScaleObjects(rNewSize, aNewBorderRect, bScaleAll);
464 
465             if (rNewSize.Width() > 0)
466             {
467                 pPage->SetSize(rNewSize);
468             }
469         }
470 
471         if( nLeft  >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0 )
472         {
473             pPage->SetBorder(nLeft, nUpper, nRight, nLower);
474         }
475 
476         pPage->SetOrientation(eOrientation);
477         pPage->SetPaperBin( nPaperBin );
478         pPage->SetBackgroundFullSize( bBackgroundFullSize );
479 
480         if ( ePageKind == PageKind::Standard )
481         {
482             GetMasterSdPage(i, PageKind::Notes)->CreateTitleAndLayout();
483         }
484 
485         pPage->CreateTitleAndLayout();
486     }
487 
488     for (i = 0; i < nPageCnt; i++)
489     {
490         // then, handle all pages
491         SdPage* pPage(GetSdPage(i, ePageKind));
492 
493         if(pUndoGroup)
494         {
495             SdUndoAction* pUndo(
496                 new SdPageFormatUndoAction(
497                     this,
498                     pPage,
499                     pPage->GetSize(),
500                     pPage->GetLeftBorder(), pPage->GetRightBorder(),
501                     pPage->GetUpperBorder(), pPage->GetLowerBorder(),
502                     pPage->GetOrientation(),
503                     pPage->GetPaperBin(),
504                     pPage->IsBackgroundFullSize(),
505                     rNewSize,
506                     nLeft, nRight,
507                     nUpper, nLower,
508                     bScaleAll,
509                     eOrientation,
510                     nPaperBin,
511                     bBackgroundFullSize));
512             pUndoGroup->AddAction(pUndo);
513         }
514 
515         if (rNewSize.Width() > 0 || nLeft  >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0)
516         {
517             ::tools::Rectangle aNewBorderRect(nLeft, nUpper, nRight, nLower);
518             pPage->ScaleObjects(rNewSize, aNewBorderRect, bScaleAll);
519 
520             if (rNewSize.Width() > 0)
521             {
522                 pPage->SetSize(rNewSize);
523             }
524         }
525 
526         if( nLeft  >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0 )
527         {
528             pPage->SetBorder(nLeft, nUpper, nRight, nLower);
529         }
530 
531         pPage->SetOrientation(eOrientation);
532         pPage->SetPaperBin( nPaperBin );
533         pPage->SetBackgroundFullSize( bBackgroundFullSize );
534 
535         if ( ePageKind == PageKind::Standard )
536         {
537             SdPage* pNotesPage = GetSdPage(i, PageKind::Notes);
538             pNotesPage->SetAutoLayout( pNotesPage->GetAutoLayout() );
539         }
540 
541         pPage->SetAutoLayout( pPage->GetAutoLayout() );
542     }
543 }
544 
AllocModel() const545 SdrModel* SdDrawDocument::AllocModel() const
546 {
547     return AllocSdDrawDocument();
548 }
549 
550 namespace
551 {
552 
553 /// Copies all user-defined properties from pSource to pDestination.
lcl_copyUserDefinedProperties(const SfxObjectShell * pSource,const SfxObjectShell * pDestination)554 void lcl_copyUserDefinedProperties(const SfxObjectShell* pSource, const SfxObjectShell* pDestination)
555 {
556     if (!pSource || !pDestination)
557         return;
558 
559     uno::Reference<document::XDocumentProperties> xSource = pSource->getDocProperties();
560     uno::Reference<document::XDocumentProperties> xDestination = pDestination->getDocProperties();
561     uno::Reference<beans::XPropertyContainer> xSourcePropertyContainer = xSource->getUserDefinedProperties();
562     uno::Reference<beans::XPropertyContainer> xDestinationPropertyContainer = xDestination->getUserDefinedProperties();
563     uno::Reference<beans::XPropertySet> xSourcePropertySet(xSourcePropertyContainer, uno::UNO_QUERY);
564     const uno::Sequence<beans::Property> aProperties = xSourcePropertySet->getPropertySetInfo()->getProperties();
565 
566     for (const beans::Property& rProperty : aProperties)
567     {
568         const OUString& rKey = rProperty.Name;
569         uno::Any aValue = xSourcePropertySet->getPropertyValue(rKey);
570         // We know that pDestination was just created, so has no properties: addProperty() will never throw.
571         xDestinationPropertyContainer->addProperty(rKey, beans::PropertyAttribute::REMOVABLE, aValue);
572     }
573 }
574 
575 }
576 
577 // This method creates a new document (SdDrawDocument) and returns a pointer to
578 // said document. The drawing engine uses this method to put the document (or
579 // parts of it) into the clipboard/DragServer.
AllocSdDrawDocument() const580 SdDrawDocument* SdDrawDocument::AllocSdDrawDocument() const
581 {
582     SdDrawDocument* pNewModel = nullptr;
583 
584     if( mpCreatingTransferable )
585     {
586         // Document is created for drag & drop/clipboard. To be able to
587         // do this, the document has to know a DocShell (SvPersist).
588         SfxObjectShell*   pObj = nullptr;
589         ::sd::DrawDocShell*     pNewDocSh = nullptr;
590 
591         if( meDocType == DocumentType::Impress )
592             mpCreatingTransferable->SetDocShell( new ::sd::DrawDocShell(
593                 SfxObjectCreateMode::EMBEDDED, true, meDocType ) );
594         else
595             mpCreatingTransferable->SetDocShell( new ::sd::GraphicDocShell(
596                 SfxObjectCreateMode::EMBEDDED ) );
597 
598         pObj = mpCreatingTransferable->GetDocShell().get();
599         pNewDocSh = static_cast< ::sd::DrawDocShell*>( pObj );
600         pNewDocSh->DoInitNew();
601         pNewModel = pNewDocSh->GetDoc();
602 
603         // Only necessary for clipboard -
604         // for drag & drop this is handled by DragServer
605         SdStyleSheetPool* pOldStylePool = static_cast<SdStyleSheetPool*>( GetStyleSheetPool() );
606         SdStyleSheetPool* pNewStylePool = static_cast<SdStyleSheetPool*>( pNewModel->GetStyleSheetPool() );
607 
608         pNewStylePool->CopyGraphicSheets(*pOldStylePool);
609         pNewStylePool->CopyCellSheets(*pOldStylePool);
610         pNewStylePool->CopyTableStyles(*pOldStylePool);
611 
612         for (sal_uInt16 i = 0; i < GetMasterSdPageCount(PageKind::Standard); i++)
613         {
614             // Move with all of the master page's layouts
615             OUString aOldLayoutName(const_cast<SdDrawDocument*>(this)->GetMasterSdPage(i, PageKind::Standard)->GetLayoutName());
616             aOldLayoutName = aOldLayoutName.copy( 0, aOldLayoutName.indexOf( SD_LT_SEPARATOR ) );
617             StyleSheetCopyResultVector aCreatedSheets;
618             pNewStylePool->CopyLayoutSheets(aOldLayoutName, *pOldStylePool, aCreatedSheets );
619         }
620 
621         lcl_copyUserDefinedProperties(GetDocSh(), pNewDocSh);
622 
623         pNewModel->NewOrLoadCompleted( DocCreationMode::Loaded );  // loaded from source document
624     }
625     else if( mbAllocDocSh )
626     {
627         // Create a DocShell which is then returned with GetAllocedDocSh()
628         SdDrawDocument* pDoc = const_cast<SdDrawDocument*>(this);
629         pDoc->SetAllocDocSh(false);
630         pDoc->mxAllocedDocShRef = new ::sd::DrawDocShell(
631             SfxObjectCreateMode::EMBEDDED, true, meDocType);
632         pDoc->mxAllocedDocShRef->DoInitNew();
633         pNewModel = pDoc->mxAllocedDocShRef->GetDoc();
634     }
635     else
636     {
637         pNewModel = new SdDrawDocument(meDocType, nullptr);
638     }
639 
640     return pNewModel;
641 }
642 
AllocSdPage(bool bMasterPage)643 rtl::Reference<SdPage> SdDrawDocument::AllocSdPage(bool bMasterPage)
644 {
645     return new SdPage(*this, bMasterPage);
646 }
647 
648 // This method creates a new page (SdPage) and returns a pointer to said page.
649 // The drawing engine uses this method to create pages (whose types it does
650 // not know, as they are _derivatives_ of SdrPage) when loading.
AllocPage(bool bMasterPage)651 rtl::Reference<SdrPage> SdDrawDocument::AllocPage(bool bMasterPage)
652 {
653     return AllocSdPage(bMasterPage);
654 }
655 
656 // When the model has changed
SetChanged(bool bFlag)657 void SdDrawDocument::SetChanged(bool bFlag)
658 {
659     if (mpDocSh)
660     {
661         if (mbNewOrLoadCompleted && mpDocSh->IsEnableSetModified())
662         {
663             // Pass on to base class
664             FmFormModel::SetChanged(bFlag);
665 
666             // Forward to ObjectShell
667             mpDocSh->SetModified(bFlag);
668         }
669     }
670     else
671     {
672         // Pass on to base class
673         FmFormModel::SetChanged(bFlag);
674     }
675 }
676 
677 // The model changed, don't call anything else
NbcSetChanged(bool bFlag)678 void SdDrawDocument::NbcSetChanged(bool bFlag)
679 {
680     // forward to baseclass
681     FmFormModel::SetChanged(bFlag);
682 }
683 
684 // NewOrLoadCompleted is called when the document is loaded, or when it is clear
685 // it won't load any more.
NewOrLoadCompleted(DocCreationMode eMode)686 void SdDrawDocument::NewOrLoadCompleted(DocCreationMode eMode)
687 {
688     if (eMode == DocCreationMode::New)
689     {
690         // New document:
691         // create slideshow and default templates,
692         // create pool for virtual controls
693         CreateLayoutTemplates();
694         CreateDefaultCellStyles();
695 
696         static_cast< SdStyleSheetPool* >( mxStyleSheetPool.get() )->CreatePseudosIfNecessary();
697     }
698     else if (eMode == DocCreationMode::Loaded)
699     {
700             // Document has finished loading
701 
702         CheckMasterPages();
703 
704         if ( GetMasterSdPageCount(PageKind::Standard) > 1 )
705             RemoveUnnecessaryMasterPages( nullptr, true, false );
706 
707         for ( sal_uInt16 i = 0; i < GetPageCount(); i++ )
708         {
709             // Check for correct layout names
710             SdPage* pPage = static_cast<SdPage*>( GetPage( i ) );
711 
712             if(pPage->TRG_HasMasterPage())
713             {
714                 SdPage& rMaster = static_cast<SdPage&>(pPage->TRG_GetMasterPage() );
715 
716                 if(rMaster.GetLayoutName() != pPage->GetLayoutName())
717                 {
718                     pPage->SetLayoutName(rMaster.GetLayoutName());
719                 }
720             }
721         }
722 
723         for ( sal_uInt16 nPage = 0; nPage < GetMasterPageCount(); nPage++)
724         {
725             // LayoutName and PageName must be the same
726             SdPage* pPage = static_cast<SdPage*>( GetMasterPage( nPage ) );
727 
728             OUString aName( pPage->GetLayoutName() );
729             aName = aName.copy( 0, aName.indexOf( SD_LT_SEPARATOR ) );
730 
731             if( aName != pPage->GetName() )
732                 pPage->SetName( aName );
733         }
734 
735         // Create names of the styles in the user's language
736         static_cast<SdStyleSheetPool*>(mxStyleSheetPool.get())->UpdateStdNames();
737 
738         // Create any missing styles - eg. formerly, there was no Subtitle style
739         static_cast<SdStyleSheetPool*>(mxStyleSheetPool.get())->CreatePseudosIfNecessary();
740     }
741 
742     // Set default style of Drawing Engine
743     OUString aName( SdResId(STR_STANDARD_STYLESHEET_NAME));
744     SetDefaultStyleSheet(static_cast<SfxStyleSheet*>(mxStyleSheetPool->Find(aName, SfxStyleFamily::Para)));
745 
746     // #i119287# Set default StyleSheet for SdrGrafObj and SdrOle2Obj
747     SetDefaultStyleSheetForSdrGrafObjAndSdrOle2Obj(static_cast<SfxStyleSheet*>(mxStyleSheetPool->Find(SdResId(STR_POOLSHEET_OBJNOLINENOFILL), SfxStyleFamily::Para)));
748 
749     // Initialize DrawOutliner and DocumentOutliner, but don't initialize the
750     // global outliner, as it is not document specific like StyleSheetPool and
751     // StyleRequestHandler are.
752     ::Outliner& rDrawOutliner = GetDrawOutliner();
753     rDrawOutliner.SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
754     EEControlBits nCntrl = rDrawOutliner.GetControlWord();
755     if (mbOnlineSpell)
756         nCntrl |= EEControlBits::ONLINESPELLING;
757     else
758         nCntrl &= ~EEControlBits::ONLINESPELLING;
759     rDrawOutliner.SetControlWord(nCntrl);
760 
761     // Initialize HitTestOutliner and DocumentOutliner, but don't initialize the
762     // global outliner, as it is not document specific like StyleSheetPool and
763     // StyleRequestHandler are.
764     m_pHitTestOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
765 
766     if(mpOutliner)
767     {
768         mpOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
769     }
770     if(mpInternalOutliner)
771     {
772         mpInternalOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
773     }
774 
775     if ( eMode == DocCreationMode::Loaded )
776     {
777         // Make presentation objects listeners of the appropriate styles
778         SdStyleSheetPool* pSPool = static_cast<SdStyleSheetPool*>( GetStyleSheetPool() );
779         sal_uInt16 nPage, nPageCount;
780 
781         // create missing layout style sheets for broken documents
782         //         that were created with the 5.2
783         nPageCount = GetMasterSdPageCount( PageKind::Standard );
784         for (nPage = 0; nPage < nPageCount; nPage++)
785         {
786             SdPage* pPage = GetMasterSdPage(nPage, PageKind::Standard);
787             pSPool->CreateLayoutStyleSheets( pPage->GetName(), true );
788         }
789 
790         // Default and notes pages:
791         for (nPage = 0; nPage < GetPageCount(); nPage++)
792         {
793             SdPage* pPage = static_cast<SdPage*>(GetPage(nPage));
794             NewOrLoadCompleted( pPage, pSPool );
795         }
796 
797         // Master pages:
798         for (nPage = 0; nPage < GetMasterPageCount(); nPage++)
799         {
800             SdPage* pPage = static_cast<SdPage*>(GetMasterPage(nPage));
801 
802             NewOrLoadCompleted( pPage, pSPool );
803         }
804     }
805 
806     mbNewOrLoadCompleted = true;
807     UpdateAllLinks();
808     SetChanged( false );
809 }
810 
811 /** updates all links, only links in this document should by resolved */
UpdateAllLinks()812 void SdDrawDocument::UpdateAllLinks()
813 {
814     if (s_pDocLockedInsertingLinks || !m_pLinkManager || m_pLinkManager->GetLinks().empty())
815         return;
816 
817     s_pDocLockedInsertingLinks = this; // lock inserting links. only links in this document should by resolved
818 
819     if (mpDocSh)
820     {
821         comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = mpDocSh->getEmbeddedObjectContainer();
822         rEmbeddedObjectContainer.setUserAllowsLinkUpdate(true);
823     }
824 
825     m_pLinkManager->UpdateAllLinks(true, false, nullptr);  // query box: update all links?
826 
827     if (s_pDocLockedInsertingLinks == this)
828         s_pDocLockedInsertingLinks = nullptr;  // unlock inserting links
829 }
830 
831 /** this loops over the presentation objects of a page and repairs some new settings
832     from old binary files and resets all default strings for empty presentation objects.
833 */
NewOrLoadCompleted(SdPage * pPage,SdStyleSheetPool * pSPool)834 void SdDrawDocument::NewOrLoadCompleted( SdPage* pPage, SdStyleSheetPool* pSPool )
835 {
836     sd::ShapeList& rPresentationShapes( pPage->GetPresentationShapeList() );
837     if(rPresentationShapes.isEmpty())
838         return;
839 
840     // Create lists of title and outline styles
841     OUString aName = pPage->GetLayoutName();
842     aName = aName.copy( 0, aName.indexOf( SD_LT_SEPARATOR ) );
843 
844     std::vector<SfxStyleSheetBase*> aOutlineList;
845     pSPool->CreateOutlineSheetList(aName,aOutlineList);
846 
847     SfxStyleSheet* pTitleSheet = static_cast<SfxStyleSheet*>(pSPool->GetTitleSheet(aName));
848 
849     SdrObject* pObj = nullptr;
850     rPresentationShapes.seekShape(0);
851 
852     // Now look for title and outline text objects, then make those objects
853     // listeners.
854     while( (pObj = rPresentationShapes.getNextShape()) )
855     {
856         if (pObj->GetObjInventor() == SdrInventor::Default)
857         {
858             OutlinerParaObject* pOPO = pObj->GetOutlinerParaObject();
859             sal_uInt16 nId = pObj->GetObjIdentifier();
860 
861             if (nId == OBJ_TITLETEXT)
862             {
863                 if( pOPO && pOPO->GetOutlinerMode() == OutlinerMode::DontKnow )
864                     pOPO->SetOutlinerMode( OutlinerMode::TitleObject );
865 
866                 // sal_True: don't delete "hard" attributes when doing this.
867                 if (pTitleSheet)
868                     pObj->SetStyleSheet(pTitleSheet, true);
869             }
870             else if (nId == OBJ_OUTLINETEXT)
871             {
872                 if( pOPO && pOPO->GetOutlinerMode() == OutlinerMode::DontKnow )
873                     pOPO->SetOutlinerMode( OutlinerMode::OutlineObject );
874 
875                 std::vector<SfxStyleSheetBase*>::iterator iter;
876                 for (iter = aOutlineList.begin(); iter != aOutlineList.end(); ++iter)
877                 {
878                     SfxStyleSheet* pSheet = static_cast<SfxStyleSheet*>(*iter);
879 
880                     if (pSheet)
881                     {
882                         pObj->StartListening(*pSheet);
883 
884                         if( iter == aOutlineList.begin())
885                             // text frame listens to stylesheet of layer 1
886                             pObj->NbcSetStyleSheet(pSheet, true);
887                     }
888                 }
889             }
890 
891             if( auto pTextObj = dynamic_cast<SdrTextObj *>( pObj ) )
892                 if (pTextObj->IsEmptyPresObj())
893                 {
894                     PresObjKind ePresObjKind = pPage->GetPresObjKind(pObj);
895                     OUString aString( pPage->GetPresObjText(ePresObjKind) );
896 
897                     if (!aString.isEmpty())
898                     {
899                         SdOutliner* pInternalOutl = GetInternalOutliner();
900                         pPage->SetObjText( pTextObj, pInternalOutl, ePresObjKind, aString );
901                         pObj->NbcSetStyleSheet( pPage->GetStyleSheetForPresObj( ePresObjKind ), true );
902                         pInternalOutl->Clear();
903                     }
904                 }
905         }
906     }
907 }
908 
909 // Local outliner that is used for outline mode. In this outliner, OutlinerViews
910 // may be inserted.
GetOutliner(bool bCreateOutliner)911 SdOutliner* SdDrawDocument::GetOutliner(bool bCreateOutliner)
912 {
913     if (!mpOutliner && bCreateOutliner)
914     {
915         mpOutliner.reset(new SdOutliner( this, OutlinerMode::TextObject ));
916 
917         if (mpDocSh)
918             mpOutliner->SetRefDevice( SD_MOD()->GetVirtualRefDevice() );
919 
920         mpOutliner->SetDefTab( m_nDefaultTabulator );
921         mpOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
922     }
923 
924     return mpOutliner.get();
925 }
926 
927 // Internal outliner that is used to create text objects. We don't insert any
928 // OutlinerViews into this outliner!
GetInternalOutliner(bool bCreateOutliner)929 SdOutliner* SdDrawDocument::GetInternalOutliner(bool bCreateOutliner)
930 {
931     if ( !mpInternalOutliner && bCreateOutliner )
932     {
933         mpInternalOutliner.reset( new SdOutliner( this, OutlinerMode::TextObject ) );
934 
935         // This outliner is only used to create special text objects. As no
936         // information about portions is saved in this outliner, the update mode
937         // can/should always remain sal_False.
938         mpInternalOutliner->SetUpdateMode( false );
939         mpInternalOutliner->EnableUndo( false );
940 
941         if (mpDocSh)
942             mpInternalOutliner->SetRefDevice( SD_MOD()->GetVirtualRefDevice() );
943 
944         mpInternalOutliner->SetDefTab( m_nDefaultTabulator );
945         mpInternalOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
946     }
947 
948     DBG_ASSERT( !mpInternalOutliner || ( ! mpInternalOutliner->GetUpdateMode() ) , "InternalOutliner: UpdateMode = sal_True !" );
949     DBG_ASSERT( !mpInternalOutliner || ( ! mpInternalOutliner->IsUndoEnabled() ), "InternalOutliner: Undo = sal_True !" );
950 
951     // If you add stuff here, always clear it out.
952     // Advantages:
953     // a) no unnecessary Clear calls
954     // b) no wasted memory
955     DBG_ASSERT( !mpInternalOutliner || ( ( mpInternalOutliner->GetParagraphCount() == 1 ) && ( mpInternalOutliner->GetText( mpInternalOutliner->GetParagraph( 0 ) ).isEmpty() ) ), "InternalOutliner: not empty!" );
956 
957     return mpInternalOutliner.get();
958 }
959 
960 // OnlineSpelling on/off
SetOnlineSpell(bool bIn)961 void SdDrawDocument::SetOnlineSpell(bool bIn)
962 {
963     mbOnlineSpell = bIn;
964     EEControlBits nCntrl;
965 
966     if(mpOutliner)
967     {
968         nCntrl = mpOutliner->GetControlWord();
969 
970         if(mbOnlineSpell)
971             nCntrl |= EEControlBits::ONLINESPELLING;
972         else
973             nCntrl &= ~EEControlBits::ONLINESPELLING;
974 
975         mpOutliner->SetControlWord(nCntrl);
976     }
977 
978     if (mpInternalOutliner)
979     {
980         nCntrl = mpInternalOutliner->GetControlWord();
981 
982         if (mbOnlineSpell)
983             nCntrl |= EEControlBits::ONLINESPELLING;
984         else
985             nCntrl &= ~EEControlBits::ONLINESPELLING;
986 
987         mpInternalOutliner->SetControlWord(nCntrl);
988     }
989 
990     ::Outliner& rOutliner = GetDrawOutliner();
991 
992     nCntrl = rOutliner.GetControlWord();
993 
994     if (mbOnlineSpell)
995         nCntrl |= EEControlBits::ONLINESPELLING;
996     else
997         nCntrl &= ~EEControlBits::ONLINESPELLING;
998 
999     rOutliner.SetControlWord(nCntrl);
1000 
1001     if (mbOnlineSpell)
1002     {
1003         StartOnlineSpelling();
1004     }
1005     else
1006     {
1007         StopOnlineSpelling();
1008     }
1009 }
1010 
1011 // OnlineSpelling: highlighting on/off
createUnoModel()1012 uno::Reference< uno::XInterface > SdDrawDocument::createUnoModel()
1013 {
1014     uno::Reference< uno::XInterface > xModel;
1015 
1016     try
1017     {
1018         if ( mpDocSh )
1019             xModel = mpDocSh->GetModel();
1020     }
1021     catch( uno::RuntimeException& )
1022     {
1023     }
1024 
1025     return xModel;
1026 }
1027 
GetPageNumType() const1028 SvxNumType SdDrawDocument::GetPageNumType() const
1029 {
1030     return mePageNumType;
1031 }
1032 
SetPrinterIndependentLayout(sal_Int32 nMode)1033 void SdDrawDocument::SetPrinterIndependentLayout (sal_Int32 nMode)
1034 {
1035     switch (nMode)
1036     {
1037         case css::document::PrinterIndependentLayout::DISABLED:
1038         case css::document::PrinterIndependentLayout::ENABLED:
1039             // Just store supported modes and inform the doc shell
1040             mnPrinterIndependentLayout = nMode;
1041 
1042             // Since it is possible that a SdDrawDocument is constructed without a
1043             // SdDrawDocShell the pointer member mpDocSh needs to be tested
1044             // before the call is executed. This is e. g. used for copy/paste.
1045             if(mpDocSh)
1046             {
1047                 mpDocSh->UpdateRefDevice ();
1048             }
1049 
1050             break;
1051 
1052         default:
1053             // Ignore unknown values
1054             break;
1055     }
1056 }
1057 
SetStartWithPresentation(bool bStartWithPresentation)1058 void SdDrawDocument::SetStartWithPresentation( bool bStartWithPresentation )
1059 {
1060     mbStartWithPresentation = bStartWithPresentation;
1061 }
1062 
SetExitAfterPresenting(bool bExitAfterPresenting)1063 void SdDrawDocument::SetExitAfterPresenting( bool bExitAfterPresenting )
1064 {
1065     mbExitAfterPresenting = bExitAfterPresenting;
1066 }
1067 
PageListChanged()1068 void SdDrawDocument::PageListChanged()
1069 {
1070     mpDrawPageListWatcher->Invalidate();
1071 }
1072 
MasterPageListChanged()1073 void SdDrawDocument::MasterPageListChanged()
1074 {
1075     mpMasterPageListWatcher->Invalidate();
1076 }
1077 
SetCalcFieldValueHdl(::Outliner * pOutliner)1078 void SdDrawDocument::SetCalcFieldValueHdl(::Outliner* pOutliner)
1079 {
1080     pOutliner->SetCalcFieldValueHdl(LINK(SD_MOD(), SdModule, CalcFieldValueHdl));
1081 }
1082 
GetAnnotationAuthorIndex(const OUString & rAuthor)1083 sal_uInt16 SdDrawDocument::GetAnnotationAuthorIndex( const OUString& rAuthor )
1084 {
1085     // force current user to have first color
1086     if( maAnnotationAuthors.empty() )
1087     {
1088         SvtUserOptions aUserOptions;
1089         maAnnotationAuthors.push_back( aUserOptions.GetFullName() );
1090     }
1091 
1092     auto iter = std::find(maAnnotationAuthors.begin(), maAnnotationAuthors.end(), rAuthor);
1093     sal_uInt16 idx = static_cast<sal_uInt16>(std::distance(maAnnotationAuthors.begin(), iter));
1094 
1095     if( idx == maAnnotationAuthors.size() )
1096     {
1097         maAnnotationAuthors.push_back( rAuthor );
1098     }
1099 
1100     return idx;
1101 }
1102 
InitLayoutVector()1103 void SdDrawDocument::InitLayoutVector()
1104 {
1105     if (utl::ConfigManager::IsFuzzing())
1106         return;
1107 
1108     const Reference<css::uno::XComponentContext> xContext(
1109         ::comphelper::getProcessComponentContext() );
1110 
1111     // get file list from configuration
1112     const Sequence< OUString > aFiles(
1113         officecfg::Office::Impress::Misc::LayoutListFiles::get(xContext) );
1114 
1115     OUString sFilename;
1116     for( const auto& rFile : aFiles )
1117     {
1118         sFilename = comphelper::getExpandedUri(xContext, rFile);
1119 
1120         // load layout file into DOM
1121         Reference< XMultiServiceFactory > xServiceFactory(
1122             xContext->getServiceManager() , UNO_QUERY_THROW );
1123         const Reference<XDocumentBuilder> xDocBuilder(
1124             DocumentBuilder::create( comphelper::getComponentContext (xServiceFactory) ));
1125 
1126         try
1127         {
1128             // loop over every layout entry in current file
1129             const Reference<XDocument> xDoc = xDocBuilder->parseURI( sFilename );
1130             const Reference<XNodeList> layoutlist = xDoc->getElementsByTagName("layout");
1131             const int nElements = layoutlist->getLength();
1132             for(int index=0; index < nElements; index++)
1133                 maLayoutInfo.push_back( layoutlist->item(index) );
1134         }
1135         catch (const uno::Exception &)
1136         {
1137             // skip missing config. files
1138         }
1139     }
1140 }
1141 
InitObjectVector()1142 void SdDrawDocument::InitObjectVector()
1143 {
1144     if (utl::ConfigManager::IsFuzzing())
1145         return;
1146 
1147     const Reference<css::uno::XComponentContext> xContext(
1148         ::comphelper::getProcessComponentContext() );
1149 
1150     // get file list from configuration
1151     const Sequence< OUString > aFiles(
1152        officecfg::Office::Impress::Misc::PresObjListFiles::get(xContext) );
1153 
1154     OUString sFilename;
1155     for( const auto& rFile : aFiles )
1156     {
1157         sFilename = comphelper::getExpandedUri(xContext, rFile);
1158 
1159         // load presentation object file into DOM
1160         Reference< XMultiServiceFactory > xServiceFactory(
1161             xContext->getServiceManager() , UNO_QUERY_THROW );
1162         const Reference<XDocumentBuilder> xDocBuilder(
1163             DocumentBuilder::create( comphelper::getComponentContext (xServiceFactory) ));
1164 
1165         try
1166         {
1167             // loop over every object entry in current file
1168             const Reference<XDocument> xDoc = xDocBuilder->parseURI( sFilename );
1169             const Reference<XNodeList> objectlist = xDoc->getElementsByTagName("object");
1170             const int nElements = objectlist->getLength();
1171             for(int index=0; index < nElements; index++)
1172                 maPresObjectInfo.push_back( objectlist->item(index) );
1173         }
1174         catch (const uno::Exception &)
1175         {
1176             // skip missing config. files
1177         }
1178     }
1179 }
1180 
dumpAsXml(xmlTextWriterPtr pWriter) const1181 void SdDrawDocument::dumpAsXml(xmlTextWriterPtr pWriter) const
1182 {
1183     bool bOwns = false;
1184     if (!pWriter)
1185     {
1186         pWriter = xmlNewTextWriterFilename("model.xml", 0);
1187         xmlTextWriterSetIndent(pWriter,1);
1188         (void)xmlTextWriterSetIndentString(pWriter, BAD_CAST("  "));
1189         (void)xmlTextWriterStartDocument(pWriter, nullptr, nullptr, nullptr);
1190         bOwns = true;
1191     }
1192     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SdDrawDocument"));
1193     (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
1194 
1195     if (mpOutliner)
1196         mpOutliner->dumpAsXml(pWriter);
1197     FmFormModel::dumpAsXml(pWriter);
1198     if (GetUndoManager())
1199         GetUndoManager()->dumpAsXml(pWriter);
1200 
1201     (void)xmlTextWriterEndElement(pWriter);
1202     if (bOwns)
1203     {
1204         (void)xmlTextWriterEndDocument(pWriter);
1205         xmlFreeTextWriter(pWriter);
1206     }
1207 }
1208 
1209 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1210