X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkrecentchooserutils.c;h=3d496d041c151a46a32b6175155fae797bb170d1;hb=b2340254109d8599244c875fe7bc5e234f64da08;hp=3f1cdb4c5e1b7148e4691dc78de654892b029a23;hpb=8910e9333d40e5f0af68eaf65d33358f684d1f5d;p=~andy%2Fgtk diff --git a/gtk/gtkrecentchooserutils.c b/gtk/gtkrecentchooserutils.c index 3f1cdb4c5..3d496d041 100644 --- a/gtk/gtkrecentchooserutils.c +++ b/gtk/gtkrecentchooserutils.c @@ -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 . * * 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 * @@ -293,3 +291,240 @@ delegate_item_activated (GtkRecentChooser *receiver, { _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 (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; +}