1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svtools/treelistbox.hxx>
21 #include <svtools/svlbitm.hxx>
22 #include "svtools/treelistentry.hxx"
23 #include "svtools/viewdataentry.hxx"
24 #include <vcl/svapp.hxx>
25 #include <vcl/button.hxx>
26 #include <vcl/decoview.hxx>
27 #include <vcl/salnativewidgets.hxx>
29 struct SvLBoxButtonData_Impl
31 SvTreeListEntry
* pEntry
;
32 sal_Bool bDefaultImages
;
33 sal_Bool bShowRadioButton
;
35 SvLBoxButtonData_Impl() : pEntry( NULL
), bDefaultImages( sal_False
), bShowRadioButton( sal_False
) {}
39 DBG_NAME(SvLBoxButtonData
)
41 void SvLBoxButtonData::InitData( sal_Bool bImagesFromDefault
, bool _bRadioBtn
, const Control
* pCtrl
)
43 pImpl
= new SvLBoxButtonData_Impl
;
46 eState
= SV_BUTTON_UNCHECKED
;
47 pImpl
->bDefaultImages
= bImagesFromDefault
;
48 pImpl
->bShowRadioButton
= ( _bRadioBtn
!= false );
50 if ( bImagesFromDefault
)
51 SetDefaultImages( pCtrl
);
54 SvLBoxButtonData::SvLBoxButtonData( const Control
* pControlForSettings
)
56 DBG_CTOR(SvLBoxButtonData
,0);
58 InitData( sal_True
, false, pControlForSettings
);
61 SvLBoxButtonData::SvLBoxButtonData( const Control
* pControlForSettings
, bool _bRadioBtn
)
63 DBG_CTOR(SvLBoxButtonData
,0);
65 InitData( sal_True
, _bRadioBtn
, pControlForSettings
);
68 SvLBoxButtonData::~SvLBoxButtonData()
70 DBG_DTOR(SvLBoxButtonData
,0);
78 void SvLBoxButtonData::CallLink()
80 DBG_CHKTHIS(SvLBoxButtonData
,0);
84 sal_uInt16
SvLBoxButtonData::GetIndex( sal_uInt16 nItemState
)
86 DBG_CHKTHIS(SvLBoxButtonData
,0);
91 case SV_ITEMSTATE_UNCHECKED
:
92 nIdx
= SV_BMP_UNCHECKED
; break;
93 case SV_ITEMSTATE_CHECKED
:
94 nIdx
= SV_BMP_CHECKED
; break;
95 case SV_ITEMSTATE_TRISTATE
:
96 nIdx
= SV_BMP_TRISTATE
; break;
97 case SV_ITEMSTATE_UNCHECKED
| SV_ITEMSTATE_HILIGHTED
:
98 nIdx
= SV_BMP_HIUNCHECKED
; break;
99 case SV_ITEMSTATE_CHECKED
| SV_ITEMSTATE_HILIGHTED
:
100 nIdx
= SV_BMP_HICHECKED
; break;
101 case SV_ITEMSTATE_TRISTATE
| SV_ITEMSTATE_HILIGHTED
:
102 nIdx
= SV_BMP_HITRISTATE
; break;
104 nIdx
= SV_BMP_UNCHECKED
;
109 void SvLBoxButtonData::SetWidthAndHeight()
111 DBG_CHKTHIS(SvLBoxButtonData
,0);
112 Size aSize
= aBmps
[0].GetSizePixel();
113 nWidth
= aSize
.Width();
114 nHeight
= aSize
.Height();
119 void SvLBoxButtonData::StoreButtonState( SvTreeListEntry
* pActEntry
, sal_uInt16 nItemFlags
)
121 DBG_CHKTHIS(SvLBoxButtonData
,0);
122 pImpl
->pEntry
= pActEntry
;
123 eState
= ConvertToButtonState( nItemFlags
);
126 SvButtonState
SvLBoxButtonData::ConvertToButtonState( sal_uInt16 nItemFlags
) const
128 DBG_CHKTHIS(SvLBoxButtonData
,0);
129 nItemFlags
&= (SV_ITEMSTATE_UNCHECKED
|
130 SV_ITEMSTATE_CHECKED
|
131 SV_ITEMSTATE_TRISTATE
);
134 case SV_ITEMSTATE_UNCHECKED
:
135 return SV_BUTTON_UNCHECKED
;
137 case SV_ITEMSTATE_CHECKED
:
138 return SV_BUTTON_CHECKED
;
140 case SV_ITEMSTATE_TRISTATE
:
141 return SV_BUTTON_TRISTATE
;
143 return SV_BUTTON_UNCHECKED
;
147 SvTreeListEntry
* SvLBoxButtonData::GetActEntry() const
149 DBG_ASSERT( pImpl
, "-SvLBoxButtonData::GetActEntry(): don't use me that way!" );
150 return pImpl
->pEntry
;
153 void SvLBoxButtonData::SetDefaultImages( const Control
* pCtrl
)
155 const AllSettings
& rSettings
= pCtrl
? pCtrl
->GetSettings() : Application::GetSettings();
157 if ( pImpl
->bShowRadioButton
)
159 aBmps
[ SV_BMP_UNCHECKED
] = RadioButton::GetRadioImage( rSettings
, BUTTON_DRAW_DEFAULT
);
160 aBmps
[ SV_BMP_CHECKED
] = RadioButton::GetRadioImage( rSettings
, BUTTON_DRAW_CHECKED
);
161 aBmps
[ SV_BMP_HICHECKED
] = RadioButton::GetRadioImage( rSettings
, BUTTON_DRAW_CHECKED
| BUTTON_DRAW_PRESSED
);
162 aBmps
[ SV_BMP_HIUNCHECKED
] = RadioButton::GetRadioImage( rSettings
, BUTTON_DRAW_DEFAULT
| BUTTON_DRAW_PRESSED
);
163 aBmps
[ SV_BMP_TRISTATE
] = RadioButton::GetRadioImage( rSettings
, BUTTON_DRAW_DONTKNOW
);
164 aBmps
[ SV_BMP_HITRISTATE
] = RadioButton::GetRadioImage( rSettings
, BUTTON_DRAW_DONTKNOW
| BUTTON_DRAW_PRESSED
);
168 aBmps
[ SV_BMP_UNCHECKED
] = CheckBox::GetCheckImage( rSettings
, BUTTON_DRAW_DEFAULT
);
169 aBmps
[ SV_BMP_CHECKED
] = CheckBox::GetCheckImage( rSettings
, BUTTON_DRAW_CHECKED
);
170 aBmps
[ SV_BMP_HICHECKED
] = CheckBox::GetCheckImage( rSettings
, BUTTON_DRAW_CHECKED
| BUTTON_DRAW_PRESSED
);
171 aBmps
[ SV_BMP_HIUNCHECKED
] = CheckBox::GetCheckImage( rSettings
, BUTTON_DRAW_DEFAULT
| BUTTON_DRAW_PRESSED
);
172 aBmps
[ SV_BMP_TRISTATE
] = CheckBox::GetCheckImage( rSettings
, BUTTON_DRAW_DONTKNOW
);
173 aBmps
[ SV_BMP_HITRISTATE
] = CheckBox::GetCheckImage( rSettings
, BUTTON_DRAW_DONTKNOW
| BUTTON_DRAW_PRESSED
);
177 sal_Bool
SvLBoxButtonData::HasDefaultImages( void ) const
179 return pImpl
->bDefaultImages
;
182 sal_Bool
SvLBoxButtonData::IsRadio() {
183 return pImpl
->bShowRadioButton
;
186 // ***************************************************************
187 // class SvLBoxString
188 // ***************************************************************
190 DBG_NAME(SvLBoxString
);
192 SvLBoxString::SvLBoxString(SvTreeListEntry
* pEntry
, sal_uInt16 nFlags
, const OUString
& rStr
)
193 : SvLBoxItem(pEntry
, nFlags
)
195 DBG_CTOR(SvLBoxString
,0);
199 SvLBoxString::SvLBoxString() : SvLBoxItem()
201 DBG_CTOR(SvLBoxString
,0);
204 SvLBoxString::~SvLBoxString()
206 DBG_DTOR(SvLBoxString
,0);
209 sal_uInt16
SvLBoxString::GetType() const
211 DBG_CHKTHIS(SvLBoxString
,0);
212 return SV_ITEM_ID_LBOXSTRING
;
215 void SvLBoxString::Paint(
216 const Point
& rPos
, SvTreeListBox
& rDev
, const SvViewDataEntry
* /*pView*/,
217 const SvTreeListEntry
* pEntry
)
219 DBG_CHKTHIS(SvLBoxString
,0);
222 sal_uInt16 nStyle
= rDev
.IsEnabled() ? 0 : TEXT_DRAW_DISABLE
;
223 if ( rDev
.IsEntryMnemonicsEnabled() )
224 nStyle
|= TEXT_DRAW_MNEMONIC
;
225 rDev
.DrawText(Rectangle(rPos
, GetSize(&rDev
, pEntry
)), maText
, nStyle
);
228 rDev
.DrawText(rPos
, maText
);
232 SvLBoxItem
* SvLBoxString::Create() const
234 DBG_CHKTHIS(SvLBoxString
,0);
235 return new SvLBoxString
;
238 void SvLBoxString::Clone( SvLBoxItem
* pSource
)
240 DBG_CHKTHIS(SvLBoxString
,0);
241 maText
= ((SvLBoxString
*)pSource
)->maText
;
244 void SvLBoxString::InitViewData(
245 SvTreeListBox
* pView
, SvTreeListEntry
* pEntry
, SvViewDataItem
* pViewData
)
247 DBG_CHKTHIS(SvLBoxString
,0);
249 pViewData
= pView
->GetViewDataItem( pEntry
, this );
251 // fdo#72125: GetTextWidth() can get very expensive; let's just count
252 // an approximate width using a cached value when we have many entries
254 if (pView
->GetEntryCount() > 100)
256 static SvTreeListBox
*pPreviousView
= NULL
;
257 static float fApproximateCharWidth
= 0.0;
258 if (pPreviousView
!= pView
)
260 pPreviousView
= pView
;
261 fApproximateCharWidth
= pView
->approximate_char_width();
263 nTextWidth
= maText
.getLength() * fApproximateCharWidth
;
266 nTextWidth
= pView
->GetTextWidth(maText
);
268 pViewData
->maSize
= Size(nTextWidth
, pView
->GetTextHeight());
271 // ***************************************************************
273 // ***************************************************************
277 SvLBoxBmp::SvLBoxBmp() : SvLBoxItem()
279 DBG_CTOR(SvLBoxBmp
,0);
282 SvLBoxBmp::~SvLBoxBmp()
284 DBG_DTOR(SvLBoxBmp
,0);
287 sal_uInt16
SvLBoxBmp::GetType() const
289 DBG_CHKTHIS(SvLBoxBmp
,0);
290 return SV_ITEM_ID_LBOXBMP
;
293 void SvLBoxBmp::InitViewData( SvTreeListBox
* pView
,SvTreeListEntry
* pEntry
,
294 SvViewDataItem
* pViewData
)
296 DBG_CHKTHIS(SvLBoxBmp
,0);
298 pViewData
= pView
->GetViewDataItem( pEntry
, this );
299 pViewData
->maSize
= aBmp
.GetSizePixel();
302 void SvLBoxBmp::Paint(
303 const Point
& rPos
, SvTreeListBox
& rDev
, const SvViewDataEntry
* /*pView*/,
304 const SvTreeListEntry
* /*pEntry*/)
306 DBG_CHKTHIS(SvLBoxBmp
,0);
307 sal_uInt16 nStyle
= rDev
.IsEnabled() ? 0 : IMAGE_DRAW_DISABLE
;
308 rDev
.DrawImage( rPos
, aBmp
,nStyle
);
311 SvLBoxItem
* SvLBoxBmp::Create() const
313 DBG_CHKTHIS(SvLBoxBmp
,0);
314 return new SvLBoxBmp
;
317 void SvLBoxBmp::Clone( SvLBoxItem
* pSource
)
319 DBG_CHKTHIS(SvLBoxBmp
,0);
320 aBmp
= ((SvLBoxBmp
*)pSource
)->aBmp
;
323 // ***************************************************************
324 // class SvLBoxButton
325 // ***************************************************************
327 DBG_NAME(SvLBoxButton
);
329 SvLBoxButton::SvLBoxButton( SvTreeListEntry
* pEntry
, SvLBoxButtonKind eTheKind
,
330 sal_uInt16 nFlags
, SvLBoxButtonData
* pBData
)
331 : SvLBoxItem( pEntry
, nFlags
)
333 DBG_CTOR(SvLBoxButton
,0);
342 SvLBoxButton::SvLBoxButton() : SvLBoxItem()
344 DBG_CTOR(SvLBoxButton
,0);
345 eKind
= SvLBoxButtonKind_enabledCheckbox
;
350 SvLBoxButton::~SvLBoxButton()
352 DBG_DTOR(SvLBoxButton
,0);
355 sal_uInt16
SvLBoxButton::GetType() const
357 DBG_CHKTHIS(SvLBoxButton
,0);
358 return SV_ITEM_ID_LBOXBUTTON
;
361 sal_Bool
SvLBoxButton::ClickHdl( SvTreeListBox
*, SvTreeListEntry
* pEntry
)
363 DBG_CHKTHIS(SvLBoxButton
,0);
364 if ( CheckModification() )
366 if ( IsStateChecked() )
370 pData
->StoreButtonState( pEntry
, nItemFlags
);
376 void SvLBoxButton::Paint(
377 const Point
& rPos
, SvTreeListBox
& rDev
, const SvViewDataEntry
* /*pView*/,
378 const SvTreeListEntry
* /*pEntry*/)
380 DBG_CHKTHIS(SvLBoxButton
,0);
381 sal_uInt16 nIndex
= eKind
== SvLBoxButtonKind_staticImage
382 ? SV_BMP_STATICIMAGE
: pData
->GetIndex( nItemFlags
);
383 sal_uInt16 nStyle
= eKind
!= SvLBoxButtonKind_disabledCheckbox
&&
384 rDev
.IsEnabled() ? 0 : IMAGE_DRAW_DISABLE
;
389 sal_Bool bNativeOK
= sal_False
;
390 ControlType eCtrlType
= (pData
->IsRadio())? CTRL_RADIOBUTTON
: CTRL_CHECKBOX
;
391 if ( nIndex
!= SV_BMP_STATICIMAGE
&& rDev
.IsNativeControlSupported( eCtrlType
, PART_ENTIRE_CONTROL
) )
394 Size
aSize(pData
->Width(), pData
->Height());
395 ImplAdjustBoxSize( aSize
, eCtrlType
, &rDev
);
396 ImplControlValue aControlValue
;
397 Rectangle
aCtrlRegion( rPos
, aSize
);
398 ControlState nState
= 0;
400 //states CTRL_STATE_DEFAULT, CTRL_STATE_PRESSED and CTRL_STATE_ROLLOVER are not implemented
401 if ( IsStateHilighted() ) nState
|= CTRL_STATE_FOCUSED
;
402 if ( nStyle
!= IMAGE_DRAW_DISABLE
) nState
|= CTRL_STATE_ENABLED
;
404 if ( IsStateChecked() )
405 aControlValue
.setTristateVal( BUTTONVALUE_ON
);
406 else if ( IsStateUnchecked() )
407 aControlValue
.setTristateVal( BUTTONVALUE_OFF
);
408 else if ( IsStateTristate() )
409 aControlValue
.setTristateVal( BUTTONVALUE_MIXED
);
412 bNativeOK
= rDev
.DrawNativeControl( eCtrlType
, PART_ENTIRE_CONTROL
,
413 aCtrlRegion
, nState
, aControlValue
, OUString() );
416 if( !bNativeOK
&& isVis
)
417 rDev
.DrawImage( rPos
, pData
->aBmps
[nIndex
+ nBaseOffs
] ,nStyle
);
420 SvLBoxItem
* SvLBoxButton::Create() const
422 DBG_CHKTHIS(SvLBoxButton
,0);
423 return new SvLBoxButton
;
426 void SvLBoxButton::Clone( SvLBoxItem
* pSource
)
428 DBG_CHKTHIS(SvLBoxButton
,0);
429 pData
= ((SvLBoxButton
*)pSource
)->pData
;
432 void SvLBoxButton::ImplAdjustBoxSize( Size
& io_rSize
, ControlType i_eType
, Window
* i_pParent
)
434 if ( i_pParent
->IsNativeControlSupported( i_eType
, PART_ENTIRE_CONTROL
) )
436 ImplControlValue aControlValue
;
437 Rectangle
aCtrlRegion( Point( 0, 0 ), io_rSize
);
438 ControlState nState
= CTRL_STATE_ENABLED
;
440 aControlValue
.setTristateVal( BUTTONVALUE_ON
);
442 Rectangle aNativeBounds
, aNativeContent
;
443 bool bNativeOK
= i_pParent
->GetNativeControlRegion( i_eType
,
453 Size
aContentSize( aNativeContent
.GetSize() );
454 // leave a little space around the box image (looks better)
455 if( aContentSize
.Height() + 2 > io_rSize
.Height() )
456 io_rSize
.Height() = aContentSize
.Height() + 2;
457 if( aContentSize
.Width() + 2 > io_rSize
.Width() )
458 io_rSize
.Width() = aContentSize
.Width() + 2;
463 void SvLBoxButton::InitViewData( SvTreeListBox
* pView
,SvTreeListEntry
* pEntry
,
464 SvViewDataItem
* pViewData
)
466 DBG_CHKTHIS(SvLBoxButton
,0);
468 pViewData
= pView
->GetViewDataItem( pEntry
, this );
469 Size
aSize( pData
->Width(), pData
->Height() );
471 ControlType eCtrlType
= (pData
->IsRadio())? CTRL_RADIOBUTTON
: CTRL_CHECKBOX
;
472 if ( eKind
!= SvLBoxButtonKind_staticImage
&& pView
)
473 ImplAdjustBoxSize( aSize
, eCtrlType
, pView
);
474 pViewData
->maSize
= aSize
;
477 bool SvLBoxButton::CheckModification() const
479 return eKind
== SvLBoxButtonKind_enabledCheckbox
;
482 void SvLBoxButton::SetStateInvisible()
487 // ***************************************************************
488 // class SvLBoxContextBmp
489 // ***************************************************************
491 struct SvLBoxContextBmp_Impl
499 // ***************************************************************
500 DBG_NAME(SvLBoxContextBmp
)
502 SvLBoxContextBmp::SvLBoxContextBmp(
503 SvTreeListEntry
* pEntry
, sal_uInt16 nItemFlags
, Image aBmp1
, Image aBmp2
,
505 :SvLBoxItem( pEntry
, nItemFlags
)
506 ,m_pImpl( new SvLBoxContextBmp_Impl
)
508 DBG_CTOR(SvLBoxContextBmp
,0);
510 m_pImpl
->m_bExpanded
= bExpanded
;
511 SetModeImages( aBmp1
, aBmp2
);
514 SvLBoxContextBmp::SvLBoxContextBmp()
516 ,m_pImpl( new SvLBoxContextBmp_Impl
)
518 m_pImpl
->m_bExpanded
= false;
519 DBG_CTOR(SvLBoxContextBmp
,0);
522 SvLBoxContextBmp::~SvLBoxContextBmp()
525 DBG_DTOR(SvLBoxContextBmp
,0);
528 sal_uInt16
SvLBoxContextBmp::GetType() const
530 DBG_CHKTHIS(SvLBoxContextBmp
,0);
531 return SV_ITEM_ID_LBOXCONTEXTBMP
;
534 sal_Bool
SvLBoxContextBmp::SetModeImages( const Image
& _rBitmap1
, const Image
& _rBitmap2
)
536 DBG_CHKTHIS(SvLBoxContextBmp
,0);
538 sal_Bool bSuccess
= sal_True
;
539 m_pImpl
->m_aImage1
= _rBitmap1
;
540 m_pImpl
->m_aImage2
= _rBitmap2
;
544 Image
& SvLBoxContextBmp::implGetImageStore( sal_Bool _bFirst
)
546 DBG_CHKTHIS(SvLBoxContextBmp
,0);
548 // OJ: #i27071# wrong mode so we just return the normal images
549 return _bFirst
? m_pImpl
->m_aImage1
: m_pImpl
->m_aImage2
;
552 void SvLBoxContextBmp::InitViewData( SvTreeListBox
* pView
,SvTreeListEntry
* pEntry
,
553 SvViewDataItem
* pViewData
)
555 DBG_CHKTHIS(SvLBoxContextBmp
,0);
557 pViewData
= pView
->GetViewDataItem( pEntry
, this );
558 pViewData
->maSize
= m_pImpl
->m_aImage1
.GetSizePixel();
561 void SvLBoxContextBmp::Paint(
562 const Point
& _rPos
, SvTreeListBox
& _rDev
,
563 const SvViewDataEntry
* pView
, const SvTreeListEntry
* pEntry
)
565 DBG_CHKTHIS(SvLBoxContextBmp
,0);
568 const Image
& rImage
= implGetImageStore(pView
->IsExpanded() != m_pImpl
->m_bExpanded
);
570 sal_Bool _bSemiTransparent
= pEntry
&& ( 0 != ( SV_ENTRYFLAG_SEMITRANSPARENT
& pEntry
->GetFlags( ) ) );
572 sal_uInt16 nStyle
= _rDev
.IsEnabled() ? 0 : IMAGE_DRAW_DISABLE
;
573 if ( _bSemiTransparent
)
574 nStyle
|= IMAGE_DRAW_SEMITRANSPARENT
;
575 _rDev
.DrawImage( _rPos
, rImage
, nStyle
);
578 SvLBoxItem
* SvLBoxContextBmp::Create() const
580 DBG_CHKTHIS(SvLBoxContextBmp
,0);
581 return new SvLBoxContextBmp
;
584 void SvLBoxContextBmp::Clone( SvLBoxItem
* pSource
)
586 DBG_CHKTHIS(SvLBoxContextBmp
,0);
587 m_pImpl
->m_aImage1
= static_cast< SvLBoxContextBmp
* >( pSource
)->m_pImpl
->m_aImage1
;
588 m_pImpl
->m_aImage2
= static_cast< SvLBoxContextBmp
* >( pSource
)->m_pImpl
->m_aImage2
;
589 m_pImpl
->m_bExpanded
= static_cast<SvLBoxContextBmp
*>(pSource
)->m_pImpl
->m_bExpanded
;
592 long SvLBoxButtonData::Width()
599 long SvLBoxButtonData::Height()
606 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */