nss: upgrade to release 3.73
[LibreOffice.git] / sd / source / core / sdpage2.cxx
blob142b40a6bb25c961aea0c39f225e6334623aae22
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 <vector>
21 #include <libxml/xmlwriter.h>
22 #include <sfx2/docfile.hxx>
23 #include <sfx2/linkmgr.hxx>
24 #include <svx/svdundo.hxx>
25 #include <editeng/outlobj.hxx>
26 #include <editeng/xmlcnitm.hxx>
27 #include <svx/svditer.hxx>
28 #include <com/sun/star/text/XTextCopy.hpp>
29 #include <tools/debug.hxx>
30 #include <svx/svddef.hxx>
31 #include <rtl/math.hxx>
32 #include <svx/svdograf.hxx>
34 #include <Annotation.hxx>
35 #include <notifydocumentevent.hxx>
36 #include <sdresid.hxx>
37 #include <sdpage.hxx>
38 #include <glob.hxx>
39 #include <strings.hrc>
40 #include <drawdoc.hxx>
41 #include <stlpool.hxx>
42 #include <pglink.hxx>
44 #include <strings.hxx>
45 #include <DrawDocShell.hxx>
47 #include <svl/itemset.hxx>
49 using namespace ::sd;
50 using namespace ::com::sun::star;
51 using namespace ::com::sun::star::uno;
52 using namespace ::com::sun::star::office;
54 /*************************************************************************
56 |* Sets: names of layout, master page links and templates for presentation
57 |* objects
59 |* Preconditions: - The page has to know the correct model!
60 |* - The corresponding master page has to be in the model.
61 |* - The corresponding style sheets have to be in the style sheet
62 |* pool.
64 |* bReplaceStyleSheets = sal_True : Named style sheets are replaced
65 |* sal_False: All style sheets are reassigned
67 |* bSetMasterPage = sal_True : search and assign master page
69 |* bReverseOrder = sal_False: search master page from head to tail
70 |* sal_True : search master page from tail to head
71 |* (for undo operations)
73 \************************************************************************/
75 void SdPage::SetPresentationLayout(const OUString& rLayoutName,
76 bool bReplaceStyleSheets,
77 bool bSetMasterPage,
78 bool bReverseOrder)
80 /*********************************************************************
81 |* Name of the layout of the page
82 \********************************************************************/
83 OUString aOldLayoutName(maLayoutName); // memorize
84 maLayoutName = rLayoutName + SD_LT_SEPARATOR STR_LAYOUT_OUTLINE;
86 /*********************************************************************
87 |* search and replace master page if necessary
88 \********************************************************************/
89 if (bSetMasterPage && !IsMasterPage())
91 SdPage* pMaster;
92 SdPage* pFoundMaster = nullptr;
93 sal_uInt16 nMaster = 0;
94 sal_uInt16 nMasterCount = getSdrModelFromSdrPage().GetMasterPageCount();
96 if( !bReverseOrder )
98 for ( nMaster = 0; nMaster < nMasterCount; nMaster++ )
100 pMaster = static_cast<SdPage*>(getSdrModelFromSdrPage().GetMasterPage(nMaster));
101 if (pMaster->GetPageKind() == mePageKind && pMaster->GetLayoutName() == maLayoutName)
103 pFoundMaster = pMaster;
104 break;
108 else
110 for ( nMaster = nMasterCount; nMaster > 0; nMaster-- )
112 pMaster = static_cast<SdPage*>(getSdrModelFromSdrPage().GetMasterPage(nMaster - 1));
113 if (pMaster->GetPageKind() == mePageKind && pMaster->GetLayoutName() == maLayoutName)
115 pFoundMaster = pMaster;
116 break;
121 DBG_ASSERT(pFoundMaster, "Masterpage for presentation layout not found!");
123 // this should never happen, but we play failsafe here
124 if( pFoundMaster == nullptr )
125 pFoundMaster = static_cast< SdDrawDocument& >(getSdrModelFromSdrPage()).GetSdPage( 0, mePageKind );
127 if( pFoundMaster )
128 TRG_SetMasterPage(*pFoundMaster);
131 /*********************************************************************
132 |* templates for presentation objects
133 \********************************************************************/
134 // list with:
135 // - pointer to templates for outline text object (old and new templates)
136 // - replace-data for OutlinerParaObject
137 std::vector<SfxStyleSheetBase*> aOutlineStyles;
138 std::vector<SfxStyleSheetBase*> aOldOutlineStyles;
139 std::vector<StyleReplaceData> aReplList;
140 bool bListsFilled = false;
142 const size_t nObjCount = GetObjCount();
144 for (size_t nObj = 0; nObj < nObjCount; ++nObj)
146 auto pObj = GetObj(nObj);
148 if (pObj->GetObjInventor() == SdrInventor::Default &&
149 pObj->GetObjIdentifier() == OBJ_OUTLINETEXT)
151 if (!bListsFilled || !bReplaceStyleSheets)
153 OUString aFullName;
154 OUString aOldFullName;
155 SfxStyleSheetBase* pSheet = nullptr;
156 SfxStyleSheetBasePool* pStShPool = getSdrModelFromSdrPage().GetStyleSheetPool();
158 for (sal_Int16 i = -1; i < 9; i++)
160 aOldFullName = aOldLayoutName + " " +
161 OUString::number( (i <= 0 ) ? 1 : i + 1 );
162 aFullName = maLayoutName + " " +
163 OUString::number( (i <= 0 ) ? 1 : i + 1);
164 pSheet = pStShPool->Find(aOldFullName, SfxStyleFamily::Page);
165 DBG_ASSERT(pSheet, "Old outline style sheet not found");
166 aOldOutlineStyles.push_back(pSheet);
168 pSheet = pStShPool->Find(aFullName, SfxStyleFamily::Page);
169 DBG_ASSERT(pSheet, "New outline style sheet not found");
170 aOutlineStyles.push_back(pSheet);
172 if (bReplaceStyleSheets && pSheet)
174 // Replace instead Set
175 StyleReplaceData aReplData;
176 aReplData.nNewFamily = pSheet->GetFamily();
177 aReplData.nFamily = pSheet->GetFamily();
178 aReplData.aNewName = aFullName;
179 aReplData.aName = aOldFullName;
180 aReplList.push_back(aReplData);
182 else
184 OutlinerParaObject* pOPO = pObj->GetOutlinerParaObject();
186 if( pOPO )
187 pOPO->SetStyleSheets( i, aFullName, SfxStyleFamily::Page );
191 bListsFilled = true;
195 std::vector<SfxStyleSheetBase*>::iterator iterOldOut = aOldOutlineStyles.begin();
197 for (const auto& rpOut : aOutlineStyles)
199 SfxStyleSheet* pSheet = static_cast<SfxStyleSheet*>(rpOut);
200 SfxStyleSheet* pOldSheet = static_cast<SfxStyleSheet*>(*iterOldOut);
202 if (pSheet != pOldSheet)
204 if (pOldSheet)
205 pObj->EndListening(*pOldSheet);
207 if (pSheet && !pObj->IsListening(*pSheet))
208 pObj->StartListening(*pSheet);
211 ++iterOldOut;
214 OutlinerParaObject* pOPO = pObj->GetOutlinerParaObject();
215 if ( bReplaceStyleSheets && pOPO )
217 for (const auto& rRepl : aReplList)
219 pOPO->ChangeStyleSheets( rRepl.aName, rRepl.nFamily, rRepl.aNewName, rRepl.nNewFamily );
223 else if (pObj->GetObjInventor() == SdrInventor::Default &&
224 pObj->GetObjIdentifier() == OBJ_TITLETEXT)
226 // We do not get PresObjKind via GetPresObjKind() since there are
227 // only PresObjListe considered. But we want to consider all "Title
228 // objects" here (paste from clipboard etc.)
229 SfxStyleSheet* pSheet = GetStyleSheetForPresObj(PresObjKind::Title);
231 if (pSheet)
232 pObj->SetStyleSheet(pSheet, true);
234 else
236 SfxStyleSheet* pSheet = GetStyleSheetForPresObj(GetPresObjKind(pObj));
238 if (pSheet)
239 pObj->SetStyleSheet(pSheet, true);
244 /*************************************************************************
246 |* disconnect outline text object from templates for outline levels
248 \************************************************************************/
250 void SdPage::EndListenOutlineText()
252 SdrObject* pOutlineTextObj = GetPresObj(PresObjKind::Outline);
254 if (!pOutlineTextObj)
255 return;
257 SdStyleSheetPool* pSPool = static_cast<SdStyleSheetPool*>(getSdrModelFromSdrPage().GetStyleSheetPool());
258 DBG_ASSERT(pSPool, "StyleSheetPool missing");
259 OUString aTrueLayoutName(maLayoutName);
260 sal_Int32 nIndex = aTrueLayoutName.indexOf( SD_LT_SEPARATOR );
261 if( nIndex != -1 )
262 aTrueLayoutName = aTrueLayoutName.copy(0, nIndex);
264 std::vector<SfxStyleSheetBase*> aOutlineStyles;
265 pSPool->CreateOutlineSheetList(aTrueLayoutName,aOutlineStyles);
267 for (const auto& rpStyle : aOutlineStyles)
269 SfxStyleSheet *pSheet = static_cast<SfxStyleSheet*>(rpStyle);
270 pOutlineTextObj->EndListening(*pSheet);
274 /*************************************************************************
276 |* Is this page read-only?
278 \************************************************************************/
280 bool SdPage::IsReadOnly() const
282 return false;
285 /*************************************************************************
287 |* Connect to sfx2::LinkManager
289 \************************************************************************/
291 void SdPage::ConnectLink()
293 sfx2::LinkManager* pLinkManager(getSdrModelFromSdrPage().GetLinkManager());
295 if (!(pLinkManager && !mpPageLink && !maFileName.isEmpty() && !maBookmarkName.isEmpty() &&
296 mePageKind==PageKind::Standard && !IsMasterPage() &&
297 static_cast< SdDrawDocument& >(getSdrModelFromSdrPage()).IsNewOrLoadCompleted()))
298 return;
300 /**********************************************************************
301 * Connect
302 * Only standard pages are allowed to be linked
303 **********************************************************************/
304 ::sd::DrawDocShell* pDocSh = static_cast< SdDrawDocument& >(getSdrModelFromSdrPage()).GetDocSh();
306 if (!pDocSh || pDocSh->GetMedium()->GetOrigURL() != maFileName)
308 // No links to document owned pages!
309 mpPageLink = new SdPageLink(this, maFileName, maBookmarkName);
310 OUString aFilterName(SdResId(STR_IMPRESS));
311 pLinkManager->InsertFileLink(*mpPageLink, sfx2::SvBaseLinkObjectType::ClientFile,
312 maFileName, &aFilterName, &maBookmarkName);
313 mpPageLink->Connect();
317 /*************************************************************************
319 |* Disconnect from sfx2::LinkManager
321 \************************************************************************/
323 void SdPage::DisconnectLink()
325 sfx2::LinkManager* pLinkManager(getSdrModelFromSdrPage().GetLinkManager());
327 if (pLinkManager && mpPageLink)
329 /**********************************************************************
330 * Disconnect
331 * (remove deletes *pGraphicLink implicit)
332 **********************************************************************/
333 pLinkManager->Remove(mpPageLink);
334 mpPageLink=nullptr;
338 void SdPage::lateInit(const SdPage& rSrcPage)
340 // call parent
341 FmFormPage::lateInit(rSrcPage);
343 // copy local variables (former stuff from copy constructor)
344 mePageKind = rSrcPage.mePageKind;
345 meAutoLayout = rSrcPage.meAutoLayout;
346 mbSelected = false;
347 mnTransitionType = rSrcPage.mnTransitionType;
348 mnTransitionSubtype = rSrcPage.mnTransitionSubtype;
349 mbTransitionDirection = rSrcPage.mbTransitionDirection;
350 mnTransitionFadeColor = rSrcPage.mnTransitionFadeColor;
351 mfTransitionDuration = rSrcPage.mfTransitionDuration;
352 mePresChange = rSrcPage.mePresChange;
353 mfTime = rSrcPage.mfTime;
354 mbSoundOn = rSrcPage.mbSoundOn;
355 mbExcluded = rSrcPage.mbExcluded;
356 maLayoutName = rSrcPage.maLayoutName;
357 maSoundFile = rSrcPage.maSoundFile;
358 mbLoopSound = rSrcPage.mbLoopSound;
359 mbStopSound = rSrcPage.mbStopSound;
360 maCreatedPageName.clear();
361 maFileName = rSrcPage.maFileName;
362 maBookmarkName = rSrcPage.maBookmarkName;
363 mbScaleObjects = rSrcPage.mbScaleObjects;
364 mbBackgroundFullSize = rSrcPage.mbBackgroundFullSize;
365 meCharSet = rSrcPage.meCharSet;
366 mnPaperBin = rSrcPage.mnPaperBin;
367 mpPageLink = nullptr; // is set when inserting via ConnectLink()
368 mbIsPrecious = false;
370 // use shape list directly to preserve constness of rSrcPage
371 const std::list< SdrObject* >& rShapeList = rSrcPage.maPresentationShapeList.getList();
372 const size_t nObjCount = GetObjCount();
373 for( SdrObject* pObj : rShapeList )
375 size_t nOrdNum = pObj->GetOrdNum();
376 InsertPresObj(nOrdNum < nObjCount ? GetObj(nOrdNum) : nullptr, rSrcPage.GetPresObjKind(pObj));
379 // header footer
380 setHeaderFooterSettings( rSrcPage.getHeaderFooterSettings() );
382 // animations
383 rSrcPage.cloneAnimations(*this);
385 // annotations
386 for(const Reference< XAnnotation >& srcAnnotation : rSrcPage.maAnnotations)
388 Reference< XAnnotation > ref;
389 createAnnotation(ref);
390 ref->setPosition(srcAnnotation->getPosition());
391 ref->setSize(srcAnnotation->getSize());
392 ref->setAuthor(srcAnnotation->getAuthor());
393 ref->setInitials(srcAnnotation->getInitials());
394 ref->setDateTime(srcAnnotation->getDateTime());
395 Reference< ::css::text::XTextCopy > srcRange ( srcAnnotation->getTextRange(), uno::UNO_QUERY);
396 Reference< ::css::text::XTextCopy > range ( ref->getTextRange(), uno::UNO_QUERY);
397 if(srcRange.is() && range.is())
398 range->copyText( srcRange );
401 // fix user calls for duplicated slide
402 SdrObjListIter aSourceIter( &rSrcPage, SdrIterMode::DeepWithGroups );
403 SdrObjListIter aTargetIter( this, SdrIterMode::DeepWithGroups );
405 while( aSourceIter.IsMore() && aTargetIter.IsMore() )
407 SdrObject* pSource = aSourceIter.Next();
408 SdrObject* pTarget = aTargetIter.Next();
410 if( pSource->GetUserCall() )
411 pTarget->SetUserCall(this);
415 /*************************************************************************
417 |* Clone
419 \************************************************************************/
421 SdrPage* SdPage::CloneSdrPage(SdrModel& rTargetModel) const
423 SdDrawDocument& rSdDrawDocument(static_cast< SdDrawDocument& >(rTargetModel));
424 SdPage* pClonedSdPage(
425 new SdPage(
426 rSdDrawDocument,
427 IsMasterPage()));
428 pClonedSdPage->lateInit(*this);
429 return pClonedSdPage;
432 /*************************************************************************
434 |* GetTextStyleSheetForObject
436 \************************************************************************/
438 SfxStyleSheet* SdPage::GetTextStyleSheetForObject( SdrObject* pObj ) const
440 const PresObjKind eKind = GetPresObjKind(pObj);
441 if( eKind != PresObjKind::NONE )
443 return GetStyleSheetForPresObj(eKind);
446 return FmFormPage::GetTextStyleSheetForObject( pObj );
449 SfxItemSet* SdPage::getOrCreateItems()
451 if( mpItems == nullptr )
452 mpItems = std::make_unique<SfxItemSet>( getSdrModelFromSdrPage().GetItemPool(), svl::Items<SDRATTR_XMLATTRIBUTES, SDRATTR_XMLATTRIBUTES>{} );
454 return mpItems.get();
457 bool SdPage::setAlienAttributes( const css::uno::Any& rAttributes )
459 SfxItemSet* pSet = getOrCreateItems();
461 SvXMLAttrContainerItem aAlienAttributes( SDRATTR_XMLATTRIBUTES );
462 if( aAlienAttributes.PutValue( rAttributes, 0 ) )
464 pSet->Put( aAlienAttributes );
465 return true;
468 return false;
471 void SdPage::getAlienAttributes( css::uno::Any& rAttributes )
473 const SfxPoolItem* pItem;
475 if( (mpItems == nullptr) || ( SfxItemState::SET != mpItems->GetItemState( SDRATTR_XMLATTRIBUTES, false, &pItem ) ) )
477 SvXMLAttrContainerItem aAlienAttributes;
478 aAlienAttributes.QueryValue( rAttributes );
480 else
482 static_cast<const SvXMLAttrContainerItem*>(pItem)->QueryValue( rAttributes );
486 void SdPage::RemoveEmptyPresentationObjects()
488 SdrObjListIter aShapeIter( this, SdrIterMode::DeepWithGroups );
490 for (SdrObject* pShape = aShapeIter.Next(); pShape; pShape = aShapeIter.Next())
492 if (pShape->IsEmptyPresObj())
494 RemoveObject( pShape->GetOrdNum() );
495 SdrObject::Free( pShape );
500 void SdPage::setTransitionType( sal_Int16 nTransitionType )
502 mnTransitionType = nTransitionType;
503 ActionChanged();
506 void SdPage::setTransitionSubtype ( sal_Int16 nTransitionSubtype )
508 mnTransitionSubtype = nTransitionSubtype;
509 ActionChanged();
512 void SdPage::setTransitionDirection ( bool bTransitionbDirection )
514 mbTransitionDirection = bTransitionbDirection;
515 ActionChanged();
518 void SdPage::setTransitionFadeColor ( sal_Int32 nTransitionFadeColor )
520 mnTransitionFadeColor = nTransitionFadeColor;
521 ActionChanged();
524 void SdPage::setTransitionDuration ( double fTransitionDuration )
526 mfTransitionDuration = fTransitionDuration;
527 ActionChanged();
530 bool SdPage::Equals(const SdPage& rOtherPage) const
532 if (GetObjCount() != rOtherPage.GetObjCount() ||
533 mePageKind != rOtherPage.mePageKind ||
534 meAutoLayout != rOtherPage.meAutoLayout ||
535 mePresChange != rOtherPage.mePresChange ||
536 !rtl::math::approxEqual(mfTime, rOtherPage.mfTime) ||
537 mbSoundOn != rOtherPage.mbSoundOn ||
538 mbExcluded != rOtherPage.mbExcluded ||
539 maLayoutName != rOtherPage.maLayoutName ||
540 maSoundFile != rOtherPage.maSoundFile ||
541 mbLoopSound != rOtherPage.mbLoopSound ||
542 mbStopSound != rOtherPage.mbStopSound ||
543 maBookmarkName != rOtherPage.maBookmarkName ||
544 mbScaleObjects != rOtherPage.mbScaleObjects ||
545 mbBackgroundFullSize != rOtherPage.mbBackgroundFullSize ||
546 meCharSet != rOtherPage.meCharSet ||
547 mnPaperBin != rOtherPage.mnPaperBin ||
548 mnTransitionType != rOtherPage.mnTransitionType ||
549 mnTransitionSubtype != rOtherPage.mnTransitionSubtype ||
550 mbTransitionDirection != rOtherPage.mbTransitionDirection ||
551 mnTransitionFadeColor != rOtherPage.mnTransitionFadeColor ||
552 !rtl::math::approxEqual(mfTransitionDuration, rOtherPage.mfTransitionDuration))
553 return false;
555 for(size_t i = 0; i < GetObjCount(); ++i)
556 if (!GetObj(i)->Equals(*(rOtherPage.GetObj(i))))
557 return false;
559 return true;
562 void SdPage::createAnnotation( css::uno::Reference< css::office::XAnnotation >& xAnnotation )
564 sd::createAnnotation( xAnnotation, this );
567 void SdPage::addAnnotation( const Reference< XAnnotation >& xAnnotation, int nIndex )
569 if( (nIndex == -1) || (nIndex > static_cast<int>(maAnnotations.size())) )
571 maAnnotations.push_back( xAnnotation );
573 else
575 maAnnotations.insert( maAnnotations.begin() + nIndex, xAnnotation );
578 if( getSdrModelFromSdrPage().IsUndoEnabled() )
580 std::unique_ptr<SdrUndoAction> pAction = CreateUndoInsertOrRemoveAnnotation( xAnnotation, true );
581 if( pAction )
582 getSdrModelFromSdrPage().AddUndo( std::move(pAction) );
585 SetChanged();
586 getSdrModelFromSdrPage().SetChanged();
587 NotifyDocumentEvent(
588 static_cast< SdDrawDocument& >(getSdrModelFromSdrPage()),
589 "OnAnnotationInserted",
590 Reference<XInterface>(xAnnotation, UNO_QUERY));
593 void SdPage::removeAnnotation( const Reference< XAnnotation >& xAnnotation )
595 if( getSdrModelFromSdrPage().IsUndoEnabled() )
597 std::unique_ptr<SdrUndoAction> pAction = CreateUndoInsertOrRemoveAnnotation( xAnnotation, false );
598 if( pAction )
599 getSdrModelFromSdrPage().AddUndo( std::move(pAction) );
602 AnnotationVector::iterator iter = std::find( maAnnotations.begin(), maAnnotations.end(), xAnnotation );
603 if( iter != maAnnotations.end() )
604 maAnnotations.erase( iter );
606 getSdrModelFromSdrPage().SetChanged();
607 NotifyDocumentEvent(
608 static_cast< SdDrawDocument& >( getSdrModelFromSdrPage() ),
609 "OnAnnotationRemoved",
610 Reference<XInterface>( xAnnotation, UNO_QUERY ) );
613 void SdPage::getGraphicsForPrefetch(std::vector<Graphic*>& graphics) const
615 for( size_t i = 0; i < GetObjCount(); ++i)
617 SdrObject* obj = GetObj(i);
618 if( SdrGrafObj* grafObj = dynamic_cast<SdrGrafObj*>(obj))
619 if(!grafObj->GetGraphic().isAvailable())
620 graphics.push_back( const_cast<Graphic*>(&grafObj->GetGraphic()));
621 if( const Graphic* fillGraphic = obj->getFillGraphic())
622 if(!fillGraphic->isAvailable())
623 graphics.push_back( const_cast<Graphic*>(fillGraphic));
627 void SdPage::dumpAsXml(xmlTextWriterPtr pWriter) const
629 xmlTextWriterStartElement(pWriter, BAD_CAST("SdPage"));
631 const char* pPageKind = nullptr;
632 switch (mePageKind)
634 case PageKind::Standard:
635 pPageKind = "PageKind::Standard";
636 break;
637 case PageKind::Notes:
638 pPageKind = "PageKind::Notes";
639 break;
640 case PageKind::Handout:
641 pPageKind = "PageKind::Handout";
642 break;
644 if (pPageKind)
645 xmlTextWriterWriteAttribute(pWriter, BAD_CAST("mePageKind"), BAD_CAST(pPageKind));
648 FmFormPage::dumpAsXml(pWriter);
649 xmlTextWriterEndElement(pWriter);
652 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */