1 /* Dia -- a diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * filedlg.c: some dialogs for saving/loading/exporting files.
5 * Copyright (C) 1999 James Henstridge
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #include <sys/types.h>
35 #include "persistence.h"
38 #include "layer_dialog.h"
39 #include "load_save.h"
40 #include "preferences.h"
41 #include "interface.h"
43 static GtkWidget
*opendlg
= NULL
;
44 static GtkWidget
*savedlg
= NULL
;
45 static GtkWidget
*exportdlg
= NULL
;
48 toggle_compress_callback(GtkWidget
*widget
)
50 /* Changes prefs exactly when the user toggles the setting, i.e.
51 * the setting really remembers what the user chose last time, but
52 * lets diagrams of the opposite kind stay that way unless the user
55 prefs
.new_diagram
.compress_save
=
56 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget
));
60 * Given an import filter index and optionally a filename for fallback
61 * return the import filter to use
63 static DiaImportFilter
*
64 ifilter_by_index (int index
, const char* filename
)
66 DiaImportFilter
*ifilter
= NULL
;
69 ifilter
= g_list_nth_data (filter_get_import_filters(), index
);
70 else if (filename
) /* fallback, should not happen */
71 ifilter
= filter_guess_import_filter(filename
);
76 typedef void* (* FilterGuessFunc
) (const gchar
* filename
);
79 * Respond to the file chooser filter facility, that is match
80 * the extension of a given filename to the selected filter
83 matching_extensions_filter (const GtkFileFilterInfo
* fi
,
86 FilterGuessFunc guess_func
= (FilterGuessFunc
)data
;
88 g_assert (guess_func
);
91 return 0; /* filter it, IMO should not happen --hb */
93 if (guess_func (fi
->filename
))
100 * React on the diagram::removed signal by destroying the dialog
102 * This function isn't used cause it conflicts with the pattern introduced:
103 * instead of destroying the dialog with the diagram, the dialog is keeping
104 * a refernce to it. As a result we could access the diagram even when the
105 * display of it is gone ...
109 diagram_removed (Diagram
* dia
, GtkWidget
* dialog
)
111 g_return_if_fail (DIA_IS_DIAGRAM (dia
));
112 g_return_if_fail (GTK_IS_WIDGET (dialog
));
114 gtk_widget_destroy (dialog
);
119 * Create the combobox menu to select Import Filter options
122 create_open_menu(void)
128 menu
= gtk_combo_box_new_text ();
129 gtk_combo_box_append_text(GTK_COMBO_BOX(menu
), _("By extension"));
131 for (tmp
= filter_get_import_filters(); tmp
!= NULL
; tmp
= tmp
->next
) {
132 DiaImportFilter
*ifilter
= tmp
->data
;
137 filter_label
= filter_get_import_filter_label(ifilter
);
138 gtk_combo_box_append_text (GTK_COMBO_BOX(menu
), filter_label
);
139 g_free(filter_label
);
145 * Respond to the user finishing the Save Dialog either accept or cancel/destroy
148 file_open_response_callback(GtkWidget
*fs
,
152 const char *filename
;
153 Diagram
*diagram
= NULL
;
155 if (response
== GTK_RESPONSE_ACCEPT
) {
156 gint index
= gtk_combo_box_get_active (GTK_COMBO_BOX(user_data
));
158 if (index
>= 0) /* remember it */
159 persistence_set_integer ("import-filter", index
);
160 filename
= gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs
));
162 diagram
= diagram_load(filename
, ifilter_by_index (index
- 1, filename
));
164 if (diagram
!= NULL
) {
165 diagram_update_extents(diagram
);
166 layer_dialog_set_diagram(diagram
);
168 if (diagram
->displays
!= NULL
) {
169 GSList
*displays
= diagram
->displays
;
170 GSList
*displays_head
= displays
;
171 diagram
->displays
= NULL
;
172 for (; displays
!= NULL
; displays
= g_slist_next(displays
)) {
173 DDisplay
*loaded_display
= (DDisplay
*)displays
->data
;
174 copy_display(loaded_display
);
175 g_free(loaded_display
);
177 g_slist_free(displays_head
);
179 new_display(diagram
);
183 gtk_widget_destroy(opendlg
);
187 * Handle menu click File/Open
189 * This is either with or without diagram
192 file_open_callback(gpointer data
, guint action
, GtkWidget
*widget
)
197 GtkWindow
*parent_window
;
198 gchar
*filename
= NULL
;
200 /* FIXME: we should not use ddisp_active but instead get the current diagram
201 * from caller. Thus we could offer the option to "load into" if invoked by
202 * <Display/File/Open. It wouldn't make any sense if invoked by
203 * <Toolbox>/File/Open ...
205 ddisp
= ddisplay_active();
207 dia
= ddisp
->diagram
;
208 parent_window
= GTK_WINDOW(ddisp
->shell
);
210 parent_window
= GTK_WINDOW(interface_get_toolbox_shell());
212 persistence_register_integer ("import-filter", 0);
213 opendlg
= gtk_file_chooser_dialog_new_with_backend(_("Open Diagram"), parent_window
,
214 GTK_FILE_CHOOSER_ACTION_OPEN
,
215 "default", /* default, not gnome-vfs */
216 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
217 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
219 gtk_dialog_set_default_response(GTK_DIALOG(opendlg
), GTK_RESPONSE_ACCEPT
);
220 gtk_window_set_role(GTK_WINDOW(opendlg
), "open_diagram");
221 gtk_window_set_position(GTK_WINDOW(opendlg
), GTK_WIN_POS_MOUSE
);
222 if (dia
&& dia
->filename
)
223 filename
= g_filename_from_utf8(dia
->filename
, -1, NULL
, NULL
, NULL
);
224 if (filename
!= NULL
) {
225 char* fnabs
= dia_get_absolute_filename (filename
);
227 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(opendlg
), fnabs
);
231 g_signal_connect(GTK_OBJECT(opendlg
), "destroy",
232 G_CALLBACK(gtk_widget_destroyed
), &opendlg
);
234 gtk_widget_set_sensitive(opendlg
, TRUE
);
235 if (GTK_WIDGET_VISIBLE(opendlg
))
238 if (!gtk_file_chooser_get_extra_widget(GTK_FILE_CHOOSER(opendlg
))) {
239 GtkWidget
*hbox
, *label
, *omenu
, *options
;
240 GtkFileFilter
* filter
;
242 options
= gtk_frame_new(_("Open Options"));
243 gtk_frame_set_shadow_type(GTK_FRAME(options
), GTK_SHADOW_ETCHED_IN
);
245 hbox
= gtk_hbox_new(FALSE
, 1);
246 gtk_container_set_border_width(GTK_CONTAINER(hbox
), 5);
247 gtk_container_add(GTK_CONTAINER(options
), hbox
);
248 gtk_widget_show(hbox
);
250 label
= gtk_label_new (_("Determine file type:"));
251 gtk_box_pack_start (GTK_BOX (hbox
), label
, FALSE
, TRUE
, 0);
252 gtk_widget_show (label
);
254 omenu
= create_open_menu();
255 gtk_box_pack_start(GTK_BOX(hbox
), omenu
, TRUE
, TRUE
, 0);
256 gtk_widget_show(omenu
);
258 gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(opendlg
),
261 gtk_widget_show(options
);
262 g_signal_connect(GTK_OBJECT(opendlg
), "response",
263 G_CALLBACK(file_open_response_callback
), omenu
);
264 /* set up file filters */
265 filter
= gtk_file_filter_new ();
266 gtk_file_filter_set_name (filter
, _("All Files"));
267 gtk_file_filter_add_pattern (filter
, "*");
268 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (opendlg
), filter
);
269 /* match the other selections extension */
270 filter
= gtk_file_filter_new ();
271 gtk_file_filter_set_name (filter
, _("Supported Formats"));
272 gtk_file_filter_add_custom (filter
, GTK_FILE_FILTER_FILENAME
,
273 matching_extensions_filter
, filter_guess_import_filter
, NULL
);
274 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (opendlg
), filter
);
276 /* candidate for user prefs */
277 gtk_combo_box_set_active (GTK_COMBO_BOX (omenu
), persistence_get_integer ("import-filter"));
280 gtk_widget_show(opendlg
);
284 * Respond to a button press (also destroy) in the save as dialog.
287 file_save_as_response_callback(GtkWidget
*fs
,
291 const char *filename
;
293 struct stat stat_struct
;
295 if (response
== GTK_RESPONSE_ACCEPT
) {
296 dia
= gtk_object_get_user_data(GTK_OBJECT(fs
));
298 filename
= gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs
));
300 if (stat(filename
, &stat_struct
) == 0) {
301 GtkWidget
*dialog
= NULL
;
302 char *utf8filename
= NULL
;
303 if (!g_utf8_validate(filename
, -1, NULL
)) {
304 utf8filename
= g_filename_to_utf8(filename
, -1, NULL
, NULL
, NULL
);
305 if (utf8filename
== NULL
) {
306 message_warning(_("Some characters in the filename are neither UTF-8\n"
307 "nor your local encoding.\nSome things will break."));
310 if (utf8filename
== NULL
) utf8filename
= g_strdup(filename
);
313 dialog
= gtk_message_dialog_new (GTK_WINDOW(fs
),
314 GTK_DIALOG_MODAL
, GTK_MESSAGE_QUESTION
,
316 _("File already exists"));
317 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog
),
318 _("The file '%s' already exists.\n"
319 "Do you want to overwrite it?"), utf8filename
);
320 g_free(utf8filename
);
321 gtk_dialog_set_default_response (GTK_DIALOG (dialog
), GTK_RESPONSE_YES
);
323 if (gtk_dialog_run (GTK_DIALOG (dialog
)) != GTK_RESPONSE_YES
) {
324 /* don't hide/destroy the dialog, but simply go back to it */
325 gtk_window_present (GTK_WINDOW (fs
));
326 gtk_widget_destroy(dialog
);
329 gtk_widget_destroy(dialog
);
332 dia
->data
->is_compressed
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(user_data
));
334 diagram_update_extents(dia
);
336 diagram_set_filename(dia
, filename
);
337 diagram_save(dia
, filename
);
339 /* if we have our own reference, drop it before destroy */
340 if ((dia
= gtk_object_get_user_data(GTK_OBJECT(fs
))) != NULL
) {
341 gtk_object_set_user_data(GTK_OBJECT(fs
), NULL
);
342 g_object_unref (dia
);
344 gtk_widget_destroy(GTK_WIDGET(fs
));
348 * Respond to the File/Save As.. menu
350 * We have only one file save dialog at a time. So if the dialog alread exists
351 * and the user tries to Save as once more only the diagram refernced will
352 * change. Maybe we should also indicate the refernced diagram in the dialog.
355 file_save_as_callback(gpointer data
, guint action
, GtkWidget
*widget
)
359 gchar
*filename
= NULL
;
361 ddisp
= ddisplay_active();
363 dia
= ddisp
->diagram
;
366 GtkWidget
*compressbutton
;
368 savedlg
= gtk_file_chooser_dialog_new_with_backend(_("Save Diagram"),
369 GTK_WINDOW(ddisp
->shell
),
370 GTK_FILE_CHOOSER_ACTION_SAVE
,
371 "gtk+", /* default, not gnome-vfs */
372 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
373 GTK_STOCK_SAVE
, GTK_RESPONSE_ACCEPT
,
375 gtk_dialog_set_default_response(GTK_DIALOG(savedlg
), GTK_RESPONSE_ACCEPT
);
376 gtk_window_set_role(GTK_WINDOW(savedlg
), "save_diagram");
377 gtk_window_set_position(GTK_WINDOW(savedlg
), GTK_WIN_POS_MOUSE
);
378 /* Need better way to make it a reasonable size. Isn't there some*/
379 /* standard look for them (or is that just Gnome?)*/
380 compressbutton
= gtk_check_button_new_with_label(_("Compress diagram files"));
381 gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(savedlg
),
383 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(compressbutton
),
384 dia
->data
->is_compressed
);
385 g_signal_connect(G_OBJECT(compressbutton
), "toggled",
386 G_CALLBACK(toggle_compress_callback
), NULL
);
387 gtk_widget_show(compressbutton
);
388 gtk_tooltips_set_tip(tool_tips
, compressbutton
,
389 _("Compression reduces file size to less than 1/10th "
390 "size and speeds up loading and saving. Some text "
391 "programs cannot manipulate compressed files."), NULL
);
392 g_signal_connect (GTK_FILE_CHOOSER(savedlg
),
393 "response", G_CALLBACK(file_save_as_response_callback
), compressbutton
);
394 g_signal_connect(GTK_OBJECT(savedlg
), "destroy",
395 G_CALLBACK(gtk_widget_destroyed
), &savedlg
);
397 GtkWidget
*compressbutton
= gtk_file_chooser_get_extra_widget(GTK_FILE_CHOOSER(savedlg
));
398 gtk_widget_set_sensitive(savedlg
, TRUE
);
399 g_signal_handlers_block_by_func(G_OBJECT(compressbutton
), toggle_compress_callback
, NULL
);
400 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(compressbutton
),
401 dia
->data
->is_compressed
);
402 g_signal_handlers_unblock_by_func(G_OBJECT(compressbutton
), toggle_compress_callback
, NULL
);
403 if (gtk_object_get_user_data(GTK_OBJECT(savedlg
)) != NULL
)
404 g_object_unref(gtk_object_get_user_data(GTK_OBJECT(savedlg
)));
405 if (GTK_WIDGET_VISIBLE(savedlg
)) {
406 /* keep a refernce to the diagram */
408 gtk_object_set_user_data(GTK_OBJECT(savedlg
), dia
);
409 gtk_window_present (GTK_WINDOW(savedlg
));
413 if (dia
&& dia
->filename
)
414 filename
= g_filename_from_utf8(dia
->filename
, -1, NULL
, NULL
, NULL
);
415 if (filename
!= NULL
) {
416 char* fnabs
= dia_get_absolute_filename (filename
);
418 gchar
*base
= g_path_get_basename(fnabs
);
419 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(savedlg
), fnabs
);
420 /* FileChooser api insist on exiting files for set_filename */
421 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(savedlg
), base
);
428 gtk_object_set_user_data(GTK_OBJECT(savedlg
), dia
);
430 gtk_widget_show(savedlg
);
434 * Respond to the File/Save menu entry.
436 * Delegates to Save As if there is no filename set yet.
439 file_save_callback(gpointer data
, guint action
, GtkWidget
*widget
)
443 diagram
= ddisplay_active_diagram();
444 if (!diagram
) return;
446 if (diagram
->unsaved
) {
447 file_save_as_callback(data
, action
, widget
);
449 gchar
*filename
= g_filename_from_utf8(diagram
->filename
, -1, NULL
, NULL
, NULL
);
450 diagram_update_extents(diagram
);
451 diagram_save(diagram
, filename
);
457 * Given an export filter index and optionally a filename for fallback
458 * return the export filter to use
460 static DiaExportFilter
*
461 efilter_by_index (int index
, const char* filename
)
463 DiaExportFilter
*efilter
= NULL
;
466 efilter
= g_list_nth_data (filter_get_export_filters(), index
);
467 else if (filename
) /* fallback, should not happen */
468 efilter
= filter_guess_export_filter(filename
);
474 * Adapt the filename to the export filter selection
477 export_set_extension(GtkWidget
*widget
)
479 int index
= gtk_combo_box_get_active (GTK_COMBO_BOX(widget
)) - 1; /* Ignore "By Extension" */
480 DiaExportFilter
*efilter
= efilter_by_index (index
, NULL
);
482 const gchar
*text
= gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(exportdlg
));
483 const gchar
*last_dot
= text
? strrchr(text
, '.') : NULL
;
484 gchar
*basename
= NULL
;
486 if (!efilter
|| last_dot
== text
|| text
[0] == '\0' ||
487 efilter
->extensions
[0] == NULL
)
489 basename
= g_path_get_basename (text
);
490 last_dot
= strrchr(basename
, '.');
491 s
= g_string_new(basename
);
493 g_string_truncate(s
, last_dot
-basename
);
494 g_string_append(s
, ".");
495 g_string_append(s
, efilter
->extensions
[0]);
496 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(exportdlg
), s
->str
);
497 g_string_free (s
, TRUE
);
502 * Create a new "option menu" for the export options
505 create_export_menu(void)
510 menu
= gtk_combo_box_new_text ();
511 gtk_combo_box_append_text(GTK_COMBO_BOX(menu
), _("By extension"));
513 for (tmp
= filter_get_export_filters(); tmp
!= NULL
; tmp
= tmp
->next
) {
514 DiaExportFilter
*ef
= tmp
->data
;
519 filter_label
= filter_get_export_filter_label(ef
);
520 gtk_combo_box_append_text (GTK_COMBO_BOX(menu
), filter_label
);
521 g_free(filter_label
);
523 g_signal_connect(GTK_OBJECT(menu
), "changed",
524 G_CALLBACK(export_set_extension
), NULL
);
529 * A button hit in the Export Dialog
532 file_export_response_callback(GtkWidget
*fs
,
536 const char *filename
;
541 dia
= gtk_object_get_user_data(GTK_OBJECT(fs
));
544 if (response
== GTK_RESPONSE_ACCEPT
) {
547 diagram_update_extents(dia
);
549 filename
= gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs
));
551 if (stat(filename
, &statbuf
) == 0) {
552 GtkWidget
*dialog
= NULL
;
554 dialog
= gtk_message_dialog_new (GTK_WINDOW(fs
),
555 GTK_DIALOG_MODAL
| GTK_DIALOG_DESTROY_WITH_PARENT
,
556 GTK_MESSAGE_QUESTION
,
558 _("File already exists"));
559 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog
),
560 _("The file '%s' already exists.\n"
561 "Do you want to overwrite it?"), dia_message_filename(filename
));
562 gtk_dialog_set_default_response (GTK_DIALOG (dialog
), GTK_RESPONSE_YES
);
564 if (gtk_dialog_run (GTK_DIALOG (dialog
)) != GTK_RESPONSE_YES
) {
565 /* if not overwrite allow to select another filename */
566 gtk_widget_destroy(dialog
);
569 gtk_widget_destroy(dialog
);
572 index
= gtk_combo_box_get_active (GTK_COMBO_BOX(user_data
));
574 persistence_set_integer ("export-filter", index
);
575 ef
= efilter_by_index (index
- 1, filename
);
577 ef
= filter_guess_export_filter(filename
);
579 g_object_ref(dia
->data
);
580 ef
->export_func(dia
->data
, filename
, dia
->filename
, ef
->user_data
);
581 g_object_unref(dia
->data
);
583 message_error(_("Could not determine which export filter\n"
584 "to use to save '%s'"), dia_message_filename(filename
));
586 g_object_unref (dia
); /* drop our diagram reference */
587 gtk_widget_destroy(exportdlg
);
591 * React to <Display>/File/Export
594 file_export_callback(gpointer data
, guint action
, GtkWidget
*widget
)
598 gchar
*filename
= NULL
;
600 ddisp
= ddisplay_active();
602 dia
= ddisp
->diagram
;
605 persistence_register_integer ("export-filter", 0);
606 exportdlg
= gtk_file_chooser_dialog_new_with_backend(_("Export Diagram"),
607 GTK_WINDOW(ddisp
->shell
),
608 GTK_FILE_CHOOSER_ACTION_SAVE
,
609 "gtk+", /* default, not gnome-vfs */
610 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
611 GTK_STOCK_SAVE
, GTK_RESPONSE_ACCEPT
,
613 gtk_dialog_set_default_response(GTK_DIALOG(exportdlg
), GTK_RESPONSE_ACCEPT
);
614 gtk_window_set_role(GTK_WINDOW(exportdlg
), "export_diagram");
615 gtk_window_set_position(GTK_WINDOW(exportdlg
), GTK_WIN_POS_MOUSE
);
616 g_signal_connect(GTK_OBJECT(exportdlg
), "destroy",
617 G_CALLBACK(gtk_widget_destroyed
), &exportdlg
);
619 if (!gtk_file_chooser_get_extra_widget(GTK_FILE_CHOOSER(exportdlg
))) {
620 GtkWidget
*hbox
, *label
, *omenu
, *options
;
621 GtkFileFilter
* filter
;
623 options
= gtk_frame_new(_("Export Options"));
624 gtk_frame_set_shadow_type(GTK_FRAME(options
), GTK_SHADOW_ETCHED_IN
);
626 hbox
= gtk_hbox_new(FALSE
, 1);
627 gtk_container_set_border_width(GTK_CONTAINER(hbox
), 5);
628 gtk_container_add(GTK_CONTAINER(options
), hbox
);
629 gtk_widget_show(hbox
);
631 label
= gtk_label_new (_("Determine file type:"));
632 gtk_box_pack_start (GTK_BOX (hbox
), label
, FALSE
, TRUE
, 0);
633 gtk_widget_show (label
);
635 omenu
= create_export_menu();
636 gtk_box_pack_start(GTK_BOX(hbox
), omenu
, TRUE
, TRUE
, 0);
637 gtk_widget_show(omenu
);
638 g_object_set_data(G_OBJECT(exportdlg
), "export-menu", omenu
);
640 gtk_widget_show(options
);
641 gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(exportdlg
), options
);
642 /* set up file filters */
643 filter
= gtk_file_filter_new ();
644 gtk_file_filter_set_name (filter
, _("All Files"));
645 gtk_file_filter_add_pattern (filter
, "*");
646 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (exportdlg
), filter
);
647 /* match the other selections extension */
648 filter
= gtk_file_filter_new ();
649 gtk_file_filter_set_name (filter
, _("Supported Formats"));
650 gtk_file_filter_add_custom (filter
, GTK_FILE_FILTER_FILENAME
,
651 matching_extensions_filter
, filter_guess_export_filter
, NULL
);
652 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (exportdlg
), filter
);
654 gtk_combo_box_set_active (GTK_COMBO_BOX (omenu
), persistence_get_integer ("export-filter"));
656 g_signal_connect(GTK_FILE_CHOOSER(exportdlg
),
657 "response", G_CALLBACK(file_export_response_callback
), omenu
);
659 if (gtk_object_get_user_data(GTK_OBJECT(exportdlg
)))
660 g_object_unref (gtk_object_get_user_data(GTK_OBJECT(exportdlg
)));
662 gtk_object_set_user_data(GTK_OBJECT(exportdlg
), dia
);
663 gtk_widget_set_sensitive(exportdlg
, TRUE
);
665 if (dia
&& dia
->filename
)
666 filename
= g_filename_from_utf8(dia
->filename
, -1, NULL
, NULL
, NULL
);
667 if (filename
!= NULL
) {
668 char* fnabs
= dia_get_absolute_filename (filename
);
670 char *folder
= g_path_get_dirname (fnabs
);
671 char *basename
= g_path_get_basename (fnabs
);
672 /* can't use gtk_file_chooser_set_filename for various reasons, see e.g. bug #305850 */
673 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(exportdlg
), folder
);
674 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(exportdlg
), basename
);
681 export_set_extension(GTK_WIDGET(g_object_get_data(G_OBJECT(exportdlg
),
684 gtk_widget_show(exportdlg
);