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