]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/combobox.cpp
no message
[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
53010e52
RR
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10#ifdef __GNUG__
11#pragma implementation "combobox.h"
12#endif
13
14#include "wx/combobox.h"
1a5a8367 15#include <wx/intl.h>
53010e52 16
47908e25
RR
17//-----------------------------------------------------------------------------
18// data
19//-----------------------------------------------------------------------------
20
21extern bool g_blockEventsOnDrag;
22
53010e52 23//-----------------------------------------------------------------------------
e1e955e1 24// "select"
47908e25 25//-----------------------------------------------------------------------------
47908e25
RR
26
27static void gtk_combo_clicked_callback( GtkWidget *WXUNUSED(widget), wxComboBox *combo )
53010e52 28{
fd0eed64
RR
29 if (!combo->HasVMT()) return;
30 if (g_blockEventsOnDrag) return;
66bd6b93 31
fd0eed64
RR
32 if (combo->m_alreadySent)
33 {
34 combo->m_alreadySent = FALSE;
35 return;
36 }
47908e25 37
fd0eed64 38 combo->m_alreadySent = TRUE;
47908e25 39
fd0eed64
RR
40 wxCommandEvent event(wxEVT_COMMAND_CHOICE_SELECTED, combo->GetId());
41 event.SetInt( combo->GetSelection() );
42 wxString tmp( combo->GetStringSelection() );
43 event.SetString( WXSTRINGCAST(tmp) );
44 event.SetEventObject(combo);
45 combo->GetEventHandler()->ProcessEvent(event);
6de97a3b 46}
47908e25 47
e1e955e1
RR
48//-----------------------------------------------------------------------------
49// wxComboBox
53010e52
RR
50//-----------------------------------------------------------------------------
51
52IMPLEMENT_DYNAMIC_CLASS(wxComboBox,wxControl)
53
b4071e91 54BEGIN_EVENT_TABLE(wxComboBox, wxControl)
fd0eed64 55 EVT_SIZE(wxComboBox::OnSize)
b4071e91
RR
56END_EVENT_TABLE()
57
fd0eed64
RR
58bool wxComboBox::Create( wxWindow *parent, wxWindowID id, const wxString& value,
59 const wxPoint& pos, const wxSize& size,
60 int n, const wxString choices[],
61 long style, const wxValidator& validator,
62 const wxString& name )
53010e52 63{
fd0eed64
RR
64 m_alreadySent = FALSE;
65 m_needParent = TRUE;
53010e52 66
fd0eed64 67 PreCreation( parent, id, pos, size, style, name );
53010e52 68
fd0eed64 69 SetValidator( validator );
6de97a3b 70
fd0eed64 71 m_widget = gtk_combo_new();
53010e52 72
fd0eed64
RR
73 wxSize newSize = size;
74 if (newSize.x == -1) newSize.x = 100;
75 if (newSize.y == -1) newSize.y = 26;
76 SetSize( newSize.x, newSize.y );
53010e52 77
fd0eed64 78 GtkWidget *list = GTK_COMBO(m_widget)->list;
53010e52 79
fd0eed64
RR
80 for (int i = 0; i < n; i++)
81 {
82 GtkWidget *list_item = gtk_list_item_new_with_label( choices[i] );
53010e52 83
fd0eed64 84 m_clientDataList.Append( (wxObject*)NULL );
f96aa4d9 85
fd0eed64 86 gtk_container_add( GTK_CONTAINER(list), list_item );
53010e52 87
fd0eed64
RR
88 gtk_widget_realize( list_item );
89 gtk_widget_realize( GTK_BIN(list_item)->child );
47908e25 90
fd0eed64 91 gtk_widget_show( list_item );
66bd6b93 92
fd0eed64
RR
93 gtk_signal_connect( GTK_OBJECT(list_item), "select",
94 GTK_SIGNAL_FUNC(gtk_combo_clicked_callback), (gpointer)this );
95 }
53010e52 96
fd0eed64 97 m_parent->AddChild( this );
6ca41e57 98
fd0eed64 99 (m_parent->m_insertCallback)( m_parent, this );
6ca41e57 100
fd0eed64 101 PostCreation();
53010e52 102
fd0eed64 103 ConnectWidget( GTK_COMBO(m_widget)->button );
b4071e91 104
fd0eed64 105 if (!value.IsNull()) SetValue( value );
53010e52 106
fd0eed64
RR
107 gtk_widget_realize( GTK_COMBO(m_widget)->list );
108 gtk_widget_realize( GTK_COMBO(m_widget)->entry );
109 gtk_widget_realize( GTK_COMBO(m_widget)->button );
f96aa4d9 110
fd0eed64
RR
111 SetBackgroundColour( parent->GetBackgroundColour() );
112 SetForegroundColour( parent->GetForegroundColour() );
f96aa4d9 113
fd0eed64 114 Show( TRUE );
53010e52 115
fd0eed64
RR
116 return TRUE;
117}
118
119wxComboBox::~wxComboBox()
120{
121 wxNode *node = m_clientDataList.First();
122 while (node)
123 {
124 wxClientData *cd = (wxClientData*)node->Data();
125 if (cd) delete cd;
126 node = node->Next();
127 }
128 m_clientDataList.Clear();
6de97a3b 129}
53010e52 130
fd0eed64 131void wxComboBox::AppendCommon( const wxString &item )
53010e52 132{
fd0eed64
RR
133 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
134
135 GtkWidget *list = GTK_COMBO(m_widget)->list;
136
137 GtkWidget *list_item = gtk_list_item_new_with_label( item );
f96aa4d9 138
fd0eed64
RR
139 gtk_signal_connect( GTK_OBJECT(list_item), "select",
140 GTK_SIGNAL_FUNC(gtk_combo_clicked_callback), (gpointer)this );
141
142 gtk_container_add( GTK_CONTAINER(list), list_item );
143
144 if (m_widgetStyle) ApplyWidgetStyle();
47908e25 145
fd0eed64 146 gtk_widget_show( list_item );
6de97a3b 147}
53010e52
RR
148
149void wxComboBox::Append( const wxString &item )
47908e25 150{
fd0eed64 151 m_clientDataList.Append( (wxObject*)NULL );
f96aa4d9 152
fd0eed64 153 AppendCommon( item );
6de97a3b 154}
47908e25 155
fd0eed64 156void wxComboBox::Append( const wxString &item, void *clientData )
53010e52 157{
fd0eed64
RR
158 if (clientData)
159 m_clientDataList.Append( (wxObject*) new wxVoidClientData( clientData ) );
160 else
161 m_clientDataList.Append( (wxObject*)NULL );
2f6407b9 162
fd0eed64 163 AppendCommon( item );
6de97a3b 164}
53010e52 165
fd0eed64 166void wxComboBox::Append( const wxString &item, wxClientData *clientData )
53010e52 167{
fd0eed64 168 m_clientDataList.Append( (wxObject*) clientData );
f96aa4d9 169
fd0eed64
RR
170 AppendCommon( item );
171}
172
173void wxComboBox::SetClientData( int n, void* clientData )
174{
175 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
2f6407b9 176
fd0eed64
RR
177 wxNode *node = m_clientDataList.Nth( n );
178 if (!node) return;
2f6407b9 179
fd0eed64
RR
180 wxClientData *cd = (wxClientData*) node->Data();
181 if (cd) delete cd;
47908e25 182
fd0eed64
RR
183 if (clientData)
184 node->SetData( (wxObject*) new wxVoidClientData(clientData) );
185 else
186 node->SetData( (wxObject*) NULL );
6de97a3b 187}
53010e52 188
fd0eed64 189void* wxComboBox::GetClientData( int n )
53010e52 190{
fd0eed64 191 wxCHECK_MSG( m_widget != NULL, NULL, "invalid combobox" );
f96aa4d9 192
fd0eed64
RR
193 wxNode *node = m_clientDataList.Nth( n );
194 if (!node) return NULL;
195
196 wxVoidClientData *cd = (wxVoidClientData*) node->Data();
197 if (cd)
198 return cd->GetData();
199 else
200 return (void*) NULL;
201}
202
203void wxComboBox::SetClientObject( int n, wxClientData* clientData )
204{
205 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
206
207 wxNode *node = m_clientDataList.Nth( n );
208 if (!node) return;
b6af8d80 209
fd0eed64
RR
210 wxClientData *cd = (wxClientData*) node->Data();
211 if (cd) delete cd;
b6af8d80 212
fd0eed64 213 node->SetData( (wxObject*) clientData );
6de97a3b 214}
53010e52 215
fd0eed64 216wxClientData* wxComboBox::GetClientObject( int n )
53010e52 217{
fd0eed64 218 wxCHECK_MSG( m_widget != NULL, (wxClientData*)NULL, "invalid combobox" );
f96aa4d9 219
fd0eed64
RR
220 wxNode *node = m_clientDataList.Nth( n );
221 if (!node) return (wxClientData*) NULL;
222
223 return (wxClientData*) node->Data();
224}
225
226void wxComboBox::Clear()
227{
228 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
b6af8d80 229
fd0eed64
RR
230 GtkWidget *list = GTK_COMBO(m_widget)->list;
231 gtk_list_clear_items( GTK_LIST(list), 0, Number() );
b6af8d80 232
fd0eed64
RR
233 wxNode *node = m_clientDataList.First();
234 while (node)
235 {
236 wxClientData *cd = (wxClientData*)node->Data();
237 if (cd) delete cd;
238 node = node->Next();
239 }
240 m_clientDataList.Clear();
6de97a3b 241}
53010e52 242
fd0eed64 243void wxComboBox::Delete( int n )
53010e52 244{
fd0eed64
RR
245 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
246
247 GtkList *listbox = GTK_LIST( GTK_COMBO(m_widget)->list );
f96aa4d9 248
fd0eed64 249 GList *child = g_list_nth( listbox->children, n );
b6af8d80 250
fd0eed64
RR
251 if (!child)
252 {
253 wxFAIL_MSG("wrong index");
254 return;
255 }
256
257 GList *list = g_list_append( NULL, child->data );
258 gtk_list_remove_items( listbox, list );
259 g_list_free( list );
260
261 wxNode *node = m_clientDataList.Nth( n );
262 if (!node)
263 {
264 wxFAIL_MSG( "wrong index" );
265 }
266 else
267 {
268 wxClientData *cd = (wxClientData*)node->Data();
269 if (cd) delete cd;
270 m_clientDataList.DeleteNode( node );
271 }
6de97a3b 272}
53010e52 273
fd0eed64 274int wxComboBox::FindString( const wxString &item )
53010e52 275{
fd0eed64 276 wxCHECK_MSG( m_widget != NULL, -1, "invalid combobox" );
f96aa4d9 277
fd0eed64 278 GtkWidget *list = GTK_COMBO(m_widget)->list;
53010e52 279
53010e52
RR
280 GList *child = GTK_LIST(list)->children;
281 int count = 0;
282 while (child)
283 {
fd0eed64
RR
284 GtkBin *bin = GTK_BIN( child->data );
285 GtkLabel *label = GTK_LABEL( bin->child );
286 if (item == label->label) return count;
287 count++;
288 child = child->next;
289 }
290
291 wxFAIL_MSG( "wxComboBox: string not found" );
292
293 return -1;
294}
295
296int wxComboBox::GetSelection() const
297{
298 wxCHECK_MSG( m_widget != NULL, -1, "invalid combobox" );
299
300 GtkWidget *list = GTK_COMBO(m_widget)->list;
301
302 GList *selection = GTK_LIST(list)->selection;
303 if (selection)
304 {
305 GList *child = GTK_LIST(list)->children;
306 int count = 0;
307 while (child)
308 {
309 if (child->data == selection->data) return count;
310 count++;
311 child = child->next;
312 }
6de97a3b 313 }
b6af8d80 314
fd0eed64 315 wxFAIL_MSG( "wxComboBox: no selection" );
b6af8d80 316
fd0eed64 317 return -1;
6de97a3b 318}
53010e52 319
debe6624 320wxString wxComboBox::GetString( int n ) const
53010e52 321{
fd0eed64 322 wxCHECK_MSG( m_widget != NULL, "", "invalid combobox" );
f96aa4d9 323
fd0eed64 324 GtkWidget *list = GTK_COMBO(m_widget)->list;
53010e52 325
fd0eed64
RR
326 GList *child = g_list_nth( GTK_LIST(list)->children, n );
327 if (child)
328 {
329 GtkBin *bin = GTK_BIN( child->data );
330 GtkLabel *label = GTK_LABEL( bin->child );
331 return label->label;
332 }
b6af8d80 333
fd0eed64 334 wxFAIL_MSG( "wxComboBox: wrong index" );
b6af8d80 335
fd0eed64 336 return "";
6de97a3b 337}
53010e52 338
fd0eed64 339wxString wxComboBox::GetStringSelection() const
53010e52 340{
fd0eed64 341 wxCHECK_MSG( m_widget != NULL, "", "invalid combobox" );
f96aa4d9 342
fd0eed64 343 GtkWidget *list = GTK_COMBO(m_widget)->list;
53010e52 344
fd0eed64
RR
345 GList *selection = GTK_LIST(list)->selection;
346 if (selection)
347 {
348 GtkBin *bin = GTK_BIN( selection->data );
349 wxString tmp = GTK_LABEL( bin->child )->label;
350 return tmp;
351 }
b6af8d80 352
fd0eed64 353 wxFAIL_MSG( "wxComboBox: no selection" );
b6af8d80 354
fd0eed64 355 return "";
6de97a3b 356}
53010e52 357
fd0eed64 358int wxComboBox::Number() const
53010e52 359{
fd0eed64 360 wxCHECK_MSG( m_widget != NULL, 0, "invalid combobox" );
f96aa4d9 361
fd0eed64 362 GtkWidget *list = GTK_COMBO(m_widget)->list;
53010e52 363
fd0eed64
RR
364 GList *child = GTK_LIST(list)->children;
365 int count = 0;
366 while (child) { count++; child = child->next; }
367 return count;
6de97a3b 368}
53010e52 369
debe6624 370void wxComboBox::SetSelection( int n )
53010e52 371{
fd0eed64 372 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
f96aa4d9 373
fd0eed64
RR
374 GtkWidget *list = GTK_COMBO(m_widget)->list;
375 gtk_list_select_item( GTK_LIST(list), n );
6de97a3b 376}
53010e52 377
47908e25
RR
378void wxComboBox::SetStringSelection( const wxString &string )
379{
fd0eed64 380 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
f96aa4d9 381
fd0eed64
RR
382 int res = FindString( string );
383 if (res == -1) return;
384 SetSelection( res );
6de97a3b 385}
47908e25 386
fd0eed64 387wxString wxComboBox::GetValue() const
53010e52 388{
fd0eed64
RR
389 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
390 wxString tmp = gtk_entry_get_text( GTK_ENTRY(entry) );
391 return tmp;
6de97a3b 392}
53010e52
RR
393
394void wxComboBox::SetValue( const wxString& value )
395{
fd0eed64 396 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
f96aa4d9 397
fd0eed64
RR
398 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
399 wxString tmp = "";
400 if (!value.IsNull()) tmp = value;
401 gtk_entry_set_text( GTK_ENTRY(entry), tmp );
6de97a3b 402}
53010e52 403
fd0eed64 404void wxComboBox::Copy()
53010e52 405{
fd0eed64 406 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
f96aa4d9 407
fd0eed64 408 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
75ed1d15 409#if (GTK_MINOR_VERSION == 1)
fd0eed64 410 gtk_editable_copy_clipboard( GTK_EDITABLE(entry) );
75ed1d15 411#else
fd0eed64 412 gtk_editable_copy_clipboard( GTK_EDITABLE(entry), 0 );
75ed1d15 413#endif
6de97a3b 414}
53010e52 415
fd0eed64 416void wxComboBox::Cut()
53010e52 417{
fd0eed64 418 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
f96aa4d9 419
fd0eed64 420 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
75ed1d15 421#if (GTK_MINOR_VERSION == 1)
fd0eed64 422 gtk_editable_cut_clipboard( GTK_EDITABLE(entry) );
75ed1d15 423#else
fd0eed64 424 gtk_editable_cut_clipboard( GTK_EDITABLE(entry), 0 );
75ed1d15 425#endif
6de97a3b 426}
53010e52 427
fd0eed64 428void wxComboBox::Paste()
53010e52 429{
fd0eed64 430 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
f96aa4d9 431
fd0eed64 432 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
75ed1d15 433#if (GTK_MINOR_VERSION == 1)
fd0eed64 434 gtk_editable_paste_clipboard( GTK_EDITABLE(entry) );
75ed1d15 435#else
fd0eed64 436 gtk_editable_paste_clipboard( GTK_EDITABLE(entry), 0 );
75ed1d15 437#endif
6de97a3b 438}
53010e52 439
debe6624 440void wxComboBox::SetInsertionPoint( long pos )
53010e52 441{
fd0eed64 442 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
f96aa4d9 443
fd0eed64
RR
444 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
445 int tmp = (int) pos;
446 gtk_entry_set_position( GTK_ENTRY(entry), tmp );
6de97a3b 447}
53010e52 448
fd0eed64 449void wxComboBox::SetInsertionPointEnd()
53010e52 450{
fd0eed64 451 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
f96aa4d9 452
fd0eed64
RR
453 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
454 int pos = GTK_ENTRY(entry)->text_length;
455 SetInsertionPoint( pos-1 );
6de97a3b 456}
53010e52 457
fd0eed64 458long wxComboBox::GetInsertionPoint() const
53010e52 459{
fd0eed64
RR
460 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
461 return (long) GTK_EDITABLE(entry)->current_pos;
6de97a3b 462}
53010e52 463
fd0eed64 464long wxComboBox::GetLastPosition() const
53010e52 465{
fd0eed64
RR
466 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
467 int pos = GTK_ENTRY(entry)->text_length;
468 return (long) pos-1;
6de97a3b 469}
53010e52 470
debe6624 471void wxComboBox::Replace( long from, long to, const wxString& value )
53010e52 472{
fd0eed64 473 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
f96aa4d9 474
fd0eed64
RR
475 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
476 gtk_editable_delete_text( GTK_EDITABLE(entry), (gint)from, (gint)to );
477 if (value.IsNull()) return;
478 gint pos = (gint)to;
479 gtk_editable_insert_text( GTK_EDITABLE(entry), value, value.Length(), &pos );
6de97a3b 480}
53010e52 481
debe6624 482void wxComboBox::Remove(long from, long to)
53010e52 483{
fd0eed64 484 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
f96aa4d9 485
fd0eed64
RR
486 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
487 gtk_editable_delete_text( GTK_EDITABLE(entry), (gint)from, (gint)to );
6de97a3b 488}
53010e52 489
debe6624 490void wxComboBox::SetSelection( long WXUNUSED(from), long WXUNUSED(to) )
53010e52 491{
fd0eed64 492 wxFAIL_MSG( "wxComboBox::SetSelection not implemented" );
6de97a3b 493}
53010e52 494
debe6624 495void wxComboBox::SetEditable( bool WXUNUSED(editable) )
53010e52 496{
fd0eed64 497 wxFAIL_MSG( "wxComboBox::SetEditable not implemented" );
b4071e91
RR
498}
499
500void wxComboBox::OnSize( wxSizeEvent &event )
501{
fd0eed64 502 wxControl::OnSize( event );
b4071e91 503
fd0eed64
RR
504 int w = 21;
505 gtk_widget_set_usize( GTK_COMBO(m_widget)->entry, m_width-w-1, m_height );
b4071e91 506
fd0eed64
RR
507 gtk_widget_set_uposition( GTK_COMBO(m_widget)->button, m_x+m_width-w, m_y );
508 gtk_widget_set_usize( GTK_COMBO(m_widget)->button, w, m_height );
6de97a3b 509}
53010e52 510
58614078 511void wxComboBox::ApplyWidgetStyle()
868a2826 512{
fd0eed64 513 SetWidgetStyle();
f96aa4d9 514
fd0eed64
RR
515 gtk_widget_set_style( GTK_COMBO(m_widget)->button, m_widgetStyle );
516 gtk_widget_set_style( GTK_COMBO(m_widget)->entry, m_widgetStyle );
517 gtk_widget_set_style( GTK_COMBO(m_widget)->list, m_widgetStyle );
868a2826 518
fd0eed64
RR
519 GtkList *list = GTK_LIST( GTK_COMBO(m_widget)->list );
520 GList *child = list->children;
521 while (child)
522 {
523 gtk_widget_set_style( GTK_WIDGET(child->data), m_widgetStyle );
58614078 524
fd0eed64
RR
525 GtkBin *bin = GTK_BIN(child->data);
526 gtk_widget_set_style( bin->child, m_widgetStyle );
868a2826 527
fd0eed64
RR
528 child = child->next;
529 }
868a2826 530}
b4071e91 531
fd0eed64 532GtkWidget* wxComboBox::GetConnectWidget()
97b3455a 533{
fd0eed64 534 return GTK_COMBO(m_widget)->entry;
97b3455a
RR
535}
536
b4071e91
RR
537bool wxComboBox::IsOwnGtkWindow( GdkWindow *window )
538{
fd0eed64
RR
539 return ( (window == GTK_ENTRY( GTK_COMBO(m_widget)->entry )->text_area) ||
540 (window == GTK_COMBO(m_widget)->button->window ) );
b4071e91 541}