diff options
Diffstat (limited to 'libslab/bookmark-agent.c')
-rw-r--r-- | libslab/bookmark-agent.c | 1244 |
1 files changed, 0 insertions, 1244 deletions
diff --git a/libslab/bookmark-agent.c b/libslab/bookmark-agent.c deleted file mode 100644 index 0f5f1bee..00000000 --- a/libslab/bookmark-agent.c +++ /dev/null @@ -1,1244 +0,0 @@ -/* - * This file is part of the Main Menu. - * - * Copyright (c) 2007 Novell, Inc. - * - * The Main Menu 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. - * - * The Main Menu 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 - * the Main Menu; if not, write to the Free Software Foundation, Inc., 51 - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "bookmark-agent.h" - -#ifdef HAVE_CONFIG_H -# include <config.h> -#else -# define PACKAGE "mate-main-menu" -#endif - -#include <gtk/gtk.h> - -#include <string.h> -#include <stdlib.h> -#include <glib/gi18n-lib.h> -#include <glib/gstdio.h> -#include <gio/gio.h> - -#include "libslab-utils.h" - -#define USER_APPS_STORE_FILE_NAME "applications.xbel" -#define USER_DOCS_STORE_FILE_NAME "documents.xbel" -#define USER_DIRS_STORE_FILE_NAME "places.xbel" -#define SYSTEM_STORE_FILE_NAME "system-items.xbel" -#define CALC_TEMPLATE_FILE_NAME "empty.ots" -#define WRITER_TEMPLATE_FILE_NAME "empty.ott" - -#define GTK_BOOKMARKS_FILE "bookmarks" - -#define TYPE_IS_RECENT(type) ((type) == BOOKMARK_STORE_RECENT_APPS || (type) == BOOKMARK_STORE_RECENT_DOCS) - -typedef struct { - BookmarkStoreType type; - - BookmarkItem **items; - gint n_items; - BookmarkStoreStatus status; - - GBookmarkFile *store; - gboolean needs_sync; - - gchar *store_path; - gchar *user_store_path; - gboolean user_modifiable; - gboolean reorderable; - const gchar *store_filename; - - GFileMonitor *store_monitor; - GFileMonitor *user_store_monitor; - - void (* update_path) (BookmarkAgent *); - void (* load_store) (BookmarkAgent *); - void (* save_store) (BookmarkAgent *); - void (* create_item) (BookmarkAgent *, const gchar *); - - gchar *gtk_store_path; - GFileMonitor *gtk_store_monitor; -} BookmarkAgentPrivate; - -enum { - PROP_0, - PROP_ITEMS, - PROP_STATUS -}; - -static BookmarkAgent *instances [BOOKMARK_STORE_N_TYPES]; - -static BookmarkAgentClass *bookmark_agent_parent_class = NULL; - -static void bookmark_agent_base_init (BookmarkAgentClass *); -static void bookmark_agent_class_init (BookmarkAgentClass *); -static void bookmark_agent_init (BookmarkAgent *); -static BookmarkAgent *bookmark_agent_new (BookmarkStoreType ); - -static void get_property (GObject *, guint, GValue *, GParamSpec *); -static void set_property (GObject *, guint, const GValue *, GParamSpec *); -static void finalize (GObject *); - -static void update_agent (BookmarkAgent *); -static void update_items (BookmarkAgent *); -static void save_store (BookmarkAgent *); -static gint get_rank (BookmarkAgent *, const gchar *); -static void set_rank (BookmarkAgent *, const gchar *, gint); - -static void load_xbel_store (BookmarkAgent *); -static void load_places_store (BookmarkAgent *); -static void update_user_spec_path (BookmarkAgent *); -static void save_xbel_store (BookmarkAgent *); -static void create_app_item (BookmarkAgent *, const gchar *); -static void create_doc_item (BookmarkAgent *, const gchar *); -static void create_dir_item (BookmarkAgent *, const gchar *); - -static void store_monitor_cb (GFileMonitor *, GFile *, GFile *, - GFileMonitorEvent, gpointer); -static void weak_destroy_cb (gpointer, GObject *); - -static gchar *find_package_data_file (const gchar *filename); - -static gint BookmarkAgent_private_offset; - -static inline gpointer bookmark_agent_get_instance_private (BookmarkAgent *this) -{ - return (G_STRUCT_MEMBER_P (this, BookmarkAgent_private_offset)); -} - -GType -bookmark_agent_get_type () -{ - static GType g_define_type_id = 0; - - if (G_UNLIKELY (g_define_type_id == 0)) { - static const GTypeInfo info = { - sizeof (BookmarkAgentClass), - (GBaseInitFunc) bookmark_agent_base_init, - NULL, - (GClassInitFunc) bookmark_agent_class_init, - NULL, NULL, - sizeof (BookmarkAgent), 0, - (GInstanceInitFunc) bookmark_agent_init, - NULL - }; - - g_define_type_id = g_type_register_static ( - G_TYPE_OBJECT, "BookmarkAgent", & info, 0); - G_ADD_PRIVATE (BookmarkAgent); - } - - return g_define_type_id; -} - -gboolean -bookmark_agent_has_item (BookmarkAgent *this, const gchar *uri) -{ - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - return g_bookmark_file_has_item (priv->store, uri); -} - -void -bookmark_agent_add_item (BookmarkAgent *this, const BookmarkItem *item) -{ - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - - if (! item) - return; - - g_return_if_fail (priv->user_modifiable); - g_return_if_fail (item->uri); - g_return_if_fail (item->mime_type); - - g_bookmark_file_set_mime_type (priv->store, item->uri, item->mime_type); - - if (item->mtime) -#if GLIB_CHECK_VERSION(2,66,0) - g_bookmark_file_set_modified_date_time (priv->store, item->uri, item->mtime); -#else - g_bookmark_file_set_modified (priv->store, item->uri, item->mtime); -#endif - - if (item->title) - g_bookmark_file_set_title (priv->store, item->uri, item->title); - - g_bookmark_file_add_application (priv->store, item->uri, item->app_name, item->app_exec); - - set_rank (this, item->uri, g_bookmark_file_get_size (priv->store) - 1); - - save_store (this); -} - -void -bookmark_agent_move_item (BookmarkAgent *this, const gchar *uri, const gchar *uri_new) -{ - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - - GError *error = NULL; - - if (! TYPE_IS_RECENT (priv->type)) - return; - - gtk_recent_manager_move_item (gtk_recent_manager_get_default (), uri, uri_new, &error); - if (error) { - g_warning ("Unable to update %s with renamed file, [%s] -> [%s]: %s", - priv->store_path, uri, uri_new, error->message); - g_error_free (error); - } -} - -void -bookmark_agent_purge_items (BookmarkAgent *this) -{ - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - - GError *error = NULL; - - gchar **uris = NULL; - gsize uris_len; - gint i; - g_return_if_fail (priv->user_modifiable); - - uris = g_bookmark_file_get_uris (priv->store, &uris_len); - if (TYPE_IS_RECENT (priv->type)) { - for (i = 0; i < uris_len; i++) { - gtk_recent_manager_remove_item (gtk_recent_manager_get_default (), uris [i], &error); - if (error) { - g_warning ("Unable to remove [%s] from %s: %s", - priv->store_path, uris [i], error->message); - g_error_free (error); - } - } - } else { - for (i = 0; i < uris_len; i++) { - g_bookmark_file_remove_item (priv->store, uris [i], NULL); - } - save_store (this); - } - g_strfreev (uris); -} - -void -bookmark_agent_remove_item (BookmarkAgent *this, const gchar *uri) -{ - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - gint rank; - - GError *error = NULL; - - gchar **uris = NULL; - gint rank_i; - gint i; - - g_return_if_fail (priv->user_modifiable); - - if (! bookmark_agent_has_item (this, uri)) - return; - - if (TYPE_IS_RECENT (priv->type)) { - gtk_recent_manager_remove_item (gtk_recent_manager_get_default (), uri, &error); - if (error) { - g_warning ("Unable to remove [%s] from %s: %s", priv->store_path, uri, error->message); - g_error_free (error); - } - } - else { - rank = get_rank (this, uri); - - g_bookmark_file_remove_item (priv->store, uri, NULL); - - if (rank >= 0) { - uris = g_bookmark_file_get_uris (priv->store, NULL); - - for (i = 0; uris && uris [i]; ++i) { - rank_i = get_rank (this, uris [i]); - - if (rank_i > rank) - set_rank (this, uris [i], rank_i - 1); - } - - g_strfreev (uris); - } - - save_store (this); - } -} - -void -bookmark_agent_reorder_items (BookmarkAgent *this, const gchar **uris) -{ - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - - gint i; - - g_return_if_fail (priv->reorderable); - - for (i = 0; uris && uris [i]; ++i) - set_rank (this, uris [i], i); - - save_store (this); -} - -#if !GLIB_CHECK_VERSION(2,66,0) -static gint -recent_item_mru_comp_func (gconstpointer a, gconstpointer b) -{ - return ((BookmarkItem *) b)->mtime - ((BookmarkItem *) a)->mtime; -} -#endif - -static GList * -make_items_from_bookmark_file (BookmarkAgent *this, GBookmarkFile *store) -{ - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - gchar **uris; - gint i; - GList *items_ordered; - - if (!store) - return NULL; - - uris = g_bookmark_file_get_uris (store, NULL); - items_ordered = NULL; - - for (i = 0; uris && uris [i]; ++i) { - gboolean include; - - if (priv->type == BOOKMARK_STORE_RECENT_APPS) - include = g_bookmark_file_has_group (store, uris [i], "recently-used-apps", NULL); - else - include = ! g_bookmark_file_get_is_private (store, uris [i], NULL); - - if (include) { - BookmarkItem *item; - - item = g_new0 (BookmarkItem, 1); - - item->uri = g_strdup (uris [i]); - item->mime_type = g_bookmark_file_get_mime_type (store, uris [i], NULL); -#if GLIB_CHECK_VERSION(2,66,0) - item->mtime = g_bookmark_file_get_modified_date_time (store, uris [i], NULL); -#else - item->mtime = g_bookmark_file_get_modified (store, uris [i], NULL); -#endif - - items_ordered = g_list_prepend (items_ordered, item); - } - } - -#if GLIB_CHECK_VERSION(2,66,0) - items_ordered = g_list_sort (items_ordered, g_date_time_compare); -#else - items_ordered = g_list_sort (items_ordered, recent_item_mru_comp_func); -#endif - g_strfreev (uris); - - return items_ordered; -} - -void -bookmark_agent_update_from_bookmark_file (BookmarkAgent *this, GBookmarkFile *store) -{ - BookmarkAgentPrivate *priv; - GList *items_ordered; - GList *node; - - g_return_if_fail (IS_BOOKMARK_AGENT (this)); - - priv = bookmark_agent_get_instance_private (this); - - items_ordered = make_items_from_bookmark_file (this, store); - - g_bookmark_file_free (priv->store); - priv->store = g_bookmark_file_new (); - - for (node = items_ordered; node; node = node->next) { - BookmarkItem *item; - - item = (BookmarkItem *) node->data; - - g_bookmark_file_set_mime_type (priv->store, item->uri, item->mime_type); - #if GLIB_CHECK_VERSION(2,66,0) - g_bookmark_file_set_modified_date_time (priv->store, item->uri, item->mtime); - #else - g_bookmark_file_set_modified (priv->store, item->uri, item->mtime); - #endif - - bookmark_item_free (item); - } - - g_list_free (items_ordered); - - update_items (this); -} - -void -bookmark_item_free (BookmarkItem *item) -{ - if (! item) - return; - - g_free (item->uri); - g_free (item->title); - g_free (item->mime_type); - g_free (item->icon); - g_free (item->app_name); - g_free (item->app_exec); - g_free (item); -} - -static void -bookmark_agent_base_init (BookmarkAgentClass *this_class) -{ - gint i; - - for (i = 0; i < BOOKMARK_STORE_N_TYPES; ++i) - instances [i] = NULL; -} - -static void -bookmark_agent_class_init (BookmarkAgentClass *this_class) -{ - GObjectClass *g_obj_class = G_OBJECT_CLASS (this_class); - - GParamSpec *items_pspec; - GParamSpec *status_pspec; - - if (BookmarkAgent_private_offset != 0) - g_type_class_adjust_private_offset (this_class, &BookmarkAgent_private_offset); - - g_obj_class->get_property = get_property; - g_obj_class->set_property = set_property; - g_obj_class->finalize = finalize; - - items_pspec = g_param_spec_pointer ( - BOOKMARK_AGENT_ITEMS_PROP, BOOKMARK_AGENT_ITEMS_PROP, - "the null-terminated list which contains the bookmark items in this store", - G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB); - - status_pspec = g_param_spec_int ( - BOOKMARK_AGENT_STORE_STATUS_PROP, BOOKMARK_AGENT_STORE_STATUS_PROP, "the status of the store", - BOOKMARK_STORE_DEFAULT_ONLY, BOOKMARK_STORE_USER, BOOKMARK_STORE_DEFAULT, - G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB); - - g_object_class_install_property (g_obj_class, PROP_ITEMS, items_pspec); - g_object_class_install_property (g_obj_class, PROP_STATUS, status_pspec); - - bookmark_agent_parent_class = g_type_class_peek_parent (this_class); -} - -static void -bookmark_agent_init (BookmarkAgent *this) -{ - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - - priv->type = -1; - - priv->items = NULL; - priv->n_items = 0; - priv->status = BOOKMARK_STORE_ABSENT; - - priv->store = NULL; - priv->needs_sync = FALSE; - - priv->store_path = NULL; - priv->user_store_path = NULL; - priv->user_modifiable = FALSE; - priv->reorderable = FALSE; - priv->store_filename = NULL; - - priv->store_monitor = NULL; - priv->user_store_monitor = NULL; - - priv->update_path = NULL; - priv->load_store = NULL; - priv->save_store = NULL; - priv->create_item = NULL; - - priv->gtk_store_path = NULL; - priv->gtk_store_monitor = NULL; -} - -static BookmarkAgent * -bookmark_agent_new (BookmarkStoreType type) -{ - BookmarkAgent *this; - BookmarkAgentPrivate *priv; - GFile *gtk_store_file; - - this = g_object_new (BOOKMARK_AGENT_TYPE, NULL); - priv = bookmark_agent_get_instance_private (this); - - priv->type = type; - priv->store = g_bookmark_file_new (); - - switch (type) { - case BOOKMARK_STORE_USER_APPS: - priv->store_filename = USER_APPS_STORE_FILE_NAME; - priv->create_item = create_app_item; - - break; - - case BOOKMARK_STORE_USER_DOCS: - priv->store_filename = USER_DOCS_STORE_FILE_NAME; - priv->create_item = create_doc_item; - - break; - - case BOOKMARK_STORE_USER_DIRS: - priv->store_filename = USER_DIRS_STORE_FILE_NAME; - priv->create_item = create_dir_item; - - priv->user_modifiable = TRUE; - priv->reorderable = FALSE; - - priv->load_store = load_places_store; - - priv->gtk_store_path = g_build_filename (g_get_user_config_dir (), - "gtk-3.0", GTK_BOOKMARKS_FILE, NULL); - gtk_store_file = g_file_new_for_path (priv->gtk_store_path); - priv->gtk_store_monitor = g_file_monitor_file (gtk_store_file, - 0, NULL, NULL); - if (priv->gtk_store_monitor) { - g_signal_connect (priv->gtk_store_monitor, "changed", - G_CALLBACK (store_monitor_cb), this); - } - - g_object_unref (gtk_store_file); - - break; - - case BOOKMARK_STORE_RECENT_APPS: - case BOOKMARK_STORE_RECENT_DOCS: - priv->user_modifiable = TRUE; - priv->reorderable = FALSE; - - priv->store_path = g_build_filename (g_get_user_data_dir (), "recently-used.xbel", NULL); - - break; - - case BOOKMARK_STORE_SYSTEM: - priv->store_filename = SYSTEM_STORE_FILE_NAME; - priv->create_item = create_app_item; - - break; - - default: - break; - } - - if ( - type == BOOKMARK_STORE_USER_APPS || type == BOOKMARK_STORE_USER_DOCS || - type == BOOKMARK_STORE_USER_DIRS || type == BOOKMARK_STORE_SYSTEM) - { - priv->user_modifiable = TRUE; - - priv->user_store_path = g_build_filename ( - g_get_user_data_dir (), PACKAGE, priv->store_filename, NULL); - - priv->update_path = update_user_spec_path; - } - - if (type == BOOKMARK_STORE_USER_APPS || type == BOOKMARK_STORE_USER_DOCS || type == BOOKMARK_STORE_SYSTEM) { - priv->reorderable = TRUE; - priv->load_store = load_xbel_store; - priv->save_store = save_xbel_store; - } - - update_agent (this); - - return this; -} - -BookmarkAgent * -bookmark_agent_get_instance (BookmarkStoreType type) -{ - g_return_val_if_fail (0 <= type, NULL); - g_return_val_if_fail (type < BOOKMARK_STORE_N_TYPES, NULL); - - if (! instances [type]) { - instances [type] = bookmark_agent_new (type); - g_object_weak_ref (G_OBJECT (instances [type]), weak_destroy_cb, GINT_TO_POINTER (type)); - } - else - g_object_ref (G_OBJECT (instances [type])); - - return instances [type]; -} - -static void -get_property (GObject *g_obj, guint prop_id, GValue *value, GParamSpec *pspec) -{ - BookmarkAgent *this = BOOKMARK_AGENT (g_obj); - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - - switch (prop_id) { - case PROP_ITEMS: - g_value_set_pointer (value, priv->items); - break; - - case PROP_STATUS: - g_value_set_int (value, priv->status); - break; - } -} - -static void -set_property (GObject *g_obj, guint prop_id, const GValue *value, GParamSpec *pspec) -{ - /* no writeable properties */ -} - -static void -finalize (GObject *g_obj) -{ - BookmarkAgent *this = BOOKMARK_AGENT (g_obj); - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - - gint i; - - for (i = 0; priv->items && priv->items [i]; ++i) - bookmark_item_free (priv->items [i]); - - g_free (priv->items); - g_free (priv->store_path); - g_free (priv->user_store_path); - g_free (priv->gtk_store_path); - - if (priv->store_monitor) { - g_signal_handlers_disconnect_by_func (priv->store_monitor, store_monitor_cb, this); - g_file_monitor_cancel (priv->store_monitor); - g_object_unref (priv->store_monitor); - } - - if (priv->user_store_monitor) { - g_signal_handlers_disconnect_by_func (priv->user_store_monitor, store_monitor_cb, this); - g_file_monitor_cancel (priv->user_store_monitor); - g_object_unref (priv->user_store_monitor); - } - - if (priv->gtk_store_monitor) { - g_signal_handlers_disconnect_by_func (priv->gtk_store_monitor, store_monitor_cb, this); - g_file_monitor_cancel (priv->gtk_store_monitor); - g_object_unref (priv->gtk_store_monitor); - } - - g_bookmark_file_free (priv->store); - - G_OBJECT_CLASS (bookmark_agent_parent_class)->finalize (g_obj); -} - -static void -update_agent (BookmarkAgent *this) -{ - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - - if (priv->update_path) - priv->update_path (this); - - if (priv->load_store) - priv->load_store (this); - - update_items (this); -} - -static void -update_items (BookmarkAgent *this) -{ - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - - gchar **uris = NULL; - gchar **uris_ordered = NULL; - gsize n_uris = 0; - gint rank = -1; - gint rank_corr = -1; - gboolean needs_update = FALSE; - gboolean store_corrupted = FALSE; - gchar *new_title, *old_title; - - gint i; - - uris = g_bookmark_file_get_uris (priv->store, & n_uris); - uris_ordered = g_new0 (gchar *, n_uris + 1); - uris_ordered [n_uris] = NULL; - - for (i = 0; uris && uris [i]; ++i) { - rank = get_rank (this, uris [i]); - - if (rank < 0 || rank >= n_uris) - rank = i; - - if (uris_ordered [rank]) { - store_corrupted = TRUE; - rank_corr = rank; - - for (rank = 0; rank < n_uris; ++rank) - if (! uris_ordered [rank]) - break; - - g_warning ( - "store corruption [%s] - multiple uris with same rank (%d): [%s] [%s], moving latter to %d", - priv->store_path, rank_corr, uris_ordered [rank_corr], uris [i], rank); - } - - set_rank (this, uris [i], rank); - - uris_ordered [rank] = uris [i]; - } - - if (priv->n_items != n_uris) - needs_update = TRUE; - - for (i = 0; ! needs_update && uris_ordered && uris_ordered [i]; ++i) { - if (priv->type == BOOKMARK_STORE_USER_DIRS) { - new_title = g_bookmark_file_get_title (priv->store, uris_ordered [i], NULL); - old_title = priv->items [i]->title; - if (!new_title && !old_title) { - if (strcmp (priv->items [i]->uri, uris_ordered [i])) - needs_update = TRUE; - } - else if ((new_title && !old_title) || (!new_title && old_title)) - needs_update = TRUE; - else if (strcmp (old_title, new_title)) - needs_update = TRUE; - g_free (new_title); - } - else if (strcmp (priv->items [i]->uri, uris_ordered [i])) - needs_update = TRUE; - } - - if (needs_update) { - for (i = 0; priv->items && priv->items [i]; ++i) - bookmark_item_free (priv->items [i]); - - g_free (priv->items); - - priv->n_items = n_uris; - priv->items = g_new0 (BookmarkItem *, priv->n_items + 1); - - for (i = 0; uris_ordered && uris_ordered [i]; ++i) { - priv->items [i] = g_new0 (BookmarkItem, 1); - priv->items [i]->uri = g_strdup (uris_ordered [i]); - priv->items [i]->title = g_bookmark_file_get_title (priv->store, uris_ordered [i], NULL); - priv->items [i]->mime_type = g_bookmark_file_get_mime_type (priv->store, uris_ordered [i], NULL); - #if GLIB_CHECK_VERSION(2,66,0) - priv->items [i]->mtime = g_bookmark_file_get_modified_date_time (priv->store, uris_ordered [i], NULL); - #else - priv->items [i]->mtime = g_bookmark_file_get_modified (priv->store, uris_ordered [i], NULL); - #endif - priv->items [i]->app_name = NULL; - priv->items [i]->app_exec = NULL; - - g_bookmark_file_get_icon (priv->store, uris_ordered [i], & priv->items [i]->icon, NULL, NULL); - } - - /* Since the bookmark store for recently-used items is updated by the caller of BookmarkAgent, - * we don't emit notifications in that case. The caller will know when to update itself. - */ - if (!TYPE_IS_RECENT (priv->type)) - g_object_notify (G_OBJECT (this), BOOKMARK_AGENT_ITEMS_PROP); - } - - if (store_corrupted) - save_store (this); - - g_strfreev (uris); - g_free (uris_ordered); -} - -static void -save_store (BookmarkAgent *this) -{ - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - - gchar *dir; - - g_return_if_fail (priv->user_modifiable); - - priv->needs_sync = TRUE; - priv->update_path (this); - - dir = g_path_get_dirname (priv->store_path); - g_mkdir_with_parents (dir, 0700); - g_free (dir); - - priv->save_store (this); - update_items (this); -} - -static gint -get_rank (BookmarkAgent *this, const gchar *uri) -{ - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - - gchar **groups; - gint rank; - - gint i; - - if (! priv->reorderable) - return -1; - - groups = g_bookmark_file_get_groups (priv->store, uri, NULL, NULL); - rank = -1; - - for (i = 0; groups && groups [i]; ++i) { - if (g_str_has_prefix (groups [i], "rank-")) { - if (rank >= 0) - g_warning ( - "store corruption - multiple ranks for same uri: [%s] [%s]", - priv->store_path, uri); - - rank = atoi (& groups [i] [5]); - } - } - - g_strfreev (groups); - - return rank; -} - -static void -set_rank (BookmarkAgent *this, const gchar *uri, gint rank) -{ - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - - gchar **groups; - gchar *group; - - gint i; - - if (! (priv->reorderable && bookmark_agent_has_item (this, uri))) - return; - - groups = g_bookmark_file_get_groups (priv->store, uri, NULL, NULL); - - for (i = 0; groups && groups [i]; ++i) - if (g_str_has_prefix (groups [i], "rank-")) - g_bookmark_file_remove_group (priv->store, uri, groups [i], NULL); - - g_strfreev (groups); - - group = g_strdup_printf ("rank-%d", rank); - g_bookmark_file_add_group (priv->store, uri, group); - g_free (group); -} - -static void -load_xbel_store (BookmarkAgent *this) -{ - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - - gchar **uris = NULL; - - GError *error = NULL; - - gint i; - gboolean success; - - if (!priv->store_path) - success = FALSE; - else { - success = g_bookmark_file_load_from_file (priv->store, priv->store_path, & error); - } - - if (!success) { - g_bookmark_file_free (priv->store); - priv->store = g_bookmark_file_new (); - - if (error) { - g_debug ("Couldn't load bookmark file [%s]: %s", priv->store_path, error->message); - g_error_free (error); - } else { - g_debug ("Couldn't load bookmark file [NULL]"); - } - return; - } - - uris = g_bookmark_file_get_uris (priv->store, NULL); - - for (i = 0; uris && uris [i]; ++i) - priv->create_item (this, uris [i]); - - g_strfreev (uris); -} - -static void -load_places_store (BookmarkAgent *this) -{ - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - - gchar **uris; - gchar **groups; - gchar **bookmarks = NULL; - - gchar *buf, *label, *uri; - - gint i, j, bookmark_len; - - load_xbel_store (this); - - uris = g_bookmark_file_get_uris (priv->store, NULL); - - for (i = 0; uris && uris [i]; ++i) { - groups = g_bookmark_file_get_groups (priv->store, uris [i], NULL, NULL); - - for (j = 0; groups && groups [j]; ++j) { - if (! strcmp (groups [j], "gtk-bookmarks")) { - g_bookmark_file_remove_item (priv->store, uris [i], NULL); - - break; - } - } - - g_strfreev (groups); - } - - g_strfreev (uris); - - g_file_get_contents (priv->gtk_store_path, & buf, NULL, NULL); - - if (buf) { - bookmarks = g_strsplit (buf, "\n", -1); - g_free (buf); - } - - for (i = 0; bookmarks && bookmarks [i]; ++i) { - bookmark_len = strlen (bookmarks [i]); - if (bookmark_len > 0) { - label = strstr (bookmarks[i], " "); - if (label != NULL) - uri = g_strndup (bookmarks [i], bookmark_len - strlen (label)); - else - uri = bookmarks [i]; - g_bookmark_file_add_group (priv->store, uri, "gtk-bookmarks"); - priv->create_item (this, uri); - if (label != NULL) { - label++; - if (strlen (label) > 0) - g_bookmark_file_set_title (priv->store, uri, label); - g_free (uri); - } - } - } - - g_strfreev (bookmarks); -} - -static gchar * -find_package_data_file (const gchar *filename) -{ - const gchar * const *dirs = NULL; - gchar *path = NULL; - gint i; - - dirs = g_get_system_data_dirs (); - - for (i = 0; ! path && dirs && dirs [i]; ++i) { - path = g_build_filename (dirs [i], PACKAGE, filename, NULL); - - if (! g_file_test (path, G_FILE_TEST_EXISTS)) { - g_free (path); - path = NULL; - } - } - - return path; -} - -static void -update_user_spec_path (BookmarkAgent *this) -{ - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - - gboolean use_user_path; - gchar *path = NULL; - - BookmarkStoreStatus status; - - use_user_path = priv->user_modifiable && - (priv->needs_sync || g_file_test (priv->user_store_path, G_FILE_TEST_EXISTS)); - - if (use_user_path) - path = g_strdup (priv->user_store_path); - else - path = find_package_data_file (priv->store_filename); - - if (use_user_path) - status = BOOKMARK_STORE_USER; - else if (path && priv->user_modifiable) - status = BOOKMARK_STORE_DEFAULT; - else if (path) - status = BOOKMARK_STORE_DEFAULT_ONLY; - else - status = BOOKMARK_STORE_ABSENT; - - if (priv->status != status) { - priv->status = status; - g_object_notify (G_OBJECT (this), BOOKMARK_AGENT_STORE_STATUS_PROP); - - if (priv->user_store_monitor) { - g_file_monitor_cancel (priv->user_store_monitor); - g_object_unref (priv->user_store_monitor); - priv->user_store_monitor = NULL; - } - - if (priv->status == BOOKMARK_STORE_DEFAULT) { - GFile *user_store_file; - - user_store_file = g_file_new_for_path (priv->user_store_path); - priv->user_store_monitor = g_file_monitor_file (user_store_file, - 0, NULL, NULL); - if (priv->user_store_monitor) { - g_signal_connect (priv->user_store_monitor, "changed", - G_CALLBACK (store_monitor_cb), this); - } - - g_object_unref (user_store_file); - } - } - - if (g_strcmp0 (priv->store_path, path)) { - g_free (priv->store_path); - priv->store_path = path; - - if (priv->store_monitor) { - g_file_monitor_cancel (priv->store_monitor); - g_object_unref (priv->store_monitor); - } - - if (priv->store_path) { - GFile *store_file; - - store_file = g_file_new_for_path (priv->store_path); - priv->store_monitor = g_file_monitor_file (store_file, - 0, NULL, NULL); - if (priv->store_monitor) { - g_signal_connect (priv->store_monitor, "changed", - G_CALLBACK (store_monitor_cb), this); - } - - g_object_unref (store_file); - } - } - else - g_free (path); -} - -static void -save_xbel_store (BookmarkAgent *this) -{ - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - - GError *error = NULL; - - if (g_bookmark_file_to_file (priv->store, priv->store_path, &error)) - return; - - if (error) { - g_warning ("Couldn't save bookmark file [%s]: %s", priv->store_path, error->message); - g_error_free (error); - } else { - g_warning ("Couldn't save bookmark file [%s]", priv->store_path); - } -} - -static void -create_app_item (BookmarkAgent *this, const gchar *uri) -{ - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - - MateDesktopItem *ditem; - gchar *uri_new = NULL; - - ditem = libslab_mate_desktop_item_new_from_unknown_id (uri); - - if (ditem) { - uri_new = g_strdup (mate_desktop_item_get_location (ditem)); - mate_desktop_item_unref (ditem); - } - - if (! uri_new) - return; - - if (g_strcmp0 (uri, uri_new)) - g_bookmark_file_move_item (priv->store, uri, uri_new, NULL); - - g_free (uri_new); -} - -static void -create_doc_item (BookmarkAgent *this, const gchar *uri) -{ - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - - gchar *uri_new = NULL; - - if ((strcmp (uri, "BLANK_SPREADSHEET") == 0) || (strcmp (uri, "BLANK_DOCUMENT") == 0)) { - gchar *template = NULL; - gchar *file; - - gchar *dir = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS)); - if (!dir) - dir = g_build_filename (g_get_home_dir (), "Documents", NULL); - - if (strcmp (uri, "BLANK_SPREADSHEET") == 0) { - g_bookmark_file_set_title (priv->store, uri, "BLANK_SPREADSHEET"); - file = g_strconcat (_("New Spreadsheet"), ".ots", NULL); - template = find_package_data_file (CALC_TEMPLATE_FILE_NAME); - } else { - g_bookmark_file_set_title (priv->store, uri, "BLANK_DOCUMENT"); - file = g_strconcat (_("New Document"), ".ott", NULL); - template = find_package_data_file (WRITER_TEMPLATE_FILE_NAME); - } - - gchar *path = g_build_filename (dir, file, NULL); - if (!g_file_test (path, G_FILE_TEST_EXISTS)) { - g_mkdir_with_parents (dir, 0700); - - if (template != NULL) { - gchar *contents; - gsize length; - - if (g_file_get_contents (template, &contents, &length, NULL)) - g_file_set_contents (path, contents, length, NULL); - - g_free (contents); - } else { - fclose (g_fopen (path, "w")); - } - } - - uri_new = g_filename_to_uri (path, NULL, NULL); - - g_free (dir); - g_free (file); - g_free (path); - g_free (template); - } - - if (!uri_new) - return; - - if (g_strcmp0 (uri, uri_new)) - g_bookmark_file_move_item (priv->store, uri, uri_new, NULL); - - g_free (uri_new); -} - -static void -create_dir_item (BookmarkAgent *this, const gchar *uri) -{ - BookmarkAgentPrivate *priv = bookmark_agent_get_instance_private (this); - - gchar *uri_new = NULL; - gchar *path = NULL; - gchar *name = NULL; - gchar *icon = NULL; - - gchar *search_string = NULL; - - gboolean gotta_free_name = FALSE; - - if (strcmp (uri, "HOME") == 0) { - uri_new = g_filename_to_uri (g_get_home_dir (), NULL, NULL); - name = g_strdup (C_("Home folder", "Home")); - gotta_free_name = TRUE; - icon = "user-home"; - } else if (strcmp (uri, "DOCUMENTS") == 0) { - path = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS)); - if (!path) - path = g_build_filename (g_get_home_dir (), "Documents", NULL); - name = _("Documents"); - uri_new = g_filename_to_uri (path, NULL, NULL); - } else if (strcmp (uri, "DESKTOP") == 0) { - path = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP)); - if (!path) - path = g_build_filename (g_get_home_dir (), "Desktop", NULL); - name = _("Desktop"); - uri_new = g_filename_to_uri (path, NULL, NULL); - icon = "user-desktop"; - } else if (strcmp (uri, "file:///") == 0) { - icon = "drive-harddisk"; - name = _("File System"); - } else if (strcmp (uri, "network:") == 0) { - icon = "network-workgroup"; - name = _("Network Servers"); - } else if (g_str_has_prefix (uri, "x-caja-search")) { - icon = "system-search"; - - path = g_build_filename (g_get_user_data_dir (), "caja", "searches", & uri [21], NULL); - - if (g_file_test (path, G_FILE_TEST_EXISTS)) { - gchar *buf = NULL; - g_file_get_contents (path, &buf, NULL, NULL); - - gchar *tag_open_ptr = NULL; - gchar *tag_close_ptr = NULL; - - if (buf) { - tag_open_ptr = strstr (buf, "<text>"); - tag_close_ptr = strstr (buf, "</text>"); - } - - if (tag_open_ptr && tag_close_ptr) { - tag_close_ptr [0] = '\0'; - tag_close_ptr [0] = 'a'; - search_string = g_strdup_printf ("\"%s\"", &tag_open_ptr[6]); - } - - g_free (buf); - } - - if (search_string) { - name = search_string; - gotta_free_name = TRUE; - } else { - name = _("Search"); - } - } - - if (icon) - g_bookmark_file_set_icon (priv->store, uri, icon, "image/png"); - - if (name) - g_bookmark_file_set_title (priv->store, uri, name); - - if (uri_new && g_strcmp0 (uri, uri_new)) - g_bookmark_file_move_item (priv->store, uri, uri_new, NULL); - - if (gotta_free_name) { - g_free (name); - } - - g_free (path); - g_free (uri_new); -} - -static void -store_monitor_cb (GFileMonitor *mon, GFile *f1, GFile *f2, - GFileMonitorEvent event_type, gpointer user_data) -{ - update_agent (BOOKMARK_AGENT (user_data)); -} - -static void -weak_destroy_cb (gpointer data, GObject *g_obj) -{ - instances [GPOINTER_TO_INT (data)] = NULL; -} |