X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;ds=sidebyside;f=shell%2Fev-window.c;h=d8d48ab13e39d456c8f89202c8f2e32357503f03;hb=f343927df4325959193353c52cff1ea4b20b2286;hp=4684f7996fbf7d3ff0b3cb35e8fdcee8a08cac7a;hpb=4bd52a8c2ee4b1c15b932ba06fb96a66225e1fce;p=evince.git diff --git a/shell/ev-window.c b/shell/ev-window.c index 4684f799..d8d48ab1 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -66,15 +66,13 @@ #include "ev-history.h" #include "ev-image.h" #include "ev-message-area.h" +#include "ev-mount-operation.h" +#include "ev-file-monitor.h" +#ifdef ENABLE_DBUS +#include "ev-media-player-keys.h" +#endif /* ENABLE_DBUS */ -#ifdef WITH_GNOME_PRINT -#include "ev-print-job.h" -#include -#endif - -#ifdef WITH_GTK_PRINT #include -#endif #ifdef ENABLE_PDF #include @@ -128,9 +126,7 @@ struct _EvWindowPrivate { /* Dialogs */ GtkWidget *properties; -#ifdef WITH_PRINT GtkWidget *print_dialog; -#endif GtkWidget *password_dialog; /* UI Builders */ @@ -167,6 +163,7 @@ struct _EvWindowPrivate { EvLinkDest *dest; gboolean unlink_temp_file; gboolean in_reload; + EvFileMonitor *monitor; EvDocument *document; EvHistory *history; @@ -174,21 +171,19 @@ struct _EvWindowPrivate { EvWindowPageMode page_mode; EvWindowTitle *title; - EvJob *load_job; - EvJob *thumbnail_job; - EvJob *save_job; -#ifdef WITH_GNOME_PRINT - GnomePrintJob *print_job; -#endif - -#ifdef WITH_GTK_PRINT + EvJob *load_job; + EvJob *reload_job; + EvJob *thumbnail_job; + EvJob *save_job; EvJob *print_job; + + /* Printing */ gboolean print_preview; GtkPrintJob *gtk_print_job; GtkPrinter *printer; GtkPrintSettings *print_settings; GtkPageSetup *print_page_setup; -#endif + }; #define EV_WINDOW_GET_PRIVATE(object) \ @@ -209,7 +204,6 @@ struct _EvWindowPrivate { #define THUMBNAILS_SIDEBAR_ID "thumbnails" #define ATTACHMENTS_SIDEBAR_ID "attachments" -#ifdef WITH_GTK_PRINT static const gchar *document_print_settings[] = { GTK_PRINT_SETTINGS_N_COPIES, GTK_PRINT_SETTINGS_COLLATE, @@ -220,7 +214,6 @@ static const gchar *document_print_settings[] = { GTK_PRINT_SETTINGS_PAGE_RANGES, GTK_PRINT_SETTINGS_PAGE_SET }; -#endif /* WITH_GTK_PRINT */ static void ev_window_update_actions (EvWindow *ev_window); static void ev_window_sidebar_visibility_changed_cb (EvSidebar *ev_sidebar, @@ -230,12 +223,13 @@ static void ev_window_set_page_mode (EvWindow *windo EvWindowPageMode page_mode); static void ev_window_load_job_cb (EvJobLoad *job, gpointer data); +static void ev_window_reload_document (EvWindow *window); +static void ev_window_reload_job_cb (EvJobLoad *job, + EvWindow *window); static void ev_window_set_icon_from_thumbnail (EvJobThumbnail *job, EvWindow *ev_window); -#ifdef WITH_GTK_PRINT static void ev_window_print_job_cb (EvJobPrint *job, EvWindow *window); -#endif static void ev_window_save_job_cb (EvJobSave *save, EvWindow *window); static void ev_window_sizing_mode_changed_cb (EvView *view, @@ -247,11 +241,13 @@ static void ev_window_zoom_changed_cb (EvView *view, static void ev_window_add_recent (EvWindow *window, const char *filename); static void ev_window_run_fullscreen (EvWindow *window); -static void ev_window_stop_fullscreen (EvWindow *window); +static void ev_window_stop_fullscreen (EvWindow *window, + gboolean unfullscreen_window); static void ev_window_cmd_view_fullscreen (GtkAction *action, EvWindow *window); static void ev_window_run_presentation (EvWindow *window); -static void ev_window_stop_presentation (EvWindow *window); +static void ev_window_stop_presentation (EvWindow *window, + gboolean unfullscreen_window); static void ev_window_cmd_view_presentation (GtkAction *action, EvWindow *window); static void ev_window_run_preview (EvWindow *window); @@ -281,6 +277,9 @@ static void ev_window_cmd_edit_find (GtkAction *actio static void find_bar_search_changed_cb (EggFindBar *find_bar, GParamSpec *param, EvWindow *ev_window); +static void ev_window_do_preview_print (EvWindow *window); +static void ev_window_load_file_remote (EvWindow *ev_window, + GFile *source_file); G_DEFINE_TYPE (EvWindow, ev_window, GTK_TYPE_WINDOW) @@ -353,24 +352,13 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) if (gconf_client_get_bool (client, GCONF_LOCKDOWN_PRINT, NULL)) { ok_to_print = FALSE; } -#ifndef WITH_PRINT - ok_to_print = FALSE; -#endif - g_object_unref (client); + g_object_unref (client); /* File menu */ ev_window_set_action_sensitive (ev_window, "FileOpenCopy", has_document); ev_window_set_action_sensitive (ev_window, "FileSaveAs", has_document && ok_to_copy); - -#ifdef WITH_GTK_PRINT ev_window_set_action_sensitive (ev_window, "FilePrintSetup", has_pages && ok_to_print); -#endif - -#ifdef WITH_GNOME_PRINT - ev_window_set_action_sensitive (ev_window, "FilePrintSetup", FALSE); -#endif - ev_window_set_action_sensitive (ev_window, "FilePrint", has_pages && ok_to_print); ev_window_set_action_sensitive (ev_window, "FileProperties", has_document && has_properties); @@ -646,9 +634,9 @@ ev_window_set_message_area (EvWindow *window, } static void -ev_window_error_message_response_cb (EvMessageArea *area, - gint response_id, - EvWindow *window) +ev_window_message_area_response_cb (EvMessageArea *area, + gint response_id, + EvWindow *window) { ev_window_set_message_area (window, NULL); } @@ -669,7 +657,28 @@ ev_window_error_message (GtkWindow *window, const gchar *msg, GError *error) if (error) ev_message_area_set_secondary_text (EV_MESSAGE_AREA (area), error->message); g_signal_connect (area, "response", - G_CALLBACK (ev_window_error_message_response_cb), + G_CALLBACK (ev_window_message_area_response_cb), + window); + gtk_widget_show (area); + ev_window_set_message_area (EV_WINDOW (window), area); +} + +static void +ev_window_warning_message (GtkWindow *window, const gchar *msg) +{ + GtkWidget *area; + + if (EV_WINDOW (window)->priv->message_area) + return; + + area = ev_message_area_new (GTK_MESSAGE_WARNING, + msg, + GTK_STOCK_CLOSE, + GTK_RESPONSE_CANCEL, + NULL); + + g_signal_connect (area, "response", + G_CALLBACK (ev_window_message_area_response_cb), window); gtk_widget_show (area); ev_window_set_message_area (EV_WINDOW (window), area); @@ -1096,13 +1105,12 @@ ev_window_set_icon_from_thumbnail (EvJobThumbnail *job, static void ev_window_refresh_window_thumbnail (EvWindow *ev_window, int rotation) { - - EvRenderContext *rc; gint page_width, page_height; gdouble scale; EvDocument *document = ev_window->priv->document; - if (!EV_IS_DOCUMENT_THUMBNAILS (document)) { + if (!EV_IS_DOCUMENT_THUMBNAILS (document) || + ev_page_cache_get_n_pages (ev_window->priv->page_cache) <= 0) { return; } @@ -1113,14 +1121,11 @@ ev_window_refresh_window_thumbnail (EvWindow *ev_window, int rotation) &page_width, &page_height); scale = (gdouble)128 / (gdouble)page_width; - rc = ev_render_context_new (rotation, 0, scale); - - ev_window->priv->thumbnail_job = ev_job_thumbnail_new (document, rc); + ev_window->priv->thumbnail_job = ev_job_thumbnail_new (document, 0, rotation, scale); g_signal_connect (ev_window->priv->thumbnail_job, "finished", G_CALLBACK (ev_window_set_icon_from_thumbnail), ev_window); ev_job_queue_add_job (EV_JOB (ev_window->priv->thumbnail_job), EV_JOB_PRIORITY_LOW); - g_object_unref (rc); } static gboolean @@ -1190,11 +1195,21 @@ ev_window_set_document (EvWindow *ev_window, EvDocument *document) if (ev_page_cache_get_n_pages (ev_window->priv->page_cache) > 0) { ev_view_set_document (view, document); + } else { + ev_window_warning_message (GTK_WINDOW (ev_window), + _("The document contains no pages")); } g_idle_add ((GSourceFunc)ev_window_setup_document, ev_window); } +static void +ev_window_document_changed (EvWindow *ev_window, + gpointer user_data) +{ + ev_window_reload_document (ev_window); +} + static void password_dialog_response (GtkWidget *password_dialog, gint response_id, @@ -1272,6 +1287,20 @@ ev_window_clear_load_job (EvWindow *ev_window) } } +static void +ev_window_clear_reload_job (EvWindow *ev_window) +{ + if (ev_window->priv->reload_job != NULL) { + + if (!ev_window->priv->reload_job->finished) + ev_job_queue_remove_job (ev_window->priv->reload_job); + + g_signal_handlers_disconnect_by_func (ev_window->priv->reload_job, ev_window_reload_job_cb, ev_window); + g_object_unref (ev_window->priv->reload_job); + ev_window->priv->reload_job = NULL; + } +} + static void ev_window_clear_local_uri (EvWindow *ev_window) { @@ -1303,7 +1332,7 @@ ev_window_clear_temp_file (EvWindow *ev_window) file = g_file_new_for_uri (ev_window->priv->uri); tempdir = g_file_new_for_path (g_get_tmp_dir ()); - if (g_file_contains_file (tempdir, file)) { + if (g_file_has_prefix (file, tempdir)) { g_file_delete (file, NULL, NULL); } @@ -1327,7 +1356,7 @@ ev_window_load_job_cb (EvJobLoad *job, EvDocument *document = EV_JOB (job)->document; g_assert (job->uri); - + ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE); /* Success! */ @@ -1366,23 +1395,19 @@ ev_window_load_job_cb (EvJobLoad *job, break; } - /* Restart the search after reloading */ - if (ev_window->priv->in_reload) { - GtkWidget *widget; - - widget = gtk_window_get_focus (GTK_WINDOW (ev_window)); - if (widget && gtk_widget_get_ancestor (widget, EGG_TYPE_FIND_BAR)) { - find_bar_search_changed_cb (EGG_FIND_BAR (ev_window->priv->find_bar), - NULL, ev_window); - } - } else if (job->search_string && EV_IS_DOCUMENT_FIND (document)) { + if (job->search_string && EV_IS_DOCUMENT_FIND (document)) { ev_window_cmd_edit_find (NULL, ev_window); egg_find_bar_set_search_string (EGG_FIND_BAR (ev_window->priv->find_bar), job->search_string); } + /* Create a monitor for the document */ + ev_window->priv->monitor = ev_file_monitor_new (job->uri); + g_signal_connect_swapped (G_OBJECT (ev_window->priv->monitor), "changed", + G_CALLBACK (ev_window_document_changed), + ev_window); + ev_window_clear_load_job (ev_window); - ev_window->priv->in_reload = FALSE; return; } @@ -1407,10 +1432,32 @@ ev_window_load_job_cb (EvJobLoad *job, _("Unable to open document"), job->error); ev_window_clear_load_job (ev_window); - ev_window->priv->in_reload = FALSE; } +} - return; +static void +ev_window_reload_job_cb (EvJobLoad *job, + EvWindow *ev_window) +{ + GtkWidget *widget; + + if (job->error) { + ev_window_clear_reload_job (ev_window); + ev_window->priv->in_reload = FALSE; + return; + } + + ev_window_set_document (ev_window, EV_JOB (job)->document); + + /* Restart the search after reloading */ + widget = gtk_window_get_focus (GTK_WINDOW (ev_window)); + if (widget && gtk_widget_get_ancestor (widget, EGG_TYPE_FIND_BAR)) { + find_bar_search_changed_cb (EGG_FIND_BAR (ev_window->priv->find_bar), + NULL, ev_window); + } + + ev_window_clear_reload_job (ev_window); + ev_window->priv->in_reload = FALSE; } /** @@ -1441,31 +1488,111 @@ ev_window_close_dialogs (EvWindow *ev_window) gtk_widget_destroy (ev_window->priv->password_dialog); ev_window->priv->password_dialog = NULL; -#ifdef WITH_PRINT if (ev_window->priv->print_dialog) gtk_widget_destroy (ev_window->priv->print_dialog); ev_window->priv->print_dialog = NULL; -#endif - -#ifdef WITH_GNOME_PRINT - if (ev_window->priv->print_job) - g_object_unref (ev_window->priv->print_job); - ev_window->priv->print_job = NULL; -#endif if (ev_window->priv->properties) gtk_widget_destroy (ev_window->priv->properties); ev_window->priv->properties = NULL; } +static void +ev_window_load_remote_failed (EvWindow *ev_window, + GError *error) +{ + ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE); + ev_window->priv->in_reload = FALSE; + ev_window_error_message (GTK_WINDOW (ev_window), + _("Unable to open document"), + error); + g_free (ev_window->priv->local_uri); + ev_window->priv->local_uri = NULL; +} + +static void +mount_volume_ready_cb (GFile *source, + GAsyncResult *async_result, + EvWindow *ev_window) +{ + GError *error = NULL; + + g_file_mount_enclosing_volume_finish (source, async_result, &error); + + if (error) { + ev_window_load_remote_failed (ev_window, error); + g_object_unref (source); + g_error_free (error); + } else { + /* Volume successfully mounted, + try opening the file again */ + ev_window_load_file_remote (ev_window, source); + } +} + static void window_open_file_copy_ready_cb (GFile *source, GAsyncResult *async_result, EvWindow *ev_window) { - g_file_copy_finish (source, async_result, NULL); - ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH); - g_object_unref (source); + GError *error = NULL; + + g_file_copy_finish (source, async_result, &error); + if (!error) { + ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH); + g_object_unref (source); + + return; + } + + if (error->domain == G_IO_ERROR && + error->code == G_IO_ERROR_NOT_MOUNTED) { + GMountOperation *operation; + + operation = ev_mount_operation_new (GTK_WINDOW (ev_window)); + g_file_mount_enclosing_volume (source, + G_MOUNT_MOUNT_NONE, + operation, NULL, + (GAsyncReadyCallback)mount_volume_ready_cb, + ev_window); + g_object_unref (operation); + } else { + ev_window_load_remote_failed (ev_window, error); + g_object_unref (source); + } + + g_error_free (error); +} + +static void +ev_window_load_file_remote (EvWindow *ev_window, + GFile *source_file) +{ + GFile *target_file; + + if (!ev_window->priv->local_uri) { + gchar *tmp_name; + gchar *base_name; + + /* We'd like to keep extension of source uri since + * it helps to resolve some mime types, say cbz */ + tmp_name = ev_tmp_filename (NULL); + base_name = g_file_get_basename (source_file); + ev_window->priv->local_uri = g_strconcat ("file:", tmp_name, "-", + base_name, NULL); + ev_job_load_set_uri (EV_JOB_LOAD (ev_window->priv->load_job), + ev_window->priv->local_uri); + g_free (base_name); + g_free (tmp_name); + } + + target_file = g_file_new_for_uri (ev_window->priv->local_uri); + g_file_copy_async (source_file, target_file, + 0, G_PRIORITY_DEFAULT, NULL, + NULL, NULL, /* no progress callback */ + (GAsyncReadyCallback) window_open_file_copy_ready_cb, + ev_window); + g_object_unref (target_file); } void @@ -1478,11 +1605,18 @@ ev_window_open_uri (EvWindow *ev_window, const gchar *print_settings) { GFile *source_file; - GFile *target_file; + ev_window->priv->in_reload = FALSE; + if (ev_window->priv->uri && g_ascii_strcasecmp (ev_window->priv->uri, uri) == 0) { - ev_window->priv->in_reload = TRUE; + ev_window_reload_document (ev_window); + return; + } + + if (ev_window->priv->monitor) { + g_object_unref (ev_window->priv->monitor); + ev_window->priv->monitor = NULL; } ev_window_close_dialogs (ev_window); @@ -1512,33 +1646,27 @@ ev_window_open_uri (EvWindow *ev_window, source_file = g_file_new_for_uri (uri); if (!g_file_is_native (source_file) && !ev_window->priv->local_uri) { - char *tmp_name; - char *base_name; - - /* We'd like to keep extension of source uri since - * it helps to resolve some mime types, say cbz */ - - tmp_name = ev_tmp_filename (NULL); - base_name = g_file_get_basename (source_file); - ev_window->priv->local_uri = g_strconcat ("file:", tmp_name, "-", base_name, NULL); - ev_job_load_set_uri (EV_JOB_LOAD (ev_window->priv->load_job), - ev_window->priv->local_uri); - g_free (base_name); - g_free (tmp_name); - - target_file = g_file_new_for_uri (ev_window->priv->local_uri); - - g_file_copy_async (source_file, target_file, - 0, G_PRIORITY_DEFAULT, NULL, - NULL, NULL, /* no progress callback */ - (GAsyncReadyCallback) window_open_file_copy_ready_cb, - ev_window); - g_object_unref (target_file); - return; + ev_window_load_file_remote (ev_window, source_file); + } else { + g_object_unref (source_file); + ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH); } +} + +static void +ev_window_reload_document (EvWindow *ev_window) +{ + const gchar *uri; - g_object_unref (source_file); - ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH); + ev_window_clear_reload_job (ev_window); + ev_window->priv->in_reload = TRUE; + + uri = ev_window->priv->local_uri ? ev_window->priv->local_uri : ev_window->priv->uri; + ev_window->priv->reload_job = ev_job_load_new (uri, NULL, 0, NULL); + g_signal_connect (ev_window->priv->reload_job, "finished", + G_CALLBACK (ev_window_reload_job_cb), + ev_window); + ev_job_queue_add_job (ev_window->priv->reload_job, EV_JOB_PRIORITY_LOW); } static void @@ -1910,7 +2038,7 @@ window_save_file_copy_ready_cb (GFile *src, _("The file could not be saved as “%s”."), name); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - error->message); + "%s", error->message); g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); @@ -2031,7 +2159,6 @@ ev_window_cmd_save_as (GtkAction *action, EvWindow *ev_window) gtk_widget_show (fc); } -#ifdef WITH_GTK_PRINT static void ev_window_print_page_setup_done_cb (GtkPageSetup *page_setup, EvWindow *window) @@ -2044,22 +2171,18 @@ ev_window_print_page_setup_done_cb (GtkPageSetup *page_setup, g_object_unref (window->priv->print_page_setup); window->priv->print_page_setup = g_object_ref (page_setup); } -#endif /* WITH_GTK_PRINT */ static void ev_window_cmd_file_print_setup (GtkAction *action, EvWindow *ev_window) { -#ifdef WITH_GTK_PRINT gtk_print_run_page_setup_dialog_async ( GTK_WINDOW (ev_window), ev_window->priv->print_page_setup, ev_window->priv->print_settings, (GtkPageSetupDoneFunc) ev_window_print_page_setup_done_cb, ev_window); -#endif /* WITH_GTK_PRINT */ } -#ifdef WITH_GTK_PRINT static void ev_window_clear_print_job (EvWindow *window) { @@ -2130,7 +2253,7 @@ ev_window_print_finished (GtkPrintJob *print_job, GTK_BUTTONS_OK, _("Failed to print document")); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - error->message); + "%s", error->message); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); @@ -2202,7 +2325,7 @@ ev_window_print_send (EvWindow *window, GtkPrintJob *job; GError *error = NULL; - job = gtk_print_job_new ("evince-print", + job = gtk_print_job_new (gtk_window_get_title (GTK_WINDOW (window)), window->priv->printer, settings, window->priv->print_page_setup); @@ -2217,7 +2340,7 @@ ev_window_print_send (EvWindow *window, window, NULL); } else { ev_window_clear_print_job (window); - g_warning (error->message); + g_warning ("%s", error->message); g_error_free (error); } } @@ -2230,7 +2353,7 @@ ev_window_print_job_cb (EvJobPrint *job, EvWindow *window) { if (job->error) { - g_warning (job->error->message); + g_warning ("%s", job->error->message); ev_window_clear_print_job (window); return; } @@ -2259,7 +2382,8 @@ ev_window_print_dialog_response_cb (GtkDialog *dialog, GtkPrintPages print_pages; const gchar *file_format; - if (response == GTK_RESPONSE_CANCEL) { + if (response != GTK_RESPONSE_OK && + response != GTK_RESPONSE_APPLY) { gtk_widget_destroy (GTK_WIDGET (dialog)); window->priv->print_dialog = NULL; @@ -2442,124 +2566,6 @@ ev_window_print_range (EvWindow *ev_window, int first_page, int last_page) gtk_widget_show (dialog); } -#endif /* WITH_GTK_PRINT */ - -#ifdef WITH_GNOME_PRINT -static gboolean -ev_window_print_dialog_response_cb (GtkDialog *print_dialog, - gint response, - EvWindow *ev_window) -{ - EvPrintJob *print_job; - GnomePrintConfig *config; - - if (response != GNOME_PRINT_DIALOG_RESPONSE_PRINT) { - gtk_widget_destroy (GTK_WIDGET (print_dialog)); - ev_window->priv->print_dialog = NULL; - g_object_unref (ev_window->priv->print_job); - ev_window->priv->print_job = NULL; - - return FALSE; - } - - config = gnome_print_dialog_get_config (GNOME_PRINT_DIALOG (print_dialog)); - - /* FIXME: Change this when we have the first backend - * that can print more than postscript - */ - if (using_pdf_printer (config)) { - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (GTK_WINDOW (print_dialog), GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - _("Generating PDF is not supported")); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - return FALSE; - } else if (!using_postscript_printer (config)) { - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (GTK_WINDOW (print_dialog), GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - _("Printing is not supported on this printer.")); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - _("You were trying to print to a printer using the “%s” driver. " - "This program requires a PostScript printer driver."), - gnome_print_config_get (config, (guchar *)"Settings.Engine.Backend.Driver")); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - return FALSE; - } - - save_print_config_to_file (config); - - print_job = g_object_new (EV_TYPE_PRINT_JOB, - "gnome_print_job", ev_window->priv->print_job, - "document", ev_window->priv->document, - "print_dialog", print_dialog, - NULL); - - if (print_job != NULL) { - ev_print_job_print (print_job, GTK_WINDOW (ev_window)); - g_object_unref (print_job); - } - - g_object_unref (config); - - gtk_widget_destroy (GTK_WIDGET (print_dialog)); - ev_window->priv->print_dialog = NULL; - g_object_unref (ev_window->priv->print_job); - ev_window->priv->print_job = NULL; - - return FALSE; -} - -void -ev_window_print_range (EvWindow *ev_window, int first_page, int last_page) -{ - GnomePrintConfig *config; - gchar *pages_label; - - g_return_if_fail (EV_IS_WINDOW (ev_window)); - g_return_if_fail (ev_window->priv->document != NULL); - - config = load_print_config_from_file (); - - if (ev_window->priv->print_job == NULL) - ev_window->priv->print_job = gnome_print_job_new (config); - - if (ev_window->priv->print_dialog == NULL) { - ev_window->priv->print_dialog = - gnome_print_dialog_new (ev_window->priv->print_job, - (guchar *) _("Print"), - (GNOME_PRINT_DIALOG_RANGE | - GNOME_PRINT_DIALOG_COPIES)); - } - - gtk_window_set_transient_for (GTK_WINDOW (ev_window->priv->print_dialog), - GTK_WINDOW (ev_window)); - g_object_unref (config); - - pages_label = g_strconcat (_("Pages"), " ", NULL); - gnome_print_dialog_construct_range_page (GNOME_PRINT_DIALOG (ev_window->priv->print_dialog), - GNOME_PRINT_RANGE_ALL | - GNOME_PRINT_RANGE_RANGE, - first_page, last_page, - NULL, (const guchar *)pages_label); - g_free (pages_label); - - gtk_dialog_set_response_sensitive (GTK_DIALOG (ev_window->priv->print_dialog), - GNOME_PRINT_DIALOG_RESPONSE_PREVIEW, - FALSE); - - g_signal_connect (G_OBJECT (ev_window->priv->print_dialog), "response", - G_CALLBACK (ev_window_print_dialog_response_cb), - ev_window); - gtk_widget_show (ev_window->priv->print_dialog); -} -#endif /* WITH_GNOME_PRINT */ static void ev_window_print (EvWindow *window) @@ -2570,9 +2576,7 @@ ev_window_print (EvWindow *window) page_cache = ev_page_cache_get (window->priv->document); last_page = ev_page_cache_get_n_pages (page_cache); -#ifdef WITH_PRINT ev_window_print_range (window, 1, last_page); -#endif } static void @@ -2638,7 +2642,7 @@ ev_window_cmd_continuous (GtkAction *action, EvWindow *ev_window) { gboolean continuous; - ev_window_stop_presentation (ev_window); + ev_window_stop_presentation (ev_window, TRUE); continuous = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); g_object_set (G_OBJECT (ev_window->priv->view), "continuous", continuous, @@ -2651,7 +2655,7 @@ ev_window_cmd_dual (GtkAction *action, EvWindow *ev_window) { gboolean dual_page; - ev_window_stop_presentation (ev_window); + ev_window_stop_presentation (ev_window, TRUE); dual_page = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); g_object_set (G_OBJECT (ev_window->priv->view), "dual-page", dual_page, @@ -2662,7 +2666,7 @@ ev_window_cmd_dual (GtkAction *action, EvWindow *ev_window) static void ev_window_cmd_view_best_fit (GtkAction *action, EvWindow *ev_window) { - ev_window_stop_presentation (ev_window); + ev_window_stop_presentation (ev_window, TRUE); if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) { ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_BEST_FIT); @@ -2675,7 +2679,7 @@ ev_window_cmd_view_best_fit (GtkAction *action, EvWindow *ev_window) static void ev_window_cmd_view_page_width (GtkAction *action, EvWindow *ev_window) { - ev_window_stop_presentation (ev_window); + ev_window_stop_presentation (ev_window, TRUE); if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) { ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_FIT_WIDTH); @@ -2804,6 +2808,12 @@ fullscreen_toolbar_remove_shadow (GtkWidget *toolbar) static void ev_window_run_fullscreen (EvWindow *window) { + EvView *view = EV_VIEW (window->priv->view); + gboolean fullscreen_window = TRUE; + + if (ev_view_get_fullscreen (view)) + return; + if (!window->priv->fullscreen_toolbar) { window->priv->fullscreen_toolbar = gtk_ui_manager_get_widget (window->priv->ui_manager, @@ -2821,11 +2831,16 @@ ev_window_run_fullscreen (EvWindow *window) window->priv->fullscreen_toolbar, 1); } + if (ev_view_get_presentation (view)) { + ev_window_stop_presentation (window, FALSE); + fullscreen_window = FALSE; + } + g_object_set (G_OBJECT (window->priv->scrolled_window), "shadow-type", GTK_SHADOW_NONE, NULL); - ev_view_set_fullscreen (EV_VIEW (window->priv->view), TRUE); + ev_view_set_fullscreen (view, TRUE); ev_window_update_fullscreen_action (window); /* If the user doesn't have the main toolbar he/she won't probably want @@ -2834,8 +2849,9 @@ ev_window_run_fullscreen (EvWindow *window) update_chrome_flag (window, EV_CHROME_FULLSCREEN_TOOLBAR, (window->priv->chrome & EV_CHROME_TOOLBAR) != 0); update_chrome_visibility (window); - - gtk_window_fullscreen (GTK_WINDOW (window)); + + if (fullscreen_window) + gtk_window_fullscreen (GTK_WINDOW (window)); gtk_widget_grab_focus (window->priv->view); if (!ev_window_is_empty (window)) @@ -2843,11 +2859,12 @@ ev_window_run_fullscreen (EvWindow *window) } static void -ev_window_stop_fullscreen (EvWindow *window) +ev_window_stop_fullscreen (EvWindow *window, + gboolean unfullscreen_window) { EvView *view = EV_VIEW (window->priv->view); - if (!ev_view_get_fullscreen (EV_VIEW (view))) + if (!ev_view_get_fullscreen (view)) return; g_object_set (G_OBJECT (window->priv->scrolled_window), @@ -2858,7 +2875,8 @@ ev_window_stop_fullscreen (EvWindow *window) ev_window_update_fullscreen_action (window); update_chrome_flag (window, EV_CHROME_FULLSCREEN_TOOLBAR, FALSE); update_chrome_visibility (window); - gtk_window_unfullscreen (GTK_WINDOW (window)); + if (unfullscreen_window) + gtk_window_unfullscreen (GTK_WINDOW (window)); if (!ev_window_is_empty (window)) ev_metadata_manager_set_boolean (window->priv->uri, "fullscreen", FALSE); @@ -2869,14 +2887,11 @@ ev_window_cmd_view_fullscreen (GtkAction *action, EvWindow *window) { gboolean fullscreen; - g_return_if_fail (EV_IS_WINDOW (window)); - ev_window_stop_presentation (window); - fullscreen = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); if (fullscreen) { ev_window_run_fullscreen (window); } else { - ev_window_stop_fullscreen (window); + ev_window_stop_fullscreen (window, TRUE); } } @@ -2961,17 +2976,29 @@ ev_window_update_presentation_action (EvWindow *window) static void ev_window_run_presentation (EvWindow *window) { + EvView *view = EV_VIEW (window->priv->view); + gboolean fullscreen_window = TRUE; + + if (ev_view_get_presentation (view)) + return; + + if (ev_view_get_fullscreen (view)) { + ev_window_stop_fullscreen (window, FALSE); + fullscreen_window = FALSE; + } + g_object_set (G_OBJECT (window->priv->scrolled_window), "shadow-type", GTK_SHADOW_NONE, NULL); - ev_view_set_presentation (EV_VIEW (window->priv->view), TRUE); + ev_view_set_presentation (view, TRUE); ev_window_update_presentation_action (window); update_chrome_visibility (window); gtk_widget_grab_focus (window->priv->view); - gtk_window_fullscreen (GTK_WINDOW (window)); + if (fullscreen_window) + gtk_window_fullscreen (GTK_WINDOW (window)); g_signal_connect (window->priv->view, "motion-notify-event", @@ -2990,9 +3017,12 @@ ev_window_run_presentation (EvWindow *window) } static void -ev_window_stop_presentation (EvWindow *window) +ev_window_stop_presentation (EvWindow *window, + gboolean unfullscreen_window) { - if (!ev_view_get_presentation (EV_VIEW (window->priv->view))) + EvView *view = EV_VIEW (window->priv->view); + + if (!ev_view_get_presentation (view)) return; g_object_set (G_OBJECT (window->priv->scrolled_window), @@ -3002,7 +3032,8 @@ ev_window_stop_presentation (EvWindow *window) ev_view_set_presentation (EV_VIEW (window->priv->view), FALSE); ev_window_update_presentation_action (window); update_chrome_visibility (window); - gtk_window_unfullscreen (GTK_WINDOW (window)); + if (unfullscreen_window) + gtk_window_unfullscreen (GTK_WINDOW (window)); g_signal_handlers_disconnect_by_func (window->priv->view, (gpointer) presentation_motion_notify_cb, @@ -3023,14 +3054,11 @@ ev_window_cmd_view_presentation (GtkAction *action, EvWindow *window) { gboolean presentation; - g_return_if_fail (EV_IS_WINDOW (window)); - ev_window_stop_fullscreen (window); - presentation = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); if (presentation) { ev_window_run_presentation (window); } else { - ev_window_stop_presentation (window); + ev_window_stop_presentation (window, TRUE); } } @@ -3206,6 +3234,12 @@ ev_window_cmd_go_previous_page (GtkAction *action, EvWindow *ev_window) ev_view_previous_page (EV_VIEW (ev_window->priv->view)); } +void +ev_window_go_previous_page (EvWindow *ev_window) +{ + ev_window_cmd_go_previous_page (NULL, ev_window); +} + static void ev_window_cmd_go_next_page (GtkAction *action, EvWindow *ev_window) { @@ -3214,6 +3248,12 @@ ev_window_cmd_go_next_page (GtkAction *action, EvWindow *ev_window) ev_view_next_page (EV_VIEW (ev_window->priv->view)); } +void +ev_window_go_next_page (EvWindow *ev_window) +{ + ev_window_cmd_go_next_page (NULL, ev_window); +} + static void ev_window_cmd_go_first_page (GtkAction *action, EvWindow *ev_window) { @@ -3222,6 +3262,12 @@ ev_window_cmd_go_first_page (GtkAction *action, EvWindow *ev_window) ev_page_cache_set_current_page (ev_window->priv->page_cache, 0); } +void +ev_window_go_first_page (EvWindow *ev_window) +{ + ev_window_cmd_go_first_page (NULL, ev_window); +} + static void ev_window_cmd_go_last_page (GtkAction *action, EvWindow *ev_window) { @@ -3233,6 +3279,12 @@ ev_window_cmd_go_last_page (GtkAction *action, EvWindow *ev_window) ev_page_cache_set_current_page (ev_window->priv->page_cache, n_pages - 1); } +void +ev_window_go_last_page (EvWindow *ev_window) +{ + ev_window_cmd_go_last_page (NULL, ev_window); +} + static void ev_window_cmd_go_forward (GtkAction *action, EvWindow *ev_window) { @@ -3263,11 +3315,7 @@ ev_window_cmd_go_backward (GtkAction *action, EvWindow *ev_window) static void ev_window_cmd_view_reload (GtkAction *action, EvWindow *ev_window) { - gchar *uri; - - uri = g_strdup (ev_window->priv->uri); - ev_window_open_uri (ev_window, uri, NULL, 0, NULL, FALSE, NULL); - g_free (uri); + ev_window_reload_document (ev_window); } static void @@ -3319,7 +3367,7 @@ ev_window_cmd_help_contents (GtkAction *action, EvWindow *ev_window) screen = gtk_widget_get_screen (GTK_WIDGET (ev_window)); gdk_spawn_command_line_on_screen (screen, command, &error); if (error != NULL) { - g_warning (error->message); + g_warning ("%s", error->message); g_error_free (error); } g_free (command); @@ -3328,18 +3376,20 @@ ev_window_cmd_help_contents (GtkAction *action, EvWindow *ev_window) static void ev_window_cmd_leave_fullscreen (GtkAction *action, EvWindow *window) { - ev_window_stop_fullscreen (window); + ev_window_stop_fullscreen (window, TRUE); } static void ev_window_cmd_start_presentation (GtkAction *action, EvWindow *window) { - ev_window_stop_fullscreen (window); ev_window_run_presentation (window); } -#ifdef WITH_GTK_PRINT -static void ev_window_do_preview_print (EvWindow *window); +void +ev_window_start_presentation (EvWindow *ev_window) +{ + ev_window_run_presentation (ev_window); +} static gboolean ev_window_enumerate_printer_cb (GtkPrinter *printer, @@ -3379,7 +3429,7 @@ ev_window_preview_print_finished (GtkPrintJob *print_job, GTK_BUTTONS_OK, _("Failed to print document")); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - error->message); + "%s", error->message); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); @@ -3403,7 +3453,7 @@ ev_window_do_preview_print (EvWindow *window) page_setup = gtk_page_setup_new (); - job = gtk_print_job_new ("evince-print", + job = gtk_print_job_new (gtk_window_get_title (GTK_WINDOW (window)), priv->printer, priv->print_settings, page_setup); @@ -3423,7 +3473,7 @@ ev_window_do_preview_print (EvWindow *window) (GtkPrintJobCompleteFunc)ev_window_preview_print_finished, window, NULL); } else { - g_warning (error->message); + g_warning ("%s", error->message); g_error_free (error); } @@ -3432,12 +3482,9 @@ ev_window_do_preview_print (EvWindow *window) gtk_widget_hide (GTK_WIDGET (window)); } -#endif /* WITH_GTK_PRINT */ - static void ev_window_cmd_preview_print (GtkAction *action, EvWindow *window) { -#ifdef WITH_GTK_PRINT EvWindowPrivate *priv = window->priv; GtkPrintSettings *print_settings = NULL; #if GTK_CHECK_VERSION (2, 11, 0) @@ -3451,7 +3498,7 @@ ev_window_cmd_preview_print (GtkAction *action, EvWindow *window) &error); if (error) { - g_warning (error->message); + g_warning ("%s", error->message); g_error_free (error); print_settings = NULL; } @@ -3468,7 +3515,6 @@ ev_window_cmd_preview_print (GtkAction *action, EvWindow *window) gtk_enumerate_printers ((GtkPrinterFunc) ev_window_enumerate_printer_cb, window, NULL, FALSE); -#endif /* WITH_GTK_PRINT */ } static void @@ -3493,9 +3539,9 @@ ev_window_cmd_escape (GtkAction *action, EvWindow *window) NULL); if (fullscreen) { - ev_window_stop_fullscreen (window); + ev_window_stop_fullscreen (window, TRUE); } else if (presentation) { - ev_window_stop_presentation (window); + ev_window_stop_presentation (window, TRUE); gtk_widget_grab_focus (window->priv->view); } else { gtk_widget_grab_focus (window->priv->view); @@ -3975,6 +4021,7 @@ static void find_bar_close_cb (EggFindBar *find_bar, EvWindow *ev_window) { + ev_view_find_cancel (EV_VIEW (ev_window->priv->view)); update_chrome_flag (ev_window, EV_CHROME_FINDBAR, FALSE); update_chrome_visibility (ev_window); } @@ -4087,7 +4134,21 @@ ev_window_dispose (GObject *object) { EvWindow *window = EV_WINDOW (object); EvWindowPrivate *priv = window->priv; +#ifdef ENABLE_DBUS + GObject *keys; + + keys = ev_application_get_media_keys (EV_APP); + if (keys) { + ev_media_player_keys_focused (EV_MEDIA_PLAYER_KEYS (keys), NULL); + g_object_unref (keys); + } +#endif /* ENABLE_DBUS */ + if (priv->monitor) { + g_object_unref (priv->monitor); + priv->monitor = NULL; + } + if (priv->title) { ev_window_title_free (priv->title); priv->title = NULL; @@ -4151,6 +4212,10 @@ ev_window_dispose (GObject *object) 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); } @@ -4165,8 +4230,6 @@ ev_window_dispose (GObject *object) } ev_window_close_dialogs (window); - -#ifdef WITH_GTK_PRINT ev_window_clear_print_job (window); if (window->priv->gtk_print_job) { @@ -4188,7 +4251,6 @@ ev_window_dispose (GObject *object) g_object_unref (window->priv->print_page_setup); window->priv->print_page_setup = NULL; } -#endif if (priv->link) { g_object_unref (priv->link); @@ -4272,7 +4334,7 @@ static const GtkActionEntry entries[] = { { "FileOpen", GTK_STOCK_OPEN, N_("_Open..."), "O", N_("Open an existing document"), G_CALLBACK (ev_window_cmd_file_open) }, - { "FileOpenCopy", NULL, N_("Op_en a Copy"), NULL, + { "FileOpenCopy", NULL, N_("Op_en a Copy"), "N", N_("Open a copy of the current document in a new window"), G_CALLBACK (ev_window_cmd_file_open_copy) }, { "FileSaveAs", GTK_STOCK_SAVE_AS, N_("_Save a Copy..."), "S", @@ -4303,9 +4365,9 @@ static const GtkActionEntry entries[] = { G_CALLBACK (ev_window_cmd_edit_find_previous) }, { "EditToolbar", NULL, N_("T_oolbar"), NULL, NULL, G_CALLBACK (ev_window_cmd_edit_toolbar) }, - { "EditRotateLeft", EV_STOCK_ROTATE_LEFT, N_("Rotate _Left"), NULL, NULL, + { "EditRotateLeft", EV_STOCK_ROTATE_LEFT, N_("Rotate _Left"), "Left", NULL, G_CALLBACK (ev_window_cmd_edit_rotate_left) }, - { "EditRotateRight", EV_STOCK_ROTATE_RIGHT, N_("Rotate _Right"), NULL, NULL, + { "EditRotateRight", EV_STOCK_ROTATE_RIGHT, N_("Rotate _Right"), "Right", NULL, G_CALLBACK (ev_window_cmd_edit_rotate_right) }, /* View menu */ @@ -4397,6 +4459,8 @@ static const GtkActionEntry entries[] = { G_CALLBACK (ev_window_cmd_view_zoom_in) }, { "CtrlKpMinus", GTK_STOCK_ZOOM_OUT, NULL, "KP_Subtract", NULL, G_CALLBACK (ev_window_cmd_view_zoom_out) }, + { "CtrlInsert", GTK_STOCK_COPY, NULL, "Insert", NULL, + G_CALLBACK (ev_window_cmd_edit_copy) }, }; /* Toggle items */ @@ -4602,6 +4666,16 @@ sidebar_widget_model_set (EvSidebarLinks *ev_sidebar_links, static gboolean view_actions_focus_in_cb (GtkWidget *widget, GdkEventFocus *event, EvWindow *window) { +#ifdef ENABLE_DBUS + GObject *keys; + + keys = ev_application_get_media_keys (EV_APP); + if (keys) { + ev_media_player_keys_focused (EV_MEDIA_PLAYER_KEYS (keys), window); + g_object_unref (keys); + } +#endif /* ENABLE_DBUS */ + update_chrome_flag (window, EV_CHROME_RAISE_TOOLBAR, FALSE); ev_window_set_action_sensitive (window, "ViewToolbar", TRUE); @@ -4744,29 +4818,11 @@ static void launch_external_uri (EvWindow *window, EvLinkAction *action) { const gchar *uri = ev_link_action_get_uri (action); - const char *content_type; - GFile *file; - GFileInfo *file_info; - GAppInfo *app; - GList *file_list = NULL; GError *error = NULL; + gboolean ret; - file = g_file_new_for_uri (uri); - file_info = g_file_query_info (file, - G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, - 0, NULL, NULL); - if (file_info == NULL) { - g_object_unref (file); - return; - } - - content_type = g_file_info_get_content_type (file_info); - app = g_app_info_get_default_for_type (content_type, TRUE); - g_object_unref (file_info); - - file_list = g_list_append (file_list, file); - - if (!g_app_info_launch (app, file_list, NULL, &error)) { + ret = g_app_info_launch_default_for_uri (uri, NULL, &error); + if (ret == FALSE) { GtkWidget *dialog; dialog = gtk_message_dialog_new (GTK_WINDOW (window), @@ -4780,11 +4836,8 @@ launch_external_uri (EvWindow *window, EvLinkAction *action) G_CALLBACK (gtk_widget_destroy), NULL); gtk_widget_show (dialog); + g_error_free(error); } - - g_object_unref (app); - g_object_unref (file); - g_list_free (file_list); } static void @@ -4895,19 +4948,14 @@ ev_view_popup_cmd_open_link_new_window (GtkAction *action, EvWindow *window) static void ev_view_popup_cmd_copy_link_address (GtkAction *action, EvWindow *window) { - GtkClipboard *clipboard; EvLinkAction *ev_action; - const gchar *uri; ev_action = ev_link_get_action (window->priv->link); if (!ev_action) return; - uri = ev_link_action_get_uri (ev_action); - - clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), - GDK_SELECTION_CLIPBOARD); - gtk_clipboard_set_text (clipboard, uri, -1); + ev_view_copy_link_address (EV_VIEW (window->priv->view), + ev_action); } @@ -4921,7 +4969,6 @@ image_save_dialog_response_cb (GtkWidget *fc, GError *error = NULL; GdkPixbuf *pixbuf; gchar *uri; - gchar *uri_extension; gchar **extensions; gchar *filename; gchar *file_format; @@ -4952,27 +4999,31 @@ image_save_dialog_response_cb (GtkWidget *fc, } extensions = gdk_pixbuf_format_get_extensions (format); - uri_extension = g_strconcat (uri, ".", extensions[0], NULL); + if (g_str_has_suffix(uri, extensions[0])) { + gchar *uri_extension; + + uri_extension = g_strconcat (uri, ".", extensions[0], NULL); + target_file = g_file_new_for_uri (uri_extension); + g_free (uri_extension); + } else { + target_file = g_file_new_for_uri (uri); + } g_strfreev(extensions); - file_format = gdk_pixbuf_format_get_name (format); + g_free (uri); - target_file = g_file_new_for_uri (uri_extension); is_native = g_file_is_native (target_file); - if (is_native) { filename = g_file_get_path (target_file); } else { filename = ev_tmp_filename ("saveimage"); } - - g_free (uri); - g_free (uri_extension); ev_document_doc_mutex_lock (); pixbuf = ev_document_images_get_image (EV_DOCUMENT_IMAGES (ev_window->priv->document), ev_window->priv->image); ev_document_doc_mutex_unlock (); - + + file_format = gdk_pixbuf_format_get_name (format); gdk_pixbuf_save (pixbuf, filename, file_format, &error, NULL); g_free (file_format); g_object_unref (pixbuf);