-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++)
- {
+// ----------------------------------------------------------------------------
+// construction
+// ----------------------------------------------------------------------------
+
+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;
+ m_prevSelection = 0; // or -1 ??
+ m_blockEvent = FALSE;
+
+ if (!PreCreation( parent, pos, size ) ||
+ !CreateBase( parent, id, pos, size, style, validator, name ))
+ {
+ wxFAIL_MSG( wxT("wxListBox creation failed") );
+ return FALSE;
+ }
+
+ 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;
+ if (style & wxLB_MULTIPLE)
+ {
+ mode = GTK_SELECTION_MULTIPLE;
+ }
+ else if (style & wxLB_EXTENDED)
+ {
+ mode = GTK_SELECTION_EXTENDED;
+ }
+ else
+ {
+ // if style was 0 set single mode
+ m_windowStyle |= wxLB_SINGLE;
+ mode = GTK_SELECTION_MULTIPLE;
+ }
+
+ gtk_list_set_selection_mode( GTK_LIST(m_list), mode );
+
+ gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget), GTK_WIDGET(m_list) );
+
+ /* make list scroll when moving the focus down using cursor keys */
+ gtk_container_set_focus_vadjustment(
+ GTK_CONTAINER(m_list),
+ gtk_scrolled_window_get_vadjustment(
+ GTK_SCROLLED_WINDOW(m_widget)));
+
+ gtk_widget_show( GTK_WIDGET(m_list) );
+
+ if ( style & wxLB_SORT )
+ {
+ // this will change DoAppend() behaviour
+ m_strings = new wxSortedArrayString;
+ }
+ else
+ {
+ m_strings = (wxSortedArrayString *)NULL;
+ }
+
+ for (int i = 0; i < n; i++)
+ {
+ // add one by one
+ DoAppend(choices[i]);
+ }
+
+ // call it after appending the strings to the listbox, otherwise it doesn't
+ // work correctly
+ SetBestSize( size );
+
+ m_parent->DoAddChild( this );
+
+ PostCreation();
+
+ SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOX ) );
+ SetForegroundColour( parent->GetForegroundColour() );
+ SetFont( parent->GetFont() );
+
+ Show( TRUE );
+
+ return TRUE;
+}
+
+wxListBox::~wxListBox()
+{
+ m_hasVMT = FALSE;
+
+ Clear();
+
+ if (m_strings)
+ delete m_strings;
+}
+
+// ----------------------------------------------------------------------------
+// adding items
+// ----------------------------------------------------------------------------
+
+void wxListBox::DoInsertItems(const wxArrayString& items, int pos)
+{
+ wxCHECK_RET( m_list != NULL, wxT("invalid listbox") );
+
+ // VZ: notice that InsertItems knows nothing about sorting, so calling it
+ // from outside (and not from our own Append) is likely to break
+ // everything
+
+ // code elsewhere supposes we have as many items in m_clientList as items
+ // in the listbox
+ wxASSERT_MSG( m_clientList.GetCount() == (size_t)GetCount(),
+ wxT("bug in client data management") );
+
+ GList *children = m_list->children;
+ int length = g_list_length(children);
+
+ wxCHECK_RET( pos <= length, wxT("invalid index in wxListBox::InsertItems") );
+
+ size_t nItems = items.GetCount();
+ int index;
+
+ if (m_strings)
+ {
+ for (size_t n = 0; n < nItems; n++)
+ {
+ index = m_strings->Add( items[n] );
+
+ if (index != GetCount())
+ {
+ GtkAddItem( items[n], index );
+ wxList::compatibility_iterator node = m_clientList.Item( index );
+ m_clientList.Insert( node, (wxObject*) NULL );
+ }
+ else
+ {
+ GtkAddItem( items[n] );
+ m_clientList.Append( (wxObject*) NULL );
+ }
+ }
+ }
+ else
+ {
+ if (pos == length)
+ {
+ for ( size_t n = 0; n < nItems; n++ )
+ {
+ GtkAddItem( items[n] );
+
+ m_clientList.Append((wxObject *)NULL);
+ }
+ }
+ else
+ {
+ wxList::compatibility_iterator node = m_clientList.Item( pos );
+ for ( size_t n = 0; n < nItems; n++ )
+ {
+ GtkAddItem( items[n], pos+n );
+
+ m_clientList.Insert( node, (wxObject *)NULL );
+ }
+ }
+ }
+
+ wxASSERT_MSG( m_clientList.GetCount() == (size_t)GetCount(),
+ wxT("bug in client data management") );
+}
+
+int wxListBox::DoAppend( const wxString& item )
+{
+ if (m_strings)
+ {
+ // need to determine the index
+ int index = m_strings->Add( item );
+
+ // only if not at the end anyway
+ if (index != GetCount())
+ {
+ GtkAddItem( item, index );
+
+ wxList::compatibility_iterator node = m_clientList.Item( index );
+ m_clientList.Insert( node, (wxObject *)NULL );
+
+ return index;
+ }
+ }
+
+ GtkAddItem(item);
+
+ m_clientList.Append((wxObject *)NULL);
+
+ return GetCount() - 1;
+}
+
+void wxListBox::GtkAddItem( const wxString &item, int pos )
+{
+ wxCHECK_RET( m_list != NULL, wxT("invalid listbox") );
+