blob: da2e88a101c76f65d5f966c4d758ca972f1af04f [file] [log] [blame]
/**************************************************************
*
* 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_svtools.hxx"
#include <svtools/svlbox.hxx>
#include <svtools/svlbitm.hxx>
#include <vcl/svapp.hxx>
#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif
#include <vcl/decoview.hxx>
#include <vcl/sound.hxx>
#include <vcl/salnativewidgets.hxx>
#define TABOFFS_NOT_VALID -2000000
struct SvLBoxButtonData_Impl
{
SvLBoxEntry* pEntry;
sal_Bool bDefaultImages;
sal_Bool bShowRadioButton;
SvLBoxButtonData_Impl() : pEntry( NULL ), bDefaultImages( sal_False ), bShowRadioButton( sal_False ) {}
};
DBG_NAME(SvLBoxButtonData)
void SvLBoxButtonData::InitData( sal_Bool bImagesFromDefault, bool _bRadioBtn, const Control* pCtrl )
{
pImpl = new SvLBoxButtonData_Impl;
bDataOk = sal_False;
eState = SV_BUTTON_UNCHECKED;
pImpl->bDefaultImages = bImagesFromDefault;
pImpl->bShowRadioButton = ( _bRadioBtn != false );
if ( bImagesFromDefault )
SetDefaultImages( pCtrl );
}
SvLBoxButtonData::SvLBoxButtonData( const Control* pControlForSettings )
{
DBG_CTOR(SvLBoxButtonData,0);
InitData( sal_True, false, pControlForSettings );
}
SvLBoxButtonData::SvLBoxButtonData( const Control* pControlForSettings, bool _bRadioBtn )
{
DBG_CTOR(SvLBoxButtonData,0);
InitData( sal_True, _bRadioBtn, pControlForSettings );
}
SvLBoxButtonData::SvLBoxButtonData()
{
DBG_CTOR(SvLBoxButtonData,0);
InitData( sal_False, false );
}
SvLBoxButtonData::~SvLBoxButtonData()
{
DBG_DTOR(SvLBoxButtonData,0);
delete pImpl;
#ifdef DBG_UTIL
pImpl = NULL;
#endif
}
void SvLBoxButtonData::CallLink()
{
DBG_CHKTHIS(SvLBoxButtonData,0);
aLink.Call( this );
}
sal_uInt16 SvLBoxButtonData::GetIndex( sal_uInt16 nItemState )
{
DBG_CHKTHIS(SvLBoxButtonData,0);
nItemState &= 0x000F;
sal_uInt16 nIdx;
switch( nItemState )
{
case SV_ITEMSTATE_UNCHECKED:
nIdx = SV_BMP_UNCHECKED; break;
case SV_ITEMSTATE_CHECKED:
nIdx = SV_BMP_CHECKED; break;
case SV_ITEMSTATE_TRISTATE:
nIdx = SV_BMP_TRISTATE; break;
case SV_ITEMSTATE_UNCHECKED | SV_ITEMSTATE_HILIGHTED:
nIdx = SV_BMP_HIUNCHECKED; break;
case SV_ITEMSTATE_CHECKED | SV_ITEMSTATE_HILIGHTED:
nIdx = SV_BMP_HICHECKED; break;
case SV_ITEMSTATE_TRISTATE | SV_ITEMSTATE_HILIGHTED:
nIdx = SV_BMP_HITRISTATE; break;
default:
nIdx = SV_BMP_UNCHECKED;
}
return nIdx;
}
void SvLBoxButtonData::SetWidthAndHeight()
{
DBG_CHKTHIS(SvLBoxButtonData,0);
Size aSize = aBmps[0].GetSizePixel();
nWidth = aSize.Width();
nHeight = aSize.Height();
bDataOk = sal_True;
}
void SvLBoxButtonData::StoreButtonState( SvLBoxEntry* pActEntry, sal_uInt16 nItemFlags )
{
DBG_CHKTHIS(SvLBoxButtonData,0);
pImpl->pEntry = pActEntry;
eState = ConvertToButtonState( nItemFlags );
}
SvButtonState SvLBoxButtonData::ConvertToButtonState( sal_uInt16 nItemFlags ) const
{
DBG_CHKTHIS(SvLBoxButtonData,0);
nItemFlags &= (SV_ITEMSTATE_UNCHECKED |
SV_ITEMSTATE_CHECKED |
SV_ITEMSTATE_TRISTATE);
switch( nItemFlags )
{
case SV_ITEMSTATE_UNCHECKED:
return SV_BUTTON_UNCHECKED;
case SV_ITEMSTATE_CHECKED:
return SV_BUTTON_CHECKED;
case SV_ITEMSTATE_TRISTATE:
return SV_BUTTON_TRISTATE;
default:
return SV_BUTTON_UNCHECKED;
}
}
SvLBoxEntry* SvLBoxButtonData::GetActEntry() const
{
DBG_ASSERT( pImpl, "-SvLBoxButtonData::GetActEntry(): don't use me that way!" );
return pImpl->pEntry;
}
void SvLBoxButtonData::SetDefaultImages( const Control* pCtrl )
{
const AllSettings& rSettings = pCtrl? pCtrl->GetSettings() : Application::GetSettings();
if ( pImpl->bShowRadioButton )
{
aBmps[ SV_BMP_UNCHECKED ] = RadioButton::GetRadioImage( rSettings, BUTTON_DRAW_DEFAULT );
aBmps[ SV_BMP_CHECKED ] = RadioButton::GetRadioImage( rSettings, BUTTON_DRAW_CHECKED );
aBmps[ SV_BMP_HICHECKED ] = RadioButton::GetRadioImage( rSettings, BUTTON_DRAW_CHECKED | BUTTON_DRAW_PRESSED );
aBmps[ SV_BMP_HIUNCHECKED ] = RadioButton::GetRadioImage( rSettings, BUTTON_DRAW_DEFAULT | BUTTON_DRAW_PRESSED );
aBmps[ SV_BMP_TRISTATE ] = RadioButton::GetRadioImage( rSettings, BUTTON_DRAW_DONTKNOW );
aBmps[ SV_BMP_HITRISTATE ] = RadioButton::GetRadioImage( rSettings, BUTTON_DRAW_DONTKNOW | BUTTON_DRAW_PRESSED );
}
else
{
aBmps[ SV_BMP_UNCHECKED ] = CheckBox::GetCheckImage( rSettings, BUTTON_DRAW_DEFAULT );
aBmps[ SV_BMP_CHECKED ] = CheckBox::GetCheckImage( rSettings, BUTTON_DRAW_CHECKED );
aBmps[ SV_BMP_HICHECKED ] = CheckBox::GetCheckImage( rSettings, BUTTON_DRAW_CHECKED | BUTTON_DRAW_PRESSED );
aBmps[ SV_BMP_HIUNCHECKED ] = CheckBox::GetCheckImage( rSettings, BUTTON_DRAW_DEFAULT | BUTTON_DRAW_PRESSED );
aBmps[ SV_BMP_TRISTATE ] = CheckBox::GetCheckImage( rSettings, BUTTON_DRAW_DONTKNOW );
aBmps[ SV_BMP_HITRISTATE ] = CheckBox::GetCheckImage( rSettings, BUTTON_DRAW_DONTKNOW | BUTTON_DRAW_PRESSED );
}
}
sal_Bool SvLBoxButtonData::HasDefaultImages( void ) const
{
return pImpl->bDefaultImages;
}
sal_Bool SvLBoxButtonData::IsRadio() {
return pImpl->bShowRadioButton;
}
// ***************************************************************
// class SvLBoxString
// ***************************************************************
DBG_NAME(SvLBoxString);
SvLBoxString::SvLBoxString( SvLBoxEntry* pEntry,sal_uInt16 nFlags,const XubString& rStr) :
SvLBoxItem( pEntry, nFlags )
{
DBG_CTOR(SvLBoxString,0);
SetText( pEntry, rStr );
}
SvLBoxString::SvLBoxString() : SvLBoxItem()
{
DBG_CTOR(SvLBoxString,0);
}
SvLBoxString::~SvLBoxString()
{
DBG_DTOR(SvLBoxString,0);
}
sal_uInt16 SvLBoxString::IsA()
{
DBG_CHKTHIS(SvLBoxString,0);
return SV_ITEM_ID_LBOXSTRING;
}
void SvLBoxString::Paint( const Point& rPos, SvLBox& rDev, sal_uInt16 /* nFlags */,
SvLBoxEntry* _pEntry)
{
DBG_CHKTHIS(SvLBoxString,0);
if ( _pEntry )
{
sal_uInt16 nStyle = rDev.IsEnabled() ? 0 : TEXT_DRAW_DISABLE;
if ( rDev.IsEntryMnemonicsEnabled() )
nStyle |= TEXT_DRAW_MNEMONIC;
rDev.DrawText( Rectangle(rPos,GetSize(&rDev,_pEntry)),aStr,nStyle);
}
else
rDev.DrawText( rPos, aStr);
}
SvLBoxItem* SvLBoxString::Create() const
{
DBG_CHKTHIS(SvLBoxString,0);
return new SvLBoxString;
}
void SvLBoxString::Clone( SvLBoxItem* pSource )
{
DBG_CHKTHIS(SvLBoxString,0);
aStr = ((SvLBoxString*)pSource)->aStr;
}
void SvLBoxString::SetText( SvLBoxEntry*, const XubString& rStr )
{
DBG_CHKTHIS(SvLBoxString,0);
aStr = rStr;
}
void SvLBoxString::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry,
SvViewDataItem* pViewData)
{
DBG_CHKTHIS(SvLBoxString,0);
if( !pViewData )
pViewData = pView->GetViewDataItem( pEntry, this );
pViewData->aSize = Size(pView->GetTextWidth( aStr ), pView->GetTextHeight());
}
// ***************************************************************
// class SvLBoxBmp
// ***************************************************************
DBG_NAME(SvLBoxBmp);
SvLBoxBmp::SvLBoxBmp( SvLBoxEntry* pEntry, sal_uInt16 nFlags, Image aBitmap ) :
SvLBoxItem( pEntry, nFlags )
{
DBG_CTOR(SvLBoxBmp,0);
SetBitmap( pEntry, aBitmap);
}
SvLBoxBmp::SvLBoxBmp() : SvLBoxItem()
{
DBG_CTOR(SvLBoxBmp,0);
}
SvLBoxBmp::~SvLBoxBmp()
{
DBG_DTOR(SvLBoxBmp,0);
}
sal_uInt16 SvLBoxBmp::IsA()
{
DBG_CHKTHIS(SvLBoxBmp,0);
return SV_ITEM_ID_LBOXBMP;
}
void SvLBoxBmp::SetBitmap( SvLBoxEntry*, Image aBitmap)
{
DBG_CHKTHIS(SvLBoxBmp,0);
aBmp = aBitmap;
}
void SvLBoxBmp::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry,
SvViewDataItem* pViewData)
{
DBG_CHKTHIS(SvLBoxBmp,0);
if( !pViewData )
pViewData = pView->GetViewDataItem( pEntry, this );
pViewData->aSize = aBmp.GetSizePixel();
}
void SvLBoxBmp::Paint( const Point& rPos, SvLBox& rDev, sal_uInt16 /* nFlags */,
SvLBoxEntry* )
{
DBG_CHKTHIS(SvLBoxBmp,0);
sal_uInt16 nStyle = rDev.IsEnabled() ? 0 : IMAGE_DRAW_DISABLE;
rDev.DrawImage( rPos, aBmp ,nStyle);
}
SvLBoxItem* SvLBoxBmp::Create() const
{
DBG_CHKTHIS(SvLBoxBmp,0);
return new SvLBoxBmp;
}
void SvLBoxBmp::Clone( SvLBoxItem* pSource )
{
DBG_CHKTHIS(SvLBoxBmp,0);
aBmp = ((SvLBoxBmp*)pSource)->aBmp;
}
// ***************************************************************
// class SvLBoxButton
// ***************************************************************
DBG_NAME(SvLBoxButton);
SvLBoxButton::SvLBoxButton( SvLBoxEntry* pEntry, SvLBoxButtonKind eTheKind,
sal_uInt16 nFlags, SvLBoxButtonData* pBData )
: SvLBoxItem( pEntry, nFlags )
{
DBG_CTOR(SvLBoxButton,0);
eKind = eTheKind;
nBaseOffs = 0;
nItemFlags = 0;
SetStateUnchecked();
pData = pBData;
}
SvLBoxButton::SvLBoxButton() : SvLBoxItem()
{
DBG_CTOR(SvLBoxButton,0);
eKind = SvLBoxButtonKind_enabledCheckbox;
nItemFlags = 0;
SetStateUnchecked();
}
SvLBoxButton::~SvLBoxButton()
{
DBG_DTOR(SvLBoxButton,0);
}
sal_uInt16 SvLBoxButton::IsA()
{
DBG_CHKTHIS(SvLBoxButton,0);
return SV_ITEM_ID_LBOXBUTTON;
}
void SvLBoxButton::Check(SvLBox*, SvLBoxEntry*, sal_Bool bOn)
{
DBG_CHKTHIS(SvLBoxButton,0);
if ( bOn != IsStateChecked() )
{
if ( bOn )
SetStateChecked();
else
SetStateUnchecked();
}
}
sal_Bool SvLBoxButton::ClickHdl( SvLBox*, SvLBoxEntry* pEntry )
{
DBG_CHKTHIS(SvLBoxButton,0);
if ( CheckModification() )
{
if ( IsStateChecked() )
SetStateUnchecked();
else
SetStateChecked();
pData->StoreButtonState( pEntry, nItemFlags );
pData->CallLink();
}
return sal_False;
}
void SvLBoxButton::Paint( const Point& rPos, SvLBox& rDev, sal_uInt16 /* nFlags */,
SvLBoxEntry* /*pEntry*/ )
{
DBG_CHKTHIS(SvLBoxButton,0);
sal_uInt16 nIndex = eKind == SvLBoxButtonKind_staticImage
? SV_BMP_STATICIMAGE : pData->GetIndex( nItemFlags );
sal_uInt16 nStyle = eKind != SvLBoxButtonKind_disabledCheckbox &&
rDev.IsEnabled() ? 0 : IMAGE_DRAW_DISABLE;
///
//Native drawing
///
sal_Bool bNativeOK = sal_False;
ControlType eCtrlType = (pData->IsRadio())? CTRL_RADIOBUTTON : CTRL_CHECKBOX;
if ( nIndex != SV_BMP_STATICIMAGE && rDev.IsNativeControlSupported( eCtrlType, PART_ENTIRE_CONTROL) )
{
Size aSize(pData->Width(), pData->Height());
ImplAdjustBoxSize( aSize, eCtrlType, &rDev );
ImplControlValue aControlValue;
Rectangle aCtrlRegion( rPos, aSize );
ControlState nState = 0;
//states CTRL_STATE_DEFAULT, CTRL_STATE_PRESSED and CTRL_STATE_ROLLOVER are not implemented
if ( IsStateHilighted() ) nState |= CTRL_STATE_FOCUSED;
if ( nStyle != IMAGE_DRAW_DISABLE ) nState |= CTRL_STATE_ENABLED;
if ( IsStateChecked() )
aControlValue.setTristateVal( BUTTONVALUE_ON );
else if ( IsStateUnchecked() )
aControlValue.setTristateVal( BUTTONVALUE_OFF );
else if ( IsStateTristate() )
aControlValue.setTristateVal( BUTTONVALUE_MIXED );
bNativeOK = rDev.DrawNativeControl( eCtrlType, PART_ENTIRE_CONTROL,
aCtrlRegion, nState, aControlValue, rtl::OUString() );
}
if( !bNativeOK)
rDev.DrawImage( rPos, pData->aBmps[nIndex + nBaseOffs] ,nStyle);
}
SvLBoxItem* SvLBoxButton::Create() const
{
DBG_CHKTHIS(SvLBoxButton,0);
return new SvLBoxButton;
}
void SvLBoxButton::Clone( SvLBoxItem* pSource )
{
DBG_CHKTHIS(SvLBoxButton,0);
pData = ((SvLBoxButton*)pSource)->pData;
}
void SvLBoxButton::ImplAdjustBoxSize( Size& io_rSize, ControlType i_eType, Window* i_pParent )
{
if ( i_pParent->IsNativeControlSupported( i_eType, PART_ENTIRE_CONTROL) )
{
ImplControlValue aControlValue;
Rectangle aCtrlRegion( Point( 0, 0 ), io_rSize );
ControlState nState = CTRL_STATE_ENABLED;
aControlValue.setTristateVal( BUTTONVALUE_ON );
Rectangle aNativeBounds, aNativeContent;
bool bNativeOK = i_pParent->GetNativeControlRegion( i_eType,
PART_ENTIRE_CONTROL,
aCtrlRegion,
nState,
aControlValue,
rtl::OUString(),
aNativeBounds,
aNativeContent );
if( bNativeOK )
{
Size aContentSize( aNativeContent.GetSize() );
// leave a little space around the box image (looks better
if( aContentSize.Height() + 2 > io_rSize.Height() )
io_rSize.Height() = aContentSize.Height() + 2;
}
}
}
void SvLBoxButton::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry,
SvViewDataItem* pViewData )
{
DBG_CHKTHIS(SvLBoxButton,0);
if( !pViewData )
pViewData = pView->GetViewDataItem( pEntry, this );
Size aSize( pData->Width(), pData->Height() );
ControlType eCtrlType = (pData->IsRadio())? CTRL_RADIOBUTTON : CTRL_CHECKBOX;
if ( eKind != SvLBoxButtonKind_staticImage && pView )
ImplAdjustBoxSize( aSize, eCtrlType, pView );
pViewData->aSize = aSize;
}
bool SvLBoxButton::CheckModification() const
{
if( eKind == SvLBoxButtonKind_disabledCheckbox )
Sound::Beep();
return eKind == SvLBoxButtonKind_enabledCheckbox;
}
// ***************************************************************
// class SvLBoxContextBmp
// ***************************************************************
struct SvLBoxContextBmp_Impl
{
Image m_aImage1;
Image m_aImage2;
Image m_aImage1_hc;
Image m_aImage2_hc;
sal_uInt16 m_nB2IndicatorFlags;
};
// ***************************************************************
DBG_NAME(SvLBoxContextBmp)
SvLBoxContextBmp::SvLBoxContextBmp( SvLBoxEntry* pEntry, sal_uInt16 nItemFlags,
Image aBmp1, Image aBmp2, sal_uInt16 nEntryFlags )
:SvLBoxItem( pEntry, nItemFlags )
,m_pImpl( new SvLBoxContextBmp_Impl )
{
DBG_CTOR(SvLBoxContextBmp,0);
m_pImpl->m_nB2IndicatorFlags = nEntryFlags;
SetModeImages( aBmp1, aBmp2 );
}
SvLBoxContextBmp::SvLBoxContextBmp()
:SvLBoxItem( )
,m_pImpl( new SvLBoxContextBmp_Impl )
{
m_pImpl->m_nB2IndicatorFlags = 0;
DBG_CTOR(SvLBoxContextBmp,0);
}
SvLBoxContextBmp::~SvLBoxContextBmp()
{
delete m_pImpl;
DBG_DTOR(SvLBoxContextBmp,0);
}
sal_uInt16 SvLBoxContextBmp::IsA()
{
DBG_CHKTHIS(SvLBoxContextBmp,0);
return SV_ITEM_ID_LBOXCONTEXTBMP;
}
sal_Bool SvLBoxContextBmp::SetModeImages( const Image& _rBitmap1, const Image& _rBitmap2, BmpColorMode _eMode )
{
DBG_CHKTHIS(SvLBoxContextBmp,0);
sal_Bool bSuccess = sal_True;
switch ( _eMode )
{
case BMP_COLOR_NORMAL:
m_pImpl->m_aImage1 = _rBitmap1;
m_pImpl->m_aImage2 = _rBitmap2;
break;
case BMP_COLOR_HIGHCONTRAST:
m_pImpl->m_aImage1_hc = _rBitmap1;
m_pImpl->m_aImage2_hc = _rBitmap2;
break;
default:
DBG_ERROR( "SvLBoxContextBmp::SetModeImages: unexpected mode!");
bSuccess = sal_False;
break;
}
return bSuccess;
}
Image& SvLBoxContextBmp::implGetImageStore( sal_Bool _bFirst, BmpColorMode _eMode )
{
DBG_CHKTHIS(SvLBoxContextBmp,0);
switch ( _eMode )
{
case BMP_COLOR_NORMAL:
return _bFirst ? m_pImpl->m_aImage1 : m_pImpl->m_aImage2;
case BMP_COLOR_HIGHCONTRAST:
return _bFirst ? m_pImpl->m_aImage1_hc : m_pImpl->m_aImage2_hc;
default:
DBG_ERROR( "SvLBoxContextBmp::implGetImageStore: unexpected mode!");
}
// OJ: #i27071# wrong mode so we just return the normal images
return _bFirst ? m_pImpl->m_aImage1 : m_pImpl->m_aImage2;
}
void SvLBoxContextBmp::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry,
SvViewDataItem* pViewData)
{
DBG_CHKTHIS(SvLBoxContextBmp,0);
if( !pViewData )
pViewData = pView->GetViewDataItem( pEntry, this );
pViewData->aSize = m_pImpl->m_aImage1.GetSizePixel();
}
void SvLBoxContextBmp::Paint( const Point& _rPos, SvLBox& _rDev,
sal_uInt16 _nViewDataEntryFlags, SvLBoxEntry* _pEntry )
{
DBG_CHKTHIS(SvLBoxContextBmp,0);
// determine the image set
BmpColorMode eMode( BMP_COLOR_NORMAL );
if ( !!m_pImpl->m_aImage1_hc )
{ // we really have HC images
if ( _rDev.GetSettings().GetStyleSettings().GetHighContrastMode() )
eMode = BMP_COLOR_HIGHCONTRAST;
}
// get the image
const Image& rImage = implGetImageStore( 0 == ( _nViewDataEntryFlags & m_pImpl->m_nB2IndicatorFlags ), eMode );
sal_Bool _bSemiTransparent = _pEntry && ( 0 != ( SV_ENTRYFLAG_SEMITRANSPARENT & _pEntry->GetFlags( ) ) );
// draw
sal_uInt16 nStyle = _rDev.IsEnabled() ? 0 : IMAGE_DRAW_DISABLE;
if ( _bSemiTransparent )
nStyle |= IMAGE_DRAW_SEMITRANSPARENT;
_rDev.DrawImage( _rPos, rImage, nStyle);
}
SvLBoxItem* SvLBoxContextBmp::Create() const
{
DBG_CHKTHIS(SvLBoxContextBmp,0);
return new SvLBoxContextBmp;
}
void SvLBoxContextBmp::Clone( SvLBoxItem* pSource )
{
DBG_CHKTHIS(SvLBoxContextBmp,0);
m_pImpl->m_aImage1 = static_cast< SvLBoxContextBmp* >( pSource )->m_pImpl->m_aImage1;
m_pImpl->m_aImage2 = static_cast< SvLBoxContextBmp* >( pSource )->m_pImpl->m_aImage2;
m_pImpl->m_nB2IndicatorFlags = static_cast< SvLBoxContextBmp* >( pSource )->m_pImpl->m_nB2IndicatorFlags;
}