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