]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/combobox.cpp
implemented menu drawing in the GTK theme
[wxWidgets.git] / src / gtk1 / combobox.cpp
CommitLineData
53010e52
RR
1/////////////////////////////////////////////////////////////////////////////
2// Name: combobox.cpp
3// Purpose:
4// Author: Robert Roebling
dbf858b5 5// Id: $Id$
01111366 6// Copyright: (c) 1998 Robert Roebling
805dd538 7// Licence: wxWindows licence
53010e52
RR
8/////////////////////////////////////////////////////////////////////////////
9
10#ifdef __GNUG__
11#pragma implementation "combobox.h"
12#endif
13
14#include "wx/combobox.h"
dcf924a3
RR
15
16#if wxUSE_COMBOBOX
17
72a16063 18#include "wx/settings.h"
b62c3631 19#include "wx/intl.h"
53010e52 20
78bcfcfc
VZ
21#include "wx/textctrl.h" // for wxEVT_COMMAND_TEXT_UPDATED
22
071a2d78
RR
23#include <gdk/gdk.h>
24#include <gtk/gtk.h>
83624f79 25
acfd422a
RR
26//-----------------------------------------------------------------------------
27// idle system
28//-----------------------------------------------------------------------------
29
30extern void wxapp_install_idle_handler();
31extern bool g_isIdle;
32
47908e25
RR
33//-----------------------------------------------------------------------------
34// data
35//-----------------------------------------------------------------------------
36
37extern bool g_blockEventsOnDrag;
38
53010e52 39//-----------------------------------------------------------------------------
e1e955e1 40// "select"
47908e25 41//-----------------------------------------------------------------------------
47908e25 42
8a85884a
VZ
43static void
44gtk_combo_clicked_callback( GtkWidget *WXUNUSED(widget), wxComboBox *combo )
53010e52 45{
acfd422a 46 if (g_isIdle) wxapp_install_idle_handler();
8a85884a 47
a2053b27 48 if (!combo->m_hasVMT) return;
acfd422a
RR
49
50 if (g_blockEventsOnDrag) return;
805dd538 51
fd0eed64
RR
52 if (combo->m_alreadySent)
53 {
54 combo->m_alreadySent = FALSE;
55 return;
56 }
47908e25 57
fd0eed64 58 combo->m_alreadySent = TRUE;
805dd538 59
159b66c0
RR
60 int curSelection = combo->GetSelection();
61
62 if (combo->m_prevSelection != curSelection)
63 {
64 GtkWidget *list = GTK_COMBO(combo->m_widget)->list;
65 gtk_list_unselect_item( GTK_LIST(list), combo->m_prevSelection );
66 }
67
68 combo->m_prevSelection = curSelection;
69
8a85884a 70 wxCommandEvent event( wxEVT_COMMAND_COMBOBOX_SELECTED, combo->GetId() );
159b66c0 71 event.SetInt( curSelection );
29006414 72 event.SetString( combo->GetStringSelection() );
8a85884a 73 event.SetEventObject( combo );
31528cd3 74
8a85884a 75 combo->GetEventHandler()->ProcessEvent( event );
6de97a3b 76}
47908e25 77
0c77152e
RR
78//-----------------------------------------------------------------------------
79// "changed"
80//-----------------------------------------------------------------------------
81
eeccd5d9 82static void
0c77152e
RR
83gtk_text_changed_callback( GtkWidget *WXUNUSED(widget), wxComboBox *combo )
84{
acfd422a 85 if (g_isIdle) wxapp_install_idle_handler();
31528cd3 86
a2053b27
RR
87 if (!combo->m_hasVMT) return;
88
8a85884a 89 wxCommandEvent event( wxEVT_COMMAND_TEXT_UPDATED, combo->GetId() );
29006414 90 event.SetString( combo->GetValue() );
0c77152e
RR
91 event.SetEventObject( combo );
92 combo->GetEventHandler()->ProcessEvent( event );
0c77152e
RR
93}
94
e1e955e1
RR
95//-----------------------------------------------------------------------------
96// wxComboBox
53010e52
RR
97//-----------------------------------------------------------------------------
98
99IMPLEMENT_DYNAMIC_CLASS(wxComboBox,wxControl)
100
b4071e91 101BEGIN_EVENT_TABLE(wxComboBox, wxControl)
fd0eed64 102 EVT_SIZE(wxComboBox::OnSize)
8a85884a 103 EVT_CHAR(wxComboBox::OnChar)
b4071e91
RR
104END_EVENT_TABLE()
105
fd0eed64
RR
106bool wxComboBox::Create( wxWindow *parent, wxWindowID id, const wxString& value,
107 const wxPoint& pos, const wxSize& size,
108 int n, const wxString choices[],
805dd538
VZ
109 long style, const wxValidator& validator,
110 const wxString& name )
53010e52 111{
fd0eed64
RR
112 m_alreadySent = FALSE;
113 m_needParent = TRUE;
b292e2f5 114 m_acceptsFocus = TRUE;
159b66c0 115 m_prevSelection = 0;
805dd538 116
db434467 117 if (!PreCreation( parent, pos, size ) ||
4dcaf11a
RR
118 !CreateBase( parent, id, pos, size, style, validator, name ))
119 {
223d09f6 120 wxFAIL_MSG( wxT("wxComboBox creation failed") );
9d9b7755 121 return FALSE;
4dcaf11a 122 }
6de97a3b 123
fd0eed64 124 m_widget = gtk_combo_new();
805dd538 125
8a85884a 126 // make it more useable
3ca6a5f0
BP
127 gtk_combo_set_use_arrows_always( GTK_COMBO(m_widget), TRUE );
128
129 // and case-sensitive
130 gtk_combo_set_case_sensitive( GTK_COMBO(m_widget), TRUE );
131
8a85884a 132
fd0eed64 133 GtkWidget *list = GTK_COMBO(m_widget)->list;
805dd538 134
159b66c0
RR
135 gtk_list_set_selection_mode( GTK_LIST(list), GTK_SELECTION_MULTIPLE );
136
fd0eed64
RR
137 for (int i = 0; i < n; i++)
138 {
19da4326 139 /* don't send first event, which GTK sends aways when
9d9b7755 140 inserting the first item */
19da4326 141 m_alreadySent = TRUE;
31528cd3 142
93c5dd39 143 GtkWidget *list_item = gtk_list_item_new_with_label( choices[i].mbc_str() );
805dd538 144
fd0eed64 145 m_clientDataList.Append( (wxObject*)NULL );
f5e27805 146 m_clientObjectList.Append( (wxObject*)NULL );
805dd538 147
fd0eed64 148 gtk_container_add( GTK_CONTAINER(list), list_item );
805dd538 149
805dd538 150 gtk_signal_connect( GTK_OBJECT(list_item), "select",
19da4326
RR
151 GTK_SIGNAL_FUNC(gtk_combo_clicked_callback), (gpointer)this );
152
153 gtk_widget_show( list_item );
fd0eed64 154 }
805dd538 155
f03fc89f 156 m_parent->DoAddChild( this );
76fcf0f2
RR
157
158 m_focusWidget = GTK_COMBO(m_widget)->entry;
805dd538 159
fd0eed64 160 PostCreation();
53010e52 161
fd0eed64 162 ConnectWidget( GTK_COMBO(m_widget)->button );
805dd538 163
fd0eed64 164 if (!value.IsNull()) SetValue( value );
805dd538 165
a260fe6a
RR
166 if (style & wxCB_READONLY)
167 gtk_entry_set_editable( GTK_ENTRY( GTK_COMBO(m_widget)->entry ), FALSE );
168
0c77152e
RR
169 gtk_signal_connect( GTK_OBJECT(GTK_COMBO(m_widget)->entry), "changed",
170 GTK_SIGNAL_FUNC(gtk_text_changed_callback), (gpointer)this);
805dd538 171
db434467
RR
172 wxSize size_best( DoGetBestSize() );
173 wxSize new_size( size );
174 if (new_size.x == -1)
175 new_size.x = size_best.x;
176 if (new_size.y == -1)
177 new_size.y = size_best.y;
178 if (new_size.y > size_best.y)
179 new_size.y = size_best.y;
180 if ((new_size.x != size.x) || (new_size.y != size.y))
4494ad58 181 {
db434467 182 SetSize( new_size.x, new_size.y );
4494ad58
RR
183
184 // This is required for tool bar support
185 gtk_widget_set_usize( m_widget, new_size.x, new_size.y );
186 }
187
db434467 188
a756f210 189 SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) );
fd0eed64 190 SetForegroundColour( parent->GetForegroundColour() );
f96aa4d9 191
fd0eed64 192 Show( TRUE );
805dd538 193
fd0eed64
RR
194 return TRUE;
195}
196
197wxComboBox::~wxComboBox()
198{
7d6d2cd4 199 wxNode *node = m_clientObjectList.First();
fd0eed64
RR
200 while (node)
201 {
202 wxClientData *cd = (wxClientData*)node->Data();
203 if (cd) delete cd;
204 node = node->Next();
205 }
7d6d2cd4
RR
206 m_clientObjectList.Clear();
207
fd0eed64 208 m_clientDataList.Clear();
6de97a3b 209}
53010e52 210
fd0eed64 211void wxComboBox::AppendCommon( const wxString &item )
53010e52 212{
223d09f6 213 wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
805dd538 214
fd0eed64 215 GtkWidget *list = GTK_COMBO(m_widget)->list;
805dd538 216
93c5dd39 217 GtkWidget *list_item = gtk_list_item_new_with_label( item.mbc_str() );
805dd538 218
ec5d85fb
RR
219 gtk_container_add( GTK_CONTAINER(list), list_item );
220
805dd538 221 gtk_signal_connect( GTK_OBJECT(list_item), "select",
fd0eed64 222 GTK_SIGNAL_FUNC(gtk_combo_clicked_callback), (gpointer)this );
805dd538 223
2b07d713
RR
224 if (GTK_WIDGET_REALIZED(m_widget))
225 {
226 gtk_widget_realize( list_item );
227 gtk_widget_realize( GTK_BIN(list_item)->child );
228
229 if (m_widgetStyle) ApplyWidgetStyle();
230 }
805dd538 231
fd0eed64 232 gtk_widget_show( list_item );
6de97a3b 233}
53010e52
RR
234
235void wxComboBox::Append( const wxString &item )
47908e25 236{
f5e27805
RR
237 m_clientDataList.Append( (wxObject*) NULL );
238 m_clientObjectList.Append( (wxObject*) NULL );
805dd538 239
fd0eed64 240 AppendCommon( item );
6de97a3b 241}
47908e25 242
fd0eed64 243void wxComboBox::Append( const wxString &item, void *clientData )
53010e52 244{
f5e27805
RR
245 m_clientDataList.Append( (wxObject*) clientData );
246 m_clientObjectList.Append( (wxObject*)NULL );
805dd538 247
fd0eed64 248 AppendCommon( item );
6de97a3b 249}
53010e52 250
fd0eed64 251void wxComboBox::Append( const wxString &item, wxClientData *clientData )
53010e52 252{
f5e27805
RR
253 m_clientDataList.Append( (wxObject*) NULL );
254 m_clientObjectList.Append( (wxObject*) clientData );
805dd538 255
fd0eed64
RR
256 AppendCommon( item );
257}
258
259void wxComboBox::SetClientData( int n, void* clientData )
260{
223d09f6 261 wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
805dd538 262
fd0eed64
RR
263 wxNode *node = m_clientDataList.Nth( n );
264 if (!node) return;
805dd538 265
f5e27805 266 node->SetData( (wxObject*) clientData );
6de97a3b 267}
53010e52 268
fd0eed64 269void* wxComboBox::GetClientData( int n )
53010e52 270{
223d09f6 271 wxCHECK_MSG( m_widget != NULL, NULL, wxT("invalid combobox") );
805dd538 272
fd0eed64
RR
273 wxNode *node = m_clientDataList.Nth( n );
274 if (!node) return NULL;
805dd538 275
f5e27805 276 return node->Data();
fd0eed64
RR
277}
278
279void wxComboBox::SetClientObject( int n, wxClientData* clientData )
280{
223d09f6 281 wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
805dd538 282
f5e27805 283 wxNode *node = m_clientObjectList.Nth( n );
fd0eed64 284 if (!node) return;
805dd538 285
fd0eed64
RR
286 wxClientData *cd = (wxClientData*) node->Data();
287 if (cd) delete cd;
805dd538 288
fd0eed64 289 node->SetData( (wxObject*) clientData );
6de97a3b 290}
53010e52 291
fd0eed64 292wxClientData* wxComboBox::GetClientObject( int n )
53010e52 293{
223d09f6 294 wxCHECK_MSG( m_widget != NULL, (wxClientData*)NULL, wxT("invalid combobox") );
805dd538 295
d6acfcb5 296 wxNode *node = m_clientObjectList.Nth( n );
fd0eed64 297 if (!node) return (wxClientData*) NULL;
805dd538 298
fd0eed64
RR
299 return (wxClientData*) node->Data();
300}
301
302void wxComboBox::Clear()
303{
223d09f6 304 wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
805dd538 305
fd0eed64
RR
306 GtkWidget *list = GTK_COMBO(m_widget)->list;
307 gtk_list_clear_items( GTK_LIST(list), 0, Number() );
805dd538 308
f5e27805 309 wxNode *node = m_clientObjectList.First();
fd0eed64
RR
310 while (node)
311 {
312 wxClientData *cd = (wxClientData*)node->Data();
313 if (cd) delete cd;
314 node = node->Next();
315 }
f5e27805 316 m_clientObjectList.Clear();
805dd538 317
fd0eed64 318 m_clientDataList.Clear();
6de97a3b 319}
53010e52 320
fd0eed64 321void wxComboBox::Delete( int n )
53010e52 322{
223d09f6 323 wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
805dd538 324
fd0eed64 325 GtkList *listbox = GTK_LIST( GTK_COMBO(m_widget)->list );
805dd538 326
fd0eed64 327 GList *child = g_list_nth( listbox->children, n );
805dd538 328
fd0eed64
RR
329 if (!child)
330 {
223d09f6 331 wxFAIL_MSG(wxT("wrong index"));
fd0eed64
RR
332 return;
333 }
805dd538 334
bbe0af5b 335 GList *list = g_list_append( (GList*) NULL, child->data );
fd0eed64
RR
336 gtk_list_remove_items( listbox, list );
337 g_list_free( list );
805dd538 338
f5e27805
RR
339 wxNode *node = m_clientObjectList.Nth( n );
340 if (node)
fd0eed64
RR
341 {
342 wxClientData *cd = (wxClientData*)node->Data();
343 if (cd) delete cd;
f5e27805
RR
344 m_clientObjectList.DeleteNode( node );
345 }
805dd538 346
f5e27805
RR
347 node = m_clientDataList.Nth( n );
348 if (node)
349 {
fd0eed64
RR
350 m_clientDataList.DeleteNode( node );
351 }
6de97a3b 352}
53010e52 353
fd0eed64 354int wxComboBox::FindString( const wxString &item )
53010e52 355{
223d09f6 356 wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid combobox") );
805dd538 357
fd0eed64 358 GtkWidget *list = GTK_COMBO(m_widget)->list;
805dd538 359
53010e52
RR
360 GList *child = GTK_LIST(list)->children;
361 int count = 0;
362 while (child)
363 {
fd0eed64
RR
364 GtkBin *bin = GTK_BIN( child->data );
365 GtkLabel *label = GTK_LABEL( bin->child );
53b88b54 366 if (item == wxString(label->label,*wxConvCurrent))
7cf8cb48 367 return count;
fd0eed64
RR
368 count++;
369 child = child->next;
370 }
805dd538 371
7cf8cb48 372 return wxNOT_FOUND;
fd0eed64
RR
373}
374
375int wxComboBox::GetSelection() const
376{
223d09f6 377 wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid combobox") );
805dd538 378
fd0eed64 379 GtkWidget *list = GTK_COMBO(m_widget)->list;
805dd538 380
fd0eed64
RR
381 GList *selection = GTK_LIST(list)->selection;
382 if (selection)
383 {
384 GList *child = GTK_LIST(list)->children;
385 int count = 0;
386 while (child)
387 {
388 if (child->data == selection->data) return count;
389 count++;
390 child = child->next;
391 }
6de97a3b 392 }
805dd538 393
fd0eed64 394 return -1;
6de97a3b 395}
53010e52 396
debe6624 397wxString wxComboBox::GetString( int n ) const
53010e52 398{
223d09f6 399 wxCHECK_MSG( m_widget != NULL, wxT(""), wxT("invalid combobox") );
805dd538 400
fd0eed64 401 GtkWidget *list = GTK_COMBO(m_widget)->list;
805dd538 402
7cf8cb48 403 wxString str;
fd0eed64
RR
404 GList *child = g_list_nth( GTK_LIST(list)->children, n );
405 if (child)
406 {
407 GtkBin *bin = GTK_BIN( child->data );
408 GtkLabel *label = GTK_LABEL( bin->child );
53b88b54 409 str = wxString(label->label,*wxConvCurrent);
7cf8cb48
VZ
410 }
411 else
412 {
223d09f6 413 wxFAIL_MSG( wxT("wxComboBox: wrong index") );
fd0eed64 414 }
805dd538 415
7cf8cb48 416 return str;
6de97a3b 417}
53010e52 418
fd0eed64 419wxString wxComboBox::GetStringSelection() const
53010e52 420{
223d09f6 421 wxCHECK_MSG( m_widget != NULL, wxT(""), wxT("invalid combobox") );
805dd538 422
fd0eed64 423 GtkWidget *list = GTK_COMBO(m_widget)->list;
805dd538 424
fd0eed64
RR
425 GList *selection = GTK_LIST(list)->selection;
426 if (selection)
427 {
428 GtkBin *bin = GTK_BIN( selection->data );
53b88b54 429 wxString tmp = wxString(GTK_LABEL( bin->child )->label,*wxConvCurrent);
fd0eed64
RR
430 return tmp;
431 }
805dd538 432
223d09f6 433 wxFAIL_MSG( wxT("wxComboBox: no selection") );
805dd538 434
223d09f6 435 return wxT("");
6de97a3b 436}
53010e52 437
fd0eed64 438int wxComboBox::Number() const
53010e52 439{
223d09f6 440 wxCHECK_MSG( m_widget != NULL, 0, wxT("invalid combobox") );
805dd538 441
fd0eed64 442 GtkWidget *list = GTK_COMBO(m_widget)->list;
805dd538 443
fd0eed64
RR
444 GList *child = GTK_LIST(list)->children;
445 int count = 0;
446 while (child) { count++; child = child->next; }
447 return count;
6de97a3b 448}
53010e52 449
debe6624 450void wxComboBox::SetSelection( int n )
53010e52 451{
223d09f6 452 wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
805dd538 453
953704c1
RR
454 DisableEvents();
455
fd0eed64 456 GtkWidget *list = GTK_COMBO(m_widget)->list;
159b66c0 457 gtk_list_unselect_item( GTK_LIST(list), m_prevSelection );
fd0eed64 458 gtk_list_select_item( GTK_LIST(list), n );
159b66c0 459 m_prevSelection = n;
953704c1
RR
460
461 EnableEvents();
6de97a3b 462}
53010e52 463
47908e25
RR
464void wxComboBox::SetStringSelection( const wxString &string )
465{
223d09f6 466 wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
805dd538 467
fd0eed64
RR
468 int res = FindString( string );
469 if (res == -1) return;
470 SetSelection( res );
6de97a3b 471}
47908e25 472
fd0eed64 473wxString wxComboBox::GetValue() const
53010e52 474{
fd0eed64 475 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
53b88b54 476 wxString tmp = wxString(gtk_entry_get_text( GTK_ENTRY(entry) ),*wxConvCurrent);
fd0eed64 477 return tmp;
6de97a3b 478}
53010e52
RR
479
480void wxComboBox::SetValue( const wxString& value )
481{
223d09f6 482 wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
805dd538 483
fd0eed64 484 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
223d09f6 485 wxString tmp = wxT("");
fd0eed64 486 if (!value.IsNull()) tmp = value;
93c5dd39 487 gtk_entry_set_text( GTK_ENTRY(entry), tmp.mbc_str() );
6de97a3b 488}
53010e52 489
fd0eed64 490void wxComboBox::Copy()
53010e52 491{
223d09f6 492 wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
805dd538 493
fd0eed64 494 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
13111b2a 495#if defined(__WXGTK13__) || (GTK_MINOR_VERSION > 0)
fd0eed64 496 gtk_editable_copy_clipboard( GTK_EDITABLE(entry) );
75ed1d15 497#else
fd0eed64 498 gtk_editable_copy_clipboard( GTK_EDITABLE(entry), 0 );
75ed1d15 499#endif
6de97a3b 500}
53010e52 501
fd0eed64 502void wxComboBox::Cut()
53010e52 503{
223d09f6 504 wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
805dd538 505
fd0eed64 506 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
13111b2a 507#if defined(__WXGTK13__) || (GTK_MINOR_VERSION > 0)
fd0eed64 508 gtk_editable_cut_clipboard( GTK_EDITABLE(entry) );
75ed1d15 509#else
fd0eed64 510 gtk_editable_cut_clipboard( GTK_EDITABLE(entry), 0 );
75ed1d15 511#endif
6de97a3b 512}
53010e52 513
fd0eed64 514void wxComboBox::Paste()
53010e52 515{
223d09f6 516 wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
805dd538 517
fd0eed64 518 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
13111b2a 519#if defined(__WXGTK13__) || (GTK_MINOR_VERSION > 0)
fd0eed64 520 gtk_editable_paste_clipboard( GTK_EDITABLE(entry) );
75ed1d15 521#else
fd0eed64 522 gtk_editable_paste_clipboard( GTK_EDITABLE(entry), 0 );
75ed1d15 523#endif
6de97a3b 524}
53010e52 525
debe6624 526void wxComboBox::SetInsertionPoint( long pos )
53010e52 527{
223d09f6 528 wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
805dd538 529
fd0eed64 530 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
073c8fe9 531 gtk_entry_set_position( GTK_ENTRY(entry), (int)pos );
6de97a3b 532}
53010e52 533
fd0eed64 534void wxComboBox::SetInsertionPointEnd()
53010e52 535{
223d09f6 536 wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
805dd538
VZ
537
538 SetInsertionPoint( -1 );
6de97a3b 539}
53010e52 540
fd0eed64 541long wxComboBox::GetInsertionPoint() const
53010e52 542{
fd0eed64
RR
543 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
544 return (long) GTK_EDITABLE(entry)->current_pos;
6de97a3b 545}
53010e52 546
fd0eed64 547long wxComboBox::GetLastPosition() const
53010e52 548{
fd0eed64
RR
549 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
550 int pos = GTK_ENTRY(entry)->text_length;
551 return (long) pos-1;
6de97a3b 552}
53010e52 553
debe6624 554void wxComboBox::Replace( long from, long to, const wxString& value )
53010e52 555{
223d09f6 556 wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
93c5dd39 557 // FIXME: not quite sure how to do this method right in multibyte mode
805dd538 558
fd0eed64
RR
559 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
560 gtk_editable_delete_text( GTK_EDITABLE(entry), (gint)from, (gint)to );
561 if (value.IsNull()) return;
562 gint pos = (gint)to;
93c5dd39 563 gtk_editable_insert_text( GTK_EDITABLE(entry), value.mbc_str(), value.Length(), &pos );
6de97a3b 564}
53010e52 565
debe6624 566void wxComboBox::Remove(long from, long to)
53010e52 567{
223d09f6 568 wxCHECK_RET( m_widget != NULL, wxT("invalid combobox") );
805dd538 569
fd0eed64
RR
570 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
571 gtk_editable_delete_text( GTK_EDITABLE(entry), (gint)from, (gint)to );
6de97a3b 572}
53010e52 573
20d10ee1 574void wxComboBox::SetSelection( long from, long to )
53010e52 575{
20d10ee1
VZ
576 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
577 gtk_editable_select_region( GTK_EDITABLE(entry), (gint)from, (gint)to );
6de97a3b 578}
53010e52 579
20d10ee1 580void wxComboBox::SetEditable( bool editable )
53010e52 581{
20d10ee1
VZ
582 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
583 gtk_entry_set_editable( GTK_ENTRY(entry), editable );
b4071e91
RR
584}
585
8a85884a
VZ
586void wxComboBox::OnChar( wxKeyEvent &event )
587{
7cf8cb48 588 if ( event.KeyCode() == WXK_RETURN )
8a85884a 589 {
7cf8cb48 590 wxString value = GetValue();
8a85884a 591
7cf8cb48
VZ
592 if ( Number() == 0 )
593 {
594 // make Enter generate "selected" event if there is only one item
595 // in the combobox - without it, it's impossible to select it at
596 // all!
597 wxCommandEvent event( wxEVT_COMMAND_COMBOBOX_SELECTED, GetId() );
598 event.SetInt( 0 );
29006414 599 event.SetString( value );
7cf8cb48
VZ
600 event.SetEventObject( this );
601 GetEventHandler()->ProcessEvent( event );
602 }
603 else
604 {
605 // add the item to the list if it's not there yet
606 if ( FindString(value) == wxNOT_FOUND )
607 {
608 Append(value);
f6bcfd97 609 SetStringSelection(value);
7cf8cb48
VZ
610
611 // and generate the selected event for it
612 wxCommandEvent event( wxEVT_COMMAND_COMBOBOX_SELECTED, GetId() );
613 event.SetInt( Number() - 1 );
29006414 614 event.SetString( value );
7cf8cb48
VZ
615 event.SetEventObject( this );
616 GetEventHandler()->ProcessEvent( event );
617 }
2b328fc9
RR
618 else
619 {
620 // This will invoke the dialog default action, such
621 // as the clicking the default button.
622
623 wxWindow *top_frame = m_parent;
624 while (top_frame->GetParent() && !(top_frame->IsTopLevel()))
625 top_frame = top_frame->GetParent();
626
627 if (top_frame && GTK_IS_WINDOW(top_frame->m_widget))
628 {
629 GtkWindow *window = GTK_WINDOW(top_frame->m_widget);
630
631 if (window->default_widget)
632 {
633 gtk_widget_activate (window->default_widget);
634 return;
635 }
636 }
637 }
7cf8cb48 638 }
8a85884a 639 }
7cf8cb48
VZ
640
641 event.Skip();
8a85884a
VZ
642}
643
953704c1
RR
644void wxComboBox::DisableEvents()
645{
646 GtkList *list = GTK_LIST( GTK_COMBO(m_widget)->list );
647 GList *child = list->children;
648 while (child)
649 {
31528cd3 650 gtk_signal_disconnect_by_func( GTK_OBJECT(child->data),
953704c1
RR
651 GTK_SIGNAL_FUNC(gtk_combo_clicked_callback), (gpointer)this );
652
653 child = child->next;
654 }
655}
656
657void wxComboBox::EnableEvents()
658{
659 GtkList *list = GTK_LIST( GTK_COMBO(m_widget)->list );
660 GList *child = list->children;
661 while (child)
662 {
663 gtk_signal_connect( GTK_OBJECT(child->data), "select",
664 GTK_SIGNAL_FUNC(gtk_combo_clicked_callback), (gpointer)this );
665
666 child = child->next;
667 }
668}
669
b4071e91
RR
670void wxComboBox::OnSize( wxSizeEvent &event )
671{
f03fc89f 672 event.Skip();
31528cd3 673
b02da6b1 674#if 0
fd0eed64
RR
675 int w = 21;
676 gtk_widget_set_usize( GTK_COMBO(m_widget)->entry, m_width-w-1, m_height );
805dd538 677
fd0eed64
RR
678 gtk_widget_set_uposition( GTK_COMBO(m_widget)->button, m_x+m_width-w, m_y );
679 gtk_widget_set_usize( GTK_COMBO(m_widget)->button, w, m_height );
b02da6b1 680#endif // 0
6de97a3b 681}
53010e52 682
58614078 683void wxComboBox::ApplyWidgetStyle()
868a2826 684{
fd0eed64 685 SetWidgetStyle();
805dd538 686
72a16063 687// gtk_widget_set_style( GTK_COMBO(m_widget)->button, m_widgetStyle );
fd0eed64
RR
688 gtk_widget_set_style( GTK_COMBO(m_widget)->entry, m_widgetStyle );
689 gtk_widget_set_style( GTK_COMBO(m_widget)->list, m_widgetStyle );
805dd538 690
fd0eed64
RR
691 GtkList *list = GTK_LIST( GTK_COMBO(m_widget)->list );
692 GList *child = list->children;
693 while (child)
694 {
695 gtk_widget_set_style( GTK_WIDGET(child->data), m_widgetStyle );
805dd538 696
fd0eed64
RR
697 GtkBin *bin = GTK_BIN(child->data);
698 gtk_widget_set_style( bin->child, m_widgetStyle );
805dd538 699
fd0eed64
RR
700 child = child->next;
701 }
868a2826 702}
b4071e91 703
fd0eed64 704GtkWidget* wxComboBox::GetConnectWidget()
97b3455a 705{
fd0eed64 706 return GTK_COMBO(m_widget)->entry;
97b3455a
RR
707}
708
b4071e91
RR
709bool wxComboBox::IsOwnGtkWindow( GdkWindow *window )
710{
fd0eed64
RR
711 return ( (window == GTK_ENTRY( GTK_COMBO(m_widget)->entry )->text_area) ||
712 (window == GTK_COMBO(m_widget)->button->window ) );
b4071e91 713}
ac57418f 714
f68586e5
VZ
715wxSize wxComboBox::DoGetBestSize() const
716{
db434467 717 wxSize ret( wxControl::DoGetBestSize() );
a6fc8ae3
VZ
718
719 // we know better our horizontal extent: it depends on the longest string
720 // in the combobox
721 ret.x = 0;
722 if ( m_widget )
723 {
724 GdkFont *font = m_font.GetInternalFont();
725
726 wxCoord width;
727 size_t count = Number();
728 for ( size_t n = 0; n < count; n++ )
729 {
730 width = (wxCoord)gdk_string_width(font, GetString(n).mbc_str());
731 if ( width > ret.x )
732 ret.x = width;
733 }
734 }
735
736 // empty combobox should have some reasonable default size too
737 if ( ret.x < 100 )
738 ret.x = 100;
db434467 739 return ret;
f68586e5
VZ
740}
741
dcf924a3 742#endif