diff options
Diffstat (limited to 'cut-n-paste-code')
-rw-r--r-- | cut-n-paste-code/libegg/Makefile.am | 10 | ||||
-rw-r--r-- | cut-n-paste-code/libegg/egg-recent-item.c | 440 | ||||
-rw-r--r-- | cut-n-paste-code/libegg/egg-recent-item.h | 78 | ||||
-rw-r--r-- | cut-n-paste-code/libegg/egg-recent-model.c | 1780 | ||||
-rw-r--r-- | cut-n-paste-code/libegg/egg-recent-model.h | 80 |
5 files changed, 0 insertions, 2388 deletions
diff --git a/cut-n-paste-code/libegg/Makefile.am b/cut-n-paste-code/libegg/Makefile.am index 11eb5ff08..70f0cf9f7 100644 --- a/cut-n-paste-code/libegg/Makefile.am +++ b/cut-n-paste-code/libegg/Makefile.am @@ -4,20 +4,12 @@ noinst_LTLIBRARIES = libegg.la INCLUDES = $(LIBEGG_CFLAGS) -EGG_RECENT_FILES = \ - egg-recent-model.c \ - egg-recent-model.h \ - egg-recent-item.c \ - egg-recent-item.h \ - $(NULL) - EGG_TREE_DND_FILES = \ eggtreemultidnd.c \ eggtreemultidnd.h \ $(NULL) libegg_la_SOURCES = \ - $(EGG_RECENT_FILES) \ $(EGG_TREE_DND_FILES) \ $(NULL) @@ -25,9 +17,7 @@ EXTRA_DIST = \ update-from-egg.sh \ $(NULL) -EGG_RECENT_DIR = $(srcdir)/../../../libegg/libegg/recent-files EGG_TREE_DND_DIR = $(srcdir)/../../../libegg/libegg/treeviewutils regenerate-built-sources: - EGGFILES="$(EGG_RECENT_FILES)" EGGDIR="$(EGG_RECENT_DIR)" $(srcdir)/update-from-egg.sh EGGFILES="$(EGG_TREE_DND_FILES)" EGGDIR="$(EGG_TREE_DND_DIR)" $(srcdir)/update-from-egg.sh diff --git a/cut-n-paste-code/libegg/egg-recent-item.c b/cut-n-paste-code/libegg/egg-recent-item.c deleted file mode 100644 index 9be7970ec..000000000 --- a/cut-n-paste-code/libegg/egg-recent-item.c +++ /dev/null @@ -1,440 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/** - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - * - * Authors: - * James Willcox <jwillcox@cs.indiana.edu> - */ - - -#include <stdio.h> -#include <string.h> -#include <glib.h> -#include <libgnomevfs/gnome-vfs.h> -#include <libgnomevfs/gnome-vfs-mime-utils.h> -#include "egg-recent-item.h" - - - -EggRecentItem * -egg_recent_item_new (void) -{ - EggRecentItem *item; - - item = g_new (EggRecentItem, 1); - - item->groups = NULL; - item->private_data = FALSE; - item->uri = NULL; - item->mime_type = NULL; - - item->refcount = 1; - - return item; -} - -static void -egg_recent_item_free (EggRecentItem *item) -{ - if (item->uri) - g_free (item->uri); - - if (item->mime_type) - g_free (item->mime_type); - - if (item->groups) { - g_list_foreach (item->groups, (GFunc)g_free, NULL); - g_list_free (item->groups); - item->groups = NULL; - } - - g_free (item); -} - -EggRecentItem * -egg_recent_item_ref (EggRecentItem *item) -{ - item->refcount++; - return item; -} - -EggRecentItem * -egg_recent_item_unref (EggRecentItem *item) -{ - item->refcount--; - - if (item->refcount == 0) { - egg_recent_item_free (item); - } - - return item; -} - - -EggRecentItem * -egg_recent_item_new_from_uri (const gchar *uri) -{ - EggRecentItem *item; - - g_return_val_if_fail (uri != NULL, NULL); - - item = egg_recent_item_new (); - - if (!egg_recent_item_set_uri (item ,uri)) { - egg_recent_item_free (item); - return NULL; - } - - item->mime_type = gnome_vfs_get_mime_type (item->uri); - - if (!item->mime_type) - item->mime_type = g_strdup (GNOME_VFS_MIME_TYPE_UNKNOWN); - - return item; -} - -/* -static GList * -egg_recent_item_copy_groups (const GList *list) -{ - GList *newlist = NULL; - - while (list) { - gchar *group = (gchar *)list->data; - - newlist = g_list_prepend (newlist, g_strdup (group)); - - list = list->next; - } - - return newlist; -} - - -EggRecentItem * -egg_recent_item_copy (const EggRecentItem *item) -{ - EggRecentItem *newitem; - - newitem = egg_recent_item_new (); - newitem->uri = g_strdup (item->uri); - if (item->mime_type) - newitem->mime_type = g_strdup (item->mime_type); - newitem->timestamp = item->timestamp; - newitem->private_data = item->private_data; - newitem->groups = egg_recent_item_copy_groups (item->groups); - - return newitem; -} -*/ - -/* -EggRecentItem * -egg_recent_item_new_valist (const gchar *uri, va_list args) -{ - EggRecentItem *item; - EggRecentArg arg; - gchar *str1; - gchar *str2; - gboolean priv; - - item = egg_recent_item_new (); - - arg = va_arg (args, EggRecentArg); - - while (arg != EGG_RECENT_ARG_NONE) { - switch (arg) { - case EGG_RECENT_ARG_MIME_TYPE: - str1 = va_arg (args, gchar*); - - egg_recent_item_set_mime_type (item, str1); - break; - case EGG_RECENT_ARG_GROUP: - str1 = va_arg (args, gchar*); - - egg_recent_item_add_group (item, str1); - break; - case EGG_RECENT_ARG_PRIVATE: - priv = va_arg (args, gboolean); - - egg_recent_item_set_private (item, priv); - break; - default: - break; - } - - arg = va_arg (args, EggRecentArg); - } - - return item; -} -*/ - -gboolean -egg_recent_item_set_uri (EggRecentItem *item, const gchar *uri) -{ - gchar *utf8_uri; - - /* if G_BROKEN_FILENAMES is not set, this should succede */ - if (g_utf8_validate (uri, -1, NULL)) { - item->uri = gnome_vfs_make_uri_from_input (uri); - } else { - utf8_uri = g_filename_to_utf8 (uri, -1, NULL, NULL, NULL); - - if (utf8_uri == NULL) { - g_warning ("Couldn't convert URI to UTF-8"); - return FALSE; - } - - if (g_utf8_validate (utf8_uri, -1, NULL)) { - item->uri = gnome_vfs_make_uri_from_input (utf8_uri); - } else { - g_free (utf8_uri); - return FALSE; - } - - g_free (utf8_uri); - } - - return TRUE; -} - -gchar * -egg_recent_item_get_uri (const EggRecentItem *item) -{ - return g_strdup (item->uri); -} - -G_CONST_RETURN gchar * -egg_recent_item_peek_uri (const EggRecentItem *item) -{ - return item->uri; -} - -gchar * -egg_recent_item_get_uri_utf8 (const EggRecentItem *item) -{ - /* this could fail, but it's not likely, since we've already done it - * once in set_uri() - */ - return g_filename_to_utf8 (item->uri, -1, NULL, NULL, NULL); -} - -gchar * -egg_recent_item_get_uri_for_display (const EggRecentItem *item) -{ - return gnome_vfs_format_uri_for_display (item->uri); -} - -/* Stolen from gnome_vfs_make_valid_utf8() */ -static char * -make_valid_utf8 (const char *name) -{ - GString *string; - const char *remainder, *invalid; - int remaining_bytes, valid_bytes; - - string = NULL; - remainder = name; - remaining_bytes = strlen (name); - - while (remaining_bytes != 0) { - if (g_utf8_validate (remainder, remaining_bytes, &invalid)) - break; - - valid_bytes = invalid - remainder; - - if (string == NULL) - string = g_string_sized_new (remaining_bytes); - - g_string_append_len (string, remainder, valid_bytes); - g_string_append_c (string, '?'); - - remaining_bytes -= valid_bytes + 1; - remainder = invalid + 1; - } - - if (string == NULL) - return g_strdup (name); - - g_string_append (string, remainder); -/* g_string_append (string, _(" (invalid file name)")); */ - g_assert (g_utf8_validate (string->str, -1, NULL)); - - return g_string_free (string, FALSE); -} - -/** - * egg_recent_item_get_short_name: - * @item: an #EggRecentItem - * - * Computes a valid UTF-8 string that can be used as the name of the item in a - * menu or list. For example, calling this function on an item that refers to - * "file:///foo/bar.txt" will yield "bar.txt". - * - * Return value: A newly-allocated string in UTF-8 encoding; free it with - * g_free(). - **/ -gchar * -egg_recent_item_get_short_name (const EggRecentItem *item) -{ - GnomeVFSURI *uri; - char *short_name; - gboolean valid; - - g_return_val_if_fail (item != NULL, NULL); - - if (item->uri == NULL) - return NULL; - - uri = gnome_vfs_uri_new (item->uri); - if (uri == NULL) - return NULL; - - short_name = gnome_vfs_uri_extract_short_name (uri); - valid = FALSE; - - if (strcmp (gnome_vfs_uri_get_scheme (uri), "file") == 0) { - char *tmp; - - tmp = g_filename_to_utf8 (short_name, -1, NULL, NULL, NULL); - if (tmp) { - g_free (short_name); - short_name = tmp; - valid = TRUE; - } - } - - if (!valid) { - char *tmp; - - tmp = make_valid_utf8 (short_name); - g_assert (tmp != NULL); - g_free (short_name); - short_name = tmp; - } - - gnome_vfs_uri_unref (uri); - - return short_name; -} - -void -egg_recent_item_set_mime_type (EggRecentItem *item, const gchar *mime) -{ - item->mime_type = g_strdup (mime); -} - -gchar * -egg_recent_item_get_mime_type (const EggRecentItem *item) -{ - return g_strdup (item->mime_type); -} - -void -egg_recent_item_set_timestamp (EggRecentItem *item, time_t timestamp) -{ - if (timestamp == (time_t) -1) - time (×tamp); - - item->timestamp = timestamp; -} - -time_t -egg_recent_item_get_timestamp (const EggRecentItem *item) -{ - return item->timestamp; -} - -G_CONST_RETURN GList * -egg_recent_item_get_groups (const EggRecentItem *item) -{ - return item->groups; -} - -gboolean -egg_recent_item_in_group (const EggRecentItem *item, const gchar *group_name) -{ - GList *tmp; - - tmp = item->groups; - while (tmp != NULL) { - gchar *val = (gchar *)tmp->data; - - if (strcmp (group_name, val) == 0) - return TRUE; - - tmp = tmp->next; - } - - return FALSE; -} - -void -egg_recent_item_add_group (EggRecentItem *item, const gchar *group_name) -{ - g_return_if_fail (group_name != NULL); - - if (!egg_recent_item_in_group (item, group_name)) - item->groups = g_list_append (item->groups, g_strdup (group_name)); -} - -void -egg_recent_item_remove_group (EggRecentItem *item, const gchar *group_name) -{ - GList *tmp; - - g_return_if_fail (group_name != NULL); - - tmp = item->groups; - while (tmp != NULL) { - gchar *val = (gchar *)tmp->data; - - if (strcmp (group_name, val) == 0) { - item->groups = g_list_remove (item->groups, - val); - g_free (val); - break; - } - - tmp = tmp->next; - } -} - -void -egg_recent_item_set_private (EggRecentItem *item, gboolean priv) -{ - item->private_data = priv; -} - -gboolean -egg_recent_item_get_private (const EggRecentItem *item) -{ - return item->private_data; -} - -GType -egg_recent_item_get_type (void) -{ - static GType boxed_type = 0; - - if (!boxed_type) { - boxed_type = g_boxed_type_register_static ("EggRecentItem", - (GBoxedCopyFunc)egg_recent_item_ref, - (GBoxedFreeFunc)egg_recent_item_unref); - } - - return boxed_type; -} diff --git a/cut-n-paste-code/libegg/egg-recent-item.h b/cut-n-paste-code/libegg/egg-recent-item.h deleted file mode 100644 index 5b3b405c9..000000000 --- a/cut-n-paste-code/libegg/egg-recent-item.h +++ /dev/null @@ -1,78 +0,0 @@ - -#ifndef __EGG_RECENT_ITEM_H__ -#define __EGG_RECENT_ITEM_H__ - -#include <time.h> -#include <glib.h> -#include <glib-object.h> - -G_BEGIN_DECLS - -#define EGG_TYPE_RECENT_ITEM (egg_recent_item_get_type ()) - -#define EGG_RECENT_ITEM_LIST_UNREF(list) \ - g_list_foreach (list, (GFunc)egg_recent_item_unref, NULL); \ - g_list_free (list); - -typedef struct _EggRecentItem EggRecentItem; - -struct _EggRecentItem { - /* do not access any of these directly */ - gchar *uri; - gchar *mime_type; - time_t timestamp; - - gboolean private_data; - - GList *groups; - - int refcount; -}; - -GType egg_recent_item_get_type (void) G_GNUC_CONST; - -/* constructors */ -EggRecentItem * egg_recent_item_new (void); - -EggRecentItem * egg_recent_item_ref (EggRecentItem *item); -EggRecentItem * egg_recent_item_unref (EggRecentItem *item); - -/* automatically fetches the mime type, etc */ -EggRecentItem * egg_recent_item_new_from_uri (const gchar *uri); - -gboolean egg_recent_item_set_uri (EggRecentItem *item, const gchar *uri); -gchar * egg_recent_item_get_uri (const EggRecentItem *item); -gchar * egg_recent_item_get_uri_utf8 (const EggRecentItem *item); -gchar * egg_recent_item_get_uri_for_display (const EggRecentItem *item); -gchar * egg_recent_item_get_short_name (const EggRecentItem *item); - -void egg_recent_item_set_mime_type (EggRecentItem *item, const gchar *mime); -gchar * egg_recent_item_get_mime_type (const EggRecentItem *item); - -void egg_recent_item_set_timestamp (EggRecentItem *item, time_t timestamp); -time_t egg_recent_item_get_timestamp (const EggRecentItem *item); - -G_CONST_RETURN gchar *egg_recent_item_peek_uri (const EggRecentItem *item); - - -/* groups */ -G_CONST_RETURN GList * egg_recent_item_get_groups (const EggRecentItem *item); - -gboolean egg_recent_item_in_group (const EggRecentItem *item, - const gchar *group_name); - -void egg_recent_item_add_group (EggRecentItem *item, - const gchar *group_name); - -void egg_recent_item_remove_group (EggRecentItem *item, - const gchar *group_name); - -void egg_recent_item_set_private (EggRecentItem *item, - gboolean priv); - -gboolean egg_recent_item_get_private (const EggRecentItem *item); - - -G_END_DECLS - -#endif /* __EGG_RECENT_ITEM_H__ */ diff --git a/cut-n-paste-code/libegg/egg-recent-model.c b/cut-n-paste-code/libegg/egg-recent-model.c deleted file mode 100644 index d4606ab6c..000000000 --- a/cut-n-paste-code/libegg/egg-recent-model.c +++ /dev/null @@ -1,1780 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/** - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - * - * Authors: - * James Willcox <jwillcox@cs.indiana.edu> - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/time.h> -#include <time.h> -#include <gtk/gtk.h> -#include <libgnomevfs/gnome-vfs.h> -#include <libgnomevfs/gnome-vfs-mime-utils.h> -#include <gconf/gconf-client.h> -#include "egg-recent-model.h" -#include "egg-recent-item.h" - -#define EGG_RECENT_MODEL_FILE_PATH "/.recently-used" -#define EGG_RECENT_MODEL_BUFFER_SIZE 8192 - -#define EGG_RECENT_MODEL_MAX_ITEMS 500 -#define EGG_RECENT_MODEL_DEFAULT_LIMIT 10 -#define EGG_RECENT_MODEL_TIMEOUT_LENGTH 200 - -#define EGG_RECENT_MODEL_KEY_DIR "/desktop/gnome/recent_files" -#define EGG_RECENT_MODEL_DEFAULT_LIMIT_KEY EGG_RECENT_MODEL_KEY_DIR "/default_limit" -#define EGG_RECENT_MODEL_EXPIRE_KEY EGG_RECENT_MODEL_KEY_DIR "/expire" - -struct _EggRecentModelPrivate { - GSList *mime_filter_values; /* list of mime types we allow */ - GSList *group_filter_values; /* list of groups we allow */ - GSList *scheme_filter_values; /* list of URI schemes we allow */ - - EggRecentModelSort sort_type; /* type of sorting to be done */ - - int limit; /* soft limit for length of the list */ - int expire_days; /* number of days to hold an item */ - - char *path; /* path to the file we store stuff in */ - - GHashTable *monitors; - - GnomeVFSMonitorHandle *monitor; - - GConfClient *client; - gboolean use_default_limit; - - guint limit_change_notify_id; - guint expiration_change_notify_id; - - guint changed_timeout; -}; - -/* signals */ -enum { - CHANGED, - LAST_SIGNAL -}; - -static GType model_signals[LAST_SIGNAL] = { 0 }; - -/* properties */ -enum { - PROP_BOGUS, - PROP_MIME_FILTERS, - PROP_GROUP_FILTERS, - PROP_SCHEME_FILTERS, - PROP_SORT_TYPE, - PROP_LIMIT -}; - -typedef struct { - GSList *states; - GList *items; - EggRecentItem *current_item; -}ParseInfo; - -typedef enum { - STATE_START, - STATE_RECENT_FILES, - STATE_RECENT_ITEM, - STATE_URI, - STATE_MIME_TYPE, - STATE_TIMESTAMP, - STATE_PRIVATE, - STATE_GROUPS, - STATE_GROUP -} ParseState; - -typedef struct _ChangedData { - EggRecentModel *model; - GList *list; -}ChangedData; - -#define TAG_RECENT_FILES "RecentFiles" -#define TAG_RECENT_ITEM "RecentItem" -#define TAG_URI "URI" -#define TAG_MIME_TYPE "Mime-Type" -#define TAG_TIMESTAMP "Timestamp" -#define TAG_PRIVATE "Private" -#define TAG_GROUPS "Groups" -#define TAG_GROUP "Group" - -static void start_element_handler (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - gpointer user_data, - GError **error); - -static void end_element_handler (GMarkupParseContext *context, - const gchar *element_name, - gpointer user_data, - GError **error); - -static void text_handler (GMarkupParseContext *context, - const gchar *text, - gsize text_len, - gpointer user_data, - GError **error); - -static void error_handler (GMarkupParseContext *context, - GError *error, - gpointer user_data); - -static GMarkupParser parser = {start_element_handler, end_element_handler, - text_handler, - NULL, - error_handler}; - -static gboolean -egg_recent_model_string_match (const GSList *list, const gchar *str) -{ - const GSList *tmp; - - if (list == NULL || str == NULL) - return TRUE; - - tmp = list; - - while (tmp) { - if (g_pattern_match_string (tmp->data, str)) - return TRUE; - - tmp = tmp->next; - } - - return FALSE; -} - -static gboolean -egg_recent_model_write_raw (EggRecentModel *model, FILE *file, - const gchar *content) -{ - int len; - int fd; - struct stat sbuf; - - rewind (file); - - len = strlen (content); - fd = fileno (file); - - if (fstat (fd, &sbuf) < 0) - g_warning ("Couldn't stat XML document."); - - if ((off_t)len < sbuf.st_size) { - ftruncate (fd, len); - } - - if (fputs (content, file) == EOF) - return FALSE; - - fsync (fd); - rewind (file); - - return TRUE; -} - -static GList * -egg_recent_model_delete_from_list (GList *list, - const gchar *uri) -{ - GList *tmp; - - if (!uri) - return list; - - tmp = list; - - while (tmp) { - EggRecentItem *item = tmp->data; - GList *next; - - next = tmp->next; - - if (!strcmp (egg_recent_item_peek_uri (item), uri)) { - egg_recent_item_unref (item); - - list = g_list_remove_link (list, tmp); - g_list_free_1 (tmp); - } - - tmp = next; - } - - return list; -} - -static void -egg_recent_model_add_new_groups (EggRecentItem *item, - EggRecentItem *upd_item) -{ - const GList *tmp; - - tmp = egg_recent_item_get_groups (upd_item); - - while (tmp) { - char *group = tmp->data; - - if (!egg_recent_item_in_group (item, group)) - egg_recent_item_add_group (item, group); - - tmp = tmp->next; - } -} - -static gboolean -egg_recent_model_update_item (GList *items, EggRecentItem *upd_item) -{ - GList *tmp; - const char *uri; - - uri = egg_recent_item_peek_uri (upd_item); - - tmp = items; - - while (tmp) { - EggRecentItem *item = tmp->data; - - if (gnome_vfs_uris_match (egg_recent_item_peek_uri (item), uri)) { - egg_recent_item_set_timestamp (item, (time_t) -1); - - egg_recent_model_add_new_groups (item, upd_item); - - return TRUE; - } - - tmp = tmp->next; - } - - return FALSE; -} - -static gchar * -egg_recent_model_read_raw (EggRecentModel *model, FILE *file) -{ - GString *string; - char buf[EGG_RECENT_MODEL_BUFFER_SIZE]; - - rewind (file); - - string = g_string_new (NULL); - while (fgets (buf, EGG_RECENT_MODEL_BUFFER_SIZE, file)) { - string = g_string_append (string, buf); - } - - rewind (file); - - return g_string_free (string, FALSE); -} - - - -static void -parse_info_init (ParseInfo *info) -{ - info->states = g_slist_prepend (NULL, STATE_START); - info->items = NULL; -} - -static void -parse_info_free (ParseInfo *info) -{ - g_slist_free (info->states); -} - -static void -push_state (ParseInfo *info, - ParseState state) -{ - info->states = g_slist_prepend (info->states, GINT_TO_POINTER (state)); -} - -static void -pop_state (ParseInfo *info) -{ - g_return_if_fail (info->states != NULL); - - info->states = g_slist_remove (info->states, info->states->data); -} - -static ParseState -peek_state (ParseInfo *info) -{ - g_return_val_if_fail (info->states != NULL, STATE_START); - - return GPOINTER_TO_INT (info->states->data); -} - -#define ELEMENT_IS(name) (strcmp (element_name, (name)) == 0) - -static void -start_element_handler (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - gpointer user_data, - GError **error) -{ - ParseInfo *info = (ParseInfo *)user_data; - - if (ELEMENT_IS (TAG_RECENT_FILES)) - push_state (info, STATE_RECENT_FILES); - else if (ELEMENT_IS (TAG_RECENT_ITEM)) { - info->current_item = egg_recent_item_new (); - push_state (info, STATE_RECENT_ITEM); - } else if (ELEMENT_IS (TAG_URI)) - push_state (info, STATE_URI); - else if (ELEMENT_IS (TAG_MIME_TYPE)) - push_state (info, STATE_MIME_TYPE); - else if (ELEMENT_IS (TAG_TIMESTAMP)) - push_state (info, STATE_TIMESTAMP); - else if (ELEMENT_IS (TAG_PRIVATE)) { - push_state (info, STATE_PRIVATE); - egg_recent_item_set_private (info->current_item, TRUE); - } else if (ELEMENT_IS (TAG_GROUPS)) - push_state (info, STATE_GROUPS); - else if (ELEMENT_IS (TAG_GROUP)) - push_state (info, STATE_GROUP); -} - -static gint -list_compare_func_mru (gpointer a, gpointer b) -{ - EggRecentItem *item_a = (EggRecentItem *)a; - EggRecentItem *item_b = (EggRecentItem *)b; - - return item_a->timestamp < item_b->timestamp; -} - -static gint -list_compare_func_lru (gpointer a, gpointer b) -{ - EggRecentItem *item_a = (EggRecentItem *)a; - EggRecentItem *item_b = (EggRecentItem *)b; - - return item_a->timestamp > item_b->timestamp; -} - - - -static void -end_element_handler (GMarkupParseContext *context, - const gchar *element_name, - gpointer user_data, - GError **error) -{ - ParseInfo *info = (ParseInfo *)user_data; - - switch (peek_state (info)) { - case STATE_RECENT_ITEM: - info->items = g_list_append (info->items, - info->current_item); - if (info->current_item->uri == NULL || - strlen (info->current_item->uri) == 0) - g_warning ("URI NOT LOADED"); - break; - default: - break; - } - - pop_state (info); -} - -static void -text_handler (GMarkupParseContext *context, - const gchar *text, - gsize text_len, - gpointer user_data, - GError **error) -{ - ParseInfo *info = (ParseInfo *)user_data; - - switch (peek_state (info)) { - case STATE_START: - case STATE_RECENT_FILES: - case STATE_RECENT_ITEM: - case STATE_PRIVATE: - case STATE_GROUPS: - break; - case STATE_URI: - egg_recent_item_set_uri (info->current_item, text); - break; - case STATE_MIME_TYPE: - egg_recent_item_set_mime_type (info->current_item, - text); - break; - case STATE_TIMESTAMP: - egg_recent_item_set_timestamp (info->current_item, - (time_t)atoi (text)); - break; - case STATE_GROUP: - egg_recent_item_add_group (info->current_item, - text); - break; - } - -} - -static void -error_handler (GMarkupParseContext *context, - GError *error, - gpointer user_data) -{ - g_warning ("Error in parse: %s", error->message); -} - -static void -egg_recent_model_enforce_limit (GList *list, int limit) -{ - int len; - GList *end; - - /* limit < 0 means unlimited */ - if (limit <= 0) - return; - - len = g_list_length (list); - - if (len > limit) { - GList *next; - - end = g_list_nth (list, limit-1); - next = end->next; - - end->next = NULL; - - EGG_RECENT_ITEM_LIST_UNREF (next); - } -} - -static GList * -egg_recent_model_sort (EggRecentModel *model, GList *list) -{ - switch (model->priv->sort_type) { - case EGG_RECENT_MODEL_SORT_MRU: - list = g_list_sort (list, - (GCompareFunc)list_compare_func_mru); - break; - case EGG_RECENT_MODEL_SORT_LRU: - list = g_list_sort (list, - (GCompareFunc)list_compare_func_lru); - break; - case EGG_RECENT_MODEL_SORT_NONE: - break; - } - - return list; -} - -static gboolean -egg_recent_model_group_match (EggRecentItem *item, GSList *groups) -{ - GSList *tmp; - - tmp = groups; - - while (tmp != NULL) { - const gchar * group = (const gchar *)tmp->data; - - if (egg_recent_item_in_group (item, group)) - return TRUE; - - tmp = tmp->next; - } - - return FALSE; -} - -static GList * -egg_recent_model_filter (EggRecentModel *model, - GList *list) -{ - EggRecentItem *item; - GList *newlist = NULL; - gchar *mime_type; - gchar *uri; - - g_return_val_if_fail (list != NULL, NULL); - - while (list) { - gboolean pass_mime_test = FALSE; - gboolean pass_group_test = FALSE; - gboolean pass_scheme_test = FALSE; - item = (EggRecentItem *)list->data; - list = list->next; - - uri = egg_recent_item_get_uri (item); - - /* filter by mime type */ - if (model->priv->mime_filter_values != NULL) { - mime_type = egg_recent_item_get_mime_type (item); - - if (egg_recent_model_string_match - (model->priv->mime_filter_values, - mime_type)) - pass_mime_test = TRUE; - - g_free (mime_type); - } else - pass_mime_test = TRUE; - - /* filter by group */ - if (pass_mime_test && model->priv->group_filter_values != NULL) { - if (egg_recent_model_group_match - (item, model->priv->group_filter_values)) - pass_group_test = TRUE; - } else if (egg_recent_item_get_private (item)) { - pass_group_test = FALSE; - } else - pass_group_test = TRUE; - - /* filter by URI scheme */ - if (pass_mime_test && pass_group_test && - model->priv->scheme_filter_values != NULL) { - gchar *scheme; - - scheme = gnome_vfs_get_uri_scheme (uri); - - if (egg_recent_model_string_match - (model->priv->scheme_filter_values, scheme)) - pass_scheme_test = TRUE; - - g_free (scheme); - } else - pass_scheme_test = TRUE; - - if (pass_mime_test && pass_group_test && pass_scheme_test) - newlist = g_list_prepend (newlist, item); - - g_free (uri); - } - - if (newlist) { - newlist = g_list_reverse (newlist); - g_list_free (list); - } - - - return newlist; -} - - - -#if 0 -static void -egg_recent_model_monitor_list_cb (GnomeVFSMonitorHandle *handle, - const gchar *monitor_uri, - const gchar *info_uri, - GnomeVFSMonitorEventType event_type, - gpointer user_data) -{ - EggRecentModel *model; - - model = EGG_RECENT_MODEL (user_data); - - if (event_type == GNOME_VFS_MONITOR_EVENT_DELETED) { - egg_recent_model_delete (model, monitor_uri); - g_hash_table_remove (model->priv->monitors, monitor_uri); - } -} - - - -static void -egg_recent_model_monitor_list (EggRecentModel *model, GList *list) -{ - GList *tmp; - - tmp = list; - while (tmp) { - EggRecentItem *item = (EggRecentItem *)tmp->data; - GnomeVFSMonitorHandle *handle; - GnomeVFSResult res; - gchar *uri; - - tmp = tmp->next; - - uri = egg_recent_item_get_uri (item); - if (g_hash_table_lookup (model->priv->monitors, uri)) { - /* already monitoring this one */ - g_free (uri); - continue; - } - - res = gnome_vfs_monitor_add (&handle, uri, - GNOME_VFS_MONITOR_FILE, - egg_recent_model_monitor_list_cb, - model); - - if (res == GNOME_VFS_OK) - g_hash_table_insert (model->priv->monitors, uri, handle); - else - g_free (uri); - } -} -#endif - - -static gboolean -egg_recent_model_changed_timeout (EggRecentModel *model) -{ - egg_recent_model_changed (model); - - return FALSE; -} - -static void -egg_recent_model_monitor_cb (GnomeVFSMonitorHandle *handle, - const gchar *monitor_uri, - const gchar *info_uri, - GnomeVFSMonitorEventType event_type, - gpointer user_data) -{ - EggRecentModel *model; - - g_return_if_fail (user_data != NULL); - g_return_if_fail (EGG_IS_RECENT_MODEL (user_data)); - model = EGG_RECENT_MODEL (user_data); - - if (event_type == GNOME_VFS_MONITOR_EVENT_CHANGED) { - if (model->priv->changed_timeout > 0) { - g_source_remove (model->priv->changed_timeout); - } - - model->priv->changed_timeout = g_timeout_add ( - EGG_RECENT_MODEL_TIMEOUT_LENGTH, - (GSourceFunc)egg_recent_model_changed_timeout, - model); - } -} - -static void -egg_recent_model_monitor (EggRecentModel *model, gboolean should_monitor) -{ - if (should_monitor && model->priv->monitor == NULL) { - char *uri; - - uri = gnome_vfs_get_uri_from_local_path (model->priv->path); - - gnome_vfs_monitor_add (&model->priv->monitor, - uri, - GNOME_VFS_MONITOR_FILE, - egg_recent_model_monitor_cb, - model); - - g_free (uri); - - /* if the above fails, don't worry about it. - * local notifications will still happen - */ - - } else if (!should_monitor && model->priv->monitor != NULL) { - gnome_vfs_monitor_cancel (model->priv->monitor); - model->priv->monitor = NULL; - } -} - -static void -egg_recent_model_set_limit_internal (EggRecentModel *model, int limit) -{ - model->priv->limit = limit; - - if (limit <= 0) - egg_recent_model_monitor (model, FALSE); - else { - egg_recent_model_monitor (model, TRUE); - egg_recent_model_changed (model); - } -} - -static GList * -egg_recent_model_read (EggRecentModel *model, FILE *file) -{ - GList *list=NULL; - gchar *content; - GMarkupParseContext *ctx; - ParseInfo info; - GError *error; - - content = egg_recent_model_read_raw (model, file); - - if (strlen (content) <= 0) { - g_free (content); - return NULL; - } - - parse_info_init (&info); - - ctx = g_markup_parse_context_new (&parser, 0, &info, NULL); - - error = NULL; - if (!g_markup_parse_context_parse (ctx, content, strlen (content), - &error)) { - g_warning (error->message); - g_error_free (error); - error = NULL; - goto out; - } - - error = NULL; - if (!g_markup_parse_context_end_parse (ctx, &error)) - goto out; - - g_markup_parse_context_free (ctx); -out: - list = info.items; - - parse_info_free (&info); - - g_free (content); - - /* - g_print ("Total items: %d\n", g_list_length (list)); - */ - - return list; -} - - -static gboolean -egg_recent_model_write (EggRecentModel *model, FILE *file, GList *list) -{ - GString *string; - gchar *data; - EggRecentItem *item; - const GList *groups; - int i; - int ret; - - string = g_string_new ("<?xml version=\"1.0\"?>\n"); - string = g_string_append (string, "<" TAG_RECENT_FILES ">\n"); - - i=0; - while (list) { - gchar *uri; - gchar *mime_type; - gchar *escaped_uri; - time_t timestamp; - item = (EggRecentItem *)list->data; - - - uri = egg_recent_item_get_uri_utf8 (item); - escaped_uri = g_markup_escape_text (uri, - strlen (uri)); - g_free (uri); - - mime_type = egg_recent_item_get_mime_type (item); - timestamp = egg_recent_item_get_timestamp (item); - - string = g_string_append (string, " <" TAG_RECENT_ITEM ">\n"); - - g_string_append_printf (string, - " <" TAG_URI ">%s</" TAG_URI ">\n", escaped_uri); - - if (mime_type) - g_string_append_printf (string, - " <" TAG_MIME_TYPE ">%s</" TAG_MIME_TYPE ">\n", mime_type); - else - g_string_append_printf (string, - " <" TAG_MIME_TYPE "></" TAG_MIME_TYPE ">\n"); - - - g_string_append_printf (string, - " <" TAG_TIMESTAMP ">%d</" TAG_TIMESTAMP ">\n", (int)timestamp); - - if (egg_recent_item_get_private (item)) - string = g_string_append (string, - " <" TAG_PRIVATE "/>\n"); - - /* write the groups */ - string = g_string_append (string, - " <" TAG_GROUPS ">\n"); - groups = egg_recent_item_get_groups (item); - - if (groups == NULL && egg_recent_item_get_private (item)) - g_warning ("Item with URI \"%s\" marked as private, but" - " does not belong to any groups.\n", uri); - - while (groups) { - const gchar *group = (const gchar *)groups->data; - gchar *escaped_group; - - escaped_group = g_markup_escape_text (group, strlen(group)); - - g_string_append_printf (string, - " <" TAG_GROUP ">%s</" TAG_GROUP ">\n", - escaped_group); - - g_free (escaped_group); - - groups = groups->next; - } - - string = g_string_append (string, " </" TAG_GROUPS ">\n"); - - string = g_string_append (string, - " </" TAG_RECENT_ITEM ">\n"); - - g_free (mime_type); - g_free (escaped_uri); - - list = list->next; - i++; - } - - string = g_string_append (string, "</" TAG_RECENT_FILES ">"); - - data = g_string_free (string, FALSE); - - ret = egg_recent_model_write_raw (model, file, data); - - g_free (data); - - return ret; -} - -static FILE * -egg_recent_model_open_file (EggRecentModel *model) -{ - FILE *file; - mode_t prev_umask; - - file = fopen (model->priv->path, "r+"); - if (file == NULL) { - /* be paranoid */ - prev_umask = umask (077); - - file = fopen (model->priv->path, "w+"); - - umask (prev_umask); - - g_return_val_if_fail (file != NULL, NULL); - } - - return file; -} - -static gboolean -egg_recent_model_lock_file (FILE *file) -{ - int fd; - gint try = 5; - - rewind (file); - fd = fileno (file); - - /* Attempt to lock the file 5 times, - * waiting a random interval (< 1 second) - * in between attempts. - * We should really be doing asynchronous - * locking, but requires substantially larger - * changes. - */ - - while (try > 0) - { - int rand_interval; - - if (lockf (fd, F_TLOCK, 0) == 0) - return TRUE; - - rand_interval = 1 + (int) (10.0 * rand()/(RAND_MAX + 1.0)); - - g_usleep (100000 * rand_interval); - - --try; - } - - return FALSE; -} - -static gboolean -egg_recent_model_unlock_file (FILE *file) -{ - int fd; - - rewind (file); - fd = fileno (file); - - return (lockf (fd, F_ULOCK, 0) == 0) ? TRUE : FALSE; -} - -static void -egg_recent_model_finalize (GObject *object) -{ - EggRecentModel *model = EGG_RECENT_MODEL (object); - - egg_recent_model_monitor (model, FALSE); - - - g_slist_foreach (model->priv->mime_filter_values, - (GFunc) g_pattern_spec_free, NULL); - g_slist_free (model->priv->mime_filter_values); - model->priv->mime_filter_values = NULL; - - g_slist_foreach (model->priv->scheme_filter_values, - (GFunc) g_pattern_spec_free, NULL); - g_slist_free (model->priv->scheme_filter_values); - model->priv->scheme_filter_values = NULL; - - g_slist_foreach (model->priv->group_filter_values, - (GFunc) g_free, NULL); - g_slist_free (model->priv->group_filter_values); - model->priv->group_filter_values = NULL; - - - if (model->priv->limit_change_notify_id) - gconf_client_notify_remove (model->priv->client, - model->priv->limit_change_notify_id); - model->priv->expiration_change_notify_id = 0; - - if (model->priv->expiration_change_notify_id) - gconf_client_notify_remove (model->priv->client, - model->priv->expiration_change_notify_id); - model->priv->expiration_change_notify_id = 0; - - g_object_unref (model->priv->client); - model->priv->client = NULL; - - - g_free (model->priv->path); - model->priv->path = NULL; - - g_hash_table_destroy (model->priv->monitors); - model->priv->monitors = NULL; - - - g_free (model->priv); -} - -static void -egg_recent_model_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - EggRecentModel *model = EGG_RECENT_MODEL (object); - - switch (prop_id) - { - case PROP_MIME_FILTERS: - model->priv->mime_filter_values = - (GSList *)g_value_get_pointer (value); - break; - - case PROP_GROUP_FILTERS: - model->priv->group_filter_values = - (GSList *)g_value_get_pointer (value); - break; - - case PROP_SCHEME_FILTERS: - model->priv->scheme_filter_values = - (GSList *)g_value_get_pointer (value); - break; - - case PROP_SORT_TYPE: - model->priv->sort_type = g_value_get_int (value); - break; - - case PROP_LIMIT: - egg_recent_model_set_limit (model, - g_value_get_int (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -egg_recent_model_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - EggRecentModel *model = EGG_RECENT_MODEL (object); - - switch (prop_id) - { - case PROP_MIME_FILTERS: - g_value_set_pointer (value, model->priv->mime_filter_values); - break; - - case PROP_GROUP_FILTERS: - g_value_set_pointer (value, model->priv->group_filter_values); - break; - - case PROP_SCHEME_FILTERS: - g_value_set_pointer (value, model->priv->scheme_filter_values); - break; - - case PROP_SORT_TYPE: - g_value_set_int (value, model->priv->sort_type); - break; - - case PROP_LIMIT: - g_value_set_int (value, model->priv->limit); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -egg_recent_model_class_init (EggRecentModelClass * klass) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (klass); - object_class->set_property = egg_recent_model_set_property; - object_class->get_property = egg_recent_model_get_property; - object_class->finalize = egg_recent_model_finalize; - - model_signals[CHANGED] = g_signal_new ("changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EggRecentModelClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - - g_object_class_install_property (object_class, - PROP_MIME_FILTERS, - g_param_spec_pointer ("mime-filters", - "Mime Filters", - "List of mime types to be allowed.", - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, - PROP_GROUP_FILTERS, - g_param_spec_pointer ("group-filters", - "Group Filters", - "List of groups to be allowed.", - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, - PROP_SCHEME_FILTERS, - g_param_spec_pointer ("scheme-filters", - "Scheme Filters", - "List of URI schemes to be allowed.", - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, - PROP_SORT_TYPE, - g_param_spec_int ("sort-type", - "Sort Type", - "Type of sorting to be done.", - 0, EGG_RECENT_MODEL_SORT_NONE, - EGG_RECENT_MODEL_SORT_MRU, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, - PROP_LIMIT, - g_param_spec_int ("limit", - "Limit", - "Max number of items allowed.", - -1, EGG_RECENT_MODEL_MAX_ITEMS, - EGG_RECENT_MODEL_DEFAULT_LIMIT, - G_PARAM_READWRITE)); - - klass->changed = NULL; -} - - - -static void -egg_recent_model_limit_changed (GConfClient *client, guint cnxn_id, - GConfEntry *entry, gpointer user_data) -{ - EggRecentModel *model; - GConfValue *value; - - model = EGG_RECENT_MODEL (user_data); - - g_return_if_fail (model != NULL); - - if (model->priv->use_default_limit == FALSE) - return; /* ignore this key */ - - /* the key was unset, and the schema has apparently failed */ - if (entry == NULL) - return; - - value = gconf_entry_get_value (entry); - - if (value->type != GCONF_VALUE_INT) { - g_warning ("Expected GConfValue of type integer, " - "got something else"); - } - - - egg_recent_model_set_limit_internal (model, gconf_value_get_int (value)); -} - -static void -egg_recent_model_expiration_changed (GConfClient *client, guint cnxn_id, - GConfEntry *entry, gpointer user_data) -{ - -} - -static void -egg_recent_model_init (EggRecentModel * model) -{ - if (!gnome_vfs_init ()) { - g_warning ("gnome-vfs initialization failed."); - return; - } - - - model->priv = g_new0 (EggRecentModelPrivate, 1); - - model->priv->path = g_strdup_printf ("%s" EGG_RECENT_MODEL_FILE_PATH, - g_get_home_dir ()); - - model->priv->mime_filter_values = NULL; - model->priv->group_filter_values = NULL; - model->priv->scheme_filter_values = NULL; - - model->priv->client = gconf_client_get_default (); - gconf_client_add_dir (model->priv->client, EGG_RECENT_MODEL_KEY_DIR, - GCONF_CLIENT_PRELOAD_ONELEVEL, NULL); - - model->priv->limit_change_notify_id = - gconf_client_notify_add (model->priv->client, - EGG_RECENT_MODEL_DEFAULT_LIMIT_KEY, - egg_recent_model_limit_changed, - model, NULL, NULL); - - model->priv->expiration_change_notify_id = - gconf_client_notify_add (model->priv->client, - EGG_RECENT_MODEL_EXPIRE_KEY, - egg_recent_model_expiration_changed, - model, NULL, NULL); - - model->priv->expire_days = gconf_client_get_int ( - model->priv->client, - EGG_RECENT_MODEL_EXPIRE_KEY, - NULL); - -#if 0 - /* keep this out, for now */ - model->priv->limit = gconf_client_get_int ( - model->priv->client, - EGG_RECENT_MODEL_DEFAULT_LIMIT_KEY, NULL); - model->priv->use_default_limit = TRUE; -#endif - model->priv->limit = EGG_RECENT_MODEL_DEFAULT_LIMIT; - model->priv->use_default_limit = FALSE; - - model->priv->monitors = g_hash_table_new_full ( - g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) gnome_vfs_monitor_cancel); - - model->priv->monitor = NULL; - egg_recent_model_monitor (model, TRUE); -} - - -/** - * egg_recent_model_new: - * @sort: the type of sorting to use - * @limit: maximum number of items in the list - * - * This creates a new EggRecentModel object. - * - * Returns: a EggRecentModel object - */ -EggRecentModel * -egg_recent_model_new (EggRecentModelSort sort) -{ - EggRecentModel *model; - - model = EGG_RECENT_MODEL (g_object_new (egg_recent_model_get_type (), - "sort-type", sort, NULL)); - - g_return_val_if_fail (model, NULL); - - return model; -} - -/** - * egg_recent_model_add_full: - * @model: A EggRecentModel object. - * @item: A EggRecentItem - * - * This function adds an item to the list of recently used URIs. - * - * Returns: gboolean - */ -gboolean -egg_recent_model_add_full (EggRecentModel * model, EggRecentItem *item) -{ - FILE *file; - GList *list = NULL; - gboolean ret = FALSE; - gboolean updated = FALSE; - char *uri; - time_t t; - - g_return_val_if_fail (model != NULL, FALSE); - g_return_val_if_fail (EGG_IS_RECENT_MODEL (model), FALSE); - - uri = egg_recent_item_get_uri (item); - if (strncmp (uri, "recent-files://", strlen ("recent-files://")) == 0) { - g_free (uri); - return FALSE; - } else { - g_free (uri); - } - - file = egg_recent_model_open_file (model); - g_return_val_if_fail (file != NULL, FALSE); - - time (&t); - egg_recent_item_set_timestamp (item, t); - - if (egg_recent_model_lock_file (file)) { - - /* read existing stuff */ - list = egg_recent_model_read (model, file); - - /* if it's already there, we just update it */ - updated = egg_recent_model_update_item (list, item); - - if (!updated) { - list = g_list_prepend (list, item); - - egg_recent_model_enforce_limit (list, - EGG_RECENT_MODEL_MAX_ITEMS); - } - - /* write new stuff */ - if (!egg_recent_model_write (model, file, list)) - g_warning ("Write failed: %s", strerror (errno)); - - if (!updated) - list = g_list_remove (list, item); - - EGG_RECENT_ITEM_LIST_UNREF (list); - ret = TRUE; - } else { - g_warning ("Failed to lock: %s", strerror (errno)); - return FALSE; - } - - if (!egg_recent_model_unlock_file (file)) - g_warning ("Failed to unlock: %s", strerror (errno)); - - fclose (file); - - if (model->priv->monitor == NULL) { - /* since monitoring isn't working, at least give a - * local notification - */ - egg_recent_model_changed (model); - } - - return ret; -} - -/** - * egg_recent_model_add: - * @model: A EggRecentModel object. - * @uri: A string URI - * - * This function adds an item to the list of recently used URIs. - * - * Returns: gboolean - */ -gboolean -egg_recent_model_add (EggRecentModel *model, const gchar *uri) -{ - EggRecentItem *item; - gboolean ret = FALSE; - - g_return_val_if_fail (model != NULL, FALSE); - g_return_val_if_fail (uri != NULL, FALSE); - - item = egg_recent_item_new_from_uri (uri); - - g_return_val_if_fail (item != NULL, FALSE); - - ret = egg_recent_model_add_full (model, item); - - egg_recent_item_unref (item); - - return ret; -} - - - -/** - * egg_recent_model_delete: - * @model: A EggRecentModel object. - * @uri: The URI you want to delete. - * - * This function deletes a URI from the file of recently used URIs. - * - * Returns: gboolean - */ -gboolean -egg_recent_model_delete (EggRecentModel * model, const gchar * uri) -{ - FILE *file; - GList *list; - unsigned int length; - gboolean ret = FALSE; - - g_return_val_if_fail (model != NULL, FALSE); - g_return_val_if_fail (EGG_IS_RECENT_MODEL (model), FALSE); - g_return_val_if_fail (uri != NULL, FALSE); - - file = egg_recent_model_open_file (model); - g_return_val_if_fail (file != NULL, FALSE); - - if (egg_recent_model_lock_file (file)) { - list = egg_recent_model_read (model, file); - - if (list == NULL) - goto out; - - length = g_list_length (list); - - list = egg_recent_model_delete_from_list (list, uri); - - if (length == g_list_length (list)) { - /* nothing was deleted */ - EGG_RECENT_ITEM_LIST_UNREF (list); - } else { - egg_recent_model_write (model, file, list); - EGG_RECENT_ITEM_LIST_UNREF (list); - ret = TRUE; - - } - } else { - g_warning ("Failed to lock: %s", strerror (errno)); - return FALSE; - } - -out: - - if (!egg_recent_model_unlock_file (file)) - g_warning ("Failed to unlock: %s", strerror (errno)); - - fclose (file); - - g_hash_table_remove (model->priv->monitors, uri); - - if (model->priv->monitor == NULL && ret) { - /* since monitoring isn't working, at least give a - * local notification - */ - egg_recent_model_changed (model); - } - - return ret; -} - - -/** - * egg_recent_model_get_list: - * @model: A EggRecentModel object. - * - * This function gets the current contents of the file - * - * Returns: a GList - */ -GList * -egg_recent_model_get_list (EggRecentModel *model) -{ - FILE *file; - GList *list=NULL; - - file = egg_recent_model_open_file (model); - g_return_val_if_fail (file != NULL, NULL); - - if (egg_recent_model_lock_file (file)) { - list = egg_recent_model_read (model, file); - - } else { - g_warning ("Failed to lock: %s", strerror (errno)); - fclose (file); - return NULL; - } - - if (!egg_recent_model_unlock_file (file)) - g_warning ("Failed to unlock: %s", strerror (errno)); - - if (list != NULL) { - list = egg_recent_model_filter (model, list); - list = egg_recent_model_sort (model, list); - - egg_recent_model_enforce_limit (list, model->priv->limit); - } - - fclose (file); - - return list; -} - - - -/** - * egg_recent_model_set_limit: - * @model: A EggRecentModel object. - * @limit: The maximum length of the list - * - * This function sets the maximum length of the list. Note: This only affects - * the length of the list emitted in the "changed" signal, not the list stored - * on disk. - * - * Returns: void - */ -void -egg_recent_model_set_limit (EggRecentModel *model, int limit) -{ - model->priv->use_default_limit = FALSE; - - egg_recent_model_set_limit_internal (model, limit); -} - -/** - * egg_recent_model_get_limit: - * @model: A EggRecentModel object. - * - * This function gets the maximum length of the list. - * - * Returns: int - */ -int -egg_recent_model_get_limit (EggRecentModel *model) -{ - return model->priv->limit; -} - - -/** - * egg_recent_model_clear: - * @model: A EggRecentModel object. - * - * This function clears the contents of the file - * - * Returns: void - */ -void -egg_recent_model_clear (EggRecentModel *model) -{ - FILE *file; - int fd; - - file = egg_recent_model_open_file (model); - g_return_if_fail (file != NULL); - - fd = fileno (file); - - if (egg_recent_model_lock_file (file)) { - ftruncate (fd, 0); - } else { - g_warning ("Failed to lock: %s", strerror (errno)); - return; - } - - if (!egg_recent_model_unlock_file (file)) - g_warning ("Failed to unlock: %s", strerror (errno)); - - fclose (file); -} - - -/** - * egg_recent_model_set_filter_mime_types: - * @model: A EggRecentModel object. - * - * Sets which mime types are allowed in the list. - * - * Returns: void - */ -void -egg_recent_model_set_filter_mime_types (EggRecentModel *model, - ...) -{ - va_list valist; - GSList *list = NULL; - gchar *str; - - g_return_if_fail (model != NULL); - - if (model->priv->mime_filter_values != NULL) { - g_slist_foreach (model->priv->mime_filter_values, - (GFunc) g_pattern_spec_free, NULL); - g_slist_free (model->priv->mime_filter_values); - model->priv->mime_filter_values = NULL; - } - - va_start (valist, model); - - str = va_arg (valist, gchar*); - - while (str != NULL) { - list = g_slist_prepend (list, g_pattern_spec_new (str)); - - str = va_arg (valist, gchar*); - } - - va_end (valist); - - model->priv->mime_filter_values = list; -} - -/** - * egg_recent_model_set_filter_groups: - * @model: A EggRecentModel object. - * - * Sets which groups are allowed in the list. - * - * Returns: void - */ -void -egg_recent_model_set_filter_groups (EggRecentModel *model, - ...) -{ - va_list valist; - GSList *list = NULL; - gchar *str; - - g_return_if_fail (model != NULL); - - if (model->priv->group_filter_values != NULL) { - g_slist_foreach (model->priv->group_filter_values, (GFunc)g_free, NULL); - g_slist_free (model->priv->group_filter_values); - model->priv->group_filter_values = NULL; - } - - va_start (valist, model); - - str = va_arg (valist, gchar*); - - while (str != NULL) { - list = g_slist_prepend (list, g_strdup (str)); - - str = va_arg (valist, gchar*); - } - - va_end (valist); - - model->priv->group_filter_values = list; -} - -/** - * egg_recent_model_set_filter_uri_schemes: - * @model: A EggRecentModel object. - * - * Sets which URI schemes (file, http, ftp, etc) are allowed in the list. - * - * Returns: void - */ -void -egg_recent_model_set_filter_uri_schemes (EggRecentModel *model, ...) -{ - va_list valist; - GSList *list = NULL; - gchar *str; - - g_return_if_fail (model != NULL); - - if (model->priv->scheme_filter_values != NULL) { - g_slist_foreach (model->priv->scheme_filter_values, - (GFunc) g_pattern_spec_free, NULL); - g_slist_free (model->priv->scheme_filter_values); - model->priv->scheme_filter_values = NULL; - } - - va_start (valist, model); - - str = va_arg (valist, gchar*); - - while (str != NULL) { - list = g_slist_prepend (list, g_pattern_spec_new (str)); - - str = va_arg (valist, gchar*); - } - - va_end (valist); - - model->priv->scheme_filter_values = list; -} - -/** - * egg_recent_model_set_sort: - * @model: A EggRecentModel object. - * @sort: A EggRecentModelSort type - * - * Sets the type of sorting to be used. - * - * Returns: void - */ -void -egg_recent_model_set_sort (EggRecentModel *model, - EggRecentModelSort sort) -{ - g_return_if_fail (model != NULL); - - model->priv->sort_type = sort; -} - -/** - * egg_recent_model_changed: - * @model: A EggRecentModel object. - * - * This function causes a "changed" signal to be emitted. - * - * Returns: void - */ -void -egg_recent_model_changed (EggRecentModel *model) -{ - GList *list = NULL; - - if (model->priv->limit > 0) { - list = egg_recent_model_get_list (model); - /* egg_recent_model_monitor_list (model, list); */ - - g_signal_emit (G_OBJECT (model), model_signals[CHANGED], 0, - list); - } - - if (list) - EGG_RECENT_ITEM_LIST_UNREF (list); -} - -static void -egg_recent_model_remove_expired_list (EggRecentModel *model, GList *list) -{ - time_t current_time; - time_t day_seconds; - - time (¤t_time); - day_seconds = model->priv->expire_days*24*60*60; - - while (list != NULL) { - EggRecentItem *item = list->data; - time_t timestamp; - - timestamp = egg_recent_item_get_timestamp (item); - - if ((timestamp+day_seconds) < current_time) { - gchar *uri = egg_recent_item_get_uri (item); - egg_recent_model_delete (model, uri); - - g_strdup (uri); - } - - list = list->next; - } -} - - -/** - * egg_recent_model_remove_expired: - * @model: A EggRecentModel object. - * - * Goes through the entire list, and removes any items that are older than - * the user-specified expiration period. - * - * Returns: void - */ -void -egg_recent_model_remove_expired (EggRecentModel *model) -{ - FILE *file; - GList *list=NULL; - - g_return_if_fail (model != NULL); - - file = egg_recent_model_open_file (model); - g_return_if_fail (file != NULL); - - if (egg_recent_model_lock_file (file)) { - list = egg_recent_model_read (model, file); - - } else { - g_warning ("Failed to lock: %s", strerror (errno)); - return; - } - - if (!egg_recent_model_unlock_file (file)) - g_warning ("Failed to unlock: %s", strerror (errno)); - - if (list != NULL) { - egg_recent_model_remove_expired_list (model, list); - EGG_RECENT_ITEM_LIST_UNREF (list); - } - - fclose (file); -} - -/** - * egg_recent_model_get_type: - * - * This returns a GType representing a EggRecentModel object. - * - * Returns: a GType - */ -GType -egg_recent_model_get_type (void) -{ - static GType egg_recent_model_type = 0; - - if(!egg_recent_model_type) { - static const GTypeInfo egg_recent_model_info = { - sizeof (EggRecentModelClass), - NULL, /* base init */ - NULL, /* base finalize */ - (GClassInitFunc)egg_recent_model_class_init, /* class init */ - NULL, /* class finalize */ - NULL, /* class data */ - sizeof (EggRecentModel), - 0, - (GInstanceInitFunc) egg_recent_model_init - }; - - egg_recent_model_type = g_type_register_static (G_TYPE_OBJECT, - "EggRecentModel", - &egg_recent_model_info, 0); - } - - return egg_recent_model_type; -} - diff --git a/cut-n-paste-code/libegg/egg-recent-model.h b/cut-n-paste-code/libegg/egg-recent-model.h deleted file mode 100644 index 8c2eb8da1..000000000 --- a/cut-n-paste-code/libegg/egg-recent-model.h +++ /dev/null @@ -1,80 +0,0 @@ -/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -#ifndef __EGG_RECENT_MODEL_H__ -#define __EGG_RECENT_MODEL_H__ - -#include "egg-recent-item.h" - -G_BEGIN_DECLS - -#define EGG_TYPE_RECENT_MODEL (egg_recent_model_get_type ()) -#define EGG_RECENT_MODEL(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, EGG_TYPE_RECENT_MODEL, EggRecentModel) -#define EGG_RECENT_MODEL_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, EGG_TYPE_RECENT_MODEL, EggRecentModelClass) -#define EGG_IS_RECENT_MODEL(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, egg_recent_model_get_type ()) - -typedef struct _EggRecentModel EggRecentModel; -typedef struct _EggRecentModelPrivate EggRecentModelPrivate; -typedef struct _EggRecentModelClass EggRecentModelClass; - -struct _EggRecentModel { - GObject parent_instance; - - EggRecentModelPrivate *priv; -}; - -struct _EggRecentModelClass { - GObjectClass parent_class; - - void (*changed) (EggRecentModel *model, GList *list); -}; - -typedef enum { - EGG_RECENT_MODEL_SORT_MRU, - EGG_RECENT_MODEL_SORT_LRU, - EGG_RECENT_MODEL_SORT_NONE -} EggRecentModelSort; - - -/* Standard group names */ -#define EGG_RECENT_GROUP_LAUNCHERS "Launchers" - - -GType egg_recent_model_get_type (void); - -/* constructors */ -EggRecentModel * egg_recent_model_new (EggRecentModelSort sort); - -/* public methods */ -void egg_recent_model_set_filter_mime_types (EggRecentModel *model, - ...); - -void egg_recent_model_set_filter_groups (EggRecentModel *model, ...); - -void egg_recent_model_set_filter_uri_schemes (EggRecentModel *model, - ...); - -void egg_recent_model_set_sort (EggRecentModel *model, - EggRecentModelSort sort); - -gboolean egg_recent_model_add_full (EggRecentModel *model, - EggRecentItem *item); - -gboolean egg_recent_model_add (EggRecentModel *model, - const gchar *uri); - -gboolean egg_recent_model_delete (EggRecentModel *model, - const gchar *uri); - -void egg_recent_model_clear (EggRecentModel *model); - -GList * egg_recent_model_get_list (EggRecentModel *model); - -void egg_recent_model_changed (EggRecentModel *model); - -void egg_recent_model_set_limit (EggRecentModel *model, int limit); -int egg_recent_model_get_limit (EggRecentModel *model); - -void egg_recent_model_remove_expired (EggRecentModel *model); - -G_END_DECLS - -#endif /* __EGG_RECENT_MODEL_H__ */ |