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