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