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 {
51 GtkWidget *simple_frame;
52 GtkWidget *copies_vbox;
55 GtkWidget *merge_frame;
56 GtkWidget *prmerge_vbox;
59 GtkWidget *outline_check;
60 GtkWidget *reverse_check;
61 GtkWidget *crop_marks_check;
63 gboolean force_outline_flag;
67 gboolean outline_flag;
68 gboolean reverse_flag;
69 gboolean crop_marks_flag;
71 gboolean collate_flag;
81 struct _glPrintOpSettings
84 GtkPrintSettings *gtk_settings;
86 gboolean outline_flag;
87 gboolean reverse_flag;
88 gboolean crop_marks_flag;
89 gboolean collate_flag;
99 /*===========================================*/
100 /* Private globals */
101 /*===========================================*/
103 /*===========================================*/
104 /* Local function prototypes */
105 /*===========================================*/
107 static void gl_print_op_finalize (GObject *object);
109 static void gl_print_op_construct (glPrintOp *op,
112 static void gl_print_op_construct_batch (glPrintOp *op,
118 gboolean outline_flag,
119 gboolean reverse_flag,
120 gboolean crop_marks_flag);
123 static GObject *create_custom_widget_cb (GtkPrintOperation *operation,
126 static void custom_widget_apply_cb (GtkPrintOperation *operation,
130 static void begin_print_cb (GtkPrintOperation *operation,
131 GtkPrintContext *context,
134 static void draw_page_cb (GtkPrintOperation *operation,
135 GtkPrintContext *context,
142 /*****************************************************************************/
143 /* Boilerplate object stuff. */
144 /*****************************************************************************/
145 G_DEFINE_TYPE (glPrintOp, gl_print_op, GTK_TYPE_PRINT_OPERATION);
148 gl_print_op_class_init (glPrintOpClass *class)
150 GObjectClass *object_class = G_OBJECT_CLASS (class);
152 gl_debug (DEBUG_PRINT, "");
154 gl_print_op_parent_class = g_type_class_peek_parent (class);
156 object_class->finalize = gl_print_op_finalize;
160 gl_print_op_init (glPrintOp *op)
162 gl_debug (DEBUG_PRINT, "");
164 gtk_print_operation_set_use_full_page (GTK_PRINT_OPERATION (op), TRUE);
166 gtk_print_operation_set_unit (GTK_PRINT_OPERATION (op), GTK_UNIT_POINTS);
168 op->priv = g_new0 (glPrintOpPrivate, 1);
173 gl_print_op_finalize (GObject *object)
175 glPrintOp* op = GL_PRINT_OP (object);
177 gl_debug (DEBUG_PRINT, "");
179 g_return_if_fail (object != NULL);
180 g_return_if_fail (GL_IS_PRINT_OP (op));
181 g_return_if_fail (op->priv != NULL);
183 if (op->priv->label) {
184 g_object_unref (G_OBJECT(op->priv->label));
186 g_free (op->priv->filename);
189 G_OBJECT_CLASS (gl_print_op_parent_class)->finalize (object);
194 /*****************************************************************************/
196 /*****************************************************************************/
198 gl_print_op_new (glLabel *label)
202 gl_debug (DEBUG_PRINT, "");
204 op = GL_PRINT_OP (g_object_new (GL_TYPE_PRINT_OP, NULL));
206 gl_print_op_construct (GL_PRINT_OP(op), label);
211 /*--------------------------------------------------------------------------*/
212 /* PRIVATE. Construct op. */
213 /*--------------------------------------------------------------------------*/
215 gl_print_op_construct (glPrintOp *op,
218 const glTemplateLabelType *label_type;
220 op->priv->label = label;
221 op->priv->force_outline_flag = FALSE;
223 label_type = gl_template_get_first_label_type (label->template);
225 op->priv->n_sheets = 1;
227 op->priv->last = gl_template_get_n_labels (label_type);
228 op->priv->n_copies = 1;
230 gtk_print_operation_set_custom_tab_label ( GTK_PRINT_OPERATION (op),
233 g_signal_connect (G_OBJECT (op), "create-custom-widget",
234 G_CALLBACK (create_custom_widget_cb), label);
236 g_signal_connect (G_OBJECT (op), "custom-widget-apply",
237 G_CALLBACK (custom_widget_apply_cb), label);
239 g_signal_connect (G_OBJECT (op), "begin-print",
240 G_CALLBACK (begin_print_cb), label);
242 g_signal_connect (G_OBJECT (op), "draw-page",
243 G_CALLBACK (draw_page_cb), label);
246 /*****************************************************************************/
247 /* NEW batch print operation. */
248 /*****************************************************************************/
250 gl_print_op_new_batch (glLabel *label,
255 gboolean outline_flag,
256 gboolean reverse_flag,
257 gboolean crop_marks_flag)
261 gl_debug (DEBUG_PRINT, "");
263 op = GL_PRINT_OP (g_object_new (GL_TYPE_PRINT_OP, NULL));
265 gl_print_op_construct_batch (GL_PRINT_OP(op),
278 /*****************************************************************************/
279 /* Get print operation settings. */
280 /*****************************************************************************/
282 gl_print_op_get_settings (glPrintOp *print_op)
284 glPrintOpSettings *settings;
286 settings = g_new0 (glPrintOpSettings, 1);
290 settings->gtk_settings =
291 gtk_print_operation_get_print_settings (GTK_PRINT_OPERATION (print_op));
293 settings->outline_flag = print_op->priv->outline_flag;
294 settings->reverse_flag = print_op->priv->reverse_flag;
295 settings->crop_marks_flag = print_op->priv->crop_marks_flag;
296 settings->collate_flag = print_op->priv->collate_flag;
298 settings->first = print_op->priv->first;
299 settings->last = print_op->priv->last;
300 settings->n_sheets = print_op->priv->n_sheets;
301 settings->n_copies = print_op->priv->n_copies;
307 /*****************************************************************************/
308 /* Set print operation settings. */
309 /*****************************************************************************/
311 gl_print_op_set_settings (glPrintOp *print_op,
312 glPrintOpSettings *settings)
317 gtk_print_operation_set_print_settings (GTK_PRINT_OPERATION (print_op),
318 settings->gtk_settings);
320 print_op->priv->outline_flag = settings->outline_flag;
321 print_op->priv->reverse_flag = settings->reverse_flag;
322 print_op->priv->crop_marks_flag = settings->crop_marks_flag;
323 print_op->priv->collate_flag = settings->collate_flag;
325 print_op->priv->first = settings->first;
326 print_op->priv->last = settings->last;
327 print_op->priv->n_sheets = settings->n_sheets;
328 print_op->priv->n_copies = settings->n_copies;
333 /*****************************************************************************/
334 /* Free print operation settings structure. */
335 /*****************************************************************************/
337 gl_print_op_free_settings(glPrintOpSettings *settings)
342 if ( settings->gtk_settings )
344 g_object_unref (settings->gtk_settings);
351 /*--------------------------------------------------------------------------*/
352 /* PRIVATE. Construct op. */
353 /*--------------------------------------------------------------------------*/
355 gl_print_op_construct_batch (glPrintOp *op,
361 gboolean outline_flag,
362 gboolean reverse_flag,
363 gboolean crop_marks_flag)
366 glMerge *merge = NULL;
367 const glTemplateLabelType *label_type = NULL;
369 op->priv->label = label;
370 op->priv->force_outline_flag = FALSE;
371 op->priv->filename = g_strdup (filename);
372 op->priv->n_sheets = n_sheets;
373 op->priv->n_copies = n_copies;
374 op->priv->first = first;
375 op->priv->outline_flag = outline_flag;
376 op->priv->reverse_flag = reverse_flag;
377 op->priv->crop_marks_flag = crop_marks_flag;
379 merge = gl_label_get_merge (label);
381 label_type = gl_template_get_first_label_type (label->template);
384 op->priv->merge_flag = FALSE;
386 op->priv->last = gl_template_get_n_labels (label_type);
391 op->priv->merge_flag = TRUE;
394 ceil ((double)(first-1 + n_copies * gl_merge_get_record_count(merge))
395 / gl_template_get_n_labels (label_type));;
397 g_object_unref (G_OBJECT(merge));
401 gtk_print_operation_set_export_filename (GTK_PRINT_OPERATION (op),
404 g_signal_connect (G_OBJECT (op), "begin-print",
405 G_CALLBACK (begin_print_cb), label);
407 g_signal_connect (G_OBJECT (op), "draw-page",
408 G_CALLBACK (draw_page_cb), label);
411 /*--------------------------------------------------------------------------*/
412 /* PRIVATE. "Create custom widget" callback */
413 /*--------------------------------------------------------------------------*/
415 create_custom_widget_cb (GtkPrintOperation *operation,
419 glPrintOp *op = GL_PRINT_OP (operation);
420 glLabel *label = GL_LABEL (user_data);
422 glMerge *merge = NULL;
424 gui = glade_xml_new (GLABELS_GLADE_DIR "print-custom-widget.glade",
425 "print_custom_widget_vbox", NULL);
428 g_warning ("Could not open print-op.glade, reinstall glabels!");
432 vbox = glade_xml_get_widget (gui, "print_custom_widget_vbox");
434 /* ----- Simple print control ----- */
435 op->priv->simple_frame = glade_xml_get_widget (gui, "simple_frame");
436 op->priv->copies_vbox = glade_xml_get_widget (gui, "copies_vbox");
437 op->priv->copies = gl_wdgt_print_copies_new (label);
438 gtk_box_pack_start (GTK_BOX(op->priv->copies_vbox),
439 op->priv->copies, FALSE, FALSE, 0);
441 /* ----- Merge print control ----- */
442 op->priv->merge_frame = glade_xml_get_widget (gui, "merge_frame");
443 op->priv->prmerge_vbox = glade_xml_get_widget (gui, "prmerge_vbox");
444 op->priv->prmerge = gl_wdgt_print_merge_new (label);
445 gtk_box_pack_start (GTK_BOX(op->priv->prmerge_vbox),
446 op->priv->prmerge, FALSE, FALSE, 0);
448 /* ----- Options ----------------- */
449 op->priv->outline_check = glade_xml_get_widget (gui, "outline_check");
450 op->priv->reverse_check = glade_xml_get_widget (gui, "reverse_check");
451 op->priv->crop_marks_check = glade_xml_get_widget (gui, "crop_marks_check");
453 g_object_unref (gui);
455 /* ---- Activate either simple or merge print control widgets. ---- */
456 merge = gl_label_get_merge (op->priv->label);
459 gl_wdgt_print_copies_set_range (GL_WDGT_PRINT_COPIES (op->priv->copies),
464 gtk_widget_show_all (op->priv->simple_frame);
465 gtk_widget_hide_all (op->priv->merge_frame);
469 gint n_records = gl_merge_get_record_count( merge );
470 gl_wdgt_print_merge_set_copies (GL_WDGT_PRINT_MERGE (op->priv->prmerge),
474 op->priv->collate_flag);
475 g_object_unref (G_OBJECT(merge));
477 gtk_widget_hide_all (op->priv->simple_frame);
478 gtk_widget_show_all (op->priv->merge_frame);
481 /* --- Set options --- */
482 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (op->priv->outline_check),
483 op->priv->outline_flag);
484 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (op->priv->reverse_check),
485 op->priv->reverse_flag);
486 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (op->priv->crop_marks_check),
487 op->priv->crop_marks_flag);
489 /* --- Do we need to force the outline flag --- */
490 if (op->priv->force_outline_flag)
492 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(op->priv->outline_check),
495 gtk_widget_set_sensitive (op->priv->outline_check, FALSE);
496 gtk_widget_set_sensitive (op->priv->reverse_check, FALSE);
497 gtk_widget_set_sensitive (op->priv->crop_marks_check, FALSE);
500 return G_OBJECT (vbox);
503 /*--------------------------------------------------------------------------*/
504 /* PRIVATE. "Custom widget apply" callback */
505 /*--------------------------------------------------------------------------*/
507 custom_widget_apply_cb (GtkPrintOperation *operation,
511 glPrintOp *op = GL_PRINT_OP (operation);
512 glMerge *merge = NULL;
515 op->priv->outline_flag =
516 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
517 (op->priv->outline_check));
518 op->priv->reverse_flag =
519 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
520 (op->priv->reverse_check));
521 op->priv->crop_marks_flag =
522 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
523 (op->priv->crop_marks_check));
525 merge = gl_label_get_merge (op->priv->label);
530 op->priv->merge_flag = FALSE;
531 gl_wdgt_print_copies_get_range (GL_WDGT_PRINT_COPIES (op->priv->copies),
539 op->priv->merge_flag = TRUE;
540 gl_wdgt_print_merge_get_copies (GL_WDGT_PRINT_MERGE (op->priv->prmerge),
543 &op->priv->collate_flag,
544 &op->priv->n_sheets);
545 g_object_unref (G_OBJECT(merge));
550 /*--------------------------------------------------------------------------*/
551 /* PRIVATE. "Begin print" callback */
552 /*--------------------------------------------------------------------------*/
554 begin_print_cb (GtkPrintOperation *operation,
555 GtkPrintContext *context,
558 glPrintOp *op = GL_PRINT_OP (operation);
560 gtk_print_operation_set_n_pages (operation, op->priv->n_sheets);
564 /*--------------------------------------------------------------------------*/
565 /* PRIVATE. "Draw page" callback. */
566 /*--------------------------------------------------------------------------*/
568 draw_page_cb (GtkPrintOperation *operation,
569 GtkPrintContext *context,
573 glPrintOp *op = GL_PRINT_OP (operation);
576 cr = gtk_print_context_get_cairo_context (context);
578 if (!op->priv->merge_flag)
580 gl_print_simple_sheet (op->priv->label,
586 op->priv->outline_flag,
587 op->priv->reverse_flag,
588 op->priv->crop_marks_flag);
592 if (op->priv->collate_flag)
594 gl_print_collated_merge_sheet (op->priv->label,
599 op->priv->outline_flag,
600 op->priv->reverse_flag,
601 op->priv->crop_marks_flag,
606 gl_print_uncollated_merge_sheet (op->priv->label,
611 op->priv->outline_flag,
612 op->priv->reverse_flag,
613 op->priv->crop_marks_flag,
620 /*****************************************************************************/
621 /* Set outline flag/checkbox. */
622 /*****************************************************************************/
624 gl_print_op_force_outline_flag (glPrintOp *op)
626 op->priv->force_outline_flag = TRUE;