-wxListBox::wxListBox(void)
-{
- m_list = (GtkList *) NULL;
-}
-
-bool wxListBox::Create( wxWindow *parent, wxWindowID id,
- const wxPoint &pos, const wxSize &size,
- int n, const wxString choices[],
- long style, const wxValidator& validator, const wxString &name )
-{
- m_needParent = TRUE;
-
- PreCreation( parent, id, pos, size, style, name );
-
- SetValidator( validator );
-
- m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL );
- gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(m_widget),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
-
- m_list = GTK_LIST( gtk_list_new() );
-
- // @@ what's the difference between BROWSE and SINGLE?
- GtkSelectionMode mode = GTK_SELECTION_BROWSE;
- if ( style & wxLB_MULTIPLE )
- mode = GTK_SELECTION_MULTIPLE;
- else if ( style & wxLB_EXTENDED )
- mode = GTK_SELECTION_EXTENDED;
-
- gtk_list_set_selection_mode( GTK_LIST(m_list), mode );
-
- gtk_container_add (GTK_CONTAINER(m_widget), GTK_WIDGET(m_list) );
- gtk_widget_show( GTK_WIDGET(m_list) );
-
- for (int i = 0; i < n; i++)
- {
+wxListBox::wxListBox()
+{
+ m_list = (GtkList *) NULL;
+#if wxUSE_CHECKLISTBOX
+ m_hasCheckBoxes = FALSE;
+#endif // wxUSE_CHECKLISTBOX
+}
+
+bool wxListBox::Create( wxWindow *parent, wxWindowID id,
+ const wxPoint &pos, const wxSize &size,
+ int n, const wxString choices[],
+ long style, const wxValidator& validator, const wxString &name )
+{
+ m_needParent = TRUE;
+ m_acceptsFocus = TRUE;
+
+ PreCreation( parent, id, pos, size, style, name );
+
+#if wxUSE_VALIDATORS
+ SetValidator( validator );
+#endif
+
+ m_widget = gtk_scrolled_window_new( (GtkAdjustment*) NULL, (GtkAdjustment*) NULL );
+ if (style & wxLB_ALWAYS_SB)
+ {
+ gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(m_widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS );
+ }
+ else
+ {
+ gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(m_widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
+ }
+
+ m_list = GTK_LIST( gtk_list_new() );
+
+ GtkSelectionMode mode = GTK_SELECTION_BROWSE;
+ if (style & wxLB_MULTIPLE)
+ mode = GTK_SELECTION_MULTIPLE;
+ else if (style & wxLB_EXTENDED)
+ mode = GTK_SELECTION_EXTENDED;
+
+ gtk_list_set_selection_mode( GTK_LIST(m_list), mode );
+
+#ifdef NEW_GTK_SCROLL_CODE
+ gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget), GTK_WIDGET(m_list) );
+#else
+ gtk_container_add( GTK_CONTAINER(m_widget), GTK_WIDGET(m_list) );
+#endif
+
+ gtk_widget_show( GTK_WIDGET(m_list) );
+
+ wxSize newSize = size;
+ if (newSize.x == -1) newSize.x = 100;
+ if (newSize.y == -1) newSize.y = 110;
+ SetSize( newSize.x, newSize.y );
+
+ for (int i = 0; i < n; i++)
+ {
+ m_clientDataList.Append( (wxObject*) NULL );
+ m_clientObjectList.Append( (wxObject*) NULL );
+
+ GtkWidget *list_item;
+
+ wxString str(choices[i]);
+#if wxUSE_CHECKLISTBOX
+ if (m_hasCheckBoxes)
+ {
+ str.Prepend(CHECKBOX_STRING);
+ }
+#endif // wxUSE_CHECKLISTBOX
+
+ list_item = gtk_list_item_new_with_label( str.mbc_str() );
+
+ gtk_container_add( GTK_CONTAINER(m_list), list_item );
+
+ gtk_signal_connect( GTK_OBJECT(list_item), "select",
+ GTK_SIGNAL_FUNC(gtk_listitem_select_callback), (gpointer)this );
+
+ if (style & wxLB_MULTIPLE)
+ gtk_signal_connect( GTK_OBJECT(list_item), "deselect",
+ GTK_SIGNAL_FUNC(gtk_listitem_select_callback), (gpointer)this );
+
+ gtk_signal_connect( GTK_OBJECT(list_item),
+ "button_press_event",
+ (GtkSignalFunc)gtk_listbox_button_press_callback,
+ (gpointer) this );
+
+ gtk_signal_connect_after( GTK_OBJECT(list_item),
+ "button_release_event",
+ (GtkSignalFunc)gtk_listbox_button_release_callback,
+ (gpointer) this );
+
+#if wxUSE_CHECKLISTBOX
+ if (m_hasCheckBoxes)
+ {
+ gtk_signal_connect( GTK_OBJECT(list_item),
+ "key_press_event",
+ (GtkSignalFunc)gtk_listbox_key_press_callback,
+ (gpointer)this );
+ }
+#endif // wxUSE_CHECKLISTBOX
+
+ ConnectWidget( list_item );
+
+ gtk_widget_show( list_item );
+ }
+
+ m_parent->DoAddChild( this );
+
+ PostCreation();
+
+ SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_WINDOW ) );
+ SetForegroundColour( parent->GetForegroundColour() );
+ SetFont( parent->GetFont() );
+
+ Show( TRUE );
+
+ return TRUE;
+}
+
+wxListBox::~wxListBox()
+{
+ Clear();
+}
+
+void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
+{
+ wxCHECK_RET( m_list != NULL, _T("invalid listbox") );
+
+ GList *children = m_list->children;
+ int length = g_list_length(children);
+ wxCHECK_RET( pos <= length, _T("invalid index in wxListBox::InsertItems") );
+
+ // VZ: it seems that GTK 1.0.6 doesn't has a function to insert an item
+ // into a listbox at the given position, this is why we first delete
+ // all items after this position, then append these items and then
+ // reappend back the old ones.
+
+ // first detach the old items
+ int n; // loop var
+
+ if ( pos == length )
+ {
+ // no need to do anything complicated
+ for ( n = 0; n < nItems; n++ )
+ {
+ Append(items[n]);
+ }
+
+ return;
+ }
+
+ wxArrayString deletedLabels;
+ wxArrayPtrVoid deletedData;
+ wxArrayInt deletedChecks; // only for check list boxes
+
+ GList *child = g_list_nth( children, pos );
+ for ( n = 0; child != NULL; n++, child = child->next )
+ {
+ // save label
+ GtkBin *bin = GTK_BIN( child->data );
+ GtkLabel *label = GTK_LABEL( bin->child );
+
+ wxString str(GET_REAL_LABEL(label->label),*wxConvCurrent);
+ deletedLabels.Add(str);
+
+ // save data
+ void *clientData = NULL;
+ wxNode *node = NULL;
+
+ if ( n < (int)m_clientObjectList.GetCount() )
+ node = m_clientObjectList.Nth( n );
+
+ if ( node )
+ {
+ clientData = node->GetData();
+ m_clientObjectList.DeleteNode( node );
+ }
+
+ if ( !clientData )
+ {
+ if ( n < (int)m_clientDataList.GetCount() )
+ node = m_clientDataList.Nth( n );
+
+ if ( node )
+ {
+ clientData = node->GetData();
+ node = m_clientDataList.Nth( n );
+ }
+ }
+
+ deletedData.Add(clientData);
+
+#if wxUSE_CHECKLISTBOX
+ // save check state
+ if ( m_hasCheckBoxes )
+ {
+ deletedChecks.Add(((wxCheckListBox *)this)->IsChecked(pos + n));
+ }
+#endif // wxUSE_CHECKLISTBOX
+ }
+
+ int nDeletedCount = n;
+
+ gtk_list_clear_items( m_list, pos, length );
+
+ // now append the new items
+ for ( n = 0; n < nItems; n++ )
+ {
+ Append(items[n]);
+ }
+
+ // and append the old items too
+ pos += nItems; // now the indices are shifter
+ for ( n = 0; n < nDeletedCount; n++ )
+ {
+ Append(deletedLabels[n], deletedData[n]);
+
+#if wxUSE_CHECKLISTBOX
+ if ( m_hasCheckBoxes )
+ {
+ ((wxCheckListBox *)this)->Check(pos + n, (bool)deletedChecks[n]);
+ }
+#endif // wxUSE_CHECKLISTBOX
+ }
+}
+
+void wxListBox::AppendCommon( const wxString &item )
+{
+ wxCHECK_RET( m_list != NULL, _T("invalid listbox") );
+