3 * Copyright (C) 2001-2009 Jim Evins <evins@snaught.com>.
5 * This file is part of gLabels.
7 * gLabels is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * gLabels is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
25 #include <glib/gi18n.h>
26 #include <gtk/gtkbuilder.h>
30 #include <gtk/gtktogglebutton.h>
32 #include <libglabels/db.h>
36 #include "wdgt-print-copies.h"
37 #include "wdgt-print-merge.h"
42 /*===========================================*/
43 /* Private data types */
44 /*===========================================*/
46 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 /*===========================================*/
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 void set_page_size (glPrintOp *op,
128 static GObject *create_custom_widget_cb (GtkPrintOperation *operation,
131 static void custom_widget_apply_cb (GtkPrintOperation *operation,
135 static void begin_print_cb (GtkPrintOperation *operation,
136 GtkPrintContext *context,
139 static void draw_page_cb (GtkPrintOperation *operation,
140 GtkPrintContext *context,
145 /*****************************************************************************/
146 /* Boilerplate object stuff. */
147 /*****************************************************************************/
148 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;
165 gl_print_op_init (glPrintOp *op)
167 gl_debug (DEBUG_PRINT, "");
169 gtk_print_operation_set_use_full_page (GTK_PRINT_OPERATION (op), TRUE);
171 gtk_print_operation_set_unit (GTK_PRINT_OPERATION (op), GTK_UNIT_POINTS);
173 op->priv = g_new0 (glPrintOpPrivate, 1);
179 gl_print_op_finalize (GObject *object)
181 glPrintOp *op = GL_PRINT_OP (object);
183 gl_debug (DEBUG_PRINT, "");
185 g_return_if_fail (object != NULL);
186 g_return_if_fail (GL_IS_PRINT_OP (op));
187 g_return_if_fail (op->priv != NULL);
189 if (op->priv->label) {
190 g_object_unref (G_OBJECT(op->priv->label));
192 if (op->priv->builder) {
193 g_object_unref (G_OBJECT(op->priv->builder));
195 g_free (op->priv->filename);
198 G_OBJECT_CLASS (gl_print_op_parent_class)->finalize (object);
204 /*****************************************************************************/
206 /*****************************************************************************/
208 gl_print_op_new (glLabel *label)
212 gl_debug (DEBUG_PRINT, "");
214 op = GL_PRINT_OP (g_object_new (GL_TYPE_PRINT_OP, NULL));
216 gl_print_op_construct (GL_PRINT_OP(op), label);
222 /*--------------------------------------------------------------------------*/
223 /* PRIVATE. Construct op. */
224 /*--------------------------------------------------------------------------*/
226 gl_print_op_construct (glPrintOp *op,
229 const lglTemplateFrame *frame;
231 op->priv->label = label;
232 op->priv->force_outline_flag = FALSE;
234 frame = (lglTemplateFrame *)label->template->frames->data;
236 op->priv->n_sheets = 1;
238 op->priv->last = lgl_template_frame_get_n_labels (frame);
239 op->priv->n_copies = 1;
241 set_page_size (op, label);
243 gtk_print_operation_set_custom_tab_label ( GTK_PRINT_OPERATION (op),
246 g_signal_connect (G_OBJECT (op), "create-custom-widget",
247 G_CALLBACK (create_custom_widget_cb), label);
249 g_signal_connect (G_OBJECT (op), "custom-widget-apply",
250 G_CALLBACK (custom_widget_apply_cb), label);
252 g_signal_connect (G_OBJECT (op), "begin-print",
253 G_CALLBACK (begin_print_cb), label);
255 g_signal_connect (G_OBJECT (op), "draw-page",
256 G_CALLBACK (draw_page_cb), label);
260 /*****************************************************************************/
261 /* NEW batch print operation. */
262 /*****************************************************************************/
264 gl_print_op_new_batch (glLabel *label,
269 gboolean outline_flag,
270 gboolean reverse_flag,
271 gboolean crop_marks_flag)
275 gl_debug (DEBUG_PRINT, "");
277 op = GL_PRINT_OP (g_object_new (GL_TYPE_PRINT_OP, NULL));
279 gl_print_op_construct_batch (GL_PRINT_OP(op),
293 /*****************************************************************************/
294 /* Get print operation settings. */
295 /*****************************************************************************/
297 gl_print_op_get_settings (glPrintOp *print_op)
299 glPrintOpSettings *settings;
301 settings = g_new0 (glPrintOpSettings, 1);
305 settings->gtk_settings =
306 gtk_print_operation_get_print_settings (GTK_PRINT_OPERATION (print_op));
308 settings->outline_flag = print_op->priv->outline_flag;
309 settings->reverse_flag = print_op->priv->reverse_flag;
310 settings->crop_marks_flag = print_op->priv->crop_marks_flag;
311 settings->collate_flag = print_op->priv->collate_flag;
313 settings->first = print_op->priv->first;
314 settings->last = print_op->priv->last;
315 settings->n_sheets = print_op->priv->n_sheets;
316 settings->n_copies = print_op->priv->n_copies;
323 /*****************************************************************************/
324 /* Set print operation settings. */
325 /*****************************************************************************/
327 gl_print_op_set_settings (glPrintOp *print_op,
328 glPrintOpSettings *settings)
333 gtk_print_operation_set_print_settings (GTK_PRINT_OPERATION (print_op),
334 settings->gtk_settings);
336 print_op->priv->outline_flag = settings->outline_flag;
337 print_op->priv->reverse_flag = settings->reverse_flag;
338 print_op->priv->crop_marks_flag = settings->crop_marks_flag;
339 print_op->priv->collate_flag = settings->collate_flag;
341 print_op->priv->first = settings->first;
342 print_op->priv->last = settings->last;
343 print_op->priv->n_sheets = settings->n_sheets;
344 print_op->priv->n_copies = settings->n_copies;
350 /*****************************************************************************/
351 /* Free print operation settings structure. */
352 /*****************************************************************************/
354 gl_print_op_free_settings(glPrintOpSettings *settings)
359 if ( settings->gtk_settings )
361 g_object_unref (settings->gtk_settings);
369 /*--------------------------------------------------------------------------*/
370 /* PRIVATE. Construct op. */
371 /*--------------------------------------------------------------------------*/
373 gl_print_op_construct_batch (glPrintOp *op,
379 gboolean outline_flag,
380 gboolean reverse_flag,
381 gboolean crop_marks_flag)
384 glMerge *merge = NULL;
385 const lglTemplateFrame *frame = NULL;
387 op->priv->label = label;
388 op->priv->force_outline_flag = FALSE;
389 op->priv->filename = g_strdup (filename);
390 op->priv->n_sheets = n_sheets;
391 op->priv->n_copies = n_copies;
392 op->priv->first = first;
393 op->priv->outline_flag = outline_flag;
394 op->priv->reverse_flag = reverse_flag;
395 op->priv->crop_marks_flag = crop_marks_flag;
397 merge = gl_label_get_merge (label);
399 frame = (lglTemplateFrame *)label->template->frames->data;
402 op->priv->merge_flag = FALSE;
404 op->priv->last = lgl_template_frame_get_n_labels (frame);
409 op->priv->merge_flag = TRUE;
412 ceil ((double)(first-1 + n_copies * gl_merge_get_record_count(merge))
413 / lgl_template_frame_get_n_labels (frame));;
415 g_object_unref (G_OBJECT(merge));
419 set_page_size (op, label);
421 gtk_print_operation_set_export_filename (GTK_PRINT_OPERATION (op),
424 g_signal_connect (G_OBJECT (op), "begin-print",
425 G_CALLBACK (begin_print_cb), label);
427 g_signal_connect (G_OBJECT (op), "draw-page",
428 G_CALLBACK (draw_page_cb), label);
432 /*--------------------------------------------------------------------------*/
433 /* PRIVATE. Set page size. */
434 /*--------------------------------------------------------------------------*/
436 set_page_size (glPrintOp *op,
443 gl_debug (DEBUG_PRINT, "begin");
445 paper = lgl_db_lookup_paper_from_id (label->template->paper_id);
451 name = gtk_paper_size_get_default ();
452 psize = gtk_paper_size_new (name);
454 gl_debug (DEBUG_PRINT, "Using default size = \"%s\"", name);
456 else if (lgl_db_is_paper_id_other (paper->id))
458 psize = gtk_paper_size_new_custom (paper->id,
460 label->template->page_width,
461 label->template->page_height,
463 gl_debug (DEBUG_PRINT, "Using custom size = %g x %g points",
464 label->template->page_width,
465 label->template->page_height);
470 psize = gtk_paper_size_new (paper->pwg_size);
471 gl_debug (DEBUG_PRINT, "Using PWG size \"%s\"", paper->pwg_size);
473 lgl_paper_free (paper);
475 su = gtk_page_setup_new ();
476 gtk_page_setup_set_paper_size (su, psize);
477 gtk_print_operation_set_default_page_setup (GTK_PRINT_OPERATION (op), su);
480 gtk_paper_size_free (psize);
482 gl_debug (DEBUG_PRINT, "end");
486 /*--------------------------------------------------------------------------*/
487 /* PRIVATE. "Create custom widget" callback */
488 /*--------------------------------------------------------------------------*/
490 create_custom_widget_cb (GtkPrintOperation *operation,
494 static gchar *object_ids[] = { "print_custom_widget_vbox", NULL };
495 GError *error = NULL;
496 glPrintOp *op = GL_PRINT_OP (operation);
497 glLabel *label = GL_LABEL (user_data);
499 glMerge *merge = NULL;
501 builder = gtk_builder_new ();
502 gtk_builder_add_objects_from_file (builder,
503 GLABELS_BUILDER_DIR "print-custom-widget.builder",
507 g_critical ("%s\n\ngLabels may not be installed correctly!", error->message);
508 g_error_free (error);
512 gl_util_get_builder_widgets (builder,
513 "print_custom_widget_vbox", &vbox,
514 "simple_frame", &op->priv->simple_frame,
515 "copies_vbox", &op->priv->copies_vbox,
516 "merge_frame", &op->priv->merge_frame,
517 "prmerge_vbox", &op->priv->prmerge_vbox,
518 "outline_check", &op->priv->outline_check,
519 "reverse_check", &op->priv->reverse_check,
520 "crop_marks_check", &op->priv->crop_marks_check,
523 /* ----- Simple print control ----- */
524 op->priv->copies = gl_wdgt_print_copies_new (label);
525 gtk_box_pack_start (GTK_BOX(op->priv->copies_vbox),
526 op->priv->copies, FALSE, FALSE, 0);
528 /* ----- Merge print control ----- */
529 op->priv->prmerge = gl_wdgt_print_merge_new (label);
530 gtk_box_pack_start (GTK_BOX(op->priv->prmerge_vbox),
531 op->priv->prmerge, FALSE, FALSE, 0);
534 op->priv->builder = builder;
537 /* ---- Activate either simple or merge print control widgets. ---- */
538 merge = gl_label_get_merge (op->priv->label);
541 gl_wdgt_print_copies_set_range (GL_WDGT_PRINT_COPIES (op->priv->copies),
546 gtk_widget_show_all (op->priv->simple_frame);
547 gtk_widget_hide_all (op->priv->merge_frame);
551 gint n_records = gl_merge_get_record_count( merge );
552 gl_wdgt_print_merge_set_copies (GL_WDGT_PRINT_MERGE (op->priv->prmerge),
556 op->priv->collate_flag);
557 g_object_unref (G_OBJECT(merge));
559 gtk_widget_hide_all (op->priv->simple_frame);
560 gtk_widget_show_all (op->priv->merge_frame);
563 /* --- Set options --- */
564 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (op->priv->outline_check),
565 op->priv->outline_flag);
566 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (op->priv->reverse_check),
567 op->priv->reverse_flag);
568 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (op->priv->crop_marks_check),
569 op->priv->crop_marks_flag);
571 /* --- Do we need to force the outline flag --- */
572 if (op->priv->force_outline_flag)
574 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(op->priv->outline_check),
577 gtk_widget_set_sensitive (op->priv->outline_check, FALSE);
578 gtk_widget_set_sensitive (op->priv->reverse_check, FALSE);
579 gtk_widget_set_sensitive (op->priv->crop_marks_check, FALSE);
582 return G_OBJECT (vbox);
586 /*--------------------------------------------------------------------------*/
587 /* PRIVATE. "Custom widget apply" callback */
588 /*--------------------------------------------------------------------------*/
590 custom_widget_apply_cb (GtkPrintOperation *operation,
594 glPrintOp *op = GL_PRINT_OP (operation);
595 glMerge *merge = NULL;
598 op->priv->outline_flag =
599 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
600 (op->priv->outline_check));
601 op->priv->reverse_flag =
602 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
603 (op->priv->reverse_check));
604 op->priv->crop_marks_flag =
605 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
606 (op->priv->crop_marks_check));
608 merge = gl_label_get_merge (op->priv->label);
613 op->priv->merge_flag = FALSE;
614 gl_wdgt_print_copies_get_range (GL_WDGT_PRINT_COPIES (op->priv->copies),
622 op->priv->merge_flag = TRUE;
623 gl_wdgt_print_merge_get_copies (GL_WDGT_PRINT_MERGE (op->priv->prmerge),
626 &op->priv->collate_flag,
627 &op->priv->n_sheets);
628 g_object_unref (G_OBJECT(merge));
634 /*--------------------------------------------------------------------------*/
635 /* PRIVATE. "Begin print" callback */
636 /*--------------------------------------------------------------------------*/
638 begin_print_cb (GtkPrintOperation *operation,
639 GtkPrintContext *context,
642 glPrintOp *op = GL_PRINT_OP (operation);
644 gtk_print_operation_set_n_pages (operation, op->priv->n_sheets);
649 /*--------------------------------------------------------------------------*/
650 /* PRIVATE. "Draw page" callback. */
651 /*--------------------------------------------------------------------------*/
653 draw_page_cb (GtkPrintOperation *operation,
654 GtkPrintContext *context,
658 glPrintOp *op = GL_PRINT_OP (operation);
661 cr = gtk_print_context_get_cairo_context (context);
663 if (!op->priv->merge_flag)
665 gl_print_simple_sheet (op->priv->label,
671 op->priv->outline_flag,
672 op->priv->reverse_flag,
673 op->priv->crop_marks_flag);
677 if (op->priv->collate_flag)
679 gl_print_collated_merge_sheet (op->priv->label,
684 op->priv->outline_flag,
685 op->priv->reverse_flag,
686 op->priv->crop_marks_flag,
691 gl_print_uncollated_merge_sheet (op->priv->label,
696 op->priv->outline_flag,
697 op->priv->reverse_flag,
698 op->priv->crop_marks_flag,
705 /*****************************************************************************/
706 /* Set outline flag/checkbox. */
707 /*****************************************************************************/
709 gl_print_op_force_outline_flag (glPrintOp *op)
711 op->priv->force_outline_flag = TRUE;
717 * Local Variables: -- emacs
719 * c-basic-offset: 8 -- emacs
720 * tab-width: 8 -- emacs
721 * indent-tabs-mode: nil -- emacs