3 * Copyright (C) 2001-2009 Jim Evins <evins@snaught.com>.
5 * This file is part of gLabels.
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.
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.
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/>.
25 #include <glib/gi18n.h>
29 #include "xml-label.h"
31 #include "file-util.h"
33 #include "new-label-dialog.h"
34 #include <libglabels.h>
39 /*===========================================*/
41 /*===========================================*/
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;
49 /* Saved state of file selectors */
50 static gchar *open_path = NULL;
51 static gchar *save_path = NULL;
54 /*===========================================*/
55 /* Local function prototypes. */
56 /*===========================================*/
57 static void new_complete (GtkDialog *dialog,
60 static void properties_complete (GtkDialog *dialog,
63 static void open_response (GtkDialog *chooser,
66 static void save_as_response (GtkDialog *chooser,
71 /*****************************************************************************/
72 /* "New" menu callback. */
73 /*****************************************************************************/
75 gl_file_new (glWindow *window)
79 gl_debug (DEBUG_FILE, "START");
81 g_return_if_fail (window && GTK_IS_WINDOW (window));
83 dialog = gl_new_label_dialog_new (GTK_WINDOW (window));
84 gtk_window_set_title (GTK_WINDOW (dialog), _("New Label or Card"));
86 g_object_set_data (G_OBJECT (dialog), "parent_window", window);
88 g_signal_connect (G_OBJECT(dialog), "complete", G_CALLBACK (new_complete), dialog);
90 if (page_size != NULL) {
91 gl_new_label_dialog_set_filter_parameters (GL_NEW_LABEL_DIALOG (dialog),
95 if (sheet_name != NULL) {
96 gl_new_label_dialog_set_template_name (GL_NEW_LABEL_DIALOG (dialog),
99 gl_new_label_dialog_set_rotate_state (GL_NEW_LABEL_DIALOG (dialog), rotate_flag);
101 gtk_widget_show_all (GTK_WIDGET (dialog));
103 gl_debug (DEBUG_FILE, "END");
107 /*---------------------------------------------------------------------------*/
108 /* PRIVATE. New "ok" button callback. */
109 /*---------------------------------------------------------------------------*/
111 new_complete (GtkDialog *dialog,
114 lglTemplate *template;
117 GtkWidget *new_window;
119 gl_debug (DEBUG_FILE, "START");
121 gl_new_label_dialog_get_filter_parameters (GL_NEW_LABEL_DIALOG (dialog),
125 if (sheet_name != NULL)
130 sheet_name = gl_new_label_dialog_get_template_name (GL_NEW_LABEL_DIALOG (dialog));
132 rotate_flag = gl_new_label_dialog_get_rotate_state (GL_NEW_LABEL_DIALOG (dialog));
134 template = lgl_db_lookup_template_from_name (sheet_name);
136 label = GL_LABEL(gl_label_new ());
137 gl_label_set_template (label, template, FALSE);
138 gl_label_set_rotate_flag (label, rotate_flag, FALSE);
140 lgl_template_free (template);
142 window = GL_WINDOW (g_object_get_data (G_OBJECT (dialog), "parent_window"));
143 if ( gl_window_is_empty (window) )
145 gl_window_set_label (window, label);
149 new_window = gl_window_new_from_label (label);
150 gtk_widget_show_all (new_window);
153 gl_debug (DEBUG_FILE, "END");
157 /*****************************************************************************/
158 /* "Properties" menu callback. */
159 /*****************************************************************************/
161 gl_file_properties (glLabel *label,
164 const lglTemplate *template;
165 gboolean rotate_flag;
169 gl_debug (DEBUG_FILE, "START");
171 g_return_if_fail (label && GL_IS_LABEL (label));
172 g_return_if_fail (window && GTK_IS_WINDOW (window));
174 dialog = gl_new_label_dialog_new (GTK_WINDOW (window));
175 gtk_window_set_title (GTK_WINDOW (dialog), _("Label properties"));
177 g_object_set_data (G_OBJECT (dialog), "label", label);
179 g_signal_connect (G_OBJECT(dialog), "complete", G_CALLBACK (properties_complete), dialog);
181 template = gl_label_get_template (label);
182 rotate_flag = gl_label_get_rotate_flag (label);
184 if (template->paper_id != NULL) {
185 gl_new_label_dialog_set_filter_parameters (GL_NEW_LABEL_DIALOG (dialog),
189 name = lgl_template_get_name (template);
191 gl_new_label_dialog_set_template_name (GL_NEW_LABEL_DIALOG (dialog), name);
195 gl_new_label_dialog_set_rotate_state (GL_NEW_LABEL_DIALOG (dialog), rotate_flag);
197 gtk_widget_show_all (GTK_WIDGET (dialog));
199 gl_debug (DEBUG_FILE, "END");
203 /*---------------------------------------------------------------------------*/
204 /* PRIVATE. Properties "ok" button callback. */
205 /*---------------------------------------------------------------------------*/
207 properties_complete (GtkDialog *dialog,
210 lglTemplate *template;
213 gl_debug (DEBUG_FILE, "START");
215 gl_new_label_dialog_get_filter_parameters (GL_NEW_LABEL_DIALOG (dialog),
219 if (sheet_name != NULL)
224 sheet_name = gl_new_label_dialog_get_template_name (GL_NEW_LABEL_DIALOG (dialog));
226 rotate_flag = gl_new_label_dialog_get_rotate_state (GL_NEW_LABEL_DIALOG (dialog));
228 template = lgl_db_lookup_template_from_name (sheet_name);
230 label = GL_LABEL(g_object_get_data (G_OBJECT (dialog), "label"));
232 gl_label_set_template (label, template, TRUE);
233 gl_label_set_rotate_flag (label, rotate_flag, TRUE);
235 gl_debug (DEBUG_FILE, "END");
239 /*****************************************************************************/
240 /* "Open" menu callback. */
241 /*****************************************************************************/
243 gl_file_open (glWindow *window)
246 GtkFileFilter *filter;
248 gl_debug (DEBUG_FILE, "START");
250 g_return_if_fail (window != NULL);
252 chooser = gtk_file_chooser_dialog_new ("Open label",
254 GTK_FILE_CHOOSER_ACTION_OPEN,
255 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
256 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
259 /* Recover state of open dialog */
260 if (open_path != NULL) {
261 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(chooser),
265 filter = gtk_file_filter_new ();
266 gtk_file_filter_add_pattern (filter, "*");
267 gtk_file_filter_set_name (filter, _("All files"));
268 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
270 filter = gtk_file_filter_new ();
271 gtk_file_filter_add_pattern (filter, "*.glabels");
272 gtk_file_filter_set_name (filter, _("gLabels documents"));
273 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
275 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), filter);
277 g_signal_connect (G_OBJECT (chooser), "response",
278 G_CALLBACK (open_response), window);
280 /* show the dialog */
281 gtk_widget_show (GTK_WIDGET (chooser));
283 gl_debug (DEBUG_FILE, "END");
287 /*---------------------------------------------------------------------------*/
288 /* PRIVATE. Open "response" callback. */
289 /*---------------------------------------------------------------------------*/
291 open_response (GtkDialog *chooser,
299 gl_debug (DEBUG_FILE, "START");
301 g_return_if_fail (chooser && GTK_IS_FILE_CHOOSER (chooser));
302 g_return_if_fail (window && GTK_IS_WINDOW (window));
306 case GTK_RESPONSE_ACCEPT:
307 /* get the filename */
308 raw_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(chooser));
309 filename = g_filename_to_utf8 (raw_filename, -1, NULL, NULL, NULL);
313 g_file_test (raw_filename, G_FILE_TEST_IS_DIR)) {
315 dialog = gtk_message_dialog_new (GTK_WINDOW(chooser),
316 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
319 _("Empty file name selection"));
320 gtk_message_dialog_format_secondary_text (
321 GTK_MESSAGE_DIALOG (dialog),
322 _("Please select a file or supply a valid file name"));
324 gtk_dialog_run (GTK_DIALOG (dialog));
325 gtk_widget_destroy (dialog);
329 if (!g_file_test (raw_filename, G_FILE_TEST_IS_REGULAR)) {
331 dialog = gtk_message_dialog_new (GTK_WINDOW(chooser),
332 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
335 _("File does not exist"));
336 gtk_message_dialog_format_secondary_text (
337 GTK_MESSAGE_DIALOG (dialog),
338 _("Please select a file or supply a valid file name"));
340 gtk_dialog_run (GTK_DIALOG (dialog));
341 gtk_widget_destroy (dialog);
346 if ( gl_file_open_real (filename, window) ) {
347 gtk_widget_destroy (GTK_WIDGET (chooser));
355 g_free (raw_filename);
359 gtk_widget_destroy (GTK_WIDGET (chooser));
364 gl_debug (DEBUG_FILE, "END");
368 /*****************************************************************************/
369 /* "Open recent" menu callback. */
370 /*****************************************************************************/
372 gl_file_open_recent (const gchar *filename,
375 gl_debug (DEBUG_FILE, "");
378 gl_debug (DEBUG_FILE, "open recent: %s", filename);
380 gl_file_open_real (filename, window);
385 /*---------------------------------------------------------------------------*/
386 /* PRIVATE. Open a file. */
387 /*---------------------------------------------------------------------------*/
389 gl_file_open_real (const gchar *filename,
394 glXMLLabelStatus status;
395 GtkWidget *new_window;
397 gl_debug (DEBUG_FILE, "START");
399 abs_filename = gl_file_util_make_absolute (filename);
400 label = gl_xml_label_open (abs_filename, &status);
404 gl_debug (DEBUG_FILE, "couldn't open file");
406 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
407 GTK_DIALOG_DESTROY_WITH_PARENT,
410 _("Could not open file \"%s\""),
412 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
413 _("Not a supported file format"));
415 gtk_dialog_run (GTK_DIALOG (dialog));
416 gtk_widget_destroy (dialog);
418 g_free (abs_filename);
420 gl_debug (DEBUG_FILE, "END false");
426 if ( gl_window_is_empty (GL_WINDOW(window)) ) {
427 gl_window_set_label (GL_WINDOW(window), label);
429 new_window = gl_window_new_from_label (label);
430 gtk_widget_show_all (new_window);
433 gl_recent_add_utf8_filename (abs_filename);
435 if (open_path != NULL)
437 open_path = g_path_get_dirname (abs_filename);
438 g_free (abs_filename);
440 gl_debug (DEBUG_FILE, "END true");
448 /*****************************************************************************/
449 /* "Save" menu callback. */
450 /*****************************************************************************/
452 gl_file_save (glLabel *label,
455 glXMLLabelStatus status;
456 gchar *filename = NULL;
458 gl_debug (DEBUG_FILE, "");
460 g_return_val_if_fail (label != NULL, FALSE);
462 if (gl_label_is_untitled (label))
464 gl_debug (DEBUG_FILE, "Untitled");
466 return gl_file_save_as (label, window);
469 if (!gl_label_is_modified (label))
471 gl_debug (DEBUG_FILE, "Not modified");
476 filename = gl_label_get_filename (label);
477 g_return_val_if_fail (filename != NULL, FALSE);
479 gl_xml_label_save (label, filename, &status);
481 if (status != XML_LABEL_OK)
485 gl_debug (DEBUG_FILE, "FAILED");
487 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
488 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
491 _("Could not save file \"%s\""),
493 gtk_message_dialog_format_secondary_text (
494 GTK_MESSAGE_DIALOG (dialog),
495 _("Error encountered during save. The file is still not saved."));
497 gtk_dialog_run (GTK_DIALOG (dialog));
498 gtk_widget_destroy (dialog);
506 gl_debug (DEBUG_FILE, "OK");
508 gl_recent_add_utf8_filename (filename);
517 /*****************************************************************************/
518 /* "Save As" menu callback. */
519 /*****************************************************************************/
521 gl_file_save_as (glLabel *label,
525 GtkFileFilter *filter;
526 gboolean saved_flag = FALSE;
529 gl_debug (DEBUG_FILE, "START");
531 g_return_val_if_fail (label && GL_IS_LABEL(label), FALSE);
532 g_return_val_if_fail (window && GL_IS_WINDOW(window), FALSE);
534 name = gl_label_get_short_name (label);
535 title = g_strdup_printf (_("Save \"%s\" as"), name);
538 chooser = gtk_file_chooser_dialog_new (title,
540 GTK_FILE_CHOOSER_ACTION_SAVE,
541 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
542 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
545 gtk_window_set_modal (GTK_WINDOW (chooser), TRUE);
549 /* Recover proper state of save-as dialog */
550 if (save_path != NULL) {
551 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(chooser),
555 filter = gtk_file_filter_new ();
556 gtk_file_filter_add_pattern (filter, "*");
557 gtk_file_filter_set_name (filter, _("All files"));
558 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
560 filter = gtk_file_filter_new ();
561 gtk_file_filter_add_pattern (filter, "*.glabels");
562 gtk_file_filter_set_name (filter, _("gLabels documents"));
563 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
565 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), filter);
567 g_signal_connect (G_OBJECT (chooser), "response",
568 G_CALLBACK (save_as_response), label);
570 g_object_set_data (G_OBJECT (chooser), "saved_flag", &saved_flag);
572 /* show the dialog */
573 gtk_widget_show (GTK_WIDGET (chooser));
575 /* Hold here and process events until we are done with this dialog. */
576 /* This is so we can return a boolean result of our save attempt. */
579 gl_debug (DEBUG_FILE, "END");
581 /* Return flag as set by one of the above callbacks, TRUE = saved */
586 /*---------------------------------------------------------------------------*/
587 /* PRIVATE. "Save As" ok button callback. */
588 /*---------------------------------------------------------------------------*/
590 save_as_response (GtkDialog *chooser,
594 gchar *raw_filename, *filename, *full_filename;
596 glXMLLabelStatus status;
597 gboolean *saved_flag;
598 gboolean cancel_flag = FALSE;
600 gl_debug (DEBUG_FILE, "START");
602 g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
604 saved_flag = g_object_get_data (G_OBJECT(chooser), "saved_flag");
608 case GTK_RESPONSE_ACCEPT:
609 /* get the filename */
610 raw_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(chooser));
612 gl_debug (DEBUG_FILE, "raw_filename = \"%s\"", raw_filename);
614 if (!raw_filename || g_file_test (raw_filename, G_FILE_TEST_IS_DIR)) {
616 dialog = gtk_message_dialog_new (GTK_WINDOW(chooser),
617 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
620 _("Empty file name selection"));
621 gtk_message_dialog_format_secondary_text (
622 GTK_MESSAGE_DIALOG (dialog),
623 _("Please supply a valid file name"));
625 gtk_dialog_run (GTK_DIALOG (dialog));
626 gtk_widget_destroy (dialog);
630 full_filename = gl_file_util_add_extension (raw_filename);
632 filename = g_filename_to_utf8 (full_filename, -1,
635 gl_debug (DEBUG_FILE, "filename = \"%s\"", filename);
637 if (g_file_test (full_filename, G_FILE_TEST_IS_REGULAR)) {
640 dialog = gtk_message_dialog_new (GTK_WINDOW(chooser),
641 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
642 GTK_MESSAGE_QUESTION,
644 _("Overwrite file \"%s\"?"),
646 gtk_message_dialog_format_secondary_text (
647 GTK_MESSAGE_DIALOG (dialog),
648 _("File already exists."));
650 ret = gtk_dialog_run (GTK_DIALOG (dialog));
651 if ( ret == GTK_RESPONSE_NO ) {
654 gtk_widget_destroy (dialog);
659 gl_xml_label_save (label, filename, &status);
661 gl_debug (DEBUG_FILE, "status of save = %d", status);
663 if ( status != XML_LABEL_OK ) {
665 dialog = gtk_message_dialog_new (
667 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
670 _("Could not save file \"%s\""),
672 gtk_message_dialog_format_secondary_text (
673 GTK_MESSAGE_DIALOG (dialog),
674 _("Error encountered during save. The file is still not saved."));
676 gtk_dialog_run (GTK_DIALOG (dialog));
677 gtk_widget_destroy (dialog);
683 gl_recent_add_utf8_filename (filename);
685 if (save_path != NULL)
687 save_path = g_path_get_dirname (filename);
689 gtk_widget_destroy (GTK_WIDGET (chooser));
696 g_free (full_filename);
699 g_free (raw_filename);
704 gtk_widget_destroy (GTK_WIDGET (chooser));
710 gl_debug (DEBUG_FILE, "END");
714 /*****************************************************************************/
715 /* "Close" menu callback. */
716 /*****************************************************************************/
718 gl_file_close (glWindow *window)
722 gboolean close = TRUE;
724 gl_debug (DEBUG_FILE, "START");
726 g_return_val_if_fail (window && GL_IS_WINDOW(window), TRUE);
728 if ( !gl_window_is_empty (window) ) {
730 view = GL_VIEW(window->view);
733 if (gl_label_is_modified (label)) {
738 fname = gl_label_get_short_name (label);
740 dialog = gtk_message_dialog_new (GTK_WINDOW(window),
741 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
744 _("Save changes to document \"%s\" before closing?"),
746 gtk_message_dialog_format_secondary_text (
747 GTK_MESSAGE_DIALOG (dialog),
748 _("Your changes will be lost if you don't save them."));
750 gtk_dialog_add_button (GTK_DIALOG (dialog),
751 _("Close without saving"),
754 gtk_dialog_add_button (GTK_DIALOG (dialog),
755 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
757 gtk_dialog_add_button (GTK_DIALOG (dialog),
758 GTK_STOCK_SAVE, GTK_RESPONSE_YES);
760 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
762 gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
764 ret = gtk_dialog_run (GTK_DIALOG (dialog));
766 gtk_widget_destroy (dialog);
772 case GTK_RESPONSE_YES:
773 close = gl_file_save (label, window);
775 case GTK_RESPONSE_NO:
782 gl_debug (DEBUG_FILE, "CLOSE: %s", close ? "TRUE" : "FALSE");
788 gtk_widget_destroy (GTK_WIDGET(window));
790 if ( gl_window_get_window_list () == NULL ) {
792 gl_debug (DEBUG_FILE, "All windows closed.");
799 gl_debug (DEBUG_FILE, "END");
805 /*****************************************************************************/
806 /* "Exit" menu callback. */
807 /*****************************************************************************/
811 const GList *window_list;
814 gl_debug (DEBUG_FILE, "START");
816 window_list = gl_window_get_window_list ();
818 for (p=(GList *)window_list; p != NULL; p=p_next) {
821 gl_file_close (GL_WINDOW(p->data));
824 gl_debug (DEBUG_FILE, "END");
830 * Local Variables: -- emacs
832 * c-basic-offset: 8 -- emacs
833 * tab-width: 8 -- emacs
834 * indent-tabs-mode: nil -- emacs