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