xref: /aoo41x/main/vcl/source/control/button.cxx (revision cdf0e10c)
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_vcl.hxx"
30 
31 #include <tools/debug.hxx>
32 #include <tools/poly.hxx>
33 #include <tools/rc.h>
34 
35 #include <vcl/image.hxx>
36 #include <vcl/bitmap.hxx>
37 #include <vcl/bitmapex.hxx>
38 #include <vcl/decoview.hxx>
39 #include <vcl/event.hxx>
40 #include <vcl/svapp.hxx>
41 #include <vcl/dialog.hxx>
42 #include <vcl/fixed.hxx>
43 #include <vcl/button.hxx>
44 #include <vcl/salnativewidgets.hxx>
45 #include <vcl/edit.hxx>
46 
47 #include <svids.hrc>
48 #include <svdata.hxx>
49 #include <window.h>
50 #include <controldata.hxx>
51 
52 // =======================================================================
53 
54 #define PUSHBUTTON_VIEW_STYLE       (WB_3DLOOK |                        \
55                                      WB_LEFT | WB_CENTER | WB_RIGHT |   \
56                                      WB_TOP | WB_VCENTER | WB_BOTTOM |  \
57                                      WB_WORDBREAK | WB_NOLABEL |        \
58                                      WB_DEFBUTTON | WB_NOLIGHTBORDER |  \
59                                      WB_RECTSTYLE | WB_SMALLSTYLE |     \
60                                      WB_TOGGLE )
61 #define RADIOBUTTON_VIEW_STYLE      (WB_3DLOOK |                        \
62                                      WB_LEFT | WB_CENTER | WB_RIGHT |   \
63                                      WB_TOP | WB_VCENTER | WB_BOTTOM |  \
64                                      WB_WORDBREAK | WB_NOLABEL)
65 #define CHECKBOX_VIEW_STYLE         (WB_3DLOOK |                        \
66                                      WB_LEFT | WB_CENTER | WB_RIGHT |   \
67                                      WB_TOP | WB_VCENTER | WB_BOTTOM |  \
68                                      WB_WORDBREAK | WB_NOLABEL)
69 
70 // =======================================================================
71 
72 class ImplCommonButtonData
73 {
74 public:
75     Rectangle       maFocusRect;
76     Rectangle       maSymbolRect;
77     sal_uInt16          mnButtonState;
78     sal_Bool            mbSmallSymbol;
79 
80     Image           maImage;
81     Image           maImageHC;
82     BitmapEx*       mpBitmapEx;
83     BitmapEx*       mpBitmapExHC;
84     ImageAlign      meImageAlign;
85     SymbolAlign     meSymbolAlign;
86 
87 public:
88                     ImplCommonButtonData();
89                    ~ImplCommonButtonData();
90 };
91 
92 // -----------------------------------------------------------------------
93 ImplCommonButtonData::ImplCommonButtonData()
94 {
95     mnButtonState   = 0;
96     mbSmallSymbol = sal_False;
97 
98     mpBitmapEx = NULL;
99     mpBitmapExHC = NULL;
100     meImageAlign = IMAGEALIGN_TOP;
101     meSymbolAlign = SYMBOLALIGN_LEFT;
102 }
103 
104 // -----------------------------------------------------------------------
105 ImplCommonButtonData::~ImplCommonButtonData()
106 {
107     delete mpBitmapEx;
108     delete mpBitmapExHC;
109 }
110 
111 // =======================================================================
112 
113 Button::Button( WindowType nType ) :
114     Control( nType )
115 {
116     mpButtonData = new ImplCommonButtonData;
117 }
118 
119 // -----------------------------------------------------------------------
120 
121 Button::Button( Window* pParent, WinBits nStyle ) :
122     Control( WINDOW_BUTTON )
123 {
124     mpButtonData = new ImplCommonButtonData;
125     ImplInit( pParent, nStyle, NULL );
126 }
127 
128 // -----------------------------------------------------------------------
129 
130 Button::Button( Window* pParent, const ResId& rResId ) :
131     Control( WINDOW_BUTTON )
132 {
133     rResId.SetRT( RSC_BUTTON );
134     mpButtonData = new ImplCommonButtonData;
135     WinBits nStyle = ImplInitRes( rResId );
136     ImplInit( pParent, nStyle, NULL );
137     ImplLoadRes( rResId );
138 
139     if ( !(nStyle & WB_HIDE) )
140         Show();
141 }
142 
143 // -----------------------------------------------------------------------
144 
145 Button::~Button()
146 {
147     delete mpButtonData;
148 }
149 
150 // -----------------------------------------------------------------------
151 
152 void Button::Click()
153 {
154     ImplCallEventListenersAndHandler( VCLEVENT_BUTTON_CLICK, maClickHdl, this );
155 }
156 
157 // -----------------------------------------------------------------------
158 
159 XubString Button::GetStandardText( StandardButtonType eButton )
160 {
161     static struct
162     {
163         sal_uInt32 nResId;
164         const char* pDefText;
165     } aResIdAry[BUTTON_COUNT] =
166     {
167         { SV_BUTTONTEXT_OK, "~OK" },
168         { SV_BUTTONTEXT_CANCEL, "~Cancel" },
169         { SV_BUTTONTEXT_YES, "~Yes" },
170         { SV_BUTTONTEXT_NO, "~No" },
171         { SV_BUTTONTEXT_RETRY, "~Retry" },
172         { SV_BUTTONTEXT_HELP, "~Help" },
173         { SV_BUTTONTEXT_CLOSE, "~Close" },
174         { SV_BUTTONTEXT_MORE, "~More" },
175         { SV_BUTTONTEXT_IGNORE, "~Ignore" },
176         { SV_BUTTONTEXT_ABORT, "~Abort" },
177         { SV_BUTTONTEXT_LESS, "~Less" }
178     };
179 
180     String aText;
181     ResMgr* pResMgr = ImplGetResMgr();
182     if( pResMgr )
183     {
184         ResId aResId( aResIdAry[(sal_uInt16)eButton].nResId, *pResMgr );
185         aText = String( aResId );
186     }
187     else
188     {
189         ByteString aT( aResIdAry[(sal_uInt16)eButton].pDefText );
190         aText = String( aT, RTL_TEXTENCODING_ASCII_US );
191     }
192     return aText;
193 }
194 
195 // -----------------------------------------------------------------------
196 
197 XubString Button::GetStandardHelpText( StandardButtonType /* eButton */ )
198 {
199     XubString aHelpText;
200     return aHelpText;
201 }
202 // -----------------------------------------------------------------------
203 sal_Bool Button::SetModeImage( const Image& rImage, BmpColorMode eMode )
204 {
205     if( eMode == BMP_COLOR_NORMAL )
206     {
207         if ( rImage != mpButtonData->maImage )
208         {
209             delete mpButtonData->mpBitmapEx;
210 
211             mpButtonData->mpBitmapEx = NULL;
212             mpButtonData->maImage = rImage;
213 
214             StateChanged( STATE_CHANGE_DATA );
215         }
216     }
217     else if( eMode == BMP_COLOR_HIGHCONTRAST )
218     {
219 		if( rImage != mpButtonData->maImageHC )
220 		{
221             delete mpButtonData->mpBitmapExHC;
222 
223             mpButtonData->mpBitmapExHC = NULL;
224             mpButtonData->maImageHC = rImage;
225 
226             StateChanged( STATE_CHANGE_DATA );
227         }
228     }
229     else
230         return sal_False;
231 
232     return sal_True;
233 }
234 
235 // -----------------------------------------------------------------------
236 const Image Button::GetModeImage( BmpColorMode eMode ) const
237 {
238     if( eMode == BMP_COLOR_NORMAL )
239     {
240         return mpButtonData->maImage;
241     }
242     else if( eMode == BMP_COLOR_HIGHCONTRAST )
243     {
244         return mpButtonData->maImageHC;
245     }
246     else
247         return Image();
248 }
249 
250 // -----------------------------------------------------------------------
251 sal_Bool Button::HasImage() const
252 {
253     return !!(mpButtonData->maImage);
254 }
255 
256 // -----------------------------------------------------------------------
257 void Button::SetImageAlign( ImageAlign eAlign )
258 {
259     if ( mpButtonData->meImageAlign != eAlign )
260     {
261         mpButtonData->meImageAlign = eAlign;
262         StateChanged( STATE_CHANGE_DATA );
263     }
264 }
265 
266 // -----------------------------------------------------------------------
267 ImageAlign Button::GetImageAlign() const
268 {
269     return mpButtonData->meImageAlign;
270 }
271 
272 // -----------------------------------------------------------------------
273 sal_Bool Button::SetModeBitmap( const BitmapEx& rBitmap, BmpColorMode eMode )
274 {
275     if ( SetModeImage( rBitmap, eMode ) )
276     {
277         if( eMode == BMP_COLOR_NORMAL )
278         {
279             if ( !mpButtonData->mpBitmapEx )
280                 mpButtonData->mpBitmapEx = new BitmapEx( rBitmap );
281         }
282         else if ( eMode == BMP_COLOR_HIGHCONTRAST )
283         {
284             if ( !mpButtonData->mpBitmapExHC )
285                 mpButtonData->mpBitmapExHC = new BitmapEx( rBitmap );
286         }
287         else
288             return sal_False;
289 
290         return sal_True;
291     }
292     return sal_False;
293 }
294 
295 // -----------------------------------------------------------------------
296 BitmapEx Button::GetModeBitmap( BmpColorMode eMode ) const
297 {
298     BitmapEx aBmp;
299 
300     if ( eMode == BMP_COLOR_NORMAL )
301 	{
302 		if ( mpButtonData->mpBitmapEx )
303 			aBmp = *( mpButtonData->mpBitmapEx );
304 	}
305     else if ( eMode == BMP_COLOR_HIGHCONTRAST )
306 	{
307 		if ( mpButtonData->mpBitmapExHC )
308 			aBmp = *( mpButtonData->mpBitmapExHC );
309 	}
310 
311     return aBmp;
312 }
313 
314 // -----------------------------------------------------------------------
315 void Button::SetFocusRect( const Rectangle& rFocusRect )
316 {
317     ImplSetFocusRect( rFocusRect );
318 }
319 
320 // -----------------------------------------------------------------------
321 const Rectangle& Button::GetFocusRect() const
322 {
323     return ImplGetFocusRect();
324 }
325 
326 // -----------------------------------------------------------------------
327 
328 const Rectangle& Button::ImplGetSymbolRect() const
329 {
330     return mpButtonData->maSymbolRect;
331 }
332 
333 void Button::ImplSetSymbolRect( const Rectangle& i_rRect )
334 {
335     mpButtonData->maSymbolRect = i_rRect;
336 }
337 
338 // -----------------------------------------------------------------------
339 
340 sal_uInt16 Button::ImplGetTextStyle( XubString& rText, WinBits nWinStyle,
341                                  sal_uLong nDrawFlags )
342 {
343     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
344     sal_uInt16 nTextStyle = FixedText::ImplGetTextStyle( nWinStyle & ~WB_DEFBUTTON );
345 
346     if ( nDrawFlags & WINDOW_DRAW_NOMNEMONIC )
347     {
348         if ( nTextStyle & TEXT_DRAW_MNEMONIC )
349         {
350             rText = GetNonMnemonicString( rText );
351             nTextStyle &= ~TEXT_DRAW_MNEMONIC;
352         }
353     }
354 
355     if ( !(nDrawFlags & WINDOW_DRAW_NODISABLE) )
356     {
357         if ( !IsEnabled() )
358             nTextStyle |= TEXT_DRAW_DISABLE;
359     }
360 
361     if ( (nDrawFlags & WINDOW_DRAW_MONO) ||
362          (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
363         nTextStyle |= TEXT_DRAW_MONO;
364 
365     return nTextStyle;
366 }
367 
368 // -----------------------------------------------------------------------
369 
370 void Button::ImplDrawAlignedImage( OutputDevice* pDev, Point& rPos,
371                                    Size& rSize, sal_Bool bLayout,
372                                    sal_uLong nImageSep, sal_uLong nDrawFlags,
373                                    sal_uInt16 nTextStyle, Rectangle *pSymbolRect,
374                                    bool bAddImageSep )
375 {
376     XubString   aText( GetText() );
377     sal_Bool        bDrawImage = HasImage() && ! ( ImplGetButtonState() & BUTTON_DRAW_NOIMAGE );
378     sal_Bool        bDrawText  = aText.Len() && ! ( ImplGetButtonState() & BUTTON_DRAW_NOTEXT );
379     sal_Bool        bHasSymbol = pSymbolRect ? sal_True : sal_False;
380 
381     // No text and no image => nothing to do => return
382     if ( !bDrawImage && !bDrawText && !bHasSymbol )
383         return;
384 
385     WinBits         nWinStyle = GetStyle();
386     Rectangle       aOutRect( rPos, rSize );
387     MetricVector   *pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL;
388     String         *pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL;
389     ImageAlign      eImageAlign = mpButtonData->meImageAlign;
390     Size            aImageSize = mpButtonData->maImage.GetSizePixel();
391 
392     if ( ( nDrawFlags & WINDOW_DRAW_NOMNEMONIC ) &&
393          ( nTextStyle & TEXT_DRAW_MNEMONIC ) )
394     {
395         aText = GetNonMnemonicString( aText );
396         nTextStyle &= ~TEXT_DRAW_MNEMONIC;
397     }
398 
399     aImageSize.Width()  = CalcZoom( aImageSize.Width() );
400     aImageSize.Height() = CalcZoom( aImageSize.Height() );
401 
402     // Drawing text or symbol only is simple, use style and output rectangle
403     if ( bHasSymbol && !bDrawImage && !bDrawText )
404     {
405         *pSymbolRect = aOutRect;
406         return;
407     }
408     else if ( bDrawText && !bDrawImage && !bHasSymbol )
409     {
410         DrawControlText( *pDev, aOutRect, aText, nTextStyle, pVector, pDisplayText );
411 
412         ImplSetFocusRect( aOutRect );
413         rSize = aOutRect.GetSize();
414         rPos = aOutRect.TopLeft();
415 
416         return;
417     }
418 
419     // check for HC mode ( image only! )
420     Image    *pImage    = &(mpButtonData->maImage);
421     BitmapEx *pBitmapEx = mpButtonData->mpBitmapEx;
422 
423     if( !!(mpButtonData->maImageHC) )
424     {
425         if( GetSettings().GetStyleSettings().GetHighContrastMode() )
426         {
427             pImage = &(mpButtonData->maImageHC);
428             pBitmapEx = mpButtonData->mpBitmapExHC;
429         }
430     }
431 
432     if ( pBitmapEx && ( pDev->GetOutDevType() == OUTDEV_PRINTER ) )
433     {
434         // Die Groesse richtet sich nach dem Bildschirm, soll auf
435         // dem Drucker genau so aussehen...
436         MapMode aMap100thMM( MAP_100TH_MM );
437         aImageSize = PixelToLogic( aImageSize, aMap100thMM );
438         aImageSize = pDev->LogicToPixel( aImageSize, aMap100thMM );
439     }
440 
441     Size aTextSize;
442     Size aSymbolSize;
443     Size aMax;
444     Point aImagePos = rPos;
445     Point aTextPos = rPos;
446     Rectangle aUnion = Rectangle( aImagePos, aImageSize );
447     Rectangle aSymbol;
448     long nSymbolHeight = 0;
449 
450     if ( bDrawText || bHasSymbol )
451     {
452         // Get the size of the text output area ( the symbol will be drawn in
453         // this area as well, so the symbol rectangle will be calculated here, too )
454 
455         Rectangle   aRect = Rectangle( Point(), rSize );
456         Size        aTSSize;
457 
458         if ( bHasSymbol )
459         {
460             if ( bDrawText )
461             {
462                 nSymbolHeight = pDev->GetTextHeight();
463                 if ( mpButtonData->mbSmallSymbol )
464                     nSymbolHeight = nSymbolHeight * 3 / 4;
465 
466                 aSymbol = Rectangle( Point(), Size( nSymbolHeight, nSymbolHeight ) );
467                 ImplCalcSymbolRect( aSymbol );
468                 aRect.Left() += 3 * nSymbolHeight / 2;
469                 aTSSize.Width() = 3 * nSymbolHeight / 2;
470             }
471             else
472             {
473                 aSymbol = Rectangle( Point(), rSize );
474                 ImplCalcSymbolRect( aSymbol );
475                 aTSSize.Width() = aSymbol.GetWidth();
476             }
477             aTSSize.Height() = aSymbol.GetHeight();
478             aSymbolSize = aSymbol.GetSize();
479         }
480 
481         if ( bDrawText )
482         {
483             if ( ( eImageAlign == IMAGEALIGN_LEFT_TOP ) ||
484                 ( eImageAlign == IMAGEALIGN_LEFT ) ||
485                 ( eImageAlign == IMAGEALIGN_LEFT_BOTTOM ) ||
486                 ( eImageAlign == IMAGEALIGN_RIGHT_TOP ) ||
487                 ( eImageAlign == IMAGEALIGN_RIGHT ) ||
488                 ( eImageAlign == IMAGEALIGN_RIGHT_BOTTOM ) )
489             {
490                 aRect.Right() -= ( aImageSize.Width() + nImageSep );
491             }
492             else if ( ( eImageAlign == IMAGEALIGN_TOP_LEFT ) ||
493                 ( eImageAlign == IMAGEALIGN_TOP ) ||
494                 ( eImageAlign == IMAGEALIGN_TOP_RIGHT ) ||
495                 ( eImageAlign == IMAGEALIGN_BOTTOM_LEFT ) ||
496                 ( eImageAlign == IMAGEALIGN_BOTTOM ) ||
497                 ( eImageAlign == IMAGEALIGN_BOTTOM_RIGHT ) )
498             {
499                 aRect.Bottom() -= ( aImageSize.Height() + nImageSep );
500             }
501 
502             aRect = pDev->GetTextRect( aRect, aText, nTextStyle );
503             aTextSize = aRect.GetSize();
504 
505             aTSSize.Width()  += aTextSize.Width();
506 
507             if ( aTSSize.Height() < aTextSize.Height() )
508                 aTSSize.Height() = aTextSize.Height();
509 
510             if( bAddImageSep && bDrawImage )
511             {
512                 long nDiff = (aImageSize.Height() - aTextSize.Height()) / 3;
513                 if( nDiff > 0 )
514                     nImageSep += nDiff;
515             }
516         }
517 
518         aMax.Width() = aTSSize.Width() > aImageSize.Width() ? aTSSize.Width() : aImageSize.Width();
519         aMax.Height() = aTSSize.Height() > aImageSize.Height() ? aTSSize.Height() : aImageSize.Height();
520 
521         // Now calculate the output area for the image and the text acording to the image align flags
522 
523         if ( ( eImageAlign == IMAGEALIGN_LEFT ) ||
524              ( eImageAlign == IMAGEALIGN_RIGHT ) )
525         {
526             aImagePos.Y() = rPos.Y() + ( aMax.Height() - aImageSize.Height() ) / 2;
527             aTextPos.Y()  = rPos.Y() + ( aMax.Height() - aTSSize.Height() ) / 2;
528         }
529         else if ( ( eImageAlign == IMAGEALIGN_LEFT_BOTTOM ) ||
530                   ( eImageAlign == IMAGEALIGN_RIGHT_BOTTOM ) )
531         {
532             aImagePos.Y() = rPos.Y() + aMax.Height() - aImageSize.Height();
533             aTextPos.Y()  = rPos.Y() + aMax.Height() - aTSSize.Height();
534         }
535         else if ( ( eImageAlign == IMAGEALIGN_TOP ) ||
536                   ( eImageAlign == IMAGEALIGN_BOTTOM ) )
537         {
538             aImagePos.X() = rPos.X() + ( aMax.Width() - aImageSize.Width() ) / 2;
539             aTextPos.X()  = rPos.X() + ( aMax.Width() - aTSSize.Width() ) / 2;
540         }
541         else if ( ( eImageAlign == IMAGEALIGN_TOP_RIGHT ) ||
542                   ( eImageAlign == IMAGEALIGN_BOTTOM_RIGHT ) )
543         {
544             aImagePos.X() = rPos.X() + aMax.Width() - aImageSize.Width();
545             aTextPos.X()  = rPos.X() + aMax.Width() - aTSSize.Width();
546         }
547 
548         if ( ( eImageAlign == IMAGEALIGN_LEFT_TOP ) ||
549              ( eImageAlign == IMAGEALIGN_LEFT ) ||
550              ( eImageAlign == IMAGEALIGN_LEFT_BOTTOM ) )
551         {
552             aTextPos.X() = rPos.X() + aImageSize.Width() + nImageSep;
553         }
554         else if ( ( eImageAlign == IMAGEALIGN_RIGHT_TOP ) ||
555                   ( eImageAlign == IMAGEALIGN_RIGHT ) ||
556                   ( eImageAlign == IMAGEALIGN_RIGHT_BOTTOM ) )
557         {
558             aImagePos.X() = rPos.X() + aTSSize.Width() + nImageSep;
559         }
560         else if ( ( eImageAlign == IMAGEALIGN_TOP_LEFT ) ||
561                   ( eImageAlign == IMAGEALIGN_TOP ) ||
562                   ( eImageAlign == IMAGEALIGN_TOP_RIGHT ) )
563         {
564             aTextPos.Y() = rPos.Y() + aImageSize.Height() + nImageSep;
565         }
566         else if ( ( eImageAlign == IMAGEALIGN_BOTTOM_LEFT ) ||
567                   ( eImageAlign == IMAGEALIGN_BOTTOM ) ||
568                   ( eImageAlign == IMAGEALIGN_BOTTOM_RIGHT ) )
569         {
570             aImagePos.Y() = rPos.Y() + aTSSize.Height() + nImageSep;
571         }
572         else if ( eImageAlign == IMAGEALIGN_CENTER )
573         {
574             aImagePos.X() = rPos.X() + ( aMax.Width()  - aImageSize.Width() ) / 2;
575             aImagePos.Y() = rPos.Y() + ( aMax.Height() - aImageSize.Height() ) / 2;
576             aTextPos.X()  = rPos.X() + ( aMax.Width()  - aTSSize.Width() ) / 2;
577             aTextPos.Y()  = rPos.Y() + ( aMax.Height() - aTSSize.Height() ) / 2;
578         }
579         aUnion = Rectangle( aImagePos, aImageSize );
580         aUnion.Union( Rectangle( aTextPos, aTSSize ) );
581     }
582 
583     // Now place the combination of text and image in the output area of the button
584     // according to the window style (WinBits)
585     long nXOffset = 0;
586     long nYOffset = 0;
587 
588     if ( nWinStyle & WB_CENTER )
589     {
590         nXOffset = ( rSize.Width() - aUnion.GetWidth() ) / 2;
591     }
592     else if ( nWinStyle & WB_RIGHT )
593     {
594         nXOffset = rSize.Width() - aUnion.GetWidth();
595     }
596 
597     if ( nWinStyle & WB_VCENTER )
598     {
599         nYOffset = ( rSize.Height() - aUnion.GetHeight() ) / 2;
600     }
601     else if ( nWinStyle & WB_BOTTOM )
602     {
603         nYOffset = rSize.Height() - aUnion.GetHeight();
604     }
605 
606     // the top left corner should always be visible, so we don't allow negative offsets
607     if ( nXOffset < 0 ) nXOffset = 0;
608     if ( nYOffset < 0 ) nYOffset = 0;
609 
610     aImagePos.X() += nXOffset;
611     aImagePos.Y() += nYOffset;
612     aTextPos.X() += nXOffset;
613     aTextPos.Y() += nYOffset;
614 
615     // set rPos and rSize to the union
616     rSize = aUnion.GetSize();
617     rPos.X() += nXOffset;
618     rPos.Y() += nYOffset;
619 
620     if ( bHasSymbol )
621     {
622         if ( mpButtonData->meSymbolAlign == SYMBOLALIGN_RIGHT )
623         {
624             Point aRightPos = Point( aTextPos.X() + aTextSize.Width() + aSymbolSize.Width()/2, aTextPos.Y() );
625             *pSymbolRect = Rectangle( aRightPos, aSymbolSize );
626         }
627         else
628         {
629             *pSymbolRect = Rectangle( aTextPos, aSymbolSize );
630             aTextPos.X() += ( 3 * nSymbolHeight / 2 );
631         }
632         if ( mpButtonData->mbSmallSymbol )
633         {
634             nYOffset = (aUnion.GetHeight() - aSymbolSize.Height())/2;
635             pSymbolRect->setY( aTextPos.Y() + nYOffset );
636         }
637     }
638 
639     sal_uInt16 nStyle = 0;
640 
641     if ( ! ( nDrawFlags & WINDOW_DRAW_NODISABLE ) &&
642          ! IsEnabled() )
643         nStyle |= IMAGE_DRAW_DISABLE;
644 
645     if ( pBitmapEx && ( pDev->GetOutDevType() == OUTDEV_PRINTER ) )
646     {
647         // Fuer die BitmapEx ueberlegt sich KA noch, wie man die disablete
648         // Darstellung hinbekommt...
649         pBitmapEx->Draw( pDev, aImagePos, aImageSize /*, nStyle*/ );
650     }
651     else
652     {
653         if ( IsZoom() )
654             pDev->DrawImage( aImagePos, aImageSize, *pImage, nStyle );
655         else
656             pDev->DrawImage( aImagePos, *pImage, nStyle );
657     }
658 
659     if ( bDrawText )
660     {
661         ImplSetFocusRect( Rectangle( aTextPos, aTextSize ) );
662         pDev->DrawText( Rectangle( aTextPos, aTextSize ), aText, nTextStyle, pVector, pDisplayText );
663     }
664     else
665     {
666         ImplSetFocusRect( Rectangle( aImagePos, aImageSize ) );
667     }
668 }
669 
670 // -----------------------------------------------------------------------
671 void Button::ImplSetFocusRect( const Rectangle &rFocusRect )
672 {
673     Rectangle aFocusRect = rFocusRect;
674     Rectangle aOutputRect = Rectangle( Point(), GetOutputSizePixel() );
675 
676     if ( ! aFocusRect.IsEmpty() )
677     {
678         aFocusRect.Left()--;
679         aFocusRect.Top()--;
680         aFocusRect.Right()++;
681         aFocusRect.Bottom()++;
682     }
683 
684     if ( aFocusRect.Left() < aOutputRect.Left() )   aFocusRect.Left() = aOutputRect.Left();
685     if ( aFocusRect.Top() < aOutputRect.Top() )     aFocusRect.Top() = aOutputRect.Top();
686     if ( aFocusRect.Right() > aOutputRect.Right() ) aFocusRect.Right() = aOutputRect.Right();
687     if ( aFocusRect.Bottom() > aOutputRect.Bottom() ) aFocusRect.Bottom() = aOutputRect.Bottom();
688 
689     mpButtonData->maFocusRect = aFocusRect;
690 }
691 
692 // -----------------------------------------------------------------------
693 const Rectangle& Button::ImplGetFocusRect() const
694 {
695     return mpButtonData->maFocusRect;
696 }
697 
698 // -----------------------------------------------------------------------
699 sal_uInt16& Button::ImplGetButtonState()
700 {
701     return mpButtonData->mnButtonState;
702 }
703 
704 // -----------------------------------------------------------------------
705 sal_uInt16 Button::ImplGetButtonState() const
706 {
707     return mpButtonData->mnButtonState;
708 }
709 
710 // -----------------------------------------------------------------------
711 void Button::ImplSetSymbolAlign( SymbolAlign eAlign )
712 {
713     if ( mpButtonData->meSymbolAlign != eAlign )
714     {
715         mpButtonData->meSymbolAlign = eAlign;
716         StateChanged( STATE_CHANGE_DATA );
717     }
718 }
719 
720 // -----------------------------------------------------------------------
721 SymbolAlign Button::ImplGetSymbolAlign() const
722 {
723     return mpButtonData->meSymbolAlign;
724 }
725 // -----------------------------------------------------------------------
726 void Button::ImplSetSmallSymbol( sal_Bool bSmall )
727 {
728     mpButtonData->mbSmallSymbol = bSmall;
729 }
730 
731 // -----------------------------------------------------------------------
732 void Button::EnableImageDisplay( sal_Bool bEnable )
733 {
734     if( bEnable )
735         mpButtonData->mnButtonState &= ~BUTTON_DRAW_NOIMAGE;
736     else
737         mpButtonData->mnButtonState |= BUTTON_DRAW_NOIMAGE;
738 }
739 
740 // -----------------------------------------------------------------------
741 sal_Bool Button::IsImageDisplayEnabled()
742 {
743     return (mpButtonData->mnButtonState & BUTTON_DRAW_NOIMAGE) == 0;
744 }
745 
746 // -----------------------------------------------------------------------
747 void Button::EnableTextDisplay( sal_Bool bEnable )
748 {
749     if( bEnable )
750         mpButtonData->mnButtonState &= ~BUTTON_DRAW_NOTEXT;
751     else
752         mpButtonData->mnButtonState |= BUTTON_DRAW_NOTEXT;
753 }
754 
755 // -----------------------------------------------------------------------
756 sal_Bool Button::IsTextDisplayEnabled()
757 {
758     return (mpButtonData->mnButtonState & BUTTON_DRAW_NOTEXT) == 0;
759 }
760 
761 // -----------------------------------------------------------------------
762 void Button::SetSmallSymbol (bool small)
763 {
764     ImplSetSmallSymbol (small);
765 }
766 
767 bool Button::IsSmallSymbol () const
768 {
769     return mpButtonData->mbSmallSymbol;
770 }
771 
772 // =======================================================================
773 
774 void PushButton::ImplInitPushButtonData()
775 {
776     mpWindowImpl->mbPushButton    = sal_True;
777 
778     meSymbol        = SYMBOL_NOSYMBOL;
779     meState         = STATE_NOCHECK;
780     meSaveValue     = STATE_NOCHECK;
781     mnDDStyle       = 0;
782     mbPressed       = sal_False;
783     mbInUserDraw    = sal_False;
784 }
785 
786 // -----------------------------------------------------------------------
787 
788 void PushButton::ImplInit( Window* pParent, WinBits nStyle )
789 {
790     nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle );
791     Button::ImplInit( pParent, nStyle, NULL );
792 
793     if ( nStyle & WB_NOLIGHTBORDER )
794         ImplGetButtonState() |= BUTTON_DRAW_NOLIGHTBORDER;
795 
796     ImplInitSettings( sal_True, sal_True, sal_True );
797 }
798 
799 // -----------------------------------------------------------------------
800 
801 WinBits PushButton::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle )
802 {
803     if ( !(nStyle & WB_NOTABSTOP) )
804         nStyle |= WB_TABSTOP;
805 
806     // if no alignment is given, default to "vertically centered". This is because since
807     // #i26046#, we respect the vertical alignment flags (previously we didn't completely),
808     // but we of course want to look as before when no vertical alignment is specified
809     if ( ( nStyle & ( WB_TOP | WB_VCENTER | WB_BOTTOM ) ) == 0 )
810         nStyle |= WB_VCENTER;
811 
812     if ( !(nStyle & WB_NOGROUP) &&
813          (!pPrevWindow ||
814           ((pPrevWindow->GetType() != WINDOW_PUSHBUTTON) &&
815            (pPrevWindow->GetType() != WINDOW_OKBUTTON) &&
816            (pPrevWindow->GetType() != WINDOW_CANCELBUTTON) &&
817            (pPrevWindow->GetType() != WINDOW_HELPBUTTON)) ) )
818         nStyle |= WB_GROUP;
819     return nStyle;
820 }
821 
822 // -----------------------------------------------------------------
823 
824 const Font& PushButton::GetCanonicalFont( const StyleSettings& _rStyle ) const
825 {
826     return _rStyle.GetPushButtonFont();
827 }
828 
829 // -----------------------------------------------------------------
830 const Color& PushButton::GetCanonicalTextColor( const StyleSettings& _rStyle ) const
831 {
832     return _rStyle.GetButtonTextColor();
833 }
834 
835 // -----------------------------------------------------------------------
836 
837 void PushButton::ImplInitSettings( sal_Bool bFont,
838                                    sal_Bool bForeground, sal_Bool bBackground )
839 {
840     Button::ImplInitSettings( bFont, bForeground );
841 
842     if ( bBackground )
843     {
844         SetBackground();
845         // #i38498#: do not check for GetParent()->IsChildTransparentModeEnabled()
846         // otherwise the formcontrol button will be overdrawn due to PARENTCLIPMODE_NOCLIP
847         // for radio and checkbox this is ok as they shoud appear transparent in documents
848         if ( IsNativeControlSupported( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL ) ||
849              (GetStyle() & WB_FLATBUTTON) != 0 )
850         {
851             EnableChildTransparentMode( sal_True );
852             SetParentClipMode( PARENTCLIPMODE_NOCLIP );
853             SetPaintTransparent( sal_True );
854             mpWindowImpl->mbUseNativeFocus = (GetStyle() & WB_FLATBUTTON)
855                 ? false
856                 : ImplGetSVData()->maNWFData.mbNoFocusRects;
857         }
858         else
859         {
860             EnableChildTransparentMode( sal_False );
861             SetParentClipMode( 0 );
862             SetPaintTransparent( sal_False );
863         }
864     }
865 }
866 
867 // -----------------------------------------------------------------------
868 
869 void PushButton::ImplDrawPushButtonFrame( Window* pDev,
870                                           Rectangle& rRect, sal_uInt16 nStyle )
871 {
872     if ( !(pDev->GetStyle() & (WB_RECTSTYLE | WB_SMALLSTYLE)) )
873     {
874         StyleSettings aStyleSettings = pDev->GetSettings().GetStyleSettings();
875         if ( pDev->IsControlBackground() )
876             aStyleSettings.Set3DColors( pDev->GetControlBackground() );
877     }
878 
879     DecorationView aDecoView( pDev );
880     if ( pDev->IsControlBackground() )
881     {
882         AllSettings     aSettings = pDev->GetSettings();
883         AllSettings     aOldSettings = aSettings;
884         StyleSettings   aStyleSettings = aSettings.GetStyleSettings();
885         aStyleSettings.Set3DColors( pDev->GetControlBackground() );
886         aSettings.SetStyleSettings( aStyleSettings );
887         pDev->OutputDevice::SetSettings( aSettings );
888         rRect = aDecoView.DrawButton( rRect, nStyle );
889         pDev->OutputDevice::SetSettings( aOldSettings );
890     }
891     else
892         rRect = aDecoView.DrawButton( rRect, nStyle );
893 }
894 
895 // -----------------------------------------------------------------------
896 
897 sal_Bool PushButton::ImplHitTestPushButton( Window* pDev,
898                                         const Point& rPos )
899 {
900     Point       aTempPoint;
901     Rectangle   aTestRect( aTempPoint, pDev->GetOutputSizePixel() );
902 
903     return aTestRect.IsInside( rPos );
904 }
905 
906 // -----------------------------------------------------------------------
907 
908 sal_uInt16 PushButton::ImplGetTextStyle( sal_uLong nDrawFlags ) const
909 {
910     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
911 
912     sal_uInt16 nTextStyle = TEXT_DRAW_MNEMONIC | TEXT_DRAW_MULTILINE | TEXT_DRAW_ENDELLIPSIS;
913 
914     if ( ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO ) ||
915          ( nDrawFlags & WINDOW_DRAW_MONO ) )
916         nTextStyle |= TEXT_DRAW_MONO;
917 
918     if ( GetStyle() & WB_WORDBREAK )
919         nTextStyle |= TEXT_DRAW_WORDBREAK;
920     if ( GetStyle() & WB_NOLABEL )
921         nTextStyle &= ~TEXT_DRAW_MNEMONIC;
922 
923     if ( GetStyle() & WB_LEFT )
924         nTextStyle |= TEXT_DRAW_LEFT;
925     else if ( GetStyle() & WB_RIGHT )
926         nTextStyle |= TEXT_DRAW_RIGHT;
927     else
928         nTextStyle |= TEXT_DRAW_CENTER;
929 
930     if ( GetStyle() & WB_TOP )
931         nTextStyle |= TEXT_DRAW_TOP;
932     else if ( GetStyle() & WB_BOTTOM )
933         nTextStyle |= TEXT_DRAW_BOTTOM;
934     else
935         nTextStyle |= TEXT_DRAW_VCENTER;
936 
937     if ( ! ( (nDrawFlags & WINDOW_DRAW_NODISABLE) || IsEnabled() ) )
938         nTextStyle |= TEXT_DRAW_DISABLE;
939 
940     return nTextStyle;
941 }
942 
943 // -----------------------------------------------------------------------
944 
945 static void ImplDrawBtnDropDownArrow( OutputDevice* pDev,
946                                       long nX, long nY,
947                                       Color& rColor, sal_Bool bBlack )
948 {
949     Color aOldLineColor = pDev->GetLineColor();
950     Color aOldFillColor = pDev->GetFillColor();
951 
952     pDev->SetLineColor();
953     if ( bBlack )
954         pDev->SetFillColor( Color( COL_BLACK ) );
955     else
956         pDev->SetFillColor( rColor );
957     pDev->DrawRect( Rectangle( nX+0, nY+0, nX+6, nY+0 ) );
958     pDev->DrawRect( Rectangle( nX+1, nY+1, nX+5, nY+1 ) );
959     pDev->DrawRect( Rectangle( nX+2, nY+2, nX+4, nY+2 ) );
960     pDev->DrawRect( Rectangle( nX+3, nY+3, nX+3, nY+3 ) );
961     if ( bBlack )
962     {
963         pDev->SetFillColor( rColor );
964         pDev->DrawRect( Rectangle( nX+2, nY+1, nX+4, nY+1 ) );
965         pDev->DrawRect( Rectangle( nX+3, nY+2, nX+3, nY+2 ) );
966     }
967     pDev->SetLineColor( aOldLineColor );
968     pDev->SetFillColor( aOldFillColor );
969 }
970 
971 // -----------------------------------------------------------------------
972 
973 void PushButton::ImplDrawPushButtonContent( OutputDevice* pDev, sal_uLong nDrawFlags,
974                                             const Rectangle& rRect,
975                                             bool bLayout,
976                                             bool bMenuBtnSep
977                                             )
978 {
979     const StyleSettings&    rStyleSettings = GetSettings().GetStyleSettings();
980     Rectangle               aInRect = rRect;
981     Color                   aColor;
982     XubString               aText = PushButton::GetText(); // PushButton:: wegen MoreButton
983     sal_uInt16                  nTextStyle = ImplGetTextStyle( nDrawFlags );
984     sal_uInt16                  nStyle;
985 
986     if( aInRect.nRight < aInRect.nLeft || aInRect.nBottom < aInRect.nTop )
987         aInRect.SetEmpty();
988 
989     pDev->Push( PUSH_CLIPREGION );
990     pDev->IntersectClipRegion( aInRect );
991 
992     if ( nDrawFlags & WINDOW_DRAW_MONO )
993         aColor = Color( COL_BLACK );
994     else if ( IsControlForeground() )
995         aColor = GetControlForeground();
996     else if( nDrawFlags & WINDOW_DRAW_ROLLOVER )
997         aColor = rStyleSettings.GetButtonRolloverTextColor();
998     else
999         aColor = rStyleSettings.GetButtonTextColor();
1000 
1001     pDev->SetTextColor( aColor );
1002 
1003     if ( IsEnabled() || (nDrawFlags & WINDOW_DRAW_NODISABLE) )
1004         nStyle = 0;
1005     else
1006         nStyle = SYMBOL_DRAW_DISABLE;
1007 
1008     Size aSize = rRect.GetSize();
1009     Point aPos = rRect.TopLeft();
1010 
1011     sal_uLong nImageSep = 1 + (pDev->GetTextHeight()-10)/2;
1012     if( nImageSep < 1 )
1013         nImageSep = 1;
1014     if ( mnDDStyle == PUSHBUTTON_DROPDOWN_MENUBUTTON )
1015     {
1016         if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
1017         {
1018             // calc Symbol- and Textrect
1019             long nSymbolSize    = pDev->GetTextHeight() / 2 + 1;
1020             aInRect.Right()    -= 5;
1021             aInRect.Left()      = aInRect.Right() - nSymbolSize;
1022             aSize.Width()      -= ( 5 + nSymbolSize );
1023 
1024             ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, nImageSep,
1025                                   nDrawFlags, nTextStyle, NULL, true );
1026         }
1027         else
1028             ImplCalcSymbolRect( aInRect );
1029 
1030         if( ! bLayout )
1031         {
1032             long nDistance = (aInRect.GetHeight() > 10) ? 2 : 1;
1033             DecorationView aDecoView( pDev );
1034             if( bMenuBtnSep )
1035             {
1036                 long nX = aInRect.Left() - 2*nDistance;;
1037                 Point aStartPt( nX, aInRect.Top()+nDistance );
1038                 Point aEndPt( nX, aInRect.Bottom()-nDistance );
1039                 aDecoView.DrawSeparator( aStartPt, aEndPt );
1040             }
1041             aDecoView.DrawSymbol( aInRect, SYMBOL_SPIN_DOWN, aColor, nStyle );
1042             aInRect.Left() -= 2*nDistance;
1043             ImplSetSymbolRect( aInRect );
1044         }
1045     }
1046     else
1047     {
1048         Rectangle aSymbolRect;
1049         // FIXME: (GetStyle() & WB_FLATBUTTON) != 0 is preliminary
1050         // in the next major this should be replaced by "true"
1051         ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, nImageSep, nDrawFlags,
1052                               nTextStyle, IsSymbol() ? &aSymbolRect : NULL, true );
1053 
1054         if ( IsSymbol() && ! bLayout )
1055         {
1056             DecorationView aDecoView( pDev );
1057             aDecoView.DrawSymbol( aSymbolRect, meSymbol, aColor, nStyle );
1058             ImplSetSymbolRect( aSymbolRect );
1059         }
1060 
1061         if ( mnDDStyle == PUSHBUTTON_DROPDOWN_TOOLBOX && !bLayout )
1062         {
1063             sal_Bool    bBlack = sal_False;
1064             Color   aArrowColor( COL_BLACK );
1065 
1066             if ( !(nDrawFlags & WINDOW_DRAW_MONO) )
1067             {
1068                 if ( !IsEnabled() )
1069                     aArrowColor = rStyleSettings.GetShadowColor();
1070                 else
1071                 {
1072                     aArrowColor = Color( COL_LIGHTGREEN );
1073                     bBlack = sal_True;
1074                 }
1075             }
1076 
1077             ImplDrawBtnDropDownArrow( pDev, aInRect.Right()-6, aInRect.Top()+1,
1078                                       aArrowColor, bBlack );
1079         }
1080     }
1081 
1082     UserDrawEvent aUDEvt( this, aInRect, 0 );
1083     UserDraw( aUDEvt );
1084 
1085     pDev->Pop();  // restore clipregion
1086 }
1087 
1088 // -----------------------------------------------------------------------
1089 
1090 void PushButton::UserDraw( const UserDrawEvent& )
1091 {
1092 }
1093 
1094 // -----------------------------------------------------------------------
1095 
1096 void PushButton::ImplDrawPushButton( bool bLayout )
1097 {
1098     if( !bLayout )
1099         HideFocus();
1100 
1101     sal_uInt16                  nButtonStyle = ImplGetButtonState();
1102     Point                   aPoint;
1103     Size                    aOutSz( GetOutputSizePixel() );
1104     Rectangle               aRect( aPoint, aOutSz );
1105     Rectangle               aInRect = aRect;
1106     Rectangle               aTextRect;
1107     sal_Bool                    bNativeOK = sal_False;
1108 
1109     // adjust style if button should be rendered 'pressed'
1110     if ( mbPressed )
1111         nButtonStyle |= BUTTON_DRAW_PRESSED;
1112 
1113     // TODO: move this to Window class or make it a member !!!
1114     ControlType aCtrlType = 0;
1115     switch( GetParent()->GetType() )
1116     {
1117         case WINDOW_LISTBOX:
1118         case WINDOW_MULTILISTBOX:
1119         case WINDOW_TREELISTBOX:
1120             aCtrlType = CTRL_LISTBOX;
1121             break;
1122 
1123         case WINDOW_COMBOBOX:
1124         case WINDOW_PATTERNBOX:
1125         case WINDOW_NUMERICBOX:
1126         case WINDOW_METRICBOX:
1127         case WINDOW_CURRENCYBOX:
1128         case WINDOW_DATEBOX:
1129         case WINDOW_TIMEBOX:
1130         case WINDOW_LONGCURRENCYBOX:
1131             aCtrlType = CTRL_COMBOBOX;
1132             break;
1133         default:
1134             break;
1135     }
1136 
1137     sal_Bool bDropDown = ( IsSymbol() && (GetSymbol()==SYMBOL_SPIN_DOWN) && !GetText().Len() );
1138 
1139     if( bDropDown && (aCtrlType == CTRL_COMBOBOX || aCtrlType == CTRL_LISTBOX ) )
1140     {
1141         if( GetParent()->IsNativeControlSupported( aCtrlType, PART_ENTIRE_CONTROL) )
1142         {
1143             // skip painting if the button was already drawn by the theme
1144             if( aCtrlType == CTRL_COMBOBOX )
1145             {
1146                 Edit* pEdit = static_cast<Edit*>(GetParent());
1147                 if( pEdit->ImplUseNativeBorder( pEdit->GetStyle() ) )
1148                     bNativeOK = sal_True;
1149             }
1150             else if( GetParent()->IsNativeControlSupported( aCtrlType, HAS_BACKGROUND_TEXTURE) )
1151             {
1152                 bNativeOK = sal_True;
1153             }
1154             if( !bNativeOK && GetParent()->IsNativeControlSupported( aCtrlType, PART_BUTTON_DOWN ) )
1155             {
1156                 // let the theme draw it, note we then need support
1157                 // for CTRL_LISTBOX/PART_BUTTON_DOWN and CTRL_COMBOBOX/PART_BUTTON_DOWN
1158 
1159                 ImplControlValue    aControlValue;
1160                 ControlState        nState = 0;
1161 
1162                 if ( mbPressed ) 						nState |= CTRL_STATE_PRESSED;
1163                 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )	nState |= CTRL_STATE_PRESSED;
1164                 if ( HasFocus() )						nState |= CTRL_STATE_FOCUSED;
1165                 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT )	nState |= CTRL_STATE_DEFAULT;
1166                 if ( Window::IsEnabled() ) 				nState |= CTRL_STATE_ENABLED;
1167 
1168                 if ( IsMouseOver() && aInRect.IsInside( GetPointerPosPixel() ) )
1169                     nState |= CTRL_STATE_ROLLOVER;
1170 
1171                 bNativeOK = DrawNativeControl( aCtrlType, PART_BUTTON_DOWN, aInRect, nState,
1172                                                 aControlValue, rtl::OUString() );
1173             }
1174         }
1175     }
1176 
1177     if( bNativeOK )
1178         return;
1179 
1180     bool bRollOver = (IsMouseOver() && aInRect.IsInside( GetPointerPosPixel() ));
1181     bool bDrawMenuSep = true;
1182     if( (GetStyle() & WB_FLATBUTTON) )
1183     {
1184         if( ! bRollOver && ! HasFocus() )
1185             bDrawMenuSep = false;
1186     }
1187     if ( (bNativeOK=IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL)) == sal_True )
1188     {
1189         PushButtonValue aControlValue;
1190         Rectangle		 aCtrlRegion( aInRect );
1191         ControlState	 nState = 0;
1192 
1193         if ( mbPressed || IsChecked() )                   nState |= CTRL_STATE_PRESSED;
1194         if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) nState |= CTRL_STATE_PRESSED;
1195         if ( HasFocus() )						nState |= CTRL_STATE_FOCUSED;
1196         if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT )	nState |= CTRL_STATE_DEFAULT;
1197         if ( Window::IsEnabled() ) 				nState |= CTRL_STATE_ENABLED;
1198 
1199         if ( bRollOver )
1200             nState |= CTRL_STATE_ROLLOVER;
1201 
1202         if( GetStyle() & WB_BEVELBUTTON )
1203             aControlValue.mbBevelButton = true;
1204 
1205         // draw frame into invisible window to have aInRect modified correctly
1206         // but do not shift the inner rect for pressed buttons (ie remove BUTTON_DRAW_PRESSED)
1207         // this assumes the theme has enough visual cues to signalize the button was pressed
1208         //Window aWin( this );
1209         //ImplDrawPushButtonFrame( &aWin, aInRect, nButtonStyle & ~BUTTON_DRAW_PRESSED );
1210 
1211         // looks better this way as symbols were displaced slightly using the above approach
1212         aInRect.Top()+=4;
1213         aInRect.Bottom()-=4;
1214         aInRect.Left()+=4;
1215         aInRect.Right()-=4;
1216 
1217         // prepare single line hint (needed on mac to decide between normal push button and
1218         // rectangular bevel button look)
1219         Size aFontSize( Application::GetSettings().GetStyleSettings().GetPushButtonFont().GetSize() );
1220         aFontSize = LogicToPixel( aFontSize, MapMode( MAP_POINT ) );
1221         Size aInRectSize( LogicToPixel( Size( aInRect.GetWidth(), aInRect.GetHeight() ) ) );
1222         aControlValue.mbSingleLine = (aInRectSize.Height() < 2 * aFontSize.Height() );
1223 
1224         if( ((nState & CTRL_STATE_ROLLOVER)) || ! (GetStyle() & WB_FLATBUTTON) )
1225         {
1226             bNativeOK = DrawNativeControl( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, nState,
1227                             aControlValue, rtl::OUString()/*PushButton::GetText()*/ );
1228         }
1229         else
1230         {
1231             bNativeOK = true;
1232         }
1233 
1234         // draw content using the same aInRect as non-native VCL would do
1235         ImplDrawPushButtonContent( this,
1236                                    (nState&CTRL_STATE_ROLLOVER) ? WINDOW_DRAW_ROLLOVER : 0,
1237                                    aInRect, bLayout, bDrawMenuSep );
1238 
1239         if ( HasFocus() )
1240             ShowFocus( ImplGetFocusRect() );
1241     }
1242 
1243     if ( bNativeOK == sal_False )
1244     {
1245         // draw PushButtonFrame, aInRect has content size afterwards
1246         if( (GetStyle() & WB_FLATBUTTON) )
1247         {
1248             Rectangle aTempRect( aInRect );
1249             if( ! bLayout && bRollOver )
1250                 ImplDrawPushButtonFrame( this, aTempRect, nButtonStyle );
1251             aInRect.Left()   += 2;
1252             aInRect.Top()    += 2;
1253             aInRect.Right()  -= 2;
1254             aInRect.Bottom() -= 2;
1255         }
1256         else
1257         {
1258             if( ! bLayout )
1259                 ImplDrawPushButtonFrame( this, aInRect, nButtonStyle );
1260         }
1261 
1262         // draw content
1263         ImplDrawPushButtonContent( this, 0, aInRect, bLayout, bDrawMenuSep );
1264 
1265         if( ! bLayout && HasFocus() )
1266         {
1267             ShowFocus( ImplGetFocusRect() );
1268         }
1269     }
1270 }
1271 
1272 // -----------------------------------------------------------------------
1273 
1274 void PushButton::ImplSetDefButton( sal_Bool bSet )
1275 {
1276     Size aSize( GetSizePixel() );
1277     Point aPos( GetPosPixel() );
1278     int dLeft(0), dRight(0), dTop(0), dBottom(0);
1279     sal_Bool bSetPos = sal_False;
1280 
1281     if ( (IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL)) == sal_True )
1282     {
1283         Rectangle aBound, aCont;
1284         Rectangle aCtrlRect( 0, 0, 80, 20 ); // use a constant size to avoid accumulating
1285                                              // will not work if the theme has dynamic adornment sizes
1286         ImplControlValue aControlValue;
1287         Rectangle		 aCtrlRegion( aCtrlRect );
1288         ControlState	 nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED;
1289 
1290         // get native size of a 'default' button
1291         // and adjust the VCL button if more space for adornment is required
1292         if( GetNativeControlRegion( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion,
1293                                 nState, aControlValue, rtl::OUString(),
1294 								aBound, aCont ) )
1295         {
1296             dLeft = aCont.Left() - aBound.Left();
1297             dTop = aCont.Top() - aBound.Top();
1298             dRight = aBound.Right() - aCont.Right();
1299             dBottom = aBound.Bottom() - aCont.Bottom();
1300             bSetPos = dLeft || dTop || dRight || dBottom;
1301         }
1302     }
1303 
1304     if ( bSet )
1305     {
1306         if( !(ImplGetButtonState() & BUTTON_DRAW_DEFAULT) && bSetPos )
1307         {
1308             // adjust pos/size when toggling from non-default to default
1309             aPos.Move(-dLeft, -dTop);
1310             aSize.Width() += dLeft + dRight;
1311             aSize.Height() += dTop + dBottom;
1312         }
1313         ImplGetButtonState() |= BUTTON_DRAW_DEFAULT;
1314     }
1315     else
1316     {
1317         if( (ImplGetButtonState() & BUTTON_DRAW_DEFAULT) && bSetPos )
1318         {
1319             // adjust pos/size when toggling from default to non-default
1320             aPos.Move(dLeft, dTop);
1321             aSize.Width() -= dLeft + dRight;
1322             aSize.Height() -= dTop + dBottom;
1323         }
1324         ImplGetButtonState() &= ~BUTTON_DRAW_DEFAULT;
1325     }
1326     if( bSetPos )
1327         SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL );
1328 
1329     Invalidate();
1330 }
1331 
1332 // -----------------------------------------------------------------------
1333 
1334 sal_Bool PushButton::ImplIsDefButton() const
1335 {
1336     return (ImplGetButtonState() & BUTTON_DRAW_DEFAULT) != 0;
1337 }
1338 
1339 // -----------------------------------------------------------------------
1340 
1341 PushButton::PushButton( WindowType nType ) :
1342     Button( nType )
1343 {
1344     ImplInitPushButtonData();
1345 }
1346 
1347 // -----------------------------------------------------------------------
1348 
1349 PushButton::PushButton( Window* pParent, WinBits nStyle ) :
1350     Button( WINDOW_PUSHBUTTON )
1351 {
1352     ImplInitPushButtonData();
1353     ImplInit( pParent, nStyle );
1354 }
1355 
1356 // -----------------------------------------------------------------------
1357 
1358 PushButton::PushButton( Window* pParent, const ResId& rResId ) :
1359     Button( WINDOW_PUSHBUTTON )
1360 {
1361     ImplInitPushButtonData();
1362     rResId.SetRT( RSC_PUSHBUTTON );
1363     WinBits nStyle = ImplInitRes( rResId );
1364     ImplInit( pParent, nStyle );
1365     ImplLoadRes( rResId );
1366 
1367     if ( !(nStyle & WB_HIDE) )
1368         Show();
1369 }
1370 
1371 // -----------------------------------------------------------------------
1372 
1373 PushButton::~PushButton()
1374 {
1375 }
1376 
1377 // -----------------------------------------------------------------------
1378 
1379 void PushButton::MouseButtonDown( const MouseEvent& rMEvt )
1380 {
1381     if ( rMEvt.IsLeft() &&
1382          ImplHitTestPushButton( this, rMEvt.GetPosPixel() ) )
1383     {
1384         sal_uInt16 nTrackFlags = 0;
1385 
1386         if ( ( GetStyle() & WB_REPEAT ) &&
1387              ! ( GetStyle() & WB_TOGGLE ) )
1388             nTrackFlags |= STARTTRACK_BUTTONREPEAT;
1389 
1390         ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
1391         ImplDrawPushButton();
1392         StartTracking( nTrackFlags );
1393 
1394         if ( nTrackFlags & STARTTRACK_BUTTONREPEAT )
1395             Click();
1396     }
1397 }
1398 
1399 // -----------------------------------------------------------------------
1400 
1401 void PushButton::Tracking( const TrackingEvent& rTEvt )
1402 {
1403     if ( rTEvt.IsTrackingEnded() )
1404     {
1405         if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
1406         {
1407             if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
1408                 GrabFocus();
1409 
1410             if ( GetStyle() & WB_TOGGLE )
1411             {
1412                 // Don't toggle, when aborted
1413                 if ( !rTEvt.IsTrackingCanceled() )
1414                 {
1415                     if ( IsChecked() )
1416                     {
1417                         Check( sal_False );
1418                         ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1419                     }
1420                     else
1421                         Check( sal_True );
1422                 }
1423             }
1424             else
1425                 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1426 
1427             ImplDrawPushButton();
1428 
1429             // Bei Abbruch kein Click-Handler rufen
1430             if ( !rTEvt.IsTrackingCanceled() )
1431             {
1432                 if ( ! ( ( GetStyle() & WB_REPEAT ) &&
1433                          ! ( GetStyle() & WB_TOGGLE ) ) )
1434                     Click();
1435             }
1436         }
1437     }
1438     else
1439     {
1440         if ( ImplHitTestPushButton( this, rTEvt.GetMouseEvent().GetPosPixel() ) )
1441         {
1442             if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
1443             {
1444                 if ( rTEvt.IsTrackingRepeat() && (GetStyle() & WB_REPEAT) &&
1445                      ! ( GetStyle() & WB_TOGGLE ) )
1446                     Click();
1447             }
1448             else
1449             {
1450                 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
1451                 ImplDrawPushButton();
1452             }
1453         }
1454         else
1455         {
1456             if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
1457             {
1458                 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1459                 ImplDrawPushButton();
1460             }
1461         }
1462     }
1463 }
1464 
1465 // -----------------------------------------------------------------------
1466 
1467 void PushButton::KeyInput( const KeyEvent& rKEvt )
1468 {
1469     KeyCode aKeyCode = rKEvt.GetKeyCode();
1470 
1471     if ( !aKeyCode.GetModifier() &&
1472          ((aKeyCode.GetCode() == KEY_RETURN) || (aKeyCode.GetCode() == KEY_SPACE)) )
1473     {
1474         if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
1475         {
1476             ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
1477             ImplDrawPushButton();
1478         }
1479 
1480         if ( ( GetStyle() & WB_REPEAT ) &&
1481              ! ( GetStyle() & WB_TOGGLE ) )
1482             Click();
1483     }
1484     else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) )
1485     {
1486         ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1487         ImplDrawPushButton();
1488     }
1489     else
1490         Button::KeyInput( rKEvt );
1491 }
1492 
1493 // -----------------------------------------------------------------------
1494 
1495 void PushButton::KeyUp( const KeyEvent& rKEvt )
1496 {
1497     KeyCode aKeyCode = rKEvt.GetKeyCode();
1498 
1499     if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) &&
1500          ((aKeyCode.GetCode() == KEY_RETURN) || (aKeyCode.GetCode() == KEY_SPACE)) )
1501     {
1502         if ( GetStyle() & WB_TOGGLE )
1503         {
1504             if ( IsChecked() )
1505             {
1506                 Check( sal_False );
1507                 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1508             }
1509             else
1510                 Check( sal_True );
1511 
1512             Toggle();
1513         }
1514         else
1515             ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1516 
1517         ImplDrawPushButton();
1518 
1519         if ( !( ( GetStyle() & WB_REPEAT )  &&
1520                 ! ( GetStyle() & WB_TOGGLE ) ) )
1521             Click();
1522     }
1523     else
1524         Button::KeyUp( rKEvt );
1525 }
1526 
1527 // -----------------------------------------------------------------------
1528 
1529 void PushButton::FillLayoutData() const
1530 {
1531     mpControlData->mpLayoutData = new vcl::ControlLayoutData();
1532     const_cast<PushButton*>(this)->ImplDrawPushButton( true );
1533 }
1534 
1535 // -----------------------------------------------------------------------
1536 
1537 void PushButton::Paint( const Rectangle& )
1538 {
1539     ImplDrawPushButton();
1540 }
1541 
1542 // -----------------------------------------------------------------------
1543 
1544 void PushButton::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
1545                        sal_uLong nFlags )
1546 {
1547     Point       aPos  = pDev->LogicToPixel( rPos );
1548     Size        aSize = pDev->LogicToPixel( rSize );
1549     Rectangle   aRect( aPos, aSize );
1550     Rectangle   aTextRect;
1551     Font        aFont = GetDrawPixelFont( pDev );
1552 
1553     pDev->Push();
1554     pDev->SetMapMode();
1555     pDev->SetFont( aFont );
1556     if ( nFlags & WINDOW_DRAW_MONO )
1557 	{
1558         pDev->SetTextColor( Color( COL_BLACK ) );
1559 	}
1560     else
1561 	{
1562         pDev->SetTextColor( GetTextColor() );
1563 
1564 		// DecoView uses the FaceColor...
1565 		AllSettings aSettings = pDev->GetSettings();
1566 		StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1567 		if ( IsControlBackground() )
1568 			aStyleSettings.SetFaceColor( GetControlBackground() );
1569 		else
1570 			aStyleSettings.SetFaceColor( GetSettings().GetStyleSettings().GetFaceColor() );
1571 		aSettings.SetStyleSettings( aStyleSettings );
1572 		pDev->SetSettings( aSettings );
1573 	}
1574     pDev->SetTextFillColor();
1575 
1576     DecorationView aDecoView( pDev );
1577     sal_uInt16 nButtonStyle = 0;
1578     if ( nFlags & WINDOW_DRAW_MONO )
1579         nButtonStyle |= BUTTON_DRAW_MONO;
1580     if ( IsChecked() )
1581         nButtonStyle |= BUTTON_DRAW_CHECKED;
1582     aRect = aDecoView.DrawButton( aRect, nButtonStyle );
1583 
1584     ImplDrawPushButtonContent( pDev, nFlags, aRect, false, true );
1585     pDev->Pop();
1586 }
1587 
1588 // -----------------------------------------------------------------------
1589 
1590 void PushButton::Resize()
1591 {
1592     Control::Resize();
1593     Invalidate();
1594 }
1595 
1596 // -----------------------------------------------------------------------
1597 
1598 void PushButton::GetFocus()
1599 {
1600     ShowFocus( ImplGetFocusRect() );
1601     SetInputContext( InputContext( GetFont() ) );
1602     Button::GetFocus();
1603 }
1604 
1605 // -----------------------------------------------------------------------
1606 
1607 void PushButton::LoseFocus()
1608 {
1609     EndSelection();
1610     HideFocus();
1611     Button::LoseFocus();
1612 }
1613 
1614 // -----------------------------------------------------------------------
1615 
1616 void PushButton::StateChanged( StateChangedType nType )
1617 {
1618     Button::StateChanged( nType );
1619 
1620     if ( (nType == STATE_CHANGE_ENABLE) ||
1621          (nType == STATE_CHANGE_TEXT) ||
1622          (nType == STATE_CHANGE_IMAGE) ||
1623          (nType == STATE_CHANGE_DATA) ||
1624          (nType == STATE_CHANGE_STATE) ||
1625          (nType == STATE_CHANGE_UPDATEMODE) )
1626     {
1627         if ( IsReallyVisible() && IsUpdateMode() )
1628             Invalidate();
1629     }
1630     else if ( nType == STATE_CHANGE_STYLE )
1631     {
1632         SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) );
1633 
1634         bool bIsDefButton = ( GetStyle() & WB_DEFBUTTON ) != 0;
1635         bool bWasDefButton = ( GetPrevStyle() & WB_DEFBUTTON ) != 0;
1636         if ( bIsDefButton != bWasDefButton )
1637             ImplSetDefButton( bIsDefButton );
1638 
1639         if ( IsReallyVisible() && IsUpdateMode() )
1640         {
1641             if ( (GetPrevStyle() & PUSHBUTTON_VIEW_STYLE) !=
1642                  (GetStyle() & PUSHBUTTON_VIEW_STYLE) )
1643                 Invalidate();
1644         }
1645     }
1646     else if ( (nType == STATE_CHANGE_ZOOM) ||
1647               (nType == STATE_CHANGE_CONTROLFONT) )
1648     {
1649         ImplInitSettings( sal_True, sal_False, sal_False );
1650         Invalidate();
1651     }
1652     else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
1653     {
1654         ImplInitSettings( sal_False, sal_True, sal_False );
1655         Invalidate();
1656     }
1657     else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
1658     {
1659         ImplInitSettings( sal_False, sal_False, sal_True );
1660         Invalidate();
1661     }
1662 }
1663 
1664 // -----------------------------------------------------------------------
1665 
1666 void PushButton::DataChanged( const DataChangedEvent& rDCEvt )
1667 {
1668     Button::DataChanged( rDCEvt );
1669 
1670     if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
1671          (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
1672          ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1673           (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
1674     {
1675         ImplInitSettings( sal_True, sal_True, sal_True );
1676         Invalidate();
1677     }
1678 }
1679 
1680 // -----------------------------------------------------------------------
1681 
1682 long PushButton::PreNotify( NotifyEvent& rNEvt )
1683 {
1684     long nDone = 0;
1685     const MouseEvent* pMouseEvt = NULL;
1686 
1687     if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
1688     {
1689         if( pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow() )
1690         {
1691             // trigger redraw as mouse over state has changed
1692 
1693             // TODO: move this to Window class or make it a member !!!
1694             ControlType aCtrlType = 0;
1695             switch( GetParent()->GetType() )
1696             {
1697                 case WINDOW_LISTBOX:
1698                 case WINDOW_MULTILISTBOX:
1699                 case WINDOW_TREELISTBOX:
1700                     aCtrlType = CTRL_LISTBOX;
1701                     break;
1702 
1703                 case WINDOW_COMBOBOX:
1704                 case WINDOW_PATTERNBOX:
1705                 case WINDOW_NUMERICBOX:
1706                 case WINDOW_METRICBOX:
1707                 case WINDOW_CURRENCYBOX:
1708                 case WINDOW_DATEBOX:
1709                 case WINDOW_TIMEBOX:
1710                 case WINDOW_LONGCURRENCYBOX:
1711                     aCtrlType = CTRL_COMBOBOX;
1712                     break;
1713                 default:
1714                     break;
1715             }
1716 
1717             sal_Bool bDropDown = ( IsSymbol() && (GetSymbol()==SYMBOL_SPIN_DOWN) && !GetText().Len() );
1718 
1719             if( bDropDown && GetParent()->IsNativeControlSupported( aCtrlType, PART_ENTIRE_CONTROL) &&
1720                    !GetParent()->IsNativeControlSupported( aCtrlType, PART_BUTTON_DOWN) )
1721             {
1722                 Window *pBorder = GetParent()->GetWindow( WINDOW_BORDER );
1723                 if(aCtrlType == CTRL_COMBOBOX)
1724                 {
1725                     // only paint the button part to avoid flickering of the combobox text
1726                     Point aPt;
1727                     Rectangle aClipRect( aPt, GetOutputSizePixel() );
1728                     aClipRect.SetPos(pBorder->ScreenToOutputPixel(OutputToScreenPixel(aClipRect.TopLeft())));
1729                     pBorder->Invalidate( aClipRect );
1730                 }
1731                 else
1732                 {
1733                     pBorder->Invalidate( INVALIDATE_NOERASE );
1734                     pBorder->Update();
1735                 }
1736             }
1737             else if( (GetStyle() & WB_FLATBUTTON) ||
1738                      IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL) )
1739             {
1740                 Invalidate();
1741             }
1742         }
1743     }
1744 
1745     return nDone ? nDone : Button::PreNotify(rNEvt);
1746 }
1747 
1748 // -----------------------------------------------------------------------
1749 
1750 void PushButton::Toggle()
1751 {
1752     ImplCallEventListenersAndHandler( VCLEVENT_PUSHBUTTON_TOGGLE, maToggleHdl, this );
1753 }
1754 
1755 // -----------------------------------------------------------------------
1756 
1757 void PushButton::SetSymbol( SymbolType eSymbol )
1758 {
1759     if ( meSymbol != eSymbol )
1760     {
1761         meSymbol = eSymbol;
1762         StateChanged( STATE_CHANGE_DATA );
1763     }
1764 }
1765 
1766 // -----------------------------------------------------------------------
1767 void PushButton::SetSymbolAlign( SymbolAlign eAlign )
1768 {
1769     ImplSetSymbolAlign( eAlign );
1770 }
1771 
1772 // -----------------------------------------------------------------------
1773 SymbolAlign PushButton::GetSymbolAlign() const
1774 {
1775     return ImplGetSymbolAlign();
1776 }
1777 
1778 // -----------------------------------------------------------------------
1779 
1780 void PushButton::SetDropDown( sal_uInt16 nStyle )
1781 {
1782     if ( mnDDStyle != nStyle )
1783     {
1784         mnDDStyle = nStyle;
1785         StateChanged( STATE_CHANGE_DATA );
1786     }
1787 }
1788 
1789 // -----------------------------------------------------------------------
1790 
1791 void PushButton::SetState( TriState eState )
1792 {
1793     if ( meState != eState )
1794     {
1795         meState = eState;
1796         if ( meState == STATE_NOCHECK )
1797             ImplGetButtonState() &= ~(BUTTON_DRAW_CHECKED | BUTTON_DRAW_DONTKNOW);
1798         else if ( meState == STATE_CHECK )
1799         {
1800             ImplGetButtonState() &= ~BUTTON_DRAW_DONTKNOW;
1801             ImplGetButtonState() |= BUTTON_DRAW_CHECKED;
1802         }
1803         else // STATE_DONTKNOW
1804         {
1805             ImplGetButtonState() &= ~BUTTON_DRAW_CHECKED;
1806             ImplGetButtonState() |= BUTTON_DRAW_DONTKNOW;
1807         }
1808 
1809         StateChanged( STATE_CHANGE_STATE );
1810         Toggle();
1811     }
1812 }
1813 
1814 // -----------------------------------------------------------------------
1815 
1816 void PushButton::SetPressed( sal_Bool bPressed )
1817 {
1818     if ( mbPressed != bPressed )
1819     {
1820         mbPressed = bPressed;
1821         StateChanged( STATE_CHANGE_DATA );
1822     }
1823 }
1824 
1825 // -----------------------------------------------------------------------
1826 
1827 void PushButton::EndSelection()
1828 {
1829     EndTracking( ENDTRACK_CANCEL );
1830     if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
1831     {
1832         ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1833         if ( !mbPressed )
1834             ImplDrawPushButton();
1835     }
1836 }
1837 
1838 // -----------------------------------------------------------------------
1839 
1840 Size PushButton::CalcMinimumSize( long nMaxWidth ) const
1841 {
1842 	Size aSize;
1843 
1844 	if ( IsSymbol() )
1845     {
1846         if ( IsSmallSymbol ())
1847             aSize = Size( 16, 12 );
1848         else
1849             aSize = Size( 26, 24 );
1850         if( mnDDStyle == PUSHBUTTON_DROPDOWN_MENUBUTTON )
1851             aSize.Width() += 4;
1852     }
1853 	else if ( IsImage() && ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) )
1854 		aSize = GetModeImage().GetSizePixel();
1855 	if ( PushButton::GetText().Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
1856 	{
1857 		sal_uLong nDrawFlags = 0;
1858 		Size textSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
1859 									 PushButton::GetText(), ImplGetTextStyle( nDrawFlags ) ).GetSize();
1860 	   aSize.Width() += int( textSize.Width () * 1.15 );
1861 	   aSize.Height() = std::max( aSize.Height(), long( textSize.Height() * 1.15 ) );
1862 	}
1863 
1864 	// cf. ImplDrawPushButton ...
1865     if( (GetStyle() & WB_SMALLSTYLE) == 0 )
1866     {
1867         aSize.Width() += 8;
1868         aSize.Height() += 8;
1869     }
1870 
1871     return CalcWindowSize( aSize );
1872 }
1873 
1874 Size PushButton::GetOptimalSize(WindowSizeType eType) const
1875 {
1876     switch (eType) {
1877     case WINDOWSIZE_MINIMUM: {
1878         return CalcMinimumSize();
1879     }
1880     default:
1881         return Button::GetOptimalSize( eType );
1882     }
1883 }
1884 
1885 // =======================================================================
1886 
1887 void OKButton::ImplInit( Window* pParent, WinBits nStyle )
1888 {
1889     PushButton::ImplInit( pParent, nStyle );
1890 
1891     SetText( Button::GetStandardText( BUTTON_OK ) );
1892     SetHelpText( Button::GetStandardHelpText( BUTTON_OK ) );
1893 }
1894 
1895 // -----------------------------------------------------------------------
1896 
1897 OKButton::OKButton( Window* pParent, WinBits nStyle ) :
1898     PushButton( WINDOW_OKBUTTON )
1899 {
1900     ImplInit( pParent, nStyle );
1901 }
1902 
1903 // -----------------------------------------------------------------------
1904 
1905 OKButton::OKButton( Window* pParent, const ResId& rResId ) :
1906     PushButton( WINDOW_OKBUTTON )
1907 {
1908     rResId.SetRT( RSC_OKBUTTON );
1909     WinBits nStyle = ImplInitRes( rResId );
1910     ImplInit( pParent, nStyle );
1911     ImplLoadRes( rResId );
1912 
1913     if ( !(nStyle & WB_HIDE) )
1914         Show();
1915 }
1916 
1917 // -----------------------------------------------------------------------
1918 
1919 void OKButton::Click()
1920 {
1921     // Ist kein Link gesetzt, dann schliesse Parent
1922     if ( !GetClickHdl() )
1923     {
1924         Window* pParent = GetParent();
1925         if ( pParent->IsSystemWindow() )
1926         {
1927             if ( pParent->IsDialog() )
1928             {
1929                 if ( ((Dialog*)pParent)->IsInExecute() )
1930                     ((Dialog*)pParent)->EndDialog( sal_True );
1931                 // gegen rekursive Aufrufe schuetzen
1932                 else if ( !((Dialog*)pParent)->IsInClose() )
1933                 {
1934                     if ( pParent->GetStyle() & WB_CLOSEABLE )
1935                         ((Dialog*)pParent)->Close();
1936                 }
1937             }
1938             else
1939             {
1940                 if ( pParent->GetStyle() & WB_CLOSEABLE )
1941                     ((SystemWindow*)pParent)->Close();
1942             }
1943         }
1944     }
1945     else
1946     {
1947         PushButton::Click();
1948     }
1949 }
1950 
1951 // =======================================================================
1952 
1953 void CancelButton::ImplInit( Window* pParent, WinBits nStyle )
1954 {
1955     PushButton::ImplInit( pParent, nStyle );
1956 
1957     SetText( Button::GetStandardText( BUTTON_CANCEL ) );
1958     SetHelpText( Button::GetStandardHelpText( BUTTON_CANCEL ) );
1959 }
1960 
1961 // -----------------------------------------------------------------------
1962 
1963 CancelButton::CancelButton( Window* pParent, WinBits nStyle ) :
1964     PushButton( WINDOW_CANCELBUTTON )
1965 {
1966     ImplInit( pParent, nStyle );
1967 }
1968 
1969 // -----------------------------------------------------------------------
1970 
1971 CancelButton::CancelButton( Window* pParent, const ResId& rResId ) :
1972     PushButton( WINDOW_CANCELBUTTON )
1973 {
1974     rResId.SetRT( RSC_CANCELBUTTON );
1975     WinBits nStyle = ImplInitRes( rResId );
1976     ImplInit( pParent, nStyle );
1977     ImplLoadRes( rResId );
1978 
1979     if ( !(nStyle & WB_HIDE) )
1980         Show();
1981 }
1982 
1983 // -----------------------------------------------------------------------
1984 
1985 void CancelButton::Click()
1986 {
1987     // Ist kein Link gesetzt, dann schliesse Parent
1988     if ( !GetClickHdl() )
1989     {
1990         Window* pParent = GetParent();
1991         if ( pParent->IsSystemWindow() )
1992         {
1993             if ( pParent->IsDialog() )
1994             {
1995                 if ( ((Dialog*)pParent)->IsInExecute() )
1996                     ((Dialog*)pParent)->EndDialog( sal_False );
1997                 // gegen rekursive Aufrufe schuetzen
1998                 else if ( !((Dialog*)pParent)->IsInClose() )
1999                 {
2000                     if ( pParent->GetStyle() & WB_CLOSEABLE )
2001                         ((Dialog*)pParent)->Close();
2002                 }
2003             }
2004             else
2005             {
2006                 if ( pParent->GetStyle() & WB_CLOSEABLE )
2007                     ((SystemWindow*)pParent)->Close();
2008             }
2009         }
2010     }
2011     else
2012     {
2013         PushButton::Click();
2014     }
2015 }
2016 
2017 // =======================================================================
2018 
2019 void HelpButton::ImplInit( Window* pParent, WinBits nStyle )
2020 {
2021     PushButton::ImplInit( pParent, nStyle | WB_NOPOINTERFOCUS );
2022 
2023     SetText( Button::GetStandardText( BUTTON_HELP ) );
2024     SetHelpText( Button::GetStandardHelpText( BUTTON_HELP ) );
2025 }
2026 
2027 // -----------------------------------------------------------------------
2028 
2029 HelpButton::HelpButton( Window* pParent, WinBits nStyle ) :
2030     PushButton( WINDOW_HELPBUTTON )
2031 {
2032     ImplInit( pParent, nStyle );
2033 }
2034 
2035 // -----------------------------------------------------------------------
2036 
2037 HelpButton::HelpButton( Window* pParent, const ResId& rResId ) :
2038     PushButton( WINDOW_HELPBUTTON )
2039 {
2040     rResId.SetRT( RSC_HELPBUTTON );
2041     WinBits nStyle = ImplInitRes( rResId );
2042     ImplInit( pParent, nStyle );
2043     ImplLoadRes( rResId );
2044 
2045     if ( !(nStyle & WB_HIDE) )
2046         Show();
2047 }
2048 
2049 // -----------------------------------------------------------------------
2050 
2051 void HelpButton::Click()
2052 {
2053     // Ist kein Link gesetzt, loese Hilfe aus
2054     if ( !GetClickHdl() )
2055     {
2056         Window* pFocusWin = Application::GetFocusWindow();
2057         if ( !pFocusWin )
2058             pFocusWin = this;
2059 
2060         HelpEvent aEvt( pFocusWin->GetPointerPosPixel(), HELPMODE_CONTEXT );
2061         pFocusWin->RequestHelp( aEvt );
2062     }
2063     PushButton::Click();
2064 }
2065 
2066 // =======================================================================
2067 
2068 void RadioButton::ImplInitRadioButtonData()
2069 {
2070     mbChecked       = sal_False;
2071     mbSaveValue     = sal_False;
2072     mbRadioCheck    = sal_True;
2073     mbStateChanged  = sal_False;
2074 }
2075 
2076 // -----------------------------------------------------------------------
2077 
2078 void RadioButton::ImplInit( Window* pParent, WinBits nStyle )
2079 {
2080     nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle );
2081     Button::ImplInit( pParent, nStyle, NULL );
2082 
2083     ImplInitSettings( sal_True, sal_True, sal_True );
2084 }
2085 
2086 // -----------------------------------------------------------------------
2087 
2088 WinBits RadioButton::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle )
2089 {
2090     if ( !(nStyle & WB_NOGROUP) &&
2091          (!pPrevWindow || (pPrevWindow->GetType() != WINDOW_RADIOBUTTON)) )
2092         nStyle |= WB_GROUP;
2093     if ( !(nStyle & WB_NOTABSTOP) )
2094     {
2095         if ( IsChecked() )
2096             nStyle |= WB_TABSTOP;
2097         else
2098             nStyle &= ~WB_TABSTOP;
2099     }
2100     return nStyle;
2101 }
2102 
2103 // -----------------------------------------------------------------
2104 
2105 const Font& RadioButton::GetCanonicalFont( const StyleSettings& _rStyle ) const
2106 {
2107     return _rStyle.GetRadioCheckFont();
2108 }
2109 
2110 // -----------------------------------------------------------------
2111 const Color& RadioButton::GetCanonicalTextColor( const StyleSettings& _rStyle ) const
2112 {
2113     return _rStyle.GetRadioCheckTextColor();
2114 }
2115 
2116 // -----------------------------------------------------------------------
2117 
2118 void RadioButton::ImplInitSettings( sal_Bool bFont,
2119                                     sal_Bool bForeground, sal_Bool bBackground )
2120 {
2121     Button::ImplInitSettings( bFont, bForeground );
2122 
2123     if ( bBackground )
2124     {
2125         Window* pParent = GetParent();
2126         if ( !IsControlBackground() &&
2127             (pParent->IsChildTransparentModeEnabled() || IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) ) )
2128         {
2129             EnableChildTransparentMode( sal_True );
2130             SetParentClipMode( PARENTCLIPMODE_NOCLIP );
2131             SetPaintTransparent( sal_True );
2132             SetBackground();
2133             if( IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) )
2134                 mpWindowImpl->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects;
2135         }
2136         else
2137         {
2138             EnableChildTransparentMode( sal_False );
2139             SetParentClipMode( 0 );
2140             SetPaintTransparent( sal_False );
2141 
2142             if ( IsControlBackground() )
2143                 SetBackground( GetControlBackground() );
2144             else
2145                 SetBackground( pParent->GetBackground() );
2146         }
2147     }
2148 }
2149 
2150 //---------------------------------------------------------------------
2151 //--- 12.03.2003 18:46:14 ---------------------------------------------
2152 
2153 void RadioButton::DrawRadioButtonState( )
2154 {
2155 	ImplDrawRadioButtonState( );
2156 }
2157 
2158 // -----------------------------------------------------------------------
2159 
2160 void RadioButton::ImplInvalidateOrDrawRadioButtonState()
2161 {
2162     if( ImplGetSVData()->maNWFData.mbCheckBoxNeedsErase )
2163     {
2164         if ( IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL) )
2165         {
2166             Invalidate();
2167             Update();
2168             return;
2169         }
2170     }
2171     ImplDrawRadioButtonState();
2172 }
2173 
2174 void RadioButton::ImplDrawRadioButtonState()
2175 {
2176     sal_uInt16 nButtonStyle = 0;
2177     sal_Bool   bNativeOK = sal_False;
2178 
2179     // no native drawing for image radio buttons
2180     if ( !maImage && (bNativeOK=IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL)) == sal_True )
2181     {
2182         ImplControlValue		    aControlValue( mbChecked ? BUTTONVALUE_ON : BUTTONVALUE_OFF );
2183         Rectangle					aCtrlRect( maStateRect.TopLeft(), maStateRect.GetSize() );
2184         ControlState				nState = 0;
2185 
2186         if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )	nState |= CTRL_STATE_PRESSED;
2187         if ( HasFocus() ) 						nState |= CTRL_STATE_FOCUSED;
2188         if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT )	nState |= CTRL_STATE_DEFAULT;
2189         if ( IsEnabled() )						nState |= CTRL_STATE_ENABLED;
2190 
2191         if ( IsMouseOver() && maMouseRect.IsInside( GetPointerPosPixel() ) )
2192             nState |= CTRL_STATE_ROLLOVER;
2193 
2194         bNativeOK = DrawNativeControl( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRect, nState,
2195                     aControlValue,rtl::OUString() );
2196 
2197     }
2198 
2199 if ( bNativeOK == sal_False )
2200 {
2201     // kein Image-RadioButton
2202     if ( !maImage )
2203     {
2204         sal_uInt16 nStyle = ImplGetButtonState();
2205         if ( !IsEnabled() )
2206             nStyle |= BUTTON_DRAW_DISABLED;
2207         if ( mbChecked )
2208             nStyle |= BUTTON_DRAW_CHECKED;
2209         Image aImage = GetRadioImage( GetSettings(), nStyle );
2210         if ( IsZoom() )
2211             DrawImage( maStateRect.TopLeft(), maStateRect.GetSize(), aImage );
2212         else
2213             DrawImage( maStateRect.TopLeft(), aImage );
2214     }
2215     else
2216     {
2217         HideFocus();
2218 
2219         DecorationView          aDecoView( this );
2220         const StyleSettings&    rStyleSettings = GetSettings().GetStyleSettings();
2221         Rectangle               aImageRect  = maStateRect;
2222         Size                    aImageSize  = maImage.GetSizePixel();
2223         sal_Bool                    bEnabled    = IsEnabled();
2224 
2225         aImageSize.Width()  = CalcZoom( aImageSize.Width() );
2226         aImageSize.Height() = CalcZoom( aImageSize.Height() );
2227 
2228         // Border und Selektionsstatus ausgeben
2229         nButtonStyle = FRAME_DRAW_DOUBLEIN;
2230         aImageRect = aDecoView.DrawFrame( aImageRect, nButtonStyle );
2231         if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) || !bEnabled )
2232             SetFillColor( rStyleSettings.GetFaceColor() );
2233         else
2234             SetFillColor( rStyleSettings.GetFieldColor() );
2235         SetLineColor();
2236         DrawRect( aImageRect );
2237 
2238         // Image ausgeben
2239         nButtonStyle = 0;
2240         if ( !bEnabled )
2241             nButtonStyle |= IMAGE_DRAW_DISABLE;
2242 
2243 		// check for HC mode
2244 		Image *pImage = &maImage;
2245 		if( !!maImageHC )
2246 		{
2247 			if( rStyleSettings.GetHighContrastMode() )
2248 				pImage = &maImageHC;
2249 		}
2250 
2251         Point aImagePos( aImageRect.TopLeft() );
2252         aImagePos.X() += (aImageRect.GetWidth()-aImageSize.Width())/2;
2253         aImagePos.Y() += (aImageRect.GetHeight()-aImageSize.Height())/2;
2254         if ( IsZoom() )
2255             DrawImage( aImagePos, aImageSize, *pImage, nButtonStyle );
2256         else
2257             DrawImage( aImagePos, *pImage, nButtonStyle );
2258 
2259         aImageRect.Left()++;
2260         aImageRect.Top()++;
2261         aImageRect.Right()--;
2262         aImageRect.Bottom()--;
2263 
2264         ImplSetFocusRect( aImageRect );
2265 
2266         if ( mbChecked )
2267         {
2268             SetLineColor( rStyleSettings.GetHighlightColor() );
2269             SetFillColor();
2270             if ( (aImageSize.Width() >= 20) || (aImageSize.Height() >= 20) )
2271             {
2272                 aImageRect.Left()++;
2273                 aImageRect.Top()++;
2274                 aImageRect.Right()--;
2275                 aImageRect.Bottom()--;
2276             }
2277             DrawRect( aImageRect );
2278             aImageRect.Left()++;
2279             aImageRect.Top()++;
2280             aImageRect.Right()--;
2281             aImageRect.Bottom()--;
2282             DrawRect( aImageRect );
2283         }
2284 
2285         if ( HasFocus() )
2286             ShowFocus( ImplGetFocusRect() );
2287     }
2288 }
2289 }
2290 
2291 // -----------------------------------------------------------------------
2292 
2293 void RadioButton::ImplDraw( OutputDevice* pDev, sal_uLong nDrawFlags,
2294                             const Point& rPos, const Size& rSize,
2295                             const Size& rImageSize, Rectangle& rStateRect,
2296                             Rectangle& rMouseRect, bool bLayout )
2297 {
2298     WinBits                 nWinStyle = GetStyle();
2299     XubString               aText( GetText() );
2300     Rectangle               aRect( rPos, rSize );
2301     MetricVector*			pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL;
2302     String*					pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL;
2303 
2304     pDev->Push( PUSH_CLIPREGION );
2305     pDev->IntersectClipRegion( Rectangle( rPos, rSize ) );
2306 
2307     // kein Image-RadioButton
2308     if ( !maImage )
2309     {
2310         if ( ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) ||
2311              ( HasImage() &&  ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) ) )
2312         {
2313             sal_uInt16 nTextStyle = Button::ImplGetTextStyle( aText, nWinStyle, nDrawFlags );
2314 
2315             const long nImageSep = GetDrawPixel( pDev, ImplGetImageToTextDistance() );
2316             Size aSize( rSize );
2317             Point aPos( rPos );
2318             aPos.X() += rImageSize.Width() + nImageSep;
2319             aSize.Width() -= rImageSize.Width() + nImageSep;
2320 
2321             // if the text rect height is smaller than the height of the image
2322             // then for single lines the default should be centered text
2323             if( (nWinStyle & (WB_TOP|WB_VCENTER|WB_BOTTOM)) == 0 &&
2324                 (rImageSize.Height() > rSize.Height() || ! (nWinStyle & WB_WORDBREAK)  ) )
2325             {
2326                 nTextStyle &= ~(TEXT_DRAW_TOP|TEXT_DRAW_BOTTOM);
2327                 nTextStyle |= TEXT_DRAW_VCENTER;
2328                 aSize.Height() = rImageSize.Height();
2329             }
2330 
2331             ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, 1,
2332                                   nDrawFlags, nTextStyle, NULL );
2333 
2334             rMouseRect          = Rectangle( aPos, aSize );
2335             rMouseRect.Left()   = rPos.X();
2336 
2337             rStateRect.Left()   = rPos.X();
2338             rStateRect.Top()    = rMouseRect.Top();
2339 
2340             if ( aSize.Height() > rImageSize.Height() )
2341                 rStateRect.Top() += ( aSize.Height() - rImageSize.Height() ) / 2;
2342             else
2343             {
2344                 rStateRect.Top() -= ( rImageSize.Height() - aSize.Height() ) / 2;
2345                 if( rStateRect.Top() < 0 )
2346                     rStateRect.Top() = 0;
2347             }
2348 
2349             rStateRect.Right()  = rStateRect.Left() + rImageSize.Width()-1;
2350             rStateRect.Bottom() = rStateRect.Top() + rImageSize.Height()-1;
2351 
2352             if ( rStateRect.Bottom() > rMouseRect.Bottom() )
2353                 rMouseRect.Bottom() = rStateRect.Bottom();
2354         }
2355         else
2356         {
2357             if ( nWinStyle & WB_CENTER )
2358                 rStateRect.Left() = rPos.X()+((rSize.Width()-rImageSize.Width())/2);
2359             else if ( nWinStyle & WB_RIGHT )
2360                 rStateRect.Left() = rPos.X()+rSize.Width()-rImageSize.Width(); //-1;
2361             else
2362                 rStateRect.Left() = rPos.X(); //+1;
2363             if ( nWinStyle & WB_VCENTER )
2364                 rStateRect.Top() = rPos.Y()+((rSize.Height()-rImageSize.Height())/2);
2365             else if ( nWinStyle & WB_BOTTOM )
2366                 rStateRect.Top() = rPos.Y()+rSize.Height()-rImageSize.Height(); //-1;
2367             else
2368                 rStateRect.Top() = rPos.Y(); //+1;
2369             rStateRect.Right()  = rStateRect.Left()+rImageSize.Width()-1;
2370             rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1;
2371             rMouseRect          = rStateRect;
2372 
2373             ImplSetFocusRect( rStateRect );
2374 
2375 /*  und oben -1, da CalcSize() auch Focus-Rechteck nicht mit einrechnet,
2376 da im Writer ansonsten die Images noch weiter oben haengen
2377             rFocusRect          = rStateRect;
2378             rFocusRect.Left()--;
2379             rFocusRect.Top()--;
2380             rFocusRect.Right()++;
2381             rFocusRect.Bottom()++;
2382 */
2383         }
2384     }
2385     else
2386     {
2387         sal_Bool        bTopImage   = (nWinStyle & WB_TOP) != 0;
2388         Size        aImageSize  = maImage.GetSizePixel();
2389         Rectangle   aImageRect( rPos, rSize );
2390         long        nTextHeight = pDev->GetTextHeight();
2391         long        nTextWidth  = pDev->GetCtrlTextWidth( aText );
2392 
2393         // Positionen und Groessen berechnen
2394         if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
2395         {
2396             Size aTmpSize( (aImageSize.Width()+8), (aImageSize.Height()+8) );
2397             if ( bTopImage )
2398             {
2399                 aImageRect.Left() = (rSize.Width()-aTmpSize.Width())/2;
2400                 aImageRect.Top()  = (rSize.Height()-(aTmpSize.Height()+nTextHeight+6))/2;
2401             }
2402             else
2403                 aImageRect.Top()  = (rSize.Height()-aTmpSize.Height())/2;
2404 
2405             aImageRect.Right()  = aImageRect.Left()+aTmpSize.Width();
2406             aImageRect.Bottom() = aImageRect.Top()+aTmpSize.Height();
2407 
2408             // Text ausgeben
2409             Point aTxtPos = rPos;
2410             if ( bTopImage )
2411             {
2412                 aTxtPos.X() += (rSize.Width()-nTextWidth)/2;
2413                 aTxtPos.Y() += aImageRect.Bottom()+6;
2414             }
2415             else
2416             {
2417                 aTxtPos.X() += aImageRect.Right()+8;
2418                 aTxtPos.Y() += (rSize.Height()-nTextHeight)/2;
2419             }
2420             pDev->DrawCtrlText( aTxtPos, aText, 0, STRING_LEN, TEXT_DRAW_MNEMONIC, pVector, pDisplayText );
2421         }
2422 
2423         rMouseRect = aImageRect;
2424         rStateRect = aImageRect;
2425     }
2426 
2427     pDev->Pop();
2428 }
2429 
2430 // -----------------------------------------------------------------------
2431 
2432 void RadioButton::ImplDrawRadioButton( bool bLayout )
2433 {
2434     if( !bLayout )
2435         HideFocus();
2436 
2437     Size aImageSize;
2438     if ( !maImage )
2439         aImageSize = ImplGetRadioImageSize();
2440     else
2441         aImageSize  = maImage.GetSizePixel();
2442     aImageSize.Width()  = CalcZoom( aImageSize.Width() );
2443     aImageSize.Height() = CalcZoom( aImageSize.Height() );
2444 
2445     // Draw control text
2446     ImplDraw( this, 0, Point(), GetOutputSizePixel(),
2447               aImageSize, maStateRect, maMouseRect, bLayout );
2448 
2449     if( !bLayout || (IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL)==sal_True) )
2450     {
2451         if ( !maImage && HasFocus() )
2452             ShowFocus( ImplGetFocusRect() );
2453 
2454         ImplDrawRadioButtonState();
2455     }
2456 }
2457 
2458 // -----------------------------------------------------------------------
2459 
2460 void RadioButton::GetRadioButtonGroup( std::vector< RadioButton* >& io_rGroup, bool bIncludeThis ) const
2461 {
2462     // empty the list
2463     io_rGroup.clear();
2464 
2465     // go back to first in group;
2466     Window* pFirst = const_cast<RadioButton*>(this);
2467     while( ( pFirst->GetStyle() & WB_GROUP ) == 0 )
2468     {
2469         Window* pWindow = pFirst->GetWindow( WINDOW_PREV );
2470         if( pWindow )
2471             pFirst = pWindow;
2472         else
2473             break;
2474     }
2475     // insert radiobuttons up to next group
2476     do
2477     {
2478         if( pFirst->GetType() == WINDOW_RADIOBUTTON )
2479         {
2480             if( pFirst != this || bIncludeThis )
2481                 io_rGroup.push_back( static_cast<RadioButton*>(pFirst) );
2482         }
2483         pFirst = pFirst->GetWindow( WINDOW_NEXT );
2484     } while( pFirst && ( ( pFirst->GetStyle() & WB_GROUP ) == 0 ) );
2485 }
2486 
2487 // -----------------------------------------------------------------------
2488 
2489 void RadioButton::ImplUncheckAllOther()
2490 {
2491     mpWindowImpl->mnStyle |= WB_TABSTOP;
2492 
2493     // Gruppe mit RadioButtons durchgehen und die gecheckten Buttons
2494     Window* pWindow;
2495     WinBits nStyle;
2496     if ( !(GetStyle() & WB_GROUP) )
2497     {
2498         pWindow = GetWindow( WINDOW_PREV );
2499         while ( pWindow )
2500         {
2501             nStyle = pWindow->GetStyle();
2502 
2503             if ( pWindow->GetType() == WINDOW_RADIOBUTTON )
2504             {
2505                 if ( ((RadioButton*)pWindow)->IsChecked() )
2506                 {
2507                     ImplDelData aDelData;
2508                     pWindow->ImplAddDel( &aDelData );
2509                     ((RadioButton*)pWindow)->SetState( sal_False );
2510                     if ( aDelData.IsDelete() )
2511                         return;
2512                     pWindow->ImplRemoveDel( &aDelData );
2513                 }
2514                 // Um falsch gesetzt WB_TABSTOPS immer zu entfernen, nicht
2515                 // innerhalb der if-Abfrage
2516                 pWindow->mpWindowImpl->mnStyle &= ~WB_TABSTOP;
2517             }
2518 
2519             if ( nStyle & WB_GROUP )
2520                 break;
2521 
2522             pWindow = pWindow->GetWindow( WINDOW_PREV );
2523         }
2524     }
2525 
2526     pWindow = GetWindow( WINDOW_NEXT );
2527     while ( pWindow )
2528     {
2529         nStyle = pWindow->GetStyle();
2530 
2531         if ( nStyle & WB_GROUP )
2532             break;
2533 
2534         if ( pWindow->GetType() == WINDOW_RADIOBUTTON )
2535         {
2536             if ( ((RadioButton*)pWindow)->IsChecked() )
2537             {
2538                 ImplDelData aDelData;
2539                 pWindow->ImplAddDel( &aDelData );
2540                 ((RadioButton*)pWindow)->SetState( sal_False );
2541                 if ( aDelData.IsDelete() )
2542                     return;
2543                 pWindow->ImplRemoveDel( &aDelData );
2544             }
2545             // Um falsch gesetzt WB_TABSTOPS immer zu entfernen, nicht
2546             // innerhalb der if-Abfrage
2547             pWindow->mpWindowImpl->mnStyle &= ~WB_TABSTOP;
2548         }
2549 
2550         pWindow = pWindow->GetWindow( WINDOW_NEXT );
2551     }
2552 }
2553 
2554 // -----------------------------------------------------------------------
2555 
2556 void RadioButton::ImplCallClick( sal_Bool bGrabFocus, sal_uInt16 nFocusFlags )
2557 {
2558     mbStateChanged = !mbChecked;
2559     mbChecked = sal_True;
2560     mpWindowImpl->mnStyle |= WB_TABSTOP;
2561     ImplInvalidateOrDrawRadioButtonState();
2562     ImplDelData aDelData;
2563     ImplAddDel( &aDelData );
2564     if ( mbRadioCheck )
2565         ImplUncheckAllOther();
2566     if ( aDelData.IsDelete() )
2567         return;
2568     if ( bGrabFocus )
2569         ImplGrabFocus( nFocusFlags );
2570     if ( aDelData.IsDelete() )
2571         return;
2572     if ( mbStateChanged )
2573         Toggle();
2574     if ( aDelData.IsDelete() )
2575         return;
2576     Click();
2577     if ( aDelData.IsDelete() )
2578         return;
2579     ImplRemoveDel( &aDelData );
2580     mbStateChanged = sal_False;
2581 }
2582 
2583 // -----------------------------------------------------------------------
2584 
2585 RadioButton::RadioButton( Window* pParent, WinBits nStyle ) :
2586     Button( WINDOW_RADIOBUTTON )
2587 {
2588     ImplInitRadioButtonData();
2589     ImplInit( pParent, nStyle );
2590 }
2591 
2592 // -----------------------------------------------------------------------
2593 
2594 RadioButton::RadioButton( Window* pParent, const ResId& rResId ) :
2595     Button( WINDOW_RADIOBUTTON )
2596 {
2597     ImplInitRadioButtonData();
2598     rResId.SetRT( RSC_RADIOBUTTON );
2599     WinBits nStyle = ImplInitRes( rResId );
2600     ImplInit( pParent, nStyle );
2601     ImplLoadRes( rResId );
2602 
2603     if ( !(nStyle & WB_HIDE) )
2604         Show();
2605 }
2606 
2607 // -----------------------------------------------------------------------
2608 
2609 void RadioButton::ImplLoadRes( const ResId& rResId )
2610 {
2611     Button::ImplLoadRes( rResId );
2612 
2613     //anderer Wert als Default ?
2614     sal_uInt16 nChecked = ReadShortRes();
2615     if ( nChecked )
2616         SetState( sal_True );
2617 }
2618 
2619 // -----------------------------------------------------------------------
2620 
2621 RadioButton::~RadioButton()
2622 {
2623 }
2624 
2625 // -----------------------------------------------------------------------
2626 
2627 void RadioButton::MouseButtonDown( const MouseEvent& rMEvt )
2628 {
2629     if ( rMEvt.IsLeft() && maMouseRect.IsInside( rMEvt.GetPosPixel() ) )
2630     {
2631         ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
2632         ImplInvalidateOrDrawRadioButtonState();
2633         StartTracking();
2634         return;
2635     }
2636 
2637     Button::MouseButtonDown( rMEvt );
2638 }
2639 
2640 // -----------------------------------------------------------------------
2641 
2642 void RadioButton::Tracking( const TrackingEvent& rTEvt )
2643 {
2644     if ( rTEvt.IsTrackingEnded() )
2645     {
2646         if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
2647         {
2648             if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
2649                 GrabFocus();
2650 
2651             ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
2652 
2653             // Bei Abbruch kein Click-Handler rufen
2654             if ( !rTEvt.IsTrackingCanceled() )
2655                 ImplCallClick();
2656             else
2657                 ImplInvalidateOrDrawRadioButtonState();
2658         }
2659     }
2660     else
2661     {
2662         if ( maMouseRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() ) )
2663         {
2664             if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
2665             {
2666                 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
2667                 ImplInvalidateOrDrawRadioButtonState();
2668             }
2669         }
2670         else
2671         {
2672             if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
2673             {
2674                 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
2675                 ImplInvalidateOrDrawRadioButtonState();
2676             }
2677         }
2678     }
2679 }
2680 
2681 // -----------------------------------------------------------------------
2682 
2683 void RadioButton::KeyInput( const KeyEvent& rKEvt )
2684 {
2685     KeyCode aKeyCode = rKEvt.GetKeyCode();
2686 
2687     if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) )
2688     {
2689         if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
2690         {
2691             ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
2692             ImplInvalidateOrDrawRadioButtonState();
2693         }
2694     }
2695     else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) )
2696     {
2697         ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
2698         ImplInvalidateOrDrawRadioButtonState();
2699     }
2700     else
2701         Button::KeyInput( rKEvt );
2702 }
2703 
2704 // -----------------------------------------------------------------------
2705 
2706 void RadioButton::KeyUp( const KeyEvent& rKEvt )
2707 {
2708     KeyCode aKeyCode = rKEvt.GetKeyCode();
2709 
2710     if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_SPACE) )
2711     {
2712         ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
2713         ImplCallClick();
2714     }
2715     else
2716         Button::KeyUp( rKEvt );
2717 }
2718 
2719 // -----------------------------------------------------------------------
2720 
2721 void RadioButton::FillLayoutData() const
2722 {
2723     mpControlData->mpLayoutData = new vcl::ControlLayoutData();
2724     const_cast<RadioButton*>(this)->ImplDrawRadioButton( true );
2725 }
2726 
2727 // -----------------------------------------------------------------------
2728 
2729 void RadioButton::Paint( const Rectangle& )
2730 {
2731     ImplDrawRadioButton();
2732 }
2733 
2734 // -----------------------------------------------------------------------
2735 
2736 void RadioButton::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
2737                         sal_uLong nFlags )
2738 {
2739     if ( !maImage )
2740     {
2741         MapMode     aResMapMode( MAP_100TH_MM );
2742         Point       aPos  = pDev->LogicToPixel( rPos );
2743         Size        aSize = pDev->LogicToPixel( rSize );
2744         Size        aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode );
2745         Size        aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode );
2746         Size        aBrd2Size = pDev->LogicToPixel( Size( 60, 60 ), aResMapMode );
2747         Font        aFont = GetDrawPixelFont( pDev );
2748         Rectangle   aStateRect;
2749         Rectangle   aMouseRect;
2750         Rectangle   aFocusRect;
2751 
2752         aImageSize.Width()  = CalcZoom( aImageSize.Width() );
2753         aImageSize.Height() = CalcZoom( aImageSize.Height() );
2754         aBrd1Size.Width()   = CalcZoom( aBrd1Size.Width() );
2755         aBrd1Size.Height()  = CalcZoom( aBrd1Size.Height() );
2756         aBrd2Size.Width()   = CalcZoom( aBrd2Size.Width() );
2757         aBrd2Size.Height()  = CalcZoom( aBrd2Size.Height() );
2758 
2759         if ( !aBrd1Size.Width() )
2760             aBrd1Size.Width() = 1;
2761         if ( !aBrd1Size.Height() )
2762             aBrd1Size.Height() = 1;
2763         if ( !aBrd2Size.Width() )
2764             aBrd2Size.Width() = 1;
2765         if ( !aBrd2Size.Height() )
2766             aBrd2Size.Height() = 1;
2767 
2768         pDev->Push();
2769         pDev->SetMapMode();
2770         pDev->SetFont( aFont );
2771         if ( nFlags & WINDOW_DRAW_MONO )
2772             pDev->SetTextColor( Color( COL_BLACK ) );
2773         else
2774             pDev->SetTextColor( GetTextColor() );
2775         pDev->SetTextFillColor();
2776 
2777         ImplDraw( pDev, nFlags, aPos, aSize,
2778                   aImageSize, aStateRect, aMouseRect );
2779 
2780         Point   aCenterPos = aStateRect.Center();
2781         long    nRadX = aImageSize.Width()/2;
2782         long    nRadY = aImageSize.Height()/2;
2783 
2784         pDev->SetLineColor();
2785         pDev->SetFillColor( Color( COL_BLACK ) );
2786         pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) );
2787         nRadX -= aBrd1Size.Width();
2788         nRadY -= aBrd1Size.Height();
2789         pDev->SetFillColor( Color( COL_WHITE ) );
2790         pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) );
2791         if ( mbChecked )
2792         {
2793             nRadX -= aBrd1Size.Width();
2794             nRadY -= aBrd1Size.Height();
2795             if ( !nRadX )
2796                 nRadX = 1;
2797             if ( !nRadY )
2798                 nRadY = 1;
2799             pDev->SetFillColor( Color( COL_BLACK ) );
2800             pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) );
2801         }
2802 
2803         pDev->Pop();
2804     }
2805     else
2806     {
2807         DBG_ERROR( "RadioButton::Draw() - not implemented for RadioButton with Image" );
2808     }
2809 }
2810 
2811 // -----------------------------------------------------------------------
2812 
2813 void RadioButton::Resize()
2814 {
2815     Control::Resize();
2816     Invalidate();
2817 }
2818 
2819 // -----------------------------------------------------------------------
2820 
2821 void RadioButton::GetFocus()
2822 {
2823     ShowFocus( ImplGetFocusRect() );
2824     SetInputContext( InputContext( GetFont() ) );
2825     Button::GetFocus();
2826 }
2827 
2828 // -----------------------------------------------------------------------
2829 
2830 void RadioButton::LoseFocus()
2831 {
2832     if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
2833     {
2834         ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
2835         ImplInvalidateOrDrawRadioButtonState();
2836     }
2837 
2838     HideFocus();
2839     Button::LoseFocus();
2840 }
2841 
2842 // -----------------------------------------------------------------------
2843 
2844 void RadioButton::StateChanged( StateChangedType nType )
2845 {
2846     Button::StateChanged( nType );
2847 
2848     if ( nType == STATE_CHANGE_STATE )
2849     {
2850         if ( IsReallyVisible() && IsUpdateMode() )
2851             Invalidate( maStateRect );
2852     }
2853     else if ( (nType == STATE_CHANGE_ENABLE) ||
2854               (nType == STATE_CHANGE_TEXT) ||
2855               (nType == STATE_CHANGE_IMAGE) ||
2856               (nType == STATE_CHANGE_DATA) ||
2857               (nType == STATE_CHANGE_UPDATEMODE) )
2858     {
2859         if ( IsUpdateMode() )
2860             Invalidate();
2861     }
2862     else if ( nType == STATE_CHANGE_STYLE )
2863     {
2864         SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) );
2865 
2866         if ( (GetPrevStyle() & RADIOBUTTON_VIEW_STYLE) !=
2867              (GetStyle() & RADIOBUTTON_VIEW_STYLE) )
2868         {
2869             if ( IsUpdateMode() )
2870                 Invalidate();
2871         }
2872     }
2873     else if ( (nType == STATE_CHANGE_ZOOM) ||
2874               (nType == STATE_CHANGE_CONTROLFONT) )
2875     {
2876         ImplInitSettings( sal_True, sal_False, sal_False );
2877         Invalidate();
2878     }
2879     else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
2880     {
2881         ImplInitSettings( sal_False, sal_True, sal_False );
2882         Invalidate();
2883     }
2884     else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
2885     {
2886         ImplInitSettings( sal_False, sal_False, sal_True );
2887         Invalidate();
2888     }
2889 }
2890 
2891 // -----------------------------------------------------------------------
2892 
2893 void RadioButton::DataChanged( const DataChangedEvent& rDCEvt )
2894 {
2895     Button::DataChanged( rDCEvt );
2896 
2897     if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
2898          (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
2899          ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
2900           (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
2901     {
2902         ImplInitSettings( sal_True, sal_True, sal_True );
2903         Invalidate();
2904     }
2905 }
2906 
2907 // -----------------------------------------------------------------------
2908 
2909 long RadioButton::PreNotify( NotifyEvent& rNEvt )
2910 {
2911     long nDone = 0;
2912     const MouseEvent* pMouseEvt = NULL;
2913 
2914     if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
2915     {
2916         if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
2917         {
2918             // trigger redraw if mouse over state has changed
2919             if( IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL) )
2920             {
2921                 if( ( maMouseRect.IsInside( GetPointerPosPixel()) &&
2922                      !maMouseRect.IsInside( GetLastPointerPosPixel()) ) ||
2923                     ( maMouseRect.IsInside( GetLastPointerPosPixel()) &&
2924                      !maMouseRect.IsInside( GetPointerPosPixel()) ) ||
2925                      pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow() )
2926                 {
2927                     Invalidate( maStateRect );
2928                 }
2929             }
2930         }
2931     }
2932 
2933     return nDone ? nDone : Button::PreNotify(rNEvt);
2934 }
2935 
2936 // -----------------------------------------------------------------------
2937 
2938 void RadioButton::Toggle()
2939 {
2940     ImplCallEventListenersAndHandler( VCLEVENT_RADIOBUTTON_TOGGLE, maToggleHdl, this );
2941 }
2942 
2943 // -----------------------------------------------------------------------
2944 
2945 sal_Bool RadioButton::SetModeRadioImage( const Image& rImage, BmpColorMode eMode )
2946 {
2947     if( eMode == BMP_COLOR_NORMAL )
2948 {
2949     if ( rImage != maImage )
2950     {
2951         maImage = rImage;
2952         StateChanged( STATE_CHANGE_DATA );
2953     }
2954 }
2955     else if( eMode == BMP_COLOR_HIGHCONTRAST )
2956     {
2957 		if( maImageHC != rImage )
2958 		{
2959 			maImageHC = rImage;
2960 			StateChanged( STATE_CHANGE_DATA );
2961 		}
2962     }
2963     else
2964         return sal_False;
2965 
2966     return sal_True;
2967 }
2968 
2969 // -----------------------------------------------------------------------
2970 
2971 const Image& RadioButton::GetModeRadioImage( BmpColorMode eMode ) const
2972 {
2973     if( eMode == BMP_COLOR_HIGHCONTRAST )
2974         return maImageHC;
2975     else
2976         return maImage;
2977 }
2978 
2979 // -----------------------------------------------------------------------
2980 
2981 void RadioButton::SetState( sal_Bool bCheck )
2982 {
2983     // TabStop-Flag richtig mitfuehren
2984     if ( bCheck )
2985         mpWindowImpl->mnStyle |= WB_TABSTOP;
2986     else
2987         mpWindowImpl->mnStyle &= ~WB_TABSTOP;
2988 
2989     if ( mbChecked != bCheck )
2990     {
2991         mbChecked = bCheck;
2992         StateChanged( STATE_CHANGE_STATE );
2993         Toggle();
2994     }
2995 }
2996 
2997 // -----------------------------------------------------------------------
2998 
2999 void RadioButton::Check( sal_Bool bCheck )
3000 {
3001     // TabStop-Flag richtig mitfuehren
3002     if ( bCheck )
3003         mpWindowImpl->mnStyle |= WB_TABSTOP;
3004     else
3005         mpWindowImpl->mnStyle &= ~WB_TABSTOP;
3006 
3007     if ( mbChecked != bCheck )
3008     {
3009         mbChecked = bCheck;
3010         ImplDelData aDelData;
3011         ImplAddDel( &aDelData );
3012         StateChanged( STATE_CHANGE_STATE );
3013         if ( aDelData.IsDelete() )
3014             return;
3015         if ( bCheck && mbRadioCheck )
3016             ImplUncheckAllOther();
3017         if ( aDelData.IsDelete() )
3018             return;
3019         Toggle();
3020         ImplRemoveDel( &aDelData );
3021     }
3022 }
3023 
3024 // -----------------------------------------------------------------------
3025 
3026 long RadioButton::ImplGetImageToTextDistance() const
3027 {
3028     // 4 pixels, but take zoom into account, so the text doesn't "jump" relative to surrounding elements,
3029     // which might have been aligned with the text of the check box
3030     return CalcZoom( 4 );
3031 }
3032 
3033 // -----------------------------------------------------------------------
3034 
3035 Size RadioButton::ImplGetRadioImageSize() const
3036 {
3037     Size aSize;
3038     // why are IsNativeControlSupported and GetNativeControlRegion not const ?
3039     RadioButton* pThis = const_cast<RadioButton*>(this);
3040     bool bDefaultSize = true;
3041     if( pThis->IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) )
3042     {
3043         ImplControlValue aControlValue;
3044         // #i45896# workaround gcc3.3 temporary problem
3045         Rectangle		 aCtrlRegion( Point( 0, 0 ), GetSizePixel() );
3046         ControlState	 nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED;
3047         Rectangle aBoundingRgn, aContentRgn;
3048 
3049         // get native size of a radio button
3050         if( pThis->GetNativeControlRegion( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion,
3051                                            nState, aControlValue, rtl::OUString(),
3052                                            aBoundingRgn, aContentRgn ) )
3053         {
3054             aSize = aContentRgn.GetSize();
3055             bDefaultSize = false;
3056         }
3057     }
3058     if( bDefaultSize )
3059         aSize = GetRadioImage( GetSettings(), 0 ).GetSizePixel();
3060     return aSize;
3061 }
3062 
3063 static void LoadThemedImageList (const StyleSettings &rStyleSettings,
3064 								 ImageList *pList, const ResId &rResId,
3065                                  sal_uInt16 nImages)
3066 {
3067 	Color aColorAry1[6];
3068 	Color aColorAry2[6];
3069 	aColorAry1[0] = Color( 0xC0, 0xC0, 0xC0 );
3070 	aColorAry1[1] = Color( 0xFF, 0xFF, 0x00 );
3071 	aColorAry1[2] = Color( 0xFF, 0xFF, 0xFF );
3072 	aColorAry1[3] = Color( 0x80, 0x80, 0x80 );
3073 	aColorAry1[4] = Color( 0x00, 0x00, 0x00 );
3074 	aColorAry1[5] = Color( 0x00, 0xFF, 0x00 );
3075 	aColorAry2[0] = rStyleSettings.GetFaceColor();
3076 	aColorAry2[1] = rStyleSettings.GetWindowColor();
3077 	aColorAry2[2] = rStyleSettings.GetLightColor();
3078 	aColorAry2[3] = rStyleSettings.GetShadowColor();
3079 	aColorAry2[4] = rStyleSettings.GetDarkShadowColor();
3080 	aColorAry2[5] = rStyleSettings.GetWindowTextColor();
3081 
3082 	Color aMaskColor(0x00, 0x00, 0xFF );
3083         DBG_ASSERT( sizeof(aColorAry1) == sizeof(aColorAry2), "aColorAry1 must match aColorAry2" );
3084 	// FIXME: do we want the mask for the checkbox ?
3085 	pList->InsertFromHorizontalBitmap (rResId, nImages, &aMaskColor,
3086         aColorAry1, aColorAry2, sizeof(aColorAry1) / sizeof(Color));
3087 }
3088 
3089 Image RadioButton::GetRadioImage( const AllSettings& rSettings, sal_uInt16 nFlags )
3090 {
3091     ImplSVData*             pSVData = ImplGetSVData();
3092     const StyleSettings&    rStyleSettings = rSettings.GetStyleSettings();
3093     sal_uInt16              nStyle = 0;
3094 
3095     if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
3096         nStyle = STYLE_RADIOBUTTON_MONO;
3097 
3098     if ( !pSVData->maCtrlData.mpRadioImgList ||
3099          (pSVData->maCtrlData.mnRadioStyle != nStyle) ||
3100          (pSVData->maCtrlData.mnLastRadioFColor != rStyleSettings.GetFaceColor().GetColor()) ||
3101          (pSVData->maCtrlData.mnLastRadioWColor != rStyleSettings.GetWindowColor().GetColor()) ||
3102          (pSVData->maCtrlData.mnLastRadioLColor != rStyleSettings.GetLightColor().GetColor()) )
3103     {
3104         if ( pSVData->maCtrlData.mpRadioImgList )
3105             delete pSVData->maCtrlData.mpRadioImgList;
3106 
3107         pSVData->maCtrlData.mnLastRadioFColor = rStyleSettings.GetFaceColor().GetColor();
3108         pSVData->maCtrlData.mnLastRadioWColor = rStyleSettings.GetWindowColor().GetColor();
3109         pSVData->maCtrlData.mnLastRadioLColor = rStyleSettings.GetLightColor().GetColor();
3110 
3111         Color pColorAry1[6];
3112         Color pColorAry2[6];
3113         pColorAry1[0] = Color( 0xC0, 0xC0, 0xC0 );
3114         pColorAry1[1] = Color( 0xFF, 0xFF, 0x00 );
3115         pColorAry1[2] = Color( 0xFF, 0xFF, 0xFF );
3116         pColorAry1[3] = Color( 0x80, 0x80, 0x80 );
3117         pColorAry1[4] = Color( 0x00, 0x00, 0x00 );
3118         pColorAry1[5] = Color( 0x00, 0xFF, 0x00 );
3119         pColorAry2[0] = rStyleSettings.GetFaceColor();
3120         pColorAry2[1] = rStyleSettings.GetWindowColor();
3121         pColorAry2[2] = rStyleSettings.GetLightColor();
3122         pColorAry2[3] = rStyleSettings.GetShadowColor();
3123         pColorAry2[4] = rStyleSettings.GetDarkShadowColor();
3124         pColorAry2[5] = rStyleSettings.GetWindowTextColor();
3125 
3126         ResMgr* pResMgr = ImplGetResMgr();
3127         pSVData->maCtrlData.mpRadioImgList = new ImageList();
3128         if( pResMgr )
3129 	    LoadThemedImageList( rStyleSettings,
3130 				 pSVData->maCtrlData.mpRadioImgList,
3131 				 ResId( SV_RESID_BITMAP_RADIO+nStyle, *pResMgr ), 6 );
3132 	pSVData->maCtrlData.mnRadioStyle = nStyle;
3133     }
3134 
3135     sal_uInt16 nId;
3136     if ( nFlags & BUTTON_DRAW_DISABLED )
3137     {
3138         if ( nFlags & BUTTON_DRAW_CHECKED )
3139             nId = 6;
3140         else
3141             nId = 5;
3142     }
3143     else if ( nFlags & BUTTON_DRAW_PRESSED )
3144     {
3145         if ( nFlags & BUTTON_DRAW_CHECKED )
3146             nId = 4;
3147         else
3148             nId = 3;
3149     }
3150     else
3151     {
3152         if ( nFlags & BUTTON_DRAW_CHECKED )
3153             nId = 2;
3154         else
3155             nId = 1;
3156     }
3157     return pSVData->maCtrlData.mpRadioImgList->GetImage( nId );
3158 }
3159 
3160 // -----------------------------------------------------------------------
3161 
3162 void RadioButton::ImplSetMinimumNWFSize()
3163 {
3164     Push( PUSH_MAPMODE );
3165     SetMapMode( MAP_PIXEL );
3166 
3167     ImplControlValue aControlValue;
3168     Size aCurSize( GetSizePixel() );
3169     Rectangle aCtrlRegion( Point( 0, 0 ), aCurSize );
3170     Rectangle aBoundingRgn, aContentRgn;
3171 
3172     // get native size of a radiobutton
3173     if( GetNativeControlRegion( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion,
3174                                 CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED, aControlValue, rtl::OUString(),
3175                                 aBoundingRgn, aContentRgn ) )
3176     {
3177         Size aSize = aContentRgn.GetSize();
3178 
3179         if( aSize.Height() > aCurSize.Height() )
3180         {
3181             aCurSize.Height() = aSize.Height();
3182             SetSizePixel( aCurSize );
3183         }
3184     }
3185 
3186     Pop();
3187 }
3188 
3189 // -----------------------------------------------------------------------
3190 
3191 Size RadioButton::CalcMinimumSize( long nMaxWidth ) const
3192 {
3193     Size aSize;
3194     if ( !maImage )
3195         aSize = ImplGetRadioImageSize();
3196     else
3197         aSize = maImage.GetSizePixel();
3198 
3199     nMaxWidth -= aSize.Width();
3200 
3201     XubString aText = GetText();
3202     if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
3203     {
3204         // subtract what will be added later
3205         nMaxWidth-=2;
3206         nMaxWidth -= ImplGetImageToTextDistance();
3207 
3208         Size aTextSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
3209                                       aText, FixedText::ImplGetTextStyle( GetStyle() ) ).GetSize();
3210         aSize.Width()+=2;   // for focus rect
3211         aSize.Width() += ImplGetImageToTextDistance();
3212         aSize.Width() += aTextSize.Width();
3213         if ( aSize.Height() < aTextSize.Height() )
3214             aSize.Height() = aTextSize.Height();
3215     }
3216     else if ( !maImage )
3217     {
3218 /* da ansonsten im Writer die Control zu weit oben haengen
3219         aSize.Width() += 2;
3220         aSize.Height() += 2;
3221 */
3222     }
3223 
3224     return CalcWindowSize( aSize );
3225 }
3226 
3227 // -----------------------------------------------------------------------
3228 
3229 Size RadioButton::GetOptimalSize(WindowSizeType eType) const
3230 {
3231     switch (eType) {
3232     case WINDOWSIZE_MINIMUM:
3233         return CalcMinimumSize();
3234     default:
3235         return Button::GetOptimalSize( eType );
3236     }
3237 }
3238 
3239 // =======================================================================
3240 
3241 void CheckBox::ImplInitCheckBoxData()
3242 {
3243     meState         = STATE_NOCHECK;
3244     meSaveValue     = STATE_NOCHECK;
3245     mbTriState      = sal_False;
3246 }
3247 
3248 // -----------------------------------------------------------------------
3249 
3250 void CheckBox::ImplInit( Window* pParent, WinBits nStyle )
3251 {
3252     nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle );
3253     Button::ImplInit( pParent, nStyle, NULL );
3254 
3255     ImplInitSettings( sal_True, sal_True, sal_True );
3256 }
3257 
3258 // -----------------------------------------------------------------------
3259 
3260 WinBits CheckBox::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle )
3261 {
3262     if ( !(nStyle & WB_NOTABSTOP) )
3263         nStyle |= WB_TABSTOP;
3264     if ( !(nStyle & WB_NOGROUP) &&
3265          (!pPrevWindow || (pPrevWindow->GetType() != WINDOW_CHECKBOX)) )
3266         nStyle |= WB_GROUP;
3267     return nStyle;
3268 }
3269 
3270 // -----------------------------------------------------------------
3271 
3272 const Font& CheckBox::GetCanonicalFont( const StyleSettings& _rStyle ) const
3273 {
3274     return _rStyle.GetRadioCheckFont();
3275 }
3276 
3277 // -----------------------------------------------------------------
3278 const Color& CheckBox::GetCanonicalTextColor( const StyleSettings& _rStyle ) const
3279 {
3280     return _rStyle.GetRadioCheckTextColor();
3281 }
3282 
3283 // -----------------------------------------------------------------------
3284 
3285 void CheckBox::ImplInitSettings( sal_Bool bFont,
3286                                  sal_Bool bForeground, sal_Bool bBackground )
3287 {
3288     Button::ImplInitSettings( bFont, bForeground );
3289 
3290     if ( bBackground )
3291     {
3292         Window* pParent = GetParent();
3293         if ( !IsControlBackground() &&
3294             (pParent->IsChildTransparentModeEnabled() || IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) ) )
3295         {
3296             EnableChildTransparentMode( sal_True );
3297             SetParentClipMode( PARENTCLIPMODE_NOCLIP );
3298             SetPaintTransparent( sal_True );
3299             SetBackground();
3300             if( IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) )
3301                 ImplGetWindowImpl()->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects;
3302         }
3303         else
3304         {
3305             EnableChildTransparentMode( sal_False );
3306             SetParentClipMode( 0 );
3307             SetPaintTransparent( sal_False );
3308 
3309             if ( IsControlBackground() )
3310                 SetBackground( GetControlBackground() );
3311             else
3312                 SetBackground( pParent->GetBackground() );
3313         }
3314     }
3315 }
3316 
3317 // -----------------------------------------------------------------------
3318 
3319 void CheckBox::ImplLoadRes( const ResId& rResId )
3320 {
3321     Button::ImplLoadRes( rResId );
3322 
3323     if ( rResId.GetRT() != RSC_TRISTATEBOX )
3324     {
3325         sal_uInt16 nChecked = ReadShortRes();
3326         //anderer Wert als Default ?
3327         if( nChecked )
3328             Check( sal_True );
3329     }
3330 }
3331 
3332 // -----------------------------------------------------------------------
3333 
3334 void CheckBox::ImplInvalidateOrDrawCheckBoxState()
3335 {
3336     if( ImplGetSVData()->maNWFData.mbCheckBoxNeedsErase )
3337     {
3338         if ( IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL) )
3339         {
3340             Invalidate();
3341             Update();
3342             return;
3343         }
3344     }
3345     ImplDrawCheckBoxState();
3346 }
3347 
3348 void CheckBox::ImplDrawCheckBoxState()
3349 {
3350     bool	bNativeOK = sal_True;
3351 
3352     if ( (bNativeOK=IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL)) == sal_True )
3353     {
3354         ImplControlValue    aControlValue( meState == STATE_CHECK ? BUTTONVALUE_ON : BUTTONVALUE_OFF );
3355         Rectangle           aCtrlRegion( maStateRect );
3356         ControlState        nState = 0;
3357 
3358         if ( HasFocus() ) 						nState |= CTRL_STATE_FOCUSED;
3359         if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT )	nState |= CTRL_STATE_DEFAULT;
3360         if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )	nState |= CTRL_STATE_PRESSED;
3361         if ( IsEnabled() )						nState |= CTRL_STATE_ENABLED;
3362 
3363         if ( meState == STATE_CHECK )
3364             aControlValue.setTristateVal( BUTTONVALUE_ON );
3365         else if ( meState == STATE_DONTKNOW )
3366             aControlValue.setTristateVal( BUTTONVALUE_MIXED );
3367 
3368         if ( IsMouseOver() && maMouseRect.IsInside( GetPointerPosPixel() ) )
3369             nState |= CTRL_STATE_ROLLOVER;
3370 
3371         bNativeOK = DrawNativeControl( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion, nState,
3372 	     						aControlValue, rtl::OUString() );
3373     }
3374 
3375     if ( bNativeOK == sal_False )
3376     {
3377         sal_uInt16 nStyle = ImplGetButtonState();
3378         if ( !IsEnabled() )
3379             nStyle |= BUTTON_DRAW_DISABLED;
3380         if ( meState == STATE_DONTKNOW )
3381             nStyle |= BUTTON_DRAW_DONTKNOW;
3382         else if ( meState == STATE_CHECK )
3383             nStyle |= BUTTON_DRAW_CHECKED;
3384         Image aImage = GetCheckImage( GetSettings(), nStyle );
3385         if ( IsZoom() )
3386             DrawImage( maStateRect.TopLeft(), maStateRect.GetSize(), aImage );
3387         else
3388             DrawImage( maStateRect.TopLeft(), aImage );
3389     }
3390 }
3391 
3392 // -----------------------------------------------------------------------
3393 
3394 void CheckBox::ImplDraw( OutputDevice* pDev, sal_uLong nDrawFlags,
3395                          const Point& rPos, const Size& rSize,
3396                          const Size& rImageSize, Rectangle& rStateRect,
3397                          Rectangle& rMouseRect, bool bLayout )
3398 {
3399     WinBits                 nWinStyle = GetStyle();
3400     XubString               aText( GetText() );
3401 
3402     pDev->Push( PUSH_CLIPREGION | PUSH_LINECOLOR );
3403     pDev->IntersectClipRegion( Rectangle( rPos, rSize ) );
3404 
3405     long nLineY = rPos.Y() + (rSize.Height()-1)/2;
3406     if ( ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) ||
3407          ( HasImage() && !  (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) ) )
3408     {
3409         sal_uInt16 nTextStyle = Button::ImplGetTextStyle( aText, nWinStyle, nDrawFlags );
3410 
3411         const long nImageSep = GetDrawPixel( pDev, ImplGetImageToTextDistance() );
3412         Size aSize( rSize );
3413         Point aPos( rPos );
3414         aPos.X() += rImageSize.Width() + nImageSep;
3415         aSize.Width() -= rImageSize.Width() + nImageSep;
3416 
3417         // if the text rect height is smaller than the height of the image
3418         // then for single lines the default should be centered text
3419         if( (nWinStyle & (WB_TOP|WB_VCENTER|WB_BOTTOM)) == 0 &&
3420             (rImageSize.Height() > rSize.Height() || ! (nWinStyle & WB_WORDBREAK) ) )
3421         {
3422             nTextStyle &= ~(TEXT_DRAW_TOP|TEXT_DRAW_BOTTOM);
3423             nTextStyle |= TEXT_DRAW_VCENTER;
3424             aSize.Height() = rImageSize.Height();
3425         }
3426 
3427         ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, 1,
3428                               nDrawFlags, nTextStyle, NULL );
3429         nLineY = aPos.Y() + aSize.Height()/2;
3430 
3431         rMouseRect          = Rectangle( aPos, aSize );
3432         rMouseRect.Left()   = rPos.X();
3433         rStateRect.Left()   = rPos.X();
3434         rStateRect.Top()    = rMouseRect.Top();
3435 
3436         if ( aSize.Height() > rImageSize.Height() )
3437             rStateRect.Top() += ( aSize.Height() - rImageSize.Height() ) / 2;
3438         else
3439         {
3440             rStateRect.Top() -= ( rImageSize.Height() - aSize.Height() ) / 2;
3441             if( rStateRect.Top() < 0 )
3442                 rStateRect.Top() = 0;
3443         }
3444 
3445         rStateRect.Right()  = rStateRect.Left()+rImageSize.Width()-1;
3446         rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1;
3447         if ( rStateRect.Bottom() > rMouseRect.Bottom() )
3448             rMouseRect.Bottom() = rStateRect.Bottom();
3449     }
3450     else
3451     {
3452         if ( nWinStyle & WB_CENTER )
3453             rStateRect.Left() = rPos.X()+((rSize.Width()-rImageSize.Width())/2);
3454         else if ( nWinStyle & WB_RIGHT )
3455             rStateRect.Left() = rPos.X()+rSize.Width()-rImageSize.Width();
3456         else
3457             rStateRect.Left() = rPos.X();
3458         if ( nWinStyle & WB_VCENTER )
3459             rStateRect.Top() = rPos.Y()+((rSize.Height()-rImageSize.Height())/2);
3460         else if ( nWinStyle & WB_BOTTOM )
3461             rStateRect.Top() = rPos.Y()+rSize.Height()-rImageSize.Height();
3462         else
3463             rStateRect.Top() = rPos.Y();
3464         rStateRect.Right()  = rStateRect.Left()+rImageSize.Width()-1;
3465         rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1;
3466         // provide space for focusrect
3467         // note: this assumes that the control's size was adjusted
3468         // accordingly in Get/LoseFocus, so the onscreen position won't change
3469         if( HasFocus() )
3470             rStateRect.Move( 1, 1 );
3471         rMouseRect          = rStateRect;
3472 
3473         ImplSetFocusRect( rStateRect );
3474     }
3475 
3476     const int nLineSpace = 4;
3477     if( (GetStyle() & WB_CBLINESTYLE) != 0 &&
3478         rMouseRect.Right()-1-nLineSpace < rPos.X()+rSize.Width() )
3479     {
3480         const StyleSettings&	rStyleSettings = GetSettings().GetStyleSettings();
3481         if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
3482             SetLineColor( Color( COL_BLACK ) );
3483         else
3484             SetLineColor( rStyleSettings.GetShadowColor() );
3485         long nLineX = rMouseRect.Right()+nLineSpace;
3486         DrawLine( Point( nLineX, nLineY ), Point( rPos.X() + rSize.Width()-1, nLineY ) );
3487         if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
3488         {
3489             SetLineColor( rStyleSettings.GetLightColor() );
3490             DrawLine( Point( nLineX, nLineY+1 ), Point( rPos.X() + rSize.Width()-1, nLineY+1 ) );
3491         }
3492     }
3493 
3494     pDev->Pop();
3495 }
3496 
3497 // -----------------------------------------------------------------------
3498 
3499 void CheckBox::ImplDrawCheckBox( bool bLayout )
3500 {
3501     Size aImageSize = ImplGetCheckImageSize();
3502     aImageSize.Width()  = CalcZoom( aImageSize.Width() );
3503     aImageSize.Height() = CalcZoom( aImageSize.Height() );
3504 
3505     if( !bLayout )
3506         HideFocus();
3507 
3508     ImplDraw( this, 0, Point(), GetOutputSizePixel(), aImageSize,
3509               maStateRect, maMouseRect, bLayout );
3510 
3511     if( !bLayout )
3512     {
3513         ImplDrawCheckBoxState();
3514         if ( HasFocus() )
3515             ShowFocus( ImplGetFocusRect() );
3516     }
3517 }
3518 
3519 // -----------------------------------------------------------------------
3520 
3521 void CheckBox::ImplCheck()
3522 {
3523     TriState eNewState;
3524     if ( meState == STATE_NOCHECK )
3525         eNewState = STATE_CHECK;
3526     else if ( !mbTriState )
3527         eNewState = STATE_NOCHECK;
3528     else if ( meState == STATE_CHECK )
3529         eNewState = STATE_DONTKNOW;
3530     else
3531         eNewState = STATE_NOCHECK;
3532     meState = eNewState;
3533 
3534     ImplDelData aDelData;
3535     ImplAddDel( &aDelData );
3536     if( (GetStyle() & WB_EARLYTOGGLE) )
3537         Toggle();
3538     ImplInvalidateOrDrawCheckBoxState();
3539     if( ! (GetStyle() & WB_EARLYTOGGLE) )
3540         Toggle();
3541     if ( aDelData.IsDelete() )
3542         return;
3543     ImplRemoveDel( &aDelData );
3544     Click();
3545 }
3546 
3547 // -----------------------------------------------------------------------
3548 
3549 CheckBox::CheckBox( Window* pParent, WinBits nStyle ) :
3550     Button( WINDOW_CHECKBOX )
3551 {
3552     ImplInitCheckBoxData();
3553     ImplInit( pParent, nStyle );
3554 }
3555 
3556 // -----------------------------------------------------------------------
3557 
3558 CheckBox::CheckBox( Window* pParent, const ResId& rResId ) :
3559     Button( WINDOW_CHECKBOX )
3560 {
3561     ImplInitCheckBoxData();
3562     rResId.SetRT( RSC_CHECKBOX );
3563     WinBits nStyle = ImplInitRes( rResId );
3564     ImplInit( pParent, nStyle );
3565     ImplLoadRes( rResId );
3566 
3567     if ( !(nStyle & WB_HIDE) )
3568         Show();
3569 }
3570 
3571 // -----------------------------------------------------------------------
3572 
3573 void CheckBox::MouseButtonDown( const MouseEvent& rMEvt )
3574 {
3575     if ( rMEvt.IsLeft() && maMouseRect.IsInside( rMEvt.GetPosPixel() ) )
3576     {
3577         ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
3578         ImplInvalidateOrDrawCheckBoxState();
3579         StartTracking();
3580         return;
3581     }
3582 
3583     Button::MouseButtonDown( rMEvt );
3584 }
3585 
3586 // -----------------------------------------------------------------------
3587 
3588 void CheckBox::Tracking( const TrackingEvent& rTEvt )
3589 {
3590     if ( rTEvt.IsTrackingEnded() )
3591     {
3592         if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
3593         {
3594             if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
3595                 GrabFocus();
3596 
3597             ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
3598 
3599             // Bei Abbruch kein Click-Handler rufen
3600             if ( !rTEvt.IsTrackingCanceled() )
3601                 ImplCheck();
3602             else
3603                 ImplInvalidateOrDrawCheckBoxState();
3604         }
3605     }
3606     else
3607     {
3608         if ( maMouseRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() ) )
3609         {
3610             if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
3611             {
3612                 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
3613                 ImplInvalidateOrDrawCheckBoxState();
3614             }
3615         }
3616         else
3617         {
3618             if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
3619             {
3620                 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
3621                 ImplInvalidateOrDrawCheckBoxState();
3622             }
3623         }
3624     }
3625 }
3626 
3627 // -----------------------------------------------------------------------
3628 
3629 void CheckBox::KeyInput( const KeyEvent& rKEvt )
3630 {
3631     KeyCode aKeyCode = rKEvt.GetKeyCode();
3632 
3633     if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) )
3634     {
3635         if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
3636         {
3637             ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
3638             ImplInvalidateOrDrawCheckBoxState();
3639         }
3640     }
3641     else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) )
3642     {
3643         ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
3644         ImplInvalidateOrDrawCheckBoxState();
3645     }
3646     else
3647         Button::KeyInput( rKEvt );
3648 }
3649 
3650 // -----------------------------------------------------------------------
3651 
3652 void CheckBox::KeyUp( const KeyEvent& rKEvt )
3653 {
3654     KeyCode aKeyCode = rKEvt.GetKeyCode();
3655 
3656     if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_SPACE) )
3657     {
3658         ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
3659         ImplCheck();
3660     }
3661     else
3662         Button::KeyUp( rKEvt );
3663 }
3664 
3665 // -----------------------------------------------------------------------
3666 
3667 void CheckBox::FillLayoutData() const
3668 {
3669     mpControlData->mpLayoutData = new vcl::ControlLayoutData();
3670     const_cast<CheckBox*>(this)->ImplDrawCheckBox( true );
3671 }
3672 
3673 // -----------------------------------------------------------------------
3674 
3675 void CheckBox::Paint( const Rectangle& )
3676 {
3677     ImplDrawCheckBox();
3678 }
3679 
3680 // -----------------------------------------------------------------------
3681 
3682 void CheckBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
3683                      sal_uLong nFlags )
3684 {
3685     MapMode     aResMapMode( MAP_100TH_MM );
3686     Point       aPos  = pDev->LogicToPixel( rPos );
3687     Size        aSize = pDev->LogicToPixel( rSize );
3688     Size        aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode );
3689     Size        aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode );
3690     Size        aBrd2Size = pDev->LogicToPixel( Size( 30, 30 ), aResMapMode );
3691     long        nCheckWidth = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode ).Width();
3692     Font        aFont = GetDrawPixelFont( pDev );
3693     Rectangle   aStateRect;
3694     Rectangle   aMouseRect;
3695 
3696     aImageSize.Width()  = CalcZoom( aImageSize.Width() );
3697     aImageSize.Height() = CalcZoom( aImageSize.Height() );
3698     aBrd1Size.Width()   = CalcZoom( aBrd1Size.Width() );
3699     aBrd1Size.Height()  = CalcZoom( aBrd1Size.Height() );
3700     aBrd2Size.Width()   = CalcZoom( aBrd2Size.Width() );
3701     aBrd2Size.Height()  = CalcZoom( aBrd2Size.Height() );
3702 
3703     if ( !aBrd1Size.Width() )
3704         aBrd1Size.Width() = 1;
3705     if ( !aBrd1Size.Height() )
3706         aBrd1Size.Height() = 1;
3707     if ( !aBrd2Size.Width() )
3708         aBrd2Size.Width() = 1;
3709     if ( !aBrd2Size.Height() )
3710         aBrd2Size.Height() = 1;
3711     if ( !nCheckWidth )
3712         nCheckWidth = 1;
3713 
3714     pDev->Push();
3715     pDev->SetMapMode();
3716     pDev->SetFont( aFont );
3717     if ( nFlags & WINDOW_DRAW_MONO )
3718         pDev->SetTextColor( Color( COL_BLACK ) );
3719     else
3720         pDev->SetTextColor( GetTextColor() );
3721     pDev->SetTextFillColor();
3722 
3723     ImplDraw( pDev, nFlags, aPos, aSize,
3724               aImageSize, aStateRect, aMouseRect, false );
3725 
3726     pDev->SetLineColor();
3727     pDev->SetFillColor( Color( COL_BLACK ) );
3728     pDev->DrawRect( aStateRect );
3729     aStateRect.Left()   += aBrd1Size.Width();
3730     aStateRect.Top()    += aBrd1Size.Height();
3731     aStateRect.Right()  -= aBrd1Size.Width();
3732     aStateRect.Bottom() -= aBrd1Size.Height();
3733     if ( meState == STATE_DONTKNOW )
3734         pDev->SetFillColor( Color( COL_LIGHTGRAY ) );
3735     else
3736         pDev->SetFillColor( Color( COL_WHITE ) );
3737     pDev->DrawRect( aStateRect );
3738 
3739     if ( meState == STATE_CHECK )
3740     {
3741         aStateRect.Left()   += aBrd2Size.Width();
3742         aStateRect.Top()    += aBrd2Size.Height();
3743         aStateRect.Right()  -= aBrd2Size.Width();
3744         aStateRect.Bottom() -= aBrd2Size.Height();
3745         Point   aPos11( aStateRect.TopLeft() );
3746         Point   aPos12( aStateRect.BottomRight() );
3747         Point   aPos21( aStateRect.TopRight() );
3748         Point   aPos22( aStateRect.BottomLeft() );
3749         Point   aTempPos11( aPos11 );
3750         Point   aTempPos12( aPos12 );
3751         Point   aTempPos21( aPos21 );
3752         Point   aTempPos22( aPos22 );
3753         pDev->SetLineColor( Color( COL_BLACK ) );
3754         long nDX = 0;
3755         for ( long i = 0; i < nCheckWidth; i++ )
3756         {
3757             if ( !(i % 2) )
3758             {
3759                 aTempPos11.X() = aPos11.X()+nDX;
3760                 aTempPos12.X() = aPos12.X()+nDX;
3761                 aTempPos21.X() = aPos21.X()+nDX;
3762                 aTempPos22.X() = aPos22.X()+nDX;
3763             }
3764             else
3765             {
3766                 nDX++;
3767                 aTempPos11.X() = aPos11.X()-nDX;
3768                 aTempPos12.X() = aPos12.X()-nDX;
3769                 aTempPos21.X() = aPos21.X()-nDX;
3770                 aTempPos22.X() = aPos22.X()-nDX;
3771             }
3772             pDev->DrawLine( aTempPos11, aTempPos12 );
3773             pDev->DrawLine( aTempPos21, aTempPos22 );
3774         }
3775     }
3776 
3777     pDev->Pop();
3778 }
3779 
3780 // -----------------------------------------------------------------------
3781 
3782 void CheckBox::Resize()
3783 {
3784     Control::Resize();
3785     Invalidate();
3786 }
3787 
3788 // -----------------------------------------------------------------------
3789 
3790 void CheckBox::GetFocus()
3791 {
3792     if ( !GetText().Len() || (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
3793     {
3794         // increase button size to have space for focus rect
3795         // checkboxes without text will draw focusrect around the check
3796         // See CheckBox::ImplDraw()
3797         Point aPos( GetPosPixel() );
3798         Size aSize( GetSizePixel() );
3799         aPos.Move(-1,-1);
3800         aSize.Height() += 2;
3801         aSize.Width() += 2;
3802         SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL );
3803         ImplDrawCheckBox();
3804     }
3805     else
3806         ShowFocus( ImplGetFocusRect() );
3807 
3808     SetInputContext( InputContext( GetFont() ) );
3809     Button::GetFocus();
3810 }
3811 
3812 // -----------------------------------------------------------------------
3813 
3814 void CheckBox::LoseFocus()
3815 {
3816     if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
3817     {
3818         ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
3819         ImplInvalidateOrDrawCheckBoxState();
3820     }
3821 
3822     HideFocus();
3823     Button::LoseFocus();
3824 
3825     if ( !GetText().Len() || (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
3826     {
3827         // decrease button size again (see GetFocus())
3828         // checkboxes without text will draw focusrect around the check
3829         Point aPos( GetPosPixel() );
3830         Size aSize( GetSizePixel() );
3831         aPos.Move(1,1);
3832         aSize.Height() -= 2;
3833         aSize.Width() -= 2;
3834         SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL );
3835         ImplDrawCheckBox();
3836     }
3837 }
3838 
3839 // -----------------------------------------------------------------------
3840 
3841 void CheckBox::StateChanged( StateChangedType nType )
3842 {
3843     Button::StateChanged( nType );
3844 
3845     if ( nType == STATE_CHANGE_STATE )
3846     {
3847         if ( IsReallyVisible() && IsUpdateMode() )
3848             Invalidate( maStateRect );
3849     }
3850     else if ( (nType == STATE_CHANGE_ENABLE) ||
3851               (nType == STATE_CHANGE_TEXT) ||
3852               (nType == STATE_CHANGE_IMAGE) ||
3853               (nType == STATE_CHANGE_DATA) ||
3854               (nType == STATE_CHANGE_UPDATEMODE) )
3855     {
3856         if ( IsUpdateMode() )
3857             Invalidate();
3858     }
3859     else if ( nType == STATE_CHANGE_STYLE )
3860     {
3861         SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) );
3862 
3863         if ( (GetPrevStyle() & CHECKBOX_VIEW_STYLE) !=
3864              (GetStyle() & CHECKBOX_VIEW_STYLE) )
3865         {
3866             if ( IsUpdateMode() )
3867                 Invalidate();
3868         }
3869     }
3870     else if ( (nType == STATE_CHANGE_ZOOM) ||
3871               (nType == STATE_CHANGE_CONTROLFONT) )
3872     {
3873         ImplInitSettings( sal_True, sal_False, sal_False );
3874         Invalidate();
3875     }
3876     else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
3877     {
3878         ImplInitSettings( sal_False, sal_True, sal_False );
3879         Invalidate();
3880     }
3881     else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
3882     {
3883         ImplInitSettings( sal_False, sal_False, sal_True );
3884         Invalidate();
3885     }
3886 }
3887 
3888 // -----------------------------------------------------------------------
3889 
3890 void CheckBox::DataChanged( const DataChangedEvent& rDCEvt )
3891 {
3892     Button::DataChanged( rDCEvt );
3893 
3894     if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
3895          (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
3896          ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
3897           (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
3898     {
3899         ImplInitSettings( sal_True, sal_True, sal_True );
3900         Invalidate();
3901     }
3902 }
3903 
3904 // -----------------------------------------------------------------------
3905 
3906 long CheckBox::PreNotify( NotifyEvent& rNEvt )
3907 {
3908     long nDone = 0;
3909     const MouseEvent* pMouseEvt = NULL;
3910 
3911     if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
3912     {
3913         if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
3914         {
3915             // trigger redraw if mouse over state has changed
3916             if( IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL) )
3917             {
3918                 if( ( maMouseRect.IsInside( GetPointerPosPixel()) &&
3919                      !maMouseRect.IsInside( GetLastPointerPosPixel()) ) ||
3920                     ( maMouseRect.IsInside( GetLastPointerPosPixel()) &&
3921                      !maMouseRect.IsInside( GetPointerPosPixel()) ) ||
3922                     pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow() )
3923                 {
3924                     Invalidate( maStateRect );
3925                 }
3926             }
3927         }
3928     }
3929 
3930     return nDone ? nDone : Button::PreNotify(rNEvt);
3931 }
3932 
3933 // -----------------------------------------------------------------------
3934 
3935 void CheckBox::Toggle()
3936 {
3937     ImplCallEventListenersAndHandler( VCLEVENT_CHECKBOX_TOGGLE, maToggleHdl, this );
3938 }
3939 
3940 // -----------------------------------------------------------------------
3941 
3942 void CheckBox::SetState( TriState eState )
3943 {
3944     if ( !mbTriState && (eState == STATE_DONTKNOW) )
3945         eState = STATE_NOCHECK;
3946 
3947     if ( meState != eState )
3948     {
3949         meState = eState;
3950         StateChanged( STATE_CHANGE_STATE );
3951         Toggle();
3952     }
3953 }
3954 
3955 // -----------------------------------------------------------------------
3956 
3957 void CheckBox::EnableTriState( sal_Bool bTriState )
3958 {
3959     if ( mbTriState != bTriState )
3960     {
3961         mbTriState = bTriState;
3962 
3963         if ( !bTriState && (meState == STATE_DONTKNOW) )
3964             SetState( STATE_NOCHECK );
3965     }
3966 }
3967 
3968 // -----------------------------------------------------------------------
3969 
3970 long CheckBox::ImplGetImageToTextDistance() const
3971 {
3972     // 4 pixels, but take zoom into account, so the text doesn't "jump" relative to surrounding elements,
3973     // which might have been aligned with the text of the check box
3974     return CalcZoom( 4 );
3975 }
3976 
3977 // -----------------------------------------------------------------------
3978 
3979 Size CheckBox::ImplGetCheckImageSize() const
3980 {
3981     Size aSize;
3982     // why are IsNativeControlSupported and GetNativeControlRegion not const ?
3983     CheckBox* pThis = const_cast<CheckBox*>(this);
3984     bool bDefaultSize = true;
3985     if( pThis->IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) )
3986     {
3987         ImplControlValue aControlValue;
3988         // #i45896# workaround gcc3.3 temporary problem
3989         Rectangle		 aCtrlRegion( Point( 0, 0 ), GetSizePixel() );
3990         ControlState	 nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED;
3991         Rectangle aBoundingRgn, aContentRgn;
3992 
3993         // get native size of a check box
3994         if( pThis->GetNativeControlRegion( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion,
3995                                            nState, aControlValue, rtl::OUString(),
3996                                            aBoundingRgn, aContentRgn ) )
3997         {
3998             aSize = aContentRgn.GetSize();
3999             bDefaultSize = false;
4000         }
4001     }
4002     if( bDefaultSize )
4003         aSize = GetCheckImage( GetSettings(), 0 ).GetSizePixel();
4004     return aSize;
4005 }
4006 
4007 Image CheckBox::GetCheckImage( const AllSettings& rSettings, sal_uInt16 nFlags )
4008 {
4009     ImplSVData*             pSVData = ImplGetSVData();
4010     const StyleSettings&    rStyleSettings = rSettings.GetStyleSettings();
4011     sal_uInt16              nStyle = 0;
4012 
4013     if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
4014         nStyle = STYLE_CHECKBOX_MONO;
4015 
4016     if ( !pSVData->maCtrlData.mpCheckImgList ||
4017          (pSVData->maCtrlData.mnCheckStyle != nStyle) ||
4018          (pSVData->maCtrlData.mnLastCheckFColor != rStyleSettings.GetFaceColor().GetColor()) ||
4019          (pSVData->maCtrlData.mnLastCheckWColor != rStyleSettings.GetWindowColor().GetColor()) ||
4020          (pSVData->maCtrlData.mnLastCheckLColor != rStyleSettings.GetLightColor().GetColor()) )
4021     {
4022         if ( pSVData->maCtrlData.mpCheckImgList )
4023             delete pSVData->maCtrlData.mpCheckImgList;
4024 
4025         pSVData->maCtrlData.mnLastCheckFColor = rStyleSettings.GetFaceColor().GetColor();
4026         pSVData->maCtrlData.mnLastCheckWColor = rStyleSettings.GetWindowColor().GetColor();
4027         pSVData->maCtrlData.mnLastCheckLColor = rStyleSettings.GetLightColor().GetColor();
4028 
4029         ResMgr* pResMgr = ImplGetResMgr();
4030         pSVData->maCtrlData.mpCheckImgList = new ImageList();
4031         if( pResMgr )
4032 	    LoadThemedImageList( rStyleSettings,
4033 				 pSVData->maCtrlData.mpCheckImgList,
4034 				 ResId( SV_RESID_BITMAP_CHECK+nStyle, *pResMgr ), 9 );
4035         pSVData->maCtrlData.mnCheckStyle = nStyle;
4036     }
4037 
4038     sal_uInt16 nId;
4039     if ( nFlags & BUTTON_DRAW_DISABLED )
4040     {
4041         if ( nFlags & BUTTON_DRAW_DONTKNOW )
4042             nId = 9;
4043         else if ( nFlags & BUTTON_DRAW_CHECKED )
4044             nId = 6;
4045         else
4046             nId = 5;
4047     }
4048     else if ( nFlags & BUTTON_DRAW_PRESSED )
4049     {
4050         if ( nFlags & BUTTON_DRAW_DONTKNOW )
4051             nId = 8;
4052         else if ( nFlags & BUTTON_DRAW_CHECKED )
4053             nId = 4;
4054         else
4055             nId = 3;
4056     }
4057     else
4058     {
4059         if ( nFlags & BUTTON_DRAW_DONTKNOW )
4060             nId = 7;
4061         else if ( nFlags & BUTTON_DRAW_CHECKED )
4062             nId = 2;
4063         else
4064             nId = 1;
4065     }
4066     return pSVData->maCtrlData.mpCheckImgList->GetImage( nId );
4067 }
4068 
4069 // -----------------------------------------------------------------------
4070 
4071 void CheckBox::ImplSetMinimumNWFSize()
4072 {
4073     Push( PUSH_MAPMODE );
4074     SetMapMode( MAP_PIXEL );
4075 
4076     ImplControlValue aControlValue;
4077     Size aCurSize( GetSizePixel() );
4078     Rectangle aCtrlRegion( Point( 0, 0 ), aCurSize );
4079     Rectangle aBoundingRgn, aContentRgn;
4080 
4081     // get native size of a radiobutton
4082     if( GetNativeControlRegion( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion,
4083                                 CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED, aControlValue, rtl::OUString(),
4084                                 aBoundingRgn, aContentRgn ) )
4085     {
4086         Size aSize = aContentRgn.GetSize();
4087 
4088         if( aSize.Height() > aCurSize.Height() )
4089         {
4090             aCurSize.Height() = aSize.Height();
4091             SetSizePixel( aCurSize );
4092         }
4093     }
4094 
4095     Pop();
4096 }
4097 
4098 // -----------------------------------------------------------------------
4099 
4100 Size CheckBox::CalcMinimumSize( long nMaxWidth ) const
4101 {
4102     Size aSize = ImplGetCheckImageSize();
4103     nMaxWidth -= aSize.Width();
4104 
4105     XubString aText = GetText();
4106     if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
4107     {
4108         // subtract what will be added later
4109         nMaxWidth-=2;
4110         nMaxWidth -= ImplGetImageToTextDistance();
4111 
4112         Size aTextSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
4113                                       aText, FixedText::ImplGetTextStyle( GetStyle() ) ).GetSize();
4114         aSize.Width()+=2;    // for focus rect
4115         aSize.Width() += ImplGetImageToTextDistance();
4116         aSize.Width() += aTextSize.Width();
4117         if ( aSize.Height() < aTextSize.Height() )
4118             aSize.Height() = aTextSize.Height();
4119     }
4120     else
4121     {
4122         // is this still correct ? since the checkbox now
4123         // shows a focus rect it should be 2 pixels wider and longer
4124 /* da ansonsten im Writer die Control zu weit oben haengen
4125         aSize.Width() += 2;
4126         aSize.Height() += 2;
4127 */
4128     }
4129 
4130     return CalcWindowSize( aSize );
4131 }
4132 
4133 // -----------------------------------------------------------------------
4134 
4135 Size CheckBox::GetOptimalSize(WindowSizeType eType) const
4136 {
4137     switch (eType) {
4138     case WINDOWSIZE_MINIMUM:
4139         return CalcMinimumSize();
4140     default:
4141         return Button::GetOptimalSize( eType );
4142     }
4143 }
4144 
4145 // =======================================================================
4146 
4147 ImageButton::ImageButton( WindowType nType ) :
4148     PushButton( nType )
4149 {
4150     ImplInitStyle();
4151 }
4152 
4153 // -----------------------------------------------------------------------
4154 
4155 ImageButton::ImageButton( Window* pParent, WinBits nStyle ) :
4156     PushButton( pParent, nStyle )
4157 {
4158     ImplInitStyle();
4159 }
4160 
4161 // -----------------------------------------------------------------------
4162 
4163 ImageButton::ImageButton( Window* pParent, const ResId& rResId ) :
4164     PushButton( pParent, rResId.SetRT( RSC_IMAGEBUTTON ) )
4165 {
4166     sal_uLong nObjMask = ReadLongRes();
4167 
4168     if ( RSC_IMAGEBUTTON_IMAGE & nObjMask )
4169     {
4170         SetModeImage( Image( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) ) );
4171         IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
4172     }
4173 
4174     if ( RSC_IMAGEBUTTON_SYMBOL & nObjMask )
4175         SetSymbol( (SymbolType)ReadLongRes() );
4176 
4177     if ( RSC_IMAGEBUTTON_STATE & nObjMask )
4178         SetState( (TriState)ReadLongRes() );
4179 
4180     ImplInitStyle();
4181 }
4182 
4183 // -----------------------------------------------------------------------
4184 
4185 ImageButton::~ImageButton()
4186 {
4187 }
4188 
4189 // -----------------------------------------------------------------------
4190 void ImageButton::ImplInitStyle()
4191 {
4192     WinBits nStyle = GetStyle();
4193 
4194     if ( ! ( nStyle & ( WB_RIGHT | WB_LEFT ) ) )
4195         nStyle |= WB_CENTER;
4196 
4197     if ( ! ( nStyle & ( WB_TOP | WB_BOTTOM ) ) )
4198         nStyle |= WB_VCENTER;
4199 
4200     SetStyle( nStyle );
4201 }
4202 
4203 // =======================================================================
4204 
4205 ImageRadioButton::ImageRadioButton( Window* pParent, WinBits nStyle ) :
4206     RadioButton( pParent, nStyle )
4207 {
4208 }
4209 
4210 // -----------------------------------------------------------------------
4211 
4212 ImageRadioButton::ImageRadioButton( Window* pParent, const ResId& rResId ) :
4213     RadioButton( pParent, rResId.SetRT( RSC_IMAGERADIOBUTTON ) )
4214 {
4215     sal_uLong nObjMask = ReadLongRes();
4216 
4217     if ( RSC_IMAGERADIOBUTTON_IMAGE & nObjMask )
4218     {
4219         SetModeRadioImage( Image( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) ) );
4220         IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
4221     }
4222 }
4223 
4224 // -----------------------------------------------------------------------
4225 
4226 ImageRadioButton::~ImageRadioButton()
4227 {
4228 }
4229 
4230 // =======================================================================
4231 
4232 TriStateBox::TriStateBox( Window* pParent, WinBits nStyle ) :
4233     CheckBox( pParent, nStyle )
4234 {
4235     EnableTriState( sal_True );
4236 }
4237 
4238 // -----------------------------------------------------------------------
4239 
4240 TriStateBox::TriStateBox( Window* pParent, const ResId& rResId ) :
4241     CheckBox( pParent, rResId.SetRT( RSC_TRISTATEBOX ) )
4242 {
4243     EnableTriState( sal_True );
4244 
4245     sal_uLong  nTriState        = ReadLongRes();
4246     sal_uInt16 bDisableTriState = ReadShortRes();
4247     //anderer Wert als Default ?
4248     if ( (TriState)nTriState != STATE_NOCHECK )
4249         SetState( (TriState)nTriState );
4250     if ( bDisableTriState )
4251         EnableTriState( sal_False );
4252 }
4253 
4254 // -----------------------------------------------------------------------
4255 
4256 TriStateBox::~TriStateBox()
4257 {
4258 }
4259 
4260 // =======================================================================
4261 
4262 DisclosureButton::DisclosureButton( Window* pParent, WinBits ) :
4263     CheckBox( pParent, WB_NOBORDER )
4264 {
4265 }
4266 
4267 // -----------------------------------------------------------------------
4268 
4269 DisclosureButton::DisclosureButton( Window* pParent, const ResId& rResId ) :
4270     CheckBox( pParent, rResId.SetRT( RSC_CHECKBOX ) )
4271 {
4272 }
4273 
4274 // -----------------------------------------------------------------------
4275 
4276 void DisclosureButton::ImplDrawCheckBoxState()
4277 {
4278     /* HACK: DisclosureButton is currently assuming, that the disclosure sign
4279        will fit into the rectangle occupied by a normal checkbox on all themes.
4280        If this does not hold true for some theme, ImplGetCheckImageSize
4281        would have to be overloaded for DisclosureButton; also GetNativeControlRegion
4282        for CTRL_LISTNODE would have to be implemented and taken into account
4283     */
4284 
4285     Rectangle aStateRect( GetStateRect() );
4286 
4287     ImplControlValue    aControlValue( GetState() == STATE_CHECK ? BUTTONVALUE_ON : BUTTONVALUE_OFF );
4288     Rectangle           aCtrlRegion( aStateRect );
4289     ControlState        nState = 0;
4290 
4291     if ( HasFocus() )						nState |= CTRL_STATE_FOCUSED;
4292     if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT )	nState |= CTRL_STATE_DEFAULT;
4293     if ( Window::IsEnabled() ) 				nState |= CTRL_STATE_ENABLED;
4294     if ( IsMouseOver() && GetMouseRect().IsInside( GetPointerPosPixel() ) )
4295         nState |= CTRL_STATE_ROLLOVER;
4296 
4297     if( ! DrawNativeControl( CTRL_LISTNODE, PART_ENTIRE_CONTROL, aCtrlRegion, nState,
4298                            aControlValue, rtl::OUString() ) )
4299     {
4300         ImplSVCtrlData& rCtrlData( ImplGetSVData()->maCtrlData );
4301         if( ! rCtrlData.mpDisclosurePlus )
4302             rCtrlData.mpDisclosurePlus = new Image( BitmapEx( VclResId( SV_DISCLOSURE_PLUS ) ) );
4303         if( ! rCtrlData.mpDisclosurePlusHC )
4304             rCtrlData.mpDisclosurePlusHC = new Image( BitmapEx( VclResId( SV_DISCLOSURE_PLUS_HC ) ) );
4305         if( ! rCtrlData.mpDisclosureMinus )
4306             rCtrlData.mpDisclosureMinus = new Image( BitmapEx( VclResId( SV_DISCLOSURE_MINUS ) ) );
4307         if( ! rCtrlData.mpDisclosureMinusHC )
4308             rCtrlData.mpDisclosureMinusHC = new Image( BitmapEx( VclResId( SV_DISCLOSURE_MINUS_HC ) ) );
4309 
4310         Image* pImg = NULL;
4311         if( GetSettings().GetStyleSettings().GetHighContrastMode() )
4312             pImg = IsChecked() ? rCtrlData.mpDisclosureMinusHC : rCtrlData.mpDisclosurePlusHC;
4313         else
4314             pImg = IsChecked() ? rCtrlData.mpDisclosureMinus : rCtrlData.mpDisclosurePlus;
4315 
4316         DBG_ASSERT( pImg, "no disclosure image" );
4317         if( ! pImg )
4318             return;
4319 
4320         sal_uInt16 nStyle = 0;
4321         if( ! IsEnabled() )
4322             nStyle |= IMAGE_DRAW_DISABLE;
4323 
4324         Size aSize( aStateRect.GetSize() );
4325         Size aImgSize( pImg->GetSizePixel() );
4326         Point aOff( (aSize.Width() - aImgSize.Width())/2,
4327                     (aSize.Height() - aImgSize.Height())/2 );
4328         aOff += aStateRect.TopLeft();
4329         DrawImage( aOff, *pImg, nStyle );
4330     }
4331 }
4332 
4333 // -----------------------------------------------------------------------
4334 
4335 void DisclosureButton::KeyInput( const KeyEvent& rKEvt )
4336 {
4337     KeyCode aKeyCode = rKEvt.GetKeyCode();
4338 
4339     if( !aKeyCode.GetModifier()  &&
4340         ( ( aKeyCode.GetCode() == KEY_ADD ) ||
4341           ( aKeyCode.GetCode() == KEY_SUBTRACT ) )
4342         )
4343     {
4344         Check( aKeyCode.GetCode() == KEY_ADD );
4345     }
4346     else
4347         Button::KeyInput( rKEvt );
4348 }
4349 
4350 
4351