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