]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkrecentchooserutils.c
filechooser: Show FUSE mounted locations in shortcuts
[~andy/gtk] / gtk / gtkrecentchooserutils.c
index b7fa81d5a04fe7583085d9295b3e0e78a89ce5cf..3d496d041c151a46a32b6175155fae797bb170d1 100644 (file)
@@ -16,9 +16,7 @@
  * Library General Public License for more details.
  *
  * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  *
  * Based on gtkfilechooserutils.c:
  *     Copyright (C) 2003 Red Hat, Inc.
@@ -226,7 +224,7 @@ static void
 delegate_unselect_uri (GtkRecentChooser *chooser,
                       const gchar      *uri)
 {
 return gtk_recent_chooser_unselect_uri (get_delegate (chooser), uri);
+ gtk_recent_chooser_unselect_uri (get_delegate (chooser), uri);
 }
 
 static GList *
@@ -294,5 +292,239 @@ delegate_item_activated (GtkRecentChooser *receiver,
   _gtk_recent_chooser_item_activated (GTK_RECENT_CHOOSER (user_data));
 }
 
-#define __GTK_RECENT_CHOOSER_UTILS_H__
-#include "gtkaliasdef.c"
+static gint
+sort_recent_items_mru (GtkRecentInfo *a,
+                      GtkRecentInfo *b,
+                      gpointer       unused)
+{
+  g_assert (a != NULL && b != NULL);
+  
+  return gtk_recent_info_get_modified (b) - gtk_recent_info_get_modified (a);
+}
+
+static gint
+sort_recent_items_lru (GtkRecentInfo *a,
+                      GtkRecentInfo *b,
+                      gpointer       unused)
+{
+  g_assert (a != NULL && b != NULL);
+  
+  return -1 * (gtk_recent_info_get_modified (b) - gtk_recent_info_get_modified (a));
+}
+
+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;
+}
+
+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: (allow-none): sorting function, or %NULL
+ * @sort_data: (allow-none): sorting function data, or %NULL
+ *
+ * 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)
+{
+  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;
+
+  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)
+    {
+    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.func = sort_func;
+      sort_recent.data = sort_data;
+
+      items = g_list_sort_with_data (items, compare_func, &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_free_full (l, (GDestroyNotify) gtk_recent_info_unref);
+    }
+
+  return items;
+}