[gtk+/multiroot-filechooser: 5/30] Keep the list of custom shortcuts in a list and rebuild it on root_uri change.



commit 7056f9a39b57956406213d1e5862f01193daba41
Author: Christian Hammond <chipx86 chipx86 com>
Date:   Wed Feb 3 17:31:21 2010 -0800

    Keep the list of custom shortcuts in a list and rebuild it on root_uri change.
    
    The old custom shortcut code assumed that the entry would be added to the
    sidebar and never removed programatically within that instance of the file
    chooser. That, clearly, doesn't work when dynamically changing the root URIs.
    
    We now maintain a list of added custom shortcuts and add/remove these based
    on the root URI whenever the root changes.

 gtk/gtkfilechooserdefault.c |  115 ++++++++++++++++++++++++++++---------------
 gtk/gtkfilechooserprivate.h |    1 +
 2 files changed, 76 insertions(+), 40 deletions(-)
---
diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c
index 6baba4d..b39850a 100644
--- a/gtk/gtkfilechooserdefault.c
+++ b/gtk/gtkfilechooserdefault.c
@@ -358,6 +358,8 @@ static int shortcuts_get_index (GtkFileChooserDefault *impl,
 				ShortcutsIndex         where);
 static int shortcut_find_position (GtkFileChooserDefault *impl,
 				   GFile                 *file);
+static int shortcuts_get_pos_for_shortcut_folder (GtkFileChooserDefault *impl,
+                                                  int                    pos);
 static void switch_to_shortcut (GtkFileChooserDefault *impl,
                                 int                    pos);
 
@@ -2227,6 +2229,46 @@ shortcuts_add_bookmarks (GtkFileChooserDefault *impl)
   profile_end ("end", NULL);
 }
 
+/* Update the list of custom shortcut folders. */
+static void
+shortcuts_add_custom_folders (GtkFileChooserDefault *impl)
+{
+  gboolean old_changing_folders;
+  GSList *l;
+
+  profile_start ("start", NULL);
+
+  old_changing_folders = impl->changing_folder;
+  impl->changing_folder = TRUE;
+
+  if (impl->num_shortcuts > 0)
+    {
+      shortcuts_remove_rows (impl,
+                             shortcuts_get_index (impl, SHORTCUTS_SHORTCUTS),
+                             impl->num_shortcuts);
+    }
+
+  impl->num_shortcuts = 0;
+
+  for (l = impl->shortcuts; l != NULL; l = l->next)
+    {
+      GFile *file = (GFile *)l->data;
+
+      if (impl->root_uri != NULL &&
+          _gtk_file_chooser_is_file_in_root (GTK_FILE_CHOOSER (impl), file))
+        {
+          int pos = shortcuts_get_pos_for_shortcut_folder (impl,
+                                                           impl->num_shortcuts);
+          shortcuts_insert_file (impl, pos, SHORTCUT_TYPE_FILE, NULL,
+                                 file, NULL, FALSE, SHORTCUTS_SHORTCUTS);
+        }
+    }
+
+  impl->changing_folder = old_changing_folders;
+
+  profile_end ("end", NULL);
+}
+
 /* Appends a separator and a row to the shortcuts list for the current folder */
 static void
 shortcuts_add_current_folder (GtkFileChooserDefault *impl)
@@ -5238,6 +5280,7 @@ set_root_uri (GtkFileChooserDefault *impl,
           /* Update all the sidebar entries to filter the root URI. */
           shortcuts_model_create (impl);
           shortcuts_add_bookmarks (impl);
+          shortcuts_add_custom_folders (impl);
         }
 
       if (impl->current_folder != NULL)
@@ -5707,6 +5750,13 @@ gtk_file_chooser_default_dispose (GObject *object)
       impl->loading_shortcuts = NULL;
     }
 
+  if (impl->shortcuts)
+    {
+      g_slist_foreach (impl->shortcuts, (GFunc)g_object_unref, NULL);
+      g_slist_free (impl->shortcuts);
+      impl->shortcuts = NULL;
+    }
+
   if (impl->file_list_drag_data_received_cancellable)
     {
       g_cancellable_cancel (impl->file_list_drag_data_received_cancellable);
@@ -7819,7 +7869,15 @@ add_shortcut_get_info_cb (GCancellable *cancellable,
 
   pos = shortcuts_get_pos_for_shortcut_folder (data->impl, data->impl->num_shortcuts);
 
-  shortcuts_insert_file (data->impl, pos, SHORTCUT_TYPE_FILE, NULL, data->file, NULL, FALSE, SHORTCUTS_SHORTCUTS);
+  g_object_ref (data->file);
+  data->impl->shortcuts = g_slist_append (data->impl->shortcuts, data->file);
+
+  if (_gtk_file_chooser_is_file_in_root (GTK_FILE_CHOOSER (data->impl),
+                                         data->file))
+    {
+      shortcuts_insert_file (data->impl, pos, SHORTCUT_TYPE_FILE, NULL,
+                             data->file, NULL, FALSE, SHORTCUTS_SHORTCUTS);
+    }
 
 out:
   g_object_unref (data->impl);
@@ -7948,13 +8006,25 @@ gtk_file_chooser_default_remove_shortcut_folder (GtkFileChooser  *chooser,
 	{
 	  shortcuts_remove_rows (impl, pos + i, 1);
 	  impl->num_shortcuts--;
-	  return TRUE;
+	  break;
 	}
 
       if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
 	g_assert_not_reached ();
     }
 
+  for (l = impl->shortcuts; l != NULL; l = l->next)
+    {
+      GFile *shortcut = (GFile *)l->data;
+
+      if (g_file_equal (shortcut, file))
+        {
+          g_object_unref (shortcut);
+          impl->shortcuts = g_slist_remove_link (impl->shortcuts, l);
+          return TRUE;
+        }
+    }
+
  out:
 
   uri = g_file_get_uri (file);
@@ -7973,44 +8043,8 @@ static GSList *
 gtk_file_chooser_default_list_shortcut_folders (GtkFileChooser *chooser)
 {
   GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
-  int pos;
-  GtkTreeIter iter;
-  int i;
-  GSList *list;
-
-  if (impl->num_shortcuts == 0)
-    return NULL;
-
-  pos = shortcuts_get_pos_for_shortcut_folder (impl, 0);
-  if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (impl->shortcuts_model), &iter, NULL, pos))
-    g_assert_not_reached ();
-
-  list = NULL;
-
-  for (i = 0; i < impl->num_shortcuts; i++)
-    {
-      gpointer col_data;
-      ShortcutType shortcut_type;
-      GFile *shortcut;
-
-      gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
-			  SHORTCUTS_COL_DATA, &col_data,
-			  SHORTCUTS_COL_TYPE, &shortcut_type,
-			  -1);
-      g_assert (col_data != NULL);
-      g_assert (shortcut_type == SHORTCUT_TYPE_FILE);
-
-      shortcut = col_data;
-      list = g_slist_prepend (list, g_object_ref (shortcut));
-
-      if (i != impl->num_shortcuts - 1)
-	{
-	  if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
-	    g_assert_not_reached ();
-	}
-    }
 
-  return g_slist_reverse (list);
+  return impl->shortcuts;
 }
 
 /* Guesses a size based upon font sizes */
@@ -9428,8 +9462,9 @@ recent_idle_load (gpointer data)
            walk = walk->next)
         {
           GtkRecentInfo *info = walk->data;
+          const char *uri = gtk_recent_info_get_uri (info);
 
-          if (is_uri_in_root (impl, gtk_recent_info_get_uri (info)))
+          if (_gtk_file_chooser_is_uri_in_root (GTK_FILE_CHOOSER (impl), uri))
             {
               // We'll sort this later, so prepend for efficiency.
               load_data->items = g_list_prepend(load_data->items, info);
diff --git a/gtk/gtkfilechooserprivate.h b/gtk/gtkfilechooserprivate.h
index b88213e..acd6d15 100644
--- a/gtk/gtkfilechooserprivate.h
+++ b/gtk/gtkfilechooserprivate.h
@@ -240,6 +240,7 @@ struct _GtkFileChooserDefault
 
   /* Handles */
   GSList *loading_shortcuts;
+  GSList *shortcuts;
   GSList *reload_icon_cancellables;
   GCancellable *file_list_drag_data_received_cancellable;
   GCancellable *update_current_folder_cancellable;



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