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