Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sd / source / core / drawdoc.cxx
blob3adb91275784c4f6e281ee37cac0f6b9ffbaccc4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <libxml/xmlwriter.h>
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>
31 #include <svl/srchitem.hxx>
32 #include <editeng/eeitem.hxx>
33 #include <editeng/scriptspaceitem.hxx>
34 #include <tools/debug.hxx>
36 #include <unotools/configmgr.hxx>
37 #include <unotools/useroptions.hxx>
38 #include <officecfg/Office/Impress.hxx>
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>
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>
84 namespace com::sun::star::linguistic2 { class XHyphenator; }
85 namespace com::sun::star::linguistic2 { class XSpellChecker1; }
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;
93 using namespace com::sun::star::xml::dom;
94 using ::com::sun::star::uno::Reference;
97 SdDrawDocument* SdDrawDocument::s_pDocLockedInsertingLinks = nullptr;
99 PresentationSettings::PresentationSettings()
100 : mbAll( true ),
101 mbEndless( false ),
102 mbCustomShow(false),
103 mbManual( false ),
104 mbMouseVisible( false ),
105 mbMouseAsPen( false ),
106 mbLockedPages( false ),
107 mbAlwaysOnTop( false ),
108 mbUseNavigation( false ),
109 mbFullScreen( true ),
110 mbAnimationAllowed( true ),
111 mnPauseTimeout( 0 ),
112 mbShowPauseLogo( false ),
113 mbStartCustomShow( false )
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 , mnImagePreferredDPI(0)
142 m_bThemedControls = false;
144 mpDrawPageListWatcher.reset(new ImpDrawPageListWatcher(*this));
145 mpMasterPageListWatcher.reset(new ImpMasterPageListWatcher(*this));
147 InitLayoutVector();
148 InitObjectVector();
149 SetObjectShell(pDrDocSh); // for VCDrawModel
151 if (mpDocSh)
153 SetSwapGraphics();
156 // Set measuring unit (of the application) and scale (of SdMod)
157 sal_Int32 nX, nY;
158 SdOptions* pOptions = SD_MOD()->GetSdOptions(meDocType);
159 pOptions->GetScale( nX, nY );
161 // Allow UI scale only for draw documents.
162 if( eType == DocumentType::Draw )
163 SetUIUnit( static_cast<FieldUnit>(pOptions->GetMetric()), Fraction( nX, nY ) ); // user-defined
164 else
165 SetUIUnit( static_cast<FieldUnit>(pOptions->GetMetric()), Fraction( 1, 1 ) ); // default
167 SetScaleUnit(MapUnit::Map100thMM);
168 SetDefaultFontHeight(o3tl::convert(24, o3tl::Length::pt, o3tl::Length::mm100));
170 m_pItemPool->SetDefaultMetric(MapUnit::Map100thMM);
171 m_pItemPool->FreezeIdRanges();
172 SetTextDefaults();
174 // DrawingEngine has to know where it is...
175 FmFormModel::SetStyleSheetPool( new SdStyleSheetPool( GetPool(), this ) );
177 // Set StyleSheetPool for DrawOutliner, so text objects can be read correctly.
178 // The link to the StyleRequest handler of the document is set later, in
179 // NewOrLoadCompleted, because only then do all the templates exist.
180 SdrOutliner& rOutliner = GetDrawOutliner();
181 rOutliner.SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
182 SetCalcFieldValueHdl( &rOutliner );
184 // set linguistic options
185 if (!utl::ConfigManager::IsFuzzing())
187 const SvtLinguConfig aLinguConfig;
188 SvtLinguOptions aOptions;
189 aLinguConfig.GetOptions( aOptions );
191 SetLanguage( MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage,
192 css::i18n::ScriptType::LATIN), EE_CHAR_LANGUAGE );
193 SetLanguage( MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage_CJK,
194 css::i18n::ScriptType::ASIAN), EE_CHAR_LANGUAGE_CJK );
195 SetLanguage( MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage_CTL,
196 css::i18n::ScriptType::COMPLEX), EE_CHAR_LANGUAGE_CTL );
198 mbOnlineSpell = aOptions.bIsSpellAuto;
201 LanguageType eRealLanguage = MsLangId::getRealLanguage( meLanguage );
202 moCharClass.emplace(LanguageTag( eRealLanguage));
204 // If the current application language is a language that uses right-to-left text...
205 LanguageType eRealCTLLanguage = Application::GetSettings().GetLanguageTag().getLanguageType();
207 // for korean and japanese languages we have a different default for apply spacing between asian, latin and ctl text
208 if (MsLangId::isKorean(eRealCTLLanguage) || (LANGUAGE_JAPANESE == eRealCTLLanguage))
210 GetPool().GetSecondaryPool()->SetPoolDefaultItem( SvxScriptSpaceItem( false, EE_PARA_ASIANCJKSPACING ) );
213 // Set DefTab and SpellOptions for the SD module
214 sal_uInt16 nDefTab = pOptions->GetDefTab();
215 SetDefaultTabulator( nDefTab );
219 Reference< XSpellChecker1 > xSpellChecker( LinguMgr::GetSpellChecker() );
220 if ( xSpellChecker.is() )
221 rOutliner.SetSpeller( xSpellChecker );
223 Reference< XHyphenator > xHyphenator( LinguMgr::GetHyphenator() );
224 if( xHyphenator.is() )
225 rOutliner.SetHyphenator( xHyphenator );
227 SetForbiddenCharsTable(SvxForbiddenCharactersTable::makeForbiddenCharactersTable(::comphelper::getProcessComponentContext()));
229 catch(...)
231 OSL_FAIL("Can't get SpellChecker");
234 rOutliner.SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
236 if (mpDocSh)
238 SetLinkManager( new sfx2::LinkManager(mpDocSh) );
241 EEControlBits nCntrl = rOutliner.GetControlWord();
242 nCntrl |= EEControlBits::ALLOWBIGOBJS;
244 if (mbOnlineSpell)
245 nCntrl |= EEControlBits::ONLINESPELLING;
246 else
247 nCntrl &= ~EEControlBits::ONLINESPELLING;
249 nCntrl &= ~ EEControlBits::ULSPACESUMMATION;
250 if ( meDocType != DocumentType::Impress )
251 SetSummationOfParagraphs( false );
252 else
254 SetSummationOfParagraphs( pOptions->IsSummationOfParagraphs() );
255 if ( pOptions->IsSummationOfParagraphs() )
256 nCntrl |= EEControlBits::ULSPACESUMMATION;
258 rOutliner.SetControlWord(nCntrl);
260 // Initialize the printer independent layout mode
261 SetPrinterIndependentLayout (pOptions->GetPrinterIndependentLayout());
263 // Set the StyleSheetPool for HitTestOutliner.
264 // The link to the StyleRequest handler of the document is set later, in
265 // NewOrLoadCompleted, because only then do all the templates exist.
266 m_pHitTestOutliner->SetStyleSheetPool( static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()) );
268 SetCalcFieldValueHdl( m_pHitTestOutliner.get() );
272 Reference< XSpellChecker1 > xSpellChecker( LinguMgr::GetSpellChecker() );
273 if ( xSpellChecker.is() )
274 m_pHitTestOutliner->SetSpeller( xSpellChecker );
276 Reference< XHyphenator > xHyphenator( LinguMgr::GetHyphenator() );
277 if( xHyphenator.is() )
278 m_pHitTestOutliner->SetHyphenator( xHyphenator );
280 catch(...)
282 OSL_FAIL("Can't get SpellChecker");
285 m_pHitTestOutliner->SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
287 EEControlBits nCntrl2 = m_pHitTestOutliner->GetControlWord();
288 nCntrl2 |= EEControlBits::ALLOWBIGOBJS;
289 nCntrl2 &= ~EEControlBits::ONLINESPELLING;
291 nCntrl2 &= ~ EEControlBits::ULSPACESUMMATION;
292 if ( pOptions->IsSummationOfParagraphs() )
293 nCntrl2 |= EEControlBits::ULSPACESUMMATION;
295 m_pHitTestOutliner->SetControlWord( nCntrl2 );
297 /** Create layers
299 * We create the following default layers on all pages and master pages:
301 * sUNO_LayerName_layout; "layout": default layer for drawing objects of normal pages
302 * localized by SdResId(STR_LAYER_LAYOUT)
304 * sUNO_LayerName_background; "background": background of the master page
305 * localized by SdResId(STR_LAYER_BCKGRND)
306 * (currently unused within normal pages and not visible to users)
308 * sUNO_LayerName_background_objects; "backgroundobjects": objects on the background of master pages
309 * localized by SdResId(STR_LAYER_BCKGRNDOBJ)
310 * (currently unused within normal pages)
312 * sUNO_LayerName_controls; "controls": default layer for controls
313 * localized by SdResId(STR_LAYER_CONTROLS)
314 * (currently special handling in regard to z-order)
316 * sUNO_LayerName_measurelines; "measurelines" : default layer for measure lines
317 * localized by SdResId(STR_LAYER_MEASURELINES)
321 SdrLayerAdmin& rLayerAdmin = GetLayerAdmin();
322 rLayerAdmin.NewLayer( sUNO_LayerName_layout );
323 rLayerAdmin.NewLayer( sUNO_LayerName_background );
324 rLayerAdmin.NewLayer( sUNO_LayerName_background_objects );
325 rLayerAdmin.NewLayer( sUNO_LayerName_controls);
326 rLayerAdmin.NewLayer( sUNO_LayerName_measurelines );
328 rLayerAdmin.SetControlLayerName(sUNO_LayerName_controls);
333 // Destructor
334 SdDrawDocument::~SdDrawDocument()
336 Broadcast(SdrHint(SdrHintKind::ModelCleared));
338 if (mpWorkStartupTimer)
340 if ( mpWorkStartupTimer->IsActive() )
341 mpWorkStartupTimer->Stop();
343 mpWorkStartupTimer.reset();
346 StopOnlineSpelling();
347 mpOnlineSearchItem.reset();
349 CloseBookmarkDoc();
350 SetAllocDocSh(false);
352 ClearModel(true);
354 if (m_pLinkManager)
356 // Release BaseLinks
357 if ( !m_pLinkManager->GetLinks().empty() )
359 m_pLinkManager->Remove( 0, m_pLinkManager->GetLinks().size() );
362 delete m_pLinkManager;
363 m_pLinkManager = nullptr;
366 maFrameViewList.clear();
367 mpCustomShowList.reset();
368 mpOutliner.reset();
369 mpInternalOutliner.reset();
370 moCharClass.reset();
373 void SdDrawDocument::adaptSizeAndBorderForAllPages(
374 const Size& rNewSize,
375 ::tools::Long nLeft,
376 ::tools::Long nRight,
377 ::tools::Long nUpper,
378 ::tools::Long nLower)
380 const sal_uInt16 nMasterPageCnt(GetMasterSdPageCount(PageKind::Standard));
381 const sal_uInt16 nPageCnt(GetSdPageCount(PageKind::Standard));
383 if(0 == nMasterPageCnt && 0 == nPageCnt)
385 return;
388 SdPage* pPage(0 != nPageCnt ? GetSdPage(0, PageKind::Standard) : GetMasterSdPage(0, PageKind::Standard));
390 // call fully implemented local version, including getting
391 // some more information from one of the Pages (1st one)
392 AdaptPageSizeForAllPages(
393 rNewSize,
394 PageKind::Standard,
395 nullptr,
396 nLeft,
397 nRight,
398 nUpper,
399 nLower,
400 true,
401 pPage->GetOrientation(),
402 pPage->GetPaperBin(),
403 pPage->IsBackgroundFullSize());
405 // adjust handout page to new format of the standard page
406 if(0 != nPageCnt)
408 GetSdPage(0, PageKind::Handout)->CreateTitleAndLayout(true);
412 void SdDrawDocument::AdaptPageSizeForAllPages(
413 const Size& rNewSize,
414 PageKind ePageKind,
415 SdUndoGroup* pUndoGroup,
416 ::tools::Long nLeft,
417 ::tools::Long nRight,
418 ::tools::Long nUpper,
419 ::tools::Long nLower,
420 bool bScaleAll,
421 Orientation eOrientation,
422 sal_uInt16 nPaperBin,
423 bool bBackgroundFullSize)
425 sal_uInt16 i;
426 const sal_uInt16 nMasterPageCnt(GetMasterSdPageCount(ePageKind));
427 const sal_uInt16 nPageCnt(GetSdPageCount(ePageKind));
429 if(0 == nMasterPageCnt && 0 == nPageCnt)
431 return;
434 for (i = 0; i < nMasterPageCnt; i++)
436 // first, handle all master pages
437 SdPage* pPage(GetMasterSdPage(i, ePageKind));
439 if(pUndoGroup)
441 SdUndoAction* pUndo(
442 new SdPageFormatUndoAction(
443 this,
444 pPage,
445 pPage->GetSize(),
446 pPage->GetLeftBorder(), pPage->GetRightBorder(),
447 pPage->GetUpperBorder(), pPage->GetLowerBorder(),
448 pPage->GetOrientation(),
449 pPage->GetPaperBin(),
450 pPage->IsBackgroundFullSize(),
451 rNewSize,
452 nLeft, nRight,
453 nUpper, nLower,
454 bScaleAll,
455 eOrientation,
456 nPaperBin,
457 bBackgroundFullSize));
458 pUndoGroup->AddAction(pUndo);
461 if (rNewSize.Width() > 0 || nLeft >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0)
463 ::tools::Rectangle aNewBorderRect(nLeft, nUpper, nRight, nLower);
464 pPage->ScaleObjects(rNewSize, aNewBorderRect, bScaleAll);
466 if (rNewSize.Width() > 0)
468 pPage->SetSize(rNewSize);
472 if( nLeft >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0 )
474 pPage->SetBorder(nLeft, nUpper, nRight, nLower);
477 pPage->SetOrientation(eOrientation);
478 pPage->SetPaperBin( nPaperBin );
479 pPage->SetBackgroundFullSize( bBackgroundFullSize );
481 if ( ePageKind == PageKind::Standard )
483 GetMasterSdPage(i, PageKind::Notes)->CreateTitleAndLayout();
486 pPage->CreateTitleAndLayout();
489 for (i = 0; i < nPageCnt; i++)
491 // then, handle all pages
492 SdPage* pPage(GetSdPage(i, ePageKind));
494 if(pUndoGroup)
496 SdUndoAction* pUndo(
497 new SdPageFormatUndoAction(
498 this,
499 pPage,
500 pPage->GetSize(),
501 pPage->GetLeftBorder(), pPage->GetRightBorder(),
502 pPage->GetUpperBorder(), pPage->GetLowerBorder(),
503 pPage->GetOrientation(),
504 pPage->GetPaperBin(),
505 pPage->IsBackgroundFullSize(),
506 rNewSize,
507 nLeft, nRight,
508 nUpper, nLower,
509 bScaleAll,
510 eOrientation,
511 nPaperBin,
512 bBackgroundFullSize));
513 pUndoGroup->AddAction(pUndo);
516 if (rNewSize.Width() > 0 || nLeft >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0)
518 ::tools::Rectangle aNewBorderRect(nLeft, nUpper, nRight, nLower);
519 pPage->ScaleObjects(rNewSize, aNewBorderRect, bScaleAll);
521 if (rNewSize.Width() > 0)
523 pPage->SetSize(rNewSize);
527 if( nLeft >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0 )
529 pPage->SetBorder(nLeft, nUpper, nRight, nLower);
532 pPage->SetOrientation(eOrientation);
533 pPage->SetPaperBin( nPaperBin );
534 pPage->SetBackgroundFullSize( bBackgroundFullSize );
536 if ( ePageKind == PageKind::Standard )
538 SdPage* pNotesPage = GetSdPage(i, PageKind::Notes);
539 pNotesPage->SetAutoLayout( pNotesPage->GetAutoLayout() );
542 pPage->SetAutoLayout( pPage->GetAutoLayout() );
546 SdrModel* SdDrawDocument::AllocModel() const
548 return AllocSdDrawDocument();
551 namespace
554 /// Copies all user-defined properties from pSource to pDestination.
555 void lcl_copyUserDefinedProperties(const SfxObjectShell* pSource, const SfxObjectShell* pDestination)
557 if (!pSource || !pDestination)
558 return;
560 uno::Reference<document::XDocumentProperties> xSource = pSource->getDocProperties();
561 uno::Reference<document::XDocumentProperties> xDestination = pDestination->getDocProperties();
562 uno::Reference<beans::XPropertyContainer> xSourcePropertyContainer = xSource->getUserDefinedProperties();
563 uno::Reference<beans::XPropertyContainer> xDestinationPropertyContainer = xDestination->getUserDefinedProperties();
564 uno::Reference<beans::XPropertySet> xSourcePropertySet(xSourcePropertyContainer, uno::UNO_QUERY);
565 const uno::Sequence<beans::Property> aProperties = xSourcePropertySet->getPropertySetInfo()->getProperties();
567 for (const beans::Property& rProperty : aProperties)
569 const OUString& rKey = rProperty.Name;
570 uno::Any aValue = xSourcePropertySet->getPropertyValue(rKey);
571 // We know that pDestination was just created, so has no properties: addProperty() will never throw.
572 xDestinationPropertyContainer->addProperty(rKey, beans::PropertyAttribute::REMOVABLE, aValue);
578 // This method creates a new document (SdDrawDocument) and returns a pointer to
579 // said document. The drawing engine uses this method to put the document (or
580 // parts of it) into the clipboard/DragServer.
581 SdDrawDocument* SdDrawDocument::AllocSdDrawDocument() const
583 SdDrawDocument* pNewModel = nullptr;
585 if( mpCreatingTransferable )
587 // Document is created for drag & drop/clipboard. To be able to
588 // do this, the document has to know a DocShell (SvPersist).
589 SfxObjectShell* pObj = nullptr;
590 ::sd::DrawDocShell* pNewDocSh = nullptr;
592 if( meDocType == DocumentType::Impress )
593 mpCreatingTransferable->SetDocShell( new ::sd::DrawDocShell(
594 SfxObjectCreateMode::EMBEDDED, true, meDocType ) );
595 else
596 mpCreatingTransferable->SetDocShell( new ::sd::GraphicDocShell(
597 SfxObjectCreateMode::EMBEDDED ) );
599 pObj = mpCreatingTransferable->GetDocShell().get();
600 pNewDocSh = static_cast< ::sd::DrawDocShell*>( pObj );
601 pNewDocSh->DoInitNew();
602 pNewModel = pNewDocSh->GetDoc();
604 // Only necessary for clipboard -
605 // for drag & drop this is handled by DragServer
606 SdStyleSheetPool* pOldStylePool = static_cast<SdStyleSheetPool*>( GetStyleSheetPool() );
607 SdStyleSheetPool* pNewStylePool = static_cast<SdStyleSheetPool*>( pNewModel->GetStyleSheetPool() );
609 pNewStylePool->CopyGraphicSheets(*pOldStylePool);
610 pNewStylePool->CopyCellSheets(*pOldStylePool);
611 pNewStylePool->CopyTableStyles(*pOldStylePool);
613 for (sal_uInt16 i = 0; i < GetMasterSdPageCount(PageKind::Standard); i++)
615 // Move with all of the master page's layouts
616 OUString aOldLayoutName(const_cast<SdDrawDocument*>(this)->GetMasterSdPage(i, PageKind::Standard)->GetLayoutName());
617 aOldLayoutName = aOldLayoutName.copy( 0, aOldLayoutName.indexOf( SD_LT_SEPARATOR ) );
618 StyleSheetCopyResultVector aCreatedSheets;
619 pNewStylePool->CopyLayoutSheets(aOldLayoutName, *pOldStylePool, aCreatedSheets );
622 lcl_copyUserDefinedProperties(GetDocSh(), pNewDocSh);
624 pNewModel->NewOrLoadCompleted( DocCreationMode::Loaded ); // loaded from source document
626 else if( mbAllocDocSh )
628 // Create a DocShell which is then returned with GetAllocedDocSh()
629 SdDrawDocument* pDoc = const_cast<SdDrawDocument*>(this);
630 pDoc->SetAllocDocSh(false);
631 pDoc->mxAllocedDocShRef = new ::sd::DrawDocShell(
632 SfxObjectCreateMode::EMBEDDED, true, meDocType);
633 pDoc->mxAllocedDocShRef->DoInitNew();
634 pNewModel = pDoc->mxAllocedDocShRef->GetDoc();
636 else
638 pNewModel = new SdDrawDocument(meDocType, nullptr);
641 return pNewModel;
644 rtl::Reference<SdPage> SdDrawDocument::AllocSdPage(bool bMasterPage)
646 return new SdPage(*this, bMasterPage);
649 // This method creates a new page (SdPage) and returns a pointer to said page.
650 // The drawing engine uses this method to create pages (whose types it does
651 // not know, as they are _derivatives_ of SdrPage) when loading.
652 rtl::Reference<SdrPage> SdDrawDocument::AllocPage(bool bMasterPage)
654 return AllocSdPage(bMasterPage);
657 // When the model has changed
658 void SdDrawDocument::SetChanged(bool bFlag)
660 if (mpDocSh)
662 if (mbNewOrLoadCompleted && mpDocSh->IsEnableSetModified())
664 // Pass on to base class
665 FmFormModel::SetChanged(bFlag);
667 // Forward to ObjectShell
668 mpDocSh->SetModified(bFlag);
671 else
673 // Pass on to base class
674 FmFormModel::SetChanged(bFlag);
678 // The model changed, don't call anything else
679 void SdDrawDocument::NbcSetChanged(bool bFlag)
681 // forward to baseclass
682 FmFormModel::SetChanged(bFlag);
685 // NewOrLoadCompleted is called when the document is loaded, or when it is clear
686 // it won't load any more.
687 void SdDrawDocument::NewOrLoadCompleted(DocCreationMode eMode)
689 if (eMode == DocCreationMode::New)
691 // New document:
692 // create slideshow and default templates,
693 // create pool for virtual controls
694 CreateLayoutTemplates();
695 CreateDefaultCellStyles();
697 static_cast< SdStyleSheetPool* >( mxStyleSheetPool.get() )->CreatePseudosIfNecessary();
699 else if (eMode == DocCreationMode::Loaded)
701 // Document has finished loading
703 CheckMasterPages();
705 if ( GetMasterSdPageCount(PageKind::Standard) > 1 )
706 RemoveUnnecessaryMasterPages( nullptr, true, false );
708 for ( sal_uInt16 i = 0; i < GetPageCount(); i++ )
710 // Check for correct layout names
711 SdPage* pPage = static_cast<SdPage*>( GetPage( i ) );
713 if(pPage->TRG_HasMasterPage())
715 SdPage& rMaster = static_cast<SdPage&>(pPage->TRG_GetMasterPage() );
717 if(rMaster.GetLayoutName() != pPage->GetLayoutName())
719 pPage->SetLayoutName(rMaster.GetLayoutName());
724 for ( sal_uInt16 nPage = 0; nPage < GetMasterPageCount(); nPage++)
726 // LayoutName and PageName must be the same
727 SdPage* pPage = static_cast<SdPage*>( GetMasterPage( nPage ) );
729 OUString aName( pPage->GetLayoutName() );
730 aName = aName.copy( 0, aName.indexOf( SD_LT_SEPARATOR ) );
732 if( aName != pPage->GetName() )
733 pPage->SetName( aName );
736 // Create names of the styles in the user's language
737 static_cast<SdStyleSheetPool*>(mxStyleSheetPool.get())->UpdateStdNames();
739 // Create any missing styles - eg. formerly, there was no Subtitle style
740 static_cast<SdStyleSheetPool*>(mxStyleSheetPool.get())->CreatePseudosIfNecessary();
743 // Set default style of Drawing Engine
744 OUString aName( SdResId(STR_STANDARD_STYLESHEET_NAME));
745 SetDefaultStyleSheet(static_cast<SfxStyleSheet*>(mxStyleSheetPool->Find(aName, SfxStyleFamily::Para)));
747 // #i119287# Set default StyleSheet for SdrGrafObj and SdrOle2Obj
748 SetDefaultStyleSheetForSdrGrafObjAndSdrOle2Obj(static_cast<SfxStyleSheet*>(mxStyleSheetPool->Find(SdResId(STR_POOLSHEET_OBJNOLINENOFILL), SfxStyleFamily::Para)));
750 // Initialize DrawOutliner and DocumentOutliner, but don't initialize the
751 // global outliner, as it is not document specific like StyleSheetPool and
752 // StyleRequestHandler are.
753 ::Outliner& rDrawOutliner = GetDrawOutliner();
754 rDrawOutliner.SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
755 EEControlBits nCntrl = rDrawOutliner.GetControlWord();
756 if (mbOnlineSpell)
757 nCntrl |= EEControlBits::ONLINESPELLING;
758 else
759 nCntrl &= ~EEControlBits::ONLINESPELLING;
760 rDrawOutliner.SetControlWord(nCntrl);
762 // Initialize HitTestOutliner and DocumentOutliner, but don't initialize the
763 // global outliner, as it is not document specific like StyleSheetPool and
764 // StyleRequestHandler are.
765 m_pHitTestOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
767 if(mpOutliner)
769 mpOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
771 if(mpInternalOutliner)
773 mpInternalOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
776 if ( eMode == DocCreationMode::Loaded )
778 // Make presentation objects listeners of the appropriate styles
779 SdStyleSheetPool* pSPool = static_cast<SdStyleSheetPool*>( GetStyleSheetPool() );
780 sal_uInt16 nPage, nPageCount;
782 // create missing layout style sheets for broken documents
783 // that were created with the 5.2
784 nPageCount = GetMasterSdPageCount( PageKind::Standard );
785 for (nPage = 0; nPage < nPageCount; nPage++)
787 SdPage* pPage = GetMasterSdPage(nPage, PageKind::Standard);
788 pSPool->CreateLayoutStyleSheets( pPage->GetName(), true );
791 // Default and notes pages:
792 for (nPage = 0; nPage < GetPageCount(); nPage++)
794 SdPage* pPage = static_cast<SdPage*>(GetPage(nPage));
795 NewOrLoadCompleted( pPage, pSPool );
798 // Master pages:
799 for (nPage = 0; nPage < GetMasterPageCount(); nPage++)
801 SdPage* pPage = static_cast<SdPage*>(GetMasterPage(nPage));
803 NewOrLoadCompleted( pPage, pSPool );
807 mbNewOrLoadCompleted = true;
808 UpdateAllLinks();
809 SetChanged( false );
812 /** updates all links, only links in this document should by resolved */
813 void SdDrawDocument::UpdateAllLinks()
815 if (s_pDocLockedInsertingLinks || !m_pLinkManager || m_pLinkManager->GetLinks().empty())
816 return;
818 s_pDocLockedInsertingLinks = this; // lock inserting links. only links in this document should by resolved
820 if (mpDocSh)
822 comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = mpDocSh->getEmbeddedObjectContainer();
823 rEmbeddedObjectContainer.setUserAllowsLinkUpdate(true);
826 m_pLinkManager->UpdateAllLinks(true, false, nullptr); // query box: update all links?
828 if (s_pDocLockedInsertingLinks == this)
829 s_pDocLockedInsertingLinks = nullptr; // unlock inserting links
832 /** this loops over the presentation objects of a page and repairs some new settings
833 from old binary files and resets all default strings for empty presentation objects.
835 void SdDrawDocument::NewOrLoadCompleted( SdPage* pPage, SdStyleSheetPool* pSPool )
837 sd::ShapeList& rPresentationShapes( pPage->GetPresentationShapeList() );
838 if(rPresentationShapes.isEmpty())
839 return;
841 // Create lists of title and outline styles
842 OUString aName = pPage->GetLayoutName();
843 aName = aName.copy( 0, aName.indexOf( SD_LT_SEPARATOR ) );
845 std::vector<SfxStyleSheetBase*> aOutlineList;
846 pSPool->CreateOutlineSheetList(aName,aOutlineList);
848 SfxStyleSheet* pTitleSheet = static_cast<SfxStyleSheet*>(pSPool->GetTitleSheet(aName));
850 SdrObject* pObj = nullptr;
851 rPresentationShapes.seekShape(0);
853 // Now look for title and outline text objects, then make those objects
854 // listeners.
855 while( (pObj = rPresentationShapes.getNextShape()) )
857 if (pObj->GetObjInventor() == SdrInventor::Default)
859 OutlinerParaObject* pOPO = pObj->GetOutlinerParaObject();
860 SdrObjKind nId = pObj->GetObjIdentifier();
862 if (nId == SdrObjKind::TitleText)
864 if( pOPO && pOPO->GetOutlinerMode() == OutlinerMode::DontKnow )
865 pOPO->SetOutlinerMode( OutlinerMode::TitleObject );
867 // sal_True: don't delete "hard" attributes when doing this.
868 if (pTitleSheet)
869 pObj->SetStyleSheet(pTitleSheet, true);
871 else if (nId == SdrObjKind::OutlineText)
873 if( pOPO && pOPO->GetOutlinerMode() == OutlinerMode::DontKnow )
874 pOPO->SetOutlinerMode( OutlinerMode::OutlineObject );
876 std::vector<SfxStyleSheetBase*>::iterator iter;
877 for (iter = aOutlineList.begin(); iter != aOutlineList.end(); ++iter)
879 SfxStyleSheet* pSheet = static_cast<SfxStyleSheet*>(*iter);
881 if (pSheet)
883 pObj->StartListening(*pSheet);
885 if( iter == aOutlineList.begin())
886 // text frame listens to stylesheet of layer 1
887 pObj->NbcSetStyleSheet(pSheet, true);
892 if( auto pTextObj = DynCastSdrTextObj( pObj ) )
893 if (pTextObj->IsEmptyPresObj())
895 PresObjKind ePresObjKind = pPage->GetPresObjKind(pObj);
896 OUString aString( pPage->GetPresObjText(ePresObjKind) );
898 if (!aString.isEmpty())
900 SdOutliner* pInternalOutl = GetInternalOutliner();
901 pPage->SetObjText( pTextObj, pInternalOutl, ePresObjKind, aString );
902 pObj->NbcSetStyleSheet( pPage->GetStyleSheetForPresObj( ePresObjKind ), true );
903 pInternalOutl->Clear();
910 // Local outliner that is used for outline mode. In this outliner, OutlinerViews
911 // may be inserted.
912 SdOutliner* SdDrawDocument::GetOutliner(bool bCreateOutliner)
914 if (!mpOutliner && bCreateOutliner)
916 mpOutliner.reset(new SdOutliner( this, OutlinerMode::TextObject ));
918 if (mpDocSh)
919 mpOutliner->SetRefDevice( SD_MOD()->GetVirtualRefDevice() );
921 mpOutliner->SetDefTab( m_nDefaultTabulator );
922 mpOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
925 return mpOutliner.get();
928 // Internal outliner that is used to create text objects. We don't insert any
929 // OutlinerViews into this outliner!
930 SdOutliner* SdDrawDocument::GetInternalOutliner(bool bCreateOutliner)
932 if ( !mpInternalOutliner && bCreateOutliner )
934 mpInternalOutliner.reset( new SdOutliner( this, OutlinerMode::TextObject ) );
936 // This outliner is only used to create special text objects. As no
937 // information about portions is saved in this outliner, the update mode
938 // can/should always remain sal_False.
939 mpInternalOutliner->SetUpdateLayout( false );
940 mpInternalOutliner->EnableUndo( false );
942 if (mpDocSh)
943 mpInternalOutliner->SetRefDevice( SD_MOD()->GetVirtualRefDevice() );
945 mpInternalOutliner->SetDefTab( m_nDefaultTabulator );
946 mpInternalOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
949 DBG_ASSERT( !mpInternalOutliner || ( ! mpInternalOutliner->IsUpdateLayout() ) , "InternalOutliner: UpdateMode = sal_True !" );
950 DBG_ASSERT( !mpInternalOutliner || ( ! mpInternalOutliner->IsUndoEnabled() ), "InternalOutliner: Undo = sal_True !" );
952 // If you add stuff here, always clear it out.
953 // Advantages:
954 // a) no unnecessary Clear calls
955 // b) no wasted memory
956 DBG_ASSERT( !mpInternalOutliner || ( ( mpInternalOutliner->GetParagraphCount() == 1 ) && ( mpInternalOutliner->GetText( mpInternalOutliner->GetParagraph( 0 ) ).isEmpty() ) ), "InternalOutliner: not empty!" );
958 return mpInternalOutliner.get();
961 // OnlineSpelling on/off
962 void SdDrawDocument::SetOnlineSpell(bool bIn)
964 mbOnlineSpell = bIn;
965 EEControlBits nCntrl;
967 if(mpOutliner)
969 nCntrl = mpOutliner->GetControlWord();
971 if(mbOnlineSpell)
972 nCntrl |= EEControlBits::ONLINESPELLING;
973 else
974 nCntrl &= ~EEControlBits::ONLINESPELLING;
976 mpOutliner->SetControlWord(nCntrl);
979 if (mpInternalOutliner)
981 nCntrl = mpInternalOutliner->GetControlWord();
983 if (mbOnlineSpell)
984 nCntrl |= EEControlBits::ONLINESPELLING;
985 else
986 nCntrl &= ~EEControlBits::ONLINESPELLING;
988 mpInternalOutliner->SetControlWord(nCntrl);
991 ::Outliner& rOutliner = GetDrawOutliner();
993 nCntrl = rOutliner.GetControlWord();
995 if (mbOnlineSpell)
996 nCntrl |= EEControlBits::ONLINESPELLING;
997 else
998 nCntrl &= ~EEControlBits::ONLINESPELLING;
1000 rOutliner.SetControlWord(nCntrl);
1002 if (mbOnlineSpell)
1004 StartOnlineSpelling();
1006 else
1008 StopOnlineSpelling();
1012 // OnlineSpelling: highlighting on/off
1013 uno::Reference< uno::XInterface > SdDrawDocument::createUnoModel()
1015 uno::Reference< uno::XInterface > xModel;
1019 if ( mpDocSh )
1020 xModel = mpDocSh->GetModel();
1022 catch( uno::RuntimeException& )
1026 return xModel;
1029 SvxNumType SdDrawDocument::GetPageNumType() const
1031 return mePageNumType;
1034 void SdDrawDocument::SetPrinterIndependentLayout (sal_Int32 nMode)
1036 switch (nMode)
1038 case css::document::PrinterIndependentLayout::DISABLED:
1039 case css::document::PrinterIndependentLayout::ENABLED:
1040 // Just store supported modes and inform the doc shell
1041 mnPrinterIndependentLayout = nMode;
1043 // Since it is possible that a SdDrawDocument is constructed without a
1044 // SdDrawDocShell the pointer member mpDocSh needs to be tested
1045 // before the call is executed. This is e. g. used for copy/paste.
1046 if(mpDocSh)
1048 mpDocSh->UpdateRefDevice ();
1051 break;
1053 default:
1054 // Ignore unknown values
1055 break;
1059 void SdDrawDocument::SetStartWithPresentation( bool bStartWithPresentation )
1061 mbStartWithPresentation = bStartWithPresentation;
1064 void SdDrawDocument::SetExitAfterPresenting( bool bExitAfterPresenting )
1066 mbExitAfterPresenting = bExitAfterPresenting;
1069 void SdDrawDocument::PageListChanged()
1071 mpDrawPageListWatcher->Invalidate();
1074 void SdDrawDocument::MasterPageListChanged()
1076 mpMasterPageListWatcher->Invalidate();
1079 void SdDrawDocument::SetCalcFieldValueHdl(::Outliner* pOutliner)
1081 pOutliner->SetCalcFieldValueHdl(LINK(SD_MOD(), SdModule, CalcFieldValueHdl));
1084 sal_uInt16 SdDrawDocument::GetAnnotationAuthorIndex( const OUString& rAuthor )
1086 // force current user to have first color
1087 if( maAnnotationAuthors.empty() )
1089 SvtUserOptions aUserOptions;
1090 maAnnotationAuthors.push_back( aUserOptions.GetFullName() );
1093 auto iter = std::find(maAnnotationAuthors.begin(), maAnnotationAuthors.end(), rAuthor);
1094 sal_uInt16 idx = static_cast<sal_uInt16>(std::distance(maAnnotationAuthors.begin(), iter));
1096 if( idx == maAnnotationAuthors.size() )
1098 maAnnotationAuthors.push_back( rAuthor );
1101 return idx;
1104 void SdDrawDocument::InitLayoutVector()
1106 if (utl::ConfigManager::IsFuzzing())
1107 return;
1109 const Reference<css::uno::XComponentContext> xContext(
1110 ::comphelper::getProcessComponentContext() );
1112 // get file list from configuration
1113 const Sequence< OUString > aFiles(
1114 officecfg::Office::Impress::Misc::LayoutListFiles::get() );
1116 if (aFiles.getLength() == 0)
1117 return;
1118 const Reference<XDocumentBuilder> xDocBuilder = DocumentBuilder::create( xContext );
1120 for( const auto& rFile : aFiles )
1122 OUString sFilename = comphelper::getExpandedUri(xContext, rFile);
1124 // load layout file into DOM
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) );
1135 catch (const uno::Exception &)
1137 // skip missing config. files
1142 void SdDrawDocument::InitObjectVector()
1144 if (utl::ConfigManager::IsFuzzing())
1145 return;
1147 const Reference<css::uno::XComponentContext> xContext(
1148 ::comphelper::getProcessComponentContext() );
1150 // get file list from configuration
1151 const Sequence< OUString > aFiles(
1152 officecfg::Office::Impress::Misc::PresObjListFiles::get() );
1154 if (aFiles.getLength() == 0)
1155 return;
1156 const Reference<XDocumentBuilder> xDocBuilder = DocumentBuilder::create( xContext );
1157 for( const auto& rFile : aFiles )
1159 OUString sFilename = comphelper::getExpandedUri(xContext, rFile);
1161 // load presentation object file into DOM
1165 // loop over every object entry in current file
1166 const Reference<XDocument> xDoc = xDocBuilder->parseURI( sFilename );
1167 const Reference<XNodeList> objectlist = xDoc->getElementsByTagName("object");
1168 const int nElements = objectlist->getLength();
1169 for(int index=0; index < nElements; index++)
1170 maPresObjectInfo.push_back( objectlist->item(index) );
1172 catch (const uno::Exception &)
1174 // skip missing config. files
1179 void SdDrawDocument::dumpAsXml(xmlTextWriterPtr pWriter) const
1181 bool bOwns = false;
1182 if (!pWriter)
1184 pWriter = xmlNewTextWriterFilename("model.xml", 0);
1185 xmlTextWriterSetIndent(pWriter,1);
1186 (void)xmlTextWriterSetIndentString(pWriter, BAD_CAST(" "));
1187 (void)xmlTextWriterStartDocument(pWriter, nullptr, nullptr, nullptr);
1188 bOwns = true;
1190 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SdDrawDocument"));
1191 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
1193 if (mpOutliner)
1194 mpOutliner->dumpAsXml(pWriter);
1195 FmFormModel::dumpAsXml(pWriter);
1196 if (GetUndoManager())
1197 GetUndoManager()->dumpAsXml(pWriter);
1199 (void)xmlTextWriterEndElement(pWriter);
1200 if (bOwns)
1202 (void)xmlTextWriterEndDocument(pWriter);
1203 xmlFreeTextWriter(pWriter);
1207 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */