1 /* ev-previewer-window.c:
2 * this file is part of evince, a gnome document viewer
4 * Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
6 * Evince is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Evince is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
23 #include <gtk/gtkunixprint.h>
24 #include <glib/gi18n.h>
25 #include <evince-view.h>
26 #include "ev-stock-icons.h"
27 #include "ev-page-action.h"
29 #include "ev-previewer-window.h"
31 struct _EvPreviewerWindow {
32 GtkWindow base_instance;
36 GtkActionGroup *action_group;
37 GtkUIManager *ui_manager;
44 GtkPrintSettings *print_settings;
45 GtkPageSetup *print_page_setup;
47 gchar *print_job_title;
51 struct _EvPreviewerWindowClass {
52 GtkWindowClass base_class;
55 G_DEFINE_TYPE (EvPreviewerWindow, ev_previewer_window, GTK_TYPE_WINDOW)
58 get_screen_dpi (GtkWindow *window)
63 screen = gtk_window_get_screen (window);
65 xdpi = 25.4 * gdk_screen_get_width (screen) / gdk_screen_get_width_mm (screen);
66 ydpi = 25.4 * gdk_screen_get_height (screen) / gdk_screen_get_height_mm (screen);
68 return (xdpi + ydpi) / 2.0;
72 ev_previewer_window_set_view_size (EvPreviewerWindow *window)
75 GtkRequisition vsb_requisition;
76 GtkRequisition hsb_requisition;
77 gint scrollbar_spacing;
82 /* Calculate the width available for the content */
83 width = window->swindow->allocation.width;
84 height = window->swindow->allocation.height;
86 if (gtk_scrolled_window_get_shadow_type (GTK_SCROLLED_WINDOW (window->swindow)) == GTK_SHADOW_IN) {
87 width -= 2 * GTK_WIDGET (window->view)->style->xthickness;
88 height -= 2 * GTK_WIDGET (window->view)->style->ythickness;
91 gtk_widget_size_request (GTK_SCROLLED_WINDOW (window->swindow)->vscrollbar,
93 gtk_widget_size_request (GTK_SCROLLED_WINDOW (window->swindow)->hscrollbar,
95 gtk_widget_style_get (window->swindow,
100 ev_view_set_zoom_for_size (window->view,
103 vsb_requisition.width + scrollbar_spacing,
104 hsb_requisition.height + scrollbar_spacing);
108 ev_previewer_window_error_dialog_run (EvPreviewerWindow *window,
113 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
115 GTK_DIALOG_DESTROY_WITH_PARENT,
118 "%s", _("Failed to print document"));
119 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
120 "%s", error->message);
121 gtk_dialog_run (GTK_DIALOG (dialog));
122 gtk_widget_destroy (dialog);
126 ev_previewer_window_previous_page (GtkAction *action,
127 EvPreviewerWindow *window)
129 ev_view_previous_page (window->view);
133 ev_previewer_window_next_page (GtkAction *action,
134 EvPreviewerWindow *window)
136 ev_view_next_page (window->view);
140 ev_previewer_window_zoom_in (GtkAction *action,
141 EvPreviewerWindow *window)
143 ev_view_set_sizing_mode (window->view, EV_SIZING_FREE);
144 ev_view_zoom_in (window->view);
148 ev_previewer_window_zoom_out (GtkAction *action,
149 EvPreviewerWindow *window)
151 ev_view_set_sizing_mode (window->view, EV_SIZING_FREE);
152 ev_view_zoom_out (window->view);
156 ev_previewer_window_zoom_best_fit (GtkToggleAction *action,
157 EvPreviewerWindow *window)
159 if (gtk_toggle_action_get_active (action)) {
160 ev_view_set_sizing_mode (window->view, EV_SIZING_BEST_FIT);
161 ev_previewer_window_set_view_size (window);
163 ev_view_set_sizing_mode (window->view, EV_SIZING_FREE);
168 ev_previewer_window_zoom_page_width (GtkToggleAction *action,
169 EvPreviewerWindow *window)
171 if (gtk_toggle_action_get_active (action)) {
172 ev_view_set_sizing_mode (window->view, EV_SIZING_FIT_WIDTH);
173 ev_previewer_window_set_view_size (window);
175 ev_view_set_sizing_mode (window->view, EV_SIZING_FREE);
180 ev_previewer_window_action_page_activated (GtkAction *action,
182 EvPreviewerWindow *window)
184 ev_view_handle_link (window->view, link);
185 gtk_widget_grab_focus (GTK_WIDGET (window->view));
189 ev_previewer_window_print_finished (GtkPrintJob *print_job,
190 EvPreviewerWindow *window,
194 ev_previewer_window_error_dialog_run (window, error);
197 g_object_unref (print_job);
198 gtk_widget_destroy (GTK_WIDGET (window));
202 ev_previewer_window_do_print (EvPreviewerWindow *window)
205 GError *error = NULL;
207 job = gtk_print_job_new (window->print_job_title ?
208 window->print_job_title :
211 window->print_settings,
212 window->print_page_setup);
213 if (gtk_print_job_set_source_file (job, window->source_file, &error)) {
214 gtk_print_job_send (job,
215 (GtkPrintJobCompleteFunc)ev_previewer_window_print_finished,
218 ev_previewer_window_error_dialog_run (window, error);
219 g_error_free (error);
222 gtk_widget_hide (GTK_WIDGET (window));
226 ev_previewer_window_enumerate_finished (EvPreviewerWindow *window)
228 if (window->printer) {
229 ev_previewer_window_do_print (window);
231 GError *error = NULL;
235 GTK_PRINT_ERROR_GENERAL,
236 _("The selected printer '%s' could not be found"),
237 gtk_print_settings_get_printer (window->print_settings));
239 ev_previewer_window_error_dialog_run (window, error);
240 g_error_free (error);
245 ev_previewer_window_enumerate_printers (GtkPrinter *printer,
246 EvPreviewerWindow *window)
248 const gchar *printer_name;
250 printer_name = gtk_print_settings_get_printer (window->print_settings);
252 && strcmp (printer_name, gtk_printer_get_name (printer)) == 0) ||
253 (!printer_name && gtk_printer_is_default (printer))) {
255 g_object_unref (window->printer);
256 window->printer = g_object_ref (printer);
258 return TRUE; /* we're done */
261 return FALSE; /* continue the enumeration */
265 ev_previewer_window_print (GtkAction *action,
266 EvPreviewerWindow *window)
268 if (!window->print_settings)
269 window->print_settings = gtk_print_settings_new ();
270 if (!window->print_page_setup)
271 window->print_page_setup = gtk_page_setup_new ();
272 gtk_enumerate_printers ((GtkPrinterFunc)ev_previewer_window_enumerate_printers,
274 (GDestroyNotify)ev_previewer_window_enumerate_finished,
278 static const GtkActionEntry action_entries[] = {
279 { "GoPreviousPage", GTK_STOCK_GO_UP, N_("_Previous Page"), "<control>Page_Up",
280 N_("Go to the previous page"),
281 G_CALLBACK (ev_previewer_window_previous_page) },
282 { "GoNextPage", GTK_STOCK_GO_DOWN, N_("_Next Page"), "<control>Page_Down",
283 N_("Go to the next page"),
284 G_CALLBACK (ev_previewer_window_next_page) },
285 { "ViewZoomIn", GTK_STOCK_ZOOM_IN, NULL, "<control>plus",
286 N_("Enlarge the document"),
287 G_CALLBACK (ev_previewer_window_zoom_in) },
288 { "ViewZoomOut", GTK_STOCK_ZOOM_OUT, NULL, "<control>minus",
289 N_("Shrink the document"),
290 G_CALLBACK (ev_previewer_window_zoom_out) },
291 { "PreviewPrint", GTK_STOCK_PRINT, N_("Print"), NULL,
292 N_("Print this document"),
293 G_CALLBACK (ev_previewer_window_print) }
296 static const GtkToggleActionEntry toggle_action_entries[] = {
297 { "ViewBestFit", EV_STOCK_ZOOM_PAGE, N_("_Best Fit"), NULL,
298 N_("Make the current document fill the window"),
299 G_CALLBACK (ev_previewer_window_zoom_best_fit) },
300 { "ViewPageWidth", EV_STOCK_ZOOM_WIDTH, N_("Fit Page _Width"), NULL,
301 N_("Make the current document fill the window width"),
302 G_CALLBACK (ev_previewer_window_zoom_page_width) }
305 /* EvView callbacks */
307 view_sizing_mode_changed (EvView *view,
309 EvPreviewerWindow *window)
311 EvSizingMode sizing_mode;
317 g_object_get (window->view,
318 "sizing_mode", &sizing_mode,
321 action = gtk_action_group_get_action (window->action_group, "ViewBestFit");
322 g_signal_handlers_block_by_func (action,
323 G_CALLBACK (ev_previewer_window_zoom_best_fit),
325 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
326 sizing_mode == EV_SIZING_BEST_FIT);
327 g_signal_handlers_unblock_by_func (action,
328 G_CALLBACK (ev_previewer_window_zoom_best_fit),
331 action = gtk_action_group_get_action (window->action_group, "ViewPageWidth");
332 g_signal_handlers_block_by_func (action,
333 G_CALLBACK (ev_previewer_window_zoom_page_width),
335 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
336 sizing_mode == EV_SIZING_FIT_WIDTH);
337 g_signal_handlers_unblock_by_func (action,
338 G_CALLBACK (ev_previewer_window_zoom_page_width),
343 ev_previewer_window_dispose (GObject *object)
345 EvPreviewerWindow *window = EV_PREVIEWER_WINDOW (object);
347 if (window->document) {
348 g_object_unref (window->document);
349 window->document = NULL;
352 if (window->action_group) {
353 g_object_unref (window->action_group);
354 window->action_group = NULL;
357 if (window->ui_manager) {
358 g_object_unref (window->ui_manager);
359 window->ui_manager = NULL;
362 if (window->print_settings) {
363 g_object_unref (window->print_settings);
364 window->print_settings = NULL;
367 if (window->print_page_setup) {
368 g_object_unref (window->print_page_setup);
369 window->print_page_setup = NULL;
372 if (window->printer) {
373 g_object_unref (window->printer);
374 window->printer = NULL;
377 if (window->print_job_title) {
378 g_free (window->print_job_title);
379 window->print_job_title = NULL;
382 if (window->source_file) {
383 g_free (window->source_file);
384 window->source_file = NULL;
387 G_OBJECT_CLASS (ev_previewer_window_parent_class)->dispose (object);
391 ev_previewer_window_init (EvPreviewerWindow *window)
396 GError *error = NULL;
398 gtk_window_set_default_size (GTK_WINDOW (window), 600, 600);
400 window->action_group = gtk_action_group_new ("PreviewerActions");
401 gtk_action_group_set_translation_domain (window->action_group, NULL);
402 gtk_action_group_add_actions (window->action_group, action_entries,
403 G_N_ELEMENTS (action_entries),
405 gtk_action_group_add_toggle_actions (window->action_group, toggle_action_entries,
406 G_N_ELEMENTS (toggle_action_entries),
408 gtk_action_group_set_sensitive (window->action_group, FALSE);
410 action = g_object_new (EV_TYPE_PAGE_ACTION,
411 "name", "PageSelector",
413 "tooltip", _("Select Page"),
414 "icon_name", "text-x-generic",
415 "visible_overflown", FALSE,
417 g_signal_connect (action, "activate_link",
418 G_CALLBACK (ev_previewer_window_action_page_activated),
420 gtk_action_group_add_action (window->action_group, action);
421 g_object_unref (action);
423 window->ui_manager = gtk_ui_manager_new ();
424 gtk_ui_manager_insert_action_group (window->ui_manager,
425 window->action_group, 0);
426 gtk_window_add_accel_group (GTK_WINDOW (window),
427 gtk_ui_manager_get_accel_group (window->ui_manager));
428 if (!gtk_ui_manager_add_ui_from_file (window->ui_manager,
429 DATADIR"/evince-previewer-ui.xml",
431 g_warning ("Failed to load ui from evince-previewer-ui.xml: %s", error->message);
432 g_error_free (error);
435 vbox = gtk_vbox_new (FALSE, 0);
437 toolbar = gtk_ui_manager_get_widget (window->ui_manager, "/PreviewToolbar");
438 gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, FALSE, 0);
439 gtk_widget_show (toolbar);
441 window->swindow = gtk_scrolled_window_new (NULL, NULL);
442 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (window->swindow),
443 GTK_POLICY_AUTOMATIC,
444 GTK_POLICY_AUTOMATIC);
446 window->view = EV_VIEW (ev_view_new ());
447 g_signal_connect (window->view, "notify::sizing-mode",
448 G_CALLBACK (view_sizing_mode_changed),
450 g_signal_connect_swapped (window->view, "zoom_invalid",
451 G_CALLBACK (ev_previewer_window_set_view_size),
454 ev_view_set_screen_dpi (window->view, get_screen_dpi (GTK_WINDOW (window)));
455 ev_view_set_continuous (window->view, FALSE);
456 ev_view_set_sizing_mode (window->view, EV_SIZING_FIT_WIDTH);
457 ev_view_set_loading (window->view, TRUE);
458 view_sizing_mode_changed (window->view, NULL, window);
460 gtk_container_add (GTK_CONTAINER (window->swindow), GTK_WIDGET (window->view));
461 gtk_widget_show (GTK_WIDGET (window->view));
463 gtk_box_pack_start (GTK_BOX (vbox), window->swindow, TRUE, TRUE, 0);
464 gtk_widget_show (window->swindow);
466 gtk_container_add (GTK_CONTAINER (window), vbox);
467 gtk_widget_show (vbox);
471 ev_previewer_window_class_init (EvPreviewerWindowClass *klass)
473 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
475 gobject_class->dispose = ev_previewer_window_dispose;
480 ev_previewer_window_new (void)
482 return GTK_WIDGET (g_object_new (EV_TYPE_PREVIEWER_WINDOW, NULL));
486 ev_previewer_window_set_document (EvPreviewerWindow *window,
487 EvDocument *document)
491 g_return_if_fail (EV_IS_PREVIEWER_WINDOW (window));
492 g_return_if_fail (EV_IS_DOCUMENT (document));
494 if (window->document)
497 action = gtk_action_group_get_action (window->action_group, "PageSelector");
498 ev_page_action_set_document (EV_PAGE_ACTION (action), document);
499 gtk_action_group_set_sensitive (window->action_group, TRUE);
501 window->document = g_object_ref (document);
502 ev_view_set_document (window->view, document);
503 ev_view_set_zoom (window->view,
504 get_screen_dpi (GTK_WINDOW (window)) / 72.0,
506 ev_view_set_loading (window->view, FALSE);
510 ev_previewer_window_set_print_settings (EvPreviewerWindow *window,
511 const gchar *print_settings)
513 if (window->print_settings)
514 g_object_unref (window->print_settings);
515 if (window->print_page_setup)
516 g_object_unref (window->print_page_setup);
517 if (window->print_job_title)
518 g_free (window->print_job_title);
520 if (print_settings && g_file_test (print_settings, G_FILE_TEST_IS_REGULAR)) {
522 GError *error = NULL;
524 key_file = g_key_file_new ();
525 g_key_file_load_from_file (key_file,
527 G_KEY_FILE_KEEP_COMMENTS |
528 G_KEY_FILE_KEEP_TRANSLATIONS,
531 GtkPrintSettings *psettings;
532 GtkPageSetup *psetup;
535 psettings = gtk_print_settings_new_from_key_file (key_file,
538 window->print_settings = psettings ? psettings : gtk_print_settings_new ();
540 psetup = gtk_page_setup_new_from_key_file (key_file,
543 window->print_page_setup = psetup ? psetup : gtk_page_setup_new ();
545 job_name = g_key_file_get_string (key_file,
546 "Print Job", "title",
549 window->print_job_title = job_name;
550 gtk_window_set_title (GTK_WINDOW (window), job_name);
553 window->print_settings = gtk_print_settings_new ();
554 window->print_page_setup = gtk_page_setup_new ();
555 g_error_free (error);
558 g_key_file_free (key_file);
560 window->print_settings = gtk_print_settings_new ();
561 window->print_page_setup = gtk_page_setup_new ();
566 ev_previewer_window_set_source_file (EvPreviewerWindow *window,
567 const gchar *source_file)
569 if (window->source_file)
570 g_free (window->source_file);
571 window->source_file = g_strdup (source_file);