1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/gtk/combobox.cpp 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  10 // For compilers that support precompilation, includes "wx.h". 
  11 #include "wx/wxprec.h" 
  15 #include "wx/combobox.h" 
  19     #include "wx/settings.h" 
  20     #include "wx/textctrl.h"    // for wxEVT_COMMAND_TEXT_UPDATED 
  21     #include "wx/arrstr.h" 
  24 #include "wx/gtk/private.h" 
  26 // ---------------------------------------------------------------------------- 
  28 // ---------------------------------------------------------------------------- 
  32 gtkcombobox_text_changed_callback( GtkWidget 
*WXUNUSED(widget
), wxComboBox 
*combo 
) 
  34     if (!combo
->m_hasVMT
) return; 
  36     wxCommandEvent 
event( wxEVT_COMMAND_TEXT_UPDATED
, combo
->GetId() ); 
  37     event
.SetString( combo
->GetValue() ); 
  38     event
.SetEventObject( combo 
); 
  39     combo
->HandleWindowEvent( event 
); 
  43 gtkcombobox_changed_callback( GtkWidget 
*WXUNUSED(widget
), wxComboBox 
*combo 
) 
  45     combo
->SendSelectionChangedEvent(wxEVT_COMMAND_COMBOBOX_SELECTED
); 
  49 gtkcombobox_popupshown_callback(GObject 
*WXUNUSED(gobject
), 
  50                                 GParamSpec 
*WXUNUSED(param_spec
), 
  54     g_object_get( combo
->m_widget
, "popup-shown", &isShown
, NULL 
); 
  55     wxCommandEvent 
event( isShown 
? wxEVT_COMMAND_COMBOBOX_DROPDOWN
 
  56                                   : wxEVT_COMMAND_COMBOBOX_CLOSEUP
, 
  58     event
.SetEventObject( combo 
); 
  59     combo
->HandleWindowEvent( event 
); 
  63 //----------------------------------------------------------------------------- 
  65 //----------------------------------------------------------------------------- 
  67 BEGIN_EVENT_TABLE(wxComboBox
, wxChoice
) 
  68     EVT_CHAR(wxComboBox::OnChar
) 
  70     EVT_MENU(wxID_CUT
, wxComboBox::OnCut
) 
  71     EVT_MENU(wxID_COPY
, wxComboBox::OnCopy
) 
  72     EVT_MENU(wxID_PASTE
, wxComboBox::OnPaste
) 
  73     EVT_MENU(wxID_UNDO
, wxComboBox::OnUndo
) 
  74     EVT_MENU(wxID_REDO
, wxComboBox::OnRedo
) 
  75     EVT_MENU(wxID_CLEAR
, wxComboBox::OnDelete
) 
  76     EVT_MENU(wxID_SELECTALL
, wxComboBox::OnSelectAll
) 
  78     EVT_UPDATE_UI(wxID_CUT
, wxComboBox::OnUpdateCut
) 
  79     EVT_UPDATE_UI(wxID_COPY
, wxComboBox::OnUpdateCopy
) 
  80     EVT_UPDATE_UI(wxID_PASTE
, wxComboBox::OnUpdatePaste
) 
  81     EVT_UPDATE_UI(wxID_UNDO
, wxComboBox::OnUpdateUndo
) 
  82     EVT_UPDATE_UI(wxID_REDO
, wxComboBox::OnUpdateRedo
) 
  83     EVT_UPDATE_UI(wxID_CLEAR
, wxComboBox::OnUpdateDelete
) 
  84     EVT_UPDATE_UI(wxID_SELECTALL
, wxComboBox::OnUpdateSelectAll
) 
  87 void wxComboBox::Init() 
  92 bool wxComboBox::Create( wxWindow 
*parent
, wxWindowID id
, 
  93                          const wxString
& value
, 
  94                          const wxPoint
& pos
, const wxSize
& size
, 
  95                          const wxArrayString
& choices
, 
  96                          long style
, const wxValidator
& validator
, 
  97                          const wxString
& name 
) 
  99     wxCArrayString 
chs(choices
); 
 101     return Create( parent
, id
, value
, pos
, size
, chs
.GetCount(), 
 102                    chs
.GetStrings(), style
, validator
, name 
); 
 105 bool wxComboBox::Create( wxWindow 
*parent
, wxWindowID id
, const wxString
& value
, 
 106                          const wxPoint
& pos
, const wxSize
& size
, 
 107                          int n
, const wxString choices
[], 
 108                          long style
, const wxValidator
& validator
, 
 109                          const wxString
& name 
) 
 111     if (!PreCreation( parent
, pos
, size 
) || 
 112         !CreateBase( parent
, id
, pos
, size
, style
, validator
, name 
)) 
 114         wxFAIL_MSG( wxT("wxComboBox creation failed") ); 
 118     if (HasFlag(wxCB_SORT
)) 
 119         m_strings 
= new wxGtkCollatedArrayString(); 
 121     GTKCreateComboBoxWidget(); 
 123     if (HasFlag(wxBORDER_NONE
)) 
 125         // Doesn't seem to work 
 126         // g_object_set (m_widget, "has-frame", FALSE, NULL); 
 129     GtkEntry 
* const entry 
= GetEntry(); 
 133         // Set it up to trigger default item on enter key press 
 134         gtk_entry_set_activates_default( entry
, 
 135                                          !HasFlag(wxTE_PROCESS_ENTER
) ); 
 137         gtk_editable_set_editable(GTK_EDITABLE(entry
), true); 
 142     m_parent
->DoAddChild( this ); 
 145         m_focusWidget 
= GTK_WIDGET( entry 
); 
 151         if (style 
& wxCB_READONLY
) 
 153             // this will assert and do nothing if the value is not in our list 
 154             // of strings which is the desired behaviour (for consistency with 
 155             // wxMSW and also because it doesn't make sense to have a string 
 156             // which is not a possible choice in a read-only combobox) 
 157             SetStringSelection(value
); 
 158             gtk_editable_set_editable(GTK_EDITABLE(entry
), false); 
 160         else // editable combobox 
 162             // any value is accepted, even if it's not in our list 
 163             gtk_entry_set_text( entry
, wxGTK_CONV(value
) ); 
 166         g_signal_connect_after (entry
, "changed", 
 167                                 G_CALLBACK (gtkcombobox_text_changed_callback
), this); 
 170     g_signal_connect_after (m_widget
, "changed", 
 171                         G_CALLBACK (gtkcombobox_changed_callback
), this); 
 173     if ( !gtk_check_version(2,10,0) ) 
 175         g_signal_connect (m_widget
, "notify::popup-shown", 
 176                           G_CALLBACK (gtkcombobox_popupshown_callback
), this); 
 179     SetInitialSize(size
); // need this too because this is a wxControlWithItems 
 184 void wxComboBox::GTKCreateComboBoxWidget() 
 186     m_widget 
= gtk_combo_box_entry_new_text(); 
 187     g_object_ref(m_widget
); 
 189     m_entry 
= GTK_ENTRY(gtk_bin_get_child(GTK_BIN(m_widget
))); 
 192 GtkEditable 
*wxComboBox::GetEditable() const 
 194     return GTK_EDITABLE(gtk_bin_get_child(GTK_BIN(m_widget
))); 
 197 void wxComboBox::OnChar( wxKeyEvent 
&event 
) 
 199     switch ( event
.GetKeyCode() ) 
 202             if ( HasFlag(wxTE_PROCESS_ENTER
) && GetEntry() ) 
 204                 // GTK automatically selects an item if its in the list 
 205                 wxCommandEvent 
eventEnter(wxEVT_COMMAND_TEXT_ENTER
, GetId()); 
 206                 eventEnter
.SetString( GetValue() ); 
 207                 eventEnter
.SetInt( GetSelection() ); 
 208                 eventEnter
.SetEventObject( this ); 
 210                 if ( HandleWindowEvent(eventEnter
) ) 
 212                     // Catch GTK event so that GTK doesn't open the drop 
 213                     // down list upon RETURN. 
 223 void wxComboBox::EnableTextChangedEvents(bool enable
) 
 230         g_signal_handlers_unblock_by_func(gtk_bin_get_child(GTK_BIN(m_widget
)), 
 231             (gpointer
)gtkcombobox_text_changed_callback
, this); 
 235         g_signal_handlers_block_by_func(gtk_bin_get_child(GTK_BIN(m_widget
)), 
 236             (gpointer
)gtkcombobox_text_changed_callback
, this); 
 240 void wxComboBox::GTKDisableEvents() 
 242     EnableTextChangedEvents(false); 
 244     g_signal_handlers_block_by_func(m_widget
, 
 245         (gpointer
)gtkcombobox_changed_callback
, this); 
 246     g_signal_handlers_block_by_func(m_widget
, 
 247         (gpointer
)gtkcombobox_popupshown_callback
, this); 
 250 void wxComboBox::GTKEnableEvents() 
 252     EnableTextChangedEvents(true); 
 254     g_signal_handlers_unblock_by_func(m_widget
, 
 255         (gpointer
)gtkcombobox_changed_callback
, this); 
 256     g_signal_handlers_unblock_by_func(m_widget
, 
 257         (gpointer
)gtkcombobox_popupshown_callback
, this); 
 260 GtkWidget
* wxComboBox::GetConnectWidget() 
 262     return GTK_WIDGET( GetEntry() ); 
 265 GdkWindow
* wxComboBox::GTKGetWindow(wxArrayGdkWindows
& /* windows */) const 
 267     return gtk_entry_get_text_window(GetEntry()); 
 272 wxComboBox::GetClassDefaultAttributes(wxWindowVariant 
WXUNUSED(variant
)) 
 274     return GetDefaultAttributesFromGTKWidget(gtk_combo_box_entry_new
, true); 
 277 void wxComboBox::SetValue(const wxString
& value
) 
 279     if ( HasFlag(wxCB_READONLY
) ) 
 280         SetStringSelection(value
); 
 282         wxTextEntry::SetValue(value
); 
 285 // ---------------------------------------------------------------------------- 
 286 // standard event handling 
 287 // ---------------------------------------------------------------------------- 
 289 void wxComboBox::OnCut(wxCommandEvent
& WXUNUSED(event
)) 
 294 void wxComboBox::OnCopy(wxCommandEvent
& WXUNUSED(event
)) 
 299 void wxComboBox::OnPaste(wxCommandEvent
& WXUNUSED(event
)) 
 304 void wxComboBox::OnUndo(wxCommandEvent
& WXUNUSED(event
)) 
 309 void wxComboBox::OnRedo(wxCommandEvent
& WXUNUSED(event
)) 
 314 void wxComboBox::OnDelete(wxCommandEvent
& WXUNUSED(event
)) 
 319 void wxComboBox::OnSelectAll(wxCommandEvent
& WXUNUSED(event
)) 
 324 void wxComboBox::OnUpdateCut(wxUpdateUIEvent
& event
) 
 326     event
.Enable( CanCut() ); 
 329 void wxComboBox::OnUpdateCopy(wxUpdateUIEvent
& event
) 
 331     event
.Enable( CanCopy() ); 
 334 void wxComboBox::OnUpdatePaste(wxUpdateUIEvent
& event
) 
 336     event
.Enable( CanPaste() ); 
 339 void wxComboBox::OnUpdateUndo(wxUpdateUIEvent
& event
) 
 341     event
.Enable( CanUndo() ); 
 344 void wxComboBox::OnUpdateRedo(wxUpdateUIEvent
& event
) 
 346     event
.Enable( CanRedo() ); 
 349 void wxComboBox::OnUpdateDelete(wxUpdateUIEvent
& event
) 
 351     event
.Enable(HasSelection() && IsEditable()) ; 
 354 void wxComboBox::OnUpdateSelectAll(wxUpdateUIEvent
& event
) 
 356     event
.Enable(!wxTextEntry::IsEmpty()); 
 359 void wxComboBox::Popup() 
 361      gtk_combo_box_popup( GTK_COMBO_BOX(m_widget
) ); 
 364 void wxComboBox::Dismiss() 
 366     gtk_combo_box_popdown( GTK_COMBO_BOX(m_widget
) ); 
 368 #endif // wxUSE_COMBOBOX