X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=shell%2Fev-window.c;h=523a8c6aa164342bde35b792b2512eb5f026ef21;hb=cdba8578739fd46880c53fdacc66c58b38278506;hp=d53d818720eff8b14497c6e7fd1e5bf85b9de43c;hpb=76f0af54740d46b8f35712234c027f77920d7c0f;p=evince.git diff --git a/shell/ev-window.c b/shell/ev-window.c index d53d8187..523a8c6a 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -61,6 +61,7 @@ #include "ev-document-images.h" #include "ev-document-links.h" #include "ev-document-thumbnails.h" +#include "ev-document-type-builtins.h" #include "ev-file-exporter.h" #include "ev-file-helpers.h" #include "ev-file-monitor.h" @@ -86,6 +87,7 @@ #include "ev-utils.h" #include "ev-keyring.h" #include "ev-view.h" +#include "ev-view-type-builtins.h" #include "ev-window.h" #include "ev-window-title.h" #include "ev-print-operation.h" @@ -115,6 +117,12 @@ typedef enum { EV_CHROME_NORMAL = EV_CHROME_MENUBAR | EV_CHROME_TOOLBAR | EV_CHROME_SIDEBAR } EvChrome; +typedef enum { + EV_SAVE_DOCUMENT, + EV_SAVE_ATTACHMENT, + EV_SAVE_IMAGE +} EvSaveType; + struct _EvWindowPrivate { /* UI */ EvChrome chrome; @@ -135,6 +143,10 @@ struct _EvWindowPrivate { GtkWidget *sidebar_attachments; GtkWidget *sidebar_layers; + /* Progress Messages */ + guint progress_idle; + GCancellable *progress_cancellable; + /* Dialogs */ GtkWidget *properties; GtkWidget *print_dialog; @@ -171,7 +183,6 @@ struct _EvWindowPrivate { char *uri; glong uri_mtime; char *local_uri; - EvLinkDest *dest; gboolean unlink_temp_file; gboolean in_reload; EvFileMonitor *monitor; @@ -183,6 +194,11 @@ struct _EvWindowPrivate { EvWindowPageMode page_mode; EvWindowTitle *title; + /* Load params */ + EvLinkDest *dest; + gchar *search_string; + EvWindowRunMode window_mode; + EvJob *load_job; EvJob *reload_job; EvJob *thumbnail_job; @@ -1059,7 +1075,7 @@ setup_view_from_metadata (EvWindow *window) /* Sizing mode */ if (ev_metadata_manager_get (uri, "sizing_mode", &sizing_mode, FALSE)) { enum_value = g_enum_get_value_by_nick - (EV_SIZING_MODE_CLASS, g_value_get_string (&sizing_mode)); + (g_type_class_peek (EV_TYPE_SIZING_MODE), g_value_get_string (&sizing_mode)); g_value_unset (&sizing_mode); ev_view_set_sizing_mode (view, enum_value->value); } @@ -1358,7 +1374,7 @@ ev_window_load_job_cb (EvJob *job, if (!ev_job_is_failed (job)) { ev_window_set_document (ev_window, document); - if (job_load->mode != EV_WINDOW_MODE_PREVIEW) { + if (ev_window->priv->window_mode != EV_WINDOW_MODE_PREVIEW) { setup_view_from_metadata (ev_window); } @@ -1378,17 +1394,23 @@ ev_window_load_job_cb (EvJob *job, flags); } - if (job_load->dest) { + if (ev_window->priv->dest) { EvLink *link; EvLinkAction *link_action; - link_action = ev_link_action_new_dest (g_object_ref (job_load->dest)); + link_action = ev_link_action_new_dest (ev_window->priv->dest); link = ev_link_new (NULL, link_action); ev_view_handle_link (EV_VIEW (ev_window->priv->view), link); g_object_unref (link); + + /* Already unrefed by ev_link_action + * FIXME: link action should inc dest ref counting + * or not unref it at all + */ + ev_window->priv->dest = NULL; } - switch (job_load->mode) { + switch (ev_window->priv->window_mode) { case EV_WINDOW_MODE_FULLSCREEN: ev_window_run_fullscreen (ev_window); break; @@ -1402,15 +1424,18 @@ ev_window_load_job_cb (EvJob *job, break; } - if (job_load->search_string && EV_IS_DOCUMENT_FIND (document)) { + if (ev_window->priv->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_load->search_string); + ev_window->priv->search_string); } + g_free (ev_window->priv->search_string); + ev_window->priv->search_string = NULL; + /* Create a monitor for the document */ ev_window->priv->monitor = ev_file_monitor_new (ev_window->priv->uri); - g_signal_connect_swapped (G_OBJECT (ev_window->priv->monitor), "changed", + g_signal_connect_swapped (ev_window->priv->monitor, "changed", G_CALLBACK (ev_window_document_changed), ev_window); @@ -1519,6 +1544,81 @@ ev_window_close_dialogs (EvWindow *ev_window) ev_window->priv->properties = NULL; } +static void +ev_window_clear_progress_idle (EvWindow *ev_window) +{ + if (ev_window->priv->progress_idle > 0) + g_source_remove (ev_window->priv->progress_idle); + ev_window->priv->progress_idle = 0; +} + +static void +reset_progress_idle (EvWindow *ev_window) +{ + ev_window->priv->progress_idle = 0; +} + +static void +ev_window_show_progress_message (EvWindow *ev_window, + guint interval, + GSourceFunc function) +{ + if (ev_window->priv->progress_idle > 0) + g_source_remove (ev_window->priv->progress_idle); + ev_window->priv->progress_idle = + g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, + interval, function, + ev_window, + (GDestroyNotify)reset_progress_idle); +} + +static void +ev_window_reset_progress_cancellable (EvWindow *ev_window) +{ + if (ev_window->priv->progress_cancellable) + g_cancellable_reset (ev_window->priv->progress_cancellable); + else + ev_window->priv->progress_cancellable = g_cancellable_new (); +} + +static void +ev_window_progress_response_cb (EvProgressMessageArea *area, + gint response, + EvWindow *ev_window) +{ + if (response == GTK_RESPONSE_CANCEL) + g_cancellable_cancel (ev_window->priv->progress_cancellable); + ev_window_set_message_area (ev_window, NULL); +} + +static gboolean +show_loading_progress (EvWindow *ev_window) +{ + GtkWidget *area; + gchar *text; + + if (ev_window->priv->message_area) + return FALSE; + + text = g_strdup_printf (_("Loading document from %s"), + ev_window->priv->uri); + area = ev_progress_message_area_new (GTK_STOCK_OPEN, + text, + GTK_STOCK_CLOSE, + GTK_RESPONSE_CLOSE, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, + NULL); + g_signal_connect (area, "response", + G_CALLBACK (ev_window_progress_response_cb), + ev_window); + gtk_widget_show (area); + ev_window_set_message_area (ev_window, area); + g_free (text); + + return FALSE; +} + static void ev_window_load_remote_failed (EvWindow *ev_window, GError *error) @@ -1582,6 +1682,8 @@ window_open_file_copy_ready_cb (GFile *source, EvWindow *ev_window) { GError *error = NULL; + + ev_window_clear_progress_idle (ev_window); g_file_copy_finish (source, async_result, &error); if (!error) { @@ -1606,6 +1708,16 @@ window_open_file_copy_ready_cb (GFile *source, (GAsyncReadyCallback)mount_volume_ready_cb, ev_window); g_object_unref (operation); + } else if (error->domain == G_IO_ERROR && + error->code == G_IO_ERROR_CANCELLED) { + ev_window_clear_load_job (ev_window); + ev_window_clear_local_uri (ev_window); + ev_window_clear_print_settings_file (ev_window); + g_free (ev_window->priv->uri); + ev_window->priv->uri = NULL; + g_object_unref (source); + + ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE); } else { ev_window_load_remote_failed (ev_window, error); g_object_unref (source); @@ -1615,8 +1727,31 @@ window_open_file_copy_ready_cb (GFile *source, } static void -ev_window_load_file_remote (EvWindow *ev_window, - GFile *source_file) +window_open_file_copy_progress_cb (goffset n_bytes, + goffset total_bytes, + EvWindow *ev_window) +{ + gchar *status; + gdouble fraction; + + if (!ev_window->priv->message_area) + return; + + fraction = n_bytes / (gdouble)total_bytes; + status = g_strdup_printf (_("Downloading document (%d%%)"), + (gint)(fraction * 100)); + + ev_progress_message_area_set_status (EV_PROGRESS_MESSAGE_AREA (ev_window->priv->message_area), + status); + ev_progress_message_area_set_fraction (EV_PROGRESS_MESSAGE_AREA (ev_window->priv->message_area), + fraction); + + g_free (status); +} + +static void +ev_window_load_file_remote (EvWindow *ev_window, + GFile *source_file) { GFile *target_file; @@ -1635,14 +1770,21 @@ ev_window_load_file_remote (EvWindow *ev_window, g_free (base_name); g_free (tmp_name); } + + ev_window_reset_progress_cancellable (ev_window); 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, + 0, G_PRIORITY_DEFAULT, + ev_window->priv->progress_cancellable, + (GFileProgressCallback)window_open_file_copy_progress_cb, + ev_window, + (GAsyncReadyCallback)window_open_file_copy_ready_cb, ev_window); g_object_unref (target_file); + + ev_window_show_progress_message (ev_window, 1, + (GSourceFunc)show_loading_progress); } void @@ -1676,6 +1818,7 @@ ev_window_open_uri (EvWindow *ev_window, ev_view_set_loading (EV_VIEW (ev_window->priv->view), TRUE); ev_window->priv->unlink_temp_file = unlink_temp_file; + ev_window->priv->window_mode = mode; if (mode == EV_WINDOW_MODE_PREVIEW) { ev_window->priv->print_settings_file = print_settings ? @@ -1686,9 +1829,18 @@ ev_window_open_uri (EvWindow *ev_window, g_free (ev_window->priv->uri); ev_window->priv->uri = g_strdup (uri); + if (ev_window->priv->search_string) + g_free (ev_window->priv->search_string); + ev_window->priv->search_string = search_string ? + g_strdup (search_string) : NULL; + + if (ev_window->priv->dest) + g_object_unref (ev_window->priv->dest); + ev_window->priv->dest = dest ? g_object_ref (dest) : NULL; + setup_size_from_metadata (ev_window); - ev_window->priv->load_job = ev_job_load_new (uri, dest, mode, search_string); + ev_window->priv->load_job = ev_job_load_new (uri); g_signal_connect (ev_window->priv->load_job, "finished", G_CALLBACK (ev_window_load_job_cb), @@ -1709,23 +1861,87 @@ ev_window_reload_local (EvWindow *ev_window) const gchar *uri; 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); + ev_window->priv->reload_job = ev_job_load_new (uri); g_signal_connect (ev_window->priv->reload_job, "finished", G_CALLBACK (ev_window_reload_job_cb), ev_window); ev_job_scheduler_push_job (ev_window->priv->reload_job, EV_JOB_PRIORITY_NONE); } +static gboolean +show_reloading_progress (EvWindow *ev_window) +{ + GtkWidget *area; + gchar *text; + + if (ev_window->priv->message_area) + return FALSE; + + text = g_strdup_printf (_("Reloading document from %s"), + ev_window->priv->uri); + area = ev_progress_message_area_new (GTK_STOCK_REFRESH, + text, + GTK_STOCK_CLOSE, + GTK_RESPONSE_CLOSE, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, + NULL); + g_signal_connect (area, "response", + G_CALLBACK (ev_window_progress_response_cb), + ev_window); + gtk_widget_show (area); + ev_window_set_message_area (ev_window, area); + g_free (text); + + return FALSE; +} + static void reload_remote_copy_ready_cb (GFile *remote, GAsyncResult *async_result, EvWindow *ev_window) { - g_file_copy_finish (remote, async_result, NULL); - ev_window_reload_local (ev_window); + GError *error = NULL; + + ev_window_clear_progress_idle (ev_window); + + g_file_copy_finish (remote, async_result, &error); + if (error) { + if (error->domain != G_IO_ERROR || + error->code != G_IO_ERROR_CANCELLED) + ev_window_error_message (ev_window, error, + "%s", _("Failed to reload document.")); + g_error_free (error); + } else { + ev_window_reload_local (ev_window); + } + g_object_unref (remote); } +static void +reload_remote_copy_progress_cb (goffset n_bytes, + goffset total_bytes, + EvWindow *ev_window) +{ + gchar *status; + gdouble fraction; + + if (!ev_window->priv->message_area) + return; + + fraction = n_bytes / (gdouble)total_bytes; + status = g_strdup_printf (_("Downloading document (%d%%)"), + (gint)(fraction * 100)); + + ev_progress_message_area_set_status (EV_PROGRESS_MESSAGE_AREA (ev_window->priv->message_area), + status); + ev_progress_message_area_set_fraction (EV_PROGRESS_MESSAGE_AREA (ev_window->priv->message_area), + fraction); + + g_free (status); +} + static void query_remote_uri_mtime_cb (GFile *remote, GAsyncResult *async_result, @@ -1750,14 +1966,21 @@ query_remote_uri_mtime_cb (GFile *remote, /* Remote file has changed */ ev_window->priv->uri_mtime = mtime.tv_sec; + + ev_window_reset_progress_cancellable (ev_window); + target_file = g_file_new_for_uri (ev_window->priv->local_uri); g_file_copy_async (remote, target_file, G_FILE_COPY_OVERWRITE, - G_PRIORITY_DEFAULT, NULL, - NULL, NULL, /* no progress callback */ - (GAsyncReadyCallback) reload_remote_copy_ready_cb, + G_PRIORITY_DEFAULT, + ev_window->priv->progress_cancellable, + (GFileProgressCallback)reload_remote_copy_progress_cb, + ev_window, + (GAsyncReadyCallback)reload_remote_copy_ready_cb, ev_window); g_object_unref (target_file); + ev_window_show_progress_message (ev_window, 1, + (GSourceFunc)show_reloading_progress); } else { g_object_unref (remote); ev_window_reload_local (ev_window); @@ -2111,7 +2334,7 @@ ev_window_setup_recent (EvWindow *ev_window) gtk_recent_info_ref (info), (GDestroyNotify) gtk_recent_info_unref); - g_signal_connect (G_OBJECT (action), "activate", + g_signal_connect (action, "activate", G_CALLBACK (ev_window_cmd_recent_file_activate), (gpointer) ev_window); @@ -2137,42 +2360,150 @@ ev_window_setup_recent (EvWindow *ev_window) g_list_free (items); } +static gboolean +show_saving_progress (GFile *dst) +{ + EvWindow *ev_window; + GtkWidget *area; + gchar *text; + gchar *uri; + EvSaveType save_type; + + ev_window = EV_WINDOW (g_object_get_data (G_OBJECT (dst), "ev-window")); + ev_window->priv->progress_idle = 0; + + if (ev_window->priv->message_area) + return FALSE; + + save_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dst), "save-type")); + uri = g_file_get_uri (dst); + switch (save_type) { + case EV_SAVE_DOCUMENT: + text = g_strdup_printf (_("Saving document to %s"), uri); + break; + case EV_SAVE_ATTACHMENT: + text = g_strdup_printf (_("Saving attachment to %s"), uri); + break; + case EV_SAVE_IMAGE: + text = g_strdup_printf (_("Saving image to %s"), uri); + break; + default: + g_assert_not_reached (); + } + g_free (uri); + area = ev_progress_message_area_new (GTK_STOCK_SAVE, + text, + GTK_STOCK_CLOSE, + GTK_RESPONSE_CLOSE, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, + NULL); + g_signal_connect (area, "response", + G_CALLBACK (ev_window_progress_response_cb), + ev_window); + gtk_widget_show (area); + ev_window_set_message_area (ev_window, area); + g_free (text); + + return FALSE; +} + static void window_save_file_copy_ready_cb (GFile *src, GAsyncResult *async_result, GFile *dst) { - EvWindow *window; - gchar *name; - GError *error = NULL; + EvWindow *ev_window; + GError *error = NULL; + ev_window = EV_WINDOW (g_object_get_data (G_OBJECT (dst), "ev-window")); + ev_window_clear_progress_idle (ev_window); + if (g_file_copy_finish (src, async_result, &error)) { ev_tmp_file_unlink (src); return; } - window = EV_WINDOW (g_object_get_data (G_OBJECT (dst), "ev-window")); - name = g_file_get_basename (dst); - ev_window_error_message (window, error, - _("The file could not be saved as “%s”."), - name); + if (error->domain != G_IO_ERROR || + error->code != G_IO_ERROR_CANCELLED) { + gchar *name; + + name = g_file_get_basename (dst); + ev_window_error_message (ev_window, error, + _("The file could not be saved as “%s”."), + name); + g_free (name); + } ev_tmp_file_unlink (src); - g_free (name); g_error_free (error); } static void -ev_window_save_remote (EvWindow *ev_window, - GFile *src, - GFile *dst) +window_save_file_copy_progress_cb (goffset n_bytes, + goffset total_bytes, + GFile *dst) { + EvWindow *ev_window; + EvSaveType save_type; + gchar *status; + gdouble fraction; + + ev_window = EV_WINDOW (g_object_get_data (G_OBJECT (dst), "ev-window")); + + if (!ev_window->priv->message_area) + return; + + fraction = n_bytes / (gdouble)total_bytes; + save_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dst), "save-type")); + + switch (save_type) { + case EV_SAVE_DOCUMENT: + status = g_strdup_printf (_("Uploading document (%d%%)"), + (gint)(fraction * 100)); + break; + case EV_SAVE_ATTACHMENT: + status = g_strdup_printf (_("Uploading attachment (%d%%)"), + (gint)(fraction * 100)); + break; + case EV_SAVE_IMAGE: + status = g_strdup_printf (_("Uploading image (%d%%)"), + (gint)(fraction * 100)); + break; + default: + g_assert_not_reached (); + } + + ev_progress_message_area_set_status (EV_PROGRESS_MESSAGE_AREA (ev_window->priv->message_area), + status); + ev_progress_message_area_set_fraction (EV_PROGRESS_MESSAGE_AREA (ev_window->priv->message_area), + fraction); + + g_free (status); +} + +static void +ev_window_save_remote (EvWindow *ev_window, + EvSaveType save_type, + GFile *src, + GFile *dst) +{ + ev_window_reset_progress_cancellable (ev_window); g_object_set_data (G_OBJECT (dst), "ev-window", ev_window); + g_object_set_data (G_OBJECT (dst), "save-type", GINT_TO_POINTER (save_type)); g_file_copy_async (src, dst, G_FILE_COPY_OVERWRITE, - G_PRIORITY_DEFAULT, NULL, - NULL, NULL, /* no progress callback */ - (GAsyncReadyCallback) window_save_file_copy_ready_cb, - dst); + G_PRIORITY_DEFAULT, + ev_window->priv->progress_cancellable, + (GFileProgressCallback)window_save_file_copy_progress_cb, + dst, + (GAsyncReadyCallback)window_save_file_copy_ready_cb, + dst); + ev_window->priv->progress_idle = + g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, + 1, + (GSourceFunc)show_saving_progress, + dst, + NULL); } static void @@ -2216,6 +2547,9 @@ file_save_dialog_response_cb (GtkWidget *fc, } uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (fc)); + /* FIXME: remote copy should be done here rather than in the save job, + * so that we can track progress and cancel the operation + */ ev_window_clear_save_job (ev_window); ev_window->priv->save_job = ev_job_save_new (ev_window->priv->document, @@ -2615,13 +2949,13 @@ ev_window_print_range (EvWindow *ev_window, ev_window->priv->print_queue = g_queue_new (); op = ev_print_operation_new (ev_window->priv->document); - g_signal_connect (G_OBJECT (op), "begin_print", + g_signal_connect (op, "begin_print", G_CALLBACK (ev_window_print_operation_begin_print), (gpointer)ev_window); - g_signal_connect (G_OBJECT (op), "status_changed", + g_signal_connect (op, "status_changed", G_CALLBACK (ev_window_print_operation_status_changed), (gpointer)ev_window); - g_signal_connect (G_OBJECT (op), "done", + g_signal_connect (op, "done", G_CALLBACK (ev_window_print_operation_done), (gpointer)ev_window); @@ -2775,7 +3109,7 @@ ev_window_cmd_file_close_window (GtkAction *action, EvWindow *ev_window) GTK_RESPONSE_NO, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - _("Close after _Printing"), + _("Close _after Printing"), GTK_RESPONSE_YES, NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES); @@ -3750,7 +4084,7 @@ save_sizing_mode (EvWindow *window) GEnumValue *enum_value; mode = ev_view_get_sizing_mode (EV_VIEW (window->priv->view)); - enum_value = g_enum_get_value (EV_SIZING_MODE_CLASS, mode); + enum_value = g_enum_get_value (g_type_class_peek (EV_TYPE_SIZING_MODE), mode); if (!ev_window_is_empty (window)) ev_metadata_manager_set_string (window->priv->uri, "sizing_mode", @@ -4374,6 +4708,40 @@ zoom_control_changed_cb (EphyZoomAction *action, } } +static void +ev_window_drag_data_received (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time) + +{ + EvWindow *window = EV_WINDOW (widget); + gchar **uris; + gint i = 0; + GSList *uri_list = NULL; + + uris = gtk_selection_data_get_uris (selection_data); + if (!uris) { + gtk_drag_finish (context, FALSE, FALSE, time); + return; + } + + for (i = 0; uris[i]; i++) { + uri_list = g_slist_prepend (uri_list, (gpointer) uris[i]); + } + + ev_application_open_uri_list (EV_APP, uri_list, + gtk_window_get_screen (GTK_WINDOW (window)), + 0); + gtk_drag_finish (context, TRUE, FALSE, time); + + g_strfreev (uris); + g_slist_free (uri_list); +} + static void ev_window_finalize (GObject *object) { @@ -4495,6 +4863,12 @@ ev_window_dispose (GObject *object) priv->local_uri = NULL; } + ev_window_clear_progress_idle (window); + if (priv->progress_cancellable) { + g_object_unref (priv->progress_cancellable); + priv->progress_cancellable = NULL; + } + ev_window_close_dialogs (window); if (window->priv->printer) { @@ -4545,6 +4919,11 @@ ev_window_dispose (GObject *object) priv->uri = NULL; } + if (priv->search_string) { + g_free (priv->search_string); + priv->search_string = NULL; + } + if (priv->dest) { g_object_unref (priv->dest); priv->dest = NULL; @@ -4584,6 +4963,7 @@ ev_window_class_init (EvWindowClass *ev_window_class) widget_class->screen_changed = ev_window_screen_changed; widget_class->window_state_event = ev_window_state_event; + widget_class->drag_data_received = ev_window_drag_data_received; g_type_class_add_private (g_object_class, sizeof (EvWindowPrivate)); } @@ -5332,9 +5712,10 @@ image_save_dialog_response_cb (GtkWidget *fc, if (!is_native) { GFile *source_file; - source_file = g_file_new_for_uri (filename); + source_file = g_file_new_for_path (filename); - ev_window_save_remote (ev_window, source_file, target_file); + ev_window_save_remote (ev_window, EV_SAVE_IMAGE, + source_file, target_file); g_object_unref (source_file); } @@ -5481,7 +5862,8 @@ attachment_save_dialog_response_cb (GtkWidget *fc, dest_file = g_object_ref (target_file); } - ev_window_save_remote (ev_window, save_to, dest_file); + ev_window_save_remote (ev_window, EV_SAVE_ATTACHMENT, + save_to, dest_file); g_object_unref (dest_file); } @@ -5877,6 +6259,13 @@ ev_window_init (EvWindow *ev_window) ev_window_sizing_mode_changed_cb (EV_VIEW (ev_window->priv->view), NULL, ev_window); ev_window_setup_action_sensitivity (ev_window); + + /* Drag and Drop */ + gtk_drag_dest_set (GTK_WIDGET (ev_window), + GTK_DEST_DEFAULT_ALL, + NULL, 0, + GDK_ACTION_COPY); + gtk_drag_dest_add_uri_targets (GTK_WIDGET (ev_window)); } /**