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 #if GTKUNIXPRINT_ENABLED
24 #include <gtk/gtkunixprint.h>
26 #include <glib/gi18n.h>
27 #include <evince-view.h>
28 #include "ev-page-action.h"
30 #include "ev-previewer-window.h"
32 struct _EvPreviewerWindow {
33 GtkWindow base_instance;
37 GtkActionGroup *action_group;
38 GtkUIManager *ui_manager;
45 GtkPrintSettings *print_settings;
46 GtkPageSetup *print_page_setup;
47 #if GTKUNIXPRINT_ENABLED
50 gchar *print_job_title;
54 struct _EvPreviewerWindowClass {
55 GtkWindowClass base_class;
58 G_DEFINE_TYPE (EvPreviewerWindow, ev_previewer_window, GTK_TYPE_WINDOW)
61 get_screen_dpi (GtkWindow *window)
66 screen = gtk_window_get_screen (window);
68 xdpi = 25.4 * gdk_screen_get_width (screen) / gdk_screen_get_width_mm (screen);
69 ydpi = 25.4 * gdk_screen_get_height (screen) / gdk_screen_get_height_mm (screen);
71 return (xdpi + ydpi) / 2.0;
74 #if GTKUNIXPRINT_ENABLED
76 ev_previewer_window_error_dialog_run (EvPreviewerWindow *window,
81 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
83 GTK_DIALOG_DESTROY_WITH_PARENT,
86 "%s", _("Failed to print document"));
87 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
88 "%s", error->message);
89 gtk_dialog_run (GTK_DIALOG (dialog));
90 gtk_widget_destroy (dialog);
95 ev_previewer_window_previous_page (GtkAction *action,
96 EvPreviewerWindow *window)
98 ev_view_previous_page (window->view);
102 ev_previewer_window_next_page (GtkAction *action,
103 EvPreviewerWindow *window)
105 ev_view_next_page (window->view);
109 ev_previewer_window_zoom_in (GtkAction *action,
110 EvPreviewerWindow *window)
112 ev_view_set_sizing_mode (window->view, EV_SIZING_FREE);
113 ev_view_zoom_in (window->view);
117 ev_previewer_window_zoom_out (GtkAction *action,
118 EvPreviewerWindow *window)
120 ev_view_set_sizing_mode (window->view, EV_SIZING_FREE);
121 ev_view_zoom_out (window->view);
125 ev_previewer_window_zoom_best_fit (GtkToggleAction *action,
126 EvPreviewerWindow *window)
128 if (gtk_toggle_action_get_active (action)) {
129 ev_view_set_sizing_mode (window->view, EV_SIZING_BEST_FIT);
131 ev_view_set_sizing_mode (window->view, EV_SIZING_FREE);
136 ev_previewer_window_zoom_page_width (GtkToggleAction *action,
137 EvPreviewerWindow *window)
139 if (gtk_toggle_action_get_active (action)) {
140 ev_view_set_sizing_mode (window->view, EV_SIZING_FIT_WIDTH);
142 ev_view_set_sizing_mode (window->view, EV_SIZING_FREE);
147 ev_previewer_window_action_page_activated (GtkAction *action,
149 EvPreviewerWindow *window)
151 ev_view_handle_link (window->view, link);
152 gtk_widget_grab_focus (GTK_WIDGET (window->view));
155 #if GTKUNIXPRINT_ENABLED
157 ev_previewer_window_print_finished (GtkPrintJob *print_job,
158 EvPreviewerWindow *window,
162 ev_previewer_window_error_dialog_run (window, error);
165 g_object_unref (print_job);
166 gtk_widget_destroy (GTK_WIDGET (window));
170 ev_previewer_window_do_print (EvPreviewerWindow *window)
173 GError *error = NULL;
175 job = gtk_print_job_new (window->print_job_title ?
176 window->print_job_title :
179 window->print_settings,
180 window->print_page_setup);
181 if (gtk_print_job_set_source_file (job, window->source_file, &error)) {
182 gtk_print_job_send (job,
183 (GtkPrintJobCompleteFunc)ev_previewer_window_print_finished,
186 ev_previewer_window_error_dialog_run (window, error);
187 g_error_free (error);
190 gtk_widget_hide (GTK_WIDGET (window));
194 ev_previewer_window_enumerate_finished (EvPreviewerWindow *window)
196 if (window->printer) {
197 ev_previewer_window_do_print (window);
199 GError *error = NULL;
203 GTK_PRINT_ERROR_GENERAL,
204 _("The selected printer '%s' could not be found"),
205 gtk_print_settings_get_printer (window->print_settings));
207 ev_previewer_window_error_dialog_run (window, error);
208 g_error_free (error);
213 ev_previewer_window_enumerate_printers (GtkPrinter *printer,
214 EvPreviewerWindow *window)
216 const gchar *printer_name;
218 printer_name = gtk_print_settings_get_printer (window->print_settings);
220 && strcmp (printer_name, gtk_printer_get_name (printer)) == 0) ||
221 (!printer_name && gtk_printer_is_default (printer))) {
223 g_object_unref (window->printer);
224 window->printer = g_object_ref (printer);
226 return TRUE; /* we're done */
229 return FALSE; /* continue the enumeration */
233 ev_previewer_window_print (GtkAction *action,
234 EvPreviewerWindow *window)
236 if (!window->print_settings)
237 window->print_settings = gtk_print_settings_new ();
238 if (!window->print_page_setup)
239 window->print_page_setup = gtk_page_setup_new ();
240 gtk_enumerate_printers ((GtkPrinterFunc)ev_previewer_window_enumerate_printers,
242 (GDestroyNotify)ev_previewer_window_enumerate_finished,
247 static const GtkActionEntry action_entries[] = {
248 { "GoPreviousPage", GTK_STOCK_GO_UP, N_("_Previous Page"), "<control>Page_Up",
249 N_("Go to the previous page"),
250 G_CALLBACK (ev_previewer_window_previous_page) },
251 { "GoNextPage", GTK_STOCK_GO_DOWN, N_("_Next Page"), "<control>Page_Down",
252 N_("Go to the next page"),
253 G_CALLBACK (ev_previewer_window_next_page) },
254 { "ViewZoomIn", GTK_STOCK_ZOOM_IN, NULL, "<control>plus",
255 N_("Enlarge the document"),
256 G_CALLBACK (ev_previewer_window_zoom_in) },
257 { "ViewZoomOut", GTK_STOCK_ZOOM_OUT, NULL, "<control>minus",
258 N_("Shrink the document"),
259 G_CALLBACK (ev_previewer_window_zoom_out) },
260 #if GTKUNIXPRINT_ENABLED
261 { "PreviewPrint", GTK_STOCK_PRINT, N_("Print"), NULL,
262 N_("Print this document"),
263 G_CALLBACK (ev_previewer_window_print) }
267 static const GtkToggleActionEntry toggle_action_entries[] = {
268 { "ViewBestFit", EV_STOCK_ZOOM_PAGE, N_("_Best Fit"), NULL,
269 N_("Make the current document fill the window"),
270 G_CALLBACK (ev_previewer_window_zoom_best_fit) },
271 { "ViewPageWidth", EV_STOCK_ZOOM_WIDTH, N_("Fit Page _Width"), NULL,
272 N_("Make the current document fill the window width"),
273 G_CALLBACK (ev_previewer_window_zoom_page_width) }
276 /* EvView callbacks */
278 view_sizing_mode_changed (EvView *view,
280 EvPreviewerWindow *window)
282 EvSizingMode sizing_mode;
288 g_object_get (window->view,
289 "sizing_mode", &sizing_mode,
292 action = gtk_action_group_get_action (window->action_group, "ViewBestFit");
293 g_signal_handlers_block_by_func (action,
294 G_CALLBACK (ev_previewer_window_zoom_best_fit),
296 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
297 sizing_mode == EV_SIZING_BEST_FIT);
298 g_signal_handlers_unblock_by_func (action,
299 G_CALLBACK (ev_previewer_window_zoom_best_fit),
302 action = gtk_action_group_get_action (window->action_group, "ViewPageWidth");
303 g_signal_handlers_block_by_func (action,
304 G_CALLBACK (ev_previewer_window_zoom_page_width),
306 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
307 sizing_mode == EV_SIZING_FIT_WIDTH);
308 g_signal_handlers_unblock_by_func (action,
309 G_CALLBACK (ev_previewer_window_zoom_page_width),
314 ev_previewer_window_dispose (GObject *object)
316 EvPreviewerWindow *window = EV_PREVIEWER_WINDOW (object);
318 if (window->document) {
319 g_object_unref (window->document);
320 window->document = NULL;
323 if (window->action_group) {
324 g_object_unref (window->action_group);
325 window->action_group = NULL;
328 if (window->ui_manager) {
329 g_object_unref (window->ui_manager);
330 window->ui_manager = NULL;
333 if (window->print_settings) {
334 g_object_unref (window->print_settings);
335 window->print_settings = NULL;
338 if (window->print_page_setup) {
339 g_object_unref (window->print_page_setup);
340 window->print_page_setup = NULL;
343 #if GTKUNIXPRINT_ENABLED
344 if (window->printer) {
345 g_object_unref (window->printer);
346 window->printer = NULL;
350 if (window->print_job_title) {
351 g_free (window->print_job_title);
352 window->print_job_title = NULL;
355 if (window->source_file) {
356 g_free (window->source_file);
357 window->source_file = NULL;
360 G_OBJECT_CLASS (ev_previewer_window_parent_class)->dispose (object);
370 dir = g_win32_get_package_installation_directory_of_module (NULL);
371 datadir = g_build_filename (dir, "share", "evince", NULL);
374 datadir = g_strdup (DATADIR);
381 ev_previewer_window_init (EvPreviewerWindow *window)
386 GError *error = NULL;
387 gchar *datadir, *ui_path;
389 gtk_window_set_default_size (GTK_WINDOW (window), 600, 600);
391 window->action_group = gtk_action_group_new ("PreviewerActions");
392 gtk_action_group_set_translation_domain (window->action_group, NULL);
393 gtk_action_group_add_actions (window->action_group, action_entries,
394 G_N_ELEMENTS (action_entries),
396 gtk_action_group_add_toggle_actions (window->action_group, toggle_action_entries,
397 G_N_ELEMENTS (toggle_action_entries),
399 gtk_action_group_set_sensitive (window->action_group, FALSE);
401 action = g_object_new (EV_TYPE_PAGE_ACTION,
402 "name", "PageSelector",
404 "tooltip", _("Select Page"),
405 "icon_name", "text-x-generic",
406 "visible_overflown", FALSE,
408 g_signal_connect (action, "activate_link",
409 G_CALLBACK (ev_previewer_window_action_page_activated),
411 gtk_action_group_add_action (window->action_group, action);
412 g_object_unref (action);
414 window->ui_manager = gtk_ui_manager_new ();
415 gtk_ui_manager_insert_action_group (window->ui_manager,
416 window->action_group, 0);
417 gtk_window_add_accel_group (GTK_WINDOW (window),
418 gtk_ui_manager_get_accel_group (window->ui_manager));
419 datadir = data_dir ();
420 ui_path = g_build_filename (datadir, "evince-previewer-ui.xml", NULL);
421 if (!gtk_ui_manager_add_ui_from_file (window->ui_manager, ui_path, &error)) {
422 g_warning ("Failed to load ui from evince-previewer-ui.xml: %s", error->message);
423 g_error_free (error);
428 vbox = gtk_vbox_new (FALSE, 0);
430 toolbar = gtk_ui_manager_get_widget (window->ui_manager, "/PreviewToolbar");
431 gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, FALSE, 0);
432 gtk_widget_show (toolbar);
434 window->swindow = gtk_scrolled_window_new (NULL, NULL);
435 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (window->swindow),
436 GTK_POLICY_AUTOMATIC,
437 GTK_POLICY_AUTOMATIC);
439 window->view = EV_VIEW (ev_view_new ());
440 g_signal_connect (window->view, "notify::sizing-mode",
441 G_CALLBACK (view_sizing_mode_changed),
444 ev_view_set_screen_dpi (window->view, get_screen_dpi (GTK_WINDOW (window)));
445 ev_view_set_continuous (window->view, FALSE);
446 ev_view_set_sizing_mode (window->view, EV_SIZING_FIT_WIDTH);
447 ev_view_set_loading (window->view, TRUE);
448 view_sizing_mode_changed (window->view, NULL, window);
450 gtk_container_add (GTK_CONTAINER (window->swindow), GTK_WIDGET (window->view));
451 gtk_widget_show (GTK_WIDGET (window->view));
453 gtk_box_pack_start (GTK_BOX (vbox), window->swindow, TRUE, TRUE, 0);
454 gtk_widget_show (window->swindow);
456 gtk_container_add (GTK_CONTAINER (window), vbox);
457 gtk_widget_show (vbox);
461 ev_previewer_window_class_init (EvPreviewerWindowClass *klass)
463 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
465 gobject_class->dispose = ev_previewer_window_dispose;
470 ev_previewer_window_new (void)
472 return GTK_WIDGET (g_object_new (EV_TYPE_PREVIEWER_WINDOW, NULL));
476 ev_previewer_window_set_document (EvPreviewerWindow *window,
477 EvDocument *document)
481 g_return_if_fail (EV_IS_PREVIEWER_WINDOW (window));
482 g_return_if_fail (EV_IS_DOCUMENT (document));
484 if (window->document)
487 action = gtk_action_group_get_action (window->action_group, "PageSelector");
488 ev_page_action_set_document (EV_PAGE_ACTION (action), document);
489 gtk_action_group_set_sensitive (window->action_group, TRUE);
491 window->document = g_object_ref (document);
492 ev_view_set_document (window->view, document);
493 ev_view_set_zoom (window->view,
494 get_screen_dpi (GTK_WINDOW (window)) / 72.0,
496 ev_view_set_loading (window->view, FALSE);
500 ev_previewer_window_set_print_settings (EvPreviewerWindow *window,
501 const gchar *print_settings)
503 if (window->print_settings)
504 g_object_unref (window->print_settings);
505 if (window->print_page_setup)
506 g_object_unref (window->print_page_setup);
507 if (window->print_job_title)
508 g_free (window->print_job_title);
510 if (print_settings && g_file_test (print_settings, G_FILE_TEST_IS_REGULAR)) {
512 GError *error = NULL;
514 key_file = g_key_file_new ();
515 g_key_file_load_from_file (key_file,
517 G_KEY_FILE_KEEP_COMMENTS |
518 G_KEY_FILE_KEEP_TRANSLATIONS,
521 GtkPrintSettings *psettings;
522 GtkPageSetup *psetup;
525 psettings = gtk_print_settings_new_from_key_file (key_file,
528 window->print_settings = psettings ? psettings : gtk_print_settings_new ();
530 psetup = gtk_page_setup_new_from_key_file (key_file,
533 window->print_page_setup = psetup ? psetup : gtk_page_setup_new ();
535 job_name = g_key_file_get_string (key_file,
536 "Print Job", "title",
539 window->print_job_title = job_name;
540 gtk_window_set_title (GTK_WINDOW (window), job_name);
543 window->print_settings = gtk_print_settings_new ();
544 window->print_page_setup = gtk_page_setup_new ();
545 g_error_free (error);
548 g_key_file_free (key_file);
550 window->print_settings = gtk_print_settings_new ();
551 window->print_page_setup = gtk_page_setup_new ();
556 ev_previewer_window_set_source_file (EvPreviewerWindow *window,
557 const gchar *source_file)
559 if (window->source_file)
560 g_free (window->source_file);
561 window->source_file = g_strdup (source_file);