[nautilus/wip/delete_notification: 5/6] general: Add in app notification for move to trash



commit 0de1492999058361efec3758fca86c1ee03ab1ba
Author: Carlos Soriano <csoriano gnome org>
Date:   Tue Jan 27 17:48:05 2015 +0100

    general: Add in app notification for move to trash
    
    We want to make sure the user has feedback when moving files to trash,
    so add an in app notification when some file has been moved to trash.
    
    Currently the notification manager only supports one notification at
    once, since the undo machinery only support to undo the last operation,
    not a specific operation.
    Even if we add support to it I'm not sure if multiple notifications of
    deleted files would be good, so instead of that just show one at once.
    
    To achieve that, connect to the undo state and delete all notification
    when the undo state changes. For that reason, we have to make sure that
    that's called before we add the new notification. So we set the undo
    action before the delete_callback, where the new notification is added.

 libnautilus-private/nautilus-file-operations.c |   42 +++++-
 src/Makefile.am                                |    4 +
 src/nautilus-notification-delete.c             |  226 ++++++++++++++++++++++++
 src/nautilus-notification-delete.h             |   59 ++++++
 src/nautilus-notification-manager.c            |  104 +++++++++++
 src/nautilus-notification-manager.h            |   58 ++++++
 src/nautilus-view.c                            |   21 ++-
 src/nautilus-window-slot.c                     |   22 +++
 src/nautilus-window-slot.h                     |    3 +
 9 files changed, 536 insertions(+), 3 deletions(-)
---
diff --git a/libnautilus-private/nautilus-file-operations.c b/libnautilus-private/nautilus-file-operations.c
index 0315a46..ae38e75 100644
--- a/libnautilus-private/nautilus-file-operations.c
+++ b/libnautilus-private/nautilus-file-operations.c
@@ -971,7 +971,6 @@ finalize_common (CommonJob *common)
        }
 
        if (common->undo_info != NULL) {
-               nautilus_file_undo_manager_set_action (common->undo_info);
                g_object_unref (common->undo_info);
        }
 
@@ -1903,6 +1902,15 @@ delete_job_done (gpointer user_data)
 
        g_list_free_full (job->files, g_object_unref);
 
+       /* It's important the undo action is set before the callback and only here,
+        * since the callback is creating a notification for undo, but the notification
+        * manager is removing all notifications when the undo state changes, since
+        * it only supports one notification at once.
+        */
+       if (job->common.undo_info != NULL) {
+               nautilus_file_undo_manager_set_action (job->common.undo_info);
+       }
+
        if (job->done_callback) {
                debuting_uris = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, g_object_unref, 
NULL);
                job->done_callback (debuting_uris, job->user_cancel, job->done_callback_data);
@@ -4565,6 +4573,11 @@ copy_job_done (gpointer user_data)
        CopyMoveJob *job;
 
        job = user_data;
+
+       if (job->common.undo_info != NULL) {
+               nautilus_file_undo_manager_set_action (job->common.undo_info);
+       }
+
        if (job->done_callback) {
                job->done_callback (job->debuting_files, 
                                    !job_aborted ((CommonJob *) job),
@@ -5131,6 +5144,11 @@ move_job_done (gpointer user_data)
        CopyMoveJob *job;
 
        job = user_data;
+
+       if (job->common.undo_info != NULL) {
+               nautilus_file_undo_manager_set_action (job->common.undo_info);
+       }
+
        if (job->done_callback) {
                job->done_callback (job->debuting_files,
                                    !job_aborted ((CommonJob *) job),
@@ -5474,6 +5492,11 @@ link_job_done (gpointer user_data)
        CopyMoveJob *job;
 
        job = user_data;
+
+       if (job->common.undo_info != NULL) {
+               nautilus_file_undo_manager_set_action (job->common.undo_info);
+       }
+
        if (job->done_callback) {
                job->done_callback (job->debuting_files,
                                    !job_aborted ((CommonJob *) job),
@@ -5649,6 +5672,10 @@ set_permissions_job_done (gpointer user_data)
        
        g_object_unref (job->file);
 
+       if (job->common.undo_info != NULL) {
+               nautilus_file_undo_manager_set_action (job->common.undo_info);
+       }
+
        if (job->done_callback) {
                job->done_callback (!job_aborted ((CommonJob *) job),
                                    job->done_callback_data);
@@ -5946,6 +5973,11 @@ create_job_done (gpointer user_data)
        CreateJob *job;
 
        job = user_data;
+
+       if (job->common.undo_info != NULL) {
+               nautilus_file_undo_manager_set_action (job->common.undo_info);
+       }
+
        if (job->done_callback) {
                job->done_callback (job->created_file,
                                    !job_aborted ((CommonJob *) job),
@@ -6423,6 +6455,10 @@ empty_trash_job_done (gpointer user_data)
        
        g_list_free_full (job->trash_dirs, g_object_unref);
 
+       if (job->common.undo_info != NULL) {
+               nautilus_file_undo_manager_set_action (job->common.undo_info);
+       }
+
        if (job->done_callback) {
                job->done_callback (!job_aborted ((CommonJob *) job),
                                    job->done_callback_data);
@@ -6500,6 +6536,10 @@ mark_trusted_job_done (gpointer user_data)
        
        g_object_unref (job->file);
 
+       if (job->common.undo_info != NULL) {
+               nautilus_file_undo_manager_set_action (job->common.undo_info);
+       }
+
        if (job->done_callback) {
                job->done_callback (!job_aborted ((CommonJob *) job),
                                    job->done_callback_data);
diff --git a/src/Makefile.am b/src/Makefile.am
index d797d23..82a7511 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -178,6 +178,10 @@ nautilus_SOURCES = \
        nautilus-list-view.h                    \
        nautilus-location-entry.c               \
        nautilus-location-entry.h               \
+       nautilus-notification-delete.c          \
+       nautilus-notification-delete.h          \
+       nautilus-notification-manager.c         \
+       nautilus-notification-manager.h         \
        nautilus-main.c                         \
        nautilus-mime-actions.c                 \
        nautilus-mime-actions.h                 \
diff --git a/src/nautilus-notification-delete.c b/src/nautilus-notification-delete.c
new file mode 100644
index 0000000..70b93d3
--- /dev/null
+++ b/src/nautilus-notification-delete.c
@@ -0,0 +1,226 @@
+/* nautilus-notification-delete.c
+ *
+ * Copyright (C) 2015 Carlos Soriano <csoriano gnome org>
+ *
+ * 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/>.
+ */
+
+#include <glib/gi18n.h>
+
+#include "nautilus-notification-delete.h"
+#include "nautilus-notification-manager.h"
+#include "nautilus-file-undo-manager.h"
+
+struct _NautilusNotificationDeletePrivate
+{
+  guint n_items;
+  guint timeout_id;
+  gchar *file_name;
+  NautilusWindow *window;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (NautilusNotificationDelete, nautilus_notification_delete, GTK_TYPE_GRID)
+
+enum {
+  PROP_0,
+  PROP_N_ITEMS,
+  PROP_FILE_NAME,
+  PROP_WINDOW,
+  LAST_PROP
+};
+
+enum
+{
+  NOTIFICATION_TIMEOUT = 10
+};
+
+static void
+nautilus_notification_delete_remove_timeout (NautilusNotificationDelete *self)
+{
+  if (self->priv->timeout_id != 0)
+    {
+      g_source_remove (self->priv->timeout_id);
+      self->priv->timeout_id = 0;
+    }
+}
+
+static void
+nautilus_notification_delete_destroy (NautilusNotificationDelete *self)
+{
+  nautilus_notification_delete_remove_timeout (self);
+  gtk_widget_destroy (GTK_WIDGET (self));
+}
+
+static gboolean
+nautilus_notification_delete_on_timeout (gpointer user_data)
+{
+  NautilusNotificationDelete *self = NAUTILUS_NOTIFICATION_DELETE (user_data);
+
+  self->priv->timeout_id = 0;
+  gtk_widget_destroy (GTK_WIDGET (self));
+
+  return G_SOURCE_REMOVE;
+}
+
+static void
+nautilus_notification_delete_undo_clicked (NautilusNotificationDelete *self)
+{
+  nautilus_notification_delete_remove_timeout (self);
+  /* Notification manager will destroy all notifications after the undo
+   * state changes. So no need to destroy the notification it now */
+  nautilus_file_undo_manager_undo (GTK_WINDOW (self->priv->window));
+}
+
+static void
+nautilus_notification_delete_constructed (GObject *object)
+{
+  NautilusNotificationDelete *self = NAUTILUS_NOTIFICATION_DELETE (object);
+  GtkWidget *close;
+  gchar *label;
+  GtkWidget *label_widget;
+  GtkWidget *undo;
+
+  G_OBJECT_CLASS (nautilus_notification_delete_parent_class)->constructed (object);
+
+  if (self->priv->n_items == 1) {
+    if (self->priv->file_name != NULL)
+      label = g_strdup_printf (_("%s deleted"), self->priv->file_name);
+    else
+      label = g_strdup (_("File deleted"));
+  } else {
+    label = g_strdup_printf (_("%d files deleted"),
+                             self->priv->n_items);
+  }
+  label_widget = gtk_label_new (label);
+  gtk_widget_set_halign (label_widget, GTK_ALIGN_START);
+  gtk_container_add (GTK_CONTAINER (self), label_widget);
+  gtk_widget_set_margin_end (label_widget, 30);
+
+  undo = gtk_button_new_with_label (_("Undo"));
+  gtk_widget_set_valign (undo, GTK_ALIGN_CENTER);
+  gtk_container_add (GTK_CONTAINER (self), undo);
+  gtk_widget_set_margin_end (undo, 6);
+  g_signal_connect_swapped (undo, "clicked", G_CALLBACK (nautilus_notification_delete_undo_clicked), self);
+
+  close = gtk_button_new_from_icon_name ("window-close-symbolic", GTK_ICON_SIZE_BUTTON);
+  gtk_widget_set_valign (close, GTK_ALIGN_CENTER);
+  gtk_button_set_focus_on_click (GTK_BUTTON (close), FALSE);
+  gtk_button_set_relief (GTK_BUTTON (close), GTK_RELIEF_NONE);
+  gtk_container_add (GTK_CONTAINER (self), close);
+  g_signal_connect_swapped (close, "clicked", G_CALLBACK (nautilus_notification_delete_destroy), self);
+
+  self->priv->timeout_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
+                                                       NOTIFICATION_TIMEOUT,
+                                                       nautilus_notification_delete_on_timeout,
+                                                       g_object_ref (self),
+                                                       g_object_unref);
+
+  g_free (label);
+}
+
+NautilusNotificationDelete *
+nautilus_notification_delete_new (NautilusWindow *window,
+                                  guint           n_items,
+                                  gchar          *file_name)
+{
+  g_assert (NAUTILUS_IS_WINDOW (window));
+
+  return g_object_new (NAUTILUS_TYPE_NOTIFICATION_DELETE,
+                       "window", window,
+                       "n-items", n_items,
+                       "file-name", file_name,
+                       "column-spacing", 0,
+                       "margin-start", 12,
+                       "margin-end", 4,
+                       NULL);
+}
+
+static void
+nautilus_notification_delete_set_property (GObject      *object,
+                                           guint         prop_id,
+                                           const GValue *value,
+                                           GParamSpec   *pspec)
+{
+  NautilusNotificationDelete *self = NAUTILUS_NOTIFICATION_DELETE (object);
+
+  switch (prop_id)
+    {
+    case PROP_N_ITEMS:
+      self->priv->n_items = g_value_get_int (value);
+      break;
+
+    case PROP_FILE_NAME:
+      if (self->priv->file_name != NULL)
+        g_free (self->priv->file_name);
+      self->priv->file_name = g_strdup (g_value_get_string (value));
+      break;
+
+    case PROP_WINDOW:
+      self->priv->window = NAUTILUS_WINDOW (g_value_get_pointer (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+nautilus_notification_delete_finalize (GObject *object)
+{
+  NautilusNotificationDelete *self = NAUTILUS_NOTIFICATION_DELETE (object);
+
+  if (self->priv->file_name != NULL)
+    g_free (self->priv->file_name);
+
+  G_OBJECT_CLASS (nautilus_notification_delete_parent_class)->finalize (object);
+}
+
+static void
+nautilus_notification_delete_class_init (NautilusNotificationDeleteClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->set_property = nautilus_notification_delete_set_property;
+  object_class->constructed = nautilus_notification_delete_constructed;
+  object_class->finalize= nautilus_notification_delete_finalize;
+
+  g_object_class_install_property (object_class,
+                                   PROP_N_ITEMS,
+                                   g_param_spec_int ("n-items",
+                                                     "Number of deleted items",
+                                                     "Number of items that are being deleted",
+                                                     1,
+                                                     G_MAXINT,
+                                                     1,
+                                                     G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
+  g_object_class_install_property (object_class,
+                                   PROP_FILE_NAME,
+                                   g_param_spec_string ("file-name",
+                                                        "Name of deleted file",
+                                                        "Nane of the deleted file if it was only one file",
+                                                        "",
+                                                        G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
+  g_object_class_install_property (object_class,
+                                   PROP_WINDOW,
+                                   g_param_spec_pointer ("window",
+                                                         "Window associated",
+                                                         "The window that contains the notification",
+                                                         G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
+}
+
+static void
+nautilus_notification_delete_init (NautilusNotificationDelete *self)
+{
+  self->priv = nautilus_notification_delete_get_instance_private (self);
+}
diff --git a/src/nautilus-notification-delete.h b/src/nautilus-notification-delete.h
new file mode 100644
index 0000000..3946649
--- /dev/null
+++ b/src/nautilus-notification-delete.h
@@ -0,0 +1,59 @@
+/* nautilus-notification-delete.h
+ *
+ * Copyright (C) 2015 Carlos Soriano <csoriano gnome org>
+ *
+ * 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/>.
+ */
+
+#ifndef NAUTILUS_NOTIFICATION_DELETE_H
+#define NAUTILUS_NOTIFICATION_DELETE_H
+
+#include <gtk/gtk.h>
+#include "nautilus-window.h"
+
+G_BEGIN_DECLS
+
+#define NAUTILUS_TYPE_NOTIFICATION_DELETE            (nautilus_notification_delete_get_type())
+#define NAUTILUS_NOTIFICATION_DELETE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
NAUTILUS_TYPE_NOTIFICATION_DELETE, NautilusNotificationDelete))
+#define NAUTILUS_NOTIFICATION_DELETE_CONST(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
NAUTILUS_TYPE_NOTIFICATION_DELETE, NautilusNotificationDelete const))
+#define NAUTILUS_NOTIFICATION_DELETE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  
NAUTILUS_TYPE_NOTIFICATION_DELETE, NautilusNotificationDeleteClass))
+#define NAUTILUS_IS_NOTIFICATION_DELETE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
NAUTILUS_TYPE_NOTIFICATION_DELETE))
+#define NAUTILUS_IS_NOTIFICATION_DELETE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  
NAUTILUS_TYPE_NOTIFICATION_DELETE))
+#define NAUTILUS_NOTIFICATION_DELETE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  
NAUTILUS_TYPE_NOTIFICATION_DELETE, NautilusNotificationDeleteClass))
+
+typedef struct _NautilusNotificationDelete        NautilusNotificationDelete;
+typedef struct _NautilusNotificationDeleteClass   NautilusNotificationDeleteClass;
+typedef struct _NautilusNotificationDeletePrivate NautilusNotificationDeletePrivate;
+
+struct _NautilusNotificationDelete
+{
+  GtkGrid parent;
+
+  /*< private >*/
+  NautilusNotificationDeletePrivate *priv;
+};
+
+struct _NautilusNotificationDeleteClass
+{
+  GtkGridClass parent;
+};
+
+GType                           nautilus_notification_delete_get_type (void);
+NautilusNotificationDelete     *nautilus_notification_delete_new      (NautilusWindow *window,
+                                                                       guint           n_items,
+                                                                       gchar          *file_name);
+
+G_END_DECLS
+
+#endif /* NAUTILUS_NOTIFICATION_DELETE_H */
diff --git a/src/nautilus-notification-manager.c b/src/nautilus-notification-manager.c
new file mode 100644
index 0000000..28b124a
--- /dev/null
+++ b/src/nautilus-notification-manager.c
@@ -0,0 +1,104 @@
+/* nautilus-notification-manager.c
+ *
+ * Copyright (C) 2015 Carlos Soriano <csoriano gnome org>
+ *
+ * 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/>.
+ */
+
+#include "nautilus-notification-manager.h"
+#include "nautilus-file-undo-manager.h"
+
+struct _NautilusNotificationManagerPrivate
+{
+  GtkWidget *grid;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (NautilusNotificationManager, nautilus_notification_manager, GD_TYPE_NOTIFICATION)
+
+NautilusNotificationManager *
+nautilus_notification_manager_new (void)
+{
+  return g_object_new (NAUTILUS_TYPE_NOTIFICATION_MANAGER,
+                       "show-close-button", FALSE,
+                       "timeout", -1,
+                       NULL);
+}
+
+void
+nautilus_notification_manager_add_notification (NautilusNotificationManager *self,
+                                                GtkWidget                   *notification)
+{
+  gtk_container_add (GTK_CONTAINER (self->priv->grid), notification);
+  gtk_widget_show_all (GTK_WIDGET (self));
+}
+
+static void
+nautilus_notification_manager_remove (NautilusNotificationManager *self)
+{
+  gtk_widget_hide (GTK_WIDGET (self));
+  gtk_container_foreach (GTK_CONTAINER (self->priv->grid),
+                         (GtkCallback) gtk_widget_destroy,
+                         NULL);
+}
+
+static void
+nautilus_notification_manager_undo_manager_changed (NautilusFileUndoManager     *undo_manager,
+                                                    NautilusNotificationManager *self)
+{
+  nautilus_notification_manager_remove (self);
+}
+
+static void
+nautilus_notification_manager_finalize (GObject *object)
+{
+  NautilusNotificationManager *self = NAUTILUS_NOTIFICATION_MANAGER (object);
+
+  g_signal_handlers_disconnect_by_func (nautilus_file_undo_manager_get (),
+                                        G_CALLBACK (nautilus_notification_manager_undo_manager_changed),
+                                        self);
+
+  G_OBJECT_CLASS (nautilus_notification_manager_parent_class)->finalize (object);
+}
+
+static void
+nautilus_notification_manager_class_init (NautilusNotificationManagerClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  object_class->finalize = nautilus_notification_manager_finalize;
+}
+
+static void
+nautilus_notification_manager_init (NautilusNotificationManager *self)
+{
+  self->priv = nautilus_notification_manager_get_instance_private (self);
+
+  gtk_widget_set_halign (GTK_WIDGET (self), GTK_ALIGN_CENTER);
+  gtk_widget_set_valign (GTK_WIDGET (self), GTK_ALIGN_START);
+
+  self->priv->grid = gtk_grid_new ();
+  gtk_orientable_set_orientation (GTK_ORIENTABLE (self->priv->grid),
+                                  GTK_ORIENTATION_VERTICAL);
+  gtk_grid_set_row_spacing (GTK_GRID (self->priv->grid), 6);
+  gtk_container_add (GTK_CONTAINER (self), self->priv->grid);
+
+  g_signal_connect_swapped (self->priv->grid, "remove",
+                            G_CALLBACK (nautilus_notification_manager_remove), self);
+  /* Only support one undo operation at once. So if undo state changes,
+   * remove all notifications and the new one will be added to the appropiate
+   * notification manager
+   */
+  g_signal_connect_object (nautilus_file_undo_manager_get (), "undo-changed",
+                           G_CALLBACK (nautilus_notification_manager_undo_manager_changed), self, 0);
+}
diff --git a/src/nautilus-notification-manager.h b/src/nautilus-notification-manager.h
new file mode 100644
index 0000000..598c45e
--- /dev/null
+++ b/src/nautilus-notification-manager.h
@@ -0,0 +1,58 @@
+/* nautilus-notification-manager.h
+ *
+ * Copyright (C) 2015 Carlos Soriano <csoriano gnome org>
+ *
+ * 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/>.
+ */
+
+#ifndef NAUTILUS_NOTIFICATION_MANAGER_H
+#define NAUTILUS_NOTIFICATION_MANAGER_H
+
+#include <libgd/gd.h>
+
+G_BEGIN_DECLS
+
+#define NAUTILUS_TYPE_NOTIFICATION_MANAGER            (nautilus_notification_manager_get_type())
+#define NAUTILUS_NOTIFICATION_MANAGER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
NAUTILUS_TYPE_NOTIFICATION_MANAGER, NautilusNotificationManager))
+#define NAUTILUS_NOTIFICATION_MANAGER_CONST(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
NAUTILUS_TYPE_NOTIFICATION_MANAGER, NautilusNotificationManager const))
+#define NAUTILUS_NOTIFICATION_MANAGER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  
NAUTILUS_TYPE_NOTIFICATION_MANAGER, NautilusNotificationManagerClass))
+#define NAUTILUS_IS_NOTIFICATION_MANAGER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
NAUTILUS_TYPE_NOTIFICATION_MANAGER))
+#define NAUTILUS_IS_NOTIFICATION_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  
NAUTILUS_TYPE_NOTIFICATION_MANAGER))
+#define NAUTILUS_NOTIFICATION_MANAGER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  
NAUTILUS_TYPE_NOTIFICATION_MANAGER, NautilusNotificationManagerClass))
+
+typedef struct _NautilusNotificationManager        NautilusNotificationManager;
+typedef struct _NautilusNotificationManagerClass   NautilusNotificationManagerClass;
+typedef struct _NautilusNotificationManagerPrivate NautilusNotificationManagerPrivate;
+
+struct _NautilusNotificationManager
+{
+  GdNotification parent;
+
+  /*< private >*/
+  NautilusNotificationManagerPrivate *priv;
+};
+
+struct _NautilusNotificationManagerClass
+{
+  GdNotificationClass parent;
+};
+
+GType                            nautilus_notification_manager_get_type         (void);
+NautilusNotificationManager     *nautilus_notification_manager_new              (void);
+void                             nautilus_notification_manager_add_notification (NautilusNotificationManager 
*self,
+                                                                                 GtkWidget                   
*notification);
+
+G_END_DECLS
+
+#endif /* NAUTILUS_NOTIFICATION_MANAGER_H */
diff --git a/src/nautilus-view.c b/src/nautilus-view.c
index 02a9c38..01f4392 100644
--- a/src/nautilus-view.c
+++ b/src/nautilus-view.c
@@ -232,6 +232,9 @@ struct NautilusViewDetails
        GMenu *pathbar_menu;
 
        GActionGroup *view_action_group;
+
+       guint notification_n_items;
+       gchar *notification_file_name;
 };
 
 typedef struct {
@@ -243,7 +246,7 @@ typedef struct {
 
 static gboolean display_selection_info_idle_callback           (gpointer              data);
 static void     trash_or_delete_files                          (GtkWindow            *parent_window,
-                                                               const GList          *files,
+                                                               GList          *files,
                                                                NautilusView      *view);
 static void     load_directory                                 (NautilusView      *view,
                                                                NautilusDirectory    *directory);
@@ -3577,17 +3580,31 @@ trash_or_delete_done_cb (GHashTable *debuting_uris,
 {
        if (user_cancel) {
                view->details->selection_was_removed = FALSE;
+       } else {
+               nautilus_window_slot_add_notification_delete (view->details->slot,
+                                                             view->details->notification_n_items,
+                                                             view->details->notification_file_name);
        }
+
+       if (view->details->notification_file_name != NULL)
+               g_free (view->details->notification_file_name);
 }
 
 static void
 trash_or_delete_files (GtkWindow *parent_window,
-                      const GList *files,
+                      GList *files,
                       NautilusView *view)
 {
        GList *locations;
        const GList *node;
        
+       view->details->notification_n_items = g_list_length (files);
+       if (view->details->notification_n_items == 1) {
+               view->details->notification_file_name = nautilus_file_get_display_name (files->data);
+       } else {
+               view->details->notification_file_name = NULL;
+       }
+
        locations = NULL;
        for (node = files; node != NULL; node = node->next) {
                locations = g_list_prepend (locations,
diff --git a/src/nautilus-window-slot.c b/src/nautilus-window-slot.c
index 93ea872..88f8b1b 100644
--- a/src/nautilus-window-slot.c
+++ b/src/nautilus-window-slot.c
@@ -33,6 +33,8 @@
 #include "nautilus-trash-bar.h"
 #include "nautilus-window-private.h"
 #include "nautilus-x-content-bar.h"
+#include "nautilus-notification-manager.h"
+#include "nautilus-notification-delete.h"
 
 #include <glib/gi18n.h>
 #include <eel/eel-stock-dialogs.h>
@@ -68,6 +70,9 @@ struct NautilusWindowSlotDetails {
        GtkWidget *floating_bar;
        GtkWidget *view_overlay;
 
+       /* Notifications */
+       NautilusNotificationManager *notification_manager;
+
        /* slot contains
         *  1) an vbox containing extra_location_widgets
         *  2) the view
@@ -592,6 +597,9 @@ nautilus_window_slot_constructed (GObject *object)
        gtk_box_pack_start (GTK_BOX (slot), slot->details->view_overlay, TRUE, TRUE, 0);
        gtk_widget_show (slot->details->view_overlay);
 
+       slot->details->notification_manager = nautilus_notification_manager_new ();
+       gtk_overlay_add_overlay (GTK_OVERLAY (slot->details->view_overlay),
+                                GTK_WIDGET (slot->details->notification_manager));
        slot->details->floating_bar = nautilus_floating_bar_new (NULL, NULL, FALSE);
        gtk_widget_set_halign (slot->details->floating_bar, GTK_ALIGN_END);
        gtk_widget_set_valign (slot->details->floating_bar, GTK_ALIGN_END);
@@ -2401,6 +2409,20 @@ location_has_really_changed (NautilusWindowSlot *slot)
        }
 }
 
+void
+nautilus_window_slot_add_notification_delete (NautilusWindowSlot *slot,
+                                              guint               n_items,
+                                              gchar              *file_name)
+{
+       NautilusNotificationDelete *notification;
+
+       notification = nautilus_notification_delete_new (nautilus_window_slot_get_window (slot),
+                                                        n_items,
+                                                        file_name);
+       nautilus_notification_manager_add_notification (slot->details->notification_manager,
+                                                       GTK_WIDGET (notification));
+}
+
 static void
 nautilus_window_slot_dispose (GObject *object)
 {
diff --git a/src/nautilus-window-slot.h b/src/nautilus-window-slot.h
index ed4c873..ee60a13 100644
--- a/src/nautilus-window-slot.h
+++ b/src/nautilus-window-slot.h
@@ -124,5 +124,8 @@ void    nautilus_window_slot_set_status                        (NautilusWindowSlot *slot,
                                                            const char         *primary_status,
                                                            const char         *detail_status);
 void nautilus_window_slot_sync_view_mode (NautilusWindowSlot *slot);
+void nautilus_window_slot_add_notification_delete          (NautilusWindowSlot *slot,
+                                                            guint               n_items,
+                                                            gchar              *file_name);
 
 #endif /* NAUTILUS_WINDOW_SLOT_H */


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