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