1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
23 #include <unordered_set>
25 #include <svx/svdpage.hxx>
27 #include <o3tl/safeint.hxx>
30 #include <tools/debug.hxx>
31 #include <tools/diagnose_ex.h>
33 #include <svtools/colorcfg.hxx>
34 #include <svx/svdetc.hxx>
35 #include <svx/svdobj.hxx>
36 #include <svx/svdogrp.hxx>
37 #include <svx/svdoedge.hxx>
38 #include <svx/svdoole2.hxx>
39 #include <svx/svditer.hxx>
40 #include <svx/svdmodel.hxx>
41 #include <svx/svdlayer.hxx>
42 #include <svx/svdpagv.hxx>
43 #include <svx/xfillit0.hxx>
44 #include <svx/fmdpage.hxx>
46 #include <sdr/contact/viewcontactofsdrpage.hxx>
47 #include <svx/sdr/contact/viewobjectcontact.hxx>
48 #include <svx/sdr/contact/displayinfo.hxx>
50 #include <svl/hint.hxx>
51 #include <rtl/strbuf.hxx>
52 #include <libxml/xmlwriter.h>
54 #include <com/sun/star/lang/IllegalArgumentException.hpp>
56 using namespace ::com::sun::star
;
58 const sal_Int32
InitialObjectContainerCapacity (64);
60 ////////////////////////////////////////////////////////////////////////////////////////////////////
61 // helper to allow changing parent at SdrObject, but only from SdrObjList
63 void SetParentAtSdrObjectFromSdrObjList(SdrObject
& rSdrObject
, SdrObjList
* pNew
)
65 rSdrObject
.setParentOfSdrObject(pNew
);
68 //////////////////////////////////////////////////////////////////////////////
70 SdrObjList::SdrObjList()
72 maSdrObjListOutRect(),
73 maSdrObjListSnapRect(),
74 mbObjOrdNumsDirty(false),
77 mbIsNavigationOrderDirty(false)
79 maList
.reserve(InitialObjectContainerCapacity
);
82 void SdrObjList::impClearSdrObjList(bool bBroadcast
)
84 SdrModel
* pSdrModelFromRemovedSdrObject(nullptr);
86 while(!maList
.empty())
88 // remove last object from list
89 SdrObject
* pObj(maList
.back());
90 RemoveObjectFromContainer(maList
.size()-1);
92 // flushViewObjectContacts() is done since SdrObject::Free is not guaranteed
93 // to delete the object and thus refresh visualisations
94 pObj
->GetViewContact().flushViewObjectContacts();
98 if(nullptr == pSdrModelFromRemovedSdrObject
)
100 pSdrModelFromRemovedSdrObject
= &pObj
->getSdrModelFromSdrObject();
103 // sent remove hint (after removal, see RemoveObject())
104 // TTTT SdrPage not needed, can be accessed using SdrObject
105 SdrHint
aHint(SdrHintKind::ObjectRemoved
, *pObj
, getSdrPageFromSdrObjList());
106 pObj
->getSdrModelFromSdrObject().Broadcast(aHint
);
109 // delete the object itself
110 SdrObject::Free( pObj
);
113 if(bBroadcast
&& nullptr != pSdrModelFromRemovedSdrObject
)
115 pSdrModelFromRemovedSdrObject
->SetChanged();
119 void SdrObjList::ClearSdrObjList()
121 // clear SdrObjects with broadcasting
122 impClearSdrObjList(true);
125 SdrObjList::~SdrObjList()
127 // clear SdrObjects without broadcasting
128 impClearSdrObjList(false);
131 SdrPage
* SdrObjList::getSdrPageFromSdrObjList() const
133 // default is no page and returns zero
137 SdrObject
* SdrObjList::getSdrObjectFromSdrObjList() const
139 // default is no SdrObject (SdrObjGroup)
143 void SdrObjList::CopyObjects(const SdrObjList
& rSrcList
)
145 // clear SdrObjects with broadcasting
148 mbObjOrdNumsDirty
= false;
149 mbRectsDirty
= false;
150 size_t nCloneErrCnt(0);
151 const size_t nCount(rSrcList
.GetObjCount());
153 if(nullptr == getSdrObjectFromSdrObjList() && nullptr == getSdrPageFromSdrObjList())
155 OSL_ENSURE(false, "SdrObjList which is not part of SdrPage or SdrObject (!)");
159 SdrModel
& rTargetSdrModel(nullptr == getSdrObjectFromSdrObjList()
160 ? getSdrPageFromSdrObjList()->getSdrModelFromSdrPage()
161 : getSdrObjectFromSdrObjList()->getSdrModelFromSdrObject());
163 for (size_t no(0); no
< nCount
; ++no
)
165 SdrObject
* pSO(rSrcList
.GetObj(no
));
166 SdrObject
* pDO(pSO
->CloneSdrObject(rTargetSdrModel
));
170 NbcInsertObject(pDO
, SAL_MAX_SIZE
);
178 // and now for the Connectors
179 // The new objects would be shown in the rSrcList
180 // and then the object connections are made.
181 // Similar implementation are setup as the following:
182 // void SdrObjList::CopyObjects(const SdrObjList& rSrcList)
183 // SdrModel* SdrExchangeView::CreateMarkedObjModel() const
184 // BOOL SdrExchangeView::Paste(const SdrModel& rMod,...)
185 // void SdrEditView::CopyMarked()
186 if (nCloneErrCnt
==0) {
187 for (size_t no
=0; no
<nCount
; ++no
) {
188 const SdrObject
* pSrcOb
=rSrcList
.GetObj(no
);
189 const SdrEdgeObj
* pSrcEdge
=dynamic_cast<const SdrEdgeObj
*>( pSrcOb
);
190 if (pSrcEdge
!=nullptr) {
191 SdrObject
* pSrcNode1
=pSrcEdge
->GetConnectedNode(true);
192 SdrObject
* pSrcNode2
=pSrcEdge
->GetConnectedNode(false);
193 if (pSrcNode1
!=nullptr && pSrcNode1
->getParentSdrObjListFromSdrObject()!=pSrcEdge
->getParentSdrObjListFromSdrObject()) pSrcNode1
=nullptr; // can't do this
194 if (pSrcNode2
!=nullptr && pSrcNode2
->getParentSdrObjListFromSdrObject()!=pSrcEdge
->getParentSdrObjListFromSdrObject()) pSrcNode2
=nullptr; // across all lists (yet)
195 if (pSrcNode1
!=nullptr || pSrcNode2
!=nullptr) {
196 SdrObject
* pEdgeObjTmp
=GetObj(no
);
197 SdrEdgeObj
* pDstEdge
=dynamic_cast<SdrEdgeObj
*>( pEdgeObjTmp
);
198 if (pDstEdge
!=nullptr) {
199 if (pSrcNode1
!=nullptr) {
200 sal_uInt32 nDstNode1
=pSrcNode1
->GetOrdNum();
201 SdrObject
* pDstNode1
=GetObj(nDstNode1
);
202 if (pDstNode1
!=nullptr) { // else we get an error!
203 pDstEdge
->ConnectToNode(true,pDstNode1
);
205 OSL_FAIL("SdrObjList::operator=(): pDstNode1==NULL!");
208 if (pSrcNode2
!=nullptr) {
209 sal_uInt32 nDstNode2
=pSrcNode2
->GetOrdNum();
210 SdrObject
* pDstNode2
=GetObj(nDstNode2
);
211 if (pDstNode2
!=nullptr) { // else the node was probably not selected
212 pDstEdge
->ConnectToNode(false,pDstNode2
);
214 OSL_FAIL("SdrObjList::operator=(): pDstNode2==NULL!");
218 OSL_FAIL("SdrObjList::operator=(): pDstEdge==NULL!");
225 OStringBuffer
aStr("SdrObjList::operator=(): Error when cloning ");
227 if(nCloneErrCnt
== 1)
229 aStr
.append("a drawing object.");
233 aStr
.append(static_cast<sal_Int32
>(nCloneErrCnt
));
234 aStr
.append(" drawing objects.");
237 aStr
.append(" Not copying connectors.");
239 OSL_FAIL(aStr
.getStr());
244 void SdrObjList::RecalcObjOrdNums()
246 const size_t nCount
= GetObjCount();
247 for (size_t no
=0; no
<nCount
; ++no
) {
248 SdrObject
* pObj
=GetObj(no
);
251 mbObjOrdNumsDirty
=false;
254 void SdrObjList::RecalcRects()
256 maSdrObjListOutRect
=tools::Rectangle();
257 maSdrObjListSnapRect
=maSdrObjListOutRect
;
258 const size_t nCount
= GetObjCount();
259 for (size_t i
=0; i
<nCount
; ++i
) {
260 SdrObject
* pObj
=GetObj(i
);
262 maSdrObjListOutRect
=pObj
->GetCurrentBoundRect();
263 maSdrObjListSnapRect
=pObj
->GetSnapRect();
265 maSdrObjListOutRect
.Union(pObj
->GetCurrentBoundRect());
266 maSdrObjListSnapRect
.Union(pObj
->GetSnapRect());
271 void SdrObjList::SetSdrObjListRectsDirty()
274 SdrObject
* pParentSdrObject(getSdrObjectFromSdrObjList());
276 if(nullptr != pParentSdrObject
)
278 pParentSdrObject
->SetRectsDirty();
282 void SdrObjList::impChildInserted(SdrObject
const & rChild
)
284 sdr::contact::ViewContact
* pParent
= rChild
.GetViewContact().GetParentContact();
288 pParent
->ActionChildInserted(rChild
.GetViewContact());
292 void SdrObjList::NbcInsertObject(SdrObject
* pObj
, size_t nPos
)
294 DBG_ASSERT(pObj
!=nullptr,"SdrObjList::NbcInsertObject(NULL)");
298 DBG_ASSERT(!pObj
->IsInserted(),"The object already has the status Inserted.");
299 const size_t nCount
= GetObjCount();
300 if (nPos
>nCount
) nPos
=nCount
;
301 InsertObjectIntoContainer(*pObj
,nPos
);
303 if (nPos
<nCount
) mbObjOrdNumsDirty
=true;
304 pObj
->SetOrdNum(nPos
);
305 SetParentAtSdrObjectFromSdrObjList(*pObj
, this);
307 // Inform the parent about change to allow invalidations at
308 // evtl. existing parent visualisations
309 impChildInserted(*pObj
);
314 pObj
->InsertedStateChange(); // calls the UserCall (among others)
317 void SdrObjList::InsertObjectThenMakeNameUnique(SdrObject
* pObj
)
319 std::unordered_set
<rtl::OUString
> aNameSet
;
320 InsertObjectThenMakeNameUnique(pObj
, aNameSet
);
323 void SdrObjList::InsertObjectThenMakeNameUnique(SdrObject
* pObj
, std::unordered_set
<OUString
>& rNameSet
, size_t nPos
)
325 InsertObject(pObj
, nPos
);
326 if (pObj
->GetName().isEmpty())
329 pObj
->MakeNameUnique(rNameSet
);
330 SdrObjList
* pSdrObjList
= pObj
->GetSubList(); // group
334 SdrObjListIter
aIter(pSdrObjList
, SdrIterMode::DeepWithGroups
);
335 while (aIter
.IsMore())
337 pListObj
= aIter
.Next();
338 pListObj
->MakeNameUnique(rNameSet
);
343 void SdrObjList::InsertObject(SdrObject
* pObj
, size_t nPos
)
345 DBG_ASSERT(pObj
!=nullptr,"SdrObjList::InsertObject(NULL)");
350 // if anchor is used, reset it before grouping
351 if(getSdrObjectFromSdrObjList())
353 const Point
& rAnchorPos
= pObj
->GetAnchorPos();
354 if(rAnchorPos
.X() || rAnchorPos
.Y())
355 pObj
->NbcSetAnchorPos(Point());
358 // do insert to new group
359 NbcInsertObject(pObj
, nPos
);
361 // In case the object is inserted into a group and doesn't overlap with
362 // the group's other members, it needs an own repaint.
363 SdrObject
* pParentSdrObject(getSdrObjectFromSdrObjList());
368 pParentSdrObject
->ActionChanged();
371 // TODO: We need a different broadcast here!
372 // Repaint from object number ... (heads-up: GroupObj)
373 if(pObj
->getSdrPageFromSdrObject())
375 SdrHint
aHint(SdrHintKind::ObjectInserted
, *pObj
);
376 pObj
->getSdrModelFromSdrObject().Broadcast(aHint
);
379 pObj
->getSdrModelFromSdrObject().SetChanged();
382 SdrObject
* SdrObjList::NbcRemoveObject(size_t nObjNum
)
384 if (nObjNum
>= maList
.size())
386 OSL_ASSERT(nObjNum
<maList
.size());
390 const size_t nCount
= GetObjCount();
391 SdrObject
* pObj
=maList
[nObjNum
];
392 RemoveObjectFromContainer(nObjNum
);
394 DBG_ASSERT(pObj
!=nullptr,"Could not find object to remove.");
397 // flushViewObjectContacts() clears the VOC's and those invalidate
398 pObj
->GetViewContact().flushViewObjectContacts();
400 DBG_ASSERT(pObj
->IsInserted(),"The object does not have the status Inserted.");
402 // tdf#121022 Do first remove from SdrObjList - InsertedStateChange
403 // relies now on IsInserted which uses getParentSdrObjListFromSdrObject
404 SetParentAtSdrObjectFromSdrObjList(*pObj
, nullptr);
406 // calls UserCall, among other
407 pObj
->InsertedStateChange();
409 if (!mbObjOrdNumsDirty
)
411 // optimizing for the case that the last object has to be removed
412 if (nObjNum
+1!=nCount
) {
413 mbObjOrdNumsDirty
=true;
416 SetSdrObjListRectsDirty();
421 SdrObject
* SdrObjList::RemoveObject(size_t nObjNum
)
423 if (nObjNum
>= maList
.size())
425 OSL_ASSERT(nObjNum
<maList
.size());
429 const size_t nCount
= GetObjCount();
430 SdrObject
* pObj
=maList
[nObjNum
];
431 RemoveObjectFromContainer(nObjNum
);
433 DBG_ASSERT(pObj
!=nullptr,"Object to remove not found.");
436 // flushViewObjectContacts() clears the VOC's and those invalidate
437 pObj
->GetViewContact().flushViewObjectContacts();
438 DBG_ASSERT(pObj
->IsInserted(),"The object does not have the status Inserted.");
440 // TODO: We need a different broadcast here.
441 if (pObj
->getSdrPageFromSdrObject()!=nullptr)
443 SdrHint
aHint(SdrHintKind::ObjectRemoved
, *pObj
);
444 pObj
->getSdrModelFromSdrObject().Broadcast(aHint
);
447 pObj
->getSdrModelFromSdrObject().SetChanged();
449 // tdf#121022 Do first remove from SdrObjList - InsertedStateChange
450 // relies now on IsInserted which uses getParentSdrObjListFromSdrObject
451 SetParentAtSdrObjectFromSdrObjList(*pObj
, nullptr);
453 // calls, among other things, the UserCall
454 pObj
->InsertedStateChange();
456 if (!mbObjOrdNumsDirty
)
458 // optimization for the case that the last object is removed
459 if (nObjNum
+1!=nCount
) {
460 mbObjOrdNumsDirty
=true;
464 SetSdrObjListRectsDirty();
465 SdrObject
* pParentSdrObject(getSdrObjectFromSdrObjList());
467 if(pParentSdrObject
&& !GetObjCount())
469 // empty group created; it needs to be repainted since it's
470 // visualization changes
471 pParentSdrObject
->ActionChanged();
477 SdrObject
* SdrObjList::ReplaceObject(SdrObject
* pNewObj
, size_t nObjNum
)
479 if (nObjNum
>= maList
.size())
481 OSL_ASSERT(nObjNum
<maList
.size());
484 if (pNewObj
== nullptr)
486 OSL_ASSERT(pNewObj
!=nullptr);
490 SdrObject
* pObj
=maList
[nObjNum
];
491 DBG_ASSERT(pObj
!=nullptr,"SdrObjList::ReplaceObject: Could not find object to remove.");
493 DBG_ASSERT(pObj
->IsInserted(),"SdrObjList::ReplaceObject: the object does not have status Inserted.");
495 // TODO: We need a different broadcast here.
496 if (pObj
->getSdrPageFromSdrObject()!=nullptr)
498 SdrHint
aHint(SdrHintKind::ObjectRemoved
, *pObj
);
499 pObj
->getSdrModelFromSdrObject().Broadcast(aHint
);
502 // Change parent and replace in SdrObjList
503 SetParentAtSdrObjectFromSdrObjList(*pObj
, nullptr);
504 ReplaceObjectInContainer(*pNewObj
,nObjNum
);
506 // tdf#121022 InsertedStateChange uses the parent
507 // to detect if pObj is inserted or not, so have to call
508 // it *after* changing these settings, else an obviously wrong
509 // 'SdrUserCallType::Inserted' would be sent
510 pObj
->InsertedStateChange();
512 // flushViewObjectContacts() clears the VOC's and those
513 // trigger the evtl. needed invalidate(s)
514 pObj
->GetViewContact().flushViewObjectContacts();
516 // Setup data at new SdrObject - it already *is* inserted to
517 // the SdrObjList due to 'ReplaceObjectInContainer' above
518 pNewObj
->SetOrdNum(nObjNum
);
519 SetParentAtSdrObjectFromSdrObjList(*pNewObj
, this);
521 // Inform the parent about change to allow invalidations at
522 // evtl. existing parent visualisations, but also react on
523 // newly inserted SdrObjects (as e.g. GraphCtrlUserCall does)
524 impChildInserted(*pNewObj
);
526 pNewObj
->InsertedStateChange();
528 // TODO: We need a different broadcast here.
529 if (pNewObj
->getSdrPageFromSdrObject()!=nullptr) {
530 SdrHint
aHint(SdrHintKind::ObjectInserted
, *pNewObj
);
531 pNewObj
->getSdrModelFromSdrObject().Broadcast(aHint
);
534 pNewObj
->getSdrModelFromSdrObject().SetChanged();
536 SetSdrObjListRectsDirty();
541 SdrObject
* SdrObjList::SetObjectOrdNum(size_t nOldObjNum
, size_t nNewObjNum
)
543 if (nOldObjNum
>= maList
.size() || nNewObjNum
>= maList
.size())
545 OSL_ASSERT(nOldObjNum
<maList
.size());
546 OSL_ASSERT(nNewObjNum
<maList
.size());
550 SdrObject
* pObj
=maList
[nOldObjNum
];
551 if (nOldObjNum
==nNewObjNum
) return pObj
;
552 DBG_ASSERT(pObj
!=nullptr,"SdrObjList::SetObjectOrdNum: Object not found.");
554 DBG_ASSERT(pObj
->IsInserted(),"SdrObjList::SetObjectOrdNum: the object does not have status Inserted.");
555 RemoveObjectFromContainer(nOldObjNum
);
556 InsertObjectIntoContainer(*pObj
,nNewObjNum
);
558 // No need to delete visualisation data since same object
559 // gets inserted again. Also a single ActionChanged is enough
560 pObj
->ActionChanged();
562 pObj
->SetOrdNum(nNewObjNum
);
563 mbObjOrdNumsDirty
=true;
565 // TODO: We need a different broadcast here.
566 if (pObj
->getSdrPageFromSdrObject()!=nullptr)
567 pObj
->getSdrModelFromSdrObject().Broadcast(SdrHint(SdrHintKind::ObjectChange
, *pObj
));
568 pObj
->getSdrModelFromSdrObject().SetChanged();
573 void SdrObjList::sort( std::vector
<sal_Int32
>& sortOrder
)
575 // no negative indexes and indexes larger than maList size are allowed
576 auto it
= std::find_if( sortOrder
.begin(), sortOrder
.end(), [this](const sal_Int32
& rIt
)
577 { return ( rIt
< 0 || o3tl::make_unsigned(rIt
) >= maList
.size() ); } );
578 if ( it
!= sortOrder
.end())
579 throw css::lang::IllegalArgumentException("negative index of shape", nullptr, 1);
582 std::vector
<bool> aNoDuplicates(sortOrder
.size(), false);
583 for (size_t i
= 0; i
< sortOrder
.size(); ++i
)
585 size_t idx
= static_cast<size_t>( sortOrder
[i
] );
587 if ( aNoDuplicates
[idx
] )
588 throw css::lang::IllegalArgumentException("duplicate index of shape", nullptr, 2);
590 aNoDuplicates
[idx
] = true;
593 // example sortOrder [2 0 1]
594 // example maList [T T S T T] ( T T = shape with textbox, S = just a shape )
595 // (shapes at positions 0 and 2 have a textbox)
597 std::vector
<SdrObject
*> aNewList(maList
.size());
598 std::set
<sal_Int32
> aShapesWithTextbox
;
599 std::vector
<sal_Int32
> aIncrements
;
600 std::vector
<sal_Int32
> aDuplicates
;
602 if ( maList
.size() > 1)
604 for (size_t i
= 1; i
< maList
.size(); ++i
)
606 // if this shape is a textbox, then look at its left neighbour
607 // (shape this textbox is in)
608 // and insert the number of textboxes to the left of it
609 if (maList
[i
]->IsTextBox())
610 aShapesWithTextbox
.insert( i
- 1 - aShapesWithTextbox
.size() );
612 // example aShapesWithTextbox [0 2]
615 if (aShapesWithTextbox
.size() != maList
.size() - sortOrder
.size())
617 throw lang::IllegalArgumentException("mismatch of no. of shapes", nullptr, 0);
620 for (size_t i
= 0; i
< sortOrder
.size(); ++i
)
623 if (aShapesWithTextbox
.count(sortOrder
[i
]) > 0)
624 aDuplicates
.push_back(sortOrder
[i
]);
626 aDuplicates
.push_back(sortOrder
[i
]);
628 // example aDuplicates [2 2 0 0 1]
630 assert(aDuplicates
.size() == maList
.size());
632 aIncrements
.push_back(0);
633 for (size_t i
= 1; i
< sortOrder
.size(); ++i
)
635 if (aShapesWithTextbox
.count(i
- 1))
636 aIncrements
.push_back(aIncrements
[i
-1] + 1 );
638 aIncrements
.push_back(aIncrements
[i
-1]);
640 // example aIncrements [0 1 1]
642 assert(aIncrements
.size() == sortOrder
.size());
644 std::vector
<sal_Int32
> aNewSortOrder(maList
.size());
645 sal_Int32 nPrev
= -1;
646 for (size_t i
= 0; i
< aDuplicates
.size(); ++i
)
648 if (nPrev
!= aDuplicates
[i
])
649 aNewSortOrder
[i
] = aDuplicates
[i
] + aIncrements
[aDuplicates
[i
]];
651 aNewSortOrder
[i
] = aNewSortOrder
[i
-1] + 1;
653 nPrev
= aDuplicates
[i
];
655 // example aNewSortOrder [3 4 0 1 2]
657 assert(aNewSortOrder
.size() == maList
.size());
661 std::vector
<sal_Int32
> tmp(aNewSortOrder
);
662 std::sort(tmp
.begin(), tmp
.end());
663 for (size_t i
= 0; i
< tmp
.size(); ++i
)
665 assert(size_t(tmp
[i
]) == i
);
670 for (size_t i
= 0; i
< aNewSortOrder
.size(); ++i
)
672 aNewList
[i
] = maList
[ aNewSortOrder
[i
] ];
673 aNewList
[i
]->SetOrdNum(i
);
676 std::swap(aNewList
, maList
);
679 const tools::Rectangle
& SdrObjList::GetAllObjSnapRect() const
682 const_cast<SdrObjList
*>(this)->RecalcRects();
683 const_cast<SdrObjList
*>(this)->mbRectsDirty
=false;
685 return maSdrObjListSnapRect
;
688 const tools::Rectangle
& SdrObjList::GetAllObjBoundRect() const
690 // #i106183# for deep group hierarchies like in chart2, the invalidates
691 // through the hierarchy are not correct; use a 2nd hint for the needed
692 // recalculation. Future versions will have no bool flag at all, but
693 // just maSdrObjListOutRect in empty state to represent an invalid state, thus
694 // it's a step in the right direction.
695 if (mbRectsDirty
|| maSdrObjListOutRect
.IsEmpty())
697 const_cast<SdrObjList
*>(this)->RecalcRects();
698 const_cast<SdrObjList
*>(this)->mbRectsDirty
=false;
700 return maSdrObjListOutRect
;
703 void SdrObjList::NbcReformatAllTextObjects()
705 size_t nCount
=GetObjCount();
710 SdrObject
* pObj
= GetObj(nNum
);
712 pObj
->NbcReformatText();
713 nCount
=GetObjCount(); // ReformatText may delete an object
719 void SdrObjList::ReformatAllTextObjects()
721 NbcReformatAllTextObjects();
724 /** steps over all available objects and reformats all
725 edge objects that are connected to other objects so that
726 they may reposition themselves.
728 void SdrObjList::ReformatAllEdgeObjects()
730 // #i120437# go over whole hierarchy, not only over object level null (seen from grouping)
731 SdrObjListIter
aIter(this, SdrIterMode::DeepNoGroups
);
733 while(aIter
.IsMore())
735 SdrObject
* pObj
= aIter
.Next();
736 if (pObj
->GetObjIdentifier() != OBJ_EDGE
)
739 SdrEdgeObj
* pSdrEdgeObj
= static_cast< SdrEdgeObj
* >(pObj
);
740 pSdrEdgeObj
->Reformat();
744 void SdrObjList::BurnInStyleSheetAttributes()
746 for(size_t a
= 0; a
< GetObjCount(); ++a
)
748 GetObj(a
)->BurnInStyleSheetAttributes();
752 size_t SdrObjList::GetObjCount() const
754 return maList
.size();
758 SdrObject
* SdrObjList::GetObj(size_t nNum
) const
764 bool SdrObjList::IsReadOnly() const
767 SdrObject
* pParentSdrObject(getSdrObjectFromSdrObjList());
769 if(nullptr != pParentSdrObject
)
771 SdrPage
* pSdrPage(pParentSdrObject
->getSdrPageFromSdrObject());
773 if(nullptr != pSdrPage
)
775 bRet
= pSdrPage
->IsReadOnly();
782 void SdrObjList::FlattenGroups()
784 const size_t nObj
= GetObjCount();
785 for( size_t i
= nObj
; i
>0; )
789 void SdrObjList::UnGroupObj( size_t nObjNum
)
791 // if the given object is no group, this method is a noop
792 SdrObject
* pUngroupObj
= GetObj( nObjNum
);
795 SdrObjList
* pSrcLst
= pUngroupObj
->GetSubList();
796 if( dynamic_cast<const SdrObjGroup
*>( pUngroupObj
) != nullptr && pSrcLst
)
798 SdrObjGroup
* pUngroupGroup
= static_cast< SdrObjGroup
* > (pUngroupObj
);
800 // ungroup recursively (has to be head recursion,
801 // otherwise our indices will get trashed when doing it in
803 pSrcLst
->FlattenGroups();
805 // the position at which we insert the members of rUngroupGroup
806 size_t nInsertPos( pUngroupGroup
->GetOrdNum() );
808 const size_t nCount
= pSrcLst
->GetObjCount();
809 for( size_t i
=0; i
<nCount
; ++i
)
811 SdrObject
* pObj
= pSrcLst
->RemoveObject(0);
812 InsertObject(pObj
, nInsertPos
);
816 RemoveObject(nInsertPos
);
821 OSL_FAIL("SdrObjList::UnGroupObj: object index invalid");
825 bool SdrObjList::HasObjectNavigationOrder() const { return mxNavigationOrder
!= nullptr; }
827 void SdrObjList::SetObjectNavigationPosition (
829 const sal_uInt32 nNewPosition
)
831 // When the navigation order container has not yet been created then
832 // create one now. It is initialized with the z-order taken from
834 if (mxNavigationOrder
== nullptr)
836 mxNavigationOrder
.reset(new std::vector
<tools::WeakReference
<SdrObject
>>(maList
.begin(),
839 OSL_ASSERT(mxNavigationOrder
!= nullptr);
840 OSL_ASSERT( mxNavigationOrder
->size() == maList
.size());
842 tools::WeakReference
<SdrObject
> aReference (&rObject
);
844 // Look up the object whose navigation position is to be changed.
845 auto iObject
= ::std::find(
846 mxNavigationOrder
->begin(),
847 mxNavigationOrder
->end(),
849 if (iObject
== mxNavigationOrder
->end())
851 // The given object is not a member of the navigation order.
855 // Move the object to its new position.
856 const sal_uInt32 nOldPosition
= ::std::distance(mxNavigationOrder
->begin(), iObject
);
857 if (nOldPosition
== nNewPosition
)
860 mxNavigationOrder
->erase(iObject
);
861 sal_uInt32
nInsertPosition (nNewPosition
);
862 // Adapt insertion position for the just erased object.
863 if (nNewPosition
>= nOldPosition
)
864 nInsertPosition
-= 1;
865 if (nInsertPosition
>= mxNavigationOrder
->size())
866 mxNavigationOrder
->push_back(aReference
);
868 mxNavigationOrder
->insert(mxNavigationOrder
->begin()+nInsertPosition
, aReference
);
870 mbIsNavigationOrderDirty
= true;
872 // The navigation order is written out to file so mark the model as modified.
873 rObject
.getSdrModelFromSdrObject().SetChanged();
877 SdrObject
* SdrObjList::GetObjectForNavigationPosition (const sal_uInt32 nNavigationPosition
) const
879 if (HasObjectNavigationOrder())
881 // There is a user defined navigation order. Make sure the object
882 // index is correct and look up the object in mxNavigationOrder.
883 if (nNavigationPosition
>= mxNavigationOrder
->size())
885 OSL_ASSERT(nNavigationPosition
< mxNavigationOrder
->size());
888 return (*mxNavigationOrder
)[nNavigationPosition
].get();
892 // There is no user defined navigation order. Use the z-order
894 if (nNavigationPosition
>= maList
.size())
896 OSL_ASSERT(nNavigationPosition
< maList
.size());
899 return maList
[nNavigationPosition
];
905 void SdrObjList::ClearObjectNavigationOrder()
907 mxNavigationOrder
.reset();
908 mbIsNavigationOrderDirty
= true;
912 bool SdrObjList::RecalcNavigationPositions()
914 if (mbIsNavigationOrderDirty
)
916 if (mxNavigationOrder
!= nullptr)
918 mbIsNavigationOrderDirty
= false;
920 sal_uInt32
nIndex (0);
921 for (auto& rpObject
: *mxNavigationOrder
)
923 rpObject
->SetNavigationPosition(nIndex
);
929 return mxNavigationOrder
!= nullptr;
933 void SdrObjList::SetNavigationOrder (const uno::Reference
<container::XIndexAccess
>& rxOrder
)
937 const sal_Int32 nCount
= rxOrder
->getCount();
938 if (static_cast<sal_uInt32
>(nCount
) != maList
.size())
941 if (mxNavigationOrder
== nullptr)
942 mxNavigationOrder
.reset(new std::vector
<tools::WeakReference
<SdrObject
>>(nCount
));
944 for (sal_Int32 nIndex
=0; nIndex
<nCount
; ++nIndex
)
946 uno::Reference
<uno::XInterface
> xShape (rxOrder
->getByIndex(nIndex
), uno::UNO_QUERY
);
947 SdrObject
* pObject
= SdrObject::getSdrObjectFromXShape(xShape
);
948 if (pObject
== nullptr)
950 (*mxNavigationOrder
)[nIndex
] = pObject
;
953 mbIsNavigationOrderDirty
= true;
957 ClearObjectNavigationOrder();
962 void SdrObjList::InsertObjectIntoContainer (
964 const sal_uInt32 nInsertPosition
)
966 OSL_ASSERT(nInsertPosition
<=maList
.size());
968 // Update the navigation positions.
969 if (HasObjectNavigationOrder())
971 // The new object does not have a user defined position so append it
973 rObject
.SetNavigationPosition(mxNavigationOrder
->size());
974 mxNavigationOrder
->push_back(&rObject
);
977 // Insert object into object list. Because the insert() method requires
978 // a valid iterator as insertion position, we have to use push_back() to
979 // insert at the end of the list.
980 if (nInsertPosition
>= maList
.size())
981 maList
.push_back(&rObject
);
983 maList
.insert(maList
.begin()+nInsertPosition
, &rObject
);
984 mbObjOrdNumsDirty
=true;
988 void SdrObjList::ReplaceObjectInContainer (
989 SdrObject
& rNewObject
,
990 const sal_uInt32 nObjectPosition
)
992 if (nObjectPosition
>= maList
.size())
994 OSL_ASSERT(nObjectPosition
<maList
.size());
998 // Update the navigation positions.
999 if (HasObjectNavigationOrder())
1001 // A user defined position of the object that is to be replaced is
1002 // not transferred to the new object so erase the former and append
1003 // the later object from/to the navigation order.
1004 OSL_ASSERT(nObjectPosition
< maList
.size());
1005 tools::WeakReference
<SdrObject
> aReference (maList
[nObjectPosition
]);
1006 auto iObject
= ::std::find(
1007 mxNavigationOrder
->begin(),
1008 mxNavigationOrder
->end(),
1010 if (iObject
!= mxNavigationOrder
->end())
1011 mxNavigationOrder
->erase(iObject
);
1013 mxNavigationOrder
->push_back(&rNewObject
);
1015 mbIsNavigationOrderDirty
= true;
1018 maList
[nObjectPosition
] = &rNewObject
;
1019 mbObjOrdNumsDirty
=true;
1023 void SdrObjList::RemoveObjectFromContainer (
1024 const sal_uInt32 nObjectPosition
)
1026 if (nObjectPosition
>= maList
.size())
1028 OSL_ASSERT(nObjectPosition
<maList
.size());
1032 // Update the navigation positions.
1033 if (HasObjectNavigationOrder())
1035 tools::WeakReference
<SdrObject
> aReference (maList
[nObjectPosition
]);
1036 auto iObject
= ::std::find(
1037 mxNavigationOrder
->begin(),
1038 mxNavigationOrder
->end(),
1040 if (iObject
!= mxNavigationOrder
->end())
1041 mxNavigationOrder
->erase(iObject
);
1042 mbIsNavigationOrderDirty
= true;
1045 maList
.erase(maList
.begin()+nObjectPosition
);
1046 mbObjOrdNumsDirty
=true;
1049 void SdrObjList::dumpAsXml(xmlTextWriterPtr pWriter
) const
1051 xmlTextWriterStartElement(pWriter
, BAD_CAST("SdrObjList"));
1052 xmlTextWriterWriteFormatAttribute(pWriter
, BAD_CAST("ptr"), "%p", this);
1053 xmlTextWriterWriteFormatAttribute(pWriter
, BAD_CAST("symbol"), "%s", BAD_CAST(typeid(*this).name()));
1055 size_t nObjCount
= GetObjCount();
1056 for (size_t i
= 0; i
< nObjCount
; ++i
)
1058 if (const SdrObject
* pObject
= GetObj(i
))
1059 pObject
->dumpAsXml(pWriter
);
1062 xmlTextWriterEndElement(pWriter
);
1066 void SdrPageGridFrameList::Clear()
1068 sal_uInt16 nCount
=GetCount();
1069 for (sal_uInt16 i
=0; i
<nCount
; i
++) {
1070 delete GetObject(i
);
1078 void SdrPage::AddPageUser(sdr::PageUser
& rNewUser
)
1080 maPageUsers
.push_back(&rNewUser
);
1083 void SdrPage::RemovePageUser(sdr::PageUser
& rOldUser
)
1085 const sdr::PageUserVector::iterator aFindResult
= ::std::find(maPageUsers
.begin(), maPageUsers
.end(), &rOldUser
);
1086 if(aFindResult
!= maPageUsers
.end())
1088 maPageUsers
.erase(aFindResult
);
1093 // DrawContact section
1095 std::unique_ptr
<sdr::contact::ViewContact
> SdrPage::CreateObjectSpecificViewContact()
1097 return std::make_unique
<sdr::contact::ViewContactOfSdrPage
>(*this);
1100 const sdr::contact::ViewContact
& SdrPage::GetViewContact() const
1103 const_cast<SdrPage
*>(this)->mpViewContact
=
1104 const_cast<SdrPage
*>(this)->CreateObjectSpecificViewContact();
1106 return *mpViewContact
;
1109 sdr::contact::ViewContact
& SdrPage::GetViewContact()
1112 mpViewContact
= CreateObjectSpecificViewContact();
1114 return *mpViewContact
;
1117 void SdrPageProperties::ImpRemoveStyleSheet()
1121 EndListening(*mpStyleSheet
);
1122 maProperties
.SetParent(nullptr);
1123 mpStyleSheet
= nullptr;
1127 void SdrPageProperties::ImpAddStyleSheet(SfxStyleSheet
& rNewStyleSheet
)
1129 if(mpStyleSheet
!= &rNewStyleSheet
)
1131 ImpRemoveStyleSheet();
1132 mpStyleSheet
= &rNewStyleSheet
;
1133 StartListening(rNewStyleSheet
);
1134 maProperties
.SetParent(&rNewStyleSheet
.GetItemSet());
1138 static void ImpPageChange(SdrPage
& rSdrPage
)
1140 rSdrPage
.ActionChanged();
1141 rSdrPage
.getSdrModelFromSdrPage().SetChanged();
1142 SdrHint
aHint(SdrHintKind::PageOrderChange
, &rSdrPage
);
1143 rSdrPage
.getSdrModelFromSdrPage().Broadcast(aHint
);
1146 SdrPageProperties::SdrPageProperties(SdrPage
& rSdrPage
)
1148 mpSdrPage(&rSdrPage
),
1149 mpStyleSheet(nullptr),
1151 mpSdrPage
->getSdrModelFromSdrPage().GetItemPool(),
1152 svl::Items
<XATTR_FILL_FIRST
, XATTR_FILL_LAST
>{})
1154 if(!rSdrPage
.IsMasterPage())
1156 maProperties
.Put(XFillStyleItem(drawing::FillStyle_NONE
));
1160 SdrPageProperties::~SdrPageProperties()
1162 ImpRemoveStyleSheet();
1165 void SdrPageProperties::Notify(SfxBroadcaster
& /*rBC*/, const SfxHint
& rHint
)
1167 switch(rHint
.GetId())
1169 case SfxHintId::DataChanged
:
1171 // notify change, broadcast
1172 ImpPageChange(*mpSdrPage
);
1175 case SfxHintId::Dying
:
1177 // Style needs to be forgotten
1178 ImpRemoveStyleSheet();
1185 bool SdrPageProperties::isUsedByModel() const
1188 return mpSdrPage
->IsInserted();
1192 void SdrPageProperties::PutItemSet(const SfxItemSet
& rSet
)
1194 OSL_ENSURE(!mpSdrPage
->IsMasterPage(), "Item set at MasterPage Attributes (!)");
1195 maProperties
.Put(rSet
);
1196 ImpPageChange(*mpSdrPage
);
1199 void SdrPageProperties::PutItem(const SfxPoolItem
& rItem
)
1201 OSL_ENSURE(!mpSdrPage
->IsMasterPage(), "Item set at MasterPage Attributes (!)");
1202 maProperties
.Put(rItem
);
1203 ImpPageChange(*mpSdrPage
);
1206 void SdrPageProperties::ClearItem(const sal_uInt16 nWhich
)
1208 maProperties
.ClearItem(nWhich
);
1209 ImpPageChange(*mpSdrPage
);
1212 void SdrPageProperties::SetStyleSheet(SfxStyleSheet
* pStyleSheet
)
1216 ImpAddStyleSheet(*pStyleSheet
);
1220 ImpRemoveStyleSheet();
1223 ImpPageChange(*mpSdrPage
);
1227 SdrPage::SdrPage(SdrModel
& rModel
, bool bMasterPage
)
1231 mrSdrModelFromSdrPage(rModel
),
1238 mpLayerAdmin(new SdrLayerAdmin(&rModel
.GetLayerAdmin())),
1241 mbMaster(bMasterPage
),
1243 mbObjectsNotPersistent(false),
1244 mbPageBorderOnlyLeftRight(false)
1246 mpSdrPageProperties
.reset(new SdrPageProperties(*this));
1251 if( mxUnoPage
.is() ) try
1253 uno::Reference
< lang::XComponent
> xPageComponent( mxUnoPage
, uno::UNO_QUERY_THROW
);
1255 xPageComponent
->dispose();
1257 catch( const uno::Exception
& )
1259 DBG_UNHANDLED_EXCEPTION("svx");
1262 // tell all the registered PageUsers that the page is in destruction
1263 // This causes some (all?) PageUsers to remove themselves from the list
1264 // of page users. Therefore we have to use a copy of the list for the
1266 sdr::PageUserVector
aListCopy (maPageUsers
.begin(), maPageUsers
.end());
1267 for(sdr::PageUser
* pPageUser
: aListCopy
)
1269 DBG_ASSERT(pPageUser
, "SdrPage::~SdrPage: corrupt PageUser list (!)");
1270 pPageUser
->PageInDestruction(*this);
1273 // Clear the vector. This means that user do not need to call RemovePageUser()
1274 // when they get called from PageInDestruction().
1275 maPageUsers
.clear();
1277 mpLayerAdmin
.reset();
1279 TRG_ClearMasterPage();
1281 mpViewContact
.reset();
1282 mpSdrPageProperties
.reset();
1285 void SdrPage::lateInit(const SdrPage
& rSrcPage
)
1287 assert(!mpViewContact
);
1288 assert(!mxUnoPage
.is());
1290 // copy all the local parameters to make this instance
1291 // a valid copy of source page before copying and inserting
1292 // the contained objects
1293 mbMaster
= rSrcPage
.mbMaster
;
1294 mbPageBorderOnlyLeftRight
= rSrcPage
.mbPageBorderOnlyLeftRight
;
1295 mnWidth
= rSrcPage
.mnWidth
;
1296 mnHeight
= rSrcPage
.mnHeight
;
1297 mnBorderLeft
= rSrcPage
.mnBorderLeft
;
1298 mnBorderUpper
= rSrcPage
.mnBorderUpper
;
1299 mnBorderRight
= rSrcPage
.mnBorderRight
;
1300 mnBorderLower
= rSrcPage
.mnBorderLower
;
1301 nPageNum
= rSrcPage
.nPageNum
;
1303 if(rSrcPage
.TRG_HasMasterPage())
1305 TRG_SetMasterPage(rSrcPage
.TRG_GetMasterPage());
1306 TRG_SetMasterPageVisibleLayers(rSrcPage
.TRG_GetMasterPageVisibleLayers());
1310 TRG_ClearMasterPage();
1313 mbObjectsNotPersistent
= rSrcPage
.mbObjectsNotPersistent
;
1316 mpSdrPageProperties
.reset(new SdrPageProperties(*this));
1320 mpSdrPageProperties
->PutItemSet(rSrcPage
.getSdrPageProperties().GetItemSet());
1323 mpSdrPageProperties
->SetStyleSheet(rSrcPage
.getSdrPageProperties().GetStyleSheet());
1326 // Now copy the contained objects
1327 if(0 != rSrcPage
.GetObjCount())
1329 CopyObjects(rSrcPage
);
1333 SdrPage
* SdrPage::CloneSdrPage(SdrModel
& rTargetModel
) const
1335 SdrPage
* pClonedPage(new SdrPage(rTargetModel
));
1336 pClonedPage
->lateInit(*this);
1340 void SdrPage::SetSize(const Size
& aSiz
)
1342 bool bChanged(false);
1344 if(aSiz
.Width() != mnWidth
)
1346 mnWidth
= aSiz
.Width();
1350 if(aSiz
.Height() != mnHeight
)
1352 mnHeight
= aSiz
.Height();
1362 Size
SdrPage::GetSize() const
1364 return Size(mnWidth
,mnHeight
);
1367 sal_Int32
SdrPage::GetWidth() const
1372 void SdrPage::SetOrientation(Orientation eOri
)
1374 // square: handle like portrait format
1375 Size
aSiz(GetSize());
1376 if (aSiz
.Width()!=aSiz
.Height()) {
1377 if ((eOri
==Orientation::Portrait
) == (aSiz
.Width()>aSiz
.Height())) {
1378 // coverity[swapped_arguments : FALSE] - this is in the correct order
1379 SetSize(Size(aSiz
.Height(),aSiz
.Width()));
1384 Orientation
SdrPage::GetOrientation() const
1386 // square: handle like portrait format
1387 Orientation eRet
=Orientation::Portrait
;
1388 Size
aSiz(GetSize());
1389 if (aSiz
.Width()>aSiz
.Height()) eRet
=Orientation::Landscape
;
1393 sal_Int32
SdrPage::GetHeight() const
1398 void SdrPage::SetBorder(sal_Int32 nLft
, sal_Int32 nUpp
, sal_Int32 nRgt
, sal_Int32 nLwr
)
1400 bool bChanged(false);
1402 if(mnBorderLeft
!= nLft
)
1404 mnBorderLeft
= nLft
;
1408 if(mnBorderUpper
!= nUpp
)
1410 mnBorderUpper
= nUpp
;
1414 if(mnBorderRight
!= nRgt
)
1416 mnBorderRight
= nRgt
;
1420 if(mnBorderLower
!= nLwr
)
1422 mnBorderLower
= nLwr
;
1432 void SdrPage::SetLeftBorder(sal_Int32 nBorder
)
1434 if(mnBorderLeft
!= nBorder
)
1436 mnBorderLeft
= nBorder
;
1441 void SdrPage::SetUpperBorder(sal_Int32 nBorder
)
1443 if(mnBorderUpper
!= nBorder
)
1445 mnBorderUpper
= nBorder
;
1450 void SdrPage::SetRightBorder(sal_Int32 nBorder
)
1452 if(mnBorderRight
!= nBorder
)
1454 mnBorderRight
=nBorder
;
1459 void SdrPage::SetLowerBorder(sal_Int32 nBorder
)
1461 if(mnBorderLower
!= nBorder
)
1463 mnBorderLower
=nBorder
;
1468 sal_Int32
SdrPage::GetLeftBorder() const
1470 return mnBorderLeft
;
1473 sal_Int32
SdrPage::GetUpperBorder() const
1475 return mnBorderUpper
;
1478 sal_Int32
SdrPage::GetRightBorder() const
1480 return mnBorderRight
;
1483 sal_Int32
SdrPage::GetLowerBorder() const
1485 return mnBorderLower
;
1488 // #i68775# React on PageNum changes (from Model in most cases)
1489 void SdrPage::SetPageNum(sal_uInt16 nNew
)
1491 if(nNew
!= nPageNum
)
1496 // notify visualisations, also notifies e.g. buffered MasterPages
1501 sal_uInt16
SdrPage::GetPageNum() const
1507 if (getSdrModelFromSdrPage().IsMPgNumsDirty())
1508 getSdrModelFromSdrPage().RecalcPageNums(true);
1510 if (getSdrModelFromSdrPage().IsPagNumsDirty())
1511 getSdrModelFromSdrPage().RecalcPageNums(false);
1516 void SdrPage::SetChanged()
1518 // For test purposes, use the new ViewContact for change
1519 // notification now.
1521 getSdrModelFromSdrPage().SetChanged();
1524 SdrPage
* SdrPage::getSdrPageFromSdrObjList() const
1526 return const_cast< SdrPage
* >(this);
1529 // MasterPage interface
1531 void SdrPage::TRG_SetMasterPage(SdrPage
& rNew
)
1533 if(mpMasterPageDescriptor
&& &(mpMasterPageDescriptor
->GetUsedPage()) == &rNew
)
1536 if(mpMasterPageDescriptor
)
1537 TRG_ClearMasterPage();
1539 mpMasterPageDescriptor
.reset(new sdr::MasterPageDescriptor(*this, rNew
));
1540 GetViewContact().ActionChanged();
1543 void SdrPage::TRG_ClearMasterPage()
1545 if(mpMasterPageDescriptor
)
1549 // the flushViewObjectContacts() will do needed invalidates by deleting the involved VOCs
1550 mpMasterPageDescriptor
->GetUsedPage().GetViewContact().flushViewObjectContacts();
1552 mpMasterPageDescriptor
.reset();
1556 SdrPage
& SdrPage::TRG_GetMasterPage() const
1558 DBG_ASSERT(mpMasterPageDescriptor
!= nullptr, "TRG_GetMasterPage(): No MasterPage available. Use TRG_HasMasterPage() before access (!)");
1559 return mpMasterPageDescriptor
->GetUsedPage();
1562 const SdrLayerIDSet
& SdrPage::TRG_GetMasterPageVisibleLayers() const
1564 DBG_ASSERT(mpMasterPageDescriptor
!= nullptr, "TRG_GetMasterPageVisibleLayers(): No MasterPage available. Use TRG_HasMasterPage() before access (!)");
1565 return mpMasterPageDescriptor
->GetVisibleLayers();
1568 void SdrPage::TRG_SetMasterPageVisibleLayers(const SdrLayerIDSet
& rNew
)
1570 DBG_ASSERT(mpMasterPageDescriptor
!= nullptr, "TRG_SetMasterPageVisibleLayers(): No MasterPage available. Use TRG_HasMasterPage() before access (!)");
1571 mpMasterPageDescriptor
->SetVisibleLayers(rNew
);
1574 sdr::contact::ViewContact
& SdrPage::TRG_GetMasterPageDescriptorViewContact() const
1576 DBG_ASSERT(mpMasterPageDescriptor
!= nullptr, "TRG_GetMasterPageDescriptorViewContact(): No MasterPage available. Use TRG_HasMasterPage() before access (!)");
1577 return mpMasterPageDescriptor
->GetViewContact();
1580 // used from SdrModel::RemoveMasterPage
1581 void SdrPage::TRG_ImpMasterPageRemoved(const SdrPage
& rRemovedPage
)
1583 if(TRG_HasMasterPage())
1585 if(&TRG_GetMasterPage() == &rRemovedPage
)
1587 TRG_ClearMasterPage();
1592 void SdrPage::MakePageObjectsNamesUnique()
1594 std::unordered_set
<OUString
> aNameSet
;
1595 for (size_t no(0); no
< GetObjCount(); ++no
)
1597 SdrObject
* pObj(GetObj(no
));
1600 if (!pObj
->GetName().isEmpty())
1602 pObj
->MakeNameUnique(aNameSet
);
1603 SdrObjList
* pSdrObjList
= pObj
->GetSubList(); // group
1606 SdrObject
* pListObj
;
1607 SdrObjListIter
aIter(pSdrObjList
, SdrIterMode::DeepWithGroups
);
1608 while (aIter
.IsMore())
1610 pListObj
= aIter
.Next();
1611 pListObj
->MakeNameUnique(aNameSet
);
1619 const SdrPageGridFrameList
* SdrPage::GetGridFrameList(const SdrPageView
* /*pPV*/, const tools::Rectangle
* /*pRect*/) const
1624 const SdrLayerAdmin
& SdrPage::GetLayerAdmin() const
1626 return *mpLayerAdmin
;
1629 SdrLayerAdmin
& SdrPage::GetLayerAdmin()
1631 return *mpLayerAdmin
;
1634 OUString
SdrPage::GetLayoutName() const
1639 void SdrPage::SetInserted( bool bIns
)
1641 if( mbInserted
== bIns
)
1646 // #i120437# go over whole hierarchy, not only over object level null (seen from grouping)
1647 SdrObjListIter
aIter(this, SdrIterMode::DeepNoGroups
);
1649 while ( aIter
.IsMore() )
1651 SdrObject
* pObj
= aIter
.Next();
1652 if ( auto pOleObj
= dynamic_cast<SdrOle2Obj
* >(pObj
) )
1657 pOleObj
->Disconnect();
1662 void SdrPage::SetUnoPage(uno::Reference
<drawing::XDrawPage
> const& xNewPage
)
1664 mxUnoPage
= xNewPage
;
1667 uno::Reference
< uno::XInterface
> const & SdrPage::getUnoPage()
1669 if( !mxUnoPage
.is() )
1672 mxUnoPage
= createUnoPage();
1678 uno::Reference
< uno::XInterface
> SdrPage::createUnoPage()
1680 css::uno::Reference
< css::uno::XInterface
> xInt
=
1681 static_cast<cppu::OWeakObject
*>( new SvxFmDrawPage( this ) );
1685 SfxStyleSheet
* SdrPage::GetTextStyleSheetForObject( SdrObject
* pObj
) const
1687 return pObj
->GetStyleSheet();
1690 /** returns an averaged background color of this page */
1691 // #i75566# GetBackgroundColor -> GetPageBackgroundColor and bScreenDisplay hint value
1692 Color
SdrPage::GetPageBackgroundColor( SdrPageView
const * pView
, bool bScreenDisplay
) const
1696 if(bScreenDisplay
&& (!pView
|| pView
->GetApplicationDocumentColor() == COL_AUTO
))
1698 svtools::ColorConfig aColorConfig
;
1699 aColor
= aColorConfig
.GetColorValue( svtools::DOCCOLOR
).nColor
;
1703 aColor
= pView
->GetApplicationDocumentColor();
1706 const SfxItemSet
* pBackgroundFill
= &getSdrPageProperties().GetItemSet();
1708 if(!IsMasterPage() && TRG_HasMasterPage())
1710 if(drawing::FillStyle_NONE
== pBackgroundFill
->Get(XATTR_FILLSTYLE
).GetValue())
1712 pBackgroundFill
= &TRG_GetMasterPage().getSdrPageProperties().GetItemSet();
1716 GetDraftFillColor(*pBackgroundFill
, aColor
);
1721 /** *deprecated, use GetBackgroundColor with SdrPageView */
1722 Color
SdrPage::GetPageBackgroundColor() const
1723 // #i75566# GetBackgroundColor -> GetPageBackgroundColor
1725 return GetPageBackgroundColor( nullptr );
1728 /** this method returns true if the object from the ViewObjectContact should
1729 be visible on this page while rendering.
1730 bEdit selects if visibility test is for an editing view or a final render,
1733 bool SdrPage::checkVisibility(
1734 const sdr::contact::ViewObjectContact
& /*rOriginal*/,
1735 const sdr::contact::DisplayInfo
& /*rDisplayInfo*/,
1738 // this will be handled in the application if needed
1742 // DrawContact support: Methods for handling Page changes
1743 void SdrPage::ActionChanged()
1745 // Do necessary ViewContact actions
1746 GetViewContact().ActionChanged();
1748 // #i48535# also handle MasterPage change
1749 if(TRG_HasMasterPage())
1751 TRG_GetMasterPageDescriptorViewContact().ActionChanged();
1755 SdrPageProperties
& SdrPage::getSdrPageProperties()
1757 return *mpSdrPageProperties
;
1760 const SdrPageProperties
& SdrPage::getSdrPageProperties() const
1762 return *mpSdrPageProperties
;
1765 const SdrPageProperties
* SdrPage::getCorrectSdrPageProperties() const
1767 if(mpMasterPageDescriptor
)
1769 return mpMasterPageDescriptor
->getCorrectSdrPageProperties();
1773 return &getSdrPageProperties();
1778 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */