]> git.sur5r.net Git - glabels/blob - src/file.c
Imported Upstream version 2.2.8
[glabels] / src / file.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2
3 /*
4  *  (GLABELS) Label and Business Card Creation program for GNOME
5  *
6  *  file.c:  FILE menu dialog module
7  *
8  *  Copyright (C) 2001  Jim Evins <evins@snaught.com>.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23  */
24
25 #include <config.h>
26
27 #include "file.h"
28
29 #include <glib/gi18n.h>
30 #include <gtk/gtkmain.h>
31 #include <gtk/gtkdialog.h>
32 #include <gtk/gtkmessagedialog.h>
33 #include <gtk/gtkfilechooserdialog.h>
34 #include <gtk/gtkstock.h>
35 #include <string.h>
36
37 #include "xml-label.h"
38 #include "recent.h"
39 #include "util.h"
40 #include "window.h"
41 #include "new-label-dialog.h"
42 #include "libglabels/libglabels.h"
43 #include "debug.h"
44
45 /*===========================================*/
46 /* Private globals                           */
47 /*===========================================*/
48
49 /* Saved state for new dialog */
50 static gchar   *page_size   = NULL;
51 static gchar   *category    = NULL;
52 static gchar   *sheet_name  = NULL;
53 static gboolean rotate_flag = FALSE;
54
55 /* Saved state of file selectors */
56 static gchar *open_path = NULL;
57 static gchar *save_path = NULL;
58
59 /*===========================================*/
60 /* Local function prototypes.                */
61 /*===========================================*/
62 static void new_response                     (GtkDialog         *dialog,
63                                               gint               response,
64                                               gpointer           user_data);
65
66 static void properties_response              (GtkDialog         *dialog,
67                                               gint               response,
68                                               gpointer           user_data);
69
70 static void open_response                    (GtkDialog         *chooser,
71                                               gint               response,
72                                               glWindow          *window);
73 static void save_as_response                 (GtkDialog         *chooser,
74                                               gint               response,
75                                               glLabel           *label);
76
77 \f
78 /*****************************************************************************/
79 /* "New" menu callback.                                                      */
80 /*****************************************************************************/
81 void
82 gl_file_new (glWindow  *window)
83 {
84         GtkWidget    *dialog;
85
86         gl_debug (DEBUG_FILE, "START");
87
88         g_return_if_fail (window && GTK_IS_WINDOW (window));
89
90         dialog = gl_new_label_dialog_new (GTK_WINDOW (window));
91         gtk_window_set_title (GTK_WINDOW (dialog), _("New Label or Card"));
92
93         g_object_set_data (G_OBJECT (dialog), "parent_window", window);
94
95         g_signal_connect (G_OBJECT(dialog), "response",
96                           G_CALLBACK (new_response), dialog);
97
98         if (page_size != NULL) {
99                 gl_new_label_dialog_set_filter_parameters (GL_NEW_LABEL_DIALOG (dialog),
100                                                             page_size,
101                                                             category);
102         }
103         if (sheet_name != NULL) {
104                 gl_new_label_dialog_set_template_name (GL_NEW_LABEL_DIALOG (dialog),
105                                           sheet_name);
106         }
107         gl_new_label_dialog_set_rotate_state (GL_NEW_LABEL_DIALOG (dialog), rotate_flag);
108
109         gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
110         gtk_widget_show_all (GTK_WIDGET (dialog));
111
112         gl_debug (DEBUG_FILE, "END");
113 }
114
115 /*---------------------------------------------------------------------------*/
116 /* PRIVATE.  New "ok" button callback.                                       */
117 /*---------------------------------------------------------------------------*/
118 static void
119 new_response (GtkDialog *dialog,
120               gint       response,
121               gpointer   user_data)
122 {
123         lglTemplate *template;
124         glLabel     *label;
125         glWindow    *window;
126         GtkWidget   *new_window;
127
128         gl_debug (DEBUG_FILE, "START");
129
130         switch (response) {
131
132         case GTK_RESPONSE_OK:
133
134                 gl_new_label_dialog_get_filter_parameters (GL_NEW_LABEL_DIALOG (dialog),
135                                                             &page_size,
136                                                             &category);
137
138                 if (sheet_name != NULL)
139                         g_free (sheet_name);
140                 sheet_name =
141                         gl_new_label_dialog_get_template_name (GL_NEW_LABEL_DIALOG (dialog));
142
143                 rotate_flag =
144                         gl_new_label_dialog_get_rotate_state (GL_NEW_LABEL_DIALOG (dialog));
145
146                 template = lgl_db_lookup_template_from_name (sheet_name);
147
148                 label = GL_LABEL(gl_label_new ());
149                 gl_label_set_template (label, template);
150                 gl_label_set_rotate_flag (label, rotate_flag);
151
152                 lgl_template_free (template);
153
154                 window =
155                         GL_WINDOW (g_object_get_data (G_OBJECT (dialog),
156                                                       "parent_window"));
157                 if ( gl_window_is_empty (window) ) {
158                         gl_window_set_label (window, label);
159                 } else {
160                         new_window = gl_window_new_from_label (label);
161                         gtk_widget_show_all (new_window);
162                 }
163                 
164                 break;
165
166         default:
167                 break;
168         }
169
170         gtk_widget_destroy (GTK_WIDGET (dialog));
171
172         gl_debug (DEBUG_FILE, "END");
173 }
174
175 /*****************************************************************************/
176 /* "Properties" menu callback.                                               */
177 /*****************************************************************************/
178 void
179 gl_file_properties (glLabel   *label,
180                     glWindow  *window)
181 {
182         GtkWidget    *dialog;
183         gchar        *name;
184
185         gl_debug (DEBUG_FILE, "START");
186
187         g_return_if_fail (label && GL_IS_LABEL (label));
188         g_return_if_fail (window && GTK_IS_WINDOW (window));
189
190         dialog = gl_new_label_dialog_new (GTK_WINDOW (window));
191         gtk_window_set_title (GTK_WINDOW (dialog), _("Label properties"));
192
193         g_object_set_data (G_OBJECT (dialog), "label", label);
194
195         g_signal_connect (G_OBJECT(dialog), "response",
196                           G_CALLBACK (properties_response), dialog);
197
198         if (label->template->paper_id != NULL) {
199                 gl_new_label_dialog_set_filter_parameters (GL_NEW_LABEL_DIALOG (dialog),
200                                                            label->template->paper_id,
201                                                            NULL);
202         }
203         name = lgl_template_get_name (label->template);
204         if (name != NULL) {
205                 gl_new_label_dialog_set_template_name (GL_NEW_LABEL_DIALOG (dialog), name);
206         }
207         g_free (name);
208
209         gl_new_label_dialog_set_rotate_state (GL_NEW_LABEL_DIALOG (dialog),
210                                               label->rotate_flag);
211
212         gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
213         gtk_widget_show_all (GTK_WIDGET (dialog));
214
215         gl_debug (DEBUG_FILE, "END");
216 }
217
218 /*---------------------------------------------------------------------------*/
219 /* PRIVATE.  Properties "ok" button callback.                                */
220 /*---------------------------------------------------------------------------*/
221 static void
222 properties_response (GtkDialog *dialog,
223               gint       response,
224               gpointer   user_data)
225 {
226         lglTemplate *template;
227         glLabel     *label;
228
229         gl_debug (DEBUG_FILE, "START");
230
231         switch (response) {
232
233         case GTK_RESPONSE_OK:
234
235                 gl_new_label_dialog_get_filter_parameters (GL_NEW_LABEL_DIALOG (dialog),
236                                                             &page_size,
237                                                             &category);
238
239                 if (sheet_name != NULL)
240                         g_free (sheet_name);
241                 sheet_name =
242                         gl_new_label_dialog_get_template_name (GL_NEW_LABEL_DIALOG (dialog));
243
244                 rotate_flag =
245                         gl_new_label_dialog_get_rotate_state (GL_NEW_LABEL_DIALOG (dialog));
246
247                 template = lgl_db_lookup_template_from_name (sheet_name);
248
249                 label = GL_LABEL(g_object_get_data (G_OBJECT (dialog), "label"));
250                 gl_label_set_template (label, template);
251                 gl_label_set_rotate_flag (label, rotate_flag);
252
253                 break;
254
255         default:
256                 break;
257         }
258
259         gtk_widget_destroy (GTK_WIDGET (dialog));
260
261         gl_debug (DEBUG_FILE, "END");
262 }
263
264 /*****************************************************************************/
265 /* "Open" menu callback.                                                     */
266 /*****************************************************************************/
267 void
268 gl_file_open (glWindow  *window)
269 {
270         GtkWidget     *chooser;
271         GtkFileFilter *filter;
272
273         gl_debug (DEBUG_FILE, "START");
274
275         g_return_if_fail (window != NULL);
276
277         chooser = gtk_file_chooser_dialog_new ("Open label",
278                                                GTK_WINDOW (window),
279                                                GTK_FILE_CHOOSER_ACTION_OPEN,
280                                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
281                                                GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
282                                                NULL);
283
284         /* Recover state of open dialog */
285         if (open_path != NULL) {
286                 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(chooser),
287                                                      open_path);
288         }
289
290         filter = gtk_file_filter_new ();
291         gtk_file_filter_add_pattern (filter, "*");
292         gtk_file_filter_set_name (filter, _("All files"));
293         gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
294
295         filter = gtk_file_filter_new ();
296         gtk_file_filter_add_pattern (filter, "*.glabels");
297         gtk_file_filter_set_name (filter, _("gLabels documents"));
298         gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
299
300         gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), filter);
301
302         g_signal_connect (G_OBJECT (chooser), "response",
303                           G_CALLBACK (open_response), window);
304
305         /* show the dialog */
306         gtk_widget_show (GTK_WIDGET (chooser));
307
308         gl_debug (DEBUG_FILE, "END");
309 }
310
311 /*---------------------------------------------------------------------------*/
312 /* PRIVATE.  Open "response" callback.                                       */
313 /*---------------------------------------------------------------------------*/
314 static void
315 open_response (GtkDialog     *chooser,
316                gint           response,
317                glWindow      *window)
318 {
319         gchar            *raw_filename;
320         gchar            *filename;
321         GtkWidget        *dialog;
322
323         gl_debug (DEBUG_FILE, "START");
324
325         g_return_if_fail (chooser && GTK_IS_FILE_CHOOSER (chooser));
326         g_return_if_fail (window && GTK_IS_WINDOW (window));
327
328         switch (response) {
329
330         case GTK_RESPONSE_ACCEPT:
331                 /* get the filename */
332                 raw_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(chooser));
333                 filename = g_filename_to_utf8 (raw_filename, -1, NULL, NULL, NULL);
334
335                 if (!raw_filename || 
336                     !filename || 
337                     g_file_test (raw_filename, G_FILE_TEST_IS_DIR)) {
338
339                         dialog = gtk_message_dialog_new (GTK_WINDOW(chooser),
340                                                       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
341                                                       GTK_MESSAGE_WARNING,
342                                                       GTK_BUTTONS_CLOSE,
343                                                       _("Empty file name selection"));
344                         gtk_message_dialog_format_secondary_text (
345                                 GTK_MESSAGE_DIALOG (dialog),
346                                 _("Please select a file or supply a valid file name"));
347
348                         gtk_dialog_run (GTK_DIALOG (dialog));
349                         gtk_widget_destroy (dialog);
350
351                 } else {
352
353                         if (!g_file_test (raw_filename, G_FILE_TEST_IS_REGULAR)) {
354
355                                 dialog = gtk_message_dialog_new (GTK_WINDOW(chooser),
356                                                               GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
357                                                               GTK_MESSAGE_WARNING,
358                                                               GTK_BUTTONS_CLOSE,
359                                                               _("File does not exist"));
360                                 gtk_message_dialog_format_secondary_text (
361                                         GTK_MESSAGE_DIALOG (dialog),
362                                         _("Please select a file or supply a valid file name"));
363
364                                 gtk_dialog_run (GTK_DIALOG (dialog));
365                                 gtk_widget_destroy (dialog);
366
367
368                         } else {
369                 
370                                 if ( gl_file_open_real (filename, window) ) {
371                                         gtk_widget_destroy (GTK_WIDGET (chooser));
372                                 }
373
374                         }
375
376                 }
377
378                 g_free (filename);
379                 g_free (raw_filename);
380                 break;
381
382         default:
383                 gtk_widget_destroy (GTK_WIDGET (chooser));
384                 break;
385
386         }
387
388         gl_debug (DEBUG_FILE, "END");
389 }
390
391
392 /*****************************************************************************/
393 /* "Open recent" menu callback.                                              */
394 /*****************************************************************************/
395 void
396 gl_file_open_recent (const gchar     *filename,
397                      glWindow        *window)
398 {
399         gl_debug (DEBUG_FILE, "");
400
401         if (filename) {
402                 gl_debug (DEBUG_FILE, "open recent: %s", filename);
403
404                 gl_file_open_real (filename, window);
405         }
406 }
407
408 /*---------------------------------------------------------------------------*/
409 /* PRIVATE.  Open a file.                                                    */
410 /*---------------------------------------------------------------------------*/
411 gboolean
412 gl_file_open_real (const gchar     *filename,
413                    glWindow        *window)
414 {
415         gchar            *abs_filename;
416         glLabel          *label;
417         glXMLLabelStatus  status;
418         GtkWidget        *new_window;
419
420         gl_debug (DEBUG_FILE, "START");
421
422         abs_filename = gl_util_make_absolute (filename);
423         label = gl_xml_label_open (abs_filename, &status);
424         if (!label) {
425                 GtkWidget *dialog;
426
427                 gl_debug (DEBUG_FILE, "couldn't open file");
428
429                 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
430                                               GTK_DIALOG_DESTROY_WITH_PARENT,
431                                               GTK_MESSAGE_ERROR,
432                                               GTK_BUTTONS_CLOSE,
433                                               _("Could not open file \"%s\""),
434                                               filename);
435                 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
436                                                           _("Not a supported file format"));
437
438                 gtk_dialog_run (GTK_DIALOG (dialog));
439                 gtk_widget_destroy (dialog);
440
441                 g_free (abs_filename);
442
443                 gl_debug (DEBUG_FILE, "END false");
444
445                 return FALSE;
446
447         } else {
448
449                 if ( gl_window_is_empty (GL_WINDOW(window)) ) {
450                         gl_window_set_label (GL_WINDOW(window), label);
451                 } else {
452                         new_window = gl_window_new_from_label (label);
453                         gtk_widget_show_all (new_window);
454                 }
455
456                 gl_recent_add_utf8_filename (abs_filename);
457
458                 if (open_path != NULL)
459                         g_free (open_path);
460                 open_path = g_path_get_dirname (abs_filename);
461                 g_free (abs_filename);
462
463                 gl_debug (DEBUG_FILE, "END true");
464
465                 return TRUE;
466
467         }
468 }
469
470 /*****************************************************************************/
471 /* "Save" menu callback.                                                     */
472 /*****************************************************************************/
473 gboolean
474 gl_file_save (glLabel   *label,
475               glWindow  *window)
476 {
477         glXMLLabelStatus  status;
478         gchar            *filename = NULL;
479
480         gl_debug (DEBUG_FILE, "");
481
482         g_return_val_if_fail (label != NULL, FALSE);
483         
484         if (gl_label_is_untitled (label))
485         {
486                 gl_debug (DEBUG_FILE, "Untitled");
487
488                 return gl_file_save_as (label, window);
489         }
490
491         if (!gl_label_is_modified (label))      
492         {
493                 gl_debug (DEBUG_FILE, "Not modified");
494
495                 return TRUE;
496         }
497         
498         filename = gl_label_get_filename (label);
499         g_return_val_if_fail (filename != NULL, FALSE);
500         
501         gl_xml_label_save (label, filename, &status);
502
503         if (status != XML_LABEL_OK)
504         {
505                 GtkWidget *dialog;
506
507                 gl_debug (DEBUG_FILE, "FAILED");
508
509                 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
510                                               GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
511                                               GTK_MESSAGE_ERROR,
512                                               GTK_BUTTONS_CLOSE,
513                                               _("Could not save file \"%s\""),
514                                               filename);
515                 gtk_message_dialog_format_secondary_text (
516                         GTK_MESSAGE_DIALOG (dialog),
517                         _("Error encountered during save.  The file is still not saved."));
518
519                 gtk_dialog_run (GTK_DIALOG (dialog));
520                 gtk_widget_destroy (dialog);
521
522                 g_free (filename);
523
524                 return FALSE;
525         }       
526         else
527         {
528                 gl_debug (DEBUG_FILE, "OK");
529
530                 gl_recent_add_utf8_filename (filename);
531
532                 g_free (filename);
533
534                 return TRUE;
535         }
536 }
537
538 /*****************************************************************************/
539 /* "Save As" menu callback.                                                  */
540 /*****************************************************************************/
541 gboolean
542 gl_file_save_as (glLabel   *label,
543                  glWindow  *window)
544 {
545         GtkWidget        *chooser;
546         GtkFileFilter    *filter;
547         gboolean          saved_flag = FALSE;
548         gchar            *name, *title;
549
550         gl_debug (DEBUG_FILE, "START");
551
552         g_return_val_if_fail (label && GL_IS_LABEL(label), FALSE);
553         g_return_val_if_fail (window && GL_IS_WINDOW(window), FALSE);
554
555         name = gl_label_get_short_name (label);
556         title = g_strdup_printf (_("Save \"%s\" as"), name);
557         g_free (name);
558
559         chooser = gtk_file_chooser_dialog_new (title,
560                                                GTK_WINDOW (window),
561                                                GTK_FILE_CHOOSER_ACTION_SAVE,
562                                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
563                                                GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
564                                                NULL);
565
566         gtk_window_set_modal (GTK_WINDOW (chooser), TRUE);
567
568         g_free (title);
569
570         /* Recover proper state of save-as dialog */
571         if (save_path != NULL) {
572                 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(chooser),
573                                                      save_path);
574         }
575
576         filter = gtk_file_filter_new ();
577         gtk_file_filter_add_pattern (filter, "*");
578         gtk_file_filter_set_name (filter, _("All files"));
579         gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
580
581         filter = gtk_file_filter_new ();
582         gtk_file_filter_add_pattern (filter, "*.glabels");
583         gtk_file_filter_set_name (filter, _("gLabels documents"));
584         gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
585
586         gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), filter);
587
588         g_signal_connect (G_OBJECT (chooser), "response",
589                           G_CALLBACK (save_as_response), label);
590
591         g_object_set_data (G_OBJECT (chooser), "saved_flag", &saved_flag);
592
593         /* show the dialog */
594         gtk_widget_show (GTK_WIDGET (chooser));
595
596         /* Hold here and process events until we are done with this dialog. */
597         /* This is so we can return a boolean result of our save attempt.   */
598         gtk_main ();
599
600         gl_debug (DEBUG_FILE, "END");
601
602         /* Return flag as set by one of the above callbacks, TRUE = saved */
603         return saved_flag;
604 }
605
606 /*---------------------------------------------------------------------------*/
607 /* PRIVATE.  "Save As" ok button callback.                                   */
608 /*---------------------------------------------------------------------------*/
609 static void
610 save_as_response (GtkDialog     *chooser,
611                   gint           response,
612                   glLabel       *label)
613 {
614         gchar            *raw_filename, *filename, *full_filename;
615         GtkWidget        *dialog;
616         glXMLLabelStatus  status;
617         gboolean         *saved_flag;
618         gboolean          cancel_flag = FALSE;
619
620         gl_debug (DEBUG_FILE, "START");
621
622         g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
623
624         saved_flag = g_object_get_data (G_OBJECT(chooser), "saved_flag");
625
626         switch (response) {
627
628         case GTK_RESPONSE_ACCEPT:
629                 /* get the filename */
630                 raw_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(chooser));
631
632                 gl_debug (DEBUG_FILE, "raw_filename = \"%s\"", raw_filename);
633
634                 if (!raw_filename || g_file_test (raw_filename, G_FILE_TEST_IS_DIR)) {
635
636                         dialog = gtk_message_dialog_new (GTK_WINDOW(chooser),
637                                                       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
638                                                       GTK_MESSAGE_WARNING,
639                                                       GTK_BUTTONS_CLOSE,
640                                                       _("Empty file name selection"));
641                         gtk_message_dialog_format_secondary_text (
642                                 GTK_MESSAGE_DIALOG (dialog),
643                                 _("Please supply a valid file name"));
644
645                         gtk_dialog_run (GTK_DIALOG (dialog));
646                         gtk_widget_destroy (dialog);
647
648                 } else {
649
650                         full_filename = gl_util_add_extension (raw_filename);
651
652                         filename = g_filename_to_utf8 (full_filename, -1,
653                                                        NULL, NULL, NULL);
654
655                         gl_debug (DEBUG_FILE, "filename = \"%s\"", filename);
656
657                         if (g_file_test (full_filename, G_FILE_TEST_IS_REGULAR)) {
658                                 gint ret;
659
660                                 dialog = gtk_message_dialog_new (GTK_WINDOW(chooser),
661                                                               GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
662                                                               GTK_MESSAGE_QUESTION,
663                                                               GTK_BUTTONS_YES_NO,
664                                                               _("Overwrite file \"%s\"?"),
665                                                                filename);
666                                 gtk_message_dialog_format_secondary_text (
667                                         GTK_MESSAGE_DIALOG (dialog),
668                                         _("File already exists."));
669
670                                 ret = gtk_dialog_run (GTK_DIALOG (dialog));
671                                 if ( ret == GTK_RESPONSE_NO ) {
672                                         cancel_flag = TRUE;
673                                 }
674                                 gtk_widget_destroy (dialog);
675                         }
676
677                         if (!cancel_flag) {
678
679                                 gl_xml_label_save (label, filename, &status);
680
681                                 gl_debug (DEBUG_FILE, "status of save = %d", status);
682
683                                 if ( status != XML_LABEL_OK ) {
684
685                                         dialog = gtk_message_dialog_new (
686                                                 GTK_WINDOW(chooser),
687                                                 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
688                                                 GTK_MESSAGE_ERROR,
689                                                 GTK_BUTTONS_CLOSE,
690                                                 _("Could not save file \"%s\""),
691                                                 filename);
692                                         gtk_message_dialog_format_secondary_text (
693                                                 GTK_MESSAGE_DIALOG (dialog),
694                                                 _("Error encountered during save.  The file is still not saved."));
695
696                                         gtk_dialog_run (GTK_DIALOG (dialog));
697                                         gtk_widget_destroy (dialog);
698
699                                 } else {
700
701                                         *saved_flag = TRUE;
702
703                                         gl_recent_add_utf8_filename (filename);
704
705                                         if (save_path != NULL)
706                                                 g_free (save_path);
707                                         save_path = g_path_get_dirname (filename);
708
709                                         gtk_widget_destroy (GTK_WIDGET (chooser));
710                                         gtk_main_quit ();
711                                 }
712
713                         }
714
715                         g_free (filename);
716                         g_free (full_filename);
717                 }
718
719                 g_free (raw_filename);
720                 break;
721
722         default:
723                 *saved_flag = FALSE;
724                 gtk_widget_destroy (GTK_WIDGET (chooser));
725                 gtk_main_quit ();
726                 break;
727
728         }
729
730         gl_debug (DEBUG_FILE, "END");
731 }
732
733
734 /*****************************************************************************/
735 /* "Close" menu callback.                                                    */
736 /*****************************************************************************/
737 gboolean
738 gl_file_close (glWindow *window)
739 {
740         glView  *view;
741         glLabel *label;
742         gboolean close = TRUE;
743
744         gl_debug (DEBUG_FILE, "START");
745
746         g_return_val_if_fail (window && GL_IS_WINDOW(window), TRUE);
747
748         if ( !gl_window_is_empty (window) ) {
749
750                 view = GL_VIEW(window->view);
751                 label = view->label;
752
753                 if (gl_label_is_modified (label))       {
754                         GtkWidget *dialog;
755                         gchar *fname = NULL;
756                         gint ret;
757
758                         fname = gl_label_get_short_name (label);
759                         
760                         dialog = gtk_message_dialog_new (GTK_WINDOW(window),
761                                                          GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
762                                                          GTK_MESSAGE_WARNING,
763                                                          GTK_BUTTONS_NONE,
764                                                          _("Save changes to document \"%s\" before closing?"),
765                                                          fname);
766                         gtk_message_dialog_format_secondary_text (
767                                 GTK_MESSAGE_DIALOG (dialog),
768                                 _("Your changes will be lost if you don't save them."));
769
770                         gtk_dialog_add_button (GTK_DIALOG (dialog),
771                                                _("Close without saving"),
772                                                GTK_RESPONSE_NO);
773
774                         gtk_dialog_add_button (GTK_DIALOG (dialog),
775                                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
776
777                         gtk_dialog_add_button (GTK_DIALOG (dialog),
778                                                GTK_STOCK_SAVE, GTK_RESPONSE_YES);
779
780                         gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
781
782                         gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
783
784                         ret = gtk_dialog_run (GTK_DIALOG (dialog));
785                 
786                         gtk_widget_destroy (dialog);
787
788                         g_free (fname);
789                 
790                         switch (ret)
791                         {
792                         case GTK_RESPONSE_YES:
793                                 close = gl_file_save (label, window);
794                                 break;
795                         case GTK_RESPONSE_NO:
796                                 close = TRUE;
797                                 break;
798                         default:
799                                 close = FALSE;
800                         }
801
802                         gl_debug (DEBUG_FILE, "CLOSE: %s", close ? "TRUE" : "FALSE");
803                 }
804
805         }
806
807         if (close) {
808                 gtk_widget_destroy (GTK_WIDGET(window));
809
810                 if ( gl_window_get_window_list () == NULL ) {
811                         
812                         gl_debug (DEBUG_FILE, "All windows closed.");
813         
814                         gtk_main_quit ();
815                 }
816
817         }
818
819         gl_debug (DEBUG_FILE, "END");
820
821         return close;
822 }
823
824 /*****************************************************************************/
825 /* "Exit" menu callback.                                                     */
826 /*****************************************************************************/
827 void
828 gl_file_exit (void)
829 {
830         const GList *window_list;
831         GList       *p, *p_next;
832
833         gl_debug (DEBUG_FILE, "START");
834
835         window_list = gl_window_get_window_list ();
836
837         for (p=(GList *)window_list; p != NULL; p=p_next) {
838                 p_next = p->next;
839
840                 gl_file_close (GL_WINDOW(p->data));
841         }
842
843         gl_debug (DEBUG_FILE, "END");
844 }