1 /* this file is part of atril, a mate document viewer
2  *
3  *  Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org>
4  *
5  * Atril is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * Atril is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19 
20 #include <config.h>
21 
22 #include "ev-print-operation.h"
23 
24 #if GTKUNIXPRINT_ENABLED
25 #include <gtk/gtkunixprint.h>
26 #endif
27 #include <glib/gi18n.h>
28 #include <glib/gstdio.h>
29 #include <unistd.h>
30 
31 #include "ev-jobs.h"
32 #include "ev-job-scheduler.h"
33 
34 enum {
35 	PROP_0,
36 	PROP_DOCUMENT
37 };
38 
39 enum {
40 	DONE,
41 	BEGIN_PRINT,
42 	STATUS_CHANGED,
43 	LAST_SIGNAL
44 };
45 
46 static guint signals[LAST_SIGNAL] = { 0 };
47 
48 struct _EvPrintOperation {
49 	GObject parent;
50 
51 	EvDocument *document;
52 
53 	/* Progress */
54 	gchar      *status;
55 	gdouble     progress;
56 };
57 
58 struct _EvPrintOperationClass {
59 	GObjectClass parent_class;
60 
61 	void              (* set_current_page)       (EvPrintOperation       *op,
62 						      gint                    current_page);
63 	void              (* set_print_settings)     (EvPrintOperation       *op,
64 						      GtkPrintSettings       *print_settings);
65 	GtkPrintSettings *(* get_print_settings)     (EvPrintOperation       *op);
66 	void              (* set_default_page_setup) (EvPrintOperation       *op,
67 						      GtkPageSetup           *page_setup);
68 	GtkPageSetup     *(* get_default_page_setup) (EvPrintOperation       *op);
69 	void              (* set_job_name)           (EvPrintOperation       *op,
70 						      const gchar            *job_name);
71 	const gchar      *(* get_job_name)           (EvPrintOperation       *op);
72 	void              (* run)                    (EvPrintOperation       *op,
73 						      GtkWindow              *parent);
74 	void              (* cancel)                 (EvPrintOperation       *op);
75 	void              (* get_error)              (EvPrintOperation       *op,
76 						      GError                **error);
77 	void              (* set_embed_page_setup)   (EvPrintOperation       *op,
78 						      gboolean                embed);
79 	gboolean          (* get_embed_page_setup)   (EvPrintOperation       *op);
80 
81 	/* signals */
82 	void              (* done)                   (EvPrintOperation       *op,
83 						      GtkPrintOperationResult result);
84 	void              (* begin_print)            (EvPrintOperation       *op);
85 	void              (* status_changed)         (EvPrintOperation       *op);
86 };
87 
G_DEFINE_ABSTRACT_TYPE(EvPrintOperation,ev_print_operation,G_TYPE_OBJECT)88 G_DEFINE_ABSTRACT_TYPE (EvPrintOperation, ev_print_operation, G_TYPE_OBJECT)
89 
90 static void
91 ev_print_operation_finalize (GObject *object)
92 {
93 	EvPrintOperation *op = EV_PRINT_OPERATION (object);
94 
95 	if (op->document) {
96 		g_object_unref (op->document);
97 		op->document = NULL;
98 	}
99 
100 	if (op->status) {
101 		g_free (op->status);
102 		op->status = NULL;
103 	}
104 
105 	(* G_OBJECT_CLASS (ev_print_operation_parent_class)->finalize) (object);
106 }
107 
108 static void
ev_print_operation_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)109 ev_print_operation_set_property (GObject      *object,
110 				 guint         prop_id,
111 				 const GValue *value,
112 				 GParamSpec   *pspec)
113 {
114 	EvPrintOperation *op = EV_PRINT_OPERATION (object);
115 
116 	switch (prop_id) {
117 	case PROP_DOCUMENT:
118 		op->document = g_value_dup_object (value);
119 		break;
120 	default:
121 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
122 	}
123 }
124 
125 static void
ev_print_operation_init(EvPrintOperation * op)126 ev_print_operation_init (EvPrintOperation *op)
127 {
128 }
129 
130 static void
ev_print_operation_class_init(EvPrintOperationClass * klass)131 ev_print_operation_class_init (EvPrintOperationClass *klass)
132 {
133 	GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
134 
135 	g_object_class->set_property = ev_print_operation_set_property;
136 	g_object_class->finalize = ev_print_operation_finalize;
137 
138 	g_object_class_install_property (g_object_class,
139 					 PROP_DOCUMENT,
140 					 g_param_spec_object ("document",
141 							      "Document",
142 							      "The document to print",
143 							      EV_TYPE_DOCUMENT,
144 							      G_PARAM_WRITABLE |
145 							      G_PARAM_CONSTRUCT_ONLY));
146 	signals[DONE] =
147 		g_signal_new ("done",
148 			      G_TYPE_FROM_CLASS (g_object_class),
149 			      G_SIGNAL_RUN_LAST,
150 			      G_STRUCT_OFFSET (EvPrintOperationClass, done),
151 			      NULL, NULL,
152 			      g_cclosure_marshal_VOID__ENUM,
153 			      G_TYPE_NONE, 1,
154 			      GTK_TYPE_PRINT_OPERATION_RESULT);
155 	signals[BEGIN_PRINT] =
156 		g_signal_new ("begin_print",
157 			      G_TYPE_FROM_CLASS (g_object_class),
158 			      G_SIGNAL_RUN_LAST,
159 			      G_STRUCT_OFFSET (EvPrintOperationClass, begin_print),
160 			      NULL, NULL,
161 			      g_cclosure_marshal_VOID__VOID,
162 			      G_TYPE_NONE, 0);
163 	signals[STATUS_CHANGED] =
164 		g_signal_new ("status_changed",
165 			      G_TYPE_FROM_CLASS (g_object_class),
166 			      G_SIGNAL_RUN_LAST,
167 			      G_STRUCT_OFFSET (EvPrintOperationClass, status_changed),
168 			      NULL, NULL,
169 			      g_cclosure_marshal_VOID__VOID,
170 			      G_TYPE_NONE, 0);
171 }
172 
173 /* Public methods */
174 void
ev_print_operation_set_current_page(EvPrintOperation * op,gint current_page)175 ev_print_operation_set_current_page (EvPrintOperation *op,
176 				     gint              current_page)
177 {
178 	EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
179 
180 	g_return_if_fail (EV_IS_PRINT_OPERATION (op));
181 	g_return_if_fail (current_page >= 0);
182 
183 	class->set_current_page (op, current_page);
184 }
185 
186 void
ev_print_operation_set_print_settings(EvPrintOperation * op,GtkPrintSettings * print_settings)187 ev_print_operation_set_print_settings (EvPrintOperation *op,
188 				       GtkPrintSettings *print_settings)
189 {
190 	EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
191 
192 	g_return_if_fail (EV_IS_PRINT_OPERATION (op));
193 	g_return_if_fail (GTK_IS_PRINT_SETTINGS (print_settings));
194 
195 	class->set_print_settings (op, print_settings);
196 }
197 
198 /**
199  * ev_print_operation_get_print_settings:
200  * @op: an #EvPrintOperation
201  *
202  * Returns: (transfer none): a #GtkPrintSettings
203  */
204 GtkPrintSettings *
ev_print_operation_get_print_settings(EvPrintOperation * op)205 ev_print_operation_get_print_settings (EvPrintOperation *op)
206 {
207 	EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
208 
209 	g_return_val_if_fail (EV_IS_PRINT_OPERATION (op), NULL);
210 
211 	return class->get_print_settings (op);
212 }
213 
214 void
ev_print_operation_set_default_page_setup(EvPrintOperation * op,GtkPageSetup * page_setup)215 ev_print_operation_set_default_page_setup (EvPrintOperation *op,
216 					   GtkPageSetup     *page_setup)
217 {
218 	EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
219 
220 	g_return_if_fail (EV_IS_PRINT_OPERATION (op));
221 	g_return_if_fail (GTK_IS_PAGE_SETUP (page_setup));
222 
223 	class->set_default_page_setup (op, page_setup);
224 }
225 
226 /**
227  * ev_print_operation_get_default_page_setup:
228  * @op: an #EvPrintOperation
229  *
230  * Returns: (transfer none): a #GtkPageSetup
231  */
232 GtkPageSetup *
ev_print_operation_get_default_page_setup(EvPrintOperation * op)233 ev_print_operation_get_default_page_setup (EvPrintOperation *op)
234 {
235 	EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
236 
237 	g_return_val_if_fail (EV_IS_PRINT_OPERATION (op), NULL);
238 
239 	return class->get_default_page_setup (op);
240 }
241 
242 void
ev_print_operation_set_job_name(EvPrintOperation * op,const gchar * job_name)243 ev_print_operation_set_job_name (EvPrintOperation *op,
244 				 const gchar      *job_name)
245 {
246 	EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
247 
248 	g_return_if_fail (EV_IS_PRINT_OPERATION (op));
249 	g_return_if_fail (job_name != NULL);
250 
251 	class->set_job_name (op, job_name);
252 }
253 
254 const gchar *
ev_print_operation_get_job_name(EvPrintOperation * op)255 ev_print_operation_get_job_name (EvPrintOperation *op)
256 {
257 	EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
258 
259 	g_return_val_if_fail (EV_IS_PRINT_OPERATION (op), NULL);
260 
261 	return class->get_job_name (op);
262 }
263 
264 void
ev_print_operation_run(EvPrintOperation * op,GtkWindow * parent)265 ev_print_operation_run (EvPrintOperation *op,
266 			GtkWindow        *parent)
267 {
268 	EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
269 
270 	g_return_if_fail (EV_IS_PRINT_OPERATION (op));
271 
272 	class->run (op, parent);
273 }
274 
275 void
ev_print_operation_cancel(EvPrintOperation * op)276 ev_print_operation_cancel (EvPrintOperation *op)
277 {
278 	EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
279 
280 	g_return_if_fail (EV_IS_PRINT_OPERATION (op));
281 
282 	class->cancel (op);
283 }
284 
285 void
ev_print_operation_get_error(EvPrintOperation * op,GError ** error)286 ev_print_operation_get_error (EvPrintOperation *op,
287 			      GError          **error)
288 {
289 	EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
290 
291 	g_return_if_fail (EV_IS_PRINT_OPERATION (op));
292 
293 	class->get_error (op, error);
294 }
295 
296 void
ev_print_operation_set_embed_page_setup(EvPrintOperation * op,gboolean embed)297 ev_print_operation_set_embed_page_setup (EvPrintOperation *op,
298 					 gboolean          embed)
299 {
300 	EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
301 
302 	g_return_if_fail (EV_IS_PRINT_OPERATION (op));
303 
304 	class->set_embed_page_setup (op, embed);
305 }
306 
307 gboolean
ev_print_operation_get_embed_page_setup(EvPrintOperation * op)308 ev_print_operation_get_embed_page_setup (EvPrintOperation *op)
309 {
310 	EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
311 
312 	g_return_val_if_fail (EV_IS_PRINT_OPERATION (op), FALSE);
313 
314 	return class->get_embed_page_setup (op);
315 }
316 
317 const gchar *
ev_print_operation_get_status(EvPrintOperation * op)318 ev_print_operation_get_status (EvPrintOperation *op)
319 {
320 	g_return_val_if_fail (EV_IS_PRINT_OPERATION (op), NULL);
321 
322 	return op->status ? op->status : "";
323 }
324 
325 gdouble
ev_print_operation_get_progress(EvPrintOperation * op)326 ev_print_operation_get_progress (EvPrintOperation *op)
327 {
328 	g_return_val_if_fail (EV_IS_PRINT_OPERATION (op), 0.0);
329 
330 	return op->progress;
331 }
332 
333 static void
ev_print_operation_update_status(EvPrintOperation * op,gint page,gint n_pages,gdouble progress)334 ev_print_operation_update_status (EvPrintOperation *op,
335 				  gint              page,
336 				  gint              n_pages,
337 				  gdouble           progress)
338 {
339 	if (op->status && op->progress == progress)
340 		return;
341 
342 	g_free (op->status);
343 
344 	if (page == -1) {
345 		/* Initial state */
346 		op->status = g_strdup (_("Preparing to print…"));
347 	} else if (page > n_pages) {
348 		op->status = g_strdup (_("Finishing…"));
349 	} else {
350 		op->status = g_strdup_printf (_("Printing page %d of %d…"),
351 					      page, n_pages);
352 	}
353 
354 	op->progress = MIN (1.0, progress);
355 
356 	g_signal_emit (op, signals[STATUS_CHANGED], 0);
357 }
358 
359 #if GTKUNIXPRINT_ENABLED
360 
361 /* Export interface */
362 #define EV_TYPE_PRINT_OPERATION_EXPORT         (ev_print_operation_export_get_type())
363 #define EV_PRINT_OPERATION_EXPORT(object)      (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_PRINT_OPERATION_EXPORT, EvPrintOperationExport))
364 
365 typedef struct _EvPrintOperationExport      EvPrintOperationExport;
366 typedef struct _EvPrintOperationExportClass EvPrintOperationExportClass;
367 
368 static GType    ev_print_operation_export_get_type (void) G_GNUC_CONST;
369 
370 static void     ev_print_operation_export_begin    (EvPrintOperationExport *export);
371 static gboolean export_print_page                  (EvPrintOperationExport *export);
372 static void     export_cancel                      (EvPrintOperationExport *export);
373 
374 struct _EvPrintOperationExport {
375 	EvPrintOperation parent;
376 
377 	GtkWindow *parent_window;
378 	EvJob *job_export;
379 	GError *error;
380 
381 	gboolean print_preview;
382 	gint n_pages;
383 	gint current_page;
384 	GtkPrinter *printer;
385 	GtkPageSetup *page_setup;
386 	GtkPrintSettings *print_settings;
387 	GtkPageSet page_set;
388 	gint copies;
389 	guint collate     : 1;
390 	guint reverse     : 1;
391 	gint pages_per_sheet;
392 	gint fd;
393 	gchar *temp_file;
394 	gchar *job_name;
395 	gboolean embed_page_setup;
396 
397 	guint idle_id;
398 
399 	/* Context */
400 	EvFileExporterContext fc;
401 	gint n_pages_to_print;
402 	gint uncollated_copies;
403 	gint collated_copies;
404 	gint uncollated, collated, total;
405 
406 	gint sheet, page_count;
407 
408 	gint range, n_ranges;
409 	GtkPageRange *ranges;
410 	GtkPageRange one_range;
411 
412 	gint page, start, end, inc;
413 };
414 
415 struct _EvPrintOperationExportClass {
416 	EvPrintOperationClass parent_class;
417 };
418 
419 G_DEFINE_TYPE (EvPrintOperationExport, ev_print_operation_export, EV_TYPE_PRINT_OPERATION)
420 
421 /* Internal print queue */
422 static GHashTable *print_queue = NULL;
423 
424 static void
queue_free(GQueue * queue)425 queue_free (GQueue *queue)
426 {
427 	g_queue_foreach (queue, (GFunc)g_object_unref, NULL);
428 	g_queue_free (queue);
429 }
430 
431 static void
ev_print_queue_init(void)432 ev_print_queue_init (void)
433 {
434 	if (G_UNLIKELY (print_queue == NULL)) {
435 		print_queue = g_hash_table_new_full (g_direct_hash,
436 						     g_direct_equal,
437 						     NULL,
438 						     (GDestroyNotify)queue_free);
439 	}
440 }
441 
442 static void
remove_document_queue(gpointer data,GObject * document)443 remove_document_queue (gpointer data,
444 		       GObject *document)
445 {
446 	if (print_queue)
447 		g_hash_table_remove (print_queue, document);
448 }
449 
450 static gboolean
ev_print_queue_is_empty(EvDocument * document)451 ev_print_queue_is_empty (EvDocument *document)
452 {
453 	GQueue *queue;
454 
455 	queue = g_hash_table_lookup (print_queue, document);
456 	return (!queue || g_queue_is_empty (queue));
457 }
458 
459 static void
ev_print_queue_push(EvPrintOperation * op)460 ev_print_queue_push (EvPrintOperation *op)
461 {
462 	GQueue *queue;
463 
464 	queue = g_hash_table_lookup (print_queue, op->document);
465 	if (!queue) {
466 		queue = g_queue_new ();
467 		g_hash_table_insert (print_queue,
468 				     op->document,
469 				     queue);
470 		g_object_weak_ref (G_OBJECT (op->document),
471 				   (GWeakNotify)remove_document_queue,
472 				   NULL);
473 	}
474 
475 	g_queue_push_head (queue, g_object_ref (op));
476 }
477 
478 static EvPrintOperation *
ev_print_queue_pop(EvDocument * document)479 ev_print_queue_pop (EvDocument *document)
480 {
481 	EvPrintOperation *op;
482 	GQueue           *queue;
483 
484 	queue = g_hash_table_lookup (print_queue, document);
485 	if (!queue || g_queue_is_empty (queue))
486 		return NULL;
487 
488 	op = g_queue_pop_tail (queue);
489 	g_object_unref (op);
490 
491 	return op;
492 }
493 
494 static EvPrintOperation *
ev_print_queue_peek(EvDocument * document)495 ev_print_queue_peek (EvDocument *document)
496 {
497 	GQueue *queue;
498 
499 	queue = g_hash_table_lookup (print_queue, document);
500 	if (!queue || g_queue_is_empty (queue))
501 		return NULL;
502 
503 	return g_queue_peek_tail (queue);
504 }
505 
506 static void
ev_print_operation_export_set_current_page(EvPrintOperation * op,gint current_page)507 ev_print_operation_export_set_current_page (EvPrintOperation *op,
508 					    gint              current_page)
509 {
510 	EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
511 
512 	g_return_if_fail (current_page < export->n_pages);
513 
514 	export->current_page = current_page;
515 }
516 
517 static void
ev_print_operation_export_set_print_settings(EvPrintOperation * op,GtkPrintSettings * print_settings)518 ev_print_operation_export_set_print_settings (EvPrintOperation *op,
519 					      GtkPrintSettings *print_settings)
520 {
521 	EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
522 
523 	if (print_settings == export->print_settings)
524 		return;
525 
526 	g_object_ref (print_settings);
527 	if (export->print_settings)
528 		g_object_unref (export->print_settings);
529 	export->print_settings = print_settings;
530 }
531 
532 static GtkPrintSettings *
ev_print_operation_export_get_print_settings(EvPrintOperation * op)533 ev_print_operation_export_get_print_settings (EvPrintOperation *op)
534 {
535 	EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
536 
537 	return export->print_settings;
538 }
539 
540 static void
ev_print_operation_export_set_default_page_setup(EvPrintOperation * op,GtkPageSetup * page_setup)541 ev_print_operation_export_set_default_page_setup (EvPrintOperation *op,
542 						  GtkPageSetup     *page_setup)
543 {
544 	EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
545 
546 	if (page_setup == export->page_setup)
547 		return;
548 
549 	g_object_ref (page_setup);
550 	if (export->page_setup)
551 		g_object_unref (export->page_setup);
552 	export->page_setup = page_setup;
553 }
554 
555 static GtkPageSetup *
ev_print_operation_export_get_default_page_setup(EvPrintOperation * op)556 ev_print_operation_export_get_default_page_setup (EvPrintOperation *op)
557 {
558 	EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
559 
560 	return export->page_setup;
561 }
562 
563 static void
ev_print_operation_export_set_job_name(EvPrintOperation * op,const gchar * job_name)564 ev_print_operation_export_set_job_name (EvPrintOperation *op,
565 					const gchar      *job_name)
566 {
567 	EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
568 
569 	g_free (export->job_name);
570 	export->job_name = g_strdup (job_name);
571 }
572 
573 static const gchar *
ev_print_operation_export_get_job_name(EvPrintOperation * op)574 ev_print_operation_export_get_job_name (EvPrintOperation *op)
575 {
576 	EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
577 
578 	return export->job_name;
579 }
580 
581 static void
ev_print_operation_export_set_printer(EvPrintOperationExport * export,GtkPrinter * printer)582 ev_print_operation_export_set_printer (EvPrintOperationExport *export,
583 				       GtkPrinter             *printer)
584 {
585 	if (printer == export->printer)
586 		return;
587 
588 	g_object_ref (printer);
589 	if (export->printer)
590 		g_object_unref (export->printer);
591 	export->printer = printer;
592 }
593 
594 static void
find_range(EvPrintOperationExport * export)595 find_range (EvPrintOperationExport *export)
596 {
597 	GtkPageRange *range;
598 
599 	range = &export->ranges[export->range];
600 
601 	if (export->inc < 0) {
602 		export->start = range->end;
603 		export->end = range->start - 1;
604 	} else {
605 		export->start = range->start;
606 		export->end = range->end + 1;
607 	}
608 }
609 
610 static gboolean
clamp_ranges(EvPrintOperationExport * export)611 clamp_ranges (EvPrintOperationExport *export)
612 {
613 	gint num_of_correct_ranges = 0;
614 	gint n_pages_to_print = 0;
615 	gint i;
616 	gboolean null_flag = FALSE;
617 
618 	for (i = 0; i < export->n_ranges; i++) {
619 		gint n_pages;
620 
621 		if ((export->ranges[i].start >= 0) &&
622 		    (export->ranges[i].start < export->n_pages) &&
623 		    (export->ranges[i].end >= 0) &&
624 		    (export->ranges[i].end < export->n_pages)) {
625 			export->ranges[num_of_correct_ranges] = export->ranges[i];
626 			num_of_correct_ranges++;
627 		} else if ((export->ranges[i].start >= 0) &&
628 			   (export->ranges[i].start < export->n_pages) &&
629 			   (export->ranges[i].end >= export->n_pages)) {
630 			export->ranges[i].end = export->n_pages - 1;
631 			export->ranges[num_of_correct_ranges] = export->ranges[i];
632 			num_of_correct_ranges++;
633 		} else if ((export->ranges[i].end >= 0) &&
634 			   (export->ranges[i].end < export->n_pages) &&
635 			   (export->ranges[i].start < 0)) {
636 			export->ranges[i].start = 0;
637 			export->ranges[num_of_correct_ranges] = export->ranges[i];
638 			num_of_correct_ranges++;
639 		}
640 
641 		n_pages = export->ranges[i].end - export->ranges[i].start + 1;
642 		if (export->page_set == GTK_PAGE_SET_ALL) {
643 			n_pages_to_print += n_pages;
644 		} else if (n_pages % 2 == 0) {
645 			n_pages_to_print += n_pages / 2;
646 		} else if (export->page_set == GTK_PAGE_SET_EVEN) {
647 			if (n_pages==1 && export->ranges[i].start % 2 == 0)
648 				null_flag = TRUE;
649 			else
650 				n_pages_to_print += export->ranges[i].start % 2 == 0 ?
651 				n_pages / 2 : (n_pages / 2) + 1;
652 		} else if (export->page_set == GTK_PAGE_SET_ODD) {
653 			if (n_pages==1 && export->ranges[i].start % 2 != 0)
654 				null_flag = TRUE;
655 			else
656 				n_pages_to_print += export->ranges[i].start % 2 == 0 ?
657 				(n_pages / 2) + 1 : n_pages / 2;
658 		}
659 	}
660 
661 	if (null_flag && !n_pages_to_print) {
662 		return FALSE;
663 	} else {
664 		export->n_ranges = num_of_correct_ranges;
665 		export->n_pages_to_print = n_pages_to_print;
666 		return TRUE;
667 	}
668 }
669 
670 static void
get_first_and_last_page(EvPrintOperationExport * export,gint * first,gint * last)671 get_first_and_last_page (EvPrintOperationExport *export,
672 			 gint                   *first,
673 			 gint                   *last)
674 {
675 	gint i;
676 	gint first_page = G_MAXINT;
677 	gint last_page = G_MININT;
678 	gint max_page = export->n_pages - 1;
679 
680 	if (export->n_ranges == 0) {
681 		*first = 0;
682 		*last = max_page;
683 
684 		return;
685 	}
686 
687 	for (i = 0; i < export->n_ranges; i++) {
688 		if (export->ranges[i].start < first_page)
689 			first_page = export->ranges[i].start;
690 		if (export->ranges[i].end > last_page)
691 			last_page = export->ranges[i].end;
692 	}
693 
694 	*first = MAX (0, first_page);
695 	*last = MIN (max_page, last_page);
696 }
697 
698 static gboolean
export_print_inc_page(EvPrintOperationExport * export)699 export_print_inc_page (EvPrintOperationExport *export)
700 {
701 	do {
702 		export->page += export->inc;
703 
704 		/* note: when NOT collating, page_count is increased in export_print_page */
705 		if (export->collate) {
706 			export->page_count++;
707 			export->sheet = 1 + (export->page_count - 1) / export->pages_per_sheet;
708 		}
709 
710 		if (export->page == export->end) {
711 			export->range += export->inc;
712 			if (export->range == -1 || export->range == export->n_ranges) {
713 				export->uncollated++;
714 
715 				/* when printing multiple collated copies & multiple pages per sheet we want to
716 				 * prevent the next copy bleeding into the last sheet of the previous one
717 				 * we've reached the last range to be printed now, so this is the time to do it */
718 				if (export->pages_per_sheet > 1 && export->collate == 1 &&
719 				    (export->page_count - 1) % export->pages_per_sheet != 0) {
720 
721 					EvPrintOperation *op = EV_PRINT_OPERATION (export);
722 					ev_document_doc_mutex_lock ();
723 
724 					/* keep track of all blanks but only actualise those
725 					 * which are in the current odd / even sheet set */
726 
727 					export->page_count += export->pages_per_sheet - (export->page_count - 1) % export->pages_per_sheet;
728 					if (export->page_set == GTK_PAGE_SET_ALL ||
729 						(export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 == 0) ||
730 						(export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 == 1) ) {
731 						ev_file_exporter_end_page (EV_FILE_EXPORTER (op->document));
732 					}
733 					ev_document_doc_mutex_unlock ();
734 					export->sheet = 1 + (export->page_count - 1) / export->pages_per_sheet;
735 				}
736 
737 				if (export->uncollated == export->uncollated_copies)
738 					return FALSE;
739 
740 				export->range = export->inc < 0 ? export->n_ranges - 1 : 0;
741 			}
742 			find_range (export);
743 			export->page = export->start;
744 		}
745 
746 	/* in/decrement the page number until we reach the first page on the next EVEN or ODD sheet
747 	 * if we're not collating, we have to make sure that this is done only once! */
748 	} while ( export->collate == 1 &&
749 		((export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 == 1) ||
750 		(export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 == 0)));
751 
752 	return TRUE;
753 }
754 
755 static void
ev_print_operation_export_clear_temp_file(EvPrintOperationExport * export)756 ev_print_operation_export_clear_temp_file (EvPrintOperationExport *export)
757 {
758 	if (!export->temp_file)
759 		return;
760 
761 	g_unlink (export->temp_file);
762 	g_free (export->temp_file);
763 	export->temp_file = NULL;
764 }
765 
766 static void
ev_print_operation_export_run_next(EvPrintOperationExport * export)767 ev_print_operation_export_run_next (EvPrintOperationExport *export)
768 {
769 	EvPrintOperation *op = EV_PRINT_OPERATION (export);
770 	EvPrintOperation *next;
771 	EvDocument       *document;
772 
773 	/* First pop the current job */
774 	document = op->document;
775 	ev_print_queue_pop (document);
776 
777 	next = ev_print_queue_peek (document);
778 	if (next)
779 		ev_print_operation_export_begin (EV_PRINT_OPERATION_EXPORT (next));
780 }
781 
782 static void
gtk_print_job_finished(GtkPrintJob * print_job,EvPrintOperationExport * export,GError * error)783 gtk_print_job_finished (GtkPrintJob            *print_job,
784 			EvPrintOperationExport *export,
785 			GError                 *error)
786 {
787 	EvPrintOperation *op = EV_PRINT_OPERATION (export);
788 
789 	if (error) {
790 		g_set_error_literal (&export->error,
791 				     GTK_PRINT_ERROR,
792 				     GTK_PRINT_ERROR_GENERAL,
793 				     error->message);
794 		g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
795 	} else {
796 		g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_APPLY);
797 	}
798 
799 	ev_print_operation_export_clear_temp_file (export);
800 	g_object_unref (print_job);
801 
802 	ev_print_operation_export_run_next (export);
803 }
804 
805 static void
export_print_done(EvPrintOperationExport * export)806 export_print_done (EvPrintOperationExport *export)
807 {
808 	EvPrintOperation *op = EV_PRINT_OPERATION (export);
809 	GtkPrintSettings *settings;
810 	EvFileExporterCapabilities capabilities;
811 	GError *error = NULL;
812 
813 	g_assert (export->temp_file != NULL);
814 
815 	/* Some printers take into account some print settings,
816 	 * and others don't. However we have exported the document
817 	 * to a ps or pdf file according to such print settings. So,
818 	 * we want to send the exported file to printer with those
819 	 * settings set to default values.
820 	 */
821 	settings = gtk_print_settings_copy (export->print_settings);
822 	capabilities = ev_file_exporter_get_capabilities (EV_FILE_EXPORTER (op->document));
823 
824 	gtk_print_settings_set_page_ranges (settings, NULL, 0);
825 	gtk_print_settings_set_print_pages (settings, GTK_PRINT_PAGES_ALL);
826 	if (capabilities & EV_FILE_EXPORTER_CAN_COPIES)
827 		gtk_print_settings_set_n_copies (settings, 1);
828 	if (capabilities & EV_FILE_EXPORTER_CAN_PAGE_SET)
829 		gtk_print_settings_set_page_set (settings, GTK_PAGE_SET_ALL);
830 	if (capabilities & EV_FILE_EXPORTER_CAN_SCALE)
831 		gtk_print_settings_set_scale (settings, 1.0);
832 	if (capabilities & EV_FILE_EXPORTER_CAN_COLLATE)
833 		gtk_print_settings_set_collate (settings, FALSE);
834 	if (capabilities & EV_FILE_EXPORTER_CAN_REVERSE)
835 		gtk_print_settings_set_reverse (settings, FALSE);
836 	if (capabilities & EV_FILE_EXPORTER_CAN_NUMBER_UP) {
837 		gtk_print_settings_set_number_up (settings, 1);
838 		gtk_print_settings_set_int (settings, "cups-"GTK_PRINT_SETTINGS_NUMBER_UP, 1);
839 	}
840 
841 	if (export->print_preview) {
842 		GKeyFile *key_file;
843 		gchar    *data = NULL;
844 		gsize     data_len;
845 		gchar    *print_settings_file = NULL;
846 
847 		key_file = g_key_file_new ();
848 
849 		gtk_print_settings_to_key_file (settings, key_file, NULL);
850 		gtk_page_setup_to_key_file (export->page_setup, key_file, NULL);
851 		g_key_file_set_string (key_file, "Print Job", "title", export->job_name);
852 
853 		data = g_key_file_to_data (key_file, &data_len, &error);
854 		if (data) {
855 			gint fd;
856 
857 			fd = g_file_open_tmp ("print-settingsXXXXXX", &print_settings_file, &error);
858 			if (!error)
859 				g_file_set_contents (print_settings_file, data, data_len, &error);
860 			close (fd);
861 
862 			g_free (data);
863 		}
864 
865 		g_key_file_free (key_file);
866 
867 		if (!error) {
868 			GAppInfo *app;
869 			GdkAppLaunchContext *ctx;
870 			gchar  *cmd;
871 			gchar  *quoted_filename;
872 			gchar  *quoted_settings_filename;
873 
874 			quoted_filename = g_shell_quote (export->temp_file);
875 			quoted_settings_filename = g_shell_quote (print_settings_file);
876 			cmd = g_strdup_printf ("atril-previewer --unlink-tempfile --print-settings %s %s",
877 					       quoted_settings_filename, quoted_filename);
878 
879 			g_free (quoted_filename);
880 			g_free (quoted_settings_filename);
881 
882 			app = g_app_info_create_from_commandline (cmd, NULL, 0, &error);
883 
884 			if (app != NULL) {
885 				ctx = gdk_display_get_app_launch_context (gtk_widget_get_display (GTK_WIDGET (export->parent_window)));
886 				gdk_app_launch_context_set_screen (ctx, gtk_window_get_screen (export->parent_window));
887 
888 				g_app_info_launch (app, NULL, G_APP_LAUNCH_CONTEXT (ctx), &error);
889 
890 				g_object_unref (app);
891 				g_object_unref (ctx);
892 			}
893 
894 			g_free (cmd);
895 		}
896 
897 		if (error) {
898 			if (print_settings_file)
899 				g_unlink (print_settings_file);
900 			g_free (print_settings_file);
901 		} else {
902 			g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_APPLY);
903 			/* temp_file will be deleted by the previewer */
904 
905 			ev_print_operation_export_run_next (export);
906 		}
907 	} else {
908 		GtkPrintJob *job;
909 
910 		job = gtk_print_job_new (export->job_name,
911 					 export->printer,
912 					 settings,
913 					 export->page_setup);
914 		gtk_print_job_set_source_file (job, export->temp_file, &error);
915 		if (!error){
916 			gtk_print_job_send (job,
917 					    (GtkPrintJobCompleteFunc)gtk_print_job_finished,
918 					    g_object_ref (export),
919 					    (GDestroyNotify)g_object_unref);
920 		}
921 	}
922 	g_object_unref (settings);
923 
924 	if (error) {
925 		g_set_error_literal (&export->error,
926 				     GTK_PRINT_ERROR,
927 				     GTK_PRINT_ERROR_GENERAL,
928 				     error->message);
929 		g_error_free (error);
930 		ev_print_operation_export_clear_temp_file (export);
931 		g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
932 
933 		ev_print_operation_export_run_next (export);
934 	}
935 }
936 
937 static void
export_print_page_idle_finished(EvPrintOperationExport * export)938 export_print_page_idle_finished (EvPrintOperationExport *export)
939 {
940 	export->idle_id = 0;
941 }
942 
943 static void
export_job_finished(EvJobExport * job,EvPrintOperationExport * export)944 export_job_finished (EvJobExport            *job,
945 		     EvPrintOperationExport *export)
946 {
947 	EvPrintOperation *op = EV_PRINT_OPERATION (export);
948 
949 	if (export->pages_per_sheet == 1 ||
950 	   ( export->page_count % export->pages_per_sheet == 0 &&
951 	   ( export->page_set == GTK_PAGE_SET_ALL ||
952 	   ( export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 == 0 ) ||
953 	   ( export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 == 1 ) ) ) ) {
954 
955 		ev_document_doc_mutex_lock ();
956 		ev_file_exporter_end_page (EV_FILE_EXPORTER (op->document));
957 		ev_document_doc_mutex_unlock ();
958 	}
959 
960 	/* Reschedule */
961 	export->idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
962 					   (GSourceFunc)export_print_page,
963 					   export,
964 					   (GDestroyNotify)export_print_page_idle_finished);
965 }
966 
967 static void
export_job_cancelled(EvJobExport * job,EvPrintOperationExport * export)968 export_job_cancelled (EvJobExport            *job,
969 		      EvPrintOperationExport *export)
970 {
971 	export_cancel (export);
972 }
973 
974 static void
export_cancel(EvPrintOperationExport * export)975 export_cancel (EvPrintOperationExport *export)
976 {
977 	EvPrintOperation *op = EV_PRINT_OPERATION (export);
978 
979 	if (export->idle_id > 0)
980 		g_source_remove (export->idle_id);
981 	export->idle_id = 0;
982 
983 	if (export->job_export) {
984 		g_signal_handlers_disconnect_by_func (export->job_export,
985 						      export_job_finished,
986 						      export);
987 		g_signal_handlers_disconnect_by_func (export->job_export,
988 						      export_job_cancelled,
989 						      export);
990 		g_object_unref (export->job_export);
991 		export->job_export = NULL;
992 	}
993 
994 	if (export->fd != -1) {
995 		close (export->fd);
996 		export->fd = -1;
997 	}
998 
999 	ev_print_operation_export_clear_temp_file (export);
1000 
1001 	g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_CANCEL);
1002 
1003 	ev_print_operation_export_run_next (export);
1004 }
1005 
1006 static void
update_progress(EvPrintOperationExport * export)1007 update_progress (EvPrintOperationExport *export)
1008 {
1009 	EvPrintOperation *op = EV_PRINT_OPERATION (export);
1010 
1011 	ev_print_operation_update_status (op, export->total,
1012 					  export->n_pages_to_print,
1013 					  export->total / (gdouble)export->n_pages_to_print);
1014 }
1015 
1016 static gboolean
export_print_page(EvPrintOperationExport * export)1017 export_print_page (EvPrintOperationExport *export)
1018 {
1019 	EvPrintOperation *op = EV_PRINT_OPERATION (export);
1020 
1021 	if (!export->temp_file)
1022 		return FALSE; /* cancelled */
1023 
1024 	export->total++;
1025 	export->collated++;
1026 
1027 	/* note: when collating, page_count is increased in export_print_inc_page */
1028 	if (!export->collate) {
1029 		export->page_count++;
1030 		export->sheet = 1 + (export->page_count - 1) / export->pages_per_sheet;
1031 	}
1032 
1033 	if (export->collated == export->collated_copies) {
1034 		export->collated = 0;
1035 		if (!export_print_inc_page (export)) {
1036 			ev_document_doc_mutex_lock ();
1037 			ev_file_exporter_end (EV_FILE_EXPORTER (op->document));
1038 			ev_document_doc_mutex_unlock ();
1039 
1040 			close (export->fd);
1041 			export->fd = -1;
1042 			update_progress (export);
1043 			export_print_done (export);
1044 
1045 			return FALSE;
1046 		}
1047 	}
1048 
1049 	/* we're not collating and we've reached a sheet from the wrong sheet set */
1050 	if (!export->collate &&
1051 	    ((export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 != 0) ||
1052 	    (export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 != 1))) {
1053 
1054 		do {
1055 			export->page_count++;
1056 			export->collated++;
1057 			export->sheet = 1 + (export->page_count - 1) / export->pages_per_sheet;
1058 
1059 			if (export->collated == export->collated_copies) {
1060 				export->collated = 0;
1061 
1062 				if (!export_print_inc_page (export)) {
1063 					ev_document_doc_mutex_lock ();
1064 					ev_file_exporter_end (EV_FILE_EXPORTER (op->document));
1065 					ev_document_doc_mutex_unlock ();
1066 
1067 					close (export->fd);
1068 					export->fd = -1;
1069 
1070 					update_progress (export);
1071 
1072 					export_print_done (export);
1073 					return FALSE;
1074 				}
1075 			}
1076 
1077 		} while ((export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 != 0) ||
1078 	    		  (export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 != 1));
1079 
1080 	}
1081 
1082 	if (export->pages_per_sheet == 1 ||
1083 	    (export->page_count % export->pages_per_sheet == 1 &&
1084 	    (export->page_set == GTK_PAGE_SET_ALL ||
1085 	    (export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 == 0) ||
1086 	    (export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 == 1)))) {
1087 		ev_document_doc_mutex_lock ();
1088 		ev_file_exporter_begin_page (EV_FILE_EXPORTER (op->document));
1089 		ev_document_doc_mutex_unlock ();
1090 	}
1091 
1092 	if (!export->job_export) {
1093 		export->job_export = ev_job_export_new (op->document);
1094 		g_signal_connect (export->job_export, "finished",
1095 				  G_CALLBACK (export_job_finished),
1096 				  (gpointer)export);
1097 		g_signal_connect (export->job_export, "cancelled",
1098 				  G_CALLBACK (export_job_cancelled),
1099 				  (gpointer)export);
1100 	}
1101 
1102 	ev_job_export_set_page (EV_JOB_EXPORT (export->job_export), export->page);
1103 	ev_job_scheduler_push_job (export->job_export, EV_JOB_PRIORITY_NONE);
1104 
1105 	update_progress (export);
1106 
1107 	return FALSE;
1108 }
1109 
1110 static void
ev_print_operation_export_begin(EvPrintOperationExport * export)1111 ev_print_operation_export_begin (EvPrintOperationExport *export)
1112 {
1113 	EvPrintOperation *op = EV_PRINT_OPERATION (export);
1114 
1115 	if (!export->temp_file)
1116 		return; /* cancelled */
1117 
1118 	ev_document_doc_mutex_lock ();
1119 	ev_file_exporter_begin (EV_FILE_EXPORTER (op->document), &export->fc);
1120 	ev_document_doc_mutex_unlock ();
1121 
1122 	export->idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
1123 					   (GSourceFunc)export_print_page,
1124 					   export,
1125 					   (GDestroyNotify)export_print_page_idle_finished);
1126 }
1127 
1128 static void
ev_print_operation_export_print_dialog_response_cb(GtkDialog * dialog,gint response,EvPrintOperationExport * export)1129 ev_print_operation_export_print_dialog_response_cb (GtkDialog              *dialog,
1130 						    gint                    response,
1131 						    EvPrintOperationExport *export)
1132 {
1133 	GtkPrintPages     print_pages;
1134 	GtkPrintSettings *print_settings;
1135 	GtkPageSetup     *page_setup;
1136 	GtkPrinter       *printer;
1137 	gdouble           scale;
1138 	gdouble           width;
1139 	gdouble           height;
1140 	gint              first_page;
1141 	gint              last_page;
1142 	const gchar      *file_format;
1143 	gchar            *filename;
1144 	GError           *error = NULL;
1145 	EvPrintOperation *op = EV_PRINT_OPERATION (export);
1146 
1147 	if (response != GTK_RESPONSE_OK &&
1148 	    response != GTK_RESPONSE_APPLY) {
1149 		gtk_widget_destroy (GTK_WIDGET (dialog));
1150 		g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_CANCEL);
1151 
1152 		return;
1153 	}
1154 
1155 	export->print_preview = (response == GTK_RESPONSE_APPLY);
1156 
1157 	printer = gtk_print_unix_dialog_get_selected_printer (GTK_PRINT_UNIX_DIALOG (dialog));
1158 	ev_print_operation_export_set_printer (export, printer);
1159 
1160 	print_settings = gtk_print_unix_dialog_get_settings (GTK_PRINT_UNIX_DIALOG (dialog));
1161 	ev_print_operation_export_set_print_settings (op, print_settings);
1162 
1163 	page_setup = gtk_print_unix_dialog_get_page_setup (GTK_PRINT_UNIX_DIALOG (dialog));
1164 	ev_print_operation_export_set_default_page_setup (op, page_setup);
1165 
1166 	if (!gtk_printer_accepts_ps (export->printer)) {
1167 		gtk_widget_destroy (GTK_WIDGET (dialog));
1168 
1169 		g_set_error_literal (&export->error,
1170                                      GTK_PRINT_ERROR,
1171                                      GTK_PRINT_ERROR_GENERAL,
1172                                      _("Printing is not supported on this printer."));
1173 		g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
1174 
1175 		return;
1176 	}
1177 
1178 	file_format = gtk_print_settings_get (print_settings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT);
1179 
1180 	filename = g_strdup_printf ("atril_print.%s.XXXXXX", file_format != NULL ? file_format : "");
1181 	export->fd = g_file_open_tmp (filename, &export->temp_file, &error);
1182 	g_free (filename);
1183 	if (export->fd <= -1) {
1184 		gtk_widget_destroy (GTK_WIDGET (dialog));
1185 
1186 		g_set_error_literal (&export->error,
1187 				     GTK_PRINT_ERROR,
1188 				     GTK_PRINT_ERROR_GENERAL,
1189 				     error->message);
1190 		g_error_free (error);
1191 		g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
1192 
1193 		return;
1194 	}
1195 
1196 	export->current_page = gtk_print_unix_dialog_get_current_page (GTK_PRINT_UNIX_DIALOG (dialog));
1197 	export->page_set = gtk_print_settings_get_page_set (print_settings);
1198 	print_pages = gtk_print_settings_get_print_pages (print_settings);
1199 
1200 	switch (print_pages) {
1201 	case GTK_PRINT_PAGES_CURRENT:
1202 		export->ranges = &export->one_range;
1203 
1204 		export->ranges[0].start = export->current_page;
1205 		export->ranges[0].end = export->current_page;
1206 		export->n_ranges = 1;
1207 
1208 		break;
1209 	case GTK_PRINT_PAGES_RANGES: {
1210 		gint i;
1211 
1212 		export->ranges = gtk_print_settings_get_page_ranges (print_settings, &export->n_ranges);
1213 		for (i = 0; i < export->n_ranges; i++)
1214 			if (export->ranges[i].end == -1 || export->ranges[i].end >= export->n_pages)
1215 				export->ranges[i].end = export->n_pages - 1;
1216 	}
1217 		break;
1218 	default:
1219 		g_warning ("Unsupported print pages setting\n");
1220 	case GTK_PRINT_PAGES_ALL:
1221 		export->ranges = &export->one_range;
1222 
1223 		export->ranges[0].start = 0;
1224 		export->ranges[0].end = export->n_pages - 1;
1225 		export->n_ranges = 1;
1226 
1227 		break;
1228 	}
1229 
1230 	if (export->n_ranges < 1 || !clamp_ranges (export)) {
1231 		GtkWidget *message_dialog;
1232 
1233 		message_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog),
1234 						 GTK_DIALOG_MODAL,
1235 						 GTK_MESSAGE_WARNING,
1236 						 GTK_BUTTONS_CLOSE,
1237 						 "%s", _("Invalid page selection"));
1238 		gtk_window_set_title (GTK_WINDOW (message_dialog), _("Warning"));
1239 		gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message_dialog),
1240 							  "%s", _("Your print range selection does not include any pages"));
1241 		g_signal_connect (message_dialog, "response",
1242 				  G_CALLBACK (gtk_widget_destroy),
1243 				  NULL);
1244 		gtk_widget_show (message_dialog);
1245 
1246 		return;
1247 	} else	ev_print_operation_update_status (op, -1, -1, 0.0);
1248 
1249 	width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS);
1250 	height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS);
1251 	scale = gtk_print_settings_get_scale (print_settings) * 0.01;
1252 	if (scale != 1.0) {
1253 		width *= scale;
1254 		height *= scale;
1255 	}
1256 
1257 	export->pages_per_sheet = MAX (1, gtk_print_settings_get_number_up (print_settings));
1258 
1259 	export->copies = gtk_print_settings_get_n_copies (print_settings);
1260 	export->collate = gtk_print_settings_get_collate (print_settings);
1261 	export->reverse = gtk_print_settings_get_reverse (print_settings);
1262 
1263 	if (export->collate) {
1264 		export->uncollated_copies = export->copies;
1265 		export->collated_copies = 1;
1266 	} else {
1267 		export->uncollated_copies = 1;
1268 		export->collated_copies = export->copies;
1269 	}
1270 
1271 	if (export->reverse) {
1272 		export->range = export->n_ranges - 1;
1273 		export->inc = -1;
1274 	} else {
1275 		export->range = 0;
1276 		export->inc = 1;
1277 	}
1278 	find_range (export);
1279 
1280 	export->page = export->start - export->inc;
1281 	export->collated = export->collated_copies - 1;
1282 
1283 	get_first_and_last_page (export, &first_page, &last_page);
1284 
1285 	export->fc.format = file_format && g_ascii_strcasecmp (file_format, "pdf") == 0 ?
1286 		EV_FILE_FORMAT_PDF : EV_FILE_FORMAT_PS;
1287 	export->fc.filename = export->temp_file;
1288 	export->fc.first_page = MIN (first_page, last_page);
1289 	export->fc.last_page = MAX (first_page, last_page);
1290 	export->fc.paper_width = width;
1291 	export->fc.paper_height = height;
1292 	export->fc.duplex = FALSE;
1293 	export->fc.pages_per_sheet = export->pages_per_sheet;
1294 
1295 	if (ev_print_queue_is_empty (op->document))
1296 		ev_print_operation_export_begin (export);
1297 
1298 	ev_print_queue_push (op);
1299 
1300 	g_signal_emit (op, signals[BEGIN_PRINT], 0);
1301 
1302 	gtk_widget_destroy (GTK_WIDGET (dialog));
1303 }
1304 
1305 static void
ev_print_operation_export_run(EvPrintOperation * op,GtkWindow * parent)1306 ev_print_operation_export_run (EvPrintOperation *op,
1307 			       GtkWindow        *parent)
1308 {
1309 	EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1310 	GtkWidget              *dialog;
1311 	GtkPrintCapabilities    capabilities;
1312 
1313 	ev_print_queue_init ();
1314 
1315 	export->parent_window = parent;
1316 	export->error = NULL;
1317 
1318 	/* translators: Title of the print dialog */
1319 	dialog = gtk_print_unix_dialog_new (_("Print"), parent);
1320 	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
1321 
1322 	capabilities = GTK_PRINT_CAPABILITY_PREVIEW |
1323 		ev_file_exporter_get_capabilities (EV_FILE_EXPORTER (op->document));
1324 	gtk_print_unix_dialog_set_manual_capabilities (GTK_PRINT_UNIX_DIALOG (dialog),
1325 						       capabilities);
1326 
1327 	gtk_print_unix_dialog_set_embed_page_setup (GTK_PRINT_UNIX_DIALOG (dialog),
1328 						    export->embed_page_setup);
1329 
1330 	gtk_print_unix_dialog_set_current_page (GTK_PRINT_UNIX_DIALOG (dialog),
1331 						export->current_page);
1332 
1333 	gtk_print_unix_dialog_set_settings (GTK_PRINT_UNIX_DIALOG (dialog),
1334 					    export->print_settings);
1335 
1336 	if (export->page_setup)
1337 		gtk_print_unix_dialog_set_page_setup (GTK_PRINT_UNIX_DIALOG (dialog),
1338 						      export->page_setup);
1339 
1340 	g_signal_connect (dialog, "response",
1341 			  G_CALLBACK (ev_print_operation_export_print_dialog_response_cb),
1342 			  export);
1343 
1344 	gtk_window_present (GTK_WINDOW (dialog));
1345 }
1346 
1347 static void
ev_print_operation_export_cancel(EvPrintOperation * op)1348 ev_print_operation_export_cancel (EvPrintOperation *op)
1349 {
1350 	EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1351 
1352 	if (export->job_export &&
1353 	    !ev_job_is_finished (export->job_export)) {
1354 		ev_job_cancel (export->job_export);
1355 	} else {
1356 		export_cancel (export);
1357 	}
1358 }
1359 
1360 static void
ev_print_operation_export_get_error(EvPrintOperation * op,GError ** error)1361 ev_print_operation_export_get_error (EvPrintOperation *op,
1362 				     GError          **error)
1363 {
1364 	EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1365 
1366 	g_propagate_error (error, export->error);
1367 	export->error = NULL;
1368 }
1369 
1370 static void
ev_print_operation_export_set_embed_page_setup(EvPrintOperation * op,gboolean embed)1371 ev_print_operation_export_set_embed_page_setup (EvPrintOperation *op,
1372 						gboolean          embed)
1373 {
1374 	EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1375 
1376 	export->embed_page_setup = embed;
1377 }
1378 
1379 static gboolean
ev_print_operation_export_get_embed_page_setup(EvPrintOperation * op)1380 ev_print_operation_export_get_embed_page_setup (EvPrintOperation *op)
1381 {
1382 	EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1383 
1384 	return export->embed_page_setup;
1385 }
1386 
1387 static void
ev_print_operation_export_finalize(GObject * object)1388 ev_print_operation_export_finalize (GObject *object)
1389 {
1390 	EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (object);
1391 
1392 	if (export->idle_id > 0) {
1393 		g_source_remove (export->idle_id);
1394 		export->idle_id = 0;
1395 	}
1396 
1397 	if (export->fd != -1) {
1398 		close (export->fd);
1399 		export->fd = -1;
1400 	}
1401 
1402 	if (export->ranges) {
1403 		if (export->ranges != &export->one_range)
1404 			g_free (export->ranges);
1405 		export->ranges = NULL;
1406 		export->n_ranges = 0;
1407 	}
1408 
1409 	if (export->temp_file) {
1410 		g_free (export->temp_file);
1411 		export->temp_file = NULL;
1412 	}
1413 
1414 	if (export->job_name) {
1415 		g_free (export->job_name);
1416 		export->job_name = NULL;
1417 	}
1418 
1419 	if (export->job_export) {
1420 		if (!ev_job_is_finished (export->job_export))
1421 			ev_job_cancel (export->job_export);
1422 		g_signal_handlers_disconnect_by_func (export->job_export,
1423 						      export_job_finished,
1424 						      export);
1425 		g_signal_handlers_disconnect_by_func (export->job_export,
1426 						      export_job_cancelled,
1427 						      export);
1428 		g_object_unref (export->job_export);
1429 		export->job_export = NULL;
1430 	}
1431 
1432 	if (export->error) {
1433 		g_error_free (export->error);
1434 		export->error = NULL;
1435 	}
1436 
1437 	if (export->print_settings) {
1438 		g_object_unref (export->print_settings);
1439 		export->print_settings = NULL;
1440 	}
1441 
1442 	if (export->page_setup) {
1443 		g_object_unref (export->page_setup);
1444 		export->page_setup = NULL;
1445 	}
1446 
1447 	if (export->printer) {
1448 		g_object_unref (export->printer);
1449 		export->printer = NULL;
1450 	}
1451 
1452 	(* G_OBJECT_CLASS (ev_print_operation_export_parent_class)->finalize) (object);
1453 }
1454 
1455 static void
ev_print_operation_export_init(EvPrintOperationExport * export)1456 ev_print_operation_export_init (EvPrintOperationExport *export)
1457 {
1458 	/* sheets are counted from 1 to be physical */
1459 	export->sheet = 1;
1460 }
1461 
1462 static GObject *
ev_print_operation_export_constructor(GType type,guint n_construct_properties,GObjectConstructParam * construct_params)1463 ev_print_operation_export_constructor (GType                  type,
1464 				       guint                  n_construct_properties,
1465 				       GObjectConstructParam *construct_params)
1466 {
1467 	GObject                *object;
1468 	EvPrintOperationExport *export;
1469 	EvPrintOperation       *op;
1470 
1471 	object = G_OBJECT_CLASS (ev_print_operation_export_parent_class)->constructor (type,
1472 										       n_construct_properties,
1473 										       construct_params);
1474 	export = EV_PRINT_OPERATION_EXPORT (object);
1475 	op = EV_PRINT_OPERATION (object);
1476 	export->n_pages = ev_document_get_n_pages (op->document);
1477 
1478 	return object;
1479 }
1480 
1481 static void
ev_print_operation_export_class_init(EvPrintOperationExportClass * klass)1482 ev_print_operation_export_class_init (EvPrintOperationExportClass *klass)
1483 {
1484 	GObjectClass          *g_object_class = G_OBJECT_CLASS (klass);
1485 	EvPrintOperationClass *ev_print_op_class = EV_PRINT_OPERATION_CLASS (klass);
1486 
1487 	ev_print_op_class->set_current_page = ev_print_operation_export_set_current_page;
1488 	ev_print_op_class->set_print_settings = ev_print_operation_export_set_print_settings;
1489 	ev_print_op_class->get_print_settings = ev_print_operation_export_get_print_settings;
1490 	ev_print_op_class->set_default_page_setup = ev_print_operation_export_set_default_page_setup;
1491 	ev_print_op_class->get_default_page_setup = ev_print_operation_export_get_default_page_setup;
1492 	ev_print_op_class->set_job_name = ev_print_operation_export_set_job_name;
1493 	ev_print_op_class->get_job_name = ev_print_operation_export_get_job_name;
1494 	ev_print_op_class->run = ev_print_operation_export_run;
1495 	ev_print_op_class->cancel = ev_print_operation_export_cancel;
1496 	ev_print_op_class->get_error = ev_print_operation_export_get_error;
1497 	ev_print_op_class->set_embed_page_setup = ev_print_operation_export_set_embed_page_setup;
1498 	ev_print_op_class->get_embed_page_setup = ev_print_operation_export_get_embed_page_setup;
1499 
1500 	g_object_class->constructor = ev_print_operation_export_constructor;
1501 	g_object_class->finalize = ev_print_operation_export_finalize;
1502 }
1503 
1504 #endif /* GTKUNIXPRINT_ENABLED */
1505 
1506 /* Print to cairo interface */
1507 #define EV_TYPE_PRINT_OPERATION_PRINT         (ev_print_operation_print_get_type())
1508 #define EV_PRINT_OPERATION_PRINT(object)      (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_PRINT_OPERATION_PRINT, EvPrintOperationPrint))
1509 
1510 typedef struct _EvPrintOperationPrint      EvPrintOperationPrint;
1511 typedef struct _EvPrintOperationPrintClass EvPrintOperationPrintClass;
1512 
1513 static GType ev_print_operation_print_get_type (void) G_GNUC_CONST;
1514 
1515 typedef enum {
1516 	EV_SCALE_NONE,
1517 	EV_SCALE_SHRINK_TO_PRINTABLE_AREA,
1518 	EV_SCALE_FIT_TO_PRINTABLE_AREA
1519 } EvPrintScale;
1520 
1521 #define EV_PRINT_SETTING_PAGE_SCALE "atril-print-setting-page-scale"
1522 #define EV_PRINT_SETTING_AUTOROTATE "atril-print-setting-page-autorotate"
1523 #define EV_PRINT_SETTING_PAGE_SIZE  "atril-print-setting-page-size"
1524 
1525 struct _EvPrintOperationPrint {
1526 	EvPrintOperation parent;
1527 
1528 	GtkPrintOperation *op;
1529 	gint               n_pages_to_print;
1530 	gint               total;
1531 	EvJob             *job_print;
1532 	gchar             *job_name;
1533 
1534         /* Page handling tab */
1535         GtkWidget   *scale_combo;
1536         EvPrintScale page_scale;
1537 	GtkWidget   *autorotate_button;
1538 	gboolean     autorotate;
1539 	GtkWidget   *source_button;
1540 	gboolean     use_source_size;
1541 };
1542 
1543 struct _EvPrintOperationPrintClass {
1544 	EvPrintOperationClass parent_class;
1545 };
1546 
G_DEFINE_TYPE(EvPrintOperationPrint,ev_print_operation_print,EV_TYPE_PRINT_OPERATION)1547 G_DEFINE_TYPE (EvPrintOperationPrint, ev_print_operation_print, EV_TYPE_PRINT_OPERATION)
1548 
1549 static void
1550 ev_print_operation_print_set_current_page (EvPrintOperation *op,
1551 					   gint              current_page)
1552 {
1553 	EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1554 
1555 	gtk_print_operation_set_current_page (print->op, current_page);
1556 }
1557 
1558 static void
ev_print_operation_print_set_print_settings(EvPrintOperation * op,GtkPrintSettings * print_settings)1559 ev_print_operation_print_set_print_settings (EvPrintOperation *op,
1560 					     GtkPrintSettings *print_settings)
1561 {
1562 	EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1563 
1564 	gtk_print_operation_set_print_settings (print->op, print_settings);
1565 }
1566 
1567 static GtkPrintSettings *
ev_print_operation_print_get_print_settings(EvPrintOperation * op)1568 ev_print_operation_print_get_print_settings (EvPrintOperation *op)
1569 {
1570 	EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1571 
1572 	return gtk_print_operation_get_print_settings (print->op);
1573 }
1574 
1575 static void
ev_print_operation_print_set_default_page_setup(EvPrintOperation * op,GtkPageSetup * page_setup)1576 ev_print_operation_print_set_default_page_setup (EvPrintOperation *op,
1577 						 GtkPageSetup     *page_setup)
1578 {
1579 	EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1580 
1581 	gtk_print_operation_set_default_page_setup (print->op, page_setup);
1582 }
1583 
1584 static GtkPageSetup *
ev_print_operation_print_get_default_page_setup(EvPrintOperation * op)1585 ev_print_operation_print_get_default_page_setup (EvPrintOperation *op)
1586 {
1587 	EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1588 
1589 	return gtk_print_operation_get_default_page_setup (print->op);
1590 }
1591 
1592 static void
ev_print_operation_print_set_job_name(EvPrintOperation * op,const gchar * job_name)1593 ev_print_operation_print_set_job_name (EvPrintOperation *op,
1594 				       const gchar      *job_name)
1595 {
1596 	EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1597 
1598 	g_free (print->job_name);
1599 	print->job_name = g_strdup (job_name);
1600 
1601 	gtk_print_operation_set_job_name (print->op, print->job_name);
1602 }
1603 
1604 static const gchar *
ev_print_operation_print_get_job_name(EvPrintOperation * op)1605 ev_print_operation_print_get_job_name (EvPrintOperation *op)
1606 {
1607 	EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1608 
1609 	if (!print->job_name) {
1610 		gchar *name;
1611 
1612 		g_object_get (print->op, "job_name", &name, NULL);
1613 		print->job_name = name;
1614 	}
1615 
1616 	return print->job_name;
1617 }
1618 
1619 static void
ev_print_operation_print_run(EvPrintOperation * op,GtkWindow * parent)1620 ev_print_operation_print_run (EvPrintOperation *op,
1621 			      GtkWindow        *parent)
1622 {
1623 	EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1624 
1625 	gtk_print_operation_run (print->op,
1626 				 GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
1627 				 parent, NULL);
1628 }
1629 
1630 static void
ev_print_operation_print_cancel(EvPrintOperation * op)1631 ev_print_operation_print_cancel (EvPrintOperation *op)
1632 {
1633 	EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1634 
1635         if (print->job_print)
1636                 ev_job_cancel (print->job_print);
1637         else
1638                 gtk_print_operation_cancel (print->op);
1639 }
1640 
1641 static void
ev_print_operation_print_get_error(EvPrintOperation * op,GError ** error)1642 ev_print_operation_print_get_error (EvPrintOperation *op,
1643 				    GError          **error)
1644 {
1645 	EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1646 
1647 	gtk_print_operation_get_error (print->op, error);
1648 }
1649 
1650 static void
ev_print_operation_print_set_embed_page_setup(EvPrintOperation * op,gboolean embed)1651 ev_print_operation_print_set_embed_page_setup (EvPrintOperation *op,
1652 					       gboolean          embed)
1653 {
1654 	EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1655 
1656 	gtk_print_operation_set_embed_page_setup (print->op, embed);
1657 }
1658 
1659 static gboolean
ev_print_operation_print_get_embed_page_setup(EvPrintOperation * op)1660 ev_print_operation_print_get_embed_page_setup (EvPrintOperation *op)
1661 {
1662 	EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1663 
1664 	return gtk_print_operation_get_embed_page_setup (print->op);
1665 }
1666 
1667 static void
ev_print_operation_print_begin_print(EvPrintOperationPrint * print,GtkPrintContext * context)1668 ev_print_operation_print_begin_print (EvPrintOperationPrint *print,
1669 				      GtkPrintContext       *context)
1670 {
1671 	EvPrintOperation *op = EV_PRINT_OPERATION (print);
1672 	gint              n_pages;
1673 
1674 	n_pages = ev_document_get_n_pages (op->document);
1675 	gtk_print_operation_set_n_pages (print->op, n_pages);
1676 	ev_print_operation_update_status (op, -1, n_pages, 0);
1677 
1678 	g_signal_emit (op, signals[BEGIN_PRINT], 0);
1679 }
1680 
1681 static void
ev_print_operation_print_done(EvPrintOperationPrint * print,GtkPrintOperationResult result)1682 ev_print_operation_print_done (EvPrintOperationPrint  *print,
1683 			       GtkPrintOperationResult result)
1684 {
1685 	EvPrintOperation *op = EV_PRINT_OPERATION (print);
1686 
1687 	ev_print_operation_update_status (op, 0, print->n_pages_to_print, 1.0);
1688 
1689 	g_signal_emit (op, signals[DONE], 0, result);
1690 }
1691 
1692 static void
ev_print_operation_print_status_changed(EvPrintOperationPrint * print)1693 ev_print_operation_print_status_changed (EvPrintOperationPrint *print)
1694 {
1695 	GtkPrintStatus status;
1696 
1697 	status = gtk_print_operation_get_status (print->op);
1698 	if (status == GTK_PRINT_STATUS_GENERATING_DATA)
1699 		print->n_pages_to_print = gtk_print_operation_get_n_pages_to_print (print->op);
1700 }
1701 
1702 static void
print_job_finished(EvJobPrint * job,EvPrintOperationPrint * print)1703 print_job_finished (EvJobPrint            *job,
1704 		    EvPrintOperationPrint *print)
1705 {
1706 	EvPrintOperation *op = EV_PRINT_OPERATION (print);
1707 
1708 	gtk_print_operation_draw_page_finish (print->op);
1709 
1710 	print->total++;
1711 	ev_print_operation_update_status (op, print->total,
1712 					  print->n_pages_to_print,
1713 					  print->total / (gdouble)print->n_pages_to_print);
1714 	ev_job_print_set_cairo (job, NULL);
1715 }
1716 
1717 static gboolean
draw_page_finish_idle(EvPrintOperationPrint * print)1718 draw_page_finish_idle (EvPrintOperationPrint *print)
1719 {
1720         if (ev_job_scheduler_get_running_thread_job () == print->job_print)
1721                 return TRUE;
1722 
1723         gtk_print_operation_draw_page_finish (print->op);
1724 
1725         return FALSE;
1726 }
1727 
1728 static void
print_job_cancelled(EvJobPrint * job,EvPrintOperationPrint * print)1729 print_job_cancelled (EvJobPrint            *job,
1730                      EvPrintOperationPrint *print)
1731 {
1732         /* Finish the current page, so that draw-page
1733          * is emitted again and it will cancel the
1734          * print operation. If the job is still
1735          * running, wait until it finishes.
1736          */
1737         if (ev_job_scheduler_get_running_thread_job () == print->job_print)
1738                 g_idle_add ((GSourceFunc)draw_page_finish_idle, print);
1739         else
1740                 gtk_print_operation_draw_page_finish (print->op);
1741 }
1742 
1743 static void
ev_print_operation_print_request_page_setup(EvPrintOperationPrint * print,GtkPrintContext * context,gint page_nr,GtkPageSetup * setup)1744 ev_print_operation_print_request_page_setup (EvPrintOperationPrint *print,
1745 					     GtkPrintContext       *context,
1746 					     gint                   page_nr,
1747 					     GtkPageSetup          *setup)
1748 {
1749 	EvPrintOperation *op = EV_PRINT_OPERATION (print);
1750 	gdouble           width, height;
1751 	GtkPaperSize     *paper_size;
1752 
1753 	ev_document_get_page_size (op->document, page_nr,
1754 				   &width, &height);
1755 
1756 	if (print->use_source_size) {
1757 		paper_size = gtk_paper_size_new_custom ("custom", "custom",
1758 							width, height, GTK_UNIT_POINTS);
1759 		gtk_page_setup_set_paper_size_and_default_margins (setup, paper_size);
1760 		gtk_paper_size_free (paper_size);
1761 	}
1762 
1763 	if (print->autorotate) {
1764 		if (width > height)
1765 			gtk_page_setup_set_orientation (setup, GTK_PAGE_ORIENTATION_LANDSCAPE);
1766 		else
1767 			gtk_page_setup_set_orientation (setup, GTK_PAGE_ORIENTATION_PORTRAIT);
1768 	}
1769 }
1770 
1771 static void
_print_context_get_hard_margins(GtkPrintContext * context,gdouble * top,gdouble * bottom,gdouble * left,gdouble * right)1772 _print_context_get_hard_margins (GtkPrintContext *context,
1773 				 gdouble         *top,
1774 				 gdouble         *bottom,
1775 				 gdouble         *left,
1776 				 gdouble         *right)
1777 {
1778 	if (!gtk_print_context_get_hard_margins (context, top, bottom, left, right)) {
1779 		*top = 0;
1780 		*bottom = 0;
1781 		*left = 0;
1782 		*right = 0;
1783 	}
1784 }
1785 
1786 static void
ev_print_operation_print_draw_page(EvPrintOperationPrint * print,GtkPrintContext * context,gint page)1787 ev_print_operation_print_draw_page (EvPrintOperationPrint *print,
1788 				    GtkPrintContext       *context,
1789 				    gint                   page)
1790 {
1791 	EvPrintOperation *op = EV_PRINT_OPERATION (print);
1792 	cairo_t          *cr;
1793 	gdouble           cr_width, cr_height;
1794 	gdouble           width, height, scale;
1795 	gdouble           x_scale, y_scale;
1796 	gdouble           top, bottom, left, right;
1797 
1798 	gtk_print_operation_set_defer_drawing (print->op);
1799 
1800 	if (!print->job_print) {
1801 		print->job_print = ev_job_print_new (op->document);
1802 		g_signal_connect (G_OBJECT (print->job_print), "finished",
1803 				  G_CALLBACK (print_job_finished),
1804 				  (gpointer)print);
1805                 g_signal_connect (G_OBJECT (print->job_print), "cancelled",
1806                                   G_CALLBACK (print_job_cancelled),
1807                                   (gpointer)print);
1808 	} else if (g_cancellable_is_cancelled (print->job_print->cancellable)) {
1809                 gtk_print_operation_cancel (print->op);
1810                 ev_job_print_set_cairo (EV_JOB_PRINT (print->job_print), NULL);
1811                 return;
1812         }
1813 
1814 	ev_job_print_set_page (EV_JOB_PRINT (print->job_print), page);
1815 
1816 	cr = gtk_print_context_get_cairo_context (context);
1817 	cr_width = gtk_print_context_get_width (context);
1818 	cr_height = gtk_print_context_get_height (context);
1819 	ev_document_get_page_size (op->document, page, &width, &height);
1820 
1821 	if (print->page_scale == EV_SCALE_NONE) {
1822 		/* Center document page on the printed page */
1823 		if (print->autorotate)
1824 			cairo_translate (cr, (cr_width - width) / 2, (cr_height - height) / 2);
1825 	} else {
1826 		_print_context_get_hard_margins (context, &top, &bottom, &left, &right);
1827 
1828 		x_scale = (cr_width - left - right) / width;
1829 		y_scale = (cr_height - top - bottom) / height;
1830 
1831 		if (x_scale < y_scale)
1832 			scale = x_scale;
1833 		else
1834 			scale = y_scale;
1835 
1836 		if (print->autorotate) {
1837 			double left_right_sides, top_bottom_sides;
1838 
1839 			cairo_translate (cr, (cr_width - scale * width) / 2,
1840 					 (cr_height - scale * height) / 2);
1841 
1842 			/* Ensure document page is within the margins. The
1843 			 * scale guarantees the document will fit in the
1844 			 * margins so we just need to check each side and
1845 			 * if it overhangs the margin, translate it to the
1846 			 * margin. */
1847 			left_right_sides = (cr_width - width*scale)/2;
1848 			top_bottom_sides = (cr_height - height*scale)/2;
1849 			if (left_right_sides < left)
1850 				cairo_translate (cr, left - left_right_sides, 0);
1851 
1852 			if (left_right_sides < right)
1853 				cairo_translate (cr, -(right - left_right_sides), 0);
1854 
1855 			if (top_bottom_sides < top)
1856 				cairo_translate (cr, 0, top - top_bottom_sides);
1857 
1858 			if (top_bottom_sides < bottom)
1859 				cairo_translate (cr, 0, -(bottom - top_bottom_sides));
1860 		} else {
1861 			cairo_translate (cr, left, top);
1862 		}
1863 
1864 		if (print->page_scale == EV_SCALE_FIT_TO_PRINTABLE_AREA || scale < 1.0) {
1865 			cairo_scale (cr, scale, scale);
1866 		}
1867 	}
1868 
1869 	ev_job_print_set_cairo (EV_JOB_PRINT (print->job_print), cr);
1870 	ev_job_scheduler_push_job (print->job_print, EV_JOB_PRIORITY_NONE);
1871 }
1872 
1873 static GObject *
ev_print_operation_print_create_custom_widget(EvPrintOperationPrint * print,GtkPrintContext * context)1874 ev_print_operation_print_create_custom_widget (EvPrintOperationPrint *print,
1875 					       GtkPrintContext       *context)
1876 {
1877 	GtkPrintSettings *settings;
1878 	GtkWidget        *label;
1879 	GtkWidget        *grid;
1880 	EvPrintScale      page_scale;
1881 	gboolean          autorotate;
1882 	gboolean          use_source_size;
1883 
1884 	settings = gtk_print_operation_get_print_settings (print->op);
1885 	page_scale = gtk_print_settings_get_int_with_default (settings, EV_PRINT_SETTING_PAGE_SCALE, 1);
1886 	autorotate = gtk_print_settings_has_key (settings, EV_PRINT_SETTING_AUTOROTATE) ?
1887 		gtk_print_settings_get_bool (settings, EV_PRINT_SETTING_AUTOROTATE) :
1888 		TRUE;
1889 	use_source_size = gtk_print_settings_get_bool (settings, EV_PRINT_SETTING_PAGE_SIZE);
1890 
1891 	grid = gtk_grid_new ();
1892 	gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
1893 	gtk_grid_set_column_spacing (GTK_GRID (grid), 12);
1894 	gtk_container_set_border_width (GTK_CONTAINER (grid), 12);
1895 
1896 	label = gtk_label_new (_("Page Scaling:"));
1897 	gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
1898 	gtk_widget_show (label);
1899 
1900 	print->scale_combo = gtk_combo_box_text_new ();
1901 	/* translators: Value for 'Page Scaling:' to not scale the document pages on printing */
1902 	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (print->scale_combo), _("None"));
1903 	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (print->scale_combo), _("Shrink to Printable Area"));
1904 	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (print->scale_combo), _("Fit to Printable Area"));
1905 	gtk_combo_box_set_active (GTK_COMBO_BOX (print->scale_combo), page_scale);
1906 	gtk_widget_set_tooltip_text (print->scale_combo,
1907 		_("Scale document pages to fit the selected printer page. Select from one of the following:\n"
1908 		  "\n"
1909 		  "• \"None\": No page scaling is performed.\n"
1910 		  "\n"
1911 		  "• \"Shrink to Printable Area\": Document pages larger than the printable area"
1912 		  " are reduced to fit the printable area of the printer page.\n"
1913 		  "\n"
1914 		  "• \"Fit to Printable Area\": Document pages are enlarged or reduced as"
1915 		  " required to fit the printable area of the printer page.\n"));
1916 	gtk_grid_attach (GTK_GRID (grid), print->scale_combo, 1, 0, 1, 1);
1917 	gtk_widget_show (print->scale_combo);
1918 
1919 	print->autorotate_button = gtk_check_button_new_with_label (_("Auto Rotate and Center"));
1920 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (print->autorotate_button), autorotate);
1921 	gtk_widget_set_tooltip_text (print->autorotate_button,
1922 		_("Rotate printer page orientation of each page to match orientation of each document page. "
1923 		  "Document pages will be centered within the printer page."));
1924 	gtk_grid_attach (GTK_GRID (grid), print->autorotate_button, 0, 1, 2, 1);
1925 	gtk_widget_show (print->autorotate_button);
1926 
1927 	print->source_button = gtk_check_button_new_with_label (_("Select page size using document page size"));
1928 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (print->source_button), use_source_size);
1929 	gtk_widget_set_tooltip_text (print->source_button, _("When enabled, each page will be printed on "
1930 							     "the same size paper as the document page."));
1931 	gtk_grid_attach (GTK_GRID (grid), print->source_button, 0, 2, 2, 1);
1932 	gtk_widget_show (print->source_button);
1933 
1934 	return G_OBJECT (grid);
1935 }
1936 
1937 static void
ev_print_operation_print_custom_widget_apply(EvPrintOperationPrint * print,GtkPrintContext * context)1938 ev_print_operation_print_custom_widget_apply (EvPrintOperationPrint *print,
1939 					      GtkPrintContext       *context)
1940 {
1941 	GtkPrintSettings *settings;
1942 
1943 	print->page_scale = gtk_combo_box_get_active (GTK_COMBO_BOX (print->scale_combo));
1944 	print->autorotate = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (print->autorotate_button));
1945 	print->use_source_size = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (print->source_button));
1946 	settings = gtk_print_operation_get_print_settings (print->op);
1947 	gtk_print_settings_set_int (settings, EV_PRINT_SETTING_PAGE_SCALE, print->page_scale);
1948 	gtk_print_settings_set_bool (settings, EV_PRINT_SETTING_AUTOROTATE, print->autorotate);
1949 	gtk_print_settings_set_bool (settings, EV_PRINT_SETTING_PAGE_SIZE, print->use_source_size);
1950 }
1951 
1952 static void
ev_print_operation_print_finalize(GObject * object)1953 ev_print_operation_print_finalize (GObject *object)
1954 {
1955 	EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (object);
1956 
1957 	if (print->op) {
1958 		g_object_unref (print->op);
1959 		print->op = NULL;
1960 	}
1961 
1962 	if (print->job_name) {
1963 		g_free (print->job_name);
1964 		print->job_name = NULL;
1965 	}
1966 
1967 	if (print->job_print) {
1968 		if (!ev_job_is_finished (print->job_print))
1969 			ev_job_cancel (print->job_print);
1970 		g_signal_handlers_disconnect_by_func (print->job_print,
1971 						      print_job_finished,
1972 						      print);
1973 		g_signal_handlers_disconnect_by_func (print->job_print,
1974 						      print_job_cancelled,
1975 						      print);
1976 		g_object_unref (print->job_print);
1977 		print->job_print = NULL;
1978 	}
1979 
1980 	(* G_OBJECT_CLASS (ev_print_operation_print_parent_class)->finalize) (object);
1981 }
1982 
1983 static void
ev_print_operation_print_init(EvPrintOperationPrint * print)1984 ev_print_operation_print_init (EvPrintOperationPrint *print)
1985 {
1986 	print->op = gtk_print_operation_new ();
1987 	g_signal_connect_swapped (print->op, "begin_print",
1988 				  G_CALLBACK (ev_print_operation_print_begin_print),
1989 				  print);
1990 	g_signal_connect_swapped (print->op, "done",
1991 				  G_CALLBACK (ev_print_operation_print_done),
1992 				  print);
1993 	g_signal_connect_swapped (print->op, "draw_page",
1994 				  G_CALLBACK (ev_print_operation_print_draw_page),
1995 				  print);
1996 	g_signal_connect_swapped (print->op, "status_changed",
1997 				  G_CALLBACK (ev_print_operation_print_status_changed),
1998 				  print);
1999 	g_signal_connect_swapped (print->op, "request_page_setup",
2000 				  G_CALLBACK (ev_print_operation_print_request_page_setup),
2001 				  print);
2002 	g_signal_connect_swapped (print->op, "create_custom_widget",
2003 				  G_CALLBACK (ev_print_operation_print_create_custom_widget),
2004 				  print);
2005 	g_signal_connect_swapped (print->op, "custom_widget_apply",
2006 				  G_CALLBACK (ev_print_operation_print_custom_widget_apply),
2007 				  print);
2008 	gtk_print_operation_set_allow_async (print->op, TRUE);
2009 	gtk_print_operation_set_use_full_page (print->op, TRUE);
2010 	gtk_print_operation_set_unit (print->op, GTK_UNIT_POINTS);
2011 	gtk_print_operation_set_custom_tab_label (print->op, _("Page Handling"));
2012 }
2013 
2014 static void
ev_print_operation_print_class_init(EvPrintOperationPrintClass * klass)2015 ev_print_operation_print_class_init (EvPrintOperationPrintClass *klass)
2016 {
2017 	GObjectClass          *g_object_class = G_OBJECT_CLASS (klass);
2018 	EvPrintOperationClass *ev_print_op_class = EV_PRINT_OPERATION_CLASS (klass);
2019 
2020 	ev_print_op_class->set_current_page = ev_print_operation_print_set_current_page;
2021 	ev_print_op_class->set_print_settings = ev_print_operation_print_set_print_settings;
2022 	ev_print_op_class->get_print_settings = ev_print_operation_print_get_print_settings;
2023 	ev_print_op_class->set_default_page_setup = ev_print_operation_print_set_default_page_setup;
2024 	ev_print_op_class->get_default_page_setup = ev_print_operation_print_get_default_page_setup;
2025 	ev_print_op_class->set_job_name = ev_print_operation_print_set_job_name;
2026 	ev_print_op_class->get_job_name = ev_print_operation_print_get_job_name;
2027 	ev_print_op_class->run = ev_print_operation_print_run;
2028 	ev_print_op_class->cancel = ev_print_operation_print_cancel;
2029 	ev_print_op_class->get_error = ev_print_operation_print_get_error;
2030 	ev_print_op_class->set_embed_page_setup = ev_print_operation_print_set_embed_page_setup;
2031 	ev_print_op_class->get_embed_page_setup = ev_print_operation_print_get_embed_page_setup;
2032 
2033 	g_object_class->finalize = ev_print_operation_print_finalize;
2034 }
2035 
2036 gboolean
ev_print_operation_exists_for_document(EvDocument * document)2037 ev_print_operation_exists_for_document (EvDocument *document)
2038 {
2039 #if GTKUNIXPRINT_ENABLED
2040 	return (EV_IS_FILE_EXPORTER(document) || EV_IS_DOCUMENT_PRINT(document));
2041 #else
2042 	return EV_IS_DOCUMENT_PRINT(document);
2043 #endif /* GTKUNIXPRINT_ENABLED */
2044 }
2045 
2046 /* Factory method */
2047 EvPrintOperation *
ev_print_operation_new(EvDocument * document)2048 ev_print_operation_new (EvDocument *document)
2049 {
2050 	EvPrintOperation *op = NULL;
2051 
2052 	g_return_val_if_fail (ev_print_operation_exists_for_document (document), NULL);
2053 
2054 	if (EV_IS_DOCUMENT_PRINT (document))
2055 		op = EV_PRINT_OPERATION (g_object_new (EV_TYPE_PRINT_OPERATION_PRINT,
2056 						       "document", document, NULL));
2057 	else
2058 #if GTKUNIXPRINT_ENABLED
2059 		op = EV_PRINT_OPERATION (g_object_new (EV_TYPE_PRINT_OPERATION_EXPORT,
2060 						       "document", document, NULL));
2061 #else
2062 		op = NULL;
2063 #endif
2064 	return op;
2065 }
2066