1 /*
2 * gedit-print-job.c
3 * This file is part of gedit
4 *
5 * Copyright (C) 2000-2001 Chema Celorio, Paolo Maggi
6 * Copyright (C) 2002-2008 Paolo Maggi
7 * Copyright (C) 2015 Sébastien Wilmet
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "gedit-print-job.h"
24
25 #include <glib/gi18n.h>
26 #include <tepl/tepl.h>
27
28 #include "gedit-debug.h"
29 #include "gedit-document-private.h"
30 #include "gedit-print-preview.h"
31 #include "gedit-utils.h"
32 #include "gedit-dirs.h"
33 #include "gedit-settings.h"
34
35 struct _GeditPrintJob
36 {
37 GObject parent_instance;
38
39 GSettings *gsettings;
40
41 GeditView *view;
42
43 GtkPrintOperation *operation;
44 GtkSourcePrintCompositor *compositor;
45
46 GtkWidget *preview;
47
48 gchar *status_string;
49 gdouble progress;
50
51 /* Widgets part of the custom print preferences widget.
52 * These pointers are valid just when the dialog is displayed.
53 */
54 GtkToggleButton *syntax_checkbutton;
55 GtkToggleButton *page_header_checkbutton;
56 GtkToggleButton *line_numbers_checkbutton;
57 GtkSpinButton *line_numbers_spinbutton;
58 GtkToggleButton *text_wrapping_checkbutton;
59 GtkToggleButton *do_not_split_checkbutton;
60 GtkFontButton *body_fontbutton;
61 GtkFontButton *headers_fontbutton;
62 GtkFontButton *numbers_fontbutton;
63
64 guint is_preview : 1;
65 };
66
67 enum
68 {
69 PROP_0,
70 PROP_VIEW,
71 LAST_PROP
72 };
73
74 static GParamSpec *properties[LAST_PROP];
75
76 enum
77 {
78 PRINTING,
79 SHOW_PREVIEW,
80 DONE,
81 LAST_SIGNAL
82 };
83
84 static guint signals[LAST_SIGNAL];
85
G_DEFINE_TYPE(GeditPrintJob,gedit_print_job,G_TYPE_OBJECT)86 G_DEFINE_TYPE (GeditPrintJob, gedit_print_job, G_TYPE_OBJECT)
87
88 static void
89 gedit_print_job_get_property (GObject *object,
90 guint prop_id,
91 GValue *value,
92 GParamSpec *pspec)
93 {
94 GeditPrintJob *job = GEDIT_PRINT_JOB (object);
95
96 switch (prop_id)
97 {
98 case PROP_VIEW:
99 g_value_set_object (value, job->view);
100 break;
101
102 default:
103 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
104 break;
105 }
106 }
107
108 static void
gedit_print_job_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)109 gedit_print_job_set_property (GObject *object,
110 guint prop_id,
111 const GValue *value,
112 GParamSpec *pspec)
113 {
114 GeditPrintJob *job = GEDIT_PRINT_JOB (object);
115
116 switch (prop_id)
117 {
118 case PROP_VIEW:
119 job->view = g_value_get_object (value);
120 break;
121
122 default:
123 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
124 break;
125 }
126 }
127
128 static void
gedit_print_job_dispose(GObject * object)129 gedit_print_job_dispose (GObject *object)
130 {
131 GeditPrintJob *job = GEDIT_PRINT_JOB (object);
132
133 g_clear_object (&job->gsettings);
134 g_clear_object (&job->operation);
135 g_clear_object (&job->compositor);
136 g_clear_object (&job->preview);
137
138 G_OBJECT_CLASS (gedit_print_job_parent_class)->dispose (object);
139 }
140
141 static void
gedit_print_job_finalize(GObject * object)142 gedit_print_job_finalize (GObject *object)
143 {
144 GeditPrintJob *job = GEDIT_PRINT_JOB (object);
145
146 g_free (job->status_string);
147
148 G_OBJECT_CLASS (gedit_print_job_parent_class)->finalize (object);
149 }
150
151 static void
gedit_print_job_printing(GeditPrintJob * job,GeditPrintJobStatus status)152 gedit_print_job_printing (GeditPrintJob *job,
153 GeditPrintJobStatus status)
154 {
155 }
156
157 static void
gedit_print_job_show_preview(GeditPrintJob * job,GtkWidget * preview)158 gedit_print_job_show_preview (GeditPrintJob *job,
159 GtkWidget *preview)
160 {
161 }
162
163 static void
gedit_print_job_done(GeditPrintJob * job,GeditPrintJobResult result,const GError * error)164 gedit_print_job_done (GeditPrintJob *job,
165 GeditPrintJobResult result,
166 const GError *error)
167 {
168 }
169
170 static void
gedit_print_job_class_init(GeditPrintJobClass * klass)171 gedit_print_job_class_init (GeditPrintJobClass *klass)
172 {
173 GObjectClass *object_class;
174
175 object_class = G_OBJECT_CLASS (klass);
176
177 object_class->get_property = gedit_print_job_get_property;
178 object_class->set_property = gedit_print_job_set_property;
179 object_class->dispose = gedit_print_job_dispose;
180 object_class->finalize = gedit_print_job_finalize;
181
182 properties[PROP_VIEW] =
183 g_param_spec_object ("view",
184 "Gedit View",
185 "Gedit View to print",
186 GEDIT_TYPE_VIEW,
187 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
188
189 g_object_class_install_properties (object_class, LAST_PROP, properties);
190
191 signals[PRINTING] =
192 g_signal_new_class_handler ("printing",
193 G_TYPE_FROM_CLASS (klass),
194 G_SIGNAL_RUN_LAST,
195 G_CALLBACK (gedit_print_job_printing),
196 NULL, NULL, NULL,
197 G_TYPE_NONE,
198 1,
199 G_TYPE_UINT);
200
201 signals[SHOW_PREVIEW] =
202 g_signal_new_class_handler ("show-preview",
203 G_TYPE_FROM_CLASS (klass),
204 G_SIGNAL_RUN_LAST,
205 G_CALLBACK (gedit_print_job_show_preview),
206 NULL, NULL, NULL,
207 G_TYPE_NONE,
208 1,
209 GTK_TYPE_WIDGET);
210
211 signals[DONE] =
212 g_signal_new_class_handler ("done",
213 G_TYPE_FROM_CLASS (klass),
214 G_SIGNAL_RUN_LAST,
215 G_CALLBACK (gedit_print_job_done),
216 NULL, NULL, NULL,
217 G_TYPE_NONE,
218 2,
219 G_TYPE_UINT,
220 G_TYPE_POINTER);
221 }
222
223 static void
gedit_print_job_init(GeditPrintJob * job)224 gedit_print_job_init (GeditPrintJob *job)
225 {
226 job->gsettings = g_settings_new ("org.gnome.gedit.preferences.print");
227
228 job->status_string = g_strdup (_("Preparing…"));
229 }
230
231 static void
restore_button_clicked(GtkButton * button,GeditPrintJob * job)232 restore_button_clicked (GtkButton *button,
233 GeditPrintJob *job)
234
235 {
236 g_settings_reset (job->gsettings, GEDIT_SETTINGS_PRINT_FONT_BODY_PANGO);
237 g_settings_reset (job->gsettings, GEDIT_SETTINGS_PRINT_FONT_HEADER_PANGO);
238 g_settings_reset (job->gsettings, GEDIT_SETTINGS_PRINT_FONT_NUMBERS_PANGO);
239 }
240
241 static GObject *
create_custom_widget_cb(GtkPrintOperation * operation,GeditPrintJob * job)242 create_custom_widget_cb (GtkPrintOperation *operation,
243 GeditPrintJob *job)
244 {
245 GtkBuilder *builder;
246 GtkWidget *contents;
247 GtkWidget *line_numbers_hbox;
248 GtkWidget *restore_button;
249 guint line_numbers;
250 GtkWrapMode wrap_mode;
251
252 gchar *root_objects[] = {
253 "adjustment1",
254 "contents",
255 NULL
256 };
257
258 builder = gtk_builder_new ();
259 gtk_builder_add_objects_from_resource (builder, "/org/gnome/gedit/ui/gedit-print-preferences.ui",
260 root_objects, NULL);
261 contents = GTK_WIDGET (gtk_builder_get_object (builder, "contents"));
262 g_object_ref (contents);
263 job->syntax_checkbutton = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "syntax_checkbutton"));
264 job->line_numbers_checkbutton = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "line_numbers_checkbutton"));
265 line_numbers_hbox = GTK_WIDGET (gtk_builder_get_object (builder, "line_numbers_hbox"));
266 job->line_numbers_spinbutton = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "line_numbers_spinbutton"));
267 job->page_header_checkbutton = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "page_header_checkbutton"));
268 job->text_wrapping_checkbutton = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "text_wrapping_checkbutton"));
269 job->do_not_split_checkbutton = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "do_not_split_checkbutton"));
270 job->body_fontbutton = GTK_FONT_BUTTON (gtk_builder_get_object (builder, "body_fontbutton"));
271 job->headers_fontbutton = GTK_FONT_BUTTON (gtk_builder_get_object (builder, "headers_fontbutton"));
272 job->numbers_fontbutton = GTK_FONT_BUTTON (gtk_builder_get_object (builder, "numbers_fontbutton"));
273 restore_button = GTK_WIDGET (gtk_builder_get_object (builder, "restore_button"));
274 g_object_unref (builder);
275
276 /* Syntax highlighting */
277 g_settings_bind (job->gsettings, GEDIT_SETTINGS_PRINT_SYNTAX_HIGHLIGHTING,
278 job->syntax_checkbutton, "active",
279 G_SETTINGS_BIND_GET);
280
281 /* Print header */
282 g_settings_bind (job->gsettings, GEDIT_SETTINGS_PRINT_HEADER,
283 job->page_header_checkbutton, "active",
284 G_SETTINGS_BIND_GET);
285
286 /* Line numbers */
287 g_settings_get (job->gsettings, GEDIT_SETTINGS_PRINT_LINE_NUMBERS,
288 "u", &line_numbers);
289
290 if (line_numbers > 0)
291 {
292 gtk_spin_button_set_value (job->line_numbers_spinbutton, line_numbers);
293 }
294 else
295 {
296 gtk_spin_button_set_value (job->line_numbers_spinbutton, 1);
297 }
298
299 gtk_toggle_button_set_active (job->line_numbers_checkbutton,
300 line_numbers > 0);
301
302 g_object_bind_property (job->line_numbers_checkbutton, "active",
303 line_numbers_hbox, "sensitive",
304 G_BINDING_SYNC_CREATE);
305
306 /* Fonts */
307 g_settings_bind (job->gsettings, GEDIT_SETTINGS_PRINT_FONT_BODY_PANGO,
308 job->body_fontbutton, "font-name",
309 G_SETTINGS_BIND_GET);
310
311 g_settings_bind (job->gsettings, GEDIT_SETTINGS_PRINT_FONT_HEADER_PANGO,
312 job->headers_fontbutton, "font-name",
313 G_SETTINGS_BIND_GET);
314
315 g_settings_bind (job->gsettings, GEDIT_SETTINGS_PRINT_FONT_NUMBERS_PANGO,
316 job->numbers_fontbutton, "font-name",
317 G_SETTINGS_BIND_GET);
318
319 /* Wrap mode */
320 wrap_mode = g_settings_get_enum (job->gsettings, GEDIT_SETTINGS_PRINT_WRAP_MODE);
321
322 switch (wrap_mode)
323 {
324 case GTK_WRAP_WORD:
325 gtk_toggle_button_set_active (job->text_wrapping_checkbutton, TRUE);
326 gtk_toggle_button_set_active (job->do_not_split_checkbutton, TRUE);
327 break;
328
329 case GTK_WRAP_CHAR:
330 gtk_toggle_button_set_active (job->text_wrapping_checkbutton, TRUE);
331 gtk_toggle_button_set_active (job->do_not_split_checkbutton, FALSE);
332 break;
333
334 default:
335 gtk_toggle_button_set_active (job->text_wrapping_checkbutton, FALSE);
336 break;
337 }
338
339 g_object_bind_property (job->text_wrapping_checkbutton, "active",
340 job->do_not_split_checkbutton, "sensitive",
341 G_BINDING_SYNC_CREATE);
342
343 g_object_bind_property (job->text_wrapping_checkbutton, "active",
344 job->do_not_split_checkbutton, "inconsistent",
345 G_BINDING_INVERT_BOOLEAN | G_BINDING_SYNC_CREATE);
346
347 /* Restore */
348 g_signal_connect (restore_button,
349 "clicked",
350 G_CALLBACK (restore_button_clicked),
351 job);
352
353 return G_OBJECT (contents);
354 }
355
356 static void
custom_widget_apply_cb(GtkPrintOperation * operation,GtkWidget * widget,GeditPrintJob * job)357 custom_widget_apply_cb (GtkPrintOperation *operation,
358 GtkWidget *widget,
359 GeditPrintJob *job)
360 {
361 gboolean syntax;
362 gboolean page_header;
363 const gchar *body_font;
364 const gchar *header_font;
365 const gchar *numbers_font;
366 GtkWrapMode wrap_mode;
367
368 syntax = gtk_toggle_button_get_active (job->syntax_checkbutton);
369 page_header = gtk_toggle_button_get_active (job->page_header_checkbutton);
370 body_font = gtk_font_chooser_get_font (GTK_FONT_CHOOSER (job->body_fontbutton));
371 header_font = gtk_font_chooser_get_font (GTK_FONT_CHOOSER (job->headers_fontbutton));
372 numbers_font = gtk_font_chooser_get_font (GTK_FONT_CHOOSER (job->numbers_fontbutton));
373
374 g_settings_set_boolean (job->gsettings,
375 GEDIT_SETTINGS_PRINT_SYNTAX_HIGHLIGHTING,
376 syntax);
377
378 g_settings_set_boolean (job->gsettings,
379 GEDIT_SETTINGS_PRINT_HEADER,
380 page_header);
381
382 g_settings_set_string (job->gsettings,
383 GEDIT_SETTINGS_PRINT_FONT_BODY_PANGO,
384 body_font);
385
386 g_settings_set_string (job->gsettings,
387 GEDIT_SETTINGS_PRINT_FONT_HEADER_PANGO,
388 header_font);
389
390 g_settings_set_string (job->gsettings,
391 GEDIT_SETTINGS_PRINT_FONT_NUMBERS_PANGO,
392 numbers_font);
393
394 if (gtk_toggle_button_get_active (job->line_numbers_checkbutton))
395 {
396 gint num;
397
398 num = gtk_spin_button_get_value_as_int (job->line_numbers_spinbutton);
399
400 g_settings_set (job->gsettings,
401 GEDIT_SETTINGS_PRINT_LINE_NUMBERS,
402 "u", MAX (1, num));
403 }
404 else
405 {
406 g_settings_set (job->gsettings,
407 GEDIT_SETTINGS_PRINT_LINE_NUMBERS,
408 "u", 0);
409 }
410
411 if (gtk_toggle_button_get_active (job->text_wrapping_checkbutton))
412 {
413 if (gtk_toggle_button_get_active (job->do_not_split_checkbutton))
414 {
415 wrap_mode = GTK_WRAP_WORD;
416 }
417 else
418 {
419 wrap_mode = GTK_WRAP_CHAR;
420 }
421 }
422 else
423 {
424 wrap_mode = GTK_WRAP_NONE;
425 }
426
427 g_settings_set_enum (job->gsettings,
428 GEDIT_SETTINGS_PRINT_WRAP_MODE,
429 wrap_mode);
430 }
431
432 static void
preview_ready(GtkPrintOperationPreview * gtk_preview,GtkPrintContext * context,GeditPrintJob * job)433 preview_ready (GtkPrintOperationPreview *gtk_preview,
434 GtkPrintContext *context,
435 GeditPrintJob *job)
436 {
437 job->is_preview = TRUE;
438
439 g_signal_emit (job, signals[SHOW_PREVIEW], 0, job->preview);
440
441 g_clear_object (&job->preview);
442 }
443
444 static gboolean
preview_cb(GtkPrintOperation * op,GtkPrintOperationPreview * gtk_preview,GtkPrintContext * context,GtkWindow * parent,GeditPrintJob * job)445 preview_cb (GtkPrintOperation *op,
446 GtkPrintOperationPreview *gtk_preview,
447 GtkPrintContext *context,
448 GtkWindow *parent,
449 GeditPrintJob *job)
450 {
451 g_clear_object (&job->preview);
452 job->preview = gedit_print_preview_new (op, gtk_preview, context);
453 g_object_ref_sink (job->preview);
454
455 g_signal_connect_after (gtk_preview,
456 "ready",
457 G_CALLBACK (preview_ready),
458 job);
459
460 return TRUE;
461 }
462
463 static void
create_compositor(GeditPrintJob * job)464 create_compositor (GeditPrintJob *job)
465 {
466 GtkSourceBuffer *buf;
467 gchar *print_font_body;
468 gchar *print_font_header;
469 gchar *print_font_numbers;
470 gboolean syntax_hl;
471 GtkWrapMode wrap_mode;
472 guint print_line_numbers;
473 gboolean print_header;
474 guint tab_width;
475 gdouble margin;
476
477 buf = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (job->view)));
478
479 print_font_body = g_settings_get_string (job->gsettings,
480 GEDIT_SETTINGS_PRINT_FONT_BODY_PANGO);
481
482 print_font_header = g_settings_get_string (job->gsettings,
483 GEDIT_SETTINGS_PRINT_FONT_HEADER_PANGO);
484
485 print_font_numbers = g_settings_get_string (job->gsettings,
486 GEDIT_SETTINGS_PRINT_FONT_NUMBERS_PANGO);
487
488 g_settings_get (job->gsettings,
489 GEDIT_SETTINGS_PRINT_LINE_NUMBERS,
490 "u", &print_line_numbers);
491
492 print_header = g_settings_get_boolean (job->gsettings,
493 GEDIT_SETTINGS_PRINT_HEADER);
494
495 wrap_mode = g_settings_get_enum (job->gsettings,
496 GEDIT_SETTINGS_PRINT_WRAP_MODE);
497
498 syntax_hl = g_settings_get_boolean (job->gsettings,
499 GEDIT_SETTINGS_PRINT_SYNTAX_HIGHLIGHTING);
500
501 syntax_hl &= gtk_source_buffer_get_highlight_syntax (buf);
502
503 tab_width = gtk_source_view_get_tab_width (GTK_SOURCE_VIEW (job->view));
504
505 job->compositor = GTK_SOURCE_PRINT_COMPOSITOR (
506 g_object_new (GTK_SOURCE_TYPE_PRINT_COMPOSITOR,
507 "buffer", buf,
508 "tab-width", tab_width,
509 "highlight-syntax", syntax_hl,
510 "wrap-mode", wrap_mode,
511 "print-line-numbers", print_line_numbers,
512 "print-header", print_header,
513 "print-footer", FALSE,
514 "body-font-name", print_font_body,
515 "line-numbers-font-name", print_font_numbers,
516 "header-font-name", print_font_header,
517 NULL));
518
519 margin = g_settings_get_double (job->gsettings, GEDIT_SETTINGS_PRINT_MARGIN_LEFT);
520 gtk_source_print_compositor_set_left_margin (job->compositor, margin, GTK_UNIT_MM);
521
522 margin = g_settings_get_double (job->gsettings, GEDIT_SETTINGS_PRINT_MARGIN_TOP);
523 gtk_source_print_compositor_set_top_margin (job->compositor, margin, GTK_UNIT_MM);
524
525 margin = g_settings_get_double (job->gsettings, GEDIT_SETTINGS_PRINT_MARGIN_RIGHT);
526 gtk_source_print_compositor_set_right_margin (job->compositor, margin, GTK_UNIT_MM);
527
528 margin = g_settings_get_double (job->gsettings, GEDIT_SETTINGS_PRINT_MARGIN_BOTTOM);
529 gtk_source_print_compositor_set_bottom_margin (job->compositor, margin, GTK_UNIT_MM);
530
531 if (print_header)
532 {
533 gchar *doc_name;
534 gchar *name_to_display;
535 gchar *left;
536
537 doc_name = _gedit_document_get_uri_for_display (GEDIT_DOCUMENT (buf));
538 name_to_display = tepl_utils_str_middle_truncate (doc_name, 60);
539
540 left = g_strdup_printf (_("File: %s"), name_to_display);
541
542 gtk_source_print_compositor_set_header_format (job->compositor,
543 TRUE,
544 left,
545 NULL,
546 /* Translators: %N is the current page number, %Q is the total
547 * number of pages (ex. Page 2 of 10)
548 */
549 _("Page %N of %Q"));
550
551 g_free (doc_name);
552 g_free (name_to_display);
553 g_free (left);
554 }
555
556 g_free (print_font_body);
557 g_free (print_font_header);
558 g_free (print_font_numbers);
559 }
560
561 static void
begin_print_cb(GtkPrintOperation * operation,GtkPrintContext * context,GeditPrintJob * job)562 begin_print_cb (GtkPrintOperation *operation,
563 GtkPrintContext *context,
564 GeditPrintJob *job)
565 {
566 create_compositor (job);
567
568 job->progress = 0.0;
569
570 g_signal_emit (job,
571 signals[PRINTING],
572 0,
573 GEDIT_PRINT_JOB_STATUS_PAGINATING);
574 }
575
576 static gboolean
paginate_cb(GtkPrintOperation * operation,GtkPrintContext * context,GeditPrintJob * job)577 paginate_cb (GtkPrintOperation *operation,
578 GtkPrintContext *context,
579 GeditPrintJob *job)
580 {
581 gboolean finished;
582
583 finished = gtk_source_print_compositor_paginate (job->compositor, context);
584
585 if (finished)
586 {
587 gint n_pages;
588
589 n_pages = gtk_source_print_compositor_get_n_pages (job->compositor);
590 gtk_print_operation_set_n_pages (job->operation, n_pages);
591 }
592
593 job->progress = gtk_source_print_compositor_get_pagination_progress (job->compositor);
594
595 /* When previewing, the progress is just for pagination, when printing
596 * it's split between pagination and rendering.
597 */
598 if (!job->is_preview)
599 {
600 job->progress /= 2.0;
601 }
602
603 g_signal_emit (job,
604 signals[PRINTING],
605 0,
606 GEDIT_PRINT_JOB_STATUS_PAGINATING);
607
608 return finished;
609 }
610
611 static void
draw_page_cb(GtkPrintOperation * operation,GtkPrintContext * context,gint page_nr,GeditPrintJob * job)612 draw_page_cb (GtkPrintOperation *operation,
613 GtkPrintContext *context,
614 gint page_nr,
615 GeditPrintJob *job)
616 {
617 /* In preview, pages are drawn on the fly, so rendering is
618 * not part of the progress.
619 */
620 if (!job->is_preview)
621 {
622 gint n_pages;
623
624 n_pages = gtk_source_print_compositor_get_n_pages (job->compositor);
625
626 g_free (job->status_string);
627 job->status_string = g_strdup_printf (_("Rendering page %d of %d…"), page_nr + 1, n_pages);
628
629 job->progress = page_nr / (2.0 * n_pages) + 0.5;
630
631 g_signal_emit (job,
632 signals[PRINTING],
633 0,
634 GEDIT_PRINT_JOB_STATUS_DRAWING);
635 }
636
637 gtk_source_print_compositor_draw_page (job->compositor, context, page_nr);
638 }
639
640 static void
end_print_cb(GtkPrintOperation * operation,GtkPrintContext * context,GeditPrintJob * job)641 end_print_cb (GtkPrintOperation *operation,
642 GtkPrintContext *context,
643 GeditPrintJob *job)
644 {
645 g_clear_object (&job->compositor);
646 }
647
648 static void
done_cb(GtkPrintOperation * operation,GtkPrintOperationResult result,GeditPrintJob * job)649 done_cb (GtkPrintOperation *operation,
650 GtkPrintOperationResult result,
651 GeditPrintJob *job)
652 {
653 GError *error = NULL;
654 GeditPrintJobResult print_result;
655
656 switch (result)
657 {
658 case GTK_PRINT_OPERATION_RESULT_CANCEL:
659 print_result = GEDIT_PRINT_JOB_RESULT_CANCEL;
660 break;
661
662 case GTK_PRINT_OPERATION_RESULT_APPLY:
663 print_result = GEDIT_PRINT_JOB_RESULT_OK;
664 break;
665
666 case GTK_PRINT_OPERATION_RESULT_ERROR:
667 print_result = GEDIT_PRINT_JOB_RESULT_ERROR;
668 gtk_print_operation_get_error (operation, &error);
669 break;
670
671 default:
672 g_return_if_reached ();
673 }
674
675 /* Avoid that job is destroyed in the handler of the "done" message. */
676 g_object_ref (job);
677 g_signal_emit (job, signals[DONE], 0, print_result, error);
678 g_object_unref (job);
679 }
680
681 GeditPrintJob *
gedit_print_job_new(GeditView * view)682 gedit_print_job_new (GeditView *view)
683 {
684 g_return_val_if_fail (GEDIT_IS_VIEW (view), NULL);
685
686 return g_object_new (GEDIT_TYPE_PRINT_JOB,
687 "view", view,
688 NULL);
689 }
690
691 /* Note that gedit_print_job_print() can only be called once on a given
692 * GeditPrintJob.
693 */
694 GtkPrintOperationResult
gedit_print_job_print(GeditPrintJob * job,GtkPrintOperationAction action,GtkPageSetup * page_setup,GtkPrintSettings * settings,GtkWindow * parent,GError ** error)695 gedit_print_job_print (GeditPrintJob *job,
696 GtkPrintOperationAction action,
697 GtkPageSetup *page_setup,
698 GtkPrintSettings *settings,
699 GtkWindow *parent,
700 GError **error)
701 {
702 GeditDocument *doc;
703 gchar *job_name;
704
705 g_return_val_if_fail (job->operation == NULL, GTK_PRINT_OPERATION_RESULT_ERROR);
706 g_return_val_if_fail (job->compositor == NULL, GTK_PRINT_OPERATION_RESULT_ERROR);
707
708 job->operation = gtk_print_operation_new ();
709
710 job->is_preview = action == GTK_PRINT_OPERATION_ACTION_PREVIEW;
711
712 if (settings != NULL)
713 {
714 gtk_print_operation_set_print_settings (job->operation,
715 settings);
716 }
717
718 if (page_setup != NULL)
719 {
720 gtk_print_operation_set_default_page_setup (job->operation,
721 page_setup);
722 }
723
724 doc = GEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (job->view)));
725 job_name = gedit_document_get_short_name_for_display (doc);
726 gtk_print_operation_set_job_name (job->operation, job_name);
727 g_free (job_name);
728
729 gtk_print_operation_set_embed_page_setup (job->operation, TRUE);
730
731 gtk_print_operation_set_custom_tab_label (job->operation, _("Text Editor"));
732
733 gtk_print_operation_set_allow_async (job->operation, TRUE);
734
735 g_signal_connect (job->operation,
736 "create-custom-widget",
737 G_CALLBACK (create_custom_widget_cb),
738 job);
739
740 g_signal_connect (job->operation,
741 "custom-widget-apply",
742 G_CALLBACK (custom_widget_apply_cb),
743 job);
744
745 g_signal_connect (job->operation,
746 "preview",
747 G_CALLBACK (preview_cb),
748 job);
749
750 g_signal_connect (job->operation,
751 "begin-print",
752 G_CALLBACK (begin_print_cb),
753 job);
754
755 g_signal_connect (job->operation,
756 "paginate",
757 G_CALLBACK (paginate_cb),
758 job);
759
760 g_signal_connect (job->operation,
761 "draw-page",
762 G_CALLBACK (draw_page_cb),
763 job);
764
765 g_signal_connect_object (job->operation,
766 "end-print",
767 G_CALLBACK (end_print_cb),
768 job,
769 0);
770
771 g_signal_connect_object (job->operation,
772 "done",
773 G_CALLBACK (done_cb),
774 job,
775 0);
776
777 return gtk_print_operation_run (job->operation,
778 action,
779 parent,
780 error);
781 }
782
783 void
gedit_print_job_cancel(GeditPrintJob * job)784 gedit_print_job_cancel (GeditPrintJob *job)
785 {
786 g_return_if_fail (GEDIT_IS_PRINT_JOB (job));
787
788 gtk_print_operation_cancel (job->operation);
789 }
790
791 const gchar *
gedit_print_job_get_status_string(GeditPrintJob * job)792 gedit_print_job_get_status_string (GeditPrintJob *job)
793 {
794 g_return_val_if_fail (GEDIT_IS_PRINT_JOB (job), NULL);
795 g_return_val_if_fail (job->status_string != NULL, NULL);
796
797 return job->status_string;
798 }
799
800 gdouble
gedit_print_job_get_progress(GeditPrintJob * job)801 gedit_print_job_get_progress (GeditPrintJob *job)
802 {
803 g_return_val_if_fail (GEDIT_IS_PRINT_JOB (job), 0.0);
804
805 return job->progress;
806 }
807
808 GtkPrintSettings *
gedit_print_job_get_print_settings(GeditPrintJob * job)809 gedit_print_job_get_print_settings (GeditPrintJob *job)
810 {
811 g_return_val_if_fail (GEDIT_IS_PRINT_JOB (job), NULL);
812
813 return gtk_print_operation_get_print_settings (job->operation);
814 }
815
816 GtkPageSetup *
gedit_print_job_get_page_setup(GeditPrintJob * job)817 gedit_print_job_get_page_setup (GeditPrintJob *job)
818 {
819 g_return_val_if_fail (GEDIT_IS_PRINT_JOB (job), NULL);
820
821 return gtk_print_operation_get_default_page_setup (job->operation);
822 }
823
824 /* ex:set ts=8 noet: */
825