[gnome-flashback] desktop: disable Empty Trash if trash is empty



commit 78914e9ad101156e90b16975c4de54dd17da3e6f
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Fri Nov 15 19:01:28 2019 +0200

    desktop: disable Empty Trash if trash is empty

 gnome-flashback/libdesktop/gf-icon.c       |  5 ++
 gnome-flashback/libdesktop/gf-trash-icon.c | 93 ++++++++++++++++++++++++++++++
 gnome-flashback/libdesktop/gf-trash-icon.h |  6 +-
 3 files changed, 102 insertions(+), 2 deletions(-)
---
diff --git a/gnome-flashback/libdesktop/gf-icon.c b/gnome-flashback/libdesktop/gf-icon.c
index 69239a9..41463ef 100644
--- a/gnome-flashback/libdesktop/gf-icon.c
+++ b/gnome-flashback/libdesktop/gf-icon.c
@@ -219,11 +219,16 @@ create_popup_menu (GfIcon *self)
   if (GF_IS_TRASH_ICON (self) &&
       n_selected_icons == 1)
     {
+      gboolean is_empty;
+
       item = gtk_separator_menu_item_new ();
       gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
       gtk_widget_show (item);
 
+      is_empty = gf_trash_icon_is_empty (GF_TRASH_ICON (self));
+
       item = gtk_menu_item_new_with_label (_("Empty Trash"));
+      gtk_widget_set_sensitive (item, !is_empty);
       gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
       gtk_widget_show (item);
 
diff --git a/gnome-flashback/libdesktop/gf-trash-icon.c b/gnome-flashback/libdesktop/gf-trash-icon.c
index 1900a4a..55b8bf6 100644
--- a/gnome-flashback/libdesktop/gf-trash-icon.c
+++ b/gnome-flashback/libdesktop/gf-trash-icon.c
@@ -25,10 +25,93 @@ struct _GfTrashIcon
   GCancellable *cancellable;
 
   GFileMonitor *monitor;
+
+  gboolean      empty;
 };
 
 G_DEFINE_TYPE (GfTrashIcon, gf_trash_icon, GF_TYPE_ICON)
 
+static void
+next_files_cb (GObject      *object,
+               GAsyncResult *res,
+               gpointer      user_data)
+{
+  GFileEnumerator *enumerator;
+  GList *files;
+  GError *error;
+  GfTrashIcon *self;
+
+  enumerator = G_FILE_ENUMERATOR (object);
+
+  error = NULL;
+  files = g_file_enumerator_next_files_finish (enumerator, res, &error);
+
+  if (error != NULL)
+    {
+      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+        g_warning ("%s", error->message);
+
+      g_error_free (error);
+      return;
+    }
+
+  self = GF_TRASH_ICON (user_data);
+  self->empty = files == NULL;
+
+  g_list_free_full (files, g_object_unref);
+}
+
+static void
+enumerate_children_cb (GObject      *object,
+                       GAsyncResult *res,
+                       gpointer      user_data)
+{
+  GFileEnumerator *enumerator;
+  GError *error;
+  GfTrashIcon *self;
+
+  error = NULL;
+  enumerator = g_file_enumerate_children_finish (G_FILE (object), res, &error);
+
+  if (error != NULL)
+    {
+      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+        g_warning ("%s", error->message);
+
+      g_error_free (error);
+      return;
+    }
+
+  self = GF_TRASH_ICON (user_data);
+  self->empty = TRUE;
+
+  g_file_enumerator_next_files_async (enumerator,
+                                      1,
+                                      G_PRIORITY_LOW,
+                                      self->cancellable,
+                                      next_files_cb,
+                                      user_data);
+
+  g_object_unref (enumerator);
+}
+
+static void
+check_if_empty (GfTrashIcon *self)
+{
+  g_cancellable_cancel (self->cancellable);
+  g_clear_object (&self->cancellable);
+
+  self->cancellable = g_cancellable_new ();
+
+  g_file_enumerate_children_async (gf_icon_get_file (GF_ICON (self)),
+                                   NULL,
+                                   G_FILE_QUERY_INFO_NONE,
+                                   G_PRIORITY_LOW,
+                                   self->cancellable,
+                                   enumerate_children_cb,
+                                   self);
+}
+
 static void
 trash_changed_cb (GFileMonitor      *monitor,
                   GFile             *file,
@@ -43,6 +126,7 @@ trash_changed_cb (GFileMonitor      *monitor,
       case G_FILE_MONITOR_EVENT_MOVED_IN:
       case G_FILE_MONITOR_EVENT_MOVED_OUT:
         gf_icon_update (GF_ICON (self));
+        check_if_empty (self);
         break;
 
       case G_FILE_MONITOR_EVENT_CHANGED:
@@ -83,6 +167,8 @@ gf_trash_icon_constructed (GObject *object)
   g_signal_connect (self->monitor, "changed",
                     G_CALLBACK (trash_changed_cb),
                     self);
+
+  check_if_empty (self);
 }
 
 static void
@@ -115,6 +201,7 @@ static void
 gf_trash_icon_init (GfTrashIcon *self)
 {
   self->cancellable = g_cancellable_new ();
+  self->empty = TRUE;
 }
 
 GtkWidget *
@@ -152,3 +239,9 @@ gf_trash_icon_new (GfIconView  *icon_view,
 
   return widget;
 }
+
+gboolean
+gf_trash_icon_is_empty (GfTrashIcon *self)
+{
+  return self->empty;
+}
diff --git a/gnome-flashback/libdesktop/gf-trash-icon.h b/gnome-flashback/libdesktop/gf-trash-icon.h
index f16a67b..98bf273 100644
--- a/gnome-flashback/libdesktop/gf-trash-icon.h
+++ b/gnome-flashback/libdesktop/gf-trash-icon.h
@@ -25,8 +25,10 @@ G_BEGIN_DECLS
 #define GF_TYPE_TRASH_ICON (gf_trash_icon_get_type ())
 G_DECLARE_FINAL_TYPE (GfTrashIcon, gf_trash_icon, GF, TRASH_ICON, GfIcon)
 
-GtkWidget *gf_trash_icon_new (GfIconView  *icon_view,
-                              GError     **error);
+GtkWidget *gf_trash_icon_new      (GfIconView   *icon_view,
+                                   GError      **error);
+
+gboolean   gf_trash_icon_is_empty (GfTrashIcon  *self);
 
 G_END_DECLS
 


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