update dev300-m58
[ooovba.git] / svx / source / svdraw / svdmark.cxx
blob21eef709ef4accbff50af85a3801eee8a483f1fd
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svdmark.cxx,v $
10 * $Revision: 1.17 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 ////////////////////////////////////////////////////////////////////////////////////////////////////
36 #include <svx/svdmark.hxx>
37 #include <svx/svdetc.hxx>
38 #include <svx/svdobj.hxx>
39 #include <svx/svdpage.hxx>
40 #include "svditer.hxx"
41 #include <svx/svdpagv.hxx>
42 #include <svx/svdopath.hxx> // zur Abschaltung
43 #include <svx/svdogrp.hxx> // des Cache bei
44 #include <svx/svdorect.hxx> // GetMarkDescription
45 #include "svdstr.hrc" // Namen aus der Resource
46 #include "svdglob.hxx" // StringCache
48 ////////////////////////////////////////////////////////////////////////////////////////////////////
49 #include <svx/obj3d.hxx>
50 #include <svx/scene3d.hxx>
51 #include <svtools/brdcst.hxx>
52 #include <svx/svdoedge.hxx>
54 ////////////////////////////////////////////////////////////////////////////////////////////////////
56 class ImpSdrUShortContSorter: public ContainerSorter
58 public:
59 ImpSdrUShortContSorter(Container& rNewCont)
60 : ContainerSorter(rNewCont)
63 virtual int Compare(const void* pElem1, const void* pElem2) const;
66 int ImpSdrUShortContSorter::Compare(const void* pElem1, const void* pElem2) const
68 sal_uInt16 n1((sal_uInt16)((sal_uIntPtr)pElem1));
69 sal_uInt16 n2((sal_uInt16)((sal_uIntPtr)pElem2));
71 return ((n1 < n2) ? (-1) : (n1 > n2) ? (1) : (0));
74 void SdrUShortCont::Sort() const
76 ImpSdrUShortContSorter aSort(*((Container*)(&maArray)));
77 aSort.DoSort();
78 ((SdrUShortCont*)this)->mbSorted = sal_True;
80 ULONG nNum(GetCount());
82 if(nNum > 1)
84 nNum--;
85 sal_uInt16 nVal0 = GetObject(nNum);
87 while(nNum > 0)
89 nNum--;
90 sal_uInt16 nVal1 = GetObject(nNum);
92 if(nVal1 == nVal0)
94 ((SdrUShortCont*)this)->Remove(nNum);
97 nVal0 = nVal1;
102 void SdrUShortCont::CheckSort(ULONG nPos)
104 ULONG nAnz(maArray.Count());
106 if(nPos > nAnz)
107 nPos = nAnz;
109 sal_uInt16 nAktVal = GetObject(nPos);
111 if(nPos > 0)
113 sal_uInt16 nPrevVal = GetObject(nPos - 1);
115 if(nPrevVal >= nAktVal)
116 mbSorted = sal_False;
119 if(nPos < nAnz - 1)
121 sal_uInt16 nNextVal = GetObject(nPos + 1);
123 if(nNextVal <= nAktVal)
124 mbSorted = sal_False;
128 std::set< sal_uInt16 > SdrUShortCont::getContainer()
130 std::set< sal_uInt16 > aSet;
132 sal_uInt32 nAnz = maArray.Count();
133 while(nAnz)
134 aSet.insert( GetObject(--nAnz) );
136 return aSet;
139 ////////////////////////////////////////////////////////////////////////////////////////////////////
141 SdrMark::SdrMark(SdrObject* pNewObj, SdrPageView* pNewPageView)
142 : mpSelectedSdrObject(pNewObj),
143 mpPageView(pNewPageView),
144 mpPoints(0L),
145 mpLines(0L),
146 mpGluePoints(0L),
147 mbCon1(sal_False),
148 mbCon2(sal_False),
149 mnUser(0)
151 if(mpSelectedSdrObject)
153 mpSelectedSdrObject->AddObjectUser( *this );
157 SdrMark::SdrMark(const SdrMark& rMark)
158 : ObjectUser(),
159 mpSelectedSdrObject(0L),
160 mpPageView(0L),
161 mpPoints(0L),
162 mpLines(0L),
163 mpGluePoints(0L),
164 mbCon1(sal_False),
165 mbCon2(sal_False),
166 mnUser(0)
168 *this = rMark;
171 SdrMark::~SdrMark()
173 if(mpSelectedSdrObject)
175 mpSelectedSdrObject->RemoveObjectUser( *this );
178 if(mpPoints)
180 delete mpPoints;
183 if(mpLines)
185 delete mpLines;
188 if(mpGluePoints)
190 delete mpGluePoints;
194 void SdrMark::ObjectInDestruction(const SdrObject& rObject)
196 (void) rObject; // avoid warnings
197 OSL_ENSURE(mpSelectedSdrObject && mpSelectedSdrObject == &rObject, "SdrMark::ObjectInDestruction: called form object different from hosted one (!)");
198 OSL_ENSURE(mpSelectedSdrObject, "SdrMark::ObjectInDestruction: still seleceted SdrObject is deleted, deselect first (!)");
199 mpSelectedSdrObject = 0L;
202 void SdrMark::SetMarkedSdrObj(SdrObject* pNewObj)
204 if(mpSelectedSdrObject)
206 mpSelectedSdrObject->RemoveObjectUser( *this );
209 mpSelectedSdrObject = pNewObj;
211 if(mpSelectedSdrObject)
213 mpSelectedSdrObject->AddObjectUser( *this );
217 SdrObject* SdrMark::GetMarkedSdrObj() const
219 return mpSelectedSdrObject;
222 SdrMark& SdrMark::operator=(const SdrMark& rMark)
224 SetMarkedSdrObj(rMark.mpSelectedSdrObject);
225 mpPageView = rMark.mpPageView;
226 mbCon1 = rMark.mbCon1;
227 mbCon2 = rMark.mbCon2;
228 mnUser = rMark.mnUser;
230 if(!rMark.mpPoints)
232 if(mpPoints)
234 delete mpPoints;
235 mpPoints = 0L;
238 else
240 if(!mpPoints)
242 mpPoints = new SdrUShortCont(*rMark.mpPoints);
244 else
246 *mpPoints = *rMark.mpPoints;
250 if(!rMark.mpLines)
252 if(mpLines)
254 delete mpLines;
255 mpLines = 0L;
258 else
260 if(!mpLines)
262 mpLines = new SdrUShortCont(*rMark.mpLines);
264 else
266 *mpLines = *rMark.mpLines;
270 if(!rMark.mpGluePoints)
272 if(mpGluePoints)
274 delete mpGluePoints;
275 mpGluePoints = 0L;
278 else
280 if(!mpGluePoints)
282 mpGluePoints = new SdrUShortCont(*rMark.mpGluePoints);
284 else
286 *mpGluePoints = *rMark.mpGluePoints;
290 return *this;
293 sal_Bool SdrMark::operator==(const SdrMark& rMark) const
295 sal_Bool bRet(mpSelectedSdrObject == rMark.mpSelectedSdrObject && mpPageView == rMark.mpPageView && mbCon1 == rMark.mbCon1 && mbCon2 == rMark.mbCon2 && mnUser == rMark.mnUser);
297 if((mpPoints != 0L) != (rMark.mpPoints != 0L))
298 bRet = sal_False;
300 if((mpLines != 0L) != (rMark.mpLines != 0L))
301 bRet = sal_False;
303 if((mpGluePoints != 0L) != (rMark.mpGluePoints != 0L))
304 bRet = sal_False;
306 if(bRet && mpPoints && *mpPoints != *rMark.mpPoints)
307 bRet = sal_False;
309 if(bRet && mpLines && *mpLines != *rMark.mpLines)
310 bRet = sal_False;
312 if(bRet && mpGluePoints && *mpGluePoints != *rMark.mpGluePoints)
313 bRet = sal_False;
315 return bRet;
318 SdrPage* SdrMark::GetPage() const
320 return (mpSelectedSdrObject ? mpSelectedSdrObject->GetPage() : 0);
323 SdrObjList* SdrMark::GetObjList() const
325 return (mpSelectedSdrObject ? mpSelectedSdrObject->GetObjList() : 0);
328 ////////////////////////////////////////////////////////////////////////////////////////////////////
330 class ImpSdrMarkListSorter: public ContainerSorter
332 public:
333 ImpSdrMarkListSorter(Container& rNewCont)
334 : ContainerSorter(rNewCont)
337 virtual int Compare(const void* pElem1, const void* pElem2) const;
340 int ImpSdrMarkListSorter::Compare(const void* pElem1, const void* pElem2) const
342 SdrObject* pObj1 = ((SdrMark*)pElem1)->GetMarkedSdrObj();
343 SdrObject* pObj2 = ((SdrMark*)pElem2)->GetMarkedSdrObj();
344 SdrObjList* pOL1 = (pObj1) ? pObj1->GetObjList() : 0L;
345 SdrObjList* pOL2 = (pObj2) ? pObj2->GetObjList() : 0L;
347 if (pOL1 == pOL2)
349 // AF: Note that I reverted a change from sal_uInt32 to ULONG (made
350 // for 64bit compliance, #i78198#) because internally in SdrObject
351 // both nOrdNum and mnNavigationPosition are stored as sal_uInt32.
352 sal_uInt32 nObjOrd1((pObj1) ? pObj1->GetNavigationPosition() : 0);
353 sal_uInt32 nObjOrd2((pObj2) ? pObj2->GetNavigationPosition() : 0);
355 return (nObjOrd1 < nObjOrd2 ? -1 : 1);
357 else
359 return ((long)pOL1 < (long)pOL2) ? -1 : 1;
363 ////////////////////////////////////////////////////////////////////////////////////////////////////
365 void SdrMarkList::ForceSort() const
367 if(!mbSorted)
369 ((SdrMarkList*)this)->ImpForceSort();
373 void SdrMarkList::ImpForceSort()
375 if(!mbSorted)
377 mbSorted = sal_True;
378 ULONG nAnz = maList.Count();
380 // remove invalid
381 if(nAnz > 0 )
383 SdrMark* pAkt = (SdrMark*)maList.First();
384 while( pAkt )
386 if(pAkt->GetMarkedSdrObj() == 0)
388 maList.Remove();
389 delete pAkt;
391 pAkt= (SdrMark*)maList.Next();
393 nAnz = maList.Count();
396 if(nAnz > 1)
398 ImpSdrMarkListSorter aSort(maList);
399 aSort.DoSort();
401 // remove duplicates
402 if(maList.Count() > 1)
404 SdrMark* pAkt = (SdrMark*)maList.Last();
405 SdrMark* pCmp = (SdrMark*)maList.Prev();
407 while(pCmp)
409 if(pAkt->GetMarkedSdrObj() == pCmp->GetMarkedSdrObj() && pAkt->GetMarkedSdrObj())
411 // Con1/Con2 Merging
412 if(pCmp->IsCon1())
413 pAkt->SetCon1(sal_True);
415 if(pCmp->IsCon2())
416 pAkt->SetCon2(sal_True);
418 // pCmp loeschen.
419 maList.Remove();
421 delete pCmp;
423 else
425 pAkt = pCmp;
428 pCmp = (SdrMark*)maList.Prev();
435 void SdrMarkList::Clear()
437 for(ULONG i(0L); i < GetMarkCount(); i++)
439 SdrMark* pMark = GetMark(i);
440 delete pMark;
443 maList.Clear();
444 SetNameDirty();
447 void SdrMarkList::operator=(const SdrMarkList& rLst)
449 Clear();
451 for(ULONG i(0L); i < rLst.GetMarkCount(); i++)
453 SdrMark* pMark = rLst.GetMark(i);
454 SdrMark* pNeuMark = new SdrMark(*pMark);
455 maList.Insert(pNeuMark, CONTAINER_APPEND);
458 maMarkName = rLst.maMarkName;
459 mbNameOk = rLst.mbNameOk;
460 maPointName = rLst.maPointName;
461 mbPointNameOk = rLst.mbPointNameOk;
462 maGluePointName = rLst.maGluePointName;
463 mbGluePointNameOk = rLst.mbGluePointNameOk;
464 mbSorted = rLst.mbSorted;
467 ULONG SdrMarkList::FindObject(const SdrObject* pObj) const
469 // #109658#
471 // Since relying on OrdNums is not allowed for the selection because objects in the
472 // selection may not be inserted in a list if they are e.g. modified ATM, i changed
473 // this loop to just look if the object pointer is in the selection.
475 // Problem is that GetOrdNum() which is const, internally casts to non-const and
476 // hardly sets the OrdNum member of the object (nOrdNum) to 0 (ZERO) if the object
477 // is not inserted in a object list.
478 // Since this may be by purpose and necessary somewhere else i decided that it is
479 // less dangerous to change this method then changing SdrObject::GetOrdNum().
480 if(pObj && maList.Count())
482 for(ULONG a(0L); a < maList.Count(); a++)
484 if(((SdrMark*)(maList.GetObject(a)))->GetMarkedSdrObj() == pObj)
486 return a;
491 return CONTAINER_ENTRY_NOTFOUND;
494 void SdrMarkList::InsertEntry(const SdrMark& rMark, sal_Bool bChkSort)
496 SetNameDirty();
497 ULONG nAnz(maList.Count());
499 if(!bChkSort || !mbSorted || nAnz == 0)
501 if(!bChkSort)
502 mbSorted = sal_False;
504 maList.Insert(new SdrMark(rMark), CONTAINER_APPEND);
506 else
508 SdrMark* pLast = GetMark(ULONG(nAnz - 1));
509 const SdrObject* pLastObj = pLast->GetMarkedSdrObj();
510 const SdrObject* pNeuObj = rMark.GetMarkedSdrObj();
512 if(pLastObj == pNeuObj)
514 // Aha, den gibt's schon
515 // Con1/Con2 Merging
516 if(rMark.IsCon1())
517 pLast->SetCon1(sal_True);
519 if(rMark.IsCon2())
520 pLast->SetCon2(sal_True);
522 else
524 SdrMark* pKopie = new SdrMark(rMark);
525 maList.Insert(pKopie, CONTAINER_APPEND);
527 // und nun checken, ob die Sortierung noch ok ist
528 const SdrObjList* pLastOL = pLastObj!=0L ? pLastObj->GetObjList() : 0L;
529 const SdrObjList* pNeuOL = pNeuObj !=0L ? pNeuObj ->GetObjList() : 0L;
531 if(pLastOL == pNeuOL)
533 const ULONG nLastNum(pLastObj!=0L ? pLastObj->GetOrdNum() : 0);
534 const ULONG nNeuNum(pNeuObj !=0L ? pNeuObj ->GetOrdNum() : 0);
536 if(nNeuNum < nLastNum)
538 // irgendwann muss mal sortiert werden
539 mbSorted = sal_False;
542 else
544 // irgendwann muss mal sortiert werden
545 mbSorted = sal_False;
550 return;
553 void SdrMarkList::DeleteMark(ULONG nNum)
555 SdrMark* pMark = GetMark(nNum);
556 DBG_ASSERT(pMark!=0L,"DeleteMark: MarkEntry nicht gefunden");
558 if(pMark)
560 maList.Remove(nNum);
561 delete pMark;
562 SetNameDirty();
566 void SdrMarkList::ReplaceMark(const SdrMark& rNewMark, ULONG nNum)
568 SdrMark* pMark = GetMark(nNum);
569 DBG_ASSERT(pMark!=0L,"ReplaceMark: MarkEntry nicht gefunden");
571 if(pMark)
573 delete pMark;
574 SetNameDirty();
575 SdrMark* pKopie = new SdrMark(rNewMark);
576 maList.Replace(pKopie, nNum);
577 mbSorted = sal_False;
581 void SdrMarkList::Merge(const SdrMarkList& rSrcList, sal_Bool bReverse)
583 ULONG nAnz(rSrcList.maList.Count());
585 if(rSrcList.mbSorted)
587 // Merging ohne ein Sort bei rSrcList zu erzwingen
588 bReverse = sal_False;
591 if(!bReverse)
593 for(ULONG i(0L); i < nAnz; i++)
595 SdrMark* pM = (SdrMark*)(rSrcList.maList.GetObject(i));
596 InsertEntry(*pM);
599 else
601 for(ULONG i(nAnz); i > 0;)
603 i--;
604 SdrMark* pM = (SdrMark*)(rSrcList.maList.GetObject(i));
605 InsertEntry(*pM);
610 sal_Bool SdrMarkList::DeletePageView(const SdrPageView& rPV)
612 sal_Bool bChgd(sal_False);
614 for(ULONG i(GetMarkCount()); i > 0; )
616 i--;
617 SdrMark* pMark = GetMark(i);
619 if(pMark->GetPageView()==&rPV)
621 maList.Remove(i);
622 delete pMark;
623 SetNameDirty();
624 bChgd = sal_True;
628 return bChgd;
631 sal_Bool SdrMarkList::InsertPageView(const SdrPageView& rPV)
633 sal_Bool bChgd(sal_False);
634 DeletePageView(rPV); // erstmal alle raus, dann die ganze Seite hinten dran
635 SdrObject* pObj;
636 const SdrObjList* pOL = rPV.GetObjList();
637 ULONG nObjAnz(pOL->GetObjCount());
639 for(ULONG nO(0L); nO < nObjAnz; nO++)
641 pObj = pOL->GetObj(nO);
642 sal_Bool bDoIt(rPV.IsObjMarkable(pObj));
644 if(bDoIt)
646 SdrMark* pM = new SdrMark(pObj, (SdrPageView*)&rPV);
647 maList.Insert(pM, CONTAINER_APPEND);
648 SetNameDirty();
649 bChgd = sal_True;
653 return bChgd;
656 const XubString& SdrMarkList::GetMarkDescription() const
658 ULONG nAnz(GetMarkCount());
660 if(mbNameOk && 1L == nAnz)
662 // Bei Einfachselektion nur Textrahmen cachen
663 const SdrObject* pObj = GetMark(0)->GetMarkedSdrObj();
664 const SdrTextObj* pTextObj = PTR_CAST(SdrTextObj, pObj);
666 if(!pTextObj || !pTextObj->IsTextFrame())
668 ((SdrMarkList*)(this))->mbNameOk = sal_False;
672 if(!mbNameOk)
674 SdrMark* pMark = GetMark(0);
675 XubString aNam;
677 if(!nAnz)
679 ((SdrMarkList*)(this))->maMarkName = ImpGetResStr(STR_ObjNameNoObj);
681 else if(1L == nAnz)
683 if(pMark->GetMarkedSdrObj())
685 pMark->GetMarkedSdrObj()->TakeObjNameSingul(aNam);
688 else
690 if(pMark->GetMarkedSdrObj())
692 pMark->GetMarkedSdrObj()->TakeObjNamePlural(aNam);
693 XubString aStr1;
694 sal_Bool bEq(sal_True);
696 for(ULONG i = 1; i < GetMarkCount() && bEq; i++)
698 SdrMark* pMark2 = GetMark(i);
699 pMark2->GetMarkedSdrObj()->TakeObjNamePlural(aStr1);
700 bEq = aNam.Equals(aStr1);
703 if(!bEq)
705 aNam = ImpGetResStr(STR_ObjNamePlural);
709 aNam.Insert(sal_Unicode(' '), 0);
710 aNam.Insert(UniString::CreateFromInt32(nAnz), 0);
713 ((SdrMarkList*)(this))->maMarkName = aNam;
714 ((SdrMarkList*)(this))->mbNameOk = sal_True;
717 return maMarkName;
720 const XubString& SdrMarkList::GetPointMarkDescription(sal_Bool bGlue) const
722 sal_Bool& rNameOk = (sal_Bool&)(bGlue ? mbGluePointNameOk : mbPointNameOk);
723 XubString& rName = (XubString&)(bGlue ? maGluePointName : maPointName);
724 ULONG nMarkAnz(GetMarkCount());
725 ULONG nMarkPtAnz(0L);
726 ULONG nMarkPtObjAnz(0L);
727 ULONG n1stMarkNum(ULONG_MAX);
729 for(ULONG nMarkNum(0L); nMarkNum < nMarkAnz; nMarkNum++)
731 const SdrMark* pMark = GetMark(nMarkNum);
732 const SdrUShortCont* pPts = bGlue ? pMark->GetMarkedGluePoints() : pMark->GetMarkedPoints();
733 ULONG nAnz(pPts ? pPts->GetCount() : 0);
735 if(nAnz)
737 if(n1stMarkNum == ULONG_MAX)
739 n1stMarkNum = nMarkNum;
742 nMarkPtAnz += nAnz;
743 nMarkPtObjAnz++;
746 if(nMarkPtObjAnz > 1 && rNameOk)
748 // vorzeitige Entscheidung
749 return rName;
753 if(rNameOk && 1L == nMarkPtObjAnz)
755 // Bei Einfachselektion nur Textrahmen cachen
756 const SdrObject* pObj = GetMark(0)->GetMarkedSdrObj();
757 const SdrTextObj* pTextObj = PTR_CAST(SdrTextObj,pObj);
759 if(!pTextObj || !pTextObj->IsTextFrame())
761 rNameOk = sal_False;
765 if(!nMarkPtObjAnz)
767 rName.Erase();
768 rNameOk = sal_True;
770 else if(!rNameOk)
772 const SdrMark* pMark = GetMark(n1stMarkNum);
773 XubString aNam;
775 if(1L == nMarkPtObjAnz)
777 if(pMark->GetMarkedSdrObj())
779 pMark->GetMarkedSdrObj()->TakeObjNameSingul(aNam);
782 else
784 if(pMark->GetMarkedSdrObj())
786 pMark->GetMarkedSdrObj()->TakeObjNamePlural(aNam);
789 XubString aStr1;
790 sal_Bool bEq(sal_True);
792 for(ULONG i(n1stMarkNum + 1L); i < GetMarkCount() && bEq; i++)
794 const SdrMark* pMark2 = GetMark(i);
795 const SdrUShortCont* pPts = bGlue ? pMark2->GetMarkedGluePoints() : pMark2->GetMarkedPoints();
797 if(pPts && pPts->GetCount() && pMark2->GetMarkedSdrObj())
799 pMark2->GetMarkedSdrObj()->TakeObjNamePlural(aStr1);
800 bEq = aNam.Equals(aStr1);
804 if(!bEq)
806 aNam = ImpGetResStr(STR_ObjNamePlural);
809 aNam.Insert(sal_Unicode(' '), 0);
810 aNam.Insert(UniString::CreateFromInt32(nMarkPtObjAnz), 0);
813 XubString aStr1;
815 if(1L == nMarkPtAnz)
817 aStr1 = (ImpGetResStr(bGlue ? STR_ViewMarkedGluePoint : STR_ViewMarkedPoint));
819 else
821 aStr1 = (ImpGetResStr(bGlue ? STR_ViewMarkedGluePoints : STR_ViewMarkedPoints));
822 aStr1.SearchAndReplaceAscii("%2", UniString::CreateFromInt32(nMarkPtAnz));
825 aStr1.SearchAndReplaceAscii("%1", aNam);
826 rName = aStr1;
827 rNameOk = sal_True;
830 return rName;
833 sal_Bool SdrMarkList::TakeBoundRect(SdrPageView* pPV, Rectangle& rRect) const
835 sal_Bool bFnd(sal_False);
836 Rectangle aR;
838 for(ULONG i(0L); i < GetMarkCount(); i++)
840 SdrMark* pMark = GetMark(i);
842 if(!pPV || pMark->GetPageView() == pPV)
844 if(pMark->GetMarkedSdrObj())
846 aR = pMark->GetMarkedSdrObj()->GetCurrentBoundRect();
848 if(bFnd)
850 rRect.Union(aR);
852 else
854 rRect = aR;
855 bFnd = sal_True;
861 return bFnd;
864 sal_Bool SdrMarkList::TakeSnapRect(SdrPageView* pPV, Rectangle& rRect) const
866 sal_Bool bFnd(sal_False);
868 for(ULONG i(0L); i < GetMarkCount(); i++)
870 SdrMark* pMark = GetMark(i);
872 if(!pPV || pMark->GetPageView() == pPV)
874 if(pMark->GetMarkedSdrObj())
876 Rectangle aR(pMark->GetMarkedSdrObj()->GetSnapRect());
878 if(bFnd)
880 rRect.Union(aR);
882 else
884 rRect = aR;
885 bFnd = sal_True;
891 return bFnd;
894 ////////////////////////////////////////////////////////////////////////////////////////////////////
896 namespace sdr
898 ViewSelection::ViewSelection()
899 : mbEdgesOfMarkedNodesDirty(sal_False)
903 void ViewSelection::SetEdgesOfMarkedNodesDirty()
905 if(!mbEdgesOfMarkedNodesDirty)
907 mbEdgesOfMarkedNodesDirty = sal_True;
908 maEdgesOfMarkedNodes.Clear();
909 maMarkedEdgesOfMarkedNodes.Clear();
910 maAllMarkedObjects.Clear();
914 const SdrMarkList& ViewSelection::GetEdgesOfMarkedNodes() const
916 if(mbEdgesOfMarkedNodesDirty)
918 ((ViewSelection*)this)->ImpForceEdgesOfMarkedNodes();
921 return maEdgesOfMarkedNodes;
924 const SdrMarkList& ViewSelection::GetMarkedEdgesOfMarkedNodes() const
926 if(mbEdgesOfMarkedNodesDirty)
928 ((ViewSelection*)this)->ImpForceEdgesOfMarkedNodes();
931 return maMarkedEdgesOfMarkedNodes;
934 const List& ViewSelection::GetAllMarkedObjects() const
936 if(mbEdgesOfMarkedNodesDirty)
938 ((ViewSelection*)this)->ImpForceEdgesOfMarkedNodes();
941 return maAllMarkedObjects;
944 void ViewSelection::ImplCollectCompleteSelection(SdrObject* pObj)
946 if(pObj)
948 sal_Bool bIsGroup(pObj->IsGroupObject());
950 if(bIsGroup && pObj->ISA(E3dObject) && !pObj->ISA(E3dScene))
952 bIsGroup = sal_False;
955 if(bIsGroup)
957 SdrObjList* pList = pObj->GetSubList();
959 for(ULONG a(0L); a < pList->GetObjCount(); a++)
961 SdrObject* pObj2 = pList->GetObj(a);
962 ImplCollectCompleteSelection(pObj2);
966 maAllMarkedObjects.Insert(pObj, LIST_APPEND);
970 void ViewSelection::ImpForceEdgesOfMarkedNodes()
972 if(mbEdgesOfMarkedNodesDirty)
974 mbEdgesOfMarkedNodesDirty = sal_False;
975 maMarkedObjectList.ForceSort();
976 maEdgesOfMarkedNodes.Clear();
977 maMarkedEdgesOfMarkedNodes.Clear();
978 maAllMarkedObjects.Clear();
980 // #126320# GetMarkCount after ForceSort
981 const ULONG nMarkAnz(maMarkedObjectList.GetMarkCount());
983 for(ULONG a(0L); a < nMarkAnz; a++)
985 SdrObject* pCandidate = maMarkedObjectList.GetMark(a)->GetMarkedSdrObj();
987 if(pCandidate)
989 // build transitive hull
990 ImplCollectCompleteSelection(pCandidate);
992 if(pCandidate->IsNode())
994 // travel over broadcaster/listener to access edges connected to the selected object
995 const SfxBroadcaster* pBC = pCandidate->GetBroadcaster();
997 if(pBC)
999 sal_uInt16 nLstAnz(pBC->GetListenerCount());
1001 for(sal_uInt16 nl(0); nl < nLstAnz; nl++)
1003 SfxListener* pLst = pBC->GetListener(nl);
1004 SdrEdgeObj* pEdge = PTR_CAST(SdrEdgeObj, pLst);
1006 if(pEdge && pEdge->IsInserted() && pEdge->GetPage() == pCandidate->GetPage())
1008 SdrMark aM(pEdge, maMarkedObjectList.GetMark(a)->GetPageView());
1010 if(pEdge->GetConnectedNode(sal_True) == pCandidate)
1012 aM.SetCon1(sal_True);
1015 if(pEdge->GetConnectedNode(sal_False) == pCandidate)
1017 aM.SetCon2(sal_True);
1020 if(CONTAINER_ENTRY_NOTFOUND == maMarkedObjectList.FindObject(pEdge))
1022 // nachsehen, ob er selbst markiert ist
1023 maEdgesOfMarkedNodes.InsertEntry(aM);
1025 else
1027 maMarkedEdgesOfMarkedNodes.InsertEntry(aM);
1036 maEdgesOfMarkedNodes.ForceSort();
1037 maMarkedEdgesOfMarkedNodes.ForceSort();
1040 } // end of namespace sdr
1042 ////////////////////////////////////////////////////////////////////////////////////////////////////
1043 // eof