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> // To turn off
30 : #include <svx/svdogrp.hxx> // the cache at
31 : #include <svx/svdorect.hxx> // GetMarkDescription.
32 : #include "svx/svdstr.hrc" // names taken from the resource
33 : #include "svx/svdglob.hxx" // StringCache
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 13 : SdrMark::SdrMark(SdrObject* pNewObj, SdrPageView* pNewPageView)
45 : : mpSelectedSdrObject(pNewObj),
46 : mpPageView(pNewPageView),
47 : mpPoints(0L),
48 : mpLines(0L),
49 : mpGluePoints(0L),
50 : mbCon1(sal_False),
51 : mbCon2(sal_False),
52 13 : mnUser(0)
53 : {
54 13 : if(mpSelectedSdrObject)
55 : {
56 13 : mpSelectedSdrObject->AddObjectUser( *this );
57 : }
58 13 : }
59 :
60 13 : SdrMark::SdrMark(const SdrMark& rMark)
61 : : ObjectUser(),
62 : mpSelectedSdrObject(0L),
63 : mpPageView(0L),
64 : mpPoints(0L),
65 : mpLines(0L),
66 : mpGluePoints(0L),
67 : mbCon1(sal_False),
68 : mbCon2(sal_False),
69 13 : mnUser(0)
70 : {
71 13 : *this = rMark;
72 13 : }
73 :
74 65 : SdrMark::~SdrMark()
75 : {
76 26 : if(mpSelectedSdrObject)
77 : {
78 26 : mpSelectedSdrObject->RemoveObjectUser( *this );
79 : }
80 :
81 26 : if(mpPoints)
82 : {
83 0 : delete mpPoints;
84 : }
85 :
86 26 : if(mpLines)
87 : {
88 0 : delete mpLines;
89 : }
90 :
91 26 : if(mpGluePoints)
92 : {
93 0 : delete mpGluePoints;
94 : }
95 39 : }
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 13 : void SdrMark::SetMarkedSdrObj(SdrObject* pNewObj)
106 : {
107 13 : if(mpSelectedSdrObject)
108 : {
109 0 : mpSelectedSdrObject->RemoveObjectUser( *this );
110 : }
111 :
112 13 : mpSelectedSdrObject = pNewObj;
113 :
114 13 : if(mpSelectedSdrObject)
115 : {
116 13 : mpSelectedSdrObject->AddObjectUser( *this );
117 : }
118 13 : }
119 :
120 156 : SdrObject* SdrMark::GetMarkedSdrObj() const
121 : {
122 156 : return mpSelectedSdrObject;
123 : }
124 :
125 13 : SdrMark& SdrMark::operator=(const SdrMark& rMark)
126 : {
127 13 : SetMarkedSdrObj(rMark.mpSelectedSdrObject);
128 13 : mpPageView = rMark.mpPageView;
129 13 : mbCon1 = rMark.mbCon1;
130 13 : mbCon2 = rMark.mbCon2;
131 13 : mnUser = rMark.mnUser;
132 :
133 13 : if(!rMark.mpPoints)
134 : {
135 13 : 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 13 : if(!rMark.mpLines)
154 : {
155 13 : 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 13 : if(!rMark.mpGluePoints)
174 : {
175 13 : 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 13 : return *this;
194 : }
195 :
196 0 : sal_Bool SdrMark::operator==(const SdrMark& rMark) const
197 : {
198 0 : sal_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 = sal_False;
202 :
203 0 : if((mpLines != 0L) != (rMark.mpLines != 0L))
204 0 : bRet = sal_False;
205 :
206 0 : if((mpGluePoints != 0L) != (rMark.mpGluePoints != 0L))
207 0 : bRet = sal_False;
208 :
209 0 : if(bRet && mpPoints && *mpPoints != *rMark.mpPoints)
210 0 : bRet = sal_False;
211 :
212 0 : if(bRet && mpLines && *mpLines != *rMark.mpLines)
213 0 : bRet = sal_False;
214 :
215 0 : if(bRet && mpGluePoints && *mpGluePoints != *rMark.mpGluePoints)
216 0 : bRet = sal_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 (long)pOL1 < (long)pOL2;
243 : }
244 : }
245 :
246 : ////////////////////////////////////////////////////////////////////////////////////////////////////
247 :
248 339 : void SdrMarkList::ForceSort() const
249 : {
250 339 : if(!mbSorted)
251 : {
252 182 : ((SdrMarkList*)this)->ImpForceSort();
253 : }
254 339 : }
255 :
256 182 : void SdrMarkList::ImpForceSort()
257 : {
258 182 : if(!mbSorted)
259 : {
260 182 : mbSorted = sal_True;
261 182 : sal_uLong nAnz = maList.size();
262 :
263 : // remove invalid
264 182 : 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 182 : 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(sal_True);
297 :
298 0 : if(pCmp->IsCon2())
299 0 : pAkt->SetCon2(sal_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 182 : }
317 :
318 2429 : void SdrMarkList::Clear()
319 : {
320 2442 : for(sal_uLong i(0L); i < GetMarkCount(); i++)
321 : {
322 13 : SdrMark* pMark = GetMark(i);
323 13 : delete pMark;
324 : }
325 :
326 2429 : maList.clear();
327 2429 : SetNameDirty();
328 2429 : }
329 :
330 9 : void SdrMarkList::operator=(const SdrMarkList& rLst)
331 : {
332 9 : Clear();
333 :
334 9 : 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 9 : maMarkName = rLst.maMarkName;
342 9 : mbNameOk = rLst.mbNameOk;
343 9 : maPointName = rLst.maPointName;
344 9 : mbPointNameOk = rLst.mbPointNameOk;
345 9 : maGluePointName = rLst.maGluePointName;
346 9 : mbGluePointNameOk = rLst.mbGluePointNameOk;
347 9 : mbSorted = rLst.mbSorted;
348 9 : }
349 :
350 153 : SdrMark* SdrMarkList::GetMark(sal_uLong nNum) const
351 : {
352 153 : 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 13 : void SdrMarkList::InsertEntry(const SdrMark& rMark, sal_Bool bChkSort)
381 : {
382 13 : SetNameDirty();
383 13 : sal_uLong nAnz(maList.size());
384 :
385 13 : if(!bChkSort || !mbSorted || nAnz == 0)
386 : {
387 13 : if(!bChkSort)
388 0 : mbSorted = sal_False;
389 :
390 13 : 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(sal_True);
404 :
405 0 : if(rMark.IsCon2())
406 0 : pLast->SetCon2(sal_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 = sal_False;
426 : }
427 : }
428 : else
429 : {
430 : // at some point, we have to sort
431 0 : mbSorted = sal_False;
432 : }
433 : }
434 : }
435 :
436 13 : 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 = sal_False;
464 : }
465 0 : }
466 :
467 0 : void SdrMarkList::Merge(const SdrMarkList& rSrcList, sal_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 = sal_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 65 : sal_Bool SdrMarkList::DeletePageView(const SdrPageView& rPV)
497 : {
498 65 : sal_Bool bChgd(sal_False);
499 :
500 130 : 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 = sal_True;
510 : }
511 : else
512 0 : ++it;
513 : }
514 :
515 65 : return bChgd;
516 : }
517 :
518 0 : sal_Bool SdrMarkList::InsertPageView(const SdrPageView& rPV)
519 : {
520 0 : sal_Bool bChgd(sal_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 : sal_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 = sal_True;
537 : }
538 : }
539 :
540 0 : return bChgd;
541 : }
542 :
543 0 : const XubString& 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 = sal_False;
556 : }
557 : }
558 :
559 0 : if(!mbNameOk)
560 : {
561 0 : SdrMark* pMark = GetMark(0);
562 0 : XubString aNam;
563 :
564 0 : if(!nAnz)
565 : {
566 0 : ((SdrMarkList*)(this))->maMarkName = ImpGetResStr(STR_ObjNameNoObj);
567 : }
568 0 : else if(1L == nAnz)
569 : {
570 0 : if(pMark->GetMarkedSdrObj())
571 : {
572 0 : pMark->GetMarkedSdrObj()->TakeObjNameSingul(aNam);
573 : }
574 : }
575 : else
576 : {
577 0 : if(pMark->GetMarkedSdrObj())
578 : {
579 0 : pMark->GetMarkedSdrObj()->TakeObjNamePlural(aNam);
580 0 : XubString aStr1;
581 0 : sal_Bool bEq(sal_True);
582 :
583 0 : for(sal_uLong i = 1; i < GetMarkCount() && bEq; i++)
584 : {
585 0 : SdrMark* pMark2 = GetMark(i);
586 0 : pMark2->GetMarkedSdrObj()->TakeObjNamePlural(aStr1);
587 0 : bEq = aNam.Equals(aStr1);
588 : }
589 :
590 0 : if(!bEq)
591 : {
592 0 : aNam = ImpGetResStr(STR_ObjNamePlural);
593 0 : }
594 : }
595 :
596 0 : aNam.Insert(sal_Unicode(' '), 0);
597 0 : aNam.Insert(UniString::CreateFromInt32(nAnz), 0);
598 : }
599 :
600 0 : ((SdrMarkList*)(this))->maMarkName = aNam;
601 0 : ((SdrMarkList*)(this))->mbNameOk = sal_True;
602 : }
603 :
604 0 : return maMarkName;
605 : }
606 :
607 0 : const XubString& SdrMarkList::GetPointMarkDescription(sal_Bool bGlue) const
608 : {
609 0 : sal_Bool& rNameOk = (sal_Bool&)(bGlue ? mbGluePointNameOk : mbPointNameOk);
610 0 : XubString& rName = (XubString&)(bGlue ? maGluePointName : maPointName);
611 0 : sal_uLong nMarkAnz(GetMarkCount());
612 0 : sal_uLong nMarkPtAnz(0L);
613 0 : sal_uLong nMarkPtObjAnz(0L);
614 0 : sal_uLong n1stMarkNum(ULONG_MAX);
615 :
616 0 : for(sal_uLong nMarkNum(0L); nMarkNum < nMarkAnz; nMarkNum++)
617 : {
618 0 : const SdrMark* pMark = GetMark(nMarkNum);
619 0 : const SdrUShortCont* pPts = bGlue ? pMark->GetMarkedGluePoints() : pMark->GetMarkedPoints();
620 0 : sal_uLong nAnz(pPts ? pPts->size() : 0);
621 :
622 0 : if(nAnz)
623 : {
624 0 : if(n1stMarkNum == ULONG_MAX)
625 : {
626 0 : n1stMarkNum = nMarkNum;
627 : }
628 :
629 0 : nMarkPtAnz += nAnz;
630 0 : nMarkPtObjAnz++;
631 : }
632 :
633 0 : if(nMarkPtObjAnz > 1 && rNameOk)
634 : {
635 : // preliminary decision
636 0 : return rName;
637 : }
638 : }
639 :
640 0 : if(rNameOk && 1L == nMarkPtObjAnz)
641 : {
642 : // if it's a single selection, cache only text frame
643 0 : const SdrObject* pObj = GetMark(0)->GetMarkedSdrObj();
644 0 : const SdrTextObj* pTextObj = PTR_CAST(SdrTextObj,pObj);
645 :
646 0 : if(!pTextObj || !pTextObj->IsTextFrame())
647 : {
648 0 : rNameOk = sal_False;
649 : }
650 : }
651 :
652 0 : if(!nMarkPtObjAnz)
653 : {
654 0 : rName.Erase();
655 0 : rNameOk = sal_True;
656 : }
657 0 : else if(!rNameOk)
658 : {
659 0 : const SdrMark* pMark = GetMark(n1stMarkNum);
660 0 : XubString aNam;
661 :
662 0 : if(1L == nMarkPtObjAnz)
663 : {
664 0 : if(pMark->GetMarkedSdrObj())
665 : {
666 0 : pMark->GetMarkedSdrObj()->TakeObjNameSingul(aNam);
667 : }
668 : }
669 : else
670 : {
671 0 : if(pMark->GetMarkedSdrObj())
672 : {
673 0 : pMark->GetMarkedSdrObj()->TakeObjNamePlural(aNam);
674 : }
675 :
676 0 : XubString aStr1;
677 0 : sal_Bool bEq(sal_True);
678 :
679 0 : for(sal_uLong i(n1stMarkNum + 1L); i < GetMarkCount() && bEq; i++)
680 : {
681 0 : const SdrMark* pMark2 = GetMark(i);
682 0 : const SdrUShortCont* pPts = bGlue ? pMark2->GetMarkedGluePoints() : pMark2->GetMarkedPoints();
683 :
684 0 : if(pPts && !pPts->empty() && pMark2->GetMarkedSdrObj())
685 : {
686 0 : pMark2->GetMarkedSdrObj()->TakeObjNamePlural(aStr1);
687 0 : bEq = aNam.Equals(aStr1);
688 : }
689 : }
690 :
691 0 : if(!bEq)
692 : {
693 0 : aNam = ImpGetResStr(STR_ObjNamePlural);
694 : }
695 :
696 0 : aNam.Insert(sal_Unicode(' '), 0);
697 0 : aNam.Insert(UniString::CreateFromInt32(nMarkPtObjAnz), 0);
698 : }
699 :
700 0 : XubString aStr1;
701 :
702 0 : if(1L == nMarkPtAnz)
703 : {
704 0 : aStr1 = (ImpGetResStr(bGlue ? STR_ViewMarkedGluePoint : STR_ViewMarkedPoint));
705 : }
706 : else
707 : {
708 0 : aStr1 = (ImpGetResStr(bGlue ? STR_ViewMarkedGluePoints : STR_ViewMarkedPoints));
709 0 : aStr1.SearchAndReplaceAscii("%2", UniString::CreateFromInt32(nMarkPtAnz));
710 : }
711 :
712 0 : aStr1.SearchAndReplaceAscii("%1", aNam);
713 0 : rName = aStr1;
714 0 : rNameOk = sal_True;
715 : }
716 :
717 0 : return rName;
718 : }
719 :
720 2109 : sal_Bool SdrMarkList::TakeBoundRect(SdrPageView* pPV, Rectangle& rRect) const
721 : {
722 2109 : sal_Bool bFnd(sal_False);
723 2109 : Rectangle aR;
724 :
725 2122 : for(sal_uLong i(0L); i < GetMarkCount(); i++)
726 : {
727 13 : SdrMark* pMark = GetMark(i);
728 :
729 13 : if(!pPV || pMark->GetPageView() == pPV)
730 : {
731 13 : if(pMark->GetMarkedSdrObj())
732 : {
733 13 : aR = pMark->GetMarkedSdrObj()->GetCurrentBoundRect();
734 :
735 13 : if(bFnd)
736 : {
737 0 : rRect.Union(aR);
738 : }
739 : else
740 : {
741 13 : rRect = aR;
742 13 : bFnd = sal_True;
743 : }
744 : }
745 : }
746 : }
747 :
748 2109 : return bFnd;
749 : }
750 :
751 2109 : sal_Bool SdrMarkList::TakeSnapRect(SdrPageView* pPV, Rectangle& rRect) const
752 : {
753 2109 : sal_Bool bFnd(sal_False);
754 :
755 2122 : for(sal_uLong i(0L); i < GetMarkCount(); i++)
756 : {
757 13 : SdrMark* pMark = GetMark(i);
758 :
759 13 : if(!pPV || pMark->GetPageView() == pPV)
760 : {
761 13 : if(pMark->GetMarkedSdrObj())
762 : {
763 13 : Rectangle aR(pMark->GetMarkedSdrObj()->GetSnapRect());
764 :
765 13 : if(bFnd)
766 : {
767 0 : rRect.Union(aR);
768 : }
769 : else
770 : {
771 13 : rRect = aR;
772 13 : bFnd = sal_True;
773 : }
774 : }
775 : }
776 : }
777 :
778 2109 : return bFnd;
779 : }
780 :
781 : ////////////////////////////////////////////////////////////////////////////////////////////////////
782 :
783 : namespace sdr
784 : {
785 640 : ViewSelection::ViewSelection()
786 640 : : mbEdgesOfMarkedNodesDirty(sal_False)
787 : {
788 640 : }
789 :
790 272 : void ViewSelection::SetEdgesOfMarkedNodesDirty()
791 : {
792 272 : if(!mbEdgesOfMarkedNodesDirty)
793 : {
794 258 : mbEdgesOfMarkedNodesDirty = sal_True;
795 258 : maEdgesOfMarkedNodes.Clear();
796 258 : maMarkedEdgesOfMarkedNodes.Clear();
797 258 : maAllMarkedObjects.clear();
798 : }
799 272 : }
800 :
801 0 : const SdrMarkList& ViewSelection::GetEdgesOfMarkedNodes() const
802 : {
803 0 : if(mbEdgesOfMarkedNodesDirty)
804 : {
805 0 : ((ViewSelection*)this)->ImpForceEdgesOfMarkedNodes();
806 : }
807 :
808 0 : return maEdgesOfMarkedNodes;
809 : }
810 :
811 0 : const SdrMarkList& ViewSelection::GetMarkedEdgesOfMarkedNodes() const
812 : {
813 0 : if(mbEdgesOfMarkedNodesDirty)
814 : {
815 0 : ((ViewSelection*)this)->ImpForceEdgesOfMarkedNodes();
816 : }
817 :
818 0 : return maMarkedEdgesOfMarkedNodes;
819 : }
820 :
821 0 : const std::vector<SdrObject*>& ViewSelection::GetAllMarkedObjects() const
822 : {
823 0 : if(mbEdgesOfMarkedNodesDirty)
824 0 : ((ViewSelection*)this)->ImpForceEdgesOfMarkedNodes();
825 :
826 0 : return maAllMarkedObjects;
827 : }
828 :
829 0 : void ViewSelection::ImplCollectCompleteSelection(SdrObject* pObj)
830 : {
831 0 : if(pObj)
832 : {
833 0 : sal_Bool bIsGroup(pObj->IsGroupObject());
834 :
835 0 : if(bIsGroup && pObj->ISA(E3dObject) && !pObj->ISA(E3dScene))
836 : {
837 0 : bIsGroup = sal_False;
838 : }
839 :
840 0 : if(bIsGroup)
841 : {
842 0 : SdrObjList* pList = pObj->GetSubList();
843 :
844 0 : for(sal_uLong a(0L); a < pList->GetObjCount(); a++)
845 : {
846 0 : SdrObject* pObj2 = pList->GetObj(a);
847 0 : ImplCollectCompleteSelection(pObj2);
848 : }
849 : }
850 :
851 0 : maAllMarkedObjects.push_back(pObj);
852 : }
853 0 : }
854 :
855 0 : void ViewSelection::ImpForceEdgesOfMarkedNodes()
856 : {
857 0 : if(mbEdgesOfMarkedNodesDirty)
858 : {
859 0 : mbEdgesOfMarkedNodesDirty = sal_False;
860 0 : maMarkedObjectList.ForceSort();
861 0 : maEdgesOfMarkedNodes.Clear();
862 0 : maMarkedEdgesOfMarkedNodes.Clear();
863 0 : maAllMarkedObjects.clear();
864 :
865 : // GetMarkCount after ForceSort
866 0 : const sal_uLong nMarkAnz(maMarkedObjectList.GetMarkCount());
867 :
868 0 : for(sal_uLong a(0L); a < nMarkAnz; a++)
869 : {
870 0 : SdrObject* pCandidate = maMarkedObjectList.GetMark(a)->GetMarkedSdrObj();
871 :
872 0 : if(pCandidate)
873 : {
874 : // build transitive hull
875 0 : ImplCollectCompleteSelection(pCandidate);
876 :
877 0 : if(pCandidate->IsNode())
878 : {
879 : // travel over broadcaster/listener to access edges connected to the selected object
880 0 : const SfxBroadcaster* pBC = pCandidate->GetBroadcaster();
881 :
882 0 : if(pBC)
883 : {
884 0 : sal_uInt16 nLstAnz(pBC->GetListenerCount());
885 :
886 0 : for(sal_uInt16 nl(0); nl < nLstAnz; nl++)
887 : {
888 0 : SfxListener* pLst = pBC->GetListener(nl);
889 0 : SdrEdgeObj* pEdge = PTR_CAST(SdrEdgeObj, pLst);
890 :
891 0 : if(pEdge && pEdge->IsInserted() && pEdge->GetPage() == pCandidate->GetPage())
892 : {
893 0 : SdrMark aM(pEdge, maMarkedObjectList.GetMark(a)->GetPageView());
894 :
895 0 : if(pEdge->GetConnectedNode(sal_True) == pCandidate)
896 : {
897 0 : aM.SetCon1(sal_True);
898 : }
899 :
900 0 : if(pEdge->GetConnectedNode(sal_False) == pCandidate)
901 : {
902 0 : aM.SetCon2(sal_True);
903 : }
904 :
905 0 : if(CONTAINER_ENTRY_NOTFOUND == maMarkedObjectList.FindObject(pEdge))
906 : {
907 : // check if it itself is selected
908 0 : maEdgesOfMarkedNodes.InsertEntry(aM);
909 : }
910 : else
911 : {
912 0 : maMarkedEdgesOfMarkedNodes.InsertEntry(aM);
913 0 : }
914 : }
915 : }
916 : }
917 : }
918 : }
919 : }
920 :
921 0 : maEdgesOfMarkedNodes.ForceSort();
922 0 : maMarkedEdgesOfMarkedNodes.ForceSort();
923 : }
924 0 : }
925 : } // end of namespace sdr
926 :
927 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|