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