1 /***************************************************************************
2     begin       : Sun May 16 2010
3     copyright   : (C) 2010 by Martin Preuss
4     email       : martin@libchipcard.de
5 
6  ***************************************************************************
7  *          Please see toplevel file COPYING for license details           *
8  ***************************************************************************/
9 
10 
11 typedef struct W_COMBOBOX W_COMBOBOX;
12 struct W_COMBOBOX {
13   GWEN_STRINGLIST *entries;
14 };
15 
16 
GWEN_INHERIT(GWEN_WIDGET,W_COMBOBOX)17 GWEN_INHERIT(GWEN_WIDGET, W_COMBOBOX)
18 
19 
20 
21 
22 static GWENHYWFAR_CB
23 int Gtk2Gui_WComboBox_SetIntProperty(GWEN_WIDGET *w,
24                                      GWEN_DIALOG_PROPERTY prop,
25                                      GWEN_UNUSED int index,
26                                      int value,
27                                      GWEN_UNUSED int doSignal)
28 {
29   GtkWidget *g;
30   W_COMBOBOX *xw;
31 
32   assert(w);
33   xw=GWEN_INHERIT_GETDATA(GWEN_WIDGET, W_COMBOBOX, w);
34   assert(xw);
35 
36   g=GTK_WIDGET(GWEN_Widget_GetImplData(w, GTK2_DIALOG_WIDGET_REAL));
37   assert(g);
38 
39   switch (prop) {
40   case GWEN_DialogProperty_Enabled:
41     gtk_widget_set_sensitive(GTK_WIDGET(g), (value==0)?FALSE:TRUE);
42     return 0;
43 
44   case GWEN_DialogProperty_Focus:
45     gtk_widget_grab_focus(GTK_WIDGET(g));
46     return 0;
47 
48   case GWEN_DialogProperty_Value:
49     gtk_combo_box_set_active(GTK_COMBO_BOX(g), value);
50     return 0;
51 
52   case GWEN_DialogProperty_ClearValues: {
53     GtkListStore *store;
54 
55     store=GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(g)));
56     assert(store);
57     gtk_list_store_clear(store);
58     GWEN_StringList_Clear(xw->entries);
59     return 0;
60   }
61 
62 
63   default:
64     break;
65   }
66 
67   DBG_WARN(GWEN_LOGDOMAIN,
68            "Function is not appropriate for this type of widget (%s)",
69            GWEN_Widget_Type_toString(GWEN_Widget_GetType(w)));
70   return GWEN_ERROR_INVALID;
71 }
72 
73 
74 
75 
76 static GWENHYWFAR_CB
Gtk2Gui_WComboBox_GetIntProperty(GWEN_WIDGET * w,GWEN_DIALOG_PROPERTY prop,GWEN_UNUSED int index,int defaultValue)77 int Gtk2Gui_WComboBox_GetIntProperty(GWEN_WIDGET *w,
78                                      GWEN_DIALOG_PROPERTY prop,
79                                      GWEN_UNUSED int index,
80                                      int defaultValue)
81 {
82   GtkWidget *g;
83 
84   g=GTK_WIDGET(GWEN_Widget_GetImplData(w, GTK2_DIALOG_WIDGET_REAL));
85   assert(g);
86 
87   switch (prop) {
88   case GWEN_DialogProperty_Enabled:
89     return (gtk_widget_get_sensitive(GTK_WIDGET(g))==TRUE)?1:0;
90 
91   case GWEN_DialogProperty_Focus:
92     return (gtk_widget_has_focus(GTK_WIDGET(g))==TRUE)?1:0;
93     return 0;
94 
95   case GWEN_DialogProperty_Value: {
96     gint i;
97 
98     i=gtk_combo_box_get_active(GTK_COMBO_BOX(g));
99     if (i==-1)
100       return defaultValue;
101     else
102       return i;
103   }
104 
105   case GWEN_DialogProperty_ValueCount: {
106     GtkListStore *store;
107     gint i;
108 
109     store=GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(g)));
110     assert(store);
111     i=gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL);
112     return i;
113   }
114 
115   default:
116     break;
117   }
118 
119   DBG_WARN(GWEN_LOGDOMAIN,
120            "Function is not appropriate for this type of widget (%s)",
121            GWEN_Widget_Type_toString(GWEN_Widget_GetType(w)));
122   return defaultValue;
123 }
124 
125 
126 
127 static GWENHYWFAR_CB
Gtk2Gui_WComboBox_SetCharProperty(GWEN_WIDGET * w,GWEN_DIALOG_PROPERTY prop,GWEN_UNUSED int index,const char * value,GWEN_UNUSED int doSignal)128 int Gtk2Gui_WComboBox_SetCharProperty(GWEN_WIDGET *w,
129                                       GWEN_DIALOG_PROPERTY prop,
130                                       GWEN_UNUSED int index,
131                                       const char *value,
132                                       GWEN_UNUSED int doSignal)
133 {
134   GtkWidget *g;
135   W_COMBOBOX *xw;
136 
137   assert(w);
138   xw=GWEN_INHERIT_GETDATA(GWEN_WIDGET, W_COMBOBOX, w);
139   assert(xw);
140 
141   g=GTK_WIDGET(GWEN_Widget_GetImplData(w, GTK2_DIALOG_WIDGET_REAL));
142   assert(g);
143 
144   switch (prop) {
145   case GWEN_DialogProperty_Value:
146     /* undefined */
147     break;
148 
149   case GWEN_DialogProperty_AddValue: {
150     GtkListStore *store;
151     GtkTreeIter iter;
152 
153     store=GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(g)));
154     assert(store);
155 
156     gtk_list_store_append(store, &iter);
157     gtk_list_store_set(store, &iter, 0, value, -1);
158     GWEN_StringList_AppendString(xw->entries, value, 0, 0);
159     return 0;
160   }
161 
162   case GWEN_DialogProperty_ClearValues: {
163     GtkListStore *store;
164 
165     store=GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(g)));
166     assert(store);
167     gtk_list_store_clear(store);
168     GWEN_StringList_Clear(xw->entries);
169     return 0;
170   }
171 
172   default:
173     break;
174   }
175 
176   DBG_WARN(GWEN_LOGDOMAIN,
177            "Function is not appropriate for this type of widget (%s)",
178            GWEN_Widget_Type_toString(GWEN_Widget_GetType(w)));
179   return GWEN_ERROR_INVALID;
180 }
181 
182 
183 
184 static GWENHYWFAR_CB
Gtk2Gui_WComboBox_GetCharProperty(GWEN_WIDGET * w,GWEN_DIALOG_PROPERTY prop,int index,const char * defaultValue)185 const char *Gtk2Gui_WComboBox_GetCharProperty(GWEN_WIDGET *w,
186                                               GWEN_DIALOG_PROPERTY prop,
187                                               int index,
188                                               const char *defaultValue)
189 {
190   GtkWidget *g;
191   W_COMBOBOX *xw;
192 
193   assert(w);
194   xw=GWEN_INHERIT_GETDATA(GWEN_WIDGET, W_COMBOBOX, w);
195   assert(xw);
196 
197   g=GTK_WIDGET(GWEN_Widget_GetImplData(w, GTK2_DIALOG_WIDGET_REAL));
198   assert(g);
199 
200   switch (prop) {
201   case GWEN_DialogProperty_Value: {
202     const char *s;
203 
204     s=GWEN_StringList_StringAt(xw->entries, index);
205     if (s && *s)
206       return s;
207     else
208       return defaultValue;
209   }
210 
211   default:
212     break;
213   }
214 
215   DBG_WARN(GWEN_LOGDOMAIN,
216            "Function is not appropriate for this type of widget (%s)",
217            GWEN_Widget_Type_toString(GWEN_Widget_GetType(w)));
218   return defaultValue;
219 }
220 
221 
222 
changed_handler(GWEN_UNUSED GtkWidget * comboBox,gpointer data)223 static void changed_handler(GWEN_UNUSED GtkWidget *comboBox, gpointer data)
224 {
225   GWEN_WIDGET *w;
226   int rv;
227 
228   w=data;
229   assert(w);
230   rv=GWEN_Dialog_EmitSignal(GWEN_Widget_GetDialog(w),
231                             GWEN_DialogEvent_TypeActivated,
232                             GWEN_Widget_GetName(w));
233   if (rv==GWEN_DialogEvent_ResultAccept)
234     Gtk2Gui_Dialog_Leave(GWEN_Widget_GetTopDialog(w), 1);
235   else if (rv==GWEN_DialogEvent_ResultReject)
236     Gtk2Gui_Dialog_Leave(GWEN_Widget_GetTopDialog(w), 0);
237 }
238 
239 
240 
Gtk2Gui_WComboBox_FreeData(GWEN_UNUSED void * bp,void * p)241 static void GWENHYWFAR_CB Gtk2Gui_WComboBox_FreeData(GWEN_UNUSED void *bp, void *p)
242 {
243   W_COMBOBOX *xw;
244 
245   xw=(W_COMBOBOX *) p;
246   GWEN_StringList_free(xw->entries);
247   GWEN_FREE_OBJECT(xw);
248 }
249 
250 
251 
Gtk2Gui_WComboBox_Setup(GWEN_WIDGET * w)252 int Gtk2Gui_WComboBox_Setup(GWEN_WIDGET *w)
253 {
254   W_COMBOBOX *xw;
255   GtkWidget *g;
256   GtkCellRenderer *cr;
257   GtkListStore *store;
258   uint32_t flags;
259   GWEN_WIDGET *wParent;
260   /*gulong changed_handler_id;*/
261 
262   flags=GWEN_Widget_GetFlags(w);
263   wParent=GWEN_Widget_Tree_GetParent(w);
264 
265   /* create widget */
266   store=gtk_list_store_new(1, G_TYPE_STRING);
267   if (flags & GWEN_WIDGET_FLAGS_READONLY)
268     g=gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
269   else
270     /* TODO: why the heck does *this* combo box have two columns in the list?? */
271     g=gtk_combo_box_entry_new_with_model(GTK_TREE_MODEL(store), 0);
272   g_object_unref(store);
273 
274   cr=gtk_cell_renderer_text_new();
275   gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(g), cr, TRUE);
276   gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(g), cr, "text", 0, NULL);
277 
278   GWEN_NEW_OBJECT(W_COMBOBOX, xw);
279   GWEN_INHERIT_SETDATA(GWEN_WIDGET, W_COMBOBOX, w, xw, Gtk2Gui_WComboBox_FreeData);
280   xw->entries=GWEN_StringList_new();
281 
282   GWEN_Widget_SetImplData(w, GTK2_DIALOG_WIDGET_REAL, (void *) g);
283   GWEN_Widget_SetImplData(w, GTK2_DIALOG_WIDGET_CONTENT, (void *) g);
284 
285   GWEN_Widget_SetSetIntPropertyFn(w, Gtk2Gui_WComboBox_SetIntProperty);
286   GWEN_Widget_SetGetIntPropertyFn(w, Gtk2Gui_WComboBox_GetIntProperty);
287   GWEN_Widget_SetSetCharPropertyFn(w, Gtk2Gui_WComboBox_SetCharProperty);
288   GWEN_Widget_SetGetCharPropertyFn(w, Gtk2Gui_WComboBox_GetCharProperty);
289 
290   /*changed_handler_id=*/g_signal_connect(g,
291                                           "changed",
292                                           G_CALLBACK(changed_handler),
293                                           w);
294 
295   if (wParent)
296     GWEN_Widget_AddChildGuiWidget(wParent, w);
297 
298   return 0;
299 }
300 
301 
302