+ wxCHECK_MSG( m_widget != NULL, NULL, wxT("invalid choice control") );
+
+ wxList::compatibility_iterator node = m_clientList.Item( n );
+ wxCHECK_MSG( node, NULL, wxT("invalid index in wxChoice::DoGetItemClientData") );
+
+ return node->GetData();
+}
+
+void wxChoice::DoClear()
+{
+ wxCHECK_RET( m_widget != NULL, wxT("invalid choice") );
+
+ gtk_option_menu_remove_menu( GTK_OPTION_MENU(m_widget) );
+ GtkWidget *menu = gtk_menu_new();
+ gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu );
+
+ m_clientList.Clear();
+
+ if ( m_strings )
+ m_strings->Clear();
+
+ // begin with no selection
+ m_selection_hack = wxNOT_FOUND;
+}
+
+void wxChoice::DoDeleteOneItem(unsigned int n)
+{
+ wxCHECK_RET( m_widget != NULL, wxT("invalid choice") );
+
+ wxCHECK_RET( IsValid(n), wxT("invalid index in wxChoice::Delete") );
+
+ // if the item to delete is before the selection, and the selection is valid
+ if (((int)n < m_selection_hack) && (m_selection_hack != wxNOT_FOUND))
+ {
+ // move the selection back one
+ m_selection_hack--;
+ }
+ else if ((int)n == m_selection_hack)
+ {
+ // invalidate the selection
+ m_selection_hack = wxNOT_FOUND;
+ }
+
+ // VZ: apparently GTK+ doesn't have a built-in function to do it (not even
+ // in 2.0), hence this dumb implementation -- still better than nothing
+ const unsigned int count = GetCount();
+
+ wxList::compatibility_iterator node = m_clientList.GetFirst();
+
+ wxArrayString items;
+ wxArrayPtrVoid itemsData;
+ items.Alloc(count);
+ for ( unsigned i = 0; i < count; i++, node = node->GetNext() )
+ {
+ if ( i != n )
+ {
+ items.Add(GetString(i));
+ itemsData.Add(node->GetData());
+ }
+ }
+
+ wxChoice::DoClear();
+
+ void ** const data = &itemsData[0];
+ if ( HasClientObjectData() )
+ Append(items, reinterpret_cast<wxClientData **>(data));
+ else
+ Append(items, data);
+}
+
+int wxChoice::FindString( const wxString &string, bool bCase ) const
+{
+ wxCHECK_MSG( m_widget != NULL, wxNOT_FOUND, wxT("invalid choice") );
+
+ // If you read this code once and you think you understand
+ // it, then you are very wrong. Robert Roebling.
+
+ GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
+ int count = 0;
+ GList *child = menu_shell->children;
+ while (child)
+ {
+ GtkBin *bin = GTK_BIN( child->data );
+ GtkLabel *label = NULL;
+ if (bin->child)
+ label = GTK_LABEL(bin->child);
+ if (!label)
+ label = GTK_LABEL( BUTTON_CHILD(m_widget) );
+
+ wxASSERT_MSG( label != NULL , wxT("wxChoice: invalid label") );
+
+ wxString tmp( label->label );
+
+ if (string.IsSameAs( tmp, bCase ))
+ return count;
+
+ child = child->next;
+ count++;
+ }
+
+ return wxNOT_FOUND;
+}
+
+int wxChoice::GetSelection() const
+{
+ wxCHECK_MSG( m_widget != NULL, wxNOT_FOUND, wxT("invalid choice") );
+
+ return m_selection_hack;
+
+}
+
+void wxChoice::SetString(unsigned int n, const wxString& str )
+{
+ wxCHECK_RET( m_widget != NULL, wxT("invalid choice") );
+
+ GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
+ unsigned int count = 0;
+ GList *child = menu_shell->children;
+ while (child)
+ {
+ GtkBin *bin = GTK_BIN( child->data );
+ if (count == n)
+ {
+ GtkLabel *label = NULL;
+ if (bin->child)
+ label = GTK_LABEL(bin->child);
+ if (!label)
+ label = GTK_LABEL( BUTTON_CHILD(m_widget) );
+
+ wxASSERT_MSG( label != NULL , wxT("wxChoice: invalid label") );
+
+ gtk_label_set_text( label, wxGTK_CONV( str ) );
+
+ return;
+ }
+ child = child->next;
+ count++;
+ }
+}
+
+wxString wxChoice::GetString(unsigned int n) const
+{
+ wxCHECK_MSG( m_widget != NULL, wxEmptyString, wxT("invalid choice") );
+
+ GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
+ unsigned int count = 0;
+ GList *child = menu_shell->children;
+ while (child)
+ {
+ GtkBin *bin = GTK_BIN( child->data );
+ if (count == n)
+ {
+ GtkLabel *label = NULL;
+ if (bin->child)
+ label = GTK_LABEL(bin->child);
+ if (!label)
+ label = GTK_LABEL( BUTTON_CHILD(m_widget) );
+
+ wxASSERT_MSG( label != NULL , wxT("wxChoice: invalid label") );
+
+ return wxString( label->label );
+ }
+ child = child->next;
+ count++;
+ }
+
+ wxFAIL_MSG( wxT("wxChoice: invalid index in GetString()") );
+
+ return wxEmptyString;
+}
+
+unsigned int wxChoice::GetCount() const
+{
+ wxCHECK_MSG( m_widget != NULL, 0, wxT("invalid choice") );
+
+ GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
+ unsigned int count = 0;
+ GList *child = menu_shell->children;
+ while (child)
+ {
+ count++;
+ child = child->next;
+ }
+ return count;