1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_svx.hxx"
24
25 #include <svx/svdmark.hxx>
26 #include <svx/svdetc.hxx>
27 #include <svx/svdobj.hxx>
28 #include <svx/svdpage.hxx>
29 #include "svx/svditer.hxx"
30 #include <svx/svdpagv.hxx>
31 #include <svx/svdopath.hxx> // zur Abschaltung
32 #include <svx/svdogrp.hxx> // des Cache bei
33 #include <svx/svdorect.hxx> // GetMarkDescription
34 #include "svx/svdstr.hrc" // Names from resource
35 #include "svx/svdglob.hxx" // StringCache
36
37 #include <svx/obj3d.hxx>
38 #include <svx/scene3d.hxx>
39 #include <svl/brdcst.hxx>
40 #include <svx/svdoedge.hxx>
41
42 class ImpSdrUShortContSorter: public ContainerSorter
43 {
44 public:
ImpSdrUShortContSorter(Container & rNewCont)45 ImpSdrUShortContSorter(Container& rNewCont)
46 : ContainerSorter(rNewCont)
47 {}
48
49 virtual int Compare(const void* pElem1, const void* pElem2) const;
50 };
51
Compare(const void * pElem1,const void * pElem2) const52 int ImpSdrUShortContSorter::Compare(const void* pElem1, const void* pElem2) const
53 {
54 sal_uInt16 n1((sal_uInt16)((sal_uIntPtr)pElem1));
55 sal_uInt16 n2((sal_uInt16)((sal_uIntPtr)pElem2));
56
57 return ((n1 < n2) ? (-1) : (n1 > n2) ? (1) : (0));
58 }
59
Sort() const60 void SdrUShortCont::Sort() const
61 {
62 ImpSdrUShortContSorter aSort(*((Container*)(&maArray)));
63 aSort.DoSort();
64 ((SdrUShortCont*)this)->mbSorted = sal_True;
65
66 sal_uLong nNum(GetCount());
67
68 if(nNum > 1)
69 {
70 nNum--;
71 sal_uInt16 nVal0 = GetObject(nNum);
72
73 while(nNum > 0)
74 {
75 nNum--;
76 sal_uInt16 nVal1 = GetObject(nNum);
77
78 if(nVal1 == nVal0)
79 {
80 ((SdrUShortCont*)this)->Remove(nNum);
81 }
82
83 nVal0 = nVal1;
84 }
85 }
86 }
87
CheckSort(sal_uLong nPos)88 void SdrUShortCont::CheckSort(sal_uLong nPos)
89 {
90 sal_uLong nAnz(maArray.Count());
91
92 if(nPos > nAnz)
93 nPos = nAnz;
94
95 sal_uInt16 nAktVal = GetObject(nPos);
96
97 if(nPos > 0)
98 {
99 sal_uInt16 nPrevVal = GetObject(nPos - 1);
100
101 if(nPrevVal >= nAktVal)
102 mbSorted = sal_False;
103 }
104
105 if(nPos < nAnz - 1)
106 {
107 sal_uInt16 nNextVal = GetObject(nPos + 1);
108
109 if(nNextVal <= nAktVal)
110 mbSorted = sal_False;
111 }
112 }
113
getContainer()114 std::set< sal_uInt16 > SdrUShortCont::getContainer()
115 {
116 std::set< sal_uInt16 > aSet;
117
118 sal_uInt32 nAnz = maArray.Count();
119 while(nAnz)
120 aSet.insert( GetObject(--nAnz) );
121
122 return aSet;
123 }
124
125 ////////////////////////////////////////////////////////////////////////////////////////////////////
126
SdrMark(SdrObject * pNewObj,SdrPageView * pNewPageView)127 SdrMark::SdrMark(SdrObject* pNewObj, SdrPageView* pNewPageView)
128 : mpSelectedSdrObject(pNewObj),
129 mpPageView(pNewPageView),
130 mpPoints(0L),
131 mpLines(0L),
132 mpGluePoints(0L),
133 mbCon1(sal_False),
134 mbCon2(sal_False),
135 mnUser(0)
136 {
137 if(mpSelectedSdrObject)
138 {
139 mpSelectedSdrObject->AddObjectUser( *this );
140 }
141 }
142
SdrMark(const SdrMark & rMark)143 SdrMark::SdrMark(const SdrMark& rMark)
144 : ObjectUser(),
145 mpSelectedSdrObject(0L),
146 mpPageView(0L),
147 mpPoints(0L),
148 mpLines(0L),
149 mpGluePoints(0L),
150 mbCon1(sal_False),
151 mbCon2(sal_False),
152 mnUser(0)
153 {
154 *this = rMark;
155 }
156
~SdrMark()157 SdrMark::~SdrMark()
158 {
159 if(mpSelectedSdrObject)
160 {
161 mpSelectedSdrObject->RemoveObjectUser( *this );
162 }
163
164 if(mpPoints)
165 {
166 delete mpPoints;
167 }
168
169 if(mpLines)
170 {
171 delete mpLines;
172 }
173
174 if(mpGluePoints)
175 {
176 delete mpGluePoints;
177 }
178 }
179
ObjectInDestruction(const SdrObject & rObject)180 void SdrMark::ObjectInDestruction(const SdrObject& rObject)
181 {
182 (void) rObject; // avoid warnings
183 OSL_ENSURE(mpSelectedSdrObject && mpSelectedSdrObject == &rObject, "SdrMark::ObjectInDestruction: called form object different from hosted one (!)");
184 OSL_ENSURE(mpSelectedSdrObject, "SdrMark::ObjectInDestruction: still selected SdrObject is deleted, deselect first (!)");
185 mpSelectedSdrObject = 0L;
186 }
187
SetMarkedSdrObj(SdrObject * pNewObj)188 void SdrMark::SetMarkedSdrObj(SdrObject* pNewObj)
189 {
190 if(mpSelectedSdrObject)
191 {
192 mpSelectedSdrObject->RemoveObjectUser( *this );
193 }
194
195 mpSelectedSdrObject = pNewObj;
196
197 if(mpSelectedSdrObject)
198 {
199 mpSelectedSdrObject->AddObjectUser( *this );
200 }
201 }
202
GetMarkedSdrObj() const203 SdrObject* SdrMark::GetMarkedSdrObj() const
204 {
205 return mpSelectedSdrObject;
206 }
207
operator =(const SdrMark & rMark)208 SdrMark& SdrMark::operator=(const SdrMark& rMark)
209 {
210 SetMarkedSdrObj(rMark.mpSelectedSdrObject);
211 mpPageView = rMark.mpPageView;
212 mbCon1 = rMark.mbCon1;
213 mbCon2 = rMark.mbCon2;
214 mnUser = rMark.mnUser;
215
216 if(!rMark.mpPoints)
217 {
218 if(mpPoints)
219 {
220 delete mpPoints;
221 mpPoints = 0L;
222 }
223 }
224 else
225 {
226 if(!mpPoints)
227 {
228 mpPoints = new SdrUShortCont(*rMark.mpPoints);
229 }
230 else
231 {
232 *mpPoints = *rMark.mpPoints;
233 }
234 }
235
236 if(!rMark.mpLines)
237 {
238 if(mpLines)
239 {
240 delete mpLines;
241 mpLines = 0L;
242 }
243 }
244 else
245 {
246 if(!mpLines)
247 {
248 mpLines = new SdrUShortCont(*rMark.mpLines);
249 }
250 else
251 {
252 *mpLines = *rMark.mpLines;
253 }
254 }
255
256 if(!rMark.mpGluePoints)
257 {
258 if(mpGluePoints)
259 {
260 delete mpGluePoints;
261 mpGluePoints = 0L;
262 }
263 }
264 else
265 {
266 if(!mpGluePoints)
267 {
268 mpGluePoints = new SdrUShortCont(*rMark.mpGluePoints);
269 }
270 else
271 {
272 *mpGluePoints = *rMark.mpGluePoints;
273 }
274 }
275
276 return *this;
277 }
278
operator ==(const SdrMark & rMark) const279 sal_Bool SdrMark::operator==(const SdrMark& rMark) const
280 {
281 sal_Bool bRet(mpSelectedSdrObject == rMark.mpSelectedSdrObject && mpPageView == rMark.mpPageView && mbCon1 == rMark.mbCon1 && mbCon2 == rMark.mbCon2 && mnUser == rMark.mnUser);
282
283 if((mpPoints != 0L) != (rMark.mpPoints != 0L))
284 bRet = sal_False;
285
286 if((mpLines != 0L) != (rMark.mpLines != 0L))
287 bRet = sal_False;
288
289 if((mpGluePoints != 0L) != (rMark.mpGluePoints != 0L))
290 bRet = sal_False;
291
292 if(bRet && mpPoints && *mpPoints != *rMark.mpPoints)
293 bRet = sal_False;
294
295 if(bRet && mpLines && *mpLines != *rMark.mpLines)
296 bRet = sal_False;
297
298 if(bRet && mpGluePoints && *mpGluePoints != *rMark.mpGluePoints)
299 bRet = sal_False;
300
301 return bRet;
302 }
303
GetPage() const304 SdrPage* SdrMark::GetPage() const
305 {
306 return (mpSelectedSdrObject ? mpSelectedSdrObject->GetPage() : 0);
307 }
308
GetObjList() const309 SdrObjList* SdrMark::GetObjList() const
310 {
311 return (mpSelectedSdrObject ? mpSelectedSdrObject->GetObjList() : 0);
312 }
313
314 ////////////////////////////////////////////////////////////////////////////////////////////////////
315
316 class ImpSdrMarkListSorter: public ContainerSorter
317 {
318 public:
ImpSdrMarkListSorter(Container & rNewCont)319 ImpSdrMarkListSorter(Container& rNewCont)
320 : ContainerSorter(rNewCont)
321 {}
322
323 virtual int Compare(const void* pElem1, const void* pElem2) const;
324 };
325
Compare(const void * pElem1,const void * pElem2) const326 int ImpSdrMarkListSorter::Compare(const void* pElem1, const void* pElem2) const
327 {
328 SdrObject* pObj1 = ((SdrMark*)pElem1)->GetMarkedSdrObj();
329 SdrObject* pObj2 = ((SdrMark*)pElem2)->GetMarkedSdrObj();
330 SdrObjList* pOL1 = (pObj1) ? pObj1->GetObjList() : 0L;
331 SdrObjList* pOL2 = (pObj2) ? pObj2->GetObjList() : 0L;
332
333 if (pOL1 == pOL2)
334 {
335 // AF: Note that I reverted a change from sal_uInt32 to sal_uLong (made
336 // for 64bit compliance, #i78198#) because internally in SdrObject
337 // both nOrdNum and mnNavigationPosition are stored as sal_uInt32.
338 sal_uInt32 nObjOrd1((pObj1) ? pObj1->GetNavigationPosition() : 0);
339 sal_uInt32 nObjOrd2((pObj2) ? pObj2->GetNavigationPosition() : 0);
340
341 return (nObjOrd1 < nObjOrd2 ? -1 : 1);
342 }
343 else
344 {
345 return ((long)pOL1 < (long)pOL2) ? -1 : 1;
346 }
347 }
348
349 ////////////////////////////////////////////////////////////////////////////////////////////////////
350
ForceSort() const351 void SdrMarkList::ForceSort() const
352 {
353 if(!mbSorted)
354 {
355 ((SdrMarkList*)this)->ImpForceSort();
356 }
357 }
358
ImpForceSort()359 void SdrMarkList::ImpForceSort()
360 {
361 if(!mbSorted)
362 {
363 mbSorted = sal_True;
364 sal_uLong nAnz = maList.Count();
365
366 // remove invalid
367 if(nAnz > 0 )
368 {
369 SdrMark* pAkt = (SdrMark*)maList.First();
370 while( pAkt )
371 {
372 if(pAkt->GetMarkedSdrObj() == 0)
373 {
374 maList.Remove();
375 delete pAkt;
376 }
377 pAkt= (SdrMark*)maList.Next();
378 }
379 nAnz = maList.Count();
380 }
381
382 if(nAnz > 1)
383 {
384 ImpSdrMarkListSorter aSort(maList);
385 aSort.DoSort();
386
387 // remove duplicates
388 if(maList.Count() > 1)
389 {
390 SdrMark* pAkt = (SdrMark*)maList.Last();
391 SdrMark* pCmp = (SdrMark*)maList.Prev();
392
393 while(pCmp)
394 {
395 if(pAkt->GetMarkedSdrObj() == pCmp->GetMarkedSdrObj() && pAkt->GetMarkedSdrObj())
396 {
397 // Con1/Con2 Merging
398 if(pCmp->IsCon1())
399 pAkt->SetCon1(sal_True);
400
401 if(pCmp->IsCon2())
402 pAkt->SetCon2(sal_True);
403
404 // pCmp loeschen.
405 maList.Remove();
406
407 delete pCmp;
408 }
409 else
410 {
411 pAkt = pCmp;
412 }
413
414 pCmp = (SdrMark*)maList.Prev();
415 }
416 }
417 }
418 }
419 }
420
Clear()421 void SdrMarkList::Clear()
422 {
423 for(sal_uLong i(0L); i < GetMarkCount(); i++)
424 {
425 SdrMark* pMark = GetMark(i);
426 delete pMark;
427 }
428
429 maList.Clear();
430 SetNameDirty();
431 }
432
operator =(const SdrMarkList & rLst)433 void SdrMarkList::operator=(const SdrMarkList& rLst)
434 {
435 Clear();
436
437 for(sal_uLong i(0L); i < rLst.GetMarkCount(); i++)
438 {
439 SdrMark* pMark = rLst.GetMark(i);
440 SdrMark* pNeuMark = new SdrMark(*pMark);
441 maList.Insert(pNeuMark, CONTAINER_APPEND);
442 }
443
444 maMarkName = rLst.maMarkName;
445 mbNameOk = rLst.mbNameOk;
446 maPointName = rLst.maPointName;
447 mbPointNameOk = rLst.mbPointNameOk;
448 maGluePointName = rLst.maGluePointName;
449 mbGluePointNameOk = rLst.mbGluePointNameOk;
450 mbSorted = rLst.mbSorted;
451 }
452
FindObject(const SdrObject * pObj) const453 sal_uLong SdrMarkList::FindObject(const SdrObject* pObj) const
454 {
455 // #109658#
456 //
457 // Since relying on OrdNums is not allowed for the selection because objects in the
458 // selection may not be inserted in a list if they are e.g. modified ATM, i changed
459 // this loop to just look if the object pointer is in the selection.
460 //
461 // Problem is that GetOrdNum() which is const, internally casts to non-const and
462 // hardly sets the OrdNum member of the object (nOrdNum) to 0 (ZERO) if the object
463 // is not inserted in a object list.
464 // Since this may be by purpose and necessary somewhere else i decided that it is
465 // less dangerous to change this method then changing SdrObject::GetOrdNum().
466 if(pObj && maList.Count())
467 {
468 for(sal_uLong a(0L); a < maList.Count(); a++)
469 {
470 if(((SdrMark*)(maList.GetObject(a)))->GetMarkedSdrObj() == pObj)
471 {
472 return a;
473 }
474 }
475 }
476
477 return CONTAINER_ENTRY_NOTFOUND;
478 }
479
InsertEntry(const SdrMark & rMark,sal_Bool bChkSort)480 void SdrMarkList::InsertEntry(const SdrMark& rMark, sal_Bool bChkSort)
481 {
482 SetNameDirty();
483 sal_uLong nAnz(maList.Count());
484
485 if(!bChkSort || !mbSorted || nAnz == 0)
486 {
487 if(!bChkSort)
488 mbSorted = sal_False;
489
490 maList.Insert(new SdrMark(rMark), CONTAINER_APPEND);
491 }
492 else
493 {
494 SdrMark* pLast = GetMark(sal_uLong(nAnz - 1));
495 const SdrObject* pLastObj = pLast->GetMarkedSdrObj();
496 const SdrObject* pNewObj = rMark.GetMarkedSdrObj();
497
498 if(pLastObj == pNewObj)
499 {
500 // Aha, den gibt es schon
501 // Con1/Con2 Merging
502 if(rMark.IsCon1())
503 pLast->SetCon1(sal_True);
504
505 if(rMark.IsCon2())
506 pLast->SetCon2(sal_True);
507 }
508 else
509 {
510 SdrMark* pKopie = new SdrMark(rMark);
511 maList.Insert(pKopie, CONTAINER_APPEND);
512
513 // und nun checken, ob die Sortierung noch ok ist
514 const SdrObjList* pLastOL = pLastObj!=0L ? pLastObj->GetObjList() : 0L;
515 const SdrObjList* pNeuOL = pNewObj !=0L ? pNewObj ->GetObjList() : 0L;
516
517 if(pLastOL == pNeuOL)
518 {
519 const sal_uLong nLastNum(pLastObj!=0L ? pLastObj->GetOrdNum() : 0);
520 const sal_uLong nNewNum(pNewObj !=0L ? pNewObj ->GetOrdNum() : 0);
521
522 if(nNewNum < nLastNum)
523 {
524 // irgendwann muss mal sortiert werden
525 mbSorted = sal_False;
526 }
527 }
528 else
529 {
530 // irgendwann muss mal sortiert werden
531 mbSorted = sal_False;
532 }
533 }
534 }
535
536 return;
537 }
538
DeleteMark(sal_uLong nNum)539 void SdrMarkList::DeleteMark(sal_uLong nNum)
540 {
541 SdrMark* pMark = GetMark(nNum);
542 DBG_ASSERT(pMark!=0L,"DeleteMark: MarkEntry nicht gefunden");
543
544 if(pMark)
545 {
546 maList.Remove(nNum);
547 delete pMark;
548 SetNameDirty();
549 }
550 }
551
ReplaceMark(const SdrMark & rNewMark,sal_uLong nNum)552 void SdrMarkList::ReplaceMark(const SdrMark& rNewMark, sal_uLong nNum)
553 {
554 SdrMark* pMark = GetMark(nNum);
555 DBG_ASSERT(pMark!=0L,"ReplaceMark: MarkEntry not found");
556
557 if(pMark)
558 {
559 delete pMark;
560 SetNameDirty();
561 SdrMark* pKopie = new SdrMark(rNewMark);
562 maList.Replace(pKopie, nNum);
563 mbSorted = sal_False;
564 }
565 }
566
Merge(const SdrMarkList & rSrcList,sal_Bool bReverse)567 void SdrMarkList::Merge(const SdrMarkList& rSrcList, sal_Bool bReverse)
568 {
569 sal_uLong nAnz(rSrcList.maList.Count());
570
571 if(rSrcList.mbSorted)
572 {
573 // Merging ohne ein Sort bei rSrcList zu erzwingen
574 bReverse = sal_False;
575 }
576
577 if(!bReverse)
578 {
579 for(sal_uLong i(0L); i < nAnz; i++)
580 {
581 SdrMark* pM = (SdrMark*)(rSrcList.maList.GetObject(i));
582 InsertEntry(*pM);
583 }
584 }
585 else
586 {
587 for(sal_uLong i(nAnz); i > 0;)
588 {
589 i--;
590 SdrMark* pM = (SdrMark*)(rSrcList.maList.GetObject(i));
591 InsertEntry(*pM);
592 }
593 }
594 }
595
DeletePageView(const SdrPageView & rPV)596 sal_Bool SdrMarkList::DeletePageView(const SdrPageView& rPV)
597 {
598 sal_Bool bChgd(sal_False);
599
600 for(sal_uLong i(GetMarkCount()); i > 0; )
601 {
602 i--;
603 SdrMark* pMark = GetMark(i);
604
605 if(pMark->GetPageView()==&rPV)
606 {
607 maList.Remove(i);
608 delete pMark;
609 SetNameDirty();
610 bChgd = sal_True;
611 }
612 }
613
614 return bChgd;
615 }
616
InsertPageView(const SdrPageView & rPV)617 sal_Bool SdrMarkList::InsertPageView(const SdrPageView& rPV)
618 {
619 sal_Bool bChgd(sal_False);
620 DeletePageView(rPV); // erstmal alle raus, dann die ganze Seite hinten dran
621 SdrObject* pObj;
622 const SdrObjList* pOL = rPV.GetObjList();
623 sal_uLong nObjAnz(pOL->GetObjCount());
624
625 for(sal_uLong nO(0L); nO < nObjAnz; nO++)
626 {
627 pObj = pOL->GetObj(nO);
628 sal_Bool bDoIt(rPV.IsObjMarkable(pObj));
629
630 if(bDoIt)
631 {
632 SdrMark* pM = new SdrMark(pObj, (SdrPageView*)&rPV);
633 maList.Insert(pM, CONTAINER_APPEND);
634 SetNameDirty();
635 bChgd = sal_True;
636 }
637 }
638
639 return bChgd;
640 }
641
GetMarkDescription() const642 const XubString& SdrMarkList::GetMarkDescription() const
643 {
644 sal_uLong nAnz(GetMarkCount());
645
646 if(mbNameOk && 1L == nAnz)
647 {
648 // Bei Einfachselektion nur Textrahmen cachen
649 const SdrObject* pObj = GetMark(0)->GetMarkedSdrObj();
650 const SdrTextObj* pTextObj = PTR_CAST(SdrTextObj, pObj);
651
652 if(!pTextObj || !pTextObj->IsTextFrame())
653 {
654 ((SdrMarkList*)(this))->mbNameOk = sal_False;
655 }
656 }
657
658 if(!mbNameOk)
659 {
660 SdrMark* pMark = GetMark(0);
661 XubString aNam;
662
663 if(!nAnz)
664 {
665 ((SdrMarkList*)(this))->maMarkName = ImpGetResStr(STR_ObjNameNoObj);
666 }
667 else if(1L == nAnz)
668 {
669 if(pMark->GetMarkedSdrObj())
670 {
671 pMark->GetMarkedSdrObj()->TakeObjNameSingul(aNam);
672 }
673 }
674 else
675 {
676 if(pMark->GetMarkedSdrObj())
677 {
678 pMark->GetMarkedSdrObj()->TakeObjNamePlural(aNam);
679 XubString aStr1;
680 sal_Bool bEq(sal_True);
681
682 for(sal_uLong i = 1; i < GetMarkCount() && bEq; i++)
683 {
684 SdrMark* pMark2 = GetMark(i);
685 pMark2->GetMarkedSdrObj()->TakeObjNamePlural(aStr1);
686 bEq = aNam.Equals(aStr1);
687 }
688
689 if(!bEq)
690 {
691 aNam = ImpGetResStr(STR_ObjNamePlural);
692 }
693 }
694
695 aNam.Insert(sal_Unicode(' '), 0);
696 aNam.Insert(UniString::CreateFromInt32(nAnz), 0);
697 }
698
699 ((SdrMarkList*)(this))->maMarkName = aNam;
700 ((SdrMarkList*)(this))->mbNameOk = sal_True;
701 }
702
703 return maMarkName;
704 }
705
GetPointMarkDescription(sal_Bool bGlue) const706 const XubString& SdrMarkList::GetPointMarkDescription(sal_Bool bGlue) const
707 {
708 sal_Bool& rNameOk = (sal_Bool&)(bGlue ? mbGluePointNameOk : mbPointNameOk);
709 XubString& rName = (XubString&)(bGlue ? maGluePointName : maPointName);
710 sal_uLong nMarkAnz(GetMarkCount());
711 sal_uLong nMarkPtAnz(0L);
712 sal_uLong nMarkPtObjAnz(0L);
713 sal_uLong n1stMarkNum(ULONG_MAX);
714
715 for(sal_uLong nMarkNum(0L); nMarkNum < nMarkAnz; nMarkNum++)
716 {
717 const SdrMark* pMark = GetMark(nMarkNum);
718 const SdrUShortCont* pPts = bGlue ? pMark->GetMarkedGluePoints() : pMark->GetMarkedPoints();
719 sal_uLong nAnz(pPts ? pPts->GetCount() : 0);
720
721 if(nAnz)
722 {
723 if(n1stMarkNum == ULONG_MAX)
724 {
725 n1stMarkNum = nMarkNum;
726 }
727
728 nMarkPtAnz += nAnz;
729 nMarkPtObjAnz++;
730 }
731
732 if(nMarkPtObjAnz > 1 && rNameOk)
733 {
734 // vorzeitige Entscheidung
735 return rName;
736 }
737 }
738
739 if(rNameOk && 1L == nMarkPtObjAnz)
740 {
741 // Bei Einfachselektion nur Textrahmen cachen
742 const SdrObject* pObj = GetMark(0)->GetMarkedSdrObj();
743 const SdrTextObj* pTextObj = PTR_CAST(SdrTextObj,pObj);
744
745 if(!pTextObj || !pTextObj->IsTextFrame())
746 {
747 rNameOk = sal_False;
748 }
749 }
750
751 if(!nMarkPtObjAnz)
752 {
753 rName.Erase();
754 rNameOk = sal_True;
755 }
756 else if(!rNameOk)
757 {
758 const SdrMark* pMark = GetMark(n1stMarkNum);
759 XubString aNam;
760
761 if(1L == nMarkPtObjAnz)
762 {
763 if(pMark->GetMarkedSdrObj())
764 {
765 pMark->GetMarkedSdrObj()->TakeObjNameSingul(aNam);
766 }
767 }
768 else
769 {
770 if(pMark->GetMarkedSdrObj())
771 {
772 pMark->GetMarkedSdrObj()->TakeObjNamePlural(aNam);
773 }
774
775 XubString aStr1;
776 sal_Bool bEq(sal_True);
777
778 for(sal_uLong i(n1stMarkNum + 1L); i < GetMarkCount() && bEq; i++)
779 {
780 const SdrMark* pMark2 = GetMark(i);
781 const SdrUShortCont* pPts = bGlue ? pMark2->GetMarkedGluePoints() : pMark2->GetMarkedPoints();
782
783 if(pPts && pPts->GetCount() && pMark2->GetMarkedSdrObj())
784 {
785 pMark2->GetMarkedSdrObj()->TakeObjNamePlural(aStr1);
786 bEq = aNam.Equals(aStr1);
787 }
788 }
789
790 if(!bEq)
791 {
792 aNam = ImpGetResStr(STR_ObjNamePlural);
793 }
794
795 aNam.Insert(sal_Unicode(' '), 0);
796 aNam.Insert(UniString::CreateFromInt32(nMarkPtObjAnz), 0);
797 }
798
799 XubString aStr1;
800
801 if(1L == nMarkPtAnz)
802 {
803 aStr1 = (ImpGetResStr(bGlue ? STR_ViewMarkedGluePoint : STR_ViewMarkedPoint));
804 }
805 else
806 {
807 aStr1 = (ImpGetResStr(bGlue ? STR_ViewMarkedGluePoints : STR_ViewMarkedPoints));
808 aStr1.SearchAndReplaceAscii("%2", UniString::CreateFromInt32(nMarkPtAnz));
809 }
810
811 aStr1.SearchAndReplaceAscii("%1", aNam);
812 rName = aStr1;
813 rNameOk = sal_True;
814 }
815
816 return rName;
817 }
818
TakeBoundRect(SdrPageView * pPV,Rectangle & rRect) const819 sal_Bool SdrMarkList::TakeBoundRect(SdrPageView* pPV, Rectangle& rRect) const
820 {
821 sal_Bool bFnd(sal_False);
822 Rectangle aR;
823
824 for(sal_uLong i(0L); i < GetMarkCount(); i++)
825 {
826 SdrMark* pMark = GetMark(i);
827
828 if(!pPV || pMark->GetPageView() == pPV)
829 {
830 if(pMark->GetMarkedSdrObj())
831 {
832 aR = pMark->GetMarkedSdrObj()->GetCurrentBoundRect();
833
834 if(bFnd)
835 {
836 rRect.Union(aR);
837 }
838 else
839 {
840 rRect = aR;
841 bFnd = sal_True;
842 }
843 }
844 }
845 }
846
847 return bFnd;
848 }
849
TakeSnapRect(SdrPageView * pPV,Rectangle & rRect) const850 sal_Bool SdrMarkList::TakeSnapRect(SdrPageView* pPV, Rectangle& rRect) const
851 {
852 sal_Bool bFnd(sal_False);
853
854 for(sal_uLong i(0L); i < GetMarkCount(); i++)
855 {
856 SdrMark* pMark = GetMark(i);
857
858 if(!pPV || pMark->GetPageView() == pPV)
859 {
860 if(pMark->GetMarkedSdrObj())
861 {
862 Rectangle aR(pMark->GetMarkedSdrObj()->GetSnapRect());
863
864 if(bFnd)
865 {
866 rRect.Union(aR);
867 }
868 else
869 {
870 rRect = aR;
871 bFnd = sal_True;
872 }
873 }
874 }
875 }
876
877 return bFnd;
878 }
879
880 ////////////////////////////////////////////////////////////////////////////////////////////////////
881
882 namespace sdr
883 {
ViewSelection()884 ViewSelection::ViewSelection()
885 : mbEdgesOfMarkedNodesDirty(sal_False)
886 {
887 }
888
SetEdgesOfMarkedNodesDirty()889 void ViewSelection::SetEdgesOfMarkedNodesDirty()
890 {
891 if(!mbEdgesOfMarkedNodesDirty)
892 {
893 mbEdgesOfMarkedNodesDirty = sal_True;
894 maEdgesOfMarkedNodes.Clear();
895 maMarkedEdgesOfMarkedNodes.Clear();
896 maAllMarkedObjects.Clear();
897 }
898 }
899
GetEdgesOfMarkedNodes() const900 const SdrMarkList& ViewSelection::GetEdgesOfMarkedNodes() const
901 {
902 if(mbEdgesOfMarkedNodesDirty)
903 {
904 ((ViewSelection*)this)->ImpForceEdgesOfMarkedNodes();
905 }
906
907 return maEdgesOfMarkedNodes;
908 }
909
GetMarkedEdgesOfMarkedNodes() const910 const SdrMarkList& ViewSelection::GetMarkedEdgesOfMarkedNodes() const
911 {
912 if(mbEdgesOfMarkedNodesDirty)
913 {
914 ((ViewSelection*)this)->ImpForceEdgesOfMarkedNodes();
915 }
916
917 return maMarkedEdgesOfMarkedNodes;
918 }
919
GetAllMarkedObjects() const920 const List& ViewSelection::GetAllMarkedObjects() const
921 {
922 if(mbEdgesOfMarkedNodesDirty)
923 {
924 ((ViewSelection*)this)->ImpForceEdgesOfMarkedNodes();
925 }
926
927 return maAllMarkedObjects;
928 }
929
ImplCollectCompleteSelection(SdrObject * pObj)930 void ViewSelection::ImplCollectCompleteSelection(SdrObject* pObj)
931 {
932 if(pObj)
933 {
934 sal_Bool bIsGroup(pObj->IsGroupObject());
935
936 if(bIsGroup && pObj->ISA(E3dObject) && !pObj->ISA(E3dScene))
937 {
938 bIsGroup = sal_False;
939 }
940
941 if(bIsGroup)
942 {
943 SdrObjList* pList = pObj->GetSubList();
944
945 for(sal_uLong a(0L); a < pList->GetObjCount(); a++)
946 {
947 SdrObject* pObj2 = pList->GetObj(a);
948 ImplCollectCompleteSelection(pObj2);
949 }
950 }
951
952 maAllMarkedObjects.Insert(pObj, LIST_APPEND);
953 }
954 }
955
ImpForceEdgesOfMarkedNodes()956 void ViewSelection::ImpForceEdgesOfMarkedNodes()
957 {
958 if(mbEdgesOfMarkedNodesDirty)
959 {
960 mbEdgesOfMarkedNodesDirty = sal_False;
961 maMarkedObjectList.ForceSort();
962 maEdgesOfMarkedNodes.Clear();
963 maMarkedEdgesOfMarkedNodes.Clear();
964 maAllMarkedObjects.Clear();
965
966 // #126320# GetMarkCount after ForceSort
967 const sal_uLong nMarkAnz(maMarkedObjectList.GetMarkCount());
968
969 for(sal_uLong a(0L); a < nMarkAnz; a++)
970 {
971 SdrObject* pCandidate = maMarkedObjectList.GetMark(a)->GetMarkedSdrObj();
972
973 if(pCandidate)
974 {
975 // build transitive hull
976 ImplCollectCompleteSelection(pCandidate);
977
978 if(pCandidate->IsNode())
979 {
980 // travel over broadcaster/listener to access edges connected to the selected object
981 const SfxBroadcaster* pBC = pCandidate->GetBroadcaster();
982
983 if(pBC)
984 {
985 sal_uInt16 nLstAnz(pBC->GetListenerCount());
986
987 for(sal_uInt16 nl(0); nl < nLstAnz; nl++)
988 {
989 SfxListener* pLst = pBC->GetListener(nl);
990 SdrEdgeObj* pEdge = PTR_CAST(SdrEdgeObj, pLst);
991
992 if(pEdge && pEdge->IsInserted() && pEdge->GetPage() == pCandidate->GetPage())
993 {
994 SdrMark aM(pEdge, maMarkedObjectList.GetMark(a)->GetPageView());
995
996 if(pEdge->GetConnectedNode(sal_True) == pCandidate)
997 {
998 aM.SetCon1(sal_True);
999 }
1000
1001 if(pEdge->GetConnectedNode(sal_False) == pCandidate)
1002 {
1003 aM.SetCon2(sal_True);
1004 }
1005
1006 if(CONTAINER_ENTRY_NOTFOUND == maMarkedObjectList.FindObject(pEdge))
1007 {
1008 // nachsehen, ob er selbst markiert ist
1009 maEdgesOfMarkedNodes.InsertEntry(aM);
1010 }
1011 else
1012 {
1013 maMarkedEdgesOfMarkedNodes.InsertEntry(aM);
1014 }
1015 }
1016 }
1017 }
1018 }
1019 }
1020 }
1021
1022 maEdgesOfMarkedNodes.ForceSort();
1023 maMarkedEdgesOfMarkedNodes.ForceSort();
1024 }
1025 }
1026 } // end of namespace sdr
1027
1028 /* vim: set noet sw=4 ts=4: */
1029