[Xfce4-commits] <thunar:jannis/new-shortcuts-pane> Load mounts without volumes; react on added/removed volumes.

Jannis Pohlmann noreply at xfce.org
Fri Jul 15 21:10:23 CEST 2011


Updating branch refs/heads/jannis/new-shortcuts-pane
         to 333b15ef81dcbef7444fc3749a46e0c2c79060c9 (commit)
       from d5529c999db4d3c596696aa0ae8b90eee9bbda6c (commit)

commit 333b15ef81dcbef7444fc3749a46e0c2c79060c9
Author: Jannis Pohlmann <jannis at xfce.org>
Date:   Tue Jun 7 16:03:32 2011 +0200

    Load mounts without volumes; react on added/removed volumes.
    
    Ejecting a few volumes is broken at the moment; e.g. empty CD media are
    always associated with a mount (burn:///), so we try to unmount that
    mount instead of ejecting the CD. There are ways to fix that I hope.

 thunar/thunar-shortcut-row.c    |  228 ++++++++++++++++++++++-----------------
 thunar/thunar-shortcuts-model.c |  168 ++++++++++++++++++++++++++++-
 thunar/thunar-shortcuts-view.c  |   51 +++++++++
 3 files changed, 349 insertions(+), 98 deletions(-)

diff --git a/thunar/thunar-shortcut-row.c b/thunar/thunar-shortcut-row.c
index 950b011..4ebaf45 100644
--- a/thunar/thunar-shortcut-row.c
+++ b/thunar/thunar-shortcut-row.c
@@ -67,63 +67,75 @@ enum
 
 
 
-static void     thunar_shortcut_row_constructed          (GObject           *object);
-static void     thunar_shortcut_row_dispose              (GObject           *object);
-static void     thunar_shortcut_row_finalize             (GObject           *object);
-static void     thunar_shortcut_row_get_property         (GObject           *object,
-                                                          guint              prop_id,
-                                                          GValue            *value,
-                                                          GParamSpec        *pspec);
-static void     thunar_shortcut_row_set_property         (GObject           *object,
-                                                          guint              prop_id,
-                                                          const GValue      *value,
-                                                          GParamSpec        *pspec);
-static gboolean thunar_shortcut_row_button_press_event   (GtkWidget         *widget,
-                                                          GdkEventButton    *event);
-static gboolean thunar_shortcut_row_key_press_event      (GtkWidget         *widget,
-                                                          GdkEventKey       *event);
-static gboolean thunar_shortcut_row_enter_notify_event   (GtkWidget         *widget,
-                                                          GdkEventCrossing  *event);
-static gboolean thunar_shortcut_row_leave_notify_event   (GtkWidget         *widget,
-                                                          GdkEventCrossing  *event);
-static gboolean thunar_shortcut_row_expose_event         (GtkWidget         *widget,
-                                                          GdkEventExpose    *event);
-static gboolean thunar_shortcut_row_focus                (GtkWidget         *widget,
-                                                          GtkDirectionType   direction);
-static gboolean thunar_shortcut_row_focus_in_event       (GtkWidget         *widget,
-                                                          GdkEventFocus     *event);
-static void     thunar_shortcut_row_size_request         (GtkWidget         *widget,
-                                                          GtkRequisition    *requisition);
-static void     thunar_shortcut_row_button_state_changed (ThunarShortcutRow *row,
-                                                          GtkStateType       previous_state,
-                                                          GtkWidget         *button);
-static void     thunar_shortcut_row_button_clicked       (ThunarShortcutRow *row,
-                                                          GtkButton         *button);
-static void     thunar_shortcut_row_mount_unmount_finish (GObject           *object,
-                                                          GAsyncResult      *result,
-                                                          gpointer           user_data);
-static void     thunar_shortcut_row_mount_eject_finish   (GObject           *object,
-                                                          GAsyncResult      *result,
-                                                          gpointer           user_data);
-static void     thunar_shortcut_row_poke_volume_finish   (ThunarBrowser     *browser,
-                                                          GVolume           *volume,
-                                                          ThunarFile        *file,
-                                                          GError            *error,
-                                                          gpointer           unused);
-static void     thunar_shortcut_row_poke_file_finish     (ThunarBrowser     *browser,
-                                                          ThunarFile        *file,
-                                                          ThunarFile        *target_file,
-                                                          GError            *error,
-                                                          gpointer           unused);
-static void     thunar_shortcut_row_resolve_and_activate (ThunarShortcutRow *row);
-static void     thunar_shortcut_row_icon_changed         (ThunarShortcutRow *row);
-static void     thunar_shortcut_row_label_changed        (ThunarShortcutRow *row);
-static void     thunar_shortcut_row_file_changed         (ThunarShortcutRow *row);
-static void     thunar_shortcut_row_eject_icon_changed   (ThunarShortcutRow *row);
-static void     thunar_shortcut_row_volume_changed       (ThunarShortcutRow *row);
-static void     thunar_shortcut_row_icon_size_changed    (ThunarShortcutRow *row);
-static void     thunar_shortcut_row_set_spinning         (ThunarShortcutRow *row,
-                                                          gboolean           spinning);
+/* row states */
+typedef enum
+{
+  THUNAR_SHORTCUT_ROW_NORMAL,
+  THUNAR_SHORTCUT_ROW_RESOLVING,
+  THUNAR_SHORTCUT_ROW_EJECTING,
+} ThunarShortcutRowState;
+
+
+
+
+static void     thunar_shortcut_row_constructed          (GObject               *object);
+static void     thunar_shortcut_row_dispose              (GObject               *object);
+static void     thunar_shortcut_row_finalize             (GObject               *object);
+static void     thunar_shortcut_row_get_property         (GObject               *object,
+                                                          guint                  prop_id,
+                                                          GValue                *value,
+                                                          GParamSpec            *pspec);
+static void     thunar_shortcut_row_set_property         (GObject               *object,
+                                                          guint                  prop_id,
+                                                          const GValue          *value,
+                                                          GParamSpec            *pspec);
+static gboolean thunar_shortcut_row_button_press_event   (GtkWidget             *widget,
+                                                          GdkEventButton        *event);
+static gboolean thunar_shortcut_row_key_press_event      (GtkWidget             *widget,
+                                                          GdkEventKey           *event);
+static gboolean thunar_shortcut_row_enter_notify_event   (GtkWidget             *widget,
+                                                          GdkEventCrossing      *event);
+static gboolean thunar_shortcut_row_leave_notify_event   (GtkWidget             *widget,
+                                                          GdkEventCrossing      *event);
+static gboolean thunar_shortcut_row_expose_event         (GtkWidget             *widget,
+                                                          GdkEventExpose        *event);
+static gboolean thunar_shortcut_row_focus                (GtkWidget             *widget,
+                                                          GtkDirectionType       direction);
+static gboolean thunar_shortcut_row_focus_in_event       (GtkWidget             *widget,
+                                                          GdkEventFocus         *event);
+static void     thunar_shortcut_row_size_request         (GtkWidget             *widget,
+                                                          GtkRequisition        *requisition);
+static void     thunar_shortcut_row_button_state_changed (ThunarShortcutRow     *row,
+                                                          GtkStateType           previous_state,
+                                                          GtkWidget             *button);
+static void     thunar_shortcut_row_button_clicked       (ThunarShortcutRow     *row,
+                                                          GtkButton             *button);
+static void     thunar_shortcut_row_mount_unmount_finish (GObject               *object,
+                                                          GAsyncResult          *result,
+                                                          gpointer               user_data);
+static void     thunar_shortcut_row_mount_eject_finish   (GObject               *object,
+                                                          GAsyncResult          *result,
+                                                          gpointer               user_data);
+static void     thunar_shortcut_row_poke_volume_finish   (ThunarBrowser         *browser,
+                                                          GVolume               *volume,
+                                                          ThunarFile            *file,
+                                                          GError                *error,
+                                                          gpointer               unused);
+static void     thunar_shortcut_row_poke_file_finish     (ThunarBrowser         *browser,
+                                                          ThunarFile            *file,
+                                                          ThunarFile            *target_file,
+                                                          GError                *error,
+                                                          gpointer               unused);
+static void     thunar_shortcut_row_resolve_and_activate (ThunarShortcutRow     *row);
+static void     thunar_shortcut_row_icon_changed         (ThunarShortcutRow     *row);
+static void     thunar_shortcut_row_label_changed        (ThunarShortcutRow     *row);
+static void     thunar_shortcut_row_file_changed         (ThunarShortcutRow     *row);
+static void     thunar_shortcut_row_eject_icon_changed   (ThunarShortcutRow     *row);
+static void     thunar_shortcut_row_volume_changed       (ThunarShortcutRow     *row);
+static void     thunar_shortcut_row_icon_size_changed    (ThunarShortcutRow     *row);
+static void     thunar_shortcut_row_set_spinning         (ThunarShortcutRow     *row,
+                                                          gboolean               spinning,
+                                                          ThunarShortcutRowState new_state);
 
 
 
@@ -134,27 +146,29 @@ struct _ThunarShortcutRowClass
 
 struct _ThunarShortcutRow
 {
-  GtkEventBox        __parent__;
-
-  ThunarPreferences *preferences;
-
-  gchar             *label;
-                    
-  GIcon             *icon;
-  GIcon             *eject_icon;
-                    
-  GFile             *file;
-  GVolume           *volume;
-                    
-  GtkWidget         *label_widget;
-  GtkWidget         *icon_image;
-  GtkWidget         *action_button;
-  GtkWidget         *action_image;
-  GtkWidget         *spinner;
-                    
-  ThunarIconSize     icon_size;
-
-  GCancellable      *cancellable;
+  GtkEventBox            __parent__;
+
+  ThunarPreferences     *preferences;
+
+  gchar                 *label;
+                        
+  GIcon                 *icon;
+  GIcon                 *eject_icon;
+                        
+  GFile                 *file;
+  GVolume               *volume;
+                        
+  GtkWidget             *label_widget;
+  GtkWidget             *icon_image;
+  GtkWidget             *action_button;
+  GtkWidget             *action_image;
+  GtkWidget             *spinner;
+                        
+  ThunarIconSize         icon_size;
+
+  GCancellable          *cancellable;
+
+  ThunarShortcutRowState state;
 };
 
 
@@ -257,6 +271,9 @@ thunar_shortcut_row_init (ThunarShortcutRow *row)
   /* create a cancellable for aborting mount/unmount operations */
   row->cancellable = g_cancellable_new ();
 
+  /* set the row state to normal */
+  row->state = THUNAR_SHORTCUT_ROW_NORMAL;
+
   /* configure general widget behavior */
   gtk_widget_set_can_focus (GTK_WIDGET (row), TRUE);
   gtk_widget_set_sensitive (GTK_WIDGET (row), TRUE);
@@ -746,6 +763,16 @@ thunar_shortcut_row_button_clicked (ThunarShortcutRow *row,
 
   _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
 
+  /* check if we are currently mounting/ejecting something */
+  if (row->state != THUNAR_SHORTCUT_ROW_NORMAL)
+    {
+      /* abort the mount/eject process */
+      g_cancellable_cancel (row->cancellable);
+
+      /* we're done, no further processing please */
+      return;
+    }
+
   if (row->volume != NULL)
     {
       toplevel = gtk_widget_get_toplevel (GTK_WIDGET (row));
@@ -761,12 +788,12 @@ thunar_shortcut_row_button_clicked (ThunarShortcutRow *row,
           g_debug ("have mount");
 
           /* check if we can unmount the mount */
-          if (FALSE && g_mount_can_unmount (mount))
+          if (g_mount_can_unmount (mount))
             {
               g_debug ("  trying to unmount the mount");
 
               /* start spinning */
-              thunar_shortcut_row_set_spinning (row, TRUE);
+              thunar_shortcut_row_set_spinning (row, TRUE, THUNAR_SHORTCUT_ROW_EJECTING);
 
               /* try unmounting the mount */
               g_mount_unmount_with_operation (mount,
@@ -781,7 +808,7 @@ thunar_shortcut_row_button_clicked (ThunarShortcutRow *row,
               g_debug ("  trying to eject the mount");
 
               /* start spinning */
-              thunar_shortcut_row_set_spinning (row, TRUE);
+              thunar_shortcut_row_set_spinning (row, TRUE, THUNAR_SHORTCUT_ROW_EJECTING);
 
               /* try ejecting the mount */
               g_mount_eject_with_operation (mount,
@@ -832,9 +859,6 @@ thunar_shortcut_row_mount_unmount_finish (GObject      *object,
   _thunar_return_if_fail (G_IS_MOUNT (mount));
   _thunar_return_if_fail (G_IS_ASYNC_RESULT (result));
 
-  /* stop spinning */
-  thunar_shortcut_row_set_spinning (row, FALSE);
-
   if (!g_mount_unmount_with_operation_finish (mount, result, &error))
     {
       thunar_dialogs_show_error (GTK_WIDGET (row), error,
@@ -842,6 +866,9 @@ thunar_shortcut_row_mount_unmount_finish (GObject      *object,
                                  row->label);
       g_error_free (error);
     }
+
+  /* stop spinning */
+  thunar_shortcut_row_set_spinning (row, FALSE, THUNAR_SHORTCUT_ROW_NORMAL);
 }
 
 
@@ -859,9 +886,6 @@ thunar_shortcut_row_mount_eject_finish (GObject      *object,
   _thunar_return_if_fail (G_IS_MOUNT (mount));
   _thunar_return_if_fail (G_IS_ASYNC_RESULT (result));
 
-  /* stop spinning */
-  thunar_shortcut_row_set_spinning (row, FALSE);
-
   if (!g_mount_eject_with_operation_finish (mount, result, &error))
     {
       thunar_dialogs_show_error (GTK_WIDGET (row), error,
@@ -869,6 +893,9 @@ thunar_shortcut_row_mount_eject_finish (GObject      *object,
                                  row->label);
       g_error_free (error);
     }
+
+  /* stop spinning */
+  thunar_shortcut_row_set_spinning (row, FALSE, THUNAR_SHORTCUT_ROW_NORMAL);
 }
 
 
@@ -886,9 +913,6 @@ thunar_shortcut_row_poke_volume_finish (ThunarBrowser *browser,
   _thunar_return_if_fail (G_IS_VOLUME (volume));
   _thunar_return_if_fail (file == NULL || THUNAR_IS_FILE (file));
   
-  /* deactivate the spinner */
-  thunar_shortcut_row_set_spinning (row, FALSE);
-
   if (error == NULL)
     {
       g_signal_emit (row, row_signals[SIGNAL_ACTIVATED], 0, file);
@@ -899,6 +923,9 @@ thunar_shortcut_row_poke_volume_finish (ThunarBrowser *browser,
                                  _("Failed to open \"%s\""),
                                  row->label);
     }
+
+  /* deactivate the spinner */
+  thunar_shortcut_row_set_spinning (row, FALSE, THUNAR_SHORTCUT_ROW_NORMAL);
 }
 
 
@@ -916,9 +943,6 @@ thunar_shortcut_row_poke_file_finish (ThunarBrowser *browser,
   _thunar_return_if_fail (THUNAR_IS_FILE (file));
   _thunar_return_if_fail (target_file == NULL || THUNAR_IS_FILE (target_file));
   
-  /* deactivate the spinner */
-  thunar_shortcut_row_set_spinning (row, FALSE);
-
   if (error == NULL)
     {
       g_signal_emit (row, row_signals[SIGNAL_ACTIVATED], 0, target_file);
@@ -929,6 +953,9 @@ thunar_shortcut_row_poke_file_finish (ThunarBrowser *browser,
                                  _("Failed to open \"%s\""),
                                  row->label);
     }
+
+  /* deactivate the spinner */
+  thunar_shortcut_row_set_spinning (row, FALSE, THUNAR_SHORTCUT_ROW_NORMAL);
 }
 
 
@@ -944,7 +971,7 @@ thunar_shortcut_row_resolve_and_activate (ThunarShortcutRow *row)
   if (row->volume != NULL)
     {
       /* activate the spinner */
-      thunar_shortcut_row_set_spinning (row, TRUE);
+      thunar_shortcut_row_set_spinning (row, TRUE, THUNAR_SHORTCUT_ROW_RESOLVING);
 
       thunar_browser_poke_volume (THUNAR_BROWSER (row), row->volume, row,
                                   thunar_shortcut_row_poke_volume_finish,
@@ -956,7 +983,7 @@ thunar_shortcut_row_resolve_and_activate (ThunarShortcutRow *row)
       if (file != NULL)
         {
           /* activate the spinner */
-          thunar_shortcut_row_set_spinning (row, TRUE);
+          thunar_shortcut_row_set_spinning (row, TRUE, THUNAR_SHORTCUT_ROW_RESOLVING);
 
           thunar_browser_poke_file (THUNAR_BROWSER (row), file, row,
                                     thunar_shortcut_row_poke_file_finish,
@@ -1108,11 +1135,18 @@ thunar_shortcut_row_icon_size_changed (ThunarShortcutRow *row)
 
 
 static void
-thunar_shortcut_row_set_spinning (ThunarShortcutRow *row,
-                                  gboolean           spinning)
+thunar_shortcut_row_set_spinning (ThunarShortcutRow     *row,
+                                  gboolean               spinning,
+                                  ThunarShortcutRowState new_state)
 {
   _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
 
+  /* apply the new state */
+  row->state = new_state;
+
+  /* reset the cancelable so that we can use it to cancel the process */
+  g_cancellable_reset (row->cancellable);
+
   if (spinning)
     {
       gtk_button_set_image (GTK_BUTTON (row->action_button), row->spinner);
diff --git a/thunar/thunar-shortcuts-model.c b/thunar/thunar-shortcuts-model.c
index 1d74b60..a6f53fa 100644
--- a/thunar/thunar-shortcuts-model.c
+++ b/thunar/thunar-shortcuts-model.c
@@ -126,12 +126,22 @@ static gboolean                thunar_shortcuts_model_find_category         (Thu
                                                                              ThunarShortcutType         type,
                                                                              ThunarShortcutCategory   **category,
                                                                              gint                      *category_index);
+static gboolean                thunar_shortcuts_model_find_volume           (ThunarShortcutsModel      *model,
+                                                                             GVolume                   *volume,
+                                                                             GtkTreeIter               *iter,
+                                                                             GtkTreePath              **path);
 static void                    thunar_shortcuts_model_add_shortcut          (ThunarShortcutsModel      *model,
                                                                              ThunarShortcut            *shortcut);
 static gboolean                thunar_shortcuts_model_load_system_shortcuts (gpointer                   user_data);
 static gboolean                thunar_shortcuts_model_load_user_dirs        (gpointer                   user_data);
 static gboolean                thunar_shortcuts_model_load_bookmarks        (gpointer                   user_data);
 static gboolean                thunar_shortcuts_model_load_volumes          (gpointer                   user_data);
+static void                    thunar_shortcuts_model_volume_added          (ThunarShortcutsModel      *model,
+                                                                             GVolume                   *volume,
+                                                                             GVolumeMonitor            *monitor);
+static void                    thunar_shortcuts_model_volume_removed        (ThunarShortcutsModel      *model,
+                                                                             GVolume                   *volume,
+                                                                             GVolumeMonitor            *monitor);
 static ThunarShortcutCategory *thunar_shortcut_category_new                 (ThunarShortcutCategoryType type);
 static void                    thunar_shortcut_category_free                (ThunarShortcutCategory    *category);
 static void                    thunar_shortcut_free                         (ThunarShortcut            *shortcut);
@@ -936,6 +946,60 @@ thunar_shortcuts_model_find_category (ThunarShortcutsModel    *model,
 
 
 
+static gboolean
+thunar_shortcuts_model_find_volume (ThunarShortcutsModel *model,
+                                    GVolume              *volume,
+                                    GtkTreeIter          *iter,
+                                    GtkTreePath         **path)
+{
+  ThunarShortcutCategory *category;
+  ThunarShortcut         *shortcut;
+  gboolean                shortcut_found = FALSE;
+  gint                    category_index;
+  gint                    shortcut_index;
+
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
+  _thunar_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
+
+  for (category_index = 0; 
+       !shortcut_found && (guint) category_index < model->categories->len; 
+       ++category_index)
+    {
+      category = g_ptr_array_index (model->categories, category_index);
+
+      for (shortcut_index = 0;
+           !shortcut_found && (guint) shortcut_index < category->shortcuts->len;
+           ++shortcut_index)
+        {
+          shortcut = g_ptr_array_index (category->shortcuts, shortcut_index);
+
+          if (shortcut->volume == volume)
+            {
+              if (iter != NULL)
+                {
+#ifndef NDEBUG
+                  (*iter).stamp = model->stamp;
+#endif
+                  (*iter).user_data = GINT_TO_POINTER (category_index);
+                  (*iter).user_data2 = GINT_TO_POINTER (shortcut_index);
+                }
+
+              if (path != NULL)
+                {
+                  *path = gtk_tree_path_new_from_indices (category_index, shortcut_index,
+                                                          -1);
+                }
+
+              shortcut_found = TRUE;
+            }
+        }
+    }
+
+  return shortcut_found;
+}
+
+
+
 static void
 thunar_shortcuts_model_add_shortcut (ThunarShortcutsModel *model,
                                      ThunarShortcut       *shortcut)
@@ -1180,6 +1244,8 @@ thunar_shortcuts_model_load_volumes (gpointer user_data)
 {
   ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (user_data);
   ThunarShortcut       *shortcut;
+  GVolume              *volume;
+  GList                *mounts;
   GList                *volumes;
   GList                *lp;
 
@@ -1212,7 +1278,45 @@ thunar_shortcuts_model_load_volumes (gpointer user_data)
   /* release the volume list */
   g_list_free (volumes);
 
-  /* TODO be notified of new and removed volumes on the system */
+  /* get a list of all mounts available */
+  mounts = g_volume_monitor_get_mounts (model->volume_monitor);
+
+  /* create shortcuts for the mounts */
+  for (lp = mounts; lp != NULL; lp = lp->next)
+    {
+      /* only create the shortcut if it has no volume */
+      volume = g_mount_get_volume (lp->data);
+      if (volume == NULL)
+        {
+          /* create the shortcut */
+          shortcut = g_slice_new0 (ThunarShortcut);
+          shortcut->file = g_mount_get_root (lp->data);
+          shortcut->icon = g_mount_get_icon (lp->data);
+          shortcut->eject_icon = g_themed_icon_new ("media-eject");
+          shortcut->name = g_mount_get_name (lp->data);
+          shortcut->type = THUNAR_SHORTCUT_REMOTE_FILE;
+          shortcut->visible = TRUE;
+          shortcut->mutable = TRUE;
+          shortcut->persistent = FALSE;
+
+          /* add the shortcut */
+          thunar_shortcuts_model_add_shortcut (model, shortcut);
+        }
+      else
+        {
+          /* release the volume again */
+          g_object_unref (volume);
+        }
+    }
+
+  /* release the mount list */
+  g_list_free (mounts);
+
+  /* be notified of new and removed volumes on the system */
+  g_signal_connect_swapped (model->volume_monitor, "volume-added",
+                            G_CALLBACK (thunar_shortcuts_model_volume_added), model);
+  g_signal_connect_swapped (model->volume_monitor, "volume-removed",
+                            G_CALLBACK (thunar_shortcuts_model_volume_removed), model);
 
   /* reset the load idle ID */
   model->load_idle_id = 0;
@@ -1222,6 +1326,68 @@ thunar_shortcuts_model_load_volumes (gpointer user_data)
 
 
 
+static void
+thunar_shortcuts_model_volume_added (ThunarShortcutsModel *model,
+                                     GVolume              *volume,
+                                     GVolumeMonitor       *monitor)
+{
+  ThunarShortcut *shortcut;
+
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
+  _thunar_return_if_fail (G_IS_VOLUME (volume));
+  _thunar_return_if_fail (G_IS_VOLUME_MONITOR (monitor));
+
+  /* create a shortcut for the volume */
+  shortcut = g_slice_new0 (ThunarShortcut);
+  shortcut->volume = g_object_ref (volume);
+  shortcut->icon = g_volume_get_icon (shortcut->volume);
+  shortcut->eject_icon = g_themed_icon_new ("media-eject");
+  shortcut->name = g_volume_get_name (shortcut->volume);
+  shortcut->type = THUNAR_SHORTCUT_VOLUME;
+  shortcut->visible = TRUE;
+  shortcut->mutable = TRUE;
+  shortcut->persistent = FALSE;
+
+  /* add the shortcut to the model */
+  thunar_shortcuts_model_add_shortcut (model, shortcut);
+}
+
+
+
+static void
+thunar_shortcuts_model_volume_removed (ThunarShortcutsModel *model,
+                                       GVolume              *volume,
+                                       GVolumeMonitor       *monitor)
+{
+  ThunarShortcutCategory *category;
+  GtkTreePath            *path;
+  gint                    category_index;
+  gint                    shortcut_index;
+  
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
+  _thunar_return_if_fail (G_IS_VOLUME (volume));
+  _thunar_return_if_fail (G_IS_VOLUME_MONITOR (monitor));
+
+  /* try to find the shortcut for this volume */
+  if (thunar_shortcuts_model_find_volume (model, volume, NULL, &path))
+    {
+      /* notify others that the shortcut was removed */
+      g_signal_emit_by_name (model, "row-deleted", path, NULL);
+
+      /* get category and shortcut indices */
+      thunar_shortcuts_model_parse_path (model, path, &category_index, &shortcut_index);
+
+      /* get the category and remove the shortcut from it */
+      category = g_ptr_array_index (model->categories, category_index);
+      g_ptr_array_remove_index (category->shortcuts, shortcut_index);
+
+      /* release the tree path */
+      gtk_tree_path_free (path);
+    }
+}
+
+
+
 static ThunarShortcutCategory *
 thunar_shortcut_category_new (ThunarShortcutCategoryType type)
 {
diff --git a/thunar/thunar-shortcuts-view.c b/thunar/thunar-shortcuts-view.c
index acd901f..2f635e5 100644
--- a/thunar/thunar-shortcuts-view.c
+++ b/thunar/thunar-shortcuts-view.c
@@ -88,6 +88,9 @@ static void       thunar_shortcuts_view_row_inserted             (ThunarShortcut
                                                                   GtkTreePath                      *path,
                                                                   GtkTreeIter                      *iter,
                                                                   GtkTreeModel                     *model);
+static void       thunar_shortcuts_view_row_deleted              (ThunarShortcutsView              *view,
+                                                                  GtkTreePath                      *path,
+                                                                  GtkTreeModel                     *model);
 static GtkWidget *thunar_shortcuts_view_get_expander_at          (ThunarShortcutsView              *view,
                                                                   gint                              index);
 static void       thunar_shortcuts_view_row_activated            (ThunarShortcutsView              *view,
@@ -295,6 +298,10 @@ thunar_shortcuts_view_constructed (GObject *object)
   /* be notified when a new shortcut is added to the model */
   g_signal_connect_swapped (view->model, "row-inserted",
                             G_CALLBACK (thunar_shortcuts_view_row_inserted), view);
+
+  /* be notified when a shortcut is removed from the model */
+  g_signal_connect_swapped (view->model, "row-deleted",
+                            G_CALLBACK (thunar_shortcuts_view_row_deleted), view);
 }
 
 
@@ -439,6 +446,50 @@ thunar_shortcuts_view_row_inserted (ThunarShortcutsView *view,
 
 
 
+static void
+thunar_shortcuts_view_row_deleted (ThunarShortcutsView *view,
+                                   GtkTreePath         *path,
+                                   GtkTreeModel        *model)
+{
+  GtkWidget *expander;
+  GtkWidget *box;
+  GList     *rows;
+  GList     *row_element;
+  gint       category_index;
+  gint       shortcut_index;
+
+  _thunar_return_if_fail (THUNAR_SHORTCUTS_VIEW (view));
+  _thunar_return_if_fail (GTK_IS_TREE_MODEL (model));
+
+
+  /* get the category and shortcut index */
+  category_index = gtk_tree_path_get_indices (path)[0];
+  shortcut_index = gtk_tree_path_get_indices (path)[1];
+
+  /* find the expander for the row widget */
+  expander = thunar_shortcuts_view_get_expander_at (view, category_index);
+
+  /* if this fails then we are out of sync with the model */
+  g_assert (expander != NULL);
+
+  /* get the box widget that holds the shortcut row */
+  box = gtk_bin_get_child (GTK_BIN (expander));
+
+  /* get a list of all shortcut rows */
+  rows = gtk_container_get_children (GTK_CONTAINER (box));
+
+  /* get the shortcut row we want to remove */
+  row_element = g_list_nth (rows, shortcut_index);
+
+  /* remove the shortcut row */
+  gtk_container_remove (GTK_CONTAINER (box), row_element->data);
+
+  /* free the row list */
+  g_list_free (rows);
+}
+
+
+
 static GtkWidget *
 thunar_shortcuts_view_get_expander_at (ThunarShortcutsView *view,
                                        gint                 expander_index)



More information about the Xfce4-commits mailing list