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