1 /*   EXTRAITS DE LA LICENCE
2 	Copyright CEA, contributeurs : Damien
3 	CALISTE, laboratoire L_Sim, (2001-2005)
4 
5 	Adresse mèl :
6 	CALISTE, damien P caliste AT cea P fr.
7 
8 	Ce logiciel est un programme informatique servant à visualiser des
9 	structures atomiques dans un rendu pseudo-3D.
10 
11 	Ce logiciel est régi par la licence CeCILL soumise au droit français et
12 	respectant les principes de diffusion des logiciels libres. Vous pouvez
13 	utiliser, modifier et/ou redistribuer ce programme sous les conditions
14 	de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
15 	sur le site "http://www.cecill.info".
16 
17 	Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
18 	pris connaissance de la licence CeCILL, et que vous en avez accepté les
19 	termes (cf. le fichier Documentation/licence.fr.txt fourni avec ce logiciel).
20 */
21 
22 /*   LICENCE SUM UP
23 	Copyright CEA, contributors : Damien
24 	CALISTE, laboratoire L_Sim, (2001-2005)
25 
26 	E-mail address:
27 	CALISTE, damien P caliste AT cea P fr.
28 
29 	This software is a computer program whose purpose is to visualize atomic
30 	configurations in 3D.
31 
32 	This software is governed by the CeCILL  license under French law and
33 	abiding by the rules of distribution of free software.  You can  use,
34 	modify and/ or redistribute the software under the terms of the CeCILL
35 	license as circulated by CEA, CNRS and INRIA at the following URL
36 	"http://www.cecill.info".
37 
38 	The fact that you are presently reading this means that you have had
39 	knowledge of the CeCILL license and that you accept its terms. You can
40 	find a copy of this licence shipped with this software at Documentation/licence.en.txt.
41 */
42 #include <gtk/gtk.h>
43 
44 #include <string.h>
45 
46 #include "gtk_elementComboBox.h"
47 #include <visu_tools.h>
48 #include <visu_elements.h>
49 
50 /**
51  * SECTION:gtk_elementComboBox
52  * @short_description: Defines a specialised #GtkComboBox to choose #VisuElement.
53  *
54  * <para>This widget looks like a #GtkComboBox and it displays a list
55  * of #VisuElement currently used by the displayed data.</para>
56  *
57  * Since: 3.6
58  */
59 
60 enum {
61   ELEMENT_SELECTED_SIGNAL,
62   LAST_SIGNAL
63 };
64 
65 /* This enum is used to access the column of the GtkListStore
66    that contains the informations of stroed shades. */
67 enum
68   {
69     /* This a pointer to the VisuElement */
70     COLUMN_ELEMENT_POINTER_TO,
71     N_COLUMN_ELEMENT
72   };
73 
74 enum
75   {
76     PROP_0,
77     NODES_PROP,
78     ELEMENT_PROP,
79     N_PROP
80   };
81 static GParamSpec *_properties[N_PROP];
82 
83 static void visu_ui_element_combobox_dispose (GObject *obj);
84 static void visu_ui_element_combobox_finalize(GObject *obj);
85 static void visu_ui_element_combobox_get_property(GObject* obj, guint property_id,
86                                                   GValue *value, GParamSpec *pspec);
87 static void visu_ui_element_combobox_set_property(GObject* obj, guint property_id,
88                                                   const GValue *value, GParamSpec *pspec);
89 
90 static guint _signals[LAST_SIGNAL] = { 0 };
91 
92 /**
93  * VisuUiElementCombobox:
94  *
95  * An opaque structure defining a #VisuUiElementCombobox widget.
96  *
97  * Since: 3.6
98  */
99 struct _VisuUiElementCombobox
100 {
101   GtkComboBox parent;
102 
103   GtkTreeModel *filter;
104 
105   VisuNodeArray *nodes;
106   gulong popDef_signal;
107 
108   gulong onChanged;
109   gpointer previousSelection;
110 
111   gboolean hasAllSelector;
112   gboolean hasNoneSelector;
113   gboolean showUnPhysical;
114   gchar *format;
115 
116   /* Memory gestion. */
117   gboolean dispose_has_run;
118 };
119 
120 /**
121  * VisuUiElementComboboxClass:
122  *
123  * An opaque structure defining the class of a #VisuUiElementCombobox widget.
124  *
125  * Since: 3.6
126  */
127 struct _VisuUiElementComboboxClass
128 {
129   GtkComboBoxClass parent_class;
130 
131   void (*elementComboBox) (VisuUiElementCombobox *shadeCombo);
132 
133   /* This listStore contains all the elements
134      known by widgets of this class. It is used
135      as TreeModel for the combobox in the widget. */
136   GtkListStore *storedElements;
137 
138   gulong newElementSignalId;
139 };
140 
141 /* Local callbacks. */
142 static void onChanged(GtkComboBox *widget, gpointer user_data);
143 static gboolean onElementNewHook(GSignalInvocationHint *ihint, guint nvalues,
144                                  const GValue *param_values, gpointer data);
145 
146 /* Local methods. */
147 static void addElementToModel(GtkTreeIter *iter, VisuUiElementComboboxClass* klass,
148                               gpointer element);
149 static void printLabel(GtkCellLayout *layout, GtkCellRenderer *cell,
150                        GtkTreeModel *model, GtkTreeIter *iter, gpointer data);
151 static gboolean showLabel(GtkTreeModel *model, GtkTreeIter *iter, gpointer data);
152 
153 /**
154  * visu_ui_element_combobox_get_type:
155  *
156  * Internal routine, retrieves the type of #VisuUiElementCombobox
157  * objects. Use VISU_TYPE_UI_ELEMENT_COMBOBOX macro instead.
158  *
159  * Since: 3.6
160  */
G_DEFINE_TYPE(VisuUiElementCombobox,visu_ui_element_combobox,GTK_TYPE_COMBO_BOX)161 G_DEFINE_TYPE(VisuUiElementCombobox, visu_ui_element_combobox, GTK_TYPE_COMBO_BOX)
162 
163 static void visu_ui_element_combobox_class_init(VisuUiElementComboboxClass *klass)
164 {
165   GtkTreeIter iter;
166   GList *elementLst;
167 
168   DBG_fprintf(stderr, "VisuUi ElementCombobox: creating the class of the widget.\n");
169   DBG_fprintf(stderr, "                     - adding new signals ;\n");
170   /**
171    * VisuUiElementCombobox::element-selected:
172    * @combo: the #VisuUiElementCombobox that emits the signal ;
173    * @element: the newly selected #VisuElement.
174    *
175    * This signal is emitted when a new element is selected.
176    *
177    * Since: 3.6
178    */
179   _signals[ELEMENT_SELECTED_SIGNAL] =
180     g_signal_new ("element-selected",
181 		  G_TYPE_FROM_CLASS (klass),
182 		  G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
183 		  G_STRUCT_OFFSET (VisuUiElementComboboxClass, elementComboBox),
184 		  NULL,
185 		  NULL,
186 		  g_cclosure_marshal_VOID__POINTER,
187 		  G_TYPE_NONE, 1, G_TYPE_POINTER);
188 
189   DBG_fprintf(stderr, "                     - initializing the listStore of elements.\n");
190   /* Init the listStore of elements. */
191   klass->storedElements = gtk_list_store_new(N_COLUMN_ELEMENT,
192                                              G_TYPE_POINTER);
193   addElementToModel(&iter, klass, (gpointer)0);
194   addElementToModel(&iter, klass, GINT_TO_POINTER(1));
195   for (elementLst = (GList*)visu_element_getAllElements(); elementLst;
196        elementLst = g_list_next(elementLst))
197     addElementToModel(&iter, klass, elementLst->data);
198 
199   /* Connect freeing methods. */
200   G_OBJECT_CLASS(klass)->dispose  = visu_ui_element_combobox_dispose;
201   G_OBJECT_CLASS(klass)->finalize = visu_ui_element_combobox_finalize;
202   G_OBJECT_CLASS(klass)->set_property = visu_ui_element_combobox_set_property;
203   G_OBJECT_CLASS(klass)->get_property = visu_ui_element_combobox_get_property;
204 
205   /**
206    * VisuUiElementCombobox::nodes:
207    *
208    * Store the #VisuNodeArray object used to filter the elements.
209    *
210    * Since: 3.8
211    */
212   _properties[NODES_PROP] = g_param_spec_object("nodes", "Nodes",
213                                                 "storing nodes used as filter model",
214                                                 VISU_TYPE_NODE_ARRAY, G_PARAM_READWRITE);
215   /**
216    * VisuUiElementCombobox::element:
217    *
218    * Store the #VisuElement currently selected.
219    *
220    * Since: 3.8
221    */
222   _properties[ELEMENT_PROP] = g_param_spec_object("element", "Element",
223                                                 "currently selected element",
224                                                   VISU_TYPE_ELEMENT, G_PARAM_READWRITE);
225 
226   g_object_class_install_properties(G_OBJECT_CLASS(klass), N_PROP, _properties);
227 
228   g_type_class_ref(VISU_TYPE_ELEMENT);
229   g_signal_add_emission_hook(g_signal_lookup("ElementNew", VISU_TYPE_ELEMENT),
230                              0, onElementNewHook, (gpointer)klass, (GDestroyNotify)0);
231 }
232 
visu_ui_element_combobox_dispose(GObject * obj)233 static void visu_ui_element_combobox_dispose(GObject *obj)
234 {
235   DBG_fprintf(stderr, "VisuUi ElementCombobox: dispose object %p.\n", (gpointer)obj);
236 
237   if (VISU_UI_ELEMENT_COMBOBOX(obj)->dispose_has_run)
238     return;
239 
240   VISU_UI_ELEMENT_COMBOBOX(obj)->dispose_has_run = TRUE;
241   visu_ui_element_combobox_setModel(VISU_UI_ELEMENT_COMBOBOX(obj), (VisuNodeArray*)0);
242 
243   /* Chain up to the parent class */
244   G_OBJECT_CLASS(visu_ui_element_combobox_parent_class)->dispose(obj);
245 }
visu_ui_element_combobox_finalize(GObject * obj)246 static void visu_ui_element_combobox_finalize(GObject *obj)
247 {
248   g_return_if_fail(obj);
249 
250   DBG_fprintf(stderr, "VisuUi ElementCombobox: finalize object %p.\n", (gpointer)obj);
251   g_free(VISU_UI_ELEMENT_COMBOBOX(obj)->format);
252 
253   /* Chain up to the parent class */
254   G_OBJECT_CLASS(visu_ui_element_combobox_parent_class)->finalize(obj);
255 
256   DBG_fprintf(stderr, " | freeing ... OK.\n");
257 }
visu_ui_element_combobox_get_property(GObject * obj,guint property_id,GValue * value,GParamSpec * pspec)258 static void visu_ui_element_combobox_get_property(GObject* obj, guint property_id,
259                                                   GValue *value, GParamSpec *pspec)
260 {
261   VisuUiElementCombobox *self = VISU_UI_ELEMENT_COMBOBOX(obj);
262   GtkTreeIter iter;
263   gpointer data;
264 
265   DBG_fprintf(stderr, "VisuUi ElementCombobox: get property '%s' -> ",
266 	      g_param_spec_get_name(pspec));
267   switch (property_id)
268     {
269     case NODES_PROP:
270       g_value_set_object(value, self->nodes);
271       DBG_fprintf(stderr, "%p.\n", g_value_get_object(value));
272       break;
273     case ELEMENT_PROP:
274       if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(obj), &iter))
275         {
276           gtk_tree_model_get(self->filter, &iter, COLUMN_ELEMENT_POINTER_TO, &data, -1);
277           g_value_set_object(value, (GPOINTER_TO_INT(data) == 1) ? NULL : data);
278         }
279       else
280         g_value_set_object(value, (GObject*)0);
281       DBG_fprintf(stderr, "%p.\n", g_value_get_object(value));
282       break;
283     default:
284       /* We don't have any other property... */
285       G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
286       break;
287     }
288 }
visu_ui_element_combobox_set_property(GObject * obj,guint property_id,const GValue * value,GParamSpec * pspec)289 static void visu_ui_element_combobox_set_property(GObject* obj, guint property_id,
290                                          const GValue *value, GParamSpec *pspec)
291 {
292   VisuUiElementCombobox *self = VISU_UI_ELEMENT_COMBOBOX(obj);
293 
294   DBG_fprintf(stderr, "VisuUi ElementCombobox: set property '%s' -> ",
295 	      g_param_spec_get_name(pspec));
296   switch (property_id)
297     {
298     case NODES_PROP:
299       DBG_fprintf(stderr, "%p\n", g_value_get_object(value));
300       visu_ui_element_combobox_setModel(self, VISU_NODE_ARRAY(g_value_get_object(value)));
301       break;
302     case ELEMENT_PROP:
303       DBG_fprintf(stderr, "%p\n", g_value_get_object(value));
304       visu_ui_element_combobox_setElement(self, VISU_ELEMENT(g_value_get_object(value)));
305       break;
306     default:
307       /* We don't have any other property... */
308       G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
309       break;
310     }
311 }
312 
313 
visu_ui_element_combobox_init(VisuUiElementCombobox * elementComboBox)314 static void visu_ui_element_combobox_init(VisuUiElementCombobox *elementComboBox)
315 {
316   DBG_fprintf(stderr, "VisuUi ElementCombobox: initializing new object (%p).\n",
317 	      (gpointer)elementComboBox);
318 
319   elementComboBox->hasAllSelector    = FALSE;
320   elementComboBox->hasNoneSelector   = FALSE;
321   elementComboBox->showUnPhysical    = FALSE;
322   elementComboBox->format            = g_strdup("%s");
323   elementComboBox->dispose_has_run   = FALSE;
324   elementComboBox->previousSelection = (gpointer)0;
325   elementComboBox->nodes             = (VisuNodeArray*)0;
326 }
327 
328 /**
329  * visu_ui_element_combobox_new:
330  * @hasAllSelector: a boolean.
331  * @hasNoneSelector: a boolean.
332  * @format: (allow-none): a string (can be NULL).
333  *
334  * Creates a #GtkComboBox with a list of available #VisuElement. This
335  * list can contain in addition a "all" value if @hasAllSelector is
336  * TRUE, or a "None" value if @hasNoneSelector is TRUE. The @format
337  * parameter is used to specify the text for each row of the
338  * #GtkComboBox. If @formt is NULL, just the name of the element is printed.
339  *
340  * Since: 3.6
341  *
342  * Returns: (transfer full): a newly created widget.
343  */
visu_ui_element_combobox_new(gboolean hasAllSelector,gboolean hasNoneSelector,const gchar * format)344 GtkWidget* visu_ui_element_combobox_new(gboolean hasAllSelector, gboolean hasNoneSelector,
345                                         const gchar *format)
346 {
347   VisuUiElementCombobox *wd;
348   GObjectClass *klass;
349   GtkCellRenderer *renderer;
350 
351   DBG_fprintf(stderr, "VisuUi ElementCombobox: creating new object with format: '%s'.\n",
352 	      format);
353   wd = VISU_UI_ELEMENT_COMBOBOX(g_object_new(VISU_TYPE_UI_ELEMENT_COMBOBOX, NULL));
354   wd->hasAllSelector  = hasAllSelector;
355   wd->hasNoneSelector = hasNoneSelector;
356   if (format)
357     {
358       g_free(wd->format);
359       wd->format = g_strdup(format);
360     }
361 
362   DBG_fprintf(stderr, "VisuUi ElementCombobox: build widgets.\n");
363   klass = G_OBJECT_GET_CLASS(wd);
364   wd->filter = gtk_tree_model_filter_new
365     (GTK_TREE_MODEL(VISU_UI_ELEMENT_COMBOBOX_CLASS(klass)->storedElements), (GtkTreePath*)0);
366   gtk_combo_box_set_model(GTK_COMBO_BOX(wd), wd->filter);
367   g_object_unref(wd->filter);
368   gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(wd->filter),
369                                          showLabel, wd, (GDestroyNotify)0);
370   gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(wd->filter));
371   DBG_fprintf(stderr, "VisuUi ElementCombobox: use filter %p.\n", (gpointer)wd->filter);
372 
373   renderer = gtk_cell_renderer_text_new();
374   gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(wd), renderer, TRUE);
375   gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(wd),
376                                      renderer, printLabel,
377                                      (gpointer)wd, (GDestroyNotify)0);
378 
379   wd->onChanged = g_signal_connect(G_OBJECT(wd), "changed",
380                                    G_CALLBACK(onChanged), (gpointer)wd);
381   gtk_combo_box_set_active(GTK_COMBO_BOX(wd), (hasAllSelector)?1:0);
382 
383   return GTK_WIDGET(wd);
384 }
385 
386 /**
387  * visu_ui_element_combobox_setModel:
388  * @combo: a #VisuUiElementCombobox object.
389  * @nodes: a #VisuNodeArray object.
390  *
391  * Binds @nodes to @combo, so the list is always displaying the
392  * #VisuElement used by @nodes.
393  *
394  * Since: 3.8
395  *
396  * Returns: TRUE if model is actually changed.
397  **/
visu_ui_element_combobox_setModel(VisuUiElementCombobox * combo,VisuNodeArray * nodes)398 gboolean visu_ui_element_combobox_setModel(VisuUiElementCombobox *combo,
399                                            VisuNodeArray *nodes)
400 {
401   g_return_val_if_fail(VISU_IS_UI_ELEMENT_COMBOBOX(combo), FALSE);
402 
403   if (combo->nodes == nodes)
404     return FALSE;
405 
406   if (combo->nodes)
407     {
408       g_signal_handler_disconnect(combo->nodes, combo->popDef_signal);
409       g_object_unref(combo->nodes);
410     }
411   combo->nodes = nodes;
412   if (nodes)
413     {
414       g_object_ref(nodes);
415       combo->popDef_signal =
416         g_signal_connect_swapped(nodes, "notify::elements",
417                                  G_CALLBACK(gtk_tree_model_filter_refilter),
418                                  combo->filter);
419     }
420   gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(combo->filter));
421   if (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)) < 0)
422     gtk_combo_box_set_active(GTK_COMBO_BOX(combo),
423                              MIN((combo->hasAllSelector)?1:0,
424                                  gtk_tree_model_iter_n_children(combo->filter,
425                                                                 (GtkTreeIter*)0) - 1));
426   return TRUE;
427 }
428 
onElementNewHook(GSignalInvocationHint * ihint _U_,guint nvalues _U_,const GValue * param_values,gpointer data)429 static gboolean onElementNewHook(GSignalInvocationHint *ihint _U_, guint nvalues _U_,
430                                  const GValue *param_values, gpointer data)
431 {
432   GtkTreeIter iter;
433   VisuElement *ele;
434 
435   DBG_fprintf(stderr, "VisuUi ElementCombobox: found a new element.\n");
436   ele = VISU_ELEMENT(g_value_get_object(param_values));
437   addElementToModel(&iter, VISU_UI_ELEMENT_COMBOBOX_CLASS(data), (gpointer)ele);
438   return TRUE;
439 }
440 
onChanged(GtkComboBox * widget,gpointer user_data _U_)441 static void onChanged(GtkComboBox *widget, gpointer user_data _U_)
442 {
443   GtkTreeIter iter;
444   gpointer *data;
445   GList *lst;
446 
447   if (!gtk_combo_box_get_active_iter(widget, &iter))
448     return;
449 
450   DBG_fprintf(stderr, "VisuUi ElementCombobox: internal combobox changed signal.\n");
451   gtk_tree_model_get(VISU_UI_ELEMENT_COMBOBOX(widget)->filter, &iter,
452                      COLUMN_ELEMENT_POINTER_TO, &data, -1);
453 
454   if (data != VISU_UI_ELEMENT_COMBOBOX(widget)->previousSelection)
455     {
456       VISU_UI_ELEMENT_COMBOBOX(widget)->previousSelection = data;
457 
458       lst = visu_ui_element_combobox_getSelection(VISU_UI_ELEMENT_COMBOBOX(widget));
459       DBG_fprintf(stderr, "VisuUi ElementCombobox: emitting 'element-selected'"
460                   " signal with list %p.\n", (gpointer)lst);
461       g_signal_emit(widget, _signals[ELEMENT_SELECTED_SIGNAL], 0, (gpointer)lst);
462       DBG_fprintf(stderr, " | free list\n");
463       if (lst)
464         g_list_free(lst);
465       DBG_fprintf(stderr, " | OK\n");
466       g_object_notify_by_pspec(G_OBJECT(widget), _properties[ELEMENT_PROP]);
467     }
468   else
469     DBG_fprintf(stderr, "VisuUi ElementCombobox: aborting 'element-selected' signal.\n");
470 }
471 
addElementToModel(GtkTreeIter * iter,VisuUiElementComboboxClass * klass,gpointer element)472 static void addElementToModel(GtkTreeIter *iter, VisuUiElementComboboxClass* klass,
473                               gpointer element)
474 {
475   g_return_if_fail(iter && klass);
476 
477   DBG_fprintf(stderr, "VisuUi ElementCombobox: appending a new element '%p'.\n",
478 	      element);
479   gtk_list_store_append(klass->storedElements, iter);
480   gtk_list_store_set(klass->storedElements, iter,
481 		     COLUMN_ELEMENT_POINTER_TO , element,
482 		     -1);
483 }
484 
printLabel(GtkCellLayout * layout _U_,GtkCellRenderer * cell,GtkTreeModel * model,GtkTreeIter * iter,gpointer data)485 static void printLabel(GtkCellLayout *layout _U_, GtkCellRenderer *cell,
486                        GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
487 {
488   gpointer pt;
489   gchar *str;
490 
491   gtk_tree_model_get(model, iter, COLUMN_ELEMENT_POINTER_TO, &pt, -1);
492   if (!pt)
493     g_object_set(G_OBJECT(cell), "text", _("None"), NULL);
494   else if (GPOINTER_TO_INT(pt) == 1)
495     g_object_set(G_OBJECT(cell), "text", _("All elements"), NULL);
496   else
497     {
498       str = g_strdup_printf(VISU_UI_ELEMENT_COMBOBOX(data)->format, ((VisuElement*)pt)->name);
499       g_object_set(G_OBJECT(cell), "text", str, NULL);
500       g_free(str);
501     }
502 }
503 
showLabel(GtkTreeModel * model,GtkTreeIter * iter,gpointer data)504 static gboolean showLabel(GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
505 {
506   gpointer pt;
507   VisuUiElementCombobox *combo;
508 
509   combo = VISU_UI_ELEMENT_COMBOBOX(data);
510   if (!combo->nodes)
511     return FALSE;
512 
513   gtk_tree_model_get(model, iter, COLUMN_ELEMENT_POINTER_TO, &pt, -1);
514   return (!pt && combo->hasNoneSelector) ||
515     (pt && GPOINTER_TO_INT(pt) == 1 && combo->hasAllSelector) ||
516     (pt && GPOINTER_TO_INT(pt) != 1 &&
517      visu_node_array_containsElement(combo->nodes, VISU_ELEMENT(pt)) &&
518      (combo->showUnPhysical || visu_element_getPhysical(VISU_ELEMENT(pt))));
519 }
520 
521 /**
522  * visu_ui_element_combobox_setSelection:
523  * @wd: a #VisuUiElementCombobox widget.
524  * @name: a string.
525  *
526  * Select a #VisuElement by providing its name.
527  *
528  * Since: 3.6
529  *
530  * Returns: TRUE if the given element exists.
531  */
visu_ui_element_combobox_setSelection(VisuUiElementCombobox * wd,const gchar * name)532 gboolean visu_ui_element_combobox_setSelection(VisuUiElementCombobox* wd, const gchar *name)
533 {
534   GtkTreeIter iter;
535   gboolean valid;
536   gpointer *pt;
537 
538   g_return_val_if_fail(VISU_IS_UI_ELEMENT_COMBOBOX(wd) && name, FALSE);
539 
540   DBG_fprintf(stderr, "VisuUi ElementCombobox: select a new element '%s'.\n",
541               name);
542 
543   for (valid = gtk_tree_model_get_iter_first(wd->filter, &iter);
544        valid; valid = gtk_tree_model_iter_next(wd->filter, &iter))
545     {
546       gtk_tree_model_get(wd->filter, &iter, COLUMN_ELEMENT_POINTER_TO, &pt, -1);
547       if (pt && GPOINTER_TO_INT(pt) != 1 &&
548           !strcmp(visu_element_getName(VISU_ELEMENT(pt)), name))
549 	{
550 	  gtk_combo_box_set_active_iter(GTK_COMBO_BOX(wd), &iter);
551 	  return TRUE;
552 	}
553     }
554   return FALSE;
555 }
556 /**
557  * visu_ui_element_combobox_setElement:
558  * @wd: a #VisuUiElementCombobox widget.
559  * @element: a #VisuElement object.
560  *
561  * Select a #VisuElement.
562  *
563  * Since: 3.8
564  *
565  * Returns: TRUE if the given element exists.
566  */
visu_ui_element_combobox_setElement(VisuUiElementCombobox * wd,const VisuElement * element)567 gboolean visu_ui_element_combobox_setElement(VisuUiElementCombobox* wd,
568                                              const VisuElement *element)
569 {
570   GtkTreeIter iter;
571   gboolean valid;
572   gpointer pt;
573 
574   g_return_val_if_fail(VISU_IS_UI_ELEMENT_COMBOBOX(wd), FALSE);
575 
576   for (valid = gtk_tree_model_get_iter_first(wd->filter, &iter);
577        valid; valid = gtk_tree_model_iter_next(wd->filter, &iter))
578     {
579       gtk_tree_model_get(wd->filter, &iter, COLUMN_ELEMENT_POINTER_TO, &pt, -1);
580       if (pt == element)
581 	{
582 	  gtk_combo_box_set_active_iter(GTK_COMBO_BOX(wd), &iter);
583 	  return TRUE;
584 	}
585     }
586   gtk_combo_box_set_active(GTK_COMBO_BOX(wd), -1);
587   return FALSE;
588 }
589 /**
590  * visu_ui_element_combobox_getSelection:
591  * @wd: a #VisuUiElementCombobox widget.
592  *
593  * Provide a list of selected elements.
594  *
595  * Since: 3.6
596  *
597  * Returns: (transfer container) (element-type VisuElement*): a newly
598  * created list of #VisuElement. It should be freed later with
599  * g_list_free().
600  */
visu_ui_element_combobox_getSelection(VisuUiElementCombobox * wd)601 GList* visu_ui_element_combobox_getSelection(VisuUiElementCombobox *wd)
602 {
603   GtkTreeIter iter;
604   gpointer *data;
605   GList *lst;
606   gboolean valid;
607 
608   g_return_val_if_fail(VISU_IS_UI_ELEMENT_COMBOBOX(wd), (GList*)0);
609 
610   if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(wd), &iter))
611     return (GList*)0;
612 
613   gtk_tree_model_get(wd->filter, &iter,
614                      COLUMN_ELEMENT_POINTER_TO, &data, -1);
615 
616   lst = (GList*)0;
617   if (GPOINTER_TO_INT(data) == 1)
618     for (valid = gtk_tree_model_get_iter_first(wd->filter, &iter); valid;
619          valid = gtk_tree_model_iter_next(wd->filter, &iter))
620       {
621         gtk_tree_model_get(wd->filter, &iter,
622                            COLUMN_ELEMENT_POINTER_TO, &data, -1);
623         if (data && GPOINTER_TO_INT(data) != 1 &&
624             visu_element_getPhysical(VISU_ELEMENT(data)))
625           lst = g_list_prepend(lst, data);
626       }
627   else if (data)
628     lst = g_list_prepend(lst, data);
629 
630   DBG_fprintf(stderr, "VisuUi ElementCombobox: return a list of %d elements.\n",
631               g_list_length(lst));
632 
633   return lst;
634 }
635 
636 /**
637  * visu_ui_element_combobox_setUnphysicalStatus:
638  * @wd: a #VisuUiElementCombobox object ;
639  * @status: a boolean
640  *
641  * If @status is TRUE, the combobox will also show elements that are
642  * tagged unphysical, see visu_element_getPhysical().
643  *
644  * Since: 3.7
645  */
visu_ui_element_combobox_setUnphysicalStatus(VisuUiElementCombobox * wd,gboolean status)646 void visu_ui_element_combobox_setUnphysicalStatus(VisuUiElementCombobox* wd,
647                                                   gboolean status)
648 {
649   g_return_if_fail(VISU_IS_UI_ELEMENT_COMBOBOX(wd));
650 
651   wd->showUnPhysical = status;
652 }
653