LibreOffice Module svx (master)  1
svdpage.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <memory>
21 #include <cassert>
22 #include <set>
23 #include <unordered_set>
24 
25 #include <svx/svdpage.hxx>
26 
27 #include <o3tl/safeint.hxx>
28 #include <string.h>
29 
30 #include <tools/debug.hxx>
31 #include <tools/diagnose_ex.h>
32 
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>
45 
49 #include <algorithm>
50 #include <svl/hint.hxx>
51 #include <rtl/strbuf.hxx>
52 #include <libxml/xmlwriter.h>
53 
54 #include <com/sun/star/lang/IllegalArgumentException.hpp>
55 
56 using namespace ::com::sun::star;
57 
58 const sal_Int32 InitialObjectContainerCapacity (64);
59 
61 // helper to allow changing parent at SdrObject, but only from SdrObjList
62 
64 {
65  rSdrObject.setParentOfSdrObject(pNew);
66 }
67 
69 
71 : maList(),
72  maSdrObjListOutRect(),
73  maSdrObjListSnapRect(),
74  mbObjOrdNumsDirty(false),
75  mbRectsDirty(false),
76  mxNavigationOrder(),
77  mbIsNavigationOrderDirty(false)
78 {
80 }
81 
82 void SdrObjList::impClearSdrObjList(bool bBroadcast)
83 {
84  SdrModel* pSdrModelFromRemovedSdrObject(nullptr);
85 
86  while(!maList.empty())
87  {
88  // remove last object from list
89  SdrObject* pObj(maList.back());
91 
92  // flushViewObjectContacts() is done since SdrObject::Free is not guaranteed
93  // to delete the object and thus refresh visualisations
94  pObj->GetViewContact().flushViewObjectContacts();
95 
96  if(bBroadcast)
97  {
98  if(nullptr == pSdrModelFromRemovedSdrObject)
99  {
100  pSdrModelFromRemovedSdrObject = &pObj->getSdrModelFromSdrObject();
101  }
102 
103  // sent remove hint (after removal, see RemoveObject())
104  // TTTT SdrPage not needed, can be accessed using SdrObject
106  pObj->getSdrModelFromSdrObject().Broadcast(aHint);
107  }
108 
109  // delete the object itself
110  SdrObject::Free( pObj );
111  }
112 
113  if(bBroadcast && nullptr != pSdrModelFromRemovedSdrObject)
114  {
115  pSdrModelFromRemovedSdrObject->SetChanged();
116  }
117 }
118 
120 {
121  // clear SdrObjects with broadcasting
122  impClearSdrObjList(true);
123 }
124 
126 {
127  // clear SdrObjects without broadcasting
128  impClearSdrObjList(false);
129 }
130 
132 {
133  // default is no page and returns zero
134  return nullptr;
135 }
136 
138 {
139  // default is no SdrObject (SdrObjGroup)
140  return nullptr;
141 }
142 
143 void SdrObjList::CopyObjects(const SdrObjList& rSrcList)
144 {
145  // clear SdrObjects with broadcasting
146  ClearSdrObjList();
147 
148  mbObjOrdNumsDirty = false;
149  mbRectsDirty = false;
150  size_t nCloneErrCnt(0);
151  const size_t nCount(rSrcList.GetObjCount());
152 
153  if(nullptr == getSdrObjectFromSdrObjList() && nullptr == getSdrPageFromSdrObjList())
154  {
155  OSL_ENSURE(false, "SdrObjList which is not part of SdrPage or SdrObject (!)");
156  return;
157  }
158 
159  SdrModel& rTargetSdrModel(nullptr == getSdrObjectFromSdrObjList()
160  ? getSdrPageFromSdrObjList()->getSdrModelFromSdrPage()
161  : getSdrObjectFromSdrObjList()->getSdrModelFromSdrObject());
162 
163  for (size_t no(0); no < nCount; ++no)
164  {
165  SdrObject* pSO(rSrcList.GetObj(no));
166  SdrObject* pDO(pSO->CloneSdrObject(rTargetSdrModel));
167 
168  if(nullptr != pDO)
169  {
170  NbcInsertObject(pDO, SAL_MAX_SIZE);
171  }
172  else
173  {
174  nCloneErrCnt++;
175  }
176  }
177 
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);
204  } else {
205  OSL_FAIL("SdrObjList::operator=(): pDstNode1==NULL!");
206  }
207  }
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);
213  } else {
214  OSL_FAIL("SdrObjList::operator=(): pDstNode2==NULL!");
215  }
216  }
217  } else {
218  OSL_FAIL("SdrObjList::operator=(): pDstEdge==NULL!");
219  }
220  }
221  }
222  }
223  } else {
224 #ifdef DBG_UTIL
225  OStringBuffer aStr("SdrObjList::operator=(): Error when cloning ");
226 
227  if(nCloneErrCnt == 1)
228  {
229  aStr.append("a drawing object.");
230  }
231  else
232  {
233  aStr.append(static_cast<sal_Int32>(nCloneErrCnt));
234  aStr.append(" drawing objects.");
235  }
236 
237  aStr.append(" Not copying connectors.");
238 
239  OSL_FAIL(aStr.getStr());
240 #endif
241  }
242 }
243 
245 {
246  const size_t nCount = GetObjCount();
247  for (size_t no=0; no<nCount; ++no) {
248  SdrObject* pObj=GetObj(no);
249  pObj->SetOrdNum(no);
250  }
251  mbObjOrdNumsDirty=false;
252 }
253 
255 {
258  const size_t nCount = GetObjCount();
259  for (size_t i=0; i<nCount; ++i) {
260  SdrObject* pObj=GetObj(i);
261  if (i==0) {
264  } else {
267  }
268  }
269 }
270 
272 {
273  mbRectsDirty=true;
274  SdrObject* pParentSdrObject(getSdrObjectFromSdrObjList());
275 
276  if(nullptr != pParentSdrObject)
277  {
278  pParentSdrObject->SetRectsDirty();
279  }
280 }
281 
283 {
285 
286  if(pParent)
287  {
288  pParent->ActionChildInserted(rChild.GetViewContact());
289  }
290 }
291 
292 void SdrObjList::NbcInsertObject(SdrObject* pObj, size_t nPos)
293 {
294  DBG_ASSERT(pObj!=nullptr,"SdrObjList::NbcInsertObject(NULL)");
295  if (pObj==nullptr)
296  return;
297 
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);
302 
303  if (nPos<nCount) mbObjOrdNumsDirty=true;
304  pObj->SetOrdNum(nPos);
306 
307  // Inform the parent about change to allow invalidations at
308  // evtl. existing parent visualisations
309  impChildInserted(*pObj);
310 
311  if (!mbRectsDirty) {
312  mbRectsDirty = true;
313  }
314  pObj->InsertedStateChange(); // calls the UserCall (among others)
315 }
316 
318 {
319  std::unordered_set<rtl::OUString> aNameSet;
320  InsertObjectThenMakeNameUnique(pObj, aNameSet);
321 }
322 
323 void SdrObjList::InsertObjectThenMakeNameUnique(SdrObject* pObj, std::unordered_set<OUString>& rNameSet, size_t nPos)
324 {
325  InsertObject(pObj, nPos);
326  if (pObj->GetName().isEmpty())
327  return;
328 
329  pObj->MakeNameUnique(rNameSet);
330  SdrObjList* pSdrObjList = pObj->GetSubList(); // group
331  if (pSdrObjList)
332  {
333  SdrObject* pListObj;
334  SdrObjListIter aIter(pSdrObjList, SdrIterMode::DeepWithGroups);
335  while (aIter.IsMore())
336  {
337  pListObj = aIter.Next();
338  pListObj->MakeNameUnique(rNameSet);
339  }
340  }
341 }
342 
343 void SdrObjList::InsertObject(SdrObject* pObj, size_t nPos)
344 {
345  DBG_ASSERT(pObj!=nullptr,"SdrObjList::InsertObject(NULL)");
346 
347  if(!pObj)
348  return;
349 
350  // if anchor is used, reset it before grouping
352  {
353  const Point& rAnchorPos = pObj->GetAnchorPos();
354  if(rAnchorPos.X() || rAnchorPos.Y())
355  pObj->NbcSetAnchorPos(Point());
356  }
357 
358  // do insert to new group
359  NbcInsertObject(pObj, nPos);
360 
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());
364 
365  if(pParentSdrObject)
366  {
367  // only repaint here
368  pParentSdrObject->ActionChanged();
369  }
370 
371  // TODO: We need a different broadcast here!
372  // Repaint from object number ... (heads-up: GroupObj)
373  if(pObj->getSdrPageFromSdrObject())
374  {
375  SdrHint aHint(SdrHintKind::ObjectInserted, *pObj);
376  pObj->getSdrModelFromSdrObject().Broadcast(aHint);
377  }
378 
380 }
381 
383 {
384  if (nObjNum >= maList.size())
385  {
386  OSL_ASSERT(nObjNum<maList.size());
387  return nullptr;
388  }
389 
390  const size_t nCount = GetObjCount();
391  SdrObject* pObj=maList[nObjNum];
392  RemoveObjectFromContainer(nObjNum);
393 
394  DBG_ASSERT(pObj!=nullptr,"Could not find object to remove.");
395  if (pObj!=nullptr)
396  {
397  // flushViewObjectContacts() clears the VOC's and those invalidate
399 
400  DBG_ASSERT(pObj->IsInserted(),"The object does not have the status Inserted.");
401 
402  // tdf#121022 Do first remove from SdrObjList - InsertedStateChange
403  // relies now on IsInserted which uses getParentSdrObjListFromSdrObject
404  SetParentAtSdrObjectFromSdrObjList(*pObj, nullptr);
405 
406  // calls UserCall, among other
407  pObj->InsertedStateChange();
408 
409  if (!mbObjOrdNumsDirty)
410  {
411  // optimizing for the case that the last object has to be removed
412  if (nObjNum+1!=nCount) {
413  mbObjOrdNumsDirty=true;
414  }
415  }
417  }
418  return pObj;
419 }
420 
422 {
423  if (nObjNum >= maList.size())
424  {
425  OSL_ASSERT(nObjNum<maList.size());
426  return nullptr;
427  }
428 
429  const size_t nCount = GetObjCount();
430  SdrObject* pObj=maList[nObjNum];
431  RemoveObjectFromContainer(nObjNum);
432 
433  DBG_ASSERT(pObj!=nullptr,"Object to remove not found.");
434  if(pObj)
435  {
436  // flushViewObjectContacts() clears the VOC's and those invalidate
438  DBG_ASSERT(pObj->IsInserted(),"The object does not have the status Inserted.");
439 
440  // TODO: We need a different broadcast here.
441  if (pObj->getSdrPageFromSdrObject()!=nullptr)
442  {
443  SdrHint aHint(SdrHintKind::ObjectRemoved, *pObj);
444  pObj->getSdrModelFromSdrObject().Broadcast(aHint);
445  }
446 
448 
449  // tdf#121022 Do first remove from SdrObjList - InsertedStateChange
450  // relies now on IsInserted which uses getParentSdrObjListFromSdrObject
451  SetParentAtSdrObjectFromSdrObjList(*pObj, nullptr);
452 
453  // calls, among other things, the UserCall
454  pObj->InsertedStateChange();
455 
456  if (!mbObjOrdNumsDirty)
457  {
458  // optimization for the case that the last object is removed
459  if (nObjNum+1!=nCount) {
460  mbObjOrdNumsDirty=true;
461  }
462  }
463 
465  SdrObject* pParentSdrObject(getSdrObjectFromSdrObjList());
466 
467  if(pParentSdrObject && !GetObjCount())
468  {
469  // empty group created; it needs to be repainted since it's
470  // visualization changes
471  pParentSdrObject->ActionChanged();
472  }
473  }
474  return pObj;
475 }
476 
478 {
479  if (nObjNum >= maList.size())
480  {
481  OSL_ASSERT(nObjNum<maList.size());
482  return nullptr;
483  }
484  if (pNewObj == nullptr)
485  {
486  OSL_ASSERT(pNewObj!=nullptr);
487  return nullptr;
488  }
489 
490  SdrObject* pObj=maList[nObjNum];
491  DBG_ASSERT(pObj!=nullptr,"SdrObjList::ReplaceObject: Could not find object to remove.");
492  if (pObj!=nullptr) {
493  DBG_ASSERT(pObj->IsInserted(),"SdrObjList::ReplaceObject: the object does not have status Inserted.");
494 
495  // TODO: We need a different broadcast here.
496  if (pObj->getSdrPageFromSdrObject()!=nullptr)
497  {
498  SdrHint aHint(SdrHintKind::ObjectRemoved, *pObj);
499  pObj->getSdrModelFromSdrObject().Broadcast(aHint);
500  }
501 
502  // Change parent and replace in SdrObjList
503  SetParentAtSdrObjectFromSdrObjList(*pObj, nullptr);
504  ReplaceObjectInContainer(*pNewObj,nObjNum);
505 
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();
511 
512  // flushViewObjectContacts() clears the VOC's and those
513  // trigger the evtl. needed invalidate(s)
515 
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);
520 
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);
525 
526  pNewObj->InsertedStateChange();
527 
528  // TODO: We need a different broadcast here.
529  if (pNewObj->getSdrPageFromSdrObject()!=nullptr) {
530  SdrHint aHint(SdrHintKind::ObjectInserted, *pNewObj);
531  pNewObj->getSdrModelFromSdrObject().Broadcast(aHint);
532  }
533 
535 
537  }
538  return pObj;
539 }
540 
541 SdrObject* SdrObjList::SetObjectOrdNum(size_t nOldObjNum, size_t nNewObjNum)
542 {
543  if (nOldObjNum >= maList.size() || nNewObjNum >= maList.size())
544  {
545  OSL_ASSERT(nOldObjNum<maList.size());
546  OSL_ASSERT(nNewObjNum<maList.size());
547  return nullptr;
548  }
549 
550  SdrObject* pObj=maList[nOldObjNum];
551  if (nOldObjNum==nNewObjNum) return pObj;
552  DBG_ASSERT(pObj!=nullptr,"SdrObjList::SetObjectOrdNum: Object not found.");
553  if (pObj!=nullptr) {
554  DBG_ASSERT(pObj->IsInserted(),"SdrObjList::SetObjectOrdNum: the object does not have status Inserted.");
555  RemoveObjectFromContainer(nOldObjNum);
556  InsertObjectIntoContainer(*pObj,nNewObjNum);
557 
558  // No need to delete visualisation data since same object
559  // gets inserted again. Also a single ActionChanged is enough
560  pObj->ActionChanged();
561 
562  pObj->SetOrdNum(nNewObjNum);
563  mbObjOrdNumsDirty=true;
564 
565  // TODO: We need a different broadcast here.
566  if (pObj->getSdrPageFromSdrObject()!=nullptr)
569  }
570  return pObj;
571 }
572 
573 void SdrObjList::sort( std::vector<sal_Int32>& sortOrder)
574 {
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);
580 
581  // no duplicates
582  std::vector<bool> aNoDuplicates(sortOrder.size(), false);
583  for (size_t i = 0; i < sortOrder.size(); ++i )
584  {
585  size_t idx = static_cast<size_t>( sortOrder[i] );
586 
587  if ( aNoDuplicates[idx] )
588  throw css::lang::IllegalArgumentException("duplicate index of shape", nullptr, 2);
589 
590  aNoDuplicates[idx] = true;
591  }
592 
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)
596 
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;
601 
602  if ( maList.size() > 1)
603  {
604  for (size_t i = 1; i< maList.size(); ++i)
605  {
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() );
611  }
612  // example aShapesWithTextbox [0 2]
613  }
614 
615  if (aShapesWithTextbox.size() != maList.size() - sortOrder.size())
616  {
617  throw lang::IllegalArgumentException("mismatch of no. of shapes", nullptr, 0);
618  }
619 
620  for (size_t i = 0; i< sortOrder.size(); ++i)
621  {
622 
623  if (aShapesWithTextbox.count(sortOrder[i]) > 0)
624  aDuplicates.push_back(sortOrder[i]);
625 
626  aDuplicates.push_back(sortOrder[i]);
627 
628  // example aDuplicates [2 2 0 0 1]
629  }
630  assert(aDuplicates.size() == maList.size());
631 
632  aIncrements.push_back(0);
633  for (size_t i = 1; i< sortOrder.size(); ++i)
634  {
635  if (aShapesWithTextbox.count(i - 1))
636  aIncrements.push_back(aIncrements[i-1] + 1 );
637  else
638  aIncrements.push_back(aIncrements[i-1]);
639 
640  // example aIncrements [0 1 1]
641  }
642  assert(aIncrements.size() == sortOrder.size());
643 
644  std::vector<sal_Int32> aNewSortOrder(maList.size());
645  sal_Int32 nPrev = -1;
646  for (size_t i = 0; i< aDuplicates.size(); ++i)
647  {
648  if (nPrev != aDuplicates[i])
649  aNewSortOrder[i] = aDuplicates[i] + aIncrements[aDuplicates[i]];
650  else
651  aNewSortOrder[i] = aNewSortOrder[i-1] + 1;
652 
653  nPrev = aDuplicates[i];
654 
655  // example aNewSortOrder [3 4 0 1 2]
656  }
657  assert(aNewSortOrder.size() == maList.size());
658 
659 #ifndef NDEBUG
660  {
661  std::vector<sal_Int32> tmp(aNewSortOrder);
662  std::sort(tmp.begin(), tmp.end());
663  for (size_t i = 0; i < tmp.size(); ++i)
664  {
665  assert(size_t(tmp[i]) == i);
666  }
667  }
668 #endif
669 
670  for (size_t i = 0; i < aNewSortOrder.size(); ++i)
671  {
672  aNewList[i] = maList[ aNewSortOrder[i] ];
673  aNewList[i]->SetOrdNum(i);
674  }
675 
676  std::swap(aNewList, maList);
677 }
678 
680 {
681  if (mbRectsDirty) {
682  const_cast<SdrObjList*>(this)->RecalcRects();
683  const_cast<SdrObjList*>(this)->mbRectsDirty=false;
684  }
685  return maSdrObjListSnapRect;
686 }
687 
689 {
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.
696  {
697  const_cast<SdrObjList*>(this)->RecalcRects();
698  const_cast<SdrObjList*>(this)->mbRectsDirty=false;
699  }
700  return maSdrObjListOutRect;
701 }
702 
704 {
705  size_t nCount=GetObjCount();
706  size_t nNum=0;
707 
708  while (nNum<nCount)
709  {
710  SdrObject* pObj = GetObj(nNum);
711 
712  pObj->NbcReformatText();
713  nCount=GetObjCount(); // ReformatText may delete an object
714  nNum++;
715  }
716 
717 }
718 
720 {
722 }
723 
729 {
730  // #i120437# go over whole hierarchy, not only over object level null (seen from grouping)
732 
733  while(aIter.IsMore())
734  {
735  SdrObject* pObj = aIter.Next();
736  if (pObj->GetObjIdentifier() != OBJ_EDGE)
737  continue;
738 
739  SdrEdgeObj* pSdrEdgeObj = static_cast< SdrEdgeObj* >(pObj);
740  pSdrEdgeObj->Reformat();
741  }
742 }
743 
745 {
746  for(size_t a = 0; a < GetObjCount(); ++a)
747  {
749  }
750 }
751 
753 {
754  return maList.size();
755 }
756 
757 
758 SdrObject* SdrObjList::GetObj(size_t nNum) const
759 {
760  return maList[nNum];
761 }
762 
763 
765 {
766  bool bRet(false);
767  SdrObject* pParentSdrObject(getSdrObjectFromSdrObjList());
768 
769  if(nullptr != pParentSdrObject)
770  {
771  SdrPage* pSdrPage(pParentSdrObject->getSdrPageFromSdrObject());
772 
773  if(nullptr != pSdrPage)
774  {
775  bRet = pSdrPage->IsReadOnly();
776  }
777  }
778 
779  return bRet;
780 }
781 
783 {
784  const size_t nObj = GetObjCount();
785  for( size_t i = nObj; i>0; )
786  UnGroupObj(--i);
787 }
788 
789 void SdrObjList::UnGroupObj( size_t nObjNum )
790 {
791  // if the given object is no group, this method is a noop
792  SdrObject* pUngroupObj = GetObj( nObjNum );
793  if( pUngroupObj )
794  {
795  SdrObjList* pSrcLst = pUngroupObj->GetSubList();
796  if(pSrcLst)
797  if(auto pUngroupGroup = dynamic_cast<SdrObjGroup*>( pUngroupObj))
798  {
799  // ungroup recursively (has to be head recursion,
800  // otherwise our indices will get trashed when doing it in
801  // the loop)
802  pSrcLst->FlattenGroups();
803 
804  // the position at which we insert the members of rUngroupGroup
805  size_t nInsertPos( pUngroupGroup->GetOrdNum() );
806 
807  const size_t nCount = pSrcLst->GetObjCount();
808  for( size_t i=0; i<nCount; ++i )
809  {
810  SdrObject* pObj = pSrcLst->RemoveObject(0);
811  InsertObject(pObj, nInsertPos);
812  ++nInsertPos;
813  }
814 
815  RemoveObject(nInsertPos);
816  }
817  }
818 #ifdef DBG_UTIL
819  else
820  OSL_FAIL("SdrObjList::UnGroupObj: object index invalid");
821 #endif
822 }
823 
824 bool SdrObjList::HasObjectNavigationOrder() const { return mxNavigationOrder != nullptr; }
825 
827  SdrObject& rObject,
828  const sal_uInt32 nNewPosition)
829 {
830  // When the navigation order container has not yet been created then
831  // create one now. It is initialized with the z-order taken from
832  // maList.
833  if (mxNavigationOrder == nullptr)
834  {
835  mxNavigationOrder.reset(new std::vector<tools::WeakReference<SdrObject>>(maList.begin(),
836  maList.end()));
837  }
838  OSL_ASSERT(mxNavigationOrder != nullptr);
839  OSL_ASSERT( mxNavigationOrder->size() == maList.size());
840 
841  tools::WeakReference<SdrObject> aReference (&rObject);
842 
843  // Look up the object whose navigation position is to be changed.
844  auto iObject = ::std::find(
845  mxNavigationOrder->begin(),
846  mxNavigationOrder->end(),
847  aReference);
848  if (iObject == mxNavigationOrder->end())
849  {
850  // The given object is not a member of the navigation order.
851  return;
852  }
853 
854  // Move the object to its new position.
855  const sal_uInt32 nOldPosition = ::std::distance(mxNavigationOrder->begin(), iObject);
856  if (nOldPosition == nNewPosition)
857  return;
858 
859  mxNavigationOrder->erase(iObject);
860  sal_uInt32 nInsertPosition (nNewPosition);
861  // Adapt insertion position for the just erased object.
862  if (nNewPosition >= nOldPosition)
863  nInsertPosition -= 1;
864  if (nInsertPosition >= mxNavigationOrder->size())
865  mxNavigationOrder->push_back(aReference);
866  else
867  mxNavigationOrder->insert(mxNavigationOrder->begin()+nInsertPosition, aReference);
868 
870 
871  // The navigation order is written out to file so mark the model as modified.
873 }
874 
875 
876 SdrObject* SdrObjList::GetObjectForNavigationPosition (const sal_uInt32 nNavigationPosition) const
877 {
879  {
880  // There is a user defined navigation order. Make sure the object
881  // index is correct and look up the object in mxNavigationOrder.
882  if (nNavigationPosition >= mxNavigationOrder->size())
883  {
884  OSL_ASSERT(nNavigationPosition < mxNavigationOrder->size());
885  }
886  else
887  return (*mxNavigationOrder)[nNavigationPosition].get();
888  }
889  else
890  {
891  // There is no user defined navigation order. Use the z-order
892  // instead.
893  if (nNavigationPosition >= maList.size())
894  {
895  OSL_ASSERT(nNavigationPosition < maList.size());
896  }
897  else
898  return maList[nNavigationPosition];
899  }
900  return nullptr;
901 }
902 
903 
905 {
906  mxNavigationOrder.reset();
908 }
909 
910 
912 {
914  {
915  if (mxNavigationOrder != nullptr)
916  {
917  mbIsNavigationOrderDirty = false;
918 
919  sal_uInt32 nIndex (0);
920  for (auto& rpObject : *mxNavigationOrder)
921  {
922  rpObject->SetNavigationPosition(nIndex);
923  ++nIndex;
924  }
925  }
926  }
927 
928  return mxNavigationOrder != nullptr;
929 }
930 
931 
932 void SdrObjList::SetNavigationOrder (const uno::Reference<container::XIndexAccess>& rxOrder)
933 {
934  if (rxOrder.is())
935  {
936  const sal_Int32 nCount = rxOrder->getCount();
937  if (static_cast<sal_uInt32>(nCount) != maList.size())
938  return;
939 
940  if (mxNavigationOrder == nullptr)
941  mxNavigationOrder.reset(new std::vector<tools::WeakReference<SdrObject>>(nCount));
942 
943  for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
944  {
945  uno::Reference<uno::XInterface> xShape (rxOrder->getByIndex(nIndex), uno::UNO_QUERY);
947  if (pObject == nullptr)
948  break;
949  (*mxNavigationOrder)[nIndex] = pObject;
950  }
951 
953  }
954  else
955  {
957  }
958 }
959 
960 
962  SdrObject& rObject,
963  const sal_uInt32 nInsertPosition)
964 {
965  OSL_ASSERT(nInsertPosition<=maList.size());
966 
967  // Update the navigation positions.
969  {
970  // The new object does not have a user defined position so append it
971  // to the list.
972  rObject.SetNavigationPosition(mxNavigationOrder->size());
973  mxNavigationOrder->push_back(&rObject);
974  }
975 
976  // Insert object into object list. Because the insert() method requires
977  // a valid iterator as insertion position, we have to use push_back() to
978  // insert at the end of the list.
979  if (nInsertPosition >= maList.size())
980  maList.push_back(&rObject);
981  else
982  maList.insert(maList.begin()+nInsertPosition, &rObject);
983  mbObjOrdNumsDirty=true;
984 }
985 
986 
988  SdrObject& rNewObject,
989  const sal_uInt32 nObjectPosition)
990 {
991  if (nObjectPosition >= maList.size())
992  {
993  OSL_ASSERT(nObjectPosition<maList.size());
994  return;
995  }
996 
997  // Update the navigation positions.
999  {
1000  // A user defined position of the object that is to be replaced is
1001  // not transferred to the new object so erase the former and append
1002  // the later object from/to the navigation order.
1003  OSL_ASSERT(nObjectPosition < maList.size());
1004  tools::WeakReference<SdrObject> aReference (maList[nObjectPosition]);
1005  auto iObject = ::std::find(
1006  mxNavigationOrder->begin(),
1007  mxNavigationOrder->end(),
1008  aReference);
1009  if (iObject != mxNavigationOrder->end())
1010  mxNavigationOrder->erase(iObject);
1011 
1012  mxNavigationOrder->push_back(&rNewObject);
1013 
1014  mbIsNavigationOrderDirty = true;
1015  }
1016 
1017  maList[nObjectPosition] = &rNewObject;
1018  mbObjOrdNumsDirty=true;
1019 }
1020 
1021 
1023  const sal_uInt32 nObjectPosition)
1024 {
1025  if (nObjectPosition >= maList.size())
1026  {
1027  OSL_ASSERT(nObjectPosition<maList.size());
1028  return;
1029  }
1030 
1031  // Update the navigation positions.
1033  {
1034  tools::WeakReference<SdrObject> aReference (maList[nObjectPosition]);
1035  auto iObject = ::std::find(
1036  mxNavigationOrder->begin(),
1037  mxNavigationOrder->end(),
1038  aReference);
1039  if (iObject != mxNavigationOrder->end())
1040  mxNavigationOrder->erase(iObject);
1041  mbIsNavigationOrderDirty = true;
1042  }
1043 
1044  maList.erase(maList.begin()+nObjectPosition);
1045  mbObjOrdNumsDirty=true;
1046 }
1047 
1049 {
1050  xmlTextWriterStartElement(pWriter, BAD_CAST("SdrObjList"));
1051  xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
1052  xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("symbol"), "%s", BAD_CAST(typeid(*this).name()));
1053 
1054  size_t nObjCount = GetObjCount();
1055  for (size_t i = 0; i < nObjCount; ++i)
1056  {
1057  if (const SdrObject* pObject = GetObj(i))
1058  pObject->dumpAsXml(pWriter);
1059  }
1060 
1061  xmlTextWriterEndElement(pWriter);
1062 }
1063 
1064 
1066 {
1067  sal_uInt16 nCount=GetCount();
1068  for (sal_uInt16 i=0; i<nCount; i++) {
1069  delete GetObject(i);
1070  }
1071  aList.clear();
1072 }
1073 
1074 
1075 // PageUser section
1076 
1078 {
1079  maPageUsers.push_back(&rNewUser);
1080 }
1081 
1083 {
1084  const sdr::PageUserVector::iterator aFindResult = ::std::find(maPageUsers.begin(), maPageUsers.end(), &rOldUser);
1085  if(aFindResult != maPageUsers.end())
1086  {
1087  maPageUsers.erase(aFindResult);
1088  }
1089 }
1090 
1091 
1092 // DrawContact section
1093 
1094 std::unique_ptr<sdr::contact::ViewContact> SdrPage::CreateObjectSpecificViewContact()
1095 {
1096  return std::make_unique<sdr::contact::ViewContactOfSdrPage>(*this);
1097 }
1098 
1100 {
1101  if (!mpViewContact)
1102  const_cast<SdrPage*>(this)->mpViewContact =
1103  const_cast<SdrPage*>(this)->CreateObjectSpecificViewContact();
1104 
1105  return *mpViewContact;
1106 }
1107 
1109 {
1110  if (!mpViewContact)
1112 
1113  return *mpViewContact;
1114 }
1115 
1117 {
1118  if(mpStyleSheet)
1119  {
1121  maProperties.SetParent(nullptr);
1122  mpStyleSheet = nullptr;
1123  }
1124 }
1125 
1127 {
1128  if(mpStyleSheet != &rNewStyleSheet)
1129  {
1131  mpStyleSheet = &rNewStyleSheet;
1132  StartListening(rNewStyleSheet);
1133  maProperties.SetParent(&rNewStyleSheet.GetItemSet());
1134  }
1135 }
1136 
1137 static void ImpPageChange(SdrPage& rSdrPage)
1138 {
1139  rSdrPage.ActionChanged();
1140  rSdrPage.getSdrModelFromSdrPage().SetChanged();
1141  SdrHint aHint(SdrHintKind::PageOrderChange, &rSdrPage);
1142  rSdrPage.getSdrModelFromSdrPage().Broadcast(aHint);
1143 }
1144 
1146 : SfxListener(),
1147  mpSdrPage(&rSdrPage),
1148  mpStyleSheet(nullptr),
1149  maProperties(
1150  mpSdrPage->getSdrModelFromSdrPage().GetItemPool(),
1152 {
1153  if(!rSdrPage.IsMasterPage())
1154  {
1155  maProperties.Put(XFillStyleItem(drawing::FillStyle_NONE));
1156  }
1157 }
1158 
1160 {
1162 }
1163 
1165 {
1166  switch(rHint.GetId())
1167  {
1168  case SfxHintId::DataChanged :
1169  {
1170  // notify change, broadcast
1172  break;
1173  }
1174  case SfxHintId::Dying :
1175  {
1176  // Style needs to be forgotten
1178  break;
1179  }
1180  default: break;
1181  }
1182 }
1183 
1185 {
1186  assert(mpSdrPage);
1187  return mpSdrPage->IsInserted();
1188 }
1189 
1190 
1192 {
1193  OSL_ENSURE(!mpSdrPage->IsMasterPage(), "Item set at MasterPage Attributes (!)");
1194  maProperties.Put(rSet);
1196 }
1197 
1199 {
1200  OSL_ENSURE(!mpSdrPage->IsMasterPage(), "Item set at MasterPage Attributes (!)");
1201  maProperties.Put(rItem);
1203 }
1204 
1205 void SdrPageProperties::ClearItem(const sal_uInt16 nWhich)
1206 {
1207  maProperties.ClearItem(nWhich);
1209 }
1210 
1212 {
1213  if(pStyleSheet)
1214  {
1215  ImpAddStyleSheet(*pStyleSheet);
1216  }
1217  else
1218  {
1220  }
1221 
1223 }
1224 
1225 
1226 SdrPage::SdrPage(SdrModel& rModel, bool bMasterPage)
1227 : SdrObjList(),
1228  tools::WeakBase(),
1229  maPageUsers(),
1230  mrSdrModelFromSdrPage(rModel),
1231  mnWidth(10),
1232  mnHeight(10),
1233  mnBorderLeft(0),
1234  mnBorderUpper(0),
1235  mnBorderRight(0),
1236  mnBorderLower(0),
1237  mpLayerAdmin(new SdrLayerAdmin(&rModel.GetLayerAdmin())),
1238  mxUnoPage(),
1239  nPageNum(0),
1240  mbMaster(bMasterPage),
1241  mbInserted(false),
1242  mbObjectsNotPersistent(false),
1243  mbPageBorderOnlyLeftRight(false)
1244 {
1245  mpSdrPageProperties.reset(new SdrPageProperties(*this));
1246 }
1247 
1249 {
1250  if( mxUnoPage.is() ) try
1251  {
1252  uno::Reference< lang::XComponent > xPageComponent( mxUnoPage, uno::UNO_QUERY_THROW );
1253  mxUnoPage.clear();
1254  xPageComponent->dispose();
1255  }
1256  catch( const uno::Exception& )
1257  {
1258  DBG_UNHANDLED_EXCEPTION("svx");
1259  }
1260 
1261  // tell all the registered PageUsers that the page is in destruction
1262  // This causes some (all?) PageUsers to remove themselves from the list
1263  // of page users. Therefore we have to use a copy of the list for the
1264  // iteration.
1265  sdr::PageUserVector aListCopy (maPageUsers.begin(), maPageUsers.end());
1266  for(sdr::PageUser* pPageUser : aListCopy)
1267  {
1268  DBG_ASSERT(pPageUser, "SdrPage::~SdrPage: corrupt PageUser list (!)");
1269  pPageUser->PageInDestruction(*this);
1270  }
1271 
1272  // Clear the vector. This means that user do not need to call RemovePageUser()
1273  // when they get called from PageInDestruction().
1274  maPageUsers.clear();
1275 
1276  mpLayerAdmin.reset();
1277 
1279 
1280  mpViewContact.reset();
1281  mpSdrPageProperties.reset();
1282 }
1283 
1284 void SdrPage::lateInit(const SdrPage& rSrcPage)
1285 {
1287  assert(!mxUnoPage.is());
1288 
1289  // copy all the local parameters to make this instance
1290  // a valid copy of source page before copying and inserting
1291  // the contained objects
1292  mbMaster = rSrcPage.mbMaster;
1294  mnWidth = rSrcPage.mnWidth;
1295  mnHeight = rSrcPage.mnHeight;
1296  mnBorderLeft = rSrcPage.mnBorderLeft;
1297  mnBorderUpper = rSrcPage.mnBorderUpper;
1298  mnBorderRight = rSrcPage.mnBorderRight;
1299  mnBorderLower = rSrcPage.mnBorderLower;
1300  nPageNum = rSrcPage.nPageNum;
1301 
1302  if(rSrcPage.TRG_HasMasterPage())
1303  {
1306  }
1307  else
1308  {
1310  }
1311 
1313 
1314  {
1315  mpSdrPageProperties.reset(new SdrPageProperties(*this));
1316 
1317  if(!IsMasterPage())
1318  {
1319  mpSdrPageProperties->PutItemSet(rSrcPage.getSdrPageProperties().GetItemSet());
1320  }
1321 
1322  mpSdrPageProperties->SetStyleSheet(rSrcPage.getSdrPageProperties().GetStyleSheet());
1323  }
1324 
1325  // Now copy the contained objects
1326  if(0 != rSrcPage.GetObjCount())
1327  {
1328  CopyObjects(rSrcPage);
1329  }
1330 }
1331 
1333 {
1334  SdrPage* pClonedPage(new SdrPage(rTargetModel));
1335  pClonedPage->lateInit(*this);
1336  return pClonedPage;
1337 }
1338 
1339 void SdrPage::SetSize(const Size& aSiz)
1340 {
1341  bool bChanged(false);
1342 
1343  if(aSiz.Width() != mnWidth)
1344  {
1345  mnWidth = aSiz.Width();
1346  bChanged = true;
1347  }
1348 
1349  if(aSiz.Height() != mnHeight)
1350  {
1351  mnHeight = aSiz.Height();
1352  bChanged = true;
1353  }
1354 
1355  if(bChanged)
1356  {
1357  SetChanged();
1358  }
1359 }
1360 
1362 {
1363  return Size(mnWidth,mnHeight);
1364 }
1365 
1366 sal_Int32 SdrPage::GetWidth() const
1367 {
1368  return mnWidth;
1369 }
1370 
1372 {
1373  // square: handle like portrait format
1374  Size aSiz(GetSize());
1375  if (aSiz.Width()!=aSiz.Height()) {
1376  if ((eOri==Orientation::Portrait) == (aSiz.Width()>aSiz.Height())) {
1377  // coverity[swapped_arguments : FALSE] - this is in the correct order
1378  SetSize(Size(aSiz.Height(),aSiz.Width()));
1379  }
1380  }
1381 }
1382 
1384 {
1385  // square: handle like portrait format
1386  Orientation eRet=Orientation::Portrait;
1387  Size aSiz(GetSize());
1388  if (aSiz.Width()>aSiz.Height()) eRet=Orientation::Landscape;
1389  return eRet;
1390 }
1391 
1392 sal_Int32 SdrPage::GetHeight() const
1393 {
1394  return mnHeight;
1395 }
1396 
1397 void SdrPage::SetBorder(sal_Int32 nLft, sal_Int32 nUpp, sal_Int32 nRgt, sal_Int32 nLwr)
1398 {
1399  bool bChanged(false);
1400 
1401  if(mnBorderLeft != nLft)
1402  {
1403  mnBorderLeft = nLft;
1404  bChanged = true;
1405  }
1406 
1407  if(mnBorderUpper != nUpp)
1408  {
1409  mnBorderUpper = nUpp;
1410  bChanged = true;
1411  }
1412 
1413  if(mnBorderRight != nRgt)
1414  {
1415  mnBorderRight = nRgt;
1416  bChanged = true;
1417  }
1418 
1419  if(mnBorderLower != nLwr)
1420  {
1421  mnBorderLower = nLwr;
1422  bChanged = true;
1423  }
1424 
1425  if(bChanged)
1426  {
1427  SetChanged();
1428  }
1429 }
1430 
1431 void SdrPage::SetLeftBorder(sal_Int32 nBorder)
1432 {
1433  if(mnBorderLeft != nBorder)
1434  {
1435  mnBorderLeft = nBorder;
1436  SetChanged();
1437  }
1438 }
1439 
1440 void SdrPage::SetUpperBorder(sal_Int32 nBorder)
1441 {
1442  if(mnBorderUpper != nBorder)
1443  {
1444  mnBorderUpper = nBorder;
1445  SetChanged();
1446  }
1447 }
1448 
1449 void SdrPage::SetRightBorder(sal_Int32 nBorder)
1450 {
1451  if(mnBorderRight != nBorder)
1452  {
1453  mnBorderRight=nBorder;
1454  SetChanged();
1455  }
1456 }
1457 
1458 void SdrPage::SetLowerBorder(sal_Int32 nBorder)
1459 {
1460  if(mnBorderLower != nBorder)
1461  {
1462  mnBorderLower=nBorder;
1463  SetChanged();
1464  }
1465 }
1466 
1467 sal_Int32 SdrPage::GetLeftBorder() const
1468 {
1469  return mnBorderLeft;
1470 }
1471 
1472 sal_Int32 SdrPage::GetUpperBorder() const
1473 {
1474  return mnBorderUpper;
1475 }
1476 
1477 sal_Int32 SdrPage::GetRightBorder() const
1478 {
1479  return mnBorderRight;
1480 }
1481 
1482 sal_Int32 SdrPage::GetLowerBorder() const
1483 {
1484  return mnBorderLower;
1485 }
1486 
1487 // #i68775# React on PageNum changes (from Model in most cases)
1488 void SdrPage::SetPageNum(sal_uInt16 nNew)
1489 {
1490  if(nNew != nPageNum)
1491  {
1492  // change
1493  nPageNum = nNew;
1494 
1495  // notify visualisations, also notifies e.g. buffered MasterPages
1496  ActionChanged();
1497  }
1498 }
1499 
1500 sal_uInt16 SdrPage::GetPageNum() const
1501 {
1502  if (!mbInserted)
1503  return 0;
1504 
1505  if (mbMaster) {
1506  if (getSdrModelFromSdrPage().IsMPgNumsDirty())
1508  } else {
1509  if (getSdrModelFromSdrPage().IsPagNumsDirty())
1511  }
1512  return nPageNum;
1513 }
1514 
1516 {
1517  // For test purposes, use the new ViewContact for change
1518  // notification now.
1519  ActionChanged();
1521 }
1522 
1524 {
1525  return const_cast< SdrPage* >(this);
1526 }
1527 
1528 // MasterPage interface
1529 
1531 {
1532  if(mpMasterPageDescriptor && &(mpMasterPageDescriptor->GetUsedPage()) == &rNew)
1533  return;
1534 
1537 
1538  mpMasterPageDescriptor.reset(new sdr::MasterPageDescriptor(*this, rNew));
1540 }
1541 
1543 {
1545  {
1546  SetChanged();
1547 
1548  // the flushViewObjectContacts() will do needed invalidates by deleting the involved VOCs
1549  mpMasterPageDescriptor->GetUsedPage().GetViewContact().flushViewObjectContacts();
1550 
1551  mpMasterPageDescriptor.reset();
1552  }
1553 }
1554 
1556 {
1557  DBG_ASSERT(mpMasterPageDescriptor != nullptr, "TRG_GetMasterPage(): No MasterPage available. Use TRG_HasMasterPage() before access (!)");
1558  return mpMasterPageDescriptor->GetUsedPage();
1559 }
1560 
1562 {
1563  DBG_ASSERT(mpMasterPageDescriptor != nullptr, "TRG_GetMasterPageVisibleLayers(): No MasterPage available. Use TRG_HasMasterPage() before access (!)");
1564  return mpMasterPageDescriptor->GetVisibleLayers();
1565 }
1566 
1568 {
1569  DBG_ASSERT(mpMasterPageDescriptor != nullptr, "TRG_SetMasterPageVisibleLayers(): No MasterPage available. Use TRG_HasMasterPage() before access (!)");
1570  mpMasterPageDescriptor->SetVisibleLayers(rNew);
1571 }
1572 
1574 {
1575  DBG_ASSERT(mpMasterPageDescriptor != nullptr, "TRG_GetMasterPageDescriptorViewContact(): No MasterPage available. Use TRG_HasMasterPage() before access (!)");
1576  return mpMasterPageDescriptor->GetViewContact();
1577 }
1578 
1579 // used from SdrModel::RemoveMasterPage
1581 {
1582  if(TRG_HasMasterPage())
1583  {
1584  if(&TRG_GetMasterPage() == &rRemovedPage)
1585  {
1587  }
1588  }
1589 }
1590 
1592 {
1593  std::unordered_set<OUString> aNameSet;
1594  for (size_t no(0); no < GetObjCount(); ++no)
1595  {
1596  SdrObject* pObj(GetObj(no));
1597  if(nullptr != pObj)
1598  {
1599  if (!pObj->GetName().isEmpty())
1600  {
1601  pObj->MakeNameUnique(aNameSet);
1602  SdrObjList* pSdrObjList = pObj->GetSubList(); // group
1603  if (pSdrObjList)
1604  {
1605  SdrObject* pListObj;
1606  SdrObjListIter aIter(pSdrObjList, SdrIterMode::DeepWithGroups);
1607  while (aIter.IsMore())
1608  {
1609  pListObj = aIter.Next();
1610  pListObj->MakeNameUnique(aNameSet);
1611  }
1612  }
1613  }
1614  }
1615  }
1616 }
1617 
1618 const SdrPageGridFrameList* SdrPage::GetGridFrameList(const SdrPageView* /*pPV*/, const tools::Rectangle* /*pRect*/) const
1619 {
1620  return nullptr;
1621 }
1622 
1624 {
1625  return *mpLayerAdmin;
1626 }
1627 
1629 {
1630  return *mpLayerAdmin;
1631 }
1632 
1633 OUString SdrPage::GetLayoutName() const
1634 {
1635  return OUString();
1636 }
1637 
1638 void SdrPage::SetInserted( bool bIns )
1639 {
1640  if( mbInserted == bIns )
1641  return;
1642 
1643  mbInserted = bIns;
1644 
1645  // #i120437# go over whole hierarchy, not only over object level null (seen from grouping)
1647 
1648  while ( aIter.IsMore() )
1649  {
1650  SdrObject* pObj = aIter.Next();
1651  if ( auto pOleObj = dynamic_cast<SdrOle2Obj* >(pObj) )
1652  {
1653  if( mbInserted )
1654  pOleObj->Connect();
1655  else
1656  pOleObj->Disconnect();
1657  }
1658  }
1659 }
1660 
1661 void SdrPage::SetUnoPage(uno::Reference<drawing::XDrawPage> const& xNewPage)
1662 {
1663  mxUnoPage = xNewPage;
1664 }
1665 
1666 uno::Reference< uno::XInterface > const & SdrPage::getUnoPage()
1667 {
1668  if( !mxUnoPage.is() )
1669  {
1670  // create one
1672  }
1673 
1674  return mxUnoPage;
1675 }
1676 
1677 uno::Reference< uno::XInterface > SdrPage::createUnoPage()
1678 {
1679  css::uno::Reference< css::uno::XInterface > xInt =
1680  static_cast<cppu::OWeakObject*>( new SvxFmDrawPage( this ) );
1681  return xInt;
1682 }
1683 
1685 {
1686  return pObj->GetStyleSheet();
1687 }
1688 
1690 // #i75566# GetBackgroundColor -> GetPageBackgroundColor and bScreenDisplay hint value
1691 Color SdrPage::GetPageBackgroundColor( SdrPageView const * pView, bool bScreenDisplay ) const
1692 {
1693  Color aColor;
1694 
1695  if(bScreenDisplay && (!pView || pView->GetApplicationDocumentColor() == COL_AUTO))
1696  {
1697  svtools::ColorConfig aColorConfig;
1698  aColor = aColorConfig.GetColorValue( svtools::DOCCOLOR ).nColor;
1699  }
1700  else
1701  {
1702  aColor = pView->GetApplicationDocumentColor();
1703  }
1704 
1705  const SfxItemSet* pBackgroundFill = &getSdrPageProperties().GetItemSet();
1706 
1707  if(!IsMasterPage() && TRG_HasMasterPage())
1708  {
1709  if(drawing::FillStyle_NONE == pBackgroundFill->Get(XATTR_FILLSTYLE).GetValue())
1710  {
1711  pBackgroundFill = &TRG_GetMasterPage().getSdrPageProperties().GetItemSet();
1712  }
1713  }
1714 
1715  GetDraftFillColor(*pBackgroundFill, aColor);
1716 
1717  return aColor;
1718 }
1719 
1722 // #i75566# GetBackgroundColor -> GetPageBackgroundColor
1723 {
1724  return GetPageBackgroundColor( nullptr );
1725 }
1726 
1733  const sdr::contact::ViewObjectContact& /*rOriginal*/,
1734  const sdr::contact::DisplayInfo& /*rDisplayInfo*/,
1735  bool /*bEdit*/)
1736 {
1737  // this will be handled in the application if needed
1738  return true;
1739 }
1740 
1741 // DrawContact support: Methods for handling Page changes
1743 {
1744  // Do necessary ViewContact actions
1746 
1747  // #i48535# also handle MasterPage change
1748  if(TRG_HasMasterPage())
1749  {
1751  }
1752 }
1753 
1755 {
1756  return *mpSdrPageProperties;
1757 }
1758 
1760 {
1761  return *mpSdrPageProperties;
1762 }
1763 
1765 {
1767  {
1768  return mpMasterPageDescriptor->getCorrectSdrPageProperties();
1769  }
1770  else
1771  {
1772  return &getSdrPageProperties();
1773  }
1774 }
1775 
1776 
1777 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetUnoPage(css::uno::Reference< css::drawing::XDrawPage > const &)
Definition: svdpage.cxx:1661
SdrPage & TRG_GetMasterPage() const
Definition: svdpage.cxx:1555
void AddPageUser(sdr::PageUser &rNewUser)
Definition: svdpage.cxx:1077
double mnHeight
std::unique_ptr< sdr::MasterPageDescriptor > mpMasterPageDescriptor
Definition: svdpage.hxx:424
void SetNavigationPosition(const sal_uInt32 nPosition)
Definition: svdobj.cxx:847
::std::vector< PageUser * > PageUserVector
Definition: sdrpageuser.hxx:46
sal_Int32 mnWidth
Definition: svdpage.hxx:406
sal_Int32 nIndex
tools::Rectangle maSdrObjListOutRect
Definition: svdpage.hxx:69
void UnGroupObj(size_t nObjNum)
Ungroup the object at the given index.
Definition: svdpage.cxx:789
virtual void SetSize(const Size &aSiz)
Definition: svdpage.cxx:1339
SdrPageProperties(SdrPage &rSdrPage)
Definition: svdpage.cxx:1145
void NbcReformatAllTextObjects()
reformat all text objects, e.g. when changing printer
Definition: svdpage.cxx:703
virtual ~SdrObjList()
Definition: svdpage.cxx:125
virtual const tools::Rectangle & GetCurrentBoundRect() const
Definition: svdobj.cxx:857
Color GetPageBackgroundColor() const
deprecated returns an averaged background color of this page
Definition: svdpage.cxx:1721
sdr::PageUserVector maPageUsers
Definition: svdpage.hxx:381
struct _xmlTextWriter * xmlTextWriterPtr
sal_Int32 GetHeight() const
Definition: svdpage.cxx:1392
void ClearItem(const sal_uInt16 nWhich=0)
Definition: svdpage.cxx:1205
void impClearSdrObjList(bool bBroadcast)
Definition: svdpage.cxx:82
virtual void SetOrientation(Orientation eOri)
Definition: svdpage.cxx:1371
void ReplaceObjectInContainer(SdrObject &rObject, const sal_uInt32 nObjectPosition)
Replace an object in the object list.
Definition: svdpage.cxx:987
const tools::Rectangle & GetAllObjBoundRect() const
Definition: svdpage.cxx:688
virtual ViewContact * GetParentContact() const
virtual Orientation GetOrientation() const
Definition: svdpage.cxx:1383
bool mbObjOrdNumsDirty
Definition: svdpage.hxx:71
SdrPage(const SdrPage &)=delete
void PutItem(const SfxPoolItem &rItem)
Definition: svdpage.cxx:1198
void SetNavigationOrder(const css::uno::Reference< css::container::XIndexAccess > &rxOrder)
Set the navigation order to the one defined by the given list of XShape objects.
Definition: svdpage.cxx:932
sal_Int32 mnBorderRight
Definition: svdpage.hxx:410
virtual void SetLeftBorder(sal_Int32 nBorder)
Definition: svdpage.cxx:1431
static SdrObject * getSdrObjectFromXShape(const css::uno::Reference< css::uno::XInterface > &xInt)
Definition: unoshape.cxx:3995
virtual void NbcInsertObject(SdrObject *pObj, size_t nPos=SAL_MAX_SIZE)
Definition: svdpage.cxx:292
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: svdpage.cxx:1164
constexpr TypedWhichId< XFillStyleItem > XATTR_FILLSTYLE(XATTR_FILL_FIRST)
constexpr::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
sal_Int32 mnHeight
Definition: svdpage.hxx:407
SdrObject * GetObj(size_t nNum) const
Definition: svdpage.cxx:758
sal_Int32 GetRightBorder() const
Definition: svdpage.cxx:1477
void RecalcObjOrdNums()
recalculate order numbers / ZIndex
Definition: svdpage.cxx:244
bool IsInserted() const
Definition: svdobj.hxx:744
void RecalcPageNums(bool bMaster)
Definition: svdmodel.cxx:1266
size_t GetObjCount() const
Definition: svdpage.cxx:752
void MakePageObjectsNamesUnique()
Definition: svdpage.cxx:1591
SdrObject * GetObjectForNavigationPosition(const sal_uInt32 nNavigationPosition) const
Return the object for the given navigation position.
Definition: svdpage.cxx:876
void CopyObjects(const SdrObjList &rSrcList)
Definition: svdpage.cxx:143
virtual bool isUsedByModel() const override
Definition: svdpage.cxx:1184
bool mbRectsDirty
Definition: svdpage.hxx:72
void TRG_ClearMasterPage()
Definition: svdpage.cxx:1542
virtual SfxItemSet & GetItemSet()
static void Free(SdrObject *&_rpObject)
Definition: svdobj.cxx:396
virtual SdrObjKind GetObjIdentifier() const
Definition: svdobj.cxx:558
sal_Int32 GetLowerBorder() const
Definition: svdpage.cxx:1482
virtual void InsertObject(SdrObject *pObj, size_t nPos=SAL_MAX_SIZE)
Definition: svdpage.cxx:343
virtual css::uno::Reference< css::uno::XInterface > createUnoPage()
Definition: svdpage.cxx:1677
EmbeddedObjectRef * pObject
SVX_DLLPRIVATE void setParentOfSdrObject(SdrObjList *pNew)
Definition: svdobj.cxx:278
virtual bool checkVisibility(const sdr::contact::ViewObjectContact &rOriginal, const sdr::contact::DisplayInfo &rDisplayInfo, bool bEdit)
this method returns true if the object from the ViewObjectContact should be visible on this page whil...
Definition: svdpage.cxx:1732
void ImpAddStyleSheet(SfxStyleSheet &rNewStyleSheet)
Definition: svdpage.cxx:1126
virtual SdrObjList * GetSubList() const
Definition: svdobj.cxx:647
sal_Int32 GetLeftBorder() const
Definition: svdpage.cxx:1467
SfxHintId GetId() const
SfxStyleSheet * mpStyleSheet
Definition: svdpage.hxx:314
sdr::contact::ViewContact & GetViewContact() const
Definition: svdobj.cxx:245
void ConnectToNode(bool bTail1, SdrObject *pObj) override
Definition: svdoedge.cxx:448
virtual ~SdrPage() override
Definition: svdpage.cxx:1248
virtual const tools::Rectangle & GetSnapRect() const
Definition: svdobj.cxx:1610
bool IsEmpty() const
virtual bool IsReadOnly() const
linked page or linked group object
Definition: svdpage.cxx:764
void RemoveObjectFromContainer(const sal_uInt32 nObjectPosition)
Remove an object from the object list.
Definition: svdpage.cxx:1022
bool IsMore() const
Definition: svditer.hxx:62
SdrPage * getSdrPageFromSdrObject() const
Definition: svdobj.cxx:263
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
int nCount
css::uno::Reference< css::uno::XInterface > mxUnoPage
Definition: svdpage.hxx:415
bool mbInserted
Definition: svdpage.hxx:429
SfxStyleSheet * GetStyleSheet() const
Definition: svdobj.cxx:2149
virtual SdrPage * getSdrPageFromSdrObjList() const override
Definition: svdpage.cxx:1523
void MakeNameUnique()
Definition: svdobj.cxx:3008
std::unique_ptr< sdr::contact::ViewContact > CreateObjectSpecificViewContact()
Definition: svdpage.cxx:1094
void BurnInStyleSheetAttributes()
Definition: svdobj.cxx:1770
sal_Int32 mnBorderLeft
Definition: svdpage.hxx:408
sal_Int32 mnBorderUpper
Definition: svdpage.hxx:409
SvGenericNameContainerMapImpl maProperties
void ReformatAllTextObjects()
Definition: svdpage.cxx:719
void TRG_SetMasterPage(SdrPage &rNew)
Definition: svdpage.cxx:1530
virtual void SetChanged(bool bFlg=true)
Definition: svdmodel.cxx:1261
void RemovePageUser(sdr::PageUser &rOldUser)
Definition: svdpage.cxx:1082
const Color & GetApplicationDocumentColor() const
Definition: svdpagv.hxx:256
SdrObject * GetConnectedNode(bool bTail1) const override
Definition: svdoedge.cxx:472
void SetStyleSheet(SfxStyleSheet *pStyleSheet)
Definition: svdpage.cxx:1211
void ReformatAllEdgeObjects()
#103122# reformats all edge objects that are connected to other objects
Definition: svdpage.cxx:728
void SetPageNum(sal_uInt16 nNew)
Definition: svdpage.cxx:1488
#define DBG_UNHANDLED_EXCEPTION(...)
std::vector< SdrPageGridFrame * > aList
Definition: svdpage.hxx:292
Orientation
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
virtual const SdrPageGridFrameList * GetGridFrameList(const SdrPageView *pPV, const tools::Rectangle *pRect) const
for snap-to-grid in Writer, also for AlignObjects if 1 object is marked if pRect != null...
Definition: svdpage.cxx:1618
std::unique_ptr< SdrLayerAdmin > mpLayerAdmin
Definition: svdpage.hxx:413
SdrPage * mpSdrPage
Definition: svdpage.hxx:313
#define DBG_ASSERT(sCon, aError)
const sal_Int32 InitialObjectContainerCapacity(64)
int i
uno_Any a
bool mbMaster
Definition: svdpage.hxx:428
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: svdpage.cxx:1048
virtual SfxStyleSheet * GetTextStyleSheetForObject(SdrObject *pObj) const
Definition: svdpage.cxx:1684
const SdrLayerIDSet & TRG_GetMasterPageVisibleLayers() const
Definition: svdpage.cxx:1561
Size GetSize() const
Definition: svdpage.cxx:1361
sal_Int32 GetUpperBorder() const
Definition: svdpage.cxx:1472
void ActionChanged() const
Definition: svdobj.cxx:257
constexpr sal_uInt16 XATTR_FILL_FIRST(XATTRSET_LINE+1)
tools::Long Width() const
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
std::unique_ptr< std::vector< tools::WeakReference< SdrObject > > > mxNavigationOrder
This list, if it exists, defines the navigation order.
Definition: svdpage.hxx:231
virtual void SetUpperBorder(sal_Int32 nBorder)
Definition: svdpage.cxx:1440
static void ImpPageChange(SdrPage &rSdrPage)
Definition: svdpage.cxx:1137
SdrModel & getSdrModelFromSdrObject() const
Definition: svdobj.cxx:273
sal_uInt32 GetOrdNum() const
The order number (aka ZOrder, aka z-index) determines whether a SdrObject is located above or below a...
Definition: svdobj.cxx:799
const SdrLayerAdmin & GetLayerAdmin() const
changing the layers does not set the modified-flag!
Definition: svdpage.cxx:1623
size
bool HasObjectNavigationOrder() const
Return whether there is an explicit, user defined, object navigation order.
Definition: svdpage.cxx:824
bool IsMasterPage() const
Definition: svdpage.hxx:450
::std::vector< SdrObject * > maList
Definition: svdpage.hxx:67
const SfxItemSet & GetItemSet() const
Definition: svdpage.hxx:334
void Reformat()
updates edges that are connected to the edges of this object as if the connected objects send a repai...
Definition: svdoedge.cxx:1629
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
virtual OUString GetLayoutName() const
Definition: svdpage.cxx:1633
SdrPageProperties & getSdrPageProperties()
Definition: svdpage.cxx:1754
void InsertObjectThenMakeNameUnique(SdrObject *pObj)
Definition: svdpage.cxx:317
bool TRG_HasMasterPage() const
Definition: svdpage.hxx:484
virtual SdrObject * NbcRemoveObject(size_t nObjNum)
remove from list without delete
Definition: svdpage.cxx:382
void flushViewObjectContacts(bool bWithHierarchy=true)
virtual ~SdrPageProperties() override
Definition: svdpage.cxx:1159
Abstract DrawObject.
Definition: svdobj.hxx:261
virtual void ActionChanged()
virtual SdrObject * RemoveObject(size_t nObjNum)
Definition: svdpage.cxx:421
OUString GetName() const
Definition: svdobj.cxx:701
void ActionChildInserted(ViewContact &rChild)
sal_uInt16 GetCount() const
Definition: svdpage.hxx:302
const sal_uInt16 idx[]
void SetObjectNavigationPosition(SdrObject &rObject, const sal_uInt32 nNewNavigationPosition)
Set the navigation position of the given object to the specified value.
Definition: svdpage.cxx:826
void SetParent(const SfxItemSet *pNew)
virtual void SetRightBorder(sal_Int32 nBorder)
Definition: svdpage.cxx:1449
void lateInit(const SdrPage &rSrcPage)
Definition: svdpage.cxx:1284
virtual SdrPage * CloneSdrPage(SdrModel &rTargetModel) const
Definition: svdpage.cxx:1332
SdrPageGridFrame * GetObject(sal_uInt16 i) const
Definition: svdpage.hxx:296
sal_Int32 mnBorderLower
Definition: svdpage.hxx:411
SdrModel & getSdrModelFromSdrPage() const
Definition: svdpage.hxx:390
virtual void NbcReformatText()
Definition: svdobj.cxx:1766
virtual void SetLowerBorder(sal_Int32 nBorder)
Definition: svdpage.cxx:1458
SdrObject * Next()
Definition: svditer.hxx:63
void ActionChanged()
Definition: svdpage.cxx:1742
void InsertedStateChange()
Definition: svdobj.cxx:2545
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
void Broadcast(const SfxHint &rHint)
void SetInserted(bool bNew=true)
Definition: svdpage.cxx:1638
void sort(std::vector< sal_Int32 > &sortOrder)
Definition: svdpage.cxx:573
sdr::contact::ViewContact & TRG_GetMasterPageDescriptorViewContact() const
Definition: svdpage.cxx:1573
bool IsInserted() const
Definition: svdpage.hxx:452
void BurnInStyleSheetAttributes()
convert attributes of the style to hard formatting
Definition: svdpage.cxx:744
virtual SdrObject * ReplaceObject(SdrObject *pNewObj, size_t nObjNum)
Replace existing object by different one.
Definition: svdpage.cxx:477
void TRG_ImpMasterPageRemoved(const SdrPage &rRemovedPage)
Definition: svdpage.cxx:1580
ColorConfigValue GetColorValue(ColorConfigEntry eEntry, bool bSmart=true) const
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
tools::Rectangle & Union(const tools::Rectangle &rRect)
const sdr::contact::ViewContact & GetViewContact() const
Definition: svdpage.cxx:1099
bool RecalcNavigationPositions()
Set the navigation position of all SdrObjects to their position in the mxNavigationOrder list...
Definition: svdpage.cxx:911
void ClearSdrObjList()
Definition: svdpage.cxx:119
void SetOrdNum(sal_uInt32 nNum)
Definition: svdobj.cxx:812
SfxStyleSheet * GetStyleSheet() const
Definition: svdpage.hxx:341
css::uno::Reference< css::uno::XInterface > const & getUnoPage()
Definition: svdpage.cxx:1666
std::unique_ptr< sdr::contact::ViewContact > mpViewContact
Definition: svdpage.hxx:383
void ClearObjectNavigationOrder()
Restore the navigation order to that defined by the z-order.
Definition: svdpage.cxx:904
const SdrPageProperties * getCorrectSdrPageProperties() const
Definition: svdpage.cxx:1764
double mnWidth
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
tools::Long Height() const
virtual SdrPage * getSdrPageFromSdrObjList() const
Definition: svdpage.cxx:131
static void impChildInserted(SdrObject const &rChild)
simple ActionChildInserted forwarder to have it on a central place
Definition: svdpage.cxx:282
void SetSdrObjListRectsDirty()
Definition: svdpage.cxx:271
void TRG_SetMasterPageVisibleLayers(const SdrLayerIDSet &rNew)
Definition: svdpage.cxx:1567
const Point & GetAnchorPos() const
Definition: svdobj.cxx:1601
void InsertObjectIntoContainer(SdrObject &rObject, const sal_uInt32 nInsertPosition)
Insert an SdrObject into maList.
Definition: svdpage.cxx:961
virtual void SetRectsDirty(bool bNotMyself=false, bool bRecursive=true)
Definition: svdobj.cxx:435
SdrObjList()
Definition: svdpage.cxx:70
virtual void SetBorder(sal_Int32 nLft, sal_Int32 nUpp, sal_Int32 nRgt, sal_Int32 Lwr)
Definition: svdpage.cxx:1397
bool mbIsNavigationOrderDirty
This flag is when the mpNavigation list has been changed but the indices of the referenced Sdr...
Definition: svdpage.hxx:235
SfxItemSet maProperties
Definition: svdpage.hxx:315
bool mbObjectsNotPersistent
Definition: svdpage.hxx:430
virtual void NbcSetAnchorPos(const Point &rPnt)
Definition: svdobj.cxx:1583
void ImpRemoveStyleSheet()
Definition: svdpage.cxx:1116
bool mbPageBorderOnlyLeftRight
Definition: svdpage.hxx:433
virtual SdrObject * SetObjectOrdNum(size_t nOldObjNum, size_t nNewObjNum)
Modify ZOrder of an SdrObject.
Definition: svdpage.cxx:541
constexpr sal_uInt16 XATTR_FILL_LAST(XATTR_FILLBACKGROUND)
A SdrPage contains exactly one SdrObjList and a description of the physical page dimensions (size / m...
Definition: svdpage.hxx:365
OLE object.
Definition: svdobjkind.hxx:47
sal_Int32 GetWidth() const
Definition: svdpage.cxx:1366
SdrObjList * getParentSdrObjListFromSdrObject() const
Definition: svdobj.cxx:299
std::unique_ptr< SdrPageProperties > mpSdrPageProperties
Definition: svdpage.hxx:414
tools::Rectangle maSdrObjListSnapRect
Definition: svdpage.hxx:70
bool GetDraftFillColor(const SfxItemSet &rSet, Color &rCol)
Returns a replacement for an XFillStyle.
Definition: svdetc.cxx:236
sal_uInt16 GetPageNum() const
Definition: svdpage.cxx:1500
sal_uInt16 nPageNum
Definition: svdpage.hxx:426
const tools::Rectangle & GetAllObjSnapRect() const
Definition: svdpage.cxx:679
virtual SdrObject * getSdrObjectFromSdrObjList() const
Definition: svdpage.cxx:137
void SetChanged()
Definition: svdpage.cxx:1515
aStr
void RecalcRects()
Definition: svdpage.cxx:254
void PutItemSet(const SfxItemSet &rSet)
Definition: svdpage.cxx:1191
void FlattenGroups()
Makes the object list flat, i.e.
Definition: svdpage.cxx:782
void SetParentAtSdrObjectFromSdrObjList(SdrObject &rSdrObject, SdrObjList *pNew)
Definition: svdpage.cxx:63
Utility class SdrEdgeObj.
Definition: svdoedge.hxx:128