+ switch (page_mode) {
+ case PAGE_MODE_DOCUMENT:
+ child = window->priv->view;
+ break;
+ case PAGE_MODE_PASSWORD:
+ child = window->priv->password_view;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ real_child = gtk_bin_get_child (GTK_BIN (window->priv->scrolled_window));
+ if (child != real_child) {
+ gtk_container_remove (GTK_CONTAINER (window->priv->scrolled_window),
+ real_child);
+ gtk_container_add (GTK_CONTAINER (window->priv->scrolled_window),
+ child);
+ }
+ ev_window_update_actions (window);
+}
+
+
+static void
+ev_window_cmd_edit_rotate_left (GtkAction *action, EvWindow *ev_window)
+{
+ ev_view_rotate_left (EV_VIEW (ev_window->priv->view));
+}
+
+static void
+ev_window_cmd_edit_rotate_right (GtkAction *action, EvWindow *ev_window)
+{
+ ev_view_rotate_right (EV_VIEW (ev_window->priv->view));
+}
+
+static void
+ev_window_cmd_edit_toolbar_cb (GtkDialog *dialog, gint response, gpointer data)
+{
+ EvWindow *ev_window = EV_WINDOW (data);
+ egg_editable_toolbar_set_edit_mode
+ (EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar), FALSE);
+ ev_application_save_toolbars_model (EV_APP);
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+ev_window_cmd_edit_toolbar (GtkAction *action, EvWindow *ev_window)
+{
+ GtkWidget *dialog;
+ GtkWidget *editor;
+
+ dialog = gtk_dialog_new_with_buttons (_("Toolbar Editor"),
+ GTK_WINDOW (ev_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CLOSE,
+ GTK_RESPONSE_CLOSE,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE);
+ gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)), 5);
+ gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2);
+ gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 400);
+
+ editor = egg_toolbar_editor_new (ev_window->priv->ui_manager,
+ ev_application_get_toolbars_model (EV_APP));
+ gtk_container_set_border_width (GTK_CONTAINER (editor), 5);
+ gtk_box_set_spacing (GTK_BOX (EGG_TOOLBAR_EDITOR (editor)), 5);
+
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), editor);
+
+ egg_editable_toolbar_set_edit_mode
+ (EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar), TRUE);
+
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (ev_window_cmd_edit_toolbar_cb),
+ ev_window);
+ gtk_widget_show_all (dialog);
+}
+
+static void
+ev_window_cmd_view_zoom_in (GtkAction *action, EvWindow *ev_window)
+{
+ g_return_if_fail (EV_IS_WINDOW (ev_window));
+
+ ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_FREE);
+ ev_view_zoom_in (EV_VIEW (ev_window->priv->view));
+}
+
+static void
+ev_window_cmd_view_zoom_out (GtkAction *action, EvWindow *ev_window)
+{
+ g_return_if_fail (EV_IS_WINDOW (ev_window));
+
+ ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_FREE);
+ ev_view_zoom_out (EV_VIEW (ev_window->priv->view));
+}
+
+static void
+ev_window_cmd_go_previous_page (GtkAction *action, EvWindow *ev_window)
+{
+ g_return_if_fail (EV_IS_WINDOW (ev_window));
+
+ ev_view_previous_page (EV_VIEW (ev_window->priv->view));
+}
+
+static void
+ev_window_cmd_go_next_page (GtkAction *action, EvWindow *ev_window)
+{
+ g_return_if_fail (EV_IS_WINDOW (ev_window));
+
+ ev_view_next_page (EV_VIEW (ev_window->priv->view));
+}
+
+static void
+ev_window_cmd_go_first_page (GtkAction *action, EvWindow *ev_window)
+{
+ g_return_if_fail (EV_IS_WINDOW (ev_window));
+
+ ev_page_cache_set_current_page (ev_window->priv->page_cache, 0);
+}
+
+static void
+ev_window_cmd_go_last_page (GtkAction *action, EvWindow *ev_window)
+{
+ int n_pages;
+
+ g_return_if_fail (EV_IS_WINDOW (ev_window));
+
+ n_pages = ev_page_cache_get_n_pages (ev_window->priv->page_cache);
+ ev_page_cache_set_current_page (ev_window->priv->page_cache, n_pages - 1);
+}
+
+static void
+ev_window_cmd_go_forward (GtkAction *action, EvWindow *ev_window)
+{
+ int n_pages, current_page;
+
+ g_return_if_fail (EV_IS_WINDOW (ev_window));
+
+ n_pages = ev_page_cache_get_n_pages (ev_window->priv->page_cache);
+ current_page = ev_page_cache_get_current_page (ev_window->priv->page_cache);
+
+ if (current_page + 10 < n_pages)
+ ev_page_cache_set_current_page (ev_window->priv->page_cache, current_page + 10);
+}
+
+static void
+ev_window_cmd_go_backward (GtkAction *action, EvWindow *ev_window)
+{
+ int current_page;
+
+ g_return_if_fail (EV_IS_WINDOW (ev_window));
+
+ current_page = ev_page_cache_get_current_page (ev_window->priv->page_cache);
+
+ if (current_page - 10 >= 0)
+ ev_page_cache_set_current_page (ev_window->priv->page_cache, current_page - 10);
+}
+
+static void
+ev_window_cmd_view_reload (GtkAction *action, EvWindow *ev_window)
+{
+ ev_window_reload_document (ev_window);
+}
+
+static void
+ev_window_cmd_view_autoscroll (GtkAction *action, EvWindow *ev_window)
+{
+ ev_view_autoscroll_start (EV_VIEW (ev_window->priv->view));
+}
+
+#if GTK_CHECK_VERSION (2, 14, 0)
+static void
+ev_window_cmd_help_contents (GtkAction *action, EvWindow *ev_window)
+{
+ GError *error = NULL;
+
+ gtk_show_uri (gtk_window_get_screen (GTK_WINDOW (ev_window)),
+ "ghelp:evince",
+ GDK_CURRENT_TIME,
+ &error);
+ if (error) {
+ ev_window_error_message (ev_window, error,
+ "%s", _("There was an error displaying help"));
+ g_error_free (error);
+ }
+}
+#else /* !GTK_CHECK_VERSION (2, 14, 0) */
+static void
+ev_window_cmd_help_contents (GtkAction *action, EvWindow *ev_window)
+{
+ GError *error = NULL;
+ GdkScreen *screen;
+ char *command;
+ const char *lang;
+ char *uri = NULL;
+
+ int i;
+
+ const char * const * langs = g_get_language_names ();
+
+ for (i = 0; langs[i]; i++) {
+ lang = langs[i];
+ if (strchr (lang, '.')) {
+ continue;
+ }
+
+ uri = g_build_filename(GNOMEDATADIR,
+ "/gnome/help/" PACKAGE,
+ lang,
+ "/evince.xml",
+ NULL);
+
+ if (g_file_test (uri, G_FILE_TEST_EXISTS)) {
+ break;
+ }
+ g_free (uri);
+ uri = NULL;
+ }
+
+ if (uri == NULL) {
+ g_warning ("Cannot find help");
+ return;
+ }
+
+ command = g_strconcat ("gnome-help ghelp://", uri, NULL);
+ g_free (uri);
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (ev_window));
+ gdk_spawn_command_line_on_screen (screen, command, &error);
+ if (error != NULL) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+ g_free (command);
+}
+#endif /* GTK_CHECK_VERSION (2, 14, 0) */
+
+static void
+ev_window_cmd_leave_fullscreen (GtkAction *action, EvWindow *window)
+{
+ ev_window_stop_fullscreen (window, TRUE);
+}
+
+static void
+ev_window_cmd_start_presentation (GtkAction *action, EvWindow *window)
+{
+ ev_window_run_presentation (window);
+}
+
+static gboolean
+ev_window_enumerate_printer_cb (GtkPrinter *printer,
+ EvWindow *window)
+{
+ EvWindowPrivate *priv = window->priv;
+ const gchar *printer_name;
+
+ printer_name = gtk_print_settings_get_printer (priv->print_settings);
+ if ((printer_name
+ && strcmp (printer_name, gtk_printer_get_name (printer)) == 0) ||
+ (!printer_name && gtk_printer_is_default (printer))) {
+ if (priv->printer)
+ g_object_unref (priv->printer);
+ priv->printer = g_object_ref (printer);
+
+ /* Now that we have the printer, we'll start the print */
+ ev_window_do_preview_print (window);
+
+ return TRUE; /* we're done */
+ }
+
+ return FALSE; /* continue the enumeration */
+}
+
+static void
+ev_window_preview_print_finished (GtkPrintJob *print_job,
+ EvWindow *window,
+ GError *error)
+{
+ if (error) {
+ ev_window_error_message (window, error,
+ "%s", _("Failed to print document"));
+ }
+
+ g_object_unref (print_job);
+ gtk_widget_destroy (GTK_WIDGET (window));
+}
+
+static void
+ev_window_do_preview_print (EvWindow *window)
+{
+ EvWindowPrivate *priv = window->priv;
+ GtkPrintJob *job;
+ gchar *filename;
+ GError *error = NULL;
+
+ g_assert (priv->print_settings != NULL);
+ g_assert (priv->printer != NULL);
+
+ job = gtk_print_job_new (gtk_window_get_title (GTK_WINDOW (window)),
+ priv->printer,
+ priv->print_settings,
+ priv->print_page_setup);
+
+ g_object_unref (priv->print_settings);
+ priv->print_settings = NULL;
+ g_object_unref (priv->print_page_setup);
+ priv->print_page_setup = NULL;
+ g_object_unref (priv->printer);
+ priv->printer = NULL;
+
+ filename = g_filename_from_uri (priv->local_uri ?
+ priv->local_uri : priv->uri,
+ NULL, NULL);
+
+ if (gtk_print_job_set_source_file (job, filename, &error)) {
+ gtk_print_job_send (job,
+ (GtkPrintJobCompleteFunc)ev_window_preview_print_finished,
+ window, NULL);
+ } else {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+
+ g_free (filename);
+
+ gtk_widget_hide (GTK_WIDGET (window));
+}
+
+static void
+ev_window_cmd_preview_print (GtkAction *action, EvWindow *window)
+{
+ EvWindowPrivate *priv = window->priv;
+ GtkPrintSettings *print_settings;
+ GtkPageSetup *page_setup;
+ const gchar *print_settings_file = priv->print_settings_file;
+
+ if (print_settings_file && g_file_test (print_settings_file, G_FILE_TEST_IS_REGULAR)) {
+ GKeyFile *key_file;
+ GError *error = NULL;
+
+ key_file = g_key_file_new ();
+ g_key_file_load_from_file (key_file,
+ print_settings_file,
+ G_KEY_FILE_KEEP_COMMENTS |
+ G_KEY_FILE_KEEP_TRANSLATIONS,
+ &error);
+ if (!error) {
+ print_settings =
+ gtk_print_settings_new_from_key_file (key_file,
+ "Print Settings",
+ NULL);
+ print_settings = print_settings ? print_settings : gtk_print_settings_new ();
+
+ page_setup = gtk_page_setup_new_from_key_file (key_file,
+ "Page Setup",
+ NULL);
+ page_setup = page_setup ? page_setup : gtk_page_setup_new ();
+ } else {
+ print_settings = gtk_print_settings_new ();
+ page_setup = gtk_page_setup_new ();
+ g_error_free (error);
+ }
+
+ g_key_file_free (key_file);
+ } else {
+ print_settings = gtk_print_settings_new ();
+ page_setup = gtk_page_setup_new ();
+ }
+
+ if (priv->print_settings)
+ g_object_unref (priv->print_settings);
+ priv->print_settings = print_settings;
+ if (priv->print_page_setup)
+ g_object_unref (priv->print_page_setup);
+ priv->print_page_setup = page_setup;
+
+ gtk_enumerate_printers ((GtkPrinterFunc) ev_window_enumerate_printer_cb,
+ window, NULL, FALSE);
+}
+
+static void
+ev_window_cmd_escape (GtkAction *action, EvWindow *window)
+{
+ GtkWidget *widget;
+
+ ev_view_autoscroll_stop (EV_VIEW (window->priv->view));
+
+ widget = gtk_window_get_focus (GTK_WINDOW (window));
+ if (widget && gtk_widget_get_ancestor (widget, EGG_TYPE_FIND_BAR)) {
+ update_chrome_flag (window, EV_CHROME_FINDBAR, FALSE);
+ update_chrome_visibility (window);
+ gtk_widget_grab_focus (window->priv->view);
+ } else {
+ gboolean fullscreen;
+ gboolean presentation;
+
+ g_object_get (window->priv->view,
+ "fullscreen", &fullscreen,
+ "presentation", &presentation,
+ NULL);
+
+ if (fullscreen) {
+ ev_window_stop_fullscreen (window, TRUE);
+ } else if (presentation) {
+ ev_window_stop_presentation (window, TRUE);
+ gtk_widget_grab_focus (window->priv->view);
+ } else {
+ gtk_widget_grab_focus (window->priv->view);
+ }
+
+ if (fullscreen && presentation)
+ g_warning ("Both fullscreen and presentation set somehow");
+ }
+}
+
+static void
+save_sizing_mode (EvWindow *window)
+{
+ EvSizingMode mode;
+ GEnumValue *enum_value;
+
+ mode = ev_view_get_sizing_mode (EV_VIEW (window->priv->view));
+ enum_value = g_enum_get_value (g_type_class_peek (EV_TYPE_SIZING_MODE), mode);
+
+ if (!ev_window_is_empty (window))
+ ev_metadata_manager_set_string (window->priv->uri, "sizing_mode",
+ enum_value->value_nick);
+}
+
+static void
+ev_window_sizing_mode_changed_cb (EvView *view, GParamSpec *pspec,
+ EvWindow *ev_window)
+{
+ GtkWidget *scrolled_window;
+ EvSizingMode sizing_mode;
+
+ g_object_get (ev_window->priv->view,
+ "sizing-mode", &sizing_mode,
+ NULL);
+
+ scrolled_window = ev_window->priv->scrolled_window;
+
+ g_signal_handlers_disconnect_by_func (ev_window->priv->view, ev_view_update_view_size, scrolled_window);
+
+ if (sizing_mode != EV_SIZING_FREE)
+ ev_view_update_view_size (EV_VIEW (ev_window->priv->view),
+ GTK_SCROLLED_WINDOW (scrolled_window));
+
+ switch (sizing_mode) {
+ case EV_SIZING_BEST_FIT:
+ g_object_set (G_OBJECT (scrolled_window),
+ "hscrollbar-policy", GTK_POLICY_NEVER,
+ "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
+ NULL);
+ g_signal_connect (ev_window->priv->view, "zoom_invalid",
+ G_CALLBACK (ev_view_update_view_size),
+ scrolled_window);
+ break;
+ case EV_SIZING_FIT_WIDTH:
+ g_object_set (G_OBJECT (scrolled_window),
+ "hscrollbar-policy", GTK_POLICY_NEVER,
+ "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
+ NULL);
+ g_signal_connect (ev_window->priv->view, "zoom_invalid",
+ G_CALLBACK (ev_view_update_view_size),
+ scrolled_window);
+ break;
+ case EV_SIZING_FREE:
+ g_object_set (G_OBJECT (scrolled_window),
+ "hscrollbar-policy", GTK_POLICY_AUTOMATIC,
+ "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
+ NULL);
+ break;
+ }
+
+ update_sizing_buttons (ev_window);
+ save_sizing_mode (ev_window);
+}
+
+static void
+ev_window_zoom_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *ev_window)
+{
+ ev_window_update_actions (ev_window);
+
+ if (ev_view_get_sizing_mode (view) == EV_SIZING_FREE && !ev_window_is_empty (ev_window)) {
+ gdouble zoom;
+
+ zoom = ev_view_get_zoom (view);
+ zoom *= 72.0 / get_screen_dpi (GTK_WINDOW(ev_window));
+ ev_metadata_manager_set_double (ev_window->priv->uri, "zoom", zoom);
+ }
+}
+
+static void
+ev_window_update_continuous_action (EvWindow *window)
+{
+ GtkAction *action;
+
+ action = gtk_action_group_get_action (window->priv->action_group, "ViewContinuous");
+ g_signal_handlers_block_by_func
+ (action, G_CALLBACK (ev_window_cmd_continuous), window);
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
+ ev_view_get_continuous (EV_VIEW (window->priv->view)));
+ g_signal_handlers_unblock_by_func
+ (action, G_CALLBACK (ev_window_cmd_continuous), window);
+}
+
+static void
+ev_window_update_dual_page_action (EvWindow *window)
+{
+ GtkAction *action;
+
+ action = gtk_action_group_get_action (window->priv->action_group, "ViewDual");
+ g_signal_handlers_block_by_func
+ (action, G_CALLBACK (ev_window_cmd_dual), window);
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
+ ev_view_get_dual_page (EV_VIEW (window->priv->view)));
+ g_signal_handlers_unblock_by_func
+ (action, G_CALLBACK (ev_window_cmd_dual), window);
+}
+
+static void
+ev_window_continuous_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *ev_window)
+{
+ ev_window_update_continuous_action (ev_window);
+
+ if (!ev_window_is_empty (ev_window))
+ ev_metadata_manager_set_boolean (ev_window->priv->uri, "continuous",
+ ev_view_get_continuous (EV_VIEW (ev_window->priv->view)));
+}
+
+static void
+ev_window_rotation_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *window)
+{
+ int rotation;
+
+ rotation = ev_view_get_rotation (EV_VIEW (window->priv->view));
+
+ if (!ev_window_is_empty (window))
+ ev_metadata_manager_set_int (window->priv->uri, "rotation",
+ rotation);
+
+ ev_sidebar_thumbnails_refresh (EV_SIDEBAR_THUMBNAILS (window->priv->sidebar_thumbs),
+ rotation);
+ ev_window_refresh_window_thumbnail (window, rotation);
+}
+
+static void
+ev_window_has_selection_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *window)
+{
+ ev_window_update_actions (window);
+}
+
+static void
+ev_window_dual_mode_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *ev_window)
+{
+ ev_window_update_dual_page_action (ev_window);
+
+ if (!ev_window_is_empty (ev_window))
+ ev_metadata_manager_set_boolean (ev_window->priv->uri, "dual-page",
+ ev_view_get_dual_page (EV_VIEW (ev_window->priv->view)));
+}
+
+static char *
+build_comments_string (void)
+{
+#ifdef ENABLE_PDF
+ PopplerBackend backend;
+ const char *backend_name;
+ const char *version;
+
+ backend = poppler_get_backend ();
+ version = poppler_get_version ();
+ switch (backend) {
+ case POPPLER_BACKEND_CAIRO:
+ backend_name = "cairo";
+ break;
+ case POPPLER_BACKEND_SPLASH:
+ backend_name = "splash";
+ break;
+ default:
+ backend_name = "unknown";
+ break;
+ }
+
+ return g_strdup_printf (_("Document Viewer.\n"
+ "Using poppler %s (%s)"),
+ version, backend_name);
+#else
+ return g_strdup_printf (_("Document Viewer"));
+#endif
+}
+
+static void
+ev_window_cmd_help_about (GtkAction *action, EvWindow *ev_window)
+{
+ const char *authors[] = {
+ "Martin Kretzschmar <m_kretzschmar@gmx.net>",
+ "Jonathan Blandford <jrb@gnome.org>",
+ "Marco Pesenti Gritti <marco@gnome.org>",
+ "Nickolay V. Shmyrev <nshmyrev@yandex.ru>",
+ "Bryan Clark <clarkbw@gnome.org>",
+ "Carlos Garcia Campos <carlosgc@gnome.org>",
+ "Wouter Bolsterlee <wbolster@gnome.org>",
+ NULL
+ };
+
+ const char *documenters[] = {
+ "Nickolay V. Shmyrev <nshmyrev@yandex.ru>",
+ NULL
+ };
+
+ const char *license[] = {
+ N_("Evince is free software; you can redistribute it and/or modify "
+ "it under the terms of the GNU General Public License as published by "
+ "the Free Software Foundation; either version 2 of the License, or "
+ "(at your option) any later version.\n"),
+ N_("Evince is distributed in the hope that it will be useful, "
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of "
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the "
+ "GNU General Public License for more details.\n"),
+ N_("You should have received a copy of the GNU General Public License "
+ "along with Evince; if not, write to the Free Software Foundation, Inc., "
+ "59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n")
+ };
+
+ char *license_trans;
+ char *comments;
+
+#ifdef ENABLE_NLS
+ const char **p;
+
+ for (p = authors; *p; ++p)
+ *p = _(*p);
+
+ for (p = documenters; *p; ++p)
+ *p = _(*p);
+#endif
+
+ license_trans = g_strconcat (_(license[0]), "\n", _(license[1]), "\n",
+ _(license[2]), "\n", NULL);
+ comments = build_comments_string ();
+
+ gtk_show_about_dialog (
+ GTK_WINDOW (ev_window),
+ "name", _("Evince"),
+ "version", VERSION,
+ "copyright",
+ _("\xc2\xa9 1996-2007 The Evince authors"),
+ "license", license_trans,
+ "website", "http://www.gnome.org/projects/evince",
+ "comments", comments,
+ "authors", authors,
+ "documenters", documenters,
+ "translator-credits", _("translator-credits"),
+ "logo-icon-name", "evince",
+ "wrap-license", TRUE,
+ NULL);
+
+ g_free (comments);
+ g_free (license_trans);
+}
+
+static void
+ev_window_view_toolbar_cb (GtkAction *action, EvWindow *ev_window)
+{
+ gboolean active;
+
+ active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+ update_chrome_flag (ev_window, EV_CHROME_TOOLBAR, active);
+ update_chrome_visibility (ev_window);
+ ev_metadata_manager_set_boolean (NULL, "show_toolbar", active);
+}
+
+static void
+ev_window_view_sidebar_cb (GtkAction *action, EvWindow *ev_window)
+{
+ if (ev_view_get_presentation (EV_VIEW (ev_window->priv->view)))
+ return;
+
+ update_chrome_flag (ev_window, EV_CHROME_SIDEBAR,
+ gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
+ update_chrome_visibility (ev_window);
+}
+
+static void
+ev_window_sidebar_current_page_changed_cb (EvSidebar *ev_sidebar,
+ GParamSpec *pspec,
+ EvWindow *ev_window)
+{
+ GtkWidget *current_page;
+ const char *id;
+
+ g_object_get (G_OBJECT (ev_sidebar), "current_page", ¤t_page, NULL);
+
+ if (current_page == ev_window->priv->sidebar_links) {
+ id = LINKS_SIDEBAR_ID;
+ } else if (current_page == ev_window->priv->sidebar_thumbs) {
+ id = THUMBNAILS_SIDEBAR_ID;
+ } else if (current_page == ev_window->priv->sidebar_attachments) {
+ id = ATTACHMENTS_SIDEBAR_ID;
+ } else if (current_page == ev_window->priv->sidebar_layers) {
+ id = LAYERS_SIDEBAR_ID;
+ } else {
+ g_assert_not_reached();
+ }
+
+ g_object_unref (current_page);
+
+ if (!ev_window_is_empty (ev_window))
+ ev_metadata_manager_set_string (ev_window->priv->uri, "sidebar_page", id);
+}
+
+static void
+ev_window_sidebar_visibility_changed_cb (EvSidebar *ev_sidebar,
+ GParamSpec *pspec,
+ EvWindow *ev_window)
+{
+ EvView *view = EV_VIEW (ev_window->priv->view);
+ GtkAction *action;
+
+ action = gtk_action_group_get_action (ev_window->priv->action_group, "ViewSidebar");
+
+ if (!ev_view_get_presentation (view)) {
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
+ GTK_WIDGET_VISIBLE (ev_sidebar));
+
+ ev_metadata_manager_set_boolean (ev_window->priv->uri, "sidebar_visibility",
+ GTK_WIDGET_VISIBLE (ev_sidebar));
+ }
+}
+
+static void
+view_menu_link_popup (EvWindow *ev_window,
+ EvLink *link)
+{
+ gboolean show_external = FALSE;
+ gboolean show_internal = FALSE;
+ GtkAction *action;
+
+ if (ev_window->priv->link)
+ g_object_unref (ev_window->priv->link);
+
+ if (link)
+ ev_window->priv->link = g_object_ref (link);
+ else
+ ev_window->priv->link = NULL;
+
+ if (ev_window->priv->link) {
+ EvLinkAction *ev_action;
+
+ ev_action = ev_link_get_action (link);
+ if (ev_action) {
+ switch (ev_link_action_get_action_type (ev_action)) {
+ case EV_LINK_ACTION_TYPE_GOTO_DEST:
+ case EV_LINK_ACTION_TYPE_GOTO_REMOTE:
+ show_internal = TRUE;
+ break;
+ case EV_LINK_ACTION_TYPE_EXTERNAL_URI:
+ case EV_LINK_ACTION_TYPE_LAUNCH:
+ show_external = TRUE;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
+ "OpenLink");
+ gtk_action_set_visible (action, show_external);
+
+ action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
+ "CopyLinkAddress");
+ gtk_action_set_visible (action, show_external);
+
+ action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
+ "GoLink");
+ gtk_action_set_visible (action, show_internal);
+
+ action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
+ "OpenLinkNewWindow");
+ gtk_action_set_visible (action, show_internal);
+}
+
+static void
+view_menu_image_popup (EvWindow *ev_window,
+ EvImage *image)
+{
+ GtkAction *action;
+ gboolean show_image = FALSE;
+
+ if (ev_window->priv->image)
+ g_object_unref (ev_window->priv->image);
+
+ if (image)
+ ev_window->priv->image = g_object_ref (image);
+ else
+ ev_window->priv->image = NULL;
+
+ show_image = (ev_window->priv->image != NULL);
+
+ action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
+ "SaveImageAs");
+ gtk_action_set_visible (action, show_image);
+
+ action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
+ "CopyImage");
+ gtk_action_set_visible (action, show_image);
+}
+
+static gboolean
+view_menu_popup_cb (EvView *view,
+ GObject *object,
+ EvWindow *ev_window)
+{
+ if (ev_view_get_presentation (EV_VIEW (ev_window->priv->view)))
+ return FALSE;
+
+ view_menu_link_popup (ev_window,
+ EV_IS_LINK (object) ? EV_LINK (object) : NULL);
+ view_menu_image_popup (ev_window,
+ EV_IS_IMAGE (object) ? EV_IMAGE (object) : NULL);
+
+ gtk_menu_popup (GTK_MENU (ev_window->priv->view_popup),
+ NULL, NULL, NULL, NULL,
+ 3, gtk_get_current_event_time ());
+ return TRUE;
+}
+
+static gboolean
+attachment_bar_menu_popup_cb (EvSidebarAttachments *attachbar,
+ GList *attach_list,
+ EvWindow *ev_window)
+{
+ GtkWidget *popup;
+
+ g_assert (attach_list != NULL);
+
+ if (ev_window->priv->attach_list) {
+ g_list_foreach (ev_window->priv->attach_list,
+ (GFunc) g_object_unref, NULL);
+ g_list_free (ev_window->priv->attach_list);
+ }
+
+ ev_window->priv->attach_list = attach_list;
+
+ popup = ev_window->priv->attachment_popup;
+
+ gtk_menu_popup (GTK_MENU (popup), NULL, NULL,
+ NULL, NULL,
+ 3, gtk_get_current_event_time ());
+
+ return TRUE;
+}
+
+static void
+ev_window_update_find_status_message (EvWindow *ev_window)
+{
+ gchar *message;
+
+ if (!ev_window->priv->find_job)
+ return;
+
+ if (ev_job_is_finished (ev_window->priv->find_job)) {
+ gint n_results;
+
+ n_results = ev_job_find_get_n_results (EV_JOB_FIND (ev_window->priv->find_job),
+ ev_page_cache_get_current_page (ev_window->priv->page_cache));
+ /* TRANS: Sometimes this could be better translated as
+ "%d hit(s) on this page". Therefore this string
+ contains plural cases. */
+ message = g_strdup_printf (ngettext ("%d found on this page",
+ "%d found on this page",
+ n_results),
+ n_results);
+ } else {
+ gdouble percent;
+
+ percent = ev_job_find_get_progress (EV_JOB_FIND (ev_window->priv->find_job));
+ message = g_strdup_printf (_("%3d%% remaining to search"),
+ (gint) ((1.0 - percent) * 100));
+ }
+
+ egg_find_bar_set_status_text (EGG_FIND_BAR (ev_window->priv->find_bar), message);
+ g_free (message);
+}
+
+static void
+ev_window_find_job_finished_cb (EvJobFind *job,
+ EvWindow *ev_window)
+{
+ ev_window_update_find_status_message (ev_window);
+}
+
+static void
+ev_window_find_job_updated_cb (EvJobFind *job,
+ gint page,
+ EvWindow *ev_window)
+{
+ ev_window_update_actions (ev_window);
+
+ ev_view_find_changed (EV_VIEW (ev_window->priv->view),
+ ev_job_find_get_results (job),
+ page);
+ ev_window_update_find_status_message (ev_window);
+}
+
+static void
+ev_window_clear_find_job (EvWindow *ev_window)
+{
+ if (ev_window->priv->find_job != NULL) {
+ if (!ev_job_is_finished (ev_window->priv->find_job))
+ ev_job_cancel (ev_window->priv->find_job);
+
+ g_signal_handlers_disconnect_by_func (ev_window->priv->find_job,
+ ev_window_find_job_finished_cb,
+ ev_window);
+ g_signal_handlers_disconnect_by_func (ev_window->priv->find_job,
+ ev_window_find_job_updated_cb,
+ ev_window);
+ g_object_unref (ev_window->priv->find_job);
+ ev_window->priv->find_job = NULL;
+ }
+}
+
+static void
+find_bar_previous_cb (EggFindBar *find_bar,
+ EvWindow *ev_window)
+{
+ ev_view_find_previous (EV_VIEW (ev_window->priv->view));
+}
+
+static void
+find_bar_next_cb (EggFindBar *find_bar,
+ EvWindow *ev_window)
+{
+ ev_view_find_next (EV_VIEW (ev_window->priv->view));
+}
+
+static void
+find_bar_close_cb (EggFindBar *find_bar,
+ EvWindow *ev_window)
+{
+ ev_view_find_cancel (EV_VIEW (ev_window->priv->view));
+ ev_window_clear_find_job (ev_window);
+ update_chrome_flag (ev_window, EV_CHROME_FINDBAR, FALSE);
+ update_chrome_visibility (ev_window);
+}
+
+static void
+find_bar_search_changed_cb (EggFindBar *find_bar,
+ GParamSpec *param,
+ EvWindow *ev_window)
+{
+ gboolean case_sensitive;
+ const char *search_string;
+
+ if (!ev_window->priv->document || !EV_IS_DOCUMENT_FIND (ev_window->priv->document))
+ return;
+
+ /* Either the string or case sensitivity could have changed. */
+ case_sensitive = egg_find_bar_get_case_sensitive (find_bar);
+ search_string = egg_find_bar_get_search_string (find_bar);
+
+ ev_view_find_search_changed (EV_VIEW (ev_window->priv->view));
+
+ ev_window_clear_find_job (ev_window);
+
+ if (search_string && search_string[0]) {
+ ev_window->priv->find_job = ev_job_find_new (ev_window->priv->document,
+ ev_page_cache_get_current_page (ev_window->priv->page_cache),
+ ev_page_cache_get_n_pages (ev_window->priv->page_cache),
+ search_string,
+ case_sensitive);
+ g_signal_connect (ev_window->priv->find_job, "finished",
+ G_CALLBACK (ev_window_find_job_finished_cb),
+ ev_window);
+ g_signal_connect (ev_window->priv->find_job, "updated",
+ G_CALLBACK (ev_window_find_job_updated_cb),
+ ev_window);
+ ev_job_scheduler_push_job (ev_window->priv->find_job, EV_JOB_PRIORITY_NONE);
+ } else {
+ ev_window_update_actions (ev_window);
+ egg_find_bar_set_status_text (EGG_FIND_BAR (ev_window->priv->find_bar),
+ NULL);
+ gtk_widget_queue_draw (GTK_WIDGET (ev_window->priv->view));
+ }
+}
+
+static void
+find_bar_visibility_changed_cb (EggFindBar *find_bar,
+ GParamSpec *param,
+ EvWindow *ev_window)
+{
+ gboolean visible;
+
+ visible = GTK_WIDGET_VISIBLE (find_bar);
+
+ if (ev_window->priv->document &&
+ EV_IS_DOCUMENT_FIND (ev_window->priv->document)) {
+ ev_view_find_set_highlight_search (EV_VIEW (ev_window->priv->view), visible);
+ ev_view_find_search_changed (EV_VIEW (ev_window->priv->view));
+ ev_window_update_actions (ev_window);
+
+ if (visible)
+ find_bar_search_changed_cb (find_bar, NULL, ev_window);
+ else
+ egg_find_bar_set_status_text (EGG_FIND_BAR (ev_window->priv->find_bar), NULL);
+ }
+}
+
+static void
+find_bar_scroll (EggFindBar *find_bar,
+ GtkScrollType scroll,
+ EvWindow *ev_window)
+{
+ ev_view_scroll (EV_VIEW (ev_window->priv->view), scroll, FALSE);
+}
+
+static void
+zoom_control_changed_cb (EphyZoomAction *action,
+ float zoom,
+ EvWindow *ev_window)
+{
+ EvSizingMode mode;
+
+ g_return_if_fail (EV_IS_WINDOW (ev_window));
+
+ if (zoom == EPHY_ZOOM_BEST_FIT) {
+ mode = EV_SIZING_BEST_FIT;
+ } else if (zoom == EPHY_ZOOM_FIT_WIDTH) {
+ mode = EV_SIZING_FIT_WIDTH;
+ } else {
+ mode = EV_SIZING_FREE;
+ }
+
+ ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), mode);
+
+ if (mode == EV_SIZING_FREE) {
+ ev_view_set_zoom (EV_VIEW (ev_window->priv->view),
+ zoom * get_screen_dpi (GTK_WINDOW (ev_window)) / 72.0,
+ FALSE);
+ }
+}
+
+static void
+ev_window_drag_data_received (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time)
+
+{
+ EvWindow *window = EV_WINDOW (widget);
+ gchar **uris;
+ gint i = 0;
+ GSList *uri_list = NULL;
+
+ uris = gtk_selection_data_get_uris (selection_data);
+ if (!uris) {
+ gtk_drag_finish (context, FALSE, FALSE, time);
+ return;
+ }
+
+ for (i = 0; uris[i]; i++) {
+ uri_list = g_slist_prepend (uri_list, (gpointer) uris[i]);
+ }
+
+ ev_application_open_uri_list (EV_APP, uri_list,
+ gtk_window_get_screen (GTK_WINDOW (window)),
+ 0);
+ gtk_drag_finish (context, TRUE, FALSE, time);
+
+ g_strfreev (uris);
+ g_slist_free (uri_list);
+}
+
+static void
+ev_window_finalize (GObject *object)
+{
+ GList *windows = ev_application_get_windows (EV_APP);
+
+ if (windows == NULL) {
+ ev_application_shutdown (EV_APP);
+ } else {
+ g_list_free (windows);
+ }
+
+ G_OBJECT_CLASS (ev_window_parent_class)->finalize (object);
+}
+
+static void
+ev_window_dispose (GObject *object)
+{
+ EvWindow *window = EV_WINDOW (object);
+ EvWindowPrivate *priv = window->priv;
+ GObject *mpkeys = ev_application_get_media_keys (EV_APP);
+
+ if (mpkeys) {
+ g_signal_handlers_disconnect_by_func (mpkeys,
+ ev_window_media_player_key_pressed,
+ window);
+ }
+
+ if (priv->setup_document_idle > 0) {
+ g_source_remove (priv->setup_document_idle);
+ priv->setup_document_idle = 0;
+ }
+
+ if (priv->monitor) {
+ g_object_unref (priv->monitor);
+ priv->monitor = NULL;
+ }
+
+ if (priv->title) {
+ ev_window_title_free (priv->title);
+ priv->title = NULL;
+ }
+
+ if (priv->ui_manager) {
+ g_object_unref (priv->ui_manager);
+ priv->ui_manager = NULL;
+ }
+
+ if (priv->action_group) {
+ g_object_unref (priv->action_group);
+ priv->action_group = NULL;
+ }
+
+ if (priv->view_popup_action_group) {
+ g_object_unref (priv->view_popup_action_group);
+ priv->view_popup_action_group = NULL;
+ }
+
+ if (priv->attachment_popup_action_group) {
+ g_object_unref (priv->attachment_popup_action_group);
+ priv->attachment_popup_action_group = NULL;
+ }
+
+ if (priv->recent_action_group) {
+ g_object_unref (priv->recent_action_group);
+ priv->recent_action_group = NULL;
+ }
+
+ if (priv->recent_manager) {
+ g_signal_handlers_disconnect_by_func (priv->recent_manager,
+ ev_window_setup_recent,
+ window);
+ priv->recent_manager = NULL;
+ }
+
+ priv->recent_ui_id = 0;
+
+ if (priv->page_cache) {
+ g_signal_handlers_disconnect_by_func (priv->page_cache, page_changed_cb, window);
+ priv->page_cache = NULL;
+ }
+
+ if (priv->document) {
+ g_object_unref (priv->document);
+ priv->document = NULL;
+ }
+
+ if (priv->view) {
+ g_object_unref (priv->view);
+ priv->view = NULL;
+ }
+
+ if (priv->password_view) {
+ g_object_unref (priv->password_view);
+ priv->password_view = NULL;
+ }
+
+ if (priv->load_job) {
+ ev_window_clear_load_job (window);
+ }
+
+ if (priv->reload_job) {
+ ev_window_clear_reload_job (window);
+ }
+
+ if (priv->save_job) {
+ ev_window_clear_save_job (window);
+ }
+
+ if (priv->thumbnail_job) {
+ ev_window_clear_thumbnail_job (window);
+ }
+
+ if (priv->find_job) {
+ ev_window_clear_find_job (window);
+ }
+
+ if (priv->local_uri) {
+ ev_window_clear_local_uri (window);
+ priv->local_uri = NULL;
+ }
+
+ ev_window_clear_progress_idle (window);
+ if (priv->progress_cancellable) {
+ g_object_unref (priv->progress_cancellable);
+ priv->progress_cancellable = NULL;
+ }
+
+ ev_window_close_dialogs (window);
+
+ if (window->priv->printer) {
+ g_object_unref (window->priv->printer);
+ window->priv->printer = NULL;
+ }
+
+ if (window->priv->print_settings) {
+ g_object_unref (window->priv->print_settings);
+ window->priv->print_settings = NULL;
+ }
+
+ if (window->priv->print_page_setup) {
+ g_object_unref (window->priv->print_page_setup);
+ window->priv->print_page_setup = NULL;
+ }
+
+ if (priv->link) {
+ g_object_unref (priv->link);
+ priv->link = NULL;
+ }
+
+ if (priv->image) {
+ g_object_unref (priv->image);
+ priv->image = NULL;
+ }
+
+ if (priv->attach_list) {
+ g_list_foreach (priv->attach_list,
+ (GFunc) g_object_unref,
+ NULL);
+ g_list_free (priv->attach_list);
+ priv->attach_list = NULL;
+ }
+
+ if (priv->find_bar) {
+ g_signal_handlers_disconnect_by_func
+ (window->priv->find_bar,
+ G_CALLBACK (find_bar_close_cb),
+ window);
+ priv->find_bar = NULL;
+ }
+
+ if (priv->uri) {
+ if (priv->unlink_temp_file)
+ ev_window_clear_temp_file (window);
+ g_free (priv->uri);
+ priv->uri = NULL;
+ }
+
+ if (priv->search_string) {
+ g_free (priv->search_string);
+ priv->search_string = NULL;
+ }
+
+ if (priv->dest) {
+ g_object_unref (priv->dest);
+ priv->dest = NULL;
+ }
+
+ if (priv->history) {
+ g_object_unref (priv->history);
+ priv->history = NULL;
+ }
+
+ if (priv->print_settings_file) {
+ ev_window_clear_print_settings_file (window);
+ priv->print_settings_file = NULL;
+ }
+
+ if (priv->presentation_timeout_id > 0) {
+ g_source_remove (priv->presentation_timeout_id);
+ priv->presentation_timeout_id = 0;
+ }
+
+ if (priv->print_queue) {
+ g_queue_free (priv->print_queue);
+ priv->print_queue = NULL;
+ }
+
+ G_OBJECT_CLASS (ev_window_parent_class)->dispose (object);
+}
+
+static void
+ev_window_class_init (EvWindowClass *ev_window_class)
+{
+ GObjectClass *g_object_class = G_OBJECT_CLASS (ev_window_class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (ev_window_class);
+
+ g_object_class->dispose = ev_window_dispose;
+ g_object_class->finalize = ev_window_finalize;
+
+ widget_class->screen_changed = ev_window_screen_changed;
+ widget_class->window_state_event = ev_window_state_event;
+ widget_class->drag_data_received = ev_window_drag_data_received;
+
+ g_type_class_add_private (g_object_class, sizeof (EvWindowPrivate));
+}