From 17c25e5bdfa617b67ac3a40f4d7a43f70cb8e91f Mon Sep 17 00:00:00 2001 From: Ting-Wei Lan Date: Sun, 15 Sep 2013 18:22:23 +0800 Subject: Archive creating can be cancelled --- embed/ephy-web-view.c | 89 ++++++++++++++++++++++++++++++++++++++----- embed/ephy-web-view.h | 2 + src/ephy-window.c | 4 ++ src/resources/epiphany-ui.xml | 1 + src/window-commands.c | 15 ++++++++ src/window-commands.h | 2 + 6 files changed, 103 insertions(+), 10 deletions(-) diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c index 033c6eb5c..298a6fc8e 100644 --- a/embed/ephy-web-view.c +++ b/embed/ephy-web-view.c @@ -76,6 +76,7 @@ struct _EphyWebViewPrivate { /* Flags */ guint is_blank : 1; guint is_setting_zoom : 1; + guint is_archiving : 1; guint load_failed : 1; guint history_frozen : 1; @@ -111,6 +112,9 @@ struct _EphyWebViewPrivate { /* TLS information. */ GTlsCertificate *certificate; GTlsCertificateFlags tls_errors; + + /* Archive cancellable */ + GCancellable *archive_cancellable; }; typedef struct { @@ -133,6 +137,7 @@ enum { PROP_EMBED_TITLE, PROP_TYPED_ADDRESS, PROP_IS_BLANK, + PROP_IS_ARCHIVING }; #define EPHY_WEB_VIEW_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_WEB_VIEW, EphyWebViewPrivate)) @@ -403,6 +408,9 @@ ephy_web_view_get_property (GObject *object, case PROP_IS_BLANK: g_value_set_boolean (value, priv->is_blank); break; + case PROP_IS_ARCHIVING: + g_value_set_boolean (value, priv->is_archiving); + break; default: break; } @@ -432,6 +440,7 @@ ephy_web_view_set_property (GObject *object, case PROP_STATUS_MESSAGE: case PROP_EMBED_TITLE: case PROP_IS_BLANK: + case PROP_IS_ARCHIVING: /* read only */ break; default: @@ -681,6 +690,11 @@ ephy_web_view_dispose (GObject *object) g_clear_object(&priv->certificate); + if (priv->archive_cancellable) { + g_cancellable_cancel (priv->archive_cancellable); + g_clear_object (&priv->archive_cancellable); + } + G_OBJECT_CLASS (ephy_web_view_parent_class)->dispose (object); } @@ -1061,6 +1075,19 @@ ephy_web_view_class_init (EphyWebViewClass *klass) FALSE, G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); +/** + * EphyWebView:is-archiving: + * + * Whether the view is archiving files. + **/ + g_object_class_install_property (gobject_class, + PROP_IS_ARCHIVING, + g_param_spec_boolean ("is-archiving", + "Is archiving", + "If the EphyWebView is archiving", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + /** * EphyWebView::new-window: * @view: the #EphyWebView that received the signal @@ -1890,7 +1917,6 @@ typedef struct { typedef struct { FileChooserInfo *info; - GCancellable *cancellable; GPtrArray *wk_filenames; GSList *filenames; char *dest; @@ -1929,8 +1955,6 @@ archive_info_free (ArchiveInfo *ainfo) { if (ainfo->info != NULL) g_free (ainfo->info); - if (ainfo->cancellable != NULL) - g_object_unref (ainfo->cancellable); if (ainfo->wk_filenames != NULL) g_ptr_array_unref (ainfo->wk_filenames); if (ainfo->filenames != NULL) @@ -1965,6 +1989,8 @@ run_file_chooser_cancel (ArchiveInfo *ainfo, GError *error, const char *reason) gtk_widget_destroy (error_dialog); } + web_view->priv->is_archiving = FALSE; + g_cancellable_reset (web_view->priv->archive_cancellable); archive_info_free (ainfo); } @@ -1982,6 +2008,8 @@ run_file_chooser_complete (ArchiveInfo *ainfo) web_view->priv->status_message = NULL; g_object_notify (G_OBJECT (web_view), "status-message"); + web_view->priv->is_archiving = FALSE; + g_cancellable_reset (web_view->priv->archive_cancellable); archive_info_free (ainfo); } @@ -2002,12 +2030,14 @@ run_file_chooser_next (ArchiveInfo *ainfo, gboolean add_to_wk_filenames) run_file_chooser_complete (ainfo); } else { GFile *file; + EphyWebView *web_view; file = g_file_new_for_path (ainfo->filenames->data); + web_view = EPHY_WEB_VIEW (ainfo->info->web_view); g_file_query_info_async (file, G_FILE_ATTRIBUTE_STANDARD_TYPE, G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT, - ainfo->cancellable, + web_view->priv->archive_cancellable, (GAsyncReadyCallback)file_query_info_cb, ainfo); } @@ -2068,6 +2098,7 @@ file_query_info_cb (GFile *file, GAsyncResult *res, ArchiveInfo *ainfo) { + EphyWebView *web_view; GFileInfo *file_info; GFileType file_type; GError *error; @@ -2082,6 +2113,12 @@ file_query_info_cb (GFile *file, return; } + web_view = EPHY_WEB_VIEW (ainfo->info->web_view); + if (g_cancellable_is_cancelled (web_view->priv->archive_cancellable)) { + run_file_chooser_cancel (ainfo, NULL, NULL); + return; + } + file_type = g_file_info_get_file_type (file_info); if (file_type == G_FILE_TYPE_DIRECTORY) { AutoarCreate *arcreate; @@ -2104,7 +2141,7 @@ file_query_info_cb (GFile *file, g_signal_connect (arcreate, "error", G_CALLBACK (archive_error_cb), ainfo); - autoar_create_start_async (arcreate, ainfo->cancellable); + autoar_create_start_async (arcreate, web_view->priv->archive_cancellable); g_object_unref (arcreate); g_free (output); g_free (tmp); @@ -2119,21 +2156,27 @@ run_file_chooser_response_cb (GtkFileChooser *file_chooser, int response_id, FileChooserInfo *info) { + EphyWebView *web_view; + GCancellable *cancellable; + + web_view = EPHY_WEB_VIEW (info->web_view); + cancellable = web_view->priv->archive_cancellable; + g_cancellable_reset (cancellable); + if (response_id == GTK_RESPONSE_OK || response_id == EPHY_RESPONSE_SELECT) { ArchiveInfo *ainfo; - GCancellable *cancellable; GSList *filenames, *iter; int format, filter; int c; + web_view->priv->is_archiving = TRUE; + filenames = gtk_file_chooser_get_filenames (file_chooser); autoar_gtk_format_filter_simple_get (info->format, &format, &filter); for (iter = filenames, c = 0; iter != NULL; iter = iter->next, c++); - cancellable = g_cancellable_new (); ainfo = g_new (ArchiveInfo, 1); ainfo->info = info; - ainfo->cancellable = g_object_ref (cancellable); ainfo->wk_filenames = g_ptr_array_new_with_free_func (g_free); ainfo->filenames = NULL; ainfo->dest = NULL; @@ -2203,8 +2246,6 @@ run_file_chooser_response_cb (GtkFileChooser *file_chooser, ainfo); } - g_object_unref (cancellable); - } else { webkit_file_chooser_request_cancel (info->request); file_chooser_info_free (info); @@ -2463,6 +2504,7 @@ ephy_web_view_init (EphyWebView *web_view) priv = web_view->priv = EPHY_WEB_VIEW_GET_PRIVATE (web_view); priv->is_blank = TRUE; + priv->is_archiving = TRUE; priv->title = g_strdup (EMPTY_PAGE); priv->document_type = EPHY_WEB_VIEW_DOCUMENT_HTML; priv->security_level = EPHY_WEB_VIEW_STATE_IS_UNKNOWN; @@ -2477,6 +2519,7 @@ ephy_web_view_init (EphyWebView *web_view) priv->history_service = EPHY_HISTORY_SERVICE (ephy_embed_shell_get_global_history_service (ephy_embed_shell_get_default ())); priv->history_service_cancellable = g_cancellable_new (); + priv->archive_cancellable = g_cancellable_new (); g_signal_connect (priv->history_service, "cleared", G_CALLBACK (ephy_web_view_history_cleared_cb), @@ -2804,6 +2847,32 @@ ephy_web_view_get_is_blank (EphyWebView *view) return view->priv->is_blank; } +/** + * ephy_web_view_get_is_archiving: + * @view: an #EphyWebView + * + * Returns whether the @view is archiving files. + * + * Return value: %TRUE if the @view is archiving files. + **/ +gboolean +ephy_web_view_get_is_archiving (EphyWebView *view) +{ + return view->priv->is_archiving; +} + +/** + * ephy_web_view_cancel_archiving: + * @view: an #EphyWebView + * + * Cancel the @view's archive work. + **/ +void +ephy_web_view_cancel_archiving (EphyWebView *view) +{ + g_cancellable_cancel (view->priv->archive_cancellable); +} + /** * ephy_web_view_get_address: * @view: an #EphyWebView diff --git a/embed/ephy-web-view.h b/embed/ephy-web-view.h index a24f96269..d22ac4586 100644 --- a/embed/ephy-web-view.h +++ b/embed/ephy-web-view.h @@ -144,6 +144,8 @@ const char * ephy_web_view_get_typed_address (EphyWebView void ephy_web_view_set_typed_address (EphyWebView *view, const char *address); gboolean ephy_web_view_get_is_blank (EphyWebView *view); +gboolean ephy_web_view_get_is_archiving (EphyWebView *view); +void ephy_web_view_cancel_archiving (EphyWebView *view); gboolean ephy_web_view_has_modified_forms (EphyWebView *view); void ephy_web_view_get_security_level (EphyWebView *view, EphyWebViewSecurityLevel *level, diff --git a/src/ephy-window.c b/src/ephy-window.c index bec411398..c05734ab8 100644 --- a/src/ephy-window.c +++ b/src/ephy-window.c @@ -168,6 +168,8 @@ static const GtkActionEntry ephy_menu_entries [] = { { "ViewEncoding", NULL, N_("Text _Encoding"), NULL, NULL, NULL }, { "ViewPageSource", NULL, N_("_Page Source"), "U", NULL, G_CALLBACK (window_cmd_view_page_source) }, + { "ViewStopArchiving", NULL, N_("Stop _Archiving"), NULL, NULL, + G_CALLBACK (window_cmd_view_stop_archiving) }, /* Bookmarks actions. */ @@ -1994,6 +1996,8 @@ populate_context_menu (WebKitWebView *web_view, priv->toolbar_action_group, "NavigationForward"); add_action_to_context_menu (context_menu, priv->action_group, "ViewReload"); + add_action_to_context_menu (context_menu, + priv->action_group, "ViewStopArchiving"); webkit_context_menu_append (context_menu, webkit_context_menu_item_new_separator ()); add_action_to_context_menu (context_menu, diff --git a/src/resources/epiphany-ui.xml b/src/resources/epiphany-ui.xml index 976dddce4..14906bcd3 100644 --- a/src/resources/epiphany-ui.xml +++ b/src/resources/epiphany-ui.xml @@ -23,6 +23,7 @@ + diff --git a/src/window-commands.c b/src/window-commands.c index 9f61c27e4..d3cf07fe1 100644 --- a/src/window-commands.c +++ b/src/window-commands.c @@ -1659,6 +1659,21 @@ window_cmd_view_page_source (GtkAction *action, } } +void +window_cmd_view_stop_archiving (GtkAction *action, + EphyWindow *window) +{ + EphyEmbed *embed; + EphyWebView *view; + + embed = ephy_embed_container_get_active_child + (EPHY_EMBED_CONTAINER (window)); + g_return_if_fail (EPHY_IS_EMBED (embed)); + view = ephy_embed_get_web_view (embed); + + ephy_web_view_cancel_archiving (view); +} + #define ABOUT_GROUP "About" void diff --git a/src/window-commands.h b/src/window-commands.h index abf5865d6..885c4034b 100644 --- a/src/window-commands.h +++ b/src/window-commands.h @@ -84,6 +84,8 @@ void window_cmd_view_zoom_normal (GtkAction *action, EphyWindow *window); void window_cmd_view_page_source (GtkAction *action, EphyWindow *window); +void window_cmd_view_stop_archiving (GtkAction *action, + EphyWindow *window); void window_cmd_help_about (GtkAction *action, GtkWidget *window); void window_cmd_tabs_next (GtkAction *action, -- cgit v1.2.3