+ if (EV_IS_DOCUMENT_FIND (document)) {
+ g_signal_connect_object (G_OBJECT (document),
+ "find_changed",
+ G_CALLBACK (find_changed_cb),
+ ev_window, 0);
+ }
+
+ ev_sidebar_set_document (sidebar, document);
+
+ if (ev_page_cache_get_n_pages (ev_window->priv->page_cache) > 0) {
+ ev_view_set_document (view, document);
+ }
+ ev_window_set_page_mode (ev_window, PAGE_MODE_DOCUMENT);
+
+ ev_window_title_set_document (ev_window->priv->title, document);
+ ev_window_title_set_uri (ev_window->priv->title, ev_window->priv->uri);
+
+ action = gtk_action_group_get_action (ev_window->priv->action_group, PAGE_SELECTOR_ACTION);
+ ev_page_action_set_document (EV_PAGE_ACTION (action), document);
+ update_action_sensitivity (ev_window);
+
+ if (ev_window->priv->properties) {
+ ev_properties_dialog_set_document (EV_PROPERTIES_DIALOG (ev_window->priv->properties),
+ ev_window->priv->document);
+ }
+
+ setup_document_from_metadata (ev_window);
+ setup_sidebar_from_metadata (ev_window, document);
+
+ info = ev_page_cache_get_info (ev_window->priv->page_cache);
+ update_document_mode (ev_window, info->mode);
+}
+
+static void
+password_dialog_response (GtkWidget *password_dialog,
+ gint response_id,
+ EvWindow *ev_window)
+{
+ char *password;
+
+ if (response_id == GTK_RESPONSE_OK) {
+
+ password = ev_password_dialog_get_password (EV_PASSWORD_DIALOG (password_dialog));
+ if (password) {
+ ev_document_doc_mutex_lock ();
+ ev_document_security_set_password (EV_DOCUMENT_SECURITY (ev_window->priv->password_document),
+ password);
+ ev_document_doc_mutex_unlock ();
+ }
+ g_free (password);
+
+ ev_password_dialog_save_password (EV_PASSWORD_DIALOG (password_dialog));
+
+ g_object_unref (ev_window->priv->password_document);
+ ev_window->priv->password_document = NULL;
+
+ ev_window_title_set_type (ev_window->priv->title, EV_WINDOW_TITLE_DOCUMENT);
+ ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH);
+
+ gtk_widget_destroy (password_dialog);
+
+ return;
+ }
+
+ gtk_widget_set_sensitive (ev_window->priv->password_view, TRUE);
+ gtk_widget_destroy (password_dialog);
+}
+
+/* Called either by ev_window_load_job_cb or by the "unlock" callback on the
+ * password_view page. It assumes that ev_window->priv->password_* has been set
+ * correctly. These are cleared by password_dialog_response() */
+
+static void
+ev_window_popup_password_dialog (EvWindow *ev_window)
+{
+ g_assert (ev_window->priv->password_document);
+
+ gtk_widget_set_sensitive (ev_window->priv->password_view, FALSE);
+
+ ev_window_title_set_uri (ev_window->priv->title, ev_window->priv->uri);
+ ev_window_title_set_type (ev_window->priv->title, EV_WINDOW_TITLE_PASSWORD);
+
+ if (ev_window->priv->password_dialog == NULL) {
+ ev_window->priv->password_dialog =
+ g_object_new (EV_TYPE_PASSWORD_DIALOG, "uri", ev_window->priv->uri, NULL);
+ gtk_window_set_transient_for (GTK_WINDOW (ev_window->priv->password_dialog), GTK_WINDOW (ev_window));
+
+ g_object_add_weak_pointer (G_OBJECT (ev_window->priv->password_dialog),
+ (gpointer *) &(ev_window->priv->password_dialog));
+ g_signal_connect (ev_window->priv->password_dialog,
+ "response",
+ G_CALLBACK (password_dialog_response),
+ ev_window);
+ gtk_widget_show (ev_window->priv->password_dialog);
+ } else {
+ ev_password_dialog_set_bad_pass (EV_PASSWORD_DIALOG (ev_window->priv->password_dialog));
+ }
+}
+
+
+static void
+ev_window_clear_jobs (EvWindow *ev_window)
+{
+ if (ev_window->priv->load_job != NULL) {
+
+ if (!ev_window->priv->load_job->finished)
+ ev_job_queue_remove_job (ev_window->priv->load_job);
+
+ g_signal_handlers_disconnect_by_func (ev_window->priv->load_job, ev_window_load_job_cb, ev_window);
+ g_object_unref (ev_window->priv->load_job);
+ ev_window->priv->load_job = NULL;
+ }
+
+ if (ev_window->priv->xfer_job != NULL) {
+
+ if (!ev_window->priv->xfer_job->finished)
+ ev_job_queue_remove_job (ev_window->priv->xfer_job);
+
+ g_signal_handlers_disconnect_by_func (ev_window->priv->xfer_job, ev_window_xfer_job_cb, ev_window);
+ g_object_unref (ev_window->priv->xfer_job);
+ ev_window->priv->xfer_job = NULL;
+ }
+}
+
+static void
+ev_window_clear_local_uri (EvWindow *ev_window)
+{
+ char *filename;
+
+ if (ev_window->priv->local_uri) {
+ filename = g_filename_from_uri (ev_window->priv->local_uri, NULL, NULL);
+ if (filename != NULL) {
+ unlink (filename);
+ g_free (filename);
+ }
+ g_free (ev_window->priv->local_uri);
+ ev_window->priv->local_uri = NULL;
+ }
+}
+
+/* This callback will executed when load job will be finished.
+ *
+ * Since the flow of the error dialog is very confusing, we assume that both
+ * document and uri will go away after this function is called, and thus we need
+ * to ref/dup them. Additionally, it needs to clear
+ * ev_window->priv->password_{uri,document}, and thus people who call this
+ * function should _not_ necessarily expect those to exist after being
+ * called. */
+static void
+ev_window_load_job_cb (EvJobLoad *job,
+ gpointer data)
+{
+ EvWindow *ev_window = EV_WINDOW (data);
+ EvDocument *document = EV_JOB (job)->document;
+
+ g_assert (document);
+ g_assert (document != ev_window->priv->document);
+ g_assert (job->uri);
+
+ ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE);
+
+ if (ev_window->priv->password_document) {
+ g_object_unref (ev_window->priv->password_document);
+ ev_window->priv->password_document = NULL;
+ }
+
+ /* Success! */
+ if (job->error == NULL) {
+
+ if (ev_window->priv->document)
+ g_object_unref (ev_window->priv->document);
+ ev_window->priv->document = g_object_ref (document);
+
+ ev_window_setup_document (ev_window);
+ ev_window_add_recent (ev_window, ev_window->priv->uri);
+ ev_window_clear_jobs (ev_window);
+
+ return;
+ }
+
+ if (job->error->domain == EV_DOCUMENT_ERROR &&
+ job->error->code == EV_DOCUMENT_ERROR_ENCRYPTED) {
+ gchar *base_name, *file_name;
+
+ ev_window->priv->password_document = g_object_ref (document);
+
+ file_name = gnome_vfs_format_uri_for_display (job->uri);
+ base_name = g_path_get_basename (file_name);
+ ev_password_view_set_file_name (EV_PASSWORD_VIEW (ev_window->priv->password_view),
+ base_name);
+ g_free (file_name);
+ g_free (base_name);
+ ev_window_set_page_mode (ev_window, PAGE_MODE_PASSWORD);
+
+ ev_window_popup_password_dialog (ev_window);
+ } else {
+ unable_to_load (ev_window, job->error->message);
+ }
+
+ return;
+}
+
+static void
+ev_window_xfer_job_cb (EvJobXfer *job,
+ gpointer data)
+{
+ EvWindow *ev_window = EV_WINDOW (data);
+
+
+
+ if (job->error != NULL) {
+ unable_to_load (ev_window, job->error->message);
+ ev_window_clear_jobs (ev_window);
+ ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE);
+ } else {
+ char *uri;
+
+ EvDocument *document = g_object_ref (EV_JOB (job)->document);
+
+ if (job->local_uri) {
+ ev_window->priv->local_uri = g_strdup (job->local_uri);
+ uri = ev_window->priv->local_uri;
+ } else {
+ ev_window->priv->local_uri = NULL;
+ uri = ev_window->priv->uri;
+ }
+
+ ev_window_clear_jobs (ev_window);
+
+ ev_window->priv->load_job = ev_job_load_new (document, uri);
+ g_signal_connect (ev_window->priv->load_job,
+ "finished",
+ G_CALLBACK (ev_window_load_job_cb),
+ ev_window);
+ ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH);
+ g_object_unref (document);
+ }
+}
+
+const char *
+ev_window_get_uri (EvWindow *ev_window)
+{
+ return ev_window->priv->uri;
+}
+
+static void
+ev_window_close_dialogs (EvWindow *ev_window)
+{
+ if (ev_window->priv->password_dialog)
+ gtk_widget_destroy (ev_window->priv->password_dialog);
+ ev_window->priv->password_dialog = NULL;
+
+#ifdef WITH_GNOME_PRINT
+ if (ev_window->priv->print_dialog) {
+ gtk_widget_destroy (ev_window->priv->print_dialog);
+ g_object_unref (ev_window->priv->print_job);
+ }
+ ev_window->priv->print_dialog = NULL;
+ ev_window->priv->print_job = NULL;
+#endif
+
+ if (ev_window->priv->properties)
+ gtk_widget_destroy (ev_window->priv->properties);
+ ev_window->priv->properties = NULL;
+}
+
+void
+ev_window_open_uri (EvWindow *ev_window, const char *uri)
+{
+
+ g_free (ev_window->priv->uri);
+ ev_window->priv->uri = g_strdup (uri);
+
+ setup_view_from_metadata (ev_window);
+
+ ev_window_close_dialogs (ev_window);
+ ev_window_clear_jobs (ev_window);
+ ev_window_clear_local_uri (ev_window);
+ ev_view_set_loading (EV_VIEW (ev_window->priv->view), TRUE);
+
+ ev_window->priv->xfer_job = ev_job_xfer_new (uri);
+ g_signal_connect (ev_window->priv->xfer_job,
+ "finished",
+ G_CALLBACK (ev_window_xfer_job_cb),
+ ev_window);
+ ev_job_queue_add_job (ev_window->priv->xfer_job, EV_JOB_PRIORITY_HIGH);
+}
+
+static void
+file_open_dialog_response_cb (GtkWidget *chooser,
+ gint response_id,
+ EvWindow *ev_window)
+{
+ if (response_id == GTK_RESPONSE_OK) {
+ GSList *uris;
+
+ uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (chooser));
+
+ ev_application_open_uri_list (EV_APP, uris, GDK_CURRENT_TIME);
+
+ g_slist_foreach (uris, (GFunc)g_free, NULL);
+ g_slist_free (uris);
+ }
+ ev_application_set_chooser_uri (EV_APP,
+ gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (chooser)));
+
+ gtk_widget_destroy (chooser);
+}
+
+static void
+ev_window_cmd_file_open (GtkAction *action, EvWindow *window)
+{
+ GtkWidget *chooser;
+
+ chooser = gtk_file_chooser_dialog_new (_("Open Document"),
+ GTK_WINDOW (window),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_OK,
+ NULL);
+
+ ev_document_types_add_filters (chooser, NULL);
+ gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (chooser), TRUE);
+ gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (chooser), FALSE);
+ if (ev_application_get_chooser_uri (EV_APP) != NULL)
+ gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (chooser),
+ ev_application_get_chooser_uri (EV_APP));
+
+ g_signal_connect (chooser, "response",
+ G_CALLBACK (file_open_dialog_response_cb),
+ window);
+
+ gtk_widget_show (chooser);
+}
+
+static void
+ev_window_cmd_recent_file_activate (GtkAction *action,
+ EvWindow *ev_window)
+{
+ char *uri;
+ EggRecentItem *item;
+
+ item = egg_recent_view_uimanager_get_item (ev_window->priv->recent_view,
+ action);
+
+ uri = egg_recent_item_get_uri (item);
+
+ ev_application_open_uri (EV_APP, uri, NULL, GDK_CURRENT_TIME, NULL);
+
+ g_free (uri);
+}
+
+static void
+ev_window_add_recent (EvWindow *window, const char *filename)
+{
+ EggRecentItem *item;
+
+ item = egg_recent_item_new_from_uri (filename);
+ egg_recent_item_add_group (item, "Evince");
+ egg_recent_model_add_full (ev_application_get_recent_model (EV_APP), item);
+}
+
+static void
+ev_window_setup_recent (EvWindow *ev_window)
+{
+
+ ev_window->priv->recent_view = egg_recent_view_uimanager_new (ev_window->priv->ui_manager,
+ "/MainMenu/FileMenu/RecentFilesMenu",
+ G_CALLBACK (ev_window_cmd_recent_file_activate),
+ ev_window);
+
+ egg_recent_view_uimanager_show_icons (EGG_RECENT_VIEW_UIMANAGER (ev_window->priv->recent_view), FALSE);
+
+ egg_recent_view_set_model (EGG_RECENT_VIEW (ev_window->priv->recent_view),
+ ev_application_get_recent_model (EV_APP));
+
+ egg_recent_view_uimanager_set_trailing_sep (ev_window->priv->recent_view, TRUE);
+
+ g_signal_connect (ev_window->priv->recent_view, "activate",
+ G_CALLBACK (ev_window_cmd_recent_file_activate), ev_window);
+}
+
+static void
+save_error_dialog (GtkWindow *window, const gchar *file_name)
+{
+ GtkWidget *error_dialog;
+
+ error_dialog = gtk_message_dialog_new (
+ window,
+ (GtkDialogFlags)GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ _("The file could not be saved as \"%s\"."),
+ file_name);
+
+ /* Easy way to make the text bold while keeping the string
+ * above free from pango markup (FIXME ?) */
+ gtk_message_dialog_format_secondary_text (