Index: gtk/gtkrecentchooserdefault.c
===================================================================
--- gtk/gtkrecentchooserdefault.c	(revision 17504)
+++ gtk/gtkrecentchooserdefault.c	(working copy)
@@ -1209,11 +1209,11 @@ gtk_recent_chooser_default_set_sort_func
   if (impl->sort_data_destroy)
     {
       impl->sort_data_destroy (impl->sort_data);
-      
-      impl->sort_func = NULL;
-      impl->sort_data = NULL;
       impl->sort_data_destroy = NULL;
     }
+      
+  impl->sort_func = NULL;
+  impl->sort_data = NULL;
   
   if (sort_func)
     {
@@ -1223,129 +1223,22 @@ gtk_recent_chooser_default_set_sort_func
     }
 }
 
-static gint
-sort_recent_items_mru (GtkRecentInfo *a,
-		       GtkRecentInfo *b,
-		       gpointer       unused)
-{
-  g_assert (a != NULL && b != NULL);
-  
-  return (gtk_recent_info_get_modified (a) < gtk_recent_info_get_modified (b));
-}
-
-static gint
-sort_recent_items_lru (GtkRecentInfo *a,
-		       GtkRecentInfo *b,
-		       gpointer       unused)
-{
-  g_assert (a != NULL && b != NULL);
-  
-  return (gtk_recent_info_get_modified (a) > gtk_recent_info_get_modified (b));
-}
-
-/* our proxy sorting function */
-static gint
-sort_recent_items_proxy (gpointer *a,
-			 gpointer *b,
-			 gpointer  user_data)
-{
-  GtkRecentInfo *info_a = (GtkRecentInfo *) a;
-  GtkRecentInfo *info_b = (GtkRecentInfo *) b;
-  GtkRecentChooserDefault *impl = GTK_RECENT_CHOOSER_DEFAULT (user_data);
-
-  if (impl->sort_func)
-    return (* impl->sort_func) (info_a,
-    				info_b,
-      				impl->sort_data);
-  
-  /* fallback */
-  return 0;
-}
-
-static void
-chooser_set_sort_type (GtkRecentChooserDefault *impl,
-		       GtkRecentSortType        sort_type)
-{
-  if (impl->sort_type == sort_type)
-    return;
-
-  impl->sort_type = sort_type;
-}
-
 static GList *
 gtk_recent_chooser_default_get_items (GtkRecentChooser *chooser)
 {
   GtkRecentChooserDefault *impl;
-  gint limit;
-  GtkRecentSortType sort_type;
-  GList *items;
-  GCompareDataFunc compare_func;
-  gint length;
-  
-  impl = GTK_RECENT_CHOOSER_DEFAULT (chooser);
-  
-  if (!impl->manager)
-    return NULL;
 
-  items = gtk_recent_manager_get_items (impl->manager);
-  if (!items)
-    return NULL;
- 
-  limit = gtk_recent_chooser_get_limit (chooser);
-  if (limit == 0)
-    return NULL;
+  impl = GTK_RECENT_CHOOSER_DEFAULT (chooser);
 
-  sort_type = gtk_recent_chooser_get_sort_type (chooser);
-  switch (sort_type)
-    {
-    case GTK_RECENT_SORT_NONE:
-      compare_func = NULL;
-      break;
-    case GTK_RECENT_SORT_MRU:
-      compare_func = (GCompareDataFunc) sort_recent_items_mru;
-      break;
-    case GTK_RECENT_SORT_LRU:
-      compare_func = (GCompareDataFunc) sort_recent_items_lru;
-      break;
-    case GTK_RECENT_SORT_CUSTOM:
-      compare_func = (GCompareDataFunc) sort_recent_items_proxy;
-      break;
-    default:
-      g_assert_not_reached ();
-      break;
-    }
-  
-  /* sort the items; the filtering will be dealt with using
-   * the treeview's own filter object
-   */
-  if (compare_func)
-    items = g_list_sort_with_data (items, compare_func, impl);
-  
-  length = g_list_length (items);
-  if ((limit != -1) && (length > limit))
-    {
-      GList *clamp, *l;
-      
-      clamp = g_list_nth (items, limit - 1);
-      if (!clamp)
-        return items;
-      
-      l = clamp->next;
-      clamp->next = NULL;
-    
-      g_list_foreach (l, (GFunc) gtk_recent_info_unref, NULL);
-      g_list_free (l);
-    }
-  
-  return items;
+  return _gtk_recent_chooser_get_items (chooser,
+                                        impl->sort_func,
+                                        impl->sort_data);
 }
 
 static GtkRecentManager *
 gtk_recent_chooser_default_get_recent_manager (GtkRecentChooser *chooser)
 {
-  GtkRecentChooserDefault *impl = GTK_RECENT_CHOOSER_DEFAULT (chooser);
-  
-  return impl->manager;
+  return GTK_RECENT_CHOOSER_DEFAULT (chooser)->manager;
 }
 
 static void
@@ -1566,6 +1459,19 @@ set_current_filter (GtkRecentChooserDefa
     }
 }
 
+static void
+chooser_set_sort_type (GtkRecentChooserDefault *impl,
+		       GtkRecentSortType        sort_type)
+{
+  if (impl->sort_type == sort_type)
+    return;
+
+  impl->sort_type = sort_type;
+  
+  reload_recent_items (impl);
+}
+
+
 static GtkIconTheme *
 get_icon_theme_for_widget (GtkWidget *widget)
 {
Index: gtk/gtkrecentchooserprivate.h
===================================================================
--- gtk/gtkrecentchooserprivate.h	(revision 17504)
+++ gtk/gtkrecentchooserprivate.h	(working copy)
@@ -32,10 +32,13 @@ G_BEGIN_DECLS
 
 #define GTK_DEFAULT_RECENT_MANAGER 	"gtk-recent-manager-default"
 
-GtkRecentManager *_gtk_recent_chooser_get_recent_manager (GtkRecentChooser *chooser);
+GtkRecentManager *_gtk_recent_chooser_get_recent_manager (GtkRecentChooser  *chooser);
+GList *           _gtk_recent_chooser_get_items          (GtkRecentChooser  *chooser,
+                                                          GtkRecentSortFunc  func,
+                                                          gpointer           data);
 
-void              _gtk_recent_chooser_item_activated     (GtkRecentChooser *chooser);
-void              _gtk_recent_chooser_selection_changed  (GtkRecentChooser *chooser);
+void              _gtk_recent_chooser_item_activated     (GtkRecentChooser  *chooser);
+void              _gtk_recent_chooser_selection_changed  (GtkRecentChooser  *chooser);
 
 G_END_DECLS
  
Index: gtk/gtkrecentchoosermenu.c
===================================================================
--- gtk/gtkrecentchoosermenu.c	(revision 17504)
+++ gtk/gtkrecentchoosermenu.c	(working copy)
@@ -602,45 +602,6 @@ gtk_recent_chooser_menu_set_sort_func (G
     }
 }
 
-static gint
-sort_recent_items_mru (GtkRecentInfo *a,
-		       GtkRecentInfo *b,
-		       gpointer       unused)
-{
-  g_assert (a != NULL && b != NULL);
-  
-  return (gtk_recent_info_get_modified (a) < gtk_recent_info_get_modified (b));
-}
-
-static gint
-sort_recent_items_lru (GtkRecentInfo *a,
-		       GtkRecentInfo *b,
-		       gpointer       unused)
-{
-  g_assert (a != NULL && b != NULL);
-  
-  return (gtk_recent_info_get_modified (a) > gtk_recent_info_get_modified (b));
-}
-
-/* our proxy sorting function */
-static gint
-sort_recent_items_proxy (gpointer *a,
-			 gpointer *b,
-			 gpointer  user_data)
-{
-  GtkRecentInfo *info_a = (GtkRecentInfo *) a;
-  GtkRecentInfo *info_b = (GtkRecentInfo *) b;
-  GtkRecentChooserMenu *menu = GTK_RECENT_CHOOSER_MENU (user_data);
-
-  if (menu->priv->sort_func)
-    return (* menu->priv->sort_func) (info_a,
-    				      info_b,
-    				      menu->priv->sort_data);
-  
-  /* fallback */
-  return 0;
-}
-
 static void
 chooser_set_sort_type (GtkRecentChooserMenu *menu,
 		       GtkRecentSortType     sort_type)
@@ -656,66 +617,11 @@ static GList *
 gtk_recent_chooser_menu_get_items (GtkRecentChooser *chooser)
 {
   GtkRecentChooserMenu *menu = GTK_RECENT_CHOOSER_MENU (chooser);
-  GtkRecentChooserMenuPrivate *priv;
-  gint limit;
-  GtkRecentSortType sort_type;
-  GList *items;
-  GCompareDataFunc compare_func;
-  gint length;
-  
-  priv = menu->priv;
-  
-  if (!priv->manager)
-    return NULL;
-  
-  limit = gtk_recent_chooser_get_limit (chooser);
-  if (limit == 0)
-    return NULL;
-
-  sort_type = gtk_recent_chooser_get_sort_type (chooser);
-  switch (sort_type)
-    {
-    case GTK_RECENT_SORT_NONE:
-      compare_func = NULL;
-      break;
-    case GTK_RECENT_SORT_MRU:
-      compare_func = (GCompareDataFunc) sort_recent_items_mru;
-      break;
-    case GTK_RECENT_SORT_LRU:
-      compare_func = (GCompareDataFunc) sort_recent_items_lru;
-      break;
-    case GTK_RECENT_SORT_CUSTOM:
-      compare_func = (GCompareDataFunc) sort_recent_items_proxy;
-      break;
-    default:
-      g_assert_not_reached ();
-      break;
-    }
-  
-  items = gtk_recent_manager_get_items (priv->manager);
-  if (!items)
-    return NULL;
-  
-  if (compare_func)  
-    items = g_list_sort_with_data (items, compare_func, menu);
- 
-  length = g_list_length (items);
-  if ((limit != -1) && (length > limit))
-    {
-      GList *clamp, *l;
-
-      clamp = g_list_nth (items, limit - 1);
-      if (!clamp)
-        return items;
-
-      l = clamp->next;
-      clamp->next = NULL;      
-      
-      g_list_foreach (l, (GFunc) gtk_recent_info_unref, NULL);
-      g_list_free (l);
-    }
+  GtkRecentChooserMenuPrivate *priv = menu->priv;
 
-  return items;
+  return _gtk_recent_chooser_get_items (chooser,
+                                        priv->sort_func,
+                                        priv->sort_data);
 }
 
 static GtkRecentManager *
Index: gtk/gtkrecentchooserutils.c
===================================================================
--- gtk/gtkrecentchooserutils.c	(revision 17504)
+++ gtk/gtkrecentchooserutils.c	(working copy)
@@ -294,3 +294,139 @@ delegate_item_activated (GtkRecentChoose
 {
   _gtk_recent_chooser_item_activated (GTK_RECENT_CHOOSER (user_data));
 }
+
+static gint
+sort_recent_items_mru (GtkRecentInfo *a,
+		       GtkRecentInfo *b,
+		       gpointer       unused)
+{
+  g_assert (a != NULL && b != NULL);
+  
+  return (gtk_recent_info_get_modified (a) < gtk_recent_info_get_modified (b));
+}
+
+static gint
+sort_recent_items_lru (GtkRecentInfo *a,
+		       GtkRecentInfo *b,
+		       gpointer       unused)
+{
+  g_assert (a != NULL && b != NULL);
+  
+  return (gtk_recent_info_get_modified (a) > gtk_recent_info_get_modified (b));
+}
+
+typedef struct
+{
+  GtkRecentSortFunc func;
+  gpointer data;
+} SortRecentData;
+
+/* our proxy sorting function */
+static gint
+sort_recent_items_proxy (gpointer *a,
+                         gpointer *b,
+                         gpointer  user_data)
+{
+  GtkRecentInfo *info_a = (GtkRecentInfo *) a;
+  GtkRecentInfo *info_b = (GtkRecentInfo *) b;
+  SortRecentData *sort_recent = user_data;
+
+  if (sort_recent->func)
+    return (* sort_recent->func) (info_a,
+                                  info_b,
+                                  sort_recent->data);
+  
+  /* fallback */
+  return 0;
+}
+
+/*
+ * _gtk_recent_chooser_get_items:
+ * @chooser: a #GtkRecentChooser
+ * @sort_func: sorting function, or %NULL
+ * @sort_data: sorting function data, or %NULL
+ *
+ * Default implementation for getting the (sorted and clamped) list
+ * of recently used resources from a #GtkRecentChooser. This function
+ * should be used by implementations of the #GtkRecentChooser
+ * interface inside the GtkRecentChooser::get_items vfunc.
+ *
+ * Return value: a list of #GtkRecentInfo objects
+ */
+GList *
+_gtk_recent_chooser_get_items (GtkRecentChooser  *chooser,
+                               GtkRecentSortFunc  sort_func,
+                               gpointer           sort_data)
+{
+  GtkRecentManager *manager;
+  gint limit;
+  GtkRecentSortType sort_type;
+  GList *items;
+  GCompareDataFunc compare_func;
+  gint length;
+
+  g_return_val_if_fail (GTK_IS_RECENT_CHOOSER (chooser), NULL);
+
+  manager = _gtk_recent_chooser_get_recent_manager (chooser);
+  if (!manager)
+    return NULL;
+
+  items = gtk_recent_manager_get_items (manager);
+  if (!items)
+    return NULL;
+
+  limit = gtk_recent_chooser_get_limit (chooser);
+  if (limit == 0)
+    return NULL;
+
+  sort_type = gtk_recent_chooser_get_sort_type (chooser);
+  switch (sort_type)
+    {
+    case GTK_RECENT_SORT_NONE:
+      compare_func = NULL;
+      break;
+    case GTK_RECENT_SORT_MRU:
+      compare_func = (GCompareDataFunc) sort_recent_items_mru;
+      break;
+    case GTK_RECENT_SORT_LRU:
+      compare_func = (GCompareDataFunc) sort_recent_items_lru;
+      break;
+    case GTK_RECENT_SORT_CUSTOM:
+      compare_func = (GCompareDataFunc) sort_recent_items_proxy;
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+    }
+
+  if (compare_func)
+    {
+      SortRecentData *sort_recent;
+
+      sort_recent = g_slice_new (SortRecentData);
+      sort_recent->func = sort_func;
+      sort_recent->data = sort_data;
+
+      items = g_list_sort_with_data (items, compare_func, sort_recent);
+
+      g_slice_free (SortRecentData, sort_recent);
+    }
+  
+  length = g_list_length (items);
+  if ((limit != -1) && (length > limit))
+    {
+      GList *clamp, *l;
+      
+      clamp = g_list_nth (items, limit - 1);
+      if (!clamp)
+        return items;
+      
+      l = clamp->next;
+      clamp->next = NULL;
+    
+      g_list_foreach (l, (GFunc) gtk_recent_info_unref, NULL);
+      g_list_free (l);
+    }
+
+  return items;
+}
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 17504)
+++ ChangeLog	(working copy)
@@ -1,3 +1,15 @@
+2007-03-13  Emmanuele Bassi  <ebassi@gnome.org>
+
+	* gtk/gtkrecentchooserdefault.c:
+	* gtk/gtkrecentchoosermenu.c:
+	* gtk/gtkrecentchooserprivate.h:
+	* gtk/gtkrecentchooserutils.c: Move the recent chooser
+	function for getting the sorted and clamped list of recent files
+	from the manager outside the various implementation.
+
+	* gtk/gtkrecentchooserdefault.c (chooser_set_sort_type): Repopulate
+	the list when the sorting order changes.
+
 2007-03-12  Matthias Clasen  <mclasen@redhat.com>
 
 	* gtk/gtksizegroup.c (gtk_size_group_add_widget): Clarify
