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>
38 #include "wdgt-print-copies.h"
39 #include "wdgt-print-merge.h"
43 /*===========================================*/
44 /* Private data types */
45 /*===========================================*/
47 struct _glPrintOpPrivate {
53 GtkWidget *simple_frame;
54 GtkWidget *copies_vbox;
57 GtkWidget *merge_frame;
58 GtkWidget *prmerge_vbox;
61 GtkWidget *outline_check;
62 GtkWidget *reverse_check;
63 GtkWidget *crop_marks_check;
65 gboolean force_outline_flag;
69 gboolean outline_flag;
70 gboolean reverse_flag;
71 gboolean crop_marks_flag;
73 gboolean collate_flag;
83 typedef struct _glPrintOpSettings
86 GtkPrintSettings *gtk_settings;
88 gboolean outline_flag;
89 gboolean reverse_flag;
90 gboolean crop_marks_flag;
91 gboolean collate_flag;
101 /*===========================================*/
102 /* Private globals */
103 /*===========================================*/
105 /*===========================================*/
106 /* Local function prototypes */
107 /*===========================================*/
109 static void gl_print_op_finalize (GObject *object);
111 static void gl_print_op_construct (glPrintOp *op,
114 static void gl_print_op_construct_batch (glPrintOp *op,
120 gboolean outline_flag,
121 gboolean reverse_flag,
122 gboolean crop_marks_flag);
125 static GObject *create_custom_widget_cb (GtkPrintOperation *operation,
128 static void custom_widget_apply_cb (GtkPrintOperation *operation,
132 static void begin_print_cb (GtkPrintOperation *operation,
133 GtkPrintContext *context,
136 static void draw_page_cb (GtkPrintOperation *operation,
137 GtkPrintContext *context,
144 /*****************************************************************************/
145 /* Boilerplate object stuff. */
146 /*****************************************************************************/
147 G_DEFINE_TYPE (glPrintOp, gl_print_op, GTK_TYPE_PRINT_OPERATION);
150 gl_print_op_class_init (glPrintOpClass *class)
152 GObjectClass *object_class = G_OBJECT_CLASS (class);
154 gl_debug (DEBUG_PRINT, "");
156 gl_print_op_parent_class = g_type_class_peek_parent (class);
158 object_class->finalize = gl_print_op_finalize;
162 gl_print_op_init (glPrintOp *op)
164 gl_debug (DEBUG_PRINT, "");
166 gtk_print_operation_set_use_full_page (GTK_PRINT_OPERATION (op), TRUE);
168 gtk_print_operation_set_unit (GTK_PRINT_OPERATION (op), GTK_UNIT_POINTS);
170 op->priv = g_new0 (glPrintOpPrivate, 1);
175 gl_print_op_finalize (GObject *object)
177 glPrintOp* op = GL_PRINT_OP (object);
179 gl_debug (DEBUG_PRINT, "");
181 g_return_if_fail (object != NULL);
182 g_return_if_fail (GL_IS_PRINT_OP (op));
183 g_return_if_fail (op->priv != NULL);
185 if (op->priv->label) {
186 g_object_unref (G_OBJECT(op->priv->label));
188 g_free (op->priv->filename);
191 G_OBJECT_CLASS (gl_print_op_parent_class)->finalize (object);
196 /*****************************************************************************/
198 /*****************************************************************************/
200 gl_print_op_new (glLabel *label)
204 gl_debug (DEBUG_PRINT, "");
206 op = GL_PRINT_OP (g_object_new (GL_TYPE_PRINT_OP, NULL));
208 gl_print_op_construct (GL_PRINT_OP(op), label);
213 /*--------------------------------------------------------------------------*/
214 /* PRIVATE. Construct op. */
215 /*--------------------------------------------------------------------------*/
217 gl_print_op_construct (glPrintOp *op,
220 const glTemplateLabelType *label_type;
222 op->priv->label = label;
223 op->priv->force_outline_flag = FALSE;
225 label_type = gl_template_get_first_label_type (label->template);
227 op->priv->n_sheets = 1;
229 op->priv->last = gl_template_get_n_labels (label_type);
230 op->priv->n_copies = 1;
232 gtk_print_operation_set_custom_tab_label ( GTK_PRINT_OPERATION (op),
235 g_signal_connect (G_OBJECT (op), "create-custom-widget",
236 G_CALLBACK (create_custom_widget_cb), label);
238 g_signal_connect (G_OBJECT (op), "custom-widget-apply",
239 G_CALLBACK (custom_widget_apply_cb), label);
241 g_signal_connect (G_OBJECT (op), "begin-print",
242 G_CALLBACK (begin_print_cb), label);
244 g_signal_connect (G_OBJECT (op), "draw-page",
245 G_CALLBACK (draw_page_cb), label);
248 /*****************************************************************************/
249 /* NEW batch print operation. */
250 /*****************************************************************************/
252 gl_print_op_new_batch (glLabel *label,
257 gboolean outline_flag,
258 gboolean reverse_flag,
259 gboolean crop_marks_flag)
263 gl_debug (DEBUG_PRINT, "");
265 op = GL_PRINT_OP (g_object_new (GL_TYPE_PRINT_OP, NULL));
267 gl_print_op_construct_batch (GL_PRINT_OP(op),
280 /*****************************************************************************/
281 /* Get print operation settings. */
282 /*****************************************************************************/
284 gl_print_op_get_settings (glPrintOp *print_op)
286 glPrintOpSettings *settings;
288 settings = g_new0 (glPrintOpSettings, 1);
292 settings->gtk_settings =
293 gtk_print_operation_get_print_settings (GTK_PRINT_OPERATION (print_op));
295 settings->outline_flag = print_op->priv->outline_flag;
296 settings->reverse_flag = print_op->priv->reverse_flag;
297 settings->crop_marks_flag = print_op->priv->crop_marks_flag;
298 settings->collate_flag = print_op->priv->collate_flag;
300 settings->first = print_op->priv->first;
301 settings->last = print_op->priv->last;
302 settings->n_sheets = print_op->priv->n_sheets;
303 settings->n_copies = print_op->priv->n_copies;
309 /*****************************************************************************/
310 /* Set print operation settings. */
311 /*****************************************************************************/
313 gl_print_op_set_settings (glPrintOp *print_op,
314 glPrintOpSettings *settings)
319 gtk_print_operation_set_print_settings (GTK_PRINT_OPERATION (print_op),
320 settings->gtk_settings);
322 print_op->priv->outline_flag = settings->outline_flag;
323 print_op->priv->reverse_flag = settings->reverse_flag;
324 print_op->priv->crop_marks_flag = settings->crop_marks_flag;
325 print_op->priv->collate_flag = settings->collate_flag;
327 print_op->priv->first = settings->first;
328 print_op->priv->last = settings->last;
329 print_op->priv->n_sheets = settings->n_sheets;
330 print_op->priv->n_copies = settings->n_copies;
335 /*****************************************************************************/
336 /* Free print operation settings structure. */
337 /*****************************************************************************/
339 gl_print_op_free_settings(glPrintOpSettings *settings)
344 if ( settings->gtk_settings )
346 g_object_unref (settings->gtk_settings);
353 /*--------------------------------------------------------------------------*/
354 /* PRIVATE. Construct op. */
355 /*--------------------------------------------------------------------------*/
357 gl_print_op_construct_batch (glPrintOp *op,
363 gboolean outline_flag,
364 gboolean reverse_flag,
365 gboolean crop_marks_flag)
368 glMerge *merge = NULL;
369 const glTemplateLabelType *label_type = NULL;
371 op->priv->label = label;
372 op->priv->force_outline_flag = FALSE;
373 op->priv->filename = g_strdup (filename);
374 op->priv->n_sheets = n_sheets;
375 op->priv->n_copies = n_copies;
376 op->priv->first = first;
377 op->priv->outline_flag = outline_flag;
378 op->priv->reverse_flag = reverse_flag;
379 op->priv->crop_marks_flag = crop_marks_flag;
381 merge = gl_label_get_merge (label);
383 label_type = gl_template_get_first_label_type (label->template);
386 op->priv->merge_flag = FALSE;
388 op->priv->last = gl_template_get_n_labels (label_type);
393 op->priv->merge_flag = TRUE;
396 ceil ((double)(first-1 + n_copies * gl_merge_get_record_count(merge))
397 / gl_template_get_n_labels (label_type));;
399 g_object_unref (G_OBJECT(merge));
403 gtk_print_operation_set_export_filename (GTK_PRINT_OPERATION (op),
406 g_signal_connect (G_OBJECT (op), "begin-print",
407 G_CALLBACK (begin_print_cb), label);
409 g_signal_connect (G_OBJECT (op), "draw-page",
410 G_CALLBACK (draw_page_cb), label);
413 /*--------------------------------------------------------------------------*/
414 /* PRIVATE. "Create custom widget" callback */
415 /*--------------------------------------------------------------------------*/
417 create_custom_widget_cb (GtkPrintOperation *operation,
420 glPrintOp *op = GL_PRINT_OP (operation);
421 glLabel *label = GL_LABEL (user_data);
425 glMerge *merge = NULL;
427 op->priv->gui = glade_xml_new (GLABELS_GLADE_DIR "print-custom-widget.glade",
428 "print_custom_widget_vbox",
431 if (!op->priv->gui) {
432 g_warning ("Could not open print-op.glade, reinstall glabels!");
436 vbox = glade_xml_get_widget (op->priv->gui, "print_custom_widget_vbox");
438 /* ----- Simple print control ----- */
439 op->priv->simple_frame = glade_xml_get_widget (op->priv->gui,
441 op->priv->copies_vbox = glade_xml_get_widget (op->priv->gui,
443 op->priv->copies = gl_wdgt_print_copies_new (label);
444 gtk_box_pack_start (GTK_BOX(op->priv->copies_vbox),
445 op->priv->copies, FALSE, FALSE, 0);
447 /* ----- Merge print control ----- */
448 op->priv->merge_frame = glade_xml_get_widget (op->priv->gui,
450 op->priv->prmerge_vbox = glade_xml_get_widget (op->priv->gui,
452 op->priv->prmerge = gl_wdgt_print_merge_new (label);
453 gtk_box_pack_start (GTK_BOX(op->priv->prmerge_vbox),
454 op->priv->prmerge, FALSE, FALSE, 0);
456 /* ----- Options ----------------- */
457 op->priv->outline_check = glade_xml_get_widget (op->priv->gui,
459 op->priv->reverse_check = glade_xml_get_widget (op->priv->gui,
461 op->priv->crop_marks_check = glade_xml_get_widget (op->priv->gui,
464 /* ---- Activate either simple or merge print control widgets. ---- */
465 merge = gl_label_get_merge (op->priv->label);
468 gl_wdgt_print_copies_set_range (GL_WDGT_PRINT_COPIES (op->priv->copies),
473 gtk_widget_show_all (op->priv->simple_frame);
474 gtk_widget_hide_all (op->priv->merge_frame);
478 gint n_records = gl_merge_get_record_count( merge );
479 gl_wdgt_print_merge_set_copies (GL_WDGT_PRINT_MERGE (op->priv->prmerge),
483 op->priv->collate_flag);
484 g_object_unref (G_OBJECT(merge));
486 gtk_widget_hide_all (op->priv->simple_frame);
487 gtk_widget_show_all (op->priv->merge_frame);
490 /* --- Do we need to force the outline flag --- */
491 if (op->priv->force_outline_flag)
493 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(op->priv->outline_check),
496 gtk_widget_set_sensitive (op->priv->outline_check, FALSE);
497 gtk_widget_set_sensitive (op->priv->reverse_check, FALSE);
498 gtk_widget_set_sensitive (op->priv->crop_marks_check, FALSE);
501 /* --- Set options --- */
502 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (op->priv->outline_check),
503 op->priv->outline_flag);
504 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (op->priv->reverse_check),
505 op->priv->reverse_flag);
506 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (op->priv->crop_marks_check),
507 op->priv->crop_marks_flag);
509 return G_OBJECT (vbox);
512 /*--------------------------------------------------------------------------*/
513 /* PRIVATE. "Custom widget apply" callback */
514 /*--------------------------------------------------------------------------*/
516 custom_widget_apply_cb (GtkPrintOperation *operation,
520 glPrintOp *op = GL_PRINT_OP (operation);
521 glMerge *merge = NULL;
524 op->priv->outline_flag =
525 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
526 (op->priv->outline_check));
527 op->priv->reverse_flag =
528 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
529 (op->priv->reverse_check));
530 op->priv->crop_marks_flag =
531 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
532 (op->priv->crop_marks_check));
534 merge = gl_label_get_merge (op->priv->label);
539 op->priv->merge_flag = FALSE;
540 gl_wdgt_print_copies_get_range (GL_WDGT_PRINT_COPIES (op->priv->copies),
548 op->priv->merge_flag = TRUE;
549 gl_wdgt_print_merge_get_copies (GL_WDGT_PRINT_MERGE (op->priv->prmerge),
552 &op->priv->collate_flag,
553 &op->priv->n_sheets);
554 g_object_unref (G_OBJECT(merge));
559 /*--------------------------------------------------------------------------*/
560 /* PRIVATE. "Begin print" callback */
561 /*--------------------------------------------------------------------------*/
563 begin_print_cb (GtkPrintOperation *operation,
564 GtkPrintContext *context,
567 glPrintOp *op = GL_PRINT_OP (operation);
569 gtk_print_operation_set_n_pages (operation, op->priv->n_sheets);
573 /*--------------------------------------------------------------------------*/
574 /* PRIVATE. "Draw page" callback. */
575 /*--------------------------------------------------------------------------*/
577 draw_page_cb (GtkPrintOperation *operation,
578 GtkPrintContext *context,
582 glPrintOp *op = GL_PRINT_OP (operation);
585 cr = gtk_print_context_get_cairo_context (context);
587 if (!op->priv->merge_flag)
589 gl_print_simple_sheet (op->priv->label,
595 op->priv->outline_flag,
596 op->priv->reverse_flag,
597 op->priv->crop_marks_flag);
601 if (op->priv->collate_flag)
603 gl_print_collated_merge_sheet (op->priv->label,
608 op->priv->outline_flag,
609 op->priv->reverse_flag,
610 op->priv->crop_marks_flag,
615 gl_print_uncollated_merge_sheet (op->priv->label,
620 op->priv->outline_flag,
621 op->priv->reverse_flag,
622 op->priv->crop_marks_flag,
629 /*****************************************************************************/
630 /* Set outline flag/checkbox. */
631 /*****************************************************************************/
633 gl_print_op_force_outline_flag (glPrintOp *op)
635 op->priv->force_outline_flag = TRUE;