From c7bae2c213369b853bb420e5cf09d192f38f8cce Mon Sep 17 00:00:00 2001 From: Nickolay V. Shmyrev Date: Tue, 17 Jan 2006 21:53:17 +0000 Subject: Update from libegg. * cut-n-paste/recent-files/egg-recent-item.c: (get_uri_shortname_for_display), (egg_recent_item_get_short_name): * cut-n-paste/recent-files/egg-recent-model.c: (parse_info_init), (parse_info_free), (valid_element), (start_element_handler), (end_element_handler), (text_handler), (egg_recent_model_filter), (egg_recent_model_monitor_cb), (egg_recent_model_poll_timeout), (egg_recent_model_monitor), (egg_recent_model_read), (egg_recent_model_open_file), (egg_recent_model_lock_file), (egg_recent_model_unlock_file), (egg_recent_model_finalize), (egg_recent_model_set_property), (egg_recent_model_class_init), (egg_recent_model_init), (egg_recent_model_add_full), (egg_recent_model_delete), (egg_recent_model_get_list), (egg_recent_model_clear), (egg_recent_model_clear_mime_filter), (egg_recent_model_set_filter_mime_types), (egg_recent_model_clear_group_filter), (egg_recent_model_set_filter_groups), (egg_recent_model_clear_scheme_filter), (egg_recent_model_set_filter_uri_schemes), (egg_recent_model_remove_expired): * cut-n-paste/recent-files/egg-recent-util.c: (egg_recent_util_get_icon): * cut-n-paste/recent-files/egg-recent-util.h: * cut-n-paste/recent-files/egg-recent-view-uimanager.c: (connect_proxy_cb), (egg_recent_view_uimanager_set_list), (egg_recent_view_uimanager_set_empty_list), (model_changed_cb), (egg_recent_view_uimanager_set_property), (egg_recent_view_uimanager_get_property), (egg_recent_view_uimanager_class_init), (egg_recent_view_uimanager_init), (egg_recent_view_uimanager_set_label_width), (egg_recent_view_uimanager_get_label_width): * cut-n-paste/recent-files/egg-recent-view-uimanager.h: * cut-n-paste/toolbar-editor/egg-editable-toolbar.c: * cut-n-paste/toolbar-editor/egg-editable-toolbar.h: * cut-n-paste/toolbar-editor/egg-toolbar-editor.c: * cut-n-paste/toolbar-editor/egg-toolbars-model.c: * cut-n-paste/toolbar-editor/egg-toolbars-model.h: Update from libegg. --- (limited to 'cut-n-paste/recent-files') diff --git a/cut-n-paste/recent-files/egg-recent-item.c b/cut-n-paste/recent-files/egg-recent-item.c index bf7fee6..ce4b64e 100644 --- a/cut-n-paste/recent-files/egg-recent-item.c +++ b/cut-n-paste/recent-files/egg-recent-item.c @@ -101,84 +101,6 @@ egg_recent_item_new_from_uri (const gchar *uri) 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->mime_type_is_explicit = item->mime_type_is_explicit - 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; -} -*/ - static void egg_recent_item_update_mime_type (EggRecentItem *item) { @@ -288,6 +210,70 @@ make_valid_utf8 (const char *name) return g_string_free (string, FALSE); } +static gchar * +get_uri_shortname_for_display (GnomeVFSURI *uri) +{ + gchar *name; + gboolean validated; + + validated = FALSE; + name = gnome_vfs_uri_extract_short_name (uri); + + if (name == NULL) + { + name = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_PASSWORD); + } + else if (g_ascii_strcasecmp (uri->method_string, "file") == 0) + { + gchar *text_uri; + gchar *local_file; + text_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_PASSWORD); + local_file = gnome_vfs_get_local_path_from_uri (text_uri); + + if (local_file != NULL) + { + g_free (name); + name = g_filename_display_basename (local_file); + validated = TRUE; + } + + g_free (local_file); + g_free (text_uri); + } + else if (!gnome_vfs_uri_has_parent (uri)) + { + const gchar *method; + + method = uri->method_string; + + if (name == NULL || + strcmp (name, GNOME_VFS_URI_PATH_STR) == 0) + { + g_free (name); + name = g_strdup (method); + } + else + { + gchar *tmp; + + tmp = name; + name = g_strdup_printf ("%s: %s", method, name); + g_free (tmp); + } + } + + if (!validated && !g_utf8_validate (name, -1, NULL)) + { + gchar *utf8_name; + + utf8_name = make_valid_utf8 (name); + g_free (name); + name = utf8_name; + } + + return name; +} + /** * egg_recent_item_get_short_name: * @item: an #EggRecentItem @@ -303,8 +289,7 @@ gchar * egg_recent_item_get_short_name (const EggRecentItem *item) { GnomeVFSURI *uri; - char *short_name; - gboolean valid; + gchar *short_name; g_return_val_if_fail (item != NULL, NULL); @@ -315,33 +300,7 @@ egg_recent_item_get_short_name (const EggRecentItem *item) if (uri == NULL) return NULL; - short_name = gnome_vfs_uri_extract_short_name (uri); - if (short_name == NULL) { - gnome_vfs_uri_unref (uri); - return NULL; - } - - 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; - } + short_name = get_uri_shortname_for_display (uri); gnome_vfs_uri_unref (uri); diff --git a/cut-n-paste/recent-files/egg-recent-model.c b/cut-n-paste/recent-files/egg-recent-model.c index 067a635..fc83fef 100644 --- a/cut-n-paste/recent-files/egg-recent-model.c +++ b/cut-n-paste/recent-files/egg-recent-model.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,12 @@ #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" @@ -71,6 +78,8 @@ struct _EggRecentModelPrivate { guint expiration_change_notify_id; guint changed_timeout; + guint poll_timeout; + time_t last_mtime; }; /* signals */ @@ -95,7 +104,7 @@ typedef struct { GSList *states; GList *items; EggRecentItem *current_item; -}ParseInfo; +} ParseInfo; typedef enum { STATE_START, @@ -109,10 +118,10 @@ typedef enum { STATE_GROUP } ParseState; -typedef struct _ChangedData { +typedef struct { EggRecentModel *model; GList *list; -}ChangedData; +} ChangedData; #define TAG_RECENT_FILES "RecentFiles" #define TAG_RECENT_ITEM "RecentItem" @@ -150,6 +159,14 @@ static GMarkupParser parser = {start_element_handler, end_element_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) { @@ -296,17 +313,23 @@ egg_recent_model_read_raw (EggRecentModel *model, FILE *file) -static void -parse_info_init (ParseInfo *info) +static ParseInfo * +parse_info_init (void) { - info->states = g_slist_prepend (NULL, STATE_START); - info->items = NULL; + 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 @@ -334,6 +357,25 @@ peek_state (ParseInfo *info) #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, @@ -347,21 +389,43 @@ start_element_handler (GMarkupParseContext *context, 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); + 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 @@ -394,14 +458,22 @@ end_element_handler (GMarkupParseContext *context, 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; + 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; + break; } pop_state (info); @@ -415,6 +487,9 @@ text_handler (GMarkupParseContext *context, GError **error) { ParseInfo *info = (ParseInfo *)user_data; + gchar *value; + + value = g_strndup (text, text_len); switch (peek_state (info)) { case STATE_START: @@ -424,22 +499,22 @@ text_handler (GMarkupParseContext *context, case STATE_GROUPS: break; case STATE_URI: - egg_recent_item_set_uri (info->current_item, text); + egg_recent_item_set_uri (info->current_item, value); break; case STATE_MIME_TYPE: - egg_recent_item_set_mime_type (info->current_item, - text); + 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 (text)); + (time_t)atoi (value)); break; case STATE_GROUP: egg_recent_item_add_group (info->current_item, text); break; } - + + g_free (value); } static void @@ -513,23 +588,23 @@ egg_recent_model_group_match (EggRecentItem *item, GSList *groups) } static GList * -egg_recent_model_filter (EggRecentModel *model, - GList *list) +egg_recent_model_filter (EggRecentModel *model, GList *list) { - EggRecentItem *item; GList *newlist = NULL; + GList *l; gchar *mime_type; gchar *uri; g_return_val_if_fail (list != NULL, NULL); - while (list) { + 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; - item = (EggRecentItem *)list->data; - list = list->next; + g_assert (item != NULL); + uri = egg_recent_item_get_uri (item); /* filter by mime type */ @@ -572,17 +647,15 @@ egg_recent_model_filter (EggRecentModel *model, 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); } - if (newlist) { - newlist = g_list_reverse (newlist); - g_list_free (list); - } + g_list_free (list); - - return newlist; + return g_list_reverse (newlist); } @@ -665,7 +738,9 @@ egg_recent_model_monitor_cb (GnomeVFSMonitorHandle *handle, 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 (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); } @@ -677,25 +752,60 @@ egg_recent_model_monitor_cb (GnomeVFSMonitorHandle *handle, } } +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); - gnome_vfs_monitor_add (&model->priv->monitor, - uri, - GNOME_VFS_MONITOR_FILE, - egg_recent_model_monitor_cb, - model); + 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); @@ -722,7 +832,7 @@ egg_recent_model_read (EggRecentModel *model, FILE *file) GList *list=NULL; gchar *content; GMarkupParseContext *ctx; - ParseInfo info; + ParseInfo *info; GError *error; content = egg_recent_model_read_raw (model, file); @@ -732,35 +842,39 @@ egg_recent_model_read (EggRecentModel *model, FILE *file) return NULL; } - parse_info_init (&info); + info = parse_info_init (); - ctx = g_markup_parse_context_new (&parser, 0, &info, NULL); + 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); + 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); - error = NULL; - goto out; + parse_info_free (info); + + return NULL; } error = NULL; - if (!g_markup_parse_context_end_parse (ctx, &error)) - goto out; - - g_markup_parse_context_free (ctx); -out: - list = info.items; + 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); - 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); - /* - g_print ("Total items: %d\n", g_list_length (list)); - */ - return list; } @@ -863,13 +977,14 @@ egg_recent_model_write (EggRecentModel *model, FILE *file, GList *list) } static FILE * -egg_recent_model_open_file (EggRecentModel *model) +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) { + if (file == NULL && for_writing) { /* be paranoid */ prev_umask = umask (077); @@ -886,7 +1001,7 @@ egg_recent_model_open_file (EggRecentModel *model) static gboolean egg_recent_model_lock_file (FILE *file) { -#ifdef F_TLOCK +#ifdef HAVE_LOCKF int fd; gint try = 5; @@ -918,13 +1033,13 @@ egg_recent_model_lock_file (FILE *file) return FALSE; #else return TRUE; -#endif +#endif /* HAVE_LOCKF */ } static gboolean egg_recent_model_unlock_file (FILE *file) { -#ifdef F_TLOCK +#ifdef HAVE_LOCKF int fd; rewind (file); @@ -933,7 +1048,7 @@ egg_recent_model_unlock_file (FILE *file) return (lockf (fd, F_ULOCK, 0) == 0) ? TRUE : FALSE; #else return TRUE; -#endif +#endif /* HAVE_LOCKF */ } static void @@ -984,8 +1099,13 @@ egg_recent_model_finalize (GObject *object) 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 @@ -999,16 +1119,25 @@ egg_recent_model_set_property (GObject *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; @@ -1069,6 +1198,10 @@ 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; @@ -1219,6 +1352,8 @@ egg_recent_model_init (EggRecentModel * model) (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); } @@ -1275,7 +1410,7 @@ egg_recent_model_add_full (EggRecentModel * model, EggRecentItem *item) g_free (uri); } - file = egg_recent_model_open_file (model); + file = egg_recent_model_open_file (model, TRUE); g_return_val_if_fail (file != NULL, FALSE); time (&t); @@ -1378,7 +1513,7 @@ egg_recent_model_delete (EggRecentModel * model, const gchar * uri) 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); + file = egg_recent_model_open_file (model, TRUE); g_return_val_if_fail (file != NULL, FALSE); if (egg_recent_model_lock_file (file)) { @@ -1437,15 +1572,15 @@ GList * egg_recent_model_get_list (EggRecentModel *model) { FILE *file; - GList *list=NULL; + GList *list = NULL; - file = egg_recent_model_open_file (model); - g_return_val_if_fail (file != NULL, NULL); + file = egg_recent_model_open_file (model, FALSE); + if (file == NULL) + return NULL; - if (egg_recent_model_lock_file (file)) { + if (egg_recent_model_lock_file (file)) list = egg_recent_model_read (model, file); - - } else { + else { g_warning ("Failed to lock: %s", strerror (errno)); fclose (file); return NULL; @@ -1516,7 +1651,7 @@ egg_recent_model_clear (EggRecentModel *model) FILE *file; int fd; - file = egg_recent_model_open_file (model); + file = egg_recent_model_open_file (model, TRUE); g_return_if_fail (file != NULL); fd = fileno (file); @@ -1532,8 +1667,27 @@ egg_recent_model_clear (EggRecentModel *model) 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: @@ -1553,12 +1707,7 @@ egg_recent_model_set_filter_mime_types (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_clear_mime_filter (model); va_start (valist, model); @@ -1575,6 +1724,18 @@ egg_recent_model_set_filter_mime_types (EggRecentModel *model, 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. @@ -1593,12 +1754,8 @@ egg_recent_model_set_filter_groups (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_clear_group_filter (model); + va_start (valist, model); str = va_arg (valist, gchar*); @@ -1614,6 +1771,19 @@ egg_recent_model_set_filter_groups (EggRecentModel *model, 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. @@ -1631,13 +1801,8 @@ egg_recent_model_set_filter_uri_schemes (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_clear_scheme_filter (model); + va_start (valist, model); str = va_arg (valist, gchar*); @@ -1740,8 +1905,9 @@ egg_recent_model_remove_expired (EggRecentModel *model) g_return_if_fail (model != NULL); - file = egg_recent_model_open_file (model); - g_return_if_fail (file != 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); diff --git a/cut-n-paste/recent-files/egg-recent-util.c b/cut-n-paste/recent-files/egg-recent-util.c index bc15a06..4597f03 100644 --- a/cut-n-paste/recent-files/egg-recent-util.c +++ b/cut-n-paste/recent-files/egg-recent-util.c @@ -2,13 +2,12 @@ #include #include #include -#include -#include -#include #ifndef USE_STABLE_LIBGNOMEUI -#include #include #endif +#include +#include +#include #include #include "egg-recent-util.h" @@ -57,72 +56,26 @@ egg_recent_util_escape_underlines (const gchar* text) return g_string_free (str, FALSE); } -#ifndef USE_STABLE_LIBGNOMEUI -static GdkPixbuf * -load_icon_file (char *filename, - guint nominal_size) -{ - GdkPixbuf *pixbuf, *scaled_pixbuf; - guint width, height; - - pixbuf = gdk_pixbuf_new_from_file_at_size (filename, nominal_size, nominal_size, NULL); - - if (pixbuf == NULL) { - return NULL; - } - - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - /* if the icon is larger than the nominal size, scale down */ - if (MAX (width, height) > nominal_size) { - if (width > height) { - height = height * nominal_size / width; - width = nominal_size; - } else { - width = width * nominal_size / height; - height = nominal_size; - } - scaled_pixbuf = gdk_pixbuf_scale_simple - (pixbuf, width, height, GDK_INTERP_BILINEAR); - g_object_unref (pixbuf); - pixbuf = scaled_pixbuf; - } - - return pixbuf; -} - GdkPixbuf * -egg_recent_util_get_icon (GnomeIconTheme *theme, const gchar *uri, +egg_recent_util_get_icon (GtkIconTheme *theme, const gchar *uri, const gchar *mime_type, int size) { +#ifndef USE_STABLE_LIBGNOMEUI gchar *icon; - gchar *filename; - const GnomeIconData *icon_data; GdkPixbuf *pixbuf; icon = gnome_icon_lookup (theme, NULL, uri, NULL, NULL, mime_type, 0, NULL); - g_return_val_if_fail (icon != NULL, NULL); - filename = gnome_icon_theme_lookup_icon (theme, icon, - size, - &icon_data, - NULL); + pixbuf = gtk_icon_theme_load_icon (theme, icon, size, 0, NULL); g_free (icon); - if (filename == NULL) { - return NULL; - } - - pixbuf = load_icon_file (filename, size); - g_free (filename); - - return pixbuf; +#endif + return NULL; } -#endif /* !USE_STABLE_LIBGNOMEUI */ gchar * egg_recent_util_get_unique_id (void) diff --git a/cut-n-paste/recent-files/egg-recent-util.h b/cut-n-paste/recent-files/egg-recent-util.h index ae8a641..82c4a71 100644 --- a/cut-n-paste/recent-files/egg-recent-util.h +++ b/cut-n-paste/recent-files/egg-recent-util.h @@ -3,20 +3,15 @@ #define __EGG_RECENT_UTIL__ #include -#ifndef USE_STABLE_LIBGNOMEUI -#include -#endif G_BEGIN_DECLS gchar * egg_recent_util_escape_underlines (const gchar *uri); gchar * egg_recent_util_get_unique_id (void); -#ifndef USE_STABLE_LIBGNOMEUI -GdkPixbuf * egg_recent_util_get_icon (GnomeIconTheme *theme, +GdkPixbuf * egg_recent_util_get_icon (GtkIconTheme *theme, const gchar *uri, const gchar *mime_type, int size); -#endif G_END_DECLS diff --git a/cut-n-paste/recent-files/egg-recent-view-uimanager.c b/cut-n-paste/recent-files/egg-recent-view-uimanager.c index ac0b852..006112b 100644 --- a/cut-n-paste/recent-files/egg-recent-view-uimanager.c +++ b/cut-n-paste/recent-files/egg-recent-view-uimanager.c @@ -1,6 +1,6 @@ /* -*- 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 @@ -43,7 +43,14 @@ #define EGG_RECENT_ACTION "EggRecentFile" #define EGG_RECENT_SEPARATOR (NULL) -#define LABEL_WIDTH_CHARS 32 +#ifndef EGG_COMPILATION +#include +#else +#define _(x) (x) +#define N_(x) (x) +#endif + +#define DEFAULT_LABEL_WIDTH_CHARS 30 struct _EggRecentViewUIManager { GObject parent_instance; @@ -73,6 +80,8 @@ struct _EggRecentViewUIManager { EggRecentModel *model; GConfClient *client; GtkIconSize icon_size; + + gint label_width; }; @@ -94,12 +103,30 @@ enum { PROP_UIMANAGER, PROP_PATH, PROP_SHOW_ICONS, - PROP_SHOW_NUMBERS + PROP_SHOW_NUMBERS, + PROP_LABEL_WIDTH }; static guint view_signals[LAST_SIGNAL] = { 0 }; static void +connect_proxy_cb (GtkActionGroup *action_group, + GtkAction *action, + GtkWidget *proxy, + EggRecentViewUIManager *view) +{ + if (GTK_IS_MENU_ITEM (proxy)) + { + GtkWidget *label; + + label = GTK_BIN (proxy)->child; + + gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END); + gtk_label_set_max_width_chars (GTK_LABEL (label), view->label_width); + } +} + +static void egg_recent_view_uimanager_clear (EggRecentViewUIManager *view) { if (view->merge_id != 0) { @@ -117,23 +144,6 @@ egg_recent_view_uimanager_clear (EggRecentViewUIManager *view) } static void -connect_proxy_cb (GtkActionGroup *action_group, - GtkAction *action, - GtkWidget *proxy) -{ - if (GTK_IS_MENU_ITEM (proxy)) - { - GtkLabel *label; - - label = (GtkLabel *) ((GtkBin *) proxy)->child; - - gtk_label_set_ellipsize (label, PANGO_ELLIPSIZE_END); - gtk_label_set_max_width_chars (label, LABEL_WIDTH_CHARS); - } -} - - -static void egg_recent_view_uimanager_set_list (EggRecentViewUIManager *view, GList *list) { GList *scan; @@ -152,7 +162,8 @@ egg_recent_view_uimanager_set_list (EggRecentViewUIManager *view, GList *list) view->action_group = gtk_action_group_new (group); g_signal_connect (view->action_group, "connect-proxy", G_CALLBACK (connect_proxy_cb), view); - gtk_ui_manager_insert_action_group (view->uimanager, view->action_group, -1); + gtk_ui_manager_insert_action_group (view->uimanager, + view->action_group, -1); g_free (group); } @@ -190,7 +201,10 @@ egg_recent_view_uimanager_set_list (EggRecentViewUIManager *view, GList *list) if (view->tooltip_func != NULL) tooltip = (*view->tooltip_func) (item, view->tooltip_func_data); - basename = g_path_get_basename (uri); + if (!tooltip) + tooltip = g_strdup_printf (_("Open '%s'"), uri); + + basename = egg_recent_item_get_short_name (item); escaped = egg_recent_util_escape_underlines (basename); g_free (basename); g_free (uri); @@ -260,6 +274,84 @@ egg_recent_view_uimanager_set_list (EggRecentViewUIManager *view, GList *list) } static void +egg_recent_view_uimanager_set_empty_list (EggRecentViewUIManager *view) +{ + gboolean is_embedded; + + g_return_if_fail (view); + + egg_recent_view_uimanager_clear (view); + + if (view->merge_id == 0) + view->merge_id = gtk_ui_manager_new_merge_id (view->uimanager); + + if (view->action_group == NULL) { + gchar *group = g_strdup_printf ("EggRecentActions%u", + view->merge_id); + view->action_group = gtk_action_group_new (group); + g_signal_connect (view->action_group, "connect-proxy", + G_CALLBACK (connect_proxy_cb), view); + gtk_ui_manager_insert_action_group (view->uimanager, + view->action_group, -1); + g_free (group); + } + + if (view->leading_sep) { + gchar *sep_action = g_strdup_printf ("EggRecentLeadingSeparator%u", + view->merge_id); + gtk_ui_manager_add_ui (view->uimanager, + view->merge_id, + view->path, + sep_action, + EGG_RECENT_SEPARATOR, + GTK_UI_MANAGER_AUTO, + FALSE); + g_free (sep_action); + } + + is_embedded = (view->leading_sep && view->trailing_sep); + + if (is_embedded) { + GtkAction *action; + gchar *name; + + name = g_strdup_printf (EGG_RECENT_NAME_PREFIX "%u-0", view->merge_id); + + action = g_object_new (GTK_TYPE_ACTION, + "name", name, + "label", _("Empty"), + "sensitive", FALSE, + NULL); + + gtk_action_group_add_action (view->action_group, action); + g_object_unref (action); + + gtk_ui_manager_add_ui (view->uimanager, + view->merge_id, + view->path, + name, + name, + GTK_UI_MANAGER_AUTO, + FALSE); + + g_free (name); + } + + if (view->trailing_sep) { + gchar *sep_action = g_strdup_printf ("EggRecentTrailingSeparator%u", + view->merge_id); + gtk_ui_manager_add_ui (view->uimanager, + view->merge_id, + view->path, + sep_action, + EGG_RECENT_SEPARATOR, + GTK_UI_MANAGER_AUTO, + FALSE); + g_free (sep_action); + } +} + +static void model_changed_cb (EggRecentModel *model, GList *list, EggRecentViewUIManager *view) @@ -267,7 +359,8 @@ model_changed_cb (EggRecentModel *model, if (list != NULL) egg_recent_view_uimanager_set_list (view, list); else - egg_recent_view_uimanager_clear (view); + egg_recent_view_uimanager_set_empty_list (view); + gtk_ui_manager_ensure_update (view->uimanager); } @@ -349,6 +442,9 @@ egg_recent_view_uimanager_set_property (GObject *object, case PROP_SHOW_NUMBERS: egg_recent_view_uimanager_show_numbers (view, g_value_get_boolean (value)); break; + case PROP_LABEL_WIDTH: + egg_recent_view_uimanager_set_label_width (view, g_value_get_int (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -376,6 +472,9 @@ egg_recent_view_uimanager_get_property (GObject *object, case PROP_SHOW_NUMBERS: g_value_set_boolean (value, view->show_numbers); break; + case PROP_LABEL_WIDTH: + g_value_set_int (value, view->label_width); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -474,6 +573,16 @@ egg_recent_view_uimanager_class_init (EggRecentViewUIManagerClass * klass) "Whether or not to show numbers", TRUE, G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_LABEL_WIDTH, + g_param_spec_int ("label-width", + "Label Width", + "The desired width of the menu label, in characters", + -1, + G_MAXINT, + DEFAULT_LABEL_WIDTH_CHARS, + G_PARAM_READWRITE)); + klass->activate = NULL; } @@ -549,6 +658,7 @@ egg_recent_view_uimanager_init (EggRecentViewUIManager * view) view->tooltip_func_data = NULL; view->icon_size = GTK_ICON_SIZE_MENU; + view->label_width = DEFAULT_LABEL_WIDTH_CHARS; } void @@ -664,6 +774,21 @@ egg_recent_view_uimanager_get_path (EggRecentViewUIManager *view) } void +egg_recent_view_uimanager_set_label_width (EggRecentViewUIManager *view, + gint chars) +{ + g_return_if_fail (EGG_IS_RECENT_VIEW_UIMANAGER (view)); + view->label_width = chars; +} + +gint +egg_recent_view_uimanager_get_label_width (EggRecentViewUIManager *view) +{ + g_return_val_if_fail (EGG_IS_RECENT_VIEW_UIMANAGER (view), DEFAULT_LABEL_WIDTH_CHARS); + return view->label_width; +} + +void egg_recent_view_uimanager_set_action_func (EggRecentViewUIManager *view, GCallback callback, gpointer user_data) @@ -707,14 +832,6 @@ egg_recent_view_uimanager_new (GtkUIManager *uimanager, return EGG_RECENT_VIEW_UIMANAGER (view); } -/** - * egg_recent_view_uimanager_get_type: - * @: - * - * This returns a GType representing a EggRecentViewUIManager object. - * - * Returns: a GType - */ GType egg_recent_view_uimanager_get_type (void) { diff --git a/cut-n-paste/recent-files/egg-recent-view-uimanager.h b/cut-n-paste/recent-files/egg-recent-view-uimanager.h index b6eadfa..8aed413 100644 --- a/cut-n-paste/recent-files/egg-recent-view-uimanager.h +++ b/cut-n-paste/recent-files/egg-recent-view-uimanager.h @@ -53,6 +53,9 @@ void egg_recent_view_uimanager_set_icon_size (EggRecentVie GtkIconSize egg_recent_view_uimanager_get_icon_size (EggRecentViewUIManager *view); EggRecentItem *egg_recent_view_uimanager_get_item (EggRecentViewUIManager *view, GtkAction *action); +void egg_recent_view_uimanager_set_label_width (EggRecentViewUIManager *view, + gint chars); +gint egg_recent_view_uimanager_get_label_width (EggRecentViewUIManager *view); G_END_DECLS -- cgit v0.9.1