]> Pileus Git - ~andy/gtk/commitdiff
Move filtering of the recent files list into the shared implementation; do
authorEmmanuele Bassi <ebassi@gnome.org>
Thu, 15 Mar 2007 10:05:34 +0000 (10:05 +0000)
committerEmmanuele Bassi <ebassi@src.gnome.org>
Thu, 15 Mar 2007 10:05:34 +0000 (10:05 +0000)
2007-03-15  Emmanuele Bassi  <ebassi@gnome.org>

* gtk/gtkrecentchooserprivate.h:
* gtk/gtkrecentchooserutils.c: Move filtering of the recent
files list into the shared implementation; do the filtering
before the sorting, so that we always clamp on the desired
size. (#418219)

* gtk/gtkrecentchoosermenu.c: Remove the filtering of the
list, as it's already been done.

* gtk/gtkrecentchooserdefault.c: Ditto; also remove the
GtkTreeModelFilter: just reload the view if the sorting and
filtering properties change.

* gtk/testrecentchoosermenu.c: Exercise the limit property.

svn path=/trunk/; revision=17516

ChangeLog
gtk/gtkrecentchooserdefault.c
gtk/gtkrecentchoosermenu.c
gtk/gtkrecentchooserprivate.h
gtk/gtkrecentchooserutils.c
tests/testrecentchoosermenu.c

index 9fbc61d17ceae2c648ef2232229ff6bd850411ca..89ceb5fdd2cba525afd8dcdc191a6710fcaccf07 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2007-03-15  Emmanuele Bassi  <ebassi@gnome.org>
+
+       * gtk/gtkrecentchooserprivate.h:
+       * gtk/gtkrecentchooserutils.c: Move filtering of the recent
+       files list into the shared implementation; do the filtering
+       before the sorting, so that we always clamp on the desired
+       size. (#418219)
+
+       * gtk/gtkrecentchoosermenu.c: Remove the filtering of the
+       list, as it's already been done.
+
+       * gtk/gtkrecentchooserdefault.c: Ditto; also remove the
+       GtkTreeModelFilter: just reload the view if the sorting and
+       filtering properties change.
+
+       * gtk/testrecentchoosermenu.c: Exercise the limit property.
+
 2007-03-14  Michael Natterer  <mitch@imendio.com>
 
        Make gtk_widget_set_extension_events() work on already realized
index faffa7ffc2c7762ffb9b32e9a5f086016e72820e..6c61a1750e884e87c17be8d8d0543728d9c883ac 100644 (file)
@@ -115,7 +115,6 @@ struct _GtkRecentChooserDefault
   
   GtkWidget *recent_view;
   GtkListStore *recent_store;
-  GtkTreeModel *recent_store_filter;
   GtkTreeViewColumn *icon_column;
   GtkTreeViewColumn *meta_column;
   GtkCellRenderer *meta_renderer;
@@ -234,10 +233,6 @@ static void set_recent_manager (GtkRecentChooserDefault *impl,
 static void chooser_set_sort_type (GtkRecentChooserDefault *impl,
                                   GtkRecentSortType        sort_type);
 
-static gboolean recent_store_filter_func (GtkTreeModel *model,
-                                         GtkTreeIter  *iter,
-                                         gpointer      user_data);
-
 static void recent_manager_changed_cb (GtkRecentManager  *manager,
                                       gpointer           user_data);
 static void recent_icon_data_func     (GtkTreeViewColumn *tree_column,
@@ -491,10 +486,6 @@ gtk_recent_chooser_default_set_property (GObject      *object,
       break;
     case GTK_RECENT_CHOOSER_PROP_SHOW_PRIVATE:
       impl->show_private = g_value_get_boolean (value);
-      
-      if (impl->recent_store && impl->recent_store_filter)
-        gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->recent_store_filter));
-
       if (impl->recent_popup_menu_show_private_item)
        {
           GtkCheckMenuItem *item = GTK_CHECK_MENU_ITEM (impl->recent_popup_menu_show_private_item);
@@ -502,12 +493,11 @@ gtk_recent_chooser_default_set_property (GObject      *object,
           gtk_check_menu_item_set_active (item, impl->show_private);
          g_signal_handlers_unblock_by_func (item, G_CALLBACK (show_private_toggled_cb), impl);
         }
+      reload_recent_items (impl);
       break;
     case GTK_RECENT_CHOOSER_PROP_SHOW_NOT_FOUND:
       impl->show_not_found = g_value_get_boolean (value);
-      
-      if (impl->recent_store && impl->recent_store_filter)
-        gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->recent_store_filter));
+      reload_recent_items (impl);
       break;
     case GTK_RECENT_CHOOSER_PROP_SHOW_TIPS:
       impl->show_tips = g_value_get_boolean (value);
@@ -531,9 +521,11 @@ gtk_recent_chooser_default_set_property (GObject      *object,
       break;
     case GTK_RECENT_CHOOSER_PROP_LOCAL_ONLY:
       impl->local_only = g_value_get_boolean (value);
+      reload_recent_items (impl);
       break;
     case GTK_RECENT_CHOOSER_PROP_LIMIT:
       impl->limit = g_value_get_int (value);
+      reload_recent_items (impl);
       break;
     case GTK_RECENT_CHOOSER_PROP_SORT_TYPE:
       chooser_set_sort_type (impl, g_value_get_enum (value));
@@ -627,12 +619,6 @@ gtk_recent_chooser_default_dispose (GObject *object)
       impl->current_filter = NULL;
     }
 
-  if (impl->recent_store_filter)
-    {
-      g_object_unref (impl->recent_store_filter);
-      impl->recent_store_filter = NULL;
-    }
-
   if (impl->recent_store)
     {
       g_object_unref (impl->recent_store);
@@ -753,17 +739,10 @@ static void
 chooser_set_model (GtkRecentChooserDefault *impl)
 {
   g_assert (impl->recent_store != NULL);
-  g_assert (impl->recent_store_filter == NULL);
   g_assert (impl->load_state == LOAD_LOADING);
-  
-  impl->recent_store_filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (impl->recent_store), NULL);
-  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (impl->recent_store_filter),
-                                         recent_store_filter_func,
-                                         impl,
-                                         NULL);
-  
+
   gtk_tree_view_set_model (GTK_TREE_VIEW (impl->recent_view),
-                          impl->recent_store_filter);
+                           GTK_TREE_MODEL (impl->recent_store));
   gtk_tree_view_columns_autosize (GTK_TREE_VIEW (impl->recent_view));
   gtk_tree_view_set_enable_search (GTK_TREE_VIEW (impl->recent_view), TRUE);
   gtk_tree_view_set_search_column (GTK_TREE_VIEW (impl->recent_view),
@@ -836,13 +815,7 @@ load_recent_items (gpointer user_data)
       impl->recent_items = NULL;
       impl->n_recent_items = 0;
       impl->loaded_items = 0;
-      
-      if (impl->recent_store_filter)
-        {
-          g_object_unref (impl->recent_store_filter);
-         impl->recent_store_filter = NULL;
-       }
-      
+
       /* load the filled up model */
       chooser_set_model (impl);
 
@@ -1258,6 +1231,7 @@ gtk_recent_chooser_default_get_items (GtkRecentChooser *chooser)
   impl = GTK_RECENT_CHOOSER_DEFAULT (chooser);
 
   return _gtk_recent_chooser_get_items (chooser,
+                                        impl->current_filter,
                                         impl->sort_func,
                                         impl->sort_data);
 }
@@ -1354,103 +1328,6 @@ gtk_recent_chooser_default_list_filters (GtkRecentChooser *chooser)
   return g_slist_copy (impl->filters);
 }
 
-static gboolean
-get_is_recent_filtered (GtkRecentChooserDefault *impl,
-                       GtkRecentInfo           *info)
-{
-  GtkRecentFilter *current_filter;
-  GtkRecentFilterInfo filter_info;
-  GtkRecentFilterFlags needed;
-  gboolean retval;
-
-  g_assert (info != NULL);
-  
-  if (!impl->current_filter)
-    return FALSE;
-  
-  current_filter = impl->current_filter;
-  needed = gtk_recent_filter_get_needed (current_filter);
-  
-  filter_info.contains = GTK_RECENT_FILTER_URI | GTK_RECENT_FILTER_MIME_TYPE;
-  
-  filter_info.uri = gtk_recent_info_get_uri (info);
-  filter_info.mime_type = gtk_recent_info_get_mime_type (info);
-  
-  if (needed & GTK_RECENT_FILTER_DISPLAY_NAME)
-    {
-      filter_info.display_name = gtk_recent_info_get_display_name (info);
-      filter_info.contains |= GTK_RECENT_FILTER_DISPLAY_NAME;
-    }
-  else
-    filter_info.uri = NULL;
-  
-  if (needed & GTK_RECENT_FILTER_APPLICATION)
-    {
-      filter_info.applications = (const gchar **) gtk_recent_info_get_applications (info, NULL);
-      filter_info.contains |= GTK_RECENT_FILTER_APPLICATION;
-    }
-  else
-    filter_info.applications = NULL;
-
-  if (needed & GTK_RECENT_FILTER_GROUP)
-    {
-      filter_info.groups = (const gchar **) gtk_recent_info_get_groups (info, NULL);
-      filter_info.contains |= GTK_RECENT_FILTER_GROUP;
-    }
-  else
-    filter_info.groups = NULL;
-
-  if (needed & GTK_RECENT_FILTER_AGE)
-    {
-      filter_info.age = gtk_recent_info_get_age (info);
-      filter_info.contains |= GTK_RECENT_FILTER_AGE;
-    }
-  else
-    filter_info.age = -1;
-  
-  retval = gtk_recent_filter_filter (current_filter, &filter_info);
-  
-  /* this we own */
-  if (filter_info.applications)
-    g_strfreev ((gchar **) filter_info.applications);
-  if (filter_info.groups)
-    g_strfreev ((gchar **) filter_info.groups);
-  
-  return !retval;
-}
-
-static gboolean
-recent_store_filter_func (GtkTreeModel *model,
-                          GtkTreeIter  *iter,
-                          gpointer      user_data)
-{
-  GtkRecentChooserDefault *impl = GTK_RECENT_CHOOSER_DEFAULT (user_data);
-  GtkRecentInfo *info = NULL;
-
-  if (!impl->current_filter)
-    return TRUE;
-  
-  gtk_tree_model_get (model, iter,
-                      RECENT_INFO_COLUMN, &info,
-                      -1);
-  if (!info)
-    return TRUE;
-    
-  if (get_is_recent_filtered (impl, info))
-    return FALSE;
-  
-  if (impl->local_only && !gtk_recent_info_is_local (info))
-    return FALSE;
-  
-  if ((!impl->show_private) && gtk_recent_info_get_private_hint (info))
-    return FALSE;
-  
-  if ((!impl->show_not_found) && !gtk_recent_info_exists (info))
-    return FALSE;
-      
-  return TRUE;
-}
-
 static void
 set_current_filter (GtkRecentChooserDefault *impl,
                    GtkRecentFilter         *filter)
@@ -1477,11 +1354,9 @@ set_current_filter (GtkRecentChooserDefault *impl,
         gtk_combo_box_set_active (GTK_COMBO_BOX (impl->filter_combo),
                                   filter_idx);
       
-      if (impl->recent_store && impl->recent_store_filter)
-        {
-          gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->recent_store_filter));
-        }
-      
+      if (impl->recent_store)
+        reload_recent_items (impl);
+
       g_object_notify (G_OBJECT (impl), "filter");
     }
 }
@@ -1490,12 +1365,13 @@ static void
 chooser_set_sort_type (GtkRecentChooserDefault *impl,
                       GtkRecentSortType        sort_type)
 {
-  if (impl->sort_type == sort_type)
-    return;
+  if (impl->sort_type != sort_type)
+    {
+      impl->sort_type = sort_type;
+      reload_recent_items (impl);
 
-  impl->sort_type = sort_type;
-  
-  reload_recent_items (impl);
+      g_object_notify (G_OBJECT (impl), "sort-type");
+    }
 }
 
 
index 99097fa8c8e69cf5fae6cbb4ca10ea31be9f0706..cff079c071e2d8e47ac12b2ffdc893360dc4b561 100644 (file)
@@ -625,6 +625,7 @@ gtk_recent_chooser_menu_get_items (GtkRecentChooser *chooser)
   GtkRecentChooserMenuPrivate *priv = menu->priv;
 
   return _gtk_recent_chooser_get_items (chooser,
+                                        priv->current_filter,
                                         priv->sort_func,
                                         priv->sort_data);
 }
@@ -697,76 +698,10 @@ gtk_recent_chooser_menu_set_current_filter (GtkRecentChooserMenu *menu,
       priv->current_filter = filter;
       g_object_ref_sink (priv->current_filter);
     }
-  
-  g_object_notify (G_OBJECT (menu), "filter");
-}
-
-static gboolean
-get_is_recent_filtered (GtkRecentChooserMenu *menu,
-                       GtkRecentInfo        *info)
-{
-  GtkRecentChooserMenuPrivate *priv;
-  GtkRecentFilter *current_filter;
-  GtkRecentFilterInfo filter_info;
-  GtkRecentFilterFlags needed;
-  gboolean retval;
-
-  g_assert (info != NULL);
-
-  priv = menu->priv;
-  
-  if (!priv->current_filter)
-    return FALSE;
-  
-  current_filter = priv->current_filter;
-  needed = gtk_recent_filter_get_needed (current_filter);
-  
-  filter_info.contains = GTK_RECENT_FILTER_URI | GTK_RECENT_FILTER_MIME_TYPE;
-  
-  filter_info.uri = gtk_recent_info_get_uri (info);
-  filter_info.mime_type = gtk_recent_info_get_mime_type (info);
-  
-  if (needed & GTK_RECENT_FILTER_DISPLAY_NAME)
-    {
-      filter_info.display_name = gtk_recent_info_get_display_name (info);
-      filter_info.contains |= GTK_RECENT_FILTER_DISPLAY_NAME;
-    }
-  else
-    filter_info.uri = NULL;
-  
-  if (needed & GTK_RECENT_FILTER_APPLICATION)
-    {
-      filter_info.applications = (const gchar **) gtk_recent_info_get_applications (info, NULL);
-      filter_info.contains |= GTK_RECENT_FILTER_APPLICATION;
-    }
-  else
-    filter_info.applications = NULL;
 
-  if (needed & GTK_RECENT_FILTER_GROUP)
-    {
-      filter_info.groups = (const gchar **) gtk_recent_info_get_groups (info, NULL);
-      filter_info.contains |= GTK_RECENT_FILTER_GROUP;
-    }
-  else
-    filter_info.groups = NULL;
-  
-  if (needed & GTK_RECENT_FILTER_AGE)
-    {
-      filter_info.age = gtk_recent_info_get_age (info);
-      filter_info.contains |= GTK_RECENT_FILTER_AGE;
-    }
-  else
-    filter_info.age = -1;
-  
-  retval = gtk_recent_filter_filter (current_filter, &filter_info);
-  
-  /* this we own */
-  if (filter_info.applications)
-    g_strfreev ((gchar **) filter_info.applications);
-  if (filter_info.groups)
-    g_strfreev ((gchar **) filter_info.groups);
+  gtk_recent_chooser_menu_populate (menu);
   
-  return !retval;
+  g_object_notify (G_OBJECT (menu), "filter");
 }
 
 /* taken from libeel/eel-strings.c */
@@ -1021,33 +956,6 @@ idle_populate_func (gpointer data)
     }
 
   info = g_list_nth_data (pdata->items, pdata->loaded_items);
-
-  /* skip non-local items on request */
-  if (priv->local_only &&
-      !gtk_recent_info_is_local (info))
-    {
-      goto check_and_return;
-    }
-      
-  /* skip private items on request */
-  if (!priv->show_private &&
-      gtk_recent_info_get_private_hint (info))
-    {
-      goto check_and_return;
-    }
-
-  /* skip non-existing items on request */
-  if (!priv->show_not_found &&
-      !gtk_recent_info_exists (info))
-    {
-      goto check_and_return;
-    }
-  /* filter items based on the currently set filter object */
-  if (get_is_recent_filtered (pdata->menu, info))
-    {
-      goto check_and_return;
-    }
-
   item = gtk_recent_chooser_menu_create_item (pdata->menu,
                                               info,
                                              pdata->displayed_items);
index 476c9327517b857e07836570adab51f7a401b182..afe8928f758686bc829711d49bf484176c72b9fa 100644 (file)
@@ -32,6 +32,7 @@ G_BEGIN_DECLS
 
 GtkRecentManager *_gtk_recent_chooser_get_recent_manager (GtkRecentChooser  *chooser);
 GList *           _gtk_recent_chooser_get_items          (GtkRecentChooser  *chooser,
+                                                          GtkRecentFilter   *filter,
                                                           GtkRecentSortFunc  func,
                                                           gpointer           data);
 
index 64fc81e331489269aa7d5f62c4e9b0e4c00b0ae1..102e2fdfd696552d7d1f710d38295d1bf82a54bc 100644 (file)
@@ -340,21 +340,84 @@ sort_recent_items_proxy (gpointer *a,
   return 0;
 }
 
+static gboolean
+get_is_recent_filtered (GtkRecentFilter *filter,
+                       GtkRecentInfo   *info)
+{
+  GtkRecentFilterInfo filter_info;
+  GtkRecentFilterFlags needed;
+  gboolean retval;
+
+  g_assert (info != NULL);
+  
+  needed = gtk_recent_filter_get_needed (filter);
+  
+  filter_info.contains = GTK_RECENT_FILTER_URI | GTK_RECENT_FILTER_MIME_TYPE;
+  
+  filter_info.uri = gtk_recent_info_get_uri (info);
+  filter_info.mime_type = gtk_recent_info_get_mime_type (info);
+  
+  if (needed & GTK_RECENT_FILTER_DISPLAY_NAME)
+    {
+      filter_info.display_name = gtk_recent_info_get_display_name (info);
+      filter_info.contains |= GTK_RECENT_FILTER_DISPLAY_NAME;
+    }
+  else
+    filter_info.uri = NULL;
+  
+  if (needed & GTK_RECENT_FILTER_APPLICATION)
+    {
+      filter_info.applications = (const gchar **) gtk_recent_info_get_applications (info, NULL);
+      filter_info.contains |= GTK_RECENT_FILTER_APPLICATION;
+    }
+  else
+    filter_info.applications = NULL;
+
+  if (needed & GTK_RECENT_FILTER_GROUP)
+    {
+      filter_info.groups = (const gchar **) gtk_recent_info_get_groups (info, NULL);
+      filter_info.contains |= GTK_RECENT_FILTER_GROUP;
+    }
+  else
+    filter_info.groups = NULL;
+
+  if (needed & GTK_RECENT_FILTER_AGE)
+    {
+      filter_info.age = gtk_recent_info_get_age (info);
+      filter_info.contains |= GTK_RECENT_FILTER_AGE;
+    }
+  else
+    filter_info.age = -1;
+  
+  retval = gtk_recent_filter_filter (filter, &filter_info);
+  
+  /* these we own */
+  if (filter_info.applications)
+    g_strfreev ((gchar **) filter_info.applications);
+  if (filter_info.groups)
+    g_strfreev ((gchar **) filter_info.groups);
+  
+  return !retval;
+}
+
 /*
  * _gtk_recent_chooser_get_items:
  * @chooser: a #GtkRecentChooser
+ * @filter: a #GtkRecentFilter
  * @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.
+ * Default implementation for getting the filtered, 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,
+                               GtkRecentFilter   *filter,
                                GtkRecentSortFunc  sort_func,
                                gpointer           sort_data)
 {
@@ -379,6 +442,50 @@ _gtk_recent_chooser_get_items (GtkRecentChooser  *chooser,
   if (limit == 0)
     return NULL;
 
+  if (filter)
+    {
+      GList *filter_items, *l;
+      gboolean local_only = FALSE;
+      gboolean show_private = FALSE;
+      gboolean show_not_found = FALSE;
+
+      g_object_get (G_OBJECT (chooser),
+                    "local-only", &local_only,
+                    "show-private", &show_private,
+                    "show-not-found", &show_not_found,
+                    NULL);
+
+      filter_items = NULL;
+      for (l = items; l != NULL; l = l->next)
+        {
+          GtkRecentInfo *info = l->data;
+          gboolean remove_item = FALSE;
+
+          if (get_is_recent_filtered (filter, info))
+            remove_item = TRUE;
+          
+          if (local_only && !gtk_recent_info_is_local (info))
+            remove_item = TRUE;
+
+          if (!show_private && gtk_recent_info_get_private_hint (info))
+            remove_item = TRUE;
+
+          if (!show_not_found && !gtk_recent_info_exists (info))
+            remove_item = TRUE;
+          
+          if (!remove_item)
+            filter_items = g_list_prepend (filter_items, info);
+          else
+            gtk_recent_info_unref (info);
+        }
+      
+      g_list_free (items);
+      items = filter_items;
+    }
+
+  if (!items)
+    return NULL;
+
   sort_type = gtk_recent_chooser_get_sort_type (chooser);
   switch (sort_type)
     {
index 18bfb08b56a0c31b82c59bfeb47ce6bd473cd0ce..3c760d0068cf1e57f05d61418ddf9ba1a0679e49 100644 (file)
@@ -61,6 +61,7 @@ create_recent_chooser_menu (void)
   
   menu = gtk_recent_chooser_menu_new_for_manager (manager);
 
+  gtk_recent_chooser_set_limit (GTK_RECENT_CHOOSER (menu), 4);
   gtk_recent_chooser_set_local_only (GTK_RECENT_CHOOSER (menu), TRUE);
   gtk_recent_chooser_set_show_icons (GTK_RECENT_CHOOSER (menu), TRUE);
   gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (menu),