bump product version to 6.4.0.3
[LibreOffice.git] / sd / source / core / drawdoc.cxx
blob93074a90ce4126e63be0f81e5333c09cf417f415
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 <editeng/forbiddencharacterstable.hxx>
30 #include <svl/srchitem.hxx>
31 #include <editeng/eeitem.hxx>
32 #include <editeng/scriptspaceitem.hxx>
33 #include <tools/debug.hxx>
35 #include <unotools/configmgr.hxx>
36 #include <unotools/useroptions.hxx>
37 #include <officecfg/Office/Impress.hxx>
39 #include <sfx2/linkmgr.hxx>
40 #include <Outliner.hxx>
41 #include <sdmod.hxx>
42 #include <editeng/editstat.hxx>
43 #include <svx/svdotext.hxx>
44 #include <editeng/unolingu.hxx>
45 #include <svl/itempool.hxx>
46 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
47 #include <com/sun/star/beans/XPropertySet.hpp>
48 #include <editeng/outlobj.hxx>
49 #include <comphelper/getexpandeduri.hxx>
50 #include <i18nlangtag/mslangid.hxx>
51 #include <i18nlangtag/languagetag.hxx>
52 #include <unotools/charclass.hxx>
53 #include <comphelper/processfactory.hxx>
54 #include <unotools/lingucfg.hxx>
55 #include <com/sun/star/uno/Reference.hxx>
56 #include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
57 #include <com/sun/star/xml/dom/XDocument.hpp>
58 #include <com/sun/star/xml/dom/XNodeList.hpp>
59 #include <com/sun/star/xml/dom/DocumentBuilder.hpp>
60 #include <com/sun/star/uno/XComponentContext.hpp>
61 #include <rtl/ustring.hxx>
63 #include <editeng/outliner.hxx>
64 #include <drawdoc.hxx>
65 #include <sdpage.hxx>
66 #include <strings.hrc>
67 #include <glob.hxx>
68 #include <stlpool.hxx>
69 #include <sdresid.hxx>
70 #include <customshowlist.hxx>
71 #include <DrawDocShell.hxx>
72 #include <GraphicDocShell.hxx>
73 #include <sdxfer.hxx>
74 #include <optsitem.hxx>
75 #include <FrameView.hxx>
76 #include <undo/undomanager.hxx>
77 #include <sdundogr.hxx>
78 #include <undopage.hxx>
79 #include <vcl/settings.hxx>
80 #include <vcl/svapp.hxx>
81 #include <unokywds.hxx>
83 namespace com { namespace sun { namespace star { namespace linguistic2 { class XHyphenator; } } } }
84 namespace com { namespace sun { namespace star { namespace linguistic2 { class XSpellChecker1; } } } }
86 using namespace ::sd;
87 using namespace ::com::sun::star;
88 using namespace ::com::sun::star::uno;
89 using namespace ::com::sun::star::lang;
90 using namespace ::com::sun::star::linguistic2;
92 using namespace com::sun::star::xml::dom;
93 using ::com::sun::star::uno::Reference;
94 using ::com::sun::star::lang::XMultiServiceFactory;
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 mbFullScreen( true ),
109 mbAnimationAllowed( true ),
110 mnPauseTimeout( 0 ),
111 mbShowPauseLogo( false )
115 SdDrawDocument::SdDrawDocument(DocumentType eType, SfxObjectShell* pDrDocSh)
116 : FmFormModel(
117 nullptr,
118 pDrDocSh)
119 , mpDocSh(static_cast< ::sd::DrawDocShell*>(pDrDocSh))
120 , mpCreatingTransferable( nullptr )
121 , mbHasOnlineSpellErrors(false)
122 , mbInitialOnlineSpellingEnabled(true)
123 , mbNewOrLoadCompleted(false)
124 , mbOnlineSpell(false)
125 , mbStartWithPresentation( false )
126 , mbExitAfterPresenting( false )
127 , meLanguage( LANGUAGE_SYSTEM )
128 , meLanguageCJK( LANGUAGE_SYSTEM )
129 , meLanguageCTL( LANGUAGE_SYSTEM )
130 , mePageNumType(SVX_NUM_ARABIC)
131 , mbAllocDocSh(false)
132 , meDocType(eType)
133 , mbEmbedFonts(false)
134 , mbEmbedUsedFontsOnly(false)
135 , mbEmbedFontScriptLatin(true)
136 , mbEmbedFontScriptAsian(true)
137 , mbEmbedFontScriptComplex(true)
139 mpDrawPageListWatcher.reset(new ImpDrawPageListWatcher(*this));
140 mpMasterPageListWatcher.reset(new ImpMasterPageListWatcher(*this));
142 InitLayoutVector();
143 InitObjectVector();
144 SetObjectShell(pDrDocSh); // for VCDrawModel
146 if (mpDocSh)
148 SetSwapGraphics();
151 // Set measuring unit (of the application) and scale (of SdMod)
152 sal_Int32 nX, nY;
153 SdOptions* pOptions = SD_MOD()->GetSdOptions(meDocType);
154 pOptions->GetScale( nX, nY );
156 // Allow UI scale only for draw documents.
157 if( eType == DocumentType::Draw )
158 SetUIUnit( static_cast<FieldUnit>(pOptions->GetMetric()), Fraction( nX, nY ) ); // user-defined
159 else
160 SetUIUnit( static_cast<FieldUnit>(pOptions->GetMetric()), Fraction( 1, 1 ) ); // default
162 SetScaleUnit(MapUnit::Map100thMM);
163 SetScaleFraction(Fraction(1, 1));
164 SetDefaultFontHeight(847); // 24p
166 m_pItemPool->SetDefaultMetric(MapUnit::Map100thMM);
167 m_pItemPool->FreezeIdRanges();
168 SetTextDefaults();
170 // DrawingEngine has to know where it is...
171 FmFormModel::SetStyleSheetPool( new SdStyleSheetPool( GetPool(), this ) );
173 // Set StyleSheetPool for DrawOutliner, so text objects can be read correctly.
174 // The link to the StyleRequest handler of the document is set later, in
175 // NewOrLoadCompleted, because only then do all the templates exist.
176 SdrOutliner& rOutliner = GetDrawOutliner();
177 rOutliner.SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
178 SetCalcFieldValueHdl( &rOutliner );
180 // set linguistic options
181 if (!utl::ConfigManager::IsFuzzing())
183 const SvtLinguConfig aLinguConfig;
184 SvtLinguOptions aOptions;
185 aLinguConfig.GetOptions( aOptions );
187 SetLanguage( MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage,
188 css::i18n::ScriptType::LATIN), EE_CHAR_LANGUAGE );
189 SetLanguage( MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage_CJK,
190 css::i18n::ScriptType::ASIAN), EE_CHAR_LANGUAGE_CJK );
191 SetLanguage( MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage_CTL,
192 css::i18n::ScriptType::COMPLEX), EE_CHAR_LANGUAGE_CTL );
194 mbOnlineSpell = aOptions.bIsSpellAuto;
197 LanguageType eRealLanguage = MsLangId::getRealLanguage( meLanguage );
198 LanguageTag aLanguageTag( eRealLanguage);
199 mpCharClass.reset(new CharClass( aLanguageTag ));
201 // If the current application language is a language that uses right-to-left text...
202 LanguageType eRealCTLLanguage = Application::GetSettings().GetLanguageTag().getLanguageType();
204 // for korean and japanese languages we have a different default for apply spacing between asian, latin and ctl text
205 if (MsLangId::isKorean(eRealCTLLanguage) || (LANGUAGE_JAPANESE == eRealCTLLanguage))
207 GetPool().GetSecondaryPool()->SetPoolDefaultItem( SvxScriptSpaceItem( false, EE_PARA_ASIANCJKSPACING ) );
210 // Set DefTab and SpellOptions for the SD module
211 sal_uInt16 nDefTab = pOptions->GetDefTab();
212 SetDefaultTabulator( nDefTab );
216 Reference< XSpellChecker1 > xSpellChecker( LinguMgr::GetSpellChecker() );
217 if ( xSpellChecker.is() )
218 rOutliner.SetSpeller( xSpellChecker );
220 Reference< XHyphenator > xHyphenator( LinguMgr::GetHyphenator() );
221 if( xHyphenator.is() )
222 rOutliner.SetHyphenator( xHyphenator );
224 SetForbiddenCharsTable(SvxForbiddenCharactersTable::makeForbiddenCharactersTable(::comphelper::getProcessComponentContext()));
226 catch(...)
228 OSL_FAIL("Can't get SpellChecker");
231 rOutliner.SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
233 if (mpDocSh)
235 SetLinkManager( new sfx2::LinkManager(mpDocSh) );
238 EEControlBits nCntrl = rOutliner.GetControlWord();
239 nCntrl |= EEControlBits::ALLOWBIGOBJS;
241 if (mbOnlineSpell)
242 nCntrl |= EEControlBits::ONLINESPELLING;
243 else
244 nCntrl &= ~EEControlBits::ONLINESPELLING;
246 nCntrl &= ~ EEControlBits::ULSPACESUMMATION;
247 if ( meDocType != DocumentType::Impress )
248 SetSummationOfParagraphs( false );
249 else
251 SetSummationOfParagraphs( pOptions->IsSummationOfParagraphs() );
252 if ( pOptions->IsSummationOfParagraphs() )
253 nCntrl |= EEControlBits::ULSPACESUMMATION;
255 rOutliner.SetControlWord(nCntrl);
257 // Initialize the printer independent layout mode
258 SetPrinterIndependentLayout (pOptions->GetPrinterIndependentLayout());
260 // Set the StyleSheetPool for HitTestOutliner.
261 // The link to the StyleRequest handler of the document is set later, in
262 // NewOrLoadCompleted, because only then do all the templates exist.
263 m_pHitTestOutliner->SetStyleSheetPool( static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()) );
265 SetCalcFieldValueHdl( m_pHitTestOutliner.get() );
269 Reference< XSpellChecker1 > xSpellChecker( LinguMgr::GetSpellChecker() );
270 if ( xSpellChecker.is() )
271 m_pHitTestOutliner->SetSpeller( xSpellChecker );
273 Reference< XHyphenator > xHyphenator( LinguMgr::GetHyphenator() );
274 if( xHyphenator.is() )
275 m_pHitTestOutliner->SetHyphenator( xHyphenator );
277 catch(...)
279 OSL_FAIL("Can't get SpellChecker");
282 m_pHitTestOutliner->SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
284 EEControlBits nCntrl2 = m_pHitTestOutliner->GetControlWord();
285 nCntrl2 |= EEControlBits::ALLOWBIGOBJS;
286 nCntrl2 &= ~EEControlBits::ONLINESPELLING;
288 nCntrl2 &= ~ EEControlBits::ULSPACESUMMATION;
289 if ( pOptions->IsSummationOfParagraphs() )
290 nCntrl2 |= EEControlBits::ULSPACESUMMATION;
292 m_pHitTestOutliner->SetControlWord( nCntrl2 );
294 /** Create layers
296 * We create the following default layers on all pages and master pages:
298 * sUNO_LayerName_layout; "layout": default layer for drawing objects of normal pages
299 * localized by SdResId(STR_LAYER_LAYOUT)
301 * sUNO_LayerName_background; "background": background of the master page
302 * localized by SdResId(STR_LAYER_BCKGRND)
303 * (currently unused within normal pages and not visible to users)
305 * sUNO_LayerName_background_objects; "backgroundobjects": objects on the background of master pages
306 * localized by SdResId(STR_LAYER_BCKGRNDOBJ)
307 * (currently unused within normal pages)
309 * sUNO_LayerName_controls; "controls": default layer for controls
310 * localized by SdResId(STR_LAYER_CONTROLS)
311 * (currently special handling in regard to z-order)
313 * sUNO_LayerName_measurelines; "measurelines" : default layer for measure lines
314 * localized by SdResId(STR_LAYER_MEASURELINES)
318 SdrLayerAdmin& rLayerAdmin = GetLayerAdmin();
319 rLayerAdmin.NewLayer( sUNO_LayerName_layout );
320 rLayerAdmin.NewLayer( sUNO_LayerName_background );
321 rLayerAdmin.NewLayer( sUNO_LayerName_background_objects );
322 rLayerAdmin.NewLayer( sUNO_LayerName_controls);
323 rLayerAdmin.NewLayer( sUNO_LayerName_measurelines );
325 rLayerAdmin.SetControlLayerName(sUNO_LayerName_controls);
330 // Destructor
331 SdDrawDocument::~SdDrawDocument()
333 Broadcast(SdrHint(SdrHintKind::ModelCleared));
335 if (mpWorkStartupTimer)
337 if ( mpWorkStartupTimer->IsActive() )
338 mpWorkStartupTimer->Stop();
340 mpWorkStartupTimer.reset();
343 StopOnlineSpelling();
344 mpOnlineSearchItem.reset();
346 CloseBookmarkDoc();
347 SetAllocDocSh(false);
349 ClearModel(true);
351 if (m_pLinkManager)
353 // Release BaseLinks
354 if ( !m_pLinkManager->GetLinks().empty() )
356 m_pLinkManager->Remove( 0, m_pLinkManager->GetLinks().size() );
359 delete m_pLinkManager;
360 m_pLinkManager = nullptr;
363 maFrameViewList.clear();
364 mpCustomShowList.reset();
365 mpOutliner.reset();
366 mpInternalOutliner.reset();
367 mpCharClass.reset();
370 void SdDrawDocument::adaptSizeAndBorderForAllPages(
371 const Size& rNewSize,
372 long nLeft,
373 long nRight,
374 long nUpper,
375 long nLower)
377 const sal_uInt16 nMasterPageCnt(GetMasterSdPageCount(PageKind::Standard));
378 const sal_uInt16 nPageCnt(GetSdPageCount(PageKind::Standard));
380 if(0 == nMasterPageCnt && 0 == nPageCnt)
382 return;
385 SdPage* pPage(0 != nPageCnt ? GetSdPage(0, PageKind::Standard) : GetMasterSdPage(0, PageKind::Standard));
387 // call fully implemented local version, including getting
388 // some more information from one of the Pages (1st one)
389 AdaptPageSizeForAllPages(
390 rNewSize,
391 PageKind::Standard,
392 nullptr,
393 nLeft,
394 nRight,
395 nUpper,
396 nLower,
397 true,
398 pPage->GetOrientation(),
399 pPage->GetPaperBin(),
400 pPage->IsBackgroundFullSize());
402 // adjust handout page to new format of the standard page
403 if(0 != nPageCnt)
405 GetSdPage(0, PageKind::Handout)->CreateTitleAndLayout(true);
409 void SdDrawDocument::AdaptPageSizeForAllPages(
410 const Size& rNewSize,
411 PageKind ePageKind,
412 SdUndoGroup* pUndoGroup,
413 long nLeft,
414 long nRight,
415 long nUpper,
416 long nLower,
417 bool bScaleAll,
418 Orientation eOrientation,
419 sal_uInt16 nPaperBin,
420 bool bBackgroundFullSize)
422 sal_uInt16 i;
423 const sal_uInt16 nMasterPageCnt(GetMasterSdPageCount(ePageKind));
424 const sal_uInt16 nPageCnt(GetSdPageCount(ePageKind));
426 if(0 == nMasterPageCnt && 0 == nPageCnt)
428 return;
431 for (i = 0; i < nMasterPageCnt; i++)
433 // first, handle all master pages
434 SdPage* pPage(GetMasterSdPage(i, ePageKind));
436 if(pUndoGroup)
438 SdUndoAction* pUndo(
439 new SdPageFormatUndoAction(
440 this,
441 pPage,
442 pPage->GetSize(),
443 pPage->GetLeftBorder(), pPage->GetRightBorder(),
444 pPage->GetUpperBorder(), pPage->GetLowerBorder(),
445 pPage->GetOrientation(),
446 pPage->GetPaperBin(),
447 pPage->IsBackgroundFullSize(),
448 rNewSize,
449 nLeft, nRight,
450 nUpper, nLower,
451 bScaleAll,
452 eOrientation,
453 nPaperBin,
454 bBackgroundFullSize));
455 pUndoGroup->AddAction(pUndo);
458 if (rNewSize.Width() > 0 || nLeft >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0)
460 ::tools::Rectangle aNewBorderRect(nLeft, nUpper, nRight, nLower);
461 pPage->ScaleObjects(rNewSize, aNewBorderRect, bScaleAll);
463 if (rNewSize.Width() > 0)
465 pPage->SetSize(rNewSize);
469 if( nLeft >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0 )
471 pPage->SetBorder(nLeft, nUpper, nRight, nLower);
474 pPage->SetOrientation(eOrientation);
475 pPage->SetPaperBin( nPaperBin );
476 pPage->SetBackgroundFullSize( bBackgroundFullSize );
478 if ( ePageKind == PageKind::Standard )
480 GetMasterSdPage(i, PageKind::Notes)->CreateTitleAndLayout();
483 pPage->CreateTitleAndLayout();
486 for (i = 0; i < nPageCnt; i++)
488 // then, handle all pages
489 SdPage* pPage(GetSdPage(i, ePageKind));
491 if(pUndoGroup)
493 SdUndoAction* pUndo(
494 new SdPageFormatUndoAction(
495 this,
496 pPage,
497 pPage->GetSize(),
498 pPage->GetLeftBorder(), pPage->GetRightBorder(),
499 pPage->GetUpperBorder(), pPage->GetLowerBorder(),
500 pPage->GetOrientation(),
501 pPage->GetPaperBin(),
502 pPage->IsBackgroundFullSize(),
503 rNewSize,
504 nLeft, nRight,
505 nUpper, nLower,
506 bScaleAll,
507 eOrientation,
508 nPaperBin,
509 bBackgroundFullSize));
510 pUndoGroup->AddAction(pUndo);
513 if (rNewSize.Width() > 0 || nLeft >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0)
515 ::tools::Rectangle aNewBorderRect(nLeft, nUpper, nRight, nLower);
516 pPage->ScaleObjects(rNewSize, aNewBorderRect, bScaleAll);
518 if (rNewSize.Width() > 0)
520 pPage->SetSize(rNewSize);
524 if( nLeft >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0 )
526 pPage->SetBorder(nLeft, nUpper, nRight, nLower);
529 pPage->SetOrientation(eOrientation);
530 pPage->SetPaperBin( nPaperBin );
531 pPage->SetBackgroundFullSize( bBackgroundFullSize );
533 if ( ePageKind == PageKind::Standard )
535 SdPage* pNotesPage = GetSdPage(i, PageKind::Notes);
536 pNotesPage->SetAutoLayout( pNotesPage->GetAutoLayout() );
539 pPage->SetAutoLayout( pPage->GetAutoLayout() );
543 SdrModel* SdDrawDocument::AllocModel() const
545 return AllocSdDrawDocument();
548 namespace
551 /// Copies all user-defined properties from pSource to pDestination.
552 void lcl_copyUserDefinedProperties(const SfxObjectShell* pSource, const SfxObjectShell* pDestination)
554 if (!pSource || !pDestination)
555 return;
557 uno::Reference<document::XDocumentProperties> xSource = pSource->getDocProperties();
558 uno::Reference<document::XDocumentProperties> xDestination = pDestination->getDocProperties();
559 uno::Reference<beans::XPropertyContainer> xSourcePropertyContainer = xSource->getUserDefinedProperties();
560 uno::Reference<beans::XPropertyContainer> xDestinationPropertyContainer = xDestination->getUserDefinedProperties();
561 uno::Reference<beans::XPropertySet> xSourcePropertySet(xSourcePropertyContainer, uno::UNO_QUERY);
562 const uno::Sequence<beans::Property> aProperties = xSourcePropertySet->getPropertySetInfo()->getProperties();
564 for (const beans::Property& rProperty : aProperties)
566 const OUString& rKey = rProperty.Name;
567 uno::Any aValue = xSourcePropertySet->getPropertyValue(rKey);
568 // We know that pDestination was just created, so has no properties: addProperty() will never throw.
569 xDestinationPropertyContainer->addProperty(rKey, beans::PropertyAttribute::REMOVABLE, aValue);
575 // This method creates a new document (SdDrawDocument) and returns a pointer to
576 // said document. The drawing engine uses this method to put the document (or
577 // parts of it) into the clipboard/DragServer.
578 SdDrawDocument* SdDrawDocument::AllocSdDrawDocument() const
580 SdDrawDocument* pNewModel = nullptr;
582 if( mpCreatingTransferable )
584 // Document is created for drag & drop/clipboard. To be able to
585 // do this, the document has to know a DocShell (SvPersist).
586 SfxObjectShell* pObj = nullptr;
587 ::sd::DrawDocShell* pNewDocSh = nullptr;
589 if( meDocType == DocumentType::Impress )
590 mpCreatingTransferable->SetDocShell( new ::sd::DrawDocShell(
591 SfxObjectCreateMode::EMBEDDED, true, meDocType ) );
592 else
593 mpCreatingTransferable->SetDocShell( new ::sd::GraphicDocShell(
594 SfxObjectCreateMode::EMBEDDED ) );
596 pObj = mpCreatingTransferable->GetDocShell().get();
597 pNewDocSh = static_cast< ::sd::DrawDocShell*>( pObj );
598 pNewDocSh->DoInitNew();
599 pNewModel = pNewDocSh->GetDoc();
601 // Only necessary for clipboard -
602 // for drag & drop this is handled by DragServer
603 SdStyleSheetPool* pOldStylePool = static_cast<SdStyleSheetPool*>( GetStyleSheetPool() );
604 SdStyleSheetPool* pNewStylePool = static_cast<SdStyleSheetPool*>( pNewModel->GetStyleSheetPool() );
606 pNewStylePool->CopyGraphicSheets(*pOldStylePool);
607 pNewStylePool->CopyCellSheets(*pOldStylePool);
608 pNewStylePool->CopyTableStyles(*pOldStylePool);
610 for (sal_uInt16 i = 0; i < GetMasterSdPageCount(PageKind::Standard); i++)
612 // Move with all of the master page's layouts
613 OUString aOldLayoutName(const_cast<SdDrawDocument*>(this)->GetMasterSdPage(i, PageKind::Standard)->GetLayoutName());
614 aOldLayoutName = aOldLayoutName.copy( 0, aOldLayoutName.indexOf( SD_LT_SEPARATOR ) );
615 StyleSheetCopyResultVector aCreatedSheets;
616 pNewStylePool->CopyLayoutSheets(aOldLayoutName, *pOldStylePool, aCreatedSheets );
619 lcl_copyUserDefinedProperties(GetDocSh(), pNewDocSh);
621 pNewModel->NewOrLoadCompleted( DOC_LOADED ); // loaded from source document
623 else if( mbAllocDocSh )
625 // Create a DocShell which is then returned with GetAllocedDocSh()
626 SdDrawDocument* pDoc = const_cast<SdDrawDocument*>(this);
627 pDoc->SetAllocDocSh(false);
628 pDoc->mxAllocedDocShRef = new ::sd::DrawDocShell(
629 SfxObjectCreateMode::EMBEDDED, true, meDocType);
630 pDoc->mxAllocedDocShRef->DoInitNew();
631 pNewModel = pDoc->mxAllocedDocShRef->GetDoc();
633 else
635 pNewModel = new SdDrawDocument(meDocType, nullptr);
638 return pNewModel;
641 SdPage* SdDrawDocument::AllocSdPage(bool bMasterPage)
643 return new SdPage(*this, bMasterPage);
646 // This method creates a new page (SdPage) and returns a pointer to said page.
647 // The drawing engine uses this method to create pages (whose types it does
648 // not know, as they are _derivatives_ of SdrPage) when loading.
649 SdrPage* SdDrawDocument::AllocPage(bool bMasterPage)
651 return AllocSdPage(bMasterPage);
654 // When the model has changed
655 void SdDrawDocument::SetChanged(bool bFlag)
657 if (mpDocSh)
659 if (mbNewOrLoadCompleted && mpDocSh->IsEnableSetModified())
661 // Pass on to base class
662 FmFormModel::SetChanged(bFlag);
664 // Forward to ObjectShell
665 mpDocSh->SetModified(bFlag);
668 else
670 // Pass on to base class
671 FmFormModel::SetChanged(bFlag);
675 // The model changed, don't call anything else
676 void SdDrawDocument::NbcSetChanged(bool bFlag)
678 // forward to baseclass
679 FmFormModel::SetChanged(bFlag);
682 // NewOrLoadCompleted is called when the document is loaded, or when it is clear
683 // it won't load any more.
684 void SdDrawDocument::NewOrLoadCompleted(DocCreationMode eMode)
686 if (eMode == NEW_DOC)
688 // New document:
689 // create slideshow and default templates,
690 // create pool for virtual controls
691 CreateLayoutTemplates();
692 CreateDefaultCellStyles();
694 static_cast< SdStyleSheetPool* >( mxStyleSheetPool.get() )->CreatePseudosIfNecessary();
696 else if (eMode == DOC_LOADED)
698 // Document has finished loading
700 CheckMasterPages();
702 if ( GetMasterSdPageCount(PageKind::Standard) > 1 )
703 RemoveUnnecessaryMasterPages( nullptr, true, false );
705 for ( sal_uInt16 i = 0; i < GetPageCount(); i++ )
707 // Check for correct layout names
708 SdPage* pPage = static_cast<SdPage*>( GetPage( i ) );
710 if(pPage->TRG_HasMasterPage())
712 SdPage& rMaster = static_cast<SdPage&>(pPage->TRG_GetMasterPage() );
714 if(rMaster.GetLayoutName() != pPage->GetLayoutName())
716 pPage->SetLayoutName(rMaster.GetLayoutName());
721 for ( sal_uInt16 nPage = 0; nPage < GetMasterPageCount(); nPage++)
723 // LayoutName and PageName must be the same
724 SdPage* pPage = static_cast<SdPage*>( GetMasterPage( nPage ) );
726 OUString aName( pPage->GetLayoutName() );
727 aName = aName.copy( 0, aName.indexOf( SD_LT_SEPARATOR ) );
729 if( aName != pPage->GetName() )
730 pPage->SetName( aName );
733 // Create names of the styles in the user's language
734 static_cast<SdStyleSheetPool*>(mxStyleSheetPool.get())->UpdateStdNames();
736 // Create any missing styles - eg. formerly, there was no Subtitle style
737 static_cast<SdStyleSheetPool*>(mxStyleSheetPool.get())->CreatePseudosIfNecessary();
740 // Set default style of Drawing Engine
741 OUString aName( SdResId(STR_STANDARD_STYLESHEET_NAME));
742 SetDefaultStyleSheet(static_cast<SfxStyleSheet*>(mxStyleSheetPool->Find(aName, SfxStyleFamily::Para)));
744 // #i119287# Set default StyleSheet for SdrGrafObj and SdrOle2Obj
745 SetDefaultStyleSheetForSdrGrafObjAndSdrOle2Obj(static_cast<SfxStyleSheet*>(mxStyleSheetPool->Find(SdResId(STR_POOLSHEET_OBJNOLINENOFILL), SfxStyleFamily::Para)));
747 // Initialize DrawOutliner and DocumentOutliner, but don't initialize the
748 // global outliner, as it is not document specific like StyleSheetPool and
749 // StyleRequestHandler are.
750 ::Outliner& rDrawOutliner = GetDrawOutliner();
751 rDrawOutliner.SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
752 EEControlBits nCntrl = rDrawOutliner.GetControlWord();
753 if (mbOnlineSpell)
754 nCntrl |= EEControlBits::ONLINESPELLING;
755 else
756 nCntrl &= ~EEControlBits::ONLINESPELLING;
757 rDrawOutliner.SetControlWord(nCntrl);
759 // Initialize HitTestOutliner and DocumentOutliner, but don't initialize the
760 // global outliner, as it is not document specific like StyleSheetPool and
761 // StyleRequestHandler are.
762 m_pHitTestOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
764 if(mpOutliner)
766 mpOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
768 if(mpInternalOutliner)
770 mpInternalOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
773 if ( eMode == DOC_LOADED )
775 // Make presentation objects listeners of the appropriate styles
776 SdStyleSheetPool* pSPool = static_cast<SdStyleSheetPool*>( GetStyleSheetPool() );
777 sal_uInt16 nPage, nPageCount;
779 // create missing layout style sheets for broken documents
780 // that were created with the 5.2
781 nPageCount = GetMasterSdPageCount( PageKind::Standard );
782 for (nPage = 0; nPage < nPageCount; nPage++)
784 SdPage* pPage = GetMasterSdPage(nPage, PageKind::Standard);
785 pSPool->CreateLayoutStyleSheets( pPage->GetName(), true );
788 // Default and notes pages:
789 for (nPage = 0; nPage < GetPageCount(); nPage++)
791 SdPage* pPage = static_cast<SdPage*>(GetPage(nPage));
792 NewOrLoadCompleted( pPage, pSPool );
795 // Master pages:
796 for (nPage = 0; nPage < GetMasterPageCount(); nPage++)
798 SdPage* pPage = static_cast<SdPage*>(GetMasterPage(nPage));
800 NewOrLoadCompleted( pPage, pSPool );
804 mbNewOrLoadCompleted = true;
805 UpdateAllLinks();
806 SetChanged( false );
809 /** updates all links, only links in this document should by resolved */
810 void SdDrawDocument::UpdateAllLinks()
812 if (s_pDocLockedInsertingLinks || !m_pLinkManager || m_pLinkManager->GetLinks().empty())
813 return;
815 s_pDocLockedInsertingLinks = this; // lock inserting links. only links in this document should by resolved
817 if (mpDocSh)
819 comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = mpDocSh->getEmbeddedObjectContainer();
820 rEmbeddedObjectContainer.setUserAllowsLinkUpdate(true);
823 m_pLinkManager->UpdateAllLinks(true, false, nullptr); // query box: update all links?
825 if (s_pDocLockedInsertingLinks == this)
826 s_pDocLockedInsertingLinks = nullptr; // unlock inserting links
829 /** this loops over the presentation objects of a page and repairs some new settings
830 from old binary files and resets all default strings for empty presentation objects.
832 void SdDrawDocument::NewOrLoadCompleted( SdPage* pPage, SdStyleSheetPool* pSPool )
834 sd::ShapeList& rPresentationShapes( pPage->GetPresentationShapeList() );
835 if(rPresentationShapes.isEmpty())
836 return;
838 // Create lists of title and outline styles
839 OUString aName = pPage->GetLayoutName();
840 aName = aName.copy( 0, aName.indexOf( SD_LT_SEPARATOR ) );
842 std::vector<SfxStyleSheetBase*> aOutlineList;
843 pSPool->CreateOutlineSheetList(aName,aOutlineList);
845 SfxStyleSheet* pTitleSheet = static_cast<SfxStyleSheet*>(pSPool->GetTitleSheet(aName));
847 SdrObject* pObj = nullptr;
848 rPresentationShapes.seekShape(0);
850 // Now look for title and outline text objects, then make those objects
851 // listeners.
852 while( (pObj = rPresentationShapes.getNextShape()) )
854 if (pObj->GetObjInventor() == SdrInventor::Default)
856 OutlinerParaObject* pOPO = pObj->GetOutlinerParaObject();
857 sal_uInt16 nId = pObj->GetObjIdentifier();
859 if (nId == OBJ_TITLETEXT)
861 if( pOPO && pOPO->GetOutlinerMode() == OutlinerMode::DontKnow )
862 pOPO->SetOutlinerMode( OutlinerMode::TitleObject );
864 // sal_True: don't delete "hard" attributes when doing this.
865 if (pTitleSheet)
866 pObj->SetStyleSheet(pTitleSheet, true);
868 else if (nId == OBJ_OUTLINETEXT)
870 if( pOPO && pOPO->GetOutlinerMode() == OutlinerMode::DontKnow )
871 pOPO->SetOutlinerMode( OutlinerMode::OutlineObject );
873 std::vector<SfxStyleSheetBase*>::iterator iter;
874 for (iter = aOutlineList.begin(); iter != aOutlineList.end(); ++iter)
876 SfxStyleSheet* pSheet = static_cast<SfxStyleSheet*>(*iter);
878 if (pSheet)
880 pObj->StartListening(*pSheet);
882 if( iter == aOutlineList.begin())
883 // text frame listens to stylesheet of layer 1
884 pObj->NbcSetStyleSheet(pSheet, true);
889 if( dynamic_cast< const SdrTextObj *>( pObj ) != nullptr && pObj->IsEmptyPresObj())
891 PresObjKind ePresObjKind = pPage->GetPresObjKind(pObj);
892 OUString aString( pPage->GetPresObjText(ePresObjKind) );
894 if (!aString.isEmpty())
896 SdOutliner* pInternalOutl = GetInternalOutliner();
897 pPage->SetObjText( static_cast<SdrTextObj*>(pObj), pInternalOutl, ePresObjKind, aString );
898 pObj->NbcSetStyleSheet( pPage->GetStyleSheetForPresObj( ePresObjKind ), true );
899 pInternalOutl->Clear();
906 // Local outliner that is used for outline mode. In this outliner, OutlinerViews
907 // may be inserted.
908 SdOutliner* SdDrawDocument::GetOutliner(bool bCreateOutliner)
910 if (!mpOutliner && bCreateOutliner)
912 mpOutliner.reset(new SdOutliner( this, OutlinerMode::TextObject ));
914 if (mpDocSh)
915 mpOutliner->SetRefDevice( SD_MOD()->GetVirtualRefDevice() );
917 mpOutliner->SetDefTab( m_nDefaultTabulator );
918 mpOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
921 return mpOutliner.get();
924 // Internal outliner that is used to create text objects. We don't insert any
925 // OutlinerViews into this outliner!
926 SdOutliner* SdDrawDocument::GetInternalOutliner(bool bCreateOutliner)
928 if ( !mpInternalOutliner && bCreateOutliner )
930 mpInternalOutliner.reset( new SdOutliner( this, OutlinerMode::TextObject ) );
932 // This outliner is only used to create special text objects. As no
933 // information about portions is saved in this outliner, the update mode
934 // can/should always remain sal_False.
935 mpInternalOutliner->SetUpdateMode( false );
936 mpInternalOutliner->EnableUndo( false );
938 if (mpDocSh)
939 mpInternalOutliner->SetRefDevice( SD_MOD()->GetVirtualRefDevice() );
941 mpInternalOutliner->SetDefTab( m_nDefaultTabulator );
942 mpInternalOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
945 DBG_ASSERT( !mpInternalOutliner || ( ! mpInternalOutliner->GetUpdateMode() ) , "InternalOutliner: UpdateMode = sal_True !" );
946 DBG_ASSERT( !mpInternalOutliner || ( ! mpInternalOutliner->IsUndoEnabled() ), "InternalOutliner: Undo = sal_True !" );
948 // If you add stuff here, always clear it out.
949 // Advantages:
950 // a) no unnecessary Clear calls
951 // b) no wasted memory
952 DBG_ASSERT( !mpInternalOutliner || ( ( mpInternalOutliner->GetParagraphCount() == 1 ) && ( mpInternalOutliner->GetText( mpInternalOutliner->GetParagraph( 0 ) ).isEmpty() ) ), "InternalOutliner: not empty!" );
954 return mpInternalOutliner.get();
957 // OnlineSpelling on/off
958 void SdDrawDocument::SetOnlineSpell(bool bIn)
960 mbOnlineSpell = bIn;
961 EEControlBits nCntrl;
963 if(mpOutliner)
965 nCntrl = mpOutliner->GetControlWord();
967 if(mbOnlineSpell)
968 nCntrl |= EEControlBits::ONLINESPELLING;
969 else
970 nCntrl &= ~EEControlBits::ONLINESPELLING;
972 mpOutliner->SetControlWord(nCntrl);
975 if (mpInternalOutliner)
977 nCntrl = mpInternalOutliner->GetControlWord();
979 if (mbOnlineSpell)
980 nCntrl |= EEControlBits::ONLINESPELLING;
981 else
982 nCntrl &= ~EEControlBits::ONLINESPELLING;
984 mpInternalOutliner->SetControlWord(nCntrl);
987 ::Outliner& rOutliner = GetDrawOutliner();
989 nCntrl = rOutliner.GetControlWord();
991 if (mbOnlineSpell)
992 nCntrl |= EEControlBits::ONLINESPELLING;
993 else
994 nCntrl &= ~EEControlBits::ONLINESPELLING;
996 rOutliner.SetControlWord(nCntrl);
998 if (mbOnlineSpell)
1000 StartOnlineSpelling();
1002 else
1004 StopOnlineSpelling();
1008 // OnlineSpelling: highlighting on/off
1009 uno::Reference< uno::XInterface > SdDrawDocument::createUnoModel()
1011 uno::Reference< uno::XInterface > xModel;
1015 if ( mpDocSh )
1016 xModel = mpDocSh->GetModel();
1018 catch( uno::RuntimeException& )
1022 return xModel;
1025 SvxNumType SdDrawDocument::GetPageNumType() const
1027 return mePageNumType;
1030 void SdDrawDocument::SetPrinterIndependentLayout (sal_Int32 nMode)
1032 switch (nMode)
1034 case css::document::PrinterIndependentLayout::DISABLED:
1035 case css::document::PrinterIndependentLayout::ENABLED:
1036 // Just store supported modes and inform the doc shell
1037 mnPrinterIndependentLayout = nMode;
1039 // Since it is possible that a SdDrawDocument is constructed without a
1040 // SdDrawDocShell the pointer member mpDocSh needs to be tested
1041 // before the call is executed. This is e. g. used for copy/paste.
1042 if(mpDocSh)
1044 mpDocSh->UpdateRefDevice ();
1047 break;
1049 default:
1050 // Ignore unknown values
1051 break;
1055 void SdDrawDocument::SetStartWithPresentation( bool bStartWithPresentation )
1057 mbStartWithPresentation = bStartWithPresentation;
1060 void SdDrawDocument::SetExitAfterPresenting( bool bExitAfterPresenting )
1062 mbExitAfterPresenting = bExitAfterPresenting;
1065 void SdDrawDocument::PageListChanged()
1067 mpDrawPageListWatcher->Invalidate();
1070 void SdDrawDocument::MasterPageListChanged()
1072 mpMasterPageListWatcher->Invalidate();
1075 void SdDrawDocument::SetCalcFieldValueHdl(::Outliner* pOutliner)
1077 pOutliner->SetCalcFieldValueHdl(LINK(SD_MOD(), SdModule, CalcFieldValueHdl));
1080 sal_uInt16 SdDrawDocument::GetAnnotationAuthorIndex( const OUString& rAuthor )
1082 // force current user to have first color
1083 if( maAnnotationAuthors.empty() )
1085 SvtUserOptions aUserOptions;
1086 maAnnotationAuthors.push_back( aUserOptions.GetFullName() );
1089 auto iter = std::find(maAnnotationAuthors.begin(), maAnnotationAuthors.end(), rAuthor);
1090 sal_uInt16 idx = static_cast<sal_uInt16>(std::distance(maAnnotationAuthors.begin(), iter));
1092 if( idx == maAnnotationAuthors.size() )
1094 maAnnotationAuthors.push_back( rAuthor );
1097 return idx;
1100 void SdDrawDocument::InitLayoutVector()
1102 if (utl::ConfigManager::IsFuzzing())
1103 return;
1105 const Reference<css::uno::XComponentContext> xContext(
1106 ::comphelper::getProcessComponentContext() );
1108 // get file list from configuration
1109 const Sequence< OUString > aFiles(
1110 officecfg::Office::Impress::Misc::LayoutListFiles::get(xContext) );
1112 OUString sFilename;
1113 for( const auto& rFile : aFiles )
1115 sFilename = comphelper::getExpandedUri(xContext, rFile);
1117 // load layout file into DOM
1118 Reference< XMultiServiceFactory > xServiceFactory(
1119 xContext->getServiceManager() , UNO_QUERY_THROW );
1120 const Reference<XDocumentBuilder> xDocBuilder(
1121 DocumentBuilder::create( comphelper::getComponentContext (xServiceFactory) ));
1125 // loop over every layout entry in current file
1126 const Reference<XDocument> xDoc = xDocBuilder->parseURI( sFilename );
1127 const Reference<XNodeList> layoutlist = xDoc->getElementsByTagName("layout");
1128 const int nElements = layoutlist->getLength();
1129 for(int index=0; index < nElements; index++)
1130 maLayoutInfo.push_back( layoutlist->item(index) );
1132 catch (const uno::Exception &)
1134 // skip missing config. files
1139 void SdDrawDocument::InitObjectVector()
1141 if (utl::ConfigManager::IsFuzzing())
1142 return;
1144 const Reference<css::uno::XComponentContext> xContext(
1145 ::comphelper::getProcessComponentContext() );
1147 // get file list from configuration
1148 const Sequence< OUString > aFiles(
1149 officecfg::Office::Impress::Misc::PresObjListFiles::get(xContext) );
1151 OUString sFilename;
1152 for( const auto& rFile : aFiles )
1154 sFilename = comphelper::getExpandedUri(xContext, rFile);
1156 // load presentation object file into DOM
1157 Reference< XMultiServiceFactory > xServiceFactory(
1158 xContext->getServiceManager() , UNO_QUERY_THROW );
1159 const Reference<XDocumentBuilder> xDocBuilder(
1160 DocumentBuilder::create( comphelper::getComponentContext (xServiceFactory) ));
1164 // loop over every object entry in current file
1165 const Reference<XDocument> xDoc = xDocBuilder->parseURI( sFilename );
1166 const Reference<XNodeList> objectlist = xDoc->getElementsByTagName("object");
1167 const int nElements = objectlist->getLength();
1168 for(int index=0; index < nElements; index++)
1169 maPresObjectInfo.push_back( objectlist->item(index) );
1171 catch (const uno::Exception &)
1173 // skip missing config. files
1178 void SdDrawDocument::dumpAsXml(xmlTextWriterPtr pWriter) const
1180 bool bOwns = false;
1181 if (!pWriter)
1183 pWriter = xmlNewTextWriterFilename("model.xml", 0);
1184 xmlTextWriterSetIndent(pWriter,1);
1185 xmlTextWriterSetIndentString(pWriter, BAD_CAST(" "));
1186 xmlTextWriterStartDocument(pWriter, nullptr, nullptr, nullptr);
1187 bOwns = true;
1189 xmlTextWriterStartElement(pWriter, BAD_CAST("SdDrawDocument"));
1190 xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
1192 if (mpOutliner)
1193 mpOutliner->dumpAsXml(pWriter);
1194 FmFormModel::dumpAsXml(pWriter);
1195 if (GetUndoManager())
1196 GetUndoManager()->dumpAsXml(pWriter);
1198 xmlTextWriterEndElement(pWriter);
1199 if (bOwns)
1201 xmlTextWriterEndDocument(pWriter);
1202 xmlFreeTextWriter(pWriter);
1206 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */