xref: /aoo42x/main/svx/source/svdraw/svdmrkv1.cxx (revision cdf0e10c)
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