[gnome-builder] core: add API to cancel transfers via actions



commit 96294117445fe2e0ccb6edfb7e3be8e4a866246f
Author: Christian Hergert <chergert redhat com>
Date:   Thu Mar 14 13:26:10 2019 -0700

    core: add API to cancel transfers via actions

 po/POTFILES.in                                 |  1 +
 src/libide/core/ide-transfer-manager-private.h | 33 +++++++++++++++
 src/libide/core/ide-transfer-manager.c         | 56 +++++++++++++++++++++++++-
 src/libide/core/ide-transfer.c                 | 28 +++++++++++++
 src/libide/core/meson.build                    |  7 +++-
 5 files changed, 122 insertions(+), 3 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 779997524..93ec86d22 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -42,6 +42,7 @@ src/libide/code/ide-unsaved-files.c
 src/libide/core/ide-context.c
 src/libide/core/ide-global.c
 src/libide/core/ide-settings.c
+src/libide/core/ide-transfer.c
 src/libide/debugger/ide-debug-manager.c
 src/libide/editor/ide-editor-page-actions.c
 src/libide/editor/ide-editor-page-shortcuts.c
diff --git a/src/libide/core/ide-transfer-manager-private.h b/src/libide/core/ide-transfer-manager-private.h
new file mode 100644
index 000000000..0f493e746
--- /dev/null
+++ b/src/libide/core/ide-transfer-manager-private.h
@@ -0,0 +1,33 @@
+/* ide-transfer-manager-private.h
+ *
+ * Copyright 2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "ide-transfer.h"
+#include "ide-transfer-manager.h"
+
+G_BEGIN_DECLS
+
+GActionGroup *_ide_transfer_manager_get_actions  (IdeTransferManager *self);
+void          _ide_transfer_manager_cancel_by_id (IdeTransferManager *self,
+                                                  gint                unique_id);
+gint          _ide_transfer_get_id               (IdeTransfer        *self);
+
+G_END_DECLS
diff --git a/src/libide/core/ide-transfer-manager.c b/src/libide/core/ide-transfer-manager.c
index 66011bf71..549e9fc67 100644
--- a/src/libide/core/ide-transfer-manager.c
+++ b/src/libide/core/ide-transfer-manager.c
@@ -28,11 +28,13 @@
 
 #include "ide-transfer.h"
 #include "ide-transfer-manager.h"
+#include "ide-transfer-manager-private.h"
 
 struct _IdeTransferManager
 {
-  GObject    parent_instance;
-  GPtrArray *transfers;
+  GObject             parent_instance;
+  GPtrArray          *transfers;
+  GSimpleActionGroup *actions;
 };
 
 static void list_model_iface_init (GListModelInterface *iface);
@@ -88,6 +90,7 @@ ide_transfer_manager_finalize (GObject *object)
   IdeTransferManager *self = (IdeTransferManager *)object;
 
   g_clear_pointer (&self->transfers, g_ptr_array_unref);
+  g_clear_object (&self->actions);
 
   G_OBJECT_CLASS (ide_transfer_manager_parent_class)->finalize (object);
 }
@@ -209,6 +212,7 @@ ide_transfer_manager_class_init (IdeTransferManagerClass *klass)
 static void
 ide_transfer_manager_init (IdeTransferManager *self)
 {
+  self->actions = g_simple_action_group_new ();
   self->transfers = g_ptr_array_new_with_free_func (g_object_unref);
 }
 
@@ -227,6 +231,8 @@ static gboolean
 ide_transfer_manager_append (IdeTransferManager *self,
                              IdeTransfer        *transfer)
 {
+  g_autofree gchar *action_name = NULL;
+  g_autoptr(GSimpleAction) action = NULL;
   guint position;
 
   IDE_ENTRY;
@@ -250,6 +256,15 @@ ide_transfer_manager_append (IdeTransferManager *self,
   g_ptr_array_add (self->transfers, g_object_ref (transfer));
   g_list_model_items_changed (G_LIST_MODEL (self), position, 0, 1);
 
+  action_name = g_strdup_printf ("cancel-%d", _ide_transfer_get_id (transfer));
+  action = g_simple_action_new (action_name, NULL);
+  g_signal_connect_object (action,
+                           "activate",
+                           G_CALLBACK (ide_transfer_cancel),
+                           transfer,
+                           G_CONNECT_SWAPPED);
+  g_action_map_add_action (G_ACTION_MAP (self->actions), G_ACTION (action));
+
   IDE_RETURN (TRUE);
 }
 
@@ -290,6 +305,11 @@ ide_transfer_manager_clear (IdeTransferManager *self)
 
       if (!ide_transfer_get_active (transfer))
         {
+          g_autofree gchar *action_name = NULL;
+
+          action_name = g_strdup_printf ("cancel-%d", _ide_transfer_get_id (transfer));
+          g_action_map_remove_action (G_ACTION_MAP (self->actions), action_name);
+
           g_ptr_array_remove_index (self->transfers, i - 1);
           g_list_model_items_changed (G_LIST_MODEL (self), i - 1, 1, 0);
         }
@@ -491,3 +511,35 @@ ide_transfer_manager_get_default (void)
 
   return instance;
 }
+
+void
+_ide_transfer_manager_cancel_by_id (IdeTransferManager *self,
+                                    gint                unique_id)
+{
+  g_return_if_fail (IDE_IS_MAIN_THREAD ());
+  g_return_if_fail (IDE_IS_TRANSFER_MANAGER (self));
+
+  g_print ("Cancelling transfer %i\n", unique_id);
+
+  for (guint i = 0; i < self->transfers->len; i++)
+    {
+      IdeTransfer *transfer = g_ptr_array_index (self->transfers, i);
+
+      if (_ide_transfer_get_id (transfer) == unique_id)
+        {
+          ide_transfer_cancel (transfer);
+          break;
+        }
+    }
+}
+
+GActionGroup *
+_ide_transfer_manager_get_actions (IdeTransferManager *self)
+{
+  if (self == NULL)
+    self = ide_transfer_manager_get_default ();
+
+  g_return_val_if_fail (IDE_IS_TRANSFER_MANAGER (self), NULL);
+
+  return G_ACTION_GROUP (self->actions);
+}
diff --git a/src/libide/core/ide-transfer.c b/src/libide/core/ide-transfer.c
index a3c35b3e0..25fefe5b7 100644
--- a/src/libide/core/ide-transfer.c
+++ b/src/libide/core/ide-transfer.c
@@ -22,9 +22,12 @@
 
 #include "config.h"
 
+#include <glib/gi18n.h>
+
 #include "ide-debug.h"
 #include "ide-macros.h"
 #include "ide-transfer.h"
+#include "ide-transfer-manager-private.h"
 
 typedef struct
 {
@@ -33,6 +36,7 @@ typedef struct
   gchar *title;
   GCancellable *cancellable;
   gdouble progress;
+  gint unique_id;
   guint active : 1;
   guint completed : 1;
 } IdeTransferPrivate;
@@ -51,6 +55,7 @@ enum {
 G_DEFINE_TYPE_WITH_PRIVATE (IdeTransfer, ide_transfer, IDE_TYPE_OBJECT)
 
 static GParamSpec *properties [N_PROPS];
+static gint last_unique_id;
 
 static void
 ide_transfer_real_execute_async (IdeTransfer         *self,
@@ -224,6 +229,9 @@ ide_transfer_class_init (IdeTransferClass *klass)
 static void
 ide_transfer_init (IdeTransfer *self)
 {
+  IdeTransferPrivate *priv = ide_transfer_get_instance_private (self);
+
+  priv->unique_id = ++last_unique_id;
 }
 
 static void
@@ -499,12 +507,16 @@ ide_transfer_create_notification (IdeTransfer *self)
 {
   IdeTransferPrivate *priv = ide_transfer_get_instance_private (self);
   g_autoptr(IdeNotification) notif = NULL;
+  g_autofree gchar *action_name = NULL;
+  g_autoptr(GIcon) icon = NULL;
 
   g_return_val_if_fail (IDE_IS_TRANSFER (self), NULL);
 
   if (priv->completed)
     return NULL;
 
+  icon = g_themed_icon_new ("media-playback-stop-symbolic");
+
   notif = ide_notification_new ();
   ide_notification_set_has_progress (notif, TRUE);
   g_object_bind_property (self, "title", notif, "title", G_BINDING_SYNC_CREATE);
@@ -512,6 +524,12 @@ ide_transfer_create_notification (IdeTransfer *self)
   g_object_bind_property (self, "progress", notif, "progress", G_BINDING_SYNC_CREATE);
   g_object_bind_property (self, "icon-name", notif, "icon-name", G_BINDING_SYNC_CREATE);
 
+  /* We avoid using params beacuse it causes buttons to go into toggle-mode
+   * using action state.
+   */
+  action_name = g_strdup_printf ("transfer-manager.cancel-%d", priv->unique_id);
+  ide_notification_add_button (notif, _("Cancel"), icon, action_name);
+
   g_signal_connect_object (self,
                            "notify::completed",
                            G_CALLBACK (ide_transfer_notification_notify_completed),
@@ -520,3 +538,13 @@ ide_transfer_create_notification (IdeTransfer *self)
 
   return g_steal_pointer (&notif);
 }
+
+gint
+_ide_transfer_get_id (IdeTransfer *self)
+{
+  IdeTransferPrivate *priv = ide_transfer_get_instance_private (self);
+
+  g_return_val_if_fail (IDE_IS_TRANSFER (self), 0);
+
+  return priv->unique_id;
+}
diff --git a/src/libide/core/meson.build b/src/libide/core/meson.build
index 4713ca157..1fa82fad9 100644
--- a/src/libide/core/meson.build
+++ b/src/libide/core/meson.build
@@ -69,6 +69,10 @@ libide_core_public_headers = [
   'libide-core.h',
 ]
 
+libide_core_private_headers = [
+  'ide-transfer-manager-private.h',
+]
+
 install_headers(libide_core_public_headers, subdir: libide_core_header_subdir)
 
 #
@@ -111,7 +115,7 @@ libide_core = static_library('ide-core-' + libide_api_version, libide_core_sourc
 )
 
 libide_core_dep = declare_dependency(
-              sources: libide_core_generated_headers,
+              sources: libide_core_private_headers + libide_core_generated_headers,
          dependencies: libide_core_deps,
            link_whole: libide_core,
   include_directories: include_directories('.'),
@@ -119,6 +123,7 @@ libide_core_dep = declare_dependency(
 
 gnome_builder_public_sources += files(libide_core_public_sources)
 gnome_builder_public_headers += files(libide_core_public_headers)
+gnome_builder_private_headers += files(libide_core_private_headers)
 gnome_builder_generated_headers += libide_core_generated_headers
 gnome_builder_include_subdirs += libide_core_header_subdir
 gnome_builder_gir_extra_args += ['--c-include=libide-core.h', '-DIDE_CORE_COMPILATION']


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]