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;
35 EvDocumentModel *model;
38 GtkActionGroup *action_group;
39 GtkUIManager *ui_manager;
46 GtkPrintSettings *print_settings;
47 GtkPageSetup *print_page_setup;
48 #if GTKUNIXPRINT_ENABLED
51 gchar *print_job_title;
55 struct _EvPreviewerWindowClass {
56 GtkWindowClass base_class;
64 #define MIN_SCALE 0.05409
67 G_DEFINE_TYPE (EvPreviewerWindow, ev_previewer_window, GTK_TYPE_WINDOW)
70 get_screen_dpi (GtkWindow *window)
75 screen = gtk_window_get_screen (window);
77 xdpi = 25.4 * gdk_screen_get_width (screen) / gdk_screen_get_width_mm (screen);
78 ydpi = 25.4 * gdk_screen_get_height (screen) / gdk_screen_get_height_mm (screen);
80 return (xdpi + ydpi) / 2.0;
83 #if GTKUNIXPRINT_ENABLED
85 ev_previewer_window_error_dialog_run (EvPreviewerWindow *window,
90 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
92 GTK_DIALOG_DESTROY_WITH_PARENT,
95 "%s", _("Failed to print document"));
96 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
97 "%s", error->message);
98 gtk_dialog_run (GTK_DIALOG (dialog));
99 gtk_widget_destroy (dialog);
104 ev_previewer_window_previous_page (GtkAction *action,
105 EvPreviewerWindow *window)
107 ev_view_previous_page (window->view);
111 ev_previewer_window_next_page (GtkAction *action,
112 EvPreviewerWindow *window)
114 ev_view_next_page (window->view);
118 ev_previewer_window_zoom_in (GtkAction *action,
119 EvPreviewerWindow *window)
121 ev_document_model_set_sizing_mode (window->model, EV_SIZING_FREE);
122 ev_view_zoom_in (window->view);
126 ev_previewer_window_zoom_out (GtkAction *action,
127 EvPreviewerWindow *window)
129 ev_document_model_set_sizing_mode (window->model, EV_SIZING_FREE);
130 ev_view_zoom_out (window->view);
134 ev_previewer_window_zoom_best_fit (GtkToggleAction *action,
135 EvPreviewerWindow *window)
137 ev_document_model_set_sizing_mode (window->model,
138 gtk_toggle_action_get_active (action) ?
139 EV_SIZING_BEST_FIT : EV_SIZING_FREE);
143 ev_previewer_window_zoom_page_width (GtkToggleAction *action,
144 EvPreviewerWindow *window)
146 ev_document_model_set_sizing_mode (window->model,
147 gtk_toggle_action_get_active (action) ?
148 EV_SIZING_FIT_WIDTH : EV_SIZING_FREE);
152 ev_previewer_window_action_page_activated (GtkAction *action,
154 EvPreviewerWindow *window)
156 ev_view_handle_link (window->view, link);
157 gtk_widget_grab_focus (GTK_WIDGET (window->view));
160 #if GTKUNIXPRINT_ENABLED
162 ev_previewer_window_print_finished (GtkPrintJob *print_job,
163 EvPreviewerWindow *window,
167 ev_previewer_window_error_dialog_run (window, error);
170 g_object_unref (print_job);
171 gtk_widget_destroy (GTK_WIDGET (window));
175 ev_previewer_window_do_print (EvPreviewerWindow *window)
178 GError *error = NULL;
180 job = gtk_print_job_new (window->print_job_title ?
181 window->print_job_title :
184 window->print_settings,
185 window->print_page_setup);
186 if (gtk_print_job_set_source_file (job, window->source_file, &error)) {
187 gtk_print_job_send (job,
188 (GtkPrintJobCompleteFunc)ev_previewer_window_print_finished,
191 ev_previewer_window_error_dialog_run (window, error);
192 g_error_free (error);
195 gtk_widget_hide (GTK_WIDGET (window));
199 ev_previewer_window_enumerate_finished (EvPreviewerWindow *window)
201 if (window->printer) {
202 ev_previewer_window_do_print (window);
204 GError *error = NULL;
208 GTK_PRINT_ERROR_GENERAL,
209 _("The selected printer '%s' could not be found"),
210 gtk_print_settings_get_printer (window->print_settings));
212 ev_previewer_window_error_dialog_run (window, error);
213 g_error_free (error);
218 ev_previewer_window_enumerate_printers (GtkPrinter *printer,
219 EvPreviewerWindow *window)
221 const gchar *printer_name;
223 printer_name = gtk_print_settings_get_printer (window->print_settings);
225 && strcmp (printer_name, gtk_printer_get_name (printer)) == 0) ||
226 (!printer_name && gtk_printer_is_default (printer))) {
228 g_object_unref (window->printer);
229 window->printer = g_object_ref (printer);
231 return TRUE; /* we're done */
234 return FALSE; /* continue the enumeration */
238 ev_previewer_window_print (GtkAction *action,
239 EvPreviewerWindow *window)
241 if (!window->print_settings)
242 window->print_settings = gtk_print_settings_new ();
243 if (!window->print_page_setup)
244 window->print_page_setup = gtk_page_setup_new ();
245 gtk_enumerate_printers ((GtkPrinterFunc)ev_previewer_window_enumerate_printers,
247 (GDestroyNotify)ev_previewer_window_enumerate_finished,
252 static const GtkActionEntry action_entries[] = {
253 { "GoPreviousPage", GTK_STOCK_GO_UP, N_("_Previous Page"), "<control>Page_Up",
254 N_("Go to the previous page"),
255 G_CALLBACK (ev_previewer_window_previous_page) },
256 { "GoNextPage", GTK_STOCK_GO_DOWN, N_("_Next Page"), "<control>Page_Down",
257 N_("Go to the next page"),
258 G_CALLBACK (ev_previewer_window_next_page) },
259 { "ViewZoomIn", GTK_STOCK_ZOOM_IN, NULL, "<control>plus",
260 N_("Enlarge the document"),
261 G_CALLBACK (ev_previewer_window_zoom_in) },
262 { "ViewZoomOut", GTK_STOCK_ZOOM_OUT, NULL, "<control>minus",
263 N_("Shrink the document"),
264 G_CALLBACK (ev_previewer_window_zoom_out) },
265 #if GTKUNIXPRINT_ENABLED
266 { "PreviewPrint", GTK_STOCK_PRINT, N_("Print"), NULL,
267 N_("Print this document"),
268 G_CALLBACK (ev_previewer_window_print) }
272 static const GtkToggleActionEntry toggle_action_entries[] = {
273 { "ViewBestFit", EV_STOCK_ZOOM_PAGE, N_("_Best Fit"), NULL,
274 N_("Make the current document fill the window"),
275 G_CALLBACK (ev_previewer_window_zoom_best_fit) },
276 { "ViewPageWidth", EV_STOCK_ZOOM_WIDTH, N_("Fit Page _Width"), NULL,
277 N_("Make the current document fill the window width"),
278 G_CALLBACK (ev_previewer_window_zoom_page_width) }
282 view_sizing_mode_changed (EvDocumentModel *model,
284 EvPreviewerWindow *window)
286 EvSizingMode sizing_mode = ev_document_model_get_sizing_mode (model);
289 action = gtk_action_group_get_action (window->action_group, "ViewBestFit");
290 g_signal_handlers_block_by_func (action,
291 G_CALLBACK (ev_previewer_window_zoom_best_fit),
293 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
294 sizing_mode == EV_SIZING_BEST_FIT);
295 g_signal_handlers_unblock_by_func (action,
296 G_CALLBACK (ev_previewer_window_zoom_best_fit),
299 action = gtk_action_group_get_action (window->action_group, "ViewPageWidth");
300 g_signal_handlers_block_by_func (action,
301 G_CALLBACK (ev_previewer_window_zoom_page_width),
303 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
304 sizing_mode == EV_SIZING_FIT_WIDTH);
305 g_signal_handlers_unblock_by_func (action,
306 G_CALLBACK (ev_previewer_window_zoom_page_width),
311 ev_previewer_window_set_document (EvPreviewerWindow *window,
313 EvDocumentModel *model)
315 EvDocument *document = ev_document_model_get_document (model);
317 window->document = g_object_ref (document);
319 g_signal_connect (model, "notify::sizing-mode",
320 G_CALLBACK (view_sizing_mode_changed),
322 ev_view_set_loading (window->view, FALSE);
323 gtk_action_group_set_sensitive (window->action_group, TRUE);
327 ev_previewer_window_dispose (GObject *object)
329 EvPreviewerWindow *window = EV_PREVIEWER_WINDOW (object);
332 g_object_unref (window->model);
333 window->model = NULL;
336 if (window->document) {
337 g_object_unref (window->document);
338 window->document = NULL;
341 if (window->action_group) {
342 g_object_unref (window->action_group);
343 window->action_group = NULL;
346 if (window->ui_manager) {
347 g_object_unref (window->ui_manager);
348 window->ui_manager = NULL;
351 if (window->print_settings) {
352 g_object_unref (window->print_settings);
353 window->print_settings = NULL;
356 if (window->print_page_setup) {
357 g_object_unref (window->print_page_setup);
358 window->print_page_setup = NULL;
361 #if GTKUNIXPRINT_ENABLED
362 if (window->printer) {
363 g_object_unref (window->printer);
364 window->printer = NULL;
368 if (window->print_job_title) {
369 g_free (window->print_job_title);
370 window->print_job_title = NULL;
373 if (window->source_file) {
374 g_free (window->source_file);
375 window->source_file = NULL;
378 G_OBJECT_CLASS (ev_previewer_window_parent_class)->dispose (object);
388 dir = g_win32_get_package_installation_directory_of_module (NULL);
389 datadir = g_build_filename (dir, "share", "evince", NULL);
392 datadir = g_strdup (DATADIR);
399 ev_previewer_window_init (EvPreviewerWindow *window)
401 gtk_window_set_default_size (GTK_WINDOW (window), 600, 600);
405 ev_previewer_window_set_property (GObject *object,
410 EvPreviewerWindow *window = EV_PREVIEWER_WINDOW (object);
414 window->model = g_value_dup_object (value);
417 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
422 ev_previewer_window_constructor (GType type,
423 guint n_construct_properties,
424 GObjectConstructParam *construct_params)
427 EvPreviewerWindow *window;
431 GError *error = NULL;
432 gchar *datadir, *ui_path;
435 object = G_OBJECT_CLASS (ev_previewer_window_parent_class)->constructor (type,
436 n_construct_properties,
438 window = EV_PREVIEWER_WINDOW (object);
440 dpi = get_screen_dpi (GTK_WINDOW (window));
441 ev_document_model_set_min_scale (window->model, MIN_SCALE * dpi / 72.0);
442 ev_document_model_set_max_scale (window->model, MAX_SCALE * dpi / 72.0);
443 ev_document_model_set_sizing_mode (window->model, EV_SIZING_FIT_WIDTH);
444 g_signal_connect_swapped (window->model, "notify::document",
445 G_CALLBACK (ev_previewer_window_set_document),
448 window->action_group = gtk_action_group_new ("PreviewerActions");
449 gtk_action_group_set_translation_domain (window->action_group, NULL);
450 gtk_action_group_add_actions (window->action_group, action_entries,
451 G_N_ELEMENTS (action_entries),
453 gtk_action_group_add_toggle_actions (window->action_group, toggle_action_entries,
454 G_N_ELEMENTS (toggle_action_entries),
456 gtk_action_group_set_sensitive (window->action_group, FALSE);
458 action = g_object_new (EV_TYPE_PAGE_ACTION,
459 "name", "PageSelector",
461 "tooltip", _("Select Page"),
462 "icon_name", "text-x-generic",
463 "visible_overflown", FALSE,
465 ev_page_action_set_model (EV_PAGE_ACTION (action), window->model);
466 g_signal_connect (action, "activate_link",
467 G_CALLBACK (ev_previewer_window_action_page_activated),
469 gtk_action_group_add_action (window->action_group, action);
470 g_object_unref (action);
472 window->ui_manager = gtk_ui_manager_new ();
473 gtk_ui_manager_insert_action_group (window->ui_manager,
474 window->action_group, 0);
475 gtk_window_add_accel_group (GTK_WINDOW (window),
476 gtk_ui_manager_get_accel_group (window->ui_manager));
477 datadir = data_dir ();
478 ui_path = g_build_filename (datadir, "evince-previewer-ui.xml", NULL);
479 if (!gtk_ui_manager_add_ui_from_file (window->ui_manager, ui_path, &error)) {
480 g_warning ("Failed to load ui from evince-previewer-ui.xml: %s", error->message);
481 g_error_free (error);
486 view_sizing_mode_changed (window->model, NULL, window);
488 vbox = gtk_vbox_new (FALSE, 0);
490 toolbar = gtk_ui_manager_get_widget (window->ui_manager, "/PreviewToolbar");
491 gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, FALSE, 0);
492 gtk_widget_show (toolbar);
494 window->swindow = gtk_scrolled_window_new (NULL, NULL);
495 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (window->swindow),
496 GTK_POLICY_AUTOMATIC,
497 GTK_POLICY_AUTOMATIC);
499 window->view = EV_VIEW (ev_view_new ());
500 ev_view_set_model (window->view, window->model);
501 ev_view_set_continuous (window->view, FALSE);
502 ev_view_set_loading (window->view, TRUE);
504 gtk_container_add (GTK_CONTAINER (window->swindow), GTK_WIDGET (window->view));
505 gtk_widget_show (GTK_WIDGET (window->view));
507 gtk_box_pack_start (GTK_BOX (vbox), window->swindow, TRUE, TRUE, 0);
508 gtk_widget_show (window->swindow);
510 gtk_container_add (GTK_CONTAINER (window), vbox);
511 gtk_widget_show (vbox);
518 ev_previewer_window_class_init (EvPreviewerWindowClass *klass)
520 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
522 gobject_class->constructor = ev_previewer_window_constructor;
523 gobject_class->set_property = ev_previewer_window_set_property;
524 gobject_class->dispose = ev_previewer_window_dispose;
526 g_object_class_install_property (gobject_class,
528 g_param_spec_object ("model",
530 "The document model",
531 EV_TYPE_DOCUMENT_MODEL,
533 G_PARAM_CONSTRUCT_ONLY));
538 ev_previewer_window_new (EvDocumentModel *model)
540 return GTK_WIDGET (g_object_new (EV_TYPE_PREVIEWER_WINDOW, "model", model, NULL));
544 ev_previewer_window_set_print_settings (EvPreviewerWindow *window,
545 const gchar *print_settings)
547 if (window->print_settings)
548 g_object_unref (window->print_settings);
549 if (window->print_page_setup)
550 g_object_unref (window->print_page_setup);
551 if (window->print_job_title)
552 g_free (window->print_job_title);
554 if (print_settings && g_file_test (print_settings, G_FILE_TEST_IS_REGULAR)) {
556 GError *error = NULL;
558 key_file = g_key_file_new ();
559 g_key_file_load_from_file (key_file,
561 G_KEY_FILE_KEEP_COMMENTS |
562 G_KEY_FILE_KEEP_TRANSLATIONS,
565 GtkPrintSettings *psettings;
566 GtkPageSetup *psetup;
569 psettings = gtk_print_settings_new_from_key_file (key_file,
572 window->print_settings = psettings ? psettings : gtk_print_settings_new ();
574 psetup = gtk_page_setup_new_from_key_file (key_file,
577 window->print_page_setup = psetup ? psetup : gtk_page_setup_new ();
579 job_name = g_key_file_get_string (key_file,
580 "Print Job", "title",
583 window->print_job_title = job_name;
584 gtk_window_set_title (GTK_WINDOW (window), job_name);
587 window->print_settings = gtk_print_settings_new ();
588 window->print_page_setup = gtk_page_setup_new ();
589 g_error_free (error);
592 g_key_file_free (key_file);
594 window->print_settings = gtk_print_settings_new ();
595 window->print_page_setup = gtk_page_setup_new ();
600 ev_previewer_window_set_source_file (EvPreviewerWindow *window,
601 const gchar *source_file)
603 if (window->source_file)
604 g_free (window->source_file);
605 window->source_file = g_strdup (source_file);