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 0 : 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 0 : mnUser(0)
53 : {
54 0 : if(mpSelectedSdrObject)
55 : {
56 0 : mpSelectedSdrObject->AddObjectUser( *this );
57 : }
58 0 : }
59 :
60 0 : 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 0 : mnUser(0)
70 : {
71 0 : *this = rMark;
72 0 : }
73 :
74 0 : SdrMark::~SdrMark()
75 : {
76 0 : if(mpSelectedSdrObject)
77 : {
78 0 : mpSelectedSdrObject->RemoveObjectUser( *this );
79 : }
80 :
81 0 : if(mpPoints)
82 : {
83 0 : delete mpPoints;
84 : }
85 :
86 0 : if(mpLines)
87 : {
88 0 : delete mpLines;
89 : }
90 :
91 0 : if(mpGluePoints)
92 : {
93 0 : delete mpGluePoints;
94 : }
95 0 : }
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 0 : void SdrMark::SetMarkedSdrObj(SdrObject* pNewObj)
106 : {
107 0 : if(mpSelectedSdrObject)
108 : {
109 0 : mpSelectedSdrObject->RemoveObjectUser( *this );
110 : }
111 :
112 0 : mpSelectedSdrObject = pNewObj;
113 :
114 0 : if(mpSelectedSdrObject)
115 : {
116 0 : mpSelectedSdrObject->AddObjectUser( *this );
117 : }
118 0 : }
119 :
120 0 : SdrObject* SdrMark::GetMarkedSdrObj() const
121 : {
122 0 : return mpSelectedSdrObject;
123 : }
124 :
125 0 : SdrMark& SdrMark::operator=(const SdrMark& rMark)
126 : {
127 0 : SetMarkedSdrObj(rMark.mpSelectedSdrObject);
128 0 : mpPageView = rMark.mpPageView;
129 0 : mbCon1 = rMark.mbCon1;
130 0 : mbCon2 = rMark.mbCon2;
131 0 : mnUser = rMark.mnUser;
132 :
133 0 : if(!rMark.mpPoints)
134 : {
135 0 : 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 0 : if(!rMark.mpLines)
154 : {
155 0 : 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 0 : if(!rMark.mpGluePoints)
174 : {
175 0 : 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 0 : 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 0 : static bool ImpSdrMarkListSorter(SdrMark* const& lhs, SdrMark* const& rhs)
224 : {
225 0 : SdrObject* pObj1 = lhs->GetMarkedSdrObj();
226 0 : SdrObject* pObj2 = rhs->GetMarkedSdrObj();
227 0 : SdrObjList* pOL1 = (pObj1) ? pObj1->GetObjList() : 0L;
228 0 : SdrObjList* pOL2 = (pObj2) ? pObj2->GetObjList() : 0L;
229 :
230 0 : 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 0 : sal_uInt32 nObjOrd1((pObj1) ? pObj1->GetNavigationPosition() : 0);
236 0 : sal_uInt32 nObjOrd2((pObj2) ? pObj2->GetNavigationPosition() : 0);
237 :
238 0 : return nObjOrd1 < nObjOrd2;
239 : }
240 : else
241 : {
242 0 : return (sal_IntPtr)pOL1 < (sal_IntPtr)pOL2;
243 : }
244 : }
245 :
246 :
247 :
248 0 : void SdrMarkList::ForceSort() const
249 : {
250 0 : if(!mbSorted)
251 : {
252 0 : ((SdrMarkList*)this)->ImpForceSort();
253 : }
254 0 : }
255 :
256 0 : void SdrMarkList::ImpForceSort()
257 : {
258 0 : if(!mbSorted)
259 : {
260 0 : mbSorted = true;
261 0 : sal_uLong nAnz = maList.size();
262 :
263 : // remove invalid
264 0 : if(nAnz > 0 )
265 : {
266 0 : for(std::vector<SdrMark*>::iterator it = maList.begin(); it != maList.end(); )
267 : {
268 0 : SdrMark* pAkt = *it;
269 0 : if(pAkt->GetMarkedSdrObj() == 0)
270 : {
271 0 : it = maList.erase( it );
272 0 : delete pAkt;
273 : }
274 : else
275 0 : ++it;
276 : }
277 0 : nAnz = maList.size();
278 : }
279 :
280 0 : if(nAnz > 1)
281 : {
282 0 : std::sort(maList.begin(), maList.end(), ImpSdrMarkListSorter);
283 :
284 : // remove duplicates
285 0 : if(maList.size() > 1)
286 : {
287 0 : SdrMark* pAkt = maList.back();
288 0 : int i = maList.size() - 2;
289 0 : while(i)
290 : {
291 0 : SdrMark* pCmp = maList[i];
292 0 : 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 0 : pAkt = pCmp;
309 : }
310 :
311 0 : --i;
312 : }
313 : }
314 : }
315 : }
316 0 : }
317 :
318 0 : void SdrMarkList::Clear()
319 : {
320 0 : for(sal_uLong i(0L); i < GetMarkCount(); i++)
321 : {
322 0 : SdrMark* pMark = GetMark(i);
323 0 : delete pMark;
324 : }
325 :
326 0 : maList.clear();
327 0 : SetNameDirty();
328 0 : }
329 :
330 0 : void SdrMarkList::operator=(const SdrMarkList& rLst)
331 : {
332 0 : Clear();
333 :
334 0 : for(sal_uLong i(0L); i < rLst.GetMarkCount(); i++)
335 : {
336 0 : SdrMark* pMark = rLst.GetMark(i);
337 0 : SdrMark* pNeuMark = new SdrMark(*pMark);
338 0 : maList.push_back(pNeuMark);
339 : }
340 :
341 0 : maMarkName = rLst.maMarkName;
342 0 : mbNameOk = rLst.mbNameOk;
343 0 : maPointName = rLst.maPointName;
344 0 : mbPointNameOk = rLst.mbPointNameOk;
345 0 : maGluePointName = rLst.maGluePointName;
346 0 : mbGluePointNameOk = rLst.mbGluePointNameOk;
347 0 : mbSorted = rLst.mbSorted;
348 0 : }
349 :
350 0 : SdrMark* SdrMarkList::GetMark(sal_uLong nNum) const
351 : {
352 0 : return (nNum < maList.size()) ? maList[nNum] : NULL;
353 : }
354 :
355 0 : 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 0 : 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 0 : return CONTAINER_ENTRY_NOTFOUND;
378 : }
379 :
380 0 : void SdrMarkList::InsertEntry(const SdrMark& rMark, bool bChkSort)
381 : {
382 0 : SetNameDirty();
383 0 : sal_uLong nAnz(maList.size());
384 :
385 0 : if(!bChkSort || !mbSorted || nAnz == 0)
386 : {
387 0 : if(!bChkSort)
388 0 : mbSorted = false;
389 :
390 0 : maList.push_back(new SdrMark(rMark));
391 : }
392 : else
393 : {
394 0 : SdrMark* pLast = GetMark(sal_uLong(nAnz - 1));
395 0 : const SdrObject* pLastObj = pLast->GetMarkedSdrObj();
396 0 : const SdrObject* pNeuObj = rMark.GetMarkedSdrObj();
397 :
398 0 : 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 0 : SdrMark* pKopie = new SdrMark(rMark);
411 0 : maList.push_back(pKopie);
412 :
413 : // now check if the sort is ok
414 0 : const SdrObjList* pLastOL = pLastObj!=0L ? pLastObj->GetObjList() : 0L;
415 0 : const SdrObjList* pNeuOL = pNeuObj !=0L ? pNeuObj ->GetObjList() : 0L;
416 :
417 0 : if(pLastOL == pNeuOL)
418 : {
419 0 : const sal_uLong nLastNum(pLastObj!=0L ? pLastObj->GetOrdNum() : 0);
420 0 : const sal_uLong nNeuNum(pNeuObj !=0L ? pNeuObj ->GetOrdNum() : 0);
421 :
422 0 : if(nNeuNum < nLastNum)
423 : {
424 : // at some point, we have to sort
425 0 : mbSorted = false;
426 : }
427 : }
428 : else
429 : {
430 : // at some point, we have to sort
431 0 : mbSorted = false;
432 : }
433 : }
434 : }
435 :
436 0 : return;
437 : }
438 :
439 0 : void SdrMarkList::DeleteMark(sal_uLong nNum)
440 : {
441 0 : SdrMark* pMark = GetMark(nNum);
442 : DBG_ASSERT(pMark!=0L,"DeleteMark: MarkEntry not found.");
443 :
444 0 : if(pMark)
445 : {
446 0 : maList.erase(maList.begin() + nNum);
447 0 : delete pMark;
448 0 : SetNameDirty();
449 : }
450 0 : }
451 :
452 0 : void SdrMarkList::ReplaceMark(const SdrMark& rNewMark, sal_uLong nNum)
453 : {
454 0 : SdrMark* pMark = GetMark(nNum);
455 : DBG_ASSERT(pMark!=0L,"ReplaceMark: MarkEntry not found.");
456 :
457 0 : if(pMark)
458 : {
459 0 : delete pMark;
460 0 : SetNameDirty();
461 0 : SdrMark* pKopie = new SdrMark(rNewMark);
462 0 : maList[nNum] = pKopie;
463 0 : mbSorted = false;
464 : }
465 0 : }
466 :
467 0 : void SdrMarkList::Merge(const SdrMarkList& rSrcList, bool bReverse)
468 : {
469 0 : sal_uLong nAnz(rSrcList.maList.size());
470 :
471 0 : if(rSrcList.mbSorted)
472 : {
473 : // merge without forcing a Sort in rSrcList
474 0 : bReverse = false;
475 : }
476 :
477 0 : if(!bReverse)
478 : {
479 0 : for(sal_uLong i(0L); i < nAnz; i++)
480 : {
481 0 : SdrMark* pM = rSrcList.maList[i];
482 0 : InsertEntry(*pM);
483 : }
484 : }
485 : else
486 : {
487 0 : for(sal_uLong i(nAnz); i > 0;)
488 : {
489 0 : i--;
490 0 : SdrMark* pM = rSrcList.maList[i];
491 0 : InsertEntry(*pM);
492 : }
493 : }
494 0 : }
495 :
496 0 : bool SdrMarkList::DeletePageView(const SdrPageView& rPV)
497 : {
498 0 : bool bChgd(false);
499 :
500 0 : for(std::vector<SdrMark*>::iterator it = maList.begin(); it != maList.end(); )
501 : {
502 0 : SdrMark* pMark = *it;
503 :
504 0 : if(pMark->GetPageView()==&rPV)
505 : {
506 0 : it = maList.erase(it);
507 0 : delete pMark;
508 0 : SetNameDirty();
509 0 : bChgd = true;
510 : }
511 : else
512 0 : ++it;
513 : }
514 :
515 0 : 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 0 : const OUString& SdrMarkList::GetMarkDescription() const
544 : {
545 0 : sal_uLong nAnz(GetMarkCount());
546 :
547 0 : 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 0 : if(!mbNameOk)
560 : {
561 0 : SdrMark* pMark = GetMark(0);
562 0 : OUString aNam;
563 :
564 0 : if(!nAnz)
565 : {
566 0 : const_cast<SdrMarkList*>(this)->maMarkName = ImpGetResStr(STR_ObjNameNoObj);
567 : }
568 0 : else if(1L == nAnz)
569 : {
570 0 : if(pMark->GetMarkedSdrObj())
571 : {
572 0 : aNam = pMark->GetMarkedSdrObj()->TakeObjNameSingul();
573 : }
574 : }
575 : else
576 : {
577 0 : if(pMark->GetMarkedSdrObj())
578 : {
579 0 : aNam = pMark->GetMarkedSdrObj()->TakeObjNamePlural();
580 0 : bool bEq(true);
581 :
582 0 : for(sal_uLong i = 1; i < GetMarkCount() && bEq; i++)
583 : {
584 0 : SdrMark* pMark2 = GetMark(i);
585 0 : OUString aStr1(pMark2->GetMarkedSdrObj()->TakeObjNamePlural());
586 0 : bEq = aNam == aStr1;
587 0 : }
588 :
589 0 : if(!bEq)
590 : {
591 0 : aNam = ImpGetResStr(STR_ObjNamePlural);
592 : }
593 : }
594 :
595 0 : aNam = OUString::number( nAnz ) + " " + aNam;
596 : }
597 :
598 0 : const_cast<SdrMarkList*>(this)->maMarkName = aNam;
599 0 : const_cast<SdrMarkList*>(this)->mbNameOk = true;
600 : }
601 :
602 0 : 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 0 : bool SdrMarkList::TakeBoundRect(SdrPageView* pPV, Rectangle& rRect) const
717 : {
718 0 : bool bFnd(false);
719 0 : Rectangle aR;
720 :
721 0 : for(sal_uLong i(0L); i < GetMarkCount(); i++)
722 : {
723 0 : SdrMark* pMark = GetMark(i);
724 :
725 0 : if(!pPV || pMark->GetPageView() == pPV)
726 : {
727 0 : if(pMark->GetMarkedSdrObj())
728 : {
729 0 : aR = pMark->GetMarkedSdrObj()->GetCurrentBoundRect();
730 :
731 0 : if(bFnd)
732 : {
733 0 : rRect.Union(aR);
734 : }
735 : else
736 : {
737 0 : rRect = aR;
738 0 : bFnd = true;
739 : }
740 : }
741 : }
742 : }
743 :
744 0 : return bFnd;
745 : }
746 :
747 0 : bool SdrMarkList::TakeSnapRect(SdrPageView* pPV, Rectangle& rRect) const
748 : {
749 0 : bool bFnd(false);
750 :
751 0 : for(sal_uLong i(0L); i < GetMarkCount(); i++)
752 : {
753 0 : SdrMark* pMark = GetMark(i);
754 :
755 0 : if(!pPV || pMark->GetPageView() == pPV)
756 : {
757 0 : if(pMark->GetMarkedSdrObj())
758 : {
759 0 : Rectangle aR(pMark->GetMarkedSdrObj()->GetSnapRect());
760 :
761 0 : if(bFnd)
762 : {
763 0 : rRect.Union(aR);
764 : }
765 : else
766 : {
767 0 : rRect = aR;
768 0 : bFnd = true;
769 : }
770 : }
771 : }
772 : }
773 :
774 0 : return bFnd;
775 : }
776 :
777 :
778 :
779 : namespace sdr
780 : {
781 0 : ViewSelection::ViewSelection()
782 0 : : mbEdgesOfMarkedNodesDirty(false)
783 : {
784 0 : }
785 :
786 0 : void ViewSelection::SetEdgesOfMarkedNodesDirty()
787 : {
788 0 : if(!mbEdgesOfMarkedNodesDirty)
789 : {
790 0 : mbEdgesOfMarkedNodesDirty = true;
791 0 : maEdgesOfMarkedNodes.Clear();
792 0 : maMarkedEdgesOfMarkedNodes.Clear();
793 0 : maAllMarkedObjects.clear();
794 : }
795 0 : }
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 0 : const SdrMarkList& ViewSelection::GetMarkedEdgesOfMarkedNodes() const
808 : {
809 0 : if(mbEdgesOfMarkedNodesDirty)
810 : {
811 0 : ((ViewSelection*)this)->ImpForceEdgesOfMarkedNodes();
812 : }
813 :
814 0 : return maMarkedEdgesOfMarkedNodes;
815 : }
816 :
817 0 : const std::vector<SdrObject*>& ViewSelection::GetAllMarkedObjects() const
818 : {
819 0 : if(mbEdgesOfMarkedNodesDirty)
820 0 : ((ViewSelection*)this)->ImpForceEdgesOfMarkedNodes();
821 :
822 0 : return maAllMarkedObjects;
823 : }
824 :
825 0 : void ViewSelection::ImplCollectCompleteSelection(SdrObject* pObj)
826 : {
827 0 : if(pObj)
828 : {
829 0 : bool bIsGroup(pObj->IsGroupObject());
830 :
831 0 : if(bIsGroup && pObj->ISA(E3dObject) && !pObj->ISA(E3dScene))
832 : {
833 0 : bIsGroup = false;
834 : }
835 :
836 0 : if(bIsGroup)
837 : {
838 0 : SdrObjList* pList = pObj->GetSubList();
839 :
840 0 : for(sal_uLong a(0L); a < pList->GetObjCount(); a++)
841 : {
842 0 : SdrObject* pObj2 = pList->GetObj(a);
843 0 : ImplCollectCompleteSelection(pObj2);
844 : }
845 : }
846 :
847 0 : maAllMarkedObjects.push_back(pObj);
848 : }
849 0 : }
850 :
851 0 : void ViewSelection::ImpForceEdgesOfMarkedNodes()
852 : {
853 0 : if(mbEdgesOfMarkedNodesDirty)
854 : {
855 0 : mbEdgesOfMarkedNodesDirty = false;
856 0 : maMarkedObjectList.ForceSort();
857 0 : maEdgesOfMarkedNodes.Clear();
858 0 : maMarkedEdgesOfMarkedNodes.Clear();
859 0 : maAllMarkedObjects.clear();
860 :
861 : // GetMarkCount after ForceSort
862 0 : const sal_uLong nMarkAnz(maMarkedObjectList.GetMarkCount());
863 :
864 0 : for(sal_uLong a(0L); a < nMarkAnz; a++)
865 : {
866 0 : SdrObject* pCandidate = maMarkedObjectList.GetMark(a)->GetMarkedSdrObj();
867 :
868 0 : if(pCandidate)
869 : {
870 : // build transitive hull
871 0 : ImplCollectCompleteSelection(pCandidate);
872 :
873 0 : if(pCandidate->IsNode())
874 : {
875 : // travel over broadcaster/listener to access edges connected to the selected object
876 0 : const SfxBroadcaster* pBC = pCandidate->GetBroadcaster();
877 :
878 0 : 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 0 : maEdgesOfMarkedNodes.ForceSort();
918 0 : maMarkedEdgesOfMarkedNodes.ForceSort();
919 : }
920 0 : }
921 : } // end of namespace sdr
922 :
923 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|