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