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