/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"

#include <tools/debug.hxx>
#include <tools/poly.hxx>
#include <tools/rc.h>

#include <vcl/image.hxx>
#include <vcl/bitmap.hxx>
#include <vcl/bitmapex.hxx>
#include <vcl/decoview.hxx>
#include <vcl/event.hxx>
#include <vcl/svapp.hxx>
#include <vcl/dialog.hxx>
#include <vcl/fixed.hxx>
#include <vcl/button.hxx>
#include <vcl/salnativewidgets.hxx>
#include <vcl/edit.hxx>

#include <svids.hrc>
#include <svdata.hxx>
#include <window.h>
#include <controldata.hxx>

// =======================================================================

#define PUSHBUTTON_VIEW_STYLE       (WB_3DLOOK |                        \
                                     WB_LEFT | WB_CENTER | WB_RIGHT |   \
                                     WB_TOP | WB_VCENTER | WB_BOTTOM |  \
                                     WB_WORDBREAK | WB_NOLABEL |        \
                                     WB_DEFBUTTON | WB_NOLIGHTBORDER |  \
                                     WB_RECTSTYLE | WB_SMALLSTYLE |     \
                                     WB_TOGGLE )
#define RADIOBUTTON_VIEW_STYLE      (WB_3DLOOK |                        \
                                     WB_LEFT | WB_CENTER | WB_RIGHT |   \
                                     WB_TOP | WB_VCENTER | WB_BOTTOM |  \
                                     WB_WORDBREAK | WB_NOLABEL)
#define CHECKBOX_VIEW_STYLE         (WB_3DLOOK |                        \
                                     WB_LEFT | WB_CENTER | WB_RIGHT |   \
                                     WB_TOP | WB_VCENTER | WB_BOTTOM |  \
                                     WB_WORDBREAK | WB_NOLABEL)

// =======================================================================

class ImplCommonButtonData
{
public:
    Rectangle       maFocusRect;
    Rectangle       maSymbolRect;
    sal_uInt16          mnButtonState;
    sal_Bool            mbSmallSymbol;

    Image           maImage;
    Image           maImageHC;
    BitmapEx*       mpBitmapEx;
    BitmapEx*       mpBitmapExHC;
    ImageAlign      meImageAlign;
    SymbolAlign     meSymbolAlign;

public:
                    ImplCommonButtonData();
                   ~ImplCommonButtonData();
};

// -----------------------------------------------------------------------
ImplCommonButtonData::ImplCommonButtonData()
{
    mnButtonState   = 0;
    mbSmallSymbol = sal_False;

    mpBitmapEx = NULL;
    mpBitmapExHC = NULL;
    meImageAlign = IMAGEALIGN_TOP;
    meSymbolAlign = SYMBOLALIGN_LEFT;
}

// -----------------------------------------------------------------------
ImplCommonButtonData::~ImplCommonButtonData()
{
    delete mpBitmapEx;
    delete mpBitmapExHC;
}

// =======================================================================

Button::Button( WindowType nType ) :
    Control( nType )
{
    mpButtonData = new ImplCommonButtonData;
}

// -----------------------------------------------------------------------

Button::Button( Window* pParent, WinBits nStyle ) :
    Control( WINDOW_BUTTON )
{
    mpButtonData = new ImplCommonButtonData;
    ImplInit( pParent, nStyle, NULL );
}

// -----------------------------------------------------------------------

Button::Button( Window* pParent, const ResId& rResId ) :
    Control( WINDOW_BUTTON )
{
    rResId.SetRT( RSC_BUTTON );
    mpButtonData = new ImplCommonButtonData;
    WinBits nStyle = ImplInitRes( rResId );
    ImplInit( pParent, nStyle, NULL );
    ImplLoadRes( rResId );

    if ( !(nStyle & WB_HIDE) )
        Show();
}

// -----------------------------------------------------------------------

Button::~Button()
{
    delete mpButtonData;
}

// -----------------------------------------------------------------------

void Button::Click()
{
    ImplCallEventListenersAndHandler( VCLEVENT_BUTTON_CLICK, maClickHdl, this );
}

// -----------------------------------------------------------------------

XubString Button::GetStandardText( StandardButtonType eButton )
{
    static struct
    {
        sal_uInt32 nResId;
        const char* pDefText;
    } aResIdAry[BUTTON_COUNT] =
    {
        { SV_BUTTONTEXT_OK, "~OK" },
        { SV_BUTTONTEXT_CANCEL, "~Cancel" },
        { SV_BUTTONTEXT_YES, "~Yes" },
        { SV_BUTTONTEXT_NO, "~No" },
        { SV_BUTTONTEXT_RETRY, "~Retry" },
        { SV_BUTTONTEXT_HELP, "~Help" },
        { SV_BUTTONTEXT_CLOSE, "~Close" },
        { SV_BUTTONTEXT_MORE, "~More" },
        { SV_BUTTONTEXT_IGNORE, "~Ignore" },
        { SV_BUTTONTEXT_ABORT, "~Abort" },
        { SV_BUTTONTEXT_LESS, "~Less" }
    };

    String aText;
    ResMgr* pResMgr = ImplGetResMgr();
    if( pResMgr )
    {
        ResId aResId( aResIdAry[(sal_uInt16)eButton].nResId, *pResMgr );
        aText = String( aResId );
    }
    else
    {
        ByteString aT( aResIdAry[(sal_uInt16)eButton].pDefText );
        aText = String( aT, RTL_TEXTENCODING_ASCII_US );
    }
    return aText;
}

// -----------------------------------------------------------------------

XubString Button::GetStandardHelpText( StandardButtonType /* eButton */ )
{
    XubString aHelpText;
    return aHelpText;
}
// -----------------------------------------------------------------------
sal_Bool Button::SetModeImage( const Image& rImage, BmpColorMode eMode )
{
    if( eMode == BMP_COLOR_NORMAL )
    {
        if ( rImage != mpButtonData->maImage )
        {
            delete mpButtonData->mpBitmapEx;

            mpButtonData->mpBitmapEx = NULL;
            mpButtonData->maImage = rImage;

            StateChanged( STATE_CHANGE_DATA );
        }
    }
    else if( eMode == BMP_COLOR_HIGHCONTRAST )
    {
		if( rImage != mpButtonData->maImageHC )
		{
            delete mpButtonData->mpBitmapExHC;

            mpButtonData->mpBitmapExHC = NULL;
            mpButtonData->maImageHC = rImage;

            StateChanged( STATE_CHANGE_DATA );
        }
    }
    else
        return sal_False;

    return sal_True;
}

// -----------------------------------------------------------------------
const Image Button::GetModeImage( BmpColorMode eMode ) const
{
    if( eMode == BMP_COLOR_NORMAL )
    {
        return mpButtonData->maImage;
    }
    else if( eMode == BMP_COLOR_HIGHCONTRAST )
    {
        return mpButtonData->maImageHC;
    }
    else
        return Image();
}

// -----------------------------------------------------------------------
sal_Bool Button::HasImage() const
{
    return !!(mpButtonData->maImage);
}

// -----------------------------------------------------------------------
void Button::SetImageAlign( ImageAlign eAlign )
{
    if ( mpButtonData->meImageAlign != eAlign )
    {
        mpButtonData->meImageAlign = eAlign;
        StateChanged( STATE_CHANGE_DATA );
    }
}

// -----------------------------------------------------------------------
ImageAlign Button::GetImageAlign() const
{
    return mpButtonData->meImageAlign;
}

// -----------------------------------------------------------------------
sal_Bool Button::SetModeBitmap( const BitmapEx& rBitmap, BmpColorMode eMode )
{
    if ( SetModeImage( rBitmap, eMode ) )
    {
        if( eMode == BMP_COLOR_NORMAL )
        {
            if ( !mpButtonData->mpBitmapEx )
                mpButtonData->mpBitmapEx = new BitmapEx( rBitmap );
        }
        else if ( eMode == BMP_COLOR_HIGHCONTRAST )
        {
            if ( !mpButtonData->mpBitmapExHC )
                mpButtonData->mpBitmapExHC = new BitmapEx( rBitmap );
        }
        else
            return sal_False;

        return sal_True;
    }
    return sal_False;
}

// -----------------------------------------------------------------------
BitmapEx Button::GetModeBitmap( BmpColorMode eMode ) const
{
    BitmapEx aBmp;

    if ( eMode == BMP_COLOR_NORMAL )
	{
		if ( mpButtonData->mpBitmapEx )
			aBmp = *( mpButtonData->mpBitmapEx );
	}
    else if ( eMode == BMP_COLOR_HIGHCONTRAST )
	{
		if ( mpButtonData->mpBitmapExHC )
			aBmp = *( mpButtonData->mpBitmapExHC );
	}

    return aBmp;
}

// -----------------------------------------------------------------------
void Button::SetFocusRect( const Rectangle& rFocusRect )
{
    ImplSetFocusRect( rFocusRect );
}

// -----------------------------------------------------------------------
const Rectangle& Button::GetFocusRect() const
{
    return ImplGetFocusRect();
}

// -----------------------------------------------------------------------

const Rectangle& Button::ImplGetSymbolRect() const
{
    return mpButtonData->maSymbolRect;
}

void Button::ImplSetSymbolRect( const Rectangle& i_rRect )
{
    mpButtonData->maSymbolRect = i_rRect;
}

// -----------------------------------------------------------------------

sal_uInt16 Button::ImplGetTextStyle( XubString& rText, WinBits nWinStyle,
                                 sal_uLong nDrawFlags )
{
    const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
    sal_uInt16 nTextStyle = FixedText::ImplGetTextStyle( nWinStyle & ~WB_DEFBUTTON );

    if ( nDrawFlags & WINDOW_DRAW_NOMNEMONIC )
    {
        if ( nTextStyle & TEXT_DRAW_MNEMONIC )
        {
            rText = GetNonMnemonicString( rText );
            nTextStyle &= ~TEXT_DRAW_MNEMONIC;
        }
    }

    if ( !(nDrawFlags & WINDOW_DRAW_NODISABLE) )
    {
        if ( !IsEnabled() )
            nTextStyle |= TEXT_DRAW_DISABLE;
    }

    if ( (nDrawFlags & WINDOW_DRAW_MONO) ||
         (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
        nTextStyle |= TEXT_DRAW_MONO;

    return nTextStyle;
}

// -----------------------------------------------------------------------

void Button::ImplDrawAlignedImage( OutputDevice* pDev, Point& rPos,
                                   Size& rSize, sal_Bool bLayout,
                                   sal_uLong nImageSep, sal_uLong nDrawFlags,
                                   sal_uInt16 nTextStyle, Rectangle *pSymbolRect,
                                   bool bAddImageSep )
{
    XubString   aText( GetText() );
    sal_Bool        bDrawImage = HasImage() && ! ( ImplGetButtonState() & BUTTON_DRAW_NOIMAGE );
    sal_Bool        bDrawText  = aText.Len() && ! ( ImplGetButtonState() & BUTTON_DRAW_NOTEXT );
    sal_Bool        bHasSymbol = pSymbolRect ? sal_True : sal_False;

    // No text and no image => nothing to do => return
    if ( !bDrawImage && !bDrawText && !bHasSymbol )
        return;

    WinBits         nWinStyle = GetStyle();
    Rectangle       aOutRect( rPos, rSize );
    MetricVector   *pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL;
    String         *pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL;
    ImageAlign      eImageAlign = mpButtonData->meImageAlign;
    Size            aImageSize = mpButtonData->maImage.GetSizePixel();

    if ( ( nDrawFlags & WINDOW_DRAW_NOMNEMONIC ) &&
         ( nTextStyle & TEXT_DRAW_MNEMONIC ) )
    {
        aText = GetNonMnemonicString( aText );
        nTextStyle &= ~TEXT_DRAW_MNEMONIC;
    }

    aImageSize.Width()  = CalcZoom( aImageSize.Width() );
    aImageSize.Height() = CalcZoom( aImageSize.Height() );
    
    // Drawing text or symbol only is simple, use style and output rectangle
    if ( bHasSymbol && !bDrawImage && !bDrawText )
    {
        *pSymbolRect = aOutRect;
        return;
    }
    else if ( bDrawText && !bDrawImage && !bHasSymbol )
    {
        DrawControlText( *pDev, aOutRect, aText, nTextStyle, pVector, pDisplayText );

        ImplSetFocusRect( aOutRect );
        rSize = aOutRect.GetSize();
        rPos = aOutRect.TopLeft();

        return;
    }

    // check for HC mode ( image only! )
    Image    *pImage    = &(mpButtonData->maImage);
    BitmapEx *pBitmapEx = mpButtonData->mpBitmapEx;

    if( !!(mpButtonData->maImageHC) )
    {
        if( GetSettings().GetStyleSettings().GetHighContrastMode() )
        {
            pImage = &(mpButtonData->maImageHC);
            pBitmapEx = mpButtonData->mpBitmapExHC;
        }
    }

    if ( pBitmapEx && ( pDev->GetOutDevType() == OUTDEV_PRINTER ) )
    {
        // Die Groesse richtet sich nach dem Bildschirm, soll auf
        // dem Drucker genau so aussehen...
        MapMode aMap100thMM( MAP_100TH_MM );
        aImageSize = PixelToLogic( aImageSize, aMap100thMM );
        aImageSize = pDev->LogicToPixel( aImageSize, aMap100thMM );
    }

    Size aTextSize;
    Size aSymbolSize;
    Size aMax;
    Point aImagePos = rPos;
    Point aTextPos = rPos;
    Rectangle aUnion = Rectangle( aImagePos, aImageSize );
    Rectangle aSymbol;
    long nSymbolHeight = 0;

    if ( bDrawText || bHasSymbol )
    {
        // Get the size of the text output area ( the symbol will be drawn in
        // this area as well, so the symbol rectangle will be calculated here, too )

        Rectangle   aRect = Rectangle( Point(), rSize );
        Size        aTSSize;

        if ( bHasSymbol )
        {
            if ( bDrawText )
            {
                nSymbolHeight = pDev->GetTextHeight();
                if ( mpButtonData->mbSmallSymbol )
                    nSymbolHeight = nSymbolHeight * 3 / 4;

                aSymbol = Rectangle( Point(), Size( nSymbolHeight, nSymbolHeight ) );
                ImplCalcSymbolRect( aSymbol );
                aRect.Left() += 3 * nSymbolHeight / 2;
                aTSSize.Width() = 3 * nSymbolHeight / 2;
            }
            else
            {
                aSymbol = Rectangle( Point(), rSize );
                ImplCalcSymbolRect( aSymbol );
                aTSSize.Width() = aSymbol.GetWidth();
            }
            aTSSize.Height() = aSymbol.GetHeight();
            aSymbolSize = aSymbol.GetSize();
        }

        if ( bDrawText )
        {
            if ( ( eImageAlign == IMAGEALIGN_LEFT_TOP ) ||
                ( eImageAlign == IMAGEALIGN_LEFT ) ||
                ( eImageAlign == IMAGEALIGN_LEFT_BOTTOM ) ||
                ( eImageAlign == IMAGEALIGN_RIGHT_TOP ) ||
                ( eImageAlign == IMAGEALIGN_RIGHT ) ||
                ( eImageAlign == IMAGEALIGN_RIGHT_BOTTOM ) )
            {
                aRect.Right() -= ( aImageSize.Width() + nImageSep );
            }
            else if ( ( eImageAlign == IMAGEALIGN_TOP_LEFT ) ||
                ( eImageAlign == IMAGEALIGN_TOP ) ||
                ( eImageAlign == IMAGEALIGN_TOP_RIGHT ) ||
                ( eImageAlign == IMAGEALIGN_BOTTOM_LEFT ) ||
                ( eImageAlign == IMAGEALIGN_BOTTOM ) ||
                ( eImageAlign == IMAGEALIGN_BOTTOM_RIGHT ) )
            {
                aRect.Bottom() -= ( aImageSize.Height() + nImageSep );
            }

            aRect = pDev->GetTextRect( aRect, aText, nTextStyle );
            aTextSize = aRect.GetSize();

            aTSSize.Width()  += aTextSize.Width();

            if ( aTSSize.Height() < aTextSize.Height() )
                aTSSize.Height() = aTextSize.Height();
            
            if( bAddImageSep && bDrawImage )
            {
                long nDiff = (aImageSize.Height() - aTextSize.Height()) / 3;
                if( nDiff > 0 )
                    nImageSep += nDiff;
            }
        }

        aMax.Width() = aTSSize.Width() > aImageSize.Width() ? aTSSize.Width() : aImageSize.Width();
        aMax.Height() = aTSSize.Height() > aImageSize.Height() ? aTSSize.Height() : aImageSize.Height();

        // Now calculate the output area for the image and the text acording to the image align flags

        if ( ( eImageAlign == IMAGEALIGN_LEFT ) ||
             ( eImageAlign == IMAGEALIGN_RIGHT ) )
        {
            aImagePos.Y() = rPos.Y() + ( aMax.Height() - aImageSize.Height() ) / 2;
            aTextPos.Y()  = rPos.Y() + ( aMax.Height() - aTSSize.Height() ) / 2;
        }
        else if ( ( eImageAlign == IMAGEALIGN_LEFT_BOTTOM ) ||
                  ( eImageAlign == IMAGEALIGN_RIGHT_BOTTOM ) )
        {
            aImagePos.Y() = rPos.Y() + aMax.Height() - aImageSize.Height();
            aTextPos.Y()  = rPos.Y() + aMax.Height() - aTSSize.Height();
        }
        else if ( ( eImageAlign == IMAGEALIGN_TOP ) ||
                  ( eImageAlign == IMAGEALIGN_BOTTOM ) )
        {
            aImagePos.X() = rPos.X() + ( aMax.Width() - aImageSize.Width() ) / 2;
            aTextPos.X()  = rPos.X() + ( aMax.Width() - aTSSize.Width() ) / 2;
        }
        else if ( ( eImageAlign == IMAGEALIGN_TOP_RIGHT ) ||
                  ( eImageAlign == IMAGEALIGN_BOTTOM_RIGHT ) )
        {
            aImagePos.X() = rPos.X() + aMax.Width() - aImageSize.Width();
            aTextPos.X()  = rPos.X() + aMax.Width() - aTSSize.Width();
        }

        if ( ( eImageAlign == IMAGEALIGN_LEFT_TOP ) ||
             ( eImageAlign == IMAGEALIGN_LEFT ) ||
             ( eImageAlign == IMAGEALIGN_LEFT_BOTTOM ) )
        {
            aTextPos.X() = rPos.X() + aImageSize.Width() + nImageSep;
        }
        else if ( ( eImageAlign == IMAGEALIGN_RIGHT_TOP ) ||
                  ( eImageAlign == IMAGEALIGN_RIGHT ) ||
                  ( eImageAlign == IMAGEALIGN_RIGHT_BOTTOM ) )
        {
            aImagePos.X() = rPos.X() + aTSSize.Width() + nImageSep;
        }
        else if ( ( eImageAlign == IMAGEALIGN_TOP_LEFT ) ||
                  ( eImageAlign == IMAGEALIGN_TOP ) ||
                  ( eImageAlign == IMAGEALIGN_TOP_RIGHT ) )
        {
            aTextPos.Y() = rPos.Y() + aImageSize.Height() + nImageSep;
        }
        else if ( ( eImageAlign == IMAGEALIGN_BOTTOM_LEFT ) ||
                  ( eImageAlign == IMAGEALIGN_BOTTOM ) ||
                  ( eImageAlign == IMAGEALIGN_BOTTOM_RIGHT ) )
        {
            aImagePos.Y() = rPos.Y() + aTSSize.Height() + nImageSep;
        }
        else if ( eImageAlign == IMAGEALIGN_CENTER )
        {
            aImagePos.X() = rPos.X() + ( aMax.Width()  - aImageSize.Width() ) / 2;
            aImagePos.Y() = rPos.Y() + ( aMax.Height() - aImageSize.Height() ) / 2;
            aTextPos.X()  = rPos.X() + ( aMax.Width()  - aTSSize.Width() ) / 2;
            aTextPos.Y()  = rPos.Y() + ( aMax.Height() - aTSSize.Height() ) / 2;
        }
        aUnion = Rectangle( aImagePos, aImageSize );
        aUnion.Union( Rectangle( aTextPos, aTSSize ) );
    }

    // Now place the combination of text and image in the output area of the button
    // according to the window style (WinBits)
    long nXOffset = 0;
    long nYOffset = 0;

    if ( nWinStyle & WB_CENTER )
    {
        nXOffset = ( rSize.Width() - aUnion.GetWidth() ) / 2;
    }
    else if ( nWinStyle & WB_RIGHT )
    {
        nXOffset = rSize.Width() - aUnion.GetWidth();
    }

    if ( nWinStyle & WB_VCENTER )
    {
        nYOffset = ( rSize.Height() - aUnion.GetHeight() ) / 2;
    }
    else if ( nWinStyle & WB_BOTTOM )
    {
        nYOffset = rSize.Height() - aUnion.GetHeight();
    }

    // the top left corner should always be visible, so we don't allow negative offsets
    if ( nXOffset < 0 ) nXOffset = 0;
    if ( nYOffset < 0 ) nYOffset = 0;

    aImagePos.X() += nXOffset;
    aImagePos.Y() += nYOffset;
    aTextPos.X() += nXOffset;
    aTextPos.Y() += nYOffset;

    // set rPos and rSize to the union
    rSize = aUnion.GetSize();
    rPos.X() += nXOffset;
    rPos.Y() += nYOffset;

    if ( bHasSymbol )
    {
        if ( mpButtonData->meSymbolAlign == SYMBOLALIGN_RIGHT )
        {
            Point aRightPos = Point( aTextPos.X() + aTextSize.Width() + aSymbolSize.Width()/2, aTextPos.Y() );
            *pSymbolRect = Rectangle( aRightPos, aSymbolSize );
        }
        else
        {
            *pSymbolRect = Rectangle( aTextPos, aSymbolSize );
            aTextPos.X() += ( 3 * nSymbolHeight / 2 );
        }
        if ( mpButtonData->mbSmallSymbol )
        {
            nYOffset = (aUnion.GetHeight() - aSymbolSize.Height())/2;
            pSymbolRect->setY( aTextPos.Y() + nYOffset );
        }
    }

    sal_uInt16 nStyle = 0;

    if ( ! ( nDrawFlags & WINDOW_DRAW_NODISABLE ) &&
         ! IsEnabled() )
        nStyle |= IMAGE_DRAW_DISABLE;

    if ( pBitmapEx && ( pDev->GetOutDevType() == OUTDEV_PRINTER ) )
    {
        // Fuer die BitmapEx ueberlegt sich KA noch, wie man die disablete
        // Darstellung hinbekommt...
        pBitmapEx->Draw( pDev, aImagePos, aImageSize /*, nStyle*/ );
    }
    else
    {
        if ( IsZoom() )
            pDev->DrawImage( aImagePos, aImageSize, *pImage, nStyle );
        else
            pDev->DrawImage( aImagePos, *pImage, nStyle );
    }

    if ( bDrawText )
    {
        ImplSetFocusRect( Rectangle( aTextPos, aTextSize ) );
        pDev->DrawText( Rectangle( aTextPos, aTextSize ), aText, nTextStyle, pVector, pDisplayText );
    }
    else
    {
        ImplSetFocusRect( Rectangle( aImagePos, aImageSize ) );
    }
}

// -----------------------------------------------------------------------
void Button::ImplSetFocusRect( const Rectangle &rFocusRect )
{
    Rectangle aFocusRect = rFocusRect;
    Rectangle aOutputRect = Rectangle( Point(), GetOutputSizePixel() );

    if ( ! aFocusRect.IsEmpty() )
    {
        aFocusRect.Left()--;
        aFocusRect.Top()--;
        aFocusRect.Right()++;
        aFocusRect.Bottom()++;
    }

    if ( aFocusRect.Left() < aOutputRect.Left() )   aFocusRect.Left() = aOutputRect.Left();
    if ( aFocusRect.Top() < aOutputRect.Top() )     aFocusRect.Top() = aOutputRect.Top();
    if ( aFocusRect.Right() > aOutputRect.Right() ) aFocusRect.Right() = aOutputRect.Right();
    if ( aFocusRect.Bottom() > aOutputRect.Bottom() ) aFocusRect.Bottom() = aOutputRect.Bottom();

    mpButtonData->maFocusRect = aFocusRect;
}

// -----------------------------------------------------------------------
const Rectangle& Button::ImplGetFocusRect() const
{
    return mpButtonData->maFocusRect;
}

// -----------------------------------------------------------------------
sal_uInt16& Button::ImplGetButtonState()
{
    return mpButtonData->mnButtonState;
}

// -----------------------------------------------------------------------
sal_uInt16 Button::ImplGetButtonState() const
{
    return mpButtonData->mnButtonState;
}

// -----------------------------------------------------------------------
void Button::ImplSetSymbolAlign( SymbolAlign eAlign )
{
    if ( mpButtonData->meSymbolAlign != eAlign )
    {
        mpButtonData->meSymbolAlign = eAlign;
        StateChanged( STATE_CHANGE_DATA );
    }
}

// -----------------------------------------------------------------------
SymbolAlign Button::ImplGetSymbolAlign() const
{
    return mpButtonData->meSymbolAlign;
}
// -----------------------------------------------------------------------
void Button::ImplSetSmallSymbol( sal_Bool bSmall )
{
    mpButtonData->mbSmallSymbol = bSmall;
}

// -----------------------------------------------------------------------
void Button::EnableImageDisplay( sal_Bool bEnable )
{
    if( bEnable )
        mpButtonData->mnButtonState &= ~BUTTON_DRAW_NOIMAGE;
    else
        mpButtonData->mnButtonState |= BUTTON_DRAW_NOIMAGE;
}

// -----------------------------------------------------------------------
sal_Bool Button::IsImageDisplayEnabled()
{
    return (mpButtonData->mnButtonState & BUTTON_DRAW_NOIMAGE) == 0;
}

// -----------------------------------------------------------------------
void Button::EnableTextDisplay( sal_Bool bEnable )
{
    if( bEnable )
        mpButtonData->mnButtonState &= ~BUTTON_DRAW_NOTEXT;
    else
        mpButtonData->mnButtonState |= BUTTON_DRAW_NOTEXT;
}

// -----------------------------------------------------------------------
sal_Bool Button::IsTextDisplayEnabled()
{
    return (mpButtonData->mnButtonState & BUTTON_DRAW_NOTEXT) == 0;
}

// -----------------------------------------------------------------------
void Button::SetSmallSymbol (bool small)
{
    ImplSetSmallSymbol (small);
}

bool Button::IsSmallSymbol () const
{
    return mpButtonData->mbSmallSymbol;
}

// =======================================================================

void PushButton::ImplInitPushButtonData()
{
    mpWindowImpl->mbPushButton    = sal_True;

    meSymbol        = SYMBOL_NOSYMBOL;
    meState         = STATE_NOCHECK;
    meSaveValue     = STATE_NOCHECK;
    mnDDStyle       = 0;
    mbPressed       = sal_False;
    mbInUserDraw    = sal_False;
}

// -----------------------------------------------------------------------

void PushButton::ImplInit( Window* pParent, WinBits nStyle )
{
    nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle );
    Button::ImplInit( pParent, nStyle, NULL );

    if ( nStyle & WB_NOLIGHTBORDER )
        ImplGetButtonState() |= BUTTON_DRAW_NOLIGHTBORDER;

    ImplInitSettings( sal_True, sal_True, sal_True );
}

// -----------------------------------------------------------------------

WinBits PushButton::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle )
{
    if ( !(nStyle & WB_NOTABSTOP) )
        nStyle |= WB_TABSTOP;

    // if no alignment is given, default to "vertically centered". This is because since
    // #i26046#, we respect the vertical alignment flags (previously we didn't completely),
    // but we of course want to look as before when no vertical alignment is specified
    if ( ( nStyle & ( WB_TOP | WB_VCENTER | WB_BOTTOM ) ) == 0 )
        nStyle |= WB_VCENTER;

    if ( !(nStyle & WB_NOGROUP) &&
         (!pPrevWindow ||
          ((pPrevWindow->GetType() != WINDOW_PUSHBUTTON) &&
           (pPrevWindow->GetType() != WINDOW_OKBUTTON) &&
           (pPrevWindow->GetType() != WINDOW_CANCELBUTTON) &&
           (pPrevWindow->GetType() != WINDOW_HELPBUTTON)) ) )
        nStyle |= WB_GROUP;
    return nStyle;
}

// -----------------------------------------------------------------

const Font& PushButton::GetCanonicalFont( const StyleSettings& _rStyle ) const
{
    return _rStyle.GetPushButtonFont();
}

// -----------------------------------------------------------------
const Color& PushButton::GetCanonicalTextColor( const StyleSettings& _rStyle ) const
{
    return _rStyle.GetButtonTextColor();
}

// -----------------------------------------------------------------------

void PushButton::ImplInitSettings( sal_Bool bFont,
                                   sal_Bool bForeground, sal_Bool bBackground )
{
    Button::ImplInitSettings( bFont, bForeground );

    if ( bBackground )
    {
        SetBackground();
        // #i38498#: do not check for GetParent()->IsChildTransparentModeEnabled()
        // otherwise the formcontrol button will be overdrawn due to PARENTCLIPMODE_NOCLIP
        // for radio and checkbox this is ok as they shoud appear transparent in documents
        if ( IsNativeControlSupported( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL ) ||
             (GetStyle() & WB_FLATBUTTON) != 0 )
        {
            EnableChildTransparentMode( sal_True );
            SetParentClipMode( PARENTCLIPMODE_NOCLIP );
            SetPaintTransparent( sal_True );
            mpWindowImpl->mbUseNativeFocus = (GetStyle() & WB_FLATBUTTON)
                ? false
                : ImplGetSVData()->maNWFData.mbNoFocusRects;
        }
        else
        {
            EnableChildTransparentMode( sal_False );
            SetParentClipMode( 0 );
            SetPaintTransparent( sal_False );
        }
    }
}

// -----------------------------------------------------------------------

void PushButton::ImplDrawPushButtonFrame( Window* pDev,
                                          Rectangle& rRect, sal_uInt16 nStyle )
{
    if ( !(pDev->GetStyle() & (WB_RECTSTYLE | WB_SMALLSTYLE)) )
    {
        StyleSettings aStyleSettings = pDev->GetSettings().GetStyleSettings();
        if ( pDev->IsControlBackground() )
            aStyleSettings.Set3DColors( pDev->GetControlBackground() );
    }

    DecorationView aDecoView( pDev );
    if ( pDev->IsControlBackground() )
    {
        AllSettings     aSettings = pDev->GetSettings();
        AllSettings     aOldSettings = aSettings;
        StyleSettings   aStyleSettings = aSettings.GetStyleSettings();
        aStyleSettings.Set3DColors( pDev->GetControlBackground() );
        aSettings.SetStyleSettings( aStyleSettings );
        pDev->OutputDevice::SetSettings( aSettings );
        rRect = aDecoView.DrawButton( rRect, nStyle );
        pDev->OutputDevice::SetSettings( aOldSettings );
    }
    else
        rRect = aDecoView.DrawButton( rRect, nStyle );
}

// -----------------------------------------------------------------------

sal_Bool PushButton::ImplHitTestPushButton( Window* pDev,
                                        const Point& rPos )
{
    Point       aTempPoint;
    Rectangle   aTestRect( aTempPoint, pDev->GetOutputSizePixel() );

    return aTestRect.IsInside( rPos );
}

// -----------------------------------------------------------------------

sal_uInt16 PushButton::ImplGetTextStyle( sal_uLong nDrawFlags ) const
{
    const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();

    sal_uInt16 nTextStyle = TEXT_DRAW_MNEMONIC | TEXT_DRAW_MULTILINE | TEXT_DRAW_ENDELLIPSIS;

    if ( ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO ) ||
         ( nDrawFlags & WINDOW_DRAW_MONO ) )
        nTextStyle |= TEXT_DRAW_MONO;

    if ( GetStyle() & WB_WORDBREAK )
        nTextStyle |= TEXT_DRAW_WORDBREAK;
    if ( GetStyle() & WB_NOLABEL )
        nTextStyle &= ~TEXT_DRAW_MNEMONIC;

    if ( GetStyle() & WB_LEFT )
        nTextStyle |= TEXT_DRAW_LEFT;
    else if ( GetStyle() & WB_RIGHT )
        nTextStyle |= TEXT_DRAW_RIGHT;
    else
        nTextStyle |= TEXT_DRAW_CENTER;

    if ( GetStyle() & WB_TOP )
        nTextStyle |= TEXT_DRAW_TOP;
    else if ( GetStyle() & WB_BOTTOM )
        nTextStyle |= TEXT_DRAW_BOTTOM;
    else
        nTextStyle |= TEXT_DRAW_VCENTER;

    if ( ! ( (nDrawFlags & WINDOW_DRAW_NODISABLE) || IsEnabled() ) )
        nTextStyle |= TEXT_DRAW_DISABLE;

    return nTextStyle;
}

// -----------------------------------------------------------------------

static void ImplDrawBtnDropDownArrow( OutputDevice* pDev,
                                      long nX, long nY,
                                      Color& rColor, sal_Bool bBlack )
{
    Color aOldLineColor = pDev->GetLineColor();
    Color aOldFillColor = pDev->GetFillColor();

    pDev->SetLineColor();
    if ( bBlack )
        pDev->SetFillColor( Color( COL_BLACK ) );
    else
        pDev->SetFillColor( rColor );
    pDev->DrawRect( Rectangle( nX+0, nY+0, nX+6, nY+0 ) );
    pDev->DrawRect( Rectangle( nX+1, nY+1, nX+5, nY+1 ) );
    pDev->DrawRect( Rectangle( nX+2, nY+2, nX+4, nY+2 ) );
    pDev->DrawRect( Rectangle( nX+3, nY+3, nX+3, nY+3 ) );
    if ( bBlack )
    {
        pDev->SetFillColor( rColor );
        pDev->DrawRect( Rectangle( nX+2, nY+1, nX+4, nY+1 ) );
        pDev->DrawRect( Rectangle( nX+3, nY+2, nX+3, nY+2 ) );
    }
    pDev->SetLineColor( aOldLineColor );
    pDev->SetFillColor( aOldFillColor );
}

// -----------------------------------------------------------------------

void PushButton::ImplDrawPushButtonContent( OutputDevice* pDev, sal_uLong nDrawFlags,
                                            const Rectangle& rRect,
                                            bool bLayout,
                                            bool bMenuBtnSep
                                            )
{
    const StyleSettings&    rStyleSettings = GetSettings().GetStyleSettings();
    Rectangle               aInRect = rRect;
    Color                   aColor;
    XubString               aText = PushButton::GetText(); // PushButton:: wegen MoreButton
    sal_uInt16                  nTextStyle = ImplGetTextStyle( nDrawFlags );
    sal_uInt16                  nStyle;

    if( aInRect.nRight < aInRect.nLeft || aInRect.nBottom < aInRect.nTop )
        aInRect.SetEmpty();

    pDev->Push( PUSH_CLIPREGION );
    pDev->IntersectClipRegion( aInRect );

    if ( nDrawFlags & WINDOW_DRAW_MONO )
        aColor = Color( COL_BLACK );
    else if ( IsControlForeground() )
        aColor = GetControlForeground();
    else if( nDrawFlags & WINDOW_DRAW_ROLLOVER )
        aColor = rStyleSettings.GetButtonRolloverTextColor();
    else
        aColor = rStyleSettings.GetButtonTextColor();

    pDev->SetTextColor( aColor );

    if ( IsEnabled() || (nDrawFlags & WINDOW_DRAW_NODISABLE) )
        nStyle = 0;
    else
        nStyle = SYMBOL_DRAW_DISABLE;

    Size aSize = rRect.GetSize();
    Point aPos = rRect.TopLeft();

    sal_uLong nImageSep = 1 + (pDev->GetTextHeight()-10)/2;
    if( nImageSep < 1 )
        nImageSep = 1;
    if ( mnDDStyle == PUSHBUTTON_DROPDOWN_MENUBUTTON )
    {
        if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
        {
            // calc Symbol- and Textrect
            long nSymbolSize    = pDev->GetTextHeight() / 2 + 1;
            aInRect.Right()    -= 5;
            aInRect.Left()      = aInRect.Right() - nSymbolSize;
            aSize.Width()      -= ( 5 + nSymbolSize );

            ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, nImageSep,
                                  nDrawFlags, nTextStyle, NULL, true );
        }
        else
            ImplCalcSymbolRect( aInRect );

        if( ! bLayout )
        {
            long nDistance = (aInRect.GetHeight() > 10) ? 2 : 1;
            DecorationView aDecoView( pDev );
            if( bMenuBtnSep )
            {
                long nX = aInRect.Left() - 2*nDistance;;
                Point aStartPt( nX, aInRect.Top()+nDistance );
                Point aEndPt( nX, aInRect.Bottom()-nDistance );
                aDecoView.DrawSeparator( aStartPt, aEndPt );
            }
            aDecoView.DrawSymbol( aInRect, SYMBOL_SPIN_DOWN, aColor, nStyle );
            aInRect.Left() -= 2*nDistance;
            ImplSetSymbolRect( aInRect );
        }
    }
    else
    {
        Rectangle aSymbolRect;
        // FIXME: (GetStyle() & WB_FLATBUTTON) != 0 is preliminary
        // in the next major this should be replaced by "true"
        ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, nImageSep, nDrawFlags,
                              nTextStyle, IsSymbol() ? &aSymbolRect : NULL, true );

        if ( IsSymbol() && ! bLayout )
        {
            DecorationView aDecoView( pDev );
            aDecoView.DrawSymbol( aSymbolRect, meSymbol, aColor, nStyle );
            ImplSetSymbolRect( aSymbolRect );
        }

        if ( mnDDStyle == PUSHBUTTON_DROPDOWN_TOOLBOX && !bLayout )
        {
            sal_Bool    bBlack = sal_False;
            Color   aArrowColor( COL_BLACK );

            if ( !(nDrawFlags & WINDOW_DRAW_MONO) )
            {
                if ( !IsEnabled() )
                    aArrowColor = rStyleSettings.GetShadowColor();
                else
                {
                    aArrowColor = Color( COL_LIGHTGREEN );
                    bBlack = sal_True;
                }
            }

            ImplDrawBtnDropDownArrow( pDev, aInRect.Right()-6, aInRect.Top()+1,
                                      aArrowColor, bBlack );
        }
    }

    UserDrawEvent aUDEvt( this, aInRect, 0 );
    UserDraw( aUDEvt );

    pDev->Pop();  // restore clipregion
}

// -----------------------------------------------------------------------

void PushButton::UserDraw( const UserDrawEvent& )
{
}

// -----------------------------------------------------------------------

void PushButton::ImplDrawPushButton( bool bLayout )
{
    if( !bLayout )
        HideFocus();

    sal_uInt16                  nButtonStyle = ImplGetButtonState();
    Point                   aPoint;
    Size                    aOutSz( GetOutputSizePixel() );
    Rectangle               aRect( aPoint, aOutSz );
    Rectangle               aInRect = aRect;
    Rectangle               aTextRect;
    sal_Bool                    bNativeOK = sal_False;

    // adjust style if button should be rendered 'pressed'
    if ( mbPressed )
        nButtonStyle |= BUTTON_DRAW_PRESSED;

    // TODO: move this to Window class or make it a member !!!
    ControlType aCtrlType = 0;
    switch( GetParent()->GetType() )
    {
        case WINDOW_LISTBOX:
        case WINDOW_MULTILISTBOX:
        case WINDOW_TREELISTBOX:
            aCtrlType = CTRL_LISTBOX;
            break;

        case WINDOW_COMBOBOX:
        case WINDOW_PATTERNBOX:
        case WINDOW_NUMERICBOX:
        case WINDOW_METRICBOX:
        case WINDOW_CURRENCYBOX:
        case WINDOW_DATEBOX:
        case WINDOW_TIMEBOX:
        case WINDOW_LONGCURRENCYBOX:
            aCtrlType = CTRL_COMBOBOX;
            break;
        default:
            break;
    }

    sal_Bool bDropDown = ( IsSymbol() && (GetSymbol()==SYMBOL_SPIN_DOWN) && !GetText().Len() );

    if( bDropDown && (aCtrlType == CTRL_COMBOBOX || aCtrlType == CTRL_LISTBOX ) )
    {
        if( GetParent()->IsNativeControlSupported( aCtrlType, PART_ENTIRE_CONTROL) )
        {
            // skip painting if the button was already drawn by the theme
            if( aCtrlType == CTRL_COMBOBOX )
            {
                Edit* pEdit = static_cast<Edit*>(GetParent());
                if( pEdit->ImplUseNativeBorder( pEdit->GetStyle() ) )
                    bNativeOK = sal_True;
            }
            else if( GetParent()->IsNativeControlSupported( aCtrlType, HAS_BACKGROUND_TEXTURE) )
            {
                bNativeOK = sal_True;
            }
            if( !bNativeOK && GetParent()->IsNativeControlSupported( aCtrlType, PART_BUTTON_DOWN ) )
            {
                // let the theme draw it, note we then need support
                // for CTRL_LISTBOX/PART_BUTTON_DOWN and CTRL_COMBOBOX/PART_BUTTON_DOWN

                ImplControlValue    aControlValue;
                ControlState        nState = 0;

                if ( mbPressed ) 						nState |= CTRL_STATE_PRESSED;
                if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )	nState |= CTRL_STATE_PRESSED;
                if ( HasFocus() )						nState |= CTRL_STATE_FOCUSED;
                if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT )	nState |= CTRL_STATE_DEFAULT;
                if ( Window::IsEnabled() ) 				nState |= CTRL_STATE_ENABLED;

                if ( IsMouseOver() && aInRect.IsInside( GetPointerPosPixel() ) )
                    nState |= CTRL_STATE_ROLLOVER;

                bNativeOK = DrawNativeControl( aCtrlType, PART_BUTTON_DOWN, aInRect, nState,
                                                aControlValue, rtl::OUString() );
            }
        }
    }

    if( bNativeOK )
        return;

    bool bRollOver = (IsMouseOver() && aInRect.IsInside( GetPointerPosPixel() ));
    bool bDrawMenuSep = true;
    if( (GetStyle() & WB_FLATBUTTON) )
    {
        if( ! bRollOver && ! HasFocus() )
            bDrawMenuSep = false;
    }
    if ( (bNativeOK=IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL)) == sal_True )
    {
        PushButtonValue aControlValue;
        Rectangle		 aCtrlRegion( aInRect );
        ControlState	 nState = 0;

        if ( mbPressed || IsChecked() )                   nState |= CTRL_STATE_PRESSED;
        if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) nState |= CTRL_STATE_PRESSED;
        if ( HasFocus() )						nState |= CTRL_STATE_FOCUSED;
        if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT )	nState |= CTRL_STATE_DEFAULT;
        if ( Window::IsEnabled() ) 				nState |= CTRL_STATE_ENABLED;

        if ( bRollOver )
            nState |= CTRL_STATE_ROLLOVER;
        
        if( GetStyle() & WB_BEVELBUTTON )
            aControlValue.mbBevelButton = true;

        // draw frame into invisible window to have aInRect modified correctly
        // but do not shift the inner rect for pressed buttons (ie remove BUTTON_DRAW_PRESSED)
        // this assumes the theme has enough visual cues to signalize the button was pressed
        //Window aWin( this );
        //ImplDrawPushButtonFrame( &aWin, aInRect, nButtonStyle & ~BUTTON_DRAW_PRESSED );

        // looks better this way as symbols were displaced slightly using the above approach
        aInRect.Top()+=4;
        aInRect.Bottom()-=4;
        aInRect.Left()+=4;
        aInRect.Right()-=4;
        
        // prepare single line hint (needed on mac to decide between normal push button and
        // rectangular bevel button look)
        Size aFontSize( Application::GetSettings().GetStyleSettings().GetPushButtonFont().GetSize() );
        aFontSize = LogicToPixel( aFontSize, MapMode( MAP_POINT ) );
        Size aInRectSize( LogicToPixel( Size( aInRect.GetWidth(), aInRect.GetHeight() ) ) );
        aControlValue.mbSingleLine = (aInRectSize.Height() < 2 * aFontSize.Height() );

        if( ((nState & CTRL_STATE_ROLLOVER)) || ! (GetStyle() & WB_FLATBUTTON) )
        {
            bNativeOK = DrawNativeControl( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, nState,
                            aControlValue, rtl::OUString()/*PushButton::GetText()*/ );
        }
        else
        {
            bNativeOK = true;
        }

        // draw content using the same aInRect as non-native VCL would do
        ImplDrawPushButtonContent( this,
                                   (nState&CTRL_STATE_ROLLOVER) ? WINDOW_DRAW_ROLLOVER : 0,
                                   aInRect, bLayout, bDrawMenuSep );

        if ( HasFocus() )
            ShowFocus( ImplGetFocusRect() );
    }

    if ( bNativeOK == sal_False )
    {
        // draw PushButtonFrame, aInRect has content size afterwards
        if( (GetStyle() & WB_FLATBUTTON) )
        {
            Rectangle aTempRect( aInRect );
            if( ! bLayout && bRollOver )
                ImplDrawPushButtonFrame( this, aTempRect, nButtonStyle );
            aInRect.Left()   += 2;
            aInRect.Top()    += 2;
            aInRect.Right()  -= 2;
            aInRect.Bottom() -= 2;
        }
        else
        {
            if( ! bLayout )
                ImplDrawPushButtonFrame( this, aInRect, nButtonStyle );
        }

        // draw content
        ImplDrawPushButtonContent( this, 0, aInRect, bLayout, bDrawMenuSep );

        if( ! bLayout && HasFocus() )
        {
            ShowFocus( ImplGetFocusRect() );
        }
    }
}

// -----------------------------------------------------------------------

void PushButton::ImplSetDefButton( sal_Bool bSet )
{
    Size aSize( GetSizePixel() );
    Point aPos( GetPosPixel() );
    int dLeft(0), dRight(0), dTop(0), dBottom(0);
    sal_Bool bSetPos = sal_False;

    if ( (IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL)) == sal_True )
    {
        Rectangle aBound, aCont;
        Rectangle aCtrlRect( 0, 0, 80, 20 ); // use a constant size to avoid accumulating
                                             // will not work if the theme has dynamic adornment sizes
        ImplControlValue aControlValue;
        Rectangle		 aCtrlRegion( aCtrlRect );
        ControlState	 nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED;

        // get native size of a 'default' button
        // and adjust the VCL button if more space for adornment is required
        if( GetNativeControlRegion( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion,
                                nState, aControlValue, rtl::OUString(),
								aBound, aCont ) )
        {
            dLeft = aCont.Left() - aBound.Left();
            dTop = aCont.Top() - aBound.Top();
            dRight = aBound.Right() - aCont.Right();
            dBottom = aBound.Bottom() - aCont.Bottom();
            bSetPos = dLeft || dTop || dRight || dBottom;
        }
    }

    if ( bSet )
    {
        if( !(ImplGetButtonState() & BUTTON_DRAW_DEFAULT) && bSetPos )
        {
            // adjust pos/size when toggling from non-default to default
            aPos.Move(-dLeft, -dTop);
            aSize.Width() += dLeft + dRight;
            aSize.Height() += dTop + dBottom;
        }
        ImplGetButtonState() |= BUTTON_DRAW_DEFAULT;
    }
    else
    {
        if( (ImplGetButtonState() & BUTTON_DRAW_DEFAULT) && bSetPos )
        {
            // adjust pos/size when toggling from default to non-default
            aPos.Move(dLeft, dTop);
            aSize.Width() -= dLeft + dRight;
            aSize.Height() -= dTop + dBottom;
        }
        ImplGetButtonState() &= ~BUTTON_DRAW_DEFAULT;
    }
    if( bSetPos )
        SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL );

    Invalidate();
}

// -----------------------------------------------------------------------

sal_Bool PushButton::ImplIsDefButton() const
{
    return (ImplGetButtonState() & BUTTON_DRAW_DEFAULT) != 0;
}

// -----------------------------------------------------------------------

PushButton::PushButton( WindowType nType ) :
    Button( nType )
{
    ImplInitPushButtonData();
}

// -----------------------------------------------------------------------

PushButton::PushButton( Window* pParent, WinBits nStyle ) :
    Button( WINDOW_PUSHBUTTON )
{
    ImplInitPushButtonData();
    ImplInit( pParent, nStyle );
}

// -----------------------------------------------------------------------

PushButton::PushButton( Window* pParent, const ResId& rResId ) :
    Button( WINDOW_PUSHBUTTON )
{
    ImplInitPushButtonData();
    rResId.SetRT( RSC_PUSHBUTTON );
    WinBits nStyle = ImplInitRes( rResId );
    ImplInit( pParent, nStyle );
    ImplLoadRes( rResId );

    if ( !(nStyle & WB_HIDE) )
        Show();
}

// -----------------------------------------------------------------------

PushButton::~PushButton()
{
}

// -----------------------------------------------------------------------

void PushButton::MouseButtonDown( const MouseEvent& rMEvt )
{
    if ( rMEvt.IsLeft() &&
         ImplHitTestPushButton( this, rMEvt.GetPosPixel() ) )
    {
        sal_uInt16 nTrackFlags = 0;

        if ( ( GetStyle() & WB_REPEAT ) &&
             ! ( GetStyle() & WB_TOGGLE ) )
            nTrackFlags |= STARTTRACK_BUTTONREPEAT;

        ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
        ImplDrawPushButton();
        StartTracking( nTrackFlags );

        if ( nTrackFlags & STARTTRACK_BUTTONREPEAT )
            Click();
    }
}

// -----------------------------------------------------------------------

void PushButton::Tracking( const TrackingEvent& rTEvt )
{
    if ( rTEvt.IsTrackingEnded() )
    {
        if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
        {
            if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
                GrabFocus();

            if ( GetStyle() & WB_TOGGLE )
            {
                // Don't toggle, when aborted
                if ( !rTEvt.IsTrackingCanceled() )
                {
                    if ( IsChecked() )
                    {
                        Check( sal_False );
                        ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
                    }
                    else
                        Check( sal_True );
                }
            }
            else
                ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;

            ImplDrawPushButton();

            // Bei Abbruch kein Click-Handler rufen
            if ( !rTEvt.IsTrackingCanceled() )
            {
                if ( ! ( ( GetStyle() & WB_REPEAT ) &&
                         ! ( GetStyle() & WB_TOGGLE ) ) )
                    Click();
            }
        }
    }
    else
    {
        if ( ImplHitTestPushButton( this, rTEvt.GetMouseEvent().GetPosPixel() ) )
        {
            if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
            {
                if ( rTEvt.IsTrackingRepeat() && (GetStyle() & WB_REPEAT) &&
                     ! ( GetStyle() & WB_TOGGLE ) )
                    Click();
            }
            else
            {
                ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
                ImplDrawPushButton();
            }
        }
        else
        {
            if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
            {
                ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
                ImplDrawPushButton();
            }
        }
    }
}

// -----------------------------------------------------------------------

void PushButton::KeyInput( const KeyEvent& rKEvt )
{
    KeyCode aKeyCode = rKEvt.GetKeyCode();

    if ( !aKeyCode.GetModifier() &&
         ((aKeyCode.GetCode() == KEY_RETURN) || (aKeyCode.GetCode() == KEY_SPACE)) )
    {
        if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
        {
            ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
            ImplDrawPushButton();
        }

        if ( ( GetStyle() & WB_REPEAT ) &&
             ! ( GetStyle() & WB_TOGGLE ) )
            Click();
    }
    else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) )
    {
        ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
        ImplDrawPushButton();
    }
    else
        Button::KeyInput( rKEvt );
}

// -----------------------------------------------------------------------

void PushButton::KeyUp( const KeyEvent& rKEvt )
{
    KeyCode aKeyCode = rKEvt.GetKeyCode();

    if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) &&
         ((aKeyCode.GetCode() == KEY_RETURN) || (aKeyCode.GetCode() == KEY_SPACE)) )
    {
        if ( GetStyle() & WB_TOGGLE )
        {
            if ( IsChecked() )
            {
                Check( sal_False );
                ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
            }
            else
                Check( sal_True );

            Toggle();
        }
        else
            ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;

        ImplDrawPushButton();

        if ( !( ( GetStyle() & WB_REPEAT )  &&
                ! ( GetStyle() & WB_TOGGLE ) ) )
            Click();
    }
    else
        Button::KeyUp( rKEvt );
}

// -----------------------------------------------------------------------

void PushButton::FillLayoutData() const
{
    mpControlData->mpLayoutData = new vcl::ControlLayoutData();
    const_cast<PushButton*>(this)->ImplDrawPushButton( true );
}

// -----------------------------------------------------------------------

void PushButton::Paint( const Rectangle& )
{
    ImplDrawPushButton();
}

// -----------------------------------------------------------------------

void PushButton::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
                       sal_uLong nFlags )
{
    Point       aPos  = pDev->LogicToPixel( rPos );
    Size        aSize = pDev->LogicToPixel( rSize );
    Rectangle   aRect( aPos, aSize );
    Rectangle   aTextRect;
    Font        aFont = GetDrawPixelFont( pDev );

    pDev->Push();
    pDev->SetMapMode();
    pDev->SetFont( aFont );
    if ( nFlags & WINDOW_DRAW_MONO )
	{
        pDev->SetTextColor( Color( COL_BLACK ) );
	}
    else
	{
        pDev->SetTextColor( GetTextColor() );

		// DecoView uses the FaceColor...
		AllSettings aSettings = pDev->GetSettings();
		StyleSettings aStyleSettings = aSettings.GetStyleSettings();
		if ( IsControlBackground() )
			aStyleSettings.SetFaceColor( GetControlBackground() );
		else
			aStyleSettings.SetFaceColor( GetSettings().GetStyleSettings().GetFaceColor() );
		aSettings.SetStyleSettings( aStyleSettings );
		pDev->SetSettings( aSettings );
	}
    pDev->SetTextFillColor();

    DecorationView aDecoView( pDev );
    sal_uInt16 nButtonStyle = 0;
    if ( nFlags & WINDOW_DRAW_MONO )
        nButtonStyle |= BUTTON_DRAW_MONO;
    if ( IsChecked() )
        nButtonStyle |= BUTTON_DRAW_CHECKED;
    aRect = aDecoView.DrawButton( aRect, nButtonStyle );

    ImplDrawPushButtonContent( pDev, nFlags, aRect, false, true );
    pDev->Pop();
}

// -----------------------------------------------------------------------

void PushButton::Resize()
{
    Control::Resize();
    Invalidate();
}

// -----------------------------------------------------------------------

void PushButton::GetFocus()
{
    ShowFocus( ImplGetFocusRect() );
    SetInputContext( InputContext( GetFont() ) );
    Button::GetFocus();
}

// -----------------------------------------------------------------------

void PushButton::LoseFocus()
{
    EndSelection();
    HideFocus();
    Button::LoseFocus();
}

// -----------------------------------------------------------------------

void PushButton::StateChanged( StateChangedType nType )
{
    Button::StateChanged( nType );

    if ( (nType == STATE_CHANGE_ENABLE) ||
         (nType == STATE_CHANGE_TEXT) ||
         (nType == STATE_CHANGE_IMAGE) ||
         (nType == STATE_CHANGE_DATA) ||
         (nType == STATE_CHANGE_STATE) ||
         (nType == STATE_CHANGE_UPDATEMODE) )
    {
        if ( IsReallyVisible() && IsUpdateMode() )
            Invalidate();
    }
    else if ( nType == STATE_CHANGE_STYLE )
    {
        SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) );

        bool bIsDefButton = ( GetStyle() & WB_DEFBUTTON ) != 0;
        bool bWasDefButton = ( GetPrevStyle() & WB_DEFBUTTON ) != 0;
        if ( bIsDefButton != bWasDefButton )
            ImplSetDefButton( bIsDefButton );

        if ( IsReallyVisible() && IsUpdateMode() )
        {
            if ( (GetPrevStyle() & PUSHBUTTON_VIEW_STYLE) !=
                 (GetStyle() & PUSHBUTTON_VIEW_STYLE) )
                Invalidate();
        }
    }
    else if ( (nType == STATE_CHANGE_ZOOM) ||
              (nType == STATE_CHANGE_CONTROLFONT) )
    {
        ImplInitSettings( sal_True, sal_False, sal_False );
        Invalidate();
    }
    else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
    {
        ImplInitSettings( sal_False, sal_True, sal_False );
        Invalidate();
    }
    else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
    {
        ImplInitSettings( sal_False, sal_False, sal_True );
        Invalidate();
    }
}

// -----------------------------------------------------------------------

void PushButton::DataChanged( const DataChangedEvent& rDCEvt )
{
    Button::DataChanged( rDCEvt );

    if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
         (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
         ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
          (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
    {
        ImplInitSettings( sal_True, sal_True, sal_True );
        Invalidate();
    }
}

// -----------------------------------------------------------------------

long PushButton::PreNotify( NotifyEvent& rNEvt )
{
    long nDone = 0;
    const MouseEvent* pMouseEvt = NULL;

    if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
    {
        if( pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow() )
        {
            // trigger redraw as mouse over state has changed

            // TODO: move this to Window class or make it a member !!!
            ControlType aCtrlType = 0;
            switch( GetParent()->GetType() )
            {
                case WINDOW_LISTBOX:
                case WINDOW_MULTILISTBOX:
                case WINDOW_TREELISTBOX:
                    aCtrlType = CTRL_LISTBOX;
                    break;

                case WINDOW_COMBOBOX:
                case WINDOW_PATTERNBOX:
                case WINDOW_NUMERICBOX:
                case WINDOW_METRICBOX:
                case WINDOW_CURRENCYBOX:
                case WINDOW_DATEBOX:
                case WINDOW_TIMEBOX:
                case WINDOW_LONGCURRENCYBOX:
                    aCtrlType = CTRL_COMBOBOX;
                    break;
                default:
                    break;
            }

            sal_Bool bDropDown = ( IsSymbol() && (GetSymbol()==SYMBOL_SPIN_DOWN) && !GetText().Len() );

            if( bDropDown && GetParent()->IsNativeControlSupported( aCtrlType, PART_ENTIRE_CONTROL) &&
                   !GetParent()->IsNativeControlSupported( aCtrlType, PART_BUTTON_DOWN) )
            {
                Window *pBorder = GetParent()->GetWindow( WINDOW_BORDER );
                if(aCtrlType == CTRL_COMBOBOX)
                {
                    // only paint the button part to avoid flickering of the combobox text
                    Point aPt;
                    Rectangle aClipRect( aPt, GetOutputSizePixel() );
                    aClipRect.SetPos(pBorder->ScreenToOutputPixel(OutputToScreenPixel(aClipRect.TopLeft())));
                    pBorder->Invalidate( aClipRect );
                }
                else
                {
                    pBorder->Invalidate( INVALIDATE_NOERASE );
                    pBorder->Update();
                }
            }
            else if( (GetStyle() & WB_FLATBUTTON) ||
                     IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL) )
            {
                Invalidate();
            }
        }
    }

    return nDone ? nDone : Button::PreNotify(rNEvt);
}

// -----------------------------------------------------------------------

void PushButton::Toggle()
{
    ImplCallEventListenersAndHandler( VCLEVENT_PUSHBUTTON_TOGGLE, maToggleHdl, this );
}

// -----------------------------------------------------------------------

void PushButton::SetSymbol( SymbolType eSymbol )
{
    if ( meSymbol != eSymbol )
    {
        meSymbol = eSymbol;
        StateChanged( STATE_CHANGE_DATA );
    }
}

// -----------------------------------------------------------------------
void PushButton::SetSymbolAlign( SymbolAlign eAlign )
{
    ImplSetSymbolAlign( eAlign );
}

// -----------------------------------------------------------------------
SymbolAlign PushButton::GetSymbolAlign() const
{
    return ImplGetSymbolAlign();
}

// -----------------------------------------------------------------------

void PushButton::SetDropDown( sal_uInt16 nStyle )
{
    if ( mnDDStyle != nStyle )
    {
        mnDDStyle = nStyle;
        StateChanged( STATE_CHANGE_DATA );
    }
}

// -----------------------------------------------------------------------

void PushButton::SetState( TriState eState )
{
    if ( meState != eState )
    {
        meState = eState;
        if ( meState == STATE_NOCHECK )
            ImplGetButtonState() &= ~(BUTTON_DRAW_CHECKED | BUTTON_DRAW_DONTKNOW);
        else if ( meState == STATE_CHECK )
        {
            ImplGetButtonState() &= ~BUTTON_DRAW_DONTKNOW;
            ImplGetButtonState() |= BUTTON_DRAW_CHECKED;
        }
        else // STATE_DONTKNOW
        {
            ImplGetButtonState() &= ~BUTTON_DRAW_CHECKED;
            ImplGetButtonState() |= BUTTON_DRAW_DONTKNOW;
        }

        StateChanged( STATE_CHANGE_STATE );
        Toggle();
    }
}

// -----------------------------------------------------------------------

void PushButton::SetPressed( sal_Bool bPressed )
{
    if ( mbPressed != bPressed )
    {
        mbPressed = bPressed;
        StateChanged( STATE_CHANGE_DATA );
    }
}

// -----------------------------------------------------------------------

void PushButton::EndSelection()
{
    EndTracking( ENDTRACK_CANCEL );
    if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
    {
        ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
        if ( !mbPressed )
            ImplDrawPushButton();
    }
}

// -----------------------------------------------------------------------

Size PushButton::CalcMinimumSize( long nMaxWidth ) const
{
	Size aSize;

	if ( IsSymbol() )
    {
        if ( IsSmallSymbol ())
            aSize = Size( 16, 12 );
        else
            aSize = Size( 26, 24 );
        if( mnDDStyle == PUSHBUTTON_DROPDOWN_MENUBUTTON )
            aSize.Width() += 4;
    }
	else if ( IsImage() && ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) )
		aSize = GetModeImage().GetSizePixel();
	if ( PushButton::GetText().Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
	{
		sal_uLong nDrawFlags = 0;
		Size textSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
									 PushButton::GetText(), ImplGetTextStyle( nDrawFlags ) ).GetSize();
	   aSize.Width() += int( textSize.Width () * 1.15 );
	   aSize.Height() = std::max( aSize.Height(), long( textSize.Height() * 1.15 ) );
	}

	// cf. ImplDrawPushButton ...
    if( (GetStyle() & WB_SMALLSTYLE) == 0 )
    {
        aSize.Width() += 8;
        aSize.Height() += 8;
    }

    return CalcWindowSize( aSize );
}    

Size PushButton::GetOptimalSize(WindowSizeType eType) const
{
    switch (eType) {
    case WINDOWSIZE_MINIMUM: {
        return CalcMinimumSize();
    }
    default:
        return Button::GetOptimalSize( eType );
    }
}

// =======================================================================

void OKButton::ImplInit( Window* pParent, WinBits nStyle )
{
    PushButton::ImplInit( pParent, nStyle );

    SetText( Button::GetStandardText( BUTTON_OK ) );
    SetHelpText( Button::GetStandardHelpText( BUTTON_OK ) );
}

// -----------------------------------------------------------------------

OKButton::OKButton( Window* pParent, WinBits nStyle ) :
    PushButton( WINDOW_OKBUTTON )
{
    ImplInit( pParent, nStyle );
}

// -----------------------------------------------------------------------

OKButton::OKButton( Window* pParent, const ResId& rResId ) :
    PushButton( WINDOW_OKBUTTON )
{
    rResId.SetRT( RSC_OKBUTTON );
    WinBits nStyle = ImplInitRes( rResId );
    ImplInit( pParent, nStyle );
    ImplLoadRes( rResId );

    if ( !(nStyle & WB_HIDE) )
        Show();
}

// -----------------------------------------------------------------------

void OKButton::Click()
{
    // Ist kein Link gesetzt, dann schliesse Parent
    if ( !GetClickHdl() )
    {
        Window* pParent = GetParent();
        if ( pParent->IsSystemWindow() )
        {
            if ( pParent->IsDialog() )
            {
                if ( ((Dialog*)pParent)->IsInExecute() )
                    ((Dialog*)pParent)->EndDialog( sal_True );
                // gegen rekursive Aufrufe schuetzen
                else if ( !((Dialog*)pParent)->IsInClose() )
                {
                    if ( pParent->GetStyle() & WB_CLOSEABLE )
                        ((Dialog*)pParent)->Close();
                }
            }
            else
            {
                if ( pParent->GetStyle() & WB_CLOSEABLE )
                    ((SystemWindow*)pParent)->Close();
            }
        }
    }
    else
    {
        PushButton::Click();
    }
}

// =======================================================================

void CancelButton::ImplInit( Window* pParent, WinBits nStyle )
{
    PushButton::ImplInit( pParent, nStyle );

    SetText( Button::GetStandardText( BUTTON_CANCEL ) );
    SetHelpText( Button::GetStandardHelpText( BUTTON_CANCEL ) );
}

// -----------------------------------------------------------------------

CancelButton::CancelButton( Window* pParent, WinBits nStyle ) :
    PushButton( WINDOW_CANCELBUTTON )
{
    ImplInit( pParent, nStyle );
}

// -----------------------------------------------------------------------

CancelButton::CancelButton( Window* pParent, const ResId& rResId ) :
    PushButton( WINDOW_CANCELBUTTON )
{
    rResId.SetRT( RSC_CANCELBUTTON );
    WinBits nStyle = ImplInitRes( rResId );
    ImplInit( pParent, nStyle );
    ImplLoadRes( rResId );

    if ( !(nStyle & WB_HIDE) )
        Show();
}

// -----------------------------------------------------------------------

void CancelButton::Click()
{
    // Ist kein Link gesetzt, dann schliesse Parent
    if ( !GetClickHdl() )
    {
        Window* pParent = GetParent();
        if ( pParent->IsSystemWindow() )
        {
            if ( pParent->IsDialog() )
            {
                if ( ((Dialog*)pParent)->IsInExecute() )
                    ((Dialog*)pParent)->EndDialog( sal_False );
                // gegen rekursive Aufrufe schuetzen
                else if ( !((Dialog*)pParent)->IsInClose() )
                {
                    if ( pParent->GetStyle() & WB_CLOSEABLE )
                        ((Dialog*)pParent)->Close();
                }
            }
            else
            {
                if ( pParent->GetStyle() & WB_CLOSEABLE )
                    ((SystemWindow*)pParent)->Close();
            }
        }
    }
    else
    {
        PushButton::Click();
    }
}

// =======================================================================

void HelpButton::ImplInit( Window* pParent, WinBits nStyle )
{
    PushButton::ImplInit( pParent, nStyle | WB_NOPOINTERFOCUS );

    SetText( Button::GetStandardText( BUTTON_HELP ) );
    SetHelpText( Button::GetStandardHelpText( BUTTON_HELP ) );
}

// -----------------------------------------------------------------------

HelpButton::HelpButton( Window* pParent, WinBits nStyle ) :
    PushButton( WINDOW_HELPBUTTON )
{
    ImplInit( pParent, nStyle );
}

// -----------------------------------------------------------------------

HelpButton::HelpButton( Window* pParent, const ResId& rResId ) :
    PushButton( WINDOW_HELPBUTTON )
{
    rResId.SetRT( RSC_HELPBUTTON );
    WinBits nStyle = ImplInitRes( rResId );
    ImplInit( pParent, nStyle );
    ImplLoadRes( rResId );

    if ( !(nStyle & WB_HIDE) )
        Show();
}

// -----------------------------------------------------------------------

void HelpButton::Click()
{
    // Ist kein Link gesetzt, loese Hilfe aus
    if ( !GetClickHdl() )
    {
        Window* pFocusWin = Application::GetFocusWindow();
        if ( !pFocusWin )
            pFocusWin = this;

        HelpEvent aEvt( pFocusWin->GetPointerPosPixel(), HELPMODE_CONTEXT );
        pFocusWin->RequestHelp( aEvt );
    }
    PushButton::Click();
}

// =======================================================================

void RadioButton::ImplInitRadioButtonData()
{
    mbChecked       = sal_False;
    mbSaveValue     = sal_False;
    mbRadioCheck    = sal_True;
    mbStateChanged  = sal_False;
}

// -----------------------------------------------------------------------

void RadioButton::ImplInit( Window* pParent, WinBits nStyle )
{
    nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle );
    Button::ImplInit( pParent, nStyle, NULL );

    ImplInitSettings( sal_True, sal_True, sal_True );
}

// -----------------------------------------------------------------------

WinBits RadioButton::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle )
{
    if ( !(nStyle & WB_NOGROUP) &&
         (!pPrevWindow || (pPrevWindow->GetType() != WINDOW_RADIOBUTTON)) )
        nStyle |= WB_GROUP;
    if ( !(nStyle & WB_NOTABSTOP) )
    {
        if ( IsChecked() )
            nStyle |= WB_TABSTOP;
        else
            nStyle &= ~WB_TABSTOP;
    }
    return nStyle;
}

// -----------------------------------------------------------------

const Font& RadioButton::GetCanonicalFont( const StyleSettings& _rStyle ) const
{
    return _rStyle.GetRadioCheckFont();
}

// -----------------------------------------------------------------
const Color& RadioButton::GetCanonicalTextColor( const StyleSettings& _rStyle ) const
{
    return _rStyle.GetRadioCheckTextColor();
}

// -----------------------------------------------------------------------

void RadioButton::ImplInitSettings( sal_Bool bFont,
                                    sal_Bool bForeground, sal_Bool bBackground )
{
    Button::ImplInitSettings( bFont, bForeground );

    if ( bBackground )
    {
        Window* pParent = GetParent();
        if ( !IsControlBackground() &&
            (pParent->IsChildTransparentModeEnabled() || IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) ) )
        {
            EnableChildTransparentMode( sal_True );
            SetParentClipMode( PARENTCLIPMODE_NOCLIP );
            SetPaintTransparent( sal_True );
            SetBackground();
            if( IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) )
                mpWindowImpl->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects;
        }
        else
        {
            EnableChildTransparentMode( sal_False );
            SetParentClipMode( 0 );
            SetPaintTransparent( sal_False );

            if ( IsControlBackground() )
                SetBackground( GetControlBackground() );
            else
                SetBackground( pParent->GetBackground() );
        }
    }
}

//---------------------------------------------------------------------
//--- 12.03.2003 18:46:14 ---------------------------------------------

void RadioButton::DrawRadioButtonState( )
{
	ImplDrawRadioButtonState( );
}

// -----------------------------------------------------------------------

void RadioButton::ImplInvalidateOrDrawRadioButtonState()
{
    if( ImplGetSVData()->maNWFData.mbCheckBoxNeedsErase )
    {
        if ( IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL) )
        {
            Invalidate();
            Update();
            return;
        }
    }
    ImplDrawRadioButtonState();
}

void RadioButton::ImplDrawRadioButtonState()
{
    sal_uInt16 nButtonStyle = 0;
    sal_Bool   bNativeOK = sal_False;

    // no native drawing for image radio buttons
    if ( !maImage && (bNativeOK=IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL)) == sal_True )
    {
        ImplControlValue		    aControlValue( mbChecked ? BUTTONVALUE_ON : BUTTONVALUE_OFF );
        Rectangle					aCtrlRect( maStateRect.TopLeft(), maStateRect.GetSize() );
        ControlState				nState = 0;

        if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )	nState |= CTRL_STATE_PRESSED;
        if ( HasFocus() ) 						nState |= CTRL_STATE_FOCUSED;
        if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT )	nState |= CTRL_STATE_DEFAULT;
        if ( IsEnabled() )						nState |= CTRL_STATE_ENABLED;

        if ( IsMouseOver() && maMouseRect.IsInside( GetPointerPosPixel() ) )
            nState |= CTRL_STATE_ROLLOVER;

        bNativeOK = DrawNativeControl( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRect, nState,
                    aControlValue,rtl::OUString() );

    }

if ( bNativeOK == sal_False )
{
    // kein Image-RadioButton
    if ( !maImage )
    {
        sal_uInt16 nStyle = ImplGetButtonState();
        if ( !IsEnabled() )
            nStyle |= BUTTON_DRAW_DISABLED;
        if ( mbChecked )
            nStyle |= BUTTON_DRAW_CHECKED;
        Image aImage = GetRadioImage( GetSettings(), nStyle );
        if ( IsZoom() )
            DrawImage( maStateRect.TopLeft(), maStateRect.GetSize(), aImage );
        else
            DrawImage( maStateRect.TopLeft(), aImage );
    }
    else
    {
        HideFocus();

        DecorationView          aDecoView( this );
        const StyleSettings&    rStyleSettings = GetSettings().GetStyleSettings();
        Rectangle               aImageRect  = maStateRect;
        Size                    aImageSize  = maImage.GetSizePixel();
        sal_Bool                    bEnabled    = IsEnabled();

        aImageSize.Width()  = CalcZoom( aImageSize.Width() );
        aImageSize.Height() = CalcZoom( aImageSize.Height() );

        // Border und Selektionsstatus ausgeben
        nButtonStyle = FRAME_DRAW_DOUBLEIN;
        aImageRect = aDecoView.DrawFrame( aImageRect, nButtonStyle );
        if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) || !bEnabled )
            SetFillColor( rStyleSettings.GetFaceColor() );
        else
            SetFillColor( rStyleSettings.GetFieldColor() );
        SetLineColor();
        DrawRect( aImageRect );

        // Image ausgeben
        nButtonStyle = 0;
        if ( !bEnabled )
            nButtonStyle |= IMAGE_DRAW_DISABLE;

		// check for HC mode
		Image *pImage = &maImage;
		if( !!maImageHC )
		{
			if( rStyleSettings.GetHighContrastMode() )
				pImage = &maImageHC;
		}

        Point aImagePos( aImageRect.TopLeft() );
        aImagePos.X() += (aImageRect.GetWidth()-aImageSize.Width())/2;
        aImagePos.Y() += (aImageRect.GetHeight()-aImageSize.Height())/2;
        if ( IsZoom() )
            DrawImage( aImagePos, aImageSize, *pImage, nButtonStyle );
        else
            DrawImage( aImagePos, *pImage, nButtonStyle );

        aImageRect.Left()++;
        aImageRect.Top()++;
        aImageRect.Right()--;
        aImageRect.Bottom()--;

        ImplSetFocusRect( aImageRect );

        if ( mbChecked )
        {
            SetLineColor( rStyleSettings.GetHighlightColor() );
            SetFillColor();
            if ( (aImageSize.Width() >= 20) || (aImageSize.Height() >= 20) )
            {
                aImageRect.Left()++;
                aImageRect.Top()++;
                aImageRect.Right()--;
                aImageRect.Bottom()--;
            }
            DrawRect( aImageRect );
            aImageRect.Left()++;
            aImageRect.Top()++;
            aImageRect.Right()--;
            aImageRect.Bottom()--;
            DrawRect( aImageRect );
        }

        if ( HasFocus() )
            ShowFocus( ImplGetFocusRect() );
    }
}
}

// -----------------------------------------------------------------------

void RadioButton::ImplDraw( OutputDevice* pDev, sal_uLong nDrawFlags,
                            const Point& rPos, const Size& rSize,
                            const Size& rImageSize, Rectangle& rStateRect,
                            Rectangle& rMouseRect, bool bLayout )
{
    WinBits                 nWinStyle = GetStyle();
    XubString               aText( GetText() );
    Rectangle               aRect( rPos, rSize );
    MetricVector*			pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL;
    String*					pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL;

    pDev->Push( PUSH_CLIPREGION );
    pDev->IntersectClipRegion( Rectangle( rPos, rSize ) );

    // kein Image-RadioButton
    if ( !maImage )
    {
        if ( ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) ||
             ( HasImage() &&  ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) ) )
        {
            sal_uInt16 nTextStyle = Button::ImplGetTextStyle( aText, nWinStyle, nDrawFlags );

            const long nImageSep = GetDrawPixel( pDev, ImplGetImageToTextDistance() );
            Size aSize( rSize );
            Point aPos( rPos );
            aPos.X() += rImageSize.Width() + nImageSep;
            aSize.Width() -= rImageSize.Width() + nImageSep;

            // if the text rect height is smaller than the height of the image
            // then for single lines the default should be centered text
            if( (nWinStyle & (WB_TOP|WB_VCENTER|WB_BOTTOM)) == 0 &&
                (rImageSize.Height() > rSize.Height() || ! (nWinStyle & WB_WORDBREAK)  ) )
            {
                nTextStyle &= ~(TEXT_DRAW_TOP|TEXT_DRAW_BOTTOM);
                nTextStyle |= TEXT_DRAW_VCENTER;
                aSize.Height() = rImageSize.Height();
            }

            ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, 1,
                                  nDrawFlags, nTextStyle, NULL );

            rMouseRect          = Rectangle( aPos, aSize );
            rMouseRect.Left()   = rPos.X();

            rStateRect.Left()   = rPos.X();
            rStateRect.Top()    = rMouseRect.Top();

            if ( aSize.Height() > rImageSize.Height() )
                rStateRect.Top() += ( aSize.Height() - rImageSize.Height() ) / 2;
            else
            {
                rStateRect.Top() -= ( rImageSize.Height() - aSize.Height() ) / 2;
                if( rStateRect.Top() < 0 )
                    rStateRect.Top() = 0;
            }

            rStateRect.Right()  = rStateRect.Left() + rImageSize.Width()-1;
            rStateRect.Bottom() = rStateRect.Top() + rImageSize.Height()-1;

            if ( rStateRect.Bottom() > rMouseRect.Bottom() )
                rMouseRect.Bottom() = rStateRect.Bottom();
        }
        else
        {
            if ( nWinStyle & WB_CENTER )
                rStateRect.Left() = rPos.X()+((rSize.Width()-rImageSize.Width())/2);
            else if ( nWinStyle & WB_RIGHT )
                rStateRect.Left() = rPos.X()+rSize.Width()-rImageSize.Width(); //-1;
            else
                rStateRect.Left() = rPos.X(); //+1;
            if ( nWinStyle & WB_VCENTER )
                rStateRect.Top() = rPos.Y()+((rSize.Height()-rImageSize.Height())/2);
            else if ( nWinStyle & WB_BOTTOM )
                rStateRect.Top() = rPos.Y()+rSize.Height()-rImageSize.Height(); //-1;
            else
                rStateRect.Top() = rPos.Y(); //+1;
            rStateRect.Right()  = rStateRect.Left()+rImageSize.Width()-1;
            rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1;
            rMouseRect          = rStateRect;

            ImplSetFocusRect( rStateRect );

/*  und oben -1, da CalcSize() auch Focus-Rechteck nicht mit einrechnet,
da im Writer ansonsten die Images noch weiter oben haengen
            rFocusRect          = rStateRect;
            rFocusRect.Left()--;
            rFocusRect.Top()--;
            rFocusRect.Right()++;
            rFocusRect.Bottom()++;
*/
        }
    }
    else
    {
        sal_Bool        bTopImage   = (nWinStyle & WB_TOP) != 0;
        Size        aImageSize  = maImage.GetSizePixel();
        Rectangle   aImageRect( rPos, rSize );
        long        nTextHeight = pDev->GetTextHeight();
        long        nTextWidth  = pDev->GetCtrlTextWidth( aText );

        // Positionen und Groessen berechnen
        if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
        {
            Size aTmpSize( (aImageSize.Width()+8), (aImageSize.Height()+8) );
            if ( bTopImage )
            {
                aImageRect.Left() = (rSize.Width()-aTmpSize.Width())/2;
                aImageRect.Top()  = (rSize.Height()-(aTmpSize.Height()+nTextHeight+6))/2;
            }
            else
                aImageRect.Top()  = (rSize.Height()-aTmpSize.Height())/2;

            aImageRect.Right()  = aImageRect.Left()+aTmpSize.Width();
            aImageRect.Bottom() = aImageRect.Top()+aTmpSize.Height();

            // Text ausgeben
            Point aTxtPos = rPos;
            if ( bTopImage )
            {
                aTxtPos.X() += (rSize.Width()-nTextWidth)/2;
                aTxtPos.Y() += aImageRect.Bottom()+6;
            }
            else
            {
                aTxtPos.X() += aImageRect.Right()+8;
                aTxtPos.Y() += (rSize.Height()-nTextHeight)/2;
            }
            pDev->DrawCtrlText( aTxtPos, aText, 0, STRING_LEN, TEXT_DRAW_MNEMONIC, pVector, pDisplayText );
        }

        rMouseRect = aImageRect;
        rStateRect = aImageRect;
    }

    pDev->Pop();
}

// -----------------------------------------------------------------------

void RadioButton::ImplDrawRadioButton( bool bLayout )
{
    if( !bLayout )
        HideFocus();

    Size aImageSize;
    if ( !maImage )
        aImageSize = ImplGetRadioImageSize();
    else
        aImageSize  = maImage.GetSizePixel();
    aImageSize.Width()  = CalcZoom( aImageSize.Width() );
    aImageSize.Height() = CalcZoom( aImageSize.Height() );

    // Draw control text
    ImplDraw( this, 0, Point(), GetOutputSizePixel(),
              aImageSize, maStateRect, maMouseRect, bLayout );

    if( !bLayout || (IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL)==sal_True) )
    {
        if ( !maImage && HasFocus() )
            ShowFocus( ImplGetFocusRect() );

        ImplDrawRadioButtonState();
    }
}

// -----------------------------------------------------------------------

void RadioButton::GetRadioButtonGroup( std::vector< RadioButton* >& io_rGroup, bool bIncludeThis ) const
{
    // empty the list
    io_rGroup.clear();
    
    // go back to first in group;
    Window* pFirst = const_cast<RadioButton*>(this);
    while( ( pFirst->GetStyle() & WB_GROUP ) == 0 )
    {
        Window* pWindow = pFirst->GetWindow( WINDOW_PREV );
        if( pWindow )
            pFirst = pWindow;
        else
            break;
    }
    // insert radiobuttons up to next group
    do
    {
        if( pFirst->GetType() == WINDOW_RADIOBUTTON )
        {
            if( pFirst != this || bIncludeThis )
                io_rGroup.push_back( static_cast<RadioButton*>(pFirst) );
        }
        pFirst = pFirst->GetWindow( WINDOW_NEXT );
    } while( pFirst && ( ( pFirst->GetStyle() & WB_GROUP ) == 0 ) );
}

// -----------------------------------------------------------------------

void RadioButton::ImplUncheckAllOther()
{
    mpWindowImpl->mnStyle |= WB_TABSTOP;

    // Gruppe mit RadioButtons durchgehen und die gecheckten Buttons
    Window* pWindow;
    WinBits nStyle;
    if ( !(GetStyle() & WB_GROUP) )
    {
        pWindow = GetWindow( WINDOW_PREV );
        while ( pWindow )
        {
            nStyle = pWindow->GetStyle();

            if ( pWindow->GetType() == WINDOW_RADIOBUTTON )
            {
                if ( ((RadioButton*)pWindow)->IsChecked() )
                {
                    ImplDelData aDelData;
                    pWindow->ImplAddDel( &aDelData );
                    ((RadioButton*)pWindow)->SetState( sal_False );
                    if ( aDelData.IsDelete() )
                        return;
                    pWindow->ImplRemoveDel( &aDelData );
                }
                // Um falsch gesetzt WB_TABSTOPS immer zu entfernen, nicht
                // innerhalb der if-Abfrage
                pWindow->mpWindowImpl->mnStyle &= ~WB_TABSTOP;
            }

            if ( nStyle & WB_GROUP )
                break;

            pWindow = pWindow->GetWindow( WINDOW_PREV );
        }
    }

    pWindow = GetWindow( WINDOW_NEXT );
    while ( pWindow )
    {
        nStyle = pWindow->GetStyle();

        if ( nStyle & WB_GROUP )
            break;

        if ( pWindow->GetType() == WINDOW_RADIOBUTTON )
        {
            if ( ((RadioButton*)pWindow)->IsChecked() )
            {
                ImplDelData aDelData;
                pWindow->ImplAddDel( &aDelData );
                ((RadioButton*)pWindow)->SetState( sal_False );
                if ( aDelData.IsDelete() )
                    return;
                pWindow->ImplRemoveDel( &aDelData );
            }
            // Um falsch gesetzt WB_TABSTOPS immer zu entfernen, nicht
            // innerhalb der if-Abfrage
            pWindow->mpWindowImpl->mnStyle &= ~WB_TABSTOP;
        }

        pWindow = pWindow->GetWindow( WINDOW_NEXT );
    }
}

// -----------------------------------------------------------------------

void RadioButton::ImplCallClick( sal_Bool bGrabFocus, sal_uInt16 nFocusFlags )
{
    mbStateChanged = !mbChecked;
    mbChecked = sal_True;
    mpWindowImpl->mnStyle |= WB_TABSTOP;
    ImplInvalidateOrDrawRadioButtonState();
    ImplDelData aDelData;
    ImplAddDel( &aDelData );
    if ( mbRadioCheck )
        ImplUncheckAllOther();
    if ( aDelData.IsDelete() )
        return;
    if ( bGrabFocus )
        ImplGrabFocus( nFocusFlags );
    if ( aDelData.IsDelete() )
        return;
    if ( mbStateChanged )
        Toggle();
    if ( aDelData.IsDelete() )
        return;
    Click();
    if ( aDelData.IsDelete() )
        return;
    ImplRemoveDel( &aDelData );
    mbStateChanged = sal_False;
}

// -----------------------------------------------------------------------

RadioButton::RadioButton( Window* pParent, WinBits nStyle ) :
    Button( WINDOW_RADIOBUTTON )
{
    ImplInitRadioButtonData();
    ImplInit( pParent, nStyle );
}

// -----------------------------------------------------------------------

RadioButton::RadioButton( Window* pParent, const ResId& rResId ) :
    Button( WINDOW_RADIOBUTTON )
{
    ImplInitRadioButtonData();
    rResId.SetRT( RSC_RADIOBUTTON );
    WinBits nStyle = ImplInitRes( rResId );
    ImplInit( pParent, nStyle );
    ImplLoadRes( rResId );

    if ( !(nStyle & WB_HIDE) )
        Show();
}

// -----------------------------------------------------------------------

void RadioButton::ImplLoadRes( const ResId& rResId )
{
    Button::ImplLoadRes( rResId );

    //anderer Wert als Default ?
    sal_uInt16 nChecked = ReadShortRes();
    if ( nChecked )
        SetState( sal_True );
}

// -----------------------------------------------------------------------

RadioButton::~RadioButton()
{
}

// -----------------------------------------------------------------------

void RadioButton::MouseButtonDown( const MouseEvent& rMEvt )
{
    if ( rMEvt.IsLeft() && maMouseRect.IsInside( rMEvt.GetPosPixel() ) )
    {
        ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
        ImplInvalidateOrDrawRadioButtonState();
        StartTracking();
        return;
    }

    Button::MouseButtonDown( rMEvt );
}

// -----------------------------------------------------------------------

void RadioButton::Tracking( const TrackingEvent& rTEvt )
{
    if ( rTEvt.IsTrackingEnded() )
    {
        if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
        {
            if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
                GrabFocus();

            ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;

            // Bei Abbruch kein Click-Handler rufen
            if ( !rTEvt.IsTrackingCanceled() )
                ImplCallClick();
            else
                ImplInvalidateOrDrawRadioButtonState();
        }
    }
    else
    {
        if ( maMouseRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() ) )
        {
            if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
            {
                ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
                ImplInvalidateOrDrawRadioButtonState();
            }
        }
        else
        {
            if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
            {
                ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
                ImplInvalidateOrDrawRadioButtonState();
            }
        }
    }
}

// -----------------------------------------------------------------------

void RadioButton::KeyInput( const KeyEvent& rKEvt )
{
    KeyCode aKeyCode = rKEvt.GetKeyCode();

    if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) )
    {
        if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
        {
            ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
            ImplInvalidateOrDrawRadioButtonState();
        }
    }
    else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) )
    {
        ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
        ImplInvalidateOrDrawRadioButtonState();
    }
    else
        Button::KeyInput( rKEvt );
}

// -----------------------------------------------------------------------

void RadioButton::KeyUp( const KeyEvent& rKEvt )
{
    KeyCode aKeyCode = rKEvt.GetKeyCode();

    if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_SPACE) )
    {
        ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
        ImplCallClick();
    }
    else
        Button::KeyUp( rKEvt );
}

// -----------------------------------------------------------------------

void RadioButton::FillLayoutData() const
{
    mpControlData->mpLayoutData = new vcl::ControlLayoutData();
    const_cast<RadioButton*>(this)->ImplDrawRadioButton( true );
}

// -----------------------------------------------------------------------

void RadioButton::Paint( const Rectangle& )
{
    ImplDrawRadioButton();
}

// -----------------------------------------------------------------------

void RadioButton::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
                        sal_uLong nFlags )
{
    if ( !maImage )
    {
        MapMode     aResMapMode( MAP_100TH_MM );
        Point       aPos  = pDev->LogicToPixel( rPos );
        Size        aSize = pDev->LogicToPixel( rSize );
        Size        aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode );
        Size        aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode );
        Size        aBrd2Size = pDev->LogicToPixel( Size( 60, 60 ), aResMapMode );
        Font        aFont = GetDrawPixelFont( pDev );
        Rectangle   aStateRect;
        Rectangle   aMouseRect;
        Rectangle   aFocusRect;

        aImageSize.Width()  = CalcZoom( aImageSize.Width() );
        aImageSize.Height() = CalcZoom( aImageSize.Height() );
        aBrd1Size.Width()   = CalcZoom( aBrd1Size.Width() );
        aBrd1Size.Height()  = CalcZoom( aBrd1Size.Height() );
        aBrd2Size.Width()   = CalcZoom( aBrd2Size.Width() );
        aBrd2Size.Height()  = CalcZoom( aBrd2Size.Height() );

        if ( !aBrd1Size.Width() )
            aBrd1Size.Width() = 1;
        if ( !aBrd1Size.Height() )
            aBrd1Size.Height() = 1;
        if ( !aBrd2Size.Width() )
            aBrd2Size.Width() = 1;
        if ( !aBrd2Size.Height() )
            aBrd2Size.Height() = 1;

        pDev->Push();
        pDev->SetMapMode();
        pDev->SetFont( aFont );
        if ( nFlags & WINDOW_DRAW_MONO )
            pDev->SetTextColor( Color( COL_BLACK ) );
        else
            pDev->SetTextColor( GetTextColor() );
        pDev->SetTextFillColor();

        ImplDraw( pDev, nFlags, aPos, aSize,
                  aImageSize, aStateRect, aMouseRect );

        Point   aCenterPos = aStateRect.Center();
        long    nRadX = aImageSize.Width()/2;
        long    nRadY = aImageSize.Height()/2;

        pDev->SetLineColor();
        pDev->SetFillColor( Color( COL_BLACK ) );
        pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) );
        nRadX -= aBrd1Size.Width();
        nRadY -= aBrd1Size.Height();
        pDev->SetFillColor( Color( COL_WHITE ) );
        pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) );
        if ( mbChecked )
        {
            nRadX -= aBrd1Size.Width();
            nRadY -= aBrd1Size.Height();
            if ( !nRadX )
                nRadX = 1;
            if ( !nRadY )
                nRadY = 1;
            pDev->SetFillColor( Color( COL_BLACK ) );
            pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) );
        }

        pDev->Pop();
    }
    else
    {
        DBG_ERROR( "RadioButton::Draw() - not implemented for RadioButton with Image" );
    }
}

// -----------------------------------------------------------------------

void RadioButton::Resize()
{
    Control::Resize();
    Invalidate();
}

// -----------------------------------------------------------------------

void RadioButton::GetFocus()
{
    ShowFocus( ImplGetFocusRect() );
    SetInputContext( InputContext( GetFont() ) );
    Button::GetFocus();
}

// -----------------------------------------------------------------------

void RadioButton::LoseFocus()
{
    if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
    {
        ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
        ImplInvalidateOrDrawRadioButtonState();
    }

    HideFocus();
    Button::LoseFocus();
}

// -----------------------------------------------------------------------

void RadioButton::StateChanged( StateChangedType nType )
{
    Button::StateChanged( nType );

    if ( nType == STATE_CHANGE_STATE )
    {
        if ( IsReallyVisible() && IsUpdateMode() )
            Invalidate( maStateRect );
    }
    else if ( (nType == STATE_CHANGE_ENABLE) ||
              (nType == STATE_CHANGE_TEXT) ||
              (nType == STATE_CHANGE_IMAGE) ||
              (nType == STATE_CHANGE_DATA) ||
              (nType == STATE_CHANGE_UPDATEMODE) )
    {
        if ( IsUpdateMode() )
            Invalidate();
    }
    else if ( nType == STATE_CHANGE_STYLE )
    {
        SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) );

        if ( (GetPrevStyle() & RADIOBUTTON_VIEW_STYLE) !=
             (GetStyle() & RADIOBUTTON_VIEW_STYLE) )
        {
            if ( IsUpdateMode() )
                Invalidate();
        }
    }
    else if ( (nType == STATE_CHANGE_ZOOM) ||
              (nType == STATE_CHANGE_CONTROLFONT) )
    {
        ImplInitSettings( sal_True, sal_False, sal_False );
        Invalidate();
    }
    else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
    {
        ImplInitSettings( sal_False, sal_True, sal_False );
        Invalidate();
    }
    else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
    {
        ImplInitSettings( sal_False, sal_False, sal_True );
        Invalidate();
    }
}

// -----------------------------------------------------------------------

void RadioButton::DataChanged( const DataChangedEvent& rDCEvt )
{
    Button::DataChanged( rDCEvt );

    if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
         (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
         ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
          (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
    {
        ImplInitSettings( sal_True, sal_True, sal_True );
        Invalidate();
    }
}

// -----------------------------------------------------------------------

long RadioButton::PreNotify( NotifyEvent& rNEvt )
{
    long nDone = 0;
    const MouseEvent* pMouseEvt = NULL;

    if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
    {
        if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
        {
            // trigger redraw if mouse over state has changed
            if( IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL) )
            {
                if( ( maMouseRect.IsInside( GetPointerPosPixel()) &&
                     !maMouseRect.IsInside( GetLastPointerPosPixel()) ) ||
                    ( maMouseRect.IsInside( GetLastPointerPosPixel()) &&
                     !maMouseRect.IsInside( GetPointerPosPixel()) ) ||
                     pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow() )
                {
                    Invalidate( maStateRect );
                }
            }
        }
    }

    return nDone ? nDone : Button::PreNotify(rNEvt);
}

// -----------------------------------------------------------------------

void RadioButton::Toggle()
{
    ImplCallEventListenersAndHandler( VCLEVENT_RADIOBUTTON_TOGGLE, maToggleHdl, this );
}

// -----------------------------------------------------------------------

sal_Bool RadioButton::SetModeRadioImage( const Image& rImage, BmpColorMode eMode )
{
    if( eMode == BMP_COLOR_NORMAL )
{
    if ( rImage != maImage )
    {
        maImage = rImage;
        StateChanged( STATE_CHANGE_DATA );
    }
}
    else if( eMode == BMP_COLOR_HIGHCONTRAST )
    {
		if( maImageHC != rImage )
		{
			maImageHC = rImage;
			StateChanged( STATE_CHANGE_DATA );
		}
    }
    else
        return sal_False;

    return sal_True;
}

// -----------------------------------------------------------------------

const Image& RadioButton::GetModeRadioImage( BmpColorMode eMode ) const
{
    if( eMode == BMP_COLOR_HIGHCONTRAST )
        return maImageHC;
    else
        return maImage;
}

// -----------------------------------------------------------------------

void RadioButton::SetState( sal_Bool bCheck )
{
    // TabStop-Flag richtig mitfuehren
    if ( bCheck )
        mpWindowImpl->mnStyle |= WB_TABSTOP;
    else
        mpWindowImpl->mnStyle &= ~WB_TABSTOP;

    if ( mbChecked != bCheck )
    {
        mbChecked = bCheck;
        StateChanged( STATE_CHANGE_STATE );
        Toggle();
    }
}

// -----------------------------------------------------------------------

void RadioButton::Check( sal_Bool bCheck )
{
    // TabStop-Flag richtig mitfuehren
    if ( bCheck )
        mpWindowImpl->mnStyle |= WB_TABSTOP;
    else
        mpWindowImpl->mnStyle &= ~WB_TABSTOP;

    if ( mbChecked != bCheck )
    {
        mbChecked = bCheck;
        ImplDelData aDelData;
        ImplAddDel( &aDelData );
        StateChanged( STATE_CHANGE_STATE );
        if ( aDelData.IsDelete() )
            return;
        if ( bCheck && mbRadioCheck )
            ImplUncheckAllOther();
        if ( aDelData.IsDelete() )
            return;
        Toggle();
        ImplRemoveDel( &aDelData );
    }
}

// -----------------------------------------------------------------------

long RadioButton::ImplGetImageToTextDistance() const
{
    // 4 pixels, but take zoom into account, so the text doesn't "jump" relative to surrounding elements,
    // which might have been aligned with the text of the check box
    return CalcZoom( 4 );
}

// -----------------------------------------------------------------------

Size RadioButton::ImplGetRadioImageSize() const
{
    Size aSize;
    // why are IsNativeControlSupported and GetNativeControlRegion not const ?
    RadioButton* pThis = const_cast<RadioButton*>(this);
    bool bDefaultSize = true;
    if( pThis->IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) )
    {
        ImplControlValue aControlValue;
        // #i45896# workaround gcc3.3 temporary problem
        Rectangle		 aCtrlRegion( Point( 0, 0 ), GetSizePixel() );
        ControlState	 nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED;
        Rectangle aBoundingRgn, aContentRgn;

        // get native size of a radio button
        if( pThis->GetNativeControlRegion( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion,
                                           nState, aControlValue, rtl::OUString(),
                                           aBoundingRgn, aContentRgn ) )
        {
            aSize = aContentRgn.GetSize();
            bDefaultSize = false;
        }
    }
    if( bDefaultSize )
        aSize = GetRadioImage( GetSettings(), 0 ).GetSizePixel();
    return aSize;
}

static void LoadThemedImageList (const StyleSettings &rStyleSettings,
								 ImageList *pList, const ResId &rResId,
                                 sal_uInt16 nImages)
{
	Color aColorAry1[6];
	Color aColorAry2[6];
	aColorAry1[0] = Color( 0xC0, 0xC0, 0xC0 );
	aColorAry1[1] = Color( 0xFF, 0xFF, 0x00 );
	aColorAry1[2] = Color( 0xFF, 0xFF, 0xFF );
	aColorAry1[3] = Color( 0x80, 0x80, 0x80 );
	aColorAry1[4] = Color( 0x00, 0x00, 0x00 );
	aColorAry1[5] = Color( 0x00, 0xFF, 0x00 );
	aColorAry2[0] = rStyleSettings.GetFaceColor();
	aColorAry2[1] = rStyleSettings.GetWindowColor();
	aColorAry2[2] = rStyleSettings.GetLightColor();
	aColorAry2[3] = rStyleSettings.GetShadowColor();
	aColorAry2[4] = rStyleSettings.GetDarkShadowColor();
	aColorAry2[5] = rStyleSettings.GetWindowTextColor();

	Color aMaskColor(0x00, 0x00, 0xFF );
        DBG_ASSERT( sizeof(aColorAry1) == sizeof(aColorAry2), "aColorAry1 must match aColorAry2" );
	// FIXME: do we want the mask for the checkbox ?
	pList->InsertFromHorizontalBitmap (rResId, nImages, &aMaskColor, 
        aColorAry1, aColorAry2, sizeof(aColorAry1) / sizeof(Color));
}

Image RadioButton::GetRadioImage( const AllSettings& rSettings, sal_uInt16 nFlags )
{
    ImplSVData*             pSVData = ImplGetSVData();
    const StyleSettings&    rStyleSettings = rSettings.GetStyleSettings();
    sal_uInt16              nStyle = 0;

    if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
        nStyle = STYLE_RADIOBUTTON_MONO;

    if ( !pSVData->maCtrlData.mpRadioImgList ||
         (pSVData->maCtrlData.mnRadioStyle != nStyle) ||
         (pSVData->maCtrlData.mnLastRadioFColor != rStyleSettings.GetFaceColor().GetColor()) ||
         (pSVData->maCtrlData.mnLastRadioWColor != rStyleSettings.GetWindowColor().GetColor()) ||
         (pSVData->maCtrlData.mnLastRadioLColor != rStyleSettings.GetLightColor().GetColor()) )
    {
        if ( pSVData->maCtrlData.mpRadioImgList )
            delete pSVData->maCtrlData.mpRadioImgList;

        pSVData->maCtrlData.mnLastRadioFColor = rStyleSettings.GetFaceColor().GetColor();
        pSVData->maCtrlData.mnLastRadioWColor = rStyleSettings.GetWindowColor().GetColor();
        pSVData->maCtrlData.mnLastRadioLColor = rStyleSettings.GetLightColor().GetColor();

        Color pColorAry1[6];
        Color pColorAry2[6];
        pColorAry1[0] = Color( 0xC0, 0xC0, 0xC0 );
        pColorAry1[1] = Color( 0xFF, 0xFF, 0x00 );
        pColorAry1[2] = Color( 0xFF, 0xFF, 0xFF );
        pColorAry1[3] = Color( 0x80, 0x80, 0x80 );
        pColorAry1[4] = Color( 0x00, 0x00, 0x00 );
        pColorAry1[5] = Color( 0x00, 0xFF, 0x00 );
        pColorAry2[0] = rStyleSettings.GetFaceColor();
        pColorAry2[1] = rStyleSettings.GetWindowColor();
        pColorAry2[2] = rStyleSettings.GetLightColor();
        pColorAry2[3] = rStyleSettings.GetShadowColor();
        pColorAry2[4] = rStyleSettings.GetDarkShadowColor();
        pColorAry2[5] = rStyleSettings.GetWindowTextColor();

        ResMgr* pResMgr = ImplGetResMgr();
        pSVData->maCtrlData.mpRadioImgList = new ImageList();
        if( pResMgr )
	    LoadThemedImageList( rStyleSettings,
				 pSVData->maCtrlData.mpRadioImgList,
				 ResId( SV_RESID_BITMAP_RADIO+nStyle, *pResMgr ), 6 );
	pSVData->maCtrlData.mnRadioStyle = nStyle;
    }

    sal_uInt16 nId;
    if ( nFlags & BUTTON_DRAW_DISABLED )
    {
        if ( nFlags & BUTTON_DRAW_CHECKED )
            nId = 6;
        else
            nId = 5;
    }
    else if ( nFlags & BUTTON_DRAW_PRESSED )
    {
        if ( nFlags & BUTTON_DRAW_CHECKED )
            nId = 4;
        else
            nId = 3;
    }
    else
    {
        if ( nFlags & BUTTON_DRAW_CHECKED )
            nId = 2;
        else
            nId = 1;
    }
    return pSVData->maCtrlData.mpRadioImgList->GetImage( nId );
}

// -----------------------------------------------------------------------

void RadioButton::ImplSetMinimumNWFSize()
{
    Push( PUSH_MAPMODE );
    SetMapMode( MAP_PIXEL );

    ImplControlValue aControlValue;
    Size aCurSize( GetSizePixel() );
    Rectangle aCtrlRegion( Point( 0, 0 ), aCurSize );
    Rectangle aBoundingRgn, aContentRgn;
    
    // get native size of a radiobutton
    if( GetNativeControlRegion( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion,
                                CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED, aControlValue, rtl::OUString(),
                                aBoundingRgn, aContentRgn ) )
    {
        Size aSize = aContentRgn.GetSize();
        
        if( aSize.Height() > aCurSize.Height() )
        {
            aCurSize.Height() = aSize.Height();
            SetSizePixel( aCurSize );
        }
    }
    
    Pop();
}

// -----------------------------------------------------------------------

Size RadioButton::CalcMinimumSize( long nMaxWidth ) const
{
    Size aSize;
    if ( !maImage )
        aSize = ImplGetRadioImageSize();
    else
        aSize = maImage.GetSizePixel();

    nMaxWidth -= aSize.Width();

    XubString aText = GetText();
    if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
    {
        // subtract what will be added later
        nMaxWidth-=2;
        nMaxWidth -= ImplGetImageToTextDistance();

        Size aTextSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
                                      aText, FixedText::ImplGetTextStyle( GetStyle() ) ).GetSize();
        aSize.Width()+=2;   // for focus rect
        aSize.Width() += ImplGetImageToTextDistance();
        aSize.Width() += aTextSize.Width();
        if ( aSize.Height() < aTextSize.Height() )
            aSize.Height() = aTextSize.Height();
    }
    else if ( !maImage )
    {
/* da ansonsten im Writer die Control zu weit oben haengen
        aSize.Width() += 2;
        aSize.Height() += 2;
*/
    }

    return CalcWindowSize( aSize );
}

// -----------------------------------------------------------------------

Size RadioButton::GetOptimalSize(WindowSizeType eType) const
{
    switch (eType) {
    case WINDOWSIZE_MINIMUM:
        return CalcMinimumSize();
    default:
        return Button::GetOptimalSize( eType );
    }
}

// =======================================================================

void CheckBox::ImplInitCheckBoxData()
{
    meState         = STATE_NOCHECK;
    meSaveValue     = STATE_NOCHECK;
    mbTriState      = sal_False;
}

// -----------------------------------------------------------------------

void CheckBox::ImplInit( Window* pParent, WinBits nStyle )
{
    nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle );
    Button::ImplInit( pParent, nStyle, NULL );

    ImplInitSettings( sal_True, sal_True, sal_True );
}

// -----------------------------------------------------------------------

WinBits CheckBox::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle )
{
    if ( !(nStyle & WB_NOTABSTOP) )
        nStyle |= WB_TABSTOP;
    if ( !(nStyle & WB_NOGROUP) &&
         (!pPrevWindow || (pPrevWindow->GetType() != WINDOW_CHECKBOX)) )
        nStyle |= WB_GROUP;
    return nStyle;
}

// -----------------------------------------------------------------

const Font& CheckBox::GetCanonicalFont( const StyleSettings& _rStyle ) const
{
    return _rStyle.GetRadioCheckFont();
}

// -----------------------------------------------------------------
const Color& CheckBox::GetCanonicalTextColor( const StyleSettings& _rStyle ) const
{
    return _rStyle.GetRadioCheckTextColor();
}

// -----------------------------------------------------------------------

void CheckBox::ImplInitSettings( sal_Bool bFont,
                                 sal_Bool bForeground, sal_Bool bBackground )
{
    Button::ImplInitSettings( bFont, bForeground );

    if ( bBackground )
    {
        Window* pParent = GetParent();
        if ( !IsControlBackground() &&
            (pParent->IsChildTransparentModeEnabled() || IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) ) )
        {
            EnableChildTransparentMode( sal_True );
            SetParentClipMode( PARENTCLIPMODE_NOCLIP );
            SetPaintTransparent( sal_True );
            SetBackground();
            if( IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) )
                ImplGetWindowImpl()->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects;
        }
        else
        {
            EnableChildTransparentMode( sal_False );
            SetParentClipMode( 0 );
            SetPaintTransparent( sal_False );

            if ( IsControlBackground() )
                SetBackground( GetControlBackground() );
            else
                SetBackground( pParent->GetBackground() );
        }
    }
}

// -----------------------------------------------------------------------

void CheckBox::ImplLoadRes( const ResId& rResId )
{
    Button::ImplLoadRes( rResId );

    if ( rResId.GetRT() != RSC_TRISTATEBOX )
    {
        sal_uInt16 nChecked = ReadShortRes();
        //anderer Wert als Default ?
        if( nChecked )
            Check( sal_True );
    }
}

// -----------------------------------------------------------------------

void CheckBox::ImplInvalidateOrDrawCheckBoxState()
{
    if( ImplGetSVData()->maNWFData.mbCheckBoxNeedsErase )
    {
        if ( IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL) )
        {
            Invalidate();
            Update();
            return;
        }
    }
    ImplDrawCheckBoxState();
}

void CheckBox::ImplDrawCheckBoxState()
{
    bool	bNativeOK = sal_True;

    if ( (bNativeOK=IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL)) == sal_True )
    {
        ImplControlValue    aControlValue( meState == STATE_CHECK ? BUTTONVALUE_ON : BUTTONVALUE_OFF );
        Rectangle           aCtrlRegion( maStateRect );
        ControlState        nState = 0;

        if ( HasFocus() ) 						nState |= CTRL_STATE_FOCUSED;
        if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT )	nState |= CTRL_STATE_DEFAULT;
        if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )	nState |= CTRL_STATE_PRESSED;
        if ( IsEnabled() )						nState |= CTRL_STATE_ENABLED;

        if ( meState == STATE_CHECK )
            aControlValue.setTristateVal( BUTTONVALUE_ON );
        else if ( meState == STATE_DONTKNOW )
            aControlValue.setTristateVal( BUTTONVALUE_MIXED );

        if ( IsMouseOver() && maMouseRect.IsInside( GetPointerPosPixel() ) )
            nState |= CTRL_STATE_ROLLOVER;

        bNativeOK = DrawNativeControl( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion, nState,
	     						aControlValue, rtl::OUString() );
    }

    if ( bNativeOK == sal_False )
    {
        sal_uInt16 nStyle = ImplGetButtonState();
        if ( !IsEnabled() )
            nStyle |= BUTTON_DRAW_DISABLED;
        if ( meState == STATE_DONTKNOW )
            nStyle |= BUTTON_DRAW_DONTKNOW;
        else if ( meState == STATE_CHECK )
            nStyle |= BUTTON_DRAW_CHECKED;
        Image aImage = GetCheckImage( GetSettings(), nStyle );
        if ( IsZoom() )
            DrawImage( maStateRect.TopLeft(), maStateRect.GetSize(), aImage );
        else
            DrawImage( maStateRect.TopLeft(), aImage );
    }
}

// -----------------------------------------------------------------------

void CheckBox::ImplDraw( OutputDevice* pDev, sal_uLong nDrawFlags,
                         const Point& rPos, const Size& rSize,
                         const Size& rImageSize, Rectangle& rStateRect,
                         Rectangle& rMouseRect, bool bLayout )
{
    WinBits                 nWinStyle = GetStyle();
    XubString               aText( GetText() );
    
    pDev->Push( PUSH_CLIPREGION | PUSH_LINECOLOR );
    pDev->IntersectClipRegion( Rectangle( rPos, rSize ) );

    long nLineY = rPos.Y() + (rSize.Height()-1)/2;
    if ( ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) ||
         ( HasImage() && !  (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) ) )
    {
        sal_uInt16 nTextStyle = Button::ImplGetTextStyle( aText, nWinStyle, nDrawFlags );

        const long nImageSep = GetDrawPixel( pDev, ImplGetImageToTextDistance() );
        Size aSize( rSize );
        Point aPos( rPos );
        aPos.X() += rImageSize.Width() + nImageSep;
        aSize.Width() -= rImageSize.Width() + nImageSep;

        // if the text rect height is smaller than the height of the image
        // then for single lines the default should be centered text
        if( (nWinStyle & (WB_TOP|WB_VCENTER|WB_BOTTOM)) == 0 &&
            (rImageSize.Height() > rSize.Height() || ! (nWinStyle & WB_WORDBREAK) ) )
        {
            nTextStyle &= ~(TEXT_DRAW_TOP|TEXT_DRAW_BOTTOM);
            nTextStyle |= TEXT_DRAW_VCENTER;
            aSize.Height() = rImageSize.Height();
        }

        ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, 1,
                              nDrawFlags, nTextStyle, NULL );
        nLineY = aPos.Y() + aSize.Height()/2;

        rMouseRect          = Rectangle( aPos, aSize );
        rMouseRect.Left()   = rPos.X();
        rStateRect.Left()   = rPos.X();
        rStateRect.Top()    = rMouseRect.Top();

        if ( aSize.Height() > rImageSize.Height() )
            rStateRect.Top() += ( aSize.Height() - rImageSize.Height() ) / 2;
        else
        {
            rStateRect.Top() -= ( rImageSize.Height() - aSize.Height() ) / 2;
            if( rStateRect.Top() < 0 )
                rStateRect.Top() = 0;
        }

        rStateRect.Right()  = rStateRect.Left()+rImageSize.Width()-1;
        rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1;
        if ( rStateRect.Bottom() > rMouseRect.Bottom() )
            rMouseRect.Bottom() = rStateRect.Bottom();
    }
    else
    {
        if ( nWinStyle & WB_CENTER )
            rStateRect.Left() = rPos.X()+((rSize.Width()-rImageSize.Width())/2);
        else if ( nWinStyle & WB_RIGHT )
            rStateRect.Left() = rPos.X()+rSize.Width()-rImageSize.Width();
        else
            rStateRect.Left() = rPos.X();
        if ( nWinStyle & WB_VCENTER )
            rStateRect.Top() = rPos.Y()+((rSize.Height()-rImageSize.Height())/2);
        else if ( nWinStyle & WB_BOTTOM )
            rStateRect.Top() = rPos.Y()+rSize.Height()-rImageSize.Height();
        else
            rStateRect.Top() = rPos.Y();
        rStateRect.Right()  = rStateRect.Left()+rImageSize.Width()-1;
        rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1;
        // provide space for focusrect
        // note: this assumes that the control's size was adjusted
        // accordingly in Get/LoseFocus, so the onscreen position won't change
        if( HasFocus() )
            rStateRect.Move( 1, 1 );
        rMouseRect          = rStateRect;

        ImplSetFocusRect( rStateRect );
    }
    
    const int nLineSpace = 4;
    if( (GetStyle() & WB_CBLINESTYLE) != 0 &&
        rMouseRect.Right()-1-nLineSpace < rPos.X()+rSize.Width() )
    {
        const StyleSettings&	rStyleSettings = GetSettings().GetStyleSettings();
        if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
            SetLineColor( Color( COL_BLACK ) );
        else
            SetLineColor( rStyleSettings.GetShadowColor() );
        long nLineX = rMouseRect.Right()+nLineSpace;
        DrawLine( Point( nLineX, nLineY ), Point( rPos.X() + rSize.Width()-1, nLineY ) );
        if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
        {
            SetLineColor( rStyleSettings.GetLightColor() );
            DrawLine( Point( nLineX, nLineY+1 ), Point( rPos.X() + rSize.Width()-1, nLineY+1 ) );
        }
    }

    pDev->Pop();
}

// -----------------------------------------------------------------------

void CheckBox::ImplDrawCheckBox( bool bLayout )
{
    Size aImageSize = ImplGetCheckImageSize();
    aImageSize.Width()  = CalcZoom( aImageSize.Width() );
    aImageSize.Height() = CalcZoom( aImageSize.Height() );

    if( !bLayout )
        HideFocus();

    ImplDraw( this, 0, Point(), GetOutputSizePixel(), aImageSize,
              maStateRect, maMouseRect, bLayout );

    if( !bLayout )
    {
        ImplDrawCheckBoxState();
        if ( HasFocus() )
            ShowFocus( ImplGetFocusRect() );
    }
}

// -----------------------------------------------------------------------

void CheckBox::ImplCheck()
{
    TriState eNewState;
    if ( meState == STATE_NOCHECK )
        eNewState = STATE_CHECK;
    else if ( !mbTriState )
        eNewState = STATE_NOCHECK;
    else if ( meState == STATE_CHECK )
        eNewState = STATE_DONTKNOW;
    else
        eNewState = STATE_NOCHECK;
    meState = eNewState;

    ImplDelData aDelData;
    ImplAddDel( &aDelData );
    if( (GetStyle() & WB_EARLYTOGGLE) )
        Toggle();
    ImplInvalidateOrDrawCheckBoxState();
    if( ! (GetStyle() & WB_EARLYTOGGLE) )
        Toggle();
    if ( aDelData.IsDelete() )
        return;
    ImplRemoveDel( &aDelData );
    Click();
}

// -----------------------------------------------------------------------

CheckBox::CheckBox( Window* pParent, WinBits nStyle ) :
    Button( WINDOW_CHECKBOX )
{
    ImplInitCheckBoxData();
    ImplInit( pParent, nStyle );
}

// -----------------------------------------------------------------------

CheckBox::CheckBox( Window* pParent, const ResId& rResId ) :
    Button( WINDOW_CHECKBOX )
{
    ImplInitCheckBoxData();
    rResId.SetRT( RSC_CHECKBOX );
    WinBits nStyle = ImplInitRes( rResId );
    ImplInit( pParent, nStyle );
    ImplLoadRes( rResId );

    if ( !(nStyle & WB_HIDE) )
        Show();
}

// -----------------------------------------------------------------------

void CheckBox::MouseButtonDown( const MouseEvent& rMEvt )
{
    if ( rMEvt.IsLeft() && maMouseRect.IsInside( rMEvt.GetPosPixel() ) )
    {
        ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
        ImplInvalidateOrDrawCheckBoxState();
        StartTracking();
        return;
    }

    Button::MouseButtonDown( rMEvt );
}

// -----------------------------------------------------------------------

void CheckBox::Tracking( const TrackingEvent& rTEvt )
{
    if ( rTEvt.IsTrackingEnded() )
    {
        if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
        {
            if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
                GrabFocus();

            ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;

            // Bei Abbruch kein Click-Handler rufen
            if ( !rTEvt.IsTrackingCanceled() )
                ImplCheck();
            else
                ImplInvalidateOrDrawCheckBoxState();
        }
    }
    else
    {
        if ( maMouseRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() ) )
        {
            if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
            {
                ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
                ImplInvalidateOrDrawCheckBoxState();
            }
        }
        else
        {
            if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
            {
                ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
                ImplInvalidateOrDrawCheckBoxState();
            }
        }
    }
}

// -----------------------------------------------------------------------

void CheckBox::KeyInput( const KeyEvent& rKEvt )
{
    KeyCode aKeyCode = rKEvt.GetKeyCode();

    if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) )
    {
        if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
        {
            ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
            ImplInvalidateOrDrawCheckBoxState();
        }
    }
    else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) )
    {
        ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
        ImplInvalidateOrDrawCheckBoxState();
    }
    else
        Button::KeyInput( rKEvt );
}

// -----------------------------------------------------------------------

void CheckBox::KeyUp( const KeyEvent& rKEvt )
{
    KeyCode aKeyCode = rKEvt.GetKeyCode();

    if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_SPACE) )
    {
        ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
        ImplCheck();
    }
    else
        Button::KeyUp( rKEvt );
}

// -----------------------------------------------------------------------

void CheckBox::FillLayoutData() const
{
    mpControlData->mpLayoutData = new vcl::ControlLayoutData();
    const_cast<CheckBox*>(this)->ImplDrawCheckBox( true );
}

// -----------------------------------------------------------------------

void CheckBox::Paint( const Rectangle& )
{
    ImplDrawCheckBox();
}

// -----------------------------------------------------------------------

void CheckBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
                     sal_uLong nFlags )
{
    MapMode     aResMapMode( MAP_100TH_MM );
    Point       aPos  = pDev->LogicToPixel( rPos );
    Size        aSize = pDev->LogicToPixel( rSize );
    Size        aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode );
    Size        aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode );
    Size        aBrd2Size = pDev->LogicToPixel( Size( 30, 30 ), aResMapMode );
    long        nCheckWidth = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode ).Width();
    Font        aFont = GetDrawPixelFont( pDev );
    Rectangle   aStateRect;
    Rectangle   aMouseRect;

    aImageSize.Width()  = CalcZoom( aImageSize.Width() );
    aImageSize.Height() = CalcZoom( aImageSize.Height() );
    aBrd1Size.Width()   = CalcZoom( aBrd1Size.Width() );
    aBrd1Size.Height()  = CalcZoom( aBrd1Size.Height() );
    aBrd2Size.Width()   = CalcZoom( aBrd2Size.Width() );
    aBrd2Size.Height()  = CalcZoom( aBrd2Size.Height() );

    if ( !aBrd1Size.Width() )
        aBrd1Size.Width() = 1;
    if ( !aBrd1Size.Height() )
        aBrd1Size.Height() = 1;
    if ( !aBrd2Size.Width() )
        aBrd2Size.Width() = 1;
    if ( !aBrd2Size.Height() )
        aBrd2Size.Height() = 1;
    if ( !nCheckWidth )
        nCheckWidth = 1;

    pDev->Push();
    pDev->SetMapMode();
    pDev->SetFont( aFont );
    if ( nFlags & WINDOW_DRAW_MONO )
        pDev->SetTextColor( Color( COL_BLACK ) );
    else
        pDev->SetTextColor( GetTextColor() );
    pDev->SetTextFillColor();

    ImplDraw( pDev, nFlags, aPos, aSize,
              aImageSize, aStateRect, aMouseRect, false );

    pDev->SetLineColor();
    pDev->SetFillColor( Color( COL_BLACK ) );
    pDev->DrawRect( aStateRect );
    aStateRect.Left()   += aBrd1Size.Width();
    aStateRect.Top()    += aBrd1Size.Height();
    aStateRect.Right()  -= aBrd1Size.Width();
    aStateRect.Bottom() -= aBrd1Size.Height();
    if ( meState == STATE_DONTKNOW )
        pDev->SetFillColor( Color( COL_LIGHTGRAY ) );
    else
        pDev->SetFillColor( Color( COL_WHITE ) );
    pDev->DrawRect( aStateRect );

    if ( meState == STATE_CHECK )
    {
        aStateRect.Left()   += aBrd2Size.Width();
        aStateRect.Top()    += aBrd2Size.Height();
        aStateRect.Right()  -= aBrd2Size.Width();
        aStateRect.Bottom() -= aBrd2Size.Height();
        Point   aPos11( aStateRect.TopLeft() );
        Point   aPos12( aStateRect.BottomRight() );
        Point   aPos21( aStateRect.TopRight() );
        Point   aPos22( aStateRect.BottomLeft() );
        Point   aTempPos11( aPos11 );
        Point   aTempPos12( aPos12 );
        Point   aTempPos21( aPos21 );
        Point   aTempPos22( aPos22 );
        pDev->SetLineColor( Color( COL_BLACK ) );
        long nDX = 0;
        for ( long i = 0; i < nCheckWidth; i++ )
        {
            if ( !(i % 2) )
            {
                aTempPos11.X() = aPos11.X()+nDX;
                aTempPos12.X() = aPos12.X()+nDX;
                aTempPos21.X() = aPos21.X()+nDX;
                aTempPos22.X() = aPos22.X()+nDX;
            }
            else
            {
                nDX++;
                aTempPos11.X() = aPos11.X()-nDX;
                aTempPos12.X() = aPos12.X()-nDX;
                aTempPos21.X() = aPos21.X()-nDX;
                aTempPos22.X() = aPos22.X()-nDX;
            }
            pDev->DrawLine( aTempPos11, aTempPos12 );
            pDev->DrawLine( aTempPos21, aTempPos22 );
        }
    }

    pDev->Pop();
}

// -----------------------------------------------------------------------

void CheckBox::Resize()
{
    Control::Resize();
    Invalidate();
}

// -----------------------------------------------------------------------

void CheckBox::GetFocus()
{
    if ( !GetText().Len() || (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
    {
        // increase button size to have space for focus rect
        // checkboxes without text will draw focusrect around the check
        // See CheckBox::ImplDraw()
        Point aPos( GetPosPixel() );
        Size aSize( GetSizePixel() );
        aPos.Move(-1,-1);
        aSize.Height() += 2;
        aSize.Width() += 2;
        SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL );
        ImplDrawCheckBox();
    }
    else
        ShowFocus( ImplGetFocusRect() );

    SetInputContext( InputContext( GetFont() ) );
    Button::GetFocus();
}

// -----------------------------------------------------------------------

void CheckBox::LoseFocus()
{
    if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
    {
        ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
        ImplInvalidateOrDrawCheckBoxState();
    }

    HideFocus();
    Button::LoseFocus();

    if ( !GetText().Len() || (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
    {
        // decrease button size again (see GetFocus())
        // checkboxes without text will draw focusrect around the check
        Point aPos( GetPosPixel() );
        Size aSize( GetSizePixel() );
        aPos.Move(1,1);
        aSize.Height() -= 2;
        aSize.Width() -= 2;
        SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL );
        ImplDrawCheckBox();
    }
}

// -----------------------------------------------------------------------

void CheckBox::StateChanged( StateChangedType nType )
{
    Button::StateChanged( nType );

    if ( nType == STATE_CHANGE_STATE )
    {
        if ( IsReallyVisible() && IsUpdateMode() )
            Invalidate( maStateRect );
    }
    else if ( (nType == STATE_CHANGE_ENABLE) ||
              (nType == STATE_CHANGE_TEXT) ||
              (nType == STATE_CHANGE_IMAGE) ||
              (nType == STATE_CHANGE_DATA) ||
              (nType == STATE_CHANGE_UPDATEMODE) )
    {
        if ( IsUpdateMode() )
            Invalidate();
    }
    else if ( nType == STATE_CHANGE_STYLE )
    {
        SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) );

        if ( (GetPrevStyle() & CHECKBOX_VIEW_STYLE) !=
             (GetStyle() & CHECKBOX_VIEW_STYLE) )
        {
            if ( IsUpdateMode() )
                Invalidate();
        }
    }
    else if ( (nType == STATE_CHANGE_ZOOM) ||
              (nType == STATE_CHANGE_CONTROLFONT) )
    {
        ImplInitSettings( sal_True, sal_False, sal_False );
        Invalidate();
    }
    else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
    {
        ImplInitSettings( sal_False, sal_True, sal_False );
        Invalidate();
    }
    else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
    {
        ImplInitSettings( sal_False, sal_False, sal_True );
        Invalidate();
    }
}

// -----------------------------------------------------------------------

void CheckBox::DataChanged( const DataChangedEvent& rDCEvt )
{
    Button::DataChanged( rDCEvt );

    if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
         (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
         ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
          (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
    {
        ImplInitSettings( sal_True, sal_True, sal_True );
        Invalidate();
    }
}

// -----------------------------------------------------------------------

long CheckBox::PreNotify( NotifyEvent& rNEvt )
{
    long nDone = 0;
    const MouseEvent* pMouseEvt = NULL;

    if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
    {
        if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
        {
            // trigger redraw if mouse over state has changed
            if( IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL) )
            {
                if( ( maMouseRect.IsInside( GetPointerPosPixel()) && 
                     !maMouseRect.IsInside( GetLastPointerPosPixel()) ) ||
                    ( maMouseRect.IsInside( GetLastPointerPosPixel()) && 
                     !maMouseRect.IsInside( GetPointerPosPixel()) ) ||
                    pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow() )
                {
                    Invalidate( maStateRect );
                }
            }
        }
    }

    return nDone ? nDone : Button::PreNotify(rNEvt);
}

// -----------------------------------------------------------------------

void CheckBox::Toggle()
{
    ImplCallEventListenersAndHandler( VCLEVENT_CHECKBOX_TOGGLE, maToggleHdl, this );
}

// -----------------------------------------------------------------------

void CheckBox::SetState( TriState eState )
{
    if ( !mbTriState && (eState == STATE_DONTKNOW) )
        eState = STATE_NOCHECK;

    if ( meState != eState )
    {
        meState = eState;
        StateChanged( STATE_CHANGE_STATE );
        Toggle();
    }
}

// -----------------------------------------------------------------------

void CheckBox::EnableTriState( sal_Bool bTriState )
{
    if ( mbTriState != bTriState )
    {
        mbTriState = bTriState;

        if ( !bTriState && (meState == STATE_DONTKNOW) )
            SetState( STATE_NOCHECK );
    }
}

// -----------------------------------------------------------------------

long CheckBox::ImplGetImageToTextDistance() const
{
    // 4 pixels, but take zoom into account, so the text doesn't "jump" relative to surrounding elements,
    // which might have been aligned with the text of the check box
    return CalcZoom( 4 );
}

// -----------------------------------------------------------------------

Size CheckBox::ImplGetCheckImageSize() const
{
    Size aSize;
    // why are IsNativeControlSupported and GetNativeControlRegion not const ?
    CheckBox* pThis = const_cast<CheckBox*>(this);
    bool bDefaultSize = true;
    if( pThis->IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) )
    {
        ImplControlValue aControlValue;
        // #i45896# workaround gcc3.3 temporary problem
        Rectangle		 aCtrlRegion( Point( 0, 0 ), GetSizePixel() );
        ControlState	 nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED;
        Rectangle aBoundingRgn, aContentRgn;
        
        // get native size of a check box
        if( pThis->GetNativeControlRegion( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion,
                                           nState, aControlValue, rtl::OUString(),
                                           aBoundingRgn, aContentRgn ) )
        {
            aSize = aContentRgn.GetSize();
            bDefaultSize = false;
        }
    }
    if( bDefaultSize ) 
        aSize = GetCheckImage( GetSettings(), 0 ).GetSizePixel();
    return aSize;
}

Image CheckBox::GetCheckImage( const AllSettings& rSettings, sal_uInt16 nFlags )
{
    ImplSVData*             pSVData = ImplGetSVData();
    const StyleSettings&    rStyleSettings = rSettings.GetStyleSettings();
    sal_uInt16              nStyle = 0;

    if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
        nStyle = STYLE_CHECKBOX_MONO;

    if ( !pSVData->maCtrlData.mpCheckImgList ||
         (pSVData->maCtrlData.mnCheckStyle != nStyle) ||
         (pSVData->maCtrlData.mnLastCheckFColor != rStyleSettings.GetFaceColor().GetColor()) ||
         (pSVData->maCtrlData.mnLastCheckWColor != rStyleSettings.GetWindowColor().GetColor()) ||
         (pSVData->maCtrlData.mnLastCheckLColor != rStyleSettings.GetLightColor().GetColor()) )
    {
        if ( pSVData->maCtrlData.mpCheckImgList )
            delete pSVData->maCtrlData.mpCheckImgList;

        pSVData->maCtrlData.mnLastCheckFColor = rStyleSettings.GetFaceColor().GetColor();
        pSVData->maCtrlData.mnLastCheckWColor = rStyleSettings.GetWindowColor().GetColor();
        pSVData->maCtrlData.mnLastCheckLColor = rStyleSettings.GetLightColor().GetColor();

        ResMgr* pResMgr = ImplGetResMgr();
        pSVData->maCtrlData.mpCheckImgList = new ImageList();
        if( pResMgr )
	    LoadThemedImageList( rStyleSettings,
				 pSVData->maCtrlData.mpCheckImgList,
				 ResId( SV_RESID_BITMAP_CHECK+nStyle, *pResMgr ), 9 );
        pSVData->maCtrlData.mnCheckStyle = nStyle;
    }

    sal_uInt16 nId;
    if ( nFlags & BUTTON_DRAW_DISABLED )
    {
        if ( nFlags & BUTTON_DRAW_DONTKNOW )
            nId = 9;
        else if ( nFlags & BUTTON_DRAW_CHECKED )
            nId = 6;
        else
            nId = 5;
    }
    else if ( nFlags & BUTTON_DRAW_PRESSED )
    {
        if ( nFlags & BUTTON_DRAW_DONTKNOW )
            nId = 8;
        else if ( nFlags & BUTTON_DRAW_CHECKED )
            nId = 4;
        else
            nId = 3;
    }
    else
    {
        if ( nFlags & BUTTON_DRAW_DONTKNOW )
            nId = 7;
        else if ( nFlags & BUTTON_DRAW_CHECKED )
            nId = 2;
        else
            nId = 1;
    }
    return pSVData->maCtrlData.mpCheckImgList->GetImage( nId );
}

// -----------------------------------------------------------------------

void CheckBox::ImplSetMinimumNWFSize()
{
    Push( PUSH_MAPMODE );
    SetMapMode( MAP_PIXEL );

    ImplControlValue aControlValue;
    Size aCurSize( GetSizePixel() );
    Rectangle aCtrlRegion( Point( 0, 0 ), aCurSize );
    Rectangle aBoundingRgn, aContentRgn;
    
    // get native size of a radiobutton
    if( GetNativeControlRegion( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion,
                                CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED, aControlValue, rtl::OUString(),
                                aBoundingRgn, aContentRgn ) )
    {
        Size aSize = aContentRgn.GetSize();
        
        if( aSize.Height() > aCurSize.Height() )
        {
            aCurSize.Height() = aSize.Height();
            SetSizePixel( aCurSize );
        }
    }
    
    Pop();
}

// -----------------------------------------------------------------------

Size CheckBox::CalcMinimumSize( long nMaxWidth ) const
{
    Size aSize = ImplGetCheckImageSize();
    nMaxWidth -= aSize.Width();

    XubString aText = GetText();
    if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
    {
        // subtract what will be added later
        nMaxWidth-=2;
        nMaxWidth -= ImplGetImageToTextDistance();

        Size aTextSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
                                      aText, FixedText::ImplGetTextStyle( GetStyle() ) ).GetSize();
        aSize.Width()+=2;    // for focus rect
        aSize.Width() += ImplGetImageToTextDistance();
        aSize.Width() += aTextSize.Width();
        if ( aSize.Height() < aTextSize.Height() )
            aSize.Height() = aTextSize.Height();
    }
    else
    {
        // is this still correct ? since the checkbox now
        // shows a focus rect it should be 2 pixels wider and longer
/* da ansonsten im Writer die Control zu weit oben haengen
        aSize.Width() += 2;
        aSize.Height() += 2;
*/
    }

    return CalcWindowSize( aSize );
}

// -----------------------------------------------------------------------

Size CheckBox::GetOptimalSize(WindowSizeType eType) const
{
    switch (eType) {
    case WINDOWSIZE_MINIMUM:
        return CalcMinimumSize();
    default:
        return Button::GetOptimalSize( eType );
    }
}

// =======================================================================

ImageButton::ImageButton( WindowType nType ) :
    PushButton( nType )
{
    ImplInitStyle();
}

// -----------------------------------------------------------------------

ImageButton::ImageButton( Window* pParent, WinBits nStyle ) :
    PushButton( pParent, nStyle )
{
    ImplInitStyle();
}

// -----------------------------------------------------------------------

ImageButton::ImageButton( Window* pParent, const ResId& rResId ) :
    PushButton( pParent, rResId.SetRT( RSC_IMAGEBUTTON ) )
{
    sal_uLong nObjMask = ReadLongRes();

    if ( RSC_IMAGEBUTTON_IMAGE & nObjMask )
    {
        SetModeImage( Image( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) ) );
        IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
    }

    if ( RSC_IMAGEBUTTON_SYMBOL & nObjMask )
        SetSymbol( (SymbolType)ReadLongRes() );

    if ( RSC_IMAGEBUTTON_STATE & nObjMask )
        SetState( (TriState)ReadLongRes() );

    ImplInitStyle();
}

// -----------------------------------------------------------------------

ImageButton::~ImageButton()
{
}

// -----------------------------------------------------------------------
void ImageButton::ImplInitStyle()
{
    WinBits nStyle = GetStyle();

    if ( ! ( nStyle & ( WB_RIGHT | WB_LEFT ) ) )
        nStyle |= WB_CENTER;

    if ( ! ( nStyle & ( WB_TOP | WB_BOTTOM ) ) )
        nStyle |= WB_VCENTER;

    SetStyle( nStyle );
}

// =======================================================================

ImageRadioButton::ImageRadioButton( Window* pParent, WinBits nStyle ) :
    RadioButton( pParent, nStyle )
{
}

// -----------------------------------------------------------------------

ImageRadioButton::ImageRadioButton( Window* pParent, const ResId& rResId ) :
    RadioButton( pParent, rResId.SetRT( RSC_IMAGERADIOBUTTON ) )
{
    sal_uLong nObjMask = ReadLongRes();

    if ( RSC_IMAGERADIOBUTTON_IMAGE & nObjMask )
    {
        SetModeRadioImage( Image( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) ) );
        IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
    }
}

// -----------------------------------------------------------------------

ImageRadioButton::~ImageRadioButton()
{
}

// =======================================================================

TriStateBox::TriStateBox( Window* pParent, WinBits nStyle ) :
    CheckBox( pParent, nStyle )
{
    EnableTriState( sal_True );
}

// -----------------------------------------------------------------------

TriStateBox::TriStateBox( Window* pParent, const ResId& rResId ) :
    CheckBox( pParent, rResId.SetRT( RSC_TRISTATEBOX ) )
{
    EnableTriState( sal_True );

    sal_uLong  nTriState        = ReadLongRes();
    sal_uInt16 bDisableTriState = ReadShortRes();
    //anderer Wert als Default ?
    if ( (TriState)nTriState != STATE_NOCHECK )
        SetState( (TriState)nTriState );
    if ( bDisableTriState )
        EnableTriState( sal_False );
}

// -----------------------------------------------------------------------

TriStateBox::~TriStateBox()
{
}

// =======================================================================

DisclosureButton::DisclosureButton( Window* pParent, WinBits ) :
    CheckBox( pParent, WB_NOBORDER )
{
}

// -----------------------------------------------------------------------

DisclosureButton::DisclosureButton( Window* pParent, const ResId& rResId ) :
    CheckBox( pParent, rResId.SetRT( RSC_CHECKBOX ) )
{
}

// -----------------------------------------------------------------------

void DisclosureButton::ImplDrawCheckBoxState()
{
    /* HACK: DisclosureButton is currently assuming, that the disclosure sign
       will fit into the rectangle occupied by a normal checkbox on all themes.
       If this does not hold true for some theme, ImplGetCheckImageSize
       would have to be overloaded for DisclosureButton; also GetNativeControlRegion
       for CTRL_LISTNODE would have to be implemented and taken into account
    */
    
    Rectangle aStateRect( GetStateRect() );
    
    ImplControlValue    aControlValue( GetState() == STATE_CHECK ? BUTTONVALUE_ON : BUTTONVALUE_OFF );
    Rectangle           aCtrlRegion( aStateRect );
    ControlState        nState = 0;

    if ( HasFocus() )						nState |= CTRL_STATE_FOCUSED;
    if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT )	nState |= CTRL_STATE_DEFAULT;
    if ( Window::IsEnabled() ) 				nState |= CTRL_STATE_ENABLED;
    if ( IsMouseOver() && GetMouseRect().IsInside( GetPointerPosPixel() ) )
        nState |= CTRL_STATE_ROLLOVER;

    if( ! DrawNativeControl( CTRL_LISTNODE, PART_ENTIRE_CONTROL, aCtrlRegion, nState,
                           aControlValue, rtl::OUString() ) )
    {
        ImplSVCtrlData& rCtrlData( ImplGetSVData()->maCtrlData );
        if( ! rCtrlData.mpDisclosurePlus )
            rCtrlData.mpDisclosurePlus = new Image( BitmapEx( VclResId( SV_DISCLOSURE_PLUS ) ) );
        if( ! rCtrlData.mpDisclosurePlusHC )
            rCtrlData.mpDisclosurePlusHC = new Image( BitmapEx( VclResId( SV_DISCLOSURE_PLUS_HC ) ) );
        if( ! rCtrlData.mpDisclosureMinus )
            rCtrlData.mpDisclosureMinus = new Image( BitmapEx( VclResId( SV_DISCLOSURE_MINUS ) ) );
        if( ! rCtrlData.mpDisclosureMinusHC )
            rCtrlData.mpDisclosureMinusHC = new Image( BitmapEx( VclResId( SV_DISCLOSURE_MINUS_HC ) ) );
    
        Image* pImg = NULL;
        if( GetSettings().GetStyleSettings().GetHighContrastMode() )
            pImg = IsChecked() ? rCtrlData.mpDisclosureMinusHC : rCtrlData.mpDisclosurePlusHC;
        else
            pImg = IsChecked() ? rCtrlData.mpDisclosureMinus : rCtrlData.mpDisclosurePlus;
        
        DBG_ASSERT( pImg, "no disclosure image" );
        if( ! pImg )
            return;
    
        sal_uInt16 nStyle = 0;
        if( ! IsEnabled() )
            nStyle |= IMAGE_DRAW_DISABLE;
        
        Size aSize( aStateRect.GetSize() );
        Size aImgSize( pImg->GetSizePixel() );
        Point aOff( (aSize.Width() - aImgSize.Width())/2,
                    (aSize.Height() - aImgSize.Height())/2 );
        aOff += aStateRect.TopLeft();
        DrawImage( aOff, *pImg, nStyle );
    }
}

// -----------------------------------------------------------------------

void DisclosureButton::KeyInput( const KeyEvent& rKEvt )
{
    KeyCode aKeyCode = rKEvt.GetKeyCode();

    if( !aKeyCode.GetModifier()  &&
        ( ( aKeyCode.GetCode() == KEY_ADD ) ||
          ( aKeyCode.GetCode() == KEY_SUBTRACT ) )
        )
    {
        Check( aKeyCode.GetCode() == KEY_ADD );
    }
    else
        Button::KeyInput( rKEvt );
}


