1 /*   EXTRAITS DE LA LICENCE
2 	Copyright CEA, contributeurs : Luc BILLARD et Damien
3 	CALISTE, laboratoire L_Sim, (2001-2005)
4 
5 	Adresse mèl :
6 	BILLARD, non joignable par mèl ;
7 	CALISTE, damien P caliste AT cea P fr.
8 
9 	Ce logiciel est un programme informatique servant à visualiser des
10 	structures atomiques dans un rendu pseudo-3D.
11 
12 	Ce logiciel est régi par la licence CeCILL soumise au droit français et
13 	respectant les principes de diffusion des logiciels libres. Vous pouvez
14 	utiliser, modifier et/ou redistribuer ce programme sous les conditions
15 	de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
16 	sur le site "http://www.cecill.info".
17 
18 	Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
19 	pris connaissance de la licence CeCILL, et que vous en avez accepté les
20 	termes (cf. le fichier Documentation/licence.fr.txt fourni avec ce logiciel).
21 */
22 
23 /*   LICENCE SUM UP
24 	Copyright CEA, contributors : Luc BILLARD et Damien
25 	CALISTE, laboratoire L_Sim, (2001-2005)
26 
27 	E-mail address:
28 	BILLARD, not reachable any more ;
29 	CALISTE, damien P caliste AT cea P fr.
30 
31 	This software is a computer program whose purpose is to visualize atomic
32 	configurations in 3D.
33 
34 	This software is governed by the CeCILL  license under French law and
35 	abiding by the rules of distribution of free software.  You can  use,
36 	modify and/ or redistribute the software under the terms of the CeCILL
37 	license as circulated by CEA, CNRS and INRIA at the following URL
38 	"http://www.cecill.info".
39 
40 	The fact that you are presently reading this means that you have had
41 	knowledge of the CeCILL license and that you accept its terms. You can
42 	find a copy of this licence shipped with this software at Documentation/licence.en.txt.
43 */
44 #include <gtk/gtk.h>
45 
46 #include <visu_gtk.h>
47 #include <gtk_main.h>
48 #include "gtk_dumpDialogWidget.h"
49 #include <support.h>
50 #include <dumpModules/fileDump.h>
51 #include <dumpModules/glDump.h>
52 
53 /**
54  * SECTION:gtk_dumpDialogWidget
55  * @short_description: Defines a widget to export into different file
56  * formats.
57  *
58  * <para>This widget is based on the #GtkFileChooser in the save
59  * mode. It proposes the user to choose a file to save to. In
60  * addition, it automatically build a list of filters, corresponding
61  * to the available export routines in V_Sim. By default, the filter
62  * is set on 'auto', which means that the filter method is selected
63  * with the file extension. The dialog also has a progress bar.</para>
64  *
65  * <para>This widget is also a dialog, and should be used with
66  * gtk_dialog_run(). After the response GTK_RESPONSE_ACCEPT has been
67  * recieved, one can grep the selected filename with
68  * visu_ui_dump_dialog_getFilename(). The dialog does not call the exporting
69  * routine by itself, the calling method should take care of
70  * that. When doing it, the filechoosing part should be made
71  * insensitive, using visu_ui_dump_dialog_start() and the progress bar should be
72  * updated accordingly (get it with
73  * visu_ui_dump_dialog_getProgressBar()).</para>
74  *
75  * <para>The user interface propose also to change the size  (see
76  * visu_ui_dump_dialog_getHeight() and visu_ui_dump_dialog_getWidth()) and if
77  * some options are associated to a file format, these options are
78  * displayed.</para>
79  */
80 
81 static void visu_ui_dump_dialog_dispose (GObject *obj);
82 static void visu_ui_dump_dialog_finalize(GObject *obj);
83 
84 struct _VisuUiDumpDialog
85 {
86   GtkDialog dialog;
87 
88   GtkWidget *fileChooser;
89 
90   GtkWidget *hBoxOptions;
91   GtkWidget *comboType;
92   VisuDump  *selectedToolFileFormat;
93   GtkWidget *expanderToolFileFormat;
94   GtkWidget *checkFileExtension;
95   GtkWidget *spinWidth, *spinHeight;
96 
97   GtkWidget *infoBar;
98   GtkWidget *progressBar;
99   GtkWidget *cancelButton;
100 
101   gchar     *dumpFileName;
102 
103   VisuData  *dataObj;
104 
105   /* Memory gestion. */
106   gboolean dispose_has_run;
107 };
108 
109 struct _VisuUiDumpDialogClass
110 {
111   GtkDialogClass parent_class;
112 
113   guint width, height;
114   gchar *current_dir;
115 
116   guint formatId;
117 
118   void (*dumpDialog) (VisuUiDumpDialog *dump);
119 };
120 
121 /* Local callbacks */
122 static void onWidthHeightChanged(GtkSpinButton *spin, gpointer data);
123 static void onSpinPropertyChange(GtkSpinButton *spin, gpointer data);
124 static void onCheckPropertyChange(GtkToggleButton *toggle, gpointer data);
125 static void onComboToolFileFormatChange(GtkComboBox *combo, gpointer data);
126 static void onVisuUiDumpDialogResponse(GtkDialog *dialog, gint id, gpointer *data);
127 
G_DEFINE_TYPE(VisuUiDumpDialog,visu_ui_dump_dialog,GTK_TYPE_DIALOG)128 G_DEFINE_TYPE(VisuUiDumpDialog, visu_ui_dump_dialog, GTK_TYPE_DIALOG)
129 
130 static void visu_ui_dump_dialog_class_init(VisuUiDumpDialogClass *klass)
131 {
132   DBG_fprintf(stderr, "Gtk VisuUiDumpDialog: creating the class of the widget.\n");
133 
134   klass->width  = 0;
135   klass->height = 0;
136   klass->current_dir = (gchar*)0;
137   klass->formatId = 0;
138 
139   G_OBJECT_CLASS(klass)->dispose = visu_ui_dump_dialog_dispose;
140   G_OBJECT_CLASS(klass)->finalize = visu_ui_dump_dialog_finalize;
141 }
142 
visu_ui_dump_dialog_init(VisuUiDumpDialog * dumpDialog)143 static void visu_ui_dump_dialog_init(VisuUiDumpDialog *dumpDialog)
144 {
145   DBG_fprintf(stderr, "Gtk VisuUiDumpDialog: initializing new object (%p).\n",
146 	      (gpointer)dumpDialog);
147 
148   dumpDialog->selectedToolFileFormat = (VisuDump*)0;
149   dumpDialog->dumpFileName = (gchar*)0;
150   dumpDialog->dataObj = (VisuData*)0;
151 
152   g_signal_connect(G_OBJECT(dumpDialog), "response",
153 		   G_CALLBACK(onVisuUiDumpDialogResponse), (gpointer)dumpDialog);
154 }
155 
visu_ui_dump_dialog_dispose(GObject * obj)156 static void visu_ui_dump_dialog_dispose(GObject *obj)
157 {
158   DBG_fprintf(stderr, "Gtk VisuUiDumpDialog: dispose object %p.\n", (gpointer)obj);
159 
160   if (VISU_UI_DUMP_DIALOG(obj)->dispose_has_run)
161     return;
162 
163   VISU_UI_DUMP_DIALOG(obj)->dispose_has_run = TRUE;
164   /* Chain up to the parent class */
165   G_OBJECT_CLASS(visu_ui_dump_dialog_parent_class)->dispose(obj);
166 }
visu_ui_dump_dialog_finalize(GObject * obj)167 static void visu_ui_dump_dialog_finalize(GObject *obj)
168 {
169   VisuUiDumpDialog *dialog;
170 
171   g_return_if_fail(obj);
172 
173   DBG_fprintf(stderr, "Gtk VisuUiDumpDialog: finalize object %p.\n", (gpointer)obj);
174 
175   dialog = VISU_UI_DUMP_DIALOG(obj);
176   if (dialog->dumpFileName)
177     /* Free the stored filename. */
178     g_free(dialog->dumpFileName);
179 
180   /* Chain up to the parent class */
181   G_OBJECT_CLASS(visu_ui_dump_dialog_parent_class)->finalize(obj);
182 
183   DBG_fprintf(stderr, "Gtk VisuUiDumpDialog: freeing ... OK.\n");
184 }
185 
186 /**
187  * visu_ui_dump_dialog_new :
188  * @dataObj: (allow-none): a #VisuData object (can be NULL) ;
189  * @parent: (allow-none): the parent window ;
190  * @suggestedFilename: (allow-none): a string or NULL.
191  * @suggestedWidth: a positive suggested width for exportation or a
192  * negative value to get the default.
193  * @suggestedHeight: idem for height.
194  *
195  * A #VisuUiDumpDialog widget is complete dialog window widget, but it is already
196  * prepared for dumping, proposing known file formats. It is usefull to get
197  * an filename to export to. It has also a progress bar that can illustrate
198  * the process. The given @dataObj argument is used to initialize some
199  * values related to the data to be dumped.
200  *
201  * Returns: a newly created #VisuUiDumpDialog widget.
202  */
visu_ui_dump_dialog_new(VisuData * dataObj,GtkWindow * parent,const gchar * suggestedFilename,gint suggestedWidth,gint suggestedHeight)203 GtkWidget* visu_ui_dump_dialog_new(VisuData *dataObj, GtkWindow *parent,
204                                    const gchar *suggestedFilename,
205                                    gint suggestedWidth, gint suggestedHeight)
206 {
207   VisuUiDumpDialog *dumpDialog;
208   VisuUiDumpDialogClass *klass;
209   const gchar *directory;
210   const gchar *filename, *labelType;
211   GList *format;
212   GtkWidget *hbox2, *hbox;
213   GtkWidget *label;
214   GtkWidget *wd;
215   GtkWidget *vbox;
216 
217   if (!parent)
218     parent = visu_ui_getRenderWindow();
219 
220   DBG_fprintf(stderr, "Gtk VisuUiDumpDialog: creating a new VisuUiDumpDialog object.\n");
221 
222   dumpDialog = VISU_UI_DUMP_DIALOG(g_object_new(VISU_TYPE_UI_DUMP_DIALOG, NULL));
223   gtk_window_set_title(GTK_WINDOW(dumpDialog),
224 		       _("Export to a file (image, atomic structures...)"));
225   klass = VISU_UI_DUMP_DIALOG_CLASS(G_OBJECT_GET_CLASS(dumpDialog));
226   /* This is to avoid a bug in gtk 2.4 */
227 #if GTK_MAJOR_VERSION > 2 || GTK_MINOR_VERSION > 5
228   gtk_window_set_modal(GTK_WINDOW(dumpDialog), TRUE);
229 #endif
230   gtk_window_set_transient_for(GTK_WINDOW(dumpDialog), GTK_WINDOW(parent));
231   gtk_window_set_position(GTK_WINDOW(dumpDialog), GTK_WIN_POS_CENTER_ON_PARENT);
232 
233   dumpDialog->cancelButton = gtk_dialog_add_button(GTK_DIALOG(dumpDialog),
234                                                    TOOL_ICON_CANCEL, GTK_RESPONSE_CANCEL);
235   gtk_dialog_add_button(GTK_DIALOG(dumpDialog), TOOL_ICON_SAVE, GTK_RESPONSE_ACCEPT);
236   gtk_dialog_set_default_response(GTK_DIALOG(dumpDialog), GTK_RESPONSE_ACCEPT);
237 
238   /* Create the file chooser part. */
239   dumpDialog->fileChooser = gtk_file_chooser_widget_new(GTK_FILE_CHOOSER_ACTION_SAVE);
240   gtk_widget_set_size_request(dumpDialog->fileChooser, -1, 350);
241 #if GTK_MAJOR_VERSION > 2 || GTK_MINOR_VERSION > 7
242   gtk_file_chooser_set_do_overwrite_confirmation
243     (GTK_FILE_CHOOSER(dumpDialog->fileChooser), TRUE);
244 #endif
245   gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dumpDialog))),
246 		     dumpDialog->fileChooser, TRUE, TRUE, 2);
247   gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dumpDialog->fileChooser),
248 				       FALSE);
249   /* We set the suggested filename, either a previous one
250      or the one given. */
251   filename = (const gchar*)0;
252   dumpDialog->dataObj = dataObj;
253   if (dataObj)
254     filename = (const gchar*)g_object_get_data(G_OBJECT(dataObj),
255 					       "visu_ui_dump_dialog_filename");
256   if (!filename)
257     filename = suggestedFilename;
258   if (filename)
259     gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dumpDialog->fileChooser),
260 				      filename);
261 
262   /* Create the file options part. */
263   dumpDialog->hBoxOptions = gtk_hbox_new(FALSE, 0);
264   gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(dumpDialog->fileChooser),
265 				    dumpDialog->hBoxOptions);
266 
267   vbox = gtk_vbox_new(FALSE, 0);
268   gtk_box_pack_start(GTK_BOX(dumpDialog->hBoxOptions), vbox, TRUE, TRUE, 2);
269   hbox = gtk_hbox_new(FALSE, 0);
270   gtk_box_pack_start(GTK_BOX(vbox),
271 		     hbox, FALSE, FALSE, 0);
272   /* Label to introduce the combobox which allow to choose the format */
273   label = gtk_label_new(_("Choose the file format : "));
274   gtk_label_set_xalign(GTK_LABEL(label), 0.);
275   gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
276   dumpDialog->comboType = gtk_combo_box_text_new();
277   /* Set the combo entry that let V_Sim detect the desired format through the extension. */
278   gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(dumpDialog->comboType),
279                             (const gchar*)0, _("Autodetect format"));
280   gtk_box_pack_start(GTK_BOX(hbox), dumpDialog->comboType, FALSE, FALSE, 0);
281   /* Add an expander for file format options. */
282   dumpDialog->expanderToolFileFormat = gtk_expander_new(_("File format option:"));
283   gtk_widget_set_sensitive(dumpDialog->expanderToolFileFormat, FALSE);
284   gtk_box_pack_start(GTK_BOX(vbox),
285 		     dumpDialog->expanderToolFileFormat, FALSE, FALSE, 0);
286   g_signal_connect(G_OBJECT(dumpDialog->comboType), "changed",
287 		   G_CALLBACK(onComboToolFileFormatChange), (gpointer)dumpDialog);
288   /* Add a separator. */
289   wd = gtk_vseparator_new();
290   gtk_box_pack_start(GTK_BOX(dumpDialog->hBoxOptions),
291 		     wd, FALSE, FALSE, 0);
292   /* Create common options part. */
293   vbox = gtk_vbox_new(FALSE, 0);
294   gtk_box_pack_start(GTK_BOX(dumpDialog->hBoxOptions), vbox, TRUE, TRUE, 2);
295   dumpDialog->checkFileExtension = gtk_check_button_new_with_label(_("Add extension"));
296   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dumpDialog->checkFileExtension), TRUE);
297   gtk_widget_set_sensitive(dumpDialog->checkFileExtension, FALSE);
298   gtk_box_pack_start(GTK_BOX(vbox), dumpDialog->checkFileExtension, FALSE, FALSE, 0);
299   hbox = gtk_hbox_new(FALSE, 0);
300   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
301   label = gtk_label_new(_("Width: "));
302   gtk_label_set_xalign(GTK_LABEL(label), 0.);
303   gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
304   dumpDialog->spinWidth = gtk_spin_button_new_with_range(1., 2000., 1.);
305   if (klass->width > 0)
306     gtk_spin_button_set_value(GTK_SPIN_BUTTON(dumpDialog->spinWidth),
307 			      (gdouble)klass->width);
308   else if (suggestedWidth > 0)
309     gtk_spin_button_set_value(GTK_SPIN_BUTTON(dumpDialog->spinWidth),
310 			      (gdouble)suggestedWidth);
311   gtk_box_pack_start(GTK_BOX(hbox), dumpDialog->spinWidth, FALSE, FALSE, 0);
312   label = gtk_label_new(_("px"));
313   gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
314   hbox = gtk_hbox_new(FALSE, 0);
315   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
316   label = gtk_label_new(_("Height: "));
317   gtk_label_set_xalign(GTK_LABEL(label), 0.);
318   gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
319   dumpDialog->spinHeight = gtk_spin_button_new_with_range(1., 2000., 1.);
320   if (klass->height > 0)
321     gtk_spin_button_set_value(GTK_SPIN_BUTTON(dumpDialog->spinHeight),
322 			      (gdouble)klass->height);
323   else if (suggestedHeight > 0)
324     gtk_spin_button_set_value(GTK_SPIN_BUTTON(dumpDialog->spinHeight),
325 			      (gdouble)suggestedHeight);
326   gtk_box_pack_start(GTK_BOX(hbox), dumpDialog->spinHeight, FALSE, FALSE, 0);
327   label = gtk_label_new(_("px"));
328   gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
329   g_signal_connect(G_OBJECT(dumpDialog->spinWidth), "value-changed",
330 		   G_CALLBACK(onWidthHeightChanged), (gpointer)&klass->width);
331   g_signal_connect(G_OBJECT(dumpDialog->spinHeight), "value-changed",
332 		   G_CALLBACK(onWidthHeightChanged), (gpointer)&klass->height);
333 
334 
335   /* Create the progress bar part. */
336   hbox2 = gtk_hbox_new(FALSE, 0);
337   gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dumpDialog))),
338 		     hbox2, FALSE, FALSE, 2);
339   /* Label to introduce the progress bar */
340   label = gtk_label_new(_("Dump progress : "));
341   gtk_label_set_xalign(GTK_LABEL(label), 0.);
342   gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
343   dumpDialog->progressBar = gtk_progress_bar_new();
344   gtk_box_pack_start(GTK_BOX(hbox2), dumpDialog->progressBar, TRUE, TRUE, 2);
345 
346   /* Add an info bar for warning and so on. */
347 #if GTK_MAJOR_VERSION > 2 || GTK_MINOR_VERSION > 17
348   dumpDialog->infoBar = gtk_info_bar_new();
349   gtk_widget_set_no_show_all(dumpDialog->infoBar, TRUE);
350   gtk_info_bar_set_message_type(GTK_INFO_BAR(dumpDialog->infoBar),
351                                 GTK_MESSAGE_WARNING);
352   label = gtk_label_new(_("Current box has translations applied,"
353                           " do you want to proceed to exportation anyway?"));
354   gtk_widget_show(label);
355   gtk_container_add
356     (GTK_CONTAINER(gtk_info_bar_get_content_area(GTK_INFO_BAR(dumpDialog->infoBar))),
357      label);
358   gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dumpDialog))),
359 		     dumpDialog->infoBar, FALSE, FALSE, 2);
360 #endif
361 
362   /* Setting default values. */
363   gtk_widget_set_name(GTK_WIDGET(dumpDialog), "filesel");
364   directory = visu_ui_main_getLastOpenDirectory(visu_ui_main_class_getCurrentPanel());
365   if (klass->current_dir)
366     gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dumpDialog->fileChooser),
367 					klass->current_dir);
368   else if (directory)
369     gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dumpDialog->fileChooser),
370 					directory);
371   for (format = visu_dump_pool_getAllModules(); format; format = g_list_next(format))
372     {
373       labelType = tool_file_format_getLabel(TOOL_FILE_FORMAT(format->data));
374       if (labelType)
375 	gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(dumpDialog->comboType),
376                                   (const gchar*)0, labelType);
377     }
378   gtk_combo_box_set_active(GTK_COMBO_BOX(dumpDialog->comboType), klass->formatId);
379 
380   gtk_widget_show_all(GTK_WIDGET(dumpDialog));
381   return GTK_WIDGET(dumpDialog);
382 }
383 
384 
385 /*******************/
386 /* Local callbacks */
387 /*******************/
onSpinPropertyChange(GtkSpinButton * spin,gpointer data)388 static void onSpinPropertyChange(GtkSpinButton *spin, gpointer data)
389 {
390   GValue *val;
391 
392   val = (GValue*)data;
393   g_value_set_int(val, (int)gtk_spin_button_get_value(spin));
394   DBG_fprintf(stderr, "Gtk VisuUiDumpDialog: set property spin to %d.\n",
395               g_value_get_int(val));
396 }
onCheckPropertyChange(GtkToggleButton * toggle,gpointer data)397 static void onCheckPropertyChange(GtkToggleButton *toggle, gpointer data)
398 {
399   GValue *val;
400 
401   val = (GValue*)data;
402   g_value_set_boolean(val, gtk_toggle_button_get_active(toggle));
403   DBG_fprintf(stderr, "Gtk VisuUiDumpDialog: set property check to %d.\n",
404               g_value_get_boolean(val));
405 }
onComboToolFileFormatChange(GtkComboBox * combo,gpointer data)406 static void onComboToolFileFormatChange(GtkComboBox *combo, gpointer data)
407 {
408   int formatInt, i;
409   GList *dumpTypes;
410   ToolFileFormatIter iter;
411   GtkWidget *wd, *label, *hbox, *vbox;
412 
413   g_return_if_fail(VISU_IS_UI_DUMP_DIALOG(data));
414 
415   /* Empty the expander for properties. */
416   wd = gtk_bin_get_child(GTK_BIN(VISU_UI_DUMP_DIALOG(data)->expanderToolFileFormat));
417   if (wd)
418     gtk_widget_destroy(wd);
419 
420   dumpTypes = visu_dump_pool_getAllModules();
421   formatInt = gtk_combo_box_get_active(combo);
422   VISU_UI_DUMP_DIALOG_GET_CLASS(data)->formatId = (guint)formatInt;
423   DBG_fprintf(stderr, "Gtk VisuUiDumpDialog: On file format change (%d).\n", formatInt);
424   /* Select auto file format -> no properties. */
425   if (formatInt == 0)
426     {
427       gtk_widget_set_sensitive(VISU_UI_DUMP_DIALOG(data)->expanderToolFileFormat, FALSE);
428       gtk_widget_set_sensitive(VISU_UI_DUMP_DIALOG(data)->checkFileExtension, FALSE);
429       return;
430     }
431   else
432     /* Search for the selected property. */
433     for(i = 0; i < formatInt - 1; i++) dumpTypes = g_list_next(dumpTypes);
434   /* Set the check box for extension auto completion. */
435   gtk_widget_set_sensitive(VISU_UI_DUMP_DIALOG(data)->checkFileExtension, TRUE);
436   /* Get properties if exist for this format. */
437   iter.lst = (GList*)0;
438   tool_file_format_iterNextProperty(TOOL_FILE_FORMAT(dumpTypes->data), &iter);
439   if (!iter.lst)
440     {
441       gtk_widget_set_sensitive(VISU_UI_DUMP_DIALOG(data)->expanderToolFileFormat, FALSE);
442       return;
443     }
444   gtk_widget_set_sensitive(VISU_UI_DUMP_DIALOG(data)->expanderToolFileFormat, TRUE);
445   vbox = gtk_vbox_new(FALSE, 0);
446   gtk_container_add(GTK_CONTAINER(VISU_UI_DUMP_DIALOG(data)->expanderToolFileFormat), vbox);
447   iter.lst = (GList*)0;
448   for (tool_file_format_iterNextProperty(TOOL_FILE_FORMAT(dumpTypes->data), &iter); iter.lst;
449        tool_file_format_iterNextProperty(TOOL_FILE_FORMAT(dumpTypes->data), &iter))
450     {
451       hbox = gtk_hbox_new(FALSE, 0);
452       gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
453       label = gtk_label_new(iter.label);
454       gtk_label_set_xalign(GTK_LABEL(label), 1.);
455       gtk_widget_set_margin_start(label, 10);
456       gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
457       switch (G_VALUE_TYPE(iter.val))
458 	{
459 	case G_TYPE_INT:
460 	  wd = gtk_spin_button_new_with_range(0., 100., 1.);
461 	  gtk_spin_button_set_value(GTK_SPIN_BUTTON(wd), (gdouble)g_value_get_int(iter.val));
462 	  gtk_box_pack_start(GTK_BOX(hbox), wd, FALSE, FALSE, 0);
463 	  g_signal_connect(G_OBJECT(wd), "value-changed",
464 			   G_CALLBACK(onSpinPropertyChange), iter.val);
465 	  break;
466 	case G_TYPE_BOOLEAN:
467 	  wd = gtk_check_button_new();
468 	  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wd), g_value_get_boolean(iter.val));
469 	  gtk_box_pack_start(GTK_BOX(hbox), wd, FALSE, FALSE, 0);
470 	  g_signal_connect(G_OBJECT(wd), "toggled",
471 			   G_CALLBACK(onCheckPropertyChange), iter.val);
472 	  break;
473 	default:
474 	  g_warning("Unknown, or nsupprted file format property"
475 		    " given to 'onComboToolFileFormatChange'.");
476 	};
477     }
478   gtk_widget_show_all(vbox);
479   /* Expand the option expander. */
480   gtk_expander_set_expanded(GTK_EXPANDER(VISU_UI_DUMP_DIALOG(data)->expanderToolFileFormat), TRUE);
481 }
onVisuUiDumpDialogResponse(GtkDialog * dialog,gint id,gpointer * data)482 static void onVisuUiDumpDialogResponse(GtkDialog *dialog, gint id, gpointer *data)
483 {
484   gchar *filename;
485   int formatInt;
486   gchar *ext, *pattern;
487   GList *dumpTypes;
488   VisuUiDumpDialog *dumpDialog;
489   VisuUiDumpDialogClass *klass;
490 
491   g_return_if_fail(VISU_IS_UI_DUMP_DIALOG(data));
492 
493   dumpDialog = VISU_UI_DUMP_DIALOG(data);
494 
495   DBG_fprintf(stderr, "Gtk VisuUiDumpDialog: catch the 'response' signal:"
496 	      " %d (ACCEPT is %d).\n", id, GTK_RESPONSE_ACCEPT);
497   /* Get the filename. */
498   filename = (gchar*)0;
499   formatInt = -1;
500   if (id == GTK_RESPONSE_ACCEPT)
501     {
502       filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dumpDialog->fileChooser));
503       formatInt = gtk_combo_box_get_active(GTK_COMBO_BOX(dumpDialog->comboType));
504       if (!filename)
505 	{
506 	  /* Autodetect failed, no format match the given filename */
507 	  visu_ui_raiseWarning(_("Saving a file"),
508 			       _("No filename chosen."),
509 			       GTK_WINDOW(dialog));
510 	  g_signal_stop_emission_by_name(G_OBJECT(dumpDialog), "response");
511 	  return;
512 	}
513     }
514 
515   if (formatInt >= 0)
516     {
517       dumpTypes = visu_dump_pool_getAllModules();
518       if (formatInt == 0)
519 	/* The automatic format has been selected, we look in the pattern list to
520 	   find a matching pattern. */
521 	while (dumpTypes && !tool_file_format_match
522                (TOOL_FILE_FORMAT(dumpTypes->data), filename))
523 	  dumpTypes = g_list_next(dumpTypes);
524       else
525         dumpTypes = g_list_nth(dumpTypes, formatInt - 1);
526       if (!dumpTypes)
527 	{
528 	  /* Autodetect failed, no format match the given filename */
529 	  visu_ui_raiseWarning(_("Saving a file"),
530 			       _("The filename doesn't match any known format."),
531 			       GTK_WINDOW(dialog));
532 	  g_free(filename);
533 	  g_signal_stop_emission_by_name(G_OBJECT(dumpDialog), "response");
534 	  return;
535 	}
536       DBG_fprintf(stderr, "Gtk VisuUiDumpDialog: export to dump %p.\n", dumpTypes->data);
537 
538       /* Special warning for non bitmap exportation with translations. */
539 #if GTK_MAJOR_VERSION > 2 || GTK_MINOR_VERSION > 17
540       if (VISU_IS_DUMP_DATA(dumpTypes->data) &&
541           visu_pointset_getTranslationPeriodicStatus(VISU_POINTSET(dumpDialog->dataObj)) &&
542           !gtk_widget_get_visible(dumpDialog->infoBar))
543         {
544           gtk_widget_show(dumpDialog->infoBar);
545 	  g_free(filename);
546 	  g_signal_stop_emission_by_name(G_OBJECT(dumpDialog), "response");
547 	  return;
548         }
549 #endif
550 
551       if (formatInt > 0 &&
552 	  gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dumpDialog->checkFileExtension)))
553 	{
554 	  if (tool_file_format_canMatch(TOOL_FILE_FORMAT(dumpTypes->data)) &&
555               !tool_file_format_match(TOOL_FILE_FORMAT(dumpTypes->data), filename))
556 	    {
557 	      pattern = (gchar*) tool_file_format_getFilePatterns
558                 (TOOL_FILE_FORMAT(dumpTypes->data))->data;
559 	      ext = g_strrstr(pattern, ".");
560 	      dumpDialog->dumpFileName = g_strdup_printf("%s%s", filename, ext);
561 	      g_free(filename);
562 	    }
563 	  else
564 	    dumpDialog->dumpFileName = filename;
565 	}
566       else
567 	dumpDialog->dumpFileName = filename;
568       dumpDialog->selectedToolFileFormat = VISU_DUMP(dumpTypes->data);
569       DBG_fprintf(stderr, "Gtk VisuUiDumpDialog: '%s' file format chosen.\n",
570 		  tool_file_format_getName(TOOL_FILE_FORMAT(dumpDialog->selectedToolFileFormat)));
571       /* Save the filename in a property of the VisuData object. */
572       filename = g_path_get_basename(dumpDialog->dumpFileName);
573       g_object_set_data_full(G_OBJECT(dumpDialog->dataObj), "visu_ui_dump_dialog_filename",
574 			     (gpointer)filename, g_free);
575 
576       /* Save the dirname in the class. */
577       klass = VISU_UI_DUMP_DIALOG_CLASS(G_OBJECT_GET_CLASS(dumpDialog));
578       if (klass->current_dir)
579 	g_free(klass->current_dir);
580       klass->current_dir = g_path_get_dirname(dumpDialog->dumpFileName);
581     }
582 }
onWidthHeightChanged(GtkSpinButton * spin,gpointer data)583 static void onWidthHeightChanged(GtkSpinButton *spin, gpointer data)
584 {
585   *(guint*)data = (guint)gtk_spin_button_get_value(spin);
586 }
587 
588 /******************/
589 /* Public methods */
590 /******************/
visu_ui_dump_dialog_getFilename(VisuUiDumpDialog * dialog)591 gchar* visu_ui_dump_dialog_getFilename(VisuUiDumpDialog *dialog)
592 {
593   g_return_val_if_fail(dialog, (gchar*)0);
594   return dialog->dumpFileName;
595 }
visu_ui_dump_dialog_getType(VisuUiDumpDialog * dialog)596 VisuDump* visu_ui_dump_dialog_getType(VisuUiDumpDialog *dialog)
597 {
598   g_return_val_if_fail(dialog, (VisuDump*)0);
599   return dialog->selectedToolFileFormat;
600 }
visu_ui_dump_dialog_getProgressBar(VisuUiDumpDialog * dialog)601 GtkProgressBar* visu_ui_dump_dialog_getProgressBar(VisuUiDumpDialog *dialog)
602 {
603   g_return_val_if_fail(dialog, (GtkProgressBar*)0);
604   return GTK_PROGRESS_BAR(dialog->progressBar);
605 }
visu_ui_dump_dialog_getCancelButton(VisuUiDumpDialog * dialog)606 GtkButton* visu_ui_dump_dialog_getCancelButton(VisuUiDumpDialog *dialog)
607 {
608   g_return_val_if_fail(dialog, (GtkButton*)0);
609   return GTK_BUTTON(dialog->cancelButton);
610 }
visu_ui_dump_dialog_getWidth(VisuUiDumpDialog * dialog)611 gint visu_ui_dump_dialog_getWidth(VisuUiDumpDialog *dialog)
612 {
613   g_return_val_if_fail(dialog, 0);
614   return (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(dialog->spinWidth));
615 }
visu_ui_dump_dialog_getHeight(VisuUiDumpDialog * dialog)616 gint visu_ui_dump_dialog_getHeight(VisuUiDumpDialog *dialog)
617 {
618   g_return_val_if_fail(dialog, 0);
619   return (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(dialog->spinHeight));
620 }
visu_ui_dump_dialog_start(VisuUiDumpDialog * dialog)621 void visu_ui_dump_dialog_start(VisuUiDumpDialog *dialog)
622 {
623   /* Put everything except the progress bar insensitive */
624   gtk_widget_set_sensitive(dialog->fileChooser, FALSE);
625   gtk_widget_set_sensitive(dialog->hBoxOptions, FALSE);
626 }
visu_ui_dump_dialog_stop(VisuUiDumpDialog * dialog)627 void visu_ui_dump_dialog_stop(VisuUiDumpDialog *dialog)
628 {
629   /* Put everything except the progress bar sensitive */
630   gtk_widget_set_sensitive(dialog->fileChooser, TRUE);
631   gtk_widget_set_sensitive(dialog->hBoxOptions, TRUE);
632 }
633