nss: upgrade to release 3.73
[LibreOffice.git] / sd / source / core / drawdoc.cxx
blob69f746150d64fd71a2d1a26bf0f82c982f184ee1
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;
95 using ::com::sun::star::lang::XMultiServiceFactory;
98 SdDrawDocument* SdDrawDocument::s_pDocLockedInsertingLinks = nullptr;
100 PresentationSettings::PresentationSettings()
101 : mbAll( true ),
102 mbEndless( false ),
103 mbCustomShow(false),
104 mbManual( false ),
105 mbMouseVisible( false ),
106 mbMouseAsPen( false ),
107 mbLockedPages( false ),
108 mbAlwaysOnTop( false ),
109 mbFullScreen( true ),
110 mbAnimationAllowed( true ),
111 mnPauseTimeout( 0 ),
112 mbShowPauseLogo( false )
116 SdDrawDocument::SdDrawDocument(DocumentType eType, SfxObjectShell* pDrDocSh)
117 : FmFormModel(
118 nullptr,
119 pDrDocSh)
120 , mpDocSh(static_cast< ::sd::DrawDocShell*>(pDrDocSh))
121 , mpCreatingTransferable( nullptr )
122 , mbHasOnlineSpellErrors(false)
123 , mbInitialOnlineSpellingEnabled(true)
124 , mbNewOrLoadCompleted(false)
125 , mbOnlineSpell(false)
126 , mbStartWithPresentation( false )
127 , mbExitAfterPresenting( false )
128 , meLanguage( LANGUAGE_SYSTEM )
129 , meLanguageCJK( LANGUAGE_SYSTEM )
130 , meLanguageCTL( LANGUAGE_SYSTEM )
131 , mePageNumType(SVX_NUM_ARABIC)
132 , mbAllocDocSh(false)
133 , meDocType(eType)
134 , mbEmbedFonts(false)
135 , mbEmbedUsedFontsOnly(false)
136 , mbEmbedFontScriptLatin(true)
137 , mbEmbedFontScriptAsian(true)
138 , mbEmbedFontScriptComplex(true)
140 mpDrawPageListWatcher.reset(new ImpDrawPageListWatcher(*this));
141 mpMasterPageListWatcher.reset(new ImpMasterPageListWatcher(*this));
143 InitLayoutVector();
144 InitObjectVector();
145 SetObjectShell(pDrDocSh); // for VCDrawModel
147 if (mpDocSh)
149 SetSwapGraphics();
152 // Set measuring unit (of the application) and scale (of SdMod)
153 sal_Int32 nX, nY;
154 SdOptions* pOptions = SD_MOD()->GetSdOptions(meDocType);
155 pOptions->GetScale( nX, nY );
157 // Allow UI scale only for draw documents.
158 if( eType == DocumentType::Draw )
159 SetUIUnit( static_cast<FieldUnit>(pOptions->GetMetric()), Fraction( nX, nY ) ); // user-defined
160 else
161 SetUIUnit( static_cast<FieldUnit>(pOptions->GetMetric()), Fraction( 1, 1 ) ); // default
163 SetScaleUnit(MapUnit::Map100thMM);
164 SetScaleFraction(Fraction(1, 1));
165 SetDefaultFontHeight(847); // 24p
167 m_pItemPool->SetDefaultMetric(MapUnit::Map100thMM);
168 m_pItemPool->FreezeIdRanges();
169 SetTextDefaults();
171 // DrawingEngine has to know where it is...
172 FmFormModel::SetStyleSheetPool( new SdStyleSheetPool( GetPool(), this ) );
174 // Set StyleSheetPool for DrawOutliner, so text objects can be read correctly.
175 // The link to the StyleRequest handler of the document is set later, in
176 // NewOrLoadCompleted, because only then do all the templates exist.
177 SdrOutliner& rOutliner = GetDrawOutliner();
178 rOutliner.SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
179 SetCalcFieldValueHdl( &rOutliner );
181 // set linguistic options
182 if (!utl::ConfigManager::IsFuzzing())
184 const SvtLinguConfig aLinguConfig;
185 SvtLinguOptions aOptions;
186 aLinguConfig.GetOptions( aOptions );
188 SetLanguage( MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage,
189 css::i18n::ScriptType::LATIN), EE_CHAR_LANGUAGE );
190 SetLanguage( MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage_CJK,
191 css::i18n::ScriptType::ASIAN), EE_CHAR_LANGUAGE_CJK );
192 SetLanguage( MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage_CTL,
193 css::i18n::ScriptType::COMPLEX), EE_CHAR_LANGUAGE_CTL );
195 mbOnlineSpell = aOptions.bIsSpellAuto;
198 LanguageType eRealLanguage = MsLangId::getRealLanguage( meLanguage );
199 LanguageTag aLanguageTag( eRealLanguage);
200 mpCharClass.reset(new CharClass( aLanguageTag ));
202 // If the current application language is a language that uses right-to-left text...
203 LanguageType eRealCTLLanguage = Application::GetSettings().GetLanguageTag().getLanguageType();
205 // for korean and japanese languages we have a different default for apply spacing between asian, latin and ctl text
206 if (MsLangId::isKorean(eRealCTLLanguage) || (LANGUAGE_JAPANESE == eRealCTLLanguage))
208 GetPool().GetSecondaryPool()->SetPoolDefaultItem( SvxScriptSpaceItem( false, EE_PARA_ASIANCJKSPACING ) );
211 // Set DefTab and SpellOptions for the SD module
212 sal_uInt16 nDefTab = pOptions->GetDefTab();
213 SetDefaultTabulator( nDefTab );
217 Reference< XSpellChecker1 > xSpellChecker( LinguMgr::GetSpellChecker() );
218 if ( xSpellChecker.is() )
219 rOutliner.SetSpeller( xSpellChecker );
221 Reference< XHyphenator > xHyphenator( LinguMgr::GetHyphenator() );
222 if( xHyphenator.is() )
223 rOutliner.SetHyphenator( xHyphenator );
225 SetForbiddenCharsTable(SvxForbiddenCharactersTable::makeForbiddenCharactersTable(::comphelper::getProcessComponentContext()));
227 catch(...)
229 OSL_FAIL("Can't get SpellChecker");
232 rOutliner.SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
234 if (mpDocSh)
236 SetLinkManager( new sfx2::LinkManager(mpDocSh) );
239 EEControlBits nCntrl = rOutliner.GetControlWord();
240 nCntrl |= EEControlBits::ALLOWBIGOBJS;
242 if (mbOnlineSpell)
243 nCntrl |= EEControlBits::ONLINESPELLING;
244 else
245 nCntrl &= ~EEControlBits::ONLINESPELLING;
247 nCntrl &= ~ EEControlBits::ULSPACESUMMATION;
248 if ( meDocType != DocumentType::Impress )
249 SetSummationOfParagraphs( false );
250 else
252 SetSummationOfParagraphs( pOptions->IsSummationOfParagraphs() );
253 if ( pOptions->IsSummationOfParagraphs() )
254 nCntrl |= EEControlBits::ULSPACESUMMATION;
256 rOutliner.SetControlWord(nCntrl);
258 // Initialize the printer independent layout mode
259 SetPrinterIndependentLayout (pOptions->GetPrinterIndependentLayout());
261 // Set the StyleSheetPool for HitTestOutliner.
262 // The link to the StyleRequest handler of the document is set later, in
263 // NewOrLoadCompleted, because only then do all the templates exist.
264 m_pHitTestOutliner->SetStyleSheetPool( static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()) );
266 SetCalcFieldValueHdl( m_pHitTestOutliner.get() );
270 Reference< XSpellChecker1 > xSpellChecker( LinguMgr::GetSpellChecker() );
271 if ( xSpellChecker.is() )
272 m_pHitTestOutliner->SetSpeller( xSpellChecker );
274 Reference< XHyphenator > xHyphenator( LinguMgr::GetHyphenator() );
275 if( xHyphenator.is() )
276 m_pHitTestOutliner->SetHyphenator( xHyphenator );
278 catch(...)
280 OSL_FAIL("Can't get SpellChecker");
283 m_pHitTestOutliner->SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
285 EEControlBits nCntrl2 = m_pHitTestOutliner->GetControlWord();
286 nCntrl2 |= EEControlBits::ALLOWBIGOBJS;
287 nCntrl2 &= ~EEControlBits::ONLINESPELLING;
289 nCntrl2 &= ~ EEControlBits::ULSPACESUMMATION;
290 if ( pOptions->IsSummationOfParagraphs() )
291 nCntrl2 |= EEControlBits::ULSPACESUMMATION;
293 m_pHitTestOutliner->SetControlWord( nCntrl2 );
295 /** Create layers
297 * We create the following default layers on all pages and master pages:
299 * sUNO_LayerName_layout; "layout": default layer for drawing objects of normal pages
300 * localized by SdResId(STR_LAYER_LAYOUT)
302 * sUNO_LayerName_background; "background": background of the master page
303 * localized by SdResId(STR_LAYER_BCKGRND)
304 * (currently unused within normal pages and not visible to users)
306 * sUNO_LayerName_background_objects; "backgroundobjects": objects on the background of master pages
307 * localized by SdResId(STR_LAYER_BCKGRNDOBJ)
308 * (currently unused within normal pages)
310 * sUNO_LayerName_controls; "controls": default layer for controls
311 * localized by SdResId(STR_LAYER_CONTROLS)
312 * (currently special handling in regard to z-order)
314 * sUNO_LayerName_measurelines; "measurelines" : default layer for measure lines
315 * localized by SdResId(STR_LAYER_MEASURELINES)
319 SdrLayerAdmin& rLayerAdmin = GetLayerAdmin();
320 rLayerAdmin.NewLayer( sUNO_LayerName_layout );
321 rLayerAdmin.NewLayer( sUNO_LayerName_background );
322 rLayerAdmin.NewLayer( sUNO_LayerName_background_objects );
323 rLayerAdmin.NewLayer( sUNO_LayerName_controls);
324 rLayerAdmin.NewLayer( sUNO_LayerName_measurelines );
326 rLayerAdmin.SetControlLayerName(sUNO_LayerName_controls);
331 // Destructor
332 SdDrawDocument::~SdDrawDocument()
334 Broadcast(SdrHint(SdrHintKind::ModelCleared));
336 if (mpWorkStartupTimer)
338 if ( mpWorkStartupTimer->IsActive() )
339 mpWorkStartupTimer->Stop();
341 mpWorkStartupTimer.reset();
344 StopOnlineSpelling();
345 mpOnlineSearchItem.reset();
347 CloseBookmarkDoc();
348 SetAllocDocSh(false);
350 ClearModel(true);
352 if (m_pLinkManager)
354 // Release BaseLinks
355 if ( !m_pLinkManager->GetLinks().empty() )
357 m_pLinkManager->Remove( 0, m_pLinkManager->GetLinks().size() );
360 delete m_pLinkManager;
361 m_pLinkManager = nullptr;
364 maFrameViewList.clear();
365 mpCustomShowList.reset();
366 mpOutliner.reset();
367 mpInternalOutliner.reset();
368 mpCharClass.reset();
371 void SdDrawDocument::adaptSizeAndBorderForAllPages(
372 const Size& rNewSize,
373 ::tools::Long nLeft,
374 ::tools::Long nRight,
375 ::tools::Long nUpper,
376 ::tools::Long nLower)
378 const sal_uInt16 nMasterPageCnt(GetMasterSdPageCount(PageKind::Standard));
379 const sal_uInt16 nPageCnt(GetSdPageCount(PageKind::Standard));
381 if(0 == nMasterPageCnt && 0 == nPageCnt)
383 return;
386 SdPage* pPage(0 != nPageCnt ? GetSdPage(0, PageKind::Standard) : GetMasterSdPage(0, PageKind::Standard));
388 // call fully implemented local version, including getting
389 // some more information from one of the Pages (1st one)
390 AdaptPageSizeForAllPages(
391 rNewSize,
392 PageKind::Standard,
393 nullptr,
394 nLeft,
395 nRight,
396 nUpper,
397 nLower,
398 true,
399 pPage->GetOrientation(),
400 pPage->GetPaperBin(),
401 pPage->IsBackgroundFullSize());
403 // adjust handout page to new format of the standard page
404 if(0 != nPageCnt)
406 GetSdPage(0, PageKind::Handout)->CreateTitleAndLayout(true);
410 void SdDrawDocument::AdaptPageSizeForAllPages(
411 const Size& rNewSize,
412 PageKind ePageKind,
413 SdUndoGroup* pUndoGroup,
414 ::tools::Long nLeft,
415 ::tools::Long nRight,
416 ::tools::Long nUpper,
417 ::tools::Long nLower,
418 bool bScaleAll,
419 Orientation eOrientation,
420 sal_uInt16 nPaperBin,
421 bool bBackgroundFullSize)
423 sal_uInt16 i;
424 const sal_uInt16 nMasterPageCnt(GetMasterSdPageCount(ePageKind));
425 const sal_uInt16 nPageCnt(GetSdPageCount(ePageKind));
427 if(0 == nMasterPageCnt && 0 == nPageCnt)
429 return;
432 for (i = 0; i < nMasterPageCnt; i++)
434 // first, handle all master pages
435 SdPage* pPage(GetMasterSdPage(i, ePageKind));
437 if(pUndoGroup)
439 SdUndoAction* pUndo(
440 new SdPageFormatUndoAction(
441 this,
442 pPage,
443 pPage->GetSize(),
444 pPage->GetLeftBorder(), pPage->GetRightBorder(),
445 pPage->GetUpperBorder(), pPage->GetLowerBorder(),
446 pPage->GetOrientation(),
447 pPage->GetPaperBin(),
448 pPage->IsBackgroundFullSize(),
449 rNewSize,
450 nLeft, nRight,
451 nUpper, nLower,
452 bScaleAll,
453 eOrientation,
454 nPaperBin,
455 bBackgroundFullSize));
456 pUndoGroup->AddAction(pUndo);
459 if (rNewSize.Width() > 0 || nLeft >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0)
461 ::tools::Rectangle aNewBorderRect(nLeft, nUpper, nRight, nLower);
462 pPage->ScaleObjects(rNewSize, aNewBorderRect, bScaleAll);
464 if (rNewSize.Width() > 0)
466 pPage->SetSize(rNewSize);
470 if( nLeft >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0 )
472 pPage->SetBorder(nLeft, nUpper, nRight, nLower);
475 pPage->SetOrientation(eOrientation);
476 pPage->SetPaperBin( nPaperBin );
477 pPage->SetBackgroundFullSize( bBackgroundFullSize );
479 if ( ePageKind == PageKind::Standard )
481 GetMasterSdPage(i, PageKind::Notes)->CreateTitleAndLayout();
484 pPage->CreateTitleAndLayout();
487 for (i = 0; i < nPageCnt; i++)
489 // then, handle all pages
490 SdPage* pPage(GetSdPage(i, ePageKind));
492 if(pUndoGroup)
494 SdUndoAction* pUndo(
495 new SdPageFormatUndoAction(
496 this,
497 pPage,
498 pPage->GetSize(),
499 pPage->GetLeftBorder(), pPage->GetRightBorder(),
500 pPage->GetUpperBorder(), pPage->GetLowerBorder(),
501 pPage->GetOrientation(),
502 pPage->GetPaperBin(),
503 pPage->IsBackgroundFullSize(),
504 rNewSize,
505 nLeft, nRight,
506 nUpper, nLower,
507 bScaleAll,
508 eOrientation,
509 nPaperBin,
510 bBackgroundFullSize));
511 pUndoGroup->AddAction(pUndo);
514 if (rNewSize.Width() > 0 || nLeft >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0)
516 ::tools::Rectangle aNewBorderRect(nLeft, nUpper, nRight, nLower);
517 pPage->ScaleObjects(rNewSize, aNewBorderRect, bScaleAll);
519 if (rNewSize.Width() > 0)
521 pPage->SetSize(rNewSize);
525 if( nLeft >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0 )
527 pPage->SetBorder(nLeft, nUpper, nRight, nLower);
530 pPage->SetOrientation(eOrientation);
531 pPage->SetPaperBin( nPaperBin );
532 pPage->SetBackgroundFullSize( bBackgroundFullSize );
534 if ( ePageKind == PageKind::Standard )
536 SdPage* pNotesPage = GetSdPage(i, PageKind::Notes);
537 pNotesPage->SetAutoLayout( pNotesPage->GetAutoLayout() );
540 pPage->SetAutoLayout( pPage->GetAutoLayout() );
544 SdrModel* SdDrawDocument::AllocModel() const
546 return AllocSdDrawDocument();
549 namespace
552 /// Copies all user-defined properties from pSource to pDestination.
553 void lcl_copyUserDefinedProperties(const SfxObjectShell* pSource, const SfxObjectShell* pDestination)
555 if (!pSource || !pDestination)
556 return;
558 uno::Reference<document::XDocumentProperties> xSource = pSource->getDocProperties();
559 uno::Reference<document::XDocumentProperties> xDestination = pDestination->getDocProperties();
560 uno::Reference<beans::XPropertyContainer> xSourcePropertyContainer = xSource->getUserDefinedProperties();
561 uno::Reference<beans::XPropertyContainer> xDestinationPropertyContainer = xDestination->getUserDefinedProperties();
562 uno::Reference<beans::XPropertySet> xSourcePropertySet(xSourcePropertyContainer, uno::UNO_QUERY);
563 const uno::Sequence<beans::Property> aProperties = xSourcePropertySet->getPropertySetInfo()->getProperties();
565 for (const beans::Property& rProperty : aProperties)
567 const OUString& rKey = rProperty.Name;
568 uno::Any aValue = xSourcePropertySet->getPropertyValue(rKey);
569 // We know that pDestination was just created, so has no properties: addProperty() will never throw.
570 xDestinationPropertyContainer->addProperty(rKey, beans::PropertyAttribute::REMOVABLE, aValue);
576 // This method creates a new document (SdDrawDocument) and returns a pointer to
577 // said document. The drawing engine uses this method to put the document (or
578 // parts of it) into the clipboard/DragServer.
579 SdDrawDocument* SdDrawDocument::AllocSdDrawDocument() const
581 SdDrawDocument* pNewModel = nullptr;
583 if( mpCreatingTransferable )
585 // Document is created for drag & drop/clipboard. To be able to
586 // do this, the document has to know a DocShell (SvPersist).
587 SfxObjectShell* pObj = nullptr;
588 ::sd::DrawDocShell* pNewDocSh = nullptr;
590 if( meDocType == DocumentType::Impress )
591 mpCreatingTransferable->SetDocShell( new ::sd::DrawDocShell(
592 SfxObjectCreateMode::EMBEDDED, true, meDocType ) );
593 else
594 mpCreatingTransferable->SetDocShell( new ::sd::GraphicDocShell(
595 SfxObjectCreateMode::EMBEDDED ) );
597 pObj = mpCreatingTransferable->GetDocShell().get();
598 pNewDocSh = static_cast< ::sd::DrawDocShell*>( pObj );
599 pNewDocSh->DoInitNew();
600 pNewModel = pNewDocSh->GetDoc();
602 // Only necessary for clipboard -
603 // for drag & drop this is handled by DragServer
604 SdStyleSheetPool* pOldStylePool = static_cast<SdStyleSheetPool*>( GetStyleSheetPool() );
605 SdStyleSheetPool* pNewStylePool = static_cast<SdStyleSheetPool*>( pNewModel->GetStyleSheetPool() );
607 pNewStylePool->CopyGraphicSheets(*pOldStylePool);
608 pNewStylePool->CopyCellSheets(*pOldStylePool);
609 pNewStylePool->CopyTableStyles(*pOldStylePool);
611 for (sal_uInt16 i = 0; i < GetMasterSdPageCount(PageKind::Standard); i++)
613 // Move with all of the master page's layouts
614 OUString aOldLayoutName(const_cast<SdDrawDocument*>(this)->GetMasterSdPage(i, PageKind::Standard)->GetLayoutName());
615 aOldLayoutName = aOldLayoutName.copy( 0, aOldLayoutName.indexOf( SD_LT_SEPARATOR ) );
616 StyleSheetCopyResultVector aCreatedSheets;
617 pNewStylePool->CopyLayoutSheets(aOldLayoutName, *pOldStylePool, aCreatedSheets );
620 lcl_copyUserDefinedProperties(GetDocSh(), pNewDocSh);
622 pNewModel->NewOrLoadCompleted( DocCreationMode::Loaded ); // loaded from source document
624 else if( mbAllocDocSh )
626 // Create a DocShell which is then returned with GetAllocedDocSh()
627 SdDrawDocument* pDoc = const_cast<SdDrawDocument*>(this);
628 pDoc->SetAllocDocSh(false);
629 pDoc->mxAllocedDocShRef = new ::sd::DrawDocShell(
630 SfxObjectCreateMode::EMBEDDED, true, meDocType);
631 pDoc->mxAllocedDocShRef->DoInitNew();
632 pNewModel = pDoc->mxAllocedDocShRef->GetDoc();
634 else
636 pNewModel = new SdDrawDocument(meDocType, nullptr);
639 return pNewModel;
642 SdPage* SdDrawDocument::AllocSdPage(bool bMasterPage)
644 return new SdPage(*this, bMasterPage);
647 // This method creates a new page (SdPage) and returns a pointer to said page.
648 // The drawing engine uses this method to create pages (whose types it does
649 // not know, as they are _derivatives_ of SdrPage) when loading.
650 SdrPage* SdDrawDocument::AllocPage(bool bMasterPage)
652 return AllocSdPage(bMasterPage);
655 // When the model has changed
656 void SdDrawDocument::SetChanged(bool bFlag)
658 if (mpDocSh)
660 if (mbNewOrLoadCompleted && mpDocSh->IsEnableSetModified())
662 // Pass on to base class
663 FmFormModel::SetChanged(bFlag);
665 // Forward to ObjectShell
666 mpDocSh->SetModified(bFlag);
669 else
671 // Pass on to base class
672 FmFormModel::SetChanged(bFlag);
676 // The model changed, don't call anything else
677 void SdDrawDocument::NbcSetChanged(bool bFlag)
679 // forward to baseclass
680 FmFormModel::SetChanged(bFlag);
683 // NewOrLoadCompleted is called when the document is loaded, or when it is clear
684 // it won't load any more.
685 void SdDrawDocument::NewOrLoadCompleted(DocCreationMode eMode)
687 if (eMode == DocCreationMode::New)
689 // New document:
690 // create slideshow and default templates,
691 // create pool for virtual controls
692 CreateLayoutTemplates();
693 CreateDefaultCellStyles();
695 static_cast< SdStyleSheetPool* >( mxStyleSheetPool.get() )->CreatePseudosIfNecessary();
697 else if (eMode == DocCreationMode::Loaded)
699 // Document has finished loading
701 CheckMasterPages();
703 if ( GetMasterSdPageCount(PageKind::Standard) > 1 )
704 RemoveUnnecessaryMasterPages( nullptr, true, false );
706 for ( sal_uInt16 i = 0; i < GetPageCount(); i++ )
708 // Check for correct layout names
709 SdPage* pPage = static_cast<SdPage*>( GetPage( i ) );
711 if(pPage->TRG_HasMasterPage())
713 SdPage& rMaster = static_cast<SdPage&>(pPage->TRG_GetMasterPage() );
715 if(rMaster.GetLayoutName() != pPage->GetLayoutName())
717 pPage->SetLayoutName(rMaster.GetLayoutName());
722 for ( sal_uInt16 nPage = 0; nPage < GetMasterPageCount(); nPage++)
724 // LayoutName and PageName must be the same
725 SdPage* pPage = static_cast<SdPage*>( GetMasterPage( nPage ) );
727 OUString aName( pPage->GetLayoutName() );
728 aName = aName.copy( 0, aName.indexOf( SD_LT_SEPARATOR ) );
730 if( aName != pPage->GetName() )
731 pPage->SetName( aName );
734 // Create names of the styles in the user's language
735 static_cast<SdStyleSheetPool*>(mxStyleSheetPool.get())->UpdateStdNames();
737 // Create any missing styles - eg. formerly, there was no Subtitle style
738 static_cast<SdStyleSheetPool*>(mxStyleSheetPool.get())->CreatePseudosIfNecessary();
741 // Set default style of Drawing Engine
742 OUString aName( SdResId(STR_STANDARD_STYLESHEET_NAME));
743 SetDefaultStyleSheet(static_cast<SfxStyleSheet*>(mxStyleSheetPool->Find(aName, SfxStyleFamily::Para)));
745 // #i119287# Set default StyleSheet for SdrGrafObj and SdrOle2Obj
746 SetDefaultStyleSheetForSdrGrafObjAndSdrOle2Obj(static_cast<SfxStyleSheet*>(mxStyleSheetPool->Find(SdResId(STR_POOLSHEET_OBJNOLINENOFILL), SfxStyleFamily::Para)));
748 // Initialize DrawOutliner and DocumentOutliner, but don't initialize the
749 // global outliner, as it is not document specific like StyleSheetPool and
750 // StyleRequestHandler are.
751 ::Outliner& rDrawOutliner = GetDrawOutliner();
752 rDrawOutliner.SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
753 EEControlBits nCntrl = rDrawOutliner.GetControlWord();
754 if (mbOnlineSpell)
755 nCntrl |= EEControlBits::ONLINESPELLING;
756 else
757 nCntrl &= ~EEControlBits::ONLINESPELLING;
758 rDrawOutliner.SetControlWord(nCntrl);
760 // Initialize HitTestOutliner and DocumentOutliner, but don't initialize the
761 // global outliner, as it is not document specific like StyleSheetPool and
762 // StyleRequestHandler are.
763 m_pHitTestOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
765 if(mpOutliner)
767 mpOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
769 if(mpInternalOutliner)
771 mpInternalOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
774 if ( eMode == DocCreationMode::Loaded )
776 // Make presentation objects listeners of the appropriate styles
777 SdStyleSheetPool* pSPool = static_cast<SdStyleSheetPool*>( GetStyleSheetPool() );
778 sal_uInt16 nPage, nPageCount;
780 // create missing layout style sheets for broken documents
781 // that were created with the 5.2
782 nPageCount = GetMasterSdPageCount( PageKind::Standard );
783 for (nPage = 0; nPage < nPageCount; nPage++)
785 SdPage* pPage = GetMasterSdPage(nPage, PageKind::Standard);
786 pSPool->CreateLayoutStyleSheets( pPage->GetName(), true );
789 // Default and notes pages:
790 for (nPage = 0; nPage < GetPageCount(); nPage++)
792 SdPage* pPage = static_cast<SdPage*>(GetPage(nPage));
793 NewOrLoadCompleted( pPage, pSPool );
796 // Master pages:
797 for (nPage = 0; nPage < GetMasterPageCount(); nPage++)
799 SdPage* pPage = static_cast<SdPage*>(GetMasterPage(nPage));
801 NewOrLoadCompleted( pPage, pSPool );
805 mbNewOrLoadCompleted = true;
806 UpdateAllLinks();
807 SetChanged( false );
810 /** updates all links, only links in this document should by resolved */
811 void SdDrawDocument::UpdateAllLinks()
813 if (s_pDocLockedInsertingLinks || !m_pLinkManager || m_pLinkManager->GetLinks().empty())
814 return;
816 s_pDocLockedInsertingLinks = this; // lock inserting links. only links in this document should by resolved
818 if (mpDocSh)
820 comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = mpDocSh->getEmbeddedObjectContainer();
821 rEmbeddedObjectContainer.setUserAllowsLinkUpdate(true);
824 m_pLinkManager->UpdateAllLinks(true, false, nullptr); // query box: update all links?
826 if (s_pDocLockedInsertingLinks == this)
827 s_pDocLockedInsertingLinks = nullptr; // unlock inserting links
830 /** this loops over the presentation objects of a page and repairs some new settings
831 from old binary files and resets all default strings for empty presentation objects.
833 void SdDrawDocument::NewOrLoadCompleted( SdPage* pPage, SdStyleSheetPool* pSPool )
835 sd::ShapeList& rPresentationShapes( pPage->GetPresentationShapeList() );
836 if(rPresentationShapes.isEmpty())
837 return;
839 // Create lists of title and outline styles
840 OUString aName = pPage->GetLayoutName();
841 aName = aName.copy( 0, aName.indexOf( SD_LT_SEPARATOR ) );
843 std::vector<SfxStyleSheetBase*> aOutlineList;
844 pSPool->CreateOutlineSheetList(aName,aOutlineList);
846 SfxStyleSheet* pTitleSheet = static_cast<SfxStyleSheet*>(pSPool->GetTitleSheet(aName));
848 SdrObject* pObj = nullptr;
849 rPresentationShapes.seekShape(0);
851 // Now look for title and outline text objects, then make those objects
852 // listeners.
853 while( (pObj = rPresentationShapes.getNextShape()) )
855 if (pObj->GetObjInventor() == SdrInventor::Default)
857 OutlinerParaObject* pOPO = pObj->GetOutlinerParaObject();
858 sal_uInt16 nId = pObj->GetObjIdentifier();
860 if (nId == OBJ_TITLETEXT)
862 if( pOPO && pOPO->GetOutlinerMode() == OutlinerMode::DontKnow )
863 pOPO->SetOutlinerMode( OutlinerMode::TitleObject );
865 // sal_True: don't delete "hard" attributes when doing this.
866 if (pTitleSheet)
867 pObj->SetStyleSheet(pTitleSheet, true);
869 else if (nId == OBJ_OUTLINETEXT)
871 if( pOPO && pOPO->GetOutlinerMode() == OutlinerMode::DontKnow )
872 pOPO->SetOutlinerMode( OutlinerMode::OutlineObject );
874 std::vector<SfxStyleSheetBase*>::iterator iter;
875 for (iter = aOutlineList.begin(); iter != aOutlineList.end(); ++iter)
877 SfxStyleSheet* pSheet = static_cast<SfxStyleSheet*>(*iter);
879 if (pSheet)
881 pObj->StartListening(*pSheet);
883 if( iter == aOutlineList.begin())
884 // text frame listens to stylesheet of layer 1
885 pObj->NbcSetStyleSheet(pSheet, true);
890 if( dynamic_cast< const SdrTextObj *>( pObj ) != nullptr && pObj->IsEmptyPresObj())
892 PresObjKind ePresObjKind = pPage->GetPresObjKind(pObj);
893 OUString aString( pPage->GetPresObjText(ePresObjKind) );
895 if (!aString.isEmpty())
897 SdOutliner* pInternalOutl = GetInternalOutliner();
898 pPage->SetObjText( static_cast<SdrTextObj*>(pObj), pInternalOutl, ePresObjKind, aString );
899 pObj->NbcSetStyleSheet( pPage->GetStyleSheetForPresObj( ePresObjKind ), true );
900 pInternalOutl->Clear();
907 // Local outliner that is used for outline mode. In this outliner, OutlinerViews
908 // may be inserted.
909 SdOutliner* SdDrawDocument::GetOutliner(bool bCreateOutliner)
911 if (!mpOutliner && bCreateOutliner)
913 mpOutliner.reset(new SdOutliner( this, OutlinerMode::TextObject ));
915 if (mpDocSh)
916 mpOutliner->SetRefDevice( SD_MOD()->GetVirtualRefDevice() );
918 mpOutliner->SetDefTab( m_nDefaultTabulator );
919 mpOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
922 return mpOutliner.get();
925 // Internal outliner that is used to create text objects. We don't insert any
926 // OutlinerViews into this outliner!
927 SdOutliner* SdDrawDocument::GetInternalOutliner(bool bCreateOutliner)
929 if ( !mpInternalOutliner && bCreateOutliner )
931 mpInternalOutliner.reset( new SdOutliner( this, OutlinerMode::TextObject ) );
933 // This outliner is only used to create special text objects. As no
934 // information about portions is saved in this outliner, the update mode
935 // can/should always remain sal_False.
936 mpInternalOutliner->SetUpdateMode( false );
937 mpInternalOutliner->EnableUndo( false );
939 if (mpDocSh)
940 mpInternalOutliner->SetRefDevice( SD_MOD()->GetVirtualRefDevice() );
942 mpInternalOutliner->SetDefTab( m_nDefaultTabulator );
943 mpInternalOutliner->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>(GetStyleSheetPool()));
946 DBG_ASSERT( !mpInternalOutliner || ( ! mpInternalOutliner->GetUpdateMode() ) , "InternalOutliner: UpdateMode = sal_True !" );
947 DBG_ASSERT( !mpInternalOutliner || ( ! mpInternalOutliner->IsUndoEnabled() ), "InternalOutliner: Undo = sal_True !" );
949 // If you add stuff here, always clear it out.
950 // Advantages:
951 // a) no unnecessary Clear calls
952 // b) no wasted memory
953 DBG_ASSERT( !mpInternalOutliner || ( ( mpInternalOutliner->GetParagraphCount() == 1 ) && ( mpInternalOutliner->GetText( mpInternalOutliner->GetParagraph( 0 ) ).isEmpty() ) ), "InternalOutliner: not empty!" );
955 return mpInternalOutliner.get();
958 // OnlineSpelling on/off
959 void SdDrawDocument::SetOnlineSpell(bool bIn)
961 mbOnlineSpell = bIn;
962 EEControlBits nCntrl;
964 if(mpOutliner)
966 nCntrl = mpOutliner->GetControlWord();
968 if(mbOnlineSpell)
969 nCntrl |= EEControlBits::ONLINESPELLING;
970 else
971 nCntrl &= ~EEControlBits::ONLINESPELLING;
973 mpOutliner->SetControlWord(nCntrl);
976 if (mpInternalOutliner)
978 nCntrl = mpInternalOutliner->GetControlWord();
980 if (mbOnlineSpell)
981 nCntrl |= EEControlBits::ONLINESPELLING;
982 else
983 nCntrl &= ~EEControlBits::ONLINESPELLING;
985 mpInternalOutliner->SetControlWord(nCntrl);
988 ::Outliner& rOutliner = GetDrawOutliner();
990 nCntrl = rOutliner.GetControlWord();
992 if (mbOnlineSpell)
993 nCntrl |= EEControlBits::ONLINESPELLING;
994 else
995 nCntrl &= ~EEControlBits::ONLINESPELLING;
997 rOutliner.SetControlWord(nCntrl);
999 if (mbOnlineSpell)
1001 StartOnlineSpelling();
1003 else
1005 StopOnlineSpelling();
1009 // OnlineSpelling: highlighting on/off
1010 uno::Reference< uno::XInterface > SdDrawDocument::createUnoModel()
1012 uno::Reference< uno::XInterface > xModel;
1016 if ( mpDocSh )
1017 xModel = mpDocSh->GetModel();
1019 catch( uno::RuntimeException& )
1023 return xModel;
1026 SvxNumType SdDrawDocument::GetPageNumType() const
1028 return mePageNumType;
1031 void SdDrawDocument::SetPrinterIndependentLayout (sal_Int32 nMode)
1033 switch (nMode)
1035 case css::document::PrinterIndependentLayout::DISABLED:
1036 case css::document::PrinterIndependentLayout::ENABLED:
1037 // Just store supported modes and inform the doc shell
1038 mnPrinterIndependentLayout = nMode;
1040 // Since it is possible that a SdDrawDocument is constructed without a
1041 // SdDrawDocShell the pointer member mpDocSh needs to be tested
1042 // before the call is executed. This is e. g. used for copy/paste.
1043 if(mpDocSh)
1045 mpDocSh->UpdateRefDevice ();
1048 break;
1050 default:
1051 // Ignore unknown values
1052 break;
1056 void SdDrawDocument::SetStartWithPresentation( bool bStartWithPresentation )
1058 mbStartWithPresentation = bStartWithPresentation;
1061 void SdDrawDocument::SetExitAfterPresenting( bool bExitAfterPresenting )
1063 mbExitAfterPresenting = bExitAfterPresenting;
1066 void SdDrawDocument::PageListChanged()
1068 mpDrawPageListWatcher->Invalidate();
1071 void SdDrawDocument::MasterPageListChanged()
1073 mpMasterPageListWatcher->Invalidate();
1076 void SdDrawDocument::SetCalcFieldValueHdl(::Outliner* pOutliner)
1078 pOutliner->SetCalcFieldValueHdl(LINK(SD_MOD(), SdModule, CalcFieldValueHdl));
1081 sal_uInt16 SdDrawDocument::GetAnnotationAuthorIndex( const OUString& rAuthor )
1083 // force current user to have first color
1084 if( maAnnotationAuthors.empty() )
1086 SvtUserOptions aUserOptions;
1087 maAnnotationAuthors.push_back( aUserOptions.GetFullName() );
1090 auto iter = std::find(maAnnotationAuthors.begin(), maAnnotationAuthors.end(), rAuthor);
1091 sal_uInt16 idx = static_cast<sal_uInt16>(std::distance(maAnnotationAuthors.begin(), iter));
1093 if( idx == maAnnotationAuthors.size() )
1095 maAnnotationAuthors.push_back( rAuthor );
1098 return idx;
1101 void SdDrawDocument::InitLayoutVector()
1103 if (utl::ConfigManager::IsFuzzing())
1104 return;
1106 const Reference<css::uno::XComponentContext> xContext(
1107 ::comphelper::getProcessComponentContext() );
1109 // get file list from configuration
1110 const Sequence< OUString > aFiles(
1111 officecfg::Office::Impress::Misc::LayoutListFiles::get(xContext) );
1113 OUString sFilename;
1114 for( const auto& rFile : aFiles )
1116 sFilename = comphelper::getExpandedUri(xContext, rFile);
1118 // load layout file into DOM
1119 Reference< XMultiServiceFactory > xServiceFactory(
1120 xContext->getServiceManager() , UNO_QUERY_THROW );
1121 const Reference<XDocumentBuilder> xDocBuilder(
1122 DocumentBuilder::create( comphelper::getComponentContext (xServiceFactory) ));
1126 // loop over every layout entry in current file
1127 const Reference<XDocument> xDoc = xDocBuilder->parseURI( sFilename );
1128 const Reference<XNodeList> layoutlist = xDoc->getElementsByTagName("layout");
1129 const int nElements = layoutlist->getLength();
1130 for(int index=0; index < nElements; index++)
1131 maLayoutInfo.push_back( layoutlist->item(index) );
1133 catch (const uno::Exception &)
1135 // skip missing config. files
1140 void SdDrawDocument::InitObjectVector()
1142 if (utl::ConfigManager::IsFuzzing())
1143 return;
1145 const Reference<css::uno::XComponentContext> xContext(
1146 ::comphelper::getProcessComponentContext() );
1148 // get file list from configuration
1149 const Sequence< OUString > aFiles(
1150 officecfg::Office::Impress::Misc::PresObjListFiles::get(xContext) );
1152 OUString sFilename;
1153 for( const auto& rFile : aFiles )
1155 sFilename = comphelper::getExpandedUri(xContext, rFile);
1157 // load presentation object file into DOM
1158 Reference< XMultiServiceFactory > xServiceFactory(
1159 xContext->getServiceManager() , UNO_QUERY_THROW );
1160 const Reference<XDocumentBuilder> xDocBuilder(
1161 DocumentBuilder::create( comphelper::getComponentContext (xServiceFactory) ));
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 xmlTextWriterSetIndentString(pWriter, BAD_CAST(" "));
1187 xmlTextWriterStartDocument(pWriter, nullptr, nullptr, nullptr);
1188 bOwns = true;
1190 xmlTextWriterStartElement(pWriter, BAD_CAST("SdDrawDocument"));
1191 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 xmlTextWriterEndElement(pWriter);
1200 if (bOwns)
1202 xmlTextWriterEndDocument(pWriter);
1203 xmlFreeTextWriter(pWriter);
1207 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */