1 /* EXTRAITS DE LA LICENCE
2 Copyright CEA, contributeurs : Damien
3 CALISTE, laboratoire L_Sim, (2016)
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, (2016)
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
43 #include "gtk_dataChooser.h"
44
45 #include <support.h>
46 #include <visu_gtk.h>
47 #include <visu_dataatomic.h>
48 #include <visu_dataspin.h>
49 #include <visu_configFile.h>
50 #include <openGLFunctions/view.h>
51 #include <visu_extset.h>
52 #include <extensions/nodes.h>
53 #include <extensions/box.h>
54
55 /* Parameters. */
56 #define FLAG_PARAMETER_PREVIEW "main_usePreview"
57 #define DESC_PARAMETER_PREVIEW "Automatically compute preview in filechooser ; boolean"
58 static gboolean usePreview;
59
60 /**
61 * SECTION:gtk_dataChooser
62 * @short_description: A customed file chooser, allowing to slect one
63 * or several files a create a #VisuDataLoadable object accordingly.
64 *
65 * <para>This is a standard file chooser with additional combo box to
66 * select which kind of #VisuDataLoadable we want to select, simple
67 * atomic or spin files.</para>
68 */
69
70
71 /* enum { */
72 /* PROP_0, */
73 /* N_PROPS */
74 /* }; */
75 /* static GParamSpec *_properties[N_PROPS]; */
76
77 /**
78 * VisuUiDataChooserPrivate:
79 *
80 * Private data.
81 */
82 struct _VisuUiDataChooserPrivate
83 {
84 gboolean dispose_has_run;
85
86 GtkWidget *comboMethod, *boxMethod;
87
88 GtkWidget *checkPreview;
89 GtkWidget *image;
90 GtkWidget *boxDescr;
91 guint worker;
92
93 GtkWidget *checkAtomic, *checkSpin;
94 GtkWidget *labelPosition, *labelSpin;
95
96 gchar *atomicFile, *spinFile;
97 VisuDataLoader *atomicFormat, *spinFormat;
98 };
99
100 static void visu_ui_data_chooser_dispose(GObject* obj);
101
102 static void _setMethod(VisuUiDataChooser *this);
103 static void _updatePreview(VisuUiDataChooser *this);
104 static gboolean _setFile(VisuUiDataChooser *this);
105 static void exportParameters(GString *data, VisuData *dataObj);
106
107 /* Pointset interface. */
G_DEFINE_TYPE_WITH_CODE(VisuUiDataChooser,visu_ui_data_chooser,GTK_TYPE_FILE_CHOOSER_DIALOG,G_ADD_PRIVATE (VisuUiDataChooser))108 G_DEFINE_TYPE_WITH_CODE(VisuUiDataChooser, visu_ui_data_chooser, GTK_TYPE_FILE_CHOOSER_DIALOG,
109 G_ADD_PRIVATE(VisuUiDataChooser))
110
111 static void visu_ui_data_chooser_class_init(VisuUiDataChooserClass *klass)
112 {
113 VisuConfigFileEntry *entry;
114
115 G_OBJECT_CLASS(klass)->dispose = visu_ui_data_chooser_dispose;
116
117 /* Set private variables. */
118 usePreview = TRUE;
119 entry = visu_config_file_addBooleanEntry(VISU_CONFIG_FILE_PARAMETER,
120 FLAG_PARAMETER_PREVIEW,
121 DESC_PARAMETER_PREVIEW,
122 &usePreview, FALSE);
123 visu_config_file_entry_setVersion(entry, 3.4f);
124 visu_config_file_addExportFunction(VISU_CONFIG_FILE_PARAMETER,
125 exportParameters);
126 }
visu_ui_data_chooser_init(VisuUiDataChooser * obj)127 static void visu_ui_data_chooser_init(VisuUiDataChooser *obj)
128 {
129 obj->priv = visu_ui_data_chooser_get_instance_private(obj);
130 obj->priv->dispose_has_run = FALSE;
131 obj->priv->atomicFile = (gchar*)0;
132 obj->priv->spinFile = (gchar*)0;
133 obj->priv->atomicFormat = (VisuDataLoader*)0;
134 obj->priv->spinFormat = (VisuDataLoader*)0;
135 }
visu_ui_data_chooser_dispose(GObject * obj)136 static void visu_ui_data_chooser_dispose(GObject* obj)
137 {
138 VisuUiDataChooser *this;
139
140 this = VISU_UI_DATA_CHOOSER(obj);
141 if (this->priv->dispose_has_run)
142 return;
143 this->priv->dispose_has_run = TRUE;
144
145 g_free(this->priv->atomicFile);
146 g_free(this->priv->spinFile);
147 if (this->priv->worker)
148 g_source_remove(this->priv->worker);
149
150 G_OBJECT_CLASS(visu_ui_data_chooser_parent_class)->dispose(obj);
151 }
152
153 /**
154 * visu_ui_data_chooser_new:
155 * @parent: (allow-none): a #GtkWindow parent.
156 *
157 * Creates a dialog allowing to select files to load.
158 *
159 * Since: 3.8
160 *
161 * Returns: (transfer full): a newly created #VisuUiDataChooser object.
162 **/
visu_ui_data_chooser_new(GtkWindow * parent)163 GtkWidget* visu_ui_data_chooser_new(GtkWindow *parent)
164 {
165 VisuUiDataChooser *this;
166 GtkWidget *vbox, *label;
167 GtkWidget *hbox;
168 GtkWidget *frame;
169
170 #if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 12
171 GtkTooltips *tooltips;
172
173 tooltips = gtk_tooltips_new ();
174 #endif
175
176 this = g_object_new(VISU_TYPE_UI_DATA_CHOOSER, "title", _("Load session"), NULL);
177 gtk_widget_set_name(GTK_WIDGET(this), "filesel");
178 gtk_window_set_transient_for(GTK_WINDOW(this), parent);
179 gtk_window_set_position(GTK_WINDOW(this), GTK_WIN_POS_CENTER_ON_PARENT);
180 gtk_window_set_modal(GTK_WINDOW(this), TRUE);
181 gtk_dialog_add_buttons(GTK_DIALOG(this),
182 TOOL_ICON_CANCEL, GTK_RESPONSE_CANCEL,
183 TOOL_ICON_OPEN, GTK_RESPONSE_OK,
184 NULL);
185 gtk_file_chooser_set_action(GTK_FILE_CHOOSER(this), GTK_FILE_CHOOSER_ACTION_OPEN);
186
187 vbox = gtk_dialog_get_content_area(GTK_DIALOG(this));
188
189 hbox = gtk_hbox_new(FALSE, 0);
190 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
191 this->priv->boxMethod = gtk_hbox_new(FALSE, 0);
192 gtk_box_pack_start(GTK_BOX(vbox), this->priv->boxMethod, FALSE, FALSE, 0);
193
194 label = gtk_label_new(_("Rendering method:"));
195 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
196 gtk_label_set_xalign(GTK_LABEL(label), 0.);
197 this->priv->comboMethod = gtk_combo_box_text_new();
198 gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(this->priv->comboMethod),
199 "atomic", _("display node as atoms"));
200 gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(this->priv->comboMethod),
201 "spin", _("display node as spins"));
202 g_signal_connect_swapped(this->priv->comboMethod, "changed",
203 G_CALLBACK(_setMethod), this);
204 gtk_combo_box_set_active(GTK_COMBO_BOX(this->priv->comboMethod), 0);
205 gtk_box_pack_end(GTK_BOX(hbox), this->priv->comboMethod, FALSE, FALSE, 0);
206
207 /* The preview widget. */
208 vbox = gtk_vbox_new(FALSE, 0);
209 gtk_widget_set_hexpand(vbox, FALSE);
210
211 this->priv->checkPreview = gtk_check_button_new_with_mnemonic(_("_Preview:"));
212 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(this->priv->checkPreview),
213 usePreview);
214 gtk_box_pack_start(GTK_BOX(vbox), this->priv->checkPreview, FALSE, FALSE, 5);
215
216 frame = gtk_frame_new(NULL);
217 gtk_widget_set_size_request(frame, 150, 150);
218 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
219 gtk_widget_set_vexpand(frame, FALSE);
220 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, FALSE, 0);
221 this->priv->image = gtk_image_new();
222 gtk_container_add(GTK_CONTAINER(frame), this->priv->image);
223 this->priv->boxDescr = gtk_hbox_new(FALSE, 0);
224 gtk_box_pack_start(GTK_BOX(vbox), this->priv->boxDescr, FALSE, FALSE, 0);
225
226 gtk_widget_show_all(vbox);
227
228 gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(this), vbox);
229 gtk_file_chooser_set_use_preview_label(GTK_FILE_CHOOSER(this), FALSE);
230 gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(this), TRUE);
231
232 g_signal_connect(this, "update-preview", G_CALLBACK(_updatePreview), (gpointer)0);
233
234 /* /\* The additional widgets. *\/ */
235
236 /* /\* Hiding mode button *\/ */
237 /* hbox = gtk_hbox_new(FALSE, 0); */
238 /* gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2); */
239 /* label = gtk_label_new(LABEL_SPIN_POLICY); */
240 /* gtk_widget_set_name(label, "label_head_2"); */
241 /* gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2); */
242 /* hiding_mode = createHidingModeRadioWidgets(); */
243 /* gtk_box_pack_start(GTK_BOX(hbox), hiding_mode, FALSE, FALSE, 2); */
244
245 gtk_widget_show_all(GTK_WIDGET(this));
246
247 return GTK_WIDGET(this);
248 }
249
_getDescr(VisuDataLoadable * previewData)250 static GtkWidget* _getDescr(VisuDataLoadable *previewData)
251 {
252 GtkWidget *table, *wd;
253 const gchar *comment;
254 gchar *text;
255 VisuNodeArrayIter iter;
256
257 /* We reset the flag of material. */
258 comment = visu_data_getDescription(VISU_DATA(previewData));
259 visu_node_array_iter_new(VISU_NODE_ARRAY(previewData), &iter);
260 table = gtk_grid_new();
261 tool_grid_resize(table, iter.nElements + 1, 2);
262 wd = gtk_label_new(_("<i>Box composition:</i>"));
263 gtk_label_set_use_markup(GTK_LABEL(wd), TRUE);
264 gtk_label_set_xalign(GTK_LABEL(wd), 0.);
265 gtk_widget_set_hexpand(wd, TRUE);
266 gtk_grid_attach(GTK_GRID(table), wd, 0, 0, 2, 1);
267 for (visu_node_array_iterStart(VISU_NODE_ARRAY(previewData), &iter); iter.element;
268 visu_node_array_iterNextElement(VISU_NODE_ARRAY(previewData), &iter, FALSE))
269 {
270 wd = gtk_label_new("");
271 text = g_markup_printf_escaped(_("<span size=\"small\"><b>%s:</b></span>"),
272 iter.element->name);
273 gtk_label_set_markup(GTK_LABEL(wd), text);
274 gtk_label_set_xalign(GTK_LABEL(wd), 1.);
275 gtk_widget_set_hexpand(wd, TRUE);
276 g_free(text);
277 gtk_grid_attach(GTK_GRID(table), wd, 0, iter.iElement + 1, 1, 1);
278 wd = gtk_label_new("");
279 if (iter.nStoredNodes > 1)
280 text = g_markup_printf_escaped
281 (_("<span size=\"small\">%d nodes</span>"),
282 iter.nStoredNodes);
283 else if (iter.nStoredNodes == 1)
284 text = g_strdup(_("<span size=\"small\">1 node</span>"));
285 else
286 text = g_strdup_printf("negative node number %d", iter.nStoredNodes);
287 gtk_label_set_markup(GTK_LABEL(wd), text);
288 gtk_label_set_xalign(GTK_LABEL(wd), 0.);
289 gtk_widget_set_hexpand(wd, TRUE);
290 g_free(text);
291 gtk_grid_attach(GTK_GRID(table), wd, 1, iter.iElement + 1, 1, 1);
292 }
293 if (comment && comment[0])
294 {
295 wd = gtk_label_new(_("<i>Description:</i>"));
296 gtk_label_set_use_markup(GTK_LABEL(wd), TRUE);
297 gtk_label_set_xalign(GTK_LABEL(wd), 0.);
298 gtk_widget_set_hexpand(wd, TRUE);
299 gtk_grid_attach(GTK_GRID(table), wd, 0, iter.nElements + 2, 2, 1);
300 wd = gtk_label_new("");
301 text = g_markup_printf_escaped("<span size=\"small\">%s</span>",
302 comment);
303 gtk_label_set_markup(GTK_LABEL(wd), text);
304 g_free(text);
305 gtk_label_set_xalign(GTK_LABEL(wd), 0.);
306 gtk_label_set_justify(GTK_LABEL(wd), GTK_JUSTIFY_FILL);
307 gtk_label_set_line_wrap(GTK_LABEL(wd), TRUE);
308 gtk_widget_set_size_request(wd, 150, -1);
309 gtk_widget_set_hexpand(wd, TRUE);
310 gtk_grid_attach(GTK_GRID(table), wd, 0, iter.nElements + 3, 2, 1);
311 }
312 gtk_widget_show_all(table);
313 return table;
314 }
315
_freeUChar(guchar * pixels,gpointer data _U_)316 static void _freeUChar(guchar *pixels, gpointer data _U_)
317 {
318 g_free(pixels);
319 }
_renderPreview(VisuUiDataChooser * this)320 static gboolean _renderPreview(VisuUiDataChooser *this)
321 {
322 GError *error;
323 gboolean valid;
324 VisuGlView *view;
325 VisuGlExtNodes *nodes;
326 VisuGlExtBox *box;
327 VisuGlExtSet *set;
328 GArray* image;
329 GdkPixbuf *pixbuf;
330 VisuDataLoadable *preview;
331
332 this->priv->worker = 0;
333
334 DBG_fprintf(stderr, "Gtk DataChooser: rendering preview.\n");
335 error = (GError*)0;
336 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(this->priv->comboMethod)))
337 {
338 case 0:
339 if (!this->priv->atomicFile)
340 return G_SOURCE_REMOVE;
341 preview = VISU_DATA_LOADABLE(visu_data_atomic_new(this->priv->atomicFile, this->priv->atomicFormat));
342 break;
343 case 1:
344 if (!this->priv->atomicFile || !this->priv->spinFile)
345 return G_SOURCE_REMOVE;
346 preview = VISU_DATA_LOADABLE(visu_data_spin_new(this->priv->atomicFile,
347 this->priv->spinFile,
348 (VisuDataLoader*)0,
349 (VisuDataLoader*)0));
350 break;
351 default:
352 preview = (VisuDataLoadable*)0;
353 break;
354 }
355 valid = visu_data_loadable_load(preview, 0, (GCancellable*)0, &error);
356 if (!valid)
357 {
358 if (preview)
359 g_object_unref(preview);
360 gtk_image_set_from_icon_name(GTK_IMAGE(this->priv->image),
361 "dialog-question", GTK_ICON_SIZE_DIALOG);
362 gtk_box_pack_start(GTK_BOX(this->priv->boxDescr),
363 gtk_label_new(_("Not a V_Sim file")), TRUE, FALSE, 0);
364 gtk_widget_show_all(this->priv->boxDescr);
365
366 return FALSE;
367 }
368 if (error)
369 {
370 if (preview)
371 g_object_unref(preview);
372 gtk_image_set_from_icon_name(GTK_IMAGE(this->priv->image),
373 "dialog-error", GTK_ICON_SIZE_DIALOG);
374 gtk_box_pack_start(GTK_BOX(this->priv->boxDescr),
375 gtk_label_new(_("This file has errors")), TRUE, FALSE, 0);
376 gtk_widget_show_all(this->priv->boxDescr);
377
378 return FALSE;
379 }
380
381 gtk_box_pack_start(GTK_BOX(this->priv->boxDescr),
382 _getDescr(preview), FALSE, FALSE, 0);
383
384 view = visu_gl_view_new_withSize((guint)150, (guint)150);
385 g_object_set(G_OBJECT(view), "auto-adjust", TRUE, NULL);
386 visu_boxed_setBox(VISU_BOXED(view), VISU_BOXED(preview));
387 /* Setup extensions for the preview. */
388 set = visu_gl_ext_set_new();
389 nodes = visu_gl_ext_nodes_new();
390 visu_gl_ext_set_add(set, VISU_GL_EXT(nodes));
391 g_object_unref(nodes);
392 visu_node_array_renderer_setNodeArray(VISU_NODE_ARRAY_RENDERER(nodes),
393 VISU_NODE_ARRAY(preview));
394 g_object_unref(preview);
395 box = visu_gl_ext_box_new("box preview");
396 visu_gl_ext_set_add(set, VISU_GL_EXT(box));
397 g_object_unref(box);
398 visu_gl_ext_box_setBox(box, visu_boxed_getBox(VISU_BOXED(preview)));
399 visu_gl_ext_set_setGlView(set, view);
400 g_object_unref(view);
401 image = visu_gl_ext_set_getPixmapData(set, 0, 0, FALSE);
402 g_object_unref(set);
403
404 pixbuf =
405 gdk_pixbuf_new_from_data((guchar*)image->data, GDK_COLORSPACE_RGB,
406 FALSE, 8, 150, 150, 3 * 150,
407 (GdkPixbufDestroyNotify)_freeUChar, (gpointer)0);
408 g_array_free(image, FALSE);
409 gtk_image_set_from_pixbuf(GTK_IMAGE(this->priv->image), pixbuf);
410 g_object_unref(pixbuf);
411
412 return FALSE;
413 }
414
_updatePreview(VisuUiDataChooser * this)415 static void _updatePreview(VisuUiDataChooser *this)
416 {
417 GList *lst, *child;
418
419 lst = gtk_container_get_children(GTK_CONTAINER(this->priv->boxDescr));
420 for (child = lst; child; child = g_list_next(child))
421 gtk_widget_destroy(GTK_WIDGET(child->data));
422 g_list_free(lst);
423 gtk_image_clear(GTK_IMAGE(this->priv->image));
424
425 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(this->priv->checkPreview)) ||
426 !_setFile(this))
427 return;
428
429 if (!this->priv->worker)
430 this->priv->worker = g_idle_add((GSourceFunc)_renderPreview, this);
431 }
432
_createFilter(GtkFileChooser * chooser,GList * list)433 static void _createFilter(GtkFileChooser *chooser, GList *list)
434 {
435 GtkFileFilter *filter, *filterAll;
436 const GList *tmpLst2, *tmpLst;
437 const char *name;
438
439 GSList *filters, *it;
440
441 filters = gtk_file_chooser_list_filters(chooser);
442 for (it = filters; it; it = g_slist_next(it))
443 gtk_file_chooser_remove_filter(chooser, GTK_FILE_FILTER(it->data));
444
445 filters = (GSList*)0;
446 filterAll = gtk_file_filter_new();
447 gtk_file_filter_set_name(filterAll, _("All supported formats"));
448 for (tmpLst = list; tmpLst; tmpLst = g_list_next(tmpLst))
449 {
450 filter = gtk_file_filter_new();
451 name = tool_file_format_getLabel(TOOL_FILE_FORMAT(tmpLst->data));
452 if (name)
453 gtk_file_filter_set_name(filter, name);
454 else
455 gtk_file_filter_set_name(filter, _("No description"));
456 for (tmpLst2 = tool_file_format_getFilePatterns(TOOL_FILE_FORMAT(tmpLst->data));
457 tmpLst2; tmpLst2 = g_list_next(tmpLst2))
458 {
459 gtk_file_filter_add_pattern(filter, (gchar*)tmpLst2->data);
460 gtk_file_filter_add_pattern(filterAll, (gchar*)tmpLst2->data);
461 }
462 g_object_set_data(G_OBJECT(filter), "_VisuDataLoader", tmpLst->data);
463 filters = g_slist_append(filters, (gpointer)filter);
464 }
465 filters = g_slist_append(filters, (gpointer)filterAll);
466 filter = gtk_file_filter_new();
467 gtk_file_filter_set_name(filter, _("All files"));
468 gtk_file_filter_add_pattern (filter, "*");
469 filters = g_slist_append(filters, (gpointer)filter);
470
471 for (it = filters; it; it = g_slist_next(it))
472 gtk_file_chooser_add_filter(chooser, GTK_FILE_FILTER(it->data));
473 gtk_file_chooser_set_filter(chooser, filterAll);
474
475 g_slist_free(filters);
476 }
477
_setSpinInput(VisuUiDataChooser * this)478 static void _setSpinInput(VisuUiDataChooser *this)
479 {
480 if (gtk_combo_box_get_active(GTK_COMBO_BOX(this->priv->comboMethod)) != 1)
481 return;
482
483 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(this->priv->checkAtomic)))
484 _createFilter(GTK_FILE_CHOOSER(this), visu_data_atomic_class_getLoaders());
485 else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(this->priv->checkSpin)))
486 _createFilter(GTK_FILE_CHOOSER(this), visu_data_spin_class_getLoaders());
487 }
488
_setMethod(VisuUiDataChooser * this)489 static void _setMethod(VisuUiDataChooser *this)
490 {
491 GList *lst, *child;
492 GtkWidget *table;
493
494 g_free(this->priv->atomicFile);
495 this->priv->atomicFile = (gchar*)0;
496 g_free(this->priv->spinFile);
497 this->priv->spinFile = (gchar*)0;
498
499 lst = gtk_container_get_children(GTK_CONTAINER(this->priv->boxMethod));
500 for (child = lst; child; child = g_list_next(child))
501 gtk_widget_destroy(GTK_WIDGET(child->data));
502
503 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(this->priv->comboMethod)))
504 {
505 case 0:
506 _createFilter(GTK_FILE_CHOOSER(this), visu_data_atomic_class_getLoaders());
507 break;
508 case 1:
509 /* The table for the two file types selections (spin & position). */
510 table = gtk_grid_new();
511 tool_grid_resize(table, 2, 4);
512 gtk_box_pack_start(GTK_BOX(this->priv->boxMethod), table, TRUE, TRUE, 2);
513
514 /* Position button. */
515 this->priv->checkAtomic = gtk_radio_button_new_with_label(NULL, _("Positions:"));
516 gtk_grid_attach(GTK_GRID(table), this->priv->checkAtomic, 0, 0, 1, 1);
517 g_signal_connect_swapped(this->priv->checkAtomic, "toggled",
518 G_CALLBACK(_setSpinInput), this);
519
520 /* Spin button */
521 this->priv->checkSpin = gtk_radio_button_new_with_label_from_widget
522 (GTK_RADIO_BUTTON(this->priv->checkAtomic), _("Spins:"));
523 gtk_grid_attach(GTK_GRID(table), this->priv->checkSpin, 0, 1, 1, 1);
524 g_signal_connect_swapped(this->priv->checkSpin, "toggled",
525 G_CALLBACK(_setSpinInput), this);
526
527 this->priv->labelPosition = gtk_label_new(_("None"));
528 gtk_widget_set_hexpand(this->priv->labelPosition, TRUE);
529 gtk_label_set_xalign(GTK_LABEL(this->priv->labelPosition), 0.);
530 gtk_widget_set_margin_start(this->priv->labelPosition, 10);
531 gtk_grid_attach(GTK_GRID(table), this->priv->labelPosition, 3, 0, 1, 1);
532
533 this->priv->labelSpin = gtk_label_new(_("None"));
534 gtk_widget_set_hexpand(this->priv->labelSpin, TRUE);
535 gtk_label_set_xalign(GTK_LABEL(this->priv->labelSpin), 0.);
536 gtk_widget_set_margin_start(this->priv->labelSpin, 10);
537 gtk_grid_attach(GTK_GRID(table), this->priv->labelSpin, 3, 1, 1, 1);
538
539 gtk_widget_show_all(table);
540
541 _setSpinInput(this);
542 break;
543 default:
544 break;
545 }
546 }
547
_setFile(VisuUiDataChooser * this)548 static gboolean _setFile(VisuUiDataChooser *this)
549 {
550 gchar *filename;
551 VisuDataLoader *format;
552
553 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(this));
554 format = VISU_DATA_LOADER(g_object_get_data(G_OBJECT(gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(this))), "_VisuDataLoader"));
555
556 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(this->priv->comboMethod)))
557 {
558 case 0:
559 g_free(this->priv->atomicFile);
560 this->priv->atomicFile = filename;
561 this->priv->atomicFormat = format;
562 return TRUE;
563 case 1:
564 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(this->priv->checkAtomic)))
565 {
566 g_free(this->priv->atomicFile);
567 this->priv->atomicFile = filename;
568 this->priv->atomicFormat = format;
569 if (filename)
570 gtk_label_set_text(GTK_LABEL(this->priv->labelPosition), filename);
571 else
572 gtk_label_set_text(GTK_LABEL(this->priv->labelPosition), _("None"));
573 }
574 else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(this->priv->checkSpin)))
575 {
576 g_free(this->priv->spinFile);
577 this->priv->spinFile = filename;
578 this->priv->spinFormat = format;
579 if (filename)
580 gtk_label_set_text(GTK_LABEL(this->priv->labelSpin), filename);
581 else
582 gtk_label_set_text(GTK_LABEL(this->priv->labelSpin), _("None"));
583 }
584 return this->priv->atomicFile && this->priv->spinFile;
585 default:
586 break;
587 }
588 return FALSE;
589 }
590
591 /**
592 * visu_ui_data_chooser_run:
593 * @this: a #VisuUiDataChooser object.
594 *
595 * Runs a file dialog chooser to select a #VisuDataLoadable file.
596 *
597 * Since: 3.8
598 *
599 * Returns: (transfer full): a newly created #VisuDataLoadable object.
600 **/
visu_ui_data_chooser_run(VisuUiDataChooser * this)601 VisuDataLoadable* visu_ui_data_chooser_run(VisuUiDataChooser *this)
602 {
603 gint status;
604
605 do
606 {
607 status = gtk_dialog_run(GTK_DIALOG(this));
608 if (status != GTK_RESPONSE_OK)
609 return (VisuDataLoadable*)0;
610
611 } while (!_setFile(this));
612
613 switch (gtk_combo_box_get_active(GTK_COMBO_BOX(this->priv->comboMethod)))
614 {
615 case 0:
616 return VISU_DATA_LOADABLE(visu_data_atomic_new(this->priv->atomicFile,
617 this->priv->atomicFormat));
618 case 1:
619 return VISU_DATA_LOADABLE(visu_data_spin_new(this->priv->atomicFile,
620 this->priv->spinFile,
621 this->priv->atomicFormat,
622 this->priv->spinFormat));
623 default:
624 break;
625 }
626 return (VisuDataLoadable*)0;
627 }
628
exportParameters(GString * data,VisuData * dataObj _U_)629 static void exportParameters(GString *data, VisuData *dataObj _U_)
630 {
631 g_string_append_printf(data, "# %s\n", DESC_PARAMETER_PREVIEW);
632 g_string_append_printf(data, "%s[gtk]: %d\n\n", FLAG_PARAMETER_PREVIEW,
633 usePreview);
634 }
635