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 * print-op.c: Print operation module
8 * Copyright (C) 2001-2007 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
28 #include <glib/gi18n.h>
29 #include <glade/glade-xml.h>
33 #include <gtk/gtktogglebutton.h>
35 #include <libglabels/db.h>
39 #include "wdgt-print-copies.h"
40 #include "wdgt-print-merge.h"
44 /*===========================================*/
45 /* Private data types */
46 /*===========================================*/
48 struct _glPrintOpPrivate {
52 GtkWidget *simple_frame;
53 GtkWidget *copies_vbox;
56 GtkWidget *merge_frame;
57 GtkWidget *prmerge_vbox;
60 GtkWidget *outline_check;
61 GtkWidget *reverse_check;
62 GtkWidget *crop_marks_check;
64 gboolean force_outline_flag;
68 gboolean outline_flag;
69 gboolean reverse_flag;
70 gboolean crop_marks_flag;
72 gboolean collate_flag;
82 struct _glPrintOpSettings
85 GtkPrintSettings *gtk_settings;
87 gboolean outline_flag;
88 gboolean reverse_flag;
89 gboolean crop_marks_flag;
90 gboolean collate_flag;
100 /*===========================================*/
101 /* Private globals */
102 /*===========================================*/
104 /*===========================================*/
105 /* Local function prototypes */
106 /*===========================================*/
108 static void gl_print_op_finalize (GObject *object);
110 static void gl_print_op_construct (glPrintOp *op,
113 static void gl_print_op_construct_batch (glPrintOp *op,
119 gboolean outline_flag,
120 gboolean reverse_flag,
121 gboolean crop_marks_flag);
124 static void set_page_size (glPrintOp *op,
127 static GObject *create_custom_widget_cb (GtkPrintOperation *operation,
130 static void custom_widget_apply_cb (GtkPrintOperation *operation,
134 static void begin_print_cb (GtkPrintOperation *operation,
135 GtkPrintContext *context,
138 static void draw_page_cb (GtkPrintOperation *operation,
139 GtkPrintContext *context,
146 /*****************************************************************************/
147 /* Boilerplate object stuff. */
148 /*****************************************************************************/
149 G_DEFINE_TYPE (glPrintOp, gl_print_op, GTK_TYPE_PRINT_OPERATION);
152 gl_print_op_class_init (glPrintOpClass *class)
154 GObjectClass *object_class = G_OBJECT_CLASS (class);
156 gl_debug (DEBUG_PRINT, "");
158 gl_print_op_parent_class = g_type_class_peek_parent (class);
160 object_class->finalize = gl_print_op_finalize;
164 gl_print_op_init (glPrintOp *op)
166 gl_debug (DEBUG_PRINT, "");
168 gtk_print_operation_set_use_full_page (GTK_PRINT_OPERATION (op), TRUE);
170 gtk_print_operation_set_unit (GTK_PRINT_OPERATION (op), GTK_UNIT_POINTS);
172 op->priv = g_new0 (glPrintOpPrivate, 1);
177 gl_print_op_finalize (GObject *object)
179 glPrintOp* op = GL_PRINT_OP (object);
181 gl_debug (DEBUG_PRINT, "");
183 g_return_if_fail (object != NULL);
184 g_return_if_fail (GL_IS_PRINT_OP (op));
185 g_return_if_fail (op->priv != NULL);
187 if (op->priv->label) {
188 g_object_unref (G_OBJECT(op->priv->label));
190 g_free (op->priv->filename);
193 G_OBJECT_CLASS (gl_print_op_parent_class)->finalize (object);
198 /*****************************************************************************/
200 /*****************************************************************************/
202 gl_print_op_new (glLabel *label)
206 gl_debug (DEBUG_PRINT, "");
208 op = GL_PRINT_OP (g_object_new (GL_TYPE_PRINT_OP, NULL));
210 gl_print_op_construct (GL_PRINT_OP(op), label);
215 /*--------------------------------------------------------------------------*/
216 /* PRIVATE. Construct op. */
217 /*--------------------------------------------------------------------------*/
219 gl_print_op_construct (glPrintOp *op,
222 const lglTemplateFrame *frame;
224 op->priv->label = label;
225 op->priv->force_outline_flag = FALSE;
227 frame = (lglTemplateFrame *)label->template->frames->data;
229 op->priv->n_sheets = 1;
231 op->priv->last = lgl_template_frame_get_n_labels (frame);
232 op->priv->n_copies = 1;
234 set_page_size (op, label);
236 gtk_print_operation_set_custom_tab_label ( GTK_PRINT_OPERATION (op),
239 g_signal_connect (G_OBJECT (op), "create-custom-widget",
240 G_CALLBACK (create_custom_widget_cb), label);
242 g_signal_connect (G_OBJECT (op), "custom-widget-apply",
243 G_CALLBACK (custom_widget_apply_cb), label);
245 g_signal_connect (G_OBJECT (op), "begin-print",
246 G_CALLBACK (begin_print_cb), label);
248 g_signal_connect (G_OBJECT (op), "draw-page",
249 G_CALLBACK (draw_page_cb), label);
252 /*****************************************************************************/
253 /* NEW batch print operation. */
254 /*****************************************************************************/
256 gl_print_op_new_batch (glLabel *label,
261 gboolean outline_flag,
262 gboolean reverse_flag,
263 gboolean crop_marks_flag)
267 gl_debug (DEBUG_PRINT, "");
269 op = GL_PRINT_OP (g_object_new (GL_TYPE_PRINT_OP, NULL));
271 gl_print_op_construct_batch (GL_PRINT_OP(op),
284 /*****************************************************************************/
285 /* Get print operation settings. */
286 /*****************************************************************************/
288 gl_print_op_get_settings (glPrintOp *print_op)
290 glPrintOpSettings *settings;
292 settings = g_new0 (glPrintOpSettings, 1);
296 settings->gtk_settings =
297 gtk_print_operation_get_print_settings (GTK_PRINT_OPERATION (print_op));
299 settings->outline_flag = print_op->priv->outline_flag;
300 settings->reverse_flag = print_op->priv->reverse_flag;
301 settings->crop_marks_flag = print_op->priv->crop_marks_flag;
302 settings->collate_flag = print_op->priv->collate_flag;
304 settings->first = print_op->priv->first;
305 settings->last = print_op->priv->last;
306 settings->n_sheets = print_op->priv->n_sheets;
307 settings->n_copies = print_op->priv->n_copies;
313 /*****************************************************************************/
314 /* Set print operation settings. */
315 /*****************************************************************************/
317 gl_print_op_set_settings (glPrintOp *print_op,
318 glPrintOpSettings *settings)
323 gtk_print_operation_set_print_settings (GTK_PRINT_OPERATION (print_op),
324 settings->gtk_settings);
326 print_op->priv->outline_flag = settings->outline_flag;
327 print_op->priv->reverse_flag = settings->reverse_flag;
328 print_op->priv->crop_marks_flag = settings->crop_marks_flag;
329 print_op->priv->collate_flag = settings->collate_flag;
331 print_op->priv->first = settings->first;
332 print_op->priv->last = settings->last;
333 print_op->priv->n_sheets = settings->n_sheets;
334 print_op->priv->n_copies = settings->n_copies;
339 /*****************************************************************************/
340 /* Free print operation settings structure. */
341 /*****************************************************************************/
343 gl_print_op_free_settings(glPrintOpSettings *settings)
348 if ( settings->gtk_settings )
350 g_object_unref (settings->gtk_settings);
357 /*--------------------------------------------------------------------------*/
358 /* PRIVATE. Construct op. */
359 /*--------------------------------------------------------------------------*/
361 gl_print_op_construct_batch (glPrintOp *op,
367 gboolean outline_flag,
368 gboolean reverse_flag,
369 gboolean crop_marks_flag)
372 glMerge *merge = NULL;
373 const lglTemplateFrame *frame = NULL;
375 op->priv->label = label;
376 op->priv->force_outline_flag = FALSE;
377 op->priv->filename = g_strdup (filename);
378 op->priv->n_sheets = n_sheets;
379 op->priv->n_copies = n_copies;
380 op->priv->first = first;
381 op->priv->outline_flag = outline_flag;
382 op->priv->reverse_flag = reverse_flag;
383 op->priv->crop_marks_flag = crop_marks_flag;
385 merge = gl_label_get_merge (label);
387 frame = (lglTemplateFrame *)label->template->frames->data;
390 op->priv->merge_flag = FALSE;
392 op->priv->last = lgl_template_frame_get_n_labels (frame);
397 op->priv->merge_flag = TRUE;
400 ceil ((double)(first-1 + n_copies * gl_merge_get_record_count(merge))
401 / lgl_template_frame_get_n_labels (frame));;
403 g_object_unref (G_OBJECT(merge));
407 set_page_size (op, label);
409 gtk_print_operation_set_export_filename (GTK_PRINT_OPERATION (op),
412 g_signal_connect (G_OBJECT (op), "begin-print",
413 G_CALLBACK (begin_print_cb), label);
415 g_signal_connect (G_OBJECT (op), "draw-page",
416 G_CALLBACK (draw_page_cb), label);
419 /*--------------------------------------------------------------------------*/
420 /* PRIVATE. Set page size. */
421 /*--------------------------------------------------------------------------*/
423 set_page_size (glPrintOp *op,
430 gl_debug (DEBUG_PRINT, "begin");
432 paper = lgl_db_lookup_paper_from_id (label->template->paper_id);
438 name = gtk_paper_size_get_default ();
439 psize = gtk_paper_size_new (name);
441 gl_debug (DEBUG_PRINT, "Using default size = \"%s\"", name);
443 else if (lgl_db_is_paper_id_other (paper->id))
445 psize = gtk_paper_size_new_custom (paper->id,
447 label->template->page_width,
448 label->template->page_height,
450 gl_debug (DEBUG_PRINT, "Using custom size = %g x %g points",
451 label->template->page_width,
452 label->template->page_height);
457 psize = gtk_paper_size_new (paper->pwg_size);
458 gl_debug (DEBUG_PRINT, "Using PWG size \"%s\"", paper->pwg_size);
460 lgl_paper_free (paper);
462 su = gtk_page_setup_new ();
463 gtk_page_setup_set_paper_size (su, psize);
464 gtk_print_operation_set_default_page_setup (GTK_PRINT_OPERATION (op), su);
467 gtk_paper_size_free (psize);
469 gl_debug (DEBUG_PRINT, "end");
472 /*--------------------------------------------------------------------------*/
473 /* PRIVATE. "Create custom widget" callback */
474 /*--------------------------------------------------------------------------*/
476 create_custom_widget_cb (GtkPrintOperation *operation,
480 glPrintOp *op = GL_PRINT_OP (operation);
481 glLabel *label = GL_LABEL (user_data);
483 glMerge *merge = NULL;
485 gui = glade_xml_new (GLABELS_GLADE_DIR "print-custom-widget.glade",
486 "print_custom_widget_vbox", NULL);
489 g_warning ("Could not open print-op.glade, reinstall glabels!");
493 vbox = glade_xml_get_widget (gui, "print_custom_widget_vbox");
495 /* ----- Simple print control ----- */
496 op->priv->simple_frame = glade_xml_get_widget (gui, "simple_frame");
497 op->priv->copies_vbox = glade_xml_get_widget (gui, "copies_vbox");
498 op->priv->copies = gl_wdgt_print_copies_new (label);
499 gtk_box_pack_start (GTK_BOX(op->priv->copies_vbox),
500 op->priv->copies, FALSE, FALSE, 0);
502 /* ----- Merge print control ----- */
503 op->priv->merge_frame = glade_xml_get_widget (gui, "merge_frame");
504 op->priv->prmerge_vbox = glade_xml_get_widget (gui, "prmerge_vbox");
505 op->priv->prmerge = gl_wdgt_print_merge_new (label);
506 gtk_box_pack_start (GTK_BOX(op->priv->prmerge_vbox),
507 op->priv->prmerge, FALSE, FALSE, 0);
509 /* ----- Options ----------------- */
510 op->priv->outline_check = glade_xml_get_widget (gui, "outline_check");
511 op->priv->reverse_check = glade_xml_get_widget (gui, "reverse_check");
512 op->priv->crop_marks_check = glade_xml_get_widget (gui, "crop_marks_check");
514 g_object_unref (gui);
516 /* ---- Activate either simple or merge print control widgets. ---- */
517 merge = gl_label_get_merge (op->priv->label);
520 gl_wdgt_print_copies_set_range (GL_WDGT_PRINT_COPIES (op->priv->copies),
525 gtk_widget_show_all (op->priv->simple_frame);
526 gtk_widget_hide_all (op->priv->merge_frame);
530 gint n_records = gl_merge_get_record_count( merge );
531 gl_wdgt_print_merge_set_copies (GL_WDGT_PRINT_MERGE (op->priv->prmerge),
535 op->priv->collate_flag);
536 g_object_unref (G_OBJECT(merge));
538 gtk_widget_hide_all (op->priv->simple_frame);
539 gtk_widget_show_all (op->priv->merge_frame);
542 /* --- Set options --- */
543 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (op->priv->outline_check),
544 op->priv->outline_flag);
545 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (op->priv->reverse_check),
546 op->priv->reverse_flag);
547 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (op->priv->crop_marks_check),
548 op->priv->crop_marks_flag);
550 /* --- Do we need to force the outline flag --- */
551 if (op->priv->force_outline_flag)
553 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(op->priv->outline_check),
556 gtk_widget_set_sensitive (op->priv->outline_check, FALSE);
557 gtk_widget_set_sensitive (op->priv->reverse_check, FALSE);
558 gtk_widget_set_sensitive (op->priv->crop_marks_check, FALSE);
561 return G_OBJECT (vbox);
564 /*--------------------------------------------------------------------------*/
565 /* PRIVATE. "Custom widget apply" callback */
566 /*--------------------------------------------------------------------------*/
568 custom_widget_apply_cb (GtkPrintOperation *operation,
572 glPrintOp *op = GL_PRINT_OP (operation);
573 glMerge *merge = NULL;
576 op->priv->outline_flag =
577 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
578 (op->priv->outline_check));
579 op->priv->reverse_flag =
580 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
581 (op->priv->reverse_check));
582 op->priv->crop_marks_flag =
583 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
584 (op->priv->crop_marks_check));
586 merge = gl_label_get_merge (op->priv->label);
591 op->priv->merge_flag = FALSE;
592 gl_wdgt_print_copies_get_range (GL_WDGT_PRINT_COPIES (op->priv->copies),
600 op->priv->merge_flag = TRUE;
601 gl_wdgt_print_merge_get_copies (GL_WDGT_PRINT_MERGE (op->priv->prmerge),
604 &op->priv->collate_flag,
605 &op->priv->n_sheets);
606 g_object_unref (G_OBJECT(merge));
611 /*--------------------------------------------------------------------------*/
612 /* PRIVATE. "Begin print" callback */
613 /*--------------------------------------------------------------------------*/
615 begin_print_cb (GtkPrintOperation *operation,
616 GtkPrintContext *context,
619 glPrintOp *op = GL_PRINT_OP (operation);
621 gtk_print_operation_set_n_pages (operation, op->priv->n_sheets);
625 /*--------------------------------------------------------------------------*/
626 /* PRIVATE. "Draw page" callback. */
627 /*--------------------------------------------------------------------------*/
629 draw_page_cb (GtkPrintOperation *operation,
630 GtkPrintContext *context,
634 glPrintOp *op = GL_PRINT_OP (operation);
637 cr = gtk_print_context_get_cairo_context (context);
639 if (!op->priv->merge_flag)
641 gl_print_simple_sheet (op->priv->label,
647 op->priv->outline_flag,
648 op->priv->reverse_flag,
649 op->priv->crop_marks_flag);
653 if (op->priv->collate_flag)
655 gl_print_collated_merge_sheet (op->priv->label,
660 op->priv->outline_flag,
661 op->priv->reverse_flag,
662 op->priv->crop_marks_flag,
667 gl_print_uncollated_merge_sheet (op->priv->label,
672 op->priv->outline_flag,
673 op->priv->reverse_flag,
674 op->priv->crop_marks_flag,
681 /*****************************************************************************/
682 /* Set outline flag/checkbox. */
683 /*****************************************************************************/
685 gl_print_op_force_outline_flag (glPrintOp *op)
687 op->priv->force_outline_flag = TRUE;