xref: /AOO41X/main/svx/source/svdraw/svdmrkv1.cxx (revision f6e50924346d0b8c0b07c91832a97665dd718b0c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 
27 #include <svx/svdmrkv.hxx>
28 #include <svx/svdetc.hxx>
29 #include <svx/svdoedge.hxx>
30 #include "svx/svdglob.hxx"
31 #include <svx/svdpagv.hxx>
32 #include <svx/svdpage.hxx>
33 #include "svddrgm1.hxx"
34 
35 ////////////////////////////////////////////////////////////////////////////////////////////////////
36 ////////////////////////////////////////////////////////////////////////////////////////////////////
37 ////////////////////////////////////////////////////////////////////////////////////////////////////
38 //
39 //  @@@@@  @@  @@ @@  @@ @@  @@ @@@@@@ @@   @@  @@@@  @@@@@  @@  @@ @@ @@@@@ @@@@@  @@  @@ @@  @@  @@@@
40 //  @@  @@ @@  @@ @@@ @@ @@  @@   @@   @@@ @@@ @@  @@ @@  @@ @@  @@ @@ @@    @@  @@ @@  @@ @@@ @@ @@  @@
41 //  @@  @@ @@  @@ @@@@@@ @@ @@    @@   @@@@@@@ @@  @@ @@  @@ @@ @@  @@ @@    @@  @@ @@  @@ @@@@@@ @@
42 //  @@@@@  @@  @@ @@@@@@ @@@@     @@   @@@@@@@ @@@@@@ @@@@@  @@@@   @@ @@@@  @@@@@  @@  @@ @@@@@@ @@ @@@
43 //  @@     @@  @@ @@ @@@ @@ @@    @@   @@ @ @@ @@  @@ @@  @@ @@ @@  @@ @@    @@  @@ @@  @@ @@ @@@ @@  @@
44 //  @@     @@  @@ @@  @@ @@  @@   @@   @@   @@ @@  @@ @@  @@ @@  @@ @@ @@    @@  @@ @@  @@ @@  @@ @@  @@
45 //  @@      @@@@  @@  @@ @@  @@   @@   @@   @@ @@  @@ @@  @@ @@  @@ @@ @@@@@ @@  @@  @@@@  @@  @@  @@@@@
46 //
47 ////////////////////////////////////////////////////////////////////////////////////////////////////
48 
HasMarkablePoints() const49 sal_Bool SdrMarkView::HasMarkablePoints() const
50 {
51     ForceUndirtyMrkPnt();
52     bool bRet=false;
53     if (!ImpIsFrameHandles()) {
54         sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
55         if (nMarkAnz<=nFrameHandlesLimit) {
56             for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz && !bRet; nMarkNum++) {
57                 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
58                 const SdrObject* pObj=pM->GetMarkedSdrObj();
59                 bRet=pObj->IsPolyObj();
60             }
61         }
62     }
63     return bRet;
64 }
65 
GetMarkablePointCount() const66 sal_uIntPtr SdrMarkView::GetMarkablePointCount() const
67 {
68     ForceUndirtyMrkPnt();
69     sal_uIntPtr nAnz=0;
70     if (!ImpIsFrameHandles()) {
71         sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
72         if (nMarkAnz<=nFrameHandlesLimit) {
73             for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++) {
74                 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
75                 const SdrObject* pObj=pM->GetMarkedSdrObj();
76                 if (pObj->IsPolyObj()) {
77                     nAnz+=pObj->GetPointCount();
78                 }
79             }
80         }
81     }
82     return nAnz;
83 }
84 
HasMarkedPoints() const85 sal_Bool SdrMarkView::HasMarkedPoints() const
86 {
87     ForceUndirtyMrkPnt();
88     sal_Bool bRet=sal_False;
89     if (!ImpIsFrameHandles()) {
90         sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
91         if (nMarkAnz<=nFrameHandlesLimit) {
92             for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz && !bRet; nMarkNum++) {
93                 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
94                 const SdrUShortCont* pPts=pM->GetMarkedPoints();
95                 bRet=pPts!=NULL && pPts->GetCount()!=0;
96             }
97         }
98     }
99     return bRet;
100 }
101 
GetMarkedPointCount() const102 sal_uIntPtr SdrMarkView::GetMarkedPointCount() const
103 {
104     ForceUndirtyMrkPnt();
105     sal_uIntPtr nAnz=0;
106     if (!ImpIsFrameHandles()) {
107         sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
108         if (nMarkAnz<=nFrameHandlesLimit) {
109             for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++) {
110                 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
111                 const SdrUShortCont* pPts=pM->GetMarkedPoints();
112                 if (pPts!=NULL) nAnz+=pPts->GetCount();
113             }
114         }
115     }
116     return nAnz;
117 }
118 
IsPointMarkable(const SdrHdl & rHdl) const119 sal_Bool SdrMarkView::IsPointMarkable(const SdrHdl& rHdl) const
120 {
121     return !ImpIsFrameHandles() && &rHdl!=NULL && !rHdl.IsPlusHdl() && rHdl.GetKind()!=HDL_GLUE && rHdl.GetKind()!=HDL_SMARTTAG && rHdl.GetObj()!=NULL && rHdl.GetObj()->IsPolyObj();
122 }
123 
MarkPointHelper(SdrHdl * pHdl,SdrMark * pMark,sal_Bool bUnmark)124 sal_Bool SdrMarkView::MarkPointHelper(SdrHdl* pHdl, SdrMark* pMark, sal_Bool bUnmark)
125 {
126     return ImpMarkPoint( pHdl, pMark, bUnmark );
127 }
128 
ImpMarkPoint(SdrHdl * pHdl,SdrMark * pMark,sal_Bool bUnmark)129 sal_Bool SdrMarkView::ImpMarkPoint(SdrHdl* pHdl, SdrMark* pMark, sal_Bool bUnmark)
130 {
131     if (pHdl==NULL || pHdl->IsPlusHdl() || pHdl->GetKind()==HDL_GLUE)
132         return sal_False;
133 
134     if (pHdl->IsSelected() != bUnmark)
135         return sal_False;
136 
137     SdrObject* pObj=pHdl->GetObj();
138     if (pObj==NULL || !pObj->IsPolyObj())
139         return sal_False;
140 
141     if (pMark==NULL)
142     {
143         sal_uIntPtr nMarkNum=TryToFindMarkedObject(pObj);
144         if (nMarkNum==CONTAINER_ENTRY_NOTFOUND)
145             return sal_False;
146         pMark=GetSdrMarkByIndex(nMarkNum);
147     }
148     const sal_uInt32 nHdlNum(pHdl->GetObjHdlNum());
149     SdrUShortCont* pPts=pMark->ForceMarkedPoints();
150     if (!bUnmark)
151     {
152         pPts->Insert((sal_uInt16)nHdlNum);
153     }
154     else
155     {
156         sal_uIntPtr nBla=pPts->GetPos((sal_uInt16)nHdlNum);
157         if (nBla!=CONTAINER_ENTRY_NOTFOUND)
158         {
159             pPts->Remove(nBla);
160         }
161         else
162         {
163             return sal_False; // Fehlerfall!
164         }
165     }
166 
167     pHdl->SetSelected(!bUnmark);
168     if (!bPlusHdlAlways)
169     {
170         if (!bUnmark)
171         {
172             sal_uInt32 nAnz(pObj->GetPlusHdlCount(*pHdl));
173             for (sal_uInt32 i=0; i<nAnz; i++)
174             {
175                 SdrHdl* pPlusHdl=pObj->GetPlusHdl(*pHdl,i);
176                 if (pPlusHdl!=NULL)
177                 {
178                     pPlusHdl->SetObj(pObj);
179                     pPlusHdl->SetPageView(pMark->GetPageView());
180                     pPlusHdl->SetPlusHdl(sal_True);
181                     aHdl.AddHdl(pPlusHdl);
182                 }
183             }
184         }
185         else
186         {
187             for (sal_uIntPtr i = aHdl.GetHdlCount(); i>0;)
188             {
189                 i--;
190                 SdrHdl* pPlusHdl=aHdl.GetHdl(i);
191                 if (pPlusHdl->IsPlusHdl() && pPlusHdl->GetSourceHdlNum()==nHdlNum)
192                 {
193                     aHdl.RemoveHdl(i);
194                     delete pPlusHdl;
195                 }
196             }
197         }
198     }
199 
200     // #97016# II: Sort handles. This was missing in ImpMarkPoint all the time.
201     aHdl.Sort();
202 
203     return sal_True;
204 }
205 
206 
MarkPoint(SdrHdl & rHdl,sal_Bool bUnmark)207 sal_Bool SdrMarkView::MarkPoint(SdrHdl& rHdl, sal_Bool bUnmark)
208 {
209     if (&rHdl==NULL) return sal_False;
210     ForceUndirtyMrkPnt();
211     sal_Bool bRet=sal_False;
212     const SdrObject* pObj=rHdl.GetObj();
213     if (IsPointMarkable(rHdl) && rHdl.IsSelected()==bUnmark) {
214         sal_uIntPtr nMarkNum=TryToFindMarkedObject(pObj);
215         if (nMarkNum!=CONTAINER_ENTRY_NOTFOUND) {
216             SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
217             SdrUShortCont* pPts=pM->ForceMarkedPoints();
218             pPts->ForceSort();
219             if (ImpMarkPoint(&rHdl,pM,bUnmark)) {
220                 pPts->ForceSort();
221                 MarkListHasChanged();
222                 bRet=sal_True;
223             }
224         }
225     }
226 
227     return bRet;
228 }
229 
MarkPoints(const Rectangle * pRect,sal_Bool bUnmark)230 sal_Bool SdrMarkView::MarkPoints(const Rectangle* pRect, sal_Bool bUnmark)
231 {
232     ForceUndirtyMrkPnt();
233     sal_Bool bChgd=sal_False;
234     SortMarkedObjects();
235     const SdrObject* pObj0=NULL;
236     const SdrPageView* pPV0=NULL;
237     SdrMark* pM=NULL;
238     aHdl.Sort();
239     //HMHBOOL bHideHdl=IsMarkHdlShown() && IsSolidMarkHdl() && !bPlusHdlAlways;
240     sal_uIntPtr nHdlAnz=aHdl.GetHdlCount();
241     for (sal_uIntPtr nHdlNum=nHdlAnz; nHdlNum>0;) {
242         nHdlNum--;
243         SdrHdl* pHdl=aHdl.GetHdl(nHdlNum);
244         if (IsPointMarkable(*pHdl) && pHdl->IsSelected()==bUnmark) {
245             const SdrObject* pObj=pHdl->GetObj();
246             const SdrPageView* pPV=pHdl->GetPageView();
247             if (pObj!=pObj0 || pPV!=pPV0 || pM==NULL) { // Dieser Abschnitt dient zur Optimierung,
248                 if (pM!=NULL) {
249                     SdrUShortCont* pPts=pM->GetMarkedPoints();
250                     if (pPts!=NULL) pPts->ForceSort();
251                 }
252                 sal_uIntPtr nMarkNum=TryToFindMarkedObject(pObj);  // damit ImpMarkPoint() nicht staendig das
253                 if (nMarkNum!=CONTAINER_ENTRY_NOTFOUND) { // Objekt in der MarkList suchen muss.
254                     pM=GetSdrMarkByIndex(nMarkNum);
255                     pObj0=pObj;
256                     pPV0=pPV;
257                     SdrUShortCont* pPts=pM->ForceMarkedPoints();
258                     pPts->ForceSort();
259                 } else {
260 #ifdef DBG_UTIL
261                     if (pObj->IsInserted()) {
262                         DBG_ERROR("SdrMarkView::MarkPoints(const Rectangle* pRect): Markiertes Objekt nicht gefunden");
263                     }
264 #endif
265                     pM=NULL;
266                 }
267             }
268             Point aPos(pHdl->GetPos());
269             if (pM!=NULL && (pRect==NULL || pRect->IsInside(aPos))) {
270                 //HMHif (bHideHdl && IsMarkHdlShown() && pHdl->GetObj()!=NULL) {
271                     //HMHsal_uInt32 nAnz=pHdl->GetObj()->GetPlusHdlCount(*pHdl);
272                     //HMHif (nAnz!=0L) HideMarkHdl(); // #36987#
273                 //HMH}
274                 if (ImpMarkPoint(pHdl,pM,bUnmark)) bChgd=sal_True;
275             }
276         }
277     }
278     if (pM!=NULL) { // Den zuletzt geaenderten MarkEntry ggf. noch aufraeumen
279         SdrUShortCont* pPts=pM->GetMarkedPoints();
280         if (pPts!=NULL) pPts->ForceSort();
281     }
282     //HMHif (bHideHdl) ShowMarkHdl(); // #36987#
283     if (bChgd) {
284         MarkListHasChanged();
285     }
286 
287     return bChgd;
288 }
289 
MarkNextPoint(sal_Bool)290 sal_Bool SdrMarkView::MarkNextPoint(sal_Bool /*bPrev*/)
291 {
292     ForceUndirtyMrkPnt();
293     sal_Bool bChgd=sal_False;
294     SortMarkedObjects();
295     // ...
296     if (bChgd) {
297         MarkListHasChanged();
298     }
299     return bChgd;
300 }
301 
MarkNextPoint(const Point &,sal_Bool)302 sal_Bool SdrMarkView::MarkNextPoint(const Point& /*rPnt*/, sal_Bool /*bPrev*/)
303 {
304     ForceUndirtyMrkPnt();
305     sal_Bool bChgd=sal_False;
306     SortMarkedObjects();
307     // ...
308     if (bChgd) {
309         MarkListHasChanged();
310     }
311     return bChgd;
312 }
313 
GetMarkedPointsRect() const314 const Rectangle& SdrMarkView::GetMarkedPointsRect() const
315 {
316     ForceUndirtyMrkPnt();
317     if (bMarkedPointsRectsDirty) ImpSetPointsRects();
318     return aMarkedPointsRect;
319 }
320 
SetPlusHandlesAlwaysVisible(sal_Bool bOn)321 void SdrMarkView::SetPlusHandlesAlwaysVisible(sal_Bool bOn)
322 { // HandlePaint optimieren !!!!!!!
323     ForceUndirtyMrkPnt();
324     if (bOn!=bPlusHdlAlways) {
325         //HMHBOOL bVis=IsMarkHdlShown();
326         //HMHif (bVis) HideMarkHdl();
327         bPlusHdlAlways=bOn;
328         SetMarkHandles();
329         //HMHif (bVis) ShowMarkHdl();
330         MarkListHasChanged();
331     }
332 }
333 
334 ////////////////////////////////////////////////////////////////////////////////////////////////////
335 // ImpSetPointsRects() ist fuer PolyPoints und GluePoints!
336 ////////////////////////////////////////////////////////////////////////////////////////////////////
337 
ImpSetPointsRects() const338 void SdrMarkView::ImpSetPointsRects() const
339 {
340     Rectangle aPnts;
341     Rectangle aGlue;
342     sal_uIntPtr nHdlAnz=aHdl.GetHdlCount();
343     for (sal_uIntPtr nHdlNum=0; nHdlNum<nHdlAnz; nHdlNum++) {
344         const SdrHdl* pHdl=aHdl.GetHdl(nHdlNum);
345         SdrHdlKind eKind=pHdl->GetKind();
346         if ((eKind==HDL_POLY && pHdl->IsSelected()) || eKind==HDL_GLUE) {
347             Point aPt(pHdl->GetPos());
348             Rectangle& rR=eKind==HDL_GLUE ? aGlue : aPnts;
349             if (rR.IsEmpty()) {
350                 rR=Rectangle(aPt,aPt);
351             } else {
352                 if (aPt.X()<rR.Left  ()) rR.Left  ()=aPt.X();
353                 if (aPt.X()>rR.Right ()) rR.Right ()=aPt.X();
354                 if (aPt.Y()<rR.Top   ()) rR.Top   ()=aPt.Y();
355                 if (aPt.Y()>rR.Bottom()) rR.Bottom()=aPt.Y();
356             }
357         }
358     }
359     ((SdrMarkView*)this)->aMarkedPointsRect=aPnts;
360     ((SdrMarkView*)this)->aMarkedGluePointsRect=aGlue;
361     ((SdrMarkView*)this)->bMarkedPointsRectsDirty=sal_False;
362 }
363 
364 ////////////////////////////////////////////////////////////////////////////////////////////////////
365 // UndirtyMrkPnt() ist fuer PolyPoints und GluePoints!
366 ////////////////////////////////////////////////////////////////////////////////////////////////////
367 
UndirtyMrkPnt() const368 void SdrMarkView::UndirtyMrkPnt() const
369 {
370     sal_Bool bChg=sal_False;
371     sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
372     for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++) {
373         SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
374         const SdrObject* pObj=pM->GetMarkedSdrObj();
375         // PolyPoints
376         SdrUShortCont* pPts=pM->GetMarkedPoints();
377         if (pPts!=NULL) {
378             if (pObj->IsPolyObj()) {
379                 // Ungueltig markierte Punkte entfernen, also alle
380                 // Eintraege die groesser sind als die Punktanzahl des Objekts
381                 sal_uInt32 nMax(pObj->GetPointCount());
382                 sal_uInt32 nPtNum(0xffffffff);
383 
384                 pPts->ForceSort();
385 
386                 for (sal_uInt32 nIndex(pPts->GetCount()); nIndex > 0L && nPtNum >= nMax;)
387                 {
388                     nIndex--;
389                     nPtNum = pPts->GetObject(nIndex);
390 
391                     if(nPtNum >= nMax)
392                     {
393                         pPts->Remove(nIndex);
394                         bChg = sal_True;
395                     }
396                 }
397             }
398             else
399             {
400                 DBG_ERROR("SdrMarkView::UndirtyMrkPnt(): Markierte Punkte an einem Objekt, dass kein PolyObj ist!");
401                 if(pPts && pPts->GetCount())
402                 {
403                     pPts->Clear();
404                     bChg = sal_True;
405                 }
406             }
407         }
408 
409         // GluePoints
410         pPts=pM->GetMarkedGluePoints();
411         const SdrGluePointList* pGPL=pObj->GetGluePointList();
412         if (pPts!=NULL) {
413             if (pGPL!=NULL) {
414                 // Ungueltig markierte Klebepunkte entfernen, also alle
415                 // Eintraege (Id's) die nicht in der GluePointList des
416                 // Objekts enthalten sind
417                 pPts->ForceSort();
418                 for (sal_uIntPtr nIndex=pPts->GetCount(); nIndex>0;) {
419                     nIndex--;
420                     sal_uInt16 nId=pPts->GetObject(nIndex);
421                     if (pGPL->FindGluePoint(nId)==SDRGLUEPOINT_NOTFOUND) {
422                         pPts->Remove(nIndex);
423                         bChg=sal_True;
424                     }
425                 }
426             } else {
427                 if (pPts!=NULL && pPts->GetCount()!=0) {
428                     pPts->Clear(); // Objekt hat keine Klebepunkte (mehr)
429                     bChg=sal_True;
430                 }
431             }
432         }
433     }
434     if (bChg) ((SdrMarkView*)this)->bMarkedPointsRectsDirty=sal_True;
435     ((SdrMarkView*)this)->bMrkPntDirty=sal_False;
436 }
437 
438 ////////////////////////////////////////////////////////////////////////////////////////////////////
439 ////////////////////////////////////////////////////////////////////////////////////////////////////
440 ////////////////////////////////////////////////////////////////////////////////////////////////////
441 
HasMarkableGluePoints() const442 sal_Bool SdrMarkView::HasMarkableGluePoints() const
443 {
444     sal_Bool bRet=sal_False;
445     if (IsGluePointEditMode()) {
446         ForceUndirtyMrkPnt();
447         sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
448         for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz && !bRet; nMarkNum++) {
449             const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
450             const SdrObject* pObj=pM->GetMarkedSdrObj();
451             const SdrGluePointList* pGPL=pObj->GetGluePointList();
452 
453             // #i38892#
454             if(pGPL && pGPL->GetCount())
455             {
456                 for(sal_uInt16 a(0); !bRet && a < pGPL->GetCount(); a++)
457                 {
458                     if((*pGPL)[a].IsUserDefined())
459                     {
460                         bRet = sal_True;
461                     }
462                 }
463             }
464         }
465     }
466     return bRet;
467 }
468 
GetMarkableGluePointCount() const469 sal_uIntPtr SdrMarkView::GetMarkableGluePointCount() const
470 {
471     sal_uIntPtr nAnz=0;
472     if (IsGluePointEditMode()) {
473         ForceUndirtyMrkPnt();
474         sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
475         for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++) {
476             const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
477             const SdrObject* pObj=pM->GetMarkedSdrObj();
478             const SdrGluePointList* pGPL=pObj->GetGluePointList();
479 
480             // #i38892#
481             if(pGPL && pGPL->GetCount())
482             {
483                 for(sal_uInt16 a(0); a < pGPL->GetCount(); a++)
484                 {
485                     if((*pGPL)[a].IsUserDefined())
486                     {
487                         nAnz++;
488                     }
489                 }
490             }
491         }
492     }
493     return nAnz;
494 }
495 
HasMarkedGluePoints() const496 sal_Bool SdrMarkView::HasMarkedGluePoints() const
497 {
498     ForceUndirtyMrkPnt();
499     sal_Bool bRet=sal_False;
500     sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
501     for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz && !bRet; nMarkNum++) {
502         const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
503         const SdrUShortCont* pPts=pM->GetMarkedGluePoints();
504         bRet=pPts!=NULL && pPts->GetCount()!=0;
505     }
506     return bRet;
507 }
508 
GetMarkedGluePointCount() const509 sal_uIntPtr SdrMarkView::GetMarkedGluePointCount() const
510 {
511     ForceUndirtyMrkPnt();
512     sal_uIntPtr nAnz=0;
513     sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
514     for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++) {
515         const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
516         const SdrUShortCont* pPts=pM->GetMarkedGluePoints();
517         if (pPts!=NULL) nAnz+=pPts->GetCount();
518     }
519     return nAnz;
520 }
521 
MarkGluePoints(const Rectangle * pRect,sal_Bool bUnmark)522 sal_Bool SdrMarkView::MarkGluePoints(const Rectangle* pRect, sal_Bool bUnmark)
523 {
524     if (!IsGluePointEditMode() && !bUnmark) return sal_False;
525     ForceUndirtyMrkPnt();
526     sal_Bool bChgd=sal_False;
527     SortMarkedObjects();
528     sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
529     for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++) {
530         SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
531         const SdrObject* pObj=pM->GetMarkedSdrObj();
532         const SdrGluePointList* pGPL=pObj->GetGluePointList();
533         SdrUShortCont* pPts=pM->GetMarkedGluePoints();
534         if (bUnmark && pRect==NULL) { // UnmarkAll
535             if (pPts!=NULL && pPts->GetCount()!=0) {
536                 pPts->Clear();
537                 bChgd=sal_True;
538             }
539         } else {
540             if (pGPL!=NULL && (pPts!=NULL || !bUnmark)) {
541                 sal_uInt16 nGPAnz=pGPL->GetCount();
542                 for (sal_uInt16 nGPNum=0; nGPNum<nGPAnz; nGPNum++) {
543                     const SdrGluePoint& rGP=(*pGPL)[nGPNum];
544 
545                     // #i38892#
546                     if(rGP.IsUserDefined())
547                     {
548                         Point aPos(rGP.GetAbsolutePos(*pObj));
549                         if (pRect==NULL || pRect->IsInside(aPos)) {
550                             if (pPts==NULL) pPts=pM->ForceMarkedGluePoints();
551                             else pPts->ForceSort();
552                             sal_uIntPtr nPos=pPts->GetPos(rGP.GetId());
553                             if (!bUnmark && nPos==CONTAINER_ENTRY_NOTFOUND) {
554                                 bChgd=sal_True;
555                                 pPts->Insert(rGP.GetId());
556                             }
557                             if (bUnmark && nPos!=CONTAINER_ENTRY_NOTFOUND) {
558                                 bChgd=sal_True;
559                                 pPts->Remove(nPos);
560                             }
561                         }
562                     }
563                 }
564             }
565         }
566     }
567     if (bChgd) {
568         AdjustMarkHdl();
569         MarkListHasChanged();
570     }
571     return bChgd;
572 }
573 
PickGluePoint(const Point & rPnt,SdrObject * & rpObj,sal_uInt16 & rnId,SdrPageView * & rpPV,sal_uIntPtr nOptions) const574 sal_Bool SdrMarkView::PickGluePoint(const Point& rPnt, SdrObject*& rpObj, sal_uInt16& rnId, SdrPageView*& rpPV, sal_uIntPtr nOptions) const
575 {
576     SdrObject* pObj0=rpObj;
577     //SdrPageView* pPV0=rpPV;
578     sal_uInt16 nId0=rnId;
579     rpObj=NULL; rpPV=NULL; rnId=0;
580     if (!IsGluePointEditMode()) return sal_False;
581     sal_Bool bBack=(nOptions & SDRSEARCH_BACKWARD) !=0;
582     sal_Bool bNext=(nOptions & SDRSEARCH_NEXT) !=0;
583     OutputDevice* pOut=(OutputDevice*)pActualOutDev;
584     if (pOut==NULL) pOut=GetFirstOutputDevice(); //GetWin(0);
585     if (pOut==NULL) return sal_False;
586     SortMarkedObjects();
587     sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
588     sal_uIntPtr nMarkNum=bBack ? 0 : nMarkAnz;
589     if (bNext) {
590         nMarkNum=((SdrMarkView*)this)->TryToFindMarkedObject(pObj0);
591         if (nMarkNum==CONTAINER_ENTRY_NOTFOUND) return sal_False;
592         if (!bBack) nMarkNum++;
593     }
594     while (bBack ? nMarkNum<nMarkAnz : nMarkNum>0) {
595         if (!bBack) nMarkNum--;
596         const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
597         SdrObject* pObj=pM->GetMarkedSdrObj();
598         SdrPageView* pPV=pM->GetPageView();
599         const SdrGluePointList* pGPL=pObj->GetGluePointList();
600         if (pGPL!=NULL) {
601             sal_uInt16 nNum=pGPL->HitTest(rPnt,*pOut,pObj,bBack,bNext,nId0);
602             if (nNum!=SDRGLUEPOINT_NOTFOUND)
603             {
604                 // #i38892#
605                 const SdrGluePoint& rCandidate = (*pGPL)[nNum];
606 
607                 if(rCandidate.IsUserDefined())
608                 {
609                     rpObj=pObj;
610                     rnId=(*pGPL)[nNum].GetId();
611                     rpPV=pPV;
612                     return sal_True;
613                 }
614             }
615         }
616         bNext=sal_False; // HitNextGluePoint nur beim ersten Obj
617         if (bBack) nMarkNum++;
618     }
619     return sal_False;
620 }
621 
MarkGluePoint(const SdrObject * pObj,sal_uInt16 nId,const SdrPageView *,sal_Bool bUnmark)622 sal_Bool SdrMarkView::MarkGluePoint(const SdrObject* pObj, sal_uInt16 nId, const SdrPageView* /*pPV*/, sal_Bool bUnmark)
623 {
624     if (!IsGluePointEditMode()) return sal_False;
625     ForceUndirtyMrkPnt();
626     sal_Bool bChgd=sal_False;
627     if (pObj!=NULL) {
628         sal_uIntPtr nMarkPos=TryToFindMarkedObject(pObj);
629         if (nMarkPos!=CONTAINER_ENTRY_NOTFOUND) {
630             SdrMark* pM=GetSdrMarkByIndex(nMarkPos);
631             SdrUShortCont* pPts=bUnmark ? pM->GetMarkedGluePoints() : pM->ForceMarkedGluePoints();
632             if (pPts!=NULL) {
633                 sal_uIntPtr nPointPos=pPts->GetPos(nId);
634                 if (!bUnmark && nPointPos==CONTAINER_ENTRY_NOTFOUND) {
635                     bChgd=sal_True;
636                     pPts->Insert(nId);
637                 }
638                 if (bUnmark && nPointPos!=CONTAINER_ENTRY_NOTFOUND) {
639                     bChgd=sal_True;
640                     pPts->Remove(nPointPos);
641                 }
642             }
643         } else {
644             // Objekt implizit markieren ...
645             // ... fehlende Implementation
646         }
647     }
648     if (bChgd) {
649         AdjustMarkHdl();
650         MarkListHasChanged();
651     }
652     return bChgd;
653 }
654 
IsGluePointMarked(const SdrObject * pObj,sal_uInt16 nId) const655 sal_Bool SdrMarkView::IsGluePointMarked(const SdrObject* pObj, sal_uInt16 nId) const
656 {
657     ForceUndirtyMrkPnt();
658     sal_Bool bRet=sal_False;
659     sal_uIntPtr nPos=((SdrMarkView*)this)->TryToFindMarkedObject(pObj); // casting auf NonConst
660     if (nPos!=CONTAINER_ENTRY_NOTFOUND) {
661         const SdrMark* pM=GetSdrMarkByIndex(nPos);
662         const SdrUShortCont* pPts=pM->GetMarkedGluePoints();
663         if (pPts!=NULL) {
664             bRet=pPts->Exist(nId);
665         }
666     }
667     return bRet;
668 }
669 
UnmarkGluePoint(const SdrHdl & rHdl)670 sal_Bool SdrMarkView::UnmarkGluePoint(const SdrHdl& rHdl)
671 {
672     if (&rHdl!=NULL && rHdl.GetKind()==HDL_GLUE && rHdl.GetObj()!=NULL) {
673         return MarkGluePoint(rHdl.GetObj(),(sal_uInt16)rHdl.GetObjHdlNum(),rHdl.GetPageView(),sal_True);
674     } else return sal_False;
675 }
676 
GetGluePointHdl(const SdrObject * pObj,sal_uInt16 nId) const677 SdrHdl* SdrMarkView::GetGluePointHdl(const SdrObject* pObj, sal_uInt16 nId) const
678 {
679     ForceUndirtyMrkPnt();
680     sal_uIntPtr nHdlAnz=aHdl.GetHdlCount();
681     for (sal_uIntPtr nHdlNum=0; nHdlNum<nHdlAnz; nHdlNum++) {
682         SdrHdl* pHdl=aHdl.GetHdl(nHdlNum);
683         if (pHdl->GetObj()==pObj &&
684             pHdl->GetKind()==HDL_GLUE &&
685             pHdl->GetObjHdlNum()==nId ) return pHdl;
686     }
687     return NULL;
688 }
689 
MarkNextGluePoint(sal_Bool)690 sal_Bool SdrMarkView::MarkNextGluePoint(sal_Bool /*bPrev*/)
691 {
692     ForceUndirtyMrkPnt();
693     sal_Bool bChgd=sal_False;
694     SortMarkedObjects();
695     // ...
696     if (bChgd) {
697         MarkListHasChanged();
698     }
699     return bChgd;
700 }
701 
MarkNextGluePoint(const Point &,sal_Bool)702 sal_Bool SdrMarkView::MarkNextGluePoint(const Point& /*rPnt*/, sal_Bool /*bPrev*/)
703 {
704     ForceUndirtyMrkPnt();
705     sal_Bool bChgd=sal_False;
706     SortMarkedObjects();
707     // ...
708     if (bChgd) {
709         MarkListHasChanged();
710     }
711     return bChgd;
712 }
713 
GetMarkedGluePointsRect() const714 const Rectangle& SdrMarkView::GetMarkedGluePointsRect() const
715 {
716     ForceUndirtyMrkPnt();
717     if (bMarkedPointsRectsDirty) ImpSetPointsRects();
718     return aMarkedGluePointsRect;
719 }
720 
721