1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
4 * (GLABELS) Label and Business Card Creation program for GNOME
6 * file.c: FILE menu dialog module
8 * Copyright (C) 2001 Jim Evins <evins@snaught.com>.
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.
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.
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
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>
37 #include "xml-label.h"
41 #include "new-label-dialog.h"
42 #include "libglabels/libglabels.h"
45 /*===========================================*/
47 /*===========================================*/
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;
55 /* Saved state of file selectors */
56 static gchar *open_path = NULL;
57 static gchar *save_path = NULL;
59 /*===========================================*/
60 /* Local function prototypes. */
61 /*===========================================*/
62 static void new_response (GtkDialog *dialog,
66 static void properties_response (GtkDialog *dialog,
70 static void open_response (GtkDialog *chooser,
73 static void save_as_response (GtkDialog *chooser,
78 /*****************************************************************************/
79 /* "New" menu callback. */
80 /*****************************************************************************/
82 gl_file_new (glWindow *window)
86 gl_debug (DEBUG_FILE, "START");
88 g_return_if_fail (window && GTK_IS_WINDOW (window));
90 dialog = gl_new_label_dialog_new (GTK_WINDOW (window));
91 gtk_window_set_title (GTK_WINDOW (dialog), _("New Label or Card"));
93 g_object_set_data (G_OBJECT (dialog), "parent_window", window);
95 g_signal_connect (G_OBJECT(dialog), "response",
96 G_CALLBACK (new_response), dialog);
98 if (page_size != NULL) {
99 gl_new_label_dialog_set_filter_parameters (GL_NEW_LABEL_DIALOG (dialog),
103 if (sheet_name != NULL) {
104 gl_new_label_dialog_set_template_name (GL_NEW_LABEL_DIALOG (dialog),
107 gl_new_label_dialog_set_rotate_state (GL_NEW_LABEL_DIALOG (dialog), rotate_flag);
109 gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
110 gtk_widget_show_all (GTK_WIDGET (dialog));
112 gl_debug (DEBUG_FILE, "END");
115 /*---------------------------------------------------------------------------*/
116 /* PRIVATE. New "ok" button callback. */
117 /*---------------------------------------------------------------------------*/
119 new_response (GtkDialog *dialog,
123 lglTemplate *template;
126 GtkWidget *new_window;
128 gl_debug (DEBUG_FILE, "START");
132 case GTK_RESPONSE_OK:
134 gl_new_label_dialog_get_filter_parameters (GL_NEW_LABEL_DIALOG (dialog),
138 if (sheet_name != NULL)
141 gl_new_label_dialog_get_template_name (GL_NEW_LABEL_DIALOG (dialog));
144 gl_new_label_dialog_get_rotate_state (GL_NEW_LABEL_DIALOG (dialog));
146 template = lgl_db_lookup_template_from_name (sheet_name);
148 label = GL_LABEL(gl_label_new ());
149 gl_label_set_template (label, template);
150 gl_label_set_rotate_flag (label, rotate_flag);
152 lgl_template_free (template);
155 GL_WINDOW (g_object_get_data (G_OBJECT (dialog),
157 if ( gl_window_is_empty (window) ) {
158 gl_window_set_label (window, label);
160 new_window = gl_window_new_from_label (label);
161 gtk_widget_show_all (new_window);
170 gtk_widget_destroy (GTK_WIDGET (dialog));
172 gl_debug (DEBUG_FILE, "END");
175 /*****************************************************************************/
176 /* "Properties" menu callback. */
177 /*****************************************************************************/
179 gl_file_properties (glLabel *label,
185 gl_debug (DEBUG_FILE, "START");
187 g_return_if_fail (label && GL_IS_LABEL (label));
188 g_return_if_fail (window && GTK_IS_WINDOW (window));
190 dialog = gl_new_label_dialog_new (GTK_WINDOW (window));
191 gtk_window_set_title (GTK_WINDOW (dialog), _("Label properties"));
193 g_object_set_data (G_OBJECT (dialog), "label", label);
195 g_signal_connect (G_OBJECT(dialog), "response",
196 G_CALLBACK (properties_response), dialog);
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,
203 name = lgl_template_get_name (label->template);
205 gl_new_label_dialog_set_template_name (GL_NEW_LABEL_DIALOG (dialog), name);
209 gl_new_label_dialog_set_rotate_state (GL_NEW_LABEL_DIALOG (dialog),
212 gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
213 gtk_widget_show_all (GTK_WIDGET (dialog));
215 gl_debug (DEBUG_FILE, "END");
218 /*---------------------------------------------------------------------------*/
219 /* PRIVATE. Properties "ok" button callback. */
220 /*---------------------------------------------------------------------------*/
222 properties_response (GtkDialog *dialog,
226 lglTemplate *template;
229 gl_debug (DEBUG_FILE, "START");
233 case GTK_RESPONSE_OK:
235 gl_new_label_dialog_get_filter_parameters (GL_NEW_LABEL_DIALOG (dialog),
239 if (sheet_name != NULL)
242 gl_new_label_dialog_get_template_name (GL_NEW_LABEL_DIALOG (dialog));
245 gl_new_label_dialog_get_rotate_state (GL_NEW_LABEL_DIALOG (dialog));
247 template = lgl_db_lookup_template_from_name (sheet_name);
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);
259 gtk_widget_destroy (GTK_WIDGET (dialog));
261 gl_debug (DEBUG_FILE, "END");
264 /*****************************************************************************/
265 /* "Open" menu callback. */
266 /*****************************************************************************/
268 gl_file_open (glWindow *window)
271 GtkFileFilter *filter;
273 gl_debug (DEBUG_FILE, "START");
275 g_return_if_fail (window != NULL);
277 chooser = gtk_file_chooser_dialog_new ("Open label",
279 GTK_FILE_CHOOSER_ACTION_OPEN,
280 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
281 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
284 /* Recover state of open dialog */
285 if (open_path != NULL) {
286 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(chooser),
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);
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);
300 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), filter);
302 g_signal_connect (G_OBJECT (chooser), "response",
303 G_CALLBACK (open_response), window);
305 /* show the dialog */
306 gtk_widget_show (GTK_WIDGET (chooser));
308 gl_debug (DEBUG_FILE, "END");
311 /*---------------------------------------------------------------------------*/
312 /* PRIVATE. Open "response" callback. */
313 /*---------------------------------------------------------------------------*/
315 open_response (GtkDialog *chooser,
323 gl_debug (DEBUG_FILE, "START");
325 g_return_if_fail (chooser && GTK_IS_FILE_CHOOSER (chooser));
326 g_return_if_fail (window && GTK_IS_WINDOW (window));
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);
337 g_file_test (raw_filename, G_FILE_TEST_IS_DIR)) {
339 dialog = gtk_message_dialog_new (GTK_WINDOW(chooser),
340 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
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"));
348 gtk_dialog_run (GTK_DIALOG (dialog));
349 gtk_widget_destroy (dialog);
353 if (!g_file_test (raw_filename, G_FILE_TEST_IS_REGULAR)) {
355 dialog = gtk_message_dialog_new (GTK_WINDOW(chooser),
356 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
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"));
364 gtk_dialog_run (GTK_DIALOG (dialog));
365 gtk_widget_destroy (dialog);
370 if ( gl_file_open_real (filename, window) ) {
371 gtk_widget_destroy (GTK_WIDGET (chooser));
379 g_free (raw_filename);
383 gtk_widget_destroy (GTK_WIDGET (chooser));
388 gl_debug (DEBUG_FILE, "END");
392 /*****************************************************************************/
393 /* "Open recent" menu callback. */
394 /*****************************************************************************/
396 gl_file_open_recent (const gchar *filename,
399 gl_debug (DEBUG_FILE, "");
402 gl_debug (DEBUG_FILE, "open recent: %s", filename);
404 gl_file_open_real (filename, window);
408 /*---------------------------------------------------------------------------*/
409 /* PRIVATE. Open a file. */
410 /*---------------------------------------------------------------------------*/
412 gl_file_open_real (const gchar *filename,
417 glXMLLabelStatus status;
418 GtkWidget *new_window;
420 gl_debug (DEBUG_FILE, "START");
422 abs_filename = gl_util_make_absolute (filename);
423 label = gl_xml_label_open (abs_filename, &status);
427 gl_debug (DEBUG_FILE, "couldn't open file");
429 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
430 GTK_DIALOG_DESTROY_WITH_PARENT,
433 _("Could not open file \"%s\""),
435 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
436 _("Not a supported file format"));
438 gtk_dialog_run (GTK_DIALOG (dialog));
439 gtk_widget_destroy (dialog);
441 g_free (abs_filename);
443 gl_debug (DEBUG_FILE, "END false");
449 if ( gl_window_is_empty (GL_WINDOW(window)) ) {
450 gl_window_set_label (GL_WINDOW(window), label);
452 new_window = gl_window_new_from_label (label);
453 gtk_widget_show_all (new_window);
456 gl_recent_add_utf8_filename (abs_filename);
458 if (open_path != NULL)
460 open_path = g_path_get_dirname (abs_filename);
461 g_free (abs_filename);
463 gl_debug (DEBUG_FILE, "END true");
470 /*****************************************************************************/
471 /* "Save" menu callback. */
472 /*****************************************************************************/
474 gl_file_save (glLabel *label,
477 glXMLLabelStatus status;
478 gchar *filename = NULL;
480 gl_debug (DEBUG_FILE, "");
482 g_return_val_if_fail (label != NULL, FALSE);
484 if (gl_label_is_untitled (label))
486 gl_debug (DEBUG_FILE, "Untitled");
488 return gl_file_save_as (label, window);
491 if (!gl_label_is_modified (label))
493 gl_debug (DEBUG_FILE, "Not modified");
498 filename = gl_label_get_filename (label);
499 g_return_val_if_fail (filename != NULL, FALSE);
501 gl_xml_label_save (label, filename, &status);
503 if (status != XML_LABEL_OK)
507 gl_debug (DEBUG_FILE, "FAILED");
509 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
510 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
513 _("Could not save file \"%s\""),
515 gtk_message_dialog_format_secondary_text (
516 GTK_MESSAGE_DIALOG (dialog),
517 _("Error encountered during save. The file is still not saved."));
519 gtk_dialog_run (GTK_DIALOG (dialog));
520 gtk_widget_destroy (dialog);
528 gl_debug (DEBUG_FILE, "OK");
530 gl_recent_add_utf8_filename (filename);
538 /*****************************************************************************/
539 /* "Save As" menu callback. */
540 /*****************************************************************************/
542 gl_file_save_as (glLabel *label,
546 GtkFileFilter *filter;
547 gboolean saved_flag = FALSE;
550 gl_debug (DEBUG_FILE, "START");
552 g_return_val_if_fail (label && GL_IS_LABEL(label), FALSE);
553 g_return_val_if_fail (window && GL_IS_WINDOW(window), FALSE);
555 name = gl_label_get_short_name (label);
556 title = g_strdup_printf (_("Save \"%s\" as"), name);
559 chooser = gtk_file_chooser_dialog_new (title,
561 GTK_FILE_CHOOSER_ACTION_SAVE,
562 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
563 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
566 gtk_window_set_modal (GTK_WINDOW (chooser), TRUE);
570 /* Recover proper state of save-as dialog */
571 if (save_path != NULL) {
572 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(chooser),
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);
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);
586 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), filter);
588 g_signal_connect (G_OBJECT (chooser), "response",
589 G_CALLBACK (save_as_response), label);
591 g_object_set_data (G_OBJECT (chooser), "saved_flag", &saved_flag);
593 /* show the dialog */
594 gtk_widget_show (GTK_WIDGET (chooser));
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. */
600 gl_debug (DEBUG_FILE, "END");
602 /* Return flag as set by one of the above callbacks, TRUE = saved */
606 /*---------------------------------------------------------------------------*/
607 /* PRIVATE. "Save As" ok button callback. */
608 /*---------------------------------------------------------------------------*/
610 save_as_response (GtkDialog *chooser,
614 gchar *raw_filename, *filename, *full_filename;
616 glXMLLabelStatus status;
617 gboolean *saved_flag;
618 gboolean cancel_flag = FALSE;
620 gl_debug (DEBUG_FILE, "START");
622 g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
624 saved_flag = g_object_get_data (G_OBJECT(chooser), "saved_flag");
628 case GTK_RESPONSE_ACCEPT:
629 /* get the filename */
630 raw_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(chooser));
632 gl_debug (DEBUG_FILE, "raw_filename = \"%s\"", raw_filename);
634 if (!raw_filename || g_file_test (raw_filename, G_FILE_TEST_IS_DIR)) {
636 dialog = gtk_message_dialog_new (GTK_WINDOW(chooser),
637 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
640 _("Empty file name selection"));
641 gtk_message_dialog_format_secondary_text (
642 GTK_MESSAGE_DIALOG (dialog),
643 _("Please supply a valid file name"));
645 gtk_dialog_run (GTK_DIALOG (dialog));
646 gtk_widget_destroy (dialog);
650 full_filename = gl_util_add_extension (raw_filename);
652 filename = g_filename_to_utf8 (full_filename, -1,
655 gl_debug (DEBUG_FILE, "filename = \"%s\"", filename);
657 if (g_file_test (full_filename, G_FILE_TEST_IS_REGULAR)) {
660 dialog = gtk_message_dialog_new (GTK_WINDOW(chooser),
661 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
662 GTK_MESSAGE_QUESTION,
664 _("Overwrite file \"%s\"?"),
666 gtk_message_dialog_format_secondary_text (
667 GTK_MESSAGE_DIALOG (dialog),
668 _("File already exists."));
670 ret = gtk_dialog_run (GTK_DIALOG (dialog));
671 if ( ret == GTK_RESPONSE_NO ) {
674 gtk_widget_destroy (dialog);
679 gl_xml_label_save (label, filename, &status);
681 gl_debug (DEBUG_FILE, "status of save = %d", status);
683 if ( status != XML_LABEL_OK ) {
685 dialog = gtk_message_dialog_new (
687 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
690 _("Could not save file \"%s\""),
692 gtk_message_dialog_format_secondary_text (
693 GTK_MESSAGE_DIALOG (dialog),
694 _("Error encountered during save. The file is still not saved."));
696 gtk_dialog_run (GTK_DIALOG (dialog));
697 gtk_widget_destroy (dialog);
703 gl_recent_add_utf8_filename (filename);
705 if (save_path != NULL)
707 save_path = g_path_get_dirname (filename);
709 gtk_widget_destroy (GTK_WIDGET (chooser));
716 g_free (full_filename);
719 g_free (raw_filename);
724 gtk_widget_destroy (GTK_WIDGET (chooser));
730 gl_debug (DEBUG_FILE, "END");
734 /*****************************************************************************/
735 /* "Close" menu callback. */
736 /*****************************************************************************/
738 gl_file_close (glWindow *window)
742 gboolean close = TRUE;
744 gl_debug (DEBUG_FILE, "START");
746 g_return_val_if_fail (window && GL_IS_WINDOW(window), TRUE);
748 if ( !gl_window_is_empty (window) ) {
750 view = GL_VIEW(window->view);
753 if (gl_label_is_modified (label)) {
758 fname = gl_label_get_short_name (label);
760 dialog = gtk_message_dialog_new (GTK_WINDOW(window),
761 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
764 _("Save changes to document \"%s\" before closing?"),
766 gtk_message_dialog_format_secondary_text (
767 GTK_MESSAGE_DIALOG (dialog),
768 _("Your changes will be lost if you don't save them."));
770 gtk_dialog_add_button (GTK_DIALOG (dialog),
771 _("Close without saving"),
774 gtk_dialog_add_button (GTK_DIALOG (dialog),
775 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
777 gtk_dialog_add_button (GTK_DIALOG (dialog),
778 GTK_STOCK_SAVE, GTK_RESPONSE_YES);
780 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
782 gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
784 ret = gtk_dialog_run (GTK_DIALOG (dialog));
786 gtk_widget_destroy (dialog);
792 case GTK_RESPONSE_YES:
793 close = gl_file_save (label, window);
795 case GTK_RESPONSE_NO:
802 gl_debug (DEBUG_FILE, "CLOSE: %s", close ? "TRUE" : "FALSE");
808 gtk_widget_destroy (GTK_WIDGET(window));
810 if ( gl_window_get_window_list () == NULL ) {
812 gl_debug (DEBUG_FILE, "All windows closed.");
819 gl_debug (DEBUG_FILE, "END");
824 /*****************************************************************************/
825 /* "Exit" menu callback. */
826 /*****************************************************************************/
830 const GList *window_list;
833 gl_debug (DEBUG_FILE, "START");
835 window_list = gl_window_get_window_list ();
837 for (p=(GList *)window_list; p != NULL; p=p_next) {
840 gl_file_close (GL_WINDOW(p->data));
843 gl_debug (DEBUG_FILE, "END");