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