Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/cut-n-paste
diff options
context:
space:
mode:
Diffstat (limited to 'cut-n-paste')
-rw-r--r--cut-n-paste/recent-files/egg-recent-item.c173
-rw-r--r--cut-n-paste/recent-files/egg-recent-model.c380
-rw-r--r--cut-n-paste/recent-files/egg-recent-util.c63
-rw-r--r--cut-n-paste/recent-files/egg-recent-util.h7
-rw-r--r--cut-n-paste/recent-files/egg-recent-view-uimanager.c179
-rw-r--r--cut-n-paste/recent-files/egg-recent-view-uimanager.h3
6 files changed, 499 insertions, 306 deletions
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 <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>
@@ -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 <stdio.h>
#include <string.h>
#include <gtk/gtk.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/types.h>
#ifndef USE_STABLE_LIBGNOMEUI
-#include <libgnomeui/gnome-icon-theme.h>
#include <libgnomeui/gnome-icon-lookup.h>
#endif
+#include <time.h>
+#include <unistd.h>
+#include <sys/types.h>
#include <math.h>
#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 <gtk/gtk.h>
-#ifndef USE_STABLE_LIBGNOMEUI
-#include <libgnomeui/gnome-icon-theme.h>
-#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 <glib/gi18n.h>
+#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