xref: /aoo41x/main/svx/source/svdraw/svdhdl.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 <algorithm>
32 
33 #include <svx/svdhdl.hxx>
34 #include <svx/svdpagv.hxx>
35 #include <svx/svdetc.hxx>
36 #include <svx/svdmrkv.hxx>
37 #include <vcl/window.hxx>
38 
39 #include <vcl/virdev.hxx>
40 #include <tools/poly.hxx>
41 #include <vcl/bmpacc.hxx>
42 
43 #include <svx/sxekitm.hxx>
44 #include "svx/svdstr.hrc"
45 #include "svx/svdglob.hxx"
46 
47 #include <svx/svdmodel.hxx>
48 #include "gradtrns.hxx"
49 #include <svx/xflgrit.hxx>
50 #include <svx/svdundo.hxx>
51 #include <svx/dialmgr.hxx>
52 #include <svx/xflftrit.hxx>
53 
54 // #105678#
55 #include <svx/svdopath.hxx>
56 #include <basegfx/vector/b2dvector.hxx>
57 #include <basegfx/polygon/b2dpolygon.hxx>
58 #include <svx/sdr/overlay/overlaymanager.hxx>
59 #include <svx/sdr/overlay/overlayanimatedbitmapex.hxx>
60 #include <svx/sdr/overlay/overlaybitmapex.hxx>
61 #include <svx/sdr/overlay/overlayline.hxx>
62 #include <svx/sdr/overlay/overlaytriangle.hxx>
63 #include <svx/sdr/overlay/overlayhatchrect.hxx>
64 #include <svx/sdrpagewindow.hxx>
65 #include <svx/sdrpaintwindow.hxx>
66 #include <vcl/svapp.hxx>
67 #include <svx/sdr/overlay/overlaypolypolygon.hxx>
68 #include <vcl/lazydelete.hxx>
69 
70 ////////////////////////////////////////////////////////////////////////////////////////////////////
71 // #i15222#
72 // Due to the ressource problems in Win95/98 with bitmap ressources i
73 // will change this handle bitmap provinging class. Old version was splitting
74 // and preparing all small handle bitmaps in device bitmap format, now this will
75 // be done on the fly. Thus, tehre is only the one big bitmap remembered. With
76 // three source bitmaps, this will be 3 system bitmap ressources instead of hundreds.
77 // The price for that needs to be evaluated. Maybe we will need another change here
78 // if this is too expensive.
79 class SdrHdlBitmapSet
80 {
81 	// the bitmap holding all infos
82 	BitmapEx				    maMarkersBitmap;
83 
84     // the cropped Bitmaps for reusage
85     ::std::vector< BitmapEx >   maRealMarkers;
86 
87     // elpers
88     BitmapEx& impGetOrCreateTargetBitmap(sal_uInt16 nIndex, const Rectangle& rRectangle);
89 
90 public:
91 	SdrHdlBitmapSet(sal_uInt16 nResId);
92 	~SdrHdlBitmapSet();
93 
94 	const BitmapEx& GetBitmapEx(BitmapMarkerKind eKindOfMarker, sal_uInt16 nInd=0);
95 };
96 
97 ////////////////////////////////////////////////////////////////////////////////////////////////////
98 #define KIND_COUNT          (14)
99 #define INDEX_COUNT         (6)
100 #define INDIVIDUAL_COUNT    (4)
101 
102 SdrHdlBitmapSet::SdrHdlBitmapSet(sal_uInt16 nResId)
103 :   maMarkersBitmap(),
104     // 14 kinds (BitmapMarkerKind) use index [0..5], 4 extra
105     maRealMarkers((KIND_COUNT * INDEX_COUNT) + INDIVIDUAL_COUNT)
106 {
107 	// #101928# change color used for transparent parts to 0x00ff00ff (ImageList standard)
108 	const Color aColTransparent(0x00ff00ff);
109 	const Bitmap aBitmap(ResId(nResId, *ImpGetResMgr()));
110     const Bitmap aMask(aBitmap.CreateMask(aColTransparent));
111 
112     // create a real BitmapEx with an AlphaMask
113     maMarkersBitmap = BitmapEx(aBitmap, aMask);
114     // maMarkersBitmap = BitmapEx(aBitmap, aColTransparent);
115 }
116 
117 SdrHdlBitmapSet::~SdrHdlBitmapSet()
118 {
119 }
120 
121 BitmapEx& SdrHdlBitmapSet::impGetOrCreateTargetBitmap(sal_uInt16 nIndex, const Rectangle& rRectangle)
122 {
123     BitmapEx& rTargetBitmap = maRealMarkers[nIndex];
124 
125     if(rTargetBitmap.IsEmpty())
126     {
127         rTargetBitmap = maMarkersBitmap;
128         rTargetBitmap.Crop(rRectangle);
129     }
130 
131     return rTargetBitmap;
132 }
133 
134 // change getting of bitmap to use the big ressource bitmap
135 const BitmapEx& SdrHdlBitmapSet::GetBitmapEx(BitmapMarkerKind eKindOfMarker, sal_uInt16 nInd)
136 {
137 	// fill in size and source position in maMarkersBitmap
138 	const sal_uInt16 nYPos(nInd * 11);
139 
140 	switch(eKindOfMarker)
141 	{
142 		default:
143 		{
144 			DBG_ERROR( "unknown kind of marker" );
145 			// no break here, return Rect_7x7 as default
146 		}
147 		case Rect_7x7:
148 		{
149             return impGetOrCreateTargetBitmap((0 * INDEX_COUNT) + nInd, Rectangle(Point(0, nYPos), Size(7, 7)));
150 		}
151 
152 		case Rect_9x9:
153 		{
154 			return impGetOrCreateTargetBitmap((1 * INDEX_COUNT) + nInd, Rectangle(Point(7, nYPos), Size(9, 9)));
155 		}
156 
157 		case Rect_11x11:
158 		{
159 			return impGetOrCreateTargetBitmap((2 * INDEX_COUNT) + nInd, Rectangle(Point(16, nYPos), Size(11, 11)));
160 		}
161 
162 		case Rect_13x13:
163 		{
164             const sal_uInt16 nIndex((3 * INDEX_COUNT) + nInd);
165 
166 			switch(nInd)
167 			{
168     			case 0:
169                 {
170                     return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(72, 66), Size(13, 13)));
171                 }
172 	    		case 1:
173                 {
174                     return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(85, 66), Size(13, 13)));
175                 }
176 		    	case 2:
177                 {
178                     return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(72, 78), Size(13, 13)));
179                 }
180 			    case 3:
181                 {
182                     return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(85, 78), Size(13, 13)));
183                 }
184     			case 4:
185                 {
186                     return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(98, 78), Size(13, 13)));
187                 }
188                 default: // case 5:
189                 {
190                     return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(98, 66), Size(13, 13)));
191                 }
192 			}
193 		}
194 
195 		case Circ_7x7:
196 		{
197 			return impGetOrCreateTargetBitmap((4 * INDEX_COUNT) + nInd, Rectangle(Point(27, nYPos), Size(7, 7)));
198 		}
199 
200 		case Circ_9x9:
201 		case Customshape1:
202 		{
203 			return impGetOrCreateTargetBitmap((5 * INDEX_COUNT) + nInd, Rectangle(Point(34, nYPos), Size(9, 9)));
204 		}
205 
206 		case Circ_11x11:
207 		{
208 			return impGetOrCreateTargetBitmap((6 * INDEX_COUNT) + nInd, Rectangle(Point(43, nYPos), Size(11, 11)));
209 		}
210 
211 		case Elli_7x9:
212 		{
213 			return impGetOrCreateTargetBitmap((7 * INDEX_COUNT) + nInd, Rectangle(Point(54, nYPos), Size(7, 9)));
214 		}
215 
216 		case Elli_9x11:
217 		{
218 			return impGetOrCreateTargetBitmap((8 * INDEX_COUNT) + nInd, Rectangle(Point(61, nYPos), Size(9, 11)));
219 		}
220 
221 		case Elli_9x7:
222 		{
223 			return impGetOrCreateTargetBitmap((9 * INDEX_COUNT) + nInd, Rectangle(Point(70, nYPos), Size(9, 7)));
224 		}
225 
226 		case Elli_11x9:
227 		{
228 			return impGetOrCreateTargetBitmap((10 * INDEX_COUNT) + nInd, Rectangle(Point(79, nYPos), Size(11, 9)));
229 		}
230 
231 		case RectPlus_7x7:
232 		{
233 			return impGetOrCreateTargetBitmap((11 * INDEX_COUNT) + nInd, Rectangle(Point(90, nYPos), Size(7, 7)));
234 		}
235 
236 		case RectPlus_9x9:
237 		{
238 			return impGetOrCreateTargetBitmap((12 * INDEX_COUNT) + nInd, Rectangle(Point(97, nYPos), Size(9, 9)));
239 		}
240 
241 		case RectPlus_11x11:
242 		{
243 			return impGetOrCreateTargetBitmap((13 * INDEX_COUNT) + nInd, Rectangle(Point(106, nYPos), Size(11, 11)));
244 		}
245 
246 		case Crosshair:
247 		{
248 			return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 0, Rectangle(Point(0, 68), Size(15, 15)));
249 		}
250 
251 		case Glue:
252 		{
253 			return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 1, Rectangle(Point(15, 74), Size(9, 9)));
254 		}
255 
256 		case Anchor: // #101688# AnchorTR for SW
257 		case AnchorTR:
258 		{
259 			return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 2, Rectangle(Point(24, 68), Size(24, 23)));
260 		}
261 
262 		// #98388# add AnchorPressed to be able to aninate anchor control
263 		case AnchorPressed:
264 		case AnchorPressedTR:
265 		{
266 			return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 3, Rectangle(Point(48, 68), Size(24, 23)));
267 		}
268 	}
269 
270 	// cannot happen since all pathes return something; return Rect_7x7 as default (see switch)
271     return maRealMarkers[0];
272 }
273 
274 ////////////////////////////////////////////////////////////////////////////////////////////////////
275 
276 SdrHdlBitmapSet& getSimpleSet()
277 {
278     static vcl::DeleteOnDeinit< SdrHdlBitmapSet > aSimpleSet(new SdrHdlBitmapSet(SIP_SA_MARKERS));
279     return *aSimpleSet.get();
280 }
281 
282 SdrHdlBitmapSet& getModernSet()
283 {
284     static vcl::DeleteOnDeinit< SdrHdlBitmapSet > aModernSet(new SdrHdlBitmapSet(SIP_SA_FINE_MARKERS));
285     return *aModernSet.get();
286 }
287 
288 SdrHdlBitmapSet& getHighContrastSet()
289 {
290     static vcl::DeleteOnDeinit< SdrHdlBitmapSet > aHighContrastSet(new SdrHdlBitmapSet(SIP_SA_ACCESSIBILITY_MARKERS));
291     return *aHighContrastSet.get();
292 }
293 
294 ////////////////////////////////////////////////////////////////////////////////////////////////////
295 
296 SdrHdl::SdrHdl():
297     pObj(NULL),
298     pPV(NULL),
299     pHdlList(NULL),
300     eKind(HDL_MOVE),
301     nDrehWink(0),
302     nObjHdlNum(0),
303     nPolyNum(0),
304     nPPntNum(0),
305     nSourceHdlNum(0),
306     bSelect(sal_False),
307     b1PixMore(sal_False),
308     bPlusHdl(sal_False),
309 	mbMoveOutside(false),
310 	mbMouseOver(false)
311 {
312 }
313 
314 SdrHdl::SdrHdl(const Point& rPnt, SdrHdlKind eNewKind):
315     pObj(NULL),
316     pPV(NULL),
317     pHdlList(NULL),
318     aPos(rPnt),
319     eKind(eNewKind),
320     nDrehWink(0),
321     nObjHdlNum(0),
322     nPolyNum(0),
323     nPPntNum(0),
324     nSourceHdlNum(0),
325     bSelect(sal_False),
326     b1PixMore(sal_False),
327     bPlusHdl(sal_False),
328 	mbMoveOutside(false),
329 	mbMouseOver(false)
330 {
331 }
332 
333 SdrHdl::~SdrHdl()
334 {
335 	GetRidOfIAObject();
336 }
337 
338 void SdrHdl::Set1PixMore(sal_Bool bJa)
339 {
340 	if(b1PixMore != bJa)
341 	{
342 		b1PixMore = bJa;
343 
344 		// create new display
345 		Touch();
346 	}
347 }
348 
349 void SdrHdl::SetMoveOutside( bool bMoveOutside )
350 {
351 	if(mbMoveOutside != bMoveOutside)
352 	{
353 		mbMoveOutside = bMoveOutside;
354 
355 		// create new display
356 		Touch();
357 	}
358 }
359 
360 void SdrHdl::SetDrehWink(long n)
361 {
362 	if(nDrehWink != n)
363 	{
364 		nDrehWink = n;
365 
366 		// create new display
367 		Touch();
368 	}
369 }
370 
371 void SdrHdl::SetPos(const Point& rPnt)
372 {
373 	if(aPos != rPnt)
374 	{
375 		// remember new position
376 		aPos = rPnt;
377 
378 		// create new display
379 		Touch();
380 	}
381 }
382 
383 void SdrHdl::SetSelected(sal_Bool bJa)
384 {
385 	if(bSelect != bJa)
386 	{
387 		// remember new value
388 		bSelect = bJa;
389 
390 		// create new display
391 		Touch();
392 	}
393 }
394 
395 void SdrHdl::SetHdlList(SdrHdlList* pList)
396 {
397 	if(pHdlList != pList)
398 	{
399 		// rememver list
400 		pHdlList = pList;
401 
402 		// now its possible to create graphic representation
403 		Touch();
404 	}
405 }
406 
407 void SdrHdl::SetObj(SdrObject* pNewObj)
408 {
409 	if(pObj != pNewObj)
410 	{
411 		// remember new object
412 		pObj = pNewObj;
413 
414 		// graphic representation may have changed
415 		Touch();
416 	}
417 }
418 
419 void SdrHdl::Touch()
420 {
421 	// force update of graphic representation
422 	CreateB2dIAObject();
423 }
424 
425 void SdrHdl::GetRidOfIAObject()
426 {
427 	//OLMaIAOGroup.Delete();
428 
429 	// OVERLAYMANAGER
430 	maOverlayGroup.clear();
431 }
432 
433 void SdrHdl::CreateB2dIAObject()
434 {
435 	// first throw away old one
436 	GetRidOfIAObject();
437 
438 	if(pHdlList && pHdlList->GetView() && !pHdlList->GetView()->areMarkHandlesHidden())
439 	{
440 		BitmapColorIndex eColIndex = LightGreen;
441 		BitmapMarkerKind eKindOfMarker = Rect_7x7;
442 
443         sal_Bool bRot = pHdlList->IsRotateShear();
444         if(pObj)
445             eColIndex = (bSelect) ? Cyan : LightCyan;
446         if(bRot)
447 		{
448 			// Drehhandles in Rot
449             if(pObj && bSelect)
450 				eColIndex = Red;
451 			else
452 	            eColIndex = LightRed;
453         }
454 
455 		switch(eKind)
456 		{
457 			case HDL_MOVE:
458 			{
459 				eKindOfMarker = (b1PixMore) ? Rect_9x9 : Rect_7x7;
460 				break;
461 			}
462 			case HDL_UPLFT:
463 			case HDL_UPRGT:
464 			case HDL_LWLFT:
465 			case HDL_LWRGT:
466 			{
467 				// corner handles
468 				if(bRot)
469 				{
470 					eKindOfMarker = Circ_7x7;
471 				}
472 				else
473 				{
474 					eKindOfMarker = Rect_7x7;
475 				}
476 				break;
477 			}
478 			case HDL_UPPER:
479 			case HDL_LOWER:
480 			{
481 				// Upper/Lower handles
482 				if(bRot)
483 				{
484 					eKindOfMarker = Elli_9x7;
485 				}
486 				else
487 				{
488 					eKindOfMarker = Rect_7x7;
489 				}
490 				break;
491 			}
492 			case HDL_LEFT:
493 			case HDL_RIGHT:
494 			{
495 				// Left/Right handles
496 				if(bRot)
497 				{
498 					eKindOfMarker = Elli_7x9;
499 				}
500 				else
501 				{
502 					eKindOfMarker = Rect_7x7;
503 				}
504 				break;
505 			}
506 			case HDL_POLY:
507 			{
508 				if(bRot)
509 				{
510 					eKindOfMarker = (b1PixMore) ? Circ_9x9 : Circ_7x7;
511 				}
512 				else
513 				{
514 					eKindOfMarker = (b1PixMore) ? Rect_9x9 : Rect_7x7;
515 				}
516 				break;
517 			}
518 			case HDL_BWGT: // weight at poly
519 			{
520 				eKindOfMarker = Circ_7x7;
521 				break;
522 			}
523 			case HDL_CIRC:
524 			{
525 				eKindOfMarker = Rect_11x11;
526 				break;
527 			}
528 			case HDL_REF1:
529 			case HDL_REF2:
530 			{
531 				eKindOfMarker = Crosshair;
532 				break;
533 			}
534 			case HDL_GLUE:
535 			{
536 				eKindOfMarker = Glue;
537 				break;
538 			}
539 			case HDL_ANCHOR:
540 			{
541 				eKindOfMarker = Anchor;
542 				break;
543 			}
544 			case HDL_USER:
545 			{
546 				break;
547 			}
548 			// #101688# top right anchor for SW
549 			case HDL_ANCHOR_TR:
550 			{
551 				eKindOfMarker = AnchorTR;
552 				break;
553 			}
554 
555 			// for SJ and the CustomShapeHandles:
556 			case HDL_CUSTOMSHAPE1:
557 			{
558 				eKindOfMarker = Customshape1;
559 				eColIndex = Yellow;
560 				break;
561 			}
562             default:
563                 break;
564 		}
565 
566 		SdrMarkView* pView = pHdlList->GetView();
567 		SdrPageView* pPageView = pView->GetSdrPageView();
568 
569 		if(pPageView)
570 		{
571 			for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
572 			{
573 				// const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
574 				const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
575 
576 				if(rPageWindow.GetPaintWindow().OutputToWindow())
577 				{
578 					Point aMoveOutsideOffset(0, 0);
579 
580 					// add offset if necessary
581 					if(pHdlList->IsMoveOutside() || mbMoveOutside)
582 					{
583 						OutputDevice& rOutDev = rPageWindow.GetPaintWindow().GetOutputDevice();
584 						Size aOffset = rOutDev.PixelToLogic(Size(4, 4));
585 
586 						if(eKind == HDL_UPLFT || eKind == HDL_UPPER || eKind == HDL_UPRGT)
587 							aMoveOutsideOffset.Y() -= aOffset.Width();
588 						if(eKind == HDL_LWLFT || eKind == HDL_LOWER || eKind == HDL_LWRGT)
589 							aMoveOutsideOffset.Y() += aOffset.Height();
590 						if(eKind == HDL_UPLFT || eKind == HDL_LEFT  || eKind == HDL_LWLFT)
591 							aMoveOutsideOffset.X() -= aOffset.Width();
592 						if(eKind == HDL_UPRGT || eKind == HDL_RIGHT || eKind == HDL_LWRGT)
593 							aMoveOutsideOffset.X() += aOffset.Height();
594 					}
595 
596 					if(rPageWindow.GetOverlayManager())
597 					{
598 						basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
599 						::sdr::overlay::OverlayObject* pNewOverlayObject = CreateOverlayObject(
600 							aPosition,
601 							eColIndex,
602 							eKindOfMarker,
603 							aMoveOutsideOffset);
604 
605 						// OVERLAYMANAGER
606 						if(pNewOverlayObject)
607 						{
608 							rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
609 							maOverlayGroup.append(*pNewOverlayObject);
610 						}
611 					}
612 				}
613 			}
614 		}
615 	}
616 }
617 
618 BitmapMarkerKind SdrHdl::GetNextBigger(BitmapMarkerKind eKnd) const
619 {
620 	BitmapMarkerKind eRetval(eKnd);
621 
622 	switch(eKnd)
623 	{
624 		case Rect_7x7:			eRetval = Rect_9x9;			break;
625 		case Rect_9x9:			eRetval = Rect_11x11;		break;
626 		case Rect_11x11:		eRetval = Rect_13x13;		break;
627 		//case Rect_13x13:		eRetval = ;	break;
628 
629 		case Circ_7x7:			eRetval = Circ_9x9;			break;
630 		case Circ_9x9:			eRetval = Circ_11x11;		break;
631 		//case Circ_11x11:		eRetval = ;	break;
632 
633 		case Elli_7x9:			eRetval = Elli_9x11;		break;
634 		//case Elli_9x11:			eRetval = ;	break;
635 
636 		case Elli_9x7:			eRetval = Elli_11x9;		break;
637 		//case Elli_11x9:			eRetval = ;	break;
638 
639 		case RectPlus_7x7:		eRetval = RectPlus_9x9;		break;
640 		case RectPlus_9x9:		eRetval = RectPlus_11x11;	break;
641 		//case RectPlus_11x11:	eRetval = ;	break;
642 
643 		//case Crosshair:			eRetval = ;	break;
644 		//case Glue:				eRetval = ;	break;
645 
646 		// #98388# let anchor blink with it's pressed state
647 		case Anchor:			eRetval = AnchorPressed;	break;
648 
649 		// #101688# same for AnchorTR
650 		case AnchorTR:			eRetval = AnchorPressedTR;	break;
651         default:
652             break;
653 	}
654 
655 	return eRetval;
656 }
657 
658 // #101928#
659 BitmapEx SdrHdl::ImpGetBitmapEx(BitmapMarkerKind eKindOfMarker, sal_uInt16 nInd, sal_Bool bFine, sal_Bool bIsHighContrast)
660 {
661 	if(bIsHighContrast)
662 	{
663 		return getHighContrastSet().GetBitmapEx(eKindOfMarker, nInd);
664 	}
665 	else
666 	{
667 		if(bFine)
668 		{
669 			return getModernSet().GetBitmapEx(eKindOfMarker, nInd);
670 		}
671 		else
672 		{
673 			return getSimpleSet().GetBitmapEx(eKindOfMarker, nInd);
674 		}
675 	}
676 }
677 
678 ::sdr::overlay::OverlayObject* SdrHdl::CreateOverlayObject(
679 	const basegfx::B2DPoint& rPos,
680 	BitmapColorIndex eColIndex, BitmapMarkerKind eKindOfMarker, Point aMoveOutsideOffset)
681 {
682 	::sdr::overlay::OverlayObject* pRetval = 0L;
683 	sal_Bool bIsFineHdl(pHdlList->IsFineHdl());
684 	const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
685 	sal_Bool bIsHighContrast(rStyleSettings.GetHighContrastMode());
686 
687 	// support bigger sizes
688 	sal_Bool bForceBiggerSize(sal_False);
689 
690 	if(pHdlList->GetHdlSize() > 3)
691 	{
692 		bForceBiggerSize = sal_True;
693 	}
694 
695 	// #101928# ...for high contrast, too.
696 	if(!bForceBiggerSize && bIsHighContrast)
697 	{
698 		// #107925#
699 		// ...but not for anchors, else they will not blink when activated
700 		if(Anchor != eKindOfMarker && AnchorTR != eKindOfMarker)
701 		{
702 			bForceBiggerSize = sal_True;
703 		}
704 	}
705 
706 	if(bForceBiggerSize)
707 	{
708 		eKindOfMarker = GetNextBigger(eKindOfMarker);
709 	}
710 
711 	// #97016# II This handle has the focus, visualize it
712 	if(IsFocusHdl() && pHdlList && pHdlList->GetFocusHdl() == this)
713 	{
714 		// create animated handle
715 		BitmapMarkerKind eNextBigger = GetNextBigger(eKindOfMarker);
716 
717 		if(eNextBigger == eKindOfMarker)
718 		{
719 			// this may happen for the not supported getting-bigger types.
720 			// Choose an alternative here
721 			switch(eKindOfMarker)
722 			{
723 				case Rect_13x13:		eNextBigger = Rect_11x11;	break;
724 				case Circ_11x11:		eNextBigger = Elli_11x9;	break;
725 				case Elli_9x11:			eNextBigger = Elli_11x9;	break;
726 				case Elli_11x9:			eNextBigger = Elli_9x11;	break;
727 				case RectPlus_11x11:	eNextBigger = Rect_13x13;	break;
728 
729 				case Crosshair:
730 					eNextBigger = Glue;
731 					break;
732 
733 				case Glue:
734 					eNextBigger = Crosshair;
735 					break;
736                 default:
737                     break;
738 			}
739 		}
740 
741 		// create animated hdl
742 		// #101928# use ImpGetBitmapEx(...) now
743 		BitmapEx aBmpEx1 = ImpGetBitmapEx(eKindOfMarker, (sal_uInt16)eColIndex, bIsFineHdl, bIsHighContrast);
744 		BitmapEx aBmpEx2 = ImpGetBitmapEx(eNextBigger, (sal_uInt16)eColIndex, bIsFineHdl, bIsHighContrast);
745 
746 		// #i53216# Use system cursor blink time. Use the unsigned value.
747 		const sal_uInt32 nBlinkTime((sal_uInt32)Application::GetSettings().GetStyleSettings().GetCursorBlinkTime());
748 
749 		if(eKindOfMarker == Anchor || eKindOfMarker == AnchorPressed)
750 		{
751 			// #98388# when anchor is used take upper left as reference point inside the handle
752 			pRetval = new ::sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime);
753 		}
754 		else if(eKindOfMarker == AnchorTR || eKindOfMarker == AnchorPressedTR)
755 		{
756 			// #101688# AnchorTR for SW, take top right as (0,0)
757 			pRetval = new ::sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime,
758 				(sal_uInt16)(aBmpEx1.GetSizePixel().Width() - 1), 0,
759 				(sal_uInt16)(aBmpEx2.GetSizePixel().Width() - 1), 0);
760 		}
761 		else
762 		{
763 			// create centered handle as default
764 			pRetval = new ::sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime,
765 				(sal_uInt16)(aBmpEx1.GetSizePixel().Width() - 1) >> 1,
766 				(sal_uInt16)(aBmpEx1.GetSizePixel().Height() - 1) >> 1,
767 				(sal_uInt16)(aBmpEx2.GetSizePixel().Width() - 1) >> 1,
768 				(sal_uInt16)(aBmpEx2.GetSizePixel().Height() - 1) >> 1);
769 		}
770 	}
771 	else
772 	{
773 		// create normal handle
774 		// #101928# use ImpGetBitmapEx(...) now
775 		BitmapEx aBmpEx = ImpGetBitmapEx(eKindOfMarker, (sal_uInt16)eColIndex, bIsFineHdl, bIsHighContrast);
776 
777 		if(eKindOfMarker == Anchor || eKindOfMarker == AnchorPressed)
778 		{
779 			// #98388# upper left as reference point inside the handle for AnchorPressed, too
780 			pRetval = new ::sdr::overlay::OverlayBitmapEx(rPos, aBmpEx);
781 		}
782 		else if(eKindOfMarker == AnchorTR || eKindOfMarker == AnchorPressedTR)
783 		{
784 			// #101688# AnchorTR for SW, take top right as (0,0)
785 			pRetval = new ::sdr::overlay::OverlayBitmapEx(rPos, aBmpEx,
786 				(sal_uInt16)(aBmpEx.GetSizePixel().Width() - 1), 0);
787 		}
788 		else
789 		{
790 			sal_uInt16 nCenX((sal_uInt16)(aBmpEx.GetSizePixel().Width() - 1L) >> 1);
791 			sal_uInt16 nCenY((sal_uInt16)(aBmpEx.GetSizePixel().Height() - 1L) >> 1);
792 
793 			if(aMoveOutsideOffset.X() > 0)
794 			{
795 				nCenX = 0;
796 			}
797 			else if(aMoveOutsideOffset.X() < 0)
798 			{
799 				nCenX = (sal_uInt16)(aBmpEx.GetSizePixel().Width() - 1);
800 			}
801 
802 			if(aMoveOutsideOffset.Y() > 0)
803 			{
804 				nCenY = 0;
805 			}
806 			else if(aMoveOutsideOffset.Y() < 0)
807 			{
808 				nCenY = (sal_uInt16)(aBmpEx.GetSizePixel().Height() - 1);
809 			}
810 
811 			// create centered handle as default
812 			pRetval = new ::sdr::overlay::OverlayBitmapEx(rPos, aBmpEx, nCenX, nCenY);
813 		}
814 	}
815 
816 	return pRetval;
817 }
818 
819 bool SdrHdl::IsHdlHit(const Point& rPnt) const
820 {
821 	// OVERLAYMANAGER
822 	basegfx::B2DPoint aPosition(rPnt.X(), rPnt.Y());
823 	return maOverlayGroup.isHitLogic(aPosition);
824 }
825 
826 Pointer SdrHdl::GetPointer() const
827 {
828     PointerStyle ePtr=POINTER_MOVE;
829     const sal_Bool bSize=eKind>=HDL_UPLFT && eKind<=HDL_LWRGT;
830     const sal_Bool bRot=pHdlList!=NULL && pHdlList->IsRotateShear();
831     const sal_Bool bDis=pHdlList!=NULL && pHdlList->IsDistortShear();
832     if (bSize && pHdlList!=NULL && (bRot || bDis)) {
833         switch (eKind) {
834             case HDL_UPLFT: case HDL_UPRGT:
835             case HDL_LWLFT: case HDL_LWRGT: ePtr=bRot ? POINTER_ROTATE : POINTER_REFHAND; break;
836             case HDL_LEFT : case HDL_RIGHT: ePtr=POINTER_VSHEAR; break;
837             case HDL_UPPER: case HDL_LOWER: ePtr=POINTER_HSHEAR; break;
838             default:
839                 break;
840         }
841     } else {
842         // Fuer Resize von gedrehten Rechtecken die Mauszeiger etwas mitdrehen
843         if (bSize && nDrehWink!=0) {
844             long nHdlWink=0;
845             switch (eKind) {
846                 case HDL_LWRGT: nHdlWink=31500; break;
847                 case HDL_LOWER: nHdlWink=27000; break;
848                 case HDL_LWLFT: nHdlWink=22500; break;
849                 case HDL_LEFT : nHdlWink=18000; break;
850                 case HDL_UPLFT: nHdlWink=13500; break;
851                 case HDL_UPPER: nHdlWink=9000;  break;
852                 case HDL_UPRGT: nHdlWink=4500;  break;
853                 case HDL_RIGHT: nHdlWink=0;     break;
854                 default:
855                     break;
856             }
857             nHdlWink+=nDrehWink+2249; // und etwas drauf (zum runden)
858             while (nHdlWink<0) nHdlWink+=36000;
859             while (nHdlWink>=36000) nHdlWink-=36000;
860             nHdlWink/=4500;
861             switch ((sal_uInt8)nHdlWink) {
862                 case 0: ePtr=POINTER_ESIZE;  break;
863                 case 1: ePtr=POINTER_NESIZE; break;
864                 case 2: ePtr=POINTER_NSIZE;  break;
865                 case 3: ePtr=POINTER_NWSIZE; break;
866                 case 4: ePtr=POINTER_WSIZE;  break;
867                 case 5: ePtr=POINTER_SWSIZE; break;
868                 case 6: ePtr=POINTER_SSIZE;  break;
869                 case 7: ePtr=POINTER_SESIZE; break;
870             } // switch
871         } else {
872             switch (eKind) {
873                 case HDL_UPLFT: ePtr=POINTER_NWSIZE;  break;
874                 case HDL_UPPER: ePtr=POINTER_NSIZE;     break;
875                 case HDL_UPRGT: ePtr=POINTER_NESIZE;  break;
876                 case HDL_LEFT : ePtr=POINTER_WSIZE;     break;
877                 case HDL_RIGHT: ePtr=POINTER_ESIZE;     break;
878                 case HDL_LWLFT: ePtr=POINTER_SWSIZE;  break;
879                 case HDL_LOWER: ePtr=POINTER_SSIZE;     break;
880                 case HDL_LWRGT: ePtr=POINTER_SESIZE;  break;
881                 case HDL_POLY : ePtr=POINTER_MOVEPOINT; break;
882                 case HDL_CIRC : ePtr=POINTER_HAND;      break;
883                 case HDL_REF1 : ePtr=POINTER_REFHAND;   break;
884                 case HDL_REF2 : ePtr=POINTER_REFHAND;   break;
885                 case HDL_BWGT : ePtr=POINTER_MOVEBEZIERWEIGHT; break;
886                 case HDL_GLUE : ePtr=POINTER_MOVEPOINT; break;
887 				case HDL_CUSTOMSHAPE1 : ePtr=POINTER_HAND; break;
888                 default:
889                     break;
890             }
891         }
892     }
893     return Pointer(ePtr);
894 }
895 
896 // #97016# II
897 sal_Bool SdrHdl::IsFocusHdl() const
898 {
899 	switch(eKind)
900 	{
901 		case HDL_UPLFT:		// Oben links
902 		case HDL_UPPER:		// Oben
903 		case HDL_UPRGT:		// Oben rechts
904 		case HDL_LEFT:		// Links
905 		case HDL_RIGHT:		// Rechts
906 		case HDL_LWLFT:		// Unten links
907 		case HDL_LOWER:		// Unten
908 		case HDL_LWRGT:		// Unten rechts
909 		{
910 			// if it's a activated TextEdit, it's moved to extended points
911 			if(pHdlList && pHdlList->IsMoveOutside())
912 				return sal_False;
913 			else
914 				return sal_True;
915 		}
916 
917 		case HDL_MOVE:		// Handle zum Verschieben des Objekts
918 		case HDL_POLY:		// Punktselektion an Polygon oder Bezierkurve
919 		case HDL_BWGT:		// Gewicht an einer Bezierkurve
920 		case HDL_CIRC:		// Winkel an Kreissegmenten, Eckenradius am Rect
921 		case HDL_REF1:		// Referenzpunkt 1, z.B. Rotationsmitte
922 		case HDL_REF2:		// Referenzpunkt 2, z.B. Endpunkt der Spiegelachse
923 		//case HDL_MIRX:		// Die Spiegelachse selbst
924 		case HDL_GLUE:		// GluePoint
925 
926 		// #98388# do NOT activate here, let SW implement their own SdrHdl and
927 		// overload IsFocusHdl() there to make the anchor accessible
928 		//case HDL_ANCHOR:		// anchor symbol (SD, SW)
929 		// #101688# same for AnchorTR
930 		//case HDL_ANCHOR_TR:	// anchor symbol (SD, SW)
931 
932 		//case HDL_TRNS:		// interactive transparence
933 		//case HDL_GRAD:		// interactive gradient
934 		//case HDL_COLR:		// interactive color
935 
936 		// for SJ and the CustomShapeHandles:
937 		case HDL_CUSTOMSHAPE1:
938 
939 		case HDL_USER:
940 		{
941 			return sal_True;
942 		}
943 
944 		default:
945 		{
946 			return sal_False;
947 		}
948 	}
949 }
950 
951 void SdrHdl::onMouseEnter(const MouseEvent& /*rMEvt*/)
952 {
953 }
954 
955 void SdrHdl::onMouseLeave()
956 {
957 }
958 
959 bool SdrHdl::isMouseOver() const
960 {
961 	return mbMouseOver;
962 }
963 
964 ////////////////////////////////////////////////////////////////////////////////////////////////////
965 // class SdrHdlColor
966 
967 SdrHdlColor::SdrHdlColor(const Point& rRef, Color aCol, const Size& rSize, sal_Bool bLum)
968 :	SdrHdl(rRef, HDL_COLR),
969 	aMarkerSize(rSize),
970 	bUseLuminance(bLum)
971 {
972 	if(IsUseLuminance())
973 		aCol = GetLuminance(aCol);
974 
975 	// remember color
976 	aMarkerColor = aCol;
977 }
978 
979 SdrHdlColor::~SdrHdlColor()
980 {
981 }
982 
983 void SdrHdlColor::CreateB2dIAObject()
984 {
985 	// first throw away old one
986 	GetRidOfIAObject();
987 
988 	if(pHdlList)
989 	{
990 		SdrMarkView* pView = pHdlList->GetView();
991 
992 		if(pView && !pView->areMarkHandlesHidden())
993 		{
994 			SdrPageView* pPageView = pView->GetSdrPageView();
995 
996 			if(pPageView)
997 			{
998 				for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
999 				{
1000 					// const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
1001 					const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1002 
1003 					if(rPageWindow.GetPaintWindow().OutputToWindow())
1004 					{
1005 						if(rPageWindow.GetOverlayManager())
1006 						{
1007 							Bitmap aBmpCol(CreateColorDropper(aMarkerColor));
1008 							basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
1009 							::sdr::overlay::OverlayObject* pNewOverlayObject = new
1010 								::sdr::overlay::OverlayBitmapEx(
1011 									aPosition,
1012                                     BitmapEx(aBmpCol),
1013 									(sal_uInt16)(aBmpCol.GetSizePixel().Width() - 1) >> 1,
1014 									(sal_uInt16)(aBmpCol.GetSizePixel().Height() - 1) >> 1
1015 								);
1016 							DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
1017 
1018 							// OVERLAYMANAGER
1019 							if(pNewOverlayObject)
1020 							{
1021 								rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1022 								maOverlayGroup.append(*pNewOverlayObject);
1023 							}
1024 						}
1025 					}
1026 				}
1027 			}
1028 		}
1029 	}
1030 }
1031 
1032 Bitmap SdrHdlColor::CreateColorDropper(Color aCol)
1033 {
1034 	// get the Bitmap
1035 	Bitmap aRetval(aMarkerSize, 24);
1036 	aRetval.Erase(aCol);
1037 
1038 	// get write access
1039 	BitmapWriteAccess* pWrite = aRetval.AcquireWriteAccess();
1040 	DBG_ASSERT(pWrite, "Got NO write access to a new Bitmap !!!");
1041 
1042 	if(pWrite)
1043 	{
1044 		// draw outer border
1045 		sal_Int32 nWidth = aMarkerSize.Width();
1046 		sal_Int32 nHeight = aMarkerSize.Height();
1047 
1048 		pWrite->SetLineColor(Color(COL_LIGHTGRAY));
1049 		pWrite->DrawLine(Point(0, 0), Point(0, nHeight - 1));
1050 		pWrite->DrawLine(Point(1, 0), Point(nWidth - 1, 0));
1051 		pWrite->SetLineColor(Color(COL_GRAY));
1052 		pWrite->DrawLine(Point(1, nHeight - 1), Point(nWidth - 1, nHeight - 1));
1053 		pWrite->DrawLine(Point(nWidth - 1, 1), Point(nWidth - 1, nHeight - 2));
1054 
1055 		// draw lighter UpperLeft
1056         const Color aLightColor(
1057             (sal_uInt8)(::std::min((sal_Int16)((sal_Int16)aCol.GetRed() + (sal_Int16)0x0040), (sal_Int16)0x00ff)),
1058             (sal_uInt8)(::std::min((sal_Int16)((sal_Int16)aCol.GetGreen() + (sal_Int16)0x0040), (sal_Int16)0x00ff)),
1059             (sal_uInt8)(::std::min((sal_Int16)((sal_Int16)aCol.GetBlue() + (sal_Int16)0x0040), (sal_Int16)0x00ff)));
1060 		pWrite->SetLineColor(aLightColor);
1061 		pWrite->DrawLine(Point(1, 1), Point(1, nHeight - 2));
1062 		pWrite->DrawLine(Point(2, 1), Point(nWidth - 2, 1));
1063 
1064 		// draw darker LowerRight
1065         const Color aDarkColor(
1066             (sal_uInt8)(::std::max((sal_Int16)((sal_Int16)aCol.GetRed() - (sal_Int16)0x0040), (sal_Int16)0x0000)),
1067             (sal_uInt8)(::std::max((sal_Int16)((sal_Int16)aCol.GetGreen() - (sal_Int16)0x0040), (sal_Int16)0x0000)),
1068             (sal_uInt8)(::std::max((sal_Int16)((sal_Int16)aCol.GetBlue() - (sal_Int16)0x0040), (sal_Int16)0x0000)));
1069 		pWrite->SetLineColor(aDarkColor);
1070 		pWrite->DrawLine(Point(2, nHeight - 2), Point(nWidth - 2, nHeight - 2));
1071 		pWrite->DrawLine(Point(nWidth - 2, 2), Point(nWidth - 2, nHeight - 3));
1072 
1073 		// get rid of write access
1074 		delete pWrite;
1075 	}
1076 
1077 	return aRetval;
1078 }
1079 
1080 Color SdrHdlColor::GetLuminance(const Color& rCol)
1081 {
1082 	sal_uInt8 aLum = rCol.GetLuminance();
1083 	Color aRetval(aLum, aLum, aLum);
1084 	return aRetval;
1085 }
1086 
1087 void SdrHdlColor::CallColorChangeLink()
1088 {
1089 	aColorChangeHdl.Call(this);
1090 }
1091 
1092 void SdrHdlColor::SetColor(Color aNew, sal_Bool bCallLink)
1093 {
1094 	if(IsUseLuminance())
1095 		aNew = GetLuminance(aNew);
1096 
1097 	if(aMarkerColor != aNew)
1098 	{
1099 		// remember new color
1100 		aMarkerColor = aNew;
1101 
1102 		// create new display
1103 		Touch();
1104 
1105 		// tell about change
1106 		if(bCallLink)
1107 			CallColorChangeLink();
1108 	}
1109 }
1110 
1111 void SdrHdlColor::SetSize(const Size& rNew)
1112 {
1113 	if(rNew != aMarkerSize)
1114 	{
1115 		// remember new size
1116 		aMarkerSize = rNew;
1117 
1118 		// create new display
1119 		Touch();
1120 	}
1121 }
1122 
1123 ////////////////////////////////////////////////////////////////////////////////////////////////////
1124 // class SdrHdlGradient
1125 
1126 SdrHdlGradient::SdrHdlGradient(const Point& rRef1, const Point& rRef2, sal_Bool bGrad)
1127 :	SdrHdl(rRef1, bGrad ? HDL_GRAD : HDL_TRNS),
1128 	pColHdl1(NULL),
1129 	pColHdl2(NULL),
1130     a2ndPos(rRef2),
1131     bGradient(bGrad)
1132 {
1133 }
1134 
1135 SdrHdlGradient::~SdrHdlGradient()
1136 {
1137 }
1138 
1139 void SdrHdlGradient::Set2ndPos(const Point& rPnt)
1140 {
1141 	if(a2ndPos != rPnt)
1142 	{
1143 		// remember new position
1144 		a2ndPos = rPnt;
1145 
1146 		// create new display
1147 		Touch();
1148 	}
1149 }
1150 
1151 void SdrHdlGradient::CreateB2dIAObject()
1152 {
1153 	// first throw away old one
1154 	GetRidOfIAObject();
1155 
1156 	if(pHdlList)
1157 	{
1158 		SdrMarkView* pView = pHdlList->GetView();
1159 
1160 		if(pView && !pView->areMarkHandlesHidden())
1161 		{
1162 			SdrPageView* pPageView = pView->GetSdrPageView();
1163 
1164 			if(pPageView)
1165 			{
1166 				for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
1167 				{
1168 					const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1169 
1170 					if(rPageWindow.GetPaintWindow().OutputToWindow())
1171 					{
1172 						if(rPageWindow.GetOverlayManager())
1173 						{
1174 							// striped line in between
1175 							basegfx::B2DVector aVec(a2ndPos.X() - aPos.X(), a2ndPos.Y() - aPos.Y());
1176 							double fVecLen = aVec.getLength();
1177 							double fLongPercentArrow = (1.0 - 0.05) * fVecLen;
1178 							double fHalfArrowWidth = (0.05 * 0.5) * fVecLen;
1179 							aVec.normalize();
1180 							basegfx::B2DVector aPerpend(-aVec.getY(), aVec.getX());
1181 							sal_Int32 nMidX = (sal_Int32)(aPos.X() + aVec.getX() * fLongPercentArrow);
1182 							sal_Int32 nMidY = (sal_Int32)(aPos.Y() + aVec.getY() * fLongPercentArrow);
1183 							Point aMidPoint(nMidX, nMidY);
1184 
1185 							basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
1186 							basegfx::B2DPoint aMidPos(aMidPoint.X(), aMidPoint.Y());
1187 
1188 							::sdr::overlay::OverlayObject* pNewOverlayObject = new
1189 								::sdr::overlay::OverlayLineStriped(
1190 									aPosition, aMidPos
1191 								);
1192 							DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
1193 
1194 							pNewOverlayObject->setBaseColor(IsGradient() ? Color(COL_BLACK) : Color(COL_BLUE));
1195 							rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1196 							maOverlayGroup.append(*pNewOverlayObject);
1197 
1198 							// arrowhead
1199 							Point aLeft(aMidPoint.X() + (sal_Int32)(aPerpend.getX() * fHalfArrowWidth),
1200 										aMidPoint.Y() + (sal_Int32)(aPerpend.getY() * fHalfArrowWidth));
1201 							Point aRight(aMidPoint.X() - (sal_Int32)(aPerpend.getX() * fHalfArrowWidth),
1202 										aMidPoint.Y() - (sal_Int32)(aPerpend.getY() * fHalfArrowWidth));
1203 
1204 							basegfx::B2DPoint aPositionLeft(aLeft.X(), aLeft.Y());
1205 							basegfx::B2DPoint aPositionRight(aRight.X(), aRight.Y());
1206 							basegfx::B2DPoint aPosition2(a2ndPos.X(), a2ndPos.Y());
1207 
1208 							pNewOverlayObject = new
1209 								::sdr::overlay::OverlayTriangle(
1210 									aPositionLeft,
1211                                     aPosition2,
1212                                     aPositionRight,
1213                                     IsGradient() ? Color(COL_BLACK) : Color(COL_BLUE)
1214 								);
1215 							DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
1216 
1217 							rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1218 							maOverlayGroup.append(*pNewOverlayObject);
1219 						}
1220 					}
1221 				}
1222 			}
1223 		}
1224 	}
1225 }
1226 
1227 IMPL_LINK(SdrHdlGradient, ColorChangeHdl, SdrHdl*, /*pHdl*/)
1228 {
1229 	if(GetObj())
1230 		FromIAOToItem(GetObj(), sal_True, sal_True);
1231 	return 0;
1232 }
1233 
1234 void SdrHdlGradient::FromIAOToItem(SdrObject* _pObj, sal_Bool bSetItemOnObject, sal_Bool bUndo)
1235 {
1236 	// from IAO positions and colors to gradient
1237     const SfxItemSet& rSet = _pObj->GetMergedItemSet();
1238 
1239 	GradTransformer aGradTransformer;
1240 	GradTransGradient aOldGradTransGradient;
1241 	GradTransGradient aGradTransGradient;
1242 	GradTransVector aGradTransVector;
1243 
1244 	String aString;
1245 
1246 	aGradTransVector.maPositionA = basegfx::B2DPoint(GetPos().X(), GetPos().Y());
1247 	aGradTransVector.maPositionB = basegfx::B2DPoint(Get2ndPos().X(), Get2ndPos().Y());
1248 	if(pColHdl1)
1249 		aGradTransVector.aCol1 = pColHdl1->GetColor();
1250 	if(pColHdl2)
1251 		aGradTransVector.aCol2 = pColHdl2->GetColor();
1252 
1253 	if(IsGradient())
1254 		aOldGradTransGradient.aGradient = ((XFillGradientItem&)rSet.Get(XATTR_FILLGRADIENT)).GetGradientValue();
1255 	else
1256 		aOldGradTransGradient.aGradient = ((XFillFloatTransparenceItem&)rSet.Get(XATTR_FILLFLOATTRANSPARENCE)).GetGradientValue();
1257 
1258 	// transform vector data to gradient
1259     aGradTransformer.VecToGrad(aGradTransVector, aGradTransGradient, aOldGradTransGradient, _pObj, bMoveSingleHandle, bMoveFirstHandle);
1260 
1261 	if(bSetItemOnObject)
1262 	{
1263         SdrModel* pModel = _pObj->GetModel();
1264 		SfxItemSet aNewSet(pModel->GetItemPool());
1265 
1266 		if(IsGradient())
1267 		{
1268 			aString = String();
1269 			XFillGradientItem aNewGradItem(aString, aGradTransGradient.aGradient);
1270 			aNewSet.Put(aNewGradItem);
1271 		}
1272 		else
1273 		{
1274 			aString = String();
1275 			XFillFloatTransparenceItem aNewTransItem(aString, aGradTransGradient.aGradient);
1276 			aNewSet.Put(aNewTransItem);
1277 		}
1278 
1279 		if(bUndo && pModel->IsUndoEnabled())
1280 		{
1281 			pModel->BegUndo(SVX_RESSTR(IsGradient() ? SIP_XA_FILLGRADIENT : SIP_XA_FILLTRANSPARENCE));
1282 			pModel->AddUndo(pModel->GetSdrUndoFactory().CreateUndoAttrObject(*_pObj));
1283 			pModel->EndUndo();
1284 		}
1285 
1286 		pObj->SetMergedItemSetAndBroadcast(aNewSet);
1287 	}
1288 
1289 	// back transformation, set values on pIAOHandle
1290     aGradTransformer.GradToVec(aGradTransGradient, aGradTransVector, _pObj);
1291 
1292 	SetPos(Point(FRound(aGradTransVector.maPositionA.getX()), FRound(aGradTransVector.maPositionA.getY())));
1293 	Set2ndPos(Point(FRound(aGradTransVector.maPositionB.getX()), FRound(aGradTransVector.maPositionB.getY())));
1294 	if(pColHdl1)
1295 	{
1296 		pColHdl1->SetPos(Point(FRound(aGradTransVector.maPositionA.getX()), FRound(aGradTransVector.maPositionA.getY())));
1297 		pColHdl1->SetColor(aGradTransVector.aCol1);
1298 	}
1299 	if(pColHdl2)
1300 	{
1301 		pColHdl2->SetPos(Point(FRound(aGradTransVector.maPositionB.getX()), FRound(aGradTransVector.maPositionB.getY())));
1302 		pColHdl2->SetColor(aGradTransVector.aCol2);
1303 	}
1304 }
1305 
1306 ////////////////////////////////////////////////////////////////////////////////////////////////////
1307 
1308 SdrHdlLine::~SdrHdlLine() {}
1309 
1310 void SdrHdlLine::CreateB2dIAObject()
1311 {
1312 	// first throw away old one
1313 	GetRidOfIAObject();
1314 
1315 	if(pHdlList)
1316 	{
1317 		SdrMarkView* pView = pHdlList->GetView();
1318 
1319 		if(pView && !pView->areMarkHandlesHidden() && pHdl1 && pHdl2)
1320 		{
1321 			SdrPageView* pPageView = pView->GetSdrPageView();
1322 
1323 			if(pPageView)
1324 			{
1325 				for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
1326 				{
1327 					const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1328 
1329 					if(rPageWindow.GetPaintWindow().OutputToWindow())
1330 					{
1331 						if(rPageWindow.GetOverlayManager())
1332 						{
1333 							basegfx::B2DPoint aPosition1(pHdl1->GetPos().X(), pHdl1->GetPos().Y());
1334 							basegfx::B2DPoint aPosition2(pHdl2->GetPos().X(), pHdl2->GetPos().Y());
1335 
1336 							::sdr::overlay::OverlayObject* pNewOverlayObject = new
1337 								::sdr::overlay::OverlayLineStriped(
1338 									aPosition1,
1339 									aPosition2
1340 								);
1341 							DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
1342 
1343 							// OVERLAYMANAGER
1344 							if(pNewOverlayObject)
1345 							{
1346 								// color(?)
1347 								pNewOverlayObject->setBaseColor(Color(COL_LIGHTRED));
1348 
1349 								rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1350 								maOverlayGroup.append(*pNewOverlayObject);
1351 							}
1352 						}
1353 					}
1354 				}
1355 			}
1356 		}
1357 	}
1358 }
1359 
1360 Pointer SdrHdlLine::GetPointer() const
1361 {
1362     return Pointer(POINTER_REFHAND);
1363 }
1364 
1365 ////////////////////////////////////////////////////////////////////////////////////////////////////
1366 
1367 SdrHdlBezWgt::~SdrHdlBezWgt() {}
1368 
1369 void SdrHdlBezWgt::CreateB2dIAObject()
1370 {
1371 	// call parent
1372 	SdrHdl::CreateB2dIAObject();
1373 
1374 	// create lines
1375 	if(pHdlList)
1376 	{
1377 		SdrMarkView* pView = pHdlList->GetView();
1378 
1379 		if(pView && !pView->areMarkHandlesHidden())
1380 		{
1381 			SdrPageView* pPageView = pView->GetSdrPageView();
1382 
1383 			if(pPageView)
1384 			{
1385 				for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
1386 				{
1387 					const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1388 
1389 					if(rPageWindow.GetPaintWindow().OutputToWindow())
1390 					{
1391 						if(rPageWindow.GetOverlayManager())
1392 						{
1393 							basegfx::B2DPoint aPosition1(pHdl1->GetPos().X(), pHdl1->GetPos().Y());
1394 							basegfx::B2DPoint aPosition2(aPos.X(), aPos.Y());
1395 
1396 							if(!aPosition1.equal(aPosition2))
1397 							{
1398 								::sdr::overlay::OverlayObject* pNewOverlayObject = new
1399 									::sdr::overlay::OverlayLineStriped(
1400 										aPosition1,
1401 										aPosition2
1402 									);
1403 								DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
1404 
1405 								// OVERLAYMANAGER
1406 								if(pNewOverlayObject)
1407 								{
1408 									// line part is not hittable
1409 									pNewOverlayObject->setHittable(sal_False);
1410 
1411 									// color(?)
1412 									pNewOverlayObject->setBaseColor(Color(COL_LIGHTBLUE));
1413 
1414 									rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1415 									maOverlayGroup.append(*pNewOverlayObject);
1416 								}
1417 							}
1418 						}
1419 					}
1420 				}
1421 			}
1422 		}
1423 	}
1424 }
1425 
1426 ////////////////////////////////////////////////////////////////////////////////////////////////////
1427 
1428 E3dVolumeMarker::E3dVolumeMarker(const basegfx::B2DPolyPolygon& rWireframePoly)
1429 {
1430 	aWireframePoly = rWireframePoly;
1431 }
1432 
1433 void E3dVolumeMarker::CreateB2dIAObject()
1434 {
1435 	// create lines
1436 	if(pHdlList)
1437 	{
1438 		SdrMarkView* pView = pHdlList->GetView();
1439 
1440 		if(pView && !pView->areMarkHandlesHidden())
1441 		{
1442 			SdrPageView* pPageView = pView->GetSdrPageView();
1443 
1444 			if(pPageView)
1445 			{
1446 				for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
1447 				{
1448 					const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1449 
1450 					if(rPageWindow.GetPaintWindow().OutputToWindow())
1451 					{
1452 						if(rPageWindow.GetOverlayManager() && aWireframePoly.count())
1453 							{
1454 								::sdr::overlay::OverlayObject* pNewOverlayObject = new
1455 								::sdr::overlay::OverlayPolyPolygonStriped(aWireframePoly);
1456 								DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
1457 
1458 								// OVERLAYMANAGER
1459 								if(pNewOverlayObject)
1460 								{
1461 									pNewOverlayObject->setBaseColor(Color(COL_BLACK));
1462 
1463 									rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1464 									maOverlayGroup.append(*pNewOverlayObject);
1465 								}
1466 							}
1467 						}
1468 					}
1469 				}
1470 			}
1471 		}
1472 	}
1473 
1474 ////////////////////////////////////////////////////////////////////////////////////////////////////
1475 
1476 ImpEdgeHdl::~ImpEdgeHdl()
1477 {
1478 }
1479 
1480 void ImpEdgeHdl::CreateB2dIAObject()
1481 {
1482 	if(nObjHdlNum <= 1 && pObj)
1483 	{
1484 		// first throw away old one
1485 		GetRidOfIAObject();
1486 
1487 		BitmapColorIndex eColIndex = LightCyan;
1488 		BitmapMarkerKind eKindOfMarker = Rect_7x7;
1489 
1490 		if(pHdlList)
1491 		{
1492 			SdrMarkView* pView = pHdlList->GetView();
1493 
1494 			if(pView && !pView->areMarkHandlesHidden())
1495 			{
1496 				const SdrEdgeObj* pEdge = (SdrEdgeObj*)pObj;
1497 
1498 				if(pEdge->GetConnectedNode(nObjHdlNum == 0) != NULL)
1499 					eColIndex = LightRed;
1500 
1501 				if(nPPntNum < 2)
1502 				{
1503 					// Handle with plus sign inside
1504 					eKindOfMarker = Circ_7x7;
1505 				}
1506 
1507 				SdrPageView* pPageView = pView->GetSdrPageView();
1508 
1509 				if(pPageView)
1510 				{
1511 					for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
1512 					{
1513 						const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1514 
1515 						if(rPageWindow.GetPaintWindow().OutputToWindow())
1516 						{
1517 							if(rPageWindow.GetOverlayManager())
1518 							{
1519 								basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
1520 
1521 								::sdr::overlay::OverlayObject* pNewOverlayObject = CreateOverlayObject(
1522 									aPosition,
1523 									eColIndex,
1524 									eKindOfMarker);
1525 
1526 								// OVERLAYMANAGER
1527 								if(pNewOverlayObject)
1528 								{
1529 									rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1530 									maOverlayGroup.append(*pNewOverlayObject);
1531 								}
1532 							}
1533 						}
1534 					}
1535 				}
1536 			}
1537 		}
1538 	}
1539 	else
1540 	{
1541 		// call parent
1542 		SdrHdl::CreateB2dIAObject();
1543 	}
1544 }
1545 
1546 void ImpEdgeHdl::SetLineCode(SdrEdgeLineCode eCode)
1547 {
1548 	if(eLineCode != eCode)
1549 	{
1550 		// remember new value
1551 		eLineCode = eCode;
1552 
1553 		// create new display
1554 		Touch();
1555 	}
1556 }
1557 
1558 Pointer ImpEdgeHdl::GetPointer() const
1559 {
1560     SdrEdgeObj* pEdge=PTR_CAST(SdrEdgeObj,pObj);
1561     if (pEdge==NULL)
1562 		return SdrHdl::GetPointer();
1563     if (nObjHdlNum<=1)
1564 		return Pointer(POINTER_MOVEPOINT); //Pointer(POINTER_DRAW_CONNECT);
1565     if (IsHorzDrag())
1566 		return Pointer(POINTER_ESIZE);
1567     else
1568 		return Pointer(POINTER_SSIZE);
1569 }
1570 
1571 sal_Bool ImpEdgeHdl::IsHorzDrag() const
1572 {
1573     SdrEdgeObj* pEdge=PTR_CAST(SdrEdgeObj,pObj);
1574     if (pEdge==NULL)
1575 		return sal_False;
1576     if (nObjHdlNum<=1)
1577 		return sal_False;
1578 
1579 	SdrEdgeKind eEdgeKind = ((SdrEdgeKindItem&)(pEdge->GetObjectItem(SDRATTR_EDGEKIND))).GetValue();
1580 
1581 	const SdrEdgeInfoRec& rInfo=pEdge->aEdgeInfo;
1582     if (eEdgeKind==SDREDGE_ORTHOLINES || eEdgeKind==SDREDGE_BEZIER)
1583 	{
1584         return !rInfo.ImpIsHorzLine(eLineCode,*pEdge->pEdgeTrack);
1585     }
1586 	else if (eEdgeKind==SDREDGE_THREELINES)
1587 	{
1588         long nWink=nObjHdlNum==2 ? rInfo.nAngle1 : rInfo.nAngle2;
1589         if (nWink==0 || nWink==18000)
1590 			return sal_True;
1591         else
1592 			return sal_False;
1593     }
1594     return sal_False;
1595 }
1596 
1597 ////////////////////////////////////////////////////////////////////////////////////////////////////
1598 
1599 ImpMeasureHdl::~ImpMeasureHdl()
1600 {
1601 }
1602 
1603 void ImpMeasureHdl::CreateB2dIAObject()
1604 {
1605 	// first throw away old one
1606 	GetRidOfIAObject();
1607 
1608 	if(pHdlList)
1609 	{
1610 		SdrMarkView* pView = pHdlList->GetView();
1611 
1612 		if(pView && !pView->areMarkHandlesHidden())
1613 		{
1614 			BitmapColorIndex eColIndex = LightCyan;
1615 			BitmapMarkerKind eKindOfMarker = Rect_9x9;
1616 
1617 			if(nObjHdlNum > 1)
1618 			{
1619 				eKindOfMarker = Rect_7x7;
1620 			}
1621 
1622 			if(bSelect)
1623 			{
1624 				eColIndex = Cyan;
1625 			}
1626 
1627 			SdrPageView* pPageView = pView->GetSdrPageView();
1628 
1629 			if(pPageView)
1630 			{
1631 				for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
1632 				{
1633 					const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1634 
1635 					if(rPageWindow.GetPaintWindow().OutputToWindow())
1636 					{
1637 						if(rPageWindow.GetOverlayManager())
1638 						{
1639 							basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
1640 
1641 							::sdr::overlay::OverlayObject* pNewOverlayObject = CreateOverlayObject(
1642 								aPosition,
1643 								eColIndex,
1644 								eKindOfMarker);
1645 
1646 							// OVERLAYMANAGER
1647 							if(pNewOverlayObject)
1648 							{
1649 								rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1650 								maOverlayGroup.append(*pNewOverlayObject);
1651 							}
1652 						}
1653 					}
1654 				}
1655 			}
1656 		}
1657 	}
1658 }
1659 
1660 Pointer ImpMeasureHdl::GetPointer() const
1661 {
1662     switch (nObjHdlNum)
1663 	{
1664         case 0: case 1: return Pointer(POINTER_HAND);
1665         case 2: case 3: return Pointer(POINTER_MOVEPOINT);
1666         case 4: case 5: return SdrHdl::GetPointer(); // wird dann entsprechend gedreht
1667     } // switch
1668     return Pointer(POINTER_NOTALLOWED);
1669 }
1670 
1671 ////////////////////////////////////////////////////////////////////////////////////////////////////
1672 
1673 ImpTextframeHdl::ImpTextframeHdl(const Rectangle& rRect) :
1674     SdrHdl(rRect.TopLeft(),HDL_MOVE),
1675     maRect(rRect)
1676 {
1677 }
1678 
1679 void ImpTextframeHdl::CreateB2dIAObject()
1680 {
1681 	// first throw away old one
1682 	GetRidOfIAObject();
1683 
1684 	if(pHdlList)
1685 	{
1686 		SdrMarkView* pView = pHdlList->GetView();
1687 
1688 		if(pView && !pView->areMarkHandlesHidden())
1689 		{
1690 			SdrPageView* pPageView = pView->GetSdrPageView();
1691 
1692 			if(pPageView)
1693 			{
1694 				for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
1695 				{
1696 					const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1697 
1698 					if(rPageWindow.GetPaintWindow().OutputToWindow())
1699 					{
1700 						if(rPageWindow.GetOverlayManager())
1701 						{
1702                             const basegfx::B2DPoint aTopLeft(maRect.Left(), maRect.Top());
1703                             const basegfx::B2DPoint aBottomRight(maRect.Right(), maRect.Bottom());
1704                             const svtools::ColorConfig aColorConfig;
1705                             const Color aHatchCol( aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor );
1706 
1707                             ::sdr::overlay::OverlayHatchRect* pNewOverlayObject = new ::sdr::overlay::OverlayHatchRect(
1708                                 aTopLeft,
1709                                 aBottomRight,
1710                                 aHatchCol,
1711                                 3.0,
1712                                 3.0,
1713                                 45 * F_PI180,
1714                                 nDrehWink * -F_PI18000);
1715                             pNewOverlayObject->setHittable(false);
1716 
1717                             // OVERLAYMANAGER
1718                             if(pNewOverlayObject)
1719                             {
1720                                 rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1721                                 maOverlayGroup.append(*pNewOverlayObject);
1722                             }
1723                         }
1724                     }
1725                 }
1726             }
1727 		}
1728 	}
1729 }
1730 
1731 ////////////////////////////////////////////////////////////////////////////////////////////////////
1732 
1733 class ImpSdrHdlListSorter: public ContainerSorter {
1734 public:
1735     ImpSdrHdlListSorter(Container& rNewCont): ContainerSorter(rNewCont) {}
1736     virtual int Compare(const void* pElem1, const void* pElem2) const;
1737 };
1738 
1739 int ImpSdrHdlListSorter::Compare(const void* pElem1, const void* pElem2) const
1740 {
1741     SdrHdlKind eKind1=((SdrHdl*)pElem1)->GetKind();
1742     SdrHdlKind eKind2=((SdrHdl*)pElem2)->GetKind();
1743     // Level 1: Erst normale Handles, dann Glue, dann User, dann Plushandles, dann Retpunkt-Handles
1744     unsigned n1=1;
1745     unsigned n2=1;
1746     if (eKind1!=eKind2)
1747 	{
1748         if (eKind1==HDL_REF1 || eKind1==HDL_REF2 || eKind1==HDL_MIRX) n1=5;
1749         else if (eKind1==HDL_GLUE) n1=2;
1750         else if (eKind1==HDL_USER) n1=3;
1751 		else if (eKind1==HDL_SMARTTAG) n1=0;
1752         if (eKind2==HDL_REF1 || eKind2==HDL_REF2 || eKind2==HDL_MIRX) n2=5;
1753         else if (eKind2==HDL_GLUE) n2=2;
1754         else if (eKind2==HDL_USER) n2=3;
1755 		else if (eKind2==HDL_SMARTTAG) n2=0;
1756     }
1757     if (((SdrHdl*)pElem1)->IsPlusHdl()) n1=4;
1758     if (((SdrHdl*)pElem2)->IsPlusHdl()) n2=4;
1759     if (n1==n2)
1760 	{
1761         // Level 2: PageView (Pointer)
1762         SdrPageView* pPV1=((SdrHdl*)pElem1)->GetPageView();
1763         SdrPageView* pPV2=((SdrHdl*)pElem2)->GetPageView();
1764         if (pPV1==pPV2)
1765 		{
1766             // Level 3: Position (x+y)
1767             SdrObject* pObj1=((SdrHdl*)pElem1)->GetObj();
1768             SdrObject* pObj2=((SdrHdl*)pElem2)->GetObj();
1769             if (pObj1==pObj2)
1770 			{
1771                 sal_uInt32 nNum1=((SdrHdl*)pElem1)->GetObjHdlNum();
1772                 sal_uInt32 nNum2=((SdrHdl*)pElem2)->GetObjHdlNum();
1773                 if (nNum1==nNum2)
1774 				{ // #48763#
1775                     if (eKind1==eKind2)
1776                         return (long)pElem1<(long)pElem2 ? -1 : 1; // Notloesung, um immer die gleiche Sortierung zu haben
1777                     return (sal_uInt16)eKind1<(sal_uInt16)eKind2 ? -1 : 1;
1778                 }
1779 				else
1780 					return nNum1<nNum2 ? -1 : 1;
1781             }
1782 			else
1783 			{
1784                 return (long)pObj1<(long)pObj2 ? -1 : 1;
1785             }
1786         }
1787 		else
1788 		{
1789             return (long)pPV1<(long)pPV2 ? -1 : 1;
1790         }
1791     }
1792 	else
1793 	{
1794         return n1<n2 ? -1 : 1;
1795     }
1796 }
1797 
1798 SdrMarkView* SdrHdlList::GetView() const
1799 {
1800 	return pView;
1801 }
1802 
1803 // #105678# Help struct for re-sorting handles
1804 struct ImplHdlAndIndex
1805 {
1806 	SdrHdl*						mpHdl;
1807 	sal_uInt32					mnIndex;
1808 };
1809 
1810 // #105678# Help method for sorting handles taking care of OrdNums, keeping order in
1811 // single objects and re-sorting polygon handles intuitively
1812 extern "C" int __LOADONCALLAPI ImplSortHdlFunc( const void* pVoid1, const void* pVoid2 )
1813 {
1814 	const ImplHdlAndIndex* p1 = (ImplHdlAndIndex*)pVoid1;
1815 	const ImplHdlAndIndex* p2 = (ImplHdlAndIndex*)pVoid2;
1816 
1817 	if(p1->mpHdl->GetObj() == p2->mpHdl->GetObj())
1818 	{
1819 		if(p1->mpHdl->GetObj() && p1->mpHdl->GetObj()->ISA(SdrPathObj))
1820 		{
1821 			// same object and a path object
1822 			if((p1->mpHdl->GetKind() == HDL_POLY || p1->mpHdl->GetKind() == HDL_BWGT)
1823 				&& (p2->mpHdl->GetKind() == HDL_POLY || p2->mpHdl->GetKind() == HDL_BWGT))
1824 			{
1825 				// both handles are point or control handles
1826 				if(p1->mpHdl->GetPolyNum() == p2->mpHdl->GetPolyNum())
1827 				{
1828 					if(p1->mpHdl->GetPointNum() < p2->mpHdl->GetPointNum())
1829 					{
1830 						return -1;
1831 					}
1832 					else
1833 					{
1834 						return 1;
1835 					}
1836 				}
1837 				else if(p1->mpHdl->GetPolyNum() < p2->mpHdl->GetPolyNum())
1838 				{
1839 					return -1;
1840 				}
1841 				else
1842 				{
1843 					return 1;
1844 				}
1845 			}
1846 		}
1847 	}
1848 	else
1849 	{
1850 		if(!p1->mpHdl->GetObj())
1851 		{
1852 			return -1;
1853 		}
1854 		else if(!p2->mpHdl->GetObj())
1855 		{
1856 			return 1;
1857 		}
1858 		else
1859 		{
1860 			// different objects, use OrdNum for sort
1861 			const sal_uInt32 nOrdNum1 = p1->mpHdl->GetObj()->GetOrdNum();
1862 			const sal_uInt32 nOrdNum2 = p2->mpHdl->GetObj()->GetOrdNum();
1863 
1864 			if(nOrdNum1 < nOrdNum2)
1865 			{
1866 				return -1;
1867 			}
1868 			else
1869 			{
1870 				return 1;
1871 			}
1872 		}
1873 	}
1874 
1875 	// fallback to indices
1876 	if(p1->mnIndex < p2->mnIndex)
1877 	{
1878 		return -1;
1879 	}
1880 	else
1881 	{
1882 		return 1;
1883 	}
1884 }
1885 
1886 ////////////////////////////////////////////////////////////////////////////////////////////////////
1887 // #97016# II
1888 
1889 void SdrHdlList::TravelFocusHdl(sal_Bool bForward)
1890 {
1891 	// security correction
1892 	if(mnFocusIndex != CONTAINER_ENTRY_NOTFOUND && mnFocusIndex >= GetHdlCount())
1893 		mnFocusIndex = CONTAINER_ENTRY_NOTFOUND;
1894 
1895 	if(aList.Count())
1896 	{
1897 		// take care of old handle
1898 		const sal_uIntPtr nOldHdlNum(mnFocusIndex);
1899 		SdrHdl* pOld = GetHdl(nOldHdlNum);
1900 		//SDOsal_Bool bRefresh(sal_False);
1901 
1902 		if(pOld)
1903 		{
1904 			// switch off old handle
1905 			mnFocusIndex = CONTAINER_ENTRY_NOTFOUND;
1906 			pOld->Touch();
1907 			//SDObRefresh = sal_True;
1908 		}
1909 
1910 		// #105678# Alloc pointer array for sorted handle list
1911 		ImplHdlAndIndex* pHdlAndIndex = new ImplHdlAndIndex[aList.Count()];
1912 
1913 		// #105678# build sorted handle list
1914 		sal_uInt32 a;
1915 		for( a = 0; a < aList.Count(); a++)
1916 		{
1917 			pHdlAndIndex[a].mpHdl = (SdrHdl*)aList.GetObject(a);
1918 			pHdlAndIndex[a].mnIndex = a;
1919 		}
1920 
1921 		// #105678# qsort all entries
1922 		qsort(pHdlAndIndex, aList.Count(), sizeof(ImplHdlAndIndex), ImplSortHdlFunc);
1923 
1924 		// #105678# look for old num in sorted array
1925 		sal_uIntPtr nOldHdl(nOldHdlNum);
1926 
1927 		if(nOldHdlNum != CONTAINER_ENTRY_NOTFOUND)
1928 		{
1929 			for(a = 0; a < aList.Count(); a++)
1930 			{
1931 				if(pHdlAndIndex[a].mpHdl == pOld)
1932 				{
1933 					nOldHdl = a;
1934 					break;
1935 				}
1936 			}
1937 		}
1938 
1939 		// #105678# build new HdlNum
1940 		sal_uIntPtr nNewHdl(nOldHdl);
1941 
1942 		// #105678# do the focus travel
1943 		if(bForward)
1944 		{
1945 			if(nOldHdl != CONTAINER_ENTRY_NOTFOUND)
1946 			{
1947 				if(nOldHdl == aList.Count() - 1)
1948 				{
1949 					// end forward run
1950 					nNewHdl = CONTAINER_ENTRY_NOTFOUND;
1951 				}
1952 				else
1953 				{
1954 					// simply the next handle
1955 					nNewHdl++;
1956 				}
1957 			}
1958 			else
1959 			{
1960 				// start forward run at first entry
1961 				nNewHdl = 0;
1962 			}
1963 		}
1964 		else
1965 		{
1966 			if(nOldHdl == CONTAINER_ENTRY_NOTFOUND)
1967 			{
1968 				// start backward run at last entry
1969 				nNewHdl = aList.Count() - 1;
1970 
1971 			}
1972 			else
1973 			{
1974 				if(nOldHdl == 0)
1975 				{
1976 					// end backward run
1977 					nNewHdl = CONTAINER_ENTRY_NOTFOUND;
1978 				}
1979 				else
1980 				{
1981 					// simply the previous handle
1982 					nNewHdl--;
1983 				}
1984 			}
1985 		}
1986 
1987 		// #105678# build new HdlNum
1988 		sal_uInt32 nNewHdlNum(nNewHdl);
1989 
1990 		// look for old num in sorted array
1991 		if(nNewHdl != CONTAINER_ENTRY_NOTFOUND)
1992 		{
1993 			SdrHdl* pNew = pHdlAndIndex[nNewHdl].mpHdl;
1994 
1995 			for(a = 0; a < aList.Count(); a++)
1996 			{
1997 				if((SdrHdl*)aList.GetObject(a) == pNew)
1998 				{
1999 					nNewHdlNum = a;
2000 					break;
2001 				}
2002 			}
2003 		}
2004 
2005 		// take care of next handle
2006 		if(nOldHdlNum != nNewHdlNum)
2007 		{
2008 			mnFocusIndex = nNewHdlNum;
2009 			SdrHdl* pNew = GetHdl(mnFocusIndex);
2010 
2011 			if(pNew)
2012 			{
2013 				pNew->Touch();
2014 				//SDObRefresh = sal_True;
2015 			}
2016 		}
2017 
2018 		// #105678# free mem again
2019 		delete [] pHdlAndIndex;
2020 	}
2021 }
2022 
2023 SdrHdl* SdrHdlList::GetFocusHdl() const
2024 {
2025 	if(mnFocusIndex != CONTAINER_ENTRY_NOTFOUND && mnFocusIndex < GetHdlCount())
2026 		return GetHdl(mnFocusIndex);
2027 	else
2028 		return 0L;
2029 }
2030 
2031 void SdrHdlList::SetFocusHdl(SdrHdl* pNew)
2032 {
2033 	if(pNew)
2034 	{
2035 		SdrHdl* pActual = GetFocusHdl();
2036 
2037 		if(!pActual || pActual != pNew)
2038 		{
2039 			sal_uIntPtr nNewHdlNum = GetHdlNum(pNew);
2040 
2041 			if(nNewHdlNum != CONTAINER_ENTRY_NOTFOUND)
2042 			{
2043 				//SDOsal_Bool bRefresh(sal_False);
2044 				mnFocusIndex = nNewHdlNum;
2045 
2046 				if(pActual)
2047 				{
2048 					pActual->Touch();
2049 					//SDObRefresh = sal_True;
2050 				}
2051 
2052 				if(pNew)
2053 				{
2054 					pNew->Touch();
2055 					//SDObRefresh = sal_True;
2056 				}
2057 
2058 				//OLMif(bRefresh)
2059 				//OLM{
2060 				//OLM	if(pView)
2061 				//OLM		pView->RefreshAllIAOManagers();
2062 				//OLM}
2063 			}
2064 		}
2065 	}
2066 }
2067 
2068 void SdrHdlList::ResetFocusHdl()
2069 {
2070 	SdrHdl* pHdl = GetFocusHdl();
2071 
2072 	mnFocusIndex = CONTAINER_ENTRY_NOTFOUND;
2073 
2074 	if(pHdl)
2075 	{
2076 		pHdl->Touch();
2077 	}
2078 }
2079 
2080 ////////////////////////////////////////////////////////////////////////////////////////////////////
2081 
2082 SdrHdlList::SdrHdlList(SdrMarkView* pV)
2083 :	mnFocusIndex(CONTAINER_ENTRY_NOTFOUND),
2084 	pView(pV),
2085 	aList(1024,32,32)
2086 {
2087 	nHdlSize = 3;
2088 	bRotateShear = sal_False;
2089 	bMoveOutside = sal_False;
2090 	bDistortShear = sal_False;
2091 	bFineHandles = sal_False;
2092 }
2093 
2094 SdrHdlList::~SdrHdlList()
2095 {
2096 	Clear();
2097 }
2098 
2099 void SdrHdlList::SetHdlSize(sal_uInt16 nSiz)
2100 {
2101 	if(nHdlSize != nSiz)
2102 	{
2103 		// remember new value
2104 		nHdlSize = nSiz;
2105 
2106 		// propagate change to IAOs
2107 		for(sal_uInt32 i=0; i<GetHdlCount(); i++)
2108 		{
2109 			SdrHdl* pHdl = GetHdl(i);
2110 			pHdl->Touch();
2111 		}
2112 	}
2113 }
2114 
2115 void SdrHdlList::SetMoveOutside(sal_Bool bOn)
2116 {
2117 	if(bMoveOutside != bOn)
2118 	{
2119 		// remember new value
2120 		bMoveOutside = bOn;
2121 
2122 		// propagate change to IAOs
2123 		for(sal_uInt32 i=0; i<GetHdlCount(); i++)
2124 		{
2125 			SdrHdl* pHdl = GetHdl(i);
2126 			pHdl->Touch();
2127 		}
2128 	}
2129 }
2130 
2131 void SdrHdlList::SetRotateShear(sal_Bool bOn)
2132 {
2133 	bRotateShear = bOn;
2134 }
2135 
2136 void SdrHdlList::SetDistortShear(sal_Bool bOn)
2137 {
2138 	bDistortShear = bOn;
2139 }
2140 
2141 void SdrHdlList::SetFineHdl(sal_Bool bOn)
2142 {
2143 	if(bFineHandles != bOn)
2144 	{
2145 		// remember new state
2146 		bFineHandles = bOn;
2147 
2148 		// propagate change to IAOs
2149 		for(sal_uInt32 i=0; i<GetHdlCount(); i++)
2150 		{
2151 			SdrHdl* pHdl = GetHdl(i);
2152 			pHdl->Touch();
2153 		}
2154 	}
2155 }
2156 
2157 SdrHdl* SdrHdlList::RemoveHdl(sal_uIntPtr nNum)
2158 {
2159 	SdrHdl* pRetval = (SdrHdl*)aList.Remove(nNum);
2160 
2161 	return pRetval;
2162 }
2163 
2164 void SdrHdlList::Clear()
2165 {
2166 	for (sal_uIntPtr i=0; i<GetHdlCount(); i++)
2167 	{
2168 		SdrHdl* pHdl=GetHdl(i);
2169 		delete pHdl;
2170 	}
2171 	aList.Clear();
2172 
2173 	bRotateShear=sal_False;
2174 	bDistortShear=sal_False;
2175 }
2176 
2177 void SdrHdlList::Sort()
2178 {
2179 	// #97016# II: remember current focused handle
2180 	SdrHdl* pPrev = GetFocusHdl();
2181 
2182     ImpSdrHdlListSorter aSort(aList);
2183     aSort.DoSort();
2184 
2185 	// #97016# II: get now and compare
2186 	SdrHdl* pNow = GetFocusHdl();
2187 
2188 	if(pPrev != pNow)
2189 	{
2190 		//SDOsal_Bool bRefresh(sal_False);
2191 
2192 		if(pPrev)
2193 		{
2194 			pPrev->Touch();
2195 			//SDObRefresh = sal_True;
2196 		}
2197 
2198 		if(pNow)
2199 		{
2200 			pNow->Touch();
2201 			//SDObRefresh = sal_True;
2202 		}
2203 	}
2204 }
2205 
2206 sal_uIntPtr SdrHdlList::GetHdlNum(const SdrHdl* pHdl) const
2207 {
2208     if (pHdl==NULL)
2209 		return CONTAINER_ENTRY_NOTFOUND;
2210     sal_uIntPtr nPos=aList.GetPos(pHdl);
2211     return nPos;
2212 }
2213 
2214 void SdrHdlList::AddHdl(SdrHdl* pHdl, sal_Bool bAtBegin)
2215 {
2216     if (pHdl!=NULL)
2217 	{
2218         if (bAtBegin)
2219 		{
2220             aList.Insert(pHdl,sal_uIntPtr(0));
2221         }
2222 		else
2223 		{
2224             aList.Insert(pHdl,CONTAINER_APPEND);
2225         }
2226         pHdl->SetHdlList(this);
2227     }
2228 }
2229 
2230 SdrHdl* SdrHdlList::IsHdlListHit(const Point& rPnt, sal_Bool bBack, sal_Bool bNext, SdrHdl* pHdl0) const
2231 {
2232    SdrHdl* pRet=NULL;
2233    sal_uIntPtr nAnz=GetHdlCount();
2234    sal_uIntPtr nNum=bBack ? 0 : nAnz;
2235    while ((bBack ? nNum<nAnz : nNum>0) && pRet==NULL)
2236    {
2237        if (!bBack)
2238 		   nNum--;
2239        SdrHdl* pHdl=GetHdl(nNum);
2240        if (bNext)
2241 	   {
2242            if (pHdl==pHdl0)
2243 			   bNext=sal_False;
2244        }
2245 	   else
2246 	   {
2247            if (pHdl->IsHdlHit(rPnt))
2248 			   pRet=pHdl;
2249        }
2250        if (bBack)
2251 		   nNum++;
2252    }
2253    return pRet;
2254 }
2255 
2256 SdrHdl* SdrHdlList::GetHdl(SdrHdlKind eKind1) const
2257 {
2258    SdrHdl* pRet=NULL;
2259    for (sal_uIntPtr i=0; i<GetHdlCount() && pRet==NULL; i++)
2260    {
2261        SdrHdl* pHdl=GetHdl(i);
2262        if (pHdl->GetKind()==eKind1)
2263 		   pRet=pHdl;
2264    }
2265    return pRet;
2266 }
2267 
2268 // --------------------------------------------------------------------
2269 // SdrCropHdl
2270 // --------------------------------------------------------------------
2271 
2272 SdrCropHdl::SdrCropHdl(const Point& rPnt, SdrHdlKind eNewKind)
2273 : SdrHdl( rPnt, eNewKind )
2274 {
2275 }
2276 
2277 // --------------------------------------------------------------------
2278 
2279 BitmapEx SdrCropHdl::GetHandlesBitmap( bool bIsFineHdl, bool bIsHighContrast )
2280 {
2281 	if( bIsHighContrast )
2282 	{
2283 		static BitmapEx* pHighContrastBitmap = 0;
2284 		if( pHighContrastBitmap == 0 )
2285 			pHighContrastBitmap = new BitmapEx(ResId(SIP_SA_ACCESSIBILITY_CROP_MARKERS, *ImpGetResMgr()));
2286 		return *pHighContrastBitmap;
2287 	}
2288 	else if( bIsFineHdl )
2289 	{
2290 		static BitmapEx* pModernBitmap = 0;
2291 		if( pModernBitmap == 0 )
2292 			pModernBitmap = new BitmapEx(ResId(SIP_SA_CROP_FINE_MARKERS, *ImpGetResMgr()));
2293 		return *pModernBitmap;
2294 	}
2295 	else
2296 	{
2297 		static BitmapEx* pSimpleBitmap = 0;
2298 		if( pSimpleBitmap == 0 )
2299 			pSimpleBitmap = new BitmapEx(ResId(SIP_SA_CROP_MARKERS, *ImpGetResMgr()));
2300 		return *pSimpleBitmap;
2301 	}
2302 }
2303 
2304 // --------------------------------------------------------------------
2305 
2306 BitmapEx SdrCropHdl::GetBitmapForHandle( const BitmapEx& rBitmap, int nSize )
2307 {
2308 	int nPixelSize = 0, nX = 0, nY = 0, nOffset = 0;
2309 
2310 	if( nSize <= 3 )
2311 	{
2312 		nPixelSize = 13;
2313 		nOffset = 0;
2314 	}
2315 	else if( nSize <=4 )
2316 	{
2317 		nPixelSize = 17;
2318 		nOffset = 36;
2319 	}
2320 	else
2321 	{
2322 		nPixelSize = 21;
2323 		nOffset = 84;
2324 	}
2325 
2326 	switch( eKind )
2327 	{
2328 		case HDL_UPLFT: nX = 0; nY = 0; break;
2329 		case HDL_UPPER: nX = 1; nY = 0; break;
2330 		case HDL_UPRGT: nX = 2; nY = 0; break;
2331 		case HDL_LEFT:  nX = 0; nY = 1; break;
2332 		case HDL_RIGHT: nX = 2; nY = 1; break;
2333 		case HDL_LWLFT: nX = 0; nY = 2; break;
2334 		case HDL_LOWER: nX = 1; nY = 2; break;
2335 		case HDL_LWRGT: nX = 2; nY = 2; break;
2336 		default: break;
2337 	}
2338 
2339 	Rectangle aSourceRect( Point( nX * (nPixelSize-1) + nOffset,  nY * (nPixelSize-1)), Size(nPixelSize, nPixelSize) );
2340 
2341 	BitmapEx aRetval(rBitmap);
2342 	aRetval.Crop(aSourceRect);
2343 	return aRetval;
2344 }
2345 
2346 // --------------------------------------------------------------------
2347 
2348 void SdrCropHdl::CreateB2dIAObject()
2349 {
2350 	// first throw away old one
2351 	GetRidOfIAObject();
2352 
2353 	SdrMarkView* pView = pHdlList ? pHdlList->GetView() : 0;
2354 	SdrPageView* pPageView = pView ? pView->GetSdrPageView() : 0;
2355 
2356 	if( pPageView && !pView->areMarkHandlesHidden() )
2357 	{
2358 		sal_Bool bIsFineHdl(pHdlList->IsFineHdl());
2359 		const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
2360 		sal_Bool bIsHighContrast(rStyleSettings.GetHighContrastMode());
2361 		int nHdlSize = pHdlList->GetHdlSize();
2362 		if( bIsHighContrast )
2363 			nHdlSize = 4;
2364 
2365 		const BitmapEx aHandlesBitmap( GetHandlesBitmap( bIsFineHdl, bIsHighContrast ) );
2366 		BitmapEx aBmpEx1( GetBitmapForHandle( aHandlesBitmap, nHdlSize ) );
2367 
2368 		for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
2369 		{
2370 			// const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
2371 			const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
2372 
2373 			if(rPageWindow.GetPaintWindow().OutputToWindow())
2374 			{
2375 				if(rPageWindow.GetOverlayManager())
2376 				{
2377 					basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
2378 
2379 					::sdr::overlay::OverlayObject* pOverlayObject = 0L;
2380 
2381 					// animate focused handles
2382 					if(IsFocusHdl() && (pHdlList->GetFocusHdl() == this))
2383 					{
2384 						if( nHdlSize >= 2 )
2385 							nHdlSize = 1;
2386 
2387 						BitmapEx aBmpEx2( GetBitmapForHandle( aHandlesBitmap, nHdlSize + 1 ) );
2388 
2389 						const sal_uInt32 nBlinkTime = sal::static_int_cast<sal_uInt32>(rStyleSettings.GetCursorBlinkTime());
2390 
2391 						pOverlayObject = new ::sdr::overlay::OverlayAnimatedBitmapEx(aPosition, aBmpEx1, aBmpEx2, nBlinkTime,
2392 							(sal_uInt16)(aBmpEx1.GetSizePixel().Width() - 1) >> 1,
2393 							(sal_uInt16)(aBmpEx1.GetSizePixel().Height() - 1) >> 1,
2394 							(sal_uInt16)(aBmpEx2.GetSizePixel().Width() - 1) >> 1,
2395 							(sal_uInt16)(aBmpEx2.GetSizePixel().Height() - 1) >> 1);
2396 					}
2397 					else
2398 					{
2399 						// create centered handle as default
2400 						pOverlayObject = new ::sdr::overlay::OverlayBitmapEx(aPosition, aBmpEx1,
2401 							(sal_uInt16)(aBmpEx1.GetSizePixel().Width() - 1) >> 1,
2402 							(sal_uInt16)(aBmpEx1.GetSizePixel().Height() - 1) >> 1);
2403 					}
2404 
2405 					// OVERLAYMANAGER
2406 					if(pOverlayObject)
2407 					{
2408 						rPageWindow.GetOverlayManager()->add(*pOverlayObject);
2409 						maOverlayGroup.append(*pOverlayObject);
2410 					}
2411 				}
2412 			}
2413 		}
2414 	}
2415 }
2416 
2417 // --------------------------------------------------------------------
2418