diff options
author | Carlos Garcia Campos <carlosgc@gnome.org> | 2007-10-26 15:29:32 (GMT) |
---|---|---|
committer | Carlos Garcia Campos <carlosgc@src.gnome.org> | 2007-10-26 15:29:32 (GMT) |
commit | f75f5694d713ead3d2942127ad0dfeb7259a0357 (patch) | |
tree | 038a48e5fede4b57e0e7d49f849fc9929d605142 /cut-n-paste/recent-files/egg-recent-model.c | |
parent | f7e355c8f2621f8026a9461a25ee4e1d60b28bb7 (diff) |
Removed
2007-10-26 Carlos Garcia Campos <carlosgc@gnome.org>
* configure.ac:
* cut-n-paste/Makefile.am:
* cut-n-paste/recent-files/*: Removed
* help/reference/Makefile.am:
* shell/Makefile.am:
* shell/ev-application.[ch]: (ev_application_shutdown),
(ev_application_init):
* shell/ev-window.c: (ev_window_add_recent),
(ev_window_setup_recent), (ev_window_dispose), (ev_window_init):
Bump requirements to gtk+ 2.10.0 and remove egg-recent code.
svn path=/trunk/; revision=2722
Diffstat (limited to 'cut-n-paste/recent-files/egg-recent-model.c')
-rw-r--r-- | cut-n-paste/recent-files/egg-recent-model.c | 1963 |
1 files changed, 0 insertions, 1963 deletions
diff --git a/cut-n-paste/recent-files/egg-recent-model.c b/cut-n-paste/recent-files/egg-recent-model.c deleted file mode 100644 index c9c255b..0000000 --- a/cut-n-paste/recent-files/egg-recent-model.c +++ /dev/null @@ -1,1963 +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 <sys/stat.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_POLL_TIME 3 - -/* needed for Darwin */ -#if !HAVE_DECL_LOCKF -int lockf (int filedes, int function, off_t size); -#endif - -#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; - guint poll_timeout; - time_t last_mtime; -}; - -/* 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 { - 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 GObjectClass *parent_class; - -static void egg_recent_model_clear_mime_filter (EggRecentModel *model); -static void egg_recent_model_clear_group_filter (EggRecentModel *model); -static void egg_recent_model_clear_scheme_filter (EggRecentModel *model); - -static GObjectClass *parent_class; - -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; - -#ifndef G_OS_WIN32 - fsync (fd); -#endif - 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 ParseInfo * -parse_info_init (void) -{ - ParseInfo *retval; - - retval = g_new0 (ParseInfo, 1); - retval->states = g_slist_prepend (NULL, STATE_START); - retval->items = NULL; - - return retval; -} - -static void -parse_info_free (ParseInfo *info) -{ - g_slist_free (info->states); - g_free (info); -} - -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 gboolean -valid_element (ParseInfo *info, - int valid_parent_state, - const gchar *element_name, - const gchar *valid_element, - GError **error) -{ - if (peek_state (info) != valid_parent_state) { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - "Unexpected tag '%s', tag '%s' expected", - element_name, valid_element); - return FALSE; - } - - return TRUE; -} - -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)) { - if (valid_element (info, STATE_RECENT_FILES, - TAG_RECENT_ITEM, TAG_RECENT_FILES, error)) { - info->current_item = egg_recent_item_new (); - push_state (info, STATE_RECENT_ITEM); - } - } else if (ELEMENT_IS (TAG_URI)) { - if (valid_element (info, STATE_RECENT_ITEM, - TAG_URI, TAG_RECENT_ITEM, error)) { - push_state (info, STATE_URI); - } - } else if (ELEMENT_IS (TAG_MIME_TYPE)) { - if (valid_element (info, STATE_RECENT_ITEM, - TAG_MIME_TYPE, TAG_RECENT_ITEM, error)) { - push_state (info, STATE_MIME_TYPE); - } - } else if (ELEMENT_IS (TAG_TIMESTAMP)) { - if (valid_element (info, STATE_RECENT_ITEM, - TAG_TIMESTAMP, TAG_RECENT_ITEM, error)) { - push_state (info, STATE_TIMESTAMP); - } - } else if (ELEMENT_IS (TAG_PRIVATE)) { - if (valid_element (info, STATE_RECENT_ITEM, - TAG_PRIVATE, TAG_RECENT_ITEM, error)) { - push_state (info, STATE_PRIVATE); - egg_recent_item_set_private (info->current_item, TRUE); - } - } else if (ELEMENT_IS (TAG_GROUPS)) { - if (valid_element (info, STATE_RECENT_ITEM, - TAG_GROUPS, TAG_RECENT_ITEM, error)) { - push_state (info, STATE_GROUPS); - } - } else if (ELEMENT_IS (TAG_GROUP)) { - if (valid_element (info, STATE_GROUPS, - TAG_GROUP, TAG_GROUPS, error)) { - 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: - if (!info->current_item) { - g_warning ("No recent item found\n"); - break; - } - - if (!info->current_item->uri) { - g_warning ("Invalid item found\n"); - break; - } - - info->items = g_list_prepend (info->items, - info->current_item); - info->current_item = NULL; - 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; - gchar *value; - - value = g_strndup (text, text_len); - - 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, value); - break; - case STATE_MIME_TYPE: - egg_recent_item_set_mime_type (info->current_item, value); - break; - case STATE_TIMESTAMP: - egg_recent_item_set_timestamp (info->current_item, - (time_t)atoi (value)); - break; - case STATE_GROUP: - egg_recent_item_add_group (info->current_item, - text); - break; - } - - g_free (value); -} - -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) -{ - GList *newlist = NULL; - GList *l; - gchar *mime_type; - gchar *uri; - - g_return_val_if_fail (list != NULL, NULL); - - for (l = list; l != NULL ; l = l->next) { - EggRecentItem *item = (EggRecentItem *) l->data; - gboolean pass_mime_test = FALSE; - gboolean pass_group_test = FALSE; - gboolean pass_scheme_test = FALSE; - - g_assert (item != NULL); - - 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); - else - egg_recent_item_unref (item); - - g_free (uri); - } - - g_list_free (list); - - return g_list_reverse (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) -{ - model->priv->changed_timeout = 0; - - 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 || - event_type == GNOME_VFS_MONITOR_EVENT_CREATED || - event_type == GNOME_VFS_MONITOR_EVENT_DELETED) { - 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 gboolean -egg_recent_model_poll_timeout (gpointer user_data) -{ - EggRecentModel *model; - struct stat stat_buf; - int stat_res; - - model = EGG_RECENT_MODEL (user_data); - stat_res = stat (model->priv->path, &stat_buf); - - if (!stat_res && stat_buf.st_mtime && - stat_buf.st_mtime != model->priv->last_mtime) { - model->priv->last_mtime = stat_buf.st_mtime; - - 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); - } - return TRUE; -} - -static void -egg_recent_model_monitor (EggRecentModel *model, gboolean should_monitor) -{ - if (should_monitor && model->priv->monitor == NULL) { - char *uri; - GnomeVFSResult result; - - uri = gnome_vfs_get_uri_from_local_path (model->priv->path); - - result = 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 - */ - if (result == GNOME_VFS_ERROR_NOT_SUPPORTED) { - if (model->priv->poll_timeout > 0) - g_source_remove (model->priv->poll_timeout); - - model->priv->poll_timeout = g_timeout_add ( - EGG_RECENT_MODEL_POLL_TIME * 1000, - egg_recent_model_poll_timeout, - model); - } - - } 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; - } - - info = parse_info_init (); - - 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 while parsing the .recently-used file: %s\n", - error->message); - - g_error_free (error); - parse_info_free (info); - - return NULL; - } - - error = NULL; - if (!g_markup_parse_context_end_parse (ctx, &error)) { - g_warning ("Unable to complete parsing of the .recently-used file: %s\n", - error->message); - - g_error_free (error); - g_markup_parse_context_free (ctx); - parse_info_free (info); - - return NULL; - } - - list = g_list_reverse (info->items); - - g_markup_parse_context_free (ctx); - parse_info_free (info); - g_free (content); - - 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, - gboolean for_writing) -{ - FILE *file; - mode_t prev_umask; - - file = fopen (model->priv->path, "r+"); - if (file == NULL && for_writing) { - /* 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) -{ -#ifdef HAVE_LOCKF - 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; -#else - return TRUE; -#endif /* HAVE_LOCKF */ -} - -static gboolean -egg_recent_model_unlock_file (FILE *file) -{ -#ifdef HAVE_LOCKF - int fd; - - rewind (file); - fd = fileno (file); - - return (lockf (fd, F_ULOCK, 0) == 0) ? TRUE : FALSE; -#else - return TRUE; -#endif /* HAVE_LOCKF */ -} - -static void -egg_recent_model_finalize (GObject *object) -{ - EggRecentModel *model = EGG_RECENT_MODEL (object); - - if (model->priv->changed_timeout > 0) { - g_source_remove (model->priv->changed_timeout); - } - - 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; - - if (model->priv->poll_timeout > 0) - g_source_remove (model->priv->poll_timeout); - model->priv->poll_timeout =0; - - g_free (model->priv); - - parent_class->finalize (object); -} - -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: - if (model->priv->mime_filter_values != NULL) - egg_recent_model_clear_mime_filter (model); - - model->priv->mime_filter_values = - (GSList *)g_value_get_pointer (value); - break; - - case PROP_GROUP_FILTERS: - if (model->priv->group_filter_values != NULL) - egg_recent_model_clear_group_filter (model); - - model->priv->group_filter_values = - (GSList *)g_value_get_pointer (value); - break; - - case PROP_SCHEME_FILTERS: - if (model->priv->scheme_filter_values != NULL) - egg_recent_model_clear_scheme_filter (model); - - 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; - - parent_class = g_type_class_peek_parent (klass); - - parent_class = g_type_class_peek_parent (klass); - - 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; - model->priv->poll_timeout = 0; - model->priv->last_mtime = 0; - 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, TRUE); - 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)); - fclose (file); - 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, TRUE); - 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, FALSE); - if (file == NULL) - return 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, TRUE); - 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); - - if (model->priv->monitor == NULL) { - /* since monitoring isn't working, at least give a - * local notification - */ - egg_recent_model_changed (model); - } -} - -static void -egg_recent_model_clear_mime_filter (EggRecentModel *model) -{ - 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; - } -} - -/** - * 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); - - egg_recent_model_clear_mime_filter (model); - - 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; -} - -static void -egg_recent_model_clear_group_filter (EggRecentModel *model) -{ - 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; - } -} - -/** - * 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); - - egg_recent_model_clear_group_filter (model); - - 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; -} - -static void -egg_recent_model_clear_scheme_filter (EggRecentModel *model) -{ - 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; - } -} - -/** - * 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); - - egg_recent_model_clear_scheme_filter (model); - - 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, FALSE); - if (file == NULL) - return; - - 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) { - 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; -} - |