]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk/combobox.cpp
no message
[wxWidgets.git] / src / gtk / combobox.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: combobox.cpp
3// Purpose:
4// Author: Robert Roebling
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10#ifdef __GNUG__
11#pragma implementation "combobox.h"
12#endif
13
14#include "wx/combobox.h"
15#include <wx/intl.h>
16
17//-----------------------------------------------------------------------------
18// data
19//-----------------------------------------------------------------------------
20
21extern bool g_blockEventsOnDrag;
22
23//-----------------------------------------------------------------------------
24// "select"
25//-----------------------------------------------------------------------------
26
27static void gtk_combo_clicked_callback( GtkWidget *WXUNUSED(widget), wxComboBox *combo )
28{
29 if (!combo->HasVMT()) return;
30 if (g_blockEventsOnDrag) return;
31
32 if (combo->m_alreadySent)
33 {
34 combo->m_alreadySent = FALSE;
35 return;
36 }
37
38 combo->m_alreadySent = TRUE;
39
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);
46}
47
48//-----------------------------------------------------------------------------
49// wxComboBox
50//-----------------------------------------------------------------------------
51
52IMPLEMENT_DYNAMIC_CLASS(wxComboBox,wxControl)
53
54BEGIN_EVENT_TABLE(wxComboBox, wxControl)
55 EVT_SIZE(wxComboBox::OnSize)
56END_EVENT_TABLE()
57
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 )
63{
64 m_alreadySent = FALSE;
65 m_needParent = TRUE;
66
67 PreCreation( parent, id, pos, size, style, name );
68
69 SetValidator( validator );
70
71 m_widget = gtk_combo_new();
72
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 );
77
78 GtkWidget *list = GTK_COMBO(m_widget)->list;
79
80 for (int i = 0; i < n; i++)
81 {
82 GtkWidget *list_item = gtk_list_item_new_with_label( choices[i] );
83
84 m_clientDataList.Append( (wxObject*)NULL );
85
86 gtk_container_add( GTK_CONTAINER(list), list_item );
87
88 gtk_widget_realize( list_item );
89 gtk_widget_realize( GTK_BIN(list_item)->child );
90
91 gtk_widget_show( list_item );
92
93 gtk_signal_connect( GTK_OBJECT(list_item), "select",
94 GTK_SIGNAL_FUNC(gtk_combo_clicked_callback), (gpointer)this );
95 }
96
97 m_parent->AddChild( this );
98
99 (m_parent->m_insertCallback)( m_parent, this );
100
101 PostCreation();
102
103 ConnectWidget( GTK_COMBO(m_widget)->button );
104
105 if (!value.IsNull()) SetValue( value );
106
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 );
110
111 SetBackgroundColour( parent->GetBackgroundColour() );
112 SetForegroundColour( parent->GetForegroundColour() );
113
114 Show( TRUE );
115
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();
129}
130
131void wxComboBox::AppendCommon( const wxString &item )
132{
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 );
138
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();
145
146 gtk_widget_show( list_item );
147}
148
149void wxComboBox::Append( const wxString &item )
150{
151 m_clientDataList.Append( (wxObject*)NULL );
152
153 AppendCommon( item );
154}
155
156void wxComboBox::Append( const wxString &item, void *clientData )
157{
158 if (clientData)
159 m_clientDataList.Append( (wxObject*) new wxVoidClientData( clientData ) );
160 else
161 m_clientDataList.Append( (wxObject*)NULL );
162
163 AppendCommon( item );
164}
165
166void wxComboBox::Append( const wxString &item, wxClientData *clientData )
167{
168 m_clientDataList.Append( (wxObject*) clientData );
169
170 AppendCommon( item );
171}
172
173void wxComboBox::SetClientData( int n, void* clientData )
174{
175 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
176
177 wxNode *node = m_clientDataList.Nth( n );
178 if (!node) return;
179
180 wxClientData *cd = (wxClientData*) node->Data();
181 if (cd) delete cd;
182
183 if (clientData)
184 node->SetData( (wxObject*) new wxVoidClientData(clientData) );
185 else
186 node->SetData( (wxObject*) NULL );
187}
188
189void* wxComboBox::GetClientData( int n )
190{
191 wxCHECK_MSG( m_widget != NULL, NULL, "invalid combobox" );
192
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;
209
210 wxClientData *cd = (wxClientData*) node->Data();
211 if (cd) delete cd;
212
213 node->SetData( (wxObject*) clientData );
214}
215
216wxClientData* wxComboBox::GetClientObject( int n )
217{
218 wxCHECK_MSG( m_widget != NULL, (wxClientData*)NULL, "invalid combobox" );
219
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" );
229
230 GtkWidget *list = GTK_COMBO(m_widget)->list;
231 gtk_list_clear_items( GTK_LIST(list), 0, Number() );
232
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();
241}
242
243void wxComboBox::Delete( int n )
244{
245 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
246
247 GtkList *listbox = GTK_LIST( GTK_COMBO(m_widget)->list );
248
249 GList *child = g_list_nth( listbox->children, n );
250
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 }
272}
273
274int wxComboBox::FindString( const wxString &item )
275{
276 wxCHECK_MSG( m_widget != NULL, -1, "invalid combobox" );
277
278 GtkWidget *list = GTK_COMBO(m_widget)->list;
279
280 GList *child = GTK_LIST(list)->children;
281 int count = 0;
282 while (child)
283 {
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 }
313 }
314
315 wxFAIL_MSG( "wxComboBox: no selection" );
316
317 return -1;
318}
319
320wxString wxComboBox::GetString( int n ) const
321{
322 wxCHECK_MSG( m_widget != NULL, "", "invalid combobox" );
323
324 GtkWidget *list = GTK_COMBO(m_widget)->list;
325
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 }
333
334 wxFAIL_MSG( "wxComboBox: wrong index" );
335
336 return "";
337}
338
339wxString wxComboBox::GetStringSelection() const
340{
341 wxCHECK_MSG( m_widget != NULL, "", "invalid combobox" );
342
343 GtkWidget *list = GTK_COMBO(m_widget)->list;
344
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 }
352
353 wxFAIL_MSG( "wxComboBox: no selection" );
354
355 return "";
356}
357
358int wxComboBox::Number() const
359{
360 wxCHECK_MSG( m_widget != NULL, 0, "invalid combobox" );
361
362 GtkWidget *list = GTK_COMBO(m_widget)->list;
363
364 GList *child = GTK_LIST(list)->children;
365 int count = 0;
366 while (child) { count++; child = child->next; }
367 return count;
368}
369
370void wxComboBox::SetSelection( int n )
371{
372 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
373
374 GtkWidget *list = GTK_COMBO(m_widget)->list;
375 gtk_list_select_item( GTK_LIST(list), n );
376}
377
378void wxComboBox::SetStringSelection( const wxString &string )
379{
380 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
381
382 int res = FindString( string );
383 if (res == -1) return;
384 SetSelection( res );
385}
386
387wxString wxComboBox::GetValue() const
388{
389 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
390 wxString tmp = gtk_entry_get_text( GTK_ENTRY(entry) );
391 return tmp;
392}
393
394void wxComboBox::SetValue( const wxString& value )
395{
396 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
397
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 );
402}
403
404void wxComboBox::Copy()
405{
406 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
407
408 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
409#if (GTK_MINOR_VERSION == 1)
410 gtk_editable_copy_clipboard( GTK_EDITABLE(entry) );
411#else
412 gtk_editable_copy_clipboard( GTK_EDITABLE(entry), 0 );
413#endif
414}
415
416void wxComboBox::Cut()
417{
418 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
419
420 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
421#if (GTK_MINOR_VERSION == 1)
422 gtk_editable_cut_clipboard( GTK_EDITABLE(entry) );
423#else
424 gtk_editable_cut_clipboard( GTK_EDITABLE(entry), 0 );
425#endif
426}
427
428void wxComboBox::Paste()
429{
430 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
431
432 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
433#if (GTK_MINOR_VERSION == 1)
434 gtk_editable_paste_clipboard( GTK_EDITABLE(entry) );
435#else
436 gtk_editable_paste_clipboard( GTK_EDITABLE(entry), 0 );
437#endif
438}
439
440void wxComboBox::SetInsertionPoint( long pos )
441{
442 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
443
444 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
445 int tmp = (int) pos;
446 gtk_entry_set_position( GTK_ENTRY(entry), tmp );
447}
448
449void wxComboBox::SetInsertionPointEnd()
450{
451 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
452
453 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
454 int pos = GTK_ENTRY(entry)->text_length;
455 SetInsertionPoint( pos-1 );
456}
457
458long wxComboBox::GetInsertionPoint() const
459{
460 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
461 return (long) GTK_EDITABLE(entry)->current_pos;
462}
463
464long wxComboBox::GetLastPosition() const
465{
466 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
467 int pos = GTK_ENTRY(entry)->text_length;
468 return (long) pos-1;
469}
470
471void wxComboBox::Replace( long from, long to, const wxString& value )
472{
473 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
474
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 );
480}
481
482void wxComboBox::Remove(long from, long to)
483{
484 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
485
486 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
487 gtk_editable_delete_text( GTK_EDITABLE(entry), (gint)from, (gint)to );
488}
489
490void wxComboBox::SetSelection( long WXUNUSED(from), long WXUNUSED(to) )
491{
492 wxFAIL_MSG( "wxComboBox::SetSelection not implemented" );
493}
494
495void wxComboBox::SetEditable( bool WXUNUSED(editable) )
496{
497 wxFAIL_MSG( "wxComboBox::SetEditable not implemented" );
498}
499
500void wxComboBox::OnSize( wxSizeEvent &event )
501{
502 wxControl::OnSize( event );
503
504 int w = 21;
505 gtk_widget_set_usize( GTK_COMBO(m_widget)->entry, m_width-w-1, m_height );
506
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 );
509}
510
511void wxComboBox::ApplyWidgetStyle()
512{
513 SetWidgetStyle();
514
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 );
518
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 );
524
525 GtkBin *bin = GTK_BIN(child->data);
526 gtk_widget_set_style( bin->child, m_widgetStyle );
527
528 child = child->next;
529 }
530}
531
532GtkWidget* wxComboBox::GetConnectWidget()
533{
534 return GTK_COMBO(m_widget)->entry;
535}
536
537bool wxComboBox::IsOwnGtkWindow( GdkWindow *window )
538{
539 return ( (window == GTK_ENTRY( GTK_COMBO(m_widget)->entry )->text_area) ||
540 (window == GTK_COMBO(m_widget)->button->window ) );
541}