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