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 "label-properties-dialog.h"
34 #include "new-label-dialog.h"
35 #include <libglabels.h>
40 /*===========================================*/
42 /*===========================================*/
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;
50 /* Saved state of file selectors */
51 static gchar *open_path = NULL;
52 static gchar *save_path = NULL;
55 /*===========================================*/
56 /* Local function prototypes. */
57 /*===========================================*/
58 static void new_complete (GtkDialog *dialog,
61 static void properties_choose_complete (GtkDialog *dialog,
64 static void open_response (GtkDialog *chooser,
67 static void save_as_response (GtkDialog *chooser,
72 /*****************************************************************************/
73 /* "New" menu callback. */
74 /*****************************************************************************/
76 gl_file_new (glWindow *window)
80 gl_debug (DEBUG_FILE, "START");
82 g_return_if_fail (window && GTK_IS_WINDOW (window));
84 dialog = gl_new_label_dialog_new (GTK_WINDOW (window));
85 gtk_window_set_title (GTK_WINDOW (dialog), _("New Label or Card"));
87 g_object_set_data (G_OBJECT (dialog), "parent_window", window);
89 g_signal_connect (G_OBJECT(dialog), "complete", G_CALLBACK (new_complete), dialog);
91 if (page_size != NULL) {
92 gl_new_label_dialog_set_filter_parameters (GL_NEW_LABEL_DIALOG (dialog),
96 if (sheet_name != NULL) {
97 gl_new_label_dialog_set_template_name (GL_NEW_LABEL_DIALOG (dialog),
100 gl_new_label_dialog_set_rotate_state (GL_NEW_LABEL_DIALOG (dialog), rotate_flag);
102 gtk_widget_show_all (GTK_WIDGET (dialog));
104 gl_debug (DEBUG_FILE, "END");
108 /*---------------------------------------------------------------------------*/
109 /* PRIVATE. New "ok" button callback. */
110 /*---------------------------------------------------------------------------*/
112 new_complete (GtkDialog *dialog,
115 lglTemplate *template;
118 GtkWidget *new_window;
120 gl_debug (DEBUG_FILE, "START");
122 gl_new_label_dialog_get_filter_parameters (GL_NEW_LABEL_DIALOG (dialog),
126 if (sheet_name != NULL)
131 sheet_name = gl_new_label_dialog_get_template_name (GL_NEW_LABEL_DIALOG (dialog));
133 rotate_flag = gl_new_label_dialog_get_rotate_state (GL_NEW_LABEL_DIALOG (dialog));
135 template = lgl_db_lookup_template_from_name (sheet_name);
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);
141 lgl_template_free (template);
143 window = GL_WINDOW (g_object_get_data (G_OBJECT (dialog), "parent_window"));
144 if ( gl_window_is_empty (window) )
146 gl_window_set_label (window, label);
150 new_window = gl_window_new_from_label (label);
151 gtk_widget_show_all (new_window);
154 gl_debug (DEBUG_FILE, "END");
157 /*****************************************************************************/
158 /* "Properties" menu callback. */
159 /*****************************************************************************/
161 gl_file_properties (glLabel *label,
167 gl_debug (DEBUG_FILE, "START");
169 g_return_if_fail (label && GL_IS_LABEL (label));
170 g_return_if_fail (window && GTK_IS_WINDOW (window));
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"));
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);
181 gl_debug (DEBUG_FILE, "END");
184 /*****************************************************************************/
185 /* Choose properties assistent. */
186 /*****************************************************************************/
188 gl_file_choose_properties (glLabel *label,
191 const lglTemplate *template;
192 gboolean rotate_flag;
196 gl_debug (DEBUG_FILE, "START");
198 g_return_if_fail (label && GL_IS_LABEL (label));
199 g_return_if_fail (window && GTK_IS_WINDOW (window));
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"));
205 g_object_set_data (G_OBJECT (dialog), "label", label);
207 g_signal_connect (G_OBJECT(dialog), "complete", G_CALLBACK (properties_choose_complete), dialog);
209 template = gl_label_get_template (label);
210 rotate_flag = gl_label_get_rotate_flag (label);
212 if (template->paper_id != NULL) {
213 gl_new_label_dialog_set_filter_parameters (GL_NEW_LABEL_DIALOG (dialog),
217 name = lgl_template_get_name (template);
219 gl_new_label_dialog_set_template_name (GL_NEW_LABEL_DIALOG (dialog), name);
223 gl_new_label_dialog_set_rotate_state (GL_NEW_LABEL_DIALOG (dialog), rotate_flag);
225 gtk_widget_show_all (GTK_WIDGET (dialog));
227 gl_debug (DEBUG_FILE, "END");
231 /*---------------------------------------------------------------------------*/
232 /* PRIVATE. Properties assistant "OK" button callback. */
233 /*---------------------------------------------------------------------------*/
235 properties_choose_complete (GtkDialog *dialog,
238 lglTemplate *template;
241 gl_debug (DEBUG_FILE, "START");
243 gl_new_label_dialog_get_filter_parameters (GL_NEW_LABEL_DIALOG (dialog),
247 if (sheet_name != NULL)
252 sheet_name = gl_new_label_dialog_get_template_name (GL_NEW_LABEL_DIALOG (dialog));
254 rotate_flag = gl_new_label_dialog_get_rotate_state (GL_NEW_LABEL_DIALOG (dialog));
256 template = lgl_db_lookup_template_from_name (sheet_name);
258 label = GL_LABEL(g_object_get_data (G_OBJECT (dialog), "label"));
260 gl_label_set_template (label, template, TRUE);
261 gl_label_set_rotate_flag (label, rotate_flag, TRUE);
263 gl_debug (DEBUG_FILE, "END");
267 /*****************************************************************************/
268 /* "Open" menu callback. */
269 /*****************************************************************************/
271 gl_file_open (glWindow *window)
274 GtkFileFilter *filter;
276 gl_debug (DEBUG_FILE, "START");
278 g_return_if_fail (window != NULL);
280 chooser = gtk_file_chooser_dialog_new ("Open label",
282 GTK_FILE_CHOOSER_ACTION_OPEN,
283 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
284 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
287 /* Recover state of open dialog */
288 if (open_path != NULL) {
289 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(chooser),
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);
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);
303 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), filter);
305 g_signal_connect (G_OBJECT (chooser), "response",
306 G_CALLBACK (open_response), window);
308 /* show the dialog */
309 gtk_widget_show (GTK_WIDGET (chooser));
311 gl_debug (DEBUG_FILE, "END");
315 /*---------------------------------------------------------------------------*/
316 /* PRIVATE. Open "response" callback. */
317 /*---------------------------------------------------------------------------*/
319 open_response (GtkDialog *chooser,
327 gl_debug (DEBUG_FILE, "START");
329 g_return_if_fail (chooser && GTK_IS_FILE_CHOOSER (chooser));
330 g_return_if_fail (window && GTK_IS_WINDOW (window));
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);
341 g_file_test (raw_filename, G_FILE_TEST_IS_DIR)) {
343 dialog = gtk_message_dialog_new (GTK_WINDOW(chooser),
344 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
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"));
352 gtk_dialog_run (GTK_DIALOG (dialog));
353 gtk_widget_destroy (dialog);
357 if (!g_file_test (raw_filename, G_FILE_TEST_IS_REGULAR)) {
359 dialog = gtk_message_dialog_new (GTK_WINDOW(chooser),
360 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
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"));
368 gtk_dialog_run (GTK_DIALOG (dialog));
369 gtk_widget_destroy (dialog);
374 if ( gl_file_open_real (filename, window) ) {
375 gtk_widget_destroy (GTK_WIDGET (chooser));
383 g_free (raw_filename);
387 gtk_widget_destroy (GTK_WIDGET (chooser));
392 gl_debug (DEBUG_FILE, "END");
396 /*****************************************************************************/
397 /* "Open recent" menu callback. */
398 /*****************************************************************************/
400 gl_file_open_recent (const gchar *filename,
403 gl_debug (DEBUG_FILE, "");
406 gl_debug (DEBUG_FILE, "open recent: %s", filename);
408 gl_file_open_real (filename, window);
413 /*---------------------------------------------------------------------------*/
414 /* PRIVATE. Open a file. */
415 /*---------------------------------------------------------------------------*/
417 gl_file_open_real (const gchar *filename,
422 glXMLLabelStatus status;
423 GtkWidget *new_window;
425 gl_debug (DEBUG_FILE, "START");
427 abs_filename = gl_file_util_make_absolute (filename);
428 label = gl_xml_label_open (abs_filename, &status);
432 gl_debug (DEBUG_FILE, "couldn't open file");
434 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
435 GTK_DIALOG_DESTROY_WITH_PARENT,
438 _("Could not open file \"%s\""),
440 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
441 _("Not a supported file format"));
443 gtk_dialog_run (GTK_DIALOG (dialog));
444 gtk_widget_destroy (dialog);
446 g_free (abs_filename);
448 gl_debug (DEBUG_FILE, "END false");
454 if ( gl_window_is_empty (GL_WINDOW(window)) ) {
455 gl_window_set_label (GL_WINDOW(window), label);
457 new_window = gl_window_new_from_label (label);
458 gtk_widget_show_all (new_window);
461 gl_recent_add_utf8_filename (abs_filename);
463 if (open_path != NULL)
465 open_path = g_path_get_dirname (abs_filename);
466 g_free (abs_filename);
468 gl_debug (DEBUG_FILE, "END true");
476 /*****************************************************************************/
477 /* "Save" menu callback. */
478 /*****************************************************************************/
480 gl_file_save (glLabel *label,
483 glXMLLabelStatus status;
484 gchar *filename = NULL;
486 gl_debug (DEBUG_FILE, "");
488 g_return_val_if_fail (label != NULL, FALSE);
490 if (gl_label_is_untitled (label))
492 gl_debug (DEBUG_FILE, "Untitled");
494 return gl_file_save_as (label, window);
497 if (!gl_label_is_modified (label))
499 gl_debug (DEBUG_FILE, "Not modified");
504 filename = gl_label_get_filename (label);
505 g_return_val_if_fail (filename != NULL, FALSE);
507 gl_xml_label_save (label, filename, &status);
509 if (status != XML_LABEL_OK)
513 gl_debug (DEBUG_FILE, "FAILED");
515 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
516 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
519 _("Could not save file \"%s\""),
521 gtk_message_dialog_format_secondary_text (
522 GTK_MESSAGE_DIALOG (dialog),
523 _("Error encountered during save. The file is still not saved."));
525 gtk_dialog_run (GTK_DIALOG (dialog));
526 gtk_widget_destroy (dialog);
534 gl_debug (DEBUG_FILE, "OK");
536 gl_recent_add_utf8_filename (filename);
545 /*****************************************************************************/
546 /* "Save As" menu callback. */
547 /*****************************************************************************/
549 gl_file_save_as (glLabel *label,
553 GtkFileFilter *filter;
554 gboolean saved_flag = FALSE;
556 gchar *filename = NULL;
559 gl_debug (DEBUG_FILE, "START");
561 g_return_val_if_fail (label && GL_IS_LABEL(label), FALSE);
562 g_return_val_if_fail (window && GL_IS_WINDOW(window), FALSE);
564 name = gl_label_get_short_name (label);
565 title = g_strdup_printf (_("Save \"%s\" as"), name);
568 chooser = gtk_file_chooser_dialog_new (title,
570 GTK_FILE_CHOOSER_ACTION_SAVE,
571 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
572 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
575 gtk_window_set_modal (GTK_WINDOW (chooser), TRUE);
579 /* Recover proper state of save-as dialog */
580 filename = gl_label_get_filename (label);
581 if (filename != NULL)
583 path = g_path_get_dirname (filename);
584 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(chooser),
589 else if (save_path != NULL)
591 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(chooser),
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);
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);
605 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), filter);
607 g_signal_connect (G_OBJECT (chooser), "response",
608 G_CALLBACK (save_as_response), label);
610 g_object_set_data (G_OBJECT (chooser), "saved_flag", &saved_flag);
612 /* show the dialog */
613 gtk_widget_show (GTK_WIDGET (chooser));
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. */
619 gl_debug (DEBUG_FILE, "END");
621 /* Return flag as set by one of the above callbacks, TRUE = saved */
626 /*---------------------------------------------------------------------------*/
627 /* PRIVATE. "Save As" ok button callback. */
628 /*---------------------------------------------------------------------------*/
630 save_as_response (GtkDialog *chooser,
634 gchar *raw_filename, *filename, *full_filename;
636 glXMLLabelStatus status;
637 gboolean *saved_flag;
638 gboolean cancel_flag = FALSE;
640 gl_debug (DEBUG_FILE, "START");
642 g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
644 saved_flag = g_object_get_data (G_OBJECT(chooser), "saved_flag");
648 case GTK_RESPONSE_ACCEPT:
649 /* get the filename */
650 raw_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(chooser));
652 gl_debug (DEBUG_FILE, "raw_filename = \"%s\"", raw_filename);
654 if (!raw_filename || g_file_test (raw_filename, G_FILE_TEST_IS_DIR)) {
656 dialog = gtk_message_dialog_new (GTK_WINDOW(chooser),
657 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
660 _("Empty file name selection"));
661 gtk_message_dialog_format_secondary_text (
662 GTK_MESSAGE_DIALOG (dialog),
663 _("Please supply a valid file name"));
665 gtk_dialog_run (GTK_DIALOG (dialog));
666 gtk_widget_destroy (dialog);
670 full_filename = gl_file_util_add_extension (raw_filename);
672 filename = g_filename_to_utf8 (full_filename, -1,
675 gl_debug (DEBUG_FILE, "filename = \"%s\"", filename);
677 if (g_file_test (full_filename, G_FILE_TEST_IS_REGULAR)) {
680 dialog = gtk_message_dialog_new (GTK_WINDOW(chooser),
681 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
682 GTK_MESSAGE_QUESTION,
684 _("Overwrite file \"%s\"?"),
686 gtk_message_dialog_format_secondary_text (
687 GTK_MESSAGE_DIALOG (dialog),
688 _("File already exists."));
690 ret = gtk_dialog_run (GTK_DIALOG (dialog));
691 if ( ret == GTK_RESPONSE_NO ) {
694 gtk_widget_destroy (dialog);
699 gl_xml_label_save (label, filename, &status);
701 gl_debug (DEBUG_FILE, "status of save = %d", status);
703 if ( status != XML_LABEL_OK ) {
705 dialog = gtk_message_dialog_new (
707 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
710 _("Could not save file \"%s\""),
712 gtk_message_dialog_format_secondary_text (
713 GTK_MESSAGE_DIALOG (dialog),
714 _("Error encountered during save. The file is still not saved."));
716 gtk_dialog_run (GTK_DIALOG (dialog));
717 gtk_widget_destroy (dialog);
723 gl_recent_add_utf8_filename (filename);
725 if (save_path != NULL)
727 save_path = g_path_get_dirname (filename);
729 gtk_widget_destroy (GTK_WIDGET (chooser));
736 g_free (full_filename);
739 g_free (raw_filename);
744 gtk_widget_destroy (GTK_WIDGET (chooser));
750 gl_debug (DEBUG_FILE, "END");
754 /*****************************************************************************/
755 /* "Close" menu callback. */
756 /*****************************************************************************/
758 gl_file_close (glWindow *window)
762 gboolean close = TRUE;
764 gl_debug (DEBUG_FILE, "START");
766 g_return_val_if_fail (window && GL_IS_WINDOW(window), TRUE);
768 if ( !gl_window_is_empty (window) ) {
770 view = GL_VIEW(window->view);
773 if (gl_label_is_modified (label)) {
778 fname = gl_label_get_short_name (label);
780 dialog = gtk_message_dialog_new (GTK_WINDOW(window),
781 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
784 _("Save changes to document \"%s\" before closing?"),
786 gtk_message_dialog_format_secondary_text (
787 GTK_MESSAGE_DIALOG (dialog),
788 _("Your changes will be lost if you don't save them."));
790 gtk_dialog_add_button (GTK_DIALOG (dialog),
791 _("Close without saving"),
794 gtk_dialog_add_button (GTK_DIALOG (dialog),
795 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
797 gtk_dialog_add_button (GTK_DIALOG (dialog),
798 GTK_STOCK_SAVE, GTK_RESPONSE_YES);
800 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
802 gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
804 ret = gtk_dialog_run (GTK_DIALOG (dialog));
806 gtk_widget_destroy (dialog);
812 case GTK_RESPONSE_YES:
813 close = gl_file_save (label, window);
815 case GTK_RESPONSE_NO:
822 gl_debug (DEBUG_FILE, "CLOSE: %s", close ? "TRUE" : "FALSE");
828 gtk_widget_destroy (GTK_WIDGET(window));
830 if ( gl_window_get_window_list () == NULL ) {
832 gl_debug (DEBUG_FILE, "All windows closed.");
839 gl_debug (DEBUG_FILE, "END");
845 /*****************************************************************************/
846 /* "Exit" menu callback. */
847 /*****************************************************************************/
851 const GList *window_list;
854 gl_debug (DEBUG_FILE, "START");
856 window_list = gl_window_get_window_list ();
858 for (p=(GList *)window_list; p != NULL; p=p_next) {
861 gl_file_close (GL_WINDOW(p->data));
864 gl_debug (DEBUG_FILE, "END");
870 * Local Variables: -- emacs
872 * c-basic-offset: 8 -- emacs
873 * tab-width: 8 -- emacs
874 * indent-tabs-mode: nil -- emacs