Line data Source code
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 :
21 :
22 :
23 : #include <svx/svdmark.hxx>
24 : #include <svx/svdetc.hxx>
25 : #include <svx/svdobj.hxx>
26 : #include <svx/svdpage.hxx>
27 : #include "svx/svditer.hxx"
28 : #include <svx/svdpagv.hxx>
29 : #include <svx/svdopath.hxx>
30 : #include <svx/svdogrp.hxx>
31 : #include <svx/svdorect.hxx>
32 : #include "svx/svdstr.hrc"
33 : #include "svx/svdglob.hxx"
34 :
35 :
36 : #include <svx/obj3d.hxx>
37 : #include <svx/scene3d.hxx>
38 : #include <svl/brdcst.hxx>
39 : #include <svx/svdoedge.hxx>
40 :
41 :
42 :
43 :
44 356 : SdrMark::SdrMark(SdrObject* pNewObj, SdrPageView* pNewPageView)
45 : : mpSelectedSdrObject(pNewObj),
46 : mpPageView(pNewPageView),
47 : mpPoints(0L),
48 : mpLines(0L),
49 : mpGluePoints(0L),
50 : mbCon1(false),
51 : mbCon2(false),
52 356 : mnUser(0)
53 : {
54 356 : if(mpSelectedSdrObject)
55 : {
56 356 : mpSelectedSdrObject->AddObjectUser( *this );
57 : }
58 356 : }
59 :
60 417 : SdrMark::SdrMark(const SdrMark& rMark)
61 : : ObjectUser(),
62 : mpSelectedSdrObject(0L),
63 : mpPageView(0L),
64 : mpPoints(0L),
65 : mpLines(0L),
66 : mpGluePoints(0L),
67 : mbCon1(false),
68 : mbCon2(false),
69 417 : mnUser(0)
70 : {
71 417 : *this = rMark;
72 417 : }
73 :
74 1963 : SdrMark::~SdrMark()
75 : {
76 773 : if(mpSelectedSdrObject)
77 : {
78 773 : mpSelectedSdrObject->RemoveObjectUser( *this );
79 : }
80 :
81 773 : if(mpPoints)
82 : {
83 0 : delete mpPoints;
84 : }
85 :
86 773 : if(mpLines)
87 : {
88 0 : delete mpLines;
89 : }
90 :
91 773 : if(mpGluePoints)
92 : {
93 0 : delete mpGluePoints;
94 : }
95 1190 : }
96 :
97 0 : void SdrMark::ObjectInDestruction(const SdrObject& rObject)
98 : {
99 : (void) rObject; // avoid warnings
100 : OSL_ENSURE(mpSelectedSdrObject && mpSelectedSdrObject == &rObject, "SdrMark::ObjectInDestruction: called form object different from hosted one (!)");
101 : OSL_ENSURE(mpSelectedSdrObject, "SdrMark::ObjectInDestruction: still selected SdrObject is deleted, deselect first (!)");
102 0 : mpSelectedSdrObject = 0L;
103 0 : }
104 :
105 417 : void SdrMark::SetMarkedSdrObj(SdrObject* pNewObj)
106 : {
107 417 : if(mpSelectedSdrObject)
108 : {
109 0 : mpSelectedSdrObject->RemoveObjectUser( *this );
110 : }
111 :
112 417 : mpSelectedSdrObject = pNewObj;
113 :
114 417 : if(mpSelectedSdrObject)
115 : {
116 417 : mpSelectedSdrObject->AddObjectUser( *this );
117 : }
118 417 : }
119 :
120 4795 : SdrObject* SdrMark::GetMarkedSdrObj() const
121 : {
122 4795 : return mpSelectedSdrObject;
123 : }
124 :
125 417 : SdrMark& SdrMark::operator=(const SdrMark& rMark)
126 : {
127 417 : SetMarkedSdrObj(rMark.mpSelectedSdrObject);
128 417 : mpPageView = rMark.mpPageView;
129 417 : mbCon1 = rMark.mbCon1;
130 417 : mbCon2 = rMark.mbCon2;
131 417 : mnUser = rMark.mnUser;
132 :
133 417 : if(!rMark.mpPoints)
134 : {
135 417 : if(mpPoints)
136 : {
137 0 : delete mpPoints;
138 0 : mpPoints = 0L;
139 : }
140 : }
141 : else
142 : {
143 0 : if(!mpPoints)
144 : {
145 0 : mpPoints = new SdrUShortCont(*rMark.mpPoints);
146 : }
147 : else
148 : {
149 0 : *mpPoints = *rMark.mpPoints;
150 : }
151 : }
152 :
153 417 : if(!rMark.mpLines)
154 : {
155 417 : if(mpLines)
156 : {
157 0 : delete mpLines;
158 0 : mpLines = 0L;
159 : }
160 : }
161 : else
162 : {
163 0 : if(!mpLines)
164 : {
165 0 : mpLines = new SdrUShortCont(*rMark.mpLines);
166 : }
167 : else
168 : {
169 0 : *mpLines = *rMark.mpLines;
170 : }
171 : }
172 :
173 417 : if(!rMark.mpGluePoints)
174 : {
175 417 : if(mpGluePoints)
176 : {
177 0 : delete mpGluePoints;
178 0 : mpGluePoints = 0L;
179 : }
180 : }
181 : else
182 : {
183 0 : if(!mpGluePoints)
184 : {
185 0 : mpGluePoints = new SdrUShortCont(*rMark.mpGluePoints);
186 : }
187 : else
188 : {
189 0 : *mpGluePoints = *rMark.mpGluePoints;
190 : }
191 : }
192 :
193 417 : return *this;
194 : }
195 :
196 0 : bool SdrMark::operator==(const SdrMark& rMark) const
197 : {
198 0 : bool bRet(mpSelectedSdrObject == rMark.mpSelectedSdrObject && mpPageView == rMark.mpPageView && mbCon1 == rMark.mbCon1 && mbCon2 == rMark.mbCon2 && mnUser == rMark.mnUser);
199 :
200 0 : if((mpPoints != 0L) != (rMark.mpPoints != 0L))
201 0 : bRet = false;
202 :
203 0 : if((mpLines != 0L) != (rMark.mpLines != 0L))
204 0 : bRet = false;
205 :
206 0 : if((mpGluePoints != 0L) != (rMark.mpGluePoints != 0L))
207 0 : bRet = false;
208 :
209 0 : if(bRet && mpPoints && *mpPoints != *rMark.mpPoints)
210 0 : bRet = false;
211 :
212 0 : if(bRet && mpLines && *mpLines != *rMark.mpLines)
213 0 : bRet = false;
214 :
215 0 : if(bRet && mpGluePoints && *mpGluePoints != *rMark.mpGluePoints)
216 0 : bRet = false;
217 :
218 0 : return bRet;
219 : }
220 :
221 :
222 :
223 90 : static bool ImpSdrMarkListSorter(SdrMark* const& lhs, SdrMark* const& rhs)
224 : {
225 90 : SdrObject* pObj1 = lhs->GetMarkedSdrObj();
226 90 : SdrObject* pObj2 = rhs->GetMarkedSdrObj();
227 90 : SdrObjList* pOL1 = (pObj1) ? pObj1->GetObjList() : 0L;
228 90 : SdrObjList* pOL2 = (pObj2) ? pObj2->GetObjList() : 0L;
229 :
230 90 : if (pOL1 == pOL2)
231 : {
232 : // AF: Note that I reverted a change from sal_uInt32 to sal_uLong (made
233 : // for 64bit compliance, #i78198#) because internally in SdrObject
234 : // both nOrdNum and mnNavigationPosition are stored as sal_uInt32.
235 90 : sal_uInt32 nObjOrd1((pObj1) ? pObj1->GetNavigationPosition() : 0);
236 90 : sal_uInt32 nObjOrd2((pObj2) ? pObj2->GetNavigationPosition() : 0);
237 :
238 90 : return nObjOrd1 < nObjOrd2;
239 : }
240 : else
241 : {
242 0 : return (sal_IntPtr)pOL1 < (sal_IntPtr)pOL2;
243 : }
244 : }
245 :
246 :
247 :
248 9577 : void SdrMarkList::ForceSort() const
249 : {
250 9577 : if(!mbSorted)
251 : {
252 3474 : ((SdrMarkList*)this)->ImpForceSort();
253 : }
254 9577 : }
255 :
256 3474 : void SdrMarkList::ImpForceSort()
257 : {
258 3474 : if(!mbSorted)
259 : {
260 3474 : mbSorted = true;
261 3474 : sal_uLong nAnz = maList.size();
262 :
263 : // remove invalid
264 3474 : if(nAnz > 0 )
265 : {
266 163 : for(std::vector<SdrMark*>::iterator it = maList.begin(); it != maList.end(); )
267 : {
268 89 : SdrMark* pAkt = *it;
269 89 : if(pAkt->GetMarkedSdrObj() == 0)
270 : {
271 0 : it = maList.erase( it );
272 0 : delete pAkt;
273 : }
274 : else
275 89 : ++it;
276 : }
277 37 : nAnz = maList.size();
278 : }
279 :
280 3474 : if(nAnz > 1)
281 : {
282 36 : std::sort(maList.begin(), maList.end(), ImpSdrMarkListSorter);
283 :
284 : // remove duplicates
285 36 : if(maList.size() > 1)
286 : {
287 36 : SdrMark* pAkt = maList.back();
288 36 : int i = maList.size() - 2;
289 88 : while(i)
290 : {
291 16 : SdrMark* pCmp = maList[i];
292 16 : if(pAkt->GetMarkedSdrObj() == pCmp->GetMarkedSdrObj() && pAkt->GetMarkedSdrObj())
293 : {
294 : // Con1/Con2 Merging
295 0 : if(pCmp->IsCon1())
296 0 : pAkt->SetCon1(true);
297 :
298 0 : if(pCmp->IsCon2())
299 0 : pAkt->SetCon2(true);
300 :
301 : // delete pCmp
302 0 : maList.erase(maList.begin() + i);
303 :
304 0 : delete pCmp;
305 : }
306 : else
307 : {
308 16 : pAkt = pCmp;
309 : }
310 :
311 16 : --i;
312 : }
313 : }
314 : }
315 : }
316 3474 : }
317 :
318 35699 : void SdrMarkList::Clear()
319 : {
320 35951 : for(sal_uLong i(0L); i < GetMarkCount(); i++)
321 : {
322 252 : SdrMark* pMark = GetMark(i);
323 252 : delete pMark;
324 : }
325 :
326 35699 : maList.clear();
327 35699 : SetNameDirty();
328 35699 : }
329 :
330 158 : void SdrMarkList::operator=(const SdrMarkList& rLst)
331 : {
332 158 : Clear();
333 :
334 199 : for(sal_uLong i(0L); i < rLst.GetMarkCount(); i++)
335 : {
336 41 : SdrMark* pMark = rLst.GetMark(i);
337 41 : SdrMark* pNeuMark = new SdrMark(*pMark);
338 41 : maList.push_back(pNeuMark);
339 : }
340 :
341 158 : maMarkName = rLst.maMarkName;
342 158 : mbNameOk = rLst.mbNameOk;
343 158 : maPointName = rLst.maPointName;
344 158 : mbPointNameOk = rLst.mbPointNameOk;
345 158 : maGluePointName = rLst.maGluePointName;
346 158 : mbGluePointNameOk = rLst.mbGluePointNameOk;
347 158 : mbSorted = rLst.mbSorted;
348 158 : }
349 :
350 4431 : SdrMark* SdrMarkList::GetMark(sal_uLong nNum) const
351 : {
352 4431 : return (nNum < maList.size()) ? maList[nNum] : NULL;
353 : }
354 :
355 7 : sal_uLong SdrMarkList::FindObject(const SdrObject* pObj) const
356 : {
357 : // Since relying on OrdNums is not allowed for the selection because objects in the
358 : // selection may not be inserted in a list if they are e.g. modified ATM, i changed
359 : // this loop to just look if the object pointer is in the selection.
360 :
361 : // Problem is that GetOrdNum() which is const, internally casts to non-const and
362 : // hardly sets the OrdNum member of the object (nOrdNum) to 0 (ZERO) if the object
363 : // is not inserted in a object list.
364 : // Since this may be by purpose and necessary somewhere else i decided that it is
365 : // less dangerous to change this method then changing SdrObject::GetOrdNum().
366 7 : if(pObj && !maList.empty())
367 : {
368 0 : for(sal_uLong a(0L); a < maList.size(); a++)
369 : {
370 0 : if(maList[a]->GetMarkedSdrObj() == pObj)
371 : {
372 0 : return a;
373 : }
374 : }
375 : }
376 :
377 7 : return CONTAINER_ENTRY_NOTFOUND;
378 : }
379 :
380 356 : void SdrMarkList::InsertEntry(const SdrMark& rMark, bool bChkSort)
381 : {
382 356 : SetNameDirty();
383 356 : sal_uLong nAnz(maList.size());
384 :
385 356 : if(!bChkSort || !mbSorted || nAnz == 0)
386 : {
387 249 : if(!bChkSort)
388 15 : mbSorted = false;
389 :
390 249 : maList.push_back(new SdrMark(rMark));
391 : }
392 : else
393 : {
394 107 : SdrMark* pLast = GetMark(sal_uLong(nAnz - 1));
395 107 : const SdrObject* pLastObj = pLast->GetMarkedSdrObj();
396 107 : const SdrObject* pNeuObj = rMark.GetMarkedSdrObj();
397 :
398 107 : if(pLastObj == pNeuObj)
399 : {
400 : // This one already exists.
401 : // Con1/Con2 Merging
402 0 : if(rMark.IsCon1())
403 0 : pLast->SetCon1(true);
404 :
405 0 : if(rMark.IsCon2())
406 0 : pLast->SetCon2(true);
407 : }
408 : else
409 : {
410 107 : SdrMark* pKopie = new SdrMark(rMark);
411 107 : maList.push_back(pKopie);
412 :
413 : // now check if the sort is ok
414 107 : const SdrObjList* pLastOL = pLastObj!=0L ? pLastObj->GetObjList() : 0L;
415 107 : const SdrObjList* pNeuOL = pNeuObj !=0L ? pNeuObj ->GetObjList() : 0L;
416 :
417 107 : if(pLastOL == pNeuOL)
418 : {
419 107 : const sal_uLong nLastNum(pLastObj!=0L ? pLastObj->GetOrdNum() : 0);
420 107 : const sal_uLong nNeuNum(pNeuObj !=0L ? pNeuObj ->GetOrdNum() : 0);
421 :
422 107 : if(nNeuNum < nLastNum)
423 : {
424 : // at some point, we have to sort
425 11 : mbSorted = false;
426 : }
427 : }
428 : else
429 : {
430 : // at some point, we have to sort
431 0 : mbSorted = false;
432 : }
433 : }
434 : }
435 :
436 356 : return;
437 : }
438 :
439 20 : void SdrMarkList::DeleteMark(sal_uLong nNum)
440 : {
441 20 : SdrMark* pMark = GetMark(nNum);
442 : DBG_ASSERT(pMark!=0L,"DeleteMark: MarkEntry not found.");
443 :
444 20 : if(pMark)
445 : {
446 20 : maList.erase(maList.begin() + nNum);
447 20 : delete pMark;
448 20 : SetNameDirty();
449 : }
450 20 : }
451 :
452 20 : void SdrMarkList::ReplaceMark(const SdrMark& rNewMark, sal_uLong nNum)
453 : {
454 20 : SdrMark* pMark = GetMark(nNum);
455 : DBG_ASSERT(pMark!=0L,"ReplaceMark: MarkEntry not found.");
456 :
457 20 : if(pMark)
458 : {
459 20 : delete pMark;
460 20 : SetNameDirty();
461 20 : SdrMark* pKopie = new SdrMark(rNewMark);
462 20 : maList[nNum] = pKopie;
463 20 : mbSorted = false;
464 : }
465 20 : }
466 :
467 10 : void SdrMarkList::Merge(const SdrMarkList& rSrcList, bool bReverse)
468 : {
469 10 : sal_uLong nAnz(rSrcList.maList.size());
470 :
471 10 : if(rSrcList.mbSorted)
472 : {
473 : // merge without forcing a Sort in rSrcList
474 5 : bReverse = false;
475 : }
476 :
477 10 : if(!bReverse)
478 : {
479 10 : for(sal_uLong i(0L); i < nAnz; i++)
480 : {
481 5 : SdrMark* pM = rSrcList.maList[i];
482 5 : InsertEntry(*pM);
483 : }
484 : }
485 : else
486 : {
487 25 : for(sal_uLong i(nAnz); i > 0;)
488 : {
489 15 : i--;
490 15 : SdrMark* pM = rSrcList.maList[i];
491 15 : InsertEntry(*pM);
492 : }
493 : }
494 10 : }
495 :
496 2818 : bool SdrMarkList::DeletePageView(const SdrPageView& rPV)
497 : {
498 2818 : bool bChgd(false);
499 :
500 5761 : for(std::vector<SdrMark*>::iterator it = maList.begin(); it != maList.end(); )
501 : {
502 125 : SdrMark* pMark = *it;
503 :
504 125 : if(pMark->GetPageView()==&rPV)
505 : {
506 125 : it = maList.erase(it);
507 125 : delete pMark;
508 125 : SetNameDirty();
509 125 : bChgd = true;
510 : }
511 : else
512 0 : ++it;
513 : }
514 :
515 2818 : return bChgd;
516 : }
517 :
518 0 : bool SdrMarkList::InsertPageView(const SdrPageView& rPV)
519 : {
520 0 : bool bChgd(false);
521 0 : DeletePageView(rPV); // delete all of them, then append the entire page
522 : SdrObject* pObj;
523 0 : const SdrObjList* pOL = rPV.GetObjList();
524 0 : sal_uLong nObjAnz(pOL->GetObjCount());
525 :
526 0 : for(sal_uLong nO(0L); nO < nObjAnz; nO++)
527 : {
528 0 : pObj = pOL->GetObj(nO);
529 0 : bool bDoIt(rPV.IsObjMarkable(pObj));
530 :
531 0 : if(bDoIt)
532 : {
533 0 : SdrMark* pM = new SdrMark(pObj, (SdrPageView*)&rPV);
534 0 : maList.push_back(pM);
535 0 : SetNameDirty();
536 0 : bChgd = true;
537 : }
538 : }
539 :
540 0 : return bChgd;
541 : }
542 :
543 24 : const OUString& SdrMarkList::GetMarkDescription() const
544 : {
545 24 : sal_uLong nAnz(GetMarkCount());
546 :
547 24 : if(mbNameOk && 1L == nAnz)
548 : {
549 : // if it's a single selection, cache only text frame
550 0 : const SdrObject* pObj = GetMark(0)->GetMarkedSdrObj();
551 0 : const SdrTextObj* pTextObj = PTR_CAST(SdrTextObj, pObj);
552 :
553 0 : if(!pTextObj || !pTextObj->IsTextFrame())
554 : {
555 0 : ((SdrMarkList*)(this))->mbNameOk = false;
556 : }
557 : }
558 :
559 24 : if(!mbNameOk)
560 : {
561 24 : SdrMark* pMark = GetMark(0);
562 24 : OUString aNam;
563 :
564 24 : if(!nAnz)
565 : {
566 0 : const_cast<SdrMarkList*>(this)->maMarkName = ImpGetResStr(STR_ObjNameNoObj);
567 : }
568 24 : else if(1L == nAnz)
569 : {
570 7 : if(pMark->GetMarkedSdrObj())
571 : {
572 7 : aNam = pMark->GetMarkedSdrObj()->TakeObjNameSingul();
573 : }
574 : }
575 : else
576 : {
577 17 : if(pMark->GetMarkedSdrObj())
578 : {
579 17 : aNam = pMark->GetMarkedSdrObj()->TakeObjNamePlural();
580 17 : bool bEq(true);
581 :
582 43 : for(sal_uLong i = 1; i < GetMarkCount() && bEq; i++)
583 : {
584 26 : SdrMark* pMark2 = GetMark(i);
585 26 : OUString aStr1(pMark2->GetMarkedSdrObj()->TakeObjNamePlural());
586 26 : bEq = aNam == aStr1;
587 26 : }
588 :
589 17 : if(!bEq)
590 : {
591 10 : aNam = ImpGetResStr(STR_ObjNamePlural);
592 : }
593 : }
594 :
595 17 : aNam = OUString::number( nAnz ) + " " + aNam;
596 : }
597 :
598 24 : const_cast<SdrMarkList*>(this)->maMarkName = aNam;
599 24 : const_cast<SdrMarkList*>(this)->mbNameOk = true;
600 : }
601 :
602 24 : return maMarkName;
603 : }
604 :
605 0 : const OUString& SdrMarkList::GetPointMarkDescription(bool bGlue) const
606 : {
607 0 : bool& rNameOk = (bool&)(bGlue ? mbGluePointNameOk : mbPointNameOk);
608 0 : OUString& rName = const_cast<OUString&>(bGlue ? maGluePointName : maPointName);
609 0 : sal_uLong nMarkAnz(GetMarkCount());
610 0 : sal_uLong nMarkPtAnz(0L);
611 0 : sal_uLong nMarkPtObjAnz(0L);
612 0 : sal_uLong n1stMarkNum(ULONG_MAX);
613 :
614 0 : for(sal_uLong nMarkNum(0L); nMarkNum < nMarkAnz; nMarkNum++)
615 : {
616 0 : const SdrMark* pMark = GetMark(nMarkNum);
617 0 : const SdrUShortCont* pPts = bGlue ? pMark->GetMarkedGluePoints() : pMark->GetMarkedPoints();
618 0 : sal_uLong nAnz(pPts ? pPts->size() : 0);
619 :
620 0 : if(nAnz)
621 : {
622 0 : if(n1stMarkNum == ULONG_MAX)
623 : {
624 0 : n1stMarkNum = nMarkNum;
625 : }
626 :
627 0 : nMarkPtAnz += nAnz;
628 0 : nMarkPtObjAnz++;
629 : }
630 :
631 0 : if(nMarkPtObjAnz > 1 && rNameOk)
632 : {
633 : // preliminary decision
634 0 : return rName;
635 : }
636 : }
637 :
638 0 : if(rNameOk && 1L == nMarkPtObjAnz)
639 : {
640 : // if it's a single selection, cache only text frame
641 0 : const SdrObject* pObj = GetMark(0)->GetMarkedSdrObj();
642 0 : const SdrTextObj* pTextObj = PTR_CAST(SdrTextObj,pObj);
643 :
644 0 : if(!pTextObj || !pTextObj->IsTextFrame())
645 : {
646 0 : rNameOk = false;
647 : }
648 : }
649 :
650 0 : if(!nMarkPtObjAnz)
651 : {
652 0 : rName = OUString();
653 0 : rNameOk = true;
654 : }
655 0 : else if(!rNameOk)
656 : {
657 0 : const SdrMark* pMark = GetMark(n1stMarkNum);
658 0 : OUString aNam;
659 :
660 0 : if(1L == nMarkPtObjAnz)
661 : {
662 0 : if(pMark->GetMarkedSdrObj())
663 : {
664 0 : aNam = pMark->GetMarkedSdrObj()->TakeObjNameSingul();
665 : }
666 : }
667 : else
668 : {
669 0 : if(pMark->GetMarkedSdrObj())
670 : {
671 0 : aNam = pMark->GetMarkedSdrObj()->TakeObjNamePlural();
672 : }
673 :
674 0 : bool bEq(true);
675 :
676 0 : for(sal_uLong i(n1stMarkNum + 1L); i < GetMarkCount() && bEq; i++)
677 : {
678 0 : const SdrMark* pMark2 = GetMark(i);
679 0 : const SdrUShortCont* pPts = bGlue ? pMark2->GetMarkedGluePoints() : pMark2->GetMarkedPoints();
680 :
681 0 : if(pPts && !pPts->empty() && pMark2->GetMarkedSdrObj())
682 : {
683 0 : OUString aStr1(pMark2->GetMarkedSdrObj()->TakeObjNamePlural());
684 0 : bEq = aNam == aStr1;
685 : }
686 : }
687 :
688 0 : if(!bEq)
689 : {
690 0 : aNam = ImpGetResStr(STR_ObjNamePlural);
691 : }
692 :
693 0 : aNam = OUString::number( nMarkPtObjAnz ) + " " + aNam;
694 : }
695 :
696 0 : OUString aStr1;
697 :
698 0 : if(1L == nMarkPtAnz)
699 : {
700 0 : aStr1 = (ImpGetResStr(bGlue ? STR_ViewMarkedGluePoint : STR_ViewMarkedPoint));
701 : }
702 : else
703 : {
704 0 : aStr1 = (ImpGetResStr(bGlue ? STR_ViewMarkedGluePoints : STR_ViewMarkedPoints));
705 0 : aStr1 = aStr1.replaceFirst("%2", OUString::number( nMarkPtAnz ));
706 : }
707 :
708 0 : aStr1 = aStr1.replaceFirst("%1", aNam);
709 0 : rName = aStr1;
710 0 : rNameOk = true;
711 : }
712 :
713 0 : return rName;
714 : }
715 :
716 20932 : bool SdrMarkList::TakeBoundRect(SdrPageView* pPV, Rectangle& rRect) const
717 : {
718 20932 : bool bFnd(false);
719 20932 : Rectangle aR;
720 :
721 21266 : for(sal_uLong i(0L); i < GetMarkCount(); i++)
722 : {
723 334 : SdrMark* pMark = GetMark(i);
724 :
725 334 : if(!pPV || pMark->GetPageView() == pPV)
726 : {
727 334 : if(pMark->GetMarkedSdrObj())
728 : {
729 334 : aR = pMark->GetMarkedSdrObj()->GetCurrentBoundRect();
730 :
731 334 : if(bFnd)
732 : {
733 79 : rRect.Union(aR);
734 : }
735 : else
736 : {
737 255 : rRect = aR;
738 255 : bFnd = true;
739 : }
740 : }
741 : }
742 : }
743 :
744 20932 : return bFnd;
745 : }
746 :
747 20932 : bool SdrMarkList::TakeSnapRect(SdrPageView* pPV, Rectangle& rRect) const
748 : {
749 20932 : bool bFnd(false);
750 :
751 21266 : for(sal_uLong i(0L); i < GetMarkCount(); i++)
752 : {
753 334 : SdrMark* pMark = GetMark(i);
754 :
755 334 : if(!pPV || pMark->GetPageView() == pPV)
756 : {
757 334 : if(pMark->GetMarkedSdrObj())
758 : {
759 334 : Rectangle aR(pMark->GetMarkedSdrObj()->GetSnapRect());
760 :
761 334 : if(bFnd)
762 : {
763 79 : rRect.Union(aR);
764 : }
765 : else
766 : {
767 255 : rRect = aR;
768 255 : bFnd = true;
769 : }
770 : }
771 : }
772 : }
773 :
774 20932 : return bFnd;
775 : }
776 :
777 :
778 :
779 : namespace sdr
780 : {
781 5800 : ViewSelection::ViewSelection()
782 5800 : : mbEdgesOfMarkedNodesDirty(false)
783 : {
784 5800 : }
785 :
786 2628 : void ViewSelection::SetEdgesOfMarkedNodesDirty()
787 : {
788 2628 : if(!mbEdgesOfMarkedNodesDirty)
789 : {
790 2394 : mbEdgesOfMarkedNodesDirty = true;
791 2394 : maEdgesOfMarkedNodes.Clear();
792 2394 : maMarkedEdgesOfMarkedNodes.Clear();
793 2394 : maAllMarkedObjects.clear();
794 : }
795 2628 : }
796 :
797 0 : const SdrMarkList& ViewSelection::GetEdgesOfMarkedNodes() const
798 : {
799 0 : if(mbEdgesOfMarkedNodesDirty)
800 : {
801 0 : ((ViewSelection*)this)->ImpForceEdgesOfMarkedNodes();
802 : }
803 :
804 0 : return maEdgesOfMarkedNodes;
805 : }
806 :
807 23 : const SdrMarkList& ViewSelection::GetMarkedEdgesOfMarkedNodes() const
808 : {
809 23 : if(mbEdgesOfMarkedNodesDirty)
810 : {
811 0 : ((ViewSelection*)this)->ImpForceEdgesOfMarkedNodes();
812 : }
813 :
814 23 : return maMarkedEdgesOfMarkedNodes;
815 : }
816 :
817 23 : const std::vector<SdrObject*>& ViewSelection::GetAllMarkedObjects() const
818 : {
819 23 : if(mbEdgesOfMarkedNodesDirty)
820 23 : ((ViewSelection*)this)->ImpForceEdgesOfMarkedNodes();
821 :
822 23 : return maAllMarkedObjects;
823 : }
824 :
825 103 : void ViewSelection::ImplCollectCompleteSelection(SdrObject* pObj)
826 : {
827 103 : if(pObj)
828 : {
829 103 : bool bIsGroup(pObj->IsGroupObject());
830 :
831 103 : if(bIsGroup && pObj->ISA(E3dObject) && !pObj->ISA(E3dScene))
832 : {
833 0 : bIsGroup = false;
834 : }
835 :
836 103 : if(bIsGroup)
837 : {
838 5 : SdrObjList* pList = pObj->GetSubList();
839 :
840 20 : for(sal_uLong a(0L); a < pList->GetObjCount(); a++)
841 : {
842 15 : SdrObject* pObj2 = pList->GetObj(a);
843 15 : ImplCollectCompleteSelection(pObj2);
844 : }
845 : }
846 :
847 103 : maAllMarkedObjects.push_back(pObj);
848 : }
849 103 : }
850 :
851 23 : void ViewSelection::ImpForceEdgesOfMarkedNodes()
852 : {
853 23 : if(mbEdgesOfMarkedNodesDirty)
854 : {
855 23 : mbEdgesOfMarkedNodesDirty = false;
856 23 : maMarkedObjectList.ForceSort();
857 23 : maEdgesOfMarkedNodes.Clear();
858 23 : maMarkedEdgesOfMarkedNodes.Clear();
859 23 : maAllMarkedObjects.clear();
860 :
861 : // GetMarkCount after ForceSort
862 23 : const sal_uLong nMarkAnz(maMarkedObjectList.GetMarkCount());
863 :
864 111 : for(sal_uLong a(0L); a < nMarkAnz; a++)
865 : {
866 88 : SdrObject* pCandidate = maMarkedObjectList.GetMark(a)->GetMarkedSdrObj();
867 :
868 88 : if(pCandidate)
869 : {
870 : // build transitive hull
871 88 : ImplCollectCompleteSelection(pCandidate);
872 :
873 88 : if(pCandidate->IsNode())
874 : {
875 : // travel over broadcaster/listener to access edges connected to the selected object
876 88 : const SfxBroadcaster* pBC = pCandidate->GetBroadcaster();
877 :
878 88 : if(pBC)
879 : {
880 0 : sal_uInt16 nLstAnz(pBC->GetListenerCount());
881 :
882 0 : for(sal_uInt16 nl(0); nl < nLstAnz; nl++)
883 : {
884 0 : SfxListener* pLst = pBC->GetListener(nl);
885 0 : SdrEdgeObj* pEdge = PTR_CAST(SdrEdgeObj, pLst);
886 :
887 0 : if(pEdge && pEdge->IsInserted() && pEdge->GetPage() == pCandidate->GetPage())
888 : {
889 0 : SdrMark aM(pEdge, maMarkedObjectList.GetMark(a)->GetPageView());
890 :
891 0 : if(pEdge->GetConnectedNode(true) == pCandidate)
892 : {
893 0 : aM.SetCon1(true);
894 : }
895 :
896 0 : if(pEdge->GetConnectedNode(false) == pCandidate)
897 : {
898 0 : aM.SetCon2(true);
899 : }
900 :
901 0 : if(CONTAINER_ENTRY_NOTFOUND == maMarkedObjectList.FindObject(pEdge))
902 : {
903 : // check if it itself is selected
904 0 : maEdgesOfMarkedNodes.InsertEntry(aM);
905 : }
906 : else
907 : {
908 0 : maMarkedEdgesOfMarkedNodes.InsertEntry(aM);
909 0 : }
910 : }
911 : }
912 : }
913 : }
914 : }
915 : }
916 :
917 23 : maEdgesOfMarkedNodes.ForceSort();
918 23 : maMarkedEdgesOfMarkedNodes.ForceSort();
919 : }
920 23 : }
921 : } // end of namespace sdr
922 :
923 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|