1 /*
2 * pluma-print-preview.c
3 *
4 * Copyright (C) 2008 Paolo Borelli
5 * Copyright (C) 2012-2021 MATE Developers
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 */
22
23 /*
24 * Modified by the pluma Team, 1998-2006. See the AUTHORS file for a
25 * list of people on the pluma Team.
26 * See the ChangeLog files for a list of changes.
27 *
28 * $Id: pluma-commands-search.c 5931 2007-09-25 20:05:40Z pborelli $
29 */
30
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34
35 #include <math.h>
36 #include <stdlib.h>
37 #include <glib/gi18n.h>
38 #include <gtk/gtk.h>
39 #include <gdk/gdkkeysyms.h>
40 #include <cairo-pdf.h>
41
42 #include "pluma-print-preview.h"
43
44 #define PRINTER_DPI (72.)
45
46 struct _PlumaPrintPreviewPrivate
47 {
48 GtkPrintOperation *operation;
49 GtkPrintContext *context;
50 GtkPrintOperationPreview *gtk_preview;
51
52 GtkWidget *layout;
53 GtkWidget *scrolled_window;
54
55 GtkToolItem *next;
56 GtkToolItem *prev;
57 GtkWidget *page_entry;
58 GtkWidget *last;
59 GtkToolItem *multi;
60 GtkToolItem *zoom_one;
61 GtkToolItem *zoom_fit;
62 GtkToolItem *zoom_in;
63 GtkToolItem *zoom_out;
64
65 /* real size of the page in inches */
66 double paper_w;
67 double paper_h;
68 double dpi;
69
70 double scale;
71
72 /* size of the tile of a page (including padding
73 * and drop shadow) in pixels */
74 gint tile_w;
75 gint tile_h;
76
77 GtkPageOrientation orientation;
78
79 /* multipage support */
80 gint rows;
81 gint cols;
82
83 guint n_pages;
84 guint cur_page;
85 };
86
G_DEFINE_TYPE_WITH_PRIVATE(PlumaPrintPreview,pluma_print_preview,GTK_TYPE_BOX)87 G_DEFINE_TYPE_WITH_PRIVATE (PlumaPrintPreview, pluma_print_preview, GTK_TYPE_BOX)
88
89 static void
90 pluma_print_preview_get_property (GObject *object,
91 guint prop_id,
92 GValue *value,
93 GParamSpec *pspec)
94 {
95 //PlumaPrintPreview *preview = PLUMA_PRINT_PREVIEW (object);
96
97 switch (prop_id)
98 {
99 default:
100 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
101 break;
102 }
103 }
104
105 static void
pluma_print_preview_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)106 pluma_print_preview_set_property (GObject *object,
107 guint prop_id,
108 const GValue *value,
109 GParamSpec *pspec)
110 {
111 //PlumaPrintPreview *preview = PLUMA_PRINT_PREVIEW (object);
112
113 switch (prop_id)
114 {
115 default:
116 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
117 break;
118 }
119 }
120
121 static void
pluma_print_preview_finalize(GObject * object)122 pluma_print_preview_finalize (GObject *object)
123 {
124 //PlumaPrintPreview *preview = PLUMA_PRINT_PREVIEW (object);
125
126 G_OBJECT_CLASS (pluma_print_preview_parent_class)->finalize (object);
127 }
128
129 static void
pluma_print_preview_grab_focus(GtkWidget * widget)130 pluma_print_preview_grab_focus (GtkWidget *widget)
131 {
132 PlumaPrintPreview *preview;
133
134 preview = PLUMA_PRINT_PREVIEW (widget);
135
136 gtk_widget_grab_focus (GTK_WIDGET (preview->priv->layout));
137 }
138
139 static void
pluma_print_preview_class_init(PlumaPrintPreviewClass * klass)140 pluma_print_preview_class_init (PlumaPrintPreviewClass *klass)
141 {
142 GObjectClass *object_class;
143 GtkWidgetClass *widget_class;
144
145 object_class = G_OBJECT_CLASS (klass);
146 widget_class = GTK_WIDGET_CLASS (klass);
147
148 object_class->get_property = pluma_print_preview_get_property;
149 object_class->set_property = pluma_print_preview_set_property;
150 object_class->finalize = pluma_print_preview_finalize;
151
152 widget_class->grab_focus = pluma_print_preview_grab_focus;
153 }
154
155 static void
update_layout_size(PlumaPrintPreview * preview)156 update_layout_size (PlumaPrintPreview *preview)
157 {
158 PlumaPrintPreviewPrivate *priv;
159
160 priv = preview->priv;
161
162 /* force size of the drawing area to make the scrolled window work */
163 gtk_layout_set_size (GTK_LAYOUT (priv->layout),
164 priv->tile_w * priv->cols,
165 priv->tile_h * priv->rows);
166
167 gtk_widget_queue_draw (preview->priv->layout);
168 }
169
170 static void
set_rows_and_cols(PlumaPrintPreview * preview,gint rows,gint cols)171 set_rows_and_cols (PlumaPrintPreview *preview,
172 gint rows,
173 gint cols)
174 {
175 /* TODO: set the zoom appropriately */
176
177 preview->priv->rows = rows;
178 preview->priv->cols = cols;
179 update_layout_size (preview);
180 }
181
182 /* get the paper size in points: these must be used only
183 * after the widget has been mapped and the dpi is known */
184
185 static double
get_paper_width(PlumaPrintPreview * preview)186 get_paper_width (PlumaPrintPreview *preview)
187 {
188 return preview->priv->paper_w * preview->priv->dpi;
189 }
190
191 static double
get_paper_height(PlumaPrintPreview * preview)192 get_paper_height (PlumaPrintPreview *preview)
193 {
194 return preview->priv->paper_h * preview->priv->dpi;
195 }
196
197 #define PAGE_PAD 12
198 #define PAGE_SHADOW_OFFSET 5
199
200 /* The tile size is the size of the area where a page
201 * will be drawn including the padding and idependent
202 * of the orientation */
203
204 /* updates the tile size to the current zoom and page size */
205 static void
update_tile_size(PlumaPrintPreview * preview)206 update_tile_size (PlumaPrintPreview *preview)
207 {
208 PlumaPrintPreviewPrivate *priv;
209 gint w, h;
210
211 priv = preview->priv;
212
213 w = 2 * PAGE_PAD + floor (priv->scale * get_paper_width (preview) + 0.5);
214 h = 2 * PAGE_PAD + floor (priv->scale * get_paper_height (preview) + 0.5);
215
216 if ((priv->orientation == GTK_PAGE_ORIENTATION_LANDSCAPE) ||
217 (priv->orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE))
218 {
219 priv->tile_w = h;
220 priv->tile_h = w;
221 }
222 else
223 {
224 priv->tile_w = w;
225 priv->tile_h = h;
226 }
227 }
228
229 /* Zoom should always be set with one of these two function
230 * so that the tile size is properly updated */
231
232 static void
set_zoom_factor(PlumaPrintPreview * preview,double zoom)233 set_zoom_factor (PlumaPrintPreview *preview,
234 double zoom)
235 {
236 PlumaPrintPreviewPrivate *priv;
237
238 priv = preview->priv;
239
240 priv->scale = zoom;
241
242 update_tile_size (preview);
243 update_layout_size (preview);
244 }
245
246 static void
set_zoom_fit_to_size(PlumaPrintPreview * preview)247 set_zoom_fit_to_size (PlumaPrintPreview *preview)
248 {
249 PlumaPrintPreviewPrivate *priv;
250 double width, height;
251 double p_width, p_height;
252 double zoomx, zoomy;
253
254 priv = preview->priv;
255
256 g_object_get (gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (priv->layout)),
257 "page-size", &width,
258 NULL);
259 g_object_get (gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (priv->layout)),
260 "page-size", &height,
261 NULL);
262
263 width /= priv->cols;
264 height /= priv->rows;
265
266 if ((priv->orientation == GTK_PAGE_ORIENTATION_LANDSCAPE) ||
267 (priv->orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE))
268 {
269 p_width = get_paper_height (preview);
270 p_height = get_paper_width (preview);
271 }
272 else
273 {
274 p_width = get_paper_width (preview);
275 p_height = get_paper_height (preview);
276 }
277
278 zoomx = MAX (1, width - 2 * PAGE_PAD) / p_width;
279 zoomy = MAX (1, height - 2 * PAGE_PAD) / p_height;
280
281 if (zoomx <= zoomy)
282 {
283 priv->tile_w = width;
284 priv->tile_h = floor (0.5 + width * (p_height / p_width));
285 priv->scale = zoomx;
286 }
287 else
288 {
289 priv->tile_w = floor (0.5 + height * (p_width / p_height));
290 priv->tile_h = height;
291 priv->scale = zoomy;
292 }
293
294 update_layout_size (preview);
295 }
296
297 #define ZOOM_IN_FACTOR (1.2)
298 #define ZOOM_OUT_FACTOR (1.0 / ZOOM_IN_FACTOR)
299
300 static void
zoom_in(PlumaPrintPreview * preview)301 zoom_in (PlumaPrintPreview *preview)
302 {
303 set_zoom_factor (preview,
304 preview->priv->scale * ZOOM_IN_FACTOR);
305 }
306
307 static void
zoom_out(PlumaPrintPreview * preview)308 zoom_out (PlumaPrintPreview *preview)
309 {
310 set_zoom_factor (preview,
311 preview->priv->scale * ZOOM_OUT_FACTOR);
312 }
313
314 static void
goto_page(PlumaPrintPreview * preview,gint page)315 goto_page (PlumaPrintPreview *preview, gint page)
316 {
317 gchar c[32];
318
319 g_snprintf (c, 32, "%d", page + 1);
320 gtk_entry_set_text (GTK_ENTRY (preview->priv->page_entry), c);
321
322 gtk_widget_set_sensitive (GTK_WIDGET (preview->priv->prev),
323 (page > 0) && (preview->priv->n_pages > 1));
324 gtk_widget_set_sensitive (GTK_WIDGET (preview->priv->next),
325 (page != (preview->priv->n_pages - 1)) &&
326 (preview->priv->n_pages > 1));
327
328 if (page != preview->priv->cur_page)
329 {
330 preview->priv->cur_page = page;
331 if (preview->priv->n_pages > 0)
332 gtk_widget_queue_draw (preview->priv->layout);
333 }
334 }
335
336 static void
prev_button_clicked(GtkWidget * button,PlumaPrintPreview * preview)337 prev_button_clicked (GtkWidget *button,
338 PlumaPrintPreview *preview)
339 {
340 GdkEvent *event;
341 gint page;
342
343 event = gtk_get_current_event ();
344
345 if (event->button.state & GDK_SHIFT_MASK)
346 page = 0;
347 else
348 page = preview->priv->cur_page - preview->priv->rows * preview->priv->cols;
349
350 goto_page (preview, MAX (page, 0));
351
352 gdk_event_free (event);
353 }
354
355 static void
next_button_clicked(GtkWidget * button,PlumaPrintPreview * preview)356 next_button_clicked (GtkWidget *button,
357 PlumaPrintPreview *preview)
358 {
359 GdkEvent *event;
360 gint page;
361
362 event = gtk_get_current_event ();
363
364 if (event->button.state & GDK_SHIFT_MASK)
365 page = preview->priv->n_pages - 1;
366 else
367 page = preview->priv->cur_page + preview->priv->rows * preview->priv->cols;
368
369 goto_page (preview, MIN (page, preview->priv->n_pages - 1));
370
371 gdk_event_free (event);
372 }
373
374 static void
page_entry_activated(GtkEntry * entry,PlumaPrintPreview * preview)375 page_entry_activated (GtkEntry *entry,
376 PlumaPrintPreview *preview)
377 {
378 const gchar *text;
379 gint page;
380
381 text = gtk_entry_get_text (entry);
382
383 page = CLAMP (atoi (text), 1, preview->priv->n_pages) - 1;
384 goto_page (preview, page);
385
386 gtk_widget_grab_focus (GTK_WIDGET (preview->priv->layout));
387 }
388
389 static void
page_entry_insert_text(GtkEditable * editable,const gchar * text,gint length,gint * position)390 page_entry_insert_text (GtkEditable *editable,
391 const gchar *text,
392 gint length,
393 gint *position)
394 {
395 gunichar c;
396 const gchar *p;
397 const gchar *end;
398
399 p = text;
400 end = text + length;
401
402 while (p != end)
403 {
404 const gchar *next;
405 next = g_utf8_next_char (p);
406
407 c = g_utf8_get_char (p);
408
409 if (!g_unichar_isdigit (c))
410 {
411 g_signal_stop_emission_by_name (editable, "insert-text");
412 break;
413 }
414
415 p = next;
416 }
417 }
418
419 static gboolean
page_entry_focus_out(GtkWidget * widget,GdkEventFocus * event,PlumaPrintPreview * preview)420 page_entry_focus_out (GtkWidget *widget,
421 GdkEventFocus *event,
422 PlumaPrintPreview *preview)
423 {
424 const gchar *text;
425 gint page;
426
427 text = gtk_entry_get_text (GTK_ENTRY (widget));
428 page = atoi (text) - 1;
429
430 /* Reset the page number only if really needed */
431 if (page != preview->priv->cur_page)
432 {
433 gchar *str;
434
435 str = g_strdup_printf ("%d", preview->priv->cur_page + 1);
436 gtk_entry_set_text (GTK_ENTRY (widget), str);
437 g_free (str);
438 }
439
440 return FALSE;
441 }
442
443 static void
on_1x1_clicked(GtkMenuItem * i,PlumaPrintPreview * preview)444 on_1x1_clicked (GtkMenuItem *i, PlumaPrintPreview *preview)
445 {
446 set_rows_and_cols (preview, 1, 1);
447 }
448
449 static void
on_1x2_clicked(GtkMenuItem * i,PlumaPrintPreview * preview)450 on_1x2_clicked (GtkMenuItem *i, PlumaPrintPreview *preview)
451 {
452 set_rows_and_cols (preview, 1, 2);
453 }
454
455 static void
on_2x1_clicked(GtkMenuItem * i,PlumaPrintPreview * preview)456 on_2x1_clicked (GtkMenuItem *i, PlumaPrintPreview *preview)
457 {
458 set_rows_and_cols (preview, 2, 1);
459 }
460
461 static void
on_2x2_clicked(GtkMenuItem * i,PlumaPrintPreview * preview)462 on_2x2_clicked (GtkMenuItem *i, PlumaPrintPreview *preview)
463 {
464 set_rows_and_cols (preview, 2, 2);
465 }
466
467 static void
multi_button_clicked(GtkWidget * button,PlumaPrintPreview * preview)468 multi_button_clicked (GtkWidget *button,
469 PlumaPrintPreview *preview)
470 {
471 GtkWidget *m, *i;
472
473 m = gtk_menu_new ();
474 gtk_widget_show (m);
475 g_signal_connect (m,
476 "selection_done",
477 G_CALLBACK (gtk_widget_destroy),
478 m);
479
480 i = gtk_menu_item_new_with_label ("1x1");
481 gtk_widget_show (i);
482 gtk_menu_attach (GTK_MENU (m), i, 0, 1, 0, 1);
483 g_signal_connect (i, "activate", G_CALLBACK (on_1x1_clicked), preview);
484
485 i = gtk_menu_item_new_with_label ("2x1");
486 gtk_widget_show (i);
487 gtk_menu_attach (GTK_MENU (m), i, 0, 1, 1, 2);
488 g_signal_connect (i, "activate", G_CALLBACK (on_2x1_clicked), preview);
489
490 i = gtk_menu_item_new_with_label ("1x2");
491 gtk_widget_show (i);
492 gtk_menu_attach (GTK_MENU (m), i, 1, 2, 0, 1);
493 g_signal_connect (i, "activate", G_CALLBACK (on_1x2_clicked), preview);
494
495 i = gtk_menu_item_new_with_label ("2x2");
496 gtk_widget_show (i);
497 gtk_menu_attach (GTK_MENU (m), i, 1, 2, 1, 2);
498 g_signal_connect (i, "activate", G_CALLBACK (on_2x2_clicked), preview);
499
500 gtk_menu_popup_at_pointer (GTK_MENU (m), NULL);
501 }
502
503 static void
zoom_one_button_clicked(GtkWidget * button,PlumaPrintPreview * preview)504 zoom_one_button_clicked (GtkWidget *button,
505 PlumaPrintPreview *preview)
506 {
507 set_zoom_factor (preview, 1);
508 }
509
510 static void
zoom_fit_button_clicked(GtkWidget * button,PlumaPrintPreview * preview)511 zoom_fit_button_clicked (GtkWidget *button,
512 PlumaPrintPreview *preview)
513 {
514 set_zoom_fit_to_size (preview);
515 }
516
517 static void
zoom_in_button_clicked(GtkWidget * button,PlumaPrintPreview * preview)518 zoom_in_button_clicked (GtkWidget *button,
519 PlumaPrintPreview *preview)
520 {
521 zoom_in (preview);
522 }
523
524 static void
zoom_out_button_clicked(GtkWidget * button,PlumaPrintPreview * preview)525 zoom_out_button_clicked (GtkWidget *button,
526 PlumaPrintPreview *preview)
527 {
528 zoom_out (preview);
529 }
530
531 static void
close_button_clicked(GtkWidget * button,PlumaPrintPreview * preview)532 close_button_clicked (GtkWidget *button,
533 PlumaPrintPreview *preview)
534 {
535 gtk_widget_destroy (GTK_WIDGET (preview));
536 }
537
538 static gboolean
ignore_mouse_buttons(GtkWidget * widget,GdkEventKey * event,PlumaPrintPreview * preview)539 ignore_mouse_buttons (GtkWidget *widget,
540 GdkEventKey *event,
541 PlumaPrintPreview *preview)
542 {
543 return TRUE;
544 }
545
546 static void
create_bar(PlumaPrintPreview * preview)547 create_bar (PlumaPrintPreview *preview)
548 {
549 PlumaPrintPreviewPrivate *priv;
550 GtkWidget *toolbar;
551 GtkToolItem *i;
552 AtkObject *atko;
553 GtkWidget *status;
554
555 priv = preview->priv;
556
557 toolbar = gtk_toolbar_new ();
558 gtk_toolbar_set_style (GTK_TOOLBAR (toolbar),
559 GTK_TOOLBAR_BOTH_HORIZ);
560 gtk_widget_show (toolbar);
561 gtk_box_pack_start (GTK_BOX (preview),
562 toolbar,
563 FALSE, FALSE, 0);
564
565 priv->prev = gtk_tool_button_new (NULL, NULL);
566 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (priv->prev), "go-previous");
567 gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->prev),
568 "P_revious Page");
569 gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (priv->prev), TRUE);
570 gtk_tool_item_set_tooltip_text (priv->prev, _("Show the previous page"));
571 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->prev, -1);
572 g_signal_connect (priv->prev,
573 "clicked",
574 G_CALLBACK (prev_button_clicked),
575 preview);
576 gtk_widget_show (GTK_WIDGET (priv->prev));
577
578 priv->next = gtk_tool_button_new (NULL, NULL);
579 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (priv->next), "go-next");
580 gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->next),
581 "_Next Page");
582 gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (priv->next), TRUE);
583 gtk_tool_item_set_tooltip_text (priv->next, _("Show the next page"));
584 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->next, -1);
585 g_signal_connect (priv->next,
586 "clicked",
587 G_CALLBACK (next_button_clicked),
588 preview);
589 gtk_widget_show (GTK_WIDGET (priv->next));
590
591 i = gtk_separator_tool_item_new ();
592 gtk_widget_show (GTK_WIDGET (i));
593 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1);
594
595 status = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
596 priv->page_entry = gtk_entry_new ();
597 gtk_entry_set_width_chars (GTK_ENTRY (priv->page_entry), 3);
598 gtk_entry_set_max_length (GTK_ENTRY (priv->page_entry), 6);
599 gtk_widget_set_tooltip_text (priv->page_entry, _("Current page (Alt+P)"));
600
601 g_signal_connect (priv->page_entry,
602 "activate",
603 G_CALLBACK (page_entry_activated),
604 preview);
605 g_signal_connect (priv->page_entry,
606 "insert-text",
607 G_CALLBACK (page_entry_insert_text),
608 NULL);
609 g_signal_connect (priv->page_entry,
610 "focus-out-event",
611 G_CALLBACK (page_entry_focus_out),
612 preview);
613
614 gtk_box_pack_start (GTK_BOX (status),
615 priv->page_entry,
616 FALSE, FALSE, 0);
617 /* gtk_label_set_mnemonic_widget ((GtkLabel *) l, mp->priv->page_entry); */
618
619 /* We are displaying 'XXX of XXX'. */
620 gtk_box_pack_start (GTK_BOX (status),
621 /* Translators: the "of" from "1 of 19" in print preview. */
622 gtk_label_new (_("of")),
623 FALSE, FALSE, 0);
624
625 priv->last = gtk_label_new ("");
626 gtk_box_pack_start (GTK_BOX (status),
627 priv->last,
628 FALSE, FALSE, 0);
629 atko = gtk_widget_get_accessible (priv->last);
630 atk_object_set_name (atko, _("Page total"));
631 atk_object_set_description (atko, _("The total number of pages in the document"));
632
633 gtk_widget_show_all (status);
634
635 i = gtk_tool_item_new ();
636 gtk_container_add (GTK_CONTAINER (i), status);
637 gtk_widget_show (GTK_WIDGET (i));
638 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1);
639
640 i = gtk_separator_tool_item_new ();
641 gtk_widget_show (GTK_WIDGET (i));
642 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1);
643
644 priv->multi = gtk_tool_button_new (NULL, NULL);
645 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (priv->multi), "dnd-multiple");
646 gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->multi),
647 "_Show Multiple Pages");
648 gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (priv->multi), TRUE);
649 gtk_tool_item_set_tooltip_text (priv->multi, _("Show multiple pages"));
650 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->multi, -1);
651 g_signal_connect (priv->multi,
652 "clicked",
653 G_CALLBACK (multi_button_clicked),
654 preview);
655 gtk_widget_show (GTK_WIDGET (priv->multi));
656
657 i = gtk_separator_tool_item_new ();
658 gtk_widget_show (GTK_WIDGET (i));
659 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1);
660
661 priv->zoom_one = gtk_tool_button_new (NULL, NULL);
662 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (priv->zoom_one), "zoom-original");
663 gtk_tool_item_set_tooltip_text (priv->zoom_one, _("Zoom 1:1"));
664 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->zoom_one, -1);
665 g_signal_connect (priv->zoom_one,
666 "clicked",
667 G_CALLBACK (zoom_one_button_clicked),
668 preview);
669 gtk_widget_show (GTK_WIDGET (priv->zoom_one));
670
671 priv->zoom_fit = gtk_tool_button_new (NULL, NULL);
672 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (priv->zoom_fit), "zoom-fit-best");
673 gtk_tool_item_set_tooltip_text (priv->zoom_fit, _("Zoom to fit the whole page"));
674 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->zoom_fit, -1);
675 g_signal_connect (priv->zoom_fit,
676 "clicked",
677 G_CALLBACK (zoom_fit_button_clicked),
678 preview);
679 gtk_widget_show (GTK_WIDGET (priv->zoom_fit));
680
681 priv->zoom_in = gtk_tool_button_new (NULL, NULL);
682 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (priv->zoom_in), "zoom-in");
683 gtk_tool_item_set_tooltip_text (priv->zoom_in, _("Zoom the page in"));
684 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->zoom_in, -1);
685 g_signal_connect (priv->zoom_in,
686 "clicked",
687 G_CALLBACK (zoom_in_button_clicked),
688 preview);
689 gtk_widget_show (GTK_WIDGET (priv->zoom_in));
690
691 priv->zoom_out = gtk_tool_button_new (NULL, NULL);
692 gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (priv->zoom_out), "zoom-out");
693 gtk_tool_item_set_tooltip_text (priv->zoom_out, _("Zoom the page out"));
694 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->zoom_out, -1);
695 g_signal_connect (priv->zoom_out,
696 "clicked",
697 G_CALLBACK (zoom_out_button_clicked),
698 preview);
699 gtk_widget_show (GTK_WIDGET (priv->zoom_out));
700
701 i = gtk_separator_tool_item_new ();
702 gtk_widget_show (GTK_WIDGET (i));
703 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1);
704
705 i = gtk_tool_button_new (NULL, _("_Close Preview"));
706 gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (i), TRUE);
707 gtk_tool_item_set_is_important (i, TRUE);
708 gtk_tool_item_set_tooltip_text (i, _("Close print preview"));
709 g_signal_connect (i, "clicked",
710 G_CALLBACK (close_button_clicked), preview);
711 gtk_widget_show (GTK_WIDGET (i));
712 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1);
713
714 g_signal_connect (GTK_TOOLBAR (toolbar),
715 "button-press-event",
716 G_CALLBACK (ignore_mouse_buttons),
717 preview);
718 }
719
720 static gint
get_first_page_displayed(PlumaPrintPreview * preview)721 get_first_page_displayed (PlumaPrintPreview *preview)
722 {
723 PlumaPrintPreviewPrivate *priv;
724
725 priv = preview->priv;
726
727 return priv->cur_page - priv->cur_page % (priv->cols * priv->rows);
728 }
729
730 /* returns the page number (starting from 0) or -1 if no page */
731 static gint
get_page_at_coords(PlumaPrintPreview * preview,gint x,gint y)732 get_page_at_coords (PlumaPrintPreview *preview,
733 gint x,
734 gint y)
735 {
736 PlumaPrintPreviewPrivate *priv;
737 GtkAdjustment *hadj, *vadj;
738 gint r, c, pg;
739
740 priv = preview->priv;
741
742 if (priv->tile_h <= 0 || priv->tile_w <= 0)
743 return -1;
744
745 hadj = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (priv->layout));
746 vadj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (priv->layout));
747
748 x += gtk_adjustment_get_value (hadj);
749 y += gtk_adjustment_get_value (vadj);
750
751 r = 1 + y / (priv->tile_h);
752 c = 1 + x / (priv->tile_w);
753
754 if (c > priv->cols)
755 return -1;
756
757 pg = get_first_page_displayed (preview) - 1;
758 pg += (r - 1) * priv->cols + c;
759
760 if (pg >= priv->n_pages)
761 return -1;
762
763 /* FIXME: we could try to be picky and check
764 * if we actually are inside the page */
765 return pg;
766 }
767
768 static gboolean
preview_layout_query_tooltip(GtkWidget * widget,gint x,gint y,gboolean keyboard_tip,GtkTooltip * tooltip,PlumaPrintPreview * preview)769 preview_layout_query_tooltip (GtkWidget *widget,
770 gint x,
771 gint y,
772 gboolean keyboard_tip,
773 GtkTooltip *tooltip,
774 PlumaPrintPreview *preview)
775 {
776 gint pg;
777 gchar *tip;
778
779 pg = get_page_at_coords (preview, x, y);
780 if (pg < 0)
781 return FALSE;
782
783 tip = g_strdup_printf (_("Page %d of %d"), pg + 1, preview->priv->n_pages);
784 gtk_tooltip_set_text (tooltip, tip);
785 g_free (tip);
786
787 return TRUE;
788 }
789
790 static gint
preview_layout_key_press(GtkWidget * widget,GdkEventKey * event,PlumaPrintPreview * preview)791 preview_layout_key_press (GtkWidget *widget,
792 GdkEventKey *event,
793 PlumaPrintPreview *preview)
794 {
795 PlumaPrintPreviewPrivate *priv;
796 GtkAdjustment *hadj, *vadj;
797 double x, y;
798 guint h, w;
799 double hlower, hupper, vlower, vupper;
800 double hpage, vpage;
801 double hstep, vstep;
802 gboolean domove = FALSE;
803 gboolean ret = TRUE;
804
805 priv = preview->priv;
806
807 hadj = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (priv->layout));
808 vadj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (priv->layout));
809
810 x = gtk_adjustment_get_value (hadj);
811 y = gtk_adjustment_get_value (vadj);
812
813 g_object_get (hadj,
814 "lower", &hlower,
815 "upper", &hupper,
816 "page-size", &hpage,
817 NULL);
818 g_object_get (vadj,
819 "lower", &vlower,
820 "upper", &vupper,
821 "page-size", &vpage,
822 NULL);
823
824 gtk_layout_get_size (GTK_LAYOUT (priv->layout), &w, &h);
825
826 hstep = 10;
827 vstep = 10;
828
829 switch (event->keyval) {
830 case '1':
831 set_zoom_fit_to_size (preview);
832 break;
833 case '+':
834 case '=':
835 case GDK_KEY_KP_Add:
836 zoom_in (preview);
837 break;
838 case '-':
839 case '_':
840 case GDK_KEY_KP_Subtract:
841 zoom_out (preview);
842 break;
843 case GDK_KEY_KP_Right:
844 case GDK_KEY_Right:
845 if (event->state & GDK_SHIFT_MASK)
846 x = hupper - hpage;
847 else
848 x = MIN (hupper - hpage, x + hstep);
849 domove = TRUE;
850 break;
851 case GDK_KEY_KP_Left:
852 case GDK_KEY_Left:
853 if (event->state & GDK_SHIFT_MASK)
854 x = hlower;
855 else
856 x = MAX (hlower, x - hstep);
857 domove = TRUE;
858 break;
859 case GDK_KEY_KP_Up:
860 case GDK_KEY_Up:
861 if (event->state & GDK_SHIFT_MASK)
862 goto page_up;
863 y = MAX (vlower, y - vstep);
864 domove = TRUE;
865 break;
866 case GDK_KEY_KP_Down:
867 case GDK_KEY_Down:
868 if (event->state & GDK_SHIFT_MASK)
869 goto page_down;
870 y = MIN (vupper - vpage, y + vstep);
871 domove = TRUE;
872 break;
873 case GDK_KEY_KP_Page_Up:
874 case GDK_KEY_Page_Up:
875 case GDK_KEY_Delete:
876 case GDK_KEY_KP_Delete:
877 case GDK_KEY_BackSpace:
878 page_up:
879 if (y <= vlower)
880 {
881 if (preview->priv->cur_page > 0)
882 {
883 goto_page (preview, preview->priv->cur_page - 1);
884 y = (vupper - vpage);
885 }
886 }
887 else
888 {
889 y = vlower;
890 }
891 domove = TRUE;
892 break;
893 case GDK_KEY_KP_Page_Down:
894 case GDK_KEY_Page_Down:
895 case ' ':
896 page_down:
897 if (y >= (vupper - vpage))
898 {
899 if (preview->priv->cur_page < preview->priv->n_pages - 1)
900 {
901 goto_page (preview, preview->priv->cur_page + 1);
902 y = vlower;
903 }
904 }
905 else
906 {
907 y = (vupper - vpage);
908 }
909 domove = TRUE;
910 break;
911 case GDK_KEY_KP_Home:
912 case GDK_KEY_Home:
913 goto_page (preview, 0);
914 y = 0;
915 domove = TRUE;
916 break;
917 case GDK_KEY_KP_End:
918 case GDK_KEY_End:
919 goto_page (preview, preview->priv->n_pages - 1);
920 y = 0;
921 domove = TRUE;
922 break;
923 case GDK_KEY_Escape:
924 gtk_widget_destroy (GTK_WIDGET (preview));
925 break;
926 case 'c':
927 if (event->state & GDK_MOD1_MASK)
928 {
929 gtk_widget_destroy (GTK_WIDGET (preview));
930 }
931 break;
932 case 'p':
933 if (event->state & GDK_MOD1_MASK)
934 {
935 gtk_widget_grab_focus (preview->priv->page_entry);
936 }
937 break;
938 default:
939 /* by default do not stop the default handler */
940 ret = FALSE;
941 }
942
943 if (domove)
944 {
945 gtk_adjustment_set_value (hadj, x);
946 gtk_adjustment_set_value (vadj, y);
947 }
948
949 return ret;
950 }
951
952 static void
create_preview_layout(PlumaPrintPreview * preview)953 create_preview_layout (PlumaPrintPreview *preview)
954 {
955 PlumaPrintPreviewPrivate *priv;
956 AtkObject *atko;
957
958 priv = preview->priv;
959
960 priv->layout = gtk_layout_new (NULL, NULL);
961 // gtk_widget_set_double_buffered (priv->layout, FALSE);
962
963 atko = gtk_widget_get_accessible (GTK_WIDGET (priv->layout));
964 atk_object_set_name (atko, _("Page Preview"));
965 atk_object_set_description (atko, _("The preview of a page in the document to be printed"));
966
967 gtk_widget_add_events (priv->layout,
968 GDK_POINTER_MOTION_MASK |
969 GDK_BUTTON_PRESS_MASK |
970 GDK_KEY_PRESS_MASK);
971
972 gtk_widget_set_can_focus (priv->layout, TRUE);
973
974 g_signal_connect (priv->layout,
975 "key-press-event",
976 G_CALLBACK (preview_layout_key_press),
977 preview);
978
979 g_object_set (priv->layout, "has-tooltip", TRUE, NULL);
980 g_signal_connect (priv->layout,
981 "query-tooltip",
982 G_CALLBACK (preview_layout_query_tooltip),
983 preview);
984
985 g_signal_connect (priv->layout,
986 "button-press-event",
987 G_CALLBACK (ignore_mouse_buttons),
988 preview);
989
990 priv->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
991 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scrolled_window),
992 GTK_POLICY_AUTOMATIC,
993 GTK_POLICY_AUTOMATIC);
994
995 gtk_container_add (GTK_CONTAINER (priv->scrolled_window), priv->layout);
996 gtk_box_pack_end (GTK_BOX (preview),
997 priv->scrolled_window,
998 TRUE, TRUE, 0);
999
1000 gtk_widget_show_all (GTK_WIDGET (priv->scrolled_window));
1001 gtk_widget_grab_focus (GTK_WIDGET (priv->layout));
1002 }
1003
1004 static void
pluma_print_preview_init(PlumaPrintPreview * preview)1005 pluma_print_preview_init (PlumaPrintPreview *preview)
1006 {
1007 PlumaPrintPreviewPrivate *priv;
1008
1009 priv = pluma_print_preview_get_instance_private (preview);
1010
1011 preview->priv = priv;
1012
1013 priv->operation = NULL;
1014 priv->context = NULL;
1015 priv->gtk_preview = NULL;
1016
1017 GtkStyleContext *context;
1018
1019 context = gtk_widget_get_style_context (GTK_WIDGET (preview));
1020 gtk_style_context_add_class (context, "pluma-print-preview");
1021 gtk_orientable_set_orientation (GTK_ORIENTABLE (preview),
1022 GTK_ORIENTATION_VERTICAL);
1023
1024 create_bar (preview);
1025 create_preview_layout (preview);
1026
1027 // FIXME
1028 priv->cur_page = 0;
1029 priv->paper_w = 0;
1030 priv->paper_h = 0;
1031 priv->dpi = PRINTER_DPI;
1032 priv->scale = 1.0;
1033 priv->rows = 1;
1034 priv->cols = 1;
1035 }
1036
1037 static void
draw_page_content(cairo_t * cr,gint page_number,PlumaPrintPreview * preview)1038 draw_page_content (cairo_t *cr,
1039 gint page_number,
1040 PlumaPrintPreview *preview)
1041 {
1042 /* scale to the desired size */
1043 cairo_scale (cr, preview->priv->scale, preview->priv->scale);
1044
1045 /* rotate acording to page orientation if needed */
1046 if ((preview->priv->orientation == GTK_PAGE_ORIENTATION_LANDSCAPE) ||
1047 (preview->priv->orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE))
1048 {
1049 cairo_matrix_t matrix;
1050
1051 cairo_matrix_init (&matrix,
1052 0, -1,
1053 1, 0,
1054 0, get_paper_width (preview));
1055 cairo_transform (cr, &matrix);
1056 }
1057
1058 gtk_print_context_set_cairo_context (preview->priv->context,
1059 cr,
1060 preview->priv->dpi,
1061 preview->priv->dpi);
1062
1063 gtk_print_operation_preview_render_page (preview->priv->gtk_preview,
1064 page_number);
1065 }
1066
1067 /* For the frame, we scale and rotate manually, since
1068 * the line width should not depend on the zoom and
1069 * the drop shadow should be on the bottom right no matter
1070 * the orientation */
1071 static void
draw_page_frame(cairo_t * cr,PlumaPrintPreview * preview)1072 draw_page_frame (cairo_t *cr,
1073 PlumaPrintPreview *preview)
1074 {
1075 double w, h;
1076
1077 w = get_paper_width (preview);
1078 h = get_paper_height (preview);
1079
1080 if ((preview->priv->orientation == GTK_PAGE_ORIENTATION_LANDSCAPE) ||
1081 (preview->priv->orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE))
1082 {
1083 double tmp;
1084
1085 tmp = w;
1086 w = h;
1087 h = tmp;
1088 }
1089
1090 w *= preview->priv->scale;
1091 h *= preview->priv->scale;
1092
1093 /* drop shadow */
1094 cairo_set_source_rgb (cr, 0, 0, 0);
1095 cairo_rectangle (cr,
1096 PAGE_SHADOW_OFFSET, PAGE_SHADOW_OFFSET,
1097 w, h);
1098 cairo_fill (cr);
1099
1100 /* page frame */
1101 cairo_set_source_rgb (cr, 1, 1, 1);
1102 cairo_rectangle (cr,
1103 0, 0,
1104 w, h);
1105 cairo_fill_preserve (cr);
1106 cairo_set_source_rgb (cr, 0, 0, 0);
1107 cairo_set_line_width (cr, 1);
1108 cairo_stroke (cr);
1109 }
1110
1111 static void
draw_page(cairo_t * cr,double x,double y,gint page_number,PlumaPrintPreview * preview)1112 draw_page (cairo_t *cr,
1113 double x,
1114 double y,
1115 gint page_number,
1116 PlumaPrintPreview *preview)
1117 {
1118 cairo_save (cr);
1119
1120 /* move to the page top left corner */
1121 cairo_translate (cr, x + PAGE_PAD, y + PAGE_PAD);
1122
1123 draw_page_frame (cr, preview);
1124 draw_page_content (cr, page_number, preview);
1125
1126 cairo_restore (cr);
1127 }
1128
1129 static gboolean
preview_draw(GtkWidget * widget,cairo_t * cr,PlumaPrintPreview * preview)1130 preview_draw (GtkWidget *widget,
1131 cairo_t *cr,
1132 PlumaPrintPreview *preview)
1133 {
1134 PlumaPrintPreviewPrivate *priv;
1135 GdkWindow *bin_window;
1136 gint pg;
1137 gint i, j;
1138
1139 priv = preview->priv;
1140
1141 bin_window = gtk_layout_get_bin_window (GTK_LAYOUT (priv->layout));
1142
1143 if (!gtk_cairo_should_draw_window (cr, bin_window))
1144 return TRUE;
1145
1146 cairo_save (cr);
1147
1148 gtk_cairo_transform_to_window (cr, widget, bin_window);
1149
1150 /* get the first page to display */
1151 pg = get_first_page_displayed (preview);
1152
1153 for (i = 0; i < priv->cols; ++i)
1154 {
1155 for (j = 0; j < priv->rows; ++j)
1156 {
1157 if (!gtk_print_operation_preview_is_selected (priv->gtk_preview,
1158 pg))
1159 {
1160 continue;
1161 }
1162
1163 if (pg == priv->n_pages)
1164 break;
1165
1166 draw_page (cr,
1167 j * priv->tile_w,
1168 i * priv->tile_h,
1169 pg,
1170 preview);
1171
1172 ++pg;
1173 }
1174 }
1175
1176 cairo_restore (cr);
1177
1178 return TRUE;
1179 }
1180
1181 static double
get_screen_dpi(PlumaPrintPreview * preview)1182 get_screen_dpi (PlumaPrintPreview *preview)
1183 {
1184 GdkScreen *screen;
1185 double dpi;
1186
1187 screen = gtk_widget_get_screen (GTK_WIDGET (preview));
1188
1189 dpi = gdk_screen_get_resolution (screen);
1190 if (dpi < 30. || 600. < dpi)
1191 {
1192 g_warning ("Invalid the x-resolution for the screen, assuming 96dpi");
1193 dpi = 96.;
1194 }
1195
1196 return dpi;
1197 }
1198
1199 static void
set_n_pages(PlumaPrintPreview * preview,gint n_pages)1200 set_n_pages (PlumaPrintPreview *preview,
1201 gint n_pages)
1202 {
1203 gchar *str;
1204
1205 preview->priv->n_pages = n_pages;
1206
1207 // FIXME: count the visible pages
1208
1209 str = g_strdup_printf ("%d", n_pages);
1210 gtk_label_set_markup (GTK_LABEL (preview->priv->last), str);
1211 g_free (str);
1212 }
1213
1214 static void
preview_ready(GtkPrintOperationPreview * gtk_preview,GtkPrintContext * context,PlumaPrintPreview * preview)1215 preview_ready (GtkPrintOperationPreview *gtk_preview,
1216 GtkPrintContext *context,
1217 PlumaPrintPreview *preview)
1218 {
1219 gint n_pages;
1220
1221 g_object_get (preview->priv->operation, "n-pages", &n_pages, NULL);
1222 set_n_pages (preview, n_pages);
1223 goto_page (preview, 0);
1224
1225 /* figure out the dpi */
1226 preview->priv->dpi = get_screen_dpi (preview);
1227
1228 set_zoom_factor (preview, 1.0);
1229
1230 /* let the default gtklayout handler clear the background */
1231 g_signal_connect_after (preview->priv->layout,
1232 "draw",
1233 G_CALLBACK (preview_draw),
1234 preview);
1235
1236 gtk_widget_queue_draw (preview->priv->layout);
1237 }
1238
1239 static void
update_paper_size(PlumaPrintPreview * preview,GtkPageSetup * page_setup)1240 update_paper_size (PlumaPrintPreview *preview,
1241 GtkPageSetup *page_setup)
1242 {
1243 GtkPaperSize *paper_size;
1244
1245 paper_size = gtk_page_setup_get_paper_size (page_setup);
1246
1247 preview->priv->paper_w = gtk_paper_size_get_width (paper_size, GTK_UNIT_INCH);
1248 preview->priv->paper_h = gtk_paper_size_get_height (paper_size, GTK_UNIT_INCH);
1249
1250 preview->priv->orientation = gtk_page_setup_get_orientation (page_setup);
1251 }
1252
1253 static void
preview_got_page_size(GtkPrintOperationPreview * gtk_preview,GtkPrintContext * context,GtkPageSetup * page_setup,PlumaPrintPreview * preview)1254 preview_got_page_size (GtkPrintOperationPreview *gtk_preview,
1255 GtkPrintContext *context,
1256 GtkPageSetup *page_setup,
1257 PlumaPrintPreview *preview)
1258 {
1259 update_paper_size (preview, page_setup);
1260 }
1261
1262 /* HACK: we need a dummy surface to paginate... can we use something simpler? */
1263
1264 static cairo_status_t
dummy_write_func(G_GNUC_UNUSED gpointer closure,G_GNUC_UNUSED const guchar * data,G_GNUC_UNUSED guint length)1265 dummy_write_func (G_GNUC_UNUSED gpointer closure,
1266 G_GNUC_UNUSED const guchar *data,
1267 G_GNUC_UNUSED guint length)
1268 {
1269 return CAIRO_STATUS_SUCCESS;
1270 }
1271
1272 #define PRINTER_DPI (72.)
1273
1274 static cairo_surface_t *
create_preview_surface_platform(GtkPaperSize * paper_size,double * dpi_x,double * dpi_y)1275 create_preview_surface_platform (GtkPaperSize *paper_size,
1276 double *dpi_x,
1277 double *dpi_y)
1278 {
1279 double width, height;
1280 cairo_surface_t *sf;
1281
1282 width = gtk_paper_size_get_width (paper_size, GTK_UNIT_POINTS);
1283 height = gtk_paper_size_get_height (paper_size, GTK_UNIT_POINTS);
1284
1285 *dpi_x = *dpi_y = PRINTER_DPI;
1286
1287 sf = cairo_pdf_surface_create_for_stream (dummy_write_func, NULL,
1288 width, height);
1289 return sf;
1290 }
1291
1292 static cairo_surface_t *
create_preview_surface(PlumaPrintPreview * preview,double * dpi_x,double * dpi_y)1293 create_preview_surface (PlumaPrintPreview *preview,
1294 double *dpi_x,
1295 double *dpi_y)
1296 {
1297 GtkPageSetup *page_setup;
1298 GtkPaperSize *paper_size;
1299
1300 page_setup = gtk_print_context_get_page_setup (preview->priv->context);
1301 /* gtk_page_setup_get_paper_size swaps width and height for landscape */
1302 paper_size = gtk_page_setup_get_paper_size (page_setup);
1303
1304 return create_preview_surface_platform (paper_size, dpi_x, dpi_y);
1305 }
1306
1307 GtkWidget *
pluma_print_preview_new(GtkPrintOperation * op,GtkPrintOperationPreview * gtk_preview,GtkPrintContext * context)1308 pluma_print_preview_new (GtkPrintOperation *op,
1309 GtkPrintOperationPreview *gtk_preview,
1310 GtkPrintContext *context)
1311 {
1312 PlumaPrintPreview *preview;
1313 GtkPageSetup *page_setup;
1314 cairo_surface_t *surface;
1315 cairo_t *cr;
1316 double dpi_x, dpi_y;
1317
1318 g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), NULL);
1319 g_return_val_if_fail (GTK_IS_PRINT_OPERATION_PREVIEW (gtk_preview), NULL);
1320
1321 preview = g_object_new (PLUMA_TYPE_PRINT_PREVIEW, NULL);
1322
1323 preview->priv->operation = g_object_ref (op);
1324 preview->priv->gtk_preview = g_object_ref (gtk_preview);
1325 preview->priv->context = g_object_ref (context);
1326
1327 /* FIXME: is this legal?? */
1328 gtk_print_operation_set_unit (op, GTK_UNIT_POINTS);
1329
1330 g_signal_connect (gtk_preview, "ready",
1331 G_CALLBACK (preview_ready), preview);
1332 g_signal_connect (gtk_preview, "got-page-size",
1333 G_CALLBACK (preview_got_page_size), preview);
1334
1335 page_setup = gtk_print_context_get_page_setup (preview->priv->context);
1336 update_paper_size (preview, page_setup);
1337
1338 /* FIXME: we need a cr to paginate... but we can't get the drawing
1339 * area surface because it's not there yet... for now I create
1340 * a dummy pdf surface */
1341
1342 surface = create_preview_surface (preview, &dpi_x, &dpi_y);
1343 cr = cairo_create (surface);
1344 gtk_print_context_set_cairo_context (context, cr, dpi_x, dpi_y);
1345 cairo_destroy (cr);
1346 cairo_surface_destroy (surface);
1347
1348 return GTK_WIDGET (preview);
1349 }
1350
1351