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