1 /////////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     implementation of wxCheckListBox class 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  13 // headers & declarations 
  14 // ============================================================================ 
  17 #pragma implementation "checklst.h" 
  22 #if wxUSE_CHECKLISTBOX 
  24 #include "wx/checklst.h" 
  25 #include "wx/arrstr.h" 
  27 #include "wx/mac/uma.h" 
  28 #include <Appearance.h> 
  30 // ============================================================================ 
  31 // implementation of wxCheckListBox 
  32 // ============================================================================ 
  34 IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox
, wxListBox
) 
  36 BEGIN_EVENT_TABLE(wxCheckListBox
, wxListBox
) 
  39 const short kTextColumnId 
= 1024 ; 
  40 const short kCheckboxColumnId 
= 1025 ; 
  42 // new databrowser based version 
  45 void wxCheckListBox::Init() 
  49 bool wxCheckListBox::Create(wxWindow 
*parent
, 
  53                             const wxArrayString
& choices
, 
  55                             const wxValidator
& validator
, 
  58     wxCArrayString 
chs(choices
); 
  60     return Create(parent
, id
, pos
, size
, chs
.GetCount(), chs
.GetStrings(), 
  61                   style
, validator
, name
); 
  64 #if TARGET_API_MAC_OSX 
  65 static pascal void DataBrowserItemNotificationProc(ControlRef browser
, DataBrowserItemID itemID
,  
  66     DataBrowserItemNotification message
, DataBrowserItemDataRef itemData
) 
  68 static pascal  void DataBrowserItemNotificationProc(ControlRef browser
, DataBrowserItemID itemID
,  
  69     DataBrowserItemNotification message
) 
  72     long ref 
= GetControlReference( browser 
) ; 
  75         wxCheckListBox
* list 
= wxDynamicCast( (wxObject
*) ref 
, wxCheckListBox 
) ; 
  76         size_t i 
= itemID 
- 1 ; 
  77         if (i 
>= 0 && i 
< list
->GetCount() ) 
  79             bool trigger 
= false ; 
  81                 wxEVT_COMMAND_LISTBOX_SELECTED
, list
->GetId() ); 
  84                 case kDataBrowserItemDeselected 
: 
  85                     if ( list
->HasMultipleSelection() ) 
  88                 case kDataBrowserItemSelected 
: 
  91                 case kDataBrowserItemDoubleClicked 
: 
  92                     event
.SetEventType(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
) ; 
 101                 event
.SetEventObject( list 
); 
 102                 if ( list
->HasClientObjectData() ) 
 103                     event
.SetClientObject( list
->GetClientObject(i
) ); 
 104                 else if ( list
->HasClientUntypedData() ) 
 105                     event
.SetClientData( list
->GetClientData(i
) ); 
 106                 event
.SetString( list
->GetString(i
) ); 
 108                 event
.SetExtraLong( list
->HasMultipleSelection() ? message 
== kDataBrowserItemSelected 
: TRUE 
); 
 109                 wxPostEvent( list
->GetEventHandler() , event 
) ; 
 110                 // direct notification is not always having the listbox GetSelection() having in synch with event 
 111                 // list->GetEventHandler()->ProcessEvent(event) ;  
 118 static pascal OSStatus 
ListBoxGetSetItemData(ControlRef browser
,  
 119     DataBrowserItemID itemID
, DataBrowserPropertyID property
,  
 120     DataBrowserItemDataRef itemData
, Boolean changeValue
) 
 122         OSStatus err 
= errDataBrowserPropertyNotSupported
; 
 131                     long ref 
= GetControlReference( browser 
) ; 
 134                         wxCheckListBox
* list 
= wxDynamicCast( (wxObject
*) ref 
, wxCheckListBox 
) ; 
 135                     size_t i 
= itemID 
- 1 ; 
 136                     if (i 
>= 0 && i 
< list
->GetCount() ) 
 138                                 wxMacCFStringHolder 
cf( list
->GetString(i
) , list
->GetFont().GetEncoding() ) ; 
 139                                 verify_noerr( ::SetDataBrowserItemDataText( itemData 
, cf 
) ) ; 
 145             case kCheckboxColumnId 
: 
 147                     long ref 
= GetControlReference( browser 
) ; 
 150                         wxCheckListBox
* list 
= wxDynamicCast( (wxObject
*) ref 
, wxCheckListBox 
) ; 
 151                     size_t i 
= itemID 
- 1 ; 
 152                     if (i 
>= 0 && i 
< list
->GetCount() ) 
 154                                 verify_noerr( ::SetDataBrowserItemDataButtonValue( itemData 
, list
->IsChecked( i 
) ? kThemeButtonOn 
: kThemeButtonOff 
) ) ; 
 160                 case kDataBrowserItemIsEditableProperty
: 
 162                     err 
= ::SetDataBrowserItemDataBooleanValue(itemData
, true); 
 174                 case kCheckboxColumnId 
: 
 176                     long ref 
= GetControlReference( browser 
) ; 
 179                         wxCheckListBox
* list 
= wxDynamicCast( (wxObject
*) ref 
, wxCheckListBox 
) ; 
 180                     size_t i 
= itemID 
- 1 ; 
 181                     if (i 
>= 0 && i 
< list
->GetCount() ) 
 183                                 // we have to change this behind the back, since Check() would be triggering another update round 
 184                         bool newVal 
= !list
->IsChecked( i 
) ; 
 185                                 verify_noerr( ::SetDataBrowserItemDataButtonValue( itemData 
, newVal 
? kThemeButtonOn 
: kThemeButtonOff 
) ) ; 
 187                                 list
->m_checks
[ i 
] = newVal 
; 
 189                         wxCommandEvent 
event(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
, list
->GetId()); 
 191                         event
.SetEventObject(list
); 
 192                         list
->GetEventHandler()->ProcessEvent(event
); 
 206 bool wxCheckListBox::Create(wxWindow 
*parent
, wxWindowID id
, 
 209                        int n
, const wxString choices
[], 
 211                        const wxValidator
& validator
, 
 212                        const wxString
& name
) 
 214     m_macIsUserPane 
= FALSE 
; 
 216     wxASSERT_MSG( !(style 
& wxLB_MULTIPLE
) || !(style 
& wxLB_EXTENDED
), 
 217                   _T("only one of listbox selection modes can be specified") ); 
 219     if ( !wxListBoxBase::Create(parent
, id
, pos
, size
, style 
& ~(wxHSCROLL
|wxVSCROLL
), validator
, name
) ) 
 222     m_noItems 
= 0 ; // this will be increased by our append command 
 225     Rect bounds 
= wxMacGetBoundsForControl( this , pos 
, size 
) ; 
 227     m_peer 
= new wxMacControl() ; 
 228     verify_noerr( ::CreateDataBrowserControl( MAC_WXHWND(parent
->MacGetTopLevelWindowRef()), &bounds
, kDataBrowserListView 
, m_peer
->GetControlRefAddr() ) ); 
 231     DataBrowserSelectionFlags  options 
= kDataBrowserDragSelect 
; 
 232     if ( style 
& wxLB_MULTIPLE 
) 
 234         options 
+= kDataBrowserAlwaysExtendSelection 
+ kDataBrowserCmdTogglesSelection  
; 
 236     else if ( style 
& wxLB_EXTENDED 
) 
 242         options 
+= kDataBrowserSelectOnlyOne 
; 
 244     verify_noerr(m_peer
->SetSelectionFlags( options 
) );  
 246     DataBrowserListViewColumnDesc columnDesc 
; 
 247     columnDesc
.headerBtnDesc
.titleOffset 
= 0; 
 248         columnDesc
.headerBtnDesc
.version 
= kDataBrowserListViewLatestHeaderDesc
; 
 250         columnDesc
.headerBtnDesc
.btnFontStyle
.flags     
=  
 251                 kControlUseFontMask 
| kControlUseJustMask
; 
 253         columnDesc
.headerBtnDesc
.btnContentInfo
.contentType 
= kControlNoContent
; 
 254         columnDesc
.headerBtnDesc
.btnFontStyle
.just 
= teFlushDefault
; 
 255         columnDesc
.headerBtnDesc
.btnFontStyle
.font 
= kControlFontViewSystemFont
; 
 256         columnDesc
.headerBtnDesc
.btnFontStyle
.style 
= normal
; 
 257         columnDesc
.headerBtnDesc
.titleString 
= NULL 
; // CFSTR( "" ); 
 261         columnDesc
.headerBtnDesc
.minimumWidth 
= 30 ; 
 262         columnDesc
.headerBtnDesc
.maximumWidth 
= 30; 
 264         columnDesc
.propertyDesc
.propertyID 
= kCheckboxColumnId
; 
 265         columnDesc
.propertyDesc
.propertyType 
= kDataBrowserCheckboxType
; 
 266         columnDesc
.propertyDesc
.propertyFlags 
= kDataBrowserPropertyIsMutable 
| kDataBrowserTableViewSelectionColumn 
| 
 267                                             kDataBrowserDefaultPropertyFlags
; 
 268         verify_noerr( m_peer
->AddListViewColumn( &columnDesc
, kDataBrowserListViewAppendColumn
) ) ; 
 272         columnDesc
.headerBtnDesc
.minimumWidth 
= 0; 
 273         columnDesc
.headerBtnDesc
.maximumWidth 
= 10000; 
 275         columnDesc
.propertyDesc
.propertyID 
= kTextColumnId
; 
 276         columnDesc
.propertyDesc
.propertyType 
= kDataBrowserTextType
; 
 277         columnDesc
.propertyDesc
.propertyFlags 
= kDataBrowserTableViewSelectionColumn
 
 278 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 
 279          | kDataBrowserListViewTypeSelectColumn
 
 284         verify_noerr( m_peer
->AddListViewColumn( &columnDesc
, kDataBrowserListViewAppendColumn
) ) ; 
 286     verify_noerr( m_peer
->AutoSizeListViewColumns() ) ; 
 287     verify_noerr( m_peer
->SetHasScrollBars( false , true ) ) ; 
 288     verify_noerr( m_peer
->SetTableViewHiliteStyle( kDataBrowserTableViewFillHilite  
) ) ; 
 289     verify_noerr( m_peer
->SetListViewHeaderBtnHeight(0 ) ) ; 
 291     DataBrowserCallbacks callbacks 
; 
 292     callbacks
.version 
= kDataBrowserLatestCallbacks
; 
 293     InitDataBrowserCallbacks(&callbacks
); 
 294     callbacks
.u
.v1
.itemDataCallback 
= NewDataBrowserItemDataUPP(ListBoxGetSetItemData
);  
 295         callbacks
.u
.v1
.itemNotificationCallback 
= 
 296 #if TARGET_API_MAC_OSX 
 297             (DataBrowserItemNotificationUPP
) NewDataBrowserItemNotificationWithItemUPP(DataBrowserItemNotificationProc
) ; 
 299             NewDataBrowserItemNotificationUPP(DataBrowserItemNotificationProc
) ; 
 301     m_peer
->SetCallbacks( &callbacks
); 
 303     MacPostControlCreate(pos
,size
) ; 
 305     for ( int i 
= 0 ; i 
< n 
; i
++ ) 
 307         Append( choices
[i
] ) ; 
 310     SetBestSize(size
);   // Needed because it is a wxControlWithItems 
 315 // ---------------------------------------------------------------------------- 
 316 // wxCheckListBox functions 
 317 // ---------------------------------------------------------------------------- 
 319 bool wxCheckListBox::IsChecked(size_t item
) const 
 321     wxCHECK_MSG( item 
< m_checks
.GetCount(), FALSE
, 
 322                  _T("invalid index in wxCheckListBox::IsChecked") ); 
 324     return m_checks
[item
] != 0; 
 327 void wxCheckListBox::Check(size_t item
, bool check
) 
 329     wxCHECK_RET( item 
< m_checks
.GetCount(), 
 330                  _T("invalid index in wxCheckListBox::Check") ); 
 332     bool isChecked 
= m_checks
[item
] != 0; 
 333     if ( check 
!= isChecked 
) 
 335         m_checks
[item
] = check
; 
 336         UInt32 id 
= item 
+ 1 ; 
 337         verify_noerr( m_peer
->UpdateItems(kDataBrowserNoItem 
, 1 , &id 
, kDataBrowserItemNoProperty 
, kDataBrowserItemNoProperty 
) ) ; 
 341 // ---------------------------------------------------------------------------- 
 342 // methods forwarded to wxCheckListBox 
 343 // ---------------------------------------------------------------------------- 
 345 void wxCheckListBox::Delete(int n
) 
 347     wxCHECK_RET( n 
< GetCount(), _T("invalid index in wxCheckListBox::Delete") ); 
 349     wxListBox::Delete(n
); 
 351     m_checks
.RemoveAt(n
); 
 354 int wxCheckListBox::DoAppend(const wxString
& item
) 
 356     int pos 
= wxListBox::DoAppend(item
); 
 358     // the item is initially unchecked 
 359     m_checks
.Insert(FALSE
, pos
); 
 364 void wxCheckListBox::DoInsertItems(const wxArrayString
& items
, int pos
) 
 366     wxListBox::DoInsertItems(items
, pos
); 
 368     size_t count 
= items
.GetCount(); 
 369     for ( size_t n 
= 0; n 
< count
; n
++ ) 
 371         m_checks
.Insert(FALSE
, pos 
+ n
); 
 375 void wxCheckListBox::DoSetItems(const wxArrayString
& items
, void **clientData
) 
 377     // call it first as it does DoClear() 
 378     wxListBox::DoSetItems(items
, clientData
); 
 380     size_t count 
= items
.GetCount(); 
 381     for ( size_t n 
= 0; n 
< count
; n
++ ) 
 387 void wxCheckListBox::DoClear() 
 392 #endif // wxUSE_CHECKLISTBOX