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