[nautilus] general: Add in app notification for move to trash



commit 736c3ed36cef85c5e185385265dcab0bb63e0d55
Author: Carlos Soriano <csoriano gnome org>
Date:   Thu Jan 29 15:23:49 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 and create the new notification if the undo
    operation is "move to trash" and if the undo manager state is "undo".
    
    https://bugzilla.gnome.org/show_bug.cgi?id=743630

 .../nautilus-file-undo-operations.c                |    8 +-
 .../nautilus-file-undo-operations.h                |    3 +
 src/Makefile.am                                    |    4 +
 src/nautilus-notification-delete.c                 |  204 ++++++++++++++++++++
 src/nautilus-notification-delete.h                 |   57 ++++++
 src/nautilus-notification-manager.c                |   77 ++++++++
 src/nautilus-notification-manager.h                |   59 ++++++
 src/nautilus-window-private.h                      |    3 +
 src/nautilus-window.c                              |   47 ++++-
 9 files changed, 455 insertions(+), 7 deletions(-)
---
diff --git a/libnautilus-private/nautilus-file-undo-operations.c 
b/libnautilus-private/nautilus-file-undo-operations.c
index 8215636..33a1426 100644
--- a/libnautilus-private/nautilus-file-undo-operations.c
+++ b/libnautilus-private/nautilus-file-undo-operations.c
@@ -186,7 +186,7 @@ nautilus_file_undo_info_class_init (NautilusFileUndoInfoClass *klass)
        g_object_class_install_properties (oclass, N_PROPERTIES, properties);
 }
 
-static NautilusFileUndoOp
+NautilusFileUndoOp
 nautilus_file_undo_info_get_op_type (NautilusFileUndoInfo *self)
 {
        return self->priv->op_type;
@@ -1270,6 +1270,12 @@ nautilus_file_undo_info_trash_add_file (NautilusFileUndoInfoTrash *self,
        g_hash_table_insert (self->priv->trashed, g_object_ref (file), GSIZE_TO_POINTER (orig_trash_time));
 }
 
+GList *
+nautilus_file_undo_info_trash_get_files (NautilusFileUndoInfoTrash *self)
+{
+       return g_hash_table_get_keys (self->priv->trashed);
+}
+
 /* recursive permissions */
 G_DEFINE_TYPE (NautilusFileUndoInfoRecPermissions, nautilus_file_undo_info_rec_permissions, 
NAUTILUS_TYPE_FILE_UNDO_INFO)
 
diff --git a/libnautilus-private/nautilus-file-undo-operations.h 
b/libnautilus-private/nautilus-file-undo-operations.h
index 5a3953f..498c766 100644
--- a/libnautilus-private/nautilus-file-undo-operations.h
+++ b/libnautilus-private/nautilus-file-undo-operations.h
@@ -96,6 +96,8 @@ void nautilus_file_undo_info_get_strings (NautilusFileUndoInfo *self,
                                          gchar **redo_label,
                                          gchar **redo_description);
 
+NautilusFileUndoOp nautilus_file_undo_info_get_op_type (NautilusFileUndoInfo *self);
+
 /* copy/move/duplicate/link/restore from trash */
 #define NAUTILUS_TYPE_FILE_UNDO_INFO_EXT         (nautilus_file_undo_info_ext_get_type ())
 #define NAUTILUS_FILE_UNDO_INFO_EXT(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), 
NAUTILUS_TYPE_FILE_UNDO_INFO_EXT, NautilusFileUndoInfoExt))
@@ -206,6 +208,7 @@ GType nautilus_file_undo_info_trash_get_type (void) G_GNUC_CONST;
 NautilusFileUndoInfo *nautilus_file_undo_info_trash_new (gint item_count);
 void nautilus_file_undo_info_trash_add_file (NautilusFileUndoInfoTrash *self,
                                             GFile                     *file);
+GList *nautilus_file_undo_info_trash_get_files (NautilusFileUndoInfoTrash *self);
 
 /* recursive permissions */
 #define NAUTILUS_TYPE_FILE_UNDO_INFO_REC_PERMISSIONS         
(nautilus_file_undo_info_rec_permissions_get_type ())
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..afa7205
--- /dev/null
+++ b/src/nautilus-notification-delete.c
@@ -0,0 +1,204 @@
+/* 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 2 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-window.h"
+#include "nautilus-notification-delete.h"
+#include "nautilus-notification-manager.h"
+#include "nautilus-file-undo-manager.h"
+#include "nautilus-file-undo-operations.h"
+
+struct _NautilusNotificationDeletePrivate
+{
+  guint timeout_id;
+  NautilusWindow *window;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (NautilusNotificationDelete, nautilus_notification_delete, GTK_TYPE_GRID)
+
+enum {
+  PROP_0,
+  PROP_WINDOW,
+  LAST_PROP
+};
+
+#define  NOTIFICATION_TIMEOUT 6
+
+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);
+  /* The 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_finalize (GObject *object)
+{
+  NautilusNotificationDelete *self = NAUTILUS_NOTIFICATION_DELETE (object);
+
+  nautilus_notification_delete_remove_timeout (self);
+
+  G_OBJECT_CLASS (nautilus_notification_delete_parent_class)->finalize (object);
+}
+
+NautilusNotificationDelete *
+nautilus_notification_delete_new (NautilusWindow *window)
+{
+  g_assert (NAUTILUS_IS_WINDOW (window));
+
+  return g_object_new (NAUTILUS_TYPE_NOTIFICATION_DELETE,
+                       "window", window,
+                       "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_WINDOW:
+      self->priv->window = g_value_get_object (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+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->finalize = nautilus_notification_delete_finalize;
+
+  g_object_class_install_property (object_class,
+                                   PROP_WINDOW,
+                                   g_param_spec_object ("window",
+                                                        "Window associated",
+                                                        "The window that contains the notification",
+                                                        NAUTILUS_TYPE_WINDOW,
+                                                        G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
+}
+
+static void
+nautilus_notification_delete_init (NautilusNotificationDelete *self)
+{
+  GtkWidget *close;
+  gchar *label;
+  gchar *file_label;
+  gchar *markup = NULL;
+  GtkWidget *label_widget;
+  GtkWidget *undo_widget;
+  NautilusFileUndoInfo *undo_info;
+  GList *files;
+  gint length;
+
+  self->priv = nautilus_notification_delete_get_instance_private (self);
+
+  undo_info = nautilus_file_undo_manager_get_action ();
+  g_assert (NAUTILUS_IS_FILE_UNDO_INFO_TRASH (undo_info));
+  files = nautilus_file_undo_info_trash_get_files (NAUTILUS_FILE_UNDO_INFO_TRASH (undo_info));
+
+  length = g_list_length (files);
+  if (length == 1)
+    {
+      file_label = g_file_get_basename (files->data);
+      label = g_strdup_printf (_("%s deleted"), file_label);
+      g_free (file_label);
+    }
+  else
+    {
+      label = g_strdup_printf (ngettext ("%d file deleted", "%d files deleted", length), length);
+    }
+
+  label_widget = gtk_label_new (label);
+  gtk_label_set_max_width_chars (GTK_LABEL (label_widget), 50);
+  gtk_label_set_ellipsize (GTK_LABEL (label_widget), PANGO_ELLIPSIZE_MIDDLE);
+  markup = g_markup_printf_escaped ("<span font_weight=\"bold\">%s</span>", label);
+  gtk_label_set_markup (GTK_LABEL (label_widget), markup);
+  gtk_widget_set_halign (label_widget, GTK_ALIGN_START);
+  gtk_widget_set_margin_end (label_widget, 30);
+  gtk_container_add (GTK_CONTAINER (self), label_widget);
+
+  undo_widget = gtk_button_new_with_label (_("Undo"));
+  gtk_widget_set_valign (undo_widget, GTK_ALIGN_CENTER);
+  gtk_container_add (GTK_CONTAINER (self), undo_widget);
+  gtk_widget_set_margin_end (undo_widget, 6);
+  g_signal_connect_swapped (undo_widget, "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);
+  g_free (markup);
+  g_list_free (files);
+}
diff --git a/src/nautilus-notification-delete.h b/src/nautilus-notification-delete.h
new file mode 100644
index 0000000..67bfffb
--- /dev/null
+++ b/src/nautilus-notification-delete.h
@@ -0,0 +1,57 @@
+/* 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 2 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);
+
+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..511a353
--- /dev/null
+++ b/src/nautilus-notification-manager.c
@@ -0,0 +1,77 @@
+/* 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 2 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"
+
+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));
+}
+
+void
+nautilus_notification_manager_remove_all (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_class_init (NautilusNotificationManagerClass *Klass)
+{
+
+}
+
+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_all),
+                            self);
+}
diff --git a/src/nautilus-notification-manager.h b/src/nautilus-notification-manager.h
new file mode 100644
index 0000000..f66fe8c
--- /dev/null
+++ b/src/nautilus-notification-manager.h
@@ -0,0 +1,59 @@
+/* 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 2 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);
+void                             nautilus_notification_manager_remove_all       (NautilusNotificationManager 
*self);
+
+G_END_DECLS
+
+#endif /* NAUTILUS_NOTIFICATION_MANAGER_H */
diff --git a/src/nautilus-window-private.h b/src/nautilus-window-private.h
index 0a4fab9..cbd018b 100644
--- a/src/nautilus-window-private.h
+++ b/src/nautilus-window-private.h
@@ -54,6 +54,9 @@ struct NautilusWindowDetails
         /* Main view */
         GtkWidget *main_view;
 
+       /* Notifications */
+        GtkWidget *notification_manager;
+
         /* Toolbar */
         GtkWidget *toolbar;
         gboolean temporary_navigation_bar;
diff --git a/src/nautilus-window.c b/src/nautilus-window.c
index a80b0c5..37b8829 100644
--- a/src/nautilus-window.c
+++ b/src/nautilus-window.c
@@ -42,6 +42,10 @@
 #include "nautilus-window-slot.h"
 #include "nautilus-list-view.h"
 #include "nautilus-view.h"
+#include "nautilus-notification-manager.h"
+#include "nautilus-notification-delete.h"
+#include "nautilus-file-undo-manager.h"
+#include "nautilus-file-undo-operations.h"
 
 #include <eel/eel-debug.h>
 #include <eel/eel-gtk-extensions.h>
@@ -1461,6 +1465,27 @@ nautilus_window_ensure_location_entry (NautilusWindow *window)
 }
 
 static void
+nautilus_window_on_undo_changed (NautilusFileUndoManager *manager,
+                                 NautilusWindow          *window)
+{
+       NautilusNotificationDelete *notification;
+       NautilusFileUndoInfo *undo_info;
+       NautilusFileUndoManagerState state;
+
+       nautilus_notification_manager_remove_all (NAUTILUS_NOTIFICATION_MANAGER 
(window->details->notification_manager));
+       undo_info = nautilus_file_undo_manager_get_action ();
+       state = nautilus_file_undo_manager_get_state ();
+
+       if (undo_info != NULL &&
+            state == NAUTILUS_FILE_UNDO_MANAGER_STATE_UNDO &&
+            nautilus_file_undo_info_get_op_type (undo_info) == NAUTILUS_FILE_UNDO_OP_MOVE_TO_TRASH) {
+               notification = nautilus_notification_delete_new (window);
+               nautilus_notification_manager_add_notification (NAUTILUS_NOTIFICATION_MANAGER 
(window->details->notification_manager),
+                                                                GTK_WIDGET (notification));
+       }
+}
+
+static void
 path_bar_location_changed_callback (GtkWidget      *widget,
                                    GFile          *location,
                                    NautilusWindow *window)
@@ -1823,9 +1848,8 @@ create_notebook (NautilusWindow *window)
        gtk_widget_show (notebook);
        gtk_container_set_border_width (GTK_CONTAINER (notebook), 0);
 
-       gtk_box_pack_start (GTK_BOX (window->details->main_view),
-                           notebook,
-                           TRUE, TRUE, 0);
+       gtk_container_add (GTK_CONTAINER (window->details->main_view),
+                           notebook);
 
        return notebook;
 }
@@ -1867,14 +1891,21 @@ nautilus_window_constructed (GObject *self)
        gtk_container_add (GTK_CONTAINER (grid), window->details->content_paned);
        gtk_widget_show (window->details->content_paned);
 
-       window->details->main_view = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-       gtk_paned_pack2 (GTK_PANED (window->details->content_paned), window->details->main_view,
-                        TRUE, FALSE);
+       window->details->main_view = gtk_overlay_new ();
+       gtk_paned_pack2 (GTK_PANED (window->details->content_paned),
+                         window->details->main_view,
+                         TRUE, FALSE);
        gtk_widget_show (window->details->main_view);
 
        window->details->notebook = create_notebook (window);
        nautilus_window_set_initial_window_geometry (window);
 
+       window->details->notification_manager = GTK_WIDGET (nautilus_notification_manager_new ());
+       gtk_overlay_add_overlay (GTK_OVERLAY (window->details->main_view),
+                                 window->details->notification_manager);
+       g_signal_connect_after (nautilus_file_undo_manager_get (), "undo-changed",
+                                G_CALLBACK (nautilus_window_on_undo_changed), self);
+
        /* Is required that the UI is constructed before initializating the actions, since
         * some actions trigger UI widgets to show/hide. */
        nautilus_window_initialize_actions (window);
@@ -1999,6 +2030,10 @@ nautilus_window_finalize (GObject *object)
                window->details->sidebar_width_handler_id = 0;
        }
 
+       g_signal_handlers_disconnect_by_func (nautilus_file_undo_manager_get (),
+                                              G_CALLBACK (nautilus_window_on_undo_changed),
+                                              window);
+
        /* nautilus_window_close() should have run */
        g_assert (window->details->slots == NULL);
 


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