1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
2 /* this file is part of evince, a gnome document viewer
4 * Copyright (C) 2004 Martin Kretzschmar
5 * Copyright (C) 2004 Red Hat, Inc.
6 * Copyright (C) 2000, 2001, 2002, 2003, 2004 Marco Pesenti Gritti
7 * Copyright (C) 2003, 2004 Christian Persch
10 * Martin Kretzschmar <martink@gnome.org>
12 * Evince is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * Evince is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
31 #include "ev-window.h"
32 #include "ev-page-action.h"
33 #include "ev-sidebar.h"
34 #include "ev-sidebar-links.h"
35 #include "ev-sidebar-thumbnails.h"
37 #include "ev-password.h"
38 #include "ev-password-view.h"
39 #include "ev-print-job.h"
40 #include "ev-document-find.h"
41 #include "ev-document-security.h"
42 #include "eggfindbar.h"
44 #include "pdf-document.h"
45 #include "pixbuf-document.h"
46 #include "ps-document.h"
48 #include <glib/gi18n.h>
51 #include <libgnomevfs/gnome-vfs-mime-utils.h>
52 #include <libgnomeprintui/gnome-print-dialog.h>
56 #include "ev-application.h"
57 #include "ev-stock-icons.h"
60 PAGE_MODE_SINGLE_PAGE,
61 PAGE_MODE_CONTINUOUS_PAGE,
65 struct _EvWindowPrivate {
69 GtkWidget *thumbs_sidebar;
71 GtkWidget *scrolled_window;
73 GtkWidget *password_view;
74 GtkActionGroup *action_group;
75 GtkUIManager *ui_manager;
77 guint help_message_cid;
78 guint view_message_cid;
79 GtkWidget *exit_fullscreen_popup;
84 /* These members are used temporarily when in PAGE_MODE_PASSWORD */
85 EvDocument *password_document;
86 GtkWidget *password_dialog;
89 gboolean fullscreen_mode;
91 #define EV_WINDOW_GET_PRIVATE(object) \
92 (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_WINDOW, EvWindowPrivate))
95 #define PAGE_SELECTOR_ACTION "PageSelector"
98 static void ev_window_update_fullscreen_popup (EvWindow *window);
99 static void ev_window_set_page_mode (EvWindow *window,
100 EvWindowPageMode page_mode);
101 static gboolean start_loading_document (EvWindow *ev_window,
102 EvDocument *document,
106 G_DEFINE_TYPE (EvWindow, ev_window, GTK_TYPE_WINDOW)
109 set_action_sensitive (EvWindow *ev_window,
113 GtkAction *action = gtk_action_group_get_action (ev_window->priv->action_group,
115 gtk_action_set_sensitive (action, sensitive);
119 update_action_sensitivity (EvWindow *ev_window)
121 EvDocument *document;
124 document = ev_window->priv->document;
126 view = EV_VIEW (ev_window->priv->view);
129 /* "FileOpen": always sensitive */
130 set_action_sensitive (ev_window, "FileSaveAs", document!=NULL);
131 set_action_sensitive (ev_window, "FilePrint", document!=NULL);
132 /* "FileCloseWindow": always sensitive */
135 set_action_sensitive (ev_window, "EditCopy", document!=NULL);
136 set_action_sensitive (ev_window, "EditSelectAll", document!=NULL);
139 set_action_sensitive (ev_window, "EditFind", EV_IS_DOCUMENT_FIND (document));
141 set_action_sensitive (ev_window, "EditFind", FALSE);
144 set_action_sensitive (ev_window, "ViewZoomIn", document!=NULL);
145 set_action_sensitive (ev_window, "ViewZoomOut", document!=NULL);
146 set_action_sensitive (ev_window, "ViewNormalSize", document!=NULL);
147 set_action_sensitive (ev_window, "ViewBestFit", document!=NULL);
148 set_action_sensitive (ev_window, "ViewPageWidth", document!=NULL);
155 page = ev_view_get_page (EV_VIEW (ev_window->priv->view));
156 n_pages = ev_document_get_n_pages (document);
158 set_action_sensitive (ev_window, "GoPageUp", page > 1);
159 set_action_sensitive (ev_window, "GoPageDown", page < n_pages);
160 set_action_sensitive (ev_window, "GoFirstPage", page > 1);
161 set_action_sensitive (ev_window, "GoLastPage", page < n_pages);
163 set_action_sensitive (ev_window, "GoFirstPage", FALSE);
164 set_action_sensitive (ev_window, "GoPageUp", FALSE);
165 set_action_sensitive (ev_window, "GoPageDown", FALSE);
166 set_action_sensitive (ev_window, "GoLastPage", FALSE);
170 /* "HelpContents": always sensitive */
171 /* "HelpAbout": always sensitive */
173 /* Toolbar-specific actions: */
174 set_action_sensitive (ev_window, PAGE_SELECTOR_ACTION, document!=NULL);
178 ev_window_open_page (EvWindow *ev_window, int page)
180 ev_view_set_page (EV_VIEW (ev_window->priv->view), page);
184 ev_window_open_link (EvWindow *ev_window, EvLink *link)
186 ev_view_go_to_link (EV_VIEW (ev_window->priv->view), link);
190 ev_window_is_empty (const EvWindow *ev_window)
192 g_return_val_if_fail (EV_IS_WINDOW (ev_window), FALSE);
194 return ev_window->priv->document == NULL;
198 unable_to_load (EvWindow *ev_window,
199 const char *error_message)
203 dialog = gtk_message_dialog_new (GTK_WINDOW (ev_window),
204 GTK_DIALOG_DESTROY_WITH_PARENT,
207 _("Unable to open document"));
208 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
209 "%s", error_message);
210 gtk_dialog_run (GTK_DIALOG (dialog));
211 gtk_widget_destroy (dialog);
214 /* Would be nice to have this in gdk-pixbuf */
216 mime_type_supported_by_gdk_pixbuf (const gchar *mime_type)
218 GSList *formats, *list;
219 gboolean retval = FALSE;
221 formats = gdk_pixbuf_get_formats ();
225 GdkPixbufFormat *format = list->data;
229 if (gdk_pixbuf_format_is_disabled (format))
232 mime_types = gdk_pixbuf_format_get_mime_types (format);
234 for (i = 0; mime_types[i] != NULL; i++) {
235 if (strcmp (mime_types[i], mime_type) == 0) {
247 g_slist_free (formats);
253 update_window_title (EvDocument *document, GParamSpec *pspec, EvWindow *ev_window)
256 char *doc_title = NULL;
257 gboolean password_needed;
259 password_needed = (ev_window->priv->password_document != NULL);
262 doc_title = ev_document_get_title (document);
264 /* Make sure we get a valid title back */
266 if (doc_title[0] == '\000' ||
267 !g_utf8_validate (doc_title, -1, NULL)) {
273 if (doc_title == NULL && ev_window->priv->uri) {
274 doc_title = g_path_get_basename (ev_window->priv->uri);
277 if (password_needed) {
278 if (doc_title == NULL) {
279 title = g_strdup (_("Document Viewer - Password Required"));
281 title = g_strdup_printf (_("%s - Password Required"), doc_title);
284 if (doc_title == NULL) {
285 title = g_strdup (_("Document Viewer"));
287 title = g_strdup (doc_title);
291 gtk_window_set_title (GTK_WINDOW (ev_window), title);
298 update_total_pages (EvWindow *ev_window)
303 pages = ev_document_get_n_pages (ev_window->priv->document);
304 action = gtk_action_group_get_action
305 (ev_window->priv->action_group, PAGE_SELECTOR_ACTION);
306 ev_page_action_set_total_pages (EV_PAGE_ACTION (action), pages);
309 /* This function assumes that ev_window just had ev_window->document set.
312 ev_window_setup_document (EvWindow *ev_window)
314 EvDocument *document;
315 EvView *view = EV_VIEW (ev_window->priv->view);
316 EvSidebar *sidebar = EV_SIDEBAR (ev_window->priv->sidebar);
318 document = ev_window->priv->document;
320 g_signal_connect_object (G_OBJECT (document),
322 G_CALLBACK (update_window_title),
325 ev_window_set_page_mode (ev_window, PAGE_MODE_SINGLE_PAGE);
327 ev_sidebar_set_document (sidebar, document);
328 ev_view_set_document (view, document);
330 update_window_title (ev_window->priv->document, NULL, ev_window);
331 update_total_pages (ev_window);
332 update_action_sensitivity (ev_window);
336 password_dialog_response (GtkWidget *password_dialog,
342 if (response_id == GTK_RESPONSE_OK) {
343 EvDocument *document;
346 password = ev_password_dialog_get_password (password_dialog);
348 ev_document_security_set_password (EV_DOCUMENT_SECURITY (ev_window->priv->password_document),
352 document = ev_window->priv->password_document;
353 uri = ev_window->priv->password_uri;
355 ev_window->priv->password_document = NULL;
356 ev_window->priv->password_uri = NULL;
358 if (start_loading_document (ev_window, document, uri)) {
359 gtk_widget_destroy (password_dialog);
362 g_object_unref (document);
368 gtk_widget_set_sensitive (ev_window->priv->password_view, TRUE);
369 gtk_widget_destroy (password_dialog);
372 /* Called either by start_loading_document or by the "unlock" callback on the
373 * password_view page. It assumes that ev_window->priv->password_* has been set
374 * correctly. These are cleared by password_dialog_response() */
377 ev_window_popup_password_dialog (EvWindow *ev_window)
379 g_assert (ev_window->priv->password_document);
380 g_assert (ev_window->priv->password_uri);
382 gtk_widget_set_sensitive (ev_window->priv->password_view, FALSE);
384 update_window_title (ev_window->priv->password_document, NULL, ev_window);
385 if (ev_window->priv->password_dialog == NULL) {
388 file_name = g_path_get_basename (ev_window->priv->password_uri);
389 ev_window->priv->password_dialog =
390 ev_password_dialog_new (GTK_WIDGET (ev_window), file_name);
391 g_object_add_weak_pointer (G_OBJECT (ev_window->priv->password_dialog),
392 (gpointer *) &(ev_window->priv->password_dialog));
393 g_signal_connect (ev_window->priv->password_dialog,
395 G_CALLBACK (password_dialog_response),
398 gtk_widget_show (ev_window->priv->password_dialog);
400 ev_password_dialog_set_bad_pass (ev_window->priv->password_dialog);
404 /* This wil try to load the document. It might be called multiple times on the
405 * same document by the password dialog.
407 * Since the flow of the error dialog is very confusing, we assume that both
408 * document and uri will go away after this function is called, and thus we need
409 * to ref/dup them. Additionally, it needs to clear
410 * ev_window->priv->password_{uri,document}, and thus people who call this
411 * function should _not_ necessarily expect those to exist after being
414 start_loading_document (EvWindow *ev_window,
415 EvDocument *document,
419 GError *error = NULL;
422 g_assert (document != ev_window->priv->document);
424 if (ev_window->priv->password_document) {
425 g_object_unref (ev_window->priv->password_document);
426 ev_window->priv->password_document = NULL;
428 if (ev_window->priv->password_uri) {
429 g_free (ev_window->priv->password_uri);
430 ev_window->priv->password_uri = NULL;
433 result = ev_document_load (document, uri, &error);
437 if (ev_window->priv->document)
438 g_object_unref (ev_window->priv->document);
439 ev_window->priv->document = g_object_ref (document);
440 ev_window_setup_document (ev_window);
445 /* unable to load the document */
446 g_assert (error != NULL);
448 if (error->domain == EV_DOCUMENT_ERROR &&
449 error->code == EV_DOCUMENT_ERROR_ENCRYPTED) {
452 ev_window->priv->password_document = g_object_ref (document);
453 ev_window->priv->password_uri = g_strdup (uri);
455 file_name = g_path_get_basename (uri);
456 ev_password_view_set_file_name (EV_PASSWORD_VIEW (ev_window->priv->password_view),
459 ev_window_set_page_mode (ev_window, PAGE_MODE_PASSWORD);
461 ev_window_popup_password_dialog (ev_window);
463 unable_to_load (ev_window, error->message);
465 g_error_free (error);
471 ev_window_open (EvWindow *ev_window, const char *uri)
473 EvDocument *document = NULL;
476 g_free (ev_window->priv->uri);
477 ev_window->priv->uri = g_strdup (uri);
479 mime_type = gnome_vfs_get_mime_type (uri);
481 if (mime_type == NULL)
483 else if (!strcmp (mime_type, "application/pdf"))
484 document = g_object_new (PDF_TYPE_DOCUMENT, NULL);
485 else if (!strcmp (mime_type, "application/postscript"))
486 document = g_object_new (PS_TYPE_DOCUMENT, NULL);
487 else if (mime_type_supported_by_gdk_pixbuf (mime_type))
488 document = g_object_new (PIXBUF_TYPE_DOCUMENT, NULL);
491 start_loading_document (ev_window, document, uri);
492 /* See the comment on start_loading_document on ref counting.
493 * As the password dialog flow is confusing, we're very explicit
494 * on ref counting. */
495 g_object_unref (document);
499 error_message = g_strdup_printf (_("Unhandled MIME type: '%s'"),
500 mime_type?mime_type:"<Unknown MIME Type>");
501 unable_to_load (ev_window, error_message);
502 g_free (error_message);
509 ev_window_cmd_file_open (GtkAction *action, EvWindow *ev_window)
511 ev_application_open (EV_APP, NULL);
516 overwrite_existing_file (GtkWindow *window, const gchar *file_name)
519 gchar *utf8_file_name;
523 utf8_file_name = g_filename_to_utf8 (file_name, -1, NULL, NULL, NULL);
524 msgbox = gtk_message_dialog_new (
526 (GtkDialogFlags)GTK_DIALOG_DESTROY_WITH_PARENT,
527 GTK_MESSAGE_QUESTION,
529 _("A file named \"%s\" already exists."),
531 g_free (utf8_file_name);
533 gtk_message_dialog_format_secondary_text (
534 GTK_MESSAGE_DIALOG (msgbox),
535 _("Do you want to replace it with the one you are saving?"));
537 gtk_dialog_add_button (GTK_DIALOG (msgbox),
538 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
540 gtk_dialog_add_button (GTK_DIALOG (msgbox),
541 _("_Replace"), GTK_RESPONSE_YES);
543 gtk_dialog_set_default_response (GTK_DIALOG (msgbox),
544 GTK_RESPONSE_CANCEL);
546 obj = gtk_widget_get_accessible (msgbox);
548 if (GTK_IS_ACCESSIBLE (obj))
549 atk_object_set_name (obj, _("Question"));
551 ret = gtk_dialog_run (GTK_DIALOG (msgbox));
552 gtk_widget_destroy (msgbox);
554 return (ret == GTK_RESPONSE_YES);
559 save_error_dialog (GtkWindow *window, const gchar *file_name)
561 GtkWidget *error_dialog;
563 error_dialog = gtk_message_dialog_new (
565 (GtkDialogFlags)GTK_DIALOG_DESTROY_WITH_PARENT,
568 _("The file could not be saved as \"%s\"."),
571 /* Easy way to make the text bold while keeping the string
572 * above free from pango markup (FIXME ?) */
573 gtk_message_dialog_format_secondary_text (
574 GTK_MESSAGE_DIALOG (error_dialog), " ");
576 gtk_dialog_run (GTK_DIALOG (error_dialog));
577 gtk_widget_destroy (error_dialog);
581 ev_window_cmd_save_as (GtkAction *action, EvWindow *ev_window)
584 GtkFileFilter *pdf_filter, *all_filter;
587 fc = gtk_file_chooser_dialog_new (
589 NULL, GTK_FILE_CHOOSER_ACTION_SAVE,
590 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
591 GTK_STOCK_SAVE, GTK_RESPONSE_OK,
593 gtk_window_set_modal (GTK_WINDOW (fc), TRUE);
595 pdf_filter = gtk_file_filter_new ();
596 gtk_file_filter_set_name (pdf_filter, _("PDF Documents"));
597 gtk_file_filter_add_mime_type (pdf_filter, "application/pdf");
598 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (fc), pdf_filter);
600 all_filter = gtk_file_filter_new ();
601 gtk_file_filter_set_name (all_filter, _("All Files"));
602 gtk_file_filter_add_pattern (all_filter, "*");
603 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (fc), all_filter);
604 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (fc), pdf_filter);
606 gtk_dialog_set_default_response (GTK_DIALOG (fc), GTK_RESPONSE_OK);
608 gtk_widget_show (fc);
610 while (gtk_dialog_run (GTK_DIALOG (fc)) == GTK_RESPONSE_OK) {
611 uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (fc));
614 if (g_file_test (uri, G_FILE_TEST_EXISTS) &&
615 !overwrite_existing_file (GTK_WINDOW (fc), uri))
619 if (ev_document_save (ev_window->priv->document, uri, NULL))
622 save_error_dialog (GTK_WINDOW (fc), uri);
624 gtk_widget_destroy (fc);
628 using_postscript_printer (GnomePrintConfig *config)
630 const guchar *driver;
631 const guchar *transport;
633 driver = gnome_print_config_get (
634 config, (const guchar *)"Settings.Engine.Backend.Driver");
636 transport = gnome_print_config_get (
637 config, (const guchar *)"Settings.Transport.Backend");
640 if (!strcmp ((const gchar *)driver, "gnome-print-ps"))
644 } else if (transport) {
645 if (!strcmp ((const gchar *)transport, "CUPS"))
653 ev_window_print (EvWindow *ev_window)
655 GnomePrintConfig *config;
657 GtkWidget *print_dialog;
658 EvPrintJob *print_job = NULL;
660 g_return_if_fail (EV_IS_WINDOW (ev_window));
661 g_return_if_fail (ev_window->priv->document != NULL);
663 config = gnome_print_config_default ();
664 job = gnome_print_job_new (config);
666 print_dialog = gnome_print_dialog_new (job, _("Print"),
667 (GNOME_PRINT_DIALOG_RANGE |
668 GNOME_PRINT_DIALOG_COPIES));
669 gtk_dialog_set_response_sensitive (GTK_DIALOG (print_dialog),
670 GNOME_PRINT_DIALOG_RESPONSE_PREVIEW,
675 response = gtk_dialog_run (GTK_DIALOG (print_dialog));
677 if (response != GNOME_PRINT_DIALOG_RESPONSE_PRINT)
680 /* FIXME: Change this when we have the first backend
681 * that can print more than postscript
683 if (!using_postscript_printer (config)) {
686 dialog = gtk_message_dialog_new (
687 GTK_WINDOW (print_dialog), GTK_DIALOG_MODAL,
688 GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
689 _("Printing is not supported on this printer."));
690 gtk_message_dialog_format_secondary_text (
691 GTK_MESSAGE_DIALOG (dialog),
692 _("You were trying to print to a printer using the \"%s\" driver. This program requires a PostScript printer driver."),
693 gnome_print_config_get (
694 config, "Settings.Engine.Backend.Driver"));
695 gtk_dialog_run (GTK_DIALOG (dialog));
696 gtk_widget_destroy (dialog);
701 print_job = g_object_new (EV_TYPE_PRINT_JOB,
702 "gnome_print_job", job,
703 "document", ev_window->priv->document,
704 "print_dialog", print_dialog,
709 gtk_widget_destroy (print_dialog);
711 if (print_job != NULL) {
712 ev_print_job_print (print_job, GTK_WINDOW (ev_window));
713 g_object_unref (print_job);
718 ev_window_cmd_file_print (GtkAction *action, EvWindow *ev_window)
720 ev_window_print (ev_window);
724 ev_window_cmd_file_close_window (GtkAction *action, EvWindow *ev_window)
726 g_return_if_fail (EV_IS_WINDOW (ev_window));
728 gtk_widget_destroy (GTK_WIDGET (ev_window));
732 find_not_supported_dialog (EvWindow *ev_window)
736 /* If you change this so it isn't modal, be sure you don't
737 * allow multiple copies of the dialog...
740 dialog = gtk_message_dialog_new (GTK_WINDOW (ev_window),
741 GTK_DIALOG_DESTROY_WITH_PARENT,
744 _("The \"Find\" feature will not work with this document"));
745 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
746 _("Searching for text is only supported for PDF documents."));
747 gtk_dialog_run (GTK_DIALOG (dialog));
748 gtk_widget_destroy (dialog);
752 ev_window_cmd_edit_select_all (GtkAction *action, EvWindow *ev_window)
754 g_return_if_fail (EV_IS_WINDOW (ev_window));
756 ev_view_select_all (EV_VIEW (ev_window->priv->view));
760 ev_window_cmd_edit_find (GtkAction *action, EvWindow *ev_window)
762 g_return_if_fail (EV_IS_WINDOW (ev_window));
764 if (ev_window->priv->document == NULL) {
765 g_printerr ("We should have set the Find menu item insensitive since there's no document\n");
766 } else if (!EV_IS_DOCUMENT_FIND (ev_window->priv->document)) {
767 find_not_supported_dialog (ev_window);
769 gtk_widget_show (ev_window->priv->find_bar);
771 if (ev_window->priv->exit_fullscreen_popup)
772 ev_window_update_fullscreen_popup (ev_window);
774 egg_find_bar_grab_focus (EGG_FIND_BAR (ev_window->priv->find_bar));
779 ev_window_cmd_edit_copy (GtkAction *action, EvWindow *ev_window)
781 g_return_if_fail (EV_IS_WINDOW (ev_window));
783 ev_view_copy (EV_VIEW (ev_window->priv->view));
787 ev_window_update_fullscreen_popup (EvWindow *window)
789 GtkWidget *popup = window->priv->exit_fullscreen_popup;
790 int popup_width, popup_height;
791 GdkRectangle screen_rect;
793 g_return_if_fail (popup != NULL);
798 popup_width = popup->requisition.width;
799 popup_height = popup->requisition.height;
801 /* FIXME multihead */
802 gdk_screen_get_monitor_geometry (gdk_screen_get_default (),
803 gdk_screen_get_monitor_at_window
804 (gdk_screen_get_default (),
805 GTK_WIDGET (window)->window),
808 if (GTK_WIDGET_VISIBLE (window->priv->find_bar)) {
811 gtk_widget_size_request (window->priv->find_bar, &req);
813 screen_rect.height -= req.height;
816 if (gtk_widget_get_direction (popup) == GTK_TEXT_DIR_RTL)
818 gtk_window_move (GTK_WINDOW (popup),
819 screen_rect.x + screen_rect.width - popup_width,
820 screen_rect.height - popup_height);
824 gtk_window_move (GTK_WINDOW (popup),
825 screen_rect.x, screen_rect.height - popup_height);
830 screen_size_changed_cb (GdkScreen *screen,
833 ev_window_update_fullscreen_popup (window);
837 destroy_exit_fullscreen_popup (EvWindow *window)
839 if (window->priv->exit_fullscreen_popup != NULL)
841 /* FIXME multihead */
842 g_signal_handlers_disconnect_by_func
843 (gdk_screen_get_default (),
844 G_CALLBACK (screen_size_changed_cb), window);
846 gtk_widget_destroy (window->priv->exit_fullscreen_popup);
847 window->priv->exit_fullscreen_popup = NULL;
852 exit_fullscreen_button_clicked_cb (GtkWidget *button, EvWindow *window)
856 action = gtk_action_group_get_action (window->priv->action_group, "ViewFullscreen");
857 g_return_if_fail (action != NULL);
859 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
863 fullscreen_popup_size_request_cb (GtkWidget *popup, GtkRequisition *req, EvWindow *window)
865 ev_window_update_fullscreen_popup (window);
869 ev_window_fullscreen (EvWindow *window)
871 GtkWidget *popup, *button, *icon, *label, *hbox, *main_menu;
873 window->priv->fullscreen_mode = TRUE;
875 popup = gtk_window_new (GTK_WINDOW_POPUP);
876 window->priv->exit_fullscreen_popup = popup;
878 button = gtk_button_new ();
879 g_signal_connect (button, "clicked",
880 G_CALLBACK (exit_fullscreen_button_clicked_cb),
882 gtk_widget_show (button);
883 gtk_container_add (GTK_CONTAINER (popup), button);
885 hbox = gtk_hbox_new (FALSE, 2);
886 gtk_widget_show (hbox);
887 gtk_container_add (GTK_CONTAINER (button), hbox);
889 icon = gtk_image_new_from_stock (GTK_STOCK_QUIT, GTK_ICON_SIZE_BUTTON);
890 gtk_widget_show (icon);
891 gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
893 label = gtk_label_new (_("Exit Fullscreen"));
894 gtk_widget_show (label);
895 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
897 gtk_window_set_resizable (GTK_WINDOW (popup), FALSE);
899 /* FIXME multihead */
900 g_signal_connect (gdk_screen_get_default (), "size-changed",
901 G_CALLBACK (screen_size_changed_cb), window);
902 g_signal_connect (popup, "size_request",
903 G_CALLBACK (fullscreen_popup_size_request_cb), window);
905 main_menu = gtk_ui_manager_get_widget (window->priv->ui_manager, "/MainMenu");
906 gtk_widget_hide (main_menu);
907 gtk_widget_hide (window->priv->statusbar);
909 ev_window_update_fullscreen_popup (window);
911 gtk_widget_show (popup);
915 ev_window_unfullscreen (EvWindow *window)
917 GtkWidget *main_menu;
919 window->priv->fullscreen_mode = FALSE;
921 main_menu = gtk_ui_manager_get_widget (window->priv->ui_manager, "/MainMenu");
922 gtk_widget_show (main_menu);
923 gtk_widget_show (window->priv->statusbar);
925 destroy_exit_fullscreen_popup (window);
929 ev_window_cmd_view_fullscreen (GtkAction *action, EvWindow *ev_window)
933 g_return_if_fail (EV_IS_WINDOW (ev_window));
935 fullscreen = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
938 gtk_window_fullscreen (GTK_WINDOW (ev_window));
940 gtk_window_unfullscreen (GTK_WINDOW (ev_window));
945 ev_window_state_event_cb (GtkWidget *widget, GdkEventWindowState *event, EvWindow *window)
947 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)
949 GtkActionGroup *action_group;
953 fullscreen = event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN;
957 ev_window_fullscreen (window);
961 ev_window_unfullscreen (window);
964 action_group = window->priv->action_group;
966 action = gtk_action_group_get_action (action_group, "ViewFullscreen");
967 g_signal_handlers_block_by_func
968 (action, G_CALLBACK (ev_window_cmd_view_fullscreen), window);
969 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), fullscreen);
970 g_signal_handlers_unblock_by_func
971 (action, G_CALLBACK (ev_window_cmd_view_fullscreen), window);
979 ev_window_focus_out_cb (GtkWidget *widget, GdkEventFocus *event, EvWindow *ev_window)
981 gtk_window_unfullscreen (GTK_WINDOW (ev_window));
987 ev_window_set_page_mode (EvWindow *window,
988 EvWindowPageMode page_mode)
990 GtkWidget *child = NULL;
991 GtkWidget *real_child;
994 case PAGE_MODE_SINGLE_PAGE:
995 child = window->priv->view;
997 case PAGE_MODE_PASSWORD:
998 child = window->priv->password_view;
1001 g_warning ("page_mode not implemented yet\n");
1002 g_assert_not_reached ();
1004 real_child = gtk_bin_get_child (GTK_BIN (window->priv->scrolled_window));
1005 if (child != real_child) {
1006 gtk_container_remove (GTK_CONTAINER (window->priv->scrolled_window),
1008 gtk_container_add (GTK_CONTAINER (window->priv->scrolled_window),
1014 ev_window_cmd_view_zoom_in (GtkAction *action, EvWindow *ev_window)
1016 g_return_if_fail (EV_IS_WINDOW (ev_window));
1018 ev_view_zoom_in (EV_VIEW (ev_window->priv->view));
1022 ev_window_cmd_view_zoom_out (GtkAction *action, EvWindow *ev_window)
1024 g_return_if_fail (EV_IS_WINDOW (ev_window));
1026 ev_view_zoom_out (EV_VIEW (ev_window->priv->view));
1030 ev_window_cmd_view_normal_size (GtkAction *action, EvWindow *ev_window)
1032 g_return_if_fail (EV_IS_WINDOW (ev_window));
1034 ev_view_normal_size (EV_VIEW (ev_window->priv->view));
1038 ev_window_cmd_view_best_fit (GtkAction *action, EvWindow *ev_window)
1040 g_return_if_fail (EV_IS_WINDOW (ev_window));
1042 ev_view_best_fit (EV_VIEW (ev_window->priv->view));
1046 ev_window_cmd_view_page_width (GtkAction *action, EvWindow *ev_window)
1048 g_return_if_fail (EV_IS_WINDOW (ev_window));
1050 ev_view_fit_width (EV_VIEW (ev_window->priv->view));
1054 ev_window_cmd_go_page_up (GtkAction *action, EvWindow *ev_window)
1056 g_return_if_fail (EV_IS_WINDOW (ev_window));
1058 ev_view_set_page (EV_VIEW (ev_window->priv->view),
1059 ev_view_get_page (EV_VIEW (ev_window->priv->view)) - 1);
1063 ev_window_cmd_go_page_down (GtkAction *action, EvWindow *ev_window)
1065 g_return_if_fail (EV_IS_WINDOW (ev_window));
1067 ev_view_set_page (EV_VIEW (ev_window->priv->view),
1068 ev_view_get_page (EV_VIEW (ev_window->priv->view)) + 1);
1072 ev_window_cmd_go_first_page (GtkAction *action, EvWindow *ev_window)
1074 g_return_if_fail (EV_IS_WINDOW (ev_window));
1076 ev_view_set_page (EV_VIEW (ev_window->priv->view), 1);
1080 ev_window_cmd_go_last_page (GtkAction *action, EvWindow *ev_window)
1082 g_return_if_fail (EV_IS_WINDOW (ev_window));
1084 ev_view_set_page (EV_VIEW (ev_window->priv->view), G_MAXINT);
1088 ev_window_cmd_help_contents (GtkAction *action, EvWindow *ev_window)
1090 g_return_if_fail (EV_IS_WINDOW (ev_window));
1096 ev_window_cmd_help_about (GtkAction *action, EvWindow *ev_window)
1098 const char *authors[] = {
1103 const char *documenters[] = {
1104 N_("Not so many..."),
1108 const char *license[] = {
1109 N_("Evince is free software; you can redistribute it and/or modify\n"
1110 "it under the terms of the GNU General Public License as published by\n"
1111 "the Free Software Foundation; either version 2 of the License, or\n"
1112 "(at your option) any later version.\n"),
1113 N_("Evince is distributed in the hope that it will be useful,\n"
1114 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
1115 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
1116 "GNU General Public License for more details.\n"),
1117 N_("You should have received a copy of the GNU General Public License\n"
1118 "along with Evince; if not, write to the Free Software Foundation, Inc.,\n"
1119 "59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n")
1122 char *license_trans;
1127 for (p = authors; *p; ++p)
1130 for (p = documenters; *p; ++p)
1134 license_trans = g_strconcat (_(license[0]), "\n", _(license[1]), "\n",
1135 _(license[2]), "\n", NULL);
1137 gtk_show_about_dialog (
1138 GTK_WINDOW (ev_window),
1139 "name", _("Evince"),
1142 _("\xc2\xa9 1996-2004 The Evince authors"),
1143 "license", license_trans,
1144 "website", "http://www.gnome.org/projects/evince",
1145 "comments", _("PostScript and PDF File Viewer."),
1147 "documenters", documenters,
1148 "translator-credits", _("translator-credits"),
1151 g_free (license_trans);
1155 ev_window_view_toolbar_cb (GtkAction *action, EvWindow *ev_window)
1158 G_OBJECT (gtk_ui_manager_get_widget (
1159 ev_window->priv->ui_manager,
1162 gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)),
1167 ev_window_view_statusbar_cb (GtkAction *action, EvWindow *ev_window)
1170 ev_window->priv->statusbar,
1172 gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)),
1177 ev_window_view_sidebar_cb (GtkAction *action, EvWindow *ev_window)
1180 ev_window->priv->sidebar,
1182 gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)),
1187 menu_item_select_cb (GtkMenuItem *proxy, EvWindow *ev_window)
1192 action = g_object_get_data (G_OBJECT (proxy), "gtk-action");
1193 g_return_if_fail (action != NULL);
1195 g_object_get (G_OBJECT (action), "tooltip", &message, NULL);
1197 gtk_statusbar_push (GTK_STATUSBAR (ev_window->priv->statusbar),
1198 ev_window->priv->help_message_cid, message);
1204 menu_item_deselect_cb (GtkMenuItem *proxy, EvWindow *ev_window)
1206 gtk_statusbar_pop (GTK_STATUSBAR (ev_window->priv->statusbar),
1207 ev_window->priv->help_message_cid);
1211 connect_proxy_cb (GtkUIManager *ui_manager, GtkAction *action,
1212 GtkWidget *proxy, EvWindow *ev_window)
1214 if (GTK_IS_MENU_ITEM (proxy)) {
1215 g_signal_connect (proxy, "select",
1216 G_CALLBACK (menu_item_select_cb), ev_window);
1217 g_signal_connect (proxy, "deselect",
1218 G_CALLBACK (menu_item_deselect_cb),
1224 disconnect_proxy_cb (GtkUIManager *ui_manager, GtkAction *action,
1225 GtkWidget *proxy, EvWindow *ev_window)
1227 if (GTK_IS_MENU_ITEM (proxy)) {
1228 g_signal_handlers_disconnect_by_func
1229 (proxy, G_CALLBACK (menu_item_select_cb), ev_window);
1230 g_signal_handlers_disconnect_by_func
1231 (proxy, G_CALLBACK (menu_item_deselect_cb), ev_window);
1236 update_current_page (EvWindow *ev_window,
1241 EvSidebarThumbnails *thumbs;
1243 thumbs = EV_SIDEBAR_THUMBNAILS (ev_window->priv->thumbs_sidebar);
1244 ev_sidebar_thumbnails_select_page (thumbs, ev_view_get_page (view));
1246 action = gtk_action_group_get_action
1247 (ev_window->priv->action_group, PAGE_SELECTOR_ACTION);
1249 page = ev_view_get_page (EV_VIEW (ev_window->priv->view));
1250 ev_page_action_set_current_page (EV_PAGE_ACTION (action), page);
1254 view_page_changed_cb (EvView *view,
1255 EvWindow *ev_window)
1257 update_current_page (ev_window, view);
1258 update_action_sensitivity (ev_window);
1262 view_status_changed_cb (EvView *view,
1264 EvWindow *ev_window)
1266 const char *message;
1268 gtk_statusbar_pop (GTK_STATUSBAR (ev_window->priv->statusbar),
1269 ev_window->priv->view_message_cid);
1271 message = ev_view_get_status (view);
1273 gtk_statusbar_push (GTK_STATUSBAR (ev_window->priv->statusbar),
1274 ev_window->priv->view_message_cid, message);
1279 view_find_status_changed_cb (EvView *view,
1281 EvWindow *ev_window)
1285 text = ev_view_get_find_status (view);
1286 egg_find_bar_set_status_text (EGG_FIND_BAR (ev_window->priv->find_bar),
1291 find_bar_previous_cb (EggFindBar *find_bar,
1292 EvWindow *ev_window)
1294 ev_view_find_previous (EV_VIEW (ev_window->priv->view));
1298 find_bar_next_cb (EggFindBar *find_bar,
1299 EvWindow *ev_window)
1301 ev_view_find_next (EV_VIEW (ev_window->priv->view));
1305 find_bar_close_cb (EggFindBar *find_bar,
1306 EvWindow *ev_window)
1308 gtk_widget_hide (ev_window->priv->find_bar);
1310 if (ev_window->priv->exit_fullscreen_popup)
1311 ev_window_update_fullscreen_popup (ev_window);
1315 find_bar_search_changed_cb (EggFindBar *find_bar,
1317 EvWindow *ev_window)
1319 gboolean case_sensitive;
1321 const char *search_string;
1323 g_return_if_fail (EV_IS_WINDOW (ev_window));
1325 /* Either the string or case sensitivity could have changed,
1326 * we connect this callback to both. We also connect it
1327 * to ::visible so when the find bar is hidden, we should
1328 * pretend the search string is NULL/""
1331 case_sensitive = egg_find_bar_get_case_sensitive (find_bar);
1332 visible = GTK_WIDGET_VISIBLE (find_bar);
1333 search_string = egg_find_bar_get_search_string (find_bar);
1336 g_printerr ("search for '%s'\n", search_string ? search_string : "(nil)");
1339 if (ev_window->priv->document &&
1340 EV_IS_DOCUMENT_FIND (ev_window->priv->document)) {
1341 if (visible && search_string) {
1342 ev_document_find_begin (EV_DOCUMENT_FIND (ev_window->priv->document), search_string, case_sensitive);
1344 ev_document_find_cancel (EV_DOCUMENT_FIND (ev_window->priv->document));
1345 egg_find_bar_set_status_text (EGG_FIND_BAR (ev_window->priv->find_bar),
1352 ev_window_dispose (GObject *object)
1354 EvWindowPrivate *priv;
1356 g_return_if_fail (object != NULL && EV_IS_WINDOW (object));
1358 priv = EV_WINDOW (object)->priv;
1360 if (priv->ui_manager) {
1361 g_object_unref (priv->ui_manager);
1362 priv->ui_manager = NULL;
1365 if (priv->action_group) {
1366 g_object_unref (priv->action_group);
1367 priv->action_group = NULL;
1370 if (priv->document) {
1371 g_object_unref (priv->document);
1372 priv->document = NULL;
1375 if (priv->password_document) {
1376 g_object_unref (priv->password_document);
1377 priv->password_document = NULL;
1380 if (priv->password_uri) {
1381 g_free (priv->password_uri);
1382 priv->password_uri = NULL;
1385 G_OBJECT_CLASS (ev_window_parent_class)->dispose (object);
1389 ev_window_class_init (EvWindowClass *ev_window_class)
1391 GObjectClass *g_object_class;
1393 g_object_class = G_OBJECT_CLASS (ev_window_class);
1394 g_object_class->dispose = ev_window_dispose;
1396 g_type_class_add_private (g_object_class, sizeof (EvWindowPrivate));
1401 static GtkActionEntry entries[] = {
1402 { "File", NULL, N_("_File") },
1403 { "Edit", NULL, N_("_Edit") },
1404 { "View", NULL, N_("_View") },
1405 { "Go", NULL, N_("_Go") },
1406 { "Help", NULL, N_("_Help") },
1409 { "FileOpen", GTK_STOCK_OPEN, N_("_Open"), "<control>O",
1411 G_CALLBACK (ev_window_cmd_file_open) },
1412 { "FileSaveAs", GTK_STOCK_SAVE_AS, N_("_Save a Copy..."), NULL,
1413 N_("Save the current document with a new filename"),
1414 G_CALLBACK (ev_window_cmd_save_as) },
1415 { "FilePrint", GTK_STOCK_PRINT, N_("_Print"), "<control>P",
1416 N_("Print this document"),
1417 G_CALLBACK (ev_window_cmd_file_print) },
1418 { "FileCloseWindow", GTK_STOCK_CLOSE, N_("_Close"), "<control>W",
1419 N_("Close this window"),
1420 G_CALLBACK (ev_window_cmd_file_close_window) },
1423 { "EditCopy", GTK_STOCK_COPY, N_("_Copy"), "<control>C",
1424 N_("Copy text from the document"),
1425 G_CALLBACK (ev_window_cmd_edit_copy) },
1426 { "EditSelectAll", NULL, N_("Select _All"), "<control>A",
1427 N_("Select the entire page"),
1428 G_CALLBACK (ev_window_cmd_edit_select_all) },
1429 { "EditFind", GTK_STOCK_FIND, N_("_Find"), "<control>F",
1430 N_("Find a word or phrase in the document"),
1431 G_CALLBACK (ev_window_cmd_edit_find) },
1434 { "ViewZoomIn", GTK_STOCK_ZOOM_IN, N_("Zoom _In"), "<control>plus",
1435 N_("Enlarge the document"),
1436 G_CALLBACK (ev_window_cmd_view_zoom_in) },
1437 { "ViewZoomOut", GTK_STOCK_ZOOM_OUT, N_("Zoom _Out"), "<control>minus",
1438 N_("Shrink the document"),
1439 G_CALLBACK (ev_window_cmd_view_zoom_out) },
1440 { "ViewNormalSize", GTK_STOCK_ZOOM_100, N_("_Normal Size"), "<control>0",
1441 N_("Zoom to the normal size"),
1442 G_CALLBACK (ev_window_cmd_view_normal_size) },
1443 { "ViewBestFit", GTK_STOCK_ZOOM_FIT, N_("_Best Fit"), NULL,
1444 N_("Zoom to fit the document to the current window"),
1445 G_CALLBACK (ev_window_cmd_view_best_fit) },
1446 { "ViewPageWidth", EV_STOCK_ZOOM_FIT_WIDTH, N_("Fit Page _Width"), NULL,
1447 N_("Zoom to fit the width of the current window "),
1448 G_CALLBACK (ev_window_cmd_view_page_width) },
1451 { "GoPageUp", GTK_STOCK_GO_UP, N_("_Page Up"), "<control>Page_Up",
1452 N_("Go to the previous page"),
1453 G_CALLBACK (ev_window_cmd_go_page_up) },
1454 { "GoPageDown", GTK_STOCK_GO_DOWN, N_("_Page Down"), "<control>Page_Down",
1455 N_("Go to the next page"),
1456 G_CALLBACK (ev_window_cmd_go_page_down) },
1457 { "GoFirstPage", GTK_STOCK_GOTO_FIRST, N_("_First Page"), "<control>Home",
1458 N_("Go to the first page"),
1459 G_CALLBACK (ev_window_cmd_go_first_page) },
1460 { "GoLastPage", GTK_STOCK_GOTO_LAST, N_("_Last Page"), "<control>End",
1461 N_("Go to the last page"),
1462 G_CALLBACK (ev_window_cmd_go_last_page) },
1465 { "HelpContents", GTK_STOCK_HELP, N_("_Contents"), NULL,
1466 N_("Display help for the viewer application"),
1467 G_CALLBACK (ev_window_cmd_help_contents) },
1469 { "HelpAbout", GTK_STOCK_ABOUT, N_("_About"), NULL,
1470 N_("Display credits for the document viewer creators"),
1471 G_CALLBACK (ev_window_cmd_help_about) },
1475 static GtkToggleActionEntry toggle_entries[] = {
1477 { "ViewToolbar", NULL, N_("_Toolbar"), "<shift><control>T",
1478 N_("Show or hide toolbar"),
1479 G_CALLBACK (ev_window_view_toolbar_cb), TRUE },
1480 { "ViewStatusbar", NULL, N_("_Statusbar"), NULL,
1481 N_("Show or hide statusbar"),
1482 G_CALLBACK (ev_window_view_statusbar_cb), TRUE },
1483 { "ViewSidebar", NULL, N_("Side_bar"), "F9",
1484 N_("Show or hide sidebar"),
1485 G_CALLBACK (ev_window_view_sidebar_cb), TRUE },
1486 { "ViewFullscreen", NULL, N_("_Fullscreen"), "F11",
1487 N_("Expand the window to fill the screen"),
1488 G_CALLBACK (ev_window_cmd_view_fullscreen) },
1492 goto_page_cb (GtkAction *action, int page_number, EvWindow *ev_window)
1494 EvView *view = EV_VIEW (ev_window->priv->view);
1496 if (ev_view_get_page (view) != page_number) {
1497 ev_view_set_page (view, page_number);
1502 register_custom_actions (EvWindow *window, GtkActionGroup *group)
1506 action = g_object_new (EV_TYPE_PAGE_ACTION,
1507 "name", PAGE_SELECTOR_ACTION,
1509 "tooltip", _("Select Page"),
1511 g_signal_connect (action, "goto_page",
1512 G_CALLBACK (goto_page_cb), window);
1513 gtk_action_group_add_action (group, action);
1514 g_object_unref (action);
1518 set_short_labels (GtkActionGroup *action_group)
1522 action = gtk_action_group_get_action (action_group, "GoPageUp");
1523 g_object_set (action, "short_label", _("Up"), NULL);
1524 action = gtk_action_group_get_action (action_group, "GoPageDown");
1525 g_object_set (action, "short_label", _("Down"), NULL);
1526 action = gtk_action_group_get_action (action_group, "ViewPageWidth");
1527 g_object_set (action, "short_label", _("Fit Width"), NULL);
1531 ev_window_init (EvWindow *ev_window)
1533 GtkActionGroup *action_group;
1534 GtkAccelGroup *accel_group;
1535 GError *error = NULL;
1538 GtkWidget *sidebar_widget;
1540 ev_window->priv = EV_WINDOW_GET_PRIVATE (ev_window);
1542 update_window_title (NULL, NULL, ev_window);
1544 ev_window->priv->main_box = gtk_vbox_new (FALSE, 0);
1545 gtk_container_add (GTK_CONTAINER (ev_window), ev_window->priv->main_box);
1546 gtk_widget_show (ev_window->priv->main_box);
1548 action_group = gtk_action_group_new ("MenuActions");
1549 ev_window->priv->action_group = action_group;
1550 gtk_action_group_set_translation_domain (action_group, NULL);
1551 gtk_action_group_add_actions (action_group, entries,
1552 G_N_ELEMENTS (entries), ev_window);
1553 gtk_action_group_add_toggle_actions (action_group, toggle_entries,
1554 G_N_ELEMENTS (toggle_entries),
1556 set_short_labels (action_group);
1557 register_custom_actions (ev_window, action_group);
1559 ev_window->priv->ui_manager = gtk_ui_manager_new ();
1560 gtk_ui_manager_insert_action_group (ev_window->priv->ui_manager,
1564 gtk_ui_manager_get_accel_group (ev_window->priv->ui_manager);
1565 gtk_window_add_accel_group (GTK_WINDOW (ev_window), accel_group);
1567 g_signal_connect (ev_window->priv->ui_manager, "connect_proxy",
1568 G_CALLBACK (connect_proxy_cb), ev_window);
1569 g_signal_connect (ev_window->priv->ui_manager, "disconnect_proxy",
1570 G_CALLBACK (disconnect_proxy_cb), ev_window);
1572 if (!gtk_ui_manager_add_ui_from_file (ev_window->priv->ui_manager,
1573 DATADIR"/evince-ui.xml",
1575 g_message ("building menus failed: %s", error->message);
1576 g_error_free (error);
1579 menubar = gtk_ui_manager_get_widget (ev_window->priv->ui_manager,
1581 gtk_box_pack_start (GTK_BOX (ev_window->priv->main_box), menubar,
1584 toolbar = gtk_ui_manager_get_widget (ev_window->priv->ui_manager,
1586 gtk_box_pack_start (GTK_BOX (ev_window->priv->main_box), toolbar,
1589 /* Add the main area */
1590 ev_window->priv->hpaned = gtk_hpaned_new ();
1591 gtk_widget_show (ev_window->priv->hpaned);
1592 gtk_box_pack_start (GTK_BOX (ev_window->priv->main_box), ev_window->priv->hpaned,
1595 ev_window->priv->sidebar = ev_sidebar_new ();
1596 gtk_widget_show (ev_window->priv->sidebar);
1597 gtk_paned_add1 (GTK_PANED (ev_window->priv->hpaned),
1598 ev_window->priv->sidebar);
1600 /* Stub sidebar, for now */
1601 sidebar_widget = ev_sidebar_links_new ();
1602 gtk_widget_show (sidebar_widget);
1603 ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar),
1608 ev_window->priv->thumbs_sidebar = ev_sidebar_thumbnails_new ();
1609 gtk_widget_show (ev_window->priv->thumbs_sidebar);
1610 ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar),
1613 ev_window->priv->thumbs_sidebar);
1615 ev_window->priv->scrolled_window =
1616 GTK_WIDGET (g_object_new (GTK_TYPE_SCROLLED_WINDOW,
1617 "hscrollbar-policy", GTK_POLICY_AUTOMATIC,
1618 "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
1619 "shadow-type", GTK_SHADOW_IN,
1621 gtk_widget_show (ev_window->priv->scrolled_window);
1623 gtk_paned_add2 (GTK_PANED (ev_window->priv->hpaned),
1624 ev_window->priv->scrolled_window);
1626 ev_window->priv->view = ev_view_new ();
1627 ev_window->priv->password_view = ev_password_view_new ();
1628 g_signal_connect_swapped (ev_window->priv->password_view,
1630 G_CALLBACK (ev_window_popup_password_dialog),
1632 gtk_widget_show (ev_window->priv->view);
1633 gtk_widget_show (ev_window->priv->password_view);
1634 /* We own a ref on these widgets, as we can swap them in and out */
1635 g_object_ref (ev_window->priv->view);
1636 g_object_ref (ev_window->priv->password_view);
1638 gtk_container_add (GTK_CONTAINER (ev_window->priv->scrolled_window),
1639 ev_window->priv->view);
1640 g_signal_connect (ev_window->priv->view,
1642 G_CALLBACK (view_page_changed_cb),
1644 g_signal_connect (ev_window->priv->view,
1645 "notify::find-status",
1646 G_CALLBACK (view_find_status_changed_cb),
1648 g_signal_connect (ev_window->priv->view,
1650 G_CALLBACK (view_status_changed_cb),
1653 ev_window->priv->statusbar = gtk_statusbar_new ();
1654 gtk_widget_show (ev_window->priv->statusbar);
1655 gtk_box_pack_end (GTK_BOX (ev_window->priv->main_box),
1656 ev_window->priv->statusbar,
1658 ev_window->priv->help_message_cid = gtk_statusbar_get_context_id
1659 (GTK_STATUSBAR (ev_window->priv->statusbar), "help_message");
1660 ev_window->priv->view_message_cid = gtk_statusbar_get_context_id
1661 (GTK_STATUSBAR (ev_window->priv->statusbar), "view_message");
1663 ev_window->priv->find_bar = egg_find_bar_new ();
1664 gtk_box_pack_end (GTK_BOX (ev_window->priv->main_box),
1665 ev_window->priv->find_bar,
1668 /* Connect to find bar signals */
1669 g_signal_connect (ev_window->priv->find_bar,
1671 G_CALLBACK (find_bar_previous_cb),
1673 g_signal_connect (ev_window->priv->find_bar,
1675 G_CALLBACK (find_bar_next_cb),
1677 g_signal_connect (ev_window->priv->find_bar,
1679 G_CALLBACK (find_bar_close_cb),
1681 g_signal_connect (ev_window->priv->find_bar,
1682 "notify::search-string",
1683 G_CALLBACK (find_bar_search_changed_cb),
1685 g_signal_connect (ev_window->priv->find_bar,
1686 "notify::case-sensitive",
1687 G_CALLBACK (find_bar_search_changed_cb),
1689 g_signal_connect (ev_window->priv->find_bar,
1691 G_CALLBACK (find_bar_search_changed_cb),
1694 g_signal_connect (ev_window, "window-state-event",
1695 G_CALLBACK (ev_window_state_event_cb),
1697 g_signal_connect (ev_window, "focus_out_event",
1698 G_CALLBACK (ev_window_focus_out_cb),
1701 /* Give focus to the scrolled window */
1702 gtk_widget_grab_focus (ev_window->priv->scrolled_window);
1704 update_action_sensitivity (ev_window);