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