2 * (GLABELS) Label and Business Card Creation program for GNOME
4 * file.c: FILE menu dialog module
6 * Copyright (C) 2001 Jim Evins <evins@snaught.com>.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include "xml-label.h"
34 #include "wdgt-media-select.h"
35 #include "wdgt-rotate-label.h"
38 /*===========================================*/
40 /*===========================================*/
42 /* Saved state for new dialog */
43 static gchar *page_size = NULL;
44 static gchar *sheet_name = NULL;
45 static gboolean rotate_flag = FALSE;
47 /* Saved state of file selectors */
48 static gchar *open_path = NULL;
49 static gchar *save_path = NULL;
51 /*===========================================*/
52 /* Local function prototypes. */
53 /*===========================================*/
54 static void create_new_dialog_widgets (GtkDialog *dlg);
55 static void new_template_changed (glWdgtMediaSelect *select,
57 static void new_response (GtkDialog *dlg,
60 static void open_ok (GtkWidget * widget,
61 GtkFileSelection * fsel);
63 static void save_as_ok_cb (GtkWidget * widget, GtkFileSelection * fsel);
64 static void save_as_cancel_cb (GtkWidget * widget, GtkFileSelection * fsel);
65 static void save_as_destroy_cb (GtkWidget * widget, gboolean * destroy_flag);
68 /*****************************************************************************/
69 /* "New" menu callback. */
70 /*****************************************************************************/
75 BonoboWindow *win = glabels_get_active_window ();
77 gl_debug (DEBUG_FILE, "START");
79 g_return_if_fail (glabels_mdi != NULL);
80 g_return_if_fail (win != NULL);
82 dlg = gtk_dialog_new_with_buttons (_("New Label or Card"),
84 GTK_DIALOG_DESTROY_WITH_PARENT,
85 GTK_STOCK_OK, GTK_RESPONSE_OK,
86 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
89 create_new_dialog_widgets (GTK_DIALOG (dlg));
91 g_signal_connect (G_OBJECT(dlg), "response",
92 G_CALLBACK (new_response), dlg);
94 gtk_widget_show_all (GTK_WIDGET (dlg));
96 gl_debug (DEBUG_FILE, "END");
99 /*---------------------------------------------------------------------------*/
100 /* PRIVATE. Create widgets. */
101 /*---------------------------------------------------------------------------*/
103 create_new_dialog_widgets (GtkDialog * dlg)
105 GtkWidget *wframe, *wvbox, *template_entry, *rotate_sel;
107 gl_debug (DEBUG_FILE, "START");
109 wframe = gtk_frame_new (_("Media Type"));
110 gtk_box_pack_start (GTK_BOX (dlg->vbox), wframe, FALSE, FALSE, 0);
112 wvbox = gtk_vbox_new (FALSE, GNOME_PAD);
113 gtk_container_set_border_width (GTK_CONTAINER (wvbox), 10);
114 gtk_container_add (GTK_CONTAINER (wframe), wvbox);
116 template_entry = gl_wdgt_media_select_new ();
117 gtk_container_add (GTK_CONTAINER (wvbox), template_entry);
119 wframe = gtk_frame_new (_("Label orientation"));
120 gtk_box_pack_start (GTK_BOX (dlg->vbox), wframe, FALSE, FALSE, 0);
122 wvbox = gtk_vbox_new (FALSE, GNOME_PAD);
123 gtk_container_set_border_width (GTK_CONTAINER (wvbox), 10);
124 gtk_container_add (GTK_CONTAINER (wframe), wvbox);
126 rotate_sel = gl_wdgt_rotate_label_new ();
127 gtk_box_pack_start (GTK_BOX (wvbox), rotate_sel, FALSE, FALSE, 0);
129 g_object_set_data (G_OBJECT (dlg), "template_entry",
131 g_object_set_data (G_OBJECT (dlg), "rotate_sel", rotate_sel);
133 g_signal_connect (G_OBJECT (template_entry), "changed",
134 G_CALLBACK (new_template_changed), rotate_sel);
136 if (page_size != NULL) {
137 gl_wdgt_media_select_set_page_size (GL_WDGT_MEDIA_SELECT (template_entry),
140 if (sheet_name != NULL) {
141 gl_wdgt_media_select_set_name (GL_WDGT_MEDIA_SELECT (template_entry),
143 gl_wdgt_rotate_label_set_template_name (GL_WDGT_ROTATE_LABEL
144 (rotate_sel), sheet_name);
147 gl_wdgt_media_select_get_name (GL_WDGT_MEDIA_SELECT (template_entry));
148 gl_wdgt_rotate_label_set_template_name (GL_WDGT_ROTATE_LABEL
149 (rotate_sel), sheet_name);
151 gl_wdgt_rotate_label_set_state (GL_WDGT_ROTATE_LABEL (rotate_sel), rotate_flag);
153 gl_debug (DEBUG_FILE, "END");
156 /*---------------------------------------------------------------------------*/
157 /* PRIVATE. New template changed callback. */
158 /*---------------------------------------------------------------------------*/
160 new_template_changed (glWdgtMediaSelect * select,
163 glWdgtRotateLabel *rotate_sel = GL_WDGT_ROTATE_LABEL (data);
166 gl_debug (DEBUG_FILE, "START");
168 name = gl_wdgt_media_select_get_name (GL_WDGT_MEDIA_SELECT (select));
170 gl_wdgt_rotate_label_set_template_name (GL_WDGT_ROTATE_LABEL (rotate_sel),
175 gl_debug (DEBUG_FILE, "END");
178 /*---------------------------------------------------------------------------*/
179 /* PRIVATE. New "ok" button callback. */
180 /*---------------------------------------------------------------------------*/
182 new_response (GtkDialog *dlg,
186 GtkWidget *template_entry, *rotate_sel;
187 glMDIChild *new_child = NULL;
190 gl_debug (DEBUG_FILE, "START");
193 case GTK_RESPONSE_OK:
195 GTK_WIDGET (g_object_get_data (G_OBJECT (dlg),
197 rotate_sel = GTK_WIDGET (g_object_get_data (G_OBJECT (dlg),
200 if (page_size != NULL)
203 gl_wdgt_media_select_get_page_size (GL_WDGT_MEDIA_SELECT (template_entry));
205 if (sheet_name != NULL)
208 gl_wdgt_media_select_get_name (GL_WDGT_MEDIA_SELECT (template_entry));
211 gl_wdgt_rotate_label_get_state (GL_WDGT_ROTATE_LABEL (rotate_sel));
213 new_child = gl_mdi_child_new (sheet_name, rotate_flag);
214 gl_debug (DEBUG_FILE, "template set.");
216 ret = bonobo_mdi_add_child (BONOBO_MDI (glabels_mdi),
217 BONOBO_MDI_CHILD (new_child));
218 g_return_if_fail (ret != FALSE);
219 gl_debug (DEBUG_FILE, "Child added.");
221 ret = bonobo_mdi_add_view (BONOBO_MDI (glabels_mdi),
222 BONOBO_MDI_CHILD (new_child));
223 g_return_if_fail (ret != FALSE);
224 gl_debug (DEBUG_FILE, "View added.");
226 gtk_widget_grab_focus (GTK_WIDGET (glabels_get_active_view ()));
230 gtk_widget_destroy (GTK_WIDGET (dlg));
232 gl_debug (DEBUG_FILE, "END");
235 /*****************************************************************************/
236 /* "Open" menu callback. */
237 /*****************************************************************************/
239 gl_file_open (glMDIChild *active_child)
241 GtkFileSelection *fsel;
242 BonoboWindow *app = glabels_get_active_window ();
244 gl_debug (DEBUG_FILE, "START");
246 g_return_if_fail (app != NULL);
248 fsel = GTK_FILE_SELECTION (gtk_file_selection_new (_("Open")));
249 gtk_window_set_transient_for (GTK_WINDOW (fsel), GTK_WINDOW (app));
250 gtk_window_set_title (GTK_WINDOW (fsel), _("Open label"));
252 g_signal_connect (G_OBJECT (fsel->ok_button), "clicked",
253 G_CALLBACK (open_ok), fsel);
255 g_signal_connect_swapped (G_OBJECT (fsel->cancel_button), "clicked",
256 G_CALLBACK (gtk_widget_destroy),
259 /* Recover state of open dialog */
260 if (open_path != NULL) {
261 gtk_file_selection_set_filename (fsel, open_path);
264 /* show the dialog */
265 gtk_widget_show (GTK_WIDGET (fsel));
267 gl_debug (DEBUG_FILE, "END");
270 /*---------------------------------------------------------------------------*/
271 /* PRIVATE. Open "O.K." button callback. */
272 /*---------------------------------------------------------------------------*/
274 open_ok (GtkWidget * widget,
275 GtkFileSelection * fsel)
279 glMDIChild *new_child = NULL;
281 GnomeRecentModel *recent;
283 gl_debug (DEBUG_FILE, "START");
285 g_return_if_fail (GTK_IS_FILE_SELECTION (fsel));
287 /* get the filename */
288 filename = g_strdup (gtk_file_selection_get_filename (fsel));
290 if ( gl_file_open_real (filename, GTK_WINDOW(fsel)) ) {
291 gtk_widget_destroy (GTK_WIDGET (fsel));
297 gl_debug (DEBUG_FILE, "END");
300 /*****************************************************************************/
301 /* "Open recent" menu callback. */
302 /*****************************************************************************/
304 gl_file_open_recent (GnomeRecentView *view,
305 const gchar *filename,
308 gl_debug (DEBUG_FILE, "");
310 return gl_file_open_real (filename, GTK_WINDOW(win));
313 /*---------------------------------------------------------------------------*/
314 /* PRIVATE. Open a file. */
315 /*---------------------------------------------------------------------------*/
317 gl_file_open_real (const gchar *filename,
321 glMDIChild *new_child = NULL;
323 GnomeRecentModel *recent;
326 gl_debug (DEBUG_FILE, "START");
328 abs_filename = gl_util_make_absolute (filename);
329 new_child = gl_mdi_child_new_with_uri (filename, NULL);
332 gl_debug (DEBUG_FILE, "couldn't open file");
334 dlg = gtk_message_dialog_new (GTK_WINDOW(win),
335 GTK_DIALOG_DESTROY_WITH_PARENT,
338 _("Cannot open file '%s'"),
340 gtk_dialog_run (GTK_DIALOG (dlg));
341 gtk_widget_destroy (dlg);
343 g_free (abs_filename);
345 gl_debug (DEBUG_FILE, "END false");
351 ret = bonobo_mdi_add_child (BONOBO_MDI (glabels_mdi),
352 BONOBO_MDI_CHILD (new_child));
353 g_return_if_fail (ret != FALSE);
354 gl_debug (DEBUG_FILE, "Child added.");
356 ret = bonobo_mdi_add_view (BONOBO_MDI (glabels_mdi),
357 BONOBO_MDI_CHILD (new_child));
358 g_return_if_fail (ret != FALSE);
359 gl_debug (DEBUG_FILE, "View added.");
361 gtk_widget_grab_focus (GTK_WIDGET (glabels_get_active_view ()));
363 recent = gl_recent_get_model ();
364 gnome_recent_model_add (recent, abs_filename);
366 if (open_path != NULL)
368 open_path = g_path_get_dirname (abs_filename);
369 if (open_path != NULL)
370 open_path = g_strconcat (open_path, "/", NULL);
372 g_free (abs_filename);
374 gl_debug (DEBUG_FILE, "END true");
381 /*****************************************************************************/
382 /* "Save" menu callback. */
383 /*****************************************************************************/
385 gl_file_save (glMDIChild *child)
387 glXMLLabelStatus status;
388 glLabel *label = NULL;
389 GError *error = NULL;
390 gchar *filename = NULL;
391 GnomeRecentModel *recent;
393 gl_debug (DEBUG_FILE, "");
395 g_return_val_if_fail (child != NULL, FALSE);
397 label = child->label;
398 g_return_val_if_fail (label != NULL, FALSE);
400 if (gl_label_is_untitled (label))
402 gl_debug (DEBUG_FILE, "Untitled");
404 return gl_file_save_as (child);
407 if (!gl_label_is_modified (label))
409 gl_debug (DEBUG_FILE, "Not modified");
414 filename = gl_label_get_filename (label);
415 g_return_val_if_fail (filename != NULL, FALSE);
417 gl_xml_label_save (label, filename, &status);
419 if (status != XML_LABEL_OK)
423 gl_debug (DEBUG_FILE, "FAILED");
425 dialog = gtk_message_dialog_new (GTK_WINDOW(glabels_get_active_window()),
426 GTK_DIALOG_DESTROY_WITH_PARENT,
429 _("Error saving file '%s'"),
431 gtk_dialog_run (GTK_DIALOG (dialog));
432 gtk_widget_destroy (dialog);
440 gl_debug (DEBUG_FILE, "OK");
442 recent = gl_recent_get_model ();
443 gnome_recent_model_add (recent, filename);
451 /*****************************************************************************/
452 /* "Save As" menu callback. */
453 /*****************************************************************************/
455 gl_file_save_as (glMDIChild *child)
457 GtkFileSelection *fsel;
458 BonoboWindow *app = glabels_get_active_window ();
459 gboolean saved_flag = FALSE;
460 gboolean destroy_flag = FALSE;
462 gl_debug (DEBUG_FILE, "START");
464 g_return_val_if_fail (child != NULL, FALSE);
465 g_return_val_if_fail (app != NULL, FALSE);
468 fsel = GTK_FILE_SELECTION (gtk_file_selection_new (_("Save label as")));
469 gtk_window_set_modal (GTK_WINDOW (fsel), TRUE);
470 gtk_window_set_transient_for (GTK_WINDOW (fsel), GTK_WINDOW (app));
472 g_object_set_data (G_OBJECT (fsel), "child", child);
473 g_object_set_data (G_OBJECT (fsel), "saved_flag", &saved_flag);
475 g_signal_connect (G_OBJECT (fsel->ok_button), "clicked",
476 G_CALLBACK (save_as_ok_cb), fsel);
478 g_signal_connect (G_OBJECT (fsel->cancel_button), "clicked",
479 G_CALLBACK (save_as_cancel_cb), fsel);
481 g_signal_connect (G_OBJECT (fsel), "destroy",
482 G_CALLBACK (save_as_destroy_cb), &destroy_flag);
484 /* Recover proper state of save-as dialog */
485 if (save_path != NULL) {
486 gtk_file_selection_set_filename (fsel, save_path);
489 /* show the dialog */
490 gtk_widget_show (GTK_WIDGET (fsel));
492 /* Hold here and process events until we are done with this dialog. */
495 /* Destroy dialog if not already destroyed. */
497 /* Disconnect our destroy callback first, so that we don't kill the
498 * current gtk_main() loop. */
499 g_signal_handlers_disconnect_by_func (GTK_OBJECT (fsel),
500 G_CALLBACK (save_as_destroy_cb),
502 gtk_widget_destroy (GTK_WIDGET (fsel));
505 gl_debug (DEBUG_FILE, "END");
507 /* Return flag as set by one of the above callbacks, TRUE = saved */
511 /*---------------------------------------------------------------------------*/
512 /* PRIVATE. "Save As" ok button callback. */
513 /*---------------------------------------------------------------------------*/
515 save_as_ok_cb (GtkWidget * widget,
516 GtkFileSelection * fsel)
518 gchar *raw_filename, *filename;
522 glXMLLabelStatus status;
523 GnomeRecentModel *recent;
524 gboolean *saved_flag;
526 gl_debug (DEBUG_FILE, "START");
528 g_return_if_fail (GTK_IS_FILE_SELECTION (fsel));
530 child = g_object_get_data (G_OBJECT(fsel), "child");
531 saved_flag = g_object_get_data (G_OBJECT(fsel), "saved_flag");
533 g_return_if_fail (child != NULL);
534 g_return_if_fail (GL_IS_MDI_CHILD (child));
535 gl_debug (DEBUG_FILE, "Got child");
537 label = child->label;
539 /* get the filename */
540 raw_filename = g_strdup (gtk_file_selection_get_filename (fsel));
542 gl_debug (DEBUG_FILE, "raw_filename = \"%s\"", raw_filename);
544 if (!raw_filename || (raw_filename[strlen (raw_filename) - 1] == '/')) {
546 dlg = gtk_message_dialog_new (GTK_WINDOW(fsel),
547 GTK_DIALOG_DESTROY_WITH_PARENT,
550 _("Must supply file name"));
551 gtk_window_set_modal (GTK_WINDOW (dlg), TRUE);
555 filename = gl_util_add_extension (raw_filename);
557 gl_debug (DEBUG_FILE, "filename = \"%s\"", filename);
559 gl_xml_label_save (label, filename, &status);
561 gl_debug (DEBUG_FILE, "status of save = %d", status);
563 if ( status != XML_LABEL_OK ) {
565 dlg = gtk_message_dialog_new (GTK_WINDOW(fsel),
566 GTK_DIALOG_DESTROY_WITH_PARENT,
569 _("Error writing file '%s'"),
571 gtk_window_set_modal (GTK_WINDOW (dlg), TRUE);
577 recent = gl_recent_get_model ();
578 gnome_recent_model_add (recent, filename);
580 if (save_path != NULL)
582 save_path = g_path_get_dirname (filename);
583 if (save_path != NULL)
584 save_path = g_strconcat (save_path, "/", NULL);
586 gtk_widget_destroy (GTK_WIDGET (fsel));
592 g_free (raw_filename);
594 gl_debug (DEBUG_FILE, "END");
597 /*---------------------------------------------------------------------------*/
598 /* PRIVATE. "Save As" cancel button callback. */
599 /*---------------------------------------------------------------------------*/
601 save_as_cancel_cb (GtkWidget * widget,
602 GtkFileSelection * fsel)
604 gboolean *saved_flag = g_object_get_data (G_OBJECT (fsel), "saved_flag");
606 g_return_if_fail (GTK_IS_FILE_SELECTION (fsel));
609 gtk_widget_hide (GTK_WIDGET (fsel));
613 /*---------------------------------------------------------------------------*/
614 /* PRIVATE. "Save As" destroy callback. */
615 /*---------------------------------------------------------------------------*/
617 save_as_destroy_cb (GtkWidget * widget,
618 gboolean * destroy_flag)
620 *destroy_flag = TRUE;
625 /*****************************************************************************/
626 /* "Close" menu callback. */
627 /*****************************************************************************/
629 gl_file_close (GtkWidget * view)
632 BonoboMDIChild* child;
634 gl_debug (DEBUG_FILE, "START");
636 g_return_if_fail (view != NULL);
638 child = bonobo_mdi_get_child_from_view (view);
639 g_return_if_fail (child != NULL);
641 if (g_list_length (bonobo_mdi_child_get_views (child)) > 1)
643 ret = bonobo_mdi_remove_view (BONOBO_MDI (glabels_mdi), view, FALSE);
644 gl_debug (DEBUG_FILE, "View removed.");
648 ret = bonobo_mdi_remove_child (BONOBO_MDI (glabels_mdi), child, FALSE);
649 gl_debug (DEBUG_FILE, "Child removed.");
653 gl_mdi_set_active_window_title (BONOBO_MDI (glabels_mdi));
655 if (bonobo_mdi_get_active_child (BONOBO_MDI (glabels_mdi)) == NULL)
657 gl_mdi_set_active_window_verbs_sensitivity (BONOBO_MDI (glabels_mdi));
660 gl_debug (DEBUG_FILE, "END");
663 /*****************************************************************************/
665 /*****************************************************************************/
667 gl_file_close_all (void)
670 gl_debug (DEBUG_FILE, "");
672 gl_debug (DEBUG_FILE, "START");
674 ret = bonobo_mdi_remove_all (BONOBO_MDI (glabels_mdi), FALSE);
676 if (bonobo_mdi_get_active_child (BONOBO_MDI (glabels_mdi)) == NULL)
678 gl_mdi_set_active_window_verbs_sensitivity (BONOBO_MDI (glabels_mdi));
681 gl_debug (DEBUG_FILE, "END");
686 /*****************************************************************************/
687 /* "Exit" menu callback. */
688 /*****************************************************************************/
692 gl_debug (DEBUG_FILE, "");
694 if (!gl_file_close_all ())
697 gl_debug (DEBUG_FILE, "All files closed.");
699 /* We need to disconnect the signal because mdi "destroy" event
700 is connected to gl_file_exit ( i.e. this function ). */
701 g_signal_handlers_disconnect_by_func (G_OBJECT (glabels_mdi),
702 G_CALLBACK (gl_file_exit), NULL);
704 gl_prefs_save_settings ();
706 gl_debug (DEBUG_FILE, "Unref glabels_mdi.");
708 g_object_unref (G_OBJECT (glabels_mdi));
710 gl_debug (DEBUG_FILE, "Unref glabels_mdi: DONE");
714 gl_debug (DEBUG_FILE, "END");