1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  12 #pragma implementation "listbox.h" 
  15 #include "wx/listbox.h" 
  19 #include "wx/dynarray.h" 
  22 #include "wx/checklst.h" 
  23 #include "wx/settings.h" 
  26 #include "wx/tooltip.h" 
  29 #if wxUSE_DRAG_AND_DROP 
  36 //----------------------------------------------------------------------------- 
  38 //----------------------------------------------------------------------------- 
  40 extern void wxapp_install_idle_handler(); 
  43 //------------------------------------------------------------------------- 
  44 // conditional compilation 
  45 //------------------------------------------------------------------------- 
  47 #if (GTK_MINOR_VERSION > 0) 
  48     #define NEW_GTK_SCROLL_CODE 
  51 //----------------------------------------------------------------------------- 
  53 //----------------------------------------------------------------------------- 
  55 #if wxUSE_CHECKLISTBOX 
  57 #define CHECKBOX_STRING "[-] " 
  59 // checklistboxes have "[±] " prepended to their lables, this macro removes it 
  60 // (NB: 4 below is the length of CHECKBOX_STRING above) 
  62 // the argument to it is a "const char *" pointer 
  63 #define GET_REAL_LABEL(label) ((m_hasCheckBoxes)?(label)+4 : (label)) 
  65 #else // !wxUSE_CHECKLISTBOX 
  67 #define GET_REAL_LABEL(label) (label) 
  69 #endif // wxUSE_CHECKLISTBOX 
  71 //----------------------------------------------------------------------------- 
  73 //----------------------------------------------------------------------------- 
  75 extern bool   g_blockEventsOnDrag
; 
  76 extern bool   g_blockEventsOnScroll
; 
  78 static bool   g_hasDoubleClicked 
= FALSE
; 
  80 //----------------------------------------------------------------------------- 
  81 // "button_release_event" 
  82 //----------------------------------------------------------------------------- 
  84 /* we would normally emit a wxEVT_COMMAND_LISTBOX_DOUBLECLICKED event once 
  85    a GDK_2BUTTON_PRESS occurs, but this has the particular problem of the 
  86    listbox keeping the focus until it receives a GDK_BUTTON_RELEASE event. 
  87    this can lead to race conditions so that we emit the dclick event 
  88    after the GDK_BUTTON_RELEASE event after the GDK_2BUTTON_PRESS event */ 
  91 gtk_listbox_button_release_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxListBox 
*listbox 
) 
  93     if (g_isIdle
) wxapp_install_idle_handler(); 
  95     if (g_blockEventsOnDrag
) return FALSE
; 
  96     if (g_blockEventsOnScroll
) return FALSE
; 
  98     if (!listbox
->m_hasVMT
) return FALSE
; 
 100     if (!g_hasDoubleClicked
) return FALSE
; 
 102         wxCommandEvent 
event( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
, listbox
->GetId() ); 
 103         event
.SetEventObject( listbox 
); 
 105         wxArrayInt aSelections
; 
 106         int count 
= listbox
->GetSelections(aSelections
); 
 109             event
.m_commandInt 
= aSelections
[0] ; 
 110             event
.m_clientData 
= listbox
->GetClientData( event
.m_commandInt 
); 
 111             wxString 
str(listbox
->GetString(event
.m_commandInt
)); 
 112             if (!str
.IsEmpty()) event
.m_commandString 
= str
; 
 116             event
.m_commandInt 
= -1 ; 
 117             event
.m_commandString
.Empty(); 
 120         listbox
->GetEventHandler()->ProcessEvent( event 
); 
 125 //----------------------------------------------------------------------------- 
 126 // "button_press_event" 
 127 //----------------------------------------------------------------------------- 
 130 gtk_listbox_button_press_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxListBox 
*listbox 
) 
 132     if (g_isIdle
) wxapp_install_idle_handler(); 
 134     if (g_blockEventsOnDrag
) return FALSE
; 
 135     if (g_blockEventsOnScroll
) return FALSE
; 
 137     if (!listbox
->m_hasVMT
) return FALSE
; 
 139     int sel 
= listbox
->GetIndex( widget 
); 
 141 #if wxUSE_CHECKLISTBOX 
 142     if ((listbox
->m_hasCheckBoxes
) && (gdk_event
->x 
< 15) && (gdk_event
->type 
!= GDK_2BUTTON_PRESS
)) 
 144         wxCheckListBox 
*clb 
= (wxCheckListBox 
*)listbox
; 
 146         clb
->Check( sel
, !clb
->IsChecked(sel
) ); 
 148         wxCommandEvent 
event( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
, listbox
->GetId() ); 
 149         event
.SetEventObject( listbox 
); 
 151         listbox
->GetEventHandler()->ProcessEvent( event 
); 
 153 #endif // wxUSE_CHECKLISTBOX 
 155     /* emit wxEVT_COMMAND_LISTBOX_DOUBLECLICKED later */ 
 156     g_hasDoubleClicked 
= (gdk_event
->type 
== GDK_2BUTTON_PRESS
); 
 161 //----------------------------------------------------------------------------- 
 163 //----------------------------------------------------------------------------- 
 165 #if wxUSE_CHECKLISTBOX 
 167 gtk_listbox_key_press_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxListBox 
*listbox 
) 
 169     if (g_isIdle
) wxapp_install_idle_handler(); 
 171     if (g_blockEventsOnDrag
) return FALSE
; 
 173     if (!listbox
->m_hasVMT
) return FALSE
; 
 175     if (gdk_event
->keyval 
!= ' ') return FALSE
; 
 177     int sel 
= listbox
->GetIndex( widget 
); 
 179     wxCheckListBox 
*clb 
= (wxCheckListBox 
*)listbox
; 
 181     clb
->Check( sel
, !clb
->IsChecked(sel
) ); 
 183     wxCommandEvent 
event( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
, listbox
->GetId() ); 
 184     event
.SetEventObject( listbox 
); 
 186     listbox
->GetEventHandler()->ProcessEvent( event 
); 
 190 #endif // wxUSE_CHECKLISTBOX 
 192 //----------------------------------------------------------------------------- 
 193 // "select" and "deselect" 
 194 //----------------------------------------------------------------------------- 
 196 static void gtk_listitem_select_callback( GtkWidget 
*WXUNUSED(widget
), wxListBox 
*listbox 
) 
 198     if (g_isIdle
) wxapp_install_idle_handler(); 
 200     if (!listbox
->m_hasVMT
) return; 
 201     if (g_blockEventsOnDrag
) return; 
 203     wxCommandEvent 
event(wxEVT_COMMAND_LISTBOX_SELECTED
, listbox
->GetId() ); 
 205     wxArrayInt aSelections
; 
 206     int count 
= listbox
->GetSelections(aSelections
); 
 209         event
.m_commandInt 
= aSelections
[0] ; 
 210         event
.m_clientData 
= listbox
->GetClientData( event
.m_commandInt 
); 
 211         wxString 
str(listbox
->GetString(event
.m_commandInt
)); 
 212         if (!str
.IsEmpty()) event
.m_commandString 
= str
; 
 216         event
.m_commandInt 
= -1 ; 
 217         event
.m_commandString
.Empty(); 
 220     event
.SetEventObject( listbox 
); 
 222     listbox
->GetEventHandler()->ProcessEvent( event 
); 
 225 //----------------------------------------------------------------------------- 
 227 //----------------------------------------------------------------------------- 
 229 IMPLEMENT_DYNAMIC_CLASS(wxListBox
,wxControl
) 
 231 wxListBox::wxListBox() 
 233     m_list 
= (GtkList 
*) NULL
; 
 234 #if wxUSE_CHECKLISTBOX 
 235     m_hasCheckBoxes 
= FALSE
; 
 236 #endif // wxUSE_CHECKLISTBOX 
 239 bool wxListBox::Create( wxWindow 
*parent
, wxWindowID id
, 
 240                         const wxPoint 
&pos
, const wxSize 
&size
, 
 241                         int n
, const wxString choices
[], 
 242                         long style
, const wxValidator
& validator
, const wxString 
&name 
) 
 245     m_acceptsFocus 
= TRUE
; 
 247     PreCreation( parent
, id
, pos
, size
, style
, name 
); 
 249     SetValidator( validator 
); 
 251     m_widget 
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL 
); 
 252     if (style 
& wxLB_ALWAYS_SB
) 
 254       gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(m_widget
), 
 255         GTK_POLICY_AUTOMATIC
, GTK_POLICY_ALWAYS 
); 
 259       gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(m_widget
), 
 260         GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC 
); 
 263     m_list 
= GTK_LIST( gtk_list_new() ); 
 265     GtkSelectionMode mode 
= GTK_SELECTION_BROWSE
; 
 266     if (style 
& wxLB_MULTIPLE
) 
 267         mode 
= GTK_SELECTION_MULTIPLE
; 
 268     else if (style 
& wxLB_EXTENDED
) 
 269         mode 
= GTK_SELECTION_EXTENDED
; 
 271     gtk_list_set_selection_mode( GTK_LIST(m_list
), mode 
); 
 273 #ifdef NEW_GTK_SCROLL_CODE 
 274     gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), GTK_WIDGET(m_list
) ); 
 276     gtk_container_add( GTK_CONTAINER(m_widget
), GTK_WIDGET(m_list
) ); 
 279     gtk_widget_show( GTK_WIDGET(m_list
) ); 
 281     wxSize newSize 
= size
; 
 282     if (newSize
.x 
== -1) newSize
.x 
= 100; 
 283     if (newSize
.y 
== -1) newSize
.y 
= 110; 
 284     SetSize( newSize
.x
, newSize
.y 
); 
 286     for (int i 
= 0; i 
< n
; i
++) 
 288         m_clientDataList
.Append( (wxObject
*) NULL 
); 
 289         m_clientObjectList
.Append( (wxObject
*) NULL 
); 
 291         GtkWidget 
*list_item
; 
 293         wxString 
str(choices
[i
]); 
 294 #if wxUSE_CHECKLISTBOX 
 297             str
.Prepend(CHECKBOX_STRING
); 
 299 #endif // wxUSE_CHECKLISTBOX 
 301         list_item 
= gtk_list_item_new_with_label( str
.mbc_str() ); 
 303         gtk_container_add( GTK_CONTAINER(m_list
), list_item 
); 
 305         gtk_signal_connect( GTK_OBJECT(list_item
), "select", 
 306           GTK_SIGNAL_FUNC(gtk_listitem_select_callback
), (gpointer
)this ); 
 308         if (style 
& wxLB_MULTIPLE
) 
 309             gtk_signal_connect( GTK_OBJECT(list_item
), "deselect", 
 310               GTK_SIGNAL_FUNC(gtk_listitem_select_callback
), (gpointer
)this ); 
 312         gtk_signal_connect( GTK_OBJECT(list_item
), 
 313                             "button_press_event", 
 314                             (GtkSignalFunc
)gtk_listbox_button_press_callback
, 
 317         gtk_signal_connect_after( GTK_OBJECT(list_item
), 
 318                             "button_release_event", 
 319                             (GtkSignalFunc
)gtk_listbox_button_release_callback
, 
 322 #if wxUSE_CHECKLISTBOX 
 325             gtk_signal_connect( GTK_OBJECT(list_item
), 
 327                             (GtkSignalFunc
)gtk_listbox_key_press_callback
, 
 330 #endif // wxUSE_CHECKLISTBOX 
 332         ConnectWidget( list_item 
); 
 334         gtk_widget_show( list_item 
); 
 337     m_parent
->DoAddChild( this ); 
 341     SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_WINDOW 
) ); 
 342     SetForegroundColour( parent
->GetForegroundColour() ); 
 343     SetFont( parent
->GetFont() ); 
 350 wxListBox::~wxListBox() 
 355 void wxListBox::InsertItems(int nItems
, const wxString items
[], int pos
) 
 357     wxCHECK_RET( m_list 
!= NULL
, _T("invalid listbox") ); 
 359     GList 
*children 
= m_list
->children
; 
 360     int length 
= g_list_length(children
); 
 361     wxCHECK_RET( pos 
<= length
, _T("invalid index in wxListBox::InsertItems") ); 
 363     // VZ: it seems that GTK 1.0.6 doesn't has a function to insert an item 
 364     //     into a listbox at the given position, this is why we first delete 
 365     //     all items after this position, then append these items and then 
 366     //     reappend back the old ones. 
 368     // first detach the old items 
 373         // no need to do anything complicated 
 374         for ( n 
= 0; n 
< nItems
; n
++ ) 
 382     wxArrayString deletedLabels
; 
 383     wxArrayPtrVoid deletedData
; 
 384     wxArrayInt deletedChecks
;   // only for check list boxes 
 386     GList 
*child 
= g_list_nth( children
, pos 
); 
 387     for ( n 
= 0; child 
!= NULL
; n
++, child 
= child
->next 
) 
 390         GtkBin 
*bin 
= GTK_BIN( child
->data 
); 
 391         GtkLabel 
*label 
= GTK_LABEL( bin
->child 
); 
 393         wxString 
str(GET_REAL_LABEL(label
->label
),*wxConvCurrent
); 
 394         deletedLabels
.Add(str
); 
 397         void *clientData 
= NULL
; 
 400         if ( n 
< (int)m_clientObjectList
.GetCount() ) 
 401             node 
= m_clientObjectList
.Nth( n 
); 
 405             clientData 
= node
->GetData(); 
 406             m_clientObjectList
.DeleteNode( node 
); 
 411             if ( n 
< (int)m_clientDataList
.GetCount() ) 
 412                 node 
= m_clientDataList
.Nth( n 
);         
 416                 clientData 
= node
->GetData(); 
 417                 node 
= m_clientDataList
.Nth( n 
); 
 421         deletedData
.Add(clientData
); 
 423 #if wxUSE_CHECKLISTBOX 
 425         if ( m_hasCheckBoxes 
) 
 427             deletedChecks
.Add(((wxCheckListBox 
*)this)->IsChecked(pos 
+ n
)); 
 429 #endif // wxUSE_CHECKLISTBOX 
 432     int nDeletedCount 
= n
; 
 434     gtk_list_clear_items( m_list
, pos
, length 
); 
 436     // now append the new items 
 437     for ( n 
= 0; n 
< nItems
; n
++ ) 
 442     // and append the old items too 
 443     pos 
+= nItems
;  // now the indices are shifter 
 444     for ( n 
= 0; n 
< nDeletedCount
; n
++ ) 
 446         Append(deletedLabels
[n
], deletedData
[n
]); 
 448 #if wxUSE_CHECKLISTBOX 
 449         if ( m_hasCheckBoxes 
) 
 451             ((wxCheckListBox 
*)this)->Check(pos 
+ n
, (bool)deletedChecks
[n
]); 
 453 #endif // wxUSE_CHECKLISTBOX 
 457 void wxListBox::AppendCommon( const wxString 
&item 
) 
 459     wxCHECK_RET( m_list 
!= NULL
, _T("invalid listbox") ); 
 461     GtkWidget 
*list_item
; 
 463     wxString 
label(item
); 
 464 #if wxUSE_CHECKLISTBOX 
 467         label
.Prepend(CHECKBOX_STRING
); 
 469 #endif // wxUSE_CHECKLISTBOX 
 471     list_item 
= gtk_list_item_new_with_label( label
.mbc_str() ); 
 473     gtk_container_add( GTK_CONTAINER(m_list
), list_item 
); 
 475     gtk_signal_connect( GTK_OBJECT(list_item
), "select", 
 476       GTK_SIGNAL_FUNC(gtk_listitem_select_callback
), (gpointer
)this ); 
 478     if (HasFlag(wxLB_MULTIPLE
)) 
 479         gtk_signal_connect( GTK_OBJECT(list_item
), "deselect", 
 480           GTK_SIGNAL_FUNC(gtk_listitem_select_callback
), (gpointer
)this ); 
 482     gtk_signal_connect( GTK_OBJECT(list_item
), 
 483                         "button_press_event", 
 484                         (GtkSignalFunc
)gtk_listbox_button_press_callback
, 
 487     gtk_signal_connect_after( GTK_OBJECT(list_item
), 
 488                         "button_release_event", 
 489                         (GtkSignalFunc
)gtk_listbox_button_release_callback
, 
 492 #if wxUSE_CHECKLISTBOX 
 495        gtk_signal_connect( GTK_OBJECT(list_item
), 
 497                            (GtkSignalFunc
)gtk_listbox_key_press_callback
, 
 500 #endif // wxUSE_CHECKLISTBOX 
 502     gtk_widget_show( list_item 
); 
 504     ConnectWidget( list_item 
); 
 506     if (GTK_WIDGET_REALIZED(m_widget
)) 
 508         gtk_widget_realize( list_item 
); 
 509         gtk_widget_realize( GTK_BIN(list_item
)->child 
); 
 511         if (m_widgetStyle
) ApplyWidgetStyle(); 
 513 #if wxUSE_DRAG_AND_DROP 
 514 #ifndef NEW_GTK_DND_CODE 
 515         if (m_dropTarget
) m_dropTarget
->RegisterWidget( list_item 
); 
 520         if (m_tooltip
) m_tooltip
->Apply( this ); 
 525 void wxListBox::Append( const wxString 
&item 
) 
 527     m_clientDataList
.Append( (wxObject
*) NULL 
); 
 528     m_clientObjectList
.Append( (wxObject
*) NULL 
); 
 530     AppendCommon( item 
); 
 533 void wxListBox::Append( const wxString 
&item
, void *clientData 
) 
 535     m_clientDataList
.Append( (wxObject
*) clientData 
); 
 536     m_clientObjectList
.Append( (wxObject
*) NULL 
); 
 538     AppendCommon( item 
); 
 541 void wxListBox::Append( const wxString 
&item
, wxClientData 
*clientData 
) 
 543     m_clientObjectList
.Append( (wxObject
*) clientData 
); 
 544     m_clientDataList
.Append( (wxObject
*) NULL 
); 
 546     AppendCommon( item 
); 
 549 void wxListBox::SetClientData( int n
, void* clientData 
) 
 551     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid combobox") ); 
 553     wxNode 
*node 
= m_clientDataList
.Nth( n 
); 
 556     node
->SetData( (wxObject
*) clientData 
); 
 559 void* wxListBox::GetClientData( int n 
) 
 561     wxCHECK_MSG( m_widget 
!= NULL
, NULL
, _T("invalid combobox") ); 
 563     wxNode 
*node 
= m_clientDataList
.Nth( n 
); 
 564     if (!node
) return NULL
; 
 569 void wxListBox::SetClientObject( int n
, wxClientData
* clientData 
) 
 571     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid combobox") ); 
 573     wxNode 
*node 
= m_clientObjectList
.Nth( n 
); 
 576     wxClientData 
*cd 
= (wxClientData
*) node
->Data(); 
 579     node
->SetData( (wxObject
*) clientData 
); 
 582 wxClientData
* wxListBox::GetClientObject( int n 
) 
 584     wxCHECK_MSG( m_widget 
!= NULL
, (wxClientData
*)NULL
, _T("invalid combobox") ); 
 586     wxNode 
*node 
= m_clientObjectList
.Nth( n 
); 
 587     if (!node
) return (wxClientData
*) NULL
; 
 589     return (wxClientData
*) node
->Data(); 
 592 void wxListBox::Clear() 
 594     wxCHECK_RET( m_list 
!= NULL
, _T("invalid listbox") ); 
 596     gtk_list_clear_items( m_list
, 0, Number() ); 
 598     wxNode 
*node 
= m_clientObjectList
.First(); 
 601         wxClientData 
*cd 
= (wxClientData
*)node
->Data(); 
 605     m_clientObjectList
.Clear(); 
 607     m_clientDataList
.Clear(); 
 610 void wxListBox::Delete( int n 
) 
 612     wxCHECK_RET( m_list 
!= NULL
, _T("invalid listbox") ); 
 614     GList 
*child 
= g_list_nth( m_list
->children
, n 
); 
 616     wxCHECK_RET( child
, _T("wrong listbox index") ); 
 618     GList 
*list 
= g_list_append( (GList
*) NULL
, child
->data 
); 
 619     gtk_list_remove_items( m_list
, list 
); 
 622     wxNode 
*node 
= m_clientObjectList
.Nth( n 
); 
 625         wxClientData 
*cd 
= (wxClientData
*)node
->Data(); 
 627         m_clientObjectList
.DeleteNode( node 
); 
 630     node 
= m_clientDataList
.Nth( n 
); 
 633         m_clientDataList
.DeleteNode( node 
); 
 637 void wxListBox::Deselect( int n 
) 
 639     wxCHECK_RET( m_list 
!= NULL
, _T("invalid listbox") ); 
 641     gtk_list_unselect_item( m_list
, n 
); 
 644 int wxListBox::FindString( const wxString 
&item 
) const 
 646     wxCHECK_MSG( m_list 
!= NULL
, -1, _T("invalid listbox") ); 
 648     GList 
*child 
= m_list
->children
; 
 652         GtkBin 
*bin 
= GTK_BIN( child
->data 
); 
 653         GtkLabel 
*label 
= GTK_LABEL( bin
->child 
); 
 655         wxString str 
= wxString(GET_REAL_LABEL(label
->label
),*wxConvCurrent
); 
 664   // it's not an error if the string is not found -> no wxCHECK 
 669 int wxListBox::GetSelection() const 
 671     wxCHECK_MSG( m_list 
!= NULL
, -1, _T("invalid listbox") ); 
 673     GList 
*child 
= m_list
->children
; 
 677         if (GTK_WIDGET(child
->data
)->state 
== GTK_STATE_SELECTED
) return count
; 
 684 int wxListBox::GetSelections( wxArrayInt
& aSelections 
) const 
 686     wxCHECK_MSG( m_list 
!= NULL
, -1, _T("invalid listbox") ); 
 688     // get the number of selected items first 
 689     GList 
*child 
= m_list
->children
; 
 691     for (child 
= m_list
->children
; child 
!= NULL
; child 
= child
->next
) 
 693         if (GTK_WIDGET(child
->data
)->state 
== GTK_STATE_SELECTED
) 
 702         aSelections
.Alloc(count
); // optimization attempt 
 704         for (child 
= m_list
->children
; child 
!= NULL
; child 
= child
->next
, i
++) 
 706             if (GTK_WIDGET(child
->data
)->state 
== GTK_STATE_SELECTED
) 
 714 wxString 
wxListBox::GetString( int n 
) const 
 716     wxCHECK_MSG( m_list 
!= NULL
, _T(""), _T("invalid listbox") ); 
 718     GList 
*child 
= g_list_nth( m_list
->children
, n 
); 
 721         GtkBin 
*bin 
= GTK_BIN( child
->data 
); 
 722         GtkLabel 
*label 
= GTK_LABEL( bin
->child 
); 
 724         wxString str 
= wxString(GET_REAL_LABEL(label
->label
),*wxConvCurrent
); 
 729     wxFAIL_MSG(_T("wrong listbox index")); 
 734 wxString 
wxListBox::GetStringSelection() const 
 736     wxCHECK_MSG( m_list 
!= NULL
, _T(""), _T("invalid listbox") ); 
 738     GList 
*selection 
= m_list
->selection
; 
 741         GtkBin 
*bin 
= GTK_BIN( selection
->data 
); 
 742         GtkLabel 
*label 
= GTK_LABEL( bin
->child 
); 
 744         wxString str 
= wxString(GET_REAL_LABEL(label
->label
),*wxConvCurrent
); 
 749     wxFAIL_MSG(_T("no listbox selection available")); 
 753 int wxListBox::Number() 
 755     wxCHECK_MSG( m_list 
!= NULL
, -1, _T("invalid listbox") ); 
 757     GList 
*child 
= m_list
->children
; 
 759     while (child
) { count
++; child 
= child
->next
; } 
 763 bool wxListBox::Selected( int n 
) 
 765     wxCHECK_MSG( m_list 
!= NULL
, FALSE
, _T("invalid listbox") ); 
 767     GList 
*target 
= g_list_nth( m_list
->children
, n 
); 
 770         GList 
*child 
= m_list
->selection
; 
 773             if (child
->data 
== target
->data
) return TRUE
; 
 777     wxFAIL_MSG(_T("wrong listbox index")); 
 781 void wxListBox::Set( int WXUNUSED(n
), const wxString 
*WXUNUSED(choices
) ) 
 783     wxFAIL_MSG(_T("wxListBox::Set not implemented")); 
 786 void wxListBox::SetFirstItem( int WXUNUSED(n
) ) 
 788     wxFAIL_MSG(_T("wxListBox::SetFirstItem not implemented")); 
 791 void wxListBox::SetFirstItem( const wxString 
&WXUNUSED(item
) ) 
 793     wxFAIL_MSG(_T("wxListBox::SetFirstItem not implemented")); 
 796 void wxListBox::SetSelection( int n
, bool select 
) 
 798     wxCHECK_RET( m_list 
!= NULL
, _T("invalid listbox") ); 
 801         gtk_list_select_item( m_list
, n 
); 
 803         gtk_list_unselect_item( m_list
, n 
); 
 806 void wxListBox::SetString( int n
, const wxString 
&string 
) 
 808     wxCHECK_RET( m_list 
!= NULL
, _T("invalid listbox") ); 
 810     GList 
*child 
= g_list_nth( m_list
->children
, n 
); 
 813         GtkBin 
*bin 
= GTK_BIN( child
->data 
); 
 814         GtkLabel 
*label 
= GTK_LABEL( bin
->child 
); 
 817 #if wxUSE_CHECKLISTBOX 
 819             str 
+= CHECKBOX_STRING
; 
 820 #endif // wxUSE_CHECKLISTBOX 
 823         gtk_label_set( label
, str
.mbc_str() ); 
 827         wxFAIL_MSG(_T("wrong listbox index")); 
 831 void wxListBox::SetStringSelection( const wxString 
&string
, bool select 
) 
 833     wxCHECK_RET( m_list 
!= NULL
, _T("invalid listbox") ); 
 835     SetSelection( FindString(string
), select 
); 
 838 int wxListBox::GetIndex( GtkWidget 
*item 
) const 
 842         GList 
*child 
= m_list
->children
; 
 846             if (GTK_WIDGET(child
->data
) == item
) return count
; 
 855 void wxListBox::ApplyToolTip( GtkTooltips 
*tips
, const wxChar 
*tip 
) 
 857     GList 
*child 
= m_list
->children
; 
 860         gtk_tooltips_set_tip( tips
, GTK_WIDGET( child
->data 
), wxConvLocal
.cWX2MB(tip
), (gchar
*) NULL 
); 
 864 #endif // wxUSE_TOOLTIPS 
 866 #if wxUSE_DRAG_AND_DROP 
 867 void wxListBox::SetDropTarget( wxDropTarget 
*dropTarget 
) 
 869     wxCHECK_RET( m_list 
!= NULL
, _T("invalid listbox") ); 
 871 #ifndef NEW_GTK_DND_CODE 
 874         GList 
*child 
= m_list
->children
; 
 877             m_dropTarget
->UnregisterWidget( GTK_WIDGET( child
->data 
) ); 
 883     wxWindow::SetDropTarget( dropTarget 
); 
 885 #ifndef NEW_GTK_DND_CODE 
 888         GList 
*child 
= m_list
->children
; 
 891             m_dropTarget
->RegisterWidget( GTK_WIDGET( child
->data 
) ); 
 899 GtkWidget 
*wxListBox::GetConnectWidget() 
 901     return GTK_WIDGET(m_list
); 
 904 bool wxListBox::IsOwnGtkWindow( GdkWindow 
*window 
) 
 906     if (wxWindow::IsOwnGtkWindow( window 
)) return TRUE
; 
 908     GList 
*child 
= m_list
->children
; 
 911         GtkWidget 
*bin 
= GTK_WIDGET( child
->data 
); 
 912         if (bin
->window 
== window
) return TRUE
; 
 919 void wxListBox::ApplyWidgetStyle() 
 923     if (m_backgroundColour
.Ok()) 
 925         GdkWindow 
*window 
= GTK_WIDGET(m_list
)->window
; 
 928             m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window 
) ); 
 929             gdk_window_set_background( window
, m_backgroundColour
.GetColor() ); 
 930             gdk_window_clear( window 
); 
 934     GList 
*child 
= m_list
->children
; 
 937         gtk_widget_set_style( GTK_WIDGET(child
->data
), m_widgetStyle 
); 
 939         GtkBin 
*bin 
= GTK_BIN( child
->data 
); 
 940         GtkWidget 
*label 
= GTK_WIDGET( bin
->child 
); 
 941         gtk_widget_set_style( label
, m_widgetStyle 
);