2 * (GLABELS) Label and Business Card Creation program for GNOME
4 * print-dialog.c: Print dialog module
6 * Copyright (C) 2001-2003 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
28 #include <libgnomeprintui/gnome-print-dialog.h>
29 #include <libgnomeprint/gnome-print-job.h>
30 #include <libgnomeprintui/gnome-print-job-preview.h>
32 #include "print-dialog.h"
36 #include "wdgt-print-copies.h"
37 #include "wdgt-print-merge.h"
41 /***************************************************************************/
42 /* FIXME: GnomePrinterSelector is not public in libgnomeprintui-2.2. */
44 /* I know that I'm asking for trouble, but here are standin prototypes: */
45 GtkWidget *gnome_printer_selector_new (GnomePrintConfig *config);
46 GnomePrintConfig *gnome_printer_selector_get_config (GtkWidget *psel);
47 #define GNOME_PRINTER_SELECTOR(x) (x)
48 /***************************************************************************/
50 /*===========================================*/
51 /* Private data types */
52 /*===========================================*/
54 struct _glPrintDialogPrivate {
58 GtkWidget *simple_frame;
61 GtkWidget *merge_frame;
64 GtkWidget *outline_check;
65 GtkWidget *reverse_check;
66 GtkWidget *crop_marks_check;
68 GtkWidget *printer_select;
72 /*===========================================*/
74 /*===========================================*/
76 static glHigDialogClass* parent_class = NULL;
78 /*===========================================*/
79 /* Local function prototypes */
80 /*===========================================*/
82 static void gl_print_dialog_class_init (glPrintDialogClass *klass);
83 static void gl_print_dialog_init (glPrintDialog *dlg);
84 static void gl_print_dialog_finalize (GObject *object);
86 static void gl_print_dialog_construct (glPrintDialog *dialog,
90 static GtkWidget *job_page_new (glPrintDialog *dialog,
93 static GtkWidget *printer_page_new (glPrintDialog *dialog,
96 static void merge_changed_cb (glLabel *label,
97 glPrintDialog *dialog);
99 static void size_changed_cb (glLabel *label,
100 glPrintDialog *dialog);
102 static void delete_event_cb (glPrintDialog *dialog,
105 static void print_response_cb (glPrintDialog *dialog,
109 static void print_sheets (GnomePrintConfig *config,
111 gboolean preview_flag,
115 gboolean outline_flag,
116 gboolean reverse_flag,
117 gboolean crop_marks_flag);
119 static void print_sheets_merge (GnomePrintConfig *config,
121 gboolean preview_flag,
124 gboolean collate_flag,
125 gboolean outline_flag,
126 gboolean reverse_flag,
127 gboolean crop_marks_flag);
132 /*****************************************************************************/
133 /* Boilerplate object stuff. */
134 /*****************************************************************************/
136 gl_print_dialog_get_type (void)
138 static GType dialog_type = 0;
142 static const GTypeInfo dialog_info =
144 sizeof (glPrintDialogClass),
145 NULL, /* base_init */
146 NULL, /* base_finalize */
147 (GClassInitFunc) gl_print_dialog_class_init,
148 NULL, /* class_finalize */
149 NULL, /* class_data */
150 sizeof (glPrintDialog),
152 (GInstanceInitFunc) gl_print_dialog_init
155 dialog_type = g_type_register_static (GL_TYPE_HIG_DIALOG,
165 gl_print_dialog_class_init (glPrintDialogClass *klass)
167 GObjectClass *object_class = G_OBJECT_CLASS (klass);
169 gl_debug (DEBUG_PRINT, "");
171 parent_class = g_type_class_peek_parent (klass);
173 object_class->finalize = gl_print_dialog_finalize;
177 gl_print_dialog_init (glPrintDialog *dialog)
179 GtkWidget *pp_button;
181 gl_debug (DEBUG_PRINT, "");
183 dialog->priv = g_new0 (glPrintDialogPrivate, 1);
185 gtk_dialog_add_buttons (GTK_DIALOG(dialog),
186 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
187 GTK_STOCK_PRINT, GNOME_PRINT_DIALOG_RESPONSE_PRINT,
191 gtk_dialog_add_button (GTK_DIALOG (dialog),
192 GTK_STOCK_PRINT_PREVIEW, GNOME_PRINT_DIALOG_RESPONSE_PREVIEW);
193 gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (GTK_DIALOG (dialog)->action_area),
195 gtk_dialog_set_default_response (GTK_DIALOG (dialog),
196 GNOME_PRINT_DIALOG_RESPONSE_PRINT);
198 gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
200 g_signal_connect (G_OBJECT(dialog),
202 G_CALLBACK (delete_event_cb),
208 gl_print_dialog_finalize (GObject *object)
210 glPrintDialog* dialog;
212 gl_debug (DEBUG_PRINT, "");
214 g_return_if_fail (object != NULL);
216 dialog = GL_PRINT_DIALOG (object);
218 g_return_if_fail (GL_IS_PRINT_DIALOG (dialog));
219 g_return_if_fail (dialog->priv != NULL);
221 if (dialog->priv->label) {
222 g_object_unref (G_OBJECT(dialog->priv->label));
224 g_free (dialog->priv);
226 G_OBJECT_CLASS (parent_class)->finalize (object);
228 g_free (dialog->priv);
231 /*****************************************************************************/
232 /* NEW object properties dialog. */
233 /*****************************************************************************/
235 gl_print_dialog_new (glLabel *label,
240 gl_debug (DEBUG_PRINT, "");
242 dialog = GTK_WIDGET (g_object_new (GL_TYPE_PRINT_DIALOG, NULL));
244 gl_print_dialog_construct (GL_PRINT_DIALOG(dialog), label, win);
249 /*--------------------------------------------------------------------------*/
250 /* PRIVATE. Construct dialog. */
251 /*--------------------------------------------------------------------------*/
253 gl_print_dialog_construct (glPrintDialog *dialog,
257 GtkWidget *notebook, *page;
260 gl_debug (DEBUG_PRINT, "START");
262 g_return_if_fail (label && GL_IS_LABEL(label));
264 dialog->priv->label = GL_LABEL(g_object_ref (G_OBJECT(label)));
266 name = gl_label_get_short_name (label);
267 title = g_strdup_printf ("%s \"%s\"", _("Print"), name);
270 gtk_window_set_title (GTK_WINDOW(dialog), title);
272 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(win));
273 gtk_window_set_destroy_with_parent (GTK_WINDOW(dialog), TRUE);
276 notebook = gtk_notebook_new ();
277 gl_hig_dialog_add_widget (GL_HIG_DIALOG(dialog), notebook);
279 /* ----- Create Job notebook page ----- */
280 page = job_page_new (dialog, label);
281 gtk_notebook_append_page (GTK_NOTEBOOK(notebook), page,
282 gtk_label_new_with_mnemonic (_("_Job")));
284 /* ----- Create Printer notebook page ----- */
285 page = printer_page_new (dialog, label);
286 gtk_notebook_append_page (GTK_NOTEBOOK(notebook), page,
287 gtk_label_new_with_mnemonic (_("P_rinter")));
289 g_signal_connect (G_OBJECT(dialog), "response",
290 G_CALLBACK (print_response_cb), label);
292 gtk_widget_show_all (GTK_WIDGET (dialog));
294 merge_changed_cb (GL_LABEL(label), dialog);
299 gl_debug (DEBUG_PRINT, "END");
302 /*---------------------------------------------------------------------------*/
303 /* PRIVATE. Create "Job" page. */
304 /*---------------------------------------------------------------------------*/
306 job_page_new (glPrintDialog *dialog,
312 vbox = gl_hig_vbox_new (GL_HIG_VBOX_OUTER);
314 /* ----------- Add simple-copies widget ------------ */
315 dialog->priv->simple_frame = gl_hig_category_new (_("Copies"));
316 gl_hig_vbox_add_widget (GL_HIG_VBOX(vbox), dialog->priv->simple_frame);
318 dialog->priv->copies = gl_wdgt_print_copies_new (label);
319 gl_hig_category_add_widget (GL_HIG_CATEGORY(dialog->priv->simple_frame),
320 dialog->priv->copies);
322 /* ------- Add merge control widget ------------ */
323 dialog->priv->merge_frame = gl_hig_category_new (_("Document merge control"));
324 gl_hig_vbox_add_widget (GL_HIG_VBOX(vbox), dialog->priv->merge_frame);
326 dialog->priv->prmerge = gl_wdgt_print_merge_new (label);
327 gl_hig_category_add_widget (GL_HIG_CATEGORY(dialog->priv->merge_frame),
328 dialog->priv->prmerge);
330 /* ----------- Add custom print options area ------------ */
331 wframe = gl_hig_category_new (_("Options"));
332 gl_hig_vbox_add_widget (GL_HIG_VBOX(vbox), wframe);
334 /* add Outline check button */
335 dialog->priv->outline_check =
336 gtk_check_button_new_with_label (
337 _("print outlines (to test printer alignment)"));
338 gl_hig_category_add_widget (GL_HIG_CATEGORY(wframe), dialog->priv->outline_check);
339 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->outline_check),
342 /* add Reverse check button */
343 dialog->priv->reverse_check =
344 gtk_check_button_new_with_label (
345 _("print in reverse (i.e. a mirror image)"));
346 gl_hig_category_add_widget (GL_HIG_CATEGORY(wframe), dialog->priv->reverse_check);
347 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->reverse_check),
350 /* add Crop marks check button */
351 dialog->priv->crop_marks_check =
352 gtk_check_button_new_with_label (_("print crop marks"));
353 gl_hig_category_add_widget (GL_HIG_CATEGORY(wframe), dialog->priv->crop_marks_check);
354 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->crop_marks_check),
357 g_signal_connect (G_OBJECT(label), "merge_changed",
358 G_CALLBACK (merge_changed_cb), dialog);
360 g_signal_connect (G_OBJECT(label), "size_changed",
361 G_CALLBACK (size_changed_cb), dialog);
366 /*---------------------------------------------------------------------------*/
367 /* PRIVATE. Create "Printer" page. */
368 /*---------------------------------------------------------------------------*/
370 printer_page_new (glPrintDialog *dialog,
374 GtkWidget *printer_select;
376 vbox = gl_hig_vbox_new (GL_HIG_VBOX_OUTER);
378 /* FIXME: GnomePrinterSelector is not public in libgnomeprintui-2.2 */
379 dialog->priv->printer_select =
380 gnome_printer_selector_new (gnome_print_config_default ());
381 gtk_widget_show (dialog->priv->printer_select);
382 gl_hig_vbox_add_widget (GL_HIG_VBOX(vbox), dialog->priv->printer_select);
387 /*--------------------------------------------------------------------------*/
388 /* PRIVATE. "merge_changed" callback. */
389 /*--------------------------------------------------------------------------*/
391 merge_changed_cb (glLabel *label,
392 glPrintDialog *dialog)
397 gl_debug (DEBUG_PRINT, "START");
399 merge = gl_label_get_merge (label);
402 gtk_widget_show_all (dialog->priv->simple_frame);
403 gtk_widget_hide_all (dialog->priv->merge_frame);
407 n_records = gl_merge_get_record_count( merge );
408 gl_wdgt_print_merge_set_copies (GL_WDGT_PRINT_MERGE(dialog->priv->prmerge),
409 1, 1, n_records, FALSE);
410 g_object_unref (G_OBJECT(merge));
412 gtk_widget_hide_all (dialog->priv->simple_frame);
413 gtk_widget_show_all (dialog->priv->merge_frame);
416 gl_debug (DEBUG_PRINT, "END");
419 /*--------------------------------------------------------------------------*/
420 /* PRIVATE. "size_changed" (template changed) callback. */
421 /*--------------------------------------------------------------------------*/
423 size_changed_cb (glLabel *label,
424 glPrintDialog *dialog)
426 gl_debug (DEBUG_PRINT, "START");
428 /* Remove and unref original widgets. */
429 gtk_container_remove (GTK_CONTAINER(GL_HIG_CATEGORY(dialog->priv->simple_frame)->vbox),
430 dialog->priv->copies);
431 gtk_container_remove (GTK_CONTAINER(GL_HIG_CATEGORY(dialog->priv->merge_frame)->vbox),
432 dialog->priv->prmerge);
434 /* Create new widgets based on updated label and install */
435 dialog->priv->copies = gl_wdgt_print_copies_new (label);
436 gl_hig_category_add_widget (GL_HIG_CATEGORY(dialog->priv->simple_frame),
437 dialog->priv->copies);
438 dialog->priv->prmerge = gl_wdgt_print_merge_new (label);
439 gl_hig_category_add_widget (GL_HIG_CATEGORY(dialog->priv->merge_frame),
440 dialog->priv->prmerge);
442 /* Update these widgets. */
443 merge_changed_cb (label, dialog);
445 gl_debug (DEBUG_PRINT, "END");
448 /*--------------------------------------------------------------------------*/
449 /* PRIVATE. delete event callback. */
450 /*--------------------------------------------------------------------------*/
452 delete_event_cb (glPrintDialog *dialog,
455 gl_debug (DEBUG_PRINT, "START");
457 gtk_widget_hide (GTK_WIDGET(dialog));
459 gl_debug (DEBUG_PRINT, "END");
462 /*---------------------------------------------------------------------------*/
463 /* PRIVATE. Print "response" callback. */
464 /*---------------------------------------------------------------------------*/
466 print_response_cb (glPrintDialog *dialog,
470 GnomePrintConfig *config;
472 gboolean outline_flag, reverse_flag, crop_marks_flag, collate_flag;
473 gint first, last, n_sheets, n_copies;
477 case GNOME_PRINT_DIALOG_RESPONSE_PRINT:
478 case GNOME_PRINT_DIALOG_RESPONSE_PREVIEW:
480 /* FIXME: GnomePrinterSelector is not public in libgnomeprintui-2.2. */
481 config = gnome_printer_selector_get_config (GNOME_PRINTER_SELECTOR(dialog->priv->printer_select));
484 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
485 (dialog->priv->outline_check));
487 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
488 (dialog->priv->reverse_check));
490 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
491 (dialog->priv->crop_marks_check));
493 merge = gl_label_get_merge (label);
497 gl_wdgt_print_copies_get_range (GL_WDGT_PRINT_COPIES (dialog->priv->copies),
498 &n_sheets, &first, &last);
499 print_sheets (config, label,
500 (response == GNOME_PRINT_DIALOG_RESPONSE_PREVIEW),
501 n_sheets, first, last,
502 outline_flag, reverse_flag, crop_marks_flag);
506 gl_wdgt_print_merge_get_copies (GL_WDGT_PRINT_MERGE (dialog->priv->prmerge),
509 print_sheets_merge (config, label,
510 (response == GNOME_PRINT_DIALOG_RESPONSE_PREVIEW),
516 g_object_unref (G_OBJECT(merge));
525 gtk_widget_hide (GTK_WIDGET(dialog));
528 /*---------------------------------------------------------------------------*/
529 /* PRIVATE. print the sheets */
530 /*---------------------------------------------------------------------------*/
532 print_sheets (GnomePrintConfig *config,
534 gboolean preview_flag,
538 gboolean outline_flag,
539 gboolean reverse_flag,
540 gboolean crop_marks_flag)
545 job = gnome_print_job_new (config);
546 flags.outline = outline_flag;
547 flags.reverse = reverse_flag;
548 flags.crop_marks = crop_marks_flag;
549 gl_print_simple (job, label, n_sheets, first, last, &flags);
550 gnome_print_job_close (job);
553 GtkWidget *preview_widget =
554 gnome_print_job_preview_new (job, _("Print preview"));
555 gtk_widget_show (GTK_WIDGET (preview_widget));
557 gnome_print_job_print (job);
560 g_object_unref (G_OBJECT (job));
563 /*---------------------------------------------------------------------------*/
564 /* PRIVATE. print the sheets with merge data */
565 /*---------------------------------------------------------------------------*/
567 print_sheets_merge (GnomePrintConfig *config,
569 gboolean preview_flag,
572 gboolean collate_flag,
573 gboolean outline_flag,
574 gboolean reverse_flag,
575 gboolean crop_marks_flag)
580 job = gnome_print_job_new (config);
581 flags.outline = outline_flag;
582 flags.reverse = reverse_flag;
583 flags.crop_marks = crop_marks_flag;
584 if ( collate_flag ) {
585 gl_print_merge_collated (job, label, n_copies, first, &flags);
587 gl_print_merge_uncollated (job, label, n_copies, first, &flags);
589 gnome_print_job_close (job);
592 GtkWidget *preview_widget =
593 gnome_print_job_preview_new (job, _("Print preview"));
594 gtk_widget_show (GTK_WIDGET (preview_widget));
596 gnome_print_job_print (job);
599 g_object_unref (G_OBJECT (job));
602 /*****************************************************************************/
603 /* Set outline flag/checkbox. */
604 /*****************************************************************************/
606 gl_print_dialog_force_outline_flag (glPrintDialog *dialog)
608 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(dialog->priv->outline_check),
611 gtk_widget_set_sensitive (dialog->priv->outline_check, FALSE);
612 gtk_widget_set_sensitive (dialog->priv->reverse_check, FALSE);
613 gtk_widget_set_sensitive (dialog->priv->crop_marks_check, FALSE);