1 /* GTK - The GIMP Toolkit
2  * gtkprintoperation.c: Print Operation
3  * Copyright (C) 2006, Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20 
21 #include "config.h"
22 
23 #include <errno.h>
24 #include <stdlib.h>
25 #include <math.h>
26 
27 #include <string.h>
28 #include "gtkprintoperation-private.h"
29 #include "gtkmarshalers.h"
30 #include <cairo-pdf.h>
31 #include "gtkintl.h"
32 #include "gtkprivate.h"
33 #include "gtkmessagedialog.h"
34 #include "gtkalias.h"
35 
36 #define SHOW_PROGRESS_TIME 1200
37 
38 #define GTK_PRINT_OPERATION_GET_PRIVATE(obj)(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_PRINT_OPERATION, GtkPrintOperationPrivate))
39 
40 enum
41 {
42   DONE,
43   BEGIN_PRINT,
44   PAGINATE,
45   REQUEST_PAGE_SETUP,
46   DRAW_PAGE,
47   END_PRINT,
48   STATUS_CHANGED,
49   CREATE_CUSTOM_WIDGET,
50   CUSTOM_WIDGET_APPLY,
51   PREVIEW,
52   UPDATE_CUSTOM_WIDGET,
53   LAST_SIGNAL
54 };
55 
56 enum
57 {
58   PROP_0,
59   PROP_DEFAULT_PAGE_SETUP,
60   PROP_PRINT_SETTINGS,
61   PROP_JOB_NAME,
62   PROP_N_PAGES,
63   PROP_CURRENT_PAGE,
64   PROP_USE_FULL_PAGE,
65   PROP_TRACK_PRINT_STATUS,
66   PROP_UNIT,
67   PROP_SHOW_PROGRESS,
68   PROP_ALLOW_ASYNC,
69   PROP_EXPORT_FILENAME,
70   PROP_STATUS,
71   PROP_STATUS_STRING,
72   PROP_CUSTOM_TAB_LABEL,
73   PROP_EMBED_PAGE_SETUP,
74   PROP_HAS_SELECTION,
75   PROP_SUPPORT_SELECTION,
76   PROP_N_PAGES_TO_PRINT
77 };
78 
79 static guint signals[LAST_SIGNAL] = { 0 };
80 static int job_nr = 0;
81 typedef struct _PrintPagesData PrintPagesData;
82 
83 static void          preview_iface_init      (GtkPrintOperationPreviewIface *iface);
84 static GtkPageSetup *create_page_setup       (GtkPrintOperation             *op);
85 static void          common_render_page      (GtkPrintOperation             *op,
86 					      gint                           page_nr);
87 static void          increment_page_sequence (PrintPagesData *data);
88 static void          prepare_data            (PrintPagesData *data);
89 static void          clamp_page_ranges       (PrintPagesData *data);
90 
91 
G_DEFINE_TYPE_WITH_CODE(GtkPrintOperation,gtk_print_operation,G_TYPE_OBJECT,G_IMPLEMENT_INTERFACE (GTK_TYPE_PRINT_OPERATION_PREVIEW,preview_iface_init))92 G_DEFINE_TYPE_WITH_CODE (GtkPrintOperation, gtk_print_operation, G_TYPE_OBJECT,
93 			 G_IMPLEMENT_INTERFACE (GTK_TYPE_PRINT_OPERATION_PREVIEW,
94 						preview_iface_init))
95 
96 /**
97  * gtk_print_error_quark:
98  *
99  * Registers an error quark for #GtkPrintOperation if necessary.
100  *
101  * Return value: The error quark used for #GtkPrintOperation errors.
102  *
103  * Since: 2.10
104  **/
105 GQuark
106 gtk_print_error_quark (void)
107 {
108   static GQuark quark = 0;
109   if (quark == 0)
110     quark = g_quark_from_static_string ("gtk-print-error-quark");
111   return quark;
112 }
113 
114 static void
gtk_print_operation_finalize(GObject * object)115 gtk_print_operation_finalize (GObject *object)
116 {
117   GtkPrintOperation *print_operation = GTK_PRINT_OPERATION (object);
118   GtkPrintOperationPrivate *priv = print_operation->priv;
119 
120   if (priv->free_platform_data &&
121       priv->platform_data)
122     {
123       priv->free_platform_data (priv->platform_data);
124       priv->free_platform_data = NULL;
125     }
126 
127   if (priv->default_page_setup)
128     g_object_unref (priv->default_page_setup);
129 
130   if (priv->print_settings)
131     g_object_unref (priv->print_settings);
132 
133   if (priv->print_context)
134     g_object_unref (priv->print_context);
135 
136   g_free (priv->export_filename);
137   g_free (priv->job_name);
138   g_free (priv->custom_tab_label);
139   g_free (priv->status_string);
140 
141   if (priv->print_pages_idle_id > 0)
142     g_source_remove (priv->print_pages_idle_id);
143 
144   if (priv->show_progress_timeout_id > 0)
145     g_source_remove (priv->show_progress_timeout_id);
146 
147   if (priv->error)
148     g_error_free (priv->error);
149 
150   G_OBJECT_CLASS (gtk_print_operation_parent_class)->finalize (object);
151 }
152 
153 static void
gtk_print_operation_init(GtkPrintOperation * operation)154 gtk_print_operation_init (GtkPrintOperation *operation)
155 {
156   GtkPrintOperationPrivate *priv;
157   const char *appname;
158 
159   priv = operation->priv = GTK_PRINT_OPERATION_GET_PRIVATE (operation);
160 
161   priv->status = GTK_PRINT_STATUS_INITIAL;
162   priv->status_string = g_strdup ("");
163   priv->default_page_setup = NULL;
164   priv->print_settings = NULL;
165   priv->nr_of_pages = -1;
166   priv->nr_of_pages_to_print = -1;
167   priv->page_position = -1;
168   priv->current_page = -1;
169   priv->use_full_page = FALSE;
170   priv->show_progress = FALSE;
171   priv->export_filename = NULL;
172   priv->track_print_status = FALSE;
173   priv->is_sync = FALSE;
174   priv->support_selection = FALSE;
175   priv->has_selection = FALSE;
176   priv->embed_page_setup = FALSE;
177 
178   priv->page_drawing_state = GTK_PAGE_DRAWING_STATE_READY;
179 
180   priv->rloop = NULL;
181   priv->unit = GTK_UNIT_PIXEL;
182 
183   appname = g_get_application_name ();
184   if (appname == NULL)
185     appname = "";
186   /* translators: this string is the default job title for print
187    * jobs. %s gets replaced by the application name, %d gets replaced
188    * by the job number.
189    */
190   priv->job_name = g_strdup_printf (_("%s job #%d"), appname, ++job_nr);
191 }
192 
193 static void
preview_iface_render_page(GtkPrintOperationPreview * preview,gint page_nr)194 preview_iface_render_page (GtkPrintOperationPreview *preview,
195 			   gint                      page_nr)
196 {
197 
198   GtkPrintOperation *op;
199 
200   op = GTK_PRINT_OPERATION (preview);
201   common_render_page (op, page_nr);
202 }
203 
204 static void
preview_iface_end_preview(GtkPrintOperationPreview * preview)205 preview_iface_end_preview (GtkPrintOperationPreview *preview)
206 {
207   GtkPrintOperation *op;
208 
209   op = GTK_PRINT_OPERATION (preview);
210 
211   g_signal_emit (op, signals[END_PRINT], 0, op->priv->print_context);
212 
213   if (op->priv->rloop)
214     g_main_loop_quit (op->priv->rloop);
215 
216   if (op->priv->end_run)
217     op->priv->end_run (op, op->priv->is_sync, TRUE);
218 
219   _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED, NULL);
220 
221   g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_APPLY);
222 }
223 
224 static gboolean
preview_iface_is_selected(GtkPrintOperationPreview * preview,gint page_nr)225 preview_iface_is_selected (GtkPrintOperationPreview *preview,
226 			   gint                      page_nr)
227 {
228   GtkPrintOperation *op;
229   GtkPrintOperationPrivate *priv;
230   int i;
231 
232   op = GTK_PRINT_OPERATION (preview);
233   priv = op->priv;
234 
235   switch (priv->print_pages)
236     {
237     case GTK_PRINT_PAGES_SELECTION:
238     case GTK_PRINT_PAGES_ALL:
239       return (page_nr >= 0) && (page_nr < priv->nr_of_pages);
240     case GTK_PRINT_PAGES_CURRENT:
241       return page_nr == priv->current_page;
242     case GTK_PRINT_PAGES_RANGES:
243       for (i = 0; i < priv->num_page_ranges; i++)
244 	{
245 	  if (page_nr >= priv->page_ranges[i].start &&
246 	      (page_nr <= priv->page_ranges[i].end || priv->page_ranges[i].end == -1))
247 	    return TRUE;
248 	}
249       return FALSE;
250     }
251   return FALSE;
252 }
253 
254 static void
preview_iface_init(GtkPrintOperationPreviewIface * iface)255 preview_iface_init (GtkPrintOperationPreviewIface *iface)
256 {
257   iface->render_page = preview_iface_render_page;
258   iface->end_preview = preview_iface_end_preview;
259   iface->is_selected = preview_iface_is_selected;
260 }
261 
262 static void
preview_start_page(GtkPrintOperation * op,GtkPrintContext * print_context,GtkPageSetup * page_setup)263 preview_start_page (GtkPrintOperation *op,
264 		    GtkPrintContext   *print_context,
265 		    GtkPageSetup      *page_setup)
266 {
267   if ((op->priv->manual_number_up < 2) ||
268       (op->priv->page_position % op->priv->manual_number_up == 0))
269     g_signal_emit_by_name (op, "got-page-size", print_context, page_setup);
270 }
271 
272 static void
preview_end_page(GtkPrintOperation * op,GtkPrintContext * print_context)273 preview_end_page (GtkPrintOperation *op,
274 		  GtkPrintContext   *print_context)
275 {
276   cairo_t *cr;
277 
278   cr = gtk_print_context_get_cairo_context (print_context);
279 
280   if ((op->priv->manual_number_up < 2) ||
281       ((op->priv->page_position + 1) % op->priv->manual_number_up == 0) ||
282       (op->priv->page_position == op->priv->nr_of_pages_to_print - 1))
283     cairo_show_page (cr);
284 }
285 
286 static void
preview_end_run(GtkPrintOperation * op,gboolean wait,gboolean cancelled)287 preview_end_run (GtkPrintOperation *op,
288 		 gboolean           wait,
289 		 gboolean           cancelled)
290 {
291   g_free (op->priv->page_ranges);
292   op->priv->page_ranges = NULL;
293 }
294 
295 
296 static void
gtk_print_operation_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)297 gtk_print_operation_set_property (GObject      *object,
298 				  guint         prop_id,
299 				  const GValue *value,
300 				  GParamSpec   *pspec)
301 {
302   GtkPrintOperation *op = GTK_PRINT_OPERATION (object);
303 
304   switch (prop_id)
305     {
306     case PROP_DEFAULT_PAGE_SETUP:
307       gtk_print_operation_set_default_page_setup (op, g_value_get_object (value));
308       break;
309     case PROP_PRINT_SETTINGS:
310       gtk_print_operation_set_print_settings (op, g_value_get_object (value));
311       break;
312     case PROP_JOB_NAME:
313       gtk_print_operation_set_job_name (op, g_value_get_string (value));
314       break;
315     case PROP_N_PAGES:
316       gtk_print_operation_set_n_pages (op, g_value_get_int (value));
317       break;
318     case PROP_CURRENT_PAGE:
319       gtk_print_operation_set_current_page (op, g_value_get_int (value));
320       break;
321     case PROP_USE_FULL_PAGE:
322       gtk_print_operation_set_use_full_page (op, g_value_get_boolean (value));
323       break;
324     case PROP_TRACK_PRINT_STATUS:
325       gtk_print_operation_set_track_print_status (op, g_value_get_boolean (value));
326       break;
327     case PROP_UNIT:
328       gtk_print_operation_set_unit (op, g_value_get_enum (value));
329       break;
330     case PROP_ALLOW_ASYNC:
331       gtk_print_operation_set_allow_async (op, g_value_get_boolean (value));
332       break;
333     case PROP_SHOW_PROGRESS:
334       gtk_print_operation_set_show_progress (op, g_value_get_boolean (value));
335       break;
336     case PROP_EXPORT_FILENAME:
337       gtk_print_operation_set_export_filename (op, g_value_get_string (value));
338       break;
339     case PROP_CUSTOM_TAB_LABEL:
340       gtk_print_operation_set_custom_tab_label (op, g_value_get_string (value));
341       break;
342     case PROP_EMBED_PAGE_SETUP:
343       gtk_print_operation_set_embed_page_setup (op, g_value_get_boolean (value));
344       break;
345     case PROP_HAS_SELECTION:
346       gtk_print_operation_set_has_selection (op, g_value_get_boolean (value));
347       break;
348     case PROP_SUPPORT_SELECTION:
349       gtk_print_operation_set_support_selection (op, g_value_get_boolean (value));
350       break;
351     default:
352       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
353       break;
354     }
355 }
356 
357 static void
gtk_print_operation_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)358 gtk_print_operation_get_property (GObject    *object,
359 				  guint       prop_id,
360 				  GValue     *value,
361 				  GParamSpec *pspec)
362 {
363   GtkPrintOperation *op = GTK_PRINT_OPERATION (object);
364   GtkPrintOperationPrivate *priv = op->priv;
365 
366   switch (prop_id)
367     {
368     case PROP_DEFAULT_PAGE_SETUP:
369       g_value_set_object (value, priv->default_page_setup);
370       break;
371     case PROP_PRINT_SETTINGS:
372       g_value_set_object (value, priv->print_settings);
373       break;
374     case PROP_JOB_NAME:
375       g_value_set_string (value, priv->job_name);
376       break;
377     case PROP_N_PAGES:
378       g_value_set_int (value, priv->nr_of_pages);
379       break;
380     case PROP_CURRENT_PAGE:
381       g_value_set_int (value, priv->current_page);
382       break;
383     case PROP_USE_FULL_PAGE:
384       g_value_set_boolean (value, priv->use_full_page);
385       break;
386     case PROP_TRACK_PRINT_STATUS:
387       g_value_set_boolean (value, priv->track_print_status);
388       break;
389     case PROP_UNIT:
390       g_value_set_enum (value, priv->unit);
391       break;
392     case PROP_ALLOW_ASYNC:
393       g_value_set_boolean (value, priv->allow_async);
394       break;
395     case PROP_SHOW_PROGRESS:
396       g_value_set_boolean (value, priv->show_progress);
397       break;
398     case PROP_EXPORT_FILENAME:
399       g_value_set_string (value, priv->export_filename);
400       break;
401     case PROP_STATUS:
402       g_value_set_enum (value, priv->status);
403       break;
404     case PROP_STATUS_STRING:
405       g_value_set_string (value, priv->status_string);
406       break;
407     case PROP_CUSTOM_TAB_LABEL:
408       g_value_set_string (value, priv->custom_tab_label);
409       break;
410     case PROP_EMBED_PAGE_SETUP:
411       g_value_set_boolean (value, priv->embed_page_setup);
412       break;
413     case PROP_HAS_SELECTION:
414       g_value_set_boolean (value, priv->has_selection);
415       break;
416     case PROP_SUPPORT_SELECTION:
417       g_value_set_boolean (value, priv->support_selection);
418       break;
419     case PROP_N_PAGES_TO_PRINT:
420       g_value_set_int (value, priv->nr_of_pages_to_print);
421       break;
422     default:
423       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
424       break;
425     }
426 }
427 
428 struct _PrintPagesData
429 {
430   GtkPrintOperation *op;
431   gint uncollated_copies;
432   gint collated_copies;
433   gint uncollated, collated, total;
434 
435   gint range, num_ranges;
436   GtkPageRange *ranges;
437   GtkPageRange one_range;
438 
439   gint page;
440   gint sheet;
441   gint first_position, last_position;
442   gint first_sheet;
443   gint num_of_sheets;
444   gint *pages;
445 
446   GtkWidget *progress;
447 
448   gboolean initialized;
449   gboolean is_preview;
450   gboolean done;
451 };
452 
453 typedef struct
454 {
455   GtkPrintOperationPreview *preview;
456   GtkPrintContext *print_context;
457   GtkWindow *parent;
458   cairo_surface_t *surface;
459   gchar *filename;
460   gboolean wait;
461   PrintPagesData *pages_data;
462 } PreviewOp;
463 
464 static void
preview_print_idle_done(gpointer data)465 preview_print_idle_done (gpointer data)
466 {
467   GtkPrintOperation *op;
468   PreviewOp *pop = (PreviewOp *) data;
469 
470   op = GTK_PRINT_OPERATION (pop->preview);
471 
472   cairo_surface_finish (pop->surface);
473   /* Surface is destroyed in launch_preview */
474   _gtk_print_operation_platform_backend_launch_preview (op,
475 							pop->surface,
476 							pop->parent,
477 							pop->filename);
478 
479   g_free (pop->filename);
480 
481   gtk_print_operation_preview_end_preview (pop->preview);
482 
483   g_object_unref (pop->pages_data->op);
484   g_free (pop->pages_data->pages);
485   g_free (pop->pages_data);
486 
487   g_object_unref (op);
488   g_free (pop);
489 }
490 
491 static gboolean
preview_print_idle(gpointer data)492 preview_print_idle (gpointer data)
493 {
494   PreviewOp *pop;
495   GtkPrintOperation *op;
496   GtkPrintOperationPrivate *priv;
497   gboolean done = FALSE;
498 
499   pop = (PreviewOp *) data;
500   op = GTK_PRINT_OPERATION (pop->preview);
501   priv = op->priv;
502 
503 
504   if (priv->page_drawing_state == GTK_PAGE_DRAWING_STATE_READY)
505     {
506       if (!pop->pages_data->initialized)
507         {
508           pop->pages_data->initialized = TRUE;
509           prepare_data (pop->pages_data);
510         }
511       else
512         {
513           increment_page_sequence (pop->pages_data);
514 
515           if (!pop->pages_data->done)
516             gtk_print_operation_preview_render_page (pop->preview, pop->pages_data->page);
517           else
518             done = priv->page_drawing_state == GTK_PAGE_DRAWING_STATE_READY;
519         }
520     }
521 
522   return !done;
523 }
524 
525 static void
preview_got_page_size(GtkPrintOperationPreview * preview,GtkPrintContext * context,GtkPageSetup * page_setup,PreviewOp * pop)526 preview_got_page_size (GtkPrintOperationPreview *preview,
527 		       GtkPrintContext          *context,
528 		       GtkPageSetup             *page_setup,
529 		       PreviewOp                *pop)
530 {
531   GtkPrintOperation *op = GTK_PRINT_OPERATION (preview);
532   cairo_t *cr;
533 
534   _gtk_print_operation_platform_backend_resize_preview_surface (op, page_setup, pop->surface);
535 
536   cr = gtk_print_context_get_cairo_context (pop->print_context);
537   _gtk_print_operation_platform_backend_preview_start_page (op, pop->surface, cr);
538 
539 }
540 
541 static void
preview_ready(GtkPrintOperationPreview * preview,GtkPrintContext * context,PreviewOp * pop)542 preview_ready (GtkPrintOperationPreview *preview,
543                GtkPrintContext          *context,
544 	       PreviewOp                *pop)
545 {
546   pop->print_context = context;
547 
548   g_object_ref (preview);
549 
550   gdk_threads_add_idle_full (G_PRIORITY_DEFAULT_IDLE + 10,
551 	                     preview_print_idle,
552 		             pop,
553 		             preview_print_idle_done);
554 }
555 
556 
557 static gboolean
gtk_print_operation_preview_handler(GtkPrintOperation * op,GtkPrintOperationPreview * preview,GtkPrintContext * context,GtkWindow * parent)558 gtk_print_operation_preview_handler (GtkPrintOperation        *op,
559                                      GtkPrintOperationPreview *preview,
560 				     GtkPrintContext          *context,
561 				     GtkWindow                *parent)
562 {
563   gdouble dpi_x, dpi_y;
564   PreviewOp *pop;
565   GtkPageSetup *page_setup;
566   cairo_t *cr;
567 
568   pop = g_new0 (PreviewOp, 1);
569   pop->filename = NULL;
570   pop->preview = preview;
571   pop->parent = parent;
572   pop->pages_data = g_new0 (PrintPagesData, 1);
573   pop->pages_data->op = g_object_ref (GTK_PRINT_OPERATION (preview));
574   pop->pages_data->is_preview = TRUE;
575 
576   page_setup = gtk_print_context_get_page_setup (context);
577 
578   pop->surface =
579     _gtk_print_operation_platform_backend_create_preview_surface (op,
580 								  page_setup,
581 								  &dpi_x, &dpi_y,
582 								  &pop->filename);
583 
584   if (pop->surface == NULL)
585     {
586       g_free (pop);
587       return FALSE;
588     }
589 
590   cr = cairo_create (pop->surface);
591   gtk_print_context_set_cairo_context (op->priv->print_context, cr,
592 				       dpi_x, dpi_y);
593   cairo_destroy (cr);
594 
595   g_signal_connect (preview, "ready", (GCallback) preview_ready, pop);
596   g_signal_connect (preview, "got-page-size", (GCallback) preview_got_page_size, pop);
597 
598   return TRUE;
599 }
600 
601 static GtkWidget *
gtk_print_operation_create_custom_widget(GtkPrintOperation * operation)602 gtk_print_operation_create_custom_widget (GtkPrintOperation *operation)
603 {
604   return NULL;
605 }
606 
607 static gboolean
gtk_print_operation_paginate(GtkPrintOperation * operation,GtkPrintContext * context)608 gtk_print_operation_paginate (GtkPrintOperation *operation,
609                               GtkPrintContext   *context)
610 {
611   /* assume the number of pages is already set and pagination is not needed */
612   return TRUE;
613 }
614 
615 static void
gtk_print_operation_done(GtkPrintOperation * operation,GtkPrintOperationResult result)616 gtk_print_operation_done (GtkPrintOperation       *operation,
617                           GtkPrintOperationResult  result)
618 {
619   GtkPrintOperationPrivate *priv = operation->priv;
620 
621   if (priv->print_context)
622     {
623       g_object_unref (priv->print_context);
624       priv->print_context = NULL;
625     }
626 }
627 
628 static gboolean
custom_widget_accumulator(GSignalInvocationHint * ihint,GValue * return_accu,const GValue * handler_return,gpointer dummy)629 custom_widget_accumulator (GSignalInvocationHint *ihint,
630 			   GValue                *return_accu,
631 			   const GValue          *handler_return,
632 			   gpointer               dummy)
633 {
634   gboolean continue_emission;
635   GtkWidget *widget;
636 
637   widget = g_value_get_object (handler_return);
638   if (widget != NULL)
639     g_value_set_object (return_accu, widget);
640   continue_emission = (widget == NULL);
641 
642   return continue_emission;
643 }
644 
645 static gboolean
paginate_accumulator(GSignalInvocationHint * ihint,GValue * return_accu,const GValue * handler_return,gpointer dummy)646 paginate_accumulator (GSignalInvocationHint *ihint,
647                       GValue                *return_accu,
648                       const GValue          *handler_return,
649                       gpointer               dummy)
650 {
651   *return_accu = *handler_return;
652 
653   /* Stop signal emission on first invocation, so if it's a callback then
654    * the default handler won't run. */
655   return FALSE;
656 }
657 
658 static void
gtk_print_operation_class_init(GtkPrintOperationClass * class)659 gtk_print_operation_class_init (GtkPrintOperationClass *class)
660 {
661   GObjectClass *gobject_class = (GObjectClass *)class;
662 
663   gobject_class->set_property = gtk_print_operation_set_property;
664   gobject_class->get_property = gtk_print_operation_get_property;
665   gobject_class->finalize = gtk_print_operation_finalize;
666 
667   class->preview = gtk_print_operation_preview_handler;
668   class->create_custom_widget = gtk_print_operation_create_custom_widget;
669   class->paginate = gtk_print_operation_paginate;
670   class->done = gtk_print_operation_done;
671 
672   g_type_class_add_private (gobject_class, sizeof (GtkPrintOperationPrivate));
673 
674   /**
675    * GtkPrintOperation::done:
676    * @operation: the #GtkPrintOperation on which the signal was emitted
677    * @result: the result of the print operation
678    *
679    * Emitted when the print operation run has finished doing
680    * everything required for printing.
681    *
682    * @result gives you information about what happened during the run.
683    * If @result is %GTK_PRINT_OPERATION_RESULT_ERROR then you can call
684    * gtk_print_operation_get_error() for more information.
685    *
686    * If you enabled print status tracking then
687    * gtk_print_operation_is_finished() may still return %FALSE
688    * after #GtkPrintOperation::done was emitted.
689    *
690    * Since: 2.10
691    */
692   signals[DONE] =
693     g_signal_new (I_("done"),
694 		  G_TYPE_FROM_CLASS (gobject_class),
695 		  G_SIGNAL_RUN_LAST,
696 		  G_STRUCT_OFFSET (GtkPrintOperationClass, done),
697 		  NULL, NULL,
698 		  g_cclosure_marshal_VOID__ENUM,
699 		  G_TYPE_NONE, 1, GTK_TYPE_PRINT_OPERATION_RESULT);
700 
701   /**
702    * GtkPrintOperation::begin-print:
703    * @operation: the #GtkPrintOperation on which the signal was emitted
704    * @context: the #GtkPrintContext for the current operation
705    *
706    * Emitted after the user has finished changing print settings
707    * in the dialog, before the actual rendering starts.
708    *
709    * A typical use for ::begin-print is to use the parameters from the
710    * #GtkPrintContext and paginate the document accordingly, and then
711    * set the number of pages with gtk_print_operation_set_n_pages().
712    *
713    * Since: 2.10
714    */
715   signals[BEGIN_PRINT] =
716     g_signal_new (I_("begin-print"),
717 		  G_TYPE_FROM_CLASS (gobject_class),
718 		  G_SIGNAL_RUN_LAST,
719 		  G_STRUCT_OFFSET (GtkPrintOperationClass, begin_print),
720 		  NULL, NULL,
721 		  g_cclosure_marshal_VOID__OBJECT,
722 		  G_TYPE_NONE, 1, GTK_TYPE_PRINT_CONTEXT);
723 
724    /**
725    * GtkPrintOperation::paginate:
726    * @operation: the #GtkPrintOperation on which the signal was emitted
727    * @context: the #GtkPrintContext for the current operation
728    *
729    * Emitted after the #GtkPrintOperation::begin-print signal, but before
730    * the actual rendering starts. It keeps getting emitted until a connected
731    * signal handler returns %TRUE.
732    *
733    * The ::paginate signal is intended to be used for paginating a document
734    * in small chunks, to avoid blocking the user interface for a long
735    * time. The signal handler should update the number of pages using
736    * gtk_print_operation_set_n_pages(), and return %TRUE if the document
737    * has been completely paginated.
738    *
739    * If you don't need to do pagination in chunks, you can simply do
740    * it all in the ::begin-print handler, and set the number of pages
741    * from there.
742    *
743    * Return value: %TRUE if pagination is complete
744    *
745    * Since: 2.10
746    */
747   signals[PAGINATE] =
748     g_signal_new (I_("paginate"),
749 		  G_TYPE_FROM_CLASS (gobject_class),
750 		  G_SIGNAL_RUN_LAST,
751 		  G_STRUCT_OFFSET (GtkPrintOperationClass, paginate),
752 		  paginate_accumulator, NULL,
753 		  _gtk_marshal_BOOLEAN__OBJECT,
754 		  G_TYPE_BOOLEAN, 1, GTK_TYPE_PRINT_CONTEXT);
755 
756 
757   /**
758    * GtkPrintOperation::request-page-setup:
759    * @operation: the #GtkPrintOperation on which the signal was emitted
760    * @context: the #GtkPrintContext for the current operation
761    * @page_nr: the number of the currently printed page (0-based)
762    * @setup: the #GtkPageSetup
763    *
764    * Emitted once for every page that is printed, to give
765    * the application a chance to modify the page setup. Any changes
766    * done to @setup will be in force only for printing this page.
767    *
768    * Since: 2.10
769    */
770   signals[REQUEST_PAGE_SETUP] =
771     g_signal_new (I_("request-page-setup"),
772 		  G_TYPE_FROM_CLASS (gobject_class),
773 		  G_SIGNAL_RUN_LAST,
774 		  G_STRUCT_OFFSET (GtkPrintOperationClass, request_page_setup),
775 		  NULL, NULL,
776 		  _gtk_marshal_VOID__OBJECT_INT_OBJECT,
777 		  G_TYPE_NONE, 3,
778 		  GTK_TYPE_PRINT_CONTEXT,
779 		  G_TYPE_INT,
780 		  GTK_TYPE_PAGE_SETUP);
781 
782   /**
783    * GtkPrintOperation::draw-page:
784    * @operation: the #GtkPrintOperation on which the signal was emitted
785    * @context: the #GtkPrintContext for the current operation
786    * @page_nr: the number of the currently printed page (0-based)
787    *
788    * Emitted for every page that is printed. The signal handler
789    * must render the @page_nr's page onto the cairo context obtained
790    * from @context using gtk_print_context_get_cairo_context().
791    * |[
792    * static void
793    * draw_page (GtkPrintOperation *operation,
794    *            GtkPrintContext   *context,
795    *            gint               page_nr,
796    *            gpointer           user_data)
797    * {
798    *   cairo_t *cr;
799    *   PangoLayout *layout;
800    *   gdouble width, text_height;
801    *   gint layout_height;
802    *   PangoFontDescription *desc;
803    *
804    *   cr = gtk_print_context_get_cairo_context (context);
805    *   width = gtk_print_context_get_width (context);
806    *
807    *   cairo_rectangle (cr, 0, 0, width, HEADER_HEIGHT);
808    *
809    *   cairo_set_source_rgb (cr, 0.8, 0.8, 0.8);
810    *   cairo_fill (cr);
811    *
812    *   layout = gtk_print_context_create_pango_layout (context);
813    *
814    *   desc = pango_font_description_from_string ("sans 14");
815    *   pango_layout_set_font_description (layout, desc);
816    *   pango_font_description_free (desc);
817    *
818    *   pango_layout_set_text (layout, "some text", -1);
819    *   pango_layout_set_width (layout, width * PANGO_SCALE);
820    *   pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
821    *
822    *   pango_layout_get_size (layout, NULL, &layout_height);
823    *   text_height = (gdouble)layout_height / PANGO_SCALE;
824    *
825    *   cairo_move_to (cr, width / 2,  (HEADER_HEIGHT - text_height) / 2);
826    *   pango_cairo_show_layout (cr, layout);
827    *
828    *   g_object_unref (layout);
829    * }
830    * ]|
831    *
832    * Use gtk_print_operation_set_use_full_page() and
833    * gtk_print_operation_set_unit() before starting the print operation
834    * to set up the transformation of the cairo context according to your
835    * needs.
836    *
837    * Since: 2.10
838    */
839   signals[DRAW_PAGE] =
840     g_signal_new (I_("draw-page"),
841 		  G_TYPE_FROM_CLASS (gobject_class),
842 		  G_SIGNAL_RUN_LAST,
843 		  G_STRUCT_OFFSET (GtkPrintOperationClass, draw_page),
844 		  NULL, NULL,
845 		  _gtk_marshal_VOID__OBJECT_INT,
846 		  G_TYPE_NONE, 2,
847 		  GTK_TYPE_PRINT_CONTEXT,
848 		  G_TYPE_INT);
849 
850   /**
851    * GtkPrintOperation::end-print:
852    * @operation: the #GtkPrintOperation on which the signal was emitted
853    * @context: the #GtkPrintContext for the current operation
854    *
855    * Emitted after all pages have been rendered.
856    * A handler for this signal can clean up any resources that have
857    * been allocated in the #GtkPrintOperation::begin-print handler.
858    *
859    * Since: 2.10
860    */
861   signals[END_PRINT] =
862     g_signal_new (I_("end-print"),
863 		  G_TYPE_FROM_CLASS (gobject_class),
864 		  G_SIGNAL_RUN_LAST,
865 		  G_STRUCT_OFFSET (GtkPrintOperationClass, end_print),
866 		  NULL, NULL,
867 		  g_cclosure_marshal_VOID__OBJECT,
868 		  G_TYPE_NONE, 1, GTK_TYPE_PRINT_CONTEXT);
869 
870   /**
871    * GtkPrintOperation::status-changed:
872    * @operation: the #GtkPrintOperation on which the signal was emitted
873    *
874    * Emitted at between the various phases of the print operation.
875    * See #GtkPrintStatus for the phases that are being discriminated.
876    * Use gtk_print_operation_get_status() to find out the current
877    * status.
878    *
879    * Since: 2.10
880    */
881   signals[STATUS_CHANGED] =
882     g_signal_new (I_("status-changed"),
883 		  G_TYPE_FROM_CLASS (class),
884 		  G_SIGNAL_RUN_LAST,
885 		  G_STRUCT_OFFSET (GtkPrintOperationClass, status_changed),
886 		  NULL, NULL,
887 		  g_cclosure_marshal_VOID__VOID,
888 		  G_TYPE_NONE, 0);
889 
890 
891   /**
892    * GtkPrintOperation::create-custom-widget:
893    * @operation: the #GtkPrintOperation on which the signal was emitted
894    *
895    * Emitted when displaying the print dialog. If you return a
896    * widget in a handler for this signal it will be added to a custom
897    * tab in the print dialog. You typically return a container widget
898    * with multiple widgets in it.
899    *
900    * The print dialog owns the returned widget, and its lifetime is not
901    * controlled by the application. However, the widget is guaranteed
902    * to stay around until the #GtkPrintOperation::custom-widget-apply
903    * signal is emitted on the operation. Then you can read out any
904    * information you need from the widgets.
905    *
906    * Returns: (transfer none): A custom widget that gets embedded in
907    *          the print dialog, or %NULL
908    *
909    * Since: 2.10
910    */
911   signals[CREATE_CUSTOM_WIDGET] =
912     g_signal_new (I_("create-custom-widget"),
913 		  G_TYPE_FROM_CLASS (class),
914 		  G_SIGNAL_RUN_LAST,
915 		  G_STRUCT_OFFSET (GtkPrintOperationClass, create_custom_widget),
916 		  custom_widget_accumulator, NULL,
917 		  _gtk_marshal_OBJECT__VOID,
918 		  G_TYPE_OBJECT, 0);
919 
920   /**
921    * GtkPrintOperation::update-custom-widget:
922    * @operation: the #GtkPrintOperation on which the signal was emitted
923    * @widget: the custom widget added in create-custom-widget
924    * @setup: actual page setup
925    * @settings: actual print settings
926    *
927    * Emitted after change of selected printer. The actual page setup and
928    * print settings are passed to the custom widget, which can actualize
929    * itself according to this change.
930    *
931    * Since: 2.18
932    */
933   signals[UPDATE_CUSTOM_WIDGET] =
934     g_signal_new (I_("update-custom-widget"),
935 		  G_TYPE_FROM_CLASS (class),
936 		  G_SIGNAL_RUN_LAST,
937 		  G_STRUCT_OFFSET (GtkPrintOperationClass, update_custom_widget),
938 		  NULL, NULL,
939 		  _gtk_marshal_VOID__OBJECT_OBJECT_OBJECT,
940 		  G_TYPE_NONE, 3, GTK_TYPE_WIDGET, GTK_TYPE_PAGE_SETUP, GTK_TYPE_PRINT_SETTINGS);
941 
942   /**
943    * GtkPrintOperation::custom-widget-apply:
944    * @operation: the #GtkPrintOperation on which the signal was emitted
945    * @widget: the custom widget added in create-custom-widget
946    *
947    * Emitted right before #GtkPrintOperation::begin-print if you added
948    * a custom widget in the #GtkPrintOperation::create-custom-widget handler.
949    * When you get this signal you should read the information from the
950    * custom widgets, as the widgets are not guaraneed to be around at a
951    * later time.
952    *
953    * Since: 2.10
954    */
955   signals[CUSTOM_WIDGET_APPLY] =
956     g_signal_new (I_("custom-widget-apply"),
957 		  G_TYPE_FROM_CLASS (class),
958 		  G_SIGNAL_RUN_LAST,
959 		  G_STRUCT_OFFSET (GtkPrintOperationClass, custom_widget_apply),
960 		  NULL, NULL,
961 		  g_cclosure_marshal_VOID__OBJECT,
962 		  G_TYPE_NONE, 1, GTK_TYPE_WIDGET);
963 
964    /**
965    * GtkPrintOperation::preview:
966    * @operation: the #GtkPrintOperation on which the signal was emitted
967    * @preview: the #GtkPrintPreviewOperation for the current operation
968    * @context: the #GtkPrintContext that will be used
969    * @parent: (allow-none): the #GtkWindow to use as window parent, or %NULL
970    *
971    * Gets emitted when a preview is requested from the native dialog.
972    *
973    * The default handler for this signal uses an external viewer
974    * application to preview.
975    *
976    * To implement a custom print preview, an application must return
977    * %TRUE from its handler for this signal. In order to use the
978    * provided @context for the preview implementation, it must be
979    * given a suitable cairo context with gtk_print_context_set_cairo_context().
980    *
981    * The custom preview implementation can use
982    * gtk_print_operation_preview_is_selected() and
983    * gtk_print_operation_preview_render_page() to find pages which
984    * are selected for print and render them. The preview must be
985    * finished by calling gtk_print_operation_preview_end_preview()
986    * (typically in response to the user clicking a close button).
987    *
988    * Returns: %TRUE if the listener wants to take over control of the preview
989    *
990    * Since: 2.10
991    */
992   signals[PREVIEW] =
993     g_signal_new (I_("preview"),
994 		  G_TYPE_FROM_CLASS (gobject_class),
995 		  G_SIGNAL_RUN_LAST,
996 		  G_STRUCT_OFFSET (GtkPrintOperationClass, preview),
997 		  _gtk_boolean_handled_accumulator, NULL,
998 		  _gtk_marshal_BOOLEAN__OBJECT_OBJECT_OBJECT,
999 		  G_TYPE_BOOLEAN, 3,
1000 		  GTK_TYPE_PRINT_OPERATION_PREVIEW,
1001 		  GTK_TYPE_PRINT_CONTEXT,
1002 		  GTK_TYPE_WINDOW);
1003 
1004 
1005   /**
1006    * GtkPrintOperation:default-page-setup:
1007    *
1008    * The #GtkPageSetup used by default.
1009    *
1010    * This page setup will be used by gtk_print_operation_run(),
1011    * but it can be overridden on a per-page basis by connecting
1012    * to the #GtkPrintOperation::request-page-setup signal.
1013    *
1014    * Since: 2.10
1015    */
1016   g_object_class_install_property (gobject_class,
1017 				   PROP_DEFAULT_PAGE_SETUP,
1018 				   g_param_spec_object ("default-page-setup",
1019 							P_("Default Page Setup"),
1020 							P_("The GtkPageSetup used by default"),
1021 							GTK_TYPE_PAGE_SETUP,
1022 							GTK_PARAM_READWRITE));
1023 
1024   /**
1025    * GtkPrintOperation:print-settings:
1026    *
1027    * The #GtkPrintSettings used for initializing the dialog.
1028    *
1029    * Setting this property is typically used to re-establish
1030    * print settings from a previous print operation, see
1031    * gtk_print_operation_run().
1032    *
1033    * Since: 2.10
1034    */
1035   g_object_class_install_property (gobject_class,
1036 				   PROP_PRINT_SETTINGS,
1037 				   g_param_spec_object ("print-settings",
1038 							P_("Print Settings"),
1039 							P_("The GtkPrintSettings used for initializing the dialog"),
1040 							GTK_TYPE_PRINT_SETTINGS,
1041 							GTK_PARAM_READWRITE));
1042 
1043   /**
1044    * GtkPrintOperation:job-name:
1045    *
1046    * A string used to identify the job (e.g. in monitoring
1047    * applications like eggcups).
1048    *
1049    * If you don't set a job name, GTK+ picks a default one
1050    * by numbering successive print jobs.
1051    *
1052    * Since: 2.10
1053    */
1054   g_object_class_install_property (gobject_class,
1055 				   PROP_JOB_NAME,
1056 				   g_param_spec_string ("job-name",
1057 							P_("Job Name"),
1058 							P_("A string used for identifying the print job."),
1059 							"",
1060 							GTK_PARAM_READWRITE));
1061 
1062   /**
1063    * GtkPrintOperation:n-pages:
1064    *
1065    * The number of pages in the document.
1066    *
1067    * This <emphasis>must</emphasis> be set to a positive number
1068    * before the rendering starts. It may be set in a
1069    * #GtkPrintOperation::begin-print signal hander.
1070    *
1071    * Note that the page numbers passed to the
1072    * #GtkPrintOperation::request-page-setup and
1073    * #GtkPrintOperation::draw-page signals are 0-based, i.e. if
1074    * the user chooses to print all pages, the last ::draw-page signal
1075    * will be for page @n_pages - 1.
1076    *
1077    * Since: 2.10
1078    */
1079   g_object_class_install_property (gobject_class,
1080 				   PROP_N_PAGES,
1081 				   g_param_spec_int ("n-pages",
1082 						     P_("Number of Pages"),
1083 						     P_("The number of pages in the document."),
1084 						     -1,
1085 						     G_MAXINT,
1086 						     -1,
1087 						     GTK_PARAM_READWRITE));
1088 
1089   /**
1090    * GtkPrintOperation:current-page:
1091    *
1092    * The current page in the document.
1093    *
1094    * If this is set before gtk_print_operation_run(),
1095    * the user will be able to select to print only the current page.
1096    *
1097    * Note that this only makes sense for pre-paginated documents.
1098    *
1099    * Since: 2.10
1100    */
1101   g_object_class_install_property (gobject_class,
1102 				   PROP_CURRENT_PAGE,
1103 				   g_param_spec_int ("current-page",
1104 						     P_("Current Page"),
1105 						     P_("The current page in the document"),
1106 						     -1,
1107 						     G_MAXINT,
1108 						     -1,
1109 						     GTK_PARAM_READWRITE));
1110 
1111   /**
1112    * GtkPrintOperation:use-full-page:
1113    *
1114    * If %TRUE, the transformation for the cairo context obtained
1115    * from #GtkPrintContext puts the origin at the top left corner
1116    * of the page (which may not be the top left corner of the sheet,
1117    * depending on page orientation and the number of pages per sheet).
1118    * Otherwise, the origin is at the top left corner of the imageable
1119    * area (i.e. inside the margins).
1120    *
1121    * Since: 2.10
1122    */
1123   g_object_class_install_property (gobject_class,
1124 				   PROP_USE_FULL_PAGE,
1125 				   g_param_spec_boolean ("use-full-page",
1126 							 P_("Use full page"),
1127 							 P_("TRUE if the origin of the context should be at the corner of the page and not the corner of the imageable area"),
1128 							 FALSE,
1129 							 GTK_PARAM_READWRITE));
1130 
1131 
1132   /**
1133    * GtkPrintOperation:track-print-status:
1134    *
1135    * If %TRUE, the print operation will try to continue report on
1136    * the status of the print job in the printer queues and printer.
1137    * This can allow your application to show things like "out of paper"
1138    * issues, and when the print job actually reaches the printer.
1139    * However, this is often implemented using polling, and should
1140    * not be enabled unless needed.
1141    *
1142    * Since: 2.10
1143    */
1144   g_object_class_install_property (gobject_class,
1145 				   PROP_TRACK_PRINT_STATUS,
1146 				   g_param_spec_boolean ("track-print-status",
1147 							 P_("Track Print Status"),
1148 							 P_("TRUE if the print operation will continue to report on the print job status after the print data has been sent to the printer or print server."),
1149 							 FALSE,
1150 							 GTK_PARAM_READWRITE));
1151 
1152 
1153   /**
1154    * GtkPrintOperation:unit:
1155    *
1156    * The transformation for the cairo context obtained from
1157    * #GtkPrintContext is set up in such a way that distances
1158    * are measured in units of @unit.
1159    *
1160    * Since: 2.10
1161    */
1162   g_object_class_install_property (gobject_class,
1163 				   PROP_UNIT,
1164 				   g_param_spec_enum ("unit",
1165 						      P_("Unit"),
1166 						      P_("The unit in which distances can be measured in the context"),
1167 						      GTK_TYPE_UNIT,
1168 						      GTK_UNIT_PIXEL,
1169 						      GTK_PARAM_READWRITE));
1170 
1171 
1172   /**
1173    * GtkPrintOperation:show-progress:
1174    *
1175    * Determines whether to show a progress dialog during the
1176    * print operation.
1177    *
1178    * Since: 2.10
1179    */
1180   g_object_class_install_property (gobject_class,
1181 				   PROP_SHOW_PROGRESS,
1182 				   g_param_spec_boolean ("show-progress",
1183 							 P_("Show Dialog"),
1184 							 P_("TRUE if a progress dialog is shown while printing."),
1185 							 FALSE,
1186 							 GTK_PARAM_READWRITE));
1187 
1188   /**
1189    * GtkPrintOperation:allow-async:
1190    *
1191    * Determines whether the print operation may run asynchronously or not.
1192    *
1193    * Some systems don't support asynchronous printing, but those that do
1194    * will return %GTK_PRINT_OPERATION_RESULT_IN_PROGRESS as the status, and
1195    * emit the #GtkPrintOperation::done signal when the operation is actually
1196    * done.
1197    *
1198    * The Windows port does not support asynchronous operation at all (this
1199    * is unlikely to change). On other platforms, all actions except for
1200    * %GTK_PRINT_OPERATION_ACTION_EXPORT support asynchronous operation.
1201    *
1202    * Since: 2.10
1203    */
1204   g_object_class_install_property (gobject_class,
1205 				   PROP_ALLOW_ASYNC,
1206 				   g_param_spec_boolean ("allow-async",
1207 							 P_("Allow Async"),
1208 							 P_("TRUE if print process may run asynchronous."),
1209 							 FALSE,
1210 							 GTK_PARAM_READWRITE));
1211 
1212   /**
1213    * GtkPrintOperation:export-filename:
1214    *
1215    * The name of a file to generate instead of showing the print dialog.
1216    * Currently, PDF is the only supported format.
1217    *
1218    * The intended use of this property is for implementing
1219    * "Export to PDF" actions.
1220    *
1221    * "Print to PDF" support is independent of this and is done
1222    * by letting the user pick the "Print to PDF" item from the
1223    * list of printers in the print dialog.
1224    *
1225    * Since: 2.10
1226    */
1227   g_object_class_install_property (gobject_class,
1228 				   PROP_EXPORT_FILENAME,
1229 				   g_param_spec_string ("export-filename",
1230 							P_("Export filename"),
1231 							P_("Export filename"),
1232 							NULL,
1233 							GTK_PARAM_READWRITE));
1234 
1235   /**
1236    * GtkPrintOperation:status:
1237    *
1238    * The status of the print operation.
1239    *
1240    * Since: 2.10
1241    */
1242   g_object_class_install_property (gobject_class,
1243 				   PROP_STATUS,
1244 				   g_param_spec_enum ("status",
1245 						      P_("Status"),
1246 						      P_("The status of the print operation"),
1247 						      GTK_TYPE_PRINT_STATUS,
1248 						      GTK_PRINT_STATUS_INITIAL,
1249 						      GTK_PARAM_READABLE));
1250 
1251   /**
1252    * GtkPrintOperation:status-string:
1253    *
1254    * A string representation of the status of the print operation.
1255    * The string is translated and suitable for displaying the print
1256    * status e.g. in a #GtkStatusbar.
1257    *
1258    * See the #GtkPrintOperation:status property for a status value that
1259    * is suitable for programmatic use.
1260    *
1261    * Since: 2.10
1262    */
1263   g_object_class_install_property (gobject_class,
1264 				   PROP_STATUS_STRING,
1265 				   g_param_spec_string ("status-string",
1266 							P_("Status String"),
1267 							P_("A human-readable description of the status"),
1268 							"",
1269 							GTK_PARAM_READABLE));
1270 
1271 
1272   /**
1273    * GtkPrintOperation:custom-tab-label:
1274    *
1275    * Used as the label of the tab containing custom widgets.
1276    * Note that this property may be ignored on some platforms.
1277    *
1278    * If this is %NULL, GTK+ uses a default label.
1279    *
1280    * Since: 2.10
1281    */
1282   g_object_class_install_property (gobject_class,
1283 				   PROP_CUSTOM_TAB_LABEL,
1284 				   g_param_spec_string ("custom-tab-label",
1285 							P_("Custom tab label"),
1286 							P_("Label for the tab containing custom widgets."),
1287 							NULL,
1288 							GTK_PARAM_READWRITE));
1289 
1290   /**
1291    * GtkPrintOperation:support-selection:
1292    *
1293    * If %TRUE, the print operation will support print of selection.
1294    * This allows the print dialog to show a "Selection" button.
1295    *
1296    * Since: 2.18
1297    */
1298   g_object_class_install_property (gobject_class,
1299 				   PROP_SUPPORT_SELECTION,
1300 				   g_param_spec_boolean ("support-selection",
1301 							 P_("Support Selection"),
1302 							 P_("TRUE if the print operation will support print of selection."),
1303 							 FALSE,
1304 							 GTK_PARAM_READWRITE));
1305 
1306   /**
1307    * GtkPrintOperation:has-selection:
1308    *
1309    * Determines whether there is a selection in your application.
1310    * This can allow your application to print the selection.
1311    * This is typically used to make a "Selection" button sensitive.
1312    *
1313    * Since: 2.18
1314    */
1315   g_object_class_install_property (gobject_class,
1316 				   PROP_HAS_SELECTION,
1317 				   g_param_spec_boolean ("has-selection",
1318 							 P_("Has Selection"),
1319 							 P_("TRUE if a selection exists."),
1320 							 FALSE,
1321 							 GTK_PARAM_READWRITE));
1322 
1323 
1324   /**
1325    * GtkPrintOperation:embed-page-setup:
1326    *
1327    * If %TRUE, page size combo box and orientation combo box are embedded into page setup page.
1328    *
1329    * Since: 2.18
1330    */
1331   g_object_class_install_property (gobject_class,
1332 				   PROP_EMBED_PAGE_SETUP,
1333 				   g_param_spec_boolean ("embed-page-setup",
1334 							 P_("Embed Page Setup"),
1335 							 P_("TRUE if page setup combos are embedded in GtkPrintDialog"),
1336 							 FALSE,
1337 							 GTK_PARAM_READWRITE));
1338   /**
1339    * GtkPrintOperation:n-pages-to-print:
1340    *
1341    * The number of pages that will be printed.
1342    *
1343    * Note that this value is set during print preparation phase
1344    * (%GTK_PRINT_STATUS_PREPARING), so this value should never be
1345    * get before the data generation phase (%GTK_PRINT_STATUS_GENERATING_DATA).
1346    * You can connect to the #GtkPrintOperation::status-changed signal
1347    * and call gtk_print_operation_get_n_pages_to_print() when
1348    * print status is %GTK_PRINT_STATUS_GENERATING_DATA.
1349    * This is typically used to track the progress of print operation.
1350    *
1351    * Since: 2.18
1352    */
1353   g_object_class_install_property (gobject_class,
1354 				   PROP_N_PAGES_TO_PRINT,
1355 				   g_param_spec_int ("n-pages-to-print",
1356 						     P_("Number of Pages To Print"),
1357 						     P_("The number of pages that will be printed."),
1358 						     -1,
1359 						     G_MAXINT,
1360 						     -1,
1361 						     GTK_PARAM_READABLE));
1362 }
1363 
1364 /**
1365  * gtk_print_operation_new:
1366  *
1367  * Creates a new #GtkPrintOperation.
1368  *
1369  * Returns: a new #GtkPrintOperation
1370  *
1371  * Since: 2.10
1372  */
1373 GtkPrintOperation *
gtk_print_operation_new(void)1374 gtk_print_operation_new (void)
1375 {
1376   GtkPrintOperation *print_operation;
1377 
1378   print_operation = g_object_new (GTK_TYPE_PRINT_OPERATION, NULL);
1379 
1380   return print_operation;
1381 }
1382 
1383 /**
1384  * gtk_print_operation_set_default_page_setup:
1385  * @op: a #GtkPrintOperation
1386  * @default_page_setup: (allow-none): a #GtkPageSetup, or %NULL
1387  *
1388  * Makes @default_page_setup the default page setup for @op.
1389  *
1390  * This page setup will be used by gtk_print_operation_run(),
1391  * but it can be overridden on a per-page basis by connecting
1392  * to the #GtkPrintOperation::request-page-setup signal.
1393  *
1394  * Since: 2.10
1395  **/
1396 void
gtk_print_operation_set_default_page_setup(GtkPrintOperation * op,GtkPageSetup * default_page_setup)1397 gtk_print_operation_set_default_page_setup (GtkPrintOperation *op,
1398 					    GtkPageSetup      *default_page_setup)
1399 {
1400   GtkPrintOperationPrivate *priv;
1401 
1402   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1403   g_return_if_fail (default_page_setup == NULL ||
1404                     GTK_IS_PAGE_SETUP (default_page_setup));
1405 
1406   priv = op->priv;
1407 
1408   if (default_page_setup != priv->default_page_setup)
1409     {
1410       if (default_page_setup)
1411 	g_object_ref (default_page_setup);
1412 
1413       if (priv->default_page_setup)
1414 	g_object_unref (priv->default_page_setup);
1415 
1416       priv->default_page_setup = default_page_setup;
1417 
1418       g_object_notify (G_OBJECT (op), "default-page-setup");
1419     }
1420 }
1421 
1422 /**
1423  * gtk_print_operation_get_default_page_setup:
1424  * @op: a #GtkPrintOperation
1425  *
1426  * Returns the default page setup, see
1427  * gtk_print_operation_set_default_page_setup().
1428  *
1429  * Returns: (transfer none): the default page setup
1430  *
1431  * Since: 2.10
1432  */
1433 GtkPageSetup *
gtk_print_operation_get_default_page_setup(GtkPrintOperation * op)1434 gtk_print_operation_get_default_page_setup (GtkPrintOperation *op)
1435 {
1436   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), NULL);
1437 
1438   return op->priv->default_page_setup;
1439 }
1440 
1441 
1442 /**
1443  * gtk_print_operation_set_print_settings:
1444  * @op: a #GtkPrintOperation
1445  * @print_settings: (allow-none): #GtkPrintSettings
1446  *
1447  * Sets the print settings for @op. This is typically used to
1448  * re-establish print settings from a previous print operation,
1449  * see gtk_print_operation_run().
1450  *
1451  * Since: 2.10
1452  **/
1453 void
gtk_print_operation_set_print_settings(GtkPrintOperation * op,GtkPrintSettings * print_settings)1454 gtk_print_operation_set_print_settings (GtkPrintOperation *op,
1455 					GtkPrintSettings  *print_settings)
1456 {
1457   GtkPrintOperationPrivate *priv;
1458 
1459   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1460   g_return_if_fail (print_settings == NULL ||
1461                     GTK_IS_PRINT_SETTINGS (print_settings));
1462 
1463   priv = op->priv;
1464 
1465   if (print_settings != priv->print_settings)
1466     {
1467       if (print_settings)
1468         g_object_ref (print_settings);
1469 
1470       if (priv->print_settings)
1471         g_object_unref (priv->print_settings);
1472 
1473       priv->print_settings = print_settings;
1474 
1475       g_object_notify (G_OBJECT (op), "print-settings");
1476     }
1477 }
1478 
1479 /**
1480  * gtk_print_operation_get_print_settings:
1481  * @op: a #GtkPrintOperation
1482  *
1483  * Returns the current print settings.
1484  *
1485  * Note that the return value is %NULL until either
1486  * gtk_print_operation_set_print_settings() or
1487  * gtk_print_operation_run() have been called.
1488  *
1489  * Return value: (transfer none): the current print settings of @op.
1490  *
1491  * Since: 2.10
1492  **/
1493 GtkPrintSettings *
gtk_print_operation_get_print_settings(GtkPrintOperation * op)1494 gtk_print_operation_get_print_settings (GtkPrintOperation *op)
1495 {
1496   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), NULL);
1497 
1498   return op->priv->print_settings;
1499 }
1500 
1501 /**
1502  * gtk_print_operation_set_job_name:
1503  * @op: a #GtkPrintOperation
1504  * @job_name: a string that identifies the print job
1505  *
1506  * Sets the name of the print job. The name is used to identify
1507  * the job (e.g. in monitoring applications like eggcups).
1508  *
1509  * If you don't set a job name, GTK+ picks a default one by
1510  * numbering successive print jobs.
1511  *
1512  * Since: 2.10
1513  **/
1514 void
gtk_print_operation_set_job_name(GtkPrintOperation * op,const gchar * job_name)1515 gtk_print_operation_set_job_name (GtkPrintOperation *op,
1516 				  const gchar       *job_name)
1517 {
1518   GtkPrintOperationPrivate *priv;
1519 
1520   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1521   g_return_if_fail (job_name != NULL);
1522 
1523   priv = op->priv;
1524 
1525   g_free (priv->job_name);
1526   priv->job_name = g_strdup (job_name);
1527 
1528   g_object_notify (G_OBJECT (op), "job-name");
1529 }
1530 
1531 /**
1532  * gtk_print_operation_set_n_pages:
1533  * @op: a #GtkPrintOperation
1534  * @n_pages: the number of pages
1535  *
1536  * Sets the number of pages in the document.
1537  *
1538  * This <emphasis>must</emphasis> be set to a positive number
1539  * before the rendering starts. It may be set in a
1540  * #GtkPrintOperation::begin-print signal hander.
1541  *
1542  * Note that the page numbers passed to the
1543  * #GtkPrintOperation::request-page-setup
1544  * and #GtkPrintOperation::draw-page signals are 0-based, i.e. if
1545  * the user chooses to print all pages, the last ::draw-page signal
1546  * will be for page @n_pages - 1.
1547  *
1548  * Since: 2.10
1549  **/
1550 void
gtk_print_operation_set_n_pages(GtkPrintOperation * op,gint n_pages)1551 gtk_print_operation_set_n_pages (GtkPrintOperation *op,
1552 				 gint               n_pages)
1553 {
1554   GtkPrintOperationPrivate *priv;
1555 
1556   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1557   g_return_if_fail (n_pages > 0);
1558 
1559   priv = op->priv;
1560   g_return_if_fail (priv->current_page == -1 ||
1561 		    priv->current_page < n_pages);
1562 
1563   if (priv->nr_of_pages != n_pages)
1564     {
1565       priv->nr_of_pages = n_pages;
1566 
1567       g_object_notify (G_OBJECT (op), "n-pages");
1568     }
1569 }
1570 
1571 /**
1572  * gtk_print_operation_set_current_page:
1573  * @op: a #GtkPrintOperation
1574  * @current_page: the current page, 0-based
1575  *
1576  * Sets the current page.
1577  *
1578  * If this is called before gtk_print_operation_run(),
1579  * the user will be able to select to print only the current page.
1580  *
1581  * Note that this only makes sense for pre-paginated documents.
1582  *
1583  * Since: 2.10
1584  **/
1585 void
gtk_print_operation_set_current_page(GtkPrintOperation * op,gint current_page)1586 gtk_print_operation_set_current_page (GtkPrintOperation *op,
1587 				      gint               current_page)
1588 {
1589   GtkPrintOperationPrivate *priv;
1590 
1591   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1592   g_return_if_fail (current_page >= 0);
1593 
1594   priv = op->priv;
1595   g_return_if_fail (priv->nr_of_pages == -1 ||
1596 		    current_page < priv->nr_of_pages);
1597 
1598   if (priv->current_page != current_page)
1599     {
1600       priv->current_page = current_page;
1601 
1602       g_object_notify (G_OBJECT (op), "current-page");
1603     }
1604 }
1605 
1606 /**
1607  * gtk_print_operation_set_use_full_page:
1608  * @op: a #GtkPrintOperation
1609  * @full_page: %TRUE to set up the #GtkPrintContext for the full page
1610  *
1611  * If @full_page is %TRUE, the transformation for the cairo context
1612  * obtained from #GtkPrintContext puts the origin at the top left
1613  * corner of the page (which may not be the top left corner of the
1614  * sheet, depending on page orientation and the number of pages per
1615  * sheet). Otherwise, the origin is at the top left corner of the
1616  * imageable area (i.e. inside the margins).
1617  *
1618  * Since: 2.10
1619  */
1620 void
gtk_print_operation_set_use_full_page(GtkPrintOperation * op,gboolean full_page)1621 gtk_print_operation_set_use_full_page (GtkPrintOperation *op,
1622 				       gboolean           full_page)
1623 {
1624   GtkPrintOperationPrivate *priv;
1625 
1626   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1627 
1628   full_page = full_page != FALSE;
1629 
1630   priv = op->priv;
1631 
1632   if (priv->use_full_page != full_page)
1633     {
1634       priv->use_full_page = full_page;
1635 
1636       g_object_notify (G_OBJECT (op), "use-full-page");
1637     }
1638 }
1639 
1640 /**
1641  * gtk_print_operation_set_unit:
1642  * @op: a #GtkPrintOperation
1643  * @unit: the unit to use
1644  *
1645  * Sets up the transformation for the cairo context obtained from
1646  * #GtkPrintContext in such a way that distances are measured in
1647  * units of @unit.
1648  *
1649  * Since: 2.10
1650  */
1651 void
gtk_print_operation_set_unit(GtkPrintOperation * op,GtkUnit unit)1652 gtk_print_operation_set_unit (GtkPrintOperation *op,
1653 			      GtkUnit            unit)
1654 {
1655   GtkPrintOperationPrivate *priv;
1656 
1657   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1658 
1659   priv = op->priv;
1660 
1661   if (priv->unit != unit)
1662     {
1663       priv->unit = unit;
1664 
1665       g_object_notify (G_OBJECT (op), "unit");
1666     }
1667 }
1668 
1669 /**
1670  * gtk_print_operation_set_track_print_status:
1671  * @op: a #GtkPrintOperation
1672  * @track_status: %TRUE to track status after printing
1673  *
1674  * If track_status is %TRUE, the print operation will try to continue report
1675  * on the status of the print job in the printer queues and printer. This
1676  * can allow your application to show things like "out of paper" issues,
1677  * and when the print job actually reaches the printer.
1678  *
1679  * This function is often implemented using some form of polling, so it should
1680  * not be enabled unless needed.
1681  *
1682  * Since: 2.10
1683  */
1684 void
gtk_print_operation_set_track_print_status(GtkPrintOperation * op,gboolean track_status)1685 gtk_print_operation_set_track_print_status (GtkPrintOperation  *op,
1686 					    gboolean            track_status)
1687 {
1688   GtkPrintOperationPrivate *priv;
1689 
1690   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1691 
1692   priv = op->priv;
1693 
1694   if (priv->track_print_status != track_status)
1695     {
1696       priv->track_print_status = track_status;
1697 
1698       g_object_notify (G_OBJECT (op), "track-print-status");
1699     }
1700 }
1701 
1702 void
_gtk_print_operation_set_status(GtkPrintOperation * op,GtkPrintStatus status,const gchar * string)1703 _gtk_print_operation_set_status (GtkPrintOperation *op,
1704 				 GtkPrintStatus     status,
1705 				 const gchar       *string)
1706 {
1707   GtkPrintOperationPrivate *priv = op->priv;
1708   static const gchar *status_strs[] = {
1709     NC_("print operation status", "Initial state"),
1710     NC_("print operation status", "Preparing to print"),
1711     NC_("print operation status", "Generating data"),
1712     NC_("print operation status", "Sending data"),
1713     NC_("print operation status", "Waiting"),
1714     NC_("print operation status", "Blocking on issue"),
1715     NC_("print operation status", "Printing"),
1716     NC_("print operation status", "Finished"),
1717     NC_("print operation status", "Finished with error")
1718   };
1719 
1720   if (status < 0 || status > GTK_PRINT_STATUS_FINISHED_ABORTED)
1721     status = GTK_PRINT_STATUS_FINISHED_ABORTED;
1722 
1723   if (string == NULL)
1724     string = g_dpgettext2 (GETTEXT_PACKAGE, "print operation status", status_strs[status]);
1725 
1726   if (priv->status == status &&
1727       strcmp (string, priv->status_string) == 0)
1728     return;
1729 
1730   g_free (priv->status_string);
1731   priv->status_string = g_strdup (string);
1732   priv->status = status;
1733 
1734   g_object_notify (G_OBJECT (op), "status");
1735   g_object_notify (G_OBJECT (op), "status-string");
1736 
1737   g_signal_emit (op, signals[STATUS_CHANGED], 0);
1738 }
1739 
1740 
1741 /**
1742  * gtk_print_operation_get_status:
1743  * @op: a #GtkPrintOperation
1744  *
1745  * Returns the status of the print operation.
1746  * Also see gtk_print_operation_get_status_string().
1747  *
1748  * Return value: the status of the print operation
1749  *
1750  * Since: 2.10
1751  **/
1752 GtkPrintStatus
gtk_print_operation_get_status(GtkPrintOperation * op)1753 gtk_print_operation_get_status (GtkPrintOperation *op)
1754 {
1755   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op),
1756                         GTK_PRINT_STATUS_FINISHED_ABORTED);
1757 
1758   return op->priv->status;
1759 }
1760 
1761 /**
1762  * gtk_print_operation_get_status_string:
1763  * @op: a #GtkPrintOperation
1764  *
1765  * Returns a string representation of the status of the
1766  * print operation. The string is translated and suitable
1767  * for displaying the print status e.g. in a #GtkStatusbar.
1768  *
1769  * Use gtk_print_operation_get_status() to obtain a status
1770  * value that is suitable for programmatic use.
1771  *
1772  * Return value: a string representation of the status
1773  *    of the print operation
1774  *
1775  * Since: 2.10
1776  **/
1777 const gchar *
gtk_print_operation_get_status_string(GtkPrintOperation * op)1778 gtk_print_operation_get_status_string (GtkPrintOperation *op)
1779 {
1780   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), "");
1781 
1782   return op->priv->status_string;
1783 }
1784 
1785 /**
1786  * gtk_print_operation_is_finished:
1787  * @op: a #GtkPrintOperation
1788  *
1789  * A convenience function to find out if the print operation
1790  * is finished, either successfully (%GTK_PRINT_STATUS_FINISHED)
1791  * or unsuccessfully (%GTK_PRINT_STATUS_FINISHED_ABORTED).
1792  *
1793  * Note: when you enable print status tracking the print operation
1794  * can be in a non-finished state even after done has been called, as
1795  * the operation status then tracks the print job status on the printer.
1796  *
1797  * Return value: %TRUE, if the print operation is finished.
1798  *
1799  * Since: 2.10
1800  **/
1801 gboolean
gtk_print_operation_is_finished(GtkPrintOperation * op)1802 gtk_print_operation_is_finished (GtkPrintOperation *op)
1803 {
1804   GtkPrintOperationPrivate *priv;
1805 
1806   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), TRUE);
1807 
1808   priv = op->priv;
1809   return
1810     priv->status == GTK_PRINT_STATUS_FINISHED_ABORTED ||
1811     priv->status == GTK_PRINT_STATUS_FINISHED;
1812 }
1813 
1814 /**
1815  * gtk_print_operation_set_show_progress:
1816  * @op: a #GtkPrintOperation
1817  * @show_progress: %TRUE to show a progress dialog
1818  *
1819  * If @show_progress is %TRUE, the print operation will show a
1820  * progress dialog during the print operation.
1821  *
1822  * Since: 2.10
1823  */
1824 void
gtk_print_operation_set_show_progress(GtkPrintOperation * op,gboolean show_progress)1825 gtk_print_operation_set_show_progress (GtkPrintOperation  *op,
1826 				       gboolean            show_progress)
1827 {
1828   GtkPrintOperationPrivate *priv;
1829 
1830   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1831 
1832   priv = op->priv;
1833 
1834   show_progress = show_progress != FALSE;
1835 
1836   if (priv->show_progress != show_progress)
1837     {
1838       priv->show_progress = show_progress;
1839 
1840       g_object_notify (G_OBJECT (op), "show-progress");
1841     }
1842 }
1843 
1844 /**
1845  * gtk_print_operation_set_allow_async:
1846  * @op: a #GtkPrintOperation
1847  * @allow_async: %TRUE to allow asynchronous operation
1848  *
1849  * Sets whether the gtk_print_operation_run() may return
1850  * before the print operation is completed. Note that
1851  * some platforms may not allow asynchronous operation.
1852  *
1853  * Since: 2.10
1854  */
1855 void
gtk_print_operation_set_allow_async(GtkPrintOperation * op,gboolean allow_async)1856 gtk_print_operation_set_allow_async (GtkPrintOperation  *op,
1857 				     gboolean            allow_async)
1858 {
1859   GtkPrintOperationPrivate *priv;
1860 
1861   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1862 
1863   priv = op->priv;
1864 
1865   allow_async = allow_async != FALSE;
1866 
1867   if (priv->allow_async != allow_async)
1868     {
1869       priv->allow_async = allow_async;
1870 
1871       g_object_notify (G_OBJECT (op), "allow-async");
1872     }
1873 }
1874 
1875 
1876 /**
1877  * gtk_print_operation_set_custom_tab_label:
1878  * @op: a #GtkPrintOperation
1879  * @label: (allow-none): the label to use, or %NULL to use the default label
1880  *
1881  * Sets the label for the tab holding custom widgets.
1882  *
1883  * Since: 2.10
1884  */
1885 void
gtk_print_operation_set_custom_tab_label(GtkPrintOperation * op,const gchar * label)1886 gtk_print_operation_set_custom_tab_label (GtkPrintOperation  *op,
1887 					  const gchar        *label)
1888 {
1889   GtkPrintOperationPrivate *priv;
1890 
1891   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1892 
1893   priv = op->priv;
1894 
1895   g_free (priv->custom_tab_label);
1896   priv->custom_tab_label = g_strdup (label);
1897 
1898   g_object_notify (G_OBJECT (op), "custom-tab-label");
1899 }
1900 
1901 
1902 /**
1903  * gtk_print_operation_set_export_filename:
1904  * @op: a #GtkPrintOperation
1905  * @filename: the filename for the exported file
1906  *
1907  * Sets up the #GtkPrintOperation to generate a file instead
1908  * of showing the print dialog. The indended use of this function
1909  * is for implementing "Export to PDF" actions. Currently, PDF
1910  * is the only supported format.
1911  *
1912  * "Print to PDF" support is independent of this and is done
1913  * by letting the user pick the "Print to PDF" item from the list
1914  * of printers in the print dialog.
1915  *
1916  * Since: 2.10
1917  */
1918 void
gtk_print_operation_set_export_filename(GtkPrintOperation * op,const gchar * filename)1919 gtk_print_operation_set_export_filename (GtkPrintOperation *op,
1920 					 const gchar       *filename)
1921 {
1922   GtkPrintOperationPrivate *priv;
1923 
1924   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1925 
1926   priv = op->priv;
1927 
1928   g_free (priv->export_filename);
1929   priv->export_filename = g_strdup (filename);
1930 
1931   g_object_notify (G_OBJECT (op), "export-filename");
1932 }
1933 
1934 /* Creates the initial page setup used for printing unless the
1935  * app overrides this on a per-page basis using request_page_setup.
1936  *
1937  * Data is taken from, in order, if existing:
1938  *
1939  * PrintSettings returned from the print dialog
1940  *  (initial dialog values are set from default_page_setup
1941  *   if unset in app specified print_settings)
1942  * default_page_setup
1943  * per-locale default setup
1944  */
1945 static GtkPageSetup *
create_page_setup(GtkPrintOperation * op)1946 create_page_setup (GtkPrintOperation *op)
1947 {
1948   GtkPrintOperationPrivate *priv = op->priv;
1949   GtkPageSetup *page_setup;
1950   GtkPrintSettings *settings;
1951 
1952   if (priv->default_page_setup)
1953     page_setup = gtk_page_setup_copy (priv->default_page_setup);
1954   else
1955     page_setup = gtk_page_setup_new ();
1956 
1957   settings = priv->print_settings;
1958   if (settings)
1959     {
1960       GtkPaperSize *paper_size;
1961 
1962       if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_ORIENTATION))
1963 	gtk_page_setup_set_orientation (page_setup,
1964 					gtk_print_settings_get_orientation (settings));
1965 
1966 
1967       paper_size = gtk_print_settings_get_paper_size (settings);
1968       if (paper_size)
1969 	{
1970 	  gtk_page_setup_set_paper_size (page_setup, paper_size);
1971 	  gtk_paper_size_free (paper_size);
1972 	}
1973 
1974       /* TODO: Margins? */
1975     }
1976 
1977   return page_setup;
1978 }
1979 
1980 static void
pdf_start_page(GtkPrintOperation * op,GtkPrintContext * print_context,GtkPageSetup * page_setup)1981 pdf_start_page (GtkPrintOperation *op,
1982 		GtkPrintContext   *print_context,
1983 		GtkPageSetup      *page_setup)
1984 {
1985   GtkPaperSize *paper_size;
1986   cairo_surface_t *surface = op->priv->platform_data;
1987   gdouble w, h;
1988 
1989   paper_size = gtk_page_setup_get_paper_size (page_setup);
1990 
1991   w = gtk_paper_size_get_width (paper_size, GTK_UNIT_POINTS);
1992   h = gtk_paper_size_get_height (paper_size, GTK_UNIT_POINTS);
1993 
1994   cairo_pdf_surface_set_size (surface, w, h);
1995 }
1996 
1997 static void
pdf_end_page(GtkPrintOperation * op,GtkPrintContext * print_context)1998 pdf_end_page (GtkPrintOperation *op,
1999 	      GtkPrintContext   *print_context)
2000 {
2001   cairo_t *cr;
2002 
2003   cr = gtk_print_context_get_cairo_context (print_context);
2004 
2005   if ((op->priv->manual_number_up < 2) ||
2006       ((op->priv->page_position + 1) % op->priv->manual_number_up == 0) ||
2007       (op->priv->page_position == op->priv->nr_of_pages_to_print - 1))
2008     cairo_show_page (cr);
2009 }
2010 
2011 static void
pdf_end_run(GtkPrintOperation * op,gboolean wait,gboolean cancelled)2012 pdf_end_run (GtkPrintOperation *op,
2013 	     gboolean           wait,
2014 	     gboolean           cancelled)
2015 {
2016   GtkPrintOperationPrivate *priv = op->priv;
2017   cairo_surface_t *surface = priv->platform_data;
2018 
2019   cairo_surface_finish (surface);
2020   cairo_surface_destroy (surface);
2021 
2022   priv->platform_data = NULL;
2023   priv->free_platform_data = NULL;
2024 }
2025 
2026 static GtkPrintOperationResult
run_pdf(GtkPrintOperation * op,GtkWindow * parent,gboolean * do_print)2027 run_pdf (GtkPrintOperation  *op,
2028 	 GtkWindow          *parent,
2029 	 gboolean           *do_print)
2030 {
2031   GtkPrintOperationPrivate *priv = op->priv;
2032   GtkPageSetup *page_setup;
2033   cairo_surface_t *surface;
2034   cairo_t *cr;
2035   gdouble width, height;
2036 
2037   priv->print_context = _gtk_print_context_new (op);
2038 
2039   page_setup = create_page_setup (op);
2040   _gtk_print_context_set_page_setup (priv->print_context, page_setup);
2041 
2042   /* This will be overwritten later by the non-default size, but
2043      we need to pass some size: */
2044   width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS);
2045   height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS);
2046   g_object_unref (page_setup);
2047 
2048   surface = cairo_pdf_surface_create (priv->export_filename,
2049 				      width, height);
2050   if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
2051     {
2052       g_set_error_literal (&priv->error,
2053                            GTK_PRINT_ERROR,
2054                            GTK_PRINT_ERROR_GENERAL,
2055                            cairo_status_to_string (cairo_surface_status (surface)));
2056       *do_print = FALSE;
2057       return GTK_PRINT_OPERATION_RESULT_ERROR;
2058     }
2059 
2060   /* this would crash on a nil surface */
2061   cairo_surface_set_fallback_resolution (surface, 300, 300);
2062 
2063   priv->platform_data = surface;
2064   priv->free_platform_data = (GDestroyNotify) cairo_surface_destroy;
2065 
2066   cr = cairo_create (surface);
2067   gtk_print_context_set_cairo_context (op->priv->print_context,
2068 				       cr, 72, 72);
2069   cairo_destroy (cr);
2070 
2071 
2072   priv->print_pages = GTK_PRINT_PAGES_ALL;
2073   priv->page_ranges = NULL;
2074   priv->num_page_ranges = 0;
2075 
2076   priv->manual_num_copies = 1;
2077   priv->manual_collation = FALSE;
2078   priv->manual_reverse = FALSE;
2079   priv->manual_page_set = GTK_PAGE_SET_ALL;
2080   priv->manual_scale = 1.0;
2081   priv->manual_orientation = TRUE;
2082   priv->manual_number_up = 1;
2083   priv->manual_number_up_layout = GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM;
2084 
2085   *do_print = TRUE;
2086 
2087   priv->start_page = pdf_start_page;
2088   priv->end_page = pdf_end_page;
2089   priv->end_run = pdf_end_run;
2090 
2091   return GTK_PRINT_OPERATION_RESULT_APPLY;
2092 }
2093 
2094 
2095 static void
clamp_page_ranges(PrintPagesData * data)2096 clamp_page_ranges (PrintPagesData *data)
2097 {
2098   GtkPrintOperationPrivate *priv;
2099   gint                      num_of_correct_ranges;
2100   gint                      i;
2101 
2102   priv = data->op->priv;
2103 
2104   num_of_correct_ranges = 0;
2105 
2106   for (i = 0; i < data->num_ranges; i++)
2107     if ((data->ranges[i].start >= 0) &&
2108         (data->ranges[i].start < priv->nr_of_pages) &&
2109         (data->ranges[i].end >= 0) &&
2110         (data->ranges[i].end < priv->nr_of_pages))
2111       {
2112         data->ranges[num_of_correct_ranges] = data->ranges[i];
2113         num_of_correct_ranges++;
2114       }
2115     else if ((data->ranges[i].start >= 0) &&
2116              (data->ranges[i].start < priv->nr_of_pages) &&
2117              (data->ranges[i].end >= priv->nr_of_pages))
2118       {
2119         data->ranges[i].end = priv->nr_of_pages - 1;
2120         data->ranges[num_of_correct_ranges] = data->ranges[i];
2121         num_of_correct_ranges++;
2122       }
2123     else if ((data->ranges[i].end >= 0) &&
2124              (data->ranges[i].end < priv->nr_of_pages) &&
2125              (data->ranges[i].start < 0))
2126       {
2127         data->ranges[i].start = 0;
2128         data->ranges[num_of_correct_ranges] = data->ranges[i];
2129         num_of_correct_ranges++;
2130       }
2131 
2132   data->num_ranges = num_of_correct_ranges;
2133 }
2134 
2135 static void
increment_page_sequence(PrintPagesData * data)2136 increment_page_sequence (PrintPagesData *data)
2137 {
2138   GtkPrintOperationPrivate *priv = data->op->priv;
2139   gint inc;
2140 
2141   if (data->total == -1)
2142     {
2143       data->total = 0;
2144       return;
2145     }
2146 
2147   /* check whether we reached last position */
2148   if (priv->page_position == data->last_position &&
2149       !(data->collated_copies > 1 && data->collated < (data->collated_copies - 1)))
2150     {
2151       if (data->uncollated_copies > 1 && data->uncollated < (data->uncollated_copies - 1))
2152         {
2153           priv->page_position = data->first_position;
2154           data->sheet = data->first_sheet;
2155           data->uncollated++;
2156         }
2157       else
2158         {
2159           data->done = TRUE;
2160 	  return;
2161         }
2162     }
2163   else
2164     {
2165       if (priv->manual_reverse)
2166         inc = -1;
2167       else
2168         inc = 1;
2169 
2170       /* changing sheet */
2171       if (priv->manual_number_up < 2 ||
2172           (priv->page_position + 1) % priv->manual_number_up == 0 ||
2173           priv->page_position == data->last_position ||
2174           priv->page_position == priv->nr_of_pages_to_print - 1)
2175         {
2176           /* check whether to print the same sheet again */
2177           if (data->collated_copies > 1)
2178             {
2179               if (data->collated < (data->collated_copies - 1))
2180                 {
2181                   data->collated++;
2182                   data->total++;
2183                   priv->page_position = data->sheet * priv->manual_number_up;
2184 
2185                   if (priv->page_position < 0 ||
2186                       priv->page_position >= priv->nr_of_pages_to_print ||
2187                       data->sheet < 0 ||
2188                       data->sheet >= data->num_of_sheets)
2189 		    {
2190                       data->done = TRUE;
2191 		      return;
2192 		    }
2193                   else
2194                     data->page = data->pages[priv->page_position];
2195 
2196                   return;
2197                 }
2198               else
2199                 data->collated = 0;
2200             }
2201 
2202           if (priv->manual_page_set == GTK_PAGE_SET_ODD ||
2203               priv->manual_page_set == GTK_PAGE_SET_EVEN)
2204             data->sheet += 2 * inc;
2205           else
2206             data->sheet += inc;
2207 
2208           priv->page_position = data->sheet * priv->manual_number_up;
2209         }
2210       else
2211         priv->page_position += 1;
2212     }
2213 
2214   /* general check */
2215   if (priv->page_position < 0 ||
2216       priv->page_position >= priv->nr_of_pages_to_print ||
2217       data->sheet < 0 ||
2218       data->sheet >= data->num_of_sheets)
2219     {
2220       data->done = TRUE;
2221       return;
2222     }
2223   else
2224     data->page = data->pages[priv->page_position];
2225 
2226   data->total++;
2227 }
2228 
2229 static void
print_pages_idle_done(gpointer user_data)2230 print_pages_idle_done (gpointer user_data)
2231 {
2232   PrintPagesData *data;
2233   GtkPrintOperationPrivate *priv;
2234 
2235   data = (PrintPagesData*)user_data;
2236   priv = data->op->priv;
2237 
2238   priv->print_pages_idle_id = 0;
2239 
2240   if (priv->show_progress_timeout_id > 0)
2241     {
2242       g_source_remove (priv->show_progress_timeout_id);
2243       priv->show_progress_timeout_id = 0;
2244     }
2245 
2246   if (data->progress)
2247     gtk_widget_destroy (data->progress);
2248 
2249   if (priv->rloop && !data->is_preview)
2250     g_main_loop_quit (priv->rloop);
2251 
2252   if (!data->is_preview)
2253     g_signal_emit (data->op, signals[DONE], 0,
2254 		   priv->cancelled ?
2255 		   GTK_PRINT_OPERATION_RESULT_CANCEL :
2256 		   GTK_PRINT_OPERATION_RESULT_APPLY);
2257 
2258   g_object_unref (data->op);
2259   g_free (data->pages);
2260   g_free (data);
2261 }
2262 
2263 static void
update_progress(PrintPagesData * data)2264 update_progress (PrintPagesData *data)
2265 {
2266   GtkPrintOperationPrivate *priv;
2267   gchar *text = NULL;
2268 
2269   priv = data->op->priv;
2270 
2271   if (data->progress)
2272     {
2273       if (priv->status == GTK_PRINT_STATUS_PREPARING)
2274 	{
2275 	  if (priv->nr_of_pages_to_print > 0)
2276 	    text = g_strdup_printf (_("Preparing %d"), priv->nr_of_pages_to_print);
2277 	  else
2278 	    text = g_strdup (_("Preparing"));
2279 	}
2280       else if (priv->status == GTK_PRINT_STATUS_GENERATING_DATA)
2281 	text = g_strdup_printf (_("Printing %d"), data->total);
2282 
2283       if (text)
2284 	{
2285 	  g_object_set (data->progress, "text", text, NULL);
2286 	  g_free (text);
2287 	}
2288     }
2289  }
2290 
2291 /**
2292  * gtk_print_operation_set_defer_drawing:
2293  * @op: a #GtkPrintOperation
2294  *
2295  * Sets up the #GtkPrintOperation to wait for calling of
2296  * gtk_print_operation_draw_page_finish() from application. It can
2297  * be used for drawing page in another thread.
2298  *
2299  * This function must be called in the callback of "draw-page" signal.
2300  *
2301  * Since: 2.16
2302  **/
2303 void
gtk_print_operation_set_defer_drawing(GtkPrintOperation * op)2304 gtk_print_operation_set_defer_drawing (GtkPrintOperation *op)
2305 {
2306   GtkPrintOperationPrivate *priv = op->priv;
2307 
2308   g_return_if_fail (priv->page_drawing_state == GTK_PAGE_DRAWING_STATE_DRAWING);
2309 
2310   priv->page_drawing_state = GTK_PAGE_DRAWING_STATE_DEFERRED_DRAWING;
2311 }
2312 
2313 /**
2314  * gtk_print_operation_set_embed_page_setup:
2315  * @op: a #GtkPrintOperation
2316  * @embed: %TRUE to embed page setup selection in the #GtkPrintDialog
2317  *
2318  * Embed page size combo box and orientation combo box into page setup page.
2319  * Selected page setup is stored as default page setup in #GtkPrintOperation.
2320  *
2321  * Since: 2.18
2322  **/
2323 void
gtk_print_operation_set_embed_page_setup(GtkPrintOperation * op,gboolean embed)2324 gtk_print_operation_set_embed_page_setup (GtkPrintOperation  *op,
2325                                           gboolean            embed)
2326 {
2327   GtkPrintOperationPrivate *priv;
2328 
2329   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
2330 
2331   priv = op->priv;
2332 
2333   embed = embed != FALSE;
2334   if (priv->embed_page_setup != embed)
2335     {
2336       priv->embed_page_setup = embed;
2337       g_object_notify (G_OBJECT (op), "embed-page-setup");
2338     }
2339 }
2340 
2341 /**
2342  * gtk_print_operation_get_embed_page_setup:
2343  * @op: a #GtkPrintOperation
2344  *
2345  * Gets the value of #GtkPrintOperation::embed-page-setup property.
2346  *
2347  * Returns: whether page setup selection combos are embedded
2348  *
2349  * Since: 2.18
2350  */
2351 gboolean
gtk_print_operation_get_embed_page_setup(GtkPrintOperation * op)2352 gtk_print_operation_get_embed_page_setup (GtkPrintOperation *op)
2353 {
2354   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), FALSE);
2355 
2356   return op->priv->embed_page_setup;
2357 }
2358 
2359 /**
2360  * gtk_print_operation_draw_page_finish:
2361  * @op: a #GtkPrintOperation
2362  *
2363  * Signalize that drawing of particular page is complete.
2364  *
2365  * It is called after completion of page drawing (e.g. drawing in another
2366  * thread).
2367  * If gtk_print_operation_set_defer_drawing() was called before, then this function
2368  * has to be called by application. In another case it is called by the library
2369  * itself.
2370  *
2371  * Since: 2.16
2372  **/
2373 void
gtk_print_operation_draw_page_finish(GtkPrintOperation * op)2374 gtk_print_operation_draw_page_finish (GtkPrintOperation *op)
2375 {
2376   GtkPrintOperationPrivate *priv = op->priv;
2377   GtkPageSetup *page_setup;
2378   GtkPrintContext *print_context;
2379   cairo_t *cr;
2380 
2381   print_context = priv->print_context;
2382   page_setup = gtk_print_context_get_page_setup (print_context);
2383 
2384   cr = gtk_print_context_get_cairo_context (print_context);
2385 
2386   priv->end_page (op, print_context);
2387 
2388   cairo_restore (cr);
2389 
2390   g_object_unref (page_setup);
2391 
2392   priv->page_drawing_state = GTK_PAGE_DRAWING_STATE_READY;
2393 }
2394 
2395 static void
common_render_page(GtkPrintOperation * op,gint page_nr)2396 common_render_page (GtkPrintOperation *op,
2397 		    gint               page_nr)
2398 {
2399   GtkPrintOperationPrivate *priv = op->priv;
2400   GtkPageSetup *page_setup;
2401   GtkPrintContext *print_context;
2402   cairo_t *cr;
2403 
2404   print_context = priv->print_context;
2405 
2406   page_setup = create_page_setup (op);
2407 
2408   g_signal_emit (op, signals[REQUEST_PAGE_SETUP], 0,
2409 		 print_context, page_nr, page_setup);
2410 
2411   _gtk_print_context_set_page_setup (print_context, page_setup);
2412 
2413   priv->start_page (op, print_context, page_setup);
2414 
2415   cr = gtk_print_context_get_cairo_context (print_context);
2416 
2417   cairo_save (cr);
2418   if (priv->manual_scale != 1.0 && priv->manual_number_up <= 1)
2419     cairo_scale (cr,
2420 		 priv->manual_scale,
2421 		 priv->manual_scale);
2422 
2423   if (priv->manual_orientation)
2424     _gtk_print_context_rotate_according_to_orientation (print_context);
2425 
2426   if (priv->manual_number_up > 1)
2427     {
2428       GtkPageOrientation  orientation;
2429       GtkPageSetup       *page_setup;
2430       gdouble             paper_width, paper_height;
2431       gdouble             page_width, page_height;
2432       gdouble             context_width, context_height;
2433       gdouble             bottom_margin, top_margin, left_margin, right_margin;
2434       gdouble             x_step, y_step;
2435       gdouble             x_scale, y_scale, scale;
2436       gdouble             horizontal_offset = 0.0, vertical_offset = 0.0;
2437       gint                columns, rows, x, y, tmp_length;
2438 
2439       page_setup = gtk_print_context_get_page_setup (print_context);
2440       orientation = gtk_page_setup_get_orientation (page_setup);
2441 
2442       top_margin = gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_POINTS);
2443       bottom_margin = gtk_page_setup_get_bottom_margin (page_setup, GTK_UNIT_POINTS);
2444       left_margin = gtk_page_setup_get_left_margin (page_setup, GTK_UNIT_POINTS);
2445       right_margin = gtk_page_setup_get_right_margin (page_setup, GTK_UNIT_POINTS);
2446 
2447       paper_width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS);
2448       paper_height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS);
2449 
2450       context_width = gtk_print_context_get_width (print_context);
2451       context_height = gtk_print_context_get_height (print_context);
2452 
2453       if (orientation == GTK_PAGE_ORIENTATION_PORTRAIT ||
2454           orientation == GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
2455         {
2456           page_width = paper_width - (left_margin + right_margin);
2457           page_height = paper_height - (top_margin + bottom_margin);
2458         }
2459       else
2460         {
2461           page_width = paper_width - (top_margin + bottom_margin);
2462           page_height = paper_height - (left_margin + right_margin);
2463         }
2464 
2465       if (orientation == GTK_PAGE_ORIENTATION_PORTRAIT ||
2466           orientation == GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
2467         cairo_translate (cr, left_margin, top_margin);
2468       else
2469         cairo_translate (cr, top_margin, left_margin);
2470 
2471       switch (priv->manual_number_up)
2472         {
2473           default:
2474             columns = 1;
2475             rows = 1;
2476             break;
2477           case 2:
2478             columns = 2;
2479             rows = 1;
2480             break;
2481           case 4:
2482             columns = 2;
2483             rows = 2;
2484             break;
2485           case 6:
2486             columns = 3;
2487             rows = 2;
2488             break;
2489           case 9:
2490             columns = 3;
2491             rows = 3;
2492             break;
2493           case 16:
2494             columns = 4;
2495             rows = 4;
2496             break;
2497         }
2498 
2499       if (orientation == GTK_PAGE_ORIENTATION_LANDSCAPE ||
2500           orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE)
2501         {
2502           tmp_length = columns;
2503           columns = rows;
2504           rows = tmp_length;
2505         }
2506 
2507       switch (priv->manual_number_up_layout)
2508         {
2509           case GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM:
2510             x = priv->page_position % columns;
2511             y = (priv->page_position / columns) % rows;
2512             break;
2513           case GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_BOTTOM_TO_TOP:
2514             x = priv->page_position % columns;
2515             y = rows - 1 - (priv->page_position / columns) % rows;
2516             break;
2517           case GTK_NUMBER_UP_LAYOUT_RIGHT_TO_LEFT_TOP_TO_BOTTOM:
2518             x = columns - 1 - priv->page_position % columns;
2519             y = (priv->page_position / columns) % rows;
2520             break;
2521           case GTK_NUMBER_UP_LAYOUT_RIGHT_TO_LEFT_BOTTOM_TO_TOP:
2522             x = columns - 1 - priv->page_position % columns;
2523             y = rows - 1 - (priv->page_position / columns) % rows;
2524             break;
2525           case GTK_NUMBER_UP_LAYOUT_TOP_TO_BOTTOM_LEFT_TO_RIGHT:
2526             x = (priv->page_position / rows) % columns;
2527             y = priv->page_position % rows;
2528             break;
2529           case GTK_NUMBER_UP_LAYOUT_TOP_TO_BOTTOM_RIGHT_TO_LEFT:
2530             x = columns - 1 - (priv->page_position / rows) % columns;
2531             y = priv->page_position % rows;
2532             break;
2533           case GTK_NUMBER_UP_LAYOUT_BOTTOM_TO_TOP_LEFT_TO_RIGHT:
2534             x = (priv->page_position / rows) % columns;
2535             y = rows - 1 - priv->page_position % rows;
2536             break;
2537           case GTK_NUMBER_UP_LAYOUT_BOTTOM_TO_TOP_RIGHT_TO_LEFT:
2538             x = columns - 1 - (priv->page_position / rows) % columns;
2539             y = rows - 1 - priv->page_position % rows;
2540             break;
2541           default:
2542             g_assert_not_reached();
2543             x = 0;
2544             y = 0;
2545         }
2546 
2547       if (priv->manual_number_up == 4 || priv->manual_number_up == 9 || priv->manual_number_up == 16)
2548         {
2549           x_scale = page_width / (columns * paper_width);
2550           y_scale = page_height / (rows * paper_height);
2551 
2552           scale = x_scale < y_scale ? x_scale : y_scale;
2553 
2554           x_step = paper_width * (x_scale / scale);
2555           y_step = paper_height * (y_scale / scale);
2556 
2557           if ((left_margin + right_margin) > 0)
2558             {
2559               horizontal_offset = left_margin * (x_step - context_width) / (left_margin + right_margin);
2560               vertical_offset = top_margin * (y_step - context_height) / (top_margin + bottom_margin);
2561             }
2562           else
2563             {
2564               horizontal_offset = (x_step - context_width) / 2.0;
2565               vertical_offset = (y_step - context_height) / 2.0;
2566             }
2567 
2568           cairo_scale (cr, scale, scale);
2569 
2570           cairo_translate (cr,
2571                            x * x_step + horizontal_offset,
2572                            y * y_step + vertical_offset);
2573 
2574           if (priv->manual_scale != 1.0)
2575             cairo_scale (cr, priv->manual_scale, priv->manual_scale);
2576         }
2577 
2578       if (priv->manual_number_up == 2 || priv->manual_number_up == 6)
2579         {
2580           x_scale = page_height / (columns * paper_width);
2581           y_scale = page_width / (rows * paper_height);
2582 
2583           scale = x_scale < y_scale ? x_scale : y_scale;
2584 
2585           horizontal_offset = (paper_width * (x_scale / scale) - paper_width) / 2.0 * columns;
2586           vertical_offset = (paper_height * (y_scale / scale) - paper_height) / 2.0 * rows;
2587 
2588           if (!priv->use_full_page)
2589             {
2590               horizontal_offset -= right_margin;
2591               vertical_offset += top_margin;
2592             }
2593 
2594           cairo_scale (cr, scale, scale);
2595 
2596           cairo_translate (cr,
2597                            y * paper_height + vertical_offset,
2598                            (columns - x) * paper_width + horizontal_offset);
2599 
2600           if (priv->manual_scale != 1.0)
2601             cairo_scale (cr, priv->manual_scale, priv->manual_scale);
2602 
2603           cairo_rotate (cr, - G_PI / 2);
2604         }
2605     }
2606   else
2607     if (!priv->use_full_page)
2608       _gtk_print_context_translate_into_margin (print_context);
2609 
2610   priv->page_drawing_state = GTK_PAGE_DRAWING_STATE_DRAWING;
2611 
2612   g_signal_emit (op, signals[DRAW_PAGE], 0,
2613 		 print_context, page_nr);
2614 
2615   if (priv->page_drawing_state == GTK_PAGE_DRAWING_STATE_DRAWING)
2616     gtk_print_operation_draw_page_finish (op);
2617 }
2618 
2619 static void
prepare_data(PrintPagesData * data)2620 prepare_data (PrintPagesData *data)
2621 {
2622   GtkPrintOperationPrivate *priv;
2623   GtkPageSetup             *page_setup;
2624   gboolean                  paginated = FALSE;
2625   gint                      i, j, counter;
2626 
2627   priv = data->op->priv;
2628 
2629   if (priv->manual_collation)
2630     {
2631       data->uncollated_copies = priv->manual_num_copies;
2632       data->collated_copies = 1;
2633     }
2634   else
2635     {
2636       data->uncollated_copies = 1;
2637       data->collated_copies = priv->manual_num_copies;
2638     }
2639 
2640   if (!data->initialized)
2641     {
2642       data->initialized = TRUE;
2643       page_setup = create_page_setup (data->op);
2644       _gtk_print_context_set_page_setup (priv->print_context,
2645                                          page_setup);
2646       g_object_unref (page_setup);
2647 
2648       g_signal_emit (data->op, signals[BEGIN_PRINT], 0, priv->print_context);
2649 
2650       return;
2651     }
2652 
2653   g_signal_emit (data->op, signals[PAGINATE], 0, priv->print_context, &paginated);
2654   if (!paginated)
2655     return;
2656 
2657   /* Initialize parts of PrintPagesData that depend on nr_of_pages
2658    */
2659   if (priv->print_pages == GTK_PRINT_PAGES_RANGES)
2660     {
2661       if (priv->page_ranges == NULL)
2662         {
2663           g_warning ("no pages to print");
2664           priv->cancelled = TRUE;
2665           return;
2666         }
2667       data->ranges = priv->page_ranges;
2668       data->num_ranges = priv->num_page_ranges;
2669       for (i = 0; i < data->num_ranges; i++)
2670         if (data->ranges[i].end == -1 ||
2671             data->ranges[i].end >= priv->nr_of_pages)
2672           data->ranges[i].end = priv->nr_of_pages - 1;
2673     }
2674   else if (priv->print_pages == GTK_PRINT_PAGES_CURRENT &&
2675    priv->current_page != -1)
2676     {
2677       data->ranges = &data->one_range;
2678       data->num_ranges = 1;
2679       data->ranges[0].start = priv->current_page;
2680       data->ranges[0].end = priv->current_page;
2681     }
2682   else
2683     {
2684       data->ranges = &data->one_range;
2685       data->num_ranges = 1;
2686       data->ranges[0].start = 0;
2687       data->ranges[0].end = priv->nr_of_pages - 1;
2688     }
2689 
2690   clamp_page_ranges (data);
2691 
2692   if (data->num_ranges < 1)
2693     {
2694       priv->cancelled = TRUE;
2695       return;
2696     }
2697 
2698   priv->nr_of_pages_to_print = 0;
2699   for (i = 0; i < data->num_ranges; i++)
2700     priv->nr_of_pages_to_print += data->ranges[i].end - data->ranges[i].start + 1;
2701 
2702   data->pages = g_new (gint, priv->nr_of_pages_to_print);
2703   counter = 0;
2704   for (i = 0; i < data->num_ranges; i++)
2705     for (j = data->ranges[i].start; j <= data->ranges[i].end; j++)
2706       {
2707         data->pages[counter] = j;
2708         counter++;
2709       }
2710 
2711   data->total = -1;
2712   data->collated = 0;
2713   data->uncollated = 0;
2714 
2715   if (priv->manual_number_up > 1)
2716     {
2717       if (priv->nr_of_pages_to_print % priv->manual_number_up == 0)
2718         data->num_of_sheets = priv->nr_of_pages_to_print / priv->manual_number_up;
2719       else
2720         data->num_of_sheets = priv->nr_of_pages_to_print / priv->manual_number_up + 1;
2721     }
2722   else
2723     data->num_of_sheets = priv->nr_of_pages_to_print;
2724 
2725   if (priv->manual_reverse)
2726     {
2727       /* data->sheet is 0-based */
2728       if (priv->manual_page_set == GTK_PAGE_SET_ODD)
2729         data->sheet = (data->num_of_sheets - 1) - (data->num_of_sheets - 1) % 2;
2730       else if (priv->manual_page_set == GTK_PAGE_SET_EVEN)
2731         data->sheet = (data->num_of_sheets - 1) - (1 - (data->num_of_sheets - 1) % 2);
2732       else
2733         data->sheet = data->num_of_sheets - 1;
2734     }
2735   else
2736     {
2737       /* data->sheet is 0-based */
2738       if (priv->manual_page_set == GTK_PAGE_SET_ODD)
2739         data->sheet = 0;
2740       else if (priv->manual_page_set == GTK_PAGE_SET_EVEN)
2741         {
2742           if (data->num_of_sheets > 1)
2743             data->sheet = 1;
2744           else
2745             data->sheet = -1;
2746         }
2747       else
2748         data->sheet = 0;
2749     }
2750 
2751   priv->page_position = data->sheet * priv->manual_number_up;
2752 
2753   if (priv->page_position < 0 || priv->page_position >= priv->nr_of_pages_to_print)
2754     {
2755       priv->cancelled = TRUE;
2756       return;
2757     }
2758 
2759   data->page = data->pages[priv->page_position];
2760   data->first_position = priv->page_position;
2761   data->first_sheet = data->sheet;
2762 
2763   if (priv->manual_reverse)
2764     {
2765       if (priv->manual_page_set == GTK_PAGE_SET_ODD)
2766         data->last_position = MIN (priv->manual_number_up - 1, priv->nr_of_pages_to_print - 1);
2767       else if (priv->manual_page_set == GTK_PAGE_SET_EVEN)
2768         data->last_position = MIN (2 * priv->manual_number_up - 1, priv->nr_of_pages_to_print - 1);
2769       else
2770         data->last_position = MIN (priv->manual_number_up - 1, priv->nr_of_pages_to_print - 1);
2771     }
2772   else
2773     {
2774       if (priv->manual_page_set == GTK_PAGE_SET_ODD)
2775         data->last_position = MIN (((data->num_of_sheets - 1) - ((data->num_of_sheets - 1) % 2)) * priv->manual_number_up - 1, priv->nr_of_pages_to_print - 1);
2776       else if (priv->manual_page_set == GTK_PAGE_SET_EVEN)
2777         data->last_position = MIN (((data->num_of_sheets - 1) - (1 - (data->num_of_sheets - 1) % 2)) * priv->manual_number_up - 1, priv->nr_of_pages_to_print - 1);
2778       else
2779         data->last_position = priv->nr_of_pages_to_print - 1;
2780     }
2781 
2782 
2783   _gtk_print_operation_set_status (data->op,
2784                                    GTK_PRINT_STATUS_GENERATING_DATA,
2785                                    NULL);
2786 }
2787 
2788 static gboolean
print_pages_idle(gpointer user_data)2789 print_pages_idle (gpointer user_data)
2790 {
2791   PrintPagesData *data;
2792   GtkPrintOperationPrivate *priv;
2793   gboolean done = FALSE;
2794 
2795   data = (PrintPagesData*)user_data;
2796   priv = data->op->priv;
2797 
2798   if (priv->page_drawing_state == GTK_PAGE_DRAWING_STATE_READY)
2799     {
2800       if (priv->status == GTK_PRINT_STATUS_PREPARING)
2801         {
2802           prepare_data (data);
2803           goto out;
2804         }
2805 
2806       if (data->is_preview && !priv->cancelled)
2807         {
2808           done = TRUE;
2809 
2810           g_signal_emit_by_name (data->op, "ready", priv->print_context);
2811           goto out;
2812         }
2813 
2814       increment_page_sequence (data);
2815 
2816       if (!data->done)
2817         common_render_page (data->op, data->page);
2818       else
2819         done = priv->page_drawing_state == GTK_PAGE_DRAWING_STATE_READY;
2820 
2821  out:
2822 
2823       if (priv->cancelled)
2824         {
2825           _gtk_print_operation_set_status (data->op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
2826 
2827           data->is_preview = FALSE;
2828           done = TRUE;
2829         }
2830 
2831       if (done && !data->is_preview)
2832         {
2833           g_signal_emit (data->op, signals[END_PRINT], 0, priv->print_context);
2834           priv->end_run (data->op, priv->is_sync, priv->cancelled);
2835         }
2836 
2837       update_progress (data);
2838     }
2839 
2840   return !done;
2841 }
2842 
2843 static void
handle_progress_response(GtkWidget * dialog,gint response,gpointer data)2844 handle_progress_response (GtkWidget *dialog,
2845 			  gint       response,
2846 			  gpointer   data)
2847 {
2848   GtkPrintOperation *op = (GtkPrintOperation *)data;
2849 
2850   gtk_widget_hide (dialog);
2851   gtk_print_operation_cancel (op);
2852 }
2853 
2854 static gboolean
show_progress_timeout(PrintPagesData * data)2855 show_progress_timeout (PrintPagesData *data)
2856 {
2857   gtk_window_present (GTK_WINDOW (data->progress));
2858 
2859   data->op->priv->show_progress_timeout_id = 0;
2860 
2861   return FALSE;
2862 }
2863 
2864 static void
print_pages(GtkPrintOperation * op,GtkWindow * parent,gboolean do_print,GtkPrintOperationResult result)2865 print_pages (GtkPrintOperation       *op,
2866 	     GtkWindow               *parent,
2867 	     gboolean                 do_print,
2868 	     GtkPrintOperationResult  result)
2869 {
2870   GtkPrintOperationPrivate *priv = op->priv;
2871   PrintPagesData *data;
2872 
2873   if (!do_print)
2874     {
2875       _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
2876       g_signal_emit (op, signals[DONE], 0, result);
2877       return;
2878   }
2879 
2880   _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_PREPARING, NULL);
2881 
2882   data = g_new0 (PrintPagesData, 1);
2883   data->op = g_object_ref (op);
2884   data->is_preview = (priv->action == GTK_PRINT_OPERATION_ACTION_PREVIEW);
2885 
2886   if (priv->show_progress)
2887     {
2888       GtkWidget *progress;
2889 
2890       progress = gtk_message_dialog_new (parent, 0,
2891 					 GTK_MESSAGE_OTHER,
2892 					 GTK_BUTTONS_CANCEL,
2893 					 _("Preparing"));
2894       g_signal_connect (progress, "response",
2895 			G_CALLBACK (handle_progress_response), op);
2896 
2897       priv->show_progress_timeout_id =
2898 	gdk_threads_add_timeout (SHOW_PROGRESS_TIME,
2899 		       (GSourceFunc)show_progress_timeout,
2900 		       data);
2901 
2902       data->progress = progress;
2903     }
2904 
2905   if (data->is_preview)
2906     {
2907       gboolean handled;
2908 
2909       g_signal_emit_by_name (op, "preview",
2910 			     GTK_PRINT_OPERATION_PREVIEW (op),
2911 			     priv->print_context,
2912 			     parent,
2913 			     &handled);
2914 
2915       if (!handled)
2916         {
2917           GtkWidget *error_dialog;
2918 
2919           error_dialog = gtk_message_dialog_new (parent,
2920                                                  GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
2921                                                  GTK_MESSAGE_ERROR,
2922                                                  GTK_BUTTONS_OK,
2923                                                  _("Error creating print preview"));
2924 
2925           gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (error_dialog),
2926                                                     _("The most probable reason is that a temporary file could not be created."));
2927 
2928           if (parent && parent->group)
2929             gtk_window_group_add_window (parent->group, GTK_WINDOW (error_dialog));
2930 
2931           g_signal_connect (error_dialog, "response",
2932                             G_CALLBACK (gtk_widget_destroy), NULL);
2933 
2934           gtk_widget_show (error_dialog);
2935 
2936           print_pages_idle_done (data);
2937 
2938           return;
2939         }
2940 
2941       if (gtk_print_context_get_cairo_context (priv->print_context) == NULL)
2942         {
2943           /* Programmer error */
2944           g_error ("You must set a cairo context on the print context");
2945         }
2946 
2947       priv->start_page = preview_start_page;
2948       priv->end_page = preview_end_page;
2949       priv->end_run = preview_end_run;
2950 
2951       priv->print_pages = gtk_print_settings_get_print_pages (priv->print_settings);
2952       priv->page_ranges = gtk_print_settings_get_page_ranges (priv->print_settings,
2953 							      &priv->num_page_ranges);
2954       priv->manual_num_copies = 1;
2955       priv->manual_collation = FALSE;
2956       priv->manual_reverse = gtk_print_settings_get_reverse (priv->print_settings);
2957       priv->manual_page_set = gtk_print_settings_get_page_set (priv->print_settings);
2958       priv->manual_scale = gtk_print_settings_get_scale (priv->print_settings) / 100.0;
2959       priv->manual_orientation = TRUE;
2960       priv->manual_number_up = gtk_print_settings_get_number_up (priv->print_settings);
2961       priv->manual_number_up_layout = gtk_print_settings_get_number_up_layout (priv->print_settings);
2962     }
2963 
2964   priv->print_pages_idle_id = gdk_threads_add_idle_full (G_PRIORITY_DEFAULT_IDLE + 10,
2965 					                 print_pages_idle,
2966 					                 data,
2967 					                 print_pages_idle_done);
2968 
2969   /* Recursive main loop to make sure we don't exit  on sync operations  */
2970   if (priv->is_sync)
2971     {
2972       priv->rloop = g_main_loop_new (NULL, FALSE);
2973 
2974       g_object_ref (op);
2975       GDK_THREADS_LEAVE ();
2976       g_main_loop_run (priv->rloop);
2977       GDK_THREADS_ENTER ();
2978 
2979       g_main_loop_unref (priv->rloop);
2980       priv->rloop = NULL;
2981       g_object_unref (op);
2982     }
2983 }
2984 
2985 /**
2986  * gtk_print_operation_get_error:
2987  * @op: a #GtkPrintOperation
2988  * @error: return location for the error
2989  *
2990  * Call this when the result of a print operation is
2991  * %GTK_PRINT_OPERATION_RESULT_ERROR, either as returned by
2992  * gtk_print_operation_run(), or in the #GtkPrintOperation::done signal
2993  * handler. The returned #GError will contain more details on what went wrong.
2994  *
2995  * Since: 2.10
2996  **/
2997 void
gtk_print_operation_get_error(GtkPrintOperation * op,GError ** error)2998 gtk_print_operation_get_error (GtkPrintOperation  *op,
2999 			       GError            **error)
3000 {
3001   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
3002 
3003   g_propagate_error (error, op->priv->error);
3004 
3005   op->priv->error = NULL;
3006 }
3007 
3008 
3009 /**
3010  * gtk_print_operation_run:
3011  * @op: a #GtkPrintOperation
3012  * @action: the action to start
3013  * @parent: (allow-none): Transient parent of the dialog
3014  * @error: (allow-none): Return location for errors, or %NULL
3015  *
3016  * Runs the print operation, by first letting the user modify
3017  * print settings in the print dialog, and then print the document.
3018  *
3019  * Normally that this function does not return until the rendering of all
3020  * pages is complete. You can connect to the
3021  * #GtkPrintOperation::status-changed signal on @op to obtain some
3022  * information about the progress of the print operation.
3023  * Furthermore, it may use a recursive mainloop to show the print dialog.
3024  *
3025  * If you call gtk_print_operation_set_allow_async() or set the
3026  * #GtkPrintOperation:allow-async property the operation will run
3027  * asynchronously if this is supported on the platform. The
3028  * #GtkPrintOperation::done signal will be emitted with the result of the
3029  * operation when the it is done (i.e. when the dialog is canceled, or when
3030  * the print succeeds or fails).
3031  * |[
3032  * if (settings != NULL)
3033  *   gtk_print_operation_set_print_settings (print, settings);
3034  *
3035  * if (page_setup != NULL)
3036  *   gtk_print_operation_set_default_page_setup (print, page_setup);
3037  *
3038  * g_signal_connect (print, "begin-print",
3039  *                   G_CALLBACK (begin_print), &data);
3040  * g_signal_connect (print, "draw-page",
3041  *                   G_CALLBACK (draw_page), &data);
3042  *
3043  * res = gtk_print_operation_run (print,
3044  *                                GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
3045  *                                parent,
3046  *                                &error);
3047  *
3048  * if (res == GTK_PRINT_OPERATION_RESULT_ERROR)
3049  *  {
3050  *    error_dialog = gtk_message_dialog_new (GTK_WINDOW (parent),
3051  *   			                     GTK_DIALOG_DESTROY_WITH_PARENT,
3052  * 					     GTK_MESSAGE_ERROR,
3053  * 					     GTK_BUTTONS_CLOSE,
3054  * 					     "Error printing file:\n%s",
3055  * 					     error->message);
3056  *    g_signal_connect (error_dialog, "response",
3057  *                      G_CALLBACK (gtk_widget_destroy), NULL);
3058  *    gtk_widget_show (error_dialog);
3059  *    g_error_free (error);
3060  *  }
3061  * else if (res == GTK_PRINT_OPERATION_RESULT_APPLY)
3062  *  {
3063  *    if (settings != NULL)
3064  *	g_object_unref (settings);
3065  *    settings = g_object_ref (gtk_print_operation_get_print_settings (print));
3066  *  }
3067  * ]|
3068  *
3069  * Note that gtk_print_operation_run() can only be called once on a
3070  * given #GtkPrintOperation.
3071  *
3072  * Return value: the result of the print operation. A return value of
3073  *   %GTK_PRINT_OPERATION_RESULT_APPLY indicates that the printing was
3074  *   completed successfully. In this case, it is a good idea to obtain
3075  *   the used print settings with gtk_print_operation_get_print_settings()
3076  *   and store them for reuse with the next print operation. A value of
3077  *   %GTK_PRINT_OPERATION_RESULT_IN_PROGRESS means the operation is running
3078  *   asynchronously, and will emit the #GtkPrintOperation::done signal when
3079  *   done.
3080  *
3081  * Since: 2.10
3082  **/
3083 GtkPrintOperationResult
gtk_print_operation_run(GtkPrintOperation * op,GtkPrintOperationAction action,GtkWindow * parent,GError ** error)3084 gtk_print_operation_run (GtkPrintOperation        *op,
3085 			 GtkPrintOperationAction   action,
3086 			 GtkWindow                *parent,
3087 			 GError                  **error)
3088 {
3089   GtkPrintOperationPrivate *priv;
3090   GtkPrintOperationResult result;
3091   GtkPageSetup *page_setup;
3092   gboolean do_print;
3093   gboolean run_print_pages;
3094 
3095   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op),
3096                         GTK_PRINT_OPERATION_RESULT_ERROR);
3097   g_return_val_if_fail (op->priv->status == GTK_PRINT_STATUS_INITIAL,
3098                         GTK_PRINT_OPERATION_RESULT_ERROR);
3099   priv = op->priv;
3100 
3101   run_print_pages = TRUE;
3102   do_print = FALSE;
3103   priv->error = NULL;
3104   priv->action = action;
3105 
3106   if (priv->print_settings == NULL)
3107     priv->print_settings = gtk_print_settings_new ();
3108 
3109   if (action == GTK_PRINT_OPERATION_ACTION_EXPORT)
3110     {
3111       /* note: if you implement async EXPORT, update the docs
3112        * docs for the allow-async property.
3113        */
3114       priv->is_sync = TRUE;
3115       g_return_val_if_fail (priv->export_filename != NULL, GTK_PRINT_OPERATION_RESULT_ERROR);
3116       result = run_pdf (op, parent, &do_print);
3117     }
3118   else if (action == GTK_PRINT_OPERATION_ACTION_PREVIEW)
3119     {
3120       priv->is_sync = !priv->allow_async;
3121       priv->print_context = _gtk_print_context_new (op);
3122       page_setup = create_page_setup (op);
3123       _gtk_print_context_set_page_setup (priv->print_context, page_setup);
3124       g_object_unref (page_setup);
3125       do_print = TRUE;
3126       result = priv->is_sync ? GTK_PRINT_OPERATION_RESULT_APPLY : GTK_PRINT_OPERATION_RESULT_IN_PROGRESS;
3127     }
3128 #ifndef G_OS_WIN32
3129   else if (priv->allow_async)
3130     {
3131       priv->is_sync = FALSE;
3132       _gtk_print_operation_platform_backend_run_dialog_async (op,
3133 							      action == GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
3134 							      parent,
3135 							      print_pages);
3136       result = GTK_PRINT_OPERATION_RESULT_IN_PROGRESS;
3137       run_print_pages = FALSE; /* print_pages is called asynchronously from dialog */
3138     }
3139 #endif
3140   else
3141     {
3142       priv->is_sync = TRUE;
3143       result = _gtk_print_operation_platform_backend_run_dialog (op,
3144 								 action == GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
3145 								 parent,
3146 								 &do_print);
3147     }
3148 
3149   if (run_print_pages)
3150     print_pages (op, parent, do_print, result);
3151 
3152   if (priv->error && error)
3153     *error = g_error_copy (priv->error);
3154 
3155   return result;
3156 }
3157 
3158 /**
3159  * gtk_print_operation_cancel:
3160  * @op: a #GtkPrintOperation
3161  *
3162  * Cancels a running print operation. This function may
3163  * be called from a #GtkPrintOperation::begin-print,
3164  * #GtkPrintOperation::paginate or #GtkPrintOperation::draw-page
3165  * signal handler to stop the currently running print
3166  * operation.
3167  *
3168  * Since: 2.10
3169  */
3170 void
gtk_print_operation_cancel(GtkPrintOperation * op)3171 gtk_print_operation_cancel (GtkPrintOperation *op)
3172 {
3173   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
3174 
3175   op->priv->cancelled = TRUE;
3176 }
3177 
3178 /**
3179  * gtk_print_operation_set_support_selection:
3180  * @op: a #GtkPrintOperation
3181  * @support_selection: %TRUE to support selection
3182  *
3183  * Sets whether selection is supported by #GtkPrintOperation.
3184  *
3185  * Since: 2.18
3186  */
3187 void
gtk_print_operation_set_support_selection(GtkPrintOperation * op,gboolean support_selection)3188 gtk_print_operation_set_support_selection (GtkPrintOperation  *op,
3189                                            gboolean            support_selection)
3190 {
3191   GtkPrintOperationPrivate *priv;
3192 
3193   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
3194 
3195   priv = op->priv;
3196 
3197   support_selection = support_selection != FALSE;
3198   if (priv->support_selection != support_selection)
3199     {
3200       priv->support_selection = support_selection;
3201       g_object_notify (G_OBJECT (op), "support-selection");
3202     }
3203 }
3204 
3205 /**
3206  * gtk_print_operation_get_support_selection:
3207  * @op: a #GtkPrintOperation
3208  *
3209  * Gets the value of #GtkPrintOperation::support-selection property.
3210  *
3211  * Returns: whether the application supports print of selection
3212  *
3213  * Since: 2.18
3214  */
3215 gboolean
gtk_print_operation_get_support_selection(GtkPrintOperation * op)3216 gtk_print_operation_get_support_selection (GtkPrintOperation *op)
3217 {
3218   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), FALSE);
3219 
3220   return op->priv->support_selection;
3221 }
3222 
3223 /**
3224  * gtk_print_operation_set_has_selection:
3225  * @op: a #GtkPrintOperation
3226  * @has_selection: %TRUE indicates that a selection exists
3227  *
3228  * Sets whether there is a selection to print.
3229  *
3230  * Application has to set number of pages to which the selection
3231  * will draw by gtk_print_operation_set_n_pages() in a callback of
3232  * #GtkPrintOperation::begin-print.
3233  *
3234  * Since: 2.18
3235  */
3236 void
gtk_print_operation_set_has_selection(GtkPrintOperation * op,gboolean has_selection)3237 gtk_print_operation_set_has_selection (GtkPrintOperation  *op,
3238                                        gboolean            has_selection)
3239 {
3240   GtkPrintOperationPrivate *priv;
3241 
3242   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
3243 
3244   priv = op->priv;
3245 
3246   has_selection = has_selection != FALSE;
3247   if (priv->has_selection != has_selection)
3248     {
3249       priv->has_selection = has_selection;
3250       g_object_notify (G_OBJECT (op), "has-selection");
3251     }
3252 }
3253 
3254 /**
3255  * gtk_print_operation_get_has_selection:
3256  * @op: a #GtkPrintOperation
3257  *
3258  * Gets the value of #GtkPrintOperation::has-selection property.
3259  *
3260  * Returns: whether there is a selection
3261  *
3262  * Since: 2.18
3263  */
3264 gboolean
gtk_print_operation_get_has_selection(GtkPrintOperation * op)3265 gtk_print_operation_get_has_selection (GtkPrintOperation *op)
3266 {
3267   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), FALSE);
3268 
3269   return op->priv->has_selection;
3270 }
3271 
3272 /**
3273  * gtk_print_operation_get_n_pages_to_print:
3274  * @op: a #GtkPrintOperation
3275  *
3276  * Returns the number of pages that will be printed.
3277  *
3278  * Note that this value is set during print preparation phase
3279  * (%GTK_PRINT_STATUS_PREPARING), so this function should never be
3280  * called before the data generation phase (%GTK_PRINT_STATUS_GENERATING_DATA).
3281  * You can connect to the #GtkPrintOperation::status-changed signal
3282  * and call gtk_print_operation_get_n_pages_to_print() when
3283  * print status is %GTK_PRINT_STATUS_GENERATING_DATA.
3284  * This is typically used to track the progress of print operation.
3285  *
3286  * Returns: the number of pages that will be printed
3287  *
3288  * Since: 2.18
3289  **/
3290 gint
gtk_print_operation_get_n_pages_to_print(GtkPrintOperation * op)3291 gtk_print_operation_get_n_pages_to_print (GtkPrintOperation *op)
3292 {
3293   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), -1);
3294 
3295   return op->priv->nr_of_pages_to_print;
3296 }
3297 
3298 #define __GTK_PRINT_OPERATION_C__
3299 #include "gtkaliasdef.c"
3300