xref: /AOO41X/main/svx/source/svdraw/svdhdl.cxx (revision 5980243063f6840bf3a2e60b2243db5da5e78fa6)
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_7x7 : Customshape_9x9;
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